Skip to content

Commit 4456647

Browse files
committed
Remove some unit tests; add CLI test for new flags
1 parent 1b13ccf commit 4456647

File tree

11 files changed

+74
-377
lines changed

11 files changed

+74
-377
lines changed

README.md

+12-12
Original file line numberDiff line numberDiff line change
@@ -98,18 +98,18 @@ npx openapi-typescript schema.yaml
9898

9999
#### CLI Options
100100

101-
| Option | Alias | Default | Description |
102-
| :----------------------------- | :---- | :------: | :------------------------------------------------------------------------------------------------------ |
103-
| `--output [location]` | `-o` | (stdout) | Where should the output file be saved? |
104-
| `--auth [token]` | | | (optional) Provide an auth token to be passed along in the request (only if accessing a private schema) |
105-
| `--immutable-types` | `-it` | `false` | (optional) Generates immutable types (readonly properties and readonly array) |
106-
| `--additional-properties` | `-ap` | `false` | (optional) Allow arbitrary properties for all schema objects without `additionalProperties: false` |
107-
| `--default-non-nullable` | | `false` | (optional) Treat schema objects with default values as non-nullable |
108-
| `--prettier-config [location]` | `-c` | | (optional) Path to your custom Prettier configuration for output |
109-
| `--raw-schema` | | `false` | Generate TS types from partial schema (e.g. having `components.schema` at the top level) |
110-
| `--httpMethod` | `-m` | `GET` | (optional) Provide the HTTP Verb/Method for fetching a schema from a remote URL |
111-
| `--headersObject` | `-h` | | (optional) Provide a JSON object as string of HTTP headers for remote schema request. This will take **prescedence** if the singular headers flag is specified as well. |
112-
| `--header` | `-x` | | (optional) Provide an array of or singular headers as an alternative to a JSON object. Each header must follow the `key: value` pattern |
101+
| Option | Alias | Default | Description |
102+
| :----------------------------- | :---- | :------: | :-------------------------------------------------------------------------------------------------------------------------------------- |
103+
| `--output [location]` | `-o` | (stdout) | Where should the output file be saved? |
104+
| `--auth [token]` | | | (optional) Provide an auth token to be passed along in the request (only if accessing a private schema) |
105+
| `--immutable-types` | `-it` | `false` | (optional) Generates immutable types (readonly properties and readonly array) |
106+
| `--additional-properties` | `-ap` | `false` | (optional) Allow arbitrary properties for all schema objects without `additionalProperties: false` |
107+
| `--default-non-nullable` | | `false` | (optional) Treat schema objects with default values as non-nullable |
108+
| `--prettier-config [location]` | `-c` | | (optional) Path to your custom Prettier configuration for output |
109+
| `--raw-schema` | | `false` | Generate TS types from partial schema (e.g. having `components.schema` at the top level) |
110+
| `--httpMethod` | `-m` | `GET` | (optional) Provide the HTTP Verb/Method for fetching a schema from a remote URL |
111+
| `--headersObject` | `-h` | | (optional) Provide a JSON object as string of HTTP headers for remote schema request. This will take priority over `--header` |
112+
| `--header` | `-x` | | (optional) Provide an array of or singular headers as an alternative to a JSON object. Each header must follow the `key: value` pattern |
113113

114114
### 🐢 Node
115115

bin/cli.js

+14-11
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ const meow = require("meow");
66
const path = require("path");
77
const glob = require("tiny-glob");
88
const { default: openapiTS } = require("../dist/cjs/index.js");
9-
const { getCLISchemaHeadersJSON, getCLIHeadersFromArray } = require("./utils");
109

1110
const cli = meow(
1211
`Usage
@@ -88,15 +87,19 @@ async function generateSchema(pathToSpec) {
8887
const output = cli.flags.output ? OUTPUT_FILE : OUTPUT_STDOUT; // FILE or STDOUT
8988

9089
// Parse incoming headers from CLI flags
91-
// If both header flags are present, default to JSON.
92-
// Otherwise, we can use the preferred header parsing function.
93-
let finalHttpHeaders = {};
94-
if (cli.flags.header && cli.flags.headersObject) {
95-
finalHttpHeaders = getCLISchemaHeadersJSON(cli.flags.headersObject);
96-
} else if (cli.flags.headersObject) {
97-
finalHttpHeaders = getCLISchemaHeadersJSON(cli.flags.headersObject);
98-
} else if (cli.flags.header) {
99-
finalHttpHeaders = getCLIHeadersFromArray(cli.flags.header);
90+
let httpHeaders = {};
91+
// prefer --headersObject if specified
92+
if (cli.flags.headersObject) {
93+
httpHeaders = JSON.parse(cli.flags.headersObject); // note: this will generate a recognizable error for the user to act on
94+
}
95+
// otherwise, parse --header
96+
else if (Array.isArray(cli.flags.header)) {
97+
cli.flags.header.forEach((header) => {
98+
const firstColon = header.indexOf(":");
99+
const k = header.substring(0, firstColon).trim();
100+
const v = header.substring(firstColon + 1).trim();
101+
httpHeaders[k] = v;
102+
});
100103
}
101104

102105
// generate schema
@@ -109,7 +112,7 @@ async function generateSchema(pathToSpec) {
109112
rawSchema: cli.flags.rawSchema,
110113
silent: output === OUTPUT_STDOUT,
111114
version: cli.flags.version,
112-
httpHeaders: finalHttpHeaders,
115+
httpHeaders,
113116
httpMethod: cli.flags.httpMethod,
114117
});
115118

bin/utils.js

-70
This file was deleted.

package-lock.json

+3-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
"tiny-glob": "^0.2.9"
7070
},
7171
"devDependencies": {
72-
"@types/jest": "^27.0.0",
72+
"@types/jest": "^27.0.2",
7373
"@types/js-yaml": "^4.0.1",
7474
"@types/mime": "^2.0.3",
7575
"@types/node-fetch": "^2.5.12",

src/load.ts

+14-37
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ import slash from "slash";
66
import mime from "mime";
77
import yaml from "js-yaml";
88
import { red } from "kleur";
9-
import { GlobalContext, HTTPHeaderMap, HTTPVerb, PrimitiveValue } from "./types";
9+
import { GlobalContext, Headers } from "./types";
1010
import { parseRef } from "./utils";
1111

1212
type PartialSchema = Record<string, any>; // not a very accurate type, but this is easier to deal with before we know we’re dealing with a valid spec
1313
type SchemaMap = { [url: string]: PartialSchema };
1414

1515
export const VIRTUAL_JSON_URL = `file:///_json`; // fake URL reserved for dynamic JSON
1616

17-
export function parseSchema(schema: any, type: "YAML" | "JSON") {
17+
function parseSchema(schema: any, type: "YAML" | "JSON") {
1818
if (type === "YAML") {
1919
try {
2020
return yaml.load(schema);
@@ -30,7 +30,7 @@ export function parseSchema(schema: any, type: "YAML" | "JSON") {
3030
}
3131
}
3232

33-
export function isFile(url: URL): boolean {
33+
function isFile(url: URL): boolean {
3434
return url.protocol === "file:";
3535
}
3636

@@ -61,58 +61,35 @@ export function resolveSchema(url: string): URL {
6161
* @param {HTTPHeaderMap} httpHeaders
6262
* @return {Record<string, string>} {Record<string, string>} Final HTTP headers outcome.
6363
*/
64-
export function parseHttpHeaders<THeader = any>(httpHeaders: HTTPHeaderMap<THeader>): Record<string, string> {
64+
function parseHttpHeaders(httpHeaders: Record<string, any>): Headers {
6565
const finalHeaders: Record<string, string> = {};
6666

67-
// Ensure HTTP Headers are defined
68-
if (httpHeaders == null) {
69-
return finalHeaders;
70-
}
71-
72-
// Check to early return if the HTTP Headers are not in the proper shape
73-
if (typeof httpHeaders !== "object") {
74-
return finalHeaders;
75-
}
76-
77-
// Check whether the passed headers are a map or JSON object data structure
78-
const isHeaderMap = httpHeaders instanceof Headers;
79-
const isStandardMap = httpHeaders instanceof Map;
80-
const isMap = isHeaderMap || isStandardMap;
81-
const headerKeys = isMap ? Array.from((httpHeaders as Headers).keys()) : Object.keys(httpHeaders);
82-
8367
// Obtain the header key
84-
headerKeys.forEach((headerKey) => {
85-
let headerVal: PrimitiveValue = "";
86-
if (isMap) {
87-
headerVal = (httpHeaders as Headers).get(headerKey);
88-
} else {
89-
headerVal = (httpHeaders as Record<string, PrimitiveValue>)[headerKey as string];
90-
}
91-
68+
for (const [k, v] of Object.entries(httpHeaders)) {
9269
// If the value of the header is already a string, we can move on, otherwise we have to parse it
93-
if (typeof headerVal === "string") {
94-
finalHeaders[headerKey] = headerVal;
70+
if (typeof v === "string") {
71+
finalHeaders[k] = v;
9572
} else {
9673
try {
97-
const stringVal = JSON.stringify(headerVal);
98-
finalHeaders[headerKey] = stringVal;
74+
const stringVal = JSON.stringify(v);
75+
finalHeaders[k] = stringVal;
9976
} catch (err) {
10077
/* istanbul ignore next */
10178
console.error(
102-
red(`Cannot parse key: ${headerKey} into JSON format. Continuing with the next HTTP header that is specified`)
79+
red(`Cannot parse key: ${k} into JSON format. Continuing with the next HTTP header that is specified`)
10380
);
10481
}
10582
}
106-
});
83+
}
10784

10885
return finalHeaders;
10986
}
11087

11188
interface LoadOptions extends GlobalContext {
11289
rootURL: URL;
11390
schemas: SchemaMap;
114-
httpHeaders?: HTTPHeaderMap;
115-
httpMethod?: HTTPVerb;
91+
httpHeaders?: Headers;
92+
httpMethod?: string;
11693
}
11794

11895
// temporary cache for load()
@@ -147,7 +124,7 @@ export default async function load(
147124
contentType = mime.getType(schemaID) || "";
148125
} else {
149126
// load remote
150-
const headers: HeadersInit = {
127+
const headers: Headers = {
151128
"User-Agent": "openapi-typescript",
152129
};
153130
if (options.auth) headers.Authorizaton = options.auth;

src/types.ts

+4-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import type { URL } from "url";
2-
import type { Headers } from "node-fetch";
32

43
export interface OpenAPI2 {
54
swagger: string; // required
@@ -22,6 +21,8 @@ export interface OpenAPI3 {
2221
};
2322
}
2423

24+
export type Headers = Record<string, string>;
25+
2526
export interface HeaderObject {
2627
// note: this extends ParameterObject, minus "name" & "in"
2728
type?: string; // required
@@ -114,13 +115,6 @@ export interface SchemaObject {
114115

115116
export type SchemaFormatter = (schemaObj: SchemaObject) => string | undefined;
116117

117-
export type PrimitiveValue = string | number | boolean | bigint | null | undefined | symbol;
118-
119-
export type HTTPHeaderMap<T = any> = T extends string
120-
? Headers | Map<string, PrimitiveValue> | Record<string, PrimitiveValue>
121-
: null;
122-
123-
export type HTTPVerb = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "OPTIONS";
124118
export interface SwaggerToTSOptions<T = any> {
125119
/** Allow arbitrary properties on schemas (default: false) */
126120
additionalProperties?: boolean;
@@ -148,17 +142,15 @@ export interface SwaggerToTSOptions<T = any> {
148142
* or Accept: text/yaml to be sent in order to figure out how to properly fetch the OpenAPI/Swagger document as code.
149143
* These headers will only be sent in the case that the schema URL protocol is of type http or https.
150144
*/
151-
httpHeaders?: HTTPHeaderMap<T>;
145+
httpHeaders?: Headers;
152146
/**
153147
* HTTP verb used to fetch the schema from a remote server. This is only applied
154148
* when the schema is a string and has the http or https protocol present. By default,
155149
* the request will use the HTTP GET method to fetch the schema from the server.
156150
*
157-
* @type {HTTPVerb}
158-
* @memberof SwaggerToTSOptions
159151
* @default {string} GET
160152
*/
161-
httpMethod?: HTTPVerb;
153+
httpMethod?: string;
162154
}
163155

164156
/** Context passed to all submodules */

src/utils.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import { METHODS as HTTPMethods } from "http";
2-
3-
import { HTTPVerb, OpenAPI2, OpenAPI3, ReferenceObject } from "./types";
1+
import { OpenAPI2, OpenAPI3, ReferenceObject } from "./types";
42

53
export function comment(text: string): string {
64
const commentText = text.trim().replace(/\*\//g, "*\\/");

0 commit comments

Comments
 (0)