@gqlkit-ts/cli 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/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 +640 -133
- 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/gen-orchestrator/orchestrator.d.ts.map +1 -1
- package/dist/gen-orchestrator/orchestrator.js +13 -6
- 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 +14 -61
- 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/emitter/code-emitter.d.ts.map +1 -1
- package/dist/schema-generator/emitter/code-emitter.js +20 -0
- package/dist/schema-generator/emitter/code-emitter.js.map +1 -1
- package/dist/schema-generator/generate-schema.d.ts +1 -0
- package/dist/schema-generator/generate-schema.d.ts.map +1 -1
- package/dist/schema-generator/generate-schema.js +72 -3
- package/dist/schema-generator/generate-schema.js.map +1 -1
- package/dist/schema-generator/integrator/result-integrator.d.ts +14 -2
- package/dist/schema-generator/integrator/result-integrator.d.ts.map +1 -1
- package/dist/schema-generator/integrator/result-integrator.js +54 -1
- 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/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/type-extractor/converter/graphql-converter.d.ts.map +1 -1
- package/dist/type-extractor/converter/graphql-converter.js +21 -7
- package/dist/type-extractor/converter/graphql-converter.js.map +1 -1
- package/dist/type-extractor/extractor/field-type-resolver.js +42 -3
- 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/docs/coding-agents.md +64 -0
- package/docs/configuration.md +6 -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 +946 -201
- 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/gen-orchestrator/orchestrator.ts +20 -6
- package/src/resolver-extractor/extract-resolvers.ts +19 -0
- package/src/resolver-extractor/extractor/define-api-extractor.ts +23 -89
- package/src/resolver-extractor/index.ts +0 -6
- package/src/resolver-extractor/validator/abstract-resolver-validator.ts +16 -8
- package/src/schema-generator/emitter/code-emitter.ts +34 -0
- package/src/schema-generator/generate-schema.ts +99 -2
- package/src/schema-generator/integrator/result-integrator.ts +70 -1
- package/src/schema-generator/resolver-collector/resolver-collector.ts +34 -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/type-extractor/converter/graphql-converter.ts +31 -7
- package/src/type-extractor/extractor/field-type-resolver.ts +48 -3
- package/src/type-extractor/extractor/type-extractor.ts +103 -26
- package/src/type-extractor/types/diagnostics.ts +12 -2
- package/src/type-extractor/types/ts-type-reference-factory.ts +18 -5
- package/src/type-extractor/types/typescript.ts +4 -0
- 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,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts an enum name from any naming convention to UPPER_SNAKE_CASE.
|
|
3
|
+
*
|
|
4
|
+
* Supports PascalCase, camelCase, UPPER_SNAKE_CASE, and single word inputs.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* toUpperSnakeCase("UserStatus") // => "USER_STATUS"
|
|
8
|
+
* toUpperSnakeCase("userStatus") // => "USER_STATUS"
|
|
9
|
+
* toUpperSnakeCase("USER_STATUS") // => "USER_STATUS"
|
|
10
|
+
* toUpperSnakeCase("Status") // => "STATUS"
|
|
11
|
+
*/
|
|
12
|
+
export function toUpperSnakeCase(name: string): string {
|
|
13
|
+
return name
|
|
14
|
+
.replace(/([a-z])([A-Z])/g, "$1_$2")
|
|
15
|
+
.replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2")
|
|
16
|
+
.toUpperCase();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Builds the prefix candidate string for enum prefix stripping.
|
|
21
|
+
*
|
|
22
|
+
* Converts the enum name to UPPER_SNAKE_CASE and appends "_" to create
|
|
23
|
+
* the prefix that will be checked against all enum values.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* buildEnumPrefixCandidate("UserStatus") // => "USER_STATUS_"
|
|
27
|
+
* buildEnumPrefixCandidate("userStatus") // => "USER_STATUS_"
|
|
28
|
+
* buildEnumPrefixCandidate("USER_STATUS") // => "USER_STATUS_"
|
|
29
|
+
* buildEnumPrefixCandidate("Status") // => "STATUS_"
|
|
30
|
+
*/
|
|
31
|
+
export function buildEnumPrefixCandidate(enumName: string): string {
|
|
32
|
+
return `${toUpperSnakeCase(enumName)}_`;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface DetectEnumPrefixParams {
|
|
36
|
+
readonly enumName: string;
|
|
37
|
+
readonly memberValues: ReadonlyArray<string>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface DetectEnumPrefixResult {
|
|
41
|
+
readonly shouldStrip: boolean;
|
|
42
|
+
readonly prefix: string | null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Detects whether an enum is a candidate for prefix stripping.
|
|
47
|
+
*
|
|
48
|
+
* Conditions for stripping:
|
|
49
|
+
* 1. All memberValues must start with `${toUpperSnakeCase(enumName)}_`
|
|
50
|
+
* 2. After removing the prefix, the remaining string must be non-empty
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* detectEnumPrefix({
|
|
54
|
+
* enumName: "UserStatus",
|
|
55
|
+
* memberValues: ["USER_STATUS_ACTIVE", "USER_STATUS_INACTIVE"]
|
|
56
|
+
* })
|
|
57
|
+
* // => { shouldStrip: true, prefix: "USER_STATUS_" }
|
|
58
|
+
*
|
|
59
|
+
* detectEnumPrefix({
|
|
60
|
+
* enumName: "UserStatus",
|
|
61
|
+
* memberValues: ["ACTIVE", "INACTIVE"]
|
|
62
|
+
* })
|
|
63
|
+
* // => { shouldStrip: false, prefix: null }
|
|
64
|
+
*/
|
|
65
|
+
export function detectEnumPrefix(
|
|
66
|
+
params: DetectEnumPrefixParams,
|
|
67
|
+
): DetectEnumPrefixResult {
|
|
68
|
+
const { enumName, memberValues } = params;
|
|
69
|
+
|
|
70
|
+
if (memberValues.length === 0) {
|
|
71
|
+
return { shouldStrip: false, prefix: null };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const prefixCandidate = buildEnumPrefixCandidate(enumName);
|
|
75
|
+
|
|
76
|
+
for (const value of memberValues) {
|
|
77
|
+
if (!value.startsWith(prefixCandidate)) {
|
|
78
|
+
return { shouldStrip: false, prefix: null };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const stripped = value.slice(prefixCandidate.length);
|
|
82
|
+
if (stripped === "") {
|
|
83
|
+
return { shouldStrip: false, prefix: null };
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return { shouldStrip: true, prefix: prefixCandidate };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Removes the detected prefix from an enum value.
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* stripEnumPrefix("USER_STATUS_ACTIVE", "USER_STATUS_")
|
|
95
|
+
* // => "ACTIVE"
|
|
96
|
+
*/
|
|
97
|
+
export function stripEnumPrefix(value: string, prefix: string): string {
|
|
98
|
+
return value.slice(prefix.length);
|
|
99
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IgnoreFields metadata detector.
|
|
3
|
+
*
|
|
4
|
+
* This module provides functions to detect ignoreFields metadata embedded
|
|
5
|
+
* in TypeScript intersection types using the $gqlkitTypeMeta property.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import ts from "typescript";
|
|
9
|
+
import { METADATA_PROPERTIES } from "./constants.js";
|
|
10
|
+
import { getActualMetadataType } from "./metadata-detector.js";
|
|
11
|
+
|
|
12
|
+
const TYPE_META_PROPERTY = METADATA_PROPERTIES.TYPE_META;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Parameters for detectIgnoreFieldsMetadata function.
|
|
16
|
+
*/
|
|
17
|
+
export interface DetectIgnoreFieldsParams {
|
|
18
|
+
readonly type: ts.Type;
|
|
19
|
+
readonly checker: ts.TypeChecker;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Extracts ignoreFields from a type's metadata.
|
|
24
|
+
* Returns null if the type doesn't have $gqlkitTypeMeta or ignoreFields is not specified.
|
|
25
|
+
*/
|
|
26
|
+
function extractIgnoreFieldsFromType(
|
|
27
|
+
type: ts.Type,
|
|
28
|
+
checker: ts.TypeChecker,
|
|
29
|
+
): ReadonlySet<string> | null {
|
|
30
|
+
const metaProp = type.getProperty(TYPE_META_PROPERTY);
|
|
31
|
+
if (!metaProp) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const rawMetadataType = checker.getTypeOfSymbol(metaProp);
|
|
36
|
+
const metadataType = getActualMetadataType(rawMetadataType);
|
|
37
|
+
if (!metadataType) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const ignoreFieldsProp = metadataType.getProperty("ignoreFields");
|
|
42
|
+
if (!ignoreFieldsProp) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const rawIgnoreFieldsType = checker.getTypeOfSymbol(ignoreFieldsProp);
|
|
47
|
+
const ignoreFieldsType = getActualMetadataType(rawIgnoreFieldsType);
|
|
48
|
+
if (!ignoreFieldsType) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return extractStringLiteralUnion(ignoreFieldsType);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Extracts string literals from a type (single literal or union of literals).
|
|
57
|
+
*/
|
|
58
|
+
function extractStringLiteralUnion(type: ts.Type): ReadonlySet<string> | null {
|
|
59
|
+
if (type.flags & ts.TypeFlags.StringLiteral) {
|
|
60
|
+
const value = (type as ts.StringLiteralType).value;
|
|
61
|
+
return new Set([value]);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (type.isUnion()) {
|
|
65
|
+
const values = new Set<string>();
|
|
66
|
+
for (const member of type.types) {
|
|
67
|
+
if (member.flags & ts.TypeFlags.StringLiteral) {
|
|
68
|
+
values.add((member as ts.StringLiteralType).value);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (values.size > 0) {
|
|
72
|
+
return values;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Detects ignoreFields metadata from a TypeScript type.
|
|
81
|
+
*
|
|
82
|
+
* This function analyzes TypeScript types to detect ignoreFields metadata
|
|
83
|
+
* from the $gqlkitTypeMeta property. It extracts string literal or string
|
|
84
|
+
* literal union types and returns them as a Set.
|
|
85
|
+
*
|
|
86
|
+
* @param params - The detection parameters containing type and checker
|
|
87
|
+
* @returns The ignoreFields set or null if not specified
|
|
88
|
+
*/
|
|
89
|
+
export function detectIgnoreFieldsMetadata(
|
|
90
|
+
params: DetectIgnoreFieldsParams,
|
|
91
|
+
): ReadonlySet<string> | null {
|
|
92
|
+
const { type, checker } = params;
|
|
93
|
+
|
|
94
|
+
const result = extractIgnoreFieldsFromType(type, checker);
|
|
95
|
+
if (result) {
|
|
96
|
+
return result;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (type.isIntersection()) {
|
|
100
|
+
for (const member of type.types) {
|
|
101
|
+
const memberResult = extractIgnoreFieldsFromType(member, checker);
|
|
102
|
+
if (memberResult) {
|
|
103
|
+
return memberResult;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
@@ -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
|
+
}
|
|
@@ -3,6 +3,10 @@ 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";
|
|
6
10
|
import { convertTsTypeToGraphQLType } from "../../shared/type-converter.js";
|
|
7
11
|
import type {
|
|
8
12
|
Diagnostic,
|
|
@@ -60,6 +64,11 @@ interface ConvertEnumMembersResult {
|
|
|
60
64
|
readonly hasError: boolean;
|
|
61
65
|
}
|
|
62
66
|
|
|
67
|
+
interface ConvertedMemberInfo {
|
|
68
|
+
readonly convertedName: string;
|
|
69
|
+
readonly member: EnumMemberInfo;
|
|
70
|
+
}
|
|
71
|
+
|
|
63
72
|
function convertEnumMembers(
|
|
64
73
|
params: ConvertEnumMembersParams,
|
|
65
74
|
): ConvertEnumMembersResult {
|
|
@@ -69,7 +78,7 @@ function convertEnumMembers(
|
|
|
69
78
|
let isNumeric = false;
|
|
70
79
|
let needsMapping = false;
|
|
71
80
|
|
|
72
|
-
const
|
|
81
|
+
const eligibleMembers: ConvertedMemberInfo[] = [];
|
|
73
82
|
|
|
74
83
|
for (const member of members) {
|
|
75
84
|
const convertedName = toScreamingSnakeCase(member.name);
|
|
@@ -93,16 +102,31 @@ function convertEnumMembers(
|
|
|
93
102
|
isNumeric = true;
|
|
94
103
|
}
|
|
95
104
|
|
|
96
|
-
|
|
105
|
+
eligibleMembers.push({ convertedName, member });
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const prefixDetectionResult = detectEnumPrefix({
|
|
109
|
+
enumName,
|
|
110
|
+
memberValues: eligibleMembers.map((m) => m.convertedName),
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
const finalNameToOriginals = new Map<string, string[]>();
|
|
114
|
+
|
|
115
|
+
for (const { convertedName, member } of eligibleMembers) {
|
|
116
|
+
let finalName = convertedName;
|
|
117
|
+
if (prefixDetectionResult.shouldStrip && prefixDetectionResult.prefix) {
|
|
118
|
+
finalName = stripEnumPrefix(convertedName, prefixDetectionResult.prefix);
|
|
119
|
+
needsMapping = true;
|
|
120
|
+
} else if (convertedName !== member.value) {
|
|
97
121
|
needsMapping = true;
|
|
98
122
|
}
|
|
99
123
|
|
|
100
|
-
const existingOriginals =
|
|
124
|
+
const existingOriginals = finalNameToOriginals.get(finalName) ?? [];
|
|
101
125
|
existingOriginals.push(member.value);
|
|
102
|
-
|
|
126
|
+
finalNameToOriginals.set(finalName, existingOriginals);
|
|
103
127
|
|
|
104
128
|
values.push({
|
|
105
|
-
name:
|
|
129
|
+
name: finalName,
|
|
106
130
|
originalValue: member.value,
|
|
107
131
|
numericValue: member.numericValue,
|
|
108
132
|
description: member.description,
|
|
@@ -111,11 +135,11 @@ function convertEnumMembers(
|
|
|
111
135
|
}
|
|
112
136
|
|
|
113
137
|
let hasError = false;
|
|
114
|
-
for (const [
|
|
138
|
+
for (const [finalName, originals] of finalNameToOriginals) {
|
|
115
139
|
if (originals.length > 1) {
|
|
116
140
|
diagnostics.push({
|
|
117
141
|
code: "DUPLICATE_ENUM_VALUE_AFTER_CONVERSION",
|
|
118
|
-
message: `Enum '${enumName}' has duplicate value '${
|
|
142
|
+
message: `Enum '${enumName}' has duplicate value '${finalName}' after conversion (from '${originals.join("' and '")}')`,
|
|
119
143
|
severity: "error",
|
|
120
144
|
location: enumLocation,
|
|
121
145
|
});
|
|
@@ -287,6 +287,28 @@ function resolveFieldTypeInternal(
|
|
|
287
287
|
}
|
|
288
288
|
}
|
|
289
289
|
|
|
290
|
+
// Type alias expansion: type aliases not in knownTypeNames should be expanded as inline objects
|
|
291
|
+
// This handles cases like: type MyPayload = { user: User; success: boolean; }
|
|
292
|
+
// where MyPayload is used as return type but not declared as a schema type
|
|
293
|
+
// Only expand if the underlying type is an anonymous object literal, not a named type
|
|
294
|
+
// IMPORTANT: Only expand if the name doesn't exist in schema at all.
|
|
295
|
+
// If the name exists but symbols don't match, that's a shadowing case handled by later logic.
|
|
296
|
+
if (type.aliasSymbol) {
|
|
297
|
+
const aliasName = type.aliasSymbol.getName();
|
|
298
|
+
if (!knownTypeNames.has(aliasName)) {
|
|
299
|
+
// Check if this is an anonymous object type (not an interface or another named type)
|
|
300
|
+
// using ts.ObjectFlags.Anonymous for a more robust check than internal symbol names
|
|
301
|
+
const isAnonymousObject =
|
|
302
|
+
(type.flags & ts.TypeFlags.Object) !== 0 &&
|
|
303
|
+
((type as ts.ObjectType).objectFlags & ts.ObjectFlags.Anonymous) !== 0;
|
|
304
|
+
|
|
305
|
+
if (isAnonymousObject) {
|
|
306
|
+
// Not a known schema type and is an anonymous object - expand to generate Payload type
|
|
307
|
+
return tryExtractAsInlineObject(type, ctx);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
290
312
|
// Extract type name from typeNode first (takes precedence over type.symbol).
|
|
291
313
|
// This handles cases like:
|
|
292
314
|
// - `typeof def` where the type's symbol is internal (__type, __object)
|
|
@@ -406,7 +428,7 @@ function tryExtractAsInlineObject(
|
|
|
406
428
|
type: ts.Type,
|
|
407
429
|
ctx: InternalFieldTypeContext,
|
|
408
430
|
): TSTypeReference {
|
|
409
|
-
const { visitedTypes } = ctx;
|
|
431
|
+
const { visitedTypes, checker } = ctx;
|
|
410
432
|
if (visitedTypes.has(type)) {
|
|
411
433
|
// Cycle detected, return a placeholder reference
|
|
412
434
|
const typeName = type.symbol?.getName() ?? "Unknown";
|
|
@@ -417,11 +439,34 @@ function tryExtractAsInlineObject(
|
|
|
417
439
|
|
|
418
440
|
const inlineProperties = extractInlineObjectPropertiesShared(
|
|
419
441
|
type,
|
|
420
|
-
|
|
442
|
+
checker,
|
|
421
443
|
(propType) => resolveFieldTypeInternal(propType, undefined, ctx),
|
|
422
444
|
);
|
|
423
445
|
|
|
424
|
-
|
|
446
|
+
// Extract type-level TSDoc from the alias symbol if present (Requirement 7.2)
|
|
447
|
+
// Only extract from user-defined types, not built-in TypeScript utility types
|
|
448
|
+
let description: string | null = null;
|
|
449
|
+
let deprecated: DeprecationInfo | null = null;
|
|
450
|
+
if (type.aliasSymbol) {
|
|
451
|
+
const declarations = type.aliasSymbol.getDeclarations();
|
|
452
|
+
const isUserDefined =
|
|
453
|
+
declarations?.some((decl) => {
|
|
454
|
+
const sourceFile = decl.getSourceFile();
|
|
455
|
+
return !sourceFile.isDeclarationFile;
|
|
456
|
+
}) ?? false;
|
|
457
|
+
|
|
458
|
+
if (isUserDefined) {
|
|
459
|
+
const tsdocInfo = extractTsDocFromSymbol(type.aliasSymbol, checker);
|
|
460
|
+
description = tsdocInfo.description;
|
|
461
|
+
deprecated = tsdocInfo.deprecated;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
return createInlineObjectType({
|
|
466
|
+
properties: inlineProperties,
|
|
467
|
+
description,
|
|
468
|
+
deprecated,
|
|
469
|
+
});
|
|
425
470
|
}
|
|
426
471
|
|
|
427
472
|
/**
|
|
@@ -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,
|