@soda-gql/core 0.13.2 → 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-8FNIWzv-.d.ts → index-CRWc3q9X.d.cts} +292 -598
- 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-DTUPt4z4.d.cts → index-DJ-yqsXz.d.ts} +292 -598
- package/dist/index-DJ-yqsXz.d.ts.map +1 -0
- package/dist/index.cjs +421 -493
- 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 +415 -489
- 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-8FNIWzv-.d.ts.map +0 -1
- package/dist/index-DTUPt4z4.d.cts.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
|
|
@@ -2426,6 +2409,155 @@ function mergeVariableDefinitions(parentVars, interpolationMap) {
|
|
|
2426
2409
|
return merged;
|
|
2427
2410
|
}
|
|
2428
2411
|
|
|
2412
|
+
//#endregion
|
|
2413
|
+
//#region packages/core/src/composer/var-ref-tools.ts
|
|
2414
|
+
/**
|
|
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
|
|
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
|
+
};
|
|
2426
|
+
/**
|
|
2427
|
+
* Get the variable name from a VarRef.
|
|
2428
|
+
* Throws if the VarRef contains a nested-value instead of a variable reference.
|
|
2429
|
+
*/
|
|
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
|
+
};
|
|
2435
|
+
/**
|
|
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.
|
|
2439
|
+
*/
|
|
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
|
+
|
|
2429
2561
|
//#endregion
|
|
2430
2562
|
//#region packages/core/src/composer/fragment-tagged-template.ts
|
|
2431
2563
|
/**
|
|
@@ -2504,27 +2636,33 @@ function buildFieldsFromSelectionSet(selectionSet, schema, typeName, varAssignme
|
|
|
2504
2636
|
result[alias] = true;
|
|
2505
2637
|
continue;
|
|
2506
2638
|
}
|
|
2507
|
-
const factory = f[fieldName];
|
|
2508
|
-
if (!factory) throw new Error(`Field "${fieldName}" is not defined on type "${typeName}"`);
|
|
2509
2639
|
const args = buildArgsFromASTArguments(selection.arguments ?? [], varAssignments);
|
|
2510
|
-
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;
|
|
2511
2646
|
if (selection.selectionSet) {
|
|
2512
|
-
const curried =
|
|
2647
|
+
const curried = f(fieldName, args, extras);
|
|
2513
2648
|
if (typeof curried === "function") {
|
|
2514
|
-
const
|
|
2515
|
-
const parsedType = parseOutputField(
|
|
2649
|
+
const fieldDefRaw = schema.object[typeName]?.fields[fieldName];
|
|
2650
|
+
const parsedType = parseOutputField(typeof fieldDefRaw === "string" ? fieldDefRaw : fieldDefRaw?.spec);
|
|
2516
2651
|
if (parsedType.kind === "union") {
|
|
2517
2652
|
const unionInput = {};
|
|
2518
2653
|
let hasTypename = false;
|
|
2519
2654
|
const unsupportedSelections = [];
|
|
2520
2655
|
for (const sel of selection.selectionSet.selections) if (sel.kind === graphql.Kind.INLINE_FRAGMENT) {
|
|
2521
|
-
if (sel.directives?.length) throw new Error("Directives on inline fragments are not supported in tagged templates");
|
|
2522
2656
|
if (!sel.typeCondition) throw new Error("Inline fragments without type conditions are not supported in tagged templates");
|
|
2523
2657
|
const memberName = sel.typeCondition.name.value;
|
|
2524
|
-
|
|
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`);
|
|
2525
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.`);
|
|
2526
|
-
|
|
2527
|
-
|
|
2662
|
+
unionInput[memberName] = {
|
|
2663
|
+
fields: buildFieldsFromSelectionSet(sel.selectionSet, schema, memberName, varAssignments, interpolationMap),
|
|
2664
|
+
directives: buildDirectivesFromAST(sel.directives, varAssignments, "INLINE_FRAGMENT")
|
|
2665
|
+
};
|
|
2528
2666
|
} else if (sel.kind === graphql.Kind.FIELD && sel.name.value === "__typename") {
|
|
2529
2667
|
if (sel.alias) throw new Error("Aliases on __typename in union selections are not supported in tagged templates. Use \"__typename\" without an alias.");
|
|
2530
2668
|
if (sel.directives?.length) throw new Error(`Directives on __typename in union selections are not supported in tagged templates.`);
|
|
@@ -2551,7 +2689,7 @@ function buildFieldsFromSelectionSet(selectionSet, schema, typeName, varAssignme
|
|
|
2551
2689
|
}
|
|
2552
2690
|
} else Object.assign(result, curried);
|
|
2553
2691
|
} else {
|
|
2554
|
-
const fieldResult =
|
|
2692
|
+
const fieldResult = f(fieldName, args, extras);
|
|
2555
2693
|
if (typeof fieldResult === "function") {
|
|
2556
2694
|
const emptyResult = fieldResult(() => ({}));
|
|
2557
2695
|
Object.assign(result, emptyResult);
|
|
@@ -2574,6 +2712,18 @@ function buildFieldsFromSelectionSet(selectionSet, schema, typeName, varAssignme
|
|
|
2574
2712
|
return result;
|
|
2575
2713
|
}
|
|
2576
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
|
+
/**
|
|
2577
2727
|
* Build a simple args object from GraphQL AST argument nodes.
|
|
2578
2728
|
* Extracts literal values from the AST for passing to field factories.
|
|
2579
2729
|
*/
|
|
@@ -2677,7 +2827,10 @@ function createFragmentTaggedTemplate(schema) {
|
|
|
2677
2827
|
let metadataBuilder = null;
|
|
2678
2828
|
if (options?.metadata !== void 0) {
|
|
2679
2829
|
const metadata = options.metadata;
|
|
2680
|
-
if (typeof metadata === "function") metadataBuilder = () => metadata({
|
|
2830
|
+
if (typeof metadata === "function") metadataBuilder = () => metadata({
|
|
2831
|
+
$,
|
|
2832
|
+
$var: varRefTools
|
|
2833
|
+
});
|
|
2681
2834
|
else metadataBuilder = () => metadata;
|
|
2682
2835
|
}
|
|
2683
2836
|
recordFragmentUsage({
|
|
@@ -2695,11 +2848,6 @@ function createFragmentTaggedTemplate(schema) {
|
|
|
2695
2848
|
//#endregion
|
|
2696
2849
|
//#region packages/core/src/composer/operation-core.ts
|
|
2697
2850
|
/**
|
|
2698
|
-
* Core operation building logic shared by operation and extend composers.
|
|
2699
|
-
* @module
|
|
2700
|
-
* @internal
|
|
2701
|
-
*/
|
|
2702
|
-
/**
|
|
2703
2851
|
* Builds an operation artifact from the provided parameters.
|
|
2704
2852
|
*
|
|
2705
2853
|
* This function contains the core logic for:
|
|
@@ -2712,10 +2860,10 @@ function createFragmentTaggedTemplate(schema) {
|
|
|
2712
2860
|
* @param params - Operation building parameters
|
|
2713
2861
|
* @returns Operation artifact or Promise of artifact (if async metadata)
|
|
2714
2862
|
*
|
|
2715
|
-
* @internal Used by
|
|
2863
|
+
* @internal Used by extend.ts and operation-tagged-template.ts
|
|
2716
2864
|
*/
|
|
2717
2865
|
const buildOperationArtifact = (params) => {
|
|
2718
|
-
const { schema, operationType, operationTypeName, operationName, variables, adapter, metadata: metadataBuilder, transformDocument: operationTransformDocument, adapterTransformDocument } = params;
|
|
2866
|
+
const { schema, operationType, operationTypeName, operationName, variables, variableDefinitionNodes, adapter, metadata: metadataBuilder, transformDocument: operationTransformDocument, adapterTransformDocument } = params;
|
|
2719
2867
|
const $ = createVarRefs(variables);
|
|
2720
2868
|
const { fieldsFactory } = params;
|
|
2721
2869
|
const f = createFieldFactories(schema, operationTypeName);
|
|
@@ -2729,6 +2877,7 @@ const buildOperationArtifact = (params) => {
|
|
|
2729
2877
|
operationName,
|
|
2730
2878
|
operationType,
|
|
2731
2879
|
operationTypeName,
|
|
2880
|
+
variableDefinitionNodes,
|
|
2732
2881
|
variables,
|
|
2733
2882
|
fields,
|
|
2734
2883
|
schema
|
|
@@ -2756,6 +2905,7 @@ const buildOperationArtifact = (params) => {
|
|
|
2756
2905
|
const schemaLevel = adapter.schemaLevel;
|
|
2757
2906
|
return metadataBuilder?.({
|
|
2758
2907
|
$,
|
|
2908
|
+
$var: varRefTools,
|
|
2759
2909
|
document,
|
|
2760
2910
|
fragmentMetadata: aggregatedFragmentMetadata,
|
|
2761
2911
|
schemaLevel
|
|
@@ -2812,14 +2962,14 @@ const wrapArtifactAsOperation = (artifactFactory) => {
|
|
|
2812
2962
|
//#endregion
|
|
2813
2963
|
//#region packages/core/src/composer/extend.ts
|
|
2814
2964
|
/**
|
|
2815
|
-
* Extend composer factory for creating Operations from
|
|
2965
|
+
* Extend composer factory for creating Operations from TemplateCompatSpec.
|
|
2816
2966
|
* @module
|
|
2817
2967
|
*/
|
|
2818
2968
|
/**
|
|
2819
2969
|
* Creates a factory for extending compat specs into full operations.
|
|
2820
2970
|
*
|
|
2821
|
-
* The extend function takes a
|
|
2822
|
-
* optional metadata/transformDocument options, then creates a full Operation.
|
|
2971
|
+
* The extend function takes a TemplateCompatSpec (created by `query.compat("Name")\`...\``)
|
|
2972
|
+
* and optional metadata/transformDocument options, then creates a full Operation.
|
|
2823
2973
|
*
|
|
2824
2974
|
* @param schema - The GraphQL schema definition
|
|
2825
2975
|
* @param adapter - Optional metadata adapter for custom metadata handling
|
|
@@ -2832,21 +2982,7 @@ const createExtendComposer = (schema, adapter, transformDocument) => {
|
|
|
2832
2982
|
const resolvedAdapter = adapter ?? defaultMetadataAdapter;
|
|
2833
2983
|
return (compat, options) => {
|
|
2834
2984
|
const spec = compat.value;
|
|
2835
|
-
|
|
2836
|
-
const { operationType, operationName, variables, fieldsBuilder } = spec;
|
|
2837
|
-
const operationTypeName = schema.operations[operationType];
|
|
2838
|
-
return Operation.create((() => buildOperationArtifact({
|
|
2839
|
-
schema,
|
|
2840
|
-
operationType,
|
|
2841
|
-
operationTypeName,
|
|
2842
|
-
operationName,
|
|
2843
|
-
variables,
|
|
2844
|
-
fieldsFactory: fieldsBuilder,
|
|
2845
|
-
adapter: resolvedAdapter,
|
|
2846
|
-
metadata: options?.metadata,
|
|
2847
|
-
transformDocument: options?.transformDocument,
|
|
2848
|
-
adapterTransformDocument: transformDocument
|
|
2849
|
-
})));
|
|
2985
|
+
return buildOperationFromTemplateSpec(schema, spec, resolvedAdapter, options, transformDocument);
|
|
2850
2986
|
};
|
|
2851
2987
|
};
|
|
2852
2988
|
/**
|
|
@@ -2867,6 +3003,7 @@ const buildOperationFromTemplateSpec = (schema, spec, adapter, options, adapterT
|
|
|
2867
3003
|
operationTypeName,
|
|
2868
3004
|
operationName,
|
|
2869
3005
|
variables: varSpecifiers,
|
|
3006
|
+
variableDefinitionNodes: opDef.variableDefinitions ?? [],
|
|
2870
3007
|
fieldsFactory: ({ $ }) => {
|
|
2871
3008
|
return buildFieldsFromSelectionSet(filteredSelectionSet, schema, operationTypeName, $);
|
|
2872
3009
|
},
|
|
@@ -2877,54 +3014,11 @@ const buildOperationFromTemplateSpec = (schema, spec, adapter, options, adapterT
|
|
|
2877
3014
|
}));
|
|
2878
3015
|
};
|
|
2879
3016
|
|
|
2880
|
-
//#endregion
|
|
2881
|
-
//#region packages/core/src/composer/operation.ts
|
|
2882
|
-
/**
|
|
2883
|
-
* Operation composer factory for creating typed GraphQL operations.
|
|
2884
|
-
* @module
|
|
2885
|
-
*/
|
|
2886
|
-
/**
|
|
2887
|
-
* Creates a factory for composing GraphQL operations.
|
|
2888
|
-
*
|
|
2889
|
-
* Returns a curried function: first select operation type (query/mutation/subscription),
|
|
2890
|
-
* then define the operation with name, variables, and fields.
|
|
2891
|
-
*
|
|
2892
|
-
* Handles metadata aggregation from fragments (sync or async) and builds
|
|
2893
|
-
* the TypedDocumentNode automatically.
|
|
2894
|
-
*
|
|
2895
|
-
* @param schema - The GraphQL schema definition
|
|
2896
|
-
* @param adapter - Optional metadata adapter for custom metadata handling
|
|
2897
|
-
* @param transformDocument - Optional document transformer called after building
|
|
2898
|
-
* @returns Operation type selector function
|
|
2899
|
-
*
|
|
2900
|
-
* @internal Used by `createGqlElementComposer`
|
|
2901
|
-
*/
|
|
2902
|
-
const createOperationComposerFactory = (schema, adapter, transformDocument) => {
|
|
2903
|
-
const resolvedAdapter = adapter ?? defaultMetadataAdapter;
|
|
2904
|
-
return (operationType) => {
|
|
2905
|
-
const operationTypeName = schema.operations[operationType];
|
|
2906
|
-
if (operationTypeName === null) throw new Error(`Operation type ${operationType} is not defined in schema roots`);
|
|
2907
|
-
return (options) => {
|
|
2908
|
-
return Operation.create((() => buildOperationArtifact({
|
|
2909
|
-
schema,
|
|
2910
|
-
operationType,
|
|
2911
|
-
operationTypeName,
|
|
2912
|
-
operationName: options.name,
|
|
2913
|
-
variables: options.variables ?? {},
|
|
2914
|
-
fieldsFactory: options.fields,
|
|
2915
|
-
adapter: resolvedAdapter,
|
|
2916
|
-
metadata: options.metadata,
|
|
2917
|
-
transformDocument: options.transformDocument,
|
|
2918
|
-
adapterTransformDocument: transformDocument
|
|
2919
|
-
})));
|
|
2920
|
-
};
|
|
2921
|
-
};
|
|
2922
|
-
};
|
|
2923
|
-
|
|
2924
3017
|
//#endregion
|
|
2925
3018
|
//#region packages/core/src/composer/operation-tagged-template.ts
|
|
2926
3019
|
/**
|
|
2927
3020
|
* Operation tagged template function for creating GraphQL operations from template literals.
|
|
3021
|
+
* Also supports options object dispatch for callback builder path.
|
|
2928
3022
|
* @module
|
|
2929
3023
|
*/
|
|
2930
3024
|
/**
|
|
@@ -2938,9 +3032,9 @@ function buildSyntheticOperationSource(operationType, operationName, body) {
|
|
|
2938
3032
|
* Resolves a metadata option from OperationTemplateMetadataOptions into a MetadataBuilder
|
|
2939
3033
|
* compatible with buildOperationArtifact.
|
|
2940
3034
|
*
|
|
2941
|
-
* - `undefined`
|
|
2942
|
-
* - Raw value
|
|
2943
|
-
* - Callback
|
|
3035
|
+
* - `undefined` -> `undefined` (no metadata)
|
|
3036
|
+
* - Raw value -> `() => value` (static metadata)
|
|
3037
|
+
* - Callback -> forwarded directly (receives full pipeline context)
|
|
2944
3038
|
*/
|
|
2945
3039
|
const resolveMetadataOption = (metadataOption) => {
|
|
2946
3040
|
if (metadataOption === void 0) return void 0;
|
|
@@ -2948,8 +3042,11 @@ const resolveMetadataOption = (metadataOption) => {
|
|
|
2948
3042
|
return () => metadataOption;
|
|
2949
3043
|
};
|
|
2950
3044
|
/**
|
|
2951
|
-
* Creates a curried
|
|
2952
|
-
*
|
|
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>.
|
|
2953
3050
|
*
|
|
2954
3051
|
* @param schema - The GraphQL schema definition
|
|
2955
3052
|
* @param operationType - The operation type (query, mutation, subscription)
|
|
@@ -2959,250 +3056,99 @@ const resolveMetadataOption = (metadataOption) => {
|
|
|
2959
3056
|
const createOperationTaggedTemplate = (schema, operationType, metadataAdapter, adapterTransformDocument) => {
|
|
2960
3057
|
const schemaIndex = createSchemaIndexFromSchema(schema);
|
|
2961
3058
|
return (operationName) => {
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
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}.`);
|
|
2966
|
-
}
|
|
2967
|
-
let body = strings[0] ?? "";
|
|
2968
|
-
const interpolationMap = /* @__PURE__ */ new Map();
|
|
2969
|
-
for (let i = 0; i < values.length; i++) {
|
|
2970
|
-
const placeholderName = `__INTERPOLATION_${i}__`;
|
|
2971
|
-
interpolationMap.set(placeholderName, values[i]);
|
|
2972
|
-
body += placeholderName + (strings[i + 1] ?? "");
|
|
2973
|
-
}
|
|
2974
|
-
const source = buildSyntheticOperationSource(operationType, operationName, body);
|
|
2975
|
-
let document;
|
|
2976
|
-
try {
|
|
2977
|
-
document = (0, graphql.parse)(source);
|
|
2978
|
-
} catch (error) {
|
|
2979
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
2980
|
-
throw new Error(`GraphQL parse error in tagged template: ${message}`);
|
|
2981
|
-
}
|
|
2982
|
-
const opDefs = document.definitions.filter((def) => def.kind === graphql.Kind.OPERATION_DEFINITION);
|
|
2983
|
-
if (opDefs.length !== 1) throw new Error(`Internal error: expected exactly one operation definition in synthesized source`);
|
|
2984
|
-
const opNode = opDefs[0];
|
|
2985
|
-
if (opNode.kind !== graphql.Kind.OPERATION_DEFINITION) throw new Error("Unexpected definition kind");
|
|
2986
|
-
let varSpecifiers = buildVarSpecifiers(opNode.variableDefinitions ?? [], schemaIndex);
|
|
2987
|
-
varSpecifiers = mergeVariableDefinitions(varSpecifiers, interpolationMap);
|
|
2988
|
-
const operationTypeName = schema.operations[operationType];
|
|
2989
|
-
if (operationTypeName === null) throw new Error(`Operation type ${operationType} is not defined in schema roots`);
|
|
2990
|
-
const resolvedAdapter = metadataAdapter ?? defaultMetadataAdapter;
|
|
2991
|
-
return (options) => {
|
|
2992
|
-
const resolvedMetadata = resolveMetadataOption(options?.metadata);
|
|
2993
|
-
return wrapArtifactAsOperation(() => buildOperationArtifact({
|
|
2994
|
-
schema,
|
|
2995
|
-
operationType,
|
|
2996
|
-
operationTypeName,
|
|
2997
|
-
operationName,
|
|
2998
|
-
variables: varSpecifiers,
|
|
2999
|
-
fieldsFactory: ({ $ }) => {
|
|
3000
|
-
return buildFieldsFromSelectionSet(filterUnresolvedFragmentSpreads(opNode.selectionSet, interpolationMap), schema, operationTypeName, $, interpolationMap);
|
|
3001
|
-
},
|
|
3002
|
-
adapter: resolvedAdapter,
|
|
3003
|
-
metadata: resolvedMetadata,
|
|
3004
|
-
adapterTransformDocument
|
|
3005
|
-
}));
|
|
3006
|
-
};
|
|
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);
|
|
3007
3062
|
};
|
|
3063
|
+
return dispatch;
|
|
3008
3064
|
};
|
|
3009
3065
|
};
|
|
3010
|
-
|
|
3011
|
-
//#endregion
|
|
3012
|
-
//#region packages/core/src/composer/var-ref-tools.ts
|
|
3013
|
-
/**
|
|
3014
|
-
* Recursively checks if a NestedValue contains any VarRef.
|
|
3015
|
-
*
|
|
3016
|
-
* Used by getVarRefValue to determine if it's safe to return as ConstValue.
|
|
3017
|
-
* @internal
|
|
3018
|
-
*/
|
|
3019
|
-
const hasVarRefInside = (value) => {
|
|
3020
|
-
if (value instanceof VarRef) return true;
|
|
3021
|
-
if (Array.isArray(value)) return value.some(hasVarRefInside);
|
|
3022
|
-
if (typeof value === "object" && value !== null) return Object.values(value).some(hasVarRefInside);
|
|
3023
|
-
return false;
|
|
3024
|
-
};
|
|
3025
|
-
/**
|
|
3026
|
-
* Get the variable name from a VarRef.
|
|
3027
|
-
* Throws if the VarRef contains a nested-value instead of a variable reference.
|
|
3028
|
-
*/
|
|
3029
|
-
const getVarRefName = (varRef) => {
|
|
3030
|
-
const inner = VarRef.getInner(varRef);
|
|
3031
|
-
if (inner.type !== "variable") throw new Error("Expected variable reference, got nested-value");
|
|
3032
|
-
return inner.name;
|
|
3033
|
-
};
|
|
3034
3066
|
/**
|
|
3035
|
-
*
|
|
3036
|
-
* Throws if the VarRef contains a variable reference instead of a nested-value,
|
|
3037
|
-
* or if the nested-value contains any VarRef inside.
|
|
3067
|
+
* Handles the tagged template path.
|
|
3038
3068
|
*/
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
const
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
}
|
|
3051
|
-
const
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
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);
|
|
3064
3111
|
},
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
return createSelectableProxy({
|
|
3070
|
-
varInner: value instanceof VarRef ? VarRef.getInner(value) : {
|
|
3071
|
-
type: "nested-value",
|
|
3072
|
-
value
|
|
3073
|
-
},
|
|
3074
|
-
segments: nextSegments
|
|
3075
|
-
});
|
|
3076
|
-
}
|
|
3077
|
-
throw new Error(`Cannot access children of primitive value at path [${current.segments.join(".")}]`);
|
|
3078
|
-
} });
|
|
3079
|
-
SelectableProxyInnerRegistry.set(proxy, current);
|
|
3080
|
-
return proxy;
|
|
3081
|
-
};
|
|
3082
|
-
/**
|
|
3083
|
-
* Get the variable name from a VarRef at a specific path.
|
|
3084
|
-
*
|
|
3085
|
-
* @param varRef - The VarRef containing a nested-value
|
|
3086
|
-
* @param selector - Path builder function, e.g., p => p.user.age
|
|
3087
|
-
* @returns The variable name at the specified path
|
|
3088
|
-
* @throws If path doesn't lead to a VarRef with type "variable"
|
|
3089
|
-
*
|
|
3090
|
-
* @example
|
|
3091
|
-
* const ref = createVarRefFromNestedValue({
|
|
3092
|
-
* user: { age: someVariableRef }
|
|
3093
|
-
* });
|
|
3094
|
-
* getNameAt(ref, p => p.user.age); // returns the variable name
|
|
3095
|
-
*/
|
|
3096
|
-
const getNameAt = (varRef, selector) => {
|
|
3097
|
-
const inner = getSelectableProxyInner(selector(createSelectableProxy({
|
|
3098
|
-
varInner: VarRef.getInner(varRef),
|
|
3099
|
-
segments: []
|
|
3100
|
-
})));
|
|
3101
|
-
if (inner.varInner.type === "virtual") throw new Error(`Value at path [${inner.segments.join(".")}] is inside a variable`);
|
|
3102
|
-
if (inner.varInner.type !== "variable") throw new Error(`Value at path [${inner.segments.join(".")}] is not a variable`);
|
|
3103
|
-
return inner.varInner.name;
|
|
3104
|
-
};
|
|
3105
|
-
/**
|
|
3106
|
-
* Get the const value from a nested-value VarRef at a specific path.
|
|
3107
|
-
*
|
|
3108
|
-
* @param varRef - The VarRef containing a nested-value
|
|
3109
|
-
* @param pathFn - Path builder function, e.g., p => p.user.name
|
|
3110
|
-
* @returns The const value at the specified path
|
|
3111
|
-
* @throws If path leads to a VarRef or if value contains VarRef inside
|
|
3112
|
-
*
|
|
3113
|
-
* @example
|
|
3114
|
-
* const ref = createVarRefFromNestedValue({
|
|
3115
|
-
* user: { name: "Alice", age: someVariableRef }
|
|
3116
|
-
* });
|
|
3117
|
-
* getValueAt(ref, p => p.user.name); // returns "Alice"
|
|
3118
|
-
*/
|
|
3119
|
-
const getValueAt = (varRef, selector) => {
|
|
3120
|
-
const inner = getSelectableProxyInner(selector(createSelectableProxy({
|
|
3121
|
-
varInner: VarRef.getInner(varRef),
|
|
3122
|
-
segments: []
|
|
3123
|
-
})));
|
|
3124
|
-
if (inner.varInner.type === "virtual") throw new Error(`Value at path [${inner.segments.join(".")}] is inside a variable`);
|
|
3125
|
-
if (inner.varInner.type !== "nested-value") throw new Error(`Value at path [${inner.segments.join(".")}] is not a nested-value`);
|
|
3126
|
-
if (hasVarRefInside(inner.varInner.value)) throw new Error(`Value at path [${inner.segments.join(".")}] contains nested VarRef`);
|
|
3127
|
-
return inner.varInner.value;
|
|
3128
|
-
};
|
|
3129
|
-
/**
|
|
3130
|
-
* Gets the full path to a variable within a nested structure.
|
|
3131
|
-
*
|
|
3132
|
-
* Returns path segments starting with `$variableName` followed by
|
|
3133
|
-
* property accesses within that variable's value.
|
|
3134
|
-
*
|
|
3135
|
-
* @example
|
|
3136
|
-
* ```typescript
|
|
3137
|
-
* getVariablePath($.filter, p => p.user.id)
|
|
3138
|
-
* // Returns: ["$filter", "user", "id"]
|
|
3139
|
-
* ```
|
|
3140
|
-
*/
|
|
3141
|
-
const getVariablePath = (varRef, selector) => {
|
|
3142
|
-
const inner = getSelectableProxyInner(selector(createSelectableProxy({
|
|
3143
|
-
varInner: VarRef.getInner(varRef),
|
|
3144
|
-
segments: []
|
|
3145
|
-
})));
|
|
3146
|
-
if (inner.varInner.type === "virtual") return [`$${inner.varInner.varName}`, ...inner.segments.slice(inner.varInner.varSegments.length)];
|
|
3147
|
-
if (inner.varInner.type === "variable") return [`$${inner.varInner.name}`];
|
|
3148
|
-
throw new Error(`Value at path [${inner.segments.join(".")}] is not a variable or inside a variable`);
|
|
3149
|
-
};
|
|
3150
|
-
|
|
3151
|
-
//#endregion
|
|
3152
|
-
//#region packages/core/src/composer/var-builder.ts
|
|
3153
|
-
/**
|
|
3154
|
-
* Creates a factory function for generating schema-scoped variable methods.
|
|
3155
|
-
* This ensures proper type inference for nested input objects by binding the schema type upfront.
|
|
3156
|
-
*
|
|
3157
|
-
* @example
|
|
3158
|
-
* ```typescript
|
|
3159
|
-
* const createMethod = createVarMethodFactory<typeof schema>();
|
|
3160
|
-
* const inputTypeMethods = {
|
|
3161
|
-
* Boolean: createMethod("scalar", "Boolean"),
|
|
3162
|
-
* user_bool_exp: createMethod("input", "user_bool_exp"),
|
|
3163
|
-
* } satisfies InputTypeMethods<typeof schema>;
|
|
3164
|
-
* ```
|
|
3165
|
-
*/
|
|
3166
|
-
const createVarMethodFactory = () => {
|
|
3167
|
-
return (kind, typeName) => {
|
|
3168
|
-
return ((modifier, extras) => ({
|
|
3169
|
-
kind,
|
|
3170
|
-
name: typeName,
|
|
3171
|
-
modifier,
|
|
3172
|
-
defaultValue: extras?.default ? { default: extras.default() } : null,
|
|
3173
|
-
directives: extras?.directives ?? {}
|
|
3112
|
+
adapter: resolvedAdapter,
|
|
3113
|
+
metadata: resolvedMetadata,
|
|
3114
|
+
transformDocument: options?.transformDocument,
|
|
3115
|
+
adapterTransformDocument
|
|
3174
3116
|
}));
|
|
3175
3117
|
};
|
|
3176
|
-
}
|
|
3118
|
+
}
|
|
3177
3119
|
/**
|
|
3178
|
-
*
|
|
3179
|
-
*
|
|
3180
|
-
* The returned builder provides type-safe variable definition methods
|
|
3181
|
-
* for all input types in the schema. Also includes utilities for
|
|
3182
|
-
* extracting variable names and values from VarRefs.
|
|
3183
|
-
*
|
|
3184
|
-
* @param inputTypeMethods - Methods for each input type (from codegen)
|
|
3185
|
-
* @returns Variable builder with methods for all input types
|
|
3186
|
-
*
|
|
3187
|
-
* @internal Used by `createGqlElementComposer`
|
|
3120
|
+
* Handles the options object path.
|
|
3188
3121
|
*/
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
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
|
+
}));
|
|
3198
3150
|
};
|
|
3199
|
-
|
|
3200
|
-
varBuilder.getValue = getVarRefValue;
|
|
3201
|
-
varBuilder.getNameAt = getNameAt;
|
|
3202
|
-
varBuilder.getValueAt = getValueAt;
|
|
3203
|
-
varBuilder.getVariablePath = getVariablePath;
|
|
3204
|
-
return varBuilder;
|
|
3205
|
-
};
|
|
3151
|
+
}
|
|
3206
3152
|
|
|
3207
3153
|
//#endregion
|
|
3208
3154
|
//#region packages/core/src/composer/gql-composer.ts
|
|
@@ -3212,57 +3158,37 @@ const createVarBuilder = (inputTypeMethods) => {
|
|
|
3212
3158
|
* This is the main entry point for defining GraphQL operations and fragments.
|
|
3213
3159
|
* The returned function provides a context with:
|
|
3214
3160
|
* - `fragment`: Tagged template function for fragment definitions
|
|
3215
|
-
* - `query/mutation/subscription`: Operation builders
|
|
3216
|
-
* - `$var`: Variable definition helpers
|
|
3161
|
+
* - `query/mutation/subscription`: Operation builders (tagged template + options object + .compat)
|
|
3217
3162
|
* - `$dir`: Field directive helpers (@skip, @include)
|
|
3218
3163
|
* - `$colocate`: Fragment colocation utilities
|
|
3219
3164
|
*
|
|
3220
3165
|
* @param schema - The GraphQL schema definition
|
|
3221
|
-
* @param options - Configuration including
|
|
3166
|
+
* @param options - Configuration including optional adapter
|
|
3222
3167
|
* @returns Element composer function
|
|
3223
3168
|
*
|
|
3224
3169
|
* @example
|
|
3225
3170
|
* ```typescript
|
|
3226
|
-
* const gql = createGqlElementComposer(schema, {
|
|
3227
|
-
*
|
|
3228
|
-
* const GetUser = gql(({ query, $
|
|
3229
|
-
* query
|
|
3230
|
-
*
|
|
3231
|
-
*
|
|
3232
|
-
* fields: ({ f, $ }) => ({
|
|
3233
|
-
* ...f.user({ id: "1" })(({ f }) => ({
|
|
3234
|
-
* ...f.name(),
|
|
3235
|
-
* ...f.email({}, { directives: [$dir.skip({ if: $.showEmail })] }),
|
|
3236
|
-
* })),
|
|
3237
|
-
* }),
|
|
3238
|
-
* })
|
|
3171
|
+
* const gql = createGqlElementComposer(schema, {});
|
|
3172
|
+
*
|
|
3173
|
+
* const GetUser = gql(({ query, $dir }) =>
|
|
3174
|
+
* query("GetUser")`($id: ID!) {
|
|
3175
|
+
* user(id: $id) { name email }
|
|
3176
|
+
* }`()
|
|
3239
3177
|
* );
|
|
3240
3178
|
* ```
|
|
3241
3179
|
*/
|
|
3242
3180
|
const createGqlElementComposer = (schema, options) => {
|
|
3243
|
-
const { adapter,
|
|
3181
|
+
const { adapter, directiveMethods } = options;
|
|
3244
3182
|
const helpers = adapter?.helpers;
|
|
3245
3183
|
const metadataAdapter = adapter?.metadata;
|
|
3246
3184
|
const transformDocument = adapter?.transformDocument;
|
|
3247
|
-
const fragment = createFragmentTaggedTemplate(schema);
|
|
3248
|
-
const createOperationComposer = createOperationComposerFactory(schema, metadataAdapter, transformDocument);
|
|
3249
3185
|
const transformedContext = require_context_transformer.applyContextTransformer({
|
|
3250
|
-
fragment,
|
|
3251
|
-
query: Object.assign(createOperationTaggedTemplate(schema, "query", metadataAdapter, transformDocument), {
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
}),
|
|
3255
|
-
mutation: Object.assign(createOperationTaggedTemplate(schema, "mutation", metadataAdapter, transformDocument), {
|
|
3256
|
-
operation: createOperationComposer("mutation"),
|
|
3257
|
-
compat: createCompatTaggedTemplate(schema, "mutation")
|
|
3258
|
-
}),
|
|
3259
|
-
subscription: Object.assign(createOperationTaggedTemplate(schema, "subscription", metadataAdapter, transformDocument), {
|
|
3260
|
-
operation: createOperationComposer("subscription"),
|
|
3261
|
-
compat: createCompatTaggedTemplate(schema, "subscription")
|
|
3262
|
-
}),
|
|
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") }),
|
|
3263
3190
|
define: (factory) => GqlDefine.create(factory),
|
|
3264
3191
|
extend: createExtendComposer(schema, metadataAdapter, transformDocument),
|
|
3265
|
-
$var: createVarBuilder(inputTypeMethods),
|
|
3266
3192
|
$dir: directiveMethods ?? createStandardDirectives(),
|
|
3267
3193
|
$colocate: createColocateHelper(),
|
|
3268
3194
|
...helpers ?? {}
|
|
@@ -3433,15 +3359,15 @@ const calculateUnionType = (schema, union, formatters, unionTypeName) => {
|
|
|
3433
3359
|
if (unionDef) {
|
|
3434
3360
|
const allMemberNames = Object.keys(unionDef.types);
|
|
3435
3361
|
for (const typeName of allMemberNames) {
|
|
3436
|
-
const
|
|
3437
|
-
if (
|
|
3438
|
-
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);
|
|
3439
3365
|
memberTypes.push(`${fieldsType} & { readonly __typename: "${typeName}" }`);
|
|
3440
3366
|
} else memberTypes.push(`{ readonly __typename: "${typeName}" }`);
|
|
3441
3367
|
}
|
|
3442
3368
|
}
|
|
3443
|
-
} else for (const [typeName,
|
|
3444
|
-
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);
|
|
3445
3371
|
memberTypes.push(memberType);
|
|
3446
3372
|
}
|
|
3447
3373
|
if (memberTypes.length === 0) return "never";
|
|
@@ -3583,7 +3509,7 @@ const generateInputTypeFromSpecifiers = (schema, specifiers, options = {}) => {
|
|
|
3583
3509
|
* Generate a TypeScript type string for input variables from VariableDefinitions.
|
|
3584
3510
|
*
|
|
3585
3511
|
* Unlike generateInputTypeFromSpecifiers which works with deferred specifier strings,
|
|
3586
|
-
* this function works with VarSpecifier objects
|
|
3512
|
+
* this function works with VarSpecifier objects from variable definitions.
|
|
3587
3513
|
* Used for generating Fragment input types in prebuilt mode.
|
|
3588
3514
|
*
|
|
3589
3515
|
* @param schema - The GraphQL schema
|
|
@@ -3622,7 +3548,6 @@ exports.calculateFieldType = calculateFieldType;
|
|
|
3622
3548
|
exports.calculateFieldsType = calculateFieldsType;
|
|
3623
3549
|
exports.collectVariableUsages = collectVariableUsages;
|
|
3624
3550
|
exports.createColocateHelper = createColocateHelper;
|
|
3625
|
-
exports.createCompatComposer = createCompatComposer;
|
|
3626
3551
|
exports.createCompatTaggedTemplate = createCompatTaggedTemplate;
|
|
3627
3552
|
exports.createDefaultAdapter = createDefaultAdapter;
|
|
3628
3553
|
exports.createDirectiveBuilder = createDirectiveBuilder;
|
|
@@ -3631,15 +3556,12 @@ exports.createExtendComposer = createExtendComposer;
|
|
|
3631
3556
|
exports.createFieldFactories = createFieldFactories;
|
|
3632
3557
|
exports.createFragmentTaggedTemplate = createFragmentTaggedTemplate;
|
|
3633
3558
|
exports.createGqlElementComposer = createGqlElementComposer;
|
|
3634
|
-
exports.createOperationComposerFactory = createOperationComposerFactory;
|
|
3635
3559
|
exports.createOperationTaggedTemplate = createOperationTaggedTemplate;
|
|
3636
3560
|
exports.createSchemaIndex = createSchemaIndex;
|
|
3637
3561
|
exports.createSchemaIndexFromSchema = createSchemaIndexFromSchema;
|
|
3638
3562
|
exports.createStandardDirectives = createStandardDirectives;
|
|
3639
3563
|
exports.createTypedDirectiveMethod = createTypedDirectiveMethod;
|
|
3640
3564
|
exports.createVarAssignments = createVarAssignments;
|
|
3641
|
-
exports.createVarBuilder = createVarBuilder;
|
|
3642
|
-
exports.createVarMethodFactory = createVarMethodFactory;
|
|
3643
3565
|
exports.createVarRefFromVariable = createVarRefFromVariable;
|
|
3644
3566
|
exports.createVarRefs = createVarRefs;
|
|
3645
3567
|
exports.defaultMetadataAdapter = defaultMetadataAdapter;
|
|
@@ -3658,14 +3580,19 @@ exports.getCurrentFieldPath = getCurrentFieldPath;
|
|
|
3658
3580
|
exports.getEnumType = getEnumType;
|
|
3659
3581
|
exports.getFieldReturnType = getFieldReturnType;
|
|
3660
3582
|
exports.getInputFieldType = getInputFieldType;
|
|
3583
|
+
exports.getNameAt = getNameAt;
|
|
3661
3584
|
exports.getScalarInputType = getScalarInputType;
|
|
3662
3585
|
exports.getScalarOutputType = getScalarOutputType;
|
|
3586
|
+
exports.getValueAt = getValueAt;
|
|
3587
|
+
exports.getVarRefName = getVarRefName;
|
|
3588
|
+
exports.getVarRefValue = getVarRefValue;
|
|
3589
|
+
exports.getVariablePath = getVariablePath;
|
|
3663
3590
|
exports.graphqlTypeToTypeScript = graphqlTypeToTypeScript;
|
|
3591
|
+
exports.hasVarRefInside = hasVarRefInside;
|
|
3664
3592
|
exports.inferVariablesFromUsages = inferVariablesFromUsages;
|
|
3665
3593
|
exports.isDirectiveRef = isDirectiveRef;
|
|
3666
3594
|
exports.isListType = isListType;
|
|
3667
3595
|
exports.isModifierAssignable = isModifierAssignable;
|
|
3668
|
-
exports.isTemplateCompatSpec = isTemplateCompatSpec;
|
|
3669
3596
|
exports.mergeModifiers = mergeModifiers;
|
|
3670
3597
|
exports.mergeVariableUsages = mergeVariableUsages;
|
|
3671
3598
|
exports.ok = ok;
|
|
@@ -3677,6 +3604,7 @@ exports.preprocessFragmentArgs = preprocessFragmentArgs;
|
|
|
3677
3604
|
exports.recordFragmentUsage = recordFragmentUsage;
|
|
3678
3605
|
exports.sortFragmentsByDependency = sortFragmentsByDependency;
|
|
3679
3606
|
exports.transformParsedGraphql = transformParsedGraphql;
|
|
3607
|
+
exports.varRefTools = varRefTools;
|
|
3680
3608
|
exports.withFieldPath = withFieldPath;
|
|
3681
3609
|
exports.withFragmentUsageCollection = withFragmentUsageCollection;
|
|
3682
3610
|
exports.wrapArtifactAsOperation = wrapArtifactAsOperation;
|