@nmarks/graphql-codegen-per-operation-file-preset 1.0.4 → 1.0.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/cjs/index.js +61 -8
- package/esm/index.js +61 -8
- package/package.json +1 -1
package/cjs/index.js
CHANGED
|
@@ -38,14 +38,19 @@ function needsSchemaTypesImport(document, schema, config) {
|
|
|
38
38
|
let needsImport = false;
|
|
39
39
|
// Get scalar mappings from config
|
|
40
40
|
const scalarMappings = config.scalars || {};
|
|
41
|
-
// Check if document has
|
|
42
|
-
|
|
41
|
+
// Check if document has an operation definition
|
|
42
|
+
// ALL operations (query/mutation/subscription) generate a Variables type that uses Types.Exact
|
|
43
|
+
// even if they have no variables: Types.Exact<{ [key: string]: never; }>
|
|
44
|
+
let hasOperation = false;
|
|
43
45
|
// Collect all type names referenced in the document
|
|
44
46
|
const referencedTypeNames = new Set();
|
|
45
47
|
(0, graphql_1.visit)(document, {
|
|
48
|
+
// Operations always need Types import for their Variables type
|
|
49
|
+
OperationDefinition: () => {
|
|
50
|
+
hasOperation = true;
|
|
51
|
+
},
|
|
46
52
|
// Check variable types for input types or custom scalars
|
|
47
53
|
VariableDefinition: (node) => {
|
|
48
|
-
hasVariables = true; // Any variable means we need Types import
|
|
49
54
|
const typeName = getBaseTypeName(node.type);
|
|
50
55
|
referencedTypeNames.add(typeName);
|
|
51
56
|
},
|
|
@@ -54,8 +59,8 @@ function needsSchemaTypesImport(document, schema, config) {
|
|
|
54
59
|
referencedTypeNames.add(node.typeCondition.name.value);
|
|
55
60
|
},
|
|
56
61
|
});
|
|
57
|
-
//
|
|
58
|
-
if (
|
|
62
|
+
// All operations generate Variables type that uses Types.Exact
|
|
63
|
+
if (hasOperation) {
|
|
59
64
|
return true;
|
|
60
65
|
}
|
|
61
66
|
// Helper to recursively check if a type needs importing
|
|
@@ -180,17 +185,65 @@ exports.preset = {
|
|
|
180
185
|
document: singleDefDocument,
|
|
181
186
|
location: source.documents[0].location,
|
|
182
187
|
};
|
|
188
|
+
// Find other fragments in the same source file (they are "local" now but will be "external" after split)
|
|
189
|
+
const localFragments = definitions
|
|
190
|
+
.filter(d => d.definition.kind === graphql_1.Kind.FRAGMENT_DEFINITION && d.name !== name)
|
|
191
|
+
.map(d => d.definition);
|
|
192
|
+
// Add local fragments to external fragments list so they're available during generation
|
|
193
|
+
const localFragmentNodes = localFragments.map(frag => ({
|
|
194
|
+
level: 0,
|
|
195
|
+
isExternal: true,
|
|
196
|
+
name: frag.name.value,
|
|
197
|
+
onType: frag.typeCondition.name.value,
|
|
198
|
+
node: frag,
|
|
199
|
+
}));
|
|
200
|
+
const allExternalFragments = [
|
|
201
|
+
...source.externalFragments,
|
|
202
|
+
...localFragmentNodes,
|
|
203
|
+
];
|
|
183
204
|
// Update fragment imports to use the correct output path for this operation
|
|
184
205
|
const updatedFragmentImports = source.fragmentImports.map(fragmentImport => ({
|
|
185
206
|
...fragmentImport,
|
|
186
207
|
outputPath: filename, // Update to actual output path
|
|
187
208
|
}));
|
|
209
|
+
// Generate fragment imports for local fragments (they'll be in separate files after splitting)
|
|
210
|
+
const localFragmentImports = localFragments.map((frag) => {
|
|
211
|
+
var _a;
|
|
212
|
+
const fragmentFilePath = (0, utils_js_1.generateOperationFilePath)(source.documents[0].location, frag.name.value, folder, extension);
|
|
213
|
+
// Get fragment import identifiers (document + type)
|
|
214
|
+
const identifiers = [
|
|
215
|
+
{
|
|
216
|
+
name: `${frag.name.value}FragmentDoc`,
|
|
217
|
+
kind: 'document',
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
name: `${frag.name.value}Fragment`,
|
|
221
|
+
kind: 'type',
|
|
222
|
+
},
|
|
223
|
+
];
|
|
224
|
+
return {
|
|
225
|
+
baseDir,
|
|
226
|
+
baseOutputDir: options.baseOutputDir,
|
|
227
|
+
outputPath: filename,
|
|
228
|
+
importSource: {
|
|
229
|
+
path: fragmentFilePath,
|
|
230
|
+
identifiers,
|
|
231
|
+
},
|
|
232
|
+
emitLegacyCommonJSImports: options.config.emitLegacyCommonJSImports,
|
|
233
|
+
importExtension: options.config.importExtension,
|
|
234
|
+
typesImport: (_a = options.config.useTypeImports) !== null && _a !== void 0 ? _a : false,
|
|
235
|
+
};
|
|
236
|
+
});
|
|
237
|
+
const allFragmentImports = [
|
|
238
|
+
...updatedFragmentImports,
|
|
239
|
+
...localFragmentImports,
|
|
240
|
+
];
|
|
188
241
|
// Check if THIS specific operation uses types (not the whole source file)
|
|
189
242
|
const singleDefDocumentWithFragments = {
|
|
190
243
|
...singleDefDocument,
|
|
191
244
|
definitions: [
|
|
192
245
|
...singleDefDocument.definitions,
|
|
193
|
-
...
|
|
246
|
+
...allExternalFragments.map(fragment => fragment.node),
|
|
194
247
|
],
|
|
195
248
|
};
|
|
196
249
|
const needsTypesImport = needsSchemaTypesImport(singleDefDocumentWithFragments, schemaObject, options.config);
|
|
@@ -221,8 +274,8 @@ exports.preset = {
|
|
|
221
274
|
...options.config,
|
|
222
275
|
exportFragmentSpreadSubTypes: true,
|
|
223
276
|
namespacedImportName: importTypesNamespace,
|
|
224
|
-
externalFragments:
|
|
225
|
-
fragmentImports:
|
|
277
|
+
externalFragments: allExternalFragments,
|
|
278
|
+
fragmentImports: allFragmentImports,
|
|
226
279
|
};
|
|
227
280
|
artifacts.push({
|
|
228
281
|
...options,
|
package/esm/index.js
CHANGED
|
@@ -34,14 +34,19 @@ function needsSchemaTypesImport(document, schema, config) {
|
|
|
34
34
|
let needsImport = false;
|
|
35
35
|
// Get scalar mappings from config
|
|
36
36
|
const scalarMappings = config.scalars || {};
|
|
37
|
-
// Check if document has
|
|
38
|
-
|
|
37
|
+
// Check if document has an operation definition
|
|
38
|
+
// ALL operations (query/mutation/subscription) generate a Variables type that uses Types.Exact
|
|
39
|
+
// even if they have no variables: Types.Exact<{ [key: string]: never; }>
|
|
40
|
+
let hasOperation = false;
|
|
39
41
|
// Collect all type names referenced in the document
|
|
40
42
|
const referencedTypeNames = new Set();
|
|
41
43
|
visit(document, {
|
|
44
|
+
// Operations always need Types import for their Variables type
|
|
45
|
+
OperationDefinition: () => {
|
|
46
|
+
hasOperation = true;
|
|
47
|
+
},
|
|
42
48
|
// Check variable types for input types or custom scalars
|
|
43
49
|
VariableDefinition: (node) => {
|
|
44
|
-
hasVariables = true; // Any variable means we need Types import
|
|
45
50
|
const typeName = getBaseTypeName(node.type);
|
|
46
51
|
referencedTypeNames.add(typeName);
|
|
47
52
|
},
|
|
@@ -50,8 +55,8 @@ function needsSchemaTypesImport(document, schema, config) {
|
|
|
50
55
|
referencedTypeNames.add(node.typeCondition.name.value);
|
|
51
56
|
},
|
|
52
57
|
});
|
|
53
|
-
//
|
|
54
|
-
if (
|
|
58
|
+
// All operations generate Variables type that uses Types.Exact
|
|
59
|
+
if (hasOperation) {
|
|
55
60
|
return true;
|
|
56
61
|
}
|
|
57
62
|
// Helper to recursively check if a type needs importing
|
|
@@ -176,17 +181,65 @@ export const preset = {
|
|
|
176
181
|
document: singleDefDocument,
|
|
177
182
|
location: source.documents[0].location,
|
|
178
183
|
};
|
|
184
|
+
// Find other fragments in the same source file (they are "local" now but will be "external" after split)
|
|
185
|
+
const localFragments = definitions
|
|
186
|
+
.filter(d => d.definition.kind === Kind.FRAGMENT_DEFINITION && d.name !== name)
|
|
187
|
+
.map(d => d.definition);
|
|
188
|
+
// Add local fragments to external fragments list so they're available during generation
|
|
189
|
+
const localFragmentNodes = localFragments.map(frag => ({
|
|
190
|
+
level: 0,
|
|
191
|
+
isExternal: true,
|
|
192
|
+
name: frag.name.value,
|
|
193
|
+
onType: frag.typeCondition.name.value,
|
|
194
|
+
node: frag,
|
|
195
|
+
}));
|
|
196
|
+
const allExternalFragments = [
|
|
197
|
+
...source.externalFragments,
|
|
198
|
+
...localFragmentNodes,
|
|
199
|
+
];
|
|
179
200
|
// Update fragment imports to use the correct output path for this operation
|
|
180
201
|
const updatedFragmentImports = source.fragmentImports.map(fragmentImport => ({
|
|
181
202
|
...fragmentImport,
|
|
182
203
|
outputPath: filename, // Update to actual output path
|
|
183
204
|
}));
|
|
205
|
+
// Generate fragment imports for local fragments (they'll be in separate files after splitting)
|
|
206
|
+
const localFragmentImports = localFragments.map((frag) => {
|
|
207
|
+
var _a;
|
|
208
|
+
const fragmentFilePath = generateOperationFilePath(source.documents[0].location, frag.name.value, folder, extension);
|
|
209
|
+
// Get fragment import identifiers (document + type)
|
|
210
|
+
const identifiers = [
|
|
211
|
+
{
|
|
212
|
+
name: `${frag.name.value}FragmentDoc`,
|
|
213
|
+
kind: 'document',
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
name: `${frag.name.value}Fragment`,
|
|
217
|
+
kind: 'type',
|
|
218
|
+
},
|
|
219
|
+
];
|
|
220
|
+
return {
|
|
221
|
+
baseDir,
|
|
222
|
+
baseOutputDir: options.baseOutputDir,
|
|
223
|
+
outputPath: filename,
|
|
224
|
+
importSource: {
|
|
225
|
+
path: fragmentFilePath,
|
|
226
|
+
identifiers,
|
|
227
|
+
},
|
|
228
|
+
emitLegacyCommonJSImports: options.config.emitLegacyCommonJSImports,
|
|
229
|
+
importExtension: options.config.importExtension,
|
|
230
|
+
typesImport: (_a = options.config.useTypeImports) !== null && _a !== void 0 ? _a : false,
|
|
231
|
+
};
|
|
232
|
+
});
|
|
233
|
+
const allFragmentImports = [
|
|
234
|
+
...updatedFragmentImports,
|
|
235
|
+
...localFragmentImports,
|
|
236
|
+
];
|
|
184
237
|
// Check if THIS specific operation uses types (not the whole source file)
|
|
185
238
|
const singleDefDocumentWithFragments = {
|
|
186
239
|
...singleDefDocument,
|
|
187
240
|
definitions: [
|
|
188
241
|
...singleDefDocument.definitions,
|
|
189
|
-
...
|
|
242
|
+
...allExternalFragments.map(fragment => fragment.node),
|
|
190
243
|
],
|
|
191
244
|
};
|
|
192
245
|
const needsTypesImport = needsSchemaTypesImport(singleDefDocumentWithFragments, schemaObject, options.config);
|
|
@@ -217,8 +270,8 @@ export const preset = {
|
|
|
217
270
|
...options.config,
|
|
218
271
|
exportFragmentSpreadSubTypes: true,
|
|
219
272
|
namespacedImportName: importTypesNamespace,
|
|
220
|
-
externalFragments:
|
|
221
|
-
fragmentImports:
|
|
273
|
+
externalFragments: allExternalFragments,
|
|
274
|
+
fragmentImports: allFragmentImports,
|
|
222
275
|
};
|
|
223
276
|
artifacts.push({
|
|
224
277
|
...options,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nmarks/graphql-codegen-per-operation-file-preset",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "GraphQL Code Generator preset for generating one file per operation/fragment",
|
|
5
5
|
"peerDependencies": {
|
|
6
6
|
"graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
|