@decocms/apps-shopify 8.0.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 (39) hide show
  1. package/package.json +7 -24
  2. package/src/client.ts +113 -46
  3. package/src/{utils/graphqlOperationName.ts → graphqlOperationName.ts} +22 -22
  4. package/src/index.ts +8 -41
  5. package/src/actions/cart/addItems.ts +0 -36
  6. package/src/actions/cart/updateCoupons.ts +0 -31
  7. package/src/actions/cart/updateItems.ts +0 -31
  8. package/src/actions/user/signIn.ts +0 -40
  9. package/src/actions/user/signUp.ts +0 -31
  10. package/src/init.ts +0 -39
  11. package/src/loaders/ProductDetailsPage.ts +0 -31
  12. package/src/loaders/ProductList.ts +0 -102
  13. package/src/loaders/ProductListingPage.ts +0 -172
  14. package/src/loaders/RelatedProducts.ts +0 -42
  15. package/src/loaders/cart.ts +0 -74
  16. package/src/loaders/shop.ts +0 -35
  17. package/src/loaders/user.ts +0 -39
  18. package/src/manifest.gen.ts +0 -39
  19. package/src/mod.ts +0 -67
  20. package/src/registry.ts +0 -9
  21. package/src/utils/__tests__/graphqlOperationName.test.ts +0 -80
  22. package/src/utils/__tests__/instrumentedFetch.test.ts +0 -84
  23. package/src/utils/__tests__/operationRouter.test.ts +0 -56
  24. package/src/utils/__tests__/transform.test.ts +0 -216
  25. package/src/utils/admin/admin.ts +0 -57
  26. package/src/utils/admin/queries.ts +0 -29
  27. package/src/utils/cart.ts +0 -32
  28. package/src/utils/cookies.ts +0 -82
  29. package/src/utils/enums.ts +0 -438
  30. package/src/utils/graphql.ts +0 -69
  31. package/src/utils/instrumentedFetch.ts +0 -55
  32. package/src/utils/operationRouter.ts +0 -70
  33. package/src/utils/storefront/queries.ts +0 -525
  34. package/src/utils/storefront/storefront.graphql.gen.ts +0 -129
  35. package/src/utils/transform.ts +0 -430
  36. package/src/utils/types.ts +0 -191
  37. package/src/utils/user.ts +0 -23
  38. package/src/utils/utils.ts +0 -159
  39. package/tsconfig.json +0 -7
@@ -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,69 +0,0 @@
1
- import type { InstrumentedFetchInit } from "@decocms/blocks/sdk/instrumentedFetch";
2
- import { extractGraphqlOperationName } from "./graphqlOperationName";
3
-
4
- export function gql(strings: TemplateStringsArray, ...values: unknown[]): string {
5
- return strings.reduce((acc, str, i) => acc + str + (values[i] ?? ""), "");
6
- }
7
-
8
- export interface QueryDefinition {
9
- fragments?: string[];
10
- query: string;
11
- }
12
-
13
- export function buildQuery(def: QueryDefinition): string {
14
- const fragments = def.fragments?.join("\n") ?? "";
15
- return fragments ? `${fragments}\n${def.query}` : def.query;
16
- }
17
-
18
- export interface GraphQLClient {
19
- query<T>(query: string | QueryDefinition, variables?: Record<string, unknown>): Promise<T>;
20
- }
21
-
22
- export function createGraphqlClient(
23
- endpoint: string,
24
- headers: Record<string, string>,
25
- fetchFn?: typeof fetch,
26
- ): GraphQLClient {
27
- const _fetch = fetchFn ?? globalThis.fetch;
28
- return {
29
- async query<T>(
30
- queryOrDef: string | QueryDefinition,
31
- variables?: Record<string, unknown>,
32
- ): Promise<T> {
33
- const query = typeof queryOrDef === "string" ? queryOrDef : buildQuery(queryOrDef);
34
-
35
- // Stamp the GraphQL operation as init.operation so the framework's
36
- // span name becomes `shopify.<OperationName>` instead of the
37
- // generic `shopify.storefront.graphql` from the URL router. The
38
- // extra field is silently dropped by plain `fetch` and read by
39
- // any `InstrumentedFetch` configured via `setShopifyFetch`.
40
- const operation = extractGraphqlOperationName(query);
41
- const init: InstrumentedFetchInit = {
42
- method: "POST",
43
- headers: {
44
- "Content-Type": "application/json",
45
- ...headers,
46
- },
47
- body: JSON.stringify({ query, variables }),
48
- ...(operation ? { operation } : {}),
49
- };
50
- const response = await _fetch(endpoint, init);
51
-
52
- if (!response.ok) {
53
- throw new Error(`Shopify GraphQL error: ${response.status} ${response.statusText}`);
54
- }
55
-
56
- const json = (await response.json()) as { data?: T; errors?: Array<{ message: string }> };
57
-
58
- if (json.errors?.length) {
59
- throw new Error(`Shopify GraphQL errors: ${json.errors.map((e) => e.message).join(", ")}`);
60
- }
61
-
62
- if (json.data === undefined) {
63
- throw new Error("Shopify GraphQL response missing data");
64
- }
65
-
66
- return json.data;
67
- },
68
- };
69
- }
@@ -1,55 +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 {
27
- createInstrumentedFetch,
28
- type InstrumentedFetch,
29
- } from "@decocms/blocks/sdk/instrumentedFetch";
30
- import { recordCommerceMetric } from "@decocms/blocks/sdk/observability";
31
- import { shopifyOperationRouter } from "./operationRouter";
32
-
33
- export interface CreateShopifyFetchOptions {
34
- baseFetch?: typeof fetch;
35
- disableHistogram?: boolean;
36
- }
37
-
38
- export function createShopifyFetch(options: CreateShopifyFetchOptions = {}): InstrumentedFetch {
39
- const { baseFetch, disableHistogram = false } = options;
40
- return createInstrumentedFetch({
41
- name: "shopify",
42
- baseFetch,
43
- resolveOperation: shopifyOperationRouter,
44
- onComplete: disableHistogram
45
- ? undefined
46
- : ({ operation, status, durationMs, cached }) => {
47
- recordCommerceMetric(durationMs, {
48
- provider: "shopify",
49
- operation,
50
- status_class: `${Math.floor(status / 100)}xx`,
51
- cached,
52
- });
53
- },
54
- });
55
- }
@@ -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
- * `./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
- }