@thefittingroom/sdk 0.0.6 → 0.0.8

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 CHANGED
@@ -47,7 +47,6 @@ const brandId = 9001
47
47
  // The environment: 'development', 'dev', 'production', 'prod'
48
48
  const env = 'dev'
49
49
  const shop = initShop(brandId, env)
50
- await shop.onInit()
51
50
  ```
52
51
 
53
52
  ### Shop API
@@ -55,6 +54,9 @@ await shop.onInit()
55
54
  #### Auth
56
55
 
57
56
  ```typescript
57
+ // Hook used to check authentication, return isLoggedIn Promise<boolean>
58
+ await shop.onInit()
59
+
58
60
  // Login user with session
59
61
  shop.user.login(username, password)
60
62
 
@@ -10,7 +10,7 @@ export declare class TfrShop {
10
10
  get user(): import("..").FirebaseUser;
11
11
  get isLoggedIn(): boolean;
12
12
  onInit(): Promise<boolean>;
13
- tryOn(colorwaySizeAssetSku: string): Promise<any>;
13
+ tryOn(colorwaySizeAssetSku: string): Promise<types.TryOnFrames>;
14
14
  awaitAvatarCreated(): Promise<boolean>;
15
15
  getRecommendedSizes(brandStyleId: string): Promise<SizeRecommendation>;
16
16
  getStyles(ids: number[], skus: string[]): Promise<Map<number, types.FirestoreStyle>>;
@@ -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
  };
@@ -6,6 +6,9 @@ export interface ErrorOutsideRecommendedSizes {
6
6
  recommended_size_id: number;
7
7
  available_size_ids: number[];
8
8
  }
9
+ export declare class AvatarNotCreatedError extends Error {
10
+ constructor();
11
+ }
9
12
  export declare class NoFramesFoundError extends Error {
10
13
  constructor();
11
14
  }
@@ -26,3 +29,4 @@ export declare class RecommendedAvailableSizesError extends Error {
26
29
  available_sizes: string[];
27
30
  constructor(recommended_size: string, available_sizes: string[]);
28
31
  }
32
+ export declare const AvatarNotCreated = "avatar not created";
package/dist/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * thefittingroom v0.0.6 (2023-07-18T23:18:09.529Z)
2
+ * thefittingroom v0.0.8 (2023-07-19T17:34:22.852Z)
3
3
  * Copyright 2022-present, TheFittingRoom, Inc. All rights reserved.
4
4
  */
5
5
  /**
@@ -22724,6 +22724,12 @@ function getAuth(app = getApp()) {
22724
22724
  }
22725
22725
  registerAuth("Browser" /* ClientPlatform.BROWSER */);
22726
22726
 
22727
+ class AvatarNotCreatedError extends Error {
22728
+ constructor() {
22729
+ super('Avatar not created');
22730
+ this.name = 'AvatarNotCreatedError';
22731
+ }
22732
+ }
22727
22733
  class NoFramesFoundError extends Error {
22728
22734
  constructor() {
22729
22735
  super('no frames found');
@@ -22762,15 +22768,19 @@ class RecommendedAvailableSizesError extends Error {
22762
22768
  this.available_sizes = available_sizes;
22763
22769
  }
22764
22770
  }
22771
+ // Backend responses
22772
+ const AvatarNotCreated = 'avatar not created';
22765
22773
 
22766
22774
  var errors = /*#__PURE__*/Object.freeze({
22767
22775
  __proto__: null,
22776
+ AvatarNotCreatedError: AvatarNotCreatedError,
22768
22777
  NoFramesFoundError: NoFramesFoundError,
22769
22778
  RequestTimeoutError: RequestTimeoutError,
22770
22779
  UserNotLoggedInError: UserNotLoggedInError,
22771
22780
  NoColorwaySizeAssetsFoundError: NoColorwaySizeAssetsFoundError,
22772
22781
  NoStylesFoundError: NoStylesFoundError,
22773
- RecommendedAvailableSizesError: RecommendedAvailableSizesError
22782
+ RecommendedAvailableSizesError: RecommendedAvailableSizesError,
22783
+ AvatarNotCreated: AvatarNotCreated
22774
22784
  });
22775
22785
 
22776
22786
  class FirebaseUser {
@@ -22809,6 +22819,20 @@ class FirebaseUser {
22809
22819
  const userProfile = await Ol(Aa(this.firestore, 'users', this.id));
22810
22820
  return userProfile.data();
22811
22821
  }
22822
+ watchUserProfileForChanges(predicate, timeout) {
22823
+ let unsub;
22824
+ const q = sl(Ta(this.firestore, 'users'), rl(Eh(), '==', this.id));
22825
+ const cancel = setTimeout(() => unsub(), timeout);
22826
+ return new Promise((resolve) => {
22827
+ unsub = jl(q, (snapshot) => {
22828
+ if (!predicate(snapshot))
22829
+ return;
22830
+ clearTimeout(cancel);
22831
+ unsub();
22832
+ resolve(snapshot.docs[0].data());
22833
+ });
22834
+ });
22835
+ }
22812
22836
  async login(username, password) {
22813
22837
  if (this.auth.currentUser)
22814
22838
  await this.auth.signOut();
@@ -22829,9 +22853,15 @@ class FirebaseUser {
22829
22853
 
22830
22854
  class Firebase {
22831
22855
  constructor() {
22832
- this.promisefyOnSnapshot = (q) => {
22856
+ this.promisefyOnSnapshot = (q, unsubscribeWhenData) => {
22833
22857
  let unsub;
22834
- const promise = new Promise((resolve) => (unsub = jl(q, (snapshot) => resolve(snapshot))));
22858
+ const promise = new Promise((resolve) => {
22859
+ unsub = jl(q, (snapshot) => {
22860
+ resolve(snapshot);
22861
+ if (unsubscribeWhenData)
22862
+ unsub();
22863
+ });
22864
+ });
22835
22865
  return { promise, unsubscribe: () => unsub() };
22836
22866
  };
22837
22867
  const firebaseKeys = Config.getInstance().firebase;
@@ -22842,9 +22872,9 @@ class Firebase {
22842
22872
  onInit() {
22843
22873
  return this.user.onInit();
22844
22874
  }
22845
- query(collectionName, constraint) {
22875
+ query(collectionName, constraint, unsubscribeWhenData = true) {
22846
22876
  const q = sl(Ta(this.firestore, collectionName), constraint);
22847
- return this.promisefyOnSnapshot(q);
22877
+ return this.promisefyOnSnapshot(q, unsubscribeWhenData);
22848
22878
  }
22849
22879
  getDocs(collectionName, constraints) {
22850
22880
  const q = sl(Ta(this.firestore, collectionName), ...constraints);
@@ -22862,7 +22892,6 @@ const getFirebaseError = (e) => {
22862
22892
  };
22863
22893
 
22864
22894
  const asyncTry = (promise) => promise.then((data) => [null, data]).catch((error) => [error]);
22865
- const asyncWait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
22866
22895
 
22867
22896
  class Fetcher {
22868
22897
  static get endpoint() {
@@ -22967,9 +22996,16 @@ class TfrShop {
22967
22996
  async getRecommendedSizes(brandStyleId) {
22968
22997
  if (!this.isLoggedIn)
22969
22998
  throw new UserNotLoggedInError();
22970
- const res = await Fetcher.Get(this.user, `/styles/${brandStyleId}/recommendation`);
22971
- const json = await res.json();
22972
- return json;
22999
+ try {
23000
+ const res = await Fetcher.Get(this.user, `/styles/${brandStyleId}/recommendation`);
23001
+ const json = await res.json();
23002
+ return json;
23003
+ }
23004
+ catch (error) {
23005
+ if ((error === null || error === void 0 ? void 0 : error.error) === AvatarNotCreated)
23006
+ throw new AvatarNotCreatedError();
23007
+ throw error;
23008
+ }
22973
23009
  }
22974
23010
  async getStyles(ids, skus) {
22975
23011
  const constraints = [rl('brand_id', '==', this.brandId)];
@@ -22996,17 +23032,14 @@ class TfrShop {
22996
23032
  console.log(res);
22997
23033
  }
22998
23034
  async awaitColorwaySizeAssetFrames(colorwaySizeAssetSKU) {
23035
+ var _a, _b, _c, _d;
22999
23036
  if (!this.isLoggedIn)
23000
23037
  throw new UserNotLoggedInError();
23001
- console.log('polling');
23002
- try {
23003
- const frames = await this.getColorwaySizeAssetFrames(colorwaySizeAssetSKU);
23004
- return frames;
23005
- }
23006
- catch (_a) {
23007
- await asyncWait(1500);
23008
- return this.awaitColorwaySizeAssetFrames(colorwaySizeAssetSKU);
23009
- }
23038
+ 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]); };
23039
+ const userProfile = (await this.user.watchUserProfileForChanges(predicate, TfrShop.vtoTimeout));
23040
+ 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))
23041
+ throw new NoFramesFoundError();
23042
+ return userProfile.vto[this.brandId][colorwaySizeAssetSKU].frames;
23010
23043
  }
23011
23044
  async requestThenGetColorwaySizeAssetFrames(colorwaySizeAssetSku) {
23012
23045
  var _a, _b;
@@ -23018,6 +23051,8 @@ class TfrShop {
23018
23051
  return this.awaitColorwaySizeAssetFrames(colorwaySizeAssetSku);
23019
23052
  }
23020
23053
  catch (error) {
23054
+ if ((error === null || error === void 0 ? void 0 : error.error) === AvatarNotCreated)
23055
+ throw new AvatarNotCreatedError();
23021
23056
  if (!error.recommended_size_id)
23022
23057
  throw new Error(error);
23023
23058
  const errorOutsideRecommended = error;