react-native-mosquito-transport 0.0.47 → 0.0.48
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 +8 -0
- package/package.json +2 -2
- package/src/index.d.ts +54 -23
- package/src/index.js +5 -2
- package/src/products/auth/accessor.js +1 -1
- package/src/products/auth/index.js +4 -3
- package/src/products/http_callable/index.js +6 -5
- package/src/products/storage/index.js +59 -40
package/TODO
CHANGED
|
@@ -25,3 +25,11 @@
|
|
|
25
25
|
- transform undefined to void instead of null
|
|
26
26
|
- add metadata to provider auth login
|
|
27
27
|
<!-- - error: "refreshToken retry limit exceeded" <--- no need -->
|
|
28
|
+
|
|
29
|
+
- _areYouOk() should timeout max 5000
|
|
30
|
+
- .json() should be parse nicely
|
|
31
|
+
- when server is offline and suddenly comes online, fetchHttp throw some error
|
|
32
|
+
- string to Buffer may be in utf16
|
|
33
|
+
|
|
34
|
+
# changes made
|
|
35
|
+
storage uploadFile method and others
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-mosquito-transport",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.48",
|
|
4
4
|
"description": "React native javascript sdk for mosquito-transport (https://github.com/brainbehindx/mosquito-transport)",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@turf/turf": "^7.2.0",
|
|
31
31
|
"buffer": "^6.0.3",
|
|
32
|
-
"entity-serializer": "^1.0.
|
|
32
|
+
"entity-serializer": "^1.0.4",
|
|
33
33
|
"guard-object": "^1.1.4",
|
|
34
34
|
"poke-object": "^1.0.1",
|
|
35
35
|
"simplify-error": "^1.0.1",
|
package/src/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BSON } from "./vendor/bson";
|
|
2
2
|
|
|
3
|
-
interface RNMTConfig {
|
|
3
|
+
export interface RNMTConfig {
|
|
4
4
|
dbName?: string;
|
|
5
5
|
dbUrl?: string;
|
|
6
6
|
projectUrl: string;
|
|
@@ -38,7 +38,7 @@ interface RNMTConfig {
|
|
|
38
38
|
castBSON?: boolean;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
interface GetDatabase {
|
|
41
|
+
export interface GetDatabase {
|
|
42
42
|
collection: (path: string) => RNMTCollection;
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -98,7 +98,7 @@ type auth_provider_id_values = auth_provider_id['GOOGLE'] |
|
|
|
98
98
|
interface ReleaseCacheOption_IO {
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
interface ReleaseCacheOption {
|
|
101
|
+
export interface ReleaseCacheOption {
|
|
102
102
|
/**
|
|
103
103
|
* fs is used as the default caching mechanism
|
|
104
104
|
*
|
|
@@ -137,7 +137,7 @@ interface ReleaseCacheOption {
|
|
|
137
137
|
promoteCache?: boolean;
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
interface RNMTSocket {
|
|
140
|
+
export interface RNMTSocket {
|
|
141
141
|
timeout: (timeout?: number) => ({
|
|
142
142
|
emitWithAck: (...args: any) => Promise<any>;
|
|
143
143
|
});
|
|
@@ -167,13 +167,18 @@ interface CountConfig {
|
|
|
167
167
|
disableAuth?: boolean;
|
|
168
168
|
}
|
|
169
169
|
|
|
170
|
-
interface FetchHttpResponse extends Response {
|
|
170
|
+
export interface FetchHttpResponse extends Response {
|
|
171
171
|
/**
|
|
172
172
|
* true if this response was from local cache
|
|
173
173
|
*/
|
|
174
174
|
fromCache?: boolean | undefined;
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
+
interface CustomSocketOption extends OveridenProjectUrl {
|
|
178
|
+
disableAuth?: boolean;
|
|
179
|
+
authHandshake?: Object;
|
|
180
|
+
}
|
|
181
|
+
|
|
177
182
|
export default class RNMT {
|
|
178
183
|
constructor(config: RNMTConfig);
|
|
179
184
|
static initializeCache(option?: ReleaseCacheOption): void;
|
|
@@ -183,12 +188,12 @@ export default class RNMT {
|
|
|
183
188
|
storage(): RNMTStorage;
|
|
184
189
|
fetchHttp(endpoint: string, init?: RequestInit, config?: FetchHttpConfig): Promise<FetchHttpResponse>;
|
|
185
190
|
listenReachableServer(callback: (reachable: boolean) => void): () => void;
|
|
186
|
-
getSocket(options
|
|
191
|
+
getSocket(options?: CustomSocketOption): RNMTSocket;
|
|
187
192
|
onConnect: () => CollectionIO;
|
|
188
193
|
batchWrite(map: BatchWriteValue[], config?: BatchWriteConfig): Promise<DocumentWriteResult[] | undefined>;
|
|
189
194
|
}
|
|
190
195
|
|
|
191
|
-
interface RNMTCollection {
|
|
196
|
+
export interface RNMTCollection {
|
|
192
197
|
find: (find?: DocumentFind) => ({
|
|
193
198
|
get: (config?: GetConfig) => Promise<DocumentResult[]>;
|
|
194
199
|
listen: (callback: (snapshot?: DocumentResult[]) => void, onError?: (error?: DocumentError) => void, config?: GetConfig) => void;
|
|
@@ -258,7 +263,7 @@ interface RNMTCollection {
|
|
|
258
263
|
deleteMany: (find?: DocumentFind, config?: WriteConfig) => Promise<DocumentWriteResult>;
|
|
259
264
|
}
|
|
260
265
|
|
|
261
|
-
interface CollectionTaskIO<T> {
|
|
266
|
+
export interface CollectionTaskIO<T> {
|
|
262
267
|
batchWrite(map: BatchWriteValue[], config?: BatchWriteConfig): T;
|
|
263
268
|
}
|
|
264
269
|
|
|
@@ -270,7 +275,7 @@ interface OnConnectChain extends StartStop {
|
|
|
270
275
|
onDisconnect: () => CollectionTaskIO<StartStop>;
|
|
271
276
|
}
|
|
272
277
|
|
|
273
|
-
interface CollectionIO extends CollectionTaskIO<OnConnectChain> {
|
|
278
|
+
export interface CollectionIO extends CollectionTaskIO<OnConnectChain> {
|
|
274
279
|
onDisconnect: () => CollectionTaskIO<StartStop>;
|
|
275
280
|
}
|
|
276
281
|
|
|
@@ -282,7 +287,7 @@ interface DocumentError extends ErrorResponse {
|
|
|
282
287
|
|
|
283
288
|
}
|
|
284
289
|
|
|
285
|
-
interface FetchHttpConfig {
|
|
290
|
+
export interface FetchHttpConfig {
|
|
286
291
|
retrieval?: GetConfig['retrieval'];
|
|
287
292
|
/**
|
|
288
293
|
* disable sending authentication token along with this request
|
|
@@ -429,7 +434,7 @@ interface DocumentWriteValue {
|
|
|
429
434
|
|
|
430
435
|
}
|
|
431
436
|
|
|
432
|
-
interface RNMTAuth {
|
|
437
|
+
export interface RNMTAuth {
|
|
433
438
|
customSignin: (email: string, password: string) => Promise<SigninResult>;
|
|
434
439
|
customSignup: (email: string, password: string, name?: string, metadata?: Object) => Promise<SignupResult>;
|
|
435
440
|
/**
|
|
@@ -465,7 +470,7 @@ export interface SignupResult extends SigninResult {
|
|
|
465
470
|
isNewUser: boolean;
|
|
466
471
|
}
|
|
467
472
|
|
|
468
|
-
interface AuthData {
|
|
473
|
+
export interface AuthData {
|
|
469
474
|
email?: string;
|
|
470
475
|
metadata: Object;
|
|
471
476
|
signupMethod: auth_provider_id_values;
|
|
@@ -473,7 +478,8 @@ interface AuthData {
|
|
|
473
478
|
joinedOn: number;
|
|
474
479
|
uid: string;
|
|
475
480
|
claims: Object;
|
|
476
|
-
|
|
481
|
+
authVerified: boolean;
|
|
482
|
+
passwordVerified?: boolean | undefined;
|
|
477
483
|
tokenID: string;
|
|
478
484
|
disabled: boolean;
|
|
479
485
|
entityOf: string;
|
|
@@ -487,7 +493,7 @@ interface AuthData {
|
|
|
487
493
|
sub: string;
|
|
488
494
|
}
|
|
489
495
|
|
|
490
|
-
interface RefreshTokenData {
|
|
496
|
+
export interface RefreshTokenData {
|
|
491
497
|
uid: string;
|
|
492
498
|
tokenID: string;
|
|
493
499
|
isRefreshToken: true;
|
|
@@ -497,24 +503,37 @@ interface RefreshTokenData {
|
|
|
497
503
|
sub: string;
|
|
498
504
|
}
|
|
499
505
|
|
|
500
|
-
interface TokenEventData extends AuthData {
|
|
506
|
+
export interface TokenEventData extends AuthData {
|
|
501
507
|
tokenManager: TokenManager;
|
|
502
508
|
}
|
|
503
509
|
|
|
504
|
-
interface TokenManager {
|
|
510
|
+
export interface TokenManager {
|
|
505
511
|
refreshToken: string;
|
|
506
512
|
accessToken: string;
|
|
507
513
|
}
|
|
508
514
|
|
|
509
|
-
interface
|
|
515
|
+
interface OveridenProjectUrl {
|
|
516
|
+
/**
|
|
517
|
+
* The server instance to send requests to. This overrides the parent `projectUrl`, but still relies on the parent `projectUrl` for authentication token resolution and verify server reachability.
|
|
518
|
+
*/
|
|
519
|
+
projectUrl?: string;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
interface UploadOptions extends OveridenProjectUrl {
|
|
510
523
|
/**
|
|
511
524
|
* optionally create hash for this upload to save disk space
|
|
512
525
|
*/
|
|
513
526
|
createHash?: boolean;
|
|
527
|
+
|
|
514
528
|
/**
|
|
515
529
|
* wait for a reachable server before initiating the upload task
|
|
516
530
|
*/
|
|
517
531
|
awaitServer?: boolean;
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* monitor upload progress stats
|
|
535
|
+
*/
|
|
536
|
+
onProgress?: (stats: UploadProgressStats) => void;
|
|
518
537
|
}
|
|
519
538
|
|
|
520
539
|
interface DownloadOptions {
|
|
@@ -522,16 +541,28 @@ interface DownloadOptions {
|
|
|
522
541
|
* wait for a reachable server before initiating the download task
|
|
523
542
|
*/
|
|
524
543
|
awaitServer?: boolean;
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* monitor download progress stats
|
|
547
|
+
*/
|
|
548
|
+
onProgress?: (stats: DownloadProgressStats) => void;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
interface StorageTask extends Promise<string> {
|
|
552
|
+
/**
|
|
553
|
+
* abort the running task process
|
|
554
|
+
*/
|
|
555
|
+
abort: () => void;
|
|
525
556
|
}
|
|
526
557
|
|
|
527
|
-
interface RNMTStorage {
|
|
528
|
-
downloadFile: (link: string,
|
|
529
|
-
uploadFile: (
|
|
530
|
-
deleteFile: (path: string) => Promise<void>;
|
|
531
|
-
deleteFolder: (folder: string) => Promise<void>;
|
|
558
|
+
export interface RNMTStorage {
|
|
559
|
+
downloadFile: (link: string, filepath?: string | undefined, options?: DownloadOptions | undefined) => StorageTask;
|
|
560
|
+
uploadFile: (filepath: string, destination: string, options?: UploadOptions | undefined) => StorageTask;
|
|
561
|
+
deleteFile: (path: string, options?: OveridenProjectUrl | undefined) => Promise<void>;
|
|
562
|
+
deleteFolder: (folder: string, options?: OveridenProjectUrl | undefined) => Promise<void>;
|
|
532
563
|
}
|
|
533
564
|
|
|
534
|
-
interface DownloadProgressStats {
|
|
565
|
+
export interface DownloadProgressStats {
|
|
535
566
|
receivedBtyes: number;
|
|
536
567
|
expectedBytes: number;
|
|
537
568
|
isPaused: boolean;
|
package/src/index.js
CHANGED
|
@@ -165,7 +165,7 @@ class RNMT {
|
|
|
165
165
|
listenReachableServer = (callback) => listenReachableServer(callback, this.config.projectUrl);
|
|
166
166
|
|
|
167
167
|
getSocket = (configOpts) => {
|
|
168
|
-
const { disableAuth, authHandshake } = configOpts || {};
|
|
168
|
+
const { disableAuth, authHandshake, projectUrl: overidenUrl } = configOpts || {};
|
|
169
169
|
const { projectUrl, uglify, serverE2E_PublicKey, wsPrefix, extraHeaders } = this.config;
|
|
170
170
|
|
|
171
171
|
const restrictedRoute = [
|
|
@@ -278,7 +278,10 @@ class RNMT {
|
|
|
278
278
|
const mtoken = disableAuth ? undefined : Scoped.AuthJWTToken[projectUrl];
|
|
279
279
|
const [reqBuilder, [privateKey]] = uglify ? await serializeE2E({ a_extras: authHandshake }, mtoken, serverE2E_PublicKey) : [null, []];
|
|
280
280
|
|
|
281
|
-
|
|
281
|
+
const getWsPrefix = url => url.startsWith('https') ? 'wss' : 'ws';
|
|
282
|
+
const wsUrl = overidenUrl ? `${getWsPrefix(overidenUrl)}://${overidenUrl.split('://')[1]}` : `${wsPrefix}://${projectUrl.split('://')[1]}`;
|
|
283
|
+
|
|
284
|
+
socket = io(wsUrl, {
|
|
282
285
|
transports: ['websocket', 'polling', 'flashsocket'],
|
|
283
286
|
extraHeaders,
|
|
284
287
|
auth: uglify ? {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { doSignOut, revokeAuthIntance } from ".";
|
|
1
|
+
import { doSignOut, revokeAuthIntance } from "./index.js";
|
|
2
2
|
import EngineApi from "../../helpers/engine_api";
|
|
3
3
|
import { AuthTokenListener, TokenRefreshListener } from "../../helpers/listeners";
|
|
4
4
|
import { decodeBinary, deserializeE2E, listenReachableServer } from "../../helpers/peripherals";
|
|
@@ -254,11 +254,13 @@ const clearCacheForSignout = (builder, disposeEmulated) => {
|
|
|
254
254
|
export const doSignOut = async (builder) => {
|
|
255
255
|
if (!Scoped.IsStoreReady) await awaitStore();
|
|
256
256
|
const emulatedURL = CacheStore.EmulatedAuth[builder.projectUrl];
|
|
257
|
+
const thisAuthStore = emulatedURL ? undefined : basicClone(CacheStore.AuthStore[builder.projectUrl]);
|
|
257
258
|
|
|
258
259
|
clearCacheForSignout(builder, !emulatedURL);
|
|
259
260
|
updateCacheStore(['AuthStore', 'EmulatedAuth']);
|
|
260
261
|
if (emulatedURL) return;
|
|
261
|
-
|
|
262
|
+
|
|
263
|
+
await revokeAuthIntance(builder, thisAuthStore);
|
|
262
264
|
};
|
|
263
265
|
|
|
264
266
|
export const revokeAuthIntance = async (builder, authStore) => {
|
|
@@ -288,8 +290,7 @@ export const purgePendingToken = async (nodeId) => {
|
|
|
288
290
|
isConnected = (await (await fetch(_areYouOk(projectUrl), { credentials: 'omit' })).json()).status === 'yes';
|
|
289
291
|
} catch (_) { }
|
|
290
292
|
|
|
291
|
-
if (!isConnected)
|
|
292
|
-
await awaitReachableServer(projectUrl);
|
|
293
|
+
if (!isConnected) await awaitReachableServer(projectUrl);
|
|
293
294
|
|
|
294
295
|
const [reqBuilder] = await buildFetchInterface({
|
|
295
296
|
body: { token, r_token },
|
|
@@ -3,7 +3,7 @@ import { deserializeE2E, listenReachableServer, niceHash, normalizeRoute, serial
|
|
|
3
3
|
import { awaitStore, getReachableServer } from "../../helpers/utils";
|
|
4
4
|
import { RETRIEVAL } from "../../helpers/values";
|
|
5
5
|
import { Scoped } from "../../helpers/variables";
|
|
6
|
-
import { awaitRefreshToken } from "../auth/accessor";
|
|
6
|
+
import { awaitRefreshToken, parseToken } from "../auth/accessor";
|
|
7
7
|
import { simplifyCaughtError } from "simplify-error";
|
|
8
8
|
import { guardObject, Validator } from "guard-object";
|
|
9
9
|
import { serialize } from "entity-serializer";
|
|
@@ -71,17 +71,18 @@ export const mfetch = async (input = '', init, config) => {
|
|
|
71
71
|
) throw `"body" must be any of string, buffer, object`;
|
|
72
72
|
}
|
|
73
73
|
await awaitStore();
|
|
74
|
+
const thisToken = disableAuth ? '' : (Scoped.AuthJWTToken[projectUrl] || '');
|
|
74
75
|
|
|
75
76
|
const reqId = await niceHash(
|
|
76
77
|
serialize([
|
|
77
78
|
rawHeader,
|
|
78
79
|
body,
|
|
79
|
-
!!disableAuth,
|
|
80
|
+
// !!disableAuth,
|
|
80
81
|
input,
|
|
81
|
-
|
|
82
|
+
thisToken && await parseToken(thisToken).uid
|
|
82
83
|
]).toString('base64')
|
|
83
84
|
);
|
|
84
|
-
const processReqId = `${reqId}_${disableCache}_${retrieval}`;
|
|
85
|
+
const processReqId = `${reqId}_${thisToken}_${disableCache}_${retrieval}`;
|
|
85
86
|
|
|
86
87
|
let retries = 0, hasFinalize;
|
|
87
88
|
|
|
@@ -143,7 +144,7 @@ export const mfetch = async (input = '', init, config) => {
|
|
|
143
144
|
const [reqBuilder, [privateKey]] = uglified ? await serializeE2E(body, mtoken, serverE2E_PublicKey) : [null, []];
|
|
144
145
|
|
|
145
146
|
const f = await fetch(isLink ? input : `${projectUrl}/${normalizeRoute(input)}`, {
|
|
146
|
-
...(
|
|
147
|
+
...(hasBody || uglified) ? { method: 'POST' } : {},
|
|
147
148
|
credentials: 'omit',
|
|
148
149
|
...init,
|
|
149
150
|
...uglified ? { body: reqBuilder } : encodeBody ? { body: serialize(body) } : {},
|
|
@@ -5,6 +5,7 @@ import { DeviceEventEmitter, NativeEventEmitter, NativeModules, Platform } from
|
|
|
5
5
|
import { awaitReachableServer, buildFetchInterface, buildFetchResult } from "../../helpers/utils";
|
|
6
6
|
import { awaitRefreshToken } from "../auth/accessor";
|
|
7
7
|
import { simplifyError } from "simplify-error";
|
|
8
|
+
import { Validator } from "guard-object";
|
|
8
9
|
|
|
9
10
|
const LINKING_ERROR =
|
|
10
11
|
`The package 'react-native-mosquito-transport' doesn't seem to be linked. Make sure: \n\n` +
|
|
@@ -19,6 +20,7 @@ const RNMTModule = NativeModules.Mosquitodb || (
|
|
|
19
20
|
},
|
|
20
21
|
})
|
|
21
22
|
);
|
|
23
|
+
|
|
22
24
|
const emitter = Platform.OS === 'android' ?
|
|
23
25
|
DeviceEventEmitter : new NativeEventEmitter(RNMTModule);
|
|
24
26
|
|
|
@@ -27,26 +29,43 @@ export class MTStorage {
|
|
|
27
29
|
this.builder = { ...config };
|
|
28
30
|
}
|
|
29
31
|
|
|
30
|
-
downloadFile(link = '',
|
|
31
|
-
const { awaitServer } = options || {};
|
|
32
|
+
downloadFile = (link = '', destination, options) => {
|
|
33
|
+
const { awaitServer, onProgress } = options || {};
|
|
32
34
|
let hasFinished, isPaused, hasCancelled;
|
|
33
35
|
|
|
34
36
|
const { projectUrl, extraHeaders } = this.builder;
|
|
37
|
+
let onComplete;
|
|
38
|
+
|
|
39
|
+
const promise = new Promise((resolve, reject) => {
|
|
40
|
+
onComplete = (err, path) => {
|
|
41
|
+
if (hasFinished) return;
|
|
42
|
+
hasFinished = true;
|
|
43
|
+
if (path) {
|
|
44
|
+
resolve(path);
|
|
45
|
+
} else reject(err);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
promise.abort = () => {
|
|
50
|
+
if (hasFinished || hasCancelled) return;
|
|
51
|
+
RNMTModule.cancelDownload(processID);
|
|
52
|
+
hasCancelled = true;
|
|
53
|
+
onComplete?.({ error: 'download_aborted', message: 'The download process was aborted' });
|
|
54
|
+
}
|
|
35
55
|
|
|
36
56
|
if (destination && (typeof destination !== 'string' || !destination.trim())) {
|
|
37
57
|
onComplete?.({ error: 'destination_invalid', message: 'destination must be a non-empty string' });
|
|
38
|
-
return
|
|
58
|
+
return promise;
|
|
39
59
|
}
|
|
40
60
|
if (destination) destination = prefixStoragePath(destination?.trim());
|
|
41
61
|
|
|
42
|
-
if (typeof link !== 'string' || !link.trim()
|
|
62
|
+
if (typeof link !== 'string' || !Validator.LINK(link = link.trim())) {
|
|
43
63
|
onComplete?.({
|
|
44
64
|
error: 'invalid_link',
|
|
45
|
-
message: `
|
|
65
|
+
message: `downloadFile first argument has an invalid value, expected a valid link string but got '${link}' instead`
|
|
46
66
|
});
|
|
47
|
-
return
|
|
67
|
+
return promise;
|
|
48
68
|
}
|
|
49
|
-
link = link.trim();
|
|
50
69
|
|
|
51
70
|
const processID = `${++Scoped.StorageProcessID}`;
|
|
52
71
|
const init = async () => {
|
|
@@ -86,7 +105,6 @@ export class MTStorage {
|
|
|
86
105
|
onComplete?.(path ? undefined : (result?.simpleError || { error, message: errorDes }), path);
|
|
87
106
|
resultListener.remove();
|
|
88
107
|
progressListener.remove();
|
|
89
|
-
hasFinished = true;
|
|
90
108
|
});
|
|
91
109
|
|
|
92
110
|
RNMTModule.downloadFile({
|
|
@@ -103,30 +121,36 @@ export class MTStorage {
|
|
|
103
121
|
}
|
|
104
122
|
|
|
105
123
|
init();
|
|
106
|
-
|
|
107
|
-
return () => {
|
|
108
|
-
if (hasFinished || hasCancelled) return;
|
|
109
|
-
RNMTModule.cancelDownload(processID);
|
|
110
|
-
hasCancelled = true;
|
|
111
|
-
setTimeout(() => {
|
|
112
|
-
onComplete?.({ error: 'download_aborted', message: 'The download process was aborted' });
|
|
113
|
-
}, 1);
|
|
114
|
-
}
|
|
124
|
+
return promise;
|
|
115
125
|
}
|
|
116
126
|
|
|
117
|
-
uploadFile(file = '', destination = '',
|
|
118
|
-
const { createHash, awaitServer } = options || {};
|
|
127
|
+
uploadFile = (file = '', destination = '', options) => {
|
|
128
|
+
const { createHash, awaitServer, onProgress } = options || {};
|
|
119
129
|
let hasFinished, hasCancelled;
|
|
130
|
+
let thisComplete;
|
|
120
131
|
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
132
|
+
const promise = new Promise((resolve, reject) => {
|
|
133
|
+
thisComplete = (err, url) => {
|
|
134
|
+
if (hasFinished) return;
|
|
135
|
+
hasFinished = true;
|
|
136
|
+
if (url) {
|
|
137
|
+
resolve(url);
|
|
138
|
+
} else reject(err);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
promise.abort = () => {
|
|
143
|
+
if (hasFinished || hasCancelled) return;
|
|
144
|
+
hasCancelled = true;
|
|
145
|
+
setTimeout(() => {
|
|
146
|
+
thisComplete?.({ error: 'upload_aborted', message: 'The upload process was aborted' });
|
|
147
|
+
}, 0);
|
|
148
|
+
RNMTModule.cancelUpload(processID);
|
|
149
|
+
};
|
|
126
150
|
|
|
127
151
|
if (typeof file !== 'string' || !file.trim()) {
|
|
128
152
|
thisComplete?.({ error: 'file_path_invalid', message: 'file must be a non-empty string in uploadFile()' });
|
|
129
|
-
return
|
|
153
|
+
return promise;
|
|
130
154
|
}
|
|
131
155
|
destination = destination?.trim?.();
|
|
132
156
|
|
|
@@ -134,7 +158,7 @@ export class MTStorage {
|
|
|
134
158
|
validateDestination(destination);
|
|
135
159
|
} catch (error) {
|
|
136
160
|
thisComplete?.({ error: 'destination_invalid', message: error });
|
|
137
|
-
return
|
|
161
|
+
return promise;
|
|
138
162
|
}
|
|
139
163
|
|
|
140
164
|
const isAsset = file.startsWith('ph://') || file.startsWith('content://');
|
|
@@ -142,6 +166,7 @@ export class MTStorage {
|
|
|
142
166
|
|
|
143
167
|
const { projectUrl, uglify, extraHeaders } = this.builder;
|
|
144
168
|
const processID = `${++Scoped.StorageProcessID}`;
|
|
169
|
+
const thisProjectUrl = options?.projectUrl || projectUrl;
|
|
145
170
|
|
|
146
171
|
const init = async () => {
|
|
147
172
|
if (awaitServer) await awaitReachableServer(projectUrl);
|
|
@@ -167,7 +192,7 @@ export class MTStorage {
|
|
|
167
192
|
const authToken = Scoped.AuthJWTToken[projectUrl];
|
|
168
193
|
|
|
169
194
|
RNMTModule.uploadFile({
|
|
170
|
-
url: EngineApi._uploadFile(
|
|
195
|
+
url: EngineApi._uploadFile(thisProjectUrl, uglify),
|
|
171
196
|
file: isAsset ? file : file.substring('file://'.length),
|
|
172
197
|
...authToken ? { authToken } : {},
|
|
173
198
|
createHash: createHash ? 'yes' : 'no',
|
|
@@ -178,24 +203,16 @@ export class MTStorage {
|
|
|
178
203
|
}
|
|
179
204
|
|
|
180
205
|
init();
|
|
181
|
-
|
|
182
|
-
return () => {
|
|
183
|
-
if (hasFinished || hasCancelled) return;
|
|
184
|
-
hasCancelled = true;
|
|
185
|
-
setTimeout(() => {
|
|
186
|
-
thisComplete?.({ error: 'upload_aborted', message: 'The upload process was aborted' });
|
|
187
|
-
}, 0);
|
|
188
|
-
RNMTModule.cancelUpload(processID);
|
|
189
|
-
}
|
|
206
|
+
return promise;
|
|
190
207
|
}
|
|
191
208
|
|
|
192
|
-
deleteFile = (path) => deleteContent(this.builder, path);
|
|
193
|
-
deleteFolder = (path) => deleteContent(this.builder, path, true);
|
|
209
|
+
deleteFile = (path, options) => deleteContent(this.builder, path, options);
|
|
210
|
+
deleteFolder = (path, options) => deleteContent(this.builder, path, options, true);
|
|
194
211
|
}
|
|
195
212
|
|
|
196
213
|
const { _deleteFile, _deleteFolder } = EngineApi;
|
|
197
214
|
|
|
198
|
-
const deleteContent = async (builder, path, isFolder) => {
|
|
215
|
+
const deleteContent = async (builder, path, options, isFolder) => {
|
|
199
216
|
const { projectUrl, uglify, extraHeaders, serverE2E_PublicKey } = builder;
|
|
200
217
|
|
|
201
218
|
try {
|
|
@@ -207,8 +224,10 @@ const deleteContent = async (builder, path, isFolder) => {
|
|
|
207
224
|
serverE2E_PublicKey,
|
|
208
225
|
uglify
|
|
209
226
|
});
|
|
227
|
+
const thisProjectUrl = options?.projectUrl || projectUrl;
|
|
210
228
|
|
|
211
|
-
const
|
|
229
|
+
const res = await fetch((isFolder ? _deleteFolder : _deleteFile)(thisProjectUrl, uglify), reqBuilder);
|
|
230
|
+
const data = await buildFetchResult(res, uglify);
|
|
212
231
|
const result = uglify ? await deserializeE2E(data, serverE2E_PublicKey, privateKey) : data;
|
|
213
232
|
|
|
214
233
|
if (result.status !== 'success') throw 'operation not successful';
|