@gqlkit-ts/cli 0.2.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 +10 -4
- package/dist/auto-type-generator/auto-type-generator.d.ts.map +1 -1
- package/dist/auto-type-generator/auto-type-generator.js +656 -146
- package/dist/auto-type-generator/auto-type-generator.js.map +1 -1
- package/dist/auto-type-generator/index.d.ts +8 -1
- package/dist/auto-type-generator/index.d.ts.map +1 -1
- package/dist/auto-type-generator/index.js +3 -0
- package/dist/auto-type-generator/index.js.map +1 -1
- package/dist/auto-type-generator/inline-enum-collector.d.ts +13 -5
- package/dist/auto-type-generator/inline-enum-collector.d.ts.map +1 -1
- package/dist/auto-type-generator/inline-enum-collector.js +107 -71
- package/dist/auto-type-generator/inline-enum-collector.js.map +1 -1
- package/dist/auto-type-generator/inline-object-traverser.d.ts +20 -0
- package/dist/auto-type-generator/inline-object-traverser.d.ts.map +1 -0
- package/dist/auto-type-generator/inline-object-traverser.js +22 -0
- package/dist/auto-type-generator/inline-object-traverser.js.map +1 -0
- package/dist/auto-type-generator/inline-union-collector.d.ts +29 -0
- package/dist/auto-type-generator/inline-union-collector.d.ts.map +1 -0
- package/dist/auto-type-generator/inline-union-collector.js +216 -0
- package/dist/auto-type-generator/inline-union-collector.js.map +1 -0
- package/dist/auto-type-generator/inline-union-types.d.ts +29 -0
- package/dist/auto-type-generator/inline-union-types.d.ts.map +1 -0
- package/dist/auto-type-generator/inline-union-types.js +2 -0
- package/dist/auto-type-generator/inline-union-types.js.map +1 -0
- package/dist/auto-type-generator/inline-union-validator.d.ts +76 -0
- package/dist/auto-type-generator/inline-union-validator.d.ts.map +1 -0
- package/dist/auto-type-generator/inline-union-validator.js +329 -0
- package/dist/auto-type-generator/inline-union-validator.js.map +1 -0
- package/dist/auto-type-generator/naming-convention.d.ts +18 -1
- package/dist/auto-type-generator/naming-convention.d.ts.map +1 -1
- package/dist/auto-type-generator/naming-convention.js +16 -0
- package/dist/auto-type-generator/naming-convention.js.map +1 -1
- package/dist/auto-type-generator/resolve-type-generator.d.ts +20 -0
- package/dist/auto-type-generator/resolve-type-generator.d.ts.map +1 -0
- package/dist/auto-type-generator/resolve-type-generator.js +2 -0
- package/dist/auto-type-generator/resolve-type-generator.js.map +1 -0
- package/dist/auto-type-generator/resolver-field-iterator.d.ts +13 -0
- package/dist/auto-type-generator/resolver-field-iterator.d.ts.map +1 -0
- package/dist/auto-type-generator/resolver-field-iterator.js +22 -0
- package/dist/auto-type-generator/resolver-field-iterator.js.map +1 -0
- package/dist/auto-type-generator/typename-extractor.d.ts +26 -0
- package/dist/auto-type-generator/typename-extractor.d.ts.map +1 -0
- package/dist/auto-type-generator/typename-extractor.js +142 -0
- package/dist/auto-type-generator/typename-extractor.js.map +1 -0
- package/dist/auto-type-generator/typename-resolve-type-generator.d.ts +35 -0
- package/dist/auto-type-generator/typename-resolve-type-generator.d.ts.map +1 -0
- package/dist/auto-type-generator/typename-resolve-type-generator.js +177 -0
- package/dist/auto-type-generator/typename-resolve-type-generator.js.map +1 -0
- package/dist/auto-type-generator/typename-types.d.ts +43 -0
- package/dist/auto-type-generator/typename-types.d.ts.map +1 -0
- package/dist/auto-type-generator/typename-types.js +37 -0
- package/dist/auto-type-generator/typename-types.js.map +1 -0
- package/dist/auto-type-generator/typename-validator.d.ts +37 -0
- package/dist/auto-type-generator/typename-validator.d.ts.map +1 -0
- package/dist/auto-type-generator/typename-validator.js +206 -0
- package/dist/auto-type-generator/typename-validator.js.map +1 -0
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/docs.d.ts +51 -0
- package/dist/commands/docs.d.ts.map +1 -0
- package/dist/commands/docs.js +154 -0
- package/dist/commands/docs.js.map +1 -0
- 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 +32 -12
- package/dist/gen-orchestrator/orchestrator.js.map +1 -1
- package/dist/resolver-extractor/extract-resolvers.d.ts +19 -1
- package/dist/resolver-extractor/extract-resolvers.d.ts.map +1 -1
- package/dist/resolver-extractor/extractor/define-api-extractor.d.ts +5 -0
- package/dist/resolver-extractor/extractor/define-api-extractor.d.ts.map +1 -1
- package/dist/resolver-extractor/extractor/define-api-extractor.js +18 -65
- package/dist/resolver-extractor/extractor/define-api-extractor.js.map +1 -1
- package/dist/resolver-extractor/index.d.ts +0 -1
- package/dist/resolver-extractor/index.d.ts.map +1 -1
- package/dist/resolver-extractor/validator/abstract-resolver-validator.d.ts +1 -0
- package/dist/resolver-extractor/validator/abstract-resolver-validator.d.ts.map +1 -1
- package/dist/resolver-extractor/validator/abstract-resolver-validator.js +9 -5
- package/dist/resolver-extractor/validator/abstract-resolver-validator.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 +42 -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 +3 -0
- package/dist/schema-generator/generate-schema.d.ts.map +1 -1
- package/dist/schema-generator/generate-schema.js +83 -5
- package/dist/schema-generator/generate-schema.js.map +1 -1
- package/dist/schema-generator/integrator/result-integrator.d.ts +19 -9
- package/dist/schema-generator/integrator/result-integrator.d.ts.map +1 -1
- package/dist/schema-generator/integrator/result-integrator.js +60 -44
- package/dist/schema-generator/integrator/result-integrator.js.map +1 -1
- package/dist/schema-generator/resolver-collector/resolver-collector.d.ts +2 -0
- package/dist/schema-generator/resolver-collector/resolver-collector.d.ts.map +1 -1
- package/dist/schema-generator/resolver-collector/resolver-collector.js +22 -0
- package/dist/schema-generator/resolver-collector/resolver-collector.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/enum-prefix-detector.d.ts +63 -0
- package/dist/shared/enum-prefix-detector.d.ts.map +1 -0
- package/dist/shared/enum-prefix-detector.js +80 -0
- package/dist/shared/enum-prefix-detector.js.map +1 -0
- package/dist/shared/ignore-fields-detector.d.ts +26 -0
- package/dist/shared/ignore-fields-detector.d.ts.map +1 -0
- package/dist/shared/ignore-fields-detector.js +83 -0
- package/dist/shared/ignore-fields-detector.js.map +1 -0
- package/dist/shared/ignore-fields-validator.d.ts +29 -0
- package/dist/shared/ignore-fields-validator.d.ts.map +1 -0
- package/dist/shared/ignore-fields-validator.js +43 -0
- package/dist/shared/ignore-fields-validator.js.map +1 -0
- package/dist/shared/index.d.ts +2 -0
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/source-location.d.ts +5 -0
- package/dist/shared/source-location.d.ts.map +1 -1
- package/dist/shared/source-location.js +7 -0
- package/dist/shared/source-location.js.map +1 -1
- 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 +27 -18
- 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 +81 -7
- package/dist/type-extractor/extractor/field-type-resolver.js.map +1 -1
- package/dist/type-extractor/extractor/type-extractor.d.ts.map +1 -1
- package/dist/type-extractor/extractor/type-extractor.js +88 -23
- package/dist/type-extractor/extractor/type-extractor.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/types/ts-type-reference-factory.d.ts +10 -2
- package/dist/type-extractor/types/ts-type-reference-factory.d.ts.map +1 -1
- package/dist/type-extractor/types/ts-type-reference-factory.js +8 -2
- package/dist/type-extractor/types/ts-type-reference-factory.js.map +1 -1
- package/dist/type-extractor/types/typescript.d.ts +4 -0
- package/dist/type-extractor/types/typescript.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/coding-agents.md +64 -0
- package/docs/configuration.md +15 -20
- package/docs/getting-started.md +15 -12
- package/docs/index.md +36 -22
- package/docs/integration/apollo.md +8 -40
- package/docs/integration/drizzle.md +6 -10
- package/docs/integration/prisma.md +196 -0
- package/docs/integration/yoga.md +8 -40
- package/docs/schema/abstract-resolvers.md +117 -0
- package/docs/schema/directives.md +5 -0
- package/docs/schema/documentation.md +5 -0
- package/docs/schema/enums.md +99 -0
- package/docs/schema/fields.md +64 -0
- package/docs/schema/index.md +21 -0
- package/docs/schema/inputs.md +115 -15
- package/docs/schema/interfaces.md +31 -1
- package/docs/schema/objects.md +40 -0
- package/docs/schema/queries-mutations.md +136 -22
- package/docs/schema/scalars.md +5 -0
- package/docs/schema/unions.md +208 -1
- package/docs/what-is-gqlkit.md +13 -8
- package/package.json +6 -4
- package/src/auto-type-generator/auto-type-generator.ts +969 -227
- package/src/auto-type-generator/index.ts +42 -0
- package/src/auto-type-generator/inline-enum-collector.ts +187 -139
- package/src/auto-type-generator/inline-object-traverser.ts +49 -0
- package/src/auto-type-generator/inline-union-collector.ts +402 -0
- package/src/auto-type-generator/inline-union-types.ts +33 -0
- package/src/auto-type-generator/inline-union-validator.ts +482 -0
- package/src/auto-type-generator/naming-convention.ts +38 -1
- package/src/auto-type-generator/resolve-type-generator.ts +21 -0
- package/src/auto-type-generator/resolver-field-iterator.ts +39 -0
- package/src/auto-type-generator/typename-extractor.ts +230 -0
- package/src/auto-type-generator/typename-resolve-type-generator.ts +281 -0
- package/src/auto-type-generator/typename-types.ts +66 -0
- package/src/auto-type-generator/typename-validator.ts +326 -0
- package/src/cli.ts +2 -0
- package/src/commands/docs.ts +211 -0
- 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 +50 -17
- package/src/resolver-extractor/extract-resolvers.ts +19 -0
- package/src/resolver-extractor/extractor/define-api-extractor.ts +28 -94
- package/src/resolver-extractor/index.ts +0 -6
- package/src/resolver-extractor/validator/abstract-resolver-validator.ts +16 -8
- package/src/schema-generator/builder/ast-builder.ts +52 -81
- package/src/schema-generator/emitter/code-emitter.ts +82 -11
- package/src/schema-generator/emitter/sdl-emitter.ts +0 -4
- package/src/schema-generator/generate-schema.ts +109 -14
- package/src/schema-generator/integrator/result-integrator.ts +91 -63
- package/src/schema-generator/resolver-collector/resolver-collector.ts +34 -0
- package/src/shared/branded-type-detector.ts +182 -0
- package/src/shared/enum-prefix-detector.ts +99 -0
- package/src/shared/ignore-fields-detector.ts +109 -0
- package/src/shared/ignore-fields-validator.ts +66 -0
- package/src/shared/index.ts +2 -0
- package/src/shared/source-location.ts +11 -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 +37 -23
- package/src/type-extractor/extractor/field-type-resolver.ts +97 -7
- package/src/type-extractor/extractor/type-extractor.ts +103 -26
- package/src/type-extractor/types/diagnostics.ts +13 -2
- package/src/type-extractor/types/ts-type-reference-factory.ts +18 -5
- package/src/type-extractor/types/typescript.ts +4 -0
- package/src/type-extractor/validator/type-validator.ts +2 -15
- package/dist/resolver-extractor/validator/only-validator.d.ts +0 -61
- package/dist/resolver-extractor/validator/only-validator.d.ts.map +0 -1
- package/dist/resolver-extractor/validator/only-validator.js +0 -76
- package/dist/resolver-extractor/validator/only-validator.js.map +0 -1
- package/src/resolver-extractor/validator/only-validator.ts +0 -158
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IgnoreFields validator.
|
|
3
|
+
*
|
|
4
|
+
* This module provides validation functions for ignoreFields metadata,
|
|
5
|
+
* checking that specified field names exist in the type and that not
|
|
6
|
+
* all fields are excluded.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type {
|
|
10
|
+
Diagnostic,
|
|
11
|
+
SourceLocation,
|
|
12
|
+
} from "../type-extractor/types/diagnostics.js";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Parameters for validateIgnoreFields function.
|
|
16
|
+
*/
|
|
17
|
+
export interface ValidateIgnoreFieldsParams {
|
|
18
|
+
readonly typeName: string;
|
|
19
|
+
readonly ignoreFields: ReadonlySet<string>;
|
|
20
|
+
readonly allFieldNames: ReadonlySet<string>;
|
|
21
|
+
readonly sourceLocation: SourceLocation;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Validates ignoreFields metadata.
|
|
26
|
+
*
|
|
27
|
+
* This function checks:
|
|
28
|
+
* 1. All field names in ignoreFields exist in the type
|
|
29
|
+
* 2. Not all fields are excluded (at least one field must remain)
|
|
30
|
+
*
|
|
31
|
+
* @param params - The validation parameters
|
|
32
|
+
* @returns Array of diagnostics (empty if valid)
|
|
33
|
+
*/
|
|
34
|
+
export function validateIgnoreFields(
|
|
35
|
+
params: ValidateIgnoreFieldsParams,
|
|
36
|
+
): ReadonlyArray<Diagnostic> {
|
|
37
|
+
const { typeName, ignoreFields, allFieldNames, sourceLocation } = params;
|
|
38
|
+
const diagnostics: Diagnostic[] = [];
|
|
39
|
+
|
|
40
|
+
for (const fieldName of ignoreFields) {
|
|
41
|
+
if (!allFieldNames.has(fieldName)) {
|
|
42
|
+
const availableFields = [...allFieldNames].sort().join(", ");
|
|
43
|
+
diagnostics.push({
|
|
44
|
+
code: "IGNORE_FIELD_NOT_FOUND",
|
|
45
|
+
message: `Type '${typeName}': ignoreFields contains unknown field '${fieldName}'. Available fields: ${availableFields}`,
|
|
46
|
+
severity: "error",
|
|
47
|
+
location: sourceLocation,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const remainingFieldCount = [...allFieldNames].filter(
|
|
53
|
+
(f) => !ignoreFields.has(f),
|
|
54
|
+
).length;
|
|
55
|
+
|
|
56
|
+
if (remainingFieldCount === 0 && allFieldNames.size > 0) {
|
|
57
|
+
diagnostics.push({
|
|
58
|
+
code: "IGNORE_ALL_FIELDS",
|
|
59
|
+
message: `Type '${typeName}': ignoreFields excludes all fields. At least one field must remain.`,
|
|
60
|
+
severity: "error",
|
|
61
|
+
location: sourceLocation,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return diagnostics;
|
|
66
|
+
}
|
package/src/shared/index.ts
CHANGED
|
@@ -26,6 +26,8 @@ export {
|
|
|
26
26
|
type ScanResult,
|
|
27
27
|
scanDirectory,
|
|
28
28
|
} from "./file-scanner.js";
|
|
29
|
+
export type { DetectIgnoreFieldsParams } from "./ignore-fields-detector.js";
|
|
30
|
+
export type { ValidateIgnoreFieldsParams } from "./ignore-fields-validator.js";
|
|
29
31
|
export type { TypeConverter } from "./inline-object-extractor.js";
|
|
30
32
|
export { toPosixPath } from "./path-utils.js";
|
|
31
33
|
export type { SourceLocation } from "./source-location.js";
|
|
@@ -25,3 +25,14 @@ export function getSourceLocationFromNode(
|
|
|
25
25
|
column: character + 1,
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Returns the source location if present, otherwise creates a default location
|
|
31
|
+
* with the given source file and line/column 1.
|
|
32
|
+
*/
|
|
33
|
+
export function getSourceLocationOrDefault(
|
|
34
|
+
location: SourceLocation | null,
|
|
35
|
+
sourceFile: string,
|
|
36
|
+
): SourceLocation {
|
|
37
|
+
return location ?? { file: sourceFile, line: 1, column: 1 };
|
|
38
|
+
}
|
|
@@ -24,45 +24,29 @@ function isReservedName(name: string): boolean {
|
|
|
24
24
|
return name.startsWith("__");
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
* Check if a field name is eligible to be included as a GraphQL object field.
|
|
29
|
-
*/
|
|
30
|
-
export function isEligibleAsObjectField(fieldName: string): EligibilityResult {
|
|
31
|
-
if (isReservedName(fieldName)) {
|
|
32
|
-
return {
|
|
33
|
-
eligible: false,
|
|
34
|
-
skipReason: {
|
|
35
|
-
code: "RESERVED_NAME",
|
|
36
|
-
message: `Field '${fieldName}' starts with '__' which is reserved for GraphQL introspection`,
|
|
37
|
-
},
|
|
38
|
-
};
|
|
39
|
-
}
|
|
27
|
+
export type FieldEligibilityKind = "object" | "input";
|
|
40
28
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
skipReason: {
|
|
45
|
-
code: "INVALID_NAME",
|
|
46
|
-
message: `Field '${fieldName}' is not a valid GraphQL identifier (must match /^[_A-Za-z][_0-9A-Za-z]*$/)`,
|
|
47
|
-
},
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return { eligible: true, skipReason: null };
|
|
29
|
+
export interface IsEligibleFieldParams {
|
|
30
|
+
readonly fieldName: string;
|
|
31
|
+
readonly kind: FieldEligibilityKind;
|
|
52
32
|
}
|
|
53
33
|
|
|
54
34
|
/**
|
|
55
|
-
* Check if a field name is eligible to be included as a GraphQL
|
|
35
|
+
* Check if a field name is eligible to be included as a GraphQL field.
|
|
36
|
+
* Uses the kind parameter to determine the error message prefix.
|
|
56
37
|
*/
|
|
57
|
-
export function
|
|
58
|
-
|
|
38
|
+
export function isEligibleField(
|
|
39
|
+
params: IsEligibleFieldParams,
|
|
59
40
|
): EligibilityResult {
|
|
41
|
+
const { fieldName, kind } = params;
|
|
42
|
+
const prefix = kind === "input" ? "Input field" : "Field";
|
|
43
|
+
|
|
60
44
|
if (isReservedName(fieldName)) {
|
|
61
45
|
return {
|
|
62
46
|
eligible: false,
|
|
63
47
|
skipReason: {
|
|
64
48
|
code: "RESERVED_NAME",
|
|
65
|
-
message:
|
|
49
|
+
message: `${prefix} '${fieldName}' starts with '__' which is reserved for GraphQL introspection`,
|
|
66
50
|
},
|
|
67
51
|
};
|
|
68
52
|
}
|
|
@@ -72,7 +56,7 @@ export function isEligibleAsInputObjectField(
|
|
|
72
56
|
eligible: false,
|
|
73
57
|
skipReason: {
|
|
74
58
|
code: "INVALID_NAME",
|
|
75
|
-
message:
|
|
59
|
+
message: `${prefix} '${fieldName}' is not a valid GraphQL identifier (must match /^[_A-Za-z][_0-9A-Za-z]*$/)`,
|
|
76
60
|
},
|
|
77
61
|
};
|
|
78
62
|
}
|
|
@@ -3,6 +3,11 @@ import {
|
|
|
3
3
|
isBuiltInScalar,
|
|
4
4
|
PRIMITIVE_TYPE_MAP,
|
|
5
5
|
} from "../../shared/constants.js";
|
|
6
|
+
import {
|
|
7
|
+
detectEnumPrefix,
|
|
8
|
+
stripEnumPrefix,
|
|
9
|
+
} from "../../shared/enum-prefix-detector.js";
|
|
10
|
+
import { toScreamingSnakeCase } from "../../shared/string-utils.js";
|
|
6
11
|
import { convertTsTypeToGraphQLType } from "../../shared/type-converter.js";
|
|
7
12
|
import type {
|
|
8
13
|
Diagnostic,
|
|
@@ -15,11 +20,7 @@ import type {
|
|
|
15
20
|
InlineObjectProperty,
|
|
16
21
|
SourceLocation,
|
|
17
22
|
} from "../types/index.js";
|
|
18
|
-
import {
|
|
19
|
-
isEligibleAsEnumValue,
|
|
20
|
-
isEligibleAsInputObjectField,
|
|
21
|
-
isEligibleAsObjectField,
|
|
22
|
-
} from "./field-eligibility.js";
|
|
23
|
+
import { isEligibleAsEnumValue, isEligibleField } from "./field-eligibility.js";
|
|
23
24
|
|
|
24
25
|
export interface ConversionResult {
|
|
25
26
|
readonly types: ReadonlyArray<GraphQLTypeInfo>;
|
|
@@ -37,14 +38,6 @@ function isInputTypeName(name: string): boolean {
|
|
|
37
38
|
return name.endsWith("Input");
|
|
38
39
|
}
|
|
39
40
|
|
|
40
|
-
function toScreamingSnakeCase(value: string): string {
|
|
41
|
-
return value
|
|
42
|
-
.replace(/[-\s]+/g, "_")
|
|
43
|
-
.replace(/([a-z])([A-Z])/g, "$1_$2")
|
|
44
|
-
.replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2")
|
|
45
|
-
.toUpperCase();
|
|
46
|
-
}
|
|
47
|
-
|
|
48
41
|
interface ConvertEnumMembersParams {
|
|
49
42
|
readonly members: ReadonlyArray<EnumMemberInfo>;
|
|
50
43
|
readonly enumName: string;
|
|
@@ -60,6 +53,11 @@ interface ConvertEnumMembersResult {
|
|
|
60
53
|
readonly hasError: boolean;
|
|
61
54
|
}
|
|
62
55
|
|
|
56
|
+
interface ConvertedMemberInfo {
|
|
57
|
+
readonly convertedName: string;
|
|
58
|
+
readonly member: EnumMemberInfo;
|
|
59
|
+
}
|
|
60
|
+
|
|
63
61
|
function convertEnumMembers(
|
|
64
62
|
params: ConvertEnumMembersParams,
|
|
65
63
|
): ConvertEnumMembersResult {
|
|
@@ -69,7 +67,7 @@ function convertEnumMembers(
|
|
|
69
67
|
let isNumeric = false;
|
|
70
68
|
let needsMapping = false;
|
|
71
69
|
|
|
72
|
-
const
|
|
70
|
+
const eligibleMembers: ConvertedMemberInfo[] = [];
|
|
73
71
|
|
|
74
72
|
for (const member of members) {
|
|
75
73
|
const convertedName = toScreamingSnakeCase(member.name);
|
|
@@ -93,16 +91,31 @@ function convertEnumMembers(
|
|
|
93
91
|
isNumeric = true;
|
|
94
92
|
}
|
|
95
93
|
|
|
96
|
-
|
|
94
|
+
eligibleMembers.push({ convertedName, member });
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const prefixDetectionResult = detectEnumPrefix({
|
|
98
|
+
enumName,
|
|
99
|
+
memberValues: eligibleMembers.map((m) => m.convertedName),
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
const finalNameToOriginals = new Map<string, string[]>();
|
|
103
|
+
|
|
104
|
+
for (const { convertedName, member } of eligibleMembers) {
|
|
105
|
+
let finalName = convertedName;
|
|
106
|
+
if (prefixDetectionResult.shouldStrip && prefixDetectionResult.prefix) {
|
|
107
|
+
finalName = stripEnumPrefix(convertedName, prefixDetectionResult.prefix);
|
|
108
|
+
needsMapping = true;
|
|
109
|
+
} else if (convertedName !== member.value) {
|
|
97
110
|
needsMapping = true;
|
|
98
111
|
}
|
|
99
112
|
|
|
100
|
-
const existingOriginals =
|
|
113
|
+
const existingOriginals = finalNameToOriginals.get(finalName) ?? [];
|
|
101
114
|
existingOriginals.push(member.value);
|
|
102
|
-
|
|
115
|
+
finalNameToOriginals.set(finalName, existingOriginals);
|
|
103
116
|
|
|
104
117
|
values.push({
|
|
105
|
-
name:
|
|
118
|
+
name: finalName,
|
|
106
119
|
originalValue: member.value,
|
|
107
120
|
numericValue: member.numericValue,
|
|
108
121
|
description: member.description,
|
|
@@ -111,11 +124,11 @@ function convertEnumMembers(
|
|
|
111
124
|
}
|
|
112
125
|
|
|
113
126
|
let hasError = false;
|
|
114
|
-
for (const [
|
|
127
|
+
for (const [finalName, originals] of finalNameToOriginals) {
|
|
115
128
|
if (originals.length > 1) {
|
|
116
129
|
diagnostics.push({
|
|
117
130
|
code: "DUPLICATE_ENUM_VALUE_AFTER_CONVERSION",
|
|
118
|
-
message: `Enum '${enumName}' has duplicate value '${
|
|
131
|
+
message: `Enum '${enumName}' has duplicate value '${finalName}' after conversion (from '${originals.join("' and '")}')`,
|
|
119
132
|
severity: "error",
|
|
120
133
|
location: enumLocation,
|
|
121
134
|
});
|
|
@@ -139,9 +152,10 @@ function convertFields(
|
|
|
139
152
|
const diagnostics: Diagnostic[] = [];
|
|
140
153
|
|
|
141
154
|
for (const field of extracted.fields) {
|
|
142
|
-
const eligibility =
|
|
143
|
-
|
|
144
|
-
:
|
|
155
|
+
const eligibility = isEligibleField({
|
|
156
|
+
fieldName: field.name,
|
|
157
|
+
kind: isInput ? "input" : "object",
|
|
158
|
+
});
|
|
145
159
|
|
|
146
160
|
if (!eligibility.eligible) {
|
|
147
161
|
diagnostics.push({
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import ts from "typescript";
|
|
2
|
+
import {
|
|
3
|
+
detectBrandedType,
|
|
4
|
+
detectUniformBrandedType,
|
|
5
|
+
} from "../../shared/branded-type-detector.js";
|
|
2
6
|
import { isInternalTypeSymbol } from "../../shared/constants.js";
|
|
3
7
|
import { extractInlineObjectProperties as extractInlineObjectPropertiesShared } from "../../shared/inline-object-extractor.js";
|
|
4
8
|
import { isInlineObjectType } from "../../shared/inline-object-utils.js";
|
|
@@ -175,6 +179,20 @@ function resolveFieldTypeInternal(
|
|
|
175
179
|
});
|
|
176
180
|
}
|
|
177
181
|
|
|
182
|
+
// Check if all non-null types are branded primitives with the same base type
|
|
183
|
+
// This handles cases like: boolean & { __nominal: true }
|
|
184
|
+
// which expands to: (true & { __nominal: true }) | (false & { __nominal: true })
|
|
185
|
+
const uniformBrandedResult = detectUniformBrandedType(nonNullTypes);
|
|
186
|
+
if (
|
|
187
|
+
uniformBrandedResult.isBranded &&
|
|
188
|
+
uniformBrandedResult.baseType !== null
|
|
189
|
+
) {
|
|
190
|
+
return createPrimitiveType({
|
|
191
|
+
name: uniformBrandedResult.baseType,
|
|
192
|
+
nullable,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
|
|
178
196
|
if (nonNullTypes.length === 1) {
|
|
179
197
|
const nonNullTypeNode =
|
|
180
198
|
typeNode && ts.isUnionTypeNode(typeNode)
|
|
@@ -235,18 +253,45 @@ function resolveFieldTypeInternal(
|
|
|
235
253
|
return createLiteralType(typeString);
|
|
236
254
|
}
|
|
237
255
|
|
|
238
|
-
// Intersection types in field context
|
|
239
|
-
// GraphQL doesn't have intersection types, so we must
|
|
256
|
+
// Intersection types in field context
|
|
257
|
+
// GraphQL doesn't have intersection types, so we must resolve them appropriately
|
|
240
258
|
if (type.isIntersection()) {
|
|
241
|
-
// If the intersection has an alias that's in knownTypeNames, use it
|
|
259
|
+
// 1. If the intersection has an alias that's in knownTypeNames, use it as reference
|
|
242
260
|
if (type.aliasSymbol) {
|
|
243
261
|
const aliasName = type.aliasSymbol.getName();
|
|
244
262
|
if (isKnownSchemaType(aliasName, type.aliasSymbol, ctx)) {
|
|
245
263
|
return createReferenceType({ name: aliasName, nullable: false });
|
|
246
264
|
}
|
|
265
|
+
|
|
266
|
+
// 2. Check if aliasSymbol has a globalTypeMapping (custom scalar)
|
|
267
|
+
const globalMapping = globalTypeMappings.find(
|
|
268
|
+
(m) => m.typeName === aliasName,
|
|
269
|
+
);
|
|
270
|
+
if (globalMapping) {
|
|
271
|
+
return createScalarType({
|
|
272
|
+
name: globalMapping.scalarName,
|
|
273
|
+
scalarInfo: {
|
|
274
|
+
scalarName: globalMapping.scalarName,
|
|
275
|
+
typeName: globalMapping.typeName,
|
|
276
|
+
baseType: undefined,
|
|
277
|
+
isCustom: true,
|
|
278
|
+
only: globalMapping.only,
|
|
279
|
+
},
|
|
280
|
+
nullable: false,
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// 3. Check if this is a branded primitive type pattern
|
|
286
|
+
const brandedResult = detectBrandedType(type);
|
|
287
|
+
if (brandedResult.isBranded && brandedResult.baseType !== null) {
|
|
288
|
+
return createPrimitiveType({
|
|
289
|
+
name: brandedResult.baseType,
|
|
290
|
+
nullable: false,
|
|
291
|
+
});
|
|
247
292
|
}
|
|
248
293
|
|
|
249
|
-
// Otherwise, treat as inline object
|
|
294
|
+
// 4. Otherwise, treat as inline object
|
|
250
295
|
return tryExtractAsInlineObject(type, ctx);
|
|
251
296
|
}
|
|
252
297
|
|
|
@@ -287,6 +332,28 @@ function resolveFieldTypeInternal(
|
|
|
287
332
|
}
|
|
288
333
|
}
|
|
289
334
|
|
|
335
|
+
// Type alias expansion: type aliases not in knownTypeNames should be expanded as inline objects
|
|
336
|
+
// This handles cases like: type MyPayload = { user: User; success: boolean; }
|
|
337
|
+
// where MyPayload is used as return type but not declared as a schema type
|
|
338
|
+
// Only expand if the underlying type is an anonymous object literal, not a named type
|
|
339
|
+
// IMPORTANT: Only expand if the name doesn't exist in schema at all.
|
|
340
|
+
// If the name exists but symbols don't match, that's a shadowing case handled by later logic.
|
|
341
|
+
if (type.aliasSymbol) {
|
|
342
|
+
const aliasName = type.aliasSymbol.getName();
|
|
343
|
+
if (!knownTypeNames.has(aliasName)) {
|
|
344
|
+
// Check if this is an anonymous object type (not an interface or another named type)
|
|
345
|
+
// using ts.ObjectFlags.Anonymous for a more robust check than internal symbol names
|
|
346
|
+
const isAnonymousObject =
|
|
347
|
+
(type.flags & ts.TypeFlags.Object) !== 0 &&
|
|
348
|
+
((type as ts.ObjectType).objectFlags & ts.ObjectFlags.Anonymous) !== 0;
|
|
349
|
+
|
|
350
|
+
if (isAnonymousObject) {
|
|
351
|
+
// Not a known schema type and is an anonymous object - expand to generate Payload type
|
|
352
|
+
return tryExtractAsInlineObject(type, ctx);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
290
357
|
// Extract type name from typeNode first (takes precedence over type.symbol).
|
|
291
358
|
// This handles cases like:
|
|
292
359
|
// - `typeof def` where the type's symbol is internal (__type, __object)
|
|
@@ -406,7 +473,7 @@ function tryExtractAsInlineObject(
|
|
|
406
473
|
type: ts.Type,
|
|
407
474
|
ctx: InternalFieldTypeContext,
|
|
408
475
|
): TSTypeReference {
|
|
409
|
-
const { visitedTypes } = ctx;
|
|
476
|
+
const { visitedTypes, checker } = ctx;
|
|
410
477
|
if (visitedTypes.has(type)) {
|
|
411
478
|
// Cycle detected, return a placeholder reference
|
|
412
479
|
const typeName = type.symbol?.getName() ?? "Unknown";
|
|
@@ -417,11 +484,34 @@ function tryExtractAsInlineObject(
|
|
|
417
484
|
|
|
418
485
|
const inlineProperties = extractInlineObjectPropertiesShared(
|
|
419
486
|
type,
|
|
420
|
-
|
|
487
|
+
checker,
|
|
421
488
|
(propType) => resolveFieldTypeInternal(propType, undefined, ctx),
|
|
422
489
|
);
|
|
423
490
|
|
|
424
|
-
|
|
491
|
+
// Extract type-level TSDoc from the alias symbol if present (Requirement 7.2)
|
|
492
|
+
// Only extract from user-defined types, not built-in TypeScript utility types
|
|
493
|
+
let description: string | null = null;
|
|
494
|
+
let deprecated: DeprecationInfo | null = null;
|
|
495
|
+
if (type.aliasSymbol) {
|
|
496
|
+
const declarations = type.aliasSymbol.getDeclarations();
|
|
497
|
+
const isUserDefined =
|
|
498
|
+
declarations?.some((decl) => {
|
|
499
|
+
const sourceFile = decl.getSourceFile();
|
|
500
|
+
return !sourceFile.isDeclarationFile;
|
|
501
|
+
}) ?? false;
|
|
502
|
+
|
|
503
|
+
if (isUserDefined) {
|
|
504
|
+
const tsdocInfo = extractTsDocFromSymbol(type.aliasSymbol, checker);
|
|
505
|
+
description = tsdocInfo.description;
|
|
506
|
+
deprecated = tsdocInfo.deprecated;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
return createInlineObjectType({
|
|
511
|
+
properties: inlineProperties,
|
|
512
|
+
description,
|
|
513
|
+
deprecated,
|
|
514
|
+
});
|
|
425
515
|
}
|
|
426
516
|
|
|
427
517
|
/**
|
|
@@ -9,6 +9,8 @@ import {
|
|
|
9
9
|
hasDirectiveMetadata,
|
|
10
10
|
unwrapDirectiveType,
|
|
11
11
|
} from "../../shared/directive-detector.js";
|
|
12
|
+
import { detectIgnoreFieldsMetadata } from "../../shared/ignore-fields-detector.js";
|
|
13
|
+
import { validateIgnoreFields } from "../../shared/ignore-fields-validator.js";
|
|
12
14
|
import { extractInlineObjectProperties as extractInlineObjectPropertiesShared } from "../../shared/inline-object-extractor.js";
|
|
13
15
|
import { isInlineObjectType } from "../../shared/inline-object-utils.js";
|
|
14
16
|
import {
|
|
@@ -157,7 +159,11 @@ function tryExtractAsInlineObject(
|
|
|
157
159
|
(t) => convertTsTypeToReference(t, ctx).tsType,
|
|
158
160
|
);
|
|
159
161
|
return {
|
|
160
|
-
tsType: createInlineObjectType(
|
|
162
|
+
tsType: createInlineObjectType({
|
|
163
|
+
properties: inlineProperties,
|
|
164
|
+
description: null,
|
|
165
|
+
deprecated: null,
|
|
166
|
+
}),
|
|
161
167
|
};
|
|
162
168
|
}
|
|
163
169
|
|
|
@@ -404,6 +410,21 @@ interface FieldExtractionResult {
|
|
|
404
410
|
diagnostics: Diagnostic[];
|
|
405
411
|
}
|
|
406
412
|
|
|
413
|
+
function collectAllFieldNames(
|
|
414
|
+
type: ts.Type,
|
|
415
|
+
checker: ts.TypeChecker,
|
|
416
|
+
): ReadonlySet<string> {
|
|
417
|
+
const properties = extractPropertySymbols(type, checker);
|
|
418
|
+
const fieldNames = new Set<string>();
|
|
419
|
+
for (const prop of properties) {
|
|
420
|
+
const propName = prop.getName();
|
|
421
|
+
if (!propName.startsWith(" $")) {
|
|
422
|
+
fieldNames.add(propName);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
return fieldNames;
|
|
426
|
+
}
|
|
427
|
+
|
|
407
428
|
interface ExtractFieldsParams {
|
|
408
429
|
readonly type: ts.Type;
|
|
409
430
|
readonly checker: ts.TypeChecker;
|
|
@@ -414,6 +435,7 @@ interface ExtractFieldsParams {
|
|
|
414
435
|
readonly sourceFiles: ReadonlySet<string>;
|
|
415
436
|
readonly scalarMappingTable: ScalarBaseTypeMappingTable | null;
|
|
416
437
|
readonly scalarMappingContext: ScalarMappingContext;
|
|
438
|
+
readonly ignoreFields: ReadonlySet<string> | null;
|
|
417
439
|
}
|
|
418
440
|
|
|
419
441
|
function extractFieldsFromType(
|
|
@@ -429,6 +451,7 @@ function extractFieldsFromType(
|
|
|
429
451
|
sourceFiles,
|
|
430
452
|
scalarMappingTable,
|
|
431
453
|
scalarMappingContext,
|
|
454
|
+
ignoreFields,
|
|
432
455
|
} = params;
|
|
433
456
|
const fields: FieldDefinition[] = [];
|
|
434
457
|
const diagnostics: Diagnostic[] = [];
|
|
@@ -441,6 +464,10 @@ function extractFieldsFromType(
|
|
|
441
464
|
continue;
|
|
442
465
|
}
|
|
443
466
|
|
|
467
|
+
if (ignoreFields?.has(propName)) {
|
|
468
|
+
continue;
|
|
469
|
+
}
|
|
470
|
+
|
|
444
471
|
const propType = checker.getTypeOfSymbol(prop);
|
|
445
472
|
const declarations = prop.getDeclarations();
|
|
446
473
|
const declaration = declarations?.[0];
|
|
@@ -945,6 +972,19 @@ function processReexportedSymbol(
|
|
|
945
972
|
? reexportDeclaration.type
|
|
946
973
|
: undefined;
|
|
947
974
|
const unionMembers = extractUnionMembers(type, reexportTypeNode);
|
|
975
|
+
const ignoreFields = detectIgnoreFieldsMetadata({ type, checker });
|
|
976
|
+
|
|
977
|
+
if (ignoreFields !== null && kind !== "union") {
|
|
978
|
+
const allFieldNames = collectAllFieldNames(type, checker);
|
|
979
|
+
const validationDiagnostics = validateIgnoreFields({
|
|
980
|
+
typeName: exportedName,
|
|
981
|
+
ignoreFields,
|
|
982
|
+
allFieldNames,
|
|
983
|
+
sourceLocation: location,
|
|
984
|
+
});
|
|
985
|
+
diagnostics.push(...validationDiagnostics);
|
|
986
|
+
}
|
|
987
|
+
|
|
948
988
|
const fieldResult =
|
|
949
989
|
kind === "union"
|
|
950
990
|
? { fields: [], diagnostics: [] }
|
|
@@ -958,6 +998,7 @@ function processReexportedSymbol(
|
|
|
958
998
|
sourceFiles: scannedSourceFiles,
|
|
959
999
|
scalarMappingTable,
|
|
960
1000
|
scalarMappingContext,
|
|
1001
|
+
ignoreFields,
|
|
961
1002
|
});
|
|
962
1003
|
diagnostics.push(...fieldResult.diagnostics);
|
|
963
1004
|
|
|
@@ -1130,17 +1171,23 @@ interface ExtractInlineObjectMembersParams {
|
|
|
1130
1171
|
readonly checker: ts.TypeChecker;
|
|
1131
1172
|
readonly globalTypeMappings: ReadonlyArray<GlobalTypeMapping>;
|
|
1132
1173
|
readonly knownTypeNames: ReadonlySet<string>;
|
|
1174
|
+
readonly typeNode: ts.TypeNode | undefined;
|
|
1133
1175
|
}
|
|
1134
1176
|
|
|
1135
1177
|
function extractInlineObjectMembers(
|
|
1136
1178
|
params: ExtractInlineObjectMembersParams,
|
|
1137
1179
|
): InlineObjectExtractionResult | null {
|
|
1138
|
-
const { type, checker, globalTypeMappings, knownTypeNames } =
|
|
1180
|
+
const { type, checker, globalTypeMappings, knownTypeNames, typeNode } =
|
|
1181
|
+
params;
|
|
1139
1182
|
if (!type.isUnion()) {
|
|
1140
1183
|
return null;
|
|
1141
1184
|
}
|
|
1142
1185
|
|
|
1143
1186
|
const nonNullTypes = getNonNullableTypes(type);
|
|
1187
|
+
const memberTypeNodes =
|
|
1188
|
+
typeNode && ts.isUnionTypeNode(typeNode)
|
|
1189
|
+
? filterNonNullTypeNodes(typeNode)
|
|
1190
|
+
: [];
|
|
1144
1191
|
|
|
1145
1192
|
const allObjectTypes = nonNullTypes.every(
|
|
1146
1193
|
(t) =>
|
|
@@ -1163,28 +1210,45 @@ function extractInlineObjectMembers(
|
|
|
1163
1210
|
visitedTypes: new WeakSet(),
|
|
1164
1211
|
};
|
|
1165
1212
|
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1213
|
+
if (memberTypeNodes.length > 0) {
|
|
1214
|
+
for (const memberNode of memberTypeNodes) {
|
|
1215
|
+
if (ts.isTypeReferenceNode(memberNode)) {
|
|
1216
|
+
hasNamedTypes = true;
|
|
1217
|
+
} else {
|
|
1218
|
+
hasInlineObjects = true;
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
} else {
|
|
1222
|
+
for (const memberType of nonNullTypes) {
|
|
1223
|
+
if (isAnonymousObjectType(memberType)) {
|
|
1224
|
+
hasInlineObjects = true;
|
|
1225
|
+
} else {
|
|
1226
|
+
hasNamedTypes = true;
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
if (hasInlineObjects) {
|
|
1232
|
+
for (const memberType of nonNullTypes) {
|
|
1233
|
+
if (isAnonymousObjectType(memberType)) {
|
|
1234
|
+
const properties = memberType.getProperties();
|
|
1235
|
+
const memberProperties: InlineObjectProperty[] = [];
|
|
1171
1236
|
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1237
|
+
for (const prop of properties) {
|
|
1238
|
+
const propType = checker.getTypeOfSymbol(prop);
|
|
1239
|
+
const tsdocInfo = extractTsDocFromSymbol(prop, checker);
|
|
1240
|
+
const typeResult = convertTsTypeToReference(propType, ctx);
|
|
1176
1241
|
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1242
|
+
memberProperties.push({
|
|
1243
|
+
propertyName: prop.getName(),
|
|
1244
|
+
propertyType: typeResult.tsType,
|
|
1245
|
+
description: tsdocInfo.description ?? null,
|
|
1246
|
+
deprecated: tsdocInfo.deprecated ?? null,
|
|
1247
|
+
});
|
|
1248
|
+
}
|
|
1184
1249
|
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
hasNamedTypes = true;
|
|
1250
|
+
members.push({ properties: memberProperties });
|
|
1251
|
+
}
|
|
1188
1252
|
}
|
|
1189
1253
|
}
|
|
1190
1254
|
|
|
@@ -1415,6 +1479,7 @@ export function extractTypesFromProgram(
|
|
|
1415
1479
|
checker,
|
|
1416
1480
|
globalTypeMappings,
|
|
1417
1481
|
knownTypeNames,
|
|
1482
|
+
typeNode: typeAliasTypeNode,
|
|
1418
1483
|
});
|
|
1419
1484
|
const tsdocInfo = extractTsDocInfo(node, checker);
|
|
1420
1485
|
|
|
@@ -1468,6 +1533,19 @@ export function extractTypesFromProgram(
|
|
|
1468
1533
|
return;
|
|
1469
1534
|
}
|
|
1470
1535
|
|
|
1536
|
+
const ignoreFields = detectIgnoreFieldsMetadata({ type, checker });
|
|
1537
|
+
|
|
1538
|
+
if (ignoreFields !== null && kind !== "union") {
|
|
1539
|
+
const allFieldNames = collectAllFieldNames(type, checker);
|
|
1540
|
+
const validationDiagnostics = validateIgnoreFields({
|
|
1541
|
+
typeName: name,
|
|
1542
|
+
ignoreFields,
|
|
1543
|
+
allFieldNames,
|
|
1544
|
+
sourceLocation: typeSourceLocation,
|
|
1545
|
+
});
|
|
1546
|
+
diagnostics.push(...validationDiagnostics);
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1471
1549
|
const fieldResult =
|
|
1472
1550
|
kind === "union"
|
|
1473
1551
|
? { fields: [], diagnostics: [] }
|
|
@@ -1483,6 +1561,7 @@ export function extractTypesFromProgram(
|
|
|
1483
1561
|
scalarMappingContext: name.endsWith("Input")
|
|
1484
1562
|
? "input"
|
|
1485
1563
|
: "output",
|
|
1564
|
+
ignoreFields,
|
|
1486
1565
|
});
|
|
1487
1566
|
const fields = fieldResult.fields;
|
|
1488
1567
|
diagnostics.push(...fieldResult.diagnostics);
|
|
@@ -1517,11 +1596,9 @@ export function extractTypesFromProgram(
|
|
|
1517
1596
|
}
|
|
1518
1597
|
}
|
|
1519
1598
|
|
|
1520
|
-
const inlineObjectMembers =
|
|
1521
|
-
inlineObjectResult
|
|
1522
|
-
|
|
1523
|
-
? inlineObjectResult.members
|
|
1524
|
-
: null;
|
|
1599
|
+
const inlineObjectMembers = inlineObjectResult?.hasInlineObjects
|
|
1600
|
+
? inlineObjectResult.members
|
|
1601
|
+
: null;
|
|
1525
1602
|
|
|
1526
1603
|
const typeInfo: ExtractedTypeInfo = {
|
|
1527
1604
|
metadata,
|