@decocms/apps-shopify 8.1.0-next.0 → 8.1.0-next.1

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.
Files changed (42) hide show
  1. package/package.json +7 -24
  2. package/src/client.ts +113 -47
  3. package/src/index.ts +8 -50
  4. package/src/actions/cart/addItems.ts +0 -36
  5. package/src/actions/cart/updateCoupons.ts +0 -31
  6. package/src/actions/cart/updateItems.ts +0 -31
  7. package/src/actions/user/signIn.ts +0 -40
  8. package/src/actions/user/signUp.ts +0 -31
  9. package/src/init.ts +0 -39
  10. package/src/loaders/ProductDetailsPage.ts +0 -31
  11. package/src/loaders/ProductList.ts +0 -102
  12. package/src/loaders/ProductListingPage.ts +0 -172
  13. package/src/loaders/RelatedProducts.ts +0 -42
  14. package/src/loaders/cart.ts +0 -74
  15. package/src/loaders/shop.ts +0 -35
  16. package/src/loaders/user.ts +0 -39
  17. package/src/manifest.gen.ts +0 -39
  18. package/src/mod.ts +0 -67
  19. package/src/registry.ts +0 -9
  20. package/src/utils/__tests__/instrumentedFetch.test.ts +0 -84
  21. package/src/utils/__tests__/operationRouter.test.ts +0 -56
  22. package/src/utils/__tests__/transform.test.ts +0 -216
  23. package/src/utils/admin/admin.ts +0 -57
  24. package/src/utils/admin/queries.ts +0 -29
  25. package/src/utils/cart.ts +0 -32
  26. package/src/utils/cookies.ts +0 -82
  27. package/src/utils/enums.ts +0 -438
  28. package/src/utils/graphql.ts +0 -70
  29. package/src/utils/graphqlOperationName.ts +0 -2
  30. package/src/utils/instrumentedFetch.ts +0 -56
  31. package/src/utils/operationRouter.ts +0 -70
  32. package/src/utils/storefront/queries.ts +0 -525
  33. package/src/utils/storefront/storefront.graphql.gen.ts +0 -129
  34. package/src/utils/transform.ts +0 -430
  35. package/src/utils/types.ts +0 -191
  36. package/src/utils/user.ts +0 -23
  37. package/src/utils/utils.ts +0 -159
  38. package/src/v8/client.test.ts +0 -136
  39. package/src/v8/client.ts +0 -125
  40. package/src/v8/graphqlOperationName.test.ts +0 -80
  41. package/tsconfig.json +0 -7
  42. /package/src/{v8/graphqlOperationName.ts → graphqlOperationName.ts} +0 -0
@@ -1,438 +0,0 @@
1
- export enum CurrencyCode {
2
- AED = "AED",
3
- AFN = "AFN",
4
- ALL = "ALL",
5
- AMD = "AMD",
6
- ANG = "ANG",
7
- AOA = "AOA",
8
- ARS = "ARS",
9
- AUD = "AUD",
10
- AWG = "AWG",
11
- AZN = "AZN",
12
- BAM = "BAM",
13
- BBD = "BBD",
14
- BDT = "BDT",
15
- BGN = "BGN",
16
- BHD = "BHD",
17
- BIF = "BIF",
18
- BMD = "BMD",
19
- BND = "BND",
20
- BOB = "BOB",
21
- BRL = "BRL",
22
- BSD = "BSD",
23
- BTN = "BTN",
24
- BWP = "BWP",
25
- BYN = "BYN",
26
- BZD = "BZD",
27
- CAD = "CAD",
28
- CDF = "CDF",
29
- CHF = "CHF",
30
- CLP = "CLP",
31
- CNY = "CNY",
32
- COP = "COP",
33
- CRC = "CRC",
34
- CVE = "CVE",
35
- CZK = "CZK",
36
- DJF = "DJF",
37
- DKK = "DKK",
38
- DOP = "DOP",
39
- DZD = "DZD",
40
- EGP = "EGP",
41
- ERN = "ERN",
42
- ETB = "ETB",
43
- EUR = "EUR",
44
- FJD = "FJD",
45
- FKP = "FKP",
46
- GBP = "GBP",
47
- GEL = "GEL",
48
- GHS = "GHS",
49
- GIP = "GIP",
50
- GMD = "GMD",
51
- GNF = "GNF",
52
- GTQ = "GTQ",
53
- GYD = "GYD",
54
- HKD = "HKD",
55
- HNL = "HNL",
56
- HRK = "HRK",
57
- HTG = "HTG",
58
- HUF = "HUF",
59
- IDR = "IDR",
60
- ILS = "ILS",
61
- INR = "INR",
62
- IQD = "IQD",
63
- IRR = "IRR",
64
- ISK = "ISK",
65
- JEP = "JEP",
66
- JMD = "JMD",
67
- JOD = "JOD",
68
- JPY = "JPY",
69
- KES = "KES",
70
- KGS = "KGS",
71
- KHR = "KHR",
72
- KID = "KID",
73
- KMF = "KMF",
74
- KRW = "KRW",
75
- KWD = "KWD",
76
- KYD = "KYD",
77
- KZT = "KZT",
78
- LAK = "LAK",
79
- LBP = "LBP",
80
- LKR = "LKR",
81
- LRD = "LRD",
82
- LSL = "LSL",
83
- LTL = "LTL",
84
- LVL = "LVL",
85
- LYD = "LYD",
86
- MAD = "MAD",
87
- MDL = "MDL",
88
- MGA = "MGA",
89
- MKD = "MKD",
90
- MMK = "MMK",
91
- MNT = "MNT",
92
- MOP = "MOP",
93
- MRU = "MRU",
94
- MUR = "MUR",
95
- MVR = "MVR",
96
- MWK = "MWK",
97
- MXN = "MXN",
98
- MYR = "MYR",
99
- MZN = "MZN",
100
- NAD = "NAD",
101
- NGN = "NGN",
102
- NIO = "NIO",
103
- NOK = "NOK",
104
- NPR = "NPR",
105
- NZD = "NZD",
106
- OMR = "OMR",
107
- PAB = "PAB",
108
- PEN = "PEN",
109
- PGK = "PGK",
110
- PHP = "PHP",
111
- PKR = "PKR",
112
- PLN = "PLN",
113
- PYG = "PYG",
114
- QAR = "QAR",
115
- RON = "RON",
116
- RSD = "RSD",
117
- RUB = "RUB",
118
- RWF = "RWF",
119
- SAR = "SAR",
120
- SBD = "SBD",
121
- SCR = "SCR",
122
- SDG = "SDG",
123
- SEK = "SEK",
124
- SGD = "SGD",
125
- SHP = "SHP",
126
- SLL = "SLL",
127
- SOS = "SOS",
128
- SRD = "SRD",
129
- SSP = "SSP",
130
- STN = "STN",
131
- SYP = "SYP",
132
- SZL = "SZL",
133
- THB = "THB",
134
- TJS = "TJS",
135
- TMT = "TMT",
136
- TND = "TND",
137
- TOP = "TOP",
138
- TRY = "TRY",
139
- TTD = "TTD",
140
- TWD = "TWD",
141
- TZS = "TZS",
142
- UAH = "UAH",
143
- UGX = "UGX",
144
- USD = "USD",
145
- UYU = "UYU",
146
- UZS = "UZS",
147
- VED = "VED",
148
- VES = "VES",
149
- VND = "VND",
150
- VUV = "VUV",
151
- WST = "WST",
152
- XAF = "XAF",
153
- XCD = "XCD",
154
- XOF = "XOF",
155
- XPF = "XPF",
156
- XXX = "XXX",
157
- YER = "YER",
158
- ZAR = "ZAR",
159
- ZMW = "ZMW",
160
- }
161
-
162
- export enum CountryCode {
163
- AC = "AC",
164
- AD = "AD",
165
- AE = "AE",
166
- AF = "AF",
167
- AG = "AG",
168
- AI = "AI",
169
- AL = "AL",
170
- AM = "AM",
171
- AN = "AN",
172
- AO = "AO",
173
- AR = "AR",
174
- AT = "AT",
175
- AU = "AU",
176
- AW = "AW",
177
- AX = "AX",
178
- AZ = "AZ",
179
- BA = "BA",
180
- BB = "BB",
181
- BD = "BD",
182
- BE = "BE",
183
- BF = "BF",
184
- BG = "BG",
185
- BH = "BH",
186
- BI = "BI",
187
- BJ = "BJ",
188
- BL = "BL",
189
- BM = "BM",
190
- BN = "BN",
191
- BO = "BO",
192
- BQ = "BQ",
193
- BR = "BR",
194
- BS = "BS",
195
- BT = "BT",
196
- BV = "BV",
197
- BW = "BW",
198
- BY = "BY",
199
- BZ = "BZ",
200
- CA = "CA",
201
- CC = "CC",
202
- CD = "CD",
203
- CF = "CF",
204
- CG = "CG",
205
- CH = "CH",
206
- CI = "CI",
207
- CK = "CK",
208
- CL = "CL",
209
- CM = "CM",
210
- CN = "CN",
211
- CO = "CO",
212
- CR = "CR",
213
- CU = "CU",
214
- CV = "CV",
215
- CW = "CW",
216
- CX = "CX",
217
- CY = "CY",
218
- CZ = "CZ",
219
- DE = "DE",
220
- DJ = "DJ",
221
- DK = "DK",
222
- DM = "DM",
223
- DO = "DO",
224
- DZ = "DZ",
225
- EC = "EC",
226
- EE = "EE",
227
- EG = "EG",
228
- EH = "EH",
229
- ER = "ER",
230
- ES = "ES",
231
- ET = "ET",
232
- FI = "FI",
233
- FJ = "FJ",
234
- FK = "FK",
235
- FO = "FO",
236
- FR = "FR",
237
- GA = "GA",
238
- GB = "GB",
239
- GD = "GD",
240
- GE = "GE",
241
- GF = "GF",
242
- GG = "GG",
243
- GH = "GH",
244
- GI = "GI",
245
- GL = "GL",
246
- GM = "GM",
247
- GN = "GN",
248
- GP = "GP",
249
- GQ = "GQ",
250
- GR = "GR",
251
- GS = "GS",
252
- GT = "GT",
253
- GW = "GW",
254
- GY = "GY",
255
- HK = "HK",
256
- HM = "HM",
257
- HN = "HN",
258
- HR = "HR",
259
- HT = "HT",
260
- HU = "HU",
261
- ID = "ID",
262
- IE = "IE",
263
- IL = "IL",
264
- IM = "IM",
265
- IN = "IN",
266
- IO = "IO",
267
- IQ = "IQ",
268
- IR = "IR",
269
- IS = "IS",
270
- IT = "IT",
271
- JE = "JE",
272
- JM = "JM",
273
- JO = "JO",
274
- JP = "JP",
275
- KE = "KE",
276
- KG = "KG",
277
- KH = "KH",
278
- KI = "KI",
279
- KM = "KM",
280
- KN = "KN",
281
- KP = "KP",
282
- KR = "KR",
283
- KW = "KW",
284
- KY = "KY",
285
- KZ = "KZ",
286
- LA = "LA",
287
- LB = "LB",
288
- LC = "LC",
289
- LI = "LI",
290
- LK = "LK",
291
- LR = "LR",
292
- LS = "LS",
293
- LT = "LT",
294
- LU = "LU",
295
- LV = "LV",
296
- LY = "LY",
297
- MA = "MA",
298
- MC = "MC",
299
- MD = "MD",
300
- ME = "ME",
301
- MF = "MF",
302
- MG = "MG",
303
- MK = "MK",
304
- ML = "ML",
305
- MM = "MM",
306
- MN = "MN",
307
- MO = "MO",
308
- MQ = "MQ",
309
- MR = "MR",
310
- MS = "MS",
311
- MT = "MT",
312
- MU = "MU",
313
- MV = "MV",
314
- MW = "MW",
315
- MX = "MX",
316
- MY = "MY",
317
- MZ = "MZ",
318
- NA = "NA",
319
- NC = "NC",
320
- NE = "NE",
321
- NF = "NF",
322
- NG = "NG",
323
- NI = "NI",
324
- NL = "NL",
325
- NO = "NO",
326
- NP = "NP",
327
- NR = "NR",
328
- NU = "NU",
329
- NZ = "NZ",
330
- OM = "OM",
331
- PA = "PA",
332
- PE = "PE",
333
- PF = "PF",
334
- PG = "PG",
335
- PH = "PH",
336
- PK = "PK",
337
- PL = "PL",
338
- PM = "PM",
339
- PN = "PN",
340
- PS = "PS",
341
- PT = "PT",
342
- PY = "PY",
343
- QA = "QA",
344
- RE = "RE",
345
- RO = "RO",
346
- RS = "RS",
347
- RU = "RU",
348
- RW = "RW",
349
- SA = "SA",
350
- SB = "SB",
351
- SC = "SC",
352
- SD = "SD",
353
- SE = "SE",
354
- SG = "SG",
355
- SH = "SH",
356
- SI = "SI",
357
- SJ = "SJ",
358
- SK = "SK",
359
- SL = "SL",
360
- SM = "SM",
361
- SN = "SN",
362
- SO = "SO",
363
- SR = "SR",
364
- SS = "SS",
365
- ST = "ST",
366
- SV = "SV",
367
- SX = "SX",
368
- SY = "SY",
369
- SZ = "SZ",
370
- TA = "TA",
371
- TC = "TC",
372
- TD = "TD",
373
- TF = "TF",
374
- TG = "TG",
375
- TH = "TH",
376
- TJ = "TJ",
377
- TK = "TK",
378
- TL = "TL",
379
- TM = "TM",
380
- TN = "TN",
381
- TO = "TO",
382
- TR = "TR",
383
- TT = "TT",
384
- TV = "TV",
385
- TW = "TW",
386
- TZ = "TZ",
387
- UA = "UA",
388
- UG = "UG",
389
- UM = "UM",
390
- US = "US",
391
- UY = "UY",
392
- UZ = "UZ",
393
- VA = "VA",
394
- VC = "VC",
395
- VE = "VE",
396
- VG = "VG",
397
- VN = "VN",
398
- VU = "VU",
399
- WF = "WF",
400
- WS = "WS",
401
- XK = "XK",
402
- YE = "YE",
403
- YT = "YT",
404
- ZA = "ZA",
405
- ZM = "ZM",
406
- ZW = "ZW",
407
- ZZ = "ZZ",
408
- }
409
-
410
- export enum OrderCancelReason {
411
- CUSTOMER = "CUSTOMER",
412
- DECLINED = "DECLINED",
413
- FRAUD = "FRAUD",
414
- INVENTORY = "INVENTORY",
415
- OTHER = "OTHER",
416
- }
417
-
418
- export enum OrderFinancialStatus {
419
- AUTHORIZED = "AUTHORIZED",
420
- PAID = "PAID",
421
- PARTIALLY_PAID = "PARTIALLY_PAID",
422
- PARTIALLY_REFUNDED = "PARTIALLY_REFUNDED",
423
- PENDING = "PENDING",
424
- REFUNDED = "REFUNDED",
425
- VOIDED = "VOIDED",
426
- }
427
-
428
- export enum OrderFulfillmentStatus {
429
- FULFILLED = "FULFILLED",
430
- IN_PROGRESS = "IN_PROGRESS",
431
- ON_HOLD = "ON_HOLD",
432
- OPEN = "OPEN",
433
- PARTIALLY_FULFILLED = "PARTIALLY_FULFILLED",
434
- PENDING_FULFILLMENT = "PENDING_FULFILLMENT",
435
- RESTOCKED = "RESTOCKED",
436
- SCHEDULED = "SCHEDULED",
437
- UNFULFILLED = "UNFULFILLED",
438
- }
@@ -1,70 +0,0 @@
1
- import { type FetchFn, withFetchTimeout } from "@decocms/blocks/sdk/fetchTimeout";
2
- import type { InstrumentedFetchInit } from "@decocms/blocks/sdk/instrumentedFetch";
3
- import { extractGraphqlOperationName } from "./graphqlOperationName";
4
-
5
- export function gql(strings: TemplateStringsArray, ...values: unknown[]): string {
6
- return strings.reduce((acc, str, i) => acc + str + (values[i] ?? ""), "");
7
- }
8
-
9
- export interface QueryDefinition {
10
- fragments?: string[];
11
- query: string;
12
- }
13
-
14
- export function buildQuery(def: QueryDefinition): string {
15
- const fragments = def.fragments?.join("\n") ?? "";
16
- return fragments ? `${fragments}\n${def.query}` : def.query;
17
- }
18
-
19
- export interface GraphQLClient {
20
- query<T>(query: string | QueryDefinition, variables?: Record<string, unknown>): Promise<T>;
21
- }
22
-
23
- export function createGraphqlClient(
24
- endpoint: string,
25
- headers: Record<string, string>,
26
- fetchFn?: FetchFn,
27
- ): GraphQLClient {
28
- const _fetch = fetchFn ?? withFetchTimeout();
29
- return {
30
- async query<T>(
31
- queryOrDef: string | QueryDefinition,
32
- variables?: Record<string, unknown>,
33
- ): Promise<T> {
34
- const query = typeof queryOrDef === "string" ? queryOrDef : buildQuery(queryOrDef);
35
-
36
- // Stamp the GraphQL operation as init.operation so the framework's
37
- // span name becomes `shopify.<OperationName>` instead of the
38
- // generic `shopify.storefront.graphql` from the URL router. The
39
- // extra field is silently dropped by plain `fetch` and read by
40
- // any `InstrumentedFetch` configured via `setShopifyFetch`.
41
- const operation = extractGraphqlOperationName(query);
42
- const init: InstrumentedFetchInit = {
43
- method: "POST",
44
- headers: {
45
- "Content-Type": "application/json",
46
- ...headers,
47
- },
48
- body: JSON.stringify({ query, variables }),
49
- ...(operation ? { operation } : {}),
50
- };
51
- const response = await _fetch(endpoint, init);
52
-
53
- if (!response.ok) {
54
- throw new Error(`Shopify GraphQL error: ${response.status} ${response.statusText}`);
55
- }
56
-
57
- const json = (await response.json()) as { data?: T; errors?: Array<{ message: string }> };
58
-
59
- if (json.errors?.length) {
60
- throw new Error(`Shopify GraphQL errors: ${json.errors.map((e) => e.message).join(", ")}`);
61
- }
62
-
63
- if (json.data === undefined) {
64
- throw new Error("Shopify GraphQL response missing data");
65
- }
66
-
67
- return json.data;
68
- },
69
- };
70
- }
@@ -1,2 +0,0 @@
1
- // Moved to the v8 client tree; re-exported here for the v7 modules.
2
- export { extractGraphqlOperationName } from "../v8/graphqlOperationName";
@@ -1,56 +0,0 @@
1
- /**
2
- * Pre-wired instrumented fetch factory for Shopify.
3
- *
4
- * Mirrors `vtex/utils/instrumentedFetch.ts`. Bundles:
5
- *
6
- * 1. `createInstrumentedFetch` from `@decocms/start` (spans,
7
- * traceparent, URL redaction).
8
- * 2. `shopifyOperationRouter` as the URL fallback for non-GraphQL
9
- * and unnamed-GraphQL calls.
10
- * 3. An `onComplete` that records the canonical
11
- * `http.client.request.duration` histogram (via the framework's
12
- * `recordCommerceMetric(...)` helper) with `provider: "shopify"`.
13
- *
14
- * Sites do:
15
- *
16
- * ```ts
17
- * import { setShopifyFetch, createShopifyFetch } from "@decocms/apps/shopify";
18
- * setShopifyFetch(createShopifyFetch());
19
- * ```
20
- *
21
- * Per-call operation names come from `extractGraphqlOperationName`
22
- * (wired in `./graphql.ts`); the URL router fires only when the
23
- * extractor returns `undefined`.
24
- */
25
-
26
- import type { FetchFn } from "@decocms/blocks/sdk/fetchTimeout";
27
- import {
28
- createInstrumentedFetch,
29
- type InstrumentedFetch,
30
- } from "@decocms/blocks/sdk/instrumentedFetch";
31
- import { recordCommerceMetric } from "@decocms/blocks/sdk/observability";
32
- import { shopifyOperationRouter } from "./operationRouter";
33
-
34
- export interface CreateShopifyFetchOptions {
35
- baseFetch?: FetchFn;
36
- disableHistogram?: boolean;
37
- }
38
-
39
- export function createShopifyFetch(options: CreateShopifyFetchOptions = {}): InstrumentedFetch {
40
- const { baseFetch, disableHistogram = false } = options;
41
- return createInstrumentedFetch({
42
- name: "shopify",
43
- baseFetch,
44
- resolveOperation: shopifyOperationRouter,
45
- onComplete: disableHistogram
46
- ? undefined
47
- : ({ operation, status, durationMs, cached }) => {
48
- recordCommerceMetric(durationMs, {
49
- provider: "shopify",
50
- operation,
51
- status_class: `${Math.floor(status / 100)}xx`,
52
- cached,
53
- });
54
- },
55
- });
56
- }
@@ -1,70 +0,0 @@
1
- /**
2
- * URL-derived operation name router for Shopify API calls.
3
- *
4
- * Plugged into `@decocms/start`'s `createInstrumentedFetch` via the
5
- * `resolveOperation(url, method)` option. Mirrors the shape of the
6
- * VTEX router in `../../vtex/utils/operationRouter.ts`.
7
- *
8
- * Shopify's API surface from this repo is overwhelmingly GraphQL —
9
- * a single endpoint per environment (storefront vs admin). That means
10
- * the URL alone can only tell us *which GraphQL surface* a call is
11
- * hitting, not what the call actually does. The semantic operation
12
- * name lives in the GraphQL document itself (`query Foo { ... }`),
13
- * and is extracted by `extractGraphqlOperationName` (see
14
- * `../v8/graphqlOperationName.ts`) at the client layer and stamped as
15
- * `init.operation`, which always wins over this router.
16
- *
17
- * So this router exists for:
18
- *
19
- * - non-GraphQL Shopify REST endpoints we may add later
20
- * (cart API, customer accounts, billing, etc.);
21
- * - giving the GraphQL endpoints a *fallback* operation when the
22
- * extractor can't parse a name (anonymous queries, missing body).
23
- */
24
-
25
- type OperationResolver = string | ((match: RegExpMatchArray, method: string) => string);
26
-
27
- interface Matcher {
28
- pattern: RegExp;
29
- operation: OperationResolver;
30
- }
31
-
32
- const m = (pattern: RegExp, operation: OperationResolver): Matcher => ({ pattern, operation });
33
-
34
- const MATCHERS: ReadonlyArray<Matcher> = [
35
- m(/^\/admin\/api\/[0-9]{4}-[0-9]{2}\/graphql\.json/, "admin.graphql"),
36
- m(/^\/api\/[0-9]{4}-[0-9]{2}\/graphql\.json/, "storefront.graphql"),
37
-
38
- m(/^\/admin\/api\/[0-9]{4}-[0-9]{2}\/products/, "admin.products"),
39
- m(/^\/admin\/api\/[0-9]{4}-[0-9]{2}\/orders/, "admin.orders"),
40
- m(/^\/admin\/api\/[0-9]{4}-[0-9]{2}\/customers/, "admin.customers"),
41
- m(/^\/admin\/api\/[0-9]{4}-[0-9]{2}\/inventory/, "admin.inventory"),
42
-
43
- m(/^\/api\/[0-9]{4}-[0-9]{2}\/checkouts/, "storefront.checkout"),
44
- m(/^\/cart(?:\/|\.js|$)/, "storefront.cart"),
45
- ];
46
-
47
- /**
48
- * Resolve an operation name for a Shopify URL. Returns `undefined`
49
- * if no matcher fires, which causes the framework to fall back to
50
- * `shopify.fetch`.
51
- */
52
- export function shopifyOperationRouter(url: string, method: string): string | undefined {
53
- let pathname: string;
54
- try {
55
- pathname = new URL(url).pathname;
56
- } catch {
57
- const qs = url.indexOf("?");
58
- const hash = url.indexOf("#");
59
- const end = [qs, hash].filter((i) => i >= 0).sort((a, b) => a - b)[0];
60
- pathname = end === undefined ? url : url.slice(0, end);
61
- }
62
-
63
- const upperMethod = method.toUpperCase();
64
- for (const { pattern, operation } of MATCHERS) {
65
- const match = pathname.match(pattern);
66
- if (!match) continue;
67
- return typeof operation === "function" ? operation(match, upperMethod) : operation;
68
- }
69
- return undefined;
70
- }