@constructive-io/graphql-codegen 2.22.0 → 2.23.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/cli/codegen/barrel.d.ts +5 -1
- package/cli/codegen/barrel.js +13 -11
- package/cli/codegen/index.d.ts +3 -3
- package/cli/codegen/index.js +15 -9
- package/cli/codegen/orm/client-generator.js +3 -2
- package/cli/codegen/orm/custom-ops-generator.js +17 -4
- package/cli/codegen/orm/input-types-generator.js +129 -18
- package/cli/codegen/orm/model-generator.js +2 -1
- package/cli/codegen/orm/query-builder.d.ts +1 -1
- package/cli/codegen/orm/query-builder.js +2 -2
- package/cli/codegen/schema-types-generator.js +5 -5
- package/cli/codegen/utils.d.ts +6 -1
- package/cli/codegen/utils.js +23 -8
- package/cli/commands/generate-orm.d.ts +5 -3
- package/cli/commands/generate-orm.js +65 -84
- package/cli/commands/generate.d.ts +2 -0
- package/cli/commands/generate.js +66 -87
- package/cli/commands/shared.d.ts +74 -0
- package/cli/commands/shared.js +88 -0
- package/cli/index.js +75 -45
- package/cli/introspect/index.d.ts +8 -5
- package/cli/introspect/index.js +19 -7
- package/cli/introspect/infer-tables.d.ts +51 -0
- package/cli/introspect/infer-tables.js +550 -0
- package/cli/introspect/pluralize.d.ts +30 -0
- package/cli/introspect/pluralize.js +124 -0
- package/cli/introspect/source/endpoint.d.ts +34 -0
- package/cli/introspect/source/endpoint.js +35 -0
- package/cli/introspect/source/file.d.ts +20 -0
- package/cli/introspect/source/file.js +103 -0
- package/cli/introspect/source/index.d.ts +48 -0
- package/cli/introspect/source/index.js +72 -0
- package/cli/introspect/source/types.d.ts +58 -0
- package/cli/introspect/source/types.js +27 -0
- package/cli/introspect/transform.d.ts +5 -6
- package/cli/introspect/transform.js +0 -173
- package/cli/watch/cache.d.ts +3 -4
- package/cli/watch/cache.js +6 -10
- package/cli/watch/poller.d.ts +1 -2
- package/cli/watch/poller.js +27 -45
- package/cli/watch/types.d.ts +0 -3
- package/esm/cli/codegen/barrel.d.ts +5 -1
- package/esm/cli/codegen/barrel.js +13 -11
- package/esm/cli/codegen/index.d.ts +3 -3
- package/esm/cli/codegen/index.js +18 -12
- package/esm/cli/codegen/orm/client-generator.js +3 -2
- package/esm/cli/codegen/orm/custom-ops-generator.js +18 -5
- package/esm/cli/codegen/orm/input-types-generator.js +130 -19
- package/esm/cli/codegen/orm/model-generator.js +3 -2
- package/esm/cli/codegen/orm/query-builder.d.ts +1 -1
- package/esm/cli/codegen/orm/query-builder.js +2 -2
- package/esm/cli/codegen/schema-types-generator.js +6 -6
- package/esm/cli/codegen/utils.d.ts +6 -1
- package/esm/cli/codegen/utils.js +22 -8
- package/esm/cli/commands/generate-orm.d.ts +5 -3
- package/esm/cli/commands/generate-orm.js +65 -84
- package/esm/cli/commands/generate.d.ts +2 -0
- package/esm/cli/commands/generate.js +66 -87
- package/esm/cli/commands/shared.d.ts +74 -0
- package/esm/cli/commands/shared.js +84 -0
- package/esm/cli/index.js +76 -46
- package/esm/cli/introspect/index.d.ts +8 -5
- package/esm/cli/introspect/index.js +10 -3
- package/esm/cli/introspect/infer-tables.d.ts +51 -0
- package/esm/cli/introspect/infer-tables.js +547 -0
- package/esm/cli/introspect/pluralize.d.ts +30 -0
- package/esm/cli/introspect/pluralize.js +83 -0
- package/esm/cli/introspect/source/endpoint.d.ts +34 -0
- package/esm/cli/introspect/source/endpoint.js +31 -0
- package/esm/cli/introspect/source/file.d.ts +20 -0
- package/esm/cli/introspect/source/file.js +66 -0
- package/esm/cli/introspect/source/index.d.ts +48 -0
- package/esm/cli/introspect/source/index.js +54 -0
- package/esm/cli/introspect/source/types.d.ts +58 -0
- package/esm/cli/introspect/source/types.js +23 -0
- package/esm/cli/introspect/transform.d.ts +5 -6
- package/esm/cli/introspect/transform.js +0 -172
- package/esm/cli/watch/cache.d.ts +3 -4
- package/esm/cli/watch/cache.js +7 -11
- package/esm/cli/watch/poller.d.ts +1 -2
- package/esm/cli/watch/poller.js +28 -46
- package/esm/cli/watch/types.d.ts +0 -3
- package/esm/types/config.d.ts +21 -5
- package/esm/types/config.js +2 -1
- package/package.json +4 -3
- package/types/config.d.ts +21 -5
- package/types/config.js +2 -1
- package/cli/introspect/fetch-meta.d.ts +0 -31
- package/cli/introspect/fetch-meta.js +0 -108
- package/cli/introspect/meta-query.d.ts +0 -111
- package/cli/introspect/meta-query.js +0 -191
- package/esm/cli/introspect/fetch-meta.d.ts +0 -31
- package/esm/cli/introspect/fetch-meta.js +0 -104
- package/esm/cli/introspect/meta-query.d.ts +0 -111
- package/esm/cli/introspect/meta-query.js +0 -188
package/cli/codegen/barrel.d.ts
CHANGED
|
@@ -19,7 +19,11 @@ export declare function generateMutationsBarrel(tables: CleanTable[]): string;
|
|
|
19
19
|
* @param tables - The tables to include in the SDK
|
|
20
20
|
* @param hasSchemaTypes - Whether schema-types.ts was generated
|
|
21
21
|
*/
|
|
22
|
-
export
|
|
22
|
+
export interface MainBarrelOptions {
|
|
23
|
+
hasSchemaTypes?: boolean;
|
|
24
|
+
hasMutations?: boolean;
|
|
25
|
+
}
|
|
26
|
+
export declare function generateMainBarrel(tables: CleanTable[], options?: MainBarrelOptions | boolean): string;
|
|
23
27
|
/**
|
|
24
28
|
* Generate queries barrel including custom query operations
|
|
25
29
|
*/
|
package/cli/codegen/barrel.js
CHANGED
|
@@ -46,18 +46,23 @@ function generateMutationsBarrel(tables) {
|
|
|
46
46
|
}
|
|
47
47
|
return lines.join('\n') + '\n';
|
|
48
48
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
function generateMainBarrel(tables, hasSchemaTypes = false) {
|
|
49
|
+
function generateMainBarrel(tables, options = {}) {
|
|
50
|
+
// Support legacy signature where second arg was just hasSchemaTypes boolean
|
|
51
|
+
const opts = typeof options === 'boolean'
|
|
52
|
+
? { hasSchemaTypes: options, hasMutations: true }
|
|
53
|
+
: options;
|
|
54
|
+
const { hasSchemaTypes = false, hasMutations = true } = opts;
|
|
56
55
|
const tableNames = tables.map((t) => t.name).join(', ');
|
|
57
56
|
const schemaTypesExport = hasSchemaTypes
|
|
58
57
|
? `
|
|
59
58
|
// Schema types (input, payload, enum types)
|
|
60
59
|
export * from './schema-types';
|
|
60
|
+
`
|
|
61
|
+
: '';
|
|
62
|
+
const mutationsExport = hasMutations
|
|
63
|
+
? `
|
|
64
|
+
// Mutation hooks
|
|
65
|
+
export * from './mutations';
|
|
61
66
|
`
|
|
62
67
|
: '';
|
|
63
68
|
return `/**
|
|
@@ -98,10 +103,7 @@ export * from './types';
|
|
|
98
103
|
${schemaTypesExport}
|
|
99
104
|
// Query hooks
|
|
100
105
|
export * from './queries';
|
|
101
|
-
|
|
102
|
-
// Mutation hooks
|
|
103
|
-
export * from './mutations';
|
|
104
|
-
`;
|
|
106
|
+
${mutationsExport}`;
|
|
105
107
|
}
|
|
106
108
|
// ============================================================================
|
|
107
109
|
// Custom operation barrels (includes both table and custom hooks)
|
package/cli/codegen/index.d.ts
CHANGED
|
@@ -64,8 +64,8 @@ export declare function generateAllFiles(tables: CleanTable[], config: ResolvedC
|
|
|
64
64
|
export declare function generate(options: GenerateOptions): GenerateResult;
|
|
65
65
|
export { generateClientFile } from './client';
|
|
66
66
|
export { generateTypesFile } from './types';
|
|
67
|
-
export { generateAllQueryHooks, generateListQueryHook, generateSingleQueryHook } from './queries';
|
|
67
|
+
export { generateAllQueryHooks, generateListQueryHook, generateSingleQueryHook, } from './queries';
|
|
68
68
|
export { generateAllMutationHooks, generateCreateMutationHook, generateUpdateMutationHook, generateDeleteMutationHook, } from './mutations';
|
|
69
|
-
export { generateAllCustomQueryHooks, generateCustomQueryHook } from './custom-queries';
|
|
70
|
-
export { generateAllCustomMutationHooks, generateCustomMutationHook } from './custom-mutations';
|
|
69
|
+
export { generateAllCustomQueryHooks, generateCustomQueryHook, } from './custom-queries';
|
|
70
|
+
export { generateAllCustomMutationHooks, generateCustomMutationHook, } from './custom-mutations';
|
|
71
71
|
export { generateQueriesBarrel, generateMutationsBarrel, generateMainBarrel, generateCustomQueriesBarrel, generateCustomMutationsBarrel, } from './barrel';
|
package/cli/codegen/index.js
CHANGED
|
@@ -60,7 +60,9 @@ function generate(options) {
|
|
|
60
60
|
// 3. Generate types.ts (can now import enums from schema-types)
|
|
61
61
|
files.push({
|
|
62
62
|
path: 'types.ts',
|
|
63
|
-
content: (0, types_1.generateTypesFile)(tables, {
|
|
63
|
+
content: (0, types_1.generateTypesFile)(tables, {
|
|
64
|
+
enumsFromSchemaTypes: generatedEnumNames,
|
|
65
|
+
}),
|
|
64
66
|
});
|
|
65
67
|
// 4. Generate table-based query hooks (queries/*.ts)
|
|
66
68
|
const queryHooks = (0, queries_1.generateAllQueryHooks)(tables, { reactQueryEnabled });
|
|
@@ -124,17 +126,21 @@ function generate(options) {
|
|
|
124
126
|
});
|
|
125
127
|
}
|
|
126
128
|
}
|
|
127
|
-
// 8. Generate mutations/index.ts barrel (
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
:
|
|
133
|
-
|
|
129
|
+
// 8. Generate mutations/index.ts barrel (only if React Query is enabled)
|
|
130
|
+
// When reactQuery is disabled, no mutation hooks are generated, so skip the barrel
|
|
131
|
+
const hasMutations = mutationHooks.length > 0 || customMutationHooks.length > 0;
|
|
132
|
+
if (hasMutations) {
|
|
133
|
+
files.push({
|
|
134
|
+
path: 'mutations/index.ts',
|
|
135
|
+
content: customMutationHooks.length > 0
|
|
136
|
+
? (0, barrel_1.generateCustomMutationsBarrel)(tables, customMutationHooks.map((h) => h.operationName))
|
|
137
|
+
: (0, barrel_1.generateMutationsBarrel)(tables),
|
|
138
|
+
});
|
|
139
|
+
}
|
|
134
140
|
// 9. Generate main index.ts barrel (with schema-types if present)
|
|
135
141
|
files.push({
|
|
136
142
|
path: 'index.ts',
|
|
137
|
-
content: (0, barrel_1.generateMainBarrel)(tables, hasSchemaTypes),
|
|
143
|
+
content: (0, barrel_1.generateMainBarrel)(tables, { hasSchemaTypes, hasMutations }),
|
|
138
144
|
});
|
|
139
145
|
return {
|
|
140
146
|
files,
|
|
@@ -282,7 +282,8 @@ export function buildFindManyDocument<TSelect, TWhere>(
|
|
|
282
282
|
before?: string;
|
|
283
283
|
offset?: number;
|
|
284
284
|
},
|
|
285
|
-
filterTypeName: string
|
|
285
|
+
filterTypeName: string,
|
|
286
|
+
orderByTypeName: string
|
|
286
287
|
): { document: string; variables: Record<string, unknown> } {
|
|
287
288
|
const selections = select ? buildSelections(select) : 'id';
|
|
288
289
|
|
|
@@ -296,7 +297,7 @@ export function buildFindManyDocument<TSelect, TWhere>(
|
|
|
296
297
|
variables.where = args.where;
|
|
297
298
|
}
|
|
298
299
|
if (args.orderBy?.length) {
|
|
299
|
-
varDefs.push(\`$orderBy: [\${
|
|
300
|
+
varDefs.push(\`$orderBy: [\${orderByTypeName}!]\`);
|
|
300
301
|
queryArgs.push('orderBy: $orderBy');
|
|
301
302
|
variables.orderBy = args.orderBy;
|
|
302
303
|
}
|
|
@@ -8,13 +8,18 @@ const type_resolver_1 = require("../type-resolver");
|
|
|
8
8
|
const scalars_1 = require("../scalars");
|
|
9
9
|
/**
|
|
10
10
|
* Collect all input type names used by operations
|
|
11
|
+
* Includes Input, Filter, OrderBy, and Condition types
|
|
11
12
|
*/
|
|
12
13
|
function collectInputTypeNamesFromOps(operations) {
|
|
13
14
|
const inputTypes = new Set();
|
|
14
15
|
for (const op of operations) {
|
|
15
16
|
for (const arg of op.args) {
|
|
16
17
|
const baseName = (0, type_resolver_1.getTypeBaseName)(arg.type);
|
|
17
|
-
if (baseName &&
|
|
18
|
+
if (baseName &&
|
|
19
|
+
(baseName.endsWith('Input') ||
|
|
20
|
+
baseName.endsWith('Filter') ||
|
|
21
|
+
baseName.endsWith('OrderBy') ||
|
|
22
|
+
baseName.endsWith('Condition'))) {
|
|
18
23
|
inputTypes.add(baseName);
|
|
19
24
|
}
|
|
20
25
|
}
|
|
@@ -22,7 +27,11 @@ function collectInputTypeNamesFromOps(operations) {
|
|
|
22
27
|
return Array.from(inputTypes);
|
|
23
28
|
}
|
|
24
29
|
// Types that don't need Select types
|
|
25
|
-
const NON_SELECT_TYPES = new Set([
|
|
30
|
+
const NON_SELECT_TYPES = new Set([
|
|
31
|
+
...scalars_1.SCALAR_NAMES,
|
|
32
|
+
'Query',
|
|
33
|
+
'Mutation',
|
|
34
|
+
]);
|
|
26
35
|
/**
|
|
27
36
|
* Collect all payload/return type names from operations (for Select types)
|
|
28
37
|
* Filters out scalar types
|
|
@@ -68,7 +77,9 @@ function generateCustomQueryOpsFile(operations) {
|
|
|
68
77
|
// Generate Select type names for payloads
|
|
69
78
|
const selectTypeNames = payloadTypeNames.map((p) => `${p}Select`);
|
|
70
79
|
// Combine all type imports
|
|
71
|
-
const allTypeImports = [
|
|
80
|
+
const allTypeImports = [
|
|
81
|
+
...new Set([...inputTypeNames, ...payloadTypeNames, ...selectTypeNames]),
|
|
82
|
+
];
|
|
72
83
|
// Add file header
|
|
73
84
|
sourceFile.insertText(0, (0, ts_ast_1.createFileHeader)('Custom query operations') + '\n\n');
|
|
74
85
|
// Add imports
|
|
@@ -201,7 +212,9 @@ function generateCustomMutationOpsFile(operations) {
|
|
|
201
212
|
// Generate Select type names for payloads
|
|
202
213
|
const selectTypeNames = payloadTypeNames.map((p) => `${p}Select`);
|
|
203
214
|
// Combine all type imports
|
|
204
|
-
const allTypeImports = [
|
|
215
|
+
const allTypeImports = [
|
|
216
|
+
...new Set([...inputTypeNames, ...payloadTypeNames, ...selectTypeNames]),
|
|
217
|
+
];
|
|
205
218
|
// Add file header
|
|
206
219
|
sourceFile.insertText(0, (0, ts_ast_1.createFileHeader)('Custom mutation operations') + '\n\n');
|
|
207
220
|
// Add imports
|
|
@@ -5,13 +5,19 @@ exports.collectPayloadTypeNames = collectPayloadTypeNames;
|
|
|
5
5
|
exports.generateInputTypesFile = generateInputTypesFile;
|
|
6
6
|
const ts_ast_1 = require("../ts-ast");
|
|
7
7
|
const utils_1 = require("../utils");
|
|
8
|
+
const pluralize_1 = require("../../introspect/pluralize");
|
|
8
9
|
const type_resolver_1 = require("../type-resolver");
|
|
9
10
|
const scalars_1 = require("../scalars");
|
|
10
11
|
// ============================================================================
|
|
11
12
|
// Constants
|
|
12
13
|
// ============================================================================
|
|
13
14
|
/** Fields excluded from Create/Update inputs (auto-generated or system fields) */
|
|
14
|
-
const EXCLUDED_MUTATION_FIELDS = [
|
|
15
|
+
const EXCLUDED_MUTATION_FIELDS = [
|
|
16
|
+
'id',
|
|
17
|
+
'createdAt',
|
|
18
|
+
'updatedAt',
|
|
19
|
+
'nodeId',
|
|
20
|
+
];
|
|
15
21
|
// ============================================================================
|
|
16
22
|
// Type Conversion Utilities
|
|
17
23
|
// ============================================================================
|
|
@@ -58,18 +64,58 @@ function isRequired(typeRef) {
|
|
|
58
64
|
}
|
|
59
65
|
/** Configuration for all scalar filter types - matches PostGraphile's generated filters */
|
|
60
66
|
const SCALAR_FILTER_CONFIGS = [
|
|
61
|
-
{
|
|
62
|
-
|
|
63
|
-
|
|
67
|
+
{
|
|
68
|
+
name: 'StringFilter',
|
|
69
|
+
tsType: 'string',
|
|
70
|
+
operators: ['equality', 'distinct', 'inArray', 'comparison', 'string'],
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: 'IntFilter',
|
|
74
|
+
tsType: 'number',
|
|
75
|
+
operators: ['equality', 'distinct', 'inArray', 'comparison'],
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: 'FloatFilter',
|
|
79
|
+
tsType: 'number',
|
|
80
|
+
operators: ['equality', 'distinct', 'inArray', 'comparison'],
|
|
81
|
+
},
|
|
64
82
|
{ name: 'BooleanFilter', tsType: 'boolean', operators: ['equality'] },
|
|
65
|
-
{
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
{
|
|
83
|
+
{
|
|
84
|
+
name: 'UUIDFilter',
|
|
85
|
+
tsType: 'string',
|
|
86
|
+
operators: ['equality', 'distinct', 'inArray'],
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: 'DatetimeFilter',
|
|
90
|
+
tsType: 'string',
|
|
91
|
+
operators: ['equality', 'distinct', 'inArray', 'comparison'],
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: 'DateFilter',
|
|
95
|
+
tsType: 'string',
|
|
96
|
+
operators: ['equality', 'distinct', 'inArray', 'comparison'],
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
name: 'JSONFilter',
|
|
100
|
+
tsType: 'Record<string, unknown>',
|
|
101
|
+
operators: ['equality', 'distinct', 'json'],
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
name: 'BigIntFilter',
|
|
105
|
+
tsType: 'string',
|
|
106
|
+
operators: ['equality', 'distinct', 'inArray', 'comparison'],
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
name: 'BigFloatFilter',
|
|
110
|
+
tsType: 'string',
|
|
111
|
+
operators: ['equality', 'distinct', 'inArray', 'comparison'],
|
|
112
|
+
},
|
|
71
113
|
{ name: 'BitStringFilter', tsType: 'string', operators: ['equality'] },
|
|
72
|
-
{
|
|
114
|
+
{
|
|
115
|
+
name: 'InternetAddressFilter',
|
|
116
|
+
tsType: 'string',
|
|
117
|
+
operators: ['equality', 'distinct', 'inArray', 'comparison', 'inet'],
|
|
118
|
+
},
|
|
73
119
|
{ name: 'FullTextFilter', tsType: 'string', operators: ['fulltext'] },
|
|
74
120
|
];
|
|
75
121
|
/**
|
|
@@ -229,7 +275,15 @@ function getRelatedTypeName(tableName, tableByName) {
|
|
|
229
275
|
}
|
|
230
276
|
function getRelatedOrderByName(tableName, tableByName) {
|
|
231
277
|
const relatedTable = tableByName.get(tableName);
|
|
232
|
-
|
|
278
|
+
if (relatedTable) {
|
|
279
|
+
return (0, utils_1.getOrderByTypeName)(relatedTable);
|
|
280
|
+
}
|
|
281
|
+
// For ManyToMany connection types, don't pluralize - just append OrderBy
|
|
282
|
+
// These types already have a fixed suffix pattern like "UserUsersByFooManyToMany"
|
|
283
|
+
if (tableName.endsWith('ManyToMany')) {
|
|
284
|
+
return `${tableName}OrderBy`;
|
|
285
|
+
}
|
|
286
|
+
return `${(0, pluralize_1.pluralize)(tableName)}OrderBy`;
|
|
233
287
|
}
|
|
234
288
|
function getRelatedFilterName(tableName, tableByName) {
|
|
235
289
|
const relatedTable = tableByName.get(tableName);
|
|
@@ -410,6 +464,39 @@ function addTableFilterTypes(sourceFile, tables) {
|
|
|
410
464
|
}
|
|
411
465
|
}
|
|
412
466
|
// ============================================================================
|
|
467
|
+
// Condition Types Generator (AST-based)
|
|
468
|
+
// ============================================================================
|
|
469
|
+
/**
|
|
470
|
+
* Build properties for a table condition interface
|
|
471
|
+
* Condition types are simpler than Filter types - they use direct value equality
|
|
472
|
+
*/
|
|
473
|
+
function buildTableConditionProperties(table) {
|
|
474
|
+
const properties = [];
|
|
475
|
+
for (const field of table.fields) {
|
|
476
|
+
const fieldType = typeof field.type === 'string' ? field.type : field.type.gqlType;
|
|
477
|
+
if ((0, utils_1.isRelationField)(field.name, table))
|
|
478
|
+
continue;
|
|
479
|
+
// Condition types use the raw scalar type (nullable)
|
|
480
|
+
const tsType = (0, scalars_1.scalarToTsType)(fieldType, { unknownScalar: 'unknown' });
|
|
481
|
+
properties.push({
|
|
482
|
+
name: field.name,
|
|
483
|
+
type: `${tsType} | null`,
|
|
484
|
+
optional: true,
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
return properties;
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Add table condition types
|
|
491
|
+
*/
|
|
492
|
+
function addTableConditionTypes(sourceFile, tables) {
|
|
493
|
+
(0, ts_ast_1.addSectionComment)(sourceFile, 'Table Condition Types');
|
|
494
|
+
for (const table of tables) {
|
|
495
|
+
const conditionName = (0, utils_1.getConditionTypeName)(table);
|
|
496
|
+
sourceFile.addInterface((0, ts_ast_1.createInterface)(conditionName, buildTableConditionProperties(table)));
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
// ============================================================================
|
|
413
500
|
// OrderBy Types Generator (AST-based)
|
|
414
501
|
// ============================================================================
|
|
415
502
|
/**
|
|
@@ -493,7 +580,11 @@ function buildPatchProperties(table) {
|
|
|
493
580
|
continue;
|
|
494
581
|
const fieldType = typeof field.type === 'string' ? field.type : field.type.gqlType;
|
|
495
582
|
const tsType = scalarToInputTs(fieldType);
|
|
496
|
-
properties.push({
|
|
583
|
+
properties.push({
|
|
584
|
+
name: field.name,
|
|
585
|
+
type: `${tsType} | null`,
|
|
586
|
+
optional: true,
|
|
587
|
+
});
|
|
497
588
|
}
|
|
498
589
|
return properties;
|
|
499
590
|
}
|
|
@@ -607,7 +698,9 @@ function addCustomInputTypes(sourceFile, typeRegistry, usedInputTypes, tableCrud
|
|
|
607
698
|
properties.push({ name: field.name, type: tsType, optional });
|
|
608
699
|
// Follow nested Input types
|
|
609
700
|
const baseType = (0, type_resolver_1.getTypeBaseName)(field.type);
|
|
610
|
-
if (baseType &&
|
|
701
|
+
if (baseType &&
|
|
702
|
+
baseType.endsWith('Input') &&
|
|
703
|
+
!generatedTypes.has(baseType)) {
|
|
611
704
|
typesToGenerate.add(baseType);
|
|
612
705
|
}
|
|
613
706
|
}
|
|
@@ -633,7 +726,8 @@ function collectPayloadTypeNames(operations) {
|
|
|
633
726
|
const payloadTypes = new Set();
|
|
634
727
|
for (const op of operations) {
|
|
635
728
|
const baseName = (0, type_resolver_1.getTypeBaseName)(op.returnType);
|
|
636
|
-
if (baseName &&
|
|
729
|
+
if (baseName &&
|
|
730
|
+
(baseName.endsWith('Payload') || !baseName.endsWith('Connection'))) {
|
|
637
731
|
payloadTypes.add(baseName);
|
|
638
732
|
}
|
|
639
733
|
}
|
|
@@ -647,8 +741,21 @@ function addPayloadTypes(sourceFile, typeRegistry, usedPayloadTypes, alreadyGene
|
|
|
647
741
|
const generatedTypes = new Set(alreadyGeneratedTypes);
|
|
648
742
|
const typesToGenerate = new Set(Array.from(usedPayloadTypes));
|
|
649
743
|
const skipTypes = new Set([
|
|
650
|
-
'String',
|
|
651
|
-
'
|
|
744
|
+
'String',
|
|
745
|
+
'Int',
|
|
746
|
+
'Float',
|
|
747
|
+
'Boolean',
|
|
748
|
+
'ID',
|
|
749
|
+
'UUID',
|
|
750
|
+
'Datetime',
|
|
751
|
+
'Date',
|
|
752
|
+
'Time',
|
|
753
|
+
'JSON',
|
|
754
|
+
'BigInt',
|
|
755
|
+
'BigFloat',
|
|
756
|
+
'Cursor',
|
|
757
|
+
'Query',
|
|
758
|
+
'Mutation',
|
|
652
759
|
]);
|
|
653
760
|
// Process all types - no artificial limit
|
|
654
761
|
while (typesToGenerate.size > 0) {
|
|
@@ -679,7 +786,9 @@ function addPayloadTypes(sourceFile, typeRegistry, usedPayloadTypes, alreadyGene
|
|
|
679
786
|
optional: isNullable,
|
|
680
787
|
});
|
|
681
788
|
// Follow nested OBJECT types
|
|
682
|
-
if (baseType &&
|
|
789
|
+
if (baseType &&
|
|
790
|
+
!generatedTypes.has(baseType) &&
|
|
791
|
+
!skipTypes.has(baseType)) {
|
|
683
792
|
const nestedType = typeRegistry.get(baseType);
|
|
684
793
|
if (nestedType?.kind === 'OBJECT') {
|
|
685
794
|
typesToGenerate.add(baseType);
|
|
@@ -733,6 +842,8 @@ function generateInputTypesFile(typeRegistry, usedInputTypes, tables, usedPayloa
|
|
|
733
842
|
addEntitySelectTypes(sourceFile, tables, tableByName);
|
|
734
843
|
// 4. Table filter types
|
|
735
844
|
addTableFilterTypes(sourceFile, tables);
|
|
845
|
+
// 4b. Table condition types (simple equality filter)
|
|
846
|
+
addTableConditionTypes(sourceFile, tables);
|
|
736
847
|
// 5. OrderBy types
|
|
737
848
|
addOrderByTypes(sourceFile, tables);
|
|
738
849
|
// 6. CRUD input types
|
|
@@ -105,7 +105,7 @@ export declare function buildFindManyDocument(operationName: string, queryField:
|
|
|
105
105
|
after?: string;
|
|
106
106
|
before?: string;
|
|
107
107
|
offset?: number;
|
|
108
|
-
}, filterTypeName: string): {
|
|
108
|
+
}, filterTypeName: string, orderByTypeName: string): {
|
|
109
109
|
document: string;
|
|
110
110
|
variables: Record<string, unknown>;
|
|
111
111
|
};
|
|
@@ -177,7 +177,7 @@ function buildSelections(select, fieldMeta) {
|
|
|
177
177
|
/**
|
|
178
178
|
* Build a findMany query document
|
|
179
179
|
*/
|
|
180
|
-
function buildFindManyDocument(operationName, queryField, select, args, filterTypeName) {
|
|
180
|
+
function buildFindManyDocument(operationName, queryField, select, args, filterTypeName, orderByTypeName) {
|
|
181
181
|
const selections = select ? buildSelections(select) : 'id';
|
|
182
182
|
// Build variable definitions and query arguments
|
|
183
183
|
const varDefs = [];
|
|
@@ -189,7 +189,7 @@ function buildFindManyDocument(operationName, queryField, select, args, filterTy
|
|
|
189
189
|
variables.where = args.where;
|
|
190
190
|
}
|
|
191
191
|
if (args.orderBy && args.orderBy.length > 0) {
|
|
192
|
-
varDefs.push(`$orderBy: [${
|
|
192
|
+
varDefs.push(`$orderBy: [${orderByTypeName}!]`);
|
|
193
193
|
queryArgs.push('orderBy: $orderBy');
|
|
194
194
|
variables.orderBy = args.orderBy;
|
|
195
195
|
}
|
|
@@ -29,13 +29,13 @@ const SKIP_TYPES = new Set([
|
|
|
29
29
|
/**
|
|
30
30
|
* Type name patterns to skip (regex patterns)
|
|
31
31
|
*
|
|
32
|
-
* Note: We intentionally DO NOT skip Connection, Edge, Filter,
|
|
33
|
-
* because they may be referenced by custom operations
|
|
34
|
-
*
|
|
32
|
+
* Note: We intentionally DO NOT skip Connection, Edge, Filter, Patch, Condition,
|
|
33
|
+
* or OrderBy types because they may be referenced by custom operations.
|
|
34
|
+
* Previously Condition and OrderBy were skipped but they ARE needed for
|
|
35
|
+
* custom queries like `schemata`, `apiSchemata`, etc.
|
|
35
36
|
*/
|
|
36
37
|
const SKIP_TYPE_PATTERNS = [
|
|
37
|
-
|
|
38
|
-
/OrderBy$/, // e.g., UsersOrderBy (ordering is handled separately)
|
|
38
|
+
// Currently no patterns are skipped - all types may be needed by custom operations
|
|
39
39
|
];
|
|
40
40
|
// ============================================================================
|
|
41
41
|
// Type Conversion Utilities
|
package/cli/codegen/utils.d.ts
CHANGED
|
@@ -101,9 +101,14 @@ export declare function getDeleteMutationName(table: CleanTable): string;
|
|
|
101
101
|
export declare function getFilterTypeName(table: CleanTable): string;
|
|
102
102
|
/**
|
|
103
103
|
* Get PostGraphile OrderBy enum type name
|
|
104
|
-
* e.g., "CarsOrderBy"
|
|
104
|
+
* e.g., "CarsOrderBy", "AddressesOrderBy"
|
|
105
105
|
*/
|
|
106
106
|
export declare function getOrderByTypeName(table: CleanTable): string;
|
|
107
|
+
/**
|
|
108
|
+
* Get PostGraphile Condition type name (simple equality filter)
|
|
109
|
+
* e.g., "CarCondition", "AddressCondition"
|
|
110
|
+
*/
|
|
111
|
+
export declare function getConditionTypeName(table: CleanTable): string;
|
|
107
112
|
/**
|
|
108
113
|
* Get PostGraphile create input type name
|
|
109
114
|
* e.g., "CreateCarInput"
|
package/cli/codegen/utils.js
CHANGED
|
@@ -23,6 +23,7 @@ exports.getUpdateMutationName = getUpdateMutationName;
|
|
|
23
23
|
exports.getDeleteMutationName = getDeleteMutationName;
|
|
24
24
|
exports.getFilterTypeName = getFilterTypeName;
|
|
25
25
|
exports.getOrderByTypeName = getOrderByTypeName;
|
|
26
|
+
exports.getConditionTypeName = getConditionTypeName;
|
|
26
27
|
exports.getCreateInputTypeName = getCreateInputTypeName;
|
|
27
28
|
exports.getPatchTypeName = getPatchTypeName;
|
|
28
29
|
exports.getUpdateInputTypeName = getUpdateInputTypeName;
|
|
@@ -38,6 +39,7 @@ exports.getQueryKeyPrefix = getQueryKeyPrefix;
|
|
|
38
39
|
exports.getGeneratedFileHeader = getGeneratedFileHeader;
|
|
39
40
|
exports.indent = indent;
|
|
40
41
|
const scalars_1 = require("./scalars");
|
|
42
|
+
const pluralize_1 = require("../introspect/pluralize");
|
|
41
43
|
// ============================================================================
|
|
42
44
|
// String manipulation
|
|
43
45
|
// ============================================================================
|
|
@@ -75,7 +77,9 @@ function toScreamingSnake(str) {
|
|
|
75
77
|
function getTableNames(table) {
|
|
76
78
|
const typeName = table.name;
|
|
77
79
|
const singularName = table.inflection?.tableFieldName || lcFirst(typeName);
|
|
78
|
-
const pluralName = table.query?.all ||
|
|
80
|
+
const pluralName = table.query?.all ||
|
|
81
|
+
table.inflection?.allRows ||
|
|
82
|
+
lcFirst((0, pluralize_1.pluralize)(typeName));
|
|
79
83
|
const pluralTypeName = ucFirst(pluralName);
|
|
80
84
|
return {
|
|
81
85
|
typeName,
|
|
@@ -164,13 +168,15 @@ function getDeleteMutationFileName(table) {
|
|
|
164
168
|
* Uses inflection from _meta, falls back to convention
|
|
165
169
|
*/
|
|
166
170
|
function getAllRowsQueryName(table) {
|
|
167
|
-
return table.query?.all ||
|
|
171
|
+
return (table.query?.all ||
|
|
172
|
+
table.inflection?.allRows ||
|
|
173
|
+
lcFirst((0, pluralize_1.pluralize)(table.name)));
|
|
168
174
|
}
|
|
169
175
|
/**
|
|
170
176
|
* Get the GraphQL query name for fetching single row
|
|
171
177
|
*/
|
|
172
178
|
function getSingleRowQueryName(table) {
|
|
173
|
-
return table.query?.one || table.inflection?.tableFieldName || lcFirst(table.name);
|
|
179
|
+
return (table.query?.one || table.inflection?.tableFieldName || lcFirst(table.name));
|
|
174
180
|
}
|
|
175
181
|
/**
|
|
176
182
|
* Get the GraphQL mutation name for creating
|
|
@@ -202,10 +208,17 @@ function getFilterTypeName(table) {
|
|
|
202
208
|
}
|
|
203
209
|
/**
|
|
204
210
|
* Get PostGraphile OrderBy enum type name
|
|
205
|
-
* e.g., "CarsOrderBy"
|
|
211
|
+
* e.g., "CarsOrderBy", "AddressesOrderBy"
|
|
206
212
|
*/
|
|
207
213
|
function getOrderByTypeName(table) {
|
|
208
|
-
return table.inflection?.orderByType || `${table.name}
|
|
214
|
+
return table.inflection?.orderByType || `${(0, pluralize_1.pluralize)(table.name)}OrderBy`;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Get PostGraphile Condition type name (simple equality filter)
|
|
218
|
+
* e.g., "CarCondition", "AddressCondition"
|
|
219
|
+
*/
|
|
220
|
+
function getConditionTypeName(table) {
|
|
221
|
+
return table.inflection?.conditionType || `${table.name}Condition`;
|
|
209
222
|
}
|
|
210
223
|
/**
|
|
211
224
|
* Get PostGraphile create input type name
|
|
@@ -293,13 +306,15 @@ function getPrimaryKeyInfo(table) {
|
|
|
293
306
|
const pk = table.constraints?.primaryKey?.[0];
|
|
294
307
|
if (!pk || pk.fields.length === 0) {
|
|
295
308
|
// Fallback: try to find 'id' field in table fields
|
|
296
|
-
const idField = table.fields.find(f => f.name.toLowerCase() === 'id');
|
|
309
|
+
const idField = table.fields.find((f) => f.name.toLowerCase() === 'id');
|
|
297
310
|
if (idField) {
|
|
298
|
-
return [
|
|
311
|
+
return [
|
|
312
|
+
{
|
|
299
313
|
name: idField.name,
|
|
300
314
|
gqlType: idField.type.gqlType,
|
|
301
315
|
tsType: fieldTypeToTs(idField.type),
|
|
302
|
-
}
|
|
316
|
+
},
|
|
317
|
+
];
|
|
303
318
|
}
|
|
304
319
|
// Last resort: assume 'id' of type string (UUID)
|
|
305
320
|
return [{ name: 'id', gqlType: 'UUID', tsType: 'string' }];
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Generate ORM command - generates Prisma-like ORM client
|
|
2
|
+
* Generate ORM command - generates Prisma-like ORM client from GraphQL schema
|
|
3
3
|
*
|
|
4
4
|
* This command:
|
|
5
|
-
* 1. Fetches
|
|
6
|
-
* 2.
|
|
5
|
+
* 1. Fetches schema from endpoint or loads from file
|
|
6
|
+
* 2. Infers table metadata from introspection (replaces _meta)
|
|
7
7
|
* 3. Generates a Prisma-like ORM client with fluent API
|
|
8
8
|
*/
|
|
9
9
|
export interface GenerateOrmOptions {
|
|
@@ -11,6 +11,8 @@ export interface GenerateOrmOptions {
|
|
|
11
11
|
config?: string;
|
|
12
12
|
/** GraphQL endpoint URL (overrides config) */
|
|
13
13
|
endpoint?: string;
|
|
14
|
+
/** Path to GraphQL schema file (.graphql) */
|
|
15
|
+
schema?: string;
|
|
14
16
|
/** Output directory (overrides config) */
|
|
15
17
|
output?: string;
|
|
16
18
|
/** Authorization header */
|