@minipim/sdk 0.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 +155 -0
- package/dist/client.d.ts +66 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +43 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/openapi.d.ts +6862 -0
- package/dist/openapi.d.ts.map +1 -0
- package/dist/openapi.js +6 -0
- package/dist/openapi.js.map +1 -0
- package/dist/webhook.d.ts +66 -0
- package/dist/webhook.d.ts.map +1 -0
- package/dist/webhook.js +94 -0
- package/dist/webhook.js.map +1 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# @minipim/sdk
|
|
2
|
+
|
|
3
|
+
Typed TypeScript client for the [MiniPim](https://github.com/Epic-Design-Labs/minipim) API. Generated from the OpenAPI spec at `/docs/json` and wrapped with `openapi-fetch` plus a webhook-signature helper.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @minipim/sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Requires Node 18+ (for native `fetch`) or a fetch polyfill.
|
|
12
|
+
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { createMinipimClient } from '@minipim/sdk';
|
|
17
|
+
|
|
18
|
+
const pim = createMinipimClient({
|
|
19
|
+
baseUrl: 'https://api.minipim.com',
|
|
20
|
+
organizationId: '00000000-0000-0000-0000-000000000001',
|
|
21
|
+
apiKey: process.env.MINIPIM_API_KEY!,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// List products
|
|
25
|
+
const { data, error } = await pim.GET('/v1/products', {
|
|
26
|
+
params: { query: { limit: 50, sortBy: 'name', sortDir: 'asc' } },
|
|
27
|
+
});
|
|
28
|
+
if (error) throw new Error(error.error.message);
|
|
29
|
+
console.log(`got ${data.data.length} products, hasMore: ${data.hasMore}`);
|
|
30
|
+
|
|
31
|
+
// Single product with locale + channel resolution
|
|
32
|
+
const product = await pim.GET('/v1/products/{id}', {
|
|
33
|
+
params: {
|
|
34
|
+
path: { id: '0b8c5d3a-…' },
|
|
35
|
+
query: { locale: 'en_US', channel: 'headless-main' },
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
console.log(product.data?.resolvedAttributes);
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Authentication
|
|
42
|
+
|
|
43
|
+
API keys (recommended for service-to-service):
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
const pim = createMinipimClient({
|
|
47
|
+
baseUrl: 'https://api.minipim.com',
|
|
48
|
+
organizationId: '<your-org-uuid>',
|
|
49
|
+
apiKey: 'pim_xxxxxxxxxxxx',
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Issue keys in the admin UI at `/api-keys`. `x-organization-id` is required separately — API keys identify the principal, not the tenant.
|
|
54
|
+
|
|
55
|
+
Dev mode (header auth) — only when the deployment is started with `PIM_AUTH=header`:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
const pim = createMinipimClient({
|
|
59
|
+
baseUrl: 'http://localhost:4100',
|
|
60
|
+
organizationId: '00000000-0000-0000-0000-000000000001',
|
|
61
|
+
userId: 'dev-test',
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Webhooks
|
|
66
|
+
|
|
67
|
+
The headless connector POSTs events to your URL with an HMAC-SHA256 signature in `X-MiniPim-Signature-256`. Verify against the **raw** body — re-stringified JSON breaks the signature.
|
|
68
|
+
|
|
69
|
+
### Next.js App Router
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
import { verifyMinipimWebhook } from '@minipim/sdk/webhook';
|
|
73
|
+
|
|
74
|
+
export async function POST(req: Request) {
|
|
75
|
+
const raw = await req.text();
|
|
76
|
+
const sig = req.headers.get('x-minipim-signature-256') ?? '';
|
|
77
|
+
const ok = await verifyMinipimWebhook({
|
|
78
|
+
rawBody: raw,
|
|
79
|
+
signature: sig,
|
|
80
|
+
secret: process.env.MINIPIM_WEBHOOK_SECRET!,
|
|
81
|
+
});
|
|
82
|
+
if (!ok) return new Response('invalid signature', { status: 401 });
|
|
83
|
+
|
|
84
|
+
const event = JSON.parse(raw);
|
|
85
|
+
// event.name = 'product.updated' | 'category.deleted' | ...
|
|
86
|
+
// event.entity_id, event.payload, etc.
|
|
87
|
+
// Handle + return 2xx — non-2xx is silently dropped in v1 (no retries yet).
|
|
88
|
+
return Response.json({ ok: true });
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Edge / Cloudflare Workers / Vercel Edge
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
import { verifyMinipimWebhookEdge } from '@minipim/sdk/webhook';
|
|
96
|
+
|
|
97
|
+
const ok = await verifyMinipimWebhookEdge({ rawBody, signature, secret });
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Both functions:
|
|
101
|
+
- Constant-time comparison (safe against timing attacks).
|
|
102
|
+
- Return `false` on malformed signatures (don't throw).
|
|
103
|
+
- Same interface; the only difference is which crypto API they use under the hood.
|
|
104
|
+
|
|
105
|
+
## Pagination
|
|
106
|
+
|
|
107
|
+
Every list endpoint returns `{ data, limit, offset, hasMore, total? }`. Iterate via `hasMore`:
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
async function* allProducts() {
|
|
111
|
+
let offset = 0;
|
|
112
|
+
for (;;) {
|
|
113
|
+
const { data, error } = await pim.GET('/v1/products', {
|
|
114
|
+
params: { query: { limit: 200, offset } },
|
|
115
|
+
});
|
|
116
|
+
if (error) throw new Error(error.error.message);
|
|
117
|
+
for (const p of data.data) yield p;
|
|
118
|
+
if (!data.hasMore) return;
|
|
119
|
+
offset += 200;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Pass `withTotal: true` if you need `data.total` — adds one `COUNT(*)` query, so leave it off on hot reads.
|
|
125
|
+
|
|
126
|
+
## Reconciliation after downtime
|
|
127
|
+
|
|
128
|
+
`?updatedSince=<iso8601>` filters the product list to rows modified after a timestamp. Pair with `hasMore` to walk the changeset back to current state:
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
async function catchUp(since: string) {
|
|
132
|
+
for await (const p of allProducts({ updatedSince: since })) {
|
|
133
|
+
await ingest(p);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## TypeScript reference
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
import type { paths, components, operations } from '@minipim/sdk';
|
|
142
|
+
type Product = components['schemas']['ProductSelect'];
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
The generated `paths`, `components`, and `operations` cover the full surface at `/docs/json`. Use them to type DTOs, request handlers, etc.
|
|
146
|
+
|
|
147
|
+
## Related
|
|
148
|
+
|
|
149
|
+
- [Narrative integration guide](https://github.com/Epic-Design-Labs/minipim/blob/main/docs/DEVELOPERS.md) — auth, pagination, locale/channel resolution, webhook contract, common integration shapes.
|
|
150
|
+
- [Swagger UI](https://api.minipim.com/docs) — interactive endpoint reference, try-it-out enabled.
|
|
151
|
+
- [OpenAPI spec](https://api.minipim.com/docs/json) — raw JSON, what this SDK is generated from.
|
|
152
|
+
|
|
153
|
+
## License
|
|
154
|
+
|
|
155
|
+
Apache-2.0.
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin wrapper around `openapi-fetch` that pre-binds the tenancy header and
|
|
3
|
+
* (optionally) an API key. Returns the standard openapi-fetch client, so all
|
|
4
|
+
* its features (request interceptors, raw response access, etc.) work as
|
|
5
|
+
* documented at https://openapi-ts.dev/openapi-fetch/.
|
|
6
|
+
*/
|
|
7
|
+
import { type Client } from 'openapi-fetch';
|
|
8
|
+
import type { paths } from './openapi.js';
|
|
9
|
+
export interface CreateMinipimClientOptions {
|
|
10
|
+
/**
|
|
11
|
+
* Base URL of the MiniPim API, e.g. `https://api.minipim.com`. Required.
|
|
12
|
+
* Trailing slashes are normalized.
|
|
13
|
+
*/
|
|
14
|
+
baseUrl: string;
|
|
15
|
+
/**
|
|
16
|
+
* Tenant the client speaks for. Required — every authenticated endpoint
|
|
17
|
+
* needs `x-organization-id`. API keys identify the principal, not the
|
|
18
|
+
* tenant.
|
|
19
|
+
*/
|
|
20
|
+
organizationId: string;
|
|
21
|
+
/**
|
|
22
|
+
* Bearer API key (e.g. `pim_abc123…`). Issue one in the admin under
|
|
23
|
+
* /api-keys. If you're running in dev with `PIM_AUTH=header`, omit this
|
|
24
|
+
* and set `userId` instead.
|
|
25
|
+
*/
|
|
26
|
+
apiKey?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Dev-only header (`x-pim-user-id`). Only set when the deployment is in
|
|
29
|
+
* `header` auth mode. Ignored in `jwt` / `clerk` deployments.
|
|
30
|
+
*/
|
|
31
|
+
userId?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Extra headers merged onto every request — useful for tracing IDs,
|
|
34
|
+
* feature flags, etc. Don't put auth here; use `apiKey`/`userId` so the
|
|
35
|
+
* names stay consistent.
|
|
36
|
+
*/
|
|
37
|
+
headers?: Record<string, string>;
|
|
38
|
+
/**
|
|
39
|
+
* Override `fetch` — pass a polyfill in Node <18 or a wrapped fetch that
|
|
40
|
+
* adds timeouts, retries, telemetry. Defaults to the global `fetch`.
|
|
41
|
+
*/
|
|
42
|
+
fetch?: typeof fetch;
|
|
43
|
+
}
|
|
44
|
+
export type MinipimClient = Client<paths>;
|
|
45
|
+
/**
|
|
46
|
+
* Create a typed MiniPim client.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* import { createMinipimClient } from '@minipim/sdk';
|
|
51
|
+
*
|
|
52
|
+
* const pim = createMinipimClient({
|
|
53
|
+
* baseUrl: 'https://api.minipim.com',
|
|
54
|
+
* organizationId: '00000000-0000-0000-0000-000000000001',
|
|
55
|
+
* apiKey: process.env.MINIPIM_API_KEY!,
|
|
56
|
+
* });
|
|
57
|
+
*
|
|
58
|
+
* const { data, error } = await pim.GET('/v1/products', {
|
|
59
|
+
* params: { query: { limit: 50, categoryId: '…' } },
|
|
60
|
+
* });
|
|
61
|
+
* if (error) throw new Error(error.error.message);
|
|
62
|
+
* console.log(data.hasMore, data.data.length);
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
export declare function createMinipimClient(opts: CreateMinipimClientOptions): MinipimClient;
|
|
66
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAqB,EAAE,KAAK,MAAM,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAE1C,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;AAE1C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,0BAA0B,GAC/B,aAAa,CAaf"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin wrapper around `openapi-fetch` that pre-binds the tenancy header and
|
|
3
|
+
* (optionally) an API key. Returns the standard openapi-fetch client, so all
|
|
4
|
+
* its features (request interceptors, raw response access, etc.) work as
|
|
5
|
+
* documented at https://openapi-ts.dev/openapi-fetch/.
|
|
6
|
+
*/
|
|
7
|
+
import createClient from 'openapi-fetch';
|
|
8
|
+
/**
|
|
9
|
+
* Create a typed MiniPim client.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { createMinipimClient } from '@minipim/sdk';
|
|
14
|
+
*
|
|
15
|
+
* const pim = createMinipimClient({
|
|
16
|
+
* baseUrl: 'https://api.minipim.com',
|
|
17
|
+
* organizationId: '00000000-0000-0000-0000-000000000001',
|
|
18
|
+
* apiKey: process.env.MINIPIM_API_KEY!,
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* const { data, error } = await pim.GET('/v1/products', {
|
|
22
|
+
* params: { query: { limit: 50, categoryId: '…' } },
|
|
23
|
+
* });
|
|
24
|
+
* if (error) throw new Error(error.error.message);
|
|
25
|
+
* console.log(data.hasMore, data.data.length);
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export function createMinipimClient(opts) {
|
|
29
|
+
const headers = {
|
|
30
|
+
'x-organization-id': opts.organizationId,
|
|
31
|
+
...(opts.headers ?? {}),
|
|
32
|
+
};
|
|
33
|
+
if (opts.apiKey)
|
|
34
|
+
headers['Authorization'] = `Bearer ${opts.apiKey}`;
|
|
35
|
+
if (opts.userId)
|
|
36
|
+
headers['x-pim-user-id'] = opts.userId;
|
|
37
|
+
return createClient({
|
|
38
|
+
baseUrl: opts.baseUrl.replace(/\/$/, ''),
|
|
39
|
+
fetch: opts.fetch,
|
|
40
|
+
headers,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,YAA6B,MAAM,eAAe,CAAC;AAyC1D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAAgC;IAEhC,MAAM,OAAO,GAA2B;QACtC,mBAAmB,EAAE,IAAI,CAAC,cAAc;QACxC,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;KACxB,CAAC;IACF,IAAI,IAAI,CAAC,MAAM;QAAE,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,IAAI,CAAC,MAAM,EAAE,CAAC;IACpE,IAAI,IAAI,CAAC,MAAM;QAAE,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;IAExD,OAAO,YAAY,CAAQ;QACzB,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;QACxC,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,OAAO;KACR,CAAC,CAAC;AACL,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @minipim/sdk — typed TypeScript client for the MiniPim API.
|
|
3
|
+
*
|
|
4
|
+
* See https://github.com/Epic-Design-Labs/minipim/blob/main/packages/sdk/README.md
|
|
5
|
+
* for examples; the canonical narrative integration guide lives at
|
|
6
|
+
* https://github.com/Epic-Design-Labs/minipim/blob/main/docs/DEVELOPERS.md.
|
|
7
|
+
*/
|
|
8
|
+
export { createMinipimClient, type CreateMinipimClientOptions, type MinipimClient, } from './client.js';
|
|
9
|
+
export { verifyMinipimWebhook, verifyMinipimWebhookEdge, type VerifyWebhookOptions, } from './webhook.js';
|
|
10
|
+
export type { paths, components, operations } from './openapi.js';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EACL,mBAAmB,EACnB,KAAK,0BAA0B,EAC/B,KAAK,aAAa,GACnB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,oBAAoB,EACpB,wBAAwB,EACxB,KAAK,oBAAoB,GAC1B,MAAM,cAAc,CAAC;AAItB,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @minipim/sdk — typed TypeScript client for the MiniPim API.
|
|
3
|
+
*
|
|
4
|
+
* See https://github.com/Epic-Design-Labs/minipim/blob/main/packages/sdk/README.md
|
|
5
|
+
* for examples; the canonical narrative integration guide lives at
|
|
6
|
+
* https://github.com/Epic-Design-Labs/minipim/blob/main/docs/DEVELOPERS.md.
|
|
7
|
+
*/
|
|
8
|
+
export { createMinipimClient, } from './client.js';
|
|
9
|
+
export { verifyMinipimWebhook, verifyMinipimWebhookEdge, } from './webhook.js';
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EACL,mBAAmB,GAGpB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,oBAAoB,EACpB,wBAAwB,GAEzB,MAAM,cAAc,CAAC"}
|