@constructive-io/graphql-codegen 4.12.2 → 4.13.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 (33) hide show
  1. package/core/codegen/cli/command-map-generator.d.ts +1 -0
  2. package/core/codegen/cli/command-map-generator.js +4 -0
  3. package/core/codegen/cli/config-command-generator.d.ts +11 -0
  4. package/core/codegen/cli/config-command-generator.js +458 -0
  5. package/core/codegen/cli/helpers-generator.d.ts +15 -0
  6. package/core/codegen/cli/helpers-generator.js +119 -0
  7. package/core/codegen/cli/index.d.ts +4 -0
  8. package/core/codegen/cli/index.js +21 -3
  9. package/core/codegen/orm/index.js +3 -2
  10. package/core/codegen/orm/input-types-generator.d.ts +3 -1
  11. package/core/codegen/orm/input-types-generator.js +14 -6
  12. package/core/codegen/orm/model-generator.d.ts +6 -2
  13. package/core/codegen/orm/model-generator.js +59 -37
  14. package/core/codegen/templates/query-builder.ts +2 -2
  15. package/core/codegen/templates/select-types.ts +2 -2
  16. package/esm/core/codegen/cli/command-map-generator.d.ts +1 -0
  17. package/esm/core/codegen/cli/command-map-generator.js +4 -0
  18. package/esm/core/codegen/cli/config-command-generator.d.ts +11 -0
  19. package/esm/core/codegen/cli/config-command-generator.js +422 -0
  20. package/esm/core/codegen/cli/helpers-generator.d.ts +15 -0
  21. package/esm/core/codegen/cli/helpers-generator.js +83 -0
  22. package/esm/core/codegen/cli/index.d.ts +4 -0
  23. package/esm/core/codegen/cli/index.js +18 -2
  24. package/esm/core/codegen/orm/index.js +3 -2
  25. package/esm/core/codegen/orm/input-types-generator.d.ts +3 -1
  26. package/esm/core/codegen/orm/input-types-generator.js +14 -6
  27. package/esm/core/codegen/orm/model-generator.d.ts +6 -2
  28. package/esm/core/codegen/orm/model-generator.js +59 -37
  29. package/esm/types/config.d.ts +9 -0
  30. package/esm/types/config.js +1 -0
  31. package/package.json +4 -4
  32. package/types/config.d.ts +9 -0
  33. package/types/config.js +1 -0
@@ -1024,9 +1024,9 @@ function buildTableCrudTypeNames(tables) {
1024
1024
  /**
1025
1025
  * Generate custom input type statements from TypeRegistry
1026
1026
  */
1027
- function generateCustomInputTypes(typeRegistry, usedInputTypes, tableCrudTypes, comments = true) {
1027
+ function generateCustomInputTypes(typeRegistry, usedInputTypes, tableCrudTypes, comments = true, alreadyGeneratedTypes) {
1028
1028
  const statements = [];
1029
- const generatedTypes = new Set();
1029
+ const generatedTypes = new Set(alreadyGeneratedTypes ?? []);
1030
1030
  const typesToGenerate = new Set(Array.from(usedInputTypes));
1031
1031
  // Filter out types we've already generated (exact matches for table CRUD types only)
1032
1032
  if (tableCrudTypes) {
@@ -1296,7 +1296,8 @@ function collectConditionExtraInputTypes(tables, typeRegistry) {
1296
1296
  /**
1297
1297
  * Generate comprehensive input-types.ts file using Babel AST
1298
1298
  */
1299
- export function generateInputTypesFile(typeRegistry, usedInputTypes, tables, usedPayloadTypes, comments = true) {
1299
+ export function generateInputTypesFile(typeRegistry, usedInputTypes, tables, usedPayloadTypes, comments = true, options) {
1300
+ const conditionEnabled = options?.condition !== false;
1300
1301
  const statements = [];
1301
1302
  const tablesList = tables ?? [];
1302
1303
  const hasTables = tablesList.length > 0;
@@ -1323,7 +1324,9 @@ export function generateInputTypesFile(typeRegistry, usedInputTypes, tables, use
1323
1324
  // 4b. Table condition types (simple equality filter)
1324
1325
  // Pass typeRegistry to merge plugin-injected condition fields
1325
1326
  // (e.g., vectorEmbedding from VectorSearchPlugin)
1326
- statements.push(...generateTableConditionTypes(tablesList, typeRegistry));
1327
+ if (conditionEnabled) {
1328
+ statements.push(...generateTableConditionTypes(tablesList, typeRegistry));
1329
+ }
1327
1330
  // 5. OrderBy types
1328
1331
  // Pass typeRegistry to merge plugin-injected orderBy values
1329
1332
  // (e.g., EMBEDDING_DISTANCE_ASC/DESC from VectorSearchPlugin)
@@ -1337,14 +1340,19 @@ export function generateInputTypesFile(typeRegistry, usedInputTypes, tables, use
1337
1340
  // 7. Custom input types from TypeRegistry
1338
1341
  // Also include any extra types referenced by plugin-injected condition fields
1339
1342
  const mergedUsedInputTypes = new Set(usedInputTypes);
1340
- if (hasTables) {
1343
+ if (hasTables && conditionEnabled) {
1341
1344
  const conditionExtraTypes = collectConditionExtraInputTypes(tablesList, typeRegistry);
1342
1345
  for (const typeName of conditionExtraTypes) {
1343
1346
  mergedUsedInputTypes.add(typeName);
1344
1347
  }
1345
1348
  }
1346
1349
  const tableCrudTypes = tables ? buildTableCrudTypeNames(tables) : undefined;
1347
- statements.push(...generateCustomInputTypes(typeRegistry, mergedUsedInputTypes, tableCrudTypes, comments));
1350
+ // Pass customScalarTypes + enumTypes as already-generated to avoid duplicate declarations
1351
+ const alreadyGenerated = new Set([
1352
+ ...customScalarTypes,
1353
+ ...enumTypes,
1354
+ ]);
1355
+ statements.push(...generateCustomInputTypes(typeRegistry, mergedUsedInputTypes, tableCrudTypes, comments, alreadyGenerated));
1348
1356
  // 8. Payload/return types for custom operations
1349
1357
  if (usedPayloadTypes && usedPayloadTypes.size > 0) {
1350
1358
  const alreadyGeneratedTypes = new Set();
@@ -5,5 +5,9 @@ export interface GeneratedModelFile {
5
5
  modelName: string;
6
6
  tableName: string;
7
7
  }
8
- export declare function generateModelFile(table: CleanTable, _useSharedTypes: boolean): GeneratedModelFile;
9
- export declare function generateAllModelFiles(tables: CleanTable[], useSharedTypes: boolean): GeneratedModelFile[];
8
+ export declare function generateModelFile(table: CleanTable, _useSharedTypes: boolean, options?: {
9
+ condition?: boolean;
10
+ }): GeneratedModelFile;
11
+ export declare function generateAllModelFiles(tables: CleanTable[], useSharedTypes: boolean, options?: {
12
+ condition?: boolean;
13
+ }): GeneratedModelFile[];
@@ -65,7 +65,8 @@ function strictSelectGuard(selectTypeName) {
65
65
  t.tsTypeReference(t.identifier(selectTypeName)),
66
66
  ]));
67
67
  }
68
- export function generateModelFile(table, _useSharedTypes) {
68
+ export function generateModelFile(table, _useSharedTypes, options) {
69
+ const conditionEnabled = options?.condition !== false;
69
70
  const { typeName, singularName, pluralName } = getTableNames(table);
70
71
  const modelName = `${typeName}Model`;
71
72
  const baseFileName = lcFirst(typeName);
@@ -74,7 +75,7 @@ export function generateModelFile(table, _useSharedTypes) {
74
75
  const selectTypeName = `${typeName}Select`;
75
76
  const relationTypeName = `${typeName}WithRelations`;
76
77
  const whereTypeName = getFilterTypeName(table);
77
- const conditionTypeName = `${typeName}Condition`;
78
+ const conditionTypeName = conditionEnabled ? `${typeName}Condition` : undefined;
78
79
  const orderByTypeName = getOrderByTypeName(table);
79
80
  const createInputTypeName = `Create${typeName}Input`;
80
81
  const updateInputTypeName = `Update${typeName}Input`;
@@ -109,17 +110,18 @@ export function generateModelFile(table, _useSharedTypes) {
109
110
  'InferSelectResult',
110
111
  'StrictSelect',
111
112
  ], true));
112
- statements.push(createImportDeclaration('../input-types', [
113
+ const inputTypeImports = [
113
114
  typeName,
114
115
  relationTypeName,
115
116
  selectTypeName,
116
117
  whereTypeName,
117
- conditionTypeName,
118
+ ...(conditionTypeName ? [conditionTypeName] : []),
118
119
  orderByTypeName,
119
120
  createInputTypeName,
120
121
  updateInputTypeName,
121
122
  patchTypeName,
122
- ], true));
123
+ ];
124
+ statements.push(createImportDeclaration('../input-types', inputTypeImports, true));
123
125
  statements.push(createImportDeclaration('../input-types', ['connectionFieldsMap']));
124
126
  const classBody = [];
125
127
  // Constructor
@@ -133,12 +135,15 @@ export function generateModelFile(table, _useSharedTypes) {
133
135
  const pkTsType = () => tsTypeFromPrimitive(pkField.tsType);
134
136
  // ── findMany ───────────────────────────────────────────────────────────
135
137
  {
136
- const argsType = (sel) => t.tsTypeReference(t.identifier('FindManyArgs'), t.tsTypeParameterInstantiation([
137
- sel,
138
- t.tsTypeReference(t.identifier(whereTypeName)),
139
- t.tsTypeReference(t.identifier(conditionTypeName)),
140
- t.tsTypeReference(t.identifier(orderByTypeName)),
141
- ]));
138
+ const findManyTypeArgs = [
139
+ (sel) => sel,
140
+ () => t.tsTypeReference(t.identifier(whereTypeName)),
141
+ ...(conditionTypeName
142
+ ? [() => t.tsTypeReference(t.identifier(conditionTypeName))]
143
+ : []),
144
+ () => t.tsTypeReference(t.identifier(orderByTypeName)),
145
+ ];
146
+ const argsType = (sel) => t.tsTypeReference(t.identifier('FindManyArgs'), t.tsTypeParameterInstantiation(findManyTypeArgs.map(fn => fn(sel))));
142
147
  const retType = (sel) => t.tsTypeAnnotation(t.tsTypeReference(t.identifier('QueryBuilder'), t.tsTypeParameterInstantiation([
143
148
  t.tsTypeLiteral([
144
149
  t.tsPropertySignature(t.identifier(pluralQueryName), t.tsTypeAnnotation(t.tsTypeReference(t.identifier('ConnectionResult'), t.tsTypeParameterInstantiation([
@@ -156,37 +161,47 @@ export function generateModelFile(table, _useSharedTypes) {
156
161
  strictSelectGuard(selectTypeName),
157
162
  ]));
158
163
  const selectExpr = t.memberExpression(t.identifier('args'), t.identifier('select'));
164
+ const findManyObjProps = [
165
+ t.objectProperty(t.identifier('where'), t.optionalMemberExpression(t.identifier('args'), t.identifier('where'), false, true)),
166
+ ...(conditionTypeName
167
+ ? [
168
+ t.objectProperty(t.identifier('condition'), t.optionalMemberExpression(t.identifier('args'), t.identifier('condition'), false, true)),
169
+ ]
170
+ : []),
171
+ t.objectProperty(t.identifier('orderBy'), t.tsAsExpression(t.optionalMemberExpression(t.identifier('args'), t.identifier('orderBy'), false, true), t.tsUnionType([
172
+ t.tsArrayType(t.tsStringKeyword()),
173
+ t.tsUndefinedKeyword(),
174
+ ]))),
175
+ t.objectProperty(t.identifier('first'), t.optionalMemberExpression(t.identifier('args'), t.identifier('first'), false, true)),
176
+ t.objectProperty(t.identifier('last'), t.optionalMemberExpression(t.identifier('args'), t.identifier('last'), false, true)),
177
+ t.objectProperty(t.identifier('after'), t.optionalMemberExpression(t.identifier('args'), t.identifier('after'), false, true)),
178
+ t.objectProperty(t.identifier('before'), t.optionalMemberExpression(t.identifier('args'), t.identifier('before'), false, true)),
179
+ t.objectProperty(t.identifier('offset'), t.optionalMemberExpression(t.identifier('args'), t.identifier('offset'), false, true)),
180
+ ];
159
181
  const bodyArgs = [
160
182
  t.stringLiteral(typeName),
161
183
  t.stringLiteral(pluralQueryName),
162
184
  selectExpr,
163
- t.objectExpression([
164
- t.objectProperty(t.identifier('where'), t.optionalMemberExpression(t.identifier('args'), t.identifier('where'), false, true)),
165
- t.objectProperty(t.identifier('condition'), t.optionalMemberExpression(t.identifier('args'), t.identifier('condition'), false, true)),
166
- t.objectProperty(t.identifier('orderBy'), t.tsAsExpression(t.optionalMemberExpression(t.identifier('args'), t.identifier('orderBy'), false, true), t.tsUnionType([
167
- t.tsArrayType(t.tsStringKeyword()),
168
- t.tsUndefinedKeyword(),
169
- ]))),
170
- t.objectProperty(t.identifier('first'), t.optionalMemberExpression(t.identifier('args'), t.identifier('first'), false, true)),
171
- t.objectProperty(t.identifier('last'), t.optionalMemberExpression(t.identifier('args'), t.identifier('last'), false, true)),
172
- t.objectProperty(t.identifier('after'), t.optionalMemberExpression(t.identifier('args'), t.identifier('after'), false, true)),
173
- t.objectProperty(t.identifier('before'), t.optionalMemberExpression(t.identifier('args'), t.identifier('before'), false, true)),
174
- t.objectProperty(t.identifier('offset'), t.optionalMemberExpression(t.identifier('args'), t.identifier('offset'), false, true)),
175
- ]),
185
+ t.objectExpression(findManyObjProps),
176
186
  t.stringLiteral(whereTypeName),
177
187
  t.stringLiteral(orderByTypeName),
178
188
  t.identifier('connectionFieldsMap'),
179
- t.stringLiteral(conditionTypeName),
189
+ ...(conditionTypeName
190
+ ? [t.stringLiteral(conditionTypeName)]
191
+ : []),
180
192
  ];
181
193
  classBody.push(createClassMethod('findMany', createTypeParam(selectTypeName), [implParam], retType(sRef()), buildMethodBody('buildFindManyDocument', bodyArgs, 'query', typeName, pluralQueryName)));
182
194
  }
183
195
  // ── findFirst ──────────────────────────────────────────────────────────
184
196
  {
185
- const argsType = (sel) => t.tsTypeReference(t.identifier('FindFirstArgs'), t.tsTypeParameterInstantiation([
186
- sel,
187
- t.tsTypeReference(t.identifier(whereTypeName)),
188
- t.tsTypeReference(t.identifier(conditionTypeName)),
189
- ]));
197
+ const findFirstTypeArgs = [
198
+ (sel) => sel,
199
+ () => t.tsTypeReference(t.identifier(whereTypeName)),
200
+ ...(conditionTypeName
201
+ ? [() => t.tsTypeReference(t.identifier(conditionTypeName))]
202
+ : []),
203
+ ];
204
+ const argsType = (sel) => t.tsTypeReference(t.identifier('FindFirstArgs'), t.tsTypeParameterInstantiation(findFirstTypeArgs.map(fn => fn(sel))));
190
205
  const retType = (sel) => t.tsTypeAnnotation(t.tsTypeReference(t.identifier('QueryBuilder'), t.tsTypeParameterInstantiation([
191
206
  t.tsTypeLiteral([
192
207
  t.tsPropertySignature(t.identifier(pluralQueryName), t.tsTypeAnnotation(t.tsTypeLiteral([
@@ -204,17 +219,24 @@ export function generateModelFile(table, _useSharedTypes) {
204
219
  strictSelectGuard(selectTypeName),
205
220
  ]));
206
221
  const selectExpr = t.memberExpression(t.identifier('args'), t.identifier('select'));
222
+ const findFirstObjProps = [
223
+ t.objectProperty(t.identifier('where'), t.optionalMemberExpression(t.identifier('args'), t.identifier('where'), false, true)),
224
+ ...(conditionTypeName
225
+ ? [
226
+ t.objectProperty(t.identifier('condition'), t.optionalMemberExpression(t.identifier('args'), t.identifier('condition'), false, true)),
227
+ ]
228
+ : []),
229
+ ];
207
230
  const bodyArgs = [
208
231
  t.stringLiteral(typeName),
209
232
  t.stringLiteral(pluralQueryName),
210
233
  selectExpr,
211
- t.objectExpression([
212
- t.objectProperty(t.identifier('where'), t.optionalMemberExpression(t.identifier('args'), t.identifier('where'), false, true)),
213
- t.objectProperty(t.identifier('condition'), t.optionalMemberExpression(t.identifier('args'), t.identifier('condition'), false, true)),
214
- ]),
234
+ t.objectExpression(findFirstObjProps),
215
235
  t.stringLiteral(whereTypeName),
216
236
  t.identifier('connectionFieldsMap'),
217
- t.stringLiteral(conditionTypeName),
237
+ ...(conditionTypeName
238
+ ? [t.stringLiteral(conditionTypeName)]
239
+ : []),
218
240
  ];
219
241
  classBody.push(createClassMethod('findFirst', createTypeParam(selectTypeName), [implParam], retType(sRef()), buildMethodBody('buildFindFirstDocument', bodyArgs, 'query', typeName, pluralQueryName)));
220
242
  }
@@ -418,6 +440,6 @@ export function generateModelFile(table, _useSharedTypes) {
418
440
  tableName: table.name,
419
441
  };
420
442
  }
421
- export function generateAllModelFiles(tables, useSharedTypes) {
422
- return tables.map((table) => generateModelFile(table, useSharedTypes));
443
+ export function generateAllModelFiles(tables, useSharedTypes, options) {
444
+ return tables.map((table) => generateModelFile(table, useSharedTypes, options));
423
445
  }
@@ -153,6 +153,7 @@ export interface DocsConfig {
153
153
  export interface BuiltinNames {
154
154
  auth?: string;
155
155
  context?: string;
156
+ config?: string;
156
157
  }
157
158
  /**
158
159
  * CLI generation configuration
@@ -285,6 +286,14 @@ export interface GraphQLSDKConfigTarget {
285
286
  * @default true
286
287
  */
287
288
  comments?: boolean;
289
+ /**
290
+ * Generate condition types and condition arguments on findMany/findFirst.
291
+ * PostGraphile's native `condition` argument provides simple equality filtering.
292
+ * Set to `true` to include condition types and arguments in generated code.
293
+ * Set to `false` to omit them (e.g., when using connection-filter's `filter` argument exclusively).
294
+ * @default false
295
+ */
296
+ condition?: boolean;
288
297
  };
289
298
  /**
290
299
  * Whether to generate ORM client
@@ -61,6 +61,7 @@ export const DEFAULT_CONFIG = {
61
61
  codegen: {
62
62
  skipQueryField: true,
63
63
  comments: true,
64
+ condition: false,
64
65
  },
65
66
  orm: false,
66
67
  reactQuery: false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constructive-io/graphql-codegen",
3
- "version": "4.12.2",
3
+ "version": "4.13.0",
4
4
  "description": "GraphQL SDK generator for Constructive databases with React Query hooks",
5
5
  "keywords": [
6
6
  "graphql",
@@ -56,7 +56,7 @@
56
56
  "@0no-co/graphql.web": "^1.1.2",
57
57
  "@babel/generator": "^7.29.1",
58
58
  "@babel/types": "^7.29.0",
59
- "@constructive-io/graphql-query": "^3.5.2",
59
+ "@constructive-io/graphql-query": "^3.5.3",
60
60
  "@constructive-io/graphql-types": "^3.3.2",
61
61
  "@inquirerer/utils": "^3.3.1",
62
62
  "@pgpmjs/core": "^6.6.2",
@@ -64,7 +64,7 @@
64
64
  "deepmerge": "^4.3.1",
65
65
  "find-and-require-package-json": "^0.9.1",
66
66
  "gql-ast": "^3.3.2",
67
- "graphile-schema": "^1.5.2",
67
+ "graphile-schema": "^1.5.3",
68
68
  "graphql": "^16.13.0",
69
69
  "inflekt": "^0.3.3",
70
70
  "inquirerer": "^4.5.2",
@@ -101,5 +101,5 @@
101
101
  "tsx": "^4.21.0",
102
102
  "typescript": "^5.9.3"
103
103
  },
104
- "gitHead": "4fd2c9be786ad9ae2213453276a69723435d5315"
104
+ "gitHead": "67218366027bc6370e07a1b96d8bf25adba18f42"
105
105
  }
package/types/config.d.ts CHANGED
@@ -153,6 +153,7 @@ export interface DocsConfig {
153
153
  export interface BuiltinNames {
154
154
  auth?: string;
155
155
  context?: string;
156
+ config?: string;
156
157
  }
157
158
  /**
158
159
  * CLI generation configuration
@@ -285,6 +286,14 @@ export interface GraphQLSDKConfigTarget {
285
286
  * @default true
286
287
  */
287
288
  comments?: boolean;
289
+ /**
290
+ * Generate condition types and condition arguments on findMany/findFirst.
291
+ * PostGraphile's native `condition` argument provides simple equality filtering.
292
+ * Set to `true` to include condition types and arguments in generated code.
293
+ * Set to `false` to omit them (e.g., when using connection-filter's `filter` argument exclusively).
294
+ * @default false
295
+ */
296
+ condition?: boolean;
288
297
  };
289
298
  /**
290
299
  * Whether to generate ORM client
package/types/config.js CHANGED
@@ -70,6 +70,7 @@ exports.DEFAULT_CONFIG = {
70
70
  codegen: {
71
71
  skipQueryField: true,
72
72
  comments: true,
73
+ condition: false,
73
74
  },
74
75
  orm: false,
75
76
  reactQuery: false,