Skip to content

Commit 323e9a5

Browse files
authored
feat: allow CLI flags in redocly.yaml (#2646)
1 parent 889b5d5 commit 323e9a5

6 files changed

Lines changed: 64 additions & 57 deletions

File tree

.changeset/yellow-meteors-rush.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"openapi-typescript": minor
3+
---
4+
5+
Add ability to set flags in redocly.yaml

docs/cli.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ apis:
4141
root: ./openapi/external.yaml
4242
x-openapi-ts:
4343
output: ./openapi/external.ts
44+
additional-properties: true # CLI flags are also supported, either in kebab-case or camelCase format
4445
```
4546
4647
:::

packages/openapi-fetch/test/redocly.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,8 @@ apis:
5353
root: ../../openapi-typescript/examples/stripe-api.yaml
5454
x-openapi-ts:
5555
output: ./examples/schemas/stripe.d.ts
56+
read-write-visibility:
57+
root: ./read-write-visibility/schemas/read-write.yaml
58+
x-openapi-ts:
59+
output: ./read-write-visibility/schemas/read-write.d.ts
60+
read-write-markers: true

packages/openapi-typescript/bin/cli.js

Lines changed: 49 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import fs from "node:fs";
44
import path from "node:path";
55
import { performance } from "node:perf_hooks";
66
import { createConfig, findConfig, loadConfig } from "@redocly/openapi-core";
7+
import { kebabCase } from "scule";
78
import parser from "yargs-parser";
89
import openapiTS, { astToString, COMMENT_HEADER, c, error, formatTime, warn } from "../dist/index.mjs";
910

@@ -31,8 +32,8 @@ Options
3132
--path-params-as-types Convert paths to template literal types
3233
--alphabetize Sort object keys alphabetically
3334
--exclude-deprecated Exclude deprecated types
34-
--root-types (optional) Export schemas types at root level
35-
--root-types-no-schema-prefix (optional)
35+
--root-types Export schemas types at root level
36+
--root-types-no-schema-prefix
3637
Do not add "Schema" prefix to types at the root level (should only be used with --root-types)
3738
--root-types-keep-casing Keep casing of root types (should only be used with --root-types)
3839
--make-paths-enum Generate ApiPaths enum for all paths
@@ -71,32 +72,34 @@ if (args.includes("--root-types-keep-casing") && !args.includes("--root-types"))
7172
console.warn("--root-types-keep-casing has no effect without --root-types flag");
7273
}
7374

75+
const BOOLEAN_FLAGS = [
76+
"additionalProperties",
77+
"alphabetize",
78+
"arrayLength",
79+
"check",
80+
"conditionalEnums",
81+
"contentNever",
82+
"dedupeEnums",
83+
"defaultNonNullable",
84+
"emptyObjectsUnknown",
85+
"enum",
86+
"enumValues",
87+
"excludeDeprecated",
88+
"exportType",
89+
"generatePathParams",
90+
"help",
91+
"immutable",
92+
"makePathsEnum",
93+
"pathParamsAsTypes",
94+
"propertiesRequiredByDefault",
95+
"readWriteMarkers",
96+
"rootTypes",
97+
"rootTypesKeepCasing",
98+
"rootTypesNoSchemaPrefix",
99+
];
100+
74101
const flags = parser(args, {
75-
boolean: [
76-
"additionalProperties",
77-
"alphabetize",
78-
"arrayLength",
79-
"contentNever",
80-
"defaultNonNullable",
81-
"propertiesRequiredByDefault",
82-
"emptyObjectsUnknown",
83-
"enum",
84-
"enumValues",
85-
"conditionalEnums",
86-
"dedupeEnums",
87-
"check",
88-
"excludeDeprecated",
89-
"exportType",
90-
"help",
91-
"immutable",
92-
"pathParamsAsTypes",
93-
"rootTypes",
94-
"rootTypesNoSchemaPrefix",
95-
"rootTypesKeepCasing",
96-
"makePathsEnum",
97-
"generatePathParams",
98-
"readWriteMarkers",
99-
],
102+
boolean: BOOLEAN_FLAGS,
100103
string: ["output", "redocly"],
101104
alias: {
102105
redocly: ["c"],
@@ -136,36 +139,10 @@ function checkStaleOutput(current, outputPath) {
136139

137140
/**
138141
* @param {string | URL} schema
139-
* @param {@type import('@redocly/openapi-core').Config} redocly
142+
* @param {@type import('@redocly/openapi-core').Config} config
140143
*/
141-
async function generateSchema(schema, { redocly, silent = false }) {
142-
return `${COMMENT_HEADER}${astToString(
143-
await openapiTS(schema, {
144-
additionalProperties: flags.additionalProperties,
145-
alphabetize: flags.alphabetize,
146-
arrayLength: flags.arrayLength,
147-
contentNever: flags.contentNever,
148-
propertiesRequiredByDefault: flags.propertiesRequiredByDefault,
149-
defaultNonNullable: flags.defaultNonNullable,
150-
emptyObjectsUnknown: flags.emptyObjectsUnknown,
151-
enum: flags.enum,
152-
enumValues: flags.enumValues,
153-
conditionalEnums: flags.conditionalEnums,
154-
dedupeEnums: flags.dedupeEnums,
155-
excludeDeprecated: flags.excludeDeprecated,
156-
exportType: flags.exportType,
157-
immutable: flags.immutable,
158-
pathParamsAsTypes: flags.pathParamsAsTypes,
159-
rootTypes: flags.rootTypes,
160-
rootTypesNoSchemaPrefix: flags.rootTypesNoSchemaPrefix,
161-
rootTypesKeepCasing: flags.rootTypesKeepCasing,
162-
makePathsEnum: flags.makePathsEnum,
163-
generatePathParams: flags.generatePathParams,
164-
readWriteMarkers: flags.readWriteMarkers,
165-
redocly,
166-
silent,
167-
}),
168-
)}`;
144+
async function generateSchema(schema, config) {
145+
return `${COMMENT_HEADER}${astToString(await openapiTS(schema, config))}`;
169146
}
170147

171148
/** pretty-format error message but also throw */
@@ -230,6 +207,8 @@ async function main() {
230207
await Promise.all(
231208
Object.entries(redocly.apis).map(async ([name, api]) => {
232209
let configRoot = CWD;
210+
211+
const config = { ...flags, redocly };
233212
if (redocly.configFile) {
234213
// note: this will be absolute if --redoc is passed; otherwise, relative
235214
configRoot = path.isAbsolute(redocly.configFile)
@@ -241,7 +220,18 @@ async function main() {
241220
`API ${name} is missing an \`${REDOC_CONFIG_KEY}.output\` key. See https://openapi-ts.dev/cli/#multiple-schemas.`,
242221
);
243222
}
244-
const result = await generateSchema(new URL(api.root, configRoot), { redocly });
223+
224+
if (api[REDOC_CONFIG_KEY]) {
225+
for (const name of BOOLEAN_FLAGS) {
226+
if (typeof api[REDOC_CONFIG_KEY][name] === "boolean") {
227+
config[name] = api[REDOC_CONFIG_KEY][name];
228+
} else if (typeof api[REDOC_CONFIG_KEY][kebabCase(name)] === "boolean") {
229+
config[name] = api[REDOC_CONFIG_KEY][kebabCase(name)];
230+
}
231+
}
232+
}
233+
const result = await generateSchema(new URL(api.root, configRoot), config);
234+
245235
const outFile = new URL(api[REDOC_CONFIG_KEY].output, configRoot);
246236
checkStaleOutput(result, outFile);
247237
fs.mkdirSync(new URL(".", outFile), { recursive: true });
@@ -254,6 +244,7 @@ async function main() {
254244
// handle stdin
255245
else if (!input) {
256246
const result = await generateSchema(process.stdin, {
247+
...flags,
257248
redocly,
258249
silent: outputType === OUTPUT_STDOUT,
259250
});
@@ -278,6 +269,7 @@ async function main() {
278269
);
279270
}
280271
const result = await generateSchema(new URL(input, CWD), {
272+
...flags,
281273
redocly,
282274
silent: outputType === OUTPUT_STDOUT,
283275
});

packages/openapi-typescript/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
"ansi-colors": "^4.1.3",
6767
"change-case": "^5.4.4",
6868
"parse-json": "^8.3.0",
69+
"scule": "^1.3.0",
6970
"supports-color": "^10.2.2",
7071
"yargs-parser": "^21.1.1"
7172
},

pnpm-lock.yaml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)