@yunarch/config-web 0.3.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![NPM version](https://img.shields.io/npm/v/@yunarch/config-web?color=3eb910&label=)](https://www.npmjs.com/package/@yunarch/config-web)
4
4
 
5
- > A curated set of linters (ESLint, Oxlint), formatters (Prettier, Biome), TypeScript configurations for web projects, and useful CLI tools.
5
+ > A curated set of configurations and useful CLI tools for web projects.
6
6
 
7
7
  > [!NOTE]
8
8
  > This package is pure [ESM](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules). This means you need to ensure to use an **ESM-Compatible Environment** (Your runtime or bundler must support ESM) and enable **Package Type module** by adding the following to you `package.json`:
@@ -14,16 +14,18 @@
14
14
  - [📖 Why use this?](#-why-use-this)
15
15
  - [📦 What’s included?](#-whats-included)
16
16
  - [⚙️ Installation](#️-installation)
17
- - [📐 Code Formatting](#-code-formatting)
18
- - [Prettier](#prettier)
19
- - [Biome](#biome)
20
- - [🧹 Linting](#-linting)
21
- - [ESlint](#eslint)
22
- - [Override configuration](#override-configuration)
23
- - [Typescript Type aware rules](#typescript-type-aware-rules)
24
- - [Enabling ESLint and Oxlint Simultaneously](#enabling-eslint-and-oxlint-simultaneously)
25
- - [Oxlint](#oxlint)
26
- - [🔵 Typescript](#-typescript)
17
+ - [⚠️ Caveats](#️-caveats)
18
+ - [Code Formatting](#code-formatting)
19
+ - [Linting](#linting)
20
+ - [Prettier](#prettier)
21
+ - [ESlint](#eslint)
22
+ - [Override configuration](#override-configuration)
23
+ - [Typescript Type aware rules](#typescript-type-aware-rules)
24
+ - [Oxlint](#oxlint)
25
+ - [Enabling ESLint and Oxlint Simultaneously](#enabling-eslint-and-oxlint-simultaneously)
26
+ - [Biome](#biome)
27
+ - [Enabling ESLint and Biome Simultaneously](#enabling-eslint-and-biome-simultaneously)
28
+ - [Typescript](#typescript)
27
29
  - [ts-reset](#ts-reset)
28
30
  - [Utilities](#utilities)
29
31
  - [🔧 CLI Tools](#-cli-tools)
@@ -42,8 +44,7 @@ Even experienced developers can waste valuable time configuring tools from scrat
42
44
 
43
45
  This package provides ready-to-use configurations for:
44
46
 
45
- - **Code Formatting:** Prettier, Biome
46
- - **Linting:** ESLint, Oxlint
47
+ - **Shared configs for Code Style & Linting:** Pre-configured yet extensible setups for Prettier, ESLint, Oxlint, and Biome.
47
48
  - **TypeScript:** Best-practice default config and utilities.
48
49
  - **CLI Tools:** Useful command-line tools for streamlining workflows
49
50
 
@@ -74,19 +75,27 @@ npm install --save-dev eslint
74
75
  npm install --save-dev oxlint
75
76
  ```
76
77
 
77
- ## 📐 Code Formatting
78
+ ## ⚠️ Caveats
78
79
 
79
- This package comes with configurations for both `Prettier` and `Biome` to ensure consistent formatting across your codebase.
80
+ ### Code Formatting
80
81
 
81
- > [!NOTE]
82
- > While both `Prettier` and `Biome` are configured to format code in the same way, there are some [differences](https://biomejs.dev/formatter/differences-with-prettier/) between the two.
83
- >
84
- > Language support for [Prettier](https://prettier.io/docs/) and [Biome](https://biomejs.dev/internals/language-support/).
82
+ While both `Prettier` and `Biome` are configured to format code in the same way, there are some [differences](https://biomejs.dev/formatter/differences-with-prettier/) between the two.
83
+
84
+ Language support for [Prettier](https://prettier.io/docs/) and [Biome](https://biomejs.dev/internals/language-support/).
85
85
 
86
86
  > [!WARNING]
87
87
  > While it's technically possible to use both tools in the same project, **each file should be formatted by only one formatter** to avoid conflicts. This repository uses this hybrid setup, but for simplicity and consistency, **we recommend choosing a single formatter** for your own project.
88
88
 
89
- ### Prettier
89
+ ### Linting
90
+
91
+ We offer a strict yet configurable `ESLint` setup with autocomplete support. Additionally, since the `ESLint` ecosystem is extensive but can sometimes be slow, this configuration allows leveraging `Oxlint` or `Biome` for certain rules, boosting speed without compromising flexibility.
92
+
93
+ For small projects, `Oxlint` or `Biome` should be sufficient. However, for big projects or if you want to maintain consistent code style across multiple projects. I recommend `ESlint` and if need it a performance boost then combining `ESLint` with either `Oxlint` or `Biome`.
94
+
95
+ > [!NOTE]
96
+ > Avoid using all three tools (`ESLint`, `Oxlint`, and `Biome`) simultaneously, as this may lead to conflicts between `Oxlint` and `Biome` that you'll need to manually resolve.
97
+
98
+ ## Prettier
90
99
 
91
100
  The easiest way to use the prettier configuration as-is is to set it directly in your `package.json`:
92
101
 
@@ -106,32 +115,10 @@ export default {
106
115
  };
107
116
  ```
108
117
 
118
+ > [!TIP]
109
119
  > Add a `.prettierignore` file to ignore certain files and folder completly or use the CLI option [--ignore-path](https://prettier.io/docs/cli#--ignore-path) to indicate a path to a file containing patterns that describe files to ignore. By default, Prettier looks for `./.gitignore` and `./.prettierignore`.
110
120
 
111
- ### Biome
112
-
113
- To use the Biome formatter, create a `biome.json` [configuration file](https://biomejs.dev/reference/configuration/):
114
-
115
- ```jsonc
116
- {
117
- "$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
118
- "extends": ["@yunarch/config-web/biome-formatter"],
119
- // Add your overrides here...
120
- }
121
- ```
122
-
123
- > [!IMPORTANT]
124
- > We disable the `organizeImports` options as we want that to be manage by the linter configuration that we offer. feel free to enable it if you prefer to use Biome for these tasks. **Remember to disable it on ESlint configuration** if you use it.
125
-
126
- > Enable [vcs.useIgnoreFile](https://biomejs.dev/guides/integrate-in-vcs/#use-the-ignore-file), to allow Biome to ignore all the files and directories listed in your VCS ignore file.
127
-
128
- ## 🧹 Linting
129
-
130
- We offer a strict yet configurable ESLint setup with autocomplete support. Additionally, since the ESLint ecosystem is extensive but can sometimes be slow, this configuration allows leveraging Oxlint for certain rules, boosting speed without compromising flexibility.
131
-
132
- For small projects, `Oxlint` or enabling the linter in `Biome` should be sufficient. However, for big projects or if you want to maintain consistent code style across multiple projects, we recommend ESlint and for performance boost ESlint + Oxlint.
133
-
134
- ### ESlint
121
+ ## ESlint
135
122
 
136
123
  To use the ESlint linter, create a [ESlint configuration file](https://eslint.org/docs/latest/use/configure/configuration-files):
137
124
 
@@ -180,7 +167,7 @@ export default config(
180
167
 
181
168
  > Thanks to [antfu/eslint-config](https://github.com/antfu/eslint-config) for the inspiration, reference, and developed tools.
182
169
 
183
- #### Override configuration
170
+ ### Override configuration
184
171
 
185
172
  Thanks to [eslint-flat-config-utils](https://github.com/antfu/eslint-flat-config-utils) we returns a flat config composer where you can chain methods and compose the configuration in different ways.
186
173
 
@@ -221,7 +208,7 @@ export default config()
221
208
  > [!TIP]
222
209
  > There are other methods such as `remove`, `removeRules`, `append`, `insertBefore`, etc. These methods help you configure the linter to suit your specific needs.
223
210
 
224
- #### Typescript Type aware rules
211
+ ### Typescript Type aware rules
225
212
 
226
213
  By providing the `tsconfigPath` in the `typescript` configuration it will automatically enable [type aware rules](https://typescript-eslint.io/getting-started/typed-linting/) which may/will impact the linter's performance.
227
214
 
@@ -238,24 +225,7 @@ export default config({
238
225
  > [!NOTE]
239
226
  > You can pass `disableTypeAware: true` to disable type-aware rules while keeping the TypeScript parser configuration which will allow you to manually enable the type-aware rules you want.
240
227
 
241
- #### Enabling ESLint and Oxlint Simultaneously
242
-
243
- If you want to offload certain rules to Oxlint, which will reduce linting time, you can configure it as follows:
244
-
245
- ```js
246
- import { config } from '@yunarch/config-web/eslint';
247
-
248
- export default config({
249
- oxlint: {
250
- oxlintConfigPath: './.oxlintrc.json',
251
- },
252
- });
253
- ```
254
-
255
- > [!NOTE]
256
- > This setup automatically detects which rules are specified in the Oxlint configuration and disables them in ESLint accordingly.
257
-
258
- ### Oxlint
228
+ ## Oxlint
259
229
 
260
230
  To use the oxlint linter, create a `.oxlintrc.json` [configuration file](https://oxc.rs/docs/guide/usage/linter/config.html):
261
231
 
@@ -280,7 +250,57 @@ To use the oxlint linter, create a `.oxlintrc.json` [configuration file](https:/
280
250
  > Currently, `Oxlint` does not resolve configuration file paths automatically. To extend a config, you must explicitly provide the full path, like so:
281
251
  > `"extends": ["./node_modules/@yunarch/config-web/dist/linters/oxlint.config.json"]`
282
252
 
283
- ## 🔵 Typescript
253
+ ### Enabling ESLint and Oxlint Simultaneously
254
+
255
+ If you want to offload certain rules to Oxlint, which will reduce linting time, you can configure `ESlint` as follows:
256
+
257
+ ```js
258
+ import { config } from '@yunarch/config-web/eslint';
259
+
260
+ export default config({
261
+ oxlint: {
262
+ oxlintConfigPath: './.oxlintrc.json',
263
+ },
264
+ });
265
+ ```
266
+
267
+ ## Biome
268
+
269
+ To use the Biome, create a `biome.json` [configuration file](https://biomejs.dev/reference/configuration/):
270
+
271
+ ```jsonc
272
+ {
273
+ "$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
274
+ "extends": ["@yunarch/config-web/biome"],
275
+ "linter": {
276
+ "enabled": true,
277
+ },
278
+ }
279
+ ```
280
+
281
+ That’s it! Biome will now use the shared config to lint and format your code. However:
282
+
283
+ - If you prefer not to use Biome as a linter, simply remove the `"linter"` section. Linting is disabled by default unless explicitly enabled.
284
+ - If you prefer to use Biome only as a linter, disable the formatter by: `"formatter": { "enabled": false }`.
285
+
286
+ > [!TIP]
287
+ > Enable [vcs.useIgnoreFile](https://biomejs.dev/guides/integrate-in-vcs/#use-the-ignore-file), to allow Biome to ignore all the files and directories listed in your VCS ignore file.
288
+
289
+ ### Enabling ESLint and Biome Simultaneously
290
+
291
+ If you want to offload certain rules to `Biome`, which will reduce linting time, you can configure `ESlint` as follows:
292
+
293
+ ```js
294
+ import { config } from '@yunarch/config-web/eslint';
295
+
296
+ export default config({
297
+ biome: {
298
+ biomeConfigPath: './biome.json',
299
+ },
300
+ });
301
+ ```
302
+
303
+ ## Typescript
284
304
 
285
305
  Create the `tsconfig.json` file with the following content:
286
306
 
@@ -299,7 +319,7 @@ Learn more from [Typescript docs here](https://www.typescriptlang.org/tsconfig/#
299
319
  This package also includes a [`ts-reset`](https://www.totaltypescript.com/ts-reset) configuration to enhance TypeScript's built-in types. To use it, create a `reset.d.ts` file in your project with the following content:
300
320
 
301
321
  ```ts
302
- import '@yunarch/config-web/reset.d.ts';
322
+ import '@yunarch/config-web/ts-reset.d.ts';
303
323
  ```
304
324
 
305
325
  Then, include this file in your `tsconfig.json`, for example:
@@ -318,24 +338,38 @@ Then, include this file in your `tsconfig.json`, for example:
318
338
 
319
339
  ### Utilities
320
340
 
321
- As an enhacement of `ts-reset` this package also includes utilities designed to help you write stricter and more maintainable code. TypeScript uses structural typing, which means it doesn’t always prevent objects from having excess properties. Unlike `ts-reset`, which modifies built-in types globally, these utilities are opt-in. Giving you control over when and where to enforce stricter typing.
341
+ As an enhancement to the `ts-reset`, this package provides type-level utilities to help you write stricter, more maintainable TypeScript code.
342
+
343
+ TypeScript uses structural typing, which means it doesn't always prevent objects from having excess properties. While `ts-reset` modifies built-in types globally, these utilities are **opt-in**, allowing you to apply stricter typing **only where you need it**.
322
344
 
323
- To use them, simply import the desired utility from:
345
+ > [!NOTE]
346
+ > This package only provides **types**, as the package is intended to be used as a `devDependency` **only**. So you need to create runtime type-safe wrappers. **Each utility type includes usage guidance in its definition comments**.
347
+
348
+ For example, using the exposed utility types, you can define strictly typed versions of `Object.entries` and `Object.fromEntries`, ensuring safer and more predictable object manipulation:
324
349
 
325
- ```tsx
326
- import { typedObjectEntries, typedObjectFromEntries, ... } from "@yunarch/config-web/ts-utils";
350
+ ```ts
351
+ import type {
352
+ ObjectEntries,
353
+ ObjectFromEntries,
354
+ } from '@yunarch/config-web/ts-utils.d.ts';
355
+
356
+ // Strictly typed version of `Object.entries`
357
+ const typedObjectEntries: ObjectEntries = Object.entries;
358
+ const x1 = typedObjectEntries({ a: 1, b: 2 } as const);
359
+
360
+ // Strictly typed version of `Object.fromEntries`
361
+ const typedObjectFromEntries: ObjectFromEntries = Object.fromEntries;
362
+ const x2 = typedObjectFromEntries([['a', 1]] as const);
327
363
  ```
328
364
 
329
365
  ## 🔧 CLI Tools
330
366
 
331
367
  This package ships with useful command-line tools to streamline your workflow.
332
368
 
333
- - **`bun-run-all`**: CLI tool for running npm package scripts in parallel or sequential by using bun.
334
- - **`openapi-sync`**: CLI tool designed to convert OpenAPI 3.0/3.1 schemas to TypeScript types and create type-safe fetching based on a openapi schema file and keep them in sync.
335
- - **`turbo-select`**: CLI tool for filtering and selecting a single package from your Turborepo package list and executing a script command. Additionally, it can prompt you to select an environment mode (development, staging, production) useful for adjusting settings based on the environment (e.g., when using Vite).
336
-
337
- > [!NOTE]
338
- > All the CLI tools include a `--help` flag, which provides detailed information on usage and available options.
369
+ - **[`bun-run-all`](./src/cli/__docs__/bun-run-all.md)**: CLI tool for running npm package scripts in parallel or sequential by using bun.
370
+ - **[`openapi-sync`](./src/cli/__docs__/openapi-sync.md)**: CLI tool designed to convert OpenAPI 3.0/3.1 schemas to TypeScript types and create type-safe fetching based on a openapi schema file and keep them in sync.
371
+ - **[`openapi-sync-lint-msw-handlers`](./src/cli/__docs__/openapi-sync-lint-msw-handlers.md)**: CLI tool for linting and identifying missing MSW (Mock Service Worker) handlers based on OpenAPI generated services. It analyzes your codebase to find where service methods are used and suggests appropriate handlers with detailed reporting.
372
+ - **[`turbo-select`](./src/cli/__docs__/turbo-select.md)**: CLI tool for filtering and selecting a single package from your Turborepo package list and executing a script command. Additionally, it can prompt you to select an environment mode (development, staging, production) — useful for adjusting settings based on the environment (e.g., when using Vite).
339
373
 
340
374
  > [!IMPORTANT]
341
375
  > These tools are **a personal configuration** with a lot of opinions. They might not work for everyone or every use case. Additionally, tools can be added or removed without being considered a breaking change.
@@ -0,0 +1 @@
1
+ {"formatter":{"enabled":true,"includes":["**","!**/node_modules/","!**/dist/","!**/out/","!**/output","!**/.output","!**/build/","!**/*.min.*","!**/package-lock.json","!**/yarn.lock","!**/.yarn/","!**/.yarnrc.yml","!**/.pnp.*","!**/.pnp","!**/.pnp.js","!**/.pnp.cjs","!**/bun.lock","!**/bun.lockb","!**/pnpm-lock.yaml","!**/.vite-inspect","!**/.vitepress/cache","!**/vite.config.*.timestamp-*","!**/*.log","!**/npm-debug.log*","!**/yarn-debug.log*","!**/yarn-error.log*","!**/coverage/","!**/.nyc_output/","!**/__snapshots__","!**/.vscode/","!**/.idea/","!**/.cache","!**/.nuxt","!**/.next","!**/.svelte-kit","!**/.vercel","!**/.changeset","!**/.turbo/","!**/.DS_Store","!**/Thumbs.db","!**/temp","!**/.temp","!**/tmp","!**/.tmp","!**/.history","!**/mockServiceWorker.js","!**/CHANGELOG*","!**/LICENSE*"],"useEditorconfig":true,"formatWithErrors":false,"indentStyle":"space","indentWidth":2,"lineEnding":"lf","lineWidth":80,"attributePosition":"auto","bracketSpacing":true},"javascript":{"formatter":{"jsxQuoteStyle":"double","quoteProperties":"asNeeded","trailingCommas":"es5","semicolons":"always","arrowParentheses":"always","bracketSameLine":false,"quoteStyle":"single","attributePosition":"auto","bracketSpacing":true}},"linter":{"enabled":false,"includes":["!**/node_modules/","!**/dist/","!**/out/","!**/output","!**/.output","!**/build/","!**/*.min.*","!**/package-lock.json","!**/yarn.lock","!**/.yarn/","!**/.yarnrc.yml","!**/.pnp.*","!**/.pnp","!**/.pnp.js","!**/.pnp.cjs","!**/bun.lock","!**/bun.lockb","!**/pnpm-lock.yaml","!**/.vite-inspect","!**/.vitepress/cache","!**/vite.config.*.timestamp-*","!**/*.log","!**/npm-debug.log*","!**/yarn-debug.log*","!**/yarn-error.log*","!**/coverage/","!**/.nyc_output/","!**/__snapshots__","!**/.vscode/","!**/.idea/","!**/.cache","!**/.nuxt","!**/.next","!**/.svelte-kit","!**/.vercel","!**/.changeset","!**/.turbo/","!**/.DS_Store","!**/Thumbs.db","!**/temp","!**/.temp","!**/tmp","!**/.tmp","!**/.history","!**/mockServiceWorker.js","!**/CHANGELOG*","!**/LICENSE*"]},"overrides":[{"includes":["**/package.json"],"formatter":{"indentStyle":"space"}}],"assist":{"actions":{"source":{"organizeImports":"off"}}}}
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env bun
2
+ import{f as p,i as d}from"../chunk-OOETI6RK.js";p();import{styleText as y}from"util";p();import{styleText as l}from"util";var m=["blue","green","yellow","grey","white","cyan"],b=o=>`${(Number(Bun.nanoseconds()-o)/1e6/1e3).toFixed(2)}s`;function g({start:o,tasks:e,failedTasks:n}){let c=e-n,a=b(o),t=n>0?l("red",`${n} failed`):"",i=c>0?l("green",`${c} successful`):"";console.log(""),console.log(l(["white","bold"],"Tasks: "),`${t}${t&&i?"|":""}${i}`,l("gray",`-- ${e} total`)),console.log(l(["white","bold"],"Time: "),l("gray",`${a}
3
+ `))}function f({index:o,script:e,continueOnError:n,reportTime:c}){let a=m[o%m.length],t=Bun.nanoseconds(),i=Bun.spawn(["bun","run",e],{stdout:"pipe",stderr:"pipe",env:{...Bun.env,FORCE_COLOR:"1"},onExit(r,s){s===1&&!n&&process.exit(1)}});return i.stdout.pipeTo(new WritableStream({write(r){let s=new TextDecoder().decode(r).split(`
4
+ `);for(let u of s)console.log(l([a,"bold"],`${e}:`),u)}})),i.stderr.pipeTo(new WritableStream({write(r){let s=new TextDecoder().decode(r).split(`
5
+ `);for(let u of s)console.log(l([a,"bold"],`${e}:`),u)}})),i.exited.then(r=>{r===0&&c&&console.log(l([a,"bold"],`${e}:`),l(["gray"],"Finished in"),l(["white","bold"],b(t)))}),i}async function x(o,e){let{continueOnError:n,reportTime:c}=e,a=Bun.nanoseconds(),t=o.map((s,u)=>f({index:u,script:s,continueOnError:n,reportTime:c})),r=(await Promise.allSettled(t.map(s=>s.exited))).filter(s=>s.status==="rejected"||s.value!==0).length;return g({start:a,tasks:o.length,failedTasks:r}),r>0?1:0}async function T(o,e){let{continueOnError:n,reportTime:c}=e,a=Bun.nanoseconds(),t=0;for(let[i,r]of o.entries())await f({index:i,script:r,continueOnError:n,reportTime:c}).exited!==0&&t++;return g({start:a,tasks:o.length,failedTasks:t}),t>0?1:0}d().name("bun-run-all").description("Run given package scripts in parallel or sequential by using bun.").argument("<scripts...>","A list of package scripts' names.").option("-c, --continue-on-error","Continue executing other/subsequent tasks even if a task threw an error").option("-p, --parallel","Run a group of tasks in parallel.").option("-s, --sequential","Run a group of tasks sequentially.").option("-t, --time","Report execution time for each task.").addHelpText("after",`
6
+ Example usage:
7
+
8
+ $ bun-run-all script1 script2`).action(async(o,e)=>{try{console.log(y("magenta",`
9
+ \u{1F680} bun-run-all
10
+ `));let n=e.sequential??!1,c=e.parallel??!n,a=e.continueOnError??!1,t=e.time??!1;if(c===n&&(console.error("You cannot use both --parallel and --sequential options at the same time."),process.exit(1)),n){let r=await T(o,{continueOnError:a,reportTime:t});process.exit(r)}let i=await x(o,{continueOnError:a,reportTime:t});process.exit(i)}catch(n){console.error(n),process.exit(1)}}).parseAsync(process.argv);
@@ -0,0 +1 @@
1
+ var u=Object.create;var p=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var f=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var k=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,o)=>(typeof require<"u"?require:t)[o]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var T=(e,t)=>()=>(e&&(t=e(e=0)),t);var A=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var x=(e,t,o,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of y(t))!g.call(e,r)&&r!==o&&p(e,r,{get:()=>t[r],enumerable:!(i=d(t,r))||i.enumerable});return e};var B=(e,t,o)=>(o=e!=null?u(f(e)):{},x(t||!e||!e.__esModule?p(o,"default",{value:e,enumerable:!0}):o,e));import w from"path";import{fileURLToPath as h}from"url";var c,P,b,D,a=T(()=>{"use strict";c=()=>h(import.meta.url),P=()=>w.dirname(c()),b=P(),D=c()});a();import{exec as O}from"child_process";import{promisify as _,styleText as n,types as C}from"util";import{Command as $}from"commander";import E from"ora";var j=_(O);async function z(e){let{command:t,name:o,options:i}=e,r=E(o);r.spinner=i?.spinner??"aesthetic";let l=Date.now();r.start();try{let s=typeof t=="string"?await j(t):C.isPromise(t)?await t:await t();return r.succeed(i?.showTime?`${n("dim",`${Date.now()-l}ms`)} ${o}`:void 0),await new Promise(m=>{setTimeout(m,0)}),typeof s=="object"&&s&&"stdout"in s?s.stdout:s}catch(s){let m=s;throw r.fail(n("red",m.stderr??m.message??"")),s}}function G(){let e=new $;return e.configureHelp({styleTitle:t=>n("bold",t),styleCommandText:t=>n("cyan",t),styleCommandDescription:t=>n("magenta",t),styleDescriptionText:t=>n("italic",t),styleOptionText:t=>n("green",t),styleArgumentText:t=>n("yellow",t),styleSubcommandText:t=>n("blue",t)}).configureOutput({outputError:(t,o)=>{o(n("red",t))}}),e}export{k as a,A as b,B as c,b as d,D as e,a as f,j as g,z as h,G as i};