graphql-jerky 1.0.5 → 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/build/bin/jerky.cjs +16 -8
- package/build/bin/jerky.mjs +17 -9
- package/build/lib.cjs +532 -221
- package/build/lib.d.ts +1 -0
- package/build/lib.mjs +532 -221
- package/package.json +2 -1
package/build/lib.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import path, { resolve, basename, extname, join } from 'path';
|
|
2
|
+
import { pathToFileURL, fileURLToPath } from 'url';
|
|
1
3
|
import { GraphQLNonNull, GraphQLList, GraphQLScalarType, GraphQLEnumType, GraphQLDirective, Kind, GraphQLObjectType, getNamedType, getNullableType, GraphQLInterfaceType, GraphQLUnionType, GraphQLInputObjectType, DirectiveLocation, GraphQLError, parse as parse$3, Source, buildASTSchema, validateSchema } from 'graphql';
|
|
2
4
|
import jen$1, { jen } from 'jennifer-js';
|
|
3
5
|
import format from 'jennifer-js/format';
|
|
4
6
|
import partition from 'just-partition';
|
|
5
7
|
import pascalCase from 'just-pascal-case';
|
|
6
|
-
import path, { resolve, basename, extname, join } from 'path';
|
|
7
|
-
import { pathToFileURL, fileURLToPath } from 'url';
|
|
8
8
|
import fs from 'fs/promises';
|
|
9
9
|
import ts, { getLineAndCharacterOfPosition } from 'typescript';
|
|
10
10
|
import { globIterate } from 'glob';
|
|
@@ -26,29 +26,44 @@ function resolveModule(specifier, referrer) {
|
|
|
26
26
|
if (url.protocol === "file:") {
|
|
27
27
|
return parseSource(url);
|
|
28
28
|
}
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
throw new Error(`Unsupported protocol: ${url.protocol}`);
|
|
30
|
+
}
|
|
31
|
+
function pushExports(e, name, ...decls) {
|
|
32
|
+
if (!e[name]) {
|
|
33
|
+
e[name] = [];
|
|
31
34
|
}
|
|
35
|
+
e[name].push(...decls);
|
|
32
36
|
}
|
|
33
37
|
async function findExports(source, resolveModuleFn = resolveModule) {
|
|
34
38
|
const exports = {};
|
|
35
39
|
const namedExports = [];
|
|
36
40
|
for (const node of source.statements) {
|
|
37
|
-
if (ts.isFunctionDeclaration(node) ||
|
|
41
|
+
if (ts.isFunctionDeclaration(node) ||
|
|
42
|
+
ts.isClassDeclaration(node) ||
|
|
43
|
+
ts.isInterfaceDeclaration(node)) {
|
|
38
44
|
if (node.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword)) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
const name = node.modifiers.some((m) => m.kind === ts.SyntaxKind.DefaultKeyword)
|
|
46
|
+
? "default"
|
|
47
|
+
: node.name?.getText(source);
|
|
48
|
+
if (name) {
|
|
49
|
+
pushExports(exports, name, {
|
|
50
|
+
declaration: node,
|
|
51
|
+
source,
|
|
52
|
+
name: name,
|
|
53
|
+
});
|
|
45
54
|
}
|
|
46
55
|
}
|
|
47
56
|
}
|
|
48
|
-
else if (ts.isTypeAliasDeclaration(node) ||
|
|
57
|
+
else if (ts.isTypeAliasDeclaration(node) ||
|
|
58
|
+
ts.isEnumDeclaration(node) ||
|
|
59
|
+
ts.isModuleDeclaration(node)) {
|
|
49
60
|
if (node.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword)) {
|
|
50
61
|
const name = node.name.getText(source);
|
|
51
|
-
(exports
|
|
62
|
+
pushExports(exports, name, {
|
|
63
|
+
declaration: node,
|
|
64
|
+
source,
|
|
65
|
+
name: name,
|
|
66
|
+
});
|
|
52
67
|
}
|
|
53
68
|
}
|
|
54
69
|
else if (ts.isVariableStatement(node)) {
|
|
@@ -56,7 +71,11 @@ async function findExports(source, resolveModuleFn = resolveModule) {
|
|
|
56
71
|
for (const decl of node.declarationList.declarations) {
|
|
57
72
|
if (decl.name) {
|
|
58
73
|
const name = decl.name.getText(source);
|
|
59
|
-
(exports
|
|
74
|
+
pushExports(exports, name, {
|
|
75
|
+
declaration: decl,
|
|
76
|
+
source,
|
|
77
|
+
name: name,
|
|
78
|
+
});
|
|
60
79
|
}
|
|
61
80
|
}
|
|
62
81
|
}
|
|
@@ -74,7 +93,7 @@ async function findExports(source, resolveModuleFn = resolveModule) {
|
|
|
74
93
|
if (!(name in moduleExports)) {
|
|
75
94
|
throw new Error(`Exported name ${name} not found in ${JSON.stringify(specifier)}`);
|
|
76
95
|
}
|
|
77
|
-
(exports
|
|
96
|
+
pushExports(exports, name, ...moduleExports[name]);
|
|
78
97
|
}
|
|
79
98
|
}
|
|
80
99
|
else {
|
|
@@ -86,7 +105,9 @@ async function findExports(source, resolveModuleFn = resolveModule) {
|
|
|
86
105
|
}
|
|
87
106
|
}
|
|
88
107
|
}
|
|
89
|
-
else if (!node.exportClause &&
|
|
108
|
+
else if (!node.exportClause &&
|
|
109
|
+
node.moduleSpecifier &&
|
|
110
|
+
ts.isStringLiteral(node.moduleSpecifier)) {
|
|
90
111
|
// export * from 'whatever';
|
|
91
112
|
Object.assign(exports, await findExports(await resolveModuleFn(node.moduleSpecifier.text, new URL(source.fileName)), resolveModuleFn));
|
|
92
113
|
}
|
|
@@ -97,9 +118,10 @@ async function findExports(source, resolveModuleFn = resolveModule) {
|
|
|
97
118
|
for (const statement of source.statements) {
|
|
98
119
|
if (ts.isVariableStatement(statement)) {
|
|
99
120
|
for (const decl of statement.declarationList.declarations) {
|
|
100
|
-
if (ts.isIdentifier(decl.name) &&
|
|
121
|
+
if (ts.isIdentifier(decl.name) &&
|
|
122
|
+
decl.name.getText(source) in names) {
|
|
101
123
|
const name = names[decl.name.getText(source)];
|
|
102
|
-
(exports
|
|
124
|
+
pushExports(exports, name, {
|
|
103
125
|
declaration: decl,
|
|
104
126
|
source,
|
|
105
127
|
name: names[decl.name.getText(source)],
|
|
@@ -108,9 +130,11 @@ async function findExports(source, resolveModuleFn = resolveModule) {
|
|
|
108
130
|
}
|
|
109
131
|
}
|
|
110
132
|
if (ts.isFunctionDeclaration(statement)) {
|
|
111
|
-
if (statement.name &&
|
|
133
|
+
if (statement.name &&
|
|
134
|
+
ts.isIdentifier(statement.name) &&
|
|
135
|
+
statement.name.getText(source) in names) {
|
|
112
136
|
const name = names[statement.name.getText(source)];
|
|
113
|
-
(exports
|
|
137
|
+
pushExports(exports, name, {
|
|
114
138
|
declaration: statement,
|
|
115
139
|
source,
|
|
116
140
|
name: names[statement.name.getText(source)],
|
|
@@ -118,9 +142,11 @@ async function findExports(source, resolveModuleFn = resolveModule) {
|
|
|
118
142
|
}
|
|
119
143
|
}
|
|
120
144
|
if (ts.isClassDeclaration(statement)) {
|
|
121
|
-
if (statement.name &&
|
|
145
|
+
if (statement.name &&
|
|
146
|
+
ts.isIdentifier(statement.name) &&
|
|
147
|
+
statement.name.getText(source) in names) {
|
|
122
148
|
const name = names[statement.name.getText(source)];
|
|
123
|
-
(exports
|
|
149
|
+
pushExports(exports, name, {
|
|
124
150
|
declaration: statement,
|
|
125
151
|
source,
|
|
126
152
|
name: names[statement.name.getText(source)],
|
|
@@ -128,9 +154,11 @@ async function findExports(source, resolveModuleFn = resolveModule) {
|
|
|
128
154
|
}
|
|
129
155
|
}
|
|
130
156
|
if (ts.isTypeAliasDeclaration(statement)) {
|
|
131
|
-
if (statement.name &&
|
|
157
|
+
if (statement.name &&
|
|
158
|
+
ts.isIdentifier(statement.name) &&
|
|
159
|
+
statement.name.getText(source) in names) {
|
|
132
160
|
const name = names[statement.name.getText(source)];
|
|
133
|
-
(exports
|
|
161
|
+
pushExports(exports, name, {
|
|
134
162
|
declaration: statement,
|
|
135
163
|
source,
|
|
136
164
|
name: names[statement.name.getText(source)],
|
|
@@ -138,9 +166,11 @@ async function findExports(source, resolveModuleFn = resolveModule) {
|
|
|
138
166
|
}
|
|
139
167
|
}
|
|
140
168
|
if (ts.isInterfaceDeclaration(statement)) {
|
|
141
|
-
if (statement.name &&
|
|
169
|
+
if (statement.name &&
|
|
170
|
+
ts.isIdentifier(statement.name) &&
|
|
171
|
+
statement.name.getText(source) in names) {
|
|
142
172
|
const name = names[statement.name.getText(source)];
|
|
143
|
-
(exports
|
|
173
|
+
pushExports(exports, name, {
|
|
144
174
|
declaration: statement,
|
|
145
175
|
source,
|
|
146
176
|
name: names[statement.name.getText(source)],
|
|
@@ -148,9 +178,11 @@ async function findExports(source, resolveModuleFn = resolveModule) {
|
|
|
148
178
|
}
|
|
149
179
|
}
|
|
150
180
|
if (ts.isEnumDeclaration(statement)) {
|
|
151
|
-
if (statement.name &&
|
|
181
|
+
if (statement.name &&
|
|
182
|
+
ts.isIdentifier(statement.name) &&
|
|
183
|
+
statement.name.getText(source) in names) {
|
|
152
184
|
const name = names[statement.name.getText(source)];
|
|
153
|
-
(exports
|
|
185
|
+
pushExports(exports, name, {
|
|
154
186
|
declaration: statement,
|
|
155
187
|
source,
|
|
156
188
|
name: names[statement.name.getText(source)],
|
|
@@ -158,13 +190,15 @@ async function findExports(source, resolveModuleFn = resolveModule) {
|
|
|
158
190
|
}
|
|
159
191
|
}
|
|
160
192
|
if (ts.isImportDeclaration(statement)) {
|
|
161
|
-
if (statement.importClause
|
|
193
|
+
if (statement.importClause?.namedBindings &&
|
|
162
194
|
ts.isNamedImports(statement.importClause.namedBindings)) {
|
|
163
195
|
let importExports;
|
|
164
196
|
for (const element of statement.importClause.namedBindings.elements) {
|
|
165
|
-
if (element.propertyName &&
|
|
197
|
+
if (element.propertyName &&
|
|
198
|
+
ts.isIdentifier(element.propertyName) &&
|
|
166
199
|
element.propertyName.getText(source) in names) {
|
|
167
|
-
if (!importExports &&
|
|
200
|
+
if (!importExports &&
|
|
201
|
+
ts.isStringLiteral(statement.moduleSpecifier)) {
|
|
168
202
|
const specifier = statement.moduleSpecifier.getText(source);
|
|
169
203
|
importExports = await findExports(await resolveModuleFn(specifier, new URL(source.fileName)), resolveModuleFn);
|
|
170
204
|
}
|
|
@@ -175,7 +209,7 @@ async function findExports(source, resolveModuleFn = resolveModule) {
|
|
|
175
209
|
throw new Error(`Exported name ${element.name.getText(source)} not found in ${JSON.stringify(statement.moduleSpecifier.getText(source))}`);
|
|
176
210
|
}
|
|
177
211
|
const name = names[element.propertyName.getText(source)];
|
|
178
|
-
(exports
|
|
212
|
+
pushExports(exports, name, {
|
|
179
213
|
declaration: element,
|
|
180
214
|
source,
|
|
181
215
|
name: names[element.propertyName.getText(source)],
|
|
@@ -188,9 +222,11 @@ async function findExports(source, resolveModuleFn = resolveModule) {
|
|
|
188
222
|
}
|
|
189
223
|
return exports;
|
|
190
224
|
}
|
|
191
|
-
async function parseModule(
|
|
192
|
-
const url = typeof
|
|
193
|
-
|
|
225
|
+
async function parseModule(sourceOrPath) {
|
|
226
|
+
const url = typeof sourceOrPath === "string"
|
|
227
|
+
? pathToFileURL(resolve(sourceOrPath))
|
|
228
|
+
: new URL(sourceOrPath.fileName);
|
|
229
|
+
const source = typeof sourceOrPath === "string" ? await parseSource(url) : sourceOrPath;
|
|
194
230
|
return {
|
|
195
231
|
path: url,
|
|
196
232
|
exports: await findExports(source),
|
|
@@ -202,7 +238,8 @@ async function parseModule(source) {
|
|
|
202
238
|
*
|
|
203
239
|
* @see https://github.com/microsoft/TypeScript/blob/0d0a79371471d627ae298a145f8009b05cbccb72/src/compiler/scanner.ts#L81
|
|
204
240
|
*/
|
|
205
|
-
const keywords = new Set(Object.keys(ts
|
|
241
|
+
const keywords = new Set(Object.keys(ts
|
|
242
|
+
.textToKeywordObj));
|
|
206
243
|
|
|
207
244
|
class RequiredPackages {
|
|
208
245
|
requires;
|
|
@@ -222,8 +259,11 @@ class RequiredPackages {
|
|
|
222
259
|
this.requires[pkg] = new Set();
|
|
223
260
|
}
|
|
224
261
|
let symbol = alias || name;
|
|
225
|
-
if ((symbol in this.symbols || keywords.has(symbol)) &&
|
|
226
|
-
|
|
262
|
+
if ((symbol in this.symbols || keywords.has(symbol)) &&
|
|
263
|
+
this.symbols[symbol] !== pkg) {
|
|
264
|
+
for (let i = 1;
|
|
265
|
+
// biome-ignore lint/suspicious/noAssignInExpressions: it works don't fix it
|
|
266
|
+
this.symbols[(symbol = `${name}$${i}`)] && this.symbols[symbol] !== pkg; i++)
|
|
227
267
|
;
|
|
228
268
|
}
|
|
229
269
|
this.requires[pkg].add(symbol);
|
|
@@ -236,7 +276,9 @@ class RequiredPackages {
|
|
|
236
276
|
}
|
|
237
277
|
|
|
238
278
|
function renderSymbolReference(pkgs, ref, alias) {
|
|
239
|
-
const ns =
|
|
279
|
+
const ns = ref.module
|
|
280
|
+
? jen.id(pkgs.addRequires(ref.module, ref.symbol, alias ?? ref.alias))
|
|
281
|
+
: jen.id(ref.symbol);
|
|
240
282
|
return ref.property ? ns.dot(ref.property) : ns;
|
|
241
283
|
}
|
|
242
284
|
|
|
@@ -263,7 +305,7 @@ function renderImports(base, imports, aliases, extMode = "omit") {
|
|
|
263
305
|
if (mod.startsWith("file:///")) {
|
|
264
306
|
mod = fileURLToPath(mod);
|
|
265
307
|
}
|
|
266
|
-
if (mod.startsWith(
|
|
308
|
+
if (mod.startsWith("/")) {
|
|
267
309
|
mod = path.relative(base, mod);
|
|
268
310
|
if (!mod.startsWith(".")) {
|
|
269
311
|
mod = `./${mod}`;
|
|
@@ -278,13 +320,21 @@ function renderImports(base, imports, aliases, extMode = "omit") {
|
|
|
278
320
|
else if (extMode === "replace") {
|
|
279
321
|
mod = mod.replace(/\.ts$/, ".js");
|
|
280
322
|
}
|
|
281
|
-
return jen$1.import
|
|
282
|
-
.
|
|
283
|
-
.
|
|
323
|
+
return jen$1.import
|
|
324
|
+
.obj(...Array.from(symbols)
|
|
325
|
+
.sort((a, b) => a.localeCompare(b) ||
|
|
326
|
+
importAlias(a).localeCompare(importAlias(b)))
|
|
327
|
+
.map((symbol) => symbol in aliases
|
|
328
|
+
? jen$1.id(aliases[symbol]).as.id(symbol)
|
|
329
|
+
: jen$1.id(symbol)))
|
|
330
|
+
.from.lit(mod);
|
|
284
331
|
}));
|
|
285
332
|
}
|
|
286
333
|
function renderAstNode(astNode) {
|
|
287
|
-
return jen$1
|
|
334
|
+
return jen$1
|
|
335
|
+
.id("JSON")
|
|
336
|
+
.dot("parse")
|
|
337
|
+
.call(jen$1.literal(JSON.stringify(astNode, (key, value) => key === "loc" ? undefined : value)));
|
|
288
338
|
}
|
|
289
339
|
function isBuiltInDirective(name) {
|
|
290
340
|
// https://spec.graphql.org/draft/#sec-Type-System.Directives.Built-in-Directives
|
|
@@ -309,6 +359,7 @@ class GeneratorContext {
|
|
|
309
359
|
_resolversInfo;
|
|
310
360
|
_subscribersInfo;
|
|
311
361
|
_graphqlModuleSpecifier;
|
|
362
|
+
_includeSubscriptionFieldResolvers;
|
|
312
363
|
constructor(options = {}) {
|
|
313
364
|
this._scalarsInfo = options.scalarsInfo ?? {};
|
|
314
365
|
this._fieldDirectivesInfo = options.fieldDirectivesInfo ?? {};
|
|
@@ -318,32 +369,46 @@ class GeneratorContext {
|
|
|
318
369
|
this._graphqlModuleSpecifier = options.graphqlModuleSpecifier ?? "graphql";
|
|
319
370
|
this._pkgs = new RequiredPackages();
|
|
320
371
|
this._extMode = options.extMode ?? "omit";
|
|
372
|
+
this._includeSubscriptionFieldResolvers = options.includeSubscriptionFieldResolvers ?? false;
|
|
321
373
|
}
|
|
322
374
|
_gql(name) {
|
|
323
375
|
return jen$1.id(this._pkgs.addRequires(this._graphqlModuleSpecifier, name));
|
|
324
376
|
}
|
|
325
377
|
_renderGraphQLTypeIdentifier(type) {
|
|
326
378
|
if (type instanceof GraphQLNonNull) {
|
|
327
|
-
return jen$1.new
|
|
379
|
+
return jen$1.new
|
|
380
|
+
.add(this._gql("GraphQLNonNull"))
|
|
381
|
+
.params(this._renderGraphQLTypeIdentifier(type.ofType));
|
|
328
382
|
}
|
|
329
383
|
if (type instanceof GraphQLList) {
|
|
330
|
-
return jen$1.new
|
|
384
|
+
return jen$1.new
|
|
385
|
+
.add(this._gql("GraphQLList"))
|
|
386
|
+
.params(this._renderGraphQLTypeIdentifier(type.ofType));
|
|
331
387
|
}
|
|
332
388
|
if (type instanceof GraphQLScalarType) {
|
|
333
389
|
if (isPrimitiveType(type)) {
|
|
334
|
-
return this._gql(
|
|
390
|
+
return this._gql(`GraphQL${type.name}`);
|
|
335
391
|
}
|
|
336
|
-
return jen$1.id(type.name
|
|
392
|
+
return jen$1.id(`${type.name}Scalar`);
|
|
337
393
|
}
|
|
338
|
-
return jen$1.id(type.name +
|
|
394
|
+
return jen$1.id(type.name +
|
|
395
|
+
(type instanceof GraphQLEnumType
|
|
396
|
+
? "Enum"
|
|
397
|
+
: type instanceof GraphQLDirective
|
|
398
|
+
? "Directive"
|
|
399
|
+
: "Type"));
|
|
339
400
|
}
|
|
340
401
|
_renderArgumentsObject(args) {
|
|
341
402
|
return jen$1.obj(...Array.from(args)
|
|
342
403
|
.sort(compareName)
|
|
404
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
343
405
|
.map((arg) => jen$1.prop(arg.name, jen$1.obj(jen$1.prop("type", this._renderGraphQLTypeIdentifier(arg.type)), ...truthify([
|
|
344
|
-
arg.description &&
|
|
345
|
-
|
|
346
|
-
arg.
|
|
406
|
+
arg.description &&
|
|
407
|
+
jen$1.prop("description", jen$1.lit(arg.description)),
|
|
408
|
+
arg.defaultValue &&
|
|
409
|
+
jen$1.prop("defaultValue", jen$1.lit(arg.defaultValue)),
|
|
410
|
+
arg.deprecationReason &&
|
|
411
|
+
jen$1.prop("deprecationReason", jen$1.lit(arg.deprecationReason)),
|
|
347
412
|
])))));
|
|
348
413
|
}
|
|
349
414
|
_renderValueNode(node) {
|
|
@@ -374,7 +439,8 @@ class GeneratorContext {
|
|
|
374
439
|
if (type instanceof GraphQLObjectType && !resolver) {
|
|
375
440
|
// try to find resolver in interface in the declaration order
|
|
376
441
|
for (const iface of type.getInterfaces()) {
|
|
377
|
-
|
|
442
|
+
resolver = this._resolversInfo[iface.name]?.[f.name];
|
|
443
|
+
if (resolver) {
|
|
378
444
|
break;
|
|
379
445
|
}
|
|
380
446
|
}
|
|
@@ -388,24 +454,36 @@ class GeneratorContext {
|
|
|
388
454
|
continue;
|
|
389
455
|
}
|
|
390
456
|
if (!resolveFn) {
|
|
391
|
-
resolveFn = jen$1
|
|
457
|
+
resolveFn = jen$1
|
|
458
|
+
.arrow(jen$1.id("source").op(":").any)
|
|
459
|
+
.id("source")
|
|
460
|
+
.dot(f.name);
|
|
392
461
|
}
|
|
393
|
-
resolveFn = renderSymbolReference(this._pkgs, ref, `apply${pascalCase(directive.name.value)}FieldDirective`).call(resolveFn, ...(directive.arguments?.length
|
|
462
|
+
resolveFn = renderSymbolReference(this._pkgs, ref, `apply${pascalCase(directive.name.value)}FieldDirective`).call(resolveFn, ...(directive.arguments?.length
|
|
463
|
+
? [this._renderArgumentNodes(directive.arguments)]
|
|
464
|
+
: []));
|
|
394
465
|
}
|
|
395
466
|
}
|
|
396
467
|
if (resolveFn) {
|
|
397
468
|
// args probably don't need to be transformed if there's no resolver
|
|
398
469
|
const argsWithDirectives = truthify(f.args?.map((arg) => this._findInputDirectiveInfoFromArgOrField(arg, inputFieldDirectives)) ?? []);
|
|
399
470
|
if (argsWithDirectives.length) {
|
|
400
|
-
resolveFn = jen$1
|
|
471
|
+
resolveFn = jen$1
|
|
472
|
+
.parens(jen$1
|
|
473
|
+
.params(jen$1.prop("next", this._gql("GraphQLFieldResolver").types(jen$1.any, jen$1.any)))
|
|
474
|
+
.op(":")
|
|
401
475
|
.add(this._gql("GraphQLFieldResolver"))
|
|
402
|
-
.types(jen$1.any, jen$1.any, jen$1.id(type.name).dot(pascalCase(f.name
|
|
403
|
-
.op("=>")
|
|
476
|
+
.types(jen$1.any, jen$1.any, jen$1.id(type.name).dot(pascalCase(`${f.name}_args`)))
|
|
477
|
+
.op("=>")
|
|
478
|
+
.arrow(jen$1.id("source"), jen$1.id("args"), jen$1.id("context"), jen$1.id("info"))
|
|
479
|
+
.id("next")
|
|
480
|
+
.call(jen$1.id("source"), this._renderInputFieldsWithDirectives(jen$1.id("args"), argsWithDirectives, argsWithDirectives.length < (f.args?.length ?? 0)), jen$1.id("context"), jen$1.id("info")))
|
|
481
|
+
.call(resolveFn);
|
|
404
482
|
}
|
|
405
483
|
}
|
|
406
484
|
}
|
|
407
485
|
// NOTE: The way subscribers work in the graphql-js is by calling `subscribe` on the top level fields, and then
|
|
408
|
-
// calling `resolve` on the nested fields. This means that subscribers only need to be defined on
|
|
486
|
+
// calling `resolve` on the nested fields. This means that subscribers only need to be defined on
|
|
409
487
|
// `Subscription`.
|
|
410
488
|
//
|
|
411
489
|
// In theory, an alternate implementation could be created to call `subscribe` at every level, but considering
|
|
@@ -419,18 +497,25 @@ class GeneratorContext {
|
|
|
419
497
|
f.args?.length && jen$1.prop("args", this._renderArgumentsObject(f.args)),
|
|
420
498
|
f.defaultValue && jen$1.prop("defaultValue", jen$1.lit(f.defaultValue)),
|
|
421
499
|
f.description && jen$1.prop("description", jen$1.lit(f.description)),
|
|
422
|
-
f.deprecationReason &&
|
|
500
|
+
f.deprecationReason &&
|
|
501
|
+
jen$1.prop("deprecationReason", jen$1.lit(f.deprecationReason)),
|
|
423
502
|
// NOTE: Resolver functions on interface definitions are not used by the default graphql-js
|
|
424
503
|
// executor implementation, but nonetheless accessible by a potential alternate implementation.
|
|
425
504
|
resolveFn && jen$1.prop("resolve", jen$1.parens(resolveFn).as.any),
|
|
426
|
-
subscriber &&
|
|
505
|
+
subscriber &&
|
|
506
|
+
jen$1.prop("subscribe", jen$1.parens(renderSymbolReference(this._pkgs, subscriber)).as.any),
|
|
427
507
|
astNodeExpr && jen$1.prop("astNode", astNodeExpr),
|
|
428
508
|
]));
|
|
429
509
|
}
|
|
430
510
|
_renderFieldsThunk(type, inputFieldDirectives, includeAstNodes, noresolver) {
|
|
431
511
|
let astNodeExpr;
|
|
432
512
|
if (includeAstNodes) {
|
|
433
|
-
astNodeExpr = jen$1
|
|
513
|
+
astNodeExpr = jen$1
|
|
514
|
+
.id(`${type.name}Type`)
|
|
515
|
+
.dot("astNode")
|
|
516
|
+
.op("?")
|
|
517
|
+
.dot("fields")
|
|
518
|
+
.op("?.");
|
|
434
519
|
}
|
|
435
520
|
return jen$1.arrow().parens(jen$1.obj(...Object.values(type.getFields())
|
|
436
521
|
.map((field, i) => [field, i])
|
|
@@ -452,7 +537,7 @@ class GeneratorContext {
|
|
|
452
537
|
return "unknown";
|
|
453
538
|
}
|
|
454
539
|
if (type instanceof GraphQLEnumType) {
|
|
455
|
-
return
|
|
540
|
+
return `E${type.name}`;
|
|
456
541
|
}
|
|
457
542
|
return type.name;
|
|
458
543
|
}
|
|
@@ -488,19 +573,22 @@ class GeneratorContext {
|
|
|
488
573
|
}
|
|
489
574
|
}
|
|
490
575
|
if (!returnType) {
|
|
491
|
-
console.log(
|
|
576
|
+
console.log(`WARNING: Could not determine scalar ${type.name} type from parseValue or parseLiteral`);
|
|
492
577
|
}
|
|
493
|
-
|
|
578
|
+
this._scalarTypeTypeCache[type.name] = returnType;
|
|
579
|
+
return returnType;
|
|
494
580
|
}
|
|
495
581
|
_renderGraphQLTypeType(type) {
|
|
496
582
|
if (type instanceof GraphQLNonNull) {
|
|
497
583
|
return this._renderGraphQLTypeType(type.ofType);
|
|
498
584
|
}
|
|
499
585
|
if (type instanceof GraphQLList) {
|
|
500
|
-
return jen$1
|
|
586
|
+
return jen$1
|
|
587
|
+
.id("Array")
|
|
588
|
+
.types(this._renderOptionalGraphQLTypeType(type.ofType));
|
|
501
589
|
}
|
|
502
590
|
if (type instanceof GraphQLDirective) {
|
|
503
|
-
throw new Error(
|
|
591
|
+
throw new Error(`unexpected directive type ${type.name}`);
|
|
504
592
|
}
|
|
505
593
|
return jen$1.id(this._deriveGraphQLTypeName(type));
|
|
506
594
|
}
|
|
@@ -511,13 +599,20 @@ class GeneratorContext {
|
|
|
511
599
|
}
|
|
512
600
|
_renderGraphQLObjectTypeDefinition(type, { inputFieldDirectives, includeAstNodes }) {
|
|
513
601
|
const typeInterfaces = type.getInterfaces();
|
|
514
|
-
return jen$1.new
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
602
|
+
return jen$1.new
|
|
603
|
+
.add(this._gql("GraphQLObjectType"))
|
|
604
|
+
.call(jen$1.obj(jen$1.prop("name", jen$1.lit(type.name)), jen$1.prop("fields", this._renderFieldsThunk(type, inputFieldDirectives, includeAstNodes, !this._includeSubscriptionFieldResolvers && type.name === "Subscription")), ...truthify([
|
|
605
|
+
type.description &&
|
|
606
|
+
jen$1.prop("description", jen$1.lit(type.description)),
|
|
607
|
+
typeInterfaces.length &&
|
|
608
|
+
jen$1.prop("interfaces", jen$1.arrow().arr(
|
|
609
|
+
// do not sort interfaces, the declaration order may be important
|
|
610
|
+
...typeInterfaces.map(this._renderGraphQLTypeIdentifier, this))),
|
|
611
|
+
includeAstNodes &&
|
|
612
|
+
type.astNode &&
|
|
613
|
+
jen$1.prop("astNode", renderAstNode(type.astNode)),
|
|
614
|
+
])))
|
|
615
|
+
.as.add(this._gql("GraphQLObjectType"));
|
|
521
616
|
}
|
|
522
617
|
_renderGraphQLObjectTypeTypes(type) {
|
|
523
618
|
const fieldsWithArgs = Object.values(type.getFields())
|
|
@@ -527,7 +622,7 @@ class GeneratorContext {
|
|
|
527
622
|
jen$1.export.add(this._renderTypeInterface(type)),
|
|
528
623
|
...(fieldsWithArgs.length
|
|
529
624
|
? [
|
|
530
|
-
jen$1.export.namespace.add(this._renderGraphQLTypeType(type)).block(...fieldsWithArgs.map((field) => jen$1.export.interface.id(pascalCase(field.name
|
|
625
|
+
jen$1.export.namespace.add(this._renderGraphQLTypeType(type)).block(...fieldsWithArgs.map((field) => jen$1.export.interface.id(pascalCase(`${field.name}_args`)).block(...Array.from(field.args)
|
|
531
626
|
.sort(compareName)
|
|
532
627
|
.map((arg) => jen$1.prop(arg.name, this._renderOptionalGraphQLTypeType(arg.type)))))),
|
|
533
628
|
]
|
|
@@ -536,30 +631,64 @@ class GeneratorContext {
|
|
|
536
631
|
}
|
|
537
632
|
_renderGraphQLScalarTypeDefinition(type) {
|
|
538
633
|
const s = this._scalarsInfo[type.name];
|
|
539
|
-
return jen$1.new
|
|
540
|
-
|
|
541
|
-
jen$1.
|
|
542
|
-
|
|
543
|
-
|
|
634
|
+
return jen$1.new
|
|
635
|
+
.add(this._gql("GraphQLScalarType"))
|
|
636
|
+
.call(jen$1.obj(jen$1.prop("name", jen$1.lit(type.name)), ...truthify([
|
|
637
|
+
type.description &&
|
|
638
|
+
jen$1.prop("description", jen$1.lit(type.description)),
|
|
639
|
+
jen$1.prop("serialize", s?.serializeFunc
|
|
640
|
+
? renderSymbolReference(this._pkgs, s.serializeFunc)
|
|
641
|
+
: jen$1.trivia("stub").arrow(jen$1.id("v")).id("v")),
|
|
642
|
+
s?.parseValueFunc &&
|
|
643
|
+
jen$1.prop("parseValue", renderSymbolReference(this._pkgs, s.parseValueFunc)),
|
|
644
|
+
s?.parseLiteralFunc &&
|
|
645
|
+
jen$1.prop("parseLiteral", renderSymbolReference(this._pkgs, s.parseLiteralFunc)),
|
|
544
646
|
])));
|
|
545
647
|
}
|
|
546
648
|
_renderTypeResolverAndCastFunctions(type, subTypes, prefix) {
|
|
547
649
|
const sortedSubTypes = Array.from(subTypes).sort(compareName);
|
|
548
650
|
return [
|
|
549
|
-
jen$1
|
|
651
|
+
jen$1
|
|
652
|
+
.arrow(jen$1.prop("v", jen$1.any))
|
|
653
|
+
.block(jen$1
|
|
654
|
+
.switch(jen$1.id("v").computed(jen$1.id(`${prefix}Symbol_${type.name}`)))
|
|
655
|
+
.block(...sortedSubTypes.map((subType) => jen$1
|
|
656
|
+
.case(jen$1.id(`${prefix}TypeSymbol_${subType.name}_${type.name}`))
|
|
657
|
+
.return(jen$1.lit(subType.name)))), jen$1.return(jen$1.id("v").dot("__typename"))),
|
|
550
658
|
[
|
|
551
|
-
jen$1.const
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
.
|
|
659
|
+
jen$1.const
|
|
660
|
+
.id(`${prefix}Symbol_${type.name}`)
|
|
661
|
+
.op("=")
|
|
662
|
+
.id("Symbol")
|
|
663
|
+
.call(jen$1.lit(`${type.name} type`)),
|
|
664
|
+
...sortedSubTypes.map((subType) => jen$1.const
|
|
665
|
+
.id(`${prefix}TypeSymbol_${subType.name}_${type.name}`)
|
|
666
|
+
.op("=")
|
|
667
|
+
.id("Symbol")
|
|
668
|
+
.call(jen$1.lit(`${subType.name} ${type.name}`))),
|
|
669
|
+
...sortedSubTypes.map((subType) => jen$1.export.const
|
|
670
|
+
.id(`as${subType.name}${type.name}`)
|
|
671
|
+
.op("=")
|
|
672
|
+
.types(jen$1.id("T"))
|
|
673
|
+
.params(jen$1.prop("v", jen$1.any))
|
|
674
|
+
.op(":")
|
|
675
|
+
.intersect(jen$1.id("T"), jen$1.obj(jen$1.prop(jen$1.computed(jen$1.id(`${prefix}Symbol_${type.name}`)), jen$1.symbol)))
|
|
676
|
+
.op("=>")
|
|
677
|
+
.parens(jen$1.obj(jen$1.spread(jen$1.id("v")), jen$1.prop(jen$1.computed(jen$1.id(`${prefix}Symbol_${type.name}`)), jen$1.id(`${prefix}TypeSymbol_${subType.name}_${type.name}`))))),
|
|
555
678
|
],
|
|
556
679
|
];
|
|
557
680
|
}
|
|
558
681
|
_renderGraphQLInterfaceTypeDefinition(type, { inputFieldDirectives, includeAstNodes }) {
|
|
559
|
-
return jen$1.new
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
682
|
+
return jen$1.new
|
|
683
|
+
.add(this._gql("GraphQLInterfaceType"))
|
|
684
|
+
.call(jen$1.obj(jen$1.prop("name", jen$1.lit(type.name)), jen$1.prop("fields", this._renderFieldsThunk(type, inputFieldDirectives, includeAstNodes)), ...truthify([
|
|
685
|
+
type.description &&
|
|
686
|
+
jen$1.prop("description", jen$1.lit(type.description)),
|
|
687
|
+
includeAstNodes &&
|
|
688
|
+
type.astNode &&
|
|
689
|
+
jen$1.prop("astNode", renderAstNode(type.astNode)),
|
|
690
|
+
])))
|
|
691
|
+
.as.add(this._gql("GraphQLInterfaceType"));
|
|
563
692
|
}
|
|
564
693
|
_renderGraphQLInterfaceTypeTypes(type, { implementors: { implementors } }) {
|
|
565
694
|
const fieldsWithArgs = Object.values(type.getFields())
|
|
@@ -567,30 +696,55 @@ class GeneratorContext {
|
|
|
567
696
|
.sort(compareName);
|
|
568
697
|
return [
|
|
569
698
|
jen$1.export.add(this._renderTypeInterface(type)),
|
|
570
|
-
jen$1.export.namespace.id(type.name).block(...implementors.map((implementor) => jen$1.export.const
|
|
571
|
-
.
|
|
699
|
+
jen$1.export.namespace.id(type.name).block(...implementors.map((implementor) => jen$1.export.const
|
|
700
|
+
.id(`as${pascalCase(implementor.name)}`)
|
|
701
|
+
.op("=")
|
|
702
|
+
.types(jen$1.id("T"))
|
|
703
|
+
.params(jen$1.prop("v", jen$1.id("T")))
|
|
704
|
+
.op("=>")
|
|
705
|
+
.id("setTypename")
|
|
706
|
+
.call(jen$1.id("v"), jen$1.lit(implementor.name))), ...fieldsWithArgs.map((field) => jen$1.export.interface.id(pascalCase(`${field.name}_args`)).block(...Array.from(field.args)
|
|
572
707
|
.sort(compareName)
|
|
573
708
|
.map((arg) => jen$1.prop(arg.name, this._renderOptionalGraphQLTypeType(arg.type)))))),
|
|
574
709
|
];
|
|
575
710
|
}
|
|
576
711
|
_renderGraphQLUnionTypeDefinition(type) {
|
|
577
|
-
return jen$1.new
|
|
578
|
-
|
|
712
|
+
return jen$1.new
|
|
713
|
+
.add(this._gql("GraphQLUnionType"))
|
|
714
|
+
.call(jen$1.obj(jen$1.prop("name", jen$1.lit(type.name)), jen$1.prop("types", jen$1
|
|
715
|
+
.arrow()
|
|
716
|
+
.array(...type
|
|
717
|
+
.getTypes()
|
|
718
|
+
.map((type) => this._renderGraphQLTypeIdentifier(type)))), ...truthify([
|
|
719
|
+
type.description &&
|
|
720
|
+
jen$1.prop("description", jen$1.lit(type.description)),
|
|
579
721
|
])));
|
|
580
722
|
}
|
|
581
723
|
_renderGraphQLUnionTypeTypes(type) {
|
|
582
724
|
return [
|
|
583
|
-
jen$1.export.type
|
|
584
|
-
|
|
585
|
-
.
|
|
725
|
+
jen$1.export.type
|
|
726
|
+
.add(this._renderGraphQLTypeType(type))
|
|
727
|
+
.op("=")
|
|
728
|
+
.union(...Array.from(type.getTypes())
|
|
729
|
+
.sort(compareName)
|
|
730
|
+
.map(this._renderGraphQLTypeType, this)),
|
|
731
|
+
jen$1.export.namespace.id(type.name).block(...type.getTypes().map((type) => jen$1.export.const
|
|
732
|
+
.id(`as${pascalCase(type.name)}`)
|
|
733
|
+
.op("=")
|
|
734
|
+
.types(jen$1.id("T"))
|
|
735
|
+
.params(jen$1.prop("v", jen$1.id("T")))
|
|
736
|
+
.op("=>")
|
|
737
|
+
.id("setTypename")
|
|
738
|
+
.call(jen$1.id("v"), jen$1.lit(type.name)))),
|
|
586
739
|
];
|
|
587
740
|
}
|
|
588
741
|
_findInputDirectiveInfoFromArgOrField(field, inputFieldDirectives) {
|
|
589
742
|
const fieldTypeName = getNamedType(field.type).name;
|
|
590
743
|
let transform;
|
|
591
|
-
if (inputFieldDirectives[fieldTypeName] &&
|
|
744
|
+
if (inputFieldDirectives[fieldTypeName] &&
|
|
745
|
+
Object.keys(inputFieldDirectives[fieldTypeName]).length) {
|
|
592
746
|
transform = {
|
|
593
|
-
symbol:
|
|
747
|
+
symbol: `transform${fieldTypeName}`,
|
|
594
748
|
};
|
|
595
749
|
}
|
|
596
750
|
if (field.astNode?.directives?.length) {
|
|
@@ -610,9 +764,7 @@ class GeneratorContext {
|
|
|
610
764
|
}
|
|
611
765
|
}
|
|
612
766
|
_renderInputFieldsWithDirectives(valueExpr, fieldsWithDirectives, spread) {
|
|
613
|
-
return jen$1.obj(...truthify([
|
|
614
|
-
spread && jen$1.spread(valueExpr),
|
|
615
|
-
]), ...fieldsWithDirectives.map(({ field, directives, transform }) => {
|
|
767
|
+
return jen$1.obj(...truthify([spread && jen$1.spread(valueExpr)]), ...fieldsWithDirectives.map(({ field, directives, transform }) => {
|
|
616
768
|
const fieldExpr = valueExpr.dot(field.name);
|
|
617
769
|
const nullableType = getNullableType(field.type);
|
|
618
770
|
let transformedExpr;
|
|
@@ -629,48 +781,84 @@ class GeneratorContext {
|
|
|
629
781
|
transformedExpr = renderSymbolReference(this._pkgs, ref).call(transformedExpr, this._renderArgumentNodes(args));
|
|
630
782
|
}
|
|
631
783
|
if (nullableType instanceof GraphQLList) {
|
|
632
|
-
transformedExpr = jen$1
|
|
784
|
+
transformedExpr = jen$1
|
|
785
|
+
.id("Array")
|
|
786
|
+
.dot("from")
|
|
787
|
+
.call(valueExpr.dot(field.name), jen$1.arrow(jen$1.id("elem")).add(transformedExpr));
|
|
633
788
|
if (!(field.type instanceof GraphQLNonNull)) {
|
|
634
|
-
transformedExpr = jen$1.cond(valueExpr
|
|
789
|
+
transformedExpr = jen$1.cond(valueExpr
|
|
790
|
+
.dot(field.name)
|
|
791
|
+
.op("===")
|
|
792
|
+
.null.op("||")
|
|
793
|
+
.add(valueExpr)
|
|
794
|
+
.dot(field.name)
|
|
795
|
+
.op("===").undefined, jen$1.undefined, transformedExpr);
|
|
635
796
|
}
|
|
636
797
|
}
|
|
637
798
|
return jen$1.prop(field.name, transformedExpr);
|
|
638
799
|
}));
|
|
639
800
|
}
|
|
640
801
|
_renderGraphQLInputObjectTypeDefinition(type, { inputFieldDirectives, includeAstNodes }) {
|
|
641
|
-
return jen$1.new
|
|
642
|
-
|
|
643
|
-
|
|
802
|
+
return jen$1.new
|
|
803
|
+
.add(this._gql("GraphQLInputObjectType"))
|
|
804
|
+
.call(jen$1.obj(jen$1.prop("name", jen$1.lit(type.name)), jen$1.prop("fields", this._renderFieldsThunk(type, inputFieldDirectives, includeAstNodes, true)), ...truthify([
|
|
805
|
+
type.description &&
|
|
806
|
+
jen$1.prop("description", jen$1.lit(type.description)),
|
|
807
|
+
includeAstNodes &&
|
|
808
|
+
type.astNode &&
|
|
809
|
+
jen$1.prop("astNode", renderAstNode(type.astNode)),
|
|
644
810
|
])));
|
|
645
811
|
}
|
|
646
812
|
_renderGraphQLInputObjectTypeTypes(type, { inputFieldDirectives }) {
|
|
647
|
-
const fieldsWithDirectives = truthify(Object.values(type.getFields())
|
|
648
|
-
.map((f) => this._findInputDirectiveInfoFromArgOrField(f, inputFieldDirectives)));
|
|
813
|
+
const fieldsWithDirectives = truthify(Object.values(type.getFields()).map((f) => this._findInputDirectiveInfoFromArgOrField(f, inputFieldDirectives)));
|
|
649
814
|
return [
|
|
650
815
|
jen$1.export.interface.add(this._renderGraphQLTypeType(type)).block(...Object.values(type.getFields())
|
|
651
816
|
.sort(compareName)
|
|
652
817
|
.map((field) => jen$1.prop(field.name, this._renderOptionalGraphQLTypeType(field.type)))),
|
|
653
818
|
...truthify([
|
|
654
819
|
fieldsWithDirectives.length &&
|
|
655
|
-
jen$1.const
|
|
656
|
-
.
|
|
820
|
+
jen$1.const
|
|
821
|
+
.id(`transform${this._deriveGraphQLTypeName(type)}`)
|
|
822
|
+
.op("=")
|
|
823
|
+
.types(jen$1.id("T").extends.union(jen$1.id(type.name), jen$1.undefined))
|
|
824
|
+
.params(jen$1.prop("v", jen$1.id("T")))
|
|
825
|
+
.op(":")
|
|
826
|
+
.id("T")
|
|
827
|
+
.op("=>")
|
|
828
|
+
.parens(jen$1
|
|
829
|
+
.id("v")
|
|
830
|
+
.op("&&")
|
|
831
|
+
.add(this._renderInputFieldsWithDirectives(jen$1.id("v"), fieldsWithDirectives, fieldsWithDirectives.length <
|
|
832
|
+
Object.keys(type.getFields()).length))),
|
|
657
833
|
]),
|
|
658
834
|
];
|
|
659
835
|
}
|
|
660
836
|
_renderGraphQLEnumTypeDefinition(type) {
|
|
661
837
|
const sortedValues = Array.from(type.getValues()).sort(compareName);
|
|
662
|
-
return jen$1.new
|
|
663
|
-
|
|
664
|
-
|
|
838
|
+
return jen$1.new
|
|
839
|
+
.add(this._gql("GraphQLEnumType"))
|
|
840
|
+
.call(jen$1.obj(jen$1.prop("name", jen$1.lit(type.name)), jen$1.prop("values", jen$1.obj(...sortedValues.map((e) => jen$1.prop(e.name, jen$1.obj(jen$1.prop("value", jen$1.lit(e.value)), ...truthify([
|
|
841
|
+
e.description &&
|
|
842
|
+
jen$1.prop("description", jen$1.lit(e.description)),
|
|
843
|
+
e.deprecationReason &&
|
|
844
|
+
jen$1.prop("deprecationReason", jen$1.lit(e.deprecationReason)),
|
|
665
845
|
])))))), ...truthify([
|
|
666
|
-
type.description &&
|
|
846
|
+
type.description &&
|
|
847
|
+
jen$1.prop("description", jen$1.lit(type.description)),
|
|
667
848
|
])));
|
|
668
849
|
}
|
|
669
850
|
_renderGraphQLEnumTypeTypes(type) {
|
|
670
851
|
const sortedValues = Array.from(type.getValues()).sort(compareName);
|
|
671
852
|
return [
|
|
672
|
-
jen$1.export.enum
|
|
673
|
-
|
|
853
|
+
jen$1.export.enum
|
|
854
|
+
.add(this._renderGraphQLTypeType(type))
|
|
855
|
+
.obj(...sortedValues.map(({ name }) => jen$1.id(name).op("=").lit(name))),
|
|
856
|
+
jen$1.export
|
|
857
|
+
.function(jen$1.id(`is${this._deriveGraphQLTypeName(type)}`), jen$1.prop("v", jen$1.id("any")))
|
|
858
|
+
.op(":")
|
|
859
|
+
.id("v")
|
|
860
|
+
.is.add(this._renderGraphQLTypeType(type))
|
|
861
|
+
.block(jen$1.return(jen$1.id("v").in.add(this._renderGraphQLTypeType(type)))),
|
|
674
862
|
];
|
|
675
863
|
}
|
|
676
864
|
_getRenderDefintionFnForType(type) {
|
|
@@ -692,7 +880,7 @@ class GeneratorContext {
|
|
|
692
880
|
if (type instanceof GraphQLEnumType) {
|
|
693
881
|
return this._renderGraphQLEnumTypeDefinition.bind(this, type);
|
|
694
882
|
}
|
|
695
|
-
throw new Error(
|
|
883
|
+
throw new Error(`unhandled type: ${type.toString()}`);
|
|
696
884
|
}
|
|
697
885
|
_getRenderTypesFnForType(type) {
|
|
698
886
|
if (type instanceof GraphQLObjectType) {
|
|
@@ -713,10 +901,13 @@ class GeneratorContext {
|
|
|
713
901
|
if (type instanceof GraphQLEnumType) {
|
|
714
902
|
return this._renderGraphQLEnumTypeTypes.bind(this, type);
|
|
715
903
|
}
|
|
716
|
-
throw new Error(
|
|
904
|
+
throw new Error(`unhandled type: ${type.toString()}`);
|
|
717
905
|
}
|
|
718
906
|
_renderGraphQLTypeDefinitions(type, interfaces, inputFieldDirectives, includeAstNodes) {
|
|
719
|
-
return jen$1.const
|
|
907
|
+
return jen$1.const
|
|
908
|
+
.add(this._renderGraphQLTypeIdentifier(type))
|
|
909
|
+
.op("=")
|
|
910
|
+
.add(this._getRenderDefintionFnForType(type)({
|
|
720
911
|
implementors: interfaces[type.name],
|
|
721
912
|
inputFieldDirectives,
|
|
722
913
|
includeAstNodes,
|
|
@@ -729,54 +920,101 @@ class GeneratorContext {
|
|
|
729
920
|
});
|
|
730
921
|
}
|
|
731
922
|
_renderGraphQLDirectiveDefinition(directive, includeAstNodes) {
|
|
732
|
-
return jen$1.const
|
|
733
|
-
.
|
|
734
|
-
|
|
923
|
+
return jen$1.const
|
|
924
|
+
.add(this._renderGraphQLTypeIdentifier(directive))
|
|
925
|
+
.op("=")
|
|
926
|
+
.new.add(this._gql("GraphQLDirective"))
|
|
927
|
+
.call(jen$1.obj(jen$1.prop("name", jen$1.lit(directive.name)), jen$1.prop("locations", jen$1.array(...Array.from(directive.locations)
|
|
928
|
+
.sort()
|
|
929
|
+
.map((location) => jen$1.add(this._gql("DirectiveLocation")).dot(location)))), jen$1.prop("args", this._renderArgumentsObject(directive.args)), ...truthify([
|
|
930
|
+
directive.description &&
|
|
931
|
+
jen$1.prop("description", jen$1.lit(directive.description)),
|
|
735
932
|
directive.isRepeatable && jen$1.prop("isRepeatable", jen$1.true),
|
|
736
|
-
includeAstNodes &&
|
|
933
|
+
includeAstNodes &&
|
|
934
|
+
directive.astNode &&
|
|
935
|
+
jen$1.prop("astNode", renderAstNode(directive.astNode)),
|
|
737
936
|
])));
|
|
738
937
|
}
|
|
739
938
|
_renderGraphQLDirectiveTypes(directive) {
|
|
740
939
|
return truthify([
|
|
741
|
-
directive.args.length &&
|
|
742
|
-
|
|
743
|
-
|
|
940
|
+
directive.args.length &&
|
|
941
|
+
jen$1.export.interface
|
|
942
|
+
.id(pascalCase(`${directive.name}_directive_args`))
|
|
943
|
+
.block(...directive.args.map((arg) => jen$1.prop(jen$1
|
|
944
|
+
.id(arg.name)
|
|
945
|
+
.add(...truthify([
|
|
946
|
+
!(arg.type instanceof GraphQLNonNull) && jen$1.op("?"),
|
|
947
|
+
])), this._renderGraphQLTypeType(arg.type)))),
|
|
744
948
|
]);
|
|
745
949
|
}
|
|
746
950
|
schemaExprs(schema, [types, interfaces, inputFieldDirectives, includeAstNodes]) {
|
|
951
|
+
const queryType = schema.getQueryType();
|
|
952
|
+
const mutationType = schema.getMutationType();
|
|
953
|
+
const subscriptionType = schema.getSubscriptionType();
|
|
747
954
|
return [
|
|
748
955
|
...[
|
|
749
956
|
// render type definitions
|
|
750
957
|
...types
|
|
751
|
-
.map((type) => [
|
|
958
|
+
.map((type) => [
|
|
959
|
+
type.name,
|
|
960
|
+
this._renderGraphQLTypeDefinitions(type, interfaces, inputFieldDirectives, includeAstNodes),
|
|
961
|
+
])
|
|
752
962
|
.sort(compareEntryKey),
|
|
753
963
|
// render directive definitions
|
|
754
|
-
...schema
|
|
964
|
+
...schema
|
|
965
|
+
.getDirectives()
|
|
755
966
|
.filter((d) => !isBuiltInDirective(d.name))
|
|
756
|
-
.map((directive) => [
|
|
967
|
+
.map((directive) => [
|
|
968
|
+
directive.name,
|
|
969
|
+
this._renderGraphQLDirectiveDefinition(directive),
|
|
970
|
+
])
|
|
757
971
|
.sort(compareEntryKey),
|
|
758
972
|
].map(([, expr]) => expr),
|
|
759
|
-
...Array.from(PRIMITIVE_TYPES)
|
|
760
|
-
.flatMap((type) => {
|
|
973
|
+
...Array.from(PRIMITIVE_TYPES).flatMap((type) => {
|
|
761
974
|
const info = this._scalarsInfo[type];
|
|
762
975
|
if (!info) {
|
|
763
976
|
return [];
|
|
764
977
|
}
|
|
765
978
|
return [
|
|
766
979
|
jen$1.statements(...[
|
|
767
|
-
info.serializeFunc &&
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
980
|
+
info.serializeFunc &&
|
|
981
|
+
this._gql(`GraphQL${type}`)
|
|
982
|
+
.dot("serialize")
|
|
983
|
+
.op("=")
|
|
984
|
+
.parens(renderSymbolReference(this._pkgs, info.serializeFunc).as
|
|
985
|
+
.any),
|
|
986
|
+
info.parseValueFunc &&
|
|
987
|
+
this._gql(`GraphQL${type}`)
|
|
988
|
+
.dot("parseValue")
|
|
989
|
+
.op("=")
|
|
990
|
+
.parens(renderSymbolReference(this._pkgs, info.parseValueFunc).as
|
|
991
|
+
.any),
|
|
992
|
+
info.parseLiteralFunc &&
|
|
993
|
+
this._gql(`GraphQL${type}`)
|
|
994
|
+
.dot("parseLiteral")
|
|
995
|
+
.op("=")
|
|
996
|
+
.parens(renderSymbolReference(this._pkgs, info.parseLiteralFunc).as
|
|
997
|
+
.any),
|
|
998
|
+
].filter(Boolean)),
|
|
771
999
|
];
|
|
772
1000
|
}),
|
|
773
1001
|
// render schema
|
|
774
|
-
jen$1.const
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
? [
|
|
1002
|
+
jen$1.const
|
|
1003
|
+
.id("schema")
|
|
1004
|
+
.op("=")
|
|
1005
|
+
.new.add(this._gql("GraphQLSchema"))
|
|
1006
|
+
.call(jen$1.obj(...(queryType
|
|
1007
|
+
? [
|
|
1008
|
+
jen$1.prop("query", this._renderGraphQLTypeIdentifier(queryType)),
|
|
1009
|
+
]
|
|
1010
|
+
: []), ...(mutationType
|
|
1011
|
+
? [
|
|
1012
|
+
jen$1.prop("mutation", this._renderGraphQLTypeIdentifier(mutationType)),
|
|
1013
|
+
]
|
|
1014
|
+
: []), ...(subscriptionType
|
|
1015
|
+
? [
|
|
1016
|
+
jen$1.prop("subscription", this._renderGraphQLTypeIdentifier(subscriptionType)),
|
|
1017
|
+
]
|
|
780
1018
|
: []), jen$1.prop("types", jen$1.array(...types.map((type) => this._renderGraphQLTypeIdentifier(type)))), jen$1.prop("directives", jen$1.array(...Array.from(schema.getDirectives())
|
|
781
1019
|
.filter((d) => !isBuiltInDirective(d.name))
|
|
782
1020
|
.map((d) => this._renderGraphQLTypeIdentifier(d)))))),
|
|
@@ -785,15 +1023,44 @@ class GeneratorContext {
|
|
|
785
1023
|
}
|
|
786
1024
|
typesExprs(schema, [types, interfaces, inputFieldDirectives]) {
|
|
787
1025
|
return [
|
|
788
|
-
[
|
|
1026
|
+
[
|
|
1027
|
+
"",
|
|
1028
|
+
jen$1.const
|
|
1029
|
+
.id("setTypename")
|
|
1030
|
+
.op("=")
|
|
1031
|
+
.types(jen$1.id("T"))
|
|
1032
|
+
.params(jen$1.id("v").op(":").id("T"), jen$1.id("t").op(":").string)
|
|
1033
|
+
.op(":")
|
|
1034
|
+
.id("T")
|
|
1035
|
+
.op("=>")
|
|
1036
|
+
.block(jen$1
|
|
1037
|
+
.if(jen$1
|
|
1038
|
+
.op("!")
|
|
1039
|
+
.id("v")
|
|
1040
|
+
.op("||")
|
|
1041
|
+
.typeof(jen$1.id("v"))
|
|
1042
|
+
.op("!==")
|
|
1043
|
+
.lit("object"))
|
|
1044
|
+
.block(jen$1.throw.new.id("Error").call(jen$1.lit("expected object"))), jen$1.return(jen$1
|
|
1045
|
+
.id("Object")
|
|
1046
|
+
.dot("assign")
|
|
1047
|
+
.call(jen$1.id("v"), jen$1.obj(jen$1.prop(jen$1.id("__typename"), jen$1.id("t")))))),
|
|
1048
|
+
],
|
|
789
1049
|
// render type definitions
|
|
790
1050
|
...types
|
|
791
|
-
.map((type) => [
|
|
1051
|
+
.map((type) => [
|
|
1052
|
+
type.name,
|
|
1053
|
+
jen$1.statements(...this._renderGraphQLTypeTypes(type, interfaces, inputFieldDirectives)),
|
|
1054
|
+
])
|
|
792
1055
|
.sort(compareEntryKey),
|
|
793
1056
|
// render directive definitions
|
|
794
|
-
...schema
|
|
1057
|
+
...schema
|
|
1058
|
+
.getDirectives()
|
|
795
1059
|
.filter((d) => !isBuiltInDirective(d.name))
|
|
796
|
-
.map((directive) => [
|
|
1060
|
+
.map((directive) => [
|
|
1061
|
+
directive.name,
|
|
1062
|
+
jen$1.statements(...this._renderGraphQLDirectiveTypes(directive)),
|
|
1063
|
+
])
|
|
797
1064
|
.sort(compareEntryKey),
|
|
798
1065
|
].map(([, expr]) => expr);
|
|
799
1066
|
}
|
|
@@ -807,7 +1074,9 @@ class GeneratorContext {
|
|
|
807
1074
|
const base = outfile.startsWith("/") ? outfile : path.resolve(outfile);
|
|
808
1075
|
const statements = renderStatements.call(this);
|
|
809
1076
|
const [localImports, externalImports] = partition(Object.entries(this._pkgs.requires), ([pkg]) => pkg.startsWith("/"));
|
|
810
|
-
return format(jen$1
|
|
1077
|
+
return format(jen$1
|
|
1078
|
+
.statements(renderImports(path.dirname(base), externalImports, this._pkgs.aliases, this._extMode), renderImports(path.dirname(base), localImports, this._pkgs.aliases, this._extMode), ...statements)
|
|
1079
|
+
.toString());
|
|
811
1080
|
}
|
|
812
1081
|
static prepareInterfacesAndInputFieldDirectives(schema, options = {}) {
|
|
813
1082
|
if (options.fieldDirectivesInfo) {
|
|
@@ -835,7 +1104,11 @@ class GeneratorContext {
|
|
|
835
1104
|
}
|
|
836
1105
|
for (const field of Object.values(type.getFields())) {
|
|
837
1106
|
if (getNamedType(field.type) instanceof GraphQLInputObjectType) {
|
|
838
|
-
typesWithObjectFields.push([
|
|
1107
|
+
typesWithObjectFields.push([
|
|
1108
|
+
type.name,
|
|
1109
|
+
field.name,
|
|
1110
|
+
getNamedType(field.type).name,
|
|
1111
|
+
]);
|
|
839
1112
|
}
|
|
840
1113
|
const directives = field.astNode?.directives;
|
|
841
1114
|
if (!directives) {
|
|
@@ -846,22 +1119,34 @@ class GeneratorContext {
|
|
|
846
1119
|
if (!options.inputDirectivesInfo[name]) {
|
|
847
1120
|
continue;
|
|
848
1121
|
}
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
1122
|
+
if (!inputFieldDirectives[type.name]) {
|
|
1123
|
+
inputFieldDirectives[type.name] = {};
|
|
1124
|
+
}
|
|
1125
|
+
const fieldDirectives = inputFieldDirectives[type.name];
|
|
1126
|
+
if (!fieldDirectives[field.name]) {
|
|
1127
|
+
fieldDirectives[field.name] = [];
|
|
1128
|
+
}
|
|
1129
|
+
fieldDirectives[field.name].push(name);
|
|
852
1130
|
}
|
|
853
1131
|
}
|
|
854
1132
|
}
|
|
855
1133
|
for (let changes = 1; changes; changes = 0) {
|
|
856
1134
|
const newTypesWithObjectFields = new Array();
|
|
857
|
-
for (const [typeName, fieldName, objectTypeName] of typesWithObjectFields) {
|
|
1135
|
+
for (const [typeName, fieldName, objectTypeName,] of typesWithObjectFields) {
|
|
858
1136
|
console.log(`checking ${typeName}.${fieldName} for ${objectTypeName}`);
|
|
859
1137
|
if (inputFieldDirectives[objectTypeName]) {
|
|
860
|
-
inputFieldDirectives[typeName] = {
|
|
1138
|
+
inputFieldDirectives[typeName] = {
|
|
1139
|
+
...inputFieldDirectives[typeName],
|
|
1140
|
+
[fieldName]: [],
|
|
1141
|
+
};
|
|
861
1142
|
changes += 1;
|
|
862
1143
|
}
|
|
863
1144
|
else {
|
|
864
|
-
newTypesWithObjectFields.push([
|
|
1145
|
+
newTypesWithObjectFields.push([
|
|
1146
|
+
typeName,
|
|
1147
|
+
fieldName,
|
|
1148
|
+
objectTypeName,
|
|
1149
|
+
]);
|
|
865
1150
|
}
|
|
866
1151
|
}
|
|
867
1152
|
typesWithObjectFields = newTypesWithObjectFields;
|
|
@@ -882,7 +1167,12 @@ class GeneratorContext {
|
|
|
882
1167
|
interfaces[iface.name].implementors.push(type);
|
|
883
1168
|
}
|
|
884
1169
|
}
|
|
885
|
-
return [
|
|
1170
|
+
return [
|
|
1171
|
+
types,
|
|
1172
|
+
interfaces,
|
|
1173
|
+
inputFieldDirectives,
|
|
1174
|
+
options.includeAstNodes,
|
|
1175
|
+
];
|
|
886
1176
|
}
|
|
887
1177
|
}
|
|
888
1178
|
function createGenerator(schema, options) {
|
|
@@ -922,8 +1212,8 @@ function createMatcher(pattern) {
|
|
|
922
1212
|
if (typeof pattern === "string") {
|
|
923
1213
|
return pm(pattern);
|
|
924
1214
|
}
|
|
925
|
-
|
|
926
|
-
|
|
1215
|
+
const matchers = [];
|
|
1216
|
+
const globs = [];
|
|
927
1217
|
for (const p of Array.isArray(pattern) ? pattern : [pattern]) {
|
|
928
1218
|
if (typeof p === "string") {
|
|
929
1219
|
globs.push(p);
|
|
@@ -945,9 +1235,9 @@ function createMatcher(pattern) {
|
|
|
945
1235
|
}
|
|
946
1236
|
|
|
947
1237
|
async function parseResolverFile(path) {
|
|
948
|
-
return Object.fromEntries(Object.entries((await parseModule(path)).exports)
|
|
949
|
-
|
|
950
|
-
|
|
1238
|
+
return Object.fromEntries(Object.entries((await parseModule(path)).exports).flatMap(([name, decls]) => decls.flatMap(({ declaration }) => {
|
|
1239
|
+
if (ts.isVariableDeclaration(declaration) &&
|
|
1240
|
+
declaration.initializer) {
|
|
951
1241
|
if (ts.isFunctionExpression(declaration.initializer)) {
|
|
952
1242
|
return [[name, { module: path, symbol: name }]];
|
|
953
1243
|
}
|
|
@@ -966,14 +1256,18 @@ async function parseTypeResolvers(typeName, glob, ignore) {
|
|
|
966
1256
|
const result = {};
|
|
967
1257
|
for await (const entry of globIterate(glob, { withFileTypes: true })) {
|
|
968
1258
|
const fullpath = entry.fullpath();
|
|
969
|
-
if (!shouldIgnore(fullpath) &&
|
|
1259
|
+
if (!shouldIgnore(fullpath) &&
|
|
1260
|
+
entry.isFile() &&
|
|
1261
|
+
entry.name.endsWith(".ts")) {
|
|
970
1262
|
for (const [name, reference] of Object.entries(await parseResolverFile(fullpath))) {
|
|
971
1263
|
let realName = name;
|
|
972
|
-
if (realName === "default" &&
|
|
1264
|
+
if (realName === "default" &&
|
|
1265
|
+
typeof glob === "string" &&
|
|
1266
|
+
glob.endsWith("/*.ts")) {
|
|
973
1267
|
realName = basename(fullpath, extname(fullpath));
|
|
974
1268
|
}
|
|
975
1269
|
if (realName in result) {
|
|
976
|
-
console.warn(`WARNING: Duplicate resolver name: ${typeName ? typeName
|
|
1270
|
+
console.warn(`WARNING: Duplicate resolver name: ${typeName ? `${typeName}.` : ""}${name} in ${fullpath} and ${result[name].module}`);
|
|
977
1271
|
}
|
|
978
1272
|
result[realName] = reference;
|
|
979
1273
|
}
|
|
@@ -986,16 +1280,13 @@ async function parse$2(dirpath, ignore) {
|
|
|
986
1280
|
if (!dir.isDirectory()) {
|
|
987
1281
|
throw new Error(`Expected ${dirpath} to be a directory`);
|
|
988
1282
|
}
|
|
989
|
-
if (!dirpath.endsWith("/")) {
|
|
990
|
-
dirpath += "/";
|
|
991
|
-
}
|
|
992
1283
|
const out = {};
|
|
993
1284
|
const shouldIgnore = createMatcher(ignore);
|
|
994
1285
|
for await (const name of await fs.readdir(dirpath)) {
|
|
995
1286
|
const file = join(dirpath, name);
|
|
996
1287
|
const entry = await fs.stat(file);
|
|
997
1288
|
if (entry.isDirectory()) {
|
|
998
|
-
out[name] = await parseTypeResolvers(name, file
|
|
1289
|
+
out[name] = await parseTypeResolvers(name, `${file}/*.ts`, shouldIgnore);
|
|
999
1290
|
}
|
|
1000
1291
|
else if (entry.isFile() && name.endsWith(".ts")) {
|
|
1001
1292
|
out[name.slice(0, -3)] = await parseTypeResolvers(name.slice(0, -3), file, shouldIgnore);
|
|
@@ -1020,7 +1311,8 @@ function refFromImportTypeNode(node, source) {
|
|
|
1020
1311
|
console.log("WARNING: namespace import for scalar type is not supported");
|
|
1021
1312
|
return;
|
|
1022
1313
|
}
|
|
1023
|
-
if (!ts.isLiteralTypeNode(node.argument) ||
|
|
1314
|
+
if (!ts.isLiteralTypeNode(node.argument) ||
|
|
1315
|
+
!ts.isStringLiteral(node.argument.literal)) {
|
|
1024
1316
|
// this is a grammar error, handling it is out of scope
|
|
1025
1317
|
const { line, character } = getLineAndCharacterOfPosition(source, node.pos);
|
|
1026
1318
|
console.log(`WARNING: grammar error at ${source.fileName}:${line + 1}:${character + 1}`);
|
|
@@ -1035,8 +1327,8 @@ function refFromTypeReferenceNode(typeNode, source) {
|
|
|
1035
1327
|
}
|
|
1036
1328
|
const typeName = typeNode.typeName.text;
|
|
1037
1329
|
if (typeNode.typeArguments?.length) {
|
|
1038
|
-
if (typeName !==
|
|
1039
|
-
throw new Error(
|
|
1330
|
+
if (typeName !== "Promise") {
|
|
1331
|
+
throw new Error("TODO: handle type arguments");
|
|
1040
1332
|
}
|
|
1041
1333
|
return refFromTypeNode(typeNode.typeArguments[0], source);
|
|
1042
1334
|
}
|
|
@@ -1054,7 +1346,11 @@ function refFromTypeReferenceNode(typeNode, source) {
|
|
|
1054
1346
|
if (statement.importClause.name) {
|
|
1055
1347
|
// default import
|
|
1056
1348
|
if (statement.importClause.name.text === typeName) {
|
|
1057
|
-
return {
|
|
1349
|
+
return {
|
|
1350
|
+
module: statement.importClause.name.text,
|
|
1351
|
+
symbol: "default",
|
|
1352
|
+
alias: typeName,
|
|
1353
|
+
};
|
|
1058
1354
|
}
|
|
1059
1355
|
}
|
|
1060
1356
|
if (!statement.importClause.namedBindings) {
|
|
@@ -1065,17 +1361,24 @@ function refFromTypeReferenceNode(typeNode, source) {
|
|
|
1065
1361
|
// TODO: handle namespace imports (will need to check if `typeName` has a dot in it)
|
|
1066
1362
|
continue;
|
|
1067
1363
|
}
|
|
1068
|
-
for (const specifier of statement.importClause.namedBindings.elements ??
|
|
1364
|
+
for (const specifier of statement.importClause.namedBindings.elements ??
|
|
1365
|
+
[]) {
|
|
1069
1366
|
if (specifier.name.text === typeName) {
|
|
1070
|
-
return {
|
|
1367
|
+
return {
|
|
1368
|
+
module: statement.moduleSpecifier.text,
|
|
1369
|
+
symbol: specifier.propertyName?.text ?? typeName,
|
|
1370
|
+
alias: typeName,
|
|
1371
|
+
};
|
|
1071
1372
|
}
|
|
1072
1373
|
}
|
|
1073
1374
|
}
|
|
1074
|
-
else if (ts.isTypeAliasDeclaration(statement) ||
|
|
1375
|
+
else if (ts.isTypeAliasDeclaration(statement) ||
|
|
1376
|
+
ts.isInterfaceDeclaration(statement) ||
|
|
1377
|
+
ts.isEnumDeclaration(statement)) {
|
|
1075
1378
|
if (statement.name.text === typeName) {
|
|
1076
1379
|
if (!statement.modifiers?.some((mod) => mod.kind === ts.SyntaxKind.ExportKeyword)) {
|
|
1077
1380
|
console.log(statement);
|
|
1078
|
-
console.log(`WARNING: found type ${typeName} in ${source.fileName}:${locLineColumn$1(statement, source).join(
|
|
1381
|
+
console.log(`WARNING: found type ${typeName} in ${source.fileName}:${locLineColumn$1(statement, source).join(":")} but it is not exported`);
|
|
1079
1382
|
continue;
|
|
1080
1383
|
}
|
|
1081
1384
|
return { module: source.fileName, symbol: typeName };
|
|
@@ -1089,16 +1392,14 @@ function refFromTypeNode(typeNode, source) {
|
|
|
1089
1392
|
if (ts.isImportTypeNode(typeNode)) {
|
|
1090
1393
|
return refFromImportTypeNode(typeNode, source);
|
|
1091
1394
|
}
|
|
1092
|
-
|
|
1395
|
+
if (ts.isTokenKind(typeNode.kind)) {
|
|
1093
1396
|
// primitive type string, number, etc...
|
|
1094
1397
|
return { symbol: typeNode.getText(source) };
|
|
1095
1398
|
}
|
|
1096
|
-
|
|
1399
|
+
if (ts.isTypeReferenceNode(typeNode)) {
|
|
1097
1400
|
return refFromTypeReferenceNode(typeNode, source);
|
|
1098
1401
|
}
|
|
1099
|
-
|
|
1100
|
-
console.warn("WARNING: unexpected type node: " + ts.SyntaxKind[typeNode.kind]);
|
|
1101
|
-
}
|
|
1402
|
+
console.warn(`WARNING: unexpected type node: ${ts.SyntaxKind[typeNode.kind]}`);
|
|
1102
1403
|
}
|
|
1103
1404
|
function reconcileScalarType(scalarName, typeDecls, source) {
|
|
1104
1405
|
let type;
|
|
@@ -1106,7 +1407,7 @@ function reconcileScalarType(scalarName, typeDecls, source) {
|
|
|
1106
1407
|
if (!typeNode) {
|
|
1107
1408
|
continue;
|
|
1108
1409
|
}
|
|
1109
|
-
|
|
1410
|
+
const newType = refFromTypeNode(typeNode, source);
|
|
1110
1411
|
if (type && newType) {
|
|
1111
1412
|
if (type.symbol !== newType.symbol ||
|
|
1112
1413
|
type.alias !== newType.alias ||
|
|
@@ -1131,11 +1432,13 @@ function scalarInfoFromObjectLiteralExpression(scalarName, module, properties) {
|
|
|
1131
1432
|
case "serialize":
|
|
1132
1433
|
case "parseValue":
|
|
1133
1434
|
case "parseLiteral":
|
|
1134
|
-
if (!ts.isFunctionExpression(prop.initializer) &&
|
|
1435
|
+
if (!ts.isFunctionExpression(prop.initializer) &&
|
|
1436
|
+
!ts.isArrowFunction(prop.initializer)) {
|
|
1135
1437
|
console.log(`WARNING: expected scalar property ${scalarName}.${prop.name.text} to be a function, but got ${ts.SyntaxKind[prop.initializer.kind]}`);
|
|
1136
1438
|
return [];
|
|
1137
1439
|
}
|
|
1138
|
-
return [
|
|
1440
|
+
return [
|
|
1441
|
+
[
|
|
1139
1442
|
`${prop.name.text}Func`,
|
|
1140
1443
|
{
|
|
1141
1444
|
module: module,
|
|
@@ -1143,7 +1446,8 @@ function scalarInfoFromObjectLiteralExpression(scalarName, module, properties) {
|
|
|
1143
1446
|
property: prop.name.text,
|
|
1144
1447
|
declaration: prop.initializer,
|
|
1145
1448
|
},
|
|
1146
|
-
]
|
|
1449
|
+
],
|
|
1450
|
+
];
|
|
1147
1451
|
default:
|
|
1148
1452
|
console.log(`WARNING: found extraneous scalar property ${scalarName}.${prop.name.text}`);
|
|
1149
1453
|
}
|
|
@@ -1156,7 +1460,8 @@ function scalarInfoFromObjectLiteralExpression(scalarName, module, properties) {
|
|
|
1156
1460
|
case "serialize":
|
|
1157
1461
|
case "parseValue":
|
|
1158
1462
|
case "parseLiteral":
|
|
1159
|
-
return [
|
|
1463
|
+
return [
|
|
1464
|
+
[
|
|
1160
1465
|
`${prop.name.text}Func`,
|
|
1161
1466
|
{
|
|
1162
1467
|
module,
|
|
@@ -1164,7 +1469,8 @@ function scalarInfoFromObjectLiteralExpression(scalarName, module, properties) {
|
|
|
1164
1469
|
property: prop.name.text,
|
|
1165
1470
|
declaration: prop,
|
|
1166
1471
|
},
|
|
1167
|
-
]
|
|
1472
|
+
],
|
|
1473
|
+
];
|
|
1168
1474
|
default:
|
|
1169
1475
|
console.log(`WARNING: found extraneous scalar property ${scalarName}.${prop.name.text}`);
|
|
1170
1476
|
}
|
|
@@ -1183,7 +1489,8 @@ async function parse$1(path) {
|
|
|
1183
1489
|
for (const { declaration, source } of decls) {
|
|
1184
1490
|
sources[name] = source;
|
|
1185
1491
|
if (ts.isVariableDeclaration(declaration)) {
|
|
1186
|
-
if (declaration.initializer &&
|
|
1492
|
+
if (declaration.initializer &&
|
|
1493
|
+
ts.isObjectLiteralExpression(declaration.initializer)) {
|
|
1187
1494
|
scalarFnsInfos[name] = scalarInfoFromObjectLiteralExpression(name, new URL(source.fileName).toString(), declaration.initializer.properties);
|
|
1188
1495
|
}
|
|
1189
1496
|
}
|
|
@@ -1200,18 +1507,23 @@ async function parse$1(path) {
|
|
|
1200
1507
|
}
|
|
1201
1508
|
}
|
|
1202
1509
|
const infos = {};
|
|
1203
|
-
for (const name of new Set([
|
|
1510
|
+
for (const name of new Set([
|
|
1511
|
+
...Object.keys(scalarFnsInfos),
|
|
1512
|
+
...Object.keys(scalarTypeNodes),
|
|
1513
|
+
])) {
|
|
1204
1514
|
const fnsInfo = scalarFnsInfos[name];
|
|
1205
1515
|
const typeNode = scalarTypeNodes[name];
|
|
1206
1516
|
const source = sources[name];
|
|
1207
|
-
const type = typeNode
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1517
|
+
const type = typeNode
|
|
1518
|
+
? {
|
|
1519
|
+
module: source.fileName,
|
|
1520
|
+
symbol: name,
|
|
1521
|
+
}
|
|
1522
|
+
: reconcileScalarType(name, [
|
|
1523
|
+
// NOTE: omit serialize input type because it is supposed to be `unknown`
|
|
1524
|
+
fnsInfo?.parseValueFunc?.declaration?.type,
|
|
1525
|
+
fnsInfo?.parseLiteralFunc?.declaration?.type,
|
|
1526
|
+
], source);
|
|
1215
1527
|
if (type) {
|
|
1216
1528
|
if (type.module) {
|
|
1217
1529
|
type.module = new URL(type.module, source.fileName).toString();
|
|
@@ -1239,8 +1551,10 @@ function traceLine(loc, prefix = "") {
|
|
|
1239
1551
|
return `\n ${prefix}at file://${loc.source.name}:${locLineColumn(loc).join(":")}`;
|
|
1240
1552
|
}
|
|
1241
1553
|
function setTraceToSchema(err, name, loc) {
|
|
1554
|
+
// biome-ignore lint/suspicious/noExplicitAny: hacks
|
|
1242
1555
|
if (globalThis.Deno) {
|
|
1243
1556
|
if (loc) {
|
|
1557
|
+
// biome-ignore lint/suspicious/noExplicitAny: hacks
|
|
1244
1558
|
const trace = err.__callSiteEvals;
|
|
1245
1559
|
const [lineNumber, columnNumber] = locLineColumn(loc);
|
|
1246
1560
|
// NOTE: this is deno magic
|
|
@@ -1253,7 +1567,7 @@ function setTraceToSchema(err, name, loc) {
|
|
|
1253
1567
|
function: undefined,
|
|
1254
1568
|
functionName: name,
|
|
1255
1569
|
methodName: null,
|
|
1256
|
-
fileName:
|
|
1570
|
+
fileName: `file://${loc.source.name}`,
|
|
1257
1571
|
lineNumber,
|
|
1258
1572
|
columnNumber,
|
|
1259
1573
|
evalOrigin: undefined,
|
|
@@ -1297,8 +1611,7 @@ function isListValueNodeEqual(a, b) {
|
|
|
1297
1611
|
return zip(a.values, b.values).every(([a, b]) => isValueNodeEqual(a, b));
|
|
1298
1612
|
}
|
|
1299
1613
|
function isObjectValueNodeEqual(a, b) {
|
|
1300
|
-
return zip(sortNamedNodes(a.fields), sortNamedNodes(b.fields))
|
|
1301
|
-
.every(([a, b]) => a.name.value === b.name.value && isValueNodeEqual(a.value, b.value));
|
|
1614
|
+
return zip(sortNamedNodes(a.fields), sortNamedNodes(b.fields)).every(([a, b]) => a.name.value === b.name.value && isValueNodeEqual(a.value, b.value));
|
|
1302
1615
|
}
|
|
1303
1616
|
function isValueNodeEqual(a, b) {
|
|
1304
1617
|
if (a === b || (!a && !b)) {
|
|
@@ -1366,7 +1679,8 @@ function isInputValueDefinitionNodesEqual(a, b) {
|
|
|
1366
1679
|
if (!a || !b || a.length !== b.length) {
|
|
1367
1680
|
return false;
|
|
1368
1681
|
}
|
|
1369
|
-
return zip(sortNamedNodes(a), sortNamedNodes(b)).every(([a, b]) => a.name.value === b.name.value &&
|
|
1682
|
+
return zip(sortNamedNodes(a), sortNamedNodes(b)).every(([a, b]) => a.name.value === b.name.value &&
|
|
1683
|
+
isTypeNodeEqual(a.type, b.type) &&
|
|
1370
1684
|
isValueNodeEqual(a.defaultValue, b.defaultValue) &&
|
|
1371
1685
|
isDirectiveNodesEqual(a.directives, b.directives));
|
|
1372
1686
|
}
|
|
@@ -1377,17 +1691,15 @@ function mergeFieldDefinitionNodes(name, a, b) {
|
|
|
1377
1691
|
const prev = fields[f.name.value];
|
|
1378
1692
|
if (prev) {
|
|
1379
1693
|
if (!isInputValueDefinitionNodesEqual(prev.arguments, f.arguments)) {
|
|
1380
|
-
throw setTraceToSchema(new GraphQLError(`Cannot merge duplicate field with different arguments: ${name}.${f.name.value}`), name
|
|
1694
|
+
throw setTraceToSchema(new GraphQLError(`Cannot merge duplicate field with different arguments: ${name}.${f.name.value}`), `${name}.${f.name.value}`, f.loc);
|
|
1381
1695
|
}
|
|
1382
1696
|
if (!isTypeNodeEqual(prev.type, f.type)) {
|
|
1383
|
-
throw setTraceToSchema(new GraphQLError(`Cannot merge duplicate field with different type: ${name}.${f.name.value}`), name
|
|
1697
|
+
throw setTraceToSchema(new GraphQLError(`Cannot merge duplicate field with different type: ${name}.${f.name.value}`), `${name}.${f.name.value}`, f.type.loc);
|
|
1384
1698
|
}
|
|
1385
|
-
console.warn(`WARNING: there is more than one declaration for ${name}.${f.name.value}`
|
|
1386
|
-
traceLine(f.loc) +
|
|
1387
|
-
traceLine(prev.loc, "previously ") + "\n");
|
|
1699
|
+
console.warn(`WARNING: there is more than one declaration for ${name}.${f.name.value}${traceLine(f.loc)}${traceLine(prev.loc, "previously ")}\n`);
|
|
1388
1700
|
fields[f.name.value] = {
|
|
1389
1701
|
...prev,
|
|
1390
|
-
directives: mergeDirectiveNodes(name
|
|
1702
|
+
directives: mergeDirectiveNodes(`${name}.${f.name.value}`, prev.directives, f.directives),
|
|
1391
1703
|
};
|
|
1392
1704
|
}
|
|
1393
1705
|
else {
|
|
@@ -1404,17 +1716,15 @@ function mergeInputValueDefinitionNodes(name, a, b) {
|
|
|
1404
1716
|
const prev = fields[f.name.value];
|
|
1405
1717
|
if (prev) {
|
|
1406
1718
|
if (!isValueNodeEqual(prev.defaultValue, f.defaultValue)) {
|
|
1407
|
-
throw setTraceToSchema(new GraphQLError(`Cannot merge duplicate field with different arguments: ${name}.${f.name.value}`), name
|
|
1719
|
+
throw setTraceToSchema(new GraphQLError(`Cannot merge duplicate field with different arguments: ${name}.${f.name.value}`), `${name}.${f.name.value}`, f.loc);
|
|
1408
1720
|
}
|
|
1409
1721
|
if (!isTypeNodeEqual(prev.type, f.type)) {
|
|
1410
|
-
throw setTraceToSchema(new GraphQLError(`Cannot merge duplicate field with different type: ${name}.${f.name.value}`), name
|
|
1722
|
+
throw setTraceToSchema(new GraphQLError(`Cannot merge duplicate field with different type: ${name}.${f.name.value}`), `${name}.${f.name.value}`, f.type.loc);
|
|
1411
1723
|
}
|
|
1412
|
-
console.warn(`WARNING: there is more than one declaration for ${name}.${f.name.value}`
|
|
1413
|
-
traceLine(f.loc) +
|
|
1414
|
-
traceLine(prev.loc, "previously ") + "\n");
|
|
1724
|
+
console.warn(`WARNING: there is more than one declaration for ${name}.${f.name.value}${traceLine(f.loc)}${traceLine(prev.loc, "previously ")}\n`);
|
|
1415
1725
|
fields[f.name.value] = {
|
|
1416
1726
|
...prev,
|
|
1417
|
-
directives: mergeDirectiveNodes(name
|
|
1727
|
+
directives: mergeDirectiveNodes(`${name}.${f.name.value}`, prev.directives, f.directives),
|
|
1418
1728
|
};
|
|
1419
1729
|
}
|
|
1420
1730
|
else {
|
|
@@ -1439,7 +1749,7 @@ function mergeDirectiveNodes(name, a, b) {
|
|
|
1439
1749
|
for (const d of b) {
|
|
1440
1750
|
if (d.name.value in directives &&
|
|
1441
1751
|
!isArgumentNodesEqual(directives[d.name.value].arguments, d.arguments)) {
|
|
1442
|
-
throw setTraceToSchema(new GraphQLError(`Cannot merge duplicate directive with different arguments: ${name} @${d.name.value}`), name
|
|
1752
|
+
throw setTraceToSchema(new GraphQLError(`Cannot merge duplicate directive with different arguments: ${name} @${d.name.value}`), `${name} @${d.name.value}`, d.loc);
|
|
1443
1753
|
}
|
|
1444
1754
|
directives[d.name.value] = d;
|
|
1445
1755
|
}
|
|
@@ -1491,9 +1801,9 @@ function mergeUnionTypeDefinitionNodes(a, b) {
|
|
|
1491
1801
|
function mergeEnumTypeDefinitionNodes(a, b) {
|
|
1492
1802
|
const values = namedNodesDict(a.values);
|
|
1493
1803
|
if (b) {
|
|
1494
|
-
for (const v of
|
|
1804
|
+
for (const v of b.values || []) {
|
|
1495
1805
|
if (v.name.value in values) {
|
|
1496
|
-
throw setTraceToSchema(new GraphQLError(`Cannot merge duplicate enum value: ${v.name.value}.${v.name.value}`), v.name.value
|
|
1806
|
+
throw setTraceToSchema(new GraphQLError(`Cannot merge duplicate enum value: ${v.name.value}.${v.name.value}`), `${v.name.value}.${v.name.value}`, v.loc);
|
|
1497
1807
|
}
|
|
1498
1808
|
values[v.name.value] = v;
|
|
1499
1809
|
}
|
|
@@ -1532,7 +1842,7 @@ function mergeDocumentNodes(documentNodes) {
|
|
|
1532
1842
|
case Kind.UNION_TYPE_EXTENSION:
|
|
1533
1843
|
case Kind.ENUM_TYPE_EXTENSION:
|
|
1534
1844
|
case Kind.INPUT_OBJECT_TYPE_EXTENSION:
|
|
1535
|
-
throw new Error(
|
|
1845
|
+
throw new Error(`unexpected definition kind: ${definition.kind}`);
|
|
1536
1846
|
}
|
|
1537
1847
|
const prevDefinition = definitions[definition.name.value];
|
|
1538
1848
|
if (!prevDefinition) {
|
|
@@ -1545,11 +1855,10 @@ function mergeDocumentNodes(documentNodes) {
|
|
|
1545
1855
|
if (prevDefinition.kind === Kind.DIRECTIVE_DEFINITION) {
|
|
1546
1856
|
throw setTraceToSchema(new GraphQLError(`Cannot merge duplicate directive definitions: ${definition.name.value}`), definition.name.value, definition.loc);
|
|
1547
1857
|
}
|
|
1548
|
-
if (prevDefinition.description &&
|
|
1858
|
+
if (prevDefinition.description &&
|
|
1859
|
+
definition.description &&
|
|
1549
1860
|
prevDefinition.description.value !== definition.description.value) {
|
|
1550
|
-
console.warn(`WARNING: different descriptions for type ${prevDefinition.name.value}: ${JSON.stringify(prevDefinition.description.value)} and ${JSON.stringify(definition.description.value)}`
|
|
1551
|
-
traceLine(definition.description.loc) +
|
|
1552
|
-
traceLine(prevDefinition.description.loc, "previously ") + "\n");
|
|
1861
|
+
console.warn(`WARNING: different descriptions for type ${prevDefinition.name.value}: ${JSON.stringify(prevDefinition.description.value)} and ${JSON.stringify(definition.description.value)}${traceLine(definition.description.loc)}${traceLine(prevDefinition.description.loc, "previously ")}\n`);
|
|
1553
1862
|
}
|
|
1554
1863
|
switch (definition.kind) {
|
|
1555
1864
|
case Kind.SCALAR_TYPE_DEFINITION:
|
|
@@ -1559,7 +1868,8 @@ function mergeDocumentNodes(documentNodes) {
|
|
|
1559
1868
|
definitions[definition.name.value] = mergeObjectTypeDefinitionNodes(prevDefinition, definition);
|
|
1560
1869
|
break;
|
|
1561
1870
|
case Kind.INTERFACE_TYPE_DEFINITION:
|
|
1562
|
-
definitions[definition.name.value] =
|
|
1871
|
+
definitions[definition.name.value] =
|
|
1872
|
+
mergeInterfaceTypeDefinitionNodes(prevDefinition, definition);
|
|
1563
1873
|
break;
|
|
1564
1874
|
case Kind.UNION_TYPE_DEFINITION:
|
|
1565
1875
|
definitions[definition.name.value] = mergeUnionTypeDefinitionNodes(prevDefinition, definition);
|
|
@@ -1568,7 +1878,8 @@ function mergeDocumentNodes(documentNodes) {
|
|
|
1568
1878
|
definitions[definition.name.value] = mergeEnumTypeDefinitionNodes(prevDefinition, definition);
|
|
1569
1879
|
break;
|
|
1570
1880
|
case Kind.INPUT_OBJECT_TYPE_DEFINITION:
|
|
1571
|
-
definitions[definition.name.value] =
|
|
1881
|
+
definitions[definition.name.value] =
|
|
1882
|
+
mergeInputObjectTypeDefinitionNodes(prevDefinition, definition);
|
|
1572
1883
|
break;
|
|
1573
1884
|
}
|
|
1574
1885
|
}
|