diff --git a/.changeset/sync-module-hooks.md b/.changeset/sync-module-hooks.md new file mode 100644 index 0000000..4edc53a --- /dev/null +++ b/.changeset/sync-module-hooks.md @@ -0,0 +1,7 @@ +--- +'hot-hook': minor +--- + +Use synchronous `module.registerHooks()` on Node.js >= 22.22.3, 24.11.1, 25.1.0 and 26 instead of the deprecated `module.register()` (DEP0205). Older Node.js versions fall back to `module.register()`, since their `registerHooks()` breaks CommonJS loading when combined with `module.register()` hooks such as ts-node's. + +With in-thread hooks, `require()` calls also go through hot-hook. diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 7ed0f0c..0dca79e 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -49,7 +49,8 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] - node: [22, 24] + # 22.15 uses the `module.register()` fallback, see `canUseSyncHooks()` + node: ['22.15', 22, 24, 26] runs-on: ${{ matrix.os }} timeout-minutes: 10 diff --git a/README.md b/README.md index df0c3a7..80af081 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ await hot.init({ }) ``` -The `hot.init` function internally call [`register`](https://nodejs.org/api/module.html#moduleregisterspecifier-parenturl-options) from `node:module` to hook into the module loading process. This is why you need to call it as early as possible, otherwise modules imported before the call to `hot.init` will not benefit from hot module replacement. +The `hot.init` function internally calls [`registerHooks`](https://nodejs.org/api/module.html#moduleregisterhooksoptions) from `node:module` to hook into the module loading process. On Node.js versions older than 22.22.3, 24.11.1 or 25.1.0, it falls back to [`register`](https://nodejs.org/api/module.html#moduleregisterspecifier-parenturl-options). This is why you need to call it as early as possible, otherwise modules imported before the call to `hot.init` will not benefit from hot module replacement. Next, you need to include the types for `import.meta.hot` in your project. To do this, add the following code in a `.d.ts` file or in the `types` property of your `tsconfig.json`. diff --git a/package.json b/package.json index c005d6e..06c1b19 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "@types/fs-extra": "^11.0.4", "@types/node": "^22.19.2", "@types/supertest": "^6.0.3", - "c8": "^10.1.3", + "c8": "^12.0.0", "del-cli": "^6.0.0", "desm": "^1.3.1", "eslint": "^9.39.2", diff --git a/packages/hot_hook/src/dynamic_import_checker.ts b/packages/hot_hook/src/dynamic_import_checker.ts index 3965018..25d80fe 100644 --- a/packages/hot_hook/src/dynamic_import_checker.ts +++ b/packages/hot_hook/src/dynamic_import_checker.ts @@ -1,5 +1,11 @@ -import { readFile } from 'node:fs/promises' -import { parseImports } from 'parse-imports' +import { readFileSync } from 'node:fs' +import { parseImportsSync, wasmLoadPromise } from 'parse-imports' + +/** + * `parseImportsSync` needs the lexer WASM to be loaded. The check runs inside + * module hooks, which are synchronous with `module.registerHooks()`. + */ +await wasmLoadPromise /** * This class is responsible for checking if a given specifier @@ -13,14 +19,14 @@ import { parseImports } from 'parse-imports' export class DynamicImportChecker { private cache: Map> = new Map() - async ensureFileIsImportedDynamicallyFromParent(parentPath: string, specifier: string) { + ensureFileIsImportedDynamicallyFromParent(parentPath: string, specifier: string) { const cacheKey = parentPath if (this.cache.has(cacheKey) && this.cache.get(cacheKey)!.has(specifier)) { return this.cache.get(cacheKey)!.get(specifier)! } - const parentCode = await readFile(parentPath, 'utf-8') - const imports = [...(await parseImports(parentCode))] + const parentCode = readFileSync(parentPath, 'utf-8') + const imports = [...parseImportsSync(parentCode)] const matchingImport = imports.find((importStatement) => { return importStatement.moduleSpecifier.value === specifier diff --git a/packages/hot_hook/src/hot.ts b/packages/hot_hook/src/hot.ts index d80fbd4..30e8767 100644 --- a/packages/hot_hook/src/hot.ts +++ b/packages/hot_hook/src/hot.ts @@ -1,9 +1,26 @@ -import { register } from 'node:module' +import module from 'node:module' import { MessageChannel } from 'node:worker_threads' +import type { LoadHookSync, ResolveHookSync } from 'node:module' import debug from './debug.js' import type { InitOptions, InitializeHookOptions, MessageChannelMessage } from './types.js' +/** + * Whether this Node.js version can run hot-hook with `module.registerHooks()`. + * + * `registerHooks()` exists since 22.15, but until 22.22.3, 24.11.1 and 25.1.0, + * a synchronous `load` hook fails on CommonJS modules when hooks from + * `module.register()` are also registered, like ts-node's or older tsx's. + */ +function canUseSyncHooks() { + const [major, minor, patch] = process.versions.node.split('.').map(Number) + if (major >= 26) return true + + const minimum = ({ 22: [22, 3], 24: [11, 1], 25: [1, 0] } as Record)[major] + if (!minimum) return false + return minor > minimum[0] || (minor === minimum[0] && patch >= minimum[1]) +} + class Hot { #options!: InitOptions #messageChannel!: MessageChannel @@ -72,26 +89,50 @@ class Hot { /** * First, we setup a message channel to be able to communicate - * between the hook and the application process since hooks - * are running in a worker thread + * between the hook and the application process, since with the + * `module.register()` fallback hooks are running in a worker thread */ this.#messageChannel = new MessageChannel() - register('hot-hook/loader', { - parentURL: import.meta.url, - transferList: [this.#messageChannel.port2], - data: { - root: this.#options.root, - watch: this.#options.watch, - ignore: this.#options.ignore, - restart: this.#options.restart, - boundaries: this.#options.boundaries, - messagePort: this.#messageChannel.port2, - rootDirectory: this.#options.rootDirectory, - throwWhenBoundariesAreNotDynamicallyImported: - this.#options.throwWhenBoundariesAreNotDynamicallyImported, - } satisfies InitializeHookOptions, - }) + const data: InitializeHookOptions = { + root: this.#options.root, + watch: this.#options.watch, + ignore: this.#options.ignore, + restart: this.#options.restart, + boundaries: this.#options.boundaries, + messagePort: this.#messageChannel.port2, + rootDirectory: this.#options.rootDirectory, + throwWhenBoundariesAreNotDynamicallyImported: + this.#options.throwWhenBoundariesAreNotDynamicallyImported, + } + + /** + * Prefer synchronous in-thread hooks since `module.register()` is + * deprecated (DEP0205). The loader then runs on this thread but keeps + * using the message channel, like the off-thread fallback. + */ + if (canUseSyncHooks()) { + const { HotHookLoader } = await import('./loader.js') + const loader = new HotHookLoader(data) + + /** + * Safe casts: hooks return synchronously when `nextResolve`/`nextLoad` + * do, which is always the case with `registerHooks()` + */ + module.registerHooks({ + resolve: loader.resolve as ResolveHookSync, + load: loader.load as LoadHookSync, + }) + + this.#messageChannel.port2.unref() + await loader.whenWatcherReady() + } else { + module.register('hot-hook/loader', { + parentURL: import.meta.url, + transferList: [this.#messageChannel.port2], + data, + }) + } this.#messageChannel.port1.on('message', this.#onMessage.bind(this)) this.#messageChannel.port1.unref() diff --git a/packages/hot_hook/src/loader.ts b/packages/hot_hook/src/loader.ts index 9d9d78b..2842766 100644 --- a/packages/hot_hook/src/loader.ts +++ b/packages/hot_hook/src/loader.ts @@ -1,13 +1,21 @@ +import chokidar from 'chokidar' import { fileURLToPath } from 'node:url' -import chokidar, { type FSWatcher } from 'chokidar' import { access, realpath } from 'node:fs/promises' import type { MessagePort } from 'node:worker_threads' import { resolve as pathResolve, dirname } from 'node:path' -import type { InitializeHook, LoadHook, ResolveHook } from 'node:module' +import type { + LoadHook, + ResolveHook, + InitializeHook, + ResolveFnOutput, + ResolveHookContext, +} from 'node:module' import debug from './debug.js' import { Matcher } from './matcher.js' +import { then } from './maybe_async.js' import DependencyTree from './dependency_tree.js' +import { WatcherThread } from './watcher_thread.js' import { shiftInlineSourceMap } from './source_map.js' import type { InitializeHookOptions } from './types.js' import { DynamicImportChecker } from './dynamic_import_checker.js' @@ -18,50 +26,60 @@ export class HotHookLoader { #projectRoot!: string #reloadMatcher!: Matcher #messagePort?: MessagePort - #watcher?: FSWatcher + #watcher?: { add(paths: string | string[]): unknown } + #offThread: boolean #pathIgnoredMatcher!: Matcher #dependencyTree: DependencyTree #hardcodedBoundaryMatcher!: Matcher #dynamicImportChecker!: DynamicImportChecker #boundFileChangeHandler = this.#onFileChange.bind(this) + #watcherReady: Promise = Promise.resolve() - constructor(options: InitializeHookOptions) { + /** + * `offThread` is true when hooks run on the `module.register()` hooks thread + */ + constructor(options: InitializeHookOptions, offThread = false) { this.#options = options + this.#offThread = offThread this.#messagePort = options.messagePort this.#projectRoot = options.rootDirectory! - if (options.root) this.#initialize(options.root) - this.#dependencyTree = new DependencyTree({ root: options.root }) this.#dynamicImportChecker = new DynamicImportChecker() + + /** + * Start watching the `restart` files right away when the project root is + * known, so the initial scan can complete before the application runs. + */ + if (options.root || options.rootDirectory) this.#initialize(options.root) + this.#messagePort?.on('message', (message) => this.#onMessage(message)) } /** - * Initialize the class with the provided root path. + * Resolves once the watcher has scanned the files it watches so far. + * + * Waiting for it avoids missing changes made right after the application + * starts. */ - #initialize(root: string) { - this.#projectRoot = this.#projectRoot ?? dirname(root) - this.#reloadMatcher = new Matcher(this.#projectRoot, this.#options.restart || []) - this.#pathIgnoredMatcher = new Matcher(this.#projectRoot, this.#options.ignore) - this.#hardcodedBoundaryMatcher = new Matcher(this.#projectRoot, this.#options.boundaries) - - if (this.#options.watch !== false) { - this.#cleanupWatcher() - this.#watcher = this.#createWatcher().add([root, ...(this.#options.restart || [])]) - } + whenWatcherReady() { + return this.#watcherReady } /** - * Clean up the existing watcher and its event listeners + * Initialize the matchers and the watcher. Called again with the root path + * once it is resolved. */ - #cleanupWatcher() { - if (!this.#watcher) return + #initialize(root?: string) { + this.#projectRoot = this.#projectRoot ?? dirname(root!) + this.#reloadMatcher = new Matcher(this.#projectRoot, this.#options.restart || []) + this.#pathIgnoredMatcher = new Matcher(this.#projectRoot, this.#options.ignore) + this.#hardcodedBoundaryMatcher = new Matcher(this.#projectRoot, this.#options.boundaries) + + if (this.#options.watch === false) return - this.#watcher.off('change', this.#boundFileChangeHandler) - this.#watcher.off('unlink', this.#boundFileChangeHandler) - this.#watcher.close() - this.#watcher = undefined + this.#watcher ??= this.#createWatcher(this.#options.restart || []) + if (root) this.#watcher.add(root) } /** @@ -164,10 +182,12 @@ export class HotHookLoader { } /** - * Create the chokidar watcher instance. + * Create the watcher. With in-thread hooks it runs on its own thread, see + * `WatcherThread`. The off-thread hooks thread already plays that role. */ - #createWatcher() { - const watcher = chokidar.watch([]) + #createWatcher(paths: string[]) { + const watcher = this.#offThread ? chokidar.watch(paths) : new WatcherThread(paths) + this.#watcherReady = new Promise((resolve) => watcher.once('ready', () => resolve())) watcher.on('change', this.#boundFileChangeHandler) watcher.on('unlink', this.#boundFileChangeHandler) @@ -210,43 +230,49 @@ export class HotHookLoader { * The load hook. * We use it mainly for adding the import.meta.hot object to the module. */ - load: LoadHook = async (url, context, nextLoad) => { + load: LoadHook = (url, context, nextLoad) => { const parsedUrl = new URL(url) if (parsedUrl.searchParams.has('hot-hook')) { parsedUrl.searchParams.delete('hot-hook') url = parsedUrl.href } + /** + * Copy instead of deleting: in-thread hooks receive frozen import attributes + */ if (context.importAttributes?.hot) { - delete context.importAttributes.hot + const { hot: _hot, ...importAttributes } = context.importAttributes + context = { ...context, importAttributes } } - const result = await nextLoad(url, context) - if (result.format !== 'module') return result + return then(nextLoad(url, context), (result) => { + if (result.format !== 'module') return result - /** - * Decode explicitly: `source` can be a Uint8Array, and `toString()` - * would produce its comma-separated bytes - */ - const source = - typeof result.source === 'string' ? result.source : new TextDecoder().decode(result.source) + /** + * Decode explicitly: `source` can be a Uint8Array, e.g. when a + * `module.register()` hook runs after in-thread hooks, and `toString()` + * would produce its comma-separated bytes + */ + const source = + typeof result.source === 'string' ? result.source : new TextDecoder().decode(result.source) - /** - * A module can only access its `import.meta` by writing it in its own - * source (`eval` and `new Function` can't), so modules without it can't - * observe `import.meta.hot` and are loaded unchanged. Matching only - * `import.meta.hot` would miss accesses like `"hot" in import.meta` - * used by @adonisjs/fold. - */ - if (!source.includes('import.meta')) return result + /** + * A module can only access its `import.meta` by writing it in its own + * source (`eval` and `new Function` can't), so modules without it can't + * observe `import.meta.hot` and are loaded unchanged. Matching only + * `import.meta.hot` would miss accesses like `"hot" in import.meta` + * used by @adonisjs/fold. + */ + if (!source.includes('import.meta')) return result - /** - * The helpers are prepended on line 1, so shift the module's inline - * source map (from tsx, ts-node, ...) to keep positions exact. - */ - const hotSource = this.#getImportMetaHotSource() - result.source = shiftInlineSourceMap(hotSource + source, hotSource.length) - return result + /** + * The helpers are prepended on line 1, so shift the module's inline + * source map (from tsx, ts-node, ...) to keep positions exact. + */ + const hotSource = this.#getImportMetaHotSource() + result.source = shiftInlineSourceMap(hotSource + source, hotSource.length) + return result + }) } /** @@ -255,14 +281,28 @@ export class HotHookLoader { * - Adding the hot-hook query parameter to the URL ( to getting a fresh version ) * - And adding files to the watcher */ - resolve: ResolveHook = async (specifier, context, nextResolve) => { + resolve: ResolveHook = (specifier, context, nextResolve) => { const parentUrl = (context.parentURL && new URL(context.parentURL)) as URL if (parentUrl?.searchParams.has('hot-hook')) { parentUrl.searchParams.delete('hot-hook') context = { ...context, parentURL: parentUrl.href } } - const result = await nextResolve(specifier, context) + return then(nextResolve(specifier, context), (result) => + this.#onResolved(specifier, context, parentUrl, result), + ) + } + + /** + * Track the resolved file in the dependency tree and the watcher, and + * add the version query parameter to its URL + */ + #onResolved( + specifier: string, + context: ResolveHookContext, + parentUrl: URL | undefined, + result: ResolveFnOutput, + ): ResolveFnOutput { const resultUrl = new URL(result.url) if (resultUrl.protocol !== 'file:') { @@ -294,10 +334,7 @@ export class HotHookLoader { * from the parent file. Otherwise, hot-hook can't invalidate the file */ const isImportedDynamically = - await this.#dynamicImportChecker.ensureFileIsImportedDynamicallyFromParent( - parentPath, - specifier, - ) + this.#dynamicImportChecker.ensureFileIsImportedDynamicallyFromParent(parentPath, specifier) /** * Throw an error if not dynamically imported and the option is set @@ -332,7 +369,7 @@ export class HotHookLoader { let loader!: HotHookLoader export const initialize: InitializeHook = async (data: InitializeHookOptions) => { - loader = new HotHookLoader(data) + loader = new HotHookLoader(data, true) } export const load: LoadHook = (...args) => loader?.load(...args) export const resolve: ResolveHook = (...args) => loader?.resolve(...args) diff --git a/packages/hot_hook/src/maybe_async.ts b/packages/hot_hook/src/maybe_async.ts new file mode 100644 index 0000000..3ebeee0 --- /dev/null +++ b/packages/hot_hook/src/maybe_async.ts @@ -0,0 +1,10 @@ +/** + * Applies `fn` to `value`, or to its resolved value when it is a promise. + * + * This lets the same hooks run synchronously with `module.registerHooks()`, + * where `nextResolve`/`nextLoad` return plain objects, and asynchronously with + * the `module.register()` fallback, where they return promises. + */ +export function then(value: T | Promise, fn: (value: T) => R): R | Promise { + return value instanceof Promise ? value.then(fn) : fn(value) +} diff --git a/packages/hot_hook/src/watcher_thread.ts b/packages/hot_hook/src/watcher_thread.ts new file mode 100644 index 0000000..3796801 --- /dev/null +++ b/packages/hot_hook/src/watcher_thread.ts @@ -0,0 +1,58 @@ +import chokidar from 'chokidar' +import { EventEmitter } from 'node:events' +import { Worker, parentPort, workerData } from 'node:worker_threads' + +import debug from './debug.js' + +/** + * Runs a chokidar watcher on a dedicated worker thread and re-emits its + * `change`, `unlink` and `ready` events. + * + * Used with in-thread hooks: on the main thread, the watcher would keep the + * process alive and could only scan files while the application is idle. + * The worker is unref'd after its initial scan, so it does not keep the + * process alive. + */ +export class WatcherThread extends EventEmitter { + #worker: Worker + + constructor(paths: string[]) { + super() + + /** + * Empty `execArgv` so preloads like `--import=hot-hook/register` don't run + * again in the worker + */ + this.#worker = new Worker(new URL(import.meta.url), { + execArgv: [], + workerData: { hotHookWatcherPaths: paths }, + }) + this.#worker.on('message', ({ event, path }) => this.emit(event, path)) + this.#worker.on('error', (error) => debug('Watcher thread error %O', error)) + + /** + * Never leave `hot.init()` waiting if the worker dies before its scan + */ + this.#worker.once('exit', () => this.emit('ready')) + + /** + * Keep the process alive until the initial scan is done, so that + * `hot.init()` can wait for it + */ + this.once('ready', () => this.#worker.unref()) + } + + add(paths: string | string[]) { + this.#worker.postMessage(paths) + return this + } +} + +if (workerData?.hotHookWatcherPaths) { + const watcher = chokidar.watch(workerData.hotHookWatcherPaths) + watcher.on('change', (path) => parentPort!.postMessage({ event: 'change', path })) + watcher.on('unlink', (path) => parentPort!.postMessage({ event: 'unlink', path })) + watcher.on('ready', () => parentPort!.postMessage({ event: 'ready' })) + watcher.on('error', (error) => debug('Watcher error %O', error)) + parentPort!.on('message', (paths) => watcher.add(paths)) +} diff --git a/packages/hot_hook/tests/register.spec.ts b/packages/hot_hook/tests/register.spec.ts index e854688..93d9057 100644 --- a/packages/hot_hook/tests/register.spec.ts +++ b/packages/hot_hook/tests/register.spec.ts @@ -1,5 +1,6 @@ import { join } from 'node:path' import { pEvent } from 'p-event' +import pTimeout from 'p-timeout' import supertest from 'supertest' import { test } from '@japa/runner' import { setTimeout } from 'node:timers/promises' @@ -45,6 +46,46 @@ test.group('Register', () => { await supertest('http://localhost:3333').get('/').expect(200).expect('Hello World! Updated new') }) + test('works after a loader registered with module.register()', async ({ fs }) => { + await fakeInstall(fs.basePath) + + /** + * Like ts-node, preloaded before hot-hook + */ + await fs.create( + 'async-loader.js', + `import { register } from 'node:module' + register('data:text/javascript,export async function load(url, context, next) { return next(url, context) }')`, + ) + + await fs.createJson('package.json', { type: 'module' }) + await fs.create( + 'server.js', + `import * as http from 'http' + + const server = http.createServer(async (request, response) => { + const app = await import('./app.js', import.meta.hot?.boundary) + await app.default(request, response) + }) + + server.listen(3333, () => console.log('Server is running'))`, + ) + + await createHandlerFile({ path: 'app.js', response: 'Hello World!' }) + + const server = runProcess('server.js', { + cwd: fs.basePath, + nodeOptions: ['--import=./async-loader.js', '--import=hot-hook/register'], + }) + + await server.waitForOutput('Server is running') + await supertest('http://localhost:3333').get('/').expect(200).expect('Hello World!') + + await createHandlerFile({ path: 'app.js', response: 'Hello World! Updated' }) + await setTimeout(100) + await supertest('http://localhost:3333').get('/').expect(200).expect('Hello World! Updated') + }) + test('send full reload message', async ({ fs, assert }) => { await fakeInstall(fs.basePath) @@ -301,4 +342,32 @@ test.group('Register', () => { await setTimeout(100) await supertest('http://localhost:3333').get('/').expect(200).expect('Hello World! Updated') }) + + test('exits when the application is done, without deprecation warnings', async ({ + fs, + assert, + }) => { + await fakeInstall(fs.basePath) + + await fs.createJson('package.json', { + type: 'module', + hotHook: { boundaries: ['./app.js'] }, + }) + await fs.create('server.js', `await import('./app.js'); console.log('done')`) + await createHandlerFile({ path: 'app.js', response: 'Hello World!' }) + + const server = runProcess('server.js', { + cwd: fs.basePath, + nodeOptions: ['--import=hot-hook/register'], + }) + + let stderr = '' + server.child.stderr?.on('data', (data) => (stderr += data)) + + await server.waitForOutput('done') + await pTimeout(server.waitForExit(), { milliseconds: 2000 }) + + assert.equal(server.child.exitCode, 0) + assert.notInclude(stderr, 'DEP0205') + }) }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 76e1de9..9f53a05 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -42,8 +42,8 @@ importers: specifier: ^6.0.3 version: 6.0.3 c8: - specifier: ^10.1.3 - version: 10.1.3 + specifier: ^12.0.0 + version: 12.0.0 del-cli: specifier: ^6.0.0 version: 6.0.0 @@ -1057,10 +1057,6 @@ packages: '@types/node': optional: true - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} - '@istanbuljs/schema@0.1.3': resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} engines: {node: '>=8'} @@ -1189,9 +1185,6 @@ packages: '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - '@jridgewell/trace-mapping@0.3.25': - resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} @@ -1244,10 +1237,6 @@ packages: '@pinojs/redact@0.4.0': resolution: {integrity: sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==} - '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - '@pkgr/core@0.1.2': resolution: {integrity: sha512-fdDH1LSGfZdTH2sxdpVMw31BanV28K/Gry0cVFxaNP77neJSkd82mM8ErPNYs9e+0O7SdHBLTDzDgwUuy18RnQ==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} @@ -2015,6 +2004,10 @@ packages: resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} engines: {node: '>=12'} + ansi-regex@6.5.0: + resolution: {integrity: sha512-zhvbbbdt1kbw7EJ9OQoxmQcuaNR9P5kTj7e/YdmOSU10aHWbycofJxA6jKfoEy3vlLdctOF9ZHaxLtmSm998wQ==} + engines: {node: '>=12'} + ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} @@ -2091,6 +2084,10 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + better-path-resolve@1.0.0: resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} engines: {node: '>=4'} @@ -2108,6 +2105,10 @@ packages: brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + brace-expansion@5.0.12: + resolution: {integrity: sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==} + engines: {node: 20 || >=22} + braces@3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} engines: {node: '>=8'} @@ -2129,9 +2130,9 @@ packages: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} - c8@10.1.3: - resolution: {integrity: sha512-LvcyrOAaOnrrlMpW22n690PUvxiq4Uf9WMhQwNJ9vgagkL/ph1+D4uvjvDA5XCbykrc0sx+ay6pVi9YZ1GnhyA==} - engines: {node: '>=18'} + c8@12.0.0: + resolution: {integrity: sha512-4zpJvrd1nKWutnnKC2pXkFmb6iM1l+ffN//o1CzlTNwW7GSOs9a1xrLqkC48nU8oEkjmPZLPiwMsIaOvoF4Pqg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} hasBin: true peerDependencies: monocart-coverage-reports: ^2 @@ -2243,9 +2244,9 @@ packages: resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} engines: {node: '>=18'} - cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} + cliui@9.0.1: + resolution: {integrity: sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==} + engines: {node: '>=20'} clone-deep@4.0.1: resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} @@ -2511,9 +2512,6 @@ packages: duplexer@0.1.2: resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} @@ -2530,9 +2528,6 @@ packages: emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - encodeurl@2.0.0: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} @@ -2587,10 +2582,6 @@ packages: engines: {node: '>=18'} hasBin: true - escalade@3.1.2: - resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} - engines: {node: '>=6'} - escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -2742,6 +2733,7 @@ packages: eslint@9.39.2: resolution: {integrity: sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true peerDependencies: jiti: '*' @@ -2989,6 +2981,10 @@ packages: resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==} engines: {node: '>=18'} + get-east-asian-width@1.7.0: + resolution: {integrity: sha512-XjH1AECxf0giL2V1aU8vKyRR2ppRUb5c0EvT7zuJTokQ74bNo52zOtghqdWIqrhUD79fo3x0WfKZdOqxF6LG1Q==} + engines: {node: '>=18'} + get-func-name@2.0.2: resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} @@ -3032,9 +3028,9 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} - glob@10.4.5: - resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} - hasBin: true + glob@13.0.7: + resolution: {integrity: sha512-wfsFgXQ8A3SEI9XGf7Nl3Y9l7ffSrGh7SUCT7vU/2CzYPep9kjxAn1S40F9OPKxAMGCVl7HtNlJhrCJUeUq83g==} + engines: {node: 18 || 20 || >=22} globals@11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} @@ -3298,9 +3294,6 @@ packages: resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} engines: {node: '>=8'} - jackspeak@3.4.3: - resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - jest-diff@25.5.0: resolution: {integrity: sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==} engines: {node: '>= 8.3'} @@ -3491,10 +3484,6 @@ packages: loupe@3.1.0: resolution: {integrity: sha512-qKl+FrLXUhFuHUoDJG7f8P8gEMHq9NFS0c6ghXG1J0rldmZFQZoNVv/vyirE9qwCIhWZDsvEFd1sbFu3GvRQFg==} - lru-cache@10.2.0: - resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==} - engines: {node: 14 || >=16.14} - lru-cache@11.2.4: resolution: {integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==} engines: {node: 20 || >=22} @@ -3502,10 +3491,6 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} - magic-string@0.30.11: resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} @@ -3603,6 +3588,10 @@ packages: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} + minimatch@10.2.6: + resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==} + engines: {node: 18 || 20 || >=22} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -3613,8 +3602,8 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} engines: {node: '>=16 || 14 >=14.17'} mkdirp@3.0.1: @@ -3789,9 +3778,6 @@ packages: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} - package-json-from-dist@1.0.1: - resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} - package-manager-detector@0.2.0: resolution: {integrity: sha512-E385OSk9qDcXhcM9LNSe4sdhx8a9mAPrZ4sMLW+tmxl5ZuGtPUcdFu+MPP2jbgiWAZ6Pfe5soGFMd+0Db5Vrog==} @@ -3850,9 +3836,9 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - path-scurry@1.11.1: - resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} - engines: {node: '>=16 || 14 >=14.18'} + path-scurry@2.0.2: + resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} + engines: {node: 18 || 20 || >=22} path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} @@ -4085,10 +4071,6 @@ packages: resolution: {integrity: sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==} hasBin: true - require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - require-from-string@2.0.2: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} @@ -4167,11 +4149,6 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.6.0: - resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} - engines: {node: '>=10'} - hasBin: true - semver@7.7.2: resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} engines: {node: '>=10'} @@ -4325,10 +4302,6 @@ packages: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} - string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} - string-width@7.1.0: resolution: {integrity: sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==} engines: {node: '>=18'} @@ -4337,6 +4310,10 @@ packages: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} + string-width@8.3.0: + resolution: {integrity: sha512-ZbmZM0JCihQN91dWnxoipT2KOEyHqEyfRXUyjuRhW8b/xnqPDoq4gWEVApTVa9db2wN8mmoikgFBbjh71+cGeQ==} + engines: {node: '>=20'} + strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -4345,6 +4322,10 @@ packages: resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} engines: {node: '>=12'} + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} @@ -4440,9 +4421,9 @@ packages: resolution: {integrity: sha512-rcdty1xZ2/BkWa4ANjWRp4JGpda2quksXIHgn5TMjNBPZfwzJIgR68DKfSYiTL+CZWowDX/sbOo5ME/FRURvYQ==} engines: {node: '>=18'} - test-exclude@7.0.1: - resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} - engines: {node: '>=18'} + test-exclude@8.0.0: + resolution: {integrity: sha512-ZOffsNrXYggvU1mDGHk54I96r26P8SyMjO5slMKSc7+IWmtB/MQKnEC2fP51imB3/pT6YK5cT5E8f+Dd9KdyOQ==} + engines: {node: 20 || >=22} thread-stream@3.1.0: resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} @@ -4643,6 +4624,7 @@ packages: uuid@9.0.1: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028). hasBin: true v8-compile-cache-lib@3.0.1: @@ -4761,14 +4743,6 @@ packages: wordwrap@1.0.0: resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - - wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} - wrap-ansi@9.0.0: resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==} engines: {node: '>=18'} @@ -4787,16 +4761,17 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} - yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} + yargs-parser@22.0.0: + resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + + yargs@18.2.0: + resolution: {integrity: sha512-9OpKOLeaoNFecEp7P6iYbzze/5CqWoH7N3SMs/6y1XF4nMvFMspEGZzJ6uFi9MmQwXhyzqYoSEKO3tvA3Z/o2w==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} yn@3.1.1: resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} @@ -5034,7 +5009,7 @@ snapshots: '@ampproject/remapping@2.3.0': dependencies: '@jridgewell/gen-mapping': 0.3.5 - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/trace-mapping': 0.3.31 '@antfu/install-pkg@0.4.1': dependencies: @@ -5108,7 +5083,7 @@ snapshots: dependencies: '@babel/types': 7.26.0 '@jridgewell/gen-mapping': 0.3.5 - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/trace-mapping': 0.3.31 jsesc: 2.5.2 '@babel/generator@7.28.5': @@ -5733,15 +5708,6 @@ snapshots: optionalDependencies: '@types/node': 22.19.2 - '@isaacs/cliui@8.0.2': - dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 - '@istanbuljs/schema@0.1.3': {} '@japa/assert@3.0.0(@japa/runner@3.1.4)(openapi-types@12.1.3)': @@ -5884,19 +5850,19 @@ snapshots: '@jridgewell/gen-mapping@0.3.13': dependencies: - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/sourcemap-codec': 1.5.5 '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/gen-mapping@0.3.5': dependencies: '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/remapping@2.3.5': dependencies: '@jridgewell/gen-mapping': 0.3.5 - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/resolve-uri@3.1.2': {} @@ -5908,15 +5874,10 @@ snapshots: '@jridgewell/sourcemap-codec@1.5.5': {} - '@jridgewell/trace-mapping@0.3.25': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping@0.3.31': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/sourcemap-codec': 1.5.5 '@jridgewell/trace-mapping@0.3.9': dependencies: @@ -6004,9 +5965,6 @@ snapshots: '@pinojs/redact@0.4.0': {} - '@pkgjs/parseargs@0.11.0': - optional: true - '@pkgr/core@0.1.2': {} '@pkgr/core@0.2.4': {} @@ -6538,7 +6496,7 @@ snapshots: fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 - semver: 7.6.0 + semver: 7.7.2 ts-api-utils: 2.1.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: @@ -6834,6 +6792,8 @@ snapshots: ansi-regex@6.0.1: {} + ansi-regex@6.5.0: {} + ansi-styles@3.2.1: dependencies: color-convert: 1.9.3 @@ -6917,6 +6877,8 @@ snapshots: balanced-match@1.0.2: {} + balanced-match@4.0.4: {} + better-path-resolve@1.0.0: dependencies: is-windows: 1.0.2 @@ -6934,6 +6896,10 @@ snapshots: dependencies: balanced-match: 1.0.2 + brace-expansion@5.0.12: + dependencies: + balanced-match: 4.0.4 + braces@3.0.2: dependencies: fill-range: 7.0.1 @@ -6953,7 +6919,7 @@ snapshots: bytes@3.1.2: {} - c8@10.1.3: + c8@12.0.0: dependencies: '@bcoe/v8-coverage': 1.0.2 '@istanbuljs/schema': 0.1.3 @@ -6962,9 +6928,9 @@ snapshots: istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-reports: 3.1.7 - test-exclude: 7.0.1 + test-exclude: 8.0.0 v8-to-istanbul: 9.2.0 - yargs: 17.7.2 + yargs: 18.2.0 yargs-parser: 21.1.1 cac@6.7.14: {} @@ -7064,13 +7030,13 @@ snapshots: cli-truncate@4.0.0: dependencies: slice-ansi: 5.0.0 - string-width: 7.1.0 + string-width: 7.2.0 - cliui@8.0.1: + cliui@9.0.1: dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 + string-width: 7.2.0 + strip-ansi: 7.1.0 + wrap-ansi: 9.0.0 clone-deep@4.0.1: dependencies: @@ -7292,8 +7258,6 @@ snapshots: duplexer@0.1.2: {} - eastasianwidth@0.2.0: {} - ee-first@1.1.1: {} electron-to-chromium@1.5.161: {} @@ -7304,8 +7268,6 @@ snapshots: emoji-regex@8.0.0: {} - emoji-regex@9.2.2: {} - encodeurl@2.0.0: {} end-of-stream@1.4.4: @@ -7404,8 +7366,6 @@ snapshots: '@esbuild/win32-ia32': 0.27.1 '@esbuild/win32-x64': 0.27.1 - escalade@3.1.2: {} - escalade@3.2.0: {} escape-string-regexp@1.0.5: {} @@ -7892,6 +7852,8 @@ snapshots: get-east-asian-width@1.2.0: {} + get-east-asian-width@1.7.0: {} + get-func-name@2.0.2: {} get-intrinsic@1.3.0: @@ -7944,14 +7906,11 @@ snapshots: dependencies: is-glob: 4.0.3 - glob@10.4.5: + glob@13.0.7: dependencies: - foreground-child: 3.1.1 - jackspeak: 3.4.3 - minimatch: 9.0.5 - minipass: 7.1.2 - package-json-from-dist: 1.0.1 - path-scurry: 1.11.1 + minimatch: 10.2.6 + minipass: 7.1.3 + path-scurry: 2.0.2 globals@11.12.0: {} @@ -8153,12 +8112,6 @@ snapshots: html-escaper: 2.0.2 istanbul-lib-report: 3.0.1 - jackspeak@3.4.3: - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - jest-diff@25.5.0: dependencies: chalk: 3.0.0 @@ -8349,18 +8302,12 @@ snapshots: dependencies: get-func-name: 2.0.2 - lru-cache@10.2.0: {} - lru-cache@11.2.4: {} lru-cache@5.1.1: dependencies: yallist: 3.1.1 - lru-cache@6.0.0: - dependencies: - yallist: 4.0.0 - magic-string@0.30.11: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 @@ -8375,7 +8322,7 @@ snapshots: make-dir@4.0.0: dependencies: - semver: 7.6.0 + semver: 7.7.2 make-error@1.3.6: {} @@ -8437,6 +8384,10 @@ snapshots: min-indent@1.0.1: {} + minimatch@10.2.6: + dependencies: + brace-expansion: 5.0.12 + minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 @@ -8447,7 +8398,7 @@ snapshots: minimist@1.2.8: {} - minipass@7.1.2: {} + minipass@7.1.3: {} mkdirp@3.0.1: {} @@ -8612,8 +8563,6 @@ snapshots: p-try@2.2.0: {} - package-json-from-dist@1.0.1: {} - package-manager-detector@0.2.0: {} package-manager-detector@1.3.0: {} @@ -8665,10 +8614,10 @@ snapshots: path-parse@1.0.7: {} - path-scurry@1.11.1: + path-scurry@2.0.2: dependencies: - lru-cache: 10.2.0 - minipass: 7.1.2 + lru-cache: 11.2.4 + minipass: 7.1.3 path-type@4.0.0: {} @@ -8915,8 +8864,6 @@ snapshots: dependencies: jsesc: 0.5.0 - require-directory@2.1.1: {} - require-from-string@2.0.2: {} resolve-from@4.0.0: {} @@ -8994,10 +8941,6 @@ snapshots: semver@6.3.1: {} - semver@7.6.0: - dependencies: - lru-cache: 6.0.0 - semver@7.7.2: {} serialize-error@11.0.3: @@ -9145,12 +9088,6 @@ snapshots: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 - string-width@5.1.2: - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.1.0 - string-width@7.1.0: dependencies: emoji-regex: 10.3.0 @@ -9163,6 +9100,11 @@ snapshots: get-east-asian-width: 1.2.0 strip-ansi: 7.1.0 + string-width@8.3.0: + dependencies: + get-east-asian-width: 1.7.0 + strip-ansi: 7.2.0 + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 @@ -9171,6 +9113,10 @@ snapshots: dependencies: ansi-regex: 6.0.1 + strip-ansi@7.2.0: + dependencies: + ansi-regex: 6.5.0 + strip-bom@3.0.0: {} strip-final-newline@3.0.0: {} @@ -9254,11 +9200,11 @@ snapshots: terminal-size@4.0.0: {} - test-exclude@7.0.1: + test-exclude@8.0.0: dependencies: '@istanbuljs/schema': 0.1.3 - glob: 10.4.5 - minimatch: 9.0.5 + glob: 13.0.7 + minimatch: 10.2.6 thread-stream@3.1.0: dependencies: @@ -9480,7 +9426,7 @@ snapshots: v8-to-istanbul@9.2.0: dependencies: - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/trace-mapping': 0.3.31 '@types/istanbul-lib-coverage': 2.0.6 convert-source-map: 2.0.0 @@ -9569,22 +9515,10 @@ snapshots: wordwrap@1.0.0: {} - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - wrap-ansi@8.1.0: - dependencies: - ansi-styles: 6.2.1 - string-width: 5.1.2 - strip-ansi: 7.1.0 - wrap-ansi@9.0.0: dependencies: ansi-styles: 6.2.1 - string-width: 7.1.0 + string-width: 7.2.0 strip-ansi: 7.1.0 wrappy@1.0.2: {} @@ -9595,19 +9529,18 @@ snapshots: yallist@3.1.1: {} - yallist@4.0.0: {} - yargs-parser@21.1.1: {} - yargs@17.7.2: + yargs-parser@22.0.0: {} + + yargs@18.2.0: dependencies: - cliui: 8.0.1 - escalade: 3.1.2 + cliui: 9.0.1 + escalade: 3.2.0 get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 + string-width: 8.3.0 y18n: 5.0.8 - yargs-parser: 21.1.1 + yargs-parser: 22.0.0 yn@3.1.1: {}