@proofkit/fmodata 0.1.0-alpha.2 → 0.1.0-alpha.20

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 (162) hide show
  1. package/README.md +1250 -377
  2. package/dist/esm/client/batch-builder.d.ts +56 -0
  3. package/dist/esm/client/batch-builder.js +238 -0
  4. package/dist/esm/client/batch-builder.js.map +1 -0
  5. package/dist/esm/client/batch-request.d.ts +61 -0
  6. package/dist/esm/client/batch-request.js +252 -0
  7. package/dist/esm/client/batch-request.js.map +1 -0
  8. package/dist/esm/client/builders/default-select.d.ts +10 -0
  9. package/dist/esm/client/builders/default-select.js +43 -0
  10. package/dist/esm/client/builders/default-select.js.map +1 -0
  11. package/dist/esm/client/builders/expand-builder.d.ts +45 -0
  12. package/dist/esm/client/builders/expand-builder.js +174 -0
  13. package/dist/esm/client/builders/expand-builder.js.map +1 -0
  14. package/dist/esm/client/builders/index.d.ts +8 -0
  15. package/dist/esm/client/builders/query-string-builder.d.ts +18 -0
  16. package/dist/esm/client/builders/query-string-builder.js +25 -0
  17. package/dist/esm/client/builders/query-string-builder.js.map +1 -0
  18. package/dist/esm/client/builders/response-processor.d.ts +43 -0
  19. package/dist/esm/client/builders/response-processor.js +176 -0
  20. package/dist/esm/client/builders/response-processor.js.map +1 -0
  21. package/dist/esm/client/builders/select-mixin.d.ts +32 -0
  22. package/dist/esm/client/builders/select-mixin.js +30 -0
  23. package/dist/esm/client/builders/select-mixin.js.map +1 -0
  24. package/dist/esm/client/builders/select-utils.d.ts +18 -0
  25. package/dist/esm/client/builders/select-utils.js +23 -0
  26. package/dist/esm/client/builders/select-utils.js.map +1 -0
  27. package/dist/esm/client/builders/shared-types.d.ts +40 -0
  28. package/dist/esm/client/builders/table-utils.d.ts +35 -0
  29. package/dist/esm/client/builders/table-utils.js +45 -0
  30. package/dist/esm/client/builders/table-utils.js.map +1 -0
  31. package/dist/esm/client/database.d.ts +68 -15
  32. package/dist/esm/client/database.js +88 -34
  33. package/dist/esm/client/database.js.map +1 -1
  34. package/dist/esm/client/delete-builder.d.ts +31 -17
  35. package/dist/esm/client/delete-builder.js +114 -47
  36. package/dist/esm/client/delete-builder.js.map +1 -1
  37. package/dist/esm/client/entity-set.d.ts +33 -27
  38. package/dist/esm/client/entity-set.js +123 -45
  39. package/dist/esm/client/entity-set.js.map +1 -1
  40. package/dist/esm/client/error-parser.d.ts +12 -0
  41. package/dist/esm/client/error-parser.js +30 -0
  42. package/dist/esm/client/error-parser.js.map +1 -0
  43. package/dist/esm/client/filemaker-odata.d.ts +44 -6
  44. package/dist/esm/client/filemaker-odata.js +172 -28
  45. package/dist/esm/client/filemaker-odata.js.map +1 -1
  46. package/dist/esm/client/insert-builder.d.ts +39 -9
  47. package/dist/esm/client/insert-builder.js +265 -36
  48. package/dist/esm/client/insert-builder.js.map +1 -1
  49. package/dist/esm/client/query/expand-builder.d.ts +35 -0
  50. package/dist/esm/client/query/index.d.ts +3 -0
  51. package/dist/esm/client/query/query-builder.d.ts +139 -0
  52. package/dist/esm/client/query/query-builder.js +481 -0
  53. package/dist/esm/client/query/query-builder.js.map +1 -0
  54. package/dist/esm/client/query/response-processor.d.ts +25 -0
  55. package/dist/esm/client/query/types.d.ts +77 -0
  56. package/dist/esm/client/query/url-builder.d.ts +71 -0
  57. package/dist/esm/client/query/url-builder.js +107 -0
  58. package/dist/esm/client/query/url-builder.js.map +1 -0
  59. package/dist/esm/client/query-builder.d.ts +1 -94
  60. package/dist/esm/client/record-builder.d.ts +107 -22
  61. package/dist/esm/client/record-builder.js +342 -64
  62. package/dist/esm/client/record-builder.js.map +1 -1
  63. package/dist/esm/client/response-processor.d.ts +33 -0
  64. package/dist/esm/client/sanitize-json.d.ts +35 -0
  65. package/dist/esm/client/sanitize-json.js +27 -0
  66. package/dist/esm/client/sanitize-json.js.map +1 -0
  67. package/dist/esm/client/schema-manager.d.ts +57 -0
  68. package/dist/esm/client/schema-manager.js +132 -0
  69. package/dist/esm/client/schema-manager.js.map +1 -0
  70. package/dist/esm/client/update-builder.d.ts +42 -25
  71. package/dist/esm/client/update-builder.js +179 -46
  72. package/dist/esm/client/update-builder.js.map +1 -1
  73. package/dist/esm/client/webhook-builder.d.ts +126 -0
  74. package/dist/esm/client/webhook-builder.js +197 -0
  75. package/dist/esm/client/webhook-builder.js.map +1 -0
  76. package/dist/esm/errors.d.ts +90 -0
  77. package/dist/esm/errors.js +180 -0
  78. package/dist/esm/errors.js.map +1 -0
  79. package/dist/esm/index.d.ts +12 -4
  80. package/dist/esm/index.js +59 -6
  81. package/dist/esm/index.js.map +1 -1
  82. package/dist/esm/logger.d.ts +47 -0
  83. package/dist/esm/logger.js +72 -0
  84. package/dist/esm/logger.js.map +1 -0
  85. package/dist/esm/logger.test.d.ts +1 -0
  86. package/dist/esm/orm/column.d.ts +62 -0
  87. package/dist/esm/orm/column.js +62 -0
  88. package/dist/esm/orm/column.js.map +1 -0
  89. package/dist/esm/orm/field-builders.d.ts +164 -0
  90. package/dist/esm/orm/field-builders.js +168 -0
  91. package/dist/esm/orm/field-builders.js.map +1 -0
  92. package/dist/esm/orm/index.d.ts +4 -0
  93. package/dist/esm/orm/operators.d.ts +175 -0
  94. package/dist/esm/orm/operators.js +242 -0
  95. package/dist/esm/orm/operators.js.map +1 -0
  96. package/dist/esm/orm/table.d.ts +355 -0
  97. package/dist/esm/orm/table.js +200 -0
  98. package/dist/esm/orm/table.js.map +1 -0
  99. package/dist/esm/transform.d.ts +64 -0
  100. package/dist/esm/transform.js +110 -0
  101. package/dist/esm/transform.js.map +1 -0
  102. package/dist/esm/types.d.ts +157 -7
  103. package/dist/esm/types.js +7 -0
  104. package/dist/esm/types.js.map +1 -0
  105. package/dist/esm/validation.d.ts +22 -9
  106. package/dist/esm/validation.js +195 -50
  107. package/dist/esm/validation.js.map +1 -1
  108. package/package.json +19 -4
  109. package/src/client/batch-builder.ts +334 -0
  110. package/src/client/batch-request.ts +485 -0
  111. package/src/client/builders/default-select.ts +80 -0
  112. package/src/client/builders/expand-builder.ts +245 -0
  113. package/src/client/builders/index.ts +11 -0
  114. package/src/client/builders/query-string-builder.ts +49 -0
  115. package/src/client/builders/response-processor.ts +286 -0
  116. package/src/client/builders/select-mixin.ts +75 -0
  117. package/src/client/builders/select-utils.ts +56 -0
  118. package/src/client/builders/shared-types.ts +42 -0
  119. package/src/client/builders/table-utils.ts +87 -0
  120. package/src/client/database.ts +147 -89
  121. package/src/client/delete-builder.ts +189 -87
  122. package/src/client/entity-set.ts +316 -205
  123. package/src/client/error-parser.ts +59 -0
  124. package/src/client/filemaker-odata.ts +254 -41
  125. package/src/client/insert-builder.ts +420 -49
  126. package/src/client/query/expand-builder.ts +164 -0
  127. package/src/client/query/index.ts +13 -0
  128. package/src/client/query/query-builder.ts +905 -0
  129. package/src/client/query/response-processor.ts +236 -0
  130. package/src/client/query/types.ts +128 -0
  131. package/src/client/query/url-builder.ts +179 -0
  132. package/src/client/query-builder.ts +8 -1076
  133. package/src/client/record-builder.ts +704 -139
  134. package/src/client/response-processor.ts +89 -0
  135. package/src/client/sanitize-json.ts +66 -0
  136. package/src/client/schema-manager.ts +246 -0
  137. package/src/client/update-builder.ts +318 -90
  138. package/src/client/webhook-builder.ts +285 -0
  139. package/src/errors.ts +261 -0
  140. package/src/index.ts +122 -14
  141. package/src/logger.test.ts +34 -0
  142. package/src/logger.ts +140 -0
  143. package/src/orm/column.ts +106 -0
  144. package/src/orm/field-builders.ts +318 -0
  145. package/src/orm/index.ts +60 -0
  146. package/src/orm/operators.ts +487 -0
  147. package/src/orm/table.ts +759 -0
  148. package/src/transform.ts +263 -0
  149. package/src/types.ts +275 -55
  150. package/src/validation.ts +255 -55
  151. package/dist/esm/client/base-table.d.ts +0 -13
  152. package/dist/esm/client/base-table.js +0 -19
  153. package/dist/esm/client/base-table.js.map +0 -1
  154. package/dist/esm/client/query-builder.js +0 -649
  155. package/dist/esm/client/query-builder.js.map +0 -1
  156. package/dist/esm/client/table-occurrence.d.ts +0 -25
  157. package/dist/esm/client/table-occurrence.js +0 -47
  158. package/dist/esm/client/table-occurrence.js.map +0 -1
  159. package/dist/esm/filter-types.d.ts +0 -76
  160. package/src/client/base-table.ts +0 -25
  161. package/src/client/table-occurrence.ts +0 -100
  162. package/src/filter-types.ts +0 -97
@@ -1,56 +1,66 @@
1
- import { ExecutionContext, ExecutableBuilder, Result, WithSystemFields } from '../types.js';
2
- import { TableOccurrence } from './table-occurrence.js';
1
+ import { ExecutionContext, ExecutableBuilder, Result, ExecuteOptions, ExecuteMethodOptions } from '../types.js';
2
+ import { FMTable } from '../orm/table.js';
3
3
  import { QueryBuilder } from './query-builder.js';
4
- import { FFetchOptions } from '@fetchkit/ffetch';
5
4
  /**
6
5
  * Initial delete builder returned from EntitySet.delete()
7
6
  * Requires calling .byId() or .where() before .execute() is available
8
7
  */
9
- export declare class DeleteBuilder<T extends Record<string, any>> {
10
- private tableName;
8
+ export declare class DeleteBuilder<Occ extends FMTable<any, any>> {
11
9
  private databaseName;
12
10
  private context;
13
- private occurrence?;
11
+ private table;
12
+ private databaseUseEntityIds;
13
+ private databaseIncludeSpecialColumns;
14
14
  constructor(config: {
15
- occurrence?: TableOccurrence<any, any, any, any>;
16
- tableName: string;
15
+ occurrence: Occ;
17
16
  databaseName: string;
18
17
  context: ExecutionContext;
18
+ databaseUseEntityIds?: boolean;
19
+ databaseIncludeSpecialColumns?: boolean;
19
20
  });
20
21
  /**
21
22
  * Delete a single record by ID
22
23
  */
23
- byId(id: string | number): ExecutableDeleteBuilder<T>;
24
+ byId(id: string | number): ExecutableDeleteBuilder<Occ>;
24
25
  /**
25
26
  * Delete records matching a filter query
26
27
  * @param fn Callback that receives a QueryBuilder for building the filter
27
28
  */
28
- where(fn: (q: QueryBuilder<WithSystemFields<T>>) => QueryBuilder<WithSystemFields<T>>): ExecutableDeleteBuilder<T>;
29
+ where(fn: (q: QueryBuilder<Occ>) => QueryBuilder<Occ>): ExecutableDeleteBuilder<Occ>;
29
30
  }
30
31
  /**
31
32
  * Executable delete builder - has execute() method
32
33
  * Returned after calling .byId() or .where()
33
34
  */
34
- export declare class ExecutableDeleteBuilder<T extends Record<string, any>> implements ExecutableBuilder<{
35
+ export declare class ExecutableDeleteBuilder<Occ extends FMTable<any, any>> implements ExecutableBuilder<{
35
36
  deletedCount: number;
36
37
  }> {
37
- private tableName;
38
38
  private databaseName;
39
39
  private context;
40
- private occurrence?;
40
+ private table;
41
41
  private mode;
42
42
  private recordId?;
43
43
  private queryBuilder?;
44
+ private databaseUseEntityIds;
44
45
  constructor(config: {
45
- occurrence?: TableOccurrence<any, any, any, any>;
46
- tableName: string;
46
+ occurrence: Occ;
47
47
  databaseName: string;
48
48
  context: ExecutionContext;
49
49
  mode: "byId" | "byFilter";
50
50
  recordId?: string | number;
51
- queryBuilder?: QueryBuilder<any>;
51
+ queryBuilder?: QueryBuilder<Occ>;
52
+ databaseUseEntityIds?: boolean;
52
53
  });
53
- execute(options?: RequestInit & FFetchOptions): Promise<Result<{
54
+ /**
55
+ * Helper to merge database-level useEntityIds with per-request options
56
+ */
57
+ private mergeExecuteOptions;
58
+ /**
59
+ * Gets the table ID (FMTID) if using entity IDs, otherwise returns the table name
60
+ * @param useEntityIds - Optional override for entity ID usage
61
+ */
62
+ private getTableId;
63
+ execute(options?: ExecuteMethodOptions<ExecuteOptions>): Promise<Result<{
54
64
  deletedCount: number;
55
65
  }>>;
56
66
  getRequestConfig(): {
@@ -58,4 +68,8 @@ export declare class ExecutableDeleteBuilder<T extends Record<string, any>> impl
58
68
  url: string;
59
69
  body?: any;
60
70
  };
71
+ toRequest(baseUrl: string, options?: ExecuteOptions): Request;
72
+ processResponse(response: Response, options?: ExecuteOptions): Promise<Result<{
73
+ deletedCount: number;
74
+ }>>;
61
75
  }
@@ -1,29 +1,34 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
- import { QueryBuilder } from "./query-builder.js";
4
+ import { getAcceptHeader } from "../types.js";
5
+ import { isUsingEntityIds, getTableName, getTableId } from "../orm/table.js";
6
+ import { QueryBuilder } from "./query/query-builder.js";
7
+ import { parseErrorResponse } from "./error-parser.js";
5
8
  class DeleteBuilder {
6
9
  constructor(config) {
7
- __publicField(this, "tableName");
8
10
  __publicField(this, "databaseName");
9
11
  __publicField(this, "context");
10
- __publicField(this, "occurrence");
11
- this.occurrence = config.occurrence;
12
- this.tableName = config.tableName;
12
+ __publicField(this, "table");
13
+ __publicField(this, "databaseUseEntityIds");
14
+ __publicField(this, "databaseIncludeSpecialColumns");
15
+ this.table = config.occurrence;
13
16
  this.databaseName = config.databaseName;
14
17
  this.context = config.context;
18
+ this.databaseUseEntityIds = config.databaseUseEntityIds ?? false;
19
+ this.databaseIncludeSpecialColumns = config.databaseIncludeSpecialColumns ?? false;
15
20
  }
16
21
  /**
17
22
  * Delete a single record by ID
18
23
  */
19
24
  byId(id) {
20
25
  return new ExecutableDeleteBuilder({
21
- occurrence: this.occurrence,
22
- tableName: this.tableName,
26
+ occurrence: this.table,
23
27
  databaseName: this.databaseName,
24
28
  context: this.context,
25
29
  mode: "byId",
26
- recordId: id
30
+ recordId: id,
31
+ databaseUseEntityIds: this.databaseUseEntityIds
27
32
  });
28
33
  }
29
34
  /**
@@ -32,87 +37,149 @@ class DeleteBuilder {
32
37
  */
33
38
  where(fn) {
34
39
  const queryBuilder = new QueryBuilder({
35
- occurrence: void 0,
36
- tableName: this.tableName,
40
+ occurrence: this.table,
37
41
  databaseName: this.databaseName,
38
42
  context: this.context
39
43
  });
40
44
  const configuredBuilder = fn(queryBuilder);
41
45
  return new ExecutableDeleteBuilder({
42
- occurrence: this.occurrence,
43
- tableName: this.tableName,
46
+ occurrence: this.table,
44
47
  databaseName: this.databaseName,
45
48
  context: this.context,
46
49
  mode: "byFilter",
47
- queryBuilder: configuredBuilder
50
+ queryBuilder: configuredBuilder,
51
+ databaseUseEntityIds: this.databaseUseEntityIds
48
52
  });
49
53
  }
50
54
  }
51
55
  class ExecutableDeleteBuilder {
52
56
  constructor(config) {
53
- __publicField(this, "tableName");
54
57
  __publicField(this, "databaseName");
55
58
  __publicField(this, "context");
56
- __publicField(this, "occurrence");
59
+ __publicField(this, "table");
57
60
  __publicField(this, "mode");
58
61
  __publicField(this, "recordId");
59
62
  __publicField(this, "queryBuilder");
60
- this.occurrence = config.occurrence;
61
- this.tableName = config.tableName;
63
+ __publicField(this, "databaseUseEntityIds");
64
+ this.table = config.occurrence;
62
65
  this.databaseName = config.databaseName;
63
66
  this.context = config.context;
64
67
  this.mode = config.mode;
65
68
  this.recordId = config.recordId;
66
69
  this.queryBuilder = config.queryBuilder;
70
+ this.databaseUseEntityIds = config.databaseUseEntityIds ?? false;
67
71
  }
68
- async execute(options) {
69
- try {
70
- let url;
71
- if (this.mode === "byId") {
72
- url = `/${this.databaseName}/${this.tableName}('${this.recordId}')`;
73
- } else {
74
- if (!this.queryBuilder) {
75
- throw new Error("Query builder is required for filter-based delete");
76
- }
77
- const queryString = this.queryBuilder.getQueryString();
78
- const queryParams = queryString.startsWith(`/${this.tableName}`) ? queryString.slice(`/${this.tableName}`.length) : queryString;
79
- url = `/${this.databaseName}/${this.tableName}${queryParams}`;
72
+ /**
73
+ * Helper to merge database-level useEntityIds with per-request options
74
+ */
75
+ mergeExecuteOptions(options) {
76
+ return {
77
+ ...options,
78
+ useEntityIds: (options == null ? void 0 : options.useEntityIds) ?? this.databaseUseEntityIds
79
+ };
80
+ }
81
+ /**
82
+ * Gets the table ID (FMTID) if using entity IDs, otherwise returns the table name
83
+ * @param useEntityIds - Optional override for entity ID usage
84
+ */
85
+ getTableId(useEntityIds) {
86
+ var _a, _b;
87
+ const contextDefault = ((_b = (_a = this.context)._getUseEntityIds) == null ? void 0 : _b.call(_a)) ?? false;
88
+ const shouldUseIds = useEntityIds ?? contextDefault;
89
+ if (shouldUseIds) {
90
+ if (!isUsingEntityIds(this.table)) {
91
+ throw new Error(
92
+ `useEntityIds is true but table "${getTableName(this.table)}" does not have entity IDs configured`
93
+ );
80
94
  }
81
- const response = await this.context._makeRequest(url, {
82
- method: "DELETE",
83
- ...options
84
- });
85
- let deletedCount = 0;
86
- if (typeof response === "number") {
87
- deletedCount = response;
88
- } else if (response && typeof response === "object") {
89
- deletedCount = response.deletedCount || 0;
95
+ return getTableId(this.table);
96
+ }
97
+ return getTableName(this.table);
98
+ }
99
+ async execute(options) {
100
+ const mergedOptions = this.mergeExecuteOptions(options);
101
+ const tableId = this.getTableId(mergedOptions.useEntityIds);
102
+ let url;
103
+ if (this.mode === "byId") {
104
+ url = `/${this.databaseName}/${tableId}('${this.recordId}')`;
105
+ } else {
106
+ if (!this.queryBuilder) {
107
+ throw new Error("Query builder is required for filter-based delete");
90
108
  }
91
- return { data: { deletedCount }, error: void 0 };
92
- } catch (error) {
93
- return {
94
- data: void 0,
95
- error: error instanceof Error ? error : new Error(String(error))
96
- };
109
+ const queryString = this.queryBuilder.getQueryString();
110
+ const tableName = getTableName(this.table);
111
+ const queryParams = queryString.startsWith(`/${tableId}`) ? queryString.slice(`/${tableId}`.length) : queryString.startsWith(`/${tableName}`) ? queryString.slice(`/${tableName}`.length) : queryString;
112
+ url = `/${this.databaseName}/${tableId}${queryParams}`;
113
+ }
114
+ const result = await this.context._makeRequest(url, {
115
+ method: "DELETE",
116
+ ...mergedOptions
117
+ });
118
+ if (result.error) {
119
+ return { data: void 0, error: result.error };
120
+ }
121
+ const response = result.data;
122
+ let deletedCount = 0;
123
+ if (typeof response === "number") {
124
+ deletedCount = response;
125
+ } else if (response && typeof response === "object") {
126
+ deletedCount = response.deletedCount || 0;
97
127
  }
128
+ return { data: { deletedCount }, error: void 0 };
98
129
  }
99
130
  getRequestConfig() {
131
+ const tableId = this.getTableId(this.databaseUseEntityIds);
100
132
  let url;
101
133
  if (this.mode === "byId") {
102
- url = `/${this.databaseName}/${this.tableName}('${this.recordId}')`;
134
+ url = `/${this.databaseName}/${tableId}('${this.recordId}')`;
103
135
  } else {
104
136
  if (!this.queryBuilder) {
105
137
  throw new Error("Query builder is required for filter-based delete");
106
138
  }
107
139
  const queryString = this.queryBuilder.getQueryString();
108
- const queryParams = queryString.startsWith(`/${this.tableName}`) ? queryString.slice(`/${this.tableName}`.length) : queryString;
109
- url = `/${this.databaseName}/${this.tableName}${queryParams}`;
140
+ const tableName = getTableName(this.table);
141
+ const queryParams = queryString.startsWith(`/${tableId}`) ? queryString.slice(`/${tableId}`.length) : queryString.startsWith(`/${tableName}`) ? queryString.slice(`/${tableName}`.length) : queryString;
142
+ url = `/${this.databaseName}/${tableId}${queryParams}`;
110
143
  }
111
144
  return {
112
145
  method: "DELETE",
113
146
  url
114
147
  };
115
148
  }
149
+ toRequest(baseUrl, options) {
150
+ const config = this.getRequestConfig();
151
+ const fullUrl = `${baseUrl}${config.url}`;
152
+ return new Request(fullUrl, {
153
+ method: config.method,
154
+ headers: {
155
+ Accept: getAcceptHeader(options == null ? void 0 : options.includeODataAnnotations)
156
+ }
157
+ });
158
+ }
159
+ async processResponse(response, options) {
160
+ if (!response.ok) {
161
+ const tableName = getTableName(this.table);
162
+ const error = await parseErrorResponse(
163
+ response,
164
+ response.url || `/${this.databaseName}/${tableName}`
165
+ );
166
+ return { data: void 0, error };
167
+ }
168
+ const text = await response.text();
169
+ if (!text || text.trim() === "") {
170
+ const affectedRows = response.headers.get("fmodata.affected_rows");
171
+ const deletedCount2 = affectedRows ? parseInt(affectedRows, 10) : 1;
172
+ return { data: { deletedCount: deletedCount2 }, error: void 0 };
173
+ }
174
+ const rawResponse = JSON.parse(text);
175
+ let deletedCount = 0;
176
+ if (typeof rawResponse === "number") {
177
+ deletedCount = rawResponse;
178
+ } else if (rawResponse && typeof rawResponse === "object") {
179
+ deletedCount = rawResponse.deletedCount || 0;
180
+ }
181
+ return { data: { deletedCount }, error: void 0 };
182
+ }
116
183
  }
117
184
  export {
118
185
  DeleteBuilder,
@@ -1 +1 @@
1
- {"version":3,"file":"delete-builder.js","sources":["../../../src/client/delete-builder.ts"],"sourcesContent":["import type {\n ExecutionContext,\n ExecutableBuilder,\n Result,\n WithSystemFields,\n} from \"../types\";\nimport type { TableOccurrence } from \"./table-occurrence\";\nimport { QueryBuilder } from \"./query-builder\";\nimport { type FFetchOptions } from \"@fetchkit/ffetch\";\nimport buildQuery from \"odata-query\";\n\n/**\n * Initial delete builder returned from EntitySet.delete()\n * Requires calling .byId() or .where() before .execute() is available\n */\nexport class DeleteBuilder<T extends Record<string, any>> {\n private tableName: string;\n private databaseName: string;\n private context: ExecutionContext;\n private occurrence?: TableOccurrence<any, any, any, any>;\n\n constructor(config: {\n occurrence?: TableOccurrence<any, any, any, any>;\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 * Delete a single record by ID\n */\n byId(id: string | number): ExecutableDeleteBuilder<T> {\n return new ExecutableDeleteBuilder<T>({\n occurrence: this.occurrence,\n tableName: this.tableName,\n databaseName: this.databaseName,\n context: this.context,\n mode: \"byId\",\n recordId: id,\n });\n }\n\n /**\n * Delete records matching a filter query\n * @param fn Callback that receives a QueryBuilder for building the filter\n */\n where(\n fn: (\n q: QueryBuilder<WithSystemFields<T>>,\n ) => QueryBuilder<WithSystemFields<T>>,\n ): ExecutableDeleteBuilder<T> {\n // Create a QueryBuilder for the user to configure\n const queryBuilder = new QueryBuilder<\n WithSystemFields<T>,\n keyof WithSystemFields<T>,\n false,\n false,\n undefined\n >({\n occurrence: undefined,\n tableName: this.tableName,\n databaseName: this.databaseName,\n context: this.context,\n });\n\n // Let the user configure it\n const configuredBuilder = fn(queryBuilder);\n\n return new ExecutableDeleteBuilder<T>({\n occurrence: this.occurrence,\n tableName: this.tableName,\n databaseName: this.databaseName,\n context: this.context,\n mode: \"byFilter\",\n queryBuilder: configuredBuilder,\n });\n }\n}\n\n/**\n * Executable delete builder - has execute() method\n * Returned after calling .byId() or .where()\n */\nexport class ExecutableDeleteBuilder<T extends Record<string, any>>\n implements ExecutableBuilder<{ deletedCount: number }>\n{\n private tableName: string;\n private databaseName: string;\n private context: ExecutionContext;\n private occurrence?: TableOccurrence<any, any, any, any>;\n private mode: \"byId\" | \"byFilter\";\n private recordId?: string | number;\n private queryBuilder?: QueryBuilder<any>;\n\n constructor(config: {\n occurrence?: TableOccurrence<any, any, any, any>;\n tableName: string;\n databaseName: string;\n context: ExecutionContext;\n mode: \"byId\" | \"byFilter\";\n recordId?: string | number;\n queryBuilder?: QueryBuilder<any>;\n }) {\n this.occurrence = config.occurrence;\n this.tableName = config.tableName;\n this.databaseName = config.databaseName;\n this.context = config.context;\n this.mode = config.mode;\n this.recordId = config.recordId;\n this.queryBuilder = config.queryBuilder;\n }\n\n async execute(\n options?: RequestInit & FFetchOptions,\n ): Promise<Result<{ deletedCount: number }>> {\n try {\n let url: string;\n\n if (this.mode === \"byId\") {\n // Delete single record by ID: DELETE /{database}/{table}('id')\n url = `/${this.databaseName}/${this.tableName}('${this.recordId}')`;\n } else {\n // Delete by filter: DELETE /{database}/{table}?$filter=...\n if (!this.queryBuilder) {\n throw new Error(\"Query builder is required for filter-based delete\");\n }\n\n // Get the query string from the configured QueryBuilder\n const queryString = this.queryBuilder.getQueryString();\n // Remove the leading \"/\" from the query string as we'll build our own URL\n const queryParams = queryString.startsWith(`/${this.tableName}`)\n ? queryString.slice(`/${this.tableName}`.length)\n : queryString;\n\n url = `/${this.databaseName}/${this.tableName}${queryParams}`;\n }\n\n // Make DELETE request\n const response = await this.context._makeRequest(url, {\n method: \"DELETE\",\n ...options,\n });\n\n // OData returns 204 No Content with fmodata.affected_rows header\n // The _makeRequest should handle extracting the header value\n // For now, we'll check if response contains the count\n let deletedCount = 0;\n\n if (typeof response === \"number\") {\n deletedCount = response;\n } else if (response && typeof response === \"object\") {\n // Check if the response has a count property (fallback)\n deletedCount = (response as any).deletedCount || 0;\n }\n\n return { data: { deletedCount }, error: undefined };\n } catch (error) {\n return {\n data: undefined,\n error: error instanceof Error ? error : new Error(String(error)),\n };\n }\n }\n\n getRequestConfig(): { method: string; url: string; body?: any } {\n let url: string;\n\n if (this.mode === \"byId\") {\n url = `/${this.databaseName}/${this.tableName}('${this.recordId}')`;\n } else {\n if (!this.queryBuilder) {\n throw new Error(\"Query builder is required for filter-based delete\");\n }\n\n const queryString = this.queryBuilder.getQueryString();\n const queryParams = queryString.startsWith(`/${this.tableName}`)\n ? queryString.slice(`/${this.tableName}`.length)\n : queryString;\n\n url = `/${this.databaseName}/${this.tableName}${queryParams}`;\n }\n\n return {\n method: \"DELETE\",\n url,\n };\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"delete-builder.js","sources":["../../../src/client/delete-builder.ts"],"sourcesContent":["import type {\n ExecutionContext,\n ExecutableBuilder,\n Result,\n WithSpecialColumns,\n ExecuteOptions,\n ExecuteMethodOptions,\n} from \"../types\";\nimport { getAcceptHeader } from \"../types\";\nimport type { FMTable, InferSchemaOutputFromFMTable } from \"../orm/table\";\nimport {\n getTableName,\n getTableId as getTableIdHelper,\n isUsingEntityIds,\n} from \"../orm/table\";\nimport { QueryBuilder } from \"./query-builder\";\nimport { type FFetchOptions } from \"@fetchkit/ffetch\";\nimport { parseErrorResponse } from \"./error-parser\";\n\n/**\n * Initial delete builder returned from EntitySet.delete()\n * Requires calling .byId() or .where() before .execute() is available\n */\nexport class DeleteBuilder<Occ extends FMTable<any, any>> {\n private databaseName: string;\n private context: ExecutionContext;\n private table: Occ;\n private databaseUseEntityIds: boolean;\n private databaseIncludeSpecialColumns: boolean;\n\n constructor(config: {\n occurrence: Occ;\n databaseName: string;\n context: ExecutionContext;\n databaseUseEntityIds?: boolean;\n databaseIncludeSpecialColumns?: boolean;\n }) {\n this.table = config.occurrence;\n this.databaseName = config.databaseName;\n this.context = config.context;\n this.databaseUseEntityIds = config.databaseUseEntityIds ?? false;\n this.databaseIncludeSpecialColumns =\n config.databaseIncludeSpecialColumns ?? false;\n }\n\n /**\n * Delete a single record by ID\n */\n byId(id: string | number): ExecutableDeleteBuilder<Occ> {\n return new ExecutableDeleteBuilder<Occ>({\n occurrence: this.table,\n databaseName: this.databaseName,\n context: this.context,\n mode: \"byId\",\n recordId: id,\n databaseUseEntityIds: this.databaseUseEntityIds,\n });\n }\n\n /**\n * Delete records matching a filter query\n * @param fn Callback that receives a QueryBuilder for building the filter\n */\n where(\n fn: (q: QueryBuilder<Occ>) => QueryBuilder<Occ>,\n ): ExecutableDeleteBuilder<Occ> {\n // Create a QueryBuilder for the user to configure\n const queryBuilder = new QueryBuilder<Occ>({\n occurrence: this.table,\n databaseName: this.databaseName,\n context: this.context,\n });\n\n // Let the user configure it\n const configuredBuilder = fn(queryBuilder);\n\n return new ExecutableDeleteBuilder<Occ>({\n occurrence: this.table,\n databaseName: this.databaseName,\n context: this.context,\n mode: \"byFilter\",\n queryBuilder: configuredBuilder,\n databaseUseEntityIds: this.databaseUseEntityIds,\n });\n }\n}\n\n/**\n * Executable delete builder - has execute() method\n * Returned after calling .byId() or .where()\n */\nexport class ExecutableDeleteBuilder<Occ extends FMTable<any, any>>\n implements ExecutableBuilder<{ deletedCount: number }>\n{\n private databaseName: string;\n private context: ExecutionContext;\n private table: Occ;\n private mode: \"byId\" | \"byFilter\";\n private recordId?: string | number;\n private queryBuilder?: QueryBuilder<Occ>;\n private databaseUseEntityIds: boolean;\n\n constructor(config: {\n occurrence: Occ;\n databaseName: string;\n context: ExecutionContext;\n mode: \"byId\" | \"byFilter\";\n recordId?: string | number;\n queryBuilder?: QueryBuilder<Occ>;\n databaseUseEntityIds?: boolean;\n }) {\n this.table = config.occurrence;\n this.databaseName = config.databaseName;\n this.context = config.context;\n this.mode = config.mode;\n this.recordId = config.recordId;\n this.queryBuilder = config.queryBuilder;\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: options?.useEntityIds ?? this.databaseUseEntityIds,\n };\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 const contextDefault = this.context._getUseEntityIds?.() ?? false;\n const shouldUseIds = useEntityIds ?? contextDefault;\n\n if (shouldUseIds) {\n if (!isUsingEntityIds(this.table)) {\n throw new Error(\n `useEntityIds is true but table \"${getTableName(this.table)}\" does not have entity IDs configured`,\n );\n }\n return getTableIdHelper(this.table);\n }\n\n return getTableName(this.table);\n }\n\n async execute(\n options?: ExecuteMethodOptions<ExecuteOptions>,\n ): Promise<Result<{ deletedCount: number }>> {\n // Merge database-level useEntityIds with per-request options\n const mergedOptions = this.mergeExecuteOptions(options);\n\n // Get table identifier with override support\n const tableId = this.getTableId(mergedOptions.useEntityIds);\n\n let url: string;\n\n if (this.mode === \"byId\") {\n // Delete single record by ID: DELETE /{database}/{table}('id')\n url = `/${this.databaseName}/${tableId}('${this.recordId}')`;\n } else {\n // Delete by filter: DELETE /{database}/{table}?$filter=...\n if (!this.queryBuilder) {\n throw new Error(\"Query builder is required for filter-based delete\");\n }\n\n // Get the query string from the configured QueryBuilder\n const queryString = this.queryBuilder.getQueryString();\n // Remove the leading \"/\" and table name from the query string as we'll build our own URL\n const tableName = getTableName(this.table);\n const queryParams = queryString.startsWith(`/${tableId}`)\n ? queryString.slice(`/${tableId}`.length)\n : queryString.startsWith(`/${tableName}`)\n ? queryString.slice(`/${tableName}`.length)\n : queryString;\n\n url = `/${this.databaseName}/${tableId}${queryParams}`;\n }\n\n // Make DELETE request\n const result = await this.context._makeRequest(url, {\n method: \"DELETE\",\n ...mergedOptions,\n });\n\n if (result.error) {\n return { data: undefined, error: result.error };\n }\n\n const response = result.data;\n\n // OData returns 204 No Content with fmodata.affected_rows header\n // The _makeRequest should handle extracting the header value\n // For now, we'll check if response contains the count\n let deletedCount = 0;\n\n if (typeof response === \"number\") {\n deletedCount = response;\n } else if (response && typeof response === \"object\") {\n // Check if the response has a count property (fallback)\n deletedCount = (response as any).deletedCount || 0;\n }\n\n return { data: { deletedCount }, error: undefined };\n }\n\n getRequestConfig(): { method: string; url: string; body?: any } {\n // For batch operations, use database-level setting (no per-request override available here)\n const tableId = this.getTableId(this.databaseUseEntityIds);\n\n let url: string;\n\n if (this.mode === \"byId\") {\n url = `/${this.databaseName}/${tableId}('${this.recordId}')`;\n } else {\n if (!this.queryBuilder) {\n throw new Error(\"Query builder is required for filter-based delete\");\n }\n\n const queryString = this.queryBuilder.getQueryString();\n const tableName = getTableName(this.table);\n const queryParams = queryString.startsWith(`/${tableId}`)\n ? queryString.slice(`/${tableId}`.length)\n : queryString.startsWith(`/${tableName}`)\n ? queryString.slice(`/${tableName}`.length)\n : queryString;\n\n url = `/${this.databaseName}/${tableId}${queryParams}`;\n }\n\n return {\n method: \"DELETE\",\n url,\n };\n }\n\n toRequest(baseUrl: string, options?: ExecuteOptions): 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 Accept: getAcceptHeader(options?.includeODataAnnotations),\n },\n });\n }\n\n async processResponse(\n response: Response,\n options?: ExecuteOptions,\n ): Promise<Result<{ deletedCount: number }>> {\n // Check for error responses (important for batch operations)\n if (!response.ok) {\n const tableName = getTableName(this.table);\n const error = await parseErrorResponse(\n response,\n response.url || `/${this.databaseName}/${tableName}`,\n );\n return { data: undefined, error };\n }\n\n // Check for empty response (204 No Content)\n const text = await response.text();\n if (!text || text.trim() === \"\") {\n // For 204 No Content, check the fmodata.affected_rows header\n const affectedRows = response.headers.get(\"fmodata.affected_rows\");\n const deletedCount = affectedRows ? parseInt(affectedRows, 10) : 1;\n return { data: { deletedCount }, error: undefined };\n }\n\n const rawResponse = JSON.parse(text);\n\n // OData returns 204 No Content with fmodata.affected_rows header\n // The _makeRequest should handle extracting the header value\n // For now, we'll check if response contains the count\n let deletedCount = 0;\n\n if (typeof rawResponse === \"number\") {\n deletedCount = rawResponse;\n } else if (rawResponse && typeof rawResponse === \"object\") {\n // Check if the response has a count property (fallback)\n deletedCount = (rawResponse as any).deletedCount || 0;\n }\n\n return { data: { deletedCount }, error: undefined };\n }\n}\n"],"names":["getTableIdHelper","deletedCount"],"mappings":"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"}
@@ -1,43 +1,49 @@
1
- import { z } from 'zod/v4';
2
- import { ExecutionContext, InferSchemaType, InsertData, UpdateData } from '../types.js';
3
- import { BaseTable } from './base-table.js';
4
- import { TableOccurrence } from './table-occurrence.js';
5
- import { QueryBuilder } from './query-builder.js';
1
+ import { ExecutionContext } from '../types.js';
2
+ import { QueryBuilder } from './query/index.js';
6
3
  import { RecordBuilder } from './record-builder.js';
7
4
  import { InsertBuilder } from './insert-builder.js';
8
5
  import { DeleteBuilder } from './delete-builder.js';
9
6
  import { UpdateBuilder } from './update-builder.js';
10
- type ExtractNavigationNames<O extends TableOccurrence<any, any, any, any> | undefined> = O extends TableOccurrence<any, any, infer Nav, any> ? Nav extends Record<string, any> ? keyof Nav & string : never : never;
11
- type ExtractSchemaFromOccurrence<O> = O extends TableOccurrence<infer BT, any, any, any> ? BT extends BaseTable<infer S, any> ? S : never : never;
12
- type ExtractDefaultSelect<O> = O extends TableOccurrence<infer BT, any, any, infer DefSelect> ? BT extends BaseTable<infer S, any> ? DefSelect extends "all" ? keyof S : DefSelect extends "schema" ? keyof S : DefSelect extends readonly (infer K)[] ? K & keyof S : keyof S : never : never;
13
- type ResolveNavigationItem<T> = T extends () => infer R ? R : T;
14
- type FindNavigationTarget<O extends TableOccurrence<any, any, any, any> | undefined, Name extends string> = O extends TableOccurrence<any, any, infer Nav, any> ? Nav extends Record<string, any> ? Name extends keyof Nav ? ResolveNavigationItem<Nav[Name]> : TableOccurrence<BaseTable<Record<string, z.ZodTypeAny>, any>, any, any, any> : TableOccurrence<BaseTable<Record<string, z.ZodTypeAny>, any>, any, any, any> : TableOccurrence<BaseTable<Record<string, z.ZodTypeAny>, any>, any, any, any>;
15
- export declare class EntitySet<Schema extends Record<string, z.ZodType> = any, Occ extends TableOccurrence<any, any, any, any> | undefined = undefined> {
16
- private occurrence?;
17
- private tableName;
7
+ import { Database } from './database.js';
8
+ import { FMTable, InferSchemaOutputFromFMTable, InsertDataFromFMTable, UpdateDataFromFMTable, ValidExpandTarget } from '../orm/table.js';
9
+ export declare class EntitySet<Occ extends FMTable<any, any>, DatabaseIncludeSpecialColumns extends boolean = false> {
10
+ private occurrence;
18
11
  private databaseName;
19
12
  private context;
13
+ private database;
20
14
  private isNavigateFromEntitySet?;
21
15
  private navigateRelation?;
22
16
  private navigateSourceTableName?;
17
+ private navigateBasePath?;
18
+ private databaseUseEntityIds;
19
+ private databaseIncludeSpecialColumns;
20
+ private logger;
23
21
  constructor(config: {
24
- occurrence?: Occ;
25
- tableName: string;
22
+ occurrence: Occ;
26
23
  databaseName: string;
27
24
  context: ExecutionContext;
25
+ database?: any;
28
26
  });
29
- static create<OccurrenceSchema extends Record<string, z.ZodType>, Occ extends TableOccurrence<BaseTable<OccurrenceSchema, any>, any, any, any> | undefined = undefined>(config: {
30
- occurrence?: Occ;
31
- tableName: string;
27
+ static create<Occ extends FMTable<any, any>, DatabaseIncludeSpecialColumns extends boolean = false>(config: {
28
+ occurrence: Occ;
32
29
  databaseName: string;
33
30
  context: ExecutionContext;
34
- }): EntitySet<OccurrenceSchema, Occ>;
35
- list(): QueryBuilder<InferSchemaType<Schema>, Occ extends TableOccurrence<any, any, any, any> ? ExtractDefaultSelect<Occ> : keyof InferSchemaType<Schema>, false, false, Occ>;
36
- get(id: string | number): RecordBuilder<InferSchemaType<Schema>, false, keyof InferSchemaType<Schema>, Occ>;
37
- insert(data: Occ extends TableOccurrence<infer BT, any, any, any> ? BT extends BaseTable<any, any, any, any> ? InsertData<BT> : Partial<InferSchemaType<Schema>> : Partial<InferSchemaType<Schema>>): InsertBuilder<InferSchemaType<Schema>, Occ>;
38
- update(data: Occ extends TableOccurrence<infer BT, any, any, any> ? BT extends BaseTable<any, any, any, any> ? UpdateData<BT> : Partial<InferSchemaType<Schema>> : Partial<InferSchemaType<Schema>>): UpdateBuilder<InferSchemaType<Schema>, Occ extends TableOccurrence<infer BT, any, any, any> ? BT extends BaseTable<any, any, any, any> ? BT : BaseTable<Schema, any, any, any> : BaseTable<Schema, any, any, any>>;
39
- delete(): DeleteBuilder<InferSchemaType<Schema>>;
40
- navigate<RelationName extends ExtractNavigationNames<Occ>>(relationName: RelationName): EntitySet<ExtractSchemaFromOccurrence<FindNavigationTarget<Occ, RelationName>> extends Record<string, z.ZodType> ? ExtractSchemaFromOccurrence<FindNavigationTarget<Occ, RelationName>> : Record<string, z.ZodTypeAny>, FindNavigationTarget<Occ, RelationName>>;
41
- navigate(relationName: string): EntitySet<Record<string, z.ZodTypeAny>, undefined>;
31
+ database: Database<DatabaseIncludeSpecialColumns>;
32
+ }): EntitySet<Occ, DatabaseIncludeSpecialColumns>;
33
+ list(): QueryBuilder<Occ, keyof InferSchemaOutputFromFMTable<Occ>, false, false, {}, DatabaseIncludeSpecialColumns>;
34
+ get(id: string | number): RecordBuilder<Occ, false, undefined, keyof InferSchemaOutputFromFMTable<Occ>, {}, DatabaseIncludeSpecialColumns>;
35
+ insert(data: InsertDataFromFMTable<Occ>, options: {
36
+ returnFullRecord: false;
37
+ }): InsertBuilder<Occ, "minimal">;
38
+ insert(data: InsertDataFromFMTable<Occ>, options?: {
39
+ returnFullRecord?: true;
40
+ }): InsertBuilder<Occ, "representation">;
41
+ update(data: UpdateDataFromFMTable<Occ>, options: {
42
+ returnFullRecord: true;
43
+ }): UpdateBuilder<Occ, "representation">;
44
+ update(data: UpdateDataFromFMTable<Occ>, options?: {
45
+ returnFullRecord?: false;
46
+ }): UpdateBuilder<Occ, "minimal">;
47
+ delete(): DeleteBuilder<Occ>;
48
+ navigate<TargetTable extends FMTable<any, any>>(targetTable: ValidExpandTarget<Occ, TargetTable>): EntitySet<TargetTable extends FMTable<any, any> ? TargetTable : never, DatabaseIncludeSpecialColumns>;
42
49
  }
43
- export {};