@proofkit/fmodata
Version:
FileMaker OData API client
214 lines (213 loc) • 8.07 kB
JavaScript
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
import { getTableIdentifiers, transformTableName, transformResponseFields } from "../transform.js";
import { QueryBuilder } from "./query-builder.js";
import { validateSingleResponse } from "../validation.js";
class RecordBuilder {
constructor(config) {
__publicField(this, "occurrence");
__publicField(this, "tableName");
__publicField(this, "databaseName");
__publicField(this, "context");
__publicField(this, "recordId");
__publicField(this, "operation");
__publicField(this, "operationParam");
__publicField(this, "isNavigateFromEntitySet");
__publicField(this, "navigateRelation");
__publicField(this, "navigateSourceTableName");
__publicField(this, "databaseUseEntityIds");
this.occurrence = config.occurrence;
this.tableName = config.tableName;
this.databaseName = config.databaseName;
this.context = config.context;
this.recordId = config.recordId;
this.databaseUseEntityIds = config.databaseUseEntityIds ?? false;
}
/**
* Helper to merge database-level useEntityIds with per-request options
*/
mergeExecuteOptions(options) {
return {
...options,
useEntityIds: (options == null ? void 0 : options.useEntityIds) ?? this.databaseUseEntityIds
};
}
/**
* Gets the table ID (FMTID) if using entity IDs, otherwise returns the table name
* @param useEntityIds - Optional override for entity ID usage
*/
getTableId(useEntityIds) {
var _a, _b;
if (!this.occurrence) {
return this.tableName;
}
const contextDefault = ((_b = (_a = this.context)._getUseEntityIds) == null ? void 0 : _b.call(_a)) ?? false;
const shouldUseIds = useEntityIds ?? contextDefault;
if (shouldUseIds) {
const identifiers = getTableIdentifiers(this.occurrence);
if (!identifiers.id) {
throw new Error(
`useEntityIds is true but TableOccurrence "${identifiers.name}" does not have an fmtId defined`
);
}
return identifiers.id;
}
return this.occurrence.getTableName();
}
getSingleField(field) {
const newBuilder = new RecordBuilder({
occurrence: this.occurrence,
tableName: this.tableName,
databaseName: this.databaseName,
context: this.context,
recordId: this.recordId
});
newBuilder.operation = "getSingleField";
newBuilder.operationParam = field.toString();
newBuilder.isNavigateFromEntitySet = this.isNavigateFromEntitySet;
newBuilder.navigateRelation = this.navigateRelation;
newBuilder.navigateSourceTableName = this.navigateSourceTableName;
return newBuilder;
}
// Implementation
navigate(relationName) {
var _a;
const targetOccurrence = (_a = this.occurrence) == null ? void 0 : _a.navigation[relationName];
const builder = new QueryBuilder({
occurrence: targetOccurrence,
tableName: (targetOccurrence == null ? void 0 : targetOccurrence.name) ?? relationName,
databaseName: this.databaseName,
context: this.context
});
const relationId = targetOccurrence ? transformTableName(targetOccurrence) : relationName;
builder.isNavigate = true;
builder.navigateRecordId = this.recordId;
builder.navigateRelation = relationId;
if (this.isNavigateFromEntitySet && this.navigateSourceTableName && this.navigateRelation) {
builder.navigateSourceTableName = this.navigateSourceTableName;
builder.navigateBaseRelation = this.navigateRelation;
} else {
const sourceTableId = this.occurrence ? transformTableName(this.occurrence) : this.tableName;
builder.navigateSourceTableName = sourceTableId;
}
return builder;
}
async execute(options) {
var _a, _b, _c;
let url;
if (this.isNavigateFromEntitySet && this.navigateSourceTableName && this.navigateRelation) {
url = `/${this.databaseName}/${this.navigateSourceTableName}/${this.navigateRelation}('${this.recordId}')`;
} else {
const tableId = this.getTableId((options == null ? void 0 : options.useEntityIds) ?? this.databaseUseEntityIds);
url = `/${this.databaseName}/${tableId}('${this.recordId}')`;
}
if (this.operation === "getSingleField" && this.operationParam) {
url += `/${this.operationParam}`;
}
const mergedOptions = this.mergeExecuteOptions(options);
const result = await this.context._makeRequest(url, mergedOptions);
if (result.error) {
return { data: void 0, error: result.error };
}
let response = result.data;
if (this.operation === "getSingleField") {
const fieldResponse = response;
return { data: fieldResponse.value, error: void 0 };
}
const shouldUseIds = mergedOptions.useEntityIds ?? false;
if (((_a = this.occurrence) == null ? void 0 : _a.baseTable) && shouldUseIds) {
response = transformResponseFields(
response,
this.occurrence.baseTable,
void 0
// No expand configs for simple get
);
}
const schema = (_c = (_b = this.occurrence) == null ? void 0 : _b.baseTable) == null ? void 0 : _c.schema;
const validation = await validateSingleResponse(
response,
schema,
void 0,
// No selected fields for record.get()
void 0,
// No expand configs
"exact"
// Expect exactly one record
);
if (!validation.valid) {
return { data: void 0, error: validation.error };
}
if (validation.data === null) {
return { data: null, error: void 0 };
}
return { data: validation.data, error: void 0 };
}
getRequestConfig() {
let url;
if (this.isNavigateFromEntitySet && this.navigateSourceTableName && this.navigateRelation) {
url = `/${this.databaseName}/${this.navigateSourceTableName}/${this.navigateRelation}('${this.recordId}')`;
} else {
const tableId = this.getTableId(this.databaseUseEntityIds);
url = `/${this.databaseName}/${tableId}('${this.recordId}')`;
}
if (this.operation === "getSingleField" && this.operationParam) {
url += `/${this.operationParam}`;
}
return {
method: "GET",
url
};
}
toRequest(baseUrl) {
const config = this.getRequestConfig();
const fullUrl = `${baseUrl}${config.url}`;
return new Request(fullUrl, {
method: config.method,
headers: {
"Content-Type": "application/json",
Accept: "application/json"
}
});
}
async processResponse(response, options) {
var _a, _b, _c;
const rawResponse = await response.json();
if (this.operation === "getSingleField") {
const fieldResponse = rawResponse;
return { data: fieldResponse.value, error: void 0 };
}
const shouldUseIds = (options == null ? void 0 : options.useEntityIds) ?? this.databaseUseEntityIds;
let transformedResponse = rawResponse;
if (((_a = this.occurrence) == null ? void 0 : _a.baseTable) && shouldUseIds) {
transformedResponse = transformResponseFields(
rawResponse,
this.occurrence.baseTable,
void 0
// No expand configs for simple get
);
}
const schema = (_c = (_b = this.occurrence) == null ? void 0 : _b.baseTable) == null ? void 0 : _c.schema;
const validation = await validateSingleResponse(
transformedResponse,
schema,
void 0,
// No selected fields for record.get()
void 0,
// No expand configs
"exact"
// Expect exactly one record
);
if (!validation.valid) {
return { data: void 0, error: validation.error };
}
if (validation.data === null) {
return { data: null, error: void 0 };
}
return { data: validation.data, error: void 0 };
}
}
export {
RecordBuilder
};
//# sourceMappingURL=record-builder.js.map