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.
Files changed (94) hide show
  1. package/README.md +0 -4
  2. package/dist/args.js +3 -3
  3. package/dist/constants.d.ts +79 -0
  4. package/dist/constants.js +79 -0
  5. package/dist/engine/LayerPlan.d.ts +71 -8
  6. package/dist/engine/LayerPlan.js +375 -265
  7. package/dist/engine/OperationPlan.d.ts +77 -14
  8. package/dist/engine/OperationPlan.js +1508 -382
  9. package/dist/engine/OperationPlanTypes.d.ts +66 -0
  10. package/dist/engine/OperationPlanTypes.js +3 -0
  11. package/dist/engine/OutputPlan.d.ts +6 -0
  12. package/dist/engine/OutputPlan.js +138 -82
  13. package/dist/engine/StepTracker.js +76 -17
  14. package/dist/engine/executeBucket.js +327 -166
  15. package/dist/engine/lib/defaultPlanResolver.d.ts +1 -4
  16. package/dist/engine/lib/defaultPlanResolver.js +1 -5
  17. package/dist/engine/lib/withGlobalLayerPlan.d.ts +3 -1
  18. package/dist/engine/lib/withGlobalLayerPlan.js +19 -1
  19. package/dist/envelop.js +14 -3
  20. package/dist/error.d.ts +1 -1
  21. package/dist/error.js +9 -9
  22. package/dist/establishOperationPlan.d.ts +2 -1
  23. package/dist/establishOperationPlan.js +10 -10
  24. package/dist/execute.js +7 -5
  25. package/dist/global.d.ts +10 -0
  26. package/dist/global.js +25 -0
  27. package/dist/grafastGraphql.js +4 -3
  28. package/dist/grafastPrint.js +36 -4
  29. package/dist/index.d.ts +76 -8
  30. package/dist/index.js +37 -33
  31. package/dist/input.js +20 -1
  32. package/dist/inspect.js +1 -0
  33. package/dist/interfaces.d.ts +80 -122
  34. package/dist/interfaces.js +0 -77
  35. package/dist/makeGrafastSchema.d.ts +118 -35
  36. package/dist/makeGrafastSchema.js +197 -29
  37. package/dist/mermaid.js +198 -97
  38. package/dist/operationPlan-input.d.ts +1 -1
  39. package/dist/operationPlan-input.js +15 -5
  40. package/dist/planJSONInterfaces.d.ts +24 -5
  41. package/dist/prepare.d.ts +16 -9
  42. package/dist/prepare.js +54 -51
  43. package/dist/step.d.ts +45 -9
  44. package/dist/step.js +139 -22
  45. package/dist/steps/__flag.d.ts +3 -2
  46. package/dist/steps/__flag.js +31 -29
  47. package/dist/steps/__inputObject.d.ts +1 -1
  48. package/dist/steps/__inputStaticLeaf.d.ts +3 -2
  49. package/dist/steps/__inputStaticLeaf.js +13 -7
  50. package/dist/steps/__item.d.ts +1 -1
  51. package/dist/steps/__item.js +3 -3
  52. package/dist/steps/__trackedValue.d.ts +6 -3
  53. package/dist/steps/__trackedValue.js +25 -9
  54. package/dist/steps/__value.d.ts +2 -1
  55. package/dist/steps/__value.js +5 -0
  56. package/dist/steps/access.d.ts +17 -1
  57. package/dist/steps/access.js +14 -1
  58. package/dist/steps/applyInput.d.ts +1 -1
  59. package/dist/steps/applyInput.js +7 -6
  60. package/dist/steps/applyTransforms.js +9 -7
  61. package/dist/steps/bakedInput.js +2 -2
  62. package/dist/steps/coalesce.d.ts +15 -0
  63. package/dist/steps/coalesce.js +36 -0
  64. package/dist/steps/constant.js +16 -14
  65. package/dist/steps/each.d.ts +2 -2
  66. package/dist/steps/first.d.ts +2 -0
  67. package/dist/steps/first.js +5 -1
  68. package/dist/steps/graphqlResolver.d.ts +2 -2
  69. package/dist/steps/graphqlResolver.js +63 -161
  70. package/dist/steps/index.d.ts +3 -15
  71. package/dist/steps/index.js +6 -41
  72. package/dist/steps/lambda.js +1 -1
  73. package/dist/steps/last.d.ts +2 -0
  74. package/dist/steps/last.js +4 -0
  75. package/dist/steps/listTransform.d.ts +2 -2
  76. package/dist/steps/listTransform.js +11 -13
  77. package/dist/steps/load.d.ts +28 -22
  78. package/dist/steps/load.js +47 -1
  79. package/dist/steps/node.d.ts +10 -7
  80. package/dist/steps/node.js +5 -19
  81. package/dist/steps/object.js +6 -1
  82. package/dist/steps/proxy.d.ts +0 -6
  83. package/dist/steps/proxy.js +3 -3
  84. package/dist/steps/remapKeys.d.ts +1 -1
  85. package/dist/steps/remapKeys.js +0 -1
  86. package/dist/utils.d.ts +27 -5
  87. package/dist/utils.js +235 -15
  88. package/dist/version.d.ts +1 -1
  89. package/dist/version.js +1 -1
  90. package/package.json +6 -6
  91. package/dist/polymorphic.d.ts +0 -14
  92. package/dist/polymorphic.js +0 -72
  93. package/dist/steps/polymorphicBranch.d.ts +0 -27
  94. package/dist/steps/polymorphicBranch.js +0 -62
@@ -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, GraphQLScalarLiteralParser, GraphQLScalarSerializer, GraphQLScalarValueParser } from "graphql";
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
- * When defining a field with `typeDefs/plans` you can declare the field plan
8
- * directly, or you can define a configuration object that accepts the plan and
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
- * The plans/config for each field of a GraphQL object type.
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 ObjectPlans = {
28
- __assertStep?: ((step: Step) => asserts step is Step) | {
29
- new (...args: any[]): Step;
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
- [fieldName: string]: FieldPlans;
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 InputObjectPlans = {
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 type InterfaceOrUnionPlans = {
49
- __resolveType?: (o: unknown) => string;
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 type ScalarPlans = {
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 EnumPlans = {
64
- [enumValueName: string]: EnumValueApplyResolver | string | number | boolean | {
65
- value?: unknown;
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]: ObjectPlans | InputObjectPlans | InterfaceOrUnionPlans | ScalarPlans | EnumPlans;
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 astSchema = buildASTSchema(parse(typeDefs), {
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 objectPlans = plans[astType.name];
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
- if (objectPlans) {
64
- for (const [fieldName, rawFieldSpec] of Object.entries(objectPlans)) {
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
- config.extensions.grafast = { assertStep: rawFieldSpec };
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 = objectPlans && Object.hasOwn(objectPlans, fieldName)
102
- ? objectPlans[fieldName]
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 inputObjectPlans = plans[astType.name];
190
- if (inputObjectPlans) {
191
- for (const [fieldName, fieldSpec] of Object.entries(inputObjectPlans)) {
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 = inputObjectPlans && Object.hasOwn(inputObjectPlans, fieldName)
212
- ? inputObjectPlans[fieldName]
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 scalarPlans = plans[astType.name];
300
- if (typeof scalarPlans?.serialize === "function") {
301
- (0, utils_js_1.exportNameHint)(scalarPlans.serialize, `${typeName}_serialize`);
302
- config.serialize = scalarPlans.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 scalarPlans?.parseValue === "function") {
305
- (0, utils_js_1.exportNameHint)(scalarPlans.parseValue, `${typeName}_parseValue`);
306
- config.parseValue = scalarPlans.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 scalarPlans?.parseLiteral === "function") {
309
- (0, utils_js_1.exportNameHint)(scalarPlans.parseLiteral, `${typeName}_parseLiteral`);
310
- config.parseLiteral = scalarPlans.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 scalarPlans?.plan === "function") {
313
- (0, utils_js_1.exportNameHint)(scalarPlans.plan, `${typeName}_plan`);
314
- config.extensions.grafast = { plan: scalarPlans.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 enumPlans = plans[astType.name];
484
+ const enumPlan = plans[astType.name];
324
485
  const enumValues = config.values;
325
- if (enumPlans) {
326
- for (const [enumValueName, enumValueSpec] of Object.entries(enumPlans)) {
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