@openapi-qraft/cli 1.8.0 → 1.10.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 +109 -43
- package/bin.mjs +3 -1
- package/dist/bin.d.ts +6 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +37 -21
- package/dist/bin.js.map +1 -1
- package/dist/builtInPlugins.d.ts +5 -0
- package/dist/builtInPlugins.d.ts.map +1 -0
- package/dist/builtInPlugins.js +5 -0
- package/dist/builtInPlugins.js.map +1 -0
- package/package.json +4 -2
- package/src/bin.ts +57 -29
- package/src/builtInPlugins.ts +6 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# @openapi-qraft/cli
|
|
2
2
|
|
|
3
|
+
## 1.10.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [b04f28d]
|
|
8
|
+
- Updated dependencies [4d8bd3c]
|
|
9
|
+
- @openapi-qraft/plugin@1.10.0
|
|
10
|
+
- @openapi-qraft/tanstack-query-react-plugin@1.10.0
|
|
11
|
+
- @openapi-qraft/openapi-typescript-plugin@1.0.2
|
|
12
|
+
|
|
13
|
+
## 1.9.0
|
|
14
|
+
|
|
15
|
+
### Minor Changes
|
|
16
|
+
|
|
17
|
+
- 3a75364: **Plugin Support in CLI**: Introduced the `--plugin <name>` option in the OpenAPI Qraft CLI to allow users to specify
|
|
18
|
+
plugins such as `tanstack-query-react` for React service generation and `openapi-typescript` for TypeScript type
|
|
19
|
+
generation. This enhancement provides greater flexibility and customization options in the API generation process. The
|
|
20
|
+
CLI now supports using multiple plugins simultaneously, enhancing the tool's versatility for developers.
|
|
21
|
+
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- Updated dependencies [943a9d3]
|
|
25
|
+
- Updated dependencies [3a75364]
|
|
26
|
+
- @openapi-qraft/plugin@1.9.0
|
|
27
|
+
- @openapi-qraft/openapi-typescript-plugin@1.0.1
|
|
28
|
+
- @openapi-qraft/tanstack-query-react-plugin@1.9.0
|
|
29
|
+
|
|
3
30
|
## 1.8.0
|
|
4
31
|
|
|
5
32
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -19,49 +19,59 @@ npm install -g @openapi-qraft/cli
|
|
|
19
19
|
## Usage
|
|
20
20
|
|
|
21
21
|
```
|
|
22
|
-
Usage: openapi-qraft [
|
|
22
|
+
Usage: openapi-qraft --plugin tanstack-query-react --plugin openapi-typescript [input] [options]
|
|
23
|
+
|
|
24
|
+
Generate TypeScript types from OpenAPI 3.x Document. Based on "openapi-typescript" (https://github.com/drwpow/openapi-typescript/)
|
|
23
25
|
|
|
24
26
|
Arguments:
|
|
25
|
-
input
|
|
27
|
+
input Input OpenAPI Document file path, URL (json, yml) (default: null)
|
|
26
28
|
|
|
27
29
|
Options:
|
|
28
|
-
-o, --output-dir <path>
|
|
29
|
-
|
|
30
|
-
-
|
|
31
|
-
|
|
32
|
-
--
|
|
33
|
-
--
|
|
34
|
-
|
|
35
|
-
--
|
|
36
|
-
--
|
|
37
|
-
-
|
|
30
|
+
-o, --output-dir <path> Output directory for generated services
|
|
31
|
+
-rm, --clean Clean output directory before generating services
|
|
32
|
+
--filter-services <glob-pattern> Filter services to be generated by glob pattern. Eg: "/user/**,/post/**". See NPM `micromatch` package for more
|
|
33
|
+
details.
|
|
34
|
+
--postfix-services <string> Postfix to be added to the generated service name (eg: Service)
|
|
35
|
+
--service-name-base <endpoint[<index>] | tags> Use OpenAPI Operation `endpoint[<index>]` path part (e.g.: "/0/1/2") or `tags` as the base name of the service.
|
|
36
|
+
(default: "endpoint[0]")
|
|
37
|
+
--file-header <string> Header to be added to the generated file (eg: /* eslint-disable */)
|
|
38
|
+
--openapi-types-import-path <path> Path to schema types file (.d.ts), eg: "../schema.d.ts"
|
|
39
|
+
--explicit-import-extensions All import statements will include explicit `.js` extensions. Ideal for projects using ECMAScript modules.
|
|
40
|
+
--export-openapi-types [bool] Export the OpenAPI schema types from the generated `./index.ts` file (default: true)
|
|
41
|
+
--operation-generics-import-path <path> Path to operation generics file (default: "@openapi-qraft/react")
|
|
42
|
+
--openapi-types-file-name <path> OpenAPI Schema types file name, eg: "schema.d.ts" (default: "schema.ts")
|
|
43
|
+
--enum Export true TS enums instead of unions
|
|
44
|
+
-t, --export-type Export top-level `type` instead of `interface`
|
|
45
|
+
--immutable Generate readonly types
|
|
46
|
+
--additional-properties Treat schema objects as if `additionalProperties: true` is set
|
|
47
|
+
--empty-objects-unknown Generate `unknown` instead of `Record<string, never>` for empty objects
|
|
48
|
+
--default-non-nullable Set to `false` to ignore default values when generating non-nullable types
|
|
49
|
+
--properties-required-by-default Treat schema objects as if `required` is set to all properties by default
|
|
50
|
+
--array-length Generate tuples using array minItems / maxItems
|
|
51
|
+
--path-params-as-types Convert paths to template literal types
|
|
52
|
+
--alphabetize Sort object keys alphabetically
|
|
53
|
+
--exclude-deprecated Exclude deprecated types
|
|
54
|
+
--no-blob-from-binary If this option is enabled, binary format fields will not be converted to Blob types, preserving the native
|
|
55
|
+
representation
|
|
56
|
+
-h, --help display help for command
|
|
57
|
+
|
|
38
58
|
```
|
|
39
59
|
|
|
40
|
-
|
|
60
|
+
## Usage example
|
|
41
61
|
|
|
42
|
-
|
|
62
|
+
The command below generates Qraft API services for the OpenAPI schema and places them in the `src/api` directory:
|
|
43
63
|
|
|
44
|
-
```bash
|
|
45
|
-
openapi-qraft https://
|
|
64
|
+
```bash npm2yarn
|
|
65
|
+
npx openapi-qraft --plugin tanstack-query-react --plugin openapi-typescript https://raw.githubusercontent.com/swagger-api/swagger-petstore/master/src/main/resources/openapi.yaml \
|
|
66
|
+
--output-dir src/api
|
|
46
67
|
```
|
|
47
68
|
|
|
48
|
-
|
|
49
|
-
the `schema.json` file.
|
|
50
|
-
|
|
51
|
-
#### Required Options
|
|
69
|
+
### Required
|
|
52
70
|
|
|
53
71
|
- **`-o <path>, --output-dir <path>`:** Specify where to output the generated services.
|
|
54
72
|
- Example: `--output-dir src/api`
|
|
55
|
-
- **`--openapi-types-import-path <path>`:** Set the path to the schema types definition file to ensure consistent type
|
|
56
|
-
usage (assumed, you already have `openapi.d.ts` as a result of the [`openapi-typescript`](https://github.com/drwpow/openapi-typescript) utility).
|
|
57
|
-
- The path is the exact import specifier used in the _generated services_. It should be \_relative to the service
|
|
58
|
-
output directory.
|
|
59
|
-
- Examples:
|
|
60
|
-
- `--openapi-types-import-path ../openapi.d.ts`
|
|
61
|
-
- `--openapi-types-import-path '@/api/openapi.d.ts'`
|
|
62
|
-
- `--openapi-types-import-path '@external-package-types'`
|
|
63
73
|
|
|
64
|
-
|
|
74
|
+
### Edge-case Options
|
|
65
75
|
|
|
66
76
|
- **`-rm, --clean`:** Clean the specified output directory services before generating to remove stale files _(optional)_.
|
|
67
77
|
- **`--filter-services`:** Filter services to be generated by glob pattern _(optional)_. See [`micromatch`](https://github.com/micromatch/micromatch)
|
|
@@ -69,28 +79,84 @@ the `schema.json` file.
|
|
|
69
79
|
- Examples:
|
|
70
80
|
- `--filter-services '/user/**,/post/**'` - include only API endpoints that start with `/user/` or `/post/`
|
|
71
81
|
- `--filter-services '**,!/internal/**'` - include _all_ API endpoints _except_ those that start with `/internal/`
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
-
|
|
76
|
-
|
|
82
|
+
- **`--service-name-base <endpoint[<index>] | tags>`:** Use OpenAPI Operation `endpoint[<index>]` path part (e.g.: `/0/1/2`) or `tags` as the base name of the service. _(optional, default: `endpoint[0]`)_.
|
|
83
|
+
- Examples:
|
|
84
|
+
- `--service-name-base endpoint[0]` generates `services/FooService.ts` for the endpoint `/foo/bar/baz`
|
|
85
|
+
- `--service-name-base endpoint[1]` generates `services/BarService.ts` for the endpoint `/foo/bar/baz`
|
|
86
|
+
- `--service-name-base endpoint[3]` generates `services/BazService.ts` for the endpoint `/foo/bar/baz` _(if the endpoint is shorter than the index, the last part is used)_
|
|
87
|
+
- `--service-name-base tags` will generate services based on the OpenAPI Operation tags instead of the endpoint.
|
|
88
|
+
- If multiple tags are present for the operation, similar services will be created for each tag. Operation with `tags: [Foo, Bar]` will generate `services/FooService.ts` and `services/BarService.ts`.
|
|
89
|
+
- If there are no tags for the operation, the services will be created under the `default` tag. Operation with empty `tags: []` will generate `services/DefaultService.ts`.
|
|
90
|
+
- **`--explicit-import-extensions`:** Include explicit `.js` extensions in all import statements. Ideal for projects using ECMAScript modules when TypeScript's _--moduleResolution_ is `node16` or `nodenext` _(optional)_.
|
|
77
91
|
- **`--file-header <string>`:** Add a custom header to each generated file, useful for disabling linting rules or adding file
|
|
78
92
|
comments _(optional)_.
|
|
79
93
|
- Example: `--file-header '/* eslint-disable */'`
|
|
80
94
|
- **`--postfix-services <string>`:** Customize the generated service names with a specific postfix _(optional, default: `Service`)_.
|
|
81
95
|
- Example: `--postfix-services Endpoint` will generate `services/UserEndpoint.ts` instead of `services/UserService.ts`.
|
|
82
|
-
- **`--
|
|
96
|
+
- **`--plugin <name_1> --plugin <name_2>`**: Generator plugins to be used. (choices: `tanstack-query-react`, `openapi-typescript`)
|
|
83
97
|
- Examples:
|
|
84
|
-
- `--
|
|
85
|
-
- `--
|
|
86
|
-
- `--
|
|
87
|
-
- `--service-name-base tags` will generate services based on the OpenAPI Operation tags instead of the endpoint.
|
|
88
|
-
- If multiple tags are present for the operation, similar services will be created for each tag. Operation with `tags: [Foo, Bar]` will generate `services/FooService.ts` and `services/BarService.ts`.
|
|
89
|
-
- If there are no tags for the operation, the services will be created under the `default` tag. Operation with empty `tags: []` will generate `services/DefaultService.ts`.
|
|
90
|
-
- **`--explicit-import-extensions`:** Include explicit `.js` extensions in all import statements. Ideal for projects
|
|
91
|
-
using ECMAScript modules when TypeScript's _--moduleResolution_ is `node16` or `nodenext` _(optional)_.
|
|
98
|
+
- `--plugin tanstack-query-react --plugin openapi-typescript` generates Qraft Services and `openapi-typescript` types file.
|
|
99
|
+
- `--plugin tanstack-query-react` generates Qraft Services only.
|
|
100
|
+
- `--plugin openapi-typescript` generates [`openapi-typescript`](https://github.com/drwpow/openapi-typescript) types file only.
|
|
92
101
|
- **`-h, --help`:** Display help for the command (optional).
|
|
93
102
|
|
|
103
|
+
## Plugin System
|
|
104
|
+
|
|
105
|
+
The following plugins are currently supported:
|
|
106
|
+
|
|
107
|
+
- `openapi-typescript` - Generates TypeScript types from an OpenAPI Document. The main difference from the original [`openapi-typescript`](https://www.npmjs.com/package/openapi-typescript) package is that `format: binary` fields default to `Blob` types instead of remaining as `string`. This behavior can be altered using the `--no-blob-from-binary` option.
|
|
108
|
+
- `tanstack-query-react` - Generates Qraft API services for React.
|
|
109
|
+
|
|
110
|
+
> Plugin must be provided with the `--plugin <name>` option. By default, the `tanstack-query-react` plugin is used.
|
|
111
|
+
> It is possible to use multiple plugins at the same time. For example, `--plugin tanstack-query-react --plugin openapi-typescript` generates Qraft API services & schema types file.
|
|
112
|
+
|
|
113
|
+
### `--plugin tanstack-query-react` options
|
|
114
|
+
|
|
115
|
+
- **`--openapi-types-import-path <path>`:** Set the path to the schema types definition file to ensure consistent type
|
|
116
|
+
usage (assumed, you already have `schema.d.ts` as a result of the [`openapi-typescript`](https://github.com/drwpow/openapi-typescript) utility). You also probably
|
|
117
|
+
don't need the ~~`--plugin openapi-typescript`~~ option in this case.
|
|
118
|
+
- The path is the exact import specifier used in the _generated services_. It should be _relative_ to the service
|
|
119
|
+
output directory. _Optional_, if the `--plugin openapi-typescript` is used. _Required_ otherwise.
|
|
120
|
+
- Examples:
|
|
121
|
+
- `--openapi-types-import-path ../openapi.d.ts`
|
|
122
|
+
- `--openapi-types-import-path '@/api/openapi.d.ts'`
|
|
123
|
+
- `--openapi-types-import-path '@external-package-types'`
|
|
124
|
+
- **`--operation-generics-import-path <path>`:** Define the path to the operation generics file, allowing for custom
|
|
125
|
+
operation handling _(optional, default: `@openapi-qraft/react`)_.
|
|
126
|
+
- **`--export-openapi-types [bool]`:** Export the OpenAPI schema types from the generated `./index.ts` file. _(optional, default: `true`, if `--plugin openapi-typescript` is used)_
|
|
127
|
+
|
|
128
|
+
### `--plugin openapi-typescript` options
|
|
129
|
+
|
|
130
|
+
- **`--openapi-types-file-name <path>`**: OpenAPI Schema types file name, e.g., `schema.d.ts` (default: `schema.ts`).
|
|
131
|
+
- **`--enum`**: Export true TypeScript enums instead of unions.
|
|
132
|
+
- **`-t, --export-type`**: Export top-level `type` instead of `interface`.
|
|
133
|
+
- **`--immutable`**: Generate readonly types.
|
|
134
|
+
- **`--additional-properties`**: Treat schema objects as if `additionalProperties: true` is set.
|
|
135
|
+
- **`--empty-objects-unknown`**: Generate `unknown` instead of `Record<string, never>` for empty objects.
|
|
136
|
+
- **`--default-non-nullable`**: Set to `false` to ignore default values when generating non-nullable types.
|
|
137
|
+
- **`--properties-required-by-default`**: Treat schema objects as if `required` is set to all properties by default.
|
|
138
|
+
- **`--array-length`**: Generate tuples using array `minItems` / `maxItems`.
|
|
139
|
+
- **`--path-params-as-types`**: Convert paths to template literal types.
|
|
140
|
+
- **`--alphabetize`**: Sort object keys alphabetically.
|
|
141
|
+
- **`--exclude-deprecated`**: Exclude deprecated types.
|
|
142
|
+
- **`--no-blob-from-binary`**: If this option is enabled, `format: binary` fields will not be converted to `Blob` types, preserving the native type. Could be used with `--plugin openapi-typescript` option.
|
|
143
|
+
|
|
144
|
+
## In-project Setup
|
|
145
|
+
|
|
146
|
+
Add the following `"scripts"` to your `package.json` file:
|
|
147
|
+
|
|
148
|
+
```json lines title="package.json"
|
|
149
|
+
{
|
|
150
|
+
"devDependencies": {
|
|
151
|
+
"@openapi-qraft/cli": "latest"
|
|
152
|
+
},
|
|
153
|
+
"scripts": {
|
|
154
|
+
"generate-client": "openapi-qraft --plugin tanstack-query-react --plugin openapi-typescript https://raw.githubusercontent.com/swagger-api/swagger-petstore/master/src/main/resources/openapi.yaml --output-dir src/api"
|
|
155
|
+
// ...other scripts
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
94
160
|
## Contributing
|
|
95
161
|
|
|
96
162
|
Contributions to `@openapi-qraft/cli` are welcome! Please feel free to submit issues, pull requests, or suggest features
|
package/bin.mjs
CHANGED
package/dist/bin.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
export declare function main(): Promise<undefined>;
|
|
3
|
+
/**
|
|
4
|
+
* Extracts multiple `--plugin <name>` options from the `argv`
|
|
5
|
+
* and returns the filtered `argv` and the list of plugins.
|
|
6
|
+
*/
|
|
2
7
|
export declare function extractArgvPluginOptions(argv: string[]): {
|
|
3
8
|
argv: string[];
|
|
4
9
|
plugins?: undefined;
|
|
@@ -6,3 +11,4 @@ export declare function extractArgvPluginOptions(argv: string[]): {
|
|
|
6
11
|
argv: string[];
|
|
7
12
|
plugins: string[];
|
|
8
13
|
};
|
|
14
|
+
//# sourceMappingURL=bin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AASA,wBAAsB,IAAI,uBA8BzB;AA+BD;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE;;;;;;EAwBtD"}
|
package/dist/bin.js
CHANGED
|
@@ -1,34 +1,52 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { QraftCommand } from '@openapi-qraft/plugin/lib/QraftCommand';
|
|
3
|
+
import { Option } from 'commander';
|
|
3
4
|
import process from 'node:process';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
addCommandUsageWithPlugins(command, plugins);
|
|
11
|
-
command.parse(argv);
|
|
12
|
-
});
|
|
5
|
+
import { builtInPlugins } from './builtInPlugins.js';
|
|
6
|
+
export async function main() {
|
|
7
|
+
const command = new QraftCommand();
|
|
8
|
+
const { argv, plugins } = extractArgvPluginOptions(process.argv);
|
|
9
|
+
if (plugins) {
|
|
10
|
+
await setupPlugins(command, plugins);
|
|
13
11
|
}
|
|
14
12
|
else {
|
|
15
|
-
|
|
13
|
+
// default - setup tanstack-query-react plugin
|
|
14
|
+
await setupPlugins(command, [
|
|
15
|
+
'tanstack-query-react',
|
|
16
|
+
]);
|
|
17
|
+
// option to display help with all available plugins
|
|
18
|
+
command.addOption(new Option('--plugin <name_1> --plugin <name_2>', `Generator plugins to be used.`)
|
|
19
|
+
.choices(Object.keys(builtInPlugins))
|
|
20
|
+
.argParser(() => {
|
|
21
|
+
// Fallback, if plugins parsing went wrong
|
|
22
|
+
throw new Error('Plugin option must be handled before parsing the command and should not be passed to the commander');
|
|
23
|
+
}));
|
|
16
24
|
}
|
|
25
|
+
return void (await command.parseAsync(argv));
|
|
17
26
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
command
|
|
26
|
-
}
|
|
27
|
+
async function setupPlugins(command, plugins) {
|
|
28
|
+
const pluginList = [];
|
|
29
|
+
for (const pluginName of plugins) {
|
|
30
|
+
if (!(pluginName in builtInPlugins))
|
|
31
|
+
throw new Error(`Unknown plugin: '${pluginName}'`);
|
|
32
|
+
pluginList.push((await builtInPlugins[pluginName]())
|
|
33
|
+
.default);
|
|
34
|
+
addCommandUsageWithPlugins(command, plugins);
|
|
35
|
+
}
|
|
36
|
+
await Promise.all(pluginList.map((plugin) => plugin.setupCommand(command)));
|
|
37
|
+
await Promise.all(pluginList.map((plugin) => plugin.postSetupCommand?.(command, plugins)));
|
|
27
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Add plugin's usage instructions calling `command.usage(...)`
|
|
41
|
+
*/
|
|
28
42
|
function addCommandUsageWithPlugins(command, plugins) {
|
|
29
43
|
const pluginUsage = plugins.map((plugin) => `--plugin ${plugin}`).join(' ');
|
|
30
44
|
command.usage(`${pluginUsage} [input] [options]`);
|
|
31
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Extracts multiple `--plugin <name>` options from the `argv`
|
|
48
|
+
* and returns the filtered `argv` and the list of plugins.
|
|
49
|
+
*/
|
|
32
50
|
export function extractArgvPluginOptions(argv) {
|
|
33
51
|
const pluginIndex = argv.indexOf('--plugin');
|
|
34
52
|
if (pluginIndex === -1)
|
|
@@ -49,8 +67,6 @@ export function extractArgvPluginOptions(argv) {
|
|
|
49
67
|
filteredArgv.push(argv[i]);
|
|
50
68
|
}
|
|
51
69
|
}
|
|
52
|
-
if (plugins.length > 1)
|
|
53
|
-
throw new Error(`Only one plugin can be specified, got: '${plugins.join(', ')}'`);
|
|
54
70
|
return {
|
|
55
71
|
argv: filteredArgv,
|
|
56
72
|
plugins,
|
package/dist/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAC;
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const builtInPlugins: {
|
|
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
|
+
//# sourceMappingURL=builtInPlugins.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builtInPlugins.d.ts","sourceRoot":"","sources":["../src/builtInPlugins.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc;;;CAKjB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builtInPlugins.js","sourceRoot":"","sources":["../src/builtInPlugins.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,sBAAsB,EAAE,GAAG,EAAE,CAC3B,MAAM,CAAC,4CAA4C,CAAC;IACtD,oBAAoB,EAAE,GAAG,EAAE,CACzB,MAAM,CAAC,0CAA0C,CAAC;CAC5C,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openapi-qraft/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"description": "CLI for generating typed Tanstack Query React Hooks and services from OpenAPI Schemas, improving type safety in React apps",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "rimraf dist/ && tsc --project tsconfig.build.json",
|
|
@@ -14,7 +14,9 @@
|
|
|
14
14
|
"openapi-qraft": "./bin.mjs"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@openapi-qraft/
|
|
17
|
+
"@openapi-qraft/openapi-typescript-plugin": "~1.0.2",
|
|
18
|
+
"@openapi-qraft/plugin": "~1.10.0",
|
|
19
|
+
"@openapi-qraft/tanstack-query-react-plugin": "~1.10.0",
|
|
18
20
|
"commander": "^11.1.0"
|
|
19
21
|
},
|
|
20
22
|
"devDependencies": {
|
package/src/bin.ts
CHANGED
|
@@ -1,44 +1,77 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { QraftCommand } from '@openapi-qraft/plugin/lib/QraftCommand';
|
|
3
|
+
import type { QraftCommandPlugin } from '@openapi-qraft/plugin/lib/QraftCommandPlugin';
|
|
3
4
|
|
|
5
|
+
import { Option } from 'commander';
|
|
4
6
|
import process from 'node:process';
|
|
5
7
|
|
|
6
|
-
|
|
8
|
+
import { builtInPlugins } from './builtInPlugins.js';
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
export async function main() {
|
|
11
|
+
const command = new QraftCommand();
|
|
9
12
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
plugin.setupCommand(command);
|
|
15
|
-
addCommandUsageWithPlugins(command, plugins);
|
|
16
|
-
command.parse(argv);
|
|
17
|
-
}
|
|
18
|
-
);
|
|
13
|
+
const { argv, plugins } = extractArgvPluginOptions(process.argv);
|
|
14
|
+
|
|
15
|
+
if (plugins) {
|
|
16
|
+
await setupPlugins(command, plugins);
|
|
19
17
|
} else {
|
|
20
|
-
|
|
18
|
+
// default - setup tanstack-query-react plugin
|
|
19
|
+
await setupPlugins(command, [
|
|
20
|
+
'tanstack-query-react',
|
|
21
|
+
] satisfies (keyof typeof builtInPlugins)[]);
|
|
22
|
+
|
|
23
|
+
// option to display help with all available plugins
|
|
24
|
+
command.addOption(
|
|
25
|
+
new Option(
|
|
26
|
+
'--plugin <name_1> --plugin <name_2>',
|
|
27
|
+
`Generator plugins to be used.`
|
|
28
|
+
)
|
|
29
|
+
.choices(Object.keys(builtInPlugins))
|
|
30
|
+
.argParser(() => {
|
|
31
|
+
// Fallback, if plugins parsing went wrong
|
|
32
|
+
throw new Error(
|
|
33
|
+
'Plugin option must be handled before parsing the command and should not be passed to the commander'
|
|
34
|
+
);
|
|
35
|
+
})
|
|
36
|
+
);
|
|
21
37
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
|
|
38
|
+
|
|
39
|
+
return void (await command.parseAsync(argv));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async function setupPlugins(command: QraftCommand, plugins: string[]) {
|
|
43
|
+
const pluginList: QraftCommandPlugin[] = [];
|
|
44
|
+
|
|
45
|
+
for (const pluginName of plugins) {
|
|
46
|
+
if (!(pluginName in builtInPlugins))
|
|
47
|
+
throw new Error(`Unknown plugin: '${pluginName}'`);
|
|
48
|
+
|
|
49
|
+
pluginList.push(
|
|
50
|
+
(await builtInPlugins[pluginName as keyof typeof builtInPlugins]())
|
|
51
|
+
.default
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
addCommandUsageWithPlugins(command, plugins);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
await Promise.all(pluginList.map((plugin) => plugin.setupCommand(command)));
|
|
58
|
+
await Promise.all(
|
|
59
|
+
pluginList.map((plugin) => plugin.postSetupCommand?.(command, plugins))
|
|
34
60
|
);
|
|
35
61
|
}
|
|
36
62
|
|
|
63
|
+
/**
|
|
64
|
+
* Add plugin's usage instructions calling `command.usage(...)`
|
|
65
|
+
*/
|
|
37
66
|
function addCommandUsageWithPlugins(command: QraftCommand, plugins: string[]) {
|
|
38
67
|
const pluginUsage = plugins.map((plugin) => `--plugin ${plugin}`).join(' ');
|
|
39
68
|
command.usage(`${pluginUsage} [input] [options]`);
|
|
40
69
|
}
|
|
41
70
|
|
|
71
|
+
/**
|
|
72
|
+
* Extracts multiple `--plugin <name>` options from the `argv`
|
|
73
|
+
* and returns the filtered `argv` and the list of plugins.
|
|
74
|
+
*/
|
|
42
75
|
export function extractArgvPluginOptions(argv: string[]) {
|
|
43
76
|
const pluginIndex = argv.indexOf('--plugin');
|
|
44
77
|
if (pluginIndex === -1) return { argv };
|
|
@@ -59,11 +92,6 @@ export function extractArgvPluginOptions(argv: string[]) {
|
|
|
59
92
|
}
|
|
60
93
|
}
|
|
61
94
|
|
|
62
|
-
if (plugins.length > 1)
|
|
63
|
-
throw new Error(
|
|
64
|
-
`Only one plugin can be specified, got: '${plugins.join(', ')}'`
|
|
65
|
-
);
|
|
66
|
-
|
|
67
95
|
return {
|
|
68
96
|
argv: filteredArgv,
|
|
69
97
|
plugins,
|