@asteby/storefront 0.13.0 → 0.14.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/README.md +27 -1
- package/dist/chunk-IPUAZ3LQ.js +646 -0
- package/dist/chunk-IPUAZ3LQ.js.map +1 -0
- package/dist/cli.js +40 -1
- package/dist/fiscal-document.d.cts +2 -2
- package/dist/fiscal-document.d.ts +2 -2
- package/dist/index.cjs +196 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +67 -3
- package/dist/index.d.ts +67 -3
- package/dist/index.js +73 -316
- package/dist/index.js.map +1 -1
- package/dist/mock.cjs +417 -39
- package/dist/mock.cjs.map +1 -1
- package/dist/mock.d.cts +3 -1
- package/dist/mock.d.ts +3 -1
- package/dist/mock.js +272 -23
- package/dist/mock.js.map +1 -1
- package/dist/mockup.d.cts +1 -1
- package/dist/mockup.d.ts +1 -1
- package/dist/node.cjs +1 -1
- package/dist/node.js +1 -1
- package/dist/{types-C_rsJRCl.d.ts → types-BeTemDg6.d.ts} +209 -1
- package/dist/{types-BQ3S6VjF.d.cts → types-BuKb-zbi.d.cts} +209 -1
- package/package.json +1 -1
- package/dist/chunk-HBSB7XS2.js +0 -220
- package/dist/chunk-HBSB7XS2.js.map +0 -1
package/dist/mock.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a0 as IdentityRulesV1, b8 as RegionFiscalId, _ as IdentityDocumentSpec, b6 as Region, bo as Shop, aV as Product, x as Collection, bv as Theme, aA as Page, aj as Menu, b as Article, C as Cart, A as Address, a9 as InvoiceRequest, z as Customer, aq as Order, aD as PaymentAttemptResult, aS as PendingPayment, ab as InvoiceStage, B as CustomerCapabilities, b0 as PromotionAnnouncement, bn as ShippingRate, aK as PaymentMethod } from './types-BuKb-zbi.cjs';
|
|
2
2
|
import './geo.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -153,6 +153,8 @@ type MockState = {
|
|
|
153
153
|
}>;
|
|
154
154
|
/** `contact|sku` of accepted "notify me" subscriptions. */
|
|
155
155
|
restock: Set<string>;
|
|
156
|
+
/** Cash vouchers waiting for payment (`GET /customer/pending-payments`); `cus_1` only. */
|
|
157
|
+
pendingPayments: PendingPayment[];
|
|
156
158
|
/** Invoice requested per order id. */
|
|
157
159
|
invoices: Map<string, {
|
|
158
160
|
stage: InvoiceStage;
|
package/dist/mock.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a0 as IdentityRulesV1, b8 as RegionFiscalId, _ as IdentityDocumentSpec, b6 as Region, bo as Shop, aV as Product, x as Collection, bv as Theme, aA as Page, aj as Menu, b as Article, C as Cart, A as Address, a9 as InvoiceRequest, z as Customer, aq as Order, aD as PaymentAttemptResult, aS as PendingPayment, ab as InvoiceStage, B as CustomerCapabilities, b0 as PromotionAnnouncement, bn as ShippingRate, aK as PaymentMethod } from './types-BeTemDg6.js';
|
|
2
2
|
import './geo.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -153,6 +153,8 @@ type MockState = {
|
|
|
153
153
|
}>;
|
|
154
154
|
/** `contact|sku` of accepted "notify me" subscriptions. */
|
|
155
155
|
restock: Set<string>;
|
|
156
|
+
/** Cash vouchers waiting for payment (`GET /customer/pending-payments`); `cus_1` only. */
|
|
157
|
+
pendingPayments: PendingPayment[];
|
|
156
158
|
/** Invoice requested per order id. */
|
|
157
159
|
invoices: Map<string, {
|
|
158
160
|
stage: InvoiceStage;
|
package/dist/mock.js
CHANGED
|
@@ -1,6 +1,210 @@
|
|
|
1
|
-
import { resolveAvailability } from './chunk-
|
|
1
|
+
import { resolveAvailability, isTestShipment, sortTrackingEvents, orderProgress, nextAction, orderShipments, shipmentsStatus } from './chunk-IPUAZ3LQ.js';
|
|
2
2
|
import { isValidPoint, rankByDistance } from './chunk-45R47HYO.js';
|
|
3
3
|
|
|
4
|
+
// src/mock/account-seed.ts
|
|
5
|
+
var money = (cents, currency) => ({ amount: (cents / 100).toFixed(2), currency_code: currency });
|
|
6
|
+
var line = (title, variant, quantity, unitCents, currency) => ({
|
|
7
|
+
title,
|
|
8
|
+
variant_title: variant,
|
|
9
|
+
sku: null,
|
|
10
|
+
quantity,
|
|
11
|
+
unit: money(unitCents, currency),
|
|
12
|
+
total: money(unitCents * quantity, currency),
|
|
13
|
+
image: null
|
|
14
|
+
});
|
|
15
|
+
var address = { first_name: "Ana", last_name: "Prueba", city: "Quer\xE9taro", province: "Qro.", zip: "76000", country_code: "MX" };
|
|
16
|
+
function buildAccountOrders(currency) {
|
|
17
|
+
const inTransit = {
|
|
18
|
+
id: "shp_seed_1",
|
|
19
|
+
number: "ENV-00001",
|
|
20
|
+
kind: "outbound",
|
|
21
|
+
status: "in_transit",
|
|
22
|
+
environment: "production",
|
|
23
|
+
test_mode: false,
|
|
24
|
+
carrier: "Estafeta",
|
|
25
|
+
carrier_logo_key: "estafeta",
|
|
26
|
+
service: "Terrestre",
|
|
27
|
+
tracking_number: "8012345678",
|
|
28
|
+
tracking_url: "https://rastreo.example.com/estafeta/8012345678",
|
|
29
|
+
shipped_at: "2026-08-12T15:00:00.000Z",
|
|
30
|
+
delivered_at: null,
|
|
31
|
+
promised_by: "2026-08-16",
|
|
32
|
+
label_url: null,
|
|
33
|
+
events: [
|
|
34
|
+
{ id: "evt_3", status: "in_transit", description: "En tr\xE1nsito hacia tu ciudad", location: "Quer\xE9taro, Qro.", occurred_at: "2026-08-14T09:30:00.000Z", source: "carrier" },
|
|
35
|
+
{ id: "evt_2", status: "in_transit", description: "Sali\xF3 del centro de distribuci\xF3n", location: "Ciudad de M\xE9xico, CDMX", occurred_at: "2026-08-13T07:10:00.000Z", source: "carrier" },
|
|
36
|
+
{ id: "evt_1", status: "label_created", description: "Gu\xEDa generada", location: null, occurred_at: "2026-08-12T15:00:00.000Z", source: "store" }
|
|
37
|
+
],
|
|
38
|
+
map: {
|
|
39
|
+
origin: { label: "Ciudad de M\xE9xico, CDMX", lat: 19.43, lng: -99.13, precision: "city" },
|
|
40
|
+
destination: { label: "Quer\xE9taro, Qro.", lat: 20.6, lng: -100.4, precision: "city" },
|
|
41
|
+
path: [{ label: "Quer\xE9taro, Qro.", lat: 20.59, lng: -100.39, precision: "city" }]
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
const invoice = {
|
|
45
|
+
id: "inv_seed_1",
|
|
46
|
+
status: "issued",
|
|
47
|
+
kind: "invoice",
|
|
48
|
+
stage: "issued",
|
|
49
|
+
action: "download",
|
|
50
|
+
can_request: false,
|
|
51
|
+
folio: "8F3C1A52-6E0B-4B58-9C0D-2B7D6B4D7A11",
|
|
52
|
+
series: "A",
|
|
53
|
+
folio_number: "1042",
|
|
54
|
+
total: money(129900, currency),
|
|
55
|
+
issued_at: "2026-08-13T10:00:00.000Z",
|
|
56
|
+
test_mode: false,
|
|
57
|
+
environment: "production"
|
|
58
|
+
};
|
|
59
|
+
const creditNote = {
|
|
60
|
+
id: "inv_seed_1_nc",
|
|
61
|
+
status: "issued",
|
|
62
|
+
kind: "credit_note",
|
|
63
|
+
stage: "issued",
|
|
64
|
+
action: "download",
|
|
65
|
+
can_request: false,
|
|
66
|
+
folio: "1D9B7E20-4A5C-4C4B-8F11-6A0E3C9D5B02",
|
|
67
|
+
series: "NC",
|
|
68
|
+
folio_number: "7",
|
|
69
|
+
total: money(2e4, currency),
|
|
70
|
+
issued_at: "2026-08-15T10:00:00.000Z",
|
|
71
|
+
related_to: "inv_seed_1",
|
|
72
|
+
test_mode: false,
|
|
73
|
+
environment: "production"
|
|
74
|
+
};
|
|
75
|
+
return [
|
|
76
|
+
{
|
|
77
|
+
id: "ord_seed_shipped",
|
|
78
|
+
number: "0999",
|
|
79
|
+
status: "shipped",
|
|
80
|
+
created_at: "2026-08-12T12:00:00.000Z",
|
|
81
|
+
total: money(129900, currency),
|
|
82
|
+
customer_id: "cus_1",
|
|
83
|
+
lines: [line("Kit de frenos", "Delantero", 1, 109900, currency), line("L\xEDquido de frenos", "500 ml", 1, 2e4, currency)],
|
|
84
|
+
delivery_method: "shipping",
|
|
85
|
+
payment_status: "paid",
|
|
86
|
+
subtotal: money(111983, currency),
|
|
87
|
+
tax: money(17917, currency),
|
|
88
|
+
shipping: money(0, currency),
|
|
89
|
+
discount: money(0, currency),
|
|
90
|
+
tax_included: true,
|
|
91
|
+
shipping_method: "Est\xE1ndar",
|
|
92
|
+
shipping_address: address,
|
|
93
|
+
returns: [],
|
|
94
|
+
shipments: [inTransit],
|
|
95
|
+
invoices: [invoice, creditNote],
|
|
96
|
+
payments: [{ method_label: "Tarjeta Visa terminada en 4242", family: "card", status: "partially_refunded", amount: money(129900, currency), paid_at: "2026-08-12T12:01:00.000Z" }],
|
|
97
|
+
refunds: [{ id: "rfd_seed_1", amount: money(2e4, currency), status: "completed", method_label: "Tarjeta Visa terminada en 4242", created_at: "2026-08-15T09:00:00.000Z", completed_at: "2026-08-15T10:00:00.000Z", return_id: null }]
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
id: "ord_seed_preparing",
|
|
101
|
+
number: "0998",
|
|
102
|
+
status: "fulfilling",
|
|
103
|
+
created_at: "2026-08-11T12:00:00.000Z",
|
|
104
|
+
total: money(54900, currency),
|
|
105
|
+
customer_id: "cus_1",
|
|
106
|
+
lines: [line("Filtro de aceite", null, 3, 18300, currency)],
|
|
107
|
+
delivery_method: "shipping",
|
|
108
|
+
payment_status: "paid",
|
|
109
|
+
shipping_address: address,
|
|
110
|
+
shipments: [],
|
|
111
|
+
invoices: [],
|
|
112
|
+
payments: [{ method_label: "OXXO", family: "cash_voucher", status: "paid", amount: money(54900, currency), paid_at: "2026-08-11T18:00:00.000Z" }],
|
|
113
|
+
refunds: []
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
id: "ord_seed_sandbox",
|
|
117
|
+
number: "0997",
|
|
118
|
+
status: "shipped",
|
|
119
|
+
created_at: "2026-08-10T12:00:00.000Z",
|
|
120
|
+
total: money(31e3, currency),
|
|
121
|
+
customer_id: "cus_1",
|
|
122
|
+
lines: [line("Buj\xEDa iridio", null, 4, 7750, currency)],
|
|
123
|
+
delivery_method: "shipping",
|
|
124
|
+
payment_status: "paid",
|
|
125
|
+
shipments: [
|
|
126
|
+
{
|
|
127
|
+
id: "shp_seed_test",
|
|
128
|
+
kind: "outbound",
|
|
129
|
+
status: "label_created",
|
|
130
|
+
environment: "sandbox",
|
|
131
|
+
test_mode: true,
|
|
132
|
+
carrier: "Estafeta",
|
|
133
|
+
carrier_logo_key: "estafeta",
|
|
134
|
+
tracking_number: null,
|
|
135
|
+
tracking_url: null,
|
|
136
|
+
events: [],
|
|
137
|
+
map: null
|
|
138
|
+
}
|
|
139
|
+
],
|
|
140
|
+
invoices: [
|
|
141
|
+
{ id: "inv_seed_test", status: "issued", kind: "invoice", stage: "issued", action: "download", can_request: false, folio: "00000000-0000-4000-8000-000000000000", test_mode: true, environment: "sandbox" }
|
|
142
|
+
],
|
|
143
|
+
payments: [],
|
|
144
|
+
refunds: []
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
id: "ord_seed_pickup",
|
|
148
|
+
number: "0996",
|
|
149
|
+
status: "ready_for_pickup",
|
|
150
|
+
created_at: "2026-08-09T12:00:00.000Z",
|
|
151
|
+
total: money(88e3, currency),
|
|
152
|
+
customer_id: "cus_1",
|
|
153
|
+
lines: [line("Bater\xEDa 12V", null, 1, 88e3, currency)],
|
|
154
|
+
delivery_method: "pickup",
|
|
155
|
+
pickup: { location_id: null, name: "Sucursal Centro", address: "Av. Reforma 100", city: "Ciudad de M\xE9xico", phone: null, ready_at: "2026-08-10T10:00:00.000Z", delivered_at: null },
|
|
156
|
+
payment_status: "paid",
|
|
157
|
+
shipments: [],
|
|
158
|
+
invoices: [],
|
|
159
|
+
payments: [],
|
|
160
|
+
refunds: [],
|
|
161
|
+
degraded: ["invoices"]
|
|
162
|
+
}
|
|
163
|
+
];
|
|
164
|
+
}
|
|
165
|
+
function buildPendingPayments(currency, nowMs) {
|
|
166
|
+
return [
|
|
167
|
+
{
|
|
168
|
+
id: "chk_seed_oxxo",
|
|
169
|
+
number: null,
|
|
170
|
+
status: "pending_payment",
|
|
171
|
+
created_at: new Date(nowMs - 36e5).toISOString(),
|
|
172
|
+
total: money(45e3, currency),
|
|
173
|
+
expires_at: new Date(nowMs + 47 * 36e5).toISOString(),
|
|
174
|
+
payment: {
|
|
175
|
+
provider: "mercadopago",
|
|
176
|
+
method: "oxxo",
|
|
177
|
+
reference: "12345678901234",
|
|
178
|
+
barcode: "12345678901234",
|
|
179
|
+
clabe: null,
|
|
180
|
+
voucher_url: "https://pagos.example.com/ficha/abc",
|
|
181
|
+
instructions: "Paga en cualquier OXXO antes de la fecha de vencimiento.",
|
|
182
|
+
expires_at: new Date(nowMs + 47 * 36e5).toISOString(),
|
|
183
|
+
amount: money(45e3, currency)
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
id: "chk_seed_spei",
|
|
188
|
+
number: null,
|
|
189
|
+
status: "expired",
|
|
190
|
+
created_at: new Date(nowMs - 9 * 864e5).toISOString(),
|
|
191
|
+
total: money(12e4, currency),
|
|
192
|
+
expires_at: new Date(nowMs - 2 * 864e5).toISOString(),
|
|
193
|
+
payment: {
|
|
194
|
+
provider: "mercadopago",
|
|
195
|
+
method: "spei",
|
|
196
|
+
reference: null,
|
|
197
|
+
barcode: null,
|
|
198
|
+
clabe: "646180000000000001",
|
|
199
|
+
voucher_url: null,
|
|
200
|
+
instructions: null,
|
|
201
|
+
expires_at: new Date(nowMs - 2 * 864e5).toISOString(),
|
|
202
|
+
amount: money(12e4, currency)
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
];
|
|
206
|
+
}
|
|
207
|
+
|
|
4
208
|
// src/mock/region-mx.seed.ts
|
|
5
209
|
var SEED_MX_CSF = {
|
|
6
210
|
"kind": "MX:csf",
|
|
@@ -994,7 +1198,7 @@ var PRODUCT_SPECS = [
|
|
|
994
1198
|
{ handle: "llanta-265-70-r16-at", title: "Llanta 265/70 R16 All Terrain", collection: "llantas", type: "Llanta", vendor: "Marca Sur", price: 3599, attributes: { ...tire(265, 70, 16), load_index: 112, speed_rating: "T", runflat: false }, tags: ["camioneta"], description: "Para camioneta, asfalto y terracer\xEDa." },
|
|
995
1199
|
{ handle: "llanta-175-70-r13-city", title: "Llanta 175/70 R13 City", collection: "llantas", type: "Llanta", vendor: "Marca Centro", price: 999, attributes: { ...tire(175, 70, 13), load_index: 82, speed_rating: "T", runflat: false }, tags: ["auto"], stock: 0, description: "Econ\xF3mica y durable para ciudad." }
|
|
996
1200
|
];
|
|
997
|
-
var
|
|
1201
|
+
var money2 = (n, currency) => ({ amount: n.toFixed(2), currency_code: currency });
|
|
998
1202
|
function cartesian(options) {
|
|
999
1203
|
let combos = [{}];
|
|
1000
1204
|
for (const opt of options) {
|
|
@@ -1024,8 +1228,8 @@ function buildProducts(currency, imageUrl = MOCK_IMAGE_URL) {
|
|
|
1024
1228
|
sku: `${spec.handle.toUpperCase().replace(/-/g, "")}-${vi + 1}`.slice(0, 32),
|
|
1025
1229
|
title,
|
|
1026
1230
|
selected_options: Object.entries(opts).map(([name, value]) => ({ name, value })),
|
|
1027
|
-
price:
|
|
1028
|
-
compare_at_price: spec.compareAt ?
|
|
1231
|
+
price: money2(price, currency),
|
|
1232
|
+
compare_at_price: spec.compareAt ? money2(spec.compareAt + delta, currency) : null,
|
|
1029
1233
|
available_for_sale: stock > 0,
|
|
1030
1234
|
quantity_available: stock,
|
|
1031
1235
|
image: firstValue ? image(imageUrl, `${spec.handle}-${firstValue}`, `${spec.title} ${firstValue}`) : null,
|
|
@@ -1050,8 +1254,8 @@ function buildProducts(currency, imageUrl = MOCK_IMAGE_URL) {
|
|
|
1050
1254
|
images,
|
|
1051
1255
|
options,
|
|
1052
1256
|
variants,
|
|
1053
|
-
price_range: { min:
|
|
1054
|
-
compare_at_price_range: compares.length ? { min:
|
|
1257
|
+
price_range: { min: money2(Math.min(...prices), currency), max: money2(Math.max(...prices), currency) },
|
|
1258
|
+
compare_at_price_range: compares.length ? { min: money2(Math.min(...compares), currency), max: money2(Math.max(...compares), currency) } : null,
|
|
1055
1259
|
available_for_sale: variants.some((v) => v.available_for_sale),
|
|
1056
1260
|
seo: { title: `${spec.title} | Mi tienda`, description: spec.description },
|
|
1057
1261
|
updated_at: new Date(BASE_DATE - pi * 864e5).toISOString()
|
|
@@ -1113,7 +1317,7 @@ function buildLocations(currency) {
|
|
|
1113
1317
|
opening_hours: { weekly: weekdays("10:00", "18:00", [1, 2, 3, 4, 5, 6]) },
|
|
1114
1318
|
services: ["pickup"],
|
|
1115
1319
|
contacts: contacts(null),
|
|
1116
|
-
pickup: { enabled: true, fee:
|
|
1320
|
+
pickup: { enabled: true, fee: money2(30, currency), prep_days: 1 }
|
|
1117
1321
|
},
|
|
1118
1322
|
{
|
|
1119
1323
|
id: "br_occidente",
|
|
@@ -1153,7 +1357,7 @@ function buildShop(currency, imageUrl = MOCK_IMAGE_URL) {
|
|
|
1153
1357
|
logo: { url: imageUrl("logo", 256, 256), alt: "Mi tienda", width: 256, height: 256 },
|
|
1154
1358
|
contact: { email: "hola@mi-tienda.example", phone: "+52 55 0000 0000", whatsapp: "+5215500000000" },
|
|
1155
1359
|
branches: buildLocations(currency),
|
|
1156
|
-
policies: { free_shipping_min:
|
|
1360
|
+
policies: { free_shipping_min: money2(999, currency), returns_days: 30 }
|
|
1157
1361
|
};
|
|
1158
1362
|
}
|
|
1159
1363
|
function buildTheme() {
|
|
@@ -1394,8 +1598,10 @@ function createMockStorefront(options = {}) {
|
|
|
1394
1598
|
lines: [
|
|
1395
1599
|
{ title: "Playera b\xE1sica", variant_title: "M / Blanco", sku: null, quantity: 1, unit: fromCents(24900, currency), total: fromCents(24900, currency), image: null }
|
|
1396
1600
|
]
|
|
1397
|
-
}
|
|
1601
|
+
},
|
|
1602
|
+
...buildAccountOrders(currency)
|
|
1398
1603
|
],
|
|
1604
|
+
pendingPayments: buildPendingPayments(currency, Date.now()),
|
|
1399
1605
|
otps: /* @__PURE__ */ new Map(),
|
|
1400
1606
|
passwords: /* @__PURE__ */ new Map(),
|
|
1401
1607
|
pendingRegistrations: /* @__PURE__ */ new Map(),
|
|
@@ -1693,6 +1899,11 @@ function createMockStorefront(options = {}) {
|
|
|
1693
1899
|
return inv;
|
|
1694
1900
|
}
|
|
1695
1901
|
const orderInvoice = (order) => {
|
|
1902
|
+
const doc = order.invoices?.find((d) => d.kind === "invoice");
|
|
1903
|
+
if (doc) {
|
|
1904
|
+
const { id: _id, kind: _k, total: _t, issued_at: _i, cancelled_at: _c, series: _s, folio_number: _f, related_to: _r, links_expire_at: _l, test_mode: _tm, environment: _e, ...summary } = doc;
|
|
1905
|
+
return { ...summary, url: null, xml_url: null };
|
|
1906
|
+
}
|
|
1696
1907
|
const entry = state.invoices.get(order.id);
|
|
1697
1908
|
const paid = order.status !== "pending_payment";
|
|
1698
1909
|
if (entry) {
|
|
@@ -1853,21 +2064,21 @@ function createMockStorefront(options = {}) {
|
|
|
1853
2064
|
if (!Array.isArray(body.lines)) throw new HttpError(400, "validation", "`lines` must be an array", "lines");
|
|
1854
2065
|
const updates = body.lines;
|
|
1855
2066
|
updates.forEach((u, i) => {
|
|
1856
|
-
const
|
|
1857
|
-
if (!
|
|
2067
|
+
const line2 = cart.lines.find((l) => l.id === u.id);
|
|
2068
|
+
if (!line2) throw new HttpError(400, "validation", `Unknown line ${String(u.id)}`, `lines[${i}].id`);
|
|
1858
2069
|
if (typeof u.quantity !== "number" || !Number.isInteger(u.quantity) || u.quantity < 0) {
|
|
1859
2070
|
throw new HttpError(400, "validation", "quantity must be a non-negative integer", `lines[${i}].quantity`);
|
|
1860
2071
|
}
|
|
1861
2072
|
});
|
|
1862
2073
|
checkStock(
|
|
1863
2074
|
updates.flatMap((u, i) => {
|
|
1864
|
-
const
|
|
1865
|
-
return u.quantity > 0 ? [{ variant: findVariant(
|
|
2075
|
+
const line2 = cart.lines.find((l) => l.id === u.id);
|
|
2076
|
+
return u.quantity > 0 ? [{ variant: findVariant(line2.variant_id).variant, quantity: u.quantity, lineId: line2.id, field: `lines[${i}].quantity` }] : [];
|
|
1866
2077
|
})
|
|
1867
2078
|
);
|
|
1868
2079
|
for (const u of updates) {
|
|
1869
|
-
const
|
|
1870
|
-
|
|
2080
|
+
const line2 = cart.lines.find((l) => l.id === u.id);
|
|
2081
|
+
line2.quantity = u.quantity;
|
|
1871
2082
|
}
|
|
1872
2083
|
cart.lines = cart.lines.filter((l) => l.quantity > 0);
|
|
1873
2084
|
cart.updated_at = now();
|
|
@@ -1999,7 +2210,7 @@ function createMockStorefront(options = {}) {
|
|
|
1999
2210
|
}
|
|
2000
2211
|
syncAvailability(state.products);
|
|
2001
2212
|
const orderId = nextId("ord");
|
|
2002
|
-
const number = String(
|
|
2213
|
+
const number = String(Math.max(1e3, ...state.orders.map((o) => Number(o.number) || 0)) + 1);
|
|
2003
2214
|
const customerId = cart.buyer.customer_id ?? state.customers.find((c) => c.email && c.email === cart.buyer.email)?.id ?? null;
|
|
2004
2215
|
state.orders.push({
|
|
2005
2216
|
id: orderId,
|
|
@@ -2280,17 +2491,34 @@ function createMockStorefront(options = {}) {
|
|
|
2280
2491
|
}
|
|
2281
2492
|
return { body: publicCustomer(c), cache: "private" };
|
|
2282
2493
|
});
|
|
2283
|
-
const
|
|
2494
|
+
const orderView = ({ customer_id: _c, ...o }, detail) => {
|
|
2495
|
+
const order = { ...o, invoice: orderInvoice(o) };
|
|
2496
|
+
if (order.shipments) order.shipments = order.shipments.map((s) => isTestShipment(s) ? { ...s, tracking_number: null, tracking_url: null } : { ...s, events: sortTrackingEvents(s.events) });
|
|
2497
|
+
order.progress = orderProgress(order);
|
|
2498
|
+
order.next_action = nextAction(order);
|
|
2499
|
+
const live = orderShipments(order).filter((s) => !isTestShipment(s));
|
|
2500
|
+
if (order.shipments?.length) {
|
|
2501
|
+
order.shipments_summary = { count: order.shipments.length, status: shipmentsStatus(order) ?? "pending", carrier: live[0]?.carrier ?? null, ...live[0]?.tracking_url ? { tracking_url: live[0].tracking_url } : {} };
|
|
2502
|
+
}
|
|
2503
|
+
if (!detail) {
|
|
2504
|
+
delete order.shipments;
|
|
2505
|
+
delete order.invoices;
|
|
2506
|
+
delete order.payments;
|
|
2507
|
+
delete order.refunds;
|
|
2508
|
+
delete order.shipping_address;
|
|
2509
|
+
}
|
|
2510
|
+
return order;
|
|
2511
|
+
};
|
|
2284
2512
|
route("GET", "/customer/orders", "orders:read", ({ headers, search }) => {
|
|
2285
2513
|
const c = requireCustomer(headers);
|
|
2286
|
-
const orders = state.orders.filter((o) => o.customer_id === c.id).sort((a, b) => b.created_at.localeCompare(a.created_at)).map(
|
|
2514
|
+
const orders = state.orders.filter((o) => o.customer_id === c.id).sort((a, b) => b.created_at.localeCompare(a.created_at)).map((o) => orderView(o, false));
|
|
2287
2515
|
return { body: paginate(orders, search, 20), cache: "private" };
|
|
2288
2516
|
});
|
|
2289
2517
|
const findOrder = (headers, id) => {
|
|
2290
2518
|
const c = requireCustomer(headers);
|
|
2291
2519
|
return requireNode(state.orders.find((o) => o.id === id && o.customer_id === c.id), `Order ${id}`, "id");
|
|
2292
2520
|
};
|
|
2293
|
-
route("GET", "/customer/orders/:id", "orders:read", ({ headers, params }) => ({ body:
|
|
2521
|
+
route("GET", "/customer/orders/:id", "orders:read", ({ headers, params }) => ({ body: orderView(findOrder(headers, params[0]), true), cache: "private" }));
|
|
2294
2522
|
route("POST", "/customer/orders/:id/returns", "customer:write", ({ headers, params, body }) => {
|
|
2295
2523
|
const order = findOrder(headers, params[0]);
|
|
2296
2524
|
if (!Array.isArray(body.lines) || body.lines.length === 0) throw new HttpError(400, "validation", "lines are required", "lines");
|
|
@@ -2307,16 +2535,37 @@ function createMockStorefront(options = {}) {
|
|
|
2307
2535
|
state.invoices.set(order.id, { stage: "queued", request });
|
|
2308
2536
|
return { status: 202, body: { status: "requested", url: null, stage: "queued", invoice: orderInvoice(order) }, cache: "private" };
|
|
2309
2537
|
});
|
|
2538
|
+
route("GET", "/customer/pending-payments", "orders:read", ({ headers, search }) => {
|
|
2539
|
+
const c = requireCustomer(headers);
|
|
2540
|
+
const nodes = c.id === "cus_1" ? state.pendingPayments : [];
|
|
2541
|
+
return { body: paginate(nodes, search, 20), cache: "private" };
|
|
2542
|
+
});
|
|
2543
|
+
route("GET", "/customer/orders/:id/invoices/:invoice_id/:kind", "orders:read", ({ headers, params }) => {
|
|
2544
|
+
const order = findOrder(headers, params[0]);
|
|
2545
|
+
const doc = order.invoices?.find((d) => d.id === params[1]);
|
|
2546
|
+
if (!doc || params[2] !== "pdf" && params[2] !== "xml") throw new HttpError(404, "not_found", "Invoice file not found", "invoice_id");
|
|
2547
|
+
const pdf = params[2] === "pdf";
|
|
2548
|
+
const text = pdf ? `%PDF-1.4
|
|
2549
|
+
% mock invoice ${doc.id}
|
|
2550
|
+
%%EOF
|
|
2551
|
+
` : `<?xml version="1.0"?><cfdi:Comprobante mock="true" id="${doc.id}"/>`;
|
|
2552
|
+
const file = {
|
|
2553
|
+
filename: `${doc.kind === "credit_note" ? "nota-de-credito" : "factura"}-${doc.id}.${params[2]}`,
|
|
2554
|
+
content_type: pdf ? "application/pdf" : "application/xml",
|
|
2555
|
+
content_base64: btoa(text)
|
|
2556
|
+
};
|
|
2557
|
+
return { body: file, headers: { "Cache-Control": "no-store" } };
|
|
2558
|
+
});
|
|
2310
2559
|
route("GET", "/customer/addresses", "customer:read", ({ headers }) => {
|
|
2311
2560
|
const c = requireCustomer(headers);
|
|
2312
2561
|
return { body: { nodes: state.addresses.get(c.id) ?? [] }, cache: "private" };
|
|
2313
2562
|
});
|
|
2314
2563
|
route("POST", "/customer/addresses", "customer:write", ({ headers, body }) => {
|
|
2315
2564
|
const c = requireCustomer(headers);
|
|
2316
|
-
const
|
|
2317
|
-
state.addresses.set(c.id, [...state.addresses.get(c.id) ?? [],
|
|
2318
|
-
if (!c.default_address_id) c.default_address_id =
|
|
2319
|
-
return { status: 201, body:
|
|
2565
|
+
const address2 = { ...validateAddress(body), id: nextId("addr") };
|
|
2566
|
+
state.addresses.set(c.id, [...state.addresses.get(c.id) ?? [], address2]);
|
|
2567
|
+
if (!c.default_address_id) c.default_address_id = address2.id;
|
|
2568
|
+
return { status: 201, body: address2, cache: "private" };
|
|
2320
2569
|
});
|
|
2321
2570
|
route("PATCH", "/customer/addresses/:id", "customer:write", ({ headers, params, body }) => {
|
|
2322
2571
|
const c = requireCustomer(headers);
|