@drawbridge/drawbridge-utils 0.0.175 → 0.0.177
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/admin-B9ZaLvan.d.cts +697 -0
- package/dist/admin-C3HtEM6h.d.ts +697 -0
- package/dist/billing-Bc4yo9XG.d.cts +175 -0
- package/dist/billing-mNsKflmQ.d.ts +175 -0
- package/dist/billing.d.cts +1 -1
- package/dist/billing.d.ts +1 -1
- package/dist/connections/index.cjs +5928 -1920
- package/dist/connections/index.d.cts +20 -9163
- package/dist/connections/index.d.ts +20 -9163
- package/dist/connections/index.js +5917 -1921
- package/dist/connections/oauth.cjs +4 -4
- package/dist/connections/oauth.d.cts +10 -8
- package/dist/connections/oauth.d.ts +10 -8
- package/dist/connections/oauth.js +4 -4
- package/dist/features.cjs +10260 -42
- package/dist/features.d.cts +55 -42
- package/dist/features.d.ts +55 -42
- package/dist/features.js +10254 -42
- package/dist/http.cjs +10 -1
- package/dist/http.d.cts +10 -1
- package/dist/http.d.ts +10 -1
- package/dist/http.js +10 -1
- package/dist/index-B546oDNo.d.ts +13809 -0
- package/dist/index-C59xHago.d.cts +13809 -0
- package/dist/oauth/index.d.cts +1 -1
- package/dist/oauth/index.d.ts +1 -1
- package/dist/oauth-BJDh0sdM.d.cts +527 -0
- package/dist/oauth-DveZMLHx.d.ts +527 -0
- package/dist/partner-BOZltuh2.d.ts +94 -0
- package/dist/partner-ed2OfW1J.d.cts +94 -0
- package/dist/plans.cjs +10256 -51
- package/dist/plans.d.cts +37 -10
- package/dist/plans.d.ts +37 -10
- package/dist/plans.js +10262 -51
- package/dist/pricing.cjs +10401 -209
- package/dist/pricing.d.cts +34 -17
- package/dist/pricing.d.ts +34 -17
- package/dist/pricing.js +10407 -209
- package/dist/providers.cjs +5433 -1755
- package/dist/providers.d.cts +13 -15
- package/dist/providers.d.ts +13 -15
- package/dist/providers.js +5436 -1752
- package/dist/sendgrid.cjs +10 -1
- package/dist/sendgrid.js +10 -1
- package/dist/shopify/admin.cjs +562 -0
- package/dist/shopify/admin.d.cts +3 -0
- package/dist/shopify/admin.d.ts +3 -0
- package/dist/shopify/admin.js +528 -0
- package/dist/shopify/billing.cjs +166 -0
- package/dist/shopify/billing.d.cts +3 -0
- package/dist/shopify/billing.d.ts +3 -0
- package/dist/shopify/billing.js +140 -0
- package/dist/shopify/constants.cjs +63 -0
- package/dist/shopify/constants.d.cts +58 -0
- package/dist/shopify/constants.d.ts +58 -0
- package/dist/shopify/constants.js +32 -0
- package/dist/shopify/oauth.cjs +509 -0
- package/dist/shopify/oauth.d.cts +7 -0
- package/dist/shopify/oauth.d.ts +7 -0
- package/dist/shopify/oauth.js +466 -0
- package/dist/shopify/partner.cjs +156 -0
- package/dist/shopify/partner.d.cts +3 -0
- package/dist/shopify/partner.d.ts +3 -0
- package/dist/shopify/partner.js +130 -0
- package/dist/shopify/storefront.cjs +611 -0
- package/dist/shopify/storefront.d.cts +3 -0
- package/dist/shopify/storefront.d.ts +3 -0
- package/dist/shopify/storefront.js +576 -0
- package/dist/storefront-C8FKOGeD.d.cts +659 -0
- package/dist/storefront-DJFGLqPl.d.ts +659 -0
- package/dist/twilio.cjs +10 -1
- package/dist/twilio.js +10 -1
- package/package.json +98 -68
package/dist/sendgrid.cjs
CHANGED
|
@@ -31,6 +31,15 @@ module.exports = __toCommonJS(sendgrid_exports);
|
|
|
31
31
|
var DEFAULT_TIMEOUT_MS = 15e3;
|
|
32
32
|
var request = async ({
|
|
33
33
|
body,
|
|
34
|
+
// THE TRANSPORT, injectable and defaulted to the real one.
|
|
35
|
+
//
|
|
36
|
+
// Every other vendor client in this package takes a `fetcher` — it is how
|
|
37
|
+
// klaviyo, mailchimp and attentive are tested without a network, and it is a
|
|
38
|
+
// declared HOOK_OPTION. The Shopify client had no seam at all, so the only way
|
|
39
|
+
// to test a hook that used it was to inject the whole SDK namespace; that
|
|
40
|
+
// injection existed to work around an import cycle, and when the cycle went
|
|
41
|
+
// the tests lost their only hold. This is the seam they should have had.
|
|
42
|
+
fetcher = fetch,
|
|
34
43
|
headers = {},
|
|
35
44
|
method = "GET",
|
|
36
45
|
query,
|
|
@@ -44,7 +53,7 @@ var request = async ({
|
|
|
44
53
|
}
|
|
45
54
|
;
|
|
46
55
|
const isForm = type === "form";
|
|
47
|
-
const response = await
|
|
56
|
+
const response = await fetcher(fullUrl.toString(), {
|
|
48
57
|
method,
|
|
49
58
|
headers: {
|
|
50
59
|
"Content-Type": isForm ? "application/x-www-form-urlencoded" : "application/json",
|
package/dist/sendgrid.js
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
var DEFAULT_TIMEOUT_MS = 15e3;
|
|
3
3
|
var request = async ({
|
|
4
4
|
body,
|
|
5
|
+
// THE TRANSPORT, injectable and defaulted to the real one.
|
|
6
|
+
//
|
|
7
|
+
// Every other vendor client in this package takes a `fetcher` — it is how
|
|
8
|
+
// klaviyo, mailchimp and attentive are tested without a network, and it is a
|
|
9
|
+
// declared HOOK_OPTION. The Shopify client had no seam at all, so the only way
|
|
10
|
+
// to test a hook that used it was to inject the whole SDK namespace; that
|
|
11
|
+
// injection existed to work around an import cycle, and when the cycle went
|
|
12
|
+
// the tests lost their only hold. This is the seam they should have had.
|
|
13
|
+
fetcher = fetch,
|
|
5
14
|
headers = {},
|
|
6
15
|
method = "GET",
|
|
7
16
|
query,
|
|
@@ -15,7 +24,7 @@ var request = async ({
|
|
|
15
24
|
}
|
|
16
25
|
;
|
|
17
26
|
const isForm = type === "form";
|
|
18
|
-
const response = await
|
|
27
|
+
const response = await fetcher(fullUrl.toString(), {
|
|
19
28
|
method,
|
|
20
29
|
headers: {
|
|
21
30
|
"Content-Type": isForm ? "application/x-www-form-urlencoded" : "application/json",
|
|
@@ -0,0 +1,562 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
|
|
19
|
+
// lib/shopify/admin.js
|
|
20
|
+
var admin_exports = {};
|
|
21
|
+
__export(admin_exports, {
|
|
22
|
+
adminFetch: () => adminFetch,
|
|
23
|
+
createDiscountCode: () => createDiscountCode,
|
|
24
|
+
createUsageRecord: () => createUsageRecord,
|
|
25
|
+
createUsageSubscription: () => createUsageSubscription,
|
|
26
|
+
getActiveAppSubscriptions: () => getActiveAppSubscriptions,
|
|
27
|
+
getDiscounts: () => getDiscounts,
|
|
28
|
+
getOrCreateCustomer: () => getOrCreateCustomer,
|
|
29
|
+
getProductInventory: () => getProductInventory,
|
|
30
|
+
sendProductResourceFeedback: () => sendProductResourceFeedback
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(admin_exports);
|
|
33
|
+
|
|
34
|
+
// lib/http.js
|
|
35
|
+
var DEFAULT_TIMEOUT_MS = 15e3;
|
|
36
|
+
var request = async ({
|
|
37
|
+
body,
|
|
38
|
+
// THE TRANSPORT, injectable and defaulted to the real one.
|
|
39
|
+
//
|
|
40
|
+
// Every other vendor client in this package takes a `fetcher` — it is how
|
|
41
|
+
// klaviyo, mailchimp and attentive are tested without a network, and it is a
|
|
42
|
+
// declared HOOK_OPTION. The Shopify client had no seam at all, so the only way
|
|
43
|
+
// to test a hook that used it was to inject the whole SDK namespace; that
|
|
44
|
+
// injection existed to work around an import cycle, and when the cycle went
|
|
45
|
+
// the tests lost their only hold. This is the seam they should have had.
|
|
46
|
+
fetcher = fetch,
|
|
47
|
+
headers = {},
|
|
48
|
+
method = "GET",
|
|
49
|
+
query,
|
|
50
|
+
timeout = DEFAULT_TIMEOUT_MS,
|
|
51
|
+
type = "json",
|
|
52
|
+
url
|
|
53
|
+
}) => {
|
|
54
|
+
const fullUrl = new URL(url);
|
|
55
|
+
if (query) {
|
|
56
|
+
Object.entries(query).forEach(([k, v]) => fullUrl.searchParams.set(k, v));
|
|
57
|
+
}
|
|
58
|
+
;
|
|
59
|
+
const isForm = type === "form";
|
|
60
|
+
const response = await fetcher(fullUrl.toString(), {
|
|
61
|
+
method,
|
|
62
|
+
headers: {
|
|
63
|
+
"Content-Type": isForm ? "application/x-www-form-urlencoded" : "application/json",
|
|
64
|
+
...headers
|
|
65
|
+
},
|
|
66
|
+
signal: AbortSignal.timeout(timeout),
|
|
67
|
+
...body !== void 0 && {
|
|
68
|
+
body: isForm ? new URLSearchParams(body).toString() : JSON.stringify(body)
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
if (!response.ok) {
|
|
72
|
+
const text2 = await response.text().catch(() => "");
|
|
73
|
+
const error = new Error(text2 || response.statusText);
|
|
74
|
+
error.status = response.status;
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
;
|
|
78
|
+
const text = await response.text();
|
|
79
|
+
try {
|
|
80
|
+
return text ? JSON.parse(text) : null;
|
|
81
|
+
} catch {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// lib/shopify/constants.js
|
|
87
|
+
var SHOPIFY_ADMIN_API_VERSION = "2026-04";
|
|
88
|
+
var REFRESH_TOKEN_LIFETIME_MS = 90 * 24 * 60 * 60 * 1e3;
|
|
89
|
+
var ACCESS_TOKEN_REFRESH_BUFFER_MS = 5 * 60 * 1e3;
|
|
90
|
+
var PARTNER_API_VERSION = process.env.SHOPIFY_PARTNER_API_VERSION || "2026-07";
|
|
91
|
+
|
|
92
|
+
// lib/shopify/admin.js
|
|
93
|
+
var adminUrl = (domain) => `https://${domain}/admin/api/${SHOPIFY_ADMIN_API_VERSION}`;
|
|
94
|
+
var adminFetch = async ({ adminAccessToken, domain, fetcher, query, variables }) => {
|
|
95
|
+
var _a;
|
|
96
|
+
const { data, errors } = await request({
|
|
97
|
+
fetcher,
|
|
98
|
+
method: "POST",
|
|
99
|
+
url: adminUrl(domain) + "/graphql.json",
|
|
100
|
+
headers: {
|
|
101
|
+
"X-Shopify-Access-Token": adminAccessToken
|
|
102
|
+
},
|
|
103
|
+
body: {
|
|
104
|
+
query,
|
|
105
|
+
...variables && { variables }
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
if (errors) {
|
|
109
|
+
throw new Error("Shopify GraphQL error: " + ((_a = errors[0]) == null ? void 0 : _a.message));
|
|
110
|
+
}
|
|
111
|
+
;
|
|
112
|
+
return data;
|
|
113
|
+
};
|
|
114
|
+
var DISCOUNT_FIELDS = `
|
|
115
|
+
title
|
|
116
|
+
status
|
|
117
|
+
startsAt
|
|
118
|
+
endsAt
|
|
119
|
+
usageLimit
|
|
120
|
+
asyncUsageCount
|
|
121
|
+
appliesOncePerCustomer
|
|
122
|
+
context { __typename }
|
|
123
|
+
`;
|
|
124
|
+
var discountsQuery = (search, cursor, limit) => `{
|
|
125
|
+
codeDiscountNodes(first: ${limit}${search ? `, query: "title:*${search}*"` : ""}${cursor ? `, after: "${cursor}"` : ""}) {
|
|
126
|
+
edges {
|
|
127
|
+
node {
|
|
128
|
+
id
|
|
129
|
+
codeDiscount {
|
|
130
|
+
... on DiscountCodeBasic { ${DISCOUNT_FIELDS} }
|
|
131
|
+
... on DiscountCodeBxgy { ${DISCOUNT_FIELDS} }
|
|
132
|
+
... on DiscountCodeFreeShipping { ${DISCOUNT_FIELDS} }
|
|
133
|
+
... on DiscountCodeApp { ${DISCOUNT_FIELDS} }
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
pageInfo {
|
|
138
|
+
endCursor
|
|
139
|
+
hasNextPage
|
|
140
|
+
hasPreviousPage
|
|
141
|
+
startCursor
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}`;
|
|
145
|
+
var getDiscounts = async ({ fetcher, adminAccessToken, domain, search, cursor, limit }) => {
|
|
146
|
+
const data = await adminFetch({
|
|
147
|
+
fetcher,
|
|
148
|
+
adminAccessToken,
|
|
149
|
+
domain,
|
|
150
|
+
query: discountsQuery(search, cursor, limit)
|
|
151
|
+
});
|
|
152
|
+
return data == null ? void 0 : data.codeDiscountNodes;
|
|
153
|
+
};
|
|
154
|
+
var discountGid = (id) => String(id).startsWith("gid://") ? String(id) : "gid://shopify/DiscountCodeNode/" + id;
|
|
155
|
+
var createDiscountCode = async ({ fetcher, adminAccessToken, domain, discountId, code }) => {
|
|
156
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
157
|
+
const added = await adminFetch({
|
|
158
|
+
fetcher,
|
|
159
|
+
adminAccessToken,
|
|
160
|
+
domain,
|
|
161
|
+
query: `
|
|
162
|
+
mutation DiscountRedeemCodeBulkAdd($discountId: ID!, $codes: [DiscountRedeemCodeInput!]!) {
|
|
163
|
+
discountRedeemCodeBulkAdd(discountId: $discountId, codes: $codes) {
|
|
164
|
+
bulkCreation {
|
|
165
|
+
id
|
|
166
|
+
}
|
|
167
|
+
userErrors {
|
|
168
|
+
field
|
|
169
|
+
message
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
`,
|
|
174
|
+
variables: {
|
|
175
|
+
codes: [{ code }],
|
|
176
|
+
discountId: discountGid(discountId)
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
const addErrors = (_a = added == null ? void 0 : added.discountRedeemCodeBulkAdd) == null ? void 0 : _a.userErrors;
|
|
180
|
+
if (addErrors == null ? void 0 : addErrors.length) {
|
|
181
|
+
throw new Error("Shopify discount code create failed: " + addErrors[0].message);
|
|
182
|
+
}
|
|
183
|
+
;
|
|
184
|
+
const bulkCreationId = (_c = (_b = added == null ? void 0 : added.discountRedeemCodeBulkAdd) == null ? void 0 : _b.bulkCreation) == null ? void 0 : _c.id;
|
|
185
|
+
if (!bulkCreationId) {
|
|
186
|
+
throw new Error("Shopify discount code create failed: no bulk creation id returned");
|
|
187
|
+
}
|
|
188
|
+
;
|
|
189
|
+
for (let attempt = 0; attempt < 15; attempt++) {
|
|
190
|
+
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
191
|
+
const polled = await adminFetch({
|
|
192
|
+
fetcher,
|
|
193
|
+
adminAccessToken,
|
|
194
|
+
domain,
|
|
195
|
+
query: `
|
|
196
|
+
query DiscountRedeemCodeBulkCreationPoll($id: ID!) {
|
|
197
|
+
discountRedeemCodeBulkCreation(id: $id) {
|
|
198
|
+
done
|
|
199
|
+
codes(first: 1) {
|
|
200
|
+
nodes {
|
|
201
|
+
code
|
|
202
|
+
discountRedeemCode {
|
|
203
|
+
id
|
|
204
|
+
}
|
|
205
|
+
errors {
|
|
206
|
+
message
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
`,
|
|
213
|
+
variables: {
|
|
214
|
+
id: bulkCreationId
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
const creation = polled == null ? void 0 : polled.discountRedeemCodeBulkCreation;
|
|
218
|
+
if (!(creation == null ? void 0 : creation.done)) continue;
|
|
219
|
+
const node = (_e = (_d = creation.codes) == null ? void 0 : _d.nodes) == null ? void 0 : _e[0];
|
|
220
|
+
if (!((_f = node == null ? void 0 : node.discountRedeemCode) == null ? void 0 : _f.id)) {
|
|
221
|
+
throw new Error("Shopify discount code create failed: " + (((_h = (_g = node == null ? void 0 : node.errors) == null ? void 0 : _g[0]) == null ? void 0 : _h.message) || "code was not created"));
|
|
222
|
+
}
|
|
223
|
+
;
|
|
224
|
+
return {
|
|
225
|
+
code: node.code,
|
|
226
|
+
// Numeric tail keeps the stored shopifyDiscountId in the shape the
|
|
227
|
+
// legacy REST endpoint returned — it feeds a merchant-visible
|
|
228
|
+
// workflow template variable, so no gid:// leakage.
|
|
229
|
+
id: node.discountRedeemCode.id.split("/").pop()
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
;
|
|
233
|
+
throw new Error("Shopify discount code create timed out waiting for bulk creation " + bulkCreationId);
|
|
234
|
+
};
|
|
235
|
+
var getOrCreateCustomer = async ({ fetcher, adminAccessToken, domain, email, firstName, lastName, source }) => {
|
|
236
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
237
|
+
const lookupQuery = `
|
|
238
|
+
query customerByEmail( $query : String! ) {
|
|
239
|
+
customers( first : 1, query : $query ) {
|
|
240
|
+
edges {
|
|
241
|
+
node {
|
|
242
|
+
id
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
`;
|
|
248
|
+
const data = await adminFetch({
|
|
249
|
+
fetcher,
|
|
250
|
+
adminAccessToken,
|
|
251
|
+
domain,
|
|
252
|
+
query: lookupQuery,
|
|
253
|
+
variables: { query: "email:" + email }
|
|
254
|
+
});
|
|
255
|
+
const existing = (_c = (_b = (_a = data == null ? void 0 : data.customers) == null ? void 0 : _a.edges) == null ? void 0 : _b[0]) == null ? void 0 : _c.node;
|
|
256
|
+
if (existing) return existing;
|
|
257
|
+
const input = { email };
|
|
258
|
+
if (firstName) input.firstName = firstName;
|
|
259
|
+
if (lastName) input.lastName = lastName;
|
|
260
|
+
if (source) {
|
|
261
|
+
input.metafields = [{
|
|
262
|
+
namespace: "drwbrdg",
|
|
263
|
+
key: "source",
|
|
264
|
+
type: "single_line_text_field",
|
|
265
|
+
value: source
|
|
266
|
+
}];
|
|
267
|
+
}
|
|
268
|
+
;
|
|
269
|
+
const result = await adminFetch({
|
|
270
|
+
fetcher,
|
|
271
|
+
adminAccessToken,
|
|
272
|
+
domain,
|
|
273
|
+
query: `
|
|
274
|
+
mutation customerCreate( $input : CustomerInput! ) {
|
|
275
|
+
customerCreate( input : $input ) {
|
|
276
|
+
customer {
|
|
277
|
+
id
|
|
278
|
+
}
|
|
279
|
+
userErrors {
|
|
280
|
+
field
|
|
281
|
+
message
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
`,
|
|
286
|
+
variables: { input }
|
|
287
|
+
});
|
|
288
|
+
const userErrors = (_d = result == null ? void 0 : result.customerCreate) == null ? void 0 : _d.userErrors;
|
|
289
|
+
if (userErrors == null ? void 0 : userErrors.length) {
|
|
290
|
+
const emailTaken = userErrors.some((e) => {
|
|
291
|
+
var _a2;
|
|
292
|
+
return (_a2 = e.message) == null ? void 0 : _a2.includes("Email has already been taken");
|
|
293
|
+
});
|
|
294
|
+
if (emailTaken) {
|
|
295
|
+
const retry = await adminFetch({
|
|
296
|
+
fetcher,
|
|
297
|
+
adminAccessToken,
|
|
298
|
+
domain,
|
|
299
|
+
query: lookupQuery,
|
|
300
|
+
variables: { query: "email:" + email }
|
|
301
|
+
});
|
|
302
|
+
const found = (_g = (_f = (_e = retry == null ? void 0 : retry.customers) == null ? void 0 : _e.edges) == null ? void 0 : _f[0]) == null ? void 0 : _g.node;
|
|
303
|
+
if (found) return found;
|
|
304
|
+
}
|
|
305
|
+
;
|
|
306
|
+
throw new Error("Shopify customer create failed: " + userErrors[0].message);
|
|
307
|
+
}
|
|
308
|
+
;
|
|
309
|
+
return (_h = result == null ? void 0 : result.customerCreate) == null ? void 0 : _h.customer;
|
|
310
|
+
};
|
|
311
|
+
var getActiveAppSubscriptions = async ({ fetcher, adminAccessToken, domain }) => {
|
|
312
|
+
var _a, _b;
|
|
313
|
+
const data = await adminFetch({
|
|
314
|
+
fetcher,
|
|
315
|
+
adminAccessToken,
|
|
316
|
+
domain,
|
|
317
|
+
query: `{
|
|
318
|
+
currentAppInstallation {
|
|
319
|
+
activeSubscriptions {
|
|
320
|
+
id
|
|
321
|
+
name
|
|
322
|
+
status
|
|
323
|
+
test
|
|
324
|
+
lineItems {
|
|
325
|
+
id
|
|
326
|
+
plan {
|
|
327
|
+
pricingDetails {
|
|
328
|
+
__typename
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
shop {
|
|
335
|
+
myshopifyDomain
|
|
336
|
+
}
|
|
337
|
+
}`
|
|
338
|
+
});
|
|
339
|
+
return {
|
|
340
|
+
shopDomain: ((_a = data == null ? void 0 : data.shop) == null ? void 0 : _a.myshopifyDomain) || null,
|
|
341
|
+
subscriptions: (((_b = data == null ? void 0 : data.currentAppInstallation) == null ? void 0 : _b.activeSubscriptions) || []).map((subscription) => {
|
|
342
|
+
var _a2;
|
|
343
|
+
return {
|
|
344
|
+
...subscription,
|
|
345
|
+
metered: ((subscription == null ? void 0 : subscription.lineItems) || []).some(
|
|
346
|
+
(item) => {
|
|
347
|
+
var _a3, _b2;
|
|
348
|
+
return ((_b2 = (_a3 = item == null ? void 0 : item.plan) == null ? void 0 : _a3.pricingDetails) == null ? void 0 : _b2.__typename) === "AppUsagePricing";
|
|
349
|
+
}
|
|
350
|
+
),
|
|
351
|
+
// The usage line's own id — the address appUsageRecordCreate charges
|
|
352
|
+
// against. Null when the approval carries no usage component.
|
|
353
|
+
usageLineItemId: ((_a2 = ((subscription == null ? void 0 : subscription.lineItems) || []).find(
|
|
354
|
+
(item) => {
|
|
355
|
+
var _a3, _b2;
|
|
356
|
+
return ((_b2 = (_a3 = item == null ? void 0 : item.plan) == null ? void 0 : _a3.pricingDetails) == null ? void 0 : _b2.__typename) === "AppUsagePricing";
|
|
357
|
+
}
|
|
358
|
+
)) == null ? void 0 : _a2.id) || null
|
|
359
|
+
};
|
|
360
|
+
})
|
|
361
|
+
};
|
|
362
|
+
};
|
|
363
|
+
var createUsageSubscription = async ({ fetcher, adminAccessToken, cappedAmount, currencyCode = "USD", domain, name, recurringPrice = 0, returnUrl, terms, test = false }) => {
|
|
364
|
+
if (!name || !returnUrl || !terms || !(Number(cappedAmount) > 0)) {
|
|
365
|
+
throw new Error("createUsageSubscription requires name, returnUrl, terms, and a positive cappedAmount");
|
|
366
|
+
}
|
|
367
|
+
;
|
|
368
|
+
const data = await adminFetch({
|
|
369
|
+
fetcher,
|
|
370
|
+
adminAccessToken,
|
|
371
|
+
domain,
|
|
372
|
+
query: `mutation createUsageSubscription( $lineItems : [AppSubscriptionLineItemInput!]!, $name : String!, $returnUrl : URL!, $test : Boolean ) {
|
|
373
|
+
appSubscriptionCreate( lineItems : $lineItems, name : $name, returnUrl : $returnUrl, test : $test ) {
|
|
374
|
+
appSubscription { id name status test lineItems { id plan { pricingDetails { __typename } } } }
|
|
375
|
+
confirmationUrl
|
|
376
|
+
userErrors { field message }
|
|
377
|
+
}
|
|
378
|
+
}`,
|
|
379
|
+
variables: {
|
|
380
|
+
lineItems: [
|
|
381
|
+
{
|
|
382
|
+
plan: {
|
|
383
|
+
appRecurringPricingDetails: {
|
|
384
|
+
interval: "EVERY_30_DAYS",
|
|
385
|
+
price: { amount: Number(recurringPrice), currencyCode }
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
plan: {
|
|
391
|
+
appUsagePricingDetails: {
|
|
392
|
+
cappedAmount: { amount: Number(cappedAmount), currencyCode },
|
|
393
|
+
terms
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
],
|
|
398
|
+
name,
|
|
399
|
+
returnUrl,
|
|
400
|
+
test
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
const payload = data == null ? void 0 : data.appSubscriptionCreate;
|
|
404
|
+
const userErrors = (payload == null ? void 0 : payload.userErrors) || [];
|
|
405
|
+
if (userErrors.length) {
|
|
406
|
+
throw new Error("Shopify subscription create failed: " + userErrors.map((entry) => entry.message).join("; "));
|
|
407
|
+
}
|
|
408
|
+
;
|
|
409
|
+
if (!(payload == null ? void 0 : payload.confirmationUrl)) {
|
|
410
|
+
throw new Error("Shopify subscription create failed: no confirmation url returned");
|
|
411
|
+
}
|
|
412
|
+
;
|
|
413
|
+
return {
|
|
414
|
+
confirmationUrl: payload.confirmationUrl,
|
|
415
|
+
subscription: payload.appSubscription
|
|
416
|
+
};
|
|
417
|
+
};
|
|
418
|
+
var createUsageRecord = async ({ fetcher, adminAccessToken, amount, currencyCode = "USD", description, domain, idempotencyKey, subscriptionLineItemId }) => {
|
|
419
|
+
var _a;
|
|
420
|
+
if (!subscriptionLineItemId || !description || !(Number(amount) > 0)) {
|
|
421
|
+
throw new Error("createUsageRecord requires subscriptionLineItemId, description, and a positive amount");
|
|
422
|
+
}
|
|
423
|
+
;
|
|
424
|
+
const data = await adminFetch({
|
|
425
|
+
fetcher,
|
|
426
|
+
adminAccessToken,
|
|
427
|
+
domain,
|
|
428
|
+
query: `mutation createUsageRecord( $description : String!, $idempotencyKey : String, $price : MoneyInput!, $subscriptionLineItemId : ID! ) {
|
|
429
|
+
appUsageRecordCreate( description : $description, idempotencyKey : $idempotencyKey, price : $price, subscriptionLineItemId : $subscriptionLineItemId ) {
|
|
430
|
+
appUsageRecord { id }
|
|
431
|
+
userErrors { field message }
|
|
432
|
+
}
|
|
433
|
+
}`,
|
|
434
|
+
variables: {
|
|
435
|
+
description,
|
|
436
|
+
idempotencyKey: idempotencyKey ? String(idempotencyKey) : null,
|
|
437
|
+
price: { amount: Number(amount), currencyCode },
|
|
438
|
+
subscriptionLineItemId
|
|
439
|
+
}
|
|
440
|
+
});
|
|
441
|
+
const payload = data == null ? void 0 : data.appUsageRecordCreate;
|
|
442
|
+
const userErrors = (payload == null ? void 0 : payload.userErrors) || [];
|
|
443
|
+
if (userErrors.length || !((_a = payload == null ? void 0 : payload.appUsageRecord) == null ? void 0 : _a.id)) {
|
|
444
|
+
throw new Error("Shopify usage record failed: " + (userErrors.map((entry) => entry.message).join("; ") || "no record returned"));
|
|
445
|
+
}
|
|
446
|
+
;
|
|
447
|
+
return { id: payload.appUsageRecord.id };
|
|
448
|
+
};
|
|
449
|
+
var getProductInventory = async ({ fetcher, adminAccessToken, domain, productId }) => {
|
|
450
|
+
var _a, _b;
|
|
451
|
+
const data = await adminFetch({
|
|
452
|
+
fetcher,
|
|
453
|
+
adminAccessToken,
|
|
454
|
+
domain,
|
|
455
|
+
query: `{
|
|
456
|
+
product( id : "${productId}" ) {
|
|
457
|
+
variants( first : 100 ) {
|
|
458
|
+
edges {
|
|
459
|
+
node {
|
|
460
|
+
id
|
|
461
|
+
inventoryQuantity
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}`
|
|
467
|
+
});
|
|
468
|
+
const edges = ((_b = (_a = data == null ? void 0 : data.product) == null ? void 0 : _a.variants) == null ? void 0 : _b.edges) || [];
|
|
469
|
+
return edges.reduce((accumulator, edge) => {
|
|
470
|
+
var _a2, _b2;
|
|
471
|
+
const id = (_a2 = edge == null ? void 0 : edge.node) == null ? void 0 : _a2.id;
|
|
472
|
+
const quantity = (_b2 = edge == null ? void 0 : edge.node) == null ? void 0 : _b2.inventoryQuantity;
|
|
473
|
+
if (id) {
|
|
474
|
+
accumulator[id] = Number.isFinite(quantity) ? quantity : 0;
|
|
475
|
+
}
|
|
476
|
+
;
|
|
477
|
+
return accumulator;
|
|
478
|
+
}, {});
|
|
479
|
+
};
|
|
480
|
+
var getProductUpdatedAt = async ({ adminAccessToken, domain, fetcher, productId }) => {
|
|
481
|
+
var _a;
|
|
482
|
+
const data = await adminFetch({
|
|
483
|
+
fetcher,
|
|
484
|
+
adminAccessToken,
|
|
485
|
+
domain,
|
|
486
|
+
query: `
|
|
487
|
+
query ProductUpdatedAt($id: ID!) {
|
|
488
|
+
product(id: $id) {
|
|
489
|
+
updatedAt
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
`,
|
|
493
|
+
variables: { id: productId }
|
|
494
|
+
});
|
|
495
|
+
return ((_a = data == null ? void 0 : data.product) == null ? void 0 : _a.updatedAt) || null;
|
|
496
|
+
};
|
|
497
|
+
var NOT_ON_CHANNEL = "not available to the channel";
|
|
498
|
+
var OUTDATED_FEEDBACK = "later version";
|
|
499
|
+
var sendProductResourceFeedback = async ({ fetcher, adminAccessToken, domain, productId, state, messages = [] }) => {
|
|
500
|
+
var _a, _b, _c;
|
|
501
|
+
const productUpdatedAt = await getProductUpdatedAt({ adminAccessToken, domain, fetcher, productId });
|
|
502
|
+
if (!productUpdatedAt) return null;
|
|
503
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
504
|
+
const submit = async (version) => {
|
|
505
|
+
const data = await adminFetch({
|
|
506
|
+
fetcher,
|
|
507
|
+
adminAccessToken,
|
|
508
|
+
domain,
|
|
509
|
+
query: `
|
|
510
|
+
mutation ProductFeedback($feedbackInput: [ProductResourceFeedbackInput!]!) {
|
|
511
|
+
bulkProductResourceFeedbackCreate(feedbackInput: $feedbackInput) {
|
|
512
|
+
feedback {
|
|
513
|
+
productId
|
|
514
|
+
state
|
|
515
|
+
}
|
|
516
|
+
userErrors {
|
|
517
|
+
field
|
|
518
|
+
message
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
`,
|
|
523
|
+
variables: {
|
|
524
|
+
feedbackInput: [
|
|
525
|
+
{
|
|
526
|
+
productId,
|
|
527
|
+
state,
|
|
528
|
+
feedbackGeneratedAt: now,
|
|
529
|
+
productUpdatedAt: version,
|
|
530
|
+
messages
|
|
531
|
+
}
|
|
532
|
+
]
|
|
533
|
+
}
|
|
534
|
+
});
|
|
535
|
+
return data == null ? void 0 : data.bulkProductResourceFeedbackCreate;
|
|
536
|
+
};
|
|
537
|
+
let result = await submit(productUpdatedAt);
|
|
538
|
+
if ((((_b = (_a = result == null ? void 0 : result.userErrors) == null ? void 0 : _a[0]) == null ? void 0 : _b.message) || "").toLowerCase().includes(OUTDATED_FEEDBACK)) {
|
|
539
|
+
result = await submit(now);
|
|
540
|
+
}
|
|
541
|
+
;
|
|
542
|
+
const feedbackErrors = result == null ? void 0 : result.userErrors;
|
|
543
|
+
if (feedbackErrors == null ? void 0 : feedbackErrors.length) {
|
|
544
|
+
const message = feedbackErrors[0].message || "";
|
|
545
|
+
if (message.toLowerCase().includes(NOT_ON_CHANNEL)) return null;
|
|
546
|
+
throw new Error("Shopify product feedback failed: " + message);
|
|
547
|
+
}
|
|
548
|
+
;
|
|
549
|
+
return ((_c = result == null ? void 0 : result.feedback) == null ? void 0 : _c[0]) || null;
|
|
550
|
+
};
|
|
551
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
552
|
+
0 && (module.exports = {
|
|
553
|
+
adminFetch,
|
|
554
|
+
createDiscountCode,
|
|
555
|
+
createUsageRecord,
|
|
556
|
+
createUsageSubscription,
|
|
557
|
+
getActiveAppSubscriptions,
|
|
558
|
+
getDiscounts,
|
|
559
|
+
getOrCreateCustomer,
|
|
560
|
+
getProductInventory,
|
|
561
|
+
sendProductResourceFeedback
|
|
562
|
+
});
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import '../http.cjs';
|
|
2
|
+
import './constants.cjs';
|
|
3
|
+
export { a as adminFetch, c as createDiscountCode, b as createUsageRecord, d as createUsageSubscription, g as getActiveAppSubscriptions, e as getDiscounts, f as getOrCreateCustomer, h as getProductInventory, s as sendProductResourceFeedback } from '../admin-B9ZaLvan.cjs';
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import '../http.js';
|
|
2
|
+
import './constants.js';
|
|
3
|
+
export { a as adminFetch, c as createDiscountCode, b as createUsageRecord, d as createUsageSubscription, g as getActiveAppSubscriptions, e as getDiscounts, f as getOrCreateCustomer, h as getProductInventory, s as sendProductResourceFeedback } from '../admin-C3HtEM6h.js';
|