@drawbridge/drawbridge-utils 0.0.171 → 0.0.172
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/connections/index.cjs +16 -13
- package/dist/connections/index.d.cts +84 -26
- package/dist/connections/index.d.ts +84 -26
- package/dist/connections/index.js +16 -13
- package/dist/providers.cjs +16 -13
- package/dist/providers.js +16 -13
- package/package.json +2 -2
|
@@ -618,6 +618,7 @@ var row = ({ connection: connection2, data: data2, manifest, row: described }) =
|
|
|
618
618
|
};
|
|
619
619
|
};
|
|
620
620
|
var segmentRowWrites = ({ connection: connection2, data: data2, manifest, row: described, segment }) => {
|
|
621
|
+
if ((described == null ? void 0 : described.id) === void 0 || (described == null ? void 0 : described.id) === null) return [];
|
|
621
622
|
const built = row({ connection: connection2, data: data2, manifest, row: described });
|
|
622
623
|
return [
|
|
623
624
|
// PUSH IF ABSENT. The $ne guard is what makes a second concurrent register
|
|
@@ -3090,7 +3091,7 @@ var api2 = async (path, { fetcher = fetch, method = "GET", payload, token }) =>
|
|
|
3090
3091
|
}
|
|
3091
3092
|
return response.status === 204 ? null : response.json();
|
|
3092
3093
|
};
|
|
3093
|
-
var segmentName = (title) => "Drawbridge: " + title;
|
|
3094
|
+
var segmentName = (title, id) => "Drawbridge: " + title + " (" + String(id).slice(-6) + ")";
|
|
3094
3095
|
var canManageSegments = (settings) => String((settings == null ? void 0 : settings.scope) || "").split(/\s+/).includes("segments:write");
|
|
3095
3096
|
var klaviyo_default2 = {
|
|
3096
3097
|
// OAuth 2.1, and PKCE is REQUIRED rather than recommended: Klaviyo refuses an
|
|
@@ -3465,7 +3466,7 @@ var klaviyo_default2 = {
|
|
|
3465
3466
|
skipped: true
|
|
3466
3467
|
};
|
|
3467
3468
|
}
|
|
3468
|
-
const name = segmentName(segment.title);
|
|
3469
|
+
const name = segmentName(segment.title, segment.id);
|
|
3469
3470
|
const existing = segmentRowFor({ connection: connection2, segment });
|
|
3470
3471
|
let id = null;
|
|
3471
3472
|
if (existing == null ? void 0 : existing.id) {
|
|
@@ -3872,7 +3873,10 @@ var api3 = async (path, { dc, fetcher = fetch, method = "GET", payload, token })
|
|
|
3872
3873
|
};
|
|
3873
3874
|
var subscriberHash = (email) => (0, import_node_crypto5.createHash)("md5").update(String(email).trim().toLowerCase()).digest("hex");
|
|
3874
3875
|
var TAG_NAME_LIMIT = 100;
|
|
3875
|
-
var tagName = (title) =>
|
|
3876
|
+
var tagName = (title, id) => {
|
|
3877
|
+
const suffix = " (" + String(id).slice(-6) + ")";
|
|
3878
|
+
return ("Drawbridge: " + title).slice(0, TAG_NAME_LIMIT - suffix.length) + suffix;
|
|
3879
|
+
};
|
|
3876
3880
|
var mailchimp_default2 = {
|
|
3877
3881
|
// OAUTH 2, authorization code. Every url below is quoted from
|
|
3878
3882
|
// mailchimp.com/developer/marketing/guides/access-user-data-oauth-2/ rather
|
|
@@ -4053,14 +4057,17 @@ var mailchimp_default2 = {
|
|
|
4053
4057
|
}
|
|
4054
4058
|
},
|
|
4055
4059
|
{
|
|
4056
|
-
|
|
4060
|
+
// THE ID AS WELL AS THE TITLE, because the tag name carries it —
|
|
4061
|
+
// see tagName. Without it every name here would end in the
|
|
4062
|
+
// string 'undefined' and match nothing register wrote.
|
|
4063
|
+
$project: { _id: 0, id: 1, title: 1 }
|
|
4057
4064
|
}
|
|
4058
4065
|
]
|
|
4059
4066
|
});
|
|
4060
|
-
const joined = new Set(segments.map((entry) => entry.
|
|
4061
|
-
const tags = (owned || []).
|
|
4062
|
-
name: tagName(title),
|
|
4063
|
-
status: joined.has(
|
|
4067
|
+
const joined = new Set(segments.map((entry) => entry.id));
|
|
4068
|
+
const tags = (owned || []).filter((entry) => entry.id && entry.title).map((entry) => ({
|
|
4069
|
+
name: tagName(entry.title, entry.id),
|
|
4070
|
+
status: joined.has(entry.id) ? "active" : "inactive"
|
|
4064
4071
|
}));
|
|
4065
4072
|
if (tags.length > 0) {
|
|
4066
4073
|
await api3("/lists/" + audience + "/members/" + hash + "/tags", {
|
|
@@ -4112,7 +4119,7 @@ var mailchimp_default2 = {
|
|
|
4112
4119
|
if (!audience) return { message: "No Mailchimp audience is chosen for this connection.", skipped: true };
|
|
4113
4120
|
const segment = await currentSegment({ read, segment: context == null ? void 0 : context.segment });
|
|
4114
4121
|
if (!(segment == null ? void 0 : segment.id) || segment.system) return { message: "That segment is not one this connection publishes.", skipped: true };
|
|
4115
|
-
const name = tagName(segment.title);
|
|
4122
|
+
const name = tagName(segment.title, segment.id);
|
|
4116
4123
|
const existing = segmentRowFor({ connection: connection2, segment });
|
|
4117
4124
|
let id = null;
|
|
4118
4125
|
if (existing == null ? void 0 : existing.id) {
|
|
@@ -4665,10 +4672,6 @@ var shopify_default2 = {
|
|
|
4665
4672
|
if (!(context == null ? void 0 : context.lead)) return { message: "Lead id is missing.", request: request2, response: { skipped: true }, skipped: true };
|
|
4666
4673
|
if (!(discount == null ? void 0 : discount.id)) return { message: "Discount is not configured on this step.", request: request2, response: { skipped: true }, skipped: true };
|
|
4667
4674
|
const adminAccessToken = await adminToken();
|
|
4668
|
-
if (!context.shopifyCustomerId) {
|
|
4669
|
-
const customer = await shopify.admin.getOrCreateCustomer({ adminAccessToken, domain: connection2.shop, email: context.email });
|
|
4670
|
-
if (!(customer == null ? void 0 : customer.id)) return { message: "Shopify did not return a customer id \u2014 create/lookup failed.", request: request2, response: { skipped: true }, skipped: true };
|
|
4671
|
-
}
|
|
4672
4675
|
const discountCode = await shopify.admin.createDiscountCode({
|
|
4673
4676
|
adminAccessToken,
|
|
4674
4677
|
code: "DB-" + generateDiscountCode(),
|
|
@@ -854,6 +854,13 @@ const row = ({ connection, data, manifest, row : described }) => ({
|
|
|
854
854
|
|
|
855
855
|
const segmentRowWrites = ({ connection, data, manifest, row : described, segment }) => {
|
|
856
856
|
|
|
857
|
+
// NO ID, NO ROW. `String( undefined )` is the string 'undefined', which is a
|
|
858
|
+
// perfectly valid string as far as the api's schema is concerned — so a row
|
|
859
|
+
// built without a vendor id would store and then render as a live-looking
|
|
860
|
+
// link to an object that does not exist. The three hooks all guard before
|
|
861
|
+
// they get here; this is the guard that does not depend on them remembering.
|
|
862
|
+
if( described?.id === undefined || described?.id === null ) return [];
|
|
863
|
+
|
|
857
864
|
const built = row({ connection, data, manifest, row : described });
|
|
858
865
|
|
|
859
866
|
return [
|
|
@@ -3531,7 +3538,30 @@ const api$1 = async ( path, { fetcher = fetch, method = 'GET', payload, token }
|
|
|
3531
3538
|
|
|
3532
3539
|
// The segment's name at Klaviyo, spelled once. It is a LABEL — the definition
|
|
3533
3540
|
// below keys on the id — so a rename never has to touch a profile.
|
|
3534
|
-
|
|
3541
|
+
//
|
|
3542
|
+
// THE ID IS IN THE LABEL TOO, and that part is not cosmetic. Nothing makes a
|
|
3543
|
+
// THE ID IS IN THE NAME BECAUSE THE NAME IS NOT AN IDENTITY. Keyed on title
|
|
3544
|
+
// alone, a second segment called "VIP" found the first one's Klaviyo segment by
|
|
3545
|
+
// name and adopted it: both rows then pointed at one segment whose definition
|
|
3546
|
+
// computes the FIRST one's membership, so the merchant sent to the wrong people,
|
|
3547
|
+
// and deleting either segment deleted that object out from under the other with
|
|
3548
|
+
// nothing to repair it.
|
|
3549
|
+
//
|
|
3550
|
+
// The api now carries a unique index on (organization, title) and a 409 on both
|
|
3551
|
+
// create and rename, so that pair can no longer be created. The suffix stays
|
|
3552
|
+
// anyway: it is what makes the damage impossible rather than merely unlikely,
|
|
3553
|
+
// and it is the only part of this that holds if a title ever reaches Klaviyo
|
|
3554
|
+
// from somewhere that did not go through the route.
|
|
3555
|
+
//
|
|
3556
|
+
// KLAVIYO IS NOT DOING THIS FOR US. Create Segment describes `name` only as "A
|
|
3557
|
+
// helpful name to label the segment" and documents no uniqueness constraint and
|
|
3558
|
+
// no duplicate-name error (developers.klaviyo.com/en/reference/create_segment,
|
|
3559
|
+
// fetched 2026-09-12), so the search cannot lean on the vendor. What IS
|
|
3560
|
+
// documented is that filter comparisons are case-sensitive
|
|
3561
|
+
// (developers.klaviyo.com/en/docs/filtering_, same date), which is why the
|
|
3562
|
+
// find-by-name below re-checks with === and agrees with the vendor rather than
|
|
3563
|
+
// guessing.
|
|
3564
|
+
const segmentName = ( title, id ) => 'Drawbridge: ' + title + ' (' + String( id ).slice( -6 ) + ')';
|
|
3535
3565
|
|
|
3536
3566
|
// THE GRANT THIS NEEDS. Klaviyo's scopes are set on the app and a token carries
|
|
3537
3567
|
// only what the merchant consented to, so a connection made before segments were
|
|
@@ -4047,7 +4077,7 @@ var klaviyo = {
|
|
|
4047
4077
|
|
|
4048
4078
|
}
|
|
4049
4079
|
|
|
4050
|
-
const name = segmentName( segment.title );
|
|
4080
|
+
const name = segmentName( segment.title, segment.id );
|
|
4051
4081
|
const existing = segmentRowFor({ connection, segment });
|
|
4052
4082
|
|
|
4053
4083
|
let id = null;
|
|
@@ -4657,13 +4687,29 @@ const subscriberHash = ( email ) => createHash( 'md5' )
|
|
|
4657
4687
|
// server-side truncation is the worse outcome because register would then look
|
|
4658
4688
|
// for a name Mailchimp had silently changed.
|
|
4659
4689
|
//
|
|
4660
|
-
//
|
|
4661
|
-
//
|
|
4662
|
-
//
|
|
4663
|
-
//
|
|
4690
|
+
// THE SEGMENT ID IS IN THE NAME, and it has to be. Nothing makes a Drawbridge
|
|
4691
|
+
// segment title unique — no index on the collection, no check in the route, no
|
|
4692
|
+
// check in the form — so two segments called "VIP" are ordinary. Keyed on title
|
|
4693
|
+
// alone, the second one's register finds the first one's tag, adopts it, and
|
|
4694
|
+
// both rows point at one object: the merchant's two segments are one tag, and
|
|
4695
|
+
// deleting either segment deletes the tag out from under the other, leaving a
|
|
4696
|
+
// row pointing at an id that no longer exists and nothing to repair it.
|
|
4697
|
+
//
|
|
4698
|
+
// The last six characters of the id are enough to separate them and short
|
|
4699
|
+
// enough to leave the title readable in the merchant's own audience.
|
|
4700
|
+
//
|
|
4701
|
+
// A rename now changes the name and keeps the suffix, so register's find-by-name
|
|
4702
|
+
// still matches after one — and the truncation below cuts the TITLE rather than
|
|
4703
|
+
// the suffix for the same reason.
|
|
4664
4704
|
const TAG_NAME_LIMIT = 100;
|
|
4665
4705
|
|
|
4666
|
-
const tagName = ( title ) =>
|
|
4706
|
+
const tagName = ( title, id ) => {
|
|
4707
|
+
|
|
4708
|
+
const suffix = ' (' + String( id ).slice( -6 ) + ')';
|
|
4709
|
+
|
|
4710
|
+
return ( 'Drawbridge: ' + title ).slice( 0, TAG_NAME_LIMIT - suffix.length ) + suffix;
|
|
4711
|
+
|
|
4712
|
+
};
|
|
4667
4713
|
|
|
4668
4714
|
// Mailchimp — contact sync, not a sender.
|
|
4669
4715
|
var mailchimp = {
|
|
@@ -4958,19 +5004,21 @@ var mailchimp = {
|
|
|
4958
5004
|
}
|
|
4959
5005
|
},
|
|
4960
5006
|
{
|
|
4961
|
-
|
|
5007
|
+
// THE ID AS WELL AS THE TITLE, because the tag name carries it —
|
|
5008
|
+
// see tagName. Without it every name here would end in the
|
|
5009
|
+
// string 'undefined' and match nothing register wrote.
|
|
5010
|
+
$project : { _id : 0, id : 1, title : 1 }
|
|
4962
5011
|
}
|
|
4963
5012
|
]
|
|
4964
5013
|
});
|
|
4965
5014
|
|
|
4966
|
-
const joined = new Set( segments.map( ( entry ) => entry.
|
|
5015
|
+
const joined = new Set( segments.map( ( entry ) => entry.id ) );
|
|
4967
5016
|
|
|
4968
5017
|
const tags = ( owned || [] )
|
|
4969
|
-
.
|
|
4970
|
-
.
|
|
4971
|
-
|
|
4972
|
-
|
|
4973
|
-
status : joined.has( title ) ? 'active' : 'inactive'
|
|
5018
|
+
.filter( ( entry ) => entry.id && entry.title )
|
|
5019
|
+
.map( ( entry ) => ({
|
|
5020
|
+
name : tagName( entry.title, entry.id ),
|
|
5021
|
+
status : joined.has( entry.id ) ? 'active' : 'inactive'
|
|
4974
5022
|
}) );
|
|
4975
5023
|
|
|
4976
5024
|
if( tags.length > 0 ){
|
|
@@ -5040,7 +5088,7 @@ var mailchimp = {
|
|
|
5040
5088
|
|
|
5041
5089
|
if( ! segment?.id || segment.system ) return { message : 'That segment is not one this connection publishes.', skipped : true };
|
|
5042
5090
|
|
|
5043
|
-
const name = tagName( segment.title );
|
|
5091
|
+
const name = tagName( segment.title, segment.id );
|
|
5044
5092
|
const existing = segmentRowFor({ connection, segment });
|
|
5045
5093
|
|
|
5046
5094
|
let id = null;
|
|
@@ -5768,23 +5816,33 @@ var shopify = {
|
|
|
5768
5816
|
|
|
5769
5817
|
const request = { email : context?.email || null, lead : context?.lead || null, shop : connection.shop };
|
|
5770
5818
|
|
|
5819
|
+
// KEPT even though nothing below sends the address anywhere. A code
|
|
5820
|
+
// that reaches nobody is a wasted action and a merchant's wasted
|
|
5821
|
+
// allowance: issuing is only half a workflow, and the email step after
|
|
5822
|
+
// it needs somewhere to send the code.
|
|
5771
5823
|
if( ! context?.email ) return { message : 'Lead email is missing.', request, response : { skipped : true }, skipped : true };
|
|
5772
5824
|
if( ! context?.lead ) return { message : 'Lead id is missing.', request, response : { skipped : true }, skipped : true };
|
|
5773
5825
|
if( ! discount?.id ) return { message : 'Discount is not configured on this step.', request, response : { skipped : true }, skipped : true };
|
|
5774
5826
|
|
|
5775
5827
|
const adminAccessToken = await adminToken();
|
|
5776
5828
|
|
|
5777
|
-
//
|
|
5778
|
-
//
|
|
5779
|
-
//
|
|
5780
|
-
|
|
5781
|
-
|
|
5782
|
-
|
|
5783
|
-
|
|
5784
|
-
|
|
5785
|
-
|
|
5786
|
-
|
|
5787
|
-
|
|
5829
|
+
// NOTHING IS SENT TO SHOPIFY TO LINK THE CODE TO THE PERSON, because
|
|
5830
|
+
// there is nothing to send: discountRedeemCodeBulkAdd takes a discount
|
|
5831
|
+
// and a list of codes, and no customer
|
|
5832
|
+
// (shopify.dev/docs/api/admin-graphql/2026-04/mutations/discountRedeemCodeBulkAdd).
|
|
5833
|
+
// The link lives entirely on our side — `lead.shopifyDiscountCode`
|
|
5834
|
+
// below — and attribution happens when the order comes back carrying
|
|
5835
|
+
// the code, matched org-scoped against that field by commerce.order.
|
|
5836
|
+
//
|
|
5837
|
+
// This step used to call getOrCreateCustomer first, on the stated
|
|
5838
|
+
// reasoning that "the customer must exist before a code is mapped to
|
|
5839
|
+
// them". No code was ever mapped to them: the result was assigned and
|
|
5840
|
+
// discarded, createDiscountCode never received it, and redemption
|
|
5841
|
+
// attribution never consulted it. All it did was create a customer in
|
|
5842
|
+
// the merchant's store as a side effect of issuing a discount — which
|
|
5843
|
+
// QA reported as surprising, and was right to. A merchant who wants the
|
|
5844
|
+
// buyer to exist at the store adds the Create customer step, which is
|
|
5845
|
+
// what that step is for.
|
|
5788
5846
|
const discountCode = await shopify.admin.createDiscountCode({
|
|
5789
5847
|
adminAccessToken,
|
|
5790
5848
|
code : 'DB-' + generateDiscountCode(),
|
|
@@ -854,6 +854,13 @@ const row = ({ connection, data, manifest, row : described }) => ({
|
|
|
854
854
|
|
|
855
855
|
const segmentRowWrites = ({ connection, data, manifest, row : described, segment }) => {
|
|
856
856
|
|
|
857
|
+
// NO ID, NO ROW. `String( undefined )` is the string 'undefined', which is a
|
|
858
|
+
// perfectly valid string as far as the api's schema is concerned — so a row
|
|
859
|
+
// built without a vendor id would store and then render as a live-looking
|
|
860
|
+
// link to an object that does not exist. The three hooks all guard before
|
|
861
|
+
// they get here; this is the guard that does not depend on them remembering.
|
|
862
|
+
if( described?.id === undefined || described?.id === null ) return [];
|
|
863
|
+
|
|
857
864
|
const built = row({ connection, data, manifest, row : described });
|
|
858
865
|
|
|
859
866
|
return [
|
|
@@ -3531,7 +3538,30 @@ const api$1 = async ( path, { fetcher = fetch, method = 'GET', payload, token }
|
|
|
3531
3538
|
|
|
3532
3539
|
// The segment's name at Klaviyo, spelled once. It is a LABEL — the definition
|
|
3533
3540
|
// below keys on the id — so a rename never has to touch a profile.
|
|
3534
|
-
|
|
3541
|
+
//
|
|
3542
|
+
// THE ID IS IN THE LABEL TOO, and that part is not cosmetic. Nothing makes a
|
|
3543
|
+
// THE ID IS IN THE NAME BECAUSE THE NAME IS NOT AN IDENTITY. Keyed on title
|
|
3544
|
+
// alone, a second segment called "VIP" found the first one's Klaviyo segment by
|
|
3545
|
+
// name and adopted it: both rows then pointed at one segment whose definition
|
|
3546
|
+
// computes the FIRST one's membership, so the merchant sent to the wrong people,
|
|
3547
|
+
// and deleting either segment deleted that object out from under the other with
|
|
3548
|
+
// nothing to repair it.
|
|
3549
|
+
//
|
|
3550
|
+
// The api now carries a unique index on (organization, title) and a 409 on both
|
|
3551
|
+
// create and rename, so that pair can no longer be created. The suffix stays
|
|
3552
|
+
// anyway: it is what makes the damage impossible rather than merely unlikely,
|
|
3553
|
+
// and it is the only part of this that holds if a title ever reaches Klaviyo
|
|
3554
|
+
// from somewhere that did not go through the route.
|
|
3555
|
+
//
|
|
3556
|
+
// KLAVIYO IS NOT DOING THIS FOR US. Create Segment describes `name` only as "A
|
|
3557
|
+
// helpful name to label the segment" and documents no uniqueness constraint and
|
|
3558
|
+
// no duplicate-name error (developers.klaviyo.com/en/reference/create_segment,
|
|
3559
|
+
// fetched 2026-09-12), so the search cannot lean on the vendor. What IS
|
|
3560
|
+
// documented is that filter comparisons are case-sensitive
|
|
3561
|
+
// (developers.klaviyo.com/en/docs/filtering_, same date), which is why the
|
|
3562
|
+
// find-by-name below re-checks with === and agrees with the vendor rather than
|
|
3563
|
+
// guessing.
|
|
3564
|
+
const segmentName = ( title, id ) => 'Drawbridge: ' + title + ' (' + String( id ).slice( -6 ) + ')';
|
|
3535
3565
|
|
|
3536
3566
|
// THE GRANT THIS NEEDS. Klaviyo's scopes are set on the app and a token carries
|
|
3537
3567
|
// only what the merchant consented to, so a connection made before segments were
|
|
@@ -4047,7 +4077,7 @@ var klaviyo = {
|
|
|
4047
4077
|
|
|
4048
4078
|
}
|
|
4049
4079
|
|
|
4050
|
-
const name = segmentName( segment.title );
|
|
4080
|
+
const name = segmentName( segment.title, segment.id );
|
|
4051
4081
|
const existing = segmentRowFor({ connection, segment });
|
|
4052
4082
|
|
|
4053
4083
|
let id = null;
|
|
@@ -4657,13 +4687,29 @@ const subscriberHash = ( email ) => createHash( 'md5' )
|
|
|
4657
4687
|
// server-side truncation is the worse outcome because register would then look
|
|
4658
4688
|
// for a name Mailchimp had silently changed.
|
|
4659
4689
|
//
|
|
4660
|
-
//
|
|
4661
|
-
//
|
|
4662
|
-
//
|
|
4663
|
-
//
|
|
4690
|
+
// THE SEGMENT ID IS IN THE NAME, and it has to be. Nothing makes a Drawbridge
|
|
4691
|
+
// segment title unique — no index on the collection, no check in the route, no
|
|
4692
|
+
// check in the form — so two segments called "VIP" are ordinary. Keyed on title
|
|
4693
|
+
// alone, the second one's register finds the first one's tag, adopts it, and
|
|
4694
|
+
// both rows point at one object: the merchant's two segments are one tag, and
|
|
4695
|
+
// deleting either segment deletes the tag out from under the other, leaving a
|
|
4696
|
+
// row pointing at an id that no longer exists and nothing to repair it.
|
|
4697
|
+
//
|
|
4698
|
+
// The last six characters of the id are enough to separate them and short
|
|
4699
|
+
// enough to leave the title readable in the merchant's own audience.
|
|
4700
|
+
//
|
|
4701
|
+
// A rename now changes the name and keeps the suffix, so register's find-by-name
|
|
4702
|
+
// still matches after one — and the truncation below cuts the TITLE rather than
|
|
4703
|
+
// the suffix for the same reason.
|
|
4664
4704
|
const TAG_NAME_LIMIT = 100;
|
|
4665
4705
|
|
|
4666
|
-
const tagName = ( title ) =>
|
|
4706
|
+
const tagName = ( title, id ) => {
|
|
4707
|
+
|
|
4708
|
+
const suffix = ' (' + String( id ).slice( -6 ) + ')';
|
|
4709
|
+
|
|
4710
|
+
return ( 'Drawbridge: ' + title ).slice( 0, TAG_NAME_LIMIT - suffix.length ) + suffix;
|
|
4711
|
+
|
|
4712
|
+
};
|
|
4667
4713
|
|
|
4668
4714
|
// Mailchimp — contact sync, not a sender.
|
|
4669
4715
|
var mailchimp = {
|
|
@@ -4958,19 +5004,21 @@ var mailchimp = {
|
|
|
4958
5004
|
}
|
|
4959
5005
|
},
|
|
4960
5006
|
{
|
|
4961
|
-
|
|
5007
|
+
// THE ID AS WELL AS THE TITLE, because the tag name carries it —
|
|
5008
|
+
// see tagName. Without it every name here would end in the
|
|
5009
|
+
// string 'undefined' and match nothing register wrote.
|
|
5010
|
+
$project : { _id : 0, id : 1, title : 1 }
|
|
4962
5011
|
}
|
|
4963
5012
|
]
|
|
4964
5013
|
});
|
|
4965
5014
|
|
|
4966
|
-
const joined = new Set( segments.map( ( entry ) => entry.
|
|
5015
|
+
const joined = new Set( segments.map( ( entry ) => entry.id ) );
|
|
4967
5016
|
|
|
4968
5017
|
const tags = ( owned || [] )
|
|
4969
|
-
.
|
|
4970
|
-
.
|
|
4971
|
-
|
|
4972
|
-
|
|
4973
|
-
status : joined.has( title ) ? 'active' : 'inactive'
|
|
5018
|
+
.filter( ( entry ) => entry.id && entry.title )
|
|
5019
|
+
.map( ( entry ) => ({
|
|
5020
|
+
name : tagName( entry.title, entry.id ),
|
|
5021
|
+
status : joined.has( entry.id ) ? 'active' : 'inactive'
|
|
4974
5022
|
}) );
|
|
4975
5023
|
|
|
4976
5024
|
if( tags.length > 0 ){
|
|
@@ -5040,7 +5088,7 @@ var mailchimp = {
|
|
|
5040
5088
|
|
|
5041
5089
|
if( ! segment?.id || segment.system ) return { message : 'That segment is not one this connection publishes.', skipped : true };
|
|
5042
5090
|
|
|
5043
|
-
const name = tagName( segment.title );
|
|
5091
|
+
const name = tagName( segment.title, segment.id );
|
|
5044
5092
|
const existing = segmentRowFor({ connection, segment });
|
|
5045
5093
|
|
|
5046
5094
|
let id = null;
|
|
@@ -5768,23 +5816,33 @@ var shopify = {
|
|
|
5768
5816
|
|
|
5769
5817
|
const request = { email : context?.email || null, lead : context?.lead || null, shop : connection.shop };
|
|
5770
5818
|
|
|
5819
|
+
// KEPT even though nothing below sends the address anywhere. A code
|
|
5820
|
+
// that reaches nobody is a wasted action and a merchant's wasted
|
|
5821
|
+
// allowance: issuing is only half a workflow, and the email step after
|
|
5822
|
+
// it needs somewhere to send the code.
|
|
5771
5823
|
if( ! context?.email ) return { message : 'Lead email is missing.', request, response : { skipped : true }, skipped : true };
|
|
5772
5824
|
if( ! context?.lead ) return { message : 'Lead id is missing.', request, response : { skipped : true }, skipped : true };
|
|
5773
5825
|
if( ! discount?.id ) return { message : 'Discount is not configured on this step.', request, response : { skipped : true }, skipped : true };
|
|
5774
5826
|
|
|
5775
5827
|
const adminAccessToken = await adminToken();
|
|
5776
5828
|
|
|
5777
|
-
//
|
|
5778
|
-
//
|
|
5779
|
-
//
|
|
5780
|
-
|
|
5781
|
-
|
|
5782
|
-
|
|
5783
|
-
|
|
5784
|
-
|
|
5785
|
-
|
|
5786
|
-
|
|
5787
|
-
|
|
5829
|
+
// NOTHING IS SENT TO SHOPIFY TO LINK THE CODE TO THE PERSON, because
|
|
5830
|
+
// there is nothing to send: discountRedeemCodeBulkAdd takes a discount
|
|
5831
|
+
// and a list of codes, and no customer
|
|
5832
|
+
// (shopify.dev/docs/api/admin-graphql/2026-04/mutations/discountRedeemCodeBulkAdd).
|
|
5833
|
+
// The link lives entirely on our side — `lead.shopifyDiscountCode`
|
|
5834
|
+
// below — and attribution happens when the order comes back carrying
|
|
5835
|
+
// the code, matched org-scoped against that field by commerce.order.
|
|
5836
|
+
//
|
|
5837
|
+
// This step used to call getOrCreateCustomer first, on the stated
|
|
5838
|
+
// reasoning that "the customer must exist before a code is mapped to
|
|
5839
|
+
// them". No code was ever mapped to them: the result was assigned and
|
|
5840
|
+
// discarded, createDiscountCode never received it, and redemption
|
|
5841
|
+
// attribution never consulted it. All it did was create a customer in
|
|
5842
|
+
// the merchant's store as a side effect of issuing a discount — which
|
|
5843
|
+
// QA reported as surprising, and was right to. A merchant who wants the
|
|
5844
|
+
// buyer to exist at the store adds the Create customer step, which is
|
|
5845
|
+
// what that step is for.
|
|
5788
5846
|
const discountCode = await shopify.admin.createDiscountCode({
|
|
5789
5847
|
adminAccessToken,
|
|
5790
5848
|
code : 'DB-' + generateDiscountCode(),
|
|
@@ -542,6 +542,7 @@ var row = ({ connection: connection2, data: data2, manifest, row: described }) =
|
|
|
542
542
|
};
|
|
543
543
|
};
|
|
544
544
|
var segmentRowWrites = ({ connection: connection2, data: data2, manifest, row: described, segment }) => {
|
|
545
|
+
if ((described == null ? void 0 : described.id) === void 0 || (described == null ? void 0 : described.id) === null) return [];
|
|
545
546
|
const built = row({ connection: connection2, data: data2, manifest, row: described });
|
|
546
547
|
return [
|
|
547
548
|
// PUSH IF ABSENT. The $ne guard is what makes a second concurrent register
|
|
@@ -3014,7 +3015,7 @@ var api2 = async (path, { fetcher = fetch, method = "GET", payload, token }) =>
|
|
|
3014
3015
|
}
|
|
3015
3016
|
return response.status === 204 ? null : response.json();
|
|
3016
3017
|
};
|
|
3017
|
-
var segmentName = (title) => "Drawbridge: " + title;
|
|
3018
|
+
var segmentName = (title, id) => "Drawbridge: " + title + " (" + String(id).slice(-6) + ")";
|
|
3018
3019
|
var canManageSegments = (settings) => String((settings == null ? void 0 : settings.scope) || "").split(/\s+/).includes("segments:write");
|
|
3019
3020
|
var klaviyo_default2 = {
|
|
3020
3021
|
// OAuth 2.1, and PKCE is REQUIRED rather than recommended: Klaviyo refuses an
|
|
@@ -3389,7 +3390,7 @@ var klaviyo_default2 = {
|
|
|
3389
3390
|
skipped: true
|
|
3390
3391
|
};
|
|
3391
3392
|
}
|
|
3392
|
-
const name = segmentName(segment.title);
|
|
3393
|
+
const name = segmentName(segment.title, segment.id);
|
|
3393
3394
|
const existing = segmentRowFor({ connection: connection2, segment });
|
|
3394
3395
|
let id = null;
|
|
3395
3396
|
if (existing == null ? void 0 : existing.id) {
|
|
@@ -3796,7 +3797,10 @@ var api3 = async (path, { dc, fetcher = fetch, method = "GET", payload, token })
|
|
|
3796
3797
|
};
|
|
3797
3798
|
var subscriberHash = (email) => createHash2("md5").update(String(email).trim().toLowerCase()).digest("hex");
|
|
3798
3799
|
var TAG_NAME_LIMIT = 100;
|
|
3799
|
-
var tagName = (title) =>
|
|
3800
|
+
var tagName = (title, id) => {
|
|
3801
|
+
const suffix = " (" + String(id).slice(-6) + ")";
|
|
3802
|
+
return ("Drawbridge: " + title).slice(0, TAG_NAME_LIMIT - suffix.length) + suffix;
|
|
3803
|
+
};
|
|
3800
3804
|
var mailchimp_default2 = {
|
|
3801
3805
|
// OAUTH 2, authorization code. Every url below is quoted from
|
|
3802
3806
|
// mailchimp.com/developer/marketing/guides/access-user-data-oauth-2/ rather
|
|
@@ -3977,14 +3981,17 @@ var mailchimp_default2 = {
|
|
|
3977
3981
|
}
|
|
3978
3982
|
},
|
|
3979
3983
|
{
|
|
3980
|
-
|
|
3984
|
+
// THE ID AS WELL AS THE TITLE, because the tag name carries it —
|
|
3985
|
+
// see tagName. Without it every name here would end in the
|
|
3986
|
+
// string 'undefined' and match nothing register wrote.
|
|
3987
|
+
$project: { _id: 0, id: 1, title: 1 }
|
|
3981
3988
|
}
|
|
3982
3989
|
]
|
|
3983
3990
|
});
|
|
3984
|
-
const joined = new Set(segments.map((entry) => entry.
|
|
3985
|
-
const tags = (owned || []).
|
|
3986
|
-
name: tagName(title),
|
|
3987
|
-
status: joined.has(
|
|
3991
|
+
const joined = new Set(segments.map((entry) => entry.id));
|
|
3992
|
+
const tags = (owned || []).filter((entry) => entry.id && entry.title).map((entry) => ({
|
|
3993
|
+
name: tagName(entry.title, entry.id),
|
|
3994
|
+
status: joined.has(entry.id) ? "active" : "inactive"
|
|
3988
3995
|
}));
|
|
3989
3996
|
if (tags.length > 0) {
|
|
3990
3997
|
await api3("/lists/" + audience + "/members/" + hash + "/tags", {
|
|
@@ -4036,7 +4043,7 @@ var mailchimp_default2 = {
|
|
|
4036
4043
|
if (!audience) return { message: "No Mailchimp audience is chosen for this connection.", skipped: true };
|
|
4037
4044
|
const segment = await currentSegment({ read, segment: context == null ? void 0 : context.segment });
|
|
4038
4045
|
if (!(segment == null ? void 0 : segment.id) || segment.system) return { message: "That segment is not one this connection publishes.", skipped: true };
|
|
4039
|
-
const name = tagName(segment.title);
|
|
4046
|
+
const name = tagName(segment.title, segment.id);
|
|
4040
4047
|
const existing = segmentRowFor({ connection: connection2, segment });
|
|
4041
4048
|
let id = null;
|
|
4042
4049
|
if (existing == null ? void 0 : existing.id) {
|
|
@@ -4589,10 +4596,6 @@ var shopify_default2 = {
|
|
|
4589
4596
|
if (!(context == null ? void 0 : context.lead)) return { message: "Lead id is missing.", request: request2, response: { skipped: true }, skipped: true };
|
|
4590
4597
|
if (!(discount == null ? void 0 : discount.id)) return { message: "Discount is not configured on this step.", request: request2, response: { skipped: true }, skipped: true };
|
|
4591
4598
|
const adminAccessToken = await adminToken();
|
|
4592
|
-
if (!context.shopifyCustomerId) {
|
|
4593
|
-
const customer = await shopify.admin.getOrCreateCustomer({ adminAccessToken, domain: connection2.shop, email: context.email });
|
|
4594
|
-
if (!(customer == null ? void 0 : customer.id)) return { message: "Shopify did not return a customer id \u2014 create/lookup failed.", request: request2, response: { skipped: true }, skipped: true };
|
|
4595
|
-
}
|
|
4596
4599
|
const discountCode = await shopify.admin.createDiscountCode({
|
|
4597
4600
|
adminAccessToken,
|
|
4598
4601
|
code: "DB-" + generateDiscountCode(),
|
package/dist/providers.cjs
CHANGED
|
@@ -527,6 +527,7 @@ var row = ({ connection: connection2, data: data2, manifest, row: described }) =
|
|
|
527
527
|
};
|
|
528
528
|
};
|
|
529
529
|
var segmentRowWrites = ({ connection: connection2, data: data2, manifest, row: described, segment }) => {
|
|
530
|
+
if ((described == null ? void 0 : described.id) === void 0 || (described == null ? void 0 : described.id) === null) return [];
|
|
530
531
|
const built = row({ connection: connection2, data: data2, manifest, row: described });
|
|
531
532
|
return [
|
|
532
533
|
// PUSH IF ABSENT. The $ne guard is what makes a second concurrent register
|
|
@@ -2999,7 +3000,7 @@ var api2 = async (path, { fetcher = fetch, method = "GET", payload, token }) =>
|
|
|
2999
3000
|
}
|
|
3000
3001
|
return response.status === 204 ? null : response.json();
|
|
3001
3002
|
};
|
|
3002
|
-
var segmentName = (title) => "Drawbridge: " + title;
|
|
3003
|
+
var segmentName = (title, id) => "Drawbridge: " + title + " (" + String(id).slice(-6) + ")";
|
|
3003
3004
|
var canManageSegments = (settings) => String((settings == null ? void 0 : settings.scope) || "").split(/\s+/).includes("segments:write");
|
|
3004
3005
|
var klaviyo_default2 = {
|
|
3005
3006
|
// OAuth 2.1, and PKCE is REQUIRED rather than recommended: Klaviyo refuses an
|
|
@@ -3374,7 +3375,7 @@ var klaviyo_default2 = {
|
|
|
3374
3375
|
skipped: true
|
|
3375
3376
|
};
|
|
3376
3377
|
}
|
|
3377
|
-
const name = segmentName(segment.title);
|
|
3378
|
+
const name = segmentName(segment.title, segment.id);
|
|
3378
3379
|
const existing = segmentRowFor({ connection: connection2, segment });
|
|
3379
3380
|
let id = null;
|
|
3380
3381
|
if (existing == null ? void 0 : existing.id) {
|
|
@@ -3781,7 +3782,10 @@ var api3 = async (path, { dc, fetcher = fetch, method = "GET", payload, token })
|
|
|
3781
3782
|
};
|
|
3782
3783
|
var subscriberHash = (email) => (0, import_node_crypto5.createHash)("md5").update(String(email).trim().toLowerCase()).digest("hex");
|
|
3783
3784
|
var TAG_NAME_LIMIT = 100;
|
|
3784
|
-
var tagName = (title) =>
|
|
3785
|
+
var tagName = (title, id) => {
|
|
3786
|
+
const suffix = " (" + String(id).slice(-6) + ")";
|
|
3787
|
+
return ("Drawbridge: " + title).slice(0, TAG_NAME_LIMIT - suffix.length) + suffix;
|
|
3788
|
+
};
|
|
3785
3789
|
var mailchimp_default2 = {
|
|
3786
3790
|
// OAUTH 2, authorization code. Every url below is quoted from
|
|
3787
3791
|
// mailchimp.com/developer/marketing/guides/access-user-data-oauth-2/ rather
|
|
@@ -3962,14 +3966,17 @@ var mailchimp_default2 = {
|
|
|
3962
3966
|
}
|
|
3963
3967
|
},
|
|
3964
3968
|
{
|
|
3965
|
-
|
|
3969
|
+
// THE ID AS WELL AS THE TITLE, because the tag name carries it —
|
|
3970
|
+
// see tagName. Without it every name here would end in the
|
|
3971
|
+
// string 'undefined' and match nothing register wrote.
|
|
3972
|
+
$project: { _id: 0, id: 1, title: 1 }
|
|
3966
3973
|
}
|
|
3967
3974
|
]
|
|
3968
3975
|
});
|
|
3969
|
-
const joined = new Set(segments.map((entry) => entry.
|
|
3970
|
-
const tags = (owned || []).
|
|
3971
|
-
name: tagName(title),
|
|
3972
|
-
status: joined.has(
|
|
3976
|
+
const joined = new Set(segments.map((entry) => entry.id));
|
|
3977
|
+
const tags = (owned || []).filter((entry) => entry.id && entry.title).map((entry) => ({
|
|
3978
|
+
name: tagName(entry.title, entry.id),
|
|
3979
|
+
status: joined.has(entry.id) ? "active" : "inactive"
|
|
3973
3980
|
}));
|
|
3974
3981
|
if (tags.length > 0) {
|
|
3975
3982
|
await api3("/lists/" + audience + "/members/" + hash + "/tags", {
|
|
@@ -4021,7 +4028,7 @@ var mailchimp_default2 = {
|
|
|
4021
4028
|
if (!audience) return { message: "No Mailchimp audience is chosen for this connection.", skipped: true };
|
|
4022
4029
|
const segment = await currentSegment({ read, segment: context == null ? void 0 : context.segment });
|
|
4023
4030
|
if (!(segment == null ? void 0 : segment.id) || segment.system) return { message: "That segment is not one this connection publishes.", skipped: true };
|
|
4024
|
-
const name = tagName(segment.title);
|
|
4031
|
+
const name = tagName(segment.title, segment.id);
|
|
4025
4032
|
const existing = segmentRowFor({ connection: connection2, segment });
|
|
4026
4033
|
let id = null;
|
|
4027
4034
|
if (existing == null ? void 0 : existing.id) {
|
|
@@ -4593,10 +4600,6 @@ var shopify_default2 = {
|
|
|
4593
4600
|
if (!(context == null ? void 0 : context.lead)) return { message: "Lead id is missing.", request: request2, response: { skipped: true }, skipped: true };
|
|
4594
4601
|
if (!(discount == null ? void 0 : discount.id)) return { message: "Discount is not configured on this step.", request: request2, response: { skipped: true }, skipped: true };
|
|
4595
4602
|
const adminAccessToken = await adminToken();
|
|
4596
|
-
if (!context.shopifyCustomerId) {
|
|
4597
|
-
const customer = await shopify.admin.getOrCreateCustomer({ adminAccessToken, domain: connection2.shop, email: context.email });
|
|
4598
|
-
if (!(customer == null ? void 0 : customer.id)) return { message: "Shopify did not return a customer id \u2014 create/lookup failed.", request: request2, response: { skipped: true }, skipped: true };
|
|
4599
|
-
}
|
|
4600
4603
|
const discountCode = await shopify.admin.createDiscountCode({
|
|
4601
4604
|
adminAccessToken,
|
|
4602
4605
|
code: "DB-" + generateDiscountCode(),
|
package/dist/providers.js
CHANGED
|
@@ -478,6 +478,7 @@ var row = ({ connection: connection2, data: data2, manifest, row: described }) =
|
|
|
478
478
|
};
|
|
479
479
|
};
|
|
480
480
|
var segmentRowWrites = ({ connection: connection2, data: data2, manifest, row: described, segment }) => {
|
|
481
|
+
if ((described == null ? void 0 : described.id) === void 0 || (described == null ? void 0 : described.id) === null) return [];
|
|
481
482
|
const built = row({ connection: connection2, data: data2, manifest, row: described });
|
|
482
483
|
return [
|
|
483
484
|
// PUSH IF ABSENT. The $ne guard is what makes a second concurrent register
|
|
@@ -2950,7 +2951,7 @@ var api2 = async (path, { fetcher = fetch, method = "GET", payload, token }) =>
|
|
|
2950
2951
|
}
|
|
2951
2952
|
return response.status === 204 ? null : response.json();
|
|
2952
2953
|
};
|
|
2953
|
-
var segmentName = (title) => "Drawbridge: " + title;
|
|
2954
|
+
var segmentName = (title, id) => "Drawbridge: " + title + " (" + String(id).slice(-6) + ")";
|
|
2954
2955
|
var canManageSegments = (settings) => String((settings == null ? void 0 : settings.scope) || "").split(/\s+/).includes("segments:write");
|
|
2955
2956
|
var klaviyo_default2 = {
|
|
2956
2957
|
// OAuth 2.1, and PKCE is REQUIRED rather than recommended: Klaviyo refuses an
|
|
@@ -3325,7 +3326,7 @@ var klaviyo_default2 = {
|
|
|
3325
3326
|
skipped: true
|
|
3326
3327
|
};
|
|
3327
3328
|
}
|
|
3328
|
-
const name = segmentName(segment.title);
|
|
3329
|
+
const name = segmentName(segment.title, segment.id);
|
|
3329
3330
|
const existing = segmentRowFor({ connection: connection2, segment });
|
|
3330
3331
|
let id = null;
|
|
3331
3332
|
if (existing == null ? void 0 : existing.id) {
|
|
@@ -3732,7 +3733,10 @@ var api3 = async (path, { dc, fetcher = fetch, method = "GET", payload, token })
|
|
|
3732
3733
|
};
|
|
3733
3734
|
var subscriberHash = (email) => createHash2("md5").update(String(email).trim().toLowerCase()).digest("hex");
|
|
3734
3735
|
var TAG_NAME_LIMIT = 100;
|
|
3735
|
-
var tagName = (title) =>
|
|
3736
|
+
var tagName = (title, id) => {
|
|
3737
|
+
const suffix = " (" + String(id).slice(-6) + ")";
|
|
3738
|
+
return ("Drawbridge: " + title).slice(0, TAG_NAME_LIMIT - suffix.length) + suffix;
|
|
3739
|
+
};
|
|
3736
3740
|
var mailchimp_default2 = {
|
|
3737
3741
|
// OAUTH 2, authorization code. Every url below is quoted from
|
|
3738
3742
|
// mailchimp.com/developer/marketing/guides/access-user-data-oauth-2/ rather
|
|
@@ -3913,14 +3917,17 @@ var mailchimp_default2 = {
|
|
|
3913
3917
|
}
|
|
3914
3918
|
},
|
|
3915
3919
|
{
|
|
3916
|
-
|
|
3920
|
+
// THE ID AS WELL AS THE TITLE, because the tag name carries it —
|
|
3921
|
+
// see tagName. Without it every name here would end in the
|
|
3922
|
+
// string 'undefined' and match nothing register wrote.
|
|
3923
|
+
$project: { _id: 0, id: 1, title: 1 }
|
|
3917
3924
|
}
|
|
3918
3925
|
]
|
|
3919
3926
|
});
|
|
3920
|
-
const joined = new Set(segments.map((entry) => entry.
|
|
3921
|
-
const tags = (owned || []).
|
|
3922
|
-
name: tagName(title),
|
|
3923
|
-
status: joined.has(
|
|
3927
|
+
const joined = new Set(segments.map((entry) => entry.id));
|
|
3928
|
+
const tags = (owned || []).filter((entry) => entry.id && entry.title).map((entry) => ({
|
|
3929
|
+
name: tagName(entry.title, entry.id),
|
|
3930
|
+
status: joined.has(entry.id) ? "active" : "inactive"
|
|
3924
3931
|
}));
|
|
3925
3932
|
if (tags.length > 0) {
|
|
3926
3933
|
await api3("/lists/" + audience + "/members/" + hash + "/tags", {
|
|
@@ -3972,7 +3979,7 @@ var mailchimp_default2 = {
|
|
|
3972
3979
|
if (!audience) return { message: "No Mailchimp audience is chosen for this connection.", skipped: true };
|
|
3973
3980
|
const segment = await currentSegment({ read, segment: context == null ? void 0 : context.segment });
|
|
3974
3981
|
if (!(segment == null ? void 0 : segment.id) || segment.system) return { message: "That segment is not one this connection publishes.", skipped: true };
|
|
3975
|
-
const name = tagName(segment.title);
|
|
3982
|
+
const name = tagName(segment.title, segment.id);
|
|
3976
3983
|
const existing = segmentRowFor({ connection: connection2, segment });
|
|
3977
3984
|
let id = null;
|
|
3978
3985
|
if (existing == null ? void 0 : existing.id) {
|
|
@@ -4544,10 +4551,6 @@ var shopify_default2 = {
|
|
|
4544
4551
|
if (!(context == null ? void 0 : context.lead)) return { message: "Lead id is missing.", request: request2, response: { skipped: true }, skipped: true };
|
|
4545
4552
|
if (!(discount == null ? void 0 : discount.id)) return { message: "Discount is not configured on this step.", request: request2, response: { skipped: true }, skipped: true };
|
|
4546
4553
|
const adminAccessToken = await adminToken();
|
|
4547
|
-
if (!context.shopifyCustomerId) {
|
|
4548
|
-
const customer = await shopify.admin.getOrCreateCustomer({ adminAccessToken, domain: connection2.shop, email: context.email });
|
|
4549
|
-
if (!(customer == null ? void 0 : customer.id)) return { message: "Shopify did not return a customer id \u2014 create/lookup failed.", request: request2, response: { skipped: true }, skipped: true };
|
|
4550
|
-
}
|
|
4551
4554
|
const discountCode = await shopify.admin.createDiscountCode({
|
|
4552
4555
|
adminAccessToken,
|
|
4553
4556
|
code: "DB-" + generateDiscountCode(),
|
package/package.json
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"tinycolor2": "1.6.0"
|
|
14
14
|
},
|
|
15
15
|
"devDependencies": {
|
|
16
|
-
"@drawbridge/drawbridge-agents": "0.1.
|
|
16
|
+
"@drawbridge/drawbridge-agents": "0.1.59",
|
|
17
17
|
"@node-oauth/oauth2-server": "5.3.0",
|
|
18
18
|
"tsup": "8.5.1",
|
|
19
19
|
"typescript": "5.9.3",
|
|
@@ -226,5 +226,5 @@
|
|
|
226
226
|
"prepublishOnly": ". \"$HOME/.nvm/nvm.sh\" && nvm use && tsup && node --test"
|
|
227
227
|
},
|
|
228
228
|
"types": "dist/index.d.ts",
|
|
229
|
-
"version": "0.0.
|
|
229
|
+
"version": "0.0.172"
|
|
230
230
|
}
|