@mad-c/file-system-helpers 1.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/LICENSE +504 -0
- package/README.md +3 -0
- package/dist/fs-access.d.ts +14 -0
- package/dist/fs-access.js +103 -0
- package/dist/opfs.d.ts +247 -0
- package/dist/opfs.js +283 -0
- package/dist/path.d.ts +56 -0
- package/dist/path.js +180 -0
- package/dist/permissions.d.ts +14 -0
- package/dist/permissions.js +25 -0
- package/package.json +48 -0
package/dist/opfs.d.ts
ADDED
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
export interface GetDirHandleOptions {
|
|
2
|
+
/** Creates the directory structure if it doesn't exist. Throws an error otherwise */
|
|
3
|
+
recursive?: boolean;
|
|
4
|
+
/**
|
|
5
|
+
* The file system root directory to resolve against. If not provided the Origin Private File System root will be used.
|
|
6
|
+
*
|
|
7
|
+
* {@link https://developer.mozilla.org/en-US/docs/Web/API/File_System_API#origin_private_file_system|MDN Reference}
|
|
8
|
+
*/
|
|
9
|
+
rootDir?: FileSystemDirectoryHandle;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Gets the directory handle for a given path.
|
|
13
|
+
*
|
|
14
|
+
* @param path The path to get a directory handle.
|
|
15
|
+
* @param options The options for function.
|
|
16
|
+
*/
|
|
17
|
+
export declare function getDirHandle(path: string, { rootDir, recursive }?: GetDirHandleOptions): Promise<FileSystemDirectoryHandle>;
|
|
18
|
+
/**
|
|
19
|
+
* Resolves the parent item for this path or handle.
|
|
20
|
+
*
|
|
21
|
+
* If the root of the file system is passed, it returns the root itself.
|
|
22
|
+
*
|
|
23
|
+
* @param pathOrHandle A path string or a {@link FileSystemHandle}
|
|
24
|
+
* @param options The options for function.
|
|
25
|
+
*/
|
|
26
|
+
export declare function resolveParentHandle(pathOrHandle: string | FileSystemHandle, { recursive, rootDir }?: GetDirHandleOptions): Promise<{
|
|
27
|
+
parentHandle: FileSystemDirectoryHandle;
|
|
28
|
+
parentPath: string;
|
|
29
|
+
name: string;
|
|
30
|
+
}>;
|
|
31
|
+
export interface GetFileHandleOptions {
|
|
32
|
+
/** Creates the file if it doesn't exist. Throws an error otherwise */
|
|
33
|
+
touch?: boolean;
|
|
34
|
+
/** Creates the directory structure if it doesn't exist. Throws an error otherwise */
|
|
35
|
+
recursive?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* The file system root directory to resolve against. If not provided the Origin Private File System root will be used.
|
|
38
|
+
*
|
|
39
|
+
* {@link https://developer.mozilla.org/en-US/docs/Web/API/File_System_API#origin_private_file_system|MDN Reference}
|
|
40
|
+
*/
|
|
41
|
+
rootDir?: FileSystemDirectoryHandle;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Gets a file handle for a given path. Optionally creating the file if it doesn't exist.
|
|
45
|
+
*
|
|
46
|
+
* @param path A path string for the file.
|
|
47
|
+
* @param options The options for function.
|
|
48
|
+
*/
|
|
49
|
+
export declare function getFileHandle(path: string, { touch, recursive, rootDir }?: GetFileHandleOptions): Promise<FileSystemFileHandle>;
|
|
50
|
+
export interface CheckDirExistsOptions {
|
|
51
|
+
/**
|
|
52
|
+
* The file system root directory to resolve against. If not provided the Origin Private File System root will be used.
|
|
53
|
+
*
|
|
54
|
+
* {@link https://developer.mozilla.org/en-US/docs/Web/API/File_System_API#origin_private_file_system|MDN Reference}
|
|
55
|
+
*/
|
|
56
|
+
rootDir?: FileSystemDirectoryHandle;
|
|
57
|
+
}
|
|
58
|
+
export declare function checkDirExists(path: string, { rootDir }?: CheckDirExistsOptions): Promise<boolean>;
|
|
59
|
+
export interface CheckFileExistsOptions {
|
|
60
|
+
/**
|
|
61
|
+
* The file system root directory to resolve against. If not provided the Origin Private File System root will be used.
|
|
62
|
+
*
|
|
63
|
+
* {@link https://developer.mozilla.org/en-US/docs/Web/API/File_System_API#origin_private_file_system|MDN Reference}
|
|
64
|
+
*/
|
|
65
|
+
rootDir?: FileSystemDirectoryHandle;
|
|
66
|
+
}
|
|
67
|
+
export declare function checkFileExists(path: string, { rootDir }?: CheckFileExistsOptions): Promise<boolean>;
|
|
68
|
+
export interface ListDirEntriesOptions {
|
|
69
|
+
/** The depth to recurse on the directory tree. It defaults to 0 */
|
|
70
|
+
depth?: number;
|
|
71
|
+
/**
|
|
72
|
+
* The file system root directory to resolve against. If not provided the Origin Private File System root will be used.
|
|
73
|
+
*
|
|
74
|
+
* {@link https://developer.mozilla.org/en-US/docs/Web/API/File_System_API#origin_private_file_system|MDN Reference}
|
|
75
|
+
*/
|
|
76
|
+
rootDir?: FileSystemDirectoryHandle;
|
|
77
|
+
}
|
|
78
|
+
export interface FileSystemEntry {
|
|
79
|
+
name: string;
|
|
80
|
+
handle: FileSystemHandle;
|
|
81
|
+
children?: FileSystemEntry[];
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Lists the directory contents recursivelly up to the `depth` provided.
|
|
85
|
+
*
|
|
86
|
+
* It returns an array of items, if the item have children and the depth is not exceeded, the children property will be filled.
|
|
87
|
+
*
|
|
88
|
+
* @param pathOrHandle A path string or a {@link FileSystemHandle}
|
|
89
|
+
* @param options The options for function.
|
|
90
|
+
*/
|
|
91
|
+
export declare function listDirEntries(pathOrHandle: string | FileSystemDirectoryHandle, { depth, rootDir }?: ListDirEntriesOptions): Promise<FileSystemEntry[]>;
|
|
92
|
+
export interface WriteFileHandleOptions {
|
|
93
|
+
/** Creates the directory structure if it doesn't exist. Throws an error otherwise */
|
|
94
|
+
recursive?: boolean;
|
|
95
|
+
/** Overwrites the file if it exists. */
|
|
96
|
+
overwrite?: boolean;
|
|
97
|
+
/**
|
|
98
|
+
* The file system root directory to resolve against. If not provided the Origin Private File System root will be used.
|
|
99
|
+
*
|
|
100
|
+
* {@link https://developer.mozilla.org/en-US/docs/Web/API/File_System_API#origin_private_file_system|MDN Reference}
|
|
101
|
+
*/
|
|
102
|
+
rootDir?: FileSystemDirectoryHandle;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Write data to a file, overwriting existing data.
|
|
106
|
+
*
|
|
107
|
+
* @param pathOrHandle A path string or a {@link FileSystemHandle}
|
|
108
|
+
* @param data The data to write to the file.
|
|
109
|
+
* @param options The options for function.
|
|
110
|
+
*/
|
|
111
|
+
export declare function writeFile(pathOrHandle: string | FileSystemFileHandle, data: FileSystemWriteChunkType, { recursive, rootDir, overwrite }?: WriteFileHandleOptions): Promise<void>;
|
|
112
|
+
export interface AppendFileHandleOptions {
|
|
113
|
+
/** Creates the directory structure if it doesn't exist. Throws an error otherwise */
|
|
114
|
+
recursive?: boolean;
|
|
115
|
+
/**
|
|
116
|
+
* The file system root directory to resolve against. If not provided the Origin Private File System root will be used.
|
|
117
|
+
*
|
|
118
|
+
* {@link https://developer.mozilla.org/en-US/docs/Web/API/File_System_API#origin_private_file_system|MDN Reference}
|
|
119
|
+
*/
|
|
120
|
+
rootDir?: FileSystemDirectoryHandle;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Appends data to the end of a file.
|
|
124
|
+
*
|
|
125
|
+
* @param pathOrHandle A path string or a {@link FileSystemHandle}
|
|
126
|
+
* @param data The data to append to the file.
|
|
127
|
+
* @param options The options for function.
|
|
128
|
+
*/
|
|
129
|
+
export declare function appendFile(pathOrHandle: string | FileSystemFileHandle, data: FileSystemWriteChunkType, { recursive, rootDir }?: AppendFileHandleOptions): Promise<void>;
|
|
130
|
+
export interface RemoveDirOptions {
|
|
131
|
+
/**
|
|
132
|
+
* If the directory has children and this is set to `true`, removes the children.
|
|
133
|
+
* If it is set to `false` and the directory has children, throws an error.
|
|
134
|
+
* If the directory has no children, this has no effect.
|
|
135
|
+
*/
|
|
136
|
+
recursive?: boolean;
|
|
137
|
+
/**
|
|
138
|
+
* The file system root directory to resolve against. If not provided the Origin Private File System root will be used.
|
|
139
|
+
*
|
|
140
|
+
* {@link https://developer.mozilla.org/en-US/docs/Web/API/File_System_API#origin_private_file_system|MDN Reference}
|
|
141
|
+
*/
|
|
142
|
+
rootDir?: FileSystemDirectoryHandle;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Deletes a directory, optionally also deleting it's contents recursivelly.
|
|
146
|
+
*
|
|
147
|
+
* If the directory is the root of the file system, all children will be deleted but the root directory itself will be kept.
|
|
148
|
+
*
|
|
149
|
+
* @param pathOrHandle A path string or a {@link FileSystemHandle}
|
|
150
|
+
* @param options The options for function.
|
|
151
|
+
*/
|
|
152
|
+
export declare function removeDir(pathOrHandle: string | FileSystemDirectoryHandle, { recursive, rootDir }: RemoveDirOptions): Promise<void>;
|
|
153
|
+
export interface RemoveFileOptions {
|
|
154
|
+
/**
|
|
155
|
+
* The file system root directory to resolve against. If not provided the Origin Private File System root will be used.
|
|
156
|
+
*
|
|
157
|
+
* {@link https://developer.mozilla.org/en-US/docs/Web/API/File_System_API#origin_private_file_system|MDN Reference}
|
|
158
|
+
*/
|
|
159
|
+
rootDir?: FileSystemDirectoryHandle;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Deletes a file.
|
|
163
|
+
*
|
|
164
|
+
* @param pathOrHandle A path string or a {@link FileSystemHandle}
|
|
165
|
+
* @param options The options for function.
|
|
166
|
+
*/
|
|
167
|
+
export declare function removeFile(pathOrHandle: string | FileSystemFileHandle, { rootDir }?: RemoveFileOptions): Promise<void>;
|
|
168
|
+
export interface CopyDirOptions {
|
|
169
|
+
/** Creates the destination directory structure if it doesn't exist. Throws an error otherwise */
|
|
170
|
+
recursive?: boolean;
|
|
171
|
+
/** Overwrites existing files in the destination. */
|
|
172
|
+
overwrite?: boolean;
|
|
173
|
+
/**
|
|
174
|
+
* The file system root directory to resolve against. If not provided the Origin Private File System root will be used.
|
|
175
|
+
*
|
|
176
|
+
* {@link https://developer.mozilla.org/en-US/docs/Web/API/File_System_API#origin_private_file_system|MDN Reference}
|
|
177
|
+
*/
|
|
178
|
+
rootDir?: FileSystemDirectoryHandle;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Copies a directory from one location to another.
|
|
182
|
+
*
|
|
183
|
+
* @param sourcePathOrHandle The path string or a {@link FileSystemDirectoryHandle} for the source directory.
|
|
184
|
+
* @param destinationPathOrHandle The path string or a {@link FileSystemDirectoryHandle} for the destination directory.
|
|
185
|
+
* @param options The options for function.
|
|
186
|
+
*/
|
|
187
|
+
export declare function copyDir(sourcePathOrHandle: string | FileSystemDirectoryHandle, destinationPathOrHandle: string | FileSystemDirectoryHandle, { overwrite, rootDir, recursive }?: CopyDirOptions): Promise<void>;
|
|
188
|
+
export interface CopyFileOptions {
|
|
189
|
+
/** Creates the destination directory structure if it doesn't exist. Throws an error otherwise */
|
|
190
|
+
recursive?: boolean;
|
|
191
|
+
/** Overwrites the file in the destination if it already exists. */
|
|
192
|
+
overwrite?: boolean;
|
|
193
|
+
/**
|
|
194
|
+
* The file system root directory to resolve against. If not provided the Origin Private File System root will be used.
|
|
195
|
+
*
|
|
196
|
+
* {@link https://developer.mozilla.org/en-US/docs/Web/API/File_System_API#origin_private_file_system|MDN Reference}
|
|
197
|
+
*/
|
|
198
|
+
rootDir?: FileSystemDirectoryHandle;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Copies a file from one location to another.
|
|
202
|
+
*
|
|
203
|
+
* @param sourcePathOrHandle The path string or a {@link FileSystemDirectoryHandle} for the source file.
|
|
204
|
+
* @param destinationPathOrHandle The path string or a {@link FileSystemDirectoryHandle} for the destination file.
|
|
205
|
+
* @param options The options for function.
|
|
206
|
+
*/
|
|
207
|
+
export declare function copyFile(sourcePathOrHandle: string | FileSystemFileHandle, destinationPathOrHandle: string | FileSystemFileHandle, { overwrite, rootDir, recursive }?: CopyDirOptions): Promise<void>;
|
|
208
|
+
export interface MoveDirOptions {
|
|
209
|
+
/** Creates the destination directory structure if it doesn't exist. Throws an error otherwise */
|
|
210
|
+
recursive?: boolean;
|
|
211
|
+
/** Overwrites existing files in the destination. */
|
|
212
|
+
overwrite?: boolean;
|
|
213
|
+
/**
|
|
214
|
+
* The file system root directory to resolve against. If not provided the Origin Private File System root will be used.
|
|
215
|
+
*
|
|
216
|
+
* {@link https://developer.mozilla.org/en-US/docs/Web/API/File_System_API#origin_private_file_system|MDN Reference}
|
|
217
|
+
*/
|
|
218
|
+
rootDir?: FileSystemDirectoryHandle;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Moves a directory from one location to another.
|
|
222
|
+
*
|
|
223
|
+
* @param sourcePathOrHandle The path string or a {@link FileSystemDirectoryHandle} for the source directory.
|
|
224
|
+
* @param destinationPathOrHandle The path string or a {@link FileSystemDirectoryHandle} for the destination directory.
|
|
225
|
+
* @param options The options for function.
|
|
226
|
+
*/
|
|
227
|
+
export declare function moveDir(sourcePathOrHandle: string | FileSystemDirectoryHandle, destinationPathOrHandle: string | FileSystemDirectoryHandle, { overwrite, rootDir, recursive }?: CopyDirOptions): Promise<void>;
|
|
228
|
+
export interface MoveFileOptions {
|
|
229
|
+
/** Creates the destination directory structure if it doesn't exist. Throws an error otherwise */
|
|
230
|
+
recursive?: boolean;
|
|
231
|
+
/** Overwrites the file in the destination if it already exists. */
|
|
232
|
+
overwrite?: boolean;
|
|
233
|
+
/**
|
|
234
|
+
* The file system root directory to resolve against. If not provided the Origin Private File System root will be used.
|
|
235
|
+
*
|
|
236
|
+
* {@link https://developer.mozilla.org/en-US/docs/Web/API/File_System_API#origin_private_file_system|MDN Reference}
|
|
237
|
+
*/
|
|
238
|
+
rootDir?: FileSystemDirectoryHandle;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Moves a file from one location to another.
|
|
242
|
+
*
|
|
243
|
+
* @param sourcePathOrHandle The path string or a {@link FileSystemDirectoryHandle} for the source file.
|
|
244
|
+
* @param destinationPathOrHandle The path string or a {@link FileSystemDirectoryHandle} for the destination file.
|
|
245
|
+
* @param options The options for function.
|
|
246
|
+
*/
|
|
247
|
+
export declare function moveFile(sourcePathOrHandle: string | FileSystemFileHandle, destinationPathOrHandle: string | FileSystemFileHandle, { overwrite, rootDir, recursive }?: CopyDirOptions): Promise<void>;
|
package/dist/opfs.js
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
// oxlint-disable max-lines
|
|
2
|
+
import { basename, dirname, pathToSegments, resolve } from "./path.js";
|
|
3
|
+
import { requestHandlePermissions } from "./permissions.js";
|
|
4
|
+
/**
|
|
5
|
+
* Gets the directory handle for a given path.
|
|
6
|
+
*
|
|
7
|
+
* @param path The path to get a directory handle.
|
|
8
|
+
* @param options The options for function.
|
|
9
|
+
*/
|
|
10
|
+
export async function getDirHandle(path, { rootDir, recursive } = {}) {
|
|
11
|
+
const segments = pathToSegments(resolve(path));
|
|
12
|
+
let currentDirHandle = rootDir ?? await navigator.storage.getDirectory();
|
|
13
|
+
await requestHandlePermissions(currentDirHandle, 'read');
|
|
14
|
+
for (const segment of segments) {
|
|
15
|
+
// oxlint-disable-next-line no-await-in-loop
|
|
16
|
+
currentDirHandle = await currentDirHandle.getDirectoryHandle(segment, { create: recursive });
|
|
17
|
+
// oxlint-disable-next-line no-await-in-loop
|
|
18
|
+
await requestHandlePermissions(currentDirHandle, 'read');
|
|
19
|
+
}
|
|
20
|
+
return currentDirHandle;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Resolves the parent item for this path or handle.
|
|
24
|
+
*
|
|
25
|
+
* If the root of the file system is passed, it returns the root itself.
|
|
26
|
+
*
|
|
27
|
+
* @param pathOrHandle A path string or a {@link FileSystemHandle}
|
|
28
|
+
* @param options The options for function.
|
|
29
|
+
*/
|
|
30
|
+
export async function resolveParentHandle(pathOrHandle, { recursive, rootDir } = {}) {
|
|
31
|
+
const resolvedRootDir = rootDir ?? await navigator.storage.getDirectory();
|
|
32
|
+
let resolvedPath;
|
|
33
|
+
if (typeof pathOrHandle === 'string') {
|
|
34
|
+
resolvedPath = resolve(pathOrHandle);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
resolvedPath = resolve((await resolvedRootDir.resolve(pathOrHandle) ?? []).join('/'));
|
|
38
|
+
}
|
|
39
|
+
const parentDirPath = dirname(resolvedPath);
|
|
40
|
+
const parentDirHandle = await getDirHandle(parentDirPath, { rootDir, recursive });
|
|
41
|
+
return {
|
|
42
|
+
parentHandle: parentDirHandle,
|
|
43
|
+
parentPath: parentDirPath,
|
|
44
|
+
name: basename(resolvedPath)
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Gets a file handle for a given path. Optionally creating the file if it doesn't exist.
|
|
49
|
+
*
|
|
50
|
+
* @param path A path string for the file.
|
|
51
|
+
* @param options The options for function.
|
|
52
|
+
*/
|
|
53
|
+
export async function getFileHandle(path, { touch, recursive, rootDir } = {}) {
|
|
54
|
+
const resolvedPath = resolve(path);
|
|
55
|
+
const fileName = basename(resolvedPath);
|
|
56
|
+
const resolvedDir = dirname(resolvedPath);
|
|
57
|
+
const dirHandle = await getDirHandle(resolvedDir, { recursive, rootDir });
|
|
58
|
+
return dirHandle.getFileHandle(fileName, { create: touch });
|
|
59
|
+
}
|
|
60
|
+
export async function checkDirExists(path, { rootDir } = {}) {
|
|
61
|
+
try {
|
|
62
|
+
const { name, parentHandle } = await resolveParentHandle(path, { rootDir });
|
|
63
|
+
await parentHandle.getDirectoryHandle(name, { create: false });
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
if (err.name === 'NotFoundError') {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
throw err;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
export async function checkFileExists(path, { rootDir } = {}) {
|
|
74
|
+
try {
|
|
75
|
+
const { name, parentHandle } = await resolveParentHandle(path, { rootDir });
|
|
76
|
+
await parentHandle.getFileHandle(name, { create: false });
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
if (err.name === 'NotFoundError') {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
throw err;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Lists the directory contents recursivelly up to the `depth` provided.
|
|
88
|
+
*
|
|
89
|
+
* It returns an array of items, if the item have children and the depth is not exceeded, the children property will be filled.
|
|
90
|
+
*
|
|
91
|
+
* @param pathOrHandle A path string or a {@link FileSystemHandle}
|
|
92
|
+
* @param options The options for function.
|
|
93
|
+
*/
|
|
94
|
+
export async function listDirEntries(pathOrHandle, { depth = 0, rootDir } = {}) {
|
|
95
|
+
const { name, parentHandle, parentPath } = await resolveParentHandle(pathOrHandle, { rootDir });
|
|
96
|
+
const resolvedRootHandle = rootDir ?? await navigator.storage.getDirectory();
|
|
97
|
+
const dirHandle = (parentPath === '/' && name === '') ? resolvedRootHandle : await parentHandle.getDirectoryHandle(name);
|
|
98
|
+
async function getRecursiveEntries(curDirHandle, curDepth) {
|
|
99
|
+
const entries = [];
|
|
100
|
+
for await (const [name, entry] of curDirHandle.entries()) {
|
|
101
|
+
if (entry.kind === 'file' || curDepth >= depth) {
|
|
102
|
+
entries.push({
|
|
103
|
+
name,
|
|
104
|
+
handle: entry
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
entries.push({
|
|
109
|
+
name,
|
|
110
|
+
handle: entry,
|
|
111
|
+
children: await getRecursiveEntries(entry, curDepth + 1)
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return entries;
|
|
116
|
+
}
|
|
117
|
+
return getRecursiveEntries(dirHandle, 0);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Write data to a file, overwriting existing data.
|
|
121
|
+
*
|
|
122
|
+
* @param pathOrHandle A path string or a {@link FileSystemHandle}
|
|
123
|
+
* @param data The data to write to the file.
|
|
124
|
+
* @param options The options for function.
|
|
125
|
+
*/
|
|
126
|
+
export async function writeFile(pathOrHandle, data, { recursive = true, rootDir, overwrite = true } = {}) {
|
|
127
|
+
const { name, parentHandle } = await resolveParentHandle(pathOrHandle, { recursive: recursive, rootDir });
|
|
128
|
+
const fileHandle = await parentHandle.getFileHandle(name, { create: true });
|
|
129
|
+
const file = await fileHandle.getFile();
|
|
130
|
+
if (file.size && !overwrite) {
|
|
131
|
+
throw new DOMException('Cannot overwrite existing file', 'NotAllowedError');
|
|
132
|
+
}
|
|
133
|
+
await requestHandlePermissions(fileHandle, 'readwrite');
|
|
134
|
+
const stream = await fileHandle.createWritable();
|
|
135
|
+
await stream.truncate(0);
|
|
136
|
+
await stream.write(data);
|
|
137
|
+
await stream.close();
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Appends data to the end of a file.
|
|
141
|
+
*
|
|
142
|
+
* @param pathOrHandle A path string or a {@link FileSystemHandle}
|
|
143
|
+
* @param data The data to append to the file.
|
|
144
|
+
* @param options The options for function.
|
|
145
|
+
*/
|
|
146
|
+
export async function appendFile(pathOrHandle, data, { recursive, rootDir } = {}) {
|
|
147
|
+
const { name, parentHandle } = await resolveParentHandle(pathOrHandle, { recursive: recursive, rootDir });
|
|
148
|
+
const fileHandle = await parentHandle.getFileHandle(name, { create: true });
|
|
149
|
+
await requestHandlePermissions(fileHandle, 'readwrite');
|
|
150
|
+
const stream = await fileHandle.createWritable({ keepExistingData: true });
|
|
151
|
+
const file = await fileHandle.getFile();
|
|
152
|
+
await stream.seek(file.size);
|
|
153
|
+
await stream.write(data);
|
|
154
|
+
await stream.close();
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Deletes a directory, optionally also deleting it's contents recursivelly.
|
|
158
|
+
*
|
|
159
|
+
* If the directory is the root of the file system, all children will be deleted but the root directory itself will be kept.
|
|
160
|
+
*
|
|
161
|
+
* @param pathOrHandle A path string or a {@link FileSystemHandle}
|
|
162
|
+
* @param options The options for function.
|
|
163
|
+
*/
|
|
164
|
+
export async function removeDir(pathOrHandle, { recursive, rootDir }) {
|
|
165
|
+
const { name, parentHandle, parentPath } = await resolveParentHandle(pathOrHandle, { rootDir });
|
|
166
|
+
if (parentPath === '/' && name === '') {
|
|
167
|
+
await requestHandlePermissions(parentHandle, 'readwrite');
|
|
168
|
+
for await (const childName of parentHandle.keys()) {
|
|
169
|
+
await parentHandle.removeEntry(childName, { recursive });
|
|
170
|
+
}
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
const dirHandle = await parentHandle.getDirectoryHandle(name);
|
|
174
|
+
const entries = await listDirEntries(dirHandle, { rootDir, depth: 0 });
|
|
175
|
+
for (const entry of entries) {
|
|
176
|
+
// oxlint-disable-next-line no-await-in-loop
|
|
177
|
+
await parentHandle.removeEntry(entry.name, { recursive });
|
|
178
|
+
}
|
|
179
|
+
await parentHandle.removeEntry(name, { recursive });
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Deletes a file.
|
|
183
|
+
*
|
|
184
|
+
* @param pathOrHandle A path string or a {@link FileSystemHandle}
|
|
185
|
+
* @param options The options for function.
|
|
186
|
+
*/
|
|
187
|
+
export async function removeFile(pathOrHandle, { rootDir } = {}) {
|
|
188
|
+
const { name, parentHandle } = await resolveParentHandle(pathOrHandle, { rootDir });
|
|
189
|
+
const fileHandle = await parentHandle.getFileHandle(name);
|
|
190
|
+
await requestHandlePermissions(fileHandle, 'readwrite');
|
|
191
|
+
await requestHandlePermissions(parentHandle, 'readwrite');
|
|
192
|
+
await parentHandle.removeEntry(name);
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Copies a directory from one location to another.
|
|
196
|
+
*
|
|
197
|
+
* @param sourcePathOrHandle The path string or a {@link FileSystemDirectoryHandle} for the source directory.
|
|
198
|
+
* @param destinationPathOrHandle The path string or a {@link FileSystemDirectoryHandle} for the destination directory.
|
|
199
|
+
* @param options The options for function.
|
|
200
|
+
*/
|
|
201
|
+
export async function copyDir(sourcePathOrHandle, destinationPathOrHandle, { overwrite = true, rootDir, recursive = true } = {}) {
|
|
202
|
+
const entries = await listDirEntries(sourcePathOrHandle, { depth: Infinity, rootDir });
|
|
203
|
+
const { name: destName, parentHandle: destParentHandle } = await resolveParentHandle(destinationPathOrHandle, { recursive, rootDir });
|
|
204
|
+
const destHandle = await destParentHandle.getDirectoryHandle(destName);
|
|
205
|
+
async function copyRecursive(items, currentDestHandle) {
|
|
206
|
+
for (const item of items) {
|
|
207
|
+
const handle = item.handle;
|
|
208
|
+
// oxlint-disable no-await-in-loop
|
|
209
|
+
if (handle instanceof FileSystemFileHandle) {
|
|
210
|
+
const destFileHandle = await currentDestHandle.getFileHandle(item.name, { create: true });
|
|
211
|
+
// oxlint-disable-next-line no-use-before-define
|
|
212
|
+
await copyFile(handle, destFileHandle, { recursive, rootDir, overwrite });
|
|
213
|
+
}
|
|
214
|
+
else if (item.children) {
|
|
215
|
+
const newDestDirHandle = await currentDestHandle.getDirectoryHandle(item.name, { create: true });
|
|
216
|
+
await copyRecursive(item.children, newDestDirHandle);
|
|
217
|
+
}
|
|
218
|
+
// oxlint-enable no-await-in-loop
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
await copyRecursive(entries, destHandle);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Copies a file from one location to another.
|
|
225
|
+
*
|
|
226
|
+
* @param sourcePathOrHandle The path string or a {@link FileSystemDirectoryHandle} for the source file.
|
|
227
|
+
* @param destinationPathOrHandle The path string or a {@link FileSystemDirectoryHandle} for the destination file.
|
|
228
|
+
* @param options The options for function.
|
|
229
|
+
*/
|
|
230
|
+
export async function copyFile(sourcePathOrHandle, destinationPathOrHandle, { overwrite = true, rootDir, recursive = true } = {}) {
|
|
231
|
+
let sourceHandle;
|
|
232
|
+
if (typeof sourcePathOrHandle === 'string') {
|
|
233
|
+
sourceHandle = await getFileHandle(sourcePathOrHandle, { rootDir });
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
sourceHandle = sourcePathOrHandle;
|
|
237
|
+
}
|
|
238
|
+
const file = await sourceHandle.getFile();
|
|
239
|
+
await writeFile(destinationPathOrHandle, await file.arrayBuffer(), { rootDir, recursive, overwrite });
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Moves a directory from one location to another.
|
|
243
|
+
*
|
|
244
|
+
* @param sourcePathOrHandle The path string or a {@link FileSystemDirectoryHandle} for the source directory.
|
|
245
|
+
* @param destinationPathOrHandle The path string or a {@link FileSystemDirectoryHandle} for the destination directory.
|
|
246
|
+
* @param options The options for function.
|
|
247
|
+
*/
|
|
248
|
+
export async function moveDir(sourcePathOrHandle, destinationPathOrHandle, { overwrite = true, rootDir, recursive = true } = {}) {
|
|
249
|
+
const entries = await listDirEntries(sourcePathOrHandle, { depth: Infinity, rootDir });
|
|
250
|
+
const { name: destName, parentHandle: destParentHandle } = await resolveParentHandle(destinationPathOrHandle, { recursive, rootDir });
|
|
251
|
+
const destHandle = await destParentHandle.getDirectoryHandle(destName);
|
|
252
|
+
async function moveRecursive(items, currentDestHandle) {
|
|
253
|
+
for (const item of items) {
|
|
254
|
+
const handle = item.handle;
|
|
255
|
+
// oxlint-disable no-await-in-loop
|
|
256
|
+
if (handle instanceof FileSystemFileHandle) {
|
|
257
|
+
const destFileHandle = await currentDestHandle.getFileHandle(item.name, { create: true });
|
|
258
|
+
// oxlint-disable-next-line no-use-before-define
|
|
259
|
+
await moveFile(handle, destFileHandle, { recursive, rootDir, overwrite });
|
|
260
|
+
}
|
|
261
|
+
else if (item.children) {
|
|
262
|
+
const newDestDirHandle = await currentDestHandle.getDirectoryHandle(item.name, { create: true });
|
|
263
|
+
await moveRecursive(item.children, newDestDirHandle);
|
|
264
|
+
// oxlint-disable-next-line typescript/consistent-type-assertions, typescript/no-unsafe-type-assertion
|
|
265
|
+
await removeDir(handle, { recursive: true, rootDir });
|
|
266
|
+
}
|
|
267
|
+
// oxlint-enable no-await-in-loop
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
await moveRecursive(entries, destHandle);
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Moves a file from one location to another.
|
|
274
|
+
*
|
|
275
|
+
* @param sourcePathOrHandle The path string or a {@link FileSystemDirectoryHandle} for the source file.
|
|
276
|
+
* @param destinationPathOrHandle The path string or a {@link FileSystemDirectoryHandle} for the destination file.
|
|
277
|
+
* @param options The options for function.
|
|
278
|
+
*/
|
|
279
|
+
export async function moveFile(sourcePathOrHandle, destinationPathOrHandle, { overwrite = true, rootDir, recursive = true } = {}) {
|
|
280
|
+
await copyFile(sourcePathOrHandle, destinationPathOrHandle, { overwrite, rootDir, recursive });
|
|
281
|
+
await removeFile(sourcePathOrHandle, { rootDir });
|
|
282
|
+
}
|
|
283
|
+
// #endregion
|
package/dist/path.d.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Split a path string into segments and normalize it.
|
|
3
|
+
*
|
|
4
|
+
* The normalization does the following:
|
|
5
|
+
* - Removes empty path segments.
|
|
6
|
+
* - Decode from URI parts to handle paths coming from URLs.
|
|
7
|
+
*
|
|
8
|
+
* @param path The path to split into segments
|
|
9
|
+
*/
|
|
10
|
+
export declare function pathToSegments(path: string): string[];
|
|
11
|
+
/**
|
|
12
|
+
* Returns the directory name, given a path string.
|
|
13
|
+
* It is similar to node's `dirname` fucntion.
|
|
14
|
+
*
|
|
15
|
+
* @param path The path to get the directory name
|
|
16
|
+
*/
|
|
17
|
+
export declare function dirname(path: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Returns the name for the last part of a given path string.
|
|
20
|
+
* It is similar to node's `basename` function.
|
|
21
|
+
*
|
|
22
|
+
* @param path The path to get the last part.
|
|
23
|
+
* @param suffix An optional extension to remove from the item, like an extension.
|
|
24
|
+
*/
|
|
25
|
+
export declare function basename(path: string, suffix?: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* Returns the extension of the path, from the last occurrence of the `.` (dot) to the end of the string.
|
|
28
|
+
* Returns an empty string if there is no dot or if the only dot is in the start of the string.
|
|
29
|
+
* It is similar to node's `extname` function.
|
|
30
|
+
*
|
|
31
|
+
* @param path The path to get the extension
|
|
32
|
+
*/
|
|
33
|
+
export declare function extname(path: string): string;
|
|
34
|
+
/**
|
|
35
|
+
* Resolves a sequence of paths or path segments into an absolute path.
|
|
36
|
+
* It is similar to node's `resolve` function.
|
|
37
|
+
*
|
|
38
|
+
* **Note**: If no absolute path is provided, the function prepends a `/`. It assumes the starting point is _always_ the file system root.
|
|
39
|
+
*
|
|
40
|
+
* @param paths A sequence of paths or path segments
|
|
41
|
+
*/
|
|
42
|
+
export declare function resolve(...paths: string[]): string;
|
|
43
|
+
/**
|
|
44
|
+
* Encodes a path string, taking care of restricted characters and names and converting them to percent encoded characters.
|
|
45
|
+
*
|
|
46
|
+
* @param path The path to encode.
|
|
47
|
+
* @param replacer A custom replacer function that will be invoked for each segment of the path.
|
|
48
|
+
*/
|
|
49
|
+
export declare function encodePath(path: string, replacer?: (segment: string) => string): string;
|
|
50
|
+
/**
|
|
51
|
+
* Decodes a path string, converting back from perdent encoded characters.
|
|
52
|
+
*
|
|
53
|
+
* @param path The path to decode.
|
|
54
|
+
* @param replacer A custom replacer function that will be invoked for each segment of the path.
|
|
55
|
+
*/
|
|
56
|
+
export declare function decodePath(path: string, replacer?: (segment: string) => string): string;
|