goke 6.10.0 → 6.12.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.
@@ -54,7 +54,7 @@ function gokeTestable(name = '', options?: Partial<GokeOptions>) {
54
54
  }
55
55
 
56
56
  describe('injected execution context', () => {
57
- test('command action receives injected console and process', () => {
57
+ test('command action receives injected console and process', async () => {
58
58
  const stdout = createTestOutputStream()
59
59
  const cli = gokeTestable('mycli', { stdout })
60
60
  let seenArgv: string[] | undefined
@@ -66,13 +66,13 @@ describe('injected execution context', () => {
66
66
  seenArgv = process.argv
67
67
  })
68
68
 
69
- cli.parse(['node', 'bin', 'status'], { run: true })
69
+ await cli.parse(['node', 'bin', 'status'], { run: true })
70
70
 
71
71
  expect(stdout.text).toBe('ready\n')
72
72
  expect(seenArgv).toEqual(['node', 'bin', 'status'])
73
73
  })
74
74
 
75
- test('middleware receives injected console and process', () => {
75
+ test('middleware receives injected console and process', async () => {
76
76
  const stdout = createTestOutputStream()
77
77
  const cli = gokeTestable('mycli', { stdout })
78
78
  let seenArgv: string[] | undefined
@@ -85,7 +85,7 @@ describe('injected execution context', () => {
85
85
  .command('build', 'Build')
86
86
  .action(() => {})
87
87
 
88
- cli.parse(['node', 'bin', 'build'], { run: true })
88
+ await cli.parse(['node', 'bin', 'build'], { run: true })
89
89
 
90
90
  expect(stdout.text).toBe('middleware\n')
91
91
  expect(seenArgv).toEqual(['node', 'bin', 'build'])
@@ -93,14 +93,14 @@ describe('injected execution context', () => {
93
93
  })
94
94
 
95
95
  describe('clone', () => {
96
- test('clone creates isolated parse state', () => {
96
+ test('clone creates isolated parse state', async () => {
97
97
  const cli = gokeTestable('mycli')
98
98
 
99
99
  cli.command('build', 'Build').action(() => {})
100
100
 
101
101
  const cloned = cli.clone({ exit: () => {} })
102
102
 
103
- cloned.parse(['node', 'bin', 'build'], { run: false })
103
+ await cloned.parse(['node', 'bin', 'build'], { run: false })
104
104
 
105
105
  expect(cloned).not.toBe(cli)
106
106
  expect(cloned.matchedCommandName).toBe('build')
@@ -109,7 +109,7 @@ describe('clone', () => {
109
109
  })
110
110
 
111
111
  describe('createExecutionContext', () => {
112
- test('returns a context that mirrors the cli defaults when called with no override', () => {
112
+ test('returns a context that mirrors the cli defaults when called with no override', async () => {
113
113
  const stdout = createTestOutputStream()
114
114
  const stderr = createTestOutputStream()
115
115
  const cli = gokeTestable('mycli', {
@@ -52,7 +52,7 @@ describe('README smoke tests', () => {
52
52
  console.log(`logs ${deploymentId} ${options.lines}`)
53
53
  })
54
54
 
55
- cli.parse(['node', 'bin', '--env', 'production', 'up', '--dry-run'], { run: false })
55
+ await cli.parse(['node', 'bin', '--env', 'production', 'up', '--dry-run'], { run: false })
56
56
  await cli.runMatchedCommand()
57
57
 
58
58
  expect(stdout.text).toBe(
@@ -61,7 +61,7 @@ describe('README smoke tests', () => {
61
61
 
62
62
  stdout.lines.length = 0
63
63
 
64
- cli.parse(['node', 'bin', 'logs', 'dep_123'], { run: false })
64
+ await cli.parse(['node', 'bin', 'logs', 'dep_123'], { run: false })
65
65
  await cli.runMatchedCommand()
66
66
 
67
67
  expect(stdout.text).toBe('Environment: staging\nlogs dep_123 100\n')
@@ -96,7 +96,7 @@ describe('README smoke tests', () => {
96
96
 
97
97
  expect(stripAnsi(cli.helpText())).toContain('mycli lint src/**/*.ts')
98
98
 
99
- cli.parse(['node', 'bin', '--type', 'bun', '--name', 'Tommy', 'build', 'src/index.ts', '--minify'], { run: false })
99
+ await cli.parse(['node', 'bin', '--type', 'bun', '--name', 'Tommy', 'build', 'src/index.ts', '--minify'], { run: false })
100
100
  await cli.runMatchedCommand()
101
101
 
102
102
  expect(stdout.text).toBe(
@@ -135,7 +135,7 @@ describe('README smoke tests', () => {
135
135
  )
136
136
  })
137
137
 
138
- cli.parse(['node', 'bin', '--env', 'staging', '--dry-run'], { run: false })
138
+ await cli.parse(['node', 'bin', '--env', 'staging', '--dry-run'], { run: false })
139
139
  await cli.runMatchedCommand()
140
140
 
141
141
  expect(stdout.text).toBe(
@@ -144,7 +144,7 @@ describe('README smoke tests', () => {
144
144
 
145
145
  stdout.lines.length = 0
146
146
 
147
- cli.parse(['node', 'bin', 'logs', 'abc123', '--follow'], { run: false })
147
+ await cli.parse(['node', 'bin', 'logs', 'abc123', '--follow'], { run: false })
148
148
  await cli.runMatchedCommand()
149
149
 
150
150
  expect(stdout.text).toBe(
@@ -154,7 +154,7 @@ describe('README smoke tests', () => {
154
154
  })
155
155
 
156
156
  describe('documented command APIs', () => {
157
- test('alias runs the same command through a short name', () => {
157
+ test('alias runs the same command through a short name', async () => {
158
158
  const cli = gokeTestable('mycli')
159
159
  let seen = ''
160
160
 
@@ -162,12 +162,12 @@ describe('documented command APIs', () => {
162
162
  seen = 'install'
163
163
  })
164
164
 
165
- cli.parse(['node', 'bin', 'i'], { run: true })
165
+ await cli.parse(['node', 'bin', 'i'], { run: true })
166
166
 
167
167
  expect(seen).toBe('install')
168
168
  })
169
169
 
170
- test('command helpText returns command-specific help without printing', () => {
170
+ test('command helpText returns command-specific help without printing', async () => {
171
171
  const stdout = createTestOutputStream()
172
172
  const cli = goke('mycli', { stdout })
173
173
 
@@ -225,7 +225,7 @@ describe('documented command APIs', () => {
225
225
  })
226
226
 
227
227
  describe('generateDocs', () => {
228
- test('generates pages for CLI with multiple commands', () => {
228
+ test('generates pages for CLI with multiple commands', async () => {
229
229
  const cli = gokeTestable('sentry')
230
230
  .version('1.0.0')
231
231
  .help()
@@ -352,13 +352,13 @@ describe('generateDocs', () => {
352
352
  `)
353
353
  })
354
354
 
355
- test('handles CLI with no commands', () => {
355
+ test('handles CLI with no commands', async () => {
356
356
  const cli = gokeTestable('empty')
357
357
  const pages = generateDocs({ cli })
358
358
  expect(pages).toEqual([])
359
359
  })
360
360
 
361
- test('skips deprecated options', () => {
361
+ test('skips deprecated options', async () => {
362
362
  const cli = gokeTestable('mycli')
363
363
  cli
364
364
  .command('deploy', 'Deploy the app')
package/src/goke.ts CHANGED
@@ -1230,7 +1230,7 @@ class Goke<Opts = {}> extends EventEmitter {
1230
1230
  this.stderr = options?.stderr ?? process.stderr
1231
1231
  this.console = createConsole(this.stdout, this.stderr)
1232
1232
  this.columns = options?.columns ?? process.stdout.columns ?? Number.POSITIVE_INFINITY
1233
- this.exit = options?.exit ?? ((code: number) => process.exit(code))
1233
+ this.exit = options?.exit ?? ((code) => process.exit(code))
1234
1234
  this.#defaultArgv = options?.argv ?? processArgs
1235
1235
  this.globalCommand = new GlobalCommand(this)
1236
1236
  this.globalCommand.usage('<command> [options]')
@@ -1433,7 +1433,7 @@ class Goke<Opts = {}> extends EventEmitter {
1433
1433
  *
1434
1434
  * // main.ts
1435
1435
  * import { selfhostCli } from './selfhost.js'
1436
- * goke('mycli')
1436
+ * await goke('mycli')
1437
1437
  * .use(selfhostCli)
1438
1438
  * .help()
1439
1439
  * .parse(process.argv)
@@ -1595,7 +1595,7 @@ class Goke<Opts = {}> extends EventEmitter {
1595
1595
  *
1596
1596
  * @example
1597
1597
  * ```ts
1598
- * goke('mycli')
1598
+ * await goke('mycli')
1599
1599
  * .help()
1600
1600
  * .completions()
1601
1601
  * .command('deploy', 'Deploy the app')
@@ -1740,7 +1740,7 @@ class Goke<Opts = {}> extends EventEmitter {
1740
1740
  })
1741
1741
 
1742
1742
  for (const command of sortedCommands) {
1743
- const result = command.isMatched(previous as string[])
1743
+ const result = command.isMatched(previous)
1744
1744
  if (result.matched) {
1745
1745
  matchedCommand = command
1746
1746
  consumedArgs = result.consumedArgs
@@ -1890,15 +1890,15 @@ class Goke<Opts = {}> extends EventEmitter {
1890
1890
  }
1891
1891
 
1892
1892
  /**
1893
- * Parse argv
1893
+ * Parse argv and await the matched command when run is enabled.
1894
1894
  */
1895
- parse(
1895
+ async parse(
1896
1896
  argv = this.#defaultArgv,
1897
1897
  {
1898
1898
  /** Whether to run the action for matched command */
1899
1899
  run = true,
1900
1900
  } = {}
1901
- ): ParsedArgv {
1901
+ ): Promise<ParsedArgv> {
1902
1902
  this.rawArgs = argv
1903
1903
  if (!this.name) {
1904
1904
  this.name = argv[1] ? getFileName(argv[1]) : 'cli'
@@ -1964,6 +1964,11 @@ class Goke<Opts = {}> extends EventEmitter {
1964
1964
  // Don't match default command - let it fall through to "unknown command"
1965
1965
  continue
1966
1966
  }
1967
+ // Default command defines no positional args but user passed args;
1968
+ // skip matching so unknown args fall through to "unknown command"
1969
+ if (command.args.length === 0) {
1970
+ continue
1971
+ }
1967
1972
  }
1968
1973
  shouldParse = false
1969
1974
  this.setParsedInfo(parsed, command)
@@ -2014,7 +2019,7 @@ class Goke<Opts = {}> extends EventEmitter {
2014
2019
  const parsedArgv = { args: this.args, options: this.options }
2015
2020
 
2016
2021
  if (run) {
2017
- this.runMatchedCommand()
2022
+ await this.runMatchedCommand()
2018
2023
  }
2019
2024
 
2020
2025
  if (!this.matchedCommand && this.args[0] && !(this.options.help && this.showHelpOnExit)) {
package/src/just-bash.ts CHANGED
@@ -323,8 +323,7 @@ export function createJustBashCommand(
323
323
  cloned.name = name
324
324
 
325
325
  try {
326
- cloned.parse(argv, { run: false })
327
- await cloned.runMatchedCommand()
326
+ await cloned.parse(argv)
328
327
  const result = output.getResult()
329
328
  return {
330
329
  stdout: result.stdout,