@qui-cli/plugin 3.0.0 → 4.1.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/CHANGELOG.md CHANGED
@@ -2,6 +2,37 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
4
4
 
5
+ ## [4.1.0](https://github.com/battis/qui-cli/compare/plugin/4.0.0...plugin/4.1.0) (2026-01-18)
6
+
7
+
8
+ ### Features
9
+
10
+ * deprecated Plugin.hydrate() ([4194966](https://github.com/battis/qui-cli/commit/41949660396847f2560675242aed460370a3b7b4))
11
+ * simple Plugin.Conf.defaultHook() factory ([ee881f6](https://github.com/battis/qui-cli/commit/ee881f6bf91b39876dc05a49f434260725e52301))
12
+
13
+
14
+ ### Bug Fixes
15
+
16
+ * compile against Node.js v24 ([7b06b4f](https://github.com/battis/qui-cli/commit/7b06b4f4ac4f9688719041ab8b1d837b3a0ee214))
17
+ * no longer require ESM modules only as plugins ([cbf178c](https://github.com/battis/qui-cli/commit/cbf178c8a6f3cec49aff8b6de08fd547e66fb9f7))
18
+
19
+ ## [4.0.0](https://github.com/battis/qui-cli/compare/plugin/3.0.0...plugin/4.0.0) (2025-11-07)
20
+
21
+
22
+ ### ⚠ BREAKING CHANGES
23
+
24
+ * group arguments by plugin in usage
25
+ * auto-document default arg values
26
+
27
+ ### revert
28
+
29
+ * group arguments by plugin in usage ([ec3d4bf](https://github.com/battis/qui-cli/commit/ec3d4bf6ef9c59a6da3ede8603554d2dcd2581ad))
30
+
31
+
32
+ ### Features
33
+
34
+ * auto-document default arg values ([e01e157](https://github.com/battis/qui-cli/commit/e01e157f06a3a801628ca79366e3f0060be2322e))
35
+
5
36
  ## [3.0.0](https://github.com/battis/qui-cli/compare/plugin/2.4.2...plugin/3.0.0) (2025-08-02)
6
37
 
7
38
 
package/README.md CHANGED
@@ -158,7 +158,7 @@ export function options() {
158
158
  },
159
159
  opt: {
160
160
  bar: {
161
- description: `Bar value (default: "argle-bargle")`,
161
+ description: `Bar value`,
162
162
  short: 'b',
163
163
  default: 'argle-bargle'
164
164
  }
package/dist/Conf.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ export type Base = Record<string, unknown>;
2
+ export type Hook<C extends Base = Base> = (config: C) => void | Promise<void>;
3
+ export type Validator<C extends Base = Base> = Record<keyof C, (proposal?: unknown) => boolean | Promise<boolean>>;
4
+ export declare function propose<C extends Base = Base>(config: C, proposal?: C, validator?: Validator<C>): Promise<void>;
5
+ export declare function defaultHook<C extends Base = Base>(config: C, validator?: Validator<C>): Hook<C>;
package/dist/Conf.js ADDED
@@ -0,0 +1,12 @@
1
+ export async function propose(config, proposal = {}, validator = {}) {
2
+ for (const key in proposal) {
3
+ if (proposal[key] !== undefined) {
4
+ if (!validator[key] || (await validator[key](proposal[key]))) {
5
+ config[key] = proposal[key];
6
+ }
7
+ }
8
+ }
9
+ }
10
+ export function defaultHook(config, validator) {
11
+ return async (proposal = {}) => propose(config, proposal, validator);
12
+ }
@@ -1 +1,2 @@
1
+ /** @deprecated use default */
1
2
  export declare function hydrate<Fallback, Proposed extends Fallback | undefined>(proposed: Proposed, fallback: Fallback): Fallback;
@@ -1,3 +1,4 @@
1
+ /** @deprecated use default */
1
2
  export function hydrate(proposed, fallback) {
2
3
  if (proposed === undefined) {
3
4
  return fallback;
package/dist/Init.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ import { ConfigSetFromMetaSet, OptionsResults } from 'jackspeak';
2
+ import * as Opt from './Opt.js';
3
+ type FlattenConfigMetaSets<O extends Opt.Options> = ConfigSetFromMetaSet<'number', false, Exclude<O['num'], undefined>> & ConfigSetFromMetaSet<'number', true, Exclude<O['numList'], undefined>> & ConfigSetFromMetaSet<'string', false, Exclude<O['opt'], undefined>> & ConfigSetFromMetaSet<'string', false, Exclude<O['opt'], undefined>> & ConfigSetFromMetaSet<'string', true, Exclude<O['optList'], undefined>> & ConfigSetFromMetaSet<'boolean', false, Exclude<O['flag'], undefined>> & ConfigSetFromMetaSet<'boolean', true, Exclude<O['flagList'], undefined>> & Exclude<O['fields'], undefined>;
4
+ export type Arguments<O extends Opt.Options> = {
5
+ positionals: (string | undefined)[];
6
+ values: OptionsResults<FlattenConfigMetaSets<O>>;
7
+ };
8
+ export type ExpectedArguments<H extends Opt.Hook> = Arguments<Awaited<ReturnType<H>>>;
9
+ export type Hook<O extends Opt.Options = Opt.Options> = (args: Arguments<O>) => void | Promise<void>;
10
+ export {};
@@ -1,7 +1,12 @@
1
1
  import { ConfigMetaSet, ConfigSet, ConfigType } from 'jackspeak';
2
+ type DocumentationOptions = {
3
+ [longOption: string]: {
4
+ secret?: boolean;
5
+ };
6
+ };
2
7
  type MetaSet<T extends ConfigType> = {
3
- value: ConfigMetaSet<T, false>;
4
- list: ConfigMetaSet<T, true>;
8
+ value: ConfigMetaSet<T, false> & DocumentationOptions;
9
+ list: ConfigMetaSet<T, true> & DocumentationOptions;
5
10
  };
6
11
  type opt = MetaSet<'string'>;
7
12
  type flag = MetaSet<'boolean'>;
@@ -21,6 +26,6 @@ export type Options = {
21
26
  fields?: ConfigSet;
22
27
  man?: Paragraph[];
23
28
  };
24
- export declare function merge<A extends Options = Options, B extends Options = Options>(a: A, b: B): A & B;
29
+ export declare function documentDefaults(options: Options): Options;
25
30
  export type Hook = () => Options | Promise<Options>;
26
31
  export {};
package/dist/Opt.js ADDED
@@ -0,0 +1,46 @@
1
+ import { Colors } from '@qui-cli/colors';
2
+ function stringify(value) {
3
+ switch (typeof value) {
4
+ case 'string':
5
+ return Colors.quotedValue(`"${value}"`);
6
+ case 'object':
7
+ return Colors.regexpValue(value);
8
+ default:
9
+ return Colors.value(value);
10
+ }
11
+ }
12
+ export function documentDefaults(options) {
13
+ let paramType;
14
+ for (paramType in options) {
15
+ if (paramType !== 'man' && paramType !== 'fields') {
16
+ const params = options[paramType];
17
+ if (params) {
18
+ let paramName;
19
+ for (paramName in params) {
20
+ const param = params[paramName];
21
+ let docs = '';
22
+ if (param.default !== undefined && !param.secret) {
23
+ if (!docs.length) {
24
+ docs = 'Default';
25
+ }
26
+ docs = `${docs}: ${Array.isArray(param.default)
27
+ ? param.default.map((v) => stringify(v)).join(', ')
28
+ : stringify(param.default)}`;
29
+ }
30
+ if (paramType === 'flag' && param.default) {
31
+ docs = `${docs}${docs.length ? ', u' : 'U'}se ${Colors.flagArg(`--no-${paramName}`)} to disable`;
32
+ }
33
+ if (docs.length) {
34
+ if (param.description?.length) {
35
+ param.description = `${param.description} (${docs})`;
36
+ }
37
+ else {
38
+ param.description = docs;
39
+ }
40
+ }
41
+ }
42
+ }
43
+ }
44
+ }
45
+ return options;
46
+ }
package/dist/Plugin.d.ts CHANGED
@@ -1,11 +1,11 @@
1
- import * as Configuration from './Configuration.js';
2
- import * as Initialization from './Initialization.js';
3
- import * as Options from './Options.js';
1
+ import * as Conf from './Conf.js';
2
+ import * as Init from './Init.js';
3
+ import * as Opt from './Opt.js';
4
4
  import * as Run from './Run.js';
5
5
  export type Base = {
6
6
  name: string;
7
- configure?: Configuration.Hook;
8
- options?: Options.Hook;
9
- init?: Initialization.Hook;
7
+ configure?: Conf.Hook;
8
+ options?: Opt.Hook;
9
+ init?: Init.Hook;
10
10
  run?: Run.Hook;
11
11
  } & Record<string, unknown>;
@@ -1,15 +1,14 @@
1
- import { Base as PluginConfiguration } from './Configuration.js';
2
- import { Arguments } from './Initialization.js';
3
- import { Options } from './Options.js';
4
- import { Base as Plugin } from './Plugin.js';
5
- import { AccumulatedResults } from './Run.js';
6
- export declare function registered(): Plugin[];
7
- export declare function register(plugin: Plugin): Promise<void>;
1
+ import * as Conf from './Conf.js';
2
+ import * as Init from './Init.js';
3
+ import * as Opt from './Opt.js';
4
+ import * as Plugin from './Plugin.js';
5
+ import * as Run from './Run.js';
6
+ export declare function registered(): Plugin.Base[];
7
+ export declare function register(plugin: Plugin.Base): Promise<void>;
8
8
  export declare function reset(): void;
9
9
  export type Configuration = {
10
- [key: string]: PluginConfiguration;
10
+ [key: string]: Conf.Base;
11
11
  };
12
12
  export declare function configure(config?: Configuration): Promise<void>;
13
- export declare function options(): Promise<Options>;
14
- export declare function init(args: Arguments<Awaited<ReturnType<typeof options>>>): Promise<void>;
15
- export declare function run(): Promise<AccumulatedResults>;
13
+ export declare function init(args: Init.Arguments<Opt.Options>): Promise<void>;
14
+ export declare function run(): Promise<Run.AccumulatedResults>;
package/dist/Registrar.js CHANGED
@@ -1,4 +1,4 @@
1
- import { merge } from './Options.js';
1
+ import * as Opt from './Opt.js';
2
2
  const plugins = [];
3
3
  export function registered() {
4
4
  return plugins;
@@ -12,7 +12,15 @@ export async function register(plugin) {
12
12
  return;
13
13
  }
14
14
  }
15
- plugins.push(plugin);
15
+ plugins.push({
16
+ name: plugin.name,
17
+ configure: plugin.configure ? plugin.configure.bind(plugin) : undefined,
18
+ options: plugin.options
19
+ ? async () => plugin.options ? Opt.documentDefaults(await plugin.options()) : {}
20
+ : undefined,
21
+ init: plugin.init ? plugin.init.bind(plugin) : undefined,
22
+ run: plugin.run ? plugin.run.bind(plugin) : undefined
23
+ });
16
24
  }
17
25
  export function reset() {
18
26
  for (const name in plugins) {
@@ -26,15 +34,6 @@ export async function configure(config = {}) {
26
34
  }
27
35
  }
28
36
  }
29
- export async function options() {
30
- let options = {};
31
- for (const plugin of plugins) {
32
- if (plugin.options) {
33
- options = merge(options, await plugin.options());
34
- }
35
- }
36
- return options;
37
- }
38
37
  export async function init(args) {
39
38
  for (const plugin of plugins) {
40
39
  if (plugin.init) {
package/dist/Run.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export type Result = any;
1
+ export type Result = unknown;
2
2
  export type AccumulatedResults = Record<string, Result>;
3
3
  export type Hook = (results?: AccumulatedResults) => Result | Promise<Result>;
package/dist/index.d.ts CHANGED
@@ -1,9 +1,11 @@
1
- import { merge } from './Options.js';
2
- import { register } from './Registrar.js';
3
- export { Base as Configuration } from './Configuration.js';
4
- export { Arguments, ExpectedArguments } from './Initialization.js';
5
- export { Options } from './Options.js';
1
+ export * as Conf from './Conf.js';
2
+ export * as Init from './Init.js';
3
+ export * as Opt from './Opt.js';
6
4
  export * as Registrar from './Registrar.js';
5
+ export * as Run from './Run.js';
6
+ export { Base as Configuration } from './Conf.js';
7
+ export { Arguments, ExpectedArguments } from './Init.js';
8
+ export { Options, documentDefaults } from './Opt.js';
7
9
  export { AccumulatedResults } from './Run.js';
8
- export * from './Utilities.js';
9
- export { merge as mergeOptions, register };
10
+ export { register } from './Registrar.js';
11
+ export * from './Deprecated.js';
package/dist/index.js CHANGED
@@ -1,5 +1,8 @@
1
- import { merge } from './Options.js';
2
- import { register } from './Registrar.js';
1
+ export * as Conf from './Conf.js';
2
+ export * as Init from './Init.js';
3
+ export * as Opt from './Opt.js';
3
4
  export * as Registrar from './Registrar.js';
4
- export * from './Utilities.js';
5
- export { merge as mergeOptions, register };
5
+ export * as Run from './Run.js';
6
+ export { documentDefaults } from './Opt.js';
7
+ export { register } from './Registrar.js';
8
+ export * from './Deprecated.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qui-cli/plugin",
3
- "version": "3.0.0",
3
+ "version": "4.1.0",
4
4
  "description": "@qui-cli plugin structure and registrar",
5
5
  "homepage": "https://github.com/battis/qui-cli/tree/main/packages/plugin#readme",
6
6
  "repository": {
@@ -17,15 +17,16 @@
17
17
  "main": "./dist/index.js",
18
18
  "types": "./dist/index.d.ts",
19
19
  "dependencies": {
20
- "jackspeak": "^4.1.1"
20
+ "jackspeak": "^4.1.1",
21
+ "@qui-cli/colors": "3.2.3"
21
22
  },
22
23
  "devDependencies": {
23
- "@tsconfig/node20": "^20.1.6",
24
- "@types/node": "^24.1.0",
25
- "commit-and-tag-version": "^12.5.2",
26
- "del-cli": "^6.0.0",
24
+ "@tsconfig/node24": "^24.0.4",
25
+ "@types/node": "^24.10.9",
26
+ "commit-and-tag-version": "^12.6.1",
27
+ "del-cli": "^7.0.0",
27
28
  "npm-run-all": "^4.1.5",
28
- "typescript": "^5.9.2"
29
+ "typescript": "^5.9.3"
29
30
  },
30
31
  "target": "node",
31
32
  "scripts": {
@@ -33,6 +34,6 @@
33
34
  "build": "run-s build:*",
34
35
  "build:clean": "run-s clean",
35
36
  "build:compile": "tsc",
36
- "release": "commit-and-tag-version"
37
+ "version": "commit-and-tag-version"
37
38
  }
38
39
  }
@@ -1,2 +0,0 @@
1
- export type Base = Record<string, unknown>;
2
- export type Hook = (config: Base) => void | Promise<void>;
@@ -1,10 +0,0 @@
1
- import { ConfigSetFromMetaSet, OptionsResults } from 'jackspeak';
2
- import * as Options from './Options.js';
3
- type FlattenConfigMetaSets<O extends Options.Options> = ConfigSetFromMetaSet<'number', false, Exclude<O['num'], undefined>> & ConfigSetFromMetaSet<'number', true, Exclude<O['numList'], undefined>> & ConfigSetFromMetaSet<'string', false, Exclude<O['opt'], undefined>> & ConfigSetFromMetaSet<'string', false, Exclude<O['opt'], undefined>> & ConfigSetFromMetaSet<'string', true, Exclude<O['optList'], undefined>> & ConfigSetFromMetaSet<'boolean', false, Exclude<O['flag'], undefined>> & ConfigSetFromMetaSet<'boolean', true, Exclude<O['flagList'], undefined>> & Exclude<O['fields'], undefined>;
4
- export type Arguments<O extends Options.Options> = {
5
- positionals: (string | undefined)[];
6
- values: OptionsResults<FlattenConfigMetaSets<O>>;
7
- };
8
- export type ExpectedArguments<H extends Options.Hook> = Arguments<Awaited<ReturnType<H>>>;
9
- export type Hook<O extends Options.Options = Options.Options> = (args: Arguments<O>) => void | Promise<void>;
10
- export {};
@@ -1 +0,0 @@
1
- export {};
package/dist/Options.js DELETED
@@ -1,12 +0,0 @@
1
- export function merge(a, b) {
2
- return {
3
- num: { ...a.num, ...b.num },
4
- numList: { ...a.numList, ...b.numList },
5
- opt: { ...a.opt, ...b.opt },
6
- optList: { ...a.optList, ...b.optList },
7
- flag: { ...a.flag, ...b.flag },
8
- flagList: { ...a.flagList, ...b.flagList },
9
- fields: { ...a.fields, ...b.fields },
10
- man: [...(a.man || []), ...(b.man || [])]
11
- };
12
- }
@@ -1 +0,0 @@
1
- export * from './Utilities/hydrate.js';
package/dist/Utilities.js DELETED
@@ -1 +0,0 @@
1
- export * from './Utilities/hydrate.js';
File without changes