@constructive-io/graphql-codegen 2.24.1 → 2.26.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 (38) hide show
  1. package/README.md +403 -279
  2. package/cli/codegen/orm/client-generator.js +475 -136
  3. package/cli/codegen/orm/custom-ops-generator.js +8 -3
  4. package/cli/codegen/orm/model-generator.js +18 -5
  5. package/cli/codegen/orm/select-types.d.ts +33 -0
  6. package/cli/commands/generate-orm.d.ts +14 -0
  7. package/cli/commands/generate-orm.js +160 -44
  8. package/cli/commands/generate.d.ts +22 -0
  9. package/cli/commands/generate.js +195 -55
  10. package/cli/commands/init.js +29 -9
  11. package/cli/index.js +133 -28
  12. package/cli/watch/orchestrator.d.ts +4 -0
  13. package/cli/watch/orchestrator.js +4 -0
  14. package/esm/cli/codegen/orm/client-generator.js +475 -136
  15. package/esm/cli/codegen/orm/custom-ops-generator.js +8 -3
  16. package/esm/cli/codegen/orm/model-generator.js +18 -5
  17. package/esm/cli/codegen/orm/select-types.d.ts +33 -0
  18. package/esm/cli/commands/generate-orm.d.ts +14 -0
  19. package/esm/cli/commands/generate-orm.js +161 -45
  20. package/esm/cli/commands/generate.d.ts +22 -0
  21. package/esm/cli/commands/generate.js +195 -56
  22. package/esm/cli/commands/init.js +29 -9
  23. package/esm/cli/index.js +134 -29
  24. package/esm/cli/watch/orchestrator.d.ts +4 -0
  25. package/esm/cli/watch/orchestrator.js +5 -1
  26. package/esm/types/config.d.ts +39 -2
  27. package/esm/types/config.js +88 -4
  28. package/esm/types/index.d.ts +2 -2
  29. package/esm/types/index.js +1 -1
  30. package/package.json +10 -7
  31. package/types/config.d.ts +39 -2
  32. package/types/config.js +91 -4
  33. package/types/index.d.ts +2 -2
  34. package/types/index.js +2 -1
  35. package/cli/codegen/orm/query-builder.d.ts +0 -161
  36. package/cli/codegen/orm/query-builder.js +0 -366
  37. package/esm/cli/codegen/orm/query-builder.d.ts +0 -161
  38. package/esm/cli/codegen/orm/query-builder.js +0 -353
package/types/config.js CHANGED
@@ -5,7 +5,10 @@
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.DEFAULT_ORM_CONFIG = exports.DEFAULT_CONFIG = exports.DEFAULT_QUERY_KEY_CONFIG = exports.DEFAULT_WATCH_CONFIG = void 0;
7
7
  exports.defineConfig = defineConfig;
8
+ exports.isMultiConfig = isMultiConfig;
9
+ exports.mergeConfig = mergeConfig;
8
10
  exports.resolveConfig = resolveConfig;
11
+ exports.resolveConfigTargets = resolveConfigTargets;
9
12
  /**
10
13
  * Default watch configuration values
11
14
  */
@@ -76,10 +79,80 @@ exports.DEFAULT_ORM_CONFIG = {
76
79
  function defineConfig(config) {
77
80
  return config;
78
81
  }
82
+ /**
83
+ * Type guard for multi-target configs
84
+ */
85
+ function isMultiConfig(config) {
86
+ const targets = config.targets;
87
+ return typeof targets === 'object' && targets !== null;
88
+ }
89
+ /**
90
+ * Merge two target configs (defaults + overrides)
91
+ */
92
+ function mergeConfig(base, overrides) {
93
+ const headers = base.headers || overrides.headers
94
+ ? { ...(base.headers ?? {}), ...(overrides.headers ?? {}) }
95
+ : undefined;
96
+ const tables = base.tables || overrides.tables
97
+ ? { ...(base.tables ?? {}), ...(overrides.tables ?? {}) }
98
+ : undefined;
99
+ const queries = base.queries || overrides.queries
100
+ ? { ...(base.queries ?? {}), ...(overrides.queries ?? {}) }
101
+ : undefined;
102
+ const mutations = base.mutations || overrides.mutations
103
+ ? { ...(base.mutations ?? {}), ...(overrides.mutations ?? {}) }
104
+ : undefined;
105
+ const hooks = base.hooks || overrides.hooks
106
+ ? { ...(base.hooks ?? {}), ...(overrides.hooks ?? {}) }
107
+ : undefined;
108
+ const postgraphile = base.postgraphile || overrides.postgraphile
109
+ ? { ...(base.postgraphile ?? {}), ...(overrides.postgraphile ?? {}) }
110
+ : undefined;
111
+ const codegen = base.codegen || overrides.codegen
112
+ ? { ...(base.codegen ?? {}), ...(overrides.codegen ?? {}) }
113
+ : undefined;
114
+ const orm = base.orm || overrides.orm
115
+ ? { ...(base.orm ?? {}), ...(overrides.orm ?? {}) }
116
+ : undefined;
117
+ const reactQuery = base.reactQuery || overrides.reactQuery
118
+ ? { ...(base.reactQuery ?? {}), ...(overrides.reactQuery ?? {}) }
119
+ : undefined;
120
+ const queryKeys = base.queryKeys || overrides.queryKeys
121
+ ? {
122
+ ...(base.queryKeys ?? {}),
123
+ ...(overrides.queryKeys ?? {}),
124
+ relationships: {
125
+ ...(base.queryKeys?.relationships ?? {}),
126
+ ...(overrides.queryKeys?.relationships ?? {}),
127
+ },
128
+ }
129
+ : undefined;
130
+ const watch = base.watch || overrides.watch
131
+ ? { ...(base.watch ?? {}), ...(overrides.watch ?? {}) }
132
+ : undefined;
133
+ return {
134
+ ...base,
135
+ ...overrides,
136
+ headers,
137
+ tables,
138
+ queries,
139
+ mutations,
140
+ hooks,
141
+ postgraphile,
142
+ codegen,
143
+ orm,
144
+ reactQuery,
145
+ queryKeys,
146
+ watch,
147
+ };
148
+ }
79
149
  /**
80
150
  * Resolve configuration by applying defaults
81
151
  */
82
152
  function resolveConfig(config) {
153
+ if (isMultiConfig(config)) {
154
+ throw new Error('Multi-target config cannot be resolved with resolveConfig(). Use resolveConfigTargets().');
155
+ }
83
156
  return {
84
157
  endpoint: config.endpoint ?? '',
85
158
  schema: config.schema ?? null,
@@ -121,10 +194,14 @@ function resolveConfig(config) {
121
194
  },
122
195
  queryKeys: {
123
196
  style: config.queryKeys?.style ?? exports.DEFAULT_QUERY_KEY_CONFIG.style,
124
- relationships: config.queryKeys?.relationships ?? exports.DEFAULT_QUERY_KEY_CONFIG.relationships,
125
- generateScopedKeys: config.queryKeys?.generateScopedKeys ?? exports.DEFAULT_QUERY_KEY_CONFIG.generateScopedKeys,
126
- generateCascadeHelpers: config.queryKeys?.generateCascadeHelpers ?? exports.DEFAULT_QUERY_KEY_CONFIG.generateCascadeHelpers,
127
- generateMutationKeys: config.queryKeys?.generateMutationKeys ?? exports.DEFAULT_QUERY_KEY_CONFIG.generateMutationKeys,
197
+ relationships: config.queryKeys?.relationships ??
198
+ exports.DEFAULT_QUERY_KEY_CONFIG.relationships,
199
+ generateScopedKeys: config.queryKeys?.generateScopedKeys ??
200
+ exports.DEFAULT_QUERY_KEY_CONFIG.generateScopedKeys,
201
+ generateCascadeHelpers: config.queryKeys?.generateCascadeHelpers ??
202
+ exports.DEFAULT_QUERY_KEY_CONFIG.generateCascadeHelpers,
203
+ generateMutationKeys: config.queryKeys?.generateMutationKeys ??
204
+ exports.DEFAULT_QUERY_KEY_CONFIG.generateMutationKeys,
128
205
  },
129
206
  watch: {
130
207
  pollInterval: config.watch?.pollInterval ?? exports.DEFAULT_WATCH_CONFIG.pollInterval,
@@ -134,3 +211,13 @@ function resolveConfig(config) {
134
211
  },
135
212
  };
136
213
  }
214
+ /**
215
+ * Resolve all targets in a multi-target config
216
+ */
217
+ function resolveConfigTargets(config) {
218
+ const defaults = config.defaults ?? {};
219
+ return Object.entries(config.targets).map(([name, target]) => ({
220
+ name,
221
+ config: resolveConfig(mergeConfig(defaults, target)),
222
+ }));
223
+ }
package/types/index.d.ts CHANGED
@@ -5,5 +5,5 @@ export type { CleanTable, CleanField, CleanFieldType, CleanRelations, CleanBelon
5
5
  export type { PageInfo, ConnectionResult, QueryOptions, OrderByItem, FilterOperator, FieldFilter, RelationalFilter, Filter, } from './query';
6
6
  export type { MutationOptions, CreateInput, UpdateInput, DeleteInput, MutationResult, } from './mutation';
7
7
  export type { SimpleFieldSelection, FieldSelectionPreset, FieldSelection, SelectionOptions, } from './selection';
8
- export type { GraphQLSDKConfig, ResolvedConfig, } from './config';
9
- export { defineConfig, resolveConfig, DEFAULT_CONFIG } from './config';
8
+ export type { GraphQLSDKConfig, GraphQLSDKConfigTarget, GraphQLSDKMultiConfig, ResolvedConfig, ResolvedTargetConfig, } from './config';
9
+ export { defineConfig, resolveConfig, resolveConfigTargets, DEFAULT_CONFIG, } from './config';
package/types/index.js CHANGED
@@ -3,8 +3,9 @@
3
3
  * Type exports for @constructive-io/graphql-codegen
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.DEFAULT_CONFIG = exports.resolveConfig = exports.defineConfig = void 0;
6
+ exports.DEFAULT_CONFIG = exports.resolveConfigTargets = exports.resolveConfig = exports.defineConfig = void 0;
7
7
  var config_1 = require("./config");
8
8
  Object.defineProperty(exports, "defineConfig", { enumerable: true, get: function () { return config_1.defineConfig; } });
9
9
  Object.defineProperty(exports, "resolveConfig", { enumerable: true, get: function () { return config_1.resolveConfig; } });
10
+ Object.defineProperty(exports, "resolveConfigTargets", { enumerable: true, get: function () { return config_1.resolveConfigTargets; } });
10
11
  Object.defineProperty(exports, "DEFAULT_CONFIG", { enumerable: true, get: function () { return config_1.DEFAULT_CONFIG; } });
@@ -1,161 +0,0 @@
1
- /**
2
- * Runtime query builder for ORM client
3
- *
4
- * This module provides the runtime functionality that builds GraphQL
5
- * queries/mutations from the fluent API calls and executes them.
6
- *
7
- * This file will be copied to the generated output (not generated via AST)
8
- * since it's runtime code that doesn't change based on schema.
9
- */
10
- import type { QueryResult } from './select-types';
11
- /**
12
- * ORM client configuration
13
- */
14
- export interface OrmClientConfig {
15
- endpoint: string;
16
- headers?: Record<string, string>;
17
- }
18
- /**
19
- * Internal client state
20
- */
21
- export declare class OrmClient {
22
- private endpoint;
23
- private headers;
24
- constructor(config: OrmClientConfig);
25
- /**
26
- * Execute a GraphQL query/mutation
27
- */
28
- execute<T>(document: string, variables?: Record<string, unknown>): Promise<QueryResult<T>>;
29
- /**
30
- * Update headers (e.g., for auth token refresh)
31
- */
32
- setHeaders(headers: Record<string, string>): void;
33
- /**
34
- * Get current endpoint
35
- */
36
- getEndpoint(): string;
37
- }
38
- /**
39
- * Configuration for building a query
40
- */
41
- export interface QueryBuilderConfig {
42
- client: OrmClient;
43
- operation: 'query' | 'mutation';
44
- operationName: string;
45
- fieldName: string;
46
- document: string;
47
- variables?: Record<string, unknown>;
48
- }
49
- /**
50
- * Query builder that holds the query configuration and executes it
51
- *
52
- * Usage:
53
- * ```typescript
54
- * const result = await new QueryBuilder(config).execute();
55
- * ```
56
- */
57
- export declare class QueryBuilder<TResult> {
58
- private config;
59
- constructor(config: QueryBuilderConfig);
60
- /**
61
- * Execute the query and return the result
62
- */
63
- execute(): Promise<QueryResult<TResult>>;
64
- /**
65
- * Get the GraphQL document (useful for debugging)
66
- */
67
- toGraphQL(): string;
68
- /**
69
- * Get the variables (useful for debugging)
70
- */
71
- getVariables(): Record<string, unknown> | undefined;
72
- }
73
- /**
74
- * Build field selections from a select object
75
- *
76
- * Converts:
77
- * { id: true, name: true, posts: { select: { title: true } } }
78
- *
79
- * To:
80
- * id
81
- * name
82
- * posts {
83
- * nodes { title }
84
- * totalCount
85
- * pageInfo { hasNextPage hasPreviousPage startCursor endCursor }
86
- * }
87
- */
88
- export declare function buildSelections(select: Record<string, unknown> | undefined, fieldMeta?: Record<string, FieldMeta>): string;
89
- /**
90
- * Field metadata for determining connection vs direct relation
91
- */
92
- export interface FieldMeta {
93
- isConnection: boolean;
94
- isNullable: boolean;
95
- typeName: string;
96
- }
97
- /**
98
- * Build a findMany query document
99
- */
100
- export declare function buildFindManyDocument(operationName: string, queryField: string, select: Record<string, unknown> | undefined, args: {
101
- where?: Record<string, unknown>;
102
- orderBy?: string[];
103
- first?: number;
104
- last?: number;
105
- after?: string;
106
- before?: string;
107
- offset?: number;
108
- }, filterTypeName: string, orderByTypeName: string): {
109
- document: string;
110
- variables: Record<string, unknown>;
111
- };
112
- /**
113
- * Build a findFirst query document
114
- */
115
- export declare function buildFindFirstDocument(operationName: string, queryField: string, select: Record<string, unknown> | undefined, args: {
116
- where?: Record<string, unknown>;
117
- }, filterTypeName: string): {
118
- document: string;
119
- variables: Record<string, unknown>;
120
- };
121
- /**
122
- * Build a create mutation document
123
- */
124
- export declare function buildCreateDocument(operationName: string, mutationField: string, entityField: string, select: Record<string, unknown> | undefined, data: Record<string, unknown>, inputTypeName: string): {
125
- document: string;
126
- variables: Record<string, unknown>;
127
- };
128
- /**
129
- * Build an update mutation document
130
- */
131
- export declare function buildUpdateDocument(operationName: string, mutationField: string, entityField: string, select: Record<string, unknown> | undefined, where: Record<string, unknown>, data: Record<string, unknown>, inputTypeName: string): {
132
- document: string;
133
- variables: Record<string, unknown>;
134
- };
135
- /**
136
- * Build a delete mutation document
137
- */
138
- export declare function buildDeleteDocument(operationName: string, mutationField: string, entityField: string, where: Record<string, unknown>, inputTypeName: string): {
139
- document: string;
140
- variables: Record<string, unknown>;
141
- };
142
- /**
143
- * Build a custom query document
144
- */
145
- export declare function buildCustomQueryDocument(operationName: string, queryField: string, select: Record<string, unknown> | undefined, args: Record<string, unknown> | undefined, variableDefinitions: Array<{
146
- name: string;
147
- type: string;
148
- }>): {
149
- document: string;
150
- variables: Record<string, unknown>;
151
- };
152
- /**
153
- * Build a custom mutation document
154
- */
155
- export declare function buildCustomMutationDocument(operationName: string, mutationField: string, select: Record<string, unknown> | undefined, args: Record<string, unknown> | undefined, variableDefinitions: Array<{
156
- name: string;
157
- type: string;
158
- }>): {
159
- document: string;
160
- variables: Record<string, unknown>;
161
- };
@@ -1,366 +0,0 @@
1
- "use strict";
2
- /**
3
- * Runtime query builder for ORM client
4
- *
5
- * This module provides the runtime functionality that builds GraphQL
6
- * queries/mutations from the fluent API calls and executes them.
7
- *
8
- * This file will be copied to the generated output (not generated via AST)
9
- * since it's runtime code that doesn't change based on schema.
10
- */
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.QueryBuilder = exports.OrmClient = void 0;
13
- exports.buildSelections = buildSelections;
14
- exports.buildFindManyDocument = buildFindManyDocument;
15
- exports.buildFindFirstDocument = buildFindFirstDocument;
16
- exports.buildCreateDocument = buildCreateDocument;
17
- exports.buildUpdateDocument = buildUpdateDocument;
18
- exports.buildDeleteDocument = buildDeleteDocument;
19
- exports.buildCustomQueryDocument = buildCustomQueryDocument;
20
- exports.buildCustomMutationDocument = buildCustomMutationDocument;
21
- /**
22
- * Internal client state
23
- */
24
- class OrmClient {
25
- endpoint;
26
- headers;
27
- constructor(config) {
28
- this.endpoint = config.endpoint;
29
- this.headers = config.headers ?? {};
30
- }
31
- /**
32
- * Execute a GraphQL query/mutation
33
- */
34
- async execute(document, variables) {
35
- const response = await fetch(this.endpoint, {
36
- method: 'POST',
37
- headers: {
38
- 'Content-Type': 'application/json',
39
- Accept: 'application/json',
40
- ...this.headers,
41
- },
42
- body: JSON.stringify({
43
- query: document,
44
- variables: variables ?? {},
45
- }),
46
- });
47
- if (!response.ok) {
48
- return {
49
- data: null,
50
- errors: [
51
- {
52
- message: `HTTP ${response.status}: ${response.statusText}`,
53
- },
54
- ],
55
- };
56
- }
57
- const json = (await response.json());
58
- return {
59
- data: json.data ?? null,
60
- errors: json.errors,
61
- };
62
- }
63
- /**
64
- * Update headers (e.g., for auth token refresh)
65
- */
66
- setHeaders(headers) {
67
- this.headers = { ...this.headers, ...headers };
68
- }
69
- /**
70
- * Get current endpoint
71
- */
72
- getEndpoint() {
73
- return this.endpoint;
74
- }
75
- }
76
- exports.OrmClient = OrmClient;
77
- /**
78
- * Query builder that holds the query configuration and executes it
79
- *
80
- * Usage:
81
- * ```typescript
82
- * const result = await new QueryBuilder(config).execute();
83
- * ```
84
- */
85
- class QueryBuilder {
86
- config;
87
- constructor(config) {
88
- this.config = config;
89
- }
90
- /**
91
- * Execute the query and return the result
92
- */
93
- async execute() {
94
- return this.config.client.execute(this.config.document, this.config.variables);
95
- }
96
- /**
97
- * Get the GraphQL document (useful for debugging)
98
- */
99
- toGraphQL() {
100
- return this.config.document;
101
- }
102
- /**
103
- * Get the variables (useful for debugging)
104
- */
105
- getVariables() {
106
- return this.config.variables;
107
- }
108
- }
109
- exports.QueryBuilder = QueryBuilder;
110
- // ============================================================================
111
- // GraphQL Document Builders (Runtime)
112
- // ============================================================================
113
- /**
114
- * Build field selections from a select object
115
- *
116
- * Converts:
117
- * { id: true, name: true, posts: { select: { title: true } } }
118
- *
119
- * To:
120
- * id
121
- * name
122
- * posts {
123
- * nodes { title }
124
- * totalCount
125
- * pageInfo { hasNextPage hasPreviousPage startCursor endCursor }
126
- * }
127
- */
128
- function buildSelections(select, fieldMeta) {
129
- if (!select) {
130
- return '';
131
- }
132
- const fields = [];
133
- for (const [key, value] of Object.entries(select)) {
134
- if (value === false || value === undefined) {
135
- continue;
136
- }
137
- if (value === true) {
138
- fields.push(key);
139
- continue;
140
- }
141
- // Nested select
142
- if (typeof value === 'object' && value !== null) {
143
- const nested = value;
144
- const meta = fieldMeta?.[key];
145
- const isConnection = meta?.isConnection ?? true; // Default to connection for relations
146
- if (nested.select) {
147
- const nestedSelections = buildSelections(nested.select);
148
- // Build arguments for the relation field
149
- const args = [];
150
- if (nested.first !== undefined) {
151
- args.push(`first: ${nested.first}`);
152
- }
153
- if (nested.filter) {
154
- args.push(`filter: ${JSON.stringify(nested.filter)}`);
155
- }
156
- if (nested.orderBy && nested.orderBy.length > 0) {
157
- args.push(`orderBy: [${nested.orderBy.join(', ')}]`);
158
- }
159
- const argsStr = args.length > 0 ? `(${args.join(', ')})` : '';
160
- if (isConnection) {
161
- // Connection type - include nodes, totalCount, pageInfo
162
- fields.push(`${key}${argsStr} {
163
- nodes { ${nestedSelections} }
164
- totalCount
165
- pageInfo { hasNextPage hasPreviousPage startCursor endCursor }
166
- }`);
167
- }
168
- else {
169
- // Direct relation (not a connection)
170
- fields.push(`${key}${argsStr} { ${nestedSelections} }`);
171
- }
172
- }
173
- }
174
- }
175
- return fields.join('\n ');
176
- }
177
- /**
178
- * Build a findMany query document
179
- */
180
- function buildFindManyDocument(operationName, queryField, select, args, filterTypeName, orderByTypeName) {
181
- const selections = select ? buildSelections(select) : 'id';
182
- // Build variable definitions and query arguments
183
- const varDefs = [];
184
- const queryArgs = [];
185
- const variables = {};
186
- if (args.where) {
187
- varDefs.push(`$where: ${filterTypeName}`);
188
- queryArgs.push('filter: $where');
189
- variables.where = args.where;
190
- }
191
- if (args.orderBy && args.orderBy.length > 0) {
192
- varDefs.push(`$orderBy: [${orderByTypeName}!]`);
193
- queryArgs.push('orderBy: $orderBy');
194
- variables.orderBy = args.orderBy;
195
- }
196
- if (args.first !== undefined) {
197
- varDefs.push('$first: Int');
198
- queryArgs.push('first: $first');
199
- variables.first = args.first;
200
- }
201
- if (args.last !== undefined) {
202
- varDefs.push('$last: Int');
203
- queryArgs.push('last: $last');
204
- variables.last = args.last;
205
- }
206
- if (args.after) {
207
- varDefs.push('$after: Cursor');
208
- queryArgs.push('after: $after');
209
- variables.after = args.after;
210
- }
211
- if (args.before) {
212
- varDefs.push('$before: Cursor');
213
- queryArgs.push('before: $before');
214
- variables.before = args.before;
215
- }
216
- if (args.offset !== undefined) {
217
- varDefs.push('$offset: Int');
218
- queryArgs.push('offset: $offset');
219
- variables.offset = args.offset;
220
- }
221
- const varDefsStr = varDefs.length > 0 ? `(${varDefs.join(', ')})` : '';
222
- const queryArgsStr = queryArgs.length > 0 ? `(${queryArgs.join(', ')})` : '';
223
- const document = `query ${operationName}Query${varDefsStr} {
224
- ${queryField}${queryArgsStr} {
225
- nodes {
226
- ${selections}
227
- }
228
- totalCount
229
- pageInfo {
230
- hasNextPage
231
- hasPreviousPage
232
- startCursor
233
- endCursor
234
- }
235
- }
236
- }`;
237
- return { document, variables };
238
- }
239
- /**
240
- * Build a findFirst query document
241
- */
242
- function buildFindFirstDocument(operationName, queryField, select, args, filterTypeName) {
243
- const selections = select ? buildSelections(select) : 'id';
244
- const varDefs = [];
245
- const queryArgs = [];
246
- const variables = {};
247
- if (args.where) {
248
- varDefs.push(`$where: ${filterTypeName}`);
249
- queryArgs.push('filter: $where');
250
- variables.where = args.where;
251
- }
252
- // findFirst uses the list query with first: 1
253
- varDefs.push('$first: Int');
254
- queryArgs.push('first: $first');
255
- variables.first = 1;
256
- const varDefsStr = varDefs.length > 0 ? `(${varDefs.join(', ')})` : '';
257
- const queryArgsStr = queryArgs.length > 0 ? `(${queryArgs.join(', ')})` : '';
258
- const document = `query ${operationName}Query${varDefsStr} {
259
- ${queryField}${queryArgsStr} {
260
- nodes {
261
- ${selections}
262
- }
263
- }
264
- }`;
265
- return { document, variables };
266
- }
267
- /**
268
- * Build a create mutation document
269
- */
270
- function buildCreateDocument(operationName, mutationField, entityField, select, data, inputTypeName) {
271
- const selections = select ? buildSelections(select) : 'id';
272
- const document = `mutation ${operationName}Mutation($input: ${inputTypeName}!) {
273
- ${mutationField}(input: $input) {
274
- ${entityField} {
275
- ${selections}
276
- }
277
- }
278
- }`;
279
- return {
280
- document,
281
- variables: {
282
- input: {
283
- [entityField]: data,
284
- },
285
- },
286
- };
287
- }
288
- /**
289
- * Build an update mutation document
290
- */
291
- function buildUpdateDocument(operationName, mutationField, entityField, select, where, data, inputTypeName) {
292
- const selections = select ? buildSelections(select) : 'id';
293
- // PostGraphile update uses nodeId or primary key in input
294
- const document = `mutation ${operationName}Mutation($input: ${inputTypeName}!) {
295
- ${mutationField}(input: $input) {
296
- ${entityField} {
297
- ${selections}
298
- }
299
- }
300
- }`;
301
- return {
302
- document,
303
- variables: {
304
- input: {
305
- id: where.id, // Assumes id-based where clause
306
- patch: data,
307
- },
308
- },
309
- };
310
- }
311
- /**
312
- * Build a delete mutation document
313
- */
314
- function buildDeleteDocument(operationName, mutationField, entityField, where, inputTypeName) {
315
- const document = `mutation ${operationName}Mutation($input: ${inputTypeName}!) {
316
- ${mutationField}(input: $input) {
317
- ${entityField} {
318
- id
319
- }
320
- }
321
- }`;
322
- return {
323
- document,
324
- variables: {
325
- input: {
326
- id: where.id,
327
- },
328
- },
329
- };
330
- }
331
- /**
332
- * Build a custom query document
333
- */
334
- function buildCustomQueryDocument(operationName, queryField, select, args, variableDefinitions) {
335
- const selections = select ? buildSelections(select) : '';
336
- const varDefs = variableDefinitions.map((v) => `$${v.name}: ${v.type}`);
337
- const queryArgs = variableDefinitions.map((v) => `${v.name}: $${v.name}`);
338
- const varDefsStr = varDefs.length > 0 ? `(${varDefs.join(', ')})` : '';
339
- const queryArgsStr = queryArgs.length > 0 ? `(${queryArgs.join(', ')})` : '';
340
- const selectionsBlock = selections ? ` {\n ${selections}\n }` : '';
341
- const document = `query ${operationName}Query${varDefsStr} {
342
- ${queryField}${queryArgsStr}${selectionsBlock}
343
- }`;
344
- return {
345
- document,
346
- variables: args ?? {},
347
- };
348
- }
349
- /**
350
- * Build a custom mutation document
351
- */
352
- function buildCustomMutationDocument(operationName, mutationField, select, args, variableDefinitions) {
353
- const selections = select ? buildSelections(select) : '';
354
- const varDefs = variableDefinitions.map((v) => `$${v.name}: ${v.type}`);
355
- const mutationArgs = variableDefinitions.map((v) => `${v.name}: $${v.name}`);
356
- const varDefsStr = varDefs.length > 0 ? `(${varDefs.join(', ')})` : '';
357
- const mutationArgsStr = mutationArgs.length > 0 ? `(${mutationArgs.join(', ')})` : '';
358
- const selectionsBlock = selections ? ` {\n ${selections}\n }` : '';
359
- const document = `mutation ${operationName}Mutation${varDefsStr} {
360
- ${mutationField}${mutationArgsStr}${selectionsBlock}
361
- }`;
362
- return {
363
- document,
364
- variables: args ?? {},
365
- };
366
- }