Mirror: The spec-compliant minimum of client-side GraphQL.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add value utilities

+82 -1
+1
README.md
··· 44 44 | `visit` | A recursive reimplementation of GraphQL.js’ visitor. | [Source](./src/printer.ts) | 45 45 | `Kind` | The GraphQL.js’ `Kind` enum, containing supported `ASTNode` kinds. | [Source](./src/kind.ts) | 46 46 | `GraphQLError` | `GraphQLError` stripped of source/location debugging. | [Source](./src/kind.ts) | 47 + | `valueFromASTUntyped` | Coerces AST values into JS values. | [Source](./src/values.ts) | 47 48 48 49 The stated goals of any reimplementation are: 49 50 1. Not to implement any execution or type system parts of the GraphQL
+1 -1
package.json
··· 1 1 { 2 2 "name": "@0no-co/graphql.web", 3 3 "description": "A spec-compliant client-side GraphQL implementation", 4 - "version": "0.1.2", 4 + "version": "0.1.3", 5 5 "author": "0no.co <hi@0no.co>", 6 6 "source": "./src/index.ts", 7 7 "main": "./dist/graphql.web",
+1
src/index.ts
··· 4 4 export * from './parser'; 5 5 export * from './visitor'; 6 6 export * from './printer'; 7 + export * from './values';
+79
src/values.ts
··· 1 + import { TypeNode, ValueNode } from './ast'; 2 + import { Kind } from './kind'; 3 + import { Maybe } from './types'; 4 + 5 + export function valueFromASTUntyped( 6 + node: ValueNode, 7 + variables?: Maybe<Record<string, any>>, 8 + ): unknown { 9 + switch (node.kind) { 10 + case Kind.NULL: 11 + return null; 12 + case Kind.INT: 13 + return parseInt(node.value, 10); 14 + case Kind.FLOAT: 15 + return parseFloat(node.value); 16 + case Kind.STRING: 17 + case Kind.ENUM: 18 + case Kind.BOOLEAN: 19 + return node.value; 20 + case Kind.LIST: { 21 + const values: unknown[] = []; 22 + for (const value of node.values) 23 + values.push(valueFromASTUntyped(value, variables)); 24 + return values; 25 + } 26 + case Kind.OBJECT: { 27 + const obj = Object.create(null); 28 + for (const field of node.fields) 29 + obj[field.name.value] = valueFromASTUntyped(field.value, variables); 30 + return obj; 31 + } 32 + case Kind.VARIABLE: 33 + return variables && variables[node.name.value]; 34 + } 35 + } 36 + 37 + export function valueFromTypeNode( 38 + node: ValueNode, 39 + type: TypeNode, 40 + variables?: Maybe<Record<string, any>>, 41 + ): unknown { 42 + if (node.kind === Kind.VARIABLE) { 43 + const variableName = node.name.value; 44 + return variables 45 + ? valueFromTypeNode(variables[variableName], type, variables) 46 + : undefined; 47 + } else if (type.kind === Kind.NON_NULL_TYPE) { 48 + return node.kind !== Kind.NULL 49 + ? valueFromTypeNode(node, type, variables) 50 + : undefined 51 + } else if (node.kind === Kind.NULL) { 52 + return null; 53 + } else if (type.kind === Kind.LIST_TYPE) { 54 + if (node.kind === Kind.LIST) { 55 + const values: unknown[] = []; 56 + for (const value of node.values) { 57 + const coerced = valueFromTypeNode(value, type.type, variables); 58 + if (coerced === undefined) { 59 + return undefined; 60 + } else { 61 + values.push(coerced); 62 + } 63 + } 64 + return values; 65 + } 66 + } else if (type.kind === Kind.NAMED_TYPE) { 67 + switch (type.name.value) { 68 + case 'Int': 69 + case 'Float': 70 + case 'String': 71 + case 'Bool': 72 + return type.name.value + 'Value' === node.kind 73 + ? valueFromASTUntyped(node, variables) 74 + : undefined; 75 + default: 76 + return valueFromASTUntyped(node, variables); 77 + } 78 + } 79 + }