@constructive-io/graphql-codegen 2.23.3 → 2.24.1

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 (92) hide show
  1. package/README.md +147 -2
  2. package/cli/codegen/babel-ast.d.ts +53 -0
  3. package/cli/codegen/babel-ast.js +160 -0
  4. package/cli/codegen/barrel.d.ts +7 -2
  5. package/cli/codegen/barrel.js +193 -102
  6. package/cli/codegen/client.js +61 -0
  7. package/cli/codegen/custom-mutations.d.ts +2 -12
  8. package/cli/codegen/custom-mutations.js +116 -124
  9. package/cli/codegen/custom-queries.d.ts +2 -10
  10. package/cli/codegen/custom-queries.js +236 -335
  11. package/cli/codegen/gql-ast.js +22 -1
  12. package/cli/codegen/index.d.ts +3 -0
  13. package/cli/codegen/index.js +73 -3
  14. package/cli/codegen/invalidation.d.ts +20 -0
  15. package/cli/codegen/invalidation.js +327 -0
  16. package/cli/codegen/mutation-keys.d.ts +24 -0
  17. package/cli/codegen/mutation-keys.js +247 -0
  18. package/cli/codegen/mutations.d.ts +5 -19
  19. package/cli/codegen/mutations.js +385 -383
  20. package/cli/codegen/orm/barrel.d.ts +1 -1
  21. package/cli/codegen/orm/barrel.js +42 -10
  22. package/cli/codegen/orm/client-generator.d.ts +1 -19
  23. package/cli/codegen/orm/client-generator.js +108 -77
  24. package/cli/codegen/orm/custom-ops-generator.d.ts +1 -12
  25. package/cli/codegen/orm/custom-ops-generator.js +192 -235
  26. package/cli/codegen/orm/input-types-generator.d.ts +13 -1
  27. package/cli/codegen/orm/input-types-generator.js +425 -147
  28. package/cli/codegen/orm/model-generator.d.ts +1 -19
  29. package/cli/codegen/orm/model-generator.js +229 -234
  30. package/cli/codegen/queries.d.ts +4 -12
  31. package/cli/codegen/queries.js +660 -390
  32. package/cli/codegen/query-keys.d.ts +15 -0
  33. package/cli/codegen/query-keys.js +477 -0
  34. package/cli/codegen/scalars.js +1 -0
  35. package/cli/codegen/schema-types-generator.d.ts +15 -10
  36. package/cli/codegen/schema-types-generator.js +87 -175
  37. package/cli/codegen/type-resolver.d.ts +1 -30
  38. package/cli/codegen/type-resolver.js +0 -53
  39. package/cli/codegen/types.d.ts +1 -1
  40. package/cli/codegen/types.js +76 -21
  41. package/cli/codegen/utils.d.ts +6 -0
  42. package/cli/codegen/utils.js +19 -0
  43. package/esm/cli/codegen/babel-ast.d.ts +53 -0
  44. package/esm/cli/codegen/babel-ast.js +111 -0
  45. package/esm/cli/codegen/barrel.d.ts +7 -2
  46. package/esm/cli/codegen/barrel.js +161 -103
  47. package/esm/cli/codegen/client.js +61 -0
  48. package/esm/cli/codegen/custom-mutations.d.ts +2 -12
  49. package/esm/cli/codegen/custom-mutations.js +83 -124
  50. package/esm/cli/codegen/custom-queries.d.ts +2 -10
  51. package/esm/cli/codegen/custom-queries.js +204 -336
  52. package/esm/cli/codegen/gql-ast.js +23 -2
  53. package/esm/cli/codegen/index.d.ts +3 -0
  54. package/esm/cli/codegen/index.js +69 -2
  55. package/esm/cli/codegen/invalidation.d.ts +20 -0
  56. package/esm/cli/codegen/invalidation.js +291 -0
  57. package/esm/cli/codegen/mutation-keys.d.ts +24 -0
  58. package/esm/cli/codegen/mutation-keys.js +211 -0
  59. package/esm/cli/codegen/mutations.d.ts +5 -19
  60. package/esm/cli/codegen/mutations.js +353 -384
  61. package/esm/cli/codegen/orm/barrel.d.ts +1 -1
  62. package/esm/cli/codegen/orm/barrel.js +10 -11
  63. package/esm/cli/codegen/orm/client-generator.d.ts +1 -19
  64. package/esm/cli/codegen/orm/client-generator.js +76 -78
  65. package/esm/cli/codegen/orm/custom-ops-generator.d.ts +1 -12
  66. package/esm/cli/codegen/orm/custom-ops-generator.js +160 -236
  67. package/esm/cli/codegen/orm/input-types-generator.d.ts +13 -1
  68. package/esm/cli/codegen/orm/input-types-generator.js +393 -148
  69. package/esm/cli/codegen/orm/model-generator.d.ts +1 -19
  70. package/esm/cli/codegen/orm/model-generator.js +197 -235
  71. package/esm/cli/codegen/queries.d.ts +4 -12
  72. package/esm/cli/codegen/queries.js +628 -391
  73. package/esm/cli/codegen/query-keys.d.ts +15 -0
  74. package/esm/cli/codegen/query-keys.js +441 -0
  75. package/esm/cli/codegen/scalars.js +1 -0
  76. package/esm/cli/codegen/schema-types-generator.d.ts +15 -10
  77. package/esm/cli/codegen/schema-types-generator.js +54 -175
  78. package/esm/cli/codegen/type-resolver.d.ts +1 -30
  79. package/esm/cli/codegen/type-resolver.js +0 -49
  80. package/esm/cli/codegen/types.d.ts +1 -1
  81. package/esm/cli/codegen/types.js +44 -22
  82. package/esm/cli/codegen/utils.d.ts +6 -0
  83. package/esm/cli/codegen/utils.js +18 -0
  84. package/esm/types/config.d.ts +75 -0
  85. package/esm/types/config.js +18 -0
  86. package/package.json +6 -4
  87. package/types/config.d.ts +75 -0
  88. package/types/config.js +19 -1
  89. package/cli/codegen/ts-ast.d.ts +0 -124
  90. package/cli/codegen/ts-ast.js +0 -280
  91. package/esm/cli/codegen/ts-ast.d.ts +0 -124
  92. package/esm/cli/codegen/ts-ast.js +0 -260
@@ -1,19 +1,7 @@
1
1
  /**
2
- * Model class generator for ORM client
2
+ * Model class generator for ORM client (Babel AST-based)
3
3
  *
4
4
  * Generates per-table model classes with findMany, findFirst, create, update, delete methods.
5
- *
6
- * Example output:
7
- * ```typescript
8
- * export class UserModel {
9
- * constructor(private client: OrmClient) {}
10
- *
11
- * findMany<S extends UserSelect>(args?: FindManyArgs<S, UserWhereInput, UserOrderBy>) {
12
- * return new QueryBuilder<...>({ ... });
13
- * }
14
- * // ...
15
- * }
16
- * ```
17
5
  */
18
6
  import type { CleanTable } from '../../../types/schema';
19
7
  export interface GeneratedModelFile {
@@ -22,11 +10,5 @@ export interface GeneratedModelFile {
22
10
  modelName: string;
23
11
  tableName: string;
24
12
  }
25
- /**
26
- * Generate a model class file for a table
27
- */
28
13
  export declare function generateModelFile(table: CleanTable, _useSharedTypes: boolean): GeneratedModelFile;
29
- /**
30
- * Generate all model files for a list of tables
31
- */
32
14
  export declare function generateAllModelFiles(tables: CleanTable[], useSharedTypes: boolean): GeneratedModelFile[];
@@ -1,21 +1,85 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
36
  exports.generateModelFile = generateModelFile;
4
37
  exports.generateAllModelFiles = generateAllModelFiles;
5
- const ts_ast_1 = require("../ts-ast");
38
+ const t = __importStar(require("@babel/types"));
39
+ const babel_ast_1 = require("../babel-ast");
6
40
  const utils_1 = require("../utils");
7
- /**
8
- * Generate a model class file for a table
9
- */
41
+ function createImportDeclaration(moduleSpecifier, namedImports, typeOnly = false) {
42
+ const specifiers = namedImports.map((name) => t.importSpecifier(t.identifier(name), t.identifier(name)));
43
+ const decl = t.importDeclaration(specifiers, t.stringLiteral(moduleSpecifier));
44
+ decl.importKind = typeOnly ? 'type' : 'value';
45
+ return decl;
46
+ }
47
+ function buildMethodBody(builderFn, args, operation, typeName, fieldName) {
48
+ const destructureDecl = t.variableDeclaration('const', [
49
+ t.variableDeclarator(t.objectPattern([
50
+ t.objectProperty(t.identifier('document'), t.identifier('document'), false, true),
51
+ t.objectProperty(t.identifier('variables'), t.identifier('variables'), false, true),
52
+ ]), t.callExpression(t.identifier(builderFn), args)),
53
+ ]);
54
+ const returnStmt = t.returnStatement(t.newExpression(t.identifier('QueryBuilder'), [
55
+ t.objectExpression([
56
+ t.objectProperty(t.identifier('client'), t.memberExpression(t.thisExpression(), t.identifier('client'))),
57
+ t.objectProperty(t.identifier('operation'), t.stringLiteral(operation)),
58
+ t.objectProperty(t.identifier('operationName'), t.stringLiteral(typeName)),
59
+ t.objectProperty(t.identifier('fieldName'), t.stringLiteral(fieldName)),
60
+ t.objectProperty(t.identifier('document'), t.identifier('document'), false, true),
61
+ t.objectProperty(t.identifier('variables'), t.identifier('variables'), false, true),
62
+ ]),
63
+ ]));
64
+ return [destructureDecl, returnStmt];
65
+ }
66
+ function createClassMethod(name, typeParameters, params, returnType, body) {
67
+ const method = t.classMethod('method', t.identifier(name), params, t.blockStatement(body));
68
+ method.typeParameters = typeParameters;
69
+ method.returnType = returnType;
70
+ return method;
71
+ }
72
+ function createConstTypeParam(constraintTypeName) {
73
+ const param = t.tsTypeParameter(t.tsTypeReference(t.identifier(constraintTypeName)), null, 'S');
74
+ param.const = true;
75
+ return t.tsTypeParameterDeclaration([param]);
76
+ }
10
77
  function generateModelFile(table, _useSharedTypes) {
11
- const project = (0, ts_ast_1.createProject)();
12
78
  const { typeName, singularName, pluralName } = (0, utils_1.getTableNames)(table);
13
79
  const modelName = `${typeName}Model`;
14
- // Avoid "index.ts" which clashes with barrel file
15
80
  const baseFileName = (0, utils_1.lcFirst)(typeName);
16
81
  const fileName = baseFileName === 'index' ? `${baseFileName}Model.ts` : `${baseFileName}.ts`;
17
82
  const entityLower = singularName;
18
- // Type names for this entity - use inflection from table metadata
19
83
  const selectTypeName = `${typeName}Select`;
20
84
  const relationTypeName = `${typeName}WithRelations`;
21
85
  const whereTypeName = (0, utils_1.getFilterTypeName)(table);
@@ -24,244 +88,175 @@ function generateModelFile(table, _useSharedTypes) {
24
88
  const updateInputTypeName = `Update${typeName}Input`;
25
89
  const deleteInputTypeName = `Delete${typeName}Input`;
26
90
  const patchTypeName = `${typeName}Patch`;
27
- const createDataType = `${createInputTypeName}['${singularName}']`;
28
- // Query names from PostGraphile
29
91
  const pluralQueryName = table.query?.all ?? pluralName;
30
92
  const createMutationName = table.query?.create ?? `create${typeName}`;
31
93
  const updateMutationName = table.query?.update;
32
94
  const deleteMutationName = table.query?.delete;
33
- const sourceFile = (0, ts_ast_1.createSourceFile)(project, fileName);
34
- // Add file header
35
- sourceFile.insertText(0, (0, ts_ast_1.createFileHeader)(`${typeName} model for ORM client`) + '\n\n');
36
- // Add imports - import types from respective modules
37
- sourceFile.addImportDeclarations([
38
- (0, ts_ast_1.createImport)({
39
- moduleSpecifier: '../client',
40
- namedImports: ['OrmClient'],
41
- }),
42
- (0, ts_ast_1.createImport)({
43
- moduleSpecifier: '../query-builder',
44
- namedImports: [
45
- 'QueryBuilder',
46
- 'buildFindManyDocument',
47
- 'buildFindFirstDocument',
48
- 'buildCreateDocument',
49
- 'buildUpdateDocument',
50
- 'buildDeleteDocument',
51
- ],
52
- }),
53
- (0, ts_ast_1.createImport)({
54
- moduleSpecifier: '../select-types',
55
- typeOnlyNamedImports: [
56
- 'ConnectionResult',
57
- 'FindManyArgs',
58
- 'FindFirstArgs',
59
- 'CreateArgs',
60
- 'UpdateArgs',
61
- 'DeleteArgs',
62
- 'InferSelectResult',
63
- ],
64
- }),
65
- ]);
66
- // Build complete set of input-types imports
67
- // Select types are now centralized in input-types.ts with relations included
68
- const inputTypeImports = new Set([
69
- typeName,
70
- relationTypeName,
71
- selectTypeName,
72
- whereTypeName,
73
- orderByTypeName,
74
- createInputTypeName,
75
- updateInputTypeName,
76
- patchTypeName,
77
- ]);
78
- // Add single combined import from input-types
79
- sourceFile.addImportDeclaration((0, ts_ast_1.createImport)({
80
- moduleSpecifier: '../input-types',
81
- typeOnlyNamedImports: Array.from(inputTypeImports),
82
- }));
83
- // Add Model class
84
- sourceFile.addStatements('\n// ============================================================================');
85
- sourceFile.addStatements('// Model Class');
86
- sourceFile.addStatements('// ============================================================================\n');
87
- // Generate the model class
88
- const classDeclaration = sourceFile.addClass({
89
- name: modelName,
90
- isExported: true,
91
- });
95
+ const statements = [];
96
+ statements.push(createImportDeclaration('../client', ['OrmClient']));
97
+ statements.push(createImportDeclaration('../query-builder', [
98
+ 'QueryBuilder', 'buildFindManyDocument', 'buildFindFirstDocument',
99
+ 'buildCreateDocument', 'buildUpdateDocument', 'buildDeleteDocument',
100
+ ]));
101
+ statements.push(createImportDeclaration('../select-types', [
102
+ 'ConnectionResult', 'FindManyArgs', 'FindFirstArgs', 'CreateArgs',
103
+ 'UpdateArgs', 'DeleteArgs', 'InferSelectResult',
104
+ ], true));
105
+ statements.push(createImportDeclaration('../input-types', [
106
+ typeName, relationTypeName, selectTypeName, whereTypeName, orderByTypeName,
107
+ createInputTypeName, updateInputTypeName, patchTypeName,
108
+ ], true));
109
+ const classBody = [];
92
110
  // Constructor
93
- classDeclaration.addConstructor({
94
- parameters: [
95
- {
96
- name: 'client',
97
- type: 'OrmClient',
98
- scope: 'private',
99
- },
100
- ],
101
- });
102
- // findMany method - uses const generic for proper literal type inference
103
- classDeclaration.addMethod({
104
- name: 'findMany',
105
- typeParameters: [`const S extends ${selectTypeName}`],
106
- parameters: [
107
- {
108
- name: 'args',
109
- type: `FindManyArgs<S, ${whereTypeName}, ${orderByTypeName}>`,
110
- hasQuestionToken: true,
111
- },
112
- ],
113
- returnType: `QueryBuilder<{ ${pluralQueryName}: ConnectionResult<InferSelectResult<${relationTypeName}, S>> }>`,
114
- statements: `const { document, variables } = buildFindManyDocument(
115
- '${typeName}',
116
- '${pluralQueryName}',
117
- args?.select,
118
- {
119
- where: args?.where,
120
- orderBy: args?.orderBy as string[] | undefined,
121
- first: args?.first,
122
- last: args?.last,
123
- after: args?.after,
124
- before: args?.before,
125
- offset: args?.offset,
126
- },
127
- '${whereTypeName}',
128
- '${orderByTypeName}'
129
- );
130
- return new QueryBuilder({
131
- client: this.client,
132
- operation: 'query',
133
- operationName: '${typeName}',
134
- fieldName: '${pluralQueryName}',
135
- document,
136
- variables,
137
- });`,
138
- });
139
- // findFirst method - uses const generic for proper literal type inference
140
- classDeclaration.addMethod({
141
- name: 'findFirst',
142
- typeParameters: [`const S extends ${selectTypeName}`],
143
- parameters: [
144
- {
145
- name: 'args',
146
- type: `FindFirstArgs<S, ${whereTypeName}>`,
147
- hasQuestionToken: true,
148
- },
149
- ],
150
- returnType: `QueryBuilder<{ ${pluralQueryName}: { nodes: InferSelectResult<${relationTypeName}, S>[] } }>`,
151
- statements: `const { document, variables } = buildFindFirstDocument(
152
- '${typeName}',
153
- '${pluralQueryName}',
154
- args?.select,
155
- { where: args?.where },
156
- '${whereTypeName}'
157
- );
158
- return new QueryBuilder({
159
- client: this.client,
160
- operation: 'query',
161
- operationName: '${typeName}',
162
- fieldName: '${pluralQueryName}',
163
- document,
164
- variables,
165
- });`,
166
- });
167
- // create method - uses const generic for proper literal type inference
168
- classDeclaration.addMethod({
169
- name: 'create',
170
- typeParameters: [`const S extends ${selectTypeName}`],
171
- parameters: [
172
- {
173
- name: 'args',
174
- type: `CreateArgs<S, ${createDataType}>`,
175
- },
176
- ],
177
- returnType: `QueryBuilder<{ ${createMutationName}: { ${entityLower}: InferSelectResult<${relationTypeName}, S> } }>`,
178
- statements: `const { document, variables } = buildCreateDocument(
179
- '${typeName}',
180
- '${createMutationName}',
181
- '${entityLower}',
182
- args.select,
183
- args.data,
184
- '${createInputTypeName}'
185
- );
186
- return new QueryBuilder({
187
- client: this.client,
188
- operation: 'mutation',
189
- operationName: '${typeName}',
190
- fieldName: '${createMutationName}',
191
- document,
192
- variables,
193
- });`,
194
- });
195
- // update method (if available) - uses const generic for proper literal type inference
111
+ const constructorParam = t.identifier('client');
112
+ constructorParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('OrmClient')));
113
+ const paramProp = t.tsParameterProperty(constructorParam);
114
+ paramProp.accessibility = 'private';
115
+ classBody.push(t.classMethod('constructor', t.identifier('constructor'), [paramProp], t.blockStatement([])));
116
+ // findMany method
117
+ const findManyParam = t.identifier('args');
118
+ findManyParam.optional = true;
119
+ findManyParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('FindManyArgs'), t.tsTypeParameterInstantiation([
120
+ t.tsTypeReference(t.identifier('S')),
121
+ t.tsTypeReference(t.identifier(whereTypeName)),
122
+ t.tsTypeReference(t.identifier(orderByTypeName)),
123
+ ])));
124
+ const findManyReturnType = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('QueryBuilder'), t.tsTypeParameterInstantiation([
125
+ t.tsTypeLiteral([
126
+ t.tsPropertySignature(t.identifier(pluralQueryName), t.tsTypeAnnotation(t.tsTypeReference(t.identifier('ConnectionResult'), t.tsTypeParameterInstantiation([
127
+ t.tsTypeReference(t.identifier('InferSelectResult'), t.tsTypeParameterInstantiation([
128
+ t.tsTypeReference(t.identifier(relationTypeName)),
129
+ t.tsTypeReference(t.identifier('S')),
130
+ ])),
131
+ ])))),
132
+ ]),
133
+ ])));
134
+ const findManyArgs = [
135
+ t.stringLiteral(typeName),
136
+ t.stringLiteral(pluralQueryName),
137
+ t.optionalMemberExpression(t.identifier('args'), t.identifier('select'), false, true),
138
+ t.objectExpression([
139
+ t.objectProperty(t.identifier('where'), t.optionalMemberExpression(t.identifier('args'), t.identifier('where'), false, true)),
140
+ t.objectProperty(t.identifier('orderBy'), t.tsAsExpression(t.optionalMemberExpression(t.identifier('args'), t.identifier('orderBy'), false, true), t.tsUnionType([t.tsArrayType(t.tsStringKeyword()), t.tsUndefinedKeyword()]))),
141
+ t.objectProperty(t.identifier('first'), t.optionalMemberExpression(t.identifier('args'), t.identifier('first'), false, true)),
142
+ t.objectProperty(t.identifier('last'), t.optionalMemberExpression(t.identifier('args'), t.identifier('last'), false, true)),
143
+ t.objectProperty(t.identifier('after'), t.optionalMemberExpression(t.identifier('args'), t.identifier('after'), false, true)),
144
+ t.objectProperty(t.identifier('before'), t.optionalMemberExpression(t.identifier('args'), t.identifier('before'), false, true)),
145
+ t.objectProperty(t.identifier('offset'), t.optionalMemberExpression(t.identifier('args'), t.identifier('offset'), false, true)),
146
+ ]),
147
+ t.stringLiteral(whereTypeName),
148
+ t.stringLiteral(orderByTypeName),
149
+ ];
150
+ classBody.push(createClassMethod('findMany', createConstTypeParam(selectTypeName), [findManyParam], findManyReturnType, buildMethodBody('buildFindManyDocument', findManyArgs, 'query', typeName, pluralQueryName)));
151
+ // findFirst method
152
+ const findFirstParam = t.identifier('args');
153
+ findFirstParam.optional = true;
154
+ findFirstParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('FindFirstArgs'), t.tsTypeParameterInstantiation([
155
+ t.tsTypeReference(t.identifier('S')),
156
+ t.tsTypeReference(t.identifier(whereTypeName)),
157
+ ])));
158
+ const findFirstReturnType = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('QueryBuilder'), t.tsTypeParameterInstantiation([
159
+ t.tsTypeLiteral([
160
+ t.tsPropertySignature(t.identifier(pluralQueryName), t.tsTypeAnnotation(t.tsTypeLiteral([
161
+ t.tsPropertySignature(t.identifier('nodes'), t.tsTypeAnnotation(t.tsArrayType(t.tsTypeReference(t.identifier('InferSelectResult'), t.tsTypeParameterInstantiation([
162
+ t.tsTypeReference(t.identifier(relationTypeName)),
163
+ t.tsTypeReference(t.identifier('S')),
164
+ ]))))),
165
+ ]))),
166
+ ]),
167
+ ])));
168
+ const findFirstArgs = [
169
+ t.stringLiteral(typeName),
170
+ t.stringLiteral(pluralQueryName),
171
+ t.optionalMemberExpression(t.identifier('args'), t.identifier('select'), false, true),
172
+ t.objectExpression([
173
+ t.objectProperty(t.identifier('where'), t.optionalMemberExpression(t.identifier('args'), t.identifier('where'), false, true)),
174
+ ]),
175
+ t.stringLiteral(whereTypeName),
176
+ ];
177
+ classBody.push(createClassMethod('findFirst', createConstTypeParam(selectTypeName), [findFirstParam], findFirstReturnType, buildMethodBody('buildFindFirstDocument', findFirstArgs, 'query', typeName, pluralQueryName)));
178
+ // create method
179
+ const createParam = t.identifier('args');
180
+ createParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('CreateArgs'), t.tsTypeParameterInstantiation([
181
+ t.tsTypeReference(t.identifier('S')),
182
+ t.tsIndexedAccessType(t.tsTypeReference(t.identifier(createInputTypeName)), t.tsLiteralType(t.stringLiteral(singularName))),
183
+ ])));
184
+ const createReturnType = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('QueryBuilder'), t.tsTypeParameterInstantiation([
185
+ t.tsTypeLiteral([
186
+ t.tsPropertySignature(t.identifier(createMutationName), t.tsTypeAnnotation(t.tsTypeLiteral([
187
+ t.tsPropertySignature(t.identifier(entityLower), t.tsTypeAnnotation(t.tsTypeReference(t.identifier('InferSelectResult'), t.tsTypeParameterInstantiation([
188
+ t.tsTypeReference(t.identifier(relationTypeName)),
189
+ t.tsTypeReference(t.identifier('S')),
190
+ ])))),
191
+ ]))),
192
+ ]),
193
+ ])));
194
+ const createArgs = [
195
+ t.stringLiteral(typeName),
196
+ t.stringLiteral(createMutationName),
197
+ t.stringLiteral(entityLower),
198
+ t.memberExpression(t.identifier('args'), t.identifier('select')),
199
+ t.memberExpression(t.identifier('args'), t.identifier('data')),
200
+ t.stringLiteral(createInputTypeName),
201
+ ];
202
+ classBody.push(createClassMethod('create', createConstTypeParam(selectTypeName), [createParam], createReturnType, buildMethodBody('buildCreateDocument', createArgs, 'mutation', typeName, createMutationName)));
203
+ // update method (if available)
196
204
  if (updateMutationName) {
197
- classDeclaration.addMethod({
198
- name: 'update',
199
- typeParameters: [`const S extends ${selectTypeName}`],
200
- parameters: [
201
- {
202
- name: 'args',
203
- type: `UpdateArgs<S, { id: string }, ${patchTypeName}>`,
204
- },
205
- ],
206
- returnType: `QueryBuilder<{ ${updateMutationName}: { ${entityLower}: InferSelectResult<${relationTypeName}, S> } }>`,
207
- statements: `const { document, variables } = buildUpdateDocument(
208
- '${typeName}',
209
- '${updateMutationName}',
210
- '${entityLower}',
211
- args.select,
212
- args.where,
213
- args.data,
214
- '${updateInputTypeName}'
215
- );
216
- return new QueryBuilder({
217
- client: this.client,
218
- operation: 'mutation',
219
- operationName: '${typeName}',
220
- fieldName: '${updateMutationName}',
221
- document,
222
- variables,
223
- });`,
224
- });
205
+ const updateParam = t.identifier('args');
206
+ updateParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('UpdateArgs'), t.tsTypeParameterInstantiation([
207
+ t.tsTypeReference(t.identifier('S')),
208
+ t.tsTypeLiteral([t.tsPropertySignature(t.identifier('id'), t.tsTypeAnnotation(t.tsStringKeyword()))]),
209
+ t.tsTypeReference(t.identifier(patchTypeName)),
210
+ ])));
211
+ const updateReturnType = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('QueryBuilder'), t.tsTypeParameterInstantiation([
212
+ t.tsTypeLiteral([
213
+ t.tsPropertySignature(t.identifier(updateMutationName), t.tsTypeAnnotation(t.tsTypeLiteral([
214
+ t.tsPropertySignature(t.identifier(entityLower), t.tsTypeAnnotation(t.tsTypeReference(t.identifier('InferSelectResult'), t.tsTypeParameterInstantiation([
215
+ t.tsTypeReference(t.identifier(relationTypeName)),
216
+ t.tsTypeReference(t.identifier('S')),
217
+ ])))),
218
+ ]))),
219
+ ]),
220
+ ])));
221
+ const updateArgs = [
222
+ t.stringLiteral(typeName),
223
+ t.stringLiteral(updateMutationName),
224
+ t.stringLiteral(entityLower),
225
+ t.memberExpression(t.identifier('args'), t.identifier('select')),
226
+ t.memberExpression(t.identifier('args'), t.identifier('where')),
227
+ t.memberExpression(t.identifier('args'), t.identifier('data')),
228
+ t.stringLiteral(updateInputTypeName),
229
+ ];
230
+ classBody.push(createClassMethod('update', createConstTypeParam(selectTypeName), [updateParam], updateReturnType, buildMethodBody('buildUpdateDocument', updateArgs, 'mutation', typeName, updateMutationName)));
225
231
  }
226
232
  // delete method (if available)
227
233
  if (deleteMutationName) {
228
- classDeclaration.addMethod({
229
- name: 'delete',
230
- parameters: [
231
- {
232
- name: 'args',
233
- type: `DeleteArgs<{ id: string }>`,
234
- },
235
- ],
236
- returnType: `QueryBuilder<{ ${deleteMutationName}: { ${entityLower}: { id: string } } }>`,
237
- statements: `const { document, variables } = buildDeleteDocument(
238
- '${typeName}',
239
- '${deleteMutationName}',
240
- '${entityLower}',
241
- args.where,
242
- '${deleteInputTypeName}'
243
- );
244
- return new QueryBuilder({
245
- client: this.client,
246
- operation: 'mutation',
247
- operationName: '${typeName}',
248
- fieldName: '${deleteMutationName}',
249
- document,
250
- variables,
251
- });`,
252
- });
234
+ const deleteParam = t.identifier('args');
235
+ deleteParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('DeleteArgs'), t.tsTypeParameterInstantiation([
236
+ t.tsTypeLiteral([t.tsPropertySignature(t.identifier('id'), t.tsTypeAnnotation(t.tsStringKeyword()))]),
237
+ ])));
238
+ const deleteReturnType = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('QueryBuilder'), t.tsTypeParameterInstantiation([
239
+ t.tsTypeLiteral([
240
+ t.tsPropertySignature(t.identifier(deleteMutationName), t.tsTypeAnnotation(t.tsTypeLiteral([
241
+ t.tsPropertySignature(t.identifier(entityLower), t.tsTypeAnnotation(t.tsTypeLiteral([t.tsPropertySignature(t.identifier('id'), t.tsTypeAnnotation(t.tsStringKeyword()))]))),
242
+ ]))),
243
+ ]),
244
+ ])));
245
+ const deleteArgs = [
246
+ t.stringLiteral(typeName),
247
+ t.stringLiteral(deleteMutationName),
248
+ t.stringLiteral(entityLower),
249
+ t.memberExpression(t.identifier('args'), t.identifier('where')),
250
+ t.stringLiteral(deleteInputTypeName),
251
+ ];
252
+ classBody.push(createClassMethod('delete', null, [deleteParam], deleteReturnType, buildMethodBody('buildDeleteDocument', deleteArgs, 'mutation', typeName, deleteMutationName)));
253
253
  }
254
- return {
255
- fileName,
256
- content: (0, ts_ast_1.getFormattedOutput)(sourceFile),
257
- modelName,
258
- tableName: table.name,
259
- };
254
+ const classDecl = t.classDeclaration(t.identifier(modelName), null, t.classBody(classBody));
255
+ statements.push(t.exportNamedDeclaration(classDecl));
256
+ const header = (0, utils_1.getGeneratedFileHeader)(`${typeName} model for ORM client`);
257
+ const code = (0, babel_ast_1.generateCode)(statements);
258
+ return { fileName, content: header + '\n' + code, modelName, tableName: table.name };
260
259
  }
261
- // Select types with relations are now generated in input-types.ts
262
- /**
263
- * Generate all model files for a list of tables
264
- */
265
260
  function generateAllModelFiles(tables, useSharedTypes) {
266
261
  return tables.map((table) => generateModelFile(table, useSharedTypes));
267
262
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Query hook generators using AST-based code generation
2
+ * Query hook generators using Babel AST-based code generation
3
3
  *
4
4
  * Output structure:
5
5
  * queries/
@@ -12,18 +12,10 @@ export interface GeneratedQueryFile {
12
12
  content: string;
13
13
  }
14
14
  export interface QueryGeneratorOptions {
15
- /** Whether to generate React Query hooks (default: true for backwards compatibility) */
16
15
  reactQueryEnabled?: boolean;
16
+ useCentralizedKeys?: boolean;
17
+ hasRelationships?: boolean;
17
18
  }
18
- /**
19
- * Generate list query hook file content using AST
20
- */
21
19
  export declare function generateListQueryHook(table: CleanTable, options?: QueryGeneratorOptions): GeneratedQueryFile;
22
- /**
23
- * Generate single item query hook file content using AST
24
- */
25
- export declare function generateSingleQueryHook(table: CleanTable, options?: QueryGeneratorOptions): GeneratedQueryFile;
26
- /**
27
- * Generate all query hook files for all tables
28
- */
20
+ export declare function generateSingleQueryHook(table: CleanTable, options?: QueryGeneratorOptions): GeneratedQueryFile | null;
29
21
  export declare function generateAllQueryHooks(tables: CleanTable[], options?: QueryGeneratorOptions): GeneratedQueryFile[];