From d7ef3802281d5a3264e391af23eb2442a67abfee Mon Sep 17 00:00:00 2001 From: Drew Powers Date: Thu, 15 Jun 2023 21:53:05 -0600 Subject: [PATCH 1/2] Multiple improvements --- .changeset/beige-ligers-hunt.md | 5 + .changeset/khaki-bobcats-shave.md | 5 + .changeset/khaki-cycles-cough.md | 5 + .changeset/long-llamas-attend.md | 5 + .changeset/mighty-dots-hammer.md | 5 + .changeset/rude-bikes-happen.md | 5 + .eslintrc.cjs | 1 + docs/src/content/docs/openapi-fetch/api.md | 17 +- packages/openapi-fetch/src/index.test.ts | 841 +++++++++++---------- packages/openapi-fetch/src/index.ts | 73 +- packages/openapi-typescript/src/utils.ts | 2 +- 11 files changed, 561 insertions(+), 403 deletions(-) create mode 100644 .changeset/beige-ligers-hunt.md create mode 100644 .changeset/khaki-bobcats-shave.md create mode 100644 .changeset/khaki-cycles-cough.md create mode 100644 .changeset/long-llamas-attend.md create mode 100644 .changeset/mighty-dots-hammer.md create mode 100644 .changeset/rude-bikes-happen.md diff --git a/.changeset/beige-ligers-hunt.md b/.changeset/beige-ligers-hunt.md new file mode 100644 index 000000000..4ad4c9246 --- /dev/null +++ b/.changeset/beige-ligers-hunt.md @@ -0,0 +1,5 @@ +--- +"openapi-fetch": patch +--- + +Clone response internally diff --git a/.changeset/khaki-bobcats-shave.md b/.changeset/khaki-bobcats-shave.md new file mode 100644 index 000000000..9bbf7bf95 --- /dev/null +++ b/.changeset/khaki-bobcats-shave.md @@ -0,0 +1,5 @@ +--- +"openapi-fetch": minor +--- + +Expose createFinalURL() logic for testing diff --git a/.changeset/khaki-cycles-cough.md b/.changeset/khaki-cycles-cough.md new file mode 100644 index 000000000..8ece43edd --- /dev/null +++ b/.changeset/khaki-cycles-cough.md @@ -0,0 +1,5 @@ +--- +"openapi-fetch": minor +--- + +Automatically remove `undefined` and `null` query params without requiring querySerializer diff --git a/.changeset/long-llamas-attend.md b/.changeset/long-llamas-attend.md new file mode 100644 index 000000000..33f3d8fa4 --- /dev/null +++ b/.changeset/long-llamas-attend.md @@ -0,0 +1,5 @@ +--- +"openapi-fetch": patch +--- + +Strip trailing slashes from baseUrl diff --git a/.changeset/mighty-dots-hammer.md b/.changeset/mighty-dots-hammer.md new file mode 100644 index 000000000..3859efb3e --- /dev/null +++ b/.changeset/mighty-dots-hammer.md @@ -0,0 +1,5 @@ +--- +"openapi-fetch": patch +--- + +Fix querySerializer typing diff --git a/.changeset/rude-bikes-happen.md b/.changeset/rude-bikes-happen.md new file mode 100644 index 000000000..1338c03e8 --- /dev/null +++ b/.changeset/rude-bikes-happen.md @@ -0,0 +1,5 @@ +--- +"openapi-fetch": minor +--- + +Allow overriding of JSON body parsing diff --git a/.eslintrc.cjs b/.eslintrc.cjs index cfd18b5c9..fb7b973fd 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -10,6 +10,7 @@ module.exports = { "@typescript-eslint/consistent-indexed-object-style": "off", // sometimes naming keys is more user-friendly "@typescript-eslint/no-dynamic-delete": "off", // delete is OK "@typescript-eslint/no-unnecessary-condition": "off", // this gives bad advice + "no-console": "error", "no-unused-vars": "off", }, overrides: [ diff --git a/docs/src/content/docs/openapi-fetch/api.md b/docs/src/content/docs/openapi-fetch/api.md index 8e81c0895..5bc36c296 100644 --- a/docs/src/content/docs/openapi-fetch/api.md +++ b/docs/src/content/docs/openapi-fetch/api.md @@ -27,14 +27,15 @@ const { get, put, post, del, options, head, patch, trace } = createClient const { data, error, response } = await get("/my-url", options); ``` -| Name | Type | Description | -| :---------------- | :-----------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `params` | ParamsObject | Provide `path` and `query` params from the OpenAPI schema | -| `params.path` | `{ [name]: value }` | Provide all `path` params (params that are part of the URL) | -| `params.query` | `{ [name]: value }` | Provide all `query params (params that are part of the searchParams | -| `body` | `{ [name]:value }` | The requestBody data, if needed (PUT/POST/PATCH/DEL only) | -| `querySerializer` | QuerySerializer | (optional) Override default param serialization (see [Parameter Serialization](#parameter-serialization)) | -| (Fetch options) | | Any valid fetch option (`headers`, `mode`, `cache`, `signal` …) (docs) | +| Name | Type | Description | +| :---------------- | :---------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `params` | ParamsObject | Provide `path` and `query` params from the OpenAPI schema | +| `params.path` | `{ [name]: value }` | Provide all `path` params (params that are part of the URL) | +| `params.query` | `{ [name]: value }` | Provide all `query params (params that are part of the searchParams | +| `body` | `{ [name]:value }` | The requestBody data, if needed (PUT/POST/PATCH/DEL only) | +| `querySerializer` | QuerySerializer | (optional) Override default param serialization (see [Parameter Serialization](#parameter-serialization)) | +| `parseAs` | `"json"` \| `"text"` \| `"arrayBuffer"` \| `"blob"` \| `"stream"` | Decide how to parse the response body, with `"stream"` skipping processing altogether (default: `"json"`) | +| (Fetch options) | | Any valid fetch option (`headers`, `mode`, `cache`, `signal` …) (docs) | ### Parameter Serialization diff --git a/packages/openapi-fetch/src/index.test.ts b/packages/openapi-fetch/src/index.test.ts index d13fc4f0b..0dec94f7b 100644 --- a/packages/openapi-fetch/src/index.test.ts +++ b/packages/openapi-fetch/src/index.test.ts @@ -2,11 +2,9 @@ import { atom, computed } from "nanostores"; import { afterEach, beforeAll, describe, expect, it, vi } from "vitest"; // @ts-expect-error import createFetchMock from "vitest-fetch-mock"; -import createClient, { FilterKeys, JSONLike, RequestBody, RequestBodyContent, RequestBodyJSON } from "./index.js"; +import createClient from "./index.js"; import type { paths } from "../test/v1.js"; -type CreateTag = paths["/tag/{name}"]["put"]; - const fetchMocker = createFetchMock(vi); beforeAll(() => { @@ -16,6 +14,20 @@ afterEach(() => { fetchMocker.resetMocks(); }); +interface MockResponse { + headers?: Record; + status: number; + body: any; +} + +function mockFetch(res: MockResponse) { + fetchMocker.mockResponse(() => res); +} + +function mockFetchOnce(res: MockResponse) { + fetchMocker.mockResponseOnce(() => res); +} + describe("client", () => { it("generates all proper functions", () => { const client = createClient(); @@ -30,465 +42,534 @@ describe("client", () => { expect(client).toHaveProperty("trace"); }); - it("marks data as undefined, but never both", async () => { - const client = createClient(); - - // data - fetchMocker.mockResponseOnce(JSON.stringify(["one", "two", "three"])); - const dataRes = await client.get("/string-array", {}); + describe("TypeScript checks", () => { + it("marks data or error as undefined, but never both", async () => { + const client = createClient(); - // … is initially possibly undefined - // @ts-expect-error - expect(dataRes.data[0]).toBe("one"); + // data + mockFetchOnce({ status: 200, body: JSON.stringify(["one", "two", "three"]) }); + const dataRes = await client.get("/string-array", {}); - // … is present if error is undefined - if (!dataRes.error) { + // … is initially possibly undefined + // @ts-expect-error expect(dataRes.data[0]).toBe("one"); - } - // … means data is undefined - if (dataRes.data) { - // @ts-expect-error - expect(() => dataRes.error.message).toThrow(); - } - - // error - fetchMocker.mockResponseOnce(() => ({ - status: 500, - body: JSON.stringify({ status: "500", message: "Something went wrong" }), - })); - const errorRes = await client.get("/string-array", {}); - - // … is initially possibly undefined - // @ts-expect-error - expect(errorRes.error.message).toBe("Something went wrong"); - - // … is present if error is undefined - if (!errorRes.data) { - expect(errorRes.error.message).toBe("Something went wrong"); - } + // … is present if error is undefined + if (!dataRes.error) { + expect(dataRes.data[0]).toBe("one"); + } - // … means data is undefined - if (errorRes.error) { - // @ts-expect-error - expect(() => errorRes.data[0]).toThrow(); - } - }); + // … means data is undefined + if (dataRes.data) { + // @ts-expect-error + expect(() => dataRes.error.message).toThrow(); + } - it("requires path params", async () => { - const client = createClient({ baseUrl: "https://myapi.com/v1" }); - fetchMocker.mockResponse(JSON.stringify({ message: "OK" })); + // error + mockFetchOnce({ status: 500, body: JSON.stringify({ code: 500, message: "Something went wrong" }) }); + const errorRes = await client.get("/string-array", {}); - // expect error on missing 'params' - // @ts-expect-error - await client.get("/post/{post_id}", {}); + // … is initially possibly undefined + // @ts-expect-error + expect(errorRes.error.message).toBe("Something went wrong"); - // expect error on empty params - // @ts-expect-error - await client.get("/post/{post_id}", { params: {} }); + // … is present if error is undefined + if (!errorRes.data) { + expect(errorRes.error.message).toBe("Something went wrong"); + } - // expect error on empty params.path - // @ts-expect-error - await client.get("/post/{post_id}", { params: { path: {} } }); + // … means data is undefined + if (errorRes.error) { + // @ts-expect-error + expect(() => errorRes.data[0]).toThrow(); + } + }); - // expect error on mismatched type (number v string) - // @ts-expect-error - await client.get("/post/{post_id}", { params: { path: { post_id: 1234 } }, query: {} }); + it("requires path params", async () => { + const client = createClient({ baseUrl: "https://myapi.com/v1" }); + mockFetch({ status: 200, body: JSON.stringify({ message: "OK" }) }); - // (no error) - await client.get("/post/{post_id}", { params: { path: { post_id: "1234" }, query: {} } }); - }); + // expect error on missing 'params' + // @ts-expect-error + await client.get("/post/{post_id}", {}); - it("requires necessary requestBodies", async () => { - const client = createClient({ baseUrl: "https://myapi.com/v1" }); - fetchMocker.mockResponse(JSON.stringify({ message: "OK" })); + // expect error on empty params + // @ts-expect-error + await client.get("/post/{post_id}", { params: {} }); - // expect error on missing `body` - // @ts-expect-error - await client.get("/post", {}); + // expect error on empty params.path + // @ts-expect-error + await client.get("/post/{post_id}", { params: { path: {} } }); - // expect error on missing fields - // @ts-expect-error - await client.put("/post", { body: { title: "Foo" } }); + // expect error on mismatched type (number v string) + // @ts-expect-error + await client.get("/post/{post_id}", { params: { path: { post_id: 1234 } }, query: {} }); - // expect present body to be good enough (all fields optional) - // (no error) - await client.put("/post", { - body: { title: "Foo", body: "Bar", publish_date: new Date("2023-04-01T12:00:00Z").getTime() }, + // (no error) + await client.get("/post/{post_id}", { params: { path: { post_id: "1234" }, query: {} } }); }); - }); - it("skips optional requestBody", async () => { - const mockData = { status: "success" }; - const client = createClient(); - fetchMocker.mockResponse(() => ({ status: 201, body: JSON.stringify(mockData) })); - - // assert omitting `body` doesn’t raise a TS error (testing the response isn’t necessary) - await client.put("/tag/{name}", { - params: { path: { name: "New Tag" } }, - }); + it("requires necessary requestBodies", async () => { + const client = createClient({ baseUrl: "https://myapi.com/v1" }); + mockFetch({ status: 200, body: JSON.stringify({ message: "OK" }) }); - // assert providing `body` with correct schema doesn’t raise a TS error - await client.put("/tag/{name}", { - params: { path: { name: "New Tag" } }, - body: { description: "This is a new tag" }, - }); + // expect error on missing `body` + // @ts-expect-error + await client.get("/post", {}); - // assert providing `body` with bad schema WILL raise a TS error - await client.put("/tag/{name}", { - params: { path: { name: "New Tag" } }, + // expect error on missing fields // @ts-expect-error - body: { foo: "Bar" }, - }); - }); + await client.put("/post", { body: { title: "Foo" } }); - it("respects baseUrl", async () => { - const client = createClient({ baseUrl: "https://myapi.com/v1" }); - fetchMocker.mockResponse(JSON.stringify({ message: "OK" })); - await client.get("/self", {}); - expect(fetchMocker.mock.calls[0][0]).toBe("https://myapi.com/v1/self"); - }); + // expect present body to be good enough (all fields optional) + // (no error) + await client.put("/post", { + body: { title: "Foo", body: "Bar", publish_date: new Date("2023-04-01T12:00:00Z").getTime() }, + }); + }); - it("preserves default headers", async () => { - const headers: HeadersInit = { Authorization: "Bearer secrettoken" }; + it("allows optional requestBody", async () => { + const mockData = { status: "success" }; + const client = createClient(); + mockFetch({ status: 201, body: JSON.stringify(mockData) }); + + // assert omitting `body` doesn’t raise a TS error (testing the response isn’t necessary) + await client.put("/tag/{name}", { + params: { path: { name: "New Tag" } }, + }); + + // assert providing `body` with correct schema doesn’t raise a TS error + await client.put("/tag/{name}", { + params: { path: { name: "New Tag" } }, + body: { description: "This is a new tag" }, + }); + + // assert providing `body` with bad schema WILL raise a TS error + await client.put("/tag/{name}", { + params: { path: { name: "New Tag" } }, + // @ts-expect-error + body: { foo: "Bar" }, + }); + }); - const client = createClient({ headers }); - fetchMocker.mockResponseOnce(JSON.stringify({ email: "user@user.com" })); - await client.get("/self", {}); + it("request body type when optional", async () => { + mockFetch({ status: 201, body: "{}" }); + const client = createClient(); - // assert default headers were passed - const options = fetchMocker.mock.calls[0][1]; - expect(options?.headers).toEqual( - new Headers({ - ...headers, // assert new header got passed - "Content-Type": "application/json", // probably doesn’t need to get tested, but this was simpler than writing lots of code to ignore these - }) - ); - }); + // expect error on wrong body type + // @ts-expect-error + await client.post("/post/optional", { body: { error: true } }); + + // (no error) + await client.post("/post/optional", { + body: { + title: "", + publish_date: 3, + body: "", + }, + }); + }); - it("allows override headers", async () => { - const client = createClient({ headers: { "Cache-Control": "max-age=10000000" } }); - fetchMocker.mockResponseOnce(JSON.stringify({ email: "user@user.com" })); - await client.get("/self", { params: {}, headers: { "Cache-Control": "no-cache" } }); - - // assert default headers were passed - const options = fetchMocker.mock.calls[0][1]; - expect(options?.headers).toEqual( - new Headers({ - "Cache-Control": "no-cache", - "Content-Type": "application/json", - }) - ); - }); + it("request body type when optional inline", async () => { + mockFetch({ status: 201, body: "{}" }); + const client = createClient(); - it("accepts a custom fetch function", async () => { - const data = { works: true }; - const client = createClient({ - fetch: async () => - Promise.resolve({ - headers: new Headers(), - json: async () => data, - status: 200, - ok: true, - } as Response), + // expect error on wrong body type + // @ts-expect-error + await client.post("/post/optional/inline", { body: { error: true } }); + + // (no error) + await client.post("/post/optional/inline", { + body: { + title: "", + publish_date: 3, + body: "", + }, + }); }); - expect((await client.get("/self", {})).data).toBe(data); }); - it("treats `default` as an error", async () => { - const client = createClient({ headers: { "Cache-Control": "max-age=10000000" } }); - fetchMocker.mockResponseOnce(() => ({ status: 500, headers: { "Content-Type": "application/json" }, body: JSON.stringify({ code: 500, message: "An unexpected error occurred" }) })); - const { error } = await client.get("/default-as-error", {}); - - // discard `data` object - if (!error) throw new Error("treats `default` as an error: error response should be present"); - - // assert `error.message` doesn’t throw TS error - expect(error.message).toBe("An unexpected error occurred"); - }); -}); + describe("options", () => { + it("respects baseUrl", async () => { + let client = createClient({ baseUrl: "https://myapi.com/v1" }); + mockFetch({ status: 200, body: JSON.stringify({ message: "OK" }) }); + await client.get("/self", {}); -describe("get()", () => { - it("sends the correct method", async () => { - const client = createClient(); - fetchMocker.mockResponseOnce(() => ({ status: 200, body: "{}" })); - await client.get("/anyMethod", {}); - expect(fetchMocker.mock.calls[0][1]?.method).toBe("GET"); - }); + // assert baseUrl and path mesh as expected + expect(fetchMocker.mock.calls[0][0]).toBe("https://myapi.com/v1/self"); - it("sends correct options, returns success", async () => { - const mockData = { title: "My Post", body: "

This is a very good post

", publish_date: new Date("2023-03-01T12:00:00Z").getTime() }; - const client = createClient(); - fetchMocker.mockResponseOnce(() => ({ status: 200, body: JSON.stringify(mockData) })); - const { data, error, response } = await client.get("/post/{post_id}", { - params: { path: { post_id: "my-post" }, query: {} }, + client = createClient({ baseUrl: "https://myapi.com/v1/" }); + await client.get("/self", {}); + // assert trailing '/' was removed + expect(fetchMocker.mock.calls[1][0]).toBe("https://myapi.com/v1/self"); }); - // assert correct URL was called - expect(fetchMocker.mock.calls[0][0]).toBe("/post/my-post"); - - // assert correct data was returned - expect(data).toEqual(mockData); - expect(response.status).toBe(200); - - // assert error is empty - expect(error).toBe(undefined); - }); - - it("sends correct options, returns error", async () => { - const mockError = { code: 404, message: "Post not found" }; - const client = createClient(); - fetchMocker.mockResponseOnce(() => ({ status: 404, body: JSON.stringify(mockError) })); - const { data, error, response } = await client.get("/post/{post_id}", { - params: { - path: { post_id: "my-post" }, - query: {}, - }, + it("preserves default headers", async () => { + const headers: HeadersInit = { Authorization: "Bearer secrettoken" }; + + const client = createClient({ headers }); + mockFetchOnce({ status: 200, body: JSON.stringify({ email: "user@user.com" }) }); + await client.get("/self", {}); + + // assert default headers were passed + const options = fetchMocker.mock.calls[0][1]; + expect(options?.headers).toEqual( + new Headers({ + ...headers, // assert new header got passed + "Content-Type": "application/json", // probably doesn’t need to get tested, but this was simpler than writing lots of code to ignore these + }) + ); }); - // assert correct URL was called - expect(fetchMocker.mock.calls[0][0]).toBe("/post/my-post"); + it("allows override headers", async () => { + const client = createClient({ headers: { "Cache-Control": "max-age=10000000" } }); + mockFetchOnce({ status: 200, body: JSON.stringify({ email: "user@user.com" }) }); + await client.get("/self", { params: {}, headers: { "Cache-Control": "no-cache" } }); + + // assert default headers were passed + const options = fetchMocker.mock.calls[0][1]; + expect(options?.headers).toEqual( + new Headers({ + "Cache-Control": "no-cache", + "Content-Type": "application/json", + }) + ); + }); - // assert correct method was called - expect(fetchMocker.mock.calls[0][1]?.method).toBe("GET"); + it("accepts a custom fetch function", async () => { + const data = { works: true }; + const customFetch = { + clone: () => ({ ...customFetch }), + headers: new Headers(), + json: async () => data, + status: 200, + ok: true, + }; + const client = createClient({ + fetch: async () => Promise.resolve(customFetch as Response), + }); + expect((await client.get("/self", {})).data).toBe(data); + }); + }); - // assert correct error was returned - expect(error).toEqual(mockError); - expect(response.status).toBe(404); + describe("requests", () => { + it("escapes URLs properly", async () => { + const client = createClient(); + mockFetchOnce({ status: 200, body: "{}" }); + await client.get("/post/{post_id}", { + params: { path: { post_id: "post?id = 🥴" }, query: {} }, + }); - // assert data is empty - expect(data).toBe(undefined); + // expect post_id to be encoded properly + expect(fetchMocker.mock.calls[0][0]).toBe("/post/post%3Fid%20%3D%20%F0%9F%A5%B4"); + }); }); - // note: this was a previous bug in the type inference - it("handles array-type responses", async () => { - const client = createClient(); - fetchMocker.mockResponseOnce(() => ({ status: 200, body: "[]" })); - const { data } = await client.get("/posts", { params: {} }); - if (!data) throw new Error("data empty"); + describe("responses", () => { + it("returns empty object on 204", async () => { + const client = createClient(); + mockFetchOnce({ status: 204, body: "" }); + const { data, error, response } = await client.put("/tag/{name}", { + params: { path: { name: "New Tag" } }, + body: { description: "This is a new tag" }, + }); - // assert array type (and only array type) was inferred - expect(data.length).toBe(0); - }); + // assert correct data was returned + expect(data).toEqual({}); + expect(response.status).toBe(204); - it("escapes URLs properly", async () => { - const client = createClient(); - fetchMocker.mockResponseOnce(() => ({ status: 200, body: "{}" })); - await client.get("/post/{post_id}", { - params: { path: { post_id: "post?id = 🥴" }, query: {} }, + // assert error is empty + expect(error).toBe(undefined); }); - // expect post_id to be encoded properly - expect(fetchMocker.mock.calls[0][0]).toBe("/post/post%3Fid%20%3D%20%F0%9F%A5%B4"); - }); + it("treats `default` as an error", async () => { + const client = createClient({ headers: { "Cache-Control": "max-age=10000000" } }); + mockFetchOnce({ status: 500, headers: { "Content-Type": "application/json" }, body: JSON.stringify({ code: 500, message: "An unexpected error occurred" }) }); + const { error } = await client.get("/default-as-error", {}); - it("serializes params properly", async () => { - const client = createClient(); - fetchMocker.mockResponseOnce(() => ({ status: 200, body: "{}" })); - await client.get("/post/{post_id}", { - params: { - path: { post_id: "my-post" }, - query: { version: 2, format: "json" }, - }, + // discard `data` object + if (!error) throw new Error("treats `default` as an error: error response should be present"); + + // assert `error.message` doesn’t throw TS error + expect(error.message).toBe("An unexpected error occurred"); }); - expect(fetchMocker.mock.calls[0][0]).toBe("/post/my-post?version=2&format=json"); - }); + it("falls back to text() on invalid JSON", async () => { + const client = createClient(); + const bodyResponse = "My Post"; + mockFetchOnce({ status: 200, body: bodyResponse }); + const { data, error } = await client.get("/post/{post_id}", { params: { path: { post_id: "my-post" } } }); + if (error) throw new Error("falls back to text(): error shouldn’t be present"); - it("serializes params properly with querySerializer", async () => { - const client = createClient(); - fetchMocker.mockResponseOnce(() => ({ status: 200, body: "{}" })); - await client.get("/post/{post_id}", { - params: { - path: { post_id: "my-post" }, - query: { version: 2, format: "json" }, - }, - querySerializer: (q) => `alpha=${q.version}&beta=${q.format}`, + // assert `data` is a string + expect(data).toBe(bodyResponse); }); - expect(fetchMocker.mock.calls[0][0]).toBe("/post/my-post?alpha=2&beta=json"); - }); -}); + describe("parseAs", () => { + it("text", async () => { + const client = createClient(); + mockFetchOnce({ status: 200, body: "{}" }); + const { data } = await client.get("/anyMethod", { parseAs: "text" }); + expect(data).toBe("{}"); + }); + + it("arrayBuffer", async () => { + const client = createClient(); + mockFetchOnce({ status: 200, body: "{}" }); + const { data } = await client.get("/anyMethod", { parseAs: "arrayBuffer" }); + expect(data instanceof ArrayBuffer).toBe(true); + }); + + it("blob", async () => { + const client = createClient(); + mockFetchOnce({ status: 200, body: "{}" }); + const { data } = await client.get("/anyMethod", { parseAs: "blob" }); + expect((data as any).constructor.name).toBe("Blob"); + }); + + it("stream", async () => { + const client = createClient(); + mockFetchOnce({ status: 200, body: "{}" }); + const { data } = await client.get("/anyMethod", { parseAs: "stream" }); + expect(data instanceof Buffer).toBe(true); + }); + }); -describe("post()", () => { - it("sends the correct method", async () => { - const client = createClient(); - fetchMocker.mockResponseOnce(() => ({ status: 200, body: "{}" })); - await client.post("/anyMethod", {}); - expect(fetchMocker.mock.calls[0][1]?.method).toBe("POST"); + describe("querySerializer", () => { + it("default", async () => { + const client = createClient(); + mockFetchOnce({ status: 200, body: "{}" }); + await client.get("/post/{post_id}", { + params: { + path: { post_id: "my-post" }, + query: { version: 2, format: "json" }, + }, + }); + + expect(fetchMocker.mock.calls[0][0]).toBe("/post/my-post?version=2&format=json"); + }); + + it("default (with empty params)", async () => { + const client = createClient(); + mockFetchOnce({ status: 200, body: "{}" }); + await client.get("/post/{post_id}", { + params: { + path: { post_id: "my-post" }, + query: { version: undefined, format: null as any }, + }, + }); + + expect(fetchMocker.mock.calls[0][0]).toBe("/post/my-post"); + }); + + it("custom", async () => { + const client = createClient(); + mockFetchOnce({ status: 200, body: "{}" }); + await client.get("/post/{post_id}", { + params: { + path: { post_id: "my-post" }, + query: { version: 2, format: "json" }, + }, + querySerializer: (q) => `alpha=${q.version}&beta=${q.format}`, + }); + + expect(fetchMocker.mock.calls[0][0]).toBe("/post/my-post?alpha=2&beta=json"); + }); + }); }); - it("sends correct options, returns success", async () => { - const mockData = { status: "success" }; - const client = createClient(); - fetchMocker.mockResponseOnce(() => ({ status: 201, body: JSON.stringify(mockData) })); - const { data, error, response } = await client.put("/post", { - params: {}, - body: { - title: "New Post", - body: "

Best post yet

", - publish_date: new Date("2023-03-31T12:00:00Z").getTime(), - }, + describe("get()", () => { + it("sends the correct method", async () => { + const client = createClient(); + mockFetchOnce({ status: 200, body: "{}" }); + await client.get("/anyMethod", {}); + expect(fetchMocker.mock.calls[0][1]?.method).toBe("GET"); }); - // assert correct URL was called - expect(fetchMocker.mock.calls[0][0]).toBe("/post"); + it("sends correct options, returns success", async () => { + const mockData = { title: "My Post", body: "

This is a very good post

", publish_date: new Date("2023-03-01T12:00:00Z").getTime() }; + const client = createClient(); + mockFetchOnce({ status: 200, body: JSON.stringify(mockData) }); + const { data, error, response } = await client.get("/post/{post_id}", { + params: { path: { post_id: "my-post" }, query: {} }, + }); - // assert correct data was returned - expect(data).toEqual(mockData); - expect(response.status).toBe(201); + // assert correct URL was called + expect(fetchMocker.mock.calls[0][0]).toBe("/post/my-post"); - // assert error is empty - expect(error).toBe(undefined); - }); + // assert correct data was returned + expect(data).toEqual(mockData); + expect(response.status).toBe(200); - it("supports sepecifying utf-8 encoding", async () => { - const mockData = { message: "My reply" }; - const client = createClient(); - fetchMocker.mockResponseOnce(() => ({ status: 201, body: JSON.stringify(mockData) })); - const { data, error, response } = await client.put("/comment", { - params: {}, - body: { - message: "My reply", - replied_at: new Date("2023-03-31T12:00:00Z").getTime(), - }, + // assert error is empty + expect(error).toBe(undefined); }); - // assert correct data was returned - expect(data).toEqual(mockData); - expect(response.status).toBe(201); - - // assert error is empty - expect(error).toBe(undefined); - }); - - it("returns empty object on 204", async () => { - const client = createClient(); - fetchMocker.mockResponseOnce(() => ({ status: 204, body: "" })); - const { data, error, response } = await client.put("/tag/{name}", { - params: { path: { name: "New Tag" } }, - body: { description: "This is a new tag" }, + it("sends correct options, returns error", async () => { + const mockError = { code: 404, message: "Post not found" }; + const client = createClient(); + mockFetchOnce({ status: 404, body: JSON.stringify(mockError) }); + const { data, error, response } = await client.get("/post/{post_id}", { + params: { + path: { post_id: "my-post" }, + query: {}, + }, + }); + + // assert correct URL was called + expect(fetchMocker.mock.calls[0][0]).toBe("/post/my-post"); + + // assert correct method was called + expect(fetchMocker.mock.calls[0][1]?.method).toBe("GET"); + + // assert correct error was returned + expect(error).toEqual(mockError); + expect(response.status).toBe(404); + + // assert data is empty + expect(data).toBe(undefined); }); - // assert correct data was returned - expect(data).toEqual({}); - expect(response.status).toBe(204); - - // assert error is empty - expect(error).toBe(undefined); - }); - - it("request body type when optional", async () => { - fetchMocker.mockResponse(() => ({ status: 201, body: "{}" })); - const client = createClient(); - - // expect error on wrong body type - // @ts-expect-error - await client.post("/post/optional", { body: { error: true } }); + // note: this was a previous bug in the type inference + it("handles array-type responses", async () => { + const client = createClient(); + mockFetchOnce({ status: 200, body: "[]" }); + const { data } = await client.get("/posts", { params: {} }); + if (!data) throw new Error("data empty"); - // (no error) - await client.post("/post/optional", { - body: { - title: "", - publish_date: 3, - body: "", - }, + // assert array type (and only array type) was inferred + expect(data.length).toBe(0); }); }); - it("request body type when optional inline", async () => { - fetchMocker.mockResponse(() => ({ status: 201, body: "{}" })); - const client = createClient(); - - // expect error on wrong body type - // @ts-expect-error - await client.post("/post/optional/inline", { body: { error: true } }); + describe("post()", () => { + it("sends the correct method", async () => { + const client = createClient(); + mockFetchOnce({ status: 200, body: "{}" }); + await client.post("/anyMethod", {}); + expect(fetchMocker.mock.calls[0][1]?.method).toBe("POST"); + }); - // (no error) - await client.post("/post/optional/inline", { - body: { - title: "", - publish_date: 3, - body: "", - }, + it("sends correct options, returns success", async () => { + const mockData = { status: "success" }; + const client = createClient(); + mockFetchOnce({ status: 201, body: JSON.stringify(mockData) }); + const { data, error, response } = await client.put("/post", { + params: {}, + body: { + title: "New Post", + body: "

Best post yet

", + publish_date: new Date("2023-03-31T12:00:00Z").getTime(), + }, + }); + + // assert correct URL was called + expect(fetchMocker.mock.calls[0][0]).toBe("/post"); + + // assert correct data was returned + expect(data).toEqual(mockData); + expect(response.status).toBe(201); + + // assert error is empty + expect(error).toBe(undefined); }); - }); -}); -describe("delete()", () => { - it("sends the correct method", async () => { - const client = createClient(); - fetchMocker.mockResponseOnce(() => ({ status: 200, body: "{}" })); - await client.del("/anyMethod", {}); - expect(fetchMocker.mock.calls[0][1]?.method).toBe("DELETE"); + it("supports sepecifying utf-8 encoding", async () => { + const mockData = { message: "My reply" }; + const client = createClient(); + mockFetchOnce({ status: 201, body: JSON.stringify(mockData) }); + const { data, error, response } = await client.put("/comment", { + params: {}, + body: { + message: "My reply", + replied_at: new Date("2023-03-31T12:00:00Z").getTime(), + }, + }); + + // assert correct data was returned + expect(data).toEqual(mockData); + expect(response.status).toBe(201); + + // assert error is empty + expect(error).toBe(undefined); + }); }); - it("returns empty object on 204", async () => { - const client = createClient(); - fetchMocker.mockResponseOnce(() => ({ status: 204, body: "" })); - const { data, error } = await client.del("/post/{post_id}", { - params: { - path: { post_id: "123" }, - }, + describe("delete()", () => { + it("sends the correct method", async () => { + const client = createClient(); + mockFetchOnce({ status: 200, body: "{}" }); + await client.del("/anyMethod", {}); + expect(fetchMocker.mock.calls[0][1]?.method).toBe("DELETE"); }); - // assert correct data was returned - expect(data).toEqual({}); + it("returns empty object on 204", async () => { + const client = createClient(); + mockFetchOnce({ status: 204, body: "" }); + const { data, error } = await client.del("/post/{post_id}", { + params: { + path: { post_id: "123" }, + }, + }); - // assert error is empty - expect(error).toBe(undefined); - }); + // assert correct data was returned + expect(data).toEqual({}); - it("returns empty object on Content-Length: 0", async () => { - const client = createClient(); - fetchMocker.mockResponseOnce(() => ({ headers: { "Content-Length": 0 }, status: 200, body: "" })); - const { data, error } = await client.del("/post/{post_id}", { - params: { - path: { post_id: "123" }, - }, + // assert error is empty + expect(error).toBe(undefined); }); - // assert correct data was returned - expect(data).toEqual({}); + it("returns empty object on Content-Length: 0", async () => { + const client = createClient(); + mockFetchOnce({ headers: { "Content-Length": "0" }, status: 200, body: "" }); + const { data, error } = await client.del("/post/{post_id}", { + params: { + path: { post_id: "123" }, + }, + }); - // assert error is empty - expect(error).toBe(undefined); + // assert correct data was returned + expect(data).toEqual({}); + + // assert error is empty + expect(error).toBe(undefined); + }); }); -}); -describe("options()", () => { - it("sends the correct method", async () => { - const client = createClient(); - fetchMocker.mockResponseOnce(() => ({ status: 200, body: "{}" })); - await client.options("/anyMethod", {}); - expect(fetchMocker.mock.calls[0][1]?.method).toBe("OPTIONS"); + describe("options()", () => { + it("sends the correct method", async () => { + const client = createClient(); + mockFetchOnce({ status: 200, body: "{}" }); + await client.options("/anyMethod", {}); + expect(fetchMocker.mock.calls[0][1]?.method).toBe("OPTIONS"); + }); }); -}); -describe("head()", () => { - it("sends the correct method", async () => { - const client = createClient(); - fetchMocker.mockResponseOnce(() => ({ status: 200, body: "{}" })); - await client.head("/anyMethod", {}); - expect(fetchMocker.mock.calls[0][1]?.method).toBe("HEAD"); + describe("head()", () => { + it("sends the correct method", async () => { + const client = createClient(); + mockFetchOnce({ status: 200, body: "{}" }); + await client.head("/anyMethod", {}); + expect(fetchMocker.mock.calls[0][1]?.method).toBe("HEAD"); + }); }); -}); -describe("patch()", () => { - it("sends the correct method", async () => { - const client = createClient(); - fetchMocker.mockResponseOnce(() => ({ status: 200, body: "{}" })); - await client.patch("/anyMethod", {}); - expect(fetchMocker.mock.calls[0][1]?.method).toBe("PATCH"); + describe("patch()", () => { + it("sends the correct method", async () => { + const client = createClient(); + mockFetchOnce({ status: 200, body: "{}" }); + await client.patch("/anyMethod", {}); + expect(fetchMocker.mock.calls[0][1]?.method).toBe("PATCH"); + }); }); -}); -describe("trace()", () => { - it("sends the correct method", async () => { - const client = createClient(); - fetchMocker.mockResponseOnce(() => ({ status: 200, body: "{}" })); - await client.trace("/anyMethod", {}); - expect(fetchMocker.mock.calls[0][1]?.method).toBe("TRACE"); + describe("trace()", () => { + it("sends the correct method", async () => { + const client = createClient(); + mockFetchOnce({ status: 200, body: "{}" }); + await client.trace("/anyMethod", {}); + expect(fetchMocker.mock.calls[0][1]?.method).toBe("TRACE"); + }); }); }); @@ -499,13 +580,13 @@ describe("examples", () => { const client = computed([token], (currentToken) => createClient({ headers: currentToken ? { Authorization: `Bearer ${currentToken}` } : {} })); // assert initial call is unauthenticated - fetchMocker.mockResponseOnce(() => ({ status: 200, body: "{}" })); + mockFetchOnce({ status: 200, body: "{}" }); await client.get().get("/post/{post_id}", { params: { path: { post_id: "1234" }, query: {} } }); expect(fetchMocker.mock.calls[0][1].headers.get("authorization")).toBeNull(); // assert after setting token, client is authenticated const tokenVal = "abcd"; - fetchMocker.mockResponseOnce(() => ({ status: 200, body: "{}" })); + mockFetchOnce({ status: 200, body: "{}" }); await new Promise((resolve) => setTimeout(() => { token.set(tokenVal); // simulate promise-like token setting @@ -528,13 +609,13 @@ describe("examples", () => { }); // assert initial call is unauthenticated - fetchMocker.mockResponseOnce(() => ({ status: 200, body: "{}" })); + mockFetchOnce({ status: 200, body: "{}" }); await client.get("/post/{post_id}", { params: { path: { post_id: "1234" }, query: {} } }); expect(fetchMocker.mock.calls[0][1].headers.get("authorization")).toBeNull(); // assert after setting token, client is authenticated const tokenVal = "abcd"; - fetchMocker.mockResponseOnce(() => ({ status: 200, body: "{}" })); + mockFetchOnce({ status: 200, body: "{}" }); await new Promise((resolve) => setTimeout(() => { token = tokenVal; // simulate promise-like token setting diff --git a/packages/openapi-fetch/src/index.ts b/packages/openapi-fetch/src/index.ts index bcd780b23..7d2b1a0ab 100644 --- a/packages/openapi-fetch/src/index.ts +++ b/packages/openapi-fetch/src/index.ts @@ -1,7 +1,8 @@ -// settings +// settings & const const DEFAULT_HEADERS = { "Content-Type": "application/json", }; +const TRAILING_SLASH_RE = /\/*$/; /** options for each client instance */ interface ClientOptions extends RequestInit { @@ -17,6 +18,7 @@ export interface BaseParams { // const export type PathItemObject = { [M in HttpMethod]: OperationObject } & { parameters?: any }; +export type ParseAs = "json" | "text" | "blob" | "arrayBuffer" | "stream"; export interface OperationObject { parameters: any; requestBody: any; // note: "any" will get overridden in inference @@ -43,8 +45,8 @@ export type RequestBodyObj = O extends { requestBody?: any } ? O["requestBody export type RequestBodyContent = undefined extends RequestBodyObj ? FilterKeys>, "content"> | undefined : FilterKeys, "content">; export type RequestBodyJSON = FilterKeys, JSONLike> extends never ? FilterKeys>, JSONLike> | undefined : FilterKeys, JSONLike>; export type RequestBody = undefined extends RequestBodyJSON ? { body?: RequestBodyJSON } : { body: RequestBodyJSON }; -export type QuerySerializer = (query: O extends { parameters: { query: any } } ? O["parameters"]["query"] : Record) => string; -export type RequestOptions = Params & RequestBody & { querySerializer?: QuerySerializer }; +export type QuerySerializer = (query: O extends { parameters: any } ? NonNullable : Record) => string; +export type RequestOptions = Params & RequestBody & { querySerializer?: QuerySerializer; parseAs?: ParseAs }; export type Success = FilterKeys, "content">; export type Error = FilterKeys, "content">; @@ -54,6 +56,31 @@ export type FetchResponse = | { data: T extends { responses: any } ? NonNullable, JSONLike>> : unknown; error?: never; response: Response } | { data?: never; error: T extends { responses: any } ? NonNullable, JSONLike>> : unknown; response: Response }; +/** Call URLSearchParams() on the object, but remove `undefined` and `null` params */ +export function defaultSerializer(q: unknown): string { + const search = new URLSearchParams(); + if (q && typeof q === "object") { + for (const [k, v] of Object.entries(q)) { + if (v === undefined || v === null) continue; + search.set(k, String(v)); + } + } + return search.toString(); +} + +/** Construct URL string from baseUrl and handle path and query params */ +export function createFinalURL(url: string, options: { baseUrl?: string; params: { query?: Record; path?: Record }; querySerializer: QuerySerializer }): string { + let finalURL = `${options.baseUrl ? options.baseUrl.replace(TRAILING_SLASH_RE, "") : ""}${url as string}`; + if (options.params.path) { + for (const [k, v] of Object.entries(options.params.path)) finalURL = finalURL.replace(`{${k}}`, encodeURIComponent(String(v))); + } + if (options.params.query) { + const search = options.querySerializer(options.params.query as any); + if (search) finalURL += `?${search}`; + } + return finalURL; +} + export default function createClient(clientOptions: ClientOptions = {}) { const { fetch = globalThis.fetch, ...options } = clientOptions; @@ -63,16 +90,10 @@ export default function createClient(clientOptions: ClientOpti }); async function coreFetch

(url: P, fetchOptions: FetchOptions): Promise> { - const { headers, body: requestBody, params = {}, querySerializer = (q: QuerySerializer) => new URLSearchParams(q as any).toString(), ...init } = fetchOptions || {}; + const { headers, body: requestBody, params = {}, parseAs = "json", querySerializer = defaultSerializer, ...init } = fetchOptions || {}; // URL - let finalURL = `${options.baseUrl ?? ""}${url as string}`; - if ((params as any).path) { - for (const [k, v] of Object.entries((params as any).path)) finalURL = finalURL.replace(`{${k}}`, encodeURIComponent(String(v))); - } - if ((params as any).query && Object.keys((params as any).query).length) { - finalURL += `?${querySerializer((params as any).query)}`; - } + const finalURL = createFinalURL(url as string, { baseUrl: options.baseUrl, params, querySerializer }); // headers const baseHeaders = new Headers(defaultHeaders); // clone defaults (don’t overwrite!) @@ -91,9 +112,33 @@ export default function createClient(clientOptions: ClientOpti body: typeof requestBody === "string" ? requestBody : JSON.stringify(requestBody), }); - // don’t parse JSON if status is 204, or Content-Length is '0' - const body = response.status === 204 || response.headers.get("Content-Length") === "0" ? {} : await response.json(); - return response.ok ? { data: body, response } : { error: body, response: response }; + // handle empty content + // note: we return `{}` because we want user truthy checks for `.data` or `.error` to succeed + if (response.status === 204 || response.headers.get("Content-Length") === "0") { + return response.ok ? { data: {} as any, response } : { error: {} as any, response }; + } + + // parse response (falling back to .text() when necessary) + if (response.ok) { + let data: any = response.body; + if (parseAs !== "stream") { + try { + data = await response.clone()[parseAs](); + } catch { + data = await response.clone().text(); + } + } + return { data, response }; + } + + // handle errors (always parse as .json() or .text()) + let error: any = {}; + try { + error = await response.clone().json(); + } catch { + error = await response.clone().text(); + } + return { error, response }; } return { diff --git a/packages/openapi-typescript/src/utils.ts b/packages/openapi-typescript/src/utils.ts index ebd82621e..9061d7b7c 100644 --- a/packages/openapi-typescript/src/utils.ts +++ b/packages/openapi-typescript/src/utils.ts @@ -285,7 +285,7 @@ export function getEntries(obj: ArrayLike | Record, alphabetize /** print error message */ export function error(msg: string) { - console.error(c.red(` ✘ ${msg}`)); + console.error(c.red(` ✘ ${msg}`)); // eslint-disable-line no-console } /** is the given string a remote URL */ From 3a61261ca0f1cccfcc340ce5910f9eed3d083721 Mon Sep 17 00:00:00 2001 From: Drew Powers Date: Thu, 15 Jun 2023 22:49:44 -0600 Subject: [PATCH 2/2] Update devDeps --- docs/package.json | 2 +- package.json | 6 +- packages/openapi-fetch/package.json | 8 +- packages/openapi-typescript/package.json | 10 +- pnpm-lock.yaml | 667 +++++++++++++++++------ 5 files changed, 502 insertions(+), 191 deletions(-) diff --git a/docs/package.json b/docs/package.json index 53bbdce6d..68153627a 100644 --- a/docs/package.json +++ b/docs/package.json @@ -26,6 +26,6 @@ "@astrojs/sitemap": "^1.3.1", "@types/node": "^20.2.3", "html-escaper": "^3.0.3", - "typescript": "^5.0.4" + "typescript": "^5.1.3" } } diff --git a/package.json b/package.json index db067c5c0..580c20388 100644 --- a/package.json +++ b/package.json @@ -22,12 +22,14 @@ "devDependencies": { "@changesets/changelog-github": "^0.4.8", "@changesets/cli": "^2.26.1", + "@typescript-eslint/eslint-plugin": "^5.59.11", + "@typescript-eslint/parser": "^5.59.11", "del-cli": "^5.0.0", - "eslint": "^8.41.0", + "eslint": "^8.42.0", "eslint-config-prettier": "^8.8.0", "eslint-plugin-prettier": "^4.2.1", "npm-run-all": "^4.1.5", "prettier": "^2.8.8", - "typescript": "^5.0.4" + "typescript": "^5.1.3" } } diff --git a/packages/openapi-fetch/package.json b/packages/openapi-fetch/package.json index 8c056c623..01887c79e 100644 --- a/packages/openapi-fetch/package.json +++ b/packages/openapi-fetch/package.json @@ -47,12 +47,12 @@ }, "devDependencies": { "del-cli": "^5.0.0", - "esbuild": "^0.17.19", + "esbuild": "^0.18.3", "nanostores": "^0.8.1", - "openapi-typescript": "^6.2.4", + "openapi-typescript": "^6.2.7", "prettier": "^2.8.8", - "typescript": "^5.0.4", - "vitest": "^0.31.1", + "typescript": "^5.1.3", + "vitest": "^0.32.0", "vitest-fetch-mock": "^0.2.2" } } diff --git a/packages/openapi-typescript/package.json b/packages/openapi-typescript/package.json index e82d16f1a..8c0996bb0 100644 --- a/packages/openapi-typescript/package.json +++ b/packages/openapi-typescript/package.json @@ -64,14 +64,12 @@ "devDependencies": { "@types/degit": "^2.8.3", "@types/js-yaml": "^4.0.5", - "@types/node": "^20.2.3", - "@typescript-eslint/eslint-plugin": "^5.59.7", - "@typescript-eslint/parser": "^5.59.7", + "@types/node": "^20.3.1", "degit": "^2.8.4", "del-cli": "^5.0.0", "execa": "^6.1.0", - "vite": "^4.3.8", - "vite-node": "^0.31.1", - "vitest": "^0.31.1" + "vite": "^4.3.9", + "vite-node": "^0.32.0", + "vitest": "^0.32.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3c6007e6e..ae3dc7b87 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,5 +1,9 @@ lockfileVersion: '6.0' +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + importers: .: @@ -10,18 +14,24 @@ importers: '@changesets/cli': specifier: ^2.26.1 version: 2.26.1 + '@typescript-eslint/eslint-plugin': + specifier: ^5.59.11 + version: 5.59.11(@typescript-eslint/parser@5.59.11)(eslint@8.42.0)(typescript@5.1.3) + '@typescript-eslint/parser': + specifier: ^5.59.11 + version: 5.59.11(eslint@8.42.0)(typescript@5.1.3) del-cli: specifier: ^5.0.0 version: 5.0.0 eslint: - specifier: ^8.41.0 - version: 8.41.0(supports-color@9.3.1) + specifier: ^8.42.0 + version: 8.42.0 eslint-config-prettier: specifier: ^8.8.0 - version: 8.8.0(eslint@8.41.0) + version: 8.8.0(eslint@8.42.0) eslint-plugin-prettier: specifier: ^4.2.1 - version: 4.2.1(eslint-config-prettier@8.8.0)(eslint@8.41.0)(prettier@2.8.8) + version: 4.2.1(eslint-config-prettier@8.8.0)(eslint@8.42.0)(prettier@2.8.8) npm-run-all: specifier: ^4.1.5 version: 4.1.5 @@ -29,8 +39,8 @@ importers: specifier: ^2.8.8 version: 2.8.8 typescript: - specifier: ^5.0.4 - version: 5.0.4 + specifier: ^5.1.3 + version: 5.1.3 docs: dependencies: @@ -81,8 +91,8 @@ importers: specifier: ^3.0.3 version: 3.0.3 typescript: - specifier: ^5.0.4 - version: 5.0.4 + specifier: ^5.1.3 + version: 5.1.3 packages/openapi-fetch: devDependencies: @@ -90,26 +100,26 @@ importers: specifier: ^5.0.0 version: 5.0.0 esbuild: - specifier: ^0.17.19 - version: 0.17.19 + specifier: ^0.18.3 + version: 0.18.3 nanostores: specifier: ^0.8.1 version: 0.8.1 openapi-typescript: - specifier: ^6.2.4 + specifier: ^6.2.7 version: link:../openapi-typescript prettier: specifier: ^2.8.8 version: 2.8.8 typescript: - specifier: ^5.0.4 - version: 5.0.4 + specifier: ^5.1.3 + version: 5.1.3 vitest: - specifier: ^0.31.1 - version: 0.31.1(supports-color@9.3.1) + specifier: ^0.32.0 + version: 0.32.0(supports-color@9.3.1) vitest-fetch-mock: specifier: ^0.2.2 - version: 0.2.2(vitest@0.31.1) + version: 0.2.2(vitest@0.32.0) packages/openapi-typescript: dependencies: @@ -139,14 +149,8 @@ importers: specifier: ^4.0.5 version: 4.0.5 '@types/node': - specifier: ^20.2.3 - version: 20.2.3 - '@typescript-eslint/eslint-plugin': - specifier: ^5.59.7 - version: 5.59.7(@typescript-eslint/parser@5.59.7)(eslint@8.41.0)(supports-color@9.3.1)(typescript@5.0.4) - '@typescript-eslint/parser': - specifier: ^5.59.7 - version: 5.59.7(eslint@8.41.0)(supports-color@9.3.1)(typescript@5.0.4) + specifier: ^20.3.1 + version: 20.3.1 degit: specifier: ^2.8.4 version: 2.8.4 @@ -157,14 +161,14 @@ importers: specifier: ^6.1.0 version: 6.1.0 vite: - specifier: ^4.3.8 - version: 4.3.8(@types/node@20.2.3)(sass@1.62.1) + specifier: ^4.3.9 + version: 4.3.9(@types/node@20.3.1) vite-node: - specifier: ^0.31.1 - version: 0.31.1(@types/node@20.2.3)(supports-color@9.3.1) + specifier: ^0.32.0 + version: 0.32.0(@types/node@20.3.1)(supports-color@9.3.1) vitest: - specifier: ^0.31.1 - version: 0.31.1(supports-color@9.3.1) + specifier: ^0.32.0 + version: 0.32.0(supports-color@9.3.1) packages: @@ -409,6 +413,14 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/highlight': 7.18.6 + dev: false + + /@babel/code-frame@7.22.5: + resolution: {integrity: sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.22.5 + dev: true /@babel/compat-data@7.21.9: resolution: {integrity: sha512-FUGed8kfhyWvbYug/Un/VPJD41rDIgoVVcR+FuzhzOYyRz5uED+Gd3SLZml0Uw2l2aHFb7ZgdW5mGA3G2cCCnQ==} @@ -539,6 +551,12 @@ packages: /@babel/helper-validator-identifier@7.19.1: resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} engines: {node: '>=6.9.0'} + dev: false + + /@babel/helper-validator-identifier@7.22.5: + resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==} + engines: {node: '>=6.9.0'} + dev: true /@babel/helper-validator-option@7.21.0: resolution: {integrity: sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==} @@ -563,6 +581,16 @@ packages: '@babel/helper-validator-identifier': 7.19.1 chalk: 2.4.2 js-tokens: 4.0.0 + dev: false + + /@babel/highlight@7.22.5: + resolution: {integrity: sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.22.5 + chalk: 2.4.2 + js-tokens: 4.0.0 + dev: true /@babel/parser@7.21.9: resolution: {integrity: sha512-q5PNg/Bi1OpGgx5jYlvWZwAorZepEudDMCLtj967aeS7WMont7dUZI46M2XwcIQqvUlMxWfdLFu4S/qSxeUu5g==} @@ -596,8 +624,8 @@ packages: '@babel/types': 7.21.5 dev: false - /@babel/runtime@7.21.5: - resolution: {integrity: sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==} + /@babel/runtime@7.22.5: + resolution: {integrity: sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==} engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.13.11 @@ -642,7 +670,7 @@ packages: /@changesets/apply-release-plan@6.1.3: resolution: {integrity: sha512-ECDNeoc3nfeAe1jqJb5aFQX7CqzQhD2klXRez2JDb/aVpGUbX673HgKrnrgJRuQR/9f2TtLoYIzrGB9qwD77mg==} dependencies: - '@babel/runtime': 7.21.5 + '@babel/runtime': 7.22.5 '@changesets/config': 2.3.0 '@changesets/get-version-range-type': 0.3.2 '@changesets/git': 2.0.0 @@ -660,7 +688,7 @@ packages: /@changesets/assemble-release-plan@5.2.3: resolution: {integrity: sha512-g7EVZCmnWz3zMBAdrcKhid4hkHT+Ft1n0mLussFMcB1dE2zCuwcvGoy9ec3yOgPGF4hoMtgHaMIk3T3TBdvU9g==} dependencies: - '@babel/runtime': 7.21.5 + '@babel/runtime': 7.22.5 '@changesets/errors': 0.1.4 '@changesets/get-dependents-graph': 1.3.5 '@changesets/types': 5.2.1 @@ -688,7 +716,7 @@ packages: resolution: {integrity: sha512-XnTa+b51vt057fyAudvDKGB0Sh72xutQZNAdXkCqPBKO2zvs2yYZx5hFZj1u9cbtpwM6Sxtcr02/FQJfZOzemQ==} hasBin: true dependencies: - '@babel/runtime': 7.21.5 + '@babel/runtime': 7.22.5 '@changesets/apply-release-plan': 6.1.3 '@changesets/assemble-release-plan': 5.2.3 '@changesets/changelog-git': 0.1.14 @@ -763,7 +791,7 @@ packages: /@changesets/get-release-plan@3.0.16: resolution: {integrity: sha512-OpP9QILpBp1bY2YNIKFzwigKh7Qe9KizRsZomzLe6pK8IUo8onkAAVUD8+JRKSr8R7d4+JRuQrfSSNlEwKyPYg==} dependencies: - '@babel/runtime': 7.21.5 + '@babel/runtime': 7.22.5 '@changesets/assemble-release-plan': 5.2.3 '@changesets/config': 2.3.0 '@changesets/pre': 1.0.14 @@ -779,7 +807,7 @@ packages: /@changesets/git@2.0.0: resolution: {integrity: sha512-enUVEWbiqUTxqSnmesyJGWfzd51PY4H7mH9yUw0hPVpZBJ6tQZFMU3F3mT/t9OJ/GjyiM4770i+sehAn6ymx6A==} dependencies: - '@babel/runtime': 7.21.5 + '@babel/runtime': 7.22.5 '@changesets/errors': 0.1.4 '@changesets/types': 5.2.1 '@manypkg/get-packages': 1.1.3 @@ -804,7 +832,7 @@ packages: /@changesets/pre@1.0.14: resolution: {integrity: sha512-dTsHmxQWEQekHYHbg+M1mDVYFvegDh9j/kySNuDKdylwfMEevTeDouR7IfHNyVodxZXu17sXoJuf2D0vi55FHQ==} dependencies: - '@babel/runtime': 7.21.5 + '@babel/runtime': 7.22.5 '@changesets/errors': 0.1.4 '@changesets/types': 5.2.1 '@manypkg/get-packages': 1.1.3 @@ -814,7 +842,7 @@ packages: /@changesets/read@0.5.9: resolution: {integrity: sha512-T8BJ6JS6j1gfO1HFq50kU3qawYxa4NTbI/ASNVVCBTsKquy2HYwM9r7ZnzkiMe8IEObAJtUVGSrePCOxAK2haQ==} dependencies: - '@babel/runtime': 7.21.5 + '@babel/runtime': 7.22.5 '@changesets/git': 2.0.0 '@changesets/logger': 0.0.5 '@changesets/parse': 0.3.16 @@ -835,7 +863,7 @@ packages: /@changesets/write@0.2.3: resolution: {integrity: sha512-Dbamr7AIMvslKnNYsLFafaVORx4H0pvCA2MHqgtNCySMe1blImEyAEOzDmcgKAkgz4+uwoLz7demIrX+JBr/Xw==} dependencies: - '@babel/runtime': 7.21.5 + '@babel/runtime': 7.22.5 '@changesets/types': 5.2.1 fs-extra: 7.0.1 human-id: 1.0.2 @@ -895,6 +923,15 @@ packages: requiresBuild: true optional: true + /@esbuild/android-arm64@0.18.3: + resolution: {integrity: sha512-PgabCsoaEEnnOiF6rUhOBXgYoLFIrHWP6mfLOzuQ1oZ1lwBdTL0hp5ivC4K3Kvz3BD8EipjeQo6l0aty3nr4qQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/android-arm@0.17.19: resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==} engines: {node: '>=12'} @@ -903,6 +940,15 @@ packages: requiresBuild: true optional: true + /@esbuild/android-arm@0.18.3: + resolution: {integrity: sha512-QOn3VIlL6Qv1eHBpQB/s7simaZgGss2ASyxDOwYSLmc6vD0uuizZkuYawHmuLjWEm5wPwp0JQWhbpaYwwGevYw==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/android-x64@0.17.19: resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} engines: {node: '>=12'} @@ -911,6 +957,15 @@ packages: requiresBuild: true optional: true + /@esbuild/android-x64@0.18.3: + resolution: {integrity: sha512-1OkJf8wNX1W5ucbp5HrK+z42b9DINb4ix59oJH/PIsh9cyFMqjgRKtCBXg0zEWhkmP1k3egdfrnS7cDTpLH43g==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/darwin-arm64@0.17.19: resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} engines: {node: '>=12'} @@ -919,6 +974,15 @@ packages: requiresBuild: true optional: true + /@esbuild/darwin-arm64@0.18.3: + resolution: {integrity: sha512-57aofORpY7wDAuMs6DeqpmgSnVfZ63RgGbR/BHdOSTqJgYvHDCMY7/o1myFntl3k0YxtLE3WAm56nMf4qy3UDw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@esbuild/darwin-x64@0.17.19: resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} engines: {node: '>=12'} @@ -927,6 +991,15 @@ packages: requiresBuild: true optional: true + /@esbuild/darwin-x64@0.18.3: + resolution: {integrity: sha512-NVBqMnxT9qvgu7Z322LUDlwjh4GDk6wEePyAQnHF9noxik/WvLFmr5v3Vgz5LSvqFducLCxsdmLztKhdpFW0Gg==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@esbuild/freebsd-arm64@0.17.19: resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} engines: {node: '>=12'} @@ -935,6 +1008,15 @@ packages: requiresBuild: true optional: true + /@esbuild/freebsd-arm64@0.18.3: + resolution: {integrity: sha512-XiLK1AsCk2wKxN7j8h9GXXCs8FPZhp07U0rnpwRkAVSVGgLaIWYSqpTRzKjAfqJiZlp+XKo1HwsmDdICEKB3Dg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/freebsd-x64@0.17.19: resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} engines: {node: '>=12'} @@ -943,6 +1025,15 @@ packages: requiresBuild: true optional: true + /@esbuild/freebsd-x64@0.18.3: + resolution: {integrity: sha512-xyITfrF0G3l1gwR79hvNCCWKQ/16uK14xNNPFgzjbIqF4EpBvhO6l3jrWxXFUW51z6dVIl2Szh3x3uIbBWzH1Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-arm64@0.17.19: resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} engines: {node: '>=12'} @@ -951,6 +1042,15 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-arm64@0.18.3: + resolution: {integrity: sha512-lsKUYVd8L/j2uNs8dhMjMsKC5MHYh77gR9EThu7YCeeFz1XpIkx1I4a7mhoVfPS2VPVD1pMCh+PgxuAHUcEmXw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-arm@0.17.19: resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} engines: {node: '>=12'} @@ -959,6 +1059,15 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-arm@0.18.3: + resolution: {integrity: sha512-fc/T0QHMzvmnlF+kfD6bHLB8u+17gg13260p/E86yYjVoKNFjonL/+Y0GGQjMbFUas9QijqOa7pcR00a9RNkwg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-ia32@0.17.19: resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} engines: {node: '>=12'} @@ -967,6 +1076,15 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-ia32@0.18.3: + resolution: {integrity: sha512-EyfGWeOwRqK5Xj18vok0qv8IFBZ1/+hKV+cqD44oVhGsxHo9TmPtoSiDrWn8Sa2swq/VuO5Aiog6YPDj81oIkA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-loong64@0.17.19: resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==} engines: {node: '>=12'} @@ -975,6 +1093,15 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-loong64@0.18.3: + resolution: {integrity: sha512-PwXkcl3t0kSeYH5RuJIeh/fHOzKZd+ZdifAWzpVO+9TLWArutTFBJvOSkTZ3CcqQqNrTj1Qyo6nqE8MQj/a7cQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-mips64el@0.17.19: resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} engines: {node: '>=12'} @@ -983,6 +1110,15 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-mips64el@0.18.3: + resolution: {integrity: sha512-CRVkkSXf5GQcq7Am2a2tdIn85oqi/bkjuPvhNqcdeTgI0xgNbqLnEPRy2AEGkRuaJWB5uCX1IC4sqnY8ET14Yg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-ppc64@0.17.19: resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} engines: {node: '>=12'} @@ -991,6 +1127,15 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-ppc64@0.18.3: + resolution: {integrity: sha512-t7zK1Cheh0xvzfZbimztiE0wGnpV+YRsBg3tefcEBN3O4GzgLu6fFpA5HxEyVm3hHZW1jAC4OhoGEp7C5Ii6Eg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-riscv64@0.17.19: resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} engines: {node: '>=12'} @@ -999,6 +1144,15 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-riscv64@0.18.3: + resolution: {integrity: sha512-fUZPtyCYih6y4lDYdSM4Yoax4nS7aH0/XixJStys+9tfp5cAlIAZhEVKOOdeGXmQn0IEyiUtlIsPnfObbeDQfQ==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-s390x@0.17.19: resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} engines: {node: '>=12'} @@ -1007,6 +1161,15 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-s390x@0.18.3: + resolution: {integrity: sha512-oIcK2LqHWqfMERqjvaKJ3QJmycHn723HsXIv5gH4iGfmePfSj+gi0ZQv2h4bHUg2bs2gJtV0DlIjGhEuvdgxLw==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-x64@0.17.19: resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} engines: {node: '>=12'} @@ -1015,6 +1178,15 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-x64@0.18.3: + resolution: {integrity: sha512-RW9lpfZ6XZ6f5to2DJPvt0f/4RXEW229Xf++quVoW+YbnPrcapIJChtD/AmZ8cK3hglO/hXxJjs21pV0/l7L5w==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/netbsd-x64@0.17.19: resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} engines: {node: '>=12'} @@ -1023,6 +1195,15 @@ packages: requiresBuild: true optional: true + /@esbuild/netbsd-x64@0.18.3: + resolution: {integrity: sha512-piZ2oBoaq58pKZvhgdV6PemlL30Uhd9GmmOkIGZYgChwNcyVSSl6iMEJxMzU7x44Lk9q+hJ6a343M/iVEMEvxA==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/openbsd-x64@0.17.19: resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} engines: {node: '>=12'} @@ -1031,6 +1212,15 @@ packages: requiresBuild: true optional: true + /@esbuild/openbsd-x64@0.18.3: + resolution: {integrity: sha512-vaMfouYTz/4tKdQsXDccqhV6wgPEr+hfuxdNU5Pl/vQxYTsqcXv5DYEa5Z1RAxCoua5aEB+Uj5V7VT/bM92wxw==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/sunos-x64@0.17.19: resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} engines: {node: '>=12'} @@ -1039,6 +1229,15 @@ packages: requiresBuild: true optional: true + /@esbuild/sunos-x64@0.18.3: + resolution: {integrity: sha512-Fa3rNQQ9q1qwy9u2cdDvuGKy3jmPnPPMDdyy/qbn5d395Pb9hjLYiPzX9BozXMPJDlCNofSY7jN3miM9gyAdHA==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-arm64@0.17.19: resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} engines: {node: '>=12'} @@ -1047,6 +1246,15 @@ packages: requiresBuild: true optional: true + /@esbuild/win32-arm64@0.18.3: + resolution: {integrity: sha512-LPJC8ub+9uzyC6ygVmp00dAqet1q1DsZ/OldGIIBt+y+Ctd1OfnKNlzQgXK8nxwY1G8fAhklFSeSRRgAUJnR0w==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-ia32@0.17.19: resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} engines: {node: '>=12'} @@ -1055,6 +1263,15 @@ packages: requiresBuild: true optional: true + /@esbuild/win32-ia32@0.18.3: + resolution: {integrity: sha512-WtUyRspyxZR6NTc2HG4xd9Wvz8lP4C6OUY1gAqisrf151HvXIxsK0mfAacFJNS7EN2wvPTgjP+SM8vgBOx5+zA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-x64@0.17.19: resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} engines: {node: '>=12'} @@ -1063,13 +1280,22 @@ packages: requiresBuild: true optional: true - /@eslint-community/eslint-utils@4.4.0(eslint@8.41.0): + /@esbuild/win32-x64@0.18.3: + resolution: {integrity: sha512-Z8qCK4BkBm40j5KUM4NrkxYQS0R12cBO1NBVtI4vws6uwh1n/VaNu31Hm+n2cJUWdFbfH57PBghkhm9yLgmPfw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@eslint-community/eslint-utils@4.4.0(eslint@8.42.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 dependencies: - eslint: 8.41.0(supports-color@9.3.1) + eslint: 8.42.0 eslint-visitor-keys: 3.4.1 dev: true @@ -1078,7 +1304,7 @@ packages: engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} dev: true - /@eslint/eslintrc@2.0.3(supports-color@9.3.1): + /@eslint/eslintrc@2.0.3: resolution: {integrity: sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: @@ -1095,13 +1321,13 @@ packages: - supports-color dev: true - /@eslint/js@8.41.0: - resolution: {integrity: sha512-LxcyMGxwmTh2lY9FwHPGWOHmYFCZvbrFCBZL4FzSSsxsRPuhrYUg/49/0KDfW8tnIEaEHtfmn6+NPN+1DqaNmA==} + /@eslint/js@8.42.0: + resolution: {integrity: sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@humanwhocodes/config-array@0.11.8(supports-color@9.3.1): - resolution: {integrity: sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==} + /@humanwhocodes/config-array@0.11.10: + resolution: {integrity: sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==} engines: {node: '>=10.10.0'} dependencies: '@humanwhocodes/object-schema': 1.2.1 @@ -1160,7 +1386,7 @@ packages: /@manypkg/find-root@1.1.0: resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} dependencies: - '@babel/runtime': 7.21.5 + '@babel/runtime': 7.22.5 '@types/node': 12.20.55 find-up: 4.1.0 fs-extra: 8.1.0 @@ -1169,7 +1395,7 @@ packages: /@manypkg/get-packages@1.1.3: resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} dependencies: - '@babel/runtime': 7.21.5 + '@babel/runtime': 7.22.5 '@changesets/types': 4.1.0 '@manypkg/find-root': 1.1.0 fs-extra: 8.1.0 @@ -1285,8 +1511,8 @@ packages: resolution: {integrity: sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==} dev: true - /@types/json-schema@7.0.11: - resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} + /@types/json-schema@7.0.12: + resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==} dev: true /@types/json5@0.0.30: @@ -1324,6 +1550,10 @@ packages: /@types/node@20.2.3: resolution: {integrity: sha512-pg9d0yC4rVNWQzX8U7xb4olIOFuuVL9za3bzMT2pu2SU0SNEi66i2qrvhE2qt0HvkhuCaWJu7pLNOt/Pj8BIrw==} + /@types/node@20.3.1: + resolution: {integrity: sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==} + dev: true + /@types/normalize-package-data@2.4.1: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} dev: true @@ -1380,8 +1610,8 @@ packages: resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} dev: false - /@typescript-eslint/eslint-plugin@5.59.7(@typescript-eslint/parser@5.59.7)(eslint@8.41.0)(supports-color@9.3.1)(typescript@5.0.4): - resolution: {integrity: sha512-BL+jYxUFIbuYwy+4fF86k5vdT9lT0CNJ6HtwrIvGh0PhH8s0yy5rjaKH2fDCrz5ITHy07WCzVGNvAmjJh4IJFA==} + /@typescript-eslint/eslint-plugin@5.59.11(@typescript-eslint/parser@5.59.11)(eslint@8.42.0)(typescript@5.1.3): + resolution: {integrity: sha512-XxuOfTkCUiOSyBWIvHlUraLw/JT/6Io1365RO6ZuI88STKMavJZPNMU0lFcUTeQXEhHiv64CbxYxBNoDVSmghg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: '@typescript-eslint/parser': ^5.0.0 @@ -1392,24 +1622,24 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.5.1 - '@typescript-eslint/parser': 5.59.7(eslint@8.41.0)(supports-color@9.3.1)(typescript@5.0.4) - '@typescript-eslint/scope-manager': 5.59.7 - '@typescript-eslint/type-utils': 5.59.7(eslint@8.41.0)(supports-color@9.3.1)(typescript@5.0.4) - '@typescript-eslint/utils': 5.59.7(eslint@8.41.0)(supports-color@9.3.1)(typescript@5.0.4) + '@typescript-eslint/parser': 5.59.11(eslint@8.42.0)(typescript@5.1.3) + '@typescript-eslint/scope-manager': 5.59.11 + '@typescript-eslint/type-utils': 5.59.11(eslint@8.42.0)(typescript@5.1.3) + '@typescript-eslint/utils': 5.59.11(eslint@8.42.0)(typescript@5.1.3) debug: 4.3.4(supports-color@9.3.1) - eslint: 8.41.0(supports-color@9.3.1) + eslint: 8.42.0 grapheme-splitter: 1.0.4 ignore: 5.2.4 natural-compare-lite: 1.4.0 - semver: 7.5.1 - tsutils: 3.21.0(typescript@5.0.4) - typescript: 5.0.4 + semver: 7.5.2 + tsutils: 3.21.0(typescript@5.1.3) + typescript: 5.1.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser@5.59.7(eslint@8.41.0)(supports-color@9.3.1)(typescript@5.0.4): - resolution: {integrity: sha512-VhpsIEuq/8i5SF+mPg9jSdIwgMBBp0z9XqjiEay+81PYLJuroN+ET1hM5IhkiYMJd9MkTz8iJLt7aaGAgzWUbQ==} + /@typescript-eslint/parser@5.59.11(eslint@8.42.0)(typescript@5.1.3): + resolution: {integrity: sha512-s9ZF3M+Nym6CAZEkJJeO2TFHHDsKAM3ecNkLuH4i4s8/RCPnF5JRip2GyviYkeEAcwGMJxkqG9h2dAsnA1nZpA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -1418,26 +1648,26 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 5.59.7 - '@typescript-eslint/types': 5.59.7 - '@typescript-eslint/typescript-estree': 5.59.7(supports-color@9.3.1)(typescript@5.0.4) + '@typescript-eslint/scope-manager': 5.59.11 + '@typescript-eslint/types': 5.59.11 + '@typescript-eslint/typescript-estree': 5.59.11(typescript@5.1.3) debug: 4.3.4(supports-color@9.3.1) - eslint: 8.41.0(supports-color@9.3.1) - typescript: 5.0.4 + eslint: 8.42.0 + typescript: 5.1.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/scope-manager@5.59.7: - resolution: {integrity: sha512-FL6hkYWK9zBGdxT2wWEd2W8ocXMu3K94i3gvMrjXpx+koFYdYV7KprKfirpgY34vTGzEPPuKoERpP8kD5h7vZQ==} + /@typescript-eslint/scope-manager@5.59.11: + resolution: {integrity: sha512-dHFOsxoLFtrIcSj5h0QoBT/89hxQONwmn3FOQ0GOQcLOOXm+MIrS8zEAhs4tWl5MraxCY3ZJpaXQQdFMc2Tu+Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.59.7 - '@typescript-eslint/visitor-keys': 5.59.7 + '@typescript-eslint/types': 5.59.11 + '@typescript-eslint/visitor-keys': 5.59.11 dev: true - /@typescript-eslint/type-utils@5.59.7(eslint@8.41.0)(supports-color@9.3.1)(typescript@5.0.4): - resolution: {integrity: sha512-ozuz/GILuYG7osdY5O5yg0QxXUAEoI4Go3Do5xeu+ERH9PorHBPSdvD3Tjp2NN2bNLh1NJQSsQu2TPu/Ly+HaQ==} + /@typescript-eslint/type-utils@5.59.11(eslint@8.42.0)(typescript@5.1.3): + resolution: {integrity: sha512-LZqVY8hMiVRF2a7/swmkStMYSoXMFlzL6sXV6U/2gL5cwnLWQgLEG8tjWPpaE4rMIdZ6VKWwcffPlo1jPfk43g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: '*' @@ -1446,23 +1676,23 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 5.59.7(supports-color@9.3.1)(typescript@5.0.4) - '@typescript-eslint/utils': 5.59.7(eslint@8.41.0)(supports-color@9.3.1)(typescript@5.0.4) + '@typescript-eslint/typescript-estree': 5.59.11(typescript@5.1.3) + '@typescript-eslint/utils': 5.59.11(eslint@8.42.0)(typescript@5.1.3) debug: 4.3.4(supports-color@9.3.1) - eslint: 8.41.0(supports-color@9.3.1) - tsutils: 3.21.0(typescript@5.0.4) - typescript: 5.0.4 + eslint: 8.42.0 + tsutils: 3.21.0(typescript@5.1.3) + typescript: 5.1.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/types@5.59.7: - resolution: {integrity: sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A==} + /@typescript-eslint/types@5.59.11: + resolution: {integrity: sha512-epoN6R6tkvBYSc+cllrz+c2sOFWkbisJZWkOE+y3xHtvYaOE6Wk6B8e114McRJwFRjGvYdJwLXQH5c9osME/AA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@typescript-eslint/typescript-estree@5.59.7(supports-color@9.3.1)(typescript@5.0.4): - resolution: {integrity: sha512-4A1NtZ1I3wMN2UGDkU9HMBL+TIQfbrh4uS0WDMMpf3xMRursDbqEf1ahh6vAAe3mObt8k3ZATnezwG4pdtWuUQ==} + /@typescript-eslint/typescript-estree@5.59.11(typescript@5.1.3): + resolution: {integrity: sha512-YupOpot5hJO0maupJXixi6l5ETdrITxeo5eBOeuV7RSKgYdU3G5cxO49/9WRnJq9EMrB7AuTSLH/bqOsXi7wPA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: typescript: '*' @@ -1470,79 +1700,79 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 5.59.7 - '@typescript-eslint/visitor-keys': 5.59.7 + '@typescript-eslint/types': 5.59.11 + '@typescript-eslint/visitor-keys': 5.59.11 debug: 4.3.4(supports-color@9.3.1) globby: 11.1.0 is-glob: 4.0.3 - semver: 7.5.1 - tsutils: 3.21.0(typescript@5.0.4) - typescript: 5.0.4 + semver: 7.5.2 + tsutils: 3.21.0(typescript@5.1.3) + typescript: 5.1.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/utils@5.59.7(eslint@8.41.0)(supports-color@9.3.1)(typescript@5.0.4): - resolution: {integrity: sha512-yCX9WpdQKaLufz5luG4aJbOpdXf/fjwGMcLFXZVPUz3QqLirG5QcwwnIHNf8cjLjxK4qtzTO8udUtMQSAToQnQ==} + /@typescript-eslint/utils@5.59.11(eslint@8.42.0)(typescript@5.1.3): + resolution: {integrity: sha512-didu2rHSOMUdJThLk4aZ1Or8IcO3HzCw/ZvEjTTIfjIrcdd5cvSIwwDy2AOlE7htSNp7QIZ10fLMyRCveesMLg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.41.0) - '@types/json-schema': 7.0.11 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.42.0) + '@types/json-schema': 7.0.12 '@types/semver': 7.5.0 - '@typescript-eslint/scope-manager': 5.59.7 - '@typescript-eslint/types': 5.59.7 - '@typescript-eslint/typescript-estree': 5.59.7(supports-color@9.3.1)(typescript@5.0.4) - eslint: 8.41.0(supports-color@9.3.1) + '@typescript-eslint/scope-manager': 5.59.11 + '@typescript-eslint/types': 5.59.11 + '@typescript-eslint/typescript-estree': 5.59.11(typescript@5.1.3) + eslint: 8.42.0 eslint-scope: 5.1.1 - semver: 7.5.1 + semver: 7.5.2 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/visitor-keys@5.59.7: - resolution: {integrity: sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ==} + /@typescript-eslint/visitor-keys@5.59.11: + resolution: {integrity: sha512-KGYniTGG3AMTuKF9QBD7EIrvufkB6O6uX3knP73xbKLMpH+QRPcgnCxjWXSHjMRuOxFLovljqQgQpR0c7GvjoA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.59.7 + '@typescript-eslint/types': 5.59.11 eslint-visitor-keys: 3.4.1 dev: true - /@vitest/expect@0.31.1: - resolution: {integrity: sha512-BV1LyNvhnX+eNYzJxlHIGPWZpwJFZaCcOIzp2CNG0P+bbetenTupk6EO0LANm4QFt0TTit+yqx7Rxd1qxi/SQA==} + /@vitest/expect@0.32.0: + resolution: {integrity: sha512-VxVHhIxKw9Lux+O9bwLEEk2gzOUe93xuFHy9SzYWnnoYZFYg1NfBtnfnYWiJN7yooJ7KNElCK5YtA7DTZvtXtg==} dependencies: - '@vitest/spy': 0.31.1 - '@vitest/utils': 0.31.1 + '@vitest/spy': 0.32.0 + '@vitest/utils': 0.32.0 chai: 4.3.7 dev: true - /@vitest/runner@0.31.1: - resolution: {integrity: sha512-imWuc82ngOtxdCUpXwtEzZIuc1KMr+VlQ3Ondph45VhWoQWit5yvG/fFcldbnCi8DUuFi+NmNx5ehMUw/cGLUw==} + /@vitest/runner@0.32.0: + resolution: {integrity: sha512-QpCmRxftHkr72xt5A08xTEs9I4iWEXIOCHWhQQguWOKE4QH7DXSKZSOFibuwEIMAD7G0ERvtUyQn7iPWIqSwmw==} dependencies: - '@vitest/utils': 0.31.1 + '@vitest/utils': 0.32.0 concordance: 5.0.4 p-limit: 4.0.0 - pathe: 1.1.0 + pathe: 1.1.1 dev: true - /@vitest/snapshot@0.31.1: - resolution: {integrity: sha512-L3w5uU9bMe6asrNzJ8WZzN+jUTX4KSgCinEJPXyny0o90fG4FPQMV0OWsq7vrCWfQlAilMjDnOF9nP8lidsJ+g==} + /@vitest/snapshot@0.32.0: + resolution: {integrity: sha512-yCKorPWjEnzpUxQpGlxulujTcSPgkblwGzAUEL+z01FTUg/YuCDZ8dxr9sHA08oO2EwxzHXNLjQKWJ2zc2a19Q==} dependencies: magic-string: 0.30.0 - pathe: 1.1.0 + pathe: 1.1.1 pretty-format: 27.5.1 dev: true - /@vitest/spy@0.31.1: - resolution: {integrity: sha512-1cTpt2m9mdo3hRLDyCG2hDQvRrePTDgEJBFQQNz1ydHHZy03EiA6EpFxY+7ODaY7vMRCie+WlFZBZ0/dQWyssQ==} + /@vitest/spy@0.32.0: + resolution: {integrity: sha512-MruAPlM0uyiq3d53BkwTeShXY0rYEfhNGQzVO5GHBmmX3clsxcWp79mMnkOVcV244sNTeDcHbcPFWIjOI4tZvw==} dependencies: - tinyspy: 2.1.0 + tinyspy: 2.1.1 dev: true - /@vitest/utils@0.31.1: - resolution: {integrity: sha512-yFyRD5ilwojsZfo3E0BnH72pSVSuLg2356cN1tCEe/0RtDzxTPYwOomIC+eQbot7m6DRy4tPZw+09mB7NkbMmA==} + /@vitest/utils@0.32.0: + resolution: {integrity: sha512-53yXunzx47MmbuvcOPpLaVljHaeSu1G2dHdmy7+9ngMnQIkBQcvwOcoclWFnxDMxFbnq8exAfh3aKSZaK71J5A==} dependencies: concordance: 5.0.4 loupe: 2.3.6 @@ -1668,6 +1898,7 @@ packages: dependencies: normalize-path: 3.0.0 picomatch: 2.3.1 + dev: false /arg@5.0.2: resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} @@ -1775,11 +2006,11 @@ packages: strip-ansi: 7.0.1 supports-esm: 1.0.0 tsconfig-resolver: 3.0.1 - typescript: 5.0.4 + typescript: 5.1.3 unist-util-visit: 4.1.2 vfile: 5.3.7 - vite: 4.3.8(@types/node@20.2.3)(sass@1.62.1) - vitefu: 0.2.4(vite@4.3.8) + vite: 4.3.9(@types/node@20.2.3)(sass@1.62.1) + vitefu: 0.2.4(vite@4.3.9) yargs-parser: 21.1.1 zod: 3.21.4 transitivePeerDependencies: @@ -1834,6 +2065,7 @@ packages: /binary-extensions@2.2.0: resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} engines: {node: '>=8'} + dev: false /bl@5.1.0: resolution: {integrity: sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==} @@ -1887,8 +2119,8 @@ packages: dependencies: fill-range: 7.0.1 - /breakword@1.0.5: - resolution: {integrity: sha512-ex5W9DoOQ/LUEU3PMdLs9ua/CYZl1678NUkKOdUSi8Aw5F1idieaiRURCBFJCwVcrD1J8Iy3vfWSloaMwO2qFg==} + /breakword@1.0.6: + resolution: {integrity: sha512-yjxDAYyK/pBvws9H4xKYpLDpYKEH6CzrBPAuXq3x18I+c/2MkVtT3qAr7Oloi6Dss9qNhPVueAAVU1CSeNDIXw==} dependencies: wcwidth: 1.0.1 dev: true @@ -2044,6 +2276,7 @@ packages: readdirp: 3.6.0 optionalDependencies: fsevents: 2.3.2 + dev: false /ci-info@3.8.0: resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==} @@ -2133,7 +2366,7 @@ packages: js-string-escape: 1.0.1 lodash: 4.17.21 md5-hex: 3.0.1 - semver: 7.5.1 + semver: 7.5.2 well-known-symbols: 2.0.0 dev: true @@ -2514,6 +2747,36 @@ packages: '@esbuild/win32-ia32': 0.17.19 '@esbuild/win32-x64': 0.17.19 + /esbuild@0.18.3: + resolution: {integrity: sha512-eadWJC4CRpj93+miO5ZBlvCv+m2x6pzyNBznTvUeLFObMmxs1IMd8cCf6qiDVEZuDL6W8W7u+ZNW3GKEfOdDsA==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.18.3 + '@esbuild/android-arm64': 0.18.3 + '@esbuild/android-x64': 0.18.3 + '@esbuild/darwin-arm64': 0.18.3 + '@esbuild/darwin-x64': 0.18.3 + '@esbuild/freebsd-arm64': 0.18.3 + '@esbuild/freebsd-x64': 0.18.3 + '@esbuild/linux-arm': 0.18.3 + '@esbuild/linux-arm64': 0.18.3 + '@esbuild/linux-ia32': 0.18.3 + '@esbuild/linux-loong64': 0.18.3 + '@esbuild/linux-mips64el': 0.18.3 + '@esbuild/linux-ppc64': 0.18.3 + '@esbuild/linux-riscv64': 0.18.3 + '@esbuild/linux-s390x': 0.18.3 + '@esbuild/linux-x64': 0.18.3 + '@esbuild/netbsd-x64': 0.18.3 + '@esbuild/openbsd-x64': 0.18.3 + '@esbuild/sunos-x64': 0.18.3 + '@esbuild/win32-arm64': 0.18.3 + '@esbuild/win32-ia32': 0.18.3 + '@esbuild/win32-x64': 0.18.3 + dev: true + /escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} @@ -2531,16 +2794,16 @@ packages: resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} engines: {node: '>=12'} - /eslint-config-prettier@8.8.0(eslint@8.41.0): + /eslint-config-prettier@8.8.0(eslint@8.42.0): resolution: {integrity: sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==} hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: - eslint: 8.41.0(supports-color@9.3.1) + eslint: 8.42.0 dev: true - /eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.8.0)(eslint@8.41.0)(prettier@2.8.8): + /eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.8.0)(eslint@8.42.0)(prettier@2.8.8): resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==} engines: {node: '>=12.0.0'} peerDependencies: @@ -2551,8 +2814,8 @@ packages: eslint-config-prettier: optional: true dependencies: - eslint: 8.41.0(supports-color@9.3.1) - eslint-config-prettier: 8.8.0(eslint@8.41.0) + eslint: 8.42.0 + eslint-config-prettier: 8.8.0(eslint@8.42.0) prettier: 2.8.8 prettier-linter-helpers: 1.0.0 dev: true @@ -2578,16 +2841,16 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint@8.41.0(supports-color@9.3.1): - resolution: {integrity: sha512-WQDQpzGBOP5IrXPo4Hc0814r4/v2rrIsB0rhT7jtunIalgg6gYXWhRMOejVO8yH21T/FGaxjmFjBMNqcIlmH1Q==} + /eslint@8.42.0: + resolution: {integrity: sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.41.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.42.0) '@eslint-community/regexpp': 4.5.1 - '@eslint/eslintrc': 2.0.3(supports-color@9.3.1) - '@eslint/js': 8.41.0 - '@humanwhocodes/config-array': 0.11.8(supports-color@9.3.1) + '@eslint/eslintrc': 2.0.3 + '@eslint/js': 8.42.0 + '@humanwhocodes/config-array': 0.11.10 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 ajv: 6.12.6 @@ -3216,6 +3479,7 @@ packages: /immutable@4.3.0: resolution: {integrity: sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==} + dev: false /import-fresh@3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} @@ -3285,6 +3549,7 @@ packages: engines: {node: '>=8'} dependencies: binary-extensions: 2.2.0 + dev: false /is-boolean-object@1.1.2: resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} @@ -4191,11 +4456,11 @@ packages: engines: {node: '>= 8.0.0'} dev: true - /mlly@1.2.1: - resolution: {integrity: sha512-1aMEByaWgBPEbWV2BOPEMySRrzl7rIHXmQxam4DM8jVjalTQDjpN2ZKOLUrwyhfZQO7IXHml2StcHMhooDeEEQ==} + /mlly@1.3.0: + resolution: {integrity: sha512-HT5mcgIQKkOrZecOjOX3DJorTikWXwsBfpcr/MGBkhfWcjiqvnaL/9ppxvIUXfjT6xt4DVIAsN9fMUz1ev4bIw==} dependencies: acorn: 8.8.2 - pathe: 1.1.0 + pathe: 1.1.1 pkg-types: 1.0.3 ufo: 1.1.2 dev: true @@ -4267,13 +4532,14 @@ packages: dependencies: hosted-git-info: 4.1.0 is-core-module: 2.12.1 - semver: 7.5.1 + semver: 7.5.2 validate-npm-package-license: 3.0.4 dev: true /normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} + dev: false /npm-run-all@4.1.5: resolution: {integrity: sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==} @@ -4466,7 +4732,7 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} dependencies: - '@babel/code-frame': 7.21.4 + '@babel/code-frame': 7.22.5 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -4530,8 +4796,8 @@ packages: engines: {node: '>=8'} dev: true - /pathe@1.1.0: - resolution: {integrity: sha512-ODbEPR0KKHqECXW1GoxdDb+AZvULmXjVPy4rt+pGo2+TnjJTIPJQSVS6N63n8T2Ip+syHhbn52OewKicV0373w==} + /pathe@1.1.1: + resolution: {integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==} dev: true /pathval@1.1.1: @@ -4570,8 +4836,8 @@ packages: resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} dependencies: jsonc-parser: 3.2.0 - mlly: 1.2.1 - pathe: 1.1.0 + mlly: 1.3.0 + pathe: 1.1.1 dev: true /pkg-up@3.1.0: @@ -4581,8 +4847,8 @@ packages: find-up: 3.0.0 dev: false - /postcss@8.4.23: - resolution: {integrity: sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==} + /postcss@8.4.24: + resolution: {integrity: sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==} engines: {node: ^10 || ^12 || >=14} dependencies: nanoid: 3.3.6 @@ -4782,6 +5048,7 @@ packages: engines: {node: '>=8.10.0'} dependencies: picomatch: 2.3.1 + dev: false /redent@3.0.0: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} @@ -4970,8 +5237,8 @@ packages: glob: 7.2.3 dev: true - /rollup@3.23.0: - resolution: {integrity: sha512-h31UlwEi7FHihLe1zbk+3Q7z1k/84rb9BSwmBSr/XjOCEaBJ2YyedQDuM0t/kfOS0IxM+vk1/zI9XxYj9V+NJQ==} + /rollup@3.25.1: + resolution: {integrity: sha512-tywOR+rwIt5m2ZAWSe5AIJcTat8vGlnPFAv15ycCrw33t6iFsXZ6mzHVFh2psSjxQPmI+xgzMZZizUAukBI4aQ==} engines: {node: '>=14.18.0', npm: '>=8.0.0'} hasBin: true optionalDependencies: @@ -5030,6 +5297,7 @@ packages: chokidar: 3.5.3 immutable: 4.3.0 source-map-js: 1.0.2 + dev: false /sax@1.2.4: resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==} @@ -5065,6 +5333,15 @@ packages: hasBin: true dependencies: lru-cache: 6.0.0 + dev: false + + /semver@7.5.2: + resolution: {integrity: sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true /server-destroy@1.0.1: resolution: {integrity: sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ==} @@ -5154,7 +5431,7 @@ packages: hasBin: true dependencies: array.prototype.flat: 1.3.1 - breakword: 1.0.5 + breakword: 1.0.6 grapheme-splitter: 1.0.4 strip-ansi: 6.0.1 wcwidth: 1.0.1 @@ -5415,8 +5692,8 @@ packages: engines: {node: '>=14.0.0'} dev: true - /tinyspy@2.1.0: - resolution: {integrity: sha512-7eORpyqImoOvkQJCSkL0d0mB4NHHIFAy4b1u8PHdDa7SjGS2njzl6/lyGoZLm+eyYEtlUmFGE0rFj66SWxZgQQ==} + /tinyspy@2.1.1: + resolution: {integrity: sha512-XPJL2uSzcOyBMky6OFrusqWlzfFrXtE0hPuMgW8A2HmaqrPo4ZQHRN/V0QXN3FSjKxpsbRrFc5LI7KOwBsT1/w==} engines: {node: '>=14.0.0'} dev: true @@ -5484,14 +5761,14 @@ packages: resolution: {integrity: sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA==} dev: false - /tsutils@3.21.0(typescript@5.0.4): + /tsutils@3.21.0(typescript@5.1.3): resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} peerDependencies: typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' dependencies: tslib: 1.14.1 - typescript: 5.0.4 + typescript: 5.1.3 dev: true /tty-table@4.2.1: @@ -5557,9 +5834,9 @@ packages: is-typed-array: 1.1.10 dev: true - /typescript@5.0.4: - resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==} - engines: {node: '>=12.20'} + /typescript@5.1.3: + resolution: {integrity: sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==} + engines: {node: '>=14.17'} hasBin: true /ufo@1.1.2: @@ -5720,17 +5997,17 @@ packages: vfile-message: 3.1.4 dev: false - /vite-node@0.31.1(@types/node@20.2.3)(supports-color@9.3.1): - resolution: {integrity: sha512-BajE/IsNQ6JyizPzu9zRgHrBwczkAs0erQf/JRpgTIESpKvNj9/Gd0vxX905klLkb0I0SJVCKbdrl5c6FnqYKA==} + /vite-node@0.32.0(@types/node@20.3.1)(supports-color@9.3.1): + resolution: {integrity: sha512-220P/y8YacYAU+daOAqiGEFXx2A8AwjadDzQqos6wSukjvvTWNqleJSwoUn0ckyNdjHIKoxn93Nh1vWBqEKr3Q==} engines: {node: '>=v14.18.0'} hasBin: true dependencies: cac: 6.7.14 debug: 4.3.4(supports-color@9.3.1) - mlly: 1.2.1 - pathe: 1.1.0 + mlly: 1.3.0 + pathe: 1.1.1 picocolors: 1.0.0 - vite: 4.3.8(@types/node@20.2.3)(sass@1.62.1) + vite: 4.3.9(@types/node@20.3.1) transitivePeerDependencies: - '@types/node' - less @@ -5741,8 +6018,8 @@ packages: - terser dev: true - /vite@4.3.8(@types/node@20.2.3)(sass@1.62.1): - resolution: {integrity: sha512-uYB8PwN7hbMrf4j1xzGDk/lqjsZvCDbt/JC5dyfxc19Pg8kRm14LinK/uq+HSLNswZEoKmweGdtpbnxRtrAXiQ==} + /vite@4.3.9(@types/node@20.2.3)(sass@1.62.1): + resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true peerDependencies: @@ -5768,13 +6045,47 @@ packages: dependencies: '@types/node': 20.2.3 esbuild: 0.17.19 - postcss: 8.4.23 - rollup: 3.23.0 + postcss: 8.4.24 + rollup: 3.25.1 sass: 1.62.1 optionalDependencies: fsevents: 2.3.2 + dev: false - /vitefu@0.2.4(vite@4.3.8): + /vite@4.3.9(@types/node@20.3.1): + resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 20.3.1 + esbuild: 0.17.19 + postcss: 8.4.24 + rollup: 3.25.1 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /vitefu@0.2.4(vite@4.3.9): resolution: {integrity: sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==} peerDependencies: vite: ^3.0.0 || ^4.0.0 @@ -5782,23 +6093,23 @@ packages: vite: optional: true dependencies: - vite: 4.3.8(@types/node@20.2.3)(sass@1.62.1) + vite: 4.3.9(@types/node@20.2.3)(sass@1.62.1) dev: false - /vitest-fetch-mock@0.2.2(vitest@0.31.1): + /vitest-fetch-mock@0.2.2(vitest@0.32.0): resolution: {integrity: sha512-XmH6QgTSjCWrqXoPREIdbj40T7i1xnGmAsTAgfckoO75W1IEHKR8hcPCQ7SO16RsdW1t85oUm6pcQRLeBgjVYQ==} engines: {node: '>=14.14.0'} peerDependencies: vitest: '>=0.16.0' dependencies: cross-fetch: 3.1.6 - vitest: 0.31.1(supports-color@9.3.1) + vitest: 0.32.0(supports-color@9.3.1) transitivePeerDependencies: - encoding dev: true - /vitest@0.31.1(supports-color@9.3.1): - resolution: {integrity: sha512-/dOoOgzoFk/5pTvg1E65WVaobknWREN15+HF+0ucudo3dDG/vCZoXTQrjIfEaWvQXmqScwkRodrTbM/ScMpRcQ==} + /vitest@0.32.0(supports-color@9.3.1): + resolution: {integrity: sha512-SW83o629gCqnV3BqBnTxhB10DAwzwEx3z+rqYZESehUB+eWsJxwcBQx7CKy0otuGMJTYh7qCVuUX23HkftGl/Q==} engines: {node: '>=v14.18.0'} hasBin: true peerDependencies: @@ -5830,12 +6141,12 @@ packages: dependencies: '@types/chai': 4.3.5 '@types/chai-subset': 1.3.3 - '@types/node': 20.2.3 - '@vitest/expect': 0.31.1 - '@vitest/runner': 0.31.1 - '@vitest/snapshot': 0.31.1 - '@vitest/spy': 0.31.1 - '@vitest/utils': 0.31.1 + '@types/node': 20.3.1 + '@vitest/expect': 0.32.0 + '@vitest/runner': 0.32.0 + '@vitest/snapshot': 0.32.0 + '@vitest/spy': 0.32.0 + '@vitest/utils': 0.32.0 acorn: 8.8.2 acorn-walk: 8.2.0 cac: 6.7.14 @@ -5844,14 +6155,14 @@ packages: debug: 4.3.4(supports-color@9.3.1) local-pkg: 0.4.3 magic-string: 0.30.0 - pathe: 1.1.0 + pathe: 1.1.1 picocolors: 1.0.0 std-env: 3.3.3 strip-literal: 1.0.1 tinybench: 2.5.0 tinypool: 0.5.0 - vite: 4.3.8(@types/node@20.2.3)(sass@1.62.1) - vite-node: 0.31.1(@types/node@20.2.3)(supports-color@9.3.1) + vite: 4.3.9(@types/node@20.3.1) + vite-node: 0.32.0(@types/node@20.3.1)(supports-color@9.3.1) why-is-node-running: 2.2.2 transitivePeerDependencies: - less