@openclaw/fs-safe 0.18.0 → 0.18.1
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 +10 -0
- package/dist/advanced.d.ts +2 -1
- package/dist/archive-durability.d.ts +1 -1
- package/dist/archive-parser.wasm +0 -0
- package/dist/archive-plan.d.ts +64 -3
- package/dist/archive-plan.js +55 -1
- package/dist/archive-tar-wasm.d.ts +1 -1
- package/dist/archive-zip-directory.d.ts +1 -1
- package/dist/archive-zip-entry.d.ts +1 -1
- package/dist/archive-zip-entry.js +1 -1
- package/dist/archive.d.ts +8 -5
- package/dist/archive.js +122 -9
- package/dist/atomic.d.ts +3 -1
- package/dist/copy-publication.d.ts +1 -1
- package/dist/create.d.ts +16 -2
- package/dist/create.js +388 -2
- package/dist/creation-boundary.d.ts +60 -0
- package/dist/creation-boundary.js +371 -0
- package/dist/directory-mode-node.js +12 -2
- package/dist/durability.d.ts +2 -1
- package/dist/file-lock-sync-acquisition.js +2 -2
- package/dist/file-lock-sync-root-acquire.js +2 -6
- package/dist/file-lock-sync-root.d.ts +2 -1
- package/dist/file-lock-sync-stale-admission.js +3 -10
- package/dist/file-lock-sync.d.ts +4 -21
- package/dist/file-store-boundary.d.ts +7 -0
- package/dist/file-store-boundary.js +58 -1
- package/dist/file-store-sync-write.js +2 -3
- package/dist/file-store.js +1 -6
- package/dist/guarded-mkdir.d.ts +1 -1
- package/dist/index.d.ts +9 -6
- package/dist/json-durable-queue-read.js +7 -3
- package/dist/json-durable-queue.js +1 -2
- package/dist/json-store.js +1 -2
- package/dist/json.js +1 -2
- package/dist/move-path.js +1 -2
- package/dist/native-operations.js +0 -1
- package/dist/native-pinned-write-windows.d.ts +1 -1
- package/dist/native-pinned-write-windows.js +1 -1
- package/dist/native-pinned-write.d.ts +1 -1
- package/dist/native-pinned-write.js +3 -6
- package/dist/native-policy-parent-windows.d.ts +1 -1
- package/dist/native-staged-file.d.ts +2 -2
- package/dist/native-staged-file.js +1 -2
- package/dist/pinned-mutation-admission.d.ts +1 -1
- package/dist/pinned-open.js +6 -1
- package/dist/pinned-operation.d.ts +1 -1
- package/dist/pinned-operation.js +3 -16
- package/dist/pinned-write-mode.js +1 -1
- package/dist/pinned-write-staged.js +1 -2
- package/dist/pinned-write.d.ts +0 -1
- package/dist/pinned-write.js +3 -5
- package/dist/private-producer-handoff-sync.d.ts +2 -12
- package/dist/private-producer-handoff-sync.js +1 -1
- package/dist/private-producer-handoff.d.ts +3 -3
- package/dist/private-temp-workspace.js +1 -2
- package/dist/publish-copy-stage.d.ts +1 -1
- package/dist/publish-file.d.ts +0 -1
- package/dist/publish-file.js +1 -2
- package/dist/replace-directory.js +1 -2
- package/dist/replace-file-rename-policy.d.ts +1 -2
- package/dist/replace-file.d.ts +3 -3
- package/dist/replace-file.js +1 -1
- package/dist/root-context.js +3 -7
- package/dist/root-create-input.d.ts +1 -1
- package/dist/root-directory-creation.d.ts +1 -1
- package/dist/root-directory-creation.js +1 -1
- package/dist/root-directory-list.js +3 -7
- package/dist/root-entries.js +2 -2
- package/dist/root-errors.d.ts +4 -0
- package/dist/root-errors.js +5 -3
- package/dist/root-impl.d.ts +0 -5
- package/dist/root-impl.js +22 -21
- package/dist/root-move-noreplace.js +4 -10
- package/dist/root-observed-path.js +2 -4
- package/dist/root-options.d.ts +1 -1
- package/dist/root-path-existing.js +2 -3
- package/dist/root-path-stat.js +2 -4
- package/dist/root-public-types.d.ts +11 -0
- package/dist/root-remove-identity.js +2 -4
- package/dist/root-remove.js +2 -4
- package/dist/root-write-admission.d.ts +1 -1
- package/dist/root-write-admission.js +3 -7
- package/dist/root-write-complete-parent.js +2 -3
- package/dist/root-write-verification.d.ts +1 -1
- package/dist/root.d.ts +2 -6
- package/dist/secret-file.js +0 -1
- package/dist/secure-temp-repair.js +5 -1
- package/dist/sidecar-lock-acquire.js +7 -10
- package/dist/sidecar-lock-policy.d.ts +1 -0
- package/dist/sidecar-lock-policy.js +7 -0
- package/dist/sidecar-lock-stale-admission.js +2 -6
- package/dist/sidecar-lock-types.d.ts +22 -16
- package/dist/temp-workspace-admission.js +1 -3
- package/dist/temp-workspace-child-admission.d.ts +16 -2
- package/dist/temp-workspace-child-admission.js +71 -3
- package/dist/temp-workspace-descriptor.d.ts +1 -1
- package/dist/temp-workspace-descriptor.js +1 -2
- package/dist/text-atomic.js +1 -1
- package/dist/windows-owner.js +1 -1
- package/dist/windows-path-alias.d.ts +1 -0
- package/dist/windows-path-alias.js +5 -0
- package/docs/advanced.md +3 -1
- package/docs/secret-file.md +4 -0
- package/docs/sidecar-lock.md +4 -0
- package/docs/store.md +6 -0
- package/docs/temp.md +8 -1
- package/docs/writing.md +5 -0
- package/package.json +8 -8
- package/dist/archive-native.d.ts +0 -10
- package/dist/archive-native.js +0 -73
- package/dist/archive-options.d.ts +0 -30
- package/dist/archive-policy.d.ts +0 -21
- package/dist/archive-policy.js +0 -38
- package/dist/archive-tar-inspect.d.ts +0 -6
- package/dist/archive-tar-inspect.js +0 -62
- package/dist/archive-tar.d.ts +0 -18
- package/dist/archive-tar.js +0 -21
- package/dist/create-directory.d.ts +0 -18
- package/dist/create-directory.js +0 -111
- package/dist/create-file-async.d.ts +0 -6
- package/dist/create-file-async.js +0 -121
- package/dist/create-file.d.ts +0 -7
- package/dist/create-file.js +0 -179
- package/dist/creation-darwin.d.ts +0 -5
- package/dist/creation-darwin.js +0 -70
- package/dist/creation-file-state.d.ts +0 -18
- package/dist/creation-file-state.js +0 -118
- package/dist/creation-path.d.ts +0 -22
- package/dist/creation-path.js +0 -83
- package/dist/creation-permissions.d.ts +0 -18
- package/dist/creation-permissions.js +0 -115
- package/dist/file-store-copy-source.d.ts +0 -4
- package/dist/file-store-copy-source.js +0 -31
- package/dist/file-store-limit.d.ts +0 -1
- package/dist/file-store-limit.js +0 -7
- package/dist/file-store-path.d.ts +0 -2
- package/dist/file-store-path.js +0 -30
- package/dist/standalone-publication-path.d.ts +0 -1
- package/dist/standalone-publication-path.js +0 -6
- package/dist/temp-workspace-identity.d.ts +0 -14
- package/dist/temp-workspace-identity.js +0 -41
- package/dist/temp-workspace-permissions.d.ts +0 -3
- package/dist/temp-workspace-permissions.js +0 -32
- /package/dist/{archive-options.js → root-public-types.js} +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
export { FsSafeError, categorizeFsSafeError,
|
|
2
|
-
export
|
|
3
|
-
export type
|
|
4
|
-
export
|
|
5
|
-
export {
|
|
6
|
-
export
|
|
1
|
+
export { FsSafeError, categorizeFsSafeError, } from "./errors.js";
|
|
2
|
+
export type * from "./errors.js";
|
|
3
|
+
export { DEFAULT_ROOT_MAX_BYTES, root, type Root, } from "./root.js";
|
|
4
|
+
export type * from "./root-public-types.js";
|
|
5
|
+
export { configureFsSafePython, configureFsSafeNative, getFsSafeNativeConfig, } from "./native-config.js";
|
|
6
|
+
export type * from "./config.js";
|
|
7
|
+
export { writeExternalFileWithinRoot, } from "./output.js";
|
|
8
|
+
export type * from "./output.js";
|
|
9
|
+
export { configureFsSafeLocks, getFsSafeLockConfig, } from "./lock-config.js";
|
|
@@ -43,6 +43,7 @@ export async function withJsonDurableQueueEntry(filePath, options, run) {
|
|
|
43
43
|
const handle = await fs.promises.open(filePath, resolveReadOpenFlags());
|
|
44
44
|
let closePromise;
|
|
45
45
|
const releaseReadPin = () => closePromise ??= (async () => { await handle.close(); })();
|
|
46
|
+
let result;
|
|
46
47
|
try {
|
|
47
48
|
const openedStat = inspectQueueEntry(() => fs.fstatSync(handle.fd, { bigint: true }), maxBytes, initialStat);
|
|
48
49
|
inspectQueueEntry(inspectPath, maxBytes, openedStat);
|
|
@@ -53,9 +54,12 @@ export async function withJsonDurableQueueEntry(filePath, options, run) {
|
|
|
53
54
|
});
|
|
54
55
|
// The migration owner may release this pin only at the verified publication
|
|
55
56
|
// boundary; until then an unlinked inode cannot be recycled into a new claim.
|
|
56
|
-
|
|
57
|
+
result = await run(JSON.parse(bytes.toString("utf8")), openedStat, releaseReadPin);
|
|
57
58
|
}
|
|
58
|
-
|
|
59
|
-
await releaseReadPin();
|
|
59
|
+
catch (error) {
|
|
60
|
+
await releaseReadPin().catch(() => undefined);
|
|
61
|
+
throw error;
|
|
60
62
|
}
|
|
63
|
+
await releaseReadPin();
|
|
64
|
+
return result;
|
|
61
65
|
}
|
|
@@ -7,8 +7,7 @@ import { withJsonDurableQueueEntry } from "./json-durable-queue-read.js";
|
|
|
7
7
|
import { stringifyJsonDocument } from "./json-stringify.js";
|
|
8
8
|
import { replaceFileAtomicWithDirectorySync } from "./replace-file.js";
|
|
9
9
|
import { assertSafePathSegment } from "./safe-path-segment.js";
|
|
10
|
-
import { admitStandalonePublicationPath } from "./
|
|
11
|
-
import { assertNoWindowsPathAlias, hasWindowsPathAlias, } from "./windows-path-alias.js";
|
|
10
|
+
import { admitStandalonePublicationPath, assertNoWindowsPathAlias, hasWindowsPathAlias, } from "./windows-path-alias.js";
|
|
12
11
|
export { DEFAULT_JSON_DURABLE_QUEUE_ENTRY_MAX_BYTES } from "./json-durable-queue-read.js";
|
|
13
12
|
function assertSafeQueueEntryId(id) {
|
|
14
13
|
assertSafePathSegment(id, { label: "queue entry id" });
|
package/dist/json-store.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { fileStore } from "./file-store.js";
|
|
3
3
|
import {} from "./json-document-store.js";
|
|
4
|
-
import { admitStandalonePublicationPath } from "./
|
|
5
|
-
import { assertNoWindowsPathAlias } from "./windows-path-alias.js";
|
|
4
|
+
import { admitStandalonePublicationPath, assertNoWindowsPathAlias } from "./windows-path-alias.js";
|
|
6
5
|
export function jsonStore(options) {
|
|
7
6
|
const filePathInput = admitStandalonePublicationPath(options.filePath);
|
|
8
7
|
const filePath = path.resolve(filePathInput);
|
package/dist/json.js
CHANGED
|
@@ -9,10 +9,9 @@ import { openRootFileSync } from "./root-file.js";
|
|
|
9
9
|
import { recursiveMkdirPath } from "./recursive-mkdir-path.js";
|
|
10
10
|
import { writeTempFileSync } from "./replace-file-descriptor.js";
|
|
11
11
|
import { SyncAtomicTempOwner } from "./replace-file-temp-owner.js";
|
|
12
|
-
import { admitStandalonePublicationPath } from "./
|
|
12
|
+
import { admitStandalonePublicationPath, assertNoWindowsPathAlias } from "./windows-path-alias.js";
|
|
13
13
|
import { writeTextAtomic } from "./text-atomic.js";
|
|
14
14
|
import { sleep } from "./timing.js";
|
|
15
|
-
import { assertNoWindowsPathAlias } from "./windows-path-alias.js";
|
|
16
15
|
const READ_RETRY_MAX_ATTEMPTS = 5;
|
|
17
16
|
const READ_RETRY_BASE_DELAY_MS = 50;
|
|
18
17
|
function isRetryableReadError(err) {
|
package/dist/move-path.js
CHANGED
|
@@ -10,8 +10,7 @@ import { resolveReadOpenFlags } from "./read-open-flags.js";
|
|
|
10
10
|
import { realpathSync } from "./realpath.js";
|
|
11
11
|
import { cleanupPinnedFilePath } from "./file-cleanup.js";
|
|
12
12
|
import { createMoveStageOwner } from "./move-path-stage.js";
|
|
13
|
-
import { admitStandalonePublicationPath } from "./
|
|
14
|
-
import { assertNoWindowsPathAlias } from "./windows-path-alias.js";
|
|
13
|
+
import { admitStandalonePublicationPath, assertNoWindowsPathAlias } from "./windows-path-alias.js";
|
|
15
14
|
export function moveCopyFallbackReasonForRenameError(error, platform = process.platform) {
|
|
16
15
|
const code = error?.code;
|
|
17
16
|
if (code === "EXDEV") {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import fsSync, {} from "node:fs";
|
|
2
2
|
import fs from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import { FsSafeError } from "./errors.js";
|
|
5
4
|
import { sameFileIdentityForCleanup } from "./file-identity.js";
|
|
6
5
|
import { getNativeBinding } from "./native.js";
|
|
7
6
|
import { captureNativeFdClose } from "./native-binding.js";
|
|
@@ -2,5 +2,5 @@ import type { FileHandle } from "node:fs/promises";
|
|
|
2
2
|
import { type AnyAsyncDirectoryGuard } from "./directory-guard.js";
|
|
3
3
|
import type { FileIdentityStat } from "./file-identity.js";
|
|
4
4
|
import type { NativeBinding } from "./native.js";
|
|
5
|
-
import type { PinnedWriteParams } from "./pinned-write.js";
|
|
5
|
+
import type { PinnedWriteParams } from "./pinned-write-types.js";
|
|
6
6
|
export declare function runPinnedWriteWindows(binding: NativeBinding, params: PinnedWriteParams, root: FileHandle, parentFd: number, parentGuard: AnyAsyncDirectoryGuard): Promise<FileIdentityStat>;
|
|
@@ -3,7 +3,7 @@ import { randomUUID } from "node:crypto";
|
|
|
3
3
|
import fsSync, {} from "node:fs";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { createFileHandle } from "./create.js";
|
|
6
|
-
import { hasPreservedCreationArtifacts } from "./creation-
|
|
6
|
+
import { hasPreservedCreationArtifacts } from "./creation-boundary.js";
|
|
7
7
|
import { assertSyncDirectoryGuard } from "./directory-guard.js";
|
|
8
8
|
import { FsSafeError } from "./errors.js";
|
|
9
9
|
import { nativeOpenFlags, removeNativeCreatedFileIfStillPinned, } from "./native-operations.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { FileIdentityStat } from "./file-identity.js";
|
|
2
2
|
import type { NativeBinding } from "./native.js";
|
|
3
|
-
import type { PinnedWriteParams } from "./pinned-write.js";
|
|
3
|
+
import type { PinnedWriteParams } from "./pinned-write-types.js";
|
|
4
4
|
export declare function runPinnedWriteNative(binding: NativeBinding, params: PinnedWriteParams): Promise<FileIdentityStat>;
|
|
@@ -63,6 +63,7 @@ import { NativePolicyDirectoryMismatch } from "./native-policy-directory-observa
|
|
|
63
63
|
import { assertPolicyStagedDirectoryCurrent, assertStagedDirectoryCurrent, describePolicyStagedDirectory, describeStagedDirectory, refreshPolicyStagedDirectoryObservation, } from "./staged-directory.js";
|
|
64
64
|
import { inspectFileIdentitySync } from "./strict-file-identity.js";
|
|
65
65
|
import { realpathSync } from "./realpath.js";
|
|
66
|
+
import { errorCauseOptions } from "./root-errors.js";
|
|
66
67
|
import { isNotFoundPathError, isSymlinkOpenError } from "./path.js";
|
|
67
68
|
import { checkedMutationDirectory, } from "./pinned-mutation-observation.js";
|
|
68
69
|
import { createPathSegmentRoute, joinPathSegmentRoute } from "./path-segment-route.js";
|
|
@@ -95,12 +96,8 @@ function normalizePolicyParentOpenError(error, params) {
|
|
|
95
96
|
if (!isSymlinkOpenError(error))
|
|
96
97
|
return error;
|
|
97
98
|
return params.mutationAdmission?.rejectParentSymlinks
|
|
98
|
-
? new FsSafeError("symlink", "symlink path component not allowed",
|
|
99
|
-
|
|
100
|
-
})
|
|
101
|
-
: new FsSafeError("path-mismatch", "native write parent changed during policy admission", {
|
|
102
|
-
cause: error instanceof Error ? error : undefined,
|
|
103
|
-
});
|
|
99
|
+
? new FsSafeError("symlink", "symlink path component not allowed", errorCauseOptions(error))
|
|
100
|
+
: new FsSafeError("path-mismatch", "native write parent changed during policy admission", errorCauseOptions(error));
|
|
104
101
|
}
|
|
105
102
|
async function describePosixParent(parentFd, pathname) {
|
|
106
103
|
const parentPath = realpathSync.native(pathname);
|
|
@@ -2,7 +2,7 @@ import { type BigIntStats } from "node:fs";
|
|
|
2
2
|
import { type AsyncDirectoryGuard } from "./directory-guard.js";
|
|
3
3
|
import { type NativeRootAdmission } from "./native-parent-admission.js";
|
|
4
4
|
import type { NativeBinding } from "./native.js";
|
|
5
|
-
import type { PinnedWriteParams } from "./pinned-write.js";
|
|
5
|
+
import type { PinnedWriteParams } from "./pinned-write-types.js";
|
|
6
6
|
import { type MutationDirectoryObservation } from "./pinned-mutation-observation.js";
|
|
7
7
|
type PolicyParent = {
|
|
8
8
|
fd: number;
|
|
@@ -3,7 +3,7 @@ import { type BigIntStats, type Stats } from "node:fs";
|
|
|
3
3
|
import type { AnyAsyncDirectoryGuard } from "./directory-guard.js";
|
|
4
4
|
import type { FileIdentityStat } from "./file-identity.js";
|
|
5
5
|
import { type NativeBinding } from "./native-binding.js";
|
|
6
|
-
import type { PinnedWriteInput, PinnedWriteParams } from "./pinned-write.js";
|
|
6
|
+
import type { PinnedWriteInput, PinnedWriteParams } from "./pinned-write-types.js";
|
|
7
7
|
import type { PublishedFileReceipt, StagedFile, StagedFileCleanupReceipt, StagedFileReceipt } from "./staged-file-types.js";
|
|
8
8
|
export type NativeStagingBinding = NativeBinding & Required<Pick<NativeBinding, "createStagedFile" | "stagedFileMatches" | "removeStagedFile">>;
|
|
9
9
|
export declare function assertNativeStaging(binding: NativeBinding): asserts binding is NativeStagingBinding;
|
|
@@ -36,10 +36,10 @@ declare class NativeStagedFile implements StagedFile {
|
|
|
36
36
|
}
|
|
37
37
|
export declare const createNativeStage: (...args: Parameters<typeof NativeStagedFile.create>) => Promise<StagedFile>;
|
|
38
38
|
export declare const writeNativeStage: typeof NativeStagedFile.write;
|
|
39
|
-
export type { PublishedFileReceipt, StagedFile, StagedFileCleanupReceipt, StagedFileFailureDetails, StagedFilePublication, StagedFileReceipt, } from "./staged-file-types.js";
|
|
40
39
|
export declare function stageFileInDirectory(options: {
|
|
41
40
|
directory: string | DirectoryReceipt<Stats | BigIntStats>;
|
|
42
41
|
content: string | Uint8Array;
|
|
43
42
|
/** Published mode; the unpublished stage stays at 0600. Defaults to 0600. */
|
|
44
43
|
mode?: number;
|
|
45
44
|
}): Promise<StagedFile>;
|
|
45
|
+
export {};
|
|
@@ -50,8 +50,7 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
|
|
|
50
50
|
var e = new Error(message);
|
|
51
51
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
52
52
|
});
|
|
53
|
-
import { assertDarwinCreationAcl } from "./creation-
|
|
54
|
-
import { assertPrivateCreationFile } from "./creation-file-state.js";
|
|
53
|
+
import { assertDarwinCreationAcl, assertPrivateCreationFile } from "./creation-boundary.js";
|
|
55
54
|
import { requireNativeBinding } from "./native.js";
|
|
56
55
|
import { syncFileBestEffortSync } from "./file-sync.js";
|
|
57
56
|
import { randomUUID } from "node:crypto";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type DenyMutationPolicy } from "./deny-mutations.js";
|
|
2
2
|
import { type RootBoundaryIdentity } from "./root-boundary.js";
|
|
3
|
-
import type { PinnedWriteMutationAdmission } from "./pinned-write.js";
|
|
3
|
+
import type { PinnedWriteMutationAdmission } from "./pinned-write-types.js";
|
|
4
4
|
import type { MutationSymlinkPolicy } from "./root-symlink-policy.js";
|
|
5
5
|
export type PinnedMutationPolicySnapshot = Readonly<{
|
|
6
6
|
denyMutations?: DenyMutationPolicy;
|
package/dist/pinned-open.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function
|
|
1
|
+
export declare function validatePinnedRelativePath(relativePath: unknown): void;
|
package/dist/pinned-operation.js
CHANGED
|
@@ -1,19 +1,7 @@
|
|
|
1
1
|
import { FsSafeError } from "./errors.js";
|
|
2
|
-
export function
|
|
3
|
-
if (typeof
|
|
4
|
-
|
|
5
|
-
}
|
|
6
|
-
if (typeof payload.relativeParentPath === "string") {
|
|
7
|
-
validatePinnedRelativePath(payload.relativeParentPath);
|
|
8
|
-
}
|
|
9
|
-
if (typeof payload.from === "string") {
|
|
10
|
-
validatePinnedRelativePath(payload.from);
|
|
11
|
-
}
|
|
12
|
-
if (typeof payload.to === "string") {
|
|
13
|
-
validatePinnedRelativePath(payload.to);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
function validatePinnedRelativePath(relativePath) {
|
|
2
|
+
export function validatePinnedRelativePath(relativePath) {
|
|
3
|
+
if (typeof relativePath !== "string")
|
|
4
|
+
return;
|
|
17
5
|
if (relativePath.length === 0 || relativePath === ".") {
|
|
18
6
|
return;
|
|
19
7
|
}
|
|
@@ -21,7 +9,6 @@ function validatePinnedRelativePath(relativePath) {
|
|
|
21
9
|
throw new FsSafeError("invalid-path", "relative path contains a NUL byte");
|
|
22
10
|
}
|
|
23
11
|
if (relativePath.startsWith("/") ||
|
|
24
|
-
relativePath.startsWith("//") ||
|
|
25
12
|
relativePath === ".." ||
|
|
26
13
|
relativePath.startsWith("../") ||
|
|
27
14
|
relativePath.startsWith("..\\")) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import { FsSafeError } from "./errors.js";
|
|
3
3
|
import { assertSynchronousCallbackResult } from "./mutation-authority.js";
|
|
4
|
-
import { assertPrivateCreationFile } from "./creation-
|
|
4
|
+
import { assertPrivateCreationFile } from "./creation-boundary.js";
|
|
5
5
|
export function assertPinnedWriteMode(fd, mode, privateCreation = false) {
|
|
6
6
|
if (process.platform === "win32")
|
|
7
7
|
return;
|
|
@@ -3,8 +3,7 @@ import fsSync, {} from "node:fs";
|
|
|
3
3
|
import fs, {} from "node:fs/promises";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { createFileHandle } from "./create.js";
|
|
6
|
-
import { hasPreservedCreationArtifacts } from "./creation-
|
|
7
|
-
import { creationAdmissionFromParent } from "./creation-path.js";
|
|
6
|
+
import { hasPreservedCreationArtifacts, creationAdmissionFromParent } from "./creation-boundary.js";
|
|
8
7
|
import { syncDirectoryBestEffort } from "./directory-durability.js";
|
|
9
8
|
import { FsSafeError } from "./errors.js";
|
|
10
9
|
import { sameFileIdentity, sha256Hex } from "./file-identity.js";
|
package/dist/pinned-write.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { FileIdentityStat } from "./file-identity.js";
|
|
2
2
|
import type { PinnedWriteParams, RenameIdentityPolicy } from "./pinned-write-types.js";
|
|
3
|
-
export type { PinnedWriteInput, RenameIdentityPolicy, PublishedWriteIdentity, PinnedMutationAdmissionReceipt, PinnedMutationAuthorizationToken, PinnedCreatedDirectoryReceipt, PinnedMutationParentWalkSession, PinnedWriteMutationAdmission, PinnedWriteParams, } from "./pinned-write-types.js";
|
|
4
3
|
export declare function runPinnedWriteHelper(params: PinnedWriteParams): Promise<FileIdentityStat>;
|
|
5
4
|
export declare function runPinnedWriteWithRenamePolicy(params: PinnedWriteParams & {
|
|
6
5
|
targetPath: string;
|
package/dist/pinned-write.js
CHANGED
|
@@ -3,7 +3,7 @@ import fsSync, {} from "node:fs";
|
|
|
3
3
|
import fs from "node:fs/promises";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { createFileHandle } from "./create.js";
|
|
6
|
-
import { creationAdmissionFromParent } from "./creation-
|
|
6
|
+
import { creationAdmissionFromParent } from "./creation-boundary.js";
|
|
7
7
|
import { normalizeMaxBytes } from "./byte-budget.js";
|
|
8
8
|
import { assertAsyncDirectoryGuard, createAsyncDirectoryGuard, createNearestExistingDirectoryGuard, inspectDirectoryIdentity } from "./directory-guard.js";
|
|
9
9
|
import { FsSafeError } from "./errors.js";
|
|
@@ -13,7 +13,7 @@ import { withAsyncDirectoryGuards } from "./guarded-mutation.js";
|
|
|
13
13
|
import { mkdirPathComponentsWithGuards } from "./guarded-mkdir.js";
|
|
14
14
|
import { runPinnedWriteNative } from "./native-pinned-write.js";
|
|
15
15
|
import { getNativeBinding } from "./native.js";
|
|
16
|
-
import {
|
|
16
|
+
import { validatePinnedRelativePath } from "./pinned-operation.js";
|
|
17
17
|
import { cleanupPinnedFilePath } from "./file-cleanup.js";
|
|
18
18
|
import { withSidecarLock } from "./sidecar-lock.js";
|
|
19
19
|
import { getFsSafeTestHooks } from "./test-hooks.js";
|
|
@@ -71,9 +71,7 @@ export async function runPinnedWriteHelper(params) {
|
|
|
71
71
|
rootIdentity,
|
|
72
72
|
};
|
|
73
73
|
assertSafeBasename(normalizedParams.basename);
|
|
74
|
-
|
|
75
|
-
relativeParentPath: normalizedParams.relativeParentPath,
|
|
76
|
-
});
|
|
74
|
+
validatePinnedRelativePath(normalizedParams.relativeParentPath);
|
|
77
75
|
assertNoWindowsPathAlias(normalizedParams.rootPath, "filesystem", "pinned write root uses a Windows filesystem namespace alias");
|
|
78
76
|
assertNoWindowsPathAlias(normalizedParams.relativeParentPath, "relative", "pinned write parent uses a Windows filesystem namespace alias");
|
|
79
77
|
assertNoWindowsPathAlias(normalizedParams.basename, "relative", "pinned write basename uses a Windows filesystem namespace alias");
|
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
import { type BigIntStats } from "node:fs";
|
|
2
1
|
import { type OwnedFileDescriptorSync } from "./create-owned-file.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
sourcePath: string;
|
|
6
|
-
targetPath: string;
|
|
7
|
-
identity: BigIntStats;
|
|
8
|
-
assertSourceParent: () => void;
|
|
9
|
-
assertTargetParent: () => void;
|
|
10
|
-
assertBeforeMutation?: () => void;
|
|
11
|
-
verifyDescriptor?: (fd: number, path: string, links: number) => void;
|
|
12
|
-
onPublished?: () => void;
|
|
13
|
-
}): OwnedFileDescriptorSync;
|
|
2
|
+
import { type CreatedHandoffParams } from "./private-producer-handoff.js";
|
|
3
|
+
export declare function handoffCreatedFileSync(params: CreatedHandoffParams<OwnedFileDescriptorSync, void>): OwnedFileDescriptorSync;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import fs
|
|
1
|
+
import fs from "node:fs";
|
|
2
2
|
import { ownFileDescriptorSync } from "./create-owned-file.js";
|
|
3
3
|
import { assertSynchronousCallbackResult } from "./mutation-authority.js";
|
|
4
4
|
import { assertInitialSource, FileHandoff, inspectLinkedFile, } from "./private-producer-handoff.js";
|
|
@@ -18,11 +18,11 @@ type HandoffPaths = HandoffParents & {
|
|
|
18
18
|
type ProducerHandoffParams = HandoffPaths & {
|
|
19
19
|
readWrite: boolean;
|
|
20
20
|
};
|
|
21
|
-
type CreatedHandoffParams = HandoffPaths & {
|
|
22
|
-
source:
|
|
21
|
+
export type CreatedHandoffParams<TSource = FileHandle, TVerification = Promise<void>> = HandoffPaths & {
|
|
22
|
+
source: TSource;
|
|
23
23
|
identity: BigIntStats;
|
|
24
24
|
assertBeforeMutation?: () => void;
|
|
25
|
-
verifyDescriptor?: (fd: number, path: string, links: number) =>
|
|
25
|
+
verifyDescriptor?: (fd: number, path: string, links: number) => TVerification;
|
|
26
26
|
onPublished?: () => void;
|
|
27
27
|
};
|
|
28
28
|
export declare function assertInitialSource(stat: BigIntStats): void;
|
|
@@ -12,9 +12,8 @@ import { registerTempPathForExit, } from "./temp-cleanup.js";
|
|
|
12
12
|
import { TempWorkspaceCleanupCapability, TempWorkspaceCleanupOwner, throwTempWorkspaceCreationFailure, } from "./temp-workspace-owner.js";
|
|
13
13
|
import { assertNoWindowsPathAlias, hasWindowsPathAlias, } from "./windows-path-alias.js";
|
|
14
14
|
import { TempWorkspaceRetainedChild } from "./temp-workspace-descriptor.js";
|
|
15
|
-
import { validateInitialTempWorkspaceChild } from "./temp-workspace-child-admission.js";
|
|
15
|
+
import { validateInitialTempWorkspaceChild, validateTempWorkspaceDirMode } from "./temp-workspace-child-admission.js";
|
|
16
16
|
import { admitTempWorkspaceRoot, admitTempWorkspaceRootSync, } from "./temp-workspace-admission.js";
|
|
17
|
-
import { validateTempWorkspaceDirMode } from "./temp-workspace-permissions.js";
|
|
18
17
|
function resolveTempWorkspaceCleanupSafety(value) {
|
|
19
18
|
if (value === undefined || value === "compatible")
|
|
20
19
|
return "compatible";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type BigIntStats } from "node:fs";
|
|
2
2
|
import { type AnyAsyncDirectoryGuard } from "./directory-guard.js";
|
|
3
|
-
import type { PublishedWriteIdentity } from "./pinned-write.js";
|
|
3
|
+
import type { PublishedWriteIdentity } from "./pinned-write-types.js";
|
|
4
4
|
export declare function publishCopyStage(params: {
|
|
5
5
|
temporaryPath: string;
|
|
6
6
|
targetPath: string;
|
package/dist/publish-file.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ import { type BigIntStats, type Stats } from "node:fs";
|
|
|
2
2
|
import { type DirectoryReceipt, type DirectorySyncOutcome } from "./directory-durability.js";
|
|
3
3
|
import { type FileIdentityStat } from "./file-identity.js";
|
|
4
4
|
import { type PublishFileExclusiveSyncFailurePolicy } from "./publish-file-failure.js";
|
|
5
|
-
export type { PublishFileExclusiveCleanup, PublishFileExclusiveDirectorySyncFailure, PublishFileExclusiveFailureDetails, PublishFileExclusiveFailurePhase, PublishFileExclusiveSyncFailurePolicy, } from "./publish-file-failure.js";
|
|
6
5
|
export type PublishFileExclusiveStrategy = "link-or-copy" | "link-required" | "rename-noreplace";
|
|
7
6
|
export type PublishFileExclusiveResult = {
|
|
8
7
|
method: "hardlink" | "exclusive-copy" | "rename-noreplace";
|
package/dist/publish-file.js
CHANGED
|
@@ -12,9 +12,8 @@ import { getNativeBinding, requireNativeBinding } from "./native.js";
|
|
|
12
12
|
import { captureNativeFdClose } from "./native-binding.js";
|
|
13
13
|
import { resolveReadOpenFlags } from "./read-open-flags.js";
|
|
14
14
|
import { directorySyncFailure, publicationFailure, rememberCreatedTarget, } from "./publish-file-failure.js";
|
|
15
|
-
import { admitStandalonePublicationPath } from "./
|
|
15
|
+
import { admitStandalonePublicationPath, assertNoWindowsPathAlias } from "./windows-path-alias.js";
|
|
16
16
|
import { getFsSafeTestHooks } from "./test-hooks.js";
|
|
17
|
-
import { assertNoWindowsPathAlias } from "./windows-path-alias.js";
|
|
18
17
|
import { hasErrorCode } from "./file-cleanup.js";
|
|
19
18
|
import { writeAllToFile } from "./write-file-handle.js";
|
|
20
19
|
const HARDLINK_FALLBACK_CODES = new Set(["EPERM", "EXDEV", "ENOTSUP", "EOPNOTSUPP", "ENOSYS"]);
|
|
@@ -8,9 +8,8 @@ import { classifyNativeRenameFailure, NATIVE_RENAME_SOURCE_IDENTITY_MISMATCH, }
|
|
|
8
8
|
import { recursiveMkdirPath } from "./recursive-mkdir-path.js";
|
|
9
9
|
import { RetainedDirectoryReplacement } from "./retained-directory-replacement.js";
|
|
10
10
|
import { assertSafePathPrefix } from "./safe-path-segment.js";
|
|
11
|
-
import { admitStandalonePublicationPath } from "./
|
|
11
|
+
import { admitStandalonePublicationPath, assertNoWindowsPathAlias } from "./windows-path-alias.js";
|
|
12
12
|
import { serializePathWrite } from "./write-queue.js";
|
|
13
|
-
import { assertNoWindowsPathAlias } from "./windows-path-alias.js";
|
|
14
13
|
function distinctGuards(source, target) {
|
|
15
14
|
return source === target ? [source] : [source, target];
|
|
16
15
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type { RenameIdentityPolicy } from "./pinned-write.js";
|
|
2
|
-
export type { RenameIdentityPolicy };
|
|
1
|
+
import type { RenameIdentityPolicy } from "./pinned-write-types.js";
|
|
3
2
|
export declare function validateRenameIdentity(policy: RenameIdentityPolicy | undefined): void;
|
|
4
3
|
export declare function atomicExpectedContentHash(policy: RenameIdentityPolicy | undefined, content: string | Uint8Array): string | undefined;
|
|
5
4
|
export declare function withAtomicRenameIdentityLock<T>(filePath: string, fn: () => Promise<T>): Promise<T>;
|
package/dist/replace-file.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import syncFs from "node:fs";
|
|
2
2
|
import fs from "node:fs/promises";
|
|
3
|
-
import
|
|
4
|
-
import { type
|
|
3
|
+
import type { RenameIdentityPolicy } from "./pinned-write-types.js";
|
|
4
|
+
import { type ReplaceFileCopyFallbackRestorePolicy, type ReplaceFileDestinationHardlinkPolicy } from "./replace-file-copy-fallback.js";
|
|
5
5
|
export type ReplaceFileAtomicFileSystem = {
|
|
6
6
|
promises: Pick<typeof fs, "mkdir" | "writeFile" | "rename" | "copyFile" | "unlink" | "rm" | "open" | "stat" | "lstat"> & {
|
|
7
7
|
/** @deprecated Accepted for adapter compatibility but never called. */
|
|
@@ -13,7 +13,6 @@ export type ReplaceFileAtomicSyncFileSystem = Pick<typeof syncFs, "mkdirSync" |
|
|
|
13
13
|
chmodSync?: typeof syncFs.chmodSync;
|
|
14
14
|
fchmodSync?: typeof syncFs.fchmodSync;
|
|
15
15
|
};
|
|
16
|
-
export type { RenameIdentityPolicy, ReplaceFileAtomicRestoreCleanup, ReplaceFileAtomicRestoreFailureDetails, ReplaceFileCopyFallbackRestorePolicy, ReplaceFileDestinationHardlinkPolicy, };
|
|
17
16
|
type ReplaceFileAtomicBaseOptions = {
|
|
18
17
|
filePath: string;
|
|
19
18
|
content: string | Uint8Array;
|
|
@@ -56,3 +55,4 @@ export type ReplaceFileAtomicResult = {
|
|
|
56
55
|
export declare function replaceFileAtomic(options: ReplaceFileAtomicOptions): Promise<ReplaceFileAtomicResult>;
|
|
57
56
|
export declare function replaceFileAtomicWithDirectorySync(options: ReplaceFileAtomicOptions, syncParent?: (directoryPath: string) => Promise<unknown>): Promise<ReplaceFileAtomicResult>;
|
|
58
57
|
export declare function replaceFileAtomicSync(options: ReplaceFileAtomicSyncOptions): ReplaceFileAtomicResult;
|
|
58
|
+
export {};
|
package/dist/replace-file.js
CHANGED
|
@@ -9,7 +9,7 @@ import { inheritedRegularFileMode } from "./replace-file-mode.js";
|
|
|
9
9
|
import { atomicExpectedContentHash, validateRenameIdentity, withAtomicRenameIdentityLock, withAtomicRenameIdentityLockSync, } from "./replace-file-rename-policy.js";
|
|
10
10
|
import { AsyncAtomicTempOwner, SyncAtomicTempOwner } from "./replace-file-temp-owner.js";
|
|
11
11
|
import { assertSafePathPrefix } from "./safe-path-segment.js";
|
|
12
|
-
import { admitStandalonePublicationPath } from "./
|
|
12
|
+
import { admitStandalonePublicationPath } from "./windows-path-alias.js";
|
|
13
13
|
import { sleep, sleepSync } from "./timing.js";
|
|
14
14
|
import { serializePathWrite } from "./write-queue.js";
|
|
15
15
|
import { hasErrorCode, readErrorCode } from "./file-cleanup.js";
|
package/dist/root-context.js
CHANGED
|
@@ -7,7 +7,7 @@ import { sameFileIdentity } from "./file-identity.js";
|
|
|
7
7
|
import { assertNoNulPathInput, assertNoUnsafeDeviceReadPath, hasNodeErrorCode, isNotFoundPathError, isPathInside, } from "./path.js";
|
|
8
8
|
import { ROOT_PATH_ALIAS_POLICIES, resolveRootPath } from "./root-path.js";
|
|
9
9
|
import { admitPathInsideRoot } from "./root-boundary.js";
|
|
10
|
-
import { outsideWorkspaceError, rootPathChangedError } from "./root-errors.js";
|
|
10
|
+
import { errorCauseOptions, outsideWorkspaceError, rootPathChangedError } from "./root-errors.js";
|
|
11
11
|
import { isDriveRelativePath } from "./safe-path-segment.js";
|
|
12
12
|
import { realpathSync } from "./realpath.js";
|
|
13
13
|
import { inspectFileIdentity } from "./strict-file-identity.js";
|
|
@@ -223,14 +223,10 @@ export async function resolvePathInRoot(root, relativePath, options) {
|
|
|
223
223
|
throw error;
|
|
224
224
|
}
|
|
225
225
|
if (hasNodeErrorCode(error, "ENAMETOOLONG")) {
|
|
226
|
-
throw new FsSafeError("invalid-path", "relative path is too long",
|
|
227
|
-
cause: error instanceof Error ? error : undefined,
|
|
228
|
-
});
|
|
226
|
+
throw new FsSafeError("invalid-path", "relative path is too long", errorCauseOptions(error));
|
|
229
227
|
}
|
|
230
228
|
const code = options?.aliasErrorCode ?? "outside-workspace";
|
|
231
|
-
throw new FsSafeError(code, code === "path-alias" ? "path alias escape blocked" : "file is outside workspace root",
|
|
232
|
-
cause: error instanceof Error ? error : undefined,
|
|
233
|
-
});
|
|
229
|
+
throw new FsSafeError(code, code === "path-alias" ? "path alias escape blocked" : "file is outside workspace root", errorCauseOptions(error));
|
|
234
230
|
}
|
|
235
231
|
return { rootReal: root.rootReal, rootWithSep: root.rootWithSep, resolved };
|
|
236
232
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PinnedWriteInput } from "./pinned-write.js";
|
|
1
|
+
import type { PinnedWriteInput } from "./pinned-write-types.js";
|
|
2
2
|
import type { RootCreateOptions, RootCreateStreamOptions, RootWriteOptions } from "./root-options.js";
|
|
3
3
|
declare const exclusiveSidecarCreate: unique symbol;
|
|
4
4
|
export declare const sidecarExclusiveCreate: Readonly<{
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PinnedWriteMutationAdmission } from "./pinned-write.js";
|
|
1
|
+
import type { PinnedWriteMutationAdmission } from "./pinned-write-types.js";
|
|
2
2
|
import { type RootContext } from "./root-context.js";
|
|
3
3
|
/**
|
|
4
4
|
* Complete the common Root.mkdir case with one exact existing parent. This is
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fsSync, {} from "node:fs";
|
|
2
2
|
import fs from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import { assertPrivateDirectory } from "./creation-
|
|
4
|
+
import { assertPrivateDirectory } from "./creation-boundary.js";
|
|
5
5
|
import { assertAsyncDirectoryGuard, assertDirectoryIdentitySync, assertSyncDirectoryGuard, createAsyncDirectoryGuard, inspectDirectoryIdentitySync, } from "./directory-guard.js";
|
|
6
6
|
import { FsSafeError } from "./errors.js";
|
|
7
7
|
import { mkdirPathComponentsWithGuards } from "./guarded-mkdir.js";
|
|
@@ -7,7 +7,7 @@ import { FsSafeError } from "./errors.js";
|
|
|
7
7
|
import { inspectNativeDirectoryObservation, isNativeDirectoryObservationGuard, } from "./native-directory-observation.js";
|
|
8
8
|
import { isNotFoundPathError } from "./path.js";
|
|
9
9
|
import { assertRootIdentityCurrent } from "./root-context.js";
|
|
10
|
-
import { rootPathChangedError } from "./root-errors.js";
|
|
10
|
+
import { errorCauseOptions, rootPathChangedError } from "./root-errors.js";
|
|
11
11
|
import { admitPathInsideRoot } from "./root-boundary.js";
|
|
12
12
|
import { createSuppressedError } from "./suppressed-error.js";
|
|
13
13
|
import { realpathSync } from "./realpath.js";
|
|
@@ -50,9 +50,7 @@ export async function createRootDirectoryObservationGuard(root, directory) {
|
|
|
50
50
|
function directoryChangedError(error) {
|
|
51
51
|
if (error instanceof FsSafeError && error.code === "path-mismatch")
|
|
52
52
|
return error;
|
|
53
|
-
return new FsSafeError("path-mismatch", "directory changed during operation",
|
|
54
|
-
cause: error instanceof Error ? error : undefined,
|
|
55
|
-
});
|
|
53
|
+
return new FsSafeError("path-mismatch", "directory changed during operation", errorCauseOptions(error));
|
|
56
54
|
}
|
|
57
55
|
export async function assertRootDirectoryObservationGuard(root, guard) {
|
|
58
56
|
if (isNativeDirectoryObservationGuard(guard)) {
|
|
@@ -162,9 +160,7 @@ export function assertRootPathObservationReceiptCurrent(root, receipt, finalTarg
|
|
|
162
160
|
}
|
|
163
161
|
function normalizeDirectoryError(error) {
|
|
164
162
|
if (isNotFoundPathError(error)) {
|
|
165
|
-
return new FsSafeError("not-found", "directory not found",
|
|
166
|
-
cause: error instanceof Error ? error : undefined,
|
|
167
|
-
});
|
|
163
|
+
return new FsSafeError("not-found", "directory not found", errorCauseOptions(error));
|
|
168
164
|
}
|
|
169
165
|
return error;
|
|
170
166
|
}
|
package/dist/root-entries.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FsSafeError } from "./errors.js";
|
|
2
|
-
import {
|
|
2
|
+
import { validatePinnedRelativePath } from "./pinned-operation.js";
|
|
3
3
|
import { resolvePathInRoot } from "./root-context.js";
|
|
4
4
|
import { openRootDirectoryListing } from "./root-directory-list.js";
|
|
5
5
|
import { readSymlinkResolution } from "./root-symlink-policy.js";
|
|
@@ -13,7 +13,7 @@ export async function* entriesInRoot(root, relativePath, options) {
|
|
|
13
13
|
throw new TypeError(`invalid root entries order: ${String(options.order)}`);
|
|
14
14
|
}
|
|
15
15
|
options.signal?.throwIfAborted();
|
|
16
|
-
|
|
16
|
+
validatePinnedRelativePath(relativePath);
|
|
17
17
|
const resolved = await resolvePathInRoot(root, relativePath, {
|
|
18
18
|
...readSymlinkResolution(options.symlinks),
|
|
19
19
|
resolveCanonical: true,
|
package/dist/root-errors.d.ts
CHANGED
|
@@ -10,3 +10,7 @@ export declare function normalizePinnedPathError(error: unknown, details?: FsSaf
|
|
|
10
10
|
export declare function normalizeRemoveGuardError(error: unknown, details?: FsSafeErrorDetails): Error;
|
|
11
11
|
export declare function normalizeRemovePathError(error: unknown, details?: FsSafeErrorDetails): Error;
|
|
12
12
|
export declare function throwFsSafeReadError(error: unknown, label: string): never;
|
|
13
|
+
/** Existing boundaries retain only Error instances as their cause. */
|
|
14
|
+
export declare function errorCauseOptions(error: unknown): {
|
|
15
|
+
cause: Error | undefined;
|
|
16
|
+
};
|
package/dist/root-errors.js
CHANGED
|
@@ -41,9 +41,7 @@ export function normalizePinnedWriteError(error) {
|
|
|
41
41
|
const message = code
|
|
42
42
|
? `${PINNED_WRITE_ERRNO_MESSAGES.get(code) ?? "filesystem write failed"} (${code})`
|
|
43
43
|
: "path is not a regular file under root";
|
|
44
|
-
return new FsSafeError("invalid-path", message,
|
|
45
|
-
cause: error instanceof Error ? error : undefined,
|
|
46
|
-
});
|
|
44
|
+
return new FsSafeError("invalid-path", message, errorCauseOptions(error));
|
|
47
45
|
}
|
|
48
46
|
export function normalizePinnedPathError(error, details) {
|
|
49
47
|
if (error instanceof FsSafeError) {
|
|
@@ -88,3 +86,7 @@ export function throwFsSafeReadError(error, label) {
|
|
|
88
86
|
}
|
|
89
87
|
throw error;
|
|
90
88
|
}
|
|
89
|
+
/** Existing boundaries retain only Error instances as their cause. */
|
|
90
|
+
export function errorCauseOptions(error) {
|
|
91
|
+
return { cause: error instanceof Error ? error : undefined };
|
|
92
|
+
}
|
package/dist/root-impl.d.ts
CHANGED
|
@@ -7,13 +7,8 @@ import { type RootContext } from "./root-context.js";
|
|
|
7
7
|
import type { DirEntry, PathStat } from "./types.js";
|
|
8
8
|
import { type RootWalkEntry, type RootWalkOptions } from "./root-walk.js";
|
|
9
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";
|
|
11
10
|
export { DEFAULT_ROOT_MAX_BYTES } from "./root-options.js";
|
|
12
|
-
export type { DenyMutationPolicy } from "./deny-mutations.js";
|
|
13
|
-
export type { RenameIdentityPolicy } from "./pinned-write.js";
|
|
14
|
-
export type { MutationSymlinkPolicy, SymlinkPolicy } from "./root-symlink-policy.js";
|
|
15
11
|
export { resolveOpenedFileRealPathForHandle } from "./opened-realpath.js";
|
|
16
|
-
export type { ReadResult } from "./read-opened-file.js";
|
|
17
12
|
export type OpenResult = {
|
|
18
13
|
handle: FileHandle;
|
|
19
14
|
containment: ContainmentGuarantee;
|