@qraft/cli-utils 1.0.0-beta.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 ADDED
@@ -0,0 +1,20 @@
1
+ # @qraft/cli-utils
2
+
3
+ ## 1.0.0-beta.0
4
+
5
+ ### Minor Changes
6
+
7
+ - a282960: Introduce unified CLI tool `@qraft/cli` that extends code generation capabilities beyond OpenAPI to support AsyncAPI
8
+ specifications. The new CLI provides three main commands:
9
+ - `qraft openapi` - Generate type-safe code from OpenAPI documents (React Query hooks and TypeScript types)
10
+ - `qraft asyncapi` - Generate TypeScript types from AsyncAPI documents
11
+ - `qraft redocly` - Generate code from Redocly configuration files supporting both OpenAPI and AsyncAPI APIs
12
+
13
+ The CLI uses a plugin-based architecture where plugins are installed as peer dependencies, allowing users to install
14
+ only the plugins they need. It maintains full backward compatibility with existing OpenAPI workflows while adding
15
+ seamless support for event-driven API specifications.
16
+
17
+ ### Patch Changes
18
+
19
+ - Updated dependencies [a282960]
20
+ - @qraft/plugin@1.0.0-beta.0
@@ -0,0 +1,6 @@
1
+ import type { QraftCommand } from '@qraft/plugin';
2
+ /**
3
+ * Adds plugin usage instructions by calling `command.usage(...)`
4
+ */
5
+ export declare function addCommandUsageWithPlugins(command: QraftCommand<any>, plugins: string[]): void;
6
+ //# sourceMappingURL=addCommandUsageWithPlugins.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"addCommandUsageWithPlugins.d.ts","sourceRoot":"","sources":["../src/addCommandUsageWithPlugins.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,YAAY,CAAC,GAAG,CAAC,EAC1B,OAAO,EAAE,MAAM,EAAE,GAChB,IAAI,CAGN"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Adds plugin usage instructions by calling `command.usage(...)`
3
+ */
4
+ export function addCommandUsageWithPlugins(command, plugins) {
5
+ const pluginUsage = plugins.map((plugin) => `--plugin ${plugin}`).join(' ');
6
+ command.usage(`${pluginUsage} [input] [options]`);
7
+ }
8
+ //# sourceMappingURL=addCommandUsageWithPlugins.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"addCommandUsageWithPlugins.js","sourceRoot":"","sources":["../src/addCommandUsageWithPlugins.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,UAAU,0BAA0B,CACxC,OAA0B,EAC1B,OAAiB;IAEjB,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,YAAY,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5E,OAAO,CAAC,KAAK,CAAC,GAAG,WAAW,oBAAoB,CAAC,CAAC;AACpD,CAAC"}
@@ -0,0 +1,10 @@
1
+ export interface ExtractArgvPluginOptionsResult {
2
+ argv: string[];
3
+ plugins?: string[];
4
+ }
5
+ /**
6
+ * Extracts multiple `--plugin <name>` options from `argv`
7
+ * and returns both the filtered `argv` and the extracted plugins list.
8
+ */
9
+ export declare function extractArgvPluginOptions(argv: string[]): ExtractArgvPluginOptionsResult;
10
+ //# sourceMappingURL=extractArgvPluginOptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractArgvPluginOptions.d.ts","sourceRoot":"","sources":["../src/extractArgvPluginOptions.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,8BAA8B;IAC7C,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,EAAE,GACb,8BAA8B,CA6BhC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Extracts multiple `--plugin <name>` options from `argv`
3
+ * and returns both the filtered `argv` and the extracted plugins list.
4
+ */
5
+ export function extractArgvPluginOptions(argv) {
6
+ const pluginIndex = argv.indexOf('--plugin');
7
+ if (pluginIndex === -1)
8
+ return { argv };
9
+ const filteredArgv = argv.slice(0, pluginIndex);
10
+ const plugins = [];
11
+ for (let i = pluginIndex; i < argv.length; i++) {
12
+ if (argv[i] === '--plugin') {
13
+ const pluginName = argv.at(i + 1);
14
+ if (!pluginName)
15
+ throw new Error(`A plugin name must be specified after the '--plugin' option`);
16
+ if (pluginName?.startsWith('--'))
17
+ throw new Error(`Invalid plugin name: '${pluginName}'. Plugin names cannot start with '--'`);
18
+ plugins.push(pluginName);
19
+ i++; // Skip next item
20
+ }
21
+ else {
22
+ filteredArgv.push(argv[i]);
23
+ }
24
+ }
25
+ return {
26
+ argv: filteredArgv,
27
+ plugins,
28
+ };
29
+ }
30
+ //# sourceMappingURL=extractArgvPluginOptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractArgvPluginOptions.js","sourceRoot":"","sources":["../src/extractArgvPluginOptions.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CACtC,IAAc;IAEd,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC7C,IAAI,WAAW,KAAK,CAAC,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAExC,MAAM,YAAY,GAAa,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,KAAK,IAAI,CAAC,GAAG,WAAW,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/C,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,UAAU,EAAE,CAAC;YAC3B,MAAM,UAAU,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAClC,IAAI,CAAC,UAAU;gBACb,MAAM,IAAI,KAAK,CACb,6DAA6D,CAC9D,CAAC;YACJ,IAAI,UAAU,EAAE,UAAU,CAAC,IAAI,CAAC;gBAC9B,MAAM,IAAI,KAAK,CACb,yBAAyB,UAAU,wCAAwC,CAC5E,CAAC;YACJ,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACzB,CAAC,EAAE,CAAC,CAAC,iBAAiB;QACxB,CAAC;aAAM,CAAC;YACN,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,OAAO;QACL,IAAI,EAAE,YAAY;QAClB,OAAO;KACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function createFileHeader(cliName: string): string;
2
+ //# sourceMappingURL=fileHeader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fileHeader.d.ts","sourceRoot":"","sources":["../src/fileHeader.ts"],"names":[],"mappings":"AAAA,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAOxD"}
@@ -0,0 +1,9 @@
1
+ export function createFileHeader(cliName) {
2
+ return `/**
3
+ * This file was auto-generated by ${cliName}.
4
+ * Do not make direct changes to the file.
5
+ */
6
+
7
+ `;
8
+ }
9
+ //# sourceMappingURL=fileHeader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fileHeader.js","sourceRoot":"","sources":["../src/fileHeader.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,OAAO;qCAC4B,OAAO;;;;CAI3C,CAAC;AACF,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Checks if the argv array contains help option flags (--help or -h).
3
+ */
4
+ export declare function hasHelpOption(argv: string[]): boolean;
5
+ //# sourceMappingURL=hasHelpOption.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hasHelpOption.d.ts","sourceRoot":"","sources":["../src/hasHelpOption.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAErD"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Checks if the argv array contains help option flags (--help or -h).
3
+ */
4
+ export function hasHelpOption(argv) {
5
+ return argv.includes('--help') || argv.includes('-h');
6
+ }
7
+ //# sourceMappingURL=hasHelpOption.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hasHelpOption.js","sourceRoot":"","sources":["../src/hasHelpOption.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,IAAc;IAC1C,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACxD,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { extractArgvPluginOptions, type ExtractArgvPluginOptionsResult, } from './extractArgvPluginOptions.js';
2
+ export { setupPlugins, type BuiltInPlugins, type SetupPluginsOptions, } from './setupPlugins.js';
3
+ export { addCommandUsageWithPlugins } from './addCommandUsageWithPlugins.js';
4
+ export { hasHelpOption } from './hasHelpOption.js';
5
+ export { createFileHeader } from './fileHeader.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EACxB,KAAK,8BAA8B,GACpC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,YAAY,EACZ,KAAK,cAAc,EACnB,KAAK,mBAAmB,GACzB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ export { extractArgvPluginOptions, } from './extractArgvPluginOptions.js';
2
+ export { setupPlugins, } from './setupPlugins.js';
3
+ export { addCommandUsageWithPlugins } from './addCommandUsageWithPlugins.js';
4
+ export { hasHelpOption } from './hasHelpOption.js';
5
+ export { createFileHeader } from './fileHeader.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,GAEzB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,YAAY,GAGb,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { QraftCommand } from '@qraft/plugin';
2
+ import type { QraftCommandPlugin } from '@qraft/plugin/lib/QraftCommandPlugin';
3
+ export type BuiltInPlugins<T extends string = string> = Record<T, () => Promise<{
4
+ default: QraftCommandPlugin<QraftCommand<any>>;
5
+ }>>;
6
+ export interface SetupPluginsOptions<T extends string> {
7
+ command: QraftCommand<any>;
8
+ plugins: T[];
9
+ builtInPlugins: BuiltInPlugins<T>;
10
+ addUsage?: (command: QraftCommand<any>, plugins: T[]) => void;
11
+ }
12
+ /**
13
+ * Loads and configures plugins for a QraftCommand.
14
+ * Validates plugin names against builtInPlugins, dynamically imports each plugin,
15
+ * and calls setupCommand/postSetupCommand lifecycle methods.
16
+ */
17
+ export declare function setupPlugins<T extends string>({ command, plugins, builtInPlugins, addUsage, }: SetupPluginsOptions<T>): Promise<void>;
18
+ //# sourceMappingURL=setupPlugins.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setupPlugins.d.ts","sourceRoot":"","sources":["../src/setupPlugins.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAE/E,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI,MAAM,CAC5D,CAAC,EACD,MAAM,OAAO,CAAC;IAAE,OAAO,EAAE,kBAAkB,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAA;CAAE,CAAC,CAClE,CAAC;AAEF,MAAM,WAAW,mBAAmB,CAAC,CAAC,SAAS,MAAM;IACnD,OAAO,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC;IAC3B,OAAO,EAAE,CAAC,EAAE,CAAC;IACb,cAAc,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;IAClC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC;CAC/D;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,CAAC,SAAS,MAAM,EAAE,EACnD,OAAO,EACP,OAAO,EACP,cAAc,EACd,QAAQ,GACT,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBxC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Loads and configures plugins for a QraftCommand.
3
+ * Validates plugin names against builtInPlugins, dynamically imports each plugin,
4
+ * and calls setupCommand/postSetupCommand lifecycle methods.
5
+ */
6
+ export async function setupPlugins({ command, plugins, builtInPlugins, addUsage, }) {
7
+ const pluginList = [];
8
+ for (const pluginName of plugins) {
9
+ if (!(pluginName in builtInPlugins))
10
+ throw new Error(`Unknown plugin: '${pluginName}'`);
11
+ pluginList.push((await builtInPlugins[pluginName]())
12
+ .default);
13
+ addUsage?.(command, plugins);
14
+ }
15
+ await Promise.all(pluginList.map((plugin) => plugin.setupCommand(command)));
16
+ await Promise.all(pluginList.map((plugin) => plugin.postSetupCommand?.(command, plugins)));
17
+ }
18
+ //# sourceMappingURL=setupPlugins.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setupPlugins.js","sourceRoot":"","sources":["../src/setupPlugins.ts"],"names":[],"mappings":"AAeA;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAmB,EACnD,OAAO,EACP,OAAO,EACP,cAAc,EACd,QAAQ,GACe;IACvB,MAAM,UAAU,GAA4C,EAAE,CAAC;IAE/D,KAAK,MAAM,UAAU,IAAI,OAAO,EAAE,CAAC;QACjC,IAAI,CAAC,CAAC,UAAU,IAAI,cAAc,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,oBAAoB,UAAU,GAAG,CAAC,CAAC;QAErD,UAAU,CAAC,IAAI,CACb,CAAC,MAAM,cAAc,CAAC,UAAyC,CAAC,EAAE,CAAC;aAChE,OAAO,CACX,CAAC;QAEF,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC/B,CAAC;IAED,MAAM,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC5E,MAAM,OAAO,CAAC,GAAG,CACf,UAAU,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CACxE,CAAC;AACJ,CAAC"}
package/package.json ADDED
@@ -0,0 +1,82 @@
1
+ {
2
+ "name": "@qraft/cli-utils",
3
+ "version": "1.0.0-beta.0",
4
+ "description": "Shared CLI utilities for Qraft code generation tools",
5
+ "scripts": {
6
+ "build": "tsc --project tsconfig.build.json",
7
+ "dev": "yarn build --watch --noEmitOnError false",
8
+ "test": "vitest run",
9
+ "typecheck": "tsc --noEmit",
10
+ "lint": "eslint",
11
+ "clean": "rimraf dist/"
12
+ },
13
+ "type": "module",
14
+ "dependencies": {
15
+ "@qraft/plugin": "1.0.0-beta.0"
16
+ },
17
+ "devDependencies": {
18
+ "@openapi-qraft/eslint-config": "1.0.1",
19
+ "@types/node": "^20.16.5",
20
+ "eslint": "^9.39.1",
21
+ "rimraf": "^6.1.2",
22
+ "typescript": "^5.6.2",
23
+ "vitest": "^3.2.4"
24
+ },
25
+ "files": [
26
+ "dist",
27
+ "src",
28
+ "!dist/**/*.test.*",
29
+ "!dist/**/*.spec.*",
30
+ "!src/**/*.test.*",
31
+ "!src/**/*.spec.*"
32
+ ],
33
+ "module": "dist/index.js",
34
+ "types": "dist/index.d.ts",
35
+ "exports": {
36
+ "./package.json": "./package.json",
37
+ ".": {
38
+ "types": "./dist/index.d.ts",
39
+ "import": "./dist/index.js"
40
+ },
41
+ "./*": {
42
+ "types": "./dist/*.d.ts",
43
+ "import": "./dist/*.js"
44
+ }
45
+ },
46
+ "typesVersions": {
47
+ "*": {
48
+ "*": [
49
+ "dist/*"
50
+ ]
51
+ }
52
+ },
53
+ "repository": {
54
+ "type": "git",
55
+ "url": "git+https://github.com/OpenAPI-Qraft/openapi-qraft.git",
56
+ "directory": "packages/cli-utils"
57
+ },
58
+ "bugs": {
59
+ "url": "https://github.com/OpenAPI-Qraft/openapi-qraft/issues"
60
+ },
61
+ "homepage": "https://openapi-qraft.github.io/openapi-qraft/",
62
+ "keywords": [
63
+ "openapi",
64
+ "swagger",
65
+ "rest",
66
+ "api",
67
+ "oapi_3",
68
+ "oapi_3_1",
69
+ "typescript",
70
+ "ts",
71
+ "dts",
72
+ "codegen",
73
+ "generation",
74
+ "fetch",
75
+ "react",
76
+ "hooks",
77
+ "TanStack Query"
78
+ ],
79
+ "publishConfig": {
80
+ "access": "public"
81
+ }
82
+ }
@@ -0,0 +1,12 @@
1
+ import type { QraftCommand } from '@qraft/plugin';
2
+
3
+ /**
4
+ * Adds plugin usage instructions by calling `command.usage(...)`
5
+ */
6
+ export function addCommandUsageWithPlugins(
7
+ command: QraftCommand<any>,
8
+ plugins: string[]
9
+ ): void {
10
+ const pluginUsage = plugins.map((plugin) => `--plugin ${plugin}`).join(' ');
11
+ command.usage(`${pluginUsage} [input] [options]`);
12
+ }
@@ -0,0 +1,41 @@
1
+ export interface ExtractArgvPluginOptionsResult {
2
+ argv: string[];
3
+ plugins?: string[];
4
+ }
5
+
6
+ /**
7
+ * Extracts multiple `--plugin <name>` options from `argv`
8
+ * and returns both the filtered `argv` and the extracted plugins list.
9
+ */
10
+ export function extractArgvPluginOptions(
11
+ argv: string[]
12
+ ): ExtractArgvPluginOptionsResult {
13
+ const pluginIndex = argv.indexOf('--plugin');
14
+ if (pluginIndex === -1) return { argv };
15
+
16
+ const filteredArgv: string[] = argv.slice(0, pluginIndex);
17
+ const plugins: string[] = [];
18
+
19
+ for (let i = pluginIndex; i < argv.length; i++) {
20
+ if (argv[i] === '--plugin') {
21
+ const pluginName = argv.at(i + 1);
22
+ if (!pluginName)
23
+ throw new Error(
24
+ `A plugin name must be specified after the '--plugin' option`
25
+ );
26
+ if (pluginName?.startsWith('--'))
27
+ throw new Error(
28
+ `Invalid plugin name: '${pluginName}'. Plugin names cannot start with '--'`
29
+ );
30
+ plugins.push(pluginName);
31
+ i++; // Skip next item
32
+ } else {
33
+ filteredArgv.push(argv[i]);
34
+ }
35
+ }
36
+
37
+ return {
38
+ argv: filteredArgv,
39
+ plugins,
40
+ };
41
+ }
@@ -0,0 +1,8 @@
1
+ export function createFileHeader(cliName: string): string {
2
+ return `/**
3
+ * This file was auto-generated by ${cliName}.
4
+ * Do not make direct changes to the file.
5
+ */
6
+
7
+ `;
8
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Checks if the argv array contains help option flags (--help or -h).
3
+ */
4
+ export function hasHelpOption(argv: string[]): boolean {
5
+ return argv.includes('--help') || argv.includes('-h');
6
+ }
package/src/index.ts ADDED
@@ -0,0 +1,12 @@
1
+ export {
2
+ extractArgvPluginOptions,
3
+ type ExtractArgvPluginOptionsResult,
4
+ } from './extractArgvPluginOptions.js';
5
+ export {
6
+ setupPlugins,
7
+ type BuiltInPlugins,
8
+ type SetupPluginsOptions,
9
+ } from './setupPlugins.js';
10
+ export { addCommandUsageWithPlugins } from './addCommandUsageWithPlugins.js';
11
+ export { hasHelpOption } from './hasHelpOption.js';
12
+ export { createFileHeader } from './fileHeader.js';
@@ -0,0 +1,45 @@
1
+ import type { QraftCommand } from '@qraft/plugin';
2
+ import type { QraftCommandPlugin } from '@qraft/plugin/lib/QraftCommandPlugin';
3
+
4
+ export type BuiltInPlugins<T extends string = string> = Record<
5
+ T,
6
+ () => Promise<{ default: QraftCommandPlugin<QraftCommand<any>> }>
7
+ >;
8
+
9
+ export interface SetupPluginsOptions<T extends string> {
10
+ command: QraftCommand<any>;
11
+ plugins: T[];
12
+ builtInPlugins: BuiltInPlugins<T>;
13
+ addUsage?: (command: QraftCommand<any>, plugins: T[]) => void;
14
+ }
15
+
16
+ /**
17
+ * Loads and configures plugins for a QraftCommand.
18
+ * Validates plugin names against builtInPlugins, dynamically imports each plugin,
19
+ * and calls setupCommand/postSetupCommand lifecycle methods.
20
+ */
21
+ export async function setupPlugins<T extends string>({
22
+ command,
23
+ plugins,
24
+ builtInPlugins,
25
+ addUsage,
26
+ }: SetupPluginsOptions<T>): Promise<void> {
27
+ const pluginList: QraftCommandPlugin<QraftCommand<any>>[] = [];
28
+
29
+ for (const pluginName of plugins) {
30
+ if (!(pluginName in builtInPlugins))
31
+ throw new Error(`Unknown plugin: '${pluginName}'`);
32
+
33
+ pluginList.push(
34
+ (await builtInPlugins[pluginName as keyof typeof builtInPlugins]())
35
+ .default
36
+ );
37
+
38
+ addUsage?.(command, plugins);
39
+ }
40
+
41
+ await Promise.all(pluginList.map((plugin) => plugin.setupCommand(command)));
42
+ await Promise.all(
43
+ pluginList.map((plugin) => plugin.postSetupCommand?.(command, plugins))
44
+ );
45
+ }