UNPKG

@proofkit/fmdapi

Version:
297 lines (296 loc) 9.66 kB
import { FileMakerError } from "./client-types.js"; function asNumber(input) { return typeof input === "string" ? parseInt(input) : input; } function DataApi(options) { if ("zodValidators" in options) { throw new Error( "zodValidators is no longer supported. Use schema instead, or re-run the typegen command" ); } const schema = options.schema; const layout = options.layout; const { create, delete: _adapterDelete, find, get, list, update, layoutMetadata, containerUpload, ...otherMethods } = options.adapter; async function _list(args) { const { fetch, timeout, ...params } = args ?? {}; if ("limit" in params && params.limit !== void 0) delete Object.assign(params, { _limit: params.limit })["limit"]; if ("offset" in params && params.offset !== void 0) { if (params.offset <= 1) delete params.offset; else delete Object.assign(params, { _offset: params.offset })["offset"]; } if ("sort" in params && params.sort !== void 0) delete Object.assign(params, { _sort: Array.isArray(params.sort) ? params.sort : [params.sort] })["sort"]; const result = await list({ layout, data: params, fetch, timeout }); if (result.dataInfo.foundCount > result.dataInfo.returnedCount) { if ((args == null ? void 0 : args.limit) === void 0 && (args == null ? void 0 : args.offset) === void 0) { console.warn( `🚨 @proofkit/fmdapi: Loaded only ${result.dataInfo.returnedCount} of the ${result.dataInfo.foundCount} records from your "${layout}" layout. Use the "listAll" method to automatically paginate through all records, or specify a "limit" and "offset" to handle pagination yourself.` ); } } return await runSchemaValidationAndTransform( schema, result ); } async function listAll(args) { let runningData = []; const limit = (args == null ? void 0 : args.limit) ?? 100; let offset = (args == null ? void 0 : args.offset) ?? 1; while (true) { const data = await _list({ ...args, offset // eslint-disable-next-line @typescript-eslint/no-explicit-any }); runningData = [...runningData, ...data.data]; if (runningData.length >= data.dataInfo.foundCount) break; offset = offset + limit; } return runningData; } async function _create(args) { const { fetch, timeout, ...params } = args ?? {}; return await create({ layout, data: params, fetch, timeout }); } async function _get(args) { args.recordId = asNumber(args.recordId); const { recordId, fetch, timeout, ...params } = args; const result = await get({ layout, data: { ...params, recordId }, fetch, timeout }); return await runSchemaValidationAndTransform( schema, result ); } async function _update(args) { args.recordId = asNumber(args.recordId); const { recordId, fetch, timeout, ...params } = args; return await update({ layout, data: { ...params, recordId }, fetch, timeout }); } async function deleteRecord(args) { args.recordId = asNumber(args.recordId); const { recordId, fetch, timeout, ...params } = args; return _adapterDelete({ layout, data: { ...params, recordId }, fetch, timeout }); } async function _find(args) { const { query: queryInput, ignoreEmptyResult = false, timeout, fetch, ...params } = args; const query = !Array.isArray(queryInput) ? [queryInput] : queryInput; if ("offset" in params && params.offset !== void 0) { if (params.offset <= 1) delete params.offset; } if ("dateformats" in params && params.dateformats !== void 0) { params.dateformats = (params.dateformats === "US" ? 0 : params.dateformats === "file_locale" ? 1 : params.dateformats === "ISO8601" ? 2 : 0).toString(); } const result = await find({ data: { ...params, query }, layout, fetch, timeout }).catch((e) => { if (ignoreEmptyResult && e instanceof FileMakerError && e.code === "401") return { data: [], dataInfo: { foundCount: 0, returnedCount: 0 } }; throw e; }); if (result.dataInfo.foundCount > result.dataInfo.returnedCount) { if ((args == null ? void 0 : args.limit) === void 0 && (args == null ? void 0 : args.offset) === void 0) { console.warn( `🚨 @proofkit/fmdapi: Loaded only ${result.dataInfo.returnedCount} of the ${result.dataInfo.foundCount} records from your "${layout}" layout. Use the "findAll" method to automatically paginate through all records, or specify a "limit" and "offset" to handle pagination yourself.` ); } } return await runSchemaValidationAndTransform(schema, result); } async function findOne(args) { const result = await _find(args); if (result.data.length !== 1) throw new Error( `${result.data.length} records found; expecting exactly 1` ); const transformedResult = await runSchemaValidationAndTransform( schema, result ); if (!transformedResult.data[0]) throw new Error("No data found"); return { ...transformedResult, data: transformedResult.data[0] }; } async function findFirst(args) { const result = await _find(args); const transformedResult = await runSchemaValidationAndTransform( schema, result ); if (!transformedResult.data[0]) throw new Error("No data found"); return { ...transformedResult, data: transformedResult.data[0] }; } async function maybeFindFirst(args) { const result = await _find({ ...args, ignoreEmptyResult: true }); const transformedResult = await runSchemaValidationAndTransform( schema, result ); if (!transformedResult.data[0]) return null; return { ...transformedResult, data: transformedResult.data[0] }; } async function findAll(args) { let runningData = []; const limit = args.limit ?? 100; let offset = args.offset ?? 1; while (true) { const data = await _find({ ...args, offset, ignoreEmptyResult: true }); runningData = [...runningData, ...data.data]; if (runningData.length === 0 || runningData.length >= data.dataInfo.foundCount) break; offset = offset + limit; } return runningData; } async function _layoutMetadata(args) { const { ...restArgs } = args ?? {}; const params = restArgs; return await layoutMetadata({ layout, fetch: params.fetch, // Now should correctly resolve to undefined if not present timeout: params.timeout // Now should correctly resolve to undefined if not present }); } async function _containerUpload(args) { const { ...params } = args; return await containerUpload({ layout, data: { ...params, containerFieldName: params.containerFieldName, repetition: params.containerFieldRepetition }, fetch: params.fetch, timeout: params.timeout }); } async function runSchemaValidationAndTransform(schema2, result) { var _a; const fieldDataIssues = []; const portalDataIssues = []; if (!schema2) return result; const transformedData = []; for (const record of result.data) { let fieldResult = schema2.fieldData["~standard"].validate( record.fieldData ); if (fieldResult instanceof Promise) fieldResult = await fieldResult; if ("value" in fieldResult) { record.fieldData = fieldResult.value; } else { fieldDataIssues.push(...fieldResult.issues); } if (schema2.portalData) { for (const [portalName, portalRecords] of Object.entries( record.portalData )) { const validatedPortalRecords = []; for (const portalRecord of portalRecords) { let portalResult = (_a = schema2.portalData[portalName]) == null ? void 0 : _a["~standard"].validate( portalRecord ); if (portalResult instanceof Promise) portalResult = await portalResult; if (portalResult && "value" in portalResult) { validatedPortalRecords.push({ ...portalResult.value, recordId: portalRecord.recordId, modId: portalRecord.modId }); } else { portalDataIssues.push(...(portalResult == null ? void 0 : portalResult.issues) ?? []); } } record.portalData[portalName] = validatedPortalRecords; } } transformedData.push(record); } result.data = transformedData; if (fieldDataIssues.length > 0 || portalDataIssues.length > 0) { console.error( `🚨 @proofkit/fmdapi: Validation issues for layout "${layout}". Run the typegen command again to generate the latest field definitions from your layout.`, { fieldDataIssues, portalDataIssues } ); throw new Error("Schema validation issues"); } return result; } return { ...otherMethods, layout: options.layout, list: _list, listAll, create: _create, get: _get, update: _update, delete: deleteRecord, find: _find, findOne, findFirst, maybeFindFirst, findAll, layoutMetadata: _layoutMetadata, containerUpload: _containerUpload }; } export { DataApi, DataApi as default }; //# sourceMappingURL=client.js.map