@constructive-io/graphql-codegen 4.6.1 → 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 (71) 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 -696
  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 -695
  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 -379
  55. package/esm/generators/mutations.d.ts +5 -28
  56. package/esm/generators/mutations.js +5 -198
  57. package/esm/generators/naming-helpers.d.ts +3 -45
  58. package/esm/generators/naming-helpers.js +3 -151
  59. package/esm/generators/select.d.ts +6 -37
  60. package/esm/generators/select.js +6 -659
  61. package/generators/field-selector.d.ts +5 -28
  62. package/generators/field-selector.js +12 -385
  63. package/generators/mutations.d.ts +5 -28
  64. package/generators/mutations.js +9 -234
  65. package/generators/naming-helpers.d.ts +3 -45
  66. package/generators/naming-helpers.js +15 -164
  67. package/generators/select.d.ts +6 -37
  68. package/generators/select.js +17 -703
  69. package/package.json +7 -6
  70. package/core/meta-object/format.json +0 -93
  71. package/esm/core/meta-object/format.json +0 -93
@@ -1,200 +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 { TypedDocumentString } from '../client/typed-document';
8
- import { getCustomAstForCleanField, requiresSubfieldSelection, } from '../core/custom-ast';
9
- import { isRelationalField } from './field-selector';
10
- import { toCamelCaseSingular, toCreateInputTypeName, toCreateMutationName, toDeleteInputTypeName, toDeleteMutationName, toUpdateInputTypeName, toUpdateMutationName, } from './naming-helpers';
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 = toCreateMutationName(table.name, table);
35
- const singularName = toCamelCaseSingular(table.name, table);
36
- const inputTypeName = toCreateInputTypeName(table.name, table);
37
- // Create the variable definition for $input
38
- const variableDefinitions = [
39
- t.variableDefinition({
40
- variable: t.variable({ name: 'input' }),
41
- type: t.nonNullType({
42
- type: t.namedType({ type: inputTypeName }),
43
- }),
44
- }),
45
- ];
46
- // Create the mutation arguments
47
- const mutationArgs = [
48
- t.argument({
49
- name: 'input',
50
- value: t.variable({ name: 'input' }),
51
- }),
52
- ];
53
- // Get the field selections for the return value using custom AST logic
54
- const fieldSelections = generateFieldSelections(table);
55
- // Build the mutation AST
56
- const ast = t.document({
57
- definitions: [
58
- t.operationDefinition({
59
- operation: OperationTypeNode.MUTATION,
60
- name: `${mutationName}Mutation`,
61
- variableDefinitions,
62
- selectionSet: t.selectionSet({
63
- selections: [
64
- t.field({
65
- name: mutationName,
66
- args: mutationArgs,
67
- selectionSet: t.selectionSet({
68
- selections: [
69
- t.field({
70
- name: singularName,
71
- selectionSet: t.selectionSet({
72
- selections: fieldSelections,
73
- }),
74
- }),
75
- ],
76
- }),
77
- }),
78
- ],
79
- }),
80
- }),
81
- ],
82
- });
83
- // Print the AST to get the query string
84
- const queryString = print(ast);
85
- return new TypedDocumentString(queryString, {
86
- __ast: ast,
87
- });
88
- }
89
- /**
90
- * Build PostGraphile-style UPDATE mutation
91
- * PostGraphile expects: mutation { updateTableName(input: { id: UUID!, patch: TableNamePatch! }) { tableName { ... } } }
92
- */
93
- export function buildPostGraphileUpdate(table, _allTables, _options = {}) {
94
- const mutationName = toUpdateMutationName(table.name, table);
95
- const singularName = toCamelCaseSingular(table.name, table);
96
- const inputTypeName = toUpdateInputTypeName(table.name);
97
- // Create the variable definition for $input
98
- const variableDefinitions = [
99
- t.variableDefinition({
100
- variable: t.variable({ name: 'input' }),
101
- type: t.nonNullType({
102
- type: t.namedType({ type: inputTypeName }),
103
- }),
104
- }),
105
- ];
106
- // Create the mutation arguments
107
- const mutationArgs = [
108
- t.argument({
109
- name: 'input',
110
- value: t.variable({ name: 'input' }),
111
- }),
112
- ];
113
- // Get the field selections for the return value using custom AST logic
114
- const fieldSelections = generateFieldSelections(table);
115
- // Build the mutation AST
116
- const ast = t.document({
117
- definitions: [
118
- t.operationDefinition({
119
- operation: OperationTypeNode.MUTATION,
120
- name: `${mutationName}Mutation`,
121
- variableDefinitions,
122
- selectionSet: t.selectionSet({
123
- selections: [
124
- t.field({
125
- name: mutationName,
126
- args: mutationArgs,
127
- selectionSet: t.selectionSet({
128
- selections: [
129
- t.field({
130
- name: singularName,
131
- selectionSet: t.selectionSet({
132
- selections: fieldSelections,
133
- }),
134
- }),
135
- ],
136
- }),
137
- }),
138
- ],
139
- }),
140
- }),
141
- ],
142
- });
143
- // Print the AST to get the query string
144
- const queryString = print(ast);
145
- return new TypedDocumentString(queryString, {
146
- __ast: ast,
147
- });
148
- }
149
- /**
150
- * Build PostGraphile-style DELETE mutation
151
- * PostGraphile expects: mutation { deleteTableName(input: { id: UUID! }) { clientMutationId } }
152
- */
153
- export function buildPostGraphileDelete(table, _allTables, _options = {}) {
154
- const mutationName = toDeleteMutationName(table.name, table);
155
- const inputTypeName = toDeleteInputTypeName(table.name);
156
- // Create the variable definition for $input
157
- const variableDefinitions = [
158
- t.variableDefinition({
159
- variable: t.variable({ name: 'input' }),
160
- type: t.nonNullType({
161
- type: t.namedType({ type: inputTypeName }),
162
- }),
163
- }),
164
- ];
165
- // Create the mutation arguments
166
- const mutationArgs = [
167
- t.argument({
168
- name: 'input',
169
- value: t.variable({ name: 'input' }),
170
- }),
171
- ];
172
- // PostGraphile delete mutations typically return clientMutationId
173
- const fieldSelections = [t.field({ name: 'clientMutationId' })];
174
- // Build the mutation AST
175
- const ast = t.document({
176
- definitions: [
177
- t.operationDefinition({
178
- operation: OperationTypeNode.MUTATION,
179
- name: `${mutationName}Mutation`,
180
- variableDefinitions,
181
- selectionSet: t.selectionSet({
182
- selections: [
183
- t.field({
184
- name: mutationName,
185
- args: mutationArgs,
186
- selectionSet: t.selectionSet({
187
- selections: fieldSelections,
188
- }),
189
- }),
190
- ],
191
- }),
192
- }),
193
- ],
194
- });
195
- // Print the AST to get the query string
196
- const queryString = print(ast);
197
- return new TypedDocumentString(queryString, {
198
- __ast: ast,
199
- });
200
- }
7
+ export { buildPostGraphileCreate, buildPostGraphileUpdate, buildPostGraphileDelete, } from '@constructive-io/graphql-query';
@@ -1,48 +1,6 @@
1
- import type { CleanTable } from '../types/schema';
2
1
  /**
3
- * Safely normalise a server-provided inflection value.
4
- * Returns `null` for null, undefined, or whitespace-only strings.
5
- */
6
- export declare function normalizeInflectionValue(value: string | null | undefined): string | null;
7
- /**
8
- * Convert PascalCase table name to camelCase plural for GraphQL queries.
9
- * Prefers server-provided `table.query.all` / `table.inflection.allRows`
10
- * when available, with guards against naive pluralisation drift and
11
- * missing camelCase boundaries.
2
+ * Re-export naming helpers from @constructive-io/graphql-query.
12
3
  *
13
- * Example: "ActionGoal" -> "actionGoals", "User" -> "users", "Person" -> "people"
14
- */
15
- export declare function toCamelCasePlural(tableName: string, table?: CleanTable | null): string;
16
- /**
17
- * Convert PascalCase table name to camelCase singular field name.
18
- * Prefers server-provided names when available.
19
- */
20
- export declare function toCamelCaseSingular(tableName: string, table?: CleanTable | null): string;
21
- export declare function toCreateMutationName(tableName: string, table?: CleanTable | null): string;
22
- export declare function toUpdateMutationName(tableName: string, table?: CleanTable | null): string;
23
- export declare function toDeleteMutationName(tableName: string, table?: CleanTable | null): string;
24
- export declare function toCreateInputTypeName(tableName: string, table?: CleanTable | null): string;
25
- export declare function toUpdateInputTypeName(tableName: string): string;
26
- export declare function toDeleteInputTypeName(tableName: string): string;
27
- export declare function toFilterTypeName(tableName: string, table?: CleanTable | null): string;
28
- /**
29
- * Resolve PostGraphile patch field name.
30
- * In v5 this is typically entity-specific: e.g. "userPatch", "contactPatch".
31
- * Prefers the value discovered from the schema (`table.query.patchFieldName`
32
- * or `table.inflection.patchField`), falls back to `${singularName}Patch`.
33
- */
34
- export declare function toPatchFieldName(tableName: string, table?: CleanTable | null): string;
35
- /**
36
- * Convert camelCase field name to SCREAMING_SNAKE_CASE for PostGraphile
37
- * orderBy enums.
38
- *
39
- * "displayName" -> "DISPLAY_NAME_ASC"
40
- * "createdAt" -> "CREATED_AT_DESC"
41
- * "id" -> "ID_ASC"
42
- */
43
- export declare function toOrderByEnumValue(fieldName: string, direction: 'asc' | 'desc'): string;
44
- /**
45
- * Generate the PostGraphile OrderBy enum type name for a table.
46
- * Prefers server-provided `table.inflection.orderByType` when available.
4
+ * Server-aware inflection naming functions now live in graphql-query.
47
5
  */
48
- export declare function toOrderByTypeName(tableName: string, table?: CleanTable | null): string;
6
+ export { normalizeInflectionValue, toCamelCaseSingular, toCreateMutationName, toUpdateMutationName, toDeleteMutationName, toCreateInputTypeName, toUpdateInputTypeName, toDeleteInputTypeName, toFilterTypeName, toPatchFieldName, toOrderByEnumValue, } from '@constructive-io/graphql-query';
@@ -1,154 +1,6 @@
1
1
  /**
2
- * Server-aware naming helpers for GraphQL query/mutation generation.
2
+ * Re-export naming helpers from @constructive-io/graphql-query.
3
3
  *
4
- * These functions prefer names already discovered from the GraphQL schema
5
- * (stored on `table.query` and `table.inflection` by `infer-tables.ts`)
6
- * and fall back to local inflection when introspection data is unavailable.
7
- *
8
- * Back-ported from Dashboard's `packages/data/src/query-generator.ts`.
9
- */
10
- import { camelize, pluralize } from 'inflekt';
11
- // ---------------------------------------------------------------------------
12
- // Internal helpers
13
- // ---------------------------------------------------------------------------
14
- /**
15
- * Safely normalise a server-provided inflection value.
16
- * Returns `null` for null, undefined, or whitespace-only strings.
17
- */
18
- export function normalizeInflectionValue(value) {
19
- if (typeof value !== 'string')
20
- return null;
21
- const trimmed = value.trim();
22
- return trimmed.length > 0 ? trimmed : null;
23
- }
24
- // ---------------------------------------------------------------------------
25
- // Plural / Singular
26
- // ---------------------------------------------------------------------------
27
- /**
28
- * Convert PascalCase table name to camelCase plural for GraphQL queries.
29
- * Prefers server-provided `table.query.all` / `table.inflection.allRows`
30
- * when available, with guards against naive pluralisation drift and
31
- * missing camelCase boundaries.
32
- *
33
- * Example: "ActionGoal" -> "actionGoals", "User" -> "users", "Person" -> "people"
34
- */
35
- export function toCamelCasePlural(tableName, table) {
36
- const singular = camelize(tableName, true);
37
- const inflectedPlural = pluralize(singular);
38
- const serverPluralCandidates = [
39
- table?.query?.all,
40
- table?.inflection?.allRows,
41
- ];
42
- for (const candidateRaw of serverPluralCandidates) {
43
- const candidate = normalizeInflectionValue(candidateRaw);
44
- if (!candidate)
45
- continue;
46
- // Guard against known fallback drift:
47
- // 1. Naive pluralisation: "activitys" instead of "activities"
48
- const isNaivePlural = candidate === `${singular}s` && candidate !== inflectedPlural;
49
- // 2. Missing camelCase boundaries: "deliveryzones" instead of "deliveryZones"
50
- const isMiscased = candidate !== inflectedPlural &&
51
- candidate.toLowerCase() === inflectedPlural.toLowerCase();
52
- if (isNaivePlural || isMiscased)
53
- continue;
54
- return candidate;
55
- }
56
- return inflectedPlural;
57
- }
58
- /**
59
- * Convert PascalCase table name to camelCase singular field name.
60
- * Prefers server-provided names when available.
61
- */
62
- export function toCamelCaseSingular(tableName, table) {
63
- const localSingular = camelize(tableName, true);
64
- for (const candidateRaw of [
65
- table?.query?.one,
66
- table?.inflection?.tableFieldName,
67
- ]) {
68
- const candidate = normalizeInflectionValue(candidateRaw);
69
- if (!candidate)
70
- continue;
71
- // Reject miscased versions: "deliveryzone" vs "deliveryZone"
72
- if (candidate !== localSingular &&
73
- candidate.toLowerCase() === localSingular.toLowerCase())
74
- continue;
75
- return candidate;
76
- }
77
- return localSingular;
78
- }
79
- // ---------------------------------------------------------------------------
80
- // Mutation names
81
- // ---------------------------------------------------------------------------
82
- export function toCreateMutationName(tableName, table) {
83
- return (normalizeInflectionValue(table?.query?.create) ?? `create${tableName}`);
84
- }
85
- export function toUpdateMutationName(tableName, table) {
86
- return (normalizeInflectionValue(table?.query?.update) ?? `update${tableName}`);
87
- }
88
- export function toDeleteMutationName(tableName, table) {
89
- return (normalizeInflectionValue(table?.query?.delete) ?? `delete${tableName}`);
90
- }
91
- // ---------------------------------------------------------------------------
92
- // Input / type names
93
- // ---------------------------------------------------------------------------
94
- export function toCreateInputTypeName(tableName, table) {
95
- return (normalizeInflectionValue(table?.inflection?.createInputType) ??
96
- `Create${tableName}Input`);
97
- }
98
- export function toUpdateInputTypeName(tableName) {
99
- return `Update${tableName}Input`;
100
- }
101
- export function toDeleteInputTypeName(tableName) {
102
- return `Delete${tableName}Input`;
103
- }
104
- export function toFilterTypeName(tableName, table) {
105
- return (normalizeInflectionValue(table?.inflection?.filterType) ??
106
- `${tableName}Filter`);
107
- }
108
- // ---------------------------------------------------------------------------
109
- // Patch field name
110
- // ---------------------------------------------------------------------------
111
- /**
112
- * Resolve PostGraphile patch field name.
113
- * In v5 this is typically entity-specific: e.g. "userPatch", "contactPatch".
114
- * Prefers the value discovered from the schema (`table.query.patchFieldName`
115
- * or `table.inflection.patchField`), falls back to `${singularName}Patch`.
116
- */
117
- export function toPatchFieldName(tableName, table) {
118
- // First check the patch field name discovered from UpdateXxxInput
119
- const introspectedPatch = normalizeInflectionValue(table?.query?.patchFieldName);
120
- if (introspectedPatch)
121
- return introspectedPatch;
122
- // Then check the inflection table
123
- const explicitPatchField = normalizeInflectionValue(table?.inflection?.patchField);
124
- if (explicitPatchField)
125
- return explicitPatchField;
126
- return `${toCamelCaseSingular(tableName, table)}Patch`;
127
- }
128
- // ---------------------------------------------------------------------------
129
- // OrderBy helpers
130
- // ---------------------------------------------------------------------------
131
- /**
132
- * Convert camelCase field name to SCREAMING_SNAKE_CASE for PostGraphile
133
- * orderBy enums.
134
- *
135
- * "displayName" -> "DISPLAY_NAME_ASC"
136
- * "createdAt" -> "CREATED_AT_DESC"
137
- * "id" -> "ID_ASC"
138
- */
139
- export function toOrderByEnumValue(fieldName, direction) {
140
- const screaming = fieldName
141
- .replace(/([a-z0-9])([A-Z])/g, '$1_$2')
142
- .toUpperCase();
143
- return `${screaming}_${direction.toUpperCase()}`;
144
- }
145
- /**
146
- * Generate the PostGraphile OrderBy enum type name for a table.
147
- * Prefers server-provided `table.inflection.orderByType` when available.
4
+ * Server-aware inflection naming functions now live in graphql-query.
148
5
  */
149
- export function toOrderByTypeName(tableName, table) {
150
- if (table?.inflection?.orderByType)
151
- return table.inflection.orderByType;
152
- const plural = toCamelCasePlural(tableName, table);
153
- return `${plural.charAt(0).toUpperCase() + plural.slice(1)}OrderBy`;
154
- }
6
+ export { normalizeInflectionValue, toCamelCaseSingular, toCreateMutationName, toUpdateMutationName, toDeleteMutationName, toCreateInputTypeName, toUpdateInputTypeName, toDeleteInputTypeName, toFilterTypeName, toPatchFieldName, toOrderByEnumValue, } from '@constructive-io/graphql-query';
@@ -1,39 +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
- export { toCamelCasePlural, toOrderByTypeName } from './naming-helpers';
7
1
  /**
8
- * Convert CleanTable to MetaObject format for QueryBuilder
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.
9
7
  */
10
- export declare function cleanTableToMetaObject(tables: CleanTable[]): MetaObject;
11
- /**
12
- * Generate basic IntrospectionSchema from CleanTable array
13
- * This creates a minimal schema for AST generation
14
- */
15
- export declare function generateIntrospectionSchema(tables: CleanTable[]): IntrospectionSchema;
16
- /**
17
- * Create AST-based query builder for a table
18
- */
19
- export declare function createASTQueryBuilder(tables: CleanTable[]): QueryBuilder;
20
- /**
21
- * Build a SELECT query for a table with optional filtering, sorting, and pagination
22
- * Uses direct AST generation without intermediate conversions
23
- */
24
- export declare function buildSelect(table: CleanTable, allTables: readonly CleanTable[], options?: QueryOptions): TypedDocumentString<Record<string, unknown>, QueryOptions>;
25
- /**
26
- * Build a single row query by primary key or unique field
27
- */
28
- export declare function buildFindOne(table: CleanTable, _pkField?: string): TypedDocumentString<Record<string, unknown>, Record<string, unknown>>;
29
- /**
30
- * Build a count query for a table
31
- */
32
- export declare function buildCount(table: CleanTable): TypedDocumentString<{
33
- [key: string]: {
34
- totalCount: number;
35
- };
36
- }, {
37
- condition?: Record<string, unknown>;
38
- filter?: Record<string, unknown>;
39
- }>;
8
+ export { buildSelect, buildFindOne, buildCount, cleanTableToMetaObject, createASTQueryBuilder, generateIntrospectionSchema, toCamelCasePlural, toOrderByTypeName, } from '@constructive-io/graphql-query';