UNPKG

@proofkit/fmodata

Version:

FileMaker OData API client

149 lines (148 loc) 5.49 kB
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