@dbx-tools/shared-fs 0.6.10
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/README.md +56 -0
- package/index.ts +14 -0
- package/lib/index.d.ts +10 -0
- package/lib/index.js +10 -0
- package/lib/src/base-fs.d.ts +268 -0
- package/lib/src/base-fs.js +622 -0
- package/lib/src/fs.d.ts +110 -0
- package/lib/src/fs.js +2 -0
- package/lib/src/memory-fs.d.ts +46 -0
- package/lib/src/memory-fs.js +131 -0
- package/lib/src/posix-path.d.ts +80 -0
- package/lib/src/posix-path.js +208 -0
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/package.json +53 -0
- package/src/base-fs.ts +882 -0
- package/src/fs.ts +142 -0
- package/src/memory-fs.ts +174 -0
- package/src/posix-path.ts +219 -0
package/README.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# `@dbx-tools/shared-fs`
|
|
2
|
+
|
|
3
|
+
Browser-safe filesystem contract and abstract base for rooted storage backends.
|
|
4
|
+
|
|
5
|
+
Key features:
|
|
6
|
+
|
|
7
|
+
- Portable `FileSystem` interface (read/write/append/copy/move, mkdir/rmdir/readdir/stat/exists)
|
|
8
|
+
- `BaseFileSystem` root accepts one or many segments (`"/path"`, objects →
|
|
9
|
+
FNV hash, `true`/`1` stringified); strings are split on `/` and only a
|
|
10
|
+
component that _cannot_ be a path component (separator, NUL / control
|
|
11
|
+
character, or `..`) is FNV-hashed, so real names like
|
|
12
|
+
`/Workspace/Users/me@corp.com/My Notes` survive intact
|
|
13
|
+
- `BaseFileSystem` so a new backend mostly implements `*At` primitives: memoized `_init`, optional `createRoot`, `toBackendPath`, parent creation before write/append/copy/move, POSIX-only paths, encoding, recursive mkdir/rmdir/readdir, and append/copy/move fallbacks
|
|
14
|
+
- Every primitive is invoked through a guard that routes failures to a
|
|
15
|
+
`mapError` hook, so an adapter writes no try/catch of its own and cannot
|
|
16
|
+
return an unnormalized error
|
|
17
|
+
- `MemoryFileSystem` in-process adapter for tests and as a reference implementation
|
|
18
|
+
- `baseFS.mapFileSystemError` / `baseFS.inferFileSystemErrorCode` on
|
|
19
|
+
`@dbx-tools/shared-core` `error` helpers
|
|
20
|
+
- `posixPath` helpers that convert roots/joins to `/`-separated form
|
|
21
|
+
(`posixPath.toPosix`, `posixPath.join`, …)
|
|
22
|
+
- Typed `FileSystemError` codes for portable failure handling
|
|
23
|
+
|
|
24
|
+
## Why use this
|
|
25
|
+
|
|
26
|
+
Use this when multiple backends (local disk, object storage, Databricks volumes, in-memory) should share one API. Node hosts implement concrete adapters such as `@dbx-tools/fs` (`LocalFileSystem`).
|
|
27
|
+
|
|
28
|
+
## Quick start
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import type { FileSystem } from "@dbx-tools/shared-fs";
|
|
32
|
+
import { BaseFileSystem, FileSystemError, MemoryFileSystem, posixPath } from "@dbx-tools/shared-fs";
|
|
33
|
+
|
|
34
|
+
const mem = new MemoryFileSystem();
|
|
35
|
+
await mem.writeFile("note.txt", "hi");
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Module map
|
|
39
|
+
|
|
40
|
+
| Export | Role |
|
|
41
|
+
| ---------------------------------------- | ---------------------------------------------------------- |
|
|
42
|
+
| `FileSystem` | Portable filesystem contract |
|
|
43
|
+
| `BaseFileSystem` | Abstract base over `*At` primitives; memoized `_init` |
|
|
44
|
+
| `baseFS.normalizeFileSystemRoot` | Join root segments (stringify / FNV-hash) |
|
|
45
|
+
| `FileSystemRootInput` | `root` option: one or many non-null segments |
|
|
46
|
+
| `MemoryFileSystem` | In-memory adapter (tests / reference) |
|
|
47
|
+
| `baseFS.mapFileSystemError` | Wrap backend failures into `FileSystemError` |
|
|
48
|
+
| `baseFS.inferFileSystemErrorCode` | Infer a code from HTTP status / message tokens |
|
|
49
|
+
| `posixPath` | POSIX root/join/normalize helpers for namespace paths |
|
|
50
|
+
| `posixPath.isHomeRelativePath` | `~` / `~/...` detection, shared by every adapter |
|
|
51
|
+
| `posixPath.expandHome` | Expand `~` against a home, with a pluggable join |
|
|
52
|
+
| `posixPath.toRelativeSegment` | Strip leading `~` / separators so input joins UNDER a base |
|
|
53
|
+
| `FileSystemError` | Typed filesystem failure |
|
|
54
|
+
| `FileEntry` / `FileStat` / options types | Shared wire shapes |
|
|
55
|
+
|
|
56
|
+
Adjacent: `@dbx-tools/fs` (local disk adapter).
|
package/index.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// GENERATED by projen watch - DO NOT EDIT.
|
|
2
|
+
// Regenerated from the exporting modules in ./src.
|
|
3
|
+
// Hand edits are overwritten on the next watch; this file is read-only.
|
|
4
|
+
|
|
5
|
+
export * as baseFS from "./src/base-fs.ts";
|
|
6
|
+
export * as fs from "./src/fs.ts";
|
|
7
|
+
export * as memoryFS from "./src/memory-fs.ts";
|
|
8
|
+
export * as posixPath from "./src/posix-path.ts";
|
|
9
|
+
export { FileSystemError, BaseFileSystem } from "./src/base-fs.ts";
|
|
10
|
+
export type { FileSystemRootSegment, FileSystemRootInput, FileSystemErrorCode, BaseFileSystemOptions } from "./src/base-fs.ts";
|
|
11
|
+
export type { FileContent, FileEntryType, FileEntry, FileStat, ReadFileOptions, WriteFileOptions, RemoveOptions, CopyOptions, MakeDirectoryOptions, ListOptions, FileSystem } from "./src/fs.ts";
|
|
12
|
+
export { MemoryFileSystem } from "./src/memory-fs.ts";
|
|
13
|
+
export type { MemoryFileSystemOptions } from "./src/memory-fs.ts";
|
|
14
|
+
export type { NormalizeResult } from "./src/posix-path.ts";
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * as baseFS from "./src/base-fs.ts";
|
|
2
|
+
export * as fs from "./src/fs.ts";
|
|
3
|
+
export * as memoryFS from "./src/memory-fs.ts";
|
|
4
|
+
export * as posixPath from "./src/posix-path.ts";
|
|
5
|
+
export { FileSystemError, BaseFileSystem } from "./src/base-fs.ts";
|
|
6
|
+
export type { FileSystemRootSegment, FileSystemRootInput, FileSystemErrorCode, BaseFileSystemOptions } from "./src/base-fs.ts";
|
|
7
|
+
export type { FileContent, FileEntryType, FileEntry, FileStat, ReadFileOptions, WriteFileOptions, RemoveOptions, CopyOptions, MakeDirectoryOptions, ListOptions, FileSystem } from "./src/fs.ts";
|
|
8
|
+
export { MemoryFileSystem } from "./src/memory-fs.ts";
|
|
9
|
+
export type { MemoryFileSystemOptions } from "./src/memory-fs.ts";
|
|
10
|
+
export type { NormalizeResult } from "./src/posix-path.ts";
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// GENERATED by projen watch - DO NOT EDIT.
|
|
2
|
+
// Regenerated from the exporting modules in ./src.
|
|
3
|
+
// Hand edits are overwritten on the next watch; this file is read-only.
|
|
4
|
+
export * as baseFS from "./src/base-fs.js";
|
|
5
|
+
export * as fs from "./src/fs.js";
|
|
6
|
+
export * as memoryFS from "./src/memory-fs.js";
|
|
7
|
+
export * as posixPath from "./src/posix-path.js";
|
|
8
|
+
export { FileSystemError, BaseFileSystem } from "./src/base-fs.js";
|
|
9
|
+
export { MemoryFileSystem } from "./src/memory-fs.js";
|
|
10
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxPQUFPLEtBQUssTUFBTSxNQUFNLGtCQUFrQixDQUFDO0FBQzNDLE9BQU8sS0FBSyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ2xDLE9BQU8sS0FBSyxRQUFRLE1BQU0sb0JBQW9CLENBQUM7QUFDL0MsT0FBTyxLQUFLLFNBQVMsTUFBTSxxQkFBcUIsQ0FBQztBQUNqRCxPQUFPLEVBQUUsZUFBZSxFQUFFLGNBQWMsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBR25FLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLG9CQUFvQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gR0VORVJBVEVEIGJ5IHByb2plbiB3YXRjaCAtIERPIE5PVCBFRElULlxuLy8gUmVnZW5lcmF0ZWQgZnJvbSB0aGUgZXhwb3J0aW5nIG1vZHVsZXMgaW4gLi9zcmMuXG4vLyBIYW5kIGVkaXRzIGFyZSBvdmVyd3JpdHRlbiBvbiB0aGUgbmV4dCB3YXRjaDsgdGhpcyBmaWxlIGlzIHJlYWQtb25seS5cblxuZXhwb3J0ICogYXMgYmFzZUZTIGZyb20gXCIuL3NyYy9iYXNlLWZzLnRzXCI7XG5leHBvcnQgKiBhcyBmcyBmcm9tIFwiLi9zcmMvZnMudHNcIjtcbmV4cG9ydCAqIGFzIG1lbW9yeUZTIGZyb20gXCIuL3NyYy9tZW1vcnktZnMudHNcIjtcbmV4cG9ydCAqIGFzIHBvc2l4UGF0aCBmcm9tIFwiLi9zcmMvcG9zaXgtcGF0aC50c1wiO1xuZXhwb3J0IHsgRmlsZVN5c3RlbUVycm9yLCBCYXNlRmlsZVN5c3RlbSB9IGZyb20gXCIuL3NyYy9iYXNlLWZzLnRzXCI7XG5leHBvcnQgdHlwZSB7IEZpbGVTeXN0ZW1Sb290U2VnbWVudCwgRmlsZVN5c3RlbVJvb3RJbnB1dCwgRmlsZVN5c3RlbUVycm9yQ29kZSwgQmFzZUZpbGVTeXN0ZW1PcHRpb25zIH0gZnJvbSBcIi4vc3JjL2Jhc2UtZnMudHNcIjtcbmV4cG9ydCB0eXBlIHsgRmlsZUNvbnRlbnQsIEZpbGVFbnRyeVR5cGUsIEZpbGVFbnRyeSwgRmlsZVN0YXQsIFJlYWRGaWxlT3B0aW9ucywgV3JpdGVGaWxlT3B0aW9ucywgUmVtb3ZlT3B0aW9ucywgQ29weU9wdGlvbnMsIE1ha2VEaXJlY3RvcnlPcHRpb25zLCBMaXN0T3B0aW9ucywgRmlsZVN5c3RlbSB9IGZyb20gXCIuL3NyYy9mcy50c1wiO1xuZXhwb3J0IHsgTWVtb3J5RmlsZVN5c3RlbSB9IGZyb20gXCIuL3NyYy9tZW1vcnktZnMudHNcIjtcbmV4cG9ydCB0eXBlIHsgTWVtb3J5RmlsZVN5c3RlbU9wdGlvbnMgfSBmcm9tIFwiLi9zcmMvbWVtb3J5LWZzLnRzXCI7XG5leHBvcnQgdHlwZSB7IE5vcm1hbGl6ZVJlc3VsdCB9IGZyb20gXCIuL3NyYy9wb3NpeC1wYXRoLnRzXCI7XG4iXX0=
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Abstract {@link FileSystem} base: lifecycle, rooted POSIX paths, encoding, and
|
|
3
|
+
* portable fallbacks so a concrete backend only implements low-level I/O.
|
|
4
|
+
*
|
|
5
|
+
* A new adapter typically overrides:
|
|
6
|
+
* - {@link onInit} / {@link onClose} (optional)
|
|
7
|
+
* - {@link createRootDirectory} when {@link BaseFileSystemOptions.createRoot} is set
|
|
8
|
+
* - {@link toBackendPath} when the backend needs non-POSIX separators
|
|
9
|
+
* - {@link preparePath} for post-resolve checks (e.g. symlink containment)
|
|
10
|
+
* - the `*At` primitives and {@link isNotFoundError}
|
|
11
|
+
* - optional `try*` hooks for native append / copy / move
|
|
12
|
+
*
|
|
13
|
+
* @module
|
|
14
|
+
*/
|
|
15
|
+
import { type OneOrMany } from "@dbx-tools/shared-core";
|
|
16
|
+
import type { CopyOptions, FileContent, FileEntry, FileStat, FileSystem, ListOptions, MakeDirectoryOptions, ReadFileOptions, RemoveOptions, WriteFileOptions } from "./fs.ts";
|
|
17
|
+
/**
|
|
18
|
+
* One root path segment. Strings are split on `/` and sanitized; numbers /
|
|
19
|
+
* booleans / bigints stringify then sanitize; objects and arrays are FNV-hashed
|
|
20
|
+
* as a single segment.
|
|
21
|
+
*/
|
|
22
|
+
export type FileSystemRootSegment = string | number | boolean | bigint | object;
|
|
23
|
+
/**
|
|
24
|
+
* A single {@link FileSystemRootSegment} or a non-empty list of them. Nested
|
|
25
|
+
* arrays/objects inside the list are one hashed segment each (not flattened).
|
|
26
|
+
*/
|
|
27
|
+
export type FileSystemRootInput = FileSystemRootSegment | OneOrMany<FileSystemRootSegment>;
|
|
28
|
+
/**
|
|
29
|
+
* Turn {@link root} into a POSIX filesystem root:
|
|
30
|
+
*
|
|
31
|
+
* 1. Expand one-or-many input segments
|
|
32
|
+
* 2. Strings split on `/` (and `\`); objects/arrays FNV-hash as one piece
|
|
33
|
+
* 3. Each resulting component that cannot be a path component - see
|
|
34
|
+
* {@link UNSAFE_PATH_SEGMENT} - is replaced with {@link hash.fnvHash}
|
|
35
|
+
* 4. Join with `/` and run {@link posixPath.normalizeRoot}
|
|
36
|
+
*
|
|
37
|
+
* Defaults to `/`. A leading `/` on the first string segment is preserved.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* normalizeFileSystemRoot("/cool/wow"); // "/cool/wow"
|
|
41
|
+
* normalizeFileSystemRoot("/Users/me@corp.com/My Notes"); // unchanged
|
|
42
|
+
* normalizeFileSystemRoot(["/path", { user: 1 }, true]); // "/path/<hash>/true"
|
|
43
|
+
*/
|
|
44
|
+
export declare function normalizeFileSystemRoot(root?: FileSystemRootInput): string;
|
|
45
|
+
export type FileSystemErrorCode = "NOT_FOUND" | "ALREADY_EXISTS" | "NOT_DIRECTORY" | "IS_DIRECTORY" | "DIRECTORY_NOT_EMPTY" | "PERMISSION_DENIED" | "READ_ONLY" | "INVALID_PATH" | "NOT_SUPPORTED" | "IO_ERROR";
|
|
46
|
+
export declare class FileSystemError extends Error {
|
|
47
|
+
readonly code: FileSystemErrorCode;
|
|
48
|
+
readonly path?: string | undefined;
|
|
49
|
+
readonly name = "FileSystemError";
|
|
50
|
+
constructor(code: FileSystemErrorCode, message: string, path?: string | undefined, options?: {
|
|
51
|
+
cause?: unknown;
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Infer a {@link FileSystemErrorCode} from HTTP status / message tokens on an
|
|
56
|
+
* unknown thrown value (via {@link error.errorContext}).
|
|
57
|
+
*
|
|
58
|
+
* Covers common SDK / REST wording so adapters do not reimplement the same
|
|
59
|
+
* "not found" / "already exists" checks. Returns undefined when nothing matches.
|
|
60
|
+
*/
|
|
61
|
+
export declare function inferFileSystemErrorCode(err: unknown): FileSystemErrorCode | undefined;
|
|
62
|
+
/**
|
|
63
|
+
* Map an unknown backend failure into a {@link FileSystemError}.
|
|
64
|
+
*
|
|
65
|
+
* Prefer a backend-specific {@link codeOf} classifier (errno, SDK code). When
|
|
66
|
+
* it returns undefined, falls back to {@link inferFileSystemErrorCode}. Message
|
|
67
|
+
* and cause always go through `@dbx-tools/shared-core` {@link error} helpers.
|
|
68
|
+
*/
|
|
69
|
+
export declare function mapFileSystemError(err: unknown, filePath: string, codeOf?: (err: unknown) => FileSystemErrorCode | undefined): FileSystemError;
|
|
70
|
+
export interface BaseFileSystemOptions<TBackend extends string = string> {
|
|
71
|
+
id: string;
|
|
72
|
+
backend: TBackend;
|
|
73
|
+
/**
|
|
74
|
+
* Filesystem root. One segment or a list of segments ({@link FileSystemRootInput}):
|
|
75
|
+
* primitives stringify, objects/arrays are FNV-hashed, then joined with `/`
|
|
76
|
+
* and normalized via {@link posixPath.normalizeRoot}. Defaults to `/`.
|
|
77
|
+
*/
|
|
78
|
+
root?: FileSystemRootInput;
|
|
79
|
+
readOnly?: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Ensure {@link root} exists during init by calling {@link createRootDirectory}.
|
|
82
|
+
* Defaults to false (remote roots usually already exist). Local disk adapters
|
|
83
|
+
* typically pass true and override {@link createRootDirectory}.
|
|
84
|
+
*/
|
|
85
|
+
createRoot?: boolean;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Base implementation for local, remote, and virtual filesystems.
|
|
89
|
+
*
|
|
90
|
+
* Subclasses implement the low-level `*At` primitives. This class provides:
|
|
91
|
+
*
|
|
92
|
+
* - Memoized {@link _init} (so an explicit {@link init} call is optional)
|
|
93
|
+
* - Optional root creation via {@link createRootDirectory}
|
|
94
|
+
* - POSIX-only rooted path normalization and traversal protection
|
|
95
|
+
* - {@link toBackendPath} for host/separator conversion at the boundary
|
|
96
|
+
* - Text encoding and decoding
|
|
97
|
+
* - {@link exists}
|
|
98
|
+
* - Parent-directory creation on write / append / copy / move
|
|
99
|
+
* - Append / copy / move fallbacks (override `try*` for native ops)
|
|
100
|
+
* - Recursive mkdir, readdir, and rmdir
|
|
101
|
+
* - Extension filtering for {@link readdir}
|
|
102
|
+
*
|
|
103
|
+
* Namespace paths always use `/`. Host adapters convert with
|
|
104
|
+
* {@link posixPath.toPosix} / {@link posixPath.toHost} in {@link toBackendPath}.
|
|
105
|
+
*/
|
|
106
|
+
export declare abstract class BaseFileSystem<TBackend extends string = string> implements FileSystem<TBackend> {
|
|
107
|
+
readonly id: string;
|
|
108
|
+
readonly backend: TBackend;
|
|
109
|
+
/** POSIX-normalized root (see {@link posixPath.normalizeRoot}). */
|
|
110
|
+
readonly root: string;
|
|
111
|
+
readonly readOnly: boolean;
|
|
112
|
+
protected readonly createRoot: boolean;
|
|
113
|
+
/**
|
|
114
|
+
* Memoized initialization. Every operation that needs a ready backend awaits
|
|
115
|
+
* this, so callers (e.g. Mastra) may call {@link init} every time or never;
|
|
116
|
+
* both are fine.
|
|
117
|
+
*/
|
|
118
|
+
protected _init: () => Promise<void>;
|
|
119
|
+
private initStarted;
|
|
120
|
+
protected constructor(options: BaseFileSystemOptions<TBackend>);
|
|
121
|
+
private createInit;
|
|
122
|
+
init(): Promise<void>;
|
|
123
|
+
close(): Promise<void>;
|
|
124
|
+
/**
|
|
125
|
+
* Ensure {@link root} exists when {@link createRoot} is true.
|
|
126
|
+
*
|
|
127
|
+
* Default is a no-op. Local adapters typically `mkdir -p`; remote adapters
|
|
128
|
+
* leave the default when the root is provisioned out of band.
|
|
129
|
+
*/
|
|
130
|
+
protected createRootDirectory(): Promise<void>;
|
|
131
|
+
/** Override when the backend requires connection or validation work. */
|
|
132
|
+
protected onInit(): Promise<void>;
|
|
133
|
+
/** Override when the backend owns connections or other resources. */
|
|
134
|
+
protected onClose(): Promise<void>;
|
|
135
|
+
protected assertWritable(operation: string): void;
|
|
136
|
+
/**
|
|
137
|
+
* Normalize an input path into an absolute POSIX path inside the virtual
|
|
138
|
+
* filesystem namespace (`/a/b`). Backslashes are converted; `..` escaping
|
|
139
|
+
* the root throws {@link FileSystemError} `PERMISSION_DENIED`.
|
|
140
|
+
*/
|
|
141
|
+
protected normalizePath(inputPath: string): string;
|
|
142
|
+
/**
|
|
143
|
+
* Convert a POSIX backend path (under {@link root}) into the form the
|
|
144
|
+
* underlying API expects.
|
|
145
|
+
*
|
|
146
|
+
* Default is identity. Local disk overrides with {@link posixPath.toHost}.
|
|
147
|
+
* Databricks / object-store adapters usually leave the default.
|
|
148
|
+
*/
|
|
149
|
+
protected toBackendPath(posixBackendPath: string): string;
|
|
150
|
+
/**
|
|
151
|
+
* Convert a normalized namespace path (`/a/b`) into a backend path.
|
|
152
|
+
*
|
|
153
|
+
* Joins {@link root} with the namespace using POSIX `/`, then applies
|
|
154
|
+
* {@link toBackendPath}. Override {@link toBackendPath} instead of this
|
|
155
|
+
* method unless the join itself must change.
|
|
156
|
+
*/
|
|
157
|
+
protected resolveBackendPath(namespacePath: string): string;
|
|
158
|
+
resolvePath(inputPath: string): string;
|
|
159
|
+
/**
|
|
160
|
+
* Resolve {@link inputPath}, ensure init, and run {@link preparePath}.
|
|
161
|
+
*/
|
|
162
|
+
protected resolveFor(inputPath: string, options?: {
|
|
163
|
+
allowMissing?: boolean;
|
|
164
|
+
}): Promise<string>;
|
|
165
|
+
/**
|
|
166
|
+
* {@link resolveFor} for a path that is ALREADY a normalized namespace path
|
|
167
|
+
* (`/a/b`). The single spelling for "namespace path to prepared backend
|
|
168
|
+
* path", so no call site has to re-derive the chain by hand.
|
|
169
|
+
*/
|
|
170
|
+
private resolveNamespaceFor;
|
|
171
|
+
/**
|
|
172
|
+
* Hook after lexical resolution. Override for realpath containment or
|
|
173
|
+
* similar backend-specific checks. Default is a no-op.
|
|
174
|
+
*/
|
|
175
|
+
protected preparePath(resolvedPath: string, _options?: {
|
|
176
|
+
allowMissing?: boolean;
|
|
177
|
+
}): Promise<string>;
|
|
178
|
+
protected joinNamespace(parent: string, child: string): string;
|
|
179
|
+
/** Namespace path without a leading slash (`.` for the root). */
|
|
180
|
+
protected toRelativePath(namespacePath: string): string;
|
|
181
|
+
protected toBytes(content: FileContent): Uint8Array;
|
|
182
|
+
/** Create parent directories for {@link inputPath} when it is nested. */
|
|
183
|
+
protected ensureParentDirectory(inputPath: string): Promise<void>;
|
|
184
|
+
protected abstract readBytesAt(resolvedPath: string): Promise<Uint8Array>;
|
|
185
|
+
protected abstract writeBytesAt(resolvedPath: string, content: Uint8Array, options: Required<WriteFileOptions>): Promise<void>;
|
|
186
|
+
protected abstract deleteFileAt(resolvedPath: string): Promise<void>;
|
|
187
|
+
protected abstract createDirectoryAt(resolvedPath: string): Promise<void>;
|
|
188
|
+
/**
|
|
189
|
+
* Remove an empty directory.
|
|
190
|
+
*
|
|
191
|
+
* Recursive deletion is implemented by {@link BaseFileSystem}.
|
|
192
|
+
*/
|
|
193
|
+
protected abstract removeDirectoryAt(resolvedPath: string): Promise<void>;
|
|
194
|
+
/** Return only the direct children of a directory (`name` is the basename). */
|
|
195
|
+
protected abstract listDirectoryAt(resolvedPath: string): Promise<FileEntry[]>;
|
|
196
|
+
protected abstract statAt(resolvedPath: string): Promise<Omit<FileStat, "path">>;
|
|
197
|
+
/**
|
|
198
|
+
* Recognize the backend's not-found error.
|
|
199
|
+
*
|
|
200
|
+
* Default accepts {@link FileSystemError} `NOT_FOUND` plus common SDK / HTTP
|
|
201
|
+
* "not found" shapes via {@link inferFileSystemErrorCode}. Override for
|
|
202
|
+
* backend-specific codes (e.g. Node `ENOENT`) that do not carry a message.
|
|
203
|
+
*/
|
|
204
|
+
protected isNotFoundError(err: unknown): boolean;
|
|
205
|
+
/**
|
|
206
|
+
* Normalize a backend failure into a {@link FileSystemError}.
|
|
207
|
+
*
|
|
208
|
+
* Every `*At` / `try*` primitive is invoked through {@link guard}, so an
|
|
209
|
+
* adapter never writes its own try/catch and cannot forget to normalize.
|
|
210
|
+
* Override only to classify backend-specific codes (e.g. Node errno).
|
|
211
|
+
*/
|
|
212
|
+
protected mapError(err: unknown, filePath: string): FileSystemError;
|
|
213
|
+
/** Run a backend primitive, routing any failure through {@link mapError}. */
|
|
214
|
+
private guard;
|
|
215
|
+
/**
|
|
216
|
+
* Override when the backend supports native append.
|
|
217
|
+
*
|
|
218
|
+
* Parent directories are already created by {@link appendFile}. Return true
|
|
219
|
+
* when the operation was performed. The default causes {@link BaseFileSystem}
|
|
220
|
+
* to use read-concatenate-write.
|
|
221
|
+
*/
|
|
222
|
+
protected tryAppendFileAt(_resolvedPath: string, _content: Uint8Array): Promise<boolean>;
|
|
223
|
+
/**
|
|
224
|
+
* Override when the backend supports native server-side copying.
|
|
225
|
+
*
|
|
226
|
+
* Parent directories of the destination are already created by {@link copyFile}.
|
|
227
|
+
*/
|
|
228
|
+
protected tryCopyFileAt(_sourcePath: string, _destinationPath: string, _options: Required<CopyOptions>): Promise<boolean>;
|
|
229
|
+
/**
|
|
230
|
+
* Override for native rename or move support.
|
|
231
|
+
*
|
|
232
|
+
* Parent directories of the destination are already created by {@link moveFile}.
|
|
233
|
+
*/
|
|
234
|
+
protected tryMoveFileAt(_sourcePath: string, _destinationPath: string, _options: Required<CopyOptions>): Promise<boolean>;
|
|
235
|
+
readFile(inputPath: string): Promise<Uint8Array>;
|
|
236
|
+
readFile(inputPath: string, options: ReadFileOptions & {
|
|
237
|
+
encoding: string;
|
|
238
|
+
}): Promise<string>;
|
|
239
|
+
writeFile(inputPath: string, content: FileContent, options?: WriteFileOptions): Promise<void>;
|
|
240
|
+
appendFile(inputPath: string, content: FileContent): Promise<void>;
|
|
241
|
+
deleteFile(inputPath: string, options?: RemoveOptions): Promise<void>;
|
|
242
|
+
copyFile(sourcePath: string, destinationPath: string, options?: CopyOptions): Promise<void>;
|
|
243
|
+
moveFile(sourcePath: string, destinationPath: string, options?: CopyOptions): Promise<void>;
|
|
244
|
+
/**
|
|
245
|
+
* Resolve the effective `overwrite` flag, rejecting when the target exists
|
|
246
|
+
* and overwriting was refused. Shared by write / copy / move so the three
|
|
247
|
+
* cannot disagree about what `overwrite: false` means.
|
|
248
|
+
*/
|
|
249
|
+
private resolveOverwrite;
|
|
250
|
+
/** Shared copy / move prologue: writability, overwrite policy, both ends resolved. */
|
|
251
|
+
private prepareTransfer;
|
|
252
|
+
/** Run a removal, swallowing a not-found failure when `force` is set. */
|
|
253
|
+
private ignoringMissing;
|
|
254
|
+
mkdir(inputPath: string, options?: MakeDirectoryOptions): Promise<void>;
|
|
255
|
+
rmdir(inputPath: string, options?: RemoveOptions): Promise<void>;
|
|
256
|
+
private removeDirectoryContents;
|
|
257
|
+
/** {@link createDirectoryAt} for a namespace path, resolved and guarded. */
|
|
258
|
+
private createDirectory;
|
|
259
|
+
/** {@link removeDirectoryAt} for a namespace path, resolved and guarded. */
|
|
260
|
+
private removeDirectory;
|
|
261
|
+
/** {@link listDirectoryAt} for a namespace path, resolved and guarded. */
|
|
262
|
+
private listDirectory;
|
|
263
|
+
readdir(inputPath: string, options?: ListOptions): Promise<FileEntry[]>;
|
|
264
|
+
private listDirectoryRecursive;
|
|
265
|
+
private filterEntries;
|
|
266
|
+
exists(inputPath: string): Promise<boolean>;
|
|
267
|
+
stat(inputPath: string): Promise<FileStat>;
|
|
268
|
+
}
|