diff --git a/.changeset/red-fans-act.md b/.changeset/red-fans-act.md new file mode 100644 index 000000000..fbec3f6b5 --- /dev/null +++ b/.changeset/red-fans-act.md @@ -0,0 +1,5 @@ +--- +"openapi-fetch": patch +--- + +Fix params.header inference diff --git a/packages/openapi-fetch/package.json b/packages/openapi-fetch/package.json index a36be1f75..d331ccd77 100644 --- a/packages/openapi-fetch/package.json +++ b/packages/openapi-fetch/package.json @@ -58,7 +58,7 @@ }, "devDependencies": { "del-cli": "^5.0.0", - "esbuild": "^0.18.11", + "esbuild": "^0.18.16", "nanostores": "^0.9.3", "openapi-typescript": "*", "prettier": "^2.8.8", diff --git a/packages/openapi-fetch/src/index.test.ts b/packages/openapi-fetch/src/index.test.ts index 0f75c5c77..2ab390c0f 100644 --- a/packages/openapi-fetch/src/index.test.ts +++ b/packages/openapi-fetch/src/index.test.ts @@ -85,106 +85,204 @@ describe("client", () => { } }); - it("requires path params", async () => { - const client = createClient({ baseUrl: "https://myapi.com/v1" }); - mockFetch({ status: 200, body: JSON.stringify({ message: "OK" }) }); + describe("params", () => { + it("path", async () => { + const client = createClient({ baseUrl: "https://myapi.com/v1" }); + mockFetch({ status: 200, body: JSON.stringify({ message: "OK" }) }); - // expect error on missing 'params' - // @ts-expect-error - await client.get("/blogposts/{post_id}", {}); + // expect error on missing 'params' + // @ts-expect-error + await client.get("/blogposts/{post_id}", {}); - // expect error on empty params - // @ts-expect-error - await client.get("/blogposts/{post_id}", { params: {} }); + // expect error on empty params + // @ts-expect-error + await client.get("/blogposts/{post_id}", { params: {} }); - // expect error on empty params.path - // @ts-expect-error - await client.get("/blogposts/{post_id}", { params: { path: {} } }); + // expect error on empty params.path + // @ts-expect-error + await client.get("/blogposts/{post_id}", { params: { path: {} } }); - // expect error on mismatched type (number v string) - // @ts-expect-error - await client.get("/blogposts/{post_id}", { params: { path: { post_id: 1234 } }, query: {} }); + // expect error on mismatched type (number v string) + // @ts-expect-error + await client.get("/blogposts/{post_id}", { params: { path: { post_id: 1234 } } }); - // (no error) - await client.get("/blogposts/{post_id}", { params: { path: { post_id: "1234" }, query: {} } }); - }); + // (no error) + await client.get("/blogposts/{post_id}", { params: { path: { post_id: "1234" } } }); - it("requires necessary requestBodies", async () => { - const client = createClient({ baseUrl: "https://myapi.com/v1" }); - mockFetch({ status: 200, body: JSON.stringify({ message: "OK" }) }); + // expect param passed correctly + const lastCall = fetchMocker.mock.calls[fetchMocker.mock.calls.length - 1]; + expect(lastCall[0]).toBe("https://myapi.com/v1/blogposts/1234"); + }); - // expect error on missing `body` - // @ts-expect-error - await client.get("/blogposts", {}); + it("header", async () => { + const client = createClient({ baseUrl: "https://myapi.com/v1" }); + mockFetch({ status: 200, body: JSON.stringify({ status: "success" }) }); - // expect error on missing fields - // @ts-expect-error - await client.put("/blogposts", { body: { title: "Foo" } }); + // expet error on missing header + // @ts-expect-error + await client.get("/header-params", {}); - // expect present body to be good enough (all fields optional) - // (no error) - await client.put("/blogposts", { - body: { title: "Foo", body: "Bar", publish_date: new Date("2023-04-01T12:00:00Z").getTime() }, - }); - }); + // expect error on incorrect header + // @ts-expect-error + await client.get("/header-params", { params: { header: { foo: "bar" } } }); - it("allows optional requestBody", async () => { - const mockData = { status: "success" }; - const client = createClient(); - mockFetch({ status: 201, body: JSON.stringify(mockData) }); + // expect error on mismatched type + // @ts-expect-error + await client.get("/header-params", { params: { header: { "x-required-header": true } } }); - // 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" } }, - }); + // (no error) + await client.get("/header-params", { params: { header: { "x-required-header": "correct" } } }); - // 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 param passed correctly + const lastCall = fetchMocker.mock.calls[fetchMocker.mock.calls.length - 1]; + expect(lastCall[1].headers.get("x-required-header")).toBe("correct"); }); - // 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" }, + describe("query", () => { + it("basic", async () => { + const client = createClient(); + mockFetchOnce({ status: 200, body: "{}" }); + await client.get("/blogposts/{post_id}", { + params: { + path: { post_id: "my-post" }, + query: { version: 2, format: "json" }, + }, + }); + + expect(fetchMocker.mock.calls[0][0]).toBe("/blogposts/my-post?version=2&format=json"); + }); + + it("array params", async () => { + const client = createClient(); + mockFetchOnce({ status: 200, body: "{}" }); + await client.get("/blogposts", { + params: { + query: { tags: ["one", "two", "three"] }, + }, + }); + + expect(fetchMocker.mock.calls[0][0]).toBe("/blogposts?tags=one%2Ctwo%2Cthree"); + }); + + it("empty/null params", async () => { + const client = createClient(); + mockFetchOnce({ status: 200, body: "{}" }); + await client.get("/blogposts/{post_id}", { + params: { + path: { post_id: "my-post" }, + query: { version: undefined, format: null as any }, + }, + }); + + expect(fetchMocker.mock.calls[0][0]).toBe("/blogposts/my-post"); + }); + + describe("querySerializer", () => { + it("custom", async () => { + const client = createClient(); + mockFetchOnce({ status: 200, body: "{}" }); + await client.get("/blogposts/{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("/blogposts/my-post?alpha=2&beta=json"); + }); + + it("applies global serializer", async () => { + const client = createClient({ + querySerializer: (q) => `alpha=${q.version}&beta=${q.format}`, + }); + mockFetchOnce({ status: 200, body: "{}" }); + await client.get("/blogposts/{post_id}", { + params: { + path: { post_id: "my-post" }, + query: { version: 2, format: "json" }, + }, + }); + + expect(fetchMocker.mock.calls[0][0]).toBe("/blogposts/my-post?alpha=2&beta=json"); + }); + + it("overrides global serializer if provided", async () => { + const client = createClient({ + querySerializer: () => "query", + }); + mockFetchOnce({ status: 200, body: "{}" }); + await client.get("/blogposts/{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("/blogposts/my-post?alpha=2&beta=json"); + }); + }); }); }); - it("request body type when optional", async () => { - mockFetch({ status: 201, body: "{}" }); - const client = createClient(); + describe("body", () => { + it("requires necessary requestBodies", async () => { + const client = createClient({ baseUrl: "https://myapi.com/v1" }); + mockFetch({ status: 200, body: JSON.stringify({ message: "OK" }) }); - // expect error on wrong body type - // @ts-expect-error - await client.put("/blogposts-optional", { body: { error: true } }); + // expect error on missing `body` + // @ts-expect-error + await client.get("/blogposts", {}); - // (no error) - await client.put("/blogposts-optional", { - body: { - title: "", - publish_date: 3, - body: "", - }, + // expect error on missing fields + // @ts-expect-error + await client.put("/blogposts", { body: { title: "Foo" } }); + + // expect present body to be good enough (all fields optional) + // (no error) + await client.put("/blogposts", { + body: { title: "Foo", body: "Bar", publish_date: new Date("2023-04-01T12:00:00Z").getTime() }, + }); }); - }); - it("request body type when optional inline", async () => { - mockFetch({ status: 201, body: "{}" }); - const client = createClient(); + it("requestBody (inline)", async () => { + mockFetch({ status: 201, body: "{}" }); + const client = createClient(); - // expect error on wrong body type - // @ts-expect-error - await client.put("/blogposts-optional-inline", { body: { error: true } }); + // expect error on wrong body type + // @ts-expect-error + await client.put("/blogposts-optional-inline", { body: { error: true } }); + + // (no error) + await client.put("/blogposts-optional-inline", { + body: { + title: "", + publish_date: 3, + body: "", + }, + }); + }); - // (no error) - await client.put("/blogposts-optional-inline", { - body: { - title: "", - publish_date: 3, - body: "", - }, + it("requestBody with required: false", async () => { + mockFetch({ status: 201, body: "{}" }); + const client = createClient(); + + // assert missing `body` doesn’t raise a TS error + await client.put("/blogposts-optional", {}); + + // assert error on type mismatch + // @ts-expect-error + await client.put("/blogposts-optional", { body: { error: true } }); + + // (no error) + await client.put("/blogposts-optional", { + body: { + title: "", + publish_date: 3, + body: "", + }, + }); }); }); }); @@ -354,91 +452,6 @@ describe("client", () => { expect(data instanceof Buffer).toBe(true); }); }); - - describe("querySerializer", () => { - it("default", async () => { - const client = createClient(); - mockFetchOnce({ status: 200, body: "{}" }); - await client.get("/blogposts/{post_id}", { - params: { - path: { post_id: "my-post" }, - query: { version: 2, format: "json" }, - }, - }); - - expect(fetchMocker.mock.calls[0][0]).toBe("/blogposts/my-post?version=2&format=json"); - }); - - it("default (array params)", async () => { - const client = createClient(); - mockFetchOnce({ status: 200, body: "{}" }); - await client.get("/blogposts", { - params: { - query: { tags: ["one", "two", "three"] }, - }, - }); - - expect(fetchMocker.mock.calls[0][0]).toBe("/blogposts?tags=one%2Ctwo%2Cthree"); - }); - - it("default (with empty params)", async () => { - const client = createClient(); - mockFetchOnce({ status: 200, body: "{}" }); - await client.get("/blogposts/{post_id}", { - params: { - path: { post_id: "my-post" }, - query: { version: undefined, format: null as any }, - }, - }); - - expect(fetchMocker.mock.calls[0][0]).toBe("/blogposts/my-post"); - }); - - it("custom", async () => { - const client = createClient(); - mockFetchOnce({ status: 200, body: "{}" }); - await client.get("/blogposts/{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("/blogposts/my-post?alpha=2&beta=json"); - }); - - it("applies global serializer", async () => { - const client = createClient({ - querySerializer: (q) => `alpha=${q.version}&beta=${q.format}`, - }); - mockFetchOnce({ status: 200, body: "{}" }); - await client.get("/blogposts/{post_id}", { - params: { - path: { post_id: "my-post" }, - query: { version: 2, format: "json" }, - }, - }); - - expect(fetchMocker.mock.calls[0][0]).toBe("/blogposts/my-post?alpha=2&beta=json"); - }); - - it("overrides global serializer if provided", async () => { - const client = createClient({ - querySerializer: () => "query", - }); - mockFetchOnce({ status: 200, body: "{}" }); - await client.get("/blogposts/{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("/blogposts/my-post?alpha=2&beta=json"); - }); - }); }); describe("get()", () => { @@ -454,7 +467,7 @@ describe("client", () => { const client = createClient(); mockFetchOnce({ status: 200, body: JSON.stringify(mockData) }); const { data, error, response } = await client.get("/blogposts/{post_id}", { - params: { path: { post_id: "my-post" }, query: {} }, + params: { path: { post_id: "my-post" } }, }); // assert correct URL was called @@ -473,10 +486,7 @@ describe("client", () => { const client = createClient(); mockFetchOnce({ status: 404, body: JSON.stringify(mockError) }); const { data, error, response } = await client.get("/blogposts/{post_id}", { - params: { - path: { post_id: "my-post" }, - query: {}, - }, + params: { path: { post_id: "my-post" } }, }); // assert correct URL was called @@ -643,7 +653,7 @@ describe("examples", () => { // assert initial call is unauthenticated mockFetchOnce({ status: 200, body: "{}" }); - await client.get().get("/blogposts/{post_id}", { params: { path: { post_id: "1234" }, query: {} } }); + await client.get().get("/blogposts/{post_id}", { params: { path: { post_id: "1234" } } }); expect(fetchMocker.mock.calls[0][1].headers.get("authorization")).toBeNull(); // assert after setting token, client is authenticated @@ -655,7 +665,7 @@ describe("examples", () => { resolve(); }, 0) ); - await client.get().get("/blogposts/{post_id}", { params: { path: { post_id: "1234" }, query: {} } }); + await client.get().get("/blogposts/{post_id}", { params: { path: { post_id: "1234" } } }); expect(fetchMocker.mock.calls[1][1].headers.get("authorization")).toBe(`Bearer ${tokenVal}`); }); @@ -672,7 +682,7 @@ describe("examples", () => { // assert initial call is unauthenticated mockFetchOnce({ status: 200, body: "{}" }); - await client.get("/blogposts/{post_id}", { params: { path: { post_id: "1234" }, query: {} } }); + await client.get("/blogposts/{post_id}", { params: { path: { post_id: "1234" } } }); expect(fetchMocker.mock.calls[0][1].headers.get("authorization")).toBeNull(); // assert after setting token, client is authenticated @@ -684,7 +694,7 @@ describe("examples", () => { resolve(); }, 0) ); - await client.get("/blogposts/{post_id}", { params: { path: { post_id: "1234" }, query: {} } }); + await client.get("/blogposts/{post_id}", { params: { path: { post_id: "1234" } } }); expect(fetchMocker.mock.calls[1][1].headers.get("authorization")).toBe(`Bearer ${tokenVal}`); }); }); diff --git a/packages/openapi-fetch/src/index.ts b/packages/openapi-fetch/src/index.ts index cf2c6b8ad..0df0cecf9 100644 --- a/packages/openapi-fetch/src/index.ts +++ b/packages/openapi-fetch/src/index.ts @@ -65,36 +65,6 @@ export type FetchResponse = | { data: T extends { responses: any } ? NonNullable, MediaType>> : unknown; error?: never; response: Response } | { data?: never; error: T extends { responses: any } ? NonNullable, MediaType>> : unknown; response: Response }; -/** serialize query params to string */ -export function defaultQuerySerializer(q: T): 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, v); - } - } - return search.toString(); -} - -/** serialize body object to string */ -export function defaultBodySerializer(body: T): string { - return JSON.stringify(body); -} - -/** 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, querySerializer: globalQuerySerializer, bodySerializer: globalBodySerializer, ...options } = clientOptions; @@ -108,25 +78,13 @@ export default function createClient(clientOptions: ClientOpti // URL const finalURL = createFinalURL(url as string, { baseUrl: options.baseUrl, params, querySerializer }); - - // headers - const baseHeaders = new Headers(defaultHeaders); // clone defaults (don’t overwrite!) - const headerOverrides = new Headers(headers); - for (const [k, v] of headerOverrides.entries()) { - if (v === undefined || v === null) baseHeaders.delete(k); // allow `undefined` | `null` to erase value - else baseHeaders.set(k, v); - } + const finalHeaders = mergeHeaders(defaultHeaders as any, headers as any, (params as any).header); // fetch! - const requestInit: RequestInit = { - redirect: "follow", - ...options, - ...init, - headers: baseHeaders, - }; + const requestInit: RequestInit = { redirect: "follow", ...options, ...init, headers: finalHeaders }; if (requestBody) requestInit.body = bodySerializer(requestBody as any); // remove `Content-Type` if serialized body is FormData; browser will correctly set Content-Type & boundary expression - if (requestInit.body instanceof FormData) baseHeaders.delete("Content-Type"); + if (requestInit.body instanceof FormData) finalHeaders.delete("Content-Type"); const response = await fetch(finalURL, requestInit); // handle empty content @@ -190,3 +148,50 @@ export default function createClient(clientOptions: ClientOpti }, }; } + +// utils + +/** serialize query params to string */ +export function defaultQuerySerializer(q: T): 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, v); + } + } + return search.toString(); +} + +/** serialize body object to string */ +export function defaultBodySerializer(body: T): string { + return JSON.stringify(body); +} + +/** 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; +} + +/** merge headers a and b, with b taking priority */ +export function mergeHeaders(...allHeaders: (Record | Headers)[]): Headers { + const headers = new Headers(); + for (const headerSet of allHeaders) { + if (!headerSet || typeof headerSet !== "object") continue; + const iterator = headerSet instanceof Headers ? headerSet.entries() : Object.entries(headerSet); + for (const [k, v] of iterator) { + if (v !== undefined && v !== null) { + headers.set(k, v as any); + } + } + } + return headers; +} diff --git a/packages/openapi-fetch/test/v1.d.ts b/packages/openapi-fetch/test/v1.d.ts index c935a8222..664c8a40c 100644 --- a/packages/openapi-fetch/test/v1.d.ts +++ b/packages/openapi-fetch/test/v1.d.ts @@ -109,6 +109,9 @@ export interface paths { }; }; }; + "/header-params": { + get: operations["getHeaderParams"]; + }; "/self": { get: { responses: { @@ -337,7 +340,7 @@ export interface components { }; }; }; - CreateTag?: { + CreateTag: { content: { "application/json": { description?: string; @@ -379,4 +382,23 @@ export interface components { export type external = Record; -export type operations = Record; +export interface operations { + + getHeaderParams: { + parameters: { + header: { + "x-required-header": string; + }; + }; + responses: { + 200: { + content: { + "application/json": { + status: string; + }; + }; + }; + 500: components["responses"]["Error"]; + }; + }; +} diff --git a/packages/openapi-fetch/test/v1.yaml b/packages/openapi-fetch/test/v1.yaml index c22075742..ac5af8621 100644 --- a/packages/openapi-fetch/test/v1.yaml +++ b/packages/openapi-fetch/test/v1.yaml @@ -101,6 +101,28 @@ paths: $ref: '#/components/responses/CreatePost' 500: $ref: '#/components/responses/Error' + /header-params: + get: + operationId: getHeaderParams + parameters: + - name: x-required-header + in: header + required: true + schema: + type: string + responses: + 200: + content: + application/json: + schema: + type: object + properties: + status: + type: string + required: + - status + 500: + $ref: '#/components/responses/Error' /self: get: responses: @@ -280,6 +302,7 @@ components: - body - publish_date CreateTag: + required: true content: application/json: schema: diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bbf26257e..f94dd34bf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -58,7 +58,7 @@ importers: version: 3.5.1 '@docsearch/react': specifier: ^3.5.1 - version: 3.5.1(@algolia/client-search@4.18.0)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0)(search-insights@2.6.0) + version: 3.5.1(@algolia/client-search@4.18.0)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0)(search-insights@2.7.0) '@types/react': specifier: ^18.2.14 version: 18.2.14 @@ -100,8 +100,8 @@ importers: specifier: ^5.0.0 version: 5.0.0 esbuild: - specifier: ^0.18.11 - version: 0.18.11 + specifier: ^0.18.16 + version: 0.18.16 nanostores: specifier: ^0.9.3 version: 0.9.3 @@ -116,7 +116,7 @@ importers: version: 5.1.6 vitest: specifier: ^0.33.0 - version: 0.33.0(supports-color@9.4.0) + version: 0.33.0 vitest-fetch-mock: specifier: ^0.2.2 version: 0.2.2(vitest@0.33.0) @@ -177,10 +177,10 @@ packages: engines: {node: '>=0.10.0'} dev: true - /@algolia/autocomplete-core@1.9.3(@algolia/client-search@4.18.0)(algoliasearch@4.18.0)(search-insights@2.6.0): + /@algolia/autocomplete-core@1.9.3(@algolia/client-search@4.18.0)(algoliasearch@4.18.0)(search-insights@2.7.0): resolution: {integrity: sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==} dependencies: - '@algolia/autocomplete-plugin-algolia-insights': 1.9.3(@algolia/client-search@4.18.0)(algoliasearch@4.18.0)(search-insights@2.6.0) + '@algolia/autocomplete-plugin-algolia-insights': 1.9.3(@algolia/client-search@4.18.0)(algoliasearch@4.18.0)(search-insights@2.7.0) '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.18.0)(algoliasearch@4.18.0) transitivePeerDependencies: - '@algolia/client-search' @@ -188,13 +188,13 @@ packages: - search-insights dev: false - /@algolia/autocomplete-plugin-algolia-insights@1.9.3(@algolia/client-search@4.18.0)(algoliasearch@4.18.0)(search-insights@2.6.0): + /@algolia/autocomplete-plugin-algolia-insights@1.9.3(@algolia/client-search@4.18.0)(algoliasearch@4.18.0)(search-insights@2.7.0): resolution: {integrity: sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==} peerDependencies: search-insights: '>= 1 < 3' dependencies: '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.18.0)(algoliasearch@4.18.0) - search-insights: 2.6.0 + search-insights: 2.7.0 transitivePeerDependencies: - '@algolia/client-search' - algoliasearch @@ -882,7 +882,7 @@ packages: resolution: {integrity: sha512-2Pu9HDg/uP/IT10rbQ+4OrTQuxIWdKVUEdcw9/w7kZJv9NeHS6skJx1xuRiFyoGKwAzcHXnLp7csE99sj+O1YA==} dev: false - /@docsearch/react@3.5.1(@algolia/client-search@4.18.0)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0)(search-insights@2.6.0): + /@docsearch/react@3.5.1(@algolia/client-search@4.18.0)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0)(search-insights@2.7.0): resolution: {integrity: sha512-t5mEODdLzZq4PTFAm/dvqcvZFdPDMdfPE5rJS5SC8OUq9mPzxEy6b+9THIqNM9P0ocCb4UC5jqBrxKclnuIbzQ==} peerDependencies: '@types/react': '>= 16.8.0 < 19.0.0' @@ -896,7 +896,7 @@ packages: react-dom: optional: true dependencies: - '@algolia/autocomplete-core': 1.9.3(@algolia/client-search@4.18.0)(algoliasearch@4.18.0)(search-insights@2.6.0) + '@algolia/autocomplete-core': 1.9.3(@algolia/client-search@4.18.0)(algoliasearch@4.18.0)(search-insights@2.7.0) '@algolia/autocomplete-preset-algolia': 1.9.3(@algolia/client-search@4.18.0)(algoliasearch@4.18.0) '@docsearch/css': 3.5.1 '@types/react': 18.2.14 @@ -933,8 +933,8 @@ packages: dev: false optional: true - /@esbuild/android-arm64@0.18.11: - resolution: {integrity: sha512-snieiq75Z1z5LJX9cduSAjUr7vEI1OdlzFPMw0HH5YI7qQHDd3qs+WZoMrWYDsfRJSq36lIA6mfZBkvL46KoIw==} + /@esbuild/android-arm64@0.18.16: + resolution: {integrity: sha512-wsCqSPqLz+6Ov+OM4EthU43DyYVVyfn15S4j1bJzylDpc1r1jZFFfJQNfDuT8SlgwuqpmpJXK4uPlHGw6ve7eA==} engines: {node: '>=12'} cpu: [arm64] os: [android] @@ -950,8 +950,8 @@ packages: dev: false optional: true - /@esbuild/android-arm@0.18.11: - resolution: {integrity: sha512-q4qlUf5ucwbUJZXF5tEQ8LF7y0Nk4P58hOsGk3ucY0oCwgQqAnqXVbUuahCddVHfrxmpyewRpiTHwVHIETYu7Q==} + /@esbuild/android-arm@0.18.16: + resolution: {integrity: sha512-gCHjjQmA8L0soklKbLKA6pgsLk1byULuHe94lkZDzcO3/Ta+bbeewJioEn1Fr7kgy9NWNFy/C+MrBwC6I/WCug==} engines: {node: '>=12'} cpu: [arm] os: [android] @@ -967,8 +967,8 @@ packages: dev: false optional: true - /@esbuild/android-x64@0.18.11: - resolution: {integrity: sha512-iPuoxQEV34+hTF6FT7om+Qwziv1U519lEOvekXO9zaMMlT9+XneAhKL32DW3H7okrCOBQ44BMihE8dclbZtTuw==} + /@esbuild/android-x64@0.18.16: + resolution: {integrity: sha512-ldsTXolyA3eTQ1//4DS+E15xl0H/3DTRJaRL0/0PgkqDsI0fV/FlOtD+h0u/AUJr+eOTlZv4aC9gvfppo3C4sw==} engines: {node: '>=12'} cpu: [x64] os: [android] @@ -984,8 +984,8 @@ packages: dev: false optional: true - /@esbuild/darwin-arm64@0.18.11: - resolution: {integrity: sha512-Gm0QkI3k402OpfMKyQEEMG0RuW2LQsSmI6OeO4El2ojJMoF5NLYb3qMIjvbG/lbMeLOGiW6ooU8xqc+S0fgz2w==} + /@esbuild/darwin-arm64@0.18.16: + resolution: {integrity: sha512-aBxruWCII+OtluORR/KvisEw0ALuw/qDQWvkoosA+c/ngC/Kwk0lLaZ+B++LLS481/VdydB2u6tYpWxUfnLAIw==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] @@ -1001,8 +1001,8 @@ packages: dev: false optional: true - /@esbuild/darwin-x64@0.18.11: - resolution: {integrity: sha512-N15Vzy0YNHu6cfyDOjiyfJlRJCB/ngKOAvoBf1qybG3eOq0SL2Lutzz9N7DYUbb7Q23XtHPn6lMDF6uWbGv9Fw==} + /@esbuild/darwin-x64@0.18.16: + resolution: {integrity: sha512-6w4Dbue280+rp3LnkgmriS1icOUZDyPuZo/9VsuMUTns7SYEiOaJ7Ca1cbhu9KVObAWfmdjUl4gwy9TIgiO5eA==} engines: {node: '>=12'} cpu: [x64] os: [darwin] @@ -1018,8 +1018,8 @@ packages: dev: false optional: true - /@esbuild/freebsd-arm64@0.18.11: - resolution: {integrity: sha512-atEyuq6a3omEY5qAh5jIORWk8MzFnCpSTUruBgeyN9jZq1K/QI9uke0ATi3MHu4L8c59CnIi4+1jDKMuqmR71A==} + /@esbuild/freebsd-arm64@0.18.16: + resolution: {integrity: sha512-x35fCebhe9s979DGKbVAwXUOcTmCIE32AIqB9CB1GralMIvxdnMLAw5CnID17ipEw9/3MvDsusj/cspYt2ZLNQ==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] @@ -1035,8 +1035,8 @@ packages: dev: false optional: true - /@esbuild/freebsd-x64@0.18.11: - resolution: {integrity: sha512-XtuPrEfBj/YYYnAAB7KcorzzpGTvOr/dTtXPGesRfmflqhA4LMF0Gh/n5+a9JBzPuJ+CGk17CA++Hmr1F/gI0Q==} + /@esbuild/freebsd-x64@0.18.16: + resolution: {integrity: sha512-YM98f+PeNXF3GbxIJlUsj+McUWG1irguBHkszCIwfr3BXtXZsXo0vqybjUDFfu9a8Wr7uUD/YSmHib+EeGAFlg==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] @@ -1052,8 +1052,8 @@ packages: dev: false optional: true - /@esbuild/linux-arm64@0.18.11: - resolution: {integrity: sha512-c6Vh2WS9VFKxKZ2TvJdA7gdy0n6eSy+yunBvv4aqNCEhSWVor1TU43wNRp2YLO9Vng2G+W94aRz+ILDSwAiYog==} + /@esbuild/linux-arm64@0.18.16: + resolution: {integrity: sha512-XIqhNUxJiuy+zsR77+H5Z2f7s4YRlriSJKtvx99nJuG5ATuJPjmZ9n0ANgnGlPCpXGSReFpgcJ7O3SMtzIFeiQ==} engines: {node: '>=12'} cpu: [arm64] os: [linux] @@ -1069,8 +1069,8 @@ packages: dev: false optional: true - /@esbuild/linux-arm@0.18.11: - resolution: {integrity: sha512-Idipz+Taso/toi2ETugShXjQ3S59b6m62KmLHkJlSq/cBejixmIydqrtM2XTvNCywFl3VC7SreSf6NV0i6sRyg==} + /@esbuild/linux-arm@0.18.16: + resolution: {integrity: sha512-b5ABb+5Ha2C9JkeZXV+b+OruR1tJ33ePmv9ZwMeETSEKlmu/WJ45XTTG+l6a2KDsQtJJ66qo/hbSGBtk0XVLHw==} engines: {node: '>=12'} cpu: [arm] os: [linux] @@ -1086,8 +1086,8 @@ packages: dev: false optional: true - /@esbuild/linux-ia32@0.18.11: - resolution: {integrity: sha512-S3hkIF6KUqRh9n1Q0dSyYcWmcVa9Cg+mSoZEfFuzoYXXsk6196qndrM+ZiHNwpZKi3XOXpShZZ+9dfN5ykqjjw==} + /@esbuild/linux-ia32@0.18.16: + resolution: {integrity: sha512-no+pfEpwnRvIyH+txbBAWtjxPU9grslmTBfsmDndj7bnBmr55rOo/PfQmRfz7Qg9isswt1FP5hBbWb23fRWnow==} engines: {node: '>=12'} cpu: [ia32] os: [linux] @@ -1103,8 +1103,8 @@ packages: dev: false optional: true - /@esbuild/linux-loong64@0.18.11: - resolution: {integrity: sha512-MRESANOoObQINBA+RMZW+Z0TJWpibtE7cPFnahzyQHDCA9X9LOmGh68MVimZlM9J8n5Ia8lU773te6O3ILW8kw==} + /@esbuild/linux-loong64@0.18.16: + resolution: {integrity: sha512-Zbnczs9ZXjmo0oZSS0zbNlJbcwKXa/fcNhYQjahDs4Xg18UumpXG/lwM2lcSvHS3mTrRyCYZvJbmzYc4laRI1g==} engines: {node: '>=12'} cpu: [loong64] os: [linux] @@ -1120,8 +1120,8 @@ packages: dev: false optional: true - /@esbuild/linux-mips64el@0.18.11: - resolution: {integrity: sha512-qVyPIZrXNMOLYegtD1u8EBccCrBVshxMrn5MkuFc3mEVsw7CCQHaqZ4jm9hbn4gWY95XFnb7i4SsT3eflxZsUg==} + /@esbuild/linux-mips64el@0.18.16: + resolution: {integrity: sha512-YMF7hih1HVR/hQVa/ot4UVffc5ZlrzEb3k2ip0nZr1w6fnYypll9td2qcoMLvd3o8j3y6EbJM3MyIcXIVzXvQQ==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] @@ -1137,8 +1137,8 @@ packages: dev: false optional: true - /@esbuild/linux-ppc64@0.18.11: - resolution: {integrity: sha512-T3yd8vJXfPirZaUOoA9D2ZjxZX4Gr3QuC3GztBJA6PklLotc/7sXTOuuRkhE9W/5JvJP/K9b99ayPNAD+R+4qQ==} + /@esbuild/linux-ppc64@0.18.16: + resolution: {integrity: sha512-Wkz++LZ29lDwUyTSEnzDaaP5OveOgTU69q9IyIw9WqLRxM4BjTBjz9un4G6TOvehWpf/J3gYVFN96TjGHrbcNQ==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] @@ -1154,8 +1154,8 @@ packages: dev: false optional: true - /@esbuild/linux-riscv64@0.18.11: - resolution: {integrity: sha512-evUoRPWiwuFk++snjH9e2cAjF5VVSTj+Dnf+rkO/Q20tRqv+644279TZlPK8nUGunjPAtQRCj1jQkDAvL6rm2w==} + /@esbuild/linux-riscv64@0.18.16: + resolution: {integrity: sha512-LFMKZ30tk78/mUv1ygvIP+568bwf4oN6reG/uczXnz6SvFn4e2QUFpUpZY9iSJT6Qpgstrhef/nMykIXZtZWGQ==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] @@ -1171,8 +1171,8 @@ packages: dev: false optional: true - /@esbuild/linux-s390x@0.18.11: - resolution: {integrity: sha512-/SlRJ15XR6i93gRWquRxYCfhTeC5PdqEapKoLbX63PLCmAkXZHY2uQm2l9bN0oPHBsOw2IswRZctMYS0MijFcg==} + /@esbuild/linux-s390x@0.18.16: + resolution: {integrity: sha512-3ZC0BgyYHYKfZo3AV2/66TD/I9tlSBaW7eWTEIkrQQKfJIifKMMttXl9FrAg+UT0SGYsCRLI35Gwdmm96vlOjg==} engines: {node: '>=12'} cpu: [s390x] os: [linux] @@ -1188,8 +1188,8 @@ packages: dev: false optional: true - /@esbuild/linux-x64@0.18.11: - resolution: {integrity: sha512-xcncej+wF16WEmIwPtCHi0qmx1FweBqgsRtEL1mSHLFR6/mb3GEZfLQnx+pUDfRDEM4DQF8dpXIW7eDOZl1IbA==} + /@esbuild/linux-x64@0.18.16: + resolution: {integrity: sha512-xu86B3647DihHJHv/wx3NCz2Dg1gjQ8bbf9cVYZzWKY+gsvxYmn/lnVlqDRazObc3UMwoHpUhNYaZset4X8IPA==} engines: {node: '>=12'} cpu: [x64] os: [linux] @@ -1205,8 +1205,8 @@ packages: dev: false optional: true - /@esbuild/netbsd-x64@0.18.11: - resolution: {integrity: sha512-aSjMHj/F7BuS1CptSXNg6S3M4F3bLp5wfFPIJM+Km2NfIVfFKhdmfHF9frhiCLIGVzDziggqWll0B+9AUbud/Q==} + /@esbuild/netbsd-x64@0.18.16: + resolution: {integrity: sha512-uVAgpimx9Ffw3xowtg/7qQPwHFx94yCje+DoBx+LNm2ePDpQXHrzE+Sb0Si2VBObYz+LcRps15cq+95YM7gkUw==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] @@ -1222,8 +1222,8 @@ packages: dev: false optional: true - /@esbuild/openbsd-x64@0.18.11: - resolution: {integrity: sha512-tNBq+6XIBZtht0xJGv7IBB5XaSyvYPCm1PxJ33zLQONdZoLVM0bgGqUrXnJyiEguD9LU4AHiu+GCXy/Hm9LsdQ==} + /@esbuild/openbsd-x64@0.18.16: + resolution: {integrity: sha512-6OjCQM9wf7z8/MBi6BOWaTL2AS/SZudsZtBziXMtNI8r/U41AxS9x7jn0ATOwVy08OotwkPqGRMkpPR2wcTJXA==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] @@ -1239,8 +1239,8 @@ packages: dev: false optional: true - /@esbuild/sunos-x64@0.18.11: - resolution: {integrity: sha512-kxfbDOrH4dHuAAOhr7D7EqaYf+W45LsAOOhAet99EyuxxQmjbk8M9N4ezHcEiCYPaiW8Dj3K26Z2V17Gt6p3ng==} + /@esbuild/sunos-x64@0.18.16: + resolution: {integrity: sha512-ZoNkruFYJp9d1LbUYCh8awgQDvB9uOMZqlQ+gGEZR7v6C+N6u7vPr86c+Chih8niBR81Q/bHOSKGBK3brJyvkQ==} engines: {node: '>=12'} cpu: [x64] os: [sunos] @@ -1256,8 +1256,8 @@ packages: dev: false optional: true - /@esbuild/win32-arm64@0.18.11: - resolution: {integrity: sha512-Sh0dDRyk1Xi348idbal7lZyfSkjhJsdFeuC13zqdipsvMetlGiFQNdO+Yfp6f6B4FbyQm7qsk16yaZk25LChzg==} + /@esbuild/win32-arm64@0.18.16: + resolution: {integrity: sha512-+j4anzQ9hrs+iqO+/wa8UE6TVkKua1pXUb0XWFOx0FiAj6R9INJ+WE//1/Xo6FG1vB5EpH3ko+XcgwiDXTxcdw==} engines: {node: '>=12'} cpu: [arm64] os: [win32] @@ -1273,8 +1273,8 @@ packages: dev: false optional: true - /@esbuild/win32-ia32@0.18.11: - resolution: {integrity: sha512-o9JUIKF1j0rqJTFbIoF4bXj6rvrTZYOrfRcGyL0Vm5uJ/j5CkBD/51tpdxe9lXEDouhRgdr/BYzUrDOvrWwJpg==} + /@esbuild/win32-ia32@0.18.16: + resolution: {integrity: sha512-5PFPmq3sSKTp9cT9dzvI67WNfRZGvEVctcZa1KGjDDu4n3H8k59Inbk0du1fz0KrAbKKNpJbdFXQMDUz7BG4rQ==} engines: {node: '>=12'} cpu: [ia32] os: [win32] @@ -1290,8 +1290,8 @@ packages: dev: false optional: true - /@esbuild/win32-x64@0.18.11: - resolution: {integrity: sha512-rQI4cjLHd2hGsM1LqgDI7oOCYbQ6IBOVsX9ejuRMSze0GqXUG2ekwiKkiBU1pRGSeCqFFHxTrcEydB2Hyoz9CA==} + /@esbuild/win32-x64@0.18.16: + resolution: {integrity: sha512-sCIVrrtcWN5Ua7jYXNG1xD199IalrbfV2+0k/2Zf2OyV2FtnQnMgdzgpRAbi4AWlKJj1jkX+M+fEGPQj6BQB4w==} engines: {node: '>=12'} cpu: [x64] os: [win32] @@ -1571,6 +1571,10 @@ packages: /@types/node@20.4.0: resolution: {integrity: sha512-jfT7iTf/4kOQ9S7CHV9BIyRaQqHu67mOjsIQBC3BKZvzvUB6zLxEwJ6sBE3ozcvP8kF6Uk5PXN0Q+c0dfhGX0g==} + /@types/node@20.4.4: + resolution: {integrity: sha512-CukZhumInROvLq3+b5gLev+vgpsIqC2D0deQr/yS1WnxvmYLlJXZpaQrQiseMY+6xusl79E04UjWoqyr+t1/Ew==} + dev: true + /@types/normalize-package-data@2.4.1: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} dev: true @@ -1827,12 +1831,6 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - /acorn@8.8.2: - resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} - engines: {node: '>=0.4.0'} - hasBin: true - dev: true - /aggregate-error@4.0.1: resolution: {integrity: sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==} engines: {node: '>=12'} @@ -2748,34 +2746,34 @@ packages: '@esbuild/win32-x64': 0.17.19 dev: false - /esbuild@0.18.11: - resolution: {integrity: sha512-i8u6mQF0JKJUlGR3OdFLKldJQMMs8OqM9Cc3UCi9XXziJ9WERM5bfkHaEAy0YAvPRMgqSW55W7xYn84XtEFTtA==} + /esbuild@0.18.16: + resolution: {integrity: sha512-1xLsOXrDqwdHxyXb/x/SOyg59jpf/SH7YMvU5RNSU7z3TInaASNJWNFJ6iRvLvLETZMasF3d1DdZLg7sgRimRQ==} engines: {node: '>=12'} hasBin: true requiresBuild: true optionalDependencies: - '@esbuild/android-arm': 0.18.11 - '@esbuild/android-arm64': 0.18.11 - '@esbuild/android-x64': 0.18.11 - '@esbuild/darwin-arm64': 0.18.11 - '@esbuild/darwin-x64': 0.18.11 - '@esbuild/freebsd-arm64': 0.18.11 - '@esbuild/freebsd-x64': 0.18.11 - '@esbuild/linux-arm': 0.18.11 - '@esbuild/linux-arm64': 0.18.11 - '@esbuild/linux-ia32': 0.18.11 - '@esbuild/linux-loong64': 0.18.11 - '@esbuild/linux-mips64el': 0.18.11 - '@esbuild/linux-ppc64': 0.18.11 - '@esbuild/linux-riscv64': 0.18.11 - '@esbuild/linux-s390x': 0.18.11 - '@esbuild/linux-x64': 0.18.11 - '@esbuild/netbsd-x64': 0.18.11 - '@esbuild/openbsd-x64': 0.18.11 - '@esbuild/sunos-x64': 0.18.11 - '@esbuild/win32-arm64': 0.18.11 - '@esbuild/win32-ia32': 0.18.11 - '@esbuild/win32-x64': 0.18.11 + '@esbuild/android-arm': 0.18.16 + '@esbuild/android-arm64': 0.18.16 + '@esbuild/android-x64': 0.18.16 + '@esbuild/darwin-arm64': 0.18.16 + '@esbuild/darwin-x64': 0.18.16 + '@esbuild/freebsd-arm64': 0.18.16 + '@esbuild/freebsd-x64': 0.18.16 + '@esbuild/linux-arm': 0.18.16 + '@esbuild/linux-arm64': 0.18.16 + '@esbuild/linux-ia32': 0.18.16 + '@esbuild/linux-loong64': 0.18.16 + '@esbuild/linux-mips64el': 0.18.16 + '@esbuild/linux-ppc64': 0.18.16 + '@esbuild/linux-riscv64': 0.18.16 + '@esbuild/linux-s390x': 0.18.16 + '@esbuild/linux-x64': 0.18.16 + '@esbuild/netbsd-x64': 0.18.16 + '@esbuild/openbsd-x64': 0.18.16 + '@esbuild/sunos-x64': 0.18.16 + '@esbuild/win32-arm64': 0.18.16 + '@esbuild/win32-ia32': 0.18.16 + '@esbuild/win32-x64': 0.18.16 /escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} @@ -4829,6 +4827,15 @@ packages: picocolors: 1.0.0 source-map-js: 1.0.2 + /postcss@8.4.27: + resolution: {integrity: sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.6 + picocolors: 1.0.0 + source-map-js: 1.0.2 + dev: true + /preact-render-to-string@5.2.6(preact@10.15.1): resolution: {integrity: sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw==} peerDependencies: @@ -5217,6 +5224,14 @@ packages: optionalDependencies: fsevents: 2.3.2 + /rollup@3.26.3: + resolution: {integrity: sha512-7Tin0C8l86TkpcMtXvQu6saWH93nhG3dGQ1/+l5V2TDMceTxO7kDiK6GzbfLWNNxqJXm591PcEZUozZm51ogwQ==} + engines: {node: '>=14.18.0', npm: '>=8.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.2 + dev: true + /run-applescript@5.0.0: resolution: {integrity: sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==} engines: {node: '>=12'} @@ -5281,8 +5296,8 @@ packages: loose-envify: 1.4.0 dev: false - /search-insights@2.6.0: - resolution: {integrity: sha512-vU2/fJ+h/Mkm/DJOe+EaM5cafJv/1rRTZpGJTuFPf/Q5LjzgMDsqPdSaZsAe+GAWHHsfsu+rQSAn6c8IGtBEVw==} + /search-insights@2.7.0: + resolution: {integrity: sha512-GLbVaGgzYEKMvuJbHRhLi1qoBFnjXZGZ6l4LxOYPCp4lI2jDRB3jPU9/XNhMwv6kvnA9slTreq6pvK+b3o3aqg==} engines: {node: '>=8.16.0'} dev: false @@ -5598,7 +5613,7 @@ packages: /strip-literal@1.0.1: resolution: {integrity: sha512-QZTsipNpa2Ppr6v1AmJHESqJ3Uz247MUS0OjrnnZjFAvEoWqxuyFuXn2xLgMtRnijJShAa1HL0gtJyUs7u7n3Q==} dependencies: - acorn: 8.8.2 + acorn: 8.10.0 dev: true /suf-log@2.5.3: @@ -5980,6 +5995,28 @@ packages: - terser dev: true + /vite-node@0.33.0(@types/node@20.4.4): + resolution: {integrity: sha512-19FpHYbwWWxDr73ruNahC+vtEdza52kA90Qb3La98yZ0xULqV8A5JLNPUff0f5zID4984tW7l3DH2przTJUZSw==} + engines: {node: '>=v14.18.0'} + hasBin: true + dependencies: + cac: 6.7.14 + debug: 4.3.4(supports-color@9.4.0) + mlly: 1.4.0 + pathe: 1.1.1 + picocolors: 1.0.0 + vite: 4.4.1(@types/node@20.4.4) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + /vite@4.4.1(@types/node@20.4.0)(sass@1.63.6): resolution: {integrity: sha512-8mmwPlsy7t+ZcTme7vdbVGuZ3Tri+lrLXr6hsF5UHdyYyARPPPMtM16QlqC9TZuCd5j3NmWs1rwka3cVSRHZTw==} engines: {node: ^14.18.0 || >=16.0.0} @@ -6009,13 +6046,85 @@ packages: optional: true dependencies: '@types/node': 20.4.0 - esbuild: 0.18.11 + esbuild: 0.18.16 postcss: 8.4.25 rollup: 3.26.2 sass: 1.63.6 optionalDependencies: fsevents: 2.3.2 + /vite@4.4.1(@types/node@20.4.4): + resolution: {integrity: sha512-8mmwPlsy7t+ZcTme7vdbVGuZ3Tri+lrLXr6hsF5UHdyYyARPPPMtM16QlqC9TZuCd5j3NmWs1rwka3cVSRHZTw==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 20.4.4 + esbuild: 0.18.16 + postcss: 8.4.25 + rollup: 3.26.2 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /vite@4.4.7(@types/node@20.4.4): + resolution: {integrity: sha512-6pYf9QJ1mHylfVh39HpuSfMPojPSKVxZvnclX1K1FyZ1PXDOcLBibdq5t1qxJSnL63ca8Wf4zts6mD8u8oc9Fw==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 20.4.4 + esbuild: 0.18.16 + postcss: 8.4.27 + rollup: 3.26.3 + optionalDependencies: + fsevents: 2.3.2 + dev: true + /vitefu@0.2.4(vite@4.4.1): resolution: {integrity: sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==} peerDependencies: @@ -6034,11 +6143,76 @@ packages: vitest: '>=0.16.0' dependencies: cross-fetch: 3.1.8 - vitest: 0.33.0(supports-color@9.4.0) + vitest: 0.33.0 transitivePeerDependencies: - encoding dev: true + /vitest@0.33.0: + resolution: {integrity: sha512-1CxaugJ50xskkQ0e969R/hW47za4YXDUfWJDxip1hwbnhUjYolpfUn2AMOulqG/Dtd9WYAtkHmM/m3yKVrEejQ==} + engines: {node: '>=v14.18.0'} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@vitest/browser': '*' + '@vitest/ui': '*' + happy-dom: '*' + jsdom: '*' + playwright: '*' + safaridriver: '*' + webdriverio: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + playwright: + optional: true + safaridriver: + optional: true + webdriverio: + optional: true + dependencies: + '@types/chai': 4.3.5 + '@types/chai-subset': 1.3.3 + '@types/node': 20.4.4 + '@vitest/expect': 0.33.0 + '@vitest/runner': 0.33.0 + '@vitest/snapshot': 0.33.0 + '@vitest/spy': 0.33.0 + '@vitest/utils': 0.33.0 + acorn: 8.10.0 + acorn-walk: 8.2.0 + cac: 6.7.14 + chai: 4.3.7 + debug: 4.3.4(supports-color@9.4.0) + local-pkg: 0.4.3 + magic-string: 0.30.1 + pathe: 1.1.1 + picocolors: 1.0.0 + std-env: 3.3.3 + strip-literal: 1.0.1 + tinybench: 2.5.0 + tinypool: 0.6.0 + vite: 4.4.7(@types/node@20.4.4) + vite-node: 0.33.0(@types/node@20.4.4) + why-is-node-running: 2.2.2 + transitivePeerDependencies: + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + /vitest@0.33.0(supports-color@9.4.0): resolution: {integrity: sha512-1CxaugJ50xskkQ0e969R/hW47za4YXDUfWJDxip1hwbnhUjYolpfUn2AMOulqG/Dtd9WYAtkHmM/m3yKVrEejQ==} engines: {node: '>=v14.18.0'}