diff --git a/.changeset/old-owls-whisper.md b/.changeset/old-owls-whisper.md new file mode 100644 index 000000000..061a0a75b --- /dev/null +++ b/.changeset/old-owls-whisper.md @@ -0,0 +1,5 @@ +--- +"openapi-typescript": patch +--- + +Fix Record appearing in union diff --git a/.changeset/tall-shrimps-pay.md b/.changeset/tall-shrimps-pay.md new file mode 100644 index 000000000..19249da28 --- /dev/null +++ b/.changeset/tall-shrimps-pay.md @@ -0,0 +1,5 @@ +--- +"openapi-typescript": patch +--- + +Improve oneOf generated types diff --git a/.eslintrc.cjs b/.eslintrc.cjs index fb7b973fd..da9fedae2 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -4,8 +4,8 @@ module.exports = { parserOptions: { project: ["./tsconfig.json"], }, - extends: ["eslint:recommended", "plugin:@typescript-eslint/strict"], - plugins: ["@typescript-eslint", "prettier"], + extends: ["eslint:recommended", "plugin:@typescript-eslint/strict", "plugin:vitest/recommended"], + plugins: ["@typescript-eslint", "no-only-tests", "prettier", "vitest"], rules: { "@typescript-eslint/consistent-indexed-object-style": "off", // sometimes naming keys is more user-friendly "@typescript-eslint/no-dynamic-delete": "off", // delete is OK @@ -19,6 +19,8 @@ module.exports = { rules: { "@typescript-eslint/ban-ts-comment": "off", // allow @ts-ignore only in tests "@typescript-eslint/no-empty-function": "off", // don’t enforce this in tests + "no-only-tests/no-only-tests": "error", + "vitest/valid-title": "off", // doesn’t work? }, }, ], diff --git a/package.json b/package.json index cecbf32f0..2b5b96d21 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,9 @@ "del-cli": "^5.0.0", "eslint": "^8.44.0", "eslint-config-prettier": "^8.8.0", + "eslint-plugin-no-only-tests": "^3.1.0", "eslint-plugin-prettier": "^4.2.1", + "eslint-plugin-vitest": "^0.2.6", "npm-run-all": "^4.1.5", "prettier": "^2.8.8", "typescript": "^5.1.6" diff --git a/packages/openapi-fetch/package.json b/packages/openapi-fetch/package.json index dd036e05e..c9cfb4a42 100644 --- a/packages/openapi-fetch/package.json +++ b/packages/openapi-fetch/package.json @@ -48,7 +48,8 @@ "build:ts-min": "esbuild --bundle src/index.ts --format=esm --minify --outfile=dist/index.min.js && cp dist/index.d.ts dist/index.min.d.ts", "build:cjs": "esbuild --bundle src/index.ts --format=cjs --outfile=dist/index.cjs", "lint": "pnpm run lint:js", - "lint:js": "prettier --check \"{src,test}/**/*\"", + "lint:js": "eslint \"{src,test}/**/*.{js,ts}\"", + "lint:prettier": "prettier --check \"{src,test}/**/*\"", "test": "pnpm run test:ts && npm run test:js", "test:js": "vitest run", "test:ts": "tsc --noEmit", diff --git a/packages/openapi-fetch/src/index.test.ts b/packages/openapi-fetch/src/index.test.ts index 55d63054d..aff8ed55d 100644 --- a/packages/openapi-fetch/src/index.test.ts +++ b/packages/openapi-fetch/src/index.test.ts @@ -227,6 +227,8 @@ describe("client", () => { }); describe("body", () => { + // these are pure type tests; no runtime assertions needed + /* eslint-disable vitest/expect-expect */ it("requires necessary requestBodies", async () => { const client = createClient({ baseUrl: "https://myapi.com/v1" }); mockFetch({ status: 200, body: JSON.stringify({ message: "OK" }) }); @@ -285,6 +287,7 @@ describe("client", () => { }); }); }); + /* eslint-enable vitest/expect-expect */ }); describe("options", () => { @@ -408,7 +411,7 @@ describe("client", () => { expect(response.status).toBe(204); // assert error is empty - expect(error).toBe(undefined); + expect(error).toBeUndefined(); }); it("treats `default` as an error", async () => { @@ -478,7 +481,7 @@ describe("client", () => { expect(response.status).toBe(200); // assert error is empty - expect(error).toBe(undefined); + expect(error).toBeUndefined(); }); it("sends correct options, returns error", async () => { @@ -500,7 +503,7 @@ describe("client", () => { expect(response.status).toBe(404); // assert data is empty - expect(data).toBe(undefined); + expect(data).toBeUndefined(); }); // note: this was a previous bug in the type inference @@ -543,7 +546,7 @@ describe("client", () => { expect(response.status).toBe(201); // assert error is empty - expect(error).toBe(undefined); + expect(error).toBeUndefined(); }); it("supports sepecifying utf-8 encoding", async () => { @@ -563,7 +566,7 @@ describe("client", () => { expect(response.status).toBe(201); // assert error is empty - expect(error).toBe(undefined); + expect(error).toBeUndefined(); }); }); @@ -588,7 +591,7 @@ describe("client", () => { expect(data).toEqual({}); // assert error is empty - expect(error).toBe(undefined); + expect(error).toBeUndefined(); }); it("returns empty object on Content-Length: 0", async () => { @@ -604,7 +607,7 @@ describe("client", () => { expect(data).toEqual({}); // assert error is empty - expect(error).toBe(undefined); + expect(error).toBeUndefined(); }); }); diff --git a/packages/openapi-typescript/examples/github-api-next.ts b/packages/openapi-typescript/examples/github-api-next.ts index fbf1ddd1e..d5348344c 100644 --- a/packages/openapi-typescript/examples/github-api-next.ts +++ b/packages/openapi-typescript/examples/github-api-next.ts @@ -13715,7 +13715,7 @@ export interface components { [key: string]: unknown; } & (components["schemas"]["simple-user"] | components["schemas"]["team"] | components["schemas"]["organization"]); /** @description The team that granted access to GitHub Copilot to the assignee. This will be null if the user was assigned a seat individually. */ - assigning_team?: components["schemas"]["team"]; + assigning_team?: components["schemas"]["team"] | null | Record; /** * Format: date * @description The pending cancellation date for the seat, in `YYYY-MM-DD` format. This will be null unless the assignee's Copilot access has been canceled during the current billing cycle. If the seat has been cancelled, this corresponds to the start of the organization's next billing cycle. @@ -23378,7 +23378,7 @@ export interface components { id: number; node_id: string; original_environment: string; - payload: string | Record; + payload: string | Record | null; /** * App * @description GitHub apps are a new way to extend GitHub. They can be installed directly on organizations and user accounts and granted access to specific repositories. They come with granular permissions and built-in webhooks. GitHub apps are first class actors within GitHub. @@ -25032,7 +25032,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -31972,7 +31972,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -33939,7 +33939,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -40211,7 +40211,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -40551,7 +40551,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -41399,7 +41399,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -41739,7 +41739,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -42588,7 +42588,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -42928,7 +42928,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -43900,7 +43900,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -44240,7 +44240,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -45088,7 +45088,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -45428,7 +45428,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -46357,7 +46357,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -46697,7 +46697,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -47562,7 +47562,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -47902,7 +47902,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -48751,7 +48751,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -49091,7 +49091,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -49940,7 +49940,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -50280,7 +50280,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -51453,7 +51453,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -51786,7 +51786,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -52725,7 +52725,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -53058,7 +53058,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -54004,7 +54004,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -54337,7 +54337,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -55132,7 +55132,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -55465,7 +55465,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -56317,7 +56317,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -56604,7 +56604,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -57450,7 +57450,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -57783,7 +57783,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -58667,7 +58667,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -59007,7 +59007,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -59911,7 +59911,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -60251,7 +60251,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -61135,7 +61135,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -61475,7 +61475,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -62376,7 +62376,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -62709,7 +62709,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -63559,7 +63559,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -63853,7 +63853,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -64753,7 +64753,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -65047,7 +65047,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -65969,7 +65969,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -66302,7 +66302,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -67188,7 +67188,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -67528,7 +67528,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -68393,7 +68393,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -68726,7 +68726,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -69575,7 +69575,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -69915,7 +69915,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -70692,7 +70692,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -70814,19 +70814,19 @@ export interface components { name?: string; version?: string; npm_user?: string; - author?: string | Record; - bugs?: string | Record; + author?: string | Record | null; + bugs?: string | Record | null; dependencies?: Record; dev_dependencies?: Record; peer_dependencies?: Record; optional_dependencies?: Record; description?: string; - dist?: string | Record; + dist?: string | Record | null; git_head?: string; homepage?: string; license?: string; main?: string; - repository?: string | Record; + repository?: string | Record | null; scripts?: Record; id?: string; node_version?: string; @@ -70839,7 +70839,7 @@ export interface components { files?: string[]; bin?: Record; man?: Record; - directories?: string | Record; + directories?: string | Record | null; os?: string[]; cpu?: string[]; readme?: string; @@ -70850,7 +70850,7 @@ export interface components { deleted_by_id?: number; }) | null; nuget_metadata?: (({ - id?: string | Record | number; + id?: string | Record | number | null; name?: string; value?: OneOf<[boolean, string, number, { url?: string; @@ -74399,7 +74399,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -74708,7 +74708,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -75017,7 +75017,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -75357,7 +75357,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -75666,7 +75666,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -95617,7 +95617,7 @@ export interface operations { body?: string; /** @description Login for the user that this issue should be assigned to. _NOTE: Only users with push access can set the assignee for new issues. The assignee is silently dropped otherwise. **This field is deprecated.**_ */ assignee?: string | null; - milestone?: string | number; + milestone?: string | number | null; /** @description Labels to associate with this issue. _NOTE: Only users with push access can set labels for new issues. Labels are silently dropped otherwise._ */ labels?: (OneOf<[string, { id?: number; @@ -95946,7 +95946,7 @@ export interface operations { content: { "application/json": { /** @description The title of the issue. */ - title?: string | number; + title?: string | number | null; /** @description The contents of the issue. */ body?: string | null; /** @description Username to assign to this issue. **This field is deprecated.** */ @@ -95961,7 +95961,7 @@ export interface operations { * @enum {string|null} */ state_reason?: "completed" | "not_planned" | "reopened" | null; - milestone?: string | number; + milestone?: string | number | null; /** @description Labels to associate with this issue. Pass one or more labels to _replace_ the set of labels on this issue. Send an empty array (`[]`) to clear all labels from the issue. Only users with push access can set labels for issues. Without push access to the repository, label changes are silently dropped. */ labels?: (OneOf<[string, { id?: number; diff --git a/packages/openapi-typescript/examples/github-api.ts b/packages/openapi-typescript/examples/github-api.ts index cbcda8410..fc5d09f15 100644 --- a/packages/openapi-typescript/examples/github-api.ts +++ b/packages/openapi-typescript/examples/github-api.ts @@ -12562,7 +12562,7 @@ export interface components { [key: string]: unknown; } & (components["schemas"]["simple-user"] | components["schemas"]["team"] | components["schemas"]["organization"]); /** @description The team that granted access to GitHub Copilot to the assignee. This will be null if the user was assigned a seat individually. */ - assigning_team?: components["schemas"]["team"]; + assigning_team?: components["schemas"]["team"] | null; /** * Format: date * @description The pending cancellation date for the seat, in `YYYY-MM-DD` format. This will be null unless the assignee's Copilot access has been canceled during the current billing cycle. If the seat has been cancelled, this corresponds to the start of the organization's next billing cycle. @@ -25549,7 +25549,7 @@ export interface components { id: number; node_id: string; original_environment: string; - payload: string | Record; + payload: string | Record | null; /** * App * @description GitHub apps are a new way to extend GitHub. They can be installed directly on organizations and user accounts and granted access to specific repositories. They come with granular permissions and built-in webhooks. GitHub apps are first class actors within GitHub. @@ -27203,7 +27203,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -34143,7 +34143,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -36110,7 +36110,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -42382,7 +42382,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -42722,7 +42722,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -43570,7 +43570,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -43910,7 +43910,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -44759,7 +44759,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -45099,7 +45099,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -46071,7 +46071,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -46411,7 +46411,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -47259,7 +47259,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -47599,7 +47599,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -48528,7 +48528,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -48868,7 +48868,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -49733,7 +49733,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -50073,7 +50073,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -50922,7 +50922,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -51262,7 +51262,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -52111,7 +52111,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -52451,7 +52451,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -53624,7 +53624,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -53957,7 +53957,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -54896,7 +54896,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -55229,7 +55229,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -56175,7 +56175,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -56508,7 +56508,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -57303,7 +57303,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -57636,7 +57636,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -58488,7 +58488,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -58775,7 +58775,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -59621,7 +59621,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -59954,7 +59954,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -60838,7 +60838,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -61178,7 +61178,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -62082,7 +62082,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -62422,7 +62422,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -63306,7 +63306,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -63646,7 +63646,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -64547,7 +64547,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -64880,7 +64880,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -65730,7 +65730,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -66024,7 +66024,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -66924,7 +66924,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -67218,7 +67218,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -68140,7 +68140,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -68473,7 +68473,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -69359,7 +69359,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -69699,7 +69699,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -70564,7 +70564,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -70897,7 +70897,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -71746,7 +71746,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -72086,7 +72086,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -72863,7 +72863,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -72985,19 +72985,19 @@ export interface components { name?: string; version?: string; npm_user?: string; - author?: string | Record; - bugs?: string | Record; + author?: string | Record | null; + bugs?: string | Record | null; dependencies?: Record; dev_dependencies?: Record; peer_dependencies?: Record; optional_dependencies?: Record; description?: string; - dist?: string | Record; + dist?: string | Record | null; git_head?: string; homepage?: string; license?: string; main?: string; - repository?: string | Record; + repository?: string | Record | null; scripts?: Record; id?: string; node_version?: string; @@ -73010,7 +73010,7 @@ export interface components { files?: string[]; bin?: Record; man?: Record; - directories?: string | Record; + directories?: string | Record | null; os?: string[]; cpu?: string[]; readme?: string; @@ -73021,7 +73021,7 @@ export interface components { deleted_by_id?: number; }) | null; nuget_metadata?: (({ - id?: string | Record | number; + id?: string | Record | number | null; name?: string; value?: OneOf<[boolean, string, number, { url?: string; @@ -76570,7 +76570,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -76879,7 +76879,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -77188,7 +77188,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -77528,7 +77528,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -77837,7 +77837,7 @@ export interface components { public?: boolean; /** Format: uri-template */ pulls_url: string; - pushed_at: number | string; + pushed_at: number | string | null; /** Format: uri-template */ releases_url: string; role_name?: string | null; @@ -97920,7 +97920,7 @@ export interface operations { body?: string; /** @description Login for the user that this issue should be assigned to. _NOTE: Only users with push access can set the assignee for new issues. The assignee is silently dropped otherwise. **This field is deprecated.**_ */ assignee?: string | null; - milestone?: string | number; + milestone?: string | number | null; /** @description Labels to associate with this issue. _NOTE: Only users with push access can set labels for new issues. Labels are silently dropped otherwise._ */ labels?: (OneOf<[string, { id?: number; @@ -98249,7 +98249,7 @@ export interface operations { content: { "application/json": { /** @description The title of the issue. */ - title?: string | number; + title?: string | number | null; /** @description The contents of the issue. */ body?: string | null; /** @description Username to assign to this issue. **This field is deprecated.** */ @@ -98265,7 +98265,7 @@ export interface operations { * @enum {string|null} */ state_reason?: "completed" | "not_planned" | "reopened" | null; - milestone?: string | number; + milestone?: string | number | null; /** @description Labels to associate with this issue. Pass one or more labels to _replace_ the set of labels on this issue. Send an empty array (`[]`) to clear all labels from the issue. Only users with push access can set labels for issues. Without push access to the repository, label changes are silently dropped. */ labels?: (OneOf<[string, { id?: number; diff --git a/packages/openapi-typescript/package.json b/packages/openapi-typescript/package.json index 11aec6709..fb31d36d0 100644 --- a/packages/openapi-typescript/package.json +++ b/packages/openapi-typescript/package.json @@ -43,7 +43,7 @@ "download:schemas": "vite-node ./scripts/download-schemas.ts", "format": "prettier --write \"src/**/*\"", "lint": "run-p -s lint:*", - "lint:js": "eslint \"src/**/*.{js,ts}\"", + "lint:js": "eslint \"{src,test}/**/*.{js,ts}\"", "lint:prettier": "prettier --check \"src/**/*\"", "prepare": "pnpm run build", "test": "run-p -s test:*", diff --git a/packages/openapi-typescript/src/transform/schema-object.ts b/packages/openapi-typescript/src/transform/schema-object.ts index 25d2b9273..2ec359ee6 100644 --- a/packages/openapi-typescript/src/transform/schema-object.ts +++ b/packages/openapi-typescript/src/transform/schema-object.ts @@ -67,20 +67,27 @@ export function defaultSchemaObjectTransform(schemaObject: SchemaObject | Refere } // oneOf (no discriminator) - const oneOf = ((typeof schemaObject === "object" && (schemaObject as any).oneOf) || (schemaObject as any).enum || undefined) as (SchemaObject | ReferenceObject)[] | undefined; // note: for objects, treat enum as oneOf + const oneOf = ((typeof schemaObject === "object" && !(schemaObject as any).discriminator && (schemaObject as any).oneOf) || (schemaObject as any).enum || undefined) as (SchemaObject | ReferenceObject)[] | undefined; // note: for objects, treat enum as oneOf if (oneOf && !oneOf.some((t) => "$ref" in t && ctx.discriminators[t.$ref])) { const oneOfNormalized = oneOf.map((item) => transformSchemaObject(item, { path, ctx })); + if (schemaObject.nullable) oneOfNormalized.push("null"); + + // handle oneOf + polymorphic array type + if ("type" in schemaObject && Array.isArray(schemaObject.type)) { + const coreTypes = schemaObject.type.map((t) => transformSchemaObject({ ...schemaObject, oneOf: undefined, type: t }, { path, ctx })); + return tsUnionOf(...oneOfNormalized, ...coreTypes); + } + // OneOf<> helper needed if any objects present ("{") const oneOfTypes = oneOfNormalized.some((t) => typeof t === "string" && t.includes("{")) ? tsOneOf(...oneOfNormalized) : tsUnionOf(...oneOfNormalized); + // handle oneOf + object type if ("type" in schemaObject && schemaObject.type === "object") { - const coreSchema = { ...schemaObject }; - delete (coreSchema as any).oneOf; - delete coreSchema.enum; - return tsIntersectionOf(transformSchemaObject(coreSchema, { path, ctx }), oneOfTypes); - } else { - return oneOfTypes; + return tsIntersectionOf(transformSchemaObject({ ...schemaObject, oneOf: undefined, enum: undefined } as any, { path, ctx }), oneOfTypes); } + + // default + return oneOfTypes; } if ("type" in schemaObject) { @@ -183,7 +190,7 @@ export function defaultSchemaObjectTransform(schemaObject: SchemaObject | Refere // discriminators for (const k of ["oneOf", "allOf", "anyOf"] as ("oneOf" | "allOf" | "anyOf")[]) { - if (!(k in schemaObject)) continue; + if (!(schemaObject as any)[k]) continue; const discriminatorRef: ReferenceObject | undefined = (schemaObject as any)[k].find((t: SchemaObject | ReferenceObject) => "$ref" in t && ctx.discriminators[t.$ref]); if (discriminatorRef) { const discriminator = ctx.discriminators[discriminatorRef.$ref]; @@ -216,7 +223,7 @@ export function defaultSchemaObjectTransform(schemaObject: SchemaObject | Refere } // oneOf (discriminator) if ("oneOf" in schemaObject && Array.isArray(schemaObject.oneOf)) { - const oneOfType = tsOneOf(...collectCompositions(schemaObject.oneOf)); + const oneOfType = tsUnionOf(...collectCompositions(schemaObject.oneOf)); finalType = finalType ? tsIntersectionOf(finalType, oneOfType) : oneOfType; } else { // allOf diff --git a/packages/openapi-typescript/test/index.test.ts b/packages/openapi-typescript/test/index.test.ts index c0556ce38..f3d5e9b11 100644 --- a/packages/openapi-typescript/test/index.test.ts +++ b/packages/openapi-typescript/test/index.test.ts @@ -488,6 +488,7 @@ export type operations = Record; components: { schemas: { Pet: { + type: "object", // note: this is “wrong” but added because this should be ignored (fixes a bug) oneOf: [{ $ref: "#/components/schemas/Cat" }, { $ref: "#/components/schemas/Dog" }, { $ref: "#/components/schemas/Lizard" }], discriminator: { propertyName: "petType", @@ -497,7 +498,7 @@ export type operations = Record; lizard: "#/components/schemas/Lizard", }, }, - }, + } as any, Cat: { type: "object", properties: { diff --git a/packages/openapi-typescript/test/schema-object.test.ts b/packages/openapi-typescript/test/schema-object.test.ts index 8be3abf72..eab63e9b1 100644 --- a/packages/openapi-typescript/test/schema-object.test.ts +++ b/packages/openapi-typescript/test/schema-object.test.ts @@ -368,6 +368,12 @@ describe("Schema Object", () => { expect(generated).toBe("0 | 1"); }); + test("nullable: true", () => { + const schema: SchemaObject = { nullable: true, oneOf: [{ type: "integer" }, { type: "string" }] }; + const generated = transformSchemaObject(schema, options); + expect(generated).toBe("number | string | null"); + }); + test("complex", () => { const schema: SchemaObject = { oneOf: [ @@ -407,6 +413,15 @@ describe("Schema Object", () => { }]>`); }); + test("oneOf + array type", () => { + const schema = { + oneOf: [{ type: "integer" }, { type: "string" }], + type: ["null", "integer", "string"], + }; + const generated = transformSchemaObject(schema, options); + expect(generated).toBe("number | string | null"); + }); + test("enum (acting as oneOf)", () => { const schema: SchemaObject = { type: "object", diff --git a/packages/openapi-typescript/test/utils.test.ts b/packages/openapi-typescript/test/utils.test.ts index 9f2c7fe26..5fe3aaf57 100644 --- a/packages/openapi-typescript/test/utils.test.ts +++ b/packages/openapi-typescript/test/utils.test.ts @@ -89,34 +89,34 @@ describe("utils", () => { describe("escObjKey", () => { it("basic", () => { - expect(escObjKey("some-prop")).toStrictEqual('"some-prop"'); + expect(escObjKey("some-prop")).toBe('"some-prop"'); }); it("@ escapes", () => { - expect(escObjKey("@type")).toStrictEqual('"@type"'); + expect(escObjKey("@type")).toBe('"@type"'); }); it("number escapes", () => { - expect(escObjKey("123var")).toStrictEqual('"123var"'); + expect(escObjKey("123var")).toBe('"123var"'); }); it("only number no escapes", () => { - expect(escObjKey("123")).toStrictEqual("123"); + expect(escObjKey("123")).toBe("123"); }); it("$ no escapes", () => { - expect(escObjKey("$ref")).toStrictEqual("$ref"); + expect(escObjKey("$ref")).toBe("$ref"); }); it("_ no escapes", () => { - expect(escObjKey("_ref_")).toStrictEqual("_ref_"); + expect(escObjKey("_ref_")).toBe("_ref_"); }); }); describe("comment", () => { it("basic", () => { - expect(comment("A comment")).toStrictEqual("/** A comment */"); - expect(comment("A multi-line \n\n comment")).toStrictEqual( + expect(comment("A comment")).toBe("/** A comment */"); + expect(comment("A multi-line \n\n comment")).toBe( // prettier-ignore "/**\n" + " * A multi-line\n" + @@ -133,7 +133,7 @@ describe("utils", () => { getSchemaObjectComment({ title: "A title", }) - ).toStrictEqual("/** A title */"); + ).toBe("/** A title */"); }); it("object with 2 properties", () => { @@ -142,7 +142,7 @@ describe("utils", () => { title: "A title", description: "A description", }) - ).toStrictEqual( + ).toBe( // prettier-ignore "/**\n" + " * A title\n" + diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d59e92cfd..4e5319e5e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,9 +29,15 @@ importers: eslint-config-prettier: specifier: ^8.8.0 version: 8.8.0(eslint@8.44.0) + eslint-plugin-no-only-tests: + specifier: ^3.1.0 + version: 3.1.0 eslint-plugin-prettier: specifier: ^4.2.1 version: 4.2.1(eslint-config-prettier@8.8.0)(eslint@8.44.0)(prettier@2.8.8) + eslint-plugin-vitest: + specifier: ^0.2.6 + version: 0.2.6(eslint@8.44.0)(typescript@5.1.6) npm-run-all: specifier: ^4.1.5 version: 4.1.5 @@ -2796,6 +2802,11 @@ packages: eslint: 8.44.0 dev: true + /eslint-plugin-no-only-tests@3.1.0: + resolution: {integrity: sha512-Lf4YW/bL6Un1R6A76pRZyE1dl1vr31G/ev8UzIc/geCgFWyrKil8hVjYqWVKGB/UIGmb6Slzs9T0wNezdSVegw==} + engines: {node: '>=5.0.0'} + dev: true + /eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.8.0)(eslint@8.44.0)(prettier@2.8.8): resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==} engines: {node: '>=12.0.0'} @@ -2813,6 +2824,19 @@ packages: prettier-linter-helpers: 1.0.0 dev: true + /eslint-plugin-vitest@0.2.6(eslint@8.44.0)(typescript@5.1.6): + resolution: {integrity: sha512-PnH4qdqzmAYu78kBnSh5Oi6L1jCtc0orJMWxFeM6k6eW2aEmi0c4Y855v6Qh//7ruU3JzN/aeZrBSVBZMP525Q==} + engines: {node: 14.x || >= 16} + peerDependencies: + eslint: '>=8.0.0' + dependencies: + '@typescript-eslint/utils': 5.61.0(eslint@8.44.0)(typescript@5.1.6) + eslint: 8.44.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + /eslint-scope@5.1.1: resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} engines: {node: '>=8.0.0'}