@symbiote-native/file-system 0.1.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 +21 -0
- package/README.md +262 -0
- package/build/angular/index.d.ts +1 -0
- package/build/angular/index.js +1 -0
- package/build/core/file-system.d.ts +169 -0
- package/build/core/file-system.js +404 -0
- package/build/core/index.d.ts +2 -0
- package/build/core/index.js +2 -0
- package/build/core/native-module.d.ts +32 -0
- package/build/core/native-module.js +2 -0
- package/build/core/types.d.ts +104 -0
- package/build/core/types.js +15 -0
- package/build/next/directory.d.ts +36 -0
- package/build/next/directory.js +59 -0
- package/build/next/file.d.ts +71 -0
- package/build/next/file.js +207 -0
- package/build/next/index.d.ts +5 -0
- package/build/next/index.js +5 -0
- package/build/next/native-module.d.ts +109 -0
- package/build/next/native-module.js +2 -0
- package/build/next/network-tasks.d.ts +118 -0
- package/build/next/network-tasks.js +333 -0
- package/build/next/node-path.d.ts +16 -0
- package/build/next/node-path.js +353 -0
- package/build/next/path-utilities.d.ts +42 -0
- package/build/next/path-utilities.js +110 -0
- package/build/next/paths.d.ts +22 -0
- package/build/next/paths.js +43 -0
- package/build/next/streams.d.ts +25 -0
- package/build/next/streams.js +55 -0
- package/build/next/types.d.ts +152 -0
- package/build/next/types.js +19 -0
- package/build/next/url-utilities.d.ts +3 -0
- package/build/next/url-utilities.js +62 -0
- package/build/next/watcher.d.ts +19 -0
- package/build/next/watcher.js +64 -0
- package/build-ngc/angular/index.d.ts +1 -0
- package/build-ngc/angular/index.js +2 -0
- package/build-ngc/angular/index.js.map +1 -0
- package/build-ngc/next/directory.d.ts +36 -0
- package/build-ngc/next/directory.js +60 -0
- package/build-ngc/next/directory.js.map +1 -0
- package/build-ngc/next/file.d.ts +71 -0
- package/build-ngc/next/file.js +208 -0
- package/build-ngc/next/file.js.map +1 -0
- package/build-ngc/next/index.d.ts +5 -0
- package/build-ngc/next/index.js +6 -0
- package/build-ngc/next/index.js.map +1 -0
- package/build-ngc/next/native-module.d.ts +109 -0
- package/build-ngc/next/native-module.js +3 -0
- package/build-ngc/next/native-module.js.map +1 -0
- package/build-ngc/next/network-tasks.d.ts +118 -0
- package/build-ngc/next/network-tasks.js +334 -0
- package/build-ngc/next/network-tasks.js.map +1 -0
- package/build-ngc/next/node-path.d.ts +16 -0
- package/build-ngc/next/node-path.js +354 -0
- package/build-ngc/next/node-path.js.map +1 -0
- package/build-ngc/next/path-utilities.d.ts +42 -0
- package/build-ngc/next/path-utilities.js +111 -0
- package/build-ngc/next/path-utilities.js.map +1 -0
- package/build-ngc/next/paths.d.ts +22 -0
- package/build-ngc/next/paths.js +44 -0
- package/build-ngc/next/paths.js.map +1 -0
- package/build-ngc/next/streams.d.ts +25 -0
- package/build-ngc/next/streams.js +56 -0
- package/build-ngc/next/streams.js.map +1 -0
- package/build-ngc/next/types.d.ts +152 -0
- package/build-ngc/next/types.js +20 -0
- package/build-ngc/next/types.js.map +1 -0
- package/build-ngc/next/url-utilities.d.ts +3 -0
- package/build-ngc/next/url-utilities.js +63 -0
- package/build-ngc/next/url-utilities.js.map +1 -0
- package/build-ngc/next/watcher.d.ts +19 -0
- package/build-ngc/next/watcher.js +65 -0
- package/build-ngc/next/watcher.js.map +1 -0
- package/native-link.json +17 -0
- package/package.json +154 -0
- package/src/angular/index.ts +1 -0
- package/src/core/file-system.ts +634 -0
- package/src/core/index.ts +2 -0
- package/src/core/native-module.ts +99 -0
- package/src/core/types.ts +135 -0
- package/src/next/directory.ts +83 -0
- package/src/next/file.ts +318 -0
- package/src/next/index.ts +5 -0
- package/src/next/native-module.ts +188 -0
- package/src/next/network-tasks.ts +456 -0
- package/src/next/node-path.ts +362 -0
- package/src/next/path-utilities.ts +144 -0
- package/src/next/paths.ts +52 -0
- package/src/next/streams-ambient.d.ts +34 -0
- package/src/next/streams.ts +81 -0
- package/src/next/types.ts +194 -0
- package/src/next/url-utilities.ts +70 -0
- package/src/next/watcher.ts +106 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { File } from './file';
|
|
2
|
+
import type { Directory } from './directory';
|
|
3
|
+
export declare class PathUtilities {
|
|
4
|
+
/**
|
|
5
|
+
* Joins path segments into a single path.
|
|
6
|
+
*/
|
|
7
|
+
static join(...paths: (string | File | Directory)[]): string;
|
|
8
|
+
/**
|
|
9
|
+
* Resolves a relative path to an absolute path.
|
|
10
|
+
*/
|
|
11
|
+
static relative(from: string | File | Directory, to: string | File | Directory): string;
|
|
12
|
+
/**
|
|
13
|
+
* Checks if a path is absolute.
|
|
14
|
+
*/
|
|
15
|
+
static isAbsolute(path: string | File | Directory): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Normalizes a path.
|
|
18
|
+
*/
|
|
19
|
+
static normalize(path: string | File | Directory): string;
|
|
20
|
+
/**
|
|
21
|
+
* Returns the directory name of a path.
|
|
22
|
+
*/
|
|
23
|
+
static dirname(path: string | File | Directory): string;
|
|
24
|
+
/**
|
|
25
|
+
* Returns the base name of a path.
|
|
26
|
+
*/
|
|
27
|
+
static basename(path: string | File | Directory, ext?: string): string;
|
|
28
|
+
/**
|
|
29
|
+
* Returns the extension of a path.
|
|
30
|
+
*/
|
|
31
|
+
static extname(path: string | File | Directory): string;
|
|
32
|
+
/**
|
|
33
|
+
* Parses a path into its components.
|
|
34
|
+
*/
|
|
35
|
+
static parse(path: string | File | Directory): {
|
|
36
|
+
root: string;
|
|
37
|
+
dir: string;
|
|
38
|
+
base: string;
|
|
39
|
+
ext: string;
|
|
40
|
+
name: string;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import * as nodePath from './node-path.js';
|
|
2
|
+
import { asUrl, isUrl, encodeURLChars } from './url-utilities.js';
|
|
3
|
+
function uriObjectToString(path) {
|
|
4
|
+
return typeof path === 'string' ? path : path.uri;
|
|
5
|
+
}
|
|
6
|
+
// React Native's own ambient `URL` type (react-native/src/types/globals.d.ts) declares every
|
|
7
|
+
// property but `search` as readonly, so a new pathname is applied by reconstructing the URL
|
|
8
|
+
// rather than assigning `.pathname` in place — matching what a real setter would do internally.
|
|
9
|
+
// Built from `.protocol`/`.host` rather than `.origin`, because `file://` URLs report `.origin`
|
|
10
|
+
// as the literal string `"null"` per spec.
|
|
11
|
+
function withPathname(url, pathname) {
|
|
12
|
+
return new URL(`${url.protocol}//${url.host}${pathname}${url.search}${url.hash}`);
|
|
13
|
+
}
|
|
14
|
+
export class PathUtilities {
|
|
15
|
+
/**
|
|
16
|
+
* Joins path segments into a single path.
|
|
17
|
+
*/
|
|
18
|
+
static join(...paths) {
|
|
19
|
+
const [firstSegment = '', ...rest] = paths.map(uriObjectToString);
|
|
20
|
+
const pathAsUrl = asUrl(firstSegment);
|
|
21
|
+
if (pathAsUrl) {
|
|
22
|
+
const joined = nodePath.join(pathAsUrl.pathname, ...rest.map(encodeURLChars));
|
|
23
|
+
return withPathname(pathAsUrl, joined).toString();
|
|
24
|
+
}
|
|
25
|
+
return nodePath.join(firstSegment, ...rest.map(encodeURLChars));
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Resolves a relative path to an absolute path.
|
|
29
|
+
*/
|
|
30
|
+
static relative(from, to) {
|
|
31
|
+
let fromPath = from;
|
|
32
|
+
let toPath = to;
|
|
33
|
+
const fromString = uriObjectToString(from);
|
|
34
|
+
const toString = uriObjectToString(to);
|
|
35
|
+
if (isUrl(fromString)) {
|
|
36
|
+
fromPath = asUrl(fromString).pathname;
|
|
37
|
+
}
|
|
38
|
+
if (isUrl(toString)) {
|
|
39
|
+
toPath = asUrl(toString).pathname;
|
|
40
|
+
}
|
|
41
|
+
return nodePath.relative(uriObjectToString(fromPath), uriObjectToString(toPath));
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Checks if a path is absolute.
|
|
45
|
+
*/
|
|
46
|
+
static isAbsolute(path) {
|
|
47
|
+
const pathString = uriObjectToString(path);
|
|
48
|
+
if (isUrl(pathString)) {
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
return nodePath.isAbsolute(pathString);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Normalizes a path.
|
|
55
|
+
*/
|
|
56
|
+
static normalize(path) {
|
|
57
|
+
const pathString = uriObjectToString(path);
|
|
58
|
+
const pathURL = asUrl(encodeURLChars(pathString));
|
|
59
|
+
if (pathURL) {
|
|
60
|
+
const normalized = encodeURLChars(nodePath.normalize(decodeURIComponent(pathURL.pathname)));
|
|
61
|
+
return withPathname(pathURL, normalized).toString();
|
|
62
|
+
}
|
|
63
|
+
return nodePath.normalize(pathString);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Returns the directory name of a path.
|
|
67
|
+
*/
|
|
68
|
+
static dirname(path) {
|
|
69
|
+
const pathString = uriObjectToString(path);
|
|
70
|
+
const pathURL = asUrl(pathString);
|
|
71
|
+
if (pathURL) {
|
|
72
|
+
const dirnamePath = encodeURLChars(nodePath.dirname(decodeURIComponent(pathURL.pathname)));
|
|
73
|
+
return withPathname(pathURL, dirnamePath).toString();
|
|
74
|
+
}
|
|
75
|
+
return nodePath.dirname(pathString);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Returns the base name of a path.
|
|
79
|
+
*/
|
|
80
|
+
static basename(path, ext) {
|
|
81
|
+
const pathString = uriObjectToString(path);
|
|
82
|
+
const pathURL = asUrl(pathString);
|
|
83
|
+
if (pathURL) {
|
|
84
|
+
return nodePath.basename(decodeURIComponent(pathURL.pathname));
|
|
85
|
+
}
|
|
86
|
+
return nodePath.basename(pathString, ext);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Returns the extension of a path.
|
|
90
|
+
*/
|
|
91
|
+
static extname(path) {
|
|
92
|
+
const pathString = uriObjectToString(path);
|
|
93
|
+
const pathURL = asUrl(pathString);
|
|
94
|
+
if (pathURL) {
|
|
95
|
+
return nodePath.extname(decodeURIComponent(pathURL.pathname));
|
|
96
|
+
}
|
|
97
|
+
return nodePath.extname(pathString);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Parses a path into its components.
|
|
101
|
+
*/
|
|
102
|
+
static parse(path) {
|
|
103
|
+
const pathString = uriObjectToString(path);
|
|
104
|
+
const pathURL = asUrl(pathString);
|
|
105
|
+
if (pathURL) {
|
|
106
|
+
return nodePath.parse(decodeURIComponent(pathURL.pathname));
|
|
107
|
+
}
|
|
108
|
+
return nodePath.parse(pathString);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Directory } from './directory';
|
|
2
|
+
import { PathUtilities } from './path-utilities';
|
|
3
|
+
import type { IPathInfo } from './types';
|
|
4
|
+
export declare class Paths extends PathUtilities {
|
|
5
|
+
/**
|
|
6
|
+
* A place to store files that can be deleted by the system when the device runs low on
|
|
7
|
+
* storage.
|
|
8
|
+
*/
|
|
9
|
+
static get cache(): Directory;
|
|
10
|
+
/** The directory where assets bundled with the application are stored. */
|
|
11
|
+
static get bundle(): Directory;
|
|
12
|
+
/** A place to store files that are safe from being deleted by the system. */
|
|
13
|
+
static get document(): Directory;
|
|
14
|
+
/** @platform ios */
|
|
15
|
+
static get appleSharedContainers(): Record<string, Directory>;
|
|
16
|
+
/** The total space on the device's internal storage, in bytes. */
|
|
17
|
+
static get totalDiskSpace(): number;
|
|
18
|
+
/** The available space on the device's internal storage, in bytes. */
|
|
19
|
+
static get availableDiskSpace(): number;
|
|
20
|
+
/** Returns an object that indicates if the specified path represents a directory. */
|
|
21
|
+
static info(...uris: string[]): IPathInfo;
|
|
22
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Directory } from './directory.js';
|
|
2
|
+
import { expoFileSystemNext } from './native-module.js';
|
|
3
|
+
import { PathUtilities } from './path-utilities.js';
|
|
4
|
+
export class Paths extends PathUtilities {
|
|
5
|
+
/**
|
|
6
|
+
* A place to store files that can be deleted by the system when the device runs low on
|
|
7
|
+
* storage.
|
|
8
|
+
*/
|
|
9
|
+
static get cache() {
|
|
10
|
+
return new Directory(expoFileSystemNext.cacheDirectory);
|
|
11
|
+
}
|
|
12
|
+
/** The directory where assets bundled with the application are stored. */
|
|
13
|
+
static get bundle() {
|
|
14
|
+
return new Directory(expoFileSystemNext.bundleDirectory);
|
|
15
|
+
}
|
|
16
|
+
/** A place to store files that are safe from being deleted by the system. */
|
|
17
|
+
static get document() {
|
|
18
|
+
return new Directory(expoFileSystemNext.documentDirectory);
|
|
19
|
+
}
|
|
20
|
+
/** @platform ios */
|
|
21
|
+
static get appleSharedContainers() {
|
|
22
|
+
const containers = expoFileSystemNext.appleSharedContainers ?? {};
|
|
23
|
+
const result = {};
|
|
24
|
+
for (const appGroupId in containers) {
|
|
25
|
+
if (containers[appGroupId]) {
|
|
26
|
+
result[appGroupId] = new Directory(containers[appGroupId]);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
31
|
+
/** The total space on the device's internal storage, in bytes. */
|
|
32
|
+
static get totalDiskSpace() {
|
|
33
|
+
return expoFileSystemNext.totalDiskSpace;
|
|
34
|
+
}
|
|
35
|
+
/** The available space on the device's internal storage, in bytes. */
|
|
36
|
+
static get availableDiskSpace() {
|
|
37
|
+
return expoFileSystemNext.availableDiskSpace;
|
|
38
|
+
}
|
|
39
|
+
/** Returns an object that indicates if the specified path represents a directory. */
|
|
40
|
+
static info(...uris) {
|
|
41
|
+
return expoFileSystemNext.info(uris.join('/'));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { IFileSystemHandle } from './types';
|
|
2
|
+
type IReadableByteStreamController = {
|
|
3
|
+
readonly byobRequest: {
|
|
4
|
+
view: ArrayBufferView | null;
|
|
5
|
+
respond(bytesWritten: number): void;
|
|
6
|
+
} | null;
|
|
7
|
+
close(): void;
|
|
8
|
+
enqueue(chunk: Uint8Array): void;
|
|
9
|
+
};
|
|
10
|
+
export declare class FileSystemReadableStreamSource {
|
|
11
|
+
handle: IFileSystemHandle;
|
|
12
|
+
size: number;
|
|
13
|
+
type: "bytes";
|
|
14
|
+
constructor(handle: IFileSystemHandle);
|
|
15
|
+
cancel(): void;
|
|
16
|
+
pull(controller: IReadableByteStreamController): void;
|
|
17
|
+
}
|
|
18
|
+
export declare class FileSystemWritableSink {
|
|
19
|
+
handle: IFileSystemHandle;
|
|
20
|
+
constructor(handle: IFileSystemHandle);
|
|
21
|
+
abort(): void;
|
|
22
|
+
close(): void;
|
|
23
|
+
write(chunk: Uint8Array): void;
|
|
24
|
+
}
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export class FileSystemReadableStreamSource {
|
|
2
|
+
handle;
|
|
3
|
+
size = 1024;
|
|
4
|
+
type = 'bytes';
|
|
5
|
+
constructor(handle) {
|
|
6
|
+
this.handle = handle;
|
|
7
|
+
}
|
|
8
|
+
cancel() {
|
|
9
|
+
this.handle.close();
|
|
10
|
+
}
|
|
11
|
+
pull(controller) {
|
|
12
|
+
const theView = controller.byobRequest?.view;
|
|
13
|
+
if (!theView) {
|
|
14
|
+
const bytes = this.handle.readBytes(this.size);
|
|
15
|
+
if (bytes.length === 0) {
|
|
16
|
+
controller.close();
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
controller.enqueue(bytes);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
// TODO: Optimize by adding a native method that can write into a TypedArray at a given offset.
|
|
23
|
+
const bytes = this.handle.readBytes(theView.byteLength - theView.byteOffset);
|
|
24
|
+
if (bytes.length === 0) {
|
|
25
|
+
controller.close();
|
|
26
|
+
controller.byobRequest.respond(0);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if (theView instanceof Uint8Array) {
|
|
30
|
+
theView.set(bytes, theView.byteOffset);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
const array = new Uint8Array(theView.buffer);
|
|
34
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
35
|
+
array[i + (theView.byteOffset ?? 0)] = bytes[i];
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
controller.byobRequest.respond(bytes.length);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export class FileSystemWritableSink {
|
|
42
|
+
handle;
|
|
43
|
+
constructor(handle) {
|
|
44
|
+
this.handle = handle;
|
|
45
|
+
}
|
|
46
|
+
abort() {
|
|
47
|
+
this.close();
|
|
48
|
+
}
|
|
49
|
+
close() {
|
|
50
|
+
this.handle.close();
|
|
51
|
+
}
|
|
52
|
+
write(chunk) {
|
|
53
|
+
this.handle.writeBytes(chunk);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import type { File } from './file';
|
|
2
|
+
import type { Directory } from './directory';
|
|
3
|
+
export type IFileCreateOptions = {
|
|
4
|
+
intermediates?: boolean;
|
|
5
|
+
overwrite?: boolean;
|
|
6
|
+
};
|
|
7
|
+
export type IRelocationOptions = {
|
|
8
|
+
overwrite?: boolean;
|
|
9
|
+
};
|
|
10
|
+
export declare enum FileSystemEncodingType {
|
|
11
|
+
UTF8 = "utf8",
|
|
12
|
+
Base64 = "base64"
|
|
13
|
+
}
|
|
14
|
+
export type IFileWriteOptions = {
|
|
15
|
+
encoding?: FileSystemEncodingType | 'utf8' | 'base64';
|
|
16
|
+
append?: boolean;
|
|
17
|
+
};
|
|
18
|
+
export declare enum FileMode {
|
|
19
|
+
ReadWrite = "rw",
|
|
20
|
+
ReadOnly = "r",
|
|
21
|
+
WriteOnly = "w",
|
|
22
|
+
Append = "wa",
|
|
23
|
+
Truncate = "wt"
|
|
24
|
+
}
|
|
25
|
+
export type IFileSystemHandle = {
|
|
26
|
+
close(): void;
|
|
27
|
+
readBytes(length: number): Uint8Array<ArrayBuffer>;
|
|
28
|
+
writeBytes(bytes: Uint8Array): void;
|
|
29
|
+
offset: number | null;
|
|
30
|
+
size: number | null;
|
|
31
|
+
};
|
|
32
|
+
export type IFileInfo = {
|
|
33
|
+
exists: boolean;
|
|
34
|
+
uri?: string;
|
|
35
|
+
size?: number;
|
|
36
|
+
modificationTime?: number;
|
|
37
|
+
creationTime?: number;
|
|
38
|
+
md5?: string;
|
|
39
|
+
};
|
|
40
|
+
export type IFileSystemInfoOptions = {
|
|
41
|
+
md5?: boolean;
|
|
42
|
+
};
|
|
43
|
+
export type IPickFileGeneralOptions = {
|
|
44
|
+
initialUri?: string;
|
|
45
|
+
mimeTypes?: string | string[];
|
|
46
|
+
multipleFiles?: boolean;
|
|
47
|
+
};
|
|
48
|
+
export type IPickSingleFileOptions = IPickFileGeneralOptions & {
|
|
49
|
+
multipleFiles?: false;
|
|
50
|
+
};
|
|
51
|
+
export type IPickMultipleFilesOptions = IPickFileGeneralOptions & {
|
|
52
|
+
multipleFiles: true;
|
|
53
|
+
};
|
|
54
|
+
export type IPickFileOptions = IPickSingleFileOptions | IPickMultipleFilesOptions;
|
|
55
|
+
export type IPickSingleFileSuccessResult = {
|
|
56
|
+
result: File;
|
|
57
|
+
canceled: false;
|
|
58
|
+
};
|
|
59
|
+
export type IPickMultipleFilesSuccessResult = {
|
|
60
|
+
result: File[];
|
|
61
|
+
canceled: false;
|
|
62
|
+
};
|
|
63
|
+
export type IPickFileCanceledResult = {
|
|
64
|
+
result: null;
|
|
65
|
+
canceled: true;
|
|
66
|
+
};
|
|
67
|
+
export type IPickSingleFileResult = IPickSingleFileSuccessResult | IPickFileCanceledResult;
|
|
68
|
+
export type IPickMultipleFilesResult = IPickMultipleFilesSuccessResult | IPickFileCanceledResult;
|
|
69
|
+
export type IDirectoryCreateOptions = {
|
|
70
|
+
intermediates?: boolean;
|
|
71
|
+
overwrite?: boolean;
|
|
72
|
+
idempotent?: boolean;
|
|
73
|
+
};
|
|
74
|
+
export type IDirectoryInfo = {
|
|
75
|
+
exists: boolean;
|
|
76
|
+
uri?: string;
|
|
77
|
+
size?: number;
|
|
78
|
+
modificationTime?: number;
|
|
79
|
+
creationTime?: number;
|
|
80
|
+
files?: string[];
|
|
81
|
+
};
|
|
82
|
+
export type IPathInfo = {
|
|
83
|
+
exists: boolean;
|
|
84
|
+
isDirectory: boolean | null;
|
|
85
|
+
};
|
|
86
|
+
export type IFileSystemDownloadProgress = {
|
|
87
|
+
bytesWritten: number;
|
|
88
|
+
totalBytes: number;
|
|
89
|
+
};
|
|
90
|
+
export type IFileSystemDownloadOptions = {
|
|
91
|
+
headers?: Record<string, string>;
|
|
92
|
+
idempotent?: boolean;
|
|
93
|
+
onProgress?: (data: IFileSystemDownloadProgress) => void;
|
|
94
|
+
signal?: AbortSignal;
|
|
95
|
+
};
|
|
96
|
+
export declare enum FileSystemUploadType {
|
|
97
|
+
BINARY_CONTENT = 0,
|
|
98
|
+
MULTIPART = 1
|
|
99
|
+
}
|
|
100
|
+
export type IFileSystemUploadProgress = {
|
|
101
|
+
bytesSent: number;
|
|
102
|
+
totalBytes: number;
|
|
103
|
+
};
|
|
104
|
+
export type IFileSystemUploadResult = {
|
|
105
|
+
body: string;
|
|
106
|
+
status: number;
|
|
107
|
+
headers: Record<string, string>;
|
|
108
|
+
};
|
|
109
|
+
export type IFileSystemNetworkTaskSessionType = 'background' | 'foreground';
|
|
110
|
+
export type IFileSystemUploadOptions = {
|
|
111
|
+
httpMethod?: 'POST' | 'PUT' | 'PATCH';
|
|
112
|
+
uploadType?: FileSystemUploadType;
|
|
113
|
+
headers?: Record<string, string>;
|
|
114
|
+
fieldName?: string;
|
|
115
|
+
mimeType?: string;
|
|
116
|
+
parameters?: Record<string, string>;
|
|
117
|
+
onProgress?: (data: IFileSystemUploadProgress) => void;
|
|
118
|
+
sessionType?: IFileSystemNetworkTaskSessionType;
|
|
119
|
+
signal?: AbortSignal;
|
|
120
|
+
};
|
|
121
|
+
export type IFileSystemDownloadTaskOptions = {
|
|
122
|
+
headers?: Record<string, string>;
|
|
123
|
+
sessionType?: IFileSystemNetworkTaskSessionType;
|
|
124
|
+
onProgress?: (data: IFileSystemDownloadProgress) => void;
|
|
125
|
+
signal?: AbortSignal;
|
|
126
|
+
};
|
|
127
|
+
export type IFileSystemDownloadPauseState = {
|
|
128
|
+
url: string;
|
|
129
|
+
fileUri: string;
|
|
130
|
+
isDirectory: boolean;
|
|
131
|
+
headers?: Record<string, string>;
|
|
132
|
+
resumeData?: string;
|
|
133
|
+
};
|
|
134
|
+
type IFileSystemTaskState = 'idle' | 'active' | 'paused' | 'completed' | 'cancelled' | 'error';
|
|
135
|
+
export type IFileSystemUploadTaskState = Exclude<IFileSystemTaskState, 'paused'>;
|
|
136
|
+
export type IFileSystemDownloadTaskState = IFileSystemTaskState;
|
|
137
|
+
export declare const DEFAULT_WATCH_DEBOUNCE_MS = 100;
|
|
138
|
+
export type IFileSystemWatchEventType = 'created' | 'modified' | 'deleted' | 'renamed';
|
|
139
|
+
export type IFileSystemWatchEvent<T extends File | Directory> = {
|
|
140
|
+
type: IFileSystemWatchEventType;
|
|
141
|
+
target: T;
|
|
142
|
+
nativeEventFlags?: number;
|
|
143
|
+
newTarget?: T;
|
|
144
|
+
};
|
|
145
|
+
export type IFileSystemWatchOptions = {
|
|
146
|
+
debounce?: number;
|
|
147
|
+
events?: IFileSystemWatchEventType[];
|
|
148
|
+
};
|
|
149
|
+
export type IFileSystemWatchSubscription = {
|
|
150
|
+
remove(): void;
|
|
151
|
+
};
|
|
152
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export var FileSystemEncodingType;
|
|
2
|
+
(function (FileSystemEncodingType) {
|
|
3
|
+
FileSystemEncodingType["UTF8"] = "utf8";
|
|
4
|
+
FileSystemEncodingType["Base64"] = "base64";
|
|
5
|
+
})(FileSystemEncodingType || (FileSystemEncodingType = {}));
|
|
6
|
+
export var FileMode;
|
|
7
|
+
(function (FileMode) {
|
|
8
|
+
FileMode["ReadWrite"] = "rw";
|
|
9
|
+
FileMode["ReadOnly"] = "r";
|
|
10
|
+
FileMode["WriteOnly"] = "w";
|
|
11
|
+
FileMode["Append"] = "wa";
|
|
12
|
+
FileMode["Truncate"] = "wt";
|
|
13
|
+
})(FileMode || (FileMode = {}));
|
|
14
|
+
export var FileSystemUploadType;
|
|
15
|
+
(function (FileSystemUploadType) {
|
|
16
|
+
FileSystemUploadType[FileSystemUploadType["BINARY_CONTENT"] = 0] = "BINARY_CONTENT";
|
|
17
|
+
FileSystemUploadType[FileSystemUploadType["MULTIPART"] = 1] = "MULTIPART";
|
|
18
|
+
})(FileSystemUploadType || (FileSystemUploadType = {}));
|
|
19
|
+
export const DEFAULT_WATCH_DEBOUNCE_MS = 100;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// Ported verbatim from expo-file-system's own vendored copy (Copyright Joyent, Inc. and other
|
|
2
|
+
// Node contributors, MIT licensed) — url-encoding helpers used when a path is a `file://`/URL
|
|
3
|
+
// rather than a bare posix path.
|
|
4
|
+
import { resolve, sep } from './node-path.js';
|
|
5
|
+
const percentRegEx = /%/g;
|
|
6
|
+
const backslashRegEx = /\\/g;
|
|
7
|
+
const newlineRegEx = /\n/g;
|
|
8
|
+
const carriageReturnRegEx = /\r/g;
|
|
9
|
+
const tabRegEx = /\t/g;
|
|
10
|
+
const questionRegex = /\?/g;
|
|
11
|
+
const hashRegex = /#/g;
|
|
12
|
+
const spaceRegEx = / /g;
|
|
13
|
+
function encodePathChars(filepath) {
|
|
14
|
+
if (filepath.indexOf('%') !== -1)
|
|
15
|
+
filepath = filepath.replace(percentRegEx, '%25');
|
|
16
|
+
if (filepath.indexOf('\\') !== -1)
|
|
17
|
+
filepath = filepath.replace(backslashRegEx, '%5C');
|
|
18
|
+
if (filepath.indexOf('\n') !== -1)
|
|
19
|
+
filepath = filepath.replace(newlineRegEx, '%0A');
|
|
20
|
+
if (filepath.indexOf('\r') !== -1)
|
|
21
|
+
filepath = filepath.replace(carriageReturnRegEx, '%0D');
|
|
22
|
+
if (filepath.indexOf('\t') !== -1)
|
|
23
|
+
filepath = filepath.replace(tabRegEx, '%09');
|
|
24
|
+
if (filepath.indexOf(' ') !== -1)
|
|
25
|
+
filepath = filepath.replace(spaceRegEx, '%20');
|
|
26
|
+
return filepath;
|
|
27
|
+
}
|
|
28
|
+
export function encodeURLChars(path) {
|
|
29
|
+
let resolved = resolve(path);
|
|
30
|
+
const filePathLast = path.charAt(path.length - 1);
|
|
31
|
+
if (filePathLast === '/' && resolved[resolved.length - 1] !== sep)
|
|
32
|
+
resolved += '/';
|
|
33
|
+
resolved = encodePathChars(resolved);
|
|
34
|
+
if (resolved.indexOf('?') !== -1)
|
|
35
|
+
resolved = resolved.replace(questionRegex, '%3F');
|
|
36
|
+
if (resolved.indexOf('#') !== -1)
|
|
37
|
+
resolved = resolved.replace(hashRegex, '%23');
|
|
38
|
+
return resolved;
|
|
39
|
+
}
|
|
40
|
+
export function isUrl(url) {
|
|
41
|
+
try {
|
|
42
|
+
return !!new URL(url);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export function asUrl(url) {
|
|
49
|
+
try {
|
|
50
|
+
const parsed = new URL(url);
|
|
51
|
+
if (parsed.hash === '') {
|
|
52
|
+
return parsed;
|
|
53
|
+
}
|
|
54
|
+
// Strip the hash by reconstructing rather than assigning `.hash = ''` — this project's
|
|
55
|
+
// resolved `URL` type declares its setters read-only (see path-utilities.ts's own note).
|
|
56
|
+
const hashIndex = parsed.href.indexOf('#');
|
|
57
|
+
return new URL(hashIndex === -1 ? parsed.href : parsed.href.slice(0, hashIndex));
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Directory } from './directory';
|
|
2
|
+
import type { File } from './file';
|
|
3
|
+
import type { IFileSystemWatchEvent, IFileSystemWatchOptions, IFileSystemWatchSubscription } from './types';
|
|
4
|
+
type ITargetFactory<T> = (uri: string, isDirectory: boolean) => T;
|
|
5
|
+
/**
|
|
6
|
+
* @hidden
|
|
7
|
+
* Internal implementation of file system watching. Use `File.watch()` or `Directory.watch()` instead.
|
|
8
|
+
*/
|
|
9
|
+
export declare class FileSystemWatcher<T extends File | Directory> implements IFileSystemWatchSubscription {
|
|
10
|
+
private readonly targetFactory;
|
|
11
|
+
private nativeWatcher;
|
|
12
|
+
private subscription;
|
|
13
|
+
private removed;
|
|
14
|
+
private readonly normalizedWatchedPath;
|
|
15
|
+
constructor(path: string, callback: (event: IFileSystemWatchEvent<T>) => void, options: IFileSystemWatchOptions | undefined, targetFactory: ITargetFactory<T>);
|
|
16
|
+
private mapEvent;
|
|
17
|
+
remove(): void;
|
|
18
|
+
}
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { expoFileSystemNext, } from './native-module.js';
|
|
2
|
+
import { DEFAULT_WATCH_DEBOUNCE_MS } from './types.js';
|
|
3
|
+
function normalizePath(path) {
|
|
4
|
+
return path.replace(/\/+$/, '');
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* @hidden
|
|
8
|
+
* Internal implementation of file system watching. Use `File.watch()` or `Directory.watch()` instead.
|
|
9
|
+
*/
|
|
10
|
+
export class FileSystemWatcher {
|
|
11
|
+
targetFactory;
|
|
12
|
+
nativeWatcher;
|
|
13
|
+
subscription = null;
|
|
14
|
+
removed = false;
|
|
15
|
+
normalizedWatchedPath;
|
|
16
|
+
constructor(path, callback, options = {}, targetFactory) {
|
|
17
|
+
this.targetFactory = targetFactory;
|
|
18
|
+
this.normalizedWatchedPath = normalizePath(path);
|
|
19
|
+
this.nativeWatcher = new expoFileSystemNext.FileSystemWatcher(path, {
|
|
20
|
+
debounce: options.debounce ?? DEFAULT_WATCH_DEBOUNCE_MS,
|
|
21
|
+
events: options.events,
|
|
22
|
+
});
|
|
23
|
+
this.subscription = this.nativeWatcher.addListener('change', (raw) => {
|
|
24
|
+
const event = this.mapEvent(raw);
|
|
25
|
+
const isWatchedTarget = normalizePath(raw.path) === this.normalizedWatchedPath;
|
|
26
|
+
if (!options.events || options.events.includes(event.type)) {
|
|
27
|
+
callback(event);
|
|
28
|
+
}
|
|
29
|
+
if ((event.type === 'deleted' || event.type === 'renamed') &&
|
|
30
|
+
isWatchedTarget) {
|
|
31
|
+
this.remove();
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
try {
|
|
35
|
+
this.nativeWatcher.start();
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
this.subscription.remove();
|
|
39
|
+
this.subscription = null;
|
|
40
|
+
this.nativeWatcher = null;
|
|
41
|
+
throw error;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
mapEvent(raw) {
|
|
45
|
+
return {
|
|
46
|
+
type: raw.type,
|
|
47
|
+
target: this.targetFactory(raw.path, raw.isDirectory),
|
|
48
|
+
newTarget: raw.newPath
|
|
49
|
+
? this.targetFactory(raw.newPath, raw.newPathIsDirectory ?? raw.isDirectory)
|
|
50
|
+
: undefined,
|
|
51
|
+
nativeEventFlags: raw.nativeEventFlags,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
remove() {
|
|
55
|
+
if (this.removed) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
this.removed = true;
|
|
59
|
+
this.subscription?.remove();
|
|
60
|
+
this.subscription = null;
|
|
61
|
+
this.nativeWatcher?.stop();
|
|
62
|
+
this.nativeWatcher = null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../next';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/angular/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { File } from './file';
|
|
2
|
+
import { expoFileSystemNext } from './native-module';
|
|
3
|
+
import type { IFileSystemWatchEvent, IFileSystemWatchOptions, IFileSystemWatchSubscription } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* Represents a directory on the filesystem.
|
|
6
|
+
*
|
|
7
|
+
* A `Directory` instance can be created for any path, and does not need to exist on the
|
|
8
|
+
* filesystem during creation.
|
|
9
|
+
*/
|
|
10
|
+
export declare class Directory extends expoFileSystemNext.FileSystemDirectory {
|
|
11
|
+
static pickDirectoryAsync: (initialUri?: string) => Promise<Directory>;
|
|
12
|
+
/**
|
|
13
|
+
* Creates an instance of a directory. It can be created for any path, and does not need to
|
|
14
|
+
* exist on the filesystem during creation.
|
|
15
|
+
*/
|
|
16
|
+
constructor(...uris: (string | File | Directory)[]);
|
|
17
|
+
/** Directory containing this directory. */
|
|
18
|
+
get parentDirectory(): Directory;
|
|
19
|
+
/**
|
|
20
|
+
* Lists the contents of a directory. Calling this method if the parent directory does not
|
|
21
|
+
* exist will throw an error.
|
|
22
|
+
*/
|
|
23
|
+
list(): (Directory | File)[];
|
|
24
|
+
/** Directory name. */
|
|
25
|
+
get name(): string;
|
|
26
|
+
createFile(name: string, mimeType: string | null): File;
|
|
27
|
+
createDirectory(name: string): Directory;
|
|
28
|
+
/**
|
|
29
|
+
* Watches this directory for changes to its contents or the directory itself. On iOS,
|
|
30
|
+
* child changes are surfaced as a coarse-grained `modified` event on the directory itself, so
|
|
31
|
+
* filtering for child-level `created`, `deleted`, or `renamed` events is not reliable. The
|
|
32
|
+
* watcher automatically stops when the directory is deleted or renamed. To stop watching
|
|
33
|
+
* manually, call `remove()` on the returned subscription.
|
|
34
|
+
*/
|
|
35
|
+
watch(callback: (event: IFileSystemWatchEvent<File | Directory>) => void, options?: IFileSystemWatchOptions): IFileSystemWatchSubscription;
|
|
36
|
+
}
|