@asteby/storefront 0.3.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/dist/mock.d.cts CHANGED
@@ -1,4 +1,5 @@
1
- import { a1 as Shop, Q as Product, p as Collection, a8 as Theme, P as Page, M as Menu, b as Article, C as Cart, A as Address, r as Customer, O as Order } from './types-CTXB8Dnl.cjs';
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
@@ -93,4 +99,4 @@ declare function createMockStorefront(options?: MockStorefrontOptions): {
93
99
  };
94
100
  type MockStorefront = ReturnType<typeof createMockStorefront>;
95
101
 
96
- 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 { a1 as Shop, Q as Product, p as Collection, a8 as Theme, P as Page, M as Menu, b as Article, C as Cart, A as Address, r as Customer, O as Order } from './types-CTXB8Dnl.js';
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
@@ -93,4 +99,4 @@ declare function createMockStorefront(options?: MockStorefrontOptions): {
93
99
  };
94
100
  type MockStorefront = ReturnType<typeof createMockStorefront>;
95
101
 
96
- 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
  }
@@ -548,7 +614,7 @@ function createMockStorefront(options = {}) {
548
614
  const percent = codes.filter((d) => d.applicable).reduce((max, d) => Math.max(max, percentFor(d.code)), 0);
549
615
  const discount = Math.round(subtotal * percent / 100);
550
616
  let shipping = null;
551
- 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");
552
618
  else if (cart.delivery.method === "shipping" && cart.delivery.rate_id) {
553
619
  const rate = shippingRates(subtotal - discount).find((r) => r.id === cart.delivery.rate_id);
554
620
  shipping = rate ? toCents(rate.cost.amount) : null;
@@ -629,6 +695,25 @@ function createMockStorefront(options = {}) {
629
695
  body: requireNode(state.collections.find((c) => c.handle === params[0]), `Collection ${params[0]}`),
630
696
  cache: "public"
631
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
+ }));
632
717
  route("GET", "/stock", "catalog:read", ({ search }) => {
633
718
  const skus = search.getAll("sku");
634
719
  if (skus.length > 250) throw new HttpError(400, "validation", "At most 250 SKUs", "sku");
@@ -712,7 +797,7 @@ function createMockStorefront(options = {}) {
712
797
  const cart = renderCart(getCartRecord(params[0]));
713
798
  const net = toCents(cart.cost.subtotal.amount) - toCents(cart.cost.discount.amount);
714
799
  return {
715
- 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: [] },
716
801
  cache: "private"
717
802
  };
718
803
  });
@@ -730,7 +815,7 @@ function createMockStorefront(options = {}) {
730
815
  cart.delivery = { method: "shipping", rate_id: rateId, branch_id: null };
731
816
  } else if (body.method === "pickup") {
732
817
  const branchId = body.branch_id;
733
- 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)) {
734
819
  throw new HttpError(400, "validation", "Unknown branch_id", "branch_id");
735
820
  }
736
821
  cart.delivery = { method: "pickup", rate_id: null, branch_id: branchId };
@@ -995,6 +1080,6 @@ function createMockStorefront(options = {}) {
995
1080
  };
996
1081
  }
997
1082
 
998
- export { MOCK_CURRENCY, MOCK_CUSTOMER_EMAIL, MOCK_IMAGE_URL, createMockStorefront };
1083
+ export { MOCK_CURRENCY, MOCK_CUSTOMER_EMAIL, MOCK_IMAGE_URL, MOCK_POSTAL_CENTROIDS, createMockStorefront };
999
1084
  //# sourceMappingURL=mock.js.map
1000
1085
  //# sourceMappingURL=mock.js.map