@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.
- package/README.md +333 -3
- package/dist/esm/client/batch-builder.d.ts +54 -0
- package/dist/esm/client/batch-builder.js +179 -0
- package/dist/esm/client/batch-builder.js.map +1 -0
- package/dist/esm/client/batch-request.d.ts +61 -0
- package/dist/esm/client/batch-request.js +252 -0
- package/dist/esm/client/batch-request.js.map +1 -0
- package/dist/esm/client/database.d.ts +43 -11
- package/dist/esm/client/database.js +64 -10
- package/dist/esm/client/database.js.map +1 -1
- package/dist/esm/client/delete-builder.d.ts +21 -2
- package/dist/esm/client/delete-builder.js +76 -9
- package/dist/esm/client/delete-builder.js.map +1 -1
- package/dist/esm/client/entity-set.d.ts +15 -4
- package/dist/esm/client/entity-set.js +23 -7
- package/dist/esm/client/entity-set.js.map +1 -1
- package/dist/esm/client/filemaker-odata.d.ts +11 -5
- package/dist/esm/client/filemaker-odata.js +46 -14
- package/dist/esm/client/filemaker-odata.js.map +1 -1
- package/dist/esm/client/insert-builder.d.ts +38 -3
- package/dist/esm/client/insert-builder.js +195 -9
- package/dist/esm/client/insert-builder.js.map +1 -1
- package/dist/esm/client/query-builder.d.ts +19 -3
- package/dist/esm/client/query-builder.js +193 -17
- package/dist/esm/client/query-builder.js.map +1 -1
- package/dist/esm/client/record-builder.d.ts +17 -2
- package/dist/esm/client/record-builder.js +87 -5
- package/dist/esm/client/record-builder.js.map +1 -1
- package/dist/esm/client/response-processor.d.ts +38 -0
- package/dist/esm/client/schema-manager.d.ts +57 -0
- package/dist/esm/client/schema-manager.js +132 -0
- package/dist/esm/client/schema-manager.js.map +1 -0
- package/dist/esm/client/update-builder.d.ts +34 -11
- package/dist/esm/client/update-builder.js +119 -19
- package/dist/esm/client/update-builder.js.map +1 -1
- package/dist/esm/errors.d.ts +14 -1
- package/dist/esm/errors.js +26 -0
- package/dist/esm/errors.js.map +1 -1
- package/dist/esm/index.d.ts +3 -2
- package/dist/esm/index.js +3 -1
- package/dist/esm/transform.d.ts +9 -0
- package/dist/esm/transform.js +7 -0
- package/dist/esm/transform.js.map +1 -1
- package/dist/esm/types.d.ts +69 -1
- package/package.json +1 -1
- package/src/client/batch-builder.ts +265 -0
- package/src/client/batch-request.ts +485 -0
- package/src/client/database.ts +106 -52
- package/src/client/delete-builder.ts +116 -14
- package/src/client/entity-set.ts +80 -6
- package/src/client/filemaker-odata.ts +65 -19
- package/src/client/insert-builder.ts +296 -18
- package/src/client/query-builder.ts +278 -17
- package/src/client/record-builder.ts +119 -11
- package/src/client/response-processor.ts +103 -0
- package/src/client/schema-manager.ts +246 -0
- package/src/client/update-builder.ts +195 -37
- package/src/errors.ts +33 -1
- package/src/index.ts +13 -0
- package/src/transform.ts +19 -6
- 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 {
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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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"}
|