@fixl-tech/igp-personalization 1.1.2

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 (54) hide show
  1. package/README.md +511 -0
  2. package/dist/catalog.d.ts +5 -0
  3. package/dist/catalog.d.ts.map +1 -0
  4. package/dist/catalog.js +76 -0
  5. package/dist/catalog.js.map +1 -0
  6. package/dist/client.d.ts +33 -0
  7. package/dist/client.d.ts.map +1 -0
  8. package/dist/client.js +101 -0
  9. package/dist/client.js.map +1 -0
  10. package/dist/designs.d.ts +12 -0
  11. package/dist/designs.d.ts.map +1 -0
  12. package/dist/designs.js +44 -0
  13. package/dist/designs.js.map +1 -0
  14. package/dist/errors.d.ts +17 -0
  15. package/dist/errors.d.ts.map +1 -0
  16. package/dist/errors.js +31 -0
  17. package/dist/errors.js.map +1 -0
  18. package/dist/ids.d.ts +2 -0
  19. package/dist/ids.d.ts.map +1 -0
  20. package/dist/ids.js +12 -0
  21. package/dist/ids.js.map +1 -0
  22. package/dist/index.d.ts +13 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +37 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/products.d.ts +12 -0
  27. package/dist/products.d.ts.map +1 -0
  28. package/dist/products.js +41 -0
  29. package/dist/products.js.map +1 -0
  30. package/dist/signing.d.ts +12 -0
  31. package/dist/signing.d.ts.map +1 -0
  32. package/dist/signing.js +55 -0
  33. package/dist/signing.js.map +1 -0
  34. package/dist/storage/json-file.d.ts +6 -0
  35. package/dist/storage/json-file.d.ts.map +1 -0
  36. package/dist/storage/json-file.js +62 -0
  37. package/dist/storage/json-file.js.map +1 -0
  38. package/dist/storage/memory.d.ts +3 -0
  39. package/dist/storage/memory.d.ts.map +1 -0
  40. package/dist/storage/memory.js +36 -0
  41. package/dist/storage/memory.js.map +1 -0
  42. package/dist/studio.d.ts +6 -0
  43. package/dist/studio.d.ts.map +1 -0
  44. package/dist/studio.js +16 -0
  45. package/dist/studio.js.map +1 -0
  46. package/dist/types.d.ts +130 -0
  47. package/dist/types.d.ts.map +1 -0
  48. package/dist/types.js +3 -0
  49. package/dist/types.js.map +1 -0
  50. package/dist/validation.d.ts +8 -0
  51. package/dist/validation.d.ts.map +1 -0
  52. package/dist/validation.js +101 -0
  53. package/dist/validation.js.map +1 -0
  54. package/package.json +52 -0
package/dist/client.js ADDED
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Client = void 0;
4
+ const errors_1 = require("./errors");
5
+ const signing_1 = require("./signing");
6
+ const API_PREFIX = '/v1';
7
+ class Client {
8
+ apiKey;
9
+ apiSecret;
10
+ baseUrl;
11
+ products;
12
+ designs;
13
+ fetchImpl;
14
+ constructor({ apiKey, apiSecret, baseUrl = 'http://localhost:5174', fetchImpl }) {
15
+ if (!apiKey || !apiSecret)
16
+ throw new Error('Client requires { apiKey, apiSecret }');
17
+ this.apiKey = apiKey;
18
+ this.apiSecret = apiSecret;
19
+ this.baseUrl = baseUrl.replace(/\/$/, '');
20
+ this.fetchImpl = fetchImpl || globalThis.fetch;
21
+ if (typeof this.fetchImpl !== 'function') {
22
+ throw new Error('global fetch is unavailable; use Node 18+ or pass { fetchImpl }');
23
+ }
24
+ this.products = {
25
+ list: () => this.request('GET', '/products'),
26
+ get: (id) => this.request('GET', `/products/${encodeURIComponent(id)}`),
27
+ addCustom: (input) => this.request('POST', '/products/custom', { body: input }),
28
+ removeCustom: (id) => this.request('DELETE', `/products/custom/${encodeURIComponent(id)}`),
29
+ };
30
+ this.designs = {
31
+ list: () => this.request('GET', '/designs'),
32
+ get: (id) => this.request('GET', `/designs/${encodeURIComponent(id)}`),
33
+ save: (input) => this.request('POST', '/designs', { body: input }),
34
+ delete: (id) => this.request('DELETE', `/designs/${encodeURIComponent(id)}`),
35
+ };
36
+ }
37
+ account() {
38
+ return this.request('GET', '/account');
39
+ }
40
+ async uploadImage(data, { filename = 'upload.png', contentType = 'image/png' } = {}) {
41
+ const path = `${API_PREFIX}/upload`;
42
+ const headers = this.headers({ method: 'POST', path, bodyStr: '' });
43
+ const form = new FormData();
44
+ const blob = data instanceof Blob ? data : new Blob([new Uint8Array(data)], { type: contentType });
45
+ form.append('image', blob, filename);
46
+ const response = await this.fetchImpl(this.baseUrl + path, { method: 'POST', headers, body: form });
47
+ return this.handle(response);
48
+ }
49
+ headers({ method, path, bodyStr }) {
50
+ const timestamp = Math.floor(Date.now() / 1000);
51
+ const signature = signing_1.signing.sign({
52
+ secret: this.apiSecret,
53
+ method,
54
+ path,
55
+ timestamp,
56
+ body: bodyStr,
57
+ });
58
+ return {
59
+ 'x-api-key': this.apiKey,
60
+ 'x-timestamp': String(timestamp),
61
+ 'x-signature': signature,
62
+ };
63
+ }
64
+ async request(method, subPath, options = {}) {
65
+ const path = API_PREFIX + subPath;
66
+ const hasBody = Object.prototype.hasOwnProperty.call(options, 'body');
67
+ const bodyStr = hasBody ? JSON.stringify(options.body) : '';
68
+ const headers = this.headers({ method, path, bodyStr });
69
+ if (hasBody)
70
+ headers['content-type'] = 'application/json';
71
+ const init = {
72
+ method,
73
+ headers,
74
+ };
75
+ if (hasBody)
76
+ init.body = bodyStr;
77
+ const response = await this.fetchImpl(this.baseUrl + path, init);
78
+ return this.handle(response);
79
+ }
80
+ async handle(response) {
81
+ let payload = null;
82
+ const text = await response.text();
83
+ if (text) {
84
+ try {
85
+ payload = JSON.parse(text);
86
+ }
87
+ catch {
88
+ payload = text;
89
+ }
90
+ }
91
+ if (!response.ok) {
92
+ const message = typeof payload === 'object' && payload !== null && 'error' in payload
93
+ ? String(payload.error)
94
+ : `Request failed with status ${response.status}`;
95
+ throw new errors_1.PersonalizationApiError(message, { status: response.status, body: payload });
96
+ }
97
+ return payload;
98
+ }
99
+ }
100
+ exports.Client = Client;
101
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";;;AAAA,qCAAmD;AACnD,uCAAoC;AAYpC,MAAM,UAAU,GAAG,KAAK,CAAC;AAIzB,MAAa,MAAM;IACR,MAAM,CAAS;IACf,SAAS,CAAS;IAClB,OAAO,CAAS;IAChB,QAAQ,CAKf;IACO,OAAO,CAKd;IAEe,SAAS,CAAe;IAEzC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,uBAAuB,EAAE,SAAS,EAAiB;QAC5F,IAAI,CAAC,MAAM,IAAI,CAAC,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAEpF,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC1C,IAAI,CAAC,SAAS,GAAG,SAAS,IAAI,UAAU,CAAC,KAAK,CAAC;QAE/C,IAAI,OAAO,IAAI,CAAC,SAAS,KAAK,UAAU,EAAE,CAAC;YACzC,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;QACrF,CAAC;QAED,IAAI,CAAC,QAAQ,GAAG;YACd,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAY,KAAK,EAAE,WAAW,CAAC;YACvD,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAU,KAAK,EAAE,aAAa,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAAC;YAChF,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAU,MAAM,EAAE,kBAAkB,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;YACxF,YAAY,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAe,QAAQ,EAAE,oBAAoB,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAAC;SACzG,CAAC;QAEF,IAAI,CAAC,OAAO,GAAG;YACb,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAW,KAAK,EAAE,UAAU,CAAC;YACrD,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAS,KAAK,EAAE,YAAY,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAAC;YAC9E,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAoC,MAAM,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;YACrG,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAe,QAAQ,EAAE,YAAY,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAAC;SAC3F,CAAC;IACJ,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,OAAO,CAAgB,KAAK,EAAE,UAAU,CAAC,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,WAAW,CACf,IAAgC,EAChC,EAAE,QAAQ,GAAG,YAAY,EAAE,WAAW,GAAG,WAAW,KAAoB,EAAE;QAE1E,MAAM,IAAI,GAAG,GAAG,UAAU,SAAS,CAAC;QACpC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;QAEpE,MAAM,IAAI,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,IAAI,YAAY,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;QACnG,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;QAErC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACpG,OAAO,IAAI,CAAC,MAAM,CAAe,QAAQ,CAAC,CAAC;IAC7C,CAAC;IAEO,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAqD;QAC1F,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAChD,MAAM,SAAS,GAAG,iBAAO,CAAC,IAAI,CAAC;YAC7B,MAAM,EAAE,IAAI,CAAC,SAAS;YACtB,MAAM;YACN,IAAI;YACJ,SAAS;YACT,IAAI,EAAE,OAAO;SACd,CAAC,CAAC;QAEH,OAAO;YACL,WAAW,EAAE,IAAI,CAAC,MAAM;YACxB,aAAa,EAAE,MAAM,CAAC,SAAS,CAAC;YAChC,aAAa,EAAE,SAAS;SACzB,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,OAAO,CAAY,MAAc,EAAE,OAAe,EAAE,UAAgC,EAAE;QAClG,MAAM,IAAI,GAAG,UAAU,GAAG,OAAO,CAAC;QAClC,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACtE,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QACxD,IAAI,OAAO;YAAE,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;QAE1D,MAAM,IAAI,GAAgB;YACxB,MAAM;YACN,OAAO;SACR,CAAC;QACF,IAAI,OAAO;YAAE,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC;QAEjC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC;QAEjE,OAAO,IAAI,CAAC,MAAM,CAAY,QAAQ,CAAC,CAAC;IAC1C,CAAC;IAEO,KAAK,CAAC,MAAM,CAAY,QAAkB;QAChD,IAAI,OAAO,GAAY,IAAI,CAAC;QAC5B,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC;gBACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAY,CAAC;YACxC,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;QACH,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,OAAO,GAAG,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,IAAI,OAAO;gBACnF,CAAC,CAAC,MAAM,CAAE,OAA8B,CAAC,KAAK,CAAC;gBAC/C,CAAC,CAAC,8BAA8B,QAAQ,CAAC,MAAM,EAAE,CAAC;YACpD,MAAM,IAAI,gCAAuB,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QACzF,CAAC;QAED,OAAO,OAAoB,CAAC;IAC9B,CAAC;CACF;AAxHD,wBAwHC"}
@@ -0,0 +1,12 @@
1
+ import type { Design, DesignInput, DesignServiceContract, StorageAdapter } from './types';
2
+ export declare class DesignService implements DesignServiceContract {
3
+ private readonly designs;
4
+ constructor(storage: StorageAdapter);
5
+ list(): Promise<Design[]>;
6
+ get(id: string): Promise<Design>;
7
+ save(input: DesignInput): Promise<Design>;
8
+ delete(id: string): Promise<{
9
+ ok: true;
10
+ }>;
11
+ }
12
+ //# sourceMappingURL=designs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"designs.d.ts","sourceRoot":"","sources":["../src/designs.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,qBAAqB,EAAE,cAAc,EAAqB,MAAM,SAAS,CAAC;AAI7G,qBAAa,aAAc,YAAW,qBAAqB;IACzD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4B;gBAExC,OAAO,EAAE,cAAc;IAI7B,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAKzB,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAMhC,IAAI,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAczC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,CAAC;CAKhD"}
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DesignService = void 0;
4
+ const errors_1 = require("./errors");
5
+ const ids_1 = require("./ids");
6
+ const validation_1 = require("./validation");
7
+ const COLLECTION = 'designs';
8
+ class DesignService {
9
+ designs;
10
+ constructor(storage) {
11
+ this.designs = storage.collection(COLLECTION);
12
+ }
13
+ async list() {
14
+ const designs = await this.designs.all();
15
+ return [...designs].sort((a, b) => String(b.createdAt).localeCompare(String(a.createdAt)));
16
+ }
17
+ async get(id) {
18
+ const design = await this.designs.get(id);
19
+ if (!design)
20
+ throw new errors_1.NotFoundError('Design not found');
21
+ return design;
22
+ }
23
+ async save(input) {
24
+ (0, validation_1.validateDesignInput)(input);
25
+ const design = {
26
+ id: (0, ids_1.createId)(10),
27
+ productId: input.productId,
28
+ productName: input.productName || input.productId,
29
+ layers: input.layers,
30
+ previewDataUrl: input.previewDataUrl || null,
31
+ createdAt: new Date().toISOString(),
32
+ };
33
+ await this.designs.put(design);
34
+ return design;
35
+ }
36
+ async delete(id) {
37
+ const removed = await this.designs.remove(id);
38
+ if (!removed)
39
+ throw new errors_1.NotFoundError('Design not found');
40
+ return { ok: true };
41
+ }
42
+ }
43
+ exports.DesignService = DesignService;
44
+ //# sourceMappingURL=designs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"designs.js","sourceRoot":"","sources":["../src/designs.ts"],"names":[],"mappings":";;;AAAA,qCAAyC;AACzC,+BAAiC;AACjC,6CAAmD;AAGnD,MAAM,UAAU,GAAG,SAAS,CAAC;AAE7B,MAAa,aAAa;IACP,OAAO,CAA4B;IAEpD,YAAY,OAAuB;QACjC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,UAAU,CAAS,UAAU,CAAC,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QACzC,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAC7F,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,EAAU;QAClB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,sBAAa,CAAC,kBAAkB,CAAC,CAAC;QACzD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAkB;QAC3B,IAAA,gCAAmB,EAAC,KAAK,CAAC,CAAC;QAC3B,MAAM,MAAM,GAAW;YACrB,EAAE,EAAE,IAAA,cAAQ,EAAC,EAAE,CAAC;YAChB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,SAAS;YACjD,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,cAAc,EAAE,KAAK,CAAC,cAAc,IAAI,IAAI;YAC5C,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QACF,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC/B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAU;QACrB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC9C,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,sBAAa,CAAC,kBAAkB,CAAC,CAAC;QAC1D,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC;CACF;AArCD,sCAqCC"}
@@ -0,0 +1,17 @@
1
+ export declare class ValidationError extends Error {
2
+ readonly code = "VALIDATION_ERROR";
3
+ constructor(message: string);
4
+ }
5
+ export declare class NotFoundError extends Error {
6
+ readonly code = "NOT_FOUND";
7
+ constructor(message: string);
8
+ }
9
+ export declare class PersonalizationApiError extends Error {
10
+ readonly status: number | undefined;
11
+ readonly body: unknown;
12
+ constructor(message: string, options?: {
13
+ status?: number;
14
+ body?: unknown;
15
+ });
16
+ }
17
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,eAAgB,SAAQ,KAAK;IACxC,QAAQ,CAAC,IAAI,sBAAsB;gBAEvB,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,IAAI,eAAe;gBAEhB,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;gBAEX,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAO;CAM/E"}
package/dist/errors.js ADDED
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PersonalizationApiError = exports.NotFoundError = exports.ValidationError = void 0;
4
+ class ValidationError extends Error {
5
+ code = 'VALIDATION_ERROR';
6
+ constructor(message) {
7
+ super(message);
8
+ this.name = 'ValidationError';
9
+ }
10
+ }
11
+ exports.ValidationError = ValidationError;
12
+ class NotFoundError extends Error {
13
+ code = 'NOT_FOUND';
14
+ constructor(message) {
15
+ super(message);
16
+ this.name = 'NotFoundError';
17
+ }
18
+ }
19
+ exports.NotFoundError = NotFoundError;
20
+ class PersonalizationApiError extends Error {
21
+ status;
22
+ body;
23
+ constructor(message, options = {}) {
24
+ super(message);
25
+ this.name = 'PersonalizationApiError';
26
+ this.status = options.status;
27
+ this.body = options.body;
28
+ }
29
+ }
30
+ exports.PersonalizationApiError = PersonalizationApiError;
31
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";;;AAAA,MAAa,eAAgB,SAAQ,KAAK;IAC/B,IAAI,GAAG,kBAAkB,CAAC;IAEnC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAPD,0CAOC;AAED,MAAa,aAAc,SAAQ,KAAK;IAC7B,IAAI,GAAG,WAAW,CAAC;IAE5B,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AAPD,sCAOC;AAED,MAAa,uBAAwB,SAAQ,KAAK;IACvC,MAAM,CAAqB;IAC3B,IAAI,CAAU;IAEvB,YAAY,OAAe,EAAE,UAA+C,EAAE;QAC5E,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;QACtC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAC3B,CAAC;CACF;AAVD,0DAUC"}
package/dist/ids.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare function createId(size?: number): string;
2
+ //# sourceMappingURL=ids.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ids.d.ts","sourceRoot":"","sources":["../src/ids.ts"],"names":[],"mappings":"AAEA,wBAAgB,QAAQ,CAAC,IAAI,SAAK,GAAG,MAAM,CAM1C"}
package/dist/ids.js ADDED
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createId = createId;
4
+ const ALPHABET = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-';
5
+ function createId(size = 10) {
6
+ let id = '';
7
+ for (let i = 0; i < size; i += 1) {
8
+ id += ALPHABET[Math.floor(Math.random() * ALPHABET.length)] ?? '0';
9
+ }
10
+ return id;
11
+ }
12
+ //# sourceMappingURL=ids.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ids.js","sourceRoot":"","sources":["../src/ids.ts"],"names":[],"mappings":";;AAEA,4BAMC;AARD,MAAM,QAAQ,GAAG,kEAAkE,CAAC;AAEpF,SAAgB,QAAQ,CAAC,IAAI,GAAG,EAAE;IAChC,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACjC,EAAE,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,GAAG,CAAC;IACrE,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC"}
@@ -0,0 +1,13 @@
1
+ export { Client } from './client';
2
+ export { BUILTIN_PRODUCTS, ALLOWED_SHAPES, normalizeProduct } from './catalog';
3
+ export { DesignService } from './designs';
4
+ export { NotFoundError, PersonalizationApiError, ValidationError } from './errors';
5
+ export { createId } from './ids';
6
+ export { ProductService } from './products';
7
+ export { buildStringToSign, sha256Hex, sign, signing, verify } from './signing';
8
+ export { createStudio } from './studio';
9
+ export { createJsonFileStorage } from './storage/json-file';
10
+ export { createMemoryStorage } from './storage/memory';
11
+ export { buildCustomProductFields, sanitizeArea, sanitizePoints, validateDesignInput, } from './validation';
12
+ export type { AccountResult, ClientOptions, CustomProductInput, Design, DesignInput, DesignLayer, DesignServiceContract, Point, PrintArea, PrintAreaShape, Product, ProductServiceContract, SigningInput, StorageAdapter, StorageCollection, StoredDocument, Studio, UploadOptions, UploadResult, VerifyInput, } from './types';
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,uBAAuB,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AACnF,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAChF,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EACL,wBAAwB,EACxB,YAAY,EACZ,cAAc,EACd,mBAAmB,GACpB,MAAM,cAAc,CAAC;AAEtB,YAAY,EACV,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,MAAM,EACN,WAAW,EACX,WAAW,EACX,qBAAqB,EACrB,KAAK,EACL,SAAS,EACT,cAAc,EACd,OAAO,EACP,sBAAsB,EACtB,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,MAAM,EACN,aAAa,EACb,YAAY,EACZ,WAAW,GACZ,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateDesignInput = exports.sanitizePoints = exports.sanitizeArea = exports.buildCustomProductFields = exports.createMemoryStorage = exports.createJsonFileStorage = exports.createStudio = exports.verify = exports.signing = exports.sign = exports.sha256Hex = exports.buildStringToSign = exports.ProductService = exports.createId = exports.ValidationError = exports.PersonalizationApiError = exports.NotFoundError = exports.DesignService = exports.normalizeProduct = exports.ALLOWED_SHAPES = exports.BUILTIN_PRODUCTS = exports.Client = void 0;
4
+ var client_1 = require("./client");
5
+ Object.defineProperty(exports, "Client", { enumerable: true, get: function () { return client_1.Client; } });
6
+ var catalog_1 = require("./catalog");
7
+ Object.defineProperty(exports, "BUILTIN_PRODUCTS", { enumerable: true, get: function () { return catalog_1.BUILTIN_PRODUCTS; } });
8
+ Object.defineProperty(exports, "ALLOWED_SHAPES", { enumerable: true, get: function () { return catalog_1.ALLOWED_SHAPES; } });
9
+ Object.defineProperty(exports, "normalizeProduct", { enumerable: true, get: function () { return catalog_1.normalizeProduct; } });
10
+ var designs_1 = require("./designs");
11
+ Object.defineProperty(exports, "DesignService", { enumerable: true, get: function () { return designs_1.DesignService; } });
12
+ var errors_1 = require("./errors");
13
+ Object.defineProperty(exports, "NotFoundError", { enumerable: true, get: function () { return errors_1.NotFoundError; } });
14
+ Object.defineProperty(exports, "PersonalizationApiError", { enumerable: true, get: function () { return errors_1.PersonalizationApiError; } });
15
+ Object.defineProperty(exports, "ValidationError", { enumerable: true, get: function () { return errors_1.ValidationError; } });
16
+ var ids_1 = require("./ids");
17
+ Object.defineProperty(exports, "createId", { enumerable: true, get: function () { return ids_1.createId; } });
18
+ var products_1 = require("./products");
19
+ Object.defineProperty(exports, "ProductService", { enumerable: true, get: function () { return products_1.ProductService; } });
20
+ var signing_1 = require("./signing");
21
+ Object.defineProperty(exports, "buildStringToSign", { enumerable: true, get: function () { return signing_1.buildStringToSign; } });
22
+ Object.defineProperty(exports, "sha256Hex", { enumerable: true, get: function () { return signing_1.sha256Hex; } });
23
+ Object.defineProperty(exports, "sign", { enumerable: true, get: function () { return signing_1.sign; } });
24
+ Object.defineProperty(exports, "signing", { enumerable: true, get: function () { return signing_1.signing; } });
25
+ Object.defineProperty(exports, "verify", { enumerable: true, get: function () { return signing_1.verify; } });
26
+ var studio_1 = require("./studio");
27
+ Object.defineProperty(exports, "createStudio", { enumerable: true, get: function () { return studio_1.createStudio; } });
28
+ var json_file_1 = require("./storage/json-file");
29
+ Object.defineProperty(exports, "createJsonFileStorage", { enumerable: true, get: function () { return json_file_1.createJsonFileStorage; } });
30
+ var memory_1 = require("./storage/memory");
31
+ Object.defineProperty(exports, "createMemoryStorage", { enumerable: true, get: function () { return memory_1.createMemoryStorage; } });
32
+ var validation_1 = require("./validation");
33
+ Object.defineProperty(exports, "buildCustomProductFields", { enumerable: true, get: function () { return validation_1.buildCustomProductFields; } });
34
+ Object.defineProperty(exports, "sanitizeArea", { enumerable: true, get: function () { return validation_1.sanitizeArea; } });
35
+ Object.defineProperty(exports, "sanitizePoints", { enumerable: true, get: function () { return validation_1.sanitizePoints; } });
36
+ Object.defineProperty(exports, "validateDesignInput", { enumerable: true, get: function () { return validation_1.validateDesignInput; } });
37
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,mCAAkC;AAAzB,gGAAA,MAAM,OAAA;AACf,qCAA+E;AAAtE,2GAAA,gBAAgB,OAAA;AAAE,yGAAA,cAAc,OAAA;AAAE,2GAAA,gBAAgB,OAAA;AAC3D,qCAA0C;AAAjC,wGAAA,aAAa,OAAA;AACtB,mCAAmF;AAA1E,uGAAA,aAAa,OAAA;AAAE,iHAAA,uBAAuB,OAAA;AAAE,yGAAA,eAAe,OAAA;AAChE,6BAAiC;AAAxB,+FAAA,QAAQ,OAAA;AACjB,uCAA4C;AAAnC,0GAAA,cAAc,OAAA;AACvB,qCAAgF;AAAvE,4GAAA,iBAAiB,OAAA;AAAE,oGAAA,SAAS,OAAA;AAAE,+FAAA,IAAI,OAAA;AAAE,kGAAA,OAAO,OAAA;AAAE,iGAAA,MAAM,OAAA;AAC5D,mCAAwC;AAA/B,sGAAA,YAAY,OAAA;AACrB,iDAA4D;AAAnD,kHAAA,qBAAqB,OAAA;AAC9B,2CAAuD;AAA9C,6GAAA,mBAAmB,OAAA;AAC5B,2CAKsB;AAJpB,sHAAA,wBAAwB,OAAA;AACxB,0GAAA,YAAY,OAAA;AACZ,4GAAA,cAAc,OAAA;AACd,iHAAA,mBAAmB,OAAA"}
@@ -0,0 +1,12 @@
1
+ import type { CustomProductInput, Product, ProductServiceContract, StorageAdapter } from './types';
2
+ export declare class ProductService implements ProductServiceContract {
3
+ private readonly custom;
4
+ constructor(storage: StorageAdapter);
5
+ list(): Promise<Product[]>;
6
+ get(id: string): Promise<Product>;
7
+ addCustom(input: CustomProductInput): Promise<Product>;
8
+ removeCustom(id: string): Promise<{
9
+ ok: true;
10
+ }>;
11
+ }
12
+ //# sourceMappingURL=products.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"products.d.ts","sourceRoot":"","sources":["../src/products.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,OAAO,EAAE,sBAAsB,EAAE,cAAc,EAAqB,MAAM,SAAS,CAAC;AAItH,qBAAa,cAAe,YAAW,sBAAsB;IAC3D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6B;gBAExC,OAAO,EAAE,cAAc;IAI7B,IAAI,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAK1B,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAMjC,SAAS,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC;IAUtD,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,CAAC;CAKtD"}
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProductService = void 0;
4
+ const catalog_1 = require("./catalog");
5
+ const errors_1 = require("./errors");
6
+ const ids_1 = require("./ids");
7
+ const validation_1 = require("./validation");
8
+ const CUSTOM_COLLECTION = 'custom-products';
9
+ class ProductService {
10
+ custom;
11
+ constructor(storage) {
12
+ this.custom = storage.collection(CUSTOM_COLLECTION);
13
+ }
14
+ async list() {
15
+ const customProducts = await this.custom.all();
16
+ return [...catalog_1.BUILTIN_PRODUCTS, ...customProducts.map(catalog_1.normalizeProduct)];
17
+ }
18
+ async get(id) {
19
+ const product = (await this.list()).find((candidate) => candidate.id === id);
20
+ if (!product)
21
+ throw new errors_1.NotFoundError('Product not found');
22
+ return product;
23
+ }
24
+ async addCustom(input) {
25
+ const product = {
26
+ id: `custom-${(0, ids_1.createId)(8)}`,
27
+ ...(0, validation_1.buildCustomProductFields)(input),
28
+ createdAt: new Date().toISOString(),
29
+ };
30
+ await this.custom.put(product);
31
+ return product;
32
+ }
33
+ async removeCustom(id) {
34
+ const removed = await this.custom.remove(id);
35
+ if (!removed)
36
+ throw new errors_1.NotFoundError('Custom product not found');
37
+ return { ok: true };
38
+ }
39
+ }
40
+ exports.ProductService = ProductService;
41
+ //# sourceMappingURL=products.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"products.js","sourceRoot":"","sources":["../src/products.ts"],"names":[],"mappings":";;;AAAA,uCAA+D;AAC/D,qCAAyC;AACzC,+BAAiC;AACjC,6CAAwD;AAGxD,MAAM,iBAAiB,GAAG,iBAAiB,CAAC;AAE5C,MAAa,cAAc;IACR,MAAM,CAA6B;IAEpD,YAAY,OAAuB;QACjC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,UAAU,CAAU,iBAAiB,CAAC,CAAC;IAC/D,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QAC/C,OAAO,CAAC,GAAG,0BAAgB,EAAE,GAAG,cAAc,CAAC,GAAG,CAAC,0BAAgB,CAAC,CAAC,CAAC;IACxE,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,EAAU;QAClB,MAAM,OAAO,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAC7E,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,sBAAa,CAAC,mBAAmB,CAAC,CAAC;QAC3D,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,KAAyB;QACvC,MAAM,OAAO,GAAY;YACvB,EAAE,EAAE,UAAU,IAAA,cAAQ,EAAC,CAAC,CAAC,EAAE;YAC3B,GAAG,IAAA,qCAAwB,EAAC,KAAK,CAAC;YAClC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QACF,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC/B,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,EAAU;QAC3B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC7C,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,sBAAa,CAAC,0BAA0B,CAAC,CAAC;QAClE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC;CACF;AAjCD,wCAiCC"}
@@ -0,0 +1,12 @@
1
+ import type { SigningInput, VerifyInput } from './types';
2
+ export declare function sha256Hex(input: string | Buffer | null | undefined): string;
3
+ export declare function buildStringToSign({ method, path, timestamp, body }: Omit<SigningInput, 'secret'>): string;
4
+ export declare function sign({ secret, method, path, timestamp, body }: SigningInput): string;
5
+ export declare function verify({ secret, method, path, timestamp, body, signature, maxSkewSeconds, now, }: VerifyInput): boolean;
6
+ export declare const signing: {
7
+ buildStringToSign: typeof buildStringToSign;
8
+ sign: typeof sign;
9
+ verify: typeof verify;
10
+ sha256Hex: typeof sha256Hex;
11
+ };
12
+ //# sourceMappingURL=signing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signing.d.ts","sourceRoot":"","sources":["../src/signing.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEzD,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAE3E;AASD,wBAAgB,iBAAiB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,GAAG,MAAM,CAOzG;AAED,wBAAgB,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,YAAY,GAAG,MAAM,CAGpF;AAED,wBAAgB,MAAM,CAAC,EACrB,MAAM,EACN,MAAM,EACN,IAAI,EACJ,SAAS,EACT,IAAI,EACJ,SAAS,EACT,cAAoB,EACpB,GAAG,GACJ,EAAE,WAAW,GAAG,OAAO,CAoBvB;AAED,eAAO,MAAM,OAAO;;;;;CAAiD,CAAC"}
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.signing = void 0;
4
+ exports.sha256Hex = sha256Hex;
5
+ exports.buildStringToSign = buildStringToSign;
6
+ exports.sign = sign;
7
+ exports.verify = verify;
8
+ const crypto = require("crypto");
9
+ function sha256Hex(input) {
10
+ return crypto.createHash('sha256').update(input ?? '').digest('hex');
11
+ }
12
+ function normalizeBody(body) {
13
+ if (body == null)
14
+ return '';
15
+ if (typeof body === 'string')
16
+ return body;
17
+ if (Buffer.isBuffer(body))
18
+ return body;
19
+ return JSON.stringify(body);
20
+ }
21
+ function buildStringToSign({ method, path, timestamp, body }) {
22
+ return [
23
+ String(method).toUpperCase(),
24
+ path,
25
+ String(timestamp),
26
+ sha256Hex(normalizeBody(body)),
27
+ ].join('\n');
28
+ }
29
+ function sign({ secret, method, path, timestamp, body }) {
30
+ const stringToSign = buildStringToSign({ method, path, timestamp, body });
31
+ return crypto.createHmac('sha256', secret).update(stringToSign).digest('hex');
32
+ }
33
+ function verify({ secret, method, path, timestamp, body, signature, maxSkewSeconds = 300, now, }) {
34
+ const ts = Number(timestamp);
35
+ if (!Number.isFinite(ts))
36
+ return false;
37
+ const current = Number.isFinite(now) ? Number(now) : Math.floor(Date.now() / 1000);
38
+ if (Math.abs(current - ts) > maxSkewSeconds)
39
+ return false;
40
+ const expected = sign({ secret, method, path, timestamp, body });
41
+ let expectedBuffer;
42
+ let actualBuffer;
43
+ try {
44
+ expectedBuffer = Buffer.from(expected, 'hex');
45
+ actualBuffer = Buffer.from(String(signature || ''), 'hex');
46
+ }
47
+ catch {
48
+ return false;
49
+ }
50
+ if (expectedBuffer.length !== actualBuffer.length || expectedBuffer.length === 0)
51
+ return false;
52
+ return crypto.timingSafeEqual(expectedBuffer, actualBuffer);
53
+ }
54
+ exports.signing = { buildStringToSign, sign, verify, sha256Hex };
55
+ //# sourceMappingURL=signing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signing.js","sourceRoot":"","sources":["../src/signing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { StorageAdapter } from '../types';
2
+ export interface JsonFileStorageOptions {
3
+ dir: string;
4
+ }
5
+ export declare function createJsonFileStorage(options: JsonFileStorageOptions): StorageAdapter;
6
+ //# sourceMappingURL=json-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-file.d.ts","sourceRoot":"","sources":["../../src/storage/json-file.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAqC,MAAM,UAAU,CAAC;AAElF,MAAM,WAAW,sBAAsB;IACrC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,GAAG,cAAc,CAsDrF"}
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createJsonFileStorage = createJsonFileStorage;
4
+ const fs = require("fs");
5
+ const path = require("path");
6
+ function createJsonFileStorage(options) {
7
+ if (!options?.dir)
8
+ throw new Error('createJsonFileStorage requires a { dir } option');
9
+ fs.mkdirSync(options.dir, { recursive: true });
10
+ function fileFor(name) {
11
+ return path.join(options.dir, `${name}.json`);
12
+ }
13
+ function read(name) {
14
+ try {
15
+ const file = fileFor(name);
16
+ if (!fs.existsSync(file))
17
+ return [];
18
+ const raw = fs.readFileSync(file, 'utf8');
19
+ return raw.trim() ? JSON.parse(raw) : [];
20
+ }
21
+ catch (error) {
22
+ const message = error instanceof Error ? error.message : String(error);
23
+ console.error(`[igp-personalization] failed to read ${name}:`, message);
24
+ return [];
25
+ }
26
+ }
27
+ function write(name, list) {
28
+ fs.writeFileSync(fileFor(name), JSON.stringify(list, null, 2), 'utf8');
29
+ }
30
+ function collection(name) {
31
+ return {
32
+ async all() {
33
+ return read(name);
34
+ },
35
+ async get(id) {
36
+ return read(name).find((doc) => doc.id === id) ?? null;
37
+ },
38
+ async put(doc) {
39
+ const list = read(name);
40
+ const index = list.findIndex((existing) => existing.id === doc.id);
41
+ if (index >= 0)
42
+ list[index] = doc;
43
+ else
44
+ list.push(doc);
45
+ write(name, list);
46
+ },
47
+ async remove(id) {
48
+ const list = read(name);
49
+ const next = list.filter((doc) => doc.id !== id);
50
+ if (next.length === list.length)
51
+ return false;
52
+ write(name, next);
53
+ return true;
54
+ },
55
+ async count() {
56
+ return read(name).length;
57
+ },
58
+ };
59
+ }
60
+ return { collection };
61
+ }
62
+ //# sourceMappingURL=json-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-file.js","sourceRoot":"","sources":["../../src/storage/json-file.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { StorageAdapter } from '../types';
2
+ export declare function createMemoryStorage(): StorageAdapter;
3
+ //# sourceMappingURL=memory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/storage/memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAqC,MAAM,UAAU,CAAC;AAElF,wBAAgB,mBAAmB,IAAI,cAAc,CAkCpD"}
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createMemoryStorage = createMemoryStorage;
4
+ function createMemoryStorage() {
5
+ const buckets = new Map();
6
+ function bucket(name) {
7
+ let existing = buckets.get(name);
8
+ if (!existing) {
9
+ existing = new Map();
10
+ buckets.set(name, existing);
11
+ }
12
+ return existing;
13
+ }
14
+ function collection(name) {
15
+ const docs = bucket(name);
16
+ return {
17
+ async all() {
18
+ return [...docs.values()];
19
+ },
20
+ async get(id) {
21
+ return docs.get(id) ?? null;
22
+ },
23
+ async put(doc) {
24
+ docs.set(doc.id, doc);
25
+ },
26
+ async remove(id) {
27
+ return docs.delete(id);
28
+ },
29
+ async count() {
30
+ return docs.size;
31
+ },
32
+ };
33
+ }
34
+ return { collection };
35
+ }
36
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/storage/memory.ts"],"names":[],"mappings":";;AAEA,kDAkCC;AAlCD,SAAgB,mBAAmB;IACjC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAuC,CAAC;IAE/D,SAAS,MAAM,CAAC,IAAY;QAC1B,IAAI,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,QAAQ,GAAG,IAAI,GAAG,EAA0B,CAAC;YAC7C,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC9B,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,SAAS,UAAU,CAA+C,IAAY;QAC5E,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAC1B,OAAO;YACL,KAAK,CAAC,GAAG;gBACP,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAW,CAAC;YACtC,CAAC;YACD,KAAK,CAAC,GAAG,CAAC,EAAU;gBAClB,OAAQ,IAAI,CAAC,GAAG,CAAC,EAAE,CAAsB,IAAI,IAAI,CAAC;YACpD,CAAC;YACD,KAAK,CAAC,GAAG,CAAC,GAAS;gBACjB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;YACxB,CAAC;YACD,KAAK,CAAC,MAAM,CAAC,EAAU;gBACrB,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACzB,CAAC;YACD,KAAK,CAAC,KAAK;gBACT,OAAO,IAAI,CAAC,IAAI,CAAC;YACnB,CAAC;SACF,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,CAAC;AACxB,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { StorageAdapter, Studio } from './types';
2
+ export interface CreateStudioOptions {
3
+ storage: StorageAdapter;
4
+ }
5
+ export declare function createStudio(options: CreateStudioOptions): Studio;
6
+ //# sourceMappingURL=studio.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"studio.d.ts","sourceRoot":"","sources":["../src/studio.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtD,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,cAAc,CAAC;CACzB;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAUjE"}
package/dist/studio.js ADDED
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createStudio = createStudio;
4
+ const designs_1 = require("./designs");
5
+ const products_1 = require("./products");
6
+ function createStudio(options) {
7
+ if (!options?.storage || typeof options.storage.collection !== 'function') {
8
+ throw new Error('createStudio requires a storage adapter with a collection(name) method');
9
+ }
10
+ return {
11
+ storage: options.storage,
12
+ products: new products_1.ProductService(options.storage),
13
+ designs: new designs_1.DesignService(options.storage),
14
+ };
15
+ }
16
+ //# sourceMappingURL=studio.js.map