diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 32296767..cbbdbd31 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,7 +59,7 @@ jobs: node-version: ${{ matrix.node }} - name: Test - run: pnpm exec vitest --coverage + run: pnpm test:all --coverage - name: Submit coverage uses: coverallsapp/github-action@master diff --git a/bin/index.ts b/bin/index.ts index f8220167..71717bf9 100755 --- a/bin/index.ts +++ b/bin/index.ts @@ -8,9 +8,8 @@ import { assertDeprecated } from '../lib/assert.js'; import * as defaults from '../lib/defaults.js'; import { concurrently } from '../lib/index.js'; import { castArray } from '../lib/utils.js'; -import { readPackageJson } from './read-package-json.js'; +import { version } from '../package.json' with { type: 'json' }; -const version = String(readPackageJson().version); const epilogue = `For documentation and more examples, visit:\nhttps://github.com/open-cli-tools/concurrently/tree/v${version}/docs`; // Clean-up arguments (yargs expects only the arguments after the program name) diff --git a/bin/read-package-json.ts b/bin/read-package-json.ts deleted file mode 100644 index ea597d78..00000000 --- a/bin/read-package-json.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { readFileSync } from 'node:fs'; -import { createRequire } from 'node:module'; - -/** - * Read the package.json file of `concurrently` - */ -export function readPackageJson(): Record { - let resolver; - try { - resolver = require.resolve; - } catch { - resolver = createRequire(import.meta.url).resolve; - } - const path = resolver('concurrently/package.json'); - const content = readFileSync(path, 'utf8'); - return JSON.parse(content); -} diff --git a/eslint.config.js b/eslint.config.js index d3117573..95a0e9b6 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -21,7 +21,19 @@ export default defineConfig( }, }, eslint.configs.recommended, - tseslint.configs.recommended, + tseslint.configs.recommendedTypeChecked, + { + languageOptions: { + parserOptions: { + projectService: true, + tsconfigRootDir: import.meta.dirname, + }, + }, + }, + { + files: ['**/*.js', '**/*.spec.ts', '**/__fixtures__/**/*', 'tests/**/*'], + extends: [tseslint.configs.disableTypeChecked], + }, { rules: { curly: 'error', @@ -36,6 +48,19 @@ export default defineConfig( varsIgnorePattern: '^_', }, ], + '@typescript-eslint/prefer-promise-reject-errors': 'off', + }, + }, + { + files: ['**/*.ts'], + ignores: ['**/*.spec.ts', '**/__fixtures__/**/*', 'tests/**/*'], + rules: { + '@typescript-eslint/consistent-type-imports': 'error', + '@typescript-eslint/no-import-type-side-effects': 'error', + '@typescript-eslint/consistent-type-exports': [ + 'error', + { fixMixedExportsWithInlineTypeSpecifier: true }, + ], }, }, { files: ['**/__fixtures__/**/*.{js,ts}'], rules: { 'no-console': 'off' } }, @@ -49,7 +74,7 @@ export default defineConfig( 'simple-import-sort/exports': 'error', 'import/first': 'error', 'import/newline-after-import': 'error', - 'import/no-duplicates': 'error', + 'import/no-duplicates': ['error', { 'prefer-inline': true }], }, }, { diff --git a/lib/command-parser/command-parser.d.ts b/lib/command-parser/command-parser.d.ts index 658ba461..1c65a7db 100644 --- a/lib/command-parser/command-parser.d.ts +++ b/lib/command-parser/command-parser.d.ts @@ -1,4 +1,4 @@ -import { CommandInfo } from '../command.js'; +import type { CommandInfo } from '../command.js'; /** * A command parser encapsulates a specific logic for mapping `CommandInfo` objects diff --git a/lib/command-parser/expand-arguments.ts b/lib/command-parser/expand-arguments.ts index 44c516ea..d4a58654 100644 --- a/lib/command-parser/expand-arguments.ts +++ b/lib/command-parser/expand-arguments.ts @@ -1,7 +1,7 @@ import { quote } from 'shell-quote'; -import { CommandInfo } from '../command.js'; -import { CommandParser } from './command-parser.js'; +import type { CommandInfo } from '../command.js'; +import type { CommandParser } from './command-parser.js'; /** * Replace placeholders with additional arguments. diff --git a/lib/command-parser/expand-shortcut.ts b/lib/command-parser/expand-shortcut.ts index e442fe76..68adff7c 100644 --- a/lib/command-parser/expand-shortcut.ts +++ b/lib/command-parser/expand-shortcut.ts @@ -1,5 +1,5 @@ -import { CommandInfo } from '../command.js'; -import { CommandParser } from './command-parser.js'; +import type { CommandInfo } from '../command.js'; +import type { CommandParser } from './command-parser.js'; /** * Expands shortcuts according to the following table: diff --git a/lib/command-parser/expand-wildcard.ts b/lib/command-parser/expand-wildcard.ts index 4aa37ecc..921c9e28 100644 --- a/lib/command-parser/expand-wildcard.ts +++ b/lib/command-parser/expand-wildcard.ts @@ -1,9 +1,9 @@ import fs from 'node:fs'; -import { CommandInfo } from '../command.js'; +import type { CommandInfo } from '../command.js'; import JSONC from '../jsonc.js'; -import { escapeRegExp } from '../utils.js'; -import { CommandParser } from './command-parser.js'; +import { escapeRegExp, isObject } from '../utils.js'; +import type { CommandParser } from './command-parser.js'; // Matches a negative filter surrounded by '(!' and ')'. const OMISSION = /\(!([^)]+)\)/; @@ -14,7 +14,7 @@ const OMISSION = /\(!([^)]+)\)/; * configuration files of the current directory. */ export class ExpandWildcard implements CommandParser { - static readDeno() { + static readDeno(this: void): unknown { try { let json: string = '{}'; @@ -30,7 +30,7 @@ export class ExpandWildcard implements CommandParser { } } - static readPackage() { + static readPackage(this: void): unknown { try { const json = fs.readFileSync('package.json', { encoding: 'utf-8' }); return JSON.parse(json); @@ -49,18 +49,23 @@ export class ExpandWildcard implements CommandParser { private relevantScripts(command: string): string[] { if (!this.packageScripts) { - this.packageScripts = Object.keys(this.readPackage().scripts || {}); + const content = this.readPackage(); + const scripts = + isObject(content) && isObject(content.scripts) ? Object.keys(content.scripts) : []; + + this.packageScripts = scripts; } if (command === 'deno task') { if (!this.denoTasks) { + const content = this.readDeno(); + const tasks = + isObject(content) && isObject(content.tasks) ? Object.keys(content.tasks) : []; + // If Deno tries to run a task that doesn't exist, // it can fall back to running a script with the same name. // Therefore, the actual list of tasks is the union of the tasks and scripts. - this.denoTasks = [ - ...Object.keys(this.readDeno().tasks || {}), - ...this.packageScripts, - ]; + this.denoTasks = [...tasks, ...this.packageScripts]; } return this.denoTasks; diff --git a/lib/command-parser/strip-quotes.ts b/lib/command-parser/strip-quotes.ts index 097f29cb..6be7a3fb 100644 --- a/lib/command-parser/strip-quotes.ts +++ b/lib/command-parser/strip-quotes.ts @@ -1,5 +1,5 @@ -import { CommandInfo } from '../command.js'; -import { CommandParser } from './command-parser.js'; +import type { CommandInfo } from '../command.js'; +import type { CommandParser } from './command-parser.js'; /** * Strips quotes around commands so that they can run on the current shell. diff --git a/lib/command.ts b/lib/command.ts index 36472ddd..220b2a4a 100644 --- a/lib/command.ts +++ b/lib/command.ts @@ -1,12 +1,12 @@ -import { Buffer } from 'node:buffer'; -import { +import type { Buffer } from 'node:buffer'; +import type { ChildProcess as BaseChildProcess, MessageOptions, SendHandle, SpawnOptions, } from 'node:child_process'; import process from 'node:process'; -import { EventEmitter, Writable } from 'node:stream'; +import type { EventEmitter, Writable } from 'node:stream'; import Rx from 'rxjs'; diff --git a/lib/completion-listener.ts b/lib/completion-listener.ts index e7b32152..5f1f7c99 100644 --- a/lib/completion-listener.ts +++ b/lib/completion-listener.ts @@ -1,7 +1,7 @@ import Rx from 'rxjs'; import { delay, filter, map, share, switchMap, take } from 'rxjs/operators'; -import { CloseEvent, Command } from './command.js'; +import type { CloseEvent, Command } from './command.js'; /** * Defines which command(s) in a list must exit successfully (with an exit code of `0`): diff --git a/lib/concurrently.spec.ts b/lib/concurrently.spec.ts index 621cc1ba..5b5d09d2 100644 --- a/lib/concurrently.spec.ts +++ b/lib/concurrently.spec.ts @@ -1,5 +1,4 @@ -import type { CpuInfo } from 'node:os'; -import os from 'node:os'; +import os, { type CpuInfo } from 'node:os'; import { Writable } from 'node:stream'; import { beforeEach, expect, it, Mock, MockedObject, vi } from 'vitest'; diff --git a/lib/concurrently.ts b/lib/concurrently.ts index c7b3ee38..72f50769 100644 --- a/lib/concurrently.ts +++ b/lib/concurrently.ts @@ -1,26 +1,26 @@ import assert from 'node:assert'; import os from 'node:os'; -import { Writable } from 'node:stream'; +import type { Writable } from 'node:stream'; import { takeUntil } from 'rxjs'; import treeKill from 'tree-kill'; import { - CloseEvent, + type CloseEvent, Command, - CommandIdentifier, - CommandInfo, - KillProcess, - SpawnCommand, + type CommandIdentifier, + type CommandInfo, + type KillProcess, + type SpawnCommand, } from './command.js'; -import { CommandParser } from './command-parser/command-parser.js'; +import type { CommandParser } from './command-parser/command-parser.js'; import { ExpandArguments } from './command-parser/expand-arguments.js'; import { ExpandShortcut } from './command-parser/expand-shortcut.js'; import { ExpandWildcard } from './command-parser/expand-wildcard.js'; import { StripQuotes } from './command-parser/strip-quotes.js'; -import { CompletionListener, SuccessCondition } from './completion-listener.js'; -import { FlowController } from './flow-control/flow-controller.js'; -import { Logger } from './logger.js'; +import { CompletionListener, type SuccessCondition } from './completion-listener.js'; +import type { FlowController } from './flow-control/flow-controller.js'; +import type { Logger } from './logger.js'; import { OutputWriter } from './output-writer.js'; import { PrefixColorSelector } from './prefix-color-selector.js'; import { getSpawnOpts, spawn } from './spawn.js'; @@ -243,6 +243,7 @@ export function concurrently( const result = new CompletionListener({ successCondition: options.successCondition }) .listen(commands, options.abortSignal) + // eslint-disable-next-line @typescript-eslint/no-misused-promises, @typescript-eslint/await-thenable .finally(() => Promise.all(handleResult.onFinishCallbacks.map((onFinish) => onFinish()))); return { diff --git a/lib/defaults.ts b/lib/defaults.ts index c96c9dfb..3870bbc4 100644 --- a/lib/defaults.ts +++ b/lib/defaults.ts @@ -2,7 +2,7 @@ // It's read by the flow controllers, the executable, etc. // Refer to tests for the meaning of the different possible values. -import { SuccessCondition } from './completion-listener.js'; +import type { SuccessCondition } from './completion-listener.js'; export const defaultInputTarget = 0; diff --git a/lib/flow-control/flow-controller.d.ts b/lib/flow-control/flow-controller.d.ts index 87f3a2b3..c18c7b52 100644 --- a/lib/flow-control/flow-controller.d.ts +++ b/lib/flow-control/flow-controller.d.ts @@ -1,4 +1,4 @@ -import { Command } from '../command.js'; +import type { Command } from '../command.js'; /** * Interface for a class that controls and/or watches the behavior of commands. diff --git a/lib/flow-control/input-handler.ts b/lib/flow-control/input-handler.ts index c8d5c09f..daaa126e 100644 --- a/lib/flow-control/input-handler.ts +++ b/lib/flow-control/input-handler.ts @@ -1,12 +1,12 @@ -import { Readable } from 'node:stream'; +import type { Readable } from 'node:stream'; import Rx from 'rxjs'; import { map } from 'rxjs/operators'; -import { Command, CommandIdentifier } from '../command.js'; +import type { Command, CommandIdentifier } from '../command.js'; import * as defaults from '../defaults.js'; -import { Logger } from '../logger.js'; -import { FlowController } from './flow-controller.js'; +import type { Logger } from '../logger.js'; +import type { FlowController } from './flow-controller.js'; /** * Sends input from concurrently through to commands. diff --git a/lib/flow-control/kill-on-signal.ts b/lib/flow-control/kill-on-signal.ts index 48ecbfd7..c89b78ae 100644 --- a/lib/flow-control/kill-on-signal.ts +++ b/lib/flow-control/kill-on-signal.ts @@ -1,9 +1,9 @@ -import EventEmitter from 'node:events'; +import type EventEmitter from 'node:events'; import { map } from 'rxjs/operators'; -import { Command } from '../command.js'; -import { FlowController } from './flow-controller.js'; +import type { Command } from '../command.js'; +import type { FlowController } from './flow-controller.js'; const SIGNALS = ['SIGINT', 'SIGTERM', 'SIGHUP'] as const; diff --git a/lib/flow-control/kill-others.ts b/lib/flow-control/kill-others.ts index 2b2786a1..083996c6 100644 --- a/lib/flow-control/kill-others.ts +++ b/lib/flow-control/kill-others.ts @@ -1,9 +1,9 @@ import { filter, map } from 'rxjs/operators'; import { Command } from '../command.js'; -import { Logger } from '../logger.js'; +import type { Logger } from '../logger.js'; import { castArray } from '../utils.js'; -import { FlowController } from './flow-controller.js'; +import type { FlowController } from './flow-controller.js'; export type ProcessCloseCondition = 'failure' | 'success'; diff --git a/lib/flow-control/log-error.ts b/lib/flow-control/log-error.ts index 1de50b91..75193054 100644 --- a/lib/flow-control/log-error.ts +++ b/lib/flow-control/log-error.ts @@ -1,6 +1,6 @@ -import { Command } from '../command.js'; -import { Logger } from '../logger.js'; -import { FlowController } from './flow-controller.js'; +import type { Command } from '../command.js'; +import type { Logger } from '../logger.js'; +import type { FlowController } from './flow-controller.js'; /** * Logs when commands failed executing, e.g. due to the executable not existing in the system. diff --git a/lib/flow-control/log-exit.ts b/lib/flow-control/log-exit.ts index 18a603d3..d4716e8a 100644 --- a/lib/flow-control/log-exit.ts +++ b/lib/flow-control/log-exit.ts @@ -1,6 +1,6 @@ -import { Command } from '../command.js'; -import { Logger } from '../logger.js'; -import { FlowController } from './flow-controller.js'; +import type { Command } from '../command.js'; +import type { Logger } from '../logger.js'; +import type { FlowController } from './flow-controller.js'; /** * Logs the exit code/signal of commands. diff --git a/lib/flow-control/log-output.ts b/lib/flow-control/log-output.ts index a4d0362f..8cd6319e 100644 --- a/lib/flow-control/log-output.ts +++ b/lib/flow-control/log-output.ts @@ -1,6 +1,6 @@ -import { Command } from '../command.js'; -import { Logger } from '../logger.js'; -import { FlowController } from './flow-controller.js'; +import type { Command } from '../command.js'; +import type { Logger } from '../logger.js'; +import type { FlowController } from './flow-controller.js'; /** * Logs the stdout and stderr output of commands. diff --git a/lib/flow-control/log-timings.ts b/lib/flow-control/log-timings.ts index abdca453..b2b2f257 100644 --- a/lib/flow-control/log-timings.ts +++ b/lib/flow-control/log-timings.ts @@ -3,11 +3,11 @@ import assert from 'node:assert'; import Rx from 'rxjs'; import { bufferCount, combineLatestWith, take } from 'rxjs/operators'; -import { CloseEvent, Command } from '../command.js'; +import type { CloseEvent, Command } from '../command.js'; import { DateFormatter } from '../date-format.js'; import * as defaults from '../defaults.js'; -import { Logger } from '../logger.js'; -import { FlowController } from './flow-controller.js'; +import type { Logger } from '../logger.js'; +import type { FlowController } from './flow-controller.js'; type TimingInfo = { name: string; @@ -21,12 +21,10 @@ type TimingInfo = { * Logs timing information about commands as they start/stop and then a summary when all commands finish. */ export class LogTimings implements FlowController { - static mapCloseEventToTimingInfo({ - command, - timings, - killed, - exitCode, - }: CloseEvent): TimingInfo { + static mapCloseEventToTimingInfo( + this: void, + { command, timings, killed, exitCode }: CloseEvent, + ): TimingInfo { const readableDurationMs = ( timings.endDate.getTime() - timings.startDate.getTime() ).toLocaleString(); diff --git a/lib/flow-control/logger-padding.ts b/lib/flow-control/logger-padding.ts index 1b837c8f..fabbeb7b 100644 --- a/lib/flow-control/logger-padding.ts +++ b/lib/flow-control/logger-padding.ts @@ -1,6 +1,6 @@ -import { Command } from '../command.js'; -import { Logger } from '../logger.js'; -import { FlowController } from './flow-controller.js'; +import type { Command } from '../command.js'; +import type { Logger } from '../logger.js'; +import type { FlowController } from './flow-controller.js'; export class LoggerPadding implements FlowController { private readonly logger: Logger; diff --git a/lib/flow-control/output-error-handler.ts b/lib/flow-control/output-error-handler.ts index 2790bb27..50e12ab1 100644 --- a/lib/flow-control/output-error-handler.ts +++ b/lib/flow-control/output-error-handler.ts @@ -1,8 +1,8 @@ -import { Writable } from 'node:stream'; +import type { Writable } from 'node:stream'; -import { Command } from '../command.js'; +import type { Command } from '../command.js'; import { fromSharedEvent } from '../observables.js'; -import { FlowController } from './flow-controller.js'; +import type { FlowController } from './flow-controller.js'; /** * Kills processes and aborts further command spawning on output stream error (namely, SIGPIPE). diff --git a/lib/flow-control/restart-process.ts b/lib/flow-control/restart-process.ts index 4083f2bf..318f820e 100644 --- a/lib/flow-control/restart-process.ts +++ b/lib/flow-control/restart-process.ts @@ -1,10 +1,10 @@ import Rx from 'rxjs'; import { defaultIfEmpty, delayWhen, filter, map, skip, take, takeWhile } from 'rxjs/operators'; -import { Command } from '../command.js'; +import type { Command } from '../command.js'; import * as defaults from '../defaults.js'; -import { Logger } from '../logger.js'; -import { FlowController } from './flow-controller.js'; +import type { Logger } from '../logger.js'; +import type { FlowController } from './flow-controller.js'; export type RestartDelay = number | 'exponential'; diff --git a/lib/flow-control/teardown.ts b/lib/flow-control/teardown.ts index ede50ebf..670be01a 100644 --- a/lib/flow-control/teardown.ts +++ b/lib/flow-control/teardown.ts @@ -1,9 +1,9 @@ import Rx from 'rxjs'; -import { Command, SpawnCommand } from '../command.js'; -import { Logger } from '../logger.js'; +import type { Command, SpawnCommand } from '../command.js'; +import type { Logger } from '../logger.js'; import { getSpawnOpts, spawn as baseSpawn } from '../spawn.js'; -import { FlowController } from './flow-controller.js'; +import type { FlowController } from './flow-controller.js'; export class Teardown implements FlowController { private readonly logger: Logger; diff --git a/lib/index.ts b/lib/index.ts index 0d052532..c77b5a8a 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -1,25 +1,25 @@ import process from 'node:process'; -import { Readable } from 'node:stream'; +import type { Readable } from 'node:stream'; import { assertDeprecated } from './assert.js'; -import { CloseEvent, Command, CommandIdentifier, TimerEvent } from './command.js'; +import { type CloseEvent, Command, type CommandIdentifier, type TimerEvent } from './command.js'; import { concurrently as createConcurrently, - ConcurrentlyCommandInput, - ConcurrentlyOptions as BaseConcurrentlyOptions, - ConcurrentlyResult, + type ConcurrentlyCommandInput, + type ConcurrentlyOptions as BaseConcurrentlyOptions, + type ConcurrentlyResult, } from './concurrently.js'; import type { FlowController } from './flow-control/flow-controller.js'; import { InputHandler } from './flow-control/input-handler.js'; import { KillOnSignal } from './flow-control/kill-on-signal.js'; -import { KillOthers, ProcessCloseCondition } from './flow-control/kill-others.js'; +import { KillOthers, type ProcessCloseCondition } from './flow-control/kill-others.js'; import { LogError } from './flow-control/log-error.js'; import { LogExit } from './flow-control/log-exit.js'; import { LogOutput } from './flow-control/log-output.js'; import { LogTimings } from './flow-control/log-timings.js'; import { LoggerPadding } from './flow-control/logger-padding.js'; import { OutputErrorHandler } from './flow-control/output-error-handler.js'; -import { RestartDelay, RestartProcess } from './flow-control/restart-process.js'; +import { type RestartDelay, RestartProcess } from './flow-control/restart-process.js'; import { Teardown } from './flow-control/teardown.js'; import { Logger } from './logger.js'; import { castArray } from './utils.js'; @@ -202,14 +202,14 @@ export function concurrently( // Main export default concurrently; -export { ConcurrentlyCommandInput, ConcurrentlyResult, createConcurrently, Logger }; +export { type ConcurrentlyCommandInput, type ConcurrentlyResult, createConcurrently, Logger }; // Command specific -export { CloseEvent, Command, CommandIdentifier, TimerEvent }; +export { type CloseEvent, Command, type CommandIdentifier, type TimerEvent }; // Flow controllers export { - FlowController, + type FlowController, InputHandler, KillOnSignal, KillOthers, diff --git a/lib/jsonc.ts b/lib/jsonc.ts index 69209733..b94f8fef 100644 --- a/lib/jsonc.ts +++ b/lib/jsonc.ts @@ -15,12 +15,12 @@ const JSONC = { try { // Fast path for valid JSON - return JSON.parse(text); + return JSON.parse(text) as unknown; } catch { // Slow path for JSONC and invalid inputs return JSON.parse( text.replace(stringOrCommentRe, '$1').replace(stringOrTrailingCommaRe, '$1'), - ); + ) as unknown; } }, stringify: JSON.stringify, diff --git a/lib/logger.ts b/lib/logger.ts index 2e370081..0c23474e 100644 --- a/lib/logger.ts +++ b/lib/logger.ts @@ -1,7 +1,7 @@ -import chalk, { Chalk, ChalkInstance } from 'chalk'; +import chalk, { Chalk, type ChalkInstance } from 'chalk'; import Rx from 'rxjs'; -import { Command, CommandIdentifier } from './command.js'; +import type { Command, CommandIdentifier } from './command.js'; import { DateFormatter } from './date-format.js'; import * as defaults from './defaults.js'; import { escapeRegExp } from './utils.js'; @@ -216,7 +216,7 @@ export class Logger { * * Each row is a single input item, and they are presented in the input order. */ - logTable(tableContents: Record[]) { + logTable(tableContents: Record[]) { // For now, can only print array tables with some content. if (this.raw || !Array.isArray(tableContents) || !tableContents.length) { return; @@ -290,7 +290,10 @@ export class Logger { this.emit(command, prefix); } - const textToWrite = text.replaceAll('\n', (lf, i) => lf + (text[i + 1] ? prefix : '')); + const textToWrite = text.replaceAll( + '\n', + (lf, i: number) => lf + (text[i + 1] ? prefix : ''), + ); this.emit(command, textToWrite); } diff --git a/lib/observables.ts b/lib/observables.ts index 9b75a557..fc127c96 100644 --- a/lib/observables.ts +++ b/lib/observables.ts @@ -1,6 +1,6 @@ -import EventEmitter from 'node:events'; +import type EventEmitter from 'node:events'; -import { fromEvent, Observable, share } from 'rxjs'; +import { fromEvent, type Observable, share } from 'rxjs'; const sharedEvents = new WeakMap>>(); diff --git a/lib/output-writer.ts b/lib/output-writer.ts index 26c1b044..2b703b1c 100644 --- a/lib/output-writer.ts +++ b/lib/output-writer.ts @@ -1,8 +1,8 @@ -import { Writable } from 'node:stream'; +import type { Writable } from 'node:stream'; import Rx from 'rxjs'; -import { Command } from './command.js'; +import type { Command } from './command.js'; import { fromSharedEvent } from './observables.js'; /** diff --git a/lib/prefix-color-selector.spec.ts b/lib/prefix-color-selector.spec.ts index 2479f066..cc0fe52c 100644 --- a/lib/prefix-color-selector.spec.ts +++ b/lib/prefix-color-selector.spec.ts @@ -1,4 +1,4 @@ -import { ChalkInstance } from 'chalk'; +import { type ChalkInstance } from 'chalk'; import { afterEach, describe, expect, it, vi } from 'vitest'; import { PrefixColorSelector } from './prefix-color-selector.js'; diff --git a/lib/prefix-color-selector.ts b/lib/prefix-color-selector.ts index 339a3629..babacc48 100644 --- a/lib/prefix-color-selector.ts +++ b/lib/prefix-color-selector.ts @@ -1,4 +1,4 @@ -import { ChalkInstance } from 'chalk'; +import type { ChalkInstance } from 'chalk'; function getConsoleColorsWithoutCustomColors(customColors: string[]): string[] { return PrefixColorSelector.ACCEPTABLE_CONSOLE_COLORS.filter( diff --git a/lib/spawn.ts b/lib/spawn.ts index 00b82a4e..8a137fb7 100644 --- a/lib/spawn.ts +++ b/lib/spawn.ts @@ -1,8 +1,13 @@ import assert from 'node:assert'; -import { ChildProcess, IOType, spawn as baseSpawn, SpawnOptions } from 'node:child_process'; +import { + type ChildProcess, + type IOType, + spawn as baseSpawn, + type SpawnOptions, +} from 'node:child_process'; import nodeProcess from 'node:process'; -import supportsColor, { ColorSupport } from 'supports-color'; +import supportsColor, { type ColorSupport } from 'supports-color'; /** * Spawns a command using `cmd.exe` on Windows, or `/bin/sh` elsewhere. diff --git a/lib/utils.spec.ts b/lib/utils.spec.ts index 014156c3..9caefee3 100644 --- a/lib/utils.spec.ts +++ b/lib/utils.spec.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest'; -import { castArray, escapeRegExp } from './utils.js'; +import { castArray, escapeRegExp, isObject } from './utils.js'; describe('#escapeRegExp()', () => { it('escapes all RegExp chars', () => { @@ -37,3 +37,20 @@ describe('#castArray()', () => { }); }); }); + +describe('#isObject()', () => { + it.each([{}, { test: 1 }])('returns true if input is an object', (input) => { + const result = isObject(input); + + expect(result).toEqual(true); + }); + + it.each([null, [], undefined, 'string', 1, () => ({})])( + 'returns false if input is not an object', + (input) => { + const result = isObject(input); + + expect(result).toEqual(false); + }, + ); +}); diff --git a/lib/utils.ts b/lib/utils.ts index 831d46b8..310a99b2 100644 --- a/lib/utils.ts +++ b/lib/utils.ts @@ -13,3 +13,10 @@ type CastArrayResult = T extends undefined | null ? never[] : T extends unkno export function castArray(value?: T) { return (Array.isArray(value) ? value : value != null ? [value] : []) as CastArrayResult; } + +/** + * Basic check if a given input is a JavaScript object. + */ +export function isObject(input: unknown): input is Record { + return typeof input === 'object' && input !== null && !Array.isArray(input); +} diff --git a/package.json b/package.json index d474b816..a0e5177d 100644 --- a/package.json +++ b/package.json @@ -20,35 +20,33 @@ "sh" ], "exports": { - ".": "./dist/lib/index.js", + ".": "./dist/lib.js", "./package.json": "./package.json" }, - "types": "./dist/lib/index.d.ts", + "types": "./dist/lib.d.ts", "publishConfig": { "bin": { - "concurrently": "./dist/bin/index.js", - "conc": "./dist/bin/index.js" + "concurrently": "./dist/bin.js", + "conc": "./dist/bin.js" } }, "files": [ - "!**/*.spec.d.ts", - "!**/*.spec.js", - "!**/__fixtures__", "dist", - "dist/tsconfig.tsbuildinfo", "docs" ], "engines": { "node": ">=20" }, "scripts": { - "build": "tsc --build", - "postbuild": "chmod +x dist/bin/index.js", + "build": "pnpm run '/^bundle|typecheck$/'", + "bundle": "tsdown", "typecheck": "tsc --noEmit", "format": "prettier --check '**/*.{json,y?(a)ml,md}'", "lint": "eslint", "prepublishOnly": "safe-publish-latest && pnpm run build", "test": "vitest --project unit", + "test:all": "vitest run", + "test:e2e": "vitest run --project e2e", "test:smoke": "vitest run --project smoke", "prepare": "husky" }, @@ -69,7 +67,6 @@ "@vitest/coverage-v8": "^3.2.4", "@vitest/eslint-plugin": "^1.3.16", "ctrlc-wrapper": "^0.0.5", - "esbuild": "~0.25.10", "eslint": "^9.37.0", "eslint-config-flat-gitignore": "^2.1.0", "eslint-config-prettier": "^10.1.8", @@ -82,6 +79,7 @@ "prettier": "^3.6.2", "safe-publish-latest": "^2.0.0", "string-argv": "^0.3.2", + "tsdown": "^0.15.6", "typescript": "~5.9.3", "typescript-eslint": "^8.46.0", "vitest": "^3.2.4" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 86f2c8f8..ad9aa9bd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -44,34 +44,31 @@ importers: version: 17.0.33 '@vitest/coverage-v8': specifier: ^3.2.4 - version: 3.2.4(supports-color@10.2.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.20)(supports-color@10.2.2)(yaml@2.8.1)) + version: 3.2.4(supports-color@10.2.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.20)(jiti@2.6.1)(supports-color@10.2.2)(yaml@2.8.1)) '@vitest/eslint-plugin': specifier: ^1.3.16 - version: 1.3.16(eslint@9.37.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.20)(supports-color@10.2.2)(yaml@2.8.1)) + version: 1.3.16(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.20)(jiti@2.6.1)(supports-color@10.2.2)(yaml@2.8.1)) ctrlc-wrapper: specifier: ^0.0.5 version: 0.0.5 - esbuild: - specifier: ~0.25.10 - version: 0.25.10 eslint: specifier: ^9.37.0 - version: 9.37.0(supports-color@10.2.2) + version: 9.37.0(jiti@2.6.1)(supports-color@10.2.2) eslint-config-flat-gitignore: specifier: ^2.1.0 - version: 2.1.0(eslint@9.37.0(supports-color@10.2.2)) + version: 2.1.0(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2)) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.37.0(supports-color@10.2.2)) + version: 10.1.8(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2)) eslint-plugin-import-lite: specifier: ^0.3.0 - version: 0.3.0(eslint@9.37.0(supports-color@10.2.2))(typescript@5.9.3) + version: 0.3.0(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2))(typescript@5.9.3) eslint-plugin-prettier: specifier: ^5.5.4 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.37.0(supports-color@10.2.2)))(eslint@9.37.0(supports-color@10.2.2))(prettier@3.6.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2)))(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2))(prettier@3.6.2) eslint-plugin-simple-import-sort: specifier: ^12.1.1 - version: 12.1.1(eslint@9.37.0(supports-color@10.2.2)) + version: 12.1.1(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2)) globals: specifier: ^16.4.0 version: 16.4.0 @@ -90,15 +87,18 @@ importers: string-argv: specifier: ^0.3.2 version: 0.3.2 + tsdown: + specifier: ^0.15.6 + version: 0.15.6(supports-color@10.2.2)(typescript@5.9.3) typescript: specifier: ~5.9.3 version: 5.9.3 typescript-eslint: specifier: ^8.46.0 - version: 8.46.0(eslint@9.37.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3) + version: 8.46.0(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3) vitest: specifier: ^3.2.4 - version: 3.2.4(@types/debug@4.1.12)(@types/node@20.19.20)(supports-color@10.2.2)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@20.19.20)(jiti@2.6.1)(supports-color@10.2.2)(yaml@2.8.1) tests: dependencies: @@ -112,6 +112,10 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} + '@babel/generator@7.28.3': + resolution: {integrity: sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==} + engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} @@ -133,6 +137,15 @@ packages: resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} + '@emnapi/core@1.5.0': + resolution: {integrity: sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg==} + + '@emnapi/runtime@1.5.0': + resolution: {integrity: sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==} + + '@emnapi/wasi-threads@1.1.0': + resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} + '@esbuild/aix-ppc64@0.25.10': resolution: {integrity: sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==} engines: {node: '>=18'} @@ -379,6 +392,9 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@napi-rs/wasm-runtime@1.0.7': + resolution: {integrity: sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -391,6 +407,9 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@oxc-project/types@0.94.0': + resolution: {integrity: sha512-+UgQT/4o59cZfH6Cp7G0hwmqEQ0wE+AdIwhikdwnhWI9Dp8CgSY081+Q3O67/wq3VJu8mgUEB93J9EHHn70fOw==} + '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -399,6 +418,95 @@ packages: resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + '@quansync/fs@0.1.5': + resolution: {integrity: sha512-lNS9hL2aS2NZgNW7BBj+6EBl4rOf8l+tQ0eRY6JWCI8jI2kc53gSoqbjojU0OnAWhzoXiOjFyGsHcDGePB3lhA==} + + '@rolldown/binding-android-arm64@1.0.0-beta.42': + resolution: {integrity: sha512-W5ZKF3TP3bOWuBfotAGp+UGjxOkGV7jRmIRbBA7NFjggx7Oi6vOmGDqpHEIX7kDCiry1cnIsWQaxNvWbMdkvzQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.0.0-beta.42': + resolution: {integrity: sha512-abw/wtgJA8OCgaTlL+xJxnN/Z01BwV1rfzIp5Hh9x+IIO6xOBfPsQ0nzi0+rWx3TyZ9FZXyC7bbC+5NpQ9EaXQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.0.0-beta.42': + resolution: {integrity: sha512-Y/UrZIRVr8CvXVEB88t6PeC46r1K9/QdPEo2ASE/b/KBEyXIx+QbM6kv9QfQVWU2Atly2+SVsQzxQsIvuk3lZQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.0.0-beta.42': + resolution: {integrity: sha512-zRM0oOk7BZiy6DoWBvdV4hyEg+j6+WcBZIMHVirMEZRu8hd18kZdJkg+bjVMfCEhwpWeFUfBfZ1qcaZ5UdYzlQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.42': + resolution: {integrity: sha512-6RjFaC52QNwo7ilU8C5H7swbGlgfTkG9pudXwzr3VYyT18s0C9gLg3mvc7OMPIGqNxnQ0M5lU8j6aQCk2DTRVg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.42': + resolution: {integrity: sha512-LMYHM5Sf6ROq+VUwHMDVX2IAuEsWTv4SnlFEedBnMGpvRuQ14lCmD4m5Q8sjyAQCgyha9oghdGoK8AEg1sXZKg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.42': + resolution: {integrity: sha512-/bNTYb9aKNhzdbPn3O4MK2aLv55AlrkUKPE4KNfBYjkoZUfDr4jWp7gsSlvTc5A/99V1RCm9axvt616ZzeXGyA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.42': + resolution: {integrity: sha512-n/SLa4h342oyeGykZdch7Y3GNCNliRPL4k5wkeZ/5eQZs+c6/ZG1SHCJQoy7bZcmxiMyaXs9HoFmv1PEKrZgWg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + + '@rolldown/binding-linux-x64-musl@1.0.0-beta.42': + resolution: {integrity: sha512-4PSd46sFzqpLHSGdaSViAb1mk55sCUMpJg+X8ittXaVocQsV3QLG/uydSH8RyL0ngHX5fy3D70LcCzlB15AgHw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + + '@rolldown/binding-openharmony-arm64@1.0.0-beta.42': + resolution: {integrity: sha512-BmWoeJJyeZXmZBcfoxG6J9+rl2G7eO47qdTkAzEegj4n3aC6CBIHOuDcbE8BvhZaEjQR0nh0nJrtEDlt65Q7Sw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-wasm32-wasi@1.0.0-beta.42': + resolution: {integrity: sha512-2Ft32F7uiDTrGZUKws6CLNTlvTWHC33l4vpXrzUucf9rYtUThAdPCOt89Pmn13tNX6AulxjGEP2R0nZjTSW3eQ==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.42': + resolution: {integrity: sha512-hC1kShXW/z221eG+WzQMN06KepvPbMBknF0iGR3VMYJLOe9gwnSTfGxFT5hf8XrPv7CEZqTWRd0GQpkSHRbGsw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.42': + resolution: {integrity: sha512-AICBYromawouGjj+GS33369E8Vwhy6UwhQEhQ5evfS8jPCsyVvoICJatbDGDGH01dwtVGLD5eDFzPicUOVpe4g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.42': + resolution: {integrity: sha512-XpZ0M+tjoEiSc9c+uZR7FCnOI0uxDRNs1elGOMjeB0pUP1QmvVbZGYNsyLbLoP4u7e3VQN8rie1OQ8/mB6rcJg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.0-beta.42': + resolution: {integrity: sha512-N7pQzk9CyE7q0bBN/q0J8s6Db279r5kUZc6d7/wWRe9/zXqC52HQovVyu6iXPIDY4BEzzgbVLhVFXrOuGJ22ZQ==} + '@rollup/rollup-android-arm-eabi@4.52.4': resolution: {integrity: sha512-BTm2qKNnWIQ5auf4deoetINJm2JzvihvGb9R6K/ETwKLql/Bb3Eg2H1FBp1gUb4YGbydMA3jcmQTR73q7J+GAA==} cpu: [arm] @@ -509,6 +617,9 @@ packages: cpu: [x64] os: [win32] + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + '@types/chai@5.2.2': resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==} @@ -681,6 +792,10 @@ packages: resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} + ansis@4.2.0: + resolution: {integrity: sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==} + engines: {node: '>=14'} + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -688,12 +803,19 @@ packages: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} + ast-kit@2.1.3: + resolution: {integrity: sha512-TH+b3Lv6pUjy/Nu0m6A2JULtdzLpmqF9x1Dhj00ZoEiML8qvVA9j1flkzTKNYgdEhWrjDwtWNpyyCUbfQe514g==} + engines: {node: '>=20.19.0'} + ast-v8-to-istanbul@0.3.5: resolution: {integrity: sha512-9SdXjNheSiE8bALAQCQQuT6fgQaoxJh7IRYrRGZ8/9nv8WhJeC1aXAwN8TbaOssGOukUvyvnkgD9+Yuykvl1aA==} balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + birpc@2.6.1: + resolution: {integrity: sha512-LPnFhlDpdSH6FJhJyn4M0kFO7vtQ5iPw24FnG0y21q09xC7e8+1LeR31S1MAIrDAHp4m7aas4bEkTDTvMAtebQ==} + brace-expansion@1.1.12: resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} @@ -728,6 +850,10 @@ packages: resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} engines: {node: '>= 16'} + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + cli-cursor@5.0.0: resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} engines: {node: '>=18'} @@ -792,6 +918,22 @@ packages: deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + + diff@8.0.2: + resolution: {integrity: sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==} + engines: {node: '>=0.3.1'} + + dts-resolver@2.1.2: + resolution: {integrity: sha512-xeXHBQkn2ISSXxbJWD828PFjtyg+/UrMDo7W4Ffcs7+YWCquxU8YjV1KoxuiL+eJ5pg3ll+bC6flVv61L3LKZg==} + engines: {node: '>=20.18.0'} + peerDependencies: + oxc-resolver: '>=11.0.0' + peerDependenciesMeta: + oxc-resolver: + optional: true + eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} @@ -804,6 +946,10 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + empathic@2.0.0: + resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==} + engines: {node: '>=14'} + environment@1.1.0: resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} engines: {node: '>=18'} @@ -980,6 +1126,9 @@ packages: resolution: {integrity: sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==} engines: {node: '>=18'} + get-tsconfig@4.12.0: + resolution: {integrity: sha512-LScr2aNr2FbjAjZh2C6X6BxRx1/x+aTDExct/xyq2XKbYOiG5c0aK7pMsSuyc0brz3ibr/lbQiHD9jzt4lccJw==} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -1007,6 +1156,9 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + hookable@5.5.3: + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} @@ -1077,6 +1229,10 @@ packages: jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + hasBin: true + js-tokens@9.0.1: resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} @@ -1084,6 +1240,11 @@ packages: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} @@ -1253,9 +1414,16 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + quansync@0.2.11: + resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -1264,6 +1432,9 @@ packages: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + restore-cursor@5.1.0: resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} engines: {node: '>=18'} @@ -1275,6 +1446,30 @@ packages: rfdc@1.4.1: resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + rolldown-plugin-dts@0.16.11: + resolution: {integrity: sha512-9IQDaPvPqTx3RjG2eQCK5GYZITo203BxKunGI80AGYicu1ySFTUyugicAaTZWRzFWh9DSnzkgNeMNbDWBbSs0w==} + engines: {node: '>=20.18.0'} + peerDependencies: + '@ts-macro/tsc': ^0.3.6 + '@typescript/native-preview': '>=7.0.0-dev.20250601.1' + rolldown: ^1.0.0-beta.9 + typescript: ^5.0.0 + vue-tsc: ~3.1.0 + peerDependenciesMeta: + '@ts-macro/tsc': + optional: true + '@typescript/native-preview': + optional: true + typescript: + optional: true + vue-tsc: + optional: true + + rolldown@1.0.0-beta.42: + resolution: {integrity: sha512-xaPcckj+BbJhYLsv8gOqezc8EdMcKKe/gk8v47B0KPvgABDrQ0qmNPAiT/gh9n9Foe0bUkEv2qzj42uU5q1WRg==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + rollup@4.52.4: resolution: {integrity: sha512-CLEVl+MnPAiKh5pl4dEWSyMTpuflgNQiLGhMv8ezD5W/qP8AKvmYpCOKRRNOh7oRKnauBZ4SyeYkMS+1VSyKwQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -1386,6 +1581,9 @@ packages: tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + tinyexec@1.0.1: + resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==} + tinyglobby@0.2.15: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} @@ -1416,6 +1614,28 @@ packages: peerDependencies: typescript: '>=4.8.4' + tsdown@0.15.6: + resolution: {integrity: sha512-W6++O3JeV9gm3JY6P/vLiC7zzTcJbZhQxXb+p3AvRMpDOPBIg82yXULyZCcwjsihY/bFG+Qw37HkezZbP7fzUg==} + engines: {node: '>=20.19.0'} + hasBin: true + peerDependencies: + '@arethetypeswrong/core': ^0.18.1 + publint: ^0.3.0 + typescript: ^5.0.0 + unplugin-lightningcss: ^0.4.0 + unplugin-unused: ^0.5.0 + peerDependenciesMeta: + '@arethetypeswrong/core': + optional: true + publint: + optional: true + typescript: + optional: true + unplugin-lightningcss: + optional: true + unplugin-unused: + optional: true + tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -1435,6 +1655,9 @@ packages: engines: {node: '>=14.17'} hasBin: true + unconfig@7.3.3: + resolution: {integrity: sha512-QCkQoOnJF8L107gxfHL0uavn7WD9b3dpBcFX6HtfQYmjw2YzWxGuFQ0N0J6tE9oguCBJn9KOvfqYDCMPHIZrBA==} + undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} @@ -1568,6 +1791,14 @@ snapshots: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 + '@babel/generator@7.28.3': + dependencies: + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + '@babel/helper-string-parser@7.27.1': {} '@babel/helper-validator-identifier@7.27.1': {} @@ -1583,6 +1814,22 @@ snapshots: '@bcoe/v8-coverage@1.0.2': {} + '@emnapi/core@1.5.0': + dependencies: + '@emnapi/wasi-threads': 1.1.0 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.5.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.1.0': + dependencies: + tslib: 2.8.1 + optional: true + '@esbuild/aix-ppc64@0.25.10': optional: true @@ -1661,18 +1908,18 @@ snapshots: '@esbuild/win32-x64@0.25.10': optional: true - '@eslint-community/eslint-utils@4.9.0(eslint@9.37.0(supports-color@10.2.2))': + '@eslint-community/eslint-utils@4.9.0(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2))': dependencies: - eslint: 9.37.0(supports-color@10.2.2) + eslint: 9.37.0(jiti@2.6.1)(supports-color@10.2.2) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} - '@eslint/compat@1.4.0(eslint@9.37.0(supports-color@10.2.2))': + '@eslint/compat@1.4.0(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2))': dependencies: '@eslint/core': 0.16.0 optionalDependencies: - eslint: 9.37.0(supports-color@10.2.2) + eslint: 9.37.0(jiti@2.6.1)(supports-color@10.2.2) '@eslint/config-array@0.21.0(supports-color@10.2.2)': dependencies: @@ -1754,6 +2001,13 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@napi-rs/wasm-runtime@1.0.7': + dependencies: + '@emnapi/core': 1.5.0 + '@emnapi/runtime': 1.5.0 + '@tybys/wasm-util': 0.10.1 + optional: true + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -1766,11 +2020,63 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 + '@oxc-project/types@0.94.0': {} + '@pkgjs/parseargs@0.11.0': optional: true '@pkgr/core@0.2.9': {} + '@quansync/fs@0.1.5': + dependencies: + quansync: 0.2.11 + + '@rolldown/binding-android-arm64@1.0.0-beta.42': + optional: true + + '@rolldown/binding-darwin-arm64@1.0.0-beta.42': + optional: true + + '@rolldown/binding-darwin-x64@1.0.0-beta.42': + optional: true + + '@rolldown/binding-freebsd-x64@1.0.0-beta.42': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.42': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.42': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.42': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.42': + optional: true + + '@rolldown/binding-linux-x64-musl@1.0.0-beta.42': + optional: true + + '@rolldown/binding-openharmony-arm64@1.0.0-beta.42': + optional: true + + '@rolldown/binding-wasm32-wasi@1.0.0-beta.42': + dependencies: + '@napi-rs/wasm-runtime': 1.0.7 + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.42': + optional: true + + '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.42': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.42': + optional: true + + '@rolldown/pluginutils@1.0.0-beta.42': {} + '@rollup/rollup-android-arm-eabi@4.52.4': optional: true @@ -1837,6 +2143,11 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.52.4': optional: true + '@tybys/wasm-util@0.10.1': + dependencies: + tslib: 2.8.1 + optional: true + '@types/chai@5.2.2': dependencies: '@types/deep-eql': 4.0.2 @@ -1867,15 +2178,15 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@8.46.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3))(eslint@9.37.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.46.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.46.0(eslint@9.37.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3) + '@typescript-eslint/parser': 8.46.0(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3) '@typescript-eslint/scope-manager': 8.46.0 - '@typescript-eslint/type-utils': 8.46.0(eslint@9.37.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3) - '@typescript-eslint/utils': 8.46.0(eslint@9.37.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3) + '@typescript-eslint/type-utils': 8.46.0(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.0(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3) '@typescript-eslint/visitor-keys': 8.46.0 - eslint: 9.37.0(supports-color@10.2.2) + eslint: 9.37.0(jiti@2.6.1)(supports-color@10.2.2) graphemer: 1.4.0 ignore: 7.0.5 natural-compare: 1.4.0 @@ -1884,14 +2195,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.46.0(eslint@9.37.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3)': + '@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3)': dependencies: '@typescript-eslint/scope-manager': 8.46.0 '@typescript-eslint/types': 8.46.0 '@typescript-eslint/typescript-estree': 8.46.0(supports-color@10.2.2)(typescript@5.9.3) '@typescript-eslint/visitor-keys': 8.46.0 debug: 4.4.3(supports-color@10.2.2) - eslint: 9.37.0(supports-color@10.2.2) + eslint: 9.37.0(jiti@2.6.1)(supports-color@10.2.2) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -1914,13 +2225,13 @@ snapshots: dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.46.0(eslint@9.37.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.46.0(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 8.46.0 '@typescript-eslint/typescript-estree': 8.46.0(supports-color@10.2.2)(typescript@5.9.3) - '@typescript-eslint/utils': 8.46.0(eslint@9.37.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.0(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3) debug: 4.4.3(supports-color@10.2.2) - eslint: 9.37.0(supports-color@10.2.2) + eslint: 9.37.0(jiti@2.6.1)(supports-color@10.2.2) ts-api-utils: 2.1.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: @@ -1944,13 +2255,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.46.0(eslint@9.37.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3)': + '@typescript-eslint/utils@8.46.0(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0(supports-color@10.2.2)) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2)) '@typescript-eslint/scope-manager': 8.46.0 '@typescript-eslint/types': 8.46.0 '@typescript-eslint/typescript-estree': 8.46.0(supports-color@10.2.2)(typescript@5.9.3) - eslint: 9.37.0(supports-color@10.2.2) + eslint: 9.37.0(jiti@2.6.1)(supports-color@10.2.2) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -1960,7 +2271,7 @@ snapshots: '@typescript-eslint/types': 8.46.0 eslint-visitor-keys: 4.2.1 - '@vitest/coverage-v8@3.2.4(supports-color@10.2.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.20)(supports-color@10.2.2)(yaml@2.8.1))': + '@vitest/coverage-v8@3.2.4(supports-color@10.2.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.20)(jiti@2.6.1)(supports-color@10.2.2)(yaml@2.8.1))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 @@ -1975,18 +2286,18 @@ snapshots: std-env: 3.9.0 test-exclude: 7.0.1 tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@20.19.20)(supports-color@10.2.2)(yaml@2.8.1) + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@20.19.20)(jiti@2.6.1)(supports-color@10.2.2)(yaml@2.8.1) transitivePeerDependencies: - supports-color - '@vitest/eslint-plugin@1.3.16(eslint@9.37.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.20)(supports-color@10.2.2)(yaml@2.8.1))': + '@vitest/eslint-plugin@1.3.16(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.20)(jiti@2.6.1)(supports-color@10.2.2)(yaml@2.8.1))': dependencies: '@typescript-eslint/scope-manager': 8.46.0 - '@typescript-eslint/utils': 8.46.0(eslint@9.37.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3) - eslint: 9.37.0(supports-color@10.2.2) + '@typescript-eslint/utils': 8.46.0(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3) + eslint: 9.37.0(jiti@2.6.1)(supports-color@10.2.2) optionalDependencies: typescript: 5.9.3 - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@20.19.20)(supports-color@10.2.2)(yaml@2.8.1) + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@20.19.20)(jiti@2.6.1)(supports-color@10.2.2)(yaml@2.8.1) transitivePeerDependencies: - supports-color @@ -1998,13 +2309,13 @@ snapshots: chai: 5.3.3 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(vite@7.1.9(@types/node@20.19.20)(yaml@2.8.1))': + '@vitest/mocker@3.2.4(vite@7.1.9(@types/node@20.19.20)(jiti@2.6.1)(yaml@2.8.1))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.19 optionalDependencies: - vite: 7.1.9(@types/node@20.19.20)(yaml@2.8.1) + vite: 7.1.9(@types/node@20.19.20)(jiti@2.6.1)(yaml@2.8.1) '@vitest/pretty-format@3.2.4': dependencies: @@ -2059,10 +2370,17 @@ snapshots: ansi-styles@6.2.3: {} + ansis@4.2.0: {} + argparse@2.0.1: {} assertion-error@2.0.1: {} + ast-kit@2.1.3: + dependencies: + '@babel/parser': 7.28.4 + pathe: 2.0.3 + ast-v8-to-istanbul@0.3.5: dependencies: '@jridgewell/trace-mapping': 0.3.31 @@ -2071,6 +2389,8 @@ snapshots: balanced-match@1.0.2: {} + birpc@2.6.1: {} + brace-expansion@1.1.12: dependencies: balanced-match: 1.0.2 @@ -2105,6 +2425,10 @@ snapshots: check-error@2.1.1: {} + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + cli-cursor@5.0.0: dependencies: restore-cursor: 5.1.0 @@ -2159,6 +2483,12 @@ snapshots: deep-is@0.1.4: {} + defu@6.1.4: {} + + diff@8.0.2: {} + + dts-resolver@2.1.2: {} + eastasianwidth@0.2.0: {} emoji-regex@10.5.0: {} @@ -2167,6 +2497,8 @@ snapshots: emoji-regex@9.2.2: {} + empathic@2.0.0: {} + environment@1.1.0: {} es-module-lexer@1.7.0: {} @@ -2204,35 +2536,35 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-flat-gitignore@2.1.0(eslint@9.37.0(supports-color@10.2.2)): + eslint-config-flat-gitignore@2.1.0(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2)): dependencies: - '@eslint/compat': 1.4.0(eslint@9.37.0(supports-color@10.2.2)) - eslint: 9.37.0(supports-color@10.2.2) + '@eslint/compat': 1.4.0(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2)) + eslint: 9.37.0(jiti@2.6.1)(supports-color@10.2.2) - eslint-config-prettier@10.1.8(eslint@9.37.0(supports-color@10.2.2)): + eslint-config-prettier@10.1.8(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2)): dependencies: - eslint: 9.37.0(supports-color@10.2.2) + eslint: 9.37.0(jiti@2.6.1)(supports-color@10.2.2) - eslint-plugin-import-lite@0.3.0(eslint@9.37.0(supports-color@10.2.2))(typescript@5.9.3): + eslint-plugin-import-lite@0.3.0(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2))(typescript@5.9.3): dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0(supports-color@10.2.2)) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2)) '@typescript-eslint/types': 8.46.0 - eslint: 9.37.0(supports-color@10.2.2) + eslint: 9.37.0(jiti@2.6.1)(supports-color@10.2.2) optionalDependencies: typescript: 5.9.3 - eslint-plugin-prettier@5.5.4(eslint-config-prettier@10.1.8(eslint@9.37.0(supports-color@10.2.2)))(eslint@9.37.0(supports-color@10.2.2))(prettier@3.6.2): + eslint-plugin-prettier@5.5.4(eslint-config-prettier@10.1.8(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2)))(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2))(prettier@3.6.2): dependencies: - eslint: 9.37.0(supports-color@10.2.2) + eslint: 9.37.0(jiti@2.6.1)(supports-color@10.2.2) prettier: 3.6.2 prettier-linter-helpers: 1.0.0 synckit: 0.11.11 optionalDependencies: - eslint-config-prettier: 10.1.8(eslint@9.37.0(supports-color@10.2.2)) + eslint-config-prettier: 10.1.8(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2)) - eslint-plugin-simple-import-sort@12.1.1(eslint@9.37.0(supports-color@10.2.2)): + eslint-plugin-simple-import-sort@12.1.1(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2)): dependencies: - eslint: 9.37.0(supports-color@10.2.2) + eslint: 9.37.0(jiti@2.6.1)(supports-color@10.2.2) eslint-scope@8.4.0: dependencies: @@ -2243,9 +2575,9 @@ snapshots: eslint-visitor-keys@4.2.1: {} - eslint@9.37.0(supports-color@10.2.2): + eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2): dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0(supports-color@10.2.2)) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2)) '@eslint-community/regexpp': 4.12.1 '@eslint/config-array': 0.21.0(supports-color@10.2.2) '@eslint/config-helpers': 0.4.0 @@ -2280,6 +2612,8 @@ snapshots: minimatch: 3.1.2 natural-compare: 1.4.0 optionator: 0.9.4 + optionalDependencies: + jiti: 2.6.1 transitivePeerDependencies: - supports-color @@ -2365,6 +2699,10 @@ snapshots: get-east-asian-width@1.4.0: {} + get-tsconfig@4.12.0: + dependencies: + resolve-pkg-maps: 1.0.0 + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -2390,6 +2728,8 @@ snapshots: has-flag@4.0.0: {} + hookable@5.5.3: {} + html-escaper@2.0.2: {} husky@9.1.7: {} @@ -2450,12 +2790,16 @@ snapshots: optionalDependencies: '@pkgjs/parseargs': 0.11.0 + jiti@2.6.1: {} + js-tokens@9.0.1: {} js-yaml@4.1.0: dependencies: argparse: 2.0.1 + jsesc@3.1.0: {} + json-buffer@3.0.1: {} json-schema-traverse@0.4.1: {} @@ -2613,12 +2957,18 @@ snapshots: punycode@2.3.1: {} + quansync@0.2.11: {} + queue-microtask@1.2.3: {} + readdirp@4.1.2: {} + require-directory@2.1.1: {} resolve-from@4.0.0: {} + resolve-pkg-maps@1.0.0: {} + restore-cursor@5.1.0: dependencies: onetime: 7.0.0 @@ -2628,6 +2978,45 @@ snapshots: rfdc@1.4.1: {} + rolldown-plugin-dts@0.16.11(rolldown@1.0.0-beta.42)(supports-color@10.2.2)(typescript@5.9.3): + dependencies: + '@babel/generator': 7.28.3 + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 + ast-kit: 2.1.3 + birpc: 2.6.1 + debug: 4.4.3(supports-color@10.2.2) + dts-resolver: 2.1.2 + get-tsconfig: 4.12.0 + magic-string: 0.30.19 + rolldown: 1.0.0-beta.42 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - oxc-resolver + - supports-color + + rolldown@1.0.0-beta.42: + dependencies: + '@oxc-project/types': 0.94.0 + '@rolldown/pluginutils': 1.0.0-beta.42 + ansis: 4.2.0 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.0-beta.42 + '@rolldown/binding-darwin-arm64': 1.0.0-beta.42 + '@rolldown/binding-darwin-x64': 1.0.0-beta.42 + '@rolldown/binding-freebsd-x64': 1.0.0-beta.42 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.42 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.42 + '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.42 + '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.42 + '@rolldown/binding-linux-x64-musl': 1.0.0-beta.42 + '@rolldown/binding-openharmony-arm64': 1.0.0-beta.42 + '@rolldown/binding-wasm32-wasi': 1.0.0-beta.42 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.42 + '@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.42 + '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.42 + rollup@4.52.4: dependencies: '@types/estree': 1.0.8 @@ -2754,6 +3143,8 @@ snapshots: tinyexec@0.3.2: {} + tinyexec@1.0.1: {} + tinyglobby@0.2.15: dependencies: fdir: 6.5.0(picomatch@4.0.3) @@ -2775,38 +3166,70 @@ snapshots: dependencies: typescript: 5.9.3 + tsdown@0.15.6(supports-color@10.2.2)(typescript@5.9.3): + dependencies: + ansis: 4.2.0 + cac: 6.7.14 + chokidar: 4.0.3 + debug: 4.4.3(supports-color@10.2.2) + diff: 8.0.2 + empathic: 2.0.0 + hookable: 5.5.3 + rolldown: 1.0.0-beta.42 + rolldown-plugin-dts: 0.16.11(rolldown@1.0.0-beta.42)(supports-color@10.2.2)(typescript@5.9.3) + semver: 7.7.3 + tinyexec: 1.0.1 + tinyglobby: 0.2.15 + tree-kill: 1.2.2 + unconfig: 7.3.3 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - '@ts-macro/tsc' + - '@typescript/native-preview' + - oxc-resolver + - supports-color + - vue-tsc + tslib@2.8.1: {} type-check@0.4.0: dependencies: prelude-ls: 1.2.1 - typescript-eslint@8.46.0(eslint@9.37.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3): + typescript-eslint@8.46.0(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.46.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3))(eslint@9.37.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3) - '@typescript-eslint/parser': 8.46.0(eslint@9.37.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.46.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3) + '@typescript-eslint/parser': 8.46.0(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3) '@typescript-eslint/typescript-estree': 8.46.0(supports-color@10.2.2)(typescript@5.9.3) - '@typescript-eslint/utils': 8.46.0(eslint@9.37.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3) - eslint: 9.37.0(supports-color@10.2.2) + '@typescript-eslint/utils': 8.46.0(eslint@9.37.0(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3) + eslint: 9.37.0(jiti@2.6.1)(supports-color@10.2.2) typescript: 5.9.3 transitivePeerDependencies: - supports-color typescript@5.9.3: {} + unconfig@7.3.3: + dependencies: + '@quansync/fs': 0.1.5 + defu: 6.1.4 + jiti: 2.6.1 + quansync: 0.2.11 + undici-types@6.21.0: {} uri-js@4.4.1: dependencies: punycode: 2.3.1 - vite-node@3.2.4(@types/node@20.19.20)(supports-color@10.2.2)(yaml@2.8.1): + vite-node@3.2.4(@types/node@20.19.20)(jiti@2.6.1)(supports-color@10.2.2)(yaml@2.8.1): dependencies: cac: 6.7.14 debug: 4.4.3(supports-color@10.2.2) es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.1.9(@types/node@20.19.20)(yaml@2.8.1) + vite: 7.1.9(@types/node@20.19.20)(jiti@2.6.1)(yaml@2.8.1) transitivePeerDependencies: - '@types/node' - jiti @@ -2821,7 +3244,7 @@ snapshots: - tsx - yaml - vite@7.1.9(@types/node@20.19.20)(yaml@2.8.1): + vite@7.1.9(@types/node@20.19.20)(jiti@2.6.1)(yaml@2.8.1): dependencies: esbuild: 0.25.10 fdir: 6.5.0(picomatch@4.0.3) @@ -2832,13 +3255,14 @@ snapshots: optionalDependencies: '@types/node': 20.19.20 fsevents: 2.3.3 + jiti: 2.6.1 yaml: 2.8.1 - vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.20)(supports-color@10.2.2)(yaml@2.8.1): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.20)(jiti@2.6.1)(supports-color@10.2.2)(yaml@2.8.1): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@7.1.9(@types/node@20.19.20)(yaml@2.8.1)) + '@vitest/mocker': 3.2.4(vite@7.1.9(@types/node@20.19.20)(jiti@2.6.1)(yaml@2.8.1)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -2856,8 +3280,8 @@ snapshots: tinyglobby: 0.2.15 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 7.1.9(@types/node@20.19.20)(yaml@2.8.1) - vite-node: 3.2.4(@types/node@20.19.20)(supports-color@10.2.2)(yaml@2.8.1) + vite: 7.1.9(@types/node@20.19.20)(jiti@2.6.1)(yaml@2.8.1) + vite-node: 3.2.4(@types/node@20.19.20)(jiti@2.6.1)(supports-color@10.2.2)(yaml@2.8.1) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 diff --git a/bin/__fixtures__/read-echo.js b/tests/e2e/__fixtures__/read-echo.js similarity index 100% rename from bin/__fixtures__/read-echo.js rename to tests/e2e/__fixtures__/read-echo.js diff --git a/bin/__fixtures__/sleep.js b/tests/e2e/__fixtures__/sleep.js similarity index 100% rename from bin/__fixtures__/sleep.js rename to tests/e2e/__fixtures__/sleep.js diff --git a/bin/index.spec.ts b/tests/e2e/index.spec.ts similarity index 93% rename from bin/index.spec.ts rename to tests/e2e/index.spec.ts index 4536a9d1..064ef2e3 100644 --- a/bin/index.spec.ts +++ b/tests/e2e/index.spec.ts @@ -1,18 +1,15 @@ import { spawn } from 'node:child_process'; -import fs from 'node:fs'; -import os from 'node:os'; -import path from 'node:path'; import readline from 'node:readline'; import { subscribeSpyTo } from '@hirez_io/observer-spy'; import { sendCtrlC, spawnWithWrapper } from 'ctrlc-wrapper'; -import { build } from 'esbuild'; import Rx from 'rxjs'; import { map } from 'rxjs/operators'; import stringArgv from 'string-argv'; -import { afterAll, beforeAll, describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'vitest'; -import { escapeRegExp } from '../lib/utils.js'; +import { escapeRegExp } from '../../lib/utils.js'; +import { version } from '../../package.json' with { type: 'json' }; const isWindows = process.platform === 'win32'; const createKillMessage = (prefix: string, signal: 'SIGTERM' | 'SIGINT' | string) => { @@ -24,37 +21,13 @@ const createKillMessage = (prefix: string, signal: 'SIGTERM' | 'SIGINT' | string return new RegExp(`${escapeRegExp(prefix)} exited with code ${map[signal] ?? signal}`); }; -let tmpDir: string; - -beforeAll(async () => { - // Build 'concurrently' and store it in a temporary directory - tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'concurrently-')); - await build({ - entryPoints: [path.join(__dirname, 'index.ts')], - platform: 'node', - bundle: true, - // it doesn't seem like esbuild is able to change a CJS module to ESM, so target CJS instead. - // https://github.com/evanw/esbuild/issues/1921 - format: 'cjs', - outfile: path.join(tmpDir, 'concurrently.cjs'), - }); - fs.copyFileSync(path.join(__dirname, '..', 'package.json'), path.join(tmpDir, 'package.json')); -}, 8000); - -afterAll(() => { - // Remove the temporary directory where 'concurrently' was stored - if (tmpDir) { - fs.rmSync(tmpDir, { recursive: true }); - } -}); - /** * Creates a child process running 'concurrently' with the given args. * Returns observables for its combined stdout + stderr output, close events, pid, and stdin stream. */ const run = (args: string, ctrlcWrapper?: boolean) => { const spawnFn = ctrlcWrapper ? spawnWithWrapper : spawn; - const child = spawnFn('node', [path.join(tmpDir, 'concurrently.cjs'), ...stringArgv(args)], { + const child = spawnFn('node', ['../../dist/bin.js', ...stringArgv(args)], { cwd: __dirname, env: { ...process.env, @@ -126,9 +99,6 @@ it('prints help when no arguments are passed', async () => { }); describe('has version command', () => { - const pkg = fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf-8'); - const { version } = JSON.parse(pkg); - it.each(['--version', '-V', '-v'])('%s', async (arg) => { const child = run(arg); const log = await child.getLogLines(); diff --git a/tests/package.json b/tests/package.json index f803ee8d..66d310b9 100644 --- a/tests/package.json +++ b/tests/package.json @@ -1,8 +1,6 @@ { + "type": "module", "dependencies": { "concurrently": "workspace:*" - }, - "scripts": { - "test": "pnpm --workspace-root test:smoke" } } diff --git a/tests/setup.ts b/tests/setup.ts new file mode 100644 index 00000000..fef97fe1 --- /dev/null +++ b/tests/setup.ts @@ -0,0 +1,32 @@ +import { build } from 'tsdown'; +import type { TestProject, TestSpecification } from 'vitest/node'; + +function buildProject() { + return build({ clean: false, logLevel: 'silent' }); +} + +function isBuildRequired(testFiles: TestSpecification[]) { + for (const file of testFiles) { + if (file.project.name === 'e2e' || file.project.name === 'smoke') { + return true; + } + } + return false; +} + +export default async function setup(project: TestProject) { + // @ts-expect-error not typed + const pattern: string[] | undefined = project.vitest.filenamePattern; + + const testFiles = await project.vitest.getRelevantTestSpecifications(pattern); + + if (isBuildRequired(testFiles)) { + await buildProject(); + } + + project.onTestsRerun(async (testFiles) => { + if (isBuildRequired(testFiles)) { + await buildProject(); + } + }); +} diff --git a/tests/cjs-import/package.json b/tests/smoke/cjs-import/package.json similarity index 100% rename from tests/cjs-import/package.json rename to tests/smoke/cjs-import/package.json diff --git a/tests/cjs-import/smoke-test.ts b/tests/smoke/cjs-import/smoke-test.ts similarity index 66% rename from tests/cjs-import/smoke-test.ts rename to tests/smoke/cjs-import/smoke-test.ts index 92822be6..727a407c 100644 --- a/tests/cjs-import/smoke-test.ts +++ b/tests/smoke/cjs-import/smoke-test.ts @@ -1,5 +1,8 @@ -import type { ConcurrentlyResult } from 'concurrently'; -import concurrently, { concurrently as concurrently2, createConcurrently } from 'concurrently'; +import concurrently, { + concurrently as concurrently2, + type ConcurrentlyResult, + createConcurrently, +} from 'concurrently'; const _result: ConcurrentlyResult = concurrently(['echo test'], { raw: true, diff --git a/tests/cjs-import/tsconfig.json b/tests/smoke/cjs-import/tsconfig.json similarity index 100% rename from tests/cjs-import/tsconfig.json rename to tests/smoke/cjs-import/tsconfig.json diff --git a/tests/cjs-require/package.json b/tests/smoke/cjs-require/package.json similarity index 100% rename from tests/cjs-require/package.json rename to tests/smoke/cjs-require/package.json diff --git a/tests/cjs-require/smoke-test.ts b/tests/smoke/cjs-require/smoke-test.ts similarity index 100% rename from tests/cjs-require/smoke-test.ts rename to tests/smoke/cjs-require/smoke-test.ts diff --git a/tests/cjs-require/tsconfig.json b/tests/smoke/cjs-require/tsconfig.json similarity index 100% rename from tests/cjs-require/tsconfig.json rename to tests/smoke/cjs-require/tsconfig.json diff --git a/tests/esm/package.json b/tests/smoke/esm/package.json similarity index 100% rename from tests/esm/package.json rename to tests/smoke/esm/package.json diff --git a/tests/esm/smoke-test.ts b/tests/smoke/esm/smoke-test.ts similarity index 66% rename from tests/esm/smoke-test.ts rename to tests/smoke/esm/smoke-test.ts index 92822be6..727a407c 100644 --- a/tests/esm/smoke-test.ts +++ b/tests/smoke/esm/smoke-test.ts @@ -1,5 +1,8 @@ -import type { ConcurrentlyResult } from 'concurrently'; -import concurrently, { concurrently as concurrently2, createConcurrently } from 'concurrently'; +import concurrently, { + concurrently as concurrently2, + type ConcurrentlyResult, + createConcurrently, +} from 'concurrently'; const _result: ConcurrentlyResult = concurrently(['echo test'], { raw: true, diff --git a/tests/esm/tsconfig.json b/tests/smoke/esm/tsconfig.json similarity index 100% rename from tests/esm/tsconfig.json rename to tests/smoke/esm/tsconfig.json diff --git a/tests/smoke-tests.spec.ts b/tests/smoke/index.spec.ts similarity index 69% rename from tests/smoke-tests.spec.ts rename to tests/smoke/index.spec.ts index 6035a951..cfc9d7a1 100644 --- a/tests/smoke-tests.spec.ts +++ b/tests/smoke/index.spec.ts @@ -1,18 +1,10 @@ import { exec as originalExec } from 'node:child_process'; import util from 'node:util'; -import { beforeAll, expect, it } from 'vitest'; +import { expect, it } from 'vitest'; const exec = util.promisify(originalExec); -beforeAll(async () => { - await exec('pnpm run build'); -}, 20_000); - -it('spawns binary', async () => { - await expect(exec('node dist/bin/index.js "echo test"')).resolves.toBeDefined(); -}); - it.each(['cjs-import', 'cjs-require', 'esm'])('loads library in %s context', async (project) => { // Use as separate execs as tsc outputs to stdout, instead of stderr, and so its text isn't shown await exec(`tsc -p ${project}`, { cwd: __dirname }).catch((err) => Promise.reject(err.stdout)); diff --git a/tsconfig.json b/tsconfig.json index 9b450aa5..3a9e88ef 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,13 +1,10 @@ { "compilerOptions": { "lib": ["es2023"], - "module": "node20", - - "outDir": "dist", - "declaration": true, - + "module": "preserve", + "target": "es2023", "strict": true, "skipLibCheck": true }, - "include": ["./bin", "./lib"] + "exclude": ["dist", "**/smoke-test.ts"] } diff --git a/tsdown.config.ts b/tsdown.config.ts new file mode 100644 index 00000000..13846faf --- /dev/null +++ b/tsdown.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from 'tsdown'; + +export default defineConfig({ + entry: { + bin: 'bin/index.ts', + lib: 'lib/index.ts', + }, +}); diff --git a/vitest.config.ts b/vitest.config.ts index 3f50728e..47ef6a72 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -7,19 +7,24 @@ export default defineConfig({ // lcov is used for coveralls reporter: ['text', 'html', 'lcov'], }, + globalSetup: 'tests/setup.ts', projects: [ { - extends: true, test: { name: 'unit', - include: ['{bin,lib}/**/*.spec.ts'], + include: ['lib/**/*.spec.ts'], + }, + }, + { + test: { + name: 'e2e', + include: ['tests/e2e/*.spec.ts'], }, }, { - extends: true, test: { name: 'smoke', - include: ['tests/**/*.spec.ts'], + include: ['tests/smoke/*.spec.ts'], }, }, ],