@openclaw/fs-safe 0.10.0 → 0.12.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/CHANGELOG.md +114 -0
- package/LICENSE +1 -0
- package/README.md +39 -6
- package/dist/absolute-path.d.ts.map +1 -1
- package/dist/absolute-path.js +3 -2
- package/dist/advanced.d.ts +5 -1
- package/dist/advanced.d.ts.map +1 -1
- package/dist/advanced.js +5 -1
- package/dist/archive-durability.d.ts +6 -6
- package/dist/archive-durability.d.ts.map +1 -1
- package/dist/archive-durability.js +1 -1
- package/dist/archive-entry.d.ts.map +1 -1
- package/dist/archive-entry.js +8 -8
- package/dist/archive-gzip-tail.d.ts +1 -0
- package/dist/archive-gzip-tail.d.ts.map +1 -1
- package/dist/archive-gzip-tail.js +16 -9
- package/dist/archive-input.d.ts.map +1 -1
- package/dist/archive-input.js +4 -2
- package/dist/archive-merge.d.ts +5 -1
- package/dist/archive-merge.d.ts.map +1 -1
- package/dist/archive-merge.js +15 -12
- package/dist/archive-native.js +4 -4
- package/dist/archive-parser.wasm +0 -0
- package/dist/archive-read.d.ts.map +1 -1
- package/dist/archive-read.js +54 -42
- package/dist/archive-staging.d.ts +6 -3
- package/dist/archive-staging.d.ts.map +1 -1
- package/dist/archive-staging.js +42 -22
- package/dist/archive-tar-stream.d.ts.map +1 -1
- package/dist/archive-tar-stream.js +7 -6
- package/dist/archive-tar-wasm.d.ts.map +1 -1
- package/dist/archive-tar-wasm.js +16 -13
- package/dist/archive-zip-admission.d.ts +1 -1
- package/dist/archive-zip-admission.d.ts.map +1 -1
- package/dist/archive-zip-admission.js +48 -12
- package/dist/archive-zip-loader.d.ts +6 -0
- package/dist/archive-zip-loader.d.ts.map +1 -0
- package/dist/archive-zip-loader.js +38 -0
- package/dist/archive-zip-names.d.ts.map +1 -1
- package/dist/archive-zip-names.js +26 -9
- package/dist/archive-zip-preflight.d.ts +2 -3
- package/dist/archive-zip-preflight.d.ts.map +1 -1
- package/dist/archive-zip-preflight.js +2 -34
- package/dist/archive.d.ts.map +1 -1
- package/dist/archive.js +12 -10
- package/dist/bounded-read.d.ts +5 -0
- package/dist/bounded-read.d.ts.map +1 -1
- package/dist/bounded-read.js +18 -11
- package/dist/copy-file-input.d.ts +0 -1
- package/dist/copy-file-input.d.ts.map +1 -1
- package/dist/copy-file-input.js +4 -26
- package/dist/copy-tree-portable.d.ts.map +1 -1
- package/dist/copy-tree-portable.js +57 -26
- package/dist/copy.d.ts +1 -1
- package/dist/copy.d.ts.map +1 -1
- package/dist/copy.js +3 -1
- package/dist/device-path.d.ts.map +1 -1
- package/dist/device-path.js +5 -3
- package/dist/directory-durability.d.ts.map +1 -1
- package/dist/directory-durability.js +5 -4
- package/dist/directory-guard.d.ts +11 -1
- package/dist/directory-guard.d.ts.map +1 -1
- package/dist/directory-guard.js +53 -11
- package/dist/durability.d.ts +1 -1
- package/dist/durability.d.ts.map +1 -1
- package/dist/durability.js +1 -1
- package/dist/file-handle-transfer.d.ts +14 -0
- package/dist/file-handle-transfer.d.ts.map +1 -0
- package/dist/file-handle-transfer.js +64 -0
- package/dist/file-hash.d.ts +3 -0
- package/dist/file-hash.d.ts.map +1 -1
- package/dist/file-hash.js +99 -32
- package/dist/file-lock-sync.d.ts.map +1 -1
- package/dist/file-lock-sync.js +8 -4
- package/dist/file-store-boundary.d.ts.map +1 -1
- package/dist/file-store-boundary.js +7 -5
- package/dist/file-store-path.d.ts +3 -0
- package/dist/file-store-path.d.ts.map +1 -0
- package/dist/file-store-path.js +27 -0
- package/dist/file-store-prune.d.ts.map +1 -1
- package/dist/file-store-prune.js +15 -5
- package/dist/file-store-sync-write.d.ts.map +1 -1
- package/dist/file-store-sync-write.js +56 -44
- package/dist/file-store.d.ts.map +1 -1
- package/dist/file-store.js +2 -18
- package/dist/filename.d.ts +1 -0
- package/dist/filename.d.ts.map +1 -1
- package/dist/filename.js +32 -14
- package/dist/guarded-mkdir.d.ts +2 -0
- package/dist/guarded-mkdir.d.ts.map +1 -1
- package/dist/guarded-mkdir.js +52 -16
- package/dist/guest-dispatch-python.d.ts +2 -0
- package/dist/guest-dispatch-python.d.ts.map +1 -0
- package/dist/guest-dispatch-python.js +117 -0
- package/dist/guest-native-python.d.ts +4 -0
- package/dist/guest-native-python.d.ts.map +1 -0
- package/dist/guest-native-python.js +135 -0
- package/dist/guest.d.ts +9 -0
- package/dist/guest.d.ts.map +1 -0
- package/dist/guest.js +421 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/install-path.d.ts +6 -0
- package/dist/install-path.d.ts.map +1 -1
- package/dist/install-path.js +16 -2
- package/dist/json-durable-queue-directory.js +3 -3
- package/dist/json-durable-queue-ownership.d.ts +2 -0
- package/dist/json-durable-queue-ownership.d.ts.map +1 -1
- package/dist/json-durable-queue-ownership.js +47 -3
- package/dist/json-durable-queue-read.d.ts +6 -0
- package/dist/json-durable-queue-read.d.ts.map +1 -0
- package/dist/json-durable-queue-read.js +59 -0
- package/dist/json-durable-queue.d.ts +1 -1
- package/dist/json-durable-queue.d.ts.map +1 -1
- package/dist/json-durable-queue.js +43 -84
- package/dist/json.d.ts.map +1 -1
- package/dist/json.js +2 -1
- package/dist/local-roots.d.ts.map +1 -1
- package/dist/local-roots.js +2 -1
- package/dist/move-path-stage.d.ts.map +1 -1
- package/dist/move-path-stage.js +2 -1
- package/dist/move-path.d.ts.map +1 -1
- package/dist/move-path.js +4 -3
- package/dist/mutation-authority.d.ts +1 -0
- package/dist/mutation-authority.d.ts.map +1 -1
- package/dist/mutation-authority.js +4 -4
- package/dist/native-binding.d.ts +14 -2
- package/dist/native-binding.d.ts.map +1 -1
- package/dist/native-pinned-write-windows.d.ts.map +1 -1
- package/dist/native-pinned-write-windows.js +3 -2
- package/dist/native-pinned-write.d.ts.map +1 -1
- package/dist/native-pinned-write.js +2 -1
- package/dist/opened-realpath.d.ts.map +1 -1
- package/dist/opened-realpath.js +5 -4
- package/dist/output.d.ts +2 -0
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +2 -0
- package/dist/overwrite-file-handle.d.ts +8 -0
- package/dist/overwrite-file-handle.d.ts.map +1 -0
- package/dist/overwrite-file-handle.js +42 -0
- package/dist/path-case.d.ts +7 -0
- package/dist/path-case.d.ts.map +1 -0
- package/dist/path-case.js +136 -0
- package/dist/path-scope-lexical.d.ts +14 -0
- package/dist/path-scope-lexical.d.ts.map +1 -0
- package/dist/path-scope-lexical.js +27 -0
- package/dist/path.d.ts.map +1 -1
- package/dist/path.js +22 -3
- package/dist/permissions-windows.d.ts +1 -1
- package/dist/permissions-windows.d.ts.map +1 -1
- package/dist/permissions-windows.js +48 -6
- package/dist/pinned-open.d.ts.map +1 -1
- package/dist/pinned-open.js +3 -1
- package/dist/pinned-write.d.ts +2 -2
- package/dist/pinned-write.d.ts.map +1 -1
- package/dist/pinned-write.js +3 -1
- package/dist/private-temp-workspace.d.ts.map +1 -1
- package/dist/private-temp-workspace.js +6 -4
- package/dist/realpath.d.ts +4 -0
- package/dist/realpath.d.ts.map +1 -0
- package/dist/realpath.js +43 -0
- package/dist/recursive-mkdir-path.d.ts +3 -0
- package/dist/recursive-mkdir-path.d.ts.map +1 -0
- package/dist/recursive-mkdir-path.js +8 -0
- package/dist/replace-directory.d.ts.map +1 -1
- package/dist/replace-directory.js +2 -1
- package/dist/replace-file-copy-fallback.d.ts.map +1 -1
- package/dist/replace-file-copy-fallback.js +23 -31
- package/dist/replace-file-copy-source.d.ts.map +1 -1
- package/dist/replace-file-copy-source.js +7 -12
- package/dist/replace-file-mode.d.ts +3 -0
- package/dist/replace-file-mode.d.ts.map +1 -0
- package/dist/replace-file-mode.js +10 -0
- package/dist/replace-file.d.ts +1 -0
- package/dist/replace-file.d.ts.map +1 -1
- package/dist/replace-file.js +14 -8
- package/dist/root-boundary.d.ts +25 -0
- package/dist/root-boundary.d.ts.map +1 -0
- package/dist/root-boundary.js +177 -0
- package/dist/root-context.d.ts.map +1 -1
- package/dist/root-context.js +40 -13
- package/dist/root-create-input.d.ts +10 -0
- package/dist/root-create-input.d.ts.map +1 -0
- package/dist/root-create-input.js +80 -0
- package/dist/root-directory-list.d.ts +3 -1
- package/dist/root-directory-list.d.ts.map +1 -1
- package/dist/root-directory-list.js +31 -5
- package/dist/root-entries.d.ts +11 -0
- package/dist/root-entries.d.ts.map +1 -0
- package/dist/root-entries.js +61 -0
- package/dist/root-errors.d.ts +5 -5
- package/dist/root-errors.d.ts.map +1 -1
- package/dist/root-errors.js +13 -12
- package/dist/root-impl.d.ts +13 -3
- package/dist/root-impl.d.ts.map +1 -1
- package/dist/root-impl.js +93 -70
- package/dist/root-move-preflight.d.ts +8 -0
- package/dist/root-move-preflight.d.ts.map +1 -0
- package/dist/root-move-preflight.js +16 -0
- package/dist/root-options.d.ts +12 -1
- package/dist/root-options.d.ts.map +1 -1
- package/dist/root-path-existing.d.ts +2 -0
- package/dist/root-path-existing.d.ts.map +1 -1
- package/dist/root-path-existing.js +14 -5
- package/dist/root-path-symlink.d.ts.map +1 -1
- package/dist/root-path-symlink.js +3 -2
- package/dist/root-path.d.ts +2 -0
- package/dist/root-path.d.ts.map +1 -1
- package/dist/root-path.js +54 -26
- package/dist/root-paths.d.ts +2 -6
- package/dist/root-paths.d.ts.map +1 -1
- package/dist/root-paths.js +24 -32
- package/dist/root-remove.d.ts +5 -0
- package/dist/root-remove.d.ts.map +1 -0
- package/dist/root-remove.js +286 -0
- package/dist/root-symlink-policy.d.ts +2 -1
- package/dist/root-symlink-policy.d.ts.map +1 -1
- package/dist/root-symlink-policy.js +2 -2
- package/dist/root-walk.d.ts.map +1 -1
- package/dist/root-walk.js +2 -1
- package/dist/root-write-mode.d.ts +2 -0
- package/dist/root-write-mode.d.ts.map +1 -1
- package/dist/root-write-mode.js +21 -7
- package/dist/root-write-verification.d.ts.map +1 -1
- package/dist/root-write-verification.js +12 -3
- package/dist/root.d.ts +2 -1
- package/dist/root.d.ts.map +1 -1
- package/dist/safe-path-segment.d.ts.map +1 -1
- package/dist/safe-path-segment.js +3 -1
- package/dist/secret-file.d.ts.map +1 -1
- package/dist/secret-file.js +2 -1
- package/dist/secret-read-async.d.ts.map +1 -1
- package/dist/secret-read-async.js +2 -1
- package/dist/secure-file-windows.d.ts +10 -0
- package/dist/secure-file-windows.d.ts.map +1 -0
- package/dist/secure-file-windows.js +186 -0
- package/dist/secure-file.d.ts.map +1 -1
- package/dist/secure-file.js +27 -7
- package/dist/secure-temp-dir.d.ts.map +1 -1
- package/dist/secure-temp-dir.js +2 -1
- package/dist/sibling-staged-file.d.ts +2 -0
- package/dist/sibling-staged-file.d.ts.map +1 -1
- package/dist/sibling-staged-file.js +49 -8
- package/dist/sibling-temp.d.ts +2 -0
- package/dist/sibling-temp.d.ts.map +1 -1
- package/dist/sibling-temp.js +8 -5
- package/dist/sidecar-lock-acquire.d.ts.map +1 -1
- package/dist/sidecar-lock-acquire.js +16 -5
- package/dist/sidecar-lock-policy.d.ts +2 -0
- package/dist/sidecar-lock-policy.d.ts.map +1 -1
- package/dist/sidecar-lock-policy.js +17 -0
- package/dist/sidecar-lock.d.ts.map +1 -1
- package/dist/sidecar-lock.js +2 -3
- package/dist/staged-directory.d.ts.map +1 -1
- package/dist/staged-directory.js +4 -3
- package/dist/temp-target.d.ts +14 -12
- package/dist/temp-target.d.ts.map +1 -1
- package/dist/temp-target.js +15 -7
- package/dist/trash.d.ts.map +1 -1
- package/dist/trash.js +7 -5
- package/dist/unicode-path.d.ts +3 -0
- package/dist/unicode-path.d.ts.map +1 -0
- package/dist/unicode-path.js +13 -0
- package/dist/walk.d.ts.map +1 -1
- package/dist/walk.js +14 -12
- package/dist/write-file-handle.d.ts +1 -0
- package/dist/write-file-handle.d.ts.map +1 -1
- package/dist/write-file-handle.js +3 -2
- package/docs/advanced.md +7 -1
- package/docs/archive.md +31 -5
- package/docs/atomic.md +17 -1
- package/docs/config.md +1 -0
- package/docs/contributing.md +33 -2
- package/docs/copy.md +75 -6
- package/docs/directory-identity.md +85 -0
- package/docs/durability.md +40 -3
- package/docs/entries.md +109 -0
- package/docs/errors.md +3 -3
- package/docs/file-store.md +21 -0
- package/docs/filename.md +9 -2
- package/docs/guest.md +146 -0
- package/docs/in-place-write.md +81 -0
- package/docs/index.md +2 -0
- package/docs/install-path.md +59 -13
- package/docs/install.md +34 -0
- package/docs/native-helper.md +14 -5
- package/docs/native.md +18 -2
- package/docs/output.md +32 -6
- package/docs/path-case.md +64 -0
- package/docs/path-scope.md +1 -1
- package/docs/path.md +1 -1
- package/docs/permissions.md +37 -3
- package/docs/public-api.md +36 -2
- package/docs/root.md +33 -3
- package/docs/secure-file.md +17 -14
- package/docs/security-model.md +1 -1
- package/docs/sidecar-lock.md +12 -3
- package/docs/store.md +22 -1
- package/docs/temp.md +39 -6
- package/docs/types.md +1 -1
- package/docs/writing.md +153 -3
- package/package.json +14 -8
package/dist/root-impl.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import type { Stats } from "node:fs";
|
|
1
|
+
import type { BigIntStats, Stats } from "node:fs";
|
|
2
2
|
import type { FileHandle } from "node:fs/promises";
|
|
3
3
|
import type { ContainmentGuarantee } from "./containment.js";
|
|
4
4
|
import { type ReadResult } from "./read-opened-file.js";
|
|
5
|
+
import { type RootEntriesOptions } from "./root-entries.js";
|
|
5
6
|
import { type RootContext } from "./root-context.js";
|
|
6
7
|
import type { DirEntry, PathStat } from "./types.js";
|
|
7
8
|
import { type RootWalkEntry, type RootWalkOptions } from "./root-walk.js";
|
|
8
|
-
import { type RootAppendOptions, type RootCopyOptions, type RootCopySource, type RootCreateJsonOptions, type RootCreateOptions, type RootDefaults, type RootMkdirOptions, type RootMoveOptions, type RootOpenOptions, type RootOpenWritableOptions, type RootReadOptions, type RootRemoveOptions, type RootWriteJsonOptions, type RootWriteOptions } from "./root-options.js";
|
|
9
|
-
export type { HardlinkPolicy, RootAppendOptions, RootCopyOptions, RootCopySource, RootCreateJsonOptions, RootCreateOptions, RootDefaults, RootMkdirOptions, RootMoveOptions, RootOpenOptions, RootOpenWritableOptions, RootOptions, RootReadOptions, RootRemoveOptions, RootWriteJsonOptions, RootWriteOptions, WritableOpenMode, } from "./root-options.js";
|
|
9
|
+
import { type RootAppendOptions, type RootCopyOptions, type RootCopySource, type RootCreateJsonOptions, type RootCreateOptions, type RootCreateStreamOptions, type RootDefaults, type RootMkdirOptions, type RootMoveOptions, type RootOpenOptions, type RootOpenWritableOptions, type RootReadOptions, type RootRemoveOptions, type RootWriteJsonOptions, type RootWriteOptions } from "./root-options.js";
|
|
10
|
+
export type { HardlinkPolicy, RootAppendOptions, RootCopyOptions, RootCopySource, RootCreateJsonOptions, RootCreateOptions, RootCreateStreamOptions, RootDefaults, RootMkdirOptions, RootMoveOptions, RootOpenOptions, RootOpenWritableOptions, RootOptions, RootReadOptions, RootRemoveOptions, RootWriteJsonOptions, RootWriteOptions, WritableOpenMode, } from "./root-options.js";
|
|
10
11
|
export { DEFAULT_ROOT_MAX_BYTES } from "./root-options.js";
|
|
11
12
|
export type { DenyMutationPolicy } from "./deny-mutations.js";
|
|
12
13
|
export type { RenameIdentityPolicy } from "./pinned-write.js";
|
|
@@ -44,6 +45,7 @@ export interface Root {
|
|
|
44
45
|
ensureRoot(options?: RootMkdirOptions): Promise<void>;
|
|
45
46
|
write(relativePath: string, data: string | Buffer, options?: RootWriteOptions): Promise<void>;
|
|
46
47
|
create(relativePath: string, data: string | Buffer, options?: RootCreateOptions): Promise<void>;
|
|
48
|
+
create(relativePath: string, data: AsyncIterable<Uint8Array>, options?: RootCreateStreamOptions): Promise<void>;
|
|
47
49
|
writeJson(relativePath: string, data: unknown, options?: RootWriteJsonOptions): Promise<void>;
|
|
48
50
|
createJson(relativePath: string, data: unknown, options?: RootCreateJsonOptions): Promise<void>;
|
|
49
51
|
copyIn(relativePath: string, source: RootCopySource, options?: RootCopyOptions): Promise<void>;
|
|
@@ -55,6 +57,7 @@ export interface Root {
|
|
|
55
57
|
list(relativePath: string, options: {
|
|
56
58
|
withFileTypes: true;
|
|
57
59
|
}): Promise<DirEntry[]>;
|
|
60
|
+
entries(relativePath: string, options?: RootEntriesOptions): AsyncIterableIterator<DirEntry>;
|
|
58
61
|
move(fromRelative: string, toRelative: string, options?: RootMoveOptions): Promise<void>;
|
|
59
62
|
walk(relativePath: string, options: RootWalkOptions): AsyncIterableIterator<RootWalkEntry>;
|
|
60
63
|
}
|
|
@@ -86,6 +89,7 @@ export declare class RootHandle implements Root {
|
|
|
86
89
|
ensureRoot(options?: RootMkdirOptions): Promise<void>;
|
|
87
90
|
write(relativePath: string, data: string | Buffer, options?: RootWriteOptions): Promise<void>;
|
|
88
91
|
create(relativePath: string, data: string | Buffer, options?: RootCreateOptions): Promise<void>;
|
|
92
|
+
create(relativePath: string, data: AsyncIterable<Uint8Array>, options?: RootCreateStreamOptions): Promise<void>;
|
|
89
93
|
writeJson(relativePath: string, data: unknown, options?: RootWriteJsonOptions): Promise<void>;
|
|
90
94
|
createJson(relativePath: string, data: unknown, options?: RootCreateJsonOptions): Promise<void>;
|
|
91
95
|
copyIn(relativePath: string, source: RootCopySource, options?: RootCopyOptions): Promise<void>;
|
|
@@ -98,9 +102,15 @@ export declare class RootHandle implements Root {
|
|
|
98
102
|
withFileTypes: true;
|
|
99
103
|
}): Promise<DirEntry[]>;
|
|
100
104
|
move(fromRelative: string, toRelative: string, options?: RootMoveOptions): Promise<void>;
|
|
105
|
+
entries(relativePath: string, options?: RootEntriesOptions): AsyncIterableIterator<DirEntry>;
|
|
101
106
|
walk(relativePath: string, options: RootWalkOptions): AsyncIterableIterator<RootWalkEntry>;
|
|
102
107
|
}
|
|
103
108
|
export declare function root(rootDir: string, defaults?: RootDefaults): Promise<Root>;
|
|
109
|
+
export declare function rootFromDirectoryGuard(guard: {
|
|
110
|
+
readonly dir: string;
|
|
111
|
+
readonly realPath: string;
|
|
112
|
+
readonly stat: BigIntStats;
|
|
113
|
+
}, defaults?: RootDefaults): Root;
|
|
104
114
|
export declare function readLocalFileSafely(params: {
|
|
105
115
|
filePath: string;
|
|
106
116
|
maxBytes?: number;
|
package/dist/root-impl.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"root-impl.d.ts","sourceRoot":"","sources":["../src/root-impl.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"root-impl.d.ts","sourceRoot":"","sources":["../src/root-impl.ts"],"names":[],"mappings":"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"}
|
package/dist/root-impl.js
CHANGED
|
@@ -69,25 +69,31 @@ import { runPinnedWriteHelper, runPinnedWriteWithRenamePolicy, } from "./pinned-
|
|
|
69
69
|
import { getNativeBinding } from "./native.js";
|
|
70
70
|
import { validatePinnedOperationPayload } from "./pinned-operation.js";
|
|
71
71
|
import { assertNoPathAliasEscape, PATH_ALIAS_POLICIES } from "./path-policy.js";
|
|
72
|
-
import { assertNoNulPathInput, assertNoUnsafeDeviceReadPath, hasNodeErrorCode, isNotFoundPathError,
|
|
72
|
+
import { assertNoNulPathInput, assertNoUnsafeDeviceReadPath, hasNodeErrorCode, isNotFoundPathError, isSymlinkOpenError, } from "./path.js";
|
|
73
73
|
import { readOpenedFileSafely } from "./read-opened-file.js";
|
|
74
74
|
import { cleanupPinnedFilePath } from "./replace-file-temp-owner.js";
|
|
75
75
|
import { resolveReadOpenFlags } from "./read-open-flags.js";
|
|
76
|
+
import { realpathSync } from "./realpath.js";
|
|
76
77
|
import { isNonRegularWriteOpenError, resolveNonblockingWriteFlag } from "./write-open-flags.js";
|
|
77
78
|
import { resolveRootPath } from "./root-path.js";
|
|
78
|
-
import {
|
|
79
|
+
import { admitPathInsideRoot } from "./root-boundary.js";
|
|
80
|
+
import { openRootDirectoryListing, listDirectoryPath, pathStatFromStats } from "./root-directory-list.js";
|
|
81
|
+
import { entriesInRoot } from "./root-entries.js";
|
|
82
|
+
import { assertMoveMutationAllowed } from "./root-move-preflight.js";
|
|
79
83
|
import { assertRootIdentityCurrent, assertValidRootDestinationPath, assertValidRootRelativePath, ensureTrailingSep, expandRelativePathWithHome, resolvePathInRoot, resolveRootContext, rootRelativeReadPath, } from "./root-context.js";
|
|
80
|
-
import { fileNotFoundError, hardlinkedPathNotAllowedError, isAlreadyExistsError, normalizePinnedPathError, normalizePinnedWriteError,
|
|
84
|
+
import { fileNotFoundError, hardlinkedPathNotAllowedError, isAlreadyExistsError, normalizePinnedPathError, normalizePinnedWriteError, outsideWorkspaceError, } from "./root-errors.js";
|
|
81
85
|
import { getFsSafeTestHooks } from "./test-hooks.js";
|
|
82
86
|
import { stringifyJsonDocument } from "./json-stringify.js";
|
|
83
87
|
import { walkRoot } from "./root-walk.js";
|
|
84
88
|
import { registerTempPathForExit } from "./temp-cleanup.js";
|
|
89
|
+
import { removePathInRootFallback, validateRemoveOptions } from "./root-remove.js";
|
|
85
90
|
import { serializePathWrite } from "./write-queue.js";
|
|
86
91
|
import { verifyAtomicWriteResult } from "./root-write-verification.js";
|
|
87
92
|
import { inheritWriteTargetMode } from "./root-write-mode.js";
|
|
88
93
|
import { inspectFileIdentity } from "./strict-file-identity.js";
|
|
89
94
|
import { createCopyPublicationObserver, onCopyPublication } from "./copy-publication.js";
|
|
90
95
|
import { writeAllToFile } from "./write-file-handle.js";
|
|
96
|
+
import { createInputOptions, rethrowCreateInputError, rootWriteInput } from "./root-create-input.js";
|
|
91
97
|
import { assertFinalSymlinkRejected, mutationSymlinkResolution, readSymlinkResolution } from "./root-symlink-policy.js";
|
|
92
98
|
import { mergeReadOptions, readDefaults, } from "./root-options.js";
|
|
93
99
|
import { composeMutationAssertions, MutationAuthorityError, rethrowMutationAuthorityError } from "./mutation-authority.js";
|
|
@@ -327,6 +333,8 @@ export class RootHandle {
|
|
|
327
333
|
}
|
|
328
334
|
async remove(relativePath, options = {}) {
|
|
329
335
|
assertValidRootRelativePath(relativePath);
|
|
336
|
+
validateRemoveOptions(options);
|
|
337
|
+
options.signal?.throwIfAborted();
|
|
330
338
|
await removePathInRoot(this.context, {
|
|
331
339
|
relativePath,
|
|
332
340
|
...this.mutationOptions(options),
|
|
@@ -365,10 +373,10 @@ export class RootHandle {
|
|
|
365
373
|
data,
|
|
366
374
|
mkdir: this.defaults.mkdir,
|
|
367
375
|
mode: this.defaults.mode,
|
|
368
|
-
...this.mutationOptions(options),
|
|
376
|
+
...this.mutationOptions(createInputOptions(data, options, this.defaults.maxBytes)),
|
|
369
377
|
durable: options.durable ?? this.defaults.durable ?? true,
|
|
370
378
|
overwrite: false,
|
|
371
|
-
}).catch(rethrowMutationAuthorityError);
|
|
379
|
+
}).catch(rethrowMutationAuthorityError).catch(rethrowCreateInputError);
|
|
372
380
|
}
|
|
373
381
|
async writeJson(relativePath, data, options = {}) {
|
|
374
382
|
const { replacer, space, trailingNewline = true, ...writeOptions } = options;
|
|
@@ -436,6 +444,13 @@ export class RootHandle {
|
|
|
436
444
|
toRelative,
|
|
437
445
|
}).catch(rethrowMutationAuthorityError);
|
|
438
446
|
}
|
|
447
|
+
entries(relativePath, options = {}) {
|
|
448
|
+
assertValidRootRelativePath(relativePath);
|
|
449
|
+
return entriesInRoot(this.context, relativePath, {
|
|
450
|
+
...options,
|
|
451
|
+
symlinks: options.symlinks ?? this.defaults.symlinks,
|
|
452
|
+
});
|
|
453
|
+
}
|
|
439
454
|
walk(relativePath, options) {
|
|
440
455
|
assertValidRootRelativePath(relativePath);
|
|
441
456
|
return walkRoot({
|
|
@@ -444,7 +459,7 @@ export class RootHandle {
|
|
|
444
459
|
list: async (relative, listingOptions) => {
|
|
445
460
|
validatePinnedOperationPayload({ relativePath: relative });
|
|
446
461
|
const resolved = await resolvePinnedPathInRoot(this.context, { relativePath: relative, allowRoot: true });
|
|
447
|
-
return await
|
|
462
|
+
return await openRootDirectoryListing(this.context, resolved.resolved, listingOptions);
|
|
448
463
|
},
|
|
449
464
|
}, relativePath, options);
|
|
450
465
|
}
|
|
@@ -453,8 +468,19 @@ export async function root(rootDir, defaults = {}) {
|
|
|
453
468
|
normalizeMaxBytes(defaults.maxBytes);
|
|
454
469
|
return new RootHandle(await resolveRootContext(rootDir), defaults);
|
|
455
470
|
}
|
|
471
|
+
// Internal callers that already hold an exact admitted directory capability must
|
|
472
|
+
// not recapture a different filesystem object while constructing the Root.
|
|
473
|
+
export function rootFromDirectoryGuard(guard, defaults = {}) {
|
|
474
|
+
normalizeMaxBytes(defaults.maxBytes);
|
|
475
|
+
return new RootHandle({
|
|
476
|
+
rootDir: path.resolve(guard.dir),
|
|
477
|
+
rootIdentity: { dev: guard.stat.dev, ino: guard.stat.ino },
|
|
478
|
+
rootReal: guard.realPath,
|
|
479
|
+
rootWithSep: ensureTrailingSep(guard.realPath),
|
|
480
|
+
}, defaults);
|
|
481
|
+
}
|
|
456
482
|
async function openFileInRoot(root, params) {
|
|
457
|
-
const {
|
|
483
|
+
const { resolved } = await resolvePathInRoot(root, params.relativePath, {
|
|
458
484
|
allowFinalSymlink: true,
|
|
459
485
|
rejectUnsafeDeviceReads: true,
|
|
460
486
|
...readSymlinkResolution(params.symlinks),
|
|
@@ -467,10 +493,16 @@ async function openFileInRoot(root, params) {
|
|
|
467
493
|
await opened.handle.close().catch(() => { });
|
|
468
494
|
throw hardlinkedPathNotAllowedError();
|
|
469
495
|
}
|
|
470
|
-
|
|
496
|
+
const admittedRealPath = admitPathInsideRoot({
|
|
497
|
+
rootPath: root.rootReal,
|
|
498
|
+
candidatePath: opened.realPath,
|
|
499
|
+
rootIdentity: root.rootIdentity,
|
|
500
|
+
});
|
|
501
|
+
if (!admittedRealPath) {
|
|
471
502
|
await opened.handle.close().catch(() => { });
|
|
472
503
|
throw outsideWorkspaceError();
|
|
473
504
|
}
|
|
505
|
+
opened.realPath = admittedRealPath.path;
|
|
474
506
|
return opened;
|
|
475
507
|
}
|
|
476
508
|
async function readFileInRoot(root, params) {
|
|
@@ -514,9 +546,10 @@ function buildAtomicWriteTempPath(targetPath) {
|
|
|
514
546
|
function rootWriteQueueKey(root, relativePath) {
|
|
515
547
|
return `${root.rootReal}\0${relativePath}`;
|
|
516
548
|
}
|
|
517
|
-
async function prepareRootWriteTarget(
|
|
549
|
+
async function prepareRootWriteTarget(root, targetPath, assertBeforeMutation) {
|
|
518
550
|
const parentPath = await mkdirPathComponentsWithGuards({
|
|
519
|
-
rootReal,
|
|
551
|
+
rootReal: root.rootReal,
|
|
552
|
+
rootIdentity: root.rootIdentity,
|
|
520
553
|
targetPath: path.dirname(targetPath),
|
|
521
554
|
assertBeforeMutation,
|
|
522
555
|
});
|
|
@@ -549,21 +582,26 @@ async function resolveGuardedWritePathInRoot(root, params) {
|
|
|
549
582
|
return resolvedPath;
|
|
550
583
|
}
|
|
551
584
|
async function openWritableFileInRoot(root, params) {
|
|
552
|
-
const {
|
|
585
|
+
const { resolved } = await resolveGuardedWritePathInRoot(root, {
|
|
553
586
|
relativePath: params.relativePath,
|
|
554
587
|
denyMutations: params.denyMutations,
|
|
555
588
|
mutationSymlinks: params.mutationSymlinks,
|
|
556
589
|
});
|
|
557
590
|
let ioPath = params.mkdir === false
|
|
558
591
|
? resolved
|
|
559
|
-
: await prepareRootWriteTarget(
|
|
592
|
+
: await prepareRootWriteTarget(root, resolved, params.assertBeforeMutation);
|
|
560
593
|
try {
|
|
561
594
|
assertFinalSymlinkRejected(ioPath, params.mutationSymlinks !== undefined);
|
|
562
|
-
const resolvedRealPath = params.mutationSymlinks === undefined ?
|
|
563
|
-
|
|
595
|
+
const resolvedRealPath = params.mutationSymlinks === undefined ? realpathSync.native(ioPath) : ioPath;
|
|
596
|
+
const admittedRealPath = admitPathInsideRoot({
|
|
597
|
+
rootPath: root.rootReal,
|
|
598
|
+
candidatePath: resolvedRealPath,
|
|
599
|
+
rootIdentity: root.rootIdentity,
|
|
600
|
+
});
|
|
601
|
+
if (!admittedRealPath) {
|
|
564
602
|
throw outsideWorkspaceError();
|
|
565
603
|
}
|
|
566
|
-
ioPath =
|
|
604
|
+
ioPath = admittedRealPath.path;
|
|
567
605
|
}
|
|
568
606
|
catch (err) {
|
|
569
607
|
if (err instanceof FsSafeError) {
|
|
@@ -633,8 +671,7 @@ async function openWritableFileInRoot(root, params) {
|
|
|
633
671
|
throw err;
|
|
634
672
|
}
|
|
635
673
|
}
|
|
636
|
-
|
|
637
|
-
realPathForCleanup = realPath;
|
|
674
|
+
let realPath = await resolveOpenedFileRealPathForHandle(handle, ioPath);
|
|
638
675
|
const realStat = fsSync.statSync(realPath);
|
|
639
676
|
if (!sameFileIdentity(stat, realStat)) {
|
|
640
677
|
throw new FsSafeError("path-mismatch", "path mismatch");
|
|
@@ -642,9 +679,16 @@ async function openWritableFileInRoot(root, params) {
|
|
|
642
679
|
if (realStat.nlink > 1) {
|
|
643
680
|
throw hardlinkedPathNotAllowedError();
|
|
644
681
|
}
|
|
645
|
-
|
|
682
|
+
const admittedRealPath = admitPathInsideRoot({
|
|
683
|
+
rootPath: root.rootReal,
|
|
684
|
+
candidatePath: realPath,
|
|
685
|
+
rootIdentity: root.rootIdentity,
|
|
686
|
+
});
|
|
687
|
+
if (!admittedRealPath) {
|
|
646
688
|
throw outsideWorkspaceError();
|
|
647
689
|
}
|
|
690
|
+
realPath = admittedRealPath.path;
|
|
691
|
+
realPathForCleanup = realPath;
|
|
648
692
|
// Truncate only after boundary and identity checks complete. This avoids
|
|
649
693
|
// irreversible side effects if a symlink target changes before validation.
|
|
650
694
|
if (params.append !== true && params.truncateExisting !== false && !createdForWrite) {
|
|
@@ -749,9 +793,11 @@ async function removePathInRoot(root, params) {
|
|
|
749
793
|
remove: true,
|
|
750
794
|
});
|
|
751
795
|
try {
|
|
752
|
-
await
|
|
796
|
+
await removePathInRootFallback(root, resolved.resolved, params);
|
|
753
797
|
}
|
|
754
798
|
catch (error) {
|
|
799
|
+
if (params.recursive)
|
|
800
|
+
throw error;
|
|
755
801
|
throw normalizePinnedPathError(error);
|
|
756
802
|
}
|
|
757
803
|
}
|
|
@@ -759,26 +805,27 @@ async function mkdirPathInRoot(root, params) {
|
|
|
759
805
|
validatePinnedOperationPayload({ relativePath: params.relativePath });
|
|
760
806
|
const resolved = await resolvePinnedPathInRoot(root, params);
|
|
761
807
|
try {
|
|
762
|
-
await mkdirPathFallback(resolved, params.assertBeforeMutation, params.mutationSymlinks !== undefined);
|
|
808
|
+
await mkdirPathFallback(root, resolved, params.assertBeforeMutation, params.mutationSymlinks !== undefined);
|
|
763
809
|
}
|
|
764
810
|
catch (error) {
|
|
765
811
|
throw normalizePinnedPathError(error);
|
|
766
812
|
}
|
|
767
813
|
}
|
|
768
814
|
async function writeFileInRoot(root, params) {
|
|
815
|
+
const input = rootWriteInput(params);
|
|
769
816
|
await serializePathWrite(rootWriteQueueKey(root, params.relativePath), async () => {
|
|
770
|
-
if (process.platform === "win32" &&
|
|
817
|
+
if (input.kind === "buffer" && process.platform === "win32" &&
|
|
771
818
|
(params.renameIdentity === "verify-content-with-lock" || !getNativeBinding())) {
|
|
772
|
-
await writeFileFallback(root, params);
|
|
819
|
+
await writeFileFallback(root, { ...params, data: input.data });
|
|
773
820
|
return;
|
|
774
821
|
}
|
|
775
822
|
const pinned = await resolvePinnedWriteTargetInRoot(root, params.relativePath, params.mode, params.denyMutations, params.overwrite, params.mutationSymlinks);
|
|
776
823
|
await serializePathWrite(pinned.targetPath, async () => {
|
|
777
|
-
await commitPinnedWriteInRoot(root, pinned, params);
|
|
824
|
+
await commitPinnedWriteInRoot(root, pinned, params, input);
|
|
778
825
|
});
|
|
779
826
|
});
|
|
780
827
|
}
|
|
781
|
-
async function commitPinnedWriteInRoot(root, pinned, params) {
|
|
828
|
+
async function commitPinnedWriteInRoot(root, pinned, params, input) {
|
|
782
829
|
let verifyingPublication = false;
|
|
783
830
|
try {
|
|
784
831
|
await runPinnedWriteWithRenamePolicy({
|
|
@@ -792,7 +839,8 @@ async function commitPinnedWriteInRoot(root, pinned, params) {
|
|
|
792
839
|
sync: params.durable !== false,
|
|
793
840
|
overwrite: params.overwrite,
|
|
794
841
|
rejectFinalSymlink: params.mutationSymlinks !== undefined,
|
|
795
|
-
input
|
|
842
|
+
input,
|
|
843
|
+
maxBytes: params.maxBytes,
|
|
796
844
|
rootIdentity: root.rootIdentity,
|
|
797
845
|
assertBeforeMutation: params.assertBeforeMutation,
|
|
798
846
|
verifyPublished: async (fd, expectedIdentity, parentGuard) => {
|
|
@@ -920,8 +968,8 @@ async function resolvePinnedWriteTargetInRoot(root, relativePath, requestedMode,
|
|
|
920
968
|
denyMutations,
|
|
921
969
|
mutationSymlinks,
|
|
922
970
|
});
|
|
923
|
-
// resolvePathInRoot already
|
|
924
|
-
// is rejected upstream.
|
|
971
|
+
// resolvePathInRoot already admits and rebases the path at the exact Root
|
|
972
|
+
// boundary, so any actual escape is rejected upstream.
|
|
925
973
|
const relativeResolved = path.relative(rootReal, resolved);
|
|
926
974
|
if (path.isAbsolute(relativeResolved)) {
|
|
927
975
|
throw outsideWorkspaceError();
|
|
@@ -950,7 +998,12 @@ async function resolvePinnedWriteTargetInRoot(root, relativePath, requestedMode,
|
|
|
950
998
|
}
|
|
951
999
|
}
|
|
952
1000
|
const mode = overwrite
|
|
953
|
-
? await inheritWriteTargetMode({
|
|
1001
|
+
? await inheritWriteTargetMode({
|
|
1002
|
+
targetPath: resolved,
|
|
1003
|
+
rootWithSep,
|
|
1004
|
+
rootIdentity: root.rootIdentity,
|
|
1005
|
+
requestedMode,
|
|
1006
|
+
})
|
|
954
1007
|
: requestedMode ?? 0o600;
|
|
955
1008
|
return {
|
|
956
1009
|
rootReal,
|
|
@@ -989,9 +1042,15 @@ async function resolvePinnedOperationPathInRoot(root, params) {
|
|
|
989
1042
|
throw outsideWorkspaceError();
|
|
990
1043
|
}
|
|
991
1044
|
const relativePosix = relativeResolved.split(path.sep).join(path.posix.sep);
|
|
992
|
-
|
|
1045
|
+
const admittedCanonicalPath = admitPathInsideRoot({
|
|
1046
|
+
rootPath: resolved.rootReal,
|
|
1047
|
+
candidatePath: resolved.canonicalPath,
|
|
1048
|
+
rootIdentity: root.rootIdentity,
|
|
1049
|
+
});
|
|
1050
|
+
if (!admittedCanonicalPath) {
|
|
993
1051
|
throw outsideWorkspaceError();
|
|
994
1052
|
}
|
|
1053
|
+
resolved.canonicalPath = admittedCanonicalPath.path;
|
|
995
1054
|
await assertMutationNotDenied(resolved.canonicalPath, params.denyMutations, {
|
|
996
1055
|
protectAncestors: params.protectDenyMutationAncestors,
|
|
997
1056
|
});
|
|
@@ -1009,6 +1068,7 @@ async function resolvePinnedRootPathInRoot(root, params) {
|
|
|
1009
1068
|
: `${ensureTrailingSep(rootReal)}${expandedPath}`,
|
|
1010
1069
|
rootPath: rootReal,
|
|
1011
1070
|
rootCanonicalPath: rootReal,
|
|
1071
|
+
rootIdentity: root.rootIdentity,
|
|
1012
1072
|
boundaryLabel: "root",
|
|
1013
1073
|
policy: params.policy,
|
|
1014
1074
|
...mutationSymlinkResolution(params.mutationSymlinks),
|
|
@@ -1026,33 +1086,10 @@ async function resolvePinnedRootPathInRoot(root, params) {
|
|
|
1026
1086
|
canonicalPath: resolved.canonicalPath,
|
|
1027
1087
|
};
|
|
1028
1088
|
}
|
|
1029
|
-
async function
|
|
1030
|
-
try {
|
|
1031
|
-
const guard = await createAsyncDirectoryGuard(path.dirname(targetPath));
|
|
1032
|
-
await getFsSafeTestHooks()?.beforeRootFallbackMutation?.("remove", targetPath);
|
|
1033
|
-
await assertAsyncDirectoryGuard(guard);
|
|
1034
|
-
return guard;
|
|
1035
|
-
}
|
|
1036
|
-
catch (error) {
|
|
1037
|
-
throw normalizeRemoveGuardError(error);
|
|
1038
|
-
}
|
|
1039
|
-
}
|
|
1040
|
-
async function removePathFallback(resolved, assertBeforeMutation, rejectFinalSymlink = false) {
|
|
1041
|
-
const guard = await prepareRemoveGuard(resolved.resolved);
|
|
1042
|
-
try {
|
|
1043
|
-
const isDirectory = fsSync.lstatSync(resolved.resolved).isDirectory();
|
|
1044
|
-
assertFinalSymlinkRejected(resolved.resolved, rejectFinalSymlink);
|
|
1045
|
-
assertBeforeMutation?.();
|
|
1046
|
-
await (isDirectory ? fs.rmdir(resolved.resolved) : fs.unlink(resolved.resolved));
|
|
1047
|
-
}
|
|
1048
|
-
catch (error) {
|
|
1049
|
-
throw normalizeRemovePathError(error);
|
|
1050
|
-
}
|
|
1051
|
-
await assertAsyncDirectoryGuard(guard).catch(error => { throw normalizeRemoveGuardError(error); });
|
|
1052
|
-
}
|
|
1053
|
-
async function mkdirPathFallback(resolved, assertBeforeMutation, rejectSymlinks = false) {
|
|
1089
|
+
async function mkdirPathFallback(root, resolved, assertBeforeMutation, rejectSymlinks = false) {
|
|
1054
1090
|
await mkdirPathComponentsWithGuards({
|
|
1055
1091
|
rootReal: resolved.rootReal, targetPath: resolved.resolved, assertBeforeMutation,
|
|
1092
|
+
rootIdentity: root.rootIdentity,
|
|
1056
1093
|
rejectSymlinks,
|
|
1057
1094
|
beforeComponent: async (componentPath) => await getFsSafeTestHooks()?.beforeRootFallbackMutation?.("mkdir", componentPath),
|
|
1058
1095
|
});
|
|
@@ -1075,20 +1112,6 @@ async function listPathFallback(root, relativePath, withFileTypes) {
|
|
|
1075
1112
|
const resolved = await resolvePinnedPathInRoot(root, { relativePath, allowRoot: true });
|
|
1076
1113
|
return await listDirectoryPath(root, resolved.resolved, withFileTypes);
|
|
1077
1114
|
}
|
|
1078
|
-
async function assertMoveMutationAllowed(root, params) {
|
|
1079
|
-
// Keep this preflight separate from the pinned resolutions in movePathFallback:
|
|
1080
|
-
// mutation denials must take precedence over source alias or identity failures.
|
|
1081
|
-
const source = await resolvePathInRoot(root, params.fromRelative, {
|
|
1082
|
-
aliasErrorCode: "path-alias",
|
|
1083
|
-
allowFinalSymlink: true,
|
|
1084
|
-
});
|
|
1085
|
-
await assertMutationNotDenied(source.resolved, params.denyMutations, { protectAncestors: true });
|
|
1086
|
-
const target = await resolvePathInRoot(root, params.toRelative, {
|
|
1087
|
-
aliasErrorCode: "path-alias",
|
|
1088
|
-
allowFinalSymlink: true,
|
|
1089
|
-
});
|
|
1090
|
-
await assertMutationNotDenied(target.resolved, params.denyMutations, { protectAncestors: true });
|
|
1091
|
-
}
|
|
1092
1115
|
async function movePathFallback(root, params) {
|
|
1093
1116
|
const source = await resolvePathInRoot(root, params.fromRelative, {
|
|
1094
1117
|
aliasErrorCode: "path-alias",
|
|
@@ -1293,14 +1316,14 @@ async function writeFileFallback(root, params) {
|
|
|
1293
1316
|
}
|
|
1294
1317
|
}
|
|
1295
1318
|
async function writeMissingFileFallback(root, params) {
|
|
1296
|
-
const {
|
|
1319
|
+
const { resolved } = await resolveGuardedWritePathInRoot(root, {
|
|
1297
1320
|
relativePath: params.relativePath,
|
|
1298
1321
|
denyMutations: params.denyMutations,
|
|
1299
1322
|
mutationSymlinks: params.mutationSymlinks,
|
|
1300
1323
|
});
|
|
1301
1324
|
const targetPath = params.mkdir === false
|
|
1302
1325
|
? resolved
|
|
1303
|
-
: await prepareRootWriteTarget(
|
|
1326
|
+
: await prepareRootWriteTarget(root, resolved, params.assertBeforeMutation);
|
|
1304
1327
|
const parentGuard = await createAsyncDirectoryGuard(path.dirname(targetPath), { bigint: true });
|
|
1305
1328
|
let created = false;
|
|
1306
1329
|
let createdIdentity;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type DenyMutationPolicy } from "./deny-mutations.js";
|
|
2
|
+
import { type RootContext } from "./root-context.js";
|
|
3
|
+
export declare function assertMoveMutationAllowed(root: RootContext, params: {
|
|
4
|
+
fromRelative: string;
|
|
5
|
+
toRelative: string;
|
|
6
|
+
denyMutations?: DenyMutationPolicy;
|
|
7
|
+
}): Promise<void>;
|
|
8
|
+
//# sourceMappingURL=root-move-preflight.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"root-move-preflight.d.ts","sourceRoot":"","sources":["../src/root-move-preflight.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAExE,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,WAAW,EACjB,MAAM,EAAE;IACN,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,kBAAkB,CAAC;CACpC,GACA,OAAO,CAAC,IAAI,CAAC,CAaf"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { assertMutationNotDenied, } from "./deny-mutations.js";
|
|
2
|
+
import { resolvePathInRoot } from "./root-context.js";
|
|
3
|
+
export async function assertMoveMutationAllowed(root, params) {
|
|
4
|
+
// Keep this preflight separate from the pinned resolutions in movePathFallback:
|
|
5
|
+
// mutation denials must take precedence over source alias or identity failures.
|
|
6
|
+
const source = await resolvePathInRoot(root, params.fromRelative, {
|
|
7
|
+
aliasErrorCode: "path-alias",
|
|
8
|
+
allowFinalSymlink: true,
|
|
9
|
+
});
|
|
10
|
+
await assertMutationNotDenied(source.resolved, params.denyMutations, { protectAncestors: true });
|
|
11
|
+
const target = await resolvePathInRoot(root, params.toRelative, {
|
|
12
|
+
aliasErrorCode: "path-alias",
|
|
13
|
+
allowFinalSymlink: true,
|
|
14
|
+
});
|
|
15
|
+
await assertMutationNotDenied(target.resolved, params.denyMutations, { protectAncestors: true });
|
|
16
|
+
}
|
package/dist/root-options.d.ts
CHANGED
|
@@ -51,6 +51,10 @@ export type RootWriteJsonOptions = RootWriteOptions & {
|
|
|
51
51
|
trailingNewline?: boolean;
|
|
52
52
|
};
|
|
53
53
|
export type RootCreateOptions = Omit<RootWriteOptions, "overwrite">;
|
|
54
|
+
export type RootCreateStreamOptions = Omit<RootCreateOptions, "encoding" | "renameIdentity"> & {
|
|
55
|
+
maxBytes?: number;
|
|
56
|
+
signal?: AbortSignal;
|
|
57
|
+
};
|
|
54
58
|
export type RootCreateJsonOptions = Omit<RootWriteJsonOptions, "overwrite">;
|
|
55
59
|
export type RootAppendOptions = RootWriteOptions & {
|
|
56
60
|
prependNewlineIfNeeded?: boolean;
|
|
@@ -58,7 +62,14 @@ export type RootAppendOptions = RootWriteOptions & {
|
|
|
58
62
|
export type RootMoveOptions = Pick<RootDefaults, "assertBeforeMutation" | "denyMutations" | "mutationSymlinks"> & {
|
|
59
63
|
overwrite?: boolean;
|
|
60
64
|
};
|
|
61
|
-
export type RootRemoveOptions = Pick<RootDefaults, "assertBeforeMutation" | "denyMutations" | "mutationSymlinks"
|
|
65
|
+
export type RootRemoveOptions = Pick<RootDefaults, "assertBeforeMutation" | "denyMutations" | "mutationSymlinks"> & {
|
|
66
|
+
recursive?: boolean;
|
|
67
|
+
force?: boolean;
|
|
68
|
+
order?: "filesystem" | "sorted";
|
|
69
|
+
maxEntries?: number;
|
|
70
|
+
maxDepth?: number;
|
|
71
|
+
signal?: AbortSignal;
|
|
72
|
+
};
|
|
62
73
|
export type RootMkdirOptions = Pick<RootDefaults, "assertBeforeMutation" | "denyMutations" | "mutationSymlinks">;
|
|
63
74
|
export type RootReadParams = Omit<RootReadOptions, "nonBlockingRead">;
|
|
64
75
|
export declare function readDefaults(defaults: RootDefaults): RootReadParams;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"root-options.d.ts","sourceRoot":"","sources":["../src/root-options.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"root-options.d.ts","sourceRoot":"","sources":["../src/root-options.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { type RootBoundaryIdentity } from "./root-boundary.js";
|
|
1
2
|
export declare function absolutePathWithRawSegments(candidate: string): string;
|
|
2
3
|
export declare function rawPathRelativeToCanonicalRoot(candidate: string, rootCanonicalPath: string, options?: {
|
|
3
4
|
rejectSymlinks?: boolean;
|
|
4
5
|
rejectFinalSymlink?: boolean;
|
|
6
|
+
rootIdentity?: RootBoundaryIdentity;
|
|
5
7
|
}): string | undefined;
|
|
6
8
|
export declare function resolvePathViaExistingAncestor(targetPath: string): Promise<string>;
|
|
7
9
|
export declare function resolvePathViaExistingAncestorSync(targetPath: string): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"root-path-existing.d.ts","sourceRoot":"","sources":["../src/root-path-existing.ts"],"names":[],"mappings":"AAMA,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAKrE;AAED,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,MAAM,EACzB,OAAO,GAAE;
|
|
1
|
+
{"version":3,"file":"root-path-existing.d.ts","sourceRoot":"","sources":["../src/root-path-existing.ts"],"names":[],"mappings":"AAMA,OAAO,EAAuB,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAEpF,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAKrE;AAED,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,MAAM,EACzB,OAAO,GAAE;IACP,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,YAAY,CAAC,EAAE,oBAAoB,CAAC;CAChC,GACL,MAAM,GAAG,SAAS,CA8CpB;AAkBD,wBAAsB,8BAA8B,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA0BxF;AAED,wBAAgB,kCAAkC,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CA0B7E"}
|
|
@@ -3,6 +3,8 @@ import path from "node:path";
|
|
|
3
3
|
import { FsSafeError } from "./errors.js";
|
|
4
4
|
import { formatErrorDetail } from "./error-detail.js";
|
|
5
5
|
import { isNotFoundPathError, isPathInside } from "./path.js";
|
|
6
|
+
import { realpathSync } from "./realpath.js";
|
|
7
|
+
import { admitPathInsideRoot } from "./root-boundary.js";
|
|
6
8
|
export function absolutePathWithRawSegments(candidate) {
|
|
7
9
|
if (path.isAbsolute(candidate))
|
|
8
10
|
return candidate;
|
|
@@ -18,6 +20,7 @@ export function rawPathRelativeToCanonicalRoot(candidate, rootCanonicalPath, opt
|
|
|
18
20
|
const finalComponentIndex = segments.findLastIndex(segment => segment !== "" && segment !== ".");
|
|
19
21
|
let prefix = filesystemRoot;
|
|
20
22
|
let traversedSymlink = false;
|
|
23
|
+
const identityCache = process.platform === "win32" ? new Map() : undefined;
|
|
21
24
|
for (let index = 0; index < segments.length; index += 1) {
|
|
22
25
|
prefix += `${prefix.endsWith(path.sep) ? "" : path.sep}${segments[index]}`;
|
|
23
26
|
let canonical;
|
|
@@ -32,7 +35,7 @@ export function rawPathRelativeToCanonicalRoot(candidate, rootCanonicalPath, opt
|
|
|
32
35
|
if (!isSymlink && !stat.isDirectory() && index < segments.length - 1)
|
|
33
36
|
return undefined;
|
|
34
37
|
traversedSymlink ||= isSymlink;
|
|
35
|
-
canonical =
|
|
38
|
+
canonical = realpathSync.native(prefix);
|
|
36
39
|
if (isSymlink && index < segments.length - 1 && !fs.statSync(canonical).isDirectory())
|
|
37
40
|
return undefined;
|
|
38
41
|
if (isSymlink && !isPathInside(rootCanonicalPath, canonical) && !isPathInside(canonical, rootCanonicalPath)) {
|
|
@@ -46,12 +49,18 @@ export function rawPathRelativeToCanonicalRoot(candidate, rootCanonicalPath, opt
|
|
|
46
49
|
return undefined;
|
|
47
50
|
continue;
|
|
48
51
|
}
|
|
49
|
-
|
|
52
|
+
const admitted = admitPathInsideRoot({
|
|
53
|
+
rootPath: rootCanonicalPath,
|
|
54
|
+
candidatePath: canonical,
|
|
55
|
+
rootIdentity: options.rootIdentity,
|
|
56
|
+
identityCache,
|
|
57
|
+
});
|
|
58
|
+
if (!admitted)
|
|
50
59
|
continue;
|
|
51
60
|
if (options.rejectSymlinks && traversedSymlink) {
|
|
52
61
|
throw new FsSafeError("symlink", "symlink path component not allowed");
|
|
53
62
|
}
|
|
54
|
-
return [
|
|
63
|
+
return [admitted.relativePath, ...segments.slice(index + 1)]
|
|
55
64
|
.filter(Boolean).join(path.sep);
|
|
56
65
|
}
|
|
57
66
|
return undefined;
|
|
@@ -87,7 +96,7 @@ export async function resolvePathViaExistingAncestor(targetPath) {
|
|
|
87
96
|
return normalized;
|
|
88
97
|
}
|
|
89
98
|
try {
|
|
90
|
-
const resolvedAncestor = path.resolve(
|
|
99
|
+
const resolvedAncestor = path.resolve(realpathSync.native(cursor));
|
|
91
100
|
return missingSuffix.length === 0
|
|
92
101
|
? resolvedAncestor
|
|
93
102
|
: path.resolve(resolvedAncestor, ...missingSuffix);
|
|
@@ -112,7 +121,7 @@ export function resolvePathViaExistingAncestorSync(targetPath) {
|
|
|
112
121
|
return normalized;
|
|
113
122
|
}
|
|
114
123
|
try {
|
|
115
|
-
const resolvedAncestor = path.resolve(
|
|
124
|
+
const resolvedAncestor = path.resolve(realpathSync(cursor));
|
|
116
125
|
return missingSuffix.length === 0
|
|
117
126
|
? resolvedAncestor
|
|
118
127
|
: path.resolve(resolvedAncestor, ...missingSuffix);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"root-path-symlink.d.ts","sourceRoot":"","sources":["../src/root-path-symlink.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"root-path-symlink.d.ts","sourceRoot":"","sources":["../src/root-path-symlink.ts"],"names":[],"mappings":"AAUA,KAAK,wBAAwB,GAAG;IAC9B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,CAAC;AAiBF,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,MAAM,CAAC,CAQjB;AAED,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,wBAA6B,GACrC,MAAM,CAQR"}
|