@proofkit/fmodata 0.1.0-alpha.6 → 0.1.0-alpha.7

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 (61) hide show
  1. package/README.md +333 -3
  2. package/dist/esm/client/batch-builder.d.ts +54 -0
  3. package/dist/esm/client/batch-builder.js +179 -0
  4. package/dist/esm/client/batch-builder.js.map +1 -0
  5. package/dist/esm/client/batch-request.d.ts +61 -0
  6. package/dist/esm/client/batch-request.js +252 -0
  7. package/dist/esm/client/batch-request.js.map +1 -0
  8. package/dist/esm/client/database.d.ts +43 -11
  9. package/dist/esm/client/database.js +64 -10
  10. package/dist/esm/client/database.js.map +1 -1
  11. package/dist/esm/client/delete-builder.d.ts +21 -2
  12. package/dist/esm/client/delete-builder.js +76 -9
  13. package/dist/esm/client/delete-builder.js.map +1 -1
  14. package/dist/esm/client/entity-set.d.ts +15 -4
  15. package/dist/esm/client/entity-set.js +23 -7
  16. package/dist/esm/client/entity-set.js.map +1 -1
  17. package/dist/esm/client/filemaker-odata.d.ts +11 -5
  18. package/dist/esm/client/filemaker-odata.js +46 -14
  19. package/dist/esm/client/filemaker-odata.js.map +1 -1
  20. package/dist/esm/client/insert-builder.d.ts +38 -3
  21. package/dist/esm/client/insert-builder.js +195 -9
  22. package/dist/esm/client/insert-builder.js.map +1 -1
  23. package/dist/esm/client/query-builder.d.ts +19 -3
  24. package/dist/esm/client/query-builder.js +193 -17
  25. package/dist/esm/client/query-builder.js.map +1 -1
  26. package/dist/esm/client/record-builder.d.ts +17 -2
  27. package/dist/esm/client/record-builder.js +87 -5
  28. package/dist/esm/client/record-builder.js.map +1 -1
  29. package/dist/esm/client/response-processor.d.ts +38 -0
  30. package/dist/esm/client/schema-manager.d.ts +57 -0
  31. package/dist/esm/client/schema-manager.js +132 -0
  32. package/dist/esm/client/schema-manager.js.map +1 -0
  33. package/dist/esm/client/update-builder.d.ts +34 -11
  34. package/dist/esm/client/update-builder.js +119 -19
  35. package/dist/esm/client/update-builder.js.map +1 -1
  36. package/dist/esm/errors.d.ts +14 -1
  37. package/dist/esm/errors.js +26 -0
  38. package/dist/esm/errors.js.map +1 -1
  39. package/dist/esm/index.d.ts +3 -2
  40. package/dist/esm/index.js +3 -1
  41. package/dist/esm/transform.d.ts +9 -0
  42. package/dist/esm/transform.js +7 -0
  43. package/dist/esm/transform.js.map +1 -1
  44. package/dist/esm/types.d.ts +69 -1
  45. package/package.json +1 -1
  46. package/src/client/batch-builder.ts +265 -0
  47. package/src/client/batch-request.ts +485 -0
  48. package/src/client/database.ts +106 -52
  49. package/src/client/delete-builder.ts +116 -14
  50. package/src/client/entity-set.ts +80 -6
  51. package/src/client/filemaker-odata.ts +65 -19
  52. package/src/client/insert-builder.ts +296 -18
  53. package/src/client/query-builder.ts +278 -17
  54. package/src/client/record-builder.ts +119 -11
  55. package/src/client/response-processor.ts +103 -0
  56. package/src/client/schema-manager.ts +246 -0
  57. package/src/client/update-builder.ts +195 -37
  58. package/src/errors.ts +33 -1
  59. package/src/index.ts +13 -0
  60. package/src/transform.ts +19 -6
  61. package/src/types.ts +89 -1
@@ -4,7 +4,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
4
4
  import buildQuery from "odata-query";
5
5
  import { validateSingleResponse, validateListResponse } from "../validation.js";
6
6
  import { RecordCountMismatchError } from "../errors.js";
7
- import { transformTableName, transformFieldName, transformOrderByField, transformFieldNamesArray, transformResponseFields } from "../transform.js";
7
+ import { getTableIdentifiers, transformFieldName, transformOrderByField, transformFieldNamesArray, transformResponseFields } from "../transform.js";
8
8
  class QueryBuilder {
9
9
  constructor(config) {
10
10
  __publicField(this, "queryOptions", {});
@@ -20,10 +20,21 @@ class QueryBuilder {
20
20
  __publicField(this, "navigateRelation");
21
21
  __publicField(this, "navigateSourceTableName");
22
22
  __publicField(this, "navigateBaseRelation");
23
+ __publicField(this, "databaseUseEntityIds");
23
24
  this.occurrence = config.occurrence;
24
25
  this.tableName = config.tableName;
25
26
  this.databaseName = config.databaseName;
26
27
  this.context = config.context;
28
+ this.databaseUseEntityIds = config.databaseUseEntityIds ?? false;
29
+ }
30
+ /**
31
+ * Helper to merge database-level useEntityIds with per-request options
32
+ */
33
+ mergeExecuteOptions(options) {
34
+ return {
35
+ ...options,
36
+ useEntityIds: (options == null ? void 0 : options.useEntityIds) === void 0 ? this.databaseUseEntityIds : options.useEntityIds
37
+ };
27
38
  }
28
39
  /**
29
40
  * Helper to conditionally strip OData annotations based on options
@@ -37,9 +48,25 @@ class QueryBuilder {
37
48
  }
38
49
  /**
39
50
  * Gets the table ID (FMTID) if using entity IDs, otherwise returns the table name
51
+ * @param useEntityIds - Optional override for entity ID usage
40
52
  */
41
- getTableId() {
42
- return this.occurrence ? transformTableName(this.occurrence) : this.tableName;
53
+ getTableId(useEntityIds) {
54
+ var _a, _b;
55
+ if (!this.occurrence) {
56
+ return this.tableName;
57
+ }
58
+ const contextDefault = ((_b = (_a = this.context)._getUseEntityIds) == null ? void 0 : _b.call(_a)) ?? false;
59
+ const shouldUseIds = useEntityIds ?? contextDefault;
60
+ if (shouldUseIds) {
61
+ const identifiers = getTableIdentifiers(this.occurrence);
62
+ if (!identifiers.id) {
63
+ throw new Error(
64
+ `useEntityIds is true but TableOccurrence "${identifiers.name}" does not have an fmtId defined`
65
+ );
66
+ }
67
+ return identifiers.id;
68
+ }
69
+ return this.occurrence.getTableName();
43
70
  }
44
71
  select(...fields) {
45
72
  const uniqueFields = [...new Set(fields)];
@@ -47,7 +74,8 @@ class QueryBuilder {
47
74
  occurrence: this.occurrence,
48
75
  tableName: this.tableName,
49
76
  databaseName: this.databaseName,
50
- context: this.context
77
+ context: this.context,
78
+ databaseUseEntityIds: this.databaseUseEntityIds
51
79
  });
52
80
  newBuilder.queryOptions = {
53
81
  ...this.queryOptions,
@@ -158,6 +186,10 @@ class QueryBuilder {
158
186
  }
159
187
  top(count) {
160
188
  this.queryOptions.top = count;
189
+ console.log("top method", {
190
+ count,
191
+ databaseUseEntityIds: this.databaseUseEntityIds
192
+ });
161
193
  return this;
162
194
  }
163
195
  skip(count) {
@@ -266,7 +298,8 @@ class QueryBuilder {
266
298
  occurrence: targetOccurrence,
267
299
  tableName: (targetOccurrence == null ? void 0 : targetOccurrence.name) ?? relation,
268
300
  databaseName: this.databaseName,
269
- context: this.context
301
+ context: this.context,
302
+ databaseUseEntityIds: this.databaseUseEntityIds
270
303
  });
271
304
  const typedBuilder = targetBuilder;
272
305
  const configuredBuilder = callback(typedBuilder);
@@ -296,7 +329,8 @@ class QueryBuilder {
296
329
  occurrence: this.occurrence,
297
330
  tableName: this.tableName,
298
331
  databaseName: this.databaseName,
299
- context: this.context
332
+ context: this.context,
333
+ databaseUseEntityIds: this.databaseUseEntityIds
300
334
  });
301
335
  newBuilder.queryOptions = { ...this.queryOptions };
302
336
  newBuilder.expandConfigs = [...this.expandConfigs];
@@ -314,7 +348,8 @@ class QueryBuilder {
314
348
  occurrence: this.occurrence,
315
349
  tableName: this.tableName,
316
350
  databaseName: this.databaseName,
317
- context: this.context
351
+ context: this.context,
352
+ databaseUseEntityIds: this.databaseUseEntityIds
318
353
  });
319
354
  newBuilder.queryOptions = { ...this.queryOptions };
320
355
  newBuilder.expandConfigs = [...this.expandConfigs];
@@ -332,7 +367,8 @@ class QueryBuilder {
332
367
  occurrence: this.occurrence,
333
368
  tableName: this.tableName,
334
369
  databaseName: this.databaseName,
335
- context: this.context
370
+ context: this.context,
371
+ databaseUseEntityIds: this.databaseUseEntityIds
336
372
  });
337
373
  newBuilder.queryOptions = { ...this.queryOptions, count: true };
338
374
  newBuilder.expandConfigs = [...this.expandConfigs];
@@ -349,6 +385,7 @@ class QueryBuilder {
349
385
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
350
386
  const queryOptionsWithoutExpand = { ...this.queryOptions };
351
387
  delete queryOptionsWithoutExpand.expand;
388
+ const mergedOptions = this.mergeExecuteOptions(options);
352
389
  if (queryOptionsWithoutExpand.select) {
353
390
  queryOptionsWithoutExpand.select = this.formatSelectFields(
354
391
  queryOptionsWithoutExpand.select,
@@ -368,12 +405,13 @@ class QueryBuilder {
368
405
  } else {
369
406
  url = `/${this.databaseName}/${this.navigateSourceTableName}('${this.navigateRecordId}')/${this.navigateRelation}${queryString}`;
370
407
  }
371
- const result2 = await this.context._makeRequest(url, options);
408
+ const result2 = await this.context._makeRequest(url, mergedOptions);
372
409
  if (result2.error) {
373
410
  return { data: void 0, error: result2.error };
374
411
  }
375
412
  let response2 = result2.data;
376
- if ((_b = this.occurrence) == null ? void 0 : _b.baseTable) {
413
+ const shouldUseIds2 = mergedOptions.useEntityIds ?? false;
414
+ if (((_b = this.occurrence) == null ? void 0 : _b.baseTable) && shouldUseIds2) {
377
415
  const expandValidationConfigs3 = this.buildExpandValidationConfigs(
378
416
  this.expandConfigs
379
417
  );
@@ -454,13 +492,14 @@ class QueryBuilder {
454
492
  if (this.isNavigate && !this.navigateRecordId && this.navigateRelation && this.navigateSourceTableName) {
455
493
  const result2 = await this.context._makeRequest(
456
494
  `/${this.databaseName}/${this.navigateSourceTableName}/${this.navigateRelation}${queryString}`,
457
- options
495
+ mergedOptions
458
496
  );
459
497
  if (result2.error) {
460
498
  return { data: void 0, error: result2.error };
461
499
  }
462
500
  let response2 = result2.data;
463
- if ((_e = this.occurrence) == null ? void 0 : _e.baseTable) {
501
+ const shouldUseIds2 = mergedOptions.useEntityIds ?? false;
502
+ if (((_e = this.occurrence) == null ? void 0 : _e.baseTable) && shouldUseIds2) {
464
503
  const expandValidationConfigs3 = this.buildExpandValidationConfigs(
465
504
  this.expandConfigs
466
505
  );
@@ -539,10 +578,10 @@ class QueryBuilder {
539
578
  }
540
579
  }
541
580
  if (this.isCountMode) {
542
- const tableId2 = this.getTableId();
581
+ const tableId2 = this.getTableId(mergedOptions.useEntityIds);
543
582
  const result2 = await this.context._makeRequest(
544
583
  `/${this.databaseName}/${tableId2}/$count${queryString}`,
545
- options
584
+ mergedOptions
546
585
  );
547
586
  if (result2.error) {
548
587
  return { data: void 0, error: result2.error };
@@ -550,16 +589,17 @@ class QueryBuilder {
550
589
  const count = typeof result2.data === "string" ? Number(result2.data) : result2.data;
551
590
  return { data: count, error: void 0 };
552
591
  }
553
- const tableId = this.getTableId();
592
+ const tableId = this.getTableId(mergedOptions.useEntityIds);
554
593
  const result = await this.context._makeRequest(
555
594
  `/${this.databaseName}/${tableId}${queryString}`,
556
- options
595
+ mergedOptions
557
596
  );
558
597
  if (result.error) {
559
598
  return { data: void 0, error: result.error };
560
599
  }
561
600
  let response = result.data;
562
- if ((_h = this.occurrence) == null ? void 0 : _h.baseTable) {
601
+ const shouldUseIds = mergedOptions.useEntityIds ?? false;
602
+ if (((_h = this.occurrence) == null ? void 0 : _h.baseTable) && shouldUseIds) {
563
603
  const expandValidationConfigs2 = this.buildExpandValidationConfigs(
564
604
  this.expandConfigs
565
605
  );
@@ -713,6 +753,142 @@ class QueryBuilder {
713
753
  url
714
754
  };
715
755
  }
756
+ toRequest(baseUrl) {
757
+ const config = this.getRequestConfig();
758
+ const fullUrl = `${baseUrl}${config.url}`;
759
+ return new Request(fullUrl, {
760
+ method: config.method,
761
+ headers: {
762
+ "Content-Type": "application/json",
763
+ Accept: "application/json"
764
+ }
765
+ });
766
+ }
767
+ async processResponse(response, options) {
768
+ var _a, _b, _c;
769
+ if (response.status === 204) {
770
+ if (this.singleMode !== false) {
771
+ if (this.singleMode === "maybe") {
772
+ return { data: null, error: void 0 };
773
+ }
774
+ return {
775
+ data: void 0,
776
+ error: new RecordCountMismatchError("one", 0)
777
+ };
778
+ }
779
+ return { data: [], error: void 0 };
780
+ }
781
+ let rawData;
782
+ try {
783
+ rawData = await response.json();
784
+ } catch (err) {
785
+ if (err instanceof SyntaxError && response.status === 204) {
786
+ return { data: [], error: void 0 };
787
+ }
788
+ return {
789
+ data: void 0,
790
+ error: {
791
+ name: "ResponseParseError",
792
+ message: `Failed to parse response JSON: ${err instanceof Error ? err.message : "Unknown error"}`,
793
+ timestamp: /* @__PURE__ */ new Date()
794
+ }
795
+ };
796
+ }
797
+ if (!rawData) {
798
+ return {
799
+ data: void 0,
800
+ error: {
801
+ name: "ResponseError",
802
+ message: "Response body was empty or null",
803
+ timestamp: /* @__PURE__ */ new Date()
804
+ }
805
+ };
806
+ }
807
+ const shouldUseIds = (options == null ? void 0 : options.useEntityIds) ?? this.databaseUseEntityIds;
808
+ let transformedData = rawData;
809
+ if (((_a = this.occurrence) == null ? void 0 : _a.baseTable) && shouldUseIds) {
810
+ const expandValidationConfigs2 = this.buildExpandValidationConfigs(
811
+ this.expandConfigs
812
+ );
813
+ transformedData = transformResponseFields(
814
+ rawData,
815
+ this.occurrence.baseTable,
816
+ expandValidationConfigs2
817
+ );
818
+ }
819
+ if ((options == null ? void 0 : options.skipValidation) === true) {
820
+ const resp = transformedData;
821
+ if (this.singleMode !== false) {
822
+ const records = resp.value ?? [resp];
823
+ const count = Array.isArray(records) ? records.length : 1;
824
+ if (count > 1) {
825
+ return {
826
+ data: void 0,
827
+ error: new RecordCountMismatchError(
828
+ this.singleMode === "exact" ? "one" : "at-most-one",
829
+ count
830
+ )
831
+ };
832
+ }
833
+ if (count === 0) {
834
+ if (this.singleMode === "exact") {
835
+ return {
836
+ data: void 0,
837
+ error: new RecordCountMismatchError("one", 0)
838
+ };
839
+ }
840
+ return { data: null, error: void 0 };
841
+ }
842
+ const record = Array.isArray(records) ? records[0] : records;
843
+ const stripped2 = this.stripODataAnnotationsIfNeeded(record, options);
844
+ return { data: stripped2, error: void 0 };
845
+ } else {
846
+ const records = resp.value ?? [];
847
+ const stripped2 = records.map(
848
+ (record) => this.stripODataAnnotationsIfNeeded(record, options)
849
+ );
850
+ return { data: stripped2, error: void 0 };
851
+ }
852
+ }
853
+ const schema = (_c = (_b = this.occurrence) == null ? void 0 : _b.baseTable) == null ? void 0 : _c.schema;
854
+ const selectedFields = this.queryOptions.select;
855
+ const expandValidationConfigs = this.buildExpandValidationConfigs(
856
+ this.expandConfigs
857
+ );
858
+ if (this.singleMode !== false) {
859
+ const validation2 = await validateSingleResponse(
860
+ transformedData,
861
+ schema,
862
+ selectedFields,
863
+ expandValidationConfigs,
864
+ this.singleMode
865
+ );
866
+ if (!validation2.valid) {
867
+ return { data: void 0, error: validation2.error };
868
+ }
869
+ if (validation2.data === null) {
870
+ return { data: null, error: void 0 };
871
+ }
872
+ const stripped2 = this.stripODataAnnotationsIfNeeded(
873
+ validation2.data,
874
+ options
875
+ );
876
+ return { data: stripped2, error: void 0 };
877
+ }
878
+ const validation = await validateListResponse(
879
+ transformedData,
880
+ schema,
881
+ selectedFields,
882
+ expandValidationConfigs
883
+ );
884
+ if (!validation.valid) {
885
+ return { data: void 0, error: validation.error };
886
+ }
887
+ const stripped = validation.data.map(
888
+ (record) => this.stripODataAnnotationsIfNeeded(record, options)
889
+ );
890
+ return { data: stripped, error: void 0 };
891
+ }
716
892
  }
717
893
  export {
718
894
  QueryBuilder
@@ -1 +1 @@
1
- {"version":3,"file":"query-builder.js","sources":["../../../src/client/query-builder.ts"],"sourcesContent":["import { QueryOptions } from \"odata-query\";\nimport buildQuery from \"odata-query\";\nimport type {\n ExecutionContext,\n ExecutableBuilder,\n WithSystemFields,\n ODataRecordMetadata,\n Result,\n InferSchemaType,\n ExecuteOptions,\n ConditionallyWithODataAnnotations,\n ExtractSchemaFromOccurrence,\n} from \"../types\";\nimport type { Filter } from \"../filter-types\";\nimport type { TableOccurrence } from \"./table-occurrence\";\nimport type { BaseTable } from \"./base-table\";\nimport { validateListResponse, validateSingleResponse } from \"../validation\";\nimport { RecordCountMismatchError } from \"../errors\";\nimport { type FFetchOptions } from \"@fetchkit/ffetch\";\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport {\n transformFieldNamesArray,\n transformFieldName,\n transformTableName,\n transformOrderByField,\n transformResponseFields,\n} from \"../transform\";\n\n// Helper type to extract navigation relation names from an occurrence\ntype ExtractNavigationNames<\n O extends TableOccurrence<any, any, any, any> | undefined,\n> =\n O extends TableOccurrence<any, any, infer Nav, any>\n ? Nav extends Record<string, any>\n ? keyof Nav & string\n : never\n : never;\n\n// Helper type to resolve a navigation item (handles both direct and lazy-loaded)\ntype ResolveNavigationItem<T> = T extends () => infer R ? R : T;\n\n// Helper type to find target occurrence by relation name\ntype FindNavigationTarget<\n O extends TableOccurrence<any, any, any, any> | undefined,\n Name extends string,\n> =\n O extends TableOccurrence<any, any, infer Nav, any>\n ? Nav extends Record<string, any>\n ? Name extends keyof Nav\n ? ResolveNavigationItem<Nav[Name]>\n : TableOccurrence<\n BaseTable<Record<string, StandardSchemaV1>, any, any, any>,\n any,\n any,\n any\n >\n : TableOccurrence<\n BaseTable<Record<string, StandardSchemaV1>, any, any, any>,\n any,\n any,\n any\n >\n : TableOccurrence<\n BaseTable<Record<string, StandardSchemaV1>, any, any, any>,\n any,\n any,\n any\n >;\n\n// Helper type to get the inferred schema type from a target occurrence\ntype GetTargetSchemaType<\n O extends TableOccurrence<any, any, any, any> | undefined,\n Rel extends string,\n> = [FindNavigationTarget<O, Rel>] extends [\n TableOccurrence<infer BT, any, any, any>,\n]\n ? [BT] extends [BaseTable<infer S, any>]\n ? [S] extends [Record<string, StandardSchemaV1>]\n ? InferSchemaType<S>\n : Record<string, any>\n : Record<string, any>\n : Record<string, any>;\n\n// Internal type for expand configuration\ntype ExpandConfig = {\n relation: string;\n options?: Partial<QueryOptions<any>>;\n};\n\n// Type to represent expanded relations\ntype ExpandedRelations = Record<string, { schema: any; selected: any }>;\n\nexport class QueryBuilder<\n T extends Record<string, any>,\n Selected extends keyof T = keyof T,\n SingleMode extends \"exact\" | \"maybe\" | false = false,\n IsCount extends boolean = false,\n Occ extends TableOccurrence<any, any, any, any> | undefined = undefined,\n Expands extends ExpandedRelations = {},\n> {\n private queryOptions: Partial<QueryOptions<T>> = {};\n private expandConfigs: ExpandConfig[] = [];\n private singleMode: SingleMode = false as SingleMode;\n private isCountMode = false as IsCount;\n private occurrence?: Occ;\n private tableName: string;\n private databaseName: string;\n private context: ExecutionContext;\n private isNavigate?: boolean;\n private navigateRecordId?: string | number;\n private navigateRelation?: string;\n private navigateSourceTableName?: string;\n private navigateBaseRelation?: string;\n constructor(config: {\n occurrence?: Occ;\n tableName: string;\n databaseName: string;\n context: ExecutionContext;\n }) {\n this.occurrence = config.occurrence;\n this.tableName = config.tableName;\n this.databaseName = config.databaseName;\n this.context = config.context;\n }\n\n /**\n * Helper to conditionally strip OData annotations based on options\n */\n private stripODataAnnotationsIfNeeded<T extends Record<string, any>>(\n data: T,\n options?: ExecuteOptions,\n ): T {\n // Only include annotations if explicitly requested\n if (options?.includeODataAnnotations === true) {\n return data;\n }\n\n // Strip OData annotations\n const { \"@id\": _id, \"@editLink\": _editLink, ...rest } = data;\n return rest as T;\n }\n\n /**\n * Gets the table ID (FMTID) if using entity IDs, otherwise returns the table name\n */\n private getTableId(): string {\n return this.occurrence\n ? transformTableName(this.occurrence)\n : this.tableName;\n }\n\n select<K extends keyof T>(\n ...fields: K[]\n ): QueryBuilder<T, K, SingleMode, IsCount, Occ, Expands> {\n const uniqueFields = [...new Set(fields)];\n const newBuilder = new QueryBuilder<\n T,\n K,\n SingleMode,\n IsCount,\n Occ,\n Expands\n >({\n occurrence: this.occurrence,\n tableName: this.tableName,\n databaseName: this.databaseName,\n context: this.context,\n });\n newBuilder.queryOptions = {\n ...this.queryOptions,\n select: uniqueFields as string[],\n };\n newBuilder.expandConfigs = [...this.expandConfigs];\n newBuilder.singleMode = this.singleMode;\n newBuilder.isCountMode = this.isCountMode;\n // Preserve navigation metadata\n newBuilder.isNavigate = this.isNavigate;\n newBuilder.navigateRecordId = this.navigateRecordId;\n newBuilder.navigateRelation = this.navigateRelation;\n newBuilder.navigateSourceTableName = this.navigateSourceTableName;\n newBuilder.navigateBaseRelation = this.navigateBaseRelation;\n return newBuilder;\n }\n\n /**\n * Transforms our filter format to odata-query's expected format\n * - Arrays of operators are converted to AND conditions\n * - Single operator objects pass through as-is\n * - Shorthand values are handled by odata-query\n */\n private transformFilter(\n filter: Filter<ExtractSchemaFromOccurrence<Occ>>,\n ): QueryOptions<T>[\"filter\"] {\n if (typeof filter === \"string\") {\n // Raw string filters pass through\n return filter;\n }\n\n if (Array.isArray(filter)) {\n // Array of filters - odata-query handles this as implicit AND\n return filter.map((f) => this.transformFilter(f as any)) as any;\n }\n\n // Check if it's a logical filter (and/or/not)\n if (\"and\" in filter || \"or\" in filter || \"not\" in filter) {\n const result: any = {};\n if (\"and\" in filter && Array.isArray(filter.and)) {\n result.and = filter.and.map((f: any) => this.transformFilter(f));\n }\n if (\"or\" in filter && Array.isArray(filter.or)) {\n result.or = filter.or.map((f: any) => this.transformFilter(f));\n }\n if (\"not\" in filter && filter.not) {\n result.not = this.transformFilter(filter.not as any);\n }\n return result;\n }\n\n // Transform field filters\n const result: any = {};\n const andConditions: any[] = [];\n\n for (const [field, value] of Object.entries(filter)) {\n // Transform field name to FMFID if using entity IDs\n const fieldId = this.occurrence?.baseTable\n ? transformFieldName(field, this.occurrence.baseTable)\n : field;\n\n if (Array.isArray(value)) {\n // Array of operators - convert to AND conditions\n if (value.length === 1) {\n // Single operator in array - unwrap it\n result[fieldId] = value[0];\n } else {\n // Multiple operators - combine with AND\n // Create separate conditions for each operator\n for (const op of value) {\n andConditions.push({ [fieldId]: op });\n }\n }\n } else if (\n value &&\n typeof value === \"object\" &&\n !(value instanceof Date) &&\n !Array.isArray(value)\n ) {\n // Check if it's an operator object (has operator keys like eq, gt, etc.)\n const operatorKeys = [\n \"eq\",\n \"ne\",\n \"gt\",\n \"ge\",\n \"lt\",\n \"le\",\n \"contains\",\n \"startswith\",\n \"endswith\",\n \"in\",\n ];\n const isOperatorObject = operatorKeys.some((key) => key in value);\n\n if (isOperatorObject) {\n // Single operator object - pass through\n result[fieldId] = value;\n } else {\n // Regular object - might be nested filter, pass through\n result[fieldId] = value;\n }\n } else {\n // Primitive value (shorthand) - pass through\n result[fieldId] = value;\n }\n }\n\n // If we have AND conditions from arrays, combine them\n if (andConditions.length > 0) {\n if (Object.keys(result).length > 0) {\n // We have both regular fields and array-derived AND conditions\n // Combine everything with AND\n return { and: [...andConditions, result] };\n } else {\n // Only array-derived AND conditions\n return { and: andConditions };\n }\n }\n\n return result;\n }\n\n filter(\n filter: Filter<ExtractSchemaFromOccurrence<Occ>>,\n ): QueryBuilder<T, Selected, SingleMode, IsCount, Occ, Expands> {\n // Transform our filter format to odata-query's expected format\n this.queryOptions.filter = this.transformFilter(filter) as any;\n return this;\n }\n\n orderBy(\n orderBy: QueryOptions<T>[\"orderBy\"],\n ): QueryBuilder<T, Selected, SingleMode, IsCount, Occ, Expands> {\n // Transform field names to FMFIDs if using entity IDs\n if (this.occurrence?.baseTable && orderBy) {\n if (Array.isArray(orderBy)) {\n this.queryOptions.orderBy = orderBy.map((field) =>\n transformOrderByField(String(field), this.occurrence!.baseTable),\n );\n } else {\n this.queryOptions.orderBy = transformOrderByField(\n String(orderBy),\n this.occurrence.baseTable,\n );\n }\n } else {\n this.queryOptions.orderBy = orderBy;\n }\n return this;\n }\n\n top(\n count: number,\n ): QueryBuilder<T, Selected, SingleMode, IsCount, Occ, Expands> {\n this.queryOptions.top = count;\n return this;\n }\n\n skip(\n count: number,\n ): QueryBuilder<T, Selected, SingleMode, IsCount, Occ, Expands> {\n this.queryOptions.skip = count;\n return this;\n }\n\n /**\n * Formats select fields for use in query strings.\n * - Transforms field names to FMFIDs if using entity IDs\n * - Wraps \"id\" fields in double quotes\n * - URL-encodes special characters but preserves spaces\n */\n private formatSelectFields(\n select: QueryOptions<any>[\"select\"],\n baseTable?: BaseTable<any, any, any, any>,\n ): string {\n if (!select) return \"\";\n const selectFieldsArray = Array.isArray(select) ? select : [select];\n\n // Transform to field IDs if using entity IDs\n const transformedFields = baseTable\n ? transformFieldNamesArray(\n selectFieldsArray.map((f) => String(f)),\n baseTable,\n )\n : selectFieldsArray.map((f) => String(f));\n\n return transformedFields\n .map((field) => {\n if (field === \"id\") return `\"id\"`;\n const encodedField = encodeURIComponent(String(field));\n return encodedField.replace(/%20/g, \" \");\n })\n .join(\",\");\n }\n\n /**\n * Builds expand validation configs from internal expand configurations.\n * These are used to validate expanded navigation properties.\n */\n private buildExpandValidationConfigs(\n configs: ExpandConfig[],\n ): import(\"../validation\").ExpandValidationConfig[] {\n return configs.map((config) => {\n // Look up target occurrence from navigation\n const targetOccurrence = this.occurrence?.navigation[config.relation];\n const targetSchema = targetOccurrence?.baseTable?.schema;\n\n // Extract selected fields from options\n const selectedFields = config.options?.select\n ? Array.isArray(config.options.select)\n ? config.options.select.map((f) => String(f))\n : [String(config.options.select)]\n : undefined;\n\n return {\n relation: config.relation,\n targetSchema: targetSchema,\n targetOccurrence: targetOccurrence,\n targetBaseTable: targetOccurrence?.baseTable,\n occurrence: targetOccurrence, // Add occurrence for transformation\n selectedFields: selectedFields,\n nestedExpands: undefined, // TODO: Handle nested expands if needed\n };\n });\n }\n\n /**\n * Builds OData expand query string from expand configurations.\n * Handles nested expands recursively.\n * Transforms relation names to FMTIDs if using entity IDs.\n */\n private buildExpandString(configs: ExpandConfig[]): string {\n if (configs.length === 0) {\n return \"\";\n }\n\n return configs\n .map((config) => {\n // Get target occurrence for this relation\n const targetOccurrence = this.occurrence?.navigation[config.relation];\n\n // When using entity IDs, use the target table's FMTID in the expand parameter\n // FileMaker expects FMTID in $expand when Prefer header is set\n const relationName =\n targetOccurrence && targetOccurrence.isUsingTableId()\n ? targetOccurrence.getTableId()\n : config.relation;\n\n if (!config.options || Object.keys(config.options).length === 0) {\n // Simple expand without options\n return relationName;\n }\n\n // Build query options for this expand\n const parts: string[] = [];\n\n if (config.options.select) {\n // Pass target base table for field transformation\n const selectFields = this.formatSelectFields(\n config.options.select,\n targetOccurrence?.baseTable,\n );\n parts.push(`$select=${selectFields}`);\n }\n\n if (config.options.filter) {\n // Filter should already be transformed by the nested builder\n // Use odata-query to build filter string\n const filterQuery = buildQuery({ filter: config.options.filter });\n const filterMatch = filterQuery.match(/\\$filter=([^&]+)/);\n if (filterMatch) {\n parts.push(`$filter=${filterMatch[1]}`);\n }\n }\n\n if (config.options.orderBy) {\n // OrderBy should already be transformed by the nested builder\n const orderByValue = Array.isArray(config.options.orderBy)\n ? config.options.orderBy.join(\",\")\n : config.options.orderBy;\n parts.push(`$orderby=${String(orderByValue)}`);\n }\n\n if (config.options.top !== undefined) {\n parts.push(`$top=${config.options.top}`);\n }\n\n if (config.options.skip !== undefined) {\n parts.push(`$skip=${config.options.skip}`);\n }\n\n // Handle nested expands (from expand configs)\n if (config.options.expand) {\n // If expand is a string, it's already been built\n if (typeof config.options.expand === \"string\") {\n parts.push(`$expand=${config.options.expand}`);\n }\n }\n\n if (parts.length === 0) {\n return relationName;\n }\n\n return `${relationName}(${parts.join(\";\")})`;\n })\n .join(\",\");\n }\n\n expand<\n Rel extends ExtractNavigationNames<Occ> | (string & {}),\n TargetOcc extends FindNavigationTarget<Occ, Rel> = FindNavigationTarget<\n Occ,\n Rel\n >,\n TargetSchema extends GetTargetSchemaType<Occ, Rel> = GetTargetSchemaType<\n Occ,\n Rel\n >,\n TargetSelected extends keyof TargetSchema = keyof TargetSchema,\n >(\n relation: Rel,\n callback?: (\n builder: QueryBuilder<\n TargetSchema,\n keyof TargetSchema,\n false,\n false,\n TargetOcc extends TableOccurrence<any, any, any, any>\n ? TargetOcc\n : undefined\n >,\n ) => QueryBuilder<\n WithSystemFields<TargetSchema>,\n TargetSelected,\n any,\n any,\n any\n >,\n ): QueryBuilder<\n T,\n Selected,\n SingleMode,\n IsCount,\n Occ,\n Expands & {\n [K in Rel]: { schema: TargetSchema; selected: TargetSelected };\n }\n > {\n // Look up target occurrence from navigation\n const targetOccurrence = this.occurrence?.navigation[relation as string];\n\n if (callback) {\n // Create a new QueryBuilder for the target occurrence\n const targetBuilder = new QueryBuilder<any>({\n occurrence: targetOccurrence,\n tableName: targetOccurrence?.name ?? (relation as string),\n databaseName: this.databaseName,\n context: this.context,\n });\n\n // Cast to the expected type for the callback\n // At runtime, the builder is untyped (any), but at compile-time we enforce proper types\n const typedBuilder = targetBuilder as QueryBuilder<\n TargetSchema,\n keyof TargetSchema,\n false,\n false,\n TargetOcc extends TableOccurrence<any, any, any, any>\n ? TargetOcc\n : undefined\n >;\n\n // Pass to callback and get configured builder\n const configuredBuilder = callback(typedBuilder);\n\n // Extract the builder's query options\n const expandOptions: Partial<QueryOptions<any>> = {\n ...configuredBuilder.queryOptions,\n };\n\n // If the configured builder has nested expands, we need to include them\n if (configuredBuilder.expandConfigs.length > 0) {\n // Build nested expand string from the configured builder's expand configs\n const nestedExpandString = this.buildExpandString(\n configuredBuilder.expandConfigs,\n );\n if (nestedExpandString) {\n // Add nested expand to options\n expandOptions.expand = nestedExpandString as any;\n }\n }\n\n const expandConfig: ExpandConfig = {\n relation: relation as string,\n options: expandOptions,\n };\n\n this.expandConfigs.push(expandConfig);\n } else {\n // Simple expand without callback\n this.expandConfigs.push({ relation: relation as string });\n }\n\n return this as any;\n }\n\n single(): QueryBuilder<T, Selected, \"exact\", IsCount, Occ, Expands> {\n const newBuilder = new QueryBuilder<\n T,\n Selected,\n \"exact\",\n IsCount,\n Occ,\n Expands\n >({\n occurrence: this.occurrence,\n tableName: this.tableName,\n databaseName: this.databaseName,\n context: this.context,\n });\n newBuilder.queryOptions = { ...this.queryOptions };\n newBuilder.expandConfigs = [...this.expandConfigs];\n newBuilder.singleMode = \"exact\";\n newBuilder.isCountMode = this.isCountMode;\n // Preserve navigation metadata\n newBuilder.isNavigate = this.isNavigate;\n newBuilder.navigateRecordId = this.navigateRecordId;\n newBuilder.navigateRelation = this.navigateRelation;\n newBuilder.navigateSourceTableName = this.navigateSourceTableName;\n newBuilder.navigateBaseRelation = this.navigateBaseRelation;\n return newBuilder;\n }\n\n maybeSingle(): QueryBuilder<T, Selected, \"maybe\", IsCount, Occ, Expands> {\n const newBuilder = new QueryBuilder<\n T,\n Selected,\n \"maybe\",\n IsCount,\n Occ,\n Expands\n >({\n occurrence: this.occurrence,\n tableName: this.tableName,\n databaseName: this.databaseName,\n context: this.context,\n });\n newBuilder.queryOptions = { ...this.queryOptions };\n newBuilder.expandConfigs = [...this.expandConfigs];\n newBuilder.singleMode = \"maybe\";\n newBuilder.isCountMode = this.isCountMode;\n // Preserve navigation metadata\n newBuilder.isNavigate = this.isNavigate;\n newBuilder.navigateRecordId = this.navigateRecordId;\n newBuilder.navigateRelation = this.navigateRelation;\n newBuilder.navigateSourceTableName = this.navigateSourceTableName;\n newBuilder.navigateBaseRelation = this.navigateBaseRelation;\n return newBuilder;\n }\n\n count(): QueryBuilder<T, Selected, SingleMode, true, Occ, Expands> {\n const newBuilder = new QueryBuilder<\n T,\n Selected,\n SingleMode,\n true,\n Occ,\n Expands\n >({\n occurrence: this.occurrence,\n tableName: this.tableName,\n databaseName: this.databaseName,\n context: this.context,\n });\n newBuilder.queryOptions = { ...this.queryOptions, count: true };\n newBuilder.expandConfigs = [...this.expandConfigs];\n newBuilder.singleMode = this.singleMode;\n newBuilder.isCountMode = true as true;\n // Preserve navigation metadata\n newBuilder.isNavigate = this.isNavigate;\n newBuilder.navigateRecordId = this.navigateRecordId;\n newBuilder.navigateRelation = this.navigateRelation;\n newBuilder.navigateSourceTableName = this.navigateSourceTableName;\n newBuilder.navigateBaseRelation = this.navigateBaseRelation;\n return newBuilder;\n }\n\n async execute<EO extends ExecuteOptions>(\n options?: RequestInit & FFetchOptions & EO,\n ): Promise<\n Result<\n IsCount extends true\n ? number\n : SingleMode extends \"exact\"\n ? ConditionallyWithODataAnnotations<\n Pick<T, Selected> & {\n [K in keyof Expands]: Pick<\n Expands[K][\"schema\"],\n Expands[K][\"selected\"]\n >[];\n },\n EO[\"includeODataAnnotations\"] extends true ? true : false\n >\n : SingleMode extends \"maybe\"\n ? ConditionallyWithODataAnnotations<\n Pick<T, Selected> & {\n [K in keyof Expands]: Pick<\n Expands[K][\"schema\"],\n Expands[K][\"selected\"]\n >[];\n },\n EO[\"includeODataAnnotations\"] extends true ? true : false\n > | null\n : ConditionallyWithODataAnnotations<\n Pick<T, Selected> & {\n [K in keyof Expands]: Pick<\n Expands[K][\"schema\"],\n Expands[K][\"selected\"]\n >[];\n },\n EO[\"includeODataAnnotations\"] extends true ? true : false\n >[]\n >\n > {\n // Build query without expand (we'll add it manually)\n const queryOptionsWithoutExpand = { ...this.queryOptions };\n delete queryOptionsWithoutExpand.expand;\n\n // Format select fields before building query\n if (queryOptionsWithoutExpand.select) {\n queryOptionsWithoutExpand.select = this.formatSelectFields(\n queryOptionsWithoutExpand.select,\n this.occurrence?.baseTable,\n ) as any;\n }\n\n let queryString = buildQuery(queryOptionsWithoutExpand);\n\n // Build custom expand string\n const expandString = this.buildExpandString(this.expandConfigs);\n if (expandString) {\n const separator = queryString.includes(\"?\") ? \"&\" : \"?\";\n queryString = `${queryString}${separator}$expand=${expandString}`;\n }\n\n // Handle navigation from RecordBuilder\n if (\n this.isNavigate &&\n this.navigateRecordId &&\n this.navigateRelation &&\n this.navigateSourceTableName\n ) {\n let url: string;\n if (this.navigateBaseRelation) {\n // Navigation from a navigated EntitySet: /sourceTable/baseRelation('recordId')/relation\n url = `/${this.databaseName}/${this.navigateSourceTableName}/${this.navigateBaseRelation}('${this.navigateRecordId}')/${this.navigateRelation}${queryString}`;\n } else {\n // Normal navigation: /sourceTable('recordId')/relation\n url = `/${this.databaseName}/${this.navigateSourceTableName}('${this.navigateRecordId}')/${this.navigateRelation}${queryString}`;\n }\n const result = await this.context._makeRequest(url, options);\n\n if (result.error) {\n return { data: undefined, error: result.error };\n }\n\n let response = result.data;\n\n // Transform response field IDs back to names if using entity IDs\n if (this.occurrence?.baseTable) {\n const expandValidationConfigs = this.buildExpandValidationConfigs(\n this.expandConfigs,\n );\n response = transformResponseFields(\n response,\n this.occurrence.baseTable,\n expandValidationConfigs,\n );\n }\n\n // Skip validation if requested\n if (options?.skipValidation === true) {\n const resp = response as any;\n if (this.singleMode !== false) {\n const records = resp.value ?? [resp];\n const count = Array.isArray(records) ? records.length : 1;\n\n if (count > 1) {\n return {\n data: undefined,\n error: new RecordCountMismatchError(\n this.singleMode === \"exact\" ? \"one\" : \"at-most-one\",\n count,\n ),\n };\n }\n\n if (count === 0) {\n if (this.singleMode === \"exact\") {\n return {\n data: undefined,\n error: new RecordCountMismatchError(\"one\", 0),\n };\n }\n return { data: null as any, error: undefined };\n }\n\n const record = Array.isArray(records) ? records[0] : records;\n const stripped = this.stripODataAnnotationsIfNeeded(record, options);\n return { data: stripped as any, error: undefined };\n } else {\n const records = resp.value ?? [];\n const stripped = records.map((record: any) =>\n this.stripODataAnnotationsIfNeeded(record, options),\n );\n return { data: stripped as any, error: undefined };\n }\n }\n\n // Get schema from occurrence if available\n const schema = this.occurrence?.baseTable?.schema;\n const selectedFields = this.queryOptions.select as\n | (keyof T)[]\n | undefined;\n const expandValidationConfigs = this.buildExpandValidationConfigs(\n this.expandConfigs,\n );\n\n if (this.singleMode !== false) {\n const validation = await validateSingleResponse<T>(\n response,\n schema,\n selectedFields,\n expandValidationConfigs,\n this.singleMode,\n );\n if (!validation.valid) {\n return { data: undefined, error: validation.error };\n }\n const stripped = validation.data\n ? this.stripODataAnnotationsIfNeeded(validation.data, options)\n : null;\n return { data: stripped as any, error: undefined };\n } else {\n const validation = await validateListResponse<T>(\n response,\n schema,\n selectedFields,\n expandValidationConfigs,\n );\n if (!validation.valid) {\n return { data: undefined, error: validation.error };\n }\n const stripped = validation.data.map((record) =>\n this.stripODataAnnotationsIfNeeded(record, options),\n );\n return { data: stripped as any, error: undefined };\n }\n }\n\n // Handle navigation from EntitySet (without record ID)\n if (\n this.isNavigate &&\n !this.navigateRecordId &&\n this.navigateRelation &&\n this.navigateSourceTableName\n ) {\n const result = await this.context._makeRequest(\n `/${this.databaseName}/${this.navigateSourceTableName}/${this.navigateRelation}${queryString}`,\n options,\n );\n\n if (result.error) {\n return { data: undefined, error: result.error };\n }\n\n let response = result.data;\n\n // Transform response field IDs back to names if using entity IDs\n if (this.occurrence?.baseTable) {\n const expandValidationConfigs = this.buildExpandValidationConfigs(\n this.expandConfigs,\n );\n response = transformResponseFields(\n response,\n this.occurrence.baseTable,\n expandValidationConfigs,\n );\n }\n\n // Skip validation if requested\n if (options?.skipValidation === true) {\n const resp = response as any;\n if (this.singleMode !== false) {\n const records = resp.value ?? [resp];\n const count = Array.isArray(records) ? records.length : 1;\n\n if (count > 1) {\n return {\n data: undefined,\n error: new RecordCountMismatchError(\n this.singleMode === \"exact\" ? \"one\" : \"at-most-one\",\n count,\n ),\n };\n }\n\n if (count === 0) {\n if (this.singleMode === \"exact\") {\n return {\n data: undefined,\n error: new RecordCountMismatchError(\"one\", 0),\n };\n }\n return { data: null as any, error: undefined };\n }\n\n const record = Array.isArray(records) ? records[0] : records;\n const stripped = this.stripODataAnnotationsIfNeeded(record, options);\n return { data: stripped as any, error: undefined };\n } else {\n const records = resp.value ?? [];\n const stripped = records.map((record: any) =>\n this.stripODataAnnotationsIfNeeded(record, options),\n );\n return { data: stripped as any, error: undefined };\n }\n }\n\n // Get schema from occurrence if available\n const schema = this.occurrence?.baseTable?.schema;\n const selectedFields = this.queryOptions.select as\n | (keyof T)[]\n | undefined;\n const expandValidationConfigs = this.buildExpandValidationConfigs(\n this.expandConfigs,\n );\n\n if (this.singleMode !== false) {\n const validation = await validateSingleResponse<T>(\n response,\n schema,\n selectedFields,\n expandValidationConfigs,\n this.singleMode,\n );\n if (!validation.valid) {\n return { data: undefined, error: validation.error };\n }\n const stripped = validation.data\n ? this.stripODataAnnotationsIfNeeded(validation.data, options)\n : null;\n return { data: stripped as any, error: undefined };\n } else {\n const validation = await validateListResponse<T>(\n response,\n schema,\n selectedFields,\n expandValidationConfigs,\n );\n if (!validation.valid) {\n return { data: undefined, error: validation.error };\n }\n const stripped = validation.data.map((record) =>\n this.stripODataAnnotationsIfNeeded(record, options),\n );\n return { data: stripped as any, error: undefined };\n }\n }\n\n // Handle $count endpoint\n if (this.isCountMode) {\n const tableId = this.getTableId();\n const result = await this.context._makeRequest(\n `/${this.databaseName}/${tableId}/$count${queryString}`,\n options,\n );\n\n if (result.error) {\n return { data: undefined, error: result.error };\n }\n\n // OData returns count as a string, convert to number\n const count =\n typeof result.data === \"string\" ? Number(result.data) : result.data;\n return { data: count as number, error: undefined } as any;\n }\n\n const tableId = this.getTableId();\n const result = await this.context._makeRequest(\n `/${this.databaseName}/${tableId}${queryString}`,\n options,\n );\n\n if (result.error) {\n return { data: undefined, error: result.error };\n }\n\n let response = result.data;\n\n // Transform response field IDs back to names if using entity IDs\n if (this.occurrence?.baseTable) {\n const expandValidationConfigs = this.buildExpandValidationConfigs(\n this.expandConfigs,\n );\n response = transformResponseFields(\n response,\n this.occurrence.baseTable,\n expandValidationConfigs,\n );\n }\n\n // Skip validation if requested\n if (options?.skipValidation === true) {\n const resp = response as any;\n if (this.singleMode !== false) {\n const records = resp.value ?? [resp];\n const count = Array.isArray(records) ? records.length : 1;\n\n if (count > 1) {\n return {\n data: undefined,\n error: new RecordCountMismatchError(\n this.singleMode === \"exact\" ? \"one\" : \"at-most-one\",\n count,\n ),\n };\n }\n\n if (count === 0) {\n if (this.singleMode === \"exact\") {\n return {\n data: undefined,\n error: new RecordCountMismatchError(\"one\", 0),\n };\n }\n return { data: null as any, error: undefined };\n }\n\n const record = Array.isArray(records) ? records[0] : records;\n const stripped = this.stripODataAnnotationsIfNeeded(record, options);\n return { data: stripped as any, error: undefined };\n } else {\n // Handle list response structure\n const records = resp.value ?? [];\n const stripped = records.map((record: any) =>\n this.stripODataAnnotationsIfNeeded(record, options),\n );\n return { data: stripped as any, error: undefined };\n }\n }\n\n // Get schema from occurrence if available\n const schema = this.occurrence?.baseTable?.schema;\n const selectedFields = this.queryOptions.select as (keyof T)[] | undefined;\n const expandValidationConfigs = this.buildExpandValidationConfigs(\n this.expandConfigs,\n );\n\n if (this.singleMode !== false) {\n const validation = await validateSingleResponse<T>(\n response,\n schema,\n selectedFields,\n expandValidationConfigs,\n this.singleMode,\n );\n if (!validation.valid) {\n return { data: undefined, error: validation.error };\n }\n const stripped = validation.data\n ? this.stripODataAnnotationsIfNeeded(validation.data, options)\n : null;\n return {\n data: stripped as any,\n error: undefined,\n };\n } else {\n const validation = await validateListResponse<T>(\n response,\n schema,\n selectedFields,\n expandValidationConfigs,\n );\n if (!validation.valid) {\n return { data: undefined, error: validation.error };\n }\n const stripped = validation.data.map((record) =>\n this.stripODataAnnotationsIfNeeded(record, options),\n );\n return {\n data: stripped as any,\n error: undefined,\n };\n }\n }\n\n getQueryString(): string {\n // Build query without expand (we'll add it manually)\n const queryOptionsWithoutExpand = { ...this.queryOptions };\n delete queryOptionsWithoutExpand.expand;\n\n // Format select fields before building query - buildQuery treats & as separator,\n // so we need to pre-encode special characters. buildQuery preserves encoded values.\n if (queryOptionsWithoutExpand.select) {\n queryOptionsWithoutExpand.select = this.formatSelectFields(\n queryOptionsWithoutExpand.select,\n ) as any;\n }\n\n let queryParams = buildQuery(queryOptionsWithoutExpand);\n\n // Post-process: buildQuery encodes spaces as %20, but we want to preserve spaces\n // Replace %20 with spaces in the $select part\n if (this.queryOptions.select) {\n queryParams = queryParams.replace(\n /\\$select=([^&]*)/,\n (match, selectValue) => {\n return `$select=${selectValue.replace(/%20/g, \" \")}`;\n },\n );\n }\n const expandString = this.buildExpandString(this.expandConfigs);\n if (expandString) {\n const separator = queryParams.includes(\"?\") ? \"&\" : \"?\";\n queryParams = `${queryParams}${separator}$expand=${expandString}`;\n }\n\n // Handle navigation from RecordBuilder (with record ID)\n if (\n this.isNavigate &&\n this.navigateRecordId &&\n this.navigateRelation &&\n this.navigateSourceTableName\n ) {\n let path: string;\n if (this.navigateBaseRelation) {\n // Navigation from a navigated EntitySet: /sourceTable/baseRelation('recordId')/relation\n path = `/${this.navigateSourceTableName}/${this.navigateBaseRelation}('${this.navigateRecordId}')/${this.navigateRelation}`;\n } else {\n // Normal navigation: /sourceTableName('recordId')/relationName\n path = `/${this.navigateSourceTableName}('${this.navigateRecordId}')/${this.navigateRelation}`;\n }\n // Append query params if any exist\n return queryParams ? `${path}${queryParams}` : path;\n }\n\n // Handle navigation from EntitySet (without record ID)\n if (\n this.isNavigate &&\n !this.navigateRecordId &&\n this.navigateRelation &&\n this.navigateSourceTableName\n ) {\n // Return the path portion: /sourceTableName/relationName\n const path = `/${this.navigateSourceTableName}/${this.navigateRelation}`;\n // Append query params if any exist\n return queryParams ? `${path}${queryParams}` : path;\n }\n\n // Default case: return table name with query params\n return `/${this.tableName}${queryParams}`;\n }\n\n getRequestConfig(): { method: string; url: string; body?: any } {\n // Build query without expand (we'll add it manually)\n const queryOptionsWithoutExpand = { ...this.queryOptions };\n delete queryOptionsWithoutExpand.expand;\n\n // Format select fields before building query\n if (queryOptionsWithoutExpand.select) {\n queryOptionsWithoutExpand.select = this.formatSelectFields(\n queryOptionsWithoutExpand.select,\n ) as any;\n }\n\n let queryString = buildQuery(queryOptionsWithoutExpand);\n\n // Build custom expand string\n const expandString = this.buildExpandString(this.expandConfigs);\n if (expandString) {\n const separator = queryString.includes(\"?\") ? \"&\" : \"?\";\n queryString = `${queryString}${separator}$expand=${expandString}`;\n }\n\n let url: string;\n\n // Handle navigation from RecordBuilder (with record ID)\n if (\n this.isNavigate &&\n this.navigateRecordId &&\n this.navigateRelation &&\n this.navigateSourceTableName\n ) {\n if (this.navigateBaseRelation) {\n // Navigation from a navigated EntitySet: /sourceTable/baseRelation('recordId')/relation\n url = `/${this.databaseName}/${this.navigateSourceTableName}/${this.navigateBaseRelation}('${this.navigateRecordId}')/${this.navigateRelation}${queryString}`;\n } else {\n // Normal navigation: /sourceTable('recordId')/relation\n url = `/${this.databaseName}/${this.navigateSourceTableName}('${this.navigateRecordId}')/${this.navigateRelation}${queryString}`;\n }\n } else if (\n this.isNavigate &&\n !this.navigateRecordId &&\n this.navigateRelation &&\n this.navigateSourceTableName\n ) {\n // Handle navigation from EntitySet (without record ID)\n url = `/${this.databaseName}/${this.navigateSourceTableName}/${this.navigateRelation}${queryString}`;\n } else if (this.isCountMode) {\n url = `/${this.databaseName}/${this.tableName}/$count${queryString}`;\n } else {\n url = `/${this.databaseName}/${this.tableName}${queryString}`;\n }\n\n return {\n method: \"GET\",\n url,\n };\n }\n}\n"],"names":["result","response","expandValidationConfigs","schema","selectedFields","tableId"],"mappings":"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"}
1
+ {"version":3,"file":"query-builder.js","sources":["../../../src/client/query-builder.ts"],"sourcesContent":["import { QueryOptions } from \"odata-query\";\nimport buildQuery from \"odata-query\";\nimport type {\n ExecutionContext,\n ExecutableBuilder,\n WithSystemFields,\n Result,\n InferSchemaType,\n ExecuteOptions,\n ConditionallyWithODataAnnotations,\n ExtractSchemaFromOccurrence,\n} from \"../types\";\nimport type { Filter } from \"../filter-types\";\nimport type { TableOccurrence } from \"./table-occurrence\";\nimport type { BaseTable } from \"./base-table\";\nimport { validateListResponse, validateSingleResponse } from \"../validation\";\nimport { RecordCountMismatchError } from \"../errors\";\nimport { type FFetchOptions } from \"@fetchkit/ffetch\";\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport {\n transformFieldNamesArray,\n transformFieldName,\n transformOrderByField,\n transformResponseFields,\n getTableIdentifiers,\n} from \"../transform\";\n\n// Helper type to extract navigation relation names from an occurrence\ntype ExtractNavigationNames<\n O extends TableOccurrence<any, any, any, any> | undefined,\n> =\n O extends TableOccurrence<any, any, infer Nav, any>\n ? Nav extends Record<string, any>\n ? keyof Nav & string\n : never\n : never;\n\n// Helper type to resolve a navigation item (handles both direct and lazy-loaded)\ntype ResolveNavigationItem<T> = T extends () => infer R ? R : T;\n\n// Helper type to find target occurrence by relation name\ntype FindNavigationTarget<\n O extends TableOccurrence<any, any, any, any> | undefined,\n Name extends string,\n> =\n O extends TableOccurrence<any, any, infer Nav, any>\n ? Nav extends Record<string, any>\n ? Name extends keyof Nav\n ? ResolveNavigationItem<Nav[Name]>\n : TableOccurrence<\n BaseTable<Record<string, StandardSchemaV1>, any, any, any>,\n any,\n any,\n any\n >\n : TableOccurrence<\n BaseTable<Record<string, StandardSchemaV1>, any, any, any>,\n any,\n any,\n any\n >\n : TableOccurrence<\n BaseTable<Record<string, StandardSchemaV1>, any, any, any>,\n any,\n any,\n any\n >;\n\n// Helper type to get the inferred schema type from a target occurrence\ntype GetTargetSchemaType<\n O extends TableOccurrence<any, any, any, any> | undefined,\n Rel extends string,\n> = [FindNavigationTarget<O, Rel>] extends [\n TableOccurrence<infer BT, any, any, any>,\n]\n ? [BT] extends [BaseTable<infer S, any>]\n ? [S] extends [Record<string, StandardSchemaV1>]\n ? InferSchemaType<S>\n : Record<string, any>\n : Record<string, any>\n : Record<string, any>;\n\n// Internal type for expand configuration\ntype ExpandConfig = {\n relation: string;\n options?: Partial<QueryOptions<any>>;\n};\n\n// Type to represent expanded relations\nexport type ExpandedRelations = Record<string, { schema: any; selected: any }>;\n\nexport type QueryReturnType<\n T extends Record<string, any>,\n Selected extends keyof T,\n SingleMode extends \"exact\" | \"maybe\" | false,\n IsCount extends boolean,\n Expands extends ExpandedRelations,\n> = IsCount extends true\n ? number\n : SingleMode extends \"exact\"\n ? Pick<T, Selected> & {\n [K in keyof Expands]: Pick<\n Expands[K][\"schema\"],\n Expands[K][\"selected\"]\n >[];\n }\n : SingleMode extends \"maybe\"\n ?\n | (Pick<T, Selected> & {\n [K in keyof Expands]: Pick<\n Expands[K][\"schema\"],\n Expands[K][\"selected\"]\n >[];\n })\n | null\n : (Pick<T, Selected> & {\n [K in keyof Expands]: Pick<\n Expands[K][\"schema\"],\n Expands[K][\"selected\"]\n >[];\n })[];\n\nexport class QueryBuilder<\n T extends Record<string, any>,\n Selected extends keyof T = keyof T,\n SingleMode extends \"exact\" | \"maybe\" | false = false,\n IsCount extends boolean = false,\n Occ extends TableOccurrence<any, any, any, any> | undefined = undefined,\n Expands extends ExpandedRelations = {},\n> implements\n ExecutableBuilder<\n QueryReturnType<T, Selected, SingleMode, IsCount, Expands>\n >\n{\n private queryOptions: Partial<QueryOptions<T>> = {};\n private expandConfigs: ExpandConfig[] = [];\n private singleMode: SingleMode = false as SingleMode;\n private isCountMode = false as IsCount;\n private occurrence?: Occ;\n private tableName: string;\n private databaseName: string;\n private context: ExecutionContext;\n private isNavigate?: boolean;\n private navigateRecordId?: string | number;\n private navigateRelation?: string;\n private navigateSourceTableName?: string;\n private navigateBaseRelation?: string;\n private databaseUseEntityIds: boolean;\n\n constructor(config: {\n occurrence?: Occ;\n tableName: string;\n databaseName: string;\n context: ExecutionContext;\n databaseUseEntityIds?: boolean;\n }) {\n this.occurrence = config.occurrence;\n this.tableName = config.tableName;\n this.databaseName = config.databaseName;\n this.context = config.context;\n this.databaseUseEntityIds = config.databaseUseEntityIds ?? false;\n }\n\n /**\n * Helper to merge database-level useEntityIds with per-request options\n */\n private mergeExecuteOptions(\n options?: RequestInit & FFetchOptions & ExecuteOptions,\n ): RequestInit & FFetchOptions & { useEntityIds?: boolean } {\n // If useEntityIds is not set in options, use the database-level setting\n return {\n ...options,\n useEntityIds:\n options?.useEntityIds === undefined\n ? this.databaseUseEntityIds\n : options.useEntityIds,\n };\n }\n\n /**\n * Helper to conditionally strip OData annotations based on options\n */\n private stripODataAnnotationsIfNeeded<T extends Record<string, any>>(\n data: T,\n options?: ExecuteOptions,\n ): T {\n // Only include annotations if explicitly requested\n if (options?.includeODataAnnotations === true) {\n return data;\n }\n\n // Strip OData annotations\n const { \"@id\": _id, \"@editLink\": _editLink, ...rest } = data;\n return rest as T;\n }\n\n /**\n * Gets the table ID (FMTID) if using entity IDs, otherwise returns the table name\n * @param useEntityIds - Optional override for entity ID usage\n */\n private getTableId(useEntityIds?: boolean): string {\n if (!this.occurrence) {\n return this.tableName;\n }\n\n const contextDefault = this.context._getUseEntityIds?.() ?? false;\n const shouldUseIds = useEntityIds ?? contextDefault;\n\n if (shouldUseIds) {\n const identifiers = getTableIdentifiers(this.occurrence);\n if (!identifiers.id) {\n throw new Error(\n `useEntityIds is true but TableOccurrence \"${identifiers.name}\" does not have an fmtId defined`,\n );\n }\n return identifiers.id;\n }\n\n return this.occurrence.getTableName();\n }\n\n select<K extends keyof T>(\n ...fields: K[]\n ): QueryBuilder<T, K, SingleMode, IsCount, Occ, Expands> {\n const uniqueFields = [...new Set(fields)];\n const newBuilder = new QueryBuilder<\n T,\n K,\n SingleMode,\n IsCount,\n Occ,\n Expands\n >({\n occurrence: this.occurrence,\n tableName: this.tableName,\n databaseName: this.databaseName,\n context: this.context,\n databaseUseEntityIds: this.databaseUseEntityIds,\n });\n newBuilder.queryOptions = {\n ...this.queryOptions,\n select: uniqueFields as string[],\n };\n newBuilder.expandConfigs = [...this.expandConfigs];\n newBuilder.singleMode = this.singleMode;\n newBuilder.isCountMode = this.isCountMode;\n // Preserve navigation metadata\n newBuilder.isNavigate = this.isNavigate;\n newBuilder.navigateRecordId = this.navigateRecordId;\n newBuilder.navigateRelation = this.navigateRelation;\n newBuilder.navigateSourceTableName = this.navigateSourceTableName;\n newBuilder.navigateBaseRelation = this.navigateBaseRelation;\n return newBuilder;\n }\n\n /**\n * Transforms our filter format to odata-query's expected format\n * - Arrays of operators are converted to AND conditions\n * - Single operator objects pass through as-is\n * - Shorthand values are handled by odata-query\n */\n private transformFilter(\n filter: Filter<ExtractSchemaFromOccurrence<Occ>>,\n ): QueryOptions<T>[\"filter\"] {\n if (typeof filter === \"string\") {\n // Raw string filters pass through\n return filter;\n }\n\n if (Array.isArray(filter)) {\n // Array of filters - odata-query handles this as implicit AND\n return filter.map((f) => this.transformFilter(f as any)) as any;\n }\n\n // Check if it's a logical filter (and/or/not)\n if (\"and\" in filter || \"or\" in filter || \"not\" in filter) {\n const result: any = {};\n if (\"and\" in filter && Array.isArray(filter.and)) {\n result.and = filter.and.map((f: any) => this.transformFilter(f));\n }\n if (\"or\" in filter && Array.isArray(filter.or)) {\n result.or = filter.or.map((f: any) => this.transformFilter(f));\n }\n if (\"not\" in filter && filter.not) {\n result.not = this.transformFilter(filter.not as any);\n }\n return result;\n }\n\n // Transform field filters\n const result: any = {};\n const andConditions: any[] = [];\n\n for (const [field, value] of Object.entries(filter)) {\n // Transform field name to FMFID if using entity IDs\n const fieldId = this.occurrence?.baseTable\n ? transformFieldName(field, this.occurrence.baseTable)\n : field;\n\n if (Array.isArray(value)) {\n // Array of operators - convert to AND conditions\n if (value.length === 1) {\n // Single operator in array - unwrap it\n result[fieldId] = value[0];\n } else {\n // Multiple operators - combine with AND\n // Create separate conditions for each operator\n for (const op of value) {\n andConditions.push({ [fieldId]: op });\n }\n }\n } else if (\n value &&\n typeof value === \"object\" &&\n !(value instanceof Date) &&\n !Array.isArray(value)\n ) {\n // Check if it's an operator object (has operator keys like eq, gt, etc.)\n const operatorKeys = [\n \"eq\",\n \"ne\",\n \"gt\",\n \"ge\",\n \"lt\",\n \"le\",\n \"contains\",\n \"startswith\",\n \"endswith\",\n \"in\",\n ];\n const isOperatorObject = operatorKeys.some((key) => key in value);\n\n if (isOperatorObject) {\n // Single operator object - pass through\n result[fieldId] = value;\n } else {\n // Regular object - might be nested filter, pass through\n result[fieldId] = value;\n }\n } else {\n // Primitive value (shorthand) - pass through\n result[fieldId] = value;\n }\n }\n\n // If we have AND conditions from arrays, combine them\n if (andConditions.length > 0) {\n if (Object.keys(result).length > 0) {\n // We have both regular fields and array-derived AND conditions\n // Combine everything with AND\n return { and: [...andConditions, result] };\n } else {\n // Only array-derived AND conditions\n return { and: andConditions };\n }\n }\n\n return result;\n }\n\n filter(\n filter: Filter<ExtractSchemaFromOccurrence<Occ>>,\n ): QueryBuilder<T, Selected, SingleMode, IsCount, Occ, Expands> {\n // Transform our filter format to odata-query's expected format\n this.queryOptions.filter = this.transformFilter(filter) as any;\n return this;\n }\n\n orderBy(\n orderBy: QueryOptions<T>[\"orderBy\"],\n ): QueryBuilder<T, Selected, SingleMode, IsCount, Occ, Expands> {\n // Transform field names to FMFIDs if using entity IDs\n if (this.occurrence?.baseTable && orderBy) {\n if (Array.isArray(orderBy)) {\n this.queryOptions.orderBy = orderBy.map((field) =>\n transformOrderByField(String(field), this.occurrence!.baseTable),\n );\n } else {\n this.queryOptions.orderBy = transformOrderByField(\n String(orderBy),\n this.occurrence.baseTable,\n );\n }\n } else {\n this.queryOptions.orderBy = orderBy;\n }\n return this;\n }\n\n top(\n count: number,\n ): QueryBuilder<T, Selected, SingleMode, IsCount, Occ, Expands> {\n this.queryOptions.top = count;\n console.log(\"top method\", {\n count,\n databaseUseEntityIds: this.databaseUseEntityIds,\n });\n return this;\n }\n\n skip(\n count: number,\n ): QueryBuilder<T, Selected, SingleMode, IsCount, Occ, Expands> {\n this.queryOptions.skip = count;\n return this;\n }\n\n /**\n * Formats select fields for use in query strings.\n * - Transforms field names to FMFIDs if using entity IDs\n * - Wraps \"id\" fields in double quotes\n * - URL-encodes special characters but preserves spaces\n */\n private formatSelectFields(\n select: QueryOptions<any>[\"select\"],\n baseTable?: BaseTable<any, any, any, any>,\n ): string {\n if (!select) return \"\";\n const selectFieldsArray = Array.isArray(select) ? select : [select];\n\n // Transform to field IDs if using entity IDs\n const transformedFields = baseTable\n ? transformFieldNamesArray(\n selectFieldsArray.map((f) => String(f)),\n baseTable,\n )\n : selectFieldsArray.map((f) => String(f));\n\n return transformedFields\n .map((field) => {\n if (field === \"id\") return `\"id\"`;\n const encodedField = encodeURIComponent(String(field));\n return encodedField.replace(/%20/g, \" \");\n })\n .join(\",\");\n }\n\n /**\n * Builds expand validation configs from internal expand configurations.\n * These are used to validate expanded navigation properties.\n */\n private buildExpandValidationConfigs(\n configs: ExpandConfig[],\n ): import(\"../validation\").ExpandValidationConfig[] {\n return configs.map((config) => {\n // Look up target occurrence from navigation\n const targetOccurrence = this.occurrence?.navigation[config.relation];\n const targetSchema = targetOccurrence?.baseTable?.schema;\n\n // Extract selected fields from options\n const selectedFields = config.options?.select\n ? Array.isArray(config.options.select)\n ? config.options.select.map((f) => String(f))\n : [String(config.options.select)]\n : undefined;\n\n return {\n relation: config.relation,\n targetSchema: targetSchema,\n targetOccurrence: targetOccurrence,\n targetBaseTable: targetOccurrence?.baseTable,\n occurrence: targetOccurrence, // Add occurrence for transformation\n selectedFields: selectedFields,\n nestedExpands: undefined, // TODO: Handle nested expands if needed\n };\n });\n }\n\n /**\n * Builds OData expand query string from expand configurations.\n * Handles nested expands recursively.\n * Transforms relation names to FMTIDs if using entity IDs.\n */\n private buildExpandString(configs: ExpandConfig[]): string {\n if (configs.length === 0) {\n return \"\";\n }\n\n return configs\n .map((config) => {\n // Get target occurrence for this relation\n const targetOccurrence = this.occurrence?.navigation[config.relation];\n\n // When using entity IDs, use the target table's FMTID in the expand parameter\n // FileMaker expects FMTID in $expand when Prefer header is set\n const relationName =\n targetOccurrence && targetOccurrence.isUsingTableId()\n ? targetOccurrence.getTableId()\n : config.relation;\n\n if (!config.options || Object.keys(config.options).length === 0) {\n // Simple expand without options\n return relationName;\n }\n\n // Build query options for this expand\n const parts: string[] = [];\n\n if (config.options.select) {\n // Pass target base table for field transformation\n const selectFields = this.formatSelectFields(\n config.options.select,\n targetOccurrence?.baseTable,\n );\n parts.push(`$select=${selectFields}`);\n }\n\n if (config.options.filter) {\n // Filter should already be transformed by the nested builder\n // Use odata-query to build filter string\n const filterQuery = buildQuery({ filter: config.options.filter });\n const filterMatch = filterQuery.match(/\\$filter=([^&]+)/);\n if (filterMatch) {\n parts.push(`$filter=${filterMatch[1]}`);\n }\n }\n\n if (config.options.orderBy) {\n // OrderBy should already be transformed by the nested builder\n const orderByValue = Array.isArray(config.options.orderBy)\n ? config.options.orderBy.join(\",\")\n : config.options.orderBy;\n parts.push(`$orderby=${String(orderByValue)}`);\n }\n\n if (config.options.top !== undefined) {\n parts.push(`$top=${config.options.top}`);\n }\n\n if (config.options.skip !== undefined) {\n parts.push(`$skip=${config.options.skip}`);\n }\n\n // Handle nested expands (from expand configs)\n if (config.options.expand) {\n // If expand is a string, it's already been built\n if (typeof config.options.expand === \"string\") {\n parts.push(`$expand=${config.options.expand}`);\n }\n }\n\n if (parts.length === 0) {\n return relationName;\n }\n\n return `${relationName}(${parts.join(\";\")})`;\n })\n .join(\",\");\n }\n\n expand<\n Rel extends ExtractNavigationNames<Occ> | (string & {}),\n TargetOcc extends FindNavigationTarget<Occ, Rel> = FindNavigationTarget<\n Occ,\n Rel\n >,\n TargetSchema extends GetTargetSchemaType<Occ, Rel> = GetTargetSchemaType<\n Occ,\n Rel\n >,\n TargetSelected extends keyof TargetSchema = keyof TargetSchema,\n >(\n relation: Rel,\n callback?: (\n builder: QueryBuilder<\n TargetSchema,\n keyof TargetSchema,\n false,\n false,\n TargetOcc extends TableOccurrence<any, any, any, any>\n ? TargetOcc\n : undefined\n >,\n ) => QueryBuilder<\n WithSystemFields<TargetSchema>,\n TargetSelected,\n any,\n any,\n any\n >,\n ): QueryBuilder<\n T,\n Selected,\n SingleMode,\n IsCount,\n Occ,\n Expands & {\n [K in Rel]: { schema: TargetSchema; selected: TargetSelected };\n }\n > {\n // Look up target occurrence from navigation\n const targetOccurrence = this.occurrence?.navigation[relation as string];\n\n if (callback) {\n // Create a new QueryBuilder for the target occurrence\n const targetBuilder = new QueryBuilder<any>({\n occurrence: targetOccurrence,\n tableName: targetOccurrence?.name ?? (relation as string),\n databaseName: this.databaseName,\n context: this.context,\n databaseUseEntityIds: this.databaseUseEntityIds,\n });\n\n // Cast to the expected type for the callback\n // At runtime, the builder is untyped (any), but at compile-time we enforce proper types\n const typedBuilder = targetBuilder as QueryBuilder<\n TargetSchema,\n keyof TargetSchema,\n false,\n false,\n TargetOcc extends TableOccurrence<any, any, any, any>\n ? TargetOcc\n : undefined\n >;\n\n // Pass to callback and get configured builder\n const configuredBuilder = callback(typedBuilder);\n\n // Extract the builder's query options\n const expandOptions: Partial<QueryOptions<any>> = {\n ...configuredBuilder.queryOptions,\n };\n\n // If the configured builder has nested expands, we need to include them\n if (configuredBuilder.expandConfigs.length > 0) {\n // Build nested expand string from the configured builder's expand configs\n const nestedExpandString = this.buildExpandString(\n configuredBuilder.expandConfigs,\n );\n if (nestedExpandString) {\n // Add nested expand to options\n expandOptions.expand = nestedExpandString as any;\n }\n }\n\n const expandConfig: ExpandConfig = {\n relation: relation as string,\n options: expandOptions,\n };\n\n this.expandConfigs.push(expandConfig);\n } else {\n // Simple expand without callback\n this.expandConfigs.push({ relation: relation as string });\n }\n\n return this as any;\n }\n\n single(): QueryBuilder<T, Selected, \"exact\", IsCount, Occ, Expands> {\n const newBuilder = new QueryBuilder<\n T,\n Selected,\n \"exact\",\n IsCount,\n Occ,\n Expands\n >({\n occurrence: this.occurrence,\n tableName: this.tableName,\n databaseName: this.databaseName,\n context: this.context,\n databaseUseEntityIds: this.databaseUseEntityIds,\n });\n newBuilder.queryOptions = { ...this.queryOptions };\n newBuilder.expandConfigs = [...this.expandConfigs];\n newBuilder.singleMode = \"exact\";\n newBuilder.isCountMode = this.isCountMode;\n // Preserve navigation metadata\n newBuilder.isNavigate = this.isNavigate;\n newBuilder.navigateRecordId = this.navigateRecordId;\n newBuilder.navigateRelation = this.navigateRelation;\n newBuilder.navigateSourceTableName = this.navigateSourceTableName;\n newBuilder.navigateBaseRelation = this.navigateBaseRelation;\n return newBuilder;\n }\n\n maybeSingle(): QueryBuilder<T, Selected, \"maybe\", IsCount, Occ, Expands> {\n const newBuilder = new QueryBuilder<\n T,\n Selected,\n \"maybe\",\n IsCount,\n Occ,\n Expands\n >({\n occurrence: this.occurrence,\n tableName: this.tableName,\n databaseName: this.databaseName,\n context: this.context,\n databaseUseEntityIds: this.databaseUseEntityIds,\n });\n newBuilder.queryOptions = { ...this.queryOptions };\n newBuilder.expandConfigs = [...this.expandConfigs];\n newBuilder.singleMode = \"maybe\";\n newBuilder.isCountMode = this.isCountMode;\n // Preserve navigation metadata\n newBuilder.isNavigate = this.isNavigate;\n newBuilder.navigateRecordId = this.navigateRecordId;\n newBuilder.navigateRelation = this.navigateRelation;\n newBuilder.navigateSourceTableName = this.navigateSourceTableName;\n newBuilder.navigateBaseRelation = this.navigateBaseRelation;\n return newBuilder;\n }\n\n count(): QueryBuilder<T, Selected, SingleMode, true, Occ, Expands> {\n const newBuilder = new QueryBuilder<\n T,\n Selected,\n SingleMode,\n true,\n Occ,\n Expands\n >({\n occurrence: this.occurrence,\n tableName: this.tableName,\n databaseName: this.databaseName,\n context: this.context,\n databaseUseEntityIds: this.databaseUseEntityIds,\n });\n newBuilder.queryOptions = { ...this.queryOptions, count: true };\n newBuilder.expandConfigs = [...this.expandConfigs];\n newBuilder.singleMode = this.singleMode;\n newBuilder.isCountMode = true as true;\n // Preserve navigation metadata\n newBuilder.isNavigate = this.isNavigate;\n newBuilder.navigateRecordId = this.navigateRecordId;\n newBuilder.navigateRelation = this.navigateRelation;\n newBuilder.navigateSourceTableName = this.navigateSourceTableName;\n newBuilder.navigateBaseRelation = this.navigateBaseRelation;\n return newBuilder;\n }\n\n async execute<EO extends ExecuteOptions>(\n options?: RequestInit & FFetchOptions & EO,\n ): Promise<\n Result<\n IsCount extends true\n ? number\n : SingleMode extends \"exact\"\n ? ConditionallyWithODataAnnotations<\n Pick<T, Selected> & {\n [K in keyof Expands]: Pick<\n Expands[K][\"schema\"],\n Expands[K][\"selected\"]\n >[];\n },\n EO[\"includeODataAnnotations\"] extends true ? true : false\n >\n : SingleMode extends \"maybe\"\n ? ConditionallyWithODataAnnotations<\n Pick<T, Selected> & {\n [K in keyof Expands]: Pick<\n Expands[K][\"schema\"],\n Expands[K][\"selected\"]\n >[];\n },\n EO[\"includeODataAnnotations\"] extends true ? true : false\n > | null\n : ConditionallyWithODataAnnotations<\n Pick<T, Selected> & {\n [K in keyof Expands]: Pick<\n Expands[K][\"schema\"],\n Expands[K][\"selected\"]\n >[];\n },\n EO[\"includeODataAnnotations\"] extends true ? true : false\n >[]\n >\n > {\n // Build query without expand (we'll add it manually)\n const queryOptionsWithoutExpand = { ...this.queryOptions };\n delete queryOptionsWithoutExpand.expand;\n\n const mergedOptions = this.mergeExecuteOptions(options);\n\n // Format select fields before building query\n if (queryOptionsWithoutExpand.select) {\n queryOptionsWithoutExpand.select = this.formatSelectFields(\n queryOptionsWithoutExpand.select,\n this.occurrence?.baseTable,\n ) as any;\n }\n\n let queryString = buildQuery(queryOptionsWithoutExpand);\n\n // Build custom expand string\n const expandString = this.buildExpandString(this.expandConfigs);\n if (expandString) {\n const separator = queryString.includes(\"?\") ? \"&\" : \"?\";\n queryString = `${queryString}${separator}$expand=${expandString}`;\n }\n\n // Handle navigation from RecordBuilder\n if (\n this.isNavigate &&\n this.navigateRecordId &&\n this.navigateRelation &&\n this.navigateSourceTableName\n ) {\n let url: string;\n if (this.navigateBaseRelation) {\n // Navigation from a navigated EntitySet: /sourceTable/baseRelation('recordId')/relation\n url = `/${this.databaseName}/${this.navigateSourceTableName}/${this.navigateBaseRelation}('${this.navigateRecordId}')/${this.navigateRelation}${queryString}`;\n } else {\n // Normal navigation: /sourceTable('recordId')/relation\n url = `/${this.databaseName}/${this.navigateSourceTableName}('${this.navigateRecordId}')/${this.navigateRelation}${queryString}`;\n }\n const result = await this.context._makeRequest(url, mergedOptions);\n\n if (result.error) {\n return { data: undefined, error: result.error };\n }\n\n let response = result.data;\n\n // Transform response field IDs back to names if using entity IDs\n // Only transform if useEntityIds resolves to true (respects per-request override)\n const shouldUseIds = mergedOptions.useEntityIds ?? false;\n\n if (this.occurrence?.baseTable && shouldUseIds) {\n const expandValidationConfigs = this.buildExpandValidationConfigs(\n this.expandConfigs,\n );\n response = transformResponseFields(\n response,\n this.occurrence.baseTable,\n expandValidationConfigs,\n );\n }\n\n // Skip validation if requested\n if (options?.skipValidation === true) {\n const resp = response as any;\n if (this.singleMode !== false) {\n const records = resp.value ?? [resp];\n const count = Array.isArray(records) ? records.length : 1;\n\n if (count > 1) {\n return {\n data: undefined,\n error: new RecordCountMismatchError(\n this.singleMode === \"exact\" ? \"one\" : \"at-most-one\",\n count,\n ),\n };\n }\n\n if (count === 0) {\n if (this.singleMode === \"exact\") {\n return {\n data: undefined,\n error: new RecordCountMismatchError(\"one\", 0),\n };\n }\n return { data: null as any, error: undefined };\n }\n\n const record = Array.isArray(records) ? records[0] : records;\n const stripped = this.stripODataAnnotationsIfNeeded(record, options);\n return { data: stripped as any, error: undefined };\n } else {\n const records = resp.value ?? [];\n const stripped = records.map((record: any) =>\n this.stripODataAnnotationsIfNeeded(record, options),\n );\n return { data: stripped as any, error: undefined };\n }\n }\n\n // Get schema from occurrence if available\n const schema = this.occurrence?.baseTable?.schema;\n const selectedFields = this.queryOptions.select as\n | (keyof T)[]\n | undefined;\n const expandValidationConfigs = this.buildExpandValidationConfigs(\n this.expandConfigs,\n );\n\n if (this.singleMode !== false) {\n const validation = await validateSingleResponse<T>(\n response,\n schema,\n selectedFields,\n expandValidationConfigs,\n this.singleMode,\n );\n if (!validation.valid) {\n return { data: undefined, error: validation.error };\n }\n const stripped = validation.data\n ? this.stripODataAnnotationsIfNeeded(validation.data, options)\n : null;\n return { data: stripped as any, error: undefined };\n } else {\n const validation = await validateListResponse<T>(\n response,\n schema,\n selectedFields,\n expandValidationConfigs,\n );\n if (!validation.valid) {\n return { data: undefined, error: validation.error };\n }\n const stripped = validation.data.map((record) =>\n this.stripODataAnnotationsIfNeeded(record, options),\n );\n return { data: stripped as any, error: undefined };\n }\n }\n\n // Handle navigation from EntitySet (without record ID)\n if (\n this.isNavigate &&\n !this.navigateRecordId &&\n this.navigateRelation &&\n this.navigateSourceTableName\n ) {\n const result = await this.context._makeRequest(\n `/${this.databaseName}/${this.navigateSourceTableName}/${this.navigateRelation}${queryString}`,\n mergedOptions,\n );\n\n if (result.error) {\n return { data: undefined, error: result.error };\n }\n\n let response = result.data;\n\n // Transform response field IDs back to names if using entity IDs\n // Only transform if useEntityIds resolves to true (respects per-request override)\n const shouldUseIds = mergedOptions.useEntityIds ?? false;\n\n if (this.occurrence?.baseTable && shouldUseIds) {\n const expandValidationConfigs = this.buildExpandValidationConfigs(\n this.expandConfigs,\n );\n response = transformResponseFields(\n response,\n this.occurrence.baseTable,\n expandValidationConfigs,\n );\n }\n\n // Skip validation if requested\n if (options?.skipValidation === true) {\n const resp = response as any;\n if (this.singleMode !== false) {\n const records = resp.value ?? [resp];\n const count = Array.isArray(records) ? records.length : 1;\n\n if (count > 1) {\n return {\n data: undefined,\n error: new RecordCountMismatchError(\n this.singleMode === \"exact\" ? \"one\" : \"at-most-one\",\n count,\n ),\n };\n }\n\n if (count === 0) {\n if (this.singleMode === \"exact\") {\n return {\n data: undefined,\n error: new RecordCountMismatchError(\"one\", 0),\n };\n }\n return { data: null as any, error: undefined };\n }\n\n const record = Array.isArray(records) ? records[0] : records;\n const stripped = this.stripODataAnnotationsIfNeeded(record, options);\n return { data: stripped as any, error: undefined };\n } else {\n const records = resp.value ?? [];\n const stripped = records.map((record: any) =>\n this.stripODataAnnotationsIfNeeded(record, options),\n );\n return { data: stripped as any, error: undefined };\n }\n }\n\n // Get schema from occurrence if available\n const schema = this.occurrence?.baseTable?.schema;\n const selectedFields = this.queryOptions.select as\n | (keyof T)[]\n | undefined;\n const expandValidationConfigs = this.buildExpandValidationConfigs(\n this.expandConfigs,\n );\n\n if (this.singleMode !== false) {\n const validation = await validateSingleResponse<T>(\n response,\n schema,\n selectedFields,\n expandValidationConfigs,\n this.singleMode,\n );\n if (!validation.valid) {\n return { data: undefined, error: validation.error };\n }\n const stripped = validation.data\n ? this.stripODataAnnotationsIfNeeded(validation.data, options)\n : null;\n return { data: stripped as any, error: undefined };\n } else {\n const validation = await validateListResponse<T>(\n response,\n schema,\n selectedFields,\n expandValidationConfigs,\n );\n if (!validation.valid) {\n return { data: undefined, error: validation.error };\n }\n const stripped = validation.data.map((record) =>\n this.stripODataAnnotationsIfNeeded(record, options),\n );\n return { data: stripped as any, error: undefined };\n }\n }\n\n // Handle $count endpoint\n if (this.isCountMode) {\n const tableId = this.getTableId(mergedOptions.useEntityIds);\n const result = await this.context._makeRequest(\n `/${this.databaseName}/${tableId}/$count${queryString}`,\n mergedOptions,\n );\n\n if (result.error) {\n return { data: undefined, error: result.error };\n }\n\n // OData returns count as a string, convert to number\n const count =\n typeof result.data === \"string\" ? Number(result.data) : result.data;\n return { data: count as number, error: undefined } as any;\n }\n\n const tableId = this.getTableId(mergedOptions.useEntityIds);\n const result = await this.context._makeRequest(\n `/${this.databaseName}/${tableId}${queryString}`,\n mergedOptions,\n );\n\n if (result.error) {\n return { data: undefined, error: result.error };\n }\n\n let response = result.data;\n\n // Transform response field IDs back to names if using entity IDs\n // Only transform if useEntityIds resolves to true (respects per-request override)\n const shouldUseIds = mergedOptions.useEntityIds ?? false;\n\n if (this.occurrence?.baseTable && shouldUseIds) {\n const expandValidationConfigs = this.buildExpandValidationConfigs(\n this.expandConfigs,\n );\n response = transformResponseFields(\n response,\n this.occurrence.baseTable,\n expandValidationConfigs,\n );\n }\n\n // Skip validation if requested\n if (options?.skipValidation === true) {\n const resp = response as any;\n if (this.singleMode !== false) {\n const records = resp.value ?? [resp];\n const count = Array.isArray(records) ? records.length : 1;\n\n if (count > 1) {\n return {\n data: undefined,\n error: new RecordCountMismatchError(\n this.singleMode === \"exact\" ? \"one\" : \"at-most-one\",\n count,\n ),\n };\n }\n\n if (count === 0) {\n if (this.singleMode === \"exact\") {\n return {\n data: undefined,\n error: new RecordCountMismatchError(\"one\", 0),\n };\n }\n return { data: null as any, error: undefined };\n }\n\n const record = Array.isArray(records) ? records[0] : records;\n const stripped = this.stripODataAnnotationsIfNeeded(record, options);\n return { data: stripped as any, error: undefined };\n } else {\n // Handle list response structure\n const records = resp.value ?? [];\n const stripped = records.map((record: any) =>\n this.stripODataAnnotationsIfNeeded(record, options),\n );\n return { data: stripped as any, error: undefined };\n }\n }\n\n // Get schema from occurrence if available\n const schema = this.occurrence?.baseTable?.schema;\n const selectedFields = this.queryOptions.select as (keyof T)[] | undefined;\n const expandValidationConfigs = this.buildExpandValidationConfigs(\n this.expandConfigs,\n );\n\n if (this.singleMode !== false) {\n const validation = await validateSingleResponse<T>(\n response,\n schema,\n selectedFields,\n expandValidationConfigs,\n this.singleMode,\n );\n if (!validation.valid) {\n return { data: undefined, error: validation.error };\n }\n const stripped = validation.data\n ? this.stripODataAnnotationsIfNeeded(validation.data, options)\n : null;\n return {\n data: stripped as any,\n error: undefined,\n };\n } else {\n const validation = await validateListResponse<T>(\n response,\n schema,\n selectedFields,\n expandValidationConfigs,\n );\n if (!validation.valid) {\n return { data: undefined, error: validation.error };\n }\n const stripped = validation.data.map((record) =>\n this.stripODataAnnotationsIfNeeded(record, options),\n );\n return {\n data: stripped as any,\n error: undefined,\n };\n }\n }\n\n getQueryString(): string {\n // Build query without expand (we'll add it manually)\n const queryOptionsWithoutExpand = { ...this.queryOptions };\n delete queryOptionsWithoutExpand.expand;\n\n // Format select fields before building query - buildQuery treats & as separator,\n // so we need to pre-encode special characters. buildQuery preserves encoded values.\n if (queryOptionsWithoutExpand.select) {\n queryOptionsWithoutExpand.select = this.formatSelectFields(\n queryOptionsWithoutExpand.select,\n ) as any;\n }\n\n let queryParams = buildQuery(queryOptionsWithoutExpand);\n\n // Post-process: buildQuery encodes spaces as %20, but we want to preserve spaces\n // Replace %20 with spaces in the $select part\n if (this.queryOptions.select) {\n queryParams = queryParams.replace(\n /\\$select=([^&]*)/,\n (match, selectValue) => {\n return `$select=${selectValue.replace(/%20/g, \" \")}`;\n },\n );\n }\n const expandString = this.buildExpandString(this.expandConfigs);\n if (expandString) {\n const separator = queryParams.includes(\"?\") ? \"&\" : \"?\";\n queryParams = `${queryParams}${separator}$expand=${expandString}`;\n }\n\n // Handle navigation from RecordBuilder (with record ID)\n if (\n this.isNavigate &&\n this.navigateRecordId &&\n this.navigateRelation &&\n this.navigateSourceTableName\n ) {\n let path: string;\n if (this.navigateBaseRelation) {\n // Navigation from a navigated EntitySet: /sourceTable/baseRelation('recordId')/relation\n path = `/${this.navigateSourceTableName}/${this.navigateBaseRelation}('${this.navigateRecordId}')/${this.navigateRelation}`;\n } else {\n // Normal navigation: /sourceTableName('recordId')/relationName\n path = `/${this.navigateSourceTableName}('${this.navigateRecordId}')/${this.navigateRelation}`;\n }\n // Append query params if any exist\n return queryParams ? `${path}${queryParams}` : path;\n }\n\n // Handle navigation from EntitySet (without record ID)\n if (\n this.isNavigate &&\n !this.navigateRecordId &&\n this.navigateRelation &&\n this.navigateSourceTableName\n ) {\n // Return the path portion: /sourceTableName/relationName\n const path = `/${this.navigateSourceTableName}/${this.navigateRelation}`;\n // Append query params if any exist\n return queryParams ? `${path}${queryParams}` : path;\n }\n\n // Default case: return table name with query params\n return `/${this.tableName}${queryParams}`;\n }\n\n getRequestConfig(): { method: string; url: string; body?: any } {\n // Build query without expand (we'll add it manually)\n const queryOptionsWithoutExpand = { ...this.queryOptions };\n delete queryOptionsWithoutExpand.expand;\n\n // Format select fields before building query\n if (queryOptionsWithoutExpand.select) {\n queryOptionsWithoutExpand.select = this.formatSelectFields(\n queryOptionsWithoutExpand.select,\n ) as any;\n }\n\n let queryString = buildQuery(queryOptionsWithoutExpand);\n\n // Build custom expand string\n const expandString = this.buildExpandString(this.expandConfigs);\n if (expandString) {\n const separator = queryString.includes(\"?\") ? \"&\" : \"?\";\n queryString = `${queryString}${separator}$expand=${expandString}`;\n }\n\n let url: string;\n\n // Handle navigation from RecordBuilder (with record ID)\n if (\n this.isNavigate &&\n this.navigateRecordId &&\n this.navigateRelation &&\n this.navigateSourceTableName\n ) {\n if (this.navigateBaseRelation) {\n // Navigation from a navigated EntitySet: /sourceTable/baseRelation('recordId')/relation\n url = `/${this.databaseName}/${this.navigateSourceTableName}/${this.navigateBaseRelation}('${this.navigateRecordId}')/${this.navigateRelation}${queryString}`;\n } else {\n // Normal navigation: /sourceTable('recordId')/relation\n url = `/${this.databaseName}/${this.navigateSourceTableName}('${this.navigateRecordId}')/${this.navigateRelation}${queryString}`;\n }\n } else if (\n this.isNavigate &&\n !this.navigateRecordId &&\n this.navigateRelation &&\n this.navigateSourceTableName\n ) {\n // Handle navigation from EntitySet (without record ID)\n url = `/${this.databaseName}/${this.navigateSourceTableName}/${this.navigateRelation}${queryString}`;\n } else if (this.isCountMode) {\n url = `/${this.databaseName}/${this.tableName}/$count${queryString}`;\n } else {\n url = `/${this.databaseName}/${this.tableName}${queryString}`;\n }\n\n return {\n method: \"GET\",\n url,\n };\n }\n\n toRequest(baseUrl: string): Request {\n const config = this.getRequestConfig();\n const fullUrl = `${baseUrl}${config.url}`;\n\n return new Request(fullUrl, {\n method: config.method,\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n });\n }\n\n async processResponse(\n response: Response,\n options?: ExecuteOptions,\n ): Promise<\n Result<QueryReturnType<T, Selected, SingleMode, IsCount, Expands>>\n > {\n // Handle 204 No Content (shouldn't happen for queries, but handle it gracefully)\n if (response.status === 204) {\n // Return empty list for list queries, null for single queries\n if (this.singleMode !== false) {\n if (this.singleMode === \"maybe\") {\n return { data: null as any, error: undefined };\n }\n return {\n data: undefined,\n error: new RecordCountMismatchError(\"one\", 0),\n };\n }\n return { data: [] as any, error: undefined };\n }\n\n // Parse the response body\n let rawData;\n try {\n rawData = await response.json();\n } catch (err) {\n // Check if it's an empty body error (common with 204 responses)\n if (err instanceof SyntaxError && response.status === 204) {\n // Handled above, but just in case\n return { data: [] as any, error: undefined };\n }\n return {\n data: undefined,\n error: {\n name: \"ResponseParseError\",\n message: `Failed to parse response JSON: ${err instanceof Error ? err.message : \"Unknown error\"}`,\n timestamp: new Date(),\n } as any,\n };\n }\n\n if (!rawData) {\n return {\n data: undefined,\n error: {\n name: \"ResponseError\",\n message: \"Response body was empty or null\",\n timestamp: new Date(),\n } as any,\n };\n }\n\n // Transform response field IDs back to names if using entity IDs\n // Only transform if useEntityIds resolves to true (respects per-request override)\n const shouldUseIds = options?.useEntityIds ?? this.databaseUseEntityIds;\n\n let transformedData = rawData;\n if (this.occurrence?.baseTable && shouldUseIds) {\n const expandValidationConfigs = this.buildExpandValidationConfigs(\n this.expandConfigs,\n );\n transformedData = transformResponseFields(\n rawData,\n this.occurrence.baseTable,\n expandValidationConfigs,\n );\n }\n\n // Skip validation if requested\n if (options?.skipValidation === true) {\n const resp = transformedData as any;\n if (this.singleMode !== false) {\n const records = resp.value ?? [resp];\n const count = Array.isArray(records) ? records.length : 1;\n\n if (count > 1) {\n return {\n data: undefined,\n error: new RecordCountMismatchError(\n this.singleMode === \"exact\" ? \"one\" : \"at-most-one\",\n count,\n ),\n };\n }\n\n if (count === 0) {\n if (this.singleMode === \"exact\") {\n return {\n data: undefined,\n error: new RecordCountMismatchError(\"one\", 0),\n };\n }\n return { data: null as any, error: undefined };\n }\n\n const record = Array.isArray(records) ? records[0] : records;\n const stripped = this.stripODataAnnotationsIfNeeded(record, options);\n return { data: stripped as any, error: undefined };\n } else {\n // Handle list response structure\n const records = resp.value ?? [];\n const stripped = records.map((record: any) =>\n this.stripODataAnnotationsIfNeeded(record, options),\n );\n return { data: stripped as any, error: undefined };\n }\n }\n\n // Get schema from occurrence if available\n const schema = this.occurrence?.baseTable?.schema;\n const selectedFields = this.queryOptions.select as (keyof T)[] | undefined;\n const expandValidationConfigs = this.buildExpandValidationConfigs(\n this.expandConfigs,\n );\n\n if (this.singleMode !== false) {\n // Single mode (one() or oneOrNull())\n const validation = await validateSingleResponse<T>(\n transformedData,\n schema,\n selectedFields,\n expandValidationConfigs,\n this.singleMode,\n );\n\n if (!validation.valid) {\n return { data: undefined, error: validation.error };\n }\n\n if (validation.data === null) {\n return { data: null as any, error: undefined };\n }\n\n const stripped = this.stripODataAnnotationsIfNeeded(\n validation.data,\n options,\n );\n return { data: stripped as any, error: undefined };\n }\n\n // List mode\n const validation = await validateListResponse<T>(\n transformedData,\n schema,\n selectedFields,\n expandValidationConfigs,\n );\n\n if (!validation.valid) {\n return { data: undefined, error: validation.error };\n }\n\n const stripped = validation.data.map((record) =>\n this.stripODataAnnotationsIfNeeded(record, options),\n );\n return { data: stripped as any, error: undefined };\n }\n}\n"],"names":["result","response","shouldUseIds","expandValidationConfigs","schema","selectedFields","tableId","stripped","validation"],"mappings":"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"}