UNPKG

@proofkit/fmodata

Version:
181 lines (180 loc) 6.36 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 createClient, { TimeoutError, AbortError, NetworkError, RetryLimitError, CircuitOpenError } from "@fetchkit/ffetch"; import { SchemaLockedError, ODataError, HTTPError } from "../errors.js"; import { Database } from "./database.js"; class FMServerConnection { constructor(config) { __publicField(this, "fetchClient"); __publicField(this, "serverUrl"); __publicField(this, "auth"); __publicField(this, "useEntityIds", false); this.fetchClient = createClient({ retries: 0, ...config.fetchClientOptions }); const url = new URL(config.serverUrl); if (url.protocol !== "https:") { url.protocol = "https:"; } url.pathname = url.pathname.replace(/\/+$/, ""); this.serverUrl = url.toString().replace(/\/+$/, ""); this.auth = config.auth; } /** * @internal * Sets whether to use FileMaker entity IDs (FMFID/FMTID) in requests */ _setUseEntityIds(useEntityIds) { this.useEntityIds = useEntityIds; } /** * @internal * Gets whether to use FileMaker entity IDs (FMFID/FMTID) in requests */ _getUseEntityIds() { return this.useEntityIds; } /** * @internal * Gets the base URL for OData requests */ _getBaseUrl() { return `${this.serverUrl}${"apiKey" in this.auth ? `/otto` : ""}/fmi/odata/v4`; } /** * @internal */ async _makeRequest(url, options) { var _a, _b, _c, _d, _e, _f; const baseUrl = `${this.serverUrl}${"apiKey" in this.auth ? `/otto` : ""}/fmi/odata/v4`; const fullUrl = baseUrl + url; const useEntityIds = (options == null ? void 0 : options.useEntityIds) ?? this.useEntityIds; const headers = { Authorization: "apiKey" in this.auth ? `Bearer ${this.auth.apiKey}` : `Basic ${btoa(`${this.auth.username}:${this.auth.password}`)}`, "Content-Type": "application/json", Accept: "application/json", ...useEntityIds ? { Prefer: "fmodata.entity-ids" } : {}, ...(options == null ? void 0 : options.headers) || {} }; const fetchHandler = options == null ? void 0 : options.fetchHandler; const { headers: _headers, fetchHandler: _fetchHandler, ...restOptions } = options || {}; const clientToUse = fetchHandler ? createClient({ retries: 0, fetchHandler }) : this.fetchClient; try { const finalOptions = { ...restOptions, headers }; const resp = url.includes("/$batch") ? await fetch(fullUrl, { method: finalOptions.method, headers: finalOptions.headers, body: finalOptions.body }) : await clientToUse(fullUrl, finalOptions); if (!resp.ok) { let errorBody; try { if ((_a = resp.headers.get("content-type")) == null ? void 0 : _a.includes("application/json")) { errorBody = await resp.json(); } } catch { } if (errorBody == null ? void 0 : errorBody.error) { const errorCode = errorBody.error.code; const errorMessage = errorBody.error.message || resp.statusText; if (errorCode === "303" || errorCode === 303) { return { data: void 0, error: new SchemaLockedError( fullUrl, errorMessage, errorBody.error ) }; } return { data: void 0, error: new ODataError( fullUrl, errorMessage, errorCode, errorBody.error ) }; } return { data: void 0, error: new HTTPError( fullUrl, resp.status, resp.statusText, errorBody ) }; } const affectedRows = resp.headers.get("fmodata.affected_rows"); if (affectedRows !== null) { return { data: parseInt(affectedRows, 10), error: void 0 }; } if (resp.status === 204) { const locationHeader = ((_c = (_b = resp.headers) == null ? void 0 : _b.get) == null ? void 0 : _c.call(_b, "Location")) || ((_e = (_d = resp.headers) == null ? void 0 : _d.get) == null ? void 0 : _e.call(_d, "location")); if (locationHeader) { return { data: { _location: locationHeader }, error: void 0 }; } return { data: 0, error: void 0 }; } if ((_f = resp.headers.get("content-type")) == null ? void 0 : _f.includes("application/json")) { const data = await resp.json(); if (data.error) { const errorCode = data.error.code; const errorMessage = data.error.message || "Unknown OData error"; if (errorCode === "303" || errorCode === 303) { return { data: void 0, error: new SchemaLockedError(fullUrl, errorMessage, data.error) }; } return { data: void 0, error: new ODataError(fullUrl, errorMessage, errorCode, data.error) }; } return { data, error: void 0 }; } return { data: await resp.text(), error: void 0 }; } catch (err) { if (err instanceof TimeoutError || err instanceof AbortError || err instanceof NetworkError || err instanceof RetryLimitError || err instanceof CircuitOpenError) { return { data: void 0, error: err }; } return { data: void 0, error: new NetworkError(fullUrl, err) }; } } database(name, config) { return new Database(name, this, config); } /** * Lists all available databases from the FileMaker OData service. * @returns Promise resolving to an array of database names */ async listDatabaseNames() { const result = await this._makeRequest("/"); if (result.error) { throw result.error; } if (result.data.value && Array.isArray(result.data.value)) { return result.data.value.map((item) => item.name); } return []; } } export { FMServerConnection }; //# sourceMappingURL=filemaker-odata.js.map