@better-fs-tools/just-bash 0.1.0 → 0.2.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/README.md CHANGED
@@ -34,9 +34,6 @@ const read = createReadTool({
34
34
 
35
35
  console.log(textOf(await read({ path: "src/index.ts" })));
36
36
  // 1|const a = 1;
37
- //
38
- // [read:weak-identity] The sandbox backend has no stable identity, ...
39
- // [read:buffered-backend] The sandbox backend buffers whole objects instead of streaming them.
40
37
  ```
41
38
 
42
39
  The same filesystem, with the write tools:
@@ -62,10 +59,6 @@ const edit = createEditTool({ ...shared, locks: memoryLocks() });
62
59
  await read({ path: "src/index.ts" });
63
60
  console.log(textOf(await edit({ path: "src/index.ts", edits: [{ oldText: "1", newText: "2" }] })));
64
61
  // Edited src/index.ts: 1 replacement at line 1.
65
- // 1|const a = 2;
66
- //
67
- // [edit:not-atomic] The sandbox backend does not replace files atomically, ...
68
- // [edit:no-compare-and-swap] The sandbox backend cannot check the file version ...
69
62
  console.log(await bash.readFile("/workspace/src/index.ts")); // const a = 2;
70
63
  ```
71
64
 
@@ -73,9 +66,9 @@ console.log(await bash.readFile("/workspace/src/index.ts")); // const a = 2;
73
66
 
74
67
  - `justBashFileSystem(fs, options)` takes the shared `FileSystemRootOptions` and `maxBufferedBytes` from `@better-fs-tools/fs`. It checks each path against `allowedRoots` and `denyRoots` before it touches the backend, and again after `realpath()`. `cwd` must be absolute and defaults to `/`.
75
68
  - `id` defaults to `"just-bash"`. It namespaces versions, so two backends that share one state store need two ids.
76
- - `maxBufferedBytes` defaults to 16 MiB. `just-bash` returns whole buffers, so reads are buffered and results have a `buffered-backend` note. A larger file gives `too-large`, which the tools report as `TOO_LARGE`.
69
+ - `maxBufferedBytes` defaults to 16 MiB. `just-bash` returns whole buffers, so reads are buffered. A larger file gives `too-large`, which the tools report as `TOO_LARGE`.
77
70
  - Reads are buffered inside `open()`, so the whole file has left the backend before the read tool's `authorize` runs. The core still passes no byte to a classifier, a converter, or the model until `authorize` allows it. If a denied read must not reach the backend, deny it in the adapter with `denyRoots` or `allowedRoots`.
78
- - `identity` defaults to `"none"`: change detection compares size and modification time, and results have a `weak-identity` note. With `identity: "required"`, the backend's `stat()` must give an identity or a device and inode for every file. A file without one is refused as `UNSUPPORTED_BACKEND`.
71
+ - `identity` defaults to `"none"`: change detection compares size and modification time. With `identity: "required"`, the backend's `stat()` must give an identity or a device and inode for every file. A file without one is refused as `UNSUPPORTED_BACKEND`.
79
72
  - `symlinks` defaults to `"reject"`, which refuses a symlink in any component of the path, as in the Node and Cloudflare adapters. `"follow-within-roots"` follows links, and the real path must still be inside the roots.
80
73
  - The resolved options are on the filesystem as `cwd`, `allowedRoots`, `denyRoots`, `maxBufferedBytes`, `identity`, and `symlinks`.
81
74
  - For a read-only view, wrap it: `readOnlyFileSystem(justBashFileSystem(bash, options))` from `@better-fs-tools/fs` drops the write methods.
@@ -87,7 +80,7 @@ console.log(await bash.readFile("/workspace/src/index.ts")); // const a = 2;
87
80
  `write()` needs `writeFile`, `mkdir`, `chmod`, and `utimes` on the backend, and `remove()` needs `rm`. They are checked when a write runs, not when the filesystem is built, so a backend without them still serves reads. A write to such a backend gives `unsupported`, which the tools report as `UNSUPPORTED_BACKEND`. The `fs` parameter has the type `JustBashBackend`: `lstat`, `realpath`, `stat`, `readFileBuffer`, and `readdir` are required, and `readdirWithFileTypes` and the write methods are optional. A full `IFileSystem` fits it, and so does a read-only backend, with no cast.
88
81
 
89
82
  - Writes apply the same roots, deny roots, and symlink policy as `open()`. Under `"reject"`, a symlink anywhere on the path is refused. Under `"follow-within-roots"`, a link inside the roots is followed to its real path and the link stays. A link out of the roots and a dangling link are refused.
90
- - `writeCapabilities` is `{ atomic: false, compareAndSwap: false, preserveMode: true }`. A write is `writeFile` and then `chmod`, and `IFileSystem` has no version check, so the adapter checks the precondition with a fresh stat just before the write. The write tools add a `not-atomic` and a `no-compare-and-swap` note.
83
+ - `writeCapabilities` is `{ compareAndSwap: false }`. A write is `writeFile` and then `chmod`, so it is not atomic. `IFileSystem` has no version check, so the adapter checks the precondition with a fresh stat just before the write.
91
84
  - `InMemoryFs` resets the mode to `0o644` on every write, so a replace calls `chmod` with the old mode.
92
85
  - `InMemoryFs` keeps `mtime` when two writes fall in one millisecond. When a replace leaves `mtime` where it was, the adapter moves it on by one millisecond with `utimes`, so every write through the adapter changes the version.
93
86
  - `identity: "required"` makes the write tools trust the version, which is the identity, size, and `mtime`. Another writer that changes a file to the same size inside the same millisecond is then not seen. With the default, `identity: "none"`, the write tools also compare the content hash of what the model read.
@@ -19,7 +19,7 @@ export type JustBashBackend = Pick<IFileSystem, "lstat" | "realpath" | "stat" |
19
19
  export interface JustBashFileSystemOptions extends FileSystemRootOptions, BufferedFileSystemOptions {
20
20
  }
21
21
  /**
22
- * `writeCapabilities` is `{ atomic: false, compareAndSwap: false, preserveMode: true }`.
22
+ * `writeCapabilities` is `{ compareAndSwap: false }`.
23
23
  * The write methods need `writeFile`, `mkdir`, `chmod`, `utimes`, and `rm` on
24
24
  * the backend. They are checked when a write runs, so a backend without them
25
25
  * still serves reads.
package/dist/index.d.ts CHANGED
@@ -11,8 +11,8 @@ export type { JustBashBackend, JustBashFileSystem, JustBashFileSystemOptions } f
11
11
  * returned, not the backend's own directory read.
12
12
  *
13
13
  * `stat`, `write` and `remove` keep the same roots, deny roots and symlink
14
- * policy as `open()`. `writeCapabilities` is `{ atomic: false,
15
- * compareAndSwap: false, preserveMode: true }`. There is no `stage()`. For a
14
+ * policy as `open()`. `writeCapabilities` is `{ compareAndSwap: false }`.
15
+ * There is no `stage()`. For a
16
16
  * read-only view, wrap the result in `readOnlyFileSystem()` from
17
17
  * `@better-fs-tools/fs`.
18
18
  */
package/dist/index.js CHANGED
@@ -11,8 +11,8 @@ export { justBashCommandRunner } from "./command-runner.js";
11
11
  * returned, not the backend's own directory read.
12
12
  *
13
13
  * `stat`, `write` and `remove` keep the same roots, deny roots and symlink
14
- * policy as `open()`. `writeCapabilities` is `{ atomic: false,
15
- * compareAndSwap: false, preserveMode: true }`. There is no `stage()`. For a
14
+ * policy as `open()`. `writeCapabilities` is `{ compareAndSwap: false }`.
15
+ * There is no `stage()`. For a
16
16
  * read-only view, wrap the result in `readOnlyFileSystem()` from
17
17
  * `@better-fs-tools/fs`.
18
18
  */
@@ -29,10 +29,7 @@ function readMethods(fs, configured) {
29
29
  const { id, cwd, allowedRoots, denyRoots, maxBufferedBytes, identity, symlinks } = configured;
30
30
  return {
31
31
  id,
32
- capabilities: Object.freeze({
33
- streaming: false,
34
- identity: identity === "required",
35
- }),
32
+ capabilities: Object.freeze({ identity: identity === "required" }),
36
33
  paths: posixPaths,
37
34
  cwd,
38
35
  allowedRoots,
package/dist/write.js CHANGED
@@ -1,9 +1,7 @@
1
1
  import { posixPaths } from "@better-fs-tools/fs";
2
2
  import { AdapterRefusal, authorizeCanonical, authorizeRequested, backendCall, canonicalPath, display, fingerprint, inspect, refuse, refuseSymlinkComponents, requireRegularFile, requireStatKey, toFileSystemError, } from "./policy.js";
3
3
  export const JUST_BASH_WRITE_CAPABILITIES = Object.freeze({
4
- atomic: false,
5
4
  compareAndSwap: false,
6
- preserveMode: true,
7
5
  });
8
6
  export function justBashWrites(fs, settings) {
9
7
  const { id, cwd, allowedRoots, denyRoots, maxBufferedBytes, identity, symlinks } = settings;
@@ -102,7 +100,6 @@ export function justBashWrites(fs, settings) {
102
100
  identity: after?.exists === true && identity === "required" ? after.version : null,
103
101
  size: after?.exists === true ? after.stat.size : null,
104
102
  createdDirectories: created,
105
- atomic: JUST_BASH_WRITE_CAPABILITIES.atomic,
106
103
  });
107
104
  return {
108
105
  async stat(requested, options = {}) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@better-fs-tools/just-bash",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "A readable and writable filesystem and a bash command runner over just-bash.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -29,12 +29,12 @@
29
29
  "access": "public"
30
30
  },
31
31
  "dependencies": {
32
- "@better-fs-tools/fs": "^0.1.0",
33
- "@better-fs-tools/shell": "^0.1.0"
32
+ "@better-fs-tools/fs": "^0.2.0",
33
+ "@better-fs-tools/shell": "^0.2.0"
34
34
  },
35
35
  "devDependencies": {
36
- "@better-fs-tools/read": "^0.1.0",
37
- "@better-fs-tools/write": "^0.1.0",
36
+ "@better-fs-tools/read": "^0.2.0",
37
+ "@better-fs-tools/write": "^0.2.0",
38
38
  "just-bash": "3.4.2"
39
39
  },
40
40
  "peerDependencies": {