@asteby/storefront 0.2.0 → 0.4.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 +51 -0
- package/dist/chunk-45R47HYO.js +144 -0
- package/dist/chunk-45R47HYO.js.map +1 -0
- package/dist/geo.cjs +154 -0
- package/dist/geo.cjs.map +1 -0
- package/dist/geo.d.cts +82 -0
- package/dist/geo.d.ts +82 -0
- package/dist/geo.js +3 -0
- package/dist/geo.js.map +1 -0
- package/dist/index.cjs +29 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +31 -3
- package/dist/index.d.ts +31 -3
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -1
- package/dist/mock.cjs +122 -7
- package/dist/mock.cjs.map +1 -1
- package/dist/mock.d.cts +9 -2
- package/dist/mock.d.ts +9 -2
- package/dist/mock.js +100 -8
- package/dist/mock.js.map +1 -1
- package/dist/{types-CTXB8Dnl.d.cts → types-BmC-RDo8.d.ts} +51 -1
- package/dist/{types-CTXB8Dnl.d.ts → types-D300wdPF.d.cts} +51 -1
- package/package.json +11 -1
package/dist/mock.d.cts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a7 as Shop, W as Product, p as Collection, ae as Theme, R as Page, M as Menu, b as Article, C as Cart, A as Address, r as Customer, P as Order } from './types-D300wdPF.cjs';
|
|
2
|
+
import './geo.cjs';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Placeholder image source for all seed data. Swap it (or pass `imageUrl` to
|
|
@@ -9,6 +10,11 @@ type MockImageUrl = typeof MOCK_IMAGE_URL;
|
|
|
9
10
|
declare const MOCK_CURRENCY = "MXN";
|
|
10
11
|
/** Seed customer that already exists (log in with OTP `000000`). */
|
|
11
12
|
declare const MOCK_CUSTOMER_EMAIL = "cliente@example.com";
|
|
13
|
+
/** Postal-code centroids the mock can resolve (the real API resolves any Mexican CP). */
|
|
14
|
+
declare const MOCK_POSTAL_CENTROIDS: Record<string, {
|
|
15
|
+
lat: number;
|
|
16
|
+
lng: number;
|
|
17
|
+
}>;
|
|
12
18
|
|
|
13
19
|
/**
|
|
14
20
|
* In-memory implementation of the whole Storefront API v1 contract, exposed
|
|
@@ -78,6 +84,7 @@ type MockState = {
|
|
|
78
84
|
status: number;
|
|
79
85
|
body: unknown;
|
|
80
86
|
}>;
|
|
87
|
+
checkouts: Map<string, unknown>;
|
|
81
88
|
seq: number;
|
|
82
89
|
};
|
|
83
90
|
declare function createMockStorefront(options?: MockStorefrontOptions): {
|
|
@@ -92,4 +99,4 @@ declare function createMockStorefront(options?: MockStorefrontOptions): {
|
|
|
92
99
|
};
|
|
93
100
|
type MockStorefront = ReturnType<typeof createMockStorefront>;
|
|
94
101
|
|
|
95
|
-
export { MOCK_CURRENCY, MOCK_CUSTOMER_EMAIL, MOCK_IMAGE_URL, type MockImageUrl, type MockState, type MockStorefront, type MockStorefrontOptions, createMockStorefront };
|
|
102
|
+
export { MOCK_CURRENCY, MOCK_CUSTOMER_EMAIL, MOCK_IMAGE_URL, MOCK_POSTAL_CENTROIDS, type MockImageUrl, type MockState, type MockStorefront, type MockStorefrontOptions, createMockStorefront };
|
package/dist/mock.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a7 as Shop, W as Product, p as Collection, ae as Theme, R as Page, M as Menu, b as Article, C as Cart, A as Address, r as Customer, P as Order } from './types-BmC-RDo8.js';
|
|
2
|
+
import './geo.js';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Placeholder image source for all seed data. Swap it (or pass `imageUrl` to
|
|
@@ -9,6 +10,11 @@ type MockImageUrl = typeof MOCK_IMAGE_URL;
|
|
|
9
10
|
declare const MOCK_CURRENCY = "MXN";
|
|
10
11
|
/** Seed customer that already exists (log in with OTP `000000`). */
|
|
11
12
|
declare const MOCK_CUSTOMER_EMAIL = "cliente@example.com";
|
|
13
|
+
/** Postal-code centroids the mock can resolve (the real API resolves any Mexican CP). */
|
|
14
|
+
declare const MOCK_POSTAL_CENTROIDS: Record<string, {
|
|
15
|
+
lat: number;
|
|
16
|
+
lng: number;
|
|
17
|
+
}>;
|
|
12
18
|
|
|
13
19
|
/**
|
|
14
20
|
* In-memory implementation of the whole Storefront API v1 contract, exposed
|
|
@@ -78,6 +84,7 @@ type MockState = {
|
|
|
78
84
|
status: number;
|
|
79
85
|
body: unknown;
|
|
80
86
|
}>;
|
|
87
|
+
checkouts: Map<string, unknown>;
|
|
81
88
|
seq: number;
|
|
82
89
|
};
|
|
83
90
|
declare function createMockStorefront(options?: MockStorefrontOptions): {
|
|
@@ -92,4 +99,4 @@ declare function createMockStorefront(options?: MockStorefrontOptions): {
|
|
|
92
99
|
};
|
|
93
100
|
type MockStorefront = ReturnType<typeof createMockStorefront>;
|
|
94
101
|
|
|
95
|
-
export { MOCK_CURRENCY, MOCK_CUSTOMER_EMAIL, MOCK_IMAGE_URL, type MockImageUrl, type MockState, type MockStorefront, type MockStorefrontOptions, createMockStorefront };
|
|
102
|
+
export { MOCK_CURRENCY, MOCK_CUSTOMER_EMAIL, MOCK_IMAGE_URL, MOCK_POSTAL_CENTROIDS, type MockImageUrl, type MockState, type MockStorefront, type MockStorefrontOptions, createMockStorefront };
|
package/dist/mock.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { isValidPoint, rankByDistance } from './chunk-45R47HYO.js';
|
|
2
|
+
|
|
1
3
|
// src/mock/seed.ts
|
|
2
4
|
var MOCK_IMAGE_URL = (seed, width = 800, height = 800) => `https://picsum.photos/seed/${encodeURIComponent(seed)}/${width}/${height}`;
|
|
3
5
|
var MOCK_CURRENCY = "MXN";
|
|
@@ -128,6 +130,73 @@ function buildCollections(imageUrl = MOCK_IMAGE_URL) {
|
|
|
128
130
|
parent_handle: c.parent ?? null
|
|
129
131
|
}));
|
|
130
132
|
}
|
|
133
|
+
var MX_TZ = "America/Mexico_City";
|
|
134
|
+
var weekdays = (open, close, days = [1, 2, 3, 4, 5]) => days.map((day) => ({ day, open, close }));
|
|
135
|
+
function buildLocations(currency) {
|
|
136
|
+
const contacts = (phone) => ({ phone, email: null, whatsapp: null });
|
|
137
|
+
return [
|
|
138
|
+
{
|
|
139
|
+
id: "br_centro",
|
|
140
|
+
name: "Sucursal Centro",
|
|
141
|
+
kind: "store",
|
|
142
|
+
address: "Av. Principal 100, Col. Centro",
|
|
143
|
+
city: "Ciudad de M\xE9xico",
|
|
144
|
+
postal_code: "06000",
|
|
145
|
+
phone: "+52 55 0000 0001",
|
|
146
|
+
lat: 19.4326,
|
|
147
|
+
lng: -99.1332,
|
|
148
|
+
timezone: MX_TZ,
|
|
149
|
+
hours: "Mo-Fr 09:00-19:00, Sa 09:00-14:00",
|
|
150
|
+
opening_hours_text: "Lun\u2013Vie 9:00\u201319:00 \xB7 S\xE1b 9:00\u201314:00",
|
|
151
|
+
opening_hours: { weekly: [...weekdays("09:00", "19:00"), { day: 6, open: "09:00", close: "14:00" }] },
|
|
152
|
+
services: ["pickup", "returns"],
|
|
153
|
+
contacts: contacts("+52 55 0000 0001"),
|
|
154
|
+
pickup: { enabled: true, fee: null, prep_days: 0 }
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
id: "br_norte",
|
|
158
|
+
name: "Sucursal Norte",
|
|
159
|
+
kind: "store",
|
|
160
|
+
address: "Calle Secundaria 25, Col. Norte",
|
|
161
|
+
city: "Monterrey",
|
|
162
|
+
postal_code: "64000",
|
|
163
|
+
phone: null,
|
|
164
|
+
lat: 25.6866,
|
|
165
|
+
lng: -100.3161,
|
|
166
|
+
timezone: MX_TZ,
|
|
167
|
+
hours: "Mo-Sa 10:00-18:00",
|
|
168
|
+
opening_hours_text: "Lun\u2013S\xE1b 10:00\u201318:00",
|
|
169
|
+
opening_hours: { weekly: weekdays("10:00", "18:00", [1, 2, 3, 4, 5, 6]) },
|
|
170
|
+
services: ["pickup"],
|
|
171
|
+
contacts: contacts(null),
|
|
172
|
+
pickup: { enabled: true, fee: money(30, currency), prep_days: 1 }
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
id: "br_occidente",
|
|
176
|
+
name: "Punto de recolecci\xF3n Occidente",
|
|
177
|
+
kind: "pickup_point",
|
|
178
|
+
address: "Av. Vallarta 1500, Col. Americana",
|
|
179
|
+
city: "Guadalajara",
|
|
180
|
+
postal_code: "44100",
|
|
181
|
+
phone: "+52 33 0000 0003",
|
|
182
|
+
lat: 20.6736,
|
|
183
|
+
lng: -103.3897,
|
|
184
|
+
timezone: MX_TZ,
|
|
185
|
+
hours: "Mo-Fr 11:00-20:00",
|
|
186
|
+
opening_hours_text: "Lun\u2013Vie 11:00\u201320:00",
|
|
187
|
+
opening_hours: { weekly: weekdays("11:00", "20:00") },
|
|
188
|
+
services: ["pickup"],
|
|
189
|
+
contacts: contacts("+52 33 0000 0003"),
|
|
190
|
+
pickup: { enabled: false, fee: null, prep_days: 2 }
|
|
191
|
+
}
|
|
192
|
+
];
|
|
193
|
+
}
|
|
194
|
+
var MOCK_POSTAL_CENTROIDS = {
|
|
195
|
+
"06000": { lat: 19.4326, lng: -99.1332 },
|
|
196
|
+
"64000": { lat: 25.6714, lng: -100.309 },
|
|
197
|
+
"44100": { lat: 20.6767, lng: -103.3475 },
|
|
198
|
+
"03100": { lat: 19.3885, lng: -99.1719 }
|
|
199
|
+
};
|
|
131
200
|
function buildShop(currency, imageUrl = MOCK_IMAGE_URL) {
|
|
132
201
|
return {
|
|
133
202
|
name: "Mi tienda",
|
|
@@ -139,10 +208,7 @@ function buildShop(currency, imageUrl = MOCK_IMAGE_URL) {
|
|
|
139
208
|
country_code: "MX",
|
|
140
209
|
logo: { url: imageUrl("logo", 256, 256), alt: "Mi tienda", width: 256, height: 256 },
|
|
141
210
|
contact: { email: "hola@mi-tienda.example", phone: "+52 55 0000 0000", whatsapp: "+5215500000000" },
|
|
142
|
-
branches:
|
|
143
|
-
{ id: "br_centro", name: "Sucursal Centro", address: "Av. Principal 100, Col. Centro", city: "Ciudad de M\xE9xico", phone: "+52 55 0000 0001", lat: 19.4326, lng: -99.1332, hours: "Mo-Fr 09:00-19:00, Sa 09:00-14:00" },
|
|
144
|
-
{ id: "br_norte", name: "Sucursal Norte", address: "Calle Secundaria 25, Col. Norte", city: "Monterrey", phone: null, lat: 25.6866, lng: -100.3161, hours: "Mo-Sa 10:00-18:00" }
|
|
145
|
-
],
|
|
211
|
+
branches: buildLocations(currency),
|
|
146
212
|
policies: { free_shipping_min: money(999, currency), returns_days: 30 }
|
|
147
213
|
};
|
|
148
214
|
}
|
|
@@ -360,6 +426,7 @@ function createMockStorefront(options = {}) {
|
|
|
360
426
|
otps: /* @__PURE__ */ new Map(),
|
|
361
427
|
sessions: /* @__PURE__ */ new Map(),
|
|
362
428
|
idempotency: /* @__PURE__ */ new Map(),
|
|
429
|
+
checkouts: /* @__PURE__ */ new Map(),
|
|
363
430
|
seq: 0
|
|
364
431
|
};
|
|
365
432
|
}
|
|
@@ -547,7 +614,7 @@ function createMockStorefront(options = {}) {
|
|
|
547
614
|
const percent = codes.filter((d) => d.applicable).reduce((max, d) => Math.max(max, percentFor(d.code)), 0);
|
|
548
615
|
const discount = Math.round(subtotal * percent / 100);
|
|
549
616
|
let shipping = null;
|
|
550
|
-
if (cart.delivery.method === "pickup") shipping = 0;
|
|
617
|
+
if (cart.delivery.method === "pickup") shipping = toCents(state.shop.branches.find((b) => b.id === cart.delivery.branch_id)?.pickup?.fee?.amount ?? "0");
|
|
551
618
|
else if (cart.delivery.method === "shipping" && cart.delivery.rate_id) {
|
|
552
619
|
const rate = shippingRates(subtotal - discount).find((r) => r.id === cart.delivery.rate_id);
|
|
553
620
|
shipping = rate ? toCents(rate.cost.amount) : null;
|
|
@@ -628,6 +695,25 @@ function createMockStorefront(options = {}) {
|
|
|
628
695
|
body: requireNode(state.collections.find((c) => c.handle === params[0]), `Collection ${params[0]}`),
|
|
629
696
|
cache: "public"
|
|
630
697
|
}));
|
|
698
|
+
const visibleLocations = () => state.shop.branches;
|
|
699
|
+
const round2 = (n) => Math.round(n * 100) / 100;
|
|
700
|
+
const withDistance = (origin) => rankByDistance(visibleLocations(), origin).map(({ item, distanceKm }) => ({ ...item, distance_km: Math.round(distanceKm * 10) / 10 }));
|
|
701
|
+
route("GET", "/locations", "catalog:read", ({ search }) => {
|
|
702
|
+
const cp = search.get("postal_code");
|
|
703
|
+
const origin = cp ? MOCK_POSTAL_CENTROIDS[cp] : void 0;
|
|
704
|
+
return { body: { nodes: origin ? withDistance(origin) : visibleLocations() }, cache: "public" };
|
|
705
|
+
});
|
|
706
|
+
route("GET", "/locations/nearest", "catalog:read", ({ search }) => {
|
|
707
|
+
const origin = { lat: Number(search.get("lat") ?? NaN), lng: Number(search.get("lng") ?? NaN) };
|
|
708
|
+
if (search.get("lat") === null || search.get("lng") === null || !isValidPoint(origin)) {
|
|
709
|
+
throw new HttpError(400, "validation", "lat and lng must be a valid point", "lat");
|
|
710
|
+
}
|
|
711
|
+
return { body: { nodes: withDistance({ lat: round2(origin.lat), lng: round2(origin.lng) }) }, cache: "private" };
|
|
712
|
+
});
|
|
713
|
+
route("GET", "/locations/:id", "catalog:read", ({ params }) => ({
|
|
714
|
+
body: requireNode(visibleLocations().find((b) => b.id === params[0]), `Location ${params[0]}`, "id"),
|
|
715
|
+
cache: "public"
|
|
716
|
+
}));
|
|
631
717
|
route("GET", "/stock", "catalog:read", ({ search }) => {
|
|
632
718
|
const skus = search.getAll("sku");
|
|
633
719
|
if (skus.length > 250) throw new HttpError(400, "validation", "At most 250 SKUs", "sku");
|
|
@@ -711,7 +797,7 @@ function createMockStorefront(options = {}) {
|
|
|
711
797
|
const cart = renderCart(getCartRecord(params[0]));
|
|
712
798
|
const net = toCents(cart.cost.subtotal.amount) - toCents(cart.cost.discount.amount);
|
|
713
799
|
return {
|
|
714
|
-
body: { rates: shippingRates(net), pickup: state.shop.branches.map((b) => ({ branch_id: b.id, name: b.name })), partial: false, unavailable: [] },
|
|
800
|
+
body: { rates: shippingRates(net), pickup: state.shop.branches.filter((b) => b.pickup?.enabled !== false).map((b) => ({ branch_id: b.id, name: b.name, address: b.address, city: b.city })), partial: false, unavailable: [] },
|
|
715
801
|
cache: "private"
|
|
716
802
|
};
|
|
717
803
|
});
|
|
@@ -729,7 +815,7 @@ function createMockStorefront(options = {}) {
|
|
|
729
815
|
cart.delivery = { method: "shipping", rate_id: rateId, branch_id: null };
|
|
730
816
|
} else if (body.method === "pickup") {
|
|
731
817
|
const branchId = body.branch_id;
|
|
732
|
-
if (typeof branchId !== "string" || !state.shop.branches.some((b) => b.id === branchId)) {
|
|
818
|
+
if (typeof branchId !== "string" || !state.shop.branches.some((b) => b.id === branchId && b.pickup?.enabled !== false)) {
|
|
733
819
|
throw new HttpError(400, "validation", "Unknown branch_id", "branch_id");
|
|
734
820
|
}
|
|
735
821
|
cart.delivery = { method: "pickup", rate_id: null, branch_id: branchId };
|
|
@@ -798,9 +884,15 @@ function createMockStorefront(options = {}) {
|
|
|
798
884
|
stock_hold_expires_at: new Date(Date.now() + 30 * 6e4).toISOString()
|
|
799
885
|
}
|
|
800
886
|
};
|
|
887
|
+
state.checkouts.set(checkoutId, result);
|
|
801
888
|
if (key) state.idempotency.set(`${params[0]}:${key}`, { status: 201, body: result });
|
|
802
889
|
return { status: 201, body: result, cache: "private" };
|
|
803
890
|
});
|
|
891
|
+
route("GET", "/checkouts/:id", "checkout:write", ({ params }) => {
|
|
892
|
+
const found = state.checkouts.get(params[0]);
|
|
893
|
+
if (!found) throw new HttpError(404, "not_found", "Checkout not found");
|
|
894
|
+
return { body: found, cache: "private" };
|
|
895
|
+
});
|
|
804
896
|
route("POST", "/customer/otp", "customer:write", ({ body }) => {
|
|
805
897
|
state.otps.set(identifierOf(body), otpCode);
|
|
806
898
|
return { status: 204 };
|
|
@@ -988,6 +1080,6 @@ function createMockStorefront(options = {}) {
|
|
|
988
1080
|
};
|
|
989
1081
|
}
|
|
990
1082
|
|
|
991
|
-
export { MOCK_CURRENCY, MOCK_CUSTOMER_EMAIL, MOCK_IMAGE_URL, createMockStorefront };
|
|
1083
|
+
export { MOCK_CURRENCY, MOCK_CUSTOMER_EMAIL, MOCK_IMAGE_URL, MOCK_POSTAL_CENTROIDS, createMockStorefront };
|
|
992
1084
|
//# sourceMappingURL=mock.js.map
|
|
993
1085
|
//# sourceMappingURL=mock.js.map
|