From 7bc922531283f6e483fd92a3905599de6b617635 Mon Sep 17 00:00:00 2001 From: Martijn Versluis Date: Mon, 28 Jul 2025 22:22:23 +0200 Subject: [PATCH] wip async --- bin/unibuild.ts | 6 +- package.json | 2 + src/asset.ts | 76 +++++++----- src/asset_file.ts | 52 ++++---- src/asset_input.ts | 6 - src/asset_options.ts | 4 +- src/build_function.ts | 2 +- src/build_stages.ts | 5 +- src/builder.ts | 156 ++++++++++++------------ src/cli.ts | 60 +++++----- src/cmd.ts | 16 ++- src/i_asset.ts | 14 +++ src/index.ts | 1 + yarn.lock | 267 +++++++++++++++++++++++++++++++++++++++++- 14 files changed, 490 insertions(+), 177 deletions(-) delete mode 100644 src/asset_input.ts create mode 100644 src/i_asset.ts diff --git a/bin/unibuild.ts b/bin/unibuild.ts index 561f83e..eba9d7d 100755 --- a/bin/unibuild.ts +++ b/bin/unibuild.ts @@ -13,7 +13,9 @@ async function findAndLoadConfig(): Promise { for (const filename of configFilenames) { const fullPath = resolve(cwd, filename); if (existsSync(fullPath)) { - const configModule = await import(pathToFileURL(fullPath).href); + const fileURL = pathToFileURL(fullPath).href; + console.log('Importing: ', fileURL); + const configModule = await import(fileURL); return configModule.default; } } @@ -23,7 +25,7 @@ async function findAndLoadConfig(): Promise { (async () => { try { const config = await findAndLoadConfig(); - new CLI(config).run(); + await new CLI(config).run(); } catch (err) { console.error('[unibuild] Error:', err); process.exit(1); diff --git a/package.json b/package.json index af3a873..274d896 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,8 @@ "dependencies": { "chalk": "^5.3.0", "commander": "^12.1.0", + "execa": "^9.6.0", + "ora": "^8.2.0", "tsx": "^4.10.5" }, "devDependencies": { diff --git a/src/asset.ts b/src/asset.ts index 1340762..5859c37 100644 --- a/src/asset.ts +++ b/src/asset.ts @@ -1,15 +1,15 @@ import AssetFile from './asset_file'; -import AssetInput from './asset_input'; import BuildFunction from './build_function'; import AssetOptions from './asset_options'; import { generateCommand } from './cmd'; +import IAsset from './i_asset'; -class Asset { +class Asset implements IAsset { buildFunction?: BuildFunction; command?: string; - input: AssetInput[]; + input: IAsset[]; name: string; @@ -30,7 +30,7 @@ class Asset { } } - static normalizeInput(inputs: string | AssetInput | (string | AssetInput)[]): AssetInput[] { + static normalizeInput(inputs: string | IAsset | (string | IAsset)[]): IAsset[] { return [inputs].flat().map((input) => { if (typeof input === 'string') { return new AssetFile(input); @@ -40,64 +40,78 @@ class Asset { }); } - get path() { + get path(): string { return this.outfile.path; } - hasAssetDependencies() { + hasAssetDependencies(): boolean { return this.input.some((input) => input instanceof Asset); } - needsBuilding(options: Partial<{ force: boolean, release: boolean }>) { - return (!this.releaseOnly || options.release) && - (options.force || this.outfileMissing() || this.inputChanged()); + async needsBuilding(options: Partial<{ force: boolean, release: boolean }>): Promise { + const outfileMissing = await this.outfileMissing(); + const inputChanged = await this.inputChanged(); + + return (!this.releaseOnly || !!options.release) && (options.force || outfileMissing || inputChanged); } - needsRebuild() { - return !this.outfileExists() || this.inputChanged() || this.inputNeedsRebuild(); + async needsRebuild(): Promise { + return !(await this.outfileExists()) || (await this.inputChanged()) || (await this.inputNeedsRebuild()); } - exists() { - return this.outfileExists(); + async exists(): Promise { + return await this.outfileExists(); } - isFile() { - return this.outfile.isFile(); + async isFile(): Promise { + return await this.outfile.isFile(); } - outfileMissing() { - return !this.outfileExists(); + async outfileMissing(): Promise { + return !(await this.outfileExists()); } - outfileExists() { - return this.outfile.exists(); + async outfileExists(): Promise { + return await this.outfile.exists(); } - modifiedTime() { - return this.outfile.modifiedTime(); + async modifiedTime(): Promise { + return await this.outfile.modifiedTime(); } - inputChanged() { - return this.input.some((input) => input.newerThan(this)); + async inputChanged(): Promise { + for (const input of this.input) { + if (await input.newerThan(this)) { + return true; + } + } + + return false; } - inputNeedsRebuild() { - return this.input.some((input) => input.needsRebuild()); + async inputNeedsRebuild(): Promise { + for (const input of this.input) { + if (await input.needsRebuild()) { + return true; + } + } + + return false; } - newerThan(other: AssetInput) { - return this.outfile.newerThan(other); + async newerThan(other: IAsset): Promise { + return await this.outfile.newerThan(other); } - canBeBuilt() { + async canBeBuilt(): Promise { return true; } - read() { - return this.outfile.read(); + async read(): Promise { + return await this.outfile.read(); } - toString() { + toString(): string { return this.outfile.toString(); } } diff --git a/src/asset_file.ts b/src/asset_file.ts index a274646..ed7366c 100644 --- a/src/asset_file.ts +++ b/src/asset_file.ts @@ -1,58 +1,66 @@ -import * as fs from 'fs'; -import AssetInput from './asset_input'; +import * as fs from 'fs/promises'; +import IAsset from './i_asset'; -class AssetFile { +class AssetFile implements IAsset { path: string; constructor(path: string) { this.path = path; } - modifiedTime(): number { - if (!this.exists()) { + async modifiedTime(): Promise { + if (!(await this.exists())) { return 0; } - return fs.statSync(this.path).mtimeMs; + const stats = await fs.stat(this.path); + return stats.mtimeMs; } - newerThan(other: AssetInput) { - return this.modifiedTime() > other.modifiedTime(); + async newerThan(other: IAsset): Promise { + return (await this.modifiedTime()) > (await other.modifiedTime()); } - exists() { - return fs.existsSync(this.path); + async exists(): Promise { + try { + await fs.access(this.path); + return true; + } catch { + return false; + } } - canBeBuilt() { + async canBeBuilt(): Promise { return false; } - needsBuilding() { + async needsBuilding(): Promise { return false; } - needsRebuild() { + async needsRebuild(): Promise { return false; } - isFile() { - return fs.lstatSync(this.path).isFile(); + async isFile(): Promise { + const stats = await fs.lstat(this.path); + return stats.isFile(); } - read() { - return fs.readFileSync(this.path).toString(); + async read(): Promise { + const data = await fs.readFile(this.path); + return data.toString(); } - write(contents: string) { - fs.writeFileSync(this.path, contents); + async write(contents: string): Promise { + await fs.writeFile(this.path, contents); } - remove() { - fs.unlinkSync(this.path); + async remove(): Promise { + await fs.unlink(this.path); } - toString() { + toString(): string { return this.path; } } diff --git a/src/asset_input.ts b/src/asset_input.ts deleted file mode 100644 index fbcdcc3..0000000 --- a/src/asset_input.ts +++ /dev/null @@ -1,6 +0,0 @@ -import Asset from './asset'; -import AssetFile from './asset_file'; - -type AssetInput = AssetFile | Asset; - -export default AssetInput; diff --git a/src/asset_options.ts b/src/asset_options.ts index 75cf453..65afe65 100644 --- a/src/asset_options.ts +++ b/src/asset_options.ts @@ -1,12 +1,12 @@ -import AssetInput from './asset_input'; import BuildFunction from './build_function'; import { CommandGenerator } from './cmd'; import Asset from './asset'; +import IAsset from './i_asset'; interface AssetOptions { build?: BuildFunction; command?: string | string[] | CommandGenerator; - input: string | AssetInput | (string | AssetInput)[]; + input: string | IAsset | (string | IAsset)[]; outfile: string; releaseOnly?: boolean; } diff --git a/src/build_function.ts b/src/build_function.ts index 552a8d7..5b7720d 100644 --- a/src/build_function.ts +++ b/src/build_function.ts @@ -1,5 +1,5 @@ import BuildOptions from './build_options'; -type BuildFunction = (options: Partial, ...args: string[]) => string; +type BuildFunction = (options: BuildOptions, ...args: string[]) => string; export default BuildFunction; diff --git a/src/build_stages.ts b/src/build_stages.ts index 39a893e..f42d486 100644 --- a/src/build_stages.ts +++ b/src/build_stages.ts @@ -1,5 +1,6 @@ import Asset from './asset'; -import AssetInput from './asset_input'; +import IAsset from './i_asset'; + class BuildStages { grouping: string[][] = []; @@ -14,7 +15,7 @@ class BuildStages { assets.forEach((asset: Asset) => { if (visited.has(asset.name)) return; - if (asset.input.every((input: AssetInput) => { + if (asset.input.every((input: IAsset) => { if (!input.canBeBuilt()) return true; const inputAsset = input as Asset; diff --git a/src/builder.ts b/src/builder.ts index 847272d..fe23b50 100644 --- a/src/builder.ts +++ b/src/builder.ts @@ -3,6 +3,7 @@ import Logger from './logger'; import BuildStages from './build_stages'; import Config from './config'; import cmd from './cmd'; +import ora from 'ora'; export interface BuildOptions { force: boolean; @@ -31,28 +32,39 @@ class Builder { this.config = config; } - build(assetNames: string[], options: Partial): void { + async build(assetNames: string[], options: BuildOptions): Promise { const requestedAssets = this.selectAssets(assetNames, options); - const assetsThatNeedBuild = this.filterAssets(requestedAssets, options); - const builtAssetsWithDependencies = this.addDependencies(assetsThatNeedBuild); + const assetsThatNeedBuild = await this.filterAssets(requestedAssets, options); + const builtAssetsWithDependencies = await this.addDependencies(assetsThatNeedBuild); const buildStages = new BuildStages(builtAssetsWithDependencies); this.logger.log(`Build ${builtAssetsWithDependencies.length} assets`, ['yellow']); - buildStages.grouping.forEach((group, index) => { - this.logger.section(`Stage ${index + 1}`, () => { - group.forEach((name) => { - const asset = this.assets[name]; - this.buildAsset(asset, options); - }); + for (const group of buildStages.grouping) { + const tasks = group.map(async (name) => { + const spinner = ora(name).start(name); + try { + await this.buildAsset(this.assets[name], options); + spinner.succeed(); + } catch (error) { + spinner.fail(`Failed to build ${name}: ${error}`); + } }); - }); + + if (options.parallel) { + await Promise.all(tasks); + } else { + for (const task of tasks) { + await task; + } + } + } } - lint({ fix }: { fix: boolean }) { + async lint({ fix }: { fix: boolean }) { this.logger.section('Linting...', () => { Object.values(this.linters).forEach((linter) => { - this.logger.section(`Linter ${linter.name}`, () => { + this.logger.section(`Linter ${linter.name}`, async () => { if (linter.requires.length > 0) { this.logger.section('Building required assets...', () => { this.build( @@ -64,65 +76,65 @@ class Builder { const command = fix && linter.autofixCommand ? linter.autofixCommand : linter.command; this.logger.log(`Running linter command: ${command}`, ['yellow']); - cmd(command); + const _output = await cmd(command); this.logger.log(`Done running linter ${linter.name}`, ['green']); }); }); }); } - test() { - this.logger.section('Testing...', () => { - Object.values(this.testers).forEach((tester) => { - this.logger.section(`Tester ${tester.name}`, () => { - if (tester.requires.length > 0) { - this.logger.section('Building required assets...', () => { - this.build( - tester.requires.map(asset => asset.name), - { force: false, parallel: false, release: true }, - ); - }); - } + async test() { + for (const tester of Object.values(this.testers)) { + if (tester.requires.length > 0) { + await this.build( + tester.requires.map(asset => asset.name), + { force: false, parallel: false, release: true }, + ); + } - this.logger.log(`Running test command: ${tester.command}`, ['yellow']); - cmd(tester.command); - this.logger.log(`Done running tester ${tester.name}`, ['green']); - }); - }); - }); + this.logger.log(`Running test command: ${tester.command}`, ['yellow']); + await cmd(tester.command); + this.logger.log(`Done running tester ${tester.name}`, ['green']); + } } - filterAssets(assets: Asset[], options: Partial): Asset[] { + async filterAssets(assets: Asset[], options: Partial): Promise { if (options.force) return assets; - return assets.filter((asset) => { - return asset.needsBuilding(options); - }); + const filteredAssets: Asset[] = []; + + for (const asset of assets) { + if (await asset.needsBuilding(options)) { + filteredAssets.push(asset); + } + } + + return filteredAssets; } - addDependencies(assets: Asset[]): Asset[] { + async addDependencies(assets: Asset[]): Promise { let allAssets : Set = new Set(); - assets.forEach((asset) => { + for (const asset of assets) { allAssets.add(asset); - asset.input.forEach((input) => { - if (input.needsRebuild()) { + for (const input of asset.input) { + if (await input.needsRebuild()) { allAssets = new Set([ ...allAssets, - ...this.addDependencies([input as Asset]) + ...(await this.addDependencies([input as Asset])) ]); } - }); - }); + } + } return Array.from(allAssets); } - clean(assetNames: string[]) { - this.selectAssets(assetNames).forEach((asset: Asset) => { - this.cleanAsset(asset); - }); + async clean(assetNames: string[]) { + for (const asset of this.selectAssets(assetNames)) { + await this.cleanAsset(asset); + } } selectAssets(assetNames: string[], options?: Partial) { @@ -145,62 +157,54 @@ class Builder { }); } - buildAsset(asset: Asset, options: Partial) { - this.logger.log(`Building ${asset.name}`, ['yellow']); - - this.logger.indent(() => { - if (asset.buildFunction) { - const inputs = this.logger.section('Reading inputs...', () => asset.input.map((input) => { - if (input.isFile()) { - this.logger.log(`Reading ${input.path}`); + async buildAsset(asset: Asset, options: BuildOptions) { + if (asset.buildFunction) { + const inputs: string[] = await Promise.all( + asset.input.map(async (input) => { + if (await input.isFile()) { return input.read(); } - this.logger.log(`Input ${input.path} is not a file, returning the path`, ['yellow']); return input.path; - })); + }) + ); - const output = asset.buildFunction(options, ...inputs); - this.logger.log(`Writing to ${asset.outfile.path}`); - asset.outfile.write(output); - this.logger.log(`Done building ${asset.name}`, ['green']); - } + const output = asset.buildFunction(options, ...inputs); + await asset.outfile.write(output); + } - if (asset.command) { - this.logger.log(`Running command: ${asset.command}`, ['yellow']); - cmd(asset.command); - this.logger.log(`Done building ${asset.name}`, ['green']); - } - }); + if (asset.command) { + await cmd(asset.command); + } } - cleanAsset(asset: Asset) { + async cleanAsset(asset: Asset) { this.logger.log(`Cleaning ${asset.name}`, ['yellow']); - if (asset.outfile.exists()) { + if (await asset.outfile.exists()) { this.logger.log(`Removing ${asset.outfile.path}`); - asset.outfile.remove(); + await asset.outfile.remove(); this.logger.log(`Done cleaning ${asset.name}`, ['green']); } else { this.logger.log(`File ${asset.outfile.path} not found`, ['yellow']); } } - bump(version: string) { + async bump(version: string): Promise { this.logger.log(`Bumping version to ${version}`, ['yellow']); - cmd(`npm version ${version}`); + await cmd(`npm version ${version}`); this.logger.log(`Done bumping version to ${version}`, ['green']); } - gitPush() { + async gitPush(): Promise { this.logger.log('Pushing commit and tag to git', ['yellow']); - cmd('git push && git push --tags'); + await cmd('git push && git push --tags'); this.logger.log('Done pushing to git', ['green']); } - publish() { + async publish(): Promise { this.logger.log('Publishing to npm', ['yellow']); - cmd('yarn npm publish'); + await cmd('yarn npm publish'); this.logger.log('Done publishing to npm', ['green']); } } diff --git a/src/cli.ts b/src/cli.ts index f722e31..a5453ad 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -12,13 +12,14 @@ class CLI { program: Command; constructor(config: Config) { + console.log('Config:', config); this.config = config; this.builder = new Builder(this.config); this.program = this.buildProgram(); } - run() { - this.program.parse(); + async run() { + await this.program.parseAsync(); } buildProgram(): Command { @@ -79,57 +80,58 @@ class CLI { return program; } - build(assetNames: string[], { force, release }: { force?: boolean, release?: boolean }) { - this.builder.build( + async build(assetNames: string[], { force, release }: { force?: boolean, release?: boolean }) { + await this.builder.build( assetNames, { force: force || false, release: release || false, + parallel: true, }, ); } - clean(assetNames: string[]) { - this.builder.clean(assetNames); + async clean(assetNames: string[]) { + await this.builder.clean(assetNames); } - lint({ fix }: { fix?: boolean }) { - this.builder.lint({ + async lint({ fix }: { fix?: boolean }) { + await this.builder.lint({ fix: fix || false, }); } - test() { - this.builder.test(); + async test() { + await this.builder.test(); } - ci() { - this.build([], { release: false }); - this.lint({ fix: false }); - this.test(); - this.build([], { release: true }); + async ci() { + await this.build([], { release: false }); + await this.lint({ fix: false }); + await this.test(); + await this.build([], { release: true }); } - bump(version: string) { - this.builder.bump(version); + async bump(version: string) { + await this.builder.bump(version); } - publish() { - this.builder.publish(); + async publish() { + await this.builder.publish(); } - gitPush() { - this.builder.gitPush(); + async gitPush() { + await this.builder.gitPush(); } - release(version: string) { - this.build([], { release: false }); - this.lint({ fix: false }); - this.test(); - this.build([], { force: true, release: true }); - this.bump(version); - this.gitPush(); - this.publish(); + async release(version: string) { + await this.build([], { release: false }); + await this.lint({ fix: false }); + await this.test(); + await this.build([], { force: true, release: true }); + await this.bump(version); + await this.gitPush(); + await this.publish(); } } diff --git a/src/cmd.ts b/src/cmd.ts index 064001e..6bffdc9 100644 --- a/src/cmd.ts +++ b/src/cmd.ts @@ -1,8 +1,10 @@ -import { execSync } from 'child_process'; -import Asset from './asset'; +import { exec } from 'child_process'; +import { promisify } from 'node:util'; export type CommandGenerator = (input: Type) => string | string[]; +const execAsync = promisify(exec); + function stringifyCommand(command: string | string[]): string { if (typeof command === 'string') { return command; @@ -19,6 +21,12 @@ export function generateCommand(command: string | string[] | CommandGenera return stringifyCommand(command); } -export default function cmd(command: string): void { - execSync(command, { stdio: 'inherit' }); +export default async function cmd(command: string): Promise { + const { stdout, stderr } = await execAsync(command); + + if (stderr) { + throw new Error(`Command "${command}" failed with error: ${stderr}`); + } + + return stdout; } diff --git a/src/i_asset.ts b/src/i_asset.ts new file mode 100644 index 0000000..0ec7aaa --- /dev/null +++ b/src/i_asset.ts @@ -0,0 +1,14 @@ +interface IAsset { + path: string; + modifiedTime(): Promise; + newerThan(other: IAsset): Promise; + exists(): Promise; + canBeBuilt(): Promise; + needsBuilding(options: Partial<{ force: boolean, release: boolean }>): Promise; + needsRebuild(): Promise; + isFile(): Promise; + read(): Promise; + toString(): string; +} + +export default IAsset; diff --git a/src/index.ts b/src/index.ts index ebbaa55..79d5c0c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,7 @@ import BuilderCallback from './builder_callback'; import configure from './configure'; export { default as Asset } from './asset'; +export { default as Config } from './config'; export default function unibuild(callback: BuilderCallback) { return configure(callback); diff --git a/yarn.lock b/yarn.lock index bab9526..fb3e207 100644 --- a/yarn.lock +++ b/yarn.lock @@ -201,6 +201,8 @@ __metadata: "@types/node": "npm:^24.0.10" chalk: "npm:^5.3.0" commander: "npm:^12.1.0" + execa: "npm:^9.6.0" + ora: "npm:^8.2.0" tsx: "npm:^4.10.5" bin: unibuild: ./bin/unibuild.js @@ -236,6 +238,20 @@ __metadata: languageName: node linkType: hard +"@sec-ant/readable-stream@npm:^0.4.1": + version: 0.4.1 + resolution: "@sec-ant/readable-stream@npm:0.4.1" + checksum: 10c0/64e9e9cf161e848067a5bf60cdc04d18495dc28bb63a8d9f8993e4dd99b91ad34e4b563c85de17d91ffb177ec17a0664991d2e115f6543e73236a906068987af + languageName: node + linkType: hard + +"@sindresorhus/merge-streams@npm:^4.0.0": + version: 4.0.0 + resolution: "@sindresorhus/merge-streams@npm:4.0.0" + checksum: 10c0/482ee543629aa1933b332f811a1ae805a213681ecdd98c042b1c1b89387df63e7812248bb4df3910b02b3cc5589d3d73e4393f30e197c9dde18046ccd471fc6b + languageName: node + linkType: hard + "@types/node@npm:^24.0.10": version: 24.0.10 resolution: "@types/node@npm:24.0.10" @@ -358,6 +374,22 @@ __metadata: languageName: node linkType: hard +"cli-cursor@npm:^5.0.0": + version: 5.0.0 + resolution: "cli-cursor@npm:5.0.0" + dependencies: + restore-cursor: "npm:^5.0.0" + checksum: 10c0/7ec62f69b79f6734ab209a3e4dbdc8af7422d44d360a7cb1efa8a0887bbe466a6e625650c466fe4359aee44dbe2dc0b6994b583d40a05d0808a5cb193641d220 + languageName: node + linkType: hard + +"cli-spinners@npm:^2.9.2": + version: 2.9.2 + resolution: "cli-spinners@npm:2.9.2" + checksum: 10c0/907a1c227ddf0d7a101e7ab8b300affc742ead4b4ebe920a5bf1bc6d45dce2958fcd195eb28fa25275062fe6fa9b109b93b63bc8033396ed3bcb50297008b3a3 + languageName: node + linkType: hard + "color-convert@npm:^2.0.1": version: 2.0.1 resolution: "color-convert@npm:2.0.1" @@ -392,6 +424,17 @@ __metadata: languageName: node linkType: hard +"cross-spawn@npm:^7.0.6": + version: 7.0.6 + resolution: "cross-spawn@npm:7.0.6" + dependencies: + path-key: "npm:^3.1.0" + shebang-command: "npm:^2.0.0" + which: "npm:^2.0.1" + checksum: 10c0/053ea8b2135caff68a9e81470e845613e374e7309a47731e81639de3eaeb90c3d01af0e0b44d2ab9d50b43467223b88567dfeb3262db942dc063b9976718ffc1 + languageName: node + linkType: hard + "debug@npm:4, debug@npm:^4.3.4": version: 4.3.7 resolution: "debug@npm:4.3.7" @@ -411,6 +454,13 @@ __metadata: languageName: node linkType: hard +"emoji-regex@npm:^10.3.0": + version: 10.4.0 + resolution: "emoji-regex@npm:10.4.0" + checksum: 10c0/a3fcedfc58bfcce21a05a5f36a529d81e88d602100145fcca3dc6f795e3c8acc4fc18fe773fbf9b6d6e9371205edb3afa2668ec3473fa2aa7fd47d2a9d46482d + languageName: node + linkType: hard + "emoji-regex@npm:^8.0.0": version: 8.0.0 resolution: "emoji-regex@npm:8.0.0" @@ -534,6 +584,26 @@ __metadata: languageName: node linkType: hard +"execa@npm:^9.6.0": + version: 9.6.0 + resolution: "execa@npm:9.6.0" + dependencies: + "@sindresorhus/merge-streams": "npm:^4.0.0" + cross-spawn: "npm:^7.0.6" + figures: "npm:^6.1.0" + get-stream: "npm:^9.0.0" + human-signals: "npm:^8.0.1" + is-plain-obj: "npm:^4.1.0" + is-stream: "npm:^4.0.1" + npm-run-path: "npm:^6.0.0" + pretty-ms: "npm:^9.2.0" + signal-exit: "npm:^4.1.0" + strip-final-newline: "npm:^4.0.0" + yoctocolors: "npm:^2.1.1" + checksum: 10c0/2c44a33142f77d3a6a590a3b769b49b27029a76768593bac1f26fed4dd1330e9c189ee61eba6a8c990fb77e37286c68c7445472ebf24c22b31e9ff320e73d7ac + languageName: node + linkType: hard + "exponential-backoff@npm:^3.1.1": version: 3.1.1 resolution: "exponential-backoff@npm:3.1.1" @@ -541,6 +611,15 @@ __metadata: languageName: node linkType: hard +"figures@npm:^6.1.0": + version: 6.1.0 + resolution: "figures@npm:6.1.0" + dependencies: + is-unicode-supported: "npm:^2.0.0" + checksum: 10c0/9159df4264d62ef447a3931537de92f5012210cf5135c35c010df50a2169377581378149abfe1eb238bd6acbba1c0d547b1f18e0af6eee49e30363cedaffcfe4 + languageName: node + linkType: hard + "foreground-child@npm:^3.1.0": version: 3.3.0 resolution: "foreground-child@npm:3.3.0" @@ -588,6 +667,23 @@ __metadata: languageName: node linkType: hard +"get-east-asian-width@npm:^1.0.0": + version: 1.3.0 + resolution: "get-east-asian-width@npm:1.3.0" + checksum: 10c0/1a049ba697e0f9a4d5514c4623781c5246982bdb61082da6b5ae6c33d838e52ce6726407df285cdbb27ec1908b333cf2820989bd3e986e37bb20979437fdf34b + languageName: node + linkType: hard + +"get-stream@npm:^9.0.0": + version: 9.0.1 + resolution: "get-stream@npm:9.0.1" + dependencies: + "@sec-ant/readable-stream": "npm:^0.4.1" + is-stream: "npm:^4.0.1" + checksum: 10c0/d70e73857f2eea1826ac570c3a912757dcfbe8a718a033fa0c23e12ac8e7d633195b01710e0559af574cbb5af101009b42df7b6f6b29ceec8dbdf7291931b948 + languageName: node + linkType: hard + "get-tsconfig@npm:^4.7.5": version: 4.10.1 resolution: "get-tsconfig@npm:4.10.1" @@ -647,6 +743,13 @@ __metadata: languageName: node linkType: hard +"human-signals@npm:^8.0.1": + version: 8.0.1 + resolution: "human-signals@npm:8.0.1" + checksum: 10c0/195ac607108c56253757717242e17cd2e21b29f06c5d2dad362e86c672bf2d096e8a3bbb2601841c376c2301c4ae7cff129e87f740aa4ebff1390c163114c7c4 + languageName: node + linkType: hard + "iconv-lite@npm:^0.6.2": version: 0.6.3 resolution: "iconv-lite@npm:0.6.3" @@ -687,6 +790,13 @@ __metadata: languageName: node linkType: hard +"is-interactive@npm:^2.0.0": + version: 2.0.0 + resolution: "is-interactive@npm:2.0.0" + checksum: 10c0/801c8f6064f85199dc6bf99b5dd98db3282e930c3bc197b32f2c5b89313bb578a07d1b8a01365c4348c2927229234f3681eb861b9c2c92bee72ff397390fa600 + languageName: node + linkType: hard + "is-lambda@npm:^1.0.1": version: 1.0.1 resolution: "is-lambda@npm:1.0.1" @@ -694,6 +804,34 @@ __metadata: languageName: node linkType: hard +"is-plain-obj@npm:^4.1.0": + version: 4.1.0 + resolution: "is-plain-obj@npm:4.1.0" + checksum: 10c0/32130d651d71d9564dc88ba7e6fda0e91a1010a3694648e9f4f47bb6080438140696d3e3e15c741411d712e47ac9edc1a8a9de1fe76f3487b0d90be06ac9975e + languageName: node + linkType: hard + +"is-stream@npm:^4.0.1": + version: 4.0.1 + resolution: "is-stream@npm:4.0.1" + checksum: 10c0/2706c7f19b851327ba374687bc4a3940805e14ca496dc672b9629e744d143b1ad9c6f1b162dece81c7bfbc0f83b32b61ccc19ad2e05aad2dd7af347408f60c7f + languageName: node + linkType: hard + +"is-unicode-supported@npm:^1.3.0": + version: 1.3.0 + resolution: "is-unicode-supported@npm:1.3.0" + checksum: 10c0/b8674ea95d869f6faabddc6a484767207058b91aea0250803cbf1221345cb0c56f466d4ecea375dc77f6633d248d33c47bd296fb8f4cdba0b4edba8917e83d8a + languageName: node + linkType: hard + +"is-unicode-supported@npm:^2.0.0": + version: 2.1.0 + resolution: "is-unicode-supported@npm:2.1.0" + checksum: 10c0/a0f53e9a7c1fdbcf2d2ef6e40d4736fdffff1c9f8944c75e15425118ff3610172c87bf7bc6c34d3903b04be59790bb2212ddbe21ee65b5a97030fc50370545a5 + languageName: node + linkType: hard + "isexe@npm:^2.0.0": version: 2.0.0 resolution: "isexe@npm:2.0.0" @@ -728,6 +866,16 @@ __metadata: languageName: node linkType: hard +"log-symbols@npm:^6.0.0": + version: 6.0.0 + resolution: "log-symbols@npm:6.0.0" + dependencies: + chalk: "npm:^5.3.0" + is-unicode-supported: "npm:^1.3.0" + checksum: 10c0/36636cacedba8f067d2deb4aad44e91a89d9efb3ead27e1846e7b82c9a10ea2e3a7bd6ce28a7ca616bebc60954ff25c67b0f92d20a6a746bb3cc52c3701891f6 + languageName: node + linkType: hard + "lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0": version: 10.4.3 resolution: "lru-cache@npm:10.4.3" @@ -755,6 +903,13 @@ __metadata: languageName: node linkType: hard +"mimic-function@npm:^5.0.0": + version: 5.0.1 + resolution: "mimic-function@npm:5.0.1" + checksum: 10c0/f3d9464dd1816ecf6bdf2aec6ba32c0728022039d992f178237d8e289b48764fee4131319e72eedd4f7f094e22ded0af836c3187a7edc4595d28dd74368fd81d + languageName: node + linkType: hard + "minimatch@npm:^9.0.4": version: 9.0.5 resolution: "minimatch@npm:9.0.5" @@ -902,6 +1057,42 @@ __metadata: languageName: node linkType: hard +"npm-run-path@npm:^6.0.0": + version: 6.0.0 + resolution: "npm-run-path@npm:6.0.0" + dependencies: + path-key: "npm:^4.0.0" + unicorn-magic: "npm:^0.3.0" + checksum: 10c0/b223c8a0dcd608abf95363ea5c3c0ccc3cd877daf0102eaf1b0f2390d6858d8337fbb7c443af2403b067a7d2c116d10691ecd22ab3c5273c44da1ff8d07753bd + languageName: node + linkType: hard + +"onetime@npm:^7.0.0": + version: 7.0.0 + resolution: "onetime@npm:7.0.0" + dependencies: + mimic-function: "npm:^5.0.0" + checksum: 10c0/5cb9179d74b63f52a196a2e7037ba2b9a893245a5532d3f44360012005c9cadb60851d56716ebff18a6f47129dab7168022445df47c2aff3b276d92585ed1221 + languageName: node + linkType: hard + +"ora@npm:^8.2.0": + version: 8.2.0 + resolution: "ora@npm:8.2.0" + dependencies: + chalk: "npm:^5.3.0" + cli-cursor: "npm:^5.0.0" + cli-spinners: "npm:^2.9.2" + is-interactive: "npm:^2.0.0" + is-unicode-supported: "npm:^2.0.0" + log-symbols: "npm:^6.0.0" + stdin-discarder: "npm:^0.2.2" + string-width: "npm:^7.2.0" + strip-ansi: "npm:^7.1.0" + checksum: 10c0/7d9291255db22e293ea164f520b6042a3e906576ab06c9cf408bf9ef5664ba0a9f3bd258baa4ada058cfcc2163ef9b6696d51237a866682ce33295349ba02c3a + languageName: node + linkType: hard + "p-map@npm:^4.0.0": version: 4.0.0 resolution: "p-map@npm:4.0.0" @@ -918,6 +1109,13 @@ __metadata: languageName: node linkType: hard +"parse-ms@npm:^4.0.0": + version: 4.0.0 + resolution: "parse-ms@npm:4.0.0" + checksum: 10c0/a7900f4f1ebac24cbf5e9708c16fb2fd482517fad353aecd7aefb8c2ba2f85ce017913ccb8925d231770404780df46244ea6fec598b3bde6490882358b4d2d16 + languageName: node + linkType: hard + "path-key@npm:^3.1.0": version: 3.1.1 resolution: "path-key@npm:3.1.1" @@ -925,6 +1123,13 @@ __metadata: languageName: node linkType: hard +"path-key@npm:^4.0.0": + version: 4.0.0 + resolution: "path-key@npm:4.0.0" + checksum: 10c0/794efeef32863a65ac312f3c0b0a99f921f3e827ff63afa5cb09a377e202c262b671f7b3832a4e64731003fa94af0263713962d317b9887bd1e0c48a342efba3 + languageName: node + linkType: hard + "path-scurry@npm:^1.11.1": version: 1.11.1 resolution: "path-scurry@npm:1.11.1" @@ -935,6 +1140,15 @@ __metadata: languageName: node linkType: hard +"pretty-ms@npm:^9.2.0": + version: 9.2.0 + resolution: "pretty-ms@npm:9.2.0" + dependencies: + parse-ms: "npm:^4.0.0" + checksum: 10c0/ab6d066f90e9f77020426986e1b018369f41575674544c539aabec2e63a20fec01166d8cf6571d0e165ad11cfe5a8134a2a48a36d42ab291c59c6deca5264cbb + languageName: node + linkType: hard + "proc-log@npm:^4.1.0, proc-log@npm:^4.2.0": version: 4.2.0 resolution: "proc-log@npm:4.2.0" @@ -959,6 +1173,16 @@ __metadata: languageName: node linkType: hard +"restore-cursor@npm:^5.0.0": + version: 5.1.0 + resolution: "restore-cursor@npm:5.1.0" + dependencies: + onetime: "npm:^7.0.0" + signal-exit: "npm:^4.1.0" + checksum: 10c0/c2ba89131eea791d1b25205bdfdc86699767e2b88dee2a590b1a6caa51737deac8bad0260a5ded2f7c074b7db2f3a626bcf1fcf3cdf35974cbeea5e2e6764f60 + languageName: node + linkType: hard + "retry@npm:^0.12.0": version: 0.12.0 resolution: "retry@npm:0.12.0" @@ -998,7 +1222,7 @@ __metadata: languageName: node linkType: hard -"signal-exit@npm:^4.0.1": +"signal-exit@npm:^4.0.1, signal-exit@npm:^4.1.0": version: 4.1.0 resolution: "signal-exit@npm:4.1.0" checksum: 10c0/41602dce540e46d599edba9d9860193398d135f7ff72cab629db5171516cfae628d21e7bfccde1bbfdf11c48726bc2a6d1a8fb8701125852fbfda7cf19c6aa83 @@ -1049,6 +1273,13 @@ __metadata: languageName: node linkType: hard +"stdin-discarder@npm:^0.2.2": + version: 0.2.2 + resolution: "stdin-discarder@npm:0.2.2" + checksum: 10c0/c78375e82e956d7a64be6e63c809c7f058f5303efcaf62ea48350af072bacdb99c06cba39209b45a071c1acbd49116af30df1df9abb448df78a6005b72f10537 + languageName: node + linkType: hard + "string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0": version: 4.2.3 resolution: "string-width@npm:4.2.3" @@ -1071,6 +1302,17 @@ __metadata: languageName: node linkType: hard +"string-width@npm:^7.2.0": + version: 7.2.0 + resolution: "string-width@npm:7.2.0" + dependencies: + emoji-regex: "npm:^10.3.0" + get-east-asian-width: "npm:^1.0.0" + strip-ansi: "npm:^7.1.0" + checksum: 10c0/eb0430dd43f3199c7a46dcbf7a0b34539c76fe3aa62763d0b0655acdcbdf360b3f66f3d58ca25ba0205f42ea3491fa00f09426d3b7d3040e506878fc7664c9b9 + languageName: node + linkType: hard + "strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": version: 6.0.1 resolution: "strip-ansi@npm:6.0.1" @@ -1080,7 +1322,7 @@ __metadata: languageName: node linkType: hard -"strip-ansi@npm:^7.0.1": +"strip-ansi@npm:^7.0.1, strip-ansi@npm:^7.1.0": version: 7.1.0 resolution: "strip-ansi@npm:7.1.0" dependencies: @@ -1089,6 +1331,13 @@ __metadata: languageName: node linkType: hard +"strip-final-newline@npm:^4.0.0": + version: 4.0.0 + resolution: "strip-final-newline@npm:4.0.0" + checksum: 10c0/b0cf2b62d597a1b0e3ebc42b88767f0a0d45601f89fd379a928a1812c8779440c81abba708082c946445af1d6b62d5f16e2a7cf4f30d9d6587b89425fae801ff + languageName: node + linkType: hard + "tar@npm:^6.1.11, tar@npm:^6.2.1": version: 6.2.1 resolution: "tar@npm:6.2.1" @@ -1126,6 +1375,13 @@ __metadata: languageName: node linkType: hard +"unicorn-magic@npm:^0.3.0": + version: 0.3.0 + resolution: "unicorn-magic@npm:0.3.0" + checksum: 10c0/0a32a997d6c15f1c2a077a15b1c4ca6f268d574cf5b8975e778bb98e6f8db4ef4e86dfcae4e158cd4c7e38fb4dd383b93b13eefddc7f178dea13d3ac8a603271 + languageName: node + linkType: hard + "unique-filename@npm:^3.0.0": version: 3.0.0 resolution: "unique-filename@npm:3.0.0" @@ -1194,3 +1450,10 @@ __metadata: checksum: 10c0/2286b5e8dbfe22204ab66e2ef5cc9bbb1e55dfc873bbe0d568aa943eb255d131890dfd5bf243637273d31119b870f49c18fcde2c6ffbb7a7a092b870dc90625a languageName: node linkType: hard + +"yoctocolors@npm:^2.1.1": + version: 2.1.1 + resolution: "yoctocolors@npm:2.1.1" + checksum: 10c0/85903f7fa96f1c70badee94789fade709f9d83dab2ec92753d612d84fcea6d34c772337a9f8914c6bed2f5fc03a428ac5d893e76fab636da5f1236ab725486d0 + languageName: node + linkType: hard