@proofkit/fmodata 0.1.0-alpha.9 → 0.1.0-beta.24
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/LICENSE.md +21 -0
- package/README.md +655 -453
- package/dist/esm/client/batch-builder.d.ts +10 -9
- package/dist/esm/client/batch-builder.js +119 -56
- package/dist/esm/client/batch-builder.js.map +1 -1
- package/dist/esm/client/batch-request.js +16 -21
- package/dist/esm/client/batch-request.js.map +1 -1
- package/dist/esm/client/builders/default-select.d.ts +10 -0
- package/dist/esm/client/builders/default-select.js +41 -0
- package/dist/esm/client/builders/default-select.js.map +1 -0
- package/dist/esm/client/builders/expand-builder.d.ts +45 -0
- package/dist/esm/client/builders/expand-builder.js +185 -0
- package/dist/esm/client/builders/expand-builder.js.map +1 -0
- package/dist/esm/client/builders/index.d.ts +9 -0
- package/dist/esm/client/builders/query-string-builder.d.ts +18 -0
- package/dist/esm/client/builders/query-string-builder.js +21 -0
- package/dist/esm/client/builders/query-string-builder.js.map +1 -0
- package/dist/esm/client/builders/response-processor.d.ts +43 -0
- package/dist/esm/client/builders/response-processor.js +175 -0
- package/dist/esm/client/builders/response-processor.js.map +1 -0
- package/dist/esm/client/builders/select-mixin.d.ts +25 -0
- package/dist/esm/client/builders/select-mixin.js +28 -0
- package/dist/esm/client/builders/select-mixin.js.map +1 -0
- package/dist/esm/client/builders/select-utils.d.ts +18 -0
- package/dist/esm/client/builders/select-utils.js +30 -0
- package/dist/esm/client/builders/select-utils.js.map +1 -0
- package/dist/esm/client/builders/shared-types.d.ts +40 -0
- package/dist/esm/client/builders/table-utils.d.ts +35 -0
- package/dist/esm/client/builders/table-utils.js +44 -0
- package/dist/esm/client/builders/table-utils.js.map +1 -0
- package/dist/esm/client/database.d.ts +34 -22
- package/dist/esm/client/database.js +48 -84
- package/dist/esm/client/database.js.map +1 -1
- package/dist/esm/client/delete-builder.d.ts +25 -30
- package/dist/esm/client/delete-builder.js +45 -30
- package/dist/esm/client/delete-builder.js.map +1 -1
- package/dist/esm/client/entity-set.d.ts +35 -43
- package/dist/esm/client/entity-set.js +126 -52
- package/dist/esm/client/entity-set.js.map +1 -1
- package/dist/esm/client/error-parser.d.ts +12 -0
- package/dist/esm/client/error-parser.js +25 -0
- package/dist/esm/client/error-parser.js.map +1 -0
- package/dist/esm/client/filemaker-odata.d.ts +26 -7
- package/dist/esm/client/filemaker-odata.js +65 -42
- package/dist/esm/client/filemaker-odata.js.map +1 -1
- package/dist/esm/client/insert-builder.d.ts +19 -24
- package/dist/esm/client/insert-builder.js +94 -58
- package/dist/esm/client/insert-builder.js.map +1 -1
- package/dist/esm/client/query/expand-builder.d.ts +35 -0
- package/dist/esm/client/query/index.d.ts +4 -0
- package/dist/esm/client/query/query-builder.d.ts +132 -0
- package/dist/esm/client/query/query-builder.js +456 -0
- package/dist/esm/client/query/query-builder.js.map +1 -0
- package/dist/esm/client/query/response-processor.d.ts +25 -0
- package/dist/esm/client/query/types.d.ts +77 -0
- package/dist/esm/client/query/url-builder.d.ts +71 -0
- package/dist/esm/client/query/url-builder.js +100 -0
- package/dist/esm/client/query/url-builder.js.map +1 -0
- package/dist/esm/client/query-builder.d.ts +2 -115
- package/dist/esm/client/record-builder.d.ts +108 -36
- package/dist/esm/client/record-builder.js +284 -119
- package/dist/esm/client/record-builder.js.map +1 -1
- package/dist/esm/client/response-processor.d.ts +4 -9
- package/dist/esm/client/sanitize-json.d.ts +35 -0
- package/dist/esm/client/sanitize-json.js +27 -0
- package/dist/esm/client/sanitize-json.js.map +1 -0
- package/dist/esm/client/schema-manager.d.ts +5 -5
- package/dist/esm/client/schema-manager.js +45 -31
- package/dist/esm/client/schema-manager.js.map +1 -1
- package/dist/esm/client/update-builder.d.ts +34 -40
- package/dist/esm/client/update-builder.js +99 -58
- package/dist/esm/client/update-builder.js.map +1 -1
- package/dist/esm/client/webhook-builder.d.ts +126 -0
- package/dist/esm/client/webhook-builder.js +189 -0
- package/dist/esm/client/webhook-builder.js.map +1 -0
- package/dist/esm/errors.d.ts +19 -2
- package/dist/esm/errors.js +39 -4
- package/dist/esm/errors.js.map +1 -1
- package/dist/esm/index.d.ts +10 -8
- package/dist/esm/index.js +40 -10
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/logger.d.ts +47 -0
- package/dist/esm/logger.js +69 -0
- package/dist/esm/logger.js.map +1 -0
- package/dist/esm/logger.test.d.ts +1 -0
- package/dist/esm/orm/column.d.ts +62 -0
- package/dist/esm/orm/column.js +63 -0
- package/dist/esm/orm/column.js.map +1 -0
- package/dist/esm/orm/field-builders.d.ts +164 -0
- package/dist/esm/orm/field-builders.js +158 -0
- package/dist/esm/orm/field-builders.js.map +1 -0
- package/dist/esm/orm/index.d.ts +5 -0
- package/dist/esm/orm/operators.d.ts +173 -0
- package/dist/esm/orm/operators.js +260 -0
- package/dist/esm/orm/operators.js.map +1 -0
- package/dist/esm/orm/table.d.ts +355 -0
- package/dist/esm/orm/table.js +202 -0
- package/dist/esm/orm/table.js.map +1 -0
- package/dist/esm/transform.d.ts +20 -21
- package/dist/esm/transform.js +44 -45
- package/dist/esm/transform.js.map +1 -1
- package/dist/esm/types.d.ts +96 -30
- package/dist/esm/types.js +7 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/esm/validation.d.ts +22 -12
- package/dist/esm/validation.js +132 -85
- package/dist/esm/validation.js.map +1 -1
- package/package.json +34 -29
- package/src/client/batch-builder.ts +153 -89
- package/src/client/batch-request.ts +25 -41
- package/src/client/builders/default-select.ts +75 -0
- package/src/client/builders/expand-builder.ts +246 -0
- package/src/client/builders/index.ts +11 -0
- package/src/client/builders/query-string-builder.ts +46 -0
- package/src/client/builders/response-processor.ts +279 -0
- package/src/client/builders/select-mixin.ts +65 -0
- package/src/client/builders/select-utils.ts +59 -0
- package/src/client/builders/shared-types.ts +45 -0
- package/src/client/builders/table-utils.ts +83 -0
- package/src/client/database.ts +89 -183
- package/src/client/delete-builder.ts +74 -84
- package/src/client/entity-set.ts +286 -293
- package/src/client/error-parser.ts +41 -0
- package/src/client/filemaker-odata.ts +98 -66
- package/src/client/insert-builder.ts +157 -118
- package/src/client/query/expand-builder.ts +160 -0
- package/src/client/query/index.ts +14 -0
- package/src/client/query/query-builder.ts +729 -0
- package/src/client/query/response-processor.ts +226 -0
- package/src/client/query/types.ts +126 -0
- package/src/client/query/url-builder.ts +151 -0
- package/src/client/query-builder.ts +10 -1455
- package/src/client/record-builder.ts +575 -240
- package/src/client/response-processor.ts +15 -42
- package/src/client/sanitize-json.ts +64 -0
- package/src/client/schema-manager.ts +61 -76
- package/src/client/update-builder.ts +161 -143
- package/src/client/webhook-builder.ts +265 -0
- package/src/errors.ts +49 -16
- package/src/index.ts +99 -54
- package/src/logger.test.ts +34 -0
- package/src/logger.ts +116 -0
- package/src/orm/column.ts +106 -0
- package/src/orm/field-builders.ts +250 -0
- package/src/orm/index.ts +61 -0
- package/src/orm/operators.ts +473 -0
- package/src/orm/table.ts +741 -0
- package/src/transform.ts +90 -70
- package/src/types.ts +154 -113
- package/src/validation.ts +200 -115
- package/dist/esm/client/base-table.d.ts +0 -125
- package/dist/esm/client/base-table.js +0 -57
- package/dist/esm/client/base-table.js.map +0 -1
- package/dist/esm/client/query-builder.js +0 -896
- package/dist/esm/client/query-builder.js.map +0 -1
- package/dist/esm/client/table-occurrence.d.ts +0 -72
- package/dist/esm/client/table-occurrence.js +0 -74
- package/dist/esm/client/table-occurrence.js.map +0 -1
- package/dist/esm/filter-types.d.ts +0 -76
- package/src/client/base-table.ts +0 -175
- package/src/client/query-builder.ts.bak +0 -1457
- package/src/client/table-occurrence.ts +0 -175
- package/src/filter-types.ts +0 -97
|
@@ -1,28 +1,29 @@
|
|
|
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 {
|
|
5
|
-
import {
|
|
4
|
+
import { isUsingEntityIds, getTableName, getTableId } from "../orm/table.js";
|
|
5
|
+
import { getAcceptHeader } from "../types.js";
|
|
6
|
+
import { parseErrorResponse } from "./error-parser.js";
|
|
7
|
+
import { QueryBuilder } from "./query/query-builder.js";
|
|
6
8
|
class DeleteBuilder {
|
|
7
9
|
constructor(config) {
|
|
8
|
-
__publicField(this, "tableName");
|
|
9
10
|
__publicField(this, "databaseName");
|
|
10
11
|
__publicField(this, "context");
|
|
11
|
-
__publicField(this, "
|
|
12
|
+
__publicField(this, "table");
|
|
12
13
|
__publicField(this, "databaseUseEntityIds");
|
|
13
|
-
this
|
|
14
|
-
this.
|
|
14
|
+
__publicField(this, "databaseIncludeSpecialColumns");
|
|
15
|
+
this.table = config.occurrence;
|
|
15
16
|
this.databaseName = config.databaseName;
|
|
16
17
|
this.context = config.context;
|
|
17
18
|
this.databaseUseEntityIds = config.databaseUseEntityIds ?? false;
|
|
19
|
+
this.databaseIncludeSpecialColumns = config.databaseIncludeSpecialColumns ?? false;
|
|
18
20
|
}
|
|
19
21
|
/**
|
|
20
22
|
* Delete a single record by ID
|
|
21
23
|
*/
|
|
22
24
|
byId(id) {
|
|
23
25
|
return new ExecutableDeleteBuilder({
|
|
24
|
-
occurrence: this.
|
|
25
|
-
tableName: this.tableName,
|
|
26
|
+
occurrence: this.table,
|
|
26
27
|
databaseName: this.databaseName,
|
|
27
28
|
context: this.context,
|
|
28
29
|
mode: "byId",
|
|
@@ -36,15 +37,13 @@ class DeleteBuilder {
|
|
|
36
37
|
*/
|
|
37
38
|
where(fn) {
|
|
38
39
|
const queryBuilder = new QueryBuilder({
|
|
39
|
-
occurrence:
|
|
40
|
-
tableName: this.tableName,
|
|
40
|
+
occurrence: this.table,
|
|
41
41
|
databaseName: this.databaseName,
|
|
42
42
|
context: this.context
|
|
43
43
|
});
|
|
44
44
|
const configuredBuilder = fn(queryBuilder);
|
|
45
45
|
return new ExecutableDeleteBuilder({
|
|
46
|
-
occurrence: this.
|
|
47
|
-
tableName: this.tableName,
|
|
46
|
+
occurrence: this.table,
|
|
48
47
|
databaseName: this.databaseName,
|
|
49
48
|
context: this.context,
|
|
50
49
|
mode: "byFilter",
|
|
@@ -55,16 +54,14 @@ class DeleteBuilder {
|
|
|
55
54
|
}
|
|
56
55
|
class ExecutableDeleteBuilder {
|
|
57
56
|
constructor(config) {
|
|
58
|
-
__publicField(this, "tableName");
|
|
59
57
|
__publicField(this, "databaseName");
|
|
60
58
|
__publicField(this, "context");
|
|
61
|
-
__publicField(this, "
|
|
59
|
+
__publicField(this, "table");
|
|
62
60
|
__publicField(this, "mode");
|
|
63
61
|
__publicField(this, "recordId");
|
|
64
62
|
__publicField(this, "queryBuilder");
|
|
65
63
|
__publicField(this, "databaseUseEntityIds");
|
|
66
|
-
this.
|
|
67
|
-
this.tableName = config.tableName;
|
|
64
|
+
this.table = config.occurrence;
|
|
68
65
|
this.databaseName = config.databaseName;
|
|
69
66
|
this.context = config.context;
|
|
70
67
|
this.mode = config.mode;
|
|
@@ -87,21 +84,17 @@ class ExecutableDeleteBuilder {
|
|
|
87
84
|
*/
|
|
88
85
|
getTableId(useEntityIds) {
|
|
89
86
|
var _a, _b;
|
|
90
|
-
if (!this.occurrence) {
|
|
91
|
-
return this.tableName;
|
|
92
|
-
}
|
|
93
87
|
const contextDefault = ((_b = (_a = this.context)._getUseEntityIds) == null ? void 0 : _b.call(_a)) ?? false;
|
|
94
88
|
const shouldUseIds = useEntityIds ?? contextDefault;
|
|
95
89
|
if (shouldUseIds) {
|
|
96
|
-
|
|
97
|
-
if (!identifiers.id) {
|
|
90
|
+
if (!isUsingEntityIds(this.table)) {
|
|
98
91
|
throw new Error(
|
|
99
|
-
`useEntityIds is true but
|
|
92
|
+
`useEntityIds is true but table "${getTableName(this.table)}" does not have entity IDs configured`
|
|
100
93
|
);
|
|
101
94
|
}
|
|
102
|
-
return
|
|
95
|
+
return getTableId(this.table);
|
|
103
96
|
}
|
|
104
|
-
return this.
|
|
97
|
+
return getTableName(this.table);
|
|
105
98
|
}
|
|
106
99
|
async execute(options) {
|
|
107
100
|
const mergedOptions = this.mergeExecuteOptions(options);
|
|
@@ -114,7 +107,15 @@ class ExecutableDeleteBuilder {
|
|
|
114
107
|
throw new Error("Query builder is required for filter-based delete");
|
|
115
108
|
}
|
|
116
109
|
const queryString = this.queryBuilder.getQueryString();
|
|
117
|
-
const
|
|
110
|
+
const tableName = getTableName(this.table);
|
|
111
|
+
let queryParams;
|
|
112
|
+
if (queryString.startsWith(`/${tableId}`)) {
|
|
113
|
+
queryParams = queryString.slice(`/${tableId}`.length);
|
|
114
|
+
} else if (queryString.startsWith(`/${tableName}`)) {
|
|
115
|
+
queryParams = queryString.slice(`/${tableName}`.length);
|
|
116
|
+
} else {
|
|
117
|
+
queryParams = queryString;
|
|
118
|
+
}
|
|
118
119
|
url = `/${this.databaseName}/${tableId}${queryParams}`;
|
|
119
120
|
}
|
|
120
121
|
const result = await this.context._makeRequest(url, {
|
|
@@ -133,6 +134,7 @@ class ExecutableDeleteBuilder {
|
|
|
133
134
|
}
|
|
134
135
|
return { data: { deletedCount }, error: void 0 };
|
|
135
136
|
}
|
|
137
|
+
// biome-ignore lint/suspicious/noExplicitAny: Request body can be any JSON-serializable value
|
|
136
138
|
getRequestConfig() {
|
|
137
139
|
const tableId = this.getTableId(this.databaseUseEntityIds);
|
|
138
140
|
let url;
|
|
@@ -143,7 +145,15 @@ class ExecutableDeleteBuilder {
|
|
|
143
145
|
throw new Error("Query builder is required for filter-based delete");
|
|
144
146
|
}
|
|
145
147
|
const queryString = this.queryBuilder.getQueryString();
|
|
146
|
-
const
|
|
148
|
+
const tableName = getTableName(this.table);
|
|
149
|
+
let queryParams;
|
|
150
|
+
if (queryString.startsWith(`/${tableId}`)) {
|
|
151
|
+
queryParams = queryString.slice(`/${tableId}`.length);
|
|
152
|
+
} else if (queryString.startsWith(`/${tableName}`)) {
|
|
153
|
+
queryParams = queryString.slice(`/${tableName}`.length);
|
|
154
|
+
} else {
|
|
155
|
+
queryParams = queryString;
|
|
156
|
+
}
|
|
147
157
|
url = `/${this.databaseName}/${tableId}${queryParams}`;
|
|
148
158
|
}
|
|
149
159
|
return {
|
|
@@ -151,21 +161,26 @@ class ExecutableDeleteBuilder {
|
|
|
151
161
|
url
|
|
152
162
|
};
|
|
153
163
|
}
|
|
154
|
-
toRequest(baseUrl) {
|
|
164
|
+
toRequest(baseUrl, options) {
|
|
155
165
|
const config = this.getRequestConfig();
|
|
156
166
|
const fullUrl = `${baseUrl}${config.url}`;
|
|
157
167
|
return new Request(fullUrl, {
|
|
158
168
|
method: config.method,
|
|
159
169
|
headers: {
|
|
160
|
-
Accept:
|
|
170
|
+
Accept: getAcceptHeader(options == null ? void 0 : options.includeODataAnnotations)
|
|
161
171
|
}
|
|
162
172
|
});
|
|
163
173
|
}
|
|
164
|
-
async processResponse(response,
|
|
174
|
+
async processResponse(response, _options) {
|
|
175
|
+
if (!response.ok) {
|
|
176
|
+
const tableName = getTableName(this.table);
|
|
177
|
+
const error = await parseErrorResponse(response, response.url || `/${this.databaseName}/${tableName}`);
|
|
178
|
+
return { data: void 0, error };
|
|
179
|
+
}
|
|
165
180
|
const text = await response.text();
|
|
166
181
|
if (!text || text.trim() === "") {
|
|
167
182
|
const affectedRows = response.headers.get("fmodata.affected_rows");
|
|
168
|
-
const deletedCount2 = affectedRows ? parseInt(affectedRows, 10) : 1;
|
|
183
|
+
const deletedCount2 = affectedRows ? Number.parseInt(affectedRows, 10) : 1;
|
|
169
184
|
return { data: { deletedCount: deletedCount2 }, error: void 0 };
|
|
170
185
|
}
|
|
171
186
|
const rawResponse = JSON.parse(text);
|
|
@@ -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 ExecuteOptions,\n} from \"../types\";\nimport type { TableOccurrence } from \"./table-occurrence\";\nimport { QueryBuilder } from \"./query-builder\";\nimport { type FFetchOptions } from \"@fetchkit/ffetch\";\nimport { getTableIdentifiers } from \"../transform\";\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 private databaseUseEntityIds: boolean;\n\n constructor(config: {\n occurrence?: TableOccurrence<any, any, any, any>;\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 * 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 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: (\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 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<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 private databaseUseEntityIds: boolean;\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 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.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 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 async execute(\n options?: RequestInit & FFetchOptions & { useEntityIds?: boolean },\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 queryParams = queryString.startsWith(`/${tableId}`)\n ? queryString.slice(`/${tableId}`.length)\n : queryString.startsWith(`/${this.tableName}`)\n ? queryString.slice(`/${this.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 queryParams = queryString.startsWith(`/${tableId}`)\n ? queryString.slice(`/${tableId}`.length)\n : queryString.startsWith(`/${this.tableName}`)\n ? queryString.slice(`/${this.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): 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: \"application/json\",\n },\n });\n }\n\n async processResponse(\n response: Response,\n options?: ExecuteOptions,\n ): Promise<Result<{ deletedCount: number }>> {\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":["deletedCount"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"delete-builder.js","sources":["../../../src/client/delete-builder.ts"],"sourcesContent":["import type { FFetchOptions } from \"@fetchkit/ffetch\";\nimport type { FMTable } from \"../orm/table\";\nimport { getTableId as getTableIdHelper, getTableName, isUsingEntityIds } from \"../orm/table\";\nimport type { ExecutableBuilder, ExecuteMethodOptions, ExecuteOptions, ExecutionContext, Result } from \"../types\";\nimport { getAcceptHeader } from \"../types\";\nimport { parseErrorResponse } from \"./error-parser\";\nimport { QueryBuilder } from \"./query-builder\";\n\n/**\n * Initial delete builder returned from EntitySet.delete()\n * Requires calling .byId() or .where() before .execute() is available\n */\n// biome-ignore lint/suspicious/noExplicitAny: Accepts any FMTable configuration\nexport class DeleteBuilder<Occ extends FMTable<any, any>> {\n private readonly databaseName: string;\n private readonly context: ExecutionContext;\n private readonly table: Occ;\n private readonly databaseUseEntityIds: boolean;\n private readonly 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 = 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(fn: (q: QueryBuilder<Occ>) => QueryBuilder<Occ>): 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 */\n// biome-ignore lint/suspicious/noExplicitAny: Accepts any FMTable configuration\nexport class ExecutableDeleteBuilder<Occ extends FMTable<any, any>>\n implements ExecutableBuilder<{ deletedCount: number }>\n{\n private readonly databaseName: string;\n private readonly context: ExecutionContext;\n private readonly table: Occ;\n private readonly mode: \"byId\" | \"byFilter\";\n private readonly recordId?: string | number;\n private readonly queryBuilder?: QueryBuilder<Occ>;\n private readonly 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(options?: ExecuteMethodOptions<ExecuteOptions>): 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 let queryParams: string;\n if (queryString.startsWith(`/${tableId}`)) {\n queryParams = queryString.slice(`/${tableId}`.length);\n } else if (queryString.startsWith(`/${tableName}`)) {\n queryParams = queryString.slice(`/${tableName}`.length);\n } else {\n queryParams = queryString;\n }\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 // biome-ignore lint/suspicious/noExplicitAny: Dynamic response type from OData API\n deletedCount = (response as any).deletedCount || 0;\n }\n\n return { data: { deletedCount }, error: undefined };\n }\n\n // biome-ignore lint/suspicious/noExplicitAny: Request body can be any JSON-serializable value\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 let queryParams: string;\n if (queryString.startsWith(`/${tableId}`)) {\n queryParams = queryString.slice(`/${tableId}`.length);\n } else if (queryString.startsWith(`/${tableName}`)) {\n queryParams = queryString.slice(`/${tableName}`.length);\n } else {\n queryParams = queryString;\n }\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(response: Response, _options?: ExecuteOptions): 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(response, response.url || `/${this.databaseName}/${tableName}`);\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 ? Number.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 // biome-ignore lint/suspicious/noExplicitAny: Dynamic response type from OData API\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,57 +1,49 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { TableOccurrence } from './table-occurrence.js';
|
|
5
|
-
import { QueryBuilder } from './query-builder.js';
|
|
6
|
-
import { RecordBuilder } from './record-builder.js';
|
|
7
|
-
import { InsertBuilder } from './insert-builder.js';
|
|
1
|
+
import { FMTable, InferSchemaOutputFromFMTable, InsertDataFromFMTable, UpdateDataFromFMTable, ValidExpandTarget } from '../orm/table.js';
|
|
2
|
+
import { ExecutionContext } from '../types.js';
|
|
3
|
+
import { Database } from './database.js';
|
|
8
4
|
import { DeleteBuilder } from './delete-builder.js';
|
|
5
|
+
import { InsertBuilder } from './insert-builder.js';
|
|
6
|
+
import { QueryBuilder } from './query/index.js';
|
|
7
|
+
import { RecordBuilder } from './record-builder.js';
|
|
9
8
|
import { UpdateBuilder } from './update-builder.js';
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
private
|
|
18
|
-
private
|
|
19
|
-
private
|
|
20
|
-
private
|
|
21
|
-
private
|
|
22
|
-
private isNavigateFromEntitySet?;
|
|
23
|
-
private navigateRelation?;
|
|
24
|
-
private navigateSourceTableName?;
|
|
9
|
+
export declare class EntitySet<Occ extends FMTable<any, any>, DatabaseIncludeSpecialColumns extends boolean = false> {
|
|
10
|
+
private readonly occurrence;
|
|
11
|
+
private readonly databaseName;
|
|
12
|
+
private readonly context;
|
|
13
|
+
private readonly database;
|
|
14
|
+
private readonly isNavigateFromEntitySet?;
|
|
15
|
+
private readonly navigateRelation?;
|
|
16
|
+
private readonly navigateSourceTableName?;
|
|
17
|
+
private readonly navigateBasePath?;
|
|
18
|
+
private readonly databaseUseEntityIds;
|
|
19
|
+
private readonly databaseIncludeSpecialColumns;
|
|
20
|
+
private readonly logger;
|
|
25
21
|
constructor(config: {
|
|
26
|
-
occurrence
|
|
27
|
-
tableName: string;
|
|
22
|
+
occurrence: Occ;
|
|
28
23
|
databaseName: string;
|
|
29
24
|
context: ExecutionContext;
|
|
30
25
|
database?: any;
|
|
31
26
|
});
|
|
32
|
-
static create<
|
|
33
|
-
occurrence
|
|
34
|
-
tableName: string;
|
|
27
|
+
static create<Occ extends FMTable<any, any>, DatabaseIncludeSpecialColumns extends boolean = false>(config: {
|
|
28
|
+
occurrence: Occ;
|
|
35
29
|
databaseName: string;
|
|
36
30
|
context: ExecutionContext;
|
|
37
|
-
database: Database<
|
|
38
|
-
}): EntitySet<
|
|
39
|
-
list(): QueryBuilder<
|
|
40
|
-
get(id: string | number): RecordBuilder<
|
|
41
|
-
insert(data: Occ
|
|
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: {
|
|
42
36
|
returnFullRecord: false;
|
|
43
|
-
}): InsertBuilder<
|
|
44
|
-
insert(data: Occ
|
|
37
|
+
}): InsertBuilder<Occ, "minimal">;
|
|
38
|
+
insert(data: InsertDataFromFMTable<Occ>, options?: {
|
|
45
39
|
returnFullRecord?: true;
|
|
46
|
-
}): InsertBuilder<
|
|
47
|
-
update(data: Occ
|
|
40
|
+
}): InsertBuilder<Occ, "representation">;
|
|
41
|
+
update(data: UpdateDataFromFMTable<Occ>, options: {
|
|
48
42
|
returnFullRecord: true;
|
|
49
|
-
}): UpdateBuilder<
|
|
50
|
-
update(data: Occ
|
|
43
|
+
}): UpdateBuilder<Occ, "representation">;
|
|
44
|
+
update(data: UpdateDataFromFMTable<Occ>, options?: {
|
|
51
45
|
returnFullRecord?: false;
|
|
52
|
-
}): UpdateBuilder<
|
|
53
|
-
delete(): DeleteBuilder<
|
|
54
|
-
navigate<
|
|
55
|
-
navigate(relationName: string): EntitySet<Record<string, StandardSchemaV1>, undefined>;
|
|
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>;
|
|
56
49
|
}
|
|
57
|
-
export {};
|
|
@@ -1,15 +1,16 @@
|
|
|
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 {
|
|
5
|
-
import {
|
|
6
|
-
import { InsertBuilder } from "./insert-builder.js";
|
|
4
|
+
import { createLogger } from "../logger.js";
|
|
5
|
+
import { getDefaultSelect, getTableSchema, getTableColumns, getTableName, FMTable } from "../orm/table.js";
|
|
7
6
|
import { DeleteBuilder } from "./delete-builder.js";
|
|
7
|
+
import { InsertBuilder } from "./insert-builder.js";
|
|
8
|
+
import { QueryBuilder } from "./query/query-builder.js";
|
|
9
|
+
import { RecordBuilder } from "./record-builder.js";
|
|
8
10
|
import { UpdateBuilder } from "./update-builder.js";
|
|
9
11
|
class EntitySet {
|
|
10
12
|
constructor(config) {
|
|
11
13
|
__publicField(this, "occurrence");
|
|
12
|
-
__publicField(this, "tableName");
|
|
13
14
|
__publicField(this, "databaseName");
|
|
14
15
|
__publicField(this, "context");
|
|
15
16
|
__publicField(this, "database");
|
|
@@ -17,120 +18,193 @@ class EntitySet {
|
|
|
17
18
|
__publicField(this, "isNavigateFromEntitySet");
|
|
18
19
|
__publicField(this, "navigateRelation");
|
|
19
20
|
__publicField(this, "navigateSourceTableName");
|
|
21
|
+
__publicField(this, "navigateBasePath");
|
|
22
|
+
// Full base path for chained navigations
|
|
23
|
+
__publicField(this, "databaseUseEntityIds");
|
|
24
|
+
__publicField(this, "databaseIncludeSpecialColumns");
|
|
25
|
+
__publicField(this, "logger");
|
|
26
|
+
var _a, _b, _c, _d;
|
|
20
27
|
this.occurrence = config.occurrence;
|
|
21
|
-
this.tableName = config.tableName;
|
|
22
28
|
this.databaseName = config.databaseName;
|
|
23
29
|
this.context = config.context;
|
|
24
30
|
this.database = config.database;
|
|
31
|
+
this.databaseUseEntityIds = ((_a = config.database) == null ? void 0 : _a._getUseEntityIds) ?? false;
|
|
32
|
+
this.databaseIncludeSpecialColumns = ((_b = config.database) == null ? void 0 : _b._getIncludeSpecialColumns) ?? false;
|
|
33
|
+
this.logger = ((_d = (_c = config.context) == null ? void 0 : _c._getLogger) == null ? void 0 : _d.call(_c)) ?? createLogger();
|
|
25
34
|
}
|
|
26
|
-
// Type-only method to help TypeScript infer the schema from
|
|
35
|
+
// Type-only method to help TypeScript infer the schema from table
|
|
36
|
+
// biome-ignore lint/suspicious/noExplicitAny: Accepts any FMTable configuration
|
|
27
37
|
static create(config) {
|
|
28
38
|
return new EntitySet({
|
|
29
39
|
occurrence: config.occurrence,
|
|
30
|
-
tableName: config.tableName,
|
|
31
40
|
databaseName: config.databaseName,
|
|
32
41
|
context: config.context,
|
|
33
42
|
database: config.database
|
|
34
43
|
});
|
|
35
44
|
}
|
|
45
|
+
// biome-ignore lint/complexity/noBannedTypes: Empty object type represents no expands by default
|
|
36
46
|
list() {
|
|
37
|
-
var _a;
|
|
38
47
|
const builder = new QueryBuilder({
|
|
39
48
|
occurrence: this.occurrence,
|
|
40
|
-
tableName: this.tableName,
|
|
41
49
|
databaseName: this.databaseName,
|
|
42
50
|
context: this.context,
|
|
43
|
-
databaseUseEntityIds:
|
|
51
|
+
databaseUseEntityIds: this.databaseUseEntityIds,
|
|
52
|
+
databaseIncludeSpecialColumns: this.databaseIncludeSpecialColumns
|
|
44
53
|
});
|
|
45
54
|
if (this.occurrence) {
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
const defaultSelectValue = getDefaultSelect(this.occurrence);
|
|
56
|
+
getTableSchema(this.occurrence);
|
|
57
|
+
if (defaultSelectValue === "schema") {
|
|
58
|
+
const allColumns = getTableColumns(this.occurrence);
|
|
59
|
+
const systemColumns = this.databaseIncludeSpecialColumns ? { ROWID: true, ROWMODID: true } : void 0;
|
|
60
|
+
const selectedBuilder = builder.select(allColumns, systemColumns).top(1e3);
|
|
61
|
+
if (this.isNavigateFromEntitySet && this.navigateRelation && this.navigateSourceTableName) {
|
|
62
|
+
selectedBuilder.navigation = {
|
|
63
|
+
relation: this.navigateRelation,
|
|
64
|
+
sourceTableName: this.navigateSourceTableName,
|
|
65
|
+
basePath: this.navigateBasePath
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
return selectedBuilder;
|
|
69
|
+
}
|
|
70
|
+
if (typeof defaultSelectValue === "object") {
|
|
71
|
+
const selectedBuilder = builder.select(defaultSelectValue).top(1e3);
|
|
72
|
+
if (this.isNavigateFromEntitySet && this.navigateRelation && this.navigateSourceTableName) {
|
|
73
|
+
selectedBuilder.navigation = {
|
|
74
|
+
relation: this.navigateRelation,
|
|
75
|
+
sourceTableName: this.navigateSourceTableName,
|
|
76
|
+
basePath: this.navigateBasePath
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
return selectedBuilder;
|
|
57
80
|
}
|
|
58
81
|
}
|
|
59
|
-
if (this.isNavigateFromEntitySet) {
|
|
60
|
-
builder.
|
|
61
|
-
|
|
62
|
-
|
|
82
|
+
if (this.isNavigateFromEntitySet && this.navigateRelation && this.navigateSourceTableName) {
|
|
83
|
+
builder.navigation = {
|
|
84
|
+
relation: this.navigateRelation,
|
|
85
|
+
sourceTableName: this.navigateSourceTableName,
|
|
86
|
+
basePath: this.navigateBasePath
|
|
87
|
+
// recordId is intentionally not set (undefined) to indicate navigation from EntitySet
|
|
88
|
+
};
|
|
63
89
|
}
|
|
64
90
|
return builder.top(1e3);
|
|
65
91
|
}
|
|
66
92
|
get(id) {
|
|
67
|
-
var _a;
|
|
68
93
|
const builder = new RecordBuilder({
|
|
69
94
|
occurrence: this.occurrence,
|
|
70
|
-
tableName: this.tableName,
|
|
71
95
|
databaseName: this.databaseName,
|
|
72
96
|
context: this.context,
|
|
73
97
|
recordId: id,
|
|
74
|
-
databaseUseEntityIds:
|
|
98
|
+
databaseUseEntityIds: this.databaseUseEntityIds,
|
|
99
|
+
databaseIncludeSpecialColumns: this.databaseIncludeSpecialColumns
|
|
75
100
|
});
|
|
76
|
-
if (this.
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
101
|
+
if (this.occurrence) {
|
|
102
|
+
const defaultSelectValue = getDefaultSelect(this.occurrence);
|
|
103
|
+
getTableSchema(this.occurrence);
|
|
104
|
+
if (defaultSelectValue === "schema") {
|
|
105
|
+
const allColumns = getTableColumns(this.occurrence);
|
|
106
|
+
const systemColumns = this.databaseIncludeSpecialColumns ? { ROWID: true, ROWMODID: true } : void 0;
|
|
107
|
+
const selectedBuilder = builder.select(allColumns, systemColumns);
|
|
108
|
+
if (this.isNavigateFromEntitySet && this.navigateRelation && this.navigateSourceTableName) {
|
|
109
|
+
selectedBuilder.navigation = {
|
|
110
|
+
relation: this.navigateRelation,
|
|
111
|
+
sourceTableName: this.navigateSourceTableName,
|
|
112
|
+
basePath: this.navigateBasePath
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
return selectedBuilder;
|
|
116
|
+
}
|
|
117
|
+
if (typeof defaultSelectValue === "object" && defaultSelectValue !== null && !Array.isArray(defaultSelectValue)) {
|
|
118
|
+
const selectedBuilder = builder.select(defaultSelectValue);
|
|
119
|
+
if (this.isNavigateFromEntitySet && this.navigateRelation && this.navigateSourceTableName) {
|
|
120
|
+
selectedBuilder.navigation = {
|
|
121
|
+
relation: this.navigateRelation,
|
|
122
|
+
sourceTableName: this.navigateSourceTableName,
|
|
123
|
+
basePath: this.navigateBasePath
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
return selectedBuilder;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if (this.isNavigateFromEntitySet && this.navigateRelation && this.navigateSourceTableName) {
|
|
130
|
+
builder.navigation = {
|
|
131
|
+
relation: this.navigateRelation,
|
|
132
|
+
sourceTableName: this.navigateSourceTableName,
|
|
133
|
+
basePath: this.navigateBasePath
|
|
134
|
+
};
|
|
80
135
|
}
|
|
81
136
|
return builder;
|
|
82
137
|
}
|
|
83
138
|
// Implementation
|
|
84
139
|
insert(data, options) {
|
|
85
|
-
|
|
86
|
-
const returnPref = (options == null ? void 0 : options.returnFullRecord) === false ? "minimal" : "representation";
|
|
140
|
+
const returnPreference = (options == null ? void 0 : options.returnFullRecord) === false ? "minimal" : "representation";
|
|
87
141
|
return new InsertBuilder({
|
|
88
142
|
occurrence: this.occurrence,
|
|
89
|
-
tableName: this.tableName,
|
|
90
143
|
databaseName: this.databaseName,
|
|
91
144
|
context: this.context,
|
|
145
|
+
// biome-ignore lint/suspicious/noExplicitAny: Input type is validated/transformed at runtime
|
|
92
146
|
data,
|
|
93
|
-
|
|
94
|
-
|
|
147
|
+
// biome-ignore lint/suspicious/noExplicitAny: Type assertion for generic type parameter
|
|
148
|
+
returnPreference,
|
|
149
|
+
databaseUseEntityIds: this.databaseUseEntityIds,
|
|
150
|
+
databaseIncludeSpecialColumns: this.databaseIncludeSpecialColumns
|
|
95
151
|
});
|
|
96
152
|
}
|
|
97
153
|
// Implementation
|
|
98
154
|
update(data, options) {
|
|
99
|
-
|
|
100
|
-
const returnPref = (options == null ? void 0 : options.returnFullRecord) === true ? "representation" : "minimal";
|
|
155
|
+
const returnPreference = (options == null ? void 0 : options.returnFullRecord) === true ? "representation" : "minimal";
|
|
101
156
|
return new UpdateBuilder({
|
|
102
157
|
occurrence: this.occurrence,
|
|
103
|
-
tableName: this.tableName,
|
|
104
158
|
databaseName: this.databaseName,
|
|
105
159
|
context: this.context,
|
|
160
|
+
// biome-ignore lint/suspicious/noExplicitAny: Input type is validated/transformed at runtime
|
|
106
161
|
data,
|
|
107
|
-
|
|
108
|
-
|
|
162
|
+
// biome-ignore lint/suspicious/noExplicitAny: Type assertion for generic type parameter
|
|
163
|
+
returnPreference,
|
|
164
|
+
databaseUseEntityIds: this.databaseUseEntityIds,
|
|
165
|
+
databaseIncludeSpecialColumns: this.databaseIncludeSpecialColumns
|
|
109
166
|
});
|
|
110
167
|
}
|
|
111
168
|
delete() {
|
|
112
|
-
var _a;
|
|
113
169
|
return new DeleteBuilder({
|
|
114
170
|
occurrence: this.occurrence,
|
|
115
|
-
tableName: this.tableName,
|
|
116
171
|
databaseName: this.databaseName,
|
|
117
172
|
context: this.context,
|
|
118
|
-
databaseUseEntityIds:
|
|
173
|
+
databaseUseEntityIds: this.databaseUseEntityIds,
|
|
174
|
+
databaseIncludeSpecialColumns: this.databaseIncludeSpecialColumns
|
|
175
|
+
// biome-ignore lint/suspicious/noExplicitAny: Type assertion for complex generic return type
|
|
119
176
|
});
|
|
120
177
|
}
|
|
121
178
|
// Implementation
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
179
|
+
// biome-ignore lint/suspicious/noExplicitAny: Accepts any FMTable configuration
|
|
180
|
+
navigate(targetTable) {
|
|
181
|
+
let relationName;
|
|
182
|
+
relationName = getTableName(targetTable);
|
|
183
|
+
if (this.occurrence && FMTable.Symbol.NavigationPaths in this.occurrence) {
|
|
184
|
+
const navigationPaths = this.occurrence[FMTable.Symbol.NavigationPaths];
|
|
185
|
+
if (navigationPaths && !navigationPaths.includes(relationName)) {
|
|
186
|
+
this.logger.warn(
|
|
187
|
+
`Cannot navigate to "${relationName}". Valid navigation paths: ${navigationPaths.length > 0 ? navigationPaths.join(", ") : "none"}`
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
125
191
|
const entitySet = new EntitySet({
|
|
126
|
-
occurrence:
|
|
127
|
-
tableName: (targetOccurrence == null ? void 0 : targetOccurrence.name) ?? relationName,
|
|
192
|
+
occurrence: targetTable,
|
|
128
193
|
databaseName: this.databaseName,
|
|
129
|
-
context: this.context
|
|
194
|
+
context: this.context,
|
|
195
|
+
database: this.database
|
|
130
196
|
});
|
|
131
197
|
entitySet.isNavigateFromEntitySet = true;
|
|
132
198
|
entitySet.navigateRelation = relationName;
|
|
133
|
-
|
|
199
|
+
if (this.isNavigateFromEntitySet && this.navigateBasePath) {
|
|
200
|
+
entitySet.navigateBasePath = `${this.navigateBasePath}/${this.navigateRelation}`;
|
|
201
|
+
entitySet.navigateSourceTableName = this.navigateSourceTableName;
|
|
202
|
+
} else if (this.isNavigateFromEntitySet && this.navigateRelation) {
|
|
203
|
+
entitySet.navigateBasePath = `${this.navigateSourceTableName}/${this.navigateRelation}`;
|
|
204
|
+
entitySet.navigateSourceTableName = this.navigateSourceTableName;
|
|
205
|
+
} else {
|
|
206
|
+
entitySet.navigateSourceTableName = getTableName(this.occurrence);
|
|
207
|
+
}
|
|
134
208
|
return entitySet;
|
|
135
209
|
}
|
|
136
210
|
}
|