@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.
@@ -1286,6 +1286,11 @@ declare class StoreFacts extends BaseService {
1286
1286
  }>;
1287
1287
  /** The store's own name and how a buyer reaches it, as set in its panel. */
1288
1288
  profile(): Promise<StoreProfile>;
1289
+ /** Where the store delivers (D117): its priced zones' countries, or everywhere. */
1290
+ shipsTo(): Promise<{
1291
+ everywhere: boolean;
1292
+ countries: string[];
1293
+ }>;
1289
1294
  checkoutOptions(): Promise<CheckoutOptions>;
1290
1295
  /**
1291
1296
  * The whole tree, flat and depth-first. Past 500 categories the engine
@@ -4901,15 +4906,35 @@ declare class UserService extends BaseService {
4901
4906
  deleteUser(): Promise<never>;
4902
4907
  checkEmail(): Promise<never>;
4903
4908
  joinAsVendor(): Promise<never>;
4904
- private signedIn;
4909
+ protected signedIn(auth: AuthResponse): Promise<{
4910
+ id: string;
4911
+ userId: string;
4912
+ email: string;
4913
+ phone: string | null;
4914
+ firstName: string;
4915
+ lastName: string;
4916
+ name: string;
4917
+ fullName: string;
4918
+ avatar: null;
4919
+ role: string;
4920
+ emailVerified: boolean;
4921
+ storeId: null;
4922
+ }>;
4905
4923
  /** An identity call, with a 404 from a build without the module said in words. */
4906
4924
  protected account<T>(path: string, req?: Parameters<BaseService['engine']>[1]): Promise<T>;
4907
4925
  }
4908
4926
  /**
4909
- * Password resets and email confirmation. Phone sign-in by one-time code is a
4910
- * Litekart flow; the engine has no such thing and says so.
4927
+ * Password resets, email confirmation, and phone sign-in. A store signs its
4928
+ * customers in one way (D116), read from `loginMethod`; the engine refuses
4929
+ * the other.
4911
4930
  */
4912
4931
  declare class AuthService extends UserService {
4932
+ private readonly facts;
4933
+ /**
4934
+ * How this store signs customers in: `email_password` or `phone_otp`.
4935
+ * A store whose accounts module says nothing signs in by email.
4936
+ */
4937
+ loginMethod(): Promise<'email_password' | 'phone_otp'>;
4913
4938
  forgotPassword({ email }: {
4914
4939
  email: string;
4915
4940
  referrer?: string;
@@ -4956,8 +4981,30 @@ declare class AuthService extends UserService {
4956
4981
  errorCode: string;
4957
4982
  message: string;
4958
4983
  }>;
4959
- getOtp(): Promise<never>;
4960
- verifyOtp(): Promise<never>;
4984
+ /** Texts a 4-digit sign-in code to `phone`, which needs its country code. */
4985
+ getOtp({ phone }: {
4986
+ phone: string;
4987
+ }): Promise<{
4988
+ expiresInMinutes: number;
4989
+ }>;
4990
+ /** Signs in the account on `phone` with the code it was sent, opening one the first time. */
4991
+ verifyOtp({ phone, otp }: {
4992
+ phone: string;
4993
+ otp: string;
4994
+ }): Promise<{
4995
+ id: string;
4996
+ userId: string;
4997
+ email: string;
4998
+ phone: string | null;
4999
+ firstName: string;
5000
+ lastName: string;
5001
+ name: string;
5002
+ fullName: string;
5003
+ avatar: null;
5004
+ role: string;
5005
+ emailVerified: boolean;
5006
+ storeId: null;
5007
+ }>;
4961
5008
  joinAsAdmin(): Promise<never>;
4962
5009
  }
4963
5010
  /** The `/my/profile` form: the same account, read and saved. */
@@ -1286,6 +1286,11 @@ declare class StoreFacts extends BaseService {
1286
1286
  }>;
1287
1287
  /** The store's own name and how a buyer reaches it, as set in its panel. */
1288
1288
  profile(): Promise<StoreProfile>;
1289
+ /** Where the store delivers (D117): its priced zones' countries, or everywhere. */
1290
+ shipsTo(): Promise<{
1291
+ everywhere: boolean;
1292
+ countries: string[];
1293
+ }>;
1289
1294
  checkoutOptions(): Promise<CheckoutOptions>;
1290
1295
  /**
1291
1296
  * The whole tree, flat and depth-first. Past 500 categories the engine
@@ -4901,15 +4906,35 @@ declare class UserService extends BaseService {
4901
4906
  deleteUser(): Promise<never>;
4902
4907
  checkEmail(): Promise<never>;
4903
4908
  joinAsVendor(): Promise<never>;
4904
- private signedIn;
4909
+ protected signedIn(auth: AuthResponse): Promise<{
4910
+ id: string;
4911
+ userId: string;
4912
+ email: string;
4913
+ phone: string | null;
4914
+ firstName: string;
4915
+ lastName: string;
4916
+ name: string;
4917
+ fullName: string;
4918
+ avatar: null;
4919
+ role: string;
4920
+ emailVerified: boolean;
4921
+ storeId: null;
4922
+ }>;
4905
4923
  /** An identity call, with a 404 from a build without the module said in words. */
4906
4924
  protected account<T>(path: string, req?: Parameters<BaseService['engine']>[1]): Promise<T>;
4907
4925
  }
4908
4926
  /**
4909
- * Password resets and email confirmation. Phone sign-in by one-time code is a
4910
- * Litekart flow; the engine has no such thing and says so.
4927
+ * Password resets, email confirmation, and phone sign-in. A store signs its
4928
+ * customers in one way (D116), read from `loginMethod`; the engine refuses
4929
+ * the other.
4911
4930
  */
4912
4931
  declare class AuthService extends UserService {
4932
+ private readonly facts;
4933
+ /**
4934
+ * How this store signs customers in: `email_password` or `phone_otp`.
4935
+ * A store whose accounts module says nothing signs in by email.
4936
+ */
4937
+ loginMethod(): Promise<'email_password' | 'phone_otp'>;
4913
4938
  forgotPassword({ email }: {
4914
4939
  email: string;
4915
4940
  referrer?: string;
@@ -4956,8 +4981,30 @@ declare class AuthService extends UserService {
4956
4981
  errorCode: string;
4957
4982
  message: string;
4958
4983
  }>;
4959
- getOtp(): Promise<never>;
4960
- verifyOtp(): Promise<never>;
4984
+ /** Texts a 4-digit sign-in code to `phone`, which needs its country code. */
4985
+ getOtp({ phone }: {
4986
+ phone: string;
4987
+ }): Promise<{
4988
+ expiresInMinutes: number;
4989
+ }>;
4990
+ /** Signs in the account on `phone` with the code it was sent, opening one the first time. */
4991
+ verifyOtp({ phone, otp }: {
4992
+ phone: string;
4993
+ otp: string;
4994
+ }): Promise<{
4995
+ id: string;
4996
+ userId: string;
4997
+ email: string;
4998
+ phone: string | null;
4999
+ firstName: string;
5000
+ lastName: string;
5001
+ name: string;
5002
+ fullName: string;
5003
+ avatar: null;
5004
+ role: string;
5005
+ emailVerified: boolean;
5006
+ storeId: null;
5007
+ }>;
4961
5008
  joinAsAdmin(): Promise<never>;
4962
5009
  }
4963
5010
  /** The `/my/profile` form: the same account, read and saved. */
package/dist/index.cjs CHANGED
@@ -1032,6 +1032,13 @@ var StoreFacts = class extends BaseService {
1032
1032
  profile() {
1033
1033
  return remember(this.key("profile"), () => this.data("/api/store"));
1034
1034
  }
1035
+ /** Where the store delivers (D117): its priced zones' countries, or everywhere. */
1036
+ shipsTo() {
1037
+ return remember(this.key("ships-to"), async () => {
1038
+ const r = await this.data("/api/checkout/countries");
1039
+ return { everywhere: r?.everywhere ?? true, countries: r?.countries ?? [] };
1040
+ });
1041
+ }
1035
1042
  checkoutOptions() {
1036
1043
  return remember(this.key("checkout"), () => this.data("/api/checkout"));
1037
1044
  }
@@ -2205,6 +2212,19 @@ var UserService = class extends BaseService {
2205
2212
  }
2206
2213
  };
2207
2214
  var AuthService = class extends UserService {
2215
+ facts = new StoreFacts(this._fetch);
2216
+ /**
2217
+ * How this store signs customers in: `email_password` or `phone_otp`.
2218
+ * A store whose accounts module says nothing signs in by email.
2219
+ */
2220
+ async loginMethod() {
2221
+ try {
2222
+ const method = (await this.facts.plugins()).get("identity")?.settings?.login_method;
2223
+ return method === "phone_otp" ? "phone_otp" : "email_password";
2224
+ } catch {
2225
+ return "email_password";
2226
+ }
2227
+ }
2208
2228
  async forgotPassword({ email }) {
2209
2229
  return this.account("/x/identity/password-reset", {
2210
2230
  method: "POST",
@@ -2231,11 +2251,21 @@ var AuthService = class extends UserService {
2231
2251
  return { errorCode: err.code ?? "invalid_token", message: err.message };
2232
2252
  }
2233
2253
  }
2234
- async getOtp() {
2235
- throw new NotSupportedError("AuthService", "getOtp", "sign in with an email and password");
2254
+ /** Texts a 4-digit sign-in code to `phone`, which needs its country code. */
2255
+ async getOtp({ phone }) {
2256
+ const res = await this.account("/x/identity/otp", {
2257
+ method: "POST",
2258
+ body: { phone: String(phone ?? "").trim() }
2259
+ });
2260
+ return { expiresInMinutes: res?.expires_in_minutes ?? 10 };
2236
2261
  }
2237
- async verifyOtp() {
2238
- throw new NotSupportedError("AuthService", "verifyOtp", "sign in with an email and password");
2262
+ /** Signs in the account on `phone` with the code it was sent, opening one the first time. */
2263
+ async verifyOtp({ phone, otp }) {
2264
+ const auth = await this.account("/x/identity/otp/verify", {
2265
+ method: "POST",
2266
+ body: { phone: String(phone ?? "").trim(), code: String(otp ?? "").trim() }
2267
+ });
2268
+ return this.signedIn(auth);
2239
2269
  }
2240
2270
  async joinAsAdmin() {
2241
2271
  throw new NotSupportedError("AuthService", "joinAsAdmin", "operators are invited from the admin panel");
@@ -2553,12 +2583,14 @@ var StoreService = class extends BaseService {
2553
2583
  return super.post(path, data);
2554
2584
  }
2555
2585
  async live() {
2556
- const [ready, plugins, menus, base, profile] = await Promise.all([
2586
+ const [ready, plugins, menus, base, profile, ships] = await Promise.all([
2557
2587
  this.facts.ready(),
2558
2588
  this.facts.plugins().catch(() => /* @__PURE__ */ new Map()),
2559
2589
  new MenuService(this._fetch).engineMenus(),
2560
2590
  readStaticStore(),
2561
- this.facts.profile().catch(() => null)
2591
+ this.facts.profile().catch(() => null),
2592
+ // An engine without the route rules nothing out.
2593
+ this.facts.shipsTo().catch(() => ({ everywhere: true, countries: [] }))
2562
2594
  ]);
2563
2595
  const code = ready.currency;
2564
2596
  const sameCurrency = (base.currency?.code ?? base.currencyCode) === code;
@@ -2587,11 +2619,30 @@ var StoreService = class extends BaseService {
2587
2619
  ...flag(plugins.has("product-reviews"))
2588
2620
  }
2589
2621
  },
2590
- ...menus?.length ? { menu: menus } : {}
2622
+ ...menus?.length ? { menu: menus } : {},
2623
+ ...deliverable(base, ships),
2624
+ // The one way this store signs customers in (D116), which the sign-in
2625
+ // form reads as PHONE or EMAIL. Without the accounts module the static
2626
+ // record says.
2627
+ ...plugins.has("identity") ? { loginType: plugins.get("identity")?.settings?.login_method === "phone_otp" ? "PHONE" : "EMAIL" } : {}
2591
2628
  };
2592
2629
  }
2593
2630
  };
2594
2631
  var storeService = new StoreService();
2632
+ function deliverable(base, ships) {
2633
+ if (ships.everywhere || !ships.countries.length) return {};
2634
+ const known = new Map((base.countries ?? []).map((c) => [String(c.code).toUpperCase(), c]));
2635
+ const countries = ships.countries.map((code) => known.get(code) ?? { code, name: regionName(code) });
2636
+ const keep = base.country && ships.countries.includes(String(base.country.code).toUpperCase());
2637
+ return { countries, ...keep ? {} : { country: countries[0] } };
2638
+ }
2639
+ function regionName(code) {
2640
+ try {
2641
+ return new Intl.DisplayNames(["en"], { type: "region" }).of(code) ?? code;
2642
+ } catch {
2643
+ return code;
2644
+ }
2645
+ }
2595
2646
 
2596
2647
  // src/services/page-service.ts
2597
2648
  var PageService = class extends BaseService {