react-native-cloud-storage 1.5.0 → 1.5.1
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/LICENSE +1 -1
- package/README.md +5 -6
- package/ios/CloudStorage.swift +262 -52
- package/ios/CloudStorage.xcodeproj/project.pbxproj +0 -28
- package/ios/CloudStorage.xcodeproj/project.xcworkspace/contents.xcworkspacedata +4 -0
- package/ios/CloudStorage.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/ios/CloudStorage.xcodeproj/project.xcworkspace/xcuserdata/max.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/CloudStorage.xcodeproj/xcuserdata/max.xcuserdatad/xcschemes/xcschememanagement.plist +22 -0
- package/ios/CloudStorageEventEmitter.swift +4 -4
- package/lib/commonjs/RNCloudStorage.js +66 -361
- package/lib/commonjs/RNCloudStorage.js.map +1 -1
- package/lib/commonjs/createRNCloudStorage.js +48 -0
- package/lib/commonjs/createRNCloudStorage.js.map +1 -0
- package/lib/commonjs/expo-plugin/types/index.js.map +1 -1
- package/lib/commonjs/expo-plugin/withRNCloudStorage.js +3 -2
- package/lib/commonjs/expo-plugin/withRNCloudStorage.js.map +1 -1
- package/lib/commonjs/expo-plugin/withRNCloudStorageIos.js +7 -4
- package/lib/commonjs/expo-plugin/withRNCloudStorageIos.js.map +1 -1
- package/lib/commonjs/google-drive/client.js +20 -16
- package/lib/commonjs/google-drive/client.js.map +1 -1
- package/lib/commonjs/google-drive/index.js +64 -42
- package/lib/commonjs/google-drive/index.js.map +1 -1
- package/lib/commonjs/google-drive/types.js +2 -1
- package/lib/commonjs/google-drive/types.js.map +1 -1
- package/lib/commonjs/hooks/useCloudFile.js +17 -14
- package/lib/commonjs/hooks/useCloudFile.js.map +1 -1
- package/lib/commonjs/hooks/useIsCloudAvailable.js +21 -11
- package/lib/commonjs/hooks/useIsCloudAvailable.js.map +1 -1
- package/lib/commonjs/index.js +7 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/types/main.js +3 -8
- package/lib/commonjs/types/main.js.map +1 -1
- package/lib/commonjs/types/native.js +3 -3
- package/lib/commonjs/types/native.js.map +1 -1
- package/lib/commonjs/utils/CloudStorageError.js +2 -1
- package/lib/commonjs/utils/CloudStorageError.js.map +1 -1
- package/lib/commonjs/utils/helpers.js +15 -8
- package/lib/commonjs/utils/helpers.js.map +1 -1
- package/lib/module/RNCloudStorage.js +65 -362
- package/lib/module/RNCloudStorage.js.map +1 -1
- package/lib/module/createRNCloudStorage.js +41 -0
- package/lib/module/createRNCloudStorage.js.map +1 -0
- package/lib/module/expo-plugin/types/index.js +1 -1
- package/lib/module/expo-plugin/types/index.js.map +1 -1
- package/lib/module/expo-plugin/withRNCloudStorage.js +0 -2
- package/lib/module/expo-plugin/withRNCloudStorage.js.map +1 -1
- package/lib/module/expo-plugin/withRNCloudStorageIos.js +5 -5
- package/lib/module/expo-plugin/withRNCloudStorageIos.js.map +1 -1
- package/lib/module/google-drive/client.js +20 -18
- package/lib/module/google-drive/client.js.map +1 -1
- package/lib/module/google-drive/index.js +62 -41
- package/lib/module/google-drive/index.js.map +1 -1
- package/lib/module/google-drive/types.js +0 -2
- package/lib/module/google-drive/types.js.map +1 -1
- package/lib/module/hooks/useCloudFile.js +16 -15
- package/lib/module/hooks/useCloudFile.js.map +1 -1
- package/lib/module/hooks/useIsCloudAvailable.js +21 -13
- package/lib/module/hooks/useIsCloudAvailable.js.map +1 -1
- package/lib/module/index.js +5 -2
- package/lib/module/index.js.map +1 -1
- package/lib/module/types/main.js +0 -9
- package/lib/module/types/main.js.map +1 -1
- package/lib/module/types/native.js +1 -4
- package/lib/module/types/native.js.map +1 -1
- package/lib/module/utils/CloudStorageError.js +0 -2
- package/lib/module/utils/CloudStorageError.js.map +1 -1
- package/lib/module/utils/helpers.js +13 -8
- package/lib/module/utils/helpers.js.map +1 -1
- package/lib/typescript/RNCloudStorage.d.ts +39 -159
- package/lib/typescript/RNCloudStorage.d.ts.map +1 -1
- package/lib/typescript/createRNCloudStorage.d.ts +3 -0
- package/lib/typescript/createRNCloudStorage.d.ts.map +1 -0
- package/lib/typescript/google-drive/client.d.ts +3 -3
- package/lib/typescript/google-drive/client.d.ts.map +1 -1
- package/lib/typescript/google-drive/index.d.ts +18 -6
- package/lib/typescript/google-drive/index.d.ts.map +1 -1
- package/lib/typescript/hooks/useCloudFile.d.ts +7 -4
- package/lib/typescript/hooks/useCloudFile.d.ts.map +1 -1
- package/lib/typescript/hooks/useIsCloudAvailable.d.ts +2 -3
- package/lib/typescript/hooks/useIsCloudAvailable.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +4 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/types/main.d.ts +0 -33
- package/lib/typescript/types/main.d.ts.map +1 -1
- package/lib/typescript/types/native.d.ts +1 -2
- package/lib/typescript/types/native.d.ts.map +1 -1
- package/lib/typescript/utils/helpers.d.ts +9 -2
- package/lib/typescript/utils/helpers.d.ts.map +1 -1
- package/package.json +11 -9
- package/src/RNCloudStorage.ts +68 -387
- package/src/createRNCloudStorage.ts +53 -0
- package/src/google-drive/client.ts +7 -8
- package/src/google-drive/index.ts +63 -38
- package/src/hooks/useCloudFile.ts +16 -13
- package/src/hooks/useIsCloudAvailable.ts +25 -12
- package/src/index.ts +5 -0
- package/src/types/main.ts +0 -38
- package/src/types/native.ts +1 -2
- package/src/utils/helpers.ts +15 -8
- package/ios/Utils/CloudKitUtils.swift +0 -112
- package/ios/Utils/CloudStorageError.swift +0 -78
- package/ios/Utils/FileUtils.swift +0 -132
- package/ios/Utils/Promise.swift +0 -58
- package/ios/Utils/Types.swift +0 -36
- package/lib/commonjs/package.json +0 -1
- package/lib/module/package.json +0 -1
package/src/RNCloudStorage.ts
CHANGED
|
@@ -1,320 +1,137 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
CloudStorageScope,
|
|
4
|
-
type CloudStorageFileStat,
|
|
5
|
-
type CloudStorageProviderOptions,
|
|
6
|
-
type DeepRequired,
|
|
7
|
-
} from './types/main';
|
|
8
|
-
import type NativeRNCloudStorage from './types/native';
|
|
9
|
-
import { isProviderSupported } from './utils/helpers';
|
|
10
|
-
import { NativeEventEmitter, NativeModules, Platform } from 'react-native';
|
|
11
|
-
import CloudStorageError from './utils/CloudStorageError';
|
|
12
|
-
import { CloudStorageErrorCode } from './types/native';
|
|
1
|
+
import { Platform } from 'react-native';
|
|
2
|
+
import createRNCloudStorage from './createRNCloudStorage';
|
|
13
3
|
import GoogleDrive from './google-drive';
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
} else {
|
|
35
|
-
throw new CloudStorageError('Unknown error', CloudStorageErrorCode.UNKNOWN, error);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
return originalFunction;
|
|
41
|
-
},
|
|
42
|
-
})
|
|
43
|
-
: null;
|
|
44
|
-
|
|
45
|
-
const defaultProviderOptions: DeepRequired<CloudStorageProviderOptions> = {
|
|
46
|
-
[CloudStorageProvider.ICloud]: {
|
|
47
|
-
scope: CloudStorageScope.AppData,
|
|
48
|
-
},
|
|
49
|
-
[CloudStorageProvider.GoogleDrive]: {
|
|
50
|
-
scope: CloudStorageScope.AppData,
|
|
51
|
-
accessToken: null,
|
|
52
|
-
strictFilenames: false,
|
|
53
|
-
timeout: 3000,
|
|
54
|
-
},
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
export default class RNCloudStorage {
|
|
58
|
-
private static defaultInstance: RNCloudStorage;
|
|
59
|
-
private provider: {
|
|
60
|
-
provider: CloudStorageProvider;
|
|
61
|
-
options: (typeof defaultProviderOptions)[keyof typeof defaultProviderOptions];
|
|
62
|
-
};
|
|
63
|
-
private cloudAvailabilityListeners: ((available: boolean) => void)[] = [];
|
|
64
|
-
|
|
65
|
-
//#region Constructor and configuration
|
|
66
|
-
/**
|
|
67
|
-
* Creates a new RNCloudStorage instance for the given provider.
|
|
68
|
-
* @param provider The provider to create the instance for. Defaults to the default provider for the current platform.
|
|
69
|
-
*/
|
|
70
|
-
constructor(
|
|
71
|
-
provider?: CloudStorageProvider,
|
|
72
|
-
options?: CloudStorageProviderOptions[keyof CloudStorageProviderOptions]
|
|
73
|
-
) {
|
|
74
|
-
if (provider && !isProviderSupported(provider)) {
|
|
75
|
-
throw new Error(`Provider ${provider} is not supported on the current platform.`);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
this.provider = {
|
|
79
|
-
provider: provider ?? RNCloudStorage.getDefaultProvider(),
|
|
80
|
-
options: defaultProviderOptions[provider ?? RNCloudStorage.getDefaultProvider()],
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
this.setProvider(provider ?? RNCloudStorage.getDefaultProvider());
|
|
84
|
-
if (options) {
|
|
85
|
-
this.setProviderOptions(options);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
private get nativeInstance(): NativeRNCloudStorage {
|
|
90
|
-
switch (this.provider.provider) {
|
|
91
|
-
case CloudStorageProvider.ICloud:
|
|
92
|
-
return (
|
|
93
|
-
nativeIosInstance ??
|
|
94
|
-
new Proxy(
|
|
95
|
-
{},
|
|
96
|
-
{
|
|
97
|
-
get() {
|
|
98
|
-
throw new Error(LINKING_ERROR);
|
|
99
|
-
},
|
|
100
|
-
}
|
|
101
|
-
)
|
|
102
|
-
);
|
|
103
|
-
default:
|
|
104
|
-
return new GoogleDrive(this.provider.options as DeepRequired<CloudStorageProviderOptions['googledrive']>);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Gets the default CloudStorageProvider for the current platform.
|
|
110
|
-
* @returns The default CloudStorageProvider.
|
|
111
|
-
*/
|
|
112
|
-
static getDefaultProvider(): CloudStorageProvider {
|
|
113
|
-
switch (Platform.OS) {
|
|
114
|
-
case 'ios':
|
|
115
|
-
return CloudStorageProvider.ICloud;
|
|
116
|
-
default:
|
|
117
|
-
return CloudStorageProvider.GoogleDrive;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Gets the list of supported CloudStorageProviders on the current platform.
|
|
123
|
-
* @returns An array of supported CloudStorageProviders.
|
|
124
|
-
*/
|
|
125
|
-
static getSupportedProviders(): CloudStorageProvider[] {
|
|
126
|
-
return Object.values(CloudStorageProvider).filter(isProviderSupported);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Gets the current CloudStorageProvider.
|
|
131
|
-
* @returns The current CloudStorageProvider.
|
|
132
|
-
*/
|
|
133
|
-
getProvider(): CloudStorageProvider {
|
|
134
|
-
return this.provider.provider;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Sets the current CloudStorageProvider.
|
|
139
|
-
* @param provider The provider to set.
|
|
140
|
-
*/
|
|
141
|
-
setProvider(provider: CloudStorageProvider): void {
|
|
142
|
-
if (!isProviderSupported(provider)) {
|
|
143
|
-
throw new Error(`Provider ${provider} is not supported on the current platform.`);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
this.provider = {
|
|
147
|
-
provider,
|
|
148
|
-
options: defaultProviderOptions[provider],
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
// Emit an event to notify useIsCloudAvailable() hook consumers of the new cloud availability status
|
|
152
|
-
this.nativeInstance.isCloudAvailable().then((available) => {
|
|
153
|
-
this.cloudAvailabilityListeners.forEach((listener) => {
|
|
154
|
-
listener(available);
|
|
155
|
-
});
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
if (provider === CloudStorageProvider.ICloud) {
|
|
159
|
-
// Listen to native cloud availability change events
|
|
160
|
-
const eventEmitter = new NativeEventEmitter(NativeModules.CloudStorageEventEmitter);
|
|
161
|
-
eventEmitter.addListener('RNCloudStorage.cloud.availability-changed', (event: { available: boolean }) => {
|
|
162
|
-
this.cloudAvailabilityListeners.forEach((listener) => {
|
|
163
|
-
listener(event.available);
|
|
164
|
-
});
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Gets the current options for the current provider.
|
|
171
|
-
* @returns The current options for the current provider.
|
|
172
|
-
*/
|
|
173
|
-
getProviderOptions(): CloudStorageProviderOptions[keyof CloudStorageProviderOptions] {
|
|
174
|
-
return this.provider.options;
|
|
175
|
-
}
|
|
4
|
+
import { CloudStorageScope, type CloudStorageFileStat } from './types/main';
|
|
5
|
+
import { verifyLeadingSlash } from './utils/helpers';
|
|
6
|
+
|
|
7
|
+
const nativeInstance = createRNCloudStorage();
|
|
8
|
+
let defaultScope = CloudStorageScope.AppData;
|
|
9
|
+
|
|
10
|
+
const RNCloudStorage = {
|
|
11
|
+
getDefaultScope: () => defaultScope,
|
|
12
|
+
setDefaultScope: (scope: CloudStorageScope) => (defaultScope = scope),
|
|
13
|
+
getGoogleDriveAccessToken: () => GoogleDrive.accessToken,
|
|
14
|
+
setGoogleDriveAccessToken: (accessToken: string | null) => (GoogleDrive.accessToken = accessToken),
|
|
15
|
+
setThrowOnFilesWithSameName: (enable: boolean) => (GoogleDrive.throwOnFilesWithSameName = enable),
|
|
16
|
+
setTimeout: (timeout: number) => (GoogleDrive.timeout = timeout),
|
|
17
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
18
|
+
subscribeToFilesWithSameName:
|
|
19
|
+
Platform.OS === 'ios'
|
|
20
|
+
? // @ts-expect-error - subscriber is undefined; just a mock
|
|
21
|
+
(subscriber: ({ path, fileIds }: { path: string; fileIds: string[] }) => void) => ({ remove: () => {} })
|
|
22
|
+
: (nativeInstance as GoogleDrive).subscribeToFilesWithSameName.bind(nativeInstance),
|
|
23
|
+
/* eslint-enable @typescript-eslint/no-unused-vars */
|
|
176
24
|
|
|
177
|
-
/**
|
|
178
|
-
* Sets the options for the current provider.
|
|
179
|
-
* @param options The options to set for the provider.
|
|
180
|
-
*/
|
|
181
|
-
setProviderOptions(options: CloudStorageProviderOptions[keyof CloudStorageProviderOptions]): void {
|
|
182
|
-
const newOptions = Object.fromEntries(Object.entries(options).filter(([_, v]) => v !== undefined));
|
|
183
|
-
this.provider.options = {
|
|
184
|
-
...this.provider.options,
|
|
185
|
-
...newOptions,
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
if (this.provider.provider === CloudStorageProvider.GoogleDrive && 'accessToken' in newOptions) {
|
|
189
|
-
// Emit an event to notify useIsCloudAvailable() hook consumers of the new cloud availability status
|
|
190
|
-
this.cloudAvailabilityListeners.forEach((listener) => {
|
|
191
|
-
listener(
|
|
192
|
-
!!(newOptions as Required<CloudStorageProviderOptions[CloudStorageProvider.GoogleDrive]>).accessToken?.length
|
|
193
|
-
);
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
subscribeToCloudAvailability(listener: (available: boolean) => void): void {
|
|
199
|
-
this.cloudAvailabilityListeners.push(listener);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
unsubscribeFromCloudAvailability(listener: (available: boolean) => void): void {
|
|
203
|
-
this.cloudAvailabilityListeners = this.cloudAvailabilityListeners.filter((l) => l !== listener);
|
|
204
|
-
}
|
|
205
|
-
//#endregion
|
|
206
|
-
|
|
207
|
-
//#region File system operations
|
|
208
25
|
/**
|
|
209
26
|
* Tests whether or not the cloud storage is available. Always returns true for Google Drive. iCloud may be
|
|
210
27
|
* unavailable right after app launch or if the user is not logged in.
|
|
211
28
|
* @returns A promise that resolves to true if the cloud storage is available, false otherwise.
|
|
212
29
|
*/
|
|
213
|
-
isCloudAvailable(): Promise<boolean> {
|
|
214
|
-
return
|
|
215
|
-
}
|
|
30
|
+
isCloudAvailable: async (): Promise<boolean> => {
|
|
31
|
+
return nativeInstance.isCloudAvailable();
|
|
32
|
+
},
|
|
216
33
|
|
|
217
34
|
/**
|
|
218
35
|
* Appends the data to the file at the given path, creating the file if it doesn't exist.
|
|
219
36
|
* @param path The file to append to.
|
|
220
37
|
* @param data The data to append.
|
|
221
|
-
* @param scope The directory scope the path is in. Defaults to the default scope
|
|
38
|
+
* @param scope The directory scope the path is in. Defaults to the set default scope.
|
|
222
39
|
* @returns A promise that resolves when the data has been appended.
|
|
223
40
|
*/
|
|
224
|
-
appendFile(path: string, data: string, scope?: CloudStorageScope): Promise<void> {
|
|
225
|
-
return
|
|
226
|
-
}
|
|
41
|
+
appendFile: (path: string, data: string, scope?: CloudStorageScope): Promise<void> => {
|
|
42
|
+
return nativeInstance.appendToFile(verifyLeadingSlash(path), data, scope ?? defaultScope);
|
|
43
|
+
},
|
|
227
44
|
|
|
228
45
|
/**
|
|
229
46
|
* Tests whether or not the file at the given path exists.
|
|
230
47
|
* @param path The path to test.
|
|
231
|
-
* @param scope The directory scope the path is in. Defaults to set default scope
|
|
48
|
+
* @param scope The directory scope the path is in. Defaults to the set default scope.
|
|
232
49
|
* @returns A promise that resolves to true if the path exists, false otherwise.
|
|
233
50
|
*/
|
|
234
|
-
exists(path: string, scope?: CloudStorageScope): Promise<boolean> {
|
|
235
|
-
return
|
|
236
|
-
}
|
|
51
|
+
exists: (path: string, scope?: CloudStorageScope): Promise<boolean> => {
|
|
52
|
+
return nativeInstance.fileExists(verifyLeadingSlash(path), scope ?? defaultScope);
|
|
53
|
+
},
|
|
237
54
|
|
|
238
55
|
/**
|
|
239
56
|
* Writes to the file at the given path, creating it if it doesn't exist or overwriting it if it does.
|
|
240
57
|
* @param path The file to write to.
|
|
241
58
|
* @param data The data to write.
|
|
242
|
-
* @param scope The directory scope the path is in. Defaults to set default scope
|
|
59
|
+
* @param scope The directory scope the path is in. Defaults to the set default scope.
|
|
243
60
|
* @returns A promise that resolves when the file has been written.
|
|
244
61
|
*/
|
|
245
|
-
writeFile(path: string, data: string, scope?: CloudStorageScope): Promise<void> {
|
|
246
|
-
return
|
|
247
|
-
}
|
|
62
|
+
writeFile: (path: string, data: string, scope?: CloudStorageScope): Promise<void> => {
|
|
63
|
+
return nativeInstance.createFile(verifyLeadingSlash(path), data, scope ?? defaultScope, true);
|
|
64
|
+
},
|
|
248
65
|
|
|
249
66
|
/**
|
|
250
67
|
* Creates a new directory at the given path.
|
|
251
68
|
* @param path The directory to create.
|
|
252
|
-
* @param scope The directory scope the path is in. Defaults to set default scope
|
|
69
|
+
* @param scope The directory scope the path is in. Defaults to the set default scope.
|
|
253
70
|
* @returns A promise that resolves when the directory has been created.
|
|
254
71
|
*/
|
|
255
|
-
mkdir(path: string, scope?: CloudStorageScope): Promise<void> {
|
|
256
|
-
return
|
|
257
|
-
}
|
|
72
|
+
mkdir: (path: string, scope?: CloudStorageScope): Promise<void> => {
|
|
73
|
+
return nativeInstance.createDirectory(verifyLeadingSlash(path), scope ?? defaultScope);
|
|
74
|
+
},
|
|
258
75
|
|
|
259
76
|
/**
|
|
260
77
|
* Lists the contents of the directory at the given path.
|
|
261
78
|
* @param path The directory to list.
|
|
262
|
-
* @param scope The directory scope the path is in. Defaults to set default scope
|
|
79
|
+
* @param scope The directory scope the path is in. Defaults to the set default scope.
|
|
263
80
|
* @returns A promise that resolves to an array of file names, excluding '.' and '..'.
|
|
264
81
|
*/
|
|
265
|
-
readdir(path: string, scope?: CloudStorageScope): Promise<string[]> {
|
|
266
|
-
return
|
|
267
|
-
}
|
|
82
|
+
readdir: (path: string, scope?: CloudStorageScope): Promise<string[]> => {
|
|
83
|
+
return nativeInstance.listFiles(verifyLeadingSlash(path), scope ?? defaultScope);
|
|
84
|
+
},
|
|
268
85
|
|
|
269
86
|
/**
|
|
270
87
|
* Reads the contents of the file at the given path.
|
|
271
88
|
* @param path The file to read.
|
|
272
|
-
* @param scope The directory scope the path is in. Defaults to set default scope
|
|
89
|
+
* @param scope The directory scope the path is in. Defaults to the set default scope.
|
|
273
90
|
* @returns A promise that resolves to the contents of the file.
|
|
274
91
|
*/
|
|
275
|
-
readFile(path: string, scope?: CloudStorageScope): Promise<string> {
|
|
276
|
-
return
|
|
277
|
-
}
|
|
92
|
+
readFile: (path: string, scope?: CloudStorageScope): Promise<string> => {
|
|
93
|
+
return nativeInstance.readFile(verifyLeadingSlash(path), scope ?? defaultScope);
|
|
94
|
+
},
|
|
278
95
|
|
|
279
96
|
/**
|
|
280
|
-
* Downloads the file at the given path. Does not have any effect on Google Drive.
|
|
97
|
+
* Downloads the file at the given path from iCloud. Does not have any effect on Google Drive.
|
|
281
98
|
* @param path The file to trigger the download for.
|
|
282
|
-
* @param scope The directory scope the path is in. Defaults to set default scope
|
|
99
|
+
* @param scope The directory scope the path is in. Defaults to the set default scope.
|
|
283
100
|
* @returns A promise that resolves once the download has been triggered.
|
|
284
101
|
*/
|
|
285
|
-
downloadFile(path: string, scope?: CloudStorageScope): Promise<void> {
|
|
286
|
-
return
|
|
287
|
-
}
|
|
102
|
+
downloadFile: (path: string, scope?: CloudStorageScope): Promise<void> => {
|
|
103
|
+
return nativeInstance.downloadFile(verifyLeadingSlash(path), scope ?? defaultScope);
|
|
104
|
+
},
|
|
288
105
|
|
|
289
106
|
/**
|
|
290
107
|
* Deletes the file at the given path.
|
|
291
108
|
* @param path The file to delete.
|
|
292
|
-
* @param scope The directory scope the path is in. Defaults to set default scope
|
|
109
|
+
* @param scope The directory scope the path is in. Defaults to the set default scope.
|
|
293
110
|
* @returns A promise that resolves when the file has been deleted.
|
|
294
111
|
*/
|
|
295
|
-
unlink(path: string, scope?: CloudStorageScope): Promise<void> {
|
|
296
|
-
return
|
|
297
|
-
}
|
|
112
|
+
unlink: (path: string, scope?: CloudStorageScope): Promise<void> => {
|
|
113
|
+
return nativeInstance.deleteFile(verifyLeadingSlash(path), scope ?? defaultScope);
|
|
114
|
+
},
|
|
298
115
|
|
|
299
116
|
/**
|
|
300
117
|
* Deletes the directory at the given path.
|
|
301
118
|
* @param path The directory to delete.
|
|
302
119
|
* @param options Options for the delete operation. Defaults to { recursive: false }.
|
|
303
|
-
* @param scope The directory scope the path is in. Defaults to set default scope
|
|
120
|
+
* @param scope The directory scope the path is in. Defaults to the set default scope.
|
|
304
121
|
* @returns A promise that resolves when the directory has been deleted.
|
|
305
122
|
*/
|
|
306
|
-
rmdir(path: string, options?: { recursive?: boolean }, scope?: CloudStorageScope): Promise<void> {
|
|
307
|
-
return
|
|
308
|
-
}
|
|
123
|
+
rmdir: (path: string, options?: { recursive?: boolean }, scope?: CloudStorageScope): Promise<void> => {
|
|
124
|
+
return nativeInstance.deleteDirectory(verifyLeadingSlash(path), options?.recursive ?? false, scope ?? defaultScope);
|
|
125
|
+
},
|
|
309
126
|
|
|
310
127
|
/**
|
|
311
128
|
* Gets the size, creation time, and modification time of the file at the given path.
|
|
312
129
|
* @param path The file to stat.
|
|
313
|
-
* @param scope The directory scope the path is in. Defaults to set default scope
|
|
130
|
+
* @param scope The directory scope the path is in. Defaults to the set default scope.
|
|
314
131
|
* @returns A promise that resolves to the CloudStorageFileStat object.
|
|
315
132
|
*/
|
|
316
|
-
async
|
|
317
|
-
const native = await
|
|
133
|
+
stat: async (path: string, scope?: CloudStorageScope): Promise<CloudStorageFileStat> => {
|
|
134
|
+
const native = await nativeInstance.statFile(verifyLeadingSlash(path), scope ?? defaultScope);
|
|
318
135
|
|
|
319
136
|
return {
|
|
320
137
|
...native,
|
|
@@ -323,143 +140,7 @@ export default class RNCloudStorage {
|
|
|
323
140
|
isDirectory: () => native.isDirectory,
|
|
324
141
|
isFile: () => native.isFile,
|
|
325
142
|
};
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
//#region Static methods for default static instance
|
|
330
|
-
static getDefaultInstance(): RNCloudStorage {
|
|
331
|
-
if (!RNCloudStorage.defaultInstance) {
|
|
332
|
-
RNCloudStorage.defaultInstance = new RNCloudStorage();
|
|
333
|
-
}
|
|
334
|
-
return RNCloudStorage.defaultInstance;
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
/**
|
|
338
|
-
* Gets the current options for the provider of the default static instance.
|
|
339
|
-
* @returns The current options for the provider of the default static instance.
|
|
340
|
-
*/
|
|
341
|
-
static getProviderOptions(): CloudStorageProviderOptions[keyof CloudStorageProviderOptions] {
|
|
342
|
-
return RNCloudStorage.getDefaultInstance().getProviderOptions();
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
/**
|
|
346
|
-
* Sets the options for the provider of the default static instance.
|
|
347
|
-
* @param options The options to set for the provider of the default static instance.
|
|
348
|
-
*/
|
|
349
|
-
static setProviderOptions(options: CloudStorageProviderOptions[keyof CloudStorageProviderOptions]): void {
|
|
350
|
-
RNCloudStorage.getDefaultInstance().setProviderOptions(options);
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
/**
|
|
354
|
-
* Tests whether or not the file at the given path exists in the provider of the default static instance.
|
|
355
|
-
* @param path The path to test.
|
|
356
|
-
* @param scope The directory scope the path is in. Defaults to set default scope set for the current provider.
|
|
357
|
-
* @returns A promise that resolves to true if the path exists, false otherwise.
|
|
358
|
-
*/
|
|
359
|
-
static exists(path: string, scope?: CloudStorageScope): Promise<boolean> {
|
|
360
|
-
return RNCloudStorage.getDefaultInstance().exists(path, scope);
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
/**
|
|
364
|
-
* Tests whether or not the cloud storage is available for the provider of the default static instance. Always returns true for Google Drive. iCloud may be
|
|
365
|
-
* unavailable right after app launch or if the user is not logged in.
|
|
366
|
-
* @returns A promise that resolves to true if the cloud storage is available, false otherwise.
|
|
367
|
-
*/
|
|
368
|
-
static isCloudAvailable(): Promise<boolean> {
|
|
369
|
-
return RNCloudStorage.getDefaultInstance().isCloudAvailable();
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
/**
|
|
373
|
-
* Appends the data to the file at the given path in the provider of the default static instance, creating the file if it doesn't exist.
|
|
374
|
-
* @param path The file to append to.
|
|
375
|
-
* @param data The data to append.
|
|
376
|
-
* @param scope The directory scope the path is in. Defaults to the default scope set for the default static instance.
|
|
377
|
-
* @returns A promise that resolves when the data has been appended.
|
|
378
|
-
*/
|
|
379
|
-
static appendFile(path: string, data: string, scope?: CloudStorageScope): Promise<void> {
|
|
380
|
-
return RNCloudStorage.getDefaultInstance().appendFile(path, data, scope);
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
/**
|
|
384
|
-
* Writes to the file at the given path in the provider of the default static instance, creating it if it doesn't exist or overwriting it if it does.
|
|
385
|
-
* @param path The file to write to.
|
|
386
|
-
* @param data The data to write.
|
|
387
|
-
* @param scope The directory scope the path is in. Defaults to the default scope set for the default static instance.
|
|
388
|
-
* @returns A promise that resolves when the file has been written.
|
|
389
|
-
*/
|
|
390
|
-
static writeFile(path: string, data: string, scope?: CloudStorageScope): Promise<void> {
|
|
391
|
-
return RNCloudStorage.getDefaultInstance().writeFile(path, data, scope);
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
/**
|
|
395
|
-
* Creates a new directory at the given path in the provider of the default static instance.
|
|
396
|
-
* @param path The directory to create.
|
|
397
|
-
* @param scope The directory scope the path is in. Defaults to the default scope set for the default static instance.
|
|
398
|
-
* @returns A promise that resolves when the directory has been created.
|
|
399
|
-
*/
|
|
400
|
-
static mkdir(path: string, scope?: CloudStorageScope): Promise<void> {
|
|
401
|
-
return RNCloudStorage.getDefaultInstance().mkdir(path, scope);
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
/**
|
|
405
|
-
* Lists the contents of the directory at the given path in the provider of the default static instance.
|
|
406
|
-
* @param path The directory to list.
|
|
407
|
-
* @param scope The directory scope the path is in. Defaults to the default scope set for the default static instance.
|
|
408
|
-
* @returns A promise that resolves to an array of file names, excluding '.' and '..'.
|
|
409
|
-
*/
|
|
410
|
-
static readdir(path: string, scope?: CloudStorageScope): Promise<string[]> {
|
|
411
|
-
return RNCloudStorage.getDefaultInstance().readdir(path, scope);
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
/**
|
|
415
|
-
* Reads the contents of the file at the given path in the provider of the default static instance.
|
|
416
|
-
* @param path The file to read.
|
|
417
|
-
* @param scope The directory scope the path is in. Defaults to the default scope set for the default static instance.
|
|
418
|
-
* @returns A promise that resolves to the contents of the file.
|
|
419
|
-
*/
|
|
420
|
-
static readFile(path: string, scope?: CloudStorageScope): Promise<string> {
|
|
421
|
-
return RNCloudStorage.getDefaultInstance().readFile(path, scope);
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
/**
|
|
425
|
-
* Downloads the file at the given path in the provider of the default static instance. Does not have any effect on Google Drive.
|
|
426
|
-
* @param path The file to trigger the download for.
|
|
427
|
-
* @param scope The directory scope the path is in. Defaults to the default scope set for the default static instance.
|
|
428
|
-
* @returns A promise that resolves once the download has been triggered.
|
|
429
|
-
*/
|
|
430
|
-
static downloadFile(path: string, scope?: CloudStorageScope): Promise<void> {
|
|
431
|
-
return RNCloudStorage.getDefaultInstance().downloadFile(path, scope);
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
/**
|
|
435
|
-
* Deletes the file at the given path in the provider of the default static instance.
|
|
436
|
-
* @param path The file to delete.
|
|
437
|
-
* @param scope The directory scope the path is in. Defaults to the default scope set for the default static instance.
|
|
438
|
-
* @returns A promise that resolves when the file has been deleted.
|
|
439
|
-
*/
|
|
440
|
-
static unlink(path: string, scope?: CloudStorageScope): Promise<void> {
|
|
441
|
-
return RNCloudStorage.getDefaultInstance().unlink(path, scope);
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
/**
|
|
445
|
-
* Deletes the directory at the given path in the provider of the default static instance.
|
|
446
|
-
* @param path The directory to delete.
|
|
447
|
-
* @param options Options for the delete operation. Defaults to { recursive: false }.
|
|
448
|
-
* @param scope The directory scope the path is in. Defaults to the default scope set for the default static instance.
|
|
449
|
-
* @returns A promise that resolves when the directory has been deleted.
|
|
450
|
-
*/
|
|
451
|
-
static rmdir(path: string, options?: { recursive?: boolean }, scope?: CloudStorageScope): Promise<void> {
|
|
452
|
-
return RNCloudStorage.getDefaultInstance().rmdir(path, options, scope);
|
|
453
|
-
}
|
|
143
|
+
},
|
|
144
|
+
};
|
|
454
145
|
|
|
455
|
-
|
|
456
|
-
* Gets the size, creation time, and modification time of the file at the given path in the provider of the default static instance.
|
|
457
|
-
* @param path The file to stat.
|
|
458
|
-
* @param scope The directory scope the path is in. Defaults to the default scope set for the default static instance.
|
|
459
|
-
* @returns A promise that resolves to the CloudStorageFileStat object.
|
|
460
|
-
*/
|
|
461
|
-
static stat(path: string, scope?: CloudStorageScope): Promise<CloudStorageFileStat> {
|
|
462
|
-
return RNCloudStorage.getDefaultInstance().stat(path, scope);
|
|
463
|
-
}
|
|
464
|
-
//#endregion
|
|
465
|
-
}
|
|
146
|
+
export default RNCloudStorage;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { NativeModules, Platform } from 'react-native';
|
|
2
|
+
import type NativeRNCloudStorage from './types/native';
|
|
3
|
+
import GoogleDrive from './google-drive';
|
|
4
|
+
import { CloudStorageErrorCode } from './types/native';
|
|
5
|
+
import CloudStorageError from './utils/CloudStorageError';
|
|
6
|
+
|
|
7
|
+
const LINKING_ERROR =
|
|
8
|
+
`The package 'react-native-cloud-storage' doesn't seem to be linked. Make sure: \n\n` +
|
|
9
|
+
Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
|
|
10
|
+
'- You rebuilt the app after installing the package\n' +
|
|
11
|
+
'- You are not using Expo Go\n';
|
|
12
|
+
|
|
13
|
+
// proxy NativeModules.CloudStorage to catch any errors thrown by the native module and wrap them in a CloudStorageError
|
|
14
|
+
const nativeIosInstance = NativeModules.CloudStorage
|
|
15
|
+
? new Proxy(NativeModules.CloudStorage, {
|
|
16
|
+
get(target: NativeRNCloudStorage, prop: keyof NativeRNCloudStorage) {
|
|
17
|
+
const originalFunction = target[prop];
|
|
18
|
+
if (typeof originalFunction === 'function') {
|
|
19
|
+
return async (...args: any[]) => {
|
|
20
|
+
try {
|
|
21
|
+
// @ts-expect-error - we can't know the types of the functions and their arguments
|
|
22
|
+
return await originalFunction(...args);
|
|
23
|
+
} catch (error: any) {
|
|
24
|
+
if (error?.code && Object.values(CloudStorageErrorCode).includes(error.code)) {
|
|
25
|
+
throw new CloudStorageError(error?.message || '', error.code as CloudStorageErrorCode);
|
|
26
|
+
} else {
|
|
27
|
+
throw new CloudStorageError('Unknown error', CloudStorageErrorCode.UNKNOWN, error);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return originalFunction;
|
|
33
|
+
},
|
|
34
|
+
})
|
|
35
|
+
: null;
|
|
36
|
+
|
|
37
|
+
export default function createRNCloudStorage(): NativeRNCloudStorage {
|
|
38
|
+
if (Platform.OS === 'ios') {
|
|
39
|
+
return (
|
|
40
|
+
nativeIosInstance ??
|
|
41
|
+
new Proxy(
|
|
42
|
+
{},
|
|
43
|
+
{
|
|
44
|
+
get() {
|
|
45
|
+
throw new Error(LINKING_ERROR);
|
|
46
|
+
},
|
|
47
|
+
}
|
|
48
|
+
)
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return new GoogleDrive();
|
|
53
|
+
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { type CloudStorageProviderOptions, type DeepRequired } from '../types/main';
|
|
2
1
|
import {
|
|
3
2
|
MimeTypes,
|
|
4
3
|
type GoogleDriveFile,
|
|
@@ -25,11 +24,13 @@ export class GoogleDriveHttpError extends Error {
|
|
|
25
24
|
// TODO: fetch timeout
|
|
26
25
|
// TODO: properly handle errors
|
|
27
26
|
export default class GoogleDriveApiClient {
|
|
27
|
+
public accessToken: string;
|
|
28
|
+
public timeout: number;
|
|
28
29
|
private _fetchTimeout: any;
|
|
29
|
-
private options: DeepRequired<CloudStorageProviderOptions['googledrive']>;
|
|
30
30
|
|
|
31
|
-
constructor(
|
|
32
|
-
this.
|
|
31
|
+
constructor(accessToken: string = '') {
|
|
32
|
+
this.accessToken = accessToken;
|
|
33
|
+
this.timeout = 3000;
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
private buildQueryString(query: object): string {
|
|
@@ -51,8 +52,6 @@ export default class GoogleDriveApiClient {
|
|
|
51
52
|
operation: `/${string}`,
|
|
52
53
|
{ queryParameters, baseUrl, ...options }: RequestInit & { queryParameters?: object; baseUrl?: string } = {}
|
|
53
54
|
): Promise<T> {
|
|
54
|
-
const { timeout, accessToken } = this.options;
|
|
55
|
-
|
|
56
55
|
let path = `${baseUrl ?? BASE_URL}${operation}`;
|
|
57
56
|
if (queryParameters) {
|
|
58
57
|
path += this.buildQueryString(queryParameters);
|
|
@@ -61,12 +60,12 @@ export default class GoogleDriveApiClient {
|
|
|
61
60
|
const abortController: AbortController = new AbortController();
|
|
62
61
|
this._fetchTimeout = setTimeout(() => {
|
|
63
62
|
abortController.abort();
|
|
64
|
-
}, timeout);
|
|
63
|
+
}, this.timeout);
|
|
65
64
|
const response = await fetch(path, {
|
|
66
65
|
...options,
|
|
67
66
|
headers: {
|
|
68
67
|
...options.headers,
|
|
69
|
-
Authorization: `Bearer ${accessToken}`,
|
|
68
|
+
Authorization: `Bearer ${this.accessToken}`,
|
|
70
69
|
},
|
|
71
70
|
signal: abortController.signal,
|
|
72
71
|
});
|