graphql-data-generator 0.4.1-alpha.4 → 0.4.1-alpha.6
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/esm/codegen.js +50 -0
- package/esm/init.js +32 -6
- package/esm/proxy.js +27 -4
- package/package.json +1 -1
- package/script/codegen.js +50 -0
- package/script/init.js +32 -6
- package/script/proxy.js +27 -4
package/esm/codegen.js
CHANGED
|
@@ -175,6 +175,7 @@ const getSelectionsType = (name, selections, definitions, fragments, references,
|
|
|
175
175
|
if (!fragment) {
|
|
176
176
|
throw new Error(`Could not find fragment '${selection.name.value}' in '${name}'`);
|
|
177
177
|
}
|
|
178
|
+
// Fragment is automatically considered used
|
|
178
179
|
selectionTypes.push(...getSelectionsType(fragment.typeCondition.name.value, fragment.selectionSet.selections, definitions, fragments, references, includeTypenames).map(([name, type, group]) => [
|
|
179
180
|
name,
|
|
180
181
|
type,
|
|
@@ -561,6 +562,55 @@ ${usedTypes.map(([name]) => ` ${name}: ${rename(name)};`).join("\n")}
|
|
|
561
562
|
? `[${type.fields?.filter((f) => usage.has(f.name.value)).map((v) => `"${v.name.value}"`).join(", ")}]`
|
|
562
563
|
: "[]"}`).join(",\n")},\n} as const;`);
|
|
563
564
|
}
|
|
565
|
+
// Generate types for fragments
|
|
566
|
+
const fragmentTypes = Object.entries(fragments).map(([fragmentName, fragment]) => {
|
|
567
|
+
const fragmentSelections = getSelectionsType(fragment.typeCondition.name.value, fragment.selectionSet.selections, types, fragments, references, includeTypenames);
|
|
568
|
+
const fragmentFields = fragmentSelections.reduce((fields, [name, type]) => {
|
|
569
|
+
fields[name] = type;
|
|
570
|
+
return fields;
|
|
571
|
+
}, {});
|
|
572
|
+
// Add __typename for object types
|
|
573
|
+
const baseTypeDef = types[fragment.typeCondition.name.value];
|
|
574
|
+
if (includeTypenames && baseTypeDef?.[0].kind === "ObjectTypeDefinition") {
|
|
575
|
+
Object.defineProperty(fragmentFields, "__typename", {
|
|
576
|
+
enumerable: true,
|
|
577
|
+
value: {
|
|
578
|
+
kind: "StringLiteral",
|
|
579
|
+
value: fragment.typeCondition.name.value,
|
|
580
|
+
optional: false,
|
|
581
|
+
},
|
|
582
|
+
});
|
|
583
|
+
}
|
|
584
|
+
return [
|
|
585
|
+
fragmentName,
|
|
586
|
+
{
|
|
587
|
+
kind: "Object",
|
|
588
|
+
value: fragmentFields,
|
|
589
|
+
optional: false,
|
|
590
|
+
},
|
|
591
|
+
[...new Set(fragmentSelections.map(([name]) => name))]
|
|
592
|
+
];
|
|
593
|
+
});
|
|
594
|
+
if (fragmentTypes.length) {
|
|
595
|
+
serializedTypes.unshift(...fragmentTypes.map(([name, type, _fields]) => `${exports.includes("types") ? "export " : ""}type ${name} = ${serializeType(type, false)};`).filter(filterOutputTypes));
|
|
596
|
+
// Update Types export to include fragments
|
|
597
|
+
const typesIndex = serializedTypes.findIndex(line => line?.startsWith("export type Types = {"));
|
|
598
|
+
if (typesIndex !== -1) {
|
|
599
|
+
const existingTypesExport = serializedTypes[typesIndex];
|
|
600
|
+
const updatedTypesExport = existingTypesExport.replace("export type Types = {", `export type Types = {
|
|
601
|
+
${fragmentTypes.map(([name]) => ` ${name}: ${name};`).join("\n")}${usedTypes.length ? "\n" : ""}`);
|
|
602
|
+
serializedTypes[typesIndex] = updatedTypesExport;
|
|
603
|
+
}
|
|
604
|
+
// Update types const export to include fragments
|
|
605
|
+
const typesConstIndex = serializedTypes.findIndex(line => line?.startsWith("export const types = {"));
|
|
606
|
+
if (typesConstIndex !== -1) {
|
|
607
|
+
const existingTypesConstExport = serializedTypes[typesConstIndex];
|
|
608
|
+
const fragmentTypesConst = fragmentTypes.map(([name, , fields]) => ` ${name}: [${fields.map(f => `"${f}"`).join(", ")}]`).join(",\n");
|
|
609
|
+
const updatedTypesConstExport = existingTypesConstExport.replace("export const types = {", `export const types = {
|
|
610
|
+
${fragmentTypesConst}${usedTypes.length && fragmentTypes.length ? "," : ""}${usedTypes.length ? "\n" : ""}`);
|
|
611
|
+
serializedTypes[typesConstIndex] = updatedTypesConstExport;
|
|
612
|
+
}
|
|
613
|
+
}
|
|
564
614
|
const usedReferences = Object.values(references).filter((r) => r[1]).map((r) => r[0]);
|
|
565
615
|
serializedTypes.unshift(...usedReferences.map((r) => {
|
|
566
616
|
// TODO: warn if missing and use unknown instead
|
package/esm/init.js
CHANGED
|
@@ -56,7 +56,7 @@ const getOperationContent = (path, operationName) => {
|
|
|
56
56
|
// Helper: Unwraps non-null and list wrappers to get the named type.
|
|
57
57
|
const getNamedType = (type) => type.kind === Kind.NAMED_TYPE ? type.name.value : getNamedType(type.type);
|
|
58
58
|
// Helper: Find a type definition in the document by name.
|
|
59
|
-
const getTypeDef = (
|
|
59
|
+
const getTypeDef = (definitions, typeName) => definitions.find((def) => "name" in def && def.name?.value === typeName);
|
|
60
60
|
/**
|
|
61
61
|
* Initialize the data builder.
|
|
62
62
|
* @param schema The plain text of your schema.
|
|
@@ -69,6 +69,32 @@ const getTypeDef = (doc, typeName) => doc.definitions.find((def) => "name" in de
|
|
|
69
69
|
*/
|
|
70
70
|
export const init = (schema, queries, mutations, subscriptions, types, inputs, scalars, options) => (fn) => {
|
|
71
71
|
const doc = parse(schema);
|
|
72
|
+
// Collect all fragment definitions from operation files
|
|
73
|
+
const fragmentDefinitions = [];
|
|
74
|
+
const collectFragments = (filePath, operationName) => {
|
|
75
|
+
try {
|
|
76
|
+
// If we have an operation name, use it; otherwise try to parse the file directly
|
|
77
|
+
let document;
|
|
78
|
+
if (operationName) {
|
|
79
|
+
document = getOperationContent(filePath, operationName);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
// Parse the file directly to get all definitions including fragments
|
|
83
|
+
const fileContent = loadFile(filePath);
|
|
84
|
+
document = parse(fileContent);
|
|
85
|
+
}
|
|
86
|
+
fragmentDefinitions.push(...document.definitions.filter((def) => def.kind === Kind.FRAGMENT_DEFINITION));
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
// Ignore files that can't be parsed
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
// Collect fragments from all operation files (parse entire files to get all fragments)
|
|
93
|
+
Object.values(queries).forEach(path => collectFragments(path));
|
|
94
|
+
Object.values(mutations).forEach(path => collectFragments(path));
|
|
95
|
+
Object.values(subscriptions).forEach(path => collectFragments(path));
|
|
96
|
+
// Combine schema definitions with fragment definitions
|
|
97
|
+
const allDefinitions = [...doc.definitions, ...fragmentDefinitions];
|
|
72
98
|
const build = {};
|
|
73
99
|
const transforms = fn(build);
|
|
74
100
|
const addObjectTransforms = (type, obj) => {
|
|
@@ -94,7 +120,7 @@ export const init = (schema, queries, mutations, subscriptions, types, inputs, s
|
|
|
94
120
|
const fields = types[type];
|
|
95
121
|
if (!fields)
|
|
96
122
|
return;
|
|
97
|
-
const typeDef = getTypeDef(
|
|
123
|
+
const typeDef = getTypeDef(allDefinitions, type);
|
|
98
124
|
if (!typeDef || !("fields" in typeDef))
|
|
99
125
|
return;
|
|
100
126
|
const selectionSet = {
|
|
@@ -113,7 +139,7 @@ export const init = (schema, queries, mutations, subscriptions, types, inputs, s
|
|
|
113
139
|
if (fieldDef) {
|
|
114
140
|
// Get the inner (named) type of the field.
|
|
115
141
|
const fieldTypeName = getNamedType(fieldDef.type);
|
|
116
|
-
const fieldTypeDef = getTypeDef(
|
|
142
|
+
const fieldTypeDef = getTypeDef(allDefinitions, fieldTypeName);
|
|
117
143
|
// If the field is an Object, build its selection set recursively.
|
|
118
144
|
if (fieldTypeDef &&
|
|
119
145
|
fieldTypeDef.kind === Kind.OBJECT_TYPE_DEFINITION) {
|
|
@@ -123,7 +149,7 @@ export const init = (schema, queries, mutations, subscriptions, types, inputs, s
|
|
|
123
149
|
} // If the field is an Interface, treat it like a union:
|
|
124
150
|
// find all Object types that implement this interface and build inline fragments.
|
|
125
151
|
else if (fieldTypeDef?.kind === Kind.INTERFACE_TYPE_DEFINITION) {
|
|
126
|
-
const implementingTypes =
|
|
152
|
+
const implementingTypes = allDefinitions.filter((def) => def.kind === Kind.OBJECT_TYPE_DEFINITION &&
|
|
127
153
|
(def.interfaces?.some((iface) => iface.name.value === fieldTypeName) ?? false));
|
|
128
154
|
const inlineFragments = implementingTypes.map((impl) => ({
|
|
129
155
|
kind: Kind.INLINE_FRAGMENT,
|
|
@@ -164,7 +190,7 @@ export const init = (schema, queries, mutations, subscriptions, types, inputs, s
|
|
|
164
190
|
});
|
|
165
191
|
return selectionSet;
|
|
166
192
|
};
|
|
167
|
-
const wrap = (type, patches) => withGetDefaultPatch((type) => transforms[type]?.default, () => toObject(_proxy(
|
|
193
|
+
const wrap = (type, patches) => withGetDefaultPatch((type) => transforms[type]?.default, () => toObject(_proxy(allDefinitions, scalars, type, patches, {
|
|
168
194
|
selectionSet: getSelectionSet(type),
|
|
169
195
|
})));
|
|
170
196
|
const objectBuilder = (type) => addObjectTransforms(type, (...patches) => {
|
|
@@ -274,7 +300,7 @@ export const init = (schema, queries, mutations, subscriptions, types, inputs, s
|
|
|
274
300
|
patches = [transforms[name].default, ...patches];
|
|
275
301
|
}
|
|
276
302
|
const { mock, parsedQuery } = withGetDefaultPatch((type) => transforms[type]?.default, () => {
|
|
277
|
-
const { request: { query: parsedQuery, ...request }, ...raw } = operation(
|
|
303
|
+
const { request: { query: parsedQuery, ...request }, ...raw } = operation(allDefinitions, scalars, query, ...patches);
|
|
278
304
|
const mock = toObject({
|
|
279
305
|
request: { ...request },
|
|
280
306
|
...raw,
|
package/esm/proxy.js
CHANGED
|
@@ -43,10 +43,24 @@ const resolveType = (definitions, path) => {
|
|
|
43
43
|
name: { kind: Kind.NAME, value: name },
|
|
44
44
|
};
|
|
45
45
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
// Check if this is a fragment type
|
|
47
|
+
if (!definition) {
|
|
48
|
+
const fragment = definitions.find((d) => d.kind === Kind.FRAGMENT_DEFINITION && d.name.value === name);
|
|
49
|
+
if (fragment) {
|
|
50
|
+
// Use the fragment definition directly
|
|
51
|
+
definition = fragment;
|
|
52
|
+
type = {
|
|
53
|
+
kind: Kind.NON_NULL_TYPE,
|
|
54
|
+
type: { kind: Kind.NAMED_TYPE, name: { kind: Kind.NAME, value: name } },
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (!type) {
|
|
59
|
+
type = {
|
|
60
|
+
kind: Kind.NON_NULL_TYPE,
|
|
61
|
+
type: { kind: Kind.NAMED_TYPE, name: { kind: Kind.NAME, value: name } },
|
|
62
|
+
};
|
|
63
|
+
}
|
|
50
64
|
}
|
|
51
65
|
else {
|
|
52
66
|
parent = definition.name.value;
|
|
@@ -594,6 +608,15 @@ export const _proxy = (definitions, scalars, path, patches, { prev, resolvedType
|
|
|
594
608
|
return prev;
|
|
595
609
|
return definition.values?.[0]?.name.value;
|
|
596
610
|
}
|
|
611
|
+
case Kind.FRAGMENT_DEFINITION: {
|
|
612
|
+
// For fragments, create a proxy for the base type with the fragment's selection set
|
|
613
|
+
const baseTypeName = definition.typeCondition.name.value;
|
|
614
|
+
return _proxy(definitions, scalars, baseTypeName, patches, {
|
|
615
|
+
prev,
|
|
616
|
+
selectionSet: definition.selectionSet,
|
|
617
|
+
nonNull: true,
|
|
618
|
+
});
|
|
619
|
+
}
|
|
597
620
|
default:
|
|
598
621
|
throw new Error(`Unhandled definition kind '${definition.kind}'`);
|
|
599
622
|
}
|
package/package.json
CHANGED
package/script/codegen.js
CHANGED
|
@@ -181,6 +181,7 @@ const getSelectionsType = (name, selections, definitions, fragments, references,
|
|
|
181
181
|
if (!fragment) {
|
|
182
182
|
throw new Error(`Could not find fragment '${selection.name.value}' in '${name}'`);
|
|
183
183
|
}
|
|
184
|
+
// Fragment is automatically considered used
|
|
184
185
|
selectionTypes.push(...getSelectionsType(fragment.typeCondition.name.value, fragment.selectionSet.selections, definitions, fragments, references, includeTypenames).map(([name, type, group]) => [
|
|
185
186
|
name,
|
|
186
187
|
type,
|
|
@@ -567,6 +568,55 @@ ${usedTypes.map(([name]) => ` ${name}: ${rename(name)};`).join("\n")}
|
|
|
567
568
|
? `[${type.fields?.filter((f) => usage.has(f.name.value)).map((v) => `"${v.name.value}"`).join(", ")}]`
|
|
568
569
|
: "[]"}`).join(",\n")},\n} as const;`);
|
|
569
570
|
}
|
|
571
|
+
// Generate types for fragments
|
|
572
|
+
const fragmentTypes = Object.entries(fragments).map(([fragmentName, fragment]) => {
|
|
573
|
+
const fragmentSelections = getSelectionsType(fragment.typeCondition.name.value, fragment.selectionSet.selections, types, fragments, references, includeTypenames);
|
|
574
|
+
const fragmentFields = fragmentSelections.reduce((fields, [name, type]) => {
|
|
575
|
+
fields[name] = type;
|
|
576
|
+
return fields;
|
|
577
|
+
}, {});
|
|
578
|
+
// Add __typename for object types
|
|
579
|
+
const baseTypeDef = types[fragment.typeCondition.name.value];
|
|
580
|
+
if (includeTypenames && baseTypeDef?.[0].kind === "ObjectTypeDefinition") {
|
|
581
|
+
Object.defineProperty(fragmentFields, "__typename", {
|
|
582
|
+
enumerable: true,
|
|
583
|
+
value: {
|
|
584
|
+
kind: "StringLiteral",
|
|
585
|
+
value: fragment.typeCondition.name.value,
|
|
586
|
+
optional: false,
|
|
587
|
+
},
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
return [
|
|
591
|
+
fragmentName,
|
|
592
|
+
{
|
|
593
|
+
kind: "Object",
|
|
594
|
+
value: fragmentFields,
|
|
595
|
+
optional: false,
|
|
596
|
+
},
|
|
597
|
+
[...new Set(fragmentSelections.map(([name]) => name))]
|
|
598
|
+
];
|
|
599
|
+
});
|
|
600
|
+
if (fragmentTypes.length) {
|
|
601
|
+
serializedTypes.unshift(...fragmentTypes.map(([name, type, _fields]) => `${exports.includes("types") ? "export " : ""}type ${name} = ${serializeType(type, false)};`).filter(filterOutputTypes));
|
|
602
|
+
// Update Types export to include fragments
|
|
603
|
+
const typesIndex = serializedTypes.findIndex(line => line?.startsWith("export type Types = {"));
|
|
604
|
+
if (typesIndex !== -1) {
|
|
605
|
+
const existingTypesExport = serializedTypes[typesIndex];
|
|
606
|
+
const updatedTypesExport = existingTypesExport.replace("export type Types = {", `export type Types = {
|
|
607
|
+
${fragmentTypes.map(([name]) => ` ${name}: ${name};`).join("\n")}${usedTypes.length ? "\n" : ""}`);
|
|
608
|
+
serializedTypes[typesIndex] = updatedTypesExport;
|
|
609
|
+
}
|
|
610
|
+
// Update types const export to include fragments
|
|
611
|
+
const typesConstIndex = serializedTypes.findIndex(line => line?.startsWith("export const types = {"));
|
|
612
|
+
if (typesConstIndex !== -1) {
|
|
613
|
+
const existingTypesConstExport = serializedTypes[typesConstIndex];
|
|
614
|
+
const fragmentTypesConst = fragmentTypes.map(([name, , fields]) => ` ${name}: [${fields.map(f => `"${f}"`).join(", ")}]`).join(",\n");
|
|
615
|
+
const updatedTypesConstExport = existingTypesConstExport.replace("export const types = {", `export const types = {
|
|
616
|
+
${fragmentTypesConst}${usedTypes.length && fragmentTypes.length ? "," : ""}${usedTypes.length ? "\n" : ""}`);
|
|
617
|
+
serializedTypes[typesConstIndex] = updatedTypesConstExport;
|
|
618
|
+
}
|
|
619
|
+
}
|
|
570
620
|
const usedReferences = Object.values(references).filter((r) => r[1]).map((r) => r[0]);
|
|
571
621
|
serializedTypes.unshift(...usedReferences.map((r) => {
|
|
572
622
|
// TODO: warn if missing and use unknown instead
|
package/script/init.js
CHANGED
|
@@ -82,7 +82,7 @@ const getOperationContent = (path, operationName) => {
|
|
|
82
82
|
// Helper: Unwraps non-null and list wrappers to get the named type.
|
|
83
83
|
const getNamedType = (type) => type.kind === graphql_1.Kind.NAMED_TYPE ? type.name.value : getNamedType(type.type);
|
|
84
84
|
// Helper: Find a type definition in the document by name.
|
|
85
|
-
const getTypeDef = (
|
|
85
|
+
const getTypeDef = (definitions, typeName) => definitions.find((def) => "name" in def && def.name?.value === typeName);
|
|
86
86
|
/**
|
|
87
87
|
* Initialize the data builder.
|
|
88
88
|
* @param schema The plain text of your schema.
|
|
@@ -95,6 +95,32 @@ const getTypeDef = (doc, typeName) => doc.definitions.find((def) => "name" in de
|
|
|
95
95
|
*/
|
|
96
96
|
const init = (schema, queries, mutations, subscriptions, types, inputs, scalars, options) => (fn) => {
|
|
97
97
|
const doc = (0, graphql_1.parse)(schema);
|
|
98
|
+
// Collect all fragment definitions from operation files
|
|
99
|
+
const fragmentDefinitions = [];
|
|
100
|
+
const collectFragments = (filePath, operationName) => {
|
|
101
|
+
try {
|
|
102
|
+
// If we have an operation name, use it; otherwise try to parse the file directly
|
|
103
|
+
let document;
|
|
104
|
+
if (operationName) {
|
|
105
|
+
document = getOperationContent(filePath, operationName);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
// Parse the file directly to get all definitions including fragments
|
|
109
|
+
const fileContent = loadFile(filePath);
|
|
110
|
+
document = (0, graphql_1.parse)(fileContent);
|
|
111
|
+
}
|
|
112
|
+
fragmentDefinitions.push(...document.definitions.filter((def) => def.kind === graphql_1.Kind.FRAGMENT_DEFINITION));
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
// Ignore files that can't be parsed
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
// Collect fragments from all operation files (parse entire files to get all fragments)
|
|
119
|
+
Object.values(queries).forEach(path => collectFragments(path));
|
|
120
|
+
Object.values(mutations).forEach(path => collectFragments(path));
|
|
121
|
+
Object.values(subscriptions).forEach(path => collectFragments(path));
|
|
122
|
+
// Combine schema definitions with fragment definitions
|
|
123
|
+
const allDefinitions = [...doc.definitions, ...fragmentDefinitions];
|
|
98
124
|
const build = {};
|
|
99
125
|
const transforms = fn(build);
|
|
100
126
|
const addObjectTransforms = (type, obj) => {
|
|
@@ -120,7 +146,7 @@ const init = (schema, queries, mutations, subscriptions, types, inputs, scalars,
|
|
|
120
146
|
const fields = types[type];
|
|
121
147
|
if (!fields)
|
|
122
148
|
return;
|
|
123
|
-
const typeDef = getTypeDef(
|
|
149
|
+
const typeDef = getTypeDef(allDefinitions, type);
|
|
124
150
|
if (!typeDef || !("fields" in typeDef))
|
|
125
151
|
return;
|
|
126
152
|
const selectionSet = {
|
|
@@ -139,7 +165,7 @@ const init = (schema, queries, mutations, subscriptions, types, inputs, scalars,
|
|
|
139
165
|
if (fieldDef) {
|
|
140
166
|
// Get the inner (named) type of the field.
|
|
141
167
|
const fieldTypeName = getNamedType(fieldDef.type);
|
|
142
|
-
const fieldTypeDef = getTypeDef(
|
|
168
|
+
const fieldTypeDef = getTypeDef(allDefinitions, fieldTypeName);
|
|
143
169
|
// If the field is an Object, build its selection set recursively.
|
|
144
170
|
if (fieldTypeDef &&
|
|
145
171
|
fieldTypeDef.kind === graphql_1.Kind.OBJECT_TYPE_DEFINITION) {
|
|
@@ -149,7 +175,7 @@ const init = (schema, queries, mutations, subscriptions, types, inputs, scalars,
|
|
|
149
175
|
} // If the field is an Interface, treat it like a union:
|
|
150
176
|
// find all Object types that implement this interface and build inline fragments.
|
|
151
177
|
else if (fieldTypeDef?.kind === graphql_1.Kind.INTERFACE_TYPE_DEFINITION) {
|
|
152
|
-
const implementingTypes =
|
|
178
|
+
const implementingTypes = allDefinitions.filter((def) => def.kind === graphql_1.Kind.OBJECT_TYPE_DEFINITION &&
|
|
153
179
|
(def.interfaces?.some((iface) => iface.name.value === fieldTypeName) ?? false));
|
|
154
180
|
const inlineFragments = implementingTypes.map((impl) => ({
|
|
155
181
|
kind: graphql_1.Kind.INLINE_FRAGMENT,
|
|
@@ -190,7 +216,7 @@ const init = (schema, queries, mutations, subscriptions, types, inputs, scalars,
|
|
|
190
216
|
});
|
|
191
217
|
return selectionSet;
|
|
192
218
|
};
|
|
193
|
-
const wrap = (type, patches) => (0, proxy_js_1.withGetDefaultPatch)((type) => transforms[type]?.default, () => (0, util_js_1.toObject)((0, proxy_js_1._proxy)(
|
|
219
|
+
const wrap = (type, patches) => (0, proxy_js_1.withGetDefaultPatch)((type) => transforms[type]?.default, () => (0, util_js_1.toObject)((0, proxy_js_1._proxy)(allDefinitions, scalars, type, patches, {
|
|
194
220
|
selectionSet: getSelectionSet(type),
|
|
195
221
|
})));
|
|
196
222
|
const objectBuilder = (type) => addObjectTransforms(type, (...patches) => {
|
|
@@ -300,7 +326,7 @@ const init = (schema, queries, mutations, subscriptions, types, inputs, scalars,
|
|
|
300
326
|
patches = [transforms[name].default, ...patches];
|
|
301
327
|
}
|
|
302
328
|
const { mock, parsedQuery } = (0, proxy_js_1.withGetDefaultPatch)((type) => transforms[type]?.default, () => {
|
|
303
|
-
const { request: { query: parsedQuery, ...request }, ...raw } = (0, proxy_js_1.operation)(
|
|
329
|
+
const { request: { query: parsedQuery, ...request }, ...raw } = (0, proxy_js_1.operation)(allDefinitions, scalars, query, ...patches);
|
|
304
330
|
const mock = (0, util_js_1.toObject)({
|
|
305
331
|
request: { ...request },
|
|
306
332
|
...raw,
|
package/script/proxy.js
CHANGED
|
@@ -47,10 +47,24 @@ const resolveType = (definitions, path) => {
|
|
|
47
47
|
name: { kind: graphql_1.Kind.NAME, value: name },
|
|
48
48
|
};
|
|
49
49
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
// Check if this is a fragment type
|
|
51
|
+
if (!definition) {
|
|
52
|
+
const fragment = definitions.find((d) => d.kind === graphql_1.Kind.FRAGMENT_DEFINITION && d.name.value === name);
|
|
53
|
+
if (fragment) {
|
|
54
|
+
// Use the fragment definition directly
|
|
55
|
+
definition = fragment;
|
|
56
|
+
type = {
|
|
57
|
+
kind: graphql_1.Kind.NON_NULL_TYPE,
|
|
58
|
+
type: { kind: graphql_1.Kind.NAMED_TYPE, name: { kind: graphql_1.Kind.NAME, value: name } },
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (!type) {
|
|
63
|
+
type = {
|
|
64
|
+
kind: graphql_1.Kind.NON_NULL_TYPE,
|
|
65
|
+
type: { kind: graphql_1.Kind.NAMED_TYPE, name: { kind: graphql_1.Kind.NAME, value: name } },
|
|
66
|
+
};
|
|
67
|
+
}
|
|
54
68
|
}
|
|
55
69
|
else {
|
|
56
70
|
parent = definition.name.value;
|
|
@@ -598,6 +612,15 @@ const _proxy = (definitions, scalars, path, patches, { prev, resolvedType = reso
|
|
|
598
612
|
return prev;
|
|
599
613
|
return definition.values?.[0]?.name.value;
|
|
600
614
|
}
|
|
615
|
+
case graphql_1.Kind.FRAGMENT_DEFINITION: {
|
|
616
|
+
// For fragments, create a proxy for the base type with the fragment's selection set
|
|
617
|
+
const baseTypeName = definition.typeCondition.name.value;
|
|
618
|
+
return (0, exports._proxy)(definitions, scalars, baseTypeName, patches, {
|
|
619
|
+
prev,
|
|
620
|
+
selectionSet: definition.selectionSet,
|
|
621
|
+
nonNull: true,
|
|
622
|
+
});
|
|
623
|
+
}
|
|
601
624
|
default:
|
|
602
625
|
throw new Error(`Unhandled definition kind '${definition.kind}'`);
|
|
603
626
|
}
|