@constructive-io/graphql-codegen 2.21.0 → 2.22.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.
Files changed (93) hide show
  1. package/cli/codegen/barrel.d.ts +4 -1
  2. package/cli/codegen/barrel.js +18 -12
  3. package/cli/codegen/client.js +33 -0
  4. package/cli/codegen/custom-mutations.d.ts +4 -0
  5. package/cli/codegen/custom-mutations.js +39 -13
  6. package/cli/codegen/custom-queries.d.ts +4 -0
  7. package/cli/codegen/custom-queries.js +36 -11
  8. package/cli/codegen/gql-ast.js +9 -5
  9. package/cli/codegen/index.js +35 -7
  10. package/cli/codegen/mutations.d.ts +2 -0
  11. package/cli/codegen/mutations.js +87 -23
  12. package/cli/codegen/orm/barrel.js +4 -2
  13. package/cli/codegen/orm/index.js +17 -0
  14. package/cli/codegen/orm/input-types-generator.js +83 -29
  15. package/cli/codegen/orm/model-generator.js +6 -4
  16. package/cli/codegen/queries.js +36 -27
  17. package/cli/codegen/scalars.d.ts +6 -4
  18. package/cli/codegen/scalars.js +17 -9
  19. package/cli/codegen/schema-types-generator.d.ts +26 -0
  20. package/cli/codegen/schema-types-generator.js +365 -0
  21. package/cli/codegen/ts-ast.d.ts +3 -1
  22. package/cli/codegen/ts-ast.js +2 -2
  23. package/cli/codegen/type-resolver.d.ts +52 -6
  24. package/cli/codegen/type-resolver.js +97 -19
  25. package/cli/codegen/types.d.ts +7 -4
  26. package/cli/codegen/types.js +94 -41
  27. package/cli/codegen/utils.d.ts +20 -2
  28. package/cli/codegen/utils.js +32 -7
  29. package/cli/commands/generate-orm.js +5 -5
  30. package/cli/commands/generate.d.ts +4 -1
  31. package/cli/commands/generate.js +27 -8
  32. package/cli/introspect/transform-schema.d.ts +33 -21
  33. package/cli/introspect/transform-schema.js +31 -21
  34. package/esm/cli/codegen/barrel.d.ts +4 -1
  35. package/esm/cli/codegen/barrel.js +18 -12
  36. package/esm/cli/codegen/client.js +33 -0
  37. package/esm/cli/codegen/custom-mutations.d.ts +4 -0
  38. package/esm/cli/codegen/custom-mutations.js +40 -14
  39. package/esm/cli/codegen/custom-queries.d.ts +4 -0
  40. package/esm/cli/codegen/custom-queries.js +37 -12
  41. package/esm/cli/codegen/gql-ast.js +10 -6
  42. package/esm/cli/codegen/index.js +35 -7
  43. package/esm/cli/codegen/mutations.d.ts +2 -0
  44. package/esm/cli/codegen/mutations.js +88 -24
  45. package/esm/cli/codegen/orm/barrel.js +4 -2
  46. package/esm/cli/codegen/orm/index.js +17 -0
  47. package/esm/cli/codegen/orm/input-types-generator.js +83 -29
  48. package/esm/cli/codegen/orm/model-generator.js +7 -5
  49. package/esm/cli/codegen/queries.js +37 -28
  50. package/esm/cli/codegen/scalars.d.ts +6 -4
  51. package/esm/cli/codegen/scalars.js +16 -8
  52. package/esm/cli/codegen/schema-types-generator.d.ts +26 -0
  53. package/esm/cli/codegen/schema-types-generator.js +362 -0
  54. package/esm/cli/codegen/ts-ast.d.ts +3 -1
  55. package/esm/cli/codegen/ts-ast.js +2 -2
  56. package/esm/cli/codegen/type-resolver.d.ts +52 -6
  57. package/esm/cli/codegen/type-resolver.js +97 -20
  58. package/esm/cli/codegen/types.d.ts +7 -4
  59. package/esm/cli/codegen/types.js +95 -41
  60. package/esm/cli/codegen/utils.d.ts +20 -2
  61. package/esm/cli/codegen/utils.js +31 -7
  62. package/esm/cli/commands/generate-orm.js +5 -5
  63. package/esm/cli/commands/generate.d.ts +4 -1
  64. package/esm/cli/commands/generate.js +27 -8
  65. package/esm/cli/introspect/transform-schema.d.ts +33 -21
  66. package/esm/cli/introspect/transform-schema.js +31 -21
  67. package/esm/types/schema.d.ts +2 -0
  68. package/package.json +8 -6
  69. package/types/schema.d.ts +2 -0
  70. package/__tests__/codegen/input-types-generator.test.d.ts +0 -1
  71. package/__tests__/codegen/input-types-generator.test.js +0 -635
  72. package/__tests__/codegen/react-query-optional.test.d.ts +0 -1
  73. package/__tests__/codegen/react-query-optional.test.js +0 -292
  74. package/cli/codegen/filters.d.ts +0 -27
  75. package/cli/codegen/filters.js +0 -357
  76. package/cli/codegen/orm/input-types-generator.test.d.ts +0 -1
  77. package/cli/codegen/orm/input-types-generator.test.js +0 -75
  78. package/cli/codegen/orm/select-types.test.d.ts +0 -11
  79. package/cli/codegen/orm/select-types.test.js +0 -22
  80. package/cli/introspect/transform-schema.test.d.ts +0 -1
  81. package/cli/introspect/transform-schema.test.js +0 -67
  82. package/esm/__tests__/codegen/input-types-generator.test.d.ts +0 -1
  83. package/esm/__tests__/codegen/input-types-generator.test.js +0 -633
  84. package/esm/__tests__/codegen/react-query-optional.test.d.ts +0 -1
  85. package/esm/__tests__/codegen/react-query-optional.test.js +0 -290
  86. package/esm/cli/codegen/filters.d.ts +0 -27
  87. package/esm/cli/codegen/filters.js +0 -351
  88. package/esm/cli/codegen/orm/input-types-generator.test.d.ts +0 -1
  89. package/esm/cli/codegen/orm/input-types-generator.test.js +0 -73
  90. package/esm/cli/codegen/orm/select-types.test.d.ts +0 -11
  91. package/esm/cli/codegen/orm/select-types.test.js +0 -21
  92. package/esm/cli/introspect/transform-schema.test.d.ts +0 -1
  93. package/esm/cli/introspect/transform-schema.test.js +0 -65
@@ -15,8 +15,11 @@ export declare function generateQueriesBarrel(tables: CleanTable[]): string;
15
15
  export declare function generateMutationsBarrel(tables: CleanTable[]): string;
16
16
  /**
17
17
  * Generate the main index.ts barrel file
18
+ *
19
+ * @param tables - The tables to include in the SDK
20
+ * @param hasSchemaTypes - Whether schema-types.ts was generated
18
21
  */
19
- export declare function generateMainBarrel(tables: CleanTable[]): string;
22
+ export declare function generateMainBarrel(tables: CleanTable[], hasSchemaTypes?: boolean): string;
20
23
  /**
21
24
  * Generate queries barrel including custom query operations
22
25
  */
@@ -12,10 +12,7 @@ const type_resolver_1 = require("./type-resolver");
12
12
  * Generate the queries/index.ts barrel file
13
13
  */
14
14
  function generateQueriesBarrel(tables) {
15
- const lines = [
16
- (0, ts_ast_1.createFileHeader)('Query hooks barrel export'),
17
- '',
18
- ];
15
+ const lines = [(0, ts_ast_1.createFileHeader)('Query hooks barrel export'), ''];
19
16
  // Export all query hooks
20
17
  for (const table of tables) {
21
18
  const listHookName = (0, utils_1.getListQueryHookName)(table);
@@ -51,31 +48,40 @@ function generateMutationsBarrel(tables) {
51
48
  }
52
49
  /**
53
50
  * Generate the main index.ts barrel file
51
+ *
52
+ * @param tables - The tables to include in the SDK
53
+ * @param hasSchemaTypes - Whether schema-types.ts was generated
54
54
  */
55
- function generateMainBarrel(tables) {
55
+ function generateMainBarrel(tables, hasSchemaTypes = false) {
56
56
  const tableNames = tables.map((t) => t.name).join(', ');
57
+ const schemaTypesExport = hasSchemaTypes
58
+ ? `
59
+ // Schema types (input, payload, enum types)
60
+ export * from './schema-types';
61
+ `
62
+ : '';
57
63
  return `/**
58
64
  * Auto-generated GraphQL SDK
59
65
  * @generated by @constructive-io/graphql-codegen
60
- *
66
+ *
61
67
  * Tables: ${tableNames}
62
- *
68
+ *
63
69
  * Usage:
64
- *
70
+ *
65
71
  * 1. Configure the client:
66
72
  * \`\`\`ts
67
73
  * import { configure } from './generated';
68
- *
74
+ *
69
75
  * configure({
70
76
  * endpoint: 'https://api.example.com/graphql',
71
77
  * headers: { Authorization: 'Bearer <token>' },
72
78
  * });
73
79
  * \`\`\`
74
- *
80
+ *
75
81
  * 2. Use the hooks:
76
82
  * \`\`\`tsx
77
83
  * import { useCarsQuery, useCreateCarMutation } from './generated';
78
- *
84
+ *
79
85
  * function MyComponent() {
80
86
  * const { data, isLoading } = useCarsQuery({ first: 10 });
81
87
  * const { mutate } = useCreateCarMutation();
@@ -89,7 +95,7 @@ export * from './client';
89
95
 
90
96
  // Entity and filter types
91
97
  export * from './types';
92
-
98
+ ${schemaTypesExport}
93
99
  // Query hooks
94
100
  export * from './queries';
95
101
 
@@ -56,6 +56,39 @@ export function getConfig(): GraphQLClientConfig {
56
56
  return globalConfig;
57
57
  }
58
58
 
59
+ /**
60
+ * Set a single header value
61
+ * Useful for updating Authorization after login
62
+ *
63
+ * @example
64
+ * \`\`\`ts
65
+ * setHeader('Authorization', 'Bearer <new-token>');
66
+ * \`\`\`
67
+ */
68
+ export function setHeader(key: string, value: string): void {
69
+ const config = getConfig();
70
+ globalConfig = {
71
+ ...config,
72
+ headers: { ...config.headers, [key]: value },
73
+ };
74
+ }
75
+
76
+ /**
77
+ * Merge multiple headers into the current configuration
78
+ *
79
+ * @example
80
+ * \`\`\`ts
81
+ * setHeaders({ Authorization: 'Bearer <token>', 'X-Custom': 'value' });
82
+ * \`\`\`
83
+ */
84
+ export function setHeaders(headers: Record<string, string>): void {
85
+ const config = getConfig();
86
+ globalConfig = {
87
+ ...config,
88
+ headers: { ...config.headers, ...headers },
89
+ };
90
+ }
91
+
59
92
  // ============================================================================
60
93
  // Error handling
61
94
  // ============================================================================
@@ -23,6 +23,8 @@ export interface GenerateCustomMutationHookOptions {
23
23
  skipQueryField?: boolean;
24
24
  /** Whether to generate React Query hooks (default: true for backwards compatibility) */
25
25
  reactQueryEnabled?: boolean;
26
+ /** Table entity type names (for import path resolution) */
27
+ tableTypeNames?: Set<string>;
26
28
  }
27
29
  /**
28
30
  * Generate a custom mutation hook file
@@ -36,6 +38,8 @@ export interface GenerateAllCustomMutationHooksOptions {
36
38
  skipQueryField?: boolean;
37
39
  /** Whether to generate React Query hooks (default: true for backwards compatibility) */
38
40
  reactQueryEnabled?: boolean;
41
+ /** Table entity type names (for import path resolution) */
42
+ tableTypeNames?: Set<string>;
39
43
  }
40
44
  /**
41
45
  * Generate all custom mutation hook files
@@ -25,13 +25,15 @@ function generateCustomMutationHook(options) {
25
25
  }
26
26
  }
27
27
  function generateCustomMutationHookInternal(options) {
28
- const { operation, typeRegistry, maxDepth = 2, skipQueryField = true } = options;
28
+ const { operation, typeRegistry, maxDepth = 2, skipQueryField = true, tableTypeNames } = options;
29
29
  const project = (0, ts_ast_1.createProject)();
30
30
  const hookName = (0, type_resolver_1.getOperationHookName)(operation.name, 'mutation');
31
31
  const fileName = (0, type_resolver_1.getOperationFileName)(operation.name, 'mutation');
32
32
  const variablesTypeName = (0, type_resolver_1.getOperationVariablesTypeName)(operation.name, 'mutation');
33
33
  const resultTypeName = (0, type_resolver_1.getOperationResultTypeName)(operation.name, 'mutation');
34
34
  const documentConstName = (0, type_resolver_1.getDocumentConstName)(operation.name, 'mutation');
35
+ // Create type tracker to collect referenced types (with table type awareness)
36
+ const tracker = (0, type_resolver_1.createTypeTracker)({ tableTypeNames });
35
37
  // Generate GraphQL document
36
38
  const mutationDocument = (0, schema_gql_ast_1.buildCustomMutationString)({
37
39
  operation,
@@ -42,8 +44,21 @@ function generateCustomMutationHookInternal(options) {
42
44
  const sourceFile = (0, ts_ast_1.createSourceFile)(project, fileName);
43
45
  // Add file header
44
46
  sourceFile.insertText(0, (0, ts_ast_1.createFileHeader)(`Custom mutation hook for ${operation.name}`) + '\n\n');
47
+ // Generate variables interface if there are arguments (with tracking)
48
+ let variablesProps = [];
49
+ if (operation.args.length > 0) {
50
+ variablesProps = generateVariablesProperties(operation.args, tracker);
51
+ }
52
+ // Generate result interface (with tracking)
53
+ const resultType = (0, type_resolver_1.typeRefToTsType)(operation.returnType, tracker);
54
+ const resultProps = [
55
+ { name: operation.name, type: resultType },
56
+ ];
57
+ // Get importable types from tracker (separated by source)
58
+ const schemaTypes = tracker.getImportableTypes(); // From schema-types.ts
59
+ const tableTypes = tracker.getTableTypes(); // From types.ts
45
60
  // Add imports
46
- sourceFile.addImportDeclarations([
61
+ const imports = [
47
62
  (0, ts_ast_1.createImport)({
48
63
  moduleSpecifier: '@tanstack/react-query',
49
64
  namedImports: ['useMutation'],
@@ -53,21 +68,31 @@ function generateCustomMutationHookInternal(options) {
53
68
  moduleSpecifier: '../client',
54
69
  namedImports: ['execute'],
55
70
  }),
56
- ]);
71
+ ];
72
+ // Add types.ts import for table entity types
73
+ if (tableTypes.length > 0) {
74
+ imports.push((0, ts_ast_1.createImport)({
75
+ moduleSpecifier: '../types',
76
+ typeOnlyNamedImports: tableTypes,
77
+ }));
78
+ }
79
+ // Add schema-types import for Input/Payload/Enum types
80
+ if (schemaTypes.length > 0) {
81
+ imports.push((0, ts_ast_1.createImport)({
82
+ moduleSpecifier: '../schema-types',
83
+ typeOnlyNamedImports: schemaTypes,
84
+ }));
85
+ }
86
+ sourceFile.addImportDeclarations(imports);
57
87
  // Add mutation document constant
58
88
  sourceFile.addVariableStatement((0, ts_ast_1.createConst)(documentConstName, '`\n' + mutationDocument + '`', {
59
89
  docs: ['GraphQL mutation document'],
60
90
  }));
61
- // Generate variables interface if there are arguments
91
+ // Add variables interface
62
92
  if (operation.args.length > 0) {
63
- const variablesProps = generateVariablesProperties(operation.args);
64
93
  sourceFile.addInterface((0, ts_ast_1.createInterface)(variablesTypeName, variablesProps));
65
94
  }
66
- // Generate result interface
67
- const resultType = (0, type_resolver_1.typeRefToTsType)(operation.returnType);
68
- const resultProps = [
69
- { name: operation.name, type: resultType },
70
- ];
95
+ // Add result interface
71
96
  sourceFile.addInterface((0, ts_ast_1.createInterface)(resultTypeName, resultProps));
72
97
  // Generate hook function
73
98
  const hookParams = generateHookParameters(operation, variablesTypeName, resultTypeName);
@@ -91,10 +116,10 @@ function generateCustomMutationHookInternal(options) {
91
116
  /**
92
117
  * Generate interface properties from CleanArguments
93
118
  */
94
- function generateVariablesProperties(args) {
119
+ function generateVariablesProperties(args, tracker) {
95
120
  return args.map((arg) => ({
96
121
  name: arg.name,
97
- type: (0, type_resolver_1.typeRefToTsType)(arg.type),
122
+ type: (0, type_resolver_1.typeRefToTsType)(arg.type, tracker),
98
123
  optional: !(0, type_resolver_1.isTypeRequired)(arg.type),
99
124
  docs: arg.description ? [arg.description] : undefined,
100
125
  }));
@@ -143,7 +168,7 @@ function generateHookBody(operation, documentConstName, variablesTypeName, resul
143
168
  * When reactQueryEnabled is false, returns empty array since mutations require React Query
144
169
  */
145
170
  function generateAllCustomMutationHooks(options) {
146
- const { operations, typeRegistry, maxDepth = 2, skipQueryField = true, reactQueryEnabled = true } = options;
171
+ const { operations, typeRegistry, maxDepth = 2, skipQueryField = true, reactQueryEnabled = true, tableTypeNames } = options;
147
172
  return operations
148
173
  .filter((op) => op.kind === 'mutation')
149
174
  .map((operation) => generateCustomMutationHook({
@@ -152,6 +177,7 @@ function generateAllCustomMutationHooks(options) {
152
177
  maxDepth,
153
178
  skipQueryField,
154
179
  reactQueryEnabled,
180
+ tableTypeNames,
155
181
  }))
156
182
  .filter((result) => result !== null);
157
183
  }
@@ -23,6 +23,8 @@ export interface GenerateCustomQueryHookOptions {
23
23
  skipQueryField?: boolean;
24
24
  /** Whether to generate React Query hooks (default: true for backwards compatibility) */
25
25
  reactQueryEnabled?: boolean;
26
+ /** Table entity type names (for import path resolution) */
27
+ tableTypeNames?: Set<string>;
26
28
  }
27
29
  /**
28
30
  * Generate a custom query hook file
@@ -35,6 +37,8 @@ export interface GenerateAllCustomQueryHooksOptions {
35
37
  skipQueryField?: boolean;
36
38
  /** Whether to generate React Query hooks (default: true for backwards compatibility) */
37
39
  reactQueryEnabled?: boolean;
40
+ /** Table entity type names (for import path resolution) */
41
+ tableTypeNames?: Set<string>;
38
42
  }
39
43
  /**
40
44
  * Generate all custom query hook files
@@ -10,7 +10,7 @@ const utils_1 = require("./utils");
10
10
  * Generate a custom query hook file
11
11
  */
12
12
  function generateCustomQueryHook(options) {
13
- const { operation, typeRegistry, maxDepth = 2, skipQueryField = true, reactQueryEnabled = true } = options;
13
+ const { operation, typeRegistry, maxDepth = 2, skipQueryField = true, reactQueryEnabled = true, tableTypeNames } = options;
14
14
  const project = (0, ts_ast_1.createProject)();
15
15
  const hookName = (0, type_resolver_1.getOperationHookName)(operation.name, 'query');
16
16
  const fileName = (0, type_resolver_1.getOperationFileName)(operation.name, 'query');
@@ -18,6 +18,8 @@ function generateCustomQueryHook(options) {
18
18
  const resultTypeName = (0, type_resolver_1.getOperationResultTypeName)(operation.name, 'query');
19
19
  const documentConstName = (0, type_resolver_1.getDocumentConstName)(operation.name, 'query');
20
20
  const queryKeyName = (0, type_resolver_1.getQueryKeyName)(operation.name);
21
+ // Create type tracker to collect referenced types (with table type awareness)
22
+ const tracker = (0, type_resolver_1.createTypeTracker)({ tableTypeNames });
21
23
  // Generate GraphQL document
22
24
  const queryDocument = (0, schema_gql_ast_1.buildCustomQueryString)({
23
25
  operation,
@@ -31,6 +33,19 @@ function generateCustomQueryHook(options) {
31
33
  ? `Custom query hook for ${operation.name}`
32
34
  : `Custom query functions for ${operation.name}`;
33
35
  sourceFile.insertText(0, (0, ts_ast_1.createFileHeader)(headerText) + '\n\n');
36
+ // Generate variables interface if there are arguments (with tracking)
37
+ let variablesProps = [];
38
+ if (operation.args.length > 0) {
39
+ variablesProps = generateVariablesProperties(operation.args, tracker);
40
+ }
41
+ // Generate result interface (with tracking)
42
+ const resultType = (0, type_resolver_1.typeRefToTsType)(operation.returnType, tracker);
43
+ const resultProps = [
44
+ { name: operation.name, type: resultType },
45
+ ];
46
+ // Get importable types from tracker (separated by source)
47
+ const schemaTypes = tracker.getImportableTypes(); // From schema-types.ts
48
+ const tableTypes = tracker.getTableTypes(); // From types.ts
34
49
  // Add imports - conditionally include React Query imports
35
50
  const imports = [];
36
51
  if (reactQueryEnabled) {
@@ -45,21 +60,30 @@ function generateCustomQueryHook(options) {
45
60
  namedImports: ['execute'],
46
61
  typeOnlyNamedImports: ['ExecuteOptions'],
47
62
  }));
63
+ // Add types.ts import for table entity types
64
+ if (tableTypes.length > 0) {
65
+ imports.push((0, ts_ast_1.createImport)({
66
+ moduleSpecifier: '../types',
67
+ typeOnlyNamedImports: tableTypes,
68
+ }));
69
+ }
70
+ // Add schema-types import for Input/Payload/Enum types
71
+ if (schemaTypes.length > 0) {
72
+ imports.push((0, ts_ast_1.createImport)({
73
+ moduleSpecifier: '../schema-types',
74
+ typeOnlyNamedImports: schemaTypes,
75
+ }));
76
+ }
48
77
  sourceFile.addImportDeclarations(imports);
49
78
  // Add query document constant
50
79
  sourceFile.addVariableStatement((0, ts_ast_1.createConst)(documentConstName, '`\n' + queryDocument + '`', {
51
80
  docs: ['GraphQL query document'],
52
81
  }));
53
- // Generate variables interface if there are arguments
82
+ // Add variables interface
54
83
  if (operation.args.length > 0) {
55
- const variablesProps = generateVariablesProperties(operation.args);
56
84
  sourceFile.addInterface((0, ts_ast_1.createInterface)(variablesTypeName, variablesProps));
57
85
  }
58
- // Generate result interface
59
- const resultType = (0, type_resolver_1.typeRefToTsType)(operation.returnType);
60
- const resultProps = [
61
- { name: operation.name, type: resultType },
62
- ];
86
+ // Add result interface
63
87
  sourceFile.addInterface((0, ts_ast_1.createInterface)(resultTypeName, resultProps));
64
88
  // Query key factory
65
89
  if (operation.args.length > 0) {
@@ -130,10 +154,10 @@ function generateCustomQueryHook(options) {
130
154
  /**
131
155
  * Generate interface properties from CleanArguments
132
156
  */
133
- function generateVariablesProperties(args) {
157
+ function generateVariablesProperties(args, tracker) {
134
158
  return args.map((arg) => ({
135
159
  name: arg.name,
136
- type: (0, type_resolver_1.typeRefToTsType)(arg.type),
160
+ type: (0, type_resolver_1.typeRefToTsType)(arg.type, tracker),
137
161
  optional: !(0, type_resolver_1.isTypeRequired)(arg.type),
138
162
  docs: arg.description ? [arg.description] : undefined,
139
163
  }));
@@ -355,7 +379,7 @@ await ${fnName}(queryClient);
355
379
  * Generate all custom query hook files
356
380
  */
357
381
  function generateAllCustomQueryHooks(options) {
358
- const { operations, typeRegistry, maxDepth = 2, skipQueryField = true, reactQueryEnabled = true } = options;
382
+ const { operations, typeRegistry, maxDepth = 2, skipQueryField = true, reactQueryEnabled = true, tableTypeNames } = options;
359
383
  return operations
360
384
  .filter((op) => op.kind === 'query')
361
385
  .map((operation) => generateCustomQueryHook({
@@ -364,5 +388,6 @@ function generateAllCustomQueryHooks(options) {
364
388
  maxDepth,
365
389
  skipQueryField,
366
390
  reactQueryEnabled,
391
+ tableTypeNames,
367
392
  }));
368
393
  }
@@ -147,16 +147,20 @@ function buildSingleQueryAST(config) {
147
147
  const { table } = config;
148
148
  const queryName = (0, utils_1.getSingleRowQueryName)(table);
149
149
  const scalarFields = (0, utils_1.getScalarFields)(table);
150
- // Variable definitions - assume UUID primary key
150
+ // Get primary key info dynamically from table constraints
151
+ const pkFields = (0, utils_1.getPrimaryKeyInfo)(table);
152
+ // For simplicity, use first PK field (most common case)
153
+ const pkField = pkFields[0];
154
+ // Variable definitions - use dynamic PK field name and type
151
155
  const variableDefinitions = [
152
156
  t.variableDefinition({
153
- variable: t.variable({ name: 'id' }),
154
- type: t.nonNullType({ type: t.namedType({ type: 'UUID' }) }),
157
+ variable: t.variable({ name: pkField.name }),
158
+ type: t.nonNullType({ type: t.namedType({ type: pkField.gqlType }) }),
155
159
  }),
156
160
  ];
157
- // Query arguments
161
+ // Query arguments - use dynamic PK field name
158
162
  const args = [
159
- t.argument({ name: 'id', value: t.variable({ name: 'id' }) }),
163
+ t.argument({ name: pkField.name, value: t.variable({ name: pkField.name }) }),
160
164
  ];
161
165
  // Field selections
162
166
  const fieldSelections = createFieldSelections(scalarFields);
@@ -5,11 +5,13 @@ exports.generateAllFiles = generateAllFiles;
5
5
  exports.generate = generate;
6
6
  const client_1 = require("./client");
7
7
  const types_1 = require("./types");
8
+ const schema_types_generator_1 = require("./schema-types-generator");
8
9
  const queries_1 = require("./queries");
9
10
  const mutations_1 = require("./mutations");
10
11
  const custom_queries_1 = require("./custom-queries");
11
12
  const custom_mutations_1 = require("./custom-mutations");
12
13
  const barrel_1 = require("./barrel");
14
+ const utils_1 = require("./utils");
13
15
  // ============================================================================
14
16
  // Main orchestrator
15
17
  // ============================================================================
@@ -34,12 +36,33 @@ function generate(options) {
34
36
  path: 'client.ts',
35
37
  content: (0, client_1.generateClientFile)(),
36
38
  });
37
- // 2. Generate types.ts
39
+ // Collect table type names for import path resolution
40
+ const tableTypeNames = new Set(tables.map((t) => (0, utils_1.getTableNames)(t).typeName));
41
+ // 2. Generate schema-types.ts for custom operations (if any)
42
+ // NOTE: This must come BEFORE types.ts so that types.ts can import enum types
43
+ let hasSchemaTypes = false;
44
+ let generatedEnumNames = [];
45
+ if (customOperations && customOperations.typeRegistry) {
46
+ const schemaTypesResult = (0, schema_types_generator_1.generateSchemaTypesFile)({
47
+ typeRegistry: customOperations.typeRegistry,
48
+ tableTypeNames,
49
+ });
50
+ // Only include if there's meaningful content
51
+ if (schemaTypesResult.content.split('\n').length > 10) {
52
+ files.push({
53
+ path: 'schema-types.ts',
54
+ content: schemaTypesResult.content,
55
+ });
56
+ hasSchemaTypes = true;
57
+ generatedEnumNames = schemaTypesResult.generatedEnums || [];
58
+ }
59
+ }
60
+ // 3. Generate types.ts (can now import enums from schema-types)
38
61
  files.push({
39
62
  path: 'types.ts',
40
- content: (0, types_1.generateTypesFile)(tables),
63
+ content: (0, types_1.generateTypesFile)(tables, { enumsFromSchemaTypes: generatedEnumNames }),
41
64
  });
42
- // 3. Generate table-based query hooks (queries/*.ts)
65
+ // 4. Generate table-based query hooks (queries/*.ts)
43
66
  const queryHooks = (0, queries_1.generateAllQueryHooks)(tables, { reactQueryEnabled });
44
67
  for (const hook of queryHooks) {
45
68
  files.push({
@@ -47,7 +70,7 @@ function generate(options) {
47
70
  content: hook.content,
48
71
  });
49
72
  }
50
- // 4. Generate custom query hooks if available
73
+ // 5. Generate custom query hooks if available
51
74
  let customQueryHooks = [];
52
75
  if (customOperations && customOperations.queries.length > 0) {
53
76
  customQueryHooks = (0, custom_queries_1.generateAllCustomQueryHooks)({
@@ -56,6 +79,7 @@ function generate(options) {
56
79
  maxDepth,
57
80
  skipQueryField,
58
81
  reactQueryEnabled,
82
+ tableTypeNames,
59
83
  });
60
84
  for (const hook of customQueryHooks) {
61
85
  files.push({
@@ -72,7 +96,10 @@ function generate(options) {
72
96
  : (0, barrel_1.generateQueriesBarrel)(tables),
73
97
  });
74
98
  // 6. Generate table-based mutation hooks (mutations/*.ts)
75
- const mutationHooks = (0, mutations_1.generateAllMutationHooks)(tables, { reactQueryEnabled });
99
+ const mutationHooks = (0, mutations_1.generateAllMutationHooks)(tables, {
100
+ reactQueryEnabled,
101
+ enumsFromSchemaTypes: generatedEnumNames,
102
+ });
76
103
  for (const hook of mutationHooks) {
77
104
  files.push({
78
105
  path: `mutations/${hook.fileName}`,
@@ -88,6 +115,7 @@ function generate(options) {
88
115
  maxDepth,
89
116
  skipQueryField,
90
117
  reactQueryEnabled,
118
+ tableTypeNames,
91
119
  });
92
120
  for (const hook of customMutationHooks) {
93
121
  files.push({
@@ -103,10 +131,10 @@ function generate(options) {
103
131
  ? (0, barrel_1.generateCustomMutationsBarrel)(tables, customMutationHooks.map((h) => h.operationName))
104
132
  : (0, barrel_1.generateMutationsBarrel)(tables),
105
133
  });
106
- // 9. Generate main index.ts barrel
134
+ // 9. Generate main index.ts barrel (with schema-types if present)
107
135
  files.push({
108
136
  path: 'index.ts',
109
- content: (0, barrel_1.generateMainBarrel)(tables),
137
+ content: (0, barrel_1.generateMainBarrel)(tables, hasSchemaTypes),
110
138
  });
111
139
  return {
112
140
  files,
@@ -15,6 +15,8 @@ export interface GeneratedMutationFile {
15
15
  export interface MutationGeneratorOptions {
16
16
  /** Whether to generate React Query hooks (default: true for backwards compatibility) */
17
17
  reactQueryEnabled?: boolean;
18
+ /** Enum type names that are available from schema-types.ts */
19
+ enumsFromSchemaTypes?: string[];
18
20
  }
19
21
  /**
20
22
  * Generate create mutation hook file content using AST