@asteby/storefront 0.24.0 → 0.25.0

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/index.js CHANGED
@@ -36,6 +36,15 @@ function isTokenPublishable(token) {
36
36
  }
37
37
 
38
38
  // src/query.ts
39
+ function accountListQuery(params) {
40
+ if (!params) return void 0;
41
+ const out = {};
42
+ for (const [key, value] of Object.entries(params)) {
43
+ if (value === void 0 || value === null || value === "") continue;
44
+ out[key] = value;
45
+ }
46
+ return out;
47
+ }
39
48
  function appendParams(search, params) {
40
49
  if (!params) return search;
41
50
  for (const [key, raw] of Object.entries(params)) {
@@ -493,7 +502,50 @@ function createStorefrontClient(config) {
493
502
  * repeat after success is also fine. Afterwards the token is dead: drop it.
494
503
  */
495
504
  deleteAccount: (input, options) => write("DELETE", "/storefront/customer", input, options),
496
- orders: (params, options) => get("/storefront/customer/orders", params, options),
505
+ /**
506
+ * The buyer's orders, newest first. Callable as before (`orders({ first })`) and, since contract 1.19, with
507
+ * `orders.list({ first, after, before, status, delivery_method, has_invoice, from, to, q })`: cursor paging
508
+ * (keyset, stable while new orders arrive), `page_info.start_cursor` / `has_previous_page` to go back, and
509
+ * `total_count` when it is cheap to know. An OPS older than 1.19 ignores the new parameters.
510
+ */
511
+ orders: Object.assign(
512
+ (params, options) => get("/storefront/customer/orders", params, options),
513
+ {
514
+ list: (params, options) => get("/storefront/customer/orders", accountListQuery(params), { ...options, cache: "no-store" })
515
+ }
516
+ ),
517
+ /**
518
+ * The buyer's invoices, one node per order that has them (`{ order, invoices }`), cursor-paged like `orders.list`.
519
+ * It replaces opening the detail of every order. An OPS older than 1.19 (no such route) is served from one page of
520
+ * orders and their details, so the account keeps working until the addon is updated.
521
+ */
522
+ invoices: {
523
+ list: async (params, options) => {
524
+ const page = await getOrNull("/storefront/customer/invoices", accountListQuery(params), { ...options, cache: "no-store" });
525
+ return page ?? legacyAccountList(client, params, options, (o) => o.invoice ? !["not_requested", "awaiting_payment", "window_closed"].includes(o.invoice.stage ?? "not_requested") : true, (o) => (o.invoices ?? []).length ? { order: orderRef(o), invoices: o.invoices ?? [] } : null);
526
+ }
527
+ },
528
+ /**
529
+ * The buyer's shipments, one node per delivered order with its service and parcels (`{ order, stage, service,
530
+ * shipments }`), cursor-paged like `orders.list`, without tracking events or map (those come with `order(id)`).
531
+ * An OPS older than 1.19 is served from one page of orders and their details.
532
+ */
533
+ shipments: {
534
+ list: async (params, options) => {
535
+ const page = await getOrNull("/storefront/customer/shipments", accountListQuery(params), { ...options, cache: "no-store" });
536
+ return page ?? legacyAccountList(
537
+ client,
538
+ params,
539
+ options,
540
+ (o) => o.delivery_method !== "pickup" && !["cancelled", "refunded", "pending_payment"].includes(o.status),
541
+ (o) => {
542
+ const service = o.shipping_service ?? null;
543
+ const shipments = o.shipments ?? [];
544
+ return service || shipments.length ? { order: orderRef(o), stage: o.progress?.stage ?? o.status, service, shipments } : null;
545
+ }
546
+ );
547
+ }
548
+ },
497
549
  /** `null` when the order does not exist or belongs to someone else. */
498
550
  order: (id, options) => getOrNull(`/storefront/customer/orders/${enc(id)}`, void 0, options),
499
551
  requestReturn: (orderId, input, options) => write("POST", `/storefront/customer/orders/${enc(orderId)}/returns`, input, options),
@@ -581,6 +633,20 @@ function createStorefrontClient(config) {
581
633
  };
582
634
  return client;
583
635
  }
636
+ var orderRef = (o) => ({ id: o.id, number: o.number, created_at: o.created_at });
637
+ async function legacyAccountList(client, params, options, keep, toNode) {
638
+ const page = await client.customer.orders.list({ ...params?.first ? { first: params.first } : {}, ...params?.after ? { after: params.after } : {}, ...params?.from ? { from: params.from } : {}, ...params?.to ? { to: params.to } : {}, ...params?.q ? { q: params.q } : {} }, options);
639
+ const details = await Promise.all(
640
+ page.nodes.filter(keep).map(
641
+ (o) => client.customer.order(o.id, options).catch((err) => {
642
+ if (err instanceof StorefrontError && err.status === 401) throw err;
643
+ return null;
644
+ })
645
+ )
646
+ );
647
+ const nodes = details.map((d) => d ? toNode(d) : null).filter((n) => n !== null);
648
+ return { nodes, page_info: { has_next_page: page.page_info.has_next_page, end_cursor: page.page_info.end_cursor } };
649
+ }
584
650
  function storefrontDomainHeader(domain, market) {
585
651
  const host = domain.trim();
586
652
  const code = (market ?? "").trim().toLowerCase();
@@ -983,6 +1049,131 @@ function deliveryNotices(delivery) {
983
1049
  };
984
1050
  }
985
1051
 
986
- export { CLIENT_IP_HEADER, COUNTRY_HEADERS, MISSING_WEIGHT, NOTE_MAX_LENGTH, PAYMENT_CHOICE_REFUSED_FIELD, appendParams, clampPercent, classifyPaymentError, createStorefrontClient, dataExportBytes, deliveryInput, deliveryNotices, diagnose, formatMoney, generateIdempotencyKey, groupInvoiceDocs, hreflangLinks, invoiceFileBytes, isAccountDeleteBlocked, isReauthRequired, isTokenPublishable, maskToken, negotiateLocale, normalizeClientIp, normalizeNote, opsSaysNotRetryable, parseDelivery, parseMoney, parseProductFilters, preferredLanguages, productListQuery, promoProgressView, promotionMessages, repairPath, rewardLabel, safeExportFilename, safeInvoiceFilename, storefrontDomainHeader, suggestMarket, toMoney, visitorCountry };
1052
+ // src/account-lists.ts
1053
+ var LIST_URL_ES = {
1054
+ after: "despues",
1055
+ before: "antes",
1056
+ pos: "pos",
1057
+ status: "estado",
1058
+ delivery: "entrega",
1059
+ invoice: "factura",
1060
+ from: "desde",
1061
+ to: "hasta",
1062
+ q: "q",
1063
+ deliveryValues: { shipping: "envio", pickup: "recoger" },
1064
+ invoiceValues: { yes: "si", no: "no" }
1065
+ };
1066
+ var LIST_URL_EN = {
1067
+ after: "after",
1068
+ before: "before",
1069
+ pos: "pos",
1070
+ status: "status",
1071
+ delivery: "delivery",
1072
+ invoice: "invoice",
1073
+ from: "from",
1074
+ to: "to",
1075
+ q: "q",
1076
+ deliveryValues: { shipping: "shipping", pickup: "pickup" },
1077
+ invoiceValues: { yes: "yes", no: "no" }
1078
+ };
1079
+ var CURSOR = /^[A-Za-z0-9_-]{1,300}$/;
1080
+ var DAY = /^\d{4}-\d{2}-\d{2}$/;
1081
+ var STATUS = /^[a-z_]{1,32}$/;
1082
+ var MAX_Q = 64;
1083
+ var MAX_POS = 1e6;
1084
+ var asParams = (search) => search instanceof URLSearchParams ? search : new URLSearchParams(typeof search === "string" ? search : "");
1085
+ var validDay = (v) => {
1086
+ if (!v || !DAY.test(v)) return void 0;
1087
+ const d = /* @__PURE__ */ new Date(`${v}T00:00:00Z`);
1088
+ return Number.isNaN(d.getTime()) || d.toISOString().slice(0, 10) !== v ? void 0 : v;
1089
+ };
1090
+ function readListQuery(search, names = LIST_URL_ES) {
1091
+ const p = asParams(search);
1092
+ const out = {};
1093
+ const after = p.get(names.after);
1094
+ const before = p.get(names.before);
1095
+ if (after && CURSOR.test(after)) out.after = after;
1096
+ else if (before && CURSOR.test(before)) out.before = before;
1097
+ const pos = Number(p.get(names.pos));
1098
+ if (Number.isInteger(pos) && pos >= 1 && pos <= MAX_POS) out.pos = pos;
1099
+ const status = p.get(names.status);
1100
+ if (status && STATUS.test(status)) out.status = status;
1101
+ const delivery = p.get(names.delivery);
1102
+ if (delivery === names.deliveryValues.shipping) out.delivery = "shipping";
1103
+ else if (delivery === names.deliveryValues.pickup) out.delivery = "pickup";
1104
+ const invoice = p.get(names.invoice);
1105
+ if (invoice === names.invoiceValues.yes) out.invoice = true;
1106
+ else if (invoice === names.invoiceValues.no) out.invoice = false;
1107
+ const from = validDay(p.get(names.from));
1108
+ const to = validDay(p.get(names.to));
1109
+ if (from) out.from = from;
1110
+ if (to && (!from || to >= from)) out.to = to;
1111
+ const q = (p.get(names.q) ?? "").trim().replace(/^#/, "").trim();
1112
+ if (q && q.length <= MAX_Q) out.q = q;
1113
+ return out;
1114
+ }
1115
+ function isFiltered(query) {
1116
+ return !!(query.status || query.delivery || query.invoice !== void 0 || query.from || query.to || query.q);
1117
+ }
1118
+ function firstPageQuery(query) {
1119
+ const { after: _a, before: _b, pos: _p, ...filters } = query;
1120
+ return filters;
1121
+ }
1122
+ function listApiParams(query, first) {
1123
+ const params = { first };
1124
+ if (query.after) params.after = query.after;
1125
+ else if (query.before) params.before = query.before;
1126
+ if (query.status) params.status = query.status;
1127
+ if (query.delivery) params.delivery_method = query.delivery;
1128
+ if (query.invoice !== void 0) params.has_invoice = query.invoice;
1129
+ if (query.from) params.from = query.from;
1130
+ if (query.to) params.to = query.to;
1131
+ if (query.q) params.q = query.q;
1132
+ return params;
1133
+ }
1134
+ function listQueryString(query, names = LIST_URL_ES) {
1135
+ const p = new URLSearchParams();
1136
+ if (query.after) p.set(names.after, query.after);
1137
+ else if (query.before) p.set(names.before, query.before);
1138
+ if (query.pos && query.pos > 1) p.set(names.pos, String(query.pos));
1139
+ if (query.status) p.set(names.status, query.status);
1140
+ if (query.delivery) p.set(names.delivery, names.deliveryValues[query.delivery]);
1141
+ if (query.invoice !== void 0) p.set(names.invoice, query.invoice ? names.invoiceValues.yes : names.invoiceValues.no);
1142
+ if (query.from) p.set(names.from, query.from);
1143
+ if (query.to) p.set(names.to, query.to);
1144
+ if (query.q) p.set(names.q, query.q);
1145
+ const s = p.toString();
1146
+ return s ? `?${s}` : "";
1147
+ }
1148
+ var listHref = (path, query, names = LIST_URL_ES) => `${path}${listQueryString(query, names)}`;
1149
+ function pagePosition({ query, pageInfo, count }) {
1150
+ if (count === 0) return void 0;
1151
+ if (!query.after && !query.before) return 1;
1152
+ if (pageInfo && pageInfo.has_previous_page === false) return 1;
1153
+ return query.pos;
1154
+ }
1155
+ function nextPageQuery(state) {
1156
+ const { query, pageInfo, count } = state;
1157
+ if (!pageInfo?.has_next_page || !pageInfo.end_cursor) return null;
1158
+ const here = pagePosition(state);
1159
+ return { ...firstPageQuery(query), after: pageInfo.end_cursor, ...here ? { pos: here + count } : {} };
1160
+ }
1161
+ function previousPageQuery(state) {
1162
+ const { query, pageInfo, first } = state;
1163
+ if (!query.after && !query.before) return null;
1164
+ if (pageInfo?.has_previous_page === false) return firstPageQuery(query);
1165
+ const cursor = pageInfo?.start_cursor;
1166
+ if (!cursor) return query.after || query.before ? firstPageQuery(query) : null;
1167
+ const here = pagePosition(state);
1168
+ if (here !== void 0 && here - first <= 1) return firstPageQuery(query);
1169
+ return { ...firstPageQuery(query), before: cursor, ...here ? { pos: Math.max(1, here - first) } : {} };
1170
+ }
1171
+ function pageRange(state) {
1172
+ const from = pagePosition(state);
1173
+ if (!from || state.count === 0) return null;
1174
+ return { from, to: from + state.count - 1, total: typeof state.total === "number" && state.total >= 0 ? state.total : null };
1175
+ }
1176
+
1177
+ export { CLIENT_IP_HEADER, COUNTRY_HEADERS, LIST_URL_EN, LIST_URL_ES, MISSING_WEIGHT, NOTE_MAX_LENGTH, PAYMENT_CHOICE_REFUSED_FIELD, accountListQuery, appendParams, clampPercent, classifyPaymentError, createStorefrontClient, dataExportBytes, deliveryInput, deliveryNotices, diagnose, firstPageQuery, formatMoney, generateIdempotencyKey, groupInvoiceDocs, hreflangLinks, invoiceFileBytes, isAccountDeleteBlocked, isFiltered, isReauthRequired, isTokenPublishable, listApiParams, listHref, listQueryString, maskToken, negotiateLocale, nextPageQuery, normalizeClientIp, normalizeNote, opsSaysNotRetryable, pagePosition, pageRange, parseDelivery, parseMoney, parseProductFilters, preferredLanguages, previousPageQuery, productListQuery, promoProgressView, promotionMessages, readListQuery, repairPath, rewardLabel, safeExportFilename, safeInvoiceFilename, storefrontDomainHeader, suggestMarket, toMoney, visitorCountry };
987
1178
  //# sourceMappingURL=index.js.map
988
1179
  //# sourceMappingURL=index.js.map