dollar-shell 1.1.12 → 1.1.14

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/AGENTS.md CHANGED
@@ -19,7 +19,8 @@ The wiki is a git submodule in `wiki/`.
19
19
  - **Test (Node):** `npm test` (runs `tape6 --flags FO`)
20
20
  - **Test (Bun):** `npm run test:bun`
21
21
  - **Test (Deno):** `npm run test:deno`
22
- - **TypeScript check:** `npm run ts-check` (`tsc --noEmit`)
22
+ - **TypeScript check:** `npm run ts-check` (`tsc --noEmit`, validates the `.d.ts` sidecars)
23
+ - **JavaScript check:** `npm run js-check` (`tsc --project tsconfig.check.json`, lints the `.js` sources for unused vars / undeclared refs)
23
24
  - **TypeScript tests:** `npm run ts-test` (run `.ts` test files with tape6)
24
25
  - **Lint:** `npm run lint` (Prettier check)
25
26
  - **Lint fix:** `npm run lint:fix` (Prettier write)
@@ -28,9 +29,10 @@ The wiki is a git submodule in `wiki/`.
28
29
 
29
30
  ```
30
31
  dollar-shell/
31
- ├── package.json # Package config
32
- ├── tsconfig.json # TypeScript config (noEmit check only)
33
- ├── src/ # Source code
32
+ ├── package.json # Package config
33
+ ├── tsconfig.json # Strict TS config checks the .d.ts sidecars
34
+ ├── tsconfig.check.json # Lint config — checkJs on .js sources, with @types/{node,bun,deno} for cross-runtime globals
35
+ ├── src/ # Source code
34
36
  │ ├── index.js # Main entry point, wires everything together
35
37
  │ ├── index.d.ts # TypeScript declarations for the full public API
36
38
  │ ├── bq-spawn.js # Template tag factory for spawn-based functions ($, $$)
@@ -90,8 +92,8 @@ await $verbose`ls -l .`;
90
92
 
91
93
  ## Key conventions
92
94
 
93
- - Do not add dependencies — the library is intentionally zero-dependency.
95
+ - Do not add runtime dependencies — the library is intentionally zero-dependency. DevDeps for tooling (`@types/node`, `@types/bun`, `@types/deno`, `prettier`, `tape-six`, `typescript`) are fine.
94
96
  - All public API is exported from `src/index.js` and typed in `src/index.d.ts`. Keep them in sync.
95
- - Wiki documentation lives in the `wiki/` submodule — update it alongside code changes.
97
+ - Wiki documentation lives in the `wiki/` submodule — update it alongside code changes. Cross-runtime behavior asymmetries (e.g. BYOB readers — only Deno supports them) are documented at `wiki/Cross-runtime-notes.md`.
96
98
  - Tests are in `tests/` (automated, tape-six) and `tests/manual/` (manual verification scripts).
97
99
  - TypeScript typing tests (`.ts`) are in `tests/` and checked by `npm run ts-check`. They can also be run as tests via `npm run ts-test`.
package/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2005-2024 Eugene Lazutkin
1
+ Copyright 2005-2026 Eugene Lazutkin
2
2
 
3
3
  Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
4
4
 
package/README.md CHANGED
@@ -237,6 +237,8 @@ BSD-3-Clause
237
237
 
238
238
  ## Release History
239
239
 
240
+ - 1.1.14 _Fixed Bun stdin abort path, added js-check, Bun + Deno wired into CI._
241
+ - 1.1.13 _Updated dev dependencies._
240
242
  - 1.1.12 _Consolidated TypeScript tests into `tests/`, removed `ts-check/`, added CJS test, improved test coverage and documentation._
241
243
  - 1.1.11 _Updated dev dependencies._
242
244
  - 1.1.10 _Fixed a bug with options chaining for attached functions, fixed Bun spawn on invalid commands, Windows-compatible tests, updated dev dependencies._
@@ -256,3 +258,5 @@ BSD-3-Clause
256
258
  - 1.0.2 _Technical release: fixed references in the package file._
257
259
  - 1.0.1 _Technical release: more tests, better documentation._
258
260
  - 1.0.0 _The initial release._
261
+
262
+ The full release notes are in the wiki: [Release notes](https://github.com/uhop/dollar-shell/wiki/Release-notes).
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dollar-shell",
3
- "description": "Run shell commands and use them in stream pipelines with ease in Node, Deno, Bun. Template tag API, web streams, TypeScript typings, zero dependencies.",
4
- "version": "1.1.12",
3
+ "description": "Run OS and shell commands using template tag functions. Same API in Node, Deno, and Bun. Web streams, TypeScript typings, zero dependencies.",
4
+ "version": "1.1.14",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
7
7
  "types": "./src/index.d.ts",
@@ -20,6 +20,7 @@
20
20
  "test:seq:bun": "bun run `tape6-seq --self` --flags FO",
21
21
  "test:seq:deno": "deno run -A `tape6-seq --self` --flags FO",
22
22
  "ts-check": "tsc --noEmit",
23
+ "js-check": "tsc --project tsconfig.check.json",
23
24
  "ts-test": "tape6 --flags FO 'tests/test-*.*ts'",
24
25
  "ts-test:bun": "tape6-bun --flags FO 'tests/test-*.*ts'",
25
26
  "ts-test:deno": "tape6-deno --flags FO 'tests/test-*.*ts'",
@@ -49,7 +50,7 @@
49
50
  "keywords": [
50
51
  "shell",
51
52
  "spawn",
52
- "$",
53
+ "subprocess",
53
54
  "dollar",
54
55
  "stream",
55
56
  "process",
@@ -60,7 +61,6 @@
60
61
  "pipeline",
61
62
  "typescript",
62
63
  "esm",
63
- "es-modules",
64
64
  "cross-runtime",
65
65
  "zero-dependency",
66
66
  "nodejs",
@@ -74,9 +74,12 @@
74
74
  },
75
75
  "license": "BSD-3-Clause",
76
76
  "devDependencies": {
77
- "prettier": "^3.8.1",
78
- "tape-six": "^1.7.11",
79
- "typescript": "^5.9.3"
77
+ "@types/bun": "^1.3.13",
78
+ "@types/deno": "^2.5.0",
79
+ "@types/node": "^25.6.0",
80
+ "prettier": "^3.8.3",
81
+ "tape-six": "^1.9.0",
82
+ "typescript": "^6.0.3"
80
83
  },
81
84
  "tape6": {
82
85
  "tests": [
package/src/index.js CHANGED
@@ -51,9 +51,10 @@ const throughProcess = bqSpawn((command, options) => {
51
51
  return sp.asDuplex;
52
52
  });
53
53
 
54
- $.from = fromProcess;
55
- $.to = toProcess;
56
- $.through = $.io = throughProcess;
54
+ const $any = /** @type {any} */ ($);
55
+ $any.from = fromProcess;
56
+ $any.to = toProcess;
57
+ $any.through = $any.io = throughProcess;
57
58
 
58
59
  // define shell functions
59
60
 
@@ -101,8 +102,9 @@ const throughShell = bqShell(shellEscape, (command, options) => {
101
102
  return sp.asDuplex;
102
103
  });
103
104
 
104
- $sh.from = fromShell;
105
- $sh.to = toShell;
106
- $sh.through = $sh.io = throughShell;
105
+ const $shAny = /** @type {any} */ ($sh);
106
+ $shAny.from = fromShell;
107
+ $shAny.to = toShell;
108
+ $shAny.through = $shAny.io = throughShell;
107
109
 
108
110
  export default $;
package/src/spawn/bun.js CHANGED
@@ -1,3 +1,24 @@
1
+ /**
2
+ * Adapt Bun's `FileSink` to a Web Streams `UnderlyingSink`. `FileSink` exposes
3
+ * `write`/`end` (close + flush) but no `close`/`abort` matching the spec, so
4
+ * `new WritableStream(fileSink)` would only work because of an undocumented
5
+ * runtime `.close` alias. This adapter sticks to the documented `.end` API.
6
+ *
7
+ * @param {import('bun').FileSink} sink
8
+ * @returns {UnderlyingSink}
9
+ */
10
+ const makeStdinSink = sink => ({
11
+ async write(/** @type {any} */ chunk) {
12
+ await sink.write(chunk);
13
+ },
14
+ async close() {
15
+ await sink.end();
16
+ },
17
+ async abort(reason) {
18
+ await sink.end(reason instanceof Error ? reason : new Error(String(reason)));
19
+ }
20
+ });
21
+
1
22
  const sanitize = (value, defaultValue = 'ignore') => {
2
23
  switch (value) {
3
24
  case 'pipe':
@@ -47,7 +68,11 @@ class Subprocess {
47
68
  return code;
48
69
  });
49
70
 
50
- this.stdin = this.childProcess.stdin ? new WritableStream(this.childProcess.stdin) : null;
71
+ const stdinSink = this.childProcess.stdin;
72
+ this.stdin =
73
+ stdinSink && typeof stdinSink !== 'number'
74
+ ? new WritableStream(makeStdinSink(stdinSink))
75
+ : null;
51
76
  this.stdout = this.childProcess.stdout || null;
52
77
  this.stderr = this.childProcess.stderr || null;
53
78
  }
package/src/spawn/node.js CHANGED
@@ -27,6 +27,7 @@ class Subprocess {
27
27
  this.killed = false;
28
28
  this.finished = false;
29
29
 
30
+ /** @type {import('node:child_process').SpawnOptions} */
30
31
  const spawnOptions = {stdio: ['ignore', 'ignore', 'ignore']};
31
32
  if (options.windowsVerbatimArguments) spawnOptions.windowsVerbatimArguments = true;
32
33
  options.cwd && (spawnOptions.cwd = options.cwd);
package/src/utils.js CHANGED
@@ -14,7 +14,8 @@ if (typeof Deno !== 'undefined') {
14
14
  }
15
15
  export {getEnv, isWindows, isAndroid};
16
16
 
17
- export const verifyStrings = strings => Array.isArray(strings) && Array.isArray(strings.raw);
17
+ export const verifyStrings = strings =>
18
+ Array.isArray(strings) && Array.isArray(/** @type {any} */ (strings).raw);
18
19
 
19
20
  export const toBase64 = s => {
20
21
  // const buf = new TextEncoder().encode(s),