@baeta/plugin-graphql 1.0.9 → 2.0.0-next.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/dist/index.js +670 -1040
- package/dist/index.js.map +1 -1
- package/package.json +16 -33
- package/CHANGELOG.md +0 -383
- package/dist/index.d.ts +0 -5
package/dist/index.js
CHANGED
|
@@ -1,54 +1,24 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __export = (target, all) => {
|
|
3
|
-
for (var name in all)
|
|
4
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5
|
-
};
|
|
6
|
-
|
|
7
1
|
// index.ts
|
|
8
2
|
import { createPluginV1, isMatch } from "@baeta/generator-sdk";
|
|
9
3
|
|
|
10
4
|
// lib/codegen.ts
|
|
11
5
|
import { join as join2 } from "@baeta/util-path";
|
|
12
|
-
import {
|
|
13
|
-
import { normalizeConfig, normalizeInstanceOrArray } from "@graphql-codegen/plugin-helpers";
|
|
14
|
-
import * as typescriptPlugin from "@graphql-codegen/typescript";
|
|
15
|
-
|
|
16
|
-
// utils/cache.ts
|
|
17
|
-
function createCache() {
|
|
18
|
-
const cache = /* @__PURE__ */ new Map();
|
|
19
|
-
return function ensure(namespace, key, factory) {
|
|
20
|
-
const cacheKey = `${namespace}:${key}`;
|
|
21
|
-
const cachedValue = cache.get(cacheKey);
|
|
22
|
-
if (cachedValue) {
|
|
23
|
-
return cachedValue;
|
|
24
|
-
}
|
|
25
|
-
const value = factory();
|
|
26
|
-
cache.set(cacheKey, value);
|
|
27
|
-
return value;
|
|
28
|
-
};
|
|
29
|
-
}
|
|
6
|
+
import { concatAST } from "graphql";
|
|
30
7
|
|
|
31
8
|
// utils/load.ts
|
|
32
|
-
import { getCachedDocumentNodeFromSchema as getCachedDocumentNodeFromSchema2 } from "@graphql-codegen/plugin-helpers";
|
|
33
9
|
import { GraphQLFileLoader } from "@graphql-tools/graphql-file-loader";
|
|
34
10
|
import {
|
|
35
11
|
loadSchema as loadSchemaToolkit
|
|
36
12
|
} from "@graphql-tools/load";
|
|
13
|
+
import {
|
|
14
|
+
getDocumentNodeFromSchema
|
|
15
|
+
} from "@graphql-tools/utils";
|
|
37
16
|
import { validateSchema } from "graphql";
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
function hashContent(content) {
|
|
44
|
-
return createHash("sha256").update(content).digest("hex");
|
|
45
|
-
}
|
|
46
|
-
function hashSchema(schema) {
|
|
47
|
-
return hashContent(print(getCachedDocumentNodeFromSchema(schema)));
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// utils/load.ts
|
|
51
|
-
async function loadSchema(schemaPointerMap, cwd, extraLoaders = []) {
|
|
17
|
+
async function loadSchema(schemas, cwd, extraLoaders = []) {
|
|
18
|
+
const schemaPointerMap = {};
|
|
19
|
+
for (const ptr of Array.isArray(schemas) ? schemas : [schemas]) {
|
|
20
|
+
schemaPointerMap[ptr] = {};
|
|
21
|
+
}
|
|
52
22
|
const outputSchemaAst = await loadSchemaToolkit(schemaPointerMap, {
|
|
53
23
|
loaders: [new GraphQLFileLoader(), ...extraLoaders],
|
|
54
24
|
cwd,
|
|
@@ -65,1090 +35,750 @@ ${messages}`);
|
|
|
65
35
|
if (!outputSchemaAst.extensions) {
|
|
66
36
|
outputSchemaAst.extensions = {};
|
|
67
37
|
}
|
|
68
|
-
outputSchemaAst.extensions.hash = hashSchema(outputSchemaAst);
|
|
69
38
|
return {
|
|
70
39
|
outputSchemaAst,
|
|
71
|
-
outputSchema:
|
|
40
|
+
outputSchema: getDocumentNodeFromSchema(outputSchemaAst)
|
|
72
41
|
};
|
|
73
42
|
}
|
|
74
43
|
|
|
75
|
-
// utils/
|
|
76
|
-
import
|
|
77
|
-
|
|
78
|
-
function
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
44
|
+
// utils/path.ts
|
|
45
|
+
import path, { normalize } from "@baeta/util-path";
|
|
46
|
+
var sep = "/";
|
|
47
|
+
function getRelativePath(filepath, basePath) {
|
|
48
|
+
const normalizedFilepath = normalize(filepath);
|
|
49
|
+
const normalizedBasePath = ensureStartsWithSeparator(
|
|
50
|
+
ensureEndsWithSeparator(normalize(basePath))
|
|
51
|
+
);
|
|
52
|
+
const [, relativePath] = normalizedFilepath.split(normalizedBasePath);
|
|
53
|
+
return relativePath;
|
|
54
|
+
}
|
|
55
|
+
function extractModuleDirectory(relativePath) {
|
|
56
|
+
const [moduleDirectory] = relativePath.split(sep);
|
|
57
|
+
return moduleDirectory;
|
|
58
|
+
}
|
|
59
|
+
function ensureStartsWithSeparator(path2) {
|
|
60
|
+
return path2.startsWith(sep) ? path2 : sep + path2;
|
|
61
|
+
}
|
|
62
|
+
function ensureEndsWithSeparator(path2) {
|
|
63
|
+
return path2.endsWith(sep) ? path2 : path2 + sep;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// utils/source.ts
|
|
67
|
+
function groupSourcesByModule(sources, basePath) {
|
|
68
|
+
const map = /* @__PURE__ */ new Map();
|
|
69
|
+
for (const source of sources) {
|
|
70
|
+
if (!source.location) {
|
|
91
71
|
continue;
|
|
92
72
|
}
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
if (mapped.default) {
|
|
96
|
-
fixedMap[key] = `${relativePath}#default`;
|
|
73
|
+
const relativePath = getRelativePath(source.location, basePath);
|
|
74
|
+
if (!relativePath) {
|
|
97
75
|
continue;
|
|
98
76
|
}
|
|
99
|
-
|
|
77
|
+
const mod = extractModuleDirectory(relativePath);
|
|
78
|
+
const existing = map.get(mod) ?? [];
|
|
79
|
+
existing.push(source);
|
|
80
|
+
map.set(mod, existing);
|
|
100
81
|
}
|
|
101
|
-
return
|
|
82
|
+
return map;
|
|
83
|
+
}
|
|
84
|
+
function getSourcesFromSchema(schema) {
|
|
85
|
+
const extensions = schema.extensions;
|
|
86
|
+
return extensions?.extendedSources ?? [];
|
|
102
87
|
}
|
|
103
88
|
|
|
104
|
-
// lib/
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
mapper.source,
|
|
118
|
-
[
|
|
119
|
-
{
|
|
120
|
-
identifier,
|
|
121
|
-
asDefault: mapper.default
|
|
122
|
-
}
|
|
123
|
-
],
|
|
124
|
-
true
|
|
125
|
-
);
|
|
126
|
-
if (result) {
|
|
127
|
-
prepend.push(result);
|
|
128
|
-
}
|
|
129
|
-
} else {
|
|
130
|
-
prepend.push(`type ContextType = ${mapper.type}`);
|
|
131
|
-
}
|
|
132
|
-
prepend.push("export type { ContextType }");
|
|
133
|
-
return {
|
|
134
|
-
content: "",
|
|
135
|
-
prepend
|
|
136
|
-
};
|
|
137
|
-
};
|
|
138
|
-
var context_default = { plugin };
|
|
139
|
-
|
|
140
|
-
// lib/modules/index.ts
|
|
141
|
-
import { basename, join, relative as relative2, resolve } from "@baeta/util-path";
|
|
142
|
-
import { BaseVisitor, getConfigValue } from "@graphql-codegen/visitor-plugin-common";
|
|
143
|
-
import {
|
|
144
|
-
concatAST,
|
|
145
|
-
isScalarType as isScalarType2
|
|
146
|
-
} from "graphql";
|
|
89
|
+
// lib/printer/printer-autoload.ts
|
|
90
|
+
import { camelCase } from "change-case-all";
|
|
91
|
+
function printAutoload(config, modules) {
|
|
92
|
+
return [printImports(config, modules), printExport(modules)].join("\n\n");
|
|
93
|
+
}
|
|
94
|
+
function printImports(config, modules) {
|
|
95
|
+
return modules.map(
|
|
96
|
+
(module) => `import ${camelCase(module)} from "./${module}/index${config.importExtension}"`
|
|
97
|
+
).join("\n");
|
|
98
|
+
}
|
|
99
|
+
function printExport(modules) {
|
|
100
|
+
return `export default [${modules.map((m) => camelCase(m)).join(", ")}];`;
|
|
101
|
+
}
|
|
147
102
|
|
|
148
|
-
// lib/
|
|
103
|
+
// lib/printer/printer-module.ts
|
|
104
|
+
import { join, relative } from "@baeta/util-path";
|
|
149
105
|
import { pascalCase } from "change-case-all";
|
|
150
|
-
import {
|
|
151
|
-
Kind as Kind3,
|
|
152
|
-
isInterfaceType,
|
|
153
|
-
isScalarType,
|
|
154
|
-
isUnionType,
|
|
155
|
-
visit
|
|
156
|
-
} from "graphql";
|
|
157
106
|
|
|
158
|
-
// lib/
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
} from "graphql";
|
|
162
|
-
import hash from "murmurhash";
|
|
163
|
-
function getObjectTypeHash(node) {
|
|
164
|
-
const fieldNames = buildFieldsNames(node.fields);
|
|
165
|
-
const typeFields = fieldNames.map(([fieldName, fieldType]) => `${fieldName}:${fieldType}`).join(",");
|
|
166
|
-
const fieldMap = {};
|
|
167
|
-
for (const [fieldName, fieldType] of fieldNames) {
|
|
168
|
-
fieldMap[fieldName] = hash.v3(fieldType).toString(36);
|
|
169
|
-
}
|
|
170
|
-
return {
|
|
171
|
-
hash: hash.v3(typeFields).toString(36),
|
|
172
|
-
fieldsHashes: fieldMap
|
|
173
|
-
};
|
|
107
|
+
// lib/printer/printer-utils.ts
|
|
108
|
+
function buildBlock({ name, lines }) {
|
|
109
|
+
return [`${name} {`, ...lines.filter(Boolean).map(indent(2)), "};"].join("\n");
|
|
174
110
|
}
|
|
175
|
-
function
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
}
|
|
179
|
-
const fieldsNames = [];
|
|
180
|
-
for (const field of fields) {
|
|
181
|
-
const fieldName = field.name.value;
|
|
182
|
-
const fieldType = buildTypeName(field.type);
|
|
183
|
-
fieldsNames.push([fieldName, fieldType]);
|
|
184
|
-
}
|
|
185
|
-
return fieldsNames.sort(([a], [b]) => a.localeCompare(b));
|
|
111
|
+
function buildCodeBlock({ name, lines }) {
|
|
112
|
+
const linesWithSep = lines.filter(Boolean).map(indent(2)).join(",\n");
|
|
113
|
+
return [`${name} {`, linesWithSep, "}"].join("\n");
|
|
186
114
|
}
|
|
187
|
-
function
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
if (node.kind === Kind.LIST_TYPE) {
|
|
192
|
-
return `[${buildTypeName(node.type)}]`;
|
|
193
|
-
}
|
|
194
|
-
if (node.kind === Kind.NON_NULL_TYPE) {
|
|
195
|
-
return `${buildTypeName(node.type)}!`;
|
|
115
|
+
function indent(size) {
|
|
116
|
+
const space = new Array(size).fill(" ").join("");
|
|
117
|
+
function indentInner(val) {
|
|
118
|
+
return val.split("\n").map((line) => `${space}${line}`).join("\n");
|
|
196
119
|
}
|
|
197
|
-
return
|
|
120
|
+
return indentInner;
|
|
198
121
|
}
|
|
199
122
|
|
|
200
|
-
// lib/
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
import {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
import
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
123
|
+
// lib/printer/printer-module.ts
|
|
124
|
+
function printModuleImports(config, moduleName) {
|
|
125
|
+
const typesDir = relative(join(config.modulesDir, moduleName), config.typesDir);
|
|
126
|
+
return [
|
|
127
|
+
'import type { DocumentNode, GraphQLScalarType } from "graphql";',
|
|
128
|
+
'import * as Baeta from "@baeta/core/sdk";',
|
|
129
|
+
`import extensions from "../extensions${config.importExtension}";`,
|
|
130
|
+
`import type {Ctx, Info} from "../types${config.importExtension}";`,
|
|
131
|
+
`import * as Types from "${typesDir}/types${config.importExtension}";`
|
|
132
|
+
].join("\n");
|
|
133
|
+
}
|
|
134
|
+
function printModuleMetadata(name, doc) {
|
|
135
|
+
return buildCodeBlock({
|
|
136
|
+
name: "const moduleMetadata =",
|
|
137
|
+
lines: [
|
|
138
|
+
`id: '${name}'`,
|
|
139
|
+
`dirname: './${name}'`,
|
|
140
|
+
`typedef: ${JSON.stringify(doc)} as unknown as DocumentNode`
|
|
141
|
+
]
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
function printBaetaModuleTypes(config) {
|
|
145
|
+
return buildBlock({
|
|
146
|
+
name: "interface BaetaModuleTypes",
|
|
147
|
+
lines: [
|
|
148
|
+
buildBlock({
|
|
149
|
+
name: "Builders:",
|
|
150
|
+
lines: printBaetaModuleTypesForFields(config, false)
|
|
151
|
+
}),
|
|
152
|
+
buildBlock({
|
|
153
|
+
name: "Factories:",
|
|
154
|
+
lines: [
|
|
155
|
+
...printBaetaModuleTypesForFields(config, true),
|
|
156
|
+
...printBaetaModuleTypesScalars(config)
|
|
157
|
+
]
|
|
158
|
+
})
|
|
159
|
+
]
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
function printBaetaModuleTypesForFields(config, isFactory) {
|
|
163
|
+
return config.registry.defined.objects.map(
|
|
164
|
+
(typeName) => printObjectTypeModuleType(typeName, config.registry.picks.objects, isFactory)
|
|
165
|
+
).filter(Boolean);
|
|
166
|
+
}
|
|
167
|
+
function printObjectTypeModuleType(typeName, objects, isFactory) {
|
|
168
|
+
const object = objects[typeName];
|
|
169
|
+
if (!object) {
|
|
170
|
+
return "";
|
|
213
171
|
}
|
|
214
|
-
|
|
215
|
-
|
|
172
|
+
const parentType = getParentType(typeName);
|
|
173
|
+
const contextType = getContextType();
|
|
174
|
+
const infoType = getInfoType();
|
|
175
|
+
if (isFactory) {
|
|
176
|
+
return `${typeName}: Baeta.TypeCompilerFactory<${parentType}, ${contextType}, ${infoType}, BaetaModuleObjectTypeFields['${typeName}']['Factory']>`;
|
|
216
177
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
findRelated(_interface);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
} else if (node.kind === Kind2.INPUT_OBJECT_TYPE_DEFINITION || node.kind === Kind2.INPUT_OBJECT_TYPE_EXTENSION) {
|
|
231
|
-
markAsUsed(node.name.value);
|
|
232
|
-
if (node.fields) {
|
|
233
|
-
for (const field of node.fields) {
|
|
234
|
-
findRelated(field);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
} else if (node.kind === Kind2.INTERFACE_TYPE_DEFINITION || node.kind === Kind2.INTERFACE_TYPE_EXTENSION) {
|
|
238
|
-
markAsUsed(node.name.value);
|
|
239
|
-
if (node.fields) {
|
|
240
|
-
for (const field of node.fields) {
|
|
241
|
-
findRelated(field);
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
if (node.interfaces) {
|
|
245
|
-
for (const _interface of node.interfaces) {
|
|
246
|
-
findRelated(_interface);
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
} else if (node.kind === Kind2.UNION_TYPE_DEFINITION || node.kind === Kind2.UNION_TYPE_EXTENSION) {
|
|
250
|
-
markAsUsed(node.name.value);
|
|
251
|
-
if (node.types) {
|
|
252
|
-
for (const type of node.types) {
|
|
253
|
-
findRelated(type);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
} else if (node.kind === Kind2.ENUM_TYPE_DEFINITION || node.kind === Kind2.ENUM_TYPE_EXTENSION) {
|
|
257
|
-
markAsUsed(node.name.value);
|
|
258
|
-
} else if (node.kind === Kind2.SCALAR_TYPE_DEFINITION || node.kind === Kind2.SCALAR_TYPE_EXTENSION) {
|
|
259
|
-
if (!isGraphQLPrimitive(node.name.value)) {
|
|
260
|
-
markAsUsed(node.name.value);
|
|
261
|
-
}
|
|
262
|
-
} else if (node.kind === Kind2.INPUT_VALUE_DEFINITION) {
|
|
263
|
-
findRelated(resolveTypeNode(node.type));
|
|
264
|
-
} else if (node.kind === Kind2.FIELD_DEFINITION) {
|
|
265
|
-
findRelated(resolveTypeNode(node.type));
|
|
266
|
-
if (node.arguments) {
|
|
267
|
-
for (const argument of node.arguments) {
|
|
268
|
-
findRelated(argument);
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
} else if (node.kind === Kind2.NAMED_TYPE && // Named type
|
|
272
|
-
!isGraphQLPrimitive(node.name.value)) {
|
|
273
|
-
markAsUsed(node.name.value);
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
return used;
|
|
277
|
-
}
|
|
278
|
-
function collectObjectFieldType(node, fieldDefinition, fieldsMap, fieldTypes) {
|
|
279
|
-
const objectName = node.name.value;
|
|
280
|
-
const fieldName = fieldDefinition.name.value;
|
|
281
|
-
const field = fieldsMap[fieldDefinition.name.value];
|
|
282
|
-
const baseName = getBaseType(field.type).name;
|
|
283
|
-
const isDefaultScalar = DEFAULT_SCALARS[baseName] != null;
|
|
284
|
-
const name = isDefaultScalar ? `Types.Scalars["${baseName}"]["output"]` : baseName;
|
|
285
|
-
const type = wrapTypeWithModifiers(name, field.type, {
|
|
286
|
-
wrapOptional: (str) => {
|
|
287
|
-
return `Types.Maybe<${str}>`;
|
|
288
|
-
},
|
|
289
|
-
wrapArray: (str) => {
|
|
290
|
-
return `Array<${str}>`;
|
|
291
|
-
}
|
|
178
|
+
return `${typeName}: Baeta.TypeMethods<${parentType}, ${contextType}, ${infoType}, BaetaModuleObjectTypeFields['${typeName}']['Builder'], BaetaModuleObjectTypeFields['${typeName}']['Factory']>`;
|
|
179
|
+
}
|
|
180
|
+
function printBaetaModuleTypesScalars(config) {
|
|
181
|
+
return config.registry.defined.scalars.map((scalar) => `${scalar}: GraphQLScalarType`);
|
|
182
|
+
}
|
|
183
|
+
function printModuleObjectTypeFields(config) {
|
|
184
|
+
const objects = config.registry.defined.objects.map((typeName) => printObjectTypeFields(config, typeName, config.registry.picks.objects)).filter(Boolean);
|
|
185
|
+
return buildBlock({
|
|
186
|
+
name: "interface BaetaModuleObjectTypeFields",
|
|
187
|
+
lines: objects
|
|
292
188
|
});
|
|
293
|
-
|
|
294
|
-
|
|
189
|
+
}
|
|
190
|
+
function printObjectTypeFields(config, typeName, objects) {
|
|
191
|
+
const fields = objects[typeName];
|
|
192
|
+
if (!fields || fields.length === 0) {
|
|
193
|
+
return "";
|
|
295
194
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
const
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
195
|
+
const fieldsBuilders = fields.map(
|
|
196
|
+
(field) => printObjectTypeFieldBuilders(config, typeName, field)
|
|
197
|
+
);
|
|
198
|
+
const fieldsFactories = fields.map(
|
|
199
|
+
(field) => printObjectTypeFieldFactories(config, typeName, field)
|
|
200
|
+
);
|
|
201
|
+
return buildBlock({
|
|
202
|
+
name: `${typeName}:`,
|
|
203
|
+
lines: [
|
|
204
|
+
buildBlock({
|
|
205
|
+
name: "Builder:",
|
|
206
|
+
lines: fieldsBuilders
|
|
207
|
+
}),
|
|
208
|
+
buildBlock({
|
|
209
|
+
name: "Factory:",
|
|
210
|
+
lines: fieldsFactories
|
|
211
|
+
})
|
|
212
|
+
]
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
function printObjectTypeFieldBuilders(config, typeName, field) {
|
|
216
|
+
const parentType = getParentType(typeName);
|
|
217
|
+
const resultType = getResultType(config, typeName, field);
|
|
218
|
+
const argumentsType = getArgsType(config, typeName, field);
|
|
219
|
+
const contextType = getContextType();
|
|
220
|
+
const infoType = getInfoType();
|
|
221
|
+
const namespace = typeName === "Subscription" ? "SubscriptionMethods" : "FieldMethods";
|
|
222
|
+
return `${field}: Baeta.${namespace}<${resultType}, ${parentType}, ${contextType}, ${argumentsType}, ${infoType}>`;
|
|
223
|
+
}
|
|
224
|
+
function printObjectTypeFieldFactories(config, typeName, field) {
|
|
225
|
+
const parentType = getParentType(typeName);
|
|
226
|
+
const resultType = getResultType(config, typeName, field);
|
|
227
|
+
const argumentsType = getArgsType(config, typeName, field);
|
|
228
|
+
const contextType = getContextType();
|
|
229
|
+
const infoType = getInfoType();
|
|
230
|
+
const namespace = typeName === "Subscription" ? "SubscriptionField" : "Field";
|
|
231
|
+
return `${field}: Baeta.${namespace}<${resultType}, ${resultType}, ${parentType}, ${contextType}, ${argumentsType}, ${infoType}>`;
|
|
232
|
+
}
|
|
233
|
+
function printModuleBuilder(config, moduleName) {
|
|
234
|
+
const objectTypes = config.registry.defined.objects.map((typeName) => printObjectTypeBuilder(typeName, config.registry.picks.objects)).filter(Boolean);
|
|
235
|
+
const builders = buildCodeBlock({
|
|
236
|
+
name: "",
|
|
237
|
+
lines: objectTypes
|
|
238
|
+
});
|
|
239
|
+
const typeNameResolvers = buildCodeBlock({
|
|
240
|
+
name: "",
|
|
241
|
+
lines: [...config.registry.defined.unions, ...config.registry.defined.interfaces].map(
|
|
242
|
+
(name) => `${name}: ${printTypeNameResolver()}`
|
|
243
|
+
)
|
|
244
|
+
});
|
|
245
|
+
const infoType = getInfoType();
|
|
246
|
+
const contextType = getContextType();
|
|
247
|
+
return [
|
|
248
|
+
`export const ${pascalCase(moduleName)}Module = Baeta.createModuleBuilder<${contextType}, ${infoType}, BaetaModuleTypes['Builders'], BaetaModuleTypes['Factories']>(moduleMetadata.id, moduleMetadata.typedef,`,
|
|
249
|
+
builders,
|
|
250
|
+
",",
|
|
251
|
+
typeNameResolvers,
|
|
252
|
+
`, ${getExtensionsVar()});`
|
|
253
|
+
].join("");
|
|
254
|
+
}
|
|
255
|
+
function printObjectTypeBuilder(typeName, objects) {
|
|
256
|
+
const fields = objects[typeName]?.map((field) => printObjectTypeFieldBuilder(typeName, field));
|
|
257
|
+
if (fields == null || fields.length === 0) {
|
|
258
|
+
return "";
|
|
304
259
|
}
|
|
305
|
-
|
|
260
|
+
const content = buildCodeBlock({
|
|
261
|
+
name: "",
|
|
262
|
+
lines: fields
|
|
263
|
+
});
|
|
264
|
+
return `${typeName}: Baeta.createTypeBuilder("${typeName}",${content}, ${getExtensionsVar()})`;
|
|
306
265
|
}
|
|
307
|
-
function
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
266
|
+
function printTypeNameResolver() {
|
|
267
|
+
return "{ __resolveType: (source: {__typename: string}) => { return source.__typename; }}";
|
|
268
|
+
}
|
|
269
|
+
function getParentType(type) {
|
|
270
|
+
if (["Query", "Mutation", "Subscription"].includes(type)) {
|
|
271
|
+
return "{}";
|
|
312
272
|
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
const fieldsMap = schemaType.getFields();
|
|
320
|
-
for (const field of type.astNode.fields ?? []) {
|
|
321
|
-
collectObjectFieldArguments(type.astNode, field, fieldArguments);
|
|
322
|
-
collectObjectFieldType(type.astNode, field, fieldsMap, fieldTypes);
|
|
323
|
-
}
|
|
273
|
+
return `Types.${type}`;
|
|
274
|
+
}
|
|
275
|
+
function getResultType(config, type, field) {
|
|
276
|
+
const fieldType = config.fieldInfo.get(type)?.get(field)?.type;
|
|
277
|
+
if (fieldType == null) {
|
|
278
|
+
return "{}";
|
|
324
279
|
}
|
|
325
|
-
return
|
|
280
|
+
return fieldType;
|
|
326
281
|
}
|
|
327
|
-
function
|
|
328
|
-
|
|
329
|
-
|
|
282
|
+
function getArgsType(config, type, field) {
|
|
283
|
+
const hasArgs = config.fieldInfo.get(type)?.get(field)?.hasArguments ?? false;
|
|
284
|
+
if (!hasArgs) {
|
|
285
|
+
return "{}";
|
|
330
286
|
}
|
|
331
|
-
|
|
332
|
-
|
|
287
|
+
const fieldUpper = field[0].toUpperCase() + field.slice(1);
|
|
288
|
+
return `Types.${type}${fieldUpper}Args`;
|
|
289
|
+
}
|
|
290
|
+
function printObjectTypeFieldBuilder(typeName, field) {
|
|
291
|
+
if (typeName === "Subscription") {
|
|
292
|
+
return `${field}: Baeta.createSubscriptionBuilder("${field}", ${getExtensionsVar()})`;
|
|
333
293
|
}
|
|
334
|
-
return
|
|
294
|
+
return `${field}: Baeta.createFieldBuilder("${typeName}", "${field}", ${getExtensionsVar()})`;
|
|
335
295
|
}
|
|
336
|
-
function
|
|
337
|
-
return
|
|
296
|
+
function getContextType() {
|
|
297
|
+
return "Ctx";
|
|
338
298
|
}
|
|
339
|
-
function
|
|
340
|
-
return
|
|
299
|
+
function getInfoType() {
|
|
300
|
+
return "Info";
|
|
341
301
|
}
|
|
342
|
-
function
|
|
343
|
-
return
|
|
302
|
+
function getExtensionsVar() {
|
|
303
|
+
return "extensions";
|
|
344
304
|
}
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
return
|
|
305
|
+
|
|
306
|
+
// lib/printer/printer-templates.ts
|
|
307
|
+
import { relative as relative2 } from "@baeta/util-path";
|
|
308
|
+
function printTypesTemplate(options) {
|
|
309
|
+
const importDir = relative2(options.modulesDir, options.typesDir);
|
|
310
|
+
return `import type { GraphQLResolveInfo } from 'graphql';
|
|
311
|
+
import type { BaseObjectTypes, BaseScalars } from '${importDir}/utility${options.importExtension}';
|
|
312
|
+
|
|
313
|
+
export interface Scalars extends BaseScalars {}
|
|
314
|
+
|
|
315
|
+
export interface ObjectTypes extends BaseObjectTypes {}
|
|
316
|
+
|
|
317
|
+
export type Ctx = {};
|
|
318
|
+
|
|
319
|
+
export type Info = GraphQLResolveInfo;
|
|
320
|
+
`;
|
|
351
321
|
}
|
|
352
|
-
function
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
322
|
+
function printExtensionsTemplate() {
|
|
323
|
+
return `import { createExtensions } from '@baeta/core';
|
|
324
|
+
|
|
325
|
+
export default createExtensions({});
|
|
326
|
+
`;
|
|
357
327
|
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
328
|
+
|
|
329
|
+
// lib/printer/printer-types.ts
|
|
330
|
+
import { pascalCase as pascalCase2 } from "change-case-all";
|
|
331
|
+
import {
|
|
332
|
+
Kind
|
|
333
|
+
} from "graphql";
|
|
334
|
+
|
|
335
|
+
// utils/scalar.ts
|
|
336
|
+
function isScalarType(definitionsMap, defaultScalars, type) {
|
|
337
|
+
return definitionsMap.scalarTypeMap.has(type.name.value) || defaultScalars.includes(type.name.value);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// lib/printer/printer-types.ts
|
|
341
|
+
function printUtilityTypes() {
|
|
342
|
+
return [
|
|
343
|
+
"export type Or<A, B> = void extends A ? B : A;",
|
|
344
|
+
"export type Maybe<T> = T | null;"
|
|
345
|
+
].join("\n\n");
|
|
346
|
+
}
|
|
347
|
+
var defaultScalarTypes = {
|
|
348
|
+
ID: "string",
|
|
349
|
+
String: "string",
|
|
350
|
+
Boolean: "boolean",
|
|
351
|
+
Int: "number",
|
|
352
|
+
Float: "number"
|
|
365
353
|
};
|
|
366
|
-
function
|
|
367
|
-
const
|
|
368
|
-
|
|
369
|
-
if (
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
354
|
+
function printBaseScalars(config) {
|
|
355
|
+
const defaultScalars = config.defaultScalars.map((scalar) => {
|
|
356
|
+
const type = defaultScalarTypes[scalar];
|
|
357
|
+
if (type == null) return null;
|
|
358
|
+
return `${scalar}: ${type};`;
|
|
359
|
+
}).filter((el) => el != null);
|
|
360
|
+
const customScalars = [...config.globalDefinitions.scalarTypeMap.values()].map(
|
|
361
|
+
(scalar) => `${scalar.name.value}: unknown;`
|
|
362
|
+
);
|
|
363
|
+
return buildBlock({
|
|
364
|
+
name: "export type BaseScalars =",
|
|
365
|
+
lines: [...defaultScalars, ...customScalars]
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
function printBaseObjectTypes(config) {
|
|
369
|
+
const objectTypes = [...config.globalDefinitions.objectTypeMap.values()].map((t) => t.name.value);
|
|
370
|
+
return buildBlock({
|
|
371
|
+
name: "export interface BaseObjectTypes",
|
|
372
|
+
lines: objectTypes.map((t) => `${t}: unknown;`)
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
function printTypesHeaders() {
|
|
376
|
+
return [
|
|
377
|
+
'import * as BaetaUtility from "./utility.ts";',
|
|
378
|
+
'import * as BaetaOverrides from "../modules/types.ts";',
|
|
379
|
+
"",
|
|
380
|
+
"export type Scalars = BaetaOverrides.Scalars;"
|
|
381
|
+
].join("\n");
|
|
382
|
+
}
|
|
383
|
+
function printRootTypesFromMap(config, rootTypes, map) {
|
|
384
|
+
return [...map.values()].filter((type) => rootTypes.includes(type.name.value)).map((type) => printObjectType(config, type)).join("\n\n");
|
|
385
|
+
}
|
|
386
|
+
function printObjectTypeTypesFromMap(config, map) {
|
|
387
|
+
return [...map.values()].map((type) => printObjectType(config, type));
|
|
388
|
+
}
|
|
389
|
+
function printObjectType(config, type) {
|
|
390
|
+
const fields = type.fields?.map((field) => printObjectTypeField(config, field));
|
|
391
|
+
return `export type ${type.name.value} = ${printOrObjectType(type, fields)}`;
|
|
392
|
+
}
|
|
393
|
+
function printObjectTypeField(config, field) {
|
|
394
|
+
const optionalMarker = printOptionalMarker(config, field.type);
|
|
395
|
+
return `${field.name.value}${optionalMarker}: ${printType(config, field.type)}`;
|
|
396
|
+
}
|
|
397
|
+
function printEnumTypesFromMap(map) {
|
|
398
|
+
return [...map.values()].map(printEnumType);
|
|
399
|
+
}
|
|
400
|
+
function printEnumType(type) {
|
|
401
|
+
const values = type.values?.map((value) => `'${value.name.value}'`);
|
|
402
|
+
return `export type ${type.name.value} = ${values?.join(" | ") || "never"}`;
|
|
403
|
+
}
|
|
404
|
+
function printInterfaceTypesFromMap(config, map) {
|
|
405
|
+
return [...map.values()].map((type) => printInterfaceType(config, type));
|
|
406
|
+
}
|
|
407
|
+
function printInterfaceType(config, type) {
|
|
408
|
+
const objectTypes = Array.from(config.globalDefinitions.objectTypeMap.values());
|
|
409
|
+
const implementingTypes = objectTypes.filter(
|
|
410
|
+
(t) => t.interfaces?.some((i) => i.name.value === type.name.value)
|
|
411
|
+
);
|
|
412
|
+
const types = implementingTypes.map((t) => printNamedTypeForInterface(t.name.value));
|
|
413
|
+
return `export type ${type.name.value} = ${types.join(" | ") || "never"}`;
|
|
414
|
+
}
|
|
415
|
+
function printNamedTypeForInterface(name) {
|
|
416
|
+
return `${name} & {__typename: "${name}"}`;
|
|
417
|
+
}
|
|
418
|
+
function printUnionTypesFromMap(config, map) {
|
|
419
|
+
return [...map.values()].map((type) => printUnionType(config, type));
|
|
420
|
+
}
|
|
421
|
+
function printUnionType(config, type) {
|
|
422
|
+
const types = type.types?.map((type2) => printNamedTypeForUnion(config, type2));
|
|
423
|
+
return `export type ${type.name.value} = ${types?.join(" | ") || "never"}`;
|
|
424
|
+
}
|
|
425
|
+
function printNamedTypeForUnion(config, type) {
|
|
426
|
+
return `${printNamedType(config, type, false)} & {__typename: "${type.name.value}"}`;
|
|
427
|
+
}
|
|
428
|
+
function printInputObjectTypeTypesFromMap(config, map) {
|
|
429
|
+
return [...map.values()].map((type) => printInputObjectType(config, type));
|
|
430
|
+
}
|
|
431
|
+
function printInputObjectType(config, type) {
|
|
432
|
+
const fields = type.fields?.map((field) => printInputObjectTypeField(config, field));
|
|
433
|
+
return buildBlock({
|
|
434
|
+
name: `export type ${type.name.value} =`,
|
|
435
|
+
lines: fields ?? []
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
function printInputObjectTypeField(config, field) {
|
|
439
|
+
const optionalMarker = printOptionalMarker(config, field.type);
|
|
440
|
+
return `${field.name.value}${optionalMarker}: ${printType(config, field.type)}`;
|
|
441
|
+
}
|
|
442
|
+
function printObjectTypeFieldsArgsFromMap(config, map) {
|
|
443
|
+
return [...map.values()].flatMap((type) => printObjectTypeArgs(config, type));
|
|
444
|
+
}
|
|
445
|
+
function printObjectTypeArgs(config, type) {
|
|
446
|
+
if (type.fields == null) {
|
|
447
|
+
return [];
|
|
380
448
|
}
|
|
381
|
-
return
|
|
449
|
+
return type.fields.map((field) => printObjectTypeFieldArgs(config, type.name.value, field)).filter(Boolean);
|
|
382
450
|
}
|
|
383
|
-
function
|
|
384
|
-
const
|
|
385
|
-
|
|
386
|
-
|
|
451
|
+
function printObjectTypeFieldArgs(config, typeName, field) {
|
|
452
|
+
const name = `${typeName + pascalCase2(field.name.value)}Args`;
|
|
453
|
+
return buildBlock({
|
|
454
|
+
name: `export type ${name} =`,
|
|
455
|
+
lines: field.arguments?.map((arg) => printObjectTypeFieldArg(config, arg)) ?? []
|
|
456
|
+
});
|
|
387
457
|
}
|
|
388
|
-
function
|
|
389
|
-
|
|
390
|
-
return normalize(parsedPath.dir);
|
|
458
|
+
function printObjectTypeFieldArg(config, arg) {
|
|
459
|
+
return `${arg.name.value}: ${printType(config, arg.type)}`;
|
|
391
460
|
}
|
|
392
|
-
function
|
|
393
|
-
|
|
461
|
+
function printType(config, type, nullable = true) {
|
|
462
|
+
switch (type.kind) {
|
|
463
|
+
case Kind.NAMED_TYPE:
|
|
464
|
+
return printNamedType(config, type, nullable);
|
|
465
|
+
case Kind.LIST_TYPE:
|
|
466
|
+
return printListType(config, type, nullable);
|
|
467
|
+
case Kind.NON_NULL_TYPE:
|
|
468
|
+
return printType(config, type.type, false);
|
|
469
|
+
default:
|
|
470
|
+
return type;
|
|
471
|
+
}
|
|
394
472
|
}
|
|
395
|
-
function
|
|
396
|
-
return
|
|
473
|
+
function printListType(config, type, nullable = true) {
|
|
474
|
+
return printValue(config, `Array<${printType(config, type.type)}>`, nullable);
|
|
397
475
|
}
|
|
398
|
-
function
|
|
399
|
-
if (
|
|
400
|
-
return
|
|
476
|
+
function printNamedType(config, type, nullable = true) {
|
|
477
|
+
if (isScalarType(config.globalDefinitions, config.defaultScalars, type)) {
|
|
478
|
+
return printScalarType(config, type, nullable);
|
|
401
479
|
}
|
|
402
|
-
return
|
|
480
|
+
return printValue(config, type.name.value, nullable);
|
|
403
481
|
}
|
|
404
|
-
function
|
|
405
|
-
|
|
406
|
-
|
|
482
|
+
function printScalarType(config, type, nullable = true) {
|
|
483
|
+
return printValue(config, `Scalars["${type.name.value}"]`, nullable);
|
|
484
|
+
}
|
|
485
|
+
function printValue(config, value, nullable) {
|
|
486
|
+
if (!nullable) {
|
|
487
|
+
return value;
|
|
407
488
|
}
|
|
489
|
+
if (config.withMaybe) {
|
|
490
|
+
return `BaetaUtility.Maybe<${value}>`;
|
|
491
|
+
}
|
|
492
|
+
return `${value} | null`;
|
|
408
493
|
}
|
|
409
|
-
function
|
|
410
|
-
return
|
|
494
|
+
function printOptionalMarker(config, type) {
|
|
495
|
+
return config.withOptional && type.kind !== Kind.NON_NULL_TYPE ? "?" : "";
|
|
411
496
|
}
|
|
412
|
-
function
|
|
413
|
-
return
|
|
497
|
+
function printOrObjectType(type, fields) {
|
|
498
|
+
return `BaetaUtility.Or<BaetaOverrides.ObjectTypes["${type.name.value}"], {
|
|
499
|
+
${fields?.map(indent(2)).join("\n") ?? ""}
|
|
500
|
+
}>`;
|
|
414
501
|
}
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
502
|
+
|
|
503
|
+
// lib/visitors/definitions-map.ts
|
|
504
|
+
import {
|
|
505
|
+
visit
|
|
506
|
+
} from "graphql";
|
|
507
|
+
function createRegistry() {
|
|
508
|
+
return {
|
|
509
|
+
scalarTypeMap: /* @__PURE__ */ new Map(),
|
|
510
|
+
enumTypeMap: /* @__PURE__ */ new Map(),
|
|
511
|
+
objectTypeMap: /* @__PURE__ */ new Map(),
|
|
512
|
+
inputObjectTypeMap: /* @__PURE__ */ new Map(),
|
|
513
|
+
unionTypeMap: /* @__PURE__ */ new Map(),
|
|
514
|
+
interfaceTypeMap: /* @__PURE__ */ new Map()
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
function createDefinitionsMapFromSources(sources) {
|
|
518
|
+
const registry = createRegistry();
|
|
519
|
+
for (const source of sources) {
|
|
520
|
+
if (source.document) {
|
|
521
|
+
collectTypesFromDocument(source.document, registry, ["Query", "Mutation", "Subscription"]);
|
|
522
|
+
}
|
|
419
523
|
}
|
|
420
|
-
return
|
|
524
|
+
return registry;
|
|
525
|
+
}
|
|
526
|
+
function createDefinitionsMapFromDocument(document) {
|
|
527
|
+
const registry = createRegistry();
|
|
528
|
+
collectTypesFromDocument(document, registry);
|
|
529
|
+
return registry;
|
|
530
|
+
}
|
|
531
|
+
function collectTypesFromDocument(document, registry, filterObjectTypes = []) {
|
|
532
|
+
visit(document, {
|
|
533
|
+
ScalarTypeDefinition(node) {
|
|
534
|
+
if (registry.scalarTypeMap.has(node.name.value)) {
|
|
535
|
+
throw new Error(`Scalar type ${node.name.value} already exists`);
|
|
536
|
+
}
|
|
537
|
+
registry.scalarTypeMap.set(node.name.value, node);
|
|
538
|
+
},
|
|
539
|
+
EnumTypeDefinition(node) {
|
|
540
|
+
if (registry.enumTypeMap.has(node.name.value)) {
|
|
541
|
+
throw new Error(`Enum type ${node.name.value} already exists, use 'extend' instead!`);
|
|
542
|
+
}
|
|
543
|
+
registry.enumTypeMap.set(node.name.value, node);
|
|
544
|
+
},
|
|
545
|
+
ObjectTypeDefinition(node) {
|
|
546
|
+
if (filterObjectTypes.includes(node.name.value)) {
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
if (registry.objectTypeMap.has(node.name.value)) {
|
|
550
|
+
throw new Error(`Object type ${node.name.value} already exists, use 'extend' instead!`);
|
|
551
|
+
}
|
|
552
|
+
registry.objectTypeMap.set(node.name.value, node);
|
|
553
|
+
},
|
|
554
|
+
InputObjectTypeDefinition(node) {
|
|
555
|
+
if (registry.inputObjectTypeMap.has(node.name.value)) {
|
|
556
|
+
throw new Error(`Input type ${node.name.value} already exists. Use 'extend' instead!`);
|
|
557
|
+
}
|
|
558
|
+
registry.inputObjectTypeMap.set(node.name.value, node);
|
|
559
|
+
},
|
|
560
|
+
UnionTypeDefinition(node) {
|
|
561
|
+
if (registry.unionTypeMap.has(node.name.value)) {
|
|
562
|
+
throw new Error(`Union type ${node.name.value} already exists, use 'extend' instead!`);
|
|
563
|
+
}
|
|
564
|
+
registry.unionTypeMap.set(node.name.value, node);
|
|
565
|
+
},
|
|
566
|
+
InterfaceTypeDefinition(node) {
|
|
567
|
+
if (registry.interfaceTypeMap.has(node.name.value)) {
|
|
568
|
+
throw new Error(`Interface type ${node.name.value} already exists. Use 'extend' instead!`);
|
|
569
|
+
}
|
|
570
|
+
registry.interfaceTypeMap.set(node.name.value, node);
|
|
571
|
+
}
|
|
572
|
+
});
|
|
421
573
|
}
|
|
422
574
|
|
|
423
|
-
// lib/
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
575
|
+
// lib/visitors/field-info.ts
|
|
576
|
+
import { Kind as Kind2 } from "graphql";
|
|
577
|
+
function createFieldInfoMap(definitionsMap, defaultScalars) {
|
|
578
|
+
const map = /* @__PURE__ */ new Map();
|
|
579
|
+
for (const objectType of definitionsMap.objectTypeMap.values()) {
|
|
580
|
+
const objectName = objectType.name.value;
|
|
581
|
+
for (const field of objectType.fields ?? []) {
|
|
582
|
+
const fieldName = field.name.value;
|
|
583
|
+
const type = printNamedType2(definitionsMap, defaultScalars, field.type, true);
|
|
584
|
+
const hasArguments = field.arguments != null && field.arguments.length > 0;
|
|
585
|
+
const fieldMap = map.get(objectName) ?? /* @__PURE__ */ new Map();
|
|
586
|
+
fieldMap.set(fieldName, { type, hasArguments });
|
|
587
|
+
map.set(objectName, fieldMap);
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
return map;
|
|
591
|
+
}
|
|
592
|
+
function printNamedType2(definitionsMap, defaultScalars, type, nullable = true) {
|
|
593
|
+
const withNullable = nullable ? " | null" : "";
|
|
594
|
+
switch (type.kind) {
|
|
595
|
+
case Kind2.NAMED_TYPE:
|
|
596
|
+
if (isScalarType(definitionsMap, defaultScalars, type)) {
|
|
597
|
+
return `Types.Scalars["${type.name.value}"]${withNullable}`;
|
|
598
|
+
}
|
|
599
|
+
return `Types.${type.name.value}${withNullable}`;
|
|
600
|
+
case Kind2.LIST_TYPE:
|
|
601
|
+
return `Array<${printNamedType2(definitionsMap, defaultScalars, type.type, nullable)}>${withNullable}`;
|
|
602
|
+
case Kind2.NON_NULL_TYPE:
|
|
603
|
+
return printNamedType2(definitionsMap, defaultScalars, type.type, false);
|
|
604
|
+
default:
|
|
605
|
+
return type;
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
// lib/visitors/module-registry.ts
|
|
610
|
+
import {
|
|
611
|
+
visit as visit2
|
|
612
|
+
} from "graphql";
|
|
613
|
+
var registryKeys = ["objects", "interfaces", "unions", "scalars"];
|
|
614
|
+
function createModuleRegistry(document) {
|
|
445
615
|
const picks = createObject(
|
|
446
616
|
registryKeys,
|
|
447
617
|
() => ({})
|
|
448
618
|
);
|
|
449
619
|
const defined = createObject(registryKeys, () => []);
|
|
450
|
-
|
|
451
|
-
const hashes = {};
|
|
452
|
-
const usedTypes = collectUsedTypes(doc);
|
|
453
|
-
visit(doc, {
|
|
620
|
+
visit2(document, {
|
|
454
621
|
ObjectTypeDefinition(node) {
|
|
455
|
-
|
|
622
|
+
defined.objects.push(node.name.value);
|
|
623
|
+
collectFields(node, picks.objects);
|
|
456
624
|
},
|
|
457
625
|
ObjectTypeExtension(node) {
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
InputObjectTypeDefinition(node) {
|
|
461
|
-
collectTypeDefinition(node);
|
|
462
|
-
},
|
|
463
|
-
InputObjectTypeExtension(node) {
|
|
464
|
-
collectTypeExtension(node);
|
|
626
|
+
pushUnique(defined.objects, node.name.value);
|
|
627
|
+
collectFields(node, picks.objects);
|
|
465
628
|
},
|
|
466
629
|
InterfaceTypeDefinition(node) {
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
InterfaceTypeExtension(node) {
|
|
470
|
-
collectTypeExtension(node);
|
|
471
|
-
},
|
|
472
|
-
ScalarTypeDefinition(node) {
|
|
473
|
-
collectTypeDefinition(node);
|
|
630
|
+
defined.interfaces.push(node.name.value);
|
|
631
|
+
collectFields(node, picks.interfaces);
|
|
474
632
|
},
|
|
475
633
|
UnionTypeDefinition(node) {
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
UnionTypeExtension(node) {
|
|
479
|
-
collectTypeExtension(node);
|
|
480
|
-
},
|
|
481
|
-
EnumTypeDefinition(node) {
|
|
482
|
-
collectTypeDefinition(node);
|
|
634
|
+
defined.unions.push(node.name.value);
|
|
635
|
+
collectUnionTypes(node, picks);
|
|
483
636
|
},
|
|
484
|
-
|
|
485
|
-
|
|
637
|
+
ScalarTypeDefinition(node) {
|
|
638
|
+
defined.scalars.push(node.name.value);
|
|
486
639
|
}
|
|
487
640
|
});
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
)
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
'import type { DocumentNode } from "graphql";',
|
|
499
|
-
'import * as Baeta from "@baeta/core/sdk";'
|
|
500
|
-
];
|
|
501
|
-
if (extensionsPath) {
|
|
502
|
-
imports.push(`import baetaExtensions from "${extensionsPath}";`);
|
|
503
|
-
}
|
|
504
|
-
imports.push("\n");
|
|
505
|
-
let content = [
|
|
506
|
-
printDefinedFields(),
|
|
507
|
-
printDefinedEnumValues(),
|
|
508
|
-
printDefinedInputFields(),
|
|
509
|
-
printSchemaTypes(usedTypes),
|
|
510
|
-
printMetadata()
|
|
511
|
-
].filter(Boolean).join("\n\n");
|
|
512
|
-
const moduleNamespace = baseVisitor.convertName(name, {
|
|
513
|
-
suffix: "Module",
|
|
514
|
-
useTypesPrefix: false,
|
|
515
|
-
useTypesSuffix: false
|
|
516
|
-
});
|
|
517
|
-
if (encapsulate === "namespace") {
|
|
518
|
-
content = `${shouldDeclare ? "declare" : "export"} namespace ${baseVisitor.convertName(name, {
|
|
519
|
-
suffix: "Module",
|
|
520
|
-
useTypesPrefix: false,
|
|
521
|
-
useTypesSuffix: false
|
|
522
|
-
})} {
|
|
523
|
-
${shouldDeclare ? `${indent(2)(imports.join("\n"))}
|
|
524
|
-
` : ""}${indent(2)(content)}
|
|
525
|
-
}`;
|
|
526
|
-
}
|
|
527
|
-
return [...shouldDeclare ? [] : imports, content, printFactoryMethod()].filter(Boolean).join("\n");
|
|
528
|
-
function printMetadata() {
|
|
529
|
-
return `export namespace ModuleMetadata {
|
|
530
|
-
export const id = '${name}';
|
|
531
|
-
export const dirname = './${name}';
|
|
532
|
-
export const hashes = ${JSON.stringify(hashes)};
|
|
533
|
-
export const typedef = ${JSON.stringify(doc)} as unknown as DocumentNode;
|
|
534
|
-
${printBaetaManager()}
|
|
535
|
-
}`;
|
|
536
|
-
}
|
|
537
|
-
function printDefinedFields() {
|
|
538
|
-
return buildBlock({
|
|
539
|
-
name: "interface DefinedFields",
|
|
540
|
-
lines: [...visited.objects, ...visited.interfaces].map(
|
|
541
|
-
(typeName) => `${typeName}: ${printPicks(typeName, {
|
|
542
|
-
...picks.objects,
|
|
543
|
-
...picks.interfaces
|
|
544
|
-
})};`
|
|
545
|
-
)
|
|
546
|
-
});
|
|
547
|
-
}
|
|
548
|
-
function printFactoryMethod() {
|
|
549
|
-
const name2 = moduleNamespace.slice(0, moduleNamespace.length - 6);
|
|
550
|
-
const createModuleFn = `create${name2}Module`;
|
|
551
|
-
const getModuleFn = `get${name2}Module`;
|
|
552
|
-
const extensionsArg = extensionsPath ? ", baetaExtensions" : "";
|
|
553
|
-
return `
|
|
554
|
-
export const ${createModuleFn} = () => Baeta.createModuleManager(ModuleMetadata${extensionsArg});
|
|
555
|
-
export const ${getModuleFn} = Baeta.createSingletonModule(${createModuleFn});
|
|
556
|
-
`;
|
|
557
|
-
}
|
|
558
|
-
function printObjectFieldResolverBuilder(typeName, field) {
|
|
559
|
-
const parentType = getParentType(typeName);
|
|
560
|
-
const resultType = getResultType(typeName, field);
|
|
561
|
-
const argumentsType = getArgsType(typeName, field);
|
|
562
|
-
const contextType = getContextType();
|
|
563
|
-
return `${field}: module.createResolverBuilder<${resultType}, ${parentType}, ${contextType}, ${argumentsType}>("${typeName}", "${field}"),`;
|
|
564
|
-
}
|
|
565
|
-
function printObjectResolverBuilder(typeName, objects) {
|
|
566
|
-
const fields = objects[typeName]?.filter(unique).map((field) => printObjectFieldResolverBuilder(typeName, field)) ?? [];
|
|
567
|
-
if (fields.length === 0) {
|
|
568
|
-
return "";
|
|
569
|
-
}
|
|
570
|
-
const parentType = getParentType(typeName);
|
|
571
|
-
const contextType = getContextType();
|
|
572
|
-
const addons = [`...module.createTypeMethods<${parentType}, ${contextType}>("${typeName}"),`];
|
|
573
|
-
const contentBody = [...addons, ...fields].map(indent(2)).join("\n");
|
|
574
|
-
const content2 = `{
|
|
575
|
-
${contentBody}
|
|
576
|
-
}`;
|
|
577
|
-
return `${typeName}: ${content2},`;
|
|
578
|
-
}
|
|
579
|
-
function printSubscriptionFieldBuilder(field) {
|
|
580
|
-
const parentType = getParentType("Subscription");
|
|
581
|
-
const resultType = getResultType("Subscription", field);
|
|
582
|
-
const argumentsType = getArgsType("Subscription", field);
|
|
583
|
-
const contextType = getContextType();
|
|
584
|
-
return `${field}: module.createSubscriptionBuilder<${resultType}, ${parentType}, ${contextType}, ${argumentsType}>("${field}"),`;
|
|
585
|
-
}
|
|
586
|
-
function printSubscriptionObjectBuilder() {
|
|
587
|
-
const subscriptions = picks.objects.Subscription?.filter(unique) ?? [];
|
|
588
|
-
if (subscriptions.length === 0) {
|
|
589
|
-
return "";
|
|
590
|
-
}
|
|
591
|
-
const fields = subscriptions.map((subscription) => printSubscriptionFieldBuilder(subscription));
|
|
592
|
-
const parentType = getParentType("Subscription");
|
|
593
|
-
const contextType = getContextType();
|
|
594
|
-
const addons = [`...module.createSubscriptionMethods<${parentType}, ${contextType}>(),`];
|
|
595
|
-
const contentBody = [...addons, ...fields].map(indent(2)).join("\n");
|
|
596
|
-
const content2 = `{
|
|
597
|
-
${contentBody}
|
|
598
|
-
}`;
|
|
599
|
-
return `Subscription: ${content2},`;
|
|
600
|
-
}
|
|
601
|
-
function printScalarBuilder() {
|
|
602
|
-
const scalars = visited.scalars;
|
|
603
|
-
if (scalars.length === 0) {
|
|
604
|
-
return "";
|
|
605
|
-
}
|
|
606
|
-
const fields = scalars.map((scalar) => `${scalar}: module.createScalarBuilder("${scalar}"),`);
|
|
607
|
-
const content2 = fields.map(indent(2)).join("\n");
|
|
608
|
-
return `Scalar: {
|
|
609
|
-
${content2}
|
|
610
|
-
},`;
|
|
611
|
-
}
|
|
612
|
-
function printTypenameResolverBuilder(name2, resultNamespace, valueNamespace) {
|
|
613
|
-
const resultType = `${importNamespace}.${resultNamespace}["${name2}"]`;
|
|
614
|
-
const valueType = `${importNamespace}.${valueNamespace}["${name2}"]`;
|
|
615
|
-
const contextType = getContextType();
|
|
616
|
-
const resolver = `$resolveType: module.createResolveType<${resultType}, ${valueType}, ${contextType}>("${name2}"),`;
|
|
617
|
-
return `${name2}: {
|
|
618
|
-
${indent(2)(resolver)}
|
|
619
|
-
},`;
|
|
620
|
-
}
|
|
621
|
-
function printInterfaceBuilder() {
|
|
622
|
-
const interfaces = defined.interfaces;
|
|
623
|
-
if (interfaces.length === 0) {
|
|
624
|
-
return "";
|
|
625
|
-
}
|
|
626
|
-
return interfaces.map(
|
|
627
|
-
(interfaceName) => printTypenameResolverBuilder(
|
|
628
|
-
interfaceName,
|
|
629
|
-
"DefinedInterfacesResults",
|
|
630
|
-
"DefinedInterfacesWithoutExtensions"
|
|
631
|
-
)
|
|
632
|
-
).join("\n");
|
|
633
|
-
}
|
|
634
|
-
function printUnionBuilder() {
|
|
635
|
-
const unions = defined.unions;
|
|
636
|
-
if (unions.length === 0) {
|
|
637
|
-
return "";
|
|
638
|
-
}
|
|
639
|
-
return unions.map(
|
|
640
|
-
(unionName) => printTypenameResolverBuilder(
|
|
641
|
-
unionName,
|
|
642
|
-
"DefinedUnionsResults",
|
|
643
|
-
"DefinedUnionsWithoutExtensions"
|
|
644
|
-
)
|
|
645
|
-
).join("\n");
|
|
646
|
-
}
|
|
647
|
-
function printBaetaManager() {
|
|
648
|
-
const objects = visited.objects.filter((type) => type !== "Subscription").map((typeName) => printObjectResolverBuilder(typeName, picks.objects)).filter(Boolean);
|
|
649
|
-
const contextType = getContextType();
|
|
650
|
-
const addons = [`...module.createModuleMethods<${contextType}>(),`];
|
|
651
|
-
const bodyFields = [
|
|
652
|
-
...addons,
|
|
653
|
-
...objects,
|
|
654
|
-
printScalarBuilder(),
|
|
655
|
-
printSubscriptionObjectBuilder(),
|
|
656
|
-
printInterfaceBuilder(),
|
|
657
|
-
printUnionBuilder()
|
|
658
|
-
];
|
|
659
|
-
const body = bodyFields.filter(Boolean).map(indent(6)).join("\n");
|
|
660
|
-
const content2 = `{
|
|
661
|
-
${body}
|
|
662
|
-
}`;
|
|
663
|
-
return `
|
|
664
|
-
export function createManager(module: Baeta.ModuleBuilder) {
|
|
665
|
-
return ${content2};
|
|
666
|
-
}`;
|
|
667
|
-
}
|
|
668
|
-
function printDefinedEnumValues() {
|
|
669
|
-
return buildBlock({
|
|
670
|
-
name: "interface DefinedEnumValues",
|
|
671
|
-
lines: visited.enums.map((typeName) => `${typeName}: ${printPicks(typeName, picks.enums)};`)
|
|
672
|
-
});
|
|
673
|
-
}
|
|
674
|
-
function encapsulateTypeName(typeName) {
|
|
675
|
-
if (encapsulate === "prefix") {
|
|
676
|
-
return `${pascalCase(name)}_${typeName}`;
|
|
677
|
-
}
|
|
678
|
-
return typeName;
|
|
679
|
-
}
|
|
680
|
-
function printDefinedInputFields() {
|
|
681
|
-
return buildBlock({
|
|
682
|
-
name: "interface DefinedInputFields",
|
|
683
|
-
lines: visited.inputs.map(
|
|
684
|
-
(typeName) => `${typeName}: ${printPicks(typeName, picks.inputs)};`
|
|
685
|
-
)
|
|
686
|
-
});
|
|
687
|
-
}
|
|
688
|
-
function printSchemaTypes(types) {
|
|
689
|
-
return types.filter((type) => !visited.scalars.includes(type)).map(printExportType).join("\n");
|
|
690
|
-
}
|
|
691
|
-
function printPicks(typeName, records) {
|
|
692
|
-
return records[typeName].filter(unique).map(withQuotes).join(" | ");
|
|
693
|
-
}
|
|
694
|
-
function printTypeBody(typeName) {
|
|
695
|
-
const normalizedTypeName = baseVisitor.convertName(typeName, {
|
|
696
|
-
useTypesSuffix: true,
|
|
697
|
-
useTypesPrefix: true
|
|
698
|
-
});
|
|
699
|
-
const coreType = `${importNamespace}.${normalizedTypeName}`;
|
|
700
|
-
if (external.enums.includes(typeName) || external.objects.includes(typeName)) {
|
|
701
|
-
if (schema && isScalarType(schema.getType(typeName))) {
|
|
702
|
-
return `${importNamespace}.Scalars['${typeName}']`;
|
|
703
|
-
}
|
|
704
|
-
return `Pick<${coreType}, ${importNamespace}.DefinedFieldsWithoutExtensions["${typeName}"]>`;
|
|
705
|
-
}
|
|
706
|
-
if (external.unions.includes(typeName)) {
|
|
707
|
-
return `${importNamespace}.DefinedUnionsWithoutExtensions["${typeName}"]`;
|
|
708
|
-
}
|
|
709
|
-
if (external.interfaces.includes(typeName)) {
|
|
710
|
-
return `Pick<${coreType}, ${importNamespace}.DefinedFieldsWithoutExtensions["${typeName}"]>`;
|
|
711
|
-
}
|
|
712
|
-
if (defined.enums.includes(typeName) && picks.enums[typeName]) {
|
|
713
|
-
return `DefinedEnumValues['${typeName}']`;
|
|
714
|
-
}
|
|
715
|
-
if (defined.unions.includes(typeName) && picks.unions[typeName]) {
|
|
716
|
-
return `${importNamespace}.DefinedUnionsWithoutExtensions["${typeName}"]`;
|
|
717
|
-
}
|
|
718
|
-
if (defined.objects.includes(typeName) && picks.objects[typeName]) {
|
|
719
|
-
return `Pick<${coreType}, DefinedFields['${typeName}']>`;
|
|
720
|
-
}
|
|
721
|
-
if (defined.interfaces.includes(typeName) && picks.interfaces[typeName]) {
|
|
722
|
-
return `${importNamespace}.DefinedInterfacesWithoutExtensions["${typeName}"]`;
|
|
723
|
-
}
|
|
724
|
-
if (defined.inputs.includes(typeName) && picks.inputs[typeName]) {
|
|
725
|
-
return `Pick<${coreType}, DefinedInputFields['${typeName}']>`;
|
|
726
|
-
}
|
|
727
|
-
if (isScalarType(schema?.getType(typeName))) {
|
|
728
|
-
return coreType;
|
|
729
|
-
}
|
|
730
|
-
if (isInterfaceType(schema?.getType(typeName))) {
|
|
731
|
-
return `${importNamespace}.DefinedInterfacesWithoutExtensions["${typeName}"]`;
|
|
732
|
-
}
|
|
733
|
-
if (isUnionType(schema?.getType(typeName))) {
|
|
734
|
-
return `${importNamespace}.DefinedUnionsWithoutExtensions["${typeName}"]`;
|
|
735
|
-
}
|
|
736
|
-
return `Pick<${coreType}, ${importNamespace}.DefinedFieldsWithoutExtensions["${typeName}"]>`;
|
|
737
|
-
}
|
|
738
|
-
function printExportType(typeName) {
|
|
739
|
-
return `export type ${encapsulateTypeName(typeName)} = ${printTypeBody(typeName)};`;
|
|
740
|
-
}
|
|
741
|
-
function collectFields(node, picksObj) {
|
|
742
|
-
const name2 = node.name.value;
|
|
743
|
-
if (node.fields) {
|
|
744
|
-
if (!picksObj[name2]) {
|
|
745
|
-
picksObj[name2] = [];
|
|
746
|
-
}
|
|
747
|
-
for (const field of node.fields) {
|
|
748
|
-
picksObj[name2].push(field.name.value);
|
|
749
|
-
}
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
function collectValuesFromEnum(node) {
|
|
753
|
-
const name2 = node.name.value;
|
|
754
|
-
if (node.values) {
|
|
755
|
-
if (!picks.enums[name2]) {
|
|
756
|
-
picks.enums[name2] = [];
|
|
757
|
-
}
|
|
758
|
-
for (const field of node.values) {
|
|
759
|
-
picks.enums[name2].push(field.name.value);
|
|
760
|
-
}
|
|
761
|
-
}
|
|
762
|
-
}
|
|
763
|
-
function collectUnionTypes(node) {
|
|
764
|
-
const name2 = node.name.value;
|
|
765
|
-
if (node.types) {
|
|
766
|
-
if (!picks.unions[name2]) {
|
|
767
|
-
picks.unions[name2] = [];
|
|
768
|
-
}
|
|
769
|
-
for (const type of node.types) {
|
|
770
|
-
picks.unions[name2].push(type.name.value);
|
|
771
|
-
}
|
|
772
|
-
}
|
|
773
|
-
}
|
|
774
|
-
function collectTypeDefinition(node) {
|
|
775
|
-
const name2 = node.name.value;
|
|
776
|
-
switch (node.kind) {
|
|
777
|
-
case Kind3.OBJECT_TYPE_DEFINITION: {
|
|
778
|
-
defined.objects.push(name2);
|
|
779
|
-
collectFields(node, picks.objects);
|
|
780
|
-
hashes[name2] = getObjectTypeHash(node);
|
|
781
|
-
break;
|
|
782
|
-
}
|
|
783
|
-
case Kind3.ENUM_TYPE_DEFINITION: {
|
|
784
|
-
defined.enums.push(name2);
|
|
785
|
-
collectValuesFromEnum(node);
|
|
786
|
-
break;
|
|
787
|
-
}
|
|
788
|
-
case Kind3.INPUT_OBJECT_TYPE_DEFINITION: {
|
|
789
|
-
defined.inputs.push(name2);
|
|
790
|
-
collectFields(node, picks.inputs);
|
|
791
|
-
break;
|
|
792
|
-
}
|
|
793
|
-
case Kind3.SCALAR_TYPE_DEFINITION: {
|
|
794
|
-
defined.scalars.push(name2);
|
|
795
|
-
break;
|
|
796
|
-
}
|
|
797
|
-
case Kind3.INTERFACE_TYPE_DEFINITION: {
|
|
798
|
-
defined.interfaces.push(name2);
|
|
799
|
-
collectFields(node, picks.interfaces);
|
|
800
|
-
break;
|
|
801
|
-
}
|
|
802
|
-
case Kind3.UNION_TYPE_DEFINITION: {
|
|
803
|
-
defined.unions.push(name2);
|
|
804
|
-
collectUnionTypes(node);
|
|
805
|
-
break;
|
|
806
|
-
}
|
|
641
|
+
return {
|
|
642
|
+
defined,
|
|
643
|
+
picks
|
|
644
|
+
};
|
|
645
|
+
}
|
|
646
|
+
function collectFields(node, picksObj) {
|
|
647
|
+
const name = node.name.value;
|
|
648
|
+
if (node.fields) {
|
|
649
|
+
if (!picksObj[name]) {
|
|
650
|
+
picksObj[name] = [];
|
|
807
651
|
}
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
const name2 = node.name.value;
|
|
811
|
-
switch (node.kind) {
|
|
812
|
-
case Kind3.OBJECT_TYPE_EXTENSION: {
|
|
813
|
-
collectFields(node, picks.objects);
|
|
814
|
-
hashes[name2] = getObjectTypeHash(node);
|
|
815
|
-
if (rootTypes.includes(name2)) {
|
|
816
|
-
pushUnique(defined.objects, name2);
|
|
817
|
-
return;
|
|
818
|
-
}
|
|
819
|
-
pushUnique(extended.objects, name2);
|
|
820
|
-
break;
|
|
821
|
-
}
|
|
822
|
-
case Kind3.ENUM_TYPE_EXTENSION: {
|
|
823
|
-
collectValuesFromEnum(node);
|
|
824
|
-
pushUnique(extended.enums, name2);
|
|
825
|
-
break;
|
|
826
|
-
}
|
|
827
|
-
case Kind3.INPUT_OBJECT_TYPE_EXTENSION: {
|
|
828
|
-
collectFields(node, picks.inputs);
|
|
829
|
-
pushUnique(extended.inputs, name2);
|
|
830
|
-
break;
|
|
831
|
-
}
|
|
832
|
-
case Kind3.INTERFACE_TYPE_EXTENSION: {
|
|
833
|
-
collectFields(node, picks.interfaces);
|
|
834
|
-
pushUnique(extended.interfaces, name2);
|
|
835
|
-
break;
|
|
836
|
-
}
|
|
837
|
-
case Kind3.UNION_TYPE_EXTENSION: {
|
|
838
|
-
pushUnique(extended.unions, name2);
|
|
839
|
-
break;
|
|
840
|
-
}
|
|
652
|
+
for (const field of node.fields) {
|
|
653
|
+
picksObj[name].push(field.name.value);
|
|
841
654
|
}
|
|
842
655
|
}
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
656
|
+
}
|
|
657
|
+
function collectUnionTypes(node, picks) {
|
|
658
|
+
const name = node.name.value;
|
|
659
|
+
if (node.types) {
|
|
660
|
+
if (!picks.unions[name]) {
|
|
661
|
+
picks.unions[name] = [];
|
|
846
662
|
}
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
function getResultType(type, field) {
|
|
850
|
-
return fieldTypes?.[type]?.[field] || "{ }";
|
|
851
|
-
}
|
|
852
|
-
function getArgsType(type, field) {
|
|
853
|
-
const hasArgs = fieldArguments?.[type]?.[field] ?? false;
|
|
854
|
-
if (!hasArgs) {
|
|
855
|
-
return "{ }";
|
|
663
|
+
for (const type of node.types) {
|
|
664
|
+
picks.unions[name].push(type.name.value);
|
|
856
665
|
}
|
|
857
|
-
const fieldUpper = field[0].toUpperCase() + field.slice(1);
|
|
858
|
-
return `Types.${type}${fieldUpper}Args`;
|
|
859
666
|
}
|
|
860
|
-
|
|
861
|
-
|
|
667
|
+
}
|
|
668
|
+
function pushUnique(list, item) {
|
|
669
|
+
if (!list.includes(item)) {
|
|
670
|
+
list.push(item);
|
|
862
671
|
}
|
|
863
672
|
}
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
const { baseOutputDir } = options;
|
|
869
|
-
const { baseTypesPath, extensionsPath, encapsulateModuleTypes, importExtension } = options.presetConfig;
|
|
870
|
-
const requireRootResolvers = getConfigValue(options?.presetConfig.requireRootResolvers, false);
|
|
871
|
-
const cwd = resolve(options.presetConfig.cwd || process.cwd());
|
|
872
|
-
const importTypesNamespace = options.presetConfig.importTypesNamespace || "Types";
|
|
873
|
-
if (!baseTypesPath) {
|
|
874
|
-
throw new Error(
|
|
875
|
-
`Preset "graphql-modules" requires you to specify "baseTypesPath" configuration and point it to your base types file (generated by "typescript" plugin)!`
|
|
876
|
-
);
|
|
877
|
-
}
|
|
878
|
-
if (!options.schemaAst?.extensions.sources) {
|
|
879
|
-
throw new Error(`Preset "graphql-modules" requires to use GraphQL SDL`);
|
|
880
|
-
}
|
|
881
|
-
const extensions = options.schemaAst?.extensions;
|
|
882
|
-
const sources = extensions?.extendedSources ?? [];
|
|
883
|
-
const sourcesByModuleMap = groupSourcesByModule(sources, baseOutputDir);
|
|
884
|
-
const modules = Object.keys(sourcesByModuleMap);
|
|
885
|
-
const baseVisitor = new BaseVisitor(options.config, {});
|
|
886
|
-
const { fieldTypes, fieldArguments } = collectObjectFieldTypesAndArguments(options.schemaAst);
|
|
887
|
-
const baseOutput = {
|
|
888
|
-
filename: resolve(cwd, baseOutputDir, baseTypesPath),
|
|
889
|
-
schema: options.schema,
|
|
890
|
-
documents: options.documents,
|
|
891
|
-
plugins: [
|
|
892
|
-
...options.plugins,
|
|
893
|
-
{
|
|
894
|
-
"modules-exported-scalars": {}
|
|
895
|
-
},
|
|
896
|
-
{
|
|
897
|
-
"modules-exported-picks": {}
|
|
898
|
-
}
|
|
899
|
-
],
|
|
900
|
-
pluginMap: {
|
|
901
|
-
...options.pluginMap,
|
|
902
|
-
"modules-exported-scalars": {
|
|
903
|
-
plugin: (schema) => {
|
|
904
|
-
const typeMap = schema.getTypeMap();
|
|
905
|
-
return Object.keys(typeMap).map((t) => {
|
|
906
|
-
if (t && typeMap[t] && isScalarType2(typeMap[t]) && !isGraphQLPrimitive(t)) {
|
|
907
|
-
const convertedName = baseVisitor.convertName(t);
|
|
908
|
-
return `export type ${convertedName} = Scalars["${t}"];`;
|
|
909
|
-
}
|
|
910
|
-
return null;
|
|
911
|
-
}).filter(Boolean).join("\n");
|
|
912
|
-
}
|
|
913
|
-
},
|
|
914
|
-
"modules-exported-picks": {
|
|
915
|
-
plugin: (schema) => {
|
|
916
|
-
const typePicks = [];
|
|
917
|
-
const unionPicks = [];
|
|
918
|
-
const unionResults = [];
|
|
919
|
-
const interfacePicks = [];
|
|
920
|
-
const interfaceResults = [];
|
|
921
|
-
const unionTypesMap = {};
|
|
922
|
-
const interfacesTypesMap = {};
|
|
923
|
-
for (const moduleName of modules) {
|
|
924
|
-
const sources2 = sourcesByModuleMap[moduleName];
|
|
925
|
-
const documents = sources2.map((source) => source.document);
|
|
926
|
-
const moduleDocument = concatAST(documents);
|
|
927
|
-
const types = moduleDocument.definitions.filter(
|
|
928
|
-
(def) => def.kind === "ObjectTypeDefinition"
|
|
929
|
-
);
|
|
930
|
-
const unionsDefinition2 = moduleDocument.definitions.filter(
|
|
931
|
-
(def) => def.kind === "UnionTypeDefinition"
|
|
932
|
-
);
|
|
933
|
-
const unionsExtensions = moduleDocument.definitions.filter(
|
|
934
|
-
(def) => def.kind === "UnionTypeExtension"
|
|
935
|
-
);
|
|
936
|
-
const unions = [...unionsDefinition2, ...unionsExtensions];
|
|
937
|
-
for (const type of types) {
|
|
938
|
-
const name = type.name.value;
|
|
939
|
-
for (const interfaceNode of type.interfaces ?? []) {
|
|
940
|
-
const interfaceName = interfaceNode.name.value;
|
|
941
|
-
if (interfacesTypesMap[interfaceName] == null) {
|
|
942
|
-
interfacesTypesMap[interfaceName] = [];
|
|
943
|
-
}
|
|
944
|
-
interfacesTypesMap[interfaceName]?.push(name);
|
|
945
|
-
}
|
|
946
|
-
if (name === "Query" || name === "Mutation" || name === "Subscription") {
|
|
947
|
-
continue;
|
|
948
|
-
}
|
|
949
|
-
const fields = type.fields ?? [];
|
|
950
|
-
if (fields.length === 0) {
|
|
951
|
-
continue;
|
|
952
|
-
}
|
|
953
|
-
const fieldNames = fields.map((f) => `"${f.name.value}"`).join(" | ");
|
|
954
|
-
typePicks.push(` ${name}: ${fieldNames};`);
|
|
955
|
-
}
|
|
956
|
-
for (const union of unions) {
|
|
957
|
-
const types2 = union.types?.map((t) => t.name.value) ?? [];
|
|
958
|
-
if (unionTypesMap[union.name.value] == null) {
|
|
959
|
-
unionTypesMap[union.name.value] = [];
|
|
960
|
-
}
|
|
961
|
-
unionTypesMap[union.name.value]?.push(...types2);
|
|
962
|
-
}
|
|
963
|
-
}
|
|
964
|
-
for (const unionName in unionTypesMap) {
|
|
965
|
-
const types = unionTypesMap[unionName];
|
|
966
|
-
if (types == null || types.length === 0) {
|
|
967
|
-
unionPicks.push(` ${unionName}: never;`);
|
|
968
|
-
unionResults.push(` ${unionName}: null;`);
|
|
969
|
-
continue;
|
|
970
|
-
}
|
|
971
|
-
const typePicks2 = types.map((t) => {
|
|
972
|
-
const normalizedTypeName = baseVisitor.convertName(t, {
|
|
973
|
-
useTypesSuffix: true,
|
|
974
|
-
useTypesPrefix: true
|
|
975
|
-
});
|
|
976
|
-
return `Pick<${normalizedTypeName}, DefinedFieldsWithoutExtensions["${t}"] | "__typename">`;
|
|
977
|
-
});
|
|
978
|
-
const resultPicks = types.map((t) => `"${t}"`);
|
|
979
|
-
unionPicks.push(` ${unionName}: ${typePicks2.join(" | ")};`);
|
|
980
|
-
unionResults.push(` ${unionName}: ${resultPicks.join(" | ")} | null;`);
|
|
981
|
-
}
|
|
982
|
-
for (const interfaceName in interfacesTypesMap) {
|
|
983
|
-
const types = interfacesTypesMap[interfaceName];
|
|
984
|
-
if (types == null || types.length === 0) {
|
|
985
|
-
interfacePicks.push(` ${interfaceName}: never;`);
|
|
986
|
-
interfaceResults.push(` ${interfaceName}: null;`);
|
|
987
|
-
continue;
|
|
988
|
-
}
|
|
989
|
-
const typePicks2 = types.map((t) => {
|
|
990
|
-
const normalizedTypeName = baseVisitor.convertName(t, {
|
|
991
|
-
useTypesSuffix: true,
|
|
992
|
-
useTypesPrefix: true
|
|
993
|
-
});
|
|
994
|
-
return `Pick<${normalizedTypeName}, DefinedFieldsWithoutExtensions["${t}"] | "__typename">`;
|
|
995
|
-
});
|
|
996
|
-
const resultPicks = types.map((t) => `"${t}"`);
|
|
997
|
-
interfacePicks.push(` ${interfaceName}: ${typePicks2.join(" | ")};`);
|
|
998
|
-
interfaceResults.push(` ${interfaceName}: ${resultPicks.join(" | ")} | null;`);
|
|
999
|
-
}
|
|
1000
|
-
const fieldsDefinition = `export type DefinedFieldsWithoutExtensions = {
|
|
1001
|
-
${typePicks.join("\n")}
|
|
1002
|
-
};`;
|
|
1003
|
-
const unionsDefinition = `export type DefinedUnionsWithoutExtensions = {
|
|
1004
|
-
${unionPicks.join("\n")}
|
|
1005
|
-
};`;
|
|
1006
|
-
const unionsResultsDefinition = `export type DefinedUnionsResults = {
|
|
1007
|
-
${unionResults.join("\n")}
|
|
1008
|
-
};`;
|
|
1009
|
-
const interfacesDefinition = `export type DefinedInterfacesWithoutExtensions = {
|
|
1010
|
-
${interfacePicks.join("\n")}
|
|
1011
|
-
};`;
|
|
1012
|
-
const interfacesResultsDefinition = `export type DefinedInterfacesResults = {
|
|
1013
|
-
${interfaceResults.join(
|
|
1014
|
-
"\n"
|
|
1015
|
-
)}
|
|
1016
|
-
};`;
|
|
1017
|
-
const result = [
|
|
1018
|
-
fieldsDefinition,
|
|
1019
|
-
unionsDefinition,
|
|
1020
|
-
unionsResultsDefinition,
|
|
1021
|
-
interfacesDefinition,
|
|
1022
|
-
interfacesResultsDefinition
|
|
1023
|
-
].join("\n\n");
|
|
1024
|
-
return `
|
|
1025
|
-
${result}
|
|
1026
|
-
`;
|
|
1027
|
-
}
|
|
1028
|
-
}
|
|
1029
|
-
},
|
|
1030
|
-
config: {
|
|
1031
|
-
...options.config,
|
|
1032
|
-
enumsAsTypes: true
|
|
1033
|
-
},
|
|
1034
|
-
schemaAst: options.schemaAst
|
|
1035
|
-
};
|
|
1036
|
-
const baseTypesFilename = basename(baseTypesPath).replace(/\.(js|ts|d.ts)$/, "") + (importExtension || "");
|
|
1037
|
-
const baseTypesDir = stripFilename(baseOutput.filename);
|
|
1038
|
-
const outputs = modules.map((moduleName) => {
|
|
1039
|
-
const filename = resolve(cwd, baseOutputDir, moduleName, options.presetConfig.filename);
|
|
1040
|
-
const dirpath = stripFilename(filename);
|
|
1041
|
-
const relativePath = relative2(dirpath, baseTypesDir);
|
|
1042
|
-
const importPath = options.presetConfig.importBaseTypesFrom || normalize(join(relativePath, baseTypesFilename));
|
|
1043
|
-
const sources2 = sourcesByModuleMap[moduleName];
|
|
1044
|
-
const documents = sources2.map((source) => source.document);
|
|
1045
|
-
const moduleDocument = concatAST(documents);
|
|
1046
|
-
const shouldDeclare = filename.endsWith(".d.ts");
|
|
1047
|
-
return {
|
|
1048
|
-
filename,
|
|
1049
|
-
schema: options.schema,
|
|
1050
|
-
documents: [],
|
|
1051
|
-
plugins: [
|
|
1052
|
-
...options.plugins.filter((p) => typeof p === "object" && !!p.add),
|
|
1053
|
-
{
|
|
1054
|
-
"graphql-modules-plugin": {}
|
|
1055
|
-
}
|
|
1056
|
-
],
|
|
1057
|
-
pluginMap: {
|
|
1058
|
-
...options.pluginMap,
|
|
1059
|
-
"graphql-modules-plugin": {
|
|
1060
|
-
plugin: (schema) => buildModule(moduleName, moduleDocument, {
|
|
1061
|
-
importNamespace: importTypesNamespace,
|
|
1062
|
-
importPath,
|
|
1063
|
-
encapsulate: encapsulateModuleTypes || "namespace",
|
|
1064
|
-
requireRootResolvers,
|
|
1065
|
-
shouldDeclare,
|
|
1066
|
-
schema,
|
|
1067
|
-
baseVisitor,
|
|
1068
|
-
useGraphQLModules: false,
|
|
1069
|
-
fieldTypes,
|
|
1070
|
-
fieldArguments,
|
|
1071
|
-
extensionsPath,
|
|
1072
|
-
rootTypes: [
|
|
1073
|
-
schema.getQueryType()?.name || "",
|
|
1074
|
-
schema.getMutationType()?.name || "",
|
|
1075
|
-
schema.getSubscriptionType()?.name || ""
|
|
1076
|
-
].filter(Boolean)
|
|
1077
|
-
})
|
|
1078
|
-
}
|
|
1079
|
-
},
|
|
1080
|
-
config: options.config,
|
|
1081
|
-
schemaAst: options.schemaAst
|
|
1082
|
-
};
|
|
1083
|
-
});
|
|
1084
|
-
return [baseOutput].concat(outputs);
|
|
673
|
+
function createObject(keys, valueFn) {
|
|
674
|
+
const obj = {};
|
|
675
|
+
for (const key of keys) {
|
|
676
|
+
obj[key] = valueFn(key);
|
|
1085
677
|
}
|
|
1086
|
-
|
|
678
|
+
return obj;
|
|
679
|
+
}
|
|
1087
680
|
|
|
1088
681
|
// lib/codegen.ts
|
|
1089
682
|
async function generate(options) {
|
|
1090
|
-
const
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
683
|
+
const { outputSchema, outputSchemaAst } = await loadSchema(
|
|
684
|
+
options.schemas,
|
|
685
|
+
options.cwd,
|
|
686
|
+
options.loaders
|
|
687
|
+
);
|
|
688
|
+
const sources = getSourcesFromSchema(outputSchemaAst);
|
|
689
|
+
const sourcesByModule = groupSourcesByModule(sources, options.modulesDir);
|
|
690
|
+
const modules = Array.from(sourcesByModule.keys());
|
|
691
|
+
const globalDefinitions = createDefinitionsMapFromDocument(outputSchema);
|
|
692
|
+
const modulesDefinitions = createDefinitionsMapFromSources(sources);
|
|
693
|
+
const defaultScalars = ["ID", "Int", "Float", "String", "Boolean"];
|
|
694
|
+
const config = {
|
|
695
|
+
globalDefinitions,
|
|
696
|
+
withMaybe: false,
|
|
697
|
+
withOptional: false,
|
|
698
|
+
defaultScalars
|
|
1102
699
|
};
|
|
1103
|
-
const
|
|
1104
|
-
const
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
700
|
+
const fieldInfo = createFieldInfoMap(globalDefinitions, defaultScalars);
|
|
701
|
+
const typesContent = [
|
|
702
|
+
printTypesHeaders(),
|
|
703
|
+
printRootTypesFromMap(
|
|
704
|
+
config,
|
|
705
|
+
["Query", "Mutation", "Subscription"],
|
|
706
|
+
globalDefinitions.objectTypeMap
|
|
707
|
+
),
|
|
708
|
+
...printEnumTypesFromMap(globalDefinitions.enumTypeMap),
|
|
709
|
+
...printObjectTypeTypesFromMap(config, modulesDefinitions.objectTypeMap),
|
|
710
|
+
...printObjectTypeFieldsArgsFromMap(config, globalDefinitions.objectTypeMap),
|
|
711
|
+
...printInputObjectTypeTypesFromMap(config, globalDefinitions.inputObjectTypeMap),
|
|
712
|
+
...printInterfaceTypesFromMap(config, globalDefinitions.interfaceTypeMap),
|
|
713
|
+
...printUnionTypesFromMap(config, globalDefinitions.unionTypeMap)
|
|
714
|
+
].join("\n\n");
|
|
715
|
+
const utilityContent = [
|
|
716
|
+
printUtilityTypes(),
|
|
717
|
+
printBaseScalars(config),
|
|
718
|
+
printBaseObjectTypes(config)
|
|
719
|
+
].join("\n\n");
|
|
720
|
+
const files = [
|
|
721
|
+
{
|
|
722
|
+
filename: join2(options.typesDir, "types.ts"),
|
|
723
|
+
content: typesContent
|
|
1124
724
|
},
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
options.
|
|
1137
|
-
|
|
1138
|
-
|
|
725
|
+
{
|
|
726
|
+
filename: join2(options.typesDir, "utility.ts"),
|
|
727
|
+
content: utilityContent
|
|
728
|
+
},
|
|
729
|
+
{
|
|
730
|
+
filename: join2(options.modulesDir, "index.ts"),
|
|
731
|
+
content: printAutoload({ importExtension: options.importExtension }, modules)
|
|
732
|
+
},
|
|
733
|
+
{
|
|
734
|
+
filename: join2(options.modulesDir, "types.ts"),
|
|
735
|
+
content: printTypesTemplate({
|
|
736
|
+
importExtension: options.importExtension,
|
|
737
|
+
typesDir: options.typesDir,
|
|
738
|
+
modulesDir: options.modulesDir
|
|
739
|
+
}),
|
|
740
|
+
options: {
|
|
741
|
+
allowOverwrite: false,
|
|
742
|
+
disableBiomeHeader: true,
|
|
743
|
+
disableEslintHeader: true,
|
|
744
|
+
disableGenerationNoticeHeader: true
|
|
745
|
+
}
|
|
746
|
+
},
|
|
747
|
+
{
|
|
748
|
+
filename: join2(options.modulesDir, "extensions.ts"),
|
|
749
|
+
content: printExtensionsTemplate(),
|
|
750
|
+
options: {
|
|
751
|
+
allowOverwrite: false,
|
|
752
|
+
disableBiomeHeader: true,
|
|
753
|
+
disableEslintHeader: true,
|
|
754
|
+
disableGenerationNoticeHeader: true
|
|
755
|
+
}
|
|
1139
756
|
}
|
|
1140
|
-
|
|
1141
|
-
const
|
|
1142
|
-
const
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
757
|
+
];
|
|
758
|
+
for (const module of modules) {
|
|
759
|
+
const sources2 = sourcesByModule.get(module);
|
|
760
|
+
const documents = sources2?.map((s) => s.document).filter((el) => el != null) ?? [];
|
|
761
|
+
if (documents.length === 0) continue;
|
|
762
|
+
const document = concatAST(documents);
|
|
763
|
+
const config2 = {
|
|
764
|
+
typesDir: options.typesDir,
|
|
765
|
+
fieldInfo,
|
|
766
|
+
importExtension: options.importExtension,
|
|
767
|
+
modulesDir: options.modulesDir,
|
|
768
|
+
registry: createModuleRegistry(document)
|
|
1149
769
|
};
|
|
1150
|
-
|
|
1151
|
-
|
|
770
|
+
files.push({
|
|
771
|
+
filename: `src/modules/${module}/${options.moduleDefinitionName}`,
|
|
772
|
+
content: [
|
|
773
|
+
printModuleImports(config2, module),
|
|
774
|
+
printModuleMetadata(module, document),
|
|
775
|
+
printBaetaModuleTypes(config2),
|
|
776
|
+
printModuleObjectTypeFields(config2),
|
|
777
|
+
printModuleBuilder(config2, module)
|
|
778
|
+
].join("\n\n")
|
|
779
|
+
});
|
|
780
|
+
}
|
|
781
|
+
return files;
|
|
1152
782
|
}
|
|
1153
783
|
|
|
1154
784
|
// index.ts
|
|
@@ -1168,7 +798,7 @@ function graphqlPlugin() {
|
|
|
1168
798
|
generate: async (ctx, next) => {
|
|
1169
799
|
const items = await generate(ctx.generatorOptions);
|
|
1170
800
|
for (const item of items) {
|
|
1171
|
-
ctx.fileManager.createAndAdd(item.filename, item.content, "graphql");
|
|
801
|
+
ctx.fileManager.createAndAdd(item.filename, item.content, "graphql", item.options);
|
|
1172
802
|
}
|
|
1173
803
|
return next();
|
|
1174
804
|
}
|