@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
|
@@ -0,0 +1,509 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
|
|
29
|
+
// lib/shopify/oauth.js
|
|
30
|
+
var oauth_exports = {};
|
|
31
|
+
__export(oauth_exports, {
|
|
32
|
+
SHOPIFY_REQUIRED_SCOPES: () => SHOPIFY_REQUIRED_SCOPES,
|
|
33
|
+
createStorefrontToken: () => createStorefrontToken,
|
|
34
|
+
getAdminToken: () => getAdminToken,
|
|
35
|
+
getShop: () => getShop,
|
|
36
|
+
missingScopes: () => missingScopes,
|
|
37
|
+
ping: () => ping,
|
|
38
|
+
refreshAdminToken: () => refreshAdminToken,
|
|
39
|
+
resolveConnectionSettings: () => resolveConnectionSettings
|
|
40
|
+
});
|
|
41
|
+
module.exports = __toCommonJS(oauth_exports);
|
|
42
|
+
|
|
43
|
+
// lib/encrypt.js
|
|
44
|
+
var import_crypto2 = __toESM(require("crypto"), 1);
|
|
45
|
+
|
|
46
|
+
// lib/token.js
|
|
47
|
+
var import_crypto = __toESM(require("crypto"), 1);
|
|
48
|
+
var generate = (bytes = 32, encoding = "base64url") => {
|
|
49
|
+
const buf = import_crypto.default.randomBytes(bytes);
|
|
50
|
+
return encoding ? buf.toString(encoding) : buf;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// lib/encrypt.js
|
|
54
|
+
var ALGORITHM = "aes-256-gcm";
|
|
55
|
+
var getKey = () => Buffer.from(process.env.ENCRYPT_CONNECTION_SECRET, "hex");
|
|
56
|
+
var encrypt = (value) => {
|
|
57
|
+
const iv = generate(12, null);
|
|
58
|
+
const cipher = import_crypto2.default.createCipheriv(ALGORITHM, getKey(), iv);
|
|
59
|
+
const data = Buffer.concat([
|
|
60
|
+
cipher.update(JSON.stringify(value), "utf8"),
|
|
61
|
+
cipher.final()
|
|
62
|
+
]);
|
|
63
|
+
const tag = cipher.getAuthTag();
|
|
64
|
+
return [iv, tag, data].map((b) => b.toString("hex")).join(":");
|
|
65
|
+
};
|
|
66
|
+
var decrypt = (value) => {
|
|
67
|
+
if (typeof value !== "string") return value;
|
|
68
|
+
const [ivHex, tagHex, dataHex] = value.split(":");
|
|
69
|
+
const decipher = import_crypto2.default.createDecipheriv(
|
|
70
|
+
ALGORITHM,
|
|
71
|
+
getKey(),
|
|
72
|
+
Buffer.from(ivHex, "hex")
|
|
73
|
+
);
|
|
74
|
+
decipher.setAuthTag(Buffer.from(tagHex, "hex"));
|
|
75
|
+
const result = Buffer.concat([
|
|
76
|
+
decipher.update(Buffer.from(dataHex, "hex")),
|
|
77
|
+
decipher.final()
|
|
78
|
+
]);
|
|
79
|
+
return JSON.parse(result.toString("utf8"));
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
// lib/http.js
|
|
83
|
+
var DEFAULT_TIMEOUT_MS = 15e3;
|
|
84
|
+
var request = async ({
|
|
85
|
+
body,
|
|
86
|
+
// THE TRANSPORT, injectable and defaulted to the real one.
|
|
87
|
+
//
|
|
88
|
+
// Every other vendor client in this package takes a `fetcher` — it is how
|
|
89
|
+
// klaviyo, mailchimp and attentive are tested without a network, and it is a
|
|
90
|
+
// declared HOOK_OPTION. The Shopify client had no seam at all, so the only way
|
|
91
|
+
// to test a hook that used it was to inject the whole SDK namespace; that
|
|
92
|
+
// injection existed to work around an import cycle, and when the cycle went
|
|
93
|
+
// the tests lost their only hold. This is the seam they should have had.
|
|
94
|
+
fetcher = fetch,
|
|
95
|
+
headers = {},
|
|
96
|
+
method = "GET",
|
|
97
|
+
query,
|
|
98
|
+
timeout = DEFAULT_TIMEOUT_MS,
|
|
99
|
+
type = "json",
|
|
100
|
+
url
|
|
101
|
+
}) => {
|
|
102
|
+
const fullUrl = new URL(url);
|
|
103
|
+
if (query) {
|
|
104
|
+
Object.entries(query).forEach(([k, v]) => fullUrl.searchParams.set(k, v));
|
|
105
|
+
}
|
|
106
|
+
;
|
|
107
|
+
const isForm = type === "form";
|
|
108
|
+
const response = await fetcher(fullUrl.toString(), {
|
|
109
|
+
method,
|
|
110
|
+
headers: {
|
|
111
|
+
"Content-Type": isForm ? "application/x-www-form-urlencoded" : "application/json",
|
|
112
|
+
...headers
|
|
113
|
+
},
|
|
114
|
+
signal: AbortSignal.timeout(timeout),
|
|
115
|
+
...body !== void 0 && {
|
|
116
|
+
body: isForm ? new URLSearchParams(body).toString() : JSON.stringify(body)
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
if (!response.ok) {
|
|
120
|
+
const text2 = await response.text().catch(() => "");
|
|
121
|
+
const error = new Error(text2 || response.statusText);
|
|
122
|
+
error.status = response.status;
|
|
123
|
+
throw error;
|
|
124
|
+
}
|
|
125
|
+
;
|
|
126
|
+
const text = await response.text();
|
|
127
|
+
try {
|
|
128
|
+
return text ? JSON.parse(text) : null;
|
|
129
|
+
} catch {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
// lib/shopify/constants.js
|
|
135
|
+
var SHOPIFY_ADMIN_API_VERSION = "2026-04";
|
|
136
|
+
var SHOPIFY_REQUIRED_SCOPES = [
|
|
137
|
+
"read_customers",
|
|
138
|
+
"write_customers",
|
|
139
|
+
"read_discounts",
|
|
140
|
+
"write_discounts",
|
|
141
|
+
"read_orders",
|
|
142
|
+
"read_products",
|
|
143
|
+
"read_publications",
|
|
144
|
+
"write_resource_feedbacks",
|
|
145
|
+
"unauthenticated_read_checkouts",
|
|
146
|
+
"unauthenticated_read_product_inventory",
|
|
147
|
+
"unauthenticated_read_product_listings",
|
|
148
|
+
"unauthenticated_write_checkouts"
|
|
149
|
+
];
|
|
150
|
+
var REFRESH_TOKEN_LIFETIME_MS = 90 * 24 * 60 * 60 * 1e3;
|
|
151
|
+
var ACCESS_TOKEN_REFRESH_BUFFER_MS = 5 * 60 * 1e3;
|
|
152
|
+
var PARTNER_API_VERSION = process.env.SHOPIFY_PARTNER_API_VERSION || "2026-07";
|
|
153
|
+
|
|
154
|
+
// lib/shopify/admin.js
|
|
155
|
+
var adminUrl = (domain) => `https://${domain}/admin/api/${SHOPIFY_ADMIN_API_VERSION}`;
|
|
156
|
+
var adminFetch = async ({ adminAccessToken, domain, fetcher, query, variables }) => {
|
|
157
|
+
var _a;
|
|
158
|
+
const { data, errors } = await request({
|
|
159
|
+
fetcher,
|
|
160
|
+
method: "POST",
|
|
161
|
+
url: adminUrl(domain) + "/graphql.json",
|
|
162
|
+
headers: {
|
|
163
|
+
"X-Shopify-Access-Token": adminAccessToken
|
|
164
|
+
},
|
|
165
|
+
body: {
|
|
166
|
+
query,
|
|
167
|
+
...variables && { variables }
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
if (errors) {
|
|
171
|
+
throw new Error("Shopify GraphQL error: " + ((_a = errors[0]) == null ? void 0 : _a.message));
|
|
172
|
+
}
|
|
173
|
+
;
|
|
174
|
+
return data;
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
// lib/shopify/oauth.js
|
|
178
|
+
var required = (name, value) => {
|
|
179
|
+
if (!value) {
|
|
180
|
+
throw new Error("Shopify " + name + " is required");
|
|
181
|
+
}
|
|
182
|
+
;
|
|
183
|
+
return value;
|
|
184
|
+
};
|
|
185
|
+
var missingScopes = (granted) => {
|
|
186
|
+
const grantedSet = new Set(
|
|
187
|
+
(Array.isArray(granted) ? granted : String(granted || "").split(",")).map((scope) => scope.trim()).filter(Boolean)
|
|
188
|
+
);
|
|
189
|
+
const satisfied = (scope) => grantedSet.has(scope) || grantedSet.has(scope.replace(/(^|_)read_/, "$1write_"));
|
|
190
|
+
return SHOPIFY_REQUIRED_SCOPES.filter((scope) => !satisfied(scope));
|
|
191
|
+
};
|
|
192
|
+
var ping = async ({ fetcher, adminAccessToken, domain }) => {
|
|
193
|
+
var _a;
|
|
194
|
+
const response = await fetch(
|
|
195
|
+
`https://${domain}/admin/api/${SHOPIFY_ADMIN_API_VERSION}/graphql.json`,
|
|
196
|
+
{
|
|
197
|
+
body: JSON.stringify({ query: "{ shop { name } }" }),
|
|
198
|
+
headers: {
|
|
199
|
+
"Content-Type": "application/json",
|
|
200
|
+
"X-Shopify-Access-Token": adminAccessToken
|
|
201
|
+
},
|
|
202
|
+
method: "POST"
|
|
203
|
+
}
|
|
204
|
+
);
|
|
205
|
+
if (!response.ok) {
|
|
206
|
+
const text = await response.text().catch(() => "");
|
|
207
|
+
const error = new Error(response.status + ": " + text);
|
|
208
|
+
error.status = response.status;
|
|
209
|
+
throw error;
|
|
210
|
+
}
|
|
211
|
+
;
|
|
212
|
+
const { errors } = await response.json().catch(() => ({}));
|
|
213
|
+
if (errors == null ? void 0 : errors.length) {
|
|
214
|
+
throw new Error("GraphQL: " + (((_a = errors[0]) == null ? void 0 : _a.message) || "unknown error"));
|
|
215
|
+
}
|
|
216
|
+
;
|
|
217
|
+
};
|
|
218
|
+
var OAUTH_ERROR_TITLE_PATTERN = /Oauth error (\w+)/i;
|
|
219
|
+
var parseOAuthErrorCode = (text) => {
|
|
220
|
+
var _a;
|
|
221
|
+
try {
|
|
222
|
+
const parsed = JSON.parse(text);
|
|
223
|
+
if (parsed == null ? void 0 : parsed.error) return parsed.error;
|
|
224
|
+
} catch {
|
|
225
|
+
}
|
|
226
|
+
;
|
|
227
|
+
return ((_a = text.match(OAUTH_ERROR_TITLE_PATTERN)) == null ? void 0 : _a[1]) || null;
|
|
228
|
+
};
|
|
229
|
+
var shopifyOAuthFetch = async (url, body) => {
|
|
230
|
+
const response = await fetch(url, {
|
|
231
|
+
method: "POST",
|
|
232
|
+
headers: {
|
|
233
|
+
"Content-Type": "application/json"
|
|
234
|
+
},
|
|
235
|
+
body: JSON.stringify(body)
|
|
236
|
+
});
|
|
237
|
+
if (!response.ok) {
|
|
238
|
+
const text = await response.text().catch(() => "");
|
|
239
|
+
const error = new Error(response.status + ": " + text);
|
|
240
|
+
error.status = response.status;
|
|
241
|
+
error.code = parseOAuthErrorCode(text);
|
|
242
|
+
throw error;
|
|
243
|
+
}
|
|
244
|
+
;
|
|
245
|
+
return response.json();
|
|
246
|
+
};
|
|
247
|
+
var getShop = async ({ fetcher, adminAccessToken, shop }) => {
|
|
248
|
+
const data = await adminFetch({
|
|
249
|
+
fetcher,
|
|
250
|
+
adminAccessToken,
|
|
251
|
+
domain: shop,
|
|
252
|
+
query: `{
|
|
253
|
+
shop {
|
|
254
|
+
currencyCode
|
|
255
|
+
id
|
|
256
|
+
myshopifyDomain
|
|
257
|
+
name
|
|
258
|
+
}
|
|
259
|
+
}`
|
|
260
|
+
});
|
|
261
|
+
const shopData = data == null ? void 0 : data.shop;
|
|
262
|
+
if (!(shopData == null ? void 0 : shopData.id)) {
|
|
263
|
+
throw new Error("Shopify shop lookup failed: no shop returned");
|
|
264
|
+
}
|
|
265
|
+
;
|
|
266
|
+
return {
|
|
267
|
+
currency: shopData.currencyCode || null,
|
|
268
|
+
id: shopData.id.split("/").pop(),
|
|
269
|
+
myshopifyDomain: shopData.myshopifyDomain,
|
|
270
|
+
name: shopData.name
|
|
271
|
+
};
|
|
272
|
+
};
|
|
273
|
+
var createStorefrontToken = async ({ fetcher, adminAccessToken, shop }) => {
|
|
274
|
+
var _a, _b, _c, _d, _e;
|
|
275
|
+
try {
|
|
276
|
+
const listed = await adminFetch({
|
|
277
|
+
fetcher,
|
|
278
|
+
adminAccessToken,
|
|
279
|
+
domain: shop,
|
|
280
|
+
query: `{
|
|
281
|
+
shop {
|
|
282
|
+
storefrontAccessTokens(first: 100) {
|
|
283
|
+
edges {
|
|
284
|
+
node {
|
|
285
|
+
id
|
|
286
|
+
title
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}`
|
|
292
|
+
});
|
|
293
|
+
const existing = (((_b = (_a = listed == null ? void 0 : listed.shop) == null ? void 0 : _a.storefrontAccessTokens) == null ? void 0 : _b.edges) || []).map((edge) => edge == null ? void 0 : edge.node);
|
|
294
|
+
const orphaned = existing.filter((token) => (token == null ? void 0 : token.title) === "Drawbridge");
|
|
295
|
+
await Promise.allSettled(
|
|
296
|
+
orphaned.map((token) => adminFetch({
|
|
297
|
+
adminAccessToken,
|
|
298
|
+
domain: shop,
|
|
299
|
+
query: `
|
|
300
|
+
mutation StorefrontAccessTokenDelete($input: StorefrontAccessTokenDeleteInput!) {
|
|
301
|
+
storefrontAccessTokenDelete(input: $input) {
|
|
302
|
+
deletedStorefrontAccessTokenId
|
|
303
|
+
userErrors {
|
|
304
|
+
field
|
|
305
|
+
message
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
`,
|
|
310
|
+
variables: {
|
|
311
|
+
input: {
|
|
312
|
+
id: token.id
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}))
|
|
316
|
+
);
|
|
317
|
+
} catch {
|
|
318
|
+
}
|
|
319
|
+
const created = await adminFetch({
|
|
320
|
+
fetcher,
|
|
321
|
+
adminAccessToken,
|
|
322
|
+
domain: shop,
|
|
323
|
+
query: `
|
|
324
|
+
mutation StorefrontAccessTokenCreate($input: StorefrontAccessTokenInput!) {
|
|
325
|
+
storefrontAccessTokenCreate(input: $input) {
|
|
326
|
+
storefrontAccessToken {
|
|
327
|
+
accessToken
|
|
328
|
+
}
|
|
329
|
+
userErrors {
|
|
330
|
+
field
|
|
331
|
+
message
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
`,
|
|
336
|
+
variables: {
|
|
337
|
+
input: {
|
|
338
|
+
title: "Drawbridge"
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
const createErrors = (_c = created == null ? void 0 : created.storefrontAccessTokenCreate) == null ? void 0 : _c.userErrors;
|
|
343
|
+
if (createErrors == null ? void 0 : createErrors.length) {
|
|
344
|
+
throw new Error("Shopify storefront token create failed: " + createErrors[0].message);
|
|
345
|
+
}
|
|
346
|
+
;
|
|
347
|
+
return ((_e = (_d = created == null ? void 0 : created.storefrontAccessTokenCreate) == null ? void 0 : _d.storefrontAccessToken) == null ? void 0 : _e.accessToken) || null;
|
|
348
|
+
};
|
|
349
|
+
var resolveTokenContext = async ({ connection, controller }) => {
|
|
350
|
+
const decrypted = (connection == null ? void 0 : connection.settings) ? decrypt(connection.settings) : {};
|
|
351
|
+
if ((decrypted == null ? void 0 : decrypted.ref) !== "shop") {
|
|
352
|
+
return {
|
|
353
|
+
raw: (connection == null ? void 0 : connection.settings) || null,
|
|
354
|
+
session: null,
|
|
355
|
+
settings: decrypted,
|
|
356
|
+
shop: null,
|
|
357
|
+
target: "connection"
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
;
|
|
361
|
+
const shop = decrypted.shop;
|
|
362
|
+
if (!controller || !shop) {
|
|
363
|
+
return { raw: null, session: {}, settings: {}, shop, target: "shop" };
|
|
364
|
+
}
|
|
365
|
+
;
|
|
366
|
+
const record = await controller.get({ collection: "shop", query: { shop } });
|
|
367
|
+
const session = (record == null ? void 0 : record.settings) ? decrypt(record.settings) : {};
|
|
368
|
+
const storefront = (record == null ? void 0 : record.storefront) ? decrypt(record.storefront) : null;
|
|
369
|
+
return {
|
|
370
|
+
raw: (record == null ? void 0 : record.settings) || null,
|
|
371
|
+
session,
|
|
372
|
+
settings: {
|
|
373
|
+
adminAccessToken: session.accessToken || null,
|
|
374
|
+
refreshToken: session.refreshToken || null,
|
|
375
|
+
refreshTokenExpiresAt: session.refreshTokenExpires || null,
|
|
376
|
+
storefrontAccessToken: (storefront == null ? void 0 : storefront.token) || null,
|
|
377
|
+
tokenExpiresAt: session.expires || null
|
|
378
|
+
},
|
|
379
|
+
shop,
|
|
380
|
+
target: "shop"
|
|
381
|
+
};
|
|
382
|
+
};
|
|
383
|
+
var resolveConnectionSettings = async ({ fetcher, connection, controller }) => {
|
|
384
|
+
const { settings } = await resolveTokenContext({ connection, controller });
|
|
385
|
+
return settings;
|
|
386
|
+
};
|
|
387
|
+
var refreshAdminToken = async ({ fetcher, clientId, clientSecret, connection, controller }) => {
|
|
388
|
+
var _a;
|
|
389
|
+
const { raw, session, settings, shop, target } = await resolveTokenContext({ connection, controller });
|
|
390
|
+
const domain = (connection == null ? void 0 : connection.shop) || ((_a = settings.source) == null ? void 0 : _a.domain) || settings.domain || shop;
|
|
391
|
+
const { refreshToken } = settings;
|
|
392
|
+
const data = await shopifyOAuthFetch(
|
|
393
|
+
`https://${domain}/admin/oauth/access_token`,
|
|
394
|
+
{
|
|
395
|
+
grant_type: "refresh_token",
|
|
396
|
+
// Throw before the grant: rotation RETIRES the old pair the moment it
|
|
397
|
+
// returns, so a credential-less call that Shopify rejects opaquely is
|
|
398
|
+
// the one failure mode worth being loud about.
|
|
399
|
+
client_id: required("clientId", clientId),
|
|
400
|
+
client_secret: required("clientSecret", clientSecret),
|
|
401
|
+
refresh_token: refreshToken
|
|
402
|
+
}
|
|
403
|
+
);
|
|
404
|
+
const adminAccessToken = data.access_token;
|
|
405
|
+
const newRefreshToken = data.refresh_token;
|
|
406
|
+
const expiresIn = data.expires_in;
|
|
407
|
+
const tokenExpiresAt = expiresIn ? new Date(Date.now() + expiresIn * 1e3) : null;
|
|
408
|
+
const refreshTokenExpiresAt = new Date(Date.now() + REFRESH_TOKEN_LIFETIME_MS);
|
|
409
|
+
let liveToken = adminAccessToken;
|
|
410
|
+
if (target === "shop") {
|
|
411
|
+
const written = await controller.update({
|
|
412
|
+
collection: "shop",
|
|
413
|
+
data: {
|
|
414
|
+
$set: {
|
|
415
|
+
settings: encrypt({
|
|
416
|
+
...session,
|
|
417
|
+
accessToken: adminAccessToken,
|
|
418
|
+
expires: tokenExpiresAt,
|
|
419
|
+
refreshToken: newRefreshToken,
|
|
420
|
+
refreshTokenExpires: refreshTokenExpiresAt
|
|
421
|
+
})
|
|
422
|
+
}
|
|
423
|
+
},
|
|
424
|
+
query: {
|
|
425
|
+
shop,
|
|
426
|
+
...raw && { settings: raw }
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
if (!written) {
|
|
430
|
+
const current = await controller.get({ collection: "shop", query: { shop } });
|
|
431
|
+
if (!(current == null ? void 0 : current.settings)) {
|
|
432
|
+
throw new Error("Shopify token refresh write-back failed: shop record missing for " + shop);
|
|
433
|
+
}
|
|
434
|
+
;
|
|
435
|
+
const currentSession = decrypt(current.settings);
|
|
436
|
+
if ((currentSession == null ? void 0 : currentSession.accessToken) && currentSession.accessToken !== settings.adminAccessToken) {
|
|
437
|
+
liveToken = currentSession.accessToken;
|
|
438
|
+
} else {
|
|
439
|
+
throw new Error("Shopify token refresh write-back failed for " + shop);
|
|
440
|
+
}
|
|
441
|
+
;
|
|
442
|
+
}
|
|
443
|
+
;
|
|
444
|
+
} else {
|
|
445
|
+
const written = await controller.update({
|
|
446
|
+
collection: "connection",
|
|
447
|
+
data: {
|
|
448
|
+
$set: {
|
|
449
|
+
settings: encrypt({
|
|
450
|
+
...settings,
|
|
451
|
+
adminAccessToken,
|
|
452
|
+
refreshToken: newRefreshToken,
|
|
453
|
+
refreshTokenExpiresAt,
|
|
454
|
+
tokenExpiresAt
|
|
455
|
+
})
|
|
456
|
+
}
|
|
457
|
+
},
|
|
458
|
+
query: {
|
|
459
|
+
id: connection.id,
|
|
460
|
+
...raw && { settings: raw }
|
|
461
|
+
}
|
|
462
|
+
});
|
|
463
|
+
if (!written) {
|
|
464
|
+
const current = await controller.get({ collection: "connection", query: { id: connection.id } });
|
|
465
|
+
const currentSettings = (current == null ? void 0 : current.settings) ? decrypt(current.settings) : null;
|
|
466
|
+
if ((currentSettings == null ? void 0 : currentSettings.adminAccessToken) && currentSettings.adminAccessToken !== settings.adminAccessToken) {
|
|
467
|
+
liveToken = currentSettings.adminAccessToken;
|
|
468
|
+
} else {
|
|
469
|
+
throw new Error("Shopify token refresh write-back failed for connection " + (connection == null ? void 0 : connection.id));
|
|
470
|
+
}
|
|
471
|
+
;
|
|
472
|
+
}
|
|
473
|
+
;
|
|
474
|
+
}
|
|
475
|
+
;
|
|
476
|
+
await ping({ adminAccessToken: liveToken, domain });
|
|
477
|
+
return liveToken;
|
|
478
|
+
};
|
|
479
|
+
var getAdminToken = async ({ fetcher, clientId, clientSecret, connection, controller }) => {
|
|
480
|
+
required("clientId", clientId);
|
|
481
|
+
required("clientSecret", clientSecret);
|
|
482
|
+
const settings = await resolveConnectionSettings({ connection, controller });
|
|
483
|
+
const { adminAccessToken, refreshToken, tokenExpiresAt } = settings;
|
|
484
|
+
if (!adminAccessToken) {
|
|
485
|
+
return null;
|
|
486
|
+
}
|
|
487
|
+
;
|
|
488
|
+
if (!refreshToken) {
|
|
489
|
+
return adminAccessToken;
|
|
490
|
+
}
|
|
491
|
+
;
|
|
492
|
+
const needsRefresh = !tokenExpiresAt || new Date(tokenExpiresAt) < new Date(Date.now() + ACCESS_TOKEN_REFRESH_BUFFER_MS);
|
|
493
|
+
if (needsRefresh) {
|
|
494
|
+
return refreshAdminToken({ clientId, clientSecret, connection, controller });
|
|
495
|
+
}
|
|
496
|
+
;
|
|
497
|
+
return adminAccessToken;
|
|
498
|
+
};
|
|
499
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
500
|
+
0 && (module.exports = {
|
|
501
|
+
SHOPIFY_REQUIRED_SCOPES,
|
|
502
|
+
createStorefrontToken,
|
|
503
|
+
getAdminToken,
|
|
504
|
+
getShop,
|
|
505
|
+
missingScopes,
|
|
506
|
+
ping,
|
|
507
|
+
refreshAdminToken,
|
|
508
|
+
resolveConnectionSettings
|
|
509
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import '../encrypt.cjs';
|
|
2
|
+
import '../admin-B9ZaLvan.cjs';
|
|
3
|
+
export { SHOPIFY_REQUIRED_SCOPES } from './constants.cjs';
|
|
4
|
+
export { c as createStorefrontToken, g as getAdminToken, a as getShop, m as missingScopes, p as ping, r as refreshAdminToken, b as resolveConnectionSettings } from '../oauth-BJDh0sdM.cjs';
|
|
5
|
+
import 'crypto';
|
|
6
|
+
import '../token.cjs';
|
|
7
|
+
import '../http.cjs';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import '../encrypt.js';
|
|
2
|
+
import '../admin-C3HtEM6h.js';
|
|
3
|
+
export { SHOPIFY_REQUIRED_SCOPES } from './constants.js';
|
|
4
|
+
export { c as createStorefrontToken, g as getAdminToken, a as getShop, m as missingScopes, p as ping, r as refreshAdminToken, b as resolveConnectionSettings } from '../oauth-DveZMLHx.js';
|
|
5
|
+
import 'crypto';
|
|
6
|
+
import '../token.js';
|
|
7
|
+
import '../http.js';
|