@minipim/sdk 0.2.0 → 0.3.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.
Files changed (49) hide show
  1. package/README.md +3 -1
  2. package/dist/attributes.cjs +80 -0
  3. package/dist/attributes.d.cts +48 -0
  4. package/dist/attributes.d.ts +12 -11
  5. package/dist/attributes.js +46 -71
  6. package/dist/index.cjs +163 -0
  7. package/dist/index.d.cts +132 -0
  8. package/dist/index.d.ts +128 -13
  9. package/dist/index.js +117 -16
  10. package/dist/openapi.cjs +18 -0
  11. package/dist/openapi.d.cts +7042 -0
  12. package/dist/openapi.d.ts +183 -9
  13. package/dist/openapi.js +0 -6
  14. package/dist/webhook-edge.cjs +68 -0
  15. package/dist/webhook-edge.d.cts +26 -0
  16. package/dist/webhook-edge.d.ts +6 -4
  17. package/dist/webhook-edge.js +40 -31
  18. package/dist/{webhook-shared.d.ts → webhook-shared-CjMkFYVb.d.cts} +3 -6
  19. package/dist/webhook-shared-CjMkFYVb.d.ts +25 -0
  20. package/dist/webhook.cjs +53 -0
  21. package/dist/webhook.d.cts +26 -0
  22. package/dist/webhook.d.ts +5 -4
  23. package/dist/webhook.js +27 -39
  24. package/package.json +45 -13
  25. package/dist/attributes.d.ts.map +0 -1
  26. package/dist/attributes.js.map +0 -1
  27. package/dist/client.d.ts +0 -66
  28. package/dist/client.d.ts.map +0 -1
  29. package/dist/client.js +0 -43
  30. package/dist/client.js.map +0 -1
  31. package/dist/errors.d.ts +0 -27
  32. package/dist/errors.d.ts.map +0 -1
  33. package/dist/errors.js +0 -30
  34. package/dist/errors.js.map +0 -1
  35. package/dist/index.d.ts.map +0 -1
  36. package/dist/index.js.map +0 -1
  37. package/dist/openapi.d.ts.map +0 -1
  38. package/dist/openapi.js.map +0 -1
  39. package/dist/paginate.d.ts +0 -34
  40. package/dist/paginate.d.ts.map +0 -1
  41. package/dist/paginate.js +0 -43
  42. package/dist/paginate.js.map +0 -1
  43. package/dist/webhook-edge.d.ts.map +0 -1
  44. package/dist/webhook-edge.js.map +0 -1
  45. package/dist/webhook-shared.d.ts.map +0 -1
  46. package/dist/webhook-shared.js +0 -30
  47. package/dist/webhook-shared.js.map +0 -1
  48. package/dist/webhook.d.ts.map +0 -1
  49. package/dist/webhook.js.map +0 -1
package/dist/index.d.ts CHANGED
@@ -1,17 +1,132 @@
1
+ import { Client } from 'openapi-fetch';
2
+ import { paths } from './openapi.js';
3
+ export { components, operations } from './openapi.js';
4
+ export { AttributeValueRecord, AttributesPayload, Measurement, Money, ResolveOptions, asMeasurement, asMoney, flattenAttributes, formatMoney, getAttribute } from './attributes.js';
5
+
1
6
  /**
2
- * @minipim/sdk typed TypeScript client for the MiniPim API.
7
+ * Thin wrapper around `openapi-fetch` that pre-binds the tenancy header and
8
+ * (optionally) an API key. Returns the standard openapi-fetch client, so all
9
+ * its features (request interceptors, raw response access, etc.) work as
10
+ * documented at https://openapi-ts.dev/openapi-fetch/.
11
+ */
12
+
13
+ interface CreateMinipimClientOptions {
14
+ /**
15
+ * Base URL of the MiniPim API, e.g. `https://api.minipim.com`. Required.
16
+ * Trailing slashes are normalized.
17
+ */
18
+ baseUrl: string;
19
+ /**
20
+ * Tenant the client speaks for. Required — every authenticated endpoint
21
+ * needs `x-organization-id`. API keys identify the principal, not the
22
+ * tenant.
23
+ */
24
+ organizationId: string;
25
+ /**
26
+ * Bearer API key (e.g. `pim_abc123…`). Issue one in the admin under
27
+ * /api-keys. If you're running in dev with `PIM_AUTH=header`, omit this
28
+ * and set `userId` instead.
29
+ */
30
+ apiKey?: string;
31
+ /**
32
+ * Dev-only header (`x-pim-user-id`). Only set when the deployment is in
33
+ * `header` auth mode. Ignored in `jwt` / `clerk` deployments.
34
+ */
35
+ userId?: string;
36
+ /**
37
+ * Extra headers merged onto every request — useful for tracing IDs,
38
+ * feature flags, etc. Don't put auth here; use `apiKey`/`userId` so the
39
+ * names stay consistent.
40
+ */
41
+ headers?: Record<string, string>;
42
+ /**
43
+ * Override `fetch` — pass a polyfill in Node <18 or a wrapped fetch that
44
+ * adds timeouts, retries, telemetry. Defaults to the global `fetch`.
45
+ */
46
+ fetch?: typeof fetch;
47
+ }
48
+ type MinipimClient = Client<paths>;
49
+ /**
50
+ * Create a typed MiniPim client.
51
+ *
52
+ * @example
53
+ * ```ts
54
+ * import { createMinipimClient } from '@minipim/sdk';
55
+ *
56
+ * const pim = createMinipimClient({
57
+ * baseUrl: 'https://api.minipim.com',
58
+ * organizationId: '00000000-0000-0000-0000-000000000001',
59
+ * apiKey: process.env.MINIPIM_API_KEY!,
60
+ * });
61
+ *
62
+ * const { data, error } = await pim.GET('/v1/products', {
63
+ * params: { query: { limit: 50, categoryId: '…' } },
64
+ * });
65
+ * if (error) throw new Error(error.error.message);
66
+ * console.log(data.hasMore, data.data.length);
67
+ * ```
68
+ */
69
+ declare function createMinipimClient(opts: CreateMinipimClientOptions): MinipimClient;
70
+
71
+ /**
72
+ * Generic pagination helper. Every MiniPim list endpoint returns
73
+ * `{ data, limit, offset, hasMore }`; this walks the pages so consumers
74
+ * don't hand-roll the `hasMore` loop. Yields one item at a time.
3
75
  *
4
- * Edge-safe: this entry point imports no `node:` modules. The Node webhook
5
- * verifier lives at `@minipim/sdk/webhook` (imports node:crypto); the Edge
6
- * verifier at `@minipim/sdk/webhook-edge`. Keeping them off the root means
7
- * `createMinipimClient` can be imported in Edge runtimes without pulling
8
- * node:crypto into the bundle.
76
+ * Typed loosely on purpose openapi-fetch's per-path generics don't
77
+ * compose into a single reusable signature without a lot of conditional-
78
+ * type machinery, and the envelope shape is uniform across list endpoints.
79
+ * The item type is yours to specify via the generic.
80
+ */
81
+
82
+ interface PaginateOptions {
83
+ /** Query params (filters, sort, withTotal, etc). `limit`/`offset` are managed for you. */
84
+ query?: Record<string, unknown>;
85
+ /** Page size. Default 200 (the API max). */
86
+ pageSize?: number;
87
+ }
88
+ /**
89
+ * Async-iterate every item across all pages of a MiniPim list endpoint.
90
+ *
91
+ * @example
92
+ * ```ts
93
+ * import { paginate } from '@minipim/sdk';
94
+ * for await (const product of paginate<Product>(pim, '/v1/products', {
95
+ * query: { status: 'active' },
96
+ * })) {
97
+ * await ingest(product);
98
+ * }
99
+ * ```
100
+ */
101
+ declare function paginate<T = unknown>(client: MinipimClient, path: string, opts?: PaginateOptions): AsyncGenerator<T, void, unknown>;
102
+ /** Collect every page into an array. Convenience around {@link paginate}. */
103
+ declare function collectAll<T = unknown>(client: MinipimClient, path: string, opts?: PaginateOptions): Promise<T[]>;
104
+
105
+ /**
106
+ * Error envelope + type guard. Every MiniPim 4xx/5xx returns
107
+ * `{ error: { code, message, details? } }`. openapi-fetch types `res.error`
108
+ * as a union across a path's declared error responses, which is awkward to
109
+ * narrow to `.error.message`. This guard collapses that to a single shape.
110
+ */
111
+ interface MinipimError {
112
+ error: {
113
+ code: string;
114
+ message: string;
115
+ details?: unknown;
116
+ };
117
+ }
118
+ /** True when `value` is a MiniPim `{ error: { code, message } }` envelope. */
119
+ declare function isMinipimError(value: unknown): value is MinipimError;
120
+ /**
121
+ * Pull a human-readable message out of an openapi-fetch `error` value,
122
+ * whatever its declared union shape. Falls back to `fallback`.
9
123
  *
10
- * See packages/sdk/README.md for examples.
124
+ * @example
125
+ * ```ts
126
+ * const { data, error } = await pim.GET('/v1/products');
127
+ * if (error) throw new Error(getErrorMessage(error, 'request failed'));
128
+ * ```
11
129
  */
12
- export { createMinipimClient, type CreateMinipimClientOptions, type MinipimClient, } from './client.js';
13
- export { paginate, collectAll, type PaginateOptions, } from './paginate.js';
14
- export { isMinipimError, getErrorMessage, type MinipimError, } from './errors.js';
15
- export { getAttribute, flattenAttributes, asMoney, asMeasurement, formatMoney, type AttributeValueRecord, type AttributesPayload, type Money, type Measurement, type ResolveOptions, } from './attributes.js';
16
- export type { paths, components, operations } from './openapi.js';
17
- //# sourceMappingURL=index.d.ts.map
130
+ declare function getErrorMessage(error: unknown, fallback?: string): string;
131
+
132
+ export { type CreateMinipimClientOptions, type MinipimClient, type MinipimError, type PaginateOptions, collectAll, createMinipimClient, getErrorMessage, isMinipimError, paginate, paths };
package/dist/index.js CHANGED
@@ -1,16 +1,117 @@
1
- /**
2
- * @minipim/sdk — typed TypeScript client for the MiniPim API.
3
- *
4
- * Edge-safe: this entry point imports no `node:` modules. The Node webhook
5
- * verifier lives at `@minipim/sdk/webhook` (imports node:crypto); the Edge
6
- * verifier at `@minipim/sdk/webhook-edge`. Keeping them off the root means
7
- * `createMinipimClient` can be imported in Edge runtimes without pulling
8
- * node:crypto into the bundle.
9
- *
10
- * See packages/sdk/README.md for examples.
11
- */
12
- export { createMinipimClient, } from './client.js';
13
- export { paginate, collectAll, } from './paginate.js';
14
- export { isMinipimError, getErrorMessage, } from './errors.js';
15
- export { getAttribute, flattenAttributes, asMoney, asMeasurement, formatMoney, } from './attributes.js';
16
- //# sourceMappingURL=index.js.map
1
+ // src/client.ts
2
+ import createClient from "openapi-fetch";
3
+ function createMinipimClient(opts) {
4
+ const headers = {
5
+ "x-organization-id": opts.organizationId,
6
+ ...opts.headers ?? {}
7
+ };
8
+ if (opts.apiKey) headers["Authorization"] = `Bearer ${opts.apiKey}`;
9
+ if (opts.userId) headers["x-pim-user-id"] = opts.userId;
10
+ return createClient({
11
+ baseUrl: opts.baseUrl.replace(/\/$/, ""),
12
+ fetch: opts.fetch,
13
+ headers
14
+ });
15
+ }
16
+
17
+ // src/paginate.ts
18
+ async function* paginate(client, path, opts = {}) {
19
+ const pageSize = opts.pageSize ?? 200;
20
+ let offset = 0;
21
+ for (; ; ) {
22
+ const get = client.GET;
23
+ const { data, error, response } = await get(path, {
24
+ params: { query: { ...opts.query ?? {}, limit: pageSize, offset } }
25
+ });
26
+ if (error || !data) {
27
+ throw new Error(
28
+ `paginate ${path} failed at offset ${offset} (HTTP ${response?.status})`
29
+ );
30
+ }
31
+ if (Array.isArray(data)) {
32
+ for (const item of data) yield item;
33
+ return;
34
+ }
35
+ if (!Array.isArray(data.data)) {
36
+ throw new Error(
37
+ `paginate ${path}: response is neither a list envelope nor an array \u2014 this endpoint may not be paginatable`
38
+ );
39
+ }
40
+ for (const item of data.data) yield item;
41
+ const more = data.hasMore ?? data.data.length === pageSize;
42
+ if (!more || data.data.length === 0) return;
43
+ offset += pageSize;
44
+ }
45
+ }
46
+ async function collectAll(client, path, opts = {}) {
47
+ const out = [];
48
+ for await (const item of paginate(client, path, opts)) out.push(item);
49
+ return out;
50
+ }
51
+
52
+ // src/errors.ts
53
+ function isMinipimError(value) {
54
+ if (!value || typeof value !== "object") return false;
55
+ const e = value.error;
56
+ return !!e && typeof e === "object" && typeof e.code === "string" && typeof e.message === "string";
57
+ }
58
+ function getErrorMessage(error, fallback = "request failed") {
59
+ return isMinipimError(error) ? error.error.message : fallback;
60
+ }
61
+
62
+ // src/attributes.ts
63
+ function getAttribute(attributes, code, opts = {}) {
64
+ const records = attributes[code];
65
+ if (!records || records.length === 0) return void 0;
66
+ const locale = opts.locale ?? null;
67
+ const channel = opts.channel ?? null;
68
+ const layers = [
69
+ [locale, channel],
70
+ [locale, null],
71
+ [null, channel],
72
+ [null, null]
73
+ ];
74
+ for (const [l, c] of layers) {
75
+ const hit = records.find((r) => r.locale === l && r.channel === c);
76
+ if (hit) return hit.value;
77
+ }
78
+ return void 0;
79
+ }
80
+ function flattenAttributes(attributes, opts = {}) {
81
+ const out = {};
82
+ for (const code of Object.keys(attributes)) {
83
+ const v = getAttribute(attributes, code, opts);
84
+ if (v !== void 0) out[code] = v;
85
+ }
86
+ return out;
87
+ }
88
+ function asMoney(value) {
89
+ if (value && typeof value === "object" && typeof value.amount_cents === "number" && typeof value.currency === "string") {
90
+ return value;
91
+ }
92
+ return null;
93
+ }
94
+ function asMeasurement(value) {
95
+ if (value && typeof value === "object" && typeof value.amount === "number" && typeof value.unit === "string") {
96
+ return value;
97
+ }
98
+ return null;
99
+ }
100
+ function formatMoney(money, locale = "en-US") {
101
+ return new Intl.NumberFormat(locale, {
102
+ style: "currency",
103
+ currency: money.currency
104
+ }).format(money.amount_cents / 100);
105
+ }
106
+ export {
107
+ asMeasurement,
108
+ asMoney,
109
+ collectAll,
110
+ createMinipimClient,
111
+ flattenAttributes,
112
+ formatMoney,
113
+ getAttribute,
114
+ getErrorMessage,
115
+ isMinipimError,
116
+ paginate
117
+ };
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+
16
+ // src/openapi.ts
17
+ var openapi_exports = {};
18
+ module.exports = __toCommonJS(openapi_exports);