Commit cca4238

Anton Golub <antongolub@antongolub.com>
2024-06-19 22:48:29
refactor: simplify setup checks (#852)
* refactor: simplify setup checks * style: make type imports explicit * chore: update no-shell err message
1 parent 7b3046b
Changed files (3)
src/core.ts
@@ -13,10 +13,15 @@
 // limitations under the License.
 
 import assert from 'node:assert'
-import { spawn, spawnSync, StdioOptions, IOType } from 'node:child_process'
+import {
+  type StdioOptions,
+  type IOType,
+  spawn,
+  spawnSync,
+} from 'node:child_process'
 import { type Encoding } from 'node:crypto'
-import { AsyncHook, AsyncLocalStorage, createHook } from 'node:async_hooks'
-import { Readable, Writable } from 'node:stream'
+import { type AsyncHook, AsyncLocalStorage, createHook } from 'node:async_hooks'
+import { type Readable, type Writable } from 'node:stream'
 import { inspect } from 'node:util'
 import { EOL } from 'node:os'
 import {
@@ -31,7 +36,7 @@ import {
   type TSpawnStore,
 } from './vendor.js'
 import {
-  Duration,
+  type Duration,
   errnoMessage,
   exitCodeInfo,
   formatCmd,
@@ -40,7 +45,6 @@ import {
   parseDuration,
   quote,
   quotePowerShell,
-  noquote,
   preferNmBin,
 } from './util.js'
 
@@ -74,7 +78,7 @@ export interface Options {
   nothrow: boolean
   prefix: string
   postfix: string
-  quote: typeof quote
+  quote?: typeof quote
   quiet: boolean
   detached: boolean
   preferLocal: boolean
@@ -114,7 +118,6 @@ export const defaults: Options = {
   quiet: false,
   prefix: '',
   postfix: '',
-  quote: noquote,
   detached: false,
   preferLocal: false,
   spawn,
@@ -145,9 +148,13 @@ export function useBash() {
 }
 
 function checkShell() {
-  if (!$.shell) {
-    throw new Error(`shell is not available: setup guide goes here`)
-  }
+  if (!$.shell)
+    throw new Error(`No shell is available: https://ï.at/zx-no-shell`)
+}
+
+function checkQuote() {
+  if (!$.quote)
+    throw new Error('No quote function is defined: https://ï.at/no-quote-func')
 }
 
 function getStore() {
@@ -156,8 +163,6 @@ function getStore() {
 
 export const $: Shell & Options = new Proxy<Shell & Options>(
   function (pieces, ...args) {
-    checkShell()
-
     if (!Array.isArray(pieces)) {
       return function (this: any, ...args: any) {
         const self = this
@@ -170,10 +175,13 @@ export const $: Shell & Options = new Proxy<Shell & Options>(
     if (pieces.some((p) => p == undefined)) {
       throw new Error(`Malformed command at ${from}`)
     }
+    checkShell()
+    checkQuote()
+
     let resolve: Resolve, reject: Resolve
     const promise = new ProcessPromise((...args) => ([resolve, reject] = args))
     const cmd = buildCmd(
-      $.quote,
+      $.quote as typeof quote,
       pieces as TemplateStringsArray,
       args
     ) as string
src/goods.ts
@@ -20,8 +20,8 @@ import {
   chalk,
   minimist,
   nodeFetch,
-  RequestInfo,
-  RequestInit,
+  type RequestInfo,
+  type RequestInit,
 } from './vendor.js'
 
 export { default as path } from 'node:path'
src/util.ts
@@ -85,10 +85,6 @@ export function normalizeMultilinePieces(
   )
 }
 
-export function noquote(): string {
-  throw new Error('No quote function is defined: https://ï.at/no-quote-func')
-}
-
 export function quote(arg: string) {
   if (/^[a-z0-9/_.\-@:=]+$/i.test(arg) || arg === '') {
     return arg