@qraft/cli 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.
Files changed (39) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +139 -0
  3. package/bin.mjs +10 -0
  4. package/dist/bin.d.ts +4 -0
  5. package/dist/bin.d.ts.map +1 -0
  6. package/dist/bin.js +96 -0
  7. package/dist/bin.js.map +1 -0
  8. package/dist/builtInPlugins.d.ts +8 -0
  9. package/dist/builtInPlugins.d.ts.map +1 -0
  10. package/dist/builtInPlugins.js +8 -0
  11. package/dist/builtInPlugins.js.map +1 -0
  12. package/dist/commands/asyncapi.d.ts +3 -0
  13. package/dist/commands/asyncapi.d.ts.map +1 -0
  14. package/dist/commands/asyncapi.js +9 -0
  15. package/dist/commands/asyncapi.js.map +1 -0
  16. package/dist/commands/openapi.d.ts +3 -0
  17. package/dist/commands/openapi.d.ts.map +1 -0
  18. package/dist/commands/openapi.js +9 -0
  19. package/dist/commands/openapi.js.map +1 -0
  20. package/dist/commands/runAsyncAPI.d.ts +3 -0
  21. package/dist/commands/runAsyncAPI.d.ts.map +1 -0
  22. package/dist/commands/runAsyncAPI.js +30 -0
  23. package/dist/commands/runAsyncAPI.js.map +1 -0
  24. package/dist/commands/runOpenAPI.d.ts +3 -0
  25. package/dist/commands/runOpenAPI.d.ts.map +1 -0
  26. package/dist/commands/runOpenAPI.js +30 -0
  27. package/dist/commands/runOpenAPI.js.map +1 -0
  28. package/dist/packageVersion.d.ts +2 -0
  29. package/dist/packageVersion.d.ts.map +1 -0
  30. package/dist/packageVersion.js +3 -0
  31. package/dist/packageVersion.js.map +1 -0
  32. package/package.json +114 -0
  33. package/src/bin.ts +134 -0
  34. package/src/builtInPlugins.ts +12 -0
  35. package/src/commands/asyncapi.ts +20 -0
  36. package/src/commands/openapi.ts +20 -0
  37. package/src/commands/runAsyncAPI.ts +52 -0
  38. package/src/commands/runOpenAPI.ts +52 -0
  39. package/src/packageVersion.ts +2 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,27 @@
1
+ # @qraft/cli
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 [7074f50]
20
+ - Updated dependencies [a282960]
21
+ - @openapi-qraft/tanstack-query-react-plugin@2.15.0-beta.1
22
+ - @qraft/asyncapi-typescript-plugin@1.0.0-beta.0
23
+ - @openapi-qraft/openapi-typescript-plugin@2.15.0-beta.1
24
+ - @qraft/asyncapi-plugin@1.0.0-beta.0
25
+ - @openapi-qraft/plugin@2.15.0-beta.1
26
+ - @qraft/cli-utils@1.0.0-beta.0
27
+ - @qraft/plugin@1.0.0-beta.0
package/README.md ADDED
@@ -0,0 +1,139 @@
1
+ # @qraft/cli
2
+
3
+ CLI tool for generating type-safe code from OpenAPI and AsyncAPI specifications.
4
+
5
+ ## Installation
6
+
7
+ **Requirements:** Node.js >= 20.19.6
8
+
9
+ ```bash
10
+ npm install -g @qraft/cli
11
+ ```
12
+
13
+ ### Required Plugins
14
+
15
+ The CLI requires additional plugins to be installed depending on which features you want to use:
16
+
17
+ **For OpenAPI generation:**
18
+
19
+ ```bash
20
+ npm install @openapi-qraft/openapi-typescript-plugin @openapi-qraft/tanstack-query-react-plugin
21
+ ```
22
+
23
+ **For AsyncAPI generation:**
24
+
25
+ ```bash
26
+ npm install @qraft/asyncapi-typescript-plugin
27
+ ```
28
+
29
+ **For both OpenAPI and AsyncAPI:**
30
+
31
+ ```bash
32
+ npm install @openapi-qraft/openapi-typescript-plugin @openapi-qraft/tanstack-query-react-plugin @qraft/asyncapi-typescript-plugin
33
+ ```
34
+
35
+ > **Note:** All plugins are peer dependencies and must be installed alongside `@qraft/cli` for the corresponding
36
+ > commands to work.
37
+
38
+ ## Commands
39
+
40
+ ### `qraft openapi`
41
+
42
+ Generate code from OpenAPI specification.
43
+
44
+ **Available plugins:**
45
+ - `tanstack-query-react` - Generates Qraft API services for React
46
+ - `openapi-typescript` - Generates TypeScript types from OpenAPI Document
47
+
48
+ **Examples:**
49
+
50
+ ```bash
51
+ # Generate TypeScript types only
52
+ qraft openapi --plugin openapi-typescript ./openapi.yaml -o ./src/types
53
+
54
+ # Generate both services and types
55
+ qraft openapi --plugin tanstack-query-react --plugin openapi-typescript ./openapi.yaml -o ./src/api
56
+
57
+ # Generate from Redocly config
58
+ qraft openapi --redocly
59
+ ```
60
+
61
+ ### `qraft asyncapi`
62
+
63
+ Generate code from AsyncAPI specification.
64
+
65
+ **Required:** Plugin must be explicitly specified.
66
+
67
+ **Available plugins:**
68
+ - `asyncapi-typescript` - Generates TypeScript types from AsyncAPI Document
69
+
70
+ **Examples:**
71
+
72
+ ```bash
73
+ # Generate TypeScript types from AsyncAPI
74
+ qraft asyncapi --plugin asyncapi-typescript ./asyncapi.yaml -o ./src/types
75
+
76
+ # Generate from Redocly config
77
+ qraft asyncapi --redocly
78
+ ```
79
+
80
+ ## Redocly Config Support
81
+
82
+ The CLI supports using a Redocly configuration file (`redocly.yaml`) to generate API clients. This allows you to define multiple API entry points and configure generation options in a single file.
83
+
84
+ ### Configuration Keys
85
+
86
+ - `x-openapi-qraft` - Configuration for OpenAPI generation
87
+ - `x-asyncapi-qraft` - Configuration for AsyncAPI generation
88
+
89
+ ### Usage
90
+
91
+ ```bash
92
+ # Generate from default redocly.yaml (both OpenAPI and AsyncAPI)
93
+ qraft redocly
94
+
95
+ # Generate from specific config file
96
+ qraft redocly --redocly ./path/to/redocly.yaml
97
+
98
+ # Generate specific APIs
99
+ qraft redocly my-api@v1
100
+
101
+ # Generate only OpenAPI from Redocly config
102
+ qraft openapi --redocly
103
+
104
+ # Generate only AsyncAPI from Redocly config
105
+ qraft asyncapi --redocly
106
+ ```
107
+
108
+ ### Example Configuration
109
+
110
+ ```yaml
111
+ # redocly.yaml
112
+ apis:
113
+ main:
114
+ root: ./openapi.json
115
+ x-openapi-qraft:
116
+ plugin:
117
+ tanstack-query-react: true
118
+ openapi-typescript: true
119
+ output-dir: src/api
120
+ clean: true
121
+
122
+ events:
123
+ root: ./asyncapi.json
124
+ x-asyncapi-qraft:
125
+ plugin:
126
+ asyncapi-typescript: true
127
+ output-dir: src/events
128
+ clean: true
129
+ ```
130
+
131
+ ## Options
132
+
133
+ All options from the underlying plugins are supported. Use `--help` to see available options for each command:
134
+
135
+ ```bash
136
+ qraft openapi --help
137
+ qraft asyncapi --help
138
+ qraft redocly --help
139
+ ```
package/bin.mjs ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * Workaround to allow `rimraf dist/` on rebuilds and keep `bin` executable
6
+ * without a need `yarn install`
7
+ */
8
+ import { main } from './dist/bin.js';
9
+
10
+ main(process.argv);
package/dist/bin.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import type { ParseOptions } from 'commander';
3
+ export declare function main(processArgv: string[], processArgvParseOptions?: ParseOptions): Promise<void>;
4
+ //# sourceMappingURL=bin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAa9C,wBAAsB,IAAI,CACxB,WAAW,EAAE,MAAM,EAAE,EACrB,uBAAuB,CAAC,EAAE,YAAY,iBAyFvC"}
package/dist/bin.js ADDED
@@ -0,0 +1,96 @@
1
+ #!/usr/bin/env node
2
+ import { ASYNCAPI_QRAFT_REDOC_CONFIG_KEY, OPENAPI_QRAFT_REDOC_CONFIG_KEY, } from '@qraft/plugin/lib/getRedocAPIsToQraft';
3
+ import { createRedoclyOption, RedoclyConfigCommand, } from '@qraft/plugin/lib/RedoclyConfigCommand';
4
+ import c from 'ansi-colors';
5
+ import { Command } from 'commander';
6
+ import { packageVersion } from './packageVersion.js';
7
+ export async function main(processArgv, processArgvParseOptions) {
8
+ const program = new Command();
9
+ program
10
+ .name('qraft')
11
+ .description('Generate type-safe code from OpenAPI and AsyncAPI specifications')
12
+ // todo::maybe add "<bin> help <command>" handling
13
+ .helpCommand(false)
14
+ .version(packageVersion);
15
+ program
16
+ .command('openapi')
17
+ .description('Generate code from OpenAPI specification')
18
+ .allowUnknownOption()
19
+ .allowExcessArguments()
20
+ .action(async () => {
21
+ const subcommandArgv = extractSubcommandArgv(processArgv, 'openapi');
22
+ const { qraftOpenapi } = await import('./commands/openapi.js');
23
+ await qraftOpenapi(subcommandArgv, processArgvParseOptions);
24
+ })
25
+ .helpOption(false); // The command handles the help independently
26
+ program
27
+ .command('asyncapi')
28
+ .description('Generate code from AsyncAPI specification')
29
+ .allowUnknownOption()
30
+ .allowExcessArguments()
31
+ .action(async () => {
32
+ const subcommandArgv = extractSubcommandArgv(processArgv, 'asyncapi');
33
+ const { qraftAsyncapi } = await import('./commands/asyncapi.js');
34
+ await qraftAsyncapi(subcommandArgv, processArgvParseOptions);
35
+ })
36
+ .helpOption(false); // The command handles the help independently
37
+ program
38
+ .command('redocly')
39
+ .description('Generate from Redocly config (both OpenAPI and AsyncAPI)')
40
+ .argument('[apis...]', 'Selective API names from Redocly config to generate')
41
+ .addOption(createRedoclyOption())
42
+ .action(async (apis, options) => {
43
+ const redoclyArgv = buildRedoclyArgv(apis, options.redocly);
44
+ await new RedoclyConfigCommand().parseConfig({
45
+ [OPENAPI_QRAFT_REDOC_CONFIG_KEY]: async (argv, parseOptions) => {
46
+ const { runOpenAPI } = await import('./commands/runOpenAPI.js');
47
+ return runOpenAPI(argv, parseOptions);
48
+ },
49
+ [ASYNCAPI_QRAFT_REDOC_CONFIG_KEY]: async (argv, parseOptions) => {
50
+ const { runAsyncAPI } = await import('./commands/runAsyncAPI.js');
51
+ return runAsyncAPI(argv, parseOptions);
52
+ },
53
+ }, redoclyArgv, { from: 'user' });
54
+ });
55
+ program.addHelpText('after', `
56
+ ${c.bold('Examples:')}
57
+ ${c.dim('# Generate React Query hooks from OpenAPI')}
58
+ $ qraft openapi --plugin tanstack-query-react ./openapi.yaml -o ./src/api
59
+
60
+ ${c.dim('# Generate TypeScript types from OpenAPI')}
61
+ $ qraft openapi --plugin openapi-typescript ./openapi.yaml -o ./src/types
62
+
63
+ ${c.dim('# Generate TypeScript types from AsyncAPI')}
64
+ $ qraft asyncapi --plugin asyncapi-typescript ./asyncapi.yaml -o ./src/types
65
+
66
+ ${c.dim('# Generate from Redocly config (both OpenAPI and AsyncAPI)')}
67
+ $ qraft redocly
68
+
69
+ ${c.dim('# Generate specific APIs from Redocly config')}
70
+ $ qraft redocly openapi-main asyncapi-main
71
+
72
+ ${c.dim('# Generate from custom Redocly config path')}
73
+ $ qraft redocly --redocly ./custom-redocly.yaml
74
+ `);
75
+ await program.parseAsync(processArgv, processArgvParseOptions);
76
+ }
77
+ function buildRedoclyArgv(apis, redoclyConfig) {
78
+ const argv = [...apis];
79
+ if (typeof redoclyConfig === 'string') {
80
+ argv.push('--redocly', redoclyConfig);
81
+ }
82
+ else if (redoclyConfig) {
83
+ argv.push('--redocly');
84
+ }
85
+ return argv;
86
+ }
87
+ function extractSubcommandArgv(processArgv, subcommand) {
88
+ const subcommandIndex = processArgv.indexOf(subcommand);
89
+ if (subcommandIndex === -1)
90
+ return processArgv;
91
+ return [
92
+ ...processArgv.slice(0, 2),
93
+ ...processArgv.slice(subcommandIndex + 1),
94
+ ];
95
+ }
96
+ //# sourceMappingURL=bin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export declare const openApiBuiltInPlugins: {
2
+ readonly 'tanstack-query-react': () => Promise<typeof import("@openapi-qraft/tanstack-query-react-plugin")>;
3
+ readonly 'openapi-typescript': () => Promise<typeof import("@openapi-qraft/openapi-typescript-plugin")>;
4
+ };
5
+ export declare const asyncApiBuiltInPlugins: {
6
+ readonly 'asyncapi-typescript': () => Promise<typeof import("@qraft/asyncapi-typescript-plugin")>;
7
+ };
8
+ //# sourceMappingURL=builtInPlugins.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builtInPlugins.d.ts","sourceRoot":"","sources":["../src/builtInPlugins.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,qBAAqB;;;CAKC,CAAC;AAEpC,eAAO,MAAM,sBAAsB;;CAEA,CAAC"}
@@ -0,0 +1,8 @@
1
+ export const openApiBuiltInPlugins = {
2
+ 'tanstack-query-react': () => import('@openapi-qraft/tanstack-query-react-plugin'),
3
+ 'openapi-typescript': () => import('@openapi-qraft/openapi-typescript-plugin'),
4
+ };
5
+ export const asyncApiBuiltInPlugins = {
6
+ 'asyncapi-typescript': () => import('@qraft/asyncapi-typescript-plugin'),
7
+ };
8
+ //# sourceMappingURL=builtInPlugins.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builtInPlugins.js","sourceRoot":"","sources":["../src/builtInPlugins.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,sBAAsB,EAAE,GAAG,EAAE,CAC3B,MAAM,CAAC,4CAA4C,CAAC;IACtD,oBAAoB,EAAE,GAAG,EAAE,CACzB,MAAM,CAAC,0CAA0C,CAAC;CACnB,CAAC;AAEpC,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,qBAAqB,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,mCAAmC,CAAC;CACvC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ParseOptions } from 'commander';
2
+ export declare function qraftAsyncapi(processArgv: string[], processArgvParseOptions?: ParseOptions): Promise<void>;
3
+ //# sourceMappingURL=asyncapi.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asyncapi.d.ts","sourceRoot":"","sources":["../../src/commands/asyncapi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAG9C,wBAAsB,aAAa,CACjC,WAAW,EAAE,MAAM,EAAE,EACrB,uBAAuB,CAAC,EAAE,YAAY,iBAcvC"}
@@ -0,0 +1,9 @@
1
+ import { runAsyncAPI } from './runAsyncAPI.js';
2
+ export async function qraftAsyncapi(processArgv, processArgvParseOptions) {
3
+ const { RedoclyConfigCommand, ASYNCAPI_QRAFT_REDOC_CONFIG_KEY } = await import('@qraft/plugin/lib/RedoclyConfigCommand');
4
+ const redoclyConfigParseResult = await new RedoclyConfigCommand().parseConfig({ [ASYNCAPI_QRAFT_REDOC_CONFIG_KEY]: runAsyncAPI }, processArgv, processArgvParseOptions);
5
+ if (redoclyConfigParseResult?.length)
6
+ return;
7
+ await runAsyncAPI(processArgv, processArgvParseOptions);
8
+ }
9
+ //# sourceMappingURL=asyncapi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asyncapi.js","sourceRoot":"","sources":["../../src/commands/asyncapi.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,WAAqB,EACrB,uBAAsC;IAEtC,MAAM,EAAE,oBAAoB,EAAE,+BAA+B,EAAE,GAC7D,MAAM,MAAM,CAAC,wCAAwC,CAAC,CAAC;IAEzD,MAAM,wBAAwB,GAAG,MAAM,IAAI,oBAAoB,EAAE,CAAC,WAAW,CAC3E,EAAE,CAAC,+BAA+B,CAAC,EAAE,WAAW,EAAE,EAClD,WAAW,EACX,uBAAuB,CACxB,CAAC;IAEF,IAAI,wBAAwB,EAAE,MAAM;QAAE,OAAO;IAE7C,MAAM,WAAW,CAAC,WAAW,EAAE,uBAAuB,CAAC,CAAC;AAC1D,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ParseOptions } from 'commander';
2
+ export declare function qraftOpenapi(processArgv: string[], processArgvParseOptions?: ParseOptions): Promise<void>;
3
+ //# sourceMappingURL=openapi.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../../src/commands/openapi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAG9C,wBAAsB,YAAY,CAChC,WAAW,EAAE,MAAM,EAAE,EACrB,uBAAuB,CAAC,EAAE,YAAY,iBAcvC"}
@@ -0,0 +1,9 @@
1
+ import { runOpenAPI } from './runOpenAPI.js';
2
+ export async function qraftOpenapi(processArgv, processArgvParseOptions) {
3
+ const { RedoclyConfigCommand, OPENAPI_QRAFT_REDOC_CONFIG_KEY } = await import('@qraft/plugin/lib/RedoclyConfigCommand');
4
+ const redoclyConfigParseResult = await new RedoclyConfigCommand().parseConfig({ [OPENAPI_QRAFT_REDOC_CONFIG_KEY]: runOpenAPI }, processArgv, processArgvParseOptions);
5
+ if (redoclyConfigParseResult?.length)
6
+ return;
7
+ await runOpenAPI(processArgv, processArgvParseOptions);
8
+ }
9
+ //# sourceMappingURL=openapi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openapi.js","sourceRoot":"","sources":["../../src/commands/openapi.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,WAAqB,EACrB,uBAAsC;IAEtC,MAAM,EAAE,oBAAoB,EAAE,8BAA8B,EAAE,GAC5D,MAAM,MAAM,CAAC,wCAAwC,CAAC,CAAC;IAEzD,MAAM,wBAAwB,GAAG,MAAM,IAAI,oBAAoB,EAAE,CAAC,WAAW,CAC3E,EAAE,CAAC,8BAA8B,CAAC,EAAE,UAAU,EAAE,EAChD,WAAW,EACX,uBAAuB,CACxB,CAAC;IAEF,IAAI,wBAAwB,EAAE,MAAM;QAAE,OAAO;IAE7C,MAAM,UAAU,CAAC,WAAW,EAAE,uBAAuB,CAAC,CAAC;AACzD,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { ParseOptions } from 'commander';
2
+ export declare function runAsyncAPI(processArgv: string[], processArgvParseOptions?: ParseOptions): Promise<void>;
3
+ //# sourceMappingURL=runAsyncAPI.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runAsyncAPI.d.ts","sourceRoot":"","sources":["../../src/commands/runAsyncAPI.ts"],"names":[],"mappings":"AAOA,OAAO,EAAU,YAAY,EAAE,MAAM,WAAW,CAAC;AAGjD,wBAAsB,WAAW,CAC/B,WAAW,EAAE,MAAM,EAAE,EACrB,uBAAuB,CAAC,EAAE,YAAY,iBAuCvC"}
@@ -0,0 +1,30 @@
1
+ import { addCommandUsageWithPlugins, createFileHeader, extractArgvPluginOptions, hasHelpOption, setupPlugins, } from '@qraft/cli-utils';
2
+ import { Option } from 'commander';
3
+ import { asyncApiBuiltInPlugins } from '../builtInPlugins.js';
4
+ export async function runAsyncAPI(processArgv, processArgvParseOptions) {
5
+ const { QraftCommand } = await import('@qraft/asyncapi-plugin');
6
+ const command = new QraftCommand('qraft asyncapi', {
7
+ defaultFileHeader: createFileHeader('@qraft/cli'),
8
+ });
9
+ const { argv, plugins } = extractArgvPluginOptions(processArgv);
10
+ if (plugins) {
11
+ await setupPlugins({
12
+ command,
13
+ plugins,
14
+ builtInPlugins: asyncApiBuiltInPlugins,
15
+ addUsage: addCommandUsageWithPlugins,
16
+ });
17
+ }
18
+ else {
19
+ command.addOption(new Option('--plugin <name_1> --plugin <name_2>', `Specifies which generator plugins should be used for code generation`)
20
+ .choices(Object.keys(asyncApiBuiltInPlugins))
21
+ .argParser(() => {
22
+ throw new Error('The plugin option must be processed before command parsing and should not be directly passed to the commander');
23
+ }));
24
+ if (!hasHelpOption(argv)) {
25
+ throw new Error(`Plugin must be explicitly specified for asyncapi command. Available plugins: ${Object.keys(asyncApiBuiltInPlugins).join(', ')}`);
26
+ }
27
+ }
28
+ await command.parseAsync(argv, processArgvParseOptions);
29
+ }
30
+ //# sourceMappingURL=runAsyncAPI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runAsyncAPI.js","sourceRoot":"","sources":["../../src/commands/runAsyncAPI.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAC1B,gBAAgB,EAChB,wBAAwB,EACxB,aAAa,EACb,YAAY,GACb,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAgB,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,WAAqB,EACrB,uBAAsC;IAEtC,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAC;IAEhE,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC,gBAAgB,EAAE;QACjD,iBAAiB,EAAE,gBAAgB,CAAC,YAAY,CAAC;KAClD,CAAC,CAAC;IAEH,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,wBAAwB,CAAC,WAAW,CAAC,CAAC;IAEhE,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,YAAY,CAAC;YACjB,OAAO;YACP,OAAO;YACP,cAAc,EAAE,sBAAsB;YACtC,QAAQ,EAAE,0BAA0B;SACrC,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,SAAS,CACf,IAAI,MAAM,CACR,qCAAqC,EACrC,sEAAsE,CACvE;aACE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;aAC5C,SAAS,CAAC,GAAG,EAAE;YACd,MAAM,IAAI,KAAK,CACb,+GAA+G,CAChH,CAAC;QACJ,CAAC,CAAC,CACL,CAAC;QAEF,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CACb,gFAAgF,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACjI,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,uBAAuB,CAAC,CAAC;AAC1D,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { ParseOptions } from 'commander';
2
+ export declare function runOpenAPI(processArgv: string[], processArgvParseOptions?: ParseOptions): Promise<void>;
3
+ //# sourceMappingURL=runOpenAPI.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runOpenAPI.d.ts","sourceRoot":"","sources":["../../src/commands/runOpenAPI.ts"],"names":[],"mappings":"AAOA,OAAO,EAAU,YAAY,EAAE,MAAM,WAAW,CAAC;AAGjD,wBAAsB,UAAU,CAC9B,WAAW,EAAE,MAAM,EAAE,EACrB,uBAAuB,CAAC,EAAE,YAAY,iBAuCvC"}
@@ -0,0 +1,30 @@
1
+ import { addCommandUsageWithPlugins, createFileHeader, extractArgvPluginOptions, hasHelpOption, setupPlugins, } from '@qraft/cli-utils';
2
+ import { Option } from 'commander';
3
+ import { openApiBuiltInPlugins } from '../builtInPlugins.js';
4
+ export async function runOpenAPI(processArgv, processArgvParseOptions) {
5
+ const { QraftCommand } = await import('@openapi-qraft/plugin');
6
+ const command = new QraftCommand('qraft openapi', {
7
+ defaultFileHeader: createFileHeader('@qraft/cli'),
8
+ });
9
+ const { argv, plugins } = extractArgvPluginOptions(processArgv);
10
+ if (plugins) {
11
+ await setupPlugins({
12
+ command,
13
+ plugins,
14
+ builtInPlugins: openApiBuiltInPlugins,
15
+ addUsage: addCommandUsageWithPlugins,
16
+ });
17
+ }
18
+ else {
19
+ command.addOption(new Option('--plugin <name_1> --plugin <name_2>', `Specifies which generator plugins should be used for code generation`)
20
+ .choices(Object.keys(openApiBuiltInPlugins))
21
+ .argParser(() => {
22
+ throw new Error('The plugin option must be processed before command parsing and should not be directly passed to the commander');
23
+ }));
24
+ if (!hasHelpOption(argv)) {
25
+ throw new Error(`Plugin must be explicitly specified for openapi command. Available plugins: ${Object.keys(openApiBuiltInPlugins).join(', ')}`);
26
+ }
27
+ }
28
+ await command.parseAsync(argv, processArgvParseOptions);
29
+ }
30
+ //# sourceMappingURL=runOpenAPI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runOpenAPI.js","sourceRoot":"","sources":["../../src/commands/runOpenAPI.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAC1B,gBAAgB,EAChB,wBAAwB,EACxB,aAAa,EACb,YAAY,GACb,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAgB,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,WAAqB,EACrB,uBAAsC;IAEtC,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAC;IAE/D,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC,eAAe,EAAE;QAChD,iBAAiB,EAAE,gBAAgB,CAAC,YAAY,CAAC;KAClD,CAAC,CAAC;IAEH,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,wBAAwB,CAAC,WAAW,CAAC,CAAC;IAEhE,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,YAAY,CAAC;YACjB,OAAO;YACP,OAAO;YACP,cAAc,EAAE,qBAAqB;YACrC,QAAQ,EAAE,0BAA0B;SACrC,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,SAAS,CACf,IAAI,MAAM,CACR,qCAAqC,EACrC,sEAAsE,CACvE;aACE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;aAC3C,SAAS,CAAC,GAAG,EAAE;YACd,MAAM,IAAI,KAAK,CACb,+GAA+G,CAChH,CAAC;QACJ,CAAC,CAAC,CACL,CAAC;QAEF,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CACb,+EAA+E,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC/H,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,uBAAuB,CAAC,CAAC;AAC1D,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const packageVersion = "1.0.0-beta.0";
2
+ //# sourceMappingURL=packageVersion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,3 @@
1
+ // This file was generated automatically
2
+ export const packageVersion = '1.0.0-beta.0';
3
+ //# sourceMappingURL=packageVersion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,MAAM,CAAC,MAAM,cAAc,GAAG,cAAc,CAAC"}
package/package.json ADDED
@@ -0,0 +1,114 @@
1
+ {
2
+ "name": "@qraft/cli",
3
+ "version": "1.0.0-beta.0",
4
+ "description": "CLI tool for generating type-safe code from OpenAPI and AsyncAPI specifications",
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
+ "write-package-version-file": "yarn exec ../../write-package-version-file.sh"
13
+ },
14
+ "type": "module",
15
+ "bin": {
16
+ "qraft": "./bin.mjs"
17
+ },
18
+ "peerDependencies": {
19
+ "@openapi-qraft/openapi-typescript-plugin": "2.15.0-beta.1",
20
+ "@openapi-qraft/plugin": "2.15.0-beta.1",
21
+ "@openapi-qraft/tanstack-query-react-plugin": "2.15.0-beta.1",
22
+ "@qraft/asyncapi-plugin": "1.0.0-beta.0",
23
+ "@qraft/asyncapi-typescript-plugin": "1.0.0-beta.0"
24
+ },
25
+ "peerDependenciesMeta": {
26
+ "@openapi-qraft/openapi-typescript-plugin": {
27
+ "optional": true
28
+ },
29
+ "@openapi-qraft/plugin": {
30
+ "optional": true
31
+ },
32
+ "@openapi-qraft/tanstack-query-react-plugin": {
33
+ "optional": true
34
+ },
35
+ "@qraft/asyncapi-plugin": {
36
+ "optional": true
37
+ },
38
+ "@qraft/asyncapi-typescript-plugin": {
39
+ "optional": true
40
+ }
41
+ },
42
+ "dependencies": {
43
+ "@qraft/cli-utils": "1.0.0-beta.0",
44
+ "@qraft/plugin": "1.0.0-beta.0",
45
+ "ansi-colors": "^4.1.3",
46
+ "commander": "^14.0.2"
47
+ },
48
+ "devDependencies": {
49
+ "@openapi-qraft/eslint-config": "1.0.1",
50
+ "@openapi-qraft/openapi-typescript-plugin": "2.15.0-beta.1",
51
+ "@openapi-qraft/plugin": "2.15.0-beta.1",
52
+ "@openapi-qraft/tanstack-query-react-plugin": "2.15.0-beta.1",
53
+ "@qraft/asyncapi-plugin": "1.0.0-beta.0",
54
+ "@qraft/asyncapi-typescript-plugin": "1.0.0-beta.0",
55
+ "@types/node": "^20.16.5",
56
+ "eslint": "^9.39.1",
57
+ "rimraf": "^6.1.2",
58
+ "typescript": "^5.6.2",
59
+ "vitest": "^3.2.4"
60
+ },
61
+ "files": [
62
+ "dist",
63
+ "src",
64
+ "!dist/**/*.test.*",
65
+ "!dist/**/*.spec.*",
66
+ "!src/**/*.test.*",
67
+ "!src/**/*.spec.*"
68
+ ],
69
+ "module": "dist/bin.js",
70
+ "types": "dist/bin.d.ts",
71
+ "exports": {
72
+ "./package.json": "./package.json",
73
+ "./*": {
74
+ "types": "./dist/*.d.ts",
75
+ "import": "./dist/*.js"
76
+ }
77
+ },
78
+ "typesVersions": {
79
+ "*": {
80
+ "*": [
81
+ "dist/*"
82
+ ]
83
+ }
84
+ },
85
+ "repository": {
86
+ "type": "git",
87
+ "url": "git+https://github.com/OpenAPI-Qraft/openapi-qraft.git",
88
+ "directory": "packages/cli"
89
+ },
90
+ "bugs": {
91
+ "url": "https://github.com/OpenAPI-Qraft/openapi-qraft/issues"
92
+ },
93
+ "homepage": "https://openapi-qraft.github.io/openapi-qraft/",
94
+ "keywords": [
95
+ "openapi",
96
+ "swagger",
97
+ "rest",
98
+ "api",
99
+ "oapi_3",
100
+ "oapi_3_1",
101
+ "typescript",
102
+ "ts",
103
+ "dts",
104
+ "codegen",
105
+ "generation",
106
+ "fetch",
107
+ "react",
108
+ "hooks",
109
+ "TanStack Query"
110
+ ],
111
+ "publishConfig": {
112
+ "access": "public"
113
+ }
114
+ }
package/src/bin.ts ADDED
@@ -0,0 +1,134 @@
1
+ #!/usr/bin/env node
2
+ import type { ParseOptions } from 'commander';
3
+ import {
4
+ ASYNCAPI_QRAFT_REDOC_CONFIG_KEY,
5
+ OPENAPI_QRAFT_REDOC_CONFIG_KEY,
6
+ } from '@qraft/plugin/lib/getRedocAPIsToQraft';
7
+ import {
8
+ createRedoclyOption,
9
+ RedoclyConfigCommand,
10
+ } from '@qraft/plugin/lib/RedoclyConfigCommand';
11
+ import c from 'ansi-colors';
12
+ import { Command } from 'commander';
13
+ import { packageVersion } from './packageVersion.js';
14
+
15
+ export async function main(
16
+ processArgv: string[],
17
+ processArgvParseOptions?: ParseOptions
18
+ ) {
19
+ const program = new Command();
20
+
21
+ program
22
+ .name('qraft')
23
+ .description(
24
+ 'Generate type-safe code from OpenAPI and AsyncAPI specifications'
25
+ )
26
+ // todo::maybe add "<bin> help <command>" handling
27
+ .helpCommand(false)
28
+ .version(packageVersion);
29
+
30
+ program
31
+ .command('openapi')
32
+ .description('Generate code from OpenAPI specification')
33
+ .allowUnknownOption()
34
+ .allowExcessArguments()
35
+ .action(async () => {
36
+ const subcommandArgv = extractSubcommandArgv(processArgv, 'openapi');
37
+ const { qraftOpenapi } = await import('./commands/openapi.js');
38
+ await qraftOpenapi(subcommandArgv, processArgvParseOptions);
39
+ })
40
+ .helpOption(false); // The command handles the help independently
41
+
42
+ program
43
+ .command('asyncapi')
44
+ .description('Generate code from AsyncAPI specification')
45
+ .allowUnknownOption()
46
+ .allowExcessArguments()
47
+ .action(async () => {
48
+ const subcommandArgv = extractSubcommandArgv(processArgv, 'asyncapi');
49
+ const { qraftAsyncapi } = await import('./commands/asyncapi.js');
50
+ await qraftAsyncapi(subcommandArgv, processArgvParseOptions);
51
+ })
52
+ .helpOption(false); // The command handles the help independently
53
+
54
+ program
55
+ .command('redocly')
56
+ .description('Generate from Redocly config (both OpenAPI and AsyncAPI)')
57
+ .argument(
58
+ '[apis...]',
59
+ 'Selective API names from Redocly config to generate'
60
+ )
61
+ .addOption(createRedoclyOption())
62
+ .action(async (apis: string[], options: { redocly: string | boolean }) => {
63
+ const redoclyArgv = buildRedoclyArgv(apis, options.redocly);
64
+
65
+ await new RedoclyConfigCommand().parseConfig(
66
+ {
67
+ [OPENAPI_QRAFT_REDOC_CONFIG_KEY]: async (argv, parseOptions) => {
68
+ const { runOpenAPI } = await import('./commands/runOpenAPI.js');
69
+ return runOpenAPI(argv, parseOptions);
70
+ },
71
+ [ASYNCAPI_QRAFT_REDOC_CONFIG_KEY]: async (argv, parseOptions) => {
72
+ const { runAsyncAPI } = await import('./commands/runAsyncAPI.js');
73
+ return runAsyncAPI(argv, parseOptions);
74
+ },
75
+ },
76
+ redoclyArgv,
77
+ { from: 'user' }
78
+ );
79
+ });
80
+
81
+ program.addHelpText(
82
+ 'after',
83
+ `
84
+ ${c.bold('Examples:')}
85
+ ${c.dim('# Generate React Query hooks from OpenAPI')}
86
+ $ qraft openapi --plugin tanstack-query-react ./openapi.yaml -o ./src/api
87
+
88
+ ${c.dim('# Generate TypeScript types from OpenAPI')}
89
+ $ qraft openapi --plugin openapi-typescript ./openapi.yaml -o ./src/types
90
+
91
+ ${c.dim('# Generate TypeScript types from AsyncAPI')}
92
+ $ qraft asyncapi --plugin asyncapi-typescript ./asyncapi.yaml -o ./src/types
93
+
94
+ ${c.dim('# Generate from Redocly config (both OpenAPI and AsyncAPI)')}
95
+ $ qraft redocly
96
+
97
+ ${c.dim('# Generate specific APIs from Redocly config')}
98
+ $ qraft redocly openapi-main asyncapi-main
99
+
100
+ ${c.dim('# Generate from custom Redocly config path')}
101
+ $ qraft redocly --redocly ./custom-redocly.yaml
102
+ `
103
+ );
104
+
105
+ await program.parseAsync(processArgv, processArgvParseOptions);
106
+ }
107
+
108
+ function buildRedoclyArgv(
109
+ apis: string[],
110
+ redoclyConfig: string | boolean
111
+ ): string[] {
112
+ const argv: string[] = [...apis];
113
+
114
+ if (typeof redoclyConfig === 'string') {
115
+ argv.push('--redocly', redoclyConfig);
116
+ } else if (redoclyConfig) {
117
+ argv.push('--redocly');
118
+ }
119
+
120
+ return argv;
121
+ }
122
+
123
+ function extractSubcommandArgv(
124
+ processArgv: string[],
125
+ subcommand: string
126
+ ): string[] {
127
+ const subcommandIndex = processArgv.indexOf(subcommand);
128
+ if (subcommandIndex === -1) return processArgv;
129
+
130
+ return [
131
+ ...processArgv.slice(0, 2),
132
+ ...processArgv.slice(subcommandIndex + 1),
133
+ ];
134
+ }
@@ -0,0 +1,12 @@
1
+ import type { BuiltInPlugins } from '@qraft/cli-utils';
2
+
3
+ export const openApiBuiltInPlugins = {
4
+ 'tanstack-query-react': () =>
5
+ import('@openapi-qraft/tanstack-query-react-plugin'),
6
+ 'openapi-typescript': () =>
7
+ import('@openapi-qraft/openapi-typescript-plugin'),
8
+ } as const satisfies BuiltInPlugins;
9
+
10
+ export const asyncApiBuiltInPlugins = {
11
+ 'asyncapi-typescript': () => import('@qraft/asyncapi-typescript-plugin'),
12
+ } as const satisfies BuiltInPlugins;
@@ -0,0 +1,20 @@
1
+ import type { ParseOptions } from 'commander';
2
+ import { runAsyncAPI } from './runAsyncAPI.js';
3
+
4
+ export async function qraftAsyncapi(
5
+ processArgv: string[],
6
+ processArgvParseOptions?: ParseOptions
7
+ ) {
8
+ const { RedoclyConfigCommand, ASYNCAPI_QRAFT_REDOC_CONFIG_KEY } =
9
+ await import('@qraft/plugin/lib/RedoclyConfigCommand');
10
+
11
+ const redoclyConfigParseResult = await new RedoclyConfigCommand().parseConfig(
12
+ { [ASYNCAPI_QRAFT_REDOC_CONFIG_KEY]: runAsyncAPI },
13
+ processArgv,
14
+ processArgvParseOptions
15
+ );
16
+
17
+ if (redoclyConfigParseResult?.length) return;
18
+
19
+ await runAsyncAPI(processArgv, processArgvParseOptions);
20
+ }
@@ -0,0 +1,20 @@
1
+ import type { ParseOptions } from 'commander';
2
+ import { runOpenAPI } from './runOpenAPI.js';
3
+
4
+ export async function qraftOpenapi(
5
+ processArgv: string[],
6
+ processArgvParseOptions?: ParseOptions
7
+ ) {
8
+ const { RedoclyConfigCommand, OPENAPI_QRAFT_REDOC_CONFIG_KEY } =
9
+ await import('@qraft/plugin/lib/RedoclyConfigCommand');
10
+
11
+ const redoclyConfigParseResult = await new RedoclyConfigCommand().parseConfig(
12
+ { [OPENAPI_QRAFT_REDOC_CONFIG_KEY]: runOpenAPI },
13
+ processArgv,
14
+ processArgvParseOptions
15
+ );
16
+
17
+ if (redoclyConfigParseResult?.length) return;
18
+
19
+ await runOpenAPI(processArgv, processArgvParseOptions);
20
+ }
@@ -0,0 +1,52 @@
1
+ import {
2
+ addCommandUsageWithPlugins,
3
+ createFileHeader,
4
+ extractArgvPluginOptions,
5
+ hasHelpOption,
6
+ setupPlugins,
7
+ } from '@qraft/cli-utils';
8
+ import { Option, ParseOptions } from 'commander';
9
+ import { asyncApiBuiltInPlugins } from '../builtInPlugins.js';
10
+
11
+ export async function runAsyncAPI(
12
+ processArgv: string[],
13
+ processArgvParseOptions?: ParseOptions
14
+ ) {
15
+ const { QraftCommand } = await import('@qraft/asyncapi-plugin');
16
+
17
+ const command = new QraftCommand('qraft asyncapi', {
18
+ defaultFileHeader: createFileHeader('@qraft/cli'),
19
+ });
20
+
21
+ const { argv, plugins } = extractArgvPluginOptions(processArgv);
22
+
23
+ if (plugins) {
24
+ await setupPlugins({
25
+ command,
26
+ plugins,
27
+ builtInPlugins: asyncApiBuiltInPlugins,
28
+ addUsage: addCommandUsageWithPlugins,
29
+ });
30
+ } else {
31
+ command.addOption(
32
+ new Option(
33
+ '--plugin <name_1> --plugin <name_2>',
34
+ `Specifies which generator plugins should be used for code generation`
35
+ )
36
+ .choices(Object.keys(asyncApiBuiltInPlugins))
37
+ .argParser(() => {
38
+ throw new Error(
39
+ 'The plugin option must be processed before command parsing and should not be directly passed to the commander'
40
+ );
41
+ })
42
+ );
43
+
44
+ if (!hasHelpOption(argv)) {
45
+ throw new Error(
46
+ `Plugin must be explicitly specified for asyncapi command. Available plugins: ${Object.keys(asyncApiBuiltInPlugins).join(', ')}`
47
+ );
48
+ }
49
+ }
50
+
51
+ await command.parseAsync(argv, processArgvParseOptions);
52
+ }
@@ -0,0 +1,52 @@
1
+ import {
2
+ addCommandUsageWithPlugins,
3
+ createFileHeader,
4
+ extractArgvPluginOptions,
5
+ hasHelpOption,
6
+ setupPlugins,
7
+ } from '@qraft/cli-utils';
8
+ import { Option, ParseOptions } from 'commander';
9
+ import { openApiBuiltInPlugins } from '../builtInPlugins.js';
10
+
11
+ export async function runOpenAPI(
12
+ processArgv: string[],
13
+ processArgvParseOptions?: ParseOptions
14
+ ) {
15
+ const { QraftCommand } = await import('@openapi-qraft/plugin');
16
+
17
+ const command = new QraftCommand('qraft openapi', {
18
+ defaultFileHeader: createFileHeader('@qraft/cli'),
19
+ });
20
+
21
+ const { argv, plugins } = extractArgvPluginOptions(processArgv);
22
+
23
+ if (plugins) {
24
+ await setupPlugins({
25
+ command,
26
+ plugins,
27
+ builtInPlugins: openApiBuiltInPlugins,
28
+ addUsage: addCommandUsageWithPlugins,
29
+ });
30
+ } else {
31
+ command.addOption(
32
+ new Option(
33
+ '--plugin <name_1> --plugin <name_2>',
34
+ `Specifies which generator plugins should be used for code generation`
35
+ )
36
+ .choices(Object.keys(openApiBuiltInPlugins))
37
+ .argParser(() => {
38
+ throw new Error(
39
+ 'The plugin option must be processed before command parsing and should not be directly passed to the commander'
40
+ );
41
+ })
42
+ );
43
+
44
+ if (!hasHelpOption(argv)) {
45
+ throw new Error(
46
+ `Plugin must be explicitly specified for openapi command. Available plugins: ${Object.keys(openApiBuiltInPlugins).join(', ')}`
47
+ );
48
+ }
49
+ }
50
+
51
+ await command.parseAsync(argv, processArgvParseOptions);
52
+ }
@@ -0,0 +1,2 @@
1
+ // This file was generated automatically
2
+ export const packageVersion = '1.0.0-beta.0';