mosquito-transport-js 0.2.3 → 0.2.5

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/TODO CHANGED
@@ -1,3 +1,4 @@
1
1
  - fix local cache query on sqlite and fs
2
2
  - fix and add all mongodb query and update operator
3
- - reauthenticate
3
+ - reauthenticate
4
+ - change `Object` in d.ts to [key: string]: any
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mosquito-transport-js",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
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",
@@ -33,11 +33,16 @@
33
33
  "@types/lodash": "^4.14.194",
34
34
  "buffer": "^6.0.3",
35
35
  "crypto-js": "^4.2.0",
36
+ "fast-json-stable-stringify": "^2.1.0",
37
+ "guard-object": "^1.0.6",
36
38
  "json-buffer": "^3.0.1",
37
- "lodash": "^4.17.21",
39
+ "lodash.get": "^4.4.2",
40
+ "lodash.isequal": "^4.5.0",
41
+ "lodash.set": "^4.3.2",
42
+ "lodash.unset": "^4.5.2",
38
43
  "set-large-timeout": "^1.0.1",
39
44
  "socket.io-client": "^4.6.2",
40
- "subscription-listener": "^1.1.1",
45
+ "subscription-listener": "^1.1.2",
41
46
  "tweetnacl": "^1.0.3"
42
47
  },
43
48
  "devDependencies": {
@@ -1,7 +1,7 @@
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; }
@@ -20,7 +20,7 @@ export const updateCacheStore = () => {
20
20
  );
21
21
 
22
22
  if (io) {
23
- io.ouput(txt);
23
+ io.output(txt);
24
24
  } else if (cacheProtocol === CACHE_PROTOCOL.LOCAL_STORAGE) {
25
25
  window.localStorage.setItem(CACHE_STORAGE_PATH, txt);
26
26
  }
@@ -63,4 +63,13 @@ export const READ_OPS_LIST = Object.values(READ_OPS);
63
63
 
64
64
  export const Regexs = {
65
65
  LINK: () => /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig
66
- }
66
+ };
67
+
68
+ export const AUTH_PROVIDER_ID = {
69
+ GOOGLE: 'google.com',
70
+ FACEBOOK: 'facebook.com',
71
+ PASSWORD: 'password',
72
+ TWITTER: 'x.com',
73
+ GITHUB: 'github.com',
74
+ APPLE: 'apple.com'
75
+ };
@@ -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,6 +25,43 @@ interface mtimestamp { $timestamp: 'now' }
25
25
  export const TIMESTAMP: mtimestamp;
26
26
  export function DOCUMENT_EXTRACTION(path: string): { $dynamicValue: number };
27
27
 
28
+ type longitude = number;
29
+ type latitude = number;
30
+
31
+ export function GEO_JSON(latitude: latitude, longitude: longitude): {
32
+ type: "Point",
33
+ coordinates: [longitude, latitude],
34
+ };
35
+
36
+ export function FIND_GEO_JSON(coordinates: [latitude, longitude], offSetMeters: number, centerMeters?: number): {
37
+ $near: {
38
+ $geometry: {
39
+ type: "Point",
40
+ coordinates: [longitude, latitude]
41
+ },
42
+ $minDistance: number | 0,
43
+ $maxDistance: number
44
+ }
45
+ };
46
+
47
+ export const AUTH_PROVIDER_ID: auth_provider_id;
48
+
49
+ interface auth_provider_id {
50
+ GOOGLE: 'google.com';
51
+ FACEBOOK: 'facebook.com';
52
+ PASSWORD: 'password';
53
+ TWITTER: 'x.com';
54
+ GITHUB: 'github.com';
55
+ APPLE: 'apple.com';
56
+ }
57
+
58
+ type auth_provider_id_values = auth_provider_id['GOOGLE'] |
59
+ auth_provider_id['FACEBOOK'] |
60
+ auth_provider_id['PASSWORD'] |
61
+ auth_provider_id['GITHUB'] |
62
+ auth_provider_id['TWITTER'] |
63
+ auth_provider_id['APPLE'];
64
+
28
65
  interface ReleaseCacheOption_IO {
29
66
  /**
30
67
  * This password will be used to encrypt data stored locally
@@ -290,6 +327,7 @@ interface DocumentFind {
290
327
  $or?: any[];
291
328
  $text?: {
292
329
  $search: string;
330
+ $field: string;
293
331
  $language?: string;
294
332
  $caseSensitive?: boolean;
295
333
  $diacriticSensitive?: boolean;
@@ -319,8 +357,11 @@ interface MTAuth {
319
357
  listenVerifiedStatus: (callback?: (verified?: boolean) => void, onError?: (error?: ErrorResponse) => void) => () => void;
320
358
  listenAuthToken: (callback: (token: string) => void) => () => void;
321
359
  getAuthToken: () => Promise<string>;
322
- listenAuth: (callback: (auth: AuthData) => void) => () => void;
323
- getAuth: () => Promise<AuthData>;
360
+ getRefreshToken: () => Promise<string>;
361
+ getRefreshTokenData: () => Promise<RefreshTokenData>;
362
+ parseToken: () => string;
363
+ listenAuth: (callback: (auth: TokenEventData) => void) => () => void;
364
+ getAuth: () => Promise<TokenEventData>;
324
365
  signOut: () => Promise<void>;
325
366
  forceRefreshToken: () => Promise<string>;
326
367
  }
@@ -338,17 +379,38 @@ interface SignupResult extends SigninResult {
338
379
  interface AuthData {
339
380
  email?: string;
340
381
  metadata: Object;
341
- signupMethod: 'google' | 'apple' | 'custom' | 'github' | 'twitter' | 'facebook' | string;
342
- currentAuthMethod: 'google' | 'apple' | 'custom' | 'github' | 'twitter' | 'facebook' | string;
382
+ signupMethod: auth_provider_id_values;
383
+ currentAuthMethod: auth_provider_id_values;
343
384
  joinedOn: number;
344
- encryptionKey: string;
345
385
  uid: string;
346
386
  claims: Object;
347
387
  emailVerified: boolean;
388
+ tokenID: string;
389
+ disabled: boolean;
390
+ entityOf: string;
348
391
  profile: {
349
392
  photo: string;
350
393
  name: string;
351
- }
394
+ },
395
+ exp: number;
396
+ aud: string;
397
+ iss: string;
398
+ sub: string;
399
+ }
400
+
401
+ interface RefreshTokenData {
402
+ uid: string;
403
+ tokenID: string;
404
+ isRefreshToken: true;
405
+ }
406
+
407
+ interface TokenEventData extends AuthData {
408
+ tokenManager: TokenManager | null;
409
+ }
410
+
411
+ interface TokenManager {
412
+ refreshToken: string;
413
+ accessToken: string;
352
414
  }
353
415
 
354
416
  declare type Base64String = string;
package/src/index.js CHANGED
@@ -5,12 +5,12 @@ import { MTAuth } from "./products/auth";
5
5
  import { MTCollection, batchWrite } from "./products/database";
6
6
  import { MTStorage } from "./products/storage";
7
7
  import { ServerReachableListener, TokenRefreshListener } from "./helpers/listeners";
8
- import { initTokenRefresher, listenTokenReady, triggerAuthToken } from "./products/auth/accessor";
8
+ import { initTokenRefresher, listenToken, listenTokenReady, parseToken, triggerAuthToken } from "./products/auth/accessor";
9
9
  import { TIMESTAMP, DOCUMENT_EXTRACTION, FIND_GEO_JSON, GEO_JSON } from "./products/database/types";
10
10
  import { mfetch } from "./products/http_callable";
11
11
  import { io } from "socket.io-client";
12
12
  import { validateCollectionPath } from "./products/database/validator";
13
- import { CACHE_PROTOCOL, Regexs } from "./helpers/values";
13
+ import { AUTH_PROVIDER_ID, CACHE_PROTOCOL, Regexs } from "./helpers/values";
14
14
  import { trySendPendingWrite } from "./products/database/accessor";
15
15
  import EngineApi from './helpers/EngineApi';
16
16
  import { parse, stringify } from 'json-buffer';
@@ -47,21 +47,42 @@ export class MosquitoTransport {
47
47
  triggerAuthToken(projectUrl);
48
48
  initTokenRefresher({ ...this.config }, true);
49
49
 
50
- const socket = io(`${this.config.wsPrefix}://${projectUrl.split('://')[1]}`, {
51
- transports: ['websocket', 'polling', 'flashsocket'],
52
- auth: { _m_internal: true, _from_base: true }
53
- });
50
+ const disconnectionGlich = {};
51
+ let socket, lastUid, lastSocketProcess = 0, hasInited;
54
52
 
55
- socket.on('_signal_signout', () => {
56
- this.auth().signOut();
57
- });
53
+ listenToken((token, thisInited) => {
54
+ const user = token && parseToken(token);
58
55
 
59
- socket.on('connect', () => {
60
- ServerReachableListener.dispatch(projectUrl, true);
61
- });
62
- socket.on('disconnect', () => {
63
- ServerReachableListener.dispatch(projectUrl, false);
64
- });
56
+ const thisUid = (user?.uid || null);
57
+ if (lastUid === thisUid && (hasInited || !thisInited)) return;
58
+ if (!hasInited) hasInited = thisInited;
59
+ lastUid = thisUid;
60
+
61
+ if (lastSocketProcess) disconnectionGlich[lastSocketProcess] = true;
62
+ socket.close();
63
+
64
+ const thisProcess = ++lastSocketProcess;
65
+ socket = io(`${this.config.wsPrefix}://${projectUrl.split('://')[1]}`, {
66
+ transports: ['websocket', 'polling', 'flashsocket'],
67
+ auth: {
68
+ _m_internal: true,
69
+ _from_base: true,
70
+ atoken: token
71
+ }
72
+ });
73
+
74
+ socket.on('_signal_signout', () => {
75
+ this.auth().signOut();
76
+ });
77
+
78
+ socket.on('connect', () => {
79
+ ServerReachableListener.dispatch(projectUrl, true);
80
+ });
81
+ socket.on('disconnect', () => {
82
+ if (!disconnectionGlich[thisProcess])
83
+ ServerReachableListener.dispatch(projectUrl, false);
84
+ });
85
+ }, projectUrl);
65
86
 
66
87
  listenReachableServer(c => {
67
88
  Scoped.IS_CONNECTED[projectUrl] = c;
@@ -300,26 +321,23 @@ export class MosquitoTransport {
300
321
  const validateReleaseCacheProp = (prop) => {
301
322
  const cacheList = [...Object.values(CACHE_PROTOCOL)];
302
323
 
303
- if (prop?.io) {
304
- Object.entries(prop).forEach(([k, v]) => {
305
- if (k === 'input' || k === 'output') {
306
- if (typeof v !== 'function')
307
- throw `Invalid value supplied to ${k}, expected a function but got "${v}"`;
308
- } else if (k === 'cachePassword') {
309
- if (typeof v !== 'string' || v.trim().length <= 0)
310
- throw `Invalid value supplied to cachePassword, value must be a string and greater than 0 characters`;
311
- } else throw `Unexpected property named ${k}`;
312
- });
313
- } else {
314
- Object.entries(prop).forEach(([k, v]) => {
315
- if (k === 'cachePassword') {
316
- if (typeof v !== 'string' || v.trim().length <= 0)
317
- throw `Invalid value supplied to cachePassword, value must be a string and greater than 0 characters`;
318
- } else if (k === 'cacheProtocol') {
319
- if (!cacheList.includes(`${v}`)) throw `unknown value supplied to ${k}, expected any of ${cacheList}`;
320
- } else throw `Unexpected property named ${k}`;
321
- });
322
- }
324
+ Object.entries(prop).forEach(([k, v]) => {
325
+ if (k === 'cachePassword') {
326
+ if (typeof v !== 'string' || v.trim().length <= 0)
327
+ throw `Invalid value supplied to cachePassword, value must be a string and greater than 0 characters`;
328
+ } else if (k === 'cacheProtocol') {
329
+ if (!cacheList.includes(`${v}`)) throw `unknown value supplied to ${k}, expected any of ${cacheList}`;
330
+ } else if (k === 'io') {
331
+ Object.entries(v).forEach(([k, v]) => {
332
+ if (k === 'input' || k === 'output') {
333
+ if (typeof v !== 'function')
334
+ throw `Invalid value supplied to "io.${k}", expected a function but got "${v}"`;
335
+ } else throw `Unexpected property named "io.${k}"`;
336
+ });
337
+ } else throw `Unexpected property named ${k}`;
338
+ });
339
+
340
+ if (!prop?.io && !prop?.cacheProtocol) throw 'You need to provide either "io" or "cacheProtocol"';
323
341
  }
324
342
 
325
343
  const validator = {
@@ -382,5 +400,6 @@ export {
382
400
  TIMESTAMP,
383
401
  DOCUMENT_EXTRACTION,
384
402
  FIND_GEO_JSON,
385
- GEO_JSON
403
+ GEO_JSON,
404
+ AUTH_PROVIDER_ID
386
405
  };
@@ -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();
@@ -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();
@@ -112,6 +119,9 @@ export class MTAuth {
112
119
  }, this.builder.projectUrl);
113
120
  });
114
121
 
122
+ /**
123
+ * @type {import('../../index').RNMTAuth['listenAuth']}
124
+ */
115
125
  listenAuth = (callback) => {
116
126
  let lastTrig;
117
127
 
@@ -2,10 +2,10 @@ import { IS_RAW_OBJECT, objToUniqueString, queryEntries, shuffleArray, sortArray
2
2
  import { awaitStore, updateCacheStore } from "../../helpers/utils";
3
3
  import { CacheStore } from "../../helpers/variables";
4
4
  import { confirmFilterDoc } from "./validator";
5
- import getLodash from 'lodash/get';
6
- import setLodash from 'lodash/set';
7
- import unsetLodash from 'lodash/unset';
8
- import isEqual from 'lodash/isEqual';
5
+ import getLodash from 'lodash.get';
6
+ import setLodash from 'lodash.set';
7
+ import unsetLodash from 'lodash.unset';
8
+ import isEqual from 'lodash.isequal';
9
9
  import { DEFAULT_DB_NAME, DEFAULT_DB_URL, DELIVERY, RETRIEVAL, WRITE_OPS, WRITE_OPS_LIST } from "../../helpers/values";
10
10
  import { DatabaseRecordsListener } from "../../helpers/listeners";
11
11
 
@@ -8,7 +8,7 @@ import { addPendingWrites, generateRecordID, getRecord, insertRecord, listenQuer
8
8
  import { validateCollectionPath, validateFilter, validateReadConfig, validateWriteValue } from "./validator";
9
9
  import { awaitRefreshToken, listenToken } from "../auth/accessor";
10
10
  import { DEFAULT_DB_NAME, DEFAULT_DB_URL, DELIVERY, RETRIEVAL } from "../../helpers/values";
11
- import setLodash from 'lodash/set';
11
+ import setLodash from 'lodash.set';
12
12
 
13
13
  export class MTCollection {
14
14
  constructor(config) {
@@ -1,7 +1,7 @@
1
1
  import { IS_DECIMAL_NUMBER, IS_RAW_OBJECT, IS_WHOLE_NUMBER, queryEntries } from "../../helpers/peripherals";
2
2
  import { READ_OPS, READ_OPS_LIST, RETRIEVAL } from "../../helpers/values";
3
- import getLodash from 'lodash/get';
4
- import isEqual from 'lodash/isEqual';
3
+ import getLodash from 'lodash.get';
4
+ import isEqual from 'lodash.isequal';
5
5
 
6
6
  const dirn = ['desc', 'asc', 'ascending', 'descending'];
7
7