@onagentic/master-data 1.0.0 → 1.1.0
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 +230 -35
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +63 -8
- package/dist/index.d.ts +63 -8
- package/dist/index.js +1 -1
- package/package.json +13 -8
package/README.md
CHANGED
|
@@ -1,81 +1,276 @@
|
|
|
1
1
|
# @onagentic/master-data
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@onagentic/master-data)
|
|
4
|
+
[](#)
|
|
5
|
+
[](#)
|
|
6
|
+
|
|
3
7
|
Lightweight TypeScript client for fetching master data from a Strapi-compatible REST API.
|
|
4
8
|
|
|
5
|
-
Supports
|
|
9
|
+
Supports Bearer/custom auth, pagination, field selection, group filtering, auto-pagination, and runtime config updates.
|
|
10
|
+
|
|
11
|
+
---
|
|
6
12
|
|
|
7
13
|
## Install
|
|
8
14
|
|
|
9
15
|
```bash
|
|
16
|
+
# npm
|
|
10
17
|
npm install @onagentic/master-data
|
|
18
|
+
|
|
19
|
+
# yarn
|
|
20
|
+
yarn add @onagentic/master-data
|
|
21
|
+
|
|
22
|
+
# pnpm
|
|
23
|
+
pnpm add @onagentic/master-data
|
|
11
24
|
```
|
|
12
25
|
|
|
26
|
+
> Requires Node.js `>=18.0.0` (uses native `fetch`).
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
13
30
|
## Quick start
|
|
14
31
|
|
|
15
32
|
```ts
|
|
16
|
-
import { createClient } from
|
|
33
|
+
import { createClient } from "@onagentic/master-data";
|
|
17
34
|
|
|
18
35
|
const client = createClient({
|
|
19
|
-
baseUrl:
|
|
36
|
+
baseUrl: "https://api.example.com",
|
|
20
37
|
token: process.env.API_TOKEN!,
|
|
21
38
|
});
|
|
22
39
|
|
|
23
|
-
//
|
|
24
|
-
const items = await client.getItems(
|
|
40
|
+
// Fetch one page — returns MasterDataItem[]
|
|
41
|
+
const items = await client.getItems("UNIQUE_KEY");
|
|
25
42
|
|
|
26
|
-
//
|
|
27
|
-
const all = await client.fetchAll(
|
|
43
|
+
// Fetch ALL pages automatically — returns MasterDataItem[]
|
|
44
|
+
const all = await client.fetchAll("UNIQUE_KEY");
|
|
28
45
|
|
|
29
46
|
// Full response with pagination meta
|
|
30
|
-
const response = await client.fetch(
|
|
47
|
+
const response = await client.fetch("UNIQUE_KEY", {
|
|
31
48
|
pagination: { page: 2, pageSize: 50 },
|
|
32
|
-
sort: { field:
|
|
33
|
-
fields: [
|
|
49
|
+
sort: { field: "label", order: "asc" },
|
|
50
|
+
fields: ["documentId", "key", "label"],
|
|
34
51
|
activeOnly: false,
|
|
35
52
|
});
|
|
36
|
-
console.log(response.meta.pagination);
|
|
53
|
+
console.log(response.meta.pagination);
|
|
54
|
+
// { page: 2, pageSize: 50, pageCount: 4, total: 180 }
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### CJS (CommonJS)
|
|
58
|
+
|
|
59
|
+
```js
|
|
60
|
+
const { createClient } = require("@onagentic/master-data");
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## API
|
|
66
|
+
|
|
67
|
+
### `createClient(config)`
|
|
68
|
+
|
|
69
|
+
Factory function. Returns a `MasterDataClient` instance.
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
const client = createClient({ baseUrl: "...", token: "..." });
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
### `MasterDataClient`
|
|
78
|
+
|
|
79
|
+
You can also instantiate the class directly:
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
import { MasterDataClient } from "@onagentic/master-data";
|
|
83
|
+
|
|
84
|
+
const client = new MasterDataClient({ baseUrl: "...", token: "..." });
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
#### `client.getItems(groupCode, options?)`
|
|
88
|
+
|
|
89
|
+
Fetch one page and return `MasterDataItem[]`.
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
const items = await client.getItems("UNIQUE_KEY");
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
#### `client.fetchAll(groupCode, options?)`
|
|
96
|
+
|
|
97
|
+
Auto-paginate all pages and return a flat `MasterDataItem[]`. Use `maxPages` to cap the number of pages fetched (default: `100`).
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
const items = await client.fetchAll("UNIQUE_KEY", { activeOnly: false });
|
|
101
|
+
const capped = await client.fetchAll("UNIQUE_KEY", { maxPages: 10 });
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
#### `client.fetch(groupCode, options?)`
|
|
105
|
+
|
|
106
|
+
Fetch one page and return the full `MasterDataResponse` (including `meta.pagination`).
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
const { data, meta } = await client.fetch("UNIQUE_KEY", {
|
|
110
|
+
pagination: { page: 1, pageSize: 25 },
|
|
111
|
+
});
|
|
112
|
+
console.log(meta.pagination.total);
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
#### `client.updateConfig(partial)`
|
|
116
|
+
|
|
117
|
+
Update config at runtime without creating a new client (e.g. after token refresh).
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
client.updateConfig({ token: "new-token" });
|
|
37
121
|
```
|
|
38
122
|
|
|
123
|
+
---
|
|
124
|
+
|
|
39
125
|
## Config options
|
|
40
126
|
|
|
41
|
-
| Option
|
|
42
|
-
|
|
43
|
-
| `baseUrl`
|
|
44
|
-
| `token`
|
|
45
|
-
| `
|
|
46
|
-
| `
|
|
47
|
-
| `
|
|
48
|
-
| `
|
|
49
|
-
| `
|
|
50
|
-
| `
|
|
127
|
+
| Option | Type | Default | Description |
|
|
128
|
+
| ------------------ | --------------------------- | ---------------------------------------------------- | ------------------------------------ |
|
|
129
|
+
| `baseUrl` | `string` | **required** | API base URL |
|
|
130
|
+
| `token` | `string` | — | Bearer token (`Authorization` header)|
|
|
131
|
+
| `headers` | `Record<string, string>` | — | Custom/additional request headers |
|
|
132
|
+
| `apiPath` | `string` | `/api/master-datas` | API endpoint path |
|
|
133
|
+
| `defaultFields` | `string[]` | `['documentId','key','label','order','is_active']` | Fields to request |
|
|
134
|
+
| `defaultPageSize` | `number` | `100` | Items per page |
|
|
135
|
+
| `defaultSortField` | `string` | `'order'` | Default sort field |
|
|
136
|
+
| `defaultSortOrder` | `'asc' \| 'desc'` | `'asc'` | Default sort direction |
|
|
137
|
+
| `timeout` | `number` | `10000` | Request timeout in milliseconds |
|
|
138
|
+
|
|
139
|
+
> `token` and `headers` can be used together. `headers` entries override the default `Authorization` header if you need a custom auth scheme (e.g. `{ Authorization: 'Token my-token' }` or `{ apikey: 'key' }`).
|
|
140
|
+
|
|
141
|
+
---
|
|
51
142
|
|
|
52
143
|
## Fetch options
|
|
53
144
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
|
57
|
-
|
|
|
58
|
-
| `
|
|
59
|
-
| `
|
|
60
|
-
| `
|
|
145
|
+
**`FetchOptions`** — used by `fetch()` and `getItems()`
|
|
146
|
+
|
|
147
|
+
| Option | Type | Default | Description |
|
|
148
|
+
| ------------ | ---------------------- | ------- | ------------------------------------ |
|
|
149
|
+
| `activeOnly` | `boolean` | `true` | Filter `is_active = true` |
|
|
150
|
+
| `pagination` | `{ page?, pageSize? }` | — | Override pagination for this request |
|
|
151
|
+
| `sort` | `{ field?, order? }` | — | Override sort for this request |
|
|
152
|
+
| `fields` | `string[]` | — | Override fields for this request |
|
|
153
|
+
|
|
154
|
+
**`FetchAllOptions`** — extends `FetchOptions`, used by `fetchAll()`
|
|
155
|
+
|
|
156
|
+
| Option | Type | Default | Description |
|
|
157
|
+
| ---------- | -------- | ------- | ------------------------------------------------------ |
|
|
158
|
+
| `maxPages` | `number` | `100` | Max pages to fetch — safeguard against infinite loops |
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## TypeScript types
|
|
163
|
+
|
|
164
|
+
All types are exported and can be imported directly:
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
import type {
|
|
168
|
+
MasterDataClientConfig,
|
|
169
|
+
MasterDataItem,
|
|
170
|
+
MasterDataResponse,
|
|
171
|
+
PaginationMeta,
|
|
172
|
+
PaginationOptions,
|
|
173
|
+
SortOptions,
|
|
174
|
+
FetchOptions,
|
|
175
|
+
FetchAllOptions,
|
|
176
|
+
} from "@onagentic/master-data";
|
|
177
|
+
|
|
178
|
+
import {
|
|
179
|
+
MasterDataClient,
|
|
180
|
+
createClient,
|
|
181
|
+
MasterDataError,
|
|
182
|
+
ValidationError,
|
|
183
|
+
TimeoutError,
|
|
184
|
+
ApiError,
|
|
185
|
+
ResponseShapeError,
|
|
186
|
+
} from "@onagentic/master-data";
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
#### `MasterDataItem`
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
interface MasterDataItem {
|
|
193
|
+
documentId: string;
|
|
194
|
+
key: string;
|
|
195
|
+
label: string;
|
|
196
|
+
order: number;
|
|
197
|
+
is_active: boolean;
|
|
198
|
+
[key: string]: unknown; // extra fields from API
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
#### `MasterDataResponse`
|
|
61
203
|
|
|
62
|
-
|
|
204
|
+
```ts
|
|
205
|
+
interface MasterDataResponse {
|
|
206
|
+
data: MasterDataItem[];
|
|
207
|
+
meta: {
|
|
208
|
+
pagination: PaginationMeta;
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
#### `PaginationMeta`
|
|
63
214
|
|
|
64
215
|
```ts
|
|
65
|
-
|
|
66
|
-
|
|
216
|
+
interface PaginationMeta {
|
|
217
|
+
page: number;
|
|
218
|
+
pageSize: number;
|
|
219
|
+
pageCount: number;
|
|
220
|
+
total: number;
|
|
221
|
+
}
|
|
67
222
|
```
|
|
68
223
|
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Error handling
|
|
227
|
+
|
|
228
|
+
All errors extend `MasterDataError` — use `instanceof` to branch by type:
|
|
229
|
+
|
|
230
|
+
```ts
|
|
231
|
+
import { ApiError, TimeoutError, ValidationError, ResponseShapeError } from "@onagentic/master-data";
|
|
232
|
+
|
|
233
|
+
try {
|
|
234
|
+
const items = await client.getItems("UNIQUE_KEY");
|
|
235
|
+
} catch (err) {
|
|
236
|
+
if (err instanceof ApiError) {
|
|
237
|
+
console.error(`HTTP ${err.status}:`, err.body);
|
|
238
|
+
} else if (err instanceof TimeoutError) {
|
|
239
|
+
console.error(`Timed out after ${err.timeoutMs}ms`);
|
|
240
|
+
} else if (err instanceof ValidationError) {
|
|
241
|
+
console.error("Bad config:", err.message);
|
|
242
|
+
} else if (err instanceof ResponseShapeError) {
|
|
243
|
+
console.error("Unexpected API response:", err.message);
|
|
244
|
+
} else {
|
|
245
|
+
throw err;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
| Class | When thrown | Extra properties |
|
|
251
|
+
| -------------------- | -------------------------------------------------- | ------------------------- |
|
|
252
|
+
| `ValidationError` | `baseUrl` or `groupCode` is missing | — |
|
|
253
|
+
| `TimeoutError` | Request exceeds `timeout` ms | `.timeoutMs: number` |
|
|
254
|
+
| `ApiError` | HTTP response is not `2xx` | `.status`, `.body` |
|
|
255
|
+
| `ResponseShapeError` | Response JSON doesn't match expected shape | — |
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
69
259
|
## Release
|
|
70
260
|
|
|
71
261
|
```bash
|
|
72
|
-
#
|
|
73
|
-
npm version patch # or minor / major
|
|
262
|
+
# 1. Bump version
|
|
263
|
+
npm version patch # or: minor / major
|
|
74
264
|
|
|
75
|
-
#
|
|
76
|
-
npm publish
|
|
265
|
+
# 2. Build, test, then publish
|
|
266
|
+
npm publish
|
|
77
267
|
```
|
|
78
268
|
|
|
269
|
+
> `prepublishOnly` runs `build` and `test` automatically before publish.
|
|
270
|
+
> No need for `--access public` — already configured in `package.json`.
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
79
274
|
## License
|
|
80
275
|
|
|
81
276
|
MIT
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
'use strict';var
|
|
1
|
+
'use strict';var l=class extends Error{constructor(t){super(`[master-data] ${t}`),this.name="MasterDataError";}},c=class extends l{constructor(t){super(t),this.name="ValidationError";}},d=class extends l{timeoutMs;constructor(t){super(`Request timed out after ${t}ms`),this.name="TimeoutError",this.timeoutMs=t;}},f=class extends l{status;body;constructor(t,a,r){super(`API error ${t} ${a}: ${r}`),this.name="ApiError",this.status=t,this.body=r;}},g=class extends l{constructor(t){super(`Unexpected response shape: ${t}`),this.name="ResponseShapeError";}};var E=["documentId","key","label","order","is_active"];var b="order";function F(e){return e.map(([t,a])=>`${encodeURIComponent(t).replace(/%5B/gi,"[").replace(/%5D/gi,"]").replace(/%24/gi,"$")}=${encodeURIComponent(a)}`).join("&")}function S(e,t,a){var s,m,D,C;let r=[],p=((s=t.sort)==null?void 0:s.field)??a.defaultSortField,u=((m=t.sort)==null?void 0:m.order)??a.defaultSortOrder;r.push([`sort[${p}]`,u]);let i=((D=t.pagination)==null?void 0:D.page)??1,n=((C=t.pagination)==null?void 0:C.pageSize)??a.defaultPageSize;r.push(["pagination[page]",String(i)]),r.push(["pagination[pageSize]",String(n)]);let o=t.fields??a.defaultFields;return r.push(["fields",o.join(",")]),r.push(["filters[$and][0][groups][code][$containsi]",e]),t.activeOnly!==false&&r.push(["filters[$and][1][is_active][$eq]","true"]),F(r)}function y(e){return {baseUrl:e.baseUrl.replace(/\/$/,""),token:e.token??"",headers:e.headers??{},apiPath:e.apiPath??"/api/master-datas",defaultFields:e.defaultFields??E,defaultPageSize:e.defaultPageSize??100,defaultSortOrder:e.defaultSortOrder??"asc",defaultSortField:e.defaultSortField??b,timeout:e.timeout??1e4}}var M=100,h=class{config;constructor(t){if(!t.baseUrl)throw new c("baseUrl is required");this.config=y(t);}async fetch(t,a={}){if(!t)throw new c("groupCode is required");let r=S(t,a,this.config),p=`${this.config.baseUrl}${this.config.apiPath}?${r}`,u=new AbortController,i=setTimeout(()=>u.abort(),this.config.timeout),n;try{let s={"Content-Type":"application/json",...this.config.token?{Authorization:`Bearer ${this.config.token}`}:{}};n=await fetch(p,{method:"GET",headers:{...s,...this.config.headers},signal:u.signal});}catch(s){throw s.name==="AbortError"?new d(this.config.timeout):s}finally{clearTimeout(i);}if(!n.ok){let s=await n.text().catch(()=>"");throw new f(n.status,n.statusText,s)}let o=await n.json();if(!R(o))throw new g("expected { data: [...], meta: { pagination: {...} } }");return o}async fetchAll(t,a={}){var o;let{maxPages:r=M,...p}=a,u=((o=p.pagination)==null?void 0:o.pageSize)??this.config.defaultPageSize,i=1,n=[];for(;i<=r;){let s=await this.fetch(t,{...p,pagination:{page:i,pageSize:u}});n.push(...s.data);let{pageCount:m}=s.meta.pagination;if(i>=m)break;i++;}return n}async getItems(t,a={}){return (await this.fetch(t,a)).data}updateConfig(t){this.config=y({...this.config,...t});}};function R(e){if(typeof e!="object"||e===null)return false;let t=e;if(!Array.isArray(t.data))return false;let a=t.meta;if(typeof a!="object"||a===null)return false;let r=a.pagination;return typeof r!="object"||r===null?false:typeof r.page=="number"&&typeof r.pageSize=="number"&&typeof r.pageCount=="number"&&typeof r.total=="number"}function T(e){return new h(e)}exports.ApiError=f;exports.MasterDataClient=h;exports.MasterDataError=l;exports.ResponseShapeError=g;exports.TimeoutError=d;exports.ValidationError=c;exports.createClient=T;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
interface MasterDataClientConfig {
|
|
2
2
|
/** Base URL of the API endpoint (e.g. https://api.example.com) */
|
|
3
3
|
baseUrl: string;
|
|
4
|
-
/**
|
|
5
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Bearer token — sent as `Authorization: Bearer <token>`.
|
|
6
|
+
* Leave empty if your API uses a different auth method via `headers`.
|
|
7
|
+
*/
|
|
8
|
+
token?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Custom request headers. Use this to override the default auth header or add extra headers.
|
|
11
|
+
* @example { apikey: 'my-api-key' } // API key style
|
|
12
|
+
* @example { Authorization: 'Token my-token' } // custom auth scheme
|
|
13
|
+
*/
|
|
14
|
+
headers?: Record<string, string>;
|
|
6
15
|
/** API path prefix (default: /api/master-datas) */
|
|
7
16
|
apiPath?: string;
|
|
8
17
|
/** Default fields to fetch (default: documentId,key,label,order,is_active) */
|
|
@@ -31,8 +40,13 @@ interface FetchOptions {
|
|
|
31
40
|
sort?: SortOptions;
|
|
32
41
|
/** Override default fields */
|
|
33
42
|
fields?: string[];
|
|
34
|
-
|
|
35
|
-
|
|
43
|
+
}
|
|
44
|
+
interface FetchAllOptions extends FetchOptions {
|
|
45
|
+
/**
|
|
46
|
+
* Maximum number of pages to fetch (default: 100).
|
|
47
|
+
* Acts as a safeguard against infinite loops when the API returns unexpected pagination data.
|
|
48
|
+
*/
|
|
49
|
+
maxPages?: number;
|
|
36
50
|
}
|
|
37
51
|
interface MasterDataItem {
|
|
38
52
|
documentId: string;
|
|
@@ -56,7 +70,7 @@ interface MasterDataResponse {
|
|
|
56
70
|
}
|
|
57
71
|
|
|
58
72
|
declare class MasterDataClient {
|
|
59
|
-
private
|
|
73
|
+
private config;
|
|
60
74
|
constructor(config: MasterDataClientConfig);
|
|
61
75
|
/**
|
|
62
76
|
* Fetch one page of master data items for the given group code.
|
|
@@ -64,11 +78,11 @@ declare class MasterDataClient {
|
|
|
64
78
|
fetch(groupCode: string, options?: FetchOptions): Promise<MasterDataResponse>;
|
|
65
79
|
/**
|
|
66
80
|
* Fetch ALL pages for the given group code and return a flat item array.
|
|
67
|
-
* Uses the `fetchAll` flag or call this method directly.
|
|
68
81
|
*/
|
|
69
|
-
fetchAll(groupCode: string, options?:
|
|
82
|
+
fetchAll(groupCode: string, options?: FetchAllOptions): Promise<MasterDataItem[]>;
|
|
70
83
|
/**
|
|
71
84
|
* Convenience: fetch items and return the data array (single page).
|
|
85
|
+
* Use `fetchAll` for automatic multi-page fetching.
|
|
72
86
|
*/
|
|
73
87
|
getItems(groupCode: string, options?: FetchOptions): Promise<MasterDataItem[]>;
|
|
74
88
|
/**
|
|
@@ -77,6 +91,47 @@ declare class MasterDataClient {
|
|
|
77
91
|
updateConfig(partial: Partial<MasterDataClientConfig>): void;
|
|
78
92
|
}
|
|
79
93
|
|
|
94
|
+
declare class MasterDataError extends Error {
|
|
95
|
+
constructor(message: string);
|
|
96
|
+
}
|
|
97
|
+
declare class ValidationError extends MasterDataError {
|
|
98
|
+
constructor(message: string);
|
|
99
|
+
}
|
|
100
|
+
declare class TimeoutError extends MasterDataError {
|
|
101
|
+
readonly timeoutMs: number;
|
|
102
|
+
constructor(timeoutMs: number);
|
|
103
|
+
}
|
|
104
|
+
declare class ApiError extends MasterDataError {
|
|
105
|
+
readonly status: number;
|
|
106
|
+
readonly body: string;
|
|
107
|
+
constructor(status: number, statusText: string, body: string);
|
|
108
|
+
}
|
|
109
|
+
declare class ResponseShapeError extends MasterDataError {
|
|
110
|
+
constructor(detail: string);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Convenience factory — create a configured client in one call.
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* ```ts
|
|
118
|
+
* import { createClient, ApiError, TimeoutError } from '@onagentic/master-data';
|
|
119
|
+
*
|
|
120
|
+
* const client = createClient({
|
|
121
|
+
* baseUrl: 'https://api.example.com',
|
|
122
|
+
* token: process.env.API_TOKEN!,
|
|
123
|
+
* });
|
|
124
|
+
*
|
|
125
|
+
* try {
|
|
126
|
+
* const items = await client.getItems('UNIQUE_KEY');
|
|
127
|
+
* const all = await client.fetchAll('UNIQUE_KEY', { maxPages: 10 });
|
|
128
|
+
* } catch (err) {
|
|
129
|
+
* if (err instanceof ApiError) console.error('HTTP', err.status, err.body);
|
|
130
|
+
* else if (err instanceof TimeoutError) console.error('Timed out after', err.timeoutMs, 'ms');
|
|
131
|
+
* else throw err;
|
|
132
|
+
* }
|
|
133
|
+
* ```
|
|
134
|
+
*/
|
|
80
135
|
declare function createClient(config: MasterDataClientConfig): MasterDataClient;
|
|
81
136
|
|
|
82
|
-
export { type FetchOptions, MasterDataClient, type MasterDataClientConfig, type MasterDataItem, type MasterDataResponse, type PaginationMeta, type PaginationOptions, type SortOptions, createClient };
|
|
137
|
+
export { ApiError, type FetchAllOptions, type FetchOptions, MasterDataClient, type MasterDataClientConfig, MasterDataError, type MasterDataItem, type MasterDataResponse, type PaginationMeta, type PaginationOptions, ResponseShapeError, type SortOptions, TimeoutError, ValidationError, createClient };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
interface MasterDataClientConfig {
|
|
2
2
|
/** Base URL of the API endpoint (e.g. https://api.example.com) */
|
|
3
3
|
baseUrl: string;
|
|
4
|
-
/**
|
|
5
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Bearer token — sent as `Authorization: Bearer <token>`.
|
|
6
|
+
* Leave empty if your API uses a different auth method via `headers`.
|
|
7
|
+
*/
|
|
8
|
+
token?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Custom request headers. Use this to override the default auth header or add extra headers.
|
|
11
|
+
* @example { apikey: 'my-api-key' } // API key style
|
|
12
|
+
* @example { Authorization: 'Token my-token' } // custom auth scheme
|
|
13
|
+
*/
|
|
14
|
+
headers?: Record<string, string>;
|
|
6
15
|
/** API path prefix (default: /api/master-datas) */
|
|
7
16
|
apiPath?: string;
|
|
8
17
|
/** Default fields to fetch (default: documentId,key,label,order,is_active) */
|
|
@@ -31,8 +40,13 @@ interface FetchOptions {
|
|
|
31
40
|
sort?: SortOptions;
|
|
32
41
|
/** Override default fields */
|
|
33
42
|
fields?: string[];
|
|
34
|
-
|
|
35
|
-
|
|
43
|
+
}
|
|
44
|
+
interface FetchAllOptions extends FetchOptions {
|
|
45
|
+
/**
|
|
46
|
+
* Maximum number of pages to fetch (default: 100).
|
|
47
|
+
* Acts as a safeguard against infinite loops when the API returns unexpected pagination data.
|
|
48
|
+
*/
|
|
49
|
+
maxPages?: number;
|
|
36
50
|
}
|
|
37
51
|
interface MasterDataItem {
|
|
38
52
|
documentId: string;
|
|
@@ -56,7 +70,7 @@ interface MasterDataResponse {
|
|
|
56
70
|
}
|
|
57
71
|
|
|
58
72
|
declare class MasterDataClient {
|
|
59
|
-
private
|
|
73
|
+
private config;
|
|
60
74
|
constructor(config: MasterDataClientConfig);
|
|
61
75
|
/**
|
|
62
76
|
* Fetch one page of master data items for the given group code.
|
|
@@ -64,11 +78,11 @@ declare class MasterDataClient {
|
|
|
64
78
|
fetch(groupCode: string, options?: FetchOptions): Promise<MasterDataResponse>;
|
|
65
79
|
/**
|
|
66
80
|
* Fetch ALL pages for the given group code and return a flat item array.
|
|
67
|
-
* Uses the `fetchAll` flag or call this method directly.
|
|
68
81
|
*/
|
|
69
|
-
fetchAll(groupCode: string, options?:
|
|
82
|
+
fetchAll(groupCode: string, options?: FetchAllOptions): Promise<MasterDataItem[]>;
|
|
70
83
|
/**
|
|
71
84
|
* Convenience: fetch items and return the data array (single page).
|
|
85
|
+
* Use `fetchAll` for automatic multi-page fetching.
|
|
72
86
|
*/
|
|
73
87
|
getItems(groupCode: string, options?: FetchOptions): Promise<MasterDataItem[]>;
|
|
74
88
|
/**
|
|
@@ -77,6 +91,47 @@ declare class MasterDataClient {
|
|
|
77
91
|
updateConfig(partial: Partial<MasterDataClientConfig>): void;
|
|
78
92
|
}
|
|
79
93
|
|
|
94
|
+
declare class MasterDataError extends Error {
|
|
95
|
+
constructor(message: string);
|
|
96
|
+
}
|
|
97
|
+
declare class ValidationError extends MasterDataError {
|
|
98
|
+
constructor(message: string);
|
|
99
|
+
}
|
|
100
|
+
declare class TimeoutError extends MasterDataError {
|
|
101
|
+
readonly timeoutMs: number;
|
|
102
|
+
constructor(timeoutMs: number);
|
|
103
|
+
}
|
|
104
|
+
declare class ApiError extends MasterDataError {
|
|
105
|
+
readonly status: number;
|
|
106
|
+
readonly body: string;
|
|
107
|
+
constructor(status: number, statusText: string, body: string);
|
|
108
|
+
}
|
|
109
|
+
declare class ResponseShapeError extends MasterDataError {
|
|
110
|
+
constructor(detail: string);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Convenience factory — create a configured client in one call.
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* ```ts
|
|
118
|
+
* import { createClient, ApiError, TimeoutError } from '@onagentic/master-data';
|
|
119
|
+
*
|
|
120
|
+
* const client = createClient({
|
|
121
|
+
* baseUrl: 'https://api.example.com',
|
|
122
|
+
* token: process.env.API_TOKEN!,
|
|
123
|
+
* });
|
|
124
|
+
*
|
|
125
|
+
* try {
|
|
126
|
+
* const items = await client.getItems('UNIQUE_KEY');
|
|
127
|
+
* const all = await client.fetchAll('UNIQUE_KEY', { maxPages: 10 });
|
|
128
|
+
* } catch (err) {
|
|
129
|
+
* if (err instanceof ApiError) console.error('HTTP', err.status, err.body);
|
|
130
|
+
* else if (err instanceof TimeoutError) console.error('Timed out after', err.timeoutMs, 'ms');
|
|
131
|
+
* else throw err;
|
|
132
|
+
* }
|
|
133
|
+
* ```
|
|
134
|
+
*/
|
|
80
135
|
declare function createClient(config: MasterDataClientConfig): MasterDataClient;
|
|
81
136
|
|
|
82
|
-
export { type FetchOptions, MasterDataClient, type MasterDataClientConfig, type MasterDataItem, type MasterDataResponse, type PaginationMeta, type PaginationOptions, type SortOptions, createClient };
|
|
137
|
+
export { ApiError, type FetchAllOptions, type FetchOptions, MasterDataClient, type MasterDataClientConfig, MasterDataError, type MasterDataItem, type MasterDataResponse, type PaginationMeta, type PaginationOptions, ResponseShapeError, type SortOptions, TimeoutError, ValidationError, createClient };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var l=class extends Error{constructor(t){super(`[master-data] ${t}`),this.name="MasterDataError";}},c=class extends l{constructor(t){super(t),this.name="ValidationError";}},d=class extends l{timeoutMs;constructor(t){super(`Request timed out after ${t}ms`),this.name="TimeoutError",this.timeoutMs=t;}},f=class extends l{status;body;constructor(t,a,r){super(`API error ${t} ${a}: ${r}`),this.name="ApiError",this.status=t,this.body=r;}},g=class extends l{constructor(t){super(`Unexpected response shape: ${t}`),this.name="ResponseShapeError";}};var E=["documentId","key","label","order","is_active"];var b="order";function F(e){return e.map(([t,a])=>`${encodeURIComponent(t).replace(/%5B/gi,"[").replace(/%5D/gi,"]").replace(/%24/gi,"$")}=${encodeURIComponent(a)}`).join("&")}function S(e,t,a){var s,m,D,C;let r=[],p=((s=t.sort)==null?void 0:s.field)??a.defaultSortField,u=((m=t.sort)==null?void 0:m.order)??a.defaultSortOrder;r.push([`sort[${p}]`,u]);let i=((D=t.pagination)==null?void 0:D.page)??1,n=((C=t.pagination)==null?void 0:C.pageSize)??a.defaultPageSize;r.push(["pagination[page]",String(i)]),r.push(["pagination[pageSize]",String(n)]);let o=t.fields??a.defaultFields;return r.push(["fields",o.join(",")]),r.push(["filters[$and][0][groups][code][$containsi]",e]),t.activeOnly!==false&&r.push(["filters[$and][1][is_active][$eq]","true"]),F(r)}function y(e){return {baseUrl:e.baseUrl.replace(/\/$/,""),token:e.token??"",headers:e.headers??{},apiPath:e.apiPath??"/api/master-datas",defaultFields:e.defaultFields??E,defaultPageSize:e.defaultPageSize??100,defaultSortOrder:e.defaultSortOrder??"asc",defaultSortField:e.defaultSortField??b,timeout:e.timeout??1e4}}var M=100,h=class{config;constructor(t){if(!t.baseUrl)throw new c("baseUrl is required");this.config=y(t);}async fetch(t,a={}){if(!t)throw new c("groupCode is required");let r=S(t,a,this.config),p=`${this.config.baseUrl}${this.config.apiPath}?${r}`,u=new AbortController,i=setTimeout(()=>u.abort(),this.config.timeout),n;try{let s={"Content-Type":"application/json",...this.config.token?{Authorization:`Bearer ${this.config.token}`}:{}};n=await fetch(p,{method:"GET",headers:{...s,...this.config.headers},signal:u.signal});}catch(s){throw s.name==="AbortError"?new d(this.config.timeout):s}finally{clearTimeout(i);}if(!n.ok){let s=await n.text().catch(()=>"");throw new f(n.status,n.statusText,s)}let o=await n.json();if(!R(o))throw new g("expected { data: [...], meta: { pagination: {...} } }");return o}async fetchAll(t,a={}){var o;let{maxPages:r=M,...p}=a,u=((o=p.pagination)==null?void 0:o.pageSize)??this.config.defaultPageSize,i=1,n=[];for(;i<=r;){let s=await this.fetch(t,{...p,pagination:{page:i,pageSize:u}});n.push(...s.data);let{pageCount:m}=s.meta.pagination;if(i>=m)break;i++;}return n}async getItems(t,a={}){return (await this.fetch(t,a)).data}updateConfig(t){this.config=y({...this.config,...t});}};function R(e){if(typeof e!="object"||e===null)return false;let t=e;if(!Array.isArray(t.data))return false;let a=t.meta;if(typeof a!="object"||a===null)return false;let r=a.pagination;return typeof r!="object"||r===null?false:typeof r.page=="number"&&typeof r.pageSize=="number"&&typeof r.pageCount=="number"&&typeof r.total=="number"}function T(e){return new h(e)}export{f as ApiError,h as MasterDataClient,l as MasterDataError,g as ResponseShapeError,d as TimeoutError,c as ValidationError,T as createClient};
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onagentic/master-data",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Lightweight client for fetching master data from a
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "Lightweight client for fetching master data from a API endpoint",
|
|
5
5
|
"keywords": [
|
|
6
|
+
"onagentic",
|
|
7
|
+
"typescript",
|
|
6
8
|
"master-data",
|
|
7
|
-
"strapi",
|
|
8
9
|
"api-client"
|
|
9
10
|
],
|
|
10
11
|
"license": "MIT",
|
|
@@ -13,7 +14,11 @@
|
|
|
13
14
|
".": {
|
|
14
15
|
"types": "./dist/index.d.ts",
|
|
15
16
|
"import": "./dist/index.js",
|
|
16
|
-
"require":
|
|
17
|
+
"require": {
|
|
18
|
+
"types": "./dist/index.d.cts",
|
|
19
|
+
"default": "./dist/index.cjs"
|
|
20
|
+
},
|
|
21
|
+
"default": "./dist/index.js"
|
|
17
22
|
}
|
|
18
23
|
},
|
|
19
24
|
"main": "./dist/index.cjs",
|
|
@@ -27,6 +32,10 @@
|
|
|
27
32
|
"test": "node --experimental-vm-modules node_modules/.bin/jest",
|
|
28
33
|
"prepublishOnly": "npm run build && npm test"
|
|
29
34
|
},
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public",
|
|
37
|
+
"registry": "https://registry.npmjs.org/"
|
|
38
|
+
},
|
|
30
39
|
"devDependencies": {
|
|
31
40
|
"@jest/globals": "^29.7.0",
|
|
32
41
|
"@types/node": "^22.0.0",
|
|
@@ -37,9 +46,5 @@
|
|
|
37
46
|
},
|
|
38
47
|
"engines": {
|
|
39
48
|
"node": ">=18.0.0"
|
|
40
|
-
},
|
|
41
|
-
"repository": {
|
|
42
|
-
"type": "git",
|
|
43
|
-
"url": "https://github.com/onagentic/master-data.git"
|
|
44
49
|
}
|
|
45
50
|
}
|