@proofkit/fmodata 0.1.0-alpha.13 → 0.1.0-alpha.14

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 (143) hide show
  1. package/README.md +489 -334
  2. package/dist/esm/client/batch-builder.d.ts +7 -4
  3. package/dist/esm/client/batch-builder.js +84 -25
  4. package/dist/esm/client/batch-builder.js.map +1 -1
  5. package/dist/esm/client/builders/default-select.d.ts +7 -0
  6. package/dist/esm/client/builders/default-select.js +42 -0
  7. package/dist/esm/client/builders/default-select.js.map +1 -0
  8. package/dist/esm/client/builders/expand-builder.d.ts +43 -0
  9. package/dist/esm/client/builders/expand-builder.js +173 -0
  10. package/dist/esm/client/builders/expand-builder.js.map +1 -0
  11. package/dist/esm/client/builders/index.d.ts +8 -0
  12. package/dist/esm/client/builders/query-string-builder.d.ts +15 -0
  13. package/dist/esm/client/builders/query-string-builder.js +25 -0
  14. package/dist/esm/client/builders/query-string-builder.js.map +1 -0
  15. package/dist/esm/client/builders/response-processor.d.ts +39 -0
  16. package/dist/esm/client/builders/response-processor.js +170 -0
  17. package/dist/esm/client/builders/response-processor.js.map +1 -0
  18. package/dist/esm/client/builders/select-mixin.d.ts +31 -0
  19. package/dist/esm/client/builders/select-mixin.js +30 -0
  20. package/dist/esm/client/builders/select-mixin.js.map +1 -0
  21. package/dist/esm/client/builders/select-utils.d.ts +8 -0
  22. package/dist/esm/client/builders/select-utils.js +15 -0
  23. package/dist/esm/client/builders/select-utils.js.map +1 -0
  24. package/dist/esm/client/builders/shared-types.d.ts +39 -0
  25. package/dist/esm/client/builders/table-utils.d.ts +35 -0
  26. package/dist/esm/client/builders/table-utils.js +45 -0
  27. package/dist/esm/client/builders/table-utils.js.map +1 -0
  28. package/dist/esm/client/database.d.ts +3 -22
  29. package/dist/esm/client/database.js +14 -76
  30. package/dist/esm/client/database.js.map +1 -1
  31. package/dist/esm/client/delete-builder.d.ts +11 -15
  32. package/dist/esm/client/delete-builder.js +26 -26
  33. package/dist/esm/client/delete-builder.js.map +1 -1
  34. package/dist/esm/client/entity-set.d.ts +32 -32
  35. package/dist/esm/client/entity-set.js +92 -69
  36. package/dist/esm/client/entity-set.js.map +1 -1
  37. package/dist/esm/client/error-parser.d.ts +12 -0
  38. package/dist/esm/client/error-parser.js +30 -0
  39. package/dist/esm/client/error-parser.js.map +1 -0
  40. package/dist/esm/client/filemaker-odata.d.ts +2 -4
  41. package/dist/esm/client/filemaker-odata.js +1 -5
  42. package/dist/esm/client/filemaker-odata.js.map +1 -1
  43. package/dist/esm/client/insert-builder.d.ts +7 -9
  44. package/dist/esm/client/insert-builder.js +70 -24
  45. package/dist/esm/client/insert-builder.js.map +1 -1
  46. package/dist/esm/client/query/expand-builder.d.ts +35 -0
  47. package/dist/esm/client/query/index.d.ts +3 -0
  48. package/dist/esm/client/query/query-builder.d.ts +134 -0
  49. package/dist/esm/client/query/query-builder.js +505 -0
  50. package/dist/esm/client/query/query-builder.js.map +1 -0
  51. package/dist/esm/client/query/response-processor.d.ts +22 -0
  52. package/dist/esm/client/query/types.d.ts +52 -0
  53. package/dist/esm/client/query/url-builder.d.ts +71 -0
  54. package/dist/esm/client/query/url-builder.js +107 -0
  55. package/dist/esm/client/query/url-builder.js.map +1 -0
  56. package/dist/esm/client/query-builder.d.ts +1 -111
  57. package/dist/esm/client/record-builder.d.ts +56 -63
  58. package/dist/esm/client/record-builder.js +158 -297
  59. package/dist/esm/client/record-builder.js.map +1 -1
  60. package/dist/esm/client/response-processor.d.ts +3 -3
  61. package/dist/esm/client/update-builder.d.ts +16 -21
  62. package/dist/esm/client/update-builder.js +56 -30
  63. package/dist/esm/client/update-builder.js.map +1 -1
  64. package/dist/esm/errors.d.ts +8 -1
  65. package/dist/esm/errors.js +17 -0
  66. package/dist/esm/errors.js.map +1 -1
  67. package/dist/esm/index.d.ts +3 -7
  68. package/dist/esm/index.js +37 -8
  69. package/dist/esm/index.js.map +1 -1
  70. package/dist/esm/orm/column.d.ts +45 -0
  71. package/dist/esm/orm/column.js +59 -0
  72. package/dist/esm/orm/column.js.map +1 -0
  73. package/dist/esm/orm/field-builders.d.ts +154 -0
  74. package/dist/esm/orm/field-builders.js +152 -0
  75. package/dist/esm/orm/field-builders.js.map +1 -0
  76. package/dist/esm/orm/index.d.ts +4 -0
  77. package/dist/esm/orm/operators.d.ts +175 -0
  78. package/dist/esm/orm/operators.js +221 -0
  79. package/dist/esm/orm/operators.js.map +1 -0
  80. package/dist/esm/orm/table.d.ts +341 -0
  81. package/dist/esm/orm/table.js +211 -0
  82. package/dist/esm/orm/table.js.map +1 -0
  83. package/dist/esm/transform.d.ts +20 -21
  84. package/dist/esm/transform.js +34 -34
  85. package/dist/esm/transform.js.map +1 -1
  86. package/dist/esm/types.d.ts +16 -13
  87. package/dist/esm/types.js.map +1 -1
  88. package/dist/esm/validation.d.ts +14 -4
  89. package/dist/esm/validation.js +45 -1
  90. package/dist/esm/validation.js.map +1 -1
  91. package/package.json +20 -17
  92. package/src/client/batch-builder.ts +100 -32
  93. package/src/client/builders/default-select.ts +69 -0
  94. package/src/client/builders/expand-builder.ts +236 -0
  95. package/src/client/builders/index.ts +11 -0
  96. package/src/client/builders/query-string-builder.ts +41 -0
  97. package/src/client/builders/response-processor.ts +273 -0
  98. package/src/client/builders/select-mixin.ts +74 -0
  99. package/src/client/builders/select-utils.ts +34 -0
  100. package/src/client/builders/shared-types.ts +41 -0
  101. package/src/client/builders/table-utils.ts +87 -0
  102. package/src/client/database.ts +19 -160
  103. package/src/client/delete-builder.ts +46 -51
  104. package/src/client/entity-set.ts +227 -302
  105. package/src/client/error-parser.ts +59 -0
  106. package/src/client/filemaker-odata.ts +3 -14
  107. package/src/client/insert-builder.ts +124 -43
  108. package/src/client/query/expand-builder.ts +164 -0
  109. package/src/client/query/index.ts +13 -0
  110. package/src/client/query/query-builder.ts +816 -0
  111. package/src/client/query/response-processor.ts +244 -0
  112. package/src/client/query/types.ts +102 -0
  113. package/src/client/query/url-builder.ts +179 -0
  114. package/src/client/query-builder.ts +8 -1454
  115. package/src/client/record-builder.ts +325 -585
  116. package/src/client/response-processor.ts +4 -5
  117. package/src/client/update-builder.ts +102 -73
  118. package/src/errors.ts +22 -1
  119. package/src/index.ts +55 -5
  120. package/src/orm/column.ts +78 -0
  121. package/src/orm/field-builders.ts +296 -0
  122. package/src/orm/index.ts +60 -0
  123. package/src/orm/operators.ts +428 -0
  124. package/src/orm/table.ts +759 -0
  125. package/src/transform.ts +62 -48
  126. package/src/types.ts +20 -63
  127. package/src/validation.ts +76 -4
  128. package/LICENSE.md +0 -21
  129. package/dist/esm/client/base-table.d.ts +0 -128
  130. package/dist/esm/client/base-table.js +0 -57
  131. package/dist/esm/client/base-table.js.map +0 -1
  132. package/dist/esm/client/build-occurrences.d.ts +0 -74
  133. package/dist/esm/client/build-occurrences.js +0 -31
  134. package/dist/esm/client/build-occurrences.js.map +0 -1
  135. package/dist/esm/client/query-builder.js +0 -900
  136. package/dist/esm/client/query-builder.js.map +0 -1
  137. package/dist/esm/client/table-occurrence.d.ts +0 -86
  138. package/dist/esm/client/table-occurrence.js +0 -58
  139. package/dist/esm/client/table-occurrence.js.map +0 -1
  140. package/src/client/base-table.ts +0 -178
  141. package/src/client/build-occurrences.ts +0 -155
  142. package/src/client/query-builder.ts.bak +0 -1457
  143. package/src/client/table-occurrence.ts +0 -156
@@ -1,900 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
- import buildQuery from "odata-query";
5
- import { getAcceptHeader } from "../types.js";
6
- import { validateSingleResponse, validateListResponse } from "../validation.js";
7
- import { RecordCountMismatchError } from "../errors.js";
8
- import { getTableIdentifiers, transformFieldName, transformOrderByField, transformFieldNamesArray, transformResponseFields } from "../transform.js";
9
- import { safeJsonParse } from "./sanitize-json.js";
10
- class QueryBuilder {
11
- constructor(config) {
12
- __publicField(this, "queryOptions", {});
13
- __publicField(this, "expandConfigs", []);
14
- __publicField(this, "singleMode", false);
15
- __publicField(this, "isCountMode", false);
16
- __publicField(this, "occurrence");
17
- __publicField(this, "tableName");
18
- __publicField(this, "databaseName");
19
- __publicField(this, "context");
20
- __publicField(this, "isNavigate");
21
- __publicField(this, "navigateRecordId");
22
- __publicField(this, "navigateRelation");
23
- __publicField(this, "navigateSourceTableName");
24
- __publicField(this, "navigateBaseRelation");
25
- __publicField(this, "navigateBasePath");
26
- // Full base path for chained entity set navigations
27
- __publicField(this, "databaseUseEntityIds");
28
- this.occurrence = config.occurrence;
29
- this.tableName = config.tableName;
30
- this.databaseName = config.databaseName;
31
- this.context = config.context;
32
- this.databaseUseEntityIds = config.databaseUseEntityIds ?? false;
33
- }
34
- /**
35
- * Helper to merge database-level useEntityIds with per-request options
36
- */
37
- mergeExecuteOptions(options) {
38
- return {
39
- ...options,
40
- useEntityIds: (options == null ? void 0 : options.useEntityIds) === void 0 ? this.databaseUseEntityIds : options.useEntityIds
41
- };
42
- }
43
- /**
44
- * Gets the table ID (FMTID) if using entity IDs, otherwise returns the table name
45
- * @param useEntityIds - Optional override for entity ID usage
46
- */
47
- getTableId(useEntityIds) {
48
- var _a, _b;
49
- if (!this.occurrence) {
50
- return this.tableName;
51
- }
52
- const contextDefault = ((_b = (_a = this.context)._getUseEntityIds) == null ? void 0 : _b.call(_a)) ?? false;
53
- const shouldUseIds = useEntityIds ?? contextDefault;
54
- if (shouldUseIds) {
55
- const identifiers = getTableIdentifiers(this.occurrence);
56
- if (!identifiers.id) {
57
- throw new Error(
58
- `useEntityIds is true but TableOccurrence "${identifiers.name}" does not have an fmtId defined`
59
- );
60
- }
61
- return identifiers.id;
62
- }
63
- return this.occurrence.getTableName();
64
- }
65
- select(...fields) {
66
- const uniqueFields = [...new Set(fields)];
67
- const newBuilder = new QueryBuilder({
68
- occurrence: this.occurrence,
69
- tableName: this.tableName,
70
- databaseName: this.databaseName,
71
- context: this.context,
72
- databaseUseEntityIds: this.databaseUseEntityIds
73
- });
74
- newBuilder.queryOptions = {
75
- ...this.queryOptions,
76
- select: uniqueFields
77
- };
78
- newBuilder.expandConfigs = [...this.expandConfigs];
79
- newBuilder.singleMode = this.singleMode;
80
- newBuilder.isCountMode = this.isCountMode;
81
- newBuilder.isNavigate = this.isNavigate;
82
- newBuilder.navigateRecordId = this.navigateRecordId;
83
- newBuilder.navigateRelation = this.navigateRelation;
84
- newBuilder.navigateSourceTableName = this.navigateSourceTableName;
85
- newBuilder.navigateBaseRelation = this.navigateBaseRelation;
86
- return newBuilder;
87
- }
88
- /**
89
- * Transforms our filter format to odata-query's expected format
90
- * - Arrays of operators are converted to AND conditions
91
- * - Single operator objects pass through as-is
92
- * - Shorthand values are handled by odata-query
93
- */
94
- transformFilter(filter) {
95
- var _a;
96
- if (typeof filter === "string") {
97
- return filter;
98
- }
99
- if (Array.isArray(filter)) {
100
- return filter.map((f) => this.transformFilter(f));
101
- }
102
- if ("and" in filter || "or" in filter || "not" in filter) {
103
- const result2 = {};
104
- if ("and" in filter && Array.isArray(filter.and)) {
105
- result2.and = filter.and.map((f) => this.transformFilter(f));
106
- }
107
- if ("or" in filter && Array.isArray(filter.or)) {
108
- result2.or = filter.or.map((f) => this.transformFilter(f));
109
- }
110
- if ("not" in filter && filter.not) {
111
- result2.not = this.transformFilter(filter.not);
112
- }
113
- return result2;
114
- }
115
- const result = {};
116
- const andConditions = [];
117
- for (const [field, value] of Object.entries(filter)) {
118
- const shouldTransform = ((_a = this.occurrence) == null ? void 0 : _a.baseTable) && this.databaseUseEntityIds;
119
- const fieldId = shouldTransform ? transformFieldName(field, this.occurrence.baseTable) : field;
120
- if (Array.isArray(value)) {
121
- if (value.length === 1) {
122
- result[fieldId] = value[0];
123
- } else {
124
- for (const op of value) {
125
- andConditions.push({ [fieldId]: op });
126
- }
127
- }
128
- } else if (value && typeof value === "object" && !(value instanceof Date) && !Array.isArray(value)) {
129
- const operatorKeys = [
130
- "eq",
131
- "ne",
132
- "gt",
133
- "ge",
134
- "lt",
135
- "le",
136
- "contains",
137
- "startswith",
138
- "endswith",
139
- "in"
140
- ];
141
- const isOperatorObject = operatorKeys.some((key) => key in value);
142
- if (isOperatorObject) {
143
- result[fieldId] = value;
144
- } else {
145
- result[fieldId] = value;
146
- }
147
- } else {
148
- result[fieldId] = value;
149
- }
150
- }
151
- if (andConditions.length > 0) {
152
- if (Object.keys(result).length > 0) {
153
- return { and: [...andConditions, result] };
154
- } else {
155
- return { and: andConditions };
156
- }
157
- }
158
- return result;
159
- }
160
- filter(filter) {
161
- this.queryOptions.filter = this.transformFilter(filter);
162
- return this;
163
- }
164
- orderBy(orderBy) {
165
- var _a;
166
- if (((_a = this.occurrence) == null ? void 0 : _a.baseTable) && orderBy) {
167
- if (Array.isArray(orderBy)) {
168
- this.queryOptions.orderBy = orderBy.map(
169
- (field) => transformOrderByField(String(field), this.occurrence.baseTable)
170
- );
171
- } else {
172
- this.queryOptions.orderBy = transformOrderByField(
173
- String(orderBy),
174
- this.occurrence.baseTable
175
- );
176
- }
177
- } else {
178
- this.queryOptions.orderBy = orderBy;
179
- }
180
- return this;
181
- }
182
- top(count) {
183
- this.queryOptions.top = count;
184
- return this;
185
- }
186
- skip(count) {
187
- this.queryOptions.skip = count;
188
- return this;
189
- }
190
- /**
191
- * Formats select fields for use in query strings.
192
- * - Transforms field names to FMFIDs if using entity IDs
193
- * - Wraps "id" fields in double quotes
194
- * - URL-encodes special characters but preserves spaces
195
- */
196
- formatSelectFields(select, baseTable, useEntityIds) {
197
- if (!select) return "";
198
- const selectFieldsArray = Array.isArray(select) ? select : [select];
199
- const shouldTransform = baseTable && (useEntityIds ?? this.databaseUseEntityIds);
200
- const transformedFields = shouldTransform ? transformFieldNamesArray(
201
- selectFieldsArray.map((f) => String(f)),
202
- baseTable
203
- ) : selectFieldsArray.map((f) => String(f));
204
- return transformedFields.map((field) => {
205
- if (field === "id") return `"id"`;
206
- const encodedField = encodeURIComponent(String(field));
207
- return encodedField.replace(/%20/g, " ");
208
- }).join(",");
209
- }
210
- /**
211
- * Builds expand validation configs from internal expand configurations.
212
- * These are used to validate expanded navigation properties.
213
- */
214
- buildExpandValidationConfigs(configs) {
215
- return configs.map((config) => {
216
- var _a, _b, _c;
217
- const targetOccurrence = (_a = this.occurrence) == null ? void 0 : _a.navigation[config.relation];
218
- const targetSchema = (_b = targetOccurrence == null ? void 0 : targetOccurrence.baseTable) == null ? void 0 : _b.schema;
219
- const selectedFields = ((_c = config.options) == null ? void 0 : _c.select) ? Array.isArray(config.options.select) ? config.options.select.map((f) => String(f)) : [String(config.options.select)] : void 0;
220
- return {
221
- relation: config.relation,
222
- targetSchema,
223
- targetOccurrence,
224
- targetBaseTable: targetOccurrence == null ? void 0 : targetOccurrence.baseTable,
225
- occurrence: targetOccurrence,
226
- // Add occurrence for transformation
227
- selectedFields,
228
- nestedExpands: void 0
229
- // TODO: Handle nested expands if needed
230
- };
231
- });
232
- }
233
- /**
234
- * Builds OData expand query string from expand configurations.
235
- * Handles nested expands recursively.
236
- * Transforms relation names to FMTIDs if using entity IDs.
237
- */
238
- buildExpandString(configs) {
239
- if (configs.length === 0) {
240
- return "";
241
- }
242
- return configs.map((config) => {
243
- var _a;
244
- const targetOccurrence = (_a = this.occurrence) == null ? void 0 : _a.navigation[config.relation];
245
- const shouldUseTableId = this.databaseUseEntityIds && (targetOccurrence == null ? void 0 : targetOccurrence.isUsingTableId());
246
- const relationName = shouldUseTableId ? targetOccurrence.getTableId() : config.relation;
247
- if (!config.options || Object.keys(config.options).length === 0) {
248
- return relationName;
249
- }
250
- const parts = [];
251
- if (config.options.select) {
252
- const selectFields = this.formatSelectFields(
253
- config.options.select,
254
- targetOccurrence == null ? void 0 : targetOccurrence.baseTable
255
- );
256
- parts.push(`$select=${selectFields}`);
257
- }
258
- if (config.options.filter) {
259
- const filterQuery = buildQuery({ filter: config.options.filter });
260
- const filterMatch = filterQuery.match(/\$filter=([^&]+)/);
261
- if (filterMatch) {
262
- parts.push(`$filter=${filterMatch[1]}`);
263
- }
264
- }
265
- if (config.options.orderBy) {
266
- const orderByValue = Array.isArray(config.options.orderBy) ? config.options.orderBy.join(",") : config.options.orderBy;
267
- parts.push(`$orderby=${String(orderByValue)}`);
268
- }
269
- if (config.options.top !== void 0) {
270
- parts.push(`$top=${config.options.top}`);
271
- }
272
- if (config.options.skip !== void 0) {
273
- parts.push(`$skip=${config.options.skip}`);
274
- }
275
- if (config.options.expand) {
276
- if (typeof config.options.expand === "string") {
277
- parts.push(`$expand=${config.options.expand}`);
278
- }
279
- }
280
- if (parts.length === 0) {
281
- return relationName;
282
- }
283
- return `${relationName}(${parts.join(";")})`;
284
- }).join(",");
285
- }
286
- expand(relation, callback) {
287
- var _a;
288
- const targetOccurrence = (_a = this.occurrence) == null ? void 0 : _a.navigation[relation];
289
- const getDefaultSelectFields = () => {
290
- var _a2;
291
- if (!targetOccurrence) return void 0;
292
- const defaultSelect = targetOccurrence.defaultSelect;
293
- if (defaultSelect === "schema") {
294
- const schema = (_a2 = targetOccurrence.baseTable) == null ? void 0 : _a2.schema;
295
- if (schema) {
296
- return [...new Set(Object.keys(schema))];
297
- }
298
- } else if (Array.isArray(defaultSelect)) {
299
- return [...new Set(defaultSelect)];
300
- }
301
- return void 0;
302
- };
303
- if (callback) {
304
- const targetBuilder = new QueryBuilder({
305
- occurrence: targetOccurrence,
306
- tableName: (targetOccurrence == null ? void 0 : targetOccurrence.name) ?? relation,
307
- databaseName: this.databaseName,
308
- context: this.context,
309
- databaseUseEntityIds: this.databaseUseEntityIds
310
- });
311
- const typedBuilder = targetBuilder;
312
- const configuredBuilder = callback(typedBuilder);
313
- const expandOptions = {
314
- ...configuredBuilder.queryOptions
315
- };
316
- if (!expandOptions.select) {
317
- const defaultFields = getDefaultSelectFields();
318
- if (defaultFields) {
319
- expandOptions.select = defaultFields;
320
- }
321
- }
322
- if (configuredBuilder.expandConfigs.length > 0) {
323
- const nestedExpandString = this.buildExpandString(
324
- configuredBuilder.expandConfigs
325
- );
326
- if (nestedExpandString) {
327
- expandOptions.expand = nestedExpandString;
328
- }
329
- }
330
- const expandConfig = {
331
- relation,
332
- options: expandOptions
333
- };
334
- this.expandConfigs.push(expandConfig);
335
- } else {
336
- const defaultFields = getDefaultSelectFields();
337
- if (defaultFields) {
338
- this.expandConfigs.push({
339
- relation,
340
- options: { select: defaultFields }
341
- });
342
- } else {
343
- this.expandConfigs.push({ relation });
344
- }
345
- }
346
- return this;
347
- }
348
- single() {
349
- const newBuilder = new QueryBuilder({
350
- occurrence: this.occurrence,
351
- tableName: this.tableName,
352
- databaseName: this.databaseName,
353
- context: this.context,
354
- databaseUseEntityIds: this.databaseUseEntityIds
355
- });
356
- newBuilder.queryOptions = { ...this.queryOptions };
357
- newBuilder.expandConfigs = [...this.expandConfigs];
358
- newBuilder.singleMode = "exact";
359
- newBuilder.isCountMode = this.isCountMode;
360
- newBuilder.isNavigate = this.isNavigate;
361
- newBuilder.navigateRecordId = this.navigateRecordId;
362
- newBuilder.navigateRelation = this.navigateRelation;
363
- newBuilder.navigateSourceTableName = this.navigateSourceTableName;
364
- newBuilder.navigateBaseRelation = this.navigateBaseRelation;
365
- return newBuilder;
366
- }
367
- maybeSingle() {
368
- const newBuilder = new QueryBuilder({
369
- occurrence: this.occurrence,
370
- tableName: this.tableName,
371
- databaseName: this.databaseName,
372
- context: this.context,
373
- databaseUseEntityIds: this.databaseUseEntityIds
374
- });
375
- newBuilder.queryOptions = { ...this.queryOptions };
376
- newBuilder.expandConfigs = [...this.expandConfigs];
377
- newBuilder.singleMode = "maybe";
378
- newBuilder.isCountMode = this.isCountMode;
379
- newBuilder.isNavigate = this.isNavigate;
380
- newBuilder.navigateRecordId = this.navigateRecordId;
381
- newBuilder.navigateRelation = this.navigateRelation;
382
- newBuilder.navigateSourceTableName = this.navigateSourceTableName;
383
- newBuilder.navigateBaseRelation = this.navigateBaseRelation;
384
- return newBuilder;
385
- }
386
- count() {
387
- const newBuilder = new QueryBuilder({
388
- occurrence: this.occurrence,
389
- tableName: this.tableName,
390
- databaseName: this.databaseName,
391
- context: this.context,
392
- databaseUseEntityIds: this.databaseUseEntityIds
393
- });
394
- newBuilder.queryOptions = { ...this.queryOptions, count: true };
395
- newBuilder.expandConfigs = [...this.expandConfigs];
396
- newBuilder.singleMode = this.singleMode;
397
- newBuilder.isCountMode = true;
398
- newBuilder.isNavigate = this.isNavigate;
399
- newBuilder.navigateRecordId = this.navigateRecordId;
400
- newBuilder.navigateRelation = this.navigateRelation;
401
- newBuilder.navigateSourceTableName = this.navigateSourceTableName;
402
- newBuilder.navigateBaseRelation = this.navigateBaseRelation;
403
- return newBuilder;
404
- }
405
- async execute(options) {
406
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
407
- const queryOptionsWithoutExpand = { ...this.queryOptions };
408
- delete queryOptionsWithoutExpand.expand;
409
- const mergedOptions = this.mergeExecuteOptions(options);
410
- if (queryOptionsWithoutExpand.select) {
411
- queryOptionsWithoutExpand.select = this.formatSelectFields(
412
- queryOptionsWithoutExpand.select,
413
- (_a = this.occurrence) == null ? void 0 : _a.baseTable
414
- );
415
- }
416
- let queryString = buildQuery(queryOptionsWithoutExpand);
417
- const expandString = this.buildExpandString(this.expandConfigs);
418
- if (expandString) {
419
- const separator = queryString.includes("?") ? "&" : "?";
420
- queryString = `${queryString}${separator}$expand=${expandString}`;
421
- }
422
- if (this.isNavigate && this.navigateRecordId && this.navigateRelation && this.navigateSourceTableName) {
423
- let url;
424
- if (this.navigateBaseRelation) {
425
- url = `/${this.databaseName}/${this.navigateSourceTableName}/${this.navigateBaseRelation}('${this.navigateRecordId}')/${this.navigateRelation}${queryString}`;
426
- } else {
427
- url = `/${this.databaseName}/${this.navigateSourceTableName}('${this.navigateRecordId}')/${this.navigateRelation}${queryString}`;
428
- }
429
- const result2 = await this.context._makeRequest(url, mergedOptions);
430
- if (result2.error) {
431
- return { data: void 0, error: result2.error };
432
- }
433
- let response2 = result2.data;
434
- const shouldUseIds2 = mergedOptions.useEntityIds ?? false;
435
- if (((_b = this.occurrence) == null ? void 0 : _b.baseTable) && shouldUseIds2) {
436
- const expandValidationConfigs3 = this.buildExpandValidationConfigs(
437
- this.expandConfigs
438
- );
439
- response2 = transformResponseFields(
440
- response2,
441
- this.occurrence.baseTable,
442
- expandValidationConfigs3
443
- );
444
- }
445
- if ((options == null ? void 0 : options.skipValidation) === true) {
446
- const resp = response2;
447
- if (this.singleMode !== false) {
448
- const records = resp.value ?? [resp];
449
- const count = Array.isArray(records) ? records.length : 1;
450
- if (count > 1) {
451
- return {
452
- data: void 0,
453
- error: new RecordCountMismatchError(
454
- this.singleMode === "exact" ? "one" : "at-most-one",
455
- count
456
- )
457
- };
458
- }
459
- if (count === 0) {
460
- if (this.singleMode === "exact") {
461
- return {
462
- data: void 0,
463
- error: new RecordCountMismatchError("one", 0)
464
- };
465
- }
466
- return { data: null, error: void 0 };
467
- }
468
- const record = Array.isArray(records) ? records[0] : records;
469
- return { data: record, error: void 0 };
470
- } else {
471
- const records = resp.value ?? [];
472
- const stripped = records.map((record) => record);
473
- return { data: stripped, error: void 0 };
474
- }
475
- }
476
- const schema2 = (_d = (_c = this.occurrence) == null ? void 0 : _c.baseTable) == null ? void 0 : _d.schema;
477
- const selectedFields2 = this.queryOptions.select;
478
- const expandValidationConfigs2 = this.buildExpandValidationConfigs(
479
- this.expandConfigs
480
- );
481
- if (this.singleMode !== false) {
482
- const validation = await validateSingleResponse(
483
- response2,
484
- schema2,
485
- selectedFields2,
486
- expandValidationConfigs2,
487
- this.singleMode
488
- );
489
- if (!validation.valid) {
490
- return { data: void 0, error: validation.error };
491
- }
492
- return { data: validation.data, error: void 0 };
493
- } else {
494
- const validation = await validateListResponse(
495
- response2,
496
- schema2,
497
- selectedFields2,
498
- expandValidationConfigs2
499
- );
500
- if (!validation.valid) {
501
- return { data: void 0, error: validation.error };
502
- }
503
- return { data: validation.data, error: void 0 };
504
- }
505
- }
506
- if (this.isNavigate && !this.navigateRecordId && this.navigateRelation && this.navigateSourceTableName) {
507
- const result2 = await this.context._makeRequest(
508
- `/${this.databaseName}/${this.navigateSourceTableName}/${this.navigateRelation}${queryString}`,
509
- mergedOptions
510
- );
511
- if (result2.error) {
512
- return { data: void 0, error: result2.error };
513
- }
514
- let response2 = result2.data;
515
- const shouldUseIds2 = mergedOptions.useEntityIds ?? false;
516
- if (((_e = this.occurrence) == null ? void 0 : _e.baseTable) && shouldUseIds2) {
517
- const expandValidationConfigs3 = this.buildExpandValidationConfigs(
518
- this.expandConfigs
519
- );
520
- response2 = transformResponseFields(
521
- response2,
522
- this.occurrence.baseTable,
523
- expandValidationConfigs3
524
- );
525
- }
526
- if ((options == null ? void 0 : options.skipValidation) === true) {
527
- const resp = response2;
528
- if (this.singleMode !== false) {
529
- const records = resp.value ?? [resp];
530
- const count = Array.isArray(records) ? records.length : 1;
531
- if (count > 1) {
532
- return {
533
- data: void 0,
534
- error: new RecordCountMismatchError(
535
- this.singleMode === "exact" ? "one" : "at-most-one",
536
- count
537
- )
538
- };
539
- }
540
- if (count === 0) {
541
- if (this.singleMode === "exact") {
542
- return {
543
- data: void 0,
544
- error: new RecordCountMismatchError("one", 0)
545
- };
546
- }
547
- return { data: null, error: void 0 };
548
- }
549
- const record = Array.isArray(records) ? records[0] : records;
550
- return { data: record, error: void 0 };
551
- } else {
552
- const records = resp.value ?? [];
553
- const stripped = records.map((record) => record);
554
- return { data: stripped, error: void 0 };
555
- }
556
- }
557
- const schema2 = (_g = (_f = this.occurrence) == null ? void 0 : _f.baseTable) == null ? void 0 : _g.schema;
558
- const selectedFields2 = this.queryOptions.select;
559
- const expandValidationConfigs2 = this.buildExpandValidationConfigs(
560
- this.expandConfigs
561
- );
562
- if (this.singleMode !== false) {
563
- const validation = await validateSingleResponse(
564
- response2,
565
- schema2,
566
- selectedFields2,
567
- expandValidationConfigs2,
568
- this.singleMode
569
- );
570
- if (!validation.valid) {
571
- return { data: void 0, error: validation.error };
572
- }
573
- return { data: validation.data, error: void 0 };
574
- } else {
575
- const validation = await validateListResponse(
576
- response2,
577
- schema2,
578
- selectedFields2,
579
- expandValidationConfigs2
580
- );
581
- if (!validation.valid) {
582
- return { data: void 0, error: validation.error };
583
- }
584
- return { data: validation.data, error: void 0 };
585
- }
586
- }
587
- if (this.isCountMode) {
588
- const tableId2 = this.getTableId(mergedOptions.useEntityIds);
589
- const result2 = await this.context._makeRequest(
590
- `/${this.databaseName}/${tableId2}/$count${queryString}`,
591
- mergedOptions
592
- );
593
- if (result2.error) {
594
- return { data: void 0, error: result2.error };
595
- }
596
- const count = typeof result2.data === "string" ? Number(result2.data) : result2.data;
597
- return { data: count, error: void 0 };
598
- }
599
- const tableId = this.getTableId(mergedOptions.useEntityIds);
600
- const result = await this.context._makeRequest(
601
- `/${this.databaseName}/${tableId}${queryString}`,
602
- mergedOptions
603
- );
604
- if (result.error) {
605
- return { data: void 0, error: result.error };
606
- }
607
- let response = result.data;
608
- const shouldUseIds = mergedOptions.useEntityIds ?? false;
609
- if (((_h = this.occurrence) == null ? void 0 : _h.baseTable) && shouldUseIds) {
610
- const expandValidationConfigs2 = this.buildExpandValidationConfigs(
611
- this.expandConfigs
612
- );
613
- response = transformResponseFields(
614
- response,
615
- this.occurrence.baseTable,
616
- expandValidationConfigs2
617
- );
618
- }
619
- if ((options == null ? void 0 : options.skipValidation) === true) {
620
- const resp = response;
621
- if (this.singleMode !== false) {
622
- const records = resp.value ?? [resp];
623
- const count = Array.isArray(records) ? records.length : 1;
624
- if (count > 1) {
625
- return {
626
- data: void 0,
627
- error: new RecordCountMismatchError(
628
- this.singleMode === "exact" ? "one" : "at-most-one",
629
- count
630
- )
631
- };
632
- }
633
- if (count === 0) {
634
- if (this.singleMode === "exact") {
635
- return {
636
- data: void 0,
637
- error: new RecordCountMismatchError("one", 0)
638
- };
639
- }
640
- return { data: null, error: void 0 };
641
- }
642
- const record = Array.isArray(records) ? records[0] : records;
643
- return { data: record, error: void 0 };
644
- } else {
645
- const records = resp.value ?? [];
646
- return { data: records, error: void 0 };
647
- }
648
- }
649
- const schema = (_j = (_i = this.occurrence) == null ? void 0 : _i.baseTable) == null ? void 0 : _j.schema;
650
- const selectedFields = this.queryOptions.select;
651
- const expandValidationConfigs = this.buildExpandValidationConfigs(
652
- this.expandConfigs
653
- );
654
- if (this.singleMode !== false) {
655
- const validation = await validateSingleResponse(
656
- response,
657
- schema,
658
- selectedFields,
659
- expandValidationConfigs,
660
- this.singleMode
661
- );
662
- if (!validation.valid) {
663
- return { data: void 0, error: validation.error };
664
- }
665
- return {
666
- data: validation.data,
667
- error: void 0
668
- };
669
- } else {
670
- const validation = await validateListResponse(
671
- response,
672
- schema,
673
- selectedFields,
674
- expandValidationConfigs
675
- );
676
- if (!validation.valid) {
677
- return { data: void 0, error: validation.error };
678
- }
679
- return {
680
- data: validation.data,
681
- error: void 0
682
- };
683
- }
684
- }
685
- getQueryString() {
686
- var _a;
687
- const queryOptionsWithoutExpand = { ...this.queryOptions };
688
- delete queryOptionsWithoutExpand.expand;
689
- if (queryOptionsWithoutExpand.select) {
690
- queryOptionsWithoutExpand.select = this.formatSelectFields(
691
- queryOptionsWithoutExpand.select,
692
- (_a = this.occurrence) == null ? void 0 : _a.baseTable
693
- );
694
- }
695
- let queryParams = buildQuery(queryOptionsWithoutExpand);
696
- if (this.queryOptions.select) {
697
- queryParams = queryParams.replace(
698
- /\$select=([^&]*)/,
699
- (match, selectValue) => {
700
- return `$select=${selectValue.replace(/%20/g, " ")}`;
701
- }
702
- );
703
- }
704
- const expandString = this.buildExpandString(this.expandConfigs);
705
- if (expandString) {
706
- const separator = queryParams.includes("?") ? "&" : "?";
707
- queryParams = `${queryParams}${separator}$expand=${expandString}`;
708
- }
709
- if (this.isNavigate && this.navigateRecordId && this.navigateRelation && this.navigateSourceTableName) {
710
- let path;
711
- if (this.navigateBaseRelation) {
712
- path = `/${this.navigateSourceTableName}/${this.navigateBaseRelation}('${this.navigateRecordId}')/${this.navigateRelation}`;
713
- } else {
714
- path = `/${this.navigateSourceTableName}('${this.navigateRecordId}')/${this.navigateRelation}`;
715
- }
716
- return queryParams ? `${path}${queryParams}` : path;
717
- }
718
- if (this.isNavigate && !this.navigateRecordId && this.navigateRelation && this.navigateSourceTableName) {
719
- let path;
720
- if (this.navigateBasePath) {
721
- path = `/${this.navigateBasePath}/${this.navigateRelation}`;
722
- } else {
723
- path = `/${this.navigateSourceTableName}/${this.navigateRelation}`;
724
- }
725
- return queryParams ? `${path}${queryParams}` : path;
726
- }
727
- const tableId = this.getTableId(this.databaseUseEntityIds);
728
- return `/${tableId}${queryParams}`;
729
- }
730
- getRequestConfig() {
731
- var _a;
732
- const queryOptionsWithoutExpand = { ...this.queryOptions };
733
- delete queryOptionsWithoutExpand.expand;
734
- if (queryOptionsWithoutExpand.select) {
735
- queryOptionsWithoutExpand.select = this.formatSelectFields(
736
- queryOptionsWithoutExpand.select,
737
- (_a = this.occurrence) == null ? void 0 : _a.baseTable
738
- );
739
- }
740
- let queryString = buildQuery(queryOptionsWithoutExpand);
741
- const expandString = this.buildExpandString(this.expandConfigs);
742
- if (expandString) {
743
- const separator = queryString.includes("?") ? "&" : "?";
744
- queryString = `${queryString}${separator}$expand=${expandString}`;
745
- }
746
- let url;
747
- if (this.isNavigate && this.navigateRecordId && this.navigateRelation && this.navigateSourceTableName) {
748
- if (this.navigateBaseRelation) {
749
- url = `/${this.databaseName}/${this.navigateSourceTableName}/${this.navigateBaseRelation}('${this.navigateRecordId}')/${this.navigateRelation}${queryString}`;
750
- } else {
751
- url = `/${this.databaseName}/${this.navigateSourceTableName}('${this.navigateRecordId}')/${this.navigateRelation}${queryString}`;
752
- }
753
- } else if (this.isNavigate && !this.navigateRecordId && this.navigateRelation && this.navigateSourceTableName) {
754
- if (this.navigateBasePath) {
755
- url = `/${this.databaseName}/${this.navigateBasePath}/${this.navigateRelation}${queryString}`;
756
- } else {
757
- url = `/${this.databaseName}/${this.navigateSourceTableName}/${this.navigateRelation}${queryString}`;
758
- }
759
- } else if (this.isCountMode) {
760
- const tableId = this.getTableId(this.databaseUseEntityIds);
761
- url = `/${this.databaseName}/${tableId}/$count${queryString}`;
762
- } else {
763
- const tableId = this.getTableId(this.databaseUseEntityIds);
764
- url = `/${this.databaseName}/${tableId}${queryString}`;
765
- }
766
- return {
767
- method: "GET",
768
- url
769
- };
770
- }
771
- toRequest(baseUrl, options) {
772
- const config = this.getRequestConfig();
773
- const fullUrl = `${baseUrl}${config.url}`;
774
- return new Request(fullUrl, {
775
- method: config.method,
776
- headers: {
777
- "Content-Type": "application/json",
778
- Accept: getAcceptHeader(options == null ? void 0 : options.includeODataAnnotations)
779
- }
780
- });
781
- }
782
- async processResponse(response, options) {
783
- var _a, _b, _c;
784
- if (response.status === 204) {
785
- if (this.singleMode !== false) {
786
- if (this.singleMode === "maybe") {
787
- return { data: null, error: void 0 };
788
- }
789
- return {
790
- data: void 0,
791
- error: new RecordCountMismatchError("one", 0)
792
- };
793
- }
794
- return { data: [], error: void 0 };
795
- }
796
- let rawData;
797
- try {
798
- rawData = await safeJsonParse(response);
799
- } catch (err) {
800
- if (err instanceof SyntaxError && response.status === 204) {
801
- return { data: [], error: void 0 };
802
- }
803
- return {
804
- data: void 0,
805
- error: {
806
- name: "ResponseParseError",
807
- message: `Failed to parse response JSON: ${err instanceof Error ? err.message : "Unknown error"}`,
808
- timestamp: /* @__PURE__ */ new Date()
809
- }
810
- };
811
- }
812
- if (!rawData) {
813
- return {
814
- data: void 0,
815
- error: {
816
- name: "ResponseError",
817
- message: "Response body was empty or null",
818
- timestamp: /* @__PURE__ */ new Date()
819
- }
820
- };
821
- }
822
- const shouldUseIds = (options == null ? void 0 : options.useEntityIds) ?? this.databaseUseEntityIds;
823
- let transformedData = rawData;
824
- if (((_a = this.occurrence) == null ? void 0 : _a.baseTable) && shouldUseIds) {
825
- const expandValidationConfigs2 = this.buildExpandValidationConfigs(
826
- this.expandConfigs
827
- );
828
- transformedData = transformResponseFields(
829
- rawData,
830
- this.occurrence.baseTable,
831
- expandValidationConfigs2
832
- );
833
- }
834
- if ((options == null ? void 0 : options.skipValidation) === true) {
835
- const resp = transformedData;
836
- if (this.singleMode !== false) {
837
- const records = resp.value ?? [resp];
838
- const count = Array.isArray(records) ? records.length : 1;
839
- if (count > 1) {
840
- return {
841
- data: void 0,
842
- error: new RecordCountMismatchError(
843
- this.singleMode === "exact" ? "one" : "at-most-one",
844
- count
845
- )
846
- };
847
- }
848
- if (count === 0) {
849
- if (this.singleMode === "exact") {
850
- return {
851
- data: void 0,
852
- error: new RecordCountMismatchError("one", 0)
853
- };
854
- }
855
- return { data: null, error: void 0 };
856
- }
857
- const record = Array.isArray(records) ? records[0] : records;
858
- return { data: record, error: void 0 };
859
- } else {
860
- const records = resp.value ?? [];
861
- return { data: records, error: void 0 };
862
- }
863
- }
864
- const schema = (_c = (_b = this.occurrence) == null ? void 0 : _b.baseTable) == null ? void 0 : _c.schema;
865
- const selectedFields = this.queryOptions.select;
866
- const expandValidationConfigs = this.buildExpandValidationConfigs(
867
- this.expandConfigs
868
- );
869
- if (this.singleMode !== false) {
870
- const validation2 = await validateSingleResponse(
871
- transformedData,
872
- schema,
873
- selectedFields,
874
- expandValidationConfigs,
875
- this.singleMode
876
- );
877
- if (!validation2.valid) {
878
- return { data: void 0, error: validation2.error };
879
- }
880
- if (validation2.data === null) {
881
- return { data: null, error: void 0 };
882
- }
883
- return { data: validation2.data, error: void 0 };
884
- }
885
- const validation = await validateListResponse(
886
- transformedData,
887
- schema,
888
- selectedFields,
889
- expandValidationConfigs
890
- );
891
- if (!validation.valid) {
892
- return { data: void 0, error: validation.error };
893
- }
894
- return { data: validation.data, error: void 0 };
895
- }
896
- }
897
- export {
898
- QueryBuilder
899
- };
900
- //# sourceMappingURL=query-builder.js.map