@proofkit/fmodata 0.1.0-alpha.1 → 0.1.0-alpha.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/README.md +760 -69
  2. package/dist/esm/client/base-table.d.ts +120 -5
  3. package/dist/esm/client/base-table.js +43 -5
  4. package/dist/esm/client/base-table.js.map +1 -1
  5. package/dist/esm/client/batch-builder.d.ts +54 -0
  6. package/dist/esm/client/batch-builder.js +179 -0
  7. package/dist/esm/client/batch-builder.js.map +1 -0
  8. package/dist/esm/client/batch-request.d.ts +61 -0
  9. package/dist/esm/client/batch-request.js +252 -0
  10. package/dist/esm/client/batch-request.js.map +1 -0
  11. package/dist/esm/client/build-occurrences.d.ts +74 -0
  12. package/dist/esm/client/build-occurrences.js +31 -0
  13. package/dist/esm/client/build-occurrences.js.map +1 -0
  14. package/dist/esm/client/database.d.ts +55 -6
  15. package/dist/esm/client/database.js +118 -15
  16. package/dist/esm/client/database.js.map +1 -1
  17. package/dist/esm/client/delete-builder.d.ts +21 -2
  18. package/dist/esm/client/delete-builder.js +96 -32
  19. package/dist/esm/client/delete-builder.js.map +1 -1
  20. package/dist/esm/client/entity-set.d.ts +26 -12
  21. package/dist/esm/client/entity-set.js +43 -12
  22. package/dist/esm/client/entity-set.js.map +1 -1
  23. package/dist/esm/client/filemaker-odata.d.ts +23 -4
  24. package/dist/esm/client/filemaker-odata.js +124 -29
  25. package/dist/esm/client/filemaker-odata.js.map +1 -1
  26. package/dist/esm/client/insert-builder.d.ts +38 -3
  27. package/dist/esm/client/insert-builder.js +231 -34
  28. package/dist/esm/client/insert-builder.js.map +1 -1
  29. package/dist/esm/client/query-builder.d.ts +28 -7
  30. package/dist/esm/client/query-builder.js +470 -212
  31. package/dist/esm/client/query-builder.js.map +1 -1
  32. package/dist/esm/client/record-builder.d.ts +96 -10
  33. package/dist/esm/client/record-builder.js +378 -39
  34. package/dist/esm/client/record-builder.js.map +1 -1
  35. package/dist/esm/client/response-processor.d.ts +38 -0
  36. package/dist/esm/client/schema-manager.d.ts +57 -0
  37. package/dist/esm/client/schema-manager.js +132 -0
  38. package/dist/esm/client/schema-manager.js.map +1 -0
  39. package/dist/esm/client/table-occurrence.d.ts +69 -8
  40. package/dist/esm/client/table-occurrence.js +35 -24
  41. package/dist/esm/client/table-occurrence.js.map +1 -1
  42. package/dist/esm/client/update-builder.d.ts +34 -11
  43. package/dist/esm/client/update-builder.js +135 -31
  44. package/dist/esm/client/update-builder.js.map +1 -1
  45. package/dist/esm/errors.d.ts +73 -0
  46. package/dist/esm/errors.js +148 -0
  47. package/dist/esm/errors.js.map +1 -0
  48. package/dist/esm/index.d.ts +13 -3
  49. package/dist/esm/index.js +29 -7
  50. package/dist/esm/index.js.map +1 -1
  51. package/dist/esm/transform.d.ts +65 -0
  52. package/dist/esm/transform.js +114 -0
  53. package/dist/esm/transform.js.map +1 -0
  54. package/dist/esm/types.d.ts +89 -5
  55. package/dist/esm/validation.d.ts +6 -3
  56. package/dist/esm/validation.js +104 -33
  57. package/dist/esm/validation.js.map +1 -1
  58. package/package.json +10 -1
  59. package/src/client/base-table.ts +161 -8
  60. package/src/client/batch-builder.ts +265 -0
  61. package/src/client/batch-request.ts +485 -0
  62. package/src/client/build-occurrences.ts +155 -0
  63. package/src/client/database.ts +175 -18
  64. package/src/client/delete-builder.ts +149 -48
  65. package/src/client/entity-set.ts +134 -28
  66. package/src/client/filemaker-odata.ts +179 -35
  67. package/src/client/insert-builder.ts +350 -40
  68. package/src/client/query-builder.ts +632 -244
  69. package/src/client/query-builder.ts.bak +1457 -0
  70. package/src/client/record-builder.ts +692 -68
  71. package/src/client/response-processor.ts +103 -0
  72. package/src/client/schema-manager.ts +246 -0
  73. package/src/client/table-occurrence.ts +107 -51
  74. package/src/client/update-builder.ts +235 -49
  75. package/src/errors.ts +217 -0
  76. package/src/index.ts +63 -6
  77. package/src/transform.ts +249 -0
  78. package/src/types.ts +201 -35
  79. package/src/validation.ts +120 -36
package/src/index.ts CHANGED
@@ -1,10 +1,38 @@
1
1
  // Barrel file - exports all public API from the client folder
2
- export { BaseTable } from "./client/base-table";
3
- export {
4
- TableOccurrence,
5
- createTableOccurrence,
6
- } from "./client/table-occurrence";
7
- export { FileMakerOData } from "./client/filemaker-odata";
2
+
3
+ // Main API - use these functions to create tables and occurrences
4
+ export { defineBaseTable } from "./client/base-table";
5
+ export { defineTableOccurrence } from "./client/table-occurrence";
6
+ export { buildOccurrences } from "./client/build-occurrences";
7
+ export { FMServerConnection } from "./client/filemaker-odata";
8
+
9
+ // Type-only exports - for type annotations only, not direct instantiation
10
+ export type { BaseTable } from "./client/base-table";
11
+ export type { TableOccurrence } from "./client/table-occurrence";
12
+ export type { Database } from "./client/database";
13
+ export type { EntitySet } from "./client/entity-set";
14
+ export type {
15
+ SchemaManager,
16
+ Field,
17
+ StringField,
18
+ NumericField,
19
+ DateField,
20
+ TimeField,
21
+ TimestampField,
22
+ ContainerField,
23
+ } from "./client/schema-manager";
24
+
25
+ // Utility types for type annotations
26
+ export type {
27
+ Result,
28
+ InferSchemaType,
29
+ InsertData,
30
+ UpdateData,
31
+ ODataRecordMetadata,
32
+ Metadata,
33
+ } from "./types";
34
+
35
+ // Filter types
8
36
  export type {
9
37
  Filter,
10
38
  TypedFilter,
@@ -15,3 +43,32 @@ export type {
15
43
  DateOperators,
16
44
  LogicalFilter,
17
45
  } from "./filter-types";
46
+
47
+ // Re-export ffetch errors
48
+ export {
49
+ TimeoutError,
50
+ AbortError,
51
+ NetworkError,
52
+ RetryLimitError,
53
+ CircuitOpenError,
54
+ } from "@fetchkit/ffetch";
55
+
56
+ // Export our errors
57
+ export {
58
+ FMODataError,
59
+ HTTPError,
60
+ ODataError,
61
+ SchemaLockedError,
62
+ ValidationError,
63
+ ResponseStructureError,
64
+ RecordCountMismatchError,
65
+ isHTTPError,
66
+ isValidationError,
67
+ isODataError,
68
+ isSchemaLockedError,
69
+ isResponseStructureError,
70
+ isRecordCountMismatchError,
71
+ isFMODataError,
72
+ } from "./errors";
73
+
74
+ export type { FMODataErrorType } from "./errors";
@@ -0,0 +1,249 @@
1
+ import type { BaseTable } from "./client/base-table";
2
+ import type { TableOccurrence } from "./client/table-occurrence";
3
+ import type { StandardSchemaV1 } from "@standard-schema/spec";
4
+
5
+ /**
6
+ * Transforms field names to FileMaker field IDs (FMFID) in an object
7
+ * @param data - Object with field names as keys
8
+ * @param baseTable - BaseTable instance to get field IDs from
9
+ * @returns Object with FMFID keys instead of field names
10
+ */
11
+ export function transformFieldNamesToIds<T extends Record<string, any>>(
12
+ data: T,
13
+ baseTable: BaseTable<any, any, any, any>,
14
+ ): Record<string, any> {
15
+ if (!baseTable.isUsingFieldIds()) {
16
+ return data;
17
+ }
18
+
19
+ const transformed: Record<string, any> = {};
20
+ for (const [fieldName, value] of Object.entries(data)) {
21
+ const fieldId = baseTable.getFieldId(fieldName as any);
22
+ transformed[fieldId] = value;
23
+ }
24
+ return transformed;
25
+ }
26
+
27
+ /**
28
+ * Transforms FileMaker field IDs (FMFID) to field names in an object
29
+ * @param data - Object with FMFID keys
30
+ * @param baseTable - BaseTable instance to get field names from
31
+ * @returns Object with field names as keys instead of FMFIDs
32
+ */
33
+ export function transformFieldIdsToNames<T extends Record<string, any>>(
34
+ data: T,
35
+ baseTable: BaseTable<any, any, any, any>,
36
+ ): Record<string, any> {
37
+ if (!baseTable.isUsingFieldIds()) {
38
+ return data;
39
+ }
40
+
41
+ const transformed: Record<string, any> = {};
42
+ for (const [key, value] of Object.entries(data)) {
43
+ // Check if this is an OData metadata field (starts with @)
44
+ if (key.startsWith("@")) {
45
+ transformed[key] = value;
46
+ continue;
47
+ }
48
+
49
+ const fieldName = baseTable.getFieldName(key);
50
+ transformed[fieldName] = value;
51
+ }
52
+ return transformed;
53
+ }
54
+
55
+ /**
56
+ * Transforms a field name to FMFID or returns the field name if not using IDs
57
+ * @param fieldName - The field name to transform
58
+ * @param baseTable - BaseTable instance to get field ID from
59
+ * @returns The FMFID or field name
60
+ */
61
+ export function transformFieldName(
62
+ fieldName: string,
63
+ baseTable: BaseTable<any, any, any, any>,
64
+ ): string {
65
+ return baseTable.getFieldId(fieldName as any);
66
+ }
67
+
68
+ /**
69
+ * Transforms a table occurrence name to FMTID or returns the name if not using IDs
70
+ * @param occurrence - TableOccurrence instance to get table ID from
71
+ * @returns The FMTID or table name
72
+ */
73
+ export function transformTableName(
74
+ occurrence: TableOccurrence<any, any, any, any>,
75
+ ): string {
76
+ return occurrence.getTableId();
77
+ }
78
+
79
+ /**
80
+ * Gets both table name and ID from an occurrence
81
+ * @param occurrence - TableOccurrence instance
82
+ * @returns Object with name (always present) and id (may be undefined if not using IDs)
83
+ */
84
+ export function getTableIdentifiers(
85
+ occurrence: TableOccurrence<any, any, any, any>,
86
+ ): { name: string; id: string | undefined } {
87
+ return {
88
+ name: occurrence.getTableName(),
89
+ id: occurrence.isUsingTableId() ? occurrence.getTableId() : undefined,
90
+ };
91
+ }
92
+
93
+ /**
94
+ * Transforms response data by converting field IDs back to field names recursively.
95
+ * Handles both single records and arrays of records, as well as nested expand relationships.
96
+ *
97
+ * @param data - Response data from FileMaker (can be single record, array, or wrapped in value property)
98
+ * @param baseTable - BaseTable instance for the main table
99
+ * @param expandConfigs - Configuration for expanded relations (optional)
100
+ * @returns Transformed data with field names instead of IDs
101
+ */
102
+ export function transformResponseFields(
103
+ data: any,
104
+ baseTable: BaseTable<any, any, any, any>,
105
+ expandConfigs?: Array<{
106
+ relation: string;
107
+ occurrence?: TableOccurrence<any, any, any, any>;
108
+ }>,
109
+ ): any {
110
+ if (!baseTable.isUsingFieldIds()) {
111
+ return data;
112
+ }
113
+
114
+ // Handle null/undefined
115
+ if (data === null || data === undefined) {
116
+ return data;
117
+ }
118
+
119
+ // Handle OData list response with value array
120
+ if (data.value && Array.isArray(data.value)) {
121
+ return {
122
+ ...data,
123
+ value: data.value.map((record: any) =>
124
+ transformSingleRecord(record, baseTable, expandConfigs),
125
+ ),
126
+ };
127
+ }
128
+
129
+ // Handle array of records
130
+ if (Array.isArray(data)) {
131
+ return data.map((record) =>
132
+ transformSingleRecord(record, baseTable, expandConfigs),
133
+ );
134
+ }
135
+
136
+ // Handle single record
137
+ return transformSingleRecord(data, baseTable, expandConfigs);
138
+ }
139
+
140
+ /**
141
+ * Transforms a single record, converting field IDs to names and handling nested expands
142
+ */
143
+ function transformSingleRecord(
144
+ record: any,
145
+ baseTable: BaseTable<any, any, any, any>,
146
+ expandConfigs?: Array<{
147
+ relation: string;
148
+ occurrence?: TableOccurrence<any, any, any, any>;
149
+ }>,
150
+ ): any {
151
+ if (!record || typeof record !== "object") {
152
+ return record;
153
+ }
154
+
155
+ const transformed: Record<string, any> = {};
156
+
157
+ for (const [key, value] of Object.entries(record)) {
158
+ // Preserve OData metadata fields
159
+ if (key.startsWith("@")) {
160
+ transformed[key] = value;
161
+ continue;
162
+ }
163
+
164
+ // Check if this is an expanded relation (by relation name)
165
+ let expandConfig = expandConfigs?.find((ec) => ec.relation === key);
166
+
167
+ // If not found by relation name, check if this key is a FMTID
168
+ // (FileMaker returns expanded relations with FMTID keys when using entity IDs)
169
+ if (!expandConfig && key.startsWith("FMTID:")) {
170
+ expandConfig = expandConfigs?.find(
171
+ (ec) =>
172
+ ec.occurrence &&
173
+ ec.occurrence.isUsingTableId() &&
174
+ ec.occurrence.getTableId() === key,
175
+ );
176
+ }
177
+
178
+ if (expandConfig && expandConfig.occurrence) {
179
+ // Transform the expanded relation data recursively
180
+ // Use the relation name (not the FMTID) as the key
181
+ const relationKey = expandConfig.relation;
182
+
183
+ if (Array.isArray(value)) {
184
+ transformed[relationKey] = value.map((nestedRecord) =>
185
+ transformSingleRecord(
186
+ nestedRecord,
187
+ expandConfig.occurrence!.baseTable,
188
+ undefined, // Don't pass nested expand configs for now
189
+ ),
190
+ );
191
+ } else if (value && typeof value === "object") {
192
+ transformed[relationKey] = transformSingleRecord(
193
+ value,
194
+ expandConfig.occurrence.baseTable,
195
+ undefined,
196
+ );
197
+ } else {
198
+ transformed[relationKey] = value;
199
+ }
200
+ continue;
201
+ }
202
+
203
+ // Transform field ID to field name
204
+ const fieldName = baseTable.getFieldName(key);
205
+ transformed[fieldName] = value;
206
+ }
207
+
208
+ return transformed;
209
+ }
210
+
211
+ /**
212
+ * Transforms an array of field names to FMFIDs
213
+ * @param fieldNames - Array of field names
214
+ * @param baseTable - BaseTable instance to get field IDs from
215
+ * @returns Array of FMFIDs or field names
216
+ */
217
+ export function transformFieldNamesArray(
218
+ fieldNames: string[],
219
+ baseTable: BaseTable<any, any, any, any>,
220
+ ): string[] {
221
+ if (!baseTable.isUsingFieldIds()) {
222
+ return fieldNames;
223
+ }
224
+
225
+ return fieldNames.map((fieldName) => baseTable.getFieldId(fieldName as any));
226
+ }
227
+
228
+ /**
229
+ * Transforms a field name in an orderBy string (e.g., "name desc" -> "FMFID:1 desc")
230
+ * @param orderByString - The orderBy string (field name with optional asc/desc)
231
+ * @param baseTable - BaseTable instance to get field ID from
232
+ * @returns Transformed orderBy string with FMFID
233
+ */
234
+ export function transformOrderByField(
235
+ orderByString: string,
236
+ baseTable: BaseTable<any, any, any, any>,
237
+ ): string {
238
+ if (!baseTable.isUsingFieldIds()) {
239
+ return orderByString;
240
+ }
241
+
242
+ // Parse the orderBy string to extract field name and direction
243
+ const parts = orderByString.trim().split(/\s+/);
244
+ const fieldName = parts[0];
245
+ const direction = parts[1]; // "asc" or "desc" or undefined
246
+
247
+ const fieldId = baseTable.getFieldId(fieldName as any);
248
+ return direction ? `${fieldId} ${direction}` : fieldId;
249
+ }
package/src/types.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import { type FFetchOptions } from "@fetchkit/ffetch";
2
- import { z } from "zod/v4";
3
2
  import type { StandardSchemaV1 } from "@standard-schema/spec";
4
3
 
5
4
  export type Auth = { username: string; password: string } | { apiKey: string };
@@ -7,18 +6,40 @@ export type Auth = { username: string; password: string } | { apiKey: string };
7
6
  export interface ExecutableBuilder<T> {
8
7
  execute(): Promise<Result<T>>;
9
8
  getRequestConfig(): { method: string; url: string; body?: any };
9
+
10
+ /**
11
+ * Convert this builder to a native Request object for batch processing.
12
+ * @param baseUrl - The base URL for the OData service
13
+ * @returns A native Request object
14
+ */
15
+ toRequest(baseUrl: string): Request;
16
+
17
+ /**
18
+ * Process a raw Response object into a typed Result.
19
+ * This allows builders to apply their own validation and transformation logic.
20
+ * @param response - The native Response object from the batch operation
21
+ * @param options - Optional execution options (e.g., skipValidation, includeODataAnnotations)
22
+ * @returns A typed Result with the builder's expected return type
23
+ */
24
+ processResponse(
25
+ response: Response,
26
+ options?: ExecuteOptions,
27
+ ): Promise<Result<T>>;
10
28
  }
11
29
 
12
30
  export interface ExecutionContext {
13
31
  _makeRequest<T>(
14
32
  url: string,
15
- options?: RequestInit & FFetchOptions,
16
- ): Promise<T>;
33
+ options?: RequestInit & FFetchOptions & { useEntityIds?: boolean },
34
+ ): Promise<Result<T>>;
35
+ _setUseEntityIds?(useEntityIds: boolean): void;
36
+ _getUseEntityIds?(): boolean;
37
+ _getBaseUrl?(): string;
17
38
  }
18
39
 
19
40
  export type InferSchemaType<Schema extends Record<string, StandardSchemaV1>> = {
20
- [K in keyof Schema]: Schema[K] extends StandardSchemaV1<any, infer Output>
21
- ? Output
41
+ [K in keyof Schema]: Schema[K] extends StandardSchemaV1<any, infer Output>
42
+ ? Output
22
43
  : never;
23
44
  };
24
45
 
@@ -63,7 +84,7 @@ export type ODataFieldResponse<T> = {
63
84
  };
64
85
 
65
86
  // Result pattern for execute responses
66
- export type Result<T, E = Error> =
87
+ export type Result<T, E = import("./errors").FMODataErrorType> =
67
88
  | { data: T; error: undefined }
68
89
  | { data: undefined; error: E };
69
90
 
@@ -71,53 +92,198 @@ export type Result<T, E = Error> =
71
92
  export type MakeFieldsRequired<T, Keys extends keyof T> = Partial<T> &
72
93
  Required<Pick<T, Keys>>;
73
94
 
95
+ // Extract keys from schema where validator doesn't allow null/undefined (auto-required fields)
96
+ export type AutoRequiredKeys<Schema extends Record<string, StandardSchemaV1>> =
97
+ {
98
+ [K in keyof Schema]: Extract<
99
+ StandardSchemaV1.InferOutput<Schema[K]>,
100
+ null | undefined
101
+ > extends never
102
+ ? K
103
+ : never;
104
+ }[keyof Schema];
105
+
106
+ // Helper type to compute excluded fields (readOnly fields + idField)
107
+ export type ExcludedFields<
108
+ IdField extends keyof any | undefined,
109
+ ReadOnly extends readonly any[],
110
+ > = IdField extends keyof any ? IdField | ReadOnly[number] : ReadOnly[number];
111
+
112
+ // Helper type for InsertData computation
113
+ type ComputeInsertData<
114
+ Schema extends Record<string, StandardSchemaV1>,
115
+ IdField extends keyof Schema | undefined,
116
+ Required extends readonly any[],
117
+ ReadOnly extends readonly any[],
118
+ > = [Required[number]] extends [keyof InferSchemaType<Schema>]
119
+ ? Required extends readonly (keyof InferSchemaType<Schema>)[]
120
+ ? MakeFieldsRequired<
121
+ Omit<InferSchemaType<Schema>, ExcludedFields<IdField, ReadOnly>>,
122
+ Exclude<
123
+ AutoRequiredKeys<Schema> | Required[number],
124
+ ExcludedFields<IdField, ReadOnly>
125
+ >
126
+ >
127
+ : MakeFieldsRequired<
128
+ Omit<InferSchemaType<Schema>, ExcludedFields<IdField, ReadOnly>>,
129
+ Exclude<AutoRequiredKeys<Schema>, ExcludedFields<IdField, ReadOnly>>
130
+ >
131
+ : MakeFieldsRequired<
132
+ Omit<InferSchemaType<Schema>, ExcludedFields<IdField, ReadOnly>>,
133
+ Exclude<AutoRequiredKeys<Schema>, ExcludedFields<IdField, ReadOnly>>
134
+ >;
135
+
74
136
  // Extract insert data type from BaseTable
75
- // This type makes the insertRequired fields required while keeping others optional
137
+ // Auto-infers required fields from validator nullability + user-specified required fields
138
+ // Excludes readOnly fields and idField
76
139
  export type InsertData<BT> = BT extends import("./client/base-table").BaseTable<
77
- infer Schema extends Record<string, z.ZodType>,
78
140
  any,
79
- infer InsertRequired extends readonly any[],
141
+ any,
142
+ any,
80
143
  any
81
144
  >
82
- ? [InsertRequired[number]] extends [keyof InferSchemaType<Schema>]
83
- ? InsertRequired extends readonly (keyof InferSchemaType<Schema>)[]
84
- ? MakeFieldsRequired<InferSchemaType<Schema>, InsertRequired[number]>
85
- : Partial<InferSchemaType<Schema>>
86
- : Partial<InferSchemaType<Schema>>
145
+ ? BT extends {
146
+ schema: infer Schema;
147
+ idField?: infer IdField;
148
+ required?: infer Required;
149
+ readOnly?: infer ReadOnly;
150
+ }
151
+ ? Schema extends Record<string, StandardSchemaV1>
152
+ ? IdField extends keyof Schema | undefined
153
+ ? Required extends readonly any[]
154
+ ? ReadOnly extends readonly any[]
155
+ ? ComputeInsertData<
156
+ Schema,
157
+ Extract<IdField, keyof Schema | undefined>,
158
+ Required,
159
+ ReadOnly
160
+ >
161
+ : Partial<Record<string, any>>
162
+ : Partial<Record<string, any>>
163
+ : Partial<Record<string, any>>
164
+ : Partial<Record<string, any>>
165
+ : Partial<Record<string, any>>
87
166
  : Partial<Record<string, any>>;
88
167
 
89
168
  // Extract update data type from BaseTable
90
- // This type makes the updateRequired fields required while keeping others optional
169
+ // All fields are optional for updates, excludes readOnly fields and idField
91
170
  export type UpdateData<BT> = BT extends import("./client/base-table").BaseTable<
92
- infer Schema extends Record<string, z.ZodType>,
93
171
  any,
94
172
  any,
95
- infer UpdateRequired extends readonly any[]
173
+ any,
174
+ any
96
175
  >
97
- ? [UpdateRequired[number]] extends [keyof InferSchemaType<Schema>]
98
- ? UpdateRequired extends readonly (keyof InferSchemaType<Schema>)[]
99
- ? MakeFieldsRequired<InferSchemaType<Schema>, UpdateRequired[number]>
100
- : Partial<InferSchemaType<Schema>>
101
- : Partial<InferSchemaType<Schema>>
176
+ ? BT extends {
177
+ schema: infer Schema;
178
+ idField?: infer IdField;
179
+ readOnly?: infer ReadOnly;
180
+ }
181
+ ? Schema extends Record<string, StandardSchemaV1>
182
+ ? IdField extends keyof Schema | undefined
183
+ ? ReadOnly extends readonly any[]
184
+ ? Partial<
185
+ Omit<
186
+ InferSchemaType<Schema>,
187
+ ExcludedFields<
188
+ Extract<IdField, keyof Schema | undefined>,
189
+ ReadOnly
190
+ >
191
+ >
192
+ >
193
+ : Partial<Record<string, any>>
194
+ : Partial<Record<string, any>>
195
+ : Partial<Record<string, any>>
196
+ : Partial<Record<string, any>>
102
197
  : Partial<Record<string, any>>;
103
198
 
104
199
  export type ExecuteOptions = {
105
200
  includeODataAnnotations?: boolean;
106
201
  skipValidation?: boolean;
202
+ /**
203
+ * Overrides the default behavior of the database to use entity IDs (rather than field names) in THIS REQUEST ONLY
204
+ */
205
+ useEntityIds?: boolean;
107
206
  };
108
207
 
109
- export type ConditionallyWithODataAnnotations<T, IncludeODataAnnotations extends boolean> =
110
- IncludeODataAnnotations extends true
111
- ? T & {
112
- "@id": string;
113
- "@editLink": string;
114
- }
115
- : T;
208
+ export type ConditionallyWithODataAnnotations<
209
+ T,
210
+ IncludeODataAnnotations extends boolean,
211
+ > = IncludeODataAnnotations extends true
212
+ ? T & {
213
+ "@id": string;
214
+ "@editLink": string;
215
+ }
216
+ : T;
116
217
 
117
218
  // Helper type to extract schema from a TableOccurrence
118
- export type ExtractSchemaFromOccurrence<Occ> =
119
- Occ extends { baseTable: { schema: infer S } }
120
- ? S extends Record<string, StandardSchemaV1>
121
- ? S
122
- : Record<string, StandardSchemaV1>
123
- : Record<string, StandardSchemaV1>;
219
+ export type ExtractSchemaFromOccurrence<Occ> = Occ extends {
220
+ baseTable: { schema: infer S };
221
+ }
222
+ ? S extends Record<string, StandardSchemaV1>
223
+ ? S
224
+ : Record<string, StandardSchemaV1>
225
+ : Record<string, StandardSchemaV1>;
226
+
227
+ export type GenericFieldMetadata = {
228
+ $Nullable?: boolean;
229
+ "@Index"?: boolean;
230
+ "@Calculation"?: boolean;
231
+ "@Summary"?: boolean;
232
+ "@Global"?: boolean;
233
+ "@Org.OData.Core.V1.Permissions"?: "Org.OData.Core.V1.Permission@Read";
234
+ };
235
+
236
+ export type StringFieldMetadata = GenericFieldMetadata & {
237
+ $Type: "Edm.String";
238
+ $DefaultValue?: "USER" | "USERNAME" | "CURRENT_USER";
239
+ $MaxLength?: number;
240
+ };
241
+
242
+ export type DecimalFieldMetadata = GenericFieldMetadata & {
243
+ $Type: "Edm.Decimal";
244
+ "@AutoGenerated"?: boolean;
245
+ };
246
+
247
+ export type DateFieldMetadata = GenericFieldMetadata & {
248
+ $Type: "Edm.Date";
249
+ $DefaultValue?: "CURDATE" | "CURRENT_DATE";
250
+ };
251
+
252
+ export type TimeOfDayFieldMetadata = GenericFieldMetadata & {
253
+ $Type: "Edm.TimeOfDay";
254
+ $DefaultValue?: "CURTIME" | "CURRENT_TIME";
255
+ };
256
+
257
+ export type DateTimeOffsetFieldMetadata = GenericFieldMetadata & {
258
+ $Type: "Edm.Date";
259
+ $DefaultValue?: "CURTIMESTAMP" | "CURRENT_TIMESTAMP";
260
+ "@VersionId"?: boolean;
261
+ };
262
+
263
+ export type StreamFieldMetadata = {
264
+ $Type: "Edm.Stream";
265
+ $Nullable?: boolean;
266
+ "@EnclosedPath": string;
267
+ "@ExternalOpenPath": string;
268
+ "@ExternalSecurePath"?: string;
269
+ };
270
+
271
+ export type FieldMetadata =
272
+ | StringFieldMetadata
273
+ | DecimalFieldMetadata
274
+ | DateFieldMetadata
275
+ | TimeOfDayFieldMetadata
276
+ | DateTimeOffsetFieldMetadata
277
+ | StreamFieldMetadata;
278
+
279
+ export type EntityType = {
280
+ $Kind: "EntityType";
281
+ $Key: string[];
282
+ } & Record<string, FieldMetadata>;
283
+
284
+ export type EntitySet = {
285
+ $Kind: "EntitySet";
286
+ $Type: string;
287
+ };
288
+
289
+ export type Metadata = Record<string, EntityType | EntitySet>;