@proofkit/fmodata 0.1.0-alpha.1 → 0.1.0-alpha.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/README.md +23 -13
- package/dist/esm/client/filemaker-odata.d.ts +1 -1
- package/dist/esm/client/filemaker-odata.js +2 -2
- package/dist/esm/client/filemaker-odata.js.map +1 -1
- package/dist/esm/index.d.ts +4 -1
- package/dist/esm/index.js +2 -2
- package/package.json +1 -1
- package/src/client/filemaker-odata.ts +1 -1
- package/src/index.ts +17 -1
package/README.md
CHANGED
|
@@ -2,12 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
A strongly-typed FileMaker OData API client.
|
|
4
4
|
|
|
5
|
-
⚠️ WARNING: This library is in "alpha" status. The API is subject to change. Feedback is welcome on the [community forum](https://community.ottomatic.cloud/c/proofkit/13) or
|
|
5
|
+
⚠️ WARNING: This library is in "alpha" status. The API is subject to change. Feedback is welcome on the [community forum](https://community.ottomatic.cloud/c/proofkit/13) or on [GitHub](https://github.com/proofgeist/proofkit/issues).
|
|
6
|
+
|
|
7
|
+
Roadmap:
|
|
8
|
+
|
|
9
|
+
- [ ] Batch operations
|
|
10
|
+
- [ ] Proper docs at proofkit.dev
|
|
11
|
+
- [ ] @proofkit/typegen integration
|
|
6
12
|
|
|
7
13
|
## Installation
|
|
8
14
|
|
|
9
15
|
```bash
|
|
10
|
-
pnpm add @proofkit/fmodata
|
|
16
|
+
pnpm add @proofkit/fmodata@alpha
|
|
11
17
|
```
|
|
12
18
|
|
|
13
19
|
## Quick Start
|
|
@@ -15,11 +21,15 @@ pnpm add @proofkit/fmodata
|
|
|
15
21
|
Here's a minimal example to get you started:
|
|
16
22
|
|
|
17
23
|
```typescript
|
|
18
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
FMServerConnection,
|
|
26
|
+
BaseTable,
|
|
27
|
+
TableOccurrence,
|
|
28
|
+
} from "@proofkit/fmodata";
|
|
19
29
|
import { z } from "zod/v4";
|
|
20
30
|
|
|
21
|
-
// 1. Create a
|
|
22
|
-
const
|
|
31
|
+
// 1. Create a connection to the server
|
|
32
|
+
const connection = new FMServerConnection({
|
|
23
33
|
serverUrl: "https://your-server.com",
|
|
24
34
|
auth: {
|
|
25
35
|
// OttoFMS API key
|
|
@@ -49,7 +59,7 @@ const usersTO = new TableOccurrence({
|
|
|
49
59
|
});
|
|
50
60
|
|
|
51
61
|
// 4. Create a database instance
|
|
52
|
-
const db =
|
|
62
|
+
const db = connection.database("MyDatabase.fmp12", {
|
|
53
63
|
occurrences: [usersTO],
|
|
54
64
|
});
|
|
55
65
|
|
|
@@ -68,11 +78,11 @@ if (data) {
|
|
|
68
78
|
|
|
69
79
|
## Core Concepts
|
|
70
80
|
|
|
71
|
-
This library relies heavily on the builder pattern for defining your queries and operations. Most operations require a final call to `execute()` to send the request to the server.
|
|
81
|
+
This library relies heavily on the builder pattern for defining your queries and operations. Most operations require a final call to `execute()` to send the request to the server. The builder pattern is designed to support batch operations in the future, allowing you to execute multiple operations in a single request as supported by the FileMaker OData API. **Note:** Batch operations are not yet supported but are planned before the production release. It's also helpful for testing the library, as you can call `getQueryString()` to get the OData query string without executing the request.
|
|
72
82
|
|
|
73
83
|
As such, there are layers to the library to help you build your queries and operations.
|
|
74
84
|
|
|
75
|
-
- `
|
|
85
|
+
- `FMServerConnection` - hold server connection details and authentication
|
|
76
86
|
- `BaseTable` - defines the fields and validators for a base table
|
|
77
87
|
- `TableOccurrence` - references a base table, and other table occurrences for navigation
|
|
78
88
|
- `Database` - connects the table occurrences to the server connection
|
|
@@ -95,7 +105,7 @@ The client can authenticate using username/password or API key:
|
|
|
95
105
|
|
|
96
106
|
```typescript
|
|
97
107
|
// Username and password authentication
|
|
98
|
-
const
|
|
108
|
+
const connection = new FMServerConnection({
|
|
99
109
|
serverUrl: "https://api.example.com",
|
|
100
110
|
auth: {
|
|
101
111
|
username: "test",
|
|
@@ -104,7 +114,7 @@ const client = new FileMakerOData({
|
|
|
104
114
|
});
|
|
105
115
|
|
|
106
116
|
// API key authentication
|
|
107
|
-
const
|
|
117
|
+
const connection = new FMServerConnection({
|
|
108
118
|
serverUrl: "https://api.example.com",
|
|
109
119
|
auth: {
|
|
110
120
|
apiKey: "your-api-key",
|
|
@@ -185,10 +195,10 @@ const result = await db
|
|
|
185
195
|
.execute();
|
|
186
196
|
```
|
|
187
197
|
|
|
188
|
-
Lastly, you can combine all table occurrences into a database instance for the full type-safe experience. This is a method on the main `
|
|
198
|
+
Lastly, you can combine all table occurrences into a database instance for the full type-safe experience. This is a method on the main `FMServerConnection` client class.
|
|
189
199
|
|
|
190
200
|
```typescript
|
|
191
|
-
const db =
|
|
201
|
+
const db = connection.database("MyDatabase.fmp12", {
|
|
192
202
|
occurrences: [contactsTO, usersTO], // Register your table occurrences
|
|
193
203
|
});
|
|
194
204
|
```
|
|
@@ -810,7 +820,7 @@ const usersTO = new TableOccurrence({
|
|
|
810
820
|
baseTable: usersBase,
|
|
811
821
|
});
|
|
812
822
|
|
|
813
|
-
const db =
|
|
823
|
+
const db = connection.database("MyDB", {
|
|
814
824
|
occurrences: [usersTO],
|
|
815
825
|
});
|
|
816
826
|
|
|
@@ -2,7 +2,7 @@ import { FFetchOptions } from '@fetchkit/ffetch';
|
|
|
2
2
|
import { Auth, ExecutionContext } from '../types.js';
|
|
3
3
|
import { Database } from './database.js';
|
|
4
4
|
import { TableOccurrence } from './table-occurrence.js';
|
|
5
|
-
export declare class
|
|
5
|
+
export declare class FMServerConnection implements ExecutionContext {
|
|
6
6
|
private fetchClient;
|
|
7
7
|
private serverUrl;
|
|
8
8
|
private auth;
|
|
@@ -3,7 +3,7 @@ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { en
|
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
4
|
import createClient from "@fetchkit/ffetch";
|
|
5
5
|
import { Database } from "./database.js";
|
|
6
|
-
class
|
|
6
|
+
class FMServerConnection {
|
|
7
7
|
constructor(config) {
|
|
8
8
|
__publicField(this, "fetchClient");
|
|
9
9
|
__publicField(this, "serverUrl");
|
|
@@ -80,6 +80,6 @@ class FileMakerOData {
|
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
export {
|
|
83
|
-
|
|
83
|
+
FMServerConnection
|
|
84
84
|
};
|
|
85
85
|
//# sourceMappingURL=filemaker-odata.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filemaker-odata.js","sources":["../../../src/client/filemaker-odata.ts"],"sourcesContent":["import createClient, { FFetchOptions } from \"@fetchkit/ffetch\";\nimport type { Auth, ExecutionContext } from \"../types\";\nimport { Database } from \"./database\";\nimport { TableOccurrence } from \"./table-occurrence\";\n\nexport class
|
|
1
|
+
{"version":3,"file":"filemaker-odata.js","sources":["../../../src/client/filemaker-odata.ts"],"sourcesContent":["import createClient, { FFetchOptions } from \"@fetchkit/ffetch\";\nimport type { Auth, ExecutionContext } from \"../types\";\nimport { Database } from \"./database\";\nimport { TableOccurrence } from \"./table-occurrence\";\n\nexport class FMServerConnection implements ExecutionContext {\n private fetchClient: ReturnType<typeof createClient>;\n private serverUrl: string;\n private auth: Auth;\n constructor(config: {\n serverUrl: string;\n auth: Auth;\n fetchClientOptions?: FFetchOptions;\n }) {\n this.fetchClient = createClient({\n retries: 0,\n ...config.fetchClientOptions,\n });\n // Ensure the URL uses https://, is valid, and has no trailing slash\n const url = new URL(config.serverUrl);\n if (url.protocol !== \"https:\") {\n url.protocol = \"https:\";\n }\n // Remove any trailing slash from pathname\n url.pathname = url.pathname.replace(/\\/+$/, \"\");\n this.serverUrl = url.toString().replace(/\\/+$/, \"\");\n this.auth = config.auth;\n }\n\n /**\n * @internal\n */\n async _makeRequest<T>(\n url: string,\n options?: RequestInit & FFetchOptions,\n ): Promise<T> {\n const baseUrl = `${this.serverUrl}${\"apiKey\" in this.auth ? `/otto` : \"\"}/fmi/odata/v4`;\n\n const headers = {\n Authorization:\n \"apiKey\" in this.auth\n ? `Bearer ${this.auth.apiKey}`\n : `Basic ${btoa(`${this.auth.username}:${this.auth.password}`)}`,\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n ...(options?.headers || {}),\n };\n\n // TEMPORARY WORKAROUND: Hopefully this feature will be fixed in the ffetch library\n // Extract fetchHandler and headers separately, only for tests where we're overriding the fetch handler per-request\n const fetchHandler = options?.fetchHandler;\n const {\n headers: _headers,\n fetchHandler: _fetchHandler,\n ...restOptions\n } = options || {};\n\n // If fetchHandler is provided, create a temporary client with it\n // Otherwise use the existing client\n const clientToUse = fetchHandler\n ? createClient({ retries: 0, fetchHandler })\n : this.fetchClient;\n\n const resp = await clientToUse(baseUrl + url, {\n ...restOptions,\n headers,\n });\n\n if (!resp.ok) {\n throw new Error(\n `Failed to make request to ${baseUrl + url}: ${resp.statusText}`,\n );\n }\n\n // Check for affected rows header (for DELETE and bulk PATCH operations)\n // FileMaker may return this with 204 No Content or 200 OK\n const affectedRows = resp.headers.get(\"fmodata.affected_rows\");\n if (affectedRows !== null) {\n return parseInt(affectedRows, 10) as T;\n }\n\n // Handle 204 No Content with no body\n if (resp.status === 204) {\n return 0 as T;\n }\n\n if (resp.headers.get(\"content-type\")?.includes(\"application/json\")) {\n let data = await resp.json();\n if (data.error) {\n throw new Error(data.error);\n }\n return data as T;\n }\n return (await resp.text()) as T;\n }\n\n database<\n const Occurrences extends readonly TableOccurrence<any, any, any, any>[],\n >(\n name: string,\n config?: { occurrences?: Occurrences },\n ): Database<Occurrences> {\n return new Database(name, this, config);\n }\n\n /**\n * Lists all available databases from the FileMaker OData service.\n * @returns Promise resolving to an array of database names\n */\n async listDatabaseNames(): Promise<string[]> {\n const response = (await this._makeRequest(\"/\")) as {\n value?: Array<{ name: string }>;\n };\n if (response.value && Array.isArray(response.value)) {\n return response.value.map((item) => item.name);\n }\n return [];\n }\n}\n"],"names":[],"mappings":";;;;;AAKO,MAAM,mBAA+C;AAAA,EAI1D,YAAY,QAIT;AAPK;AACA;AACA;AAMN,SAAK,cAAc,aAAa;AAAA,MAC9B,SAAS;AAAA,MACT,GAAG,OAAO;AAAA,IAAA,CACX;AAED,UAAM,MAAM,IAAI,IAAI,OAAO,SAAS;AAChC,QAAA,IAAI,aAAa,UAAU;AAC7B,UAAI,WAAW;AAAA,IAAA;AAGjB,QAAI,WAAW,IAAI,SAAS,QAAQ,QAAQ,EAAE;AAC9C,SAAK,YAAY,IAAI,SAAW,EAAA,QAAQ,QAAQ,EAAE;AAClD,SAAK,OAAO,OAAO;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAMrB,MAAM,aACJ,KACA,SACY;;AACN,UAAA,UAAU,GAAG,KAAK,SAAS,GAAG,YAAY,KAAK,OAAO,UAAU,EAAE;AAExE,UAAM,UAAU;AAAA,MACd,eACE,YAAY,KAAK,OACb,UAAU,KAAK,KAAK,MAAM,KAC1B,SAAS,KAAK,GAAG,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;AAAA,MAClE,gBAAgB;AAAA,MAChB,QAAQ;AAAA,MACR,IAAI,mCAAS,YAAW,CAAA;AAAA,IAC1B;AAIA,UAAM,eAAe,mCAAS;AACxB,UAAA;AAAA,MACJ,SAAS;AAAA,MACT,cAAc;AAAA,MACd,GAAG;AAAA,IACL,IAAI,WAAW,CAAC;AAIV,UAAA,cAAc,eAChB,aAAa,EAAE,SAAS,GAAG,aAAA,CAAc,IACzC,KAAK;AAET,UAAM,OAAO,MAAM,YAAY,UAAU,KAAK;AAAA,MAC5C,GAAG;AAAA,MACH;AAAA,IAAA,CACD;AAEG,QAAA,CAAC,KAAK,IAAI;AACZ,YAAM,IAAI;AAAA,QACR,6BAA6B,UAAU,GAAG,KAAK,KAAK,UAAU;AAAA,MAChE;AAAA,IAAA;AAKF,UAAM,eAAe,KAAK,QAAQ,IAAI,uBAAuB;AAC7D,QAAI,iBAAiB,MAAM;AAClB,aAAA,SAAS,cAAc,EAAE;AAAA,IAAA;AAI9B,QAAA,KAAK,WAAW,KAAK;AAChB,aAAA;AAAA,IAAA;AAGT,SAAI,UAAK,QAAQ,IAAI,cAAc,MAA/B,mBAAkC,SAAS,qBAAqB;AAC9D,UAAA,OAAO,MAAM,KAAK,KAAK;AAC3B,UAAI,KAAK,OAAO;AACR,cAAA,IAAI,MAAM,KAAK,KAAK;AAAA,MAAA;AAErB,aAAA;AAAA,IAAA;AAED,WAAA,MAAM,KAAK,KAAK;AAAA,EAAA;AAAA,EAG1B,SAGE,MACA,QACuB;AACvB,WAAO,IAAI,SAAS,MAAM,MAAM,MAAM;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOxC,MAAM,oBAAuC;AAC3C,UAAM,WAAY,MAAM,KAAK,aAAa,GAAG;AAG7C,QAAI,SAAS,SAAS,MAAM,QAAQ,SAAS,KAAK,GAAG;AACnD,aAAO,SAAS,MAAM,IAAI,CAAC,SAAS,KAAK,IAAI;AAAA,IAAA;AAE/C,WAAO,CAAC;AAAA,EAAA;AAEZ;"}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
export { BaseTable } from './client/base-table.js';
|
|
2
2
|
export { TableOccurrence, createTableOccurrence, } from './client/table-occurrence.js';
|
|
3
|
-
export { FileMakerOData } from './client/filemaker-odata.js';
|
|
3
|
+
export { FMServerConnection as FileMakerOData } from './client/filemaker-odata.js';
|
|
4
|
+
export type { Database } from './client/database.js';
|
|
5
|
+
export type { EntitySet } from './client/entity-set.js';
|
|
6
|
+
export type { Result, InferSchemaType, InsertData, UpdateData, ODataRecordMetadata, } from './types.js';
|
|
4
7
|
export type { Filter, TypedFilter, FieldFilter, StringOperators, NumberOperators, BooleanOperators, DateOperators, LogicalFilter, } from './filter-types.js';
|
package/dist/esm/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { BaseTable } from "./client/base-table.js";
|
|
2
2
|
import { TableOccurrence, createTableOccurrence } from "./client/table-occurrence.js";
|
|
3
|
-
import {
|
|
3
|
+
import { FMServerConnection } from "./client/filemaker-odata.js";
|
|
4
4
|
export {
|
|
5
5
|
BaseTable,
|
|
6
|
-
FileMakerOData,
|
|
6
|
+
FMServerConnection as FileMakerOData,
|
|
7
7
|
TableOccurrence,
|
|
8
8
|
createTableOccurrence
|
|
9
9
|
};
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@ import type { Auth, ExecutionContext } from "../types";
|
|
|
3
3
|
import { Database } from "./database";
|
|
4
4
|
import { TableOccurrence } from "./table-occurrence";
|
|
5
5
|
|
|
6
|
-
export class
|
|
6
|
+
export class FMServerConnection implements ExecutionContext {
|
|
7
7
|
private fetchClient: ReturnType<typeof createClient>;
|
|
8
8
|
private serverUrl: string;
|
|
9
9
|
private auth: Auth;
|
package/src/index.ts
CHANGED
|
@@ -4,7 +4,23 @@ export {
|
|
|
4
4
|
TableOccurrence,
|
|
5
5
|
createTableOccurrence,
|
|
6
6
|
} from "./client/table-occurrence";
|
|
7
|
-
export { FileMakerOData } from "./client/filemaker-odata";
|
|
7
|
+
export { FMServerConnection as FileMakerOData } from "./client/filemaker-odata";
|
|
8
|
+
|
|
9
|
+
// Type-only exports for TypeScript declaration file portability
|
|
10
|
+
// Users get these instances from the builder pattern, not by direct instantiation
|
|
11
|
+
export type { Database } from "./client/database";
|
|
12
|
+
export type { EntitySet } from "./client/entity-set";
|
|
13
|
+
|
|
14
|
+
// Utility types for type annotations
|
|
15
|
+
export type {
|
|
16
|
+
Result,
|
|
17
|
+
InferSchemaType,
|
|
18
|
+
InsertData,
|
|
19
|
+
UpdateData,
|
|
20
|
+
ODataRecordMetadata,
|
|
21
|
+
} from "./types";
|
|
22
|
+
|
|
23
|
+
// Filter types
|
|
8
24
|
export type {
|
|
9
25
|
Filter,
|
|
10
26
|
TypedFilter,
|