@no-mess/client 0.1.1 → 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 (65) hide show
  1. package/README.md +153 -4
  2. package/dist/client.d.ts +5 -1
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +237 -41
  5. package/dist/client.js.map +1 -1
  6. package/dist/error-utils.d.ts +20 -0
  7. package/dist/error-utils.d.ts.map +1 -0
  8. package/dist/error-utils.js +67 -0
  9. package/dist/error-utils.js.map +1 -0
  10. package/dist/index.d.ts +1 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +148 -22
  13. package/dist/index.js.map +1 -1
  14. package/dist/live-edit.d.ts.map +1 -1
  15. package/dist/live-edit.js +241 -102
  16. package/dist/live-edit.js.map +1 -1
  17. package/dist/logging.d.ts +6 -0
  18. package/dist/logging.d.ts.map +1 -0
  19. package/dist/logging.js +58 -0
  20. package/dist/logging.js.map +1 -0
  21. package/dist/react/index.d.ts +1 -1
  22. package/dist/react/index.d.ts.map +1 -1
  23. package/dist/react/index.js.map +1 -1
  24. package/dist/react/no-mess-preview.d.ts +2 -6
  25. package/dist/react/no-mess-preview.d.ts.map +1 -1
  26. package/dist/react/no-mess-preview.js.map +1 -1
  27. package/dist/react/use-no-mess-live-edit.d.ts.map +1 -1
  28. package/dist/react/use-no-mess-live-edit.js +32 -2
  29. package/dist/react/use-no-mess-live-edit.js.map +1 -1
  30. package/dist/react/use-no-mess-preview.d.ts.map +1 -1
  31. package/dist/react/use-no-mess-preview.js +29 -6
  32. package/dist/react/use-no-mess-preview.js.map +1 -1
  33. package/dist/schema/define-content-type.d.ts +13 -0
  34. package/dist/schema/define-content-type.d.ts.map +1 -0
  35. package/dist/schema/define-content-type.js +33 -0
  36. package/dist/schema/define-content-type.js.map +1 -0
  37. package/dist/schema/define-schema.d.ts +9 -0
  38. package/dist/schema/define-schema.d.ts.map +1 -0
  39. package/dist/schema/define-schema.js +9 -0
  40. package/dist/schema/define-schema.js.map +1 -0
  41. package/dist/schema/field-builders.d.ts +33 -0
  42. package/dist/schema/field-builders.d.ts.map +1 -0
  43. package/dist/schema/field-builders.js +25 -0
  44. package/dist/schema/field-builders.js.map +1 -0
  45. package/dist/schema/index.d.ts +12 -0
  46. package/dist/schema/index.d.ts.map +1 -0
  47. package/dist/schema/index.js +7 -0
  48. package/dist/schema/index.js.map +1 -0
  49. package/dist/schema/parse-schema.d.ts +23 -0
  50. package/dist/schema/parse-schema.d.ts.map +1 -0
  51. package/dist/schema/parse-schema.js +419 -0
  52. package/dist/schema/parse-schema.js.map +1 -0
  53. package/dist/schema/schema-types.d.ts +28 -0
  54. package/dist/schema/schema-types.d.ts.map +1 -0
  55. package/dist/schema/schema-types.js +17 -0
  56. package/dist/schema/schema-types.js.map +1 -0
  57. package/dist/schema/serialize-schema.d.ts +11 -0
  58. package/dist/schema/serialize-schema.d.ts.map +1 -0
  59. package/dist/schema/serialize-schema.js +85 -0
  60. package/dist/schema/serialize-schema.js.map +1 -0
  61. package/dist/types.d.ts +49 -2
  62. package/dist/types.d.ts.map +1 -1
  63. package/dist/types.js +22 -4
  64. package/dist/types.js.map +1 -1
  65. package/package.json +8 -3
package/README.md CHANGED
@@ -34,30 +34,179 @@ const post = await client.getEntry("blog-post", "hello-world");
34
34
  import { useNoMessPreview } from "@no-mess/client/react";
35
35
 
36
36
  function PreviewPage() {
37
- const { entry, isLoading, error } = useNoMessPreview({
37
+ const { entry, isLoading, error, status } = useNoMessPreview({
38
38
  apiKey: "your-api-key",
39
+ logger: (event) => {
40
+ // Forward structured diagnostics to your own telemetry pipeline.
41
+ console.debug(event.code, event.context);
42
+ },
39
43
  });
40
44
 
41
45
  if (isLoading) return <p>Loading preview...</p>;
42
46
  if (error) return <p>Error: {error.message}</p>;
47
+ if (status !== "ready") return null;
43
48
 
44
- return <h1>{entry?.fields.title}</h1>;
49
+ return <h1>{entry?.title}</h1>;
45
50
  }
46
51
  ```
47
52
 
48
53
  The `useNoMessPreview` hook handles the postMessage handshake between the no-mess admin dashboard and your preview iframe automatically.
49
54
 
55
+ ### Error handling
56
+
57
+ ```ts
58
+ import { NoMessError } from "@no-mess/client";
59
+
60
+ try {
61
+ const post = await client.getEntry("blog-post", "missing");
62
+ } catch (error) {
63
+ if (error instanceof NoMessError) {
64
+ console.error(error.message); // "Entry not found (HTTP 404)"
65
+ console.error(error.code); // "http_error"
66
+ console.error(error.kind); // "http"
67
+ console.error(error.retryable); // false
68
+ console.error(error.requestId); // if provided by the API
69
+ }
70
+ }
71
+ ```
72
+
50
73
  ### Shopify data
51
74
 
52
75
  ```ts
53
76
  const products = await client.getProducts();
54
77
  const product = await client.getProduct("product-handle");
55
78
  const collections = await client.getCollections();
79
+ const collection = await client.getCollection("collection-handle");
80
+ ```
81
+
82
+ ## Configuration
83
+
84
+ ```ts
85
+ const client = createNoMessClient({
86
+ apiKey: "nm_...", // Required — secret or publishable key
87
+ apiUrl: "https://...", // Optional — defaults to https://api.nomess.xyz
88
+ logger: (event) => {}, // Optional — structured diagnostics hook
89
+ });
90
+ ```
91
+
92
+ ### API Key Types
93
+
94
+ - **Secret keys** (`nm_...`) — Full access. Use server-side only.
95
+ - **Publishable keys** (`nm_pub_...`) — Read-only access to published content. Safe for client-side use.
96
+
97
+ ## API Reference
98
+
99
+ ### Content
100
+
101
+ | Method | Description |
102
+ |--------|-------------|
103
+ | `client.getSchemas()` | List all content type schemas |
104
+ | `client.getSchema(typeSlug)` | Get a single schema by slug |
105
+ | `client.getEntries(contentType)` | Fetch all published entries of a content type |
106
+ | `client.getEntry(contentType, slug)` | Get a single entry by slug |
107
+
108
+ ### Shopify
109
+
110
+ | Method | Description |
111
+ |--------|-------------|
112
+ | `client.getProducts()` | List all synced Shopify products |
113
+ | `client.getProduct(handle)` | Get a product by handle |
114
+ | `client.getCollections()` | List all synced Shopify collections |
115
+ | `client.getCollection(handle)` | Get a collection by handle |
116
+
117
+ ### Preview
118
+
119
+ | Method | Description |
120
+ |--------|-------------|
121
+ | `client.exchangePreviewSession(session)` | Exchange a preview session token (HMAC-SHA256 auth) |
122
+
123
+ ### React Hooks (`@no-mess/client/react`)
124
+
125
+ | Hook | Description |
126
+ |------|-------------|
127
+ | `useNoMessPreview(config)` | Subscribe to live preview updates in an iframe |
128
+ | `useNoMessLiveEdit(config)` | Enable live editing with field-level updates |
129
+
130
+ ## Schema Builder
131
+
132
+ The `@no-mess/client/schema` export provides helpers for defining content type schemas in code. Used by the [no-mess CLI](../no-mess-cli) to push and pull schemas.
133
+
134
+ ```ts
135
+ import { defineSchema, defineContentType, field } from "@no-mess/client/schema";
136
+
137
+ export default defineSchema({
138
+ contentTypes: [
139
+ defineContentType("blog-post", {
140
+ name: "Blog Post",
141
+ description: "Articles for the blog",
142
+ fields: {
143
+ title: field.text({ required: true }),
144
+ body: field.textarea({ required: true }),
145
+ heroImage: field.image(),
146
+ publishedAt: field.datetime(),
147
+ featured: field.boolean(),
148
+ externalUrl: field.url(),
149
+ category: field.select({
150
+ choices: [
151
+ { label: "Tech", value: "tech" },
152
+ { label: "Design", value: "design" },
153
+ ],
154
+ }),
155
+ relatedProduct: field.shopifyProduct(),
156
+ featuredCollection: field.shopifyCollection(),
157
+ },
158
+ }),
159
+ ],
160
+ });
161
+ ```
162
+
163
+ ### Field Types
164
+
165
+ | Builder | Type | Description |
166
+ |---------|------|-------------|
167
+ | `field.text()` | `text` | Plain text input |
168
+ | `field.textarea()` | `textarea` | Multi-line text |
169
+ | `field.number()` | `number` | Numeric value |
170
+ | `field.boolean()` | `boolean` | True/false toggle |
171
+ | `field.datetime()` | `datetime` | Date/time picker |
172
+ | `field.url()` | `url` | URL field |
173
+ | `field.image()` | `image` | Image upload |
174
+ | `field.select(opts)` | `select` | Dropdown with choices (requires `choices` array) |
175
+ | `field.shopifyProduct()` | `shopifyProduct` | Shopify product reference |
176
+ | `field.shopifyCollection()` | `shopifyCollection` | Shopify collection reference |
177
+
178
+ ### Field Options
179
+
180
+ All field builders accept an options object:
181
+
182
+ ```ts
183
+ field.text({
184
+ required: true, // Whether the field is required (default: false)
185
+ description: "...", // Help text shown in the dashboard
186
+ })
187
+ ```
188
+
189
+ The `select` builder additionally requires a `choices` array:
190
+
191
+ ```ts
192
+ field.select({
193
+ required: true,
194
+ choices: [
195
+ { label: "Draft", value: "draft" },
196
+ { label: "Published", value: "published" },
197
+ ],
198
+ })
56
199
  ```
57
200
 
58
- ## API reference
201
+ ### Schema Utilities
59
202
 
60
- Full documentation at [no-mess.xyz/docs/sdk](https://no-mess.xyz/docs/sdk).
203
+ | Function | Description |
204
+ |----------|-------------|
205
+ | `defineSchema({ contentTypes })` | Define a complete schema with content types |
206
+ | `defineContentType(slug, options)` | Define a single content type |
207
+ | `parseSchemaSource(source)` | Parse a schema.ts source string into a schema definition |
208
+ | `generateSchemaSource(schema)` | Generate schema.ts source from a schema definition |
209
+ | `generateContentTypeSource(contentType)` | Generate source for a single content type |
61
210
 
62
211
  ## License
63
212
 
package/dist/client.d.ts CHANGED
@@ -2,8 +2,11 @@ import type { GetEntryOptions, NoMessClientConfig, NoMessEntry, PreviewExchangeR
2
2
  export declare class NoMessClient {
3
3
  private apiUrl;
4
4
  private apiKey;
5
+ private logger;
5
6
  constructor(config: NoMessClientConfig);
6
- private fetch;
7
+ private emitErrorLog;
8
+ private readResponseText;
9
+ private request;
7
10
  /**
8
11
  * List all content type schemas with fields, TypeScript interfaces, and entry counts.
9
12
  */
@@ -47,5 +50,6 @@ export declare class NoMessClient {
47
50
  * Uses Web Crypto API (works in browsers, Node.js 18+, Deno, Bun, edge runtimes).
48
51
  */
49
52
  private computeProof;
53
+ private toBase64;
50
54
  }
51
55
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,kBAAkB,EAClB,WAAW,EACX,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACf,MAAM,YAAY,CAAC;AAGpB,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,kBAAkB;YAiBxB,KAAK;IA+BnB;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAI/C;;OAEG;IACG,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAI7D;;OAEG;IACG,UAAU,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,EAClD,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,CAAC,EAAE,CAAC;IAIf;;;OAGG;IACG,QAAQ,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,EAChD,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,CAAC,CAAC;IAWb;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IAI9C;;OAEG;IACG,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAIzD;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAIpD;;OAEG;IACG,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAI/D;;;OAGG;IACG,sBAAsB,CAC1B,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,qBAAqB,CAAC;IAkCjC;;;OAGG;YACW,YAAY;CA0B3B"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,eAAe,EACf,kBAAkB,EAClB,WAAW,EAGX,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACf,MAAM,YAAY,CAAC;AAWpB,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAqC;gBAEvC,MAAM,EAAE,kBAAkB;IAyBtC,OAAO,CAAC,YAAY;YAyBN,gBAAgB;YA6BhB,OAAO;IA4FrB;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAQ/C;;OAEG;IACG,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAQ7D;;OAEG;IACG,UAAU,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,EAClD,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,CAAC,EAAE,CAAC;IAQf;;;OAGG;IACG,QAAQ,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,EAChD,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,CAAC,CAAC;IAiBb;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IAQ9C;;OAEG;IACG,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAQzD;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAQpD;;OAEG;IACG,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAQ/D;;;OAGG;IACG,sBAAsB,CAC1B,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,qBAAqB,CAAC;IAoBjC;;;OAGG;YACW,YAAY;IA8E1B,OAAO,CAAC,QAAQ;CAmBjB"}
package/dist/client.js CHANGED
@@ -1,54 +1,172 @@
1
- import { DEFAULT_API_URL, NoMessError } from "./types.js";
1
+ import { createNoMessCryptoError, createNoMessHttpError, createNoMessResponseError, extractRequestId, normalizeNoMessError, safeParseJsonText, } from "./error-utils.js";
2
+ import { createSdkLogger, warnOnce } from "./logging.js";
3
+ import { DEFAULT_API_URL } from "./types.js";
2
4
  export class NoMessClient {
3
5
  constructor(config) {
4
6
  this.apiUrl = (config.apiUrl ?? DEFAULT_API_URL).replace(/\/$/, "");
5
7
  this.apiKey = config.apiKey;
8
+ this.logger = createSdkLogger(config.logger);
6
9
  if (typeof window !== "undefined" &&
7
10
  config.apiKey.startsWith("nm_") &&
8
11
  !config.apiKey.startsWith("nm_pub_")) {
9
- console.warn("[no-mess] You are using a secret API key (nm_) in a browser environment. " +
10
- "This exposes your secret key to end users. " +
11
- "Use a publishable key (nm_pub_) for client-side code instead.");
12
+ warnOnce(this.logger, "secret-key-in-browser", {
13
+ level: "warn",
14
+ code: "secret_key_in_browser",
15
+ message: "You are using a secret API key (nm_) in a browser environment. This exposes your secret key to end users. Use a publishable key (nm_pub_) for client-side code instead.",
16
+ scope: "client",
17
+ operation: "constructor",
18
+ timestamp: new Date().toISOString(),
19
+ context: {
20
+ apiUrl: this.apiUrl,
21
+ },
22
+ });
12
23
  }
13
24
  }
14
- async fetch(path, params) {
25
+ emitErrorLog(error, scope, operation, level = "error", extraContext) {
26
+ this.logger({
27
+ level,
28
+ code: error.code,
29
+ message: error.message,
30
+ scope,
31
+ operation,
32
+ error,
33
+ timestamp: new Date().toISOString(),
34
+ context: {
35
+ status: error.status,
36
+ retryable: error.retryable,
37
+ requestId: error.requestId,
38
+ ...error.details,
39
+ ...extraContext,
40
+ },
41
+ });
42
+ }
43
+ async readResponseText(response, operation, method, url) {
44
+ try {
45
+ if (typeof response.text === "function") {
46
+ return await response.text();
47
+ }
48
+ if (typeof response.json === "function") {
49
+ return JSON.stringify(await response.json());
50
+ }
51
+ }
52
+ catch (error) {
53
+ throw createNoMessResponseError("Failed to read response body", {
54
+ kind: "response",
55
+ code: "invalid_success_response",
56
+ operation,
57
+ method,
58
+ url,
59
+ requestId: extractRequestId(response),
60
+ cause: error,
61
+ });
62
+ }
63
+ return "";
64
+ }
65
+ async request({ method, path, params, body, operation, }) {
15
66
  const url = new URL(`${this.apiUrl}${path}`);
16
67
  if (params) {
17
68
  for (const [key, value] of Object.entries(params)) {
18
69
  url.searchParams.set(key, value);
19
70
  }
20
71
  }
21
- const response = await fetch(url.toString(), {
72
+ const requestUrl = url.toString();
73
+ const init = {
74
+ method,
22
75
  headers: {
23
76
  Authorization: `Bearer ${this.apiKey}`,
24
77
  "Content-Type": "application/json",
25
78
  },
26
- });
79
+ };
80
+ if (typeof body !== "undefined") {
81
+ init.body = JSON.stringify(body);
82
+ }
83
+ let response;
84
+ try {
85
+ response = await fetch(requestUrl, init);
86
+ }
87
+ catch (error) {
88
+ const normalized = normalizeNoMessError(error, {
89
+ kind: "network",
90
+ code: "request_failed",
91
+ operation,
92
+ method,
93
+ url: requestUrl,
94
+ retryable: true,
95
+ });
96
+ this.emitErrorLog(normalized, "client", operation);
97
+ throw normalized;
98
+ }
99
+ const requestId = extractRequestId(response);
100
+ const text = await this.readResponseText(response, operation, method, requestUrl);
27
101
  if (!response.ok) {
28
- const body = await response
29
- .json()
30
- .catch(() => ({ error: "Unknown error" }));
31
- throw new NoMessError(body.error ?? `HTTP ${response.status}`, response.status);
102
+ const parsed = text.trim() ? safeParseJsonText(text) : null;
103
+ const parsedBody = parsed && parsed.ok && parsed.value && typeof parsed.value === "object"
104
+ ? parsed.value
105
+ : null;
106
+ const message = typeof parsedBody?.error === "string" && parsedBody.error.trim()
107
+ ? parsedBody.error
108
+ : text.trim() || `HTTP ${response.status}`;
109
+ const error = createNoMessHttpError(message, {
110
+ kind: "http",
111
+ code: "http_error",
112
+ status: response.status,
113
+ operation,
114
+ method,
115
+ url: requestUrl,
116
+ requestId,
117
+ retryable: response.status >= 500,
118
+ });
119
+ this.emitErrorLog(error, "client", operation);
120
+ throw error;
32
121
  }
33
- return response.json();
122
+ const parsed = safeParseJsonText(text);
123
+ if (!parsed.ok) {
124
+ const error = createNoMessResponseError("Received invalid JSON response", {
125
+ kind: "response",
126
+ code: "invalid_success_response",
127
+ operation,
128
+ method,
129
+ url: requestUrl,
130
+ requestId,
131
+ details: {
132
+ responseText: text.slice(0, 200),
133
+ },
134
+ cause: parsed.error,
135
+ });
136
+ this.emitErrorLog(error, "client", operation);
137
+ throw error;
138
+ }
139
+ return parsed.value;
34
140
  }
35
141
  /**
36
142
  * List all content type schemas with fields, TypeScript interfaces, and entry counts.
37
143
  */
38
144
  async getSchemas() {
39
- return this.fetch("/api/schema");
145
+ return this.request({
146
+ method: "GET",
147
+ path: "/api/schema",
148
+ operation: "getSchemas",
149
+ });
40
150
  }
41
151
  /**
42
152
  * Get a single content type schema by slug.
43
153
  */
44
154
  async getSchema(typeSlug) {
45
- return this.fetch(`/api/schema/${typeSlug}`);
155
+ return this.request({
156
+ method: "GET",
157
+ path: `/api/schema/${typeSlug}`,
158
+ operation: "getSchema",
159
+ });
46
160
  }
47
161
  /**
48
162
  * Get all published entries of a content type.
49
163
  */
50
164
  async getEntries(contentType) {
51
- return this.fetch(`/api/content/${contentType}`);
165
+ return this.request({
166
+ method: "GET",
167
+ path: `/api/content/${contentType}`,
168
+ operation: "getEntries",
169
+ });
52
170
  }
53
171
  /**
54
172
  * Get a single entry by content type and slug.
@@ -62,31 +180,52 @@ export class NoMessClient {
62
180
  params.secret = options.previewSecret;
63
181
  }
64
182
  }
65
- return this.fetch(`/api/content/${contentType}/${slug}`, params);
183
+ return this.request({
184
+ method: "GET",
185
+ path: `/api/content/${contentType}/${slug}`,
186
+ params,
187
+ operation: "getEntry",
188
+ });
66
189
  }
67
190
  /**
68
191
  * Get all synced Shopify products.
69
192
  */
70
193
  async getProducts() {
71
- return this.fetch("/api/shopify/products");
194
+ return this.request({
195
+ method: "GET",
196
+ path: "/api/shopify/products",
197
+ operation: "getProducts",
198
+ });
72
199
  }
73
200
  /**
74
201
  * Get a single Shopify product by handle.
75
202
  */
76
203
  async getProduct(handle) {
77
- return this.fetch(`/api/shopify/products/${handle}`);
204
+ return this.request({
205
+ method: "GET",
206
+ path: `/api/shopify/products/${handle}`,
207
+ operation: "getProduct",
208
+ });
78
209
  }
79
210
  /**
80
211
  * Get all synced Shopify collections.
81
212
  */
82
213
  async getCollections() {
83
- return this.fetch("/api/shopify/collections");
214
+ return this.request({
215
+ method: "GET",
216
+ path: "/api/shopify/collections",
217
+ operation: "getCollections",
218
+ });
84
219
  }
85
220
  /**
86
221
  * Get a single Shopify collection by handle.
87
222
  */
88
223
  async getCollection(handle) {
89
- return this.fetch(`/api/shopify/collections/${handle}`);
224
+ return this.request({
225
+ method: "GET",
226
+ path: `/api/shopify/collections/${handle}`,
227
+ operation: "getCollection",
228
+ });
90
229
  }
91
230
  /**
92
231
  * Exchange a preview session for draft content.
@@ -95,40 +234,97 @@ export class NoMessClient {
95
234
  async exchangePreviewSession(session) {
96
235
  const timestamp = Math.floor(Date.now() / 1000).toString();
97
236
  const proof = await this.computeProof(session.sessionSecret, session.sessionId, timestamp);
98
- const response = await fetch(`${this.apiUrl}/api/preview/exchange`, {
237
+ return this.request({
99
238
  method: "POST",
100
- headers: {
101
- Authorization: `Bearer ${this.apiKey}`,
102
- "Content-Type": "application/json",
103
- },
104
- body: JSON.stringify({
239
+ path: "/api/preview/exchange",
240
+ operation: "exchangePreviewSession",
241
+ body: {
105
242
  sessionId: session.sessionId,
106
243
  timestamp,
107
244
  proof,
108
- }),
245
+ },
109
246
  });
110
- if (!response.ok) {
111
- const body = await response
112
- .json()
113
- .catch(() => ({ error: "Unknown error" }));
114
- throw new NoMessError(body.error ?? `HTTP ${response.status}`, response.status);
115
- }
116
- return response.json();
117
247
  }
118
248
  /**
119
249
  * Compute HMAC-SHA256 proof for preview session authentication.
120
250
  * Uses Web Crypto API (works in browsers, Node.js 18+, Deno, Bun, edge runtimes).
121
251
  */
122
252
  async computeProof(sessionSecret, sessionId, timestamp) {
253
+ if (!sessionSecret || sessionSecret.length % 2 !== 0 || !/^[0-9a-fA-F]+$/.test(sessionSecret)) {
254
+ const error = createNoMessCryptoError("Preview session secret must be a valid hex string", {
255
+ kind: "crypto",
256
+ code: "invalid_session_secret",
257
+ operation: "computeProof",
258
+ details: {
259
+ sessionId,
260
+ },
261
+ });
262
+ this.emitErrorLog(error, "client", "computeProof");
263
+ throw error;
264
+ }
265
+ if (typeof crypto === "undefined" || !crypto.subtle) {
266
+ const error = createNoMessCryptoError("Web Crypto API is not available in this runtime", {
267
+ kind: "crypto",
268
+ code: "crypto_unavailable",
269
+ operation: "computeProof",
270
+ details: {
271
+ sessionId,
272
+ },
273
+ });
274
+ this.emitErrorLog(error, "client", "computeProof");
275
+ throw error;
276
+ }
123
277
  const secretBytes = new Uint8Array((sessionSecret.match(/.{2}/g) ?? []).map((byte) => parseInt(byte, 16)));
124
- const buf = new ArrayBuffer(secretBytes.byteLength);
125
- new Uint8Array(buf).set(secretBytes);
126
- const key = await crypto.subtle.importKey("raw", buf, { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
278
+ let key;
279
+ try {
280
+ key = await crypto.subtle.importKey("raw", secretBytes, { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
281
+ }
282
+ catch (error) {
283
+ const normalized = createNoMessCryptoError("Failed to initialize preview proof signing key", {
284
+ kind: "crypto",
285
+ code: "invalid_session_secret",
286
+ operation: "computeProof",
287
+ details: {
288
+ sessionId,
289
+ },
290
+ cause: error,
291
+ });
292
+ this.emitErrorLog(normalized, "client", "computeProof");
293
+ throw normalized;
294
+ }
127
295
  const message = new TextEncoder().encode(`${sessionId}.${timestamp}`);
128
- const msgBuf = new ArrayBuffer(message.byteLength);
129
- new Uint8Array(msgBuf).set(message);
130
- const signature = await crypto.subtle.sign("HMAC", key, msgBuf);
131
- return btoa(String.fromCharCode(...new Uint8Array(signature)));
296
+ try {
297
+ const signature = await crypto.subtle.sign("HMAC", key, message);
298
+ return this.toBase64(new Uint8Array(signature));
299
+ }
300
+ catch (error) {
301
+ const normalized = createNoMessCryptoError("Failed to sign preview proof", {
302
+ kind: "crypto",
303
+ code: "crypto_unavailable",
304
+ operation: "computeProof",
305
+ details: {
306
+ sessionId,
307
+ },
308
+ cause: error,
309
+ });
310
+ this.emitErrorLog(normalized, "client", "computeProof");
311
+ throw normalized;
312
+ }
313
+ }
314
+ toBase64(bytes) {
315
+ const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
316
+ let output = "";
317
+ for (let index = 0; index < bytes.length; index += 3) {
318
+ const a = bytes[index] ?? 0;
319
+ const b = bytes[index + 1] ?? 0;
320
+ const c = bytes[index + 2] ?? 0;
321
+ const chunk = (a << 16) | (b << 8) | c;
322
+ output += alphabet[(chunk >> 18) & 0x3f];
323
+ output += alphabet[(chunk >> 12) & 0x3f];
324
+ output += index + 1 < bytes.length ? alphabet[(chunk >> 6) & 0x3f] : "=";
325
+ output += index + 2 < bytes.length ? alphabet[chunk & 0x3f] : "=";
326
+ }
327
+ return output;
132
328
  }
133
329
  }
134
330
  //# sourceMappingURL=client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { NoMessError, type NoMessErrorCode, type NoMessErrorKind, type NoMessErrorOptions } from "./types.js";
2
+ interface ErrorMetadata extends NoMessErrorOptions {
3
+ kind: NoMessErrorKind;
4
+ code: NoMessErrorCode;
5
+ }
6
+ export declare function safeParseJsonText(text: string): {
7
+ ok: true;
8
+ value: unknown;
9
+ } | {
10
+ ok: false;
11
+ error: Error;
12
+ };
13
+ export declare function extractRequestId(response: Response): string | undefined;
14
+ export declare function normalizeNoMessError(input: unknown, metadata: ErrorMetadata): NoMessError;
15
+ export declare function createNoMessHttpError(message: string, metadata: ErrorMetadata): NoMessError;
16
+ export declare function createNoMessResponseError(message: string, metadata: ErrorMetadata): NoMessError;
17
+ export declare function createNoMessProtocolError(message: string, metadata: ErrorMetadata): NoMessError;
18
+ export declare function createNoMessCryptoError(message: string, metadata: ErrorMetadata): NoMessError;
19
+ export {};
20
+ //# sourceMappingURL=error-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-utils.d.ts","sourceRoot":"","sources":["../src/error-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACxB,MAAM,YAAY,CAAC;AAEpB,UAAU,aAAc,SAAQ,kBAAkB;IAChD,IAAI,EAAE,eAAe,CAAC;IACtB,IAAI,EAAE,eAAe,CAAC;CACvB;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAC1C;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAC5B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CAS9B;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,GAAG,SAAS,CAWvE;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,aAAa,GACtB,WAAW,CAuBb;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,aAAa,GACtB,WAAW,CAMb;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,aAAa,GACtB,WAAW,CAKb;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,aAAa,GACtB,WAAW,CAKb;AAED,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,aAAa,GACtB,WAAW,CAKb"}