@constructive-io/graphql-codegen 4.6.0 → 4.7.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 (75) hide show
  1. package/client/error.d.ts +2 -93
  2. package/client/error.js +9 -273
  3. package/client/execute.d.ts +2 -55
  4. package/client/execute.js +5 -120
  5. package/client/typed-document.d.ts +2 -29
  6. package/client/typed-document.js +3 -39
  7. package/core/ast.d.ts +8 -10
  8. package/core/ast.js +17 -592
  9. package/core/custom-ast.d.ts +5 -33
  10. package/core/custom-ast.js +16 -203
  11. package/core/introspect/infer-tables.d.ts +2 -40
  12. package/core/introspect/infer-tables.js +4 -653
  13. package/core/introspect/schema-query.d.ts +3 -18
  14. package/core/introspect/schema-query.js +3 -118
  15. package/core/introspect/transform-schema.d.ts +2 -84
  16. package/core/introspect/transform-schema.js +14 -279
  17. package/core/introspect/transform.d.ts +2 -18
  18. package/core/introspect/transform.js +6 -39
  19. package/core/meta-object/convert.d.ts +2 -63
  20. package/core/meta-object/convert.js +4 -59
  21. package/core/meta-object/validate.d.ts +2 -7
  22. package/core/meta-object/validate.js +4 -30
  23. package/core/query-builder.d.ts +7 -46
  24. package/core/query-builder.js +8 -408
  25. package/core/types.d.ts +9 -139
  26. package/core/types.js +12 -26
  27. package/esm/client/error.d.ts +2 -93
  28. package/esm/client/error.js +2 -269
  29. package/esm/client/execute.d.ts +2 -55
  30. package/esm/client/execute.js +2 -118
  31. package/esm/client/typed-document.d.ts +2 -29
  32. package/esm/client/typed-document.js +2 -38
  33. package/esm/core/ast.d.ts +8 -10
  34. package/esm/core/ast.js +8 -550
  35. package/esm/core/custom-ast.d.ts +5 -33
  36. package/esm/core/custom-ast.js +5 -160
  37. package/esm/core/introspect/infer-tables.d.ts +2 -40
  38. package/esm/core/introspect/infer-tables.js +2 -652
  39. package/esm/core/introspect/schema-query.d.ts +3 -18
  40. package/esm/core/introspect/schema-query.js +2 -118
  41. package/esm/core/introspect/transform-schema.d.ts +2 -84
  42. package/esm/core/introspect/transform-schema.js +2 -269
  43. package/esm/core/introspect/transform.d.ts +2 -18
  44. package/esm/core/introspect/transform.js +2 -36
  45. package/esm/core/meta-object/convert.d.ts +2 -63
  46. package/esm/core/meta-object/convert.js +2 -58
  47. package/esm/core/meta-object/validate.d.ts +2 -7
  48. package/esm/core/meta-object/validate.js +2 -26
  49. package/esm/core/query-builder.d.ts +7 -46
  50. package/esm/core/query-builder.js +5 -373
  51. package/esm/core/types.d.ts +9 -139
  52. package/esm/core/types.js +9 -24
  53. package/esm/generators/field-selector.d.ts +5 -28
  54. package/esm/generators/field-selector.js +5 -354
  55. package/esm/generators/mutations.d.ts +5 -29
  56. package/esm/generators/mutations.js +5 -195
  57. package/esm/generators/naming-helpers.d.ts +6 -0
  58. package/esm/generators/naming-helpers.js +6 -0
  59. package/esm/generators/select.d.ts +6 -48
  60. package/esm/generators/select.js +6 -634
  61. package/esm/types/query.d.ts +9 -0
  62. package/esm/types/schema.d.ts +4 -0
  63. package/generators/field-selector.d.ts +5 -28
  64. package/generators/field-selector.js +12 -360
  65. package/generators/mutations.d.ts +5 -29
  66. package/generators/mutations.js +9 -231
  67. package/generators/naming-helpers.d.ts +6 -0
  68. package/generators/naming-helpers.js +20 -0
  69. package/generators/select.d.ts +6 -48
  70. package/generators/select.js +17 -677
  71. package/package.json +7 -6
  72. package/types/query.d.ts +9 -0
  73. package/types/schema.d.ts +4 -0
  74. package/core/meta-object/format.json +0 -93
  75. package/esm/core/meta-object/format.json +0 -93
@@ -1,356 +1,7 @@
1
1
  /**
2
- * Convert simplified field selection to QueryBuilder SelectionOptions
2
+ * Re-export field selector utilities from @constructive-io/graphql-query.
3
+ *
4
+ * The canonical implementations of convertToSelectionOptions, isRelationalField,
5
+ * getAvailableRelations, and validateFieldSelection now live in graphql-query.
3
6
  */
4
- export function convertToSelectionOptions(table, allTables, selection) {
5
- if (!selection) {
6
- return convertPresetToSelection(table, 'display');
7
- }
8
- if (typeof selection === 'string') {
9
- return convertPresetToSelection(table, selection);
10
- }
11
- return convertCustomSelectionToOptions(table, allTables, selection);
12
- }
13
- /**
14
- * Convert preset to selection options
15
- */
16
- function convertPresetToSelection(table, preset) {
17
- const options = {};
18
- switch (preset) {
19
- case 'minimal': {
20
- // Just id and first display field
21
- const minimalFields = getMinimalFields(table);
22
- minimalFields.forEach((field) => {
23
- options[field] = true;
24
- });
25
- break;
26
- }
27
- case 'display': {
28
- // Common display fields
29
- const displayFields = getDisplayFields(table);
30
- displayFields.forEach((field) => {
31
- options[field] = true;
32
- });
33
- break;
34
- }
35
- case 'all': {
36
- // All non-relational fields (includes complex fields like JSON, geometry, etc.)
37
- const allFields = getNonRelationalFields(table);
38
- allFields.forEach((field) => {
39
- options[field] = true;
40
- });
41
- break;
42
- }
43
- case 'full':
44
- // All fields including basic relations
45
- table.fields.forEach((field) => {
46
- options[field.name] = true;
47
- });
48
- break;
49
- default: {
50
- // Default to display
51
- const defaultFields = getDisplayFields(table);
52
- defaultFields.forEach((field) => {
53
- options[field] = true;
54
- });
55
- }
56
- }
57
- return options;
58
- }
59
- /**
60
- * Convert custom selection to options
61
- */
62
- function convertCustomSelectionToOptions(table, allTables, selection) {
63
- const options = {};
64
- // Start with selected fields or all non-relational fields (including complex types)
65
- let fieldsToInclude;
66
- if (selection.select) {
67
- fieldsToInclude = selection.select;
68
- }
69
- else {
70
- fieldsToInclude = getNonRelationalFields(table);
71
- }
72
- // Add basic fields
73
- fieldsToInclude.forEach((field) => {
74
- if (table.fields.some((f) => f.name === field)) {
75
- options[field] = true;
76
- }
77
- });
78
- // Handle includeRelations (simple API for relation fields)
79
- if (selection.includeRelations) {
80
- selection.includeRelations.forEach((relationField) => {
81
- if (isRelationalField(relationField, table)) {
82
- // Include with dynamically determined scalar fields from the related table
83
- options[relationField] = {
84
- select: getRelatedTableScalarFields(relationField, table, allTables),
85
- variables: {},
86
- };
87
- }
88
- });
89
- }
90
- // Handle includes (relations) - more detailed API
91
- if (selection.include) {
92
- Object.entries(selection.include).forEach(([relationField, relationSelection]) => {
93
- if (isRelationalField(relationField, table)) {
94
- if (relationSelection === true) {
95
- // Include with dynamically determined scalar fields from the related table
96
- options[relationField] = {
97
- select: getRelatedTableScalarFields(relationField, table, allTables),
98
- variables: {},
99
- };
100
- }
101
- else if (Array.isArray(relationSelection)) {
102
- // Include with specific fields
103
- const selectObj = {};
104
- relationSelection.forEach((field) => {
105
- selectObj[field] = true;
106
- });
107
- options[relationField] = {
108
- select: selectObj,
109
- variables: {},
110
- };
111
- }
112
- }
113
- });
114
- }
115
- // Handle excludes
116
- if (selection.exclude) {
117
- selection.exclude.forEach((field) => {
118
- delete options[field];
119
- });
120
- }
121
- return options;
122
- }
123
- /**
124
- * Get minimal fields - completely schema-driven, no hardcoded assumptions
125
- */
126
- function getMinimalFields(table) {
127
- // Get all non-relational fields from the actual schema
128
- const nonRelationalFields = getNonRelationalFields(table);
129
- // Return the first few fields from the schema (typically includes primary key and basic fields)
130
- // This is completely dynamic based on what the schema actually provides
131
- return nonRelationalFields.slice(0, 3); // Limit to first 3 fields for minimal selection
132
- }
133
- /**
134
- * Get display fields - completely schema-driven, no hardcoded field names
135
- */
136
- function getDisplayFields(table) {
137
- // Get all non-relational fields from the actual schema
138
- const nonRelationalFields = getNonRelationalFields(table);
139
- // Return a reasonable subset for display purposes (first half of available fields)
140
- // This is completely dynamic based on what the schema actually provides
141
- const maxDisplayFields = Math.max(5, Math.floor(nonRelationalFields.length / 2));
142
- return nonRelationalFields.slice(0, maxDisplayFields);
143
- }
144
- /**
145
- * Get all non-relational fields (includes both scalar and complex fields)
146
- * Complex fields like JSON, geometry, images should be included by default
147
- */
148
- function getNonRelationalFields(table) {
149
- return table.fields
150
- .filter((field) => !isRelationalField(field.name, table))
151
- .map((field) => field.name);
152
- }
153
- /**
154
- * Check if a field is relational using table metadata
155
- */
156
- export function isRelationalField(fieldName, table) {
157
- const { belongsTo, hasOne, hasMany, manyToMany } = table.relations;
158
- return (belongsTo.some((rel) => rel.fieldName === fieldName) ||
159
- hasOne.some((rel) => rel.fieldName === fieldName) ||
160
- hasMany.some((rel) => rel.fieldName === fieldName) ||
161
- manyToMany.some((rel) => rel.fieldName === fieldName));
162
- }
163
- /**
164
- * Get scalar fields for a related table to include in relation queries
165
- * Uses only the _meta query data - no hardcoded field names or assumptions
166
- */
167
- function getRelatedTableScalarFields(relationField, table, allTables) {
168
- // Find the related table name
169
- let referencedTableName;
170
- // Check belongsTo relations
171
- const belongsToRel = table.relations.belongsTo.find((rel) => rel.fieldName === relationField);
172
- if (belongsToRel) {
173
- referencedTableName = belongsToRel.referencesTable;
174
- }
175
- // Check hasOne relations
176
- if (!referencedTableName) {
177
- const hasOneRel = table.relations.hasOne.find((rel) => rel.fieldName === relationField);
178
- if (hasOneRel) {
179
- referencedTableName = hasOneRel.referencedByTable;
180
- }
181
- }
182
- // Check hasMany relations
183
- if (!referencedTableName) {
184
- const hasManyRel = table.relations.hasMany.find((rel) => rel.fieldName === relationField);
185
- if (hasManyRel) {
186
- referencedTableName = hasManyRel.referencedByTable;
187
- }
188
- }
189
- // Check manyToMany relations
190
- if (!referencedTableName) {
191
- const manyToManyRel = table.relations.manyToMany.find((rel) => rel.fieldName === relationField);
192
- if (manyToManyRel) {
193
- referencedTableName = manyToManyRel.rightTable;
194
- }
195
- }
196
- if (!referencedTableName) {
197
- // No related table found - return empty selection
198
- return {};
199
- }
200
- // Find the related table in allTables
201
- const relatedTable = allTables.find((t) => t.name === referencedTableName);
202
- if (!relatedTable) {
203
- // Related table not found in schema - return empty selection
204
- return {};
205
- }
206
- // Get ALL scalar fields from the related table (non-relational fields)
207
- // This is completely dynamic based on the actual schema
208
- const scalarFields = relatedTable.fields
209
- .filter((field) => !isRelationalField(field.name, relatedTable))
210
- .map((field) => field.name);
211
- // Perf guardrail: select a small, display-oriented subset.
212
- const MAX_RELATED_FIELDS = 8;
213
- const preferred = [
214
- 'displayName',
215
- 'fullName',
216
- 'preferredName',
217
- 'nickname',
218
- 'firstName',
219
- 'lastName',
220
- 'username',
221
- 'email',
222
- 'name',
223
- 'title',
224
- 'label',
225
- 'slug',
226
- 'code',
227
- 'createdAt',
228
- 'updatedAt',
229
- ];
230
- const included = [];
231
- const push = (fieldName) => {
232
- if (!fieldName)
233
- return;
234
- if (!scalarFields.includes(fieldName))
235
- return;
236
- if (included.includes(fieldName))
237
- return;
238
- if (included.length >= MAX_RELATED_FIELDS)
239
- return;
240
- included.push(fieldName);
241
- };
242
- // Always try to include stable identifiers first.
243
- push('id');
244
- push('rowId');
245
- push('nodeId');
246
- for (const fieldName of preferred)
247
- push(fieldName);
248
- for (const fieldName of scalarFields)
249
- push(fieldName);
250
- const selection = {};
251
- for (const fieldName of included)
252
- selection[fieldName] = true;
253
- return selection;
254
- }
255
- /**
256
- * Get all available relation fields from a table
257
- */
258
- export function getAvailableRelations(table) {
259
- const relations = [];
260
- // Add belongsTo relations
261
- table.relations.belongsTo.forEach((rel) => {
262
- if (rel.fieldName) {
263
- relations.push({
264
- fieldName: rel.fieldName,
265
- type: 'belongsTo',
266
- referencedTable: rel.referencesTable || undefined,
267
- });
268
- }
269
- });
270
- // Add hasOne relations
271
- table.relations.hasOne.forEach((rel) => {
272
- if (rel.fieldName) {
273
- relations.push({
274
- fieldName: rel.fieldName,
275
- type: 'hasOne',
276
- referencedTable: rel.referencedByTable || undefined,
277
- });
278
- }
279
- });
280
- // Add hasMany relations
281
- table.relations.hasMany.forEach((rel) => {
282
- if (rel.fieldName) {
283
- relations.push({
284
- fieldName: rel.fieldName,
285
- type: 'hasMany',
286
- referencedTable: rel.referencedByTable || undefined,
287
- });
288
- }
289
- });
290
- // Add manyToMany relations
291
- table.relations.manyToMany.forEach((rel) => {
292
- if (rel.fieldName) {
293
- relations.push({
294
- fieldName: rel.fieldName,
295
- type: 'manyToMany',
296
- referencedTable: rel.rightTable || undefined,
297
- });
298
- }
299
- });
300
- return relations;
301
- }
302
- /**
303
- * Validate field selection against table schema
304
- */
305
- export function validateFieldSelection(selection, table) {
306
- const errors = [];
307
- if (typeof selection === 'string') {
308
- // Presets are always valid
309
- return { isValid: true, errors: [] };
310
- }
311
- const tableFieldNames = table.fields.map((f) => f.name);
312
- // Validate select fields
313
- if (selection.select) {
314
- selection.select.forEach((field) => {
315
- if (!tableFieldNames.includes(field)) {
316
- errors.push(`Field '${field}' does not exist in table '${table.name}'`);
317
- }
318
- });
319
- }
320
- // Validate includeRelations fields
321
- if (selection.includeRelations) {
322
- selection.includeRelations.forEach((field) => {
323
- if (!isRelationalField(field, table)) {
324
- errors.push(`Field '${field}' is not a relational field in table '${table.name}'`);
325
- }
326
- });
327
- }
328
- // Validate include fields
329
- if (selection.include) {
330
- Object.keys(selection.include).forEach((field) => {
331
- if (!isRelationalField(field, table)) {
332
- errors.push(`Field '${field}' is not a relational field in table '${table.name}'`);
333
- }
334
- });
335
- }
336
- // Validate exclude fields
337
- if (selection.exclude) {
338
- selection.exclude.forEach((field) => {
339
- if (!tableFieldNames.includes(field)) {
340
- errors.push(`Exclude field '${field}' does not exist in table '${table.name}'`);
341
- }
342
- });
343
- }
344
- // Validate maxDepth
345
- if (selection.maxDepth !== undefined) {
346
- if (typeof selection.maxDepth !== 'number' ||
347
- selection.maxDepth < 0 ||
348
- selection.maxDepth > 5) {
349
- errors.push('maxDepth must be a number between 0 and 5');
350
- }
351
- }
352
- return {
353
- isValid: errors.length === 0,
354
- errors,
355
- };
356
- }
7
+ export { convertToSelectionOptions, isRelationalField, getAvailableRelations, validateFieldSelection, } from '@constructive-io/graphql-query';
@@ -1,31 +1,7 @@
1
- import { TypedDocumentString } from '../client/typed-document';
2
- import type { MutationOptions } from '../types/mutation';
3
- import type { CleanTable } from '../types/schema';
4
1
  /**
5
- * Build PostGraphile-style CREATE mutation
6
- * PostGraphile expects: mutation { createTableName(input: { tableName: TableNameInput! }) { tableName { ... } } }
2
+ * Re-export mutation generators from @constructive-io/graphql-query.
3
+ *
4
+ * The canonical implementations of buildPostGraphileCreate, buildPostGraphileUpdate,
5
+ * and buildPostGraphileDelete now live in graphql-query.
7
6
  */
8
- export declare function buildPostGraphileCreate(table: CleanTable, _allTables: CleanTable[], _options?: MutationOptions): TypedDocumentString<Record<string, unknown>, {
9
- input: {
10
- [key: string]: Record<string, unknown>;
11
- };
12
- }>;
13
- /**
14
- * Build PostGraphile-style UPDATE mutation
15
- * PostGraphile expects: mutation { updateTableName(input: { id: UUID!, patch: TableNamePatch! }) { tableName { ... } } }
16
- */
17
- export declare function buildPostGraphileUpdate(table: CleanTable, _allTables: CleanTable[], _options?: MutationOptions): TypedDocumentString<Record<string, unknown>, {
18
- input: {
19
- id: string | number;
20
- patch: Record<string, unknown>;
21
- };
22
- }>;
23
- /**
24
- * Build PostGraphile-style DELETE mutation
25
- * PostGraphile expects: mutation { deleteTableName(input: { id: UUID! }) { clientMutationId } }
26
- */
27
- export declare function buildPostGraphileDelete(table: CleanTable, _allTables: CleanTable[], _options?: MutationOptions): TypedDocumentString<Record<string, unknown>, {
28
- input: {
29
- id: string | number;
30
- };
31
- }>;
7
+ export { buildPostGraphileCreate, buildPostGraphileUpdate, buildPostGraphileDelete, } from '@constructive-io/graphql-query';
@@ -1,197 +1,7 @@
1
1
  /**
2
- * Mutation generators for CREATE, UPDATE, and DELETE operations
3
- * Uses AST-based approach for PostGraphile-compatible mutations
2
+ * Re-export mutation generators from @constructive-io/graphql-query.
3
+ *
4
+ * The canonical implementations of buildPostGraphileCreate, buildPostGraphileUpdate,
5
+ * and buildPostGraphileDelete now live in graphql-query.
4
6
  */
5
- import * as t from 'gql-ast';
6
- import { OperationTypeNode, print } from 'graphql';
7
- import { camelize } from 'inflekt';
8
- import { TypedDocumentString } from '../client/typed-document';
9
- import { getCustomAstForCleanField, requiresSubfieldSelection, } from '../core/custom-ast';
10
- import { isRelationalField } from './field-selector';
11
- /**
12
- * Generate field selections for PostGraphile mutations using custom AST logic
13
- * This handles both scalar fields and complex types that require subfield selections
14
- */
15
- function generateFieldSelections(table) {
16
- return table.fields
17
- .filter((field) => !isRelationalField(field.name, table)) // Exclude relational fields
18
- .map((field) => {
19
- if (requiresSubfieldSelection(field)) {
20
- // Use custom AST generation for complex types
21
- return getCustomAstForCleanField(field);
22
- }
23
- else {
24
- // Use simple field selection for scalar types
25
- return t.field({ name: field.name });
26
- }
27
- });
28
- }
29
- /**
30
- * Build PostGraphile-style CREATE mutation
31
- * PostGraphile expects: mutation { createTableName(input: { tableName: TableNameInput! }) { tableName { ... } } }
32
- */
33
- export function buildPostGraphileCreate(table, _allTables, _options = {}) {
34
- const mutationName = `create${table.name}`;
35
- const singularName = camelize(table.name, true);
36
- // Create the variable definition for $input
37
- const variableDefinitions = [
38
- t.variableDefinition({
39
- variable: t.variable({ name: 'input' }),
40
- type: t.nonNullType({
41
- type: t.namedType({ type: `Create${table.name}Input` }),
42
- }),
43
- }),
44
- ];
45
- // Create the mutation arguments
46
- const mutationArgs = [
47
- t.argument({
48
- name: 'input',
49
- value: t.variable({ name: 'input' }),
50
- }),
51
- ];
52
- // Get the field selections for the return value using custom AST logic
53
- const fieldSelections = generateFieldSelections(table);
54
- // Build the mutation AST
55
- const ast = t.document({
56
- definitions: [
57
- t.operationDefinition({
58
- operation: OperationTypeNode.MUTATION,
59
- name: `${mutationName}Mutation`,
60
- variableDefinitions,
61
- selectionSet: t.selectionSet({
62
- selections: [
63
- t.field({
64
- name: mutationName,
65
- args: mutationArgs,
66
- selectionSet: t.selectionSet({
67
- selections: [
68
- t.field({
69
- name: singularName,
70
- selectionSet: t.selectionSet({
71
- selections: fieldSelections,
72
- }),
73
- }),
74
- ],
75
- }),
76
- }),
77
- ],
78
- }),
79
- }),
80
- ],
81
- });
82
- // Print the AST to get the query string
83
- const queryString = print(ast);
84
- return new TypedDocumentString(queryString, {
85
- __ast: ast,
86
- });
87
- }
88
- /**
89
- * Build PostGraphile-style UPDATE mutation
90
- * PostGraphile expects: mutation { updateTableName(input: { id: UUID!, patch: TableNamePatch! }) { tableName { ... } } }
91
- */
92
- export function buildPostGraphileUpdate(table, _allTables, _options = {}) {
93
- const mutationName = `update${table.name}`;
94
- const singularName = camelize(table.name, true);
95
- // Create the variable definition for $input
96
- const variableDefinitions = [
97
- t.variableDefinition({
98
- variable: t.variable({ name: 'input' }),
99
- type: t.nonNullType({
100
- type: t.namedType({ type: `Update${table.name}Input` }),
101
- }),
102
- }),
103
- ];
104
- // Create the mutation arguments
105
- const mutationArgs = [
106
- t.argument({
107
- name: 'input',
108
- value: t.variable({ name: 'input' }),
109
- }),
110
- ];
111
- // Get the field selections for the return value using custom AST logic
112
- const fieldSelections = generateFieldSelections(table);
113
- // Build the mutation AST
114
- const ast = t.document({
115
- definitions: [
116
- t.operationDefinition({
117
- operation: OperationTypeNode.MUTATION,
118
- name: `${mutationName}Mutation`,
119
- variableDefinitions,
120
- selectionSet: t.selectionSet({
121
- selections: [
122
- t.field({
123
- name: mutationName,
124
- args: mutationArgs,
125
- selectionSet: t.selectionSet({
126
- selections: [
127
- t.field({
128
- name: singularName,
129
- selectionSet: t.selectionSet({
130
- selections: fieldSelections,
131
- }),
132
- }),
133
- ],
134
- }),
135
- }),
136
- ],
137
- }),
138
- }),
139
- ],
140
- });
141
- // Print the AST to get the query string
142
- const queryString = print(ast);
143
- return new TypedDocumentString(queryString, {
144
- __ast: ast,
145
- });
146
- }
147
- /**
148
- * Build PostGraphile-style DELETE mutation
149
- * PostGraphile expects: mutation { deleteTableName(input: { id: UUID! }) { clientMutationId } }
150
- */
151
- export function buildPostGraphileDelete(table, _allTables, _options = {}) {
152
- const mutationName = `delete${table.name}`;
153
- // Create the variable definition for $input
154
- const variableDefinitions = [
155
- t.variableDefinition({
156
- variable: t.variable({ name: 'input' }),
157
- type: t.nonNullType({
158
- type: t.namedType({ type: `Delete${table.name}Input` }),
159
- }),
160
- }),
161
- ];
162
- // Create the mutation arguments
163
- const mutationArgs = [
164
- t.argument({
165
- name: 'input',
166
- value: t.variable({ name: 'input' }),
167
- }),
168
- ];
169
- // PostGraphile delete mutations typically return clientMutationId
170
- const fieldSelections = [t.field({ name: 'clientMutationId' })];
171
- // Build the mutation AST
172
- const ast = t.document({
173
- definitions: [
174
- t.operationDefinition({
175
- operation: OperationTypeNode.MUTATION,
176
- name: `${mutationName}Mutation`,
177
- variableDefinitions,
178
- selectionSet: t.selectionSet({
179
- selections: [
180
- t.field({
181
- name: mutationName,
182
- args: mutationArgs,
183
- selectionSet: t.selectionSet({
184
- selections: fieldSelections,
185
- }),
186
- }),
187
- ],
188
- }),
189
- }),
190
- ],
191
- });
192
- // Print the AST to get the query string
193
- const queryString = print(ast);
194
- return new TypedDocumentString(queryString, {
195
- __ast: ast,
196
- });
197
- }
7
+ export { buildPostGraphileCreate, buildPostGraphileUpdate, buildPostGraphileDelete, } from '@constructive-io/graphql-query';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Re-export naming helpers from @constructive-io/graphql-query.
3
+ *
4
+ * Server-aware inflection naming functions now live in graphql-query.
5
+ */
6
+ export { normalizeInflectionValue, toCamelCaseSingular, toCreateMutationName, toUpdateMutationName, toDeleteMutationName, toCreateInputTypeName, toUpdateInputTypeName, toDeleteInputTypeName, toFilterTypeName, toPatchFieldName, toOrderByEnumValue, } from '@constructive-io/graphql-query';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Re-export naming helpers from @constructive-io/graphql-query.
3
+ *
4
+ * Server-aware inflection naming functions now live in graphql-query.
5
+ */
6
+ export { normalizeInflectionValue, toCamelCaseSingular, toCreateMutationName, toUpdateMutationName, toDeleteMutationName, toCreateInputTypeName, toUpdateInputTypeName, toDeleteInputTypeName, toFilterTypeName, toPatchFieldName, toOrderByEnumValue, } from '@constructive-io/graphql-query';
@@ -1,50 +1,8 @@
1
- import { TypedDocumentString } from '../client/typed-document';
2
- import { QueryBuilder } from '../core/query-builder';
3
- import type { IntrospectionSchema, MetaObject } from '../core/types';
4
- import type { QueryOptions } from '../types/query';
5
- import type { CleanTable } from '../types/schema';
6
1
  /**
7
- * Convert PascalCase table name to camelCase plural for GraphQL queries
8
- * Uses the inflection library for proper pluralization
9
- * Example: "ActionGoal" -> "actionGoals", "User" -> "users", "Person" -> "people"
2
+ * Re-export select query generators from @constructive-io/graphql-query.
3
+ *
4
+ * The canonical implementations of buildSelect, buildFindOne, buildCount,
5
+ * cleanTableToMetaObject, createASTQueryBuilder, generateIntrospectionSchema,
6
+ * toCamelCasePlural, and toOrderByTypeName now live in graphql-query.
10
7
  */
11
- export declare function toCamelCasePlural(tableName: string): string;
12
- /**
13
- * Generate the PostGraphile OrderBy enum type name for a table
14
- * PostGraphile uses pluralized PascalCase: "Product" -> "ProductsOrderBy"
15
- * Example: "Product" -> "ProductsOrderBy", "Person" -> "PeopleOrderBy"
16
- */
17
- export declare function toOrderByTypeName(tableName: string): string;
18
- /**
19
- * Convert CleanTable to MetaObject format for QueryBuilder
20
- */
21
- export declare function cleanTableToMetaObject(tables: CleanTable[]): MetaObject;
22
- /**
23
- * Generate basic IntrospectionSchema from CleanTable array
24
- * This creates a minimal schema for AST generation
25
- */
26
- export declare function generateIntrospectionSchema(tables: CleanTable[]): IntrospectionSchema;
27
- /**
28
- * Create AST-based query builder for a table
29
- */
30
- export declare function createASTQueryBuilder(tables: CleanTable[]): QueryBuilder;
31
- /**
32
- * Build a SELECT query for a table with optional filtering, sorting, and pagination
33
- * Uses direct AST generation without intermediate conversions
34
- */
35
- export declare function buildSelect(table: CleanTable, allTables: readonly CleanTable[], options?: QueryOptions): TypedDocumentString<Record<string, unknown>, QueryOptions>;
36
- /**
37
- * Build a single row query by primary key or unique field
38
- */
39
- export declare function buildFindOne(table: CleanTable, _pkField?: string): TypedDocumentString<Record<string, unknown>, Record<string, unknown>>;
40
- /**
41
- * Build a count query for a table
42
- */
43
- export declare function buildCount(table: CleanTable): TypedDocumentString<{
44
- [key: string]: {
45
- totalCount: number;
46
- };
47
- }, {
48
- condition?: Record<string, unknown>;
49
- filter?: Record<string, unknown>;
50
- }>;
8
+ export { buildSelect, buildFindOne, buildCount, cleanTableToMetaObject, createASTQueryBuilder, generateIntrospectionSchema, toCamelCasePlural, toOrderByTypeName, } from '@constructive-io/graphql-query';