@thefittingroom/sdk 0.0.5 → 0.0.7

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 ADDED
@@ -0,0 +1,96 @@
1
+ # The Fitting Room - Shop SDK
2
+
3
+ ### Installation
4
+
5
+ ```bash
6
+ npm i @thefittingroom/shop-sdk
7
+ ```
8
+
9
+ or
10
+
11
+ ```bash
12
+ yarn @thefittingroom/shop-sdk
13
+ ```
14
+
15
+ ### Build
16
+
17
+ ```bash
18
+ npm run build
19
+ ```
20
+
21
+ or
22
+
23
+ ```bash
24
+ yarn build
25
+ ```
26
+
27
+ ### Development
28
+
29
+ ```bash
30
+ npm run watch
31
+ ```
32
+
33
+ or
34
+
35
+ ```bash
36
+ yarn watch
37
+ ```
38
+
39
+ ## Usage
40
+
41
+ ```typescript
42
+ import { initShop } from '@thefittingroom/sdk'
43
+
44
+ // Your brandId: Number
45
+ const brandId = 9001
46
+
47
+ // The environment: 'development', 'dev', 'production', 'prod'
48
+ const env = 'dev'
49
+ const shop = initShop(brandId, env)
50
+ ```
51
+
52
+ ### Shop API
53
+
54
+ #### Auth
55
+
56
+ ```typescript
57
+ // Hook used to check authentication, return isLoggedIn Promise<boolean>
58
+ await shop.onInit()
59
+
60
+ // Login user with session
61
+ shop.user.login(username, password)
62
+
63
+ // Logout current user
64
+ shop.user.logout()
65
+
66
+ // Submit telephone number for link to iOS app
67
+ // No spaces and must include country code e.g. +18005551234
68
+ shop.submitTelephoneNumber(tel)
69
+ ```
70
+
71
+ #### Shop
72
+
73
+ ```typescript
74
+ // returns frames: types.TryOnFrames
75
+ shop.tryOn(colorwaySizeAssetSku)
76
+
77
+ // await for the avatar creation
78
+ shop.awaitAvatarCreated()
79
+
80
+ // get recommended sizes for use
81
+ shop.getRecommendedSizes()
82
+
83
+ // get available styles by ids: number[] or skus: string[]
84
+ shop.getStyles(ids, skus)
85
+ ```
86
+
87
+ #### Errors
88
+
89
+ ```typescript
90
+ NoFramesFoundError
91
+ RequestTimeoutError
92
+ UserNotLoggedInError
93
+ NoColorwaySizeAssetsFoundError
94
+ NoStylesFoundError
95
+ RecommendedAvailableSizesError
96
+ ```
@@ -1,6 +1,6 @@
1
1
  import { FirebaseUser } from '../firebase/firebase-user';
2
2
  export declare class Fetcher {
3
- private static endpoint;
3
+ private static get endpoint();
4
4
  private static Fetch;
5
5
  private static getUrl;
6
6
  private static getHeaders;
@@ -1,6 +1,6 @@
1
1
  import * as firebase from 'firebase/app';
2
2
  import * as firebaseAuth from 'firebase/auth';
3
- import { Firestore } from 'firebase/firestore';
3
+ import { DocumentData, Firestore, QuerySnapshot } from 'firebase/firestore';
4
4
  export declare class FirebaseUser {
5
5
  private readonly firestore;
6
6
  private user;
@@ -10,7 +10,8 @@ export declare class FirebaseUser {
10
10
  onInit(): Promise<boolean>;
11
11
  setUser(user: firebaseAuth.User): void;
12
12
  getToken(): Promise<string>;
13
- getUserProfile(): Promise<import("@firebase/firestore").DocumentData>;
13
+ getUserProfile(): Promise<DocumentData>;
14
+ watchUserProfileForChanges(predicate: (data: QuerySnapshot<DocumentData>) => boolean, timeout: number): Promise<DocumentData>;
14
15
  login(username: string, password: string): Promise<void>;
15
16
  logout(): Promise<void>;
16
17
  sendPasswordResetEmail(email: string): Promise<void>;
@@ -5,7 +5,7 @@ export declare class Firebase {
5
5
  readonly firestore: Firestore;
6
6
  constructor();
7
7
  onInit(): Promise<boolean>;
8
- query(collectionName: string, constraint: QueryFieldFilterConstraint): {
8
+ query(collectionName: string, constraint: QueryFieldFilterConstraint, unsubscribeWhenData?: boolean): {
9
9
  promise: Promise<QuerySnapshot<DocumentData>>;
10
10
  unsubscribe: () => void;
11
11
  };
@@ -1 +1,2 @@
1
1
  export declare const asyncTry: <T>(promise: Promise<T>) => Promise<[Error, T] | [Error]>;
2
+ export declare const asyncWait: (ms: number) => Promise<unknown>;
@@ -16,7 +16,7 @@ export declare class Config {
16
16
  url: string;
17
17
  };
18
18
  get config(): {
19
- avatarTimeout: string;
20
- vtoTimeout: string;
19
+ avatarTimeout: number;
20
+ vtoTimeout: number;
21
21
  };
22
22
  }
package/dist/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * thefittingroom v0.0.3 (2023-07-18T18:14:19.719Z)
2
+ * thefittingroom v0.0.7 (2023-07-19T15:29:31.094Z)
3
3
  * Copyright 2022-present, TheFittingRoom, Inc. All rights reserved.
4
4
  */
5
5
  /**
@@ -16350,8 +16350,8 @@ const devKeys = {
16350
16350
  url: "https://tfr.dev.thefittingroom.xyz",
16351
16351
  },
16352
16352
  config: {
16353
- avatarTimeout: "120000",
16354
- vtoTimeout: "120000",
16353
+ avatarTimeout: Number("120000"),
16354
+ vtoTimeout: Number("120000"),
16355
16355
  },
16356
16356
  };
16357
16357
  const prodKeys = {
@@ -16367,8 +16367,8 @@ const prodKeys = {
16367
16367
  url: "https://tfr.p.thefittingroom.xyz",
16368
16368
  },
16369
16369
  config: {
16370
- avatarTimeout: "120000",
16371
- vtoTimeout: "120000",
16370
+ avatarTimeout: Number("120000"),
16371
+ vtoTimeout: Number("120000"),
16372
16372
  },
16373
16373
  };
16374
16374
 
@@ -22809,6 +22809,20 @@ class FirebaseUser {
22809
22809
  const userProfile = await Ol(Aa(this.firestore, 'users', this.id));
22810
22810
  return userProfile.data();
22811
22811
  }
22812
+ watchUserProfileForChanges(predicate, timeout) {
22813
+ let unsub;
22814
+ const q = sl(Ta(this.firestore, 'users'), rl(Eh(), '==', this.id));
22815
+ const cancel = setTimeout(() => unsub(), timeout);
22816
+ return new Promise((resolve) => {
22817
+ unsub = jl(q, (snapshot) => {
22818
+ if (!predicate(snapshot))
22819
+ return;
22820
+ clearTimeout(cancel);
22821
+ unsub();
22822
+ resolve(snapshot.docs[0].data());
22823
+ });
22824
+ });
22825
+ }
22812
22826
  async login(username, password) {
22813
22827
  if (this.auth.currentUser)
22814
22828
  await this.auth.signOut();
@@ -22829,9 +22843,15 @@ class FirebaseUser {
22829
22843
 
22830
22844
  class Firebase {
22831
22845
  constructor() {
22832
- this.promisefyOnSnapshot = (q) => {
22846
+ this.promisefyOnSnapshot = (q, unsubscribeWhenData) => {
22833
22847
  let unsub;
22834
- const promise = new Promise((resolve) => (unsub = jl(q, (snapshot) => resolve(snapshot))));
22848
+ const promise = new Promise((resolve) => {
22849
+ unsub = jl(q, (snapshot) => {
22850
+ resolve(snapshot);
22851
+ if (unsubscribeWhenData)
22852
+ unsub();
22853
+ });
22854
+ });
22835
22855
  return { promise, unsubscribe: () => unsub() };
22836
22856
  };
22837
22857
  const firebaseKeys = Config.getInstance().firebase;
@@ -22842,9 +22862,9 @@ class Firebase {
22842
22862
  onInit() {
22843
22863
  return this.user.onInit();
22844
22864
  }
22845
- query(collectionName, constraint) {
22865
+ query(collectionName, constraint, unsubscribeWhenData = true) {
22846
22866
  const q = sl(Ta(this.firestore, collectionName), constraint);
22847
- return this.promisefyOnSnapshot(q);
22867
+ return this.promisefyOnSnapshot(q, unsubscribeWhenData);
22848
22868
  }
22849
22869
  getDocs(collectionName, constraints) {
22850
22870
  const q = sl(Ta(this.firestore, collectionName), ...constraints);
@@ -22864,7 +22884,7 @@ const getFirebaseError = (e) => {
22864
22884
  const asyncTry = (promise) => promise.then((data) => [null, data]).catch((error) => [error]);
22865
22885
 
22866
22886
  class Fetcher {
22867
- static endpoint() {
22887
+ static get endpoint() {
22868
22888
  const api = Config.getInstance().api;
22869
22889
  return api.url;
22870
22890
  }
@@ -22994,10 +23014,15 @@ class TfrShop {
22994
23014
  const res = await Fetcher.Post(this.user, '/ios-app-link', { phone_number: sanitizedTel }, false);
22995
23015
  console.log(res);
22996
23016
  }
22997
- awaitColorwaySizeAssetFrames(colorwaySizeAssetSKU) {
23017
+ async awaitColorwaySizeAssetFrames(colorwaySizeAssetSKU) {
23018
+ var _a, _b, _c, _d;
22998
23019
  if (!this.isLoggedIn)
22999
23020
  throw new UserNotLoggedInError();
23000
- return this.getColorwaySizeAssetFrames(colorwaySizeAssetSKU);
23021
+ const predicate = (data) => { var _a, _b, _c; return Boolean((_c = (_b = (_a = data.docs[0].data()) === null || _a === void 0 ? void 0 : _a.vto) === null || _b === void 0 ? void 0 : _b[this.brandId]) === null || _c === void 0 ? void 0 : _c[colorwaySizeAssetSKU]); };
23022
+ const userProfile = (await this.user.watchUserProfileForChanges(predicate, TfrShop.vtoTimeout));
23023
+ if (!((_d = (_c = (_b = (_a = userProfile === null || userProfile === void 0 ? void 0 : userProfile.vto) === null || _a === void 0 ? void 0 : _a[this.brandId]) === null || _b === void 0 ? void 0 : _b[colorwaySizeAssetSKU]) === null || _c === void 0 ? void 0 : _c.frames) === null || _d === void 0 ? void 0 : _d.length))
23024
+ throw new NoFramesFoundError();
23025
+ return userProfile.vto[this.brandId][colorwaySizeAssetSKU].frames;
23001
23026
  }
23002
23027
  async requestThenGetColorwaySizeAssetFrames(colorwaySizeAssetSku) {
23003
23028
  var _a, _b;
@@ -23066,6 +23091,8 @@ class TfrShop {
23066
23091
  return frames;
23067
23092
  }
23068
23093
  }
23094
+ TfrShop.avatarTimeout = 120000;
23095
+ TfrShop.vtoTimeout = 120000;
23069
23096
  const initShop = (brandId, env = 'dev') => {
23070
23097
  if (env === 'dev' || env === 'development')
23071
23098
  console.warn('TfrShop is in development mode');