Skip to content

Commit 5cefe35

Browse files
authored
Update Prettier, linting deps (openapi-ts#1283)
* Update Prettier, linting deps * Update Contributing docs
1 parent e2ffc74 commit 5cefe35

25 files changed

+766
-636
lines changed

.eslintrc.cjs

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ module.exports = {
99
rules: {
1010
"@typescript-eslint/consistent-indexed-object-style": "off", // sometimes naming keys is more user-friendly
1111
"@typescript-eslint/no-dynamic-delete": "off", // delete is OK
12+
"@typescript-eslint/no-non-null-assertion": "off", // this is better than "as"
1213
"@typescript-eslint/no-unnecessary-condition": "off", // this gives bad advice
1314
"no-console": "error",
1415
"no-unused-vars": "off",
@@ -19,6 +20,7 @@ module.exports = {
1920
rules: {
2021
"@typescript-eslint/ban-ts-comment": "off", // allow @ts-ignore only in tests
2122
"@typescript-eslint/no-empty-function": "off", // don’t enforce this in tests
23+
"@typescript-eslint/no-explicit-any": "off", // tests sometimes need this
2224
"no-only-tests/no-only-tests": "error",
2325
"vitest/valid-title": "off", // doesn’t work?
2426
},

docs/CONTRIBUTING.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ See the [README](./README.md) for basic setup.
66

77
## Corrections / small edits
88

9-
Corrections are always welcome! Please go straight to [opening a PR](https://github.com/drwpow/openapi-typescript/pulls) for correcting typos or misinformation language. Small edits are also welcome, which include shortening verbose language or clarifying confusing wording.
9+
Corrections are always welcome! Please go straight to [opening a PR](https://github.com/drwpow/openapi-typescript/pulls) for correcting typos or misinformation. Small grammar edits are also welcome such as shortening verbose language or clarifying confusing statements.
1010

1111
## Styling fixes
1212

package.json

+7-7
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,16 @@
2222
"devDependencies": {
2323
"@changesets/changelog-github": "^0.4.8",
2424
"@changesets/cli": "^2.26.2",
25-
"@typescript-eslint/eslint-plugin": "^5.61.0",
26-
"@typescript-eslint/parser": "^5.61.0",
25+
"@typescript-eslint/eslint-plugin": "^6.3.0",
26+
"@typescript-eslint/parser": "^6.3.0",
2727
"del-cli": "^5.0.0",
28-
"eslint": "^8.44.0",
29-
"eslint-config-prettier": "^8.8.0",
28+
"eslint": "^8.46.0",
29+
"eslint-config-prettier": "^9.0.0",
3030
"eslint-plugin-no-only-tests": "^3.1.0",
31-
"eslint-plugin-prettier": "^4.2.1",
32-
"eslint-plugin-vitest": "^0.2.6",
31+
"eslint-plugin-prettier": "^5.0.0",
32+
"eslint-plugin-vitest": "^0.2.8",
3333
"npm-run-all": "^4.1.5",
34-
"prettier": "^2.8.8",
34+
"prettier": "^3.0.1",
3535
"typescript": "^5.1.6"
3636
}
3737
}

packages/openapi-fetch/CONTRIBUTING.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Thanks for being willing to contribute! 🙏
66

77
## Open issues
88

9-
Please check out the [the open issues](https://github.com/drwpow/openapi-fetch/issues). Issues labelled [**Help Wanted**](https://github.com/drwpow/openapi-fetch/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) and [**Good First Issue**](https://github.com/drwpow/openapi-fetch/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) are especially good to help with.
9+
Please check out the [the open issues](https://github.com/drwpow/openapi-typescript/issues). Issues labelled [**Good First Issue**](https://github.com/drwpow/openapi-typescript/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)are especially good to start with.
1010

1111
Contributing doesn’t have to be in code! Simply answering questions in open issues, or providing workarounds, is just as important a contribution as making pull requests.
1212

@@ -26,7 +26,7 @@ However, if adding a feature or breaking change, please **open an issue first to
2626

2727
Create a new branch for your PR with `git checkout -b your-branch-name`. Add the relevant code as well as docs and tests. When you push everything up (`git push`), navigate back to your repo GitHub and you should see a prompt to open a new PR.
2828

29-
While best practices for commit messages are encouraged (e.g. start with an imperative verb, keep it short, use the body if needed), this repo doesn’t follow any specific guidelines like [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/). Clarity is favored over strict rules. Changelogs are generated separately from git (see [the Changelogs section](#changelogs)
29+
While best practices for commit messages are encouraged (e.g. start with an imperative verb, keep it short, use the body if needed), this repo doesn’t follow any specific guidelines. Clarity is favored over strict rules. Changelogs are generated separately from git (see [the Changelogs section](#changelogs))
3030

3131
### Writing the PR
3232

packages/openapi-fetch/package.json

+2-3
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,9 @@
5959
},
6060
"devDependencies": {
6161
"del-cli": "^5.0.0",
62-
"esbuild": "^0.18.17",
62+
"esbuild": "^0.19.0",
6363
"nanostores": "^0.9.3",
64-
"openapi-typescript": "*",
65-
"prettier": "^2.8.8",
64+
"openapi-typescript": "^6.4.2",
6665
"typescript": "^5.1.6",
6766
"vitest": "^0.33.0",
6867
"vitest-fetch-mock": "^0.2.2"

packages/openapi-fetch/src/index.test.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ describe("client", () => {
318318
new Headers({
319319
...headers, // assert new header got passed
320320
"Content-Type": "application/json", // probably doesn’t need to get tested, but this was simpler than writing lots of code to ignore these
321-
})
321+
}),
322322
);
323323
});
324324

@@ -333,7 +333,7 @@ describe("client", () => {
333333
new Headers({
334334
"Cache-Control": "no-cache",
335335
"Content-Type": "application/json",
336-
})
336+
}),
337337
);
338338
});
339339

@@ -372,7 +372,7 @@ describe("client", () => {
372372
it("multipart/form-data", async () => {
373373
const client = createClient<paths>();
374374
mockFetchOnce({ status: 200, body: "{}" });
375-
const { data } = await client.PUT("/contact", {
375+
await client.PUT("/contact", {
376376
body: {
377377
name: "John Doe",
378378
@@ -445,6 +445,7 @@ describe("client", () => {
445445
const client = createClient<paths>();
446446
mockFetchOnce({ status: 200, body: "{}" });
447447
const { data } = await client.GET("/anyMethod", { parseAs: "blob" });
448+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
448449
expect((data as any).constructor.name).toBe("Blob");
449450
});
450451

@@ -681,7 +682,7 @@ describe("examples", () => {
681682
setTimeout(() => {
682683
token.set(tokenVal); // simulate promise-like token setting
683684
resolve();
684-
}, 0)
685+
}, 0),
685686
);
686687
await client.get().GET("/blogposts/{post_id}", { params: { path: { post_id: "1234" } } });
687688
expect(fetchMocker.mock.calls[1][1].headers.get("authorization")).toBe(`Bearer ${tokenVal}`);
@@ -710,7 +711,7 @@ describe("examples", () => {
710711
setTimeout(() => {
711712
token = tokenVal; // simulate promise-like token setting
712713
resolve();
713-
}, 0)
714+
}, 0),
714715
);
715716
await client.GET("/blogposts/{post_id}", { params: { path: { post_id: "1234" } } });
716717
expect(fetchMocker.mock.calls[1][1].headers.get("authorization")).toBe(`Bearer ${tokenVal}`);

packages/openapi-fetch/src/index.ts

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ const DEFAULT_HEADERS = {
44
};
55
const TRAILING_SLASH_RE = /\/*$/;
66

7+
// Note: though "any" is considered bad practice in general, this library relies
8+
// on "any" for type inference only it can give. Same goes for the "{}" type.
9+
/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types */
10+
711
/** options for each client instance */
812
interface ClientOptions extends RequestInit {
913
/** set the common root URL for all API requests */

packages/openapi-typescript/CONTRIBUTING.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Thanks for being willing to contribute! 🙏
66

77
## Open issues
88

9-
Please check out the [the open issues](https://github.com/drwpow/openapi-typescript/issues). Issues labelled [**Help Wanted**](https://github.com/drwpow/openapi-typescript/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) and [**Good First Issue**](https://github.com/drwpow/openapi-typescript/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) are especially good to help with.
9+
Please check out the [the open issues](https://github.com/drwpow/openapi-typescript/issues). Issues labelled [**Good First Issue**](https://github.com/drwpow/openapi-typescript/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)are especially good to start with.
1010

1111
Contributing doesn’t have to be in code! Simply answering questions in open issues, or providing workarounds, is just as important a contribution as making pull requests.
1212

@@ -26,7 +26,7 @@ However, if adding a feature or breaking change, please **open an issue first to
2626

2727
Create a new branch for your PR with `git checkout -b your-branch-name`. Add the relevant code as well as docs and tests. When you push everything up (`git push`), navigate back to your repo GitHub and you should see a prompt to open a new PR.
2828

29-
While best practices for commit messages are encouraged (e.g. start with an imperative verb, keep it short, use the body if needed), this repo doesn’t follow any specific guidelines like [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/). Clarity is favored over strict rules. Changelogs are generated separately from git (see [the Changelogs section](#changelogs)
29+
While best practices for commit messages are encouraged (e.g. start with an imperative verb, keep it short, use the body if needed), this repo doesn’t follow any specific guidelines. Clarity is favored over strict rules. Changelogs are generated separately from git (see [the Changelogs section](#changelogs))
3030

3131
When working locally, run:
3232

packages/openapi-typescript/package.json

+5-5
Original file line numberDiff line numberDiff line change
@@ -59,21 +59,21 @@
5959
},
6060
"dependencies": {
6161
"ansi-colors": "^4.1.3",
62-
"fast-glob": "^3.3.0",
62+
"fast-glob": "^3.3.1",
6363
"js-yaml": "^4.1.0",
6464
"supports-color": "^9.4.0",
65-
"undici": "^5.22.1",
65+
"undici": "^5.23.0",
6666
"yargs-parser": "^21.1.1"
6767
},
6868
"devDependencies": {
6969
"@types/degit": "^2.8.3",
7070
"@types/js-yaml": "^4.0.5",
71-
"@types/node": "^20.4.0",
71+
"@types/node": "^20.4.9",
7272
"degit": "^2.8.4",
7373
"del-cli": "^5.0.0",
74-
"esbuild": "^0.18.17",
74+
"esbuild": "^0.19.0",
7575
"execa": "^6.1.0",
76-
"vite": "^4.4.1",
76+
"vite": "^4.4.9",
7777
"vite-node": "^0.33.0",
7878
"vitest": "^0.33.0"
7979
}

packages/openapi-typescript/src/index.ts

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { GlobalContext, OpenAPI3, OpenAPITSOptions, Subschema } from "./types.js";
1+
import type { GlobalContext, OpenAPI3, OpenAPITSOptions, SchemaObject, Subschema } from "./types.js";
22
import type { Readable } from "node:stream";
33
import { URL } from "node:url";
44
import load, { resolveSchema, VIRTUAL_JSON_URL } from "./load.js";
@@ -75,6 +75,7 @@ async function openapiTS(schema: string | URL | OpenAPI3 | Readable, options: Op
7575
// 1. basic validation
7676
for (const k of Object.keys(allSchemas)) {
7777
const subschema = allSchemas[k];
78+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
7879
if (typeof (subschema.schema as any).swagger === "string") {
7980
error("Swagger 2.0 and older no longer supported. Please use v5.");
8081
process.exit(1);
@@ -156,7 +157,7 @@ async function openapiTS(schema: string | URL | OpenAPI3 | Readable, options: Op
156157
// hack: sometimes subschemas contain only a single SchemaObject or ParameterObject and get incorrectly hinted
157158
// currently unknown what the real fix is, but this is a bandaid
158159
if (typeof subschema.schema === "object" && ("schema" in subschema.schema || "type" in subschema.schema)) {
159-
subschemaOutput = transformSchemaObject(subschema.schema as any, { path, ctx: { ...ctx, indentLv } });
160+
subschemaOutput = transformSchemaObject(subschema.schema as SchemaObject, { path, ctx: { ...ctx, indentLv } });
160161
} else {
161162
subschemaOutput += "{\n";
162163
indentLv++;
@@ -181,14 +182,14 @@ async function openapiTS(schema: string | URL | OpenAPI3 | Readable, options: Op
181182

182183
outer: for (const [name, schemaObject] of getEntries(subschema.schema!)) {
183184
if (!schemaObject || typeof schemaObject !== "object") continue;
184-
const c = getSchemaObjectComment(schemaObject as any, indentLv);
185+
const c = getSchemaObjectComment(schemaObject as SchemaObject, indentLv);
185186
if (c) subschemaOutput += indent(c, indentLv);
186187

187188
// This might be a Path Item Object; only way to test is if top-level contains a method (not allowed on Schema Object)
188189
if (!("type" in schemaObject) && !("$ref" in schemaObject)) {
189190
for (const method of ["get", "put", "post", "delete", "options", "head", "patch", "trace"] as Method[]) {
190191
if (method in schemaObject) {
191-
subschemaOutput += indent(`${escObjKey(name)}: ${transformPathItemObject(schemaObject as any, { path: `${path}${name}`, ctx: { ...ctx, indentLv } })};\n`, indentLv);
192+
subschemaOutput += indent(`${escObjKey(name)}: ${transformPathItemObject(schemaObject, { path: `${path}${name}`, ctx: { ...ctx, indentLv } })};\n`, indentLv);
192193
continue outer;
193194
}
194195
}
@@ -207,7 +208,7 @@ async function openapiTS(schema: string | URL | OpenAPI3 | Readable, options: Op
207208
break;
208209
}
209210
default: {
210-
error(`Could not resolve subschema ${subschemaID}. Unknown type "${(subschema as any).hint}".`);
211+
error(`Could not resolve subschema ${subschemaID}. Unknown type "${subschema.hint}".`);
211212
process.exit(1);
212213
}
213214
}
@@ -244,7 +245,7 @@ async function openapiTS(schema: string | URL | OpenAPI3 | Readable, options: Op
244245
"type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };",
245246
"type XOR<T, U> = (T | U) extends object ? (Without<T, U> & U) | (Without<U, T> & T) : T | U;",
246247
"type OneOf<T extends any[]> = T extends [infer Only] ? Only : T extends [infer A, infer B, ...infer Rest] ? OneOf<[XOR<A, B>, ...Rest]> : never;",
247-
""
248+
"",
248249
);
249250
}
250251

packages/openapi-typescript/src/load.ts

+17-17
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,20 @@ interface SchemaMap {
1414
const EXT_RE = /\.(yaml|yml|json)$/i;
1515
export const VIRTUAL_JSON_URL = `file:///_json`; // fake URL reserved for dynamic JSON
1616

17-
function parseYAML(schema: any): any {
17+
function parseYAML(schema: string) {
1818
try {
1919
return yaml.load(schema);
20-
} catch (err: any) {
21-
error(`YAML: ${err.toString()}`);
20+
} catch (err) {
21+
error(`YAML: ${String(err)}`);
2222
process.exit(1);
2323
}
2424
}
2525

26-
function parseJSON(schema: any): any {
26+
function parseJSON(schema: string) {
2727
try {
2828
return JSON.parse(schema);
29-
} catch (err: any) {
30-
error(`JSON: ${err.toString()}`);
29+
} catch (err) {
30+
error(`JSON: ${String(err)}`);
3131
process.exit(1);
3232
}
3333
}
@@ -56,7 +56,7 @@ export function resolveSchema(filename: string): URL {
5656
* @param {HTTPHeaderMap} httpHeaders
5757
* @return {Record<string, string>} {Record<string, string>} Final HTTP headers outcome.
5858
*/
59-
function parseHttpHeaders(httpHeaders: Record<string, any>): Record<string, any> {
59+
function parseHttpHeaders(httpHeaders: Record<string, unknown>): Record<string, unknown> {
6060
const finalHeaders: Record<string, string> = {};
6161

6262
// Obtain the header key
@@ -84,7 +84,7 @@ export interface LoadOptions extends GlobalContext {
8484
rootURL: URL;
8585
schemas: SchemaMap;
8686
urlCache: Set<string>;
87-
httpHeaders?: Record<string, any>;
87+
httpHeaders?: Record<string, unknown>;
8888
httpMethod?: string;
8989
fetch: Fetch;
9090
parameters: Record<string, ParameterObject>;
@@ -108,14 +108,14 @@ export default async function load(schema: URL | Subschema | Readable, options:
108108

109109
// remote
110110
if (schema.protocol.startsWith("http")) {
111-
const headers: Record<string, any> = { "User-Agent": "openapi-typescript" };
111+
const headers: Record<string, string> = { "User-Agent": "openapi-typescript" };
112112
if (options.auth) headers.Authorization = options.auth;
113113

114114
// Add custom parsed HTTP headers
115115
if (options.httpHeaders) {
116116
const parsedHeaders = parseHttpHeaders(options.httpHeaders);
117117
for (const [k, v] of Object.entries(parsedHeaders)) {
118-
headers[k] = v;
118+
headers[k] = v as string;
119119
}
120120
}
121121
const res = await options.fetch(schema, {
@@ -131,7 +131,7 @@ export default async function load(schema: URL | Subschema | Readable, options:
131131
} else if (ext === ".yaml" || ext === ".yml" || contentType?.includes("yaml")) {
132132
options.schemas[schemaID] = {
133133
hint,
134-
schema: parseYAML(await res.text()),
134+
schema: parseYAML(await res.text()) as any, // eslint-disable-line @typescript-eslint/no-explicit-any
135135
};
136136
}
137137
}
@@ -141,7 +141,7 @@ export default async function load(schema: URL | Subschema | Readable, options:
141141
if (ext === ".yaml" || ext === ".yml")
142142
options.schemas[schemaID] = {
143143
hint,
144-
schema: parseYAML(contents),
144+
schema: parseYAML(contents) as any, // eslint-disable-line @typescript-eslint/no-explicit-any
145145
};
146146
else if (ext === ".json")
147147
options.schemas[schemaID] = {
@@ -191,12 +191,12 @@ export default async function load(schema: URL | Subschema | Readable, options:
191191
if ("components" in currentSchema && currentSchema.components && "examples" in currentSchema.components) delete currentSchema.components.examples;
192192
}
193193

194-
const refPromises: Promise<any>[] = [];
194+
const refPromises: Promise<unknown>[] = [];
195195
walk(currentSchema, (rawNode, nodePath) => {
196196
// filter custom properties from allOf, anyOf, oneOf
197197
for (const k of ["allOf", "anyOf", "oneOf"]) {
198198
if (Array.isArray(rawNode[k])) {
199-
rawNode[k] = (rawNode as any)[k].filter((o: SchemaObject | ReferenceObject) => {
199+
rawNode[k] = (rawNode as Record<string, SchemaObject[]>)[k].filter((o: SchemaObject | ReferenceObject) => {
200200
if (!o || typeof o !== "object" || Array.isArray(o)) throw new Error(`${nodePath}.${k}: Expected array of objects. Is your schema valid?`);
201201
if (!("$ref" in o) || typeof o.$ref !== "string") return true;
202202
const ref = parseRef(o.$ref);
@@ -214,7 +214,7 @@ export default async function load(schema: URL | Subschema | Readable, options:
214214
}
215215
// $ref with custom "x-*" property
216216
if (ref.path.some((i) => i.startsWith("x-"))) {
217-
delete (node as any).$ref;
217+
delete (node as unknown as Record<string, unknown>).$ref;
218218
return;
219219
}
220220

@@ -255,7 +255,7 @@ export default async function load(schema: URL | Subschema | Readable, options:
255255
// 3. transform $refs once, at the root schema, after all have been scanned & downloaded (much easier to do here when we have the context)
256256
if (schemaID === ".") {
257257
for (const subschemaID of Object.keys(options.schemas)) {
258-
walk(options.schemas[subschemaID].schema, (rawNode, nodePath) => {
258+
walk(options.schemas[subschemaID].schema, (rawNode) => {
259259
if (!("$ref" in rawNode) || typeof rawNode.$ref !== "string") return;
260260

261261
const node = rawNode as unknown as ReferenceObject;
@@ -285,7 +285,7 @@ export default async function load(schema: URL | Subschema | Readable, options:
285285
// note: 'in' is a unique required property of parameters. and parameters can live in subschemas (i.e. "parameters" doesn’t have to be part of the traceable path)
286286
if (typeof rawNode === "object" && "in" in rawNode) {
287287
const key = k === "." ? makeTSIndex(nodePath) : makeTSIndex(["external", k, ...nodePath]);
288-
options.parameters[key] = rawNode as any;
288+
options.parameters[key] = rawNode as unknown as ParameterObject;
289289
}
290290
});
291291
}

packages/openapi-typescript/src/transform/components-object.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ export default function transformComponentsObject(components: ComponentsObject,
102102
path: `#/components/requestBodies/${name}`,
103103
ctx: { ...ctx, indentLv },
104104
})};`,
105-
indentLv
106-
)
105+
indentLv,
106+
),
107107
);
108108
} else {
109109
if (!requestBodyObject.required) key = tsOptionalProperty(key);
@@ -164,8 +164,8 @@ export default function transformComponentsObject(components: ComponentsObject,
164164
path: `#/components/pathItems/${name}`,
165165
ctx: { ...ctx, indentLv },
166166
})};`,
167-
indentLv
168-
)
167+
indentLv,
168+
),
169169
);
170170
}
171171
}

0 commit comments

Comments
 (0)