@gqlkit-ts/cli 0.0.1 → 0.1.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 +46 -0
- package/dist/auto-type-generator/auto-type-generator.d.ts.map +1 -0
- package/dist/auto-type-generator/auto-type-generator.js +353 -0
- package/dist/auto-type-generator/auto-type-generator.js.map +1 -0
- package/dist/auto-type-generator/auto-type-generator.test.d.ts +2 -0
- package/dist/auto-type-generator/auto-type-generator.test.d.ts.map +1 -0
- package/dist/auto-type-generator/auto-type-generator.test.js +613 -0
- package/dist/auto-type-generator/auto-type-generator.test.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/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/name-collision-validator.test.d.ts +2 -0
- package/dist/auto-type-generator/name-collision-validator.test.d.ts.map +1 -0
- package/dist/auto-type-generator/name-collision-validator.test.js +358 -0
- package/dist/auto-type-generator/name-collision-validator.test.js.map +1 -0
- package/dist/auto-type-generator/naming-convention.d.ts +40 -0
- package/dist/auto-type-generator/naming-convention.d.ts.map +1 -0
- package/dist/auto-type-generator/naming-convention.js +59 -0
- package/dist/auto-type-generator/naming-convention.js.map +1 -0
- package/dist/auto-type-generator/naming-convention.test.d.ts +2 -0
- package/dist/auto-type-generator/naming-convention.test.d.ts.map +1 -0
- package/dist/auto-type-generator/naming-convention.test.js +132 -0
- package/dist/auto-type-generator/naming-convention.test.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/gen.test.d.ts +2 -0
- package/dist/commands/gen.test.d.ts.map +1 -0
- package/dist/commands/gen.test.js +226 -0
- package/dist/commands/gen.test.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/loader.test.d.ts +2 -0
- package/dist/config-loader/loader.test.d.ts.map +1 -0
- package/dist/config-loader/loader.test.js +123 -0
- package/dist/config-loader/loader.test.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/config-loader/validator.test.d.ts +2 -0
- package/dist/config-loader/validator.test.d.ts.map +1 -0
- package/dist/config-loader/validator.test.js +846 -0
- package/dist/config-loader/validator.test.js.map +1 -0
- package/dist/gen-orchestrator/golden.test.d.ts +2 -0
- package/dist/gen-orchestrator/golden.test.d.ts.map +1 -0
- package/dist/gen-orchestrator/golden.test.js +102 -0
- package/dist/gen-orchestrator/golden.test.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/hook-executor/hook-executor.test.d.ts +2 -0
- package/dist/gen-orchestrator/hook-executor/hook-executor.test.d.ts.map +1 -0
- package/dist/gen-orchestrator/hook-executor/hook-executor.test.js +167 -0
- package/dist/gen-orchestrator/hook-executor/hook-executor.test.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 +407 -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/reporter/progress-reporter.test.d.ts +2 -0
- package/dist/gen-orchestrator/reporter/progress-reporter.test.d.ts.map +1 -0
- package/dist/gen-orchestrator/reporter/progress-reporter.test.js +74 -0
- package/dist/gen-orchestrator/reporter/progress-reporter.test.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 +40 -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 +50 -0
- package/dist/resolver-extractor/extractor/define-api-extractor.d.ts.map +1 -0
- package/dist/resolver-extractor/extractor/define-api-extractor.js +685 -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/resolver-extractor/validator/only-validator.test.d.ts +8 -0
- package/dist/resolver-extractor/validator/only-validator.test.d.ts.map +1 -0
- package/dist/resolver-extractor/validator/only-validator.test.js +352 -0
- package/dist/resolver-extractor/validator/only-validator.test.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/builder/ast-builder.test.d.ts +2 -0
- package/dist/schema-generator/builder/ast-builder.test.d.ts.map +1 -0
- package/dist/schema-generator/builder/ast-builder.test.js +469 -0
- package/dist/schema-generator/builder/ast-builder.test.js.map +1 -0
- package/dist/schema-generator/emitter/code-emitter.d.ts +7 -0
- package/dist/schema-generator/emitter/code-emitter.d.ts.map +1 -0
- package/dist/schema-generator/emitter/code-emitter.js +201 -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 +76 -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 +93 -0
- package/dist/schema-generator/integrator/result-integrator.d.ts.map +1 -0
- package/dist/schema-generator/integrator/result-integrator.js +396 -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 +70 -0
- package/dist/shared/constants.d.ts.map +1 -0
- package/dist/shared/constants.js +128 -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 +422 -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 +99 -0
- package/dist/shared/file-scanner.js.map +1 -0
- package/dist/shared/file-scanner.test.d.ts +2 -0
- package/dist/shared/file-scanner.test.d.ts.map +1 -0
- package/dist/shared/file-scanner.test.js +138 -0
- package/dist/shared/file-scanner.test.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 +8 -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 +22 -0
- package/dist/shared/interface-detector.d.ts.map +1 -0
- package/dist/shared/interface-detector.js +90 -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/interface-validator.test.d.ts +2 -0
- package/dist/shared/interface-validator.test.d.ts.map +1 -0
- package/dist/shared/interface-validator.test.js +145 -0
- package/dist/shared/interface-validator.test.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/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 +72 -0
- package/dist/shared/type-converter.js.map +1 -0
- package/dist/shared/typescript-utils.d.ts +55 -0
- package/dist/shared/typescript-utils.d.ts.map +1 -0
- package/dist/shared/typescript-utils.js +149 -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 +133 -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 +299 -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/type-extractor.d.ts +27 -0
- package/dist/type-extractor/extractor/type-extractor.d.ts.map +1 -0
- package/dist/type-extractor/extractor/type-extractor.js +1116 -0
- package/dist/type-extractor/extractor/type-extractor.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/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 +40 -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 +5 -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/typescript.d.ts +86 -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/types/typescript.test.d.ts +2 -0
- package/dist/type-extractor/types/typescript.test.d.ts.map +1 -0
- package/dist/type-extractor/types/typescript.test.js +287 -0
- package/dist/type-extractor/types/typescript.test.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 +32 -0
- package/docs/integration/apollo.md +109 -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 +162 -0
- package/docs/schema/fields.md +184 -0
- package/docs/schema/index.md +38 -0
- package/docs/schema/inputs.md +277 -0
- package/docs/schema/interfaces.md +178 -0
- package/docs/schema/objects.md +186 -0
- package/docs/schema/queries-mutations.md +205 -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 +59 -7
- package/README.md +0 -45
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# Object Types
|
|
2
|
+
|
|
3
|
+
Plain TypeScript type exports become GraphQL Object types.
|
|
4
|
+
|
|
5
|
+
## Basic Usage
|
|
6
|
+
|
|
7
|
+
Export a TypeScript type or interface:
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
// src/gqlkit/schema/user.ts
|
|
11
|
+
import { defineQuery, defineField } from "../gqlkit";
|
|
12
|
+
import type { IDString, Int, NoArgs } from "@gqlkit-ts/runtime";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* A user in the system
|
|
16
|
+
*/
|
|
17
|
+
export type User = {
|
|
18
|
+
/** Unique identifier */
|
|
19
|
+
id: IDString;
|
|
20
|
+
/** Display name */
|
|
21
|
+
name: string;
|
|
22
|
+
/** Age in years */
|
|
23
|
+
age: Int;
|
|
24
|
+
/** Email address (null if not verified) */
|
|
25
|
+
email: string | null;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const me = defineQuery<NoArgs, User | null>((_root, _args, ctx) => {
|
|
29
|
+
return findUserById(ctx.currentUserId);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
/** Get user's profile URL */
|
|
33
|
+
export const profileUrl = defineField<User, NoArgs, string>((parent) => {
|
|
34
|
+
return `https://example.com/users/${parent.id}`;
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Nullability
|
|
39
|
+
|
|
40
|
+
Use union with `null` to make fields nullable:
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
export type User = {
|
|
44
|
+
email: string | null; // nullable
|
|
45
|
+
name: string; // non-null
|
|
46
|
+
};
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Generates:
|
|
50
|
+
|
|
51
|
+
```graphql
|
|
52
|
+
type User {
|
|
53
|
+
email: String
|
|
54
|
+
name: String!
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Arrays
|
|
59
|
+
|
|
60
|
+
Arrays are automatically converted to GraphQL lists:
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
export type User = {
|
|
64
|
+
tags: string[]; // [String!]!
|
|
65
|
+
posts: Post[] | null; // [Post!]
|
|
66
|
+
};
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Inline Objects
|
|
70
|
+
|
|
71
|
+
Object type fields can use inline object literals for nested structures. gqlkit automatically generates Object types with the naming convention `{ParentTypeName}{PascalCaseFieldName}`:
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
export type User = {
|
|
75
|
+
id: string;
|
|
76
|
+
name: string;
|
|
77
|
+
/** User's profile information */
|
|
78
|
+
profile: {
|
|
79
|
+
/** User's biography */
|
|
80
|
+
bio: string;
|
|
81
|
+
age: number;
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Generates:
|
|
87
|
+
|
|
88
|
+
```graphql
|
|
89
|
+
type User {
|
|
90
|
+
id: String!
|
|
91
|
+
name: String!
|
|
92
|
+
"""User's profile information"""
|
|
93
|
+
profile: UserProfile!
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
type UserProfile {
|
|
97
|
+
"""User's biography"""
|
|
98
|
+
bio: String!
|
|
99
|
+
age: Float!
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Nested inline objects generate types with concatenated names (e.g., `User.profile.address` → `UserProfileAddress`).
|
|
104
|
+
|
|
105
|
+
## Implementing Interfaces
|
|
106
|
+
|
|
107
|
+
Use `GqlObject` with the `implements` option to declare that a type implements interfaces:
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
import { type GqlObject, type IDString } from "@gqlkit-ts/runtime";
|
|
111
|
+
import type { Node, Timestamped } from "./node.js";
|
|
112
|
+
import type { DateTime } from "./scalars.js";
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* A user in the system.
|
|
116
|
+
*/
|
|
117
|
+
export type User = GqlObject<
|
|
118
|
+
{
|
|
119
|
+
id: IDString;
|
|
120
|
+
name: string;
|
|
121
|
+
email: string | null;
|
|
122
|
+
createdAt: DateTime;
|
|
123
|
+
},
|
|
124
|
+
{ implements: [Node, Timestamped] }
|
|
125
|
+
>;
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Generates:
|
|
129
|
+
|
|
130
|
+
```graphql
|
|
131
|
+
"""A user in the system."""
|
|
132
|
+
type User implements Node & Timestamped {
|
|
133
|
+
id: ID!
|
|
134
|
+
name: String!
|
|
135
|
+
email: String
|
|
136
|
+
createdAt: DateTime!
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
You can combine `implements` with `directives`:
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
export type Post = GqlObject<
|
|
144
|
+
{
|
|
145
|
+
id: IDString;
|
|
146
|
+
title: string;
|
|
147
|
+
createdAt: DateTime;
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
implements: [Node, Timestamped],
|
|
151
|
+
directives: [CacheDirective<{ maxAge: 60 }>]
|
|
152
|
+
}
|
|
153
|
+
>;
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
See [Interfaces](./interfaces.md) for more details on defining interface types.
|
|
157
|
+
|
|
158
|
+
## Invalid Field Names
|
|
159
|
+
|
|
160
|
+
Field names that are not valid GraphQL identifiers are automatically skipped with a warning. Valid GraphQL names must:
|
|
161
|
+
|
|
162
|
+
- Match the pattern `/^[_A-Za-z][_0-9A-Za-z]*$/`
|
|
163
|
+
- Not start with `__` (reserved for GraphQL introspection)
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
export type User = {
|
|
167
|
+
id: string; // ✅ Valid
|
|
168
|
+
userName: string; // ✅ Valid
|
|
169
|
+
_internal: string; // ✅ Valid (single underscore is OK)
|
|
170
|
+
"0invalid": string; // ⚠️ Skipped: starts with a number
|
|
171
|
+
__reserved: string; // ⚠️ Skipped: starts with __
|
|
172
|
+
"field-name": string; // ⚠️ Skipped: contains hyphen
|
|
173
|
+
};
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Generates (invalid fields are skipped):
|
|
177
|
+
|
|
178
|
+
```graphql
|
|
179
|
+
type User {
|
|
180
|
+
id: String!
|
|
181
|
+
userName: String!
|
|
182
|
+
_internal: String!
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
When fields are skipped, gqlkit outputs a warning with the field name and location.
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# Queries & Mutations
|
|
2
|
+
|
|
3
|
+
Define Query and Mutation fields using the `@gqlkit-ts/runtime` API.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
Create `src/gqlkit/context.ts` to define your context type:
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
export type Context = {
|
|
11
|
+
userId: string;
|
|
12
|
+
db: Database;
|
|
13
|
+
};
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Create `src/gqlkit/gqlkit.ts` to export resolver factories:
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { createGqlkitApis } from "@gqlkit-ts/runtime";
|
|
20
|
+
import type { Context } from "./context";
|
|
21
|
+
|
|
22
|
+
export const { defineQuery, defineMutation, defineField } =
|
|
23
|
+
createGqlkitApis<Context>();
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Then import the factories in your schema files.
|
|
27
|
+
|
|
28
|
+
## Query Resolvers
|
|
29
|
+
|
|
30
|
+
Use `defineQuery` to define Query fields. The export name becomes the GraphQL field name:
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
import { defineQuery } from "../gqlkit";
|
|
34
|
+
import type { NoArgs } from "@gqlkit-ts/runtime";
|
|
35
|
+
import type { User } from "./user";
|
|
36
|
+
|
|
37
|
+
// Query.me
|
|
38
|
+
export const me = defineQuery<NoArgs, User | null>(
|
|
39
|
+
(_root, _args, ctx) => {
|
|
40
|
+
return ctx.db.findUser(ctx.userId);
|
|
41
|
+
}
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
// Query.user(id: String!)
|
|
45
|
+
export const user = defineQuery<{ id: string }, User | null>(
|
|
46
|
+
(_root, args, ctx) => {
|
|
47
|
+
return ctx.db.findUser(args.id);
|
|
48
|
+
}
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
// Query.users
|
|
52
|
+
export const users = defineQuery<NoArgs, User[]>(
|
|
53
|
+
(_root, _args, ctx) => {
|
|
54
|
+
return ctx.db.findAllUsers();
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Generates:
|
|
60
|
+
|
|
61
|
+
```graphql
|
|
62
|
+
type Query {
|
|
63
|
+
me: User
|
|
64
|
+
user(id: String!): User
|
|
65
|
+
users: [User!]!
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Mutation Resolvers
|
|
70
|
+
|
|
71
|
+
Use `defineMutation` to define Mutation fields:
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
import { defineMutation } from "../gqlkit";
|
|
75
|
+
import type { User, CreateUserInput } from "./user";
|
|
76
|
+
|
|
77
|
+
// Mutation.createUser(input: CreateUserInput!)
|
|
78
|
+
export const createUser = defineMutation<{ input: CreateUserInput }, User>(
|
|
79
|
+
(_root, args, ctx) => {
|
|
80
|
+
return ctx.db.createUser(args.input);
|
|
81
|
+
}
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
// Mutation.deleteUser(id: String!)
|
|
85
|
+
export const deleteUser = defineMutation<{ id: string }, boolean>(
|
|
86
|
+
(_root, args, ctx) => {
|
|
87
|
+
return ctx.db.deleteUser(args.id);
|
|
88
|
+
}
|
|
89
|
+
);
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Generates:
|
|
93
|
+
|
|
94
|
+
```graphql
|
|
95
|
+
type Mutation {
|
|
96
|
+
createUser(input: CreateUserInput!): User!
|
|
97
|
+
deleteUser(id: String!): Boolean!
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Resolver Function Signature
|
|
102
|
+
|
|
103
|
+
Query and Mutation resolvers receive four arguments:
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
(root, args, ctx, info) => ReturnType
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
| Argument | Description |
|
|
110
|
+
|----------|-------------|
|
|
111
|
+
| `root` | The root value (usually undefined) |
|
|
112
|
+
| `args` | The arguments passed to the field |
|
|
113
|
+
| `ctx` | The context object (typed via `createGqlkitApis<Context>()`) |
|
|
114
|
+
| `info` | GraphQL resolve info |
|
|
115
|
+
|
|
116
|
+
## NoArgs Type
|
|
117
|
+
|
|
118
|
+
Use the `NoArgs` type when a field has no arguments:
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
import { type NoArgs } from "@gqlkit-ts/runtime";
|
|
122
|
+
|
|
123
|
+
export const me = defineQuery<NoArgs, User | null>(
|
|
124
|
+
(_root, _args, ctx) => ctx.currentUser
|
|
125
|
+
);
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Arguments with Input Types
|
|
129
|
+
|
|
130
|
+
Use Input types for complex arguments:
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
export type SearchUsersInput = {
|
|
134
|
+
query: string;
|
|
135
|
+
limit: number | null;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
export const searchUsers = defineQuery<{ input: SearchUsersInput }, User[]>(
|
|
139
|
+
(_root, args) => {
|
|
140
|
+
return findUsers(args.input.query, args.input.limit ?? 10);
|
|
141
|
+
}
|
|
142
|
+
);
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Inline Object Arguments
|
|
146
|
+
|
|
147
|
+
Arguments can use inline object literals. gqlkit automatically generates Input Object types:
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
export const searchUsers = defineQuery<
|
|
151
|
+
{
|
|
152
|
+
/** Search filter */
|
|
153
|
+
filter: {
|
|
154
|
+
namePattern: string | null;
|
|
155
|
+
status: UserStatus | null;
|
|
156
|
+
};
|
|
157
|
+
},
|
|
158
|
+
User[]
|
|
159
|
+
>((_root, args) => []);
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Generates:
|
|
163
|
+
|
|
164
|
+
```graphql
|
|
165
|
+
type Query {
|
|
166
|
+
searchUsers(
|
|
167
|
+
"""Search filter"""
|
|
168
|
+
filter: SearchUsersFilterInput!
|
|
169
|
+
): [User!]!
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
input SearchUsersFilterInput {
|
|
173
|
+
namePattern: String
|
|
174
|
+
status: UserStatus
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
See [Field Resolvers](./fields.md) for more details on inline object arguments.
|
|
179
|
+
|
|
180
|
+
## Attaching Directives
|
|
181
|
+
|
|
182
|
+
Add a third type parameter to attach directives to Query/Mutation fields:
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
import { defineQuery } from "../gqlkit";
|
|
186
|
+
import type { NoArgs } from "@gqlkit-ts/runtime";
|
|
187
|
+
import { type AuthDirective } from "./directives.js";
|
|
188
|
+
import type { User } from "./user.js";
|
|
189
|
+
|
|
190
|
+
export const me = defineQuery<
|
|
191
|
+
NoArgs,
|
|
192
|
+
User,
|
|
193
|
+
[AuthDirective<{ role: ["USER"] }>]
|
|
194
|
+
>((_root, _args, ctx) => ctx.currentUser);
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Generates:
|
|
198
|
+
|
|
199
|
+
```graphql
|
|
200
|
+
type Query {
|
|
201
|
+
me: User! @auth(role: [USER])
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
See [Directives](./directives.md) for more details on defining and using custom directives.
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# Scalar Types
|
|
2
|
+
|
|
3
|
+
gqlkit provides built-in scalar types and supports custom scalar definitions.
|
|
4
|
+
|
|
5
|
+
## Built-in Scalar Types
|
|
6
|
+
|
|
7
|
+
gqlkit provides branded types to explicitly specify GraphQL scalar mappings:
|
|
8
|
+
|
|
9
|
+
| TypeScript type | GraphQL type |
|
|
10
|
+
|-----------------|--------------|
|
|
11
|
+
| `IDString` | `ID!` |
|
|
12
|
+
| `IDNumber` | `ID!` |
|
|
13
|
+
| `Int` | `Int!` |
|
|
14
|
+
| `Float` | `Float!` |
|
|
15
|
+
| `string` | `String!` |
|
|
16
|
+
| `number` | `Float!` |
|
|
17
|
+
| `boolean` | `Boolean!` |
|
|
18
|
+
|
|
19
|
+
### Usage
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { type IDString, type Int, type Float } from "@gqlkit-ts/runtime";
|
|
23
|
+
|
|
24
|
+
export type User = {
|
|
25
|
+
id: IDString; // ID!
|
|
26
|
+
age: Int; // Int!
|
|
27
|
+
score: Float; // Float!
|
|
28
|
+
name: string; // String!
|
|
29
|
+
balance: number; // Float!
|
|
30
|
+
active: boolean; // Boolean!
|
|
31
|
+
};
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Custom Scalars with GqlScalar
|
|
35
|
+
|
|
36
|
+
Define custom scalar types using the `GqlScalar` utility type:
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
// src/gqlkit/schema/scalars.ts
|
|
40
|
+
import { type GqlScalar } from "@gqlkit-ts/runtime";
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* ISO 8601 format date-time string
|
|
44
|
+
*/
|
|
45
|
+
export type DateTime = GqlScalar<"DateTime", Date>;
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Generates:
|
|
49
|
+
|
|
50
|
+
```graphql
|
|
51
|
+
"""ISO 8601 format date-time string"""
|
|
52
|
+
scalar DateTime
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### GqlScalar Type Parameters
|
|
56
|
+
|
|
57
|
+
`GqlScalar<Name, Base, Only?>`:
|
|
58
|
+
|
|
59
|
+
| Parameter | Description |
|
|
60
|
+
|-----------|-------------|
|
|
61
|
+
| `Name` | The GraphQL scalar name |
|
|
62
|
+
| `Base` | The TypeScript type that backs this scalar |
|
|
63
|
+
| `Only` | Optional: `"input"` or `"output"` to restrict usage |
|
|
64
|
+
|
|
65
|
+
### Input-only and Output-only Scalars
|
|
66
|
+
|
|
67
|
+
Restrict scalar usage to input or output positions:
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import { type GqlScalar } from "@gqlkit-ts/runtime";
|
|
71
|
+
|
|
72
|
+
// Input-only scalar (for input positions only)
|
|
73
|
+
export type DateTimeInput = GqlScalar<"DateTime", Date, "input">;
|
|
74
|
+
|
|
75
|
+
// Output-only scalar (for output positions only)
|
|
76
|
+
export type DateTimeOutput = GqlScalar<"DateTime", Date | string, "output">;
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
This is useful when input and output representations differ.
|
|
80
|
+
|
|
81
|
+
## Config-based Custom Scalars
|
|
82
|
+
|
|
83
|
+
Alternatively, map TypeScript types to GraphQL custom scalars via config:
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
// gqlkit.config.ts
|
|
87
|
+
import { defineConfig } from "@gqlkit-ts/cli";
|
|
88
|
+
|
|
89
|
+
export default defineConfig({
|
|
90
|
+
scalars: [
|
|
91
|
+
{
|
|
92
|
+
name: "DateTime",
|
|
93
|
+
tsType: { from: "./src/gqlkit/schema/scalars", name: "DateTime" },
|
|
94
|
+
description: "ISO 8601 datetime string",
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: "UUID",
|
|
98
|
+
tsType: { name: "string" }, // Global type
|
|
99
|
+
only: "input", // Input-only scalar
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
});
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Config Options
|
|
106
|
+
|
|
107
|
+
| Option | Description |
|
|
108
|
+
|--------|-------------|
|
|
109
|
+
| `name` | The GraphQL scalar name |
|
|
110
|
+
| `tsType.name` | The TypeScript type name |
|
|
111
|
+
| `tsType.from` | Optional: import path for the type |
|
|
112
|
+
| `description` | Optional: GraphQL description |
|
|
113
|
+
| `only` | Optional: `"input"` or `"output"` |
|
|
114
|
+
|
|
115
|
+
## Using Custom Scalars
|
|
116
|
+
|
|
117
|
+
Once defined, use custom scalars in your types:
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
import type { DateTime } from "./scalars.js";
|
|
121
|
+
|
|
122
|
+
export type User = {
|
|
123
|
+
id: IDString;
|
|
124
|
+
name: string;
|
|
125
|
+
createdAt: DateTime;
|
|
126
|
+
updatedAt: DateTime | null;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
export type CreateUserInput = {
|
|
130
|
+
name: string;
|
|
131
|
+
birthDate: DateTime;
|
|
132
|
+
};
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Registering Scalar Resolvers
|
|
136
|
+
|
|
137
|
+
Custom scalars require resolver implementations to handle serialization and parsing at runtime. Pass scalar resolvers to `createResolvers`:
|
|
138
|
+
|
|
139
|
+
```typescript
|
|
140
|
+
import { createResolvers } from "./gqlkit/__generated__/resolvers.js";
|
|
141
|
+
|
|
142
|
+
const resolvers = createResolvers({
|
|
143
|
+
scalars: {
|
|
144
|
+
DateTime: myDateTimeScalar,
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Using graphql-scalars (Recommended)
|
|
150
|
+
|
|
151
|
+
The easiest way to implement custom scalars is to use [graphql-scalars](https://the-guild.dev/graphql/scalars), which provides ready-to-use implementations for common scalar types:
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
import { GraphQLDateTime } from "graphql-scalars";
|
|
155
|
+
|
|
156
|
+
const resolvers = createResolvers({
|
|
157
|
+
scalars: {
|
|
158
|
+
DateTime: GraphQLDateTime,
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
This approach requires no manual serialize/parse implementation.
|
|
164
|
+
|
|
165
|
+
### Custom Implementation
|
|
166
|
+
|
|
167
|
+
For custom behavior, create your own `GraphQLScalarType`:
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
import { GraphQLScalarType, Kind } from "graphql";
|
|
171
|
+
|
|
172
|
+
const DateTimeScalar = new GraphQLScalarType({
|
|
173
|
+
name: "DateTime",
|
|
174
|
+
description: "ISO 8601 date-time string",
|
|
175
|
+
serialize(value) {
|
|
176
|
+
return value instanceof Date ? value.toISOString() : value;
|
|
177
|
+
},
|
|
178
|
+
parseValue(value) {
|
|
179
|
+
return new Date(value as string);
|
|
180
|
+
},
|
|
181
|
+
parseLiteral(ast) {
|
|
182
|
+
if (ast.kind === Kind.STRING) {
|
|
183
|
+
return new Date(ast.value);
|
|
184
|
+
}
|
|
185
|
+
return null;
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
const resolvers = createResolvers({
|
|
190
|
+
scalars: {
|
|
191
|
+
DateTime: DateTimeScalar,
|
|
192
|
+
},
|
|
193
|
+
});
|
|
194
|
+
```
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Union Types
|
|
2
|
+
|
|
3
|
+
TypeScript union types of object types are converted to GraphQL union types.
|
|
4
|
+
|
|
5
|
+
## Basic Usage
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import type { Post } from "./Post";
|
|
9
|
+
import type { Comment } from "./Comment";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Content that can be searched
|
|
13
|
+
*/
|
|
14
|
+
export type SearchResult = Post | Comment;
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Generates:
|
|
18
|
+
|
|
19
|
+
```graphql
|
|
20
|
+
"""Content that can be searched"""
|
|
21
|
+
union SearchResult = Comment | Post
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Using Unions in Resolvers
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { defineQuery } from "../gqlkit";
|
|
28
|
+
import type { SearchResult } from "./types";
|
|
29
|
+
|
|
30
|
+
export const search = defineQuery<{ query: string }, SearchResult[]>(
|
|
31
|
+
(_root, args, ctx) => {
|
|
32
|
+
return ctx.db.search(args.query);
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Generates:
|
|
38
|
+
|
|
39
|
+
```graphql
|
|
40
|
+
type Query {
|
|
41
|
+
search(query: String!): [SearchResult!]!
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Union vs Enum
|
|
46
|
+
|
|
47
|
+
- Use **Union** when each member is a distinct object type with different fields
|
|
48
|
+
- Use **Enum** when you need a set of string constants
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
// Union: Different object types
|
|
52
|
+
export type SearchResult = Post | Comment | User;
|
|
53
|
+
|
|
54
|
+
// Enum: String constants
|
|
55
|
+
export type Status = "ACTIVE" | "INACTIVE" | "PENDING";
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Union vs Interface
|
|
59
|
+
|
|
60
|
+
- Use **Union** when types share no common fields
|
|
61
|
+
- Use **Interface** when types share common fields that should be queryable
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
// Union: No common structure required
|
|
65
|
+
export type SearchResult = Post | Comment;
|
|
66
|
+
|
|
67
|
+
// Interface: Common fields enforced
|
|
68
|
+
export type Node = GqlInterface<{
|
|
69
|
+
id: IDString;
|
|
70
|
+
}>;
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
See [Interfaces](./interfaces.md) for more details on interface types.
|
|
74
|
+
|
|
75
|
+
## Runtime Type Resolution
|
|
76
|
+
|
|
77
|
+
When GraphQL executes a query that returns a union type, it needs to determine the concrete type at runtime. Use `defineResolveType` to handle this:
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
import { defineResolveType } from "../gqlkit";
|
|
81
|
+
|
|
82
|
+
export const searchResultResolveType = defineResolveType<SearchResult>(
|
|
83
|
+
(value) => {
|
|
84
|
+
if ("name" in value) return "User";
|
|
85
|
+
return "Post";
|
|
86
|
+
}
|
|
87
|
+
);
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
See [Abstract Type Resolution](./abstract-resolvers.md) for complete documentation.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# What is gqlkit?
|
|
2
|
+
|
|
3
|
+
gqlkit is a convention-driven code generator for GraphQL servers in TypeScript.
|
|
4
|
+
|
|
5
|
+
## Core Concept
|
|
6
|
+
|
|
7
|
+
Define GraphQL types and resolver signatures in TypeScript → `gqlkit gen` generates GraphQL schema AST and a resolver map from your codebase.
|
|
8
|
+
|
|
9
|
+
## Design Principles
|
|
10
|
+
|
|
11
|
+
- **Type-First**: Define types using plain TypeScript, no decorators needed
|
|
12
|
+
- **Fail fast with actionable errors**: Invalid resolver references, type mismatches, etc.
|
|
13
|
+
- **No runtime schema mutation**: Pure static analysis of TypeScript code
|
|
14
|
+
- **Deterministic**: Same code → same outputs, always
|
|
15
|
+
- **GraphQL-tools compatible**: Generated outputs work seamlessly with `makeExecutableSchema`
|
|
16
|
+
|
|
17
|
+
## How It Works
|
|
18
|
+
|
|
19
|
+
1. You write TypeScript types and resolvers in `src/gqlkit/schema/`
|
|
20
|
+
2. Run `gqlkit gen`
|
|
21
|
+
3. gqlkit scans your code, builds internal type graph, and validates resolver signatures
|
|
22
|
+
4. Outputs `typeDefs` (GraphQL AST) and `resolvers` map to `src/gqlkit/__generated__/`
|