Skip to content

Commit a18b8a6

Browse files
authored
schema input from stdin (#870)
* schema input from stdin fix: #869 * Add test * fixup! schema input from stdin
1 parent 39b40f8 commit a18b8a6

File tree

5 files changed

+530
-7
lines changed

5 files changed

+530
-7
lines changed

bin/cli.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,13 @@ async function main() {
144144
return;
145145
}
146146

147+
// handle stdin schema, exit
148+
if (pathToSpec === "-") {
149+
if (output !== "." && output === OUTPUT_FILE) fs.mkdirSync(path.dirname(flags.output), { recursive: true });
150+
await generateSchema(process.stdin);
151+
return;
152+
}
153+
147154
// handle local schema(s)
148155
const inputSpecPaths = await glob(pathToSpec, { filesOnly: true });
149156
const isGlob = inputSpecPaths.length > 1;

src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { URL } from "url";
66
import load, { resolveSchema, VIRTUAL_JSON_URL } from "./load.js";
77
import { swaggerVersion } from "./utils.js";
88
import { transformAll } from "./transform/index.js";
9+
import { Readable } from "stream";
910
export * from "./types.js"; // expose all types to consumers
1011

1112
export const WARNING_MESSAGE = `/**
@@ -30,7 +31,7 @@ export const WARNING_MESSAGE = `/**
3031
* @return {Promise<string>} {Promise<string>} Parsed file schema
3132
*/
3233
async function openapiTS(
33-
schema: string | URL | OpenAPI2 | OpenAPI3 | Record<string, SchemaObject>,
34+
schema: string | URL | OpenAPI2 | OpenAPI3 | Record<string, SchemaObject> | Readable,
3435
options: SwaggerToTSOptions = {} as Partial<SwaggerToTSOptions>
3536
): Promise<string> {
3637
const ctx: GlobalContext = {

src/load.ts

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { URL } from "url";
77
import mime from "mime";
88
import yaml from "js-yaml";
99
import { parseRef } from "./utils.js";
10+
import { Readable } from "stream";
1011

1112
const request = undici.request;
1213

@@ -97,13 +98,13 @@ interface LoadOptions extends GlobalContext {
9798

9899
/** Load a schema from local path or remote URL */
99100
export default async function load(
100-
schema: URL | PartialSchema,
101+
schema: URL | PartialSchema | Readable,
101102
options: LoadOptions
102103
): Promise<{ [url: string]: PartialSchema }> {
103104
const urlCache = options.urlCache || new Set<string>();
104105

105-
const isJSON = schema instanceof URL === false; // if this is dynamically-passed-in JSON, we’ll have to change a few things
106-
let schemaID = isJSON ? new URL(VIRTUAL_JSON_URL).href : (schema.href as string);
106+
const isJSON = schema instanceof URL === false && !(schema instanceof Readable); // if this is dynamically-passed-in JSON, we’ll have to change a few things
107+
let schemaID = isJSON || schema instanceof Readable ? new URL(VIRTUAL_JSON_URL).href : (schema.href as string);
107108

108109
const schemas = options.schemas;
109110

@@ -118,9 +119,25 @@ export default async function load(
118119

119120
let contents = "";
120121
let contentType = "";
121-
const schemaURL = schema as URL; // helps TypeScript
122-
123-
if (isFile(schemaURL)) {
122+
const schemaURL = schema instanceof Readable ? new URL(VIRTUAL_JSON_URL) : (schema as URL); // helps TypeScript
123+
124+
if (schema instanceof Readable) {
125+
const readable = schema;
126+
contents = await new Promise<string>((resolve) => {
127+
readable.resume();
128+
readable.setEncoding("utf8");
129+
130+
let content = "";
131+
readable.on("data", (chunk: string) => {
132+
content += chunk;
133+
});
134+
135+
readable.on("end", () => {
136+
resolve(content);
137+
});
138+
});
139+
contentType = "text/yaml";
140+
} else if (isFile(schemaURL)) {
124141
// load local
125142
contents = fs.readFileSync(schemaURL, "utf8");
126143
contentType = mime.getType(schemaID) || "";

test/bin/cli.test.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,15 @@ describe("cli", () => {
3434
expect(generated.toString("utf8")).to.equal(expected);
3535
});
3636

37+
it("stdin", async () => {
38+
execSync(`${cmd} - -o generated/stdin.ts < ./specs/petstore.yaml`, {
39+
cwd,
40+
});
41+
const generated = fs.readFileSync(new URL("./generated/stdin.ts", cwd), "utf8");
42+
const expected = eol.lf(fs.readFileSync(new URL("./expected/stdin.ts", cwd), "utf8"));
43+
expect(generated).to.equal(expected);
44+
});
45+
3746
it("supports glob paths", async () => {
3847
execSync(`${cmd} "specs/*.yaml" -o generated/`, { cwd }); // Quotes are necessary because shells like zsh treats glob weirdly
3948
const generatedPetstore = fs.readFileSync(new URL("./generated/specs/petstore.ts", cwd), "utf8");

0 commit comments

Comments
 (0)