@soda-gql/core 0.13.1 → 0.14.0
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 +39 -39
- package/dist/adapter.cjs +1 -3
- package/dist/adapter.cjs.map +1 -1
- package/dist/adapter.d.cts +3 -5
- package/dist/adapter.d.cts.map +1 -1
- package/dist/adapter.d.ts +3 -5
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +1 -3
- package/dist/adapter.js.map +1 -1
- package/dist/{index-PnGDsBZE.d.cts → index-Bdt5dpFG.d.cts} +26 -5
- package/dist/{index-PnGDsBZE.d.cts.map → index-Bdt5dpFG.d.cts.map} +1 -1
- package/dist/{index-Dl3Md53A.d.ts → index-CRWc3q9X.d.cts} +300 -626
- package/dist/index-CRWc3q9X.d.cts.map +1 -0
- package/dist/{index-CcqI7_ms.d.ts → index-D1T79XaT.d.ts} +26 -5
- package/dist/{index-CcqI7_ms.d.ts.map → index-D1T79XaT.d.ts.map} +1 -1
- package/dist/{index-Ctr8gcP8.d.cts → index-DJ-yqsXz.d.ts} +300 -626
- package/dist/index-DJ-yqsXz.d.ts.map +1 -0
- package/dist/index.cjs +609 -700
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -4
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +9 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +602 -696
- package/dist/index.js.map +1 -1
- package/dist/runtime.d.cts +2 -2
- package/dist/runtime.d.ts +2 -2
- package/dist/{schema-builder-B0DcWTQ-.d.ts → schema-builder-DTinHI5s.d.ts} +2 -2
- package/dist/{schema-builder-B0DcWTQ-.d.ts.map → schema-builder-DTinHI5s.d.ts.map} +1 -1
- package/dist/{schema-builder-C7bceM7O.d.cts → schema-builder-DfdeJY7k.d.cts} +2 -2
- package/dist/{schema-builder-C7bceM7O.d.cts.map → schema-builder-DfdeJY7k.d.cts.map} +1 -1
- package/package.json +1 -1
- package/dist/index-Ctr8gcP8.d.cts.map +0 -1
- package/dist/index-Dl3Md53A.d.ts.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -195,7 +195,7 @@ const buildArgumentValue = (value, enumLookup) => {
|
|
|
195
195
|
fields: Object.entries(value).map(([key, fieldValue]) => {
|
|
196
196
|
let fieldTypeSpecifier = null;
|
|
197
197
|
if (enumLookup.typeSpecifier?.kind === "input") {
|
|
198
|
-
const fieldSpec = enumLookup.schema.input[enumLookup.typeSpecifier.name]?.fields[key];
|
|
198
|
+
const fieldSpec = (enumLookup.schema.input?.[enumLookup.typeSpecifier.name])?.fields[key];
|
|
199
199
|
fieldTypeSpecifier = fieldSpec ? parseInputSpecifier(fieldSpec) : null;
|
|
200
200
|
}
|
|
201
201
|
const valueNode = buildArgumentValue(fieldValue, {
|
|
@@ -323,12 +323,12 @@ const isShorthand = (value) => {
|
|
|
323
323
|
const expandShorthand = (schema, typeName, fieldName) => {
|
|
324
324
|
const typeDef = schema.object[typeName];
|
|
325
325
|
if (!typeDef) throw new Error(`Type "${typeName}" not found in schema`);
|
|
326
|
-
const
|
|
327
|
-
if (!
|
|
326
|
+
const fieldDef = typeDef.fields[fieldName];
|
|
327
|
+
if (!fieldDef) throw new Error(`Field "${fieldName}" not found on type "${typeName}"`);
|
|
328
328
|
return {
|
|
329
329
|
parent: typeName,
|
|
330
330
|
field: fieldName,
|
|
331
|
-
type:
|
|
331
|
+
type: typeof fieldDef === "string" ? fieldDef : fieldDef.spec,
|
|
332
332
|
args: {},
|
|
333
333
|
directives: [],
|
|
334
334
|
object: null,
|
|
@@ -337,8 +337,10 @@ const expandShorthand = (schema, typeName, fieldName) => {
|
|
|
337
337
|
};
|
|
338
338
|
const buildUnionSelection = (union, schema) => {
|
|
339
339
|
const { selections, __typename: hasTypenameFlag } = union;
|
|
340
|
-
const inlineFragments = Object.entries(selections).map(([typeName,
|
|
341
|
-
if (!
|
|
340
|
+
const inlineFragments = Object.entries(selections).map(([typeName, member]) => {
|
|
341
|
+
if (!member || typeof member !== "object") return null;
|
|
342
|
+
const { fields, directives: memberDirectives } = member;
|
|
343
|
+
const builtDirectives = buildDirectives(memberDirectives, "INLINE_FRAGMENT", schema);
|
|
342
344
|
return {
|
|
343
345
|
kind: graphql.Kind.INLINE_FRAGMENT,
|
|
344
346
|
typeCondition: {
|
|
@@ -348,9 +350,10 @@ const buildUnionSelection = (union, schema) => {
|
|
|
348
350
|
value: typeName
|
|
349
351
|
}
|
|
350
352
|
},
|
|
353
|
+
...builtDirectives.length > 0 ? { directives: builtDirectives } : {},
|
|
351
354
|
selectionSet: {
|
|
352
355
|
kind: graphql.Kind.SELECTION_SET,
|
|
353
|
-
selections: buildField(
|
|
356
|
+
selections: buildField(fields, schema, typeName)
|
|
354
357
|
}
|
|
355
358
|
};
|
|
356
359
|
}).filter((item) => item !== null);
|
|
@@ -426,7 +429,7 @@ const buildConstValueNode = (value, enumLookup) => {
|
|
|
426
429
|
fields: Object.entries(value).map(([key, fieldValue]) => {
|
|
427
430
|
let fieldTypeSpecifier = null;
|
|
428
431
|
if (enumLookup.typeSpecifier?.kind === "input") {
|
|
429
|
-
const fieldSpec = enumLookup.schema.input[enumLookup.typeSpecifier.name]?.fields[key];
|
|
432
|
+
const fieldSpec = (enumLookup.schema.input?.[enumLookup.typeSpecifier.name])?.fields[key];
|
|
430
433
|
fieldTypeSpecifier = fieldSpec ? parseInputSpecifier(fieldSpec) : null;
|
|
431
434
|
}
|
|
432
435
|
const valueNode = buildConstValueNode(fieldValue, {
|
|
@@ -470,10 +473,10 @@ const buildConstValueNode = (value, enumLookup) => {
|
|
|
470
473
|
* followed by `[]?` or `[]!` pairs for lists.
|
|
471
474
|
*
|
|
472
475
|
* @example
|
|
473
|
-
* - `"!"`
|
|
474
|
-
* - `"?"`
|
|
475
|
-
* - `"![]!"`
|
|
476
|
-
* - `"?[]?"`
|
|
476
|
+
* - `"!"` -> `String!`
|
|
477
|
+
* - `"?"` -> `String`
|
|
478
|
+
* - `"![]!"` -> `[String!]!`
|
|
479
|
+
* - `"?[]?"` -> `[String]`
|
|
477
480
|
*/
|
|
478
481
|
const buildWithTypeModifier = (modifier, buildType) => {
|
|
479
482
|
const baseType = buildType();
|
|
@@ -532,6 +535,10 @@ const buildWithTypeModifier = (modifier, buildType) => {
|
|
|
532
535
|
}
|
|
533
536
|
return curr.type;
|
|
534
537
|
};
|
|
538
|
+
/**
|
|
539
|
+
* Builds VariableDefinitionNode[] from VarSpecifier records.
|
|
540
|
+
* Kept as private fallback for callers that don't provide pre-parsed nodes.
|
|
541
|
+
*/
|
|
535
542
|
const buildVariables = (variables, schema) => {
|
|
536
543
|
return Object.entries(variables).map(([name, varSpec]) => {
|
|
537
544
|
let defaultValue;
|
|
@@ -589,7 +596,8 @@ const buildOperationTypeNode = (operation) => {
|
|
|
589
596
|
* @returns TypedDocumentNode with inferred input/output types
|
|
590
597
|
*/
|
|
591
598
|
const buildDocument = (options) => {
|
|
592
|
-
const { operationName, operationType, operationTypeName, variables, fields, schema } = options;
|
|
599
|
+
const { operationName, operationType, operationTypeName, variableDefinitionNodes, variables, fields, schema } = options;
|
|
600
|
+
const varDefs = variableDefinitionNodes ?? buildVariables(variables, schema);
|
|
593
601
|
return {
|
|
594
602
|
kind: graphql.Kind.DOCUMENT,
|
|
595
603
|
definitions: [{
|
|
@@ -599,7 +607,7 @@ const buildDocument = (options) => {
|
|
|
599
607
|
kind: graphql.Kind.NAME,
|
|
600
608
|
value: operationName
|
|
601
609
|
},
|
|
602
|
-
variableDefinitions:
|
|
610
|
+
variableDefinitions: varDefs,
|
|
603
611
|
selectionSet: {
|
|
604
612
|
kind: graphql.Kind.SELECTION_SET,
|
|
605
613
|
selections: buildField(fields, schema, operationTypeName)
|
|
@@ -620,13 +628,13 @@ const buildDocument = (options) => {
|
|
|
620
628
|
* @example
|
|
621
629
|
* ```typescript
|
|
622
630
|
* // In operation definition
|
|
623
|
-
* query
|
|
624
|
-
*
|
|
625
|
-
* fields: ({ $ }) => $colocate({
|
|
626
|
-
* userCard:
|
|
627
|
-
* posts:
|
|
631
|
+
* query("GetData")({
|
|
632
|
+
* variables: `($userId: ID!)`,
|
|
633
|
+
* fields: ({ f, $ }) => $colocate({
|
|
634
|
+
* userCard: { ...f("user", { id: $.userId })(() => ({ ...userCardFragment.spread() })) },
|
|
635
|
+
* posts: { ...f("posts", { userId: $.userId })(() => ({ ...postsFragment.spread() })) },
|
|
628
636
|
* }),
|
|
629
|
-
* });
|
|
637
|
+
* })({});
|
|
630
638
|
*
|
|
631
639
|
* // In parser definition (same labels)
|
|
632
640
|
* createExecutionResultParser({
|
|
@@ -646,16 +654,6 @@ const createColocateHelper = () => {
|
|
|
646
654
|
return $colocate;
|
|
647
655
|
};
|
|
648
656
|
|
|
649
|
-
//#endregion
|
|
650
|
-
//#region packages/core/src/types/element/compat-spec.ts
|
|
651
|
-
/**
|
|
652
|
-
* Type guard to distinguish TemplateCompatSpec from CompatSpec at runtime.
|
|
653
|
-
* Uses structural discrimination (presence of `graphqlSource` field).
|
|
654
|
-
*/
|
|
655
|
-
const isTemplateCompatSpec = (spec) => {
|
|
656
|
-
return "graphqlSource" in spec && !("fieldsBuilder" in spec);
|
|
657
|
-
};
|
|
658
|
-
|
|
659
657
|
//#endregion
|
|
660
658
|
//#region packages/core/src/utils/promise.ts
|
|
661
659
|
/**
|
|
@@ -884,7 +882,7 @@ var GqlDefine = class GqlDefine extends GqlElement {
|
|
|
884
882
|
/**
|
|
885
883
|
* Represents a reusable GraphQL field selection on a specific type.
|
|
886
884
|
*
|
|
887
|
-
* Fragments are created via `gql(({ fragment }) => fragment
|
|
885
|
+
* Fragments are created via `gql(({ fragment }) => fragment("Name", "TypeName")\`{ ... }\`())`.
|
|
888
886
|
* Use `spread()` to include the fragment's fields in an operation.
|
|
889
887
|
*
|
|
890
888
|
* @template TTypeName - The GraphQL type this fragment selects from
|
|
@@ -934,7 +932,7 @@ var Fragment = class Fragment extends GqlElement {
|
|
|
934
932
|
/**
|
|
935
933
|
* Represents a GraphQL operation (query, mutation, or subscription).
|
|
936
934
|
*
|
|
937
|
-
* Operations are created via `gql(({ query }) => query
|
|
935
|
+
* Operations are created via `gql(({ query }) => query("Name")\`{ ... }\`())`.
|
|
938
936
|
* Produces a TypedDocumentNode for type-safe execution with GraphQL clients.
|
|
939
937
|
*
|
|
940
938
|
* @template TOperationType - 'query' | 'mutation' | 'subscription'
|
|
@@ -989,42 +987,10 @@ var Operation = class Operation extends GqlElement {
|
|
|
989
987
|
}
|
|
990
988
|
};
|
|
991
989
|
|
|
992
|
-
//#endregion
|
|
993
|
-
//#region packages/core/src/composer/compat.ts
|
|
994
|
-
/**
|
|
995
|
-
* Compat composer factory for creating GraphQL operation specifications.
|
|
996
|
-
* @module
|
|
997
|
-
*/
|
|
998
|
-
/**
|
|
999
|
-
* Creates a factory for composing compat operation specifications.
|
|
1000
|
-
*
|
|
1001
|
-
* Returns a function that creates a `GqlDefine<CompatSpec<...>>` storing
|
|
1002
|
-
* the operation specification with unevaluated fieldsBuilder.
|
|
1003
|
-
*
|
|
1004
|
-
* @param schema - The GraphQL schema definition
|
|
1005
|
-
* @param operationType - The operation type ('query' | 'mutation' | 'subscription')
|
|
1006
|
-
* @returns Compat operation composer function
|
|
1007
|
-
*
|
|
1008
|
-
* @internal Used by `createGqlElementComposer`
|
|
1009
|
-
*/
|
|
1010
|
-
const createCompatComposer = (schema, operationType) => {
|
|
1011
|
-
if (schema.operations[operationType] === null) throw new Error(`Operation type ${operationType} is not defined in schema roots`);
|
|
1012
|
-
return (options) => {
|
|
1013
|
-
return GqlDefine.create(() => ({
|
|
1014
|
-
schema,
|
|
1015
|
-
operationType,
|
|
1016
|
-
operationName: options.name,
|
|
1017
|
-
variables: options.variables ?? {},
|
|
1018
|
-
fieldsBuilder: options.fields
|
|
1019
|
-
}));
|
|
1020
|
-
};
|
|
1021
|
-
};
|
|
1022
|
-
|
|
1023
990
|
//#endregion
|
|
1024
991
|
//#region packages/core/src/composer/compat-tagged-template.ts
|
|
1025
992
|
/**
|
|
1026
993
|
* Compat tagged template function for creating deferred GraphQL operation specs.
|
|
1027
|
-
* Callback builder compat path is in compat.ts.
|
|
1028
994
|
* @module
|
|
1029
995
|
*/
|
|
1030
996
|
/**
|
|
@@ -2231,14 +2197,14 @@ const ensureCacheMapBySchema = (schema) => {
|
|
|
2231
2197
|
return cacheMap;
|
|
2232
2198
|
};
|
|
2233
2199
|
/**
|
|
2234
|
-
* Creates field
|
|
2200
|
+
* Creates a field accessor function for a given object type.
|
|
2235
2201
|
*
|
|
2236
|
-
* Returns
|
|
2202
|
+
* Returns a function f("fieldName", args, extras) for building field selections.
|
|
2237
2203
|
* Factories are cached per schema+type to avoid recreation.
|
|
2238
2204
|
*
|
|
2239
2205
|
* @param schema - The GraphQL schema definition
|
|
2240
2206
|
* @param typeName - The object type name to create factories for
|
|
2241
|
-
* @returns
|
|
2207
|
+
* @returns FieldAccessorFunction for building field selections
|
|
2242
2208
|
*
|
|
2243
2209
|
* @internal Used by operation and fragment composers
|
|
2244
2210
|
*/
|
|
@@ -2246,70 +2212,88 @@ const createFieldFactories = (schema, typeName) => {
|
|
|
2246
2212
|
const cacheMap = ensureCacheMapBySchema(schema);
|
|
2247
2213
|
const cached = cacheMap.get(typeName);
|
|
2248
2214
|
if (cached) return cached;
|
|
2249
|
-
const
|
|
2250
|
-
cacheMap.set(typeName,
|
|
2251
|
-
return
|
|
2215
|
+
const factory = createFieldFactoriesInner(schema, typeName);
|
|
2216
|
+
cacheMap.set(typeName, factory);
|
|
2217
|
+
return factory;
|
|
2252
2218
|
};
|
|
2253
2219
|
const createFieldFactoriesInner = (schema, typeName) => {
|
|
2254
2220
|
const typeDef = schema.object[typeName];
|
|
2255
2221
|
if (!typeDef) throw new Error(`Type ${typeName} is not defined in schema objects`);
|
|
2256
|
-
|
|
2222
|
+
return (fieldName, fieldArgs, extras) => {
|
|
2223
|
+
if (fieldName === "__typename") {
|
|
2224
|
+
const wrap$1 = (value) => require_schema_builder.wrapByKey(extras?.alias ?? fieldName, value);
|
|
2225
|
+
return (() => wrap$1({
|
|
2226
|
+
parent: typeName,
|
|
2227
|
+
field: fieldName,
|
|
2228
|
+
type: "s|String|!",
|
|
2229
|
+
args: {},
|
|
2230
|
+
directives: extras?.directives ?? [],
|
|
2231
|
+
object: null,
|
|
2232
|
+
union: null
|
|
2233
|
+
}));
|
|
2234
|
+
}
|
|
2235
|
+
const fieldDef = typeDef.fields[fieldName];
|
|
2236
|
+
if (!fieldDef) throw new Error(`Field "${fieldName}" is not defined on type "${typeName}"`);
|
|
2237
|
+
const typeSpecifier = typeof fieldDef === "string" ? fieldDef : fieldDef.spec;
|
|
2257
2238
|
const parsedType = parseOutputField(typeSpecifier);
|
|
2258
|
-
const
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
const
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
union: null
|
|
2276
|
-
});
|
|
2239
|
+
const wrap = (value) => require_schema_builder.wrapByKey(extras?.alias ?? fieldName, value);
|
|
2240
|
+
const directives = extras?.directives ?? [];
|
|
2241
|
+
if (parsedType.kind === "object") {
|
|
2242
|
+
const factoryReturn = ((nest) => {
|
|
2243
|
+
const nestedFields = withFieldPath(appendToPath(getCurrentFieldPath(), {
|
|
2244
|
+
field: fieldName,
|
|
2245
|
+
parentType: typeName,
|
|
2246
|
+
isList: isListType(parsedType.modifier)
|
|
2247
|
+
}), () => nest({ f: createFieldFactories(schema, parsedType.name) }));
|
|
2248
|
+
return wrap({
|
|
2249
|
+
parent: typeName,
|
|
2250
|
+
field: fieldName,
|
|
2251
|
+
type: typeSpecifier,
|
|
2252
|
+
args: fieldArgs ?? {},
|
|
2253
|
+
directives,
|
|
2254
|
+
object: nestedFields,
|
|
2255
|
+
union: null
|
|
2277
2256
|
});
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
const typenameFlag = nest.__typename;
|
|
2288
|
-
const selections = withFieldPath(newPath, () => {
|
|
2289
|
-
const result = {};
|
|
2290
|
-
for (const [memberName, builder] of Object.entries(nest)) {
|
|
2291
|
-
if (memberName === "__typename") continue;
|
|
2292
|
-
if (typeof builder !== "function") continue;
|
|
2293
|
-
result[memberName] = builder({ f: createFieldFactories(schema, memberName) });
|
|
2294
|
-
}
|
|
2295
|
-
return result;
|
|
2296
|
-
});
|
|
2297
|
-
return wrap({
|
|
2298
|
-
parent: typeName,
|
|
2299
|
-
field: fieldName,
|
|
2300
|
-
type: typeSpecifier,
|
|
2301
|
-
args: fieldArgs ?? {},
|
|
2302
|
-
directives,
|
|
2303
|
-
object: null,
|
|
2304
|
-
union: {
|
|
2305
|
-
selections,
|
|
2306
|
-
__typename: typenameFlag === true
|
|
2307
|
-
}
|
|
2308
|
-
});
|
|
2257
|
+
});
|
|
2258
|
+
return factoryReturn;
|
|
2259
|
+
}
|
|
2260
|
+
if (parsedType.kind === "union") {
|
|
2261
|
+
const factoryReturn = ((nest) => {
|
|
2262
|
+
const newPath = appendToPath(getCurrentFieldPath(), {
|
|
2263
|
+
field: fieldName,
|
|
2264
|
+
parentType: typeName,
|
|
2265
|
+
isList: isListType(parsedType.modifier)
|
|
2309
2266
|
});
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2267
|
+
const typenameFlag = nest.__typename;
|
|
2268
|
+
const selections = withFieldPath(newPath, () => {
|
|
2269
|
+
const result = {};
|
|
2270
|
+
for (const [memberName, builder] of Object.entries(nest)) {
|
|
2271
|
+
if (memberName === "__typename") continue;
|
|
2272
|
+
if (typeof builder === "function") result[memberName] = {
|
|
2273
|
+
fields: builder({ f: createFieldFactories(schema, memberName) }),
|
|
2274
|
+
directives: []
|
|
2275
|
+
};
|
|
2276
|
+
else if (builder && typeof builder === "object" && "fields" in builder) result[memberName] = builder;
|
|
2277
|
+
}
|
|
2278
|
+
return result;
|
|
2279
|
+
});
|
|
2280
|
+
return wrap({
|
|
2281
|
+
parent: typeName,
|
|
2282
|
+
field: fieldName,
|
|
2283
|
+
type: typeSpecifier,
|
|
2284
|
+
args: fieldArgs ?? {},
|
|
2285
|
+
directives,
|
|
2286
|
+
object: null,
|
|
2287
|
+
union: {
|
|
2288
|
+
selections,
|
|
2289
|
+
__typename: typenameFlag === true
|
|
2290
|
+
}
|
|
2291
|
+
});
|
|
2292
|
+
});
|
|
2293
|
+
return factoryReturn;
|
|
2294
|
+
}
|
|
2295
|
+
if (parsedType.kind === "scalar" || parsedType.kind === "enum") {
|
|
2296
|
+
const factoryReturn = (() => wrap({
|
|
2313
2297
|
parent: typeName,
|
|
2314
2298
|
field: fieldName,
|
|
2315
2299
|
type: typeSpecifier,
|
|
@@ -2317,12 +2301,11 @@ const createFieldFactoriesInner = (schema, typeName) => {
|
|
|
2317
2301
|
directives,
|
|
2318
2302
|
object: null,
|
|
2319
2303
|
union: null
|
|
2320
|
-
});
|
|
2321
|
-
|
|
2322
|
-
}
|
|
2323
|
-
|
|
2324
|
-
}
|
|
2325
|
-
return Object.fromEntries(entries);
|
|
2304
|
+
}));
|
|
2305
|
+
return factoryReturn;
|
|
2306
|
+
}
|
|
2307
|
+
throw new Error(`Unsupported field type kind: ${parsedType.kind}`);
|
|
2308
|
+
};
|
|
2326
2309
|
};
|
|
2327
2310
|
|
|
2328
2311
|
//#endregion
|
|
@@ -2403,220 +2386,6 @@ const createVarAssignments = (definitions, providedValues) => {
|
|
|
2403
2386
|
*/
|
|
2404
2387
|
const createVarRefs = (definitions) => mapValues(definitions, (_, name) => createVarRefFromVariable(name));
|
|
2405
2388
|
|
|
2406
|
-
//#endregion
|
|
2407
|
-
//#region packages/core/src/composer/operation-core.ts
|
|
2408
|
-
/**
|
|
2409
|
-
* Core operation building logic shared by operation and extend composers.
|
|
2410
|
-
* @module
|
|
2411
|
-
* @internal
|
|
2412
|
-
*/
|
|
2413
|
-
/**
|
|
2414
|
-
* Builds an operation artifact from the provided parameters.
|
|
2415
|
-
*
|
|
2416
|
-
* This function contains the core logic for:
|
|
2417
|
-
* - Creating variable refs and field factories
|
|
2418
|
-
* - Evaluating fields with fragment usage tracking
|
|
2419
|
-
* - Building the document
|
|
2420
|
-
* - Handling metadata (sync and async)
|
|
2421
|
-
* - Applying document transformations
|
|
2422
|
-
*
|
|
2423
|
-
* @param params - Operation building parameters
|
|
2424
|
-
* @returns Operation artifact or Promise of artifact (if async metadata)
|
|
2425
|
-
*
|
|
2426
|
-
* @internal Used by operation.ts, extend.ts, and operation-tagged-template.ts
|
|
2427
|
-
*/
|
|
2428
|
-
const buildOperationArtifact = (params) => {
|
|
2429
|
-
const { schema, operationType, operationTypeName, operationName, variables, adapter, metadata: metadataBuilder, transformDocument: operationTransformDocument, adapterTransformDocument } = params;
|
|
2430
|
-
const $ = createVarRefs(variables);
|
|
2431
|
-
let document;
|
|
2432
|
-
let variableNames;
|
|
2433
|
-
let fields;
|
|
2434
|
-
let fragmentUsages;
|
|
2435
|
-
if (params.mode === "prebuilt") {
|
|
2436
|
-
document = params.prebuiltDocument;
|
|
2437
|
-
variableNames = params.prebuiltVariableNames ?? Object.keys(variables);
|
|
2438
|
-
fields = {};
|
|
2439
|
-
fragmentUsages = [];
|
|
2440
|
-
} else {
|
|
2441
|
-
const { fieldsFactory } = params;
|
|
2442
|
-
const f = createFieldFactories(schema, operationTypeName);
|
|
2443
|
-
const collected = withFragmentUsageCollection(() => fieldsFactory({
|
|
2444
|
-
f,
|
|
2445
|
-
$
|
|
2446
|
-
}));
|
|
2447
|
-
fields = collected.result;
|
|
2448
|
-
fragmentUsages = collected.usages;
|
|
2449
|
-
document = buildDocument({
|
|
2450
|
-
operationName,
|
|
2451
|
-
operationType,
|
|
2452
|
-
operationTypeName,
|
|
2453
|
-
variables,
|
|
2454
|
-
fields,
|
|
2455
|
-
schema
|
|
2456
|
-
});
|
|
2457
|
-
variableNames = Object.keys(variables);
|
|
2458
|
-
}
|
|
2459
|
-
if (!fragmentUsages.some((u) => u.metadataBuilder) && !metadataBuilder && !adapterTransformDocument && !operationTransformDocument) return {
|
|
2460
|
-
operationType,
|
|
2461
|
-
operationName,
|
|
2462
|
-
schemaLabel: schema.label,
|
|
2463
|
-
variableNames,
|
|
2464
|
-
documentSource: () => fields,
|
|
2465
|
-
document,
|
|
2466
|
-
metadata: void 0
|
|
2467
|
-
};
|
|
2468
|
-
const aggregateFragmentMetadata = (resolvedFragmentMetadata) => {
|
|
2469
|
-
const fragmentMetaInfos = fragmentUsages.map((usage, index) => ({
|
|
2470
|
-
metadata: resolvedFragmentMetadata[index],
|
|
2471
|
-
fieldPath: usage.path
|
|
2472
|
-
}));
|
|
2473
|
-
return adapter.aggregateFragmentMetadata(fragmentMetaInfos);
|
|
2474
|
-
};
|
|
2475
|
-
const fragmentMetadataResults = fragmentUsages.map((usage) => usage.metadataBuilder ? usage.metadataBuilder() : void 0);
|
|
2476
|
-
const hasAsyncFragmentMetadata = fragmentMetadataResults.some((r) => isPromiseLike(r));
|
|
2477
|
-
const buildOperationMetadata = (aggregatedFragmentMetadata) => {
|
|
2478
|
-
const schemaLevel = adapter.schemaLevel;
|
|
2479
|
-
return metadataBuilder?.({
|
|
2480
|
-
$,
|
|
2481
|
-
document,
|
|
2482
|
-
fragmentMetadata: aggregatedFragmentMetadata,
|
|
2483
|
-
schemaLevel
|
|
2484
|
-
});
|
|
2485
|
-
};
|
|
2486
|
-
const makeCreateArtifact = (aggregated$1) => {
|
|
2487
|
-
return ({ metadata }) => {
|
|
2488
|
-
let finalDocument = operationTransformDocument ? operationTransformDocument({
|
|
2489
|
-
document,
|
|
2490
|
-
metadata
|
|
2491
|
-
}) : document;
|
|
2492
|
-
if (adapterTransformDocument) finalDocument = adapterTransformDocument({
|
|
2493
|
-
document: finalDocument,
|
|
2494
|
-
operationName,
|
|
2495
|
-
operationType,
|
|
2496
|
-
variableNames,
|
|
2497
|
-
schemaLevel: adapter.schemaLevel,
|
|
2498
|
-
fragmentMetadata: aggregated$1
|
|
2499
|
-
});
|
|
2500
|
-
return {
|
|
2501
|
-
operationType,
|
|
2502
|
-
operationName,
|
|
2503
|
-
schemaLabel: schema.label,
|
|
2504
|
-
variableNames,
|
|
2505
|
-
documentSource: () => fields,
|
|
2506
|
-
document: finalDocument,
|
|
2507
|
-
metadata
|
|
2508
|
-
};
|
|
2509
|
-
};
|
|
2510
|
-
};
|
|
2511
|
-
if (hasAsyncFragmentMetadata) return Promise.all(fragmentMetadataResults).then(async (resolvedFragmentMetadata) => {
|
|
2512
|
-
const aggregated$1 = aggregateFragmentMetadata(resolvedFragmentMetadata);
|
|
2513
|
-
const operationMetadata = await buildOperationMetadata(aggregated$1);
|
|
2514
|
-
return makeCreateArtifact(aggregated$1)({ metadata: operationMetadata });
|
|
2515
|
-
});
|
|
2516
|
-
const aggregated = aggregateFragmentMetadata(fragmentMetadataResults);
|
|
2517
|
-
const createArtifact = makeCreateArtifact(aggregated);
|
|
2518
|
-
const operationMetadataResult = buildOperationMetadata(aggregated);
|
|
2519
|
-
if (isPromiseLike(operationMetadataResult)) return operationMetadataResult.then((metadata) => createArtifact({ metadata }));
|
|
2520
|
-
return createArtifact({ metadata: operationMetadataResult });
|
|
2521
|
-
};
|
|
2522
|
-
/**
|
|
2523
|
-
* Wraps a buildOperationArtifact call into an Operation.create() invocation,
|
|
2524
|
-
* handling both sync and async artifact results.
|
|
2525
|
-
*
|
|
2526
|
-
* @param artifactFactory - Factory that produces the artifact (may return Promise for async metadata)
|
|
2527
|
-
* @param overrideDocumentSource - When true, overrides documentSource to return empty object.
|
|
2528
|
-
* Required for pre-built document mode where fields = {} and the real documentSource is meaningless.
|
|
2529
|
-
* Must be false for fieldsFactory mode to preserve real field selections.
|
|
2530
|
-
*
|
|
2531
|
-
* @internal Used by extend.ts and operation-tagged-template.ts
|
|
2532
|
-
*/
|
|
2533
|
-
const wrapArtifactAsOperation = (artifactFactory, overrideDocumentSource) => {
|
|
2534
|
-
return Operation.create((() => {
|
|
2535
|
-
const artifact = artifactFactory();
|
|
2536
|
-
if (overrideDocumentSource) {
|
|
2537
|
-
if (isPromiseLike(artifact)) return artifact.then((a) => ({
|
|
2538
|
-
...a,
|
|
2539
|
-
documentSource: () => ({})
|
|
2540
|
-
}));
|
|
2541
|
-
return {
|
|
2542
|
-
...artifact,
|
|
2543
|
-
documentSource: () => ({})
|
|
2544
|
-
};
|
|
2545
|
-
}
|
|
2546
|
-
if (isPromiseLike(artifact)) return artifact;
|
|
2547
|
-
return artifact;
|
|
2548
|
-
}));
|
|
2549
|
-
};
|
|
2550
|
-
|
|
2551
|
-
//#endregion
|
|
2552
|
-
//#region packages/core/src/composer/extend.ts
|
|
2553
|
-
/**
|
|
2554
|
-
* Extend composer factory for creating Operations from compat specs.
|
|
2555
|
-
* @module
|
|
2556
|
-
*/
|
|
2557
|
-
/**
|
|
2558
|
-
* Creates a factory for extending compat specs into full operations.
|
|
2559
|
-
*
|
|
2560
|
-
* The extend function takes a compat spec (created by `query.compat()`) and
|
|
2561
|
-
* optional metadata/transformDocument options, then creates a full Operation.
|
|
2562
|
-
*
|
|
2563
|
-
* @param schema - The GraphQL schema definition
|
|
2564
|
-
* @param adapter - Optional metadata adapter for custom metadata handling
|
|
2565
|
-
* @param transformDocument - Optional document transformer
|
|
2566
|
-
* @returns Extend composer function
|
|
2567
|
-
*
|
|
2568
|
-
* @internal Used by `createGqlElementComposer`
|
|
2569
|
-
*/
|
|
2570
|
-
const createExtendComposer = (schema, adapter, transformDocument) => {
|
|
2571
|
-
const resolvedAdapter = adapter ?? defaultMetadataAdapter;
|
|
2572
|
-
return (compat, options) => {
|
|
2573
|
-
const spec = compat.value;
|
|
2574
|
-
if (isTemplateCompatSpec(spec)) return buildOperationFromTemplateSpec(schema, spec, resolvedAdapter, options, transformDocument);
|
|
2575
|
-
const { operationType, operationName, variables, fieldsBuilder } = spec;
|
|
2576
|
-
const operationTypeName = schema.operations[operationType];
|
|
2577
|
-
return Operation.create((() => buildOperationArtifact({
|
|
2578
|
-
mode: "fieldsFactory",
|
|
2579
|
-
schema,
|
|
2580
|
-
operationType,
|
|
2581
|
-
operationTypeName,
|
|
2582
|
-
operationName,
|
|
2583
|
-
variables,
|
|
2584
|
-
fieldsFactory: fieldsBuilder,
|
|
2585
|
-
adapter: resolvedAdapter,
|
|
2586
|
-
metadata: options?.metadata,
|
|
2587
|
-
transformDocument: options?.transformDocument,
|
|
2588
|
-
adapterTransformDocument: transformDocument
|
|
2589
|
-
})));
|
|
2590
|
-
};
|
|
2591
|
-
};
|
|
2592
|
-
/**
|
|
2593
|
-
* Builds an Operation from a TemplateCompatSpec by parsing the raw GraphQL source.
|
|
2594
|
-
* Delegates to buildOperationArtifact with pre-built document mode.
|
|
2595
|
-
*/
|
|
2596
|
-
const buildOperationFromTemplateSpec = (schema, spec, adapter, options, adapterTransformDocument) => {
|
|
2597
|
-
const { operationType, operationName, graphqlSource } = spec;
|
|
2598
|
-
const document = (0, graphql.parse)(graphqlSource);
|
|
2599
|
-
const opDef = document.definitions.find((d) => d.kind === graphql.Kind.OPERATION_DEFINITION);
|
|
2600
|
-
if (!opDef) throw new Error("No operation definition found in compat template spec");
|
|
2601
|
-
const schemaIndex = createSchemaIndexFromSchema(spec.schema);
|
|
2602
|
-
const varSpecifiers = buildVarSpecifiers(opDef.variableDefinitions ?? [], schemaIndex);
|
|
2603
|
-
const operationTypeName = schema.operations[operationType];
|
|
2604
|
-
return wrapArtifactAsOperation(() => buildOperationArtifact({
|
|
2605
|
-
mode: "prebuilt",
|
|
2606
|
-
schema,
|
|
2607
|
-
operationType,
|
|
2608
|
-
operationTypeName,
|
|
2609
|
-
operationName,
|
|
2610
|
-
variables: varSpecifiers,
|
|
2611
|
-
prebuiltDocument: document,
|
|
2612
|
-
prebuiltVariableNames: Object.keys(varSpecifiers),
|
|
2613
|
-
adapter,
|
|
2614
|
-
metadata: options?.metadata,
|
|
2615
|
-
transformDocument: options?.transformDocument,
|
|
2616
|
-
adapterTransformDocument
|
|
2617
|
-
}), true);
|
|
2618
|
-
};
|
|
2619
|
-
|
|
2620
2389
|
//#endregion
|
|
2621
2390
|
//#region packages/core/src/composer/merge-variable-definitions.ts
|
|
2622
2391
|
/**
|
|
@@ -2641,31 +2410,180 @@ function mergeVariableDefinitions(parentVars, interpolationMap) {
|
|
|
2641
2410
|
}
|
|
2642
2411
|
|
|
2643
2412
|
//#endregion
|
|
2644
|
-
//#region packages/core/src/composer/
|
|
2413
|
+
//#region packages/core/src/composer/var-ref-tools.ts
|
|
2645
2414
|
/**
|
|
2646
|
-
*
|
|
2647
|
-
*
|
|
2648
|
-
*
|
|
2415
|
+
* Recursively checks if a NestedValue contains any VarRef.
|
|
2416
|
+
*
|
|
2417
|
+
* Used by getVarRefValue to determine if it's safe to return as ConstValue.
|
|
2418
|
+
* @internal
|
|
2649
2419
|
*/
|
|
2420
|
+
const hasVarRefInside = (value) => {
|
|
2421
|
+
if (value instanceof VarRef) return true;
|
|
2422
|
+
if (Array.isArray(value)) return value.some(hasVarRefInside);
|
|
2423
|
+
if (typeof value === "object" && value !== null) return Object.values(value).some(hasVarRefInside);
|
|
2424
|
+
return false;
|
|
2425
|
+
};
|
|
2650
2426
|
/**
|
|
2651
|
-
*
|
|
2652
|
-
*
|
|
2427
|
+
* Get the variable name from a VarRef.
|
|
2428
|
+
* Throws if the VarRef contains a nested-value instead of a variable reference.
|
|
2653
2429
|
*/
|
|
2654
|
-
|
|
2655
|
-
const
|
|
2656
|
-
if (
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
if (closeIndex === -1) return null;
|
|
2660
|
-
if (rawSource.slice(closeIndex + 1).trimStart().startsWith("on")) return rawSource.slice(openIndex + 1, closeIndex);
|
|
2661
|
-
return null;
|
|
2662
|
-
}
|
|
2430
|
+
const getVarRefName = (varRef) => {
|
|
2431
|
+
const inner = VarRef.getInner(varRef);
|
|
2432
|
+
if (inner.type !== "variable") throw new Error("Expected variable reference, got nested-value");
|
|
2433
|
+
return inner.name;
|
|
2434
|
+
};
|
|
2663
2435
|
/**
|
|
2664
|
-
*
|
|
2665
|
-
*
|
|
2436
|
+
* Get the const value from a VarRef.
|
|
2437
|
+
* Throws if the VarRef contains a variable reference instead of a nested-value,
|
|
2438
|
+
* or if the nested-value contains any VarRef inside.
|
|
2666
2439
|
*/
|
|
2667
|
-
|
|
2668
|
-
const
|
|
2440
|
+
const getVarRefValue = (varRef) => {
|
|
2441
|
+
const inner = VarRef.getInner(varRef);
|
|
2442
|
+
if (inner.type !== "nested-value") throw new Error("Expected nested-value, got variable reference");
|
|
2443
|
+
if (hasVarRefInside(inner.value)) throw new Error("Cannot get const value: nested-value contains VarRef");
|
|
2444
|
+
return inner.value;
|
|
2445
|
+
};
|
|
2446
|
+
const SelectableProxyInnerRegistry = /* @__PURE__ */ new WeakMap();
|
|
2447
|
+
const getSelectableProxyInner = (proxy) => {
|
|
2448
|
+
const inner = SelectableProxyInnerRegistry.get(proxy);
|
|
2449
|
+
if (!inner) throw new Error(`Proxy inner not found`);
|
|
2450
|
+
return inner;
|
|
2451
|
+
};
|
|
2452
|
+
const createSelectableProxy = (current) => {
|
|
2453
|
+
const proxy = new Proxy(Object.create(null), { get(_, property) {
|
|
2454
|
+
if (typeof property === "symbol") throw new Error(`Prohibited property access: ${String(property)}`);
|
|
2455
|
+
const nextSegments = [...current.segments, property];
|
|
2456
|
+
if (current.varInner.type === "virtual") return createSelectableProxy({
|
|
2457
|
+
varInner: current.varInner,
|
|
2458
|
+
segments: nextSegments
|
|
2459
|
+
});
|
|
2460
|
+
if (current.varInner.type === "variable") return createSelectableProxy({
|
|
2461
|
+
varInner: {
|
|
2462
|
+
type: "virtual",
|
|
2463
|
+
varName: current.varInner.name,
|
|
2464
|
+
varSegments: nextSegments
|
|
2465
|
+
},
|
|
2466
|
+
segments: nextSegments
|
|
2467
|
+
});
|
|
2468
|
+
if (typeof current.varInner.value === "object" && current.varInner.value !== null) {
|
|
2469
|
+
const value = current.varInner.value[property];
|
|
2470
|
+
return createSelectableProxy({
|
|
2471
|
+
varInner: value instanceof VarRef ? VarRef.getInner(value) : {
|
|
2472
|
+
type: "nested-value",
|
|
2473
|
+
value
|
|
2474
|
+
},
|
|
2475
|
+
segments: nextSegments
|
|
2476
|
+
});
|
|
2477
|
+
}
|
|
2478
|
+
throw new Error(`Cannot access children of primitive value at path [${current.segments.join(".")}]`);
|
|
2479
|
+
} });
|
|
2480
|
+
SelectableProxyInnerRegistry.set(proxy, current);
|
|
2481
|
+
return proxy;
|
|
2482
|
+
};
|
|
2483
|
+
/**
|
|
2484
|
+
* Get the variable name from a VarRef at a specific path.
|
|
2485
|
+
*
|
|
2486
|
+
* @param varRef - The VarRef containing a nested-value
|
|
2487
|
+
* @param selector - Path builder function, e.g., p => p.user.age
|
|
2488
|
+
* @returns The variable name at the specified path
|
|
2489
|
+
* @throws If path doesn't lead to a VarRef with type "variable"
|
|
2490
|
+
*
|
|
2491
|
+
* @example
|
|
2492
|
+
* const ref = createVarRefFromNestedValue({
|
|
2493
|
+
* user: { age: someVariableRef }
|
|
2494
|
+
* });
|
|
2495
|
+
* getNameAt(ref, p => p.user.age); // returns the variable name
|
|
2496
|
+
*/
|
|
2497
|
+
const getNameAt = (varRef, selector) => {
|
|
2498
|
+
const inner = getSelectableProxyInner(selector(createSelectableProxy({
|
|
2499
|
+
varInner: VarRef.getInner(varRef),
|
|
2500
|
+
segments: []
|
|
2501
|
+
})));
|
|
2502
|
+
if (inner.varInner.type === "virtual") throw new Error(`Value at path [${inner.segments.join(".")}] is inside a variable`);
|
|
2503
|
+
if (inner.varInner.type !== "variable") throw new Error(`Value at path [${inner.segments.join(".")}] is not a variable`);
|
|
2504
|
+
return inner.varInner.name;
|
|
2505
|
+
};
|
|
2506
|
+
/**
|
|
2507
|
+
* Get the const value from a nested-value VarRef at a specific path.
|
|
2508
|
+
*
|
|
2509
|
+
* @param varRef - The VarRef containing a nested-value
|
|
2510
|
+
* @param pathFn - Path builder function, e.g., p => p.user.name
|
|
2511
|
+
* @returns The const value at the specified path
|
|
2512
|
+
* @throws If path leads to a VarRef or if value contains VarRef inside
|
|
2513
|
+
*
|
|
2514
|
+
* @example
|
|
2515
|
+
* const ref = createVarRefFromNestedValue({
|
|
2516
|
+
* user: { name: "Alice", age: someVariableRef }
|
|
2517
|
+
* });
|
|
2518
|
+
* getValueAt(ref, p => p.user.name); // returns "Alice"
|
|
2519
|
+
*/
|
|
2520
|
+
const getValueAt = (varRef, selector) => {
|
|
2521
|
+
const inner = getSelectableProxyInner(selector(createSelectableProxy({
|
|
2522
|
+
varInner: VarRef.getInner(varRef),
|
|
2523
|
+
segments: []
|
|
2524
|
+
})));
|
|
2525
|
+
if (inner.varInner.type === "virtual") throw new Error(`Value at path [${inner.segments.join(".")}] is inside a variable`);
|
|
2526
|
+
if (inner.varInner.type !== "nested-value") throw new Error(`Value at path [${inner.segments.join(".")}] is not a nested-value`);
|
|
2527
|
+
if (hasVarRefInside(inner.varInner.value)) throw new Error(`Value at path [${inner.segments.join(".")}] contains nested VarRef`);
|
|
2528
|
+
return inner.varInner.value;
|
|
2529
|
+
};
|
|
2530
|
+
/**
|
|
2531
|
+
* Gets the full path to a variable within a nested structure.
|
|
2532
|
+
*
|
|
2533
|
+
* Returns path segments starting with `$variableName` followed by
|
|
2534
|
+
* property accesses within that variable's value.
|
|
2535
|
+
*
|
|
2536
|
+
* @example
|
|
2537
|
+
* ```typescript
|
|
2538
|
+
* getVariablePath($.filter, p => p.user.id)
|
|
2539
|
+
* // Returns: ["$filter", "user", "id"]
|
|
2540
|
+
* ```
|
|
2541
|
+
*/
|
|
2542
|
+
const getVariablePath = (varRef, selector) => {
|
|
2543
|
+
const inner = getSelectableProxyInner(selector(createSelectableProxy({
|
|
2544
|
+
varInner: VarRef.getInner(varRef),
|
|
2545
|
+
segments: []
|
|
2546
|
+
})));
|
|
2547
|
+
if (inner.varInner.type === "virtual") return [`$${inner.varInner.varName}`, ...inner.segments.slice(inner.varInner.varSegments.length)];
|
|
2548
|
+
if (inner.varInner.type === "variable") return [`$${inner.varInner.name}`];
|
|
2549
|
+
throw new Error(`Value at path [${inner.segments.join(".")}] is not a variable or inside a variable`);
|
|
2550
|
+
};
|
|
2551
|
+
/** Pre-built tools object passed as `$var` in metadata builder callbacks. */
|
|
2552
|
+
const varRefTools = Object.freeze({
|
|
2553
|
+
getName: getVarRefName,
|
|
2554
|
+
getValue: getVarRefValue,
|
|
2555
|
+
getNameAt,
|
|
2556
|
+
getValueAt,
|
|
2557
|
+
getPath: getVariablePath,
|
|
2558
|
+
hasVarRefInside
|
|
2559
|
+
});
|
|
2560
|
+
|
|
2561
|
+
//#endregion
|
|
2562
|
+
//#region packages/core/src/composer/fragment-tagged-template.ts
|
|
2563
|
+
/**
|
|
2564
|
+
* Fragment tagged template function for creating GraphQL fragments from template literals.
|
|
2565
|
+
* Supports Fragment Arguments RFC syntax for parameterized fragments.
|
|
2566
|
+
* @module
|
|
2567
|
+
*/
|
|
2568
|
+
/**
|
|
2569
|
+
* Extract the argument list text from a fragment definition with Fragment Arguments syntax.
|
|
2570
|
+
* Returns the text between parens in `fragment Name(...) on Type`, or null if no args.
|
|
2571
|
+
*/
|
|
2572
|
+
function extractFragmentArgText(rawSource) {
|
|
2573
|
+
const match = /\bfragment\s+\w+\s*\(/.exec(rawSource);
|
|
2574
|
+
if (!match) return null;
|
|
2575
|
+
const openIndex = match.index + match[0].length - 1;
|
|
2576
|
+
const closeIndex = findMatchingParen(rawSource, openIndex);
|
|
2577
|
+
if (closeIndex === -1) return null;
|
|
2578
|
+
if (rawSource.slice(closeIndex + 1).trimStart().startsWith("on")) return rawSource.slice(openIndex + 1, closeIndex);
|
|
2579
|
+
return null;
|
|
2580
|
+
}
|
|
2581
|
+
/**
|
|
2582
|
+
* Extract variable definitions from Fragment Arguments syntax.
|
|
2583
|
+
* Wraps the argument list in a synthetic query to parse with graphql-js.
|
|
2584
|
+
*/
|
|
2585
|
+
function extractFragmentVariables(rawSource, schemaIndex) {
|
|
2586
|
+
const argText = extractFragmentArgText(rawSource);
|
|
2669
2587
|
if (!argText?.trim()) return {};
|
|
2670
2588
|
const syntheticQuery = `query _Synthetic(${argText}) { __typename }`;
|
|
2671
2589
|
let syntheticDoc;
|
|
@@ -2680,6 +2598,30 @@ function extractFragmentVariables(rawSource, schemaIndex) {
|
|
|
2680
2598
|
return buildVarSpecifiers(opDef.variableDefinitions ?? [], schemaIndex);
|
|
2681
2599
|
}
|
|
2682
2600
|
/**
|
|
2601
|
+
* Filters out named fragment spreads that cannot be resolved without an interpolation map.
|
|
2602
|
+
* Used when building fields from compat templates or zero-interpolation tagged templates
|
|
2603
|
+
* that may contain standard GraphQL `...FragmentName` spreads.
|
|
2604
|
+
*/
|
|
2605
|
+
function filterUnresolvedFragmentSpreads(selectionSet, interpolationMap) {
|
|
2606
|
+
return {
|
|
2607
|
+
...selectionSet,
|
|
2608
|
+
selections: selectionSet.selections.filter((sel) => {
|
|
2609
|
+
if (sel.kind !== graphql.Kind.FRAGMENT_SPREAD) return true;
|
|
2610
|
+
return interpolationMap?.has(sel.name.value) ?? false;
|
|
2611
|
+
}).map((sel) => {
|
|
2612
|
+
if (sel.kind === graphql.Kind.FIELD && sel.selectionSet) return {
|
|
2613
|
+
...sel,
|
|
2614
|
+
selectionSet: filterUnresolvedFragmentSpreads(sel.selectionSet, interpolationMap)
|
|
2615
|
+
};
|
|
2616
|
+
if (sel.kind === graphql.Kind.INLINE_FRAGMENT && sel.selectionSet) return {
|
|
2617
|
+
...sel,
|
|
2618
|
+
selectionSet: filterUnresolvedFragmentSpreads(sel.selectionSet, interpolationMap)
|
|
2619
|
+
};
|
|
2620
|
+
return sel;
|
|
2621
|
+
})
|
|
2622
|
+
};
|
|
2623
|
+
}
|
|
2624
|
+
/**
|
|
2683
2625
|
* Builds field selections from a GraphQL AST SelectionSet by driving field factories.
|
|
2684
2626
|
* Converts parsed AST selections into the AnyFieldsExtended format that the document builder expects.
|
|
2685
2627
|
* Also used by typegen for static field extraction from tagged templates.
|
|
@@ -2694,27 +2636,33 @@ function buildFieldsFromSelectionSet(selectionSet, schema, typeName, varAssignme
|
|
|
2694
2636
|
result[alias] = true;
|
|
2695
2637
|
continue;
|
|
2696
2638
|
}
|
|
2697
|
-
const factory = f[fieldName];
|
|
2698
|
-
if (!factory) throw new Error(`Field "${fieldName}" is not defined on type "${typeName}"`);
|
|
2699
2639
|
const args = buildArgsFromASTArguments(selection.arguments ?? [], varAssignments);
|
|
2700
|
-
const
|
|
2640
|
+
const directives = buildDirectivesFromAST(selection.directives, varAssignments);
|
|
2641
|
+
const hasAlias = alias !== fieldName;
|
|
2642
|
+
const extras = hasAlias || directives.length > 0 ? {
|
|
2643
|
+
...hasAlias ? { alias } : {},
|
|
2644
|
+
...directives.length > 0 ? { directives } : {}
|
|
2645
|
+
} : void 0;
|
|
2701
2646
|
if (selection.selectionSet) {
|
|
2702
|
-
const curried =
|
|
2647
|
+
const curried = f(fieldName, args, extras);
|
|
2703
2648
|
if (typeof curried === "function") {
|
|
2704
|
-
const
|
|
2705
|
-
const parsedType = parseOutputField(
|
|
2649
|
+
const fieldDefRaw = schema.object[typeName]?.fields[fieldName];
|
|
2650
|
+
const parsedType = parseOutputField(typeof fieldDefRaw === "string" ? fieldDefRaw : fieldDefRaw?.spec);
|
|
2706
2651
|
if (parsedType.kind === "union") {
|
|
2707
2652
|
const unionInput = {};
|
|
2708
2653
|
let hasTypename = false;
|
|
2709
2654
|
const unsupportedSelections = [];
|
|
2710
2655
|
for (const sel of selection.selectionSet.selections) if (sel.kind === graphql.Kind.INLINE_FRAGMENT) {
|
|
2711
|
-
if (sel.directives?.length) throw new Error("Directives on inline fragments are not supported in tagged templates");
|
|
2712
2656
|
if (!sel.typeCondition) throw new Error("Inline fragments without type conditions are not supported in tagged templates");
|
|
2713
2657
|
const memberName = sel.typeCondition.name.value;
|
|
2714
|
-
|
|
2658
|
+
const unionDef = schema.union[parsedType.name];
|
|
2659
|
+
if (!unionDef) throw new Error(`Union "${parsedType.name}" is not defined in schema`);
|
|
2660
|
+
if (!(memberName in unionDef.types)) throw new Error(`Type "${memberName}" is not a member of union "${parsedType.name}" in tagged template inline fragment`);
|
|
2715
2661
|
if (memberName in unionInput) throw new Error(`Duplicate inline fragment for union member "${memberName}" in tagged template. Merge selections into a single "... on ${memberName} { ... }" block.`);
|
|
2716
|
-
|
|
2717
|
-
|
|
2662
|
+
unionInput[memberName] = {
|
|
2663
|
+
fields: buildFieldsFromSelectionSet(sel.selectionSet, schema, memberName, varAssignments, interpolationMap),
|
|
2664
|
+
directives: buildDirectivesFromAST(sel.directives, varAssignments, "INLINE_FRAGMENT")
|
|
2665
|
+
};
|
|
2718
2666
|
} else if (sel.kind === graphql.Kind.FIELD && sel.name.value === "__typename") {
|
|
2719
2667
|
if (sel.alias) throw new Error("Aliases on __typename in union selections are not supported in tagged templates. Use \"__typename\" without an alias.");
|
|
2720
2668
|
if (sel.directives?.length) throw new Error(`Directives on __typename in union selections are not supported in tagged templates.`);
|
|
@@ -2741,7 +2689,7 @@ function buildFieldsFromSelectionSet(selectionSet, schema, typeName, varAssignme
|
|
|
2741
2689
|
}
|
|
2742
2690
|
} else Object.assign(result, curried);
|
|
2743
2691
|
} else {
|
|
2744
|
-
const fieldResult =
|
|
2692
|
+
const fieldResult = f(fieldName, args, extras);
|
|
2745
2693
|
if (typeof fieldResult === "function") {
|
|
2746
2694
|
const emptyResult = fieldResult(() => ({}));
|
|
2747
2695
|
Object.assign(result, emptyResult);
|
|
@@ -2764,6 +2712,18 @@ function buildFieldsFromSelectionSet(selectionSet, schema, typeName, varAssignme
|
|
|
2764
2712
|
return result;
|
|
2765
2713
|
}
|
|
2766
2714
|
/**
|
|
2715
|
+
* Convert GraphQL AST DirectiveNodes to DirectiveRef instances.
|
|
2716
|
+
* Reuses buildArgsFromASTArguments for directive argument conversion.
|
|
2717
|
+
*/
|
|
2718
|
+
function buildDirectivesFromAST(directives, varAssignments, location = "FIELD") {
|
|
2719
|
+
if (!directives || directives.length === 0) return [];
|
|
2720
|
+
return directives.map((d) => new DirectiveRef({
|
|
2721
|
+
name: d.name.value,
|
|
2722
|
+
arguments: buildArgsFromASTArguments(d.arguments ?? [], varAssignments),
|
|
2723
|
+
locations: [location]
|
|
2724
|
+
}));
|
|
2725
|
+
}
|
|
2726
|
+
/**
|
|
2767
2727
|
* Build a simple args object from GraphQL AST argument nodes.
|
|
2768
2728
|
* Extracts literal values from the AST for passing to field factories.
|
|
2769
2729
|
*/
|
|
@@ -2867,7 +2827,10 @@ function createFragmentTaggedTemplate(schema) {
|
|
|
2867
2827
|
let metadataBuilder = null;
|
|
2868
2828
|
if (options?.metadata !== void 0) {
|
|
2869
2829
|
const metadata = options.metadata;
|
|
2870
|
-
if (typeof metadata === "function") metadataBuilder = () => metadata({
|
|
2830
|
+
if (typeof metadata === "function") metadataBuilder = () => metadata({
|
|
2831
|
+
$,
|
|
2832
|
+
$var: varRefTools
|
|
2833
|
+
});
|
|
2871
2834
|
else metadataBuilder = () => metadata;
|
|
2872
2835
|
}
|
|
2873
2836
|
recordFragmentUsage({
|
|
@@ -2883,54 +2846,179 @@ function createFragmentTaggedTemplate(schema) {
|
|
|
2883
2846
|
}
|
|
2884
2847
|
|
|
2885
2848
|
//#endregion
|
|
2886
|
-
//#region packages/core/src/composer/operation.ts
|
|
2849
|
+
//#region packages/core/src/composer/operation-core.ts
|
|
2887
2850
|
/**
|
|
2888
|
-
*
|
|
2889
|
-
*
|
|
2851
|
+
* Builds an operation artifact from the provided parameters.
|
|
2852
|
+
*
|
|
2853
|
+
* This function contains the core logic for:
|
|
2854
|
+
* - Creating variable refs and field factories
|
|
2855
|
+
* - Evaluating fields with fragment usage tracking
|
|
2856
|
+
* - Building the document
|
|
2857
|
+
* - Handling metadata (sync and async)
|
|
2858
|
+
* - Applying document transformations
|
|
2859
|
+
*
|
|
2860
|
+
* @param params - Operation building parameters
|
|
2861
|
+
* @returns Operation artifact or Promise of artifact (if async metadata)
|
|
2862
|
+
*
|
|
2863
|
+
* @internal Used by extend.ts and operation-tagged-template.ts
|
|
2890
2864
|
*/
|
|
2865
|
+
const buildOperationArtifact = (params) => {
|
|
2866
|
+
const { schema, operationType, operationTypeName, operationName, variables, variableDefinitionNodes, adapter, metadata: metadataBuilder, transformDocument: operationTransformDocument, adapterTransformDocument } = params;
|
|
2867
|
+
const $ = createVarRefs(variables);
|
|
2868
|
+
const { fieldsFactory } = params;
|
|
2869
|
+
const f = createFieldFactories(schema, operationTypeName);
|
|
2870
|
+
const collected = withFragmentUsageCollection(() => fieldsFactory({
|
|
2871
|
+
f,
|
|
2872
|
+
$
|
|
2873
|
+
}));
|
|
2874
|
+
const fields = collected.result;
|
|
2875
|
+
const fragmentUsages = collected.usages;
|
|
2876
|
+
const document = buildDocument({
|
|
2877
|
+
operationName,
|
|
2878
|
+
operationType,
|
|
2879
|
+
operationTypeName,
|
|
2880
|
+
variableDefinitionNodes,
|
|
2881
|
+
variables,
|
|
2882
|
+
fields,
|
|
2883
|
+
schema
|
|
2884
|
+
});
|
|
2885
|
+
const variableNames = Object.keys(variables);
|
|
2886
|
+
if (!fragmentUsages.some((u) => u.metadataBuilder) && !metadataBuilder && !adapterTransformDocument && !operationTransformDocument) return {
|
|
2887
|
+
operationType,
|
|
2888
|
+
operationName,
|
|
2889
|
+
schemaLabel: schema.label,
|
|
2890
|
+
variableNames,
|
|
2891
|
+
documentSource: () => fields,
|
|
2892
|
+
document,
|
|
2893
|
+
metadata: void 0
|
|
2894
|
+
};
|
|
2895
|
+
const aggregateFragmentMetadata = (resolvedFragmentMetadata) => {
|
|
2896
|
+
const fragmentMetaInfos = fragmentUsages.map((usage, index) => ({
|
|
2897
|
+
metadata: resolvedFragmentMetadata[index],
|
|
2898
|
+
fieldPath: usage.path
|
|
2899
|
+
}));
|
|
2900
|
+
return adapter.aggregateFragmentMetadata(fragmentMetaInfos);
|
|
2901
|
+
};
|
|
2902
|
+
const fragmentMetadataResults = fragmentUsages.map((usage) => usage.metadataBuilder ? usage.metadataBuilder() : void 0);
|
|
2903
|
+
const hasAsyncFragmentMetadata = fragmentMetadataResults.some((r) => isPromiseLike(r));
|
|
2904
|
+
const buildOperationMetadata = (aggregatedFragmentMetadata) => {
|
|
2905
|
+
const schemaLevel = adapter.schemaLevel;
|
|
2906
|
+
return metadataBuilder?.({
|
|
2907
|
+
$,
|
|
2908
|
+
$var: varRefTools,
|
|
2909
|
+
document,
|
|
2910
|
+
fragmentMetadata: aggregatedFragmentMetadata,
|
|
2911
|
+
schemaLevel
|
|
2912
|
+
});
|
|
2913
|
+
};
|
|
2914
|
+
const makeCreateArtifact = (aggregated$1) => {
|
|
2915
|
+
return ({ metadata }) => {
|
|
2916
|
+
let finalDocument = operationTransformDocument ? operationTransformDocument({
|
|
2917
|
+
document,
|
|
2918
|
+
metadata
|
|
2919
|
+
}) : document;
|
|
2920
|
+
if (adapterTransformDocument) finalDocument = adapterTransformDocument({
|
|
2921
|
+
document: finalDocument,
|
|
2922
|
+
operationName,
|
|
2923
|
+
operationType,
|
|
2924
|
+
variableNames,
|
|
2925
|
+
schemaLevel: adapter.schemaLevel,
|
|
2926
|
+
fragmentMetadata: aggregated$1
|
|
2927
|
+
});
|
|
2928
|
+
return {
|
|
2929
|
+
operationType,
|
|
2930
|
+
operationName,
|
|
2931
|
+
schemaLabel: schema.label,
|
|
2932
|
+
variableNames,
|
|
2933
|
+
documentSource: () => fields,
|
|
2934
|
+
document: finalDocument,
|
|
2935
|
+
metadata
|
|
2936
|
+
};
|
|
2937
|
+
};
|
|
2938
|
+
};
|
|
2939
|
+
if (hasAsyncFragmentMetadata) return Promise.all(fragmentMetadataResults).then(async (resolvedFragmentMetadata) => {
|
|
2940
|
+
const aggregated$1 = aggregateFragmentMetadata(resolvedFragmentMetadata);
|
|
2941
|
+
const operationMetadata = await buildOperationMetadata(aggregated$1);
|
|
2942
|
+
return makeCreateArtifact(aggregated$1)({ metadata: operationMetadata });
|
|
2943
|
+
});
|
|
2944
|
+
const aggregated = aggregateFragmentMetadata(fragmentMetadataResults);
|
|
2945
|
+
const createArtifact = makeCreateArtifact(aggregated);
|
|
2946
|
+
const operationMetadataResult = buildOperationMetadata(aggregated);
|
|
2947
|
+
if (isPromiseLike(operationMetadataResult)) return operationMetadataResult.then((metadata) => createArtifact({ metadata }));
|
|
2948
|
+
return createArtifact({ metadata: operationMetadataResult });
|
|
2949
|
+
};
|
|
2891
2950
|
/**
|
|
2892
|
-
*
|
|
2951
|
+
* Wraps a buildOperationArtifact call into an Operation.create() invocation,
|
|
2952
|
+
* handling both sync and async artifact results.
|
|
2893
2953
|
*
|
|
2894
|
-
*
|
|
2895
|
-
* then define the operation with name, variables, and fields.
|
|
2954
|
+
* @param artifactFactory - Factory that produces the artifact (may return Promise for async metadata)
|
|
2896
2955
|
*
|
|
2897
|
-
*
|
|
2898
|
-
|
|
2956
|
+
* @internal Used by extend.ts and operation-tagged-template.ts
|
|
2957
|
+
*/
|
|
2958
|
+
const wrapArtifactAsOperation = (artifactFactory) => {
|
|
2959
|
+
return Operation.create(artifactFactory);
|
|
2960
|
+
};
|
|
2961
|
+
|
|
2962
|
+
//#endregion
|
|
2963
|
+
//#region packages/core/src/composer/extend.ts
|
|
2964
|
+
/**
|
|
2965
|
+
* Extend composer factory for creating Operations from TemplateCompatSpec.
|
|
2966
|
+
* @module
|
|
2967
|
+
*/
|
|
2968
|
+
/**
|
|
2969
|
+
* Creates a factory for extending compat specs into full operations.
|
|
2970
|
+
*
|
|
2971
|
+
* The extend function takes a TemplateCompatSpec (created by `query.compat("Name")\`...\``)
|
|
2972
|
+
* and optional metadata/transformDocument options, then creates a full Operation.
|
|
2899
2973
|
*
|
|
2900
2974
|
* @param schema - The GraphQL schema definition
|
|
2901
2975
|
* @param adapter - Optional metadata adapter for custom metadata handling
|
|
2902
|
-
* @param transformDocument - Optional document transformer
|
|
2903
|
-
* @returns
|
|
2976
|
+
* @param transformDocument - Optional document transformer
|
|
2977
|
+
* @returns Extend composer function
|
|
2904
2978
|
*
|
|
2905
2979
|
* @internal Used by `createGqlElementComposer`
|
|
2906
2980
|
*/
|
|
2907
|
-
const
|
|
2981
|
+
const createExtendComposer = (schema, adapter, transformDocument) => {
|
|
2908
2982
|
const resolvedAdapter = adapter ?? defaultMetadataAdapter;
|
|
2909
|
-
return (
|
|
2910
|
-
const
|
|
2911
|
-
|
|
2912
|
-
return (options) => {
|
|
2913
|
-
return Operation.create((() => buildOperationArtifact({
|
|
2914
|
-
mode: "fieldsFactory",
|
|
2915
|
-
schema,
|
|
2916
|
-
operationType,
|
|
2917
|
-
operationTypeName,
|
|
2918
|
-
operationName: options.name,
|
|
2919
|
-
variables: options.variables ?? {},
|
|
2920
|
-
fieldsFactory: options.fields,
|
|
2921
|
-
adapter: resolvedAdapter,
|
|
2922
|
-
metadata: options.metadata,
|
|
2923
|
-
transformDocument: options.transformDocument,
|
|
2924
|
-
adapterTransformDocument: transformDocument
|
|
2925
|
-
})));
|
|
2926
|
-
};
|
|
2983
|
+
return (compat, options) => {
|
|
2984
|
+
const spec = compat.value;
|
|
2985
|
+
return buildOperationFromTemplateSpec(schema, spec, resolvedAdapter, options, transformDocument);
|
|
2927
2986
|
};
|
|
2928
2987
|
};
|
|
2988
|
+
/**
|
|
2989
|
+
* Builds an Operation from a TemplateCompatSpec by parsing the raw GraphQL source.
|
|
2990
|
+
* Evaluates fields via buildFieldsFromSelectionSet for correct typegen output.
|
|
2991
|
+
*/
|
|
2992
|
+
const buildOperationFromTemplateSpec = (schema, spec, adapter, options, adapterTransformDocument) => {
|
|
2993
|
+
const { operationType, operationName, graphqlSource } = spec;
|
|
2994
|
+
const opDef = (0, graphql.parse)(graphqlSource).definitions.find((d) => d.kind === graphql.Kind.OPERATION_DEFINITION);
|
|
2995
|
+
if (!opDef) throw new Error("No operation definition found in compat template spec");
|
|
2996
|
+
const schemaIndex = createSchemaIndexFromSchema(spec.schema);
|
|
2997
|
+
const varSpecifiers = buildVarSpecifiers(opDef.variableDefinitions ?? [], schemaIndex);
|
|
2998
|
+
const operationTypeName = schema.operations[operationType];
|
|
2999
|
+
const filteredSelectionSet = filterUnresolvedFragmentSpreads(opDef.selectionSet);
|
|
3000
|
+
return wrapArtifactAsOperation(() => buildOperationArtifact({
|
|
3001
|
+
schema,
|
|
3002
|
+
operationType,
|
|
3003
|
+
operationTypeName,
|
|
3004
|
+
operationName,
|
|
3005
|
+
variables: varSpecifiers,
|
|
3006
|
+
variableDefinitionNodes: opDef.variableDefinitions ?? [],
|
|
3007
|
+
fieldsFactory: ({ $ }) => {
|
|
3008
|
+
return buildFieldsFromSelectionSet(filteredSelectionSet, schema, operationTypeName, $);
|
|
3009
|
+
},
|
|
3010
|
+
adapter,
|
|
3011
|
+
metadata: options?.metadata,
|
|
3012
|
+
transformDocument: options?.transformDocument,
|
|
3013
|
+
adapterTransformDocument
|
|
3014
|
+
}));
|
|
3015
|
+
};
|
|
2929
3016
|
|
|
2930
3017
|
//#endregion
|
|
2931
3018
|
//#region packages/core/src/composer/operation-tagged-template.ts
|
|
2932
3019
|
/**
|
|
2933
3020
|
* Operation tagged template function for creating GraphQL operations from template literals.
|
|
3021
|
+
* Also supports options object dispatch for callback builder path.
|
|
2934
3022
|
* @module
|
|
2935
3023
|
*/
|
|
2936
3024
|
/**
|
|
@@ -2944,9 +3032,9 @@ function buildSyntheticOperationSource(operationType, operationName, body) {
|
|
|
2944
3032
|
* Resolves a metadata option from OperationTemplateMetadataOptions into a MetadataBuilder
|
|
2945
3033
|
* compatible with buildOperationArtifact.
|
|
2946
3034
|
*
|
|
2947
|
-
* - `undefined`
|
|
2948
|
-
* - Raw value
|
|
2949
|
-
* - Callback
|
|
3035
|
+
* - `undefined` -> `undefined` (no metadata)
|
|
3036
|
+
* - Raw value -> `() => value` (static metadata)
|
|
3037
|
+
* - Callback -> forwarded directly (receives full pipeline context)
|
|
2950
3038
|
*/
|
|
2951
3039
|
const resolveMetadataOption = (metadataOption) => {
|
|
2952
3040
|
if (metadataOption === void 0) return void 0;
|
|
@@ -2954,8 +3042,11 @@ const resolveMetadataOption = (metadataOption) => {
|
|
|
2954
3042
|
return () => metadataOption;
|
|
2955
3043
|
};
|
|
2956
3044
|
/**
|
|
2957
|
-
* Creates a curried
|
|
2958
|
-
*
|
|
3045
|
+
* Creates a curried function for a specific operation type.
|
|
3046
|
+
* Supports both tagged template and options object dispatch.
|
|
3047
|
+
*
|
|
3048
|
+
* Tagged template: `query("name")\`($var: Type!) { fields }\`` returns TemplateResult<Operation>.
|
|
3049
|
+
* Options object: `query("name")({ variables, fields })` returns TemplateResult<Operation>.
|
|
2959
3050
|
*
|
|
2960
3051
|
* @param schema - The GraphQL schema definition
|
|
2961
3052
|
* @param operationType - The operation type (query, mutation, subscription)
|
|
@@ -2965,264 +3056,99 @@ const resolveMetadataOption = (metadataOption) => {
|
|
|
2965
3056
|
const createOperationTaggedTemplate = (schema, operationType, metadataAdapter, adapterTransformDocument) => {
|
|
2966
3057
|
const schemaIndex = createSchemaIndexFromSchema(schema);
|
|
2967
3058
|
return (operationName) => {
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
if (!(value instanceof Fragment) && typeof value !== "function") throw new Error(`Tagged templates only accept Fragment instances or callback functions as interpolated values. Received ${typeof value} at position ${i}.`);
|
|
2972
|
-
}
|
|
2973
|
-
let body = strings[0] ?? "";
|
|
2974
|
-
const interpolationMap = /* @__PURE__ */ new Map();
|
|
2975
|
-
for (let i = 0; i < values.length; i++) {
|
|
2976
|
-
const placeholderName = `__INTERPOLATION_${i}__`;
|
|
2977
|
-
interpolationMap.set(placeholderName, values[i]);
|
|
2978
|
-
body += placeholderName + (strings[i + 1] ?? "");
|
|
2979
|
-
}
|
|
2980
|
-
const source = buildSyntheticOperationSource(operationType, operationName, body);
|
|
2981
|
-
let document;
|
|
2982
|
-
try {
|
|
2983
|
-
document = (0, graphql.parse)(source);
|
|
2984
|
-
} catch (error) {
|
|
2985
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
2986
|
-
throw new Error(`GraphQL parse error in tagged template: ${message}`);
|
|
2987
|
-
}
|
|
2988
|
-
const opDefs = document.definitions.filter((def) => def.kind === graphql.Kind.OPERATION_DEFINITION);
|
|
2989
|
-
if (opDefs.length !== 1) throw new Error(`Internal error: expected exactly one operation definition in synthesized source`);
|
|
2990
|
-
const opNode = opDefs[0];
|
|
2991
|
-
if (opNode.kind !== graphql.Kind.OPERATION_DEFINITION) throw new Error("Unexpected definition kind");
|
|
2992
|
-
let varSpecifiers = buildVarSpecifiers(opNode.variableDefinitions ?? [], schemaIndex);
|
|
2993
|
-
varSpecifiers = mergeVariableDefinitions(varSpecifiers, interpolationMap);
|
|
2994
|
-
const operationTypeName = schema.operations[operationType];
|
|
2995
|
-
if (operationTypeName === null) throw new Error(`Operation type ${operationType} is not defined in schema roots`);
|
|
2996
|
-
const resolvedAdapter = metadataAdapter ?? defaultMetadataAdapter;
|
|
2997
|
-
return (options) => {
|
|
2998
|
-
const resolvedMetadata = resolveMetadataOption(options?.metadata);
|
|
2999
|
-
if (interpolationMap.size === 0) return wrapArtifactAsOperation(() => buildOperationArtifact({
|
|
3000
|
-
mode: "prebuilt",
|
|
3001
|
-
schema,
|
|
3002
|
-
operationType,
|
|
3003
|
-
operationTypeName,
|
|
3004
|
-
operationName,
|
|
3005
|
-
variables: varSpecifiers,
|
|
3006
|
-
prebuiltDocument: document,
|
|
3007
|
-
prebuiltVariableNames: Object.keys(varSpecifiers),
|
|
3008
|
-
adapter: resolvedAdapter,
|
|
3009
|
-
metadata: resolvedMetadata,
|
|
3010
|
-
adapterTransformDocument
|
|
3011
|
-
}), true);
|
|
3012
|
-
return wrapArtifactAsOperation(() => buildOperationArtifact({
|
|
3013
|
-
mode: "fieldsFactory",
|
|
3014
|
-
schema,
|
|
3015
|
-
operationType,
|
|
3016
|
-
operationTypeName,
|
|
3017
|
-
operationName,
|
|
3018
|
-
variables: varSpecifiers,
|
|
3019
|
-
fieldsFactory: ({ $ }) => {
|
|
3020
|
-
return buildFieldsFromSelectionSet(opNode.selectionSet, schema, operationTypeName, $, interpolationMap);
|
|
3021
|
-
},
|
|
3022
|
-
adapter: resolvedAdapter,
|
|
3023
|
-
metadata: resolvedMetadata,
|
|
3024
|
-
adapterTransformDocument
|
|
3025
|
-
}), false);
|
|
3026
|
-
};
|
|
3059
|
+
const dispatch = (firstArg, ...rest) => {
|
|
3060
|
+
if ("raw" in firstArg) return handleTaggedTemplate(schema, schemaIndex, operationType, operationName, metadataAdapter, adapterTransformDocument, firstArg, rest);
|
|
3061
|
+
return handleOptionsObject(schema, schemaIndex, operationType, operationName, metadataAdapter, adapterTransformDocument, firstArg);
|
|
3027
3062
|
};
|
|
3063
|
+
return dispatch;
|
|
3028
3064
|
};
|
|
3029
3065
|
};
|
|
3030
|
-
|
|
3031
|
-
//#endregion
|
|
3032
|
-
//#region packages/core/src/composer/var-ref-tools.ts
|
|
3033
|
-
/**
|
|
3034
|
-
* Recursively checks if a NestedValue contains any VarRef.
|
|
3035
|
-
*
|
|
3036
|
-
* Used by getVarRefValue to determine if it's safe to return as ConstValue.
|
|
3037
|
-
* @internal
|
|
3038
|
-
*/
|
|
3039
|
-
const hasVarRefInside = (value) => {
|
|
3040
|
-
if (value instanceof VarRef) return true;
|
|
3041
|
-
if (Array.isArray(value)) return value.some(hasVarRefInside);
|
|
3042
|
-
if (typeof value === "object" && value !== null) return Object.values(value).some(hasVarRefInside);
|
|
3043
|
-
return false;
|
|
3044
|
-
};
|
|
3045
3066
|
/**
|
|
3046
|
-
*
|
|
3047
|
-
* Throws if the VarRef contains a nested-value instead of a variable reference.
|
|
3048
|
-
*/
|
|
3049
|
-
const getVarRefName = (varRef) => {
|
|
3050
|
-
const inner = VarRef.getInner(varRef);
|
|
3051
|
-
if (inner.type !== "variable") throw new Error("Expected variable reference, got nested-value");
|
|
3052
|
-
return inner.name;
|
|
3053
|
-
};
|
|
3054
|
-
/**
|
|
3055
|
-
* Get the const value from a VarRef.
|
|
3056
|
-
* Throws if the VarRef contains a variable reference instead of a nested-value,
|
|
3057
|
-
* or if the nested-value contains any VarRef inside.
|
|
3067
|
+
* Handles the tagged template path.
|
|
3058
3068
|
*/
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
const
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
}
|
|
3071
|
-
const
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3069
|
+
function handleTaggedTemplate(schema, schemaIndex, operationType, operationName, metadataAdapter, adapterTransformDocument, strings, values) {
|
|
3070
|
+
for (let i = 0; i < values.length; i++) {
|
|
3071
|
+
const value = values[i];
|
|
3072
|
+
if (!(value instanceof Fragment) && typeof value !== "function") throw new Error(`Tagged templates only accept Fragment instances or callback functions as interpolated values. Received ${typeof value} at position ${i}.`);
|
|
3073
|
+
}
|
|
3074
|
+
let body = strings[0] ?? "";
|
|
3075
|
+
const interpolationMap = /* @__PURE__ */ new Map();
|
|
3076
|
+
for (let i = 0; i < values.length; i++) {
|
|
3077
|
+
const placeholderName = `__INTERPOLATION_${i}__`;
|
|
3078
|
+
interpolationMap.set(placeholderName, values[i]);
|
|
3079
|
+
body += placeholderName + (strings[i + 1] ?? "");
|
|
3080
|
+
}
|
|
3081
|
+
const source = buildSyntheticOperationSource(operationType, operationName, body);
|
|
3082
|
+
let document;
|
|
3083
|
+
try {
|
|
3084
|
+
document = (0, graphql.parse)(source);
|
|
3085
|
+
} catch (error) {
|
|
3086
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3087
|
+
throw new Error(`GraphQL parse error in tagged template: ${message}`);
|
|
3088
|
+
}
|
|
3089
|
+
const opDefs = document.definitions.filter((def) => def.kind === graphql.Kind.OPERATION_DEFINITION);
|
|
3090
|
+
if (opDefs.length !== 1) throw new Error(`Internal error: expected exactly one operation definition in synthesized source`);
|
|
3091
|
+
const opNode = opDefs[0];
|
|
3092
|
+
if (opNode.kind !== graphql.Kind.OPERATION_DEFINITION) throw new Error("Unexpected definition kind");
|
|
3093
|
+
const varDefNodes = opNode.variableDefinitions ?? [];
|
|
3094
|
+
let varSpecifiers = buildVarSpecifiers(varDefNodes, schemaIndex);
|
|
3095
|
+
varSpecifiers = mergeVariableDefinitions(varSpecifiers, interpolationMap);
|
|
3096
|
+
const hasInterpolatedFragmentVars = [...interpolationMap.values()].some((v) => v instanceof Fragment && Object.keys(v.variableDefinitions).length > 0);
|
|
3097
|
+
const operationTypeName = schema.operations[operationType];
|
|
3098
|
+
if (operationTypeName === null) throw new Error(`Operation type ${operationType} is not defined in schema roots`);
|
|
3099
|
+
const resolvedAdapter = metadataAdapter ?? defaultMetadataAdapter;
|
|
3100
|
+
return (options) => {
|
|
3101
|
+
const resolvedMetadata = resolveMetadataOption(options?.metadata);
|
|
3102
|
+
return wrapArtifactAsOperation(() => buildOperationArtifact({
|
|
3103
|
+
schema,
|
|
3104
|
+
operationType,
|
|
3105
|
+
operationTypeName,
|
|
3106
|
+
operationName,
|
|
3107
|
+
variables: varSpecifiers,
|
|
3108
|
+
variableDefinitionNodes: hasInterpolatedFragmentVars ? void 0 : varDefNodes,
|
|
3109
|
+
fieldsFactory: ({ $ }) => {
|
|
3110
|
+
return buildFieldsFromSelectionSet(filterUnresolvedFragmentSpreads(opNode.selectionSet, interpolationMap), schema, operationTypeName, $, interpolationMap);
|
|
3084
3111
|
},
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
return createSelectableProxy({
|
|
3090
|
-
varInner: value instanceof VarRef ? VarRef.getInner(value) : {
|
|
3091
|
-
type: "nested-value",
|
|
3092
|
-
value
|
|
3093
|
-
},
|
|
3094
|
-
segments: nextSegments
|
|
3095
|
-
});
|
|
3096
|
-
}
|
|
3097
|
-
throw new Error(`Cannot access children of primitive value at path [${current.segments.join(".")}]`);
|
|
3098
|
-
} });
|
|
3099
|
-
SelectableProxyInnerRegistry.set(proxy, current);
|
|
3100
|
-
return proxy;
|
|
3101
|
-
};
|
|
3102
|
-
/**
|
|
3103
|
-
* Get the variable name from a VarRef at a specific path.
|
|
3104
|
-
*
|
|
3105
|
-
* @param varRef - The VarRef containing a nested-value
|
|
3106
|
-
* @param selector - Path builder function, e.g., p => p.user.age
|
|
3107
|
-
* @returns The variable name at the specified path
|
|
3108
|
-
* @throws If path doesn't lead to a VarRef with type "variable"
|
|
3109
|
-
*
|
|
3110
|
-
* @example
|
|
3111
|
-
* const ref = createVarRefFromNestedValue({
|
|
3112
|
-
* user: { age: someVariableRef }
|
|
3113
|
-
* });
|
|
3114
|
-
* getNameAt(ref, p => p.user.age); // returns the variable name
|
|
3115
|
-
*/
|
|
3116
|
-
const getNameAt = (varRef, selector) => {
|
|
3117
|
-
const inner = getSelectableProxyInner(selector(createSelectableProxy({
|
|
3118
|
-
varInner: VarRef.getInner(varRef),
|
|
3119
|
-
segments: []
|
|
3120
|
-
})));
|
|
3121
|
-
if (inner.varInner.type === "virtual") throw new Error(`Value at path [${inner.segments.join(".")}] is inside a variable`);
|
|
3122
|
-
if (inner.varInner.type !== "variable") throw new Error(`Value at path [${inner.segments.join(".")}] is not a variable`);
|
|
3123
|
-
return inner.varInner.name;
|
|
3124
|
-
};
|
|
3125
|
-
/**
|
|
3126
|
-
* Get the const value from a nested-value VarRef at a specific path.
|
|
3127
|
-
*
|
|
3128
|
-
* @param varRef - The VarRef containing a nested-value
|
|
3129
|
-
* @param pathFn - Path builder function, e.g., p => p.user.name
|
|
3130
|
-
* @returns The const value at the specified path
|
|
3131
|
-
* @throws If path leads to a VarRef or if value contains VarRef inside
|
|
3132
|
-
*
|
|
3133
|
-
* @example
|
|
3134
|
-
* const ref = createVarRefFromNestedValue({
|
|
3135
|
-
* user: { name: "Alice", age: someVariableRef }
|
|
3136
|
-
* });
|
|
3137
|
-
* getValueAt(ref, p => p.user.name); // returns "Alice"
|
|
3138
|
-
*/
|
|
3139
|
-
const getValueAt = (varRef, selector) => {
|
|
3140
|
-
const inner = getSelectableProxyInner(selector(createSelectableProxy({
|
|
3141
|
-
varInner: VarRef.getInner(varRef),
|
|
3142
|
-
segments: []
|
|
3143
|
-
})));
|
|
3144
|
-
if (inner.varInner.type === "virtual") throw new Error(`Value at path [${inner.segments.join(".")}] is inside a variable`);
|
|
3145
|
-
if (inner.varInner.type !== "nested-value") throw new Error(`Value at path [${inner.segments.join(".")}] is not a nested-value`);
|
|
3146
|
-
if (hasVarRefInside(inner.varInner.value)) throw new Error(`Value at path [${inner.segments.join(".")}] contains nested VarRef`);
|
|
3147
|
-
return inner.varInner.value;
|
|
3148
|
-
};
|
|
3149
|
-
/**
|
|
3150
|
-
* Gets the full path to a variable within a nested structure.
|
|
3151
|
-
*
|
|
3152
|
-
* Returns path segments starting with `$variableName` followed by
|
|
3153
|
-
* property accesses within that variable's value.
|
|
3154
|
-
*
|
|
3155
|
-
* @example
|
|
3156
|
-
* ```typescript
|
|
3157
|
-
* getVariablePath($.filter, p => p.user.id)
|
|
3158
|
-
* // Returns: ["$filter", "user", "id"]
|
|
3159
|
-
* ```
|
|
3160
|
-
*/
|
|
3161
|
-
const getVariablePath = (varRef, selector) => {
|
|
3162
|
-
const inner = getSelectableProxyInner(selector(createSelectableProxy({
|
|
3163
|
-
varInner: VarRef.getInner(varRef),
|
|
3164
|
-
segments: []
|
|
3165
|
-
})));
|
|
3166
|
-
if (inner.varInner.type === "virtual") return [`$${inner.varInner.varName}`, ...inner.segments.slice(inner.varInner.varSegments.length)];
|
|
3167
|
-
if (inner.varInner.type === "variable") return [`$${inner.varInner.name}`];
|
|
3168
|
-
throw new Error(`Value at path [${inner.segments.join(".")}] is not a variable or inside a variable`);
|
|
3169
|
-
};
|
|
3170
|
-
|
|
3171
|
-
//#endregion
|
|
3172
|
-
//#region packages/core/src/composer/var-builder.ts
|
|
3173
|
-
/**
|
|
3174
|
-
* Creates a factory function for generating schema-scoped variable methods.
|
|
3175
|
-
* This ensures proper type inference for nested input objects by binding the schema type upfront.
|
|
3176
|
-
*
|
|
3177
|
-
* @example
|
|
3178
|
-
* ```typescript
|
|
3179
|
-
* const createMethod = createVarMethodFactory<typeof schema>();
|
|
3180
|
-
* const inputTypeMethods = {
|
|
3181
|
-
* Boolean: createMethod("scalar", "Boolean"),
|
|
3182
|
-
* user_bool_exp: createMethod("input", "user_bool_exp"),
|
|
3183
|
-
* } satisfies InputTypeMethods<typeof schema>;
|
|
3184
|
-
* ```
|
|
3185
|
-
*/
|
|
3186
|
-
const createVarMethodFactory = () => {
|
|
3187
|
-
return (kind, typeName) => {
|
|
3188
|
-
return ((modifier, extras) => ({
|
|
3189
|
-
kind,
|
|
3190
|
-
name: typeName,
|
|
3191
|
-
modifier,
|
|
3192
|
-
defaultValue: extras?.default ? { default: extras.default() } : null,
|
|
3193
|
-
directives: extras?.directives ?? {}
|
|
3112
|
+
adapter: resolvedAdapter,
|
|
3113
|
+
metadata: resolvedMetadata,
|
|
3114
|
+
transformDocument: options?.transformDocument,
|
|
3115
|
+
adapterTransformDocument
|
|
3194
3116
|
}));
|
|
3195
3117
|
};
|
|
3196
|
-
}
|
|
3118
|
+
}
|
|
3197
3119
|
/**
|
|
3198
|
-
*
|
|
3199
|
-
*
|
|
3200
|
-
* The returned builder provides type-safe variable definition methods
|
|
3201
|
-
* for all input types in the schema. Also includes utilities for
|
|
3202
|
-
* extracting variable names and values from VarRefs.
|
|
3203
|
-
*
|
|
3204
|
-
* @param inputTypeMethods - Methods for each input type (from codegen)
|
|
3205
|
-
* @returns Variable builder with methods for all input types
|
|
3206
|
-
*
|
|
3207
|
-
* @internal Used by `createGqlElementComposer`
|
|
3120
|
+
* Handles the options object path.
|
|
3208
3121
|
*/
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3122
|
+
function handleOptionsObject(schema, schemaIndex, operationType, operationName, metadataAdapter, adapterTransformDocument, options) {
|
|
3123
|
+
let varSpecifiers = {};
|
|
3124
|
+
let varDefNodes = [];
|
|
3125
|
+
if (options.variables) {
|
|
3126
|
+
const opDef = (0, graphql.parse)(`query __var_parse__ ${String(options.variables).trim()} { __typename }`).definitions[0];
|
|
3127
|
+
if (opDef?.kind === graphql.Kind.OPERATION_DEFINITION) {
|
|
3128
|
+
varDefNodes = opDef.variableDefinitions ?? [];
|
|
3129
|
+
varSpecifiers = buildVarSpecifiers(varDefNodes, schemaIndex);
|
|
3130
|
+
}
|
|
3131
|
+
}
|
|
3132
|
+
const operationTypeName = schema.operations[operationType];
|
|
3133
|
+
if (operationTypeName === null) throw new Error(`Operation type ${operationType} is not defined in schema roots`);
|
|
3134
|
+
const resolvedAdapter = metadataAdapter ?? defaultMetadataAdapter;
|
|
3135
|
+
return (step2Options) => {
|
|
3136
|
+
const resolvedMetadata = resolveMetadataOption(step2Options?.metadata);
|
|
3137
|
+
return wrapArtifactAsOperation(() => buildOperationArtifact({
|
|
3138
|
+
schema,
|
|
3139
|
+
operationType,
|
|
3140
|
+
operationTypeName,
|
|
3141
|
+
operationName,
|
|
3142
|
+
variables: varSpecifiers,
|
|
3143
|
+
variableDefinitionNodes: varDefNodes,
|
|
3144
|
+
fieldsFactory: options.fields,
|
|
3145
|
+
adapter: resolvedAdapter,
|
|
3146
|
+
metadata: resolvedMetadata,
|
|
3147
|
+
transformDocument: step2Options?.transformDocument,
|
|
3148
|
+
adapterTransformDocument
|
|
3149
|
+
}));
|
|
3218
3150
|
};
|
|
3219
|
-
|
|
3220
|
-
varBuilder.getValue = getVarRefValue;
|
|
3221
|
-
varBuilder.getNameAt = getNameAt;
|
|
3222
|
-
varBuilder.getValueAt = getValueAt;
|
|
3223
|
-
varBuilder.getVariablePath = getVariablePath;
|
|
3224
|
-
return varBuilder;
|
|
3225
|
-
};
|
|
3151
|
+
}
|
|
3226
3152
|
|
|
3227
3153
|
//#endregion
|
|
3228
3154
|
//#region packages/core/src/composer/gql-composer.ts
|
|
@@ -3232,57 +3158,37 @@ const createVarBuilder = (inputTypeMethods) => {
|
|
|
3232
3158
|
* This is the main entry point for defining GraphQL operations and fragments.
|
|
3233
3159
|
* The returned function provides a context with:
|
|
3234
3160
|
* - `fragment`: Tagged template function for fragment definitions
|
|
3235
|
-
* - `query/mutation/subscription`: Operation builders
|
|
3236
|
-
* - `$var`: Variable definition helpers
|
|
3161
|
+
* - `query/mutation/subscription`: Operation builders (tagged template + options object + .compat)
|
|
3237
3162
|
* - `$dir`: Field directive helpers (@skip, @include)
|
|
3238
3163
|
* - `$colocate`: Fragment colocation utilities
|
|
3239
3164
|
*
|
|
3240
3165
|
* @param schema - The GraphQL schema definition
|
|
3241
|
-
* @param options - Configuration including
|
|
3166
|
+
* @param options - Configuration including optional adapter
|
|
3242
3167
|
* @returns Element composer function
|
|
3243
3168
|
*
|
|
3244
3169
|
* @example
|
|
3245
3170
|
* ```typescript
|
|
3246
|
-
* const gql = createGqlElementComposer(schema, {
|
|
3247
|
-
*
|
|
3248
|
-
* const GetUser = gql(({ query, $
|
|
3249
|
-
* query
|
|
3250
|
-
*
|
|
3251
|
-
*
|
|
3252
|
-
* fields: ({ f, $ }) => ({
|
|
3253
|
-
* ...f.user({ id: "1" })(({ f }) => ({
|
|
3254
|
-
* ...f.name(),
|
|
3255
|
-
* ...f.email({}, { directives: [$dir.skip({ if: $.showEmail })] }),
|
|
3256
|
-
* })),
|
|
3257
|
-
* }),
|
|
3258
|
-
* })
|
|
3171
|
+
* const gql = createGqlElementComposer(schema, {});
|
|
3172
|
+
*
|
|
3173
|
+
* const GetUser = gql(({ query, $dir }) =>
|
|
3174
|
+
* query("GetUser")`($id: ID!) {
|
|
3175
|
+
* user(id: $id) { name email }
|
|
3176
|
+
* }`()
|
|
3259
3177
|
* );
|
|
3260
3178
|
* ```
|
|
3261
3179
|
*/
|
|
3262
3180
|
const createGqlElementComposer = (schema, options) => {
|
|
3263
|
-
const { adapter,
|
|
3181
|
+
const { adapter, directiveMethods } = options;
|
|
3264
3182
|
const helpers = adapter?.helpers;
|
|
3265
3183
|
const metadataAdapter = adapter?.metadata;
|
|
3266
3184
|
const transformDocument = adapter?.transformDocument;
|
|
3267
|
-
const fragment = createFragmentTaggedTemplate(schema);
|
|
3268
|
-
const createOperationComposer = createOperationComposerFactory(schema, metadataAdapter, transformDocument);
|
|
3269
3185
|
const transformedContext = require_context_transformer.applyContextTransformer({
|
|
3270
|
-
fragment,
|
|
3271
|
-
query: Object.assign(createOperationTaggedTemplate(schema, "query", metadataAdapter, transformDocument), {
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
}),
|
|
3275
|
-
mutation: Object.assign(createOperationTaggedTemplate(schema, "mutation", metadataAdapter, transformDocument), {
|
|
3276
|
-
operation: createOperationComposer("mutation"),
|
|
3277
|
-
compat: createCompatTaggedTemplate(schema, "mutation")
|
|
3278
|
-
}),
|
|
3279
|
-
subscription: Object.assign(createOperationTaggedTemplate(schema, "subscription", metadataAdapter, transformDocument), {
|
|
3280
|
-
operation: createOperationComposer("subscription"),
|
|
3281
|
-
compat: createCompatTaggedTemplate(schema, "subscription")
|
|
3282
|
-
}),
|
|
3186
|
+
fragment: createFragmentTaggedTemplate(schema),
|
|
3187
|
+
query: Object.assign(createOperationTaggedTemplate(schema, "query", metadataAdapter, transformDocument), { compat: createCompatTaggedTemplate(schema, "query") }),
|
|
3188
|
+
mutation: Object.assign(createOperationTaggedTemplate(schema, "mutation", metadataAdapter, transformDocument), { compat: createCompatTaggedTemplate(schema, "mutation") }),
|
|
3189
|
+
subscription: Object.assign(createOperationTaggedTemplate(schema, "subscription", metadataAdapter, transformDocument), { compat: createCompatTaggedTemplate(schema, "subscription") }),
|
|
3283
3190
|
define: (factory) => GqlDefine.create(factory),
|
|
3284
3191
|
extend: createExtendComposer(schema, metadataAdapter, transformDocument),
|
|
3285
|
-
$var: createVarBuilder(inputTypeMethods),
|
|
3286
3192
|
$dir: directiveMethods ?? createStandardDirectives(),
|
|
3287
3193
|
$colocate: createColocateHelper(),
|
|
3288
3194
|
...helpers ?? {}
|
|
@@ -3453,15 +3359,15 @@ const calculateUnionType = (schema, union, formatters, unionTypeName) => {
|
|
|
3453
3359
|
if (unionDef) {
|
|
3454
3360
|
const allMemberNames = Object.keys(unionDef.types);
|
|
3455
3361
|
for (const typeName of allMemberNames) {
|
|
3456
|
-
const
|
|
3457
|
-
if (
|
|
3458
|
-
const fieldsType = calculateFieldsType(schema, fields, formatters, typeName);
|
|
3362
|
+
const member = selections[typeName];
|
|
3363
|
+
if (member && typeof member === "object") {
|
|
3364
|
+
const fieldsType = calculateFieldsType(schema, member.fields, formatters, typeName);
|
|
3459
3365
|
memberTypes.push(`${fieldsType} & { readonly __typename: "${typeName}" }`);
|
|
3460
3366
|
} else memberTypes.push(`{ readonly __typename: "${typeName}" }`);
|
|
3461
3367
|
}
|
|
3462
3368
|
}
|
|
3463
|
-
} else for (const [typeName,
|
|
3464
|
-
const memberType = calculateFieldsType(schema, fields, formatters, typeName);
|
|
3369
|
+
} else for (const [typeName, member] of Object.entries(selections)) if (member && typeof member === "object") {
|
|
3370
|
+
const memberType = calculateFieldsType(schema, member.fields, formatters, typeName);
|
|
3465
3371
|
memberTypes.push(memberType);
|
|
3466
3372
|
}
|
|
3467
3373
|
if (memberTypes.length === 0) return "never";
|
|
@@ -3603,7 +3509,7 @@ const generateInputTypeFromSpecifiers = (schema, specifiers, options = {}) => {
|
|
|
3603
3509
|
* Generate a TypeScript type string for input variables from VariableDefinitions.
|
|
3604
3510
|
*
|
|
3605
3511
|
* Unlike generateInputTypeFromSpecifiers which works with deferred specifier strings,
|
|
3606
|
-
* this function works with VarSpecifier objects
|
|
3512
|
+
* this function works with VarSpecifier objects from variable definitions.
|
|
3607
3513
|
* Used for generating Fragment input types in prebuilt mode.
|
|
3608
3514
|
*
|
|
3609
3515
|
* @param schema - The GraphQL schema
|
|
@@ -3642,7 +3548,6 @@ exports.calculateFieldType = calculateFieldType;
|
|
|
3642
3548
|
exports.calculateFieldsType = calculateFieldsType;
|
|
3643
3549
|
exports.collectVariableUsages = collectVariableUsages;
|
|
3644
3550
|
exports.createColocateHelper = createColocateHelper;
|
|
3645
|
-
exports.createCompatComposer = createCompatComposer;
|
|
3646
3551
|
exports.createCompatTaggedTemplate = createCompatTaggedTemplate;
|
|
3647
3552
|
exports.createDefaultAdapter = createDefaultAdapter;
|
|
3648
3553
|
exports.createDirectiveBuilder = createDirectiveBuilder;
|
|
@@ -3651,15 +3556,12 @@ exports.createExtendComposer = createExtendComposer;
|
|
|
3651
3556
|
exports.createFieldFactories = createFieldFactories;
|
|
3652
3557
|
exports.createFragmentTaggedTemplate = createFragmentTaggedTemplate;
|
|
3653
3558
|
exports.createGqlElementComposer = createGqlElementComposer;
|
|
3654
|
-
exports.createOperationComposerFactory = createOperationComposerFactory;
|
|
3655
3559
|
exports.createOperationTaggedTemplate = createOperationTaggedTemplate;
|
|
3656
3560
|
exports.createSchemaIndex = createSchemaIndex;
|
|
3657
3561
|
exports.createSchemaIndexFromSchema = createSchemaIndexFromSchema;
|
|
3658
3562
|
exports.createStandardDirectives = createStandardDirectives;
|
|
3659
3563
|
exports.createTypedDirectiveMethod = createTypedDirectiveMethod;
|
|
3660
3564
|
exports.createVarAssignments = createVarAssignments;
|
|
3661
|
-
exports.createVarBuilder = createVarBuilder;
|
|
3662
|
-
exports.createVarMethodFactory = createVarMethodFactory;
|
|
3663
3565
|
exports.createVarRefFromVariable = createVarRefFromVariable;
|
|
3664
3566
|
exports.createVarRefs = createVarRefs;
|
|
3665
3567
|
exports.defaultMetadataAdapter = defaultMetadataAdapter;
|
|
@@ -3668,6 +3570,7 @@ exports.defineOperationRoots = require_schema_builder.defineOperationRoots;
|
|
|
3668
3570
|
exports.defineScalar = require_schema_builder.defineScalar;
|
|
3669
3571
|
exports.err = err;
|
|
3670
3572
|
exports.extractFragmentVariables = extractFragmentVariables;
|
|
3573
|
+
exports.filterUnresolvedFragmentSpreads = filterUnresolvedFragmentSpreads;
|
|
3671
3574
|
exports.generateInputObjectType = generateInputObjectType;
|
|
3672
3575
|
exports.generateInputType = generateInputType;
|
|
3673
3576
|
exports.generateInputTypeFromSpecifiers = generateInputTypeFromSpecifiers;
|
|
@@ -3677,14 +3580,19 @@ exports.getCurrentFieldPath = getCurrentFieldPath;
|
|
|
3677
3580
|
exports.getEnumType = getEnumType;
|
|
3678
3581
|
exports.getFieldReturnType = getFieldReturnType;
|
|
3679
3582
|
exports.getInputFieldType = getInputFieldType;
|
|
3583
|
+
exports.getNameAt = getNameAt;
|
|
3680
3584
|
exports.getScalarInputType = getScalarInputType;
|
|
3681
3585
|
exports.getScalarOutputType = getScalarOutputType;
|
|
3586
|
+
exports.getValueAt = getValueAt;
|
|
3587
|
+
exports.getVarRefName = getVarRefName;
|
|
3588
|
+
exports.getVarRefValue = getVarRefValue;
|
|
3589
|
+
exports.getVariablePath = getVariablePath;
|
|
3682
3590
|
exports.graphqlTypeToTypeScript = graphqlTypeToTypeScript;
|
|
3591
|
+
exports.hasVarRefInside = hasVarRefInside;
|
|
3683
3592
|
exports.inferVariablesFromUsages = inferVariablesFromUsages;
|
|
3684
3593
|
exports.isDirectiveRef = isDirectiveRef;
|
|
3685
3594
|
exports.isListType = isListType;
|
|
3686
3595
|
exports.isModifierAssignable = isModifierAssignable;
|
|
3687
|
-
exports.isTemplateCompatSpec = isTemplateCompatSpec;
|
|
3688
3596
|
exports.mergeModifiers = mergeModifiers;
|
|
3689
3597
|
exports.mergeVariableUsages = mergeVariableUsages;
|
|
3690
3598
|
exports.ok = ok;
|
|
@@ -3696,6 +3604,7 @@ exports.preprocessFragmentArgs = preprocessFragmentArgs;
|
|
|
3696
3604
|
exports.recordFragmentUsage = recordFragmentUsage;
|
|
3697
3605
|
exports.sortFragmentsByDependency = sortFragmentsByDependency;
|
|
3698
3606
|
exports.transformParsedGraphql = transformParsedGraphql;
|
|
3607
|
+
exports.varRefTools = varRefTools;
|
|
3699
3608
|
exports.withFieldPath = withFieldPath;
|
|
3700
3609
|
exports.withFragmentUsageCollection = withFragmentUsageCollection;
|
|
3701
3610
|
exports.wrapArtifactAsOperation = wrapArtifactAsOperation;
|