hookwright 1.10.0 → 1.11.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 +73 -14
  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.10.0",
27
+ version: "1.11.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",
@@ -1155,21 +1155,21 @@ function selectionFor2(eventName) {
1155
1155
  }
1156
1156
  var COMMON_FIELDS2 = [
1157
1157
  { source: "event_name / eventName", target: "\xABgate\xBB", required: true, note: "the schema matches EITHER spelling" },
1158
- { source: "customer.phone / user_data.phone", target: "customer.phone", required: true, note: "missing phone is rejected on every event" },
1159
- { source: "customer.first_name / user_data.firstName", target: "customer.firstName" },
1160
- { source: "customer.last_name / user_data.lastName", target: "customer.lastName" },
1158
+ { source: "customer.phone / phone / data.user_data.phone / eventPayload.userData.phone", target: "customer.phone", required: true, note: "missing phone is rejected on every event" },
1159
+ { source: "customer.first_name / data.user_data.firstName / eventPayload.userData.firstName", target: "customer.firstName" },
1160
+ { source: "customer.last_name / data.user_data.lastName / eventPayload.userData.lastName", target: "customer.lastName" },
1161
1161
  { source: "\u2014 (first + last)", target: "customer.fullName", note: "built by the consumer, not sent" },
1162
- { source: "customer.email / user_data.email", target: "customer.email" },
1162
+ { source: "customer.email / email / data.user_data.email / eventPayload.userData.email", target: "customer.email" },
1163
1163
  { source: "channel", target: "channel" },
1164
1164
  { source: "timestamp / created_at", target: "eventTime" }
1165
1165
  ];
1166
1166
  var BROWSING_FIELDS = [
1167
- { source: "uiData.pageUrl / data.page_url", target: "page.url" },
1168
- { source: "uiData.pageTitle / data.page_title", target: "page.title" },
1169
- { source: "uiData.landingPageUrl", target: "page.landingPage" },
1170
- { source: "uiData.referrerPageUrl", target: "page.referrer" },
1171
- { source: "clientData.brandUrl", target: "storeUrl" },
1172
- { source: "session_id", target: "sessionId" }
1167
+ { source: "eventPayload.uiData.pageUrl / data.page_url", target: "page.url" },
1168
+ { source: "eventPayload.uiData.pageTitle / data.page_title", target: "page.title" },
1169
+ { source: "eventPayload.uiData.landingPageUrl / data.landing_page_url", target: "page.landingPage" },
1170
+ { source: "eventPayload.uiData.referrerPageUrl / data.referrer_page_url", target: "page.referrer" },
1171
+ { source: "eventPayload.clientData.brandUrl", target: "storeUrl" },
1172
+ { source: "session_id / sessionId", target: "sessionId" }
1173
1173
  ];
1174
1174
  var CART_FIELDS = [
1175
1175
  { source: "line_items[].title", target: "cart.productDetails", required: true, note: "the first PAID line wins; freebies rank last" },
@@ -1559,6 +1559,43 @@ var fieldMap5 = [
1559
1559
  { source: "event_id", target: "eventId" },
1560
1560
  { source: "event_time", target: "eventTime" }
1561
1561
  ];
1562
+ var ENVELOPE_FIELDS = [
1563
+ { source: "event_type", target: "\xABgate\xBB", required: true, note: "the schema matches on this" },
1564
+ { source: "payload.user.phone_with_dial_code", target: "customer.phone", required: true, note: "falls back to dial_code + phone" },
1565
+ { source: "payload.user.first_name", target: "customer.firstName" },
1566
+ { source: "payload.user.last_name", target: "customer.lastName" },
1567
+ { source: "payload.user.full_name", target: "customer.fullName", note: "falls back to first + last name" },
1568
+ { source: "payload.user.email", target: "customer.email" },
1569
+ { source: "store.shopify_domain", target: "store.shopify_domain" },
1570
+ { source: "store.name", target: "store.name" },
1571
+ { source: "store.main_domain", target: "store.main_domain" },
1572
+ { source: "event_id", target: "eventId" },
1573
+ { source: "event_time", target: "eventTime" }
1574
+ ];
1575
+ var COLLECTION_VIEWED_FIELDS = [
1576
+ ...ENVELOPE_FIELDS,
1577
+ { source: "payload.collection_viewed.name", target: "payload.collection_viewed.name", required: true },
1578
+ { source: "payload.collection_viewed.handle", target: "payload.collection_viewed.handle", required: true, note: "the url is built from this" },
1579
+ { source: "payload.collection_viewed.image", target: "payload.collection_viewed.image" },
1580
+ { source: "payload.collection_viewed.collection_id", target: "payload.collection_viewed.collection_id" },
1581
+ { source: "\u2014 (store domain + handle)", target: "collection_url", note: "derived, not sent" }
1582
+ ];
1583
+ var PRODUCT_VIEWED_FIELDS = [
1584
+ ...ENVELOPE_FIELDS,
1585
+ { source: "payload.product_viewed.title", target: "payload.product_viewed.title", required: true },
1586
+ { source: "payload.product_viewed.handle", target: "payload.product_viewed.handle", required: true, note: "the url is built from this" },
1587
+ { source: "payload.product_viewed.image", target: "payload.product_viewed.image" },
1588
+ { source: "payload.product_viewed.product_id", target: "payload.product_viewed.product_id" },
1589
+ { source: "\u2014 (store domain + handle)", target: "product_url", note: "derived, not sent" }
1590
+ ];
1591
+ var FIELD_MAPS3 = {
1592
+ ABANDONED_CHECKOUT: fieldMap5,
1593
+ COLLECTION_VIEWED: COLLECTION_VIEWED_FIELDS,
1594
+ PRODUCT_VIEWED: PRODUCT_VIEWED_FIELDS
1595
+ };
1596
+ function fieldMapFor(eventName) {
1597
+ return FIELD_MAPS3[eventName] ?? fieldMap5;
1598
+ }
1562
1599
  var editableFields5 = [
1563
1600
  { group: "Event", path: "event_id", label: "Event id" },
1564
1601
  { group: "Event", path: "event_time", label: "Event time" },
@@ -1734,6 +1771,7 @@ var flexype_default = {
1734
1771
  signatureScheme: "static shared secret in the header (no body signature)",
1735
1772
  signatureHeader: "x-flexype-authorization",
1736
1773
  fieldMap: fieldMap5,
1774
+ fieldMapFor,
1737
1775
  editableFields: editableFields5,
1738
1776
  buildPayload: buildPayload5,
1739
1777
  sign: sign5,
@@ -1789,7 +1827,7 @@ var EXCHANGE_FIELDS = [
1789
1827
  { source: "line_items[].exchange_product.price", target: "exchangeProduct.price + pricing.priceDifference", note: "difference is signed: positive means the shopper owes more" }
1790
1828
  ];
1791
1829
  var fieldMap6 = COMMON_FIELDS3;
1792
- function fieldMapFor(eventName) {
1830
+ function fieldMapFor2(eventName) {
1793
1831
  return eventDef3(eventName).requestType === "exchange" ? [...COMMON_FIELDS3, ...EXCHANGE_FIELDS] : COMMON_FIELDS3;
1794
1832
  }
1795
1833
  function editableFieldsFor3(eventName) {
@@ -2029,7 +2067,7 @@ var return_prime_default = {
2029
2067
  signatureScheme: "none documented \u2014 every request is accepted",
2030
2068
  signatureHeader: null,
2031
2069
  fieldMap: fieldMap6,
2032
- fieldMapFor,
2070
+ fieldMapFor: fieldMapFor2,
2033
2071
  editableFields: editableFields6,
2034
2072
  editableFieldsFor: editableFieldsFor3,
2035
2073
  selectionFor: selectionFor4,
@@ -2921,9 +2959,30 @@ function checkAllowedPhone(payload, config) {
2921
2959
  detail: ok ? `${normalized} is an approved test handset` : `${normalized} is NOT in allowedPhones \u2014 refusing to risk messaging a real shopper`
2922
2960
  };
2923
2961
  }
2962
+ function resolveSource(payload, source) {
2963
+ for (const candidate of String(source).split(" / ")) {
2964
+ const path6 = candidate.trim();
2965
+ if (!path6 || path6.startsWith("\u2014")) continue;
2966
+ if (path6.includes("[]")) {
2967
+ const [listPath, ...rest] = path6.split("[]");
2968
+ const list = getPath(payload, listPath);
2969
+ if (!Array.isArray(list)) continue;
2970
+ const leaf = rest.join("").replace(/^\./, "");
2971
+ const hit = list.find((item) => {
2972
+ const v = leaf ? getPath(item, leaf) : item;
2973
+ return v !== void 0 && v !== null && v !== "";
2974
+ });
2975
+ if (hit !== void 0) return leaf ? getPath(hit, leaf) : hit;
2976
+ continue;
2977
+ }
2978
+ const value = getPath(payload, path6);
2979
+ if (value !== void 0 && value !== null && value !== "") return value;
2980
+ }
2981
+ return void 0;
2982
+ }
2924
2983
  function coverage(payload, fieldMap8) {
2925
2984
  return fieldMap8.map((f) => {
2926
- const value = getPath(payload, f.source);
2985
+ const value = resolveSource(payload, f.source);
2927
2986
  const present = value !== void 0 && value !== null && value !== "";
2928
2987
  return {
2929
2988
  field: f.source,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hookwright",
3
- "version": "1.10.0",
3
+ "version": "1.11.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",