@proofkit/fmodata
Version:
FileMaker OData API client
149 lines (148 loc) • 5.49 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 { Effect } from "effect";
import buildQuery from "odata-query";
import { requestFromService, runLayerResult } from "../effect.js";
import { ResponseStructureError, isFMODataError, BuilderInvariantError } from "../errors.js";
import { getTableName } from "../orm/table.js";
import { mergeExecuteOptions, createODataRequest } from "./builders/table-utils.js";
import { parseErrorResponse } from "./error-parser.js";
import { QueryUrlBuilder } from "./query/url-builder.js";
import { createClientRuntime } from "./runtime.js";
function normalizeCountBuildError(error) {
if (isFMODataError(error)) {
return error;
}
if (error instanceof Error) {
return new BuilderInvariantError("CountBuilder.execute", error.message, { cause: error });
}
return new BuilderInvariantError("CountBuilder.execute", String(error));
}
class CountBuilder {
constructor(config) {
__publicField(this, "occurrence");
__publicField(this, "layer");
__publicField(this, "config");
__publicField(this, "urlBuilder");
__publicField(this, "filterExpression");
__publicField(this, "queryOptions", {});
__publicField(this, "navigationConfig");
this.occurrence = config.occurrence;
const runtime = createClientRuntime(config.layer);
this.layer = runtime.layer;
this.config = runtime.config;
this.urlBuilder = new QueryUrlBuilder(this.config.databaseName, this.occurrence, this.config.useEntityIds);
}
set navigation(navigation) {
this.navigationConfig = navigation;
}
where(expression) {
if (typeof expression === "string") {
this.filterExpression = void 0;
this.queryOptions.filter = expression;
return this;
}
this.filterExpression = expression;
this.queryOptions.filter = void 0;
return this;
}
buildQueryString(useEntityIds) {
const finalUseEntityIds = useEntityIds ?? this.config.useEntityIds;
const queryOptions = { ...this.queryOptions };
if (this.filterExpression) {
queryOptions.filter = this.filterExpression.toODataFilter(finalUseEntityIds);
}
queryOptions.count = void 0;
queryOptions.select = void 0;
queryOptions.expand = void 0;
queryOptions.top = void 0;
queryOptions.skip = void 0;
queryOptions.orderBy = void 0;
return buildQuery(queryOptions);
}
parseCountValue(raw) {
let count = Number.NaN;
if (typeof raw === "number") {
count = raw;
} else if (typeof raw === "string" && raw.trim() !== "") {
count = Number(raw);
}
return Number.isFinite(count) ? count : new ResponseStructureError("numeric count response", raw);
}
execute(options) {
const mergedOptions = mergeExecuteOptions(options, this.config.useEntityIds);
let queryString;
let url;
try {
queryString = this.buildQueryString(mergedOptions.useEntityIds);
url = this.urlBuilder.build(queryString, {
isCount: true,
useEntityIds: mergedOptions.useEntityIds,
navigation: this.navigationConfig
});
} catch (error) {
return Promise.resolve({
data: void 0,
error: normalizeCountBuildError(error)
});
}
const pipeline = requestFromService(url, mergedOptions).pipe(
Effect.flatMap((data) => {
const parsed = this.parseCountValue(data);
return parsed instanceof ResponseStructureError ? Effect.fail(parsed) : Effect.succeed(parsed);
})
);
return runLayerResult(this.layer, pipeline, "fmodata.query.count", {
"fmodata.table": getTableName(this.occurrence)
});
}
getQueryString(options) {
const useEntityIds = (options == null ? void 0 : options.useEntityIds) ?? this.config.useEntityIds;
const queryString = this.buildQueryString(useEntityIds);
return this.urlBuilder.buildPath(queryString, {
isCount: true,
useEntityIds,
navigation: this.navigationConfig
});
}
// biome-ignore lint/suspicious/noExplicitAny: Request body can be any JSON-serializable value
getRequestConfig() {
const queryString = this.buildQueryString(this.config.useEntityIds);
const url = this.urlBuilder.build(queryString, {
isCount: true,
useEntityIds: this.config.useEntityIds,
navigation: this.navigationConfig
});
return {
method: "GET",
url
};
}
toRequest(baseUrl, options) {
const config = this.getRequestConfig();
return createODataRequest(baseUrl, config, {
...options,
normalizeDatabaseName: (options == null ? void 0 : options.normalizeDatabaseName) ?? this.config.normalizeDatabaseName
});
}
async processResponse(response, _options) {
if (!response.ok) {
const error = await parseErrorResponse(
response,
response.url || `/${this.config.databaseName}/${getTableName(this.occurrence)}/$count`
);
return { data: void 0, error };
}
const raw = await response.text();
const parsed = this.parseCountValue(raw);
if (parsed instanceof ResponseStructureError) {
return { data: void 0, error: parsed };
}
return { data: parsed, error: void 0 };
}
}
export {
CountBuilder
};
//# sourceMappingURL=count-builder.js.map