grafast 0.1.1-beta.21 → 0.1.1-beta.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -4
- package/dist/args.js +3 -3
- package/dist/constants.d.ts +79 -0
- package/dist/constants.js +79 -0
- package/dist/engine/LayerPlan.d.ts +71 -8
- package/dist/engine/LayerPlan.js +375 -265
- package/dist/engine/OperationPlan.d.ts +77 -14
- package/dist/engine/OperationPlan.js +1508 -382
- package/dist/engine/OperationPlanTypes.d.ts +66 -0
- package/dist/engine/OperationPlanTypes.js +3 -0
- package/dist/engine/OutputPlan.d.ts +6 -0
- package/dist/engine/OutputPlan.js +138 -82
- package/dist/engine/StepTracker.js +76 -17
- package/dist/engine/executeBucket.js +327 -166
- package/dist/engine/lib/defaultPlanResolver.d.ts +1 -4
- package/dist/engine/lib/defaultPlanResolver.js +1 -5
- package/dist/engine/lib/withGlobalLayerPlan.d.ts +3 -1
- package/dist/engine/lib/withGlobalLayerPlan.js +19 -1
- package/dist/envelop.js +14 -3
- package/dist/error.d.ts +1 -1
- package/dist/error.js +9 -9
- package/dist/establishOperationPlan.d.ts +2 -1
- package/dist/establishOperationPlan.js +10 -10
- package/dist/execute.js +7 -5
- package/dist/global.d.ts +10 -0
- package/dist/global.js +25 -0
- package/dist/grafastGraphql.js +4 -3
- package/dist/grafastPrint.js +36 -4
- package/dist/index.d.ts +76 -8
- package/dist/index.js +37 -33
- package/dist/input.js +20 -1
- package/dist/inspect.js +1 -0
- package/dist/interfaces.d.ts +80 -122
- package/dist/interfaces.js +0 -77
- package/dist/makeGrafastSchema.d.ts +118 -35
- package/dist/makeGrafastSchema.js +197 -29
- package/dist/mermaid.js +198 -97
- package/dist/operationPlan-input.d.ts +1 -1
- package/dist/operationPlan-input.js +15 -5
- package/dist/planJSONInterfaces.d.ts +24 -5
- package/dist/prepare.d.ts +16 -9
- package/dist/prepare.js +54 -51
- package/dist/step.d.ts +45 -9
- package/dist/step.js +139 -22
- package/dist/steps/__flag.d.ts +3 -2
- package/dist/steps/__flag.js +31 -29
- package/dist/steps/__inputObject.d.ts +1 -1
- package/dist/steps/__inputStaticLeaf.d.ts +3 -2
- package/dist/steps/__inputStaticLeaf.js +13 -7
- package/dist/steps/__item.d.ts +1 -1
- package/dist/steps/__item.js +3 -3
- package/dist/steps/__trackedValue.d.ts +6 -3
- package/dist/steps/__trackedValue.js +25 -9
- package/dist/steps/__value.d.ts +2 -1
- package/dist/steps/__value.js +5 -0
- package/dist/steps/access.d.ts +17 -1
- package/dist/steps/access.js +14 -1
- package/dist/steps/applyInput.d.ts +1 -1
- package/dist/steps/applyInput.js +7 -6
- package/dist/steps/applyTransforms.js +9 -7
- package/dist/steps/bakedInput.js +2 -2
- package/dist/steps/coalesce.d.ts +15 -0
- package/dist/steps/coalesce.js +36 -0
- package/dist/steps/constant.js +16 -14
- package/dist/steps/each.d.ts +2 -2
- package/dist/steps/first.d.ts +2 -0
- package/dist/steps/first.js +5 -1
- package/dist/steps/graphqlResolver.d.ts +2 -2
- package/dist/steps/graphqlResolver.js +63 -161
- package/dist/steps/index.d.ts +3 -15
- package/dist/steps/index.js +6 -41
- package/dist/steps/lambda.js +1 -1
- package/dist/steps/last.d.ts +2 -0
- package/dist/steps/last.js +4 -0
- package/dist/steps/listTransform.d.ts +2 -2
- package/dist/steps/listTransform.js +11 -13
- package/dist/steps/load.d.ts +28 -22
- package/dist/steps/load.js +47 -1
- package/dist/steps/node.d.ts +10 -7
- package/dist/steps/node.js +5 -19
- package/dist/steps/object.js +6 -1
- package/dist/steps/proxy.d.ts +0 -6
- package/dist/steps/proxy.js +3 -3
- package/dist/steps/remapKeys.d.ts +1 -1
- package/dist/steps/remapKeys.js +0 -1
- package/dist/utils.d.ts +27 -5
- package/dist/utils.js +235 -15
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +6 -6
- package/dist/polymorphic.d.ts +0 -14
- package/dist/polymorphic.js +0 -72
- package/dist/steps/polymorphicBranch.d.ts +0 -27
- package/dist/steps/polymorphicBranch.js +0 -62
package/dist/interfaces.js
CHANGED
|
@@ -1,80 +1,3 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.$$deepDepSkip = exports.FORBIDDEN_BY_NULLABLE_BOUNDARY_FLAGS = exports.DEFAULT_FORBIDDEN_FLAGS = exports.TRAPPABLE_FLAGS = exports.DEFAULT_ACCEPT_FLAGS = exports.ALL_FLAGS = exports.FLAG_STOPPED = exports.FLAG_POLY_SKIPPED = exports.FLAG_INHIBITED = exports.FLAG_NULL = exports.FLAG_ERROR = exports.NO_FLAGS = exports.$$ts = exports.$$timeout = exports.$$subroutine = exports.$$safeError = exports.$$proxy = exports.$$streamMore = exports.$$eventEmitter = exports.$$idempotent = exports.$$concreteType = exports.$$extensions = exports.$$data = exports.$$bypassGraphQL = exports.$$verbatim = exports.$$id = exports.$$planResults = exports.$$grafastContext = exports.$$hooked = exports.$$cacheByOperation = exports.$$queryCache = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
exports.$$queryCache = Symbol("queryCache");
|
|
6
|
-
/**
|
|
7
|
-
* We store the cache directly onto the GraphQLSchema so that it gets garbage
|
|
8
|
-
* collected along with the schema when it's not needed any more. To do so, we
|
|
9
|
-
* attach it using this symbol.
|
|
10
|
-
*/
|
|
11
|
-
exports.$$cacheByOperation = Symbol("cacheByOperation");
|
|
12
|
-
exports.$$hooked = Symbol("hookArgsApplied");
|
|
13
|
-
exports.$$grafastContext = Symbol("context");
|
|
14
|
-
exports.$$planResults = Symbol("planResults");
|
|
15
|
-
exports.$$id = Symbol("id");
|
|
16
|
-
/** Return the value verbatim, don't execute */
|
|
17
|
-
exports.$$verbatim = Symbol("verbatim");
|
|
18
|
-
/**
|
|
19
|
-
* If we're sure the data is the right shape and valid, we can set this key and
|
|
20
|
-
* it can be returned directly
|
|
21
|
-
*/
|
|
22
|
-
exports.$$bypassGraphQL = Symbol("bypassGraphQL");
|
|
23
|
-
exports.$$data = Symbol("data");
|
|
24
|
-
/**
|
|
25
|
-
* For attaching additional metadata to the GraphQL execution result, for
|
|
26
|
-
* example details of the plan or SQL queries or similar that were executed.
|
|
27
|
-
*/
|
|
28
|
-
exports.$$extensions = Symbol("extensions");
|
|
29
|
-
/**
|
|
30
|
-
* The "GraphQLObjectType" type name, useful when dealing with polymorphism.
|
|
31
|
-
*/
|
|
32
|
-
exports.$$concreteType = Symbol("concreteType");
|
|
33
|
-
/**
|
|
34
|
-
* Set this key on a type if that type's serialization is idempotent (that is
|
|
35
|
-
* to say `serialize(serialize(thing)) === serialize(thing)`). This means we
|
|
36
|
-
* don't have to "roll-back" serialization if we need to fallback to graphql-js
|
|
37
|
-
* execution.
|
|
38
|
-
*/
|
|
39
|
-
exports.$$idempotent = Symbol("idempotent");
|
|
40
|
-
/**
|
|
41
|
-
* The event emitter used for outputting execution events.
|
|
42
|
-
*/
|
|
43
|
-
exports.$$eventEmitter = Symbol("executionEventEmitter");
|
|
44
|
-
/**
|
|
45
|
-
* Used to indicate that an array has more results available via a stream.
|
|
46
|
-
*/
|
|
47
|
-
exports.$$streamMore = Symbol("streamMore");
|
|
48
|
-
exports.$$proxy = Symbol("proxy");
|
|
49
|
-
/**
|
|
50
|
-
* If an error has this property set then it's safe to send through to the user
|
|
51
|
-
* without being masked.
|
|
52
|
-
*/
|
|
53
|
-
exports.$$safeError = Symbol("safeError");
|
|
54
|
-
/** The layerPlan used as a subroutine for this step */
|
|
55
|
-
exports.$$subroutine = Symbol("subroutine");
|
|
56
|
-
/** For tracking the timeout a TimeoutError happened from */
|
|
57
|
-
exports.$$timeout = Symbol("timeout");
|
|
58
|
-
/** For tracking _when_ the timeout happened (because once the JIT has warmed it might not need so long) */
|
|
59
|
-
exports.$$ts = Symbol("timestamp");
|
|
60
|
-
function flag(f) {
|
|
61
|
-
return f;
|
|
62
|
-
}
|
|
63
|
-
exports.NO_FLAGS = flag(0);
|
|
64
|
-
exports.FLAG_ERROR = flag(1 << 0);
|
|
65
|
-
exports.FLAG_NULL = flag(1 << 1);
|
|
66
|
-
exports.FLAG_INHIBITED = flag(1 << 2);
|
|
67
|
-
exports.FLAG_POLY_SKIPPED = flag(1 << 3);
|
|
68
|
-
exports.FLAG_STOPPED = flag(1 << 4);
|
|
69
|
-
exports.ALL_FLAGS = flag(exports.FLAG_ERROR | exports.FLAG_NULL | exports.FLAG_INHIBITED | exports.FLAG_POLY_SKIPPED | exports.FLAG_STOPPED);
|
|
70
|
-
/** By default, accept null values as an input */
|
|
71
|
-
exports.DEFAULT_ACCEPT_FLAGS = flag(exports.FLAG_NULL);
|
|
72
|
-
exports.TRAPPABLE_FLAGS = flag(exports.FLAG_ERROR | exports.FLAG_NULL | exports.FLAG_INHIBITED);
|
|
73
|
-
exports.DEFAULT_FORBIDDEN_FLAGS = flag(exports.ALL_FLAGS & ~exports.DEFAULT_ACCEPT_FLAGS);
|
|
74
|
-
exports.FORBIDDEN_BY_NULLABLE_BOUNDARY_FLAGS = flag(exports.FLAG_NULL | exports.FLAG_POLY_SKIPPED);
|
|
75
|
-
tslib_1.__exportStar(require("./planJSONInterfaces.js"), exports);
|
|
76
|
-
/**
|
|
77
|
-
* @internal
|
|
78
|
-
*/
|
|
79
|
-
exports.$$deepDepSkip = Symbol("deepDepSkip_experimental");
|
|
80
3
|
//# sourceMappingURL=interfaces.js.map
|
|
@@ -1,16 +1,11 @@
|
|
|
1
|
-
import type { GraphQLFieldResolver
|
|
1
|
+
import type { GraphQLFieldResolver } from "graphql";
|
|
2
2
|
import { GraphQLSchema } from "graphql";
|
|
3
3
|
import * as graphql from "graphql";
|
|
4
|
-
import type { ArgumentApplyPlanResolver, EnumValueApplyResolver, FieldPlanResolver, InputObjectFieldApplyResolver, InputObjectTypeBakedResolver, ScalarPlanResolver } from "./interfaces.js";
|
|
4
|
+
import type { AbstractTypePlanner, ArgumentApplyPlanResolver, BaseGraphQLArguments, EnumValueApplyResolver, FieldPlanResolver, InputObjectFieldApplyResolver, InputObjectTypeBakedResolver, ScalarPlanResolver } from "./interfaces.js";
|
|
5
5
|
import type { Step } from "./step.js";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
* more.
|
|
10
|
-
*/
|
|
11
|
-
export type FieldPlans = FieldPlanResolver<any, any, any> | {
|
|
12
|
-
plan?: FieldPlanResolver<any, any, any>;
|
|
13
|
-
subscribePlan?: FieldPlanResolver<any, any, any>;
|
|
6
|
+
export interface ObjectFieldConfig<TSource extends Step = Step, TArgs extends BaseGraphQLArguments = any, TResultStep extends Step = Step> {
|
|
7
|
+
plan?: FieldPlanResolver<TSource, TArgs, TResultStep>;
|
|
8
|
+
subscribePlan?: FieldPlanResolver<TSource, TArgs, TResultStep>;
|
|
14
9
|
resolve?: GraphQLFieldResolver<any, any>;
|
|
15
10
|
subscribe?: GraphQLFieldResolver<any, any>;
|
|
16
11
|
args?: {
|
|
@@ -20,21 +15,39 @@ export type FieldPlans = FieldPlanResolver<any, any, any> | {
|
|
|
20
15
|
extensions?: graphql.GraphQLArgumentExtensions;
|
|
21
16
|
};
|
|
22
17
|
};
|
|
23
|
-
}
|
|
18
|
+
}
|
|
24
19
|
/**
|
|
25
|
-
*
|
|
20
|
+
* When defining a field with `typeDefs/objects` you can declare the field plan
|
|
21
|
+
* directly, or you can define a configuration object that accepts the plan and
|
|
22
|
+
* more.
|
|
26
23
|
*/
|
|
27
|
-
export type
|
|
28
|
-
|
|
29
|
-
|
|
24
|
+
export type FieldPlan<TSource extends Step = Step, TArgs extends BaseGraphQLArguments = BaseGraphQLArguments, TResultStep extends Step = Step> = FieldPlanResolver<TSource, TArgs, TResultStep> | ObjectFieldConfig<TSource, TArgs, TResultStep>;
|
|
25
|
+
export type DeprecatedObjectPlan<TSource extends Step = Step> = {
|
|
26
|
+
__assertStep?: ((step: Step) => asserts step is TSource) | {
|
|
27
|
+
new (...args: any[]): TSource;
|
|
30
28
|
};
|
|
29
|
+
__isTypeOf?: graphql.GraphQLIsTypeOfFn<any, any>;
|
|
30
|
+
__planType?($specifier: Step): TSource;
|
|
31
31
|
} & {
|
|
32
|
-
[
|
|
32
|
+
[key: string]: FieldPlan<TSource, any, any>;
|
|
33
33
|
};
|
|
34
|
+
/**
|
|
35
|
+
* The plans/config for each field of a GraphQL object type.
|
|
36
|
+
*/
|
|
37
|
+
export interface ObjectPlan<TSource extends Step = Step> {
|
|
38
|
+
assertStep?: ((step: Step) => asserts step is TSource) | {
|
|
39
|
+
new (...args: any[]): TSource;
|
|
40
|
+
};
|
|
41
|
+
isTypeOf?: graphql.GraphQLIsTypeOfFn<any, any>;
|
|
42
|
+
planType?($specifier: Step): TSource;
|
|
43
|
+
plans?: {
|
|
44
|
+
[key: string]: FieldPlan<TSource, any, any>;
|
|
45
|
+
};
|
|
46
|
+
}
|
|
34
47
|
/**
|
|
35
48
|
* The plans for each field of a GraphQL input object type.
|
|
36
49
|
*/
|
|
37
|
-
export type
|
|
50
|
+
export type DeprecatedInputObjectPlan = {
|
|
38
51
|
__baked?: InputObjectTypeBakedResolver;
|
|
39
52
|
} & {
|
|
40
53
|
[fieldName: string]: InputObjectFieldApplyResolver<any> | {
|
|
@@ -42,44 +55,114 @@ export type InputObjectPlans = {
|
|
|
42
55
|
extensions?: graphql.GraphQLInputFieldExtensions;
|
|
43
56
|
};
|
|
44
57
|
};
|
|
58
|
+
export interface InputObjectFieldConfig<TParent = any, TData = any> {
|
|
59
|
+
apply?: InputObjectFieldApplyResolver<TParent, TData>;
|
|
60
|
+
extensions?: graphql.GraphQLInputFieldExtensions;
|
|
61
|
+
}
|
|
62
|
+
export type InputFieldPlan<TParent = any, TData = any> = InputObjectFieldApplyResolver<TParent, TData> | InputObjectFieldConfig<TParent, TData>;
|
|
63
|
+
export interface InputObjectPlan {
|
|
64
|
+
baked?: InputObjectTypeBakedResolver;
|
|
65
|
+
plans?: {
|
|
66
|
+
[fieldName: string]: InputFieldPlan;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
45
69
|
/**
|
|
46
70
|
* The plan config for an interface or union type.
|
|
47
71
|
*/
|
|
48
|
-
export
|
|
49
|
-
|
|
72
|
+
export interface AbstractTypePlan<TSource extends Step = any, TSpecifier extends Step = TSource> {
|
|
73
|
+
/**
|
|
74
|
+
* Runtime. If the polymorphic data just needs resolving to a type name, this
|
|
75
|
+
* method can be used to return said type name. If planning of polymorphism
|
|
76
|
+
* is more complex for this polymorphic type (for example, if it includes
|
|
77
|
+
* fetching of data) then the `planType` method should be used instead.
|
|
78
|
+
*
|
|
79
|
+
* Warning: this method is more expensive than planType because it requires
|
|
80
|
+
* the implementation of GraphQL.js emulation.
|
|
81
|
+
*/
|
|
82
|
+
resolveType?: graphql.GraphQLTypeResolver<any, Grafast.Context>;
|
|
83
|
+
/**
|
|
84
|
+
* Takes a step representing this polymorphic position, and returns a
|
|
85
|
+
* "specifier" step that will be input to planType. If not specified, the
|
|
86
|
+
* step's own `.toSpecifier()` will be used, if present, otherwise the
|
|
87
|
+
* step's own `.toRecord()`, and failing that the step itself.
|
|
88
|
+
*/
|
|
89
|
+
toSpecifier?($step: TSource): TSpecifier;
|
|
90
|
+
/**
|
|
91
|
+
* Plantime. `$specifier` is either a step returned from a field or list
|
|
92
|
+
* position with an abstract type, or a `__ValueStep` that represents the
|
|
93
|
+
* combined values of such steps (to prevent unbounded plan branching).
|
|
94
|
+
* `planType` must then construct a step that represents the `__typename`
|
|
95
|
+
* related to this given specifier (or `null` if no match can be found) and a
|
|
96
|
+
* `planForType` method which, when called, should return the step for the
|
|
97
|
+
* given type.
|
|
98
|
+
*/
|
|
99
|
+
planType?: ($specifier: TSpecifier) => AbstractTypePlanner;
|
|
100
|
+
}
|
|
101
|
+
export interface InterfacePlan<TSource extends Step = any, TSpecifier extends Step = TSource> extends AbstractTypePlan<TSource, TSpecifier> {
|
|
102
|
+
}
|
|
103
|
+
export interface UnionPlan<TSource extends Step = any, TSpecifier extends Step = TSource> extends AbstractTypePlan<TSource, TSpecifier> {
|
|
104
|
+
}
|
|
105
|
+
export type DeprecatedUnionOrInterfacePlan = {
|
|
106
|
+
[TKey in keyof AbstractTypePlan as `__${TKey}`]: AbstractTypePlan[TKey];
|
|
50
107
|
};
|
|
51
108
|
/**
|
|
52
109
|
* The config for a GraphQL scalar type.
|
|
53
110
|
*/
|
|
54
|
-
export
|
|
55
|
-
serialize?: GraphQLScalarSerializer<any>;
|
|
56
|
-
parseValue?: GraphQLScalarValueParser<any>;
|
|
57
|
-
parseLiteral?: GraphQLScalarLiteralParser<any>;
|
|
111
|
+
export interface ScalarPlan<TInternal = any, TExternal = any> extends Omit<graphql.GraphQLScalarTypeConfig<TInternal, TExternal>, "name" | "description" | "specifiedByURL" | "astNode" | "extensionASTNodes"> {
|
|
58
112
|
plan?: ScalarPlanResolver<any, any>;
|
|
59
|
-
}
|
|
113
|
+
}
|
|
114
|
+
export interface EnumValueConfig extends Omit<graphql.GraphQLEnumValueConfig, "description" | "deprecationReason" | "astNode"> {
|
|
115
|
+
apply?: EnumValueApplyResolver;
|
|
116
|
+
}
|
|
117
|
+
export type EnumValueInput = EnumValueApplyResolver | EnumValueConfig | string | number | boolean;
|
|
60
118
|
/**
|
|
61
119
|
* The values/configs for the entries in a GraphQL enum type.
|
|
62
120
|
*/
|
|
63
|
-
export type
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
extensions?: graphql.GraphQLEnumValueExtensions;
|
|
67
|
-
apply?: EnumValueApplyResolver;
|
|
121
|
+
export type EnumPlan = {
|
|
122
|
+
values?: {
|
|
123
|
+
[enumValueName: string]: EnumValueInput | undefined;
|
|
68
124
|
};
|
|
69
125
|
};
|
|
70
126
|
/**
|
|
71
127
|
* A map from GraphQL named type to the config for that type.
|
|
128
|
+
*
|
|
129
|
+
* @deprecated Please use the different plan types instead
|
|
72
130
|
*/
|
|
73
131
|
export interface GrafastPlans {
|
|
74
|
-
[typeName: string]:
|
|
132
|
+
[typeName: string]: DeprecatedObjectPlan | DeprecatedInputObjectPlan | DeprecatedUnionOrInterfacePlan | ScalarPlan | EnumPlan;
|
|
133
|
+
}
|
|
134
|
+
export interface GrafastSchemaConfig {
|
|
135
|
+
typeDefs: string | graphql.DocumentNode | graphql.DocumentNode[];
|
|
136
|
+
/**
|
|
137
|
+
* All the different types of plans smooshed together to simulate the old
|
|
138
|
+
* typeDefs/resolvers pattern. Avoid.
|
|
139
|
+
*
|
|
140
|
+
* @deprecated Please use objects, unions, interfaces, inputObjects, scalars or enums as appropriate.
|
|
141
|
+
*/
|
|
142
|
+
plans?: GrafastPlans;
|
|
143
|
+
scalars?: {
|
|
144
|
+
[typeName: string]: ScalarPlan;
|
|
145
|
+
};
|
|
146
|
+
enums?: {
|
|
147
|
+
[typeName: string]: EnumPlan;
|
|
148
|
+
};
|
|
149
|
+
objects?: {
|
|
150
|
+
[typeName: string]: ObjectPlan<any>;
|
|
151
|
+
};
|
|
152
|
+
unions?: {
|
|
153
|
+
[typeName: string]: UnionPlan<any>;
|
|
154
|
+
};
|
|
155
|
+
interfaces?: {
|
|
156
|
+
[typeName: string]: InterfacePlan<any>;
|
|
157
|
+
};
|
|
158
|
+
inputObjects?: {
|
|
159
|
+
[typeName: string]: InputObjectPlan;
|
|
160
|
+
};
|
|
161
|
+
enableDeferStream?: boolean;
|
|
75
162
|
}
|
|
76
163
|
/**
|
|
77
164
|
* Takes a GraphQL schema definition in Interface Definition Language (IDL/SDL)
|
|
78
165
|
* syntax and configs for the types in it and returns a GraphQL schema.
|
|
79
166
|
*/
|
|
80
|
-
export declare function makeGrafastSchema(details:
|
|
81
|
-
typeDefs: string;
|
|
82
|
-
plans: GrafastPlans;
|
|
83
|
-
enableDeferStream?: boolean;
|
|
84
|
-
}): GraphQLSchema;
|
|
167
|
+
export declare function makeGrafastSchema(details: GrafastSchemaConfig): GraphQLSchema;
|
|
85
168
|
//# sourceMappingURL=makeGrafastSchema.d.ts.map
|
|
@@ -11,10 +11,134 @@ const { buildASTSchema, isEnumType, isInputObjectType, isInterfaceType, isObject
|
|
|
11
11
|
* syntax and configs for the types in it and returns a GraphQL schema.
|
|
12
12
|
*/
|
|
13
13
|
function makeGrafastSchema(details) {
|
|
14
|
-
const { typeDefs, plans, enableDeferStream = false } = details;
|
|
15
|
-
const
|
|
14
|
+
const { typeDefs, plans: rawPlans, objects, unions, interfaces, inputObjects, scalars, enums, enableDeferStream = false, } = details;
|
|
15
|
+
const document = typeof typeDefs === "string"
|
|
16
|
+
? parse(typeDefs)
|
|
17
|
+
: Array.isArray(typeDefs)
|
|
18
|
+
? {
|
|
19
|
+
kind: graphql.Kind.DOCUMENT,
|
|
20
|
+
definitions: typeDefs.flatMap((t) => t.definitions),
|
|
21
|
+
}
|
|
22
|
+
: typeDefs;
|
|
23
|
+
if (!document || document.kind !== "Document") {
|
|
24
|
+
throw new Error("The first argument to makeGrafastSchema must be an object containing a `typeDefs` field; the value for this field should be a parsed GraphQL document, array of these, or a string.");
|
|
25
|
+
}
|
|
26
|
+
const astSchema = buildASTSchema(document, {
|
|
16
27
|
enableDeferStream,
|
|
17
28
|
});
|
|
29
|
+
let plans;
|
|
30
|
+
if (rawPlans) {
|
|
31
|
+
if (objects || unions || interfaces || inputObjects || scalars || enums) {
|
|
32
|
+
throw new Error(`plans is deprecated and may not be specified alongside newer approaches`);
|
|
33
|
+
}
|
|
34
|
+
plans = rawPlans;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
// Hackily convert the new format into the old format. We'll do away with
|
|
38
|
+
// this in future, but for now it's the easiest way to ensure compatibility
|
|
39
|
+
plans = {};
|
|
40
|
+
const assertLocation = (typeName, expectedLocation) => {
|
|
41
|
+
const t = astSchema.getType(typeName);
|
|
42
|
+
if (!t) {
|
|
43
|
+
throw new Error(`You detailed '${expectedLocation}.${typeName}', but the '${typeName}' type does not exist in the schema.`);
|
|
44
|
+
}
|
|
45
|
+
const [description, attr] = (() => {
|
|
46
|
+
if (isObjectType(t)) {
|
|
47
|
+
return ["an object type", "objects"];
|
|
48
|
+
}
|
|
49
|
+
else if (isInterfaceType(t)) {
|
|
50
|
+
return ["an interface type", "interfaces"];
|
|
51
|
+
}
|
|
52
|
+
else if (isUnionType(t)) {
|
|
53
|
+
return ["a union type", "unions"];
|
|
54
|
+
}
|
|
55
|
+
else if (isInputObjectType(t)) {
|
|
56
|
+
return ["an input object type", "inputObjects"];
|
|
57
|
+
}
|
|
58
|
+
else if (isScalarType(t)) {
|
|
59
|
+
return ["a scalar type", "scalars"];
|
|
60
|
+
}
|
|
61
|
+
else if (isEnumType(t)) {
|
|
62
|
+
return ["an enum type", "enums"];
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
throw new Error(`Type ${t} not understood`);
|
|
66
|
+
}
|
|
67
|
+
})();
|
|
68
|
+
if (expectedLocation !== attr) {
|
|
69
|
+
throw new Error(`You defined '${t}' under '${expectedLocation}', but it is ${description} so it should be defined under '${attr}'.`);
|
|
70
|
+
}
|
|
71
|
+
return t;
|
|
72
|
+
};
|
|
73
|
+
for (const [typeName, spec] of Object.entries(objects ?? {})) {
|
|
74
|
+
const t = assertLocation(typeName, "objects");
|
|
75
|
+
const o = {};
|
|
76
|
+
plans[typeName] = o;
|
|
77
|
+
const { plans: planResolvers = {}, ...rest } = spec;
|
|
78
|
+
for (const [key, val] of Object.entries(rest)) {
|
|
79
|
+
o[`__${key}`] = val;
|
|
80
|
+
}
|
|
81
|
+
for (const [key, val] of Object.entries(planResolvers)) {
|
|
82
|
+
if (!t.getFields()[key]) {
|
|
83
|
+
throw new Error(`Object type '${t}' has no field '${key}'.`);
|
|
84
|
+
}
|
|
85
|
+
o[key] = val;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
for (const [typeName, spec] of Object.entries(inputObjects ?? {})) {
|
|
89
|
+
const t = assertLocation(typeName, "inputObjects");
|
|
90
|
+
const o = {};
|
|
91
|
+
plans[typeName] = o;
|
|
92
|
+
const { plans: planResolvers = {}, ...rest } = spec;
|
|
93
|
+
for (const [key, val] of Object.entries(rest)) {
|
|
94
|
+
o[`__${key}`] = val;
|
|
95
|
+
}
|
|
96
|
+
for (const [key, val] of Object.entries(planResolvers)) {
|
|
97
|
+
if (!t.getFields()[key]) {
|
|
98
|
+
throw new Error(`Input object type '${t}' has no input field '${key}'.`);
|
|
99
|
+
}
|
|
100
|
+
o[key] = val;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
for (const [typeName, spec] of Object.entries(unions ?? {})) {
|
|
104
|
+
assertLocation(typeName, "unions");
|
|
105
|
+
const o = {};
|
|
106
|
+
plans[typeName] = o;
|
|
107
|
+
for (const [key, val] of Object.entries(spec)) {
|
|
108
|
+
o[`__${key}`] = val;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
for (const [typeName, spec] of Object.entries(interfaces ?? {})) {
|
|
112
|
+
assertLocation(typeName, "interfaces");
|
|
113
|
+
const o = {};
|
|
114
|
+
plans[typeName] = o;
|
|
115
|
+
for (const [key, val] of Object.entries(spec)) {
|
|
116
|
+
o[`__${key}`] = val;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
for (const [typeName, spec] of Object.entries(scalars ?? {})) {
|
|
120
|
+
assertLocation(typeName, "scalars");
|
|
121
|
+
plans[typeName] = spec;
|
|
122
|
+
}
|
|
123
|
+
for (const [typeName, spec] of Object.entries(enums ?? {})) {
|
|
124
|
+
const t = assertLocation(typeName, "enums");
|
|
125
|
+
const o = {};
|
|
126
|
+
plans[typeName] = o;
|
|
127
|
+
const { values = {}, ...rest } = spec;
|
|
128
|
+
if ("plans" in rest) {
|
|
129
|
+
throw new Error(`Enum type '${t}' cannot have field plans, please use 'values'.`);
|
|
130
|
+
}
|
|
131
|
+
for (const [key, val] of Object.entries(rest)) {
|
|
132
|
+
o[`__${key}`] = val;
|
|
133
|
+
}
|
|
134
|
+
for (const [key, val] of Object.entries(values)) {
|
|
135
|
+
if (!t.getValues().find((v) => v.name === key)) {
|
|
136
|
+
throw new Error(`Enum type '${t}' has no value '${key}'.`);
|
|
137
|
+
}
|
|
138
|
+
o[key] = val;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
18
142
|
const schemaConfig = astSchema.toConfig();
|
|
19
143
|
const typeByName = new Map();
|
|
20
144
|
function mapType(type) {
|
|
@@ -51,7 +175,7 @@ function makeGrafastSchema(details) {
|
|
|
51
175
|
}
|
|
52
176
|
if (isObjectType(astType)) {
|
|
53
177
|
const rawConfig = astType.toConfig();
|
|
54
|
-
const
|
|
178
|
+
const objectPlan = plans[astType.name];
|
|
55
179
|
const rawFields = rawConfig.fields;
|
|
56
180
|
const rawInterfaces = rawConfig.interfaces;
|
|
57
181
|
const config = {
|
|
@@ -60,11 +184,24 @@ function makeGrafastSchema(details) {
|
|
|
60
184
|
...rawConfig.extensions,
|
|
61
185
|
},
|
|
62
186
|
};
|
|
63
|
-
|
|
64
|
-
|
|
187
|
+
const ext = config.extensions;
|
|
188
|
+
if (objectPlan) {
|
|
189
|
+
for (const [fieldName, rawFieldSpec] of Object.entries(objectPlan)) {
|
|
65
190
|
if (fieldName === "__assertStep") {
|
|
66
191
|
(0, utils_js_1.exportNameHint)(rawFieldSpec, `${typeName}_assertStep`);
|
|
67
|
-
|
|
192
|
+
ext.grafast ??= {};
|
|
193
|
+
config.extensions.grafast.assertStep = rawFieldSpec;
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
else if (fieldName === "__planType") {
|
|
197
|
+
(0, utils_js_1.exportNameHint)(rawFieldSpec, `${typeName}_planType`);
|
|
198
|
+
ext.grafast ??= {};
|
|
199
|
+
config.extensions.grafast.planType = rawFieldSpec;
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
else if (fieldName === "__isTypeOf") {
|
|
203
|
+
(0, utils_js_1.exportNameHint)(rawFieldSpec, `${typeName}_isTypeOf`);
|
|
204
|
+
config.isTypeOf = rawFieldSpec;
|
|
68
205
|
continue;
|
|
69
206
|
}
|
|
70
207
|
else if (fieldName.startsWith("__")) {
|
|
@@ -98,8 +235,8 @@ function makeGrafastSchema(details) {
|
|
|
98
235
|
if (fieldName.startsWith("__")) {
|
|
99
236
|
continue;
|
|
100
237
|
}
|
|
101
|
-
const fieldSpec =
|
|
102
|
-
?
|
|
238
|
+
const fieldSpec = objectPlan && Object.hasOwn(objectPlan, fieldName)
|
|
239
|
+
? objectPlan[fieldName]
|
|
103
240
|
: undefined;
|
|
104
241
|
const fieldConfig = {
|
|
105
242
|
...rawFieldSpec,
|
|
@@ -186,9 +323,9 @@ function makeGrafastSchema(details) {
|
|
|
186
323
|
},
|
|
187
324
|
},
|
|
188
325
|
};
|
|
189
|
-
const
|
|
190
|
-
if (
|
|
191
|
-
for (const [fieldName, fieldSpec] of Object.entries(
|
|
326
|
+
const inputObjectPlan = plans[astType.name];
|
|
327
|
+
if (inputObjectPlan) {
|
|
328
|
+
for (const [fieldName, fieldSpec] of Object.entries(inputObjectPlan)) {
|
|
192
329
|
if (fieldName === "__baked") {
|
|
193
330
|
config.extensions.grafast.baked =
|
|
194
331
|
fieldSpec;
|
|
@@ -208,8 +345,8 @@ function makeGrafastSchema(details) {
|
|
|
208
345
|
config.fields = function () {
|
|
209
346
|
const fields = Object.create(null);
|
|
210
347
|
for (const [fieldName, rawFieldConfig] of Object.entries(rawFields)) {
|
|
211
|
-
const fieldSpec =
|
|
212
|
-
?
|
|
348
|
+
const fieldSpec = inputObjectPlan && Object.hasOwn(inputObjectPlan, fieldName)
|
|
349
|
+
? inputObjectPlan[fieldName]
|
|
213
350
|
: undefined;
|
|
214
351
|
const fieldConfig = {
|
|
215
352
|
...rawFieldConfig,
|
|
@@ -270,6 +407,18 @@ function makeGrafastSchema(details) {
|
|
|
270
407
|
(0, utils_js_1.exportNameHint)(polyPlans.__resolveType, `${typeName}_resolveType`);
|
|
271
408
|
config.resolveType = polyPlans.__resolveType;
|
|
272
409
|
}
|
|
410
|
+
if (polyPlans?.__toSpecifier) {
|
|
411
|
+
(0, utils_js_1.exportNameHint)(polyPlans.__toSpecifier, `${typeName}_toSpecifier`);
|
|
412
|
+
config.extensions ??= Object.create(null);
|
|
413
|
+
config.extensions.grafast ??= Object.create(null);
|
|
414
|
+
config.extensions.grafast.toSpecifier = polyPlans.__toSpecifier;
|
|
415
|
+
}
|
|
416
|
+
if (polyPlans?.__planType) {
|
|
417
|
+
(0, utils_js_1.exportNameHint)(polyPlans.__planType, `${typeName}_planType`);
|
|
418
|
+
config.extensions ??= Object.create(null);
|
|
419
|
+
config.extensions.grafast ??= Object.create(null);
|
|
420
|
+
config.extensions.grafast.planType = polyPlans.__planType;
|
|
421
|
+
}
|
|
273
422
|
return new graphql.GraphQLInterfaceType(config);
|
|
274
423
|
}
|
|
275
424
|
else if (isUnionType(astType)) {
|
|
@@ -286,6 +435,18 @@ function makeGrafastSchema(details) {
|
|
|
286
435
|
(0, utils_js_1.exportNameHint)(polyPlans.__resolveType, `${typeName}_resolveType`);
|
|
287
436
|
config.resolveType = polyPlans.__resolveType;
|
|
288
437
|
}
|
|
438
|
+
if (polyPlans?.__toSpecifier) {
|
|
439
|
+
(0, utils_js_1.exportNameHint)(polyPlans.__toSpecifier, `${typeName}_toSpecifier`);
|
|
440
|
+
config.extensions ??= Object.create(null);
|
|
441
|
+
config.extensions.grafast ??= Object.create(null);
|
|
442
|
+
config.extensions.grafast.toSpecifier = polyPlans.__toSpecifier;
|
|
443
|
+
}
|
|
444
|
+
if (polyPlans?.__planType) {
|
|
445
|
+
(0, utils_js_1.exportNameHint)(polyPlans.__planType, `${typeName}_planType`);
|
|
446
|
+
config.extensions ??= Object.create(null);
|
|
447
|
+
config.extensions.grafast ??= Object.create(null);
|
|
448
|
+
config.extensions.grafast.planType = polyPlans.__planType;
|
|
449
|
+
}
|
|
289
450
|
return new graphql.GraphQLUnionType(config);
|
|
290
451
|
}
|
|
291
452
|
else if (isScalarType(astType)) {
|
|
@@ -296,22 +457,22 @@ function makeGrafastSchema(details) {
|
|
|
296
457
|
...rawConfig.extensions,
|
|
297
458
|
},
|
|
298
459
|
};
|
|
299
|
-
const
|
|
300
|
-
if (typeof
|
|
301
|
-
(0, utils_js_1.exportNameHint)(
|
|
302
|
-
config.serialize =
|
|
460
|
+
const scalarPlan = plans[astType.name];
|
|
461
|
+
if (typeof scalarPlan?.serialize === "function") {
|
|
462
|
+
(0, utils_js_1.exportNameHint)(scalarPlan.serialize, `${typeName}_serialize`);
|
|
463
|
+
config.serialize = scalarPlan.serialize;
|
|
303
464
|
}
|
|
304
|
-
if (typeof
|
|
305
|
-
(0, utils_js_1.exportNameHint)(
|
|
306
|
-
config.parseValue =
|
|
465
|
+
if (typeof scalarPlan?.parseValue === "function") {
|
|
466
|
+
(0, utils_js_1.exportNameHint)(scalarPlan.parseValue, `${typeName}_parseValue`);
|
|
467
|
+
config.parseValue = scalarPlan.parseValue;
|
|
307
468
|
}
|
|
308
|
-
if (typeof
|
|
309
|
-
(0, utils_js_1.exportNameHint)(
|
|
310
|
-
config.parseLiteral =
|
|
469
|
+
if (typeof scalarPlan?.parseLiteral === "function") {
|
|
470
|
+
(0, utils_js_1.exportNameHint)(scalarPlan.parseLiteral, `${typeName}_parseLiteral`);
|
|
471
|
+
config.parseLiteral = scalarPlan.parseLiteral;
|
|
311
472
|
}
|
|
312
|
-
if (typeof
|
|
313
|
-
(0, utils_js_1.exportNameHint)(
|
|
314
|
-
config.extensions.grafast = { plan:
|
|
473
|
+
if (typeof scalarPlan?.plan === "function") {
|
|
474
|
+
(0, utils_js_1.exportNameHint)(scalarPlan.plan, `${typeName}_plan`);
|
|
475
|
+
config.extensions.grafast = { plan: scalarPlan.plan };
|
|
315
476
|
}
|
|
316
477
|
return new graphql.GraphQLScalarType(config);
|
|
317
478
|
}
|
|
@@ -320,10 +481,10 @@ function makeGrafastSchema(details) {
|
|
|
320
481
|
const config = {
|
|
321
482
|
...rawConfig,
|
|
322
483
|
};
|
|
323
|
-
const
|
|
484
|
+
const enumPlan = plans[astType.name];
|
|
324
485
|
const enumValues = config.values;
|
|
325
|
-
if (
|
|
326
|
-
for (const [enumValueName, enumValueSpec] of Object.entries(
|
|
486
|
+
if (enumPlan) {
|
|
487
|
+
for (const [enumValueName, enumValueSpec] of Object.entries(enumPlan)) {
|
|
327
488
|
const enumValue = enumValues[enumValueName];
|
|
328
489
|
if (!enumValue) {
|
|
329
490
|
console.warn(`'plans' specified configuration for enum type '${typeName}' value '${enumValueName}', but that value was not present in the type`);
|
|
@@ -389,6 +550,13 @@ function makeGrafastSchema(details) {
|
|
|
389
550
|
}
|
|
390
551
|
}
|
|
391
552
|
const schema = new graphql_1.GraphQLSchema(schemaConfig);
|
|
553
|
+
const errors = graphql.validateSchema(schema);
|
|
554
|
+
if (errors.length === 1) {
|
|
555
|
+
throw errors[0];
|
|
556
|
+
}
|
|
557
|
+
else if (errors.length > 1) {
|
|
558
|
+
throw new AggregateError(errors, `Invalid schema; first few errors:\n${errors.slice(0, 5).join("\n")}`);
|
|
559
|
+
}
|
|
392
560
|
return schema;
|
|
393
561
|
}
|
|
394
562
|
//# sourceMappingURL=makeGrafastSchema.js.map
|