bob-core 2.0.0-beta.15 → 2.0.0-beta.17

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
@@ -16,7 +16,7 @@
16
16
 
17
17
  [![npm version](https://img.shields.io/npm/v/bob-core.svg)](https://www.npmjs.com/package/bob-core)
18
18
  [![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](https://opensource.org/licenses/ISC)
19
- [![TypeScript](https://img.shields.io/badge/TypeScript-5.7-blue)](https://www.typescriptlang.org/)
19
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue)](https://www.typescriptlang.org/)
20
20
 
21
21
  [Features](#features) • [Installation](#installation) • [Quick Start](#quick-start) • [Documentation](#documentation) • [Examples](#examples)
22
22
 
@@ -187,38 +187,44 @@ Options:
187
187
  Build beautiful interactive CLIs with built-in prompts:
188
188
 
189
189
  ```typescript
190
- import { Command } from 'bob-core';
190
+ import { Command, CommandHandlerOptions, OptionsSchema } from 'bob-core';
191
191
 
192
- export default new Command('setup', {
193
- description: 'Interactive project setup'
194
- }).handler(async () => {
195
- // Text input
196
- const name = await this.io.askForInput('Project name:');
197
-
198
- // Confirmation
199
- const useTypeScript = await this.io.askForConfirmation('Use TypeScript?', true);
200
-
201
- // Selection
202
- const framework = await this.io.askForSelect('Framework:', [
203
- { title: 'React', value: 'react' },
204
- { title: 'Vue', value: 'vue' },
205
- { title: 'Svelte', value: 'svelte' }
206
- ]);
207
-
208
- // Multi-select
209
- const features = await this.io.askForSelect(
210
- 'Features:',
211
- ['ESLint', 'Prettier', 'Testing'],
212
- { type: 'multiselect' }
213
- );
214
-
215
- // Spinner/loader
216
- using loader = this.io.newLoader('Creating project...');
217
- await createProject({ name, framework, features });
218
- loader.stop();
219
-
220
- this.io.info('✅ Project created!');
221
- });
192
+ export default class SetupCommand extends Command<any, OptionsSchema, OptionsSchema> {
193
+ constructor() {
194
+ super('setup', {
195
+ description: 'Interactive project setup'
196
+ });
197
+ }
198
+
199
+ async handle(ctx: any, opts: CommandHandlerOptions<OptionsSchema, OptionsSchema>) {
200
+ // Text input
201
+ const name = await this.io.askForInput('Project name:');
202
+
203
+ // Confirmation
204
+ const useTypeScript = await this.io.askForConfirmation('Use TypeScript?', true);
205
+
206
+ // Selection
207
+ const framework = await this.io.askForSelect('Framework:', [
208
+ { title: 'React', value: 'react' },
209
+ { title: 'Vue', value: 'vue' },
210
+ { title: 'Svelte', value: 'svelte' }
211
+ ]);
212
+
213
+ // Multi-select
214
+ const features = await this.io.askForSelect(
215
+ 'Features:',
216
+ ['ESLint', 'Prettier', 'Testing'],
217
+ { type: 'multiselect' }
218
+ );
219
+
220
+ // Spinner/loader
221
+ using loader = this.io.newLoader('Creating project...');
222
+ await createProject({ name, framework, features });
223
+ loader.stop();
224
+
225
+ this.io.info('✅ Project created!');
226
+ }
227
+ }
222
228
  ```
223
229
 
224
230
  ---
@@ -383,10 +389,28 @@ BOB Core makes CLI development in TypeScript a breeze:
383
389
  | `'string'` | Text value | `'hello'` |
384
390
  | `'number'` | Numeric value | `42` |
385
391
  | `'boolean'` | True/false | `true` |
386
- | `'secret'` | Masked input | `'****'` |
387
392
  | `['string']` | String array | `['a', 'b']` |
388
393
  | `['number']` | Number array | `[1, 2, 3]` |
389
394
 
395
+ **Note:** The `secret` flag is not a type but a property of OptionDefinition.
396
+
397
+ ### Secret/Masked Input
398
+
399
+ For sensitive input like passwords, use the `secret: true` flag in the option definition:
400
+
401
+ ```typescript
402
+ options: {
403
+ password: {
404
+ type: 'string', // Type is still 'string'
405
+ secret: true, // Flag to mask input in interactive prompts
406
+ required: true,
407
+ description: 'User password'
408
+ }
409
+ }
410
+ ```
411
+
412
+ The `secret` flag masks the input when prompting interactively, making it perfect for passwords and API keys.
413
+
390
414
  ---
391
415
 
392
416
  ## Contributing
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e="bob-core",t="2.0.0-beta.17",s="BOB Core",i="module",n="./dist/cjs/src/index.js",r="./dist/esm/src/index.js",c="./dist/esm/src/index.d.ts",o=["dist"],d={".":{import:{types:"./dist/esm/src/index.d.ts",default:"./dist/esm/src/index.js"},require:{types:"./dist/cjs/src/index.d.ts",default:"./dist/cjs/src/index.js"}}},p={start:"node -r @swc-node/register debug/main.ts",build:"rimraf ./dist && vite build",typecheck:"tsc --noEmit",prepack:"npm run build",test:"vitest run",lint:"eslint .","lint:fix":"eslint . --fix"},l="Léo Hubert",m="ISC",a={"@eslint/js":"^9.37.0","@faker-js/faker":"^10.0.0","@swc-node/register":"^1.11.1","@trivago/prettier-plugin-sort-imports":"^5.2.2","@types/minimist":"^1.2.5","@types/node":"^20.14.5","@types/prompts":"^2.4.9","@types/string-similarity":"^4.0.2","@vitest/coverage-v8":"^3.2.4",eslint:"^9.37.0","eslint-config-prettier":"^10.1.8","eslint-plugin-prettier":"^5.5.4",prettier:"^3.6.2",rimraf:"^6.0.1",tsx:"^4.20.6",typescript:"^5.9.3","typescript-eslint":"^8.46.0",vite:"^7.2.7","vite-plugin-dts":"^4.5.4",vitest:"^3.2.4"},u={chalk:"^5.6.2",minimist:"^1.2.8",prompts:"^2.4.2"},y={name:e,version:t,description:s,type:i,main:n,module:r,types:c,files:o,exports:d,scripts:p,author:l,license:m,devDependencies:a,dependencies:u};exports.author=l;exports.default=y;exports.dependencies=u;exports.description=s;exports.devDependencies=a;exports.exports=d;exports.files=o;exports.license=m;exports.main=n;exports.module=r;exports.name=e;exports.scripts=p;exports.type=i;exports.types=c;exports.version=t;
@@ -8,5 +8,5 @@ export type OptionProps = {
8
8
  export declare class BadCommandOption extends BobError {
9
9
  readonly param: OptionProps;
10
10
  constructor(param: OptionProps);
11
- pretty(io: Logger): void;
11
+ pretty(logger: Logger): void;
12
12
  }
@@ -8,5 +8,5 @@ export type ParameterProps = {
8
8
  export declare class BadCommandParameter extends BobError {
9
9
  readonly param: ParameterProps;
10
10
  constructor(param: ParameterProps);
11
- pretty(io: Logger): void;
11
+ pretty(logger: Logger): void;
12
12
  }
@@ -3,5 +3,5 @@ import { BobError } from './BobError.js';
3
3
  export declare class CommandNotFoundError extends BobError {
4
4
  readonly command: string;
5
5
  constructor(command: string);
6
- pretty(io: Logger): void;
6
+ pretty(logger: Logger): void;
7
7
  }
@@ -5,5 +5,5 @@ export declare class InvalidOption extends BobError {
5
5
  private option;
6
6
  private optionsSchema;
7
7
  constructor(option: string, optionsSchema?: OptionsSchema);
8
- pretty(io: Logger): void;
8
+ pretty(logger: Logger): void;
9
9
  }
@@ -3,5 +3,5 @@ import { BobError } from './BobError.js';
3
3
  export declare class MissingRequiredArgumentValue extends BobError {
4
4
  readonly argument: string;
5
5
  constructor(argument: string);
6
- pretty(io: Logger): void;
6
+ pretty(logger: Logger): void;
7
7
  }
@@ -3,5 +3,5 @@ import { BobError } from './BobError.js';
3
3
  export declare class MissingRequiredOptionValue extends BobError {
4
4
  readonly option: string;
5
5
  constructor(option: string);
6
- pretty(io: Logger): void;
6
+ pretty(logger: Logger): void;
7
7
  }
@@ -1,5 +1,5 @@
1
1
  "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const y=require("prompts"),a=require("chalk"),H=require("minimist"),M=require("node:fs"),F=require("path");function T(s){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(s){for(const e in s)if(e!=="default"){const i=Object.getOwnPropertyDescriptor(s,e);Object.defineProperty(t,e,i.get?i:{enumerable:!0,get:()=>s[e]})}}return t.default=s,Object.freeze(t)}const W=T(M);class R{logger;constructor(t){this.logger=t.logger}log(...t){this.logger.log(...t)}info(...t){this.logger.info(...t)}warn(...t){this.logger.warn(...t)}error(...t){this.logger.error(...t)}debug(...t){this.logger.debug(...t)}async askForConfirmation(t="Do you want to continue?",e){return(await y({type:"confirm",name:"value",message:t,initial:e??!1})).value}async askForInput(t,e,i){return(await y({type:"text",name:"value",message:t,initial:e,...i}))?.value??null}async askForDate(t,e,i){return(await y({type:"date",name:"value",message:t,initial:e,...i}))?.value??null}async askForList(t,e,i){return(await y({type:"list",name:"value",message:t,initial:e,...i}))?.value??null}async askForToggle(t,e,i){return(await y({type:"toggle",name:"value",message:t,initial:e,...i}))?.value??null}async askForSelect(t,e,i){if(e.length===0)throw new Error("No options provided");const n=[];for(const o of e)typeof o=="string"?n.push({title:o,value:o}):n.push(o);return(await y({type:"select",name:"value",message:t,choices:n,...i}))?.value??null}newLoader(t="",e=["⠙","⠘","⠰","⠴","⠤","⠦","⠆","⠃","⠋","⠉"],i=100){let n=t,r=null,o=0;const m=setInterval(function(){r&&(process.stdout.write(new TextEncoder().encode("\r"+" ".repeat(r.length+5)+"\r")),r=null),process.stdout.write(new TextEncoder().encode("\r"+e[o++]+" "+n)),o=o%e.length},i),u=()=>{clearInterval(m),process.stdout.write(new TextEncoder().encode("\r"+" ".repeat(n.length+5)+"\r"))};return{[Symbol.dispose]:u,[Symbol.asyncDispose]:u,updateText:c=>{r=n,n=c},stop:u}}}class f extends Error{}function k(s){if(s==="string"||s==="number")return null;if(s==="boolean")return!1;if(Array.isArray(s)&&s.length===1){if(s[0]==="string")return[];if(s[0]==="number")return[]}throw new Error("Invalid option type: "+s)}function q(s){return typeof s=="string"||Array.isArray(s)?k(s):s.default!==void 0?s.default:k(s.type)}function g(s){return typeof s=="string"||Array.isArray(s)?{alias:[],default:q(s),description:"",required:!1,secret:!1,type:s,variadic:!1}:{alias:s.alias?Array.isArray(s.alias)?s.alias:[s.alias]:[],default:s.default??q(s.type),description:s.description??"",required:s.required??!1,secret:s.secret??!1,type:s.type,variadic:s.variadic??!1}}class $ extends f{constructor(t,e={}){super(`Invalid option ${t} in not recognized`),this.option=t,this.optionsSchema=e}pretty(t){const e=Object.entries(this.optionsSchema);if(e.length>0){t.log(`
2
- ${a.yellow("Available options")}:`);for(const[i,n]of e){const r=g(n),o=typeof r.alias=="string"?[r.alias]:r.alias,m=Array.isArray(r.type)?`[${r.type[0]}]`:r.type,u=`--${i}${o.length>0?o.map(l=>`, -${l}`).join(""):""}`,c=" ".repeat(30-u.length);t.log(` ${a.green(u)} ${c} ${r.description||"\b"} ${a.white(`(${m})`)}`)}t.log("")}t.log(`${a.white.bgRed(" ERROR ")} Option ${a.bold.yellow(this.option)} is not recognized.`)}}class O extends f{constructor(t){super(`Argument "${t}" is required.`),this.argument=t}pretty(t){t.log(`${a.white.bgRed(" ERROR ")} Argument ${a.bold.yellow(this.argument)} is required.`)}}class N extends f{constructor(t){super(`Argument "${t}" is required.`),this.option=t}pretty(t){t.log(`${a.white.bgRed(" ERROR ")} Option ${a.bold.yellow(this.option)} is required.`)}}class B extends f{constructor(t){let e=`Argument "${t.param}" value is invalid.`;t.reason?e+=` Reason: ${t.reason}`:e+=` Value: "${t.value}"`,super(e),this.param=t}pretty(t){t.log(` ${a.white.bgRed(" ERROR ")} Argument ${a.bold.yellow(this.param.param)} value is invalid. `),(this.param.value||this.param.reason)&&t.log(""),this.param.value&&t.log(` ${a.blue("Value")}: ${this.param.value}`),this.param.reason&&t.log(` ${a.yellow("Reason")}: ${this.param.reason}`)}}class C extends f{constructor(t){let e=`Option "${t.option}" value is invalid.`;t.reason?e+=` Reason: ${t.reason}`:e+=` Value: "${t.value}"`,super(e),this.param=t}pretty(t){t.log(` ${a.white.bgRed(" ERROR ")} Option ${a.bold.yellow(this.param.option)} value is invalid. `),(this.param.value||this.param.reason)&&t.log(""),this.param.value&&t.log(` ${a.blue("Value")}: ${this.param.value}`),this.param.reason&&t.log(` ${a.yellow("Reason")}: ${this.param.reason}`)}}class P extends f{constructor(t){super(`Command "${t}" not found.`),this.command=t}pretty(t){t.log(`${a.bgRed(" ERROR ")} Command ${a.yellow(this.command)} not found.`)}}function w(s,t,e,i){if(s==null)return i??null;if(t==="string")return String(s);if(t==="number"){const n=Number(s);if(isNaN(n))throw new C({option:e,reason:`Expected a number, got "${s}"`});return n}if(t==="boolean")return typeof s=="boolean"?s:s==="true"||s==="1"?!0:s==="false"||s==="0"?!1:!!s;if(Array.isArray(t)){const n=t[0],r=Array.isArray(s)?s:[s];if(n==="string")return r.map(o=>String(o));if(n==="number")return r.map(o=>{const m=Number(o);if(isNaN(m))throw new C({option:e,reason:`Expected array of numbers, got "${o}" in array`});return m})}return s}class x{options;parsedOptions=null;arguments;parsedArguments=null;io;shouldPromptForMissingOptions=!0;constructor(t){this.options=t.options,this.arguments=t.arguments,this.io=t.io}init(t){const{_:e,...i}=H(t);return this.validateUnknownOptions(i),this.parsedOptions=this.handleOptions(i),this.parsedArguments=this.handleArguments(e),{options:this.parsedOptions,arguments:this.parsedArguments}}async validate(){for(const t in this.options)if(g(this.options[t]).required&&(this.parsedOptions?.[t]===void 0||this.parsedOptions?.[t]===null))throw new N(t);for(const t in this.arguments){const e=g(this.arguments[t]),i=this.parsedArguments?.[t];if(e.required&&i==null){if(this.shouldPromptForMissingOptions){const n=await this.promptForArgument(t,e);if(n&&this.parsedArguments){this.parsedArguments[t]=w(n,e.type,t);continue}}throw new O(t)}if(e.required&&e.variadic&&Array.isArray(i)&&i.length===0){if(this.shouldPromptForMissingOptions){const n=await this.promptForArgument(t,e);if(n&&this.parsedArguments){this.parsedArguments[t]=w(n,e.type,t);continue}}throw new O(t)}}}option(t,e){if(!this.parsedOptions)throw new Error("Options have not been parsed yet. Call init() first.");return this.isEmptyValue(this.parsedOptions[t])&&e!==void 0?e:this.parsedOptions[t]}setOption(t,e){if(!this.parsedOptions)throw new Error("Options have not been parsed yet. Call init() first.");if(!(t in this.options))throw new $(t,this.options);this.parsedOptions[t]=e}argument(t,e){if(!this.parsedArguments)throw new Error("Arguments have not been parsed yet. Call init() first.");return this.isEmptyValue(this.parsedArguments[t])&&e!==void 0?e:this.parsedArguments[t]}setArgument(t,e){if(!this.parsedArguments)throw new Error("Arguments have not been parsed yet. Call init() first.");if(!(t in this.arguments))throw new $(t,this.arguments);this.parsedArguments[t]=e}isEmptyValue(t){return t==null||Array.isArray(t)&&t.length===0}validateUnknownOptions(t){const e=new Set;for(const i in this.options){e.add(i);const n=g(this.options[i]);for(const r of n.alias)e.add(r)}for(const i in t)if(!e.has(i))throw new $(i,this.options)}handleOptions(t){const e={};for(const i in this.options){const n=g(this.options[i]);e[i]=this.resolveOptionValue(i,n,t)}return e}handleArguments(t){const e={},i=[...t];for(const n in this.arguments){const r=g(this.arguments[n]);if(r.variadic){e[n]=this.handleVariadicArgument(n,r,i);continue}e[n]=this.resolveArgumentValue(n,r,i.shift())}return e}handleVariadicArgument(t,e,i){return i.length?w(i,e.type,t,e.default):e.default}resolveArgumentValue(t,e,i){return i===void 0?e.default:w(i,e.type,t,e.default)}resolveOptionValue(t,e,i){let n;const r=[t,...e.alias];for(const o of r)if(o in i){n=i[o];break}if(n===void 0){if(e.required)throw new C({option:t,reason:"Required option is missing"});return e.default}return w(n,e.type,t,e.default)}optionDefinitions(){const t={};for(const e in this.options)t[e]=g(this.options[e]);return t}argumentDefinitions(){const t={};for(const e in this.arguments)t[e]=g(this.arguments[e]);return t}availableOptions(){return Object.keys(this.options)}availableArguments(){return Object.keys(this.arguments)}disablePrompting(){return this.shouldPromptForMissingOptions=!1,this}async promptForArgument(t,e){if(!Array.isArray(e.type)&&!["string","number","secret"].includes(e.type))return null;let i=`${a.yellow.bold(t)} is required`;return e.description&&(i+=`: ${a.gray(`(${e.description})`)}`),i+=` ${a.green(`(${e.type}${e.variadic==!0?"[]":""})`)}
2
+ ${a.yellow("Available options")}:`);for(const[i,n]of e){const r=g(n),o=r.alias?typeof r.alias=="string"?[r.alias]:r.alias:[],m=Array.isArray(r.type)?`[${r.type[0]}]`:r.type,u=`--${i}${o.length>0?o.map(l=>`, -${l}`).join(""):""}`,c=" ".repeat(30-u.length);t.log(` ${a.green(u)} ${c} ${r.description||"\b"} ${a.white(`(${m})`)}`)}t.log("")}t.log(`${a.white.bgRed(" ERROR ")} Option ${a.bold.yellow(this.option)} is not recognized.`)}}class O extends f{constructor(t){super(`Argument "${t}" is required.`),this.argument=t}pretty(t){t.log(`${a.white.bgRed(" ERROR ")} Argument ${a.bold.yellow(this.argument)} is required.`)}}class N extends f{constructor(t){super(`Argument "${t}" is required.`),this.option=t}pretty(t){t.log(`${a.white.bgRed(" ERROR ")} Option ${a.bold.yellow(this.option)} is required.`)}}class B extends f{constructor(t){let e=`Argument "${t.param}" value is invalid.`;t.reason?e+=` Reason: ${t.reason}`:e+=` Value: "${t.value}"`,super(e),this.param=t}pretty(t){t.log(` ${a.white.bgRed(" ERROR ")} Argument ${a.bold.yellow(this.param.param)} value is invalid. `),(this.param.value||this.param.reason)&&t.log(""),this.param.value&&t.log(` ${a.blue("Value")}: ${this.param.value}`),this.param.reason&&t.log(` ${a.yellow("Reason")}: ${this.param.reason}`)}}class C extends f{constructor(t){let e=`Option "${t.option}" value is invalid.`;t.reason?e+=` Reason: ${t.reason}`:e+=` Value: "${t.value}"`,super(e),this.param=t}pretty(t){t.log(` ${a.white.bgRed(" ERROR ")} Option ${a.bold.yellow(this.param.option)} value is invalid. `),(this.param.value||this.param.reason)&&t.log(""),this.param.value&&t.log(` ${a.blue("Value")}: ${this.param.value}`),this.param.reason&&t.log(` ${a.yellow("Reason")}: ${this.param.reason}`)}}class P extends f{constructor(t){super(`Command "${t}" not found.`),this.command=t}pretty(t){t.log(`${a.bgRed(" ERROR ")} Command ${a.yellow(this.command)} not found.`)}}function w(s,t,e,i){if(s==null)return i??null;if(t==="string")return String(s);if(t==="number"){const n=Number(s);if(isNaN(n))throw new C({option:e,reason:`Expected a number, got "${s}"`});return n}if(t==="boolean")return typeof s=="boolean"?s:s==="true"||s==="1"?!0:s==="false"||s==="0"?!1:!!s;if(Array.isArray(t)){const n=t[0],r=Array.isArray(s)?s:[s];if(n==="string")return r.map(o=>String(o));if(n==="number")return r.map(o=>{const m=Number(o);if(isNaN(m))throw new C({option:e,reason:`Expected array of numbers, got "${o}" in array`});return m})}return s}class x{options;parsedOptions=null;arguments;parsedArguments=null;io;shouldPromptForMissingOptions=!0;constructor(t){this.options=t.options,this.arguments=t.arguments,this.io=t.io}init(t){const{_:e,...i}=H(t);return this.validateUnknownOptions(i),this.parsedOptions=this.handleOptions(i),this.parsedArguments=this.handleArguments(e),{options:this.parsedOptions,arguments:this.parsedArguments}}async validate(){for(const t in this.options)if(g(this.options[t]).required&&(this.parsedOptions?.[t]===void 0||this.parsedOptions?.[t]===null))throw new N(t);for(const t in this.arguments){const e=g(this.arguments[t]),i=this.parsedArguments?.[t];if(e.required&&i==null){if(this.shouldPromptForMissingOptions){const n=await this.promptForArgument(t,e);if(n&&this.parsedArguments){this.parsedArguments[t]=w(n,e.type,t);continue}}throw new O(t)}if(e.required&&e.variadic&&Array.isArray(i)&&i.length===0){if(this.shouldPromptForMissingOptions){const n=await this.promptForArgument(t,e);if(n&&this.parsedArguments){this.parsedArguments[t]=w(n,e.type,t);continue}}throw new O(t)}}}option(t,e){if(!this.parsedOptions)throw new Error("Options have not been parsed yet. Call init() first.");return this.isEmptyValue(this.parsedOptions[t])&&e!==void 0?e:this.parsedOptions[t]}setOption(t,e){if(!this.parsedOptions)throw new Error("Options have not been parsed yet. Call init() first.");if(!(t in this.options))throw new $(t,this.options);this.parsedOptions[t]=e}argument(t,e){if(!this.parsedArguments)throw new Error("Arguments have not been parsed yet. Call init() first.");return this.isEmptyValue(this.parsedArguments[t])&&e!==void 0?e:this.parsedArguments[t]}setArgument(t,e){if(!this.parsedArguments)throw new Error("Arguments have not been parsed yet. Call init() first.");if(!(t in this.arguments))throw new $(t,this.arguments);this.parsedArguments[t]=e}isEmptyValue(t){return t==null||Array.isArray(t)&&t.length===0}validateUnknownOptions(t){const e=new Set;for(const i in this.options){e.add(i);const n=g(this.options[i]);for(const r of n.alias)e.add(r)}for(const i in t)if(!e.has(i))throw new $(i,this.options)}handleOptions(t){const e={};for(const i in this.options){const n=g(this.options[i]);e[i]=this.resolveOptionValue(i,n,t)}return e}handleArguments(t){const e={},i=[...t];for(const n in this.arguments){const r=g(this.arguments[n]);if(r.variadic){e[n]=this.handleVariadicArgument(n,r,i);continue}e[n]=this.resolveArgumentValue(n,r,i.shift())}return e}handleVariadicArgument(t,e,i){return i.length?w(i,e.type,t,e.default):e.default}resolveArgumentValue(t,e,i){return i===void 0?e.default:w(i,e.type,t,e.default)}resolveOptionValue(t,e,i){let n;const r=[t,...e.alias];for(const o of r)if(o in i){n=i[o];break}if(n===void 0){if(e.required)throw new C({option:t,reason:"Required option is missing"});return e.default}return w(n,e.type,t,e.default)}optionDefinitions(){const t={};for(const e in this.options)t[e]=g(this.options[e]);return t}argumentDefinitions(){const t={};for(const e in this.arguments)t[e]=g(this.arguments[e]);return t}availableOptions(){return Object.keys(this.options)}availableArguments(){return Object.keys(this.arguments)}disablePrompting(){return this.shouldPromptForMissingOptions=!1,this}async promptForArgument(t,e){if(!Array.isArray(e.type)&&!["string","number","secret"].includes(e.type))return null;let i=`${a.yellow.bold(t)} is required`;return e.description&&(i+=`: ${a.gray(`(${e.description})`)}`),i+=` ${a.green(`(${e.type}${e.variadic==!0?"[]":""})`)}
3
3
  `,Array.isArray(e.type)?(i+=`Please provide one or more values, separated by commas:
4
4
  `,await this.io.askForList(i,void 0,{separator:",",validate:n=>{if(!n.length)return"Please enter at least one value";if(e.type[0]==="number"){for(const r of n.split(","))if(isNaN(Number(r)))return"Please enter only valid numbers"}return!0}})):await this.io.askForInput(i,void 0,{type:e.type==="number"?"number":e.secret?"password":"text",validate:n=>{if(n==null||typeof n=="string"&&!n.length)return"This value is required";if(e.type==="number"){const r=Number(n);if(isNaN(r))return"Please enter a valid number"}else if(e.type==="string"&&(typeof n!="string"||!n.length))return"Please enter a valid text";return!0}})}}function A(s){return new Array(s+5).join(" ")}class L{type="boolean";option="help";alias=["h"];default=!1;description=`Display help for the given command. When no command is given display help for the ${a.green("list")} command`;async handler(){const t=this.parser.argumentDefinitions(),e=this.parser.optionDefinitions(),i=Object.entries(t),n=Object.entries(e),r=n.map(([l,d])=>{const h=Array.isArray(d.alias)?d.alias:d.alias?[d.alias]:[];return{name:l,...d,optionWithAlias:`--${l}${h.map(p=>`, -${p}`).join("")}`}}),o=i.filter(([,l])=>l.required);this.io.log(a.yellow("Description:")),this.io.log(` ${this.description}
5
5
  `),this.io.log(a.yellow("Usage:")),this.io.log(` ${this.command} ${o.length>0?o.map(([l])=>`<${l}>`).join(" "):"\b"} [options]`);const m=Math.max(...r.map(l=>l.optionWithAlias.length),0),u=Math.max(...i.map(([l])=>l.length),0),c=u>m?u:m;if(i.length>0){this.io.log(`
@@ -8,7 +8,7 @@ ${a.yellow("Options")}:`);for(const l of r){const d=A(c-l.optionWithAlias.length
8
8
  ${a.yellow("Examples")}:`);let l=process.argv[0].split("/").pop();l==="node"&&(l+=" "+process.argv[1].split("/").pop());for(const[d,h]of this.commandsExamples.entries())d>0&&this.io.log(""),this.io.log(` ${h.description}
9
9
  `),this.io.log(` ${a.green(`${l} ${h.command}`)}`)}return-1}}class v{_command;description;group;commandsExamples=[];get command(){return this._command}ctx;io;logger;parser;disablePromptingFlag=!1;_preHandler;_handler;tmp;defaultOptions(){return[new L]}newCommandParser(t){return new x({io:t.io,options:t.options,arguments:t.arguments})}newCommandIO(t){return new R(t)}constructor(t,e){this._command=t,this.description=e?.description??"",this.group=e?.group,this.tmp={options:e?.options??{},arguments:e?.arguments??{}};const i=this.defaultOptions();if(i.length>0)for(const n of i)this.tmp.options[n.option]=n}disablePrompting(){return this.disablePromptingFlag=!0,this}preHandler(t){return this._preHandler=t,this}handler(t){return this._handler=t,this}options(t){return this.tmp={options:{...this.tmp?.options??{},...t},arguments:this.tmp?.arguments??{}},this}arguments(t){return this.tmp={options:this.tmp?.options??{},arguments:{...this.tmp?.arguments??{},...t}},this}async run(t){if(!this._handler&&!this.handle)throw new Error(`No handler defined for command ${this.command||"(unknown)"}`);let e;if(this.ctx=t.ctx,this.logger=t.logger,this.io=this.newCommandIO({logger:t.logger}),t&&"args"in t){const r=this.tmp?.options??{};for(const o of this.defaultOptions())o.option in r||(r[o.option]=o);this.parser=this.newCommandParser({io:this.io,options:r,arguments:this.tmp?.arguments??{}}),e=this.parser.init(t.args);for(const o of this.defaultOptions())if(e.options[o.option]===!0){const m=await o.handler.call(this);if(m&&m!==0)return m}this.disablePromptingFlag&&this.parser.disablePrompting(),await this.parser.validate()}else e={options:t.options,arguments:t.arguments};const i=this.preHandle?await this.preHandle():null;if(i&&i!==0)return i;if(!this._handler&&this.handle)this._handler=this.handle.bind(this);else if(!this._handler)throw new Error(`No handler defined for command ${this.command||"(unknown)"}`);return await this._handler(t.ctx,e)??0}}class b extends x{command;constructor(t){const e=b.parseSignature(t.signature,t.helperDefinitions,t.defaultOptions);super({io:t.io,options:e.options,arguments:e.arguments}),this.command=e.command}static parseSignature(t,e,i){const[n,...r]=t.split(/\{(.*?)\}/g).map(u=>u.trim()).filter(Boolean),o={},m={};for(const u of r){const{name:c,isOption:l,definition:d}=b.parseParamSignature(u,e);l?o[c]=d:m[c]=d}for(const u of i)o[u.option]={type:u.type,required:u.required,alias:u.alias,variadic:u.variadic??!1,description:u.description,default:u.default??null};return{command:n,options:o,arguments:m}}static parseParamSignature(t,e){let i=t,n=!1;const r={required:!0,type:"string",description:void 0,default:null,variadic:!1};if(i.includes(":")){const[o,m]=i.split(":");i=o.trim(),r.description=m.trim()}if(i.includes("=")){const[o,m]=i.split("=");i=o.trim(),r.default=m.trim(),r.required=!1,typeof r.default=="string"&&!r.default.length?r.default=null:r.default==="true"?(r.default=!0,r.type="boolean"):r.default==="false"&&(r.default=!1,r.type="boolean")}else i.startsWith("--")&&(r.required=!1,r.default=!1,r.type="boolean");if(i.includes("|")){const[o,...m]=i.split("|");i=o.trim(),r.alias=m.map(u=>u.trim())}return i.startsWith("--")&&(n=!0,i=i.slice(2)),r.default==="*"&&(r.default=[],r.type=["string"]),i.endsWith("?")&&(r.required=!1,i=i.slice(0,-1)),i.endsWith("*")&&(r.type=["string"],r.variadic=!0,r.default=[],i=i.slice(0,-1)),r.description=r.description??e[i]??e[`--${i}`],{name:i,isOption:n,definition:r}}}class _ extends v{helperDefinitions={};get command(){return this.parser?this.parser.command:this.signature.split(" ")[0]}newCommandParser(t){return new b({io:t.io,signature:this.signature,helperDefinitions:this.helperDefinitions,defaultOptions:this.defaultOptions()})}constructor(){super("")}option(t,e=null){return this.parser.option(t,e)}argument(t,e=null){return this.parser.argument(t,e)}async askForConfirmation(...t){return this.io.askForConfirmation(...t)}async askForInput(...t){return this.io.askForInput(...t)}async askForSelect(...t){return this.io.askForSelect(...t)}newLoader(...t){return this.io.newLoader(...t)}}class S{level;constructor(t={}){this.level=t.level??"info"}shouldLog(t){const e=["debug","info","warn","error"],i=e.indexOf(this.level);return e.indexOf(t)>=i}setLevel(t){this.level=t}getLevel(){return this.level}log(...t){console.log(...t)}info(...t){this.shouldLog("info")&&console.log(...t)}warn(...t){this.shouldLog("warn")&&console.warn(...t)}error(...t){this.shouldLog("error")&&console.error(...t)}debug(...t){this.shouldLog("debug")&&console.log(...t)}}class I{getBigrams(t){const e=[],i=t.toLowerCase();for(let n=0;n<i.length-1;n++)e.push(i.slice(n,n+2));return e}calculateSimilarity(t,e){if(t===e)return 1;if(t.length<2||e.length<2)return 0;const i=this.getBigrams(t),n=this.getBigrams(e),r=new Set(n);let o=0;for(const m of i)r.has(m)&&(o++,r.delete(m));return 2*o/(i.length+n.length)}findBestMatch(t,e){const i=e.map(o=>({target:o,rating:this.calculateSimilarity(t,o)}));let n=0,r=i[0]?.rating??0;for(let o=1;o<i.length;o++)i[o].rating>r&&(r=i[o].rating,n=o);return{ratings:i,bestMatch:i[n],bestMatchIndex:n}}}class V{commands={};io;logger;stringSimilarity;newCommandIO(t){return new R(t)}constructor(t){this.logger=t?.logger??new S,this.io=this.newCommandIO({logger:this.logger}),this.stringSimilarity=t?.stringSimilarity??new I}getAvailableCommands(){return Object.keys(this.commands)}getCommands(){return Object.values(this.commands)}importFile=async t=>(await import(t)).default;commandResolver=async t=>{let e=await this.importFile(t);if(!e)throw new Error(`The command at path ${t} does not have a default export.`);return e&&typeof e=="object"&&"default"in e&&(e=e.default),typeof e=="function"?new e:e instanceof v?e:null};withCommandResolver(t){return this.commandResolver=t,this}withFileImporter(t){return this.importFile=t,this}registerCommand(t,e=!1){const i=t.command;if(!i)throw new Error("Command signature is invalid, it must have a command name.");if(!e&&this.commands[i])throw new Error(`Command ${i} already registered.`);this.commands[i]=t}async loadCommandsPath(t){for await(const e of this.listCommandsFiles(t))try{const i=await this.commandResolver(e);i instanceof v&&this.registerCommand(i)}catch(i){throw new Error(`Command ${e} failed to load. ${i}`,{cause:i})}}async runCommand(t,e,...i){const n=typeof e=="string"?this.commands[e]:e,r=typeof e=="string"?e:n.command;if(!n){const o=await this.suggestCommand(r);return o?await this.runCommand(t,o,...i):1}return await n.run({ctx:t,logger:this.logger,args:i})??0}async suggestCommand(t){const e=this.getAvailableCommands(),{bestMatch:i,bestMatchIndex:n,ratings:r}=this.stringSimilarity.findBestMatch(t,e),o=r.filter(m=>m.rating>.3).map(m=>m.target);if(i.rating>0&&o.length<=1||i.rating>.7&&o.length>1){const m=e[n];return await this.askRunSimilarCommand(t,m)?m:null}if(o.length){this.io.error(`${a.bgRed(" ERROR ")} Command ${a.yellow(t)} not found.
10
10
  `);const m=await this.io.askForSelect(a.green("Did you mean to run one of these commands instead?"),o);if(m)return m}throw new P(t)}async askRunSimilarCommand(t,e){return this.io.error(`${a.bgRed(" ERROR ")} Command ${a.yellow(t)} not found.
11
- `),this.io.askForConfirmation(`${a.green(`Do you want to run ${a.yellow(e)} instead?`)} `)}async*listCommandsFiles(t){const e=W.readdirSync(t,{withFileTypes:!0});for(const i of e){const n=F.resolve(t,i.name);if(i.isDirectory())yield*this.listCommandsFiles(F.resolve(t,i.name));else{if(!n.endsWith(".ts")&&!n.endsWith(".js")&&!n.endsWith(".mjs")&&!n.endsWith(".cjs"))continue;yield n}}}}class D{logger;constructor(t){this.logger=t}handle(t){if(t instanceof f)return t.pretty(this.logger),-1;throw t}}class G extends v{constructor(t){super("help",{description:a.bold("Show help information about the CLI and its commands")}),this.opts=t}async handle(){const t=this.opts.commandRegistry.getCommands(),e=this.opts.cliName??"Bob CLI",i=this.opts.cliVersion??"0.0.0",n=(await Promise.resolve().then(()=>require("./package-o2EGFSAP.cjs")))?.default?.version??"0.0.0";this.io.log(`${e} ${a.green(i)} (core: ${a.yellow(n)})
11
+ `),this.io.askForConfirmation(`${a.green(`Do you want to run ${a.yellow(e)} instead?`)} `)}async*listCommandsFiles(t){const e=W.readdirSync(t,{withFileTypes:!0});for(const i of e){const n=F.resolve(t,i.name);if(i.isDirectory())yield*this.listCommandsFiles(F.resolve(t,i.name));else{if(!n.endsWith(".ts")&&!n.endsWith(".js")&&!n.endsWith(".mjs")&&!n.endsWith(".cjs"))continue;yield n}}}}class D{logger;constructor(t){this.logger=t}handle(t){if(t instanceof f)return t.pretty(this.logger),-1;throw t}}class G extends v{constructor(t){super("help",{description:a.bold("Show help information about the CLI and its commands")}),this.opts=t}async handle(){const t=this.opts.commandRegistry.getCommands(),e=this.opts.cliName??"Bob CLI",i=this.opts.cliVersion??"0.0.0",n=(await Promise.resolve().then(()=>require("../package-Bmqo4lY0.cjs")))?.default?.version??"0.0.0";this.io.log(`${e} ${a.green(i)} (core: ${a.yellow(n)})
12
12
 
13
13
  ${a.yellow("Usage")}:
14
14
  command [options] [arguments]
@@ -0,0 +1,33 @@
1
+ const t = "bob-core", s = "2.0.0-beta.17", e = "BOB Core", i = "module", n = "./dist/cjs/src/index.js", r = "./dist/esm/src/index.js", c = "./dist/esm/src/index.d.ts", o = ["dist"], d = { ".": { import: { types: "./dist/esm/src/index.d.ts", default: "./dist/esm/src/index.js" }, require: { types: "./dist/cjs/src/index.d.ts", default: "./dist/cjs/src/index.js" } } }, p = { start: "node -r @swc-node/register debug/main.ts", build: "rimraf ./dist && vite build", typecheck: "tsc --noEmit", prepack: "npm run build", test: "vitest run", lint: "eslint .", "lint:fix": "eslint . --fix" }, l = "Léo Hubert", m = "ISC", a = { "@eslint/js": "^9.37.0", "@faker-js/faker": "^10.0.0", "@swc-node/register": "^1.11.1", "@trivago/prettier-plugin-sort-imports": "^5.2.2", "@types/minimist": "^1.2.5", "@types/node": "^20.14.5", "@types/prompts": "^2.4.9", "@types/string-similarity": "^4.0.2", "@vitest/coverage-v8": "^3.2.4", eslint: "^9.37.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-prettier": "^5.5.4", prettier: "^3.6.2", rimraf: "^6.0.1", tsx: "^4.20.6", typescript: "^5.9.3", "typescript-eslint": "^8.46.0", vite: "^7.2.7", "vite-plugin-dts": "^4.5.4", vitest: "^3.2.4" }, u = { chalk: "^5.6.2", minimist: "^1.2.8", prompts: "^2.4.2" }, x = {
2
+ name: t,
3
+ version: s,
4
+ description: e,
5
+ type: i,
6
+ main: n,
7
+ module: r,
8
+ types: c,
9
+ files: o,
10
+ exports: d,
11
+ scripts: p,
12
+ author: l,
13
+ license: m,
14
+ devDependencies: a,
15
+ dependencies: u
16
+ };
17
+ export {
18
+ l as author,
19
+ x as default,
20
+ u as dependencies,
21
+ e as description,
22
+ a as devDependencies,
23
+ d as exports,
24
+ o as files,
25
+ m as license,
26
+ n as main,
27
+ r as module,
28
+ t as name,
29
+ p as scripts,
30
+ i as type,
31
+ c as types,
32
+ s as version
33
+ };
@@ -8,5 +8,5 @@ export type OptionProps = {
8
8
  export declare class BadCommandOption extends BobError {
9
9
  readonly param: OptionProps;
10
10
  constructor(param: OptionProps);
11
- pretty(io: Logger): void;
11
+ pretty(logger: Logger): void;
12
12
  }
@@ -8,5 +8,5 @@ export type ParameterProps = {
8
8
  export declare class BadCommandParameter extends BobError {
9
9
  readonly param: ParameterProps;
10
10
  constructor(param: ParameterProps);
11
- pretty(io: Logger): void;
11
+ pretty(logger: Logger): void;
12
12
  }
@@ -3,5 +3,5 @@ import { BobError } from './BobError.js';
3
3
  export declare class CommandNotFoundError extends BobError {
4
4
  readonly command: string;
5
5
  constructor(command: string);
6
- pretty(io: Logger): void;
6
+ pretty(logger: Logger): void;
7
7
  }
@@ -5,5 +5,5 @@ export declare class InvalidOption extends BobError {
5
5
  private option;
6
6
  private optionsSchema;
7
7
  constructor(option: string, optionsSchema?: OptionsSchema);
8
- pretty(io: Logger): void;
8
+ pretty(logger: Logger): void;
9
9
  }
@@ -3,5 +3,5 @@ import { BobError } from './BobError.js';
3
3
  export declare class MissingRequiredArgumentValue extends BobError {
4
4
  readonly argument: string;
5
5
  constructor(argument: string);
6
- pretty(io: Logger): void;
6
+ pretty(logger: Logger): void;
7
7
  }
@@ -3,5 +3,5 @@ import { BobError } from './BobError.js';
3
3
  export declare class MissingRequiredOptionValue extends BobError {
4
4
  readonly option: string;
5
5
  constructor(option: string);
6
- pretty(io: Logger): void;
6
+ pretty(logger: Logger): void;
7
7
  }
@@ -147,7 +147,7 @@ class b extends f {
147
147
  t.log(`
148
148
  ${a.yellow("Available options")}:`);
149
149
  for (const [i, n] of e) {
150
- const s = g(n), o = typeof s.alias == "string" ? [s.alias] : s.alias, m = Array.isArray(s.type) ? `[${s.type[0]}]` : s.type, u = `--${i}${o.length > 0 ? o.map((l) => `, -${l}`).join("") : ""}`, h = " ".repeat(30 - u.length);
150
+ const s = g(n), o = s.alias ? typeof s.alias == "string" ? [s.alias] : s.alias : [], m = Array.isArray(s.type) ? `[${s.type[0]}]` : s.type, u = `--${i}${o.length > 0 ? o.map((l) => `, -${l}`).join("") : ""}`, h = " ".repeat(30 - u.length);
151
151
  t.log(` ${a.green(u)} ${h} ${s.description || "\b"} ${a.white(`(${m})`)}`);
152
152
  }
153
153
  t.log("");
@@ -937,7 +937,7 @@ class M extends v {
937
937
  }), this.opts = t;
938
938
  }
939
939
  async handle() {
940
- const t = this.opts.commandRegistry.getCommands(), e = this.opts.cliName ?? "Bob CLI", i = this.opts.cliVersion ?? "0.0.0", n = (await import("./package-C-2LYcDa.js"))?.default?.version ?? "0.0.0";
940
+ const t = this.opts.commandRegistry.getCommands(), e = this.opts.cliName ?? "Bob CLI", i = this.opts.cliVersion ?? "0.0.0", n = (await import("../package-DGEyQNJq.js"))?.default?.version ?? "0.0.0";
941
941
  this.io.log(`${e} ${a.green(i)} (core: ${a.yellow(n)})
942
942
 
943
943
  ${a.yellow("Usage")}:
package/package.json CHANGED
@@ -1,23 +1,22 @@
1
1
  {
2
2
  "name": "bob-core",
3
- "version": "2.0.0-beta.15",
3
+ "version": "2.0.0-beta.17",
4
4
  "description": "BOB Core",
5
5
  "type": "module",
6
- "sideEffects": false,
7
- "files": [
8
- "dist/**"
9
- ],
6
+ "main": "./dist/cjs/src/index.js",
7
+ "module": "./dist/esm/src/index.js",
8
+ "types": "./dist/esm/src/index.d.ts",
9
+ "files": ["dist"],
10
10
  "exports": {
11
11
  ".": {
12
- "import": "./dist/esm/index.js",
13
- "require": "./dist/cjs/index.js"
14
- }
15
- },
16
- "typesVersions": {
17
- "*": {
18
- "*": [
19
- "./dist/cjs/*.d.ts"
20
- ]
12
+ "import": {
13
+ "types": "./dist/esm/src/index.d.ts",
14
+ "default": "./dist/esm/src/index.js"
15
+ },
16
+ "require": {
17
+ "types": "./dist/cjs/src/index.d.ts",
18
+ "default": "./dist/cjs/src/index.js"
19
+ }
21
20
  }
22
21
  },
23
22
  "scripts": {
@@ -47,9 +46,9 @@
47
46
  "prettier": "^3.6.2",
48
47
  "rimraf": "^6.0.1",
49
48
  "tsx": "^4.20.6",
50
- "typescript": "^5.7.3",
49
+ "typescript": "^5.9.3",
51
50
  "typescript-eslint": "^8.46.0",
52
- "vite": "^7.1.6",
51
+ "vite": "^7.2.7",
53
52
  "vite-plugin-dts": "^4.5.4",
54
53
  "vitest": "^3.2.4"
55
54
  },
@@ -1,2 +0,0 @@
1
- export * from './src/index'
2
- export {}
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e="bob-core",t="2.0.0-beta.15",s="BOB Core",i="module",n=!1,r=["dist/**"],o={".":{import:"./dist/esm/index.js",require:"./dist/cjs/index.js"}},c={"*":{"*":["./dist/cjs/*.d.ts"]}},p={start:"node -r @swc-node/register debug/main.ts",build:"rimraf ./dist && vite build",typecheck:"tsc --noEmit",prepack:"npm run build",test:"vitest run",lint:"eslint .","lint:fix":"eslint . --fix"},d="Léo Hubert",l="ISC",a={"@eslint/js":"^9.37.0","@faker-js/faker":"^10.0.0","@swc-node/register":"^1.11.1","@trivago/prettier-plugin-sort-imports":"^5.2.2","@types/minimist":"^1.2.5","@types/node":"^20.14.5","@types/prompts":"^2.4.9","@types/string-similarity":"^4.0.2","@vitest/coverage-v8":"^3.2.4",eslint:"^9.37.0","eslint-config-prettier":"^10.1.8","eslint-plugin-prettier":"^5.5.4",prettier:"^3.6.2",rimraf:"^6.0.1",tsx:"^4.20.6",typescript:"^5.7.3","typescript-eslint":"^8.46.0",vite:"^7.1.6","vite-plugin-dts":"^4.5.4",vitest:"^3.2.4"},m={chalk:"^5.6.2",minimist:"^1.2.8",prompts:"^2.4.2"},u={name:e,version:t,description:s,type:i,sideEffects:n,files:r,exports:o,typesVersions:c,scripts:p,author:d,license:l,devDependencies:a,dependencies:m};exports.author=d;exports.default=u;exports.dependencies=m;exports.description=s;exports.devDependencies=a;exports.exports=o;exports.files=r;exports.license=l;exports.name=e;exports.scripts=p;exports.sideEffects=n;exports.type=i;exports.typesVersions=c;exports.version=t;
@@ -1,11 +0,0 @@
1
- import { Mocked } from 'vitest';
2
- import { Logger } from './Logger.js';
3
- export type TestLogger = Mocked<Logger>;
4
- export declare function newTestLogger(): TestLogger;
5
- /**
6
- * Creates test fixtures with a mocked logger
7
- * @returns Object containing mocked logger instance
8
- */
9
- export declare function newFixtures(): {
10
- logger: TestLogger;
11
- };
@@ -1,2 +0,0 @@
1
- export * from './src/index'
2
- export {}
@@ -1,31 +0,0 @@
1
- const t = "bob-core", e = "2.0.0-beta.15", s = "BOB Core", i = "module", m = !1, n = ["dist/**"], r = { ".": { import: "./dist/esm/index.js", require: "./dist/cjs/index.js" } }, o = { "*": { "*": ["./dist/cjs/*.d.ts"] } }, c = { start: "node -r @swc-node/register debug/main.ts", build: "rimraf ./dist && vite build", typecheck: "tsc --noEmit", prepack: "npm run build", test: "vitest run", lint: "eslint .", "lint:fix": "eslint . --fix" }, p = "Léo Hubert", d = "ISC", l = { "@eslint/js": "^9.37.0", "@faker-js/faker": "^10.0.0", "@swc-node/register": "^1.11.1", "@trivago/prettier-plugin-sort-imports": "^5.2.2", "@types/minimist": "^1.2.5", "@types/node": "^20.14.5", "@types/prompts": "^2.4.9", "@types/string-similarity": "^4.0.2", "@vitest/coverage-v8": "^3.2.4", eslint: "^9.37.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-prettier": "^5.5.4", prettier: "^3.6.2", rimraf: "^6.0.1", tsx: "^4.20.6", typescript: "^5.7.3", "typescript-eslint": "^8.46.0", vite: "^7.1.6", "vite-plugin-dts": "^4.5.4", vitest: "^3.2.4" }, a = { chalk: "^5.6.2", minimist: "^1.2.8", prompts: "^2.4.2" }, f = {
2
- name: t,
3
- version: e,
4
- description: s,
5
- type: i,
6
- sideEffects: !1,
7
- files: n,
8
- exports: r,
9
- typesVersions: o,
10
- scripts: c,
11
- author: p,
12
- license: d,
13
- devDependencies: l,
14
- dependencies: a
15
- };
16
- export {
17
- p as author,
18
- f as default,
19
- a as dependencies,
20
- s as description,
21
- l as devDependencies,
22
- r as exports,
23
- n as files,
24
- d as license,
25
- t as name,
26
- c as scripts,
27
- m as sideEffects,
28
- i as type,
29
- o as typesVersions,
30
- e as version
31
- };
@@ -1,11 +0,0 @@
1
- import { Mocked } from 'vitest';
2
- import { Logger } from './Logger.js';
3
- export type TestLogger = Mocked<Logger>;
4
- export declare function newTestLogger(): TestLogger;
5
- /**
6
- * Creates test fixtures with a mocked logger
7
- * @returns Object containing mocked logger instance
8
- */
9
- export declare function newFixtures(): {
10
- logger: TestLogger;
11
- };