hookwright 2.2.0 → 2.3.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 (2) hide show
  1. package/dist/cli.js +58 -25
  2. package/package.json +1 -1
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: "2.2.0",
27
+ version: "2.3.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",
@@ -1826,9 +1826,9 @@ var COMMON_FIELDS3 = [
1826
1826
  { source: "request.smart_exchange", target: "smartExchange" },
1827
1827
  { source: "request.order.name", target: "order.name" },
1828
1828
  { source: "request.order.id", target: "order.id" },
1829
- { source: "request.line_items[].original_product.title", target: "product.name + product.details", required: true, note: "the first PAID line wins; freebies rank last" },
1829
+ { source: "request.line_items[].original_product.title", target: "product.details", required: true, note: "the first PAID line names the caption; freebies rank last" },
1830
1830
  { source: "request.line_items[].original_product.image.src", target: "product.image" },
1831
- { source: "request.line_items[].original_product.price", target: "product.price", note: "a zero price marks the line a freebie" },
1831
+ { source: "request.line_items[].original_product.price", target: "product.totalPrice", note: "summed across the lines, times quantity; a zero marks a freebie" },
1832
1832
  { source: "request.line_items[].original_product.sku", target: "product.sku" },
1833
1833
  { source: "request.line_items[].reason", target: "reason" },
1834
1834
  { source: "request.line_items[].quantity", target: "product.quantity" },
@@ -1845,7 +1845,7 @@ var COMMON_FIELDS3 = [
1845
1845
  ];
1846
1846
  var EXCHANGE_FIELDS = [
1847
1847
  { source: "request.line_items[].exchange_product.title", target: "exchangeProduct.name", note: "exchanges only \u2014 returns never carry it" },
1848
- { source: "request.line_items[].exchange_product.price", target: "exchangeProduct.price + pricing.priceDifference", note: "difference is signed: positive means the shopper owes more" },
1848
+ { source: "request.line_items[].exchange_product.price", target: "exchangeProduct.totalPrice + pricing.priceDifference", note: "both summed across the lines, times quantity; the difference is signed, positive means the shopper owes more" },
1849
1849
  { source: "request.line_items[].exchange_product.image.src", target: "exchangeProduct.image" },
1850
1850
  { source: "request.line_items[].exchange_product.sku", target: "exchangeProduct.sku" }
1851
1851
  ];
@@ -1892,6 +1892,7 @@ function buildPayload6(ctx) {
1892
1892
  const reached = (name) => STATUSES.indexOf(name) <= reachedIndex && def.status !== "requested";
1893
1893
  const makeLineItem = (sel, idx) => {
1894
1894
  const repl = replacementFor(sel, idx);
1895
+ const qty = def.requestType === "exchange" ? repl?.quantity ?? sel?.quantity ?? 1 : sel?.quantity ?? 1;
1895
1896
  const originalPrice = money2(sel?.variant?.price ?? 0);
1896
1897
  const exchangePrice = money2(repl?.variant?.price ?? 0);
1897
1898
  return {
@@ -1957,12 +1958,12 @@ function buildPayload6(ctx) {
1957
1958
  tracking_url: `https://www.bluedart.com/trackdartresultthirdparty?trackFor=0&trackNo=${String(now.getTime()).slice(-11)}`
1958
1959
  }
1959
1960
  ],
1960
- quantity: sel?.quantity ?? 1,
1961
+ quantity: qty,
1961
1962
  reason: ctx.reason ?? "Size of Fit Issues",
1962
1963
  shop_price: {
1963
1964
  actual_amount: originalPrice,
1964
1965
  total_tax: 0,
1965
- return_quantity: sel?.quantity ?? 1,
1966
+ return_quantity: qty,
1966
1967
  total_discount: 0,
1967
1968
  shipping_amount: 0,
1968
1969
  taxes_included: true,
@@ -1972,7 +1973,7 @@ function buildPayload6(ctx) {
1972
1973
  presentment_price: {
1973
1974
  actual_amount: originalPrice,
1974
1975
  total_tax: 0,
1975
- return_quantity: sel?.quantity ?? 1,
1976
+ return_quantity: qty,
1976
1977
  total_discount: 0,
1977
1978
  shipping_amount: 0,
1978
1979
  taxes_included: true,
@@ -3943,6 +3944,11 @@ function Build({ config, providerId = "cashfree-occ", onDone }) {
3943
3944
  const [items, setItems] = useState([]);
3944
3945
  const [pendingVariant, setPendingVariant] = useState(null);
3945
3946
  const [exchangeItems, setExchangeItems] = useState([]);
3947
+ const [side, setSide] = useState("returned");
3948
+ const [replacementChosen, setReplacementChosen] = useState([]);
3949
+ const [replacements, setReplacements] = useState([]);
3950
+ const active = () => side === "replacement" ? replacementChosen : chosen;
3951
+ const defaultQty = () => side === "replacement" ? String(items[cursor]?.quantity ?? 1) : "1";
3946
3952
  const [delta, setDelta] = useState([]);
3947
3953
  const isDeltaEvent = providerId === "nitro" && (eventName === "addtocart" || eventName === "removefromcart");
3948
3954
  const [draft, setDraft] = useState(null);
@@ -3963,13 +3969,15 @@ function Build({ config, providerId = "cashfree-occ", onDone }) {
3963
3969
  case STEP.COLLECTION:
3964
3970
  return multiEvent ? setStep(STEP.EVENT) : onDone();
3965
3971
  case STEP.VARIANT:
3966
- if (cursor === 0) return setStep(STEP.PICK);
3967
- setItems(items.slice(0, -1));
3972
+ if (cursor === 0) return setStep(side === "replacement" ? STEP.REPLACEMENT : STEP.PICK);
3973
+ if (side === "replacement") setReplacements(replacements.slice(0, -1));
3974
+ else setItems(items.slice(0, -1));
3968
3975
  return stepInto(cursor - 1);
3969
3976
  case STEP.QUANTITY:
3970
- if (chosen[cursor]?.variants.length > 1) return setStep(STEP.VARIANT);
3971
- if (cursor === 0) return setStep(STEP.PICK);
3972
- setItems(items.slice(0, -1));
3977
+ if (active()[cursor]?.variants.length > 1) return setStep(STEP.VARIANT);
3978
+ if (cursor === 0) return setStep(side === "replacement" ? STEP.REPLACEMENT : STEP.PICK);
3979
+ if (side === "replacement") setReplacements(replacements.slice(0, -1));
3980
+ else setItems(items.slice(0, -1));
3973
3981
  return stepInto(cursor - 1);
3974
3982
  case STEP.DISCOUNT: {
3975
3983
  if (selection === "none") return multiEvent ? setStep(STEP.EVENT) : onDone();
@@ -3997,7 +4005,7 @@ function Build({ config, providerId = "cashfree-occ", onDone }) {
3997
4005
  };
3998
4006
  const stepInto = (index) => {
3999
4007
  setCursor(index);
4000
- const product = chosen[index];
4008
+ const product = active()[index];
4001
4009
  if (!product) return setStep(STEP.PICK);
4002
4010
  if (product.variants.length > 1) return setStep(STEP.VARIANT);
4003
4011
  setPendingVariant(product.variants[0]);
@@ -4068,9 +4076,31 @@ function Build({ config, providerId = "cashfree-occ", onDone }) {
4068
4076
  const onReplacementsPicked = (ids) => {
4069
4077
  const picked = ids.map((id) => products.find((p) => p.id === id)).filter(Boolean);
4070
4078
  if (!picked.length) return;
4071
- const pairs = picked.map((p) => ({ product: p, variant: p.variants[0], quantity: 1 }));
4072
- setExchangeItems(pairs);
4073
- startReview(0, collection, items, delta, pairs);
4079
+ setReplacementChosen(picked);
4080
+ setReplacements([]);
4081
+ setSide("replacement");
4082
+ setCursor(0);
4083
+ const first = picked[0];
4084
+ if (first.variants.length > 1) setStep(STEP.VARIANT);
4085
+ else {
4086
+ setPendingVariant(first.variants[0]);
4087
+ setStep(STEP.QUANTITY);
4088
+ }
4089
+ };
4090
+ const advanceReplacement = (nextPairs, nextCursor) => {
4091
+ if (nextCursor >= replacementChosen.length) {
4092
+ setReplacements(nextPairs);
4093
+ setExchangeItems(nextPairs);
4094
+ setSide("returned");
4095
+ startReview(0, collection, items, delta, nextPairs);
4096
+ return;
4097
+ }
4098
+ setReplacements(nextPairs);
4099
+ setCursor(nextCursor);
4100
+ const product = replacementChosen[nextCursor];
4101
+ if (product.variants.length > 1) return setStep(STEP.VARIANT);
4102
+ setPendingVariant(product.variants[0]);
4103
+ setStep(STEP.QUANTITY);
4074
4104
  };
4075
4105
  const advance = (nextItems, nextCursor) => {
4076
4106
  if (nextCursor >= chosen.length) {
@@ -4123,13 +4153,16 @@ function Build({ config, providerId = "cashfree-occ", onDone }) {
4123
4153
  }
4124
4154
  };
4125
4155
  const onVariantPicked = (variantId) => {
4126
- const product = chosen[cursor];
4156
+ const product = active()[cursor];
4127
4157
  setPendingVariant(product.variants.find((v) => v.id === variantId) ?? product.variants[0]);
4128
4158
  setStep(STEP.QUANTITY);
4129
4159
  };
4130
4160
  const onQuantity = (raw) => {
4131
4161
  const qty = Math.max(1, Number.parseInt(raw, 10) || 1);
4132
- const product = chosen[cursor];
4162
+ const product = active()[cursor];
4163
+ if (side === "replacement") {
4164
+ return advanceReplacement([...replacements, { product, variant: pendingVariant, quantity: qty }], cursor + 1);
4165
+ }
4133
4166
  const nextItems = [...items, { product, variant: pendingVariant, quantity: qty }];
4134
4167
  advance(nextItems, cursor + 1);
4135
4168
  };
@@ -4325,31 +4358,31 @@ function Build({ config, providerId = "cashfree-occ", onDone }) {
4325
4358
  ] }),
4326
4359
  step === STEP.VARIANT && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
4327
4360
  /* @__PURE__ */ jsxs8(Text8, { children: [
4328
- `Variant for `,
4329
- /* @__PURE__ */ jsx8(Text8, { bold: true, color: palette.accent, children: chosen[cursor]?.title })
4361
+ side === "replacement" ? "Replacement variant for " : "Variant for ",
4362
+ /* @__PURE__ */ jsx8(Text8, { bold: true, color: palette.accent, children: active()[cursor]?.title })
4330
4363
  ] }),
4331
4364
  /* @__PURE__ */ jsx8(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx8(
4332
4365
  Select4,
4333
4366
  {
4334
4367
  visibleOptionCount: 8,
4335
- options: chosen[cursor].variants.map((v) => ({
4368
+ options: active()[cursor].variants.map((v) => ({
4336
4369
  label: `${truncate(v.title, 34).padEnd(35)} ${money(v.price, currency)}${v.sku ? " " + v.sku : ""}`,
4337
4370
  value: v.id
4338
4371
  })),
4339
4372
  onChange: onVariantPicked
4340
4373
  },
4341
- `variant-${cursor}`
4374
+ `variant-${side}-${cursor}`
4342
4375
  ) })
4343
4376
  ] }),
4344
4377
  step === STEP.QUANTITY && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
4345
4378
  /* @__PURE__ */ jsxs8(Text8, { children: [
4346
- `Quantity for `,
4347
- /* @__PURE__ */ jsx8(Text8, { bold: true, color: palette.accent, children: chosen[cursor]?.title }),
4379
+ side === "replacement" ? "Replacement quantity for " : "Quantity for ",
4380
+ /* @__PURE__ */ jsx8(Text8, { bold: true, color: palette.accent, children: active()[cursor]?.title }),
4348
4381
  /* @__PURE__ */ jsx8(Text8, { color: palette.dim, children: pendingVariant?.title ? ` \xB7 ${pendingVariant.title}` : "" })
4349
4382
  ] }),
4350
4383
  /* @__PURE__ */ jsxs8(Box8, { marginTop: 1, children: [
4351
4384
  /* @__PURE__ */ jsx8(Text8, { color: palette.accent, children: "\u276F " }),
4352
- /* @__PURE__ */ jsx8(TextInput, { defaultValue: "1", placeholder: "1", onSubmit: onQuantity }, `qty-${cursor}`)
4385
+ /* @__PURE__ */ jsx8(TextInput, { defaultValue: defaultQty(), placeholder: defaultQty(), onSubmit: onQuantity }, `qty-${side}-${cursor}`)
4353
4386
  ] })
4354
4387
  ] }),
4355
4388
  step === STEP.DISCOUNT && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hookwright",
3
- "version": "2.2.0",
3
+ "version": "2.3.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",