@misiki/gocommerce-connector 0.4.4 → 0.4.6

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.
@@ -1013,6 +1013,13 @@ var StoreFacts = class extends BaseService {
1013
1013
  profile() {
1014
1014
  return remember(this.key("profile"), () => this.data("/api/store"));
1015
1015
  }
1016
+ /** Where the store delivers (D117): its priced zones' countries, or everywhere. */
1017
+ shipsTo() {
1018
+ return remember(this.key("ships-to"), async () => {
1019
+ const r = await this.data("/api/checkout/countries");
1020
+ return { everywhere: r?.everywhere ?? true, countries: r?.countries ?? [] };
1021
+ });
1022
+ }
1016
1023
  checkoutOptions() {
1017
1024
  return remember(this.key("checkout"), () => this.data("/api/checkout"));
1018
1025
  }
@@ -2186,6 +2193,19 @@ var UserService = class extends BaseService {
2186
2193
  }
2187
2194
  };
2188
2195
  var AuthService = class extends UserService {
2196
+ facts = new StoreFacts(this._fetch);
2197
+ /**
2198
+ * How this store signs customers in: `email_password` or `phone_otp`.
2199
+ * A store whose accounts module says nothing signs in by email.
2200
+ */
2201
+ async loginMethod() {
2202
+ try {
2203
+ const method = (await this.facts.plugins()).get("identity")?.settings?.login_method;
2204
+ return method === "phone_otp" ? "phone_otp" : "email_password";
2205
+ } catch {
2206
+ return "email_password";
2207
+ }
2208
+ }
2189
2209
  async forgotPassword({ email }) {
2190
2210
  return this.account("/x/identity/password-reset", {
2191
2211
  method: "POST",
@@ -2212,11 +2232,21 @@ var AuthService = class extends UserService {
2212
2232
  return { errorCode: err.code ?? "invalid_token", message: err.message };
2213
2233
  }
2214
2234
  }
2215
- async getOtp() {
2216
- throw new NotSupportedError("AuthService", "getOtp", "sign in with an email and password");
2235
+ /** Texts a 4-digit sign-in code to `phone`, which needs its country code. */
2236
+ async getOtp({ phone }) {
2237
+ const res = await this.account("/x/identity/otp", {
2238
+ method: "POST",
2239
+ body: { phone: String(phone ?? "").trim() }
2240
+ });
2241
+ return { expiresInMinutes: res?.expires_in_minutes ?? 10 };
2217
2242
  }
2218
- async verifyOtp() {
2219
- throw new NotSupportedError("AuthService", "verifyOtp", "sign in with an email and password");
2243
+ /** Signs in the account on `phone` with the code it was sent, opening one the first time. */
2244
+ async verifyOtp({ phone, otp }) {
2245
+ const auth = await this.account("/x/identity/otp/verify", {
2246
+ method: "POST",
2247
+ body: { phone: String(phone ?? "").trim(), code: String(otp ?? "").trim() }
2248
+ });
2249
+ return this.signedIn(auth);
2220
2250
  }
2221
2251
  async joinAsAdmin() {
2222
2252
  throw new NotSupportedError("AuthService", "joinAsAdmin", "operators are invited from the admin panel");
@@ -2537,12 +2567,14 @@ var StoreService = class extends BaseService {
2537
2567
  return super.post(path, data);
2538
2568
  }
2539
2569
  async live() {
2540
- const [ready, plugins, menus, base, profile] = await Promise.all([
2570
+ const [ready, plugins, menus, base, profile, ships] = await Promise.all([
2541
2571
  this.facts.ready(),
2542
2572
  this.facts.plugins().catch(() => /* @__PURE__ */ new Map()),
2543
2573
  new MenuService(this._fetch).engineMenus(),
2544
2574
  readStaticStore(),
2545
- this.facts.profile().catch(() => null)
2575
+ this.facts.profile().catch(() => null),
2576
+ // An engine without the route rules nothing out.
2577
+ this.facts.shipsTo().catch(() => ({ everywhere: true, countries: [] }))
2546
2578
  ]);
2547
2579
  const code = ready.currency;
2548
2580
  const sameCurrency = (base.currency?.code ?? base.currencyCode) === code;
@@ -2571,11 +2603,30 @@ var StoreService = class extends BaseService {
2571
2603
  ...flag(plugins.has("product-reviews"))
2572
2604
  }
2573
2605
  },
2574
- ...menus?.length ? { menu: menus } : {}
2606
+ ...menus?.length ? { menu: menus } : {},
2607
+ ...deliverable(base, ships),
2608
+ // The one way this store signs customers in (D116), which the sign-in
2609
+ // form reads as PHONE or EMAIL. Without the accounts module the static
2610
+ // record says.
2611
+ ...plugins.has("identity") ? { loginType: plugins.get("identity")?.settings?.login_method === "phone_otp" ? "PHONE" : "EMAIL" } : {}
2575
2612
  };
2576
2613
  }
2577
2614
  };
2578
2615
  var storeService = new StoreService();
2616
+ function deliverable(base, ships) {
2617
+ if (ships.everywhere || !ships.countries.length) return {};
2618
+ const known = new Map((base.countries ?? []).map((c) => [String(c.code).toUpperCase(), c]));
2619
+ const countries = ships.countries.map((code) => known.get(code) ?? { code, name: regionName(code) });
2620
+ const keep = base.country && ships.countries.includes(String(base.country.code).toUpperCase());
2621
+ return { countries, ...keep ? {} : { country: countries[0] } };
2622
+ }
2623
+ function regionName(code) {
2624
+ try {
2625
+ return new Intl.DisplayNames(["en"], { type: "region" }).of(code) ?? code;
2626
+ } catch {
2627
+ return code;
2628
+ }
2629
+ }
2579
2630
 
2580
2631
  // src/services/page-service.ts
2581
2632
  var PageService = class extends BaseService {