@openclaw/fs-safe 0.12.0 → 0.13.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 +61 -0
- package/README.md +12 -7
- package/dist/absolute-path.d.ts.map +1 -1
- package/dist/absolute-path.js +32 -11
- package/dist/advanced.d.ts +2 -0
- package/dist/advanced.d.ts.map +1 -1
- package/dist/advanced.js +2 -0
- package/dist/archive-input.d.ts.map +1 -1
- package/dist/archive-input.js +6 -2
- package/dist/archive-merge.d.ts.map +1 -1
- package/dist/archive-merge.js +15 -2
- package/dist/archive-native.d.ts.map +1 -1
- package/dist/archive-native.js +7 -19
- package/dist/archive-plan.js +1 -1
- package/dist/archive-read.d.ts.map +1 -1
- package/dist/archive-read.js +18 -13
- package/dist/archive-staging.d.ts.map +1 -1
- package/dist/archive-staging.js +43 -10
- package/dist/archive-tar-inspect.d.ts.map +1 -1
- package/dist/archive-tar-inspect.js +4 -1
- 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 +2 -2
- package/dist/archive-zip-directory.d.ts +3 -0
- package/dist/archive-zip-directory.d.ts.map +1 -1
- package/dist/archive-zip-directory.js +13 -2
- package/dist/archive-zip-loader.d.ts +3 -2
- package/dist/archive-zip-loader.d.ts.map +1 -1
- package/dist/archive-zip-loader.js +30 -4
- package/dist/archive-zip-manifest.d.ts +5 -0
- package/dist/archive-zip-manifest.d.ts.map +1 -0
- package/dist/archive-zip-manifest.js +22 -0
- package/dist/archive-zip-names.d.ts +6 -1
- package/dist/archive-zip-names.d.ts.map +1 -1
- package/dist/archive-zip-names.js +35 -14
- package/dist/archive-zip-preflight.d.ts.map +1 -1
- package/dist/archive-zip-preflight.js +3 -2
- package/dist/archive.d.ts.map +1 -1
- package/dist/archive.js +9 -4
- package/dist/darwin-acl.d.ts +4 -0
- package/dist/darwin-acl.d.ts.map +1 -0
- package/dist/darwin-acl.js +24 -0
- package/dist/deny-mutations.d.ts.map +1 -1
- package/dist/deny-mutations.js +8 -2
- package/dist/directory-durability.d.ts.map +1 -1
- package/dist/directory-durability.js +67 -23
- package/dist/directory-entry-path.d.ts +3 -0
- package/dist/directory-entry-path.d.ts.map +1 -0
- package/dist/directory-entry-path.js +21 -0
- package/dist/directory-guard.d.ts +17 -1
- package/dist/directory-guard.d.ts.map +1 -1
- package/dist/directory-guard.js +134 -48
- package/dist/directory-mode-node.d.ts +12 -0
- package/dist/directory-mode-node.d.ts.map +1 -1
- package/dist/directory-mode-node.js +102 -4
- package/dist/effective-uid.d.ts +2 -0
- package/dist/effective-uid.d.ts.map +1 -0
- package/dist/effective-uid.js +25 -0
- package/dist/file-handle-transfer.d.ts.map +1 -1
- package/dist/file-handle-transfer.js +98 -27
- package/dist/file-hash.d.ts.map +1 -1
- package/dist/file-hash.js +3 -0
- package/dist/file-lock-sync.d.ts.map +1 -1
- package/dist/file-lock-sync.js +36 -6
- package/dist/file-lock.d.ts.map +1 -1
- package/dist/file-lock.js +29 -9
- package/dist/file-observation.d.ts +1 -1
- package/dist/file-observation.d.ts.map +1 -1
- package/dist/file-store-boundary.d.ts +6 -2
- package/dist/file-store-boundary.d.ts.map +1 -1
- package/dist/file-store-boundary.js +20 -65
- package/dist/file-store-copy-source.d.ts +5 -0
- package/dist/file-store-copy-source.d.ts.map +1 -0
- package/dist/file-store-copy-source.js +31 -0
- package/dist/file-store-path.d.ts.map +1 -1
- package/dist/file-store-path.js +4 -1
- package/dist/file-store-sync-directory.d.ts +16 -0
- package/dist/file-store-sync-directory.d.ts.map +1 -0
- package/dist/file-store-sync-directory.js +349 -0
- package/dist/file-store.d.ts.map +1 -1
- package/dist/file-store.js +11 -28
- package/dist/filename.d.ts.map +1 -1
- package/dist/filename.js +65 -20
- package/dist/fs.d.ts.map +1 -1
- package/dist/fs.js +3 -2
- package/dist/guarded-mkdir.d.ts +8 -0
- package/dist/guarded-mkdir.d.ts.map +1 -1
- package/dist/guarded-mkdir.js +176 -27
- package/dist/guest.d.ts.map +1 -1
- package/dist/guest.js +4 -1
- package/dist/home-dir.d.ts.map +1 -1
- package/dist/home-dir.js +73 -10
- package/dist/install-path.d.ts.map +1 -1
- package/dist/install-path.js +54 -19
- package/dist/json-durable-queue-ownership.d.ts +6 -0
- package/dist/json-durable-queue-ownership.d.ts.map +1 -1
- package/dist/json-durable-queue-ownership.js +89 -42
- package/dist/json-durable-queue-paths.d.ts +11 -0
- package/dist/json-durable-queue-paths.d.ts.map +1 -0
- package/dist/json-durable-queue-paths.js +42 -0
- package/dist/json-durable-queue-read.d.ts.map +1 -1
- package/dist/json-durable-queue-read.js +2 -0
- package/dist/json-durable-queue.d.ts.map +1 -1
- package/dist/json-durable-queue.js +50 -58
- package/dist/json-store.d.ts.map +1 -1
- package/dist/json-store.js +5 -1
- package/dist/json.d.ts.map +1 -1
- package/dist/json.js +54 -22
- package/dist/local-file-access.d.ts.map +1 -1
- package/dist/local-file-access.js +4 -0
- package/dist/local-file-descriptor.d.ts +17 -0
- package/dist/local-file-descriptor.d.ts.map +1 -0
- package/dist/local-file-descriptor.js +84 -0
- package/dist/local-roots.d.ts.map +1 -1
- package/dist/local-roots.js +35 -7
- package/dist/move-path-cleanup.d.ts +2 -0
- package/dist/move-path-cleanup.d.ts.map +1 -1
- package/dist/move-path-cleanup.js +44 -18
- package/dist/move-path.d.ts.map +1 -1
- package/dist/move-path.js +31 -6
- package/dist/native-binding.d.ts +14 -0
- package/dist/native-binding.d.ts.map +1 -1
- package/dist/native-directory-observation.d.ts +17 -0
- package/dist/native-directory-observation.d.ts.map +1 -0
- package/dist/native-directory-observation.js +37 -0
- package/dist/native-parent-admission.d.ts +31 -0
- package/dist/native-parent-admission.d.ts.map +1 -0
- package/dist/native-parent-admission.js +124 -0
- package/dist/native-pinned-write-windows.d.ts +0 -1
- package/dist/native-pinned-write-windows.d.ts.map +1 -1
- package/dist/native-pinned-write-windows.js +0 -3
- package/dist/native-pinned-write.d.ts.map +1 -1
- package/dist/native-pinned-write.js +309 -40
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +15 -5
- package/dist/overwrite-file-handle.d.ts.map +1 -1
- package/dist/overwrite-file-handle.js +5 -1
- package/dist/owner-dacl.d.ts.map +1 -1
- package/dist/owner-dacl.js +2 -0
- package/dist/path-policy.d.ts.map +1 -1
- package/dist/path-policy.js +7 -2
- package/dist/path-prefix.d.ts +7 -0
- package/dist/path-prefix.d.ts.map +1 -0
- package/dist/path-prefix.js +82 -0
- package/dist/path-scope-lexical.d.ts.map +1 -1
- package/dist/path-scope-lexical.js +18 -8
- package/dist/path-segment-route.d.ts +7 -0
- package/dist/path-segment-route.d.ts.map +1 -0
- package/dist/path-segment-route.js +24 -0
- package/dist/path-suffix-aliases.d.ts +10 -0
- package/dist/path-suffix-aliases.d.ts.map +1 -0
- package/dist/path-suffix-aliases.js +386 -0
- package/dist/path.d.ts.map +1 -1
- package/dist/path.js +16 -5
- package/dist/permissions-windows.d.ts.map +1 -1
- package/dist/permissions-windows.js +14 -3
- package/dist/permissions.d.ts.map +1 -1
- package/dist/permissions.js +37 -8
- package/dist/pinned-mutation-admission.d.ts +25 -0
- package/dist/pinned-mutation-admission.d.ts.map +1 -0
- package/dist/pinned-mutation-admission.js +425 -0
- package/dist/pinned-mutation-observation.d.ts +34 -0
- package/dist/pinned-mutation-observation.d.ts.map +1 -0
- package/dist/pinned-mutation-observation.js +142 -0
- package/dist/pinned-mutation-shared-route.d.ts +24 -0
- package/dist/pinned-mutation-shared-route.d.ts.map +1 -0
- package/dist/pinned-mutation-shared-route.js +70 -0
- package/dist/pinned-open.d.ts +6 -0
- package/dist/pinned-open.d.ts.map +1 -1
- package/dist/pinned-open.js +28 -10
- package/dist/pinned-write-types.d.ts +75 -0
- package/dist/pinned-write-types.d.ts.map +1 -0
- package/dist/pinned-write-types.js +1 -0
- package/dist/pinned-write.d.ts +7 -33
- package/dist/pinned-write.d.ts.map +1 -1
- package/dist/pinned-write.js +151 -17
- package/dist/private-directory.d.ts.map +1 -1
- package/dist/private-directory.js +2 -0
- package/dist/private-producer-handoff.d.ts +16 -0
- package/dist/private-producer-handoff.d.ts.map +1 -0
- package/dist/private-producer-handoff.js +272 -0
- package/dist/private-temp-workspace.d.ts +2 -39
- package/dist/private-temp-workspace.d.ts.map +1 -1
- package/dist/private-temp-workspace.js +183 -77
- package/dist/publish-file.d.ts.map +1 -1
- package/dist/publish-file.js +33 -29
- package/dist/regular-file.d.ts.map +1 -1
- package/dist/regular-file.js +56 -45
- package/dist/replace-directory.d.ts.map +1 -1
- package/dist/replace-directory.js +12 -5
- package/dist/replace-file-temp-owner.d.ts +1 -0
- package/dist/replace-file-temp-owner.d.ts.map +1 -1
- package/dist/replace-file-temp-owner.js +12 -1
- package/dist/replace-file.d.ts.map +1 -1
- package/dist/replace-file.js +24 -24
- package/dist/root-boundary.d.ts +4 -0
- package/dist/root-boundary.d.ts.map +1 -1
- package/dist/root-boundary.js +6 -1
- package/dist/root-context.d.ts +12 -1
- package/dist/root-context.d.ts.map +1 -1
- package/dist/root-context.js +57 -11
- package/dist/root-directory-creation.d.ts +13 -0
- package/dist/root-directory-creation.d.ts.map +1 -0
- package/dist/root-directory-creation.js +212 -0
- package/dist/root-directory-list.d.ts +16 -4
- package/dist/root-directory-list.d.ts.map +1 -1
- package/dist/root-directory-list.js +180 -39
- package/dist/root-directory.d.ts +23 -0
- package/dist/root-directory.d.ts.map +1 -0
- package/dist/root-directory.js +141 -0
- package/dist/root-errors.d.ts.map +1 -1
- package/dist/root-errors.js +12 -1
- package/dist/root-file-final-admission.d.ts +21 -0
- package/dist/root-file-final-admission.d.ts.map +1 -0
- package/dist/root-file-final-admission.js +83 -0
- package/dist/root-file.d.ts.map +1 -1
- package/dist/root-file.js +103 -24
- package/dist/root-impl.d.ts +1 -0
- package/dist/root-impl.d.ts.map +1 -1
- package/dist/root-impl.js +289 -317
- package/dist/root-move-noreplace.d.ts +14 -0
- package/dist/root-move-noreplace.d.ts.map +1 -0
- package/dist/root-move-noreplace.js +202 -0
- package/dist/root-observed-path.d.ts +9 -0
- package/dist/root-observed-path.d.ts.map +1 -0
- package/dist/root-observed-path.js +95 -0
- package/dist/root-path-errors.d.ts +12 -0
- package/dist/root-path-errors.d.ts.map +1 -0
- package/dist/root-path-errors.js +13 -0
- package/dist/root-path-existing.d.ts.map +1 -1
- package/dist/root-path-existing.js +53 -20
- package/dist/root-path-observation.d.ts +63 -0
- package/dist/root-path-observation.d.ts.map +1 -0
- package/dist/root-path-observation.js +180 -0
- package/dist/root-path-stat.d.ts +5 -0
- package/dist/root-path-stat.d.ts.map +1 -0
- package/dist/root-path-stat.js +101 -0
- package/dist/root-path-symlink.d.ts.map +1 -1
- package/dist/root-path-symlink.js +23 -4
- package/dist/root-path.d.ts +11 -0
- package/dist/root-path.d.ts.map +1 -1
- package/dist/root-path.js +215 -53
- package/dist/root-paths-lexical.d.ts +9 -0
- package/dist/root-paths-lexical.d.ts.map +1 -0
- package/dist/root-paths-lexical.js +22 -0
- package/dist/root-paths.d.ts +3 -25
- package/dist/root-paths.d.ts.map +1 -1
- package/dist/root-paths.js +77 -154
- package/dist/root-read-admission.d.ts +26 -0
- package/dist/root-read-admission.d.ts.map +1 -0
- package/dist/root-read-admission.js +94 -0
- package/dist/root-remove-identity.d.ts +15 -0
- package/dist/root-remove-identity.d.ts.map +1 -0
- package/dist/root-remove-identity.js +89 -0
- package/dist/root-remove-receipt.d.ts +17 -0
- package/dist/root-remove-receipt.d.ts.map +1 -0
- package/dist/root-remove-receipt.js +37 -0
- package/dist/root-remove.d.ts +2 -1
- package/dist/root-remove.d.ts.map +1 -1
- package/dist/root-remove.js +172 -10
- package/dist/root-write-admission.d.ts +68 -0
- package/dist/root-write-admission.d.ts.map +1 -0
- package/dist/root-write-admission.js +322 -0
- package/dist/root-write-compatibility.d.ts +13 -0
- package/dist/root-write-compatibility.d.ts.map +1 -0
- package/dist/root-write-compatibility.js +74 -0
- package/dist/root-write-complete-parent.d.ts +42 -0
- package/dist/root-write-complete-parent.d.ts.map +1 -0
- package/dist/root-write-complete-parent.js +195 -0
- package/dist/root-write-publication.d.ts +24 -0
- package/dist/root-write-publication.d.ts.map +1 -0
- package/dist/root-write-publication.js +85 -0
- package/dist/root-write-verification.d.ts.map +1 -1
- package/dist/root-write-verification.js +6 -4
- package/dist/secret-file.d.ts.map +1 -1
- package/dist/secret-file.js +62 -24
- package/dist/secret-read-async.d.ts.map +1 -1
- package/dist/secret-read-async.js +18 -13
- package/dist/secret-read-policy.d.ts.map +1 -1
- package/dist/secret-read-policy.js +5 -1
- package/dist/secure-file.d.ts.map +1 -1
- package/dist/secure-file.js +92 -7
- package/dist/secure-temp-dir.d.ts +6 -3
- package/dist/secure-temp-dir.d.ts.map +1 -1
- package/dist/secure-temp-dir.js +121 -101
- package/dist/secure-temp-repair.d.ts +35 -0
- package/dist/secure-temp-repair.d.ts.map +1 -0
- package/dist/secure-temp-repair.js +106 -0
- package/dist/sibling-staged-file.d.ts +3 -2
- package/dist/sibling-staged-file.d.ts.map +1 -1
- package/dist/sibling-staged-file.js +179 -55
- package/dist/sibling-temp.d.ts.map +1 -1
- package/dist/sibling-temp.js +27 -13
- package/dist/sidecar-lock-acquire.d.ts.map +1 -1
- package/dist/sidecar-lock-acquire.js +44 -14
- package/dist/sidecar-lock-root.d.ts.map +1 -1
- package/dist/sidecar-lock-root.js +4 -2
- package/dist/staged-directory.d.ts +14 -5
- package/dist/staged-directory.d.ts.map +1 -1
- package/dist/staged-directory.js +54 -3
- package/dist/standalone-publication-path.d.ts +2 -0
- package/dist/standalone-publication-path.d.ts.map +1 -0
- package/dist/standalone-publication-path.js +6 -0
- package/dist/stat-observation.d.ts +11 -0
- package/dist/stat-observation.d.ts.map +1 -0
- package/dist/stat-observation.js +64 -0
- package/dist/strict-file-identity.d.ts.map +1 -1
- package/dist/strict-file-identity.js +39 -2
- package/dist/symlink-parents.d.ts.map +1 -1
- package/dist/symlink-parents.js +7 -2
- package/dist/temp-target.d.ts +2 -0
- package/dist/temp-target.d.ts.map +1 -1
- package/dist/temp-target.js +130 -3
- package/dist/temp-workspace-admission.d.ts +22 -0
- package/dist/temp-workspace-admission.d.ts.map +1 -0
- package/dist/temp-workspace-admission.js +374 -0
- package/dist/temp-workspace-child-admission.d.ts +13 -0
- package/dist/temp-workspace-child-admission.d.ts.map +1 -0
- package/dist/temp-workspace-child-admission.js +95 -0
- package/dist/temp-workspace-descriptor.d.ts +48 -0
- package/dist/temp-workspace-descriptor.d.ts.map +1 -0
- package/dist/temp-workspace-descriptor.js +363 -0
- package/dist/temp-workspace-identity.d.ts +15 -0
- package/dist/temp-workspace-identity.d.ts.map +1 -0
- package/dist/temp-workspace-identity.js +41 -0
- package/dist/temp-workspace-owner.d.ts +7 -6
- package/dist/temp-workspace-owner.d.ts.map +1 -1
- package/dist/temp-workspace-owner.js +121 -61
- package/dist/temp-workspace-permissions.d.ts +4 -0
- package/dist/temp-workspace-permissions.d.ts.map +1 -0
- package/dist/temp-workspace-permissions.js +32 -0
- package/dist/temp-workspace-types.d.ts +40 -0
- package/dist/temp-workspace-types.d.ts.map +1 -0
- package/dist/temp-workspace-types.js +1 -0
- package/dist/temp.d.ts +1 -1
- package/dist/temp.d.ts.map +1 -1
- package/dist/temp.js +1 -1
- package/dist/test-hooks.d.ts +7 -0
- package/dist/test-hooks.d.ts.map +1 -1
- package/dist/text-atomic.d.ts.map +1 -1
- package/dist/text-atomic.js +3 -1
- package/dist/trash.d.ts.map +1 -1
- package/dist/trash.js +54 -8
- package/dist/walk.d.ts.map +1 -1
- package/dist/walk.js +9 -6
- package/dist/windows-owner.d.ts.map +1 -1
- package/dist/windows-owner.js +5 -0
- package/dist/windows-path-alias.d.ts +39 -0
- package/dist/windows-path-alias.d.ts.map +1 -0
- package/dist/windows-path-alias.js +153 -0
- package/docs/advanced.md +25 -0
- package/docs/archive.md +23 -2
- package/docs/atomic.md +27 -3
- package/docs/copy.md +3 -0
- package/docs/durability.md +14 -0
- package/docs/errors.md +14 -6
- package/docs/file-store.md +24 -3
- package/docs/filename.md +14 -7
- package/docs/install-path.md +2 -2
- package/docs/install.md +8 -7
- package/docs/json-store.md +5 -1
- package/docs/json.md +11 -0
- package/docs/mutation-policy-proof.md +65 -0
- package/docs/native-helper.md +26 -9
- package/docs/native.md +32 -8
- package/docs/output.md +33 -11
- package/docs/path-prefix.md +64 -0
- package/docs/path-suffix-aliases.md +159 -0
- package/docs/path.md +11 -0
- package/docs/private-file-store.md +14 -0
- package/docs/public-api.md +9 -0
- package/docs/quickstart.md +1 -1
- package/docs/reading.md +8 -1
- package/docs/root.md +18 -3
- package/docs/secret-file.md +3 -0
- package/docs/secure-file.md +6 -2
- package/docs/security-model.md +75 -8
- package/docs/sidecar-lock.md +28 -1
- package/docs/store.md +5 -1
- package/docs/temp.md +260 -36
- package/docs/test-hooks.md +14 -0
- package/docs/writing.md +38 -8
- package/package.json +10 -10
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
import fsSync from "node:fs";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import { nodeDirectorySearchOnlyFlags } from "./directory-mode-node.js";
|
|
4
|
+
import { assertOwnedDirectory } from "./directory-mode-owner.js";
|
|
5
|
+
import { FsSafeError } from "./errors.js";
|
|
6
|
+
import { assertNoWindowsPathAlias, pathForWindowsFilesystem, resolvePathPreservingWindowsRoot, } from "./windows-path-alias.js";
|
|
7
|
+
import { inspectFileIdentitySync } from "./strict-file-identity.js";
|
|
8
|
+
import { assertTempWorkspaceChildState, childHasRequestedMode, validateAdmittedTempWorkspaceChild, } from "./temp-workspace-child-admission.js";
|
|
9
|
+
import { inspectTempWorkspaceDescriptorIdentitySync, inspectTempWorkspaceDirectoryIdentitySync, projectTempWorkspaceNumericIdentity, TEMP_WORKSPACE_NUMERIC_IDENTITY_REPLAY, } from "./temp-workspace-identity.js";
|
|
10
|
+
function assertRetainedChildDirectory(stat) {
|
|
11
|
+
if (stat.isSymbolicLink() || !stat.isDirectory()) {
|
|
12
|
+
throw new FsSafeError("not-file", "temp workspace child must be a real directory");
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function closeAfterAdmissionFailure(fd, error, message) {
|
|
16
|
+
try {
|
|
17
|
+
fsSync.closeSync(fd);
|
|
18
|
+
}
|
|
19
|
+
catch (closeError) {
|
|
20
|
+
throw new AggregateError([error, closeError], message);
|
|
21
|
+
}
|
|
22
|
+
throw error;
|
|
23
|
+
}
|
|
24
|
+
function openReadableDirectory(pathname) {
|
|
25
|
+
assertNoWindowsPathAlias(pathname, "filesystem");
|
|
26
|
+
const operationPath = pathForWindowsFilesystem(pathname);
|
|
27
|
+
const flags = fsSync.constants.O_DIRECTORY | fsSync.constants.O_NOFOLLOW |
|
|
28
|
+
fsSync.constants.O_NONBLOCK;
|
|
29
|
+
return fsSync.openSync(operationPath, fsSync.constants.O_RDONLY | flags);
|
|
30
|
+
}
|
|
31
|
+
function openRetainedDirectory(pathname) {
|
|
32
|
+
try {
|
|
33
|
+
return { fd: openReadableDirectory(pathname), access: "read", proc: false };
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
if (error.code !== "EACCES")
|
|
37
|
+
throw error;
|
|
38
|
+
const route = nodeDirectorySearchOnlyFlags();
|
|
39
|
+
if (!route)
|
|
40
|
+
throw error;
|
|
41
|
+
const flags = fsSync.constants.O_DIRECTORY | fsSync.constants.O_NOFOLLOW |
|
|
42
|
+
fsSync.constants.O_NONBLOCK;
|
|
43
|
+
return {
|
|
44
|
+
fd: fsSync.openSync(pathname, route.flags | flags),
|
|
45
|
+
access: "search",
|
|
46
|
+
proc: route.proc,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function chmodDescriptor(fd, mode) {
|
|
51
|
+
return new Promise((resolve, reject) => {
|
|
52
|
+
fsSync.fchmod(fd, mode, (error) => {
|
|
53
|
+
if (error)
|
|
54
|
+
reject(error);
|
|
55
|
+
else
|
|
56
|
+
resolve();
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
export function openTempWorkspaceCleanupParent(root, admission) {
|
|
61
|
+
assertNoWindowsPathAlias(root, "filesystem");
|
|
62
|
+
const admittedRoot = admission.dir;
|
|
63
|
+
assertNoWindowsPathAlias(admittedRoot, "filesystem");
|
|
64
|
+
const pathname = resolvePathPreservingWindowsRoot(root);
|
|
65
|
+
assertNoWindowsPathAlias(pathname, "filesystem");
|
|
66
|
+
if (pathname !== resolvePathPreservingWindowsRoot(admittedRoot)) {
|
|
67
|
+
throw new FsSafeError("path-mismatch", "temp workspace cleanup parent differs from admitted root");
|
|
68
|
+
}
|
|
69
|
+
const opened = openRetainedDirectory(pathname);
|
|
70
|
+
const { fd } = opened;
|
|
71
|
+
try {
|
|
72
|
+
// Existing canonical roots deliberately retain this descriptor
|
|
73
|
+
// provisionally. Its exact association is completed at the native probe
|
|
74
|
+
// (when present) and again with the full pre-mutation ancestry admission.
|
|
75
|
+
// Guarded alias/missing-component routes retain their historical eager
|
|
76
|
+
// association through the admission implementation.
|
|
77
|
+
admission.retainCleanupParent(fd);
|
|
78
|
+
return {
|
|
79
|
+
fd,
|
|
80
|
+
access: opened.access,
|
|
81
|
+
receipt: Object.freeze({
|
|
82
|
+
path: pathname,
|
|
83
|
+
realPath: admission.realPath,
|
|
84
|
+
identity: admission.identity,
|
|
85
|
+
}),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
closeAfterAdmissionFailure(fd, error, "temp workspace cleanup parent admission and close failed");
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/** Owns the child descriptor until final admission transfers it to cleanup. */
|
|
93
|
+
export class TempWorkspaceRetainedChild {
|
|
94
|
+
#dir;
|
|
95
|
+
#identity;
|
|
96
|
+
#numericIdentity;
|
|
97
|
+
#access;
|
|
98
|
+
#fd;
|
|
99
|
+
#modeLease = false;
|
|
100
|
+
#proc;
|
|
101
|
+
#transferAuthorized = false;
|
|
102
|
+
#initialReceipt;
|
|
103
|
+
constructor(dir, identity, descriptor, initialReceipt) {
|
|
104
|
+
if (typeof identity.dev !== "bigint" || typeof identity.ino !== "bigint") {
|
|
105
|
+
throw new FsSafeError("path-mismatch", "temp workspace child identity is incomplete");
|
|
106
|
+
}
|
|
107
|
+
this.#dir = dir;
|
|
108
|
+
this.#identity = Object.freeze({ dev: identity.dev, ino: identity.ino });
|
|
109
|
+
this.#numericIdentity = TEMP_WORKSPACE_NUMERIC_IDENTITY_REPLAY
|
|
110
|
+
? projectTempWorkspaceNumericIdentity(this.#identity)
|
|
111
|
+
: undefined;
|
|
112
|
+
this.#access = descriptor.access;
|
|
113
|
+
this.#proc = descriptor.proc;
|
|
114
|
+
// Opening without following the final component pins the child, but does
|
|
115
|
+
// not admit it. Until final descriptor + name validation succeeds this
|
|
116
|
+
// handle may only be inspected, mode-validated, replaced, or closed.
|
|
117
|
+
this.#fd = descriptor.fd;
|
|
118
|
+
this.#initialReceipt = initialReceipt;
|
|
119
|
+
}
|
|
120
|
+
static retain(dir, identity) {
|
|
121
|
+
if (typeof identity.dev !== "bigint" || typeof identity.ino !== "bigint") {
|
|
122
|
+
throw new FsSafeError("path-mismatch", "temp workspace child identity is incomplete");
|
|
123
|
+
}
|
|
124
|
+
const descriptor = openRetainedDirectory(dir);
|
|
125
|
+
try {
|
|
126
|
+
return new TempWorkspaceRetainedChild(dir, identity, descriptor);
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
closeAfterAdmissionFailure(descriptor.fd, error, "temp workspace child admission and close failed");
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
static retainCreated(dir) {
|
|
133
|
+
const descriptor = openRetainedDirectory(dir);
|
|
134
|
+
try {
|
|
135
|
+
// Only this immediate post-create route installs a receipt. Freezing the
|
|
136
|
+
// exact fd result keeps its identity and complete mode immutable while
|
|
137
|
+
// the synchronous caller validates it and decides whether to correct.
|
|
138
|
+
const stat = fsSync.fstatSync(descriptor.fd, { bigint: true });
|
|
139
|
+
Object.freeze(stat);
|
|
140
|
+
const receipt = Object.freeze({ stat });
|
|
141
|
+
return {
|
|
142
|
+
retained: new TempWorkspaceRetainedChild(dir, stat, descriptor, receipt),
|
|
143
|
+
stat,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
closeAfterAdmissionFailure(descriptor.fd, error, "temp workspace created child admission and close failed");
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
discardInitialReceipt() {
|
|
151
|
+
this.#initialReceipt = undefined;
|
|
152
|
+
}
|
|
153
|
+
#consumeInitialReceipt() {
|
|
154
|
+
const receipt = this.#initialReceipt;
|
|
155
|
+
// Clear first so validation failures, procfs checks, and later admission
|
|
156
|
+
// can never reuse the creation observation.
|
|
157
|
+
this.#initialReceipt = undefined;
|
|
158
|
+
return receipt?.stat;
|
|
159
|
+
}
|
|
160
|
+
finalizeAdmission(ownerUid, mode) {
|
|
161
|
+
this.#assertModeLeaseReleased();
|
|
162
|
+
this.discardInitialReceipt();
|
|
163
|
+
if (this.#fd === undefined) {
|
|
164
|
+
throw new FsSafeError("path-mismatch", "temp workspace child descriptor is unavailable");
|
|
165
|
+
}
|
|
166
|
+
// A failed revalidation must never leave an earlier receipt transferable.
|
|
167
|
+
this.#transferAuthorized = false;
|
|
168
|
+
const current = inspectTempWorkspaceDescriptorIdentitySync(this.#fd, this.#identity, this.#numericIdentity);
|
|
169
|
+
validateAdmittedTempWorkspaceChild(current, ownerUid, mode);
|
|
170
|
+
const named = inspectTempWorkspaceDirectoryIdentitySync(this.#dir, this.#identity, this.#numericIdentity);
|
|
171
|
+
validateAdmittedTempWorkspaceChild(named, ownerUid, mode);
|
|
172
|
+
this.#transferAuthorized = true;
|
|
173
|
+
return named;
|
|
174
|
+
}
|
|
175
|
+
#assertModeLeaseReleased() {
|
|
176
|
+
if (this.#modeLease) {
|
|
177
|
+
throw new FsSafeError("path-mismatch", "temp workspace child mode operation is active");
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
#inspectModeTarget(fd, ownerUid, initial) {
|
|
181
|
+
const descriptor = initial ?? inspectTempWorkspaceDescriptorIdentitySync(fd, this.#identity, this.#numericIdentity);
|
|
182
|
+
assertTempWorkspaceChildState(descriptor, ownerUid);
|
|
183
|
+
const named = inspectTempWorkspaceDirectoryIdentitySync(this.#dir, this.#identity, this.#numericIdentity);
|
|
184
|
+
assertTempWorkspaceChildState(named, ownerUid);
|
|
185
|
+
return descriptor;
|
|
186
|
+
}
|
|
187
|
+
async #assertProcAuthority(fd, ownerUid) {
|
|
188
|
+
if ((await fs.statfs("/proc/self/fd", { bigint: true })).type !== 0x9fa0n) {
|
|
189
|
+
throw new FsSafeError("path-mismatch", "directory mode requires a trusted procfs fd namespace");
|
|
190
|
+
}
|
|
191
|
+
const procPath = `/proc/self/fd/${fd}`;
|
|
192
|
+
const opened = inspectFileIdentitySync(() => fsSync.fstatSync(fd, { bigint: true }), this.#identity);
|
|
193
|
+
const followed = inspectFileIdentitySync(() => fsSync.statSync(procPath, { bigint: true }), this.#identity);
|
|
194
|
+
assertOwnedDirectory(opened, followed);
|
|
195
|
+
assertTempWorkspaceChildState(opened, ownerUid);
|
|
196
|
+
assertTempWorkspaceChildState(followed, ownerUid);
|
|
197
|
+
}
|
|
198
|
+
#assertProcAuthoritySync(fd, ownerUid) {
|
|
199
|
+
if (fsSync.statfsSync("/proc/self/fd", { bigint: true }).type !== 0x9fa0n) {
|
|
200
|
+
throw new FsSafeError("path-mismatch", "directory mode requires a trusted procfs fd namespace");
|
|
201
|
+
}
|
|
202
|
+
const procPath = `/proc/self/fd/${fd}`;
|
|
203
|
+
const opened = inspectFileIdentitySync(() => fsSync.fstatSync(fd, { bigint: true }), this.#identity);
|
|
204
|
+
const followed = inspectFileIdentitySync(() => fsSync.statSync(procPath, { bigint: true }), this.#identity);
|
|
205
|
+
assertOwnedDirectory(opened, followed);
|
|
206
|
+
assertTempWorkspaceChildState(opened, ownerUid);
|
|
207
|
+
assertTempWorkspaceChildState(followed, ownerUid);
|
|
208
|
+
}
|
|
209
|
+
async initializeMode(mode, ownerUid, assertParent) {
|
|
210
|
+
this.#assertModeLeaseReleased();
|
|
211
|
+
this.discardInitialReceipt();
|
|
212
|
+
if (this.#fd === undefined) {
|
|
213
|
+
throw new FsSafeError("path-mismatch", "temp workspace child descriptor is unavailable");
|
|
214
|
+
}
|
|
215
|
+
const fd = this.#fd;
|
|
216
|
+
this.#transferAuthorized = false;
|
|
217
|
+
this.#modeLease = true;
|
|
218
|
+
try {
|
|
219
|
+
assertParent();
|
|
220
|
+
let current = this.#inspectModeTarget(fd, ownerUid);
|
|
221
|
+
assertParent();
|
|
222
|
+
if (childHasRequestedMode(current, mode))
|
|
223
|
+
return;
|
|
224
|
+
if (this.#proc) {
|
|
225
|
+
await this.#assertProcAuthority(fd, ownerUid);
|
|
226
|
+
// statfs is awaited. Rebind both names and the retained descriptor
|
|
227
|
+
// after that turn before dispatching the procfs descriptor chmod.
|
|
228
|
+
assertParent();
|
|
229
|
+
current = this.#inspectModeTarget(fd, ownerUid);
|
|
230
|
+
assertParent();
|
|
231
|
+
if (childHasRequestedMode(current, mode))
|
|
232
|
+
return;
|
|
233
|
+
await fs.chmod(`/proc/self/fd/${fd}`, mode & 0o7777);
|
|
234
|
+
await this.#assertProcAuthority(fd, ownerUid);
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
await chmodDescriptor(fd, mode & 0o7777);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
finally {
|
|
241
|
+
// The lease outlives every queued fd operation, including failures, so
|
|
242
|
+
// transfer or factory cleanup can never close a still-active descriptor.
|
|
243
|
+
this.#modeLease = false;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
initializeModeSync(mode, ownerUid, assertParent) {
|
|
247
|
+
this.#assertModeLeaseReleased();
|
|
248
|
+
if (this.#fd === undefined) {
|
|
249
|
+
throw new FsSafeError("path-mismatch", "temp workspace child descriptor is unavailable");
|
|
250
|
+
}
|
|
251
|
+
const fd = this.#fd;
|
|
252
|
+
this.#transferAuthorized = false;
|
|
253
|
+
this.#modeLease = true;
|
|
254
|
+
try {
|
|
255
|
+
const current = this.#inspectModeTarget(fd, ownerUid, this.#consumeInitialReceipt());
|
|
256
|
+
assertParent();
|
|
257
|
+
if (childHasRequestedMode(current, mode))
|
|
258
|
+
return;
|
|
259
|
+
if (this.#proc) {
|
|
260
|
+
this.#assertProcAuthoritySync(fd, ownerUid);
|
|
261
|
+
fsSync.chmodSync(`/proc/self/fd/${fd}`, mode & 0o7777);
|
|
262
|
+
this.#assertProcAuthoritySync(fd, ownerUid);
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
fsSync.fchmodSync(fd, mode & 0o7777);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
finally {
|
|
269
|
+
this.#modeLease = false;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
get canEnumerate() {
|
|
273
|
+
return this.#access === "read";
|
|
274
|
+
}
|
|
275
|
+
ensureReadable() {
|
|
276
|
+
this.#assertModeLeaseReleased();
|
|
277
|
+
this.discardInitialReceipt();
|
|
278
|
+
if (this.canEnumerate)
|
|
279
|
+
return true;
|
|
280
|
+
if (this.#fd === undefined) {
|
|
281
|
+
throw new FsSafeError("path-mismatch", "temp workspace child descriptor is unavailable");
|
|
282
|
+
}
|
|
283
|
+
// Opening or validating a replacement crosses a new pathname boundary.
|
|
284
|
+
// Even failure must revoke any earlier final-admission receipt.
|
|
285
|
+
this.#transferAuthorized = false;
|
|
286
|
+
let fd;
|
|
287
|
+
try {
|
|
288
|
+
fd = openReadableDirectory(this.#dir);
|
|
289
|
+
}
|
|
290
|
+
catch (error) {
|
|
291
|
+
if (error.code === "EACCES")
|
|
292
|
+
return false;
|
|
293
|
+
throw error;
|
|
294
|
+
}
|
|
295
|
+
try {
|
|
296
|
+
const openedStat = inspectTempWorkspaceDescriptorIdentitySync(fd, this.#identity, this.#numericIdentity);
|
|
297
|
+
assertRetainedChildDirectory(openedStat);
|
|
298
|
+
}
|
|
299
|
+
catch (error) {
|
|
300
|
+
closeAfterAdmissionFailure(fd, error, "temp workspace readable child admission and close failed");
|
|
301
|
+
}
|
|
302
|
+
// A failed close leaves descriptor ownership indeterminate. Relinquish the
|
|
303
|
+
// old descriptor before closing it so factory cleanup never retries that fd.
|
|
304
|
+
const previous = this.#fd;
|
|
305
|
+
this.#fd = undefined;
|
|
306
|
+
try {
|
|
307
|
+
fsSync.closeSync(previous);
|
|
308
|
+
}
|
|
309
|
+
catch (error) {
|
|
310
|
+
// The readable replacement has not been installed. Give it exactly one
|
|
311
|
+
// close attempt and leave neither indeterminate descriptor owned here.
|
|
312
|
+
try {
|
|
313
|
+
fsSync.closeSync(fd);
|
|
314
|
+
}
|
|
315
|
+
catch (closeError) {
|
|
316
|
+
throw new AggregateError([error, closeError], "temp workspace child descriptor replacement close failed");
|
|
317
|
+
}
|
|
318
|
+
throw error;
|
|
319
|
+
}
|
|
320
|
+
this.#fd = fd;
|
|
321
|
+
this.#access = "read";
|
|
322
|
+
this.#proc = false;
|
|
323
|
+
return true;
|
|
324
|
+
}
|
|
325
|
+
transfer(retainDescriptor) {
|
|
326
|
+
this.#assertModeLeaseReleased();
|
|
327
|
+
this.discardInitialReceipt();
|
|
328
|
+
if (this.#fd === undefined) {
|
|
329
|
+
throw new FsSafeError("path-mismatch", "temp workspace child descriptor is unavailable");
|
|
330
|
+
}
|
|
331
|
+
if (!this.#transferAuthorized) {
|
|
332
|
+
throw new FsSafeError("path-mismatch", "temp workspace child has not completed final admission");
|
|
333
|
+
}
|
|
334
|
+
const fd = this.#fd;
|
|
335
|
+
this.#fd = undefined;
|
|
336
|
+
if (retainDescriptor && !this.canEnumerate) {
|
|
337
|
+
try {
|
|
338
|
+
fsSync.closeSync(fd);
|
|
339
|
+
}
|
|
340
|
+
catch (closeError) {
|
|
341
|
+
throw new AggregateError([
|
|
342
|
+
new FsSafeError("helper-unavailable", "temp workspace cleanup requires a readable child descriptor"),
|
|
343
|
+
closeError,
|
|
344
|
+
], "temp workspace child descriptor rejection and close failed");
|
|
345
|
+
}
|
|
346
|
+
throw new FsSafeError("helper-unavailable", "temp workspace cleanup requires a readable child descriptor");
|
|
347
|
+
}
|
|
348
|
+
if (!retainDescriptor) {
|
|
349
|
+
fsSync.closeSync(fd);
|
|
350
|
+
return { dir: this.#dir, identity: this.#identity, directory: undefined };
|
|
351
|
+
}
|
|
352
|
+
return { dir: this.#dir, identity: this.#identity, directory: { fd } };
|
|
353
|
+
}
|
|
354
|
+
close() {
|
|
355
|
+
this.#assertModeLeaseReleased();
|
|
356
|
+
this.discardInitialReceipt();
|
|
357
|
+
if (this.#fd === undefined)
|
|
358
|
+
return;
|
|
359
|
+
const fd = this.#fd;
|
|
360
|
+
this.#fd = undefined;
|
|
361
|
+
fsSync.closeSync(fd);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type BigIntStats, type Stats } from "node:fs";
|
|
2
|
+
export type TempWorkspaceIdentity = Readonly<{
|
|
3
|
+
dev: bigint;
|
|
4
|
+
ino: bigint;
|
|
5
|
+
}>;
|
|
6
|
+
export type TempWorkspaceNumericIdentity = Readonly<{
|
|
7
|
+
dev: number;
|
|
8
|
+
ino: number;
|
|
9
|
+
}>;
|
|
10
|
+
export type TempWorkspaceIdentityStat = BigIntStats | Stats;
|
|
11
|
+
export declare const TEMP_WORKSPACE_NUMERIC_IDENTITY_REPLAY: boolean;
|
|
12
|
+
export declare function projectTempWorkspaceNumericIdentity(identity: TempWorkspaceIdentity): TempWorkspaceNumericIdentity | undefined;
|
|
13
|
+
export declare function inspectTempWorkspaceDescriptorIdentitySync(fd: number, expected: TempWorkspaceIdentity, numeric: TempWorkspaceNumericIdentity | undefined): TempWorkspaceIdentityStat;
|
|
14
|
+
export declare function inspectTempWorkspaceDirectoryIdentitySync(dir: string, expected: TempWorkspaceIdentity, numeric: TempWorkspaceNumericIdentity | undefined): TempWorkspaceIdentityStat;
|
|
15
|
+
//# sourceMappingURL=temp-workspace-identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"temp-workspace-identity.d.ts","sourceRoot":"","sources":["../src/temp-workspace-identity.ts"],"names":[],"mappings":"AAAA,OAAe,EAAE,KAAK,WAAW,EAAE,KAAK,KAAK,EAAE,MAAM,SAAS,CAAC;AAM/D,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAC3E,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAClF,MAAM,MAAM,yBAAyB,GAAG,WAAW,GAAG,KAAK,CAAC;AAE5D,eAAO,MAAM,sCAAsC,SACY,CAAC;AAEhE,wBAAgB,mCAAmC,CACjD,QAAQ,EAAE,qBAAqB,GAC9B,4BAA4B,GAAG,SAAS,CAU1C;AAqBD,wBAAgB,0CAA0C,CACxD,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,qBAAqB,EAC/B,OAAO,EAAE,4BAA4B,GAAG,SAAS,GAChD,yBAAyB,CAO3B;AAED,wBAAgB,yCAAyC,CACvD,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,qBAAqB,EAC/B,OAAO,EAAE,4BAA4B,GAAG,SAAS,GAChD,yBAAyB,CAQ3B"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import fsSync, {} from "node:fs";
|
|
2
|
+
import { observeDirectoryIdentitySync } from "./directory-guard.js";
|
|
3
|
+
import { FsSafeError } from "./errors.js";
|
|
4
|
+
import { recordFileObservationFailure } from "./file-observation.js";
|
|
5
|
+
import { inspectFileIdentitySync } from "./strict-file-identity.js";
|
|
6
|
+
export const TEMP_WORKSPACE_NUMERIC_IDENTITY_REPLAY = process.platform === "linux" || process.platform === "darwin";
|
|
7
|
+
export function projectTempWorkspaceNumericIdentity(identity) {
|
|
8
|
+
const dev = Number(identity.dev);
|
|
9
|
+
const ino = Number(identity.ino);
|
|
10
|
+
if (!Number.isSafeInteger(dev) || dev < 0 || BigInt(dev) !== identity.dev ||
|
|
11
|
+
!Number.isSafeInteger(ino) || ino < 0 || BigInt(ino) !== identity.ino) {
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
return Object.freeze({ dev, ino });
|
|
15
|
+
}
|
|
16
|
+
function identityMismatch() {
|
|
17
|
+
const error = new FsSafeError("path-mismatch", "file identity changed or could not be verified");
|
|
18
|
+
recordFileObservationFailure(error, "identity");
|
|
19
|
+
throw error;
|
|
20
|
+
}
|
|
21
|
+
function inspectNumericIdentity(current, expected) {
|
|
22
|
+
if (!Number.isSafeInteger(current.dev) || current.dev < 0 || current.dev !== expected.dev ||
|
|
23
|
+
!Number.isSafeInteger(current.ino) || current.ino < 0 || current.ino !== expected.ino) {
|
|
24
|
+
identityMismatch();
|
|
25
|
+
}
|
|
26
|
+
return current;
|
|
27
|
+
}
|
|
28
|
+
export function inspectTempWorkspaceDescriptorIdentitySync(fd, expected, numeric) {
|
|
29
|
+
// A malformed or mismatched numeric observation is definite and never
|
|
30
|
+
// retried. Unsafe receipts and other platforms retain exact replay.
|
|
31
|
+
if (TEMP_WORKSPACE_NUMERIC_IDENTITY_REPLAY && numeric) {
|
|
32
|
+
return inspectNumericIdentity(fsSync.fstatSync(fd), numeric);
|
|
33
|
+
}
|
|
34
|
+
return inspectFileIdentitySync(() => fsSync.fstatSync(fd, { bigint: true }), expected);
|
|
35
|
+
}
|
|
36
|
+
export function inspectTempWorkspaceDirectoryIdentitySync(dir, expected, numeric) {
|
|
37
|
+
if (TEMP_WORKSPACE_NUMERIC_IDENTITY_REPLAY && numeric) {
|
|
38
|
+
return inspectNumericIdentity(observeDirectoryIdentitySync(dir), numeric);
|
|
39
|
+
}
|
|
40
|
+
return inspectFileIdentitySync(() => observeDirectoryIdentitySync(dir, { bigint: true }), expected);
|
|
41
|
+
}
|
|
@@ -1,23 +1,24 @@
|
|
|
1
|
-
import { type FileIdentityStat } from "./file-identity.js";
|
|
2
1
|
import { type NativeBinding } from "./native.js";
|
|
3
|
-
import {
|
|
2
|
+
import type { TempWorkspaceRootAdmission } from "./temp-workspace-admission.js";
|
|
3
|
+
import { TempWorkspaceRetainedChild, type RetainedDirectory } from "./temp-workspace-descriptor.js";
|
|
4
4
|
export type TempWorkspaceCleanupResult = "removed" | "missing" | "identity-mismatch" | "indeterminate";
|
|
5
5
|
export type TempWorkspaceCleanupSafety = "compatible" | "require-bounded";
|
|
6
|
-
type RetainedDirectory = ReturnType<typeof openStagedDirectory>;
|
|
7
6
|
export declare class TempWorkspaceCleanupCapability {
|
|
8
7
|
#private;
|
|
9
8
|
readonly binding: NativeBinding | undefined;
|
|
10
9
|
readonly parent: RetainedDirectory | undefined;
|
|
11
|
-
constructor(root: string, safety: TempWorkspaceCleanupSafety);
|
|
10
|
+
constructor(root: string, safety: TempWorkspaceCleanupSafety, admission: TempWorkspaceRootAdmission, dirMode: number);
|
|
12
11
|
get canRemoveOwnedTree(): boolean;
|
|
12
|
+
prepareChildCreation(): void;
|
|
13
|
+
admitChildDescriptor(canEnumerate: boolean): boolean;
|
|
13
14
|
assertCurrent(): void;
|
|
15
|
+
assertAncestryCurrent(): void;
|
|
14
16
|
close(): void;
|
|
15
17
|
}
|
|
16
18
|
export declare class TempWorkspaceCleanupOwner {
|
|
17
19
|
#private;
|
|
18
|
-
constructor(
|
|
20
|
+
constructor(retained: TempWorkspaceRetainedChild, capability: TempWorkspaceCleanupCapability, retainDescriptor: boolean);
|
|
19
21
|
cleanup(): Promise<TempWorkspaceCleanupResult>;
|
|
20
22
|
cleanupSync(): TempWorkspaceCleanupResult;
|
|
21
23
|
}
|
|
22
|
-
export {};
|
|
23
24
|
//# sourceMappingURL=temp-workspace-owner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"temp-workspace-owner.d.ts","sourceRoot":"","sources":["../src/temp-workspace-owner.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"temp-workspace-owner.d.ts","sourceRoot":"","sources":["../src/temp-workspace-owner.ts"],"names":[],"mappings":"AAOA,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAEnE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAChF,OAAO,EAEL,0BAA0B,EAE1B,KAAK,iBAAiB,EACvB,MAAM,gCAAgC,CAAC;AAGxC,MAAM,MAAM,0BAA0B,GAAG,SAAS,GAAG,SAAS,GAAG,mBAAmB,GAAG,eAAe,CAAC;AACvG,MAAM,MAAM,0BAA0B,GAAG,YAAY,GAAG,iBAAiB,CAAC;AAsB1E,qBAAa,8BAA8B;;IACzC,QAAQ,CAAC,OAAO,EAAE,aAAa,GAAG,SAAS,CAAC;IAC5C,QAAQ,CAAC,MAAM,EAAE,iBAAiB,GAAG,SAAS,CAAC;IAM/C,YACE,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,0BAA0B,EAClC,SAAS,EAAE,0BAA0B,EACrC,OAAO,EAAE,MAAM,EAuEhB;IAED,IAAI,kBAAkB,IAAI,OAAO,CAGhC;IAED,oBAAoB,IAAI,IAAI,CAiB3B;IAUD,oBAAoB,CAAC,YAAY,EAAE,OAAO,GAAG,OAAO,CAenD;IAED,aAAa,IAAI,IAAI,CAEpB;IAED,qBAAqB,IAAI,IAAI,CAE5B;IAED,KAAK,IAAI,IAAI,CAIZ;CACF;AAED,qBAAa,yBAAyB;;IAWpC,YACE,QAAQ,EAAE,0BAA0B,EACpC,UAAU,EAAE,8BAA8B,EAC1C,gBAAgB,EAAE,OAAO,EAO1B;IAkLD,OAAO,IAAI,OAAO,CAAC,0BAA0B,CAAC,CAM7C;IAED,WAAW,IAAI,0BAA0B,CAexC;CACF"}
|