@travetto/openapi 8.0.0-alpha.22 → 8.0.0-alpha.23
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/README.md +7 -6
- package/__index__.ts +1 -1
- package/package.json +5 -5
- package/src/config.ts +5 -4
- package/src/controller.ts +2 -3
- package/src/generate.ts +53 -31
- package/src/service.ts +5 -7
- package/support/bin/help.ts +5 -6
- package/support/cli.openapi_client.ts +32 -22
- package/support/cli.openapi_spec.ts +4 -5
package/README.md
CHANGED
|
@@ -26,12 +26,12 @@ All of the high level configurations can be found in the following structure:
|
|
|
26
26
|
```typescript
|
|
27
27
|
import path from 'node:path';
|
|
28
28
|
|
|
29
|
-
import type {
|
|
29
|
+
import type { ContactObject, LicenseObject, ServerObject } from 'openapi3-ts/oas31';
|
|
30
30
|
|
|
31
31
|
import { Config } from '@travetto/config';
|
|
32
|
+
import { PostConstruct } from '@travetto/di';
|
|
32
33
|
import { Runtime } from '@travetto/runtime';
|
|
33
34
|
import { Required } from '@travetto/schema';
|
|
34
|
-
import { PostConstruct } from '@travetto/di';
|
|
35
35
|
|
|
36
36
|
/**
|
|
37
37
|
* API Information, infers as much as possible from the package.json
|
|
@@ -105,7 +105,8 @@ export class ApiSpecConfig {
|
|
|
105
105
|
this.persist ??= Runtime.localDevelopment;
|
|
106
106
|
}
|
|
107
107
|
if (this.persist) {
|
|
108
|
-
if (!/[.](json|ya?ml) $/.test(this.output)) {
|
|
108
|
+
if (!/[.](json|ya?ml) $/.test(this.output)) {
|
|
109
|
+
// Assume a folder
|
|
109
110
|
this.output = path.resolve(this.output, 'openapi.yml');
|
|
110
111
|
}
|
|
111
112
|
}
|
|
@@ -114,10 +115,10 @@ export class ApiSpecConfig {
|
|
|
114
115
|
```
|
|
115
116
|
|
|
116
117
|
## Spec Generation
|
|
117
|
-
The framework, when in watch mode, will generate the [OpenAPI](https://github.com/OAI/OpenAPI-Specification) specification in either [JSON](https://www.json.org) or [YAML](https://en.wikipedia.org/wiki/YAML). This module integrates with the file watching paradigm and can regenerate the openapi spec as changes to endpoints and models are made during development.
|
|
118
|
+
The framework, when in watch mode, will generate the [OpenAPI](https://github.com/OAI/OpenAPI-Specification) specification in either [JSON](https://www.json.org) or [YAML](https://en.wikipedia.org/wiki/YAML). This module integrates with the file watching paradigm and can regenerate the openapi spec as changes to endpoints and models are made during development. The output format is defined by the suffix of the output file, `.yaml` or `.json`.
|
|
118
119
|
|
|
119
120
|
## CLI - openapi:spec
|
|
120
|
-
The command will load your application, in non-listening mode, to collect all the endpoints and model information, to produce the `openapi.yml`.
|
|
121
|
+
The command will load your application, in non-listening mode, to collect all the endpoints and model information, to produce the `openapi.yml`. Once produced, the code will store the output in the specified location.
|
|
121
122
|
|
|
122
123
|
**Terminal: Help for openapi:spec**
|
|
123
124
|
```bash
|
|
@@ -163,4 +164,4 @@ Options:
|
|
|
163
164
|
--help display help for command
|
|
164
165
|
```
|
|
165
166
|
|
|
166
|
-
This tool relies upon a custom build of [OpenAPI client generation tools](https://github.com/OpenAPITools/openapi-generator), which supports watching.
|
|
167
|
+
This tool relies upon a custom build of [OpenAPI client generation tools](https://github.com/OpenAPITools/openapi-generator), which supports watching. This allows for fast responsive client generation as the shape of the API changes.
|
package/__index__.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/openapi",
|
|
3
|
-
"version": "8.0.0-alpha.
|
|
3
|
+
"version": "8.0.0-alpha.23",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "OpenAPI integration support for the Travetto framework",
|
|
6
6
|
"keywords": [
|
|
@@ -27,14 +27,14 @@
|
|
|
27
27
|
"directory": "module/openapi"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@travetto/config": "^8.0.0-alpha.
|
|
31
|
-
"@travetto/schema": "^8.0.0-alpha.
|
|
32
|
-
"@travetto/web": "^8.0.0-alpha.
|
|
30
|
+
"@travetto/config": "^8.0.0-alpha.22",
|
|
31
|
+
"@travetto/schema": "^8.0.0-alpha.22",
|
|
32
|
+
"@travetto/web": "^8.0.0-alpha.23",
|
|
33
33
|
"openapi3-ts": "^4.6.0",
|
|
34
34
|
"yaml": "^2.9.0"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
|
-
"@travetto/cli": "^8.0.0-alpha.
|
|
37
|
+
"@travetto/cli": "^8.0.0-alpha.28"
|
|
38
38
|
},
|
|
39
39
|
"peerDependenciesMeta": {
|
|
40
40
|
"@travetto/cli": {
|
package/src/config.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
|
|
3
|
-
import type {
|
|
3
|
+
import type { ContactObject, LicenseObject, ServerObject } from 'openapi3-ts/oas31';
|
|
4
4
|
|
|
5
5
|
import { Config } from '@travetto/config';
|
|
6
|
+
import { PostConstruct } from '@travetto/di';
|
|
6
7
|
import { Runtime } from '@travetto/runtime';
|
|
7
8
|
import { Required } from '@travetto/schema';
|
|
8
|
-
import { PostConstruct } from '@travetto/di';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* API Information, infers as much as possible from the package.json
|
|
@@ -79,9 +79,10 @@ export class ApiSpecConfig {
|
|
|
79
79
|
this.persist ??= Runtime.localDevelopment;
|
|
80
80
|
}
|
|
81
81
|
if (this.persist) {
|
|
82
|
-
if (!/[.](json|ya?ml)$/.test(this.output)) {
|
|
82
|
+
if (!/[.](json|ya?ml)$/.test(this.output)) {
|
|
83
|
+
// Assume a folder
|
|
83
84
|
this.output = path.resolve(this.output, 'openapi.yml');
|
|
84
85
|
}
|
|
85
86
|
}
|
|
86
87
|
}
|
|
87
|
-
}
|
|
88
|
+
}
|
package/src/controller.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { stringify } from 'yaml';
|
|
2
2
|
|
|
3
|
-
import { ConfigureInterceptor, Controller, CorsInterceptor, Get, SetHeaders } from '@travetto/web';
|
|
4
3
|
import { Inject } from '@travetto/di';
|
|
5
4
|
import { IsPrivate } from '@travetto/schema';
|
|
5
|
+
import { ConfigureInterceptor, Controller, CorsInterceptor, Get, SetHeaders } from '@travetto/web';
|
|
6
6
|
|
|
7
7
|
import type { OpenApiService } from './service.ts';
|
|
8
8
|
|
|
@@ -13,7 +13,6 @@ import type { OpenApiService } from './service.ts';
|
|
|
13
13
|
@Controller('/')
|
|
14
14
|
@ConfigureInterceptor(CorsInterceptor, { origins: ['*'] })
|
|
15
15
|
export class OpenApiController {
|
|
16
|
-
|
|
17
16
|
@Inject()
|
|
18
17
|
service: OpenApiService;
|
|
19
18
|
|
|
@@ -27,4 +26,4 @@ export class OpenApiController {
|
|
|
27
26
|
async getYmlSpec(): Promise<string> {
|
|
28
27
|
return stringify(await this.service.getSpec()); // Force output to be simple
|
|
29
28
|
}
|
|
30
|
-
}
|
|
29
|
+
}
|
package/src/generate.ts
CHANGED
|
@@ -1,14 +1,31 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
OperationObject,
|
|
3
|
+
ParameterObject,
|
|
4
|
+
PathItemObject,
|
|
5
|
+
PathsObject,
|
|
6
|
+
RequestBodyObject,
|
|
7
|
+
SchemaObject,
|
|
8
|
+
SchemasObject,
|
|
9
|
+
TagObject
|
|
4
10
|
} from 'openapi3-ts/oas31';
|
|
5
11
|
|
|
6
|
-
import { type
|
|
7
|
-
import { RuntimeError, castTo, type Class, describeFunction } from '@travetto/runtime';
|
|
12
|
+
import { type Class, castTo, describeFunction, RuntimeError } from '@travetto/runtime';
|
|
8
13
|
import {
|
|
9
|
-
type
|
|
10
|
-
type
|
|
14
|
+
type SchemaBasicType,
|
|
15
|
+
type SchemaClassConfig,
|
|
16
|
+
type SchemaFieldConfig,
|
|
17
|
+
type SchemaInputConfig,
|
|
18
|
+
SchemaNameResolver,
|
|
19
|
+
type SchemaParameterConfig,
|
|
20
|
+
SchemaRegistryIndex
|
|
11
21
|
} from '@travetto/schema';
|
|
22
|
+
import {
|
|
23
|
+
type ControllerConfig,
|
|
24
|
+
type ControllerVisitor,
|
|
25
|
+
type EndpointConfig,
|
|
26
|
+
type EndpointParameterConfig,
|
|
27
|
+
HTTP_METHODS
|
|
28
|
+
} from '@travetto/web';
|
|
12
29
|
|
|
13
30
|
import type { ApiSpecConfig } from './config.ts';
|
|
14
31
|
|
|
@@ -45,7 +62,12 @@ export class OpenapiVisitor implements ControllerVisitor<GeneratedSpec> {
|
|
|
45
62
|
/**
|
|
46
63
|
* Convert schema to a set of dotted parameters
|
|
47
64
|
*/
|
|
48
|
-
#schemaToDotParams(
|
|
65
|
+
#schemaToDotParams(
|
|
66
|
+
location: 'query' | 'header',
|
|
67
|
+
input: SchemaInputConfig,
|
|
68
|
+
prefix: string = '',
|
|
69
|
+
rootField: SchemaInputConfig = input
|
|
70
|
+
): ParameterObject[] {
|
|
49
71
|
if (!SchemaRegistryIndex.has(input.type)) {
|
|
50
72
|
throw new RuntimeError(`Unknown class, not registered as a schema: ${input.type.Ⲑid}`);
|
|
51
73
|
}
|
|
@@ -55,17 +77,19 @@ export class OpenapiVisitor implements ControllerVisitor<GeneratedSpec> {
|
|
|
55
77
|
for (const sub of Object.values(fields)) {
|
|
56
78
|
const name = sub.name;
|
|
57
79
|
if (SchemaRegistryIndex.has(sub.type)) {
|
|
58
|
-
const suffix =
|
|
80
|
+
const suffix = sub.array ? '[]' : '';
|
|
59
81
|
params.push(...this.#schemaToDotParams(location, sub, prefix ? `${prefix}.${name}${suffix}` : `${name}${suffix}.`, rootField));
|
|
60
82
|
} else {
|
|
61
83
|
params.push({
|
|
62
84
|
name: `${prefix}${name}`,
|
|
63
85
|
description: sub.description,
|
|
64
|
-
schema: sub.array
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
86
|
+
schema: sub.array
|
|
87
|
+
? {
|
|
88
|
+
type: 'array',
|
|
89
|
+
...this.#getType(sub)
|
|
90
|
+
}
|
|
91
|
+
: this.#getType(sub),
|
|
92
|
+
required: rootField?.required?.active !== false && sub.required?.active !== false,
|
|
69
93
|
in: location
|
|
70
94
|
});
|
|
71
95
|
}
|
|
@@ -77,7 +101,7 @@ export class OpenapiVisitor implements ControllerVisitor<GeneratedSpec> {
|
|
|
77
101
|
* Get the type for a given class
|
|
78
102
|
*/
|
|
79
103
|
#getType(inputOrClass: SchemaInputConfig | Class): Record<string, unknown> {
|
|
80
|
-
let field: { type: Class
|
|
104
|
+
let field: { type: Class; precision?: [number, number | undefined] };
|
|
81
105
|
if (!isInputConfig(inputOrClass)) {
|
|
82
106
|
field = { type: inputOrClass };
|
|
83
107
|
} else {
|
|
@@ -92,7 +116,9 @@ export class OpenapiVisitor implements ControllerVisitor<GeneratedSpec> {
|
|
|
92
116
|
out.$ref = `${DEFINITION}/${id}`;
|
|
93
117
|
} else {
|
|
94
118
|
switch (field.type) {
|
|
95
|
-
case String:
|
|
119
|
+
case String:
|
|
120
|
+
out.type = 'string';
|
|
121
|
+
break;
|
|
96
122
|
case castTo(BigInt):
|
|
97
123
|
out.type = 'integer';
|
|
98
124
|
out.format = 'int64';
|
|
@@ -110,7 +136,9 @@ export class OpenapiVisitor implements ControllerVisitor<GeneratedSpec> {
|
|
|
110
136
|
out.format = 'date-time';
|
|
111
137
|
out.type = 'string';
|
|
112
138
|
break;
|
|
113
|
-
case Boolean:
|
|
139
|
+
case Boolean:
|
|
140
|
+
out.type = 'boolean';
|
|
141
|
+
break;
|
|
114
142
|
default:
|
|
115
143
|
out.type = 'object';
|
|
116
144
|
break;
|
|
@@ -244,7 +272,7 @@ export class OpenapiVisitor implements ControllerVisitor<GeneratedSpec> {
|
|
|
244
272
|
} else if (body.binary) {
|
|
245
273
|
return {
|
|
246
274
|
content: {
|
|
247
|
-
[mime ?? 'application/octet-stream']: { schema: { type: 'string', format: 'binary' } }
|
|
275
|
+
[mime ?? 'application/octet-stream']: { schema: { type: 'string', format: 'binary' } }
|
|
248
276
|
},
|
|
249
277
|
description: 'Raw binary data'
|
|
250
278
|
};
|
|
@@ -266,11 +294,11 @@ export class OpenapiVisitor implements ControllerVisitor<GeneratedSpec> {
|
|
|
266
294
|
/**
|
|
267
295
|
* Process endpoint parameter
|
|
268
296
|
*/
|
|
269
|
-
#processEndpointParam(
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
) {
|
|
297
|
+
#processEndpointParam(
|
|
298
|
+
endpoint: EndpointConfig,
|
|
299
|
+
param: EndpointParameterConfig,
|
|
300
|
+
input: SchemaParameterConfig
|
|
301
|
+
): { requestBody: RequestBodyObject } | { parameters: ParameterObject[] } | undefined {
|
|
274
302
|
const complex = input.type && SchemaRegistryIndex.has(input.type);
|
|
275
303
|
|
|
276
304
|
if (param.location) {
|
|
@@ -360,17 +388,11 @@ export class OpenapiVisitor implements ControllerVisitor<GeneratedSpec> {
|
|
|
360
388
|
paths: Object.fromEntries(
|
|
361
389
|
Object.entries(this.#paths)
|
|
362
390
|
.toSorted(([a], [b]) => a.localeCompare(b))
|
|
363
|
-
.map(([key, value]) => [key, Object.fromEntries(
|
|
364
|
-
Object.entries(value)
|
|
365
|
-
.toSorted(([a], [b]) => a.localeCompare(b))
|
|
366
|
-
)])
|
|
391
|
+
.map(([key, value]) => [key, Object.fromEntries(Object.entries(value).toSorted(([a], [b]) => a.localeCompare(b)))])
|
|
367
392
|
),
|
|
368
393
|
components: {
|
|
369
|
-
schemas: Object.fromEntries(
|
|
370
|
-
Object.entries(this.#schemas)
|
|
371
|
-
.toSorted(([a], [b]) => a.localeCompare(b))
|
|
372
|
-
)
|
|
394
|
+
schemas: Object.fromEntries(Object.entries(this.#schemas).toSorted(([a], [b]) => a.localeCompare(b)))
|
|
373
395
|
}
|
|
374
396
|
};
|
|
375
397
|
}
|
|
376
|
-
}
|
|
398
|
+
}
|
package/src/service.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { createReadStream, existsSync } from 'node:fs';
|
|
2
|
+
|
|
2
3
|
import type { OpenAPIObject } from 'openapi3-ts/oas31';
|
|
3
4
|
import { stringify } from 'yaml';
|
|
4
5
|
|
|
6
|
+
import { Inject, Injectable, PostConstruct } from '@travetto/di';
|
|
5
7
|
import { ManifestFileUtil } from '@travetto/manifest';
|
|
6
8
|
import { BinaryMetadataUtil, JSONUtil } from '@travetto/runtime';
|
|
7
|
-
import { Injectable, Inject, PostConstruct } from '@travetto/di';
|
|
8
9
|
import { ControllerVisitUtil, type WebConfig } from '@travetto/web';
|
|
9
10
|
|
|
10
11
|
import type { ApiHostConfig, ApiInfoConfig, ApiSpecConfig } from './config.ts';
|
|
@@ -15,7 +16,6 @@ import { OpenapiVisitor } from './generate.ts';
|
|
|
15
16
|
*/
|
|
16
17
|
@Injectable()
|
|
17
18
|
export class OpenApiService {
|
|
18
|
-
|
|
19
19
|
@Inject()
|
|
20
20
|
apiHostConfig: ApiHostConfig;
|
|
21
21
|
|
|
@@ -60,7 +60,7 @@ export class OpenApiService {
|
|
|
60
60
|
this.#spec = {
|
|
61
61
|
...this.apiHostConfig,
|
|
62
62
|
info: { ...this.apiInfoConfig },
|
|
63
|
-
...await ControllerVisitUtil.visit(new OpenapiVisitor(this.apiSpecConfig))
|
|
63
|
+
...(await ControllerVisitUtil.visit(new OpenapiVisitor(this.apiSpecConfig)))
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
66
|
return this.#spec!;
|
|
@@ -75,9 +75,7 @@ export class OpenApiService {
|
|
|
75
75
|
|
|
76
76
|
const spec = await this.getSpec();
|
|
77
77
|
|
|
78
|
-
const output = this.apiSpecConfig.output.endsWith('.json') ?
|
|
79
|
-
JSONUtil.toUTF8Pretty(spec) :
|
|
80
|
-
stringify(spec);
|
|
78
|
+
const output = this.apiSpecConfig.output.endsWith('.json') ? JSONUtil.toUTF8Pretty(spec) : stringify(spec);
|
|
81
79
|
|
|
82
80
|
if (existsSync(this.apiSpecConfig.output)) {
|
|
83
81
|
const existing = await BinaryMetadataUtil.hash(createReadStream(this.apiSpecConfig.output));
|
|
@@ -94,4 +92,4 @@ export class OpenApiService {
|
|
|
94
92
|
console.error('Unable to persist openapi spec', error);
|
|
95
93
|
}
|
|
96
94
|
}
|
|
97
|
-
}
|
|
95
|
+
}
|
package/support/bin/help.ts
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
import fs from 'node:fs/promises';
|
|
2
1
|
import { spawn } from 'node:child_process';
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
|
|
5
|
-
import { JSONUtil, ExecUtil, Runtime } from '@travetto/runtime';
|
|
6
5
|
import { cliTpl } from '@travetto/cli';
|
|
6
|
+
import { ExecUtil, JSONUtil, Runtime } from '@travetto/runtime';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Help utility for openapi client command
|
|
10
10
|
*/
|
|
11
11
|
export class OpenApiClientHelp {
|
|
12
|
-
|
|
13
12
|
static async getListOfFormats(dockerImage: string): Promise<string[]> {
|
|
14
13
|
const formatCache = Runtime.toolPath('openapi-formats.json');
|
|
15
|
-
if (!await fs.stat(formatCache, { throwIfNoEntry: false })) {
|
|
14
|
+
if (!(await fs.stat(formatCache, { throwIfNoEntry: false }))) {
|
|
16
15
|
const { stdout } = await ExecUtil.getResult(spawn('docker', ['run', '--rm', dockerImage, 'list']));
|
|
17
16
|
const lines = stdout
|
|
18
17
|
.split('DOCUMENTATION')[0]
|
|
@@ -22,7 +21,7 @@ export class OpenApiClientHelp {
|
|
|
22
21
|
.map(line => line.replace(/^\s+-\s+/, '').trim());
|
|
23
22
|
|
|
24
23
|
await fs.mkdir(path.dirname(formatCache), { recursive: true });
|
|
25
|
-
await fs.writeFile(formatCache, JSONUtil.toUTF8([...lines.toSorted()
|
|
24
|
+
await fs.writeFile(formatCache, JSONUtil.toUTF8([...lines.toSorted()]));
|
|
26
25
|
}
|
|
27
26
|
return await fs.readFile(formatCache).then(JSONUtil.fromBinaryArray<string[]>);
|
|
28
27
|
}
|
|
@@ -40,4 +39,4 @@ export class OpenApiClientHelp {
|
|
|
40
39
|
}
|
|
41
40
|
return help;
|
|
42
41
|
}
|
|
43
|
-
}
|
|
42
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
1
|
import cp from 'node:child_process';
|
|
2
|
+
import path from 'node:path';
|
|
3
3
|
|
|
4
|
-
import { type CliCommandShape,
|
|
4
|
+
import { CliCommand, type CliCommandShape, CliFlag } from '@travetto/cli';
|
|
5
5
|
import { ExecUtil } from '@travetto/runtime';
|
|
6
6
|
|
|
7
7
|
import { OpenApiClientHelp } from './bin/help.ts';
|
|
@@ -35,25 +35,35 @@ export class OpenApiClientCommand implements CliCommandShape {
|
|
|
35
35
|
this.output = path.resolve(this.output);
|
|
36
36
|
this.input = path.resolve(this.input);
|
|
37
37
|
|
|
38
|
-
const subProcess = cp.spawn(
|
|
39
|
-
'
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
38
|
+
const subProcess = cp.spawn(
|
|
39
|
+
'docker',
|
|
40
|
+
[
|
|
41
|
+
'run',
|
|
42
|
+
'--rm',
|
|
43
|
+
'-i',
|
|
44
|
+
'-v',
|
|
45
|
+
`${this.output}:/workspace`,
|
|
46
|
+
'-v',
|
|
47
|
+
`${path.dirname(this.input)}:/input`,
|
|
48
|
+
'--user',
|
|
49
|
+
`${process.geteuid?.() ?? 0}:${process.getgid?.() ?? 0}`,
|
|
50
|
+
this.dockerImage,
|
|
51
|
+
// Parameters
|
|
52
|
+
'generate',
|
|
53
|
+
'--skip-validate-spec',
|
|
54
|
+
'--remove-operation-id-prefix',
|
|
55
|
+
'-g',
|
|
56
|
+
format,
|
|
57
|
+
'-o',
|
|
58
|
+
'/workspace',
|
|
59
|
+
'-i',
|
|
60
|
+
`/input/${path.basename(this.input)}`,
|
|
61
|
+
...(this.properties.length ? ['--additional-properties', this.properties.join(',')] : [])
|
|
62
|
+
],
|
|
63
|
+
{
|
|
64
|
+
stdio: 'inherit'
|
|
65
|
+
}
|
|
66
|
+
);
|
|
57
67
|
|
|
58
68
|
const result = await ExecUtil.getResult(subProcess);
|
|
59
69
|
|
|
@@ -61,4 +71,4 @@ export class OpenApiClientCommand implements CliCommandShape {
|
|
|
61
71
|
process.exitCode = 1;
|
|
62
72
|
}
|
|
63
73
|
}
|
|
64
|
-
}
|
|
74
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
|
|
4
|
-
import { type CliCommandShape,
|
|
5
|
-
import { JSONUtil, Env } from '@travetto/runtime';
|
|
6
|
-
import { Registry } from '@travetto/registry';
|
|
4
|
+
import { CliCommand, type CliCommandShape, CliModuleFlag } from '@travetto/cli';
|
|
7
5
|
import { DependencyRegistryIndex } from '@travetto/di';
|
|
6
|
+
import { Registry } from '@travetto/registry';
|
|
7
|
+
import { Env, JSONUtil } from '@travetto/runtime';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Generate the OpenAPI specification for the selected module.
|
|
@@ -14,7 +14,6 @@ import { DependencyRegistryIndex } from '@travetto/di';
|
|
|
14
14
|
*/
|
|
15
15
|
@CliCommand()
|
|
16
16
|
export class OpenApiSpecCommand implements CliCommandShape {
|
|
17
|
-
|
|
18
17
|
/** Output files */
|
|
19
18
|
output?: string;
|
|
20
19
|
|
|
@@ -41,4 +40,4 @@ export class OpenApiSpecCommand implements CliCommandShape {
|
|
|
41
40
|
await fs.writeFile(this.output, text, 'utf8');
|
|
42
41
|
}
|
|
43
42
|
}
|
|
44
|
-
}
|
|
43
|
+
}
|