@proofkit/fmdapi 5.0.3-beta.1 → 5.1.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/intent.js ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env node
2
+ // Auto-generated by @tanstack/intent setup
3
+ // Exposes the intent end-user CLI for consumers of this library.
4
+ // Commit this file, then add to your package.json:
5
+ // "bin": { "intent": "./bin/intent.js" }
6
+ try {
7
+ await import("@tanstack/intent/intent-library");
8
+ } catch (e) {
9
+ if (e?.code === "ERR_MODULE_NOT_FOUND" || e?.code === "MODULE_NOT_FOUND") {
10
+ console.error("@tanstack/intent is not installed.");
11
+ console.error("");
12
+ console.error("Install it as a dev dependency:");
13
+ console.error(" npm add -D @tanstack/intent");
14
+ console.error("");
15
+ console.error("Or run directly:");
16
+ console.error(" npx @tanstack/intent@latest list");
17
+ process.exit(1);
18
+ }
19
+ throw e;
20
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-base.js","sources":["../../../src/adapters/fetch-base.ts"],"sourcesContent":["import type {\n AllLayoutsMetadataResponse,\n CreateResponse,\n DeleteResponse,\n GetResponse,\n LayoutMetadataResponse,\n PortalRanges,\n RawFMResponse,\n ScriptResponse,\n ScriptsMetadataResponse,\n UpdateResponse,\n} from \"../client-types.js\";\nimport { FileMakerError } from \"../client-types.js\";\nimport type {\n Adapter,\n BaseRequest,\n ContainerUploadOptions,\n CreateOptions,\n DeleteOptions,\n ExecuteScriptOptions,\n FindOptions,\n GetOptions,\n LayoutMetadataOptions,\n ListOptions,\n UpdateOptions,\n} from \"./core.js\";\nimport type { BaseFetchAdapterOptions, GetTokenArguments } from \"./fetch-base-types.js\";\n\nexport class BaseFetchAdapter implements Adapter {\n protected server: string;\n protected db: string;\n private readonly refreshToken: boolean;\n baseUrl: URL;\n\n constructor(options: BaseFetchAdapterOptions & { refreshToken?: boolean }) {\n this.server = options.server;\n this.db = options.db;\n this.refreshToken = options.refreshToken ?? false;\n this.baseUrl = new URL(`${this.server}/fmi/data/vLatest/databases/${this.db}`);\n\n if (this.db === \"\") {\n throw new Error(\"Database name is required\");\n }\n }\n\n protected getToken = (_args?: GetTokenArguments): Promise<string> => {\n // method must be implemented in subclass\n return Promise.reject(new Error(\"getToken method not implemented by Fetch Adapter\"));\n };\n\n protected request = async (params: {\n url: string;\n body?: object | FormData;\n query?: Record<string, string>;\n method?: string;\n retry?: boolean;\n portalRanges?: PortalRanges;\n timeout?: number;\n fetchOptions?: RequestInit;\n }): Promise<unknown> => {\n const { query, body, method = \"GET\", retry = false, fetchOptions = {} } = params;\n\n const url = new URL(`${this.baseUrl}${params.url}`);\n\n if (query) {\n const { _sort, ...rest } = query;\n // Filter out undefined/null values before creating URLSearchParams\n const filteredRest = Object.fromEntries(Object.entries(rest).filter(([, v]) => v !== undefined && v !== null));\n const searchParams = new URLSearchParams(filteredRest as Record<string, string>);\n if (query.portalRanges && typeof query.portalRanges === \"object\") {\n for (const [portalName, value] of Object.entries(query.portalRanges as PortalRanges)) {\n if (value) {\n if (value.offset && value.offset > 0) {\n searchParams.set(`_offset.${portalName}`, value.offset.toString());\n }\n if (value.limit) {\n searchParams.set(`_limit.${portalName}`, value.limit.toString());\n }\n }\n }\n }\n if (_sort) {\n searchParams.set(\"_sort\", JSON.stringify(_sort));\n }\n searchParams.delete(\"portalRanges\");\n url.search = searchParams.toString();\n }\n\n if (body && \"portalRanges\" in body) {\n for (const [portalName, value] of Object.entries(body.portalRanges as PortalRanges)) {\n if (value) {\n if (value.offset && value.offset > 0) {\n url.searchParams.set(`_offset.${portalName}`, value.offset.toString());\n }\n if (value.limit) {\n url.searchParams.set(`_limit.${portalName}`, value.limit.toString());\n }\n }\n }\n body.portalRanges = undefined;\n }\n\n const controller = new AbortController();\n let timeout: NodeJS.Timeout | null = null;\n if (params.timeout) {\n timeout = setTimeout(() => controller.abort(), params.timeout);\n }\n\n const token = await this.getToken({ refresh: retry });\n\n const headers = new Headers(fetchOptions?.headers);\n headers.set(\"Authorization\", `Bearer ${token}`);\n\n // Only set Content-Type for JSON bodies\n if (!(body instanceof FormData)) {\n headers.set(\"Content-Type\", \"application/json\");\n }\n\n let requestBody: string | FormData | undefined;\n if (body instanceof FormData) {\n requestBody = body;\n } else if (body) {\n requestBody = JSON.stringify(body);\n } else {\n requestBody = undefined;\n }\n\n const res = await fetch(url.toString(), {\n ...fetchOptions,\n method,\n body: requestBody,\n headers,\n signal: controller.signal,\n });\n\n if (timeout) {\n clearTimeout(timeout);\n }\n\n let respData: RawFMResponse;\n try {\n respData = await res.json();\n } catch {\n respData = {};\n }\n\n if (!res.ok) {\n if (respData?.messages?.[0].code === \"952\" && !retry && this.refreshToken) {\n // token expired, get new token and retry once\n return this.request({ ...params, retry: true });\n }\n throw new FileMakerError(\n respData?.messages?.[0].code ?? \"500\",\n `Filemaker Data API failed with (${res.status}): ${JSON.stringify(respData, null, 2)}`,\n );\n }\n\n return respData.response;\n };\n\n list = async (opts: ListOptions): Promise<GetResponse> => {\n const { data, layout } = opts;\n\n const resp = await this.request({\n url: `/layouts/${layout}/records`,\n query: data as Record<string, string>,\n fetchOptions: opts.fetch,\n timeout: opts.timeout,\n });\n return resp as GetResponse;\n };\n\n get = async (opts: GetOptions): Promise<GetResponse> => {\n const { data, layout } = opts;\n const resp = await this.request({\n url: `/layouts/${layout}/records/${data.recordId}`,\n fetchOptions: opts.fetch,\n timeout: opts.timeout,\n });\n return resp as GetResponse;\n };\n\n find = async (opts: FindOptions): Promise<GetResponse> => {\n const { data, layout } = opts;\n const resp = await this.request({\n url: `/layouts/${layout}/_find`,\n body: data,\n method: \"POST\",\n fetchOptions: opts.fetch,\n timeout: opts.timeout,\n });\n return resp as GetResponse;\n };\n\n create = async (opts: CreateOptions): Promise<CreateResponse> => {\n const { data, layout } = opts;\n const resp = await this.request({\n url: `/layouts/${layout}/records`,\n body: data,\n method: \"POST\",\n fetchOptions: opts.fetch,\n timeout: opts.timeout,\n });\n return resp as CreateResponse;\n };\n\n update = async (opts: UpdateOptions): Promise<UpdateResponse> => {\n const {\n data: { recordId, ...data },\n layout,\n } = opts;\n const resp = await this.request({\n url: `/layouts/${layout}/records/${recordId}`,\n body: data,\n method: \"PATCH\",\n fetchOptions: opts.fetch,\n timeout: opts.timeout,\n });\n return resp as UpdateResponse;\n };\n\n delete = async (opts: DeleteOptions): Promise<DeleteResponse> => {\n const { data, layout } = opts;\n const resp = await this.request({\n url: `/layouts/${layout}/records/${data.recordId}`,\n method: \"DELETE\",\n fetchOptions: opts.fetch,\n timeout: opts.timeout,\n });\n return resp as DeleteResponse;\n };\n\n layoutMetadata = async (opts: LayoutMetadataOptions): Promise<LayoutMetadataResponse> => {\n return (await this.request({\n url: `/layouts/${opts.layout}`,\n fetchOptions: opts.fetch,\n timeout: opts.timeout,\n })) as LayoutMetadataResponse;\n };\n\n /**\n * Execute a script within the database\n */\n executeScript = async (opts: ExecuteScriptOptions) => {\n const { script, scriptParam, layout } = opts;\n const resp = await this.request({\n url: `/layouts/${layout}/script/${script}`,\n query: scriptParam ? { \"script.param\": scriptParam } : undefined,\n fetchOptions: opts.fetch,\n timeout: opts.timeout,\n });\n return resp as ScriptResponse;\n };\n\n /**\n * Returns a list of available layouts on the database.\n */\n layouts = async (opts?: Omit<BaseRequest, \"layout\">) => {\n return (await this.request({\n url: \"/layouts\",\n fetchOptions: opts?.fetch,\n timeout: opts?.timeout,\n })) as AllLayoutsMetadataResponse;\n };\n\n /**\n * Returns a list of available scripts on the database.\n */\n scripts = async (opts?: Omit<BaseRequest, \"layout\">) => {\n return (await this.request({\n url: \"/scripts\",\n fetchOptions: opts?.fetch,\n timeout: opts?.timeout,\n })) as ScriptsMetadataResponse;\n };\n\n containerUpload = async (opts: ContainerUploadOptions) => {\n let url = `/layouts/${opts.layout}/records/${opts.data.recordId}/containers/${opts.data.containerFieldName}`;\n if (opts.data.repetition) {\n url += `/${opts.data.repetition}`;\n }\n const formData = new FormData();\n formData.append(\"upload\", opts.data.file);\n\n await this.request({\n url,\n method: \"POST\",\n body: formData,\n timeout: opts.timeout,\n fetchOptions: opts.fetch,\n });\n };\n\n /**\n * Set global fields for the current session\n */\n globals = async (\n opts: Omit<BaseRequest, \"layout\"> & {\n globalFields: Record<string, string | number>;\n },\n ) => {\n return (await this.request({\n url: \"/globals\",\n method: \"PATCH\",\n body: { globalFields: opts.globalFields },\n fetchOptions: opts?.fetch,\n timeout: opts?.timeout,\n })) as Record<string, never>;\n };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fetch-base.js","sources":["../../../src/adapters/fetch-base.ts"],"sourcesContent":["import type {\n AllLayoutsMetadataResponse,\n CreateResponse,\n DeleteResponse,\n GetResponse,\n LayoutMetadataResponse,\n PortalRanges,\n RawFMResponse,\n ScriptResponse,\n ScriptsMetadataResponse,\n UpdateResponse,\n} from \"../client-types.js\";\nimport { FileMakerError } from \"../client-types.js\";\nimport type {\n Adapter,\n BaseRequest,\n ContainerUploadOptions,\n CreateOptions,\n DeleteOptions,\n ExecuteScriptOptions,\n FindOptions,\n GetOptions,\n LayoutMetadataOptions,\n ListOptions,\n UpdateOptions,\n} from \"./core.js\";\nimport type { BaseFetchAdapterOptions, GetTokenArguments } from \"./fetch-base-types.js\";\n\nexport class BaseFetchAdapter implements Adapter {\n protected server: string;\n protected db: string;\n private readonly refreshToken: boolean;\n baseUrl: URL;\n\n constructor(options: BaseFetchAdapterOptions & { refreshToken?: boolean }) {\n this.server = options.server;\n this.db = options.db;\n this.refreshToken = options.refreshToken ?? false;\n this.baseUrl = new URL(`${this.server}/fmi/data/vLatest/databases/${this.db}`);\n\n if (this.db === \"\") {\n throw new Error(\"Database name is required\");\n }\n }\n\n protected getToken = (_args?: GetTokenArguments): Promise<string> => {\n // method must be implemented in subclass\n return Promise.reject(new Error(\"getToken method not implemented by Fetch Adapter\"));\n };\n\n protected request = async (params: {\n url: string;\n body?: object | FormData;\n query?: Record<string, string>;\n method?: string;\n retry?: boolean;\n portalRanges?: PortalRanges;\n timeout?: number;\n fetchOptions?: RequestInit;\n }): Promise<unknown> => {\n const { query, body, method = \"GET\", retry = false, fetchOptions = {} } = params;\n\n const url = new URL(`${this.baseUrl}${params.url}`);\n\n if (query) {\n const { _sort, ...rest } = query;\n // Filter out undefined/null values before creating URLSearchParams\n const filteredRest = Object.fromEntries(Object.entries(rest).filter(([, v]) => v !== undefined && v !== null));\n const searchParams = new URLSearchParams(filteredRest as Record<string, string>);\n if (query.portalRanges && typeof query.portalRanges === \"object\") {\n for (const [portalName, value] of Object.entries(query.portalRanges as PortalRanges)) {\n if (value) {\n if (value.offset && value.offset > 0) {\n searchParams.set(`_offset.${portalName}`, value.offset.toString());\n }\n if (value.limit) {\n searchParams.set(`_limit.${portalName}`, value.limit.toString());\n }\n }\n }\n }\n if (_sort) {\n searchParams.set(\"_sort\", JSON.stringify(_sort));\n }\n searchParams.delete(\"portalRanges\");\n url.search = searchParams.toString();\n }\n\n if (body && \"portalRanges\" in body) {\n for (const [portalName, value] of Object.entries(body.portalRanges as PortalRanges)) {\n if (value) {\n if (value.offset && value.offset > 0) {\n url.searchParams.set(`_offset.${portalName}`, value.offset.toString());\n }\n if (value.limit) {\n url.searchParams.set(`_limit.${portalName}`, value.limit.toString());\n }\n }\n }\n body.portalRanges = undefined;\n }\n\n const controller = new AbortController();\n let timeout: NodeJS.Timeout | null = null;\n if (params.timeout) {\n timeout = setTimeout(() => controller.abort(), params.timeout);\n }\n\n const token = await this.getToken({ refresh: retry });\n\n const headers = new Headers(fetchOptions?.headers);\n headers.set(\"Authorization\", `Bearer ${token}`);\n\n // Only set Content-Type for JSON bodies\n if (!(body instanceof FormData)) {\n headers.set(\"Content-Type\", \"application/json\");\n }\n\n let requestBody: string | FormData | undefined;\n if (body instanceof FormData) {\n requestBody = body;\n } else if (body) {\n requestBody = JSON.stringify(body);\n } else {\n requestBody = undefined;\n }\n\n const res = await fetch(url.toString(), {\n ...fetchOptions,\n method,\n body: requestBody,\n headers,\n signal: controller.signal,\n });\n\n if (timeout) {\n clearTimeout(timeout);\n }\n\n let respData: RawFMResponse;\n try {\n respData = await res.json();\n } catch {\n respData = {};\n }\n\n if (!res.ok) {\n if (respData?.messages?.[0].code === \"952\" && !retry && this.refreshToken) {\n // token expired, get new token and retry once\n return this.request({ ...params, retry: true });\n }\n throw new FileMakerError(\n respData?.messages?.[0].code ?? \"500\",\n `Filemaker Data API failed with (${res.status}): ${JSON.stringify(respData, null, 2)}`,\n );\n }\n\n return respData.response;\n };\n\n list = async (opts: ListOptions): Promise<GetResponse> => {\n const { data, layout } = opts;\n\n const resp = await this.request({\n url: `/layouts/${layout}/records`,\n query: data as Record<string, string>,\n fetchOptions: opts.fetch,\n timeout: opts.timeout,\n });\n return resp as GetResponse;\n };\n\n get = async (opts: GetOptions): Promise<GetResponse> => {\n const { data, layout } = opts;\n const resp = await this.request({\n url: `/layouts/${layout}/records/${data.recordId}`,\n fetchOptions: opts.fetch,\n timeout: opts.timeout,\n });\n return resp as GetResponse;\n };\n\n find = async (opts: FindOptions): Promise<GetResponse> => {\n const { data, layout } = opts;\n const resp = await this.request({\n url: `/layouts/${layout}/_find`,\n body: data,\n method: \"POST\",\n fetchOptions: opts.fetch,\n timeout: opts.timeout,\n });\n return resp as GetResponse;\n };\n\n create = async (opts: CreateOptions): Promise<CreateResponse> => {\n const { data, layout } = opts;\n const resp = await this.request({\n url: `/layouts/${layout}/records`,\n body: data,\n method: \"POST\",\n fetchOptions: opts.fetch,\n timeout: opts.timeout,\n });\n return resp as CreateResponse;\n };\n\n update = async (opts: UpdateOptions): Promise<UpdateResponse> => {\n const {\n data: { recordId, ...data },\n layout,\n } = opts;\n const resp = await this.request({\n url: `/layouts/${layout}/records/${recordId}`,\n body: data,\n method: \"PATCH\",\n fetchOptions: opts.fetch,\n timeout: opts.timeout,\n });\n return resp as UpdateResponse;\n };\n\n delete = async (opts: DeleteOptions): Promise<DeleteResponse> => {\n const { data, layout } = opts;\n const resp = await this.request({\n url: `/layouts/${layout}/records/${data.recordId}`,\n method: \"DELETE\",\n fetchOptions: opts.fetch,\n timeout: opts.timeout,\n });\n return resp as DeleteResponse;\n };\n\n layoutMetadata = async (opts: LayoutMetadataOptions): Promise<LayoutMetadataResponse> => {\n return (await this.request({\n url: `/layouts/${opts.layout}`,\n fetchOptions: opts.fetch,\n timeout: opts.timeout,\n })) as LayoutMetadataResponse;\n };\n\n /**\n * Execute a script within the database\n */\n executeScript = async (opts: ExecuteScriptOptions) => {\n const { script, scriptParam, layout } = opts;\n const resp = await this.request({\n url: `/layouts/${layout}/script/${script}`,\n query: scriptParam ? { \"script.param\": scriptParam } : undefined,\n fetchOptions: opts.fetch,\n timeout: opts.timeout,\n });\n return resp as ScriptResponse;\n };\n\n /**\n * Returns a list of available layouts on the database.\n */\n layouts = async (opts?: Omit<BaseRequest, \"layout\">) => {\n return (await this.request({\n url: \"/layouts\",\n fetchOptions: opts?.fetch,\n timeout: opts?.timeout,\n })) as AllLayoutsMetadataResponse;\n };\n\n /**\n * Returns a list of available scripts on the database.\n */\n scripts = async (opts?: Omit<BaseRequest, \"layout\">) => {\n return (await this.request({\n url: \"/scripts\",\n fetchOptions: opts?.fetch,\n timeout: opts?.timeout,\n })) as ScriptsMetadataResponse;\n };\n\n containerUpload = async (opts: ContainerUploadOptions) => {\n let url = `/layouts/${opts.layout}/records/${opts.data.recordId}/containers/${opts.data.containerFieldName}`;\n if (opts.data.repetition) {\n url += `/${opts.data.repetition}`;\n }\n const formData = new FormData();\n formData.append(\"upload\", opts.data.file);\n\n await this.request({\n url,\n method: \"POST\",\n body: formData,\n timeout: opts.timeout,\n fetchOptions: opts.fetch,\n });\n };\n\n /**\n * Set global fields for the current session\n */\n globals = async (\n opts: Omit<BaseRequest, \"layout\"> & {\n globalFields: Record<string, string | number>;\n },\n ) => {\n return (await this.request({\n url: \"/globals\",\n method: \"PATCH\",\n body: { globalFields: opts.globalFields },\n fetchOptions: opts?.fetch,\n timeout: opts?.timeout,\n })) as Record<string, never>;\n };\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.js","sources":["../../../src/adapters/fetch.ts"],"sourcesContent":["import { FileMakerError } from \"../client-types.js\";\nimport memoryStore from \"../tokenStore/memory.js\";\nimport type { TokenStoreDefinitions } from \"../tokenStore/types.js\";\nimport { BaseFetchAdapter } from \"./fetch-base.js\";\nimport type { BaseFetchAdapterOptions, GetTokenArguments } from \"./fetch-base-types.js\";\n\nexport interface FetchAdapterOptions extends BaseFetchAdapterOptions {\n auth: {\n username: string;\n password: string;\n };\n tokenStore?: TokenStoreDefinitions;\n}\n\nexport class FetchAdapter extends BaseFetchAdapter {\n private readonly username: string;\n private readonly password: string;\n private readonly tokenStore: Omit<TokenStoreDefinitions, \"getKey\">;\n private readonly getTokenKey: Required<TokenStoreDefinitions>[\"getKey\"];\n\n constructor(args: FetchAdapterOptions) {\n super({ ...args, refreshToken: true });\n this.username = args.auth.username;\n this.password = args.auth.password;\n this.tokenStore = args.tokenStore ?? memoryStore();\n this.getTokenKey = args.tokenStore?.getKey ?? (() => `${args.server}/${args.db}`);\n\n if (this.username === \"\") {\n throw new Error(\"Username is required\");\n }\n if (this.password === \"\") {\n throw new Error(\"Password is required\");\n }\n }\n\n /**\n * Gets a FileMaker Data API token for authentication.\n *\n * This token is **NOT** guaranteed to be valid, since it expires 15 minutes after the last use. Pass `refresh=true` to forcibly get a fresh token\n *\n * @param args.refresh - If true, forces getting a new token instead of using cached token\n * @internal This method is intended for internal use, you should not need to use it in most cases.\n */\n override getToken = async (args?: GetTokenArguments): Promise<string> => {\n const { refresh = false } = args ?? {};\n let token: string | null = null;\n if (!refresh) {\n token = await this.tokenStore.getToken(this.getTokenKey());\n }\n\n if (!token) {\n const res = await fetch(`${this.baseUrl}/sessions`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Basic ${Buffer.from(`${this.username}:${this.password}`).toString(\"base64\")}`,\n },\n });\n\n if (!res.ok) {\n const data = await res.json();\n throw new FileMakerError(data.messages[0].code, data.messages[0].message);\n }\n token = res.headers.get(\"X-FM-Data-Access-Token\");\n if (!token) {\n throw new Error(\"Could not get token\");\n }\n this.tokenStore.setToken(this.getTokenKey(), token);\n }\n\n return token;\n };\n\n disconnect = async (): Promise<void> => {\n const token = await this.tokenStore.getToken(this.getTokenKey());\n if (token) {\n await this.request({\n url: `/sessions/${token}`,\n method: \"DELETE\",\n fetchOptions: {\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n },\n });\n this.tokenStore.clearToken(this.getTokenKey());\n }\n };\n}\n"],"names":[],"mappings":";;;;;;AAcO,MAAM,qBAAqB,iBAAiB;AAAA,EAMjD,YAAY,MAA2B;;AACrC,UAAM,EAAE,GAAG,MAAM,cAAc,MAAM;AANtB;AACA;AACA;AACA;AAyBR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oCAAW,OAAO,SAA8C;AACvE,YAAM,EAAE,UAAU,MAAM,IAAI,QAAQ,CAAC;AACrC,UAAI,QAAuB;AAC3B,UAAI,CAAC,SAAS;AACZ,gBAAQ,MAAM,KAAK,WAAW,SAAS,KAAK,aAAa;AAAA,MAAA;AAG3D,UAAI,CAAC,OAAO;AACV,cAAM,MAAM,MAAM,MAAM,GAAG,KAAK,OAAO,aAAa;AAAA,UAClD,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,gBAAgB;AAAA,YAChB,eAAe,SAAS,OAAO,KAAK,GAAG,KAAK,QAAQ,IAAI,KAAK,QAAQ,EAAE,EAAE,SAAS,QAAQ,CAAC;AAAA,UAAA;AAAA,QAC7F,CACD;AAEG,YAAA,CAAC,IAAI,IAAI;AACL,gBAAA,OAAO,MAAM,IAAI,KAAK;AACtB,gBAAA,IAAI,eAAe,KAAK,SAAS,CAAC,EAAE,MAAM,KAAK,SAAS,CAAC,EAAE,OAAO;AAAA,QAAA;AAElE,gBAAA,IAAI,QAAQ,IAAI,wBAAwB;AAChD,YAAI,CAAC,OAAO;AACJ,gBAAA,IAAI,MAAM,qBAAqB;AAAA,QAAA;AAEvC,aAAK,WAAW,SAAS,KAAK,YAAA,GAAe,KAAK;AAAA,MAAA;AAG7C,aAAA;AAAA,IACT;AAEA,sCAAa,YAA2B;AACtC,YAAM,QAAQ,MAAM,KAAK,WAAW,SAAS,KAAK,aAAa;AAC/D,UAAI,OAAO;AACT,cAAM,KAAK,QAAQ;AAAA,UACjB,KAAK,aAAa,KAAK;AAAA,UACvB,QAAQ;AAAA,UACR,cAAc;AAAA,YACZ,SAAS;AAAA,cACP,eAAe,UAAU,KAAK;AAAA,cAC9B,gBAAgB;AAAA,YAAA;AAAA,UAClB;AAAA,QACF,CACD;AACD,aAAK,WAAW,WAAW,KAAK,YAAA,CAAa;AAAA,MAAA;AAAA,IAEjD;AAlEO,SAAA,WAAW,KAAK,KAAK;AACrB,SAAA,WAAW,KAAK,KAAK;AACrB,SAAA,aAAa,KAAK,cAAc,YAAY;AAC5C,SAAA,gBAAc,UAAK,eAAL,mBAAiB,YAAW,MAAM,GAAG,KAAK,MAAM,IAAI,KAAK,EAAE;AAE1E,QAAA,KAAK,aAAa,IAAI;AAClB,YAAA,IAAI,MAAM,sBAAsB;AAAA,IAAA;AAEpC,QAAA,KAAK,aAAa,IAAI;AAClB,YAAA,IAAI,MAAM,sBAAsB;AAAA,IAAA;AAAA,EACxC;AAyDJ;"}
1
+ {"version":3,"file":"fetch.js","sources":["../../../src/adapters/fetch.ts"],"sourcesContent":["import { FileMakerError } from \"../client-types.js\";\nimport memoryStore from \"../tokenStore/memory.js\";\nimport type { TokenStoreDefinitions } from \"../tokenStore/types.js\";\nimport { BaseFetchAdapter } from \"./fetch-base.js\";\nimport type { BaseFetchAdapterOptions, GetTokenArguments } from \"./fetch-base-types.js\";\n\nexport interface FetchAdapterOptions extends BaseFetchAdapterOptions {\n auth: {\n username: string;\n password: string;\n };\n tokenStore?: TokenStoreDefinitions;\n}\n\nexport class FetchAdapter extends BaseFetchAdapter {\n private readonly username: string;\n private readonly password: string;\n private readonly tokenStore: Omit<TokenStoreDefinitions, \"getKey\">;\n private readonly getTokenKey: Required<TokenStoreDefinitions>[\"getKey\"];\n\n constructor(args: FetchAdapterOptions) {\n super({ ...args, refreshToken: true });\n this.username = args.auth.username;\n this.password = args.auth.password;\n this.tokenStore = args.tokenStore ?? memoryStore();\n this.getTokenKey = args.tokenStore?.getKey ?? (() => `${args.server}/${args.db}`);\n\n if (this.username === \"\") {\n throw new Error(\"Username is required\");\n }\n if (this.password === \"\") {\n throw new Error(\"Password is required\");\n }\n }\n\n /**\n * Gets a FileMaker Data API token for authentication.\n *\n * This token is **NOT** guaranteed to be valid, since it expires 15 minutes after the last use. Pass `refresh=true` to forcibly get a fresh token\n *\n * @param args.refresh - If true, forces getting a new token instead of using cached token\n * @internal This method is intended for internal use, you should not need to use it in most cases.\n */\n override getToken = async (args?: GetTokenArguments): Promise<string> => {\n const { refresh = false } = args ?? {};\n let token: string | null = null;\n if (!refresh) {\n token = await this.tokenStore.getToken(this.getTokenKey());\n }\n\n if (!token) {\n const res = await fetch(`${this.baseUrl}/sessions`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Basic ${Buffer.from(`${this.username}:${this.password}`).toString(\"base64\")}`,\n },\n });\n\n if (!res.ok) {\n const data = await res.json();\n throw new FileMakerError(data.messages[0].code, data.messages[0].message);\n }\n token = res.headers.get(\"X-FM-Data-Access-Token\");\n if (!token) {\n throw new Error(\"Could not get token\");\n }\n this.tokenStore.setToken(this.getTokenKey(), token);\n }\n\n return token;\n };\n\n disconnect = async (): Promise<void> => {\n const token = await this.tokenStore.getToken(this.getTokenKey());\n if (token) {\n await this.request({\n url: `/sessions/${token}`,\n method: \"DELETE\",\n fetchOptions: {\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n },\n });\n this.tokenStore.clearToken(this.getTokenKey());\n }\n };\n}\n"],"names":[],"mappings":";;;;;;AAcO,MAAM,qBAAqB,iBAAiB;AAAA,EAMjD,YAAY,MAA2B;;AACrC,UAAM,EAAE,GAAG,MAAM,cAAc,MAAM;AANtB;AACA;AACA;AACA;AAyBR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oCAAW,OAAO,SAA8C;AACvE,YAAM,EAAE,UAAU,MAAA,IAAU,QAAQ,CAAA;AACpC,UAAI,QAAuB;AAC3B,UAAI,CAAC,SAAS;AACZ,gBAAQ,MAAM,KAAK,WAAW,SAAS,KAAK,aAAa;AAAA,MAC3D;AAEA,UAAI,CAAC,OAAO;AACV,cAAM,MAAM,MAAM,MAAM,GAAG,KAAK,OAAO,aAAa;AAAA,UAClD,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,gBAAgB;AAAA,YAChB,eAAe,SAAS,OAAO,KAAK,GAAG,KAAK,QAAQ,IAAI,KAAK,QAAQ,EAAE,EAAE,SAAS,QAAQ,CAAC;AAAA,UAAA;AAAA,QAC7F,CACD;AAED,YAAI,CAAC,IAAI,IAAI;AACX,gBAAM,OAAO,MAAM,IAAI,KAAA;AACvB,gBAAM,IAAI,eAAe,KAAK,SAAS,CAAC,EAAE,MAAM,KAAK,SAAS,CAAC,EAAE,OAAO;AAAA,QAC1E;AACA,gBAAQ,IAAI,QAAQ,IAAI,wBAAwB;AAChD,YAAI,CAAC,OAAO;AACV,gBAAM,IAAI,MAAM,qBAAqB;AAAA,QACvC;AACA,aAAK,WAAW,SAAS,KAAK,YAAA,GAAe,KAAK;AAAA,MACpD;AAEA,aAAO;AAAA,IACT;AAEA,sCAAa,YAA2B;AACtC,YAAM,QAAQ,MAAM,KAAK,WAAW,SAAS,KAAK,aAAa;AAC/D,UAAI,OAAO;AACT,cAAM,KAAK,QAAQ;AAAA,UACjB,KAAK,aAAa,KAAK;AAAA,UACvB,QAAQ;AAAA,UACR,cAAc;AAAA,YACZ,SAAS;AAAA,cACP,eAAe,UAAU,KAAK;AAAA,cAC9B,gBAAgB;AAAA,YAAA;AAAA,UAClB;AAAA,QACF,CACD;AACD,aAAK,WAAW,WAAW,KAAK,YAAA,CAAa;AAAA,MAC/C;AAAA,IACF;AAlEE,SAAK,WAAW,KAAK,KAAK;AAC1B,SAAK,WAAW,KAAK,KAAK;AAC1B,SAAK,aAAa,KAAK,cAAc,YAAA;AACrC,SAAK,gBAAc,UAAK,eAAL,mBAAiB,YAAW,MAAM,GAAG,KAAK,MAAM,IAAI,KAAK,EAAE;AAE9E,QAAI,KAAK,aAAa,IAAI;AACxB,YAAM,IAAI,MAAM,sBAAsB;AAAA,IACxC;AACA,QAAI,KAAK,aAAa,IAAI;AACxB,YAAM,IAAI,MAAM,sBAAsB;AAAA,IACxC;AAAA,EACF;AAwDF;"}
@@ -0,0 +1,32 @@
1
+ import { CreateResponse, DeleteResponse, GetResponse, LayoutMetadataResponse, ScriptResponse, UpdateResponse } from '../client-types.js';
2
+ import { Adapter, CreateOptions, DeleteOptions, ExecuteScriptOptions, FindOptions, GetOptions, LayoutMetadataOptions, ListOptions, UpdateOptions } from './core.js';
3
+ export interface FmMcpAdapterOptions {
4
+ /** Base URL of the local FM MCP server (e.g. "http://localhost:3000") */
5
+ baseUrl: string;
6
+ /** Name of the connected FileMaker file */
7
+ connectedFileName: string;
8
+ /** Name of the FM script that executes Data API calls. Defaults to "execute_data_api" */
9
+ scriptName?: string;
10
+ }
11
+ export declare class FmMcpAdapter implements Adapter {
12
+ protected baseUrl: string;
13
+ protected connectedFileName: string;
14
+ protected scriptName: string;
15
+ constructor(options: FmMcpAdapterOptions);
16
+ protected request: (params: {
17
+ layout: string;
18
+ body: object;
19
+ action?: "read" | "metaData" | "create" | "update" | "delete";
20
+ timeout?: number;
21
+ fetchOptions?: RequestInit;
22
+ }) => Promise<unknown>;
23
+ list: (opts: ListOptions) => Promise<GetResponse>;
24
+ get: (opts: GetOptions) => Promise<GetResponse>;
25
+ find: (opts: FindOptions) => Promise<GetResponse>;
26
+ create: (opts: CreateOptions) => Promise<CreateResponse>;
27
+ update: (opts: UpdateOptions) => Promise<UpdateResponse>;
28
+ delete: (opts: DeleteOptions) => Promise<DeleteResponse>;
29
+ layoutMetadata: (opts: LayoutMetadataOptions) => Promise<LayoutMetadataResponse>;
30
+ executeScript: (opts: ExecuteScriptOptions) => Promise<ScriptResponse>;
31
+ containerUpload: () => Promise<never>;
32
+ }
@@ -0,0 +1,170 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+ import { FileMakerError } from "../client-types.js";
5
+ const TRAILING_SLASHES_REGEX = /\/+$/;
6
+ class FmMcpAdapter {
7
+ constructor(options) {
8
+ __publicField(this, "baseUrl");
9
+ __publicField(this, "connectedFileName");
10
+ __publicField(this, "scriptName");
11
+ __publicField(this, "request", async (params) => {
12
+ var _a, _b;
13
+ const { action = "read", layout, body, fetchOptions = {} } = params;
14
+ const normalizedBody = { ...body };
15
+ if ("_offset" in normalizedBody) {
16
+ normalizedBody.offset = normalizedBody._offset;
17
+ normalizedBody._offset = void 0;
18
+ }
19
+ if ("_limit" in normalizedBody) {
20
+ normalizedBody.limit = normalizedBody._limit;
21
+ normalizedBody._limit = void 0;
22
+ }
23
+ if ("_sort" in normalizedBody) {
24
+ normalizedBody.sort = normalizedBody._sort;
25
+ normalizedBody._sort = void 0;
26
+ }
27
+ const scriptParam = JSON.stringify({
28
+ ...normalizedBody,
29
+ layouts: layout,
30
+ action,
31
+ version: "vLatest"
32
+ });
33
+ const controller = new AbortController();
34
+ let timeout = null;
35
+ if (params.timeout) {
36
+ timeout = setTimeout(() => controller.abort(), params.timeout);
37
+ }
38
+ const headers = new Headers(fetchOptions == null ? void 0 : fetchOptions.headers);
39
+ headers.set("Content-Type", "application/json");
40
+ let res;
41
+ try {
42
+ res = await fetch(`${this.baseUrl}/callScript`, {
43
+ ...fetchOptions,
44
+ method: "POST",
45
+ headers,
46
+ body: JSON.stringify({
47
+ connectedFileName: this.connectedFileName,
48
+ scriptName: this.scriptName,
49
+ data: scriptParam
50
+ }),
51
+ signal: controller.signal
52
+ });
53
+ } finally {
54
+ if (timeout) {
55
+ clearTimeout(timeout);
56
+ }
57
+ }
58
+ if (!res.ok) {
59
+ throw new FileMakerError(String(res.status), `FM MCP request failed (${res.status}): ${await res.text()}`);
60
+ }
61
+ const raw = await res.json();
62
+ let scriptResult;
63
+ try {
64
+ scriptResult = typeof raw.result === "string" ? JSON.parse(raw.result) : raw.result ?? raw;
65
+ } catch (err) {
66
+ throw new FileMakerError(
67
+ "500",
68
+ `FM MCP response parse failed: ${err instanceof Error ? err.message : String(err)}`
69
+ );
70
+ }
71
+ const respData = scriptResult;
72
+ const errorCode = (_b = (_a = respData.messages) == null ? void 0 : _a[0]) == null ? void 0 : _b.code;
73
+ if (errorCode !== void 0 && errorCode !== "0") {
74
+ throw new FileMakerError(
75
+ errorCode,
76
+ `Filemaker Data API failed with (${errorCode}): ${JSON.stringify(respData, null, 2)}`
77
+ );
78
+ }
79
+ return respData.response;
80
+ });
81
+ __publicField(this, "list", async (opts) => {
82
+ return await this.request({
83
+ body: opts.data,
84
+ layout: opts.layout,
85
+ timeout: opts.timeout,
86
+ fetchOptions: opts.fetch
87
+ });
88
+ });
89
+ __publicField(this, "get", async (opts) => {
90
+ return await this.request({
91
+ body: opts.data,
92
+ layout: opts.layout,
93
+ timeout: opts.timeout,
94
+ fetchOptions: opts.fetch
95
+ });
96
+ });
97
+ __publicField(this, "find", async (opts) => {
98
+ return await this.request({
99
+ body: opts.data,
100
+ layout: opts.layout,
101
+ timeout: opts.timeout,
102
+ fetchOptions: opts.fetch
103
+ });
104
+ });
105
+ __publicField(this, "create", async (opts) => {
106
+ return await this.request({
107
+ action: "create",
108
+ body: opts.data,
109
+ layout: opts.layout,
110
+ timeout: opts.timeout,
111
+ fetchOptions: opts.fetch
112
+ });
113
+ });
114
+ __publicField(this, "update", async (opts) => {
115
+ return await this.request({
116
+ action: "update",
117
+ body: opts.data,
118
+ layout: opts.layout,
119
+ timeout: opts.timeout,
120
+ fetchOptions: opts.fetch
121
+ });
122
+ });
123
+ __publicField(this, "delete", async (opts) => {
124
+ return await this.request({
125
+ action: "delete",
126
+ body: opts.data,
127
+ layout: opts.layout,
128
+ timeout: opts.timeout,
129
+ fetchOptions: opts.fetch
130
+ });
131
+ });
132
+ __publicField(this, "layoutMetadata", async (opts) => {
133
+ return await this.request({
134
+ action: "metaData",
135
+ layout: opts.layout,
136
+ body: {},
137
+ timeout: opts.timeout,
138
+ fetchOptions: opts.fetch
139
+ });
140
+ });
141
+ __publicField(this, "executeScript", async (opts) => {
142
+ const res = await fetch(`${this.baseUrl}/callScript`, {
143
+ method: "POST",
144
+ headers: { "Content-Type": "application/json" },
145
+ body: JSON.stringify({
146
+ connectedFileName: this.connectedFileName,
147
+ scriptName: opts.script,
148
+ data: opts.scriptParam
149
+ })
150
+ });
151
+ if (!res.ok) {
152
+ throw new FileMakerError(String(res.status), `FM MCP executeScript failed (${res.status}): ${await res.text()}`);
153
+ }
154
+ const raw = await res.json();
155
+ return {
156
+ scriptResult: typeof raw.result === "string" ? raw.result : JSON.stringify(raw.result)
157
+ };
158
+ });
159
+ __publicField(this, "containerUpload", () => {
160
+ throw new Error("Container upload is not supported via FM MCP adapter");
161
+ });
162
+ this.baseUrl = options.baseUrl.replace(TRAILING_SLASHES_REGEX, "");
163
+ this.connectedFileName = options.connectedFileName;
164
+ this.scriptName = options.scriptName ?? "execute_data_api";
165
+ }
166
+ }
167
+ export {
168
+ FmMcpAdapter
169
+ };
170
+ //# sourceMappingURL=fm-mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fm-mcp.js","sources":["../../../src/adapters/fm-mcp.ts"],"sourcesContent":["import type {\n CreateResponse,\n DeleteResponse,\n GetResponse,\n LayoutMetadataResponse,\n RawFMResponse,\n ScriptResponse,\n UpdateResponse,\n} from \"../client-types.js\";\nimport { FileMakerError } from \"../client-types.js\";\nimport type {\n Adapter,\n CreateOptions,\n DeleteOptions,\n ExecuteScriptOptions,\n FindOptions,\n GetOptions,\n LayoutMetadataOptions,\n ListOptions,\n UpdateOptions,\n} from \"./core.js\";\n\nconst TRAILING_SLASHES_REGEX = /\\/+$/;\n\nexport interface FmMcpAdapterOptions {\n /** Base URL of the local FM MCP server (e.g. \"http://localhost:3000\") */\n baseUrl: string;\n /** Name of the connected FileMaker file */\n connectedFileName: string;\n /** Name of the FM script that executes Data API calls. Defaults to \"execute_data_api\" */\n scriptName?: string;\n}\n\nexport class FmMcpAdapter implements Adapter {\n protected baseUrl: string;\n protected connectedFileName: string;\n protected scriptName: string;\n\n constructor(options: FmMcpAdapterOptions) {\n this.baseUrl = options.baseUrl.replace(TRAILING_SLASHES_REGEX, \"\");\n this.connectedFileName = options.connectedFileName;\n this.scriptName = options.scriptName ?? \"execute_data_api\";\n }\n\n protected request = async (params: {\n layout: string;\n body: object;\n action?: \"read\" | \"metaData\" | \"create\" | \"update\" | \"delete\";\n timeout?: number;\n fetchOptions?: RequestInit;\n }): Promise<unknown> => {\n const { action = \"read\", layout, body, fetchOptions = {} } = params;\n\n // Normalize underscore-prefixed keys to match FM script expectations\n const normalizedBody: Record<string, unknown> = { ...body } as Record<string, unknown>;\n if (\"_offset\" in normalizedBody) {\n normalizedBody.offset = normalizedBody._offset;\n normalizedBody._offset = undefined;\n }\n if (\"_limit\" in normalizedBody) {\n normalizedBody.limit = normalizedBody._limit;\n normalizedBody._limit = undefined;\n }\n if (\"_sort\" in normalizedBody) {\n normalizedBody.sort = normalizedBody._sort;\n normalizedBody._sort = undefined;\n }\n\n const scriptParam = JSON.stringify({\n ...normalizedBody,\n layouts: layout,\n action,\n version: \"vLatest\",\n });\n\n const controller = new AbortController();\n let timeout: NodeJS.Timeout | null = null;\n if (params.timeout) {\n timeout = setTimeout(() => controller.abort(), params.timeout);\n }\n\n const headers = new Headers(fetchOptions?.headers);\n headers.set(\"Content-Type\", \"application/json\");\n\n let res: Response;\n try {\n res = await fetch(`${this.baseUrl}/callScript`, {\n ...fetchOptions,\n method: \"POST\",\n headers,\n body: JSON.stringify({\n connectedFileName: this.connectedFileName,\n scriptName: this.scriptName,\n data: scriptParam,\n }),\n signal: controller.signal,\n });\n } finally {\n if (timeout) {\n clearTimeout(timeout);\n }\n }\n\n if (!res.ok) {\n throw new FileMakerError(String(res.status), `FM MCP request failed (${res.status}): ${await res.text()}`);\n }\n\n const raw = await res.json();\n // The /callScript response wraps the script result as a string or object\n let scriptResult: unknown;\n try {\n scriptResult = typeof raw.result === \"string\" ? JSON.parse(raw.result) : (raw.result ?? raw);\n } catch (err) {\n throw new FileMakerError(\n \"500\",\n `FM MCP response parse failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n\n const respData = scriptResult as RawFMResponse;\n\n const errorCode = respData.messages?.[0]?.code;\n if (errorCode !== undefined && errorCode !== \"0\") {\n throw new FileMakerError(\n errorCode,\n `Filemaker Data API failed with (${errorCode}): ${JSON.stringify(respData, null, 2)}`,\n );\n }\n\n return respData.response;\n };\n\n list = async (opts: ListOptions): Promise<GetResponse> => {\n return (await this.request({\n body: opts.data,\n layout: opts.layout,\n timeout: opts.timeout,\n fetchOptions: opts.fetch,\n })) as GetResponse;\n };\n\n get = async (opts: GetOptions): Promise<GetResponse> => {\n return (await this.request({\n body: opts.data,\n layout: opts.layout,\n timeout: opts.timeout,\n fetchOptions: opts.fetch,\n })) as GetResponse;\n };\n\n find = async (opts: FindOptions): Promise<GetResponse> => {\n return (await this.request({\n body: opts.data,\n layout: opts.layout,\n timeout: opts.timeout,\n fetchOptions: opts.fetch,\n })) as GetResponse;\n };\n\n create = async (opts: CreateOptions): Promise<CreateResponse> => {\n return (await this.request({\n action: \"create\",\n body: opts.data,\n layout: opts.layout,\n timeout: opts.timeout,\n fetchOptions: opts.fetch,\n })) as CreateResponse;\n };\n\n update = async (opts: UpdateOptions): Promise<UpdateResponse> => {\n return (await this.request({\n action: \"update\",\n body: opts.data,\n layout: opts.layout,\n timeout: opts.timeout,\n fetchOptions: opts.fetch,\n })) as UpdateResponse;\n };\n\n delete = async (opts: DeleteOptions): Promise<DeleteResponse> => {\n return (await this.request({\n action: \"delete\",\n body: opts.data,\n layout: opts.layout,\n timeout: opts.timeout,\n fetchOptions: opts.fetch,\n })) as DeleteResponse;\n };\n\n layoutMetadata = async (opts: LayoutMetadataOptions): Promise<LayoutMetadataResponse> => {\n return (await this.request({\n action: \"metaData\",\n layout: opts.layout,\n body: {},\n timeout: opts.timeout,\n fetchOptions: opts.fetch,\n })) as LayoutMetadataResponse;\n };\n\n executeScript = async (opts: ExecuteScriptOptions): Promise<ScriptResponse> => {\n const res = await fetch(`${this.baseUrl}/callScript`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n connectedFileName: this.connectedFileName,\n scriptName: opts.script,\n data: opts.scriptParam,\n }),\n });\n\n if (!res.ok) {\n throw new FileMakerError(String(res.status), `FM MCP executeScript failed (${res.status}): ${await res.text()}`);\n }\n\n const raw = await res.json();\n return {\n scriptResult: typeof raw.result === \"string\" ? raw.result : JSON.stringify(raw.result),\n } as ScriptResponse;\n };\n\n containerUpload = (): Promise<never> => {\n throw new Error(\"Container upload is not supported via FM MCP adapter\");\n };\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"otto.js","sources":["../../../src/adapters/otto.ts"],"sourcesContent":["import { BaseFetchAdapter } from \"./fetch-base.js\";\nimport type { BaseFetchAdapterOptions } from \"./fetch-base-types.js\";\n\nexport type Otto3APIKey = `KEY_${string}`;\nexport type OttoFMSAPIKey = `dk_${string}`;\nexport type OttoAPIKey = Otto3APIKey | OttoFMSAPIKey;\n\nexport function isOtto3APIKey(key: string): key is Otto3APIKey {\n return key.startsWith(\"KEY_\");\n}\nexport function isOttoFMSAPIKey(key: string): key is OttoFMSAPIKey {\n return key.startsWith(\"dk_\");\n}\nexport function isOttoAPIKey(key: string): key is OttoAPIKey {\n return isOtto3APIKey(key) || isOttoFMSAPIKey(key);\n}\n\nexport function isOttoAuth(auth: unknown): auth is OttoAuth {\n if (typeof auth !== \"object\" || auth === null) {\n return false;\n }\n return \"apiKey\" in auth;\n}\n\ntype OttoAuth =\n | {\n apiKey: Otto3APIKey;\n ottoPort?: number;\n }\n | { apiKey: OttoFMSAPIKey; ottoPort?: never };\n\nexport type OttoAdapterOptions = BaseFetchAdapterOptions & {\n auth: OttoAuth;\n};\n\nexport class OttoAdapter extends BaseFetchAdapter {\n private readonly apiKey: OttoAPIKey | Otto3APIKey;\n private readonly port: number | undefined;\n\n constructor(options: OttoAdapterOptions) {\n super({ ...options, refreshToken: false });\n this.apiKey = options.auth.apiKey;\n this.port = options.auth.ottoPort;\n\n if (this.apiKey.startsWith(\"KEY_\")) {\n // otto v3 uses port 3030\n this.baseUrl.port = (this.port ?? 3030).toString();\n } else if (this.apiKey.startsWith(\"dk_\")) {\n // otto v4 uses default port, but with /otto prefix\n this.baseUrl.pathname = `otto/${this.baseUrl.pathname.replace(/^\\/+|\\/+$/g, \"\")}`;\n } else {\n throw new Error(\"Invalid Otto API key format. Must start with 'KEY_' (Otto v3) or 'dk_' (OttoFMS)\");\n }\n }\n\n protected override getToken = (): Promise<string> => {\n return Promise.resolve(this.apiKey);\n };\n}\n"],"names":[],"mappings":";;;;AAmCO,MAAM,oBAAoB,iBAAiB;AAAA,EAIhD,YAAY,SAA6B;AACvC,UAAM,EAAE,GAAG,SAAS,cAAc,OAAO;AAJ1B;AACA;AAkBE,oCAAW,MAAuB;AAC5C,aAAA,QAAQ,QAAQ,KAAK,MAAM;AAAA,IACpC;AAhBO,SAAA,SAAS,QAAQ,KAAK;AACtB,SAAA,OAAO,QAAQ,KAAK;AAEzB,QAAI,KAAK,OAAO,WAAW,MAAM,GAAG;AAElC,WAAK,QAAQ,QAAQ,KAAK,QAAQ,MAAM,SAAS;AAAA,IACxC,WAAA,KAAK,OAAO,WAAW,KAAK,GAAG;AAEnC,WAAA,QAAQ,WAAW,QAAQ,KAAK,QAAQ,SAAS,QAAQ,cAAc,EAAE,CAAC;AAAA,IAAA,OAC1E;AACC,YAAA,IAAI,MAAM,kFAAkF;AAAA,IAAA;AAAA,EACpG;AAMJ;"}
1
+ {"version":3,"file":"otto.js","sources":["../../../src/adapters/otto.ts"],"sourcesContent":["import { BaseFetchAdapter } from \"./fetch-base.js\";\nimport type { BaseFetchAdapterOptions } from \"./fetch-base-types.js\";\n\nexport type Otto3APIKey = `KEY_${string}`;\nexport type OttoFMSAPIKey = `dk_${string}`;\nexport type OttoAPIKey = Otto3APIKey | OttoFMSAPIKey;\n\nexport function isOtto3APIKey(key: string): key is Otto3APIKey {\n return key.startsWith(\"KEY_\");\n}\nexport function isOttoFMSAPIKey(key: string): key is OttoFMSAPIKey {\n return key.startsWith(\"dk_\");\n}\nexport function isOttoAPIKey(key: string): key is OttoAPIKey {\n return isOtto3APIKey(key) || isOttoFMSAPIKey(key);\n}\n\nexport function isOttoAuth(auth: unknown): auth is OttoAuth {\n if (typeof auth !== \"object\" || auth === null) {\n return false;\n }\n return \"apiKey\" in auth;\n}\n\ntype OttoAuth =\n | {\n apiKey: Otto3APIKey;\n ottoPort?: number;\n }\n | { apiKey: OttoFMSAPIKey; ottoPort?: never };\n\nexport type OttoAdapterOptions = BaseFetchAdapterOptions & {\n auth: OttoAuth;\n};\n\nexport class OttoAdapter extends BaseFetchAdapter {\n private readonly apiKey: OttoAPIKey | Otto3APIKey;\n private readonly port: number | undefined;\n\n constructor(options: OttoAdapterOptions) {\n super({ ...options, refreshToken: false });\n this.apiKey = options.auth.apiKey;\n this.port = options.auth.ottoPort;\n\n if (this.apiKey.startsWith(\"KEY_\")) {\n // otto v3 uses port 3030\n this.baseUrl.port = (this.port ?? 3030).toString();\n } else if (this.apiKey.startsWith(\"dk_\")) {\n // otto v4 uses default port, but with /otto prefix\n this.baseUrl.pathname = `otto/${this.baseUrl.pathname.replace(/^\\/+|\\/+$/g, \"\")}`;\n } else {\n throw new Error(\"Invalid Otto API key format. Must start with 'KEY_' (Otto v3) or 'dk_' (OttoFMS)\");\n }\n }\n\n protected override getToken = (): Promise<string> => {\n return Promise.resolve(this.apiKey);\n };\n}\n"],"names":[],"mappings":";;;;AAmCO,MAAM,oBAAoB,iBAAiB;AAAA,EAIhD,YAAY,SAA6B;AACvC,UAAM,EAAE,GAAG,SAAS,cAAc,OAAO;AAJ1B;AACA;AAkBE,oCAAW,MAAuB;AACnD,aAAO,QAAQ,QAAQ,KAAK,MAAM;AAAA,IACpC;AAhBE,SAAK,SAAS,QAAQ,KAAK;AAC3B,SAAK,OAAO,QAAQ,KAAK;AAEzB,QAAI,KAAK,OAAO,WAAW,MAAM,GAAG;AAElC,WAAK,QAAQ,QAAQ,KAAK,QAAQ,MAAM,SAAA;AAAA,IAC1C,WAAW,KAAK,OAAO,WAAW,KAAK,GAAG;AAExC,WAAK,QAAQ,WAAW,QAAQ,KAAK,QAAQ,SAAS,QAAQ,cAAc,EAAE,CAAC;AAAA,IACjF,OAAO;AACL,YAAM,IAAI,MAAM,kFAAkF;AAAA,IACpG;AAAA,EACF;AAKF;"}
@@ -1 +1 @@
1
- {"version":3,"file":"client-types.js","sources":["../../src/client-types.ts"],"sourcesContent":["import { z } from \"zod/v4\";\n\nexport const ZFieldValue = z.union([z.string(), z.number(), z.null(), z.unknown()]);\nexport type FieldValue = z.infer<typeof ZFieldValue>;\n\nexport const ZFieldData = z.record(z.string(), ZFieldValue);\nexport type FieldData = Record<string, unknown>;\n\nexport interface GenericPortalData {\n [key: string]: {\n [x: string]: string | number | null | unknown;\n };\n}\n\nexport type PortalsWithIds<U extends GenericPortalData = GenericPortalData> = {\n [key in keyof U]: Array<\n U[key] & {\n recordId: string;\n modId: string;\n }\n >;\n};\nexport type UpdatePortalsWithIds<U extends GenericPortalData = GenericPortalData> = {\n [key in keyof U]: Array<\n U[key] & {\n recordId: string;\n modId?: string;\n }\n >;\n};\n\nexport interface FMRecord<T extends FieldData = FieldData, U extends GenericPortalData = GenericPortalData> {\n fieldData: T;\n recordId: string;\n modId: string;\n portalData: PortalsWithIds<U>;\n}\n\nexport interface ScriptParams {\n script?: string;\n \"script.param\"?: string;\n \"script.prerequest\"?: string;\n \"script.prerequest.param\"?: string;\n \"script.presort\"?: string;\n \"script.presort.param\"?: string;\n timeout?: number;\n}\n\nconst ZScriptResponse = z.object({\n scriptResult: z.string().optional(),\n scriptError: z.string().optional(),\n \"scriptResult.prerequest\": z.string().optional(),\n \"scriptError.prerequest\": z.string().optional(),\n \"scriptResult.presort\": z.string().optional(),\n \"scriptError.presort\": z.string().optional(),\n});\nexport type ScriptResponse = z.infer<typeof ZScriptResponse>;\n\nexport const ZDataInfo = z.object({\n database: z.string(),\n layout: z.string(),\n table: z.string(),\n totalRecordCount: z.number(),\n foundCount: z.number(),\n returnedCount: z.number(),\n});\nexport type DataInfo = z.infer<typeof ZDataInfo>;\n\nexport type CreateParams<U extends GenericPortalData = GenericPortalData> = ScriptParams & {\n portalData?: UpdatePortalsWithIds<U>;\n};\n\nexport type CreateResponse = ScriptResponse & {\n recordId: string;\n modId: string;\n};\n\nexport type UpdateParams<U extends GenericPortalData = GenericPortalData> = CreateParams<U> & {\n modId?: number;\n};\n\nexport type UpdateResponse = ScriptResponse & {\n modId: string;\n};\n\nexport type DeleteParams = ScriptParams;\n\nexport type DeleteResponse = ScriptResponse;\n\nexport interface RangeParams {\n offset?: number;\n limit?: number;\n}\nexport interface RangeParamsRaw {\n _offset?: number;\n _limit?: number;\n}\n\nexport type PortalRanges<U extends GenericPortalData = GenericPortalData> = Partial<{ [key in keyof U]: RangeParams }>;\n\nexport interface PortalRangesParams<U extends GenericPortalData = GenericPortalData> {\n portalRanges?: PortalRanges<U>;\n}\n\nexport type GetParams<U extends GenericPortalData = GenericPortalData> = ScriptParams &\n PortalRangesParams<U> & {\n \"layout.response\"?: string;\n dateformats?: \"US\" | \"file_locale\" | \"ISO8601\";\n };\n\nexport interface Sort<T extends FieldData = FieldData> {\n fieldName: keyof T;\n sortOrder?: \"ascend\" | \"descend\" | (string & {});\n}\n\nexport type ListParams<\n T extends FieldData = FieldData,\n U extends GenericPortalData = GenericPortalData,\n> = GetParams<U> &\n RangeParams & {\n sort?: Sort<T> | Sort<T>[];\n };\n\nexport type ListParamsRaw<\n T extends FieldData = FieldData,\n U extends GenericPortalData = GenericPortalData,\n> = GetParams<U> &\n RangeParamsRaw & {\n _sort?: Sort<T>[];\n };\n\nexport type GetResponse<\n T extends FieldData = FieldData,\n U extends GenericPortalData = GenericPortalData,\n> = ScriptResponse & {\n data: FMRecord<T, U>[];\n dataInfo: DataInfo;\n};\nexport type GetResponseOne<\n T extends FieldData = FieldData,\n U extends GenericPortalData = GenericPortalData,\n> = ScriptResponse & {\n data: FMRecord<T, U>;\n dataInfo: DataInfo;\n};\n\ntype SecondLevelKeys<T> = {\n [K in keyof T]: keyof T[K];\n}[keyof T];\nexport type Query<T extends FieldData = FieldData, U extends GenericPortalData = GenericPortalData> = Partial<{\n [key in keyof T]: T[key] extends number ? number | string : string;\n}> &\n Partial<{ [key in SecondLevelKeys<U>]?: string }> & {\n omit?: \"true\";\n };\n\nexport interface LayoutMetadataResponse {\n fieldMetaData: FieldMetaData[];\n portalMetaData: { [key: string]: FieldMetaData[] };\n valueLists?: ValueList[];\n}\nexport interface ProductInfoMetadataResponse {\n name: string;\n dateFormat: string;\n timeFormat: string;\n timeStampFormat: string;\n}\nexport interface DatabaseMetadataResponse {\n databases: Array<{\n name: string;\n }>;\n}\n\nexport interface FieldMetaData {\n name: string;\n type: \"normal\" | \"calculation\" | \"summary\";\n displayType: \"editText\" | \"popupList\" | \"popupMenu\" | \"checkBox\" | \"calendar\" | \"radioButtons\" | \"secureText\";\n result: \"text\" | \"number\" | \"date\" | \"time\" | \"timeStamp\" | \"container\";\n global: boolean;\n autoEnter: boolean;\n fourDigitYear: boolean;\n maxRepeat: number;\n maxCharacters: number;\n notEmpty: boolean;\n numeric: boolean;\n repetitions: number;\n timeOfDay: boolean;\n valueList?: string;\n}\n\ninterface ValueList {\n name: string;\n // TODO need to test type of value list from other file\n type: \"customList\" | \"byField\";\n values: Array<{ value: string; displayValue: string }>;\n}\n\n/**\n * Represents the data returned by a call to the Data API `layouts` endpoint.\n */\nexport interface AllLayoutsMetadataResponse {\n /**\n * A list of `Layout` or `LayoutsFolder` objects.\n */\n layouts: LayoutOrFolder[];\n}\n\n/**\n * Represents a FileMaker layout.\n */\nexport interface Layout {\n /**\n * The name of the layout\n */\n name: string;\n /**\n * If the node is a layout, `table` may contain the name of the table\n * the layout is associated with.\n */\n table: string;\n}\n\n/**\n * Represents a folder of `Layout` or `LayoutsFolder` objects.\n */\nexport interface LayoutsFolder {\n /**\n * The name of the folder\n */\n name: string;\n isFolder: boolean;\n /**\n * A list of the Layout or LayoutsFolder objects in the folder.\n */\n folderLayoutNames?: LayoutOrFolder[];\n}\n\nexport type LayoutOrFolder = Layout | LayoutsFolder;\n\n/**\n * Represents the data returned by a call to the Data API `scripts` endpoint.\n */\nexport interface ScriptsMetadataResponse {\n /**\n * A list of `Layout` or `LayoutsFolder` objects.\n */\n scripts: ScriptOrFolder[];\n}\ninterface Script {\n name: string;\n isFolder: false;\n}\ninterface ScriptFolder {\n name: string;\n isFolder: true;\n folderScriptNames: ScriptOrFolder[];\n}\nexport type ScriptOrFolder = Script | ScriptFolder;\n\nexport interface RawFMResponse<T = unknown> {\n response?: T;\n messages?: [{ code: string }];\n}\n\nexport class FileMakerError extends Error {\n readonly code: string;\n\n constructor(code: string, message: string) {\n super(message);\n this.code = code;\n }\n}\n"],"names":[],"mappings":";;;;AAEO,MAAM,cAAc,EAAE,MAAM,CAAC,EAAE,UAAU,EAAE,OAAO,GAAG,EAAE,KAAK,GAAG,EAAE,QAAA,CAAS,CAAC;AAG3E,MAAM,aAAa,EAAE,OAAO,EAAE,UAAU,WAAW;AA2ClC,EAAE,OAAO;AAAA,EAC/B,cAAc,EAAE,OAAO,EAAE,SAAS;AAAA,EAClC,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,EACjC,2BAA2B,EAAE,OAAO,EAAE,SAAS;AAAA,EAC/C,0BAA0B,EAAE,OAAO,EAAE,SAAS;AAAA,EAC9C,wBAAwB,EAAE,OAAO,EAAE,SAAS;AAAA,EAC5C,uBAAuB,EAAE,OAAO,EAAE,SAAS;AAC7C,CAAC;AAGY,MAAA,YAAY,EAAE,OAAO;AAAA,EAChC,UAAU,EAAE,OAAO;AAAA,EACnB,QAAQ,EAAE,OAAO;AAAA,EACjB,OAAO,EAAE,OAAO;AAAA,EAChB,kBAAkB,EAAE,OAAO;AAAA,EAC3B,YAAY,EAAE,OAAO;AAAA,EACrB,eAAe,EAAE,OAAO;AAC1B,CAAC;AAuMM,MAAM,uBAAuB,MAAM;AAAA,EAGxC,YAAY,MAAc,SAAiB;AACzC,UAAM,OAAO;AAHN;AAIP,SAAK,OAAO;AAAA,EAAA;AAEhB;"}
1
+ {"version":3,"file":"client-types.js","sources":["../../src/client-types.ts"],"sourcesContent":["import { z } from \"zod/v4\";\n\nexport const ZFieldValue = z.union([z.string(), z.number(), z.null(), z.unknown()]);\nexport type FieldValue = z.infer<typeof ZFieldValue>;\n\nexport const ZFieldData = z.record(z.string(), ZFieldValue);\nexport type FieldData = Record<string, unknown>;\n\nexport interface GenericPortalData {\n [key: string]: {\n [x: string]: string | number | null | unknown;\n };\n}\n\nexport type PortalsWithIds<U extends GenericPortalData = GenericPortalData> = {\n [key in keyof U]: Array<\n U[key] & {\n recordId: string;\n modId: string;\n }\n >;\n};\nexport type UpdatePortalsWithIds<U extends GenericPortalData = GenericPortalData> = {\n [key in keyof U]: Array<\n U[key] & {\n recordId: string;\n modId?: string;\n }\n >;\n};\n\nexport interface FMRecord<T extends FieldData = FieldData, U extends GenericPortalData = GenericPortalData> {\n fieldData: T;\n recordId: string;\n modId: string;\n portalData: PortalsWithIds<U>;\n}\n\nexport interface ScriptParams {\n script?: string;\n \"script.param\"?: string;\n \"script.prerequest\"?: string;\n \"script.prerequest.param\"?: string;\n \"script.presort\"?: string;\n \"script.presort.param\"?: string;\n timeout?: number;\n}\n\nconst ZScriptResponse = z.object({\n scriptResult: z.string().optional(),\n scriptError: z.string().optional(),\n \"scriptResult.prerequest\": z.string().optional(),\n \"scriptError.prerequest\": z.string().optional(),\n \"scriptResult.presort\": z.string().optional(),\n \"scriptError.presort\": z.string().optional(),\n});\nexport type ScriptResponse = z.infer<typeof ZScriptResponse>;\n\nexport const ZDataInfo = z.object({\n database: z.string(),\n layout: z.string(),\n table: z.string(),\n totalRecordCount: z.number(),\n foundCount: z.number(),\n returnedCount: z.number(),\n});\nexport type DataInfo = z.infer<typeof ZDataInfo>;\n\nexport type CreateParams<U extends GenericPortalData = GenericPortalData> = ScriptParams & {\n portalData?: UpdatePortalsWithIds<U>;\n};\n\nexport type CreateResponse = ScriptResponse & {\n recordId: string;\n modId: string;\n};\n\nexport type UpdateParams<U extends GenericPortalData = GenericPortalData> = CreateParams<U> & {\n modId?: number;\n};\n\nexport type UpdateResponse = ScriptResponse & {\n modId: string;\n};\n\nexport type DeleteParams = ScriptParams;\n\nexport type DeleteResponse = ScriptResponse;\n\nexport interface RangeParams {\n offset?: number;\n limit?: number;\n}\nexport interface RangeParamsRaw {\n _offset?: number;\n _limit?: number;\n}\n\nexport type PortalRanges<U extends GenericPortalData = GenericPortalData> = Partial<{ [key in keyof U]: RangeParams }>;\n\nexport interface PortalRangesParams<U extends GenericPortalData = GenericPortalData> {\n portalRanges?: PortalRanges<U>;\n}\n\nexport type GetParams<U extends GenericPortalData = GenericPortalData> = ScriptParams &\n PortalRangesParams<U> & {\n \"layout.response\"?: string;\n dateformats?: \"US\" | \"file_locale\" | \"ISO8601\";\n };\n\nexport interface Sort<T extends FieldData = FieldData> {\n fieldName: keyof T;\n sortOrder?: \"ascend\" | \"descend\" | (string & {});\n}\n\nexport type ListParams<\n T extends FieldData = FieldData,\n U extends GenericPortalData = GenericPortalData,\n> = GetParams<U> &\n RangeParams & {\n sort?: Sort<T> | Sort<T>[];\n };\n\nexport type ListParamsRaw<\n T extends FieldData = FieldData,\n U extends GenericPortalData = GenericPortalData,\n> = GetParams<U> &\n RangeParamsRaw & {\n _sort?: Sort<T>[];\n };\n\nexport type GetResponse<\n T extends FieldData = FieldData,\n U extends GenericPortalData = GenericPortalData,\n> = ScriptResponse & {\n data: FMRecord<T, U>[];\n dataInfo: DataInfo;\n};\nexport type GetResponseOne<\n T extends FieldData = FieldData,\n U extends GenericPortalData = GenericPortalData,\n> = ScriptResponse & {\n data: FMRecord<T, U>;\n dataInfo: DataInfo;\n};\n\ntype SecondLevelKeys<T> = {\n [K in keyof T]: keyof T[K];\n}[keyof T];\nexport type Query<T extends FieldData = FieldData, U extends GenericPortalData = GenericPortalData> = Partial<{\n [key in keyof T]: T[key] extends number ? number | string : string;\n}> &\n Partial<{ [key in SecondLevelKeys<U>]?: string }> & {\n omit?: \"true\";\n };\n\nexport interface LayoutMetadataResponse {\n fieldMetaData: FieldMetaData[];\n portalMetaData: { [key: string]: FieldMetaData[] };\n valueLists?: ValueList[];\n}\nexport interface ProductInfoMetadataResponse {\n name: string;\n dateFormat: string;\n timeFormat: string;\n timeStampFormat: string;\n}\nexport interface DatabaseMetadataResponse {\n databases: Array<{\n name: string;\n }>;\n}\n\nexport interface FieldMetaData {\n name: string;\n type: \"normal\" | \"calculation\" | \"summary\";\n displayType: \"editText\" | \"popupList\" | \"popupMenu\" | \"checkBox\" | \"calendar\" | \"radioButtons\" | \"secureText\";\n result: \"text\" | \"number\" | \"date\" | \"time\" | \"timeStamp\" | \"container\";\n global: boolean;\n autoEnter: boolean;\n fourDigitYear: boolean;\n maxRepeat: number;\n maxCharacters: number;\n notEmpty: boolean;\n numeric: boolean;\n repetitions: number;\n timeOfDay: boolean;\n valueList?: string;\n}\n\ninterface ValueList {\n name: string;\n // TODO need to test type of value list from other file\n type: \"customList\" | \"byField\";\n values: Array<{ value: string; displayValue: string }>;\n}\n\n/**\n * Represents the data returned by a call to the Data API `layouts` endpoint.\n */\nexport interface AllLayoutsMetadataResponse {\n /**\n * A list of `Layout` or `LayoutsFolder` objects.\n */\n layouts: LayoutOrFolder[];\n}\n\n/**\n * Represents a FileMaker layout.\n */\nexport interface Layout {\n /**\n * The name of the layout\n */\n name: string;\n /**\n * If the node is a layout, `table` may contain the name of the table\n * the layout is associated with.\n */\n table: string;\n}\n\n/**\n * Represents a folder of `Layout` or `LayoutsFolder` objects.\n */\nexport interface LayoutsFolder {\n /**\n * The name of the folder\n */\n name: string;\n isFolder: boolean;\n /**\n * A list of the Layout or LayoutsFolder objects in the folder.\n */\n folderLayoutNames?: LayoutOrFolder[];\n}\n\nexport type LayoutOrFolder = Layout | LayoutsFolder;\n\n/**\n * Represents the data returned by a call to the Data API `scripts` endpoint.\n */\nexport interface ScriptsMetadataResponse {\n /**\n * A list of `Layout` or `LayoutsFolder` objects.\n */\n scripts: ScriptOrFolder[];\n}\ninterface Script {\n name: string;\n isFolder: false;\n}\ninterface ScriptFolder {\n name: string;\n isFolder: true;\n folderScriptNames: ScriptOrFolder[];\n}\nexport type ScriptOrFolder = Script | ScriptFolder;\n\nexport interface RawFMResponse<T = unknown> {\n response?: T;\n messages?: [{ code: string }];\n}\n\nexport class FileMakerError extends Error {\n readonly code: string;\n\n constructor(code: string, message: string) {\n super(message);\n this.code = code;\n }\n}\n"],"names":[],"mappings":";;;;AAEO,MAAM,cAAc,EAAE,MAAM,CAAC,EAAE,UAAU,EAAE,OAAA,GAAU,EAAE,KAAA,GAAQ,EAAE,QAAA,CAAS,CAAC;AAG3E,MAAM,aAAa,EAAE,OAAO,EAAE,OAAA,GAAU,WAAW;AA2ClC,EAAE,OAAO;AAAA,EAC/B,cAAc,EAAE,OAAA,EAAS,SAAA;AAAA,EACzB,aAAa,EAAE,OAAA,EAAS,SAAA;AAAA,EACxB,2BAA2B,EAAE,OAAA,EAAS,SAAA;AAAA,EACtC,0BAA0B,EAAE,OAAA,EAAS,SAAA;AAAA,EACrC,wBAAwB,EAAE,OAAA,EAAS,SAAA;AAAA,EACnC,uBAAuB,EAAE,OAAA,EAAS,SAAA;AACpC,CAAC;AAGM,MAAM,YAAY,EAAE,OAAO;AAAA,EAChC,UAAU,EAAE,OAAA;AAAA,EACZ,QAAQ,EAAE,OAAA;AAAA,EACV,OAAO,EAAE,OAAA;AAAA,EACT,kBAAkB,EAAE,OAAA;AAAA,EACpB,YAAY,EAAE,OAAA;AAAA,EACd,eAAe,EAAE,OAAA;AACnB,CAAC;AAuMM,MAAM,uBAAuB,MAAM;AAAA,EAGxC,YAAY,MAAc,SAAiB;AACzC,UAAM,OAAO;AAHN;AAIP,SAAK,OAAO;AAAA,EACd;AACF;"}
@@ -37,7 +37,7 @@ export interface ContainerUploadArgs<T extends FieldData = FieldData> {
37
37
  }
38
38
  declare function DataApi<Fd extends FieldData = FieldData, Pd extends GenericPortalData = GenericPortalData, Opts extends ClientObjectProps = ClientObjectProps, Adp extends Adapter = Adapter>(options: Opts & {
39
39
  adapter: Adp;
40
- }): Omit<Adp, "create" | "delete" | "find" | "get" | "list" | "update" | "layoutMetadata" | "containerUpload" | "executeScript"> & {
40
+ }): Omit<Adp, "create" | "update" | "delete" | "find" | "get" | "list" | "layoutMetadata" | "containerUpload" | "executeScript"> & {
41
41
  layout: Opts["layout"];
42
42
  list: (args?: ListParams<Opts["schema"] extends object ? StandardSchemaV1.InferOutput<Opts["schema"]["fieldData"]> : Fd, Opts["schema"] extends object ? Opts["schema"]["portalData"] extends object ? { [K in keyof Opts["schema"]["portalData"]]: StandardSchemaV1.InferOutput<Opts["schema"]["portalData"][K]>; } : Pd : Pd> & FetchOptions) => Promise<GetResponse<Opts["schema"] extends object ? StandardSchemaV1.InferOutput<Opts["schema"]["fieldData"]> : Fd, Opts["schema"] extends object ? Opts["schema"]["portalData"] extends object ? { [K in keyof Opts["schema"]["portalData"]]: StandardSchemaV1.InferOutput<Opts["schema"]["portalData"][K]>; } : Pd : Pd>>;
43
43
  listAll: (args?: ListParams<Opts["schema"] extends object ? StandardSchemaV1.InferOutput<Opts["schema"]["fieldData"]> : Fd, Opts["schema"] extends object ? Opts["schema"]["portalData"] extends object ? { [K in keyof Opts["schema"]["portalData"]]: StandardSchemaV1.InferOutput<Opts["schema"]["portalData"][K]>; } : Pd : Pd> & FetchOptions) => Promise<FMRecord<Opts["schema"] extends object ? StandardSchemaV1.InferOutput<Opts["schema"]["fieldData"]> : Fd, Opts["schema"] extends object ? Opts["schema"]["portalData"] extends object ? { [K in keyof Opts["schema"]["portalData"]]: StandardSchemaV1.InferOutput<Opts["schema"]["portalData"][K]>; } : Pd : Pd>[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sources":["../../src/client.ts"],"sourcesContent":["import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport type { Adapter, ExecuteScriptOptions } from \"./adapters/core.js\";\nimport type {\n CreateParams,\n CreateResponse,\n DeleteParams,\n DeleteResponse,\n FieldData,\n FMRecord,\n GenericPortalData,\n GetParams,\n GetResponse,\n GetResponseOne,\n ListParams,\n PortalsWithIds,\n Query,\n UpdateParams,\n UpdateResponse,\n} from \"./client-types.js\";\nimport { FileMakerError } from \"./index.js\";\n\nfunction asNumber(input: string | number): number {\n return typeof input === \"string\" ? Number.parseInt(input, 10) : input;\n}\n\nexport interface ClientObjectProps {\n /**\n * The layout to use by default for all requests. Can be overrridden on each request.\n */\n layout: string;\n schema?: {\n /**\n * The schema for the field data.\n */\n fieldData: StandardSchemaV1<FieldData>;\n /**\n * The schema for the portal data.\n */\n portalData?: Record<string, StandardSchemaV1<FieldData>>;\n };\n}\n\ninterface FetchOptions {\n fetch?: RequestInit;\n}\n\nexport interface IgnoreEmptyResult {\n /**\n * If true, a find that returns no results will retun an empty array instead of throwing an error.\n * @default false\n */\n ignoreEmptyResult?: boolean;\n}\n\nexport interface ContainerUploadArgs<T extends FieldData = FieldData> {\n containerFieldName: keyof T;\n containerFieldRepetition?: string | number;\n file: Blob;\n recordId: number | string;\n modId?: number;\n timeout?: number;\n}\n\nfunction DataApi<\n Fd extends FieldData = FieldData,\n Pd extends GenericPortalData = GenericPortalData,\n Opts extends ClientObjectProps = ClientObjectProps,\n Adp extends Adapter = Adapter,\n>(options: Opts & { adapter: Adp }) {\n type InferredFieldData = Opts[\"schema\"] extends object\n ? StandardSchemaV1.InferOutput<Opts[\"schema\"][\"fieldData\"]>\n : Fd;\n type InferredPortalData = Opts[\"schema\"] extends object\n ? Opts[\"schema\"][\"portalData\"] extends object\n ? {\n [K in keyof Opts[\"schema\"][\"portalData\"]]: StandardSchemaV1.InferOutput<Opts[\"schema\"][\"portalData\"][K]>;\n }\n : Pd\n : Pd;\n\n if (\"zodValidators\" in options) {\n throw new Error(\"zodValidators is no longer supported. Use schema instead, or re-run the typegen command\");\n }\n\n const schema = options.schema;\n const layout = options.layout;\n const {\n create,\n delete: _adapterDelete,\n find,\n get,\n list,\n update,\n layoutMetadata,\n containerUpload,\n executeScript,\n ...otherMethods\n } = options.adapter;\n\n type CreateArgs<\n T extends InferredFieldData = InferredFieldData,\n U extends InferredPortalData = InferredPortalData,\n > = CreateParams<U> & {\n fieldData: Partial<T>;\n };\n type GetArgs<U extends InferredPortalData = InferredPortalData> = GetParams<U> & {\n recordId: number | string;\n };\n type UpdateArgs<\n T extends InferredFieldData = InferredFieldData,\n U extends InferredPortalData = InferredPortalData,\n > = UpdateParams<U> & {\n fieldData: Partial<T>;\n recordId: number | string;\n };\n type DeleteArgs = DeleteParams & {\n recordId: number | string;\n };\n type FindArgs<\n T extends FieldData = InferredFieldData,\n U extends InferredPortalData = InferredPortalData,\n > = ListParams<T, U> & {\n query: Query<T> | Query<T>[];\n timeout?: number;\n };\n\n type ExecuteScriptArgs = Omit<ExecuteScriptOptions, \"layout\">;\n\n /**\n * List all records from a given layout, no find criteria applied.\n */\n async function _list(\n args?: ListParams<InferredFieldData, InferredPortalData> & FetchOptions,\n ): Promise<GetResponse<InferredFieldData, InferredPortalData>>;\n async function _list(\n args?: ListParams<InferredFieldData, InferredPortalData> & FetchOptions,\n ): Promise<GetResponse<InferredFieldData, InferredPortalData>> {\n const { fetch, timeout, ...params } = args ?? {};\n\n // rename and refactor limit, offset, and sort keys for this request\n if (\"limit\" in params && params.limit !== undefined) {\n Object.assign(params, { _limit: params.limit }).limit = undefined;\n }\n if (\"offset\" in params && params.offset !== undefined) {\n if (params.offset <= 1) {\n params.offset = undefined;\n } else {\n Object.assign(params, { _offset: params.offset }).offset = undefined;\n }\n }\n if (\"sort\" in params && params.sort !== undefined) {\n Object.assign(params, {\n _sort: Array.isArray(params.sort) ? params.sort : [params.sort],\n }).sort = undefined;\n }\n\n const result = await list({\n layout,\n data: params,\n fetch,\n timeout,\n });\n\n if (\n result.dataInfo.foundCount > result.dataInfo.returnedCount &&\n args?.limit === undefined &&\n args?.offset === undefined\n ) {\n // more records found than returned and the user didn't specify a limit or offset, so we should warn them\n console.warn(\n `🚨 @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.`,\n );\n }\n\n return await runSchemaValidationAndTransform(schema, result as GetResponse<InferredFieldData, InferredPortalData>);\n }\n\n /**\n * Paginate through all records from a given layout, no find criteria applied.\n * ⚠️ WARNING: Use this method with caution, as it can be slow with large datasets\n */\n async function listAll(\n args?: ListParams<InferredFieldData, InferredPortalData> & FetchOptions,\n ): Promise<FMRecord<InferredFieldData, InferredPortalData>[]>;\n async function listAll(\n args?: ListParams<InferredFieldData, InferredPortalData> & FetchOptions,\n ): Promise<FMRecord<InferredFieldData, InferredPortalData>[]> {\n let runningData: GetResponse<InferredFieldData, InferredPortalData>[\"data\"] = [];\n const limit = args?.limit ?? 100;\n let offset = args?.offset ?? 1;\n\n while (true) {\n const data = await _list({\n ...args,\n offset,\n });\n runningData = [...runningData, ...data.data];\n if (runningData.length >= data.dataInfo.foundCount) {\n break;\n }\n offset += limit;\n }\n return runningData;\n }\n\n /**\n * Create a new record in a given layout\n */\n async function _create<\n T extends InferredFieldData = InferredFieldData,\n U extends InferredPortalData = InferredPortalData,\n >(args: CreateArgs<T, U> & FetchOptions): Promise<CreateResponse> {\n const { fetch, timeout, ...params } = args ?? {};\n return await create({\n layout,\n data: params,\n fetch,\n timeout,\n });\n }\n\n /**\n * Get a single record by Internal RecordId\n */\n async function _get(\n args: GetArgs<InferredPortalData> & FetchOptions,\n ): Promise<GetResponse<InferredFieldData, InferredPortalData>> {\n args.recordId = asNumber(args.recordId);\n const { recordId, fetch, timeout, ...params } = args;\n\n const result = await get({\n layout,\n data: { ...params, recordId },\n fetch,\n timeout,\n });\n return await runSchemaValidationAndTransform(schema, result as GetResponse<InferredFieldData, InferredPortalData>);\n }\n\n /**\n * Update a single record by internal RecordId\n */\n async function _update(\n args: UpdateArgs<InferredFieldData, InferredPortalData> & FetchOptions,\n ): Promise<UpdateResponse> {\n args.recordId = asNumber(args.recordId);\n const { recordId, fetch, timeout, ...params } = args;\n return await update({\n layout,\n data: { ...params, recordId },\n fetch,\n timeout,\n });\n }\n\n /**\n * Delete a single record by internal RecordId\n */\n function deleteRecord(args: DeleteArgs & FetchOptions): Promise<DeleteResponse> {\n args.recordId = asNumber(args.recordId);\n const { recordId, fetch, timeout, ...params } = args;\n\n return _adapterDelete({\n layout,\n data: { ...params, recordId },\n fetch,\n timeout,\n });\n }\n\n /**\n * Find records in a given layout\n */\n async function _find(\n args: FindArgs<InferredFieldData, InferredPortalData> & IgnoreEmptyResult & FetchOptions,\n ): Promise<GetResponse<InferredFieldData, InferredPortalData>> {\n const { query: queryInput, ignoreEmptyResult = false, timeout, fetch, ...params } = args;\n const query = Array.isArray(queryInput) ? queryInput : [queryInput];\n\n // rename and refactor limit, offset, and sort keys for this request\n if (\"offset\" in params && params.offset !== undefined && params.offset <= 1) {\n params.offset = undefined;\n }\n if (\"dateformats\" in params && params.dateformats !== undefined) {\n // reassign dateformats to match FileMaker's expected values\n let dateFormatValue: number;\n if (params.dateformats === \"US\") {\n dateFormatValue = 0;\n } else if (params.dateformats === \"file_locale\") {\n dateFormatValue = 1;\n } else if (params.dateformats === \"ISO8601\") {\n dateFormatValue = 2;\n } else {\n dateFormatValue = 0;\n }\n // @ts-expect-error FM wants a string, so this is fine\n params.dateformats = dateFormatValue.toString();\n }\n const result = (await find({\n data: { ...params, query },\n layout,\n fetch,\n timeout,\n }).catch((e: unknown) => {\n if (ignoreEmptyResult && e instanceof FileMakerError && e.code === \"401\") {\n return { data: [], dataInfo: { foundCount: 0, returnedCount: 0 } };\n }\n throw e;\n })) as GetResponse<InferredFieldData, InferredPortalData>;\n\n if (\n result.dataInfo.foundCount > result.dataInfo.returnedCount &&\n args?.limit === undefined &&\n args?.offset === undefined\n ) {\n // more records found than returned and the user didn't specify a limit or offset\n console.warn(\n `🚨 @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.`,\n );\n }\n\n return await runSchemaValidationAndTransform(schema, result);\n }\n\n /**\n * Helper method for `find`. Will only return the first result or throw error if there is more than 1 result.\n */\n async function findOne(\n args: FindArgs<InferredFieldData, InferredPortalData> & FetchOptions,\n ): Promise<GetResponseOne<InferredFieldData, InferredPortalData>> {\n const result = await _find(args);\n if (result.data.length !== 1) {\n throw new Error(`${result.data.length} records found; expecting exactly 1`);\n }\n const transformedResult = await runSchemaValidationAndTransform(schema, result);\n if (!transformedResult.data[0]) {\n throw new Error(\"No data found\");\n }\n return { ...transformedResult, data: transformedResult.data[0] };\n }\n\n /**\n * Helper method for `find`. Will only return the first result instead of an array.\n */\n async function findFirst(\n args: FindArgs<InferredFieldData, InferredPortalData> & IgnoreEmptyResult & FetchOptions,\n ): Promise<GetResponseOne<InferredFieldData, InferredPortalData>> {\n const result = await _find(args);\n const transformedResult = await runSchemaValidationAndTransform(schema, result);\n\n if (!transformedResult.data[0]) {\n throw new Error(\"No data found\");\n }\n return { ...transformedResult, data: transformedResult.data[0] };\n }\n\n /**\n * Helper method for `find`. Will return the first result or null if no results are found.\n */\n async function maybeFindFirst(\n args: FindArgs<InferredFieldData, InferredPortalData> & IgnoreEmptyResult & FetchOptions,\n ): Promise<GetResponseOne<InferredFieldData, InferredPortalData> | null> {\n const result = await _find({ ...args, ignoreEmptyResult: true });\n const transformedResult = await runSchemaValidationAndTransform(schema, result);\n if (!transformedResult.data[0]) {\n return null;\n }\n return { ...transformedResult, data: transformedResult.data[0] };\n }\n\n /**\n * Helper method for `find` to page through all found results.\n * ⚠️ WARNING: Use with caution as this can be a slow operation with large datasets\n */\n async function findAll(\n args: FindArgs<InferredFieldData, InferredPortalData> & FetchOptions,\n ): Promise<FMRecord<InferredFieldData, InferredPortalData>[]> {\n let runningData: GetResponse<InferredFieldData, InferredPortalData>[\"data\"] = [];\n const limit = args.limit ?? 100;\n let offset = args.offset ?? 1;\n\n while (true) {\n const data = await _find({\n ...args,\n offset,\n ignoreEmptyResult: true,\n });\n runningData = [...runningData, ...data.data];\n if (runningData.length === 0 || runningData.length >= data.dataInfo.foundCount) {\n break;\n }\n offset += limit;\n }\n return runningData;\n }\n\n async function _layoutMetadata(args?: { timeout?: number } & FetchOptions) {\n const { ...restArgs } = args ?? {};\n // Explicitly define the type for params based on FetchOptions\n const params: FetchOptions & { timeout?: number } = restArgs;\n\n return await layoutMetadata({\n layout,\n fetch: params.fetch, // Now should correctly resolve to undefined if not present\n timeout: params.timeout, // Now should correctly resolve to undefined if not present\n });\n }\n\n async function _containerUpload(args: ContainerUploadArgs<InferredFieldData> & FetchOptions) {\n const { ...params } = args;\n return await containerUpload({\n layout,\n data: {\n ...params,\n containerFieldName: params.containerFieldName as string,\n repetition: params.containerFieldRepetition,\n },\n fetch: params.fetch,\n timeout: params.timeout,\n });\n }\n\n async function runSchemaValidationAndTransform(\n schema: ClientObjectProps[\"schema\"],\n result: GetResponse<InferredFieldData, InferredPortalData>,\n ): Promise<GetResponse<InferredFieldData, InferredPortalData>> {\n const fieldDataIssues: StandardSchemaV1.Issue[] = [];\n const portalDataIssues: StandardSchemaV1.Issue[] = [];\n\n if (!schema) {\n return result;\n }\n const transformedData: FMRecord<InferredFieldData, InferredPortalData>[] = [];\n for (const record of result.data) {\n let fieldResult = schema.fieldData[\"~standard\"].validate(record.fieldData);\n if (fieldResult instanceof Promise) {\n fieldResult = await fieldResult;\n }\n if (\"value\" in fieldResult) {\n record.fieldData = fieldResult.value as InferredFieldData;\n } else {\n fieldDataIssues.push(...fieldResult.issues);\n }\n\n if (schema.portalData) {\n for (const [portalName, portalRecords] of Object.entries(record.portalData)) {\n const validatedPortalRecords: PortalsWithIds<GenericPortalData>[] = [];\n for (const portalRecord of portalRecords) {\n let portalResult = schema.portalData[portalName]?.[\"~standard\"].validate(portalRecord);\n if (portalResult instanceof Promise) {\n portalResult = await portalResult;\n }\n if (portalResult && \"value\" in portalResult) {\n validatedPortalRecords.push({\n ...portalResult.value,\n recordId: portalRecord.recordId,\n modId: portalRecord.modId,\n });\n } else {\n portalDataIssues.push(...(portalResult?.issues ?? []));\n }\n }\n // @ts-expect-error We know portalName is a valid key, but can't figure out the right assertions\n record.portalData[portalName] = validatedPortalRecords;\n }\n }\n\n transformedData.push(record);\n }\n result.data = transformedData;\n\n if (fieldDataIssues.length > 0 || portalDataIssues.length > 0) {\n console.error(\n `🚨 @proofkit/fmdapi: Validation issues for layout \"${layout}\". Run the typegen command again to generate the latest field definitions from your layout.`,\n {\n fieldDataIssues,\n portalDataIssues,\n },\n );\n throw new Error(\"Schema validation issues\");\n }\n\n return result;\n }\n\n async function _executeScript(args: ExecuteScriptArgs & FetchOptions) {\n return await executeScript({\n ...args,\n layout,\n });\n }\n\n return {\n ...otherMethods,\n layout: options.layout as Opts[\"layout\"],\n list: _list,\n listAll,\n create: _create,\n get: _get,\n update: _update,\n delete: deleteRecord,\n find: _find,\n findOne,\n findFirst,\n maybeFindFirst,\n findAll,\n layoutMetadata: _layoutMetadata,\n containerUpload: _containerUpload,\n executeScript: _executeScript,\n };\n}\n\nexport default DataApi;\nexport { DataApi };\n"],"names":["schema"],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sources":["../../src/client.ts"],"sourcesContent":["import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport type { Adapter, ExecuteScriptOptions } from \"./adapters/core.js\";\nimport type {\n CreateParams,\n CreateResponse,\n DeleteParams,\n DeleteResponse,\n FieldData,\n FMRecord,\n GenericPortalData,\n GetParams,\n GetResponse,\n GetResponseOne,\n ListParams,\n PortalsWithIds,\n Query,\n UpdateParams,\n UpdateResponse,\n} from \"./client-types.js\";\nimport { FileMakerError } from \"./index.js\";\n\nfunction asNumber(input: string | number): number {\n return typeof input === \"string\" ? Number.parseInt(input, 10) : input;\n}\n\nexport interface ClientObjectProps {\n /**\n * The layout to use by default for all requests. Can be overrridden on each request.\n */\n layout: string;\n schema?: {\n /**\n * The schema for the field data.\n */\n fieldData: StandardSchemaV1<FieldData>;\n /**\n * The schema for the portal data.\n */\n portalData?: Record<string, StandardSchemaV1<FieldData>>;\n };\n}\n\ninterface FetchOptions {\n fetch?: RequestInit;\n}\n\nexport interface IgnoreEmptyResult {\n /**\n * If true, a find that returns no results will retun an empty array instead of throwing an error.\n * @default false\n */\n ignoreEmptyResult?: boolean;\n}\n\nexport interface ContainerUploadArgs<T extends FieldData = FieldData> {\n containerFieldName: keyof T;\n containerFieldRepetition?: string | number;\n file: Blob;\n recordId: number | string;\n modId?: number;\n timeout?: number;\n}\n\nfunction DataApi<\n Fd extends FieldData = FieldData,\n Pd extends GenericPortalData = GenericPortalData,\n Opts extends ClientObjectProps = ClientObjectProps,\n Adp extends Adapter = Adapter,\n>(options: Opts & { adapter: Adp }) {\n type InferredFieldData = Opts[\"schema\"] extends object\n ? StandardSchemaV1.InferOutput<Opts[\"schema\"][\"fieldData\"]>\n : Fd;\n type InferredPortalData = Opts[\"schema\"] extends object\n ? Opts[\"schema\"][\"portalData\"] extends object\n ? {\n [K in keyof Opts[\"schema\"][\"portalData\"]]: StandardSchemaV1.InferOutput<Opts[\"schema\"][\"portalData\"][K]>;\n }\n : Pd\n : Pd;\n\n if (\"zodValidators\" in options) {\n throw new Error(\"zodValidators is no longer supported. Use schema instead, or re-run the typegen command\");\n }\n\n const schema = options.schema;\n const layout = options.layout;\n const {\n create,\n delete: _adapterDelete,\n find,\n get,\n list,\n update,\n layoutMetadata,\n containerUpload,\n executeScript,\n ...otherMethods\n } = options.adapter;\n\n type CreateArgs<\n T extends InferredFieldData = InferredFieldData,\n U extends InferredPortalData = InferredPortalData,\n > = CreateParams<U> & {\n fieldData: Partial<T>;\n };\n type GetArgs<U extends InferredPortalData = InferredPortalData> = GetParams<U> & {\n recordId: number | string;\n };\n type UpdateArgs<\n T extends InferredFieldData = InferredFieldData,\n U extends InferredPortalData = InferredPortalData,\n > = UpdateParams<U> & {\n fieldData: Partial<T>;\n recordId: number | string;\n };\n type DeleteArgs = DeleteParams & {\n recordId: number | string;\n };\n type FindArgs<\n T extends FieldData = InferredFieldData,\n U extends InferredPortalData = InferredPortalData,\n > = ListParams<T, U> & {\n query: Query<T> | Query<T>[];\n timeout?: number;\n };\n\n type ExecuteScriptArgs = Omit<ExecuteScriptOptions, \"layout\">;\n\n /**\n * List all records from a given layout, no find criteria applied.\n */\n async function _list(\n args?: ListParams<InferredFieldData, InferredPortalData> & FetchOptions,\n ): Promise<GetResponse<InferredFieldData, InferredPortalData>>;\n async function _list(\n args?: ListParams<InferredFieldData, InferredPortalData> & FetchOptions,\n ): Promise<GetResponse<InferredFieldData, InferredPortalData>> {\n const { fetch, timeout, ...params } = args ?? {};\n\n // rename and refactor limit, offset, and sort keys for this request\n if (\"limit\" in params && params.limit !== undefined) {\n Object.assign(params, { _limit: params.limit }).limit = undefined;\n }\n if (\"offset\" in params && params.offset !== undefined) {\n if (params.offset <= 1) {\n params.offset = undefined;\n } else {\n Object.assign(params, { _offset: params.offset }).offset = undefined;\n }\n }\n if (\"sort\" in params && params.sort !== undefined) {\n Object.assign(params, {\n _sort: Array.isArray(params.sort) ? params.sort : [params.sort],\n }).sort = undefined;\n }\n\n const result = await list({\n layout,\n data: params,\n fetch,\n timeout,\n });\n\n if (\n result.dataInfo.foundCount > result.dataInfo.returnedCount &&\n args?.limit === undefined &&\n args?.offset === undefined\n ) {\n // more records found than returned and the user didn't specify a limit or offset, so we should warn them\n console.warn(\n `🚨 @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.`,\n );\n }\n\n return await runSchemaValidationAndTransform(schema, result as GetResponse<InferredFieldData, InferredPortalData>);\n }\n\n /**\n * Paginate through all records from a given layout, no find criteria applied.\n * ⚠️ WARNING: Use this method with caution, as it can be slow with large datasets\n */\n async function listAll(\n args?: ListParams<InferredFieldData, InferredPortalData> & FetchOptions,\n ): Promise<FMRecord<InferredFieldData, InferredPortalData>[]>;\n async function listAll(\n args?: ListParams<InferredFieldData, InferredPortalData> & FetchOptions,\n ): Promise<FMRecord<InferredFieldData, InferredPortalData>[]> {\n let runningData: GetResponse<InferredFieldData, InferredPortalData>[\"data\"] = [];\n const limit = args?.limit ?? 100;\n let offset = args?.offset ?? 1;\n\n while (true) {\n const data = await _list({\n ...args,\n offset,\n });\n runningData = [...runningData, ...data.data];\n if (runningData.length >= data.dataInfo.foundCount) {\n break;\n }\n offset += limit;\n }\n return runningData;\n }\n\n /**\n * Create a new record in a given layout\n */\n async function _create<\n T extends InferredFieldData = InferredFieldData,\n U extends InferredPortalData = InferredPortalData,\n >(args: CreateArgs<T, U> & FetchOptions): Promise<CreateResponse> {\n const { fetch, timeout, ...params } = args ?? {};\n return await create({\n layout,\n data: params,\n fetch,\n timeout,\n });\n }\n\n /**\n * Get a single record by Internal RecordId\n */\n async function _get(\n args: GetArgs<InferredPortalData> & FetchOptions,\n ): Promise<GetResponse<InferredFieldData, InferredPortalData>> {\n args.recordId = asNumber(args.recordId);\n const { recordId, fetch, timeout, ...params } = args;\n\n const result = await get({\n layout,\n data: { ...params, recordId },\n fetch,\n timeout,\n });\n return await runSchemaValidationAndTransform(schema, result as GetResponse<InferredFieldData, InferredPortalData>);\n }\n\n /**\n * Update a single record by internal RecordId\n */\n async function _update(\n args: UpdateArgs<InferredFieldData, InferredPortalData> & FetchOptions,\n ): Promise<UpdateResponse> {\n args.recordId = asNumber(args.recordId);\n const { recordId, fetch, timeout, ...params } = args;\n return await update({\n layout,\n data: { ...params, recordId },\n fetch,\n timeout,\n });\n }\n\n /**\n * Delete a single record by internal RecordId\n */\n function deleteRecord(args: DeleteArgs & FetchOptions): Promise<DeleteResponse> {\n args.recordId = asNumber(args.recordId);\n const { recordId, fetch, timeout, ...params } = args;\n\n return _adapterDelete({\n layout,\n data: { ...params, recordId },\n fetch,\n timeout,\n });\n }\n\n /**\n * Find records in a given layout\n */\n async function _find(\n args: FindArgs<InferredFieldData, InferredPortalData> & IgnoreEmptyResult & FetchOptions,\n ): Promise<GetResponse<InferredFieldData, InferredPortalData>> {\n const { query: queryInput, ignoreEmptyResult = false, timeout, fetch, ...params } = args;\n const query = Array.isArray(queryInput) ? queryInput : [queryInput];\n\n // rename and refactor limit, offset, and sort keys for this request\n if (\"offset\" in params && params.offset !== undefined && params.offset <= 1) {\n params.offset = undefined;\n }\n if (\"dateformats\" in params && params.dateformats !== undefined) {\n // reassign dateformats to match FileMaker's expected values\n let dateFormatValue: number;\n if (params.dateformats === \"US\") {\n dateFormatValue = 0;\n } else if (params.dateformats === \"file_locale\") {\n dateFormatValue = 1;\n } else if (params.dateformats === \"ISO8601\") {\n dateFormatValue = 2;\n } else {\n dateFormatValue = 0;\n }\n // @ts-expect-error FM wants a string, so this is fine\n params.dateformats = dateFormatValue.toString();\n }\n const result = (await find({\n data: { ...params, query },\n layout,\n fetch,\n timeout,\n }).catch((e: unknown) => {\n if (ignoreEmptyResult && e instanceof FileMakerError && e.code === \"401\") {\n return { data: [], dataInfo: { foundCount: 0, returnedCount: 0 } };\n }\n throw e;\n })) as GetResponse<InferredFieldData, InferredPortalData>;\n\n if (\n result.dataInfo.foundCount > result.dataInfo.returnedCount &&\n args?.limit === undefined &&\n args?.offset === undefined\n ) {\n // more records found than returned and the user didn't specify a limit or offset\n console.warn(\n `🚨 @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.`,\n );\n }\n\n return await runSchemaValidationAndTransform(schema, result);\n }\n\n /**\n * Helper method for `find`. Will only return the first result or throw error if there is more than 1 result.\n */\n async function findOne(\n args: FindArgs<InferredFieldData, InferredPortalData> & FetchOptions,\n ): Promise<GetResponseOne<InferredFieldData, InferredPortalData>> {\n const result = await _find(args);\n if (result.data.length !== 1) {\n throw new Error(`${result.data.length} records found; expecting exactly 1`);\n }\n const transformedResult = await runSchemaValidationAndTransform(schema, result);\n if (!transformedResult.data[0]) {\n throw new Error(\"No data found\");\n }\n return { ...transformedResult, data: transformedResult.data[0] };\n }\n\n /**\n * Helper method for `find`. Will only return the first result instead of an array.\n */\n async function findFirst(\n args: FindArgs<InferredFieldData, InferredPortalData> & IgnoreEmptyResult & FetchOptions,\n ): Promise<GetResponseOne<InferredFieldData, InferredPortalData>> {\n const result = await _find(args);\n const transformedResult = await runSchemaValidationAndTransform(schema, result);\n\n if (!transformedResult.data[0]) {\n throw new Error(\"No data found\");\n }\n return { ...transformedResult, data: transformedResult.data[0] };\n }\n\n /**\n * Helper method for `find`. Will return the first result or null if no results are found.\n */\n async function maybeFindFirst(\n args: FindArgs<InferredFieldData, InferredPortalData> & IgnoreEmptyResult & FetchOptions,\n ): Promise<GetResponseOne<InferredFieldData, InferredPortalData> | null> {\n const result = await _find({ ...args, ignoreEmptyResult: true });\n const transformedResult = await runSchemaValidationAndTransform(schema, result);\n if (!transformedResult.data[0]) {\n return null;\n }\n return { ...transformedResult, data: transformedResult.data[0] };\n }\n\n /**\n * Helper method for `find` to page through all found results.\n * ⚠️ WARNING: Use with caution as this can be a slow operation with large datasets\n */\n async function findAll(\n args: FindArgs<InferredFieldData, InferredPortalData> & FetchOptions,\n ): Promise<FMRecord<InferredFieldData, InferredPortalData>[]> {\n let runningData: GetResponse<InferredFieldData, InferredPortalData>[\"data\"] = [];\n const limit = args.limit ?? 100;\n let offset = args.offset ?? 1;\n\n while (true) {\n const data = await _find({\n ...args,\n offset,\n ignoreEmptyResult: true,\n });\n runningData = [...runningData, ...data.data];\n if (runningData.length === 0 || runningData.length >= data.dataInfo.foundCount) {\n break;\n }\n offset += limit;\n }\n return runningData;\n }\n\n async function _layoutMetadata(args?: { timeout?: number } & FetchOptions) {\n const { ...restArgs } = args ?? {};\n // Explicitly define the type for params based on FetchOptions\n const params: FetchOptions & { timeout?: number } = restArgs;\n\n return await layoutMetadata({\n layout,\n fetch: params.fetch, // Now should correctly resolve to undefined if not present\n timeout: params.timeout, // Now should correctly resolve to undefined if not present\n });\n }\n\n async function _containerUpload(args: ContainerUploadArgs<InferredFieldData> & FetchOptions) {\n const { ...params } = args;\n return await containerUpload({\n layout,\n data: {\n ...params,\n containerFieldName: params.containerFieldName as string,\n repetition: params.containerFieldRepetition,\n },\n fetch: params.fetch,\n timeout: params.timeout,\n });\n }\n\n async function runSchemaValidationAndTransform(\n schema: ClientObjectProps[\"schema\"],\n result: GetResponse<InferredFieldData, InferredPortalData>,\n ): Promise<GetResponse<InferredFieldData, InferredPortalData>> {\n const fieldDataIssues: StandardSchemaV1.Issue[] = [];\n const portalDataIssues: StandardSchemaV1.Issue[] = [];\n\n if (!schema) {\n return result;\n }\n const transformedData: FMRecord<InferredFieldData, InferredPortalData>[] = [];\n for (const record of result.data) {\n let fieldResult = schema.fieldData[\"~standard\"].validate(record.fieldData);\n if (fieldResult instanceof Promise) {\n fieldResult = await fieldResult;\n }\n if (\"value\" in fieldResult) {\n record.fieldData = fieldResult.value as InferredFieldData;\n } else {\n fieldDataIssues.push(...fieldResult.issues);\n }\n\n if (schema.portalData) {\n for (const [portalName, portalRecords] of Object.entries(record.portalData)) {\n const validatedPortalRecords: PortalsWithIds<GenericPortalData>[] = [];\n for (const portalRecord of portalRecords) {\n let portalResult = schema.portalData[portalName]?.[\"~standard\"].validate(portalRecord);\n if (portalResult instanceof Promise) {\n portalResult = await portalResult;\n }\n if (portalResult && \"value\" in portalResult) {\n validatedPortalRecords.push({\n ...portalResult.value,\n recordId: portalRecord.recordId,\n modId: portalRecord.modId,\n });\n } else {\n portalDataIssues.push(...(portalResult?.issues ?? []));\n }\n }\n // @ts-expect-error We know portalName is a valid key, but can't figure out the right assertions\n record.portalData[portalName] = validatedPortalRecords;\n }\n }\n\n transformedData.push(record);\n }\n result.data = transformedData;\n\n if (fieldDataIssues.length > 0 || portalDataIssues.length > 0) {\n console.error(\n `🚨 @proofkit/fmdapi: Validation issues for layout \"${layout}\". Run the typegen command again to generate the latest field definitions from your layout.`,\n {\n fieldDataIssues,\n portalDataIssues,\n },\n );\n throw new Error(\"Schema validation issues\");\n }\n\n return result;\n }\n\n async function _executeScript(args: ExecuteScriptArgs & FetchOptions) {\n return await executeScript({\n ...args,\n layout,\n });\n }\n\n return {\n ...otherMethods,\n layout: options.layout as Opts[\"layout\"],\n list: _list,\n listAll,\n create: _create,\n get: _get,\n update: _update,\n delete: deleteRecord,\n find: _find,\n findOne,\n findFirst,\n maybeFindFirst,\n findAll,\n layoutMetadata: _layoutMetadata,\n containerUpload: _containerUpload,\n executeScript: _executeScript,\n };\n}\n\nexport default DataApi;\nexport { DataApi };\n"],"names":["schema"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  export { FetchAdapter } from './adapters/fetch.js';
2
+ export { FmMcpAdapter, type FmMcpAdapterOptions } from './adapters/fm-mcp.js';
2
3
  export { OttoAdapter, type OttoAPIKey } from './adapters/otto.js';
3
4
  export { DataApi, DataApi as default } from './client.js';
4
5
  export * as clientTypes from './client-types.js';
package/dist/esm/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { FetchAdapter } from "./adapters/fetch.js";
2
+ import { FmMcpAdapter } from "./adapters/fm-mcp.js";
2
3
  import { OttoAdapter } from "./adapters/otto.js";
3
4
  import { default as default2, default as default3 } from "./client.js";
4
5
  import * as clientTypes from "./client-types.js";
@@ -8,6 +9,7 @@ export {
8
9
  default2 as DataApi,
9
10
  FetchAdapter,
10
11
  FileMakerError,
12
+ FmMcpAdapter,
11
13
  OttoAdapter,
12
14
  clientTypes,
13
15
  default3 as default,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"memory.js","sources":["../../../src/tokenStore/memory.ts"],"sourcesContent":["import type { TokenStoreDefinitions } from \"./types.js\";\n\nexport function memoryStore(): TokenStoreDefinitions {\n const data: Record<string, string> = {};\n return {\n getToken: (key: string): string | null => {\n try {\n return data[key] ?? null;\n } catch {\n return null;\n }\n },\n clearToken: (key: string) => delete data[key],\n setToken: (key: string, value: string): void => {\n data[key] = value;\n },\n };\n}\n\nexport default memoryStore;\n"],"names":[],"mappings":"AAEO,SAAS,cAAqC;AACnD,QAAM,OAA+B,CAAC;AAC/B,SAAA;AAAA,IACL,UAAU,CAAC,QAA+B;AACpC,UAAA;AACK,eAAA,KAAK,GAAG,KAAK;AAAA,MAAA,QACd;AACC,eAAA;AAAA,MAAA;AAAA,IAEX;AAAA,IACA,YAAY,CAAC,QAAgB,OAAO,KAAK,GAAG;AAAA,IAC5C,UAAU,CAAC,KAAa,UAAwB;AAC9C,WAAK,GAAG,IAAI;AAAA,IAAA;AAAA,EAEhB;AACF;"}
1
+ {"version":3,"file":"memory.js","sources":["../../../src/tokenStore/memory.ts"],"sourcesContent":["import type { TokenStoreDefinitions } from \"./types.js\";\n\nexport function memoryStore(): TokenStoreDefinitions {\n const data: Record<string, string> = {};\n return {\n getToken: (key: string): string | null => {\n try {\n return data[key] ?? null;\n } catch {\n return null;\n }\n },\n clearToken: (key: string) => delete data[key],\n setToken: (key: string, value: string): void => {\n data[key] = value;\n },\n };\n}\n\nexport default memoryStore;\n"],"names":[],"mappings":"AAEO,SAAS,cAAqC;AACnD,QAAM,OAA+B,CAAA;AACrC,SAAO;AAAA,IACL,UAAU,CAAC,QAA+B;AACxC,UAAI;AACF,eAAO,KAAK,GAAG,KAAK;AAAA,MACtB,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,YAAY,CAAC,QAAgB,OAAO,KAAK,GAAG;AAAA,IAC5C,UAAU,CAAC,KAAa,UAAwB;AAC9C,WAAK,GAAG,IAAI;AAAA,IACd;AAAA,EAAA;AAEJ;"}
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../../src/utils.ts"],"sourcesContent":["type StripFMTableName<K extends PropertyKey> = K extends `${string}::${infer R}` ? R : K;\n\ntype TransformedFields<T extends object> = {\n [K in keyof T as K extends string ? StripFMTableName<K> : K]: T[K];\n};\n\nexport function removeFMTableNames<T extends object>(obj: T): TransformedFields<T> {\n const newObj = {} as TransformedFields<T>;\n for (const key in obj) {\n if (Object.hasOwn(obj, key)) {\n const originalKey = key as keyof T;\n const value = obj[originalKey];\n const mappedKey = (\n typeof key === \"string\" && key.includes(\"::\") ? key.split(\"::\")[1] : key\n ) as keyof TransformedFields<T>;\n\n // Use a temporary index signature cast to assign without any\n (newObj as unknown as Record<PropertyKey, unknown>)[mappedKey as unknown as PropertyKey] = value as unknown;\n }\n }\n return newObj;\n}\n\nexport type InferZodPortals<T extends Record<string, unknown>> = {\n [K in keyof T]: T[K] extends { _def: unknown; parse: (...args: unknown[]) => unknown }\n ? ReturnType<T[K][\"parse\"]>\n : T[K] extends { _def: unknown; safeParse: (...args: unknown[]) => unknown }\n ? T[K] extends { parse: (...args: unknown[]) => unknown }\n ? ReturnType<T[K][\"parse\"]>\n : unknown\n : never;\n};\n"],"names":[],"mappings":"AAMO,SAAS,mBAAqC,KAA8B;AACjF,QAAM,SAAS,CAAC;AAChB,aAAW,OAAO,KAAK;AACrB,QAAI,OAAO,OAAO,KAAK,GAAG,GAAG;AAC3B,YAAM,cAAc;AACd,YAAA,QAAQ,IAAI,WAAW;AAC7B,YAAM,YACJ,OAAO,QAAQ,YAAY,IAAI,SAAS,IAAI,IAAI,IAAI,MAAM,IAAI,EAAE,CAAC,IAAI;AAItE,aAAmD,SAAmC,IAAI;AAAA,IAAA;AAAA,EAC7F;AAEK,SAAA;AACT;"}
1
+ {"version":3,"file":"utils.js","sources":["../../src/utils.ts"],"sourcesContent":["type StripFMTableName<K extends PropertyKey> = K extends `${string}::${infer R}` ? R : K;\n\ntype TransformedFields<T extends object> = {\n [K in keyof T as K extends string ? StripFMTableName<K> : K]: T[K];\n};\n\nexport function removeFMTableNames<T extends object>(obj: T): TransformedFields<T> {\n const newObj = {} as TransformedFields<T>;\n for (const key in obj) {\n if (Object.hasOwn(obj, key)) {\n const originalKey = key as keyof T;\n const value = obj[originalKey];\n const mappedKey = (\n typeof key === \"string\" && key.includes(\"::\") ? key.split(\"::\")[1] : key\n ) as keyof TransformedFields<T>;\n\n // Use a temporary index signature cast to assign without any\n (newObj as unknown as Record<PropertyKey, unknown>)[mappedKey as unknown as PropertyKey] = value as unknown;\n }\n }\n return newObj;\n}\n\nexport type InferZodPortals<T extends Record<string, unknown>> = {\n [K in keyof T]: T[K] extends { _def: unknown; parse: (...args: unknown[]) => unknown }\n ? ReturnType<T[K][\"parse\"]>\n : T[K] extends { _def: unknown; safeParse: (...args: unknown[]) => unknown }\n ? T[K] extends { parse: (...args: unknown[]) => unknown }\n ? ReturnType<T[K][\"parse\"]>\n : unknown\n : never;\n};\n"],"names":[],"mappings":"AAMO,SAAS,mBAAqC,KAA8B;AACjF,QAAM,SAAS,CAAA;AACf,aAAW,OAAO,KAAK;AACrB,QAAI,OAAO,OAAO,KAAK,GAAG,GAAG;AAC3B,YAAM,cAAc;AACpB,YAAM,QAAQ,IAAI,WAAW;AAC7B,YAAM,YACJ,OAAO,QAAQ,YAAY,IAAI,SAAS,IAAI,IAAI,IAAI,MAAM,IAAI,EAAE,CAAC,IAAI;AAItE,aAAmD,SAAmC,IAAI;AAAA,IAC7F;AAAA,EACF;AACA,SAAO;AACT;"}