@gqlkit-ts/cli 0.0.1 → 0.2.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/LICENSE +21 -0
- package/dist/auto-type-generator/auto-type-generator.d.ts +62 -0
- package/dist/auto-type-generator/auto-type-generator.d.ts.map +1 -0
- package/dist/auto-type-generator/auto-type-generator.js +540 -0
- package/dist/auto-type-generator/auto-type-generator.js.map +1 -0
- package/dist/auto-type-generator/index.d.ts +4 -0
- package/dist/auto-type-generator/index.d.ts.map +1 -0
- package/dist/auto-type-generator/index.js +3 -0
- package/dist/auto-type-generator/index.js.map +1 -0
- package/dist/auto-type-generator/inline-enum-collector.d.ts +31 -0
- package/dist/auto-type-generator/inline-enum-collector.d.ts.map +1 -0
- package/dist/auto-type-generator/inline-enum-collector.js +157 -0
- package/dist/auto-type-generator/inline-enum-collector.js.map +1 -0
- package/dist/auto-type-generator/name-collision-validator.d.ts +17 -0
- package/dist/auto-type-generator/name-collision-validator.d.ts.map +1 -0
- package/dist/auto-type-generator/name-collision-validator.js +68 -0
- package/dist/auto-type-generator/name-collision-validator.js.map +1 -0
- package/dist/auto-type-generator/naming-convention.d.ts +44 -0
- package/dist/auto-type-generator/naming-convention.d.ts.map +1 -0
- package/dist/auto-type-generator/naming-convention.js +67 -0
- package/dist/auto-type-generator/naming-convention.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +11 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/gen.d.ts +32 -0
- package/dist/commands/gen.d.ts.map +1 -0
- package/dist/commands/gen.js +101 -0
- package/dist/commands/gen.js.map +1 -0
- package/dist/commands/main.d.ts +12 -0
- package/dist/commands/main.d.ts.map +1 -0
- package/dist/commands/main.js +5 -0
- package/dist/commands/main.js.map +1 -0
- package/dist/config/define-config.d.ts +26 -0
- package/dist/config/define-config.d.ts.map +1 -0
- package/dist/config/define-config.js +27 -0
- package/dist/config/define-config.js.map +1 -0
- package/dist/config/index.d.ts +3 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +2 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/types.d.ts +131 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +2 -0
- package/dist/config/types.js.map +1 -0
- package/dist/config-loader/index.d.ts +3 -0
- package/dist/config-loader/index.d.ts.map +1 -0
- package/dist/config-loader/index.js +2 -0
- package/dist/config-loader/index.js.map +1 -0
- package/dist/config-loader/loader.d.ts +50 -0
- package/dist/config-loader/loader.d.ts.map +1 -0
- package/dist/config-loader/loader.js +78 -0
- package/dist/config-loader/loader.js.map +1 -0
- package/dist/config-loader/validator.d.ts +13 -0
- package/dist/config-loader/validator.d.ts.map +1 -0
- package/dist/config-loader/validator.js +497 -0
- package/dist/config-loader/validator.js.map +1 -0
- package/dist/gen-orchestrator/hook-executor/hook-executor.d.ts +25 -0
- package/dist/gen-orchestrator/hook-executor/hook-executor.d.ts.map +1 -0
- package/dist/gen-orchestrator/hook-executor/hook-executor.js +68 -0
- package/dist/gen-orchestrator/hook-executor/hook-executor.js.map +1 -0
- package/dist/gen-orchestrator/orchestrator.d.ts +30 -0
- package/dist/gen-orchestrator/orchestrator.d.ts.map +1 -0
- package/dist/gen-orchestrator/orchestrator.js +505 -0
- package/dist/gen-orchestrator/orchestrator.js.map +1 -0
- package/dist/gen-orchestrator/reporter/diagnostic-reporter.d.ts +9 -0
- package/dist/gen-orchestrator/reporter/diagnostic-reporter.d.ts.map +1 -0
- package/dist/gen-orchestrator/reporter/diagnostic-reporter.js +32 -0
- package/dist/gen-orchestrator/reporter/diagnostic-reporter.js.map +1 -0
- package/dist/gen-orchestrator/reporter/progress-reporter.d.ts +19 -0
- package/dist/gen-orchestrator/reporter/progress-reporter.d.ts.map +1 -0
- package/dist/gen-orchestrator/reporter/progress-reporter.js +38 -0
- package/dist/gen-orchestrator/reporter/progress-reporter.js.map +1 -0
- package/dist/gen-orchestrator/writer/file-writer.d.ts +13 -0
- package/dist/gen-orchestrator/writer/file-writer.d.ts.map +1 -0
- package/dist/gen-orchestrator/writer/file-writer.js +22 -0
- package/dist/gen-orchestrator/writer/file-writer.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/resolver-extractor/extract-resolvers.d.ts +49 -0
- package/dist/resolver-extractor/extract-resolvers.d.ts.map +1 -0
- package/dist/resolver-extractor/extract-resolvers.js +2 -0
- package/dist/resolver-extractor/extract-resolvers.js.map +1 -0
- package/dist/resolver-extractor/extractor/define-api-extractor.d.ts +60 -0
- package/dist/resolver-extractor/extractor/define-api-extractor.d.ts.map +1 -0
- package/dist/resolver-extractor/extractor/define-api-extractor.js +509 -0
- package/dist/resolver-extractor/extractor/define-api-extractor.js.map +1 -0
- package/dist/resolver-extractor/index.d.ts +5 -0
- package/dist/resolver-extractor/index.d.ts.map +1 -0
- package/dist/resolver-extractor/index.js +2 -0
- package/dist/resolver-extractor/index.js.map +1 -0
- package/dist/resolver-extractor/validator/abstract-resolver-validator.d.ts +25 -0
- package/dist/resolver-extractor/validator/abstract-resolver-validator.d.ts.map +1 -0
- package/dist/resolver-extractor/validator/abstract-resolver-validator.js +172 -0
- package/dist/resolver-extractor/validator/abstract-resolver-validator.js.map +1 -0
- package/dist/resolver-extractor/validator/only-validator.d.ts +61 -0
- package/dist/resolver-extractor/validator/only-validator.d.ts.map +1 -0
- package/dist/resolver-extractor/validator/only-validator.js +76 -0
- package/dist/resolver-extractor/validator/only-validator.js.map +1 -0
- package/dist/schema-generator/builder/ast-builder.d.ts +7 -0
- package/dist/schema-generator/builder/ast-builder.d.ts.map +1 -0
- package/dist/schema-generator/builder/ast-builder.js +417 -0
- package/dist/schema-generator/builder/ast-builder.js.map +1 -0
- package/dist/schema-generator/emitter/code-emitter.d.ts +15 -0
- package/dist/schema-generator/emitter/code-emitter.d.ts.map +1 -0
- package/dist/schema-generator/emitter/code-emitter.js +216 -0
- package/dist/schema-generator/emitter/code-emitter.js.map +1 -0
- package/dist/schema-generator/emitter/sdl-emitter.d.ts +7 -0
- package/dist/schema-generator/emitter/sdl-emitter.d.ts.map +1 -0
- package/dist/schema-generator/emitter/sdl-emitter.js +11 -0
- package/dist/schema-generator/emitter/sdl-emitter.js.map +1 -0
- package/dist/schema-generator/generate-schema.d.ts +26 -0
- package/dist/schema-generator/generate-schema.d.ts.map +1 -0
- package/dist/schema-generator/generate-schema.js +93 -0
- package/dist/schema-generator/generate-schema.js.map +1 -0
- package/dist/schema-generator/index.d.ts +4 -0
- package/dist/schema-generator/index.d.ts.map +1 -0
- package/dist/schema-generator/index.js +2 -0
- package/dist/schema-generator/index.js.map +1 -0
- package/dist/schema-generator/integrator/result-integrator.d.ts +113 -0
- package/dist/schema-generator/integrator/result-integrator.d.ts.map +1 -0
- package/dist/schema-generator/integrator/result-integrator.js +438 -0
- package/dist/schema-generator/integrator/result-integrator.js.map +1 -0
- package/dist/schema-generator/pruner/schema-pruner.d.ts +16 -0
- package/dist/schema-generator/pruner/schema-pruner.d.ts.map +1 -0
- package/dist/schema-generator/pruner/schema-pruner.js +66 -0
- package/dist/schema-generator/pruner/schema-pruner.js.map +1 -0
- package/dist/schema-generator/resolver-collector/resolver-collector.d.ts +24 -0
- package/dist/schema-generator/resolver-collector/resolver-collector.d.ts.map +1 -0
- package/dist/schema-generator/resolver-collector/resolver-collector.js +61 -0
- package/dist/schema-generator/resolver-collector/resolver-collector.js.map +1 -0
- package/dist/shared/constants.d.ts +54 -0
- package/dist/shared/constants.d.ts.map +1 -0
- package/dist/shared/constants.js +109 -0
- package/dist/shared/constants.js.map +1 -0
- package/dist/shared/default-value-detector.d.ts +40 -0
- package/dist/shared/default-value-detector.d.ts.map +1 -0
- package/dist/shared/default-value-detector.js +124 -0
- package/dist/shared/default-value-detector.js.map +1 -0
- package/dist/shared/diagnostics.d.ts +4 -0
- package/dist/shared/diagnostics.d.ts.map +1 -0
- package/dist/shared/diagnostics.js +25 -0
- package/dist/shared/diagnostics.js.map +1 -0
- package/dist/shared/directive-definition-extractor.d.ts +64 -0
- package/dist/shared/directive-definition-extractor.d.ts.map +1 -0
- package/dist/shared/directive-definition-extractor.js +399 -0
- package/dist/shared/directive-definition-extractor.js.map +1 -0
- package/dist/shared/directive-detector.d.ts +102 -0
- package/dist/shared/directive-detector.d.ts.map +1 -0
- package/dist/shared/directive-detector.js +415 -0
- package/dist/shared/directive-detector.js.map +1 -0
- package/dist/shared/file-scanner.d.ts +25 -0
- package/dist/shared/file-scanner.d.ts.map +1 -0
- package/dist/shared/file-scanner.js +101 -0
- package/dist/shared/file-scanner.js.map +1 -0
- package/dist/shared/index.d.ts +10 -0
- package/dist/shared/index.d.ts.map +1 -0
- package/dist/shared/index.js +6 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/shared/inline-object-extractor.d.ts +13 -0
- package/dist/shared/inline-object-extractor.d.ts.map +1 -0
- package/dist/shared/inline-object-extractor.js +65 -0
- package/dist/shared/inline-object-extractor.js.map +1 -0
- package/dist/shared/inline-object-utils.d.ts +7 -0
- package/dist/shared/inline-object-utils.d.ts.map +1 -0
- package/dist/shared/inline-object-utils.js +23 -0
- package/dist/shared/inline-object-utils.js.map +1 -0
- package/dist/shared/interface-detector.d.ts +23 -0
- package/dist/shared/interface-detector.d.ts.map +1 -0
- package/dist/shared/interface-detector.js +133 -0
- package/dist/shared/interface-detector.js.map +1 -0
- package/dist/shared/interface-validator.d.ts +9 -0
- package/dist/shared/interface-validator.d.ts.map +1 -0
- package/dist/shared/interface-validator.js +152 -0
- package/dist/shared/interface-validator.js.map +1 -0
- package/dist/shared/metadata-detector.d.ts +65 -0
- package/dist/shared/metadata-detector.d.ts.map +1 -0
- package/dist/shared/metadata-detector.js +333 -0
- package/dist/shared/metadata-detector.js.map +1 -0
- package/dist/shared/path-utils.d.ts +2 -0
- package/dist/shared/path-utils.d.ts.map +1 -0
- package/dist/shared/path-utils.js +4 -0
- package/dist/shared/path-utils.js.map +1 -0
- package/dist/shared/program-factory.d.ts +14 -0
- package/dist/shared/program-factory.d.ts.map +1 -0
- package/dist/shared/program-factory.js +29 -0
- package/dist/shared/program-factory.js.map +1 -0
- package/dist/shared/source-location.d.ts +11 -0
- package/dist/shared/source-location.d.ts.map +1 -0
- package/dist/shared/source-location.js +15 -0
- package/dist/shared/source-location.js.map +1 -0
- package/dist/shared/tsconfig-loader.d.ts +13 -0
- package/dist/shared/tsconfig-loader.d.ts.map +1 -0
- package/dist/shared/tsconfig-loader.js +90 -0
- package/dist/shared/tsconfig-loader.js.map +1 -0
- package/dist/shared/tsdoc-parser.d.ts +12 -0
- package/dist/shared/tsdoc-parser.d.ts.map +1 -0
- package/dist/shared/tsdoc-parser.js +101 -0
- package/dist/shared/tsdoc-parser.js.map +1 -0
- package/dist/shared/type-converter.d.ts +3 -0
- package/dist/shared/type-converter.d.ts.map +1 -0
- package/dist/shared/type-converter.js +83 -0
- package/dist/shared/type-converter.js.map +1 -0
- package/dist/shared/typescript-utils.d.ts +82 -0
- package/dist/shared/typescript-utils.d.ts.map +1 -0
- package/dist/shared/typescript-utils.js +197 -0
- package/dist/shared/typescript-utils.js.map +1 -0
- package/dist/type-extractor/collector/result-collector.d.ts +7 -0
- package/dist/type-extractor/collector/result-collector.d.ts.map +1 -0
- package/dist/type-extractor/collector/result-collector.js +35 -0
- package/dist/type-extractor/collector/result-collector.js.map +1 -0
- package/dist/type-extractor/collector/scalar-collector.d.ts +108 -0
- package/dist/type-extractor/collector/scalar-collector.d.ts.map +1 -0
- package/dist/type-extractor/collector/scalar-collector.js +123 -0
- package/dist/type-extractor/collector/scalar-collector.js.map +1 -0
- package/dist/type-extractor/converter/field-eligibility.d.ts +34 -0
- package/dist/type-extractor/converter/field-eligibility.d.ts.map +1 -0
- package/dist/type-extractor/converter/field-eligibility.js +89 -0
- package/dist/type-extractor/converter/field-eligibility.js.map +1 -0
- package/dist/type-extractor/converter/graphql-converter.d.ts +7 -0
- package/dist/type-extractor/converter/graphql-converter.d.ts.map +1 -0
- package/dist/type-extractor/converter/graphql-converter.js +338 -0
- package/dist/type-extractor/converter/graphql-converter.js.map +1 -0
- package/dist/type-extractor/extract-types.d.ts +2 -0
- package/dist/type-extractor/extract-types.d.ts.map +1 -0
- package/dist/type-extractor/extract-types.js +2 -0
- package/dist/type-extractor/extract-types.js.map +1 -0
- package/dist/type-extractor/extractor/field-type-resolver.d.ts +28 -0
- package/dist/type-extractor/extractor/field-type-resolver.d.ts.map +1 -0
- package/dist/type-extractor/extractor/field-type-resolver.js +394 -0
- package/dist/type-extractor/extractor/field-type-resolver.js.map +1 -0
- package/dist/type-extractor/extractor/type-extractor.d.ts +36 -0
- package/dist/type-extractor/extractor/type-extractor.d.ts.map +1 -0
- package/dist/type-extractor/extractor/type-extractor.js +1082 -0
- package/dist/type-extractor/extractor/type-extractor.js.map +1 -0
- package/dist/type-extractor/extractor/type-name-collector.d.ts +24 -0
- package/dist/type-extractor/extractor/type-name-collector.d.ts.map +1 -0
- package/dist/type-extractor/extractor/type-name-collector.js +102 -0
- package/dist/type-extractor/extractor/type-name-collector.js.map +1 -0
- package/dist/type-extractor/index.d.ts +4 -0
- package/dist/type-extractor/index.d.ts.map +1 -0
- package/dist/type-extractor/index.js +2 -0
- package/dist/type-extractor/index.js.map +1 -0
- package/dist/type-extractor/mapper/scalar-base-type-mapper.d.ts +89 -0
- package/dist/type-extractor/mapper/scalar-base-type-mapper.d.ts.map +1 -0
- package/dist/type-extractor/mapper/scalar-base-type-mapper.js +158 -0
- package/dist/type-extractor/mapper/scalar-base-type-mapper.js.map +1 -0
- package/dist/type-extractor/types/diagnostics.d.ts +17 -0
- package/dist/type-extractor/types/diagnostics.d.ts.map +1 -0
- package/dist/type-extractor/types/diagnostics.js +2 -0
- package/dist/type-extractor/types/diagnostics.js.map +1 -0
- package/dist/type-extractor/types/graphql.d.ts +42 -0
- package/dist/type-extractor/types/graphql.d.ts.map +1 -0
- package/dist/type-extractor/types/graphql.js +2 -0
- package/dist/type-extractor/types/graphql.js.map +1 -0
- package/dist/type-extractor/types/index.d.ts +6 -0
- package/dist/type-extractor/types/index.d.ts.map +1 -0
- package/dist/type-extractor/types/index.js +2 -0
- package/dist/type-extractor/types/index.js.map +1 -0
- package/dist/type-extractor/types/ts-type-reference-factory.d.ts +39 -0
- package/dist/type-extractor/types/ts-type-reference-factory.d.ts.map +1 -0
- package/dist/type-extractor/types/ts-type-reference-factory.js +69 -0
- package/dist/type-extractor/types/ts-type-reference-factory.js.map +1 -0
- package/dist/type-extractor/types/typescript.d.ts +106 -0
- package/dist/type-extractor/types/typescript.d.ts.map +1 -0
- package/dist/type-extractor/types/typescript.js +2 -0
- package/dist/type-extractor/types/typescript.js.map +1 -0
- package/dist/type-extractor/validator/type-validator.d.ts +11 -0
- package/dist/type-extractor/validator/type-validator.d.ts.map +1 -0
- package/dist/type-extractor/validator/type-validator.js +53 -0
- package/dist/type-extractor/validator/type-validator.js.map +1 -0
- package/docs/configuration.md +163 -0
- package/docs/getting-started.md +117 -0
- package/docs/index.md +33 -0
- package/docs/integration/apollo.md +109 -0
- package/docs/integration/drizzle.md +191 -0
- package/docs/integration/yoga.md +108 -0
- package/docs/schema/abstract-resolvers.md +146 -0
- package/docs/schema/directives.md +196 -0
- package/docs/schema/documentation.md +176 -0
- package/docs/schema/enums.md +370 -0
- package/docs/schema/fields.md +186 -0
- package/docs/schema/index.md +38 -0
- package/docs/schema/inputs.md +279 -0
- package/docs/schema/interfaces.md +178 -0
- package/docs/schema/objects.md +188 -0
- package/docs/schema/queries-mutations.md +207 -0
- package/docs/schema/scalars.md +194 -0
- package/docs/schema/unions.md +90 -0
- package/docs/what-is-gqlkit.md +22 -0
- package/package.json +66 -7
- package/src/auto-type-generator/auto-type-generator.ts +925 -0
- package/src/auto-type-generator/index.ts +21 -0
- package/src/auto-type-generator/inline-enum-collector.ts +290 -0
- package/src/auto-type-generator/name-collision-validator.ts +119 -0
- package/src/auto-type-generator/naming-convention.ts +126 -0
- package/src/cli.ts +11 -0
- package/src/commands/gen.ts +141 -0
- package/src/commands/main.ts +5 -0
- package/src/config/define-config.ts +28 -0
- package/src/config/index.ts +7 -0
- package/src/config/types.ts +144 -0
- package/src/config-loader/index.ts +14 -0
- package/src/config-loader/loader.ts +143 -0
- package/src/config-loader/validator.ts +672 -0
- package/src/gen-orchestrator/hook-executor/hook-executor.ts +117 -0
- package/src/gen-orchestrator/orchestrator.ts +784 -0
- package/src/gen-orchestrator/reporter/diagnostic-reporter.ts +44 -0
- package/src/gen-orchestrator/reporter/progress-reporter.ts +61 -0
- package/src/gen-orchestrator/writer/file-writer.ts +38 -0
- package/src/index.ts +2 -0
- package/src/resolver-extractor/extract-resolvers.ts +63 -0
- package/src/resolver-extractor/extractor/define-api-extractor.ts +806 -0
- package/src/resolver-extractor/index.ts +19 -0
- package/src/resolver-extractor/validator/abstract-resolver-validator.ts +251 -0
- package/src/resolver-extractor/validator/only-validator.ts +158 -0
- package/src/schema-generator/builder/ast-builder.ts +706 -0
- package/src/schema-generator/emitter/code-emitter.ts +351 -0
- package/src/schema-generator/emitter/sdl-emitter.ts +13 -0
- package/src/schema-generator/generate-schema.ts +170 -0
- package/src/schema-generator/index.ts +19 -0
- package/src/schema-generator/integrator/result-integrator.ts +690 -0
- package/src/schema-generator/pruner/schema-pruner.ts +112 -0
- package/src/schema-generator/resolver-collector/resolver-collector.ts +123 -0
- package/src/shared/constants.ts +122 -0
- package/src/shared/default-value-detector.ts +172 -0
- package/src/shared/diagnostics.ts +35 -0
- package/src/shared/directive-definition-extractor.ts +564 -0
- package/src/shared/directive-detector.ts +556 -0
- package/src/shared/file-scanner.ts +170 -0
- package/src/shared/index.ts +32 -0
- package/src/shared/inline-object-extractor.ts +102 -0
- package/src/shared/inline-object-utils.ts +23 -0
- package/src/shared/interface-detector.ts +176 -0
- package/src/shared/interface-validator.ts +211 -0
- package/src/shared/metadata-detector.ts +443 -0
- package/src/shared/path-utils.ts +3 -0
- package/src/shared/program-factory.ts +51 -0
- package/src/shared/source-location.ts +27 -0
- package/src/shared/tsconfig-loader.ts +126 -0
- package/src/shared/tsdoc-parser.ts +155 -0
- package/src/shared/type-converter.ts +99 -0
- package/src/shared/typescript-utils.ts +246 -0
- package/src/type-extractor/collector/result-collector.ts +57 -0
- package/src/type-extractor/collector/scalar-collector.ts +254 -0
- package/src/type-extractor/converter/field-eligibility.ts +112 -0
- package/src/type-extractor/converter/graphql-converter.ts +459 -0
- package/src/type-extractor/extract-types.ts +1 -0
- package/src/type-extractor/extractor/field-type-resolver.ts +569 -0
- package/src/type-extractor/extractor/type-extractor.ts +1567 -0
- package/src/type-extractor/extractor/type-name-collector.ts +130 -0
- package/src/type-extractor/index.ts +20 -0
- package/src/type-extractor/mapper/scalar-base-type-mapper.ts +265 -0
- package/src/type-extractor/types/diagnostics.ts +99 -0
- package/src/type-extractor/types/graphql.ts +55 -0
- package/src/type-extractor/types/index.ts +37 -0
- package/src/type-extractor/types/ts-type-reference-factory.ts +137 -0
- package/src/type-extractor/types/typescript.ts +133 -0
- package/src/type-extractor/validator/type-validator.ts +77 -0
- package/README.md +0 -45
|
@@ -0,0 +1,925 @@
|
|
|
1
|
+
import type ts from "typescript";
|
|
2
|
+
import type {
|
|
3
|
+
ExtractResolversResult,
|
|
4
|
+
GraphQLFieldDefinition,
|
|
5
|
+
} from "../resolver-extractor/index.js";
|
|
6
|
+
import type {
|
|
7
|
+
DirectiveArgumentValue,
|
|
8
|
+
DirectiveInfo,
|
|
9
|
+
} from "../shared/directive-detector.js";
|
|
10
|
+
import type { DeprecationInfo } from "../shared/tsdoc-parser.js";
|
|
11
|
+
import { convertTsTypeToGraphQLType } from "../shared/type-converter.js";
|
|
12
|
+
import {
|
|
13
|
+
isEligibleAsInputObjectField,
|
|
14
|
+
isEligibleAsObjectField,
|
|
15
|
+
} from "../type-extractor/converter/field-eligibility.js";
|
|
16
|
+
import {
|
|
17
|
+
createReferenceType,
|
|
18
|
+
type Diagnostic,
|
|
19
|
+
type ExtractedTypeInfo,
|
|
20
|
+
type FieldDefinition,
|
|
21
|
+
type GraphQLFieldType,
|
|
22
|
+
type InlineEnumMemberInfo,
|
|
23
|
+
type InlineObjectPropertyDef,
|
|
24
|
+
type SourceLocation,
|
|
25
|
+
} from "../type-extractor/types/index.js";
|
|
26
|
+
import {
|
|
27
|
+
collectInlineEnumsFromResolvers,
|
|
28
|
+
collectInlineEnumsFromTypes,
|
|
29
|
+
type InlineEnumWithContext,
|
|
30
|
+
} from "./inline-enum-collector.js";
|
|
31
|
+
import {
|
|
32
|
+
type AutoTypeNameContext,
|
|
33
|
+
buildFieldContext,
|
|
34
|
+
generateAutoTypeName,
|
|
35
|
+
} from "./naming-convention.js";
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Information about where an auto-generated type was generated from.
|
|
39
|
+
*/
|
|
40
|
+
export interface GeneratedFromInfo {
|
|
41
|
+
readonly parentTypeName: string | null;
|
|
42
|
+
readonly fieldPath: ReadonlyArray<string>;
|
|
43
|
+
readonly context: "typeField" | "inputField" | "resolverArg";
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Field information for auto-generated types.
|
|
48
|
+
*/
|
|
49
|
+
export interface AutoGeneratedField {
|
|
50
|
+
readonly name: string;
|
|
51
|
+
readonly type: GraphQLFieldType;
|
|
52
|
+
readonly description: string | null;
|
|
53
|
+
readonly deprecated: DeprecationInfo | null;
|
|
54
|
+
readonly directives: ReadonlyArray<DirectiveInfo> | null;
|
|
55
|
+
readonly defaultValue: DirectiveArgumentValue | null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Enum value information for auto-generated enum types.
|
|
60
|
+
*/
|
|
61
|
+
export interface AutoGeneratedEnumValue {
|
|
62
|
+
/** GraphQL enum value name (SCREAMING_SNAKE_CASE) */
|
|
63
|
+
readonly name: string;
|
|
64
|
+
/** Original TypeScript value */
|
|
65
|
+
readonly originalValue: string;
|
|
66
|
+
readonly description: string | null;
|
|
67
|
+
readonly deprecated: DeprecationInfo | null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Auto-generated type information.
|
|
72
|
+
*/
|
|
73
|
+
export interface AutoGeneratedType {
|
|
74
|
+
readonly name: string;
|
|
75
|
+
readonly kind: "Object" | "InputObject" | "Enum";
|
|
76
|
+
/** Fields for Object/InputObject kinds (null for Enum) */
|
|
77
|
+
readonly fields: ReadonlyArray<AutoGeneratedField> | null;
|
|
78
|
+
/** Enum values for Enum kind (null for Object/InputObject) */
|
|
79
|
+
readonly enumValues: ReadonlyArray<AutoGeneratedEnumValue> | null;
|
|
80
|
+
/** True if enum needs value mapping (at least one value converted) */
|
|
81
|
+
readonly needsStringEnumMapping: boolean;
|
|
82
|
+
readonly sourceLocation: SourceLocation;
|
|
83
|
+
readonly generatedFrom: GeneratedFromInfo;
|
|
84
|
+
readonly description: string | null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export interface AutoTypeGeneratorInput {
|
|
88
|
+
readonly extractedTypes: ReadonlyArray<ExtractedTypeInfo>;
|
|
89
|
+
readonly resolversResult: ExtractResolversResult;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface AutoTypeGeneratorResult {
|
|
93
|
+
readonly autoGeneratedTypes: ReadonlyArray<AutoGeneratedType>;
|
|
94
|
+
readonly updatedExtractedTypes: ReadonlyArray<ExtractedTypeInfo>;
|
|
95
|
+
readonly updatedResolversResult: ExtractResolversResult;
|
|
96
|
+
readonly diagnostics: ReadonlyArray<Diagnostic>;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
interface InlineObjectWithContext {
|
|
100
|
+
readonly properties: ReadonlyArray<InlineObjectPropertyDef>;
|
|
101
|
+
readonly context: AutoTypeNameContext;
|
|
102
|
+
readonly sourceLocation: SourceLocation;
|
|
103
|
+
readonly nullable: boolean;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function isInputTypeName(name: string): boolean {
|
|
107
|
+
return name.endsWith("Input");
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function getContextKey(context: AutoTypeNameContext): string {
|
|
111
|
+
switch (context.kind) {
|
|
112
|
+
case "objectField":
|
|
113
|
+
return `objectField:${context.parentTypeName}:${context.fieldPath.join(".")}`;
|
|
114
|
+
case "inputField":
|
|
115
|
+
return `inputField:${context.parentTypeName}:${context.fieldPath.join(".")}`;
|
|
116
|
+
case "resolverArg":
|
|
117
|
+
return `resolverArg:${context.resolverType}:${context.parentTypeName ?? ""}:${context.fieldName}:${context.argName}:${context.fieldPath.join(".")}`;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function mapContextKindToGeneratedFromContext(
|
|
122
|
+
kind: AutoTypeNameContext["kind"],
|
|
123
|
+
): GeneratedFromInfo["context"] {
|
|
124
|
+
switch (kind) {
|
|
125
|
+
case "objectField":
|
|
126
|
+
return "typeField";
|
|
127
|
+
case "inputField":
|
|
128
|
+
return "inputField";
|
|
129
|
+
case "resolverArg":
|
|
130
|
+
return "resolverArg";
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function buildGeneratedFromInfo(
|
|
135
|
+
context: AutoTypeNameContext,
|
|
136
|
+
): GeneratedFromInfo {
|
|
137
|
+
const fieldPath =
|
|
138
|
+
context.kind === "resolverArg" && context.fieldPath.length === 0
|
|
139
|
+
? [context.argName]
|
|
140
|
+
: context.fieldPath;
|
|
141
|
+
|
|
142
|
+
return {
|
|
143
|
+
parentTypeName: context.parentTypeName,
|
|
144
|
+
fieldPath,
|
|
145
|
+
context: mapContextKindToGeneratedFromContext(context.kind),
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function collectInlineObjectsFromType(
|
|
150
|
+
typeInfo: ExtractedTypeInfo,
|
|
151
|
+
): InlineObjectWithContext[] {
|
|
152
|
+
const results: InlineObjectWithContext[] = [];
|
|
153
|
+
const isInput = isInputTypeName(typeInfo.metadata.name);
|
|
154
|
+
|
|
155
|
+
for (const field of typeInfo.fields) {
|
|
156
|
+
collectInlineObjectsFromField(
|
|
157
|
+
field,
|
|
158
|
+
typeInfo.metadata.name,
|
|
159
|
+
[],
|
|
160
|
+
isInput,
|
|
161
|
+
typeInfo.metadata.sourceFile,
|
|
162
|
+
results,
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return results;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function collectInlineObjectsFromField(
|
|
170
|
+
field: FieldDefinition,
|
|
171
|
+
parentTypeName: string,
|
|
172
|
+
parentPath: ReadonlyArray<string>,
|
|
173
|
+
isInput: boolean,
|
|
174
|
+
sourceFile: string,
|
|
175
|
+
results: InlineObjectWithContext[],
|
|
176
|
+
): void {
|
|
177
|
+
const tsType = field.tsType;
|
|
178
|
+
|
|
179
|
+
if (tsType.kind !== "inlineObject" || !tsType.inlineObjectProperties) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const fieldPath = [...parentPath, field.name];
|
|
184
|
+
|
|
185
|
+
const context: AutoTypeNameContext = isInput
|
|
186
|
+
? {
|
|
187
|
+
kind: "inputField",
|
|
188
|
+
parentTypeName,
|
|
189
|
+
fieldPath,
|
|
190
|
+
}
|
|
191
|
+
: {
|
|
192
|
+
kind: "objectField",
|
|
193
|
+
parentTypeName,
|
|
194
|
+
fieldPath,
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
results.push({
|
|
198
|
+
properties: tsType.inlineObjectProperties,
|
|
199
|
+
context,
|
|
200
|
+
sourceLocation: field.sourceLocation ?? {
|
|
201
|
+
file: sourceFile,
|
|
202
|
+
line: 1,
|
|
203
|
+
column: 1,
|
|
204
|
+
},
|
|
205
|
+
nullable: tsType.nullable,
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
for (const prop of tsType.inlineObjectProperties) {
|
|
209
|
+
if (
|
|
210
|
+
prop.tsType.kind === "inlineObject" &&
|
|
211
|
+
prop.tsType.inlineObjectProperties
|
|
212
|
+
) {
|
|
213
|
+
const nestedPath = [...fieldPath, prop.name];
|
|
214
|
+
const nestedContext: AutoTypeNameContext = isInput
|
|
215
|
+
? {
|
|
216
|
+
kind: "inputField",
|
|
217
|
+
parentTypeName,
|
|
218
|
+
fieldPath: nestedPath,
|
|
219
|
+
}
|
|
220
|
+
: {
|
|
221
|
+
kind: "objectField",
|
|
222
|
+
parentTypeName,
|
|
223
|
+
fieldPath: nestedPath,
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
extractNestedInlineObjects(
|
|
227
|
+
prop.tsType.inlineObjectProperties,
|
|
228
|
+
nestedContext,
|
|
229
|
+
nestedPath,
|
|
230
|
+
parentTypeName,
|
|
231
|
+
isInput,
|
|
232
|
+
sourceFile,
|
|
233
|
+
prop.sourceLocation,
|
|
234
|
+
results,
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function extractNestedInlineObjects(
|
|
241
|
+
properties: ReadonlyArray<InlineObjectPropertyDef>,
|
|
242
|
+
context: AutoTypeNameContext,
|
|
243
|
+
currentPath: ReadonlyArray<string>,
|
|
244
|
+
parentTypeName: string,
|
|
245
|
+
isInput: boolean,
|
|
246
|
+
sourceFile: string,
|
|
247
|
+
parentSourceLocation: SourceLocation | null,
|
|
248
|
+
results: InlineObjectWithContext[],
|
|
249
|
+
): void {
|
|
250
|
+
results.push({
|
|
251
|
+
properties,
|
|
252
|
+
context,
|
|
253
|
+
sourceLocation: parentSourceLocation ?? {
|
|
254
|
+
file: sourceFile,
|
|
255
|
+
line: 1,
|
|
256
|
+
column: 1,
|
|
257
|
+
},
|
|
258
|
+
nullable: false,
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
for (const prop of properties) {
|
|
262
|
+
if (
|
|
263
|
+
prop.tsType.kind === "inlineObject" &&
|
|
264
|
+
prop.tsType.inlineObjectProperties
|
|
265
|
+
) {
|
|
266
|
+
const nestedPath = [...currentPath, prop.name];
|
|
267
|
+
const nestedContext: AutoTypeNameContext = isInput
|
|
268
|
+
? {
|
|
269
|
+
kind: "inputField",
|
|
270
|
+
parentTypeName,
|
|
271
|
+
fieldPath: nestedPath,
|
|
272
|
+
}
|
|
273
|
+
: {
|
|
274
|
+
kind: "objectField",
|
|
275
|
+
parentTypeName,
|
|
276
|
+
fieldPath: nestedPath,
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
extractNestedInlineObjects(
|
|
280
|
+
prop.tsType.inlineObjectProperties,
|
|
281
|
+
nestedContext,
|
|
282
|
+
nestedPath,
|
|
283
|
+
parentTypeName,
|
|
284
|
+
isInput,
|
|
285
|
+
sourceFile,
|
|
286
|
+
prop.sourceLocation,
|
|
287
|
+
results,
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
function collectInlineObjectsFromResolvers(
|
|
294
|
+
resolversResult: ExtractResolversResult,
|
|
295
|
+
): InlineObjectWithContext[] {
|
|
296
|
+
const results: InlineObjectWithContext[] = [];
|
|
297
|
+
|
|
298
|
+
for (const field of resolversResult.queryFields.fields) {
|
|
299
|
+
collectInlineObjectsFromResolverArgs(field, "query", null, results);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
for (const field of resolversResult.mutationFields.fields) {
|
|
303
|
+
collectInlineObjectsFromResolverArgs(field, "mutation", null, results);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
for (const ext of resolversResult.typeExtensions) {
|
|
307
|
+
for (const field of ext.fields) {
|
|
308
|
+
collectInlineObjectsFromResolverArgs(
|
|
309
|
+
field,
|
|
310
|
+
"field",
|
|
311
|
+
ext.targetTypeName,
|
|
312
|
+
results,
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
return results;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
function collectInlineObjectsFromResolverArgs(
|
|
321
|
+
field: GraphQLFieldDefinition,
|
|
322
|
+
resolverType: "query" | "mutation" | "field",
|
|
323
|
+
parentTypeName: string | null,
|
|
324
|
+
results: InlineObjectWithContext[],
|
|
325
|
+
): void {
|
|
326
|
+
if (!field.args) return;
|
|
327
|
+
|
|
328
|
+
for (const arg of field.args) {
|
|
329
|
+
if (!arg.inlineObjectProperties) continue;
|
|
330
|
+
|
|
331
|
+
const context: AutoTypeNameContext = {
|
|
332
|
+
kind: "resolverArg",
|
|
333
|
+
resolverType,
|
|
334
|
+
fieldName: field.name,
|
|
335
|
+
argName: arg.name,
|
|
336
|
+
parentTypeName,
|
|
337
|
+
fieldPath: [],
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
results.push({
|
|
341
|
+
properties: arg.inlineObjectProperties,
|
|
342
|
+
context,
|
|
343
|
+
sourceLocation: field.sourceLocation,
|
|
344
|
+
nullable: arg.type.nullable,
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
extractNestedInlineObjectsFromArg(
|
|
348
|
+
arg.inlineObjectProperties,
|
|
349
|
+
resolverType,
|
|
350
|
+
field.name,
|
|
351
|
+
arg.name,
|
|
352
|
+
parentTypeName,
|
|
353
|
+
[],
|
|
354
|
+
field.sourceLocation,
|
|
355
|
+
results,
|
|
356
|
+
);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
function extractNestedInlineObjectsFromArg(
|
|
361
|
+
properties: ReadonlyArray<InlineObjectPropertyDef>,
|
|
362
|
+
resolverType: "query" | "mutation" | "field",
|
|
363
|
+
fieldName: string,
|
|
364
|
+
argName: string,
|
|
365
|
+
parentTypeName: string | null,
|
|
366
|
+
currentPath: ReadonlyArray<string>,
|
|
367
|
+
sourceLocation: SourceLocation,
|
|
368
|
+
results: InlineObjectWithContext[],
|
|
369
|
+
): void {
|
|
370
|
+
for (const prop of properties) {
|
|
371
|
+
if (
|
|
372
|
+
prop.tsType.kind === "inlineObject" &&
|
|
373
|
+
prop.tsType.inlineObjectProperties
|
|
374
|
+
) {
|
|
375
|
+
const nestedPath = [...currentPath, prop.name];
|
|
376
|
+
const nestedContext: AutoTypeNameContext = {
|
|
377
|
+
kind: "resolverArg",
|
|
378
|
+
resolverType,
|
|
379
|
+
fieldName,
|
|
380
|
+
argName,
|
|
381
|
+
parentTypeName,
|
|
382
|
+
fieldPath: nestedPath,
|
|
383
|
+
};
|
|
384
|
+
|
|
385
|
+
results.push({
|
|
386
|
+
properties: prop.tsType.inlineObjectProperties,
|
|
387
|
+
context: nestedContext,
|
|
388
|
+
sourceLocation,
|
|
389
|
+
nullable: prop.tsType.nullable,
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
extractNestedInlineObjectsFromArg(
|
|
393
|
+
prop.tsType.inlineObjectProperties,
|
|
394
|
+
resolverType,
|
|
395
|
+
fieldName,
|
|
396
|
+
argName,
|
|
397
|
+
parentTypeName,
|
|
398
|
+
nestedPath,
|
|
399
|
+
sourceLocation,
|
|
400
|
+
results,
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
interface GenerateAutoTypeResult {
|
|
407
|
+
readonly type: AutoGeneratedType;
|
|
408
|
+
readonly diagnostics: ReadonlyArray<Diagnostic>;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
interface GenerateAutoTypeParams {
|
|
412
|
+
readonly inlineObj: InlineObjectWithContext;
|
|
413
|
+
readonly generatedTypeNames: Map<string, string>;
|
|
414
|
+
readonly enumTypeNames: Map<string, string>;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
function generateAutoType(
|
|
418
|
+
params: GenerateAutoTypeParams,
|
|
419
|
+
): GenerateAutoTypeResult {
|
|
420
|
+
const { inlineObj, generatedTypeNames, enumTypeNames } = params;
|
|
421
|
+
const name = generateAutoTypeName(inlineObj.context);
|
|
422
|
+
const isInput =
|
|
423
|
+
inlineObj.context.kind === "inputField" ||
|
|
424
|
+
inlineObj.context.kind === "resolverArg";
|
|
425
|
+
|
|
426
|
+
const fields: AutoGeneratedField[] = [];
|
|
427
|
+
const diagnostics: Diagnostic[] = [];
|
|
428
|
+
|
|
429
|
+
for (const prop of inlineObj.properties) {
|
|
430
|
+
const eligibility = isInput
|
|
431
|
+
? isEligibleAsInputObjectField(prop.name)
|
|
432
|
+
: isEligibleAsObjectField(prop.name);
|
|
433
|
+
|
|
434
|
+
if (!eligibility.eligible) {
|
|
435
|
+
diagnostics.push({
|
|
436
|
+
code: "SKIPPED_FIELD",
|
|
437
|
+
message: eligibility.skipReason.message,
|
|
438
|
+
severity: "warning",
|
|
439
|
+
location: prop.sourceLocation ?? inlineObj.sourceLocation,
|
|
440
|
+
});
|
|
441
|
+
continue;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
const fieldType = resolveFieldType({
|
|
445
|
+
prop,
|
|
446
|
+
generatedTypeNames,
|
|
447
|
+
enumTypeNames,
|
|
448
|
+
parentContext: inlineObj.context,
|
|
449
|
+
});
|
|
450
|
+
fields.push({
|
|
451
|
+
name: prop.name,
|
|
452
|
+
type: fieldType,
|
|
453
|
+
description: prop.description,
|
|
454
|
+
deprecated: prop.deprecated,
|
|
455
|
+
directives: prop.directives,
|
|
456
|
+
defaultValue: prop.defaultValue,
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
return {
|
|
461
|
+
type: {
|
|
462
|
+
name,
|
|
463
|
+
kind: isInput ? "InputObject" : "Object",
|
|
464
|
+
fields,
|
|
465
|
+
enumValues: null,
|
|
466
|
+
needsStringEnumMapping: false,
|
|
467
|
+
sourceLocation: inlineObj.sourceLocation,
|
|
468
|
+
generatedFrom: buildGeneratedFromInfo(inlineObj.context),
|
|
469
|
+
description: null,
|
|
470
|
+
},
|
|
471
|
+
diagnostics,
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
interface ResolveFieldTypeParams {
|
|
476
|
+
readonly prop: InlineObjectPropertyDef;
|
|
477
|
+
readonly generatedTypeNames: Map<string, string>;
|
|
478
|
+
readonly enumTypeNames: Map<string, string>;
|
|
479
|
+
readonly parentContext: AutoTypeNameContext;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
function resolveFieldType(params: ResolveFieldTypeParams): GraphQLFieldType {
|
|
483
|
+
const { prop, generatedTypeNames, enumTypeNames, parentContext } = params;
|
|
484
|
+
|
|
485
|
+
if (
|
|
486
|
+
prop.tsType.kind === "inlineObject" &&
|
|
487
|
+
prop.tsType.inlineObjectProperties
|
|
488
|
+
) {
|
|
489
|
+
const nestedPath = [...parentContext.fieldPath, prop.name];
|
|
490
|
+
const nestedContext: AutoTypeNameContext = {
|
|
491
|
+
...parentContext,
|
|
492
|
+
fieldPath: nestedPath,
|
|
493
|
+
};
|
|
494
|
+
const contextKey = getContextKey(nestedContext);
|
|
495
|
+
const resolvedTypeName = generatedTypeNames.get(contextKey);
|
|
496
|
+
if (resolvedTypeName) {
|
|
497
|
+
return {
|
|
498
|
+
typeName: resolvedTypeName,
|
|
499
|
+
nullable: prop.tsType.nullable || prop.optional,
|
|
500
|
+
list: false,
|
|
501
|
+
listItemNullable: null,
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
if (prop.tsType.kind === "inlineEnum" && prop.tsType.inlineEnumMembers) {
|
|
507
|
+
const nestedPath = [...parentContext.fieldPath, prop.name];
|
|
508
|
+
const nestedContext: AutoTypeNameContext = {
|
|
509
|
+
...parentContext,
|
|
510
|
+
fieldPath: nestedPath,
|
|
511
|
+
};
|
|
512
|
+
const contextKey = getContextKey(nestedContext);
|
|
513
|
+
const resolvedTypeName = enumTypeNames.get(contextKey);
|
|
514
|
+
if (resolvedTypeName) {
|
|
515
|
+
return {
|
|
516
|
+
typeName: resolvedTypeName,
|
|
517
|
+
nullable: prop.tsType.nullable || prop.optional,
|
|
518
|
+
list: false,
|
|
519
|
+
listItemNullable: null,
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
return convertTsTypeToGraphQLType(prop.tsType, prop.optional);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
interface UpdateTypeNamesParams {
|
|
528
|
+
readonly generatedTypeNames: Map<string, string>;
|
|
529
|
+
readonly enumTypeNames: Map<string, string>;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
function updateExtractedTypes(
|
|
533
|
+
extractedTypes: ReadonlyArray<ExtractedTypeInfo>,
|
|
534
|
+
params: UpdateTypeNamesParams,
|
|
535
|
+
): ExtractedTypeInfo[] {
|
|
536
|
+
return extractedTypes.map((typeInfo) => {
|
|
537
|
+
const isInput = isInputTypeName(typeInfo.metadata.name);
|
|
538
|
+
return {
|
|
539
|
+
...typeInfo,
|
|
540
|
+
fields: typeInfo.fields.map((field) =>
|
|
541
|
+
updateField(field, params, typeInfo.metadata.name, isInput),
|
|
542
|
+
),
|
|
543
|
+
};
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
function updateField(
|
|
548
|
+
field: FieldDefinition,
|
|
549
|
+
params: UpdateTypeNamesParams,
|
|
550
|
+
parentTypeName: string,
|
|
551
|
+
isInput: boolean,
|
|
552
|
+
): FieldDefinition {
|
|
553
|
+
const { generatedTypeNames, enumTypeNames } = params;
|
|
554
|
+
const context = buildFieldContext(parentTypeName, [field.name], isInput);
|
|
555
|
+
const contextKey = getContextKey(context);
|
|
556
|
+
|
|
557
|
+
// Handle inline objects
|
|
558
|
+
if (
|
|
559
|
+
field.tsType.kind === "inlineObject" &&
|
|
560
|
+
field.tsType.inlineObjectProperties
|
|
561
|
+
) {
|
|
562
|
+
const resolvedTypeName = generatedTypeNames.get(contextKey);
|
|
563
|
+
if (resolvedTypeName) {
|
|
564
|
+
return {
|
|
565
|
+
...field,
|
|
566
|
+
tsType: createReferenceType({
|
|
567
|
+
name: resolvedTypeName,
|
|
568
|
+
nullable: field.tsType.nullable,
|
|
569
|
+
}),
|
|
570
|
+
};
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
// Handle inline enums
|
|
575
|
+
if (field.tsType.kind === "inlineEnum" && field.tsType.inlineEnumMembers) {
|
|
576
|
+
const resolvedTypeName = enumTypeNames.get(contextKey);
|
|
577
|
+
if (resolvedTypeName) {
|
|
578
|
+
return {
|
|
579
|
+
...field,
|
|
580
|
+
tsType: createReferenceType({
|
|
581
|
+
name: resolvedTypeName,
|
|
582
|
+
nullable: field.tsType.nullable,
|
|
583
|
+
}),
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
// Handle array of inline enums
|
|
589
|
+
if (
|
|
590
|
+
field.tsType.kind === "array" &&
|
|
591
|
+
field.tsType.elementType?.kind === "inlineEnum" &&
|
|
592
|
+
field.tsType.elementType.inlineEnumMembers
|
|
593
|
+
) {
|
|
594
|
+
const resolvedTypeName = enumTypeNames.get(contextKey);
|
|
595
|
+
if (resolvedTypeName) {
|
|
596
|
+
return {
|
|
597
|
+
...field,
|
|
598
|
+
tsType: {
|
|
599
|
+
...field.tsType,
|
|
600
|
+
elementType: createReferenceType({
|
|
601
|
+
name: resolvedTypeName,
|
|
602
|
+
nullable: field.tsType.elementType.nullable,
|
|
603
|
+
}),
|
|
604
|
+
},
|
|
605
|
+
};
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
return field;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
function updateResolversResult(
|
|
613
|
+
resolversResult: ExtractResolversResult,
|
|
614
|
+
params: UpdateTypeNamesParams,
|
|
615
|
+
): ExtractResolversResult {
|
|
616
|
+
return {
|
|
617
|
+
...resolversResult,
|
|
618
|
+
queryFields: {
|
|
619
|
+
fields: resolversResult.queryFields.fields.map((field) =>
|
|
620
|
+
updateResolverField(field, params, "query", null),
|
|
621
|
+
),
|
|
622
|
+
},
|
|
623
|
+
mutationFields: {
|
|
624
|
+
fields: resolversResult.mutationFields.fields.map((field) =>
|
|
625
|
+
updateResolverField(field, params, "mutation", null),
|
|
626
|
+
),
|
|
627
|
+
},
|
|
628
|
+
typeExtensions: resolversResult.typeExtensions.map((ext) => ({
|
|
629
|
+
...ext,
|
|
630
|
+
fields: ext.fields.map((field) =>
|
|
631
|
+
updateResolverField(field, params, "field", ext.targetTypeName),
|
|
632
|
+
),
|
|
633
|
+
})),
|
|
634
|
+
};
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
function updateResolverField(
|
|
638
|
+
field: GraphQLFieldDefinition,
|
|
639
|
+
params: UpdateTypeNamesParams,
|
|
640
|
+
resolverType: "query" | "mutation" | "field",
|
|
641
|
+
parentTypeName: string | null,
|
|
642
|
+
): GraphQLFieldDefinition {
|
|
643
|
+
if (!field.args) return field;
|
|
644
|
+
|
|
645
|
+
const { generatedTypeNames, enumTypeNames } = params;
|
|
646
|
+
|
|
647
|
+
const updatedArgs = field.args.map((arg) => {
|
|
648
|
+
const context: AutoTypeNameContext = {
|
|
649
|
+
kind: "resolverArg",
|
|
650
|
+
resolverType,
|
|
651
|
+
fieldName: field.name,
|
|
652
|
+
argName: arg.name,
|
|
653
|
+
parentTypeName,
|
|
654
|
+
fieldPath: [],
|
|
655
|
+
};
|
|
656
|
+
const contextKey = getContextKey(context);
|
|
657
|
+
|
|
658
|
+
// Handle inline objects
|
|
659
|
+
if (arg.inlineObjectProperties) {
|
|
660
|
+
const resolvedTypeName = generatedTypeNames.get(contextKey);
|
|
661
|
+
if (resolvedTypeName) {
|
|
662
|
+
return {
|
|
663
|
+
...arg,
|
|
664
|
+
type: {
|
|
665
|
+
...arg.type,
|
|
666
|
+
typeName: resolvedTypeName,
|
|
667
|
+
},
|
|
668
|
+
};
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
// Handle inline enums
|
|
673
|
+
if (arg.inlineEnumMembers) {
|
|
674
|
+
const resolvedTypeName = enumTypeNames.get(contextKey);
|
|
675
|
+
if (resolvedTypeName) {
|
|
676
|
+
return {
|
|
677
|
+
...arg,
|
|
678
|
+
type: {
|
|
679
|
+
...arg.type,
|
|
680
|
+
typeName: resolvedTypeName,
|
|
681
|
+
},
|
|
682
|
+
};
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
return arg;
|
|
687
|
+
});
|
|
688
|
+
|
|
689
|
+
return {
|
|
690
|
+
...field,
|
|
691
|
+
args: updatedArgs,
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
function buildGeneratedTypeNamesMap(
|
|
696
|
+
inlineObjects: InlineObjectWithContext[],
|
|
697
|
+
): Map<string, string> {
|
|
698
|
+
const map = new Map<string, string>();
|
|
699
|
+
|
|
700
|
+
for (const inlineObj of inlineObjects) {
|
|
701
|
+
const typeName = generateAutoTypeName(inlineObj.context);
|
|
702
|
+
const contextKey = getContextKey(inlineObj.context);
|
|
703
|
+
map.set(contextKey, typeName);
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
return map;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
function toScreamingSnakeCase(value: string): string {
|
|
710
|
+
return value
|
|
711
|
+
.replace(/[-\s]+/g, "_")
|
|
712
|
+
.replace(/([a-z])([A-Z])/g, "$1_$2")
|
|
713
|
+
.replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2")
|
|
714
|
+
.toUpperCase();
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
interface ConvertInlineEnumMembersParams {
|
|
718
|
+
readonly members: ReadonlyArray<InlineEnumMemberInfo>;
|
|
719
|
+
readonly enumName: string;
|
|
720
|
+
readonly sourceLocation: SourceLocation;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
interface ConvertEnumMembersWithDiagnosticsResult {
|
|
724
|
+
readonly enumValues: ReadonlyArray<AutoGeneratedEnumValue>;
|
|
725
|
+
readonly needsStringEnumMapping: boolean;
|
|
726
|
+
readonly diagnostics: ReadonlyArray<Diagnostic>;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
function convertInlineEnumMembers(
|
|
730
|
+
params: ConvertInlineEnumMembersParams,
|
|
731
|
+
): ConvertEnumMembersWithDiagnosticsResult {
|
|
732
|
+
const { members, enumName, sourceLocation } = params;
|
|
733
|
+
let needsStringEnumMapping = false;
|
|
734
|
+
const enumValues: AutoGeneratedEnumValue[] = [];
|
|
735
|
+
const diagnostics: Diagnostic[] = [];
|
|
736
|
+
|
|
737
|
+
const convertedNameToOriginals = new Map<string, string[]>();
|
|
738
|
+
|
|
739
|
+
for (const member of members) {
|
|
740
|
+
const convertedName = toScreamingSnakeCase(member.value);
|
|
741
|
+
|
|
742
|
+
if (convertedName !== member.value) {
|
|
743
|
+
needsStringEnumMapping = true;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
const originals = convertedNameToOriginals.get(convertedName) ?? [];
|
|
747
|
+
originals.push(member.value);
|
|
748
|
+
convertedNameToOriginals.set(convertedName, originals);
|
|
749
|
+
|
|
750
|
+
enumValues.push({
|
|
751
|
+
name: convertedName,
|
|
752
|
+
originalValue: member.value,
|
|
753
|
+
description: member.description,
|
|
754
|
+
deprecated: member.deprecated,
|
|
755
|
+
});
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
for (const [convertedName, originals] of convertedNameToOriginals) {
|
|
759
|
+
if (originals.length > 1) {
|
|
760
|
+
diagnostics.push({
|
|
761
|
+
code: "DUPLICATE_ENUM_VALUE_AFTER_CONVERSION",
|
|
762
|
+
message: `Enum '${enumName}' has duplicate value '${convertedName}' after conversion (from '${originals.join("' and '")}')`,
|
|
763
|
+
severity: "error",
|
|
764
|
+
location: sourceLocation,
|
|
765
|
+
});
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
return { enumValues, needsStringEnumMapping, diagnostics };
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
interface GenerateAutoEnumTypeResult {
|
|
773
|
+
readonly type: AutoGeneratedType;
|
|
774
|
+
readonly diagnostics: ReadonlyArray<Diagnostic>;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
function generateAutoEnumType(
|
|
778
|
+
inlineEnum: InlineEnumWithContext,
|
|
779
|
+
typeName: string,
|
|
780
|
+
): GenerateAutoEnumTypeResult {
|
|
781
|
+
const { enumValues, needsStringEnumMapping, diagnostics } =
|
|
782
|
+
convertInlineEnumMembers({
|
|
783
|
+
members: inlineEnum.members,
|
|
784
|
+
enumName: typeName,
|
|
785
|
+
sourceLocation: inlineEnum.sourceLocation,
|
|
786
|
+
});
|
|
787
|
+
|
|
788
|
+
return {
|
|
789
|
+
type: {
|
|
790
|
+
name: typeName,
|
|
791
|
+
kind: "Enum",
|
|
792
|
+
fields: null,
|
|
793
|
+
enumValues,
|
|
794
|
+
needsStringEnumMapping,
|
|
795
|
+
sourceLocation: inlineEnum.sourceLocation,
|
|
796
|
+
generatedFrom: buildGeneratedFromInfo(inlineEnum.context),
|
|
797
|
+
description: inlineEnum.externalEnumDescription,
|
|
798
|
+
},
|
|
799
|
+
diagnostics,
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
interface ExternalEnumRegistry {
|
|
804
|
+
readonly symbolToTypeName: Map<ts.Symbol, string>;
|
|
805
|
+
readonly symbolToContextKey: Map<ts.Symbol, string>;
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
interface BuildEnumTypeNamesMapResult {
|
|
809
|
+
readonly enumTypeNames: Map<string, string>;
|
|
810
|
+
readonly externalEnumRegistry: ExternalEnumRegistry;
|
|
811
|
+
readonly uniqueInlineEnums: InlineEnumWithContext[];
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
function buildEnumTypeNamesMap(
|
|
815
|
+
inlineEnums: InlineEnumWithContext[],
|
|
816
|
+
): BuildEnumTypeNamesMapResult {
|
|
817
|
+
const enumTypeNames = new Map<string, string>();
|
|
818
|
+
const symbolToTypeName = new Map<ts.Symbol, string>();
|
|
819
|
+
const symbolToContextKey = new Map<ts.Symbol, string>();
|
|
820
|
+
const uniqueInlineEnums: InlineEnumWithContext[] = [];
|
|
821
|
+
|
|
822
|
+
for (const inlineEnum of inlineEnums) {
|
|
823
|
+
const contextKey = getContextKey(inlineEnum.context);
|
|
824
|
+
|
|
825
|
+
if (inlineEnum.externalEnumSymbol !== null) {
|
|
826
|
+
const existingTypeName = symbolToTypeName.get(
|
|
827
|
+
inlineEnum.externalEnumSymbol,
|
|
828
|
+
);
|
|
829
|
+
if (existingTypeName) {
|
|
830
|
+
enumTypeNames.set(contextKey, existingTypeName);
|
|
831
|
+
continue;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
const typeName = generateAutoTypeName(inlineEnum.context);
|
|
835
|
+
symbolToTypeName.set(inlineEnum.externalEnumSymbol, typeName);
|
|
836
|
+
symbolToContextKey.set(inlineEnum.externalEnumSymbol, contextKey);
|
|
837
|
+
enumTypeNames.set(contextKey, typeName);
|
|
838
|
+
uniqueInlineEnums.push(inlineEnum);
|
|
839
|
+
} else {
|
|
840
|
+
const typeName = generateAutoTypeName(inlineEnum.context);
|
|
841
|
+
enumTypeNames.set(contextKey, typeName);
|
|
842
|
+
uniqueInlineEnums.push(inlineEnum);
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
return {
|
|
847
|
+
enumTypeNames,
|
|
848
|
+
externalEnumRegistry: { symbolToTypeName, symbolToContextKey },
|
|
849
|
+
uniqueInlineEnums,
|
|
850
|
+
};
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
export function generateAutoTypes(
|
|
854
|
+
input: AutoTypeGeneratorInput,
|
|
855
|
+
): AutoTypeGeneratorResult {
|
|
856
|
+
const inlineObjectsFromTypes: InlineObjectWithContext[] = [];
|
|
857
|
+
for (const typeInfo of input.extractedTypes) {
|
|
858
|
+
inlineObjectsFromTypes.push(...collectInlineObjectsFromType(typeInfo));
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
const inlineObjectsFromResolvers = collectInlineObjectsFromResolvers(
|
|
862
|
+
input.resolversResult,
|
|
863
|
+
);
|
|
864
|
+
|
|
865
|
+
const allInlineObjects = [
|
|
866
|
+
...inlineObjectsFromTypes,
|
|
867
|
+
...inlineObjectsFromResolvers,
|
|
868
|
+
];
|
|
869
|
+
|
|
870
|
+
const generatedTypeNames = buildGeneratedTypeNamesMap(allInlineObjects);
|
|
871
|
+
|
|
872
|
+
const inlineEnumsFromTypes = collectInlineEnumsFromTypes(
|
|
873
|
+
input.extractedTypes,
|
|
874
|
+
);
|
|
875
|
+
const inlineEnumsFromResolvers = collectInlineEnumsFromResolvers(
|
|
876
|
+
input.resolversResult,
|
|
877
|
+
);
|
|
878
|
+
const allInlineEnums = [...inlineEnumsFromTypes, ...inlineEnumsFromResolvers];
|
|
879
|
+
|
|
880
|
+
const { enumTypeNames, uniqueInlineEnums } =
|
|
881
|
+
buildEnumTypeNamesMap(allInlineEnums);
|
|
882
|
+
|
|
883
|
+
const autoGeneratedTypes: AutoGeneratedType[] = [];
|
|
884
|
+
const diagnostics: Diagnostic[] = [];
|
|
885
|
+
|
|
886
|
+
for (const inlineObj of allInlineObjects) {
|
|
887
|
+
const result = generateAutoType({
|
|
888
|
+
inlineObj,
|
|
889
|
+
generatedTypeNames,
|
|
890
|
+
enumTypeNames,
|
|
891
|
+
});
|
|
892
|
+
autoGeneratedTypes.push(result.type);
|
|
893
|
+
diagnostics.push(...result.diagnostics);
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
for (const inlineEnum of uniqueInlineEnums) {
|
|
897
|
+
const contextKey = getContextKey(inlineEnum.context);
|
|
898
|
+
const typeName = enumTypeNames.get(contextKey)!;
|
|
899
|
+
const result = generateAutoEnumType(inlineEnum, typeName);
|
|
900
|
+
autoGeneratedTypes.push(result.type);
|
|
901
|
+
diagnostics.push(...result.diagnostics);
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
const updateParams: UpdateTypeNamesParams = {
|
|
905
|
+
generatedTypeNames,
|
|
906
|
+
enumTypeNames,
|
|
907
|
+
};
|
|
908
|
+
|
|
909
|
+
const updatedExtractedTypes = updateExtractedTypes(
|
|
910
|
+
input.extractedTypes,
|
|
911
|
+
updateParams,
|
|
912
|
+
);
|
|
913
|
+
|
|
914
|
+
const updatedResolversResult = updateResolversResult(
|
|
915
|
+
input.resolversResult,
|
|
916
|
+
updateParams,
|
|
917
|
+
);
|
|
918
|
+
|
|
919
|
+
return {
|
|
920
|
+
autoGeneratedTypes,
|
|
921
|
+
updatedExtractedTypes,
|
|
922
|
+
updatedResolversResult,
|
|
923
|
+
diagnostics,
|
|
924
|
+
};
|
|
925
|
+
}
|