Skip to content

Commit 181dd8a

Browse files
chrisradekChristopher Radek
and
Christopher Radek
authored
Updates tsp-openapi3 to emit main.tsp even when formatter fails (#3794)
This updates the `tsp-openapi3` CLI so that it emits `main.tsp` even when the formatter detects an issue. The CLI will still throw the error after it is done emitting the file. The `convertOpenAPI3Document` function used by the website does not throw on formatter errors - the playground will highlight any TSP errors already. Playground example with bad emission: ![image](https://github.com/microsoft/typespec/assets/14189820/cbddf049-5928-4969-b1fa-cbf98ea95bc0) --------- Co-authored-by: Christopher Radek <Christopher.Radek@microsoft.com>
1 parent 532e6ed commit 181dd8a

File tree

5 files changed

+83
-11
lines changed

5 files changed

+83
-11
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
changeKind: fix
3+
packages:
4+
- "@typespec/openapi3"
5+
---
6+
7+
Updates tsp-openapi3 to always emit main.tsp when formatting encounters an error.

packages/openapi3/src/cli/actions/convert/convert-file.ts

+17-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import oaParser from "@readme/openapi-parser";
2-
import { resolvePath } from "@typespec/compiler";
2+
import { formatTypeSpec, resolvePath } from "@typespec/compiler";
33
import { OpenAPI3Document } from "../../../types.js";
44
import { CliHost } from "../../types.js";
55
import { handleInternalCompilerError } from "../../utils.js";
@@ -14,15 +14,30 @@ export async function convertAction(host: CliHost, args: ConvertCliArgs) {
1414
const program = transform(model);
1515
let mainTsp: string;
1616
try {
17-
mainTsp = await generateMain(program);
17+
mainTsp = generateMain(program);
1818
} catch (err) {
1919
handleInternalCompilerError(err);
2020
}
2121

22+
let formatError;
23+
// attempt to format the TSP and track if it threw an error
24+
try {
25+
mainTsp = await formatTypeSpec(mainTsp, {
26+
printWidth: 100,
27+
tabWidth: 2,
28+
});
29+
} catch (err) {
30+
formatError = err;
31+
}
32+
2233
if (args["output-dir"]) {
2334
await host.mkdirp(args["output-dir"]);
2435
await host.writeFile(resolvePath(args["output-dir"], "main.tsp"), mainTsp);
2536
}
37+
38+
if (formatError) {
39+
handleInternalCompilerError(formatError);
40+
}
2641
}
2742

2843
function parseOpenApiFile(path: string): Promise<OpenAPI3Document> {
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,17 @@
1+
import { formatTypeSpec } from "@typespec/compiler";
12
import { OpenAPI3Document } from "../../../types.js";
23
import { generateMain } from "./generators/generate-main.js";
34
import { transform } from "./transforms/transforms.js";
45

56
export async function convertOpenAPI3Document(document: OpenAPI3Document) {
67
const program = transform(document);
7-
return await generateMain(program);
8+
const content = generateMain(program);
9+
try {
10+
return await formatTypeSpec(content, {
11+
printWidth: 100,
12+
tabWidth: 2,
13+
});
14+
} catch {
15+
return content;
16+
}
817
}
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
import { formatTypeSpec } from "@typespec/compiler";
21
import { TypeSpecProgram } from "../interfaces.js";
32
import { generateModel } from "./generate-model.js";
43
import { generateOperation } from "./generate-operation.js";
54
import { generateServiceInformation } from "./generate-service-info.js";
65

7-
export async function generateMain(program: TypeSpecProgram): Promise<string> {
8-
const content = `
6+
export function generateMain(program: TypeSpecProgram): string {
7+
return `
98
import "@typespec/http";
109
import "@typespec/openapi";
1110
import "@typespec/openapi3";
@@ -19,9 +18,4 @@ export async function generateMain(program: TypeSpecProgram): Promise<string> {
1918
2019
${program.operations.map(generateOperation).join("\n\n")}
2120
`;
22-
23-
return formatTypeSpec(content, {
24-
printWidth: 100,
25-
tabWidth: 2,
26-
});
2721
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { formatTypeSpec } from "@typespec/compiler";
2+
import { strictEqual } from "node:assert";
3+
import { it } from "vitest";
4+
import { convertOpenAPI3Document } from "../../src/index.js";
5+
6+
it("should convert an OpenAPI3 document to a formatted TypeSpec program", async () => {
7+
const tsp = await convertOpenAPI3Document({
8+
info: {
9+
title: "Test Service",
10+
version: "1.0.0",
11+
},
12+
openapi: "3.0.0",
13+
paths: {},
14+
components: {
15+
schemas: {
16+
Foo: {
17+
type: "string",
18+
},
19+
},
20+
},
21+
});
22+
23+
strictEqual(
24+
tsp,
25+
await formatTypeSpec(
26+
`
27+
import "@typespec/http";
28+
import "@typespec/openapi";
29+
import "@typespec/openapi3";
30+
31+
using Http;
32+
using OpenAPI;
33+
34+
@service({
35+
title: "Test Service",
36+
})
37+
@info({
38+
version: "1.0.0",
39+
})
40+
namespace TestService;
41+
42+
scalar Foo extends string;
43+
`,
44+
{ printWidth: 100, tabWidth: 2 }
45+
)
46+
);
47+
});

0 commit comments

Comments
 (0)