@proofkit/fmodata 0.1.0-alpha.9 → 0.1.0-beta.23
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 +651 -449
- 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 +110 -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 +28 -20
- 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 +266 -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
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { transformFieldNamesArray } from "../../transform.js";
|
|
2
|
+
const VALID_FIELD_NAME_REGEX = /^[a-zA-Z][a-zA-Z0-9]*$/;
|
|
3
|
+
function needsFieldQuoting(fieldName) {
|
|
4
|
+
if (fieldName.startsWith("FMFID:") || fieldName.startsWith("FMTID:")) {
|
|
5
|
+
return false;
|
|
6
|
+
}
|
|
7
|
+
if (fieldName === "id") {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
return fieldName.includes(" ") || fieldName.includes("_") || !VALID_FIELD_NAME_REGEX.test(fieldName);
|
|
11
|
+
}
|
|
12
|
+
function formatSelectFields(select, table, useEntityIds) {
|
|
13
|
+
if (!select || select.length === 0) {
|
|
14
|
+
return "";
|
|
15
|
+
}
|
|
16
|
+
const selectArray = Array.isArray(select) ? select : [select];
|
|
17
|
+
const transformedFields = table && useEntityIds ? transformFieldNamesArray(selectArray.map(String), table) : selectArray.map(String);
|
|
18
|
+
return transformedFields.map((field) => {
|
|
19
|
+
if (needsFieldQuoting(field)) {
|
|
20
|
+
return `"${field}"`;
|
|
21
|
+
}
|
|
22
|
+
const encoded = encodeURIComponent(field);
|
|
23
|
+
return encoded.replace(/%20/g, " ");
|
|
24
|
+
}).join(",");
|
|
25
|
+
}
|
|
26
|
+
export {
|
|
27
|
+
formatSelectFields,
|
|
28
|
+
needsFieldQuoting
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=select-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-utils.js","sources":["../../../../src/client/builders/select-utils.ts"],"sourcesContent":["import type { FMTable } from \"../../orm/table\";\nimport { transformFieldNamesArray } from \"../../transform\";\n\nconst VALID_FIELD_NAME_REGEX = /^[a-zA-Z][a-zA-Z0-9]*$/;\n\n/**\n * Determines if a field name needs to be quoted in OData queries.\n * Per FileMaker docs: field names with special characters (spaces, underscores, etc.) must be quoted.\n * Also quotes \"id\" as it's an OData reserved word.\n * Entity IDs (FMFID:*, FMTID:*) are not quoted as they're identifiers, not field names.\n *\n * @param fieldName - The field name or identifier to check\n * @returns true if the field name should be quoted in OData queries\n */\nexport function needsFieldQuoting(fieldName: string): boolean {\n // Entity IDs are identifiers and don't need quoting\n if (fieldName.startsWith(\"FMFID:\") || fieldName.startsWith(\"FMTID:\")) {\n return false;\n }\n // Always quote \"id\" as it's an OData reserved word\n if (fieldName === \"id\") {\n return true;\n }\n // Quote if field name contains spaces, underscores, or other special characters\n return fieldName.includes(\" \") || fieldName.includes(\"_\") || !VALID_FIELD_NAME_REGEX.test(fieldName);\n}\n\n/**\n * Formats select fields for use in OData query strings.\n * - Transforms field names to FMFIDs if using entity IDs\n * - Wraps \"id\" fields in double quotes (OData reserved)\n * - URL-encodes special characters but preserves spaces\n */\nexport function formatSelectFields(\n select: string[] | readonly string[] | undefined,\n // biome-ignore lint/suspicious/noExplicitAny: Accepts any FMTable configuration\n table?: FMTable<any, any>,\n useEntityIds?: boolean,\n): string {\n if (!select || select.length === 0) {\n return \"\";\n }\n\n const selectArray = Array.isArray(select) ? select : [select];\n\n // Transform to field IDs if using entity IDs\n const transformedFields =\n table && useEntityIds ? transformFieldNamesArray(selectArray.map(String), table) : selectArray.map(String);\n\n return transformedFields\n .map((field) => {\n if (needsFieldQuoting(field)) {\n return `\"${field}\"`;\n }\n const encoded = encodeURIComponent(field);\n return encoded.replace(/%20/g, \" \");\n })\n .join(\",\");\n}\n"],"names":[],"mappings":";AAGA,MAAM,yBAAyB;AAWxB,SAAS,kBAAkB,WAA4B;AAE5D,MAAI,UAAU,WAAW,QAAQ,KAAK,UAAU,WAAW,QAAQ,GAAG;AAC7D,WAAA;AAAA,EAAA;AAGT,MAAI,cAAc,MAAM;AACf,WAAA;AAAA,EAAA;AAGF,SAAA,UAAU,SAAS,GAAG,KAAK,UAAU,SAAS,GAAG,KAAK,CAAC,uBAAuB,KAAK,SAAS;AACrG;AAQgB,SAAA,mBACd,QAEA,OACA,cACQ;AACR,MAAI,CAAC,UAAU,OAAO,WAAW,GAAG;AAC3B,WAAA;AAAA,EAAA;AAGT,QAAM,cAAc,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC,MAAM;AAG5D,QAAM,oBACJ,SAAS,eAAe,yBAAyB,YAAY,IAAI,MAAM,GAAG,KAAK,IAAI,YAAY,IAAI,MAAM;AAEpG,SAAA,kBACJ,IAAI,CAAC,UAAU;AACV,QAAA,kBAAkB,KAAK,GAAG;AAC5B,aAAO,IAAI,KAAK;AAAA,IAAA;AAEZ,UAAA,UAAU,mBAAmB,KAAK;AACjC,WAAA,QAAQ,QAAQ,QAAQ,GAAG;AAAA,EAAA,CACnC,EACA,KAAK,GAAG;AACb;"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { QueryOptions } from 'odata-query';
|
|
2
|
+
import { FMTable } from '../../orm/table.js';
|
|
3
|
+
import { ExecutionContext } from '../../types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Expand configuration used by both QueryBuilder and RecordBuilder
|
|
6
|
+
*/
|
|
7
|
+
export interface ExpandConfig {
|
|
8
|
+
relation: string;
|
|
9
|
+
options?: Partial<QueryOptions<any>>;
|
|
10
|
+
targetTable?: FMTable<any, any>;
|
|
11
|
+
nestedExpandConfigs?: ExpandConfig[];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Type to represent expanded relations in return types
|
|
15
|
+
*/
|
|
16
|
+
export type ExpandedRelations = Record<string, {
|
|
17
|
+
schema: any;
|
|
18
|
+
selected: any;
|
|
19
|
+
}>;
|
|
20
|
+
/**
|
|
21
|
+
* Navigation context shared between builders
|
|
22
|
+
*/
|
|
23
|
+
export interface NavigationContext {
|
|
24
|
+
isNavigate?: boolean;
|
|
25
|
+
navigateRecordId?: string | number;
|
|
26
|
+
navigateRelation?: string;
|
|
27
|
+
navigateSourceTableName?: string;
|
|
28
|
+
navigateBaseRelation?: string;
|
|
29
|
+
navigateBasePath?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Common builder configuration
|
|
33
|
+
*/
|
|
34
|
+
export interface BuilderConfig<Occ extends FMTable<any, any> | undefined> {
|
|
35
|
+
occurrence?: Occ;
|
|
36
|
+
tableName: string;
|
|
37
|
+
databaseName: string;
|
|
38
|
+
context: ExecutionContext;
|
|
39
|
+
databaseUseEntityIds?: boolean;
|
|
40
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { FFetchOptions } from '@fetchkit/ffetch';
|
|
2
|
+
import { FMTable } from '../../orm/table.js';
|
|
3
|
+
import { ExecuteOptions, ExecutionContext } from '../../types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Resolves table identifier based on entity ID settings.
|
|
6
|
+
* Used by both QueryBuilder and RecordBuilder.
|
|
7
|
+
*/
|
|
8
|
+
export declare function resolveTableId(table: FMTable<any, any> | undefined, fallbackTableName: string, context: ExecutionContext, useEntityIdsOverride?: boolean): string;
|
|
9
|
+
/**
|
|
10
|
+
* Merges database-level useEntityIds with per-request options.
|
|
11
|
+
*/
|
|
12
|
+
export declare function mergeEntityIdOptions<T extends Record<string, any>>(options: T | undefined, databaseDefault: boolean): T & {
|
|
13
|
+
useEntityIds?: boolean;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Type-safe helper for merging execute options with entity ID settings
|
|
17
|
+
*/
|
|
18
|
+
export declare function mergeExecuteOptions(options: (RequestInit & FFetchOptions & ExecuteOptions) | undefined, databaseUseEntityIds: boolean): RequestInit & FFetchOptions & {
|
|
19
|
+
useEntityIds?: boolean;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Creates an OData Request object with proper headers.
|
|
23
|
+
* Used by both QueryBuilder and RecordBuilder to eliminate duplication.
|
|
24
|
+
*
|
|
25
|
+
* @param baseUrl - Base URL for the request
|
|
26
|
+
* @param config - Request configuration with method and url
|
|
27
|
+
* @param options - Optional execution options
|
|
28
|
+
* @returns Request object ready to use
|
|
29
|
+
*/
|
|
30
|
+
export declare function createODataRequest(baseUrl: string, config: {
|
|
31
|
+
method: string;
|
|
32
|
+
url: string;
|
|
33
|
+
}, options?: {
|
|
34
|
+
includeODataAnnotations?: boolean;
|
|
35
|
+
}): Request;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { isUsingEntityIds, getTableName, getTableId } from "../../orm/table.js";
|
|
2
|
+
import { getAcceptHeader } from "../../types.js";
|
|
3
|
+
function resolveTableId(table, fallbackTableName, context, useEntityIdsOverride) {
|
|
4
|
+
var _a;
|
|
5
|
+
if (!table) {
|
|
6
|
+
return fallbackTableName;
|
|
7
|
+
}
|
|
8
|
+
const contextDefault = ((_a = context._getUseEntityIds) == null ? void 0 : _a.call(context)) ?? false;
|
|
9
|
+
const shouldUseIds = useEntityIdsOverride ?? contextDefault;
|
|
10
|
+
if (shouldUseIds) {
|
|
11
|
+
if (!isUsingEntityIds(table)) {
|
|
12
|
+
throw new Error(`useEntityIds is true but table "${getTableName(table)}" does not have entity IDs configured`);
|
|
13
|
+
}
|
|
14
|
+
return getTableId(table);
|
|
15
|
+
}
|
|
16
|
+
return getTableName(table);
|
|
17
|
+
}
|
|
18
|
+
function mergeEntityIdOptions(options, databaseDefault) {
|
|
19
|
+
return {
|
|
20
|
+
...options,
|
|
21
|
+
// biome-ignore lint/suspicious/noExplicitAny: Type assertion for optional property access
|
|
22
|
+
useEntityIds: (options == null ? void 0 : options.useEntityIds) ?? databaseDefault
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function mergeExecuteOptions(options, databaseUseEntityIds) {
|
|
26
|
+
return mergeEntityIdOptions(options, databaseUseEntityIds);
|
|
27
|
+
}
|
|
28
|
+
function createODataRequest(baseUrl, config, options) {
|
|
29
|
+
const fullUrl = `${baseUrl}${config.url}`;
|
|
30
|
+
return new Request(fullUrl, {
|
|
31
|
+
method: config.method,
|
|
32
|
+
headers: {
|
|
33
|
+
"Content-Type": "application/json",
|
|
34
|
+
Accept: getAcceptHeader(options == null ? void 0 : options.includeODataAnnotations)
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
export {
|
|
39
|
+
createODataRequest,
|
|
40
|
+
mergeEntityIdOptions,
|
|
41
|
+
mergeExecuteOptions,
|
|
42
|
+
resolveTableId
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=table-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table-utils.js","sources":["../../../../src/client/builders/table-utils.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 { ExecuteOptions, ExecutionContext } from \"../../types\";\nimport { getAcceptHeader } from \"../../types\";\n\n/**\n * Resolves table identifier based on entity ID settings.\n * Used by both QueryBuilder and RecordBuilder.\n */\nexport function resolveTableId(\n // biome-ignore lint/suspicious/noExplicitAny: Accepts any FMTable configuration\n table: FMTable<any, any> | undefined,\n fallbackTableName: string,\n context: ExecutionContext,\n useEntityIdsOverride?: boolean,\n): string {\n if (!table) {\n return fallbackTableName;\n }\n\n const contextDefault = context._getUseEntityIds?.() ?? false;\n const shouldUseIds = useEntityIdsOverride ?? contextDefault;\n\n if (shouldUseIds) {\n if (!isUsingEntityIds(table)) {\n throw new Error(`useEntityIds is true but table \"${getTableName(table)}\" does not have entity IDs configured`);\n }\n return getTableIdHelper(table);\n }\n\n return getTableName(table);\n}\n\n/**\n * Merges database-level useEntityIds with per-request options.\n */\n// biome-ignore lint/suspicious/noExplicitAny: Generic constraint accepting any record shape\nexport function mergeEntityIdOptions<T extends Record<string, any>>(\n options: T | undefined,\n databaseDefault: boolean,\n): T & { useEntityIds?: boolean } {\n return {\n ...options,\n // biome-ignore lint/suspicious/noExplicitAny: Type assertion for optional property access\n useEntityIds: (options as any)?.useEntityIds ?? databaseDefault,\n } as T & { useEntityIds?: boolean };\n}\n\n/**\n * Type-safe helper for merging execute options with entity ID settings\n */\nexport function mergeExecuteOptions(\n options: (RequestInit & FFetchOptions & ExecuteOptions) | undefined,\n databaseUseEntityIds: boolean,\n): RequestInit & FFetchOptions & { useEntityIds?: boolean } {\n return mergeEntityIdOptions(options, databaseUseEntityIds);\n}\n\n/**\n * Creates an OData Request object with proper headers.\n * Used by both QueryBuilder and RecordBuilder to eliminate duplication.\n *\n * @param baseUrl - Base URL for the request\n * @param config - Request configuration with method and url\n * @param options - Optional execution options\n * @returns Request object ready to use\n */\nexport function createODataRequest(\n baseUrl: string,\n config: { method: string; url: string },\n options?: { includeODataAnnotations?: boolean },\n): Request {\n const fullUrl = `${baseUrl}${config.url}`;\n\n return new Request(fullUrl, {\n method: config.method,\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: getAcceptHeader(options?.includeODataAnnotations),\n },\n });\n}\n"],"names":["getTableIdHelper"],"mappings":";;AAUO,SAAS,eAEd,OACA,mBACA,SACA,sBACQ;;AACR,MAAI,CAAC,OAAO;AACH,WAAA;AAAA,EAAA;AAGH,QAAA,mBAAiB,aAAQ,qBAAR,qCAAgC;AACvD,QAAM,eAAe,wBAAwB;AAE7C,MAAI,cAAc;AACZ,QAAA,CAAC,iBAAiB,KAAK,GAAG;AAC5B,YAAM,IAAI,MAAM,mCAAmC,aAAa,KAAK,CAAC,uCAAuC;AAAA,IAAA;AAE/G,WAAOA,WAAiB,KAAK;AAAA,EAAA;AAG/B,SAAO,aAAa,KAAK;AAC3B;AAMgB,SAAA,qBACd,SACA,iBACgC;AACzB,SAAA;AAAA,IACL,GAAG;AAAA;AAAA,IAEH,eAAe,mCAAiB,iBAAgB;AAAA,EAClD;AACF;AAKgB,SAAA,oBACd,SACA,sBAC0D;AACnD,SAAA,qBAAqB,SAAS,oBAAoB;AAC3D;AAWgB,SAAA,mBACd,SACA,QACA,SACS;AACT,QAAM,UAAU,GAAG,OAAO,GAAG,OAAO,GAAG;AAEhC,SAAA,IAAI,QAAQ,SAAS;AAAA,IAC1B,QAAQ,OAAO;AAAA,IACf,SAAS;AAAA,MACP,gBAAgB;AAAA,MAChB,QAAQ,gBAAgB,mCAAS,uBAAuB;AAAA,IAAA;AAAA,EAC1D,CACD;AACH;"}
|
|
@@ -1,53 +1,65 @@
|
|
|
1
1
|
import { StandardSchemaV1 } from '@standard-schema/spec';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { TableOccurrence } from './table-occurrence.js';
|
|
5
|
-
import { EntitySet } from './entity-set.js';
|
|
2
|
+
import { FMTable } from '../orm/table.js';
|
|
3
|
+
import { ExecutableBuilder, ExecutionContext, Metadata } from '../types.js';
|
|
6
4
|
import { BatchBuilder } from './batch-builder.js';
|
|
5
|
+
import { EntitySet } from './entity-set.js';
|
|
7
6
|
import { SchemaManager } from './schema-manager.js';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
import { WebhookManager } from './webhook-builder.js';
|
|
8
|
+
interface MetadataArgs {
|
|
9
|
+
format?: "xml" | "json";
|
|
10
|
+
/**
|
|
11
|
+
* If provided, only the metadata for the specified table will be returned.
|
|
12
|
+
* Requires FileMaker Server 22.0.4 or later.
|
|
13
|
+
*/
|
|
14
|
+
tableName?: string;
|
|
15
|
+
/**
|
|
16
|
+
* If true, a reduced payload size will be returned by omitting certain annotations.
|
|
17
|
+
*/
|
|
18
|
+
reduceAnnotations?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export declare class Database<IncludeSpecialColumns extends boolean = false> {
|
|
21
|
+
readonly schema: SchemaManager;
|
|
22
|
+
readonly webhook: WebhookManager;
|
|
15
23
|
private readonly databaseName;
|
|
16
24
|
private readonly context;
|
|
17
|
-
private occurrenceMap;
|
|
18
25
|
private _useEntityIds;
|
|
19
|
-
readonly
|
|
26
|
+
private readonly _includeSpecialColumns;
|
|
20
27
|
constructor(databaseName: string, context: ExecutionContext, config?: {
|
|
21
|
-
occurrences?: Occurrences | undefined;
|
|
22
28
|
/**
|
|
23
29
|
* Whether to use entity IDs instead of field names in the actual requests to the server
|
|
24
30
|
* Defaults to true if all occurrences use entity IDs, false otherwise
|
|
25
31
|
* If set to false but some occurrences do not use entity IDs, an error will be thrown
|
|
26
32
|
*/
|
|
27
33
|
useEntityIds?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Whether to include special columns (ROWID and ROWMODID) in responses.
|
|
36
|
+
* Note: Special columns are only included when there is no $select query.
|
|
37
|
+
*/
|
|
38
|
+
includeSpecialColumns?: IncludeSpecialColumns;
|
|
28
39
|
});
|
|
29
40
|
/**
|
|
30
|
-
*
|
|
41
|
+
* @internal Used by EntitySet to access database configuration
|
|
31
42
|
*/
|
|
32
|
-
|
|
43
|
+
get _getUseEntityIds(): boolean;
|
|
33
44
|
/**
|
|
34
|
-
*
|
|
35
|
-
* @internal
|
|
45
|
+
* @internal Used by EntitySet to access database configuration
|
|
36
46
|
*/
|
|
37
|
-
|
|
38
|
-
from<
|
|
47
|
+
get _getIncludeSpecialColumns(): IncludeSpecialColumns;
|
|
48
|
+
from<T extends FMTable<any, any>>(table: T): EntitySet<T, IncludeSpecialColumns>;
|
|
39
49
|
/**
|
|
40
50
|
* Retrieves the OData metadata for this database.
|
|
41
51
|
* @param args Optional configuration object
|
|
42
52
|
* @param args.format The format to retrieve metadata in. Defaults to "json".
|
|
53
|
+
* @param args.tableName If provided, only the metadata for the specified table will be returned. Requires FileMaker Server 22.0.4 or later.
|
|
54
|
+
* @param args.reduceAnnotations If true, a reduced payload size will be returned by omitting certain annotations.
|
|
43
55
|
* @returns The metadata in the specified format
|
|
44
56
|
*/
|
|
45
57
|
getMetadata(args: {
|
|
46
58
|
format: "xml";
|
|
47
|
-
}): Promise<string>;
|
|
59
|
+
} & MetadataArgs): Promise<string>;
|
|
48
60
|
getMetadata(args?: {
|
|
49
61
|
format?: "json";
|
|
50
|
-
}): Promise<Metadata>;
|
|
62
|
+
} & MetadataArgs): Promise<Metadata>;
|
|
51
63
|
/**
|
|
52
64
|
* Lists all available tables (entity sets) in this database.
|
|
53
65
|
* @returns Promise resolving to an array of table names
|
|
@@ -1,100 +1,66 @@
|
|
|
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 {
|
|
4
|
+
import { FMTable } from "../orm/table.js";
|
|
5
5
|
import { BatchBuilder } from "./batch-builder.js";
|
|
6
|
+
import { EntitySet } from "./entity-set.js";
|
|
6
7
|
import { SchemaManager } from "./schema-manager.js";
|
|
8
|
+
import { WebhookManager } from "./webhook-builder.js";
|
|
7
9
|
class Database {
|
|
8
10
|
constructor(databaseName, context, config) {
|
|
9
|
-
__publicField(this, "occurrenceMap");
|
|
10
|
-
__publicField(this, "_useEntityIds", false);
|
|
11
11
|
__publicField(this, "schema");
|
|
12
|
+
__publicField(this, "webhook");
|
|
13
|
+
__publicField(this, "databaseName");
|
|
14
|
+
__publicField(this, "context");
|
|
15
|
+
__publicField(this, "_useEntityIds");
|
|
16
|
+
__publicField(this, "_includeSpecialColumns");
|
|
12
17
|
this.databaseName = databaseName;
|
|
13
18
|
this.context = context;
|
|
14
|
-
this.occurrenceMap = /* @__PURE__ */ new Map();
|
|
15
|
-
if (config == null ? void 0 : config.occurrences) {
|
|
16
|
-
const occurrencesWithIds = [];
|
|
17
|
-
const occurrencesWithoutIds = [];
|
|
18
|
-
for (const occ of config.occurrences) {
|
|
19
|
-
this.occurrenceMap.set(occ.name, occ);
|
|
20
|
-
const hasTableId = occ.isUsingTableId();
|
|
21
|
-
const hasFieldIds = occ.baseTable.isUsingFieldIds();
|
|
22
|
-
if (hasTableId && hasFieldIds) {
|
|
23
|
-
occurrencesWithIds.push(occ.name);
|
|
24
|
-
} else if (!hasTableId && !hasFieldIds) {
|
|
25
|
-
occurrencesWithoutIds.push(occ.name);
|
|
26
|
-
} else {
|
|
27
|
-
throw new Error(
|
|
28
|
-
`TableOccurrence "${occ.name}" has inconsistent entity ID configuration. Both fmtId (${hasTableId ? "present" : "missing"}) and fmfIds (${hasFieldIds ? "present" : "missing"}) must be defined together.`
|
|
29
|
-
);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
const allOccurrencesUseEntityIds = occurrencesWithIds.length > 0 && occurrencesWithoutIds.length === 0;
|
|
33
|
-
const hasMixedUsage = occurrencesWithIds.length > 0 && occurrencesWithoutIds.length > 0;
|
|
34
|
-
if (config.useEntityIds !== void 0) {
|
|
35
|
-
if (config.useEntityIds === false) {
|
|
36
|
-
this._useEntityIds = false;
|
|
37
|
-
} else if (config.useEntityIds === true) {
|
|
38
|
-
if (hasMixedUsage || occurrencesWithoutIds.length > 0) {
|
|
39
|
-
throw new Error(
|
|
40
|
-
`useEntityIds is set to true but some occurrences do not use entity IDs. Occurrences without entity IDs: [${occurrencesWithoutIds.join(", ")}]. Either set useEntityIds to false or configure all occurrences with entity IDs.`
|
|
41
|
-
);
|
|
42
|
-
}
|
|
43
|
-
this._useEntityIds = true;
|
|
44
|
-
}
|
|
45
|
-
} else {
|
|
46
|
-
if (hasMixedUsage) {
|
|
47
|
-
throw new Error(
|
|
48
|
-
`Cannot mix TableOccurrence instances with and without entity IDs in the same database. Occurrences with entity IDs: [${occurrencesWithIds.join(", ")}]. Occurrences without entity IDs: [${occurrencesWithoutIds.join(", ")}]. Either all table occurrences must use entity IDs (fmtId + fmfIds), none should, or explicitly set useEntityIds to false.`
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
this._useEntityIds = allOccurrencesUseEntityIds;
|
|
52
|
-
}
|
|
53
|
-
} else {
|
|
54
|
-
this._useEntityIds = (config == null ? void 0 : config.useEntityIds) ?? false;
|
|
55
|
-
}
|
|
56
|
-
if (this.context._setUseEntityIds) {
|
|
57
|
-
this.context._setUseEntityIds(this._useEntityIds);
|
|
58
|
-
}
|
|
59
19
|
this.schema = new SchemaManager(this.databaseName, this.context);
|
|
20
|
+
this.webhook = new WebhookManager(this.databaseName, this.context);
|
|
21
|
+
this._useEntityIds = (config == null ? void 0 : config.useEntityIds) ?? false;
|
|
22
|
+
this._includeSpecialColumns = (config == null ? void 0 : config.includeSpecialColumns) ?? false;
|
|
60
23
|
}
|
|
61
24
|
/**
|
|
62
|
-
*
|
|
25
|
+
* @internal Used by EntitySet to access database configuration
|
|
63
26
|
*/
|
|
64
|
-
|
|
27
|
+
get _getUseEntityIds() {
|
|
65
28
|
return this._useEntityIds;
|
|
66
29
|
}
|
|
67
30
|
/**
|
|
68
|
-
*
|
|
69
|
-
* @internal
|
|
31
|
+
* @internal Used by EntitySet to access database configuration
|
|
70
32
|
*/
|
|
71
|
-
|
|
72
|
-
return this.
|
|
33
|
+
get _getIncludeSpecialColumns() {
|
|
34
|
+
return this._includeSpecialColumns;
|
|
73
35
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
context: this.context,
|
|
82
|
-
database: this
|
|
83
|
-
});
|
|
84
|
-
} else {
|
|
85
|
-
return new EntitySet({
|
|
86
|
-
tableName: name,
|
|
87
|
-
databaseName: this.databaseName,
|
|
88
|
-
context: this.context,
|
|
89
|
-
database: this
|
|
90
|
-
});
|
|
36
|
+
// biome-ignore lint/suspicious/noExplicitAny: Accepts any FMTable configuration
|
|
37
|
+
from(table) {
|
|
38
|
+
if (Object.hasOwn(table, FMTable.Symbol.UseEntityIds)) {
|
|
39
|
+
const tableUseEntityIds = table[FMTable.Symbol.UseEntityIds];
|
|
40
|
+
if (typeof tableUseEntityIds === "boolean") {
|
|
41
|
+
this._useEntityIds = tableUseEntityIds;
|
|
42
|
+
}
|
|
91
43
|
}
|
|
44
|
+
return new EntitySet({
|
|
45
|
+
occurrence: table,
|
|
46
|
+
databaseName: this.databaseName,
|
|
47
|
+
context: this.context,
|
|
48
|
+
database: this
|
|
49
|
+
});
|
|
92
50
|
}
|
|
93
51
|
async getMetadata(args) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
52
|
+
let url = `/${this.databaseName}/$metadata`;
|
|
53
|
+
if (args == null ? void 0 : args.tableName) {
|
|
54
|
+
url = `/${this.databaseName}/$metadata%23${args.tableName}`;
|
|
55
|
+
}
|
|
56
|
+
const headers = {
|
|
57
|
+
Accept: (args == null ? void 0 : args.format) === "xml" ? "application/xml" : "application/json"
|
|
58
|
+
};
|
|
59
|
+
if (args == null ? void 0 : args.reduceAnnotations) {
|
|
60
|
+
headers.Prefer = 'include-annotations="-*"';
|
|
61
|
+
}
|
|
62
|
+
const result = await this.context._makeRequest(url, {
|
|
63
|
+
headers
|
|
98
64
|
});
|
|
99
65
|
if (result.error) {
|
|
100
66
|
throw result.error;
|
|
@@ -103,9 +69,7 @@ class Database {
|
|
|
103
69
|
const data = result.data;
|
|
104
70
|
const metadata = data[this.databaseName];
|
|
105
71
|
if (!metadata) {
|
|
106
|
-
throw new Error(
|
|
107
|
-
`Metadata for database "${this.databaseName}" not found in response`
|
|
108
|
-
);
|
|
72
|
+
throw new Error(`Metadata for database "${this.databaseName}" not found in response`);
|
|
109
73
|
}
|
|
110
74
|
return metadata;
|
|
111
75
|
}
|
|
@@ -131,6 +95,7 @@ class Database {
|
|
|
131
95
|
* @param options - Optional script parameter and result schema
|
|
132
96
|
* @returns Promise resolving to script execution result
|
|
133
97
|
*/
|
|
98
|
+
// biome-ignore lint/suspicious/noExplicitAny: Required for type inference with infer
|
|
134
99
|
async runScript(scriptName, options) {
|
|
135
100
|
const body = {};
|
|
136
101
|
if ((options == null ? void 0 : options.scriptParam) !== void 0) {
|
|
@@ -145,23 +110,21 @@ class Database {
|
|
|
145
110
|
}
|
|
146
111
|
const response = result.data;
|
|
147
112
|
if ((options == null ? void 0 : options.resultSchema) && response.scriptResult !== void 0) {
|
|
148
|
-
const validationResult = options.resultSchema["~standard"].validate(
|
|
149
|
-
response.scriptResult.resultParameter
|
|
150
|
-
);
|
|
113
|
+
const validationResult = options.resultSchema["~standard"].validate(response.scriptResult.resultParameter);
|
|
151
114
|
const result2 = validationResult instanceof Promise ? await validationResult : validationResult;
|
|
152
115
|
if (result2.issues) {
|
|
153
|
-
throw new Error(
|
|
154
|
-
`Script result validation failed: ${JSON.stringify(result2.issues)}`
|
|
155
|
-
);
|
|
116
|
+
throw new Error(`Script result validation failed: ${JSON.stringify(result2.issues)}`);
|
|
156
117
|
}
|
|
157
118
|
return {
|
|
158
119
|
resultCode: response.scriptResult.code,
|
|
159
120
|
result: result2.value
|
|
121
|
+
// biome-ignore lint/suspicious/noExplicitAny: Type assertion for generic return type
|
|
160
122
|
};
|
|
161
123
|
}
|
|
162
124
|
return {
|
|
163
125
|
resultCode: response.scriptResult.code,
|
|
164
126
|
result: response.scriptResult.resultParameter
|
|
127
|
+
// biome-ignore lint/suspicious/noExplicitAny: Type assertion for generic return type
|
|
165
128
|
};
|
|
166
129
|
}
|
|
167
130
|
/**
|
|
@@ -183,6 +146,7 @@ class Database {
|
|
|
183
146
|
* }
|
|
184
147
|
* ```
|
|
185
148
|
*/
|
|
149
|
+
// biome-ignore lint/suspicious/noExplicitAny: Generic constraint accepting any ExecutableBuilder result type
|
|
186
150
|
batch(builders) {
|
|
187
151
|
return new BatchBuilder(builders, this.databaseName, this.context);
|
|
188
152
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.js","sources":["../../../src/client/database.ts"],"sourcesContent":["import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport type { ExecutionContext, ExecutableBuilder, Metadata } from \"../types\";\nimport type { BaseTable } from \"./base-table\";\nimport type { TableOccurrence } from \"./table-occurrence\";\nimport { EntitySet } from \"./entity-set\";\nimport { BatchBuilder } from \"./batch-builder\";\nimport { SchemaManager } from \"./schema-manager\";\n\n// Helper type to extract schema from a TableOccurrence\ntype ExtractSchemaFromOccurrence<O> =\n O extends TableOccurrence<infer BT, any, any, any>\n ? BT extends BaseTable<infer S, any, any, any>\n ? S\n : never\n : never;\n\n// Helper type to find an occurrence by name in the occurrences tuple\ntype FindOccurrenceByName<\n Occurrences extends readonly TableOccurrence<any, any, any, any>[],\n Name extends string,\n> = Occurrences extends readonly [\n infer First,\n ...infer Rest extends readonly TableOccurrence<any, any, any, any>[],\n]\n ? First extends TableOccurrence<any, any, any, any>\n ? First[\"name\"] extends Name\n ? First\n : FindOccurrenceByName<Rest, Name>\n : never\n : never;\n\n// Helper type to extract all occurrence names from the tuple\ntype ExtractOccurrenceNames<\n Occurrences extends readonly TableOccurrence<any, any, any, any>[],\n> = Occurrences extends readonly []\n ? string // If no occurrences, allow any string\n : Occurrences[number][\"name\"]; // Otherwise, extract union of names\n\nexport class Database<\n Occurrences extends readonly TableOccurrence<\n any,\n any,\n any,\n any\n >[] = readonly [],\n> {\n private occurrenceMap: Map<string, TableOccurrence<any, any, any, any>>;\n private _useEntityIds: boolean = false;\n public readonly schema: SchemaManager;\n\n constructor(\n private readonly databaseName: string,\n private readonly context: ExecutionContext,\n config?: {\n occurrences?: Occurrences | undefined;\n /**\n * Whether to use entity IDs instead of field names in the actual requests to the server\n * Defaults to true if all occurrences use entity IDs, false otherwise\n * If set to false but some occurrences do not use entity IDs, an error will be thrown\n */\n useEntityIds?: boolean;\n },\n ) {\n this.occurrenceMap = new Map();\n if (config?.occurrences) {\n // Validate consistency: either all occurrences use entity IDs or none do\n const occurrencesWithIds: string[] = [];\n const occurrencesWithoutIds: string[] = [];\n\n for (const occ of config.occurrences) {\n this.occurrenceMap.set(occ.name, occ);\n\n const hasTableId = occ.isUsingTableId();\n const hasFieldIds = occ.baseTable.isUsingFieldIds();\n\n // An occurrence uses entity IDs if it has both fmtId and fmfIds\n if (hasTableId && hasFieldIds) {\n occurrencesWithIds.push(occ.name);\n } else if (!hasTableId && !hasFieldIds) {\n occurrencesWithoutIds.push(occ.name);\n } else {\n // Partial entity ID usage (only one of fmtId or fmfIds) - this is an error\n throw new Error(\n `TableOccurrence \"${occ.name}\" has inconsistent entity ID configuration. ` +\n `Both fmtId (${hasTableId ? \"present\" : \"missing\"}) and fmfIds (${hasFieldIds ? \"present\" : \"missing\"}) must be defined together.`,\n );\n }\n }\n\n // Determine default value: true if all occurrences use entity IDs, false otherwise\n const allOccurrencesUseEntityIds =\n occurrencesWithIds.length > 0 && occurrencesWithoutIds.length === 0;\n const hasMixedUsage =\n occurrencesWithIds.length > 0 && occurrencesWithoutIds.length > 0;\n\n // Handle explicit useEntityIds config\n if (config.useEntityIds !== undefined) {\n if (config.useEntityIds === false) {\n // If explicitly set to false, allow mixed usage and use false\n this._useEntityIds = false;\n } else if (config.useEntityIds === true) {\n // If explicitly set to true, validate that all occurrences use entity IDs\n if (hasMixedUsage || occurrencesWithoutIds.length > 0) {\n throw new Error(\n `useEntityIds is set to true but some occurrences do not use entity IDs. ` +\n `Occurrences without entity IDs: [${occurrencesWithoutIds.join(\", \")}]. ` +\n `Either set useEntityIds to false or configure all occurrences with entity IDs.`,\n );\n }\n this._useEntityIds = true;\n }\n } else {\n // Default: true if all occurrences use entity IDs, false otherwise\n // But throw error if there's mixed usage when using defaults\n if (hasMixedUsage) {\n throw new Error(\n `Cannot mix TableOccurrence instances with and without entity IDs in the same database. ` +\n `Occurrences with entity IDs: [${occurrencesWithIds.join(\", \")}]. ` +\n `Occurrences without entity IDs: [${occurrencesWithoutIds.join(\", \")}]. ` +\n `Either all table occurrences must use entity IDs (fmtId + fmfIds), none should, or explicitly set useEntityIds to false.`,\n );\n }\n this._useEntityIds = allOccurrencesUseEntityIds;\n }\n } else {\n // No occurrences provided, use explicit config or default to false\n this._useEntityIds = config?.useEntityIds ?? false;\n }\n\n // Inform the execution context whether to use entity IDs\n if (this.context._setUseEntityIds) {\n this.context._setUseEntityIds(this._useEntityIds);\n }\n\n // Initialize schema manager\n this.schema = new SchemaManager(this.databaseName, this.context);\n }\n\n /**\n * Returns true if any table occurrence in this database is using entity IDs.\n */\n isUsingEntityIds(): boolean {\n return this._useEntityIds;\n }\n\n /**\n * Gets a table occurrence by name.\n * @internal\n */\n getOccurrence(name: string): TableOccurrence<any, any, any, any> | undefined {\n return this.occurrenceMap.get(name);\n }\n\n from<Name extends ExtractOccurrenceNames<Occurrences> | (string & {})>(\n name: Name,\n ): Occurrences extends readonly []\n ? EntitySet<Record<string, StandardSchemaV1>, undefined>\n : Name extends ExtractOccurrenceNames<Occurrences>\n ? EntitySet<\n ExtractSchemaFromOccurrence<FindOccurrenceByName<Occurrences, Name>>,\n FindOccurrenceByName<Occurrences, Name>\n >\n : EntitySet<Record<string, StandardSchemaV1>, undefined> {\n const occurrence = this.occurrenceMap.get(name as string);\n\n if (occurrence) {\n // Use EntitySet.create to preserve types better\n type OccType = FindOccurrenceByName<Occurrences, Name>;\n type SchemaType = ExtractSchemaFromOccurrence<OccType>;\n\n return EntitySet.create<SchemaType, OccType>({\n occurrence: occurrence as OccType,\n tableName: name as string,\n databaseName: this.databaseName,\n context: this.context,\n database: this,\n }) as any;\n } else {\n // Return untyped EntitySet for dynamic table access\n return new EntitySet<Record<string, StandardSchemaV1>, undefined>({\n tableName: name as string,\n databaseName: this.databaseName,\n context: this.context,\n database: this,\n }) as any;\n }\n }\n\n /**\n * Retrieves the OData metadata for this database.\n * @param args Optional configuration object\n * @param args.format The format to retrieve metadata in. Defaults to \"json\".\n * @returns The metadata in the specified format\n */\n async getMetadata(args: { format: \"xml\" }): Promise<string>;\n async getMetadata(args?: { format?: \"json\" }): Promise<Metadata>;\n async getMetadata(args?: {\n format?: \"xml\" | \"json\";\n }): Promise<string | Metadata> {\n const result = await this.context._makeRequest<\n Record<string, Metadata> | string\n >(`/${this.databaseName}/$metadata`, {\n headers: {\n Accept: args?.format === \"xml\" ? \"application/xml\" : \"application/json\",\n },\n });\n if (result.error) {\n throw result.error;\n }\n\n if (args?.format === \"json\") {\n const data = result.data as Record<string, Metadata>;\n const metadata = data[this.databaseName];\n if (!metadata) {\n throw new Error(\n `Metadata for database \"${this.databaseName}\" not found in response`,\n );\n }\n return metadata;\n }\n return result.data as string;\n }\n\n /**\n * Lists all available tables (entity sets) in this database.\n * @returns Promise resolving to an array of table names\n */\n async listTableNames(): Promise<string[]> {\n const result = await this.context._makeRequest<{\n value?: Array<{ name: string }>;\n }>(`/${this.databaseName}`);\n if (result.error) {\n throw result.error;\n }\n if (result.data.value && Array.isArray(result.data.value)) {\n return result.data.value.map((item) => item.name);\n }\n return [];\n }\n\n /**\n * Executes a FileMaker script.\n * @param scriptName - The name of the script to execute (must be valid according to OData rules)\n * @param options - Optional script parameter and result schema\n * @returns Promise resolving to script execution result\n */\n async runScript<ResultSchema extends StandardSchemaV1<string, any> = never>(\n scriptName: string,\n options?: {\n scriptParam?: string | number | Record<string, any>;\n resultSchema?: ResultSchema;\n },\n ): Promise<\n [ResultSchema] extends [never]\n ? { resultCode: number; result?: string }\n : ResultSchema extends StandardSchemaV1<string, infer Output>\n ? { resultCode: number; result: Output }\n : { resultCode: number; result?: string }\n > {\n const body: { scriptParameterValue?: unknown } = {};\n if (options?.scriptParam !== undefined) {\n body.scriptParameterValue = options.scriptParam;\n }\n\n const result = await this.context._makeRequest<{\n scriptResult: {\n code: number;\n resultParameter?: string;\n };\n }>(`/${this.databaseName}/Script.${scriptName}`, {\n method: \"POST\",\n body: Object.keys(body).length > 0 ? JSON.stringify(body) : undefined,\n });\n\n if (result.error) {\n throw result.error;\n }\n\n const response = result.data;\n\n // If resultSchema is provided, validate the result through it\n if (options?.resultSchema && response.scriptResult !== undefined) {\n const validationResult = options.resultSchema[\"~standard\"].validate(\n response.scriptResult.resultParameter,\n );\n // Handle both sync and async validation\n const result =\n validationResult instanceof Promise\n ? await validationResult\n : validationResult;\n\n if (result.issues) {\n throw new Error(\n `Script result validation failed: ${JSON.stringify(result.issues)}`,\n );\n }\n\n return {\n resultCode: response.scriptResult.code,\n result: result.value,\n } as any;\n }\n\n return {\n resultCode: response.scriptResult.code,\n result: response.scriptResult.resultParameter,\n } as any;\n }\n\n /**\n * Create a batch operation builder that allows multiple queries to be executed together\n * in a single atomic request. All operations succeed or fail together (transactional).\n *\n * @param builders - Array of executable query builders to batch\n * @returns A BatchBuilder that can be executed\n * @example\n * ```ts\n * const result = await db.batch([\n * db.from('contacts').list().top(5),\n * db.from('users').list().top(5),\n * db.from('contacts').insert({ name: 'John' })\n * ]).execute();\n *\n * if (result.data) {\n * const [contacts, users, insertResult] = result.data;\n * }\n * ```\n */\n batch<const Builders extends readonly ExecutableBuilder<any>[]>(\n builders: Builders,\n ): BatchBuilder<Builders> {\n return new BatchBuilder(builders, this.databaseName, this.context);\n }\n}\n"],"names":["result"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"database.js","sources":["../../../src/client/database.ts"],"sourcesContent":["import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport { FMTable } from \"../orm/table\";\nimport type { ExecutableBuilder, ExecutionContext, Metadata } from \"../types\";\nimport { BatchBuilder } from \"./batch-builder\";\nimport { EntitySet } from \"./entity-set\";\nimport { SchemaManager } from \"./schema-manager\";\nimport { WebhookManager } from \"./webhook-builder\";\n\ninterface MetadataArgs {\n format?: \"xml\" | \"json\";\n /**\n * If provided, only the metadata for the specified table will be returned.\n * Requires FileMaker Server 22.0.4 or later.\n */\n tableName?: string;\n /**\n * If true, a reduced payload size will be returned by omitting certain annotations.\n */\n reduceAnnotations?: boolean;\n}\n\nexport class Database<IncludeSpecialColumns extends boolean = false> {\n readonly schema: SchemaManager;\n readonly webhook: WebhookManager;\n private readonly databaseName: string;\n private readonly context: ExecutionContext;\n private _useEntityIds: boolean;\n private readonly _includeSpecialColumns: IncludeSpecialColumns;\n\n constructor(\n databaseName: string,\n context: ExecutionContext,\n config?: {\n /**\n * Whether to use entity IDs instead of field names in the actual requests to the server\n * Defaults to true if all occurrences use entity IDs, false otherwise\n * If set to false but some occurrences do not use entity IDs, an error will be thrown\n */\n useEntityIds?: boolean;\n /**\n * Whether to include special columns (ROWID and ROWMODID) in responses.\n * Note: Special columns are only included when there is no $select query.\n */\n includeSpecialColumns?: IncludeSpecialColumns;\n },\n ) {\n this.databaseName = databaseName;\n this.context = context;\n // Initialize schema manager\n this.schema = new SchemaManager(this.databaseName, this.context);\n this.webhook = new WebhookManager(this.databaseName, this.context);\n this._useEntityIds = config?.useEntityIds ?? false;\n this._includeSpecialColumns = (config?.includeSpecialColumns ?? false) as IncludeSpecialColumns;\n }\n\n /**\n * @internal Used by EntitySet to access database configuration\n */\n get _getUseEntityIds(): boolean {\n return this._useEntityIds;\n }\n\n /**\n * @internal Used by EntitySet to access database configuration\n */\n get _getIncludeSpecialColumns(): IncludeSpecialColumns {\n return this._includeSpecialColumns;\n }\n\n // biome-ignore lint/suspicious/noExplicitAny: Accepts any FMTable configuration\n from<T extends FMTable<any, any>>(table: T): EntitySet<T, IncludeSpecialColumns> {\n // Only override database-level useEntityIds if table explicitly sets it\n // (not if it's undefined, which would override the database setting)\n if (Object.hasOwn(table, FMTable.Symbol.UseEntityIds)) {\n // biome-ignore lint/suspicious/noExplicitAny: Type assertion for Symbol property access\n const tableUseEntityIds = (table as any)[FMTable.Symbol.UseEntityIds];\n if (typeof tableUseEntityIds === \"boolean\") {\n this._useEntityIds = tableUseEntityIds;\n }\n }\n return new EntitySet<T, IncludeSpecialColumns>({\n occurrence: table as T,\n databaseName: this.databaseName,\n context: this.context,\n database: this,\n });\n }\n\n /**\n * Retrieves the OData metadata for this database.\n * @param args Optional configuration object\n * @param args.format The format to retrieve metadata in. Defaults to \"json\".\n * @param args.tableName If provided, only the metadata for the specified table will be returned. Requires FileMaker Server 22.0.4 or later.\n * @param args.reduceAnnotations If true, a reduced payload size will be returned by omitting certain annotations.\n * @returns The metadata in the specified format\n */\n async getMetadata(args: { format: \"xml\" } & MetadataArgs): Promise<string>;\n async getMetadata(args?: { format?: \"json\" } & MetadataArgs): Promise<Metadata>;\n async getMetadata(args?: MetadataArgs): Promise<string | Metadata> {\n // Build the URL - if tableName is provided, append %23{tableName} to the path\n let url = `/${this.databaseName}/$metadata`;\n if (args?.tableName) {\n url = `/${this.databaseName}/$metadata%23${args.tableName}`;\n }\n\n // Build headers\n const headers: Record<string, string> = {\n Accept: args?.format === \"xml\" ? \"application/xml\" : \"application/json\",\n };\n\n // Add Prefer header if reduceAnnotations is true\n if (args?.reduceAnnotations) {\n headers.Prefer = 'include-annotations=\"-*\"';\n }\n\n const result = await this.context._makeRequest<Record<string, Metadata> | string>(url, {\n headers,\n });\n if (result.error) {\n throw result.error;\n }\n\n if (args?.format === \"json\") {\n const data = result.data as Record<string, Metadata>;\n const metadata = data[this.databaseName];\n if (!metadata) {\n throw new Error(`Metadata for database \"${this.databaseName}\" not found in response`);\n }\n return metadata;\n }\n return result.data as string;\n }\n\n /**\n * Lists all available tables (entity sets) in this database.\n * @returns Promise resolving to an array of table names\n */\n async listTableNames(): Promise<string[]> {\n const result = await this.context._makeRequest<{\n value?: Array<{ name: string }>;\n }>(`/${this.databaseName}`);\n if (result.error) {\n throw result.error;\n }\n if (result.data.value && Array.isArray(result.data.value)) {\n return result.data.value.map((item) => item.name);\n }\n return [];\n }\n\n /**\n * Executes a FileMaker script.\n * @param scriptName - The name of the script to execute (must be valid according to OData rules)\n * @param options - Optional script parameter and result schema\n * @returns Promise resolving to script execution result\n */\n // biome-ignore lint/suspicious/noExplicitAny: Required for type inference with infer\n async runScript<ResultSchema extends StandardSchemaV1<string, any> = never>(\n scriptName: string,\n options?: {\n // biome-ignore lint/suspicious/noExplicitAny: Generic constraint accepting any record shape\n scriptParam?: string | number | Record<string, any>;\n resultSchema?: ResultSchema;\n },\n ): Promise<\n [ResultSchema] extends [never]\n ? { resultCode: number; result?: string }\n : ResultSchema extends StandardSchemaV1<string, infer Output>\n ? { resultCode: number; result: Output }\n : { resultCode: number; result?: string }\n > {\n const body: { scriptParameterValue?: unknown } = {};\n if (options?.scriptParam !== undefined) {\n body.scriptParameterValue = options.scriptParam;\n }\n\n const result = await this.context._makeRequest<{\n scriptResult: {\n code: number;\n resultParameter?: string;\n };\n }>(`/${this.databaseName}/Script.${scriptName}`, {\n method: \"POST\",\n body: Object.keys(body).length > 0 ? JSON.stringify(body) : undefined,\n });\n\n if (result.error) {\n throw result.error;\n }\n\n const response = result.data;\n\n // If resultSchema is provided, validate the result through it\n if (options?.resultSchema && response.scriptResult !== undefined) {\n const validationResult = options.resultSchema[\"~standard\"].validate(response.scriptResult.resultParameter);\n // Handle both sync and async validation\n const result = validationResult instanceof Promise ? await validationResult : validationResult;\n\n if (result.issues) {\n throw new Error(`Script result validation failed: ${JSON.stringify(result.issues)}`);\n }\n\n return {\n resultCode: response.scriptResult.code,\n result: result.value,\n // biome-ignore lint/suspicious/noExplicitAny: Type assertion for generic return type\n } as any;\n }\n\n return {\n resultCode: response.scriptResult.code,\n result: response.scriptResult.resultParameter,\n // biome-ignore lint/suspicious/noExplicitAny: Type assertion for generic return type\n } as any;\n }\n\n /**\n * Create a batch operation builder that allows multiple queries to be executed together\n * in a single atomic request. All operations succeed or fail together (transactional).\n *\n * @param builders - Array of executable query builders to batch\n * @returns A BatchBuilder that can be executed\n * @example\n * ```ts\n * const result = await db.batch([\n * db.from('contacts').list().top(5),\n * db.from('users').list().top(5),\n * db.from('contacts').insert({ name: 'John' })\n * ]).execute();\n *\n * if (result.data) {\n * const [contacts, users, insertResult] = result.data;\n * }\n * ```\n */\n // biome-ignore lint/suspicious/noExplicitAny: Generic constraint accepting any ExecutableBuilder result type\n batch<const Builders extends readonly ExecutableBuilder<any>[]>(builders: Builders): BatchBuilder<Builders> {\n return new BatchBuilder(builders, this.databaseName, this.context);\n }\n}\n"],"names":["result"],"mappings":"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"}
|
|
@@ -1,57 +1,54 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { FMTable } from '../orm/table.js';
|
|
2
|
+
import { ExecutableBuilder, ExecuteMethodOptions, ExecuteOptions, ExecutionContext, Result } from '../types.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<
|
|
10
|
-
private
|
|
11
|
-
private
|
|
12
|
-
private
|
|
13
|
-
private
|
|
14
|
-
private
|
|
8
|
+
export declare class DeleteBuilder<Occ extends FMTable<any, any>> {
|
|
9
|
+
private readonly databaseName;
|
|
10
|
+
private readonly context;
|
|
11
|
+
private readonly table;
|
|
12
|
+
private readonly databaseUseEntityIds;
|
|
13
|
+
private readonly databaseIncludeSpecialColumns;
|
|
15
14
|
constructor(config: {
|
|
16
|
-
occurrence
|
|
17
|
-
tableName: string;
|
|
15
|
+
occurrence: Occ;
|
|
18
16
|
databaseName: string;
|
|
19
17
|
context: ExecutionContext;
|
|
20
18
|
databaseUseEntityIds?: boolean;
|
|
19
|
+
databaseIncludeSpecialColumns?: boolean;
|
|
21
20
|
});
|
|
22
21
|
/**
|
|
23
22
|
* Delete a single record by ID
|
|
24
23
|
*/
|
|
25
|
-
byId(id: string | number): ExecutableDeleteBuilder<
|
|
24
|
+
byId(id: string | number): ExecutableDeleteBuilder<Occ>;
|
|
26
25
|
/**
|
|
27
26
|
* Delete records matching a filter query
|
|
28
27
|
* @param fn Callback that receives a QueryBuilder for building the filter
|
|
29
28
|
*/
|
|
30
|
-
where(fn: (q: QueryBuilder<
|
|
29
|
+
where(fn: (q: QueryBuilder<Occ>) => QueryBuilder<Occ>): ExecutableDeleteBuilder<Occ>;
|
|
31
30
|
}
|
|
32
31
|
/**
|
|
33
32
|
* Executable delete builder - has execute() method
|
|
34
33
|
* Returned after calling .byId() or .where()
|
|
35
34
|
*/
|
|
36
|
-
export declare class ExecutableDeleteBuilder<
|
|
35
|
+
export declare class ExecutableDeleteBuilder<Occ extends FMTable<any, any>> implements ExecutableBuilder<{
|
|
37
36
|
deletedCount: number;
|
|
38
37
|
}> {
|
|
39
|
-
private
|
|
40
|
-
private
|
|
41
|
-
private
|
|
42
|
-
private
|
|
43
|
-
private
|
|
44
|
-
private
|
|
45
|
-
private
|
|
46
|
-
private databaseUseEntityIds;
|
|
38
|
+
private readonly databaseName;
|
|
39
|
+
private readonly context;
|
|
40
|
+
private readonly table;
|
|
41
|
+
private readonly mode;
|
|
42
|
+
private readonly recordId?;
|
|
43
|
+
private readonly queryBuilder?;
|
|
44
|
+
private readonly databaseUseEntityIds;
|
|
47
45
|
constructor(config: {
|
|
48
|
-
occurrence
|
|
49
|
-
tableName: string;
|
|
46
|
+
occurrence: Occ;
|
|
50
47
|
databaseName: string;
|
|
51
48
|
context: ExecutionContext;
|
|
52
49
|
mode: "byId" | "byFilter";
|
|
53
50
|
recordId?: string | number;
|
|
54
|
-
queryBuilder?: QueryBuilder<
|
|
51
|
+
queryBuilder?: QueryBuilder<Occ>;
|
|
55
52
|
databaseUseEntityIds?: boolean;
|
|
56
53
|
});
|
|
57
54
|
/**
|
|
@@ -63,9 +60,7 @@ export declare class ExecutableDeleteBuilder<T extends Record<string, any>> impl
|
|
|
63
60
|
* @param useEntityIds - Optional override for entity ID usage
|
|
64
61
|
*/
|
|
65
62
|
private getTableId;
|
|
66
|
-
execute(options?:
|
|
67
|
-
useEntityIds?: boolean;
|
|
68
|
-
}): Promise<Result<{
|
|
63
|
+
execute(options?: ExecuteMethodOptions<ExecuteOptions>): Promise<Result<{
|
|
69
64
|
deletedCount: number;
|
|
70
65
|
}>>;
|
|
71
66
|
getRequestConfig(): {
|
|
@@ -73,8 +68,8 @@ export declare class ExecutableDeleteBuilder<T extends Record<string, any>> impl
|
|
|
73
68
|
url: string;
|
|
74
69
|
body?: any;
|
|
75
70
|
};
|
|
76
|
-
toRequest(baseUrl: string): Request;
|
|
77
|
-
processResponse(response: Response,
|
|
71
|
+
toRequest(baseUrl: string, options?: ExecuteOptions): Request;
|
|
72
|
+
processResponse(response: Response, _options?: ExecuteOptions): Promise<Result<{
|
|
78
73
|
deletedCount: number;
|
|
79
74
|
}>>;
|
|
80
75
|
}
|