@gqlkit-ts/cli 0.3.0 → 0.4.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/README.md +143 -0
- package/dist/auto-type-generator/auto-type-generator.d.ts.map +1 -1
- package/dist/auto-type-generator/auto-type-generator.js +16 -13
- package/dist/auto-type-generator/auto-type-generator.js.map +1 -1
- package/dist/config/types.d.ts +13 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config-loader/loader.d.ts +3 -0
- package/dist/config-loader/loader.d.ts.map +1 -1
- package/dist/config-loader/loader.js +1 -0
- package/dist/config-loader/loader.js.map +1 -1
- package/dist/config-loader/validator.d.ts.map +1 -1
- package/dist/config-loader/validator.js +23 -0
- package/dist/config-loader/validator.js.map +1 -1
- package/dist/gen-orchestrator/orchestrator.d.ts.map +1 -1
- package/dist/gen-orchestrator/orchestrator.js +19 -6
- package/dist/gen-orchestrator/orchestrator.js.map +1 -1
- package/dist/resolver-extractor/extractor/define-api-extractor.js +4 -4
- package/dist/resolver-extractor/extractor/define-api-extractor.js.map +1 -1
- package/dist/schema-generator/builder/ast-builder.d.ts +2 -2
- package/dist/schema-generator/builder/ast-builder.d.ts.map +1 -1
- package/dist/schema-generator/builder/ast-builder.js +12 -34
- package/dist/schema-generator/builder/ast-builder.js.map +1 -1
- package/dist/schema-generator/emitter/code-emitter.d.ts +3 -1
- package/dist/schema-generator/emitter/code-emitter.d.ts.map +1 -1
- package/dist/schema-generator/emitter/code-emitter.js +22 -12
- package/dist/schema-generator/emitter/code-emitter.js.map +1 -1
- package/dist/schema-generator/emitter/sdl-emitter.d.ts +0 -4
- package/dist/schema-generator/emitter/sdl-emitter.d.ts.map +1 -1
- package/dist/schema-generator/emitter/sdl-emitter.js +0 -4
- package/dist/schema-generator/emitter/sdl-emitter.js.map +1 -1
- package/dist/schema-generator/generate-schema.d.ts +2 -0
- package/dist/schema-generator/generate-schema.d.ts.map +1 -1
- package/dist/schema-generator/generate-schema.js +13 -4
- package/dist/schema-generator/generate-schema.js.map +1 -1
- package/dist/schema-generator/integrator/result-integrator.d.ts +10 -12
- package/dist/schema-generator/integrator/result-integrator.d.ts.map +1 -1
- package/dist/schema-generator/integrator/result-integrator.js +18 -55
- package/dist/schema-generator/integrator/result-integrator.js.map +1 -1
- package/dist/shared/branded-type-detector.d.ts +43 -0
- package/dist/shared/branded-type-detector.d.ts.map +1 -0
- package/dist/shared/branded-type-detector.js +146 -0
- package/dist/shared/branded-type-detector.js.map +1 -0
- package/dist/shared/string-utils.d.ts +2 -0
- package/dist/shared/string-utils.d.ts.map +1 -0
- package/dist/shared/string-utils.js +8 -0
- package/dist/shared/string-utils.js.map +1 -0
- package/dist/type-extractor/converter/field-eligibility.d.ts +8 -6
- package/dist/type-extractor/converter/field-eligibility.d.ts.map +1 -1
- package/dist/type-extractor/converter/field-eligibility.js +7 -28
- package/dist/type-extractor/converter/field-eligibility.js.map +1 -1
- package/dist/type-extractor/converter/graphql-converter.d.ts.map +1 -1
- package/dist/type-extractor/converter/graphql-converter.js +6 -11
- package/dist/type-extractor/converter/graphql-converter.js.map +1 -1
- package/dist/type-extractor/extractor/field-type-resolver.d.ts.map +1 -1
- package/dist/type-extractor/extractor/field-type-resolver.js +39 -4
- package/dist/type-extractor/extractor/field-type-resolver.js.map +1 -1
- package/dist/type-extractor/types/diagnostics.d.ts +1 -1
- package/dist/type-extractor/types/diagnostics.d.ts.map +1 -1
- package/dist/type-extractor/validator/type-validator.d.ts +1 -1
- package/dist/type-extractor/validator/type-validator.d.ts.map +1 -1
- package/dist/type-extractor/validator/type-validator.js +2 -10
- package/dist/type-extractor/validator/type-validator.js.map +1 -1
- package/docs/configuration.md +9 -0
- package/package.json +1 -1
- package/src/auto-type-generator/auto-type-generator.ts +23 -26
- package/src/config/types.ts +15 -0
- package/src/config-loader/loader.ts +4 -0
- package/src/config-loader/validator.ts +33 -0
- package/src/gen-orchestrator/orchestrator.ts +30 -11
- package/src/resolver-extractor/extractor/define-api-extractor.ts +5 -5
- package/src/schema-generator/builder/ast-builder.ts +52 -81
- package/src/schema-generator/emitter/code-emitter.ts +48 -11
- package/src/schema-generator/emitter/sdl-emitter.ts +0 -4
- package/src/schema-generator/generate-schema.ts +13 -15
- package/src/schema-generator/integrator/result-integrator.ts +37 -78
- package/src/shared/branded-type-detector.ts +182 -0
- package/src/shared/string-utils.ts +7 -0
- package/src/type-extractor/converter/field-eligibility.ts +13 -29
- package/src/type-extractor/converter/graphql-converter.ts +6 -16
- package/src/type-extractor/extractor/field-type-resolver.ts +49 -4
- package/src/type-extractor/types/diagnostics.ts +1 -0
- package/src/type-extractor/validator/type-validator.ts +2 -15
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ImportExtension } from "../config/types.js";
|
|
1
2
|
import type { Diagnostic } from "../type-extractor/types/index.js";
|
|
2
3
|
import {
|
|
3
4
|
DEFAULT_RESOLVERS_PATH,
|
|
@@ -186,6 +187,31 @@ function validateTsconfigPath(
|
|
|
186
187
|
return { resolved: value, diagnostics: [] };
|
|
187
188
|
}
|
|
188
189
|
|
|
190
|
+
function validateImportExtension(
|
|
191
|
+
value: unknown,
|
|
192
|
+
configPath: string,
|
|
193
|
+
): { resolved: ImportExtension; diagnostics: Diagnostic[] } {
|
|
194
|
+
if (value === undefined) {
|
|
195
|
+
return { resolved: "js", diagnostics: [] };
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (value !== "js" && value !== "none" && value !== "ts") {
|
|
199
|
+
return {
|
|
200
|
+
resolved: "js",
|
|
201
|
+
diagnostics: [
|
|
202
|
+
{
|
|
203
|
+
code: "CONFIG_INVALID_IMPORT_EXTENSION",
|
|
204
|
+
message: 'output.importExtension must be "js", "none", or "ts"',
|
|
205
|
+
severity: "error",
|
|
206
|
+
location: { file: configPath, line: 1, column: 1 },
|
|
207
|
+
},
|
|
208
|
+
],
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return { resolved: value, diagnostics: [] };
|
|
213
|
+
}
|
|
214
|
+
|
|
189
215
|
function validateOutputConfig(
|
|
190
216
|
output: unknown,
|
|
191
217
|
configPath: string,
|
|
@@ -198,6 +224,7 @@ function validateOutputConfig(
|
|
|
198
224
|
resolversPath: DEFAULT_RESOLVERS_PATH,
|
|
199
225
|
typeDefsPath: DEFAULT_TYPEDEFS_PATH,
|
|
200
226
|
schemaPath: DEFAULT_SCHEMA_PATH,
|
|
227
|
+
importExtension: "js",
|
|
201
228
|
},
|
|
202
229
|
diagnostics: [],
|
|
203
230
|
};
|
|
@@ -228,10 +255,15 @@ function validateOutputConfig(
|
|
|
228
255
|
"output.schemaPath",
|
|
229
256
|
configPath,
|
|
230
257
|
);
|
|
258
|
+
const importExtensionResult = validateImportExtension(
|
|
259
|
+
output["importExtension"],
|
|
260
|
+
configPath,
|
|
261
|
+
);
|
|
231
262
|
|
|
232
263
|
diagnostics.push(...resolversPathResult.diagnostics);
|
|
233
264
|
diagnostics.push(...typeDefsPathResult.diagnostics);
|
|
234
265
|
diagnostics.push(...schemaPathResult.diagnostics);
|
|
266
|
+
diagnostics.push(...importExtensionResult.diagnostics);
|
|
235
267
|
|
|
236
268
|
if (diagnostics.length > 0) {
|
|
237
269
|
return { resolved: undefined, diagnostics };
|
|
@@ -242,6 +274,7 @@ function validateOutputConfig(
|
|
|
242
274
|
resolversPath: resolversPathResult.resolved,
|
|
243
275
|
typeDefsPath: typeDefsPathResult.resolved,
|
|
244
276
|
schemaPath: schemaPathResult.resolved,
|
|
277
|
+
importExtension: importExtensionResult.resolved,
|
|
245
278
|
},
|
|
246
279
|
diagnostics: [],
|
|
247
280
|
};
|
|
@@ -91,6 +91,12 @@ interface ResolversResult {
|
|
|
91
91
|
diagnostics: Diagnostics;
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
interface ScalarConfig {
|
|
95
|
+
readonly customScalarNames: string[];
|
|
96
|
+
readonly globalTypeMappings: GlobalTypeMapping[];
|
|
97
|
+
readonly configScalars: ConfigScalarMapping[];
|
|
98
|
+
}
|
|
99
|
+
|
|
94
100
|
interface PipelineContext {
|
|
95
101
|
readonly config: GenerationConfig;
|
|
96
102
|
readonly sourceFiles: ReadonlyArray<string>;
|
|
@@ -101,6 +107,7 @@ interface PipelineContext {
|
|
|
101
107
|
readonly typesResult: TypesResult | null;
|
|
102
108
|
readonly resolversResult: ResolversResult | null;
|
|
103
109
|
readonly directiveDefinitions: DirectiveDefinitionInfo[] | null;
|
|
110
|
+
readonly scalarConfig: ScalarConfig | null;
|
|
104
111
|
readonly diagnostics: Diagnostic[];
|
|
105
112
|
readonly aborted: boolean;
|
|
106
113
|
}
|
|
@@ -449,6 +456,7 @@ function createInitialContext(config: GenerationConfig): PipelineContext {
|
|
|
449
456
|
typesResult: null,
|
|
450
457
|
resolversResult: null,
|
|
451
458
|
directiveDefinitions: null,
|
|
459
|
+
scalarConfig: null,
|
|
452
460
|
diagnostics: [],
|
|
453
461
|
aborted: false,
|
|
454
462
|
};
|
|
@@ -514,11 +522,7 @@ function collectTypeNamesStep(ctx: PipelineContext): PipelineContext {
|
|
|
514
522
|
};
|
|
515
523
|
}
|
|
516
524
|
|
|
517
|
-
function prepareScalarConfig(config: GenerationConfig): {
|
|
518
|
-
customScalarNames: string[];
|
|
519
|
-
globalTypeMappings: GlobalTypeMapping[];
|
|
520
|
-
configScalars: ConfigScalarMapping[];
|
|
521
|
-
} {
|
|
525
|
+
function prepareScalarConfig(config: GenerationConfig): ScalarConfig {
|
|
522
526
|
const customScalarNames =
|
|
523
527
|
config.customScalars?.map((s) => s.graphqlName) ?? [];
|
|
524
528
|
|
|
@@ -556,18 +560,25 @@ function prepareScalarConfig(config: GenerationConfig): {
|
|
|
556
560
|
return { customScalarNames, globalTypeMappings, configScalars };
|
|
557
561
|
}
|
|
558
562
|
|
|
563
|
+
function prepareScalarConfigStep(ctx: PipelineContext): PipelineContext {
|
|
564
|
+
if (ctx.aborted) return ctx;
|
|
565
|
+
|
|
566
|
+
return { ...ctx, scalarConfig: prepareScalarConfig(ctx.config) };
|
|
567
|
+
}
|
|
568
|
+
|
|
559
569
|
function extractTypesStep(ctx: PipelineContext): PipelineContext {
|
|
560
570
|
if (
|
|
561
571
|
ctx.aborted ||
|
|
562
572
|
!ctx.program ||
|
|
563
573
|
!ctx.knownTypeNames ||
|
|
564
574
|
!ctx.knownTypeSymbols ||
|
|
565
|
-
!ctx.underlyingSymbolToTypeName
|
|
575
|
+
!ctx.underlyingSymbolToTypeName ||
|
|
576
|
+
!ctx.scalarConfig
|
|
566
577
|
)
|
|
567
578
|
return ctx;
|
|
568
579
|
|
|
569
580
|
const { customScalarNames, globalTypeMappings, configScalars } =
|
|
570
|
-
|
|
581
|
+
ctx.scalarConfig;
|
|
571
582
|
|
|
572
583
|
const typesResult = extractTypesCore({
|
|
573
584
|
program: ctx.program,
|
|
@@ -591,11 +602,12 @@ function extractResolversStep(ctx: PipelineContext): PipelineContext {
|
|
|
591
602
|
!ctx.knownTypeNames ||
|
|
592
603
|
!ctx.knownTypeSymbols ||
|
|
593
604
|
!ctx.underlyingSymbolToTypeName ||
|
|
594
|
-
!ctx.typesResult
|
|
605
|
+
!ctx.typesResult ||
|
|
606
|
+
!ctx.scalarConfig
|
|
595
607
|
)
|
|
596
608
|
return ctx;
|
|
597
609
|
|
|
598
|
-
const { globalTypeMappings } =
|
|
610
|
+
const { globalTypeMappings } = ctx.scalarConfig;
|
|
599
611
|
|
|
600
612
|
const resolversResult = extractResolversCore({
|
|
601
613
|
program: ctx.program,
|
|
@@ -663,11 +675,16 @@ function generateSchemaStep(ctx: PipelineContext): {
|
|
|
663
675
|
ctx: PipelineContext;
|
|
664
676
|
schemaResult: ReturnType<typeof generateSchema> | null;
|
|
665
677
|
} {
|
|
666
|
-
if (
|
|
678
|
+
if (
|
|
679
|
+
ctx.aborted ||
|
|
680
|
+
!ctx.typesResult ||
|
|
681
|
+
!ctx.resolversResult ||
|
|
682
|
+
!ctx.scalarConfig
|
|
683
|
+
) {
|
|
667
684
|
return { ctx, schemaResult: null };
|
|
668
685
|
}
|
|
669
686
|
|
|
670
|
-
const { customScalarNames } =
|
|
687
|
+
const { customScalarNames } = ctx.scalarConfig;
|
|
671
688
|
const allCustomScalarNames = [
|
|
672
689
|
...customScalarNames,
|
|
673
690
|
...ctx.typesResult.detectedScalarNames,
|
|
@@ -687,6 +704,7 @@ function generateSchemaStep(ctx: PipelineContext): {
|
|
|
687
704
|
enablePruning: null,
|
|
688
705
|
sourceRoot: ctx.config.cwd,
|
|
689
706
|
knownTypeNames: ctx.knownTypeNames,
|
|
707
|
+
importExtension: ctx.config.output.importExtension,
|
|
690
708
|
});
|
|
691
709
|
|
|
692
710
|
const newDiagnostics = [...ctx.diagnostics, ...schemaResult.diagnostics];
|
|
@@ -739,6 +757,7 @@ export async function executeGeneration(
|
|
|
739
757
|
ctx = await scanSourceFilesStep(ctx);
|
|
740
758
|
ctx = createProgramStep(ctx);
|
|
741
759
|
ctx = collectTypeNamesStep(ctx);
|
|
760
|
+
ctx = prepareScalarConfigStep(ctx);
|
|
742
761
|
ctx = extractTypesStep(ctx);
|
|
743
762
|
ctx = extractResolversStep(ctx);
|
|
744
763
|
ctx = extractDirectivesStep(ctx);
|
|
@@ -200,23 +200,23 @@ function extractTypeNameFromType(
|
|
|
200
200
|
function detectResolverFromMetadataType(
|
|
201
201
|
callExpr: ts.CallExpression,
|
|
202
202
|
checker: ts.TypeChecker,
|
|
203
|
-
): DefineApiResolverType |
|
|
203
|
+
): DefineApiResolverType | null {
|
|
204
204
|
const returnType = checker.getTypeAtLocation(callExpr);
|
|
205
205
|
|
|
206
206
|
const metadataProp = returnType.getProperty(RESOLVER_METADATA_PROPERTY);
|
|
207
207
|
if (!metadataProp) {
|
|
208
|
-
return
|
|
208
|
+
return null;
|
|
209
209
|
}
|
|
210
210
|
|
|
211
211
|
const metadataType = checker.getTypeOfSymbol(metadataProp);
|
|
212
212
|
const actualType = getActualMetadataType(metadataType);
|
|
213
213
|
if (!actualType) {
|
|
214
|
-
return
|
|
214
|
+
return null;
|
|
215
215
|
}
|
|
216
216
|
|
|
217
217
|
const kindProp = actualType.getProperty("kind");
|
|
218
218
|
if (!kindProp) {
|
|
219
|
-
return
|
|
219
|
+
return null;
|
|
220
220
|
}
|
|
221
221
|
|
|
222
222
|
const kindType = checker.getTypeOfSymbol(kindProp);
|
|
@@ -227,7 +227,7 @@ function detectResolverFromMetadataType(
|
|
|
227
227
|
}
|
|
228
228
|
}
|
|
229
229
|
|
|
230
|
-
return
|
|
230
|
+
return null;
|
|
231
231
|
}
|
|
232
232
|
|
|
233
233
|
function isInlineTypeLiteralDeclaration(declaration: ts.Declaration): boolean {
|
|
@@ -48,13 +48,13 @@ import type {
|
|
|
48
48
|
} from "../integrator/result-integrator.js";
|
|
49
49
|
|
|
50
50
|
export interface BuildDocumentOptions {
|
|
51
|
-
readonly sourceRoot
|
|
51
|
+
readonly sourceRoot: string | null;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
function appendSourceLocation(
|
|
55
55
|
description: string | null,
|
|
56
56
|
sourceFile: string | null,
|
|
57
|
-
sourceRoot: string |
|
|
57
|
+
sourceRoot: string | null,
|
|
58
58
|
): string | null {
|
|
59
59
|
if (!sourceRoot || !sourceFile) {
|
|
60
60
|
return description;
|
|
@@ -113,7 +113,7 @@ function buildOneOfDirective(): ConstDirectiveNode {
|
|
|
113
113
|
|
|
114
114
|
function buildDirectiveArgumentValue(
|
|
115
115
|
value: DirectiveArgumentValue,
|
|
116
|
-
expectedTypeName
|
|
116
|
+
expectedTypeName: string | null,
|
|
117
117
|
): ConstValueNode {
|
|
118
118
|
switch (value.kind) {
|
|
119
119
|
case "string":
|
|
@@ -159,7 +159,7 @@ function buildDirectiveArgumentValue(
|
|
|
159
159
|
fields: value.fields.map((f) => ({
|
|
160
160
|
kind: Kind.OBJECT_FIELD as const,
|
|
161
161
|
name: buildNameNode(f.name),
|
|
162
|
-
value: buildDirectiveArgumentValue(f.value),
|
|
162
|
+
value: buildDirectiveArgumentValue(f.value, null),
|
|
163
163
|
})),
|
|
164
164
|
};
|
|
165
165
|
}
|
|
@@ -167,7 +167,7 @@ function buildDirectiveArgumentValue(
|
|
|
167
167
|
|
|
168
168
|
function buildDirectiveArgument(
|
|
169
169
|
arg: DirectiveArgument,
|
|
170
|
-
expectedTypeName
|
|
170
|
+
expectedTypeName: string | null,
|
|
171
171
|
): ConstArgumentNode {
|
|
172
172
|
return {
|
|
173
173
|
kind: Kind.ARGUMENT,
|
|
@@ -178,7 +178,7 @@ function buildDirectiveArgument(
|
|
|
178
178
|
|
|
179
179
|
function buildCustomDirective(
|
|
180
180
|
directive: DirectiveInfo,
|
|
181
|
-
directiveDefMap
|
|
181
|
+
directiveDefMap: Map<string, DirectiveDefinitionInfo> | null,
|
|
182
182
|
): ConstDirectiveNode {
|
|
183
183
|
const def = directiveDefMap?.get(directive.name);
|
|
184
184
|
const argTypeMap = new Map<string, string>();
|
|
@@ -189,7 +189,7 @@ function buildCustomDirective(
|
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
const args = directive.args.map((arg) =>
|
|
192
|
-
buildDirectiveArgument(arg, argTypeMap.get(arg.name)),
|
|
192
|
+
buildDirectiveArgument(arg, argTypeMap.get(arg.name) ?? null),
|
|
193
193
|
);
|
|
194
194
|
|
|
195
195
|
return {
|
|
@@ -202,7 +202,7 @@ function buildCustomDirective(
|
|
|
202
202
|
function buildDirectives(
|
|
203
203
|
directives: ReadonlyArray<DirectiveInfo> | null,
|
|
204
204
|
deprecated: DeprecationInfo | null,
|
|
205
|
-
directiveDefMap
|
|
205
|
+
directiveDefMap: Map<string, DirectiveDefinitionInfo> | null,
|
|
206
206
|
): ConstDirectiveNode[] {
|
|
207
207
|
const result: ConstDirectiveNode[] = [];
|
|
208
208
|
|
|
@@ -278,7 +278,12 @@ function buildInputValueDefinitionNode(
|
|
|
278
278
|
? { description: buildStringValueNode(inputValue.description) }
|
|
279
279
|
: {}),
|
|
280
280
|
...(inputValue.defaultValue
|
|
281
|
-
? {
|
|
281
|
+
? {
|
|
282
|
+
defaultValue: buildDirectiveArgumentValue(
|
|
283
|
+
inputValue.defaultValue,
|
|
284
|
+
null,
|
|
285
|
+
),
|
|
286
|
+
}
|
|
282
287
|
: {}),
|
|
283
288
|
...(directives.length > 0 ? { directives } : {}),
|
|
284
289
|
};
|
|
@@ -290,7 +295,7 @@ function sortByName<T extends { name: string }>(items: ReadonlyArray<T>): T[] {
|
|
|
290
295
|
|
|
291
296
|
function buildBaseFieldDefinitionNode(
|
|
292
297
|
field: BaseField,
|
|
293
|
-
directiveDefMap
|
|
298
|
+
directiveDefMap: Map<string, DirectiveDefinitionInfo> | null,
|
|
294
299
|
): FieldDefinitionNode {
|
|
295
300
|
const directives = buildDirectives(
|
|
296
301
|
field.directives,
|
|
@@ -311,8 +316,8 @@ function buildBaseFieldDefinitionNode(
|
|
|
311
316
|
|
|
312
317
|
function buildFieldDefinitionNode(
|
|
313
318
|
field: ExtensionField,
|
|
314
|
-
sourceRoot
|
|
315
|
-
directiveDefMap
|
|
319
|
+
sourceRoot: string | null,
|
|
320
|
+
directiveDefMap: Map<string, DirectiveDefinitionInfo> | null,
|
|
316
321
|
): FieldDefinitionNode {
|
|
317
322
|
const directives = buildDirectives(
|
|
318
323
|
field.directives,
|
|
@@ -338,11 +343,14 @@ function buildFieldDefinitionNode(
|
|
|
338
343
|
};
|
|
339
344
|
}
|
|
340
345
|
|
|
341
|
-
function
|
|
346
|
+
function buildTypeDefinitionNode(
|
|
342
347
|
baseType: BaseType,
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
348
|
+
kind:
|
|
349
|
+
| typeof Kind.OBJECT_TYPE_DEFINITION
|
|
350
|
+
| typeof Kind.INTERFACE_TYPE_DEFINITION,
|
|
351
|
+
sourceRoot: string | null,
|
|
352
|
+
directiveDefMap: Map<string, DirectiveDefinitionInfo> | null,
|
|
353
|
+
): ObjectTypeDefinitionNode | InterfaceTypeDefinitionNode {
|
|
346
354
|
const sortedFields = baseType.fields ? sortByName(baseType.fields) : [];
|
|
347
355
|
const directives = buildDirectives(
|
|
348
356
|
baseType.directives,
|
|
@@ -364,7 +372,7 @@ function buildObjectTypeDefinitionNode(
|
|
|
364
372
|
: undefined;
|
|
365
373
|
|
|
366
374
|
return {
|
|
367
|
-
kind
|
|
375
|
+
kind,
|
|
368
376
|
name: buildNameNode(baseType.name),
|
|
369
377
|
fields: sortedFields.map((f) =>
|
|
370
378
|
buildBaseFieldDefinitionNode(f, directiveDefMap),
|
|
@@ -372,49 +380,12 @@ function buildObjectTypeDefinitionNode(
|
|
|
372
380
|
...(description ? { description: buildStringValueNode(description) } : {}),
|
|
373
381
|
...(directives.length > 0 ? { directives } : {}),
|
|
374
382
|
...(interfaces ? { interfaces } : {}),
|
|
375
|
-
};
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
function buildInterfaceTypeDefinitionNode(
|
|
379
|
-
baseType: BaseType,
|
|
380
|
-
sourceRoot?: string,
|
|
381
|
-
directiveDefMap?: Map<string, DirectiveDefinitionInfo>,
|
|
382
|
-
): InterfaceTypeDefinitionNode {
|
|
383
|
-
const sortedFields = baseType.fields ? sortByName(baseType.fields) : [];
|
|
384
|
-
const directives = buildDirectives(
|
|
385
|
-
baseType.directives,
|
|
386
|
-
baseType.deprecated,
|
|
387
|
-
directiveDefMap,
|
|
388
|
-
);
|
|
389
|
-
|
|
390
|
-
const description = appendSourceLocation(
|
|
391
|
-
baseType.description,
|
|
392
|
-
baseType.sourceFile,
|
|
393
|
-
sourceRoot,
|
|
394
|
-
);
|
|
395
|
-
|
|
396
|
-
const interfaces =
|
|
397
|
-
baseType.implementedInterfaces && baseType.implementedInterfaces.length > 0
|
|
398
|
-
? [...baseType.implementedInterfaces]
|
|
399
|
-
.sort((a, b) => a.localeCompare(b))
|
|
400
|
-
.map(buildNamedTypeNode)
|
|
401
|
-
: undefined;
|
|
402
|
-
|
|
403
|
-
return {
|
|
404
|
-
kind: Kind.INTERFACE_TYPE_DEFINITION,
|
|
405
|
-
name: buildNameNode(baseType.name),
|
|
406
|
-
fields: sortedFields.map((f) =>
|
|
407
|
-
buildBaseFieldDefinitionNode(f, directiveDefMap),
|
|
408
|
-
),
|
|
409
|
-
...(description ? { description: buildStringValueNode(description) } : {}),
|
|
410
|
-
...(directives.length > 0 ? { directives } : {}),
|
|
411
|
-
...(interfaces ? { interfaces } : {}),
|
|
412
|
-
};
|
|
383
|
+
} as ObjectTypeDefinitionNode | InterfaceTypeDefinitionNode;
|
|
413
384
|
}
|
|
414
385
|
|
|
415
386
|
function buildUnionTypeDefinitionNode(
|
|
416
387
|
baseType: BaseType,
|
|
417
|
-
sourceRoot
|
|
388
|
+
sourceRoot: string | null,
|
|
418
389
|
): UnionTypeDefinitionNode {
|
|
419
390
|
const sortedMembers = baseType.unionMembers
|
|
420
391
|
? [...baseType.unionMembers].sort((a, b) => a.localeCompare(b))
|
|
@@ -454,7 +425,7 @@ function buildEnumValueDefinitionNode(
|
|
|
454
425
|
|
|
455
426
|
function buildEnumTypeDefinitionNode(
|
|
456
427
|
baseType: BaseType,
|
|
457
|
-
sourceRoot
|
|
428
|
+
sourceRoot: string | null,
|
|
458
429
|
): EnumTypeDefinitionNode {
|
|
459
430
|
const enumValues = baseType.enumValues ?? [];
|
|
460
431
|
|
|
@@ -474,7 +445,7 @@ function buildEnumTypeDefinitionNode(
|
|
|
474
445
|
|
|
475
446
|
function buildScalarTypeDefinitionNode(
|
|
476
447
|
name: string,
|
|
477
|
-
description
|
|
448
|
+
description: string | null,
|
|
478
449
|
): ScalarTypeDefinitionNode {
|
|
479
450
|
return {
|
|
480
451
|
kind: Kind.SCALAR_TYPE_DEFINITION,
|
|
@@ -485,7 +456,7 @@ function buildScalarTypeDefinitionNode(
|
|
|
485
456
|
|
|
486
457
|
function buildInputFieldDefinitionNode(
|
|
487
458
|
field: BaseField,
|
|
488
|
-
directiveDefMap
|
|
459
|
+
directiveDefMap: Map<string, DirectiveDefinitionInfo> | null,
|
|
489
460
|
): InputValueDefinitionNode {
|
|
490
461
|
const directives = buildDirectives(
|
|
491
462
|
field.directives,
|
|
@@ -501,7 +472,7 @@ function buildInputFieldDefinitionNode(
|
|
|
501
472
|
? { description: buildStringValueNode(field.description) }
|
|
502
473
|
: {}),
|
|
503
474
|
...(field.defaultValue
|
|
504
|
-
? { defaultValue: buildDirectiveArgumentValue(field.defaultValue) }
|
|
475
|
+
? { defaultValue: buildDirectiveArgumentValue(field.defaultValue, null) }
|
|
505
476
|
: {}),
|
|
506
477
|
...(directives.length > 0 ? { directives } : {}),
|
|
507
478
|
};
|
|
@@ -509,8 +480,8 @@ function buildInputFieldDefinitionNode(
|
|
|
509
480
|
|
|
510
481
|
function buildInputObjectTypeDefinitionNode(
|
|
511
482
|
inputType: InputType,
|
|
512
|
-
sourceRoot
|
|
513
|
-
directiveDefMap
|
|
483
|
+
sourceRoot: string | null,
|
|
484
|
+
directiveDefMap: Map<string, DirectiveDefinitionInfo> | null,
|
|
514
485
|
): InputObjectTypeDefinitionNode {
|
|
515
486
|
const sortedFields = sortByName(inputType.fields);
|
|
516
487
|
|
|
@@ -538,8 +509,8 @@ function buildInputObjectTypeDefinitionNode(
|
|
|
538
509
|
|
|
539
510
|
function buildObjectTypeExtensionNode(
|
|
540
511
|
typeExtension: TypeExtension,
|
|
541
|
-
sourceRoot
|
|
542
|
-
directiveDefMap
|
|
512
|
+
sourceRoot: string | null,
|
|
513
|
+
directiveDefMap: Map<string, DirectiveDefinitionInfo> | null,
|
|
543
514
|
): ObjectTypeExtensionNode {
|
|
544
515
|
const sortedFields = sortByName(typeExtension.fields);
|
|
545
516
|
return {
|
|
@@ -553,8 +524,8 @@ function buildObjectTypeExtensionNode(
|
|
|
553
524
|
|
|
554
525
|
function buildInterfaceTypeExtensionNode(
|
|
555
526
|
typeExtension: TypeExtension,
|
|
556
|
-
sourceRoot
|
|
557
|
-
directiveDefMap
|
|
527
|
+
sourceRoot: string | null,
|
|
528
|
+
directiveDefMap: Map<string, DirectiveDefinitionInfo> | null,
|
|
558
529
|
): InterfaceTypeExtensionNode {
|
|
559
530
|
const sortedFields = sortByName(typeExtension.fields);
|
|
560
531
|
return {
|
|
@@ -600,9 +571,9 @@ function buildDirectiveDefinitionNode(
|
|
|
600
571
|
|
|
601
572
|
export function buildDocumentNode(
|
|
602
573
|
integratedResult: IntegratedResult,
|
|
603
|
-
options
|
|
574
|
+
options: BuildDocumentOptions,
|
|
604
575
|
): DocumentNode {
|
|
605
|
-
const sourceRoot = options
|
|
576
|
+
const sourceRoot = options.sourceRoot;
|
|
606
577
|
const definitions: DefinitionNode[] = [];
|
|
607
578
|
|
|
608
579
|
// Build directive definition map for argument type lookup
|
|
@@ -628,19 +599,9 @@ export function buildDocumentNode(
|
|
|
628
599
|
);
|
|
629
600
|
for (const scalar of sortedScalars) {
|
|
630
601
|
definitions.push(
|
|
631
|
-
buildScalarTypeDefinitionNode(
|
|
632
|
-
scalar.scalarName,
|
|
633
|
-
scalar.description ?? undefined,
|
|
634
|
-
),
|
|
602
|
+
buildScalarTypeDefinitionNode(scalar.scalarName, scalar.description),
|
|
635
603
|
);
|
|
636
604
|
}
|
|
637
|
-
} else if (integratedResult.customScalarNames) {
|
|
638
|
-
const sortedScalarNames = [...integratedResult.customScalarNames].sort(
|
|
639
|
-
(a, b) => a.localeCompare(b),
|
|
640
|
-
);
|
|
641
|
-
for (const scalarName of sortedScalarNames) {
|
|
642
|
-
definitions.push(buildScalarTypeDefinitionNode(scalarName));
|
|
643
|
-
}
|
|
644
605
|
}
|
|
645
606
|
|
|
646
607
|
const sortedBaseTypes = [...integratedResult.baseTypes].sort((a, b) =>
|
|
@@ -650,11 +611,21 @@ export function buildDocumentNode(
|
|
|
650
611
|
for (const baseType of sortedBaseTypes) {
|
|
651
612
|
if (baseType.kind === "Interface") {
|
|
652
613
|
definitions.push(
|
|
653
|
-
|
|
614
|
+
buildTypeDefinitionNode(
|
|
615
|
+
baseType,
|
|
616
|
+
Kind.INTERFACE_TYPE_DEFINITION,
|
|
617
|
+
sourceRoot,
|
|
618
|
+
directiveDefMap,
|
|
619
|
+
),
|
|
654
620
|
);
|
|
655
621
|
} else if (baseType.kind === "Object") {
|
|
656
622
|
definitions.push(
|
|
657
|
-
|
|
623
|
+
buildTypeDefinitionNode(
|
|
624
|
+
baseType,
|
|
625
|
+
Kind.OBJECT_TYPE_DEFINITION,
|
|
626
|
+
sourceRoot,
|
|
627
|
+
directiveDefMap,
|
|
628
|
+
),
|
|
658
629
|
);
|
|
659
630
|
} else if (baseType.kind === "Union") {
|
|
660
631
|
definitions.push(buildUnionTypeDefinitionNode(baseType, sourceRoot));
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import type { AutoGeneratedResolveType } from "../../auto-type-generator/resolve-type-generator.js";
|
|
3
3
|
import { TYPENAME_FIELD_NAMES } from "../../auto-type-generator/typename-types.js";
|
|
4
|
+
import type { ImportExtension } from "../../config/types.js";
|
|
4
5
|
import { toPosixPath } from "../../shared/index.js";
|
|
5
6
|
import type { CollectedScalarType } from "../../type-extractor/collector/scalar-collector.js";
|
|
6
7
|
import {
|
|
@@ -23,7 +24,7 @@ const GENERATED_FILE_HEADER =
|
|
|
23
24
|
|
|
24
25
|
function formatDocumentNodeAsCode(
|
|
25
26
|
integratedResult: IntegratedResult,
|
|
26
|
-
options
|
|
27
|
+
options: BuildDocumentOptions,
|
|
27
28
|
): string {
|
|
28
29
|
const doc = buildDocumentNode(integratedResult, options);
|
|
29
30
|
|
|
@@ -32,7 +33,7 @@ function formatDocumentNodeAsCode(
|
|
|
32
33
|
|
|
33
34
|
export function emitTypeDefsCode(
|
|
34
35
|
integratedResult: IntegratedResult,
|
|
35
|
-
options
|
|
36
|
+
options: BuildDocumentOptions,
|
|
36
37
|
): string {
|
|
37
38
|
const documentNodeCode = formatDocumentNodeAsCode(integratedResult, options);
|
|
38
39
|
|
|
@@ -44,13 +45,31 @@ export const typeDefs: DocumentNode = ${documentNodeCode} as DocumentNode;
|
|
|
44
45
|
`;
|
|
45
46
|
}
|
|
46
47
|
|
|
47
|
-
function
|
|
48
|
+
function applyExtension(
|
|
49
|
+
relativePath: string,
|
|
50
|
+
importExtension: ImportExtension,
|
|
51
|
+
): string {
|
|
52
|
+
switch (importExtension) {
|
|
53
|
+
case "js":
|
|
54
|
+
return relativePath.replace(/\.ts$/, ".js");
|
|
55
|
+
case "ts":
|
|
56
|
+
return relativePath;
|
|
57
|
+
case "none":
|
|
58
|
+
return relativePath.replace(/\.ts$/, "");
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function computeRelativeImportPath(
|
|
63
|
+
fromDir: string,
|
|
64
|
+
toFile: string,
|
|
65
|
+
importExtension: ImportExtension,
|
|
66
|
+
): string {
|
|
48
67
|
const relativePath = toPosixPath(path.relative(fromDir, toFile));
|
|
49
|
-
const
|
|
50
|
-
if (!
|
|
51
|
-
return `./${
|
|
68
|
+
const withExt = applyExtension(relativePath, importExtension);
|
|
69
|
+
if (!withExt.startsWith(".")) {
|
|
70
|
+
return `./${withExt}`;
|
|
52
71
|
}
|
|
53
|
-
return
|
|
72
|
+
return withExt;
|
|
54
73
|
}
|
|
55
74
|
|
|
56
75
|
interface ScalarTypeImport {
|
|
@@ -94,6 +113,7 @@ function collectScalarTypeImports(
|
|
|
94
113
|
function buildScalarTypeImports(
|
|
95
114
|
scalarTypeImports: ScalarTypeImport[],
|
|
96
115
|
outputDir: string,
|
|
116
|
+
importExtension: ImportExtension,
|
|
97
117
|
): string[] {
|
|
98
118
|
const importsByFile = new Map<string, string[]>();
|
|
99
119
|
|
|
@@ -108,7 +128,11 @@ function buildScalarTypeImports(
|
|
|
108
128
|
|
|
109
129
|
for (const sourceFile of sortedFiles) {
|
|
110
130
|
const typeNames = importsByFile.get(sourceFile) ?? [];
|
|
111
|
-
const importPath = computeRelativeImportPath(
|
|
131
|
+
const importPath = computeRelativeImportPath(
|
|
132
|
+
outputDir,
|
|
133
|
+
sourceFile,
|
|
134
|
+
importExtension,
|
|
135
|
+
);
|
|
112
136
|
imports.push(
|
|
113
137
|
`import type { ${typeNames.sort().join(", ")} } from "${importPath}";`,
|
|
114
138
|
);
|
|
@@ -172,13 +196,18 @@ function collectResolverImportsByFile(
|
|
|
172
196
|
function buildResolverImports(
|
|
173
197
|
importsByFile: Map<string, Set<string>>,
|
|
174
198
|
outputDir: string,
|
|
199
|
+
importExtension: ImportExtension,
|
|
175
200
|
): string[] {
|
|
176
201
|
const imports: string[] = [];
|
|
177
202
|
const sortedFiles = [...importsByFile.keys()].sort();
|
|
178
203
|
|
|
179
204
|
for (const sourceFile of sortedFiles) {
|
|
180
205
|
const valueNames = importsByFile.get(sourceFile) ?? new Set<string>();
|
|
181
|
-
const importPath = computeRelativeImportPath(
|
|
206
|
+
const importPath = computeRelativeImportPath(
|
|
207
|
+
outputDir,
|
|
208
|
+
sourceFile,
|
|
209
|
+
importExtension,
|
|
210
|
+
);
|
|
182
211
|
const sortedValues = [...valueNames].sort();
|
|
183
212
|
|
|
184
213
|
if (sortedValues.length > 0) {
|
|
@@ -331,6 +360,7 @@ interface EmitResolversCodeParams {
|
|
|
331
360
|
readonly customScalars: ReadonlyArray<CollectedScalarType>;
|
|
332
361
|
readonly numericEnums: ReadonlyArray<NumericEnumInfo>;
|
|
333
362
|
readonly stringEnumMappings: ReadonlyArray<StringEnumMappingInfo>;
|
|
363
|
+
readonly importExtension: ImportExtension;
|
|
334
364
|
}
|
|
335
365
|
|
|
336
366
|
export function emitResolversCode(params: EmitResolversCodeParams): string {
|
|
@@ -340,6 +370,7 @@ export function emitResolversCode(params: EmitResolversCodeParams): string {
|
|
|
340
370
|
customScalars,
|
|
341
371
|
numericEnums,
|
|
342
372
|
stringEnumMappings,
|
|
373
|
+
importExtension,
|
|
343
374
|
} = params;
|
|
344
375
|
const hasCustomScalars = customScalars.length > 0;
|
|
345
376
|
const imports: string[] = [];
|
|
@@ -349,11 +380,17 @@ export function emitResolversCode(params: EmitResolversCodeParams): string {
|
|
|
349
380
|
}
|
|
350
381
|
|
|
351
382
|
const importsByFile = collectResolverImportsByFile(resolverInfo);
|
|
352
|
-
imports.push(
|
|
383
|
+
imports.push(
|
|
384
|
+
...buildResolverImports(importsByFile, outputDir, importExtension),
|
|
385
|
+
);
|
|
353
386
|
|
|
354
387
|
if (hasCustomScalars) {
|
|
355
388
|
const scalarTypeImports = collectScalarTypeImports(customScalars);
|
|
356
|
-
const scalarImports = buildScalarTypeImports(
|
|
389
|
+
const scalarImports = buildScalarTypeImports(
|
|
390
|
+
scalarTypeImports,
|
|
391
|
+
outputDir,
|
|
392
|
+
importExtension,
|
|
393
|
+
);
|
|
357
394
|
imports.push(...scalarImports);
|
|
358
395
|
}
|
|
359
396
|
|
|
@@ -3,10 +3,6 @@ import { type DocumentNode, print } from "graphql";
|
|
|
3
3
|
const GENERATED_FILE_HEADER =
|
|
4
4
|
"# This file is auto-generated by gqlkit. DO NOT EDIT.";
|
|
5
5
|
|
|
6
|
-
/**
|
|
7
|
-
* DocumentNode を SDL 形式の文字列に変換する。
|
|
8
|
-
* graphql パッケージの print() 関数を使用して SDL を生成する。
|
|
9
|
-
*/
|
|
10
6
|
export function emitSdlContent(documentNode: DocumentNode): string {
|
|
11
7
|
const sdl = print(documentNode);
|
|
12
8
|
return `${GENERATED_FILE_HEADER}\n\n${sdl}`;
|