hookwright 1.2.1 → 1.2.3
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.
- package/README.md +3 -1
- package/dist/cli.js +45 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -75,6 +75,8 @@ Every command works without a TTY, for CI or scripting:
|
|
|
75
75
|
hookwright build --items 2 # cashfree-occ by default
|
|
76
76
|
hookwright build --provider razorpay-magic --items 2
|
|
77
77
|
hookwright build --provider nitro --event orders/create
|
|
78
|
+
hookwright build --provider nitro --event category_view --collection summer-sale
|
|
79
|
+
hookwright build --provider nitro --event view # no product needed
|
|
78
80
|
hookwright build --search "cold brew" # only products matching a title
|
|
79
81
|
hookwright build --items 3 --discount 250 --send
|
|
80
82
|
hookwright send --dry-run # print the request + curl, send nothing
|
|
@@ -142,7 +144,7 @@ Adding one is a single file in `src/providers/` exporting `buildPayload`, `sign`
|
|
|
142
144
|
```bash
|
|
143
145
|
npm install
|
|
144
146
|
npm run dev # esbuild watch
|
|
145
|
-
npm test #
|
|
147
|
+
npm test # 190 tests, no network required
|
|
146
148
|
npm start # build + run
|
|
147
149
|
```
|
|
148
150
|
|
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.
|
|
27
|
+
version: "1.2.3",
|
|
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",
|
|
@@ -776,6 +776,9 @@ var EVENTS = [
|
|
|
776
776
|
{ eventName: "orders/create", type: "nitro_orders_create", label: "Order Created", selection: "cart", subject: "ordered items" },
|
|
777
777
|
{ eventName: "orders/updated", type: "nitro_orders_updated", label: "Order Updated", selection: "cart", subject: "ordered items" }
|
|
778
778
|
];
|
|
779
|
+
function eventFromPayload(payload) {
|
|
780
|
+
return payload?.eventName;
|
|
781
|
+
}
|
|
779
782
|
function selectionFor(eventName) {
|
|
780
783
|
return EVENTS.find((e) => e.eventName === eventName)?.selection ?? "cart";
|
|
781
784
|
}
|
|
@@ -1061,6 +1064,7 @@ var nitro_default = {
|
|
|
1061
1064
|
editableFields: editableFields3,
|
|
1062
1065
|
editableFieldsFor,
|
|
1063
1066
|
selectionFor,
|
|
1067
|
+
eventFromPayload,
|
|
1064
1068
|
buildPayload: buildPayload3,
|
|
1065
1069
|
sign: sign3,
|
|
1066
1070
|
webhookUrl: webhookUrl3,
|
|
@@ -1773,10 +1777,11 @@ async function checkImages(payload, { timeoutMs = 1e4 } = {}) {
|
|
|
1773
1777
|
}));
|
|
1774
1778
|
}
|
|
1775
1779
|
async function runAll({ payload, body, provider, config, checkImageUrls = true, checkEndpoint = true, eventName }) {
|
|
1776
|
-
const
|
|
1780
|
+
const event = eventName ?? (provider.eventFromPayload ? provider.eventFromPayload(payload) : void 0);
|
|
1781
|
+
const checks = [checkGate(payload, provider, event), checkRoundTrip(body), checkPhone(payload), checkAllowedPhone(payload, config)];
|
|
1777
1782
|
if (checkImageUrls) checks.push(...await checkImages(payload));
|
|
1778
1783
|
if (checkEndpoint) checks.push(await checkEndpointExists(provider.webhookUrl(config)));
|
|
1779
|
-
const fields =
|
|
1784
|
+
const fields = event && provider.fieldMapFor ? provider.fieldMapFor(event) : provider.fieldMap;
|
|
1780
1785
|
const cov = coverage(payload, fields);
|
|
1781
1786
|
const missing = cov.filter((c2) => c2.status === "MISSING");
|
|
1782
1787
|
checks.push({
|
|
@@ -1918,7 +1923,8 @@ async function buildPayload4({ cfg, providerId = "cashfree-occ", items = [], dis
|
|
|
1918
1923
|
};
|
|
1919
1924
|
const file = savePayload({ provider: provider.id, payload, body, meta });
|
|
1920
1925
|
audit("payload.built", { provider: provider.id, valid: report.ok, file });
|
|
1921
|
-
|
|
1926
|
+
const record = { provider: provider.id, payload, body, meta };
|
|
1927
|
+
return { provider, payload, body, report, file, meta, summary, record };
|
|
1922
1928
|
}
|
|
1923
1929
|
|
|
1924
1930
|
// src/core/send.mjs
|
|
@@ -2356,7 +2362,7 @@ function Build({ config, providerId = "cashfree-occ", onDone }) {
|
|
|
2356
2362
|
};
|
|
2357
2363
|
const doSend = () => {
|
|
2358
2364
|
setStep(STEP.SENDING);
|
|
2359
|
-
dispatch({ cfg: config, record:
|
|
2365
|
+
dispatch({ cfg: config, record: built.record }).then((result) => {
|
|
2360
2366
|
setSendResult(result);
|
|
2361
2367
|
setStep(STEP.RESULT);
|
|
2362
2368
|
}).catch((err) => {
|
|
@@ -3530,18 +3536,42 @@ async function cmdBuild(args, config) {
|
|
|
3530
3536
|
const discount = Number.parseFloat(args.flags.discount ?? "0") || 0;
|
|
3531
3537
|
const search = typeof args.flags.search === "string" ? args.flags.search : void 0;
|
|
3532
3538
|
const checkImageUrls = args.flags.image !== false && args.flags["image-check"] !== false;
|
|
3533
|
-
|
|
3534
|
-
const
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3539
|
+
const provider = getProvider(providerId);
|
|
3540
|
+
const eventName = typeof args.flags.event === "string" ? args.flags.event : provider.defaultEvent;
|
|
3541
|
+
const selection = provider.selectionFor ? provider.selectionFor(eventName) : "cart";
|
|
3542
|
+
let items = [];
|
|
3543
|
+
let collection;
|
|
3544
|
+
if (selection === "collection") {
|
|
3545
|
+
log.step(`fetching collections from ${config.shopify.domain}\u2026`);
|
|
3546
|
+
const collections = await fetchCollections(config, { search });
|
|
3547
|
+
if (!collections.length) {
|
|
3548
|
+
log.fail("Shopify returned no collections");
|
|
3549
|
+
log.dim("create one in Shopify, or pick a different event");
|
|
3550
|
+
return 1;
|
|
3551
|
+
}
|
|
3552
|
+
const wanted = typeof args.flags.collection === "string" ? args.flags.collection.toLowerCase() : null;
|
|
3553
|
+
collection = collections.find((c2) => wanted && (c2.id === wanted || c2.handle === wanted || c2.title.toLowerCase() === wanted)) ?? collections[0];
|
|
3554
|
+
if (wanted && collection.title.toLowerCase() !== wanted && collection.id !== wanted && collection.handle !== wanted) {
|
|
3555
|
+
log.warn(`no collection matched "${args.flags.collection}", using ${collection.title}`);
|
|
3556
|
+
}
|
|
3557
|
+
log.ok(`collection: ${collection.title}`);
|
|
3558
|
+
} else if (selection !== "none") {
|
|
3559
|
+
log.step(`fetching products from ${config.shopify.domain}\u2026`);
|
|
3560
|
+
const products = await fetchCatalogue(config, { search });
|
|
3561
|
+
if (!products.length) {
|
|
3562
|
+
log.fail("Shopify returned no products");
|
|
3563
|
+
return 1;
|
|
3564
|
+
}
|
|
3565
|
+
items = autoSelect(products, selection === "product" ? 1 : count);
|
|
3566
|
+
log.ok(`${items.length} product(s): ${items.map((i) => i.product.title).join(", ")}`);
|
|
3567
|
+
} else {
|
|
3568
|
+
log.ok(`${eventName} needs no product or collection`);
|
|
3538
3569
|
}
|
|
3539
|
-
const items = autoSelect(products, count);
|
|
3540
|
-
log.ok(`${items.length} product(s): ${items.map((i) => i.product.title).join(", ")}`);
|
|
3541
3570
|
const built = await buildPayload4({
|
|
3542
3571
|
cfg: config,
|
|
3543
3572
|
providerId,
|
|
3544
|
-
eventName
|
|
3573
|
+
eventName,
|
|
3574
|
+
collection,
|
|
3545
3575
|
items,
|
|
3546
3576
|
discount,
|
|
3547
3577
|
phone: typeof args.flags.phone === "string" ? args.flags.phone : void 0,
|
|
@@ -3586,7 +3616,7 @@ async function cmdBuild(args, config) {
|
|
|
3586
3616
|
async function cmdSend(args, config, built) {
|
|
3587
3617
|
const bad = requireConfig(config);
|
|
3588
3618
|
if (bad) return bad;
|
|
3589
|
-
let record = built
|
|
3619
|
+
let record = built?.record ?? null;
|
|
3590
3620
|
if (!record && typeof args.flags.file === "string") record = loadPayload(args.flags.file);
|
|
3591
3621
|
if (!record) record = loadLast();
|
|
3592
3622
|
if (!record) {
|
|
@@ -3747,6 +3777,7 @@ ${c.bold("BUILD OPTIONS")}
|
|
|
3747
3777
|
--provider <id> cashfree-occ | razorpay-magic | nitro (default cashfree-occ)
|
|
3748
3778
|
--event <name> nitro only: view \xB7 category_view \xB7 product_view \xB7 addtocart
|
|
3749
3779
|
removefromcart \xB7 checkout \xB7 orders/create \xB7 orders/updated
|
|
3780
|
+
--collection <x> nitro category_view: collection id, handle or title
|
|
3750
3781
|
--items <n> how many products to put in the cart (default 1)
|
|
3751
3782
|
--search <text> only consider products matching a title
|
|
3752
3783
|
--discount <n> cart discount in major currency units (default 0)
|