react-native-mosquito-transport 0.0.18 → 0.0.21
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/.jshintignore +4 -0
- package/.jshintrc +16 -0
- package/README.md +75 -1
- package/TODO +10 -1
- package/example/ios/MosquitodbExample.xcodeproj/project.pbxproj +6 -5
- package/example/ios/MosquitodbExample.xcworkspace/contents.xcworkspacedata +10 -0
- package/example/ios/MosquitodbExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/example/ios/MosquitodbExample.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +8 -0
- package/example/ios/MosquitodbExample.xcworkspace/xcuserdata/anthony.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/example/ios/MosquitodbExample.xcworkspace/xcuserdata/anthony.xcuserdatad/WorkspaceSettings.xcsettings +14 -0
- package/ios/Mosquitodb.swift +14 -1
- package/package.json +15 -14
- package/src/helpers/engine_api.js +39 -0
- package/src/helpers/peripherals.js +73 -127
- package/src/helpers/utils.js +48 -19
- package/src/helpers/values.js +8 -47
- package/src/helpers/variables.js +14 -6
- package/src/index.d.ts +103 -43
- package/src/index.js +198 -121
- package/src/products/auth/accessor.js +97 -36
- package/src/products/auth/index.js +151 -82
- package/src/products/database/accessor.js +720 -223
- package/src/products/database/bson.js +16 -0
- package/src/products/database/counter.js +16 -0
- package/src/products/database/index.js +303 -190
- package/src/products/database/types.js +1 -1
- package/src/products/database/validator.js +517 -254
- package/src/products/http_callable/index.js +111 -106
- package/src/products/storage/index.js +97 -88
- package/src/helpers/EngineApi.js +0 -33
package/.jshintignore
ADDED
package/.jshintrc
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"undef": true, // Warns on variables used before declaration
|
|
3
|
+
"esversion": 12,
|
|
4
|
+
"globals": {
|
|
5
|
+
"process": true,
|
|
6
|
+
"clearTimeout": true,
|
|
7
|
+
"setTimeout": true,
|
|
8
|
+
"console": true,
|
|
9
|
+
"Buffer": true,
|
|
10
|
+
"clearInterval": true,
|
|
11
|
+
"setInterval": true,
|
|
12
|
+
"AbortController": true,
|
|
13
|
+
"URLSearchParams": true,
|
|
14
|
+
"URL": true
|
|
15
|
+
}
|
|
16
|
+
}
|
package/README.md
CHANGED
|
@@ -1 +1,75 @@
|
|
|
1
|
-
# react-native-mosquito-transport
|
|
1
|
+
# react-native-mosquito-transport
|
|
2
|
+
|
|
3
|
+
React native javascript sdk for [mosquito-transport](https://github.com/brainbehindx/mosquito-transport).
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm install react-native-mosquito-transport --save
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
or using yarn
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
yarn add react-native-mosquito-transport
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
```js
|
|
20
|
+
import RNMosquitoTransport from "react-native-mosquito-transport";
|
|
21
|
+
|
|
22
|
+
RNMosquitoTransport.initializeCache({
|
|
23
|
+
cachePassword: "****",
|
|
24
|
+
cacheProtocol: "sqlite",
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const mclient = new RNMosquitoTransport({
|
|
28
|
+
projectUrl: "http://localhost:3444",
|
|
29
|
+
accessKey: "SERVER_ACCESS_KEY",
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Additional Documentations
|
|
34
|
+
|
|
35
|
+
- [RNMosquitoTransport Constructor](#RNMosquitoTransportConstructor)
|
|
36
|
+
- [dbName](#dbName)
|
|
37
|
+
- [dbUrl](#dbUrl)
|
|
38
|
+
- [projectUrl](#projectUrl)
|
|
39
|
+
- [disableCache](#disableCache)
|
|
40
|
+
- [accessKey](#accessKey)
|
|
41
|
+
- [maxRetries](#maxRetries)
|
|
42
|
+
- [enableE2E_Encryption](#enableE2E_Encryption)
|
|
43
|
+
- [serverE2E_PublicKey](#serverE2E_PublicKey)
|
|
44
|
+
- [extraHeaders](#extraHeaders)
|
|
45
|
+
- [castBSON](#castBSON)
|
|
46
|
+
- [RNMosquitoTransport Methods](#RNMosquitoTransportMethods)
|
|
47
|
+
- [initialCache](#initialCache)
|
|
48
|
+
- [getDatabase](#getDatabase)
|
|
49
|
+
- [collection](#collection)
|
|
50
|
+
- [auth](#auth)
|
|
51
|
+
- [storage](#storage)
|
|
52
|
+
- [fetchHttp](#fetchHttp)
|
|
53
|
+
- [listenReachableServer](#listenReachableServer)
|
|
54
|
+
- [getSocket](#getSocket)
|
|
55
|
+
- [batchWrite](#batchWrite)
|
|
56
|
+
- [TIMESTAMP](#TIMESTAMP)
|
|
57
|
+
- [AUTH_PROVIDER_ID](#AUTH_PROVIDER_ID)
|
|
58
|
+
- [DOCUMENT_EXTRACTION](#DOCUMENT_EXTRACTION)
|
|
59
|
+
- [GEO_JSON](#GEO_JSON)
|
|
60
|
+
- [FIND_GEO_JSON](#FIND_GEO_JSON)
|
|
61
|
+
- [DoNotEncrypt](#DoNotEncrypt)
|
|
62
|
+
|
|
63
|
+
## RNMosquitoTransport Constructor
|
|
64
|
+
|
|
65
|
+
### dbName
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
### dbUrl
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
### projectUrl
|
|
72
|
+
|
|
73
|
+
this is the base url of
|
|
74
|
+
|
|
75
|
+
### disableCache
|
package/TODO
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
- fix local cache query on sqlite and fs
|
|
2
2
|
- fix and add all mongodb query and update operator
|
|
3
3
|
- reauthenticate
|
|
4
|
-
- change `Object` in d.ts to [key: string]: any
|
|
4
|
+
- change `Object` in d.ts to [key: string]: any
|
|
5
|
+
- add `getServerTimeOffset` method
|
|
6
|
+
- change null to undefined in `value`
|
|
7
|
+
- `provide functionality to add extra header to MT instance (all outgoing request)`
|
|
8
|
+
- borrowToken
|
|
9
|
+
- `add sqlite`
|
|
10
|
+
- minimize extraction data
|
|
11
|
+
- change `collection().onDisconnect()` to `collection().socket().onDisconnect()` and `collection().socket().onConnect()`
|
|
12
|
+
- add `_foreign_doc` to d.ts
|
|
13
|
+
- tree shake dependencies
|
|
@@ -354,7 +354,6 @@
|
|
|
354
354
|
);
|
|
355
355
|
name = "[CP] Copy Pods Resources";
|
|
356
356
|
outputFileListPaths = (
|
|
357
|
-
"${PODS_ROOT}/Target Support Files/Pods-MosquitodbExample/Pods-MosquitodbExample-resources-${CONFIGURATION}-output-files.xcfilelist",
|
|
358
357
|
);
|
|
359
358
|
runOnlyForDeploymentPostprocessing = 0;
|
|
360
359
|
shellPath = /bin/sh;
|
|
@@ -501,7 +500,7 @@
|
|
|
501
500
|
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
|
|
502
501
|
PRODUCT_NAME = MosquitodbExample;
|
|
503
502
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
|
504
|
-
SWIFT_VERSION = 5.
|
|
503
|
+
SWIFT_VERSION = 5.3;
|
|
505
504
|
VERSIONING_SYSTEM = "apple-generic";
|
|
506
505
|
};
|
|
507
506
|
name = Debug;
|
|
@@ -526,7 +525,7 @@
|
|
|
526
525
|
);
|
|
527
526
|
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
|
|
528
527
|
PRODUCT_NAME = MosquitodbExample;
|
|
529
|
-
SWIFT_VERSION = 5.
|
|
528
|
+
SWIFT_VERSION = 5.3;
|
|
530
529
|
VERSIONING_SYSTEM = "apple-generic";
|
|
531
530
|
};
|
|
532
531
|
name = Release;
|
|
@@ -564,7 +563,7 @@
|
|
|
564
563
|
COPY_PHASE_STRIP = NO;
|
|
565
564
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
|
566
565
|
ENABLE_TESTABILITY = YES;
|
|
567
|
-
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" =
|
|
566
|
+
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386;
|
|
568
567
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
|
569
568
|
GCC_DYNAMIC_NO_PIC = NO;
|
|
570
569
|
GCC_NO_COMMON_BLOCKS = YES;
|
|
@@ -598,6 +597,7 @@
|
|
|
598
597
|
"-DFOLLY_MOBILE=1",
|
|
599
598
|
"-DFOLLY_USE_LIBCPP=1",
|
|
600
599
|
);
|
|
600
|
+
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
|
601
601
|
SDKROOT = iphoneos;
|
|
602
602
|
};
|
|
603
603
|
name = Debug;
|
|
@@ -635,7 +635,7 @@
|
|
|
635
635
|
COPY_PHASE_STRIP = YES;
|
|
636
636
|
ENABLE_NS_ASSERTIONS = NO;
|
|
637
637
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
|
638
|
-
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" =
|
|
638
|
+
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386;
|
|
639
639
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
|
640
640
|
GCC_NO_COMMON_BLOCKS = YES;
|
|
641
641
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
|
@@ -661,6 +661,7 @@
|
|
|
661
661
|
"-DFOLLY_MOBILE=1",
|
|
662
662
|
"-DFOLLY_USE_LIBCPP=1",
|
|
663
663
|
);
|
|
664
|
+
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
|
664
665
|
SDKROOT = iphoneos;
|
|
665
666
|
VALIDATE_PRODUCT = YES;
|
|
666
667
|
};
|
|
Binary file
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
+
<plist version="1.0">
|
|
4
|
+
<dict>
|
|
5
|
+
<key>BuildLocationStyle</key>
|
|
6
|
+
<string>UseAppPreferences</string>
|
|
7
|
+
<key>CustomBuildLocationType</key>
|
|
8
|
+
<string>RelativeToDerivedData</string>
|
|
9
|
+
<key>DerivedDataLocationStyle</key>
|
|
10
|
+
<string>Default</string>
|
|
11
|
+
<key>ShowSharedSchemesAutomaticallyEnabled</key>
|
|
12
|
+
<true/>
|
|
13
|
+
</dict>
|
|
14
|
+
</plist>
|
package/ios/Mosquitodb.swift
CHANGED
|
@@ -95,11 +95,18 @@ class MosquitodbUploadTask: NSObject, URLSessionDataDelegate {
|
|
|
95
95
|
|
|
96
96
|
var request = URLRequest(url: URL(string: url)!)
|
|
97
97
|
request.httpMethod = "POST"
|
|
98
|
+
|
|
99
|
+
if let extraHeaders = options["extraHeaders"] as? [[String: String]] {
|
|
100
|
+
for (key, value) in extraHeaders {
|
|
101
|
+
request.setValue(value, forHTTPHeaderField: key)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
98
104
|
request.setValue("application/json", forHTTPHeaderField: "Accept")
|
|
99
105
|
request.setValue(authorization, forHTTPHeaderField: "Authorization")
|
|
100
106
|
if options["authToken"] != nil {
|
|
101
107
|
request.setValue(options["authToken"] as? String, forHTTPHeaderField: "Mosquito-Token")
|
|
102
108
|
}
|
|
109
|
+
request.setValue(options["createHash"] as? String, forHTTPHeaderField: "hash-upload");
|
|
103
110
|
request.setValue("buffer/upload", forHTTPHeaderField: "Content-Type")
|
|
104
111
|
request.setValue(destination, forHTTPHeaderField: "Mosquito-Destination")
|
|
105
112
|
|
|
@@ -187,6 +194,12 @@ class MosquitodbDownloadTask: NSObject, URLSessionDownloadDelegate {
|
|
|
187
194
|
|
|
188
195
|
var request = URLRequest(url: URL(string: url)!)
|
|
189
196
|
request.httpMethod = "POST"
|
|
197
|
+
|
|
198
|
+
if let extraHeaders = options["extraHeaders"] as? [[String: String]] {
|
|
199
|
+
for (key, value) in extraHeaders {
|
|
200
|
+
request.setValue(value, forHTTPHeaderField: key)
|
|
201
|
+
}
|
|
202
|
+
}
|
|
190
203
|
request.setValue(authorization, forHTTPHeaderField: "Authorization")
|
|
191
204
|
if options["authToken"] != nil {
|
|
192
205
|
request.setValue(options["authToken"] as? String, forHTTPHeaderField: "Mosquito-Token")
|
|
@@ -249,7 +262,7 @@ class MosquitodbDownloadTask: NSObject, URLSessionDownloadDelegate {
|
|
|
249
262
|
"result": "{\"file\": \"\(dest)\"}"
|
|
250
263
|
]
|
|
251
264
|
])
|
|
252
|
-
}else{
|
|
265
|
+
} else {
|
|
253
266
|
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
|
|
254
267
|
let urlName = mainOptions["urlName"] as! String
|
|
255
268
|
let destDir = documentsURL.appendingPathComponent("mosquito-transport")
|
package/package.json
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-mosquito-transport",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "React native javascript sdk for mosquito-transport (https://github.com/
|
|
3
|
+
"version": "0.0.21",
|
|
4
|
+
"description": "React native javascript sdk for mosquito-transport (https://github.com/brainbehindx/mosquito-transport)",
|
|
5
5
|
"main": "src/index.js",
|
|
6
|
+
"type": "module",
|
|
6
7
|
"scripts": {
|
|
7
8
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
9
|
},
|
|
9
10
|
"repository": {
|
|
10
11
|
"type": "git",
|
|
11
|
-
"url": "git+https://github.com/
|
|
12
|
+
"url": "git+https://github.com/brainbehindx/react-native-mosquito-transport.git"
|
|
12
13
|
},
|
|
13
14
|
"keywords": [
|
|
14
15
|
"mosquito-transport",
|
|
@@ -22,28 +23,28 @@
|
|
|
22
23
|
"author": "Anthony Onabanjo <deflexable@gmail.com> (https://github.com/deflexable)",
|
|
23
24
|
"license": "MIT",
|
|
24
25
|
"bugs": {
|
|
25
|
-
"url": "https://github.com/
|
|
26
|
+
"url": "https://github.com/brainbehindx/react-native-mosquito-transport/issues"
|
|
26
27
|
},
|
|
27
|
-
"homepage": "https://github.com/
|
|
28
|
+
"homepage": "https://github.com/brainbehindx/react-native-mosquito-transport#readme",
|
|
28
29
|
"dependencies": {
|
|
29
|
-
"@
|
|
30
|
-
"
|
|
30
|
+
"@turf/turf": "^7.1.0",
|
|
31
|
+
"bson": "^6.8.0",
|
|
31
32
|
"buffer": "^6.0.3",
|
|
32
33
|
"crypto-js": "^4.2.0",
|
|
33
|
-
"
|
|
34
|
-
"guard-object": "^1.
|
|
35
|
-
"
|
|
34
|
+
"entity-serializer": "^1.0.2",
|
|
35
|
+
"guard-object": "^1.1.3",
|
|
36
|
+
"lodash.clonedeep": "^4.5.0",
|
|
36
37
|
"lodash.get": "^4.4.2",
|
|
37
|
-
"lodash.isequal": "^4.5.0",
|
|
38
38
|
"lodash.set": "^4.3.2",
|
|
39
39
|
"lodash.unset": "^4.5.2",
|
|
40
40
|
"react-native-get-random-values": "^1.9.0",
|
|
41
|
-
"
|
|
41
|
+
"simplify-error": "^1.0.1",
|
|
42
42
|
"socket.io-client": "^4.6.2",
|
|
43
43
|
"subscription-listener": "^1.1.2",
|
|
44
44
|
"tweetnacl": "^1.0.3"
|
|
45
45
|
},
|
|
46
|
-
"
|
|
47
|
-
"
|
|
46
|
+
"peerDependencies": {
|
|
47
|
+
"react": "*",
|
|
48
|
+
"react-native": "*"
|
|
48
49
|
}
|
|
49
50
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { encodeBinary } from './peripherals';
|
|
2
|
+
|
|
3
|
+
const EngineApiBase = (baseApi, ugly, path) => {
|
|
4
|
+
const url = new URL(baseApi);
|
|
5
|
+
if (ugly) {
|
|
6
|
+
url.pathname = `/e2e/${encodeBinary(path)}`;
|
|
7
|
+
} else url.pathname = path;
|
|
8
|
+
return url.href;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const apis = {
|
|
12
|
+
_readDocument: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_readDocument'),
|
|
13
|
+
_queryCollection: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_queryCollection'),
|
|
14
|
+
_documentCount: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_documentCount'),
|
|
15
|
+
_writeDocument: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_writeDocument'),
|
|
16
|
+
_writeMapDocument: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_writeMapDocument'),
|
|
17
|
+
_customSignin: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_customSignin'),
|
|
18
|
+
_customSignup: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_customSignup'),
|
|
19
|
+
_googleSignin: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_googleSignin'),
|
|
20
|
+
_appleSignin: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_appleSignin'),
|
|
21
|
+
_facebookSignin: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_facebookSignin'),
|
|
22
|
+
_twitterSignin: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_twitterSignin'),
|
|
23
|
+
_githubSignin: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_githubSignin'),
|
|
24
|
+
_signOut: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_signOut'),
|
|
25
|
+
_refreshAuthToken: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_refreshAuthToken'),
|
|
26
|
+
_uploadFile: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_uploadFile'),
|
|
27
|
+
_deleteFile: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_deleteFile'),
|
|
28
|
+
_deleteFolder: (baseApi, ugly) => EngineApiBase(baseApi, ugly, '_deleteFolder'),
|
|
29
|
+
staticStorage: (baseApi) => `${baseApi}/storage`,
|
|
30
|
+
_areYouOk: (baseApi) => `${baseApi}/_areYouOk`,
|
|
31
|
+
// static path
|
|
32
|
+
_listenCollection: (ugly) => ugly ? encodeBinary(apis._listenCollection()) : '_listenCollection',
|
|
33
|
+
_listenDocument: (ugly) => ugly ? encodeBinary(apis._listenDocument()) : '_listenDocument',
|
|
34
|
+
_startDisconnectWriteTask: (ugly) => ugly ? encodeBinary(apis._startDisconnectWriteTask()) : '_startDisconnectWriteTask',
|
|
35
|
+
_cancelDisconnectWriteTask: (ugly) => ugly ? encodeBinary(apis._cancelDisconnectWriteTask()) : '_cancelDisconnectWriteTask',
|
|
36
|
+
_listenUserVerification: (ugly) => ugly ? encodeBinary(apis._listenUserVerification()) : '_listenUserVerification'
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export default { ...apis };
|
|
@@ -3,129 +3,44 @@ import { ServerReachableListener } from "./listeners";
|
|
|
3
3
|
import aes_pkg from 'crypto-js/aes.js';
|
|
4
4
|
import Utf8Encoder from 'crypto-js/enc-utf8.js';
|
|
5
5
|
import naclPkg from 'tweetnacl';
|
|
6
|
+
import getLodash from "lodash.get";
|
|
7
|
+
import { deserialize, serialize } from "entity-serializer";
|
|
6
8
|
|
|
7
9
|
const { encrypt, decrypt } = aes_pkg;
|
|
8
10
|
const { box, randomBytes } = naclPkg;
|
|
9
11
|
|
|
10
|
-
export const simplifyError = (error, message) => ({
|
|
11
|
-
simpleError: { error, message }
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
export const simplifyCaughtError = (e) => e?.simpleError ? e : simplifyError('unexpected_error', `${e}`);
|
|
15
|
-
|
|
16
|
-
export const everyEntrie = (obj, callback) => {
|
|
17
|
-
if (typeof obj !== 'object' || Array.isArray(obj)) return;
|
|
18
|
-
oEntries(obj).forEach(e => {
|
|
19
|
-
callback?.(e);
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export const flatEntries = (obj) => oEntries(obj);
|
|
24
|
-
|
|
25
|
-
export const flatRawEntries = () => oEntries(obj, false);
|
|
26
|
-
|
|
27
|
-
export const oEntries = (obj, includeObj = true) => {
|
|
28
|
-
let o = [];
|
|
29
|
-
|
|
30
|
-
Object.entries(obj).forEach(e => {
|
|
31
|
-
o.push(e);
|
|
32
|
-
if (e[1] && typeof e[1] === 'object' && !Array.isArray(e[1])) {
|
|
33
|
-
o = [...o, ...oEntries(e[1])];
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
return o.filter(v => includeObj || typeof v[1] !== 'object' || Array.isArray(v[1]));
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export const IS_RAW_OBJECT = (e) => e && typeof e === 'object' && !Array.isArray(e) && !(e instanceof Date);
|
|
41
|
-
|
|
42
|
-
export const IS_WHOLE_NUMBER = (v) => typeof v === 'number' && !`${v}`.includes('.');
|
|
43
|
-
|
|
44
|
-
export const IS_DECIMAL_NUMBER = (v) => typeof v === 'number' && `${v}`.includes('.');
|
|
45
|
-
|
|
46
|
-
export const queryEntries = (obj, lastPath = '', exceptions = [], seperator = '.') => {
|
|
47
|
-
let o = [];
|
|
48
|
-
const isArraySeperator = Array.isArray(lastPath);
|
|
49
|
-
|
|
50
|
-
Object.entries(obj).forEach(([key, value]) => {
|
|
51
|
-
if (IS_RAW_OBJECT(value) && !exceptions.includes(key)) {
|
|
52
|
-
o = [
|
|
53
|
-
...o,
|
|
54
|
-
...queryEntries(
|
|
55
|
-
value,
|
|
56
|
-
isArraySeperator ? [...lastPath, key] : `${lastPath}${key}${seperator}`,
|
|
57
|
-
exceptions,
|
|
58
|
-
seperator
|
|
59
|
-
)
|
|
60
|
-
];
|
|
61
|
-
} else o.push(isArraySeperator ? [[...lastPath, key], value] : [`${lastPath}${key}`, value]);
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
return o;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export const objToUniqueString = (obj) => {
|
|
68
|
-
const keys = [],
|
|
69
|
-
values = [];
|
|
70
|
-
|
|
71
|
-
if (Array.isArray(obj)) {
|
|
72
|
-
obj.forEach(e => {
|
|
73
|
-
if (IS_RAW_OBJECT(e)) {
|
|
74
|
-
queryEntries(e).map(([k, v]) => {
|
|
75
|
-
keys.push(k);
|
|
76
|
-
values.push(v);
|
|
77
|
-
});
|
|
78
|
-
} else keys.push(Array.isArray(e) ? JSON.stringify(e) : `${e}`);
|
|
79
|
-
});
|
|
80
|
-
} else if (!IS_RAW_OBJECT(obj))
|
|
81
|
-
return `${obj}`;
|
|
82
|
-
else
|
|
83
|
-
queryEntries(obj).map(([k, v]) => {
|
|
84
|
-
keys.push(k);
|
|
85
|
-
values.push(v);
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
return [
|
|
89
|
-
...keys.sort(),
|
|
90
|
-
...values.map(v => `${Array.isArray(v) ? JSON.stringify(v) : v}`).sort()
|
|
91
|
-
].join(',');
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export const cloneInstance = (v) => {
|
|
95
|
-
if (v && typeof v === 'object') {
|
|
96
|
-
return Array.isArray(v) ? [...v] : { ...v };
|
|
97
|
-
}
|
|
98
|
-
return v;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
12
|
export const listenReachableServer = (callback, projectUrl) => {
|
|
102
13
|
let lastValue;
|
|
103
14
|
return ServerReachableListener.listenTo(projectUrl, t => {
|
|
104
15
|
if (typeof t === 'boolean' && t !== lastValue) callback?.(t);
|
|
105
16
|
}, true);
|
|
106
|
-
}
|
|
17
|
+
};
|
|
107
18
|
|
|
108
19
|
export const prefixStoragePath = (path, prefix = 'file:///') => {
|
|
109
|
-
|
|
20
|
+
let cleanedPath = path.replace(/^[^/]+:\/{1,3}/, '');
|
|
110
21
|
|
|
111
|
-
|
|
22
|
+
// Continuously remove any remaining protocol patterns until none are left
|
|
23
|
+
while (/^[^/]+:\/{1,3}/.test(cleanedPath)) {
|
|
24
|
+
cleanedPath = cleanedPath.replace(/^[^/]+:\/{1,3}/, '');
|
|
25
|
+
}
|
|
112
26
|
|
|
113
|
-
|
|
114
|
-
|
|
27
|
+
// Remove any leading slashes after protocol removal
|
|
28
|
+
cleanedPath = cleanedPath.replace(/^\/+/, '');
|
|
115
29
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
return r === url ? '' : r;
|
|
119
|
-
}
|
|
30
|
+
return `${prefix}${cleanedPath}`;
|
|
31
|
+
};
|
|
120
32
|
|
|
121
33
|
export const niceTry = (promise) => new Promise(async resolve => {
|
|
122
|
-
|
|
123
34
|
try {
|
|
124
35
|
const r = await promise();
|
|
125
36
|
resolve(r);
|
|
126
37
|
} catch (e) { resolve(); }
|
|
127
38
|
});
|
|
128
39
|
|
|
40
|
+
export const normalizeRoute = (route = '') => route.split('').map((v, i, a) =>
|
|
41
|
+
((!i && v === '/') || (i === a.length - 1 && v === '/') || (i && a[i - 1] === '/' && v === '/')) ? '' : v
|
|
42
|
+
).join('');
|
|
43
|
+
|
|
129
44
|
export const shuffleArray = (n) => {
|
|
130
45
|
const array = [...n];
|
|
131
46
|
let currentIndex = array.length, randomIndex;
|
|
@@ -143,56 +58,87 @@ export const shuffleArray = (n) => {
|
|
|
143
58
|
}
|
|
144
59
|
|
|
145
60
|
export function sortArrayByObjectKey(arr = [], key) {
|
|
146
|
-
return arr.
|
|
61
|
+
return arr.sort(function (a, b) {
|
|
147
62
|
const left = getLodash(a, key),
|
|
148
63
|
right = getLodash(b, key);
|
|
149
64
|
|
|
150
65
|
return (left > right) ? 1 : (left < right) ? -1 : 0;
|
|
151
66
|
});
|
|
152
|
-
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export async function niceHash(str) {
|
|
70
|
+
try {
|
|
71
|
+
// Convert the string to a Uint8Array
|
|
72
|
+
const encoder = new TextEncoder();
|
|
73
|
+
const data = encoder.encode(str);
|
|
74
|
+
|
|
75
|
+
// Use the Web Crypto API to compute the hash
|
|
76
|
+
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
|
|
77
|
+
|
|
78
|
+
// Convert the ArrayBuffer to a hex string for readability
|
|
79
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
80
|
+
const hashHex = hashArray.map(byte => byte.toString(16).padStart(2, '0')).join('');
|
|
81
|
+
|
|
82
|
+
// Convert to base64
|
|
83
|
+
return Buffer.from(hashHex, 'hex').toString('base64');
|
|
84
|
+
} catch (_) {
|
|
85
|
+
return str;
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export const sameInstance = (var1, var2) => {
|
|
90
|
+
try {
|
|
91
|
+
return var1.constructor === var2.constructor &&
|
|
92
|
+
Object.getPrototypeOf(var1) === Object.getPrototypeOf(var2)
|
|
93
|
+
} catch (_) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
};
|
|
153
97
|
|
|
154
98
|
export const encryptString = (txt, password, iv) => {
|
|
155
99
|
return encrypt(txt, `${password || ''}${iv || ''}`).toString();
|
|
156
|
-
}
|
|
100
|
+
};
|
|
157
101
|
|
|
158
102
|
export const decryptString = (txt, password, iv) => {
|
|
159
103
|
return decrypt(txt, `${password || ''}${iv || ''}`).toString(Utf8Encoder);
|
|
160
|
-
}
|
|
104
|
+
};
|
|
161
105
|
|
|
162
|
-
export const serializeE2E = (data, auth_token, serverPublicKey) => {
|
|
106
|
+
export const serializeE2E = async (data, auth_token, serverPublicKey) => {
|
|
163
107
|
const pair = box.keyPair(),
|
|
164
|
-
nonce = randomBytes(box.nonceLength)
|
|
165
|
-
pubBase64 = Buffer.from(pair.publicKey).toString('base64'),
|
|
166
|
-
nonceBase64 = Buffer.from(nonce).toString('base64');
|
|
108
|
+
nonce = randomBytes(box.nonceLength);
|
|
167
109
|
|
|
168
110
|
return [
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
111
|
+
serialize([
|
|
112
|
+
pair.publicKey,
|
|
113
|
+
nonce,
|
|
114
|
+
Buffer.from(
|
|
115
|
+
box(
|
|
116
|
+
serialize([
|
|
117
|
+
data,
|
|
118
|
+
auth_token
|
|
119
|
+
]),
|
|
120
|
+
nonce,
|
|
121
|
+
serverPublicKey,
|
|
122
|
+
pair.secretKey
|
|
123
|
+
)
|
|
178
124
|
)
|
|
179
|
-
)
|
|
125
|
+
]),
|
|
180
126
|
[pair.secretKey, pair.publicKey]
|
|
181
127
|
];
|
|
182
|
-
}
|
|
128
|
+
};
|
|
183
129
|
|
|
184
|
-
export const deserializeE2E = (data, serverPublicKey, clientPrivateKey) => {
|
|
185
|
-
const [binaryNonce, binaryData] = data
|
|
130
|
+
export const deserializeE2E = async (data, serverPublicKey, clientPrivateKey) => {
|
|
131
|
+
const [binaryNonce, binaryData] = deserialize(data),
|
|
186
132
|
baseArray = box.open(
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
133
|
+
binaryData,
|
|
134
|
+
binaryNonce,
|
|
135
|
+
serverPublicKey,
|
|
190
136
|
clientPrivateKey
|
|
191
137
|
);
|
|
192
138
|
|
|
193
139
|
if (!baseArray) throw 'Decrypting e2e message failed';
|
|
194
|
-
return
|
|
195
|
-
}
|
|
140
|
+
return deserialize(baseArray);
|
|
141
|
+
};
|
|
196
142
|
|
|
197
143
|
export const encodeBinary = (s) => Buffer.from(s, 'utf8').toString('base64');
|
|
198
144
|
export const decodeBinary = (s) => Buffer.from(s, 'base64').toString('utf8');
|