hookwright 1.2.0 → 1.2.1

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 (3) hide show
  1. package/README.md +2 -2
  2. package/dist/cli.js +14 -9
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -94,7 +94,7 @@ A generated payload is useless if the receiver silently drops it, so every build
94
94
  - **JSON round-trip** — receivers that verify `HMAC(secret, timestamp + JSON.stringify(parsedBody))` can only match if `JSON.stringify(JSON.parse(raw)) === raw`. If it doesn't, you're told the exact byte offset.
95
95
  - **Phone** — parsed to E.164 using the shipping `country_code`, the same way the consumer does.
96
96
  - **Phone allow-list** — refuses to build for a number that isn't an approved test handset, so a live shopper can never be messaged by a test run.
97
- - **Product images** — every `image_url` is `HEAD`-checked; unreachable images fail the build.
97
+ - **Product images** — every `image_url` is `HEAD`-checked. A product with no image warns rather than blocking: the message simply renders without one.
98
98
  - **Endpoint exists** — before a signed payload is handed over, the destination is verified: the hostname must resolve, something must accept a TCP connection on the port, and the path must not 404. A typo'd host is caught here instead of looking like a silent delivery failure. The probe is `OPTIONS`, falling back to `HEAD` — **never a POST and never a body**, so it cannot create data on the receiving system. Timeouts and servers that reject `OPTIONS` warn rather than block. Skip with `--no-endpoint-check`, override with `--force`.
99
99
  - **Field coverage** — a table of every field the consumer reads, what it maps to, and its value. Missing required fields are flagged in red.
100
100
 
@@ -142,7 +142,7 @@ Adding one is a single file in `src/providers/` exporting `buildPayload`, `sign`
142
142
  ```bash
143
143
  npm install
144
144
  npm run dev # esbuild watch
145
- npm test # 185 tests, no network required
145
+ npm test # 187 tests, no network required
146
146
  npm start # build + run
147
147
  ```
148
148
 
package/dist/cli.js CHANGED
@@ -24,7 +24,7 @@ var init_package = __esm({
24
24
  "package.json"() {
25
25
  package_default = {
26
26
  name: "hookwright",
27
- version: "1.2.0",
27
+ version: "1.2.1",
28
28
  description: "Build real, signed e-commerce webhooks from a live Shopify catalogue \u2014 interactive terminal UI, no backend",
29
29
  keywords: [
30
30
  "webhook",
@@ -449,7 +449,7 @@ var fieldMap = [
449
449
  { source: "data.customer.shipping_address.zip", target: "customer.zip" },
450
450
  { source: "data.line_items[0].name", target: "cart.productName", required: true },
451
451
  { source: "data.line_items[0].currency", target: "pricing.currency", required: true, note: "currency is read off the FIRST line item, not the root" },
452
- { source: "data.line_items[0].image_url", target: "cart.image", required: true, note: "first line item with an image wins" },
452
+ { source: "data.line_items[0].image_url", target: "cart.image", note: "first line item with an image wins; blank if the product has none" },
453
453
  { source: "data.line_items[0].quantity", target: "cart.quantity" },
454
454
  { source: "data.utm_parameters.utm_source", target: "utm.source" },
455
455
  { source: "data.utm_parameters.utm_medium", target: "utm.medium" },
@@ -621,7 +621,7 @@ var fieldMap2 = [
621
621
  { source: "customer.Shipping_address.Country_code", target: "customer.countryCode", required: true, note: "region used to parse the phone" },
622
622
  { source: "customer.Shipping_address.Zip", target: "customer.zip" },
623
623
  { source: "line_items[0].name", target: "cart.productName", required: true },
624
- { source: "line_items[0].image_url", target: "cart.image", required: true },
624
+ { source: "line_items[0].image_url", target: "cart.image", note: "blank if the product has no image" },
625
625
  { source: "line_items[0].quantity", target: "cart.quantity" }
626
626
  ];
627
627
  var editableFields2 = [
@@ -805,7 +805,7 @@ var FIELD_MAPS = {
805
805
  ...COMMON_FIELDS,
806
806
  ...PAGE_FIELDS,
807
807
  { source: "eventVal.title", target: "eventVal.title", required: true },
808
- { source: "eventVal.image", target: "eventVal.image", required: true },
808
+ { source: "eventVal.image", target: "eventVal.image", note: "blank if the product has no image" },
809
809
  { source: "eventVal.price", target: "eventVal.price", required: true },
810
810
  { source: "eventVal.resource_id", target: "eventVal.resource_id", required: true },
811
811
  { source: "eventVal.resource", target: "eventVal.resource" },
@@ -2212,7 +2212,7 @@ function Build({ config, providerId = "cashfree-occ", onDone }) {
2212
2212
  setStep(STEP.COLLECTION);
2213
2213
  }).catch((err) => {
2214
2214
  if (alive) {
2215
- setError({ message: err.message, hint: err.hint });
2215
+ setError({ message: err.message, hint: err.hint, failures: err.failures });
2216
2216
  setStep(STEP.ERROR);
2217
2217
  }
2218
2218
  });
@@ -2231,7 +2231,7 @@ function Build({ config, providerId = "cashfree-occ", onDone }) {
2231
2231
  setStep(STEP.PICK);
2232
2232
  }).catch((err) => {
2233
2233
  if (!alive) return;
2234
- setError({ message: err.message, hint: err.hint });
2234
+ setError({ message: err.message, hint: err.hint, failures: err.failures });
2235
2235
  setStep(STEP.ERROR);
2236
2236
  });
2237
2237
  return () => {
@@ -2310,7 +2310,7 @@ function Build({ config, providerId = "cashfree-occ", onDone }) {
2310
2310
  setDraft({ ...next, discount });
2311
2311
  setStep(STEP.MODE);
2312
2312
  } catch (err) {
2313
- setError({ message: err.message, hint: err.hint });
2313
+ setError({ message: err.message, hint: err.hint, failures: err.failures });
2314
2314
  setStep(STEP.ERROR);
2315
2315
  }
2316
2316
  };
@@ -2334,7 +2334,7 @@ function Build({ config, providerId = "cashfree-occ", onDone }) {
2334
2334
  }
2335
2335
  setStep(STEP.REPORT);
2336
2336
  }).catch((err) => {
2337
- setError({ message: err.message, hint: err.hint });
2337
+ setError({ message: err.message, hint: err.hint, failures: err.failures });
2338
2338
  setStep(STEP.ERROR);
2339
2339
  });
2340
2340
  };
@@ -2360,7 +2360,7 @@ function Build({ config, providerId = "cashfree-occ", onDone }) {
2360
2360
  setSendResult(result);
2361
2361
  setStep(STEP.RESULT);
2362
2362
  }).catch((err) => {
2363
- setError({ message: err.message, hint: err.hint });
2363
+ setError({ message: err.message, hint: err.hint, failures: err.failures });
2364
2364
  setStep(STEP.ERROR);
2365
2365
  });
2366
2366
  };
@@ -2594,6 +2594,11 @@ function Build({ config, providerId = "cashfree-occ", onDone }) {
2594
2594
  ] }),
2595
2595
  step === STEP.ERROR && error && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
2596
2596
  /* @__PURE__ */ jsx8(Alert, { variant: "error", children: error.message }),
2597
+ error.failures?.length ? /* @__PURE__ */ jsx8(Box8, { flexDirection: "column", marginTop: 1, children: error.failures.map((f, i) => /* @__PURE__ */ jsxs8(Box8, { children: [
2598
+ /* @__PURE__ */ jsx8(Text8, { color: palette.bad, children: ` ${glyph.cross} ` }),
2599
+ /* @__PURE__ */ jsx8(Text8, { bold: true, children: `${f.name}: ` }),
2600
+ /* @__PURE__ */ jsx8(Text8, { color: palette.dim, children: f.detail })
2601
+ ] }, i)) }) : null,
2597
2602
  error.hint ? /* @__PURE__ */ jsx8(Text8, { color: palette.warn, children: ` ${error.hint}` }) : null,
2598
2603
  /* @__PURE__ */ jsx8(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx8(Text8, { color: palette.dim, children: "press enter to return to the menu" }) })
2599
2604
  ] })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hookwright",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "Build real, signed e-commerce webhooks from a live Shopify catalogue — interactive terminal UI, no backend",
5
5
  "keywords": [
6
6
  "webhook",