Commit a305771

Anton Golub <antongolub@antongolub.com>
2025-06-22 10:50:52
feat(core): enable thenable params processing for `$` literals
1 parent d7d64ff
build/cli.js
build/core.cjs
@@ -525,12 +525,6 @@ var _ProcessPromise = class _ProcessPromise extends Promise {
       const dirs = $2.preferLocal === true ? [$2.cwd, $2[CWD]] : [$2.preferLocal].flat();
       $2.env = (0, import_util.preferLocalBin)($2.env, ...dirs);
     }
-    $2.log({
-      kind: "cmd",
-      cmd: self.cmd,
-      verbose: self.isVerbose(),
-      id
-    });
     this._zurk = (0, import_vendor_core2.exec)({
       sync,
       id,
@@ -548,9 +542,27 @@ var _ProcessPromise = class _ProcessPromise extends Promise {
       stdio: (_g = self._stdio) != null ? _g : $2.stdio,
       detached: $2.detached,
       ee: self._ee,
-      run: (cb) => cb(),
+      run(cb, ctx) {
+        var _a2, _b2;
+        ((_b2 = (_a2 = self.cmd).then) == null ? void 0 : _b2.call(_a2, (_cmd) => {
+          self._command = _cmd;
+          ctx.cmd = self.fullCmd;
+          cb();
+        }, (err) => {
+          ctx.spawn = () => {
+            throw err;
+          };
+          cb();
+        })) || cb();
+      },
       on: {
         start: () => {
+          $2.log({
+            kind: "cmd",
+            cmd: self.cmd,
+            verbose: self.isVerbose(),
+            id
+          });
           !sync && timeout && self.timeout(timeout, timeoutSignal);
         },
         stdout: (data) => {
src/core.ts
@@ -170,7 +170,7 @@ const boundCtxs: [string, string, Options][] = []
 const delimiters: Array<string | RegExp | undefined> = []
 
 export const $: Shell & Options = new Proxy<Shell & Options>(
-  function (pieces: TemplateStringsArray | Partial<Options>, ...args: any) {
+  function (pieces: TemplateStringsArray | Partial<Options>, ...args: any[]) {
     const snapshot = getStore()
     if (!Array.isArray(pieces)) {
       return function (this: any, ...args: any) {
@@ -292,13 +292,6 @@ export class ProcessPromise extends Promise<ProcessOutput> {
       $.env = preferLocalBin($.env, ...dirs)
     }
 
-    $.log({
-      kind: 'cmd',
-      cmd: self.cmd,
-      verbose: self.isVerbose(),
-      id,
-    })
-
     // prettier-ignore
     this._zurk = exec({
       sync,
@@ -317,9 +310,25 @@ export class ProcessPromise extends Promise<ProcessOutput> {
       stdio:    self._stdio ?? $.stdio,
       detached: $.detached,
       ee:       self._ee,
-      run: (cb) => cb(),
+      run(cb, ctx){
+        (self.cmd as unknown as Promise<string>).then?.(_cmd => {
+          self._command = _cmd
+          ctx.cmd = self.fullCmd
+          cb()
+        }, err => {
+          ctx.spawn = () => { throw err }
+          cb()
+        }) || cb()
+      },
       on: {
         start: () => {
+          $.log({
+            kind: 'cmd',
+            cmd: self.cmd,
+            verbose: self.isVerbose(),
+            id,
+          })
+
           !sync && timeout && self.timeout(timeout, timeoutSignal)
         },
         stdout: (data) => {
test/core.test.js
@@ -113,6 +113,19 @@ describe('core', () => {
       assert.equal((await $`echo -n ${''}`).toString(), '')
     })
 
+    test('accepts thenable arguments', async () => {
+      const p1 = $`echo foo`
+      const arg = new Promise((resolve) => {
+        setTimeout(() => resolve(['thenable', 'args']), 20)
+      })
+      const p2 = $`echo ${arg} ${p1}`
+      assert(p2.cmd instanceof Promise)
+
+      const o = await p2
+      assert.equal(o.stdout.trim(), 'thenable args foo')
+      assert.equal(p2.cmd, 'echo thenable args foo')
+    })
+
     test.skip('handles multiline literals', async () => {
       assert.equal(
         (
.size-limit.json
@@ -15,7 +15,7 @@
       "README.md",
       "LICENSE"
     ],
-    "limit": "120.80 kB",
+    "limit": "121.15 kB",
     "brotli": false,
     "gzip": false
   },
@@ -29,7 +29,7 @@
       "build/globals.js",
       "build/deno.js"
     ],
-    "limit": "811.80 kB",
+    "limit": "812.20 kB",
     "brotli": false,
     "gzip": false
   },
@@ -62,7 +62,7 @@
       "README.md",
       "LICENSE"
     ],
-    "limit": "867.25 kB",
+    "limit": "867.70 kB",
     "brotli": false,
     "gzip": false
   }