Commit ae4fb3c

Anton Golub <antongolub@antongolub.com>
2024-09-13 19:02:53
chore: bump version 8.1.7 (#890)
* chore: bump version to 8.1.7 * chore: update tsx to 4.19.1 * chore: tweak up import-meta-url snippet * chore: reuse const maps
1 parent ac2567f
scripts/import-meta-url.polyfill.js
@@ -1,5 +1,5 @@
 const import_meta_url =
   typeof document === 'undefined'
-    ? new (require('url'.replace('', '')).URL)('file:' + __filename).href
+    ? new (require('url').URL)('file:' + __filename).href
     : (document.currentScript && document.currentScript.src) ||
       new URL('main.js', document.baseURI).href
src/core.ts
@@ -58,13 +58,13 @@ export interface Shell {
   }
 }
 
-const processCwd = Symbol('processCwd')
-const syncExec = Symbol('syncExec')
+const CWD = Symbol('processCwd')
+const SYNC = Symbol('syncExec')
 const eol = Buffer.from(EOL)
 
 export interface Options {
-  [processCwd]: string
-  [syncExec]: boolean
+  [CWD]: string
+  [SYNC]: boolean
   cwd?: string
   ac?: AbortController
   signal?: AbortSignal
@@ -109,8 +109,8 @@ export function syncProcessCwd(flag: boolean = true) {
 }
 
 export const defaults: Options = {
-  [processCwd]: process.cwd(),
-  [syncExec]: false,
+  [CWD]: process.cwd(),
+  [SYNC]: false,
   verbose: false,
   env: process.env,
   sync: false,
@@ -190,7 +190,7 @@ export const $: Shell & Options = new Proxy<Shell & Options>(
       pieces as TemplateStringsArray,
       args
     ) as string
-    const sync = snapshot[syncExec]
+    const sync = snapshot[SYNC]
     const callback = () => promise.isHalted() || promise.run()
 
     promise._bind(
@@ -211,7 +211,7 @@ export const $: Shell & Options = new Proxy<Shell & Options>(
   {
     set(_, key, value) {
       const target = key in Function.prototype ? _ : getStore()
-      Reflect.set(target, key === 'sync' ? syncExec : key, value)
+      Reflect.set(target, key === 'sync' ? SYNC : key, value)
 
       return true
     },
@@ -275,7 +275,7 @@ export class ProcessPromise extends Promise<ProcessOutput> {
     if ($.timeout) this.timeout($.timeout, $.timeoutSignal)
     if ($.preferLocal) {
       const dirs =
-        $.preferLocal === true ? [$.cwd, $[processCwd]] : [$.preferLocal].flat()
+        $.preferLocal === true ? [$.cwd, $[CWD]] : [$.preferLocal].flat()
       $.env = preferLocalBin($.env, ...dirs)
     }
 
@@ -288,7 +288,7 @@ export class ProcessPromise extends Promise<ProcessOutput> {
     this._zurk = exec({
       input,
       cmd: $.prefix + self._command + $.postfix,
-      cwd: $.cwd ?? $[processCwd],
+      cwd: $.cwd ?? $[CWD],
       ac: $.ac,
       signal: $.signal,
       shell: typeof $.shell === 'string' ? $.shell : true,
@@ -297,7 +297,7 @@ export class ProcessPromise extends Promise<ProcessOutput> {
       spawnSync: $.spawnSync,
       store: $.store,
       stdio: self._stdio ?? $.stdio,
-      sync: $[syncExec],
+      sync: $[SYNC],
       detached: $.detached,
       run: (cb) => cb(),
       on: {
@@ -680,7 +680,7 @@ export function within<R>(callback: () => R): R {
 }
 
 function syncCwd() {
-  if ($[processCwd] != process.cwd()) process.chdir($[processCwd])
+  if ($[CWD] != process.cwd()) process.chdir($[CWD])
 }
 
 export function cd(dir: string | ProcessOutput) {
@@ -690,7 +690,7 @@ export function cd(dir: string | ProcessOutput) {
 
   $.log({ kind: 'cd', dir })
   process.chdir(dir)
-  $[processCwd] = process.cwd()
+  $[CWD] = process.cwd()
 }
 
 export async function kill(pid: number, signal = $.killSignal) {
src/util.ts
@@ -119,176 +119,178 @@ export function quotePowerShell(arg: string) {
   return `'` + arg.replace(/'/g, "''") + `'`
 }
 
+const EXIT_CODES = {
+  2: 'Misuse of shell builtins',
+  126: 'Invoked command cannot execute',
+  127: 'Command not found',
+  128: 'Invalid exit argument',
+  129: 'Hangup',
+  130: 'Interrupt',
+  131: 'Quit and dump core',
+  132: 'Illegal instruction',
+  133: 'Trace/breakpoint trap',
+  134: 'Process aborted',
+  135: 'Bus error: "access to undefined portion of memory object"',
+  136: 'Floating point exception: "erroneous arithmetic operation"',
+  137: 'Kill (terminate immediately)',
+  138: 'User-defined 1',
+  139: 'Segmentation violation',
+  140: 'User-defined 2',
+  141: 'Write to pipe with no one reading',
+  142: 'Signal raised by alarm',
+  143: 'Termination (request to terminate)',
+  145: 'Child process terminated, stopped (or continued*)',
+  146: 'Continue if stopped',
+  147: 'Stop executing temporarily',
+  148: 'Terminal stop signal',
+  149: 'Background process attempting to read from tty ("in")',
+  150: 'Background process attempting to write to tty ("out")',
+  151: 'Urgent data available on socket',
+  152: 'CPU time limit exceeded',
+  153: 'File size limit exceeded',
+  154: 'Signal raised by timer counting virtual time: "virtual timer expired"',
+  155: 'Profiling timer expired',
+  157: 'Pollable event',
+  159: 'Bad syscall',
+}
+
 export function exitCodeInfo(exitCode: number | null): string | undefined {
-  return {
-    2: 'Misuse of shell builtins',
-    126: 'Invoked command cannot execute',
-    127: 'Command not found',
-    128: 'Invalid exit argument',
-    129: 'Hangup',
-    130: 'Interrupt',
-    131: 'Quit and dump core',
-    132: 'Illegal instruction',
-    133: 'Trace/breakpoint trap',
-    134: 'Process aborted',
-    135: 'Bus error: "access to undefined portion of memory object"',
-    136: 'Floating point exception: "erroneous arithmetic operation"',
-    137: 'Kill (terminate immediately)',
-    138: 'User-defined 1',
-    139: 'Segmentation violation',
-    140: 'User-defined 2',
-    141: 'Write to pipe with no one reading',
-    142: 'Signal raised by alarm',
-    143: 'Termination (request to terminate)',
-    145: 'Child process terminated, stopped (or continued*)',
-    146: 'Continue if stopped',
-    147: 'Stop executing temporarily',
-    148: 'Terminal stop signal',
-    149: 'Background process attempting to read from tty ("in")',
-    150: 'Background process attempting to write to tty ("out")',
-    151: 'Urgent data available on socket',
-    152: 'CPU time limit exceeded',
-    153: 'File size limit exceeded',
-    154: 'Signal raised by timer counting virtual time: "virtual timer expired"',
-    155: 'Profiling timer expired',
-    157: 'Pollable event',
-    159: 'Bad syscall',
-  }[exitCode || -1]
+  return EXIT_CODES[exitCode as keyof typeof EXIT_CODES]
 }
 
-export function errnoMessage(errno: number | undefined): string {
-  if (errno === undefined) {
-    return 'Unknown error'
-  }
+const ERRNO_CODES = {
+  0: 'Success',
+  1: 'Not super-user',
+  2: 'No such file or directory',
+  3: 'No such process',
+  4: 'Interrupted system call',
+  5: 'I/O error',
+  6: 'No such device or address',
+  7: 'Arg list too long',
+  8: 'Exec format error',
+  9: 'Bad file number',
+  10: 'No children',
+  11: 'No more processes',
+  12: 'Not enough core',
+  13: 'Permission denied',
+  14: 'Bad address',
+  15: 'Block device required',
+  16: 'Mount device busy',
+  17: 'File exists',
+  18: 'Cross-device link',
+  19: 'No such device',
+  20: 'Not a directory',
+  21: 'Is a directory',
+  22: 'Invalid argument',
+  23: 'Too many open files in system',
+  24: 'Too many open files',
+  25: 'Not a typewriter',
+  26: 'Text file busy',
+  27: 'File too large',
+  28: 'No space left on device',
+  29: 'Illegal seek',
+  30: 'Read only file system',
+  31: 'Too many links',
+  32: 'Broken pipe',
+  33: 'Math arg out of domain of func',
+  34: 'Math result not representable',
+  35: 'File locking deadlock error',
+  36: 'File or path name too long',
+  37: 'No record locks available',
+  38: 'Function not implemented',
+  39: 'Directory not empty',
+  40: 'Too many symbolic links',
+  42: 'No message of desired type',
+  43: 'Identifier removed',
+  44: 'Channel number out of range',
+  45: 'Level 2 not synchronized',
+  46: 'Level 3 halted',
+  47: 'Level 3 reset',
+  48: 'Link number out of range',
+  49: 'Protocol driver not attached',
+  50: 'No CSI structure available',
+  51: 'Level 2 halted',
+  52: 'Invalid exchange',
+  53: 'Invalid request descriptor',
+  54: 'Exchange full',
+  55: 'No anode',
+  56: 'Invalid request code',
+  57: 'Invalid slot',
+  59: 'Bad font file fmt',
+  60: 'Device not a stream',
+  61: 'No data (for no delay io)',
+  62: 'Timer expired',
+  63: 'Out of streams resources',
+  64: 'Machine is not on the network',
+  65: 'Package not installed',
+  66: 'The object is remote',
+  67: 'The link has been severed',
+  68: 'Advertise error',
+  69: 'Srmount error',
+  70: 'Communication error on send',
+  71: 'Protocol error',
+  72: 'Multihop attempted',
+  73: 'Cross mount point (not really error)',
+  74: 'Trying to read unreadable message',
+  75: 'Value too large for defined data type',
+  76: 'Given log. name not unique',
+  77: 'f.d. invalid for this operation',
+  78: 'Remote address changed',
+  79: 'Can   access a needed shared lib',
+  80: 'Accessing a corrupted shared lib',
+  81: '.lib section in a.out corrupted',
+  82: 'Attempting to link in too many libs',
+  83: 'Attempting to exec a shared library',
+  84: 'Illegal byte sequence',
+  86: 'Streams pipe error',
+  87: 'Too many users',
+  88: 'Socket operation on non-socket',
+  89: 'Destination address required',
+  90: 'Message too long',
+  91: 'Protocol wrong type for socket',
+  92: 'Protocol not available',
+  93: 'Unknown protocol',
+  94: 'Socket type not supported',
+  95: 'Not supported',
+  96: 'Protocol family not supported',
+  97: 'Address family not supported by protocol family',
+  98: 'Address already in use',
+  99: 'Address not available',
+  100: 'Network interface is not configured',
+  101: 'Network is unreachable',
+  102: 'Connection reset by network',
+  103: 'Connection aborted',
+  104: 'Connection reset by peer',
+  105: 'No buffer space available',
+  106: 'Socket is already connected',
+  107: 'Socket is not connected',
+  108: "Can't send after socket shutdown",
+  109: 'Too many references',
+  110: 'Connection timed out',
+  111: 'Connection refused',
+  112: 'Host is down',
+  113: 'Host is unreachable',
+  114: 'Socket already connected',
+  115: 'Connection already in progress',
+  116: 'Stale file handle',
+  122: 'Quota exceeded',
+  123: 'No medium (in tape drive)',
+  125: 'Operation canceled',
+  130: 'Previous owner died',
+  131: 'State not recoverable',
+}
+
+export function errnoMessage(errno?: number): string {
   return (
-    {
-      0: 'Success',
-      1: 'Not super-user',
-      2: 'No such file or directory',
-      3: 'No such process',
-      4: 'Interrupted system call',
-      5: 'I/O error',
-      6: 'No such device or address',
-      7: 'Arg list too long',
-      8: 'Exec format error',
-      9: 'Bad file number',
-      10: 'No children',
-      11: 'No more processes',
-      12: 'Not enough core',
-      13: 'Permission denied',
-      14: 'Bad address',
-      15: 'Block device required',
-      16: 'Mount device busy',
-      17: 'File exists',
-      18: 'Cross-device link',
-      19: 'No such device',
-      20: 'Not a directory',
-      21: 'Is a directory',
-      22: 'Invalid argument',
-      23: 'Too many open files in system',
-      24: 'Too many open files',
-      25: 'Not a typewriter',
-      26: 'Text file busy',
-      27: 'File too large',
-      28: 'No space left on device',
-      29: 'Illegal seek',
-      30: 'Read only file system',
-      31: 'Too many links',
-      32: 'Broken pipe',
-      33: 'Math arg out of domain of func',
-      34: 'Math result not representable',
-      35: 'File locking deadlock error',
-      36: 'File or path name too long',
-      37: 'No record locks available',
-      38: 'Function not implemented',
-      39: 'Directory not empty',
-      40: 'Too many symbolic links',
-      42: 'No message of desired type',
-      43: 'Identifier removed',
-      44: 'Channel number out of range',
-      45: 'Level 2 not synchronized',
-      46: 'Level 3 halted',
-      47: 'Level 3 reset',
-      48: 'Link number out of range',
-      49: 'Protocol driver not attached',
-      50: 'No CSI structure available',
-      51: 'Level 2 halted',
-      52: 'Invalid exchange',
-      53: 'Invalid request descriptor',
-      54: 'Exchange full',
-      55: 'No anode',
-      56: 'Invalid request code',
-      57: 'Invalid slot',
-      59: 'Bad font file fmt',
-      60: 'Device not a stream',
-      61: 'No data (for no delay io)',
-      62: 'Timer expired',
-      63: 'Out of streams resources',
-      64: 'Machine is not on the network',
-      65: 'Package not installed',
-      66: 'The object is remote',
-      67: 'The link has been severed',
-      68: 'Advertise error',
-      69: 'Srmount error',
-      70: 'Communication error on send',
-      71: 'Protocol error',
-      72: 'Multihop attempted',
-      73: 'Cross mount point (not really error)',
-      74: 'Trying to read unreadable message',
-      75: 'Value too large for defined data type',
-      76: 'Given log. name not unique',
-      77: 'f.d. invalid for this operation',
-      78: 'Remote address changed',
-      79: 'Can   access a needed shared lib',
-      80: 'Accessing a corrupted shared lib',
-      81: '.lib section in a.out corrupted',
-      82: 'Attempting to link in too many libs',
-      83: 'Attempting to exec a shared library',
-      84: 'Illegal byte sequence',
-      86: 'Streams pipe error',
-      87: 'Too many users',
-      88: 'Socket operation on non-socket',
-      89: 'Destination address required',
-      90: 'Message too long',
-      91: 'Protocol wrong type for socket',
-      92: 'Protocol not available',
-      93: 'Unknown protocol',
-      94: 'Socket type not supported',
-      95: 'Not supported',
-      96: 'Protocol family not supported',
-      97: 'Address family not supported by protocol family',
-      98: 'Address already in use',
-      99: 'Address not available',
-      100: 'Network interface is not configured',
-      101: 'Network is unreachable',
-      102: 'Connection reset by network',
-      103: 'Connection aborted',
-      104: 'Connection reset by peer',
-      105: 'No buffer space available',
-      106: 'Socket is already connected',
-      107: 'Socket is not connected',
-      108: "Can't send after socket shutdown",
-      109: 'Too many references',
-      110: 'Connection timed out',
-      111: 'Connection refused',
-      112: 'Host is down',
-      113: 'Host is unreachable',
-      114: 'Socket already connected',
-      115: 'Connection already in progress',
-      116: 'Stale file handle',
-      122: 'Quota exceeded',
-      123: 'No medium (in tape drive)',
-      125: 'Operation canceled',
-      130: 'Previous owner died',
-      131: 'State not recoverable',
-    }[-errno] || 'Unknown error'
+    ERRNO_CODES[-(errno as number) as keyof typeof ERRNO_CODES] ||
+    'Unknown error'
   )
 }
 
 export type Duration = number | `${number}m` | `${number}s` | `${number}ms`
 
 export function parseDuration(d: Duration) {
-  if (typeof d == 'number') {
+  if (typeof d === 'number') {
     if (isNaN(d) || d < 0) throw new Error(`Invalid duration: "${d}".`)
     return d
   }
@@ -315,18 +317,18 @@ export function formatCmd(cmd?: string): string {
       buf = ''
       continue
     }
-    const next: State = ch == 'EOF' ? undefined : state()
-    if (next != state) {
+    const next: State = ch === 'EOF' ? undefined : state()
+    if (next !== state) {
       out += style(state, buf)
       buf = ''
     }
-    state = next == root ? next() : next
+    state = next === root ? next() : next
     buf += ch
   }
 
   function style(state: State, s: string): string {
-    if (s == '') return ''
-    if (reservedWords.includes(s)) {
+    if (s === '') return ''
+    if (RESERVED_WORDS.has(s)) {
       return chalk.cyanBright(s)
     }
     if (state == word && wordCount == 0) {
@@ -406,7 +408,7 @@ export function formatCmd(cmd?: string): string {
   return out + '\n'
 }
 
-const reservedWords = [
+const RESERVED_WORDS = new Set([
   'if',
   'then',
   'else',
@@ -421,7 +423,7 @@ const reservedWords = [
   'do',
   'done',
   'in',
-]
+])
 
 export function getCallerLocation(err = new Error()) {
   return getCallerLocationFromString(err.stack)
package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "zx",
-  "version": "8.1.6",
+  "version": "8.1.7",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "zx",
-      "version": "8.1.6",
+      "version": "8.1.7",
       "license": "Apache-2.0",
       "bin": {
         "zx": "build/cli.js"
@@ -42,7 +42,7 @@
         "size-limit": "^11.1.5",
         "ts-node": "^10.9.2",
         "tsd": "^0.31.2",
-        "tsx": "^4.19.0",
+        "tsx": "^4.19.1",
         "typescript": "^5.6.2",
         "which": "^4.0.0",
         "yaml": "^2.5.1",
@@ -5209,9 +5209,9 @@
       "license": "0BSD"
     },
     "node_modules/tsx": {
-      "version": "4.19.0",
-      "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.0.tgz",
-      "integrity": "sha512-bV30kM7bsLZKZIOCHeMNVMJ32/LuJzLVajkQI/qf92J2Qr08ueLQvW00PUZGiuLPP760UINwupgUj8qrSCPUKg==",
+      "version": "4.19.1",
+      "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.1.tgz",
+      "integrity": "sha512-0flMz1lh74BR4wOvBjuh9olbnwqCPc35OOlfyzHba0Dc+QNUeWX/Gq2YTbnwcWPO3BMd8fkzRVrHcsR+a7z7rA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
package.json
@@ -1,6 +1,6 @@
 {
   "name": "zx",
-  "version": "8.1.6",
+  "version": "8.1.7",
   "description": "A tool for writing better scripts",
   "type": "module",
   "main": "./build/index.cjs",
@@ -121,7 +121,7 @@
     "size-limit": "^11.1.5",
     "ts-node": "^10.9.2",
     "tsd": "^0.31.2",
-    "tsx": "^4.19.0",
+    "tsx": "^4.19.1",
     "typescript": "^5.6.2",
     "which": "^4.0.0",
     "yaml": "^2.5.1",