@constructive-io/graphql-server 2.19.2 → 2.19.3

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 (205) hide show
  1. package/codegen/orm/index.d.ts +7 -603
  2. package/codegen/orm/index.js +4 -127
  3. package/codegen/orm/input-types.d.ts +14682 -7790
  4. package/codegen/orm/input-types.js +0 -5
  5. package/codegen/orm/models/api.d.ts +6 -6
  6. package/codegen/orm/models/api.js +3 -4
  7. package/codegen/orm/models/domain.d.ts +6 -6
  8. package/codegen/orm/models/domain.js +3 -4
  9. package/codegen/orm/models/index.d.ts +1 -58
  10. package/codegen/orm/models/index.js +3 -118
  11. package/codegen/orm/mutation/index.d.ts +1 -525
  12. package/codegen/orm/mutation/index.js +2 -591
  13. package/codegen/orm/query/index.d.ts +3 -257
  14. package/codegen/orm/query/index.js +8 -274
  15. package/codegen/orm/query-builder.d.ts +2 -1
  16. package/codegen/orm/query-builder.js +376 -129
  17. package/codegen/orm/select-types.d.ts +33 -0
  18. package/esm/codegen/orm/index.js +4 -127
  19. package/esm/codegen/orm/input-types.js +0 -5
  20. package/esm/codegen/orm/models/api.js +3 -4
  21. package/esm/codegen/orm/models/domain.js +3 -4
  22. package/esm/codegen/orm/models/index.js +1 -58
  23. package/esm/codegen/orm/mutation/index.js +2 -591
  24. package/esm/codegen/orm/query/index.js +8 -274
  25. package/esm/codegen/orm/query-builder.js +343 -129
  26. package/esm/middleware/api.js +145 -173
  27. package/esm/middleware/gql.js +72 -71
  28. package/middleware/api.d.ts +16 -3
  29. package/middleware/api.js +148 -173
  30. package/middleware/gql.d.ts +174 -24
  31. package/middleware/gql.js +76 -76
  32. package/middleware/types.d.ts +3 -19
  33. package/package.json +7 -4
  34. package/types.d.ts +17 -44
  35. package/codegen/orm/models/apiExtension.d.ts +0 -42
  36. package/codegen/orm/models/apiExtension.js +0 -77
  37. package/codegen/orm/models/apiModule.d.ts +0 -42
  38. package/codegen/orm/models/apiModule.js +0 -77
  39. package/codegen/orm/models/apiSchema.d.ts +0 -42
  40. package/codegen/orm/models/apiSchema.js +0 -77
  41. package/codegen/orm/models/app.d.ts +0 -42
  42. package/codegen/orm/models/app.js +0 -77
  43. package/codegen/orm/models/checkConstraint.d.ts +0 -42
  44. package/codegen/orm/models/checkConstraint.js +0 -77
  45. package/codegen/orm/models/connectedAccountsModule.d.ts +0 -42
  46. package/codegen/orm/models/connectedAccountsModule.js +0 -77
  47. package/codegen/orm/models/cryptoAddressesModule.d.ts +0 -42
  48. package/codegen/orm/models/cryptoAddressesModule.js +0 -77
  49. package/codegen/orm/models/cryptoAuthModule.d.ts +0 -42
  50. package/codegen/orm/models/cryptoAuthModule.js +0 -77
  51. package/codegen/orm/models/database.d.ts +0 -42
  52. package/codegen/orm/models/database.js +0 -77
  53. package/codegen/orm/models/databaseExtension.d.ts +0 -42
  54. package/codegen/orm/models/databaseExtension.js +0 -77
  55. package/codegen/orm/models/databaseProvision.d.ts +0 -42
  56. package/codegen/orm/models/databaseProvision.js +0 -77
  57. package/codegen/orm/models/defaultIdsModule.d.ts +0 -42
  58. package/codegen/orm/models/defaultIdsModule.js +0 -77
  59. package/codegen/orm/models/denormalizedTableField.d.ts +0 -42
  60. package/codegen/orm/models/denormalizedTableField.js +0 -77
  61. package/codegen/orm/models/emailsModule.d.ts +0 -42
  62. package/codegen/orm/models/emailsModule.js +0 -77
  63. package/codegen/orm/models/encryptedSecretsModule.d.ts +0 -42
  64. package/codegen/orm/models/encryptedSecretsModule.js +0 -77
  65. package/codegen/orm/models/extension.d.ts +0 -42
  66. package/codegen/orm/models/extension.js +0 -77
  67. package/codegen/orm/models/field.d.ts +0 -42
  68. package/codegen/orm/models/field.js +0 -77
  69. package/codegen/orm/models/fieldModule.d.ts +0 -42
  70. package/codegen/orm/models/fieldModule.js +0 -77
  71. package/codegen/orm/models/foreignKeyConstraint.d.ts +0 -42
  72. package/codegen/orm/models/foreignKeyConstraint.js +0 -77
  73. package/codegen/orm/models/fullTextSearch.d.ts +0 -42
  74. package/codegen/orm/models/fullTextSearch.js +0 -77
  75. package/codegen/orm/models/hierarchyModule.d.ts +0 -42
  76. package/codegen/orm/models/hierarchyModule.js +0 -77
  77. package/codegen/orm/models/indexModel.d.ts +0 -42
  78. package/codegen/orm/models/indexModel.js +0 -77
  79. package/codegen/orm/models/invitesModule.d.ts +0 -42
  80. package/codegen/orm/models/invitesModule.js +0 -77
  81. package/codegen/orm/models/levelsModule.d.ts +0 -42
  82. package/codegen/orm/models/levelsModule.js +0 -77
  83. package/codegen/orm/models/limitFunction.d.ts +0 -42
  84. package/codegen/orm/models/limitFunction.js +0 -77
  85. package/codegen/orm/models/limitsModule.d.ts +0 -42
  86. package/codegen/orm/models/limitsModule.js +0 -77
  87. package/codegen/orm/models/membershipTypesModule.d.ts +0 -42
  88. package/codegen/orm/models/membershipTypesModule.js +0 -77
  89. package/codegen/orm/models/membershipsModule.d.ts +0 -42
  90. package/codegen/orm/models/membershipsModule.js +0 -77
  91. package/codegen/orm/models/module.d.ts +0 -42
  92. package/codegen/orm/models/module.js +0 -77
  93. package/codegen/orm/models/moduleDefinition.d.ts +0 -42
  94. package/codegen/orm/models/moduleDefinition.js +0 -77
  95. package/codegen/orm/models/moduleField.d.ts +0 -42
  96. package/codegen/orm/models/moduleField.js +0 -77
  97. package/codegen/orm/models/moduleInputRecord.d.ts +0 -42
  98. package/codegen/orm/models/moduleInputRecord.js +0 -77
  99. package/codegen/orm/models/moduleOutput.d.ts +0 -42
  100. package/codegen/orm/models/moduleOutput.js +0 -77
  101. package/codegen/orm/models/permissionsModule.d.ts +0 -42
  102. package/codegen/orm/models/permissionsModule.js +0 -77
  103. package/codegen/orm/models/phoneNumbersModule.d.ts +0 -42
  104. package/codegen/orm/models/phoneNumbersModule.js +0 -77
  105. package/codegen/orm/models/policy.d.ts +0 -42
  106. package/codegen/orm/models/policy.js +0 -77
  107. package/codegen/orm/models/primaryKeyConstraint.d.ts +0 -42
  108. package/codegen/orm/models/primaryKeyConstraint.js +0 -77
  109. package/codegen/orm/models/procedure.d.ts +0 -42
  110. package/codegen/orm/models/procedure.js +0 -77
  111. package/codegen/orm/models/profilesModule.d.ts +0 -42
  112. package/codegen/orm/models/profilesModule.js +0 -77
  113. package/codegen/orm/models/rlsFunction.d.ts +0 -42
  114. package/codegen/orm/models/rlsFunction.js +0 -77
  115. package/codegen/orm/models/rlsModule.d.ts +0 -42
  116. package/codegen/orm/models/rlsModule.js +0 -77
  117. package/codegen/orm/models/schema.d.ts +0 -42
  118. package/codegen/orm/models/schema.js +0 -77
  119. package/codegen/orm/models/schemaGrant.d.ts +0 -42
  120. package/codegen/orm/models/schemaGrant.js +0 -77
  121. package/codegen/orm/models/secretsModule.d.ts +0 -42
  122. package/codegen/orm/models/secretsModule.js +0 -77
  123. package/codegen/orm/models/site.d.ts +0 -42
  124. package/codegen/orm/models/site.js +0 -77
  125. package/codegen/orm/models/siteMetadatum.d.ts +0 -42
  126. package/codegen/orm/models/siteMetadatum.js +0 -77
  127. package/codegen/orm/models/siteModule.d.ts +0 -42
  128. package/codegen/orm/models/siteModule.js +0 -77
  129. package/codegen/orm/models/siteTheme.d.ts +0 -42
  130. package/codegen/orm/models/siteTheme.js +0 -77
  131. package/codegen/orm/models/table.d.ts +0 -42
  132. package/codegen/orm/models/table.js +0 -77
  133. package/codegen/orm/models/tableGrant.d.ts +0 -42
  134. package/codegen/orm/models/tableGrant.js +0 -77
  135. package/codegen/orm/models/tokensModule.d.ts +0 -42
  136. package/codegen/orm/models/tokensModule.js +0 -77
  137. package/codegen/orm/models/trigger.d.ts +0 -42
  138. package/codegen/orm/models/trigger.js +0 -77
  139. package/codegen/orm/models/triggerFunction.d.ts +0 -42
  140. package/codegen/orm/models/triggerFunction.js +0 -77
  141. package/codegen/orm/models/uniqueConstraint.d.ts +0 -42
  142. package/codegen/orm/models/uniqueConstraint.js +0 -77
  143. package/codegen/orm/models/userAuthModule.d.ts +0 -42
  144. package/codegen/orm/models/userAuthModule.js +0 -77
  145. package/codegen/orm/models/usersModule.d.ts +0 -42
  146. package/codegen/orm/models/usersModule.js +0 -77
  147. package/codegen/orm/models/uuidModule.d.ts +0 -42
  148. package/codegen/orm/models/uuidModule.js +0 -77
  149. package/esm/codegen/orm/models/apiExtension.js +0 -73
  150. package/esm/codegen/orm/models/apiModule.js +0 -73
  151. package/esm/codegen/orm/models/apiSchema.js +0 -73
  152. package/esm/codegen/orm/models/app.js +0 -73
  153. package/esm/codegen/orm/models/checkConstraint.js +0 -73
  154. package/esm/codegen/orm/models/connectedAccountsModule.js +0 -73
  155. package/esm/codegen/orm/models/cryptoAddressesModule.js +0 -73
  156. package/esm/codegen/orm/models/cryptoAuthModule.js +0 -73
  157. package/esm/codegen/orm/models/database.js +0 -73
  158. package/esm/codegen/orm/models/databaseExtension.js +0 -73
  159. package/esm/codegen/orm/models/databaseProvision.js +0 -73
  160. package/esm/codegen/orm/models/defaultIdsModule.js +0 -73
  161. package/esm/codegen/orm/models/denormalizedTableField.js +0 -73
  162. package/esm/codegen/orm/models/emailsModule.js +0 -73
  163. package/esm/codegen/orm/models/encryptedSecretsModule.js +0 -73
  164. package/esm/codegen/orm/models/extension.js +0 -73
  165. package/esm/codegen/orm/models/field.js +0 -73
  166. package/esm/codegen/orm/models/fieldModule.js +0 -73
  167. package/esm/codegen/orm/models/foreignKeyConstraint.js +0 -73
  168. package/esm/codegen/orm/models/fullTextSearch.js +0 -73
  169. package/esm/codegen/orm/models/hierarchyModule.js +0 -73
  170. package/esm/codegen/orm/models/indexModel.js +0 -73
  171. package/esm/codegen/orm/models/invitesModule.js +0 -73
  172. package/esm/codegen/orm/models/levelsModule.js +0 -73
  173. package/esm/codegen/orm/models/limitFunction.js +0 -73
  174. package/esm/codegen/orm/models/limitsModule.js +0 -73
  175. package/esm/codegen/orm/models/membershipTypesModule.js +0 -73
  176. package/esm/codegen/orm/models/membershipsModule.js +0 -73
  177. package/esm/codegen/orm/models/module.js +0 -73
  178. package/esm/codegen/orm/models/moduleDefinition.js +0 -73
  179. package/esm/codegen/orm/models/moduleField.js +0 -73
  180. package/esm/codegen/orm/models/moduleInputRecord.js +0 -73
  181. package/esm/codegen/orm/models/moduleOutput.js +0 -73
  182. package/esm/codegen/orm/models/permissionsModule.js +0 -73
  183. package/esm/codegen/orm/models/phoneNumbersModule.js +0 -73
  184. package/esm/codegen/orm/models/policy.js +0 -73
  185. package/esm/codegen/orm/models/primaryKeyConstraint.js +0 -73
  186. package/esm/codegen/orm/models/procedure.js +0 -73
  187. package/esm/codegen/orm/models/profilesModule.js +0 -73
  188. package/esm/codegen/orm/models/rlsFunction.js +0 -73
  189. package/esm/codegen/orm/models/rlsModule.js +0 -73
  190. package/esm/codegen/orm/models/schema.js +0 -73
  191. package/esm/codegen/orm/models/schemaGrant.js +0 -73
  192. package/esm/codegen/orm/models/secretsModule.js +0 -73
  193. package/esm/codegen/orm/models/site.js +0 -73
  194. package/esm/codegen/orm/models/siteMetadatum.js +0 -73
  195. package/esm/codegen/orm/models/siteModule.js +0 -73
  196. package/esm/codegen/orm/models/siteTheme.js +0 -73
  197. package/esm/codegen/orm/models/table.js +0 -73
  198. package/esm/codegen/orm/models/tableGrant.js +0 -73
  199. package/esm/codegen/orm/models/tokensModule.js +0 -73
  200. package/esm/codegen/orm/models/trigger.js +0 -73
  201. package/esm/codegen/orm/models/triggerFunction.js +0 -73
  202. package/esm/codegen/orm/models/uniqueConstraint.js +0 -73
  203. package/esm/codegen/orm/models/userAuthModule.js +0 -73
  204. package/esm/codegen/orm/models/usersModule.js +0 -73
  205. package/esm/codegen/orm/models/uuidModule.js +0 -73
@@ -4,6 +4,39 @@
4
4
  * @generated by @constructive-io/graphql-codegen
5
5
  * DO NOT EDIT - changes will be overwritten
6
6
  */
7
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
+ if (k2 === undefined) k2 = k;
9
+ var desc = Object.getOwnPropertyDescriptor(m, k);
10
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
+ desc = { enumerable: true, get: function() { return m[k]; } };
12
+ }
13
+ Object.defineProperty(o, k2, desc);
14
+ }) : (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ o[k2] = m[k];
17
+ }));
18
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
20
+ }) : function(o, v) {
21
+ o["default"] = v;
22
+ });
23
+ var __importStar = (this && this.__importStar) || (function () {
24
+ var ownKeys = function(o) {
25
+ ownKeys = Object.getOwnPropertyNames || function (o) {
26
+ var ar = [];
27
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
28
+ return ar;
29
+ };
30
+ return ownKeys(o);
31
+ };
32
+ return function (mod) {
33
+ if (mod && mod.__esModule) return mod;
34
+ var result = {};
35
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
36
+ __setModuleDefault(result, mod);
37
+ return result;
38
+ };
39
+ })();
7
40
  Object.defineProperty(exports, "__esModule", { value: true });
8
41
  exports.QueryBuilder = void 0;
9
42
  exports.buildSelections = buildSelections;
@@ -13,6 +46,8 @@ exports.buildCreateDocument = buildCreateDocument;
13
46
  exports.buildUpdateDocument = buildUpdateDocument;
14
47
  exports.buildDeleteDocument = buildDeleteDocument;
15
48
  exports.buildCustomDocument = buildCustomDocument;
49
+ const t = __importStar(require("gql-ast"));
50
+ const graphql_1 = require("graphql");
16
51
  const client_1 = require("./client");
17
52
  class QueryBuilder {
18
53
  config;
@@ -66,155 +101,221 @@ class QueryBuilder {
66
101
  }
67
102
  exports.QueryBuilder = QueryBuilder;
68
103
  // ============================================================================
69
- // Document Builders
104
+ // Selection Builders
70
105
  // ============================================================================
71
106
  function buildSelections(select) {
72
- if (!select)
73
- return '';
107
+ if (!select) {
108
+ return [];
109
+ }
74
110
  const fields = [];
75
111
  for (const [key, value] of Object.entries(select)) {
76
- if (value === false || value === undefined)
112
+ if (value === false || value === undefined) {
77
113
  continue;
114
+ }
78
115
  if (value === true) {
79
- fields.push(key);
116
+ fields.push(t.field({ name: key }));
80
117
  continue;
81
118
  }
82
119
  if (typeof value === 'object' && value !== null) {
83
120
  const nested = value;
84
121
  if (nested.select) {
85
122
  const nestedSelections = buildSelections(nested.select);
86
- // Check if this is a connection type (has pagination args or explicit connection flag)
87
123
  const isConnection = nested.connection === true ||
88
124
  nested.first !== undefined ||
89
125
  nested.filter !== undefined;
126
+ const args = buildArgs([
127
+ buildOptionalArg('first', nested.first),
128
+ nested.filter
129
+ ? t.argument({
130
+ name: 'filter',
131
+ value: buildValueAst(nested.filter),
132
+ })
133
+ : null,
134
+ buildEnumListArg('orderBy', nested.orderBy),
135
+ ]);
90
136
  if (isConnection) {
91
- // Connection type - wrap in nodes/totalCount/pageInfo
92
- const args = [];
93
- if (nested.first !== undefined)
94
- args.push(`first: ${nested.first}`);
95
- if (nested.orderBy?.length)
96
- args.push(`orderBy: [${nested.orderBy.join(', ')}]`);
97
- const argsStr = args.length > 0 ? `(${args.join(', ')})` : '';
98
- fields.push(`${key}${argsStr} {
99
- nodes { ${nestedSelections} }
100
- totalCount
101
- pageInfo { hasNextPage hasPreviousPage startCursor endCursor }
102
- }`);
137
+ fields.push(t.field({
138
+ name: key,
139
+ args,
140
+ selectionSet: t.selectionSet({
141
+ selections: buildConnectionSelections(nestedSelections),
142
+ }),
143
+ }));
103
144
  }
104
145
  else {
105
- // Regular nested object - just wrap in braces
106
- fields.push(`${key} { ${nestedSelections} }`);
146
+ fields.push(t.field({
147
+ name: key,
148
+ args,
149
+ selectionSet: t.selectionSet({ selections: nestedSelections }),
150
+ }));
107
151
  }
108
152
  }
109
153
  }
110
154
  }
111
- return fields.join('\n ');
155
+ return fields;
112
156
  }
157
+ // ============================================================================
158
+ // Document Builders
159
+ // ============================================================================
113
160
  function buildFindManyDocument(operationName, queryField, select, args, filterTypeName, orderByTypeName) {
114
- const selections = select ? buildSelections(select) : 'id';
115
- const varDefs = [];
161
+ const selections = select
162
+ ? buildSelections(select)
163
+ : [t.field({ name: 'id' })];
164
+ const variableDefinitions = [];
116
165
  const queryArgs = [];
117
166
  const variables = {};
118
- if (args.where) {
119
- varDefs.push(`$where: ${filterTypeName}`);
120
- queryArgs.push('filter: $where');
121
- variables.where = args.where;
122
- }
123
- if (args.orderBy?.length) {
124
- varDefs.push(`$orderBy: [${orderByTypeName}!]`);
125
- queryArgs.push('orderBy: $orderBy');
126
- variables.orderBy = args.orderBy;
127
- }
128
- if (args.first !== undefined) {
129
- varDefs.push('$first: Int');
130
- queryArgs.push('first: $first');
131
- variables.first = args.first;
132
- }
133
- if (args.last !== undefined) {
134
- varDefs.push('$last: Int');
135
- queryArgs.push('last: $last');
136
- variables.last = args.last;
137
- }
138
- if (args.after) {
139
- varDefs.push('$after: Cursor');
140
- queryArgs.push('after: $after');
141
- variables.after = args.after;
142
- }
143
- if (args.before) {
144
- varDefs.push('$before: Cursor');
145
- queryArgs.push('before: $before');
146
- variables.before = args.before;
147
- }
148
- if (args.offset !== undefined) {
149
- varDefs.push('$offset: Int');
150
- queryArgs.push('offset: $offset');
151
- variables.offset = args.offset;
152
- }
153
- const varDefsStr = varDefs.length > 0 ? `(${varDefs.join(', ')})` : '';
154
- const queryArgsStr = queryArgs.length > 0 ? `(${queryArgs.join(', ')})` : '';
155
- const document = `query ${operationName}Query${varDefsStr} {
156
- ${queryField}${queryArgsStr} {
157
- nodes { ${selections} }
158
- totalCount
159
- pageInfo { hasNextPage hasPreviousPage startCursor endCursor }
160
- }
161
- }`;
162
- return { document, variables };
167
+ addVariable({
168
+ varName: 'where',
169
+ argName: 'filter',
170
+ typeName: filterTypeName,
171
+ value: args.where,
172
+ }, variableDefinitions, queryArgs, variables);
173
+ addVariable({
174
+ varName: 'orderBy',
175
+ typeName: '[' + orderByTypeName + '!]',
176
+ value: args.orderBy?.length ? args.orderBy : undefined,
177
+ }, variableDefinitions, queryArgs, variables);
178
+ addVariable({ varName: 'first', typeName: 'Int', value: args.first }, variableDefinitions, queryArgs, variables);
179
+ addVariable({ varName: 'last', typeName: 'Int', value: args.last }, variableDefinitions, queryArgs, variables);
180
+ addVariable({ varName: 'after', typeName: 'Cursor', value: args.after }, variableDefinitions, queryArgs, variables);
181
+ addVariable({ varName: 'before', typeName: 'Cursor', value: args.before }, variableDefinitions, queryArgs, variables);
182
+ addVariable({ varName: 'offset', typeName: 'Int', value: args.offset }, variableDefinitions, queryArgs, variables);
183
+ const document = t.document({
184
+ definitions: [
185
+ t.operationDefinition({
186
+ operation: 'query',
187
+ name: operationName + 'Query',
188
+ variableDefinitions: variableDefinitions.length
189
+ ? variableDefinitions
190
+ : undefined,
191
+ selectionSet: t.selectionSet({
192
+ selections: [
193
+ t.field({
194
+ name: queryField,
195
+ args: queryArgs.length ? queryArgs : undefined,
196
+ selectionSet: t.selectionSet({
197
+ selections: buildConnectionSelections(selections),
198
+ }),
199
+ }),
200
+ ],
201
+ }),
202
+ }),
203
+ ],
204
+ });
205
+ return { document: (0, graphql_1.print)(document), variables };
163
206
  }
164
207
  function buildFindFirstDocument(operationName, queryField, select, args, filterTypeName) {
165
- const selections = select ? buildSelections(select) : 'id';
166
- const varDefs = ['$first: Int'];
167
- const queryArgs = ['first: $first'];
168
- const variables = { first: 1 };
169
- if (args.where) {
170
- varDefs.push(`$where: ${filterTypeName}`);
171
- queryArgs.push('filter: $where');
172
- variables.where = args.where;
173
- }
174
- const document = `query ${operationName}Query(${varDefs.join(', ')}) {
175
- ${queryField}(${queryArgs.join(', ')}) {
176
- nodes { ${selections} }
177
- }
178
- }`;
179
- return { document, variables };
208
+ const selections = select
209
+ ? buildSelections(select)
210
+ : [t.field({ name: 'id' })];
211
+ const variableDefinitions = [];
212
+ const queryArgs = [];
213
+ const variables = {};
214
+ // Always add first: 1 for findFirst
215
+ addVariable({ varName: 'first', typeName: 'Int', value: 1 }, variableDefinitions, queryArgs, variables);
216
+ addVariable({
217
+ varName: 'where',
218
+ argName: 'filter',
219
+ typeName: filterTypeName,
220
+ value: args.where,
221
+ }, variableDefinitions, queryArgs, variables);
222
+ const document = t.document({
223
+ definitions: [
224
+ t.operationDefinition({
225
+ operation: 'query',
226
+ name: operationName + 'Query',
227
+ variableDefinitions,
228
+ selectionSet: t.selectionSet({
229
+ selections: [
230
+ t.field({
231
+ name: queryField,
232
+ args: queryArgs,
233
+ selectionSet: t.selectionSet({
234
+ selections: [
235
+ t.field({
236
+ name: 'nodes',
237
+ selectionSet: t.selectionSet({ selections }),
238
+ }),
239
+ ],
240
+ }),
241
+ }),
242
+ ],
243
+ }),
244
+ }),
245
+ ],
246
+ });
247
+ return { document: (0, graphql_1.print)(document), variables };
180
248
  }
181
249
  function buildCreateDocument(operationName, mutationField, entityField, select, data, inputTypeName) {
182
- const selections = select ? buildSelections(select) : 'id';
183
- const document = `mutation ${operationName}Mutation($input: ${inputTypeName}!) {
184
- ${mutationField}(input: $input) {
185
- ${entityField} { ${selections} }
186
- }
187
- }`;
250
+ const selections = select
251
+ ? buildSelections(select)
252
+ : [t.field({ name: 'id' })];
188
253
  return {
189
- document,
190
- variables: { input: { [entityField]: data } },
254
+ document: buildInputMutationDocument({
255
+ operationName,
256
+ mutationField,
257
+ inputTypeName,
258
+ resultSelections: [
259
+ t.field({
260
+ name: entityField,
261
+ selectionSet: t.selectionSet({ selections }),
262
+ }),
263
+ ],
264
+ }),
265
+ variables: {
266
+ input: {
267
+ [entityField]: data,
268
+ },
269
+ },
191
270
  };
192
271
  }
193
272
  function buildUpdateDocument(operationName, mutationField, entityField, select, where, data, inputTypeName) {
194
- const selections = select ? buildSelections(select) : 'id';
195
- const document = `mutation ${operationName}Mutation($input: ${inputTypeName}!) {
196
- ${mutationField}(input: $input) {
197
- ${entityField} { ${selections} }
198
- }
199
- }`;
273
+ const selections = select
274
+ ? buildSelections(select)
275
+ : [t.field({ name: 'id' })];
200
276
  return {
201
- document,
202
- variables: { input: { id: where.id, patch: data } },
277
+ document: buildInputMutationDocument({
278
+ operationName,
279
+ mutationField,
280
+ inputTypeName,
281
+ resultSelections: [
282
+ t.field({
283
+ name: entityField,
284
+ selectionSet: t.selectionSet({ selections }),
285
+ }),
286
+ ],
287
+ }),
288
+ variables: {
289
+ input: {
290
+ id: where.id,
291
+ patch: data,
292
+ },
293
+ },
203
294
  };
204
295
  }
205
296
  function buildDeleteDocument(operationName, mutationField, entityField, where, inputTypeName) {
206
- const document = `mutation ${operationName}Mutation($input: ${inputTypeName}!) {
207
- ${mutationField}(input: $input) {
208
- ${entityField} { id }
209
- }
210
- }`;
211
297
  return {
212
- document,
213
- variables: { input: { id: where.id } },
298
+ document: buildInputMutationDocument({
299
+ operationName,
300
+ mutationField,
301
+ inputTypeName,
302
+ resultSelections: [
303
+ t.field({
304
+ name: entityField,
305
+ selectionSet: t.selectionSet({
306
+ selections: [t.field({ name: 'id' })],
307
+ }),
308
+ }),
309
+ ],
310
+ }),
311
+ variables: {
312
+ input: {
313
+ id: where.id,
314
+ },
315
+ },
214
316
  };
215
317
  }
216
318
  function buildCustomDocument(operationType, operationName, fieldName, select, args, variableDefinitions) {
217
- // Check if select is wrapped with connection metadata
218
319
  let actualSelect = select;
219
320
  let isConnection = false;
220
321
  if (select && typeof select === 'object' && 'select' in select) {
@@ -224,26 +325,172 @@ function buildCustomDocument(operationType, operationName, fieldName, select, ar
224
325
  isConnection = wrapper.connection === true;
225
326
  }
226
327
  }
227
- const selections = actualSelect ? buildSelections(actualSelect) : '';
228
- const varDefs = variableDefinitions.map((v) => `$${v.name}: ${v.type}`);
229
- const fieldArgs = variableDefinitions.map((v) => `${v.name}: $${v.name}`);
230
- const varDefsStr = varDefs.length > 0 ? `(${varDefs.join(', ')})` : '';
231
- const fieldArgsStr = fieldArgs.length > 0 ? `(${fieldArgs.join(', ')})` : '';
232
- let selectionsBlock;
233
- if (isConnection) {
234
- // Wrap in connection structure
235
- selectionsBlock = ` {
236
- nodes { ${selections} }
237
- totalCount
238
- pageInfo { hasNextPage hasPreviousPage startCursor endCursor }
239
- }`;
240
- }
241
- else {
242
- selectionsBlock = selections ? ` { ${selections} }` : '';
243
- }
244
- const opType = operationType === 'query' ? 'query' : 'mutation';
245
- const document = `${opType} ${operationName}${varDefsStr} {
246
- ${fieldName}${fieldArgsStr}${selectionsBlock}
247
- }`;
248
- return { document, variables: (args ?? {}) };
328
+ const selections = actualSelect
329
+ ? buildSelections(actualSelect)
330
+ : [];
331
+ const variableDefs = variableDefinitions.map((definition) => t.variableDefinition({
332
+ variable: t.variable({ name: definition.name }),
333
+ type: (0, graphql_1.parseType)(definition.type),
334
+ }));
335
+ const fieldArgs = variableDefinitions.map((definition) => t.argument({
336
+ name: definition.name,
337
+ value: t.variable({ name: definition.name }),
338
+ }));
339
+ const fieldSelections = isConnection
340
+ ? buildConnectionSelections(selections)
341
+ : selections;
342
+ const document = t.document({
343
+ definitions: [
344
+ t.operationDefinition({
345
+ operation: operationType,
346
+ name: operationName,
347
+ variableDefinitions: variableDefs.length ? variableDefs : undefined,
348
+ selectionSet: t.selectionSet({
349
+ selections: [
350
+ t.field({
351
+ name: fieldName,
352
+ args: fieldArgs.length ? fieldArgs : undefined,
353
+ selectionSet: fieldSelections.length
354
+ ? t.selectionSet({ selections: fieldSelections })
355
+ : undefined,
356
+ }),
357
+ ],
358
+ }),
359
+ }),
360
+ ],
361
+ });
362
+ return {
363
+ document: (0, graphql_1.print)(document),
364
+ variables: (args ?? {}),
365
+ };
366
+ }
367
+ // ============================================================================
368
+ // Helper Functions
369
+ // ============================================================================
370
+ function buildArgs(args) {
371
+ return args.filter((arg) => arg !== null);
372
+ }
373
+ function buildOptionalArg(name, value) {
374
+ if (value === undefined) {
375
+ return null;
376
+ }
377
+ const valueNode = typeof value === 'number'
378
+ ? t.intValue({ value: value.toString() })
379
+ : t.stringValue({ value });
380
+ return t.argument({ name, value: valueNode });
381
+ }
382
+ function buildEnumListArg(name, values) {
383
+ if (!values || values.length === 0) {
384
+ return null;
385
+ }
386
+ return t.argument({
387
+ name,
388
+ value: t.listValue({
389
+ values: values.map((value) => buildEnumValue(value)),
390
+ }),
391
+ });
392
+ }
393
+ function buildEnumValue(value) {
394
+ return {
395
+ kind: 'EnumValue',
396
+ value,
397
+ };
398
+ }
399
+ function buildPageInfoSelections() {
400
+ return [
401
+ t.field({ name: 'hasNextPage' }),
402
+ t.field({ name: 'hasPreviousPage' }),
403
+ t.field({ name: 'startCursor' }),
404
+ t.field({ name: 'endCursor' }),
405
+ ];
406
+ }
407
+ function buildConnectionSelections(nodeSelections) {
408
+ return [
409
+ t.field({
410
+ name: 'nodes',
411
+ selectionSet: t.selectionSet({ selections: nodeSelections }),
412
+ }),
413
+ t.field({ name: 'totalCount' }),
414
+ t.field({
415
+ name: 'pageInfo',
416
+ selectionSet: t.selectionSet({ selections: buildPageInfoSelections() }),
417
+ }),
418
+ ];
419
+ }
420
+ function buildInputMutationDocument(config) {
421
+ const document = t.document({
422
+ definitions: [
423
+ t.operationDefinition({
424
+ operation: 'mutation',
425
+ name: config.operationName + 'Mutation',
426
+ variableDefinitions: [
427
+ t.variableDefinition({
428
+ variable: t.variable({ name: 'input' }),
429
+ type: (0, graphql_1.parseType)(config.inputTypeName + '!'),
430
+ }),
431
+ ],
432
+ selectionSet: t.selectionSet({
433
+ selections: [
434
+ t.field({
435
+ name: config.mutationField,
436
+ args: [
437
+ t.argument({
438
+ name: 'input',
439
+ value: t.variable({ name: 'input' }),
440
+ }),
441
+ ],
442
+ selectionSet: t.selectionSet({
443
+ selections: config.resultSelections,
444
+ }),
445
+ }),
446
+ ],
447
+ }),
448
+ }),
449
+ ],
450
+ });
451
+ return (0, graphql_1.print)(document);
452
+ }
453
+ function addVariable(spec, definitions, args, variables) {
454
+ if (spec.value === undefined)
455
+ return;
456
+ definitions.push(t.variableDefinition({
457
+ variable: t.variable({ name: spec.varName }),
458
+ type: (0, graphql_1.parseType)(spec.typeName),
459
+ }));
460
+ args.push(t.argument({
461
+ name: spec.argName ?? spec.varName,
462
+ value: t.variable({ name: spec.varName }),
463
+ }));
464
+ variables[spec.varName] = spec.value;
465
+ }
466
+ function buildValueAst(value) {
467
+ if (value === null) {
468
+ return t.nullValue();
469
+ }
470
+ if (typeof value === 'boolean') {
471
+ return t.booleanValue({ value });
472
+ }
473
+ if (typeof value === 'number') {
474
+ return Number.isInteger(value)
475
+ ? t.intValue({ value: value.toString() })
476
+ : t.floatValue({ value: value.toString() });
477
+ }
478
+ if (typeof value === 'string') {
479
+ return t.stringValue({ value });
480
+ }
481
+ if (Array.isArray(value)) {
482
+ return t.listValue({
483
+ values: value.map((item) => buildValueAst(item)),
484
+ });
485
+ }
486
+ if (typeof value === 'object' && value !== null) {
487
+ const obj = value;
488
+ return t.objectValue({
489
+ fields: Object.entries(obj).map(([key, val]) => t.objectField({
490
+ name: key,
491
+ value: buildValueAst(val),
492
+ })),
493
+ });
494
+ }
495
+ throw new Error('Unsupported value type: ' + typeof value);
249
496
  }
@@ -40,6 +40,39 @@ export interface UpdateArgs<TSelect, TWhere, TData> {
40
40
  export interface DeleteArgs<TWhere> {
41
41
  where: TWhere;
42
42
  }
43
+ /**
44
+ * Recursively validates select objects, rejecting unknown keys.
45
+ *
46
+ * This type ensures that users can only select fields that actually exist
47
+ * in the GraphQL schema. It returns `never` if any excess keys are found
48
+ * at any nesting level, causing a TypeScript compile error.
49
+ *
50
+ * Why this is needed:
51
+ * TypeScript's excess property checking has a quirk where it only catches
52
+ * invalid fields when they are the ONLY fields. When mixed with valid fields
53
+ * (e.g., `{ id: true, invalidField: true }`), the structural typing allows
54
+ * the excess property through. This type explicitly checks for and rejects
55
+ * such cases.
56
+ *
57
+ * @example
58
+ * // This will cause a type error because 'invalid' doesn't exist:
59
+ * type Result = DeepExact<{ id: true, invalid: true }, { id?: boolean }>;
60
+ * // Result = never (causes assignment error)
61
+ *
62
+ * @example
63
+ * // This works because all fields are valid:
64
+ * type Result = DeepExact<{ id: true }, { id?: boolean; name?: boolean }>;
65
+ * // Result = { id: true }
66
+ */
67
+ export type DeepExact<T, Shape> = T extends Shape ? Exclude<keyof T, keyof Shape> extends never ? {
68
+ [K in keyof T]: K extends keyof Shape ? T[K] extends {
69
+ select: infer NS;
70
+ } ? Shape[K] extends {
71
+ select?: infer ShapeNS;
72
+ } ? {
73
+ select: DeepExact<NS, NonNullable<ShapeNS>>;
74
+ } : T[K] : T[K] : never;
75
+ } : never : never;
43
76
  /**
44
77
  * Infer result type from select configuration
45
78
  */