@themartiancompany/opfs 1.8.11
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/COPYING +674 -0
- package/README.cn.md +301 -0
- package/README.md +241 -0
- package/dist/main.cjs +1840 -0
- package/dist/main.cjs.map +1 -0
- package/dist/main.mjs +1751 -0
- package/dist/main.mjs.map +1 -0
- package/dist/types.d.ts +920 -0
- package/dist/types.d.ts.map +1 -0
- package/docs/README.md +115 -0
- package/docs/classes/SyncMessenger.md +42 -0
- package/docs/functions/appendFile.md +29 -0
- package/docs/functions/appendFileSync.md +26 -0
- package/docs/functions/assertAbsolutePath.md +29 -0
- package/docs/functions/assertFileUrl.md +29 -0
- package/docs/functions/connectSyncAgent.md +25 -0
- package/docs/functions/copy.md +35 -0
- package/docs/functions/copySync.md +30 -0
- package/docs/functions/createFile.md +27 -0
- package/docs/functions/createFileSync.md +25 -0
- package/docs/functions/deleteTemp.md +23 -0
- package/docs/functions/deleteTempSync.md +19 -0
- package/docs/functions/downloadFile.md +58 -0
- package/docs/functions/emptyDir.md +28 -0
- package/docs/functions/emptyDirSync.md +25 -0
- package/docs/functions/exists.md +29 -0
- package/docs/functions/existsSync.md +26 -0
- package/docs/functions/generateTempPath.md +27 -0
- package/docs/functions/getFileDataByHandle.md +27 -0
- package/docs/functions/getSyncMessenger.md +22 -0
- package/docs/functions/isDirectoryHandle.md +27 -0
- package/docs/functions/isFileHandle.md +27 -0
- package/docs/functions/isFileHandleLike.md +27 -0
- package/docs/functions/isOPFSSupported.md +21 -0
- package/docs/functions/isTempPath.md +27 -0
- package/docs/functions/mkTemp.md +28 -0
- package/docs/functions/mkTempSync.md +25 -0
- package/docs/functions/mkdir.md +27 -0
- package/docs/functions/mkdirSync.md +25 -0
- package/docs/functions/move.md +34 -0
- package/docs/functions/moveSync.md +30 -0
- package/docs/functions/pruneTemp.md +28 -0
- package/docs/functions/pruneTempSync.md +25 -0
- package/docs/functions/readBlobFile.md +28 -0
- package/docs/functions/readBlobFileSync.md +25 -0
- package/docs/functions/readDir.md +28 -0
- package/docs/functions/readDirSync.md +26 -0
- package/docs/functions/readFile.md +132 -0
- package/docs/functions/readFileSync.md +70 -0
- package/docs/functions/readJsonFile.md +35 -0
- package/docs/functions/readJsonFileSync.md +31 -0
- package/docs/functions/readTextFile.md +28 -0
- package/docs/functions/readTextFileSync.md +25 -0
- package/docs/functions/remove.md +27 -0
- package/docs/functions/removeSync.md +25 -0
- package/docs/functions/setSyncMessenger.md +26 -0
- package/docs/functions/startSyncAgent.md +21 -0
- package/docs/functions/stat.md +27 -0
- package/docs/functions/statSync.md +25 -0
- package/docs/functions/toFileSystemHandleLike.md +27 -0
- package/docs/functions/unzip.md +32 -0
- package/docs/functions/unzipFromUrl.md +36 -0
- package/docs/functions/unzipSync.md +26 -0
- package/docs/functions/uploadFile.md +33 -0
- package/docs/functions/writeFile.md +32 -0
- package/docs/functions/writeFileSync.md +30 -0
- package/docs/functions/zip.md +65 -0
- package/docs/functions/zipFromUrl.md +63 -0
- package/docs/functions/zipSync.md +55 -0
- package/docs/interfaces/CopyOptions.md +17 -0
- package/docs/interfaces/DownloadFileTempResponse.md +18 -0
- package/docs/interfaces/ErrorLike.md +18 -0
- package/docs/interfaces/ExistsOptions.md +18 -0
- package/docs/interfaces/FileLike.md +21 -0
- package/docs/interfaces/FileSystemFileHandleLike.md +25 -0
- package/docs/interfaces/FileSystemHandleLike.md +22 -0
- package/docs/interfaces/MoveOptions.md +17 -0
- package/docs/interfaces/ReadDirEntry.md +18 -0
- package/docs/interfaces/ReadDirEntrySync.md +18 -0
- package/docs/interfaces/ReadDirOptions.md +17 -0
- package/docs/interfaces/ReadOptions.md +17 -0
- package/docs/interfaces/SyncAgentOptions.md +19 -0
- package/docs/interfaces/TempOptions.md +19 -0
- package/docs/interfaces/UploadRequestInit.md +21 -0
- package/docs/interfaces/WriteOptions.md +19 -0
- package/docs/interfaces/ZipOptions.md +17 -0
- package/docs/type-aliases/FileEncoding.md +15 -0
- package/docs/type-aliases/FsRequestInit.md +15 -0
- package/docs/type-aliases/ReadFileContent.md +15 -0
- package/docs/type-aliases/WriteFileContent.md +15 -0
- package/docs/type-aliases/WriteSyncFileContent.md +16 -0
- package/docs/variables/CURRENT_DIR.md +15 -0
- package/docs/variables/NOT_FOUND_ERROR.md +18 -0
- package/docs/variables/ROOT_DIR.md +15 -0
- package/docs/variables/TMP_DIR.md +15 -0
- package/package.json +141 -0
- package/src/fs/assertions.ts +63 -0
- package/src/fs/constants.ts +63 -0
- package/src/fs/defines.ts +352 -0
- package/src/fs/helpers.ts +338 -0
- package/src/fs/opfs_core.ts +413 -0
- package/src/fs/opfs_download.ts +174 -0
- package/src/fs/opfs_ext.ts +504 -0
- package/src/fs/opfs_tmp.ts +131 -0
- package/src/fs/opfs_unzip.ts +168 -0
- package/src/fs/opfs_upload.ts +126 -0
- package/src/fs/opfs_zip.ts +314 -0
- package/src/fs/support.ts +36 -0
- package/src/fs/utils.ts +176 -0
- package/src/mod.ts +41 -0
- package/src/worker/helpers.ts +168 -0
- package/src/worker/opfs_worker.ts +298 -0
- package/src/worker/opfs_worker_adapter.ts +666 -0
- package/src/worker/shared.ts +400 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
|
+
|
|
3
|
+
/** ----------------------------------------------------------------------
|
|
4
|
+
* Copyright ©
|
|
5
|
+
* Jiang Jie
|
|
6
|
+
* 2024, 2025
|
|
7
|
+
* Pellegrino Prevete
|
|
8
|
+
* 2025
|
|
9
|
+
*
|
|
10
|
+
* All rights reserved
|
|
11
|
+
* ----------------------------------------------------------------------
|
|
12
|
+
*
|
|
13
|
+
* This program is free software: you can redistribute it and/or modify
|
|
14
|
+
* it under the terms of the GNU General Public License as published by
|
|
15
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
16
|
+
* (at your option) any later version.
|
|
17
|
+
*
|
|
18
|
+
* This program is distributed in the hope that it will be useful,
|
|
19
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
20
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
21
|
+
* GNU General Public License for more details.
|
|
22
|
+
*
|
|
23
|
+
* You should have received a copy of the GNU General Public License
|
|
24
|
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import { fetchT } from '@happy-ts/fetch-t';
|
|
28
|
+
import { join,
|
|
29
|
+
SEPARATOR } from '@std/path/posix';
|
|
30
|
+
import * as fflate from 'fflate/browser';
|
|
31
|
+
import { Err,
|
|
32
|
+
type AsyncVoidIOResult,
|
|
33
|
+
type VoidIOResult } from 'happy-rusty';
|
|
34
|
+
import { Future } from 'tiny-future';
|
|
35
|
+
import { assertAbsolutePath,
|
|
36
|
+
assertFileUrl } from './assertions.ts';
|
|
37
|
+
import type { FsRequestInit } from './defines.ts';
|
|
38
|
+
import { getFinalResult } from './helpers.ts';
|
|
39
|
+
import { readFile,
|
|
40
|
+
writeFile } from './opfs_core.ts';
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Unzip a buffer then write to the target path.
|
|
44
|
+
* @param buffer - Zipped ArrayBuffer.
|
|
45
|
+
* @param targetPath - Target directory path.
|
|
46
|
+
*/
|
|
47
|
+
async function
|
|
48
|
+
unzipBufferToTarget(
|
|
49
|
+
buffer:
|
|
50
|
+
ArrayBuffer,
|
|
51
|
+
targetPath:
|
|
52
|
+
string):
|
|
53
|
+
AsyncVoidIOResult {
|
|
54
|
+
const
|
|
55
|
+
data =
|
|
56
|
+
new Uint8Array(
|
|
57
|
+
buffer);
|
|
58
|
+
const
|
|
59
|
+
future =
|
|
60
|
+
new Future<VoidIOResult>();
|
|
61
|
+
fflate.unzip(
|
|
62
|
+
data,
|
|
63
|
+
async (err, unzipped) => {
|
|
64
|
+
if (err) {
|
|
65
|
+
future.resolve(
|
|
66
|
+
Err(
|
|
67
|
+
err));
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const
|
|
71
|
+
tasks:
|
|
72
|
+
AsyncVoidIOResult[] =
|
|
73
|
+
[];
|
|
74
|
+
for ( const path in unzipped ) {
|
|
75
|
+
// ignore directory
|
|
76
|
+
if ( path.at(
|
|
77
|
+
-1) !== SEPARATOR ) {
|
|
78
|
+
tasks.push(
|
|
79
|
+
writeFile(
|
|
80
|
+
join(
|
|
81
|
+
targetPath,
|
|
82
|
+
path),
|
|
83
|
+
unzipped[
|
|
84
|
+
path]));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
future.resolve(
|
|
88
|
+
getFinalResult(
|
|
89
|
+
tasks));
|
|
90
|
+
});
|
|
91
|
+
return await future.promise;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Unzip a zip file to a directory.
|
|
96
|
+
* Equivalent to `unzip -o <zipFilePath> -d <targetPath>
|
|
97
|
+
*
|
|
98
|
+
* Usees [fflate](https://github.com/101arrowz/fflate) as the unzip backend.
|
|
99
|
+
* @param zipFilePath - Zip file path.
|
|
100
|
+
* @param targetPath - The directory to unzip to.
|
|
101
|
+
* @returns A promise that resolves to an `AsyncIOResult`
|
|
102
|
+
* indicating whether the zip file was successfully unzipped.
|
|
103
|
+
*/
|
|
104
|
+
export
|
|
105
|
+
async function
|
|
106
|
+
unzip(
|
|
107
|
+
zipFilePath:
|
|
108
|
+
string,
|
|
109
|
+
targetPath:
|
|
110
|
+
string):
|
|
111
|
+
AsyncVoidIOResult {
|
|
112
|
+
assertAbsolutePath(
|
|
113
|
+
targetPath);
|
|
114
|
+
const
|
|
115
|
+
fileRes =
|
|
116
|
+
await readFile(
|
|
117
|
+
zipFilePath);
|
|
118
|
+
return fileRes.andThenAsync(
|
|
119
|
+
buffer => {
|
|
120
|
+
return unzipBufferToTarget(
|
|
121
|
+
buffer,
|
|
122
|
+
targetPath);
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Unzip a remote zip file to a directory.
|
|
128
|
+
* Equivalent to `unzip -o <zipFilePath> -d <targetPath>
|
|
129
|
+
*
|
|
130
|
+
* Use [fflate](https://github.com/101arrowz/fflate) as the unzip backend.
|
|
131
|
+
* @param zipFileUrl - Zip file url.
|
|
132
|
+
* @param targetPath - The directory to unzip to.
|
|
133
|
+
* @param requestInit - Optional request initialization parameters.
|
|
134
|
+
* @returns A promise that resolves to an `AsyncIOResult`
|
|
135
|
+
* indicating whether the zip file was successfully unzipped.
|
|
136
|
+
*/
|
|
137
|
+
export
|
|
138
|
+
async function
|
|
139
|
+
unzipFromUrl(
|
|
140
|
+
zipFileUrl:
|
|
141
|
+
string,
|
|
142
|
+
targetPath:
|
|
143
|
+
string,
|
|
144
|
+
requestInit?:
|
|
145
|
+
FsRequestInit):
|
|
146
|
+
AsyncVoidIOResult {
|
|
147
|
+
assertFileUrl(
|
|
148
|
+
zipFileUrl);
|
|
149
|
+
assertAbsolutePath(
|
|
150
|
+
targetPath);
|
|
151
|
+
const
|
|
152
|
+
fetchRes =
|
|
153
|
+
await fetchT(
|
|
154
|
+
zipFileUrl,
|
|
155
|
+
{ redirect:
|
|
156
|
+
'follow',
|
|
157
|
+
...requestInit,
|
|
158
|
+
responseType:
|
|
159
|
+
'arraybuffer',
|
|
160
|
+
abortable:
|
|
161
|
+
false });
|
|
162
|
+
return fetchRes.andThenAsync(
|
|
163
|
+
buffer => {
|
|
164
|
+
return unzipBufferToTarget(
|
|
165
|
+
buffer,
|
|
166
|
+
targetPath);
|
|
167
|
+
});
|
|
168
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
|
+
|
|
3
|
+
/** ----------------------------------------------------------------------
|
|
4
|
+
* Copyright ©
|
|
5
|
+
* Jiang Jie
|
|
6
|
+
* 2024, 2025
|
|
7
|
+
* Pellegrino Prevete
|
|
8
|
+
* 2025
|
|
9
|
+
*
|
|
10
|
+
* All rights reserved
|
|
11
|
+
* ----------------------------------------------------------------------
|
|
12
|
+
*
|
|
13
|
+
* This program is free software: you can redistribute it and/or modify
|
|
14
|
+
* it under the terms of the GNU General Public License as published by
|
|
15
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
16
|
+
* (at your option) any later version.
|
|
17
|
+
*
|
|
18
|
+
* This program is distributed in the hope that it will be useful,
|
|
19
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
20
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
21
|
+
* GNU General Public License for more details.
|
|
22
|
+
*
|
|
23
|
+
* You should have received a copy of the GNU General Public License
|
|
24
|
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import { fetchT,
|
|
28
|
+
type FetchResponse,
|
|
29
|
+
type FetchTask } from '@happy-ts/fetch-t';
|
|
30
|
+
import { basename } from '@std/path/posix';
|
|
31
|
+
import { Err } from 'happy-rusty';
|
|
32
|
+
import { assertFileUrl } from './assertions.ts';
|
|
33
|
+
import type { UploadRequestInit } from './defines.ts';
|
|
34
|
+
import { createAbortError } from './helpers.ts';
|
|
35
|
+
import { readBlobFile } from './opfs_ext.ts';
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Uploads a file from the specified path to a URL.
|
|
39
|
+
*
|
|
40
|
+
* @param filePath - The path of the file to upload.
|
|
41
|
+
* @param fileUrl - The URL where the file will be uploaded.
|
|
42
|
+
* @param requestInit - Optional request initialization parameters.
|
|
43
|
+
* @returns A promise that resolves to an `AsyncIOResult`
|
|
44
|
+
* indicating whether the file was successfully uploaded.
|
|
45
|
+
*/
|
|
46
|
+
export function
|
|
47
|
+
uploadFile(
|
|
48
|
+
filePath:
|
|
49
|
+
string,
|
|
50
|
+
fileUrl:
|
|
51
|
+
string,
|
|
52
|
+
requestInit?:
|
|
53
|
+
UploadRequestInit):
|
|
54
|
+
FetchTask<Response> {
|
|
55
|
+
type T =
|
|
56
|
+
Response;
|
|
57
|
+
let
|
|
58
|
+
aborted:
|
|
59
|
+
boolean;
|
|
60
|
+
let
|
|
61
|
+
fetchTask:
|
|
62
|
+
FetchTask<T>;
|
|
63
|
+
assertFileUrl(
|
|
64
|
+
fileUrl);
|
|
65
|
+
aborted =
|
|
66
|
+
false;
|
|
67
|
+
const
|
|
68
|
+
response =
|
|
69
|
+
( async ():
|
|
70
|
+
FetchResponse<Response> => {
|
|
71
|
+
const
|
|
72
|
+
fileRes =
|
|
73
|
+
await readBlobFile(
|
|
74
|
+
filePath);
|
|
75
|
+
return fileRes.andThenAsync(
|
|
76
|
+
async file => {
|
|
77
|
+
// maybe aborted
|
|
78
|
+
if ( aborted ) {
|
|
79
|
+
return Err(
|
|
80
|
+
createAbortError());
|
|
81
|
+
}
|
|
82
|
+
const
|
|
83
|
+
{ // default file name
|
|
84
|
+
filename = basename(filePath),
|
|
85
|
+
...rest } =
|
|
86
|
+
requestInit ??
|
|
87
|
+
{};
|
|
88
|
+
const
|
|
89
|
+
formData =
|
|
90
|
+
new FormData();
|
|
91
|
+
formData.append(
|
|
92
|
+
filename,
|
|
93
|
+
file,
|
|
94
|
+
filename);
|
|
95
|
+
fetchTask =
|
|
96
|
+
fetchT(
|
|
97
|
+
fileUrl,
|
|
98
|
+
{ method:
|
|
99
|
+
'POST',
|
|
100
|
+
...rest,
|
|
101
|
+
abortable:
|
|
102
|
+
true,
|
|
103
|
+
body:
|
|
104
|
+
formData });
|
|
105
|
+
return fetchTask.response;
|
|
106
|
+
});
|
|
107
|
+
})();
|
|
108
|
+
return {
|
|
109
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
110
|
+
abort(reason?: any):
|
|
111
|
+
void {
|
|
112
|
+
aborted =
|
|
113
|
+
true;
|
|
114
|
+
fetchTask?.abort(
|
|
115
|
+
reason);
|
|
116
|
+
},
|
|
117
|
+
get aborted():
|
|
118
|
+
boolean {
|
|
119
|
+
return aborted;
|
|
120
|
+
},
|
|
121
|
+
get response():
|
|
122
|
+
FetchResponse<Response> {
|
|
123
|
+
return response;
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
}
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
|
+
|
|
3
|
+
/** ----------------------------------------------------------------------
|
|
4
|
+
* Copyright ©
|
|
5
|
+
* Jiang Jie
|
|
6
|
+
* 2024, 2025
|
|
7
|
+
* Pellegrino Prevete
|
|
8
|
+
* 2025
|
|
9
|
+
*
|
|
10
|
+
* All rights reserved
|
|
11
|
+
* ----------------------------------------------------------------------
|
|
12
|
+
*
|
|
13
|
+
* This program is free software: you can redistribute it and/or modify
|
|
14
|
+
* it under the terms of the GNU General Public License as published by
|
|
15
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
16
|
+
* (at your option) any later version.
|
|
17
|
+
*
|
|
18
|
+
* This program is distributed in the hope that it will be useful,
|
|
19
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
20
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
21
|
+
* GNU General Public License for more details.
|
|
22
|
+
*
|
|
23
|
+
* You should have received a copy of the GNU General Public License
|
|
24
|
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import { fetchT } from '@happy-ts/fetch-t';
|
|
28
|
+
import { basename,
|
|
29
|
+
join } from '@std/path/posix';
|
|
30
|
+
import * as fflate from 'fflate/browser';
|
|
31
|
+
import { Err,
|
|
32
|
+
Ok,
|
|
33
|
+
type AsyncIOResult,
|
|
34
|
+
type AsyncVoidIOResult,
|
|
35
|
+
type IOResult } from 'happy-rusty';
|
|
36
|
+
import { Future } from 'tiny-future';
|
|
37
|
+
import { assertAbsolutePath,
|
|
38
|
+
assertFileUrl } from './assertions.ts';
|
|
39
|
+
import type { FsRequestInit,
|
|
40
|
+
ZipOptions } from './defines.ts';
|
|
41
|
+
import { readDir,
|
|
42
|
+
stat,
|
|
43
|
+
writeFile } from './opfs_core.ts';
|
|
44
|
+
import { getFileDataByHandle,
|
|
45
|
+
isFileHandle } from './utils.ts';
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Zip a zippable data then write to the target path.
|
|
49
|
+
* @param zippable - Zippable data.
|
|
50
|
+
* @param zipFilePath - Target zip file path.
|
|
51
|
+
*/
|
|
52
|
+
async function
|
|
53
|
+
zipTo<T>(
|
|
54
|
+
zippable:
|
|
55
|
+
fflate.AsyncZippable,
|
|
56
|
+
zipFilePath?:
|
|
57
|
+
string):
|
|
58
|
+
AsyncIOResult<T> {
|
|
59
|
+
const
|
|
60
|
+
future =
|
|
61
|
+
new Future<IOResult<T>>();
|
|
62
|
+
fflate.zip(
|
|
63
|
+
zippable,
|
|
64
|
+
{ consume:
|
|
65
|
+
true },
|
|
66
|
+
async (err,
|
|
67
|
+
u8a) => {
|
|
68
|
+
if ( err ) {
|
|
69
|
+
future.resolve(
|
|
70
|
+
Err(
|
|
71
|
+
err));
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
// whether to write to file
|
|
75
|
+
if ( zipFilePath ) {
|
|
76
|
+
const
|
|
77
|
+
res =
|
|
78
|
+
await writeFile(
|
|
79
|
+
zipFilePath,
|
|
80
|
+
u8a);
|
|
81
|
+
future.resolve(
|
|
82
|
+
res as IOResult<T>);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
future.resolve(
|
|
86
|
+
Ok( u8a as T ));
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
return await future.promise;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Zip a file or directory and write to a zip file.
|
|
94
|
+
* Equivalent to `zip -r <zipFilePath> <targetPath>`.
|
|
95
|
+
*
|
|
96
|
+
* Use [fflate](https://github.com/101arrowz/fflate) as the zip backend.
|
|
97
|
+
* @param sourcePath - The path to be zipped.
|
|
98
|
+
* @param zipFilePath - The path to the zip file.
|
|
99
|
+
* @param options - Options of zip.
|
|
100
|
+
* @returns A promise that resolves to an `AsyncIOResult`
|
|
101
|
+
* indicating whether the source was successfully zipped.
|
|
102
|
+
*/
|
|
103
|
+
export
|
|
104
|
+
async function
|
|
105
|
+
zip(
|
|
106
|
+
sourcePath:
|
|
107
|
+
string,
|
|
108
|
+
zipFilePath:
|
|
109
|
+
string,
|
|
110
|
+
options?:
|
|
111
|
+
ZipOptions):
|
|
112
|
+
AsyncVoidIOResult;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Zip a file or directory and return the zip file data.
|
|
116
|
+
* Equivalent to `zip -r <zipFilePath> <targetPath>`.
|
|
117
|
+
*
|
|
118
|
+
* Use [fflate](https://github.com/101arrowz/fflate) as the zip backend.
|
|
119
|
+
* @param sourcePath - The path to be zipped.
|
|
120
|
+
* @param options - Options of zip.
|
|
121
|
+
* @returns A promise that resolves to an `AsyncIOResult` indicating
|
|
122
|
+
* whether the source was successfully zipped.
|
|
123
|
+
*/
|
|
124
|
+
export
|
|
125
|
+
async function
|
|
126
|
+
zip(
|
|
127
|
+
sourcePath:
|
|
128
|
+
string,
|
|
129
|
+
options?:
|
|
130
|
+
ZipOptions):
|
|
131
|
+
AsyncIOResult<Uint8Array>;
|
|
132
|
+
export
|
|
133
|
+
async function
|
|
134
|
+
zip<T>(
|
|
135
|
+
sourcePath:
|
|
136
|
+
string,
|
|
137
|
+
zipFilePath?:
|
|
138
|
+
string |
|
|
139
|
+
ZipOptions,
|
|
140
|
+
options?:
|
|
141
|
+
ZipOptions):
|
|
142
|
+
AsyncIOResult<T> {
|
|
143
|
+
if ( typeof zipFilePath === 'string' ) {
|
|
144
|
+
assertAbsolutePath(
|
|
145
|
+
zipFilePath);
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
options =
|
|
149
|
+
zipFilePath;
|
|
150
|
+
zipFilePath =
|
|
151
|
+
undefined;
|
|
152
|
+
}
|
|
153
|
+
const
|
|
154
|
+
statRes =
|
|
155
|
+
await stat(
|
|
156
|
+
sourcePath);
|
|
157
|
+
return statRes.andThenAsync(
|
|
158
|
+
async handle => {
|
|
159
|
+
const
|
|
160
|
+
sourceName =
|
|
161
|
+
basename(
|
|
162
|
+
sourcePath);
|
|
163
|
+
const
|
|
164
|
+
zippable:
|
|
165
|
+
fflate.AsyncZippable =
|
|
166
|
+
{};
|
|
167
|
+
if ( isFileHandle(
|
|
168
|
+
handle) ) {
|
|
169
|
+
// file
|
|
170
|
+
const
|
|
171
|
+
data =
|
|
172
|
+
await getFileDataByHandle(
|
|
173
|
+
handle);
|
|
174
|
+
zippable[
|
|
175
|
+
sourceName] =
|
|
176
|
+
data;
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
// directory
|
|
180
|
+
const
|
|
181
|
+
readDirRes =
|
|
182
|
+
await readDir(
|
|
183
|
+
sourcePath,
|
|
184
|
+
{ recursive:
|
|
185
|
+
true });
|
|
186
|
+
if ( readDirRes.isErr() ) {
|
|
187
|
+
return readDirRes.asErr();
|
|
188
|
+
}
|
|
189
|
+
// default to preserve root
|
|
190
|
+
const
|
|
191
|
+
preserveRoot =
|
|
192
|
+
options?.preserveRoot ??
|
|
193
|
+
true;
|
|
194
|
+
for await ( const { path,
|
|
195
|
+
handle } of readDirRes.unwrap()) {
|
|
196
|
+
// path
|
|
197
|
+
if ( isFileHandle(
|
|
198
|
+
handle) ) {
|
|
199
|
+
const
|
|
200
|
+
entryName =
|
|
201
|
+
preserveRoot ?
|
|
202
|
+
join(
|
|
203
|
+
sourceName,
|
|
204
|
+
path) :
|
|
205
|
+
path;
|
|
206
|
+
const
|
|
207
|
+
data =
|
|
208
|
+
await getFileDataByHandle(
|
|
209
|
+
handle);
|
|
210
|
+
zippable[
|
|
211
|
+
entryName] =
|
|
212
|
+
data;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return zipTo(
|
|
217
|
+
zippable,
|
|
218
|
+
zipFilePath);
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Zip a remote file and write to a zip file.
|
|
224
|
+
*
|
|
225
|
+
* Use [fflate](https://github.com/101arrowz/fflate) as the zip backend.
|
|
226
|
+
* @param sourceUrl - The url to be zipped.
|
|
227
|
+
* @param zipFilePath - The path to the zip file.
|
|
228
|
+
* @param requestInit - Optional request initialization parameters.
|
|
229
|
+
* @returns A promise that resolves to an `AsyncIOResult`
|
|
230
|
+
* indicating whether the source was successfully zipped.
|
|
231
|
+
*/
|
|
232
|
+
export
|
|
233
|
+
async function
|
|
234
|
+
zipFromUrl(
|
|
235
|
+
sourceUrl:
|
|
236
|
+
string,
|
|
237
|
+
zipFilePath:
|
|
238
|
+
string,
|
|
239
|
+
requestInit?:
|
|
240
|
+
FsRequestInit):
|
|
241
|
+
AsyncVoidIOResult;
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Zip a remote file and return the zip file data.
|
|
245
|
+
*
|
|
246
|
+
* Use [fflate](https://github.com/101arrowz/fflate) as the zip backend.
|
|
247
|
+
* @param sourceUrl - The url to be zipped.
|
|
248
|
+
* @param requestInit - Optional request initialization parameters.
|
|
249
|
+
* @returns A promise that resolves to an `AsyncIOResult` indicating
|
|
250
|
+
* whether the source was successfully zipped.
|
|
251
|
+
*/
|
|
252
|
+
export
|
|
253
|
+
async function
|
|
254
|
+
zipFromUrl(
|
|
255
|
+
sourceUrl:
|
|
256
|
+
string,
|
|
257
|
+
requestInit?:
|
|
258
|
+
FsRequestInit):
|
|
259
|
+
AsyncIOResult<Uint8Array>;
|
|
260
|
+
|
|
261
|
+
export
|
|
262
|
+
async function
|
|
263
|
+
zipFromUrl<T>(
|
|
264
|
+
sourceUrl:
|
|
265
|
+
string,
|
|
266
|
+
zipFilePath?:
|
|
267
|
+
string |
|
|
268
|
+
FsRequestInit,
|
|
269
|
+
requestInit?:
|
|
270
|
+
FsRequestInit):
|
|
271
|
+
AsyncIOResult<T> {
|
|
272
|
+
assertFileUrl(
|
|
273
|
+
sourceUrl);
|
|
274
|
+
if ( typeof zipFilePath === 'string' ) {
|
|
275
|
+
assertAbsolutePath(
|
|
276
|
+
zipFilePath);
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
requestInit =
|
|
280
|
+
zipFilePath;
|
|
281
|
+
zipFilePath =
|
|
282
|
+
undefined;
|
|
283
|
+
}
|
|
284
|
+
const
|
|
285
|
+
fetchRes =
|
|
286
|
+
await fetchT(
|
|
287
|
+
sourceUrl,
|
|
288
|
+
{ redirect:
|
|
289
|
+
'follow',
|
|
290
|
+
...requestInit,
|
|
291
|
+
responseType:
|
|
292
|
+
'arraybuffer',
|
|
293
|
+
abortable:
|
|
294
|
+
false,
|
|
295
|
+
});
|
|
296
|
+
return fetchRes.andThenAsync(
|
|
297
|
+
buffer => {
|
|
298
|
+
const
|
|
299
|
+
sourceName =
|
|
300
|
+
basename(
|
|
301
|
+
sourceUrl);
|
|
302
|
+
const
|
|
303
|
+
zippable:
|
|
304
|
+
fflate.AsyncZippable =
|
|
305
|
+
{};
|
|
306
|
+
zippable[
|
|
307
|
+
sourceName] =
|
|
308
|
+
new Uint8Array(
|
|
309
|
+
buffer);
|
|
310
|
+
return zipTo(
|
|
311
|
+
zippable,
|
|
312
|
+
zipFilePath);
|
|
313
|
+
});
|
|
314
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
|
+
|
|
3
|
+
/** ----------------------------------------------------------------------
|
|
4
|
+
* Copyright ©
|
|
5
|
+
* Jiang Jie
|
|
6
|
+
* 2024, 2025
|
|
7
|
+
* Pellegrino Prevete
|
|
8
|
+
* 2025
|
|
9
|
+
*
|
|
10
|
+
* All rights reserved
|
|
11
|
+
* ----------------------------------------------------------------------
|
|
12
|
+
*
|
|
13
|
+
* This program is free software: you can redistribute it and/or modify
|
|
14
|
+
* it under the terms of the GNU General Public License as published by
|
|
15
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
16
|
+
* (at your option) any later version.
|
|
17
|
+
*
|
|
18
|
+
* This program is distributed in the hope that it will be useful,
|
|
19
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
20
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
21
|
+
* GNU General Public License for more details.
|
|
22
|
+
*
|
|
23
|
+
* You should have received a copy of the GNU General Public License
|
|
24
|
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Checks if the Origin Private File System (OPFS) is supported in the current environment.
|
|
29
|
+
*
|
|
30
|
+
* @returns A boolean indicating whether OPFS is supported.
|
|
31
|
+
*/
|
|
32
|
+
export function
|
|
33
|
+
isOPFSSupported():
|
|
34
|
+
boolean {
|
|
35
|
+
return typeof navigator?.storage?.getDirectory === 'function';
|
|
36
|
+
}
|