mosquito-transport-js 0.2.2 → 0.2.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mosquito-transport-js",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "Javascript web sdk for mosquito-transport (https://github.com/deflexable/mosquito-transport)",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -10,7 +10,7 @@
10
10
  },
11
11
  "repository": {
12
12
  "type": "git",
13
- "url": "git+https://github.com/BrainBehindx/mosquito-transport-js.git"
13
+ "url": "git+https://github.com/brainbehindx/mosquito-transport-js.git"
14
14
  },
15
15
  "keywords": [
16
16
  "mosquito-transport",
@@ -25,9 +25,9 @@
25
25
  "author": "Anthony Onabanjo <deflexable@gmail.com> (https://github.com/deflexable)",
26
26
  "license": "MIT",
27
27
  "bugs": {
28
- "url": "https://github.com/BrainBehindx/mosquito-transport-js/issues"
28
+ "url": "https://github.com/brainbehindx/mosquito-transport-js/issues"
29
29
  },
30
- "homepage": "https://github.com/BrainBehindx/mosquito-transport-js#readme",
30
+ "homepage": "https://github.com/brainbehindx/mosquito-transport-js#readme",
31
31
  "dependencies": {
32
32
  "@types/crypto-js": "^4.2.1",
33
33
  "@types/lodash": "^4.14.194",
@@ -37,7 +37,7 @@
37
37
  "lodash": "^4.17.21",
38
38
  "set-large-timeout": "^1.0.1",
39
39
  "socket.io-client": "^4.6.2",
40
- "subscription-listener": "^1.1.1",
40
+ "subscription-listener": "^1.1.2",
41
41
  "tweetnacl": "^1.0.3"
42
42
  },
43
43
  "devDependencies": {
@@ -14,7 +14,6 @@ const apis = {
14
14
  _twitterSignin: (baseApi, ugly) => `${baseApi}/${ugly ? encodeBinary(apis._twitterSignin(baseApi)) : '_twitterSignin'}`,
15
15
  _githubSignin: (baseApi, ugly) => `${baseApi}/${ugly ? encodeBinary(apis._githubSignin(baseApi)) : '_githubSignin'}`,
16
16
  _signOut: (baseApi, ugly) => `${baseApi}/${ugly ? encodeBinary(apis._signOut(baseApi)) : '_signOut'}`,
17
- _invalidateToken: (baseApi, ugly) => `${baseApi}/${ugly ? encodeBinary(apis._invalidateToken(baseApi)) : '_invalidateToken'}`,
18
17
  _refreshAuthToken: (baseApi, ugly) => `${baseApi}/${ugly ? encodeBinary(apis._refreshAuthToken(baseApi)) : '_refreshAuthToken'}`,
19
18
  _downloadFile: (baseApi, ugly) => `${baseApi}/${ugly ? encodeBinary(apis._downloadFile(baseApi)) : '_downloadFile'}`,
20
19
  _uploadFile: (baseApi, ugly) => `${baseApi}/${ugly ? encodeBinary(apis._uploadFile(baseApi)) : '_uploadFile'}`,
@@ -1,13 +1,14 @@
1
1
  import { ServerReachableListener, StoreReadyListener } from "./listeners";
2
2
  import { CACHE_PROTOCOL, CACHE_STORAGE_PATH, DEFAULT_CACHE_PASSWORD } from "./values";
3
3
  import { CacheStore, Scoped } from "./variables";
4
- import { decryptString, encryptString, niceTry, serializeE2E } from "./peripherals";
4
+ import { decryptString, encryptString, serializeE2E } from "./peripherals";
5
5
 
6
6
  export const updateCacheStore = () => {
7
7
  try { window } catch (_) { return; }
8
8
  const {
9
9
  cachePassword = DEFAULT_CACHE_PASSWORD,
10
- cacheProtocol = CACHE_PROTOCOL.LOCAL_STORAGE
10
+ cacheProtocol = CACHE_PROTOCOL.LOCAL_STORAGE,
11
+ io
11
12
  } = Scoped.ReleaseCacheData;
12
13
 
13
14
  clearTimeout(Scoped.cacheStorageReducer);
@@ -18,7 +19,9 @@ export const updateCacheStore = () => {
18
19
  cachePassword
19
20
  );
20
21
 
21
- if (cacheProtocol === CACHE_PROTOCOL.LOCAL_STORAGE) {
22
+ if (io) {
23
+ io.ouput(txt);
24
+ } else if (cacheProtocol === CACHE_PROTOCOL.LOCAL_STORAGE) {
22
25
  window.localStorage.setItem(CACHE_STORAGE_PATH, txt);
23
26
  }
24
27
  }, 500);
@@ -28,17 +31,20 @@ export const releaseCacheStore = async (builder) => {
28
31
  try { window } catch (_) { return; }
29
32
  const {
30
33
  cachePassword = DEFAULT_CACHE_PASSWORD,
31
- cacheProtocol = CACHE_PROTOCOL.LOCAL_STORAGE
34
+ cacheProtocol = CACHE_PROTOCOL.LOCAL_STORAGE,
35
+ io
32
36
  } = builder;
33
37
 
34
38
  let txt;
35
39
 
36
- if (cacheProtocol === CACHE_PROTOCOL.LOCAL_STORAGE) {
40
+ if (io) {
41
+ txt = await io.input();
42
+ } else if (cacheProtocol === CACHE_PROTOCOL.LOCAL_STORAGE) {
37
43
  txt = window.localStorage.getItem(CACHE_STORAGE_PATH);
38
44
  }
39
45
 
40
46
  const j = JSON.parse(decryptString(txt || '', cachePassword, cachePassword) || '{}');
41
-
47
+
42
48
  Object.entries(j).forEach(([k, v]) => {
43
49
  CacheStore[k] = v;
44
50
  });
@@ -37,8 +37,8 @@ export const WRITE_OPS = {
37
37
  $MAX: '$max',
38
38
  $MIN: '$min',
39
39
  $MUL: '$mul',
40
- $RENAME: '$rename'
41
- // $SET_ON_INSERT: '$setOnInsert'
40
+ $RENAME: '$rename',
41
+ $SET_ON_INSERT: '$setOnInsert'
42
42
  };
43
43
  export const WRITE_OPS_LIST = Object.values(WRITE_OPS);
44
44
 
@@ -5,6 +5,7 @@ export const Scoped = {
5
5
  IS_TOKEN_READY: {},
6
6
  InitializedProject: {},
7
7
  ReleaseCacheData: undefined,
8
+ IsStoreReady: false,
8
9
  AuthJWTToken: {},
9
10
  cacheStorageReducer: undefined,
10
11
  TokenRefreshTimer: {},
package/src/index.d.ts CHANGED
@@ -25,9 +25,26 @@ interface mtimestamp { $timestamp: 'now' }
25
25
  export const TIMESTAMP: mtimestamp;
26
26
  export function DOCUMENT_EXTRACTION(path: string): { $dynamicValue: number };
27
27
 
28
+ interface ReleaseCacheOption_IO {
29
+ /**
30
+ * This password will be used to encrypt data stored locally
31
+ */
32
+ cachePassword?: string;
33
+ io: {
34
+ /**
35
+ * feeds mosquito-transport data
36
+ */
37
+ input: () => string;
38
+ /**
39
+ * emits mosquito-transport internal data
40
+ */
41
+ output: (data: string) => void;
42
+ }
43
+ }
44
+
28
45
  interface ReleaseCacheOption {
29
46
  /**
30
- * This password will be used to securely store your data locally
47
+ * This password will be used to encrypt data stored locally
31
48
  */
32
49
  cachePassword?: string;
33
50
  /**
@@ -61,7 +78,7 @@ interface BatchWriteConfig extends WriteConfig {
61
78
 
62
79
  export class MosquitoTransport {
63
80
  constructor(config: MTConfig);
64
- static releaseCache(option?: ReleaseCacheOption): void;
81
+ static releaseCache(option?: ReleaseCacheOption | ReleaseCacheOption_IO): void;
65
82
  getDatabase(dbName?: string, dbUrl?: string): GetDatabase;
66
83
  collection(path: string): MTCollection;
67
84
  auth(): MTAuth;
@@ -273,6 +290,7 @@ interface DocumentFind {
273
290
  $or?: any[];
274
291
  $text?: {
275
292
  $search: string;
293
+ $field: string;
276
294
  $language?: string;
277
295
  $caseSensitive?: boolean;
278
296
  $diacriticSensitive?: boolean;
@@ -302,8 +320,11 @@ interface MTAuth {
302
320
  listenVerifiedStatus: (callback?: (verified?: boolean) => void, onError?: (error?: ErrorResponse) => void) => () => void;
303
321
  listenAuthToken: (callback: (token: string) => void) => () => void;
304
322
  getAuthToken: () => Promise<string>;
305
- listenAuth: (callback: (auth: AuthData) => void) => () => void;
306
- getAuth: () => Promise<AuthData>;
323
+ getRefreshToken: () => Promise<string>;
324
+ getRefreshTokenData: () => Promise<RefreshTokenData>;
325
+ parseToken: () => string;
326
+ listenAuth: (callback: (auth: TokenEventData) => void) => () => void;
327
+ getAuth: () => Promise<TokenEventData>;
307
328
  signOut: () => Promise<void>;
308
329
  forceRefreshToken: () => Promise<string>;
309
330
  }
@@ -324,14 +345,35 @@ interface AuthData {
324
345
  signupMethod: 'google' | 'apple' | 'custom' | 'github' | 'twitter' | 'facebook' | string;
325
346
  currentAuthMethod: 'google' | 'apple' | 'custom' | 'github' | 'twitter' | 'facebook' | string;
326
347
  joinedOn: number;
327
- encryptionKey: string;
328
348
  uid: string;
329
349
  claims: Object;
330
350
  emailVerified: boolean;
351
+ tokenID: string;
352
+ disabled: boolean;
353
+ entityOf: string;
331
354
  profile: {
332
355
  photo: string;
333
356
  name: string;
334
- }
357
+ },
358
+ exp: number;
359
+ aud: string;
360
+ iss: string;
361
+ sub: string;
362
+ }
363
+
364
+ interface RefreshTokenData {
365
+ uid: string;
366
+ tokenID: string;
367
+ isRefreshToken: true;
368
+ }
369
+
370
+ interface TokenEventData extends AuthData {
371
+ tokenManager: TokenManager | null;
372
+ }
373
+
374
+ interface TokenManager {
375
+ refreshToken: string;
376
+ accessToken: string;
335
377
  }
336
378
 
337
379
  declare type Base64String = string;
package/src/index.js CHANGED
@@ -306,8 +306,17 @@ const validateReleaseCacheProp = (prop) => {
306
306
  throw `Invalid value supplied to cachePassword, value must be a string and greater than 0 characters`;
307
307
  } else if (k === 'cacheProtocol') {
308
308
  if (!cacheList.includes(`${v}`)) throw `unknown value supplied to ${k}, expected any of ${cacheList}`;
309
+ } else if (k === 'io') {
310
+ Object.entries(v).forEach(([k, v]) => {
311
+ if (k === 'input' || k === 'output') {
312
+ if (typeof v !== 'function')
313
+ throw `Invalid value supplied to "io.${k}", expected a function but got "${v}"`;
314
+ } else throw `Unexpected property named "io.${k}"`;
315
+ });
309
316
  } else throw `Unexpected property named ${k}`;
310
317
  });
318
+
319
+ if (!prop?.io && !prop?.cacheProtocol) throw 'You need to provide either "io" or "cacheProtocol"';
311
320
  }
312
321
 
313
322
  const validator = {
@@ -2,8 +2,8 @@ import setLargeTimeout from "set-large-timeout";
2
2
  import { doSignOut } from ".";
3
3
  import EngineApi from "../../helpers/EngineApi";
4
4
  import { AuthTokenListener, TokenRefreshListener } from "../../helpers/listeners";
5
- import { decodeBinary, deserializeE2E, listenReachableServer, simplifyCaughtError } from "../../helpers/peripherals";
6
- import { awaitReachableServer, awaitStore, buildFetchInterface, simplifyError, updateCacheStore } from "../../helpers/utils";
5
+ import { decodeBinary, deserializeE2E, listenReachableServer } from "../../helpers/peripherals";
6
+ import { awaitStore, buildFetchInterface, simplifyError, updateCacheStore } from "../../helpers/utils";
7
7
  import { CacheStore, Scoped } from "../../helpers/variables";
8
8
 
9
9
  export const listenToken = (callback, projectUrl) =>
@@ -15,6 +15,7 @@ export const listenToken = (callback, projectUrl) =>
15
15
  export const injectFreshToken = async (config, { token, refreshToken }) => {
16
16
  const { projectUrl } = config;
17
17
 
18
+ await awaitStore();
18
19
  CacheStore.AuthStore[projectUrl] = { token, refreshToken };
19
20
  Scoped.AuthJWTToken[projectUrl] = token;
20
21
  updateCacheStore();
@@ -102,7 +103,6 @@ const refreshToken = (builder, processRef, remainRetries = 7, initialRetries = 7
102
103
  if (isForceRefresh) Scoped.InitiatedForcedToken[projectUrl] = true;
103
104
  updateCacheStore();
104
105
  initTokenRefresher(builder);
105
- invalidateToken(builder, token);
106
106
  } else reject(lostProcess.simpleError);
107
107
  } catch (e) {
108
108
  if (e.simpleError) {
@@ -128,23 +128,4 @@ const refreshToken = (builder, processRef, remainRetries = 7, initialRetries = 7
128
128
  }, projectUrl);
129
129
  }
130
130
  }
131
- });
132
-
133
- export const invalidateToken = async (builder, token) => {
134
- try {
135
- const { projectUrl, accessKey, uglify, serverE2E_PublicKey } = builder;
136
- await awaitReachableServer(projectUrl);
137
-
138
- const [reqBuilder] = buildFetchInterface({
139
- body: { token },
140
- accessKey,
141
- uglify,
142
- serverE2E_PublicKey
143
- });
144
-
145
- const r = await (await fetch(EngineApi._invalidateToken(projectUrl, uglify), reqBuilder)).json();
146
- if (r.simpleError) throw r;
147
- } catch (e) {
148
- throw simplifyCaughtError(e).simpleError;
149
- }
150
- }
131
+ });
@@ -105,6 +105,13 @@ export class MTAuth {
105
105
 
106
106
  listenAuthToken = (callback) => listenToken(callback, this.builder.projectUrl);
107
107
 
108
+ getRefreshToken = async () => {
109
+ await awaitStore();
110
+ return CacheStore.AuthStore[this.builder.projectUrl]?.refreshToken;
111
+ }
112
+
113
+ parseToken = (token) => parseToken(token);
114
+
108
115
  getAuthToken = () => new Promise(resolve => {
109
116
  const l = listenToken(t => {
110
117
  l();
@@ -202,12 +202,19 @@ const evaluateFilter = (data = {}, filter = {}) => {
202
202
  } else logics.push(false);
203
203
  } else if ($ === $TEXT) {
204
204
  if (commandSplit.slice(-1)[0].$ === '$search') {
205
- const { $caseSensitive, $localFields = [], $search } = dataObj.$text;
205
+ const { $caseSensitive, $search, $field } = filter.$text;
206
206
 
207
207
  if (typeof value !== 'string' || typeof $search !== 'string')
208
208
  throw `$search must have a string value`;
209
+ if (!$field) throw '"$field" is required inside "$text" operator when "disableCache=false"';
210
+ const fieldArr = Array.isArray($field) ? $field : [$field];
209
211
 
210
- const searchTxt = $localFields.map(v => getLodash(dataObj, v || '')).map(v =>
212
+ fieldArr.forEach(v => {
213
+ if (typeof v !== 'string' || !v.trim())
214
+ throw `invalid item inside "$field", expected a non-empty string but got "${v}"`;
215
+ });
216
+
217
+ const searchTxt = fieldArr.map(v => getLodash(dataObj, v || '')).map(v =>
211
218
  `${typeof v === 'string' ? v :
212
219
  Array.isArray(v) ? v.map(v => typeof v === 'string' ? v : '').join(' ').trim() : ''}`.trim()
213
220
  ).join(' ').trim();