Skip to content

Commit ec263c2

Browse files
authored
feat: Add support for flags in gen command (#27)
* Use upperCase verb in the fetcher * Add flags override
1 parent 35c06ef commit ec263c2

File tree

2 files changed

+122
-6
lines changed

2 files changed

+122
-6
lines changed

cli/src/commands/GenerateCommand.ts

Lines changed: 121 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
import { Command, Option } from "clipanion";
1+
import { Command, Option, UsageError } from "clipanion";
2+
import * as t from "typanion";
23
import fsExtra from "fs-extra";
34
import path from "path/posix";
45
import * as swc from "@swc/core";
56
import prettier from "prettier";
67
import { fileURLToPath } from "url";
78
import slash from "slash";
89

9-
import { Config, Namespace } from "../types";
10+
import { Config, FromOptions, Namespace } from "../types";
1011
import { getOpenAPISourceFile } from "../core/getOpenAPISourceFile.js";
1112
import { parseOpenAPISourceFile } from "../core/parseOpenAPISourceFile.js";
1213

@@ -23,6 +24,43 @@ export class GenerateCommand extends Command {
2324

2425
namespace = Option.String();
2526

27+
source = Option.String(`--source`, {
28+
description: "Source of the spec (file, url or github)",
29+
validator: t.isEnum(["file", "url", "github"]),
30+
});
31+
32+
// source=file options
33+
relativePath = Option.String(`--relativePath`, {
34+
description: "[source=file] Relative path of the spec file",
35+
});
36+
37+
// source=url options
38+
url = Option.String("--url", {
39+
description: "[source=url] URL of the spec file",
40+
});
41+
method = Option.String("--method", {
42+
description: "[source=url] HTTP Method",
43+
validator: t.isEnum(["get", "post"]),
44+
});
45+
46+
// source=github options
47+
owner = Option.String("--owner", {
48+
description: "[source=github] Owner of the repository",
49+
});
50+
repository = Option.String("--repository --repo", {
51+
description: "[source=github] Repository name",
52+
});
53+
branch = Option.String("-b --branch", {
54+
description: "[source=github] Branch name",
55+
});
56+
specPath = Option.String("--specPath", {
57+
description: "[source=github] OpenAPI specs file path",
58+
});
59+
pullRequest = Option.String("--pr --pull-request", {
60+
description:
61+
"[source=github] Select a specific pull-request instead of a branch",
62+
});
63+
2664
static paths = [["gen"], ["generate"], Command.Default];
2765
static usage = Command.Usage({
2866
description: "Generate types & components from an OpenAPI file",
@@ -72,17 +110,95 @@ export class GenerateCommand extends Command {
72110
}
73111
}
74112

113+
/**
114+
* Get `from` options consolidated with cli flags.
115+
*
116+
* @param config config from openapi-codegen.config.ts
117+
* @returns consolidated configuration
118+
*/
119+
getFromOptions(config: Config): FromOptions {
120+
const source = this.source || config.from.source;
121+
122+
switch (source) {
123+
case "file": {
124+
if (config.from.source === "file") {
125+
return {
126+
...config.from,
127+
relativePath: this.relativePath ?? config.from.relativePath,
128+
};
129+
} else {
130+
if (!this.relativePath) {
131+
throw new UsageError("--relativePath argument is missing");
132+
}
133+
return {
134+
source: "file",
135+
relativePath: this.relativePath,
136+
};
137+
}
138+
}
139+
140+
case "url":
141+
if (config.from.source === "url") {
142+
return {
143+
...config.from,
144+
url: this.url ?? config.from.url,
145+
method: this.method ?? config.from.method,
146+
};
147+
} else {
148+
if (!this.url) {
149+
throw new UsageError("--url argument is missing");
150+
}
151+
return {
152+
source: "url",
153+
url: this.url,
154+
method: this.method,
155+
};
156+
}
157+
158+
case "github":
159+
if (config.from.source === "github") {
160+
return {
161+
...config.from,
162+
owner: this.owner ?? config.from.owner,
163+
branch: this.branch ?? config.from.branch,
164+
repository: this.repository ?? config.from.repository,
165+
specPath: this.specPath ?? config.from.specPath,
166+
};
167+
} else {
168+
if (!this.owner) {
169+
throw new UsageError("--owner argument is missing");
170+
}
171+
if (!this.branch) {
172+
throw new UsageError("--branch argument is missing");
173+
}
174+
if (!this.repository) {
175+
throw new UsageError("--repository argument is missing");
176+
}
177+
if (!this.specPath) {
178+
throw new UsageError("--specPath argument is missing");
179+
}
180+
181+
return {
182+
source: "github",
183+
branch: this.branch,
184+
owner: this.owner,
185+
repository: this.repository,
186+
specPath: this.specPath,
187+
};
188+
}
189+
}
190+
}
191+
75192
async execute() {
76193
const configs = await this.loadConfigs();
77194
if (!(this.namespace in configs)) {
78-
this.context.stdout.write(
195+
throw new UsageError(
79196
`"${this.namespace}" is not defined in your configuration`
80197
);
81-
process.exit(1);
82198
}
83199

84200
const config = configs[this.namespace];
85-
const sourceFile = await getOpenAPISourceFile(config.from);
201+
const sourceFile = await getOpenAPISourceFile(this.getFromOptions(config));
86202
const openAPIDocument = await parseOpenAPISourceFile(sourceFile);
87203
const prettierConfig = await prettier.resolveConfig(process.cwd());
88204

plugins/typescript/src/templates/fetcher.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export async function ${camel(prefix)}Fetch<
6161
const response = await window.fetch(
6262
resolveUrl(url, queryParams, pathParams),
6363
{
64-
method,
64+
method: method.toUpperCase(),
6565
body: body ? JSON.stringify(body) : undefined,
6666
headers: {
6767
"Content-Type": "application/json",

0 commit comments

Comments
 (0)