hookwright 1.3.0 → 1.5.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 (2) hide show
  1. package/dist/cli.js +109 -68
  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: "1.3.0",
27
+ version: "1.5.0",
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",
@@ -809,7 +809,7 @@ var FIELD_MAPS = {
809
809
  ...PAGE_FIELDS,
810
810
  { source: "eventVal.resource_id", target: "eventVal.resource_id", required: true, note: "the collection id" },
811
811
  { source: "eventVal.resource", target: "eventVal.resource" },
812
- { source: "eventVal.title", target: "collection name", required: true },
812
+ { source: "eventVal.resource_id", target: "collection lookup", required: true, note: "the consumer fetches the collection by this id" },
813
813
  { source: "eventVal.domain", target: "eventVal.domain" }
814
814
  ],
815
815
  product_view: [
@@ -828,7 +828,7 @@ var FIELD_MAPS = {
828
828
  { source: "eventVal.init_cart", target: "eventVal.init_cart" },
829
829
  { source: "eventVal.empty_cart", target: "eventVal.empty_cart" },
830
830
  { source: "eventVal.bik_customer_id", target: "eventVal.bik_customer_id" },
831
- { source: "eventVal.line_items[0].name", target: "cart enrichment", required: true }
831
+ { source: "eventVal.line_items[0].title", target: "cart enrichment", required: true }
832
832
  ],
833
833
  removefromcart: [
834
834
  ...COMMON_FIELDS,
@@ -836,7 +836,7 @@ var FIELD_MAPS = {
836
836
  { source: "eventVal.init_cart", target: "eventVal.init_cart" },
837
837
  { source: "eventVal.empty_cart", target: "eventVal.empty_cart" },
838
838
  { source: "eventVal.bik_customer_id", target: "eventVal.bik_customer_id" },
839
- { source: "eventVal.line_items[0].name", target: "cart enrichment" }
839
+ { source: "eventVal.line_items[0].title", target: "cart enrichment" }
840
840
  ],
841
841
  checkout: [
842
842
  ...COMMON_FIELDS,
@@ -875,7 +875,7 @@ var EDITABLE = {
875
875
  ],
876
876
  collection: [
877
877
  { group: "Collection", path: "eventVal.resource_id", label: "Collection id" },
878
- { group: "Collection", path: "eventVal.title", label: "Collection name" },
878
+ { group: "Collection", path: "eventVal.resource_id", label: "Collection id", type: "number" },
879
879
  { group: "Collection", path: "eventVal.l", label: "Collection URL" }
880
880
  ],
881
881
  product: [
@@ -919,105 +919,145 @@ function buildPayload3(ctx) {
919
919
  const cust = config.customer;
920
920
  const session = crypto3.randomBytes(8).toString("hex");
921
921
  const first = items[0];
922
- const lineItems = items.map(({ product, variant, quantity }) => ({
923
- id: variant ? String(variant.id) : null,
924
- product_id: String(product.id),
925
- name: product.title,
926
- title: product.title,
922
+ const cartLine = ({ product, variant, quantity }) => ({
927
923
  quantity,
928
- price: money2(variant?.price ?? 0),
929
- image: imageForVariant(product, variant),
930
- url: `https://${domain}/products/${product.handle ?? ""}`
931
- }));
932
- const cartValue = money2(lineItems.reduce((sum, li) => sum + li.price * li.quantity, 0));
933
- const productUrl = first ? `https://${domain}/products/${first.product.handle ?? ""}` : `https://${domain}`;
924
+ title: product.title,
925
+ line_price: money2((variant?.price ?? 0) * quantity).toFixed(2),
926
+ id: Number(variant?.id ?? product.id),
927
+ product_id: Number(product.id),
928
+ image_url: imageForVariant(product, variant)
929
+ });
930
+ const removedLine = ({ product, variant, quantity }) => {
931
+ const unit = money2(variant?.price ?? 0).toFixed(2);
932
+ const line = money2((variant?.price ?? 0) * quantity).toFixed(2);
933
+ const priceSet = (amount) => {
934
+ const value = Number(amount).toFixed(1);
935
+ return {
936
+ shop_money: { amount: value, currency_code: currency },
937
+ presentment_money: { amount: value, currency_code: currency }
938
+ };
939
+ };
940
+ return {
941
+ id: Number(variant?.id ?? product.id),
942
+ properties: null,
943
+ quantity,
944
+ variant_id: Number(variant?.id ?? product.id),
945
+ key: `${variant?.id ?? product.id}:${crypto3.randomBytes(16).toString("hex")}`,
946
+ discounted_price: unit,
947
+ discounts: [],
948
+ gift_card: false,
949
+ grams: 0,
950
+ line_price: line,
951
+ original_line_price: line,
952
+ original_price: unit,
953
+ price: unit,
954
+ product_id: Number(product.id),
955
+ sku: variant?.sku || "",
956
+ taxable: true,
957
+ title: product.title,
958
+ total_discount: "0.00",
959
+ vendor: config.shopify.shop?.name ?? config.shopify.domain,
960
+ discounted_price_set: priceSet(unit),
961
+ line_price_set: priceSet(line),
962
+ original_line_price_set: priceSet(line),
963
+ price_set: priceSet(unit),
964
+ total_discount_set: priceSet(0),
965
+ parent_relationship: null
966
+ };
967
+ };
968
+ const lineItems = items.map(cartLine);
969
+ const valueOf = (list) => money2(list.reduce((sum, i) => sum + money2(i.variant?.price ?? 0) * i.quantity, 0));
970
+ const cartValue = valueOf(items);
934
971
  const customer = {
935
- phone,
936
972
  email: cust.email,
937
- name: `${cust.firstName} ${cust.lastName}`.trim(),
938
- first_name: cust.firstName,
939
- last_name: cust.lastName
973
+ phone,
974
+ name: `${cust.firstName} ${cust.lastName}`.trim()
940
975
  };
976
+ const pageUrl = eventName === "product_view" ? `https://${domain}/products/${first?.product?.handle ?? ""}` : eventName === "category_view" ? `https://${domain}/collections/${ctx.collection?.handle ?? "all"}` : `https://${domain}/`;
977
+ const isBrowsing = ["view", "category_view", "product_view"].includes(eventName);
941
978
  const base = {
942
- org_token: config.defaults.orgToken ?? crypto3.randomBytes(12).toString("hex"),
979
+ org_token: config.defaults.orgToken ?? crypto3.randomUUID(),
943
980
  eventName,
981
+ u: isBrowsing ? pageUrl : "",
982
+ lang: config.defaults.lang ?? "en",
944
983
  userId: crypto3.randomUUID(),
945
984
  timestamp: now.toISOString(),
946
985
  country: cust.countryCode,
947
- domain
948
- };
949
- const page = {
950
- page: eventName === "product_view" ? "product" : eventName === "category_view" ? "collection" : "home",
951
- h: domain,
952
- l: productUrl,
953
- _ss: session,
954
- domain
986
+ state: isBrowsing ? cust.province : null,
987
+ city: isBrowsing ? cust.city : null,
988
+ pincode: isBrowsing ? cust.zip : null
955
989
  };
956
990
  let eventVal;
957
991
  switch (eventName) {
958
992
  case "view":
959
- eventVal = { page: "home", h: domain, l: `https://${domain}`, _ss: session, domain, customer };
993
+ eventVal = { page: pageUrl, h: domain, l: pageUrl, _ss: session, customer };
960
994
  break;
961
- case "category_view": {
962
- const collection = ctx.collection;
995
+ case "category_view":
963
996
  eventVal = {
964
- ...page,
965
- page: "collection",
966
- resource: "collection",
967
- resource_id: String(collection?.id ?? ""),
968
- title: collection?.title,
969
- image: collection?.image || void 0,
970
- l: collection?.handle ? `https://${domain}/collections/${collection.handle}` : `https://${domain}/collections/all`,
997
+ page: pageUrl,
998
+ resource_id: ctx.collection?.id ? Number(ctx.collection.id) : null,
999
+ resource: ctx.collection?.id ? "collection" : null,
1000
+ domain,
1001
+ h: domain,
1002
+ l: pageUrl,
1003
+ _ss: session,
971
1004
  customer
972
1005
  };
973
1006
  break;
974
- }
975
1007
  case "product_view":
976
1008
  eventVal = {
977
- ...page,
1009
+ page: pageUrl,
1010
+ resource_id: Number(first?.product?.id ?? 0),
978
1011
  resource: "product",
979
- resource_id: String(first?.product?.id ?? ""),
980
- title: first?.product?.title,
981
- image: first ? imageForVariant(first.product, first.variant) : void 0,
1012
+ domain,
982
1013
  price: money2(first?.variant?.price ?? 0),
1014
+ h: domain,
1015
+ l: pageUrl,
1016
+ _ss: session,
1017
+ image: first ? imageForVariant(first.product, first.variant) : void 0,
1018
+ title: first?.product?.title,
983
1019
  customer
984
1020
  };
985
1021
  break;
986
1022
  case "addtocart":
987
- case "removefromcart":
1023
+ case "removefromcart": {
1024
+ const added = eventName === "addtocart";
1025
+ const removed = added ? [] : items.slice(-1);
1026
+ const remaining = added ? items : items.slice(0, -1);
988
1027
  eventVal = {
989
- cart_value: cartValue,
990
- init_cart: eventName === "addtocart",
991
- empty_cart: eventName === "removefromcart" && items.length === 0,
992
- bik_customer_id: crypto3.randomUUID(),
993
- line_items: lineItems,
994
- [eventName === "addtocart" ? "items_added" : "items_removed"]: lineItems,
995
- customer
1028
+ line_items: added ? lineItems : remaining.map(cartLine),
1029
+ cart_value: added ? cartValue : valueOf(remaining),
1030
+ recent_product_image: added ? lineItems[0]?.image_url ?? null : null,
1031
+ init_cart: false,
1032
+ empty_cart: !added && remaining.length === 0,
1033
+ items_added: added ? lineItems : [],
1034
+ items_removed: removed.map(removedLine),
1035
+ customer,
1036
+ bik_customer_id: null
996
1037
  };
997
1038
  break;
1039
+ }
998
1040
  case "checkout":
999
1041
  eventVal = {
1000
1042
  checkout: cartPermalink(domain, items.map(({ variant, quantity }) => ({ variantId: variant?.id, quantity }))),
1001
- cart_value: cartValue,
1002
- bik_customer_id: crypto3.randomUUID(),
1003
- line_items: lineItems,
1004
- customer
1043
+ cart_value: cartValue.toFixed(2),
1044
+ customer,
1045
+ bik_customer_id: null
1005
1046
  };
1006
1047
  break;
1007
1048
  case "orders/create":
1008
1049
  case "orders/updated": {
1009
1050
  const orderNumber = 1e3 + Math.floor(Math.random() * 9e3);
1010
1051
  eventVal = {
1011
- url: `https://${domain}/admin/orders/${orderNumber}`,
1012
- order_id: String(Date.now()),
1052
+ url: `https://${domain}/${crypto3.randomBytes(5).toString("hex")}/orders/${crypto3.randomBytes(16).toString("hex")}/authenticate?key=${crypto3.randomBytes(16).toString("hex")}`,
1053
+ order_id: Number(`${Date.now()}`.slice(-13)),
1013
1054
  order_number: orderNumber,
1014
- order_name: `#${orderNumber}`,
1015
- price: cartValue,
1055
+ order_name: crypto3.randomBytes(4).toString("hex").toUpperCase(),
1056
+ price: cartValue.toFixed(2),
1016
1057
  currency,
1017
1058
  order_created_at: now.toISOString(),
1018
- bik_customer_id: crypto3.randomUUID(),
1019
- line_items: lineItems,
1020
- customer
1059
+ customer,
1060
+ bik_customer_id: null
1021
1061
  };
1022
1062
  break;
1023
1063
  }
@@ -1047,9 +1087,10 @@ function summarize3(payload) {
1047
1087
  const items = Array.isArray(ev.line_items) ? ev.line_items : [];
1048
1088
  return {
1049
1089
  event: payload?.eventName,
1050
- store: payload?.domain,
1090
+ // the schema keeps the domain inside eventVal, not at the root
1091
+ store: payload?.eventVal?.h ?? payload?.eventVal?.domain,
1051
1092
  customer: `${ev.customer?.name ?? ""} \xB7 ${ev.customer?.phone ?? ""}`.trim(),
1052
- items: items.map((i) => `${i.name} x${i.quantity}`).join(", ") || "\u2014",
1093
+ items: items.map((i) => `${i.title} x${i.quantity}`).join(", ") || payload?.eventVal?.title || "\u2014",
1053
1094
  total: ev.cart_value ?? ev.price ?? void 0,
1054
1095
  currency: ev.currency,
1055
1096
  extra: ev.order_name ? `order ${ev.order_name}` : ev.checkout ? "checkout started" : "",
@@ -3131,7 +3172,7 @@ function Build({ config, providerId = "cashfree-occ", onDone }) {
3131
3172
  return setStep(STEP.MODE);
3132
3173
  case STEP.RESULT:
3133
3174
  case STEP.ERROR:
3134
- return onDone();
3175
+ return built ? setStep(STEP.REPORT) : onDone();
3135
3176
  default:
3136
3177
  return onDone();
3137
3178
  }
@@ -3558,7 +3599,7 @@ function Build({ config, providerId = "cashfree-occ", onDone }) {
3558
3599
  /* @__PURE__ */ jsx8(Text8, { color: palette.dim, children: "reproduce:" }),
3559
3600
  /* @__PURE__ */ jsx8(Text8, { color: palette.dim, children: sendResult.curl })
3560
3601
  ] }),
3561
- /* @__PURE__ */ jsx8(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx8(Text8, { color: palette.dim, children: "press enter to return to the menu" }) })
3602
+ /* @__PURE__ */ jsx8(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx8(Text8, { color: palette.dim, children: "enter returns to the menu \xB7 esc goes back to the report to retry" }) })
3562
3603
  ] }),
3563
3604
  step === STEP.ERROR && error && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
3564
3605
  /* @__PURE__ */ jsx8(Alert, { variant: "error", children: error.message }),
@@ -3568,7 +3609,7 @@ function Build({ config, providerId = "cashfree-occ", onDone }) {
3568
3609
  /* @__PURE__ */ jsx8(Text8, { color: palette.dim, children: f.detail })
3569
3610
  ] }, i)) }) : null,
3570
3611
  error.hint ? /* @__PURE__ */ jsx8(Text8, { color: palette.warn, children: ` ${error.hint}` }) : null,
3571
- /* @__PURE__ */ jsx8(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx8(Text8, { color: palette.dim, children: "press enter to return to the menu" }) })
3612
+ /* @__PURE__ */ jsx8(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx8(Text8, { color: palette.dim, children: "enter returns to the menu \xB7 esc goes back to the report to retry" }) })
3572
3613
  ] })
3573
3614
  ] });
3574
3615
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hookwright",
3
- "version": "1.3.0",
3
+ "version": "1.5.0",
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",