@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.
- package/CHANGELOG.md +27 -0
- package/README.md +139 -0
- package/bin.mjs +10 -0
- package/dist/bin.d.ts +4 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +96 -0
- package/dist/bin.js.map +1 -0
- package/dist/builtInPlugins.d.ts +8 -0
- package/dist/builtInPlugins.d.ts.map +1 -0
- package/dist/builtInPlugins.js +8 -0
- package/dist/builtInPlugins.js.map +1 -0
- package/dist/commands/asyncapi.d.ts +3 -0
- package/dist/commands/asyncapi.d.ts.map +1 -0
- package/dist/commands/asyncapi.js +9 -0
- package/dist/commands/asyncapi.js.map +1 -0
- package/dist/commands/openapi.d.ts +3 -0
- package/dist/commands/openapi.d.ts.map +1 -0
- package/dist/commands/openapi.js +9 -0
- package/dist/commands/openapi.js.map +1 -0
- package/dist/commands/runAsyncAPI.d.ts +3 -0
- package/dist/commands/runAsyncAPI.d.ts.map +1 -0
- package/dist/commands/runAsyncAPI.js +30 -0
- package/dist/commands/runAsyncAPI.js.map +1 -0
- package/dist/commands/runOpenAPI.d.ts +3 -0
- package/dist/commands/runOpenAPI.d.ts.map +1 -0
- package/dist/commands/runOpenAPI.js +30 -0
- package/dist/commands/runOpenAPI.js.map +1 -0
- package/dist/packageVersion.d.ts +2 -0
- package/dist/packageVersion.d.ts.map +1 -0
- package/dist/packageVersion.js +3 -0
- package/dist/packageVersion.js.map +1 -0
- package/package.json +114 -0
- package/src/bin.ts +134 -0
- package/src/builtInPlugins.ts +12 -0
- package/src/commands/asyncapi.ts +20 -0
- package/src/commands/openapi.ts +20 -0
- package/src/commands/runAsyncAPI.ts +52 -0
- package/src/commands/runOpenAPI.ts +52 -0
- 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
package/dist/bin.d.ts
ADDED
|
@@ -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
|
package/dist/bin.js.map
ADDED
|
@@ -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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
1
|
+
{"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,cAAc,iBAAiB,CAAC"}
|
|
@@ -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
|
+
}
|