@asteby/storefront 0.15.0 → 0.16.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.
package/dist/mock.cjs CHANGED
@@ -564,6 +564,7 @@ var SEED_MX_CSF = {
564
564
  },
565
565
  "verify_kind": "qr_validator",
566
566
  "freshness_days": 90,
567
+ "image_mode": "qr_only",
567
568
  "discard_fields": [
568
569
  "curp",
569
570
  "street",
@@ -807,6 +808,16 @@ var SEED_MX_INVOICE_USES = [
807
808
  "624",
808
809
  "625",
809
810
  "626"
811
+ ],
812
+ "suggested_for_regimes": [
813
+ "601",
814
+ "612",
815
+ "621",
816
+ "622",
817
+ "623",
818
+ "624",
819
+ "625",
820
+ "626"
810
821
  ]
811
822
  },
812
823
  {
@@ -1184,6 +1195,19 @@ var SEED_MX_INVOICE_USES = [
1184
1195
  "624",
1185
1196
  "625",
1186
1197
  "626"
1198
+ ],
1199
+ "suggested_for_regimes": [
1200
+ "603",
1201
+ "605",
1202
+ "606",
1203
+ "607",
1204
+ "608",
1205
+ "610",
1206
+ "611",
1207
+ "614",
1208
+ "615",
1209
+ "616",
1210
+ "620"
1187
1211
  ]
1188
1212
  }
1189
1213
  ];
@@ -1267,7 +1291,10 @@ var MOCK_FISCAL_ID_MX = {
1267
1291
  generic_ids: SEED_MX_GENERIC_IDS,
1268
1292
  regimes: SEED_MX_REGIMES,
1269
1293
  invoice_uses: SEED_MX_INVOICE_USES,
1270
- documents: [SEED_MX_CSF]
1294
+ documents: [SEED_MX_CSF],
1295
+ // The pack's person-type patterns and check algorithm (region_settings.fiscal_id_person_patterns / _checksum).
1296
+ person_patterns: { individual: "^[A-Z\xD1&]{4}[0-9]{6}[A-Z0-9]{3}$", company: "^[A-Z\xD1&]{3}[0-9]{6}[A-Z0-9]{3}$" },
1297
+ checksum: "mx_rfc"
1271
1298
  };
1272
1299
  var MOCK_REGION_MX = {
1273
1300
  country_code: "MX",
@@ -1729,6 +1756,7 @@ function createMockStorefront(options = {}) {
1729
1756
  identity_documents: ["MX:csf"],
1730
1757
  online_verify: false
1731
1758
  },
1759
+ fiscal_profiles: { max: 10 },
1732
1760
  ...options.customerCapabilities
1733
1761
  };
1734
1762
  const missingScopes = options.missingScopes ?? [];
@@ -1759,6 +1787,7 @@ function createMockStorefront(options = {}) {
1759
1787
  carts: /* @__PURE__ */ new Map(),
1760
1788
  customers: buildCustomers(),
1761
1789
  addresses: /* @__PURE__ */ new Map(),
1790
+ fiscalProfiles: /* @__PURE__ */ new Map(),
1762
1791
  orders: [
1763
1792
  {
1764
1793
  id: "ord_seed_1",
@@ -2728,6 +2757,97 @@ function createMockStorefront(options = {}) {
2728
2757
  };
2729
2758
  return { body: file, headers: { "Cache-Control": "no-store" } };
2730
2759
  });
2760
+ const MAX_FISCAL_PROFILES = 10;
2761
+ const profilesOf = (c) => state.fiscalProfiles.get(c.id) ?? [];
2762
+ const publicProfile = (p) => {
2763
+ if (!p.document) return p;
2764
+ const { sha256: _sha, ...document } = p.document;
2765
+ return { ...p, document };
2766
+ };
2767
+ const personTypeOf = (taxId) => {
2768
+ for (const [type, pattern] of Object.entries(region?.fiscal_id?.person_patterns ?? {})) if (new RegExp(pattern).test(taxId)) return type;
2769
+ return null;
2770
+ };
2771
+ const mirrorDefaultProfile = (c) => {
2772
+ const d = profilesOf(c).find((p) => p.is_default);
2773
+ c.fiscal = d ? { country_code: d.country_code, tax_id: d.tax_id, legal_name: d.legal_name, tax_regime: d.tax_regime, postal_code: d.postal_code, invoice_use: d.invoice_use ?? null, document: d.document ?? null, verification: d.verification ?? null } : null;
2774
+ };
2775
+ const profileFields = (body, base) => {
2776
+ const merged = {
2777
+ ...base ? { tax_id: base.tax_id, legal_name: base.legal_name, tax_regime: base.tax_regime, postal_code: base.postal_code, country_code: base.country_code, ...base.invoice_use ? { use: base.invoice_use } : {} } : {},
2778
+ ...body,
2779
+ requested: true
2780
+ };
2781
+ delete merged.label;
2782
+ delete merged.is_default;
2783
+ delete merged.verification;
2784
+ const fiscal = parseInvoice(merged, "fiscal");
2785
+ return {
2786
+ country_code: String(fiscal.country_code ?? region?.country_code ?? ""),
2787
+ tax_id: String(fiscal.tax_id ?? fiscal.rfc).toUpperCase(),
2788
+ legal_name: String(fiscal.legal_name ?? fiscal.razon_social),
2789
+ tax_regime: String(fiscal.tax_regime ?? fiscal.regimen),
2790
+ postal_code: String(fiscal.postal_code ?? fiscal.cp),
2791
+ invoice_use: String(fiscal.use ?? fiscal.uso_cfdi ?? fiscal.invoice_use ?? "") || null,
2792
+ document: fiscal.document ?? base?.document ?? null
2793
+ };
2794
+ };
2795
+ const ownProfile = (c, id) => {
2796
+ const p = profilesOf(c).find((x) => x.id === id);
2797
+ if (!p) throw new HttpError(404, "not_found", "Fiscal profile not found", "id");
2798
+ return p;
2799
+ };
2800
+ const makeDefault = (c, id) => state.fiscalProfiles.set(c.id, profilesOf(c).map((p) => ({ ...p, is_default: p.id === id })));
2801
+ route("GET", "/customer/fiscal-profiles", "customer:read", ({ headers }) => {
2802
+ const c = requireCustomer(headers);
2803
+ const nodes = [...profilesOf(c)].sort((a, b) => Number(b.is_default) - Number(a.is_default) || (b.last_used_at ?? "").localeCompare(a.last_used_at ?? ""));
2804
+ return { body: { nodes: nodes.map(publicProfile) }, cache: "private" };
2805
+ });
2806
+ route("POST", "/customer/fiscal-profiles", "customer:write", ({ headers, body }) => {
2807
+ const c = requireCustomer(headers);
2808
+ const list = profilesOf(c);
2809
+ const fid = profileFields(body);
2810
+ if (list.length >= MAX_FISCAL_PROFILES) throw new HttpError(409, "conflict", "Fiscal profile limit reached; delete one first");
2811
+ if (list.some((p) => p.country_code === fid.country_code && p.tax_id === fid.tax_id)) throw new HttpError(409, "conflict", "A profile with this tax id already exists", "tax_id");
2812
+ const at = now();
2813
+ const label = typeof body.label === "string" && body.label.trim() ? body.label.trim().slice(0, 40) : fid.legal_name.slice(0, 40);
2814
+ const profile = { ...fid, id: nextId("fisc"), label, person_type: personTypeOf(fid.tax_id), is_default: false, last_used_at: null, created_at: at, updated_at: at, verification: { status: "unverified", checked_at: null } };
2815
+ state.fiscalProfiles.set(c.id, [...list, profile]);
2816
+ if (list.length === 0 || body.is_default === true) makeDefault(c, profile.id);
2817
+ mirrorDefaultProfile(c);
2818
+ return { status: 201, body: publicProfile(profilesOf(c).find((p) => p.id === profile.id)), cache: "private" };
2819
+ });
2820
+ route("PATCH", "/customer/fiscal-profiles/:id", "customer:write", ({ headers, params, body }) => {
2821
+ const c = requireCustomer(headers);
2822
+ const cur = ownProfile(c, params[0]);
2823
+ if ("verification" in body) throw new HttpError(400, "validation", "verification is set by the server", "verification");
2824
+ if (body.is_default === false && cur.is_default) throw new HttpError(400, "validation", "Make another profile the default instead", "is_default");
2825
+ const fid = profileFields(body, cur);
2826
+ if (profilesOf(c).some((p) => p.id !== cur.id && p.country_code === fid.country_code && p.tax_id === fid.tax_id)) throw new HttpError(409, "conflict", "A profile with this tax id already exists", "tax_id");
2827
+ const identityChanged = fid.tax_id !== cur.tax_id || fid.country_code !== cur.country_code;
2828
+ const updated = {
2829
+ ...cur,
2830
+ ...fid,
2831
+ document: "document" in body ? fid.document : identityChanged ? null : cur.document,
2832
+ label: typeof body.label === "string" && body.label.trim() ? body.label.trim().slice(0, 40) : cur.label,
2833
+ person_type: personTypeOf(fid.tax_id),
2834
+ verification: identityChanged ? { status: "unverified", checked_at: null } : cur.verification,
2835
+ updated_at: now()
2836
+ };
2837
+ state.fiscalProfiles.set(c.id, profilesOf(c).map((p) => p.id === cur.id ? updated : p));
2838
+ if (body.is_default === true) makeDefault(c, cur.id);
2839
+ mirrorDefaultProfile(c);
2840
+ return { body: publicProfile(profilesOf(c).find((p) => p.id === cur.id)), cache: "private" };
2841
+ });
2842
+ route("DELETE", "/customer/fiscal-profiles/:id", "customer:write", ({ headers, params }) => {
2843
+ const c = requireCustomer(headers);
2844
+ const cur = ownProfile(c, params[0]);
2845
+ const rest = profilesOf(c).filter((p) => p.id !== cur.id);
2846
+ state.fiscalProfiles.set(c.id, rest);
2847
+ if (cur.is_default && rest[0]) makeDefault(c, rest[0].id);
2848
+ mirrorDefaultProfile(c);
2849
+ return { status: 204 };
2850
+ });
2731
2851
  route("GET", "/customer/addresses", "customer:read", ({ headers }) => {
2732
2852
  const c = requireCustomer(headers);
2733
2853
  return { body: { nodes: state.addresses.get(c.id) ?? [] }, cache: "private" };