hookwright 1.5.0 → 1.7.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.
- package/dist/cli.js +190 -21
- 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.
|
|
27
|
+
version: "1.7.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",
|
|
@@ -911,7 +911,7 @@ function editableFieldsFor(eventName) {
|
|
|
911
911
|
}
|
|
912
912
|
var editableFields3 = editableFieldsFor(DEFAULT_EVENT);
|
|
913
913
|
function buildPayload3(ctx) {
|
|
914
|
-
const { config, items, phone } = ctx;
|
|
914
|
+
const { config, items, phone, live, delta } = ctx;
|
|
915
915
|
const eventName = ctx.eventName ?? DEFAULT_EVENT;
|
|
916
916
|
const now = ctx.now ?? /* @__PURE__ */ new Date();
|
|
917
917
|
const currency = ctx.currency || config.defaults.currency;
|
|
@@ -1022,16 +1022,18 @@ function buildPayload3(ctx) {
|
|
|
1022
1022
|
case "addtocart":
|
|
1023
1023
|
case "removefromcart": {
|
|
1024
1024
|
const added = eventName === "addtocart";
|
|
1025
|
-
const
|
|
1026
|
-
const
|
|
1025
|
+
const fallback = added ? items : items.slice(-1);
|
|
1026
|
+
const moved = delta?.length ? items.filter((item) => delta.includes(item)) : fallback;
|
|
1027
|
+
const untouched = items.filter((item) => !moved.includes(item));
|
|
1028
|
+
const cart = added ? items : untouched;
|
|
1027
1029
|
eventVal = {
|
|
1028
|
-
line_items:
|
|
1029
|
-
cart_value:
|
|
1030
|
-
recent_product_image: added ?
|
|
1030
|
+
line_items: cart.map(cartLine),
|
|
1031
|
+
cart_value: valueOf(cart),
|
|
1032
|
+
recent_product_image: added ? moved.map(cartLine)[0]?.image_url ?? null : null,
|
|
1031
1033
|
init_cart: false,
|
|
1032
|
-
empty_cart: !added &&
|
|
1033
|
-
items_added: added ?
|
|
1034
|
-
items_removed:
|
|
1034
|
+
empty_cart: !added && cart.length === 0,
|
|
1035
|
+
items_added: added ? moved.map(cartLine) : [],
|
|
1036
|
+
items_removed: added ? [] : moved.map(removedLine),
|
|
1035
1037
|
customer,
|
|
1036
1038
|
bik_customer_id: null
|
|
1037
1039
|
};
|
|
@@ -1039,8 +1041,8 @@ function buildPayload3(ctx) {
|
|
|
1039
1041
|
}
|
|
1040
1042
|
case "checkout":
|
|
1041
1043
|
eventVal = {
|
|
1042
|
-
checkout: cartPermalink(domain, items.map(({ variant, quantity }) => ({ variantId: variant?.id, quantity }))),
|
|
1043
|
-
cart_value: cartValue.toFixed(2),
|
|
1044
|
+
checkout: live?.kind === "checkout" ? live.url : cartPermalink(domain, items.map(({ variant, quantity }) => ({ variantId: variant?.id, quantity }))),
|
|
1045
|
+
cart_value: live?.kind === "checkout" ? live.cartValue : cartValue.toFixed(2),
|
|
1044
1046
|
customer,
|
|
1045
1047
|
bik_customer_id: null
|
|
1046
1048
|
};
|
|
@@ -1048,7 +1050,17 @@ function buildPayload3(ctx) {
|
|
|
1048
1050
|
case "orders/create":
|
|
1049
1051
|
case "orders/updated": {
|
|
1050
1052
|
const orderNumber = 1e3 + Math.floor(Math.random() * 9e3);
|
|
1051
|
-
eventVal = {
|
|
1053
|
+
eventVal = live?.kind === "order" ? {
|
|
1054
|
+
url: live.statusUrl,
|
|
1055
|
+
order_id: live.id,
|
|
1056
|
+
order_number: live.number,
|
|
1057
|
+
order_name: live.name,
|
|
1058
|
+
price: live.price,
|
|
1059
|
+
currency: live.currency ?? currency,
|
|
1060
|
+
order_created_at: live.createdAt ?? now.toISOString(),
|
|
1061
|
+
customer,
|
|
1062
|
+
bik_customer_id: null
|
|
1063
|
+
} : {
|
|
1052
1064
|
url: `https://${domain}/${crypto3.randomBytes(5).toString("hex")}/orders/${crypto3.randomBytes(16).toString("hex")}/authenticate?key=${crypto3.randomBytes(16).toString("hex")}`,
|
|
1053
1065
|
order_id: Number(`${Date.now()}`.slice(-13)),
|
|
1054
1066
|
order_number: orderNumber,
|
|
@@ -2472,6 +2484,38 @@ var ShopifyClient = class {
|
|
|
2472
2484
|
const { json } = await this.request("/products/count.json");
|
|
2473
2485
|
return json?.count ?? 0;
|
|
2474
2486
|
}
|
|
2487
|
+
/**
|
|
2488
|
+
* Abandoned checkouts, newest first. Nitro's checkout webhook carries a real
|
|
2489
|
+
* recovery link, and the cart token inside it is what the receiving side looks
|
|
2490
|
+
* the checkout up by — so it has to come from a checkout that actually exists.
|
|
2491
|
+
*/
|
|
2492
|
+
async abandonedCheckouts({ limit = 10 } = {}) {
|
|
2493
|
+
const { json } = await this.request("/checkouts.json", { query: { limit } });
|
|
2494
|
+
return json?.checkouts ?? [];
|
|
2495
|
+
}
|
|
2496
|
+
/** Orders, newest first. */
|
|
2497
|
+
async orders({ limit = 10, status = "any" } = {}) {
|
|
2498
|
+
const { json } = await this.request("/orders.json", { query: { limit, status } });
|
|
2499
|
+
return json?.orders ?? [];
|
|
2500
|
+
}
|
|
2501
|
+
/**
|
|
2502
|
+
* Creates a real order. Receipts and inventory are suppressed: this exists to
|
|
2503
|
+
* give an order webhook something true to point at, not to trade.
|
|
2504
|
+
*/
|
|
2505
|
+
async createOrder(order) {
|
|
2506
|
+
const { json } = await this.request("/orders.json", {
|
|
2507
|
+
method: "POST",
|
|
2508
|
+
body: {
|
|
2509
|
+
order: {
|
|
2510
|
+
...order,
|
|
2511
|
+
send_receipt: false,
|
|
2512
|
+
send_fulfillment_receipt: false,
|
|
2513
|
+
inventory_behaviour: "bypass"
|
|
2514
|
+
}
|
|
2515
|
+
}
|
|
2516
|
+
});
|
|
2517
|
+
return json?.order ?? null;
|
|
2518
|
+
}
|
|
2475
2519
|
/**
|
|
2476
2520
|
* Collections, from both endpoints Shopify splits them across: custom
|
|
2477
2521
|
* (manually curated) and smart (rule based). Either can back a category page.
|
|
@@ -2866,7 +2910,7 @@ function loadPayload(file) {
|
|
|
2866
2910
|
}
|
|
2867
2911
|
|
|
2868
2912
|
// src/core/build.mjs
|
|
2869
|
-
function draftPayload({ cfg, providerId = "cashfree-occ", items, discount = 0, phone, eventName, collection, envelope }) {
|
|
2913
|
+
function draftPayload({ cfg, providerId = "cashfree-occ", items, discount = 0, phone, eventName, collection, envelope, live, delta }) {
|
|
2870
2914
|
const provider = getProvider(providerId);
|
|
2871
2915
|
const event = eventName ?? provider.defaultEvent;
|
|
2872
2916
|
const resolvedPhone = phone ?? cfg.customer.phone;
|
|
@@ -2878,6 +2922,8 @@ function draftPayload({ cfg, providerId = "cashfree-occ", items, discount = 0, p
|
|
|
2878
2922
|
eventName: event,
|
|
2879
2923
|
collection,
|
|
2880
2924
|
envelope,
|
|
2925
|
+
live,
|
|
2926
|
+
delta,
|
|
2881
2927
|
phone: parsed.ok ? parsed.value : String(resolvedPhone ?? "")
|
|
2882
2928
|
});
|
|
2883
2929
|
const editable = provider.editableFieldsFor ? provider.editableFieldsFor(event) : provider.editableFields;
|
|
@@ -2893,7 +2939,7 @@ function applyEdits(payload, fields, edits) {
|
|
|
2893
2939
|
}
|
|
2894
2940
|
return payload;
|
|
2895
2941
|
}
|
|
2896
|
-
async function buildPayload8({ cfg, providerId = "cashfree-occ", items = [], discount = 0, phone, checkImageUrls = true, payload: prebuilt, eventName, collection, envelope }) {
|
|
2942
|
+
async function buildPayload8({ cfg, providerId = "cashfree-occ", items = [], discount = 0, phone, checkImageUrls = true, payload: prebuilt, eventName, collection, envelope, live, delta }) {
|
|
2897
2943
|
const provider0 = getProvider(providerId);
|
|
2898
2944
|
const needsItems = !provider0.selectionFor || ["cart", "product"].includes(provider0.selectionFor(eventName ?? provider0.defaultEvent));
|
|
2899
2945
|
if (needsItems && !items.length) throw new ConfigError("no products selected");
|
|
@@ -2902,7 +2948,7 @@ async function buildPayload8({ cfg, providerId = "cashfree-occ", items = [], dis
|
|
|
2902
2948
|
const parsed = toE164(resolvedPhone, cfg.customer.countryCode);
|
|
2903
2949
|
if (!parsed.ok) throw new ConfigError(`phone is unusable: ${parsed.reason}`);
|
|
2904
2950
|
const event = eventName ?? provider.defaultEvent;
|
|
2905
|
-
const payload = prebuilt ?? provider.buildPayload({ config: cfg, items, discount, phone: parsed.value, eventName: event, collection, envelope });
|
|
2951
|
+
const payload = prebuilt ?? provider.buildPayload({ config: cfg, items, discount, phone: parsed.value, eventName: event, collection, envelope, live, delta });
|
|
2906
2952
|
const body = JSON.stringify(payload);
|
|
2907
2953
|
const report = await runAll({ payload, body, provider, config: cfg, checkImageUrls, eventName: event });
|
|
2908
2954
|
const summary = provider.summarize ? provider.summarize(payload) : {};
|
|
@@ -2930,6 +2976,80 @@ async function buildPayload8({ cfg, providerId = "cashfree-occ", items = [], dis
|
|
|
2930
2976
|
return { provider, payload, body, report, file, meta, summary, record };
|
|
2931
2977
|
}
|
|
2932
2978
|
|
|
2979
|
+
// src/shopify/live.mjs
|
|
2980
|
+
var LIVE_EVENTS = {
|
|
2981
|
+
nitro: /* @__PURE__ */ new Set(["checkout", "orders/create", "orders/updated"])
|
|
2982
|
+
};
|
|
2983
|
+
function needsLive(providerId, eventName) {
|
|
2984
|
+
return LIVE_EVENTS[providerId]?.has(eventName) ?? false;
|
|
2985
|
+
}
|
|
2986
|
+
function clientFor(config) {
|
|
2987
|
+
return new ShopifyClient({
|
|
2988
|
+
domain: config.shopify.domain,
|
|
2989
|
+
accessToken: config.shopify.accessToken,
|
|
2990
|
+
apiVersion: config.shopify.apiVersion
|
|
2991
|
+
});
|
|
2992
|
+
}
|
|
2993
|
+
async function liveCheckout({ config, items = [], client = clientFor(config) }) {
|
|
2994
|
+
const checkouts = await client.abandonedCheckouts({ limit: 20 });
|
|
2995
|
+
if (checkouts.length === 0) return null;
|
|
2996
|
+
const wanted = new Set(items.map(({ variant }) => Number(variant?.id)).filter(Boolean));
|
|
2997
|
+
const matching = checkouts.find((c2) => (c2.line_items ?? []).some((li) => wanted.has(Number(li.variant_id))));
|
|
2998
|
+
const checkout = matching ?? checkouts[0];
|
|
2999
|
+
return {
|
|
3000
|
+
kind: "checkout",
|
|
3001
|
+
url: checkout.abandoned_checkout_url,
|
|
3002
|
+
cartValue: money2(checkout.total_price ?? 0).toFixed(2),
|
|
3003
|
+
cartToken: checkout.cart_token,
|
|
3004
|
+
lineItems: checkout.line_items ?? []
|
|
3005
|
+
};
|
|
3006
|
+
}
|
|
3007
|
+
async function liveOrder({ config, items = [], phone, client = clientFor(config) }) {
|
|
3008
|
+
const cust = config.customer ?? {};
|
|
3009
|
+
const lineItems = items.map(({ variant, product, quantity }) => ({
|
|
3010
|
+
variant_id: Number(variant?.id ?? product?.id),
|
|
3011
|
+
quantity: Number(quantity) || 1
|
|
3012
|
+
})).filter((li) => Number.isFinite(li.variant_id) && li.variant_id > 0);
|
|
3013
|
+
if (lineItems.length === 0) return null;
|
|
3014
|
+
const order = await client.createOrder({
|
|
3015
|
+
line_items: lineItems,
|
|
3016
|
+
financial_status: "paid",
|
|
3017
|
+
email: cust.email || void 0,
|
|
3018
|
+
phone: phone || cust.phone || void 0,
|
|
3019
|
+
customer: cust.email || cust.firstName ? { first_name: cust.firstName, last_name: cust.lastName, email: cust.email } : void 0,
|
|
3020
|
+
shipping_address: cust.address1 ? {
|
|
3021
|
+
first_name: cust.firstName,
|
|
3022
|
+
last_name: cust.lastName,
|
|
3023
|
+
address1: cust.address1,
|
|
3024
|
+
address2: cust.address2 || void 0,
|
|
3025
|
+
city: cust.city,
|
|
3026
|
+
province: cust.province,
|
|
3027
|
+
country_code: cust.countryCode,
|
|
3028
|
+
zip: cust.zip,
|
|
3029
|
+
phone: phone || cust.phone || void 0
|
|
3030
|
+
} : void 0,
|
|
3031
|
+
tags: "hookwright",
|
|
3032
|
+
note: "created by hookwright for webhook testing"
|
|
3033
|
+
});
|
|
3034
|
+
if (!order) return null;
|
|
3035
|
+
return {
|
|
3036
|
+
kind: "order",
|
|
3037
|
+
id: Number(order.id),
|
|
3038
|
+
number: Number(order.order_number),
|
|
3039
|
+
name: order.name,
|
|
3040
|
+
price: String(order.total_price ?? "0.00"),
|
|
3041
|
+
currency: order.currency,
|
|
3042
|
+
createdAt: order.created_at,
|
|
3043
|
+
statusUrl: order.order_status_url
|
|
3044
|
+
};
|
|
3045
|
+
}
|
|
3046
|
+
async function resolveLive({ config, providerId, eventName, items, phone, client }) {
|
|
3047
|
+
if (!needsLive(providerId, eventName)) return null;
|
|
3048
|
+
if (!config?.shopify?.domain || !config?.shopify?.accessToken) return null;
|
|
3049
|
+
if (eventName === "checkout") return await liveCheckout({ config, items, ...client ? { client } : {} });
|
|
3050
|
+
return await liveOrder({ config, items, phone, ...client ? { client } : {} });
|
|
3051
|
+
}
|
|
3052
|
+
|
|
2933
3053
|
// src/core/send.mjs
|
|
2934
3054
|
import fs4 from "node:fs";
|
|
2935
3055
|
import path4 from "node:path";
|
|
@@ -3107,7 +3227,9 @@ var STEP = {
|
|
|
3107
3227
|
PICK: "pick",
|
|
3108
3228
|
VARIANT: "variant",
|
|
3109
3229
|
QUANTITY: "quantity",
|
|
3230
|
+
DELTA: "delta",
|
|
3110
3231
|
DISCOUNT: "discount",
|
|
3232
|
+
LIVE: "live",
|
|
3111
3233
|
MODE: "mode",
|
|
3112
3234
|
FIELDS: "fields",
|
|
3113
3235
|
BUILDING: "building",
|
|
@@ -3130,6 +3252,8 @@ function Build({ config, providerId = "cashfree-occ", onDone }) {
|
|
|
3130
3252
|
const [cursor, setCursor] = useState(0);
|
|
3131
3253
|
const [items, setItems] = useState([]);
|
|
3132
3254
|
const [pendingVariant, setPendingVariant] = useState(null);
|
|
3255
|
+
const [delta, setDelta] = useState([]);
|
|
3256
|
+
const isDeltaEvent = providerId === "nitro" && (eventName === "addtocart" || eventName === "removefromcart");
|
|
3133
3257
|
const [draft, setDraft] = useState(null);
|
|
3134
3258
|
const [fieldIndex, setFieldIndex] = useState(0);
|
|
3135
3259
|
const [edits, setEdits] = useState({});
|
|
@@ -3163,6 +3287,9 @@ function Build({ config, providerId = "cashfree-occ", onDone }) {
|
|
|
3163
3287
|
setItems(items.slice(0, -1));
|
|
3164
3288
|
return stepInto(last);
|
|
3165
3289
|
}
|
|
3290
|
+
case STEP.DELTA:
|
|
3291
|
+
return setStep(STEP.PICK);
|
|
3292
|
+
case STEP.LIVE:
|
|
3166
3293
|
case STEP.MODE:
|
|
3167
3294
|
return setStep(STEP.DISCOUNT);
|
|
3168
3295
|
case STEP.FIELDS:
|
|
@@ -3250,7 +3377,8 @@ function Build({ config, providerId = "cashfree-occ", onDone }) {
|
|
|
3250
3377
|
const advance = (nextItems, nextCursor) => {
|
|
3251
3378
|
if (nextCursor >= chosen.length) {
|
|
3252
3379
|
setItems(nextItems);
|
|
3253
|
-
if (
|
|
3380
|
+
if (isDeltaEvent) setStep(STEP.DELTA);
|
|
3381
|
+
else if (selection === "cart") setStep(STEP.DISCOUNT);
|
|
3254
3382
|
else startReview(0, collection, nextItems);
|
|
3255
3383
|
return;
|
|
3256
3384
|
}
|
|
@@ -3306,27 +3434,40 @@ function Build({ config, providerId = "cashfree-occ", onDone }) {
|
|
|
3306
3434
|
const nextItems = [...items, { product, variant: pendingVariant, quantity: qty }];
|
|
3307
3435
|
advance(nextItems, cursor + 1);
|
|
3308
3436
|
};
|
|
3309
|
-
const startReview = (discount, chosenCollection = collection, chosenItems = items) => {
|
|
3437
|
+
const startReview = async (discount, chosenCollection = collection, chosenItems = items, chosenDelta = delta) => {
|
|
3310
3438
|
try {
|
|
3439
|
+
let live = null;
|
|
3440
|
+
if (needsLive(providerId, eventName)) {
|
|
3441
|
+
setStep(STEP.LIVE);
|
|
3442
|
+
live = await resolveLive({ config, providerId, eventName, items: chosenItems, phone: config.customer.phone });
|
|
3443
|
+
}
|
|
3311
3444
|
const next = draftPayload({
|
|
3312
3445
|
cfg: config,
|
|
3313
3446
|
providerId,
|
|
3314
3447
|
items: chosenItems,
|
|
3315
3448
|
discount,
|
|
3316
3449
|
eventName,
|
|
3317
|
-
collection: chosenCollection
|
|
3450
|
+
collection: chosenCollection,
|
|
3451
|
+
live,
|
|
3452
|
+
delta: chosenDelta
|
|
3318
3453
|
});
|
|
3319
|
-
setDraft({ ...next, discount });
|
|
3454
|
+
setDraft({ ...next, discount, live, delta: chosenDelta });
|
|
3320
3455
|
setStep(STEP.MODE);
|
|
3321
3456
|
} catch (err) {
|
|
3322
3457
|
setError({ message: err.message, hint: err.hint, failures: err.failures });
|
|
3323
3458
|
setStep(STEP.ERROR);
|
|
3324
3459
|
}
|
|
3325
3460
|
};
|
|
3461
|
+
const onDelta = (ids) => {
|
|
3462
|
+
const picked = items.filter((i) => ids.includes(String(i.variant?.id ?? i.product?.id)));
|
|
3463
|
+
if (!picked.length) return;
|
|
3464
|
+
setDelta(picked);
|
|
3465
|
+
startReview(0, collection, items, picked);
|
|
3466
|
+
};
|
|
3326
3467
|
const onDiscount = (raw) => startReview(Math.max(0, Number.parseFloat(raw) || 0));
|
|
3327
3468
|
const finalise = (payload) => {
|
|
3328
3469
|
setStep(STEP.BUILDING);
|
|
3329
|
-
buildPayload8({ cfg: config, providerId, items, discount: draft.discount, payload, eventName, collection }).then(async (result) => {
|
|
3470
|
+
buildPayload8({ cfg: config, providerId, items, discount: draft.discount, payload, eventName, collection, live: draft.live, delta: draft.delta }).then(async (result) => {
|
|
3330
3471
|
setBuilt(result);
|
|
3331
3472
|
let req = null;
|
|
3332
3473
|
let command = "";
|
|
@@ -3400,6 +3541,7 @@ function Build({ config, providerId = "cashfree-occ", onDone }) {
|
|
|
3400
3541
|
) })
|
|
3401
3542
|
] }),
|
|
3402
3543
|
step === STEP.LOADING && /* @__PURE__ */ jsx8(Spinner, { label: `fetching live products from ${store}\u2026` }),
|
|
3544
|
+
step === STEP.LIVE && /* @__PURE__ */ jsx8(Spinner, { label: eventName === "checkout" ? `finding a real abandoned checkout in ${store}\u2026` : `creating a real order in ${store}\u2026` }),
|
|
3403
3545
|
step === STEP.COLLECTION && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
3404
3546
|
/* @__PURE__ */ jsx8(Text8, { children: "Which collection was viewed?" }),
|
|
3405
3547
|
/* @__PURE__ */ jsx8(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx8(
|
|
@@ -3445,6 +3587,24 @@ function Build({ config, providerId = "cashfree-occ", onDone }) {
|
|
|
3445
3587
|
}
|
|
3446
3588
|
) })
|
|
3447
3589
|
] }),
|
|
3590
|
+
step === STEP.DELTA && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
3591
|
+
/* @__PURE__ */ jsxs8(Text8, { children: [
|
|
3592
|
+
eventName === "addtocart" ? "Which of those lines is the shopper adding now? " : "Which of those lines is the shopper removing? ",
|
|
3593
|
+
/* @__PURE__ */ jsx8(Text8, { color: palette.dim, children: "(space toggles \xB7 enter confirms)" })
|
|
3594
|
+
] }),
|
|
3595
|
+
/* @__PURE__ */ jsx8(Text8, { color: palette.dim, children: eventName === "addtocart" ? "The rest were already in the cart." : "The rest stay in the cart." }),
|
|
3596
|
+
/* @__PURE__ */ jsx8(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx8(
|
|
3597
|
+
MultiSelect,
|
|
3598
|
+
{
|
|
3599
|
+
visibleOptionCount: 10,
|
|
3600
|
+
options: items.map((i) => ({
|
|
3601
|
+
label: `${truncate(i.product.title, 40).padEnd(41)} x${String(i.quantity).padEnd(3)} ${money(i.variant?.price, currency)}`,
|
|
3602
|
+
value: String(i.variant?.id ?? i.product?.id)
|
|
3603
|
+
})),
|
|
3604
|
+
onSubmit: onDelta
|
|
3605
|
+
}
|
|
3606
|
+
) })
|
|
3607
|
+
] }),
|
|
3448
3608
|
step === STEP.VARIANT && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
3449
3609
|
/* @__PURE__ */ jsxs8(Text8, { children: [
|
|
3450
3610
|
`Variant for `,
|
|
@@ -4570,10 +4730,19 @@ async function cmdBuild(args, config) {
|
|
|
4570
4730
|
} else {
|
|
4571
4731
|
log.ok(`${eventName} needs no product or collection`);
|
|
4572
4732
|
}
|
|
4733
|
+
let live = null;
|
|
4734
|
+
if (needsLive(providerId, eventName)) {
|
|
4735
|
+
log.step(eventName === "checkout" ? `finding a real abandoned checkout in ${config.shopify.domain}\u2026` : `creating a real order in ${config.shopify.domain}\u2026`);
|
|
4736
|
+
live = await resolveLive({ config, providerId, eventName, items, phone: typeof args.flags.phone === "string" ? args.flags.phone : void 0 });
|
|
4737
|
+
if (live?.kind === "checkout") log.ok(`checkout cart token ${live.cartToken}`);
|
|
4738
|
+
else if (live?.kind === "order") log.ok(`order ${live.name} (${live.id})`);
|
|
4739
|
+
else log.warn("no live record available \u2014 falling back to a generated one");
|
|
4740
|
+
}
|
|
4573
4741
|
const built = await buildPayload8({
|
|
4574
4742
|
cfg: config,
|
|
4575
4743
|
providerId,
|
|
4576
4744
|
eventName,
|
|
4745
|
+
live,
|
|
4577
4746
|
collection,
|
|
4578
4747
|
envelope: typeof args.flags.envelope === "string" ? args.flags.envelope : void 0,
|
|
4579
4748
|
items,
|