@amazon-devices/expo-file-system 2.0.9000000000 → 3.0.0
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/CMakeLists.txt +41 -7
- package/README.kepler.md +1 -0
- package/build/ExponentFileSystem.kepler.d.ts.map +1 -1
- package/build/ExponentFileSystem.kepler.js +28 -45
- package/build/ExponentFileSystem.kepler.js.map +1 -1
- package/build/FileSystem.d.ts.map +1 -1
- package/build/FileSystem.js +0 -2
- package/build/FileSystem.js.map +1 -1
- package/kepler/CurlWrapper.cpp +254 -0
- package/kepler/CurlWrapper.h +56 -0
- package/kepler/ExponentFileSystem.cpp +290 -171
- package/kepler/ExponentFileSystem.h +39 -24
- package/kepler/KeplerInit.cpp +5 -10
- package/lib/aarch64-release/libexpo-file-system-3.so +0 -0
- package/lib/armv7-release/libexpo-file-system-3.so +0 -0
- package/lib/x86_64-release/libexpo-file-system-3.so +0 -0
- package/package.json +1 -1
- package/react-native.config.js +5 -3
- package/src/ExponentFileSystem.kepler.ts +33 -60
- package/src/FileSystem.ts +0 -2
- package/kepler/NetworkingRequestHandler.cpp +0 -47
|
@@ -7,12 +7,21 @@
|
|
|
7
7
|
*/
|
|
8
8
|
#pragma once
|
|
9
9
|
|
|
10
|
-
#include <
|
|
10
|
+
#include <Kepler/turbomodule/KeplerTurboModule.h>
|
|
11
|
+
#include "expo-export.h"
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
#include <memory>
|
|
14
|
+
|
|
15
|
+
#include "CurlWrapper.h"
|
|
16
|
+
|
|
17
|
+
class EXPO_EXPORT ExponentFileSystem : public com::amazon::kepler::turbomodule::KeplerTurboModule {
|
|
13
18
|
public:
|
|
14
19
|
ExponentFileSystem();
|
|
15
20
|
|
|
21
|
+
void aggregateMethods(
|
|
22
|
+
com::amazon::kepler::turbomodule::MethodAggregator<com::amazon::kepler::turbomodule::KeplerTurboModule>&
|
|
23
|
+
methodAggregator) const noexcept override;
|
|
24
|
+
|
|
16
25
|
#ifndef UNIT_TEST
|
|
17
26
|
protected:
|
|
18
27
|
#endif
|
|
@@ -20,41 +29,47 @@ protected:
|
|
|
20
29
|
std::string cacheDirectory();
|
|
21
30
|
std::string bundleDirectory();
|
|
22
31
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
32
|
+
com::amazon::kepler::turbomodule::Promise getInfoAsync(
|
|
33
|
+
const std::string fileUri,
|
|
34
|
+
com::amazon::kepler::turbomodule::NativeJSObject options);
|
|
35
|
+
com::amazon::kepler::turbomodule::Promise readAsStringAsync(
|
|
36
|
+
const std::string fileUri,
|
|
37
|
+
com::amazon::kepler::turbomodule::NativeJSObject options);
|
|
38
|
+
com::amazon::kepler::turbomodule::Promise getContentUriAsync(const std::string fileUri);
|
|
39
|
+
com::amazon::kepler::turbomodule::Promise writeAsStringAsync(
|
|
27
40
|
const std::string fileUri,
|
|
28
41
|
const std::string contents,
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const std::string fileUri,
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
42
|
+
com::amazon::kepler::turbomodule::NativeJSObject options);
|
|
43
|
+
com::amazon::kepler::turbomodule::Promise writeArrayBufferAsync(
|
|
44
|
+
const std::string fileUri,
|
|
45
|
+
const com::amazon::kepler::turbomodule::ArrayBuffer arrayBuffer);
|
|
46
|
+
com::amazon::kepler::turbomodule::Promise deleteAsync(
|
|
47
|
+
const std::string fileUri,
|
|
48
|
+
com::amazon::kepler::turbomodule::NativeJSObject options);
|
|
49
|
+
com::amazon::kepler::turbomodule::Promise moveAsync(com::amazon::kepler::turbomodule::NativeJSObject options);
|
|
50
|
+
com::amazon::kepler::turbomodule::Promise copyAsync(com::amazon::kepler::turbomodule::NativeJSObject options);
|
|
51
|
+
com::amazon::kepler::turbomodule::Promise makeDirectoryAsync(
|
|
52
|
+
const std::string fileUri,
|
|
53
|
+
com::amazon::kepler::turbomodule::NativeJSObject options);
|
|
54
|
+
com::amazon::kepler::turbomodule::Promise readDirectoryAsync(const std::string fileUri);
|
|
55
|
+
com::amazon::kepler::turbomodule::Promise getFreeDiskStorageAsync();
|
|
56
|
+
com::amazon::kepler::turbomodule::Promise getTotalDiskCapacityAsync();
|
|
57
|
+
com::amazon::kepler::turbomodule::Promise downloadAsync(
|
|
41
58
|
const std::string url,
|
|
42
59
|
const std::string fileUri,
|
|
43
|
-
|
|
60
|
+
com::amazon::kepler::turbomodule::NativeJSObject options,
|
|
44
61
|
double requestId,
|
|
45
62
|
std::vector<utils::json::JsonContainer> headers);
|
|
46
|
-
|
|
63
|
+
com::amazon::kepler::turbomodule::Promise uploadAsync(
|
|
47
64
|
const std::string url,
|
|
48
65
|
const std::string fileUri,
|
|
49
|
-
|
|
66
|
+
com::amazon::kepler::turbomodule::NativeJSObject options,
|
|
50
67
|
double requestId,
|
|
51
68
|
std::vector<utils::json::JsonContainer> headers);
|
|
52
69
|
|
|
53
|
-
void aggregateMethods(
|
|
54
|
-
volta::react::MethodAggregator<volta::react::KeplerTurboModule>& methodAggregator) const noexcept override;
|
|
55
|
-
|
|
56
70
|
private:
|
|
57
71
|
static constexpr int DIRECTORY_SIZE = 4096;
|
|
58
72
|
|
|
59
73
|
std::uintmax_t getSize(const std::string& path);
|
|
74
|
+
std::unique_ptr<CurlWrapper> curlWrapper_;
|
|
60
75
|
};
|
package/kepler/KeplerInit.cpp
CHANGED
|
@@ -6,20 +6,15 @@
|
|
|
6
6
|
* Use is subject to license terms.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
#include <
|
|
10
|
-
#include <
|
|
11
|
-
#include <keplerui-072/keplerscript-export.h>
|
|
9
|
+
#include <Kepler/turbomodule/KeplerTurboModuleRegistration.h>
|
|
10
|
+
#include <Kepler/turbomodule/TMLog.h>
|
|
12
11
|
|
|
13
12
|
#include "ExponentFileSystem.h"
|
|
14
|
-
#include "RegisterModule.h"
|
|
15
13
|
|
|
16
14
|
extern "C" {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
REGISTER_MODULE(autoLinkInfo, ExponentFileSystem, "ExponentFileSystem");
|
|
21
|
-
|
|
22
|
-
volta::react::KPLog.debug("after registering module");
|
|
15
|
+
__attribute__((visibility("default"))) void autoLinkKeplerTurboModulesV1() noexcept {
|
|
16
|
+
TMDEBUG("autoLinkKeplerTurboModulesV1 for expo-file-system");
|
|
17
|
+
KEPLER_REGISTER_TURBO_MODULE_WITH_NAME("ExponentFileSystemAppTM", ExponentFileSystem);
|
|
23
18
|
}
|
|
24
19
|
}
|
|
25
20
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name": "@amazon-devices/expo-file-system", "version": "
|
|
1
|
+
{"name": "@amazon-devices/expo-file-system", "version": "3.0.0+15.8.0", "description": "Provides access to the local file system on the device.", "main": "build/index.js", "types": "build/index.d.ts", "sideEffects": false, "scripts": {"build": "expo-module build", "clean": "expo-module clean", "lint": "expo-module lint", "test": "expo-module test", "prepublishOnly": "expo-module prepublishOnly", "expo-module": "expo-module"}, "kepler": {"temporary-alias-for-package": {"name": "expo-file-system", "version": "15.8.0"}}, "keywords": ["react-native", "expo", "file-system", "file"], "repository": {"type": "git", "url": "https://github.com/expo/expo.git", "directory": "packages/expo-file-system"}, "bugs": {"url": "https://github.com/expo/expo/issues"}, "author": "650 Industries, Inc.", "license": "See license in LICENSE", "homepage": "https://docs.expo.dev/versions/latest/sdk/filesystem/", "dependencies": {"uuid": "^3.4.0", "@amazon-devices/keplerscript-turbomodule-api": "^1.0.0"}, "devDependencies": {"expo-module-scripts": "^3.0.0", "jest-expo": "~50.0.0-alpha.0", "@types/glob": "^7.2.0", "@types/minimatch": "^3.0.5"}, "peerDependencies": {"expo": "^50.0.0-alpha.1"}}
|
package/react-native.config.js
CHANGED
|
@@ -10,9 +10,11 @@ module.exports = {
|
|
|
10
10
|
platforms: {
|
|
11
11
|
kepler: {
|
|
12
12
|
autolink: {
|
|
13
|
-
|
|
14
|
-
provider: '
|
|
15
|
-
|
|
13
|
+
ExponentFileSystemAppLib: {
|
|
14
|
+
provider: 'application',
|
|
15
|
+
linkDynamic: true,
|
|
16
|
+
libraryName: 'libexpo-file-system-3.so',
|
|
17
|
+
turbomodules: ['ExponentFileSystemAppTM'],
|
|
16
18
|
},
|
|
17
19
|
},
|
|
18
20
|
},
|
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
ReadingOptions,
|
|
13
13
|
RelocatingOptions,
|
|
14
14
|
WritingOptions,
|
|
15
|
-
FileSystemHttpResult,
|
|
16
15
|
} from './FileSystem.types';
|
|
17
16
|
import { ExponentFileSystemModule } from './types';
|
|
18
17
|
|
|
@@ -36,22 +35,17 @@ interface Spec extends KeplerTurboModule {
|
|
|
36
35
|
readonly readDirectoryAsync: (fileUri: string) => Promise<string[]>;
|
|
37
36
|
readonly getFreeDiskStorageAsync: () => Promise<string>;
|
|
38
37
|
readonly getTotalDiskCapacityAsync: () => Promise<string | undefined>;
|
|
38
|
+
readonly downloadAsync: (url: string, fileUri: string, options: Record<string, any>, requestId: number, headers: Array<{key: string, value: string}>) => Promise<FileSystemDownloadResult>;
|
|
39
|
+
readonly uploadAsync: (url: string, fileUri: string, options: Record<string, any>, requestId: number, headers: Array<{key: string, value: string}>) => Promise<FileSystemUploadResult>;
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
const nativeModule = TurboModuleRegistry.getEnforcing<Spec>('
|
|
42
|
-
const expoCryptoNativeModule = TurboModuleRegistry.getEnforcing<any>('ExpoCrypto');
|
|
42
|
+
const nativeModule = TurboModuleRegistry.getEnforcing<Spec>('ExponentFileSystemAppTM') as Spec;
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
response.headers.forEach((value: string, key: string) => {
|
|
47
|
-
responseHeaders[key] = value;
|
|
48
|
-
})
|
|
49
|
-
return responseHeaders;
|
|
50
|
-
}
|
|
44
|
+
let _requestId = 1;
|
|
45
|
+
const generateRequestId = (): number => { return _requestId++; };
|
|
51
46
|
|
|
52
|
-
function
|
|
53
|
-
|
|
54
|
-
return contentTypeKey ? responseHeaders[contentTypeKey].split(';')[0] : null;
|
|
47
|
+
function toHeadersList(headers?: Record<string, string>): Array<{key: string, value: string}> {
|
|
48
|
+
return Object.entries(headers ?? {}).map(([key, value]) => ({ key, value }));
|
|
55
49
|
}
|
|
56
50
|
|
|
57
51
|
const module: ExponentFileSystemModule = {
|
|
@@ -108,57 +102,36 @@ const module: ExponentFileSystemModule = {
|
|
|
108
102
|
return result ? parseInt(result) : 0;
|
|
109
103
|
},
|
|
110
104
|
async downloadAsync(url: string, fileUri: string, options: DownloadOptions): Promise<FileSystemDownloadResult> {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
uri: fileUri,
|
|
126
|
-
headers: responseHeaders,
|
|
127
|
-
status: response.status,
|
|
128
|
-
mimeType: getMimeTypeFromHeaders(responseHeaders)
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
if (md5) {
|
|
132
|
-
const md5ArrayBuffer = await expoCryptoNativeModule.digestAsync("MD5", data);
|
|
133
|
-
downloadResult.md5 = [...new Uint8Array(md5ArrayBuffer)]
|
|
134
|
-
.map(x => x.toString(16).padStart(2, '0'))
|
|
135
|
-
.join('');
|
|
105
|
+
console.log("[ExponentFileSystem] downloadAsync: native streaming download via libcurl");
|
|
106
|
+
console.log(`DOWNLOAD URL: ${url}`);
|
|
107
|
+
console.log(`FILE URL: ${fileUri}`);
|
|
108
|
+
|
|
109
|
+
try {
|
|
110
|
+
const result = await nativeModule.downloadAsync(url, fileUri, {
|
|
111
|
+
md5: options.md5 ?? false,
|
|
112
|
+
}, generateRequestId(), toHeadersList(options.headers));
|
|
113
|
+
|
|
114
|
+
return result as FileSystemDownloadResult;
|
|
115
|
+
} catch (error: any) {
|
|
116
|
+
console.error("[ExponentFileSystem] Download failed:", error?.message);
|
|
117
|
+
const message = error?.message ?? JSON.stringify(error);
|
|
118
|
+
throw new Error(`Download failed: ${message}`);
|
|
136
119
|
}
|
|
137
|
-
|
|
138
|
-
return downloadResult;
|
|
139
120
|
},
|
|
140
121
|
async uploadAsync(url: string, fileUri: string, options: FileSystemUploadOptions): Promise<FileSystemUploadResult> {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
122
|
+
console.log("[ExponentFileSystem] uploadAsync: native streaming upload via libcurl");
|
|
123
|
+
|
|
124
|
+
try {
|
|
125
|
+
const result = await nativeModule.uploadAsync(url, fileUri, {
|
|
126
|
+
httpMethod: options.httpMethod ?? "POST",
|
|
127
|
+
}, generateRequestId(), toHeadersList(options.headers));
|
|
128
|
+
|
|
129
|
+
return result as FileSystemUploadResult;
|
|
130
|
+
} catch (error: any) {
|
|
131
|
+
console.error("[ExponentFileSystem] Upload failed:", error?.message);
|
|
132
|
+
const message = error?.message ?? JSON.stringify(error);
|
|
133
|
+
throw new Error(`Upload failed: ${message}`);
|
|
150
134
|
}
|
|
151
|
-
|
|
152
|
-
const uploadResult = await response.text();
|
|
153
|
-
|
|
154
|
-
const responseHeaders = getHeadersFromResponse(response);
|
|
155
|
-
|
|
156
|
-
return {
|
|
157
|
-
body: uploadResult,
|
|
158
|
-
headers: responseHeaders,
|
|
159
|
-
status: response.status,
|
|
160
|
-
mimeType: getMimeTypeFromHeaders(responseHeaders)
|
|
161
|
-
};
|
|
162
135
|
},
|
|
163
136
|
addListener(eventName: string): void{},
|
|
164
137
|
removeListeners(count: number): void{},
|
package/src/FileSystem.ts
CHANGED
|
@@ -30,8 +30,6 @@ if (!ExponentFileSystem) {
|
|
|
30
30
|
"No native ExponentFileSystem module found, are you sure the expo-file-system's module is linked properly?"
|
|
31
31
|
);
|
|
32
32
|
}
|
|
33
|
-
// Prevent webpack from pruning this.
|
|
34
|
-
const _unused = new EventEmitter(ExponentFileSystem); // eslint-disable-line
|
|
35
33
|
|
|
36
34
|
function normalizeEndingSlash(p: string | null): string | null {
|
|
37
35
|
if (p != null) {
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
#include "NetworkingRequestHandler.h"
|
|
2
|
-
|
|
3
|
-
#include <fstream>
|
|
4
|
-
|
|
5
|
-
bool NetworkingRequestHandler::supports(utils::json::JsonContainer& data) {
|
|
6
|
-
return data["fileUri"].isValue();
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
void NetworkingRequestHandler::decorateRequest(
|
|
10
|
-
utils::json::JsonContainer& data,
|
|
11
|
-
const std::string& contentType,
|
|
12
|
-
volta::react::NetworkRequest& request) {
|
|
13
|
-
auto type = data["type"].getValue<std::string>("");
|
|
14
|
-
|
|
15
|
-
if (type.empty()) {
|
|
16
|
-
type = "application/octet-stream";
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
request.addHeader(volta::react::NetworkingModule::CONTENT_TYPE_HEADER_KEY, type);
|
|
20
|
-
|
|
21
|
-
try {
|
|
22
|
-
auto dataPtr = std::make_shared<std::vector<uint8_t>>();
|
|
23
|
-
|
|
24
|
-
auto fileUri = data["fileUri"].getValue<std::string>();
|
|
25
|
-
|
|
26
|
-
std::ifstream file(fileUri, std::ios::binary);
|
|
27
|
-
|
|
28
|
-
if (file.fail()) {
|
|
29
|
-
volta::react::KPLog.error("[ExponentFileSystem] unable to open file at {} for response read", fileUri);
|
|
30
|
-
} else {
|
|
31
|
-
std::copy(
|
|
32
|
-
std::istreambuf_iterator<char>(file),
|
|
33
|
-
std::istreambuf_iterator<char>(),
|
|
34
|
-
std::back_inserter(*dataPtr));
|
|
35
|
-
|
|
36
|
-
if (file.fail()) {
|
|
37
|
-
volta::react::KPLog.error("[ExponentFileSystem] error while reading response from file");
|
|
38
|
-
} else {
|
|
39
|
-
volta::react::KPLog.debug("[ExponentFileSystem] successfully read response from file");
|
|
40
|
-
volta::react::ArrayBuffer buf(dataPtr);
|
|
41
|
-
request.bodyDataBuffer = volta::react::ArrayBuffer(buf.dataVector());
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
} catch (std::exception& e) {
|
|
45
|
-
volta::react::KPLog.error("[ExponentFileSystem] reading response from file exception reason: {}", e.what());
|
|
46
|
-
}
|
|
47
|
-
}
|