@nmarks/graphql-codegen-per-operation-file-preset 1.0.1 → 1.0.2
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 +82 -2
- package/esm/index.js +83 -3
- package/package.json +1 -1
package/cjs/index.js
CHANGED
|
@@ -5,7 +5,6 @@ const tslib_1 = require("tslib");
|
|
|
5
5
|
const path_1 = require("path");
|
|
6
6
|
const graphql_1 = require("graphql");
|
|
7
7
|
const add_1 = tslib_1.__importDefault(require("@graphql-codegen/add"));
|
|
8
|
-
const plugin_helpers_1 = require("@graphql-codegen/plugin-helpers");
|
|
9
8
|
const visitor_plugin_common_1 = require("@graphql-codegen/visitor-plugin-common");
|
|
10
9
|
const resolve_document_imports_js_1 = require("./resolve-document-imports.js");
|
|
11
10
|
const utils_js_1 = require("./utils.js");
|
|
@@ -24,6 +23,87 @@ function extractDefinitions(document) {
|
|
|
24
23
|
}
|
|
25
24
|
return definitions;
|
|
26
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Check if a document actually needs type imports from the schema.
|
|
28
|
+
* Only returns true if the document uses:
|
|
29
|
+
* - Enums
|
|
30
|
+
* - Custom scalars (not built-in)
|
|
31
|
+
* - Input types (in variables)
|
|
32
|
+
*
|
|
33
|
+
* Does NOT return true for just referencing object types.
|
|
34
|
+
*/
|
|
35
|
+
function needsSchemaTypesImport(document, schema) {
|
|
36
|
+
const builtInScalars = ['String', 'Int', 'Float', 'Boolean', 'ID'];
|
|
37
|
+
let needsImport = false;
|
|
38
|
+
// Collect all type names referenced in the document
|
|
39
|
+
const referencedTypeNames = new Set();
|
|
40
|
+
(0, graphql_1.visit)(document, {
|
|
41
|
+
// Check variable types for input types or custom scalars
|
|
42
|
+
VariableDefinition: (node) => {
|
|
43
|
+
const typeName = getBaseTypeName(node.type);
|
|
44
|
+
referencedTypeNames.add(typeName);
|
|
45
|
+
},
|
|
46
|
+
// Collect fragment type conditions
|
|
47
|
+
FragmentDefinition: (node) => {
|
|
48
|
+
referencedTypeNames.add(node.typeCondition.name.value);
|
|
49
|
+
},
|
|
50
|
+
// We need to traverse into nested fields, so we'll collect all types
|
|
51
|
+
// This is a simplified approach - we'll check all types that might be used
|
|
52
|
+
});
|
|
53
|
+
// Helper to recursively check if a type needs importing
|
|
54
|
+
const checkType = (type) => {
|
|
55
|
+
if (!type)
|
|
56
|
+
return false;
|
|
57
|
+
// Unwrap lists and non-null
|
|
58
|
+
while ('ofType' in type && type.ofType) {
|
|
59
|
+
type = type.ofType;
|
|
60
|
+
}
|
|
61
|
+
// Enums need to be imported
|
|
62
|
+
if ((0, graphql_1.isEnumType)(type)) {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
// Custom scalars (not built-in) need to be imported
|
|
66
|
+
if ((0, graphql_1.isScalarType)(type) && !builtInScalars.includes(type.name)) {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
// Input types need to be imported
|
|
70
|
+
if ((0, graphql_1.isInputObjectType)(type)) {
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
return false;
|
|
74
|
+
};
|
|
75
|
+
// Check variable types
|
|
76
|
+
for (const typeName of referencedTypeNames) {
|
|
77
|
+
const type = schema.getType(typeName);
|
|
78
|
+
if (checkType(type)) {
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// Now we need to check all fields in the document to see if any return enums/custom scalars
|
|
83
|
+
// We'll do a more thorough traversal with TypeInfo
|
|
84
|
+
const typeInfo = new graphql_1.TypeInfo(schema);
|
|
85
|
+
(0, graphql_1.visit)(document, (0, graphql_1.visitWithTypeInfo)(typeInfo, {
|
|
86
|
+
Field: () => {
|
|
87
|
+
const fieldType = typeInfo.getType();
|
|
88
|
+
if (checkType(fieldType)) {
|
|
89
|
+
needsImport = true;
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
}));
|
|
93
|
+
return needsImport;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Extract the base type name from a type node
|
|
97
|
+
*/
|
|
98
|
+
function getBaseTypeName(type) {
|
|
99
|
+
if (type.kind === 'NamedType') {
|
|
100
|
+
return type.name.value;
|
|
101
|
+
}
|
|
102
|
+
if (type.kind === 'ListType' || type.kind === 'NonNullType') {
|
|
103
|
+
return getBaseTypeName(type.type);
|
|
104
|
+
}
|
|
105
|
+
return '';
|
|
106
|
+
}
|
|
27
107
|
exports.preset = {
|
|
28
108
|
buildGeneratesSection: options => {
|
|
29
109
|
var _a, _b;
|
|
@@ -84,7 +164,7 @@ exports.preset = {
|
|
|
84
164
|
...source.externalFragments.map(fragment => fragment.node),
|
|
85
165
|
],
|
|
86
166
|
};
|
|
87
|
-
const needsTypesImport = (
|
|
167
|
+
const needsTypesImport = needsSchemaTypesImport(singleDefDocumentWithFragments, schemaObject);
|
|
88
168
|
// Generate the types import statement if needed
|
|
89
169
|
const importStatements = [];
|
|
90
170
|
if (needsTypesImport && !options.config.globalNamespace) {
|
package/esm/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { join } from 'path';
|
|
2
|
-
import { buildASTSchema, Kind } from 'graphql';
|
|
2
|
+
import { buildASTSchema, isEnumType, isInputObjectType, isScalarType, Kind, TypeInfo, visit, visitWithTypeInfo } from 'graphql';
|
|
3
3
|
import addPlugin from '@graphql-codegen/add';
|
|
4
|
-
import { isUsingTypes } from '@graphql-codegen/plugin-helpers';
|
|
5
4
|
import { generateImportStatement, getConfigValue, resolveImportSource, } from '@graphql-codegen/visitor-plugin-common';
|
|
6
5
|
import { resolveDocumentImports } from './resolve-document-imports.js';
|
|
7
6
|
import { generateOperationFilePath } from './utils.js';
|
|
@@ -20,6 +19,87 @@ function extractDefinitions(document) {
|
|
|
20
19
|
}
|
|
21
20
|
return definitions;
|
|
22
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Check if a document actually needs type imports from the schema.
|
|
24
|
+
* Only returns true if the document uses:
|
|
25
|
+
* - Enums
|
|
26
|
+
* - Custom scalars (not built-in)
|
|
27
|
+
* - Input types (in variables)
|
|
28
|
+
*
|
|
29
|
+
* Does NOT return true for just referencing object types.
|
|
30
|
+
*/
|
|
31
|
+
function needsSchemaTypesImport(document, schema) {
|
|
32
|
+
const builtInScalars = ['String', 'Int', 'Float', 'Boolean', 'ID'];
|
|
33
|
+
let needsImport = false;
|
|
34
|
+
// Collect all type names referenced in the document
|
|
35
|
+
const referencedTypeNames = new Set();
|
|
36
|
+
visit(document, {
|
|
37
|
+
// Check variable types for input types or custom scalars
|
|
38
|
+
VariableDefinition: (node) => {
|
|
39
|
+
const typeName = getBaseTypeName(node.type);
|
|
40
|
+
referencedTypeNames.add(typeName);
|
|
41
|
+
},
|
|
42
|
+
// Collect fragment type conditions
|
|
43
|
+
FragmentDefinition: (node) => {
|
|
44
|
+
referencedTypeNames.add(node.typeCondition.name.value);
|
|
45
|
+
},
|
|
46
|
+
// We need to traverse into nested fields, so we'll collect all types
|
|
47
|
+
// This is a simplified approach - we'll check all types that might be used
|
|
48
|
+
});
|
|
49
|
+
// Helper to recursively check if a type needs importing
|
|
50
|
+
const checkType = (type) => {
|
|
51
|
+
if (!type)
|
|
52
|
+
return false;
|
|
53
|
+
// Unwrap lists and non-null
|
|
54
|
+
while ('ofType' in type && type.ofType) {
|
|
55
|
+
type = type.ofType;
|
|
56
|
+
}
|
|
57
|
+
// Enums need to be imported
|
|
58
|
+
if (isEnumType(type)) {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
// Custom scalars (not built-in) need to be imported
|
|
62
|
+
if (isScalarType(type) && !builtInScalars.includes(type.name)) {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
// Input types need to be imported
|
|
66
|
+
if (isInputObjectType(type)) {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
return false;
|
|
70
|
+
};
|
|
71
|
+
// Check variable types
|
|
72
|
+
for (const typeName of referencedTypeNames) {
|
|
73
|
+
const type = schema.getType(typeName);
|
|
74
|
+
if (checkType(type)) {
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// Now we need to check all fields in the document to see if any return enums/custom scalars
|
|
79
|
+
// We'll do a more thorough traversal with TypeInfo
|
|
80
|
+
const typeInfo = new TypeInfo(schema);
|
|
81
|
+
visit(document, visitWithTypeInfo(typeInfo, {
|
|
82
|
+
Field: () => {
|
|
83
|
+
const fieldType = typeInfo.getType();
|
|
84
|
+
if (checkType(fieldType)) {
|
|
85
|
+
needsImport = true;
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
}));
|
|
89
|
+
return needsImport;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Extract the base type name from a type node
|
|
93
|
+
*/
|
|
94
|
+
function getBaseTypeName(type) {
|
|
95
|
+
if (type.kind === 'NamedType') {
|
|
96
|
+
return type.name.value;
|
|
97
|
+
}
|
|
98
|
+
if (type.kind === 'ListType' || type.kind === 'NonNullType') {
|
|
99
|
+
return getBaseTypeName(type.type);
|
|
100
|
+
}
|
|
101
|
+
return '';
|
|
102
|
+
}
|
|
23
103
|
export const preset = {
|
|
24
104
|
buildGeneratesSection: options => {
|
|
25
105
|
var _a, _b;
|
|
@@ -80,7 +160,7 @@ export const preset = {
|
|
|
80
160
|
...source.externalFragments.map(fragment => fragment.node),
|
|
81
161
|
],
|
|
82
162
|
};
|
|
83
|
-
const needsTypesImport =
|
|
163
|
+
const needsTypesImport = needsSchemaTypesImport(singleDefDocumentWithFragments, schemaObject);
|
|
84
164
|
// Generate the types import statement if needed
|
|
85
165
|
const importStatements = [];
|
|
86
166
|
if (needsTypesImport && !options.config.globalNamespace) {
|
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.2",
|
|
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"
|