diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 000000000..f3f52b42d --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +20.9.0 diff --git a/.prettierignore b/.prettierignore index 9759c21a4..966ec8a76 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,7 +2,8 @@ **/node_modules **/templates **/dist -**/.vitepress +**/.vitepress/cache +**/.vitepress/dist **/test/e2e **/CHANGELOG.md diff --git a/docs/.vitepress/config/en.ts b/docs/.vitepress/config/en.ts index 2c75c1cd2..f9c78394e 100644 --- a/docs/.vitepress/config/en.ts +++ b/docs/.vitepress/config/en.ts @@ -1,28 +1,38 @@ import { defineConfig } from 'vitepress'; export default defineConfig({ - description: 'Turn your OpenAPI specification into a beautiful TypeScript client', + description: + 'Turn your OpenAPI specification into a beautiful TypeScript client', lang: 'en-US', themeConfig: { sidebar: [ { - text: 'openapi-ts', items: [ - { text: 'Get Started', link: '/openapi-ts/get-started' }, - { text: 'Configuration', link: '/openapi-ts/configuration' }, - { text: 'Clients soon', link: '/openapi-ts/clients' }, - { text: 'Interceptors', link: '/openapi-ts/interceptors' }, - { text: 'Integrations soon', link: '/openapi-ts/integrations' }, - { text: 'TanStack Query soon', link: '/openapi-ts/tanstack-query' }, - { text: 'Migrating', link: '/openapi-ts/migrating' }, + { link: '/openapi-ts/get-started', text: 'Get Started' }, + { link: '/openapi-ts/configuration', text: 'Configuration' }, + { + link: '/openapi-ts/clients', + text: 'Clients soon', + }, + { link: '/openapi-ts/interceptors', text: 'Interceptors' }, + { + link: '/openapi-ts/integrations', + text: 'Integrations soon', + }, + { + link: '/openapi-ts/tanstack-query', + text: 'TanStack Query soon', + }, + { link: '/openapi-ts/migrating', text: 'Migrating' }, ], + text: 'openapi-ts', }, { - text: '@hey-api', items: [ - { text: 'Philosophy', link: '/about' }, - { text: 'Contributing', link: '/contributing' }, + { link: '/about', text: 'Philosophy' }, + { link: '/contributing', text: 'Contributing' }, ], + text: '@hey-api', }, ], }, diff --git a/docs/.vitepress/config/index.ts b/docs/.vitepress/config/index.ts index 1529e4e3c..7c3204ecb 100644 --- a/docs/.vitepress/config/index.ts +++ b/docs/.vitepress/config/index.ts @@ -4,8 +4,8 @@ import en from './en'; import shared from './shared'; export default defineConfig({ - ...shared, - locales: { - root: { label: 'English', ...en }, - }, + ...shared, + locales: { + root: { label: 'English', ...en }, + }, }); diff --git a/docs/.vitepress/config/shared.ts b/docs/.vitepress/config/shared.ts index 23f756206..9577de68b 100644 --- a/docs/.vitepress/config/shared.ts +++ b/docs/.vitepress/config/shared.ts @@ -1,31 +1,42 @@ import { defineConfig } from 'vitepress'; export default defineConfig({ - title: 'Hey API', - lastUpdated: false, - sitemap: { - hostname: 'https://heyapi.vercel.app', + head: [ + ['link', { href: '/logo.png', rel: 'icon', type: 'image/png' }], + ['meta', { content: 'website', property: 'og:type' }], + ['meta', { content: 'en', property: 'og:locale' }], + [ + 'meta', + { + content: + 'Turn your OpenAPI specification into a beautiful TypeScript client', + property: 'og:title', + }, + ], + ['meta', { content: 'OpenAPI TypeScript', property: 'og:site_name' }], + ['meta', { content: '/logo.png', property: 'og:image' }], + ['meta', { content: 'https://heyapi.vercel.app', property: 'og:url' }], + [ + 'script', + {}, + 'window.va = window.va || function () { (window.vaq = window.vaq || []).push(arguments); };', + ], + ['script', { defer: '', src: '/_vercel/insights/script.js' }], + ], + lastUpdated: false, + sitemap: { + hostname: 'https://heyapi.vercel.app', + }, + themeConfig: { + externalLinkIcon: true, + logo: '/logo.png', + search: { + provider: 'local', }, - head: [ - ['link', { rel: 'icon', type: 'image/png', href: '/logo.png' }], - ['meta', { property: 'og:type', content: 'website' }], - ['meta', { property: 'og:locale', content: 'en' }], - ['meta', { property: 'og:title', content: 'Turn your OpenAPI specification into a beautiful TypeScript client' }], - ['meta', { property: 'og:site_name', content: 'OpenAPI TypeScript' }], - ['meta', { property: 'og:image', content: '/logo.png' }], - ['meta', { property: 'og:url', content: 'https://heyapi.vercel.app' }], - ['script', {}, 'window.va = window.va || function () { (window.vaq = window.vaq || []).push(arguments); };'], - ['script', { defer: '', src: '/_vercel/insights/script.js' }], + socialLinks: [ + { icon: 'npm', link: 'https://npmjs.com/package/@hey-api/openapi-ts' }, + { icon: 'github', link: 'https://github.com/hey-api/openapi-ts' }, ], - themeConfig: { - externalLinkIcon: true, - logo: '/logo.png', - socialLinks: [ - { icon: 'npm', link: 'https://npmjs.com/package/@hey-api/openapi-ts' }, - { icon: 'github', link: 'https://github.com/hey-api/openapi-ts' }, - ], - search: { - provider: 'local', - } - } + }, + title: 'Hey API', }); diff --git a/docs/.vitepress/theme/custom.css b/docs/.vitepress/theme/custom.css index aa07aee5e..68a087612 100644 --- a/docs/.vitepress/theme/custom.css +++ b/docs/.vitepress/theme/custom.css @@ -1,27 +1,27 @@ :root { - --c-gradient-start: #d486b8; - --vp-c-brand-1: #a37ab4; - --vp-c-brand-2: #d486b8; - --vp-c-brand-3: #a37ab4; + --c-gradient-start: #d486b8; + --vp-c-brand-1: #a37ab4; + --vp-c-brand-2: #d486b8; + --vp-c-brand-3: #a37ab4; } html.dark { - --c-gradient-start: #86b9b0; - --vp-c-bg: #001b2e; - --vp-c-bg-alt: #041421; - --vp-c-bg-soft: #041421; - --vp-c-brand-1: #b3cde4; - --vp-c-brand-2: #b3cde4; - --vp-c-brand-3: #537692; + --c-gradient-start: #86b9b0; + --vp-c-bg: #001b2e; + --vp-c-bg-alt: #041421; + --vp-c-bg-soft: #041421; + --vp-c-brand-1: #b3cde4; + --vp-c-brand-2: #b3cde4; + --vp-c-brand-3: #537692; } .soon { - background-color: var(--vp-button-brand-bg); - border-radius: 1em; - color: var(--vp-button-brand-text); - font-size: .6em; - padding: .2em .4em; - position: relative; - text-transform: lowercase; - top: -1em; + background-color: var(--vp-button-brand-bg); + border-radius: 1em; + color: var(--vp-button-brand-text); + font-size: 0.6em; + padding: 0.2em 0.4em; + position: relative; + text-transform: lowercase; + top: -1em; } diff --git a/docs/.vitepress/theme/index.js b/docs/.vitepress/theme/index.js index 149273e8d..7f6da847b 100644 --- a/docs/.vitepress/theme/index.js +++ b/docs/.vitepress/theme/index.js @@ -1,4 +1,5 @@ -import DefaultTheme from 'vitepress/theme'; import './custom.css'; +import DefaultTheme from 'vitepress/theme'; + export default DefaultTheme; diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 16e318097..451039016 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,4 +1,4 @@ -# openapi-ts-docs +# @hey-api/docs ## 0.5.2 diff --git a/docs/package.json b/docs/package.json index bac861975..3811c6286 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,5 +1,5 @@ { - "name": "openapi-ts-docs", + "name": "@hey-api/docs", "version": "0.5.2", "description": "Documentation for OpenaAPI TypeScript.", "private": true, diff --git a/packages/openapi-ts/eslint.config.js b/eslint.config.js similarity index 96% rename from packages/openapi-ts/eslint.config.js rename to eslint.config.js index d9e6aa5bd..53d467271 100644 --- a/packages/openapi-ts/eslint.config.js +++ b/eslint.config.js @@ -46,6 +46,8 @@ export default tseslint.config( 'temp/', '**/test/e2e/generated/', '**/test/generated/', + '**/.vitepress/cache', + '**/.vitepress/dist', ], }, ); diff --git a/package.json b/package.json index d57d48371..9d11b9aef 100644 --- a/package.json +++ b/package.json @@ -16,10 +16,14 @@ "scripts": { "build": "pnpm --recursive build", "changeset": "changeset", - "docs": "pnpm --filter openapi-ts-docs --", + "client-axios": "pnpm --filter @hey-api/client-axios --", + "client-core": "pnpm --filter @hey-api/client-core --", + "client-fetch": "pnpm --filter @hey-api/client-fetch --", + "client-nextjs": "pnpm --filter @hey-api/client-nextjs --", + "docs": "pnpm --filter @hey-api/docs --", "format": "prettier --write .", - "lint:fix": "prettier --check . && pnpm --recursive lint:fix", - "lint": "prettier --check . && pnpm --recursive lint", + "lint:fix": "prettier --check . && eslint . --fix", + "lint": "prettier --check . && eslint .", "openapi-ts": "pnpm --filter @hey-api/openapi-ts --", "prepare": "husky", "test:coverage": "pnpm --recursive test:coverage", @@ -33,10 +37,26 @@ }, "devDependencies": { "@changesets/cli": "2.27.1", + "@rollup/plugin-commonjs": "25.0.7", + "@rollup/plugin-terser": "0.4.4", + "@rollup/plugin-typescript": "11.1.6", "@svitejs/changesets-changelog-github-compact": "1.1.0", + "@types/node": "20.12.7", + "@vitest/coverage-v8": "1.5.0", + "eslint": "9.1.0", + "eslint-config-prettier": "9.1.0", + "eslint-plugin-simple-import-sort": "12.1.0", + "eslint-plugin-sort-keys-fix": "1.1.2", + "globals": "15.0.0", "husky": "9.0.11", "lint-staged": "15.2.2", - "prettier": "3.2.5" + "prettier": "3.2.5", + "rimraf": "5.0.5", + "rollup": "4.16.1", + "rollup-plugin-dts": "6.1.0", + "typescript": "5.4.5", + "typescript-eslint": "7.7.0", + "vitest": "1.5.0" }, "packageManager": "pnpm@8.15.7+sha256.50783dd0fa303852de2dd1557cd4b9f07cb5b018154a6e76d0f40635d6cee019" } diff --git a/packages/client-axios/package.json b/packages/client-axios/package.json new file mode 100644 index 000000000..6a9ad5ed7 --- /dev/null +++ b/packages/client-axios/package.json @@ -0,0 +1,59 @@ +{ + "name": "@hey-api/client-axios", + "version": "0.1.0", + "private": true, + "type": "module", + "description": "Type-safe Axios client for your openapi-ts types", + "homepage": "https://heyapi.vercel.app/", + "repository": { + "type": "git", + "url": "git+https://github.com/hey-api/openapi-ts.git" + }, + "bugs": { + "url": "https://github.com/hey-api/openapi-ts/issues" + }, + "license": "MIT", + "keywords": [ + "axios", + "client", + "codegen", + "generator", + "javascript", + "openapi", + "react", + "svelte", + "swagger", + "typescript", + "vue" + ], + "main": "./dist/index.cjs", + "types": "./dist/index.d.ts", + "scripts": { + "build-bundle": "rollup --config rollup.config.ts --configPlugin typescript", + "build-types-check": "tsc --project tsconfig.check.json", + "build-types-roll": "rollup --config rollup.dts.config.ts --configPlugin typescript && rimraf temp", + "build-types-temp": "tsc --emitDeclarationOnly --outDir temp -p src", + "build-types": "pnpm build-types-temp && pnpm build-types-roll && pnpm build-types-check", + "build": "pnpm clean && pnpm build-bundle && pnpm build-types", + "clean": "rimraf dist coverage node_modules/.cache", + "dev": "rimraf dist && pnpm build-bundle --watch", + "prepublishOnly": "pnpm build", + "test:coverage": "vitest run --coverage", + "test:update": "vitest watch --update", + "test:watch": "vitest watch", + "test": "vitest run", + "typecheck": "tsc --noEmit" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "dependencies": { + "@hey-api/client-core": "workspace:*" + }, + "peerDependencies": { + "axios": ">= 1.0.0 < 2" + }, + "devDependencies": { + "axios": "1.6.8" + } +} diff --git a/packages/client-axios/rollup.config.ts b/packages/client-axios/rollup.config.ts new file mode 100644 index 000000000..d5cbd4f68 --- /dev/null +++ b/packages/client-axios/rollup.config.ts @@ -0,0 +1,47 @@ +import { readFileSync } from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +import commonjs from '@rollup/plugin-commonjs'; +import terser from '@rollup/plugin-terser'; +import typescript from '@rollup/plugin-typescript'; +import type { RollupOptions } from 'rollup'; +import { defineConfig } from 'rollup'; + +const __dirname = fileURLToPath(new URL('.', import.meta.url)); + +const pkg = JSON.parse( + readFileSync(new URL('./package.json', import.meta.url)).toString(), +); + +export const externalDependencies = [ + ...Object.keys(pkg.dependencies ?? {}), + ...Object.keys(pkg.peerDependencies ?? {}), +]; + +function createConfig(isProduction: boolean) { + return defineConfig({ + external: externalDependencies, + input: path.resolve(__dirname, 'src/index.ts'), + output: { + file: path.resolve(__dirname, 'dist/index.cjs'), + format: 'cjs', + }, + plugins: [ + typescript({ + declaration: false, + tsconfig: path.resolve(__dirname, 'src/tsconfig.json'), + }), + commonjs({ + sourceMap: false, + }), + isProduction && terser(), + ], + }); +} + +export default (commandLineArgs: any): RollupOptions[] => { + const isDev = commandLineArgs.watch; + const isProduction = !isDev; + return defineConfig([createConfig(isProduction)]); +}; diff --git a/packages/client-axios/rollup.dts.config.ts b/packages/client-axios/rollup.dts.config.ts new file mode 100644 index 000000000..8a04de3c0 --- /dev/null +++ b/packages/client-axios/rollup.dts.config.ts @@ -0,0 +1,16 @@ +import { defineConfig } from 'rollup'; +import dts from 'rollup-plugin-dts'; + +import { externalDependencies } from './rollup.config'; + +export default defineConfig({ + external: externalDependencies, + input: { + index: './temp/index.d.ts', + }, + output: { + dir: './dist', + format: 'cjs', + }, + plugins: [dts({ respectExternal: true })], +}); diff --git a/packages/client-axios/src/__tests__/index.test.ts b/packages/client-axios/src/__tests__/index.test.ts new file mode 100644 index 000000000..9c9d1170f --- /dev/null +++ b/packages/client-axios/src/__tests__/index.test.ts @@ -0,0 +1,7 @@ +import { describe, expect, it } from 'vitest'; + +describe('Axios client', () => { + it('works', () => { + expect(1).toBe(1); + }); +}); diff --git a/packages/client-axios/src/index.ts b/packages/client-axios/src/index.ts new file mode 100644 index 000000000..eaabd6cfe --- /dev/null +++ b/packages/client-axios/src/index.ts @@ -0,0 +1,203 @@ +import type { + ApiRequestOptions, + ApiResult, + OnCancel, + OpenAPIConfig, +} from '@hey-api/client-core'; +import { + base64, + CancelablePromise, + catchErrorCodes, + getFormData, + getUrl, + isBlob, + isFormData, + isString, + isStringWithValue, + isSuccess, + resolve, +} from '@hey-api/client-core'; +import type { + AxiosError, + AxiosInstance, + AxiosRequestConfig, + AxiosResponse, +} from 'axios'; +import axios from 'axios'; + +export const getHeaders = async ( + config: OpenAPIConfig, + options: ApiRequestOptions, +): Promise> => { + const [token, username, password, additionalHeaders] = await Promise.all([ + resolve(options, config.TOKEN), + resolve(options, config.USERNAME), + resolve(options, config.PASSWORD), + resolve(options, config.HEADERS), + ]); + + const headers = Object.entries({ + Accept: 'application/json', + ...additionalHeaders, + ...options.headers, + }) + .filter(([, value]) => value !== undefined && value !== null) + .reduce( + (headers, [key, value]) => ({ + ...headers, + [key]: String(value), + }), + {} as Record, + ); + + if (isStringWithValue(token)) { + headers['Authorization'] = `Bearer ${token}`; + } + + if (isStringWithValue(username) && isStringWithValue(password)) { + const credentials = base64(`${username}:${password}`); + headers['Authorization'] = `Basic ${credentials}`; + } + + if (options.body !== undefined) { + if (options.mediaType) { + headers['Content-Type'] = options.mediaType; + } else if (isBlob(options.body)) { + headers['Content-Type'] = options.body.type || 'application/octet-stream'; + } else if (isString(options.body)) { + headers['Content-Type'] = 'text/plain'; + } else if (!isFormData(options.body)) { + headers['Content-Type'] = 'application/json'; + } + } else if (options.formData !== undefined) { + if (options.mediaType) { + headers['Content-Type'] = options.mediaType; + } + } + + return headers; +}; + +export const getRequestBody = (options: ApiRequestOptions): unknown => { + if (options.body) { + return options.body; + } + return undefined; +}; + +export const sendRequest = async ( + config: OpenAPIConfig, + options: ApiRequestOptions, + url: string, + body: unknown, + formData: FormData | undefined, + headers: Record, + onCancel: OnCancel, + axiosClient: AxiosInstance, +): Promise> => { + const controller = new AbortController(); + + let requestConfig: AxiosRequestConfig = { + data: body ?? formData, + headers, + method: options.method, + signal: controller.signal, + url, + withCredentials: config.WITH_CREDENTIALS, + }; + + onCancel(() => controller.abort()); + + for (const fn of config.interceptors.request._fns) { + requestConfig = await fn(requestConfig); + } + + try { + return await axiosClient.request(requestConfig); + } catch (error) { + const axiosError = error as AxiosError; + if (axiosError.response) { + return axiosError.response; + } + throw error; + } +}; + +export const getResponseHeader = ( + response: AxiosResponse, + responseHeader?: string, +): string | undefined => { + if (responseHeader) { + const content = response.headers[responseHeader]; + if (isString(content)) { + return content; + } + } + return undefined; +}; + +export const getResponseBody = (response: AxiosResponse): unknown => { + if (response.status !== 204) { + return response.data; + } + return undefined; +}; + +/** + * Request method + * @param config The OpenAPI configuration object + * @param options The request options from the service + * @param axiosClient The axios client instance to use + * @returns CancelablePromise + * @throws ApiError + */ +export const request = ( + config: OpenAPIConfig, + options: ApiRequestOptions, + axiosClient: AxiosInstance = axios, +): CancelablePromise => + new CancelablePromise(async (resolve, reject, onCancel) => { + try { + const url = getUrl(config, options); + const formData = getFormData(options); + const body = getRequestBody(options); + const headers = await getHeaders(config, options); + + if (!onCancel.isCancelled) { + let response = await sendRequest( + config, + options, + url, + body, + formData, + headers, + onCancel, + axiosClient, + ); + + for (const fn of config.interceptors.response._fns) { + response = await fn(response); + } + + const responseBody = getResponseBody(response); + const responseHeader = getResponseHeader( + response, + options.responseHeader, + ); + + const result: ApiResult = { + body: responseHeader ?? responseBody, + ok: isSuccess(response.status), + status: response.status, + statusText: response.statusText, + url, + }; + + catchErrorCodes(options, result); + + resolve(result.body); + } + } catch (error) { + reject(error); + } + }); diff --git a/packages/client-axios/src/tsconfig.json b/packages/client-axios/src/tsconfig.json new file mode 100644 index 000000000..4928e973b --- /dev/null +++ b/packages/client-axios/src/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "lib": ["ESNext"], + "stripInternal": true + }, + "exclude": ["./**/__tests__"], + "extends": "../tsconfig.base.json", + "include": ["./"] +} diff --git a/packages/client-axios/tsconfig.base.json b/packages/client-axios/tsconfig.base.json new file mode 100644 index 000000000..64e31b3e5 --- /dev/null +++ b/packages/client-axios/tsconfig.base.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "declaration": true, + "esModuleInterop": true, + "module": "ESNext", + "moduleResolution": "Bundler", + "noImplicitOverride": true, + "noUnusedLocals": true, + "strict": true, + "target": "ES2022", + "useUnknownInCatchVariables": false + } +} diff --git a/packages/client-axios/tsconfig.check.json b/packages/client-axios/tsconfig.check.json new file mode 100644 index 000000000..74f64f72a --- /dev/null +++ b/packages/client-axios/tsconfig.check.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "exactOptionalPropertyTypes": true, + "module": "NodeNext", + "moduleResolution": "NodeNext", + "noEmit": true, + "strict": true, + "target": "ES2020" + }, + "include": ["dist/**/*"] +} diff --git a/packages/client-axios/tsconfig.json b/packages/client-axios/tsconfig.json new file mode 100644 index 000000000..2d6d90ad8 --- /dev/null +++ b/packages/client-axios/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.base.json", + "compilerOptions": { + "declaration": false, + "esModuleInterop": true + }, + "exclude": ["node_modules", "**/__mocks__"], + "include": ["./src/**/*.ts", "rollup.config.ts", "rollup.dts.config.ts"] +} diff --git a/packages/client-axios/vitest.config.ts b/packages/client-axios/vitest.config.ts new file mode 100644 index 000000000..0431940e9 --- /dev/null +++ b/packages/client-axios/vitest.config.ts @@ -0,0 +1,14 @@ +import { fileURLToPath } from 'node:url'; + +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + coverage: { + exclude: ['dist', 'src/**/*.d.ts'], + include: ['src/**/*.ts'], + provider: 'v8', + }, + root: fileURLToPath(new URL('./', import.meta.url)), + }, +}); diff --git a/packages/client-core/package.json b/packages/client-core/package.json new file mode 100644 index 000000000..94aed0c6f --- /dev/null +++ b/packages/client-core/package.json @@ -0,0 +1,37 @@ +{ + "name": "@hey-api/client-core", + "version": "0.1.0", + "private": true, + "type": "module", + "description": "Core utilities for type-safe openapi-ts clients", + "homepage": "https://heyapi.vercel.app/", + "repository": { + "type": "git", + "url": "git+https://github.com/hey-api/openapi-ts.git" + }, + "bugs": { + "url": "https://github.com/hey-api/openapi-ts/issues" + }, + "license": "MIT", + "main": "./dist/index.cjs", + "types": "./dist/index.d.ts", + "scripts": { + "build-bundle": "rollup --config rollup.config.ts --configPlugin typescript", + "build-types-check": "tsc --project tsconfig.check.json", + "build-types-roll": "rollup --config rollup.dts.config.ts --configPlugin typescript && rimraf temp", + "build-types-temp": "tsc --emitDeclarationOnly --outDir temp -p src", + "build-types": "pnpm build-types-temp && pnpm build-types-roll && pnpm build-types-check", + "build": "pnpm clean && pnpm build-bundle && pnpm build-types", + "clean": "rimraf dist coverage node_modules/.cache", + "dev": "rimraf dist && pnpm build-bundle --watch", + "prepublishOnly": "pnpm build", + "test:coverage": "vitest run --coverage", + "test:update": "vitest watch --update", + "test:watch": "vitest watch", + "test": "vitest run", + "typecheck": "tsc --noEmit" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + } +} diff --git a/packages/client-core/rollup.config.ts b/packages/client-core/rollup.config.ts new file mode 100644 index 000000000..d5cbd4f68 --- /dev/null +++ b/packages/client-core/rollup.config.ts @@ -0,0 +1,47 @@ +import { readFileSync } from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +import commonjs from '@rollup/plugin-commonjs'; +import terser from '@rollup/plugin-terser'; +import typescript from '@rollup/plugin-typescript'; +import type { RollupOptions } from 'rollup'; +import { defineConfig } from 'rollup'; + +const __dirname = fileURLToPath(new URL('.', import.meta.url)); + +const pkg = JSON.parse( + readFileSync(new URL('./package.json', import.meta.url)).toString(), +); + +export const externalDependencies = [ + ...Object.keys(pkg.dependencies ?? {}), + ...Object.keys(pkg.peerDependencies ?? {}), +]; + +function createConfig(isProduction: boolean) { + return defineConfig({ + external: externalDependencies, + input: path.resolve(__dirname, 'src/index.ts'), + output: { + file: path.resolve(__dirname, 'dist/index.cjs'), + format: 'cjs', + }, + plugins: [ + typescript({ + declaration: false, + tsconfig: path.resolve(__dirname, 'src/tsconfig.json'), + }), + commonjs({ + sourceMap: false, + }), + isProduction && terser(), + ], + }); +} + +export default (commandLineArgs: any): RollupOptions[] => { + const isDev = commandLineArgs.watch; + const isProduction = !isDev; + return defineConfig([createConfig(isProduction)]); +}; diff --git a/packages/client-core/rollup.dts.config.ts b/packages/client-core/rollup.dts.config.ts new file mode 100644 index 000000000..8a04de3c0 --- /dev/null +++ b/packages/client-core/rollup.dts.config.ts @@ -0,0 +1,16 @@ +import { defineConfig } from 'rollup'; +import dts from 'rollup-plugin-dts'; + +import { externalDependencies } from './rollup.config'; + +export default defineConfig({ + external: externalDependencies, + input: { + index: './temp/index.d.ts', + }, + output: { + dir: './dist', + format: 'cjs', + }, + plugins: [dts({ respectExternal: true })], +}); diff --git a/packages/client-core/src/__tests__/index.test.ts b/packages/client-core/src/__tests__/index.test.ts new file mode 100644 index 000000000..76ce44875 --- /dev/null +++ b/packages/client-core/src/__tests__/index.test.ts @@ -0,0 +1,7 @@ +import { describe, expect, it } from 'vitest'; + +describe('client core', () => { + it('works', () => { + expect(1).toBe(1); + }); +}); diff --git a/packages/client-core/src/cancelablePromise.ts b/packages/client-core/src/cancelablePromise.ts new file mode 100644 index 000000000..f002b69e9 --- /dev/null +++ b/packages/client-core/src/cancelablePromise.ts @@ -0,0 +1,126 @@ +export class CancelError extends Error { + constructor(message: string) { + super(message); + this.name = 'CancelError'; + } + + public get isCancelled(): boolean { + return true; + } +} + +export interface OnCancel { + readonly isResolved: boolean; + readonly isRejected: boolean; + readonly isCancelled: boolean; + + (cancelHandler: () => void): void; +} + +export class CancelablePromise implements Promise { + private _isResolved: boolean; + private _isRejected: boolean; + private _isCancelled: boolean; + readonly cancelHandlers: (() => void)[]; + readonly promise: Promise; + private _resolve?: (value: T | PromiseLike) => void; + private _reject?: (reason?: unknown) => void; + + constructor( + executor: ( + resolve: (value: T | PromiseLike) => void, + reject: (reason?: unknown) => void, + onCancel: OnCancel, + ) => void, + ) { + this._isResolved = false; + this._isRejected = false; + this._isCancelled = false; + this.cancelHandlers = []; + this.promise = new Promise((resolve, reject) => { + this._resolve = resolve; + this._reject = reject; + + const onResolve = (value: T | PromiseLike): void => { + if (this._isResolved || this._isRejected || this._isCancelled) { + return; + } + this._isResolved = true; + if (this._resolve) this._resolve(value); + }; + + const onReject = (reason?: unknown): void => { + if (this._isResolved || this._isRejected || this._isCancelled) { + return; + } + this._isRejected = true; + if (this._reject) this._reject(reason); + }; + + const onCancel = (cancelHandler: () => void): void => { + if (this._isResolved || this._isRejected || this._isCancelled) { + return; + } + this.cancelHandlers.push(cancelHandler); + }; + + Object.defineProperty(onCancel, 'isResolved', { + get: (): boolean => this._isResolved, + }); + + Object.defineProperty(onCancel, 'isRejected', { + get: (): boolean => this._isRejected, + }); + + Object.defineProperty(onCancel, 'isCancelled', { + get: (): boolean => this._isCancelled, + }); + + return executor(onResolve, onReject, onCancel as OnCancel); + }); + } + + get [Symbol.toStringTag]() { + return 'Cancellable Promise'; + } + + public then( + onFulfilled?: ((value: T) => TResult1 | PromiseLike) | null, + onRejected?: ((reason: unknown) => TResult2 | PromiseLike) | null, + ): Promise { + return this.promise.then(onFulfilled, onRejected); + } + + public catch( + onRejected?: ((reason: unknown) => TResult | PromiseLike) | null, + ): Promise { + return this.promise.catch(onRejected); + } + + public finally(onFinally?: (() => void) | null): Promise { + return this.promise.finally(onFinally); + } + + public cancel(): void { + if (this._isResolved || this._isRejected || this._isCancelled) { + return; + } + this._isCancelled = true; + if (this.cancelHandlers.length) { + try { + for (const cancelHandler of this.cancelHandlers) { + cancelHandler(); + } + } catch (error) { + console.warn('Cancellation threw an error', error); + return; + } + } + this.cancelHandlers.length = 0; + if (this._reject) this._reject(new CancelError('Request aborted')); + } + + public get isCancelled(): boolean { + return this._isCancelled; + } +} diff --git a/packages/client-core/src/index.ts b/packages/client-core/src/index.ts new file mode 100644 index 000000000..8a1c6160d --- /dev/null +++ b/packages/client-core/src/index.ts @@ -0,0 +1,264 @@ +import type { + ApiRequestOptions, + ApiResult, + Headers, + Middleware, + Resolver, +} from './types'; + +export { CancelablePromise, CancelError, OnCancel } from './cancelablePromise'; +export type { ApiRequestOptions, ApiResult } from './types'; + +export class ApiError extends Error { + public readonly url: string; + public readonly status: number; + public readonly statusText: string; + public readonly body: unknown; + public readonly request: ApiRequestOptions; + + constructor( + request: ApiRequestOptions, + response: ApiResult, + message: string, + ) { + super(message); + + this.name = 'ApiError'; + this.url = response.url; + this.status = response.status; + this.statusText = response.statusText; + this.body = response.body; + this.request = request; + } +} + +export class Interceptors { + _fns: Middleware[]; + + constructor() { + this._fns = []; + } + + eject(fn: Middleware) { + const index = this._fns.indexOf(fn); + if (index !== -1) { + this._fns = [...this._fns.slice(0, index), ...this._fns.slice(index + 1)]; + } + } + + use(fn: Middleware) { + this._fns = [...this._fns, fn]; + } +} + +export type OpenAPIConfig = { + BASE: string; + CREDENTIALS: 'include' | 'omit' | 'same-origin'; + ENCODE_PATH?: ((path: string) => string) | undefined; + HEADERS?: Headers | Resolver | undefined; + PASSWORD?: string | Resolver | undefined; + TOKEN?: string | Resolver | undefined; + USERNAME?: string | Resolver | undefined; + VERSION: string; + WITH_CREDENTIALS: boolean; + interceptors: { + request: Interceptors; + response: Interceptors; + }; +}; + +export const OpenAPI: OpenAPIConfig = { + BASE: '{{{server}}}', + CREDENTIALS: 'include', + ENCODE_PATH: undefined, + HEADERS: undefined, + PASSWORD: undefined, + TOKEN: undefined, + USERNAME: undefined, + VERSION: '{{{version}}}', + WITH_CREDENTIALS: false, + interceptors: { + request: new Interceptors(), + response: new Interceptors(), + }, +}; + +export const isString = (value: unknown): value is string => + typeof value === 'string'; + +export const isStringWithValue = (value: unknown): value is string => + isString(value) && value !== ''; + +export const isBlob = (value: any): value is Blob => value instanceof Blob; + +export const isFormData = (value: unknown): value is FormData => + value instanceof FormData; + +export const isSuccess = (status: number): boolean => + status >= 200 && status < 300; + +export const base64 = (str: string): string => { + try { + return btoa(str); + } catch (err) { + return Buffer.from(str).toString('base64'); + } +}; + +export const getQueryString = (params: Record): string => { + const qs: string[] = []; + + const append = (key: string, value: unknown) => { + qs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`); + }; + + const encodePair = (key: string, value: unknown) => { + if (value === undefined || value === null) { + return; + } + + if (value instanceof Date) { + append(key, value.toISOString()); + } else if (Array.isArray(value)) { + value.forEach((v) => encodePair(key, v)); + } else if (typeof value === 'object') { + Object.entries(value).forEach(([k, v]) => encodePair(`${key}[${k}]`, v)); + } else { + append(key, value); + } + }; + + Object.entries(params).forEach(([key, value]) => encodePair(key, value)); + + return qs.length ? `?${qs.join('&')}` : ''; +}; + +export const getUrl = ( + config: OpenAPIConfig, + options: ApiRequestOptions, +): string => { + const encoder = config.ENCODE_PATH || encodeURI; + + const path = options.url + .replace('{api-version}', config.VERSION) + .replace(/{(.*?)}/g, (substring: string, group: string) => { + if (options.path?.hasOwnProperty(group)) { + return encoder(String(options.path[group])); + } + return substring; + }); + + const url = config.BASE + path; + return options.query ? url + getQueryString(options.query) : url; +}; + +export const getFormData = ( + options: ApiRequestOptions, +): FormData | undefined => { + if (options.formData) { + const formData = new FormData(); + + const process = (key: string, value: unknown) => { + if (isString(value) || isBlob(value)) { + formData.append(key, value); + } else { + formData.append(key, JSON.stringify(value)); + } + }; + + Object.entries(options.formData) + .filter(([, value]) => value !== undefined && value !== null) + .forEach(([key, value]) => { + if (Array.isArray(value)) { + value.forEach((v) => process(key, v)); + } else { + process(key, value); + } + }); + + return formData; + } + return undefined; +}; + +export const resolve = async ( + options: ApiRequestOptions, + resolver?: T | Resolver, +): Promise => { + if (typeof resolver === 'function') { + return (resolver as Resolver)(options); + } + return resolver; +}; + +export const catchErrorCodes = ( + options: ApiRequestOptions, + result: ApiResult, +): void => { + const errors: Record = { + 400: 'Bad Request', + 401: 'Unauthorized', + 402: 'Payment Required', + 403: 'Forbidden', + 404: 'Not Found', + 405: 'Method Not Allowed', + 406: 'Not Acceptable', + 407: 'Proxy Authentication Required', + 408: 'Request Timeout', + 409: 'Conflict', + 410: 'Gone', + 411: 'Length Required', + 412: 'Precondition Failed', + 413: 'Payload Too Large', + 414: 'URI Too Long', + 415: 'Unsupported Media Type', + 416: 'Range Not Satisfiable', + 417: 'Expectation Failed', + 418: 'Im a teapot', + 421: 'Misdirected Request', + 422: 'Unprocessable Content', + 423: 'Locked', + 424: 'Failed Dependency', + 425: 'Too Early', + 426: 'Upgrade Required', + 428: 'Precondition Required', + 429: 'Too Many Requests', + 431: 'Request Header Fields Too Large', + 451: 'Unavailable For Legal Reasons', + 500: 'Internal Server Error', + 501: 'Not Implemented', + 502: 'Bad Gateway', + 503: 'Service Unavailable', + 504: 'Gateway Timeout', + 505: 'HTTP Version Not Supported', + 506: 'Variant Also Negotiates', + 507: 'Insufficient Storage', + 508: 'Loop Detected', + 510: 'Not Extended', + 511: 'Network Authentication Required', + ...options.errors, + }; + + const error = errors[result.status]; + if (error) { + throw new ApiError(options, result, error); + } + + if (!result.ok) { + const errorStatus = result.status ?? 'unknown'; + const errorStatusText = result.statusText ?? 'unknown'; + const errorBody = (() => { + try { + return JSON.stringify(result.body, null, 2); + } catch (e) { + return undefined; + } + })(); + + throw new ApiError( + options, + result, + `Generic Error: status: ${errorStatus}; status text: ${errorStatusText}; body: ${errorBody}`, + ); + } +}; diff --git a/packages/client-core/src/tsconfig.json b/packages/client-core/src/tsconfig.json new file mode 100644 index 000000000..4928e973b --- /dev/null +++ b/packages/client-core/src/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "lib": ["ESNext"], + "stripInternal": true + }, + "exclude": ["./**/__tests__"], + "extends": "../tsconfig.base.json", + "include": ["./"] +} diff --git a/packages/client-core/src/types.ts b/packages/client-core/src/types.ts new file mode 100644 index 000000000..ec3aadc39 --- /dev/null +++ b/packages/client-core/src/types.ts @@ -0,0 +1,32 @@ +export type ApiResult = { + readonly body: TData; + readonly ok: boolean; + readonly status: number; + readonly statusText: string; + readonly url: string; +}; + +export type ApiRequestOptions = { + readonly method: + | 'GET' + | 'PUT' + | 'POST' + | 'DELETE' + | 'OPTIONS' + | 'HEAD' + | 'PATCH'; + readonly url: string; + readonly path?: Record; + readonly cookies?: Record; + readonly headers?: Record; + readonly query?: Record; + readonly formData?: Record; + readonly body?: any; + readonly mediaType?: string; + readonly responseHeader?: string; + readonly errors?: Record; +}; + +export type Headers = Record; +export type Middleware = (value: T) => T | Promise; +export type Resolver = (options: ApiRequestOptions) => Promise; diff --git a/packages/client-core/tsconfig.base.json b/packages/client-core/tsconfig.base.json new file mode 100644 index 000000000..64e31b3e5 --- /dev/null +++ b/packages/client-core/tsconfig.base.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "declaration": true, + "esModuleInterop": true, + "module": "ESNext", + "moduleResolution": "Bundler", + "noImplicitOverride": true, + "noUnusedLocals": true, + "strict": true, + "target": "ES2022", + "useUnknownInCatchVariables": false + } +} diff --git a/packages/client-core/tsconfig.check.json b/packages/client-core/tsconfig.check.json new file mode 100644 index 000000000..74f64f72a --- /dev/null +++ b/packages/client-core/tsconfig.check.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "exactOptionalPropertyTypes": true, + "module": "NodeNext", + "moduleResolution": "NodeNext", + "noEmit": true, + "strict": true, + "target": "ES2020" + }, + "include": ["dist/**/*"] +} diff --git a/packages/client-core/tsconfig.json b/packages/client-core/tsconfig.json new file mode 100644 index 000000000..2d6d90ad8 --- /dev/null +++ b/packages/client-core/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.base.json", + "compilerOptions": { + "declaration": false, + "esModuleInterop": true + }, + "exclude": ["node_modules", "**/__mocks__"], + "include": ["./src/**/*.ts", "rollup.config.ts", "rollup.dts.config.ts"] +} diff --git a/packages/client-core/vitest.config.ts b/packages/client-core/vitest.config.ts new file mode 100644 index 000000000..0431940e9 --- /dev/null +++ b/packages/client-core/vitest.config.ts @@ -0,0 +1,14 @@ +import { fileURLToPath } from 'node:url'; + +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + coverage: { + exclude: ['dist', 'src/**/*.d.ts'], + include: ['src/**/*.ts'], + provider: 'v8', + }, + root: fileURLToPath(new URL('./', import.meta.url)), + }, +}); diff --git a/packages/client-fetch/package.json b/packages/client-fetch/package.json new file mode 100644 index 000000000..d45add52a --- /dev/null +++ b/packages/client-fetch/package.json @@ -0,0 +1,53 @@ +{ + "name": "@hey-api/client-fetch", + "version": "0.1.0", + "private": true, + "type": "module", + "description": "Type-safe Fetch API client for your openapi-ts types", + "homepage": "https://heyapi.vercel.app/", + "repository": { + "type": "git", + "url": "git+https://github.com/hey-api/openapi-ts.git" + }, + "bugs": { + "url": "https://github.com/hey-api/openapi-ts/issues" + }, + "license": "MIT", + "keywords": [ + "client", + "codegen", + "fetch", + "generator", + "javascript", + "openapi", + "react", + "svelte", + "swagger", + "typescript", + "vue" + ], + "main": "./dist/index.cjs", + "types": "./dist/index.d.ts", + "scripts": { + "build-bundle": "rollup --config rollup.config.ts --configPlugin typescript", + "build-types-check": "tsc --project tsconfig.check.json", + "build-types-roll": "rollup --config rollup.dts.config.ts --configPlugin typescript && rimraf temp", + "build-types-temp": "tsc --emitDeclarationOnly --outDir temp -p src", + "build-types": "pnpm build-types-temp && pnpm build-types-roll && pnpm build-types-check", + "build": "pnpm clean && pnpm build-bundle && pnpm build-types", + "clean": "rimraf dist coverage node_modules/.cache", + "dev": "rimraf dist && pnpm build-bundle --watch", + "prepublishOnly": "pnpm build", + "test:coverage": "vitest run --coverage", + "test:update": "vitest watch --update", + "test:watch": "vitest watch", + "test": "vitest run", + "typecheck": "tsc --noEmit" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "dependencies": { + "@hey-api/client-core": "workspace:*" + } +} diff --git a/packages/client-fetch/rollup.config.ts b/packages/client-fetch/rollup.config.ts new file mode 100644 index 000000000..d5cbd4f68 --- /dev/null +++ b/packages/client-fetch/rollup.config.ts @@ -0,0 +1,47 @@ +import { readFileSync } from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +import commonjs from '@rollup/plugin-commonjs'; +import terser from '@rollup/plugin-terser'; +import typescript from '@rollup/plugin-typescript'; +import type { RollupOptions } from 'rollup'; +import { defineConfig } from 'rollup'; + +const __dirname = fileURLToPath(new URL('.', import.meta.url)); + +const pkg = JSON.parse( + readFileSync(new URL('./package.json', import.meta.url)).toString(), +); + +export const externalDependencies = [ + ...Object.keys(pkg.dependencies ?? {}), + ...Object.keys(pkg.peerDependencies ?? {}), +]; + +function createConfig(isProduction: boolean) { + return defineConfig({ + external: externalDependencies, + input: path.resolve(__dirname, 'src/index.ts'), + output: { + file: path.resolve(__dirname, 'dist/index.cjs'), + format: 'cjs', + }, + plugins: [ + typescript({ + declaration: false, + tsconfig: path.resolve(__dirname, 'src/tsconfig.json'), + }), + commonjs({ + sourceMap: false, + }), + isProduction && terser(), + ], + }); +} + +export default (commandLineArgs: any): RollupOptions[] => { + const isDev = commandLineArgs.watch; + const isProduction = !isDev; + return defineConfig([createConfig(isProduction)]); +}; diff --git a/packages/client-fetch/rollup.dts.config.ts b/packages/client-fetch/rollup.dts.config.ts new file mode 100644 index 000000000..8a04de3c0 --- /dev/null +++ b/packages/client-fetch/rollup.dts.config.ts @@ -0,0 +1,16 @@ +import { defineConfig } from 'rollup'; +import dts from 'rollup-plugin-dts'; + +import { externalDependencies } from './rollup.config'; + +export default defineConfig({ + external: externalDependencies, + input: { + index: './temp/index.d.ts', + }, + output: { + dir: './dist', + format: 'cjs', + }, + plugins: [dts({ respectExternal: true })], +}); diff --git a/packages/client-fetch/src/__tests__/index.test.ts b/packages/client-fetch/src/__tests__/index.test.ts new file mode 100644 index 000000000..27cc9ccdf --- /dev/null +++ b/packages/client-fetch/src/__tests__/index.test.ts @@ -0,0 +1,7 @@ +import { describe, expect, it } from 'vitest'; + +describe('Fetch API client', () => { + it('works', () => { + expect(1).toBe(1); + }); +}); diff --git a/packages/client-fetch/src/index.ts b/packages/client-fetch/src/index.ts new file mode 100644 index 000000000..7804a5dfe --- /dev/null +++ b/packages/client-fetch/src/index.ts @@ -0,0 +1,220 @@ +import type { + ApiRequestOptions, + ApiResult, + OnCancel, + OpenAPIConfig, +} from '@hey-api/client-core'; +import { + base64, + CancelablePromise, + catchErrorCodes, + getFormData, + getUrl, + isBlob, + isFormData, + isString, + isStringWithValue, + resolve, +} from '@hey-api/client-core'; + +export const getHeaders = async ( + config: OpenAPIConfig, + options: ApiRequestOptions, +): Promise => { + const [token, username, password, additionalHeaders] = await Promise.all([ + resolve(options, config.TOKEN), + resolve(options, config.USERNAME), + resolve(options, config.PASSWORD), + resolve(options, config.HEADERS), + ]); + + const headers = Object.entries({ + Accept: 'application/json', + ...additionalHeaders, + ...options.headers, + }) + .filter(([, value]) => value !== undefined && value !== null) + .reduce( + (headers, [key, value]) => ({ + ...headers, + [key]: String(value), + }), + {} as Record, + ); + + if (isStringWithValue(token)) { + headers['Authorization'] = `Bearer ${token}`; + } + + if (isStringWithValue(username) && isStringWithValue(password)) { + const credentials = base64(`${username}:${password}`); + headers['Authorization'] = `Basic ${credentials}`; + } + + if (options.body !== undefined) { + if (options.mediaType) { + headers['Content-Type'] = options.mediaType; + } else if (isBlob(options.body)) { + headers['Content-Type'] = options.body.type || 'application/octet-stream'; + } else if (isString(options.body)) { + headers['Content-Type'] = 'text/plain'; + } else if (!isFormData(options.body)) { + headers['Content-Type'] = 'application/json'; + } + } + + return new Headers(headers); +}; + +export const getRequestBody = (options: ApiRequestOptions): unknown => { + if (options.body !== undefined) { + if ( + options.mediaType?.includes('application/json') || + options.mediaType?.includes('+json') + ) { + return JSON.stringify(options.body); + } else if ( + isString(options.body) || + isBlob(options.body) || + isFormData(options.body) + ) { + return options.body; + } else { + return JSON.stringify(options.body); + } + } + return undefined; +}; + +export const sendRequest = async ( + config: OpenAPIConfig, + options: ApiRequestOptions, + url: string, + body: any, + formData: FormData | undefined, + headers: Headers, + onCancel: OnCancel, +): Promise => { + const controller = new AbortController(); + + let request: RequestInit = { + body: body ?? formData, + headers, + method: options.method, + signal: controller.signal, + }; + + if (config.WITH_CREDENTIALS) { + request.credentials = config.CREDENTIALS; + } + + for (const fn of config.interceptors.request._fns) { + request = await fn(request); + } + + onCancel(() => controller.abort()); + + return await fetch(url, request); +}; + +export const getResponseHeader = ( + response: Response, + responseHeader?: string, +): string | undefined => { + if (responseHeader) { + const content = response.headers.get(responseHeader); + if (isString(content)) { + return content; + } + } + return undefined; +}; + +export const getResponseBody = async (response: Response): Promise => { + if (response.status !== 204) { + try { + const contentType = response.headers.get('Content-Type'); + if (contentType) { + const binaryTypes = [ + 'application/octet-stream', + 'application/pdf', + 'application/zip', + 'audio/', + 'image/', + 'video/', + ]; + if ( + contentType.includes('application/json') || + contentType.includes('+json') + ) { + return await response.json(); + } else if (binaryTypes.some((type) => contentType.includes(type))) { + return await response.blob(); + } else if (contentType.includes('multipart/form-data')) { + return await response.formData(); + } else if (contentType.includes('text/')) { + return await response.text(); + } + } + } catch (error) { + console.error(error); + } + } + return undefined; +}; + +/** + * Request method + * @param config The OpenAPI configuration object + * @param options The request options from the service + * @returns CancelablePromise + * @throws ApiError + */ +export const request = ( + config: OpenAPIConfig, + options: ApiRequestOptions, +): CancelablePromise => + new CancelablePromise(async (resolve, reject, onCancel) => { + try { + const url = getUrl(config, options); + const formData = getFormData(options); + const body = getRequestBody(options); + const headers = await getHeaders(config, options); + + if (!onCancel.isCancelled) { + let response = await sendRequest( + config, + options, + url, + body, + formData, + headers, + onCancel, + ); + + for (const fn of config.interceptors.response._fns) { + response = await fn(response); + } + + const responseBody = await getResponseBody(response); + const responseHeader = getResponseHeader( + response, + options.responseHeader, + ); + + const result: ApiResult = { + body: responseHeader ?? responseBody, + ok: response.ok, + status: response.status, + statusText: response.statusText, + url, + }; + + catchErrorCodes(options, result); + + resolve(result.body); + } + } catch (error) { + reject(error); + } + }); diff --git a/packages/client-fetch/src/tsconfig.json b/packages/client-fetch/src/tsconfig.json new file mode 100644 index 000000000..4928e973b --- /dev/null +++ b/packages/client-fetch/src/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "lib": ["ESNext"], + "stripInternal": true + }, + "exclude": ["./**/__tests__"], + "extends": "../tsconfig.base.json", + "include": ["./"] +} diff --git a/packages/client-fetch/tsconfig.base.json b/packages/client-fetch/tsconfig.base.json new file mode 100644 index 000000000..64e31b3e5 --- /dev/null +++ b/packages/client-fetch/tsconfig.base.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "declaration": true, + "esModuleInterop": true, + "module": "ESNext", + "moduleResolution": "Bundler", + "noImplicitOverride": true, + "noUnusedLocals": true, + "strict": true, + "target": "ES2022", + "useUnknownInCatchVariables": false + } +} diff --git a/packages/client-fetch/tsconfig.check.json b/packages/client-fetch/tsconfig.check.json new file mode 100644 index 000000000..74f64f72a --- /dev/null +++ b/packages/client-fetch/tsconfig.check.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "exactOptionalPropertyTypes": true, + "module": "NodeNext", + "moduleResolution": "NodeNext", + "noEmit": true, + "strict": true, + "target": "ES2020" + }, + "include": ["dist/**/*"] +} diff --git a/packages/client-fetch/tsconfig.json b/packages/client-fetch/tsconfig.json new file mode 100644 index 000000000..2d6d90ad8 --- /dev/null +++ b/packages/client-fetch/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.base.json", + "compilerOptions": { + "declaration": false, + "esModuleInterop": true + }, + "exclude": ["node_modules", "**/__mocks__"], + "include": ["./src/**/*.ts", "rollup.config.ts", "rollup.dts.config.ts"] +} diff --git a/packages/client-fetch/vitest.config.ts b/packages/client-fetch/vitest.config.ts new file mode 100644 index 000000000..0431940e9 --- /dev/null +++ b/packages/client-fetch/vitest.config.ts @@ -0,0 +1,14 @@ +import { fileURLToPath } from 'node:url'; + +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + coverage: { + exclude: ['dist', 'src/**/*.d.ts'], + include: ['src/**/*.ts'], + provider: 'v8', + }, + root: fileURLToPath(new URL('./', import.meta.url)), + }, +}); diff --git a/packages/openapi-ts/package.json b/packages/openapi-ts/package.json index 61df8a535..5f36a9613 100644 --- a/packages/openapi-ts/package.json +++ b/packages/openapi-ts/package.json @@ -13,19 +13,19 @@ }, "license": "MIT", "keywords": [ - "openapi", - "swagger", + "angular", + "axios", + "codegen", + "fetch", "generator", - "typescript", "javascript", - "codegen", - "yaml", "json", - "fetch", + "node", + "openapi", + "swagger", + "typescript", "xhr", - "axios", - "angular", - "node" + "yaml" ], "main": "./dist/node/index.cjs", "types": "./dist/node/index.d.ts", @@ -45,8 +45,6 @@ "build": "pnpm clean && pnpm build-bundle && pnpm build-types", "clean": "rimraf dist test/generated test/e2e/generated coverage node_modules/.cache", "dev": "rimraf dist && pnpm build-bundle --watch", - "lint:fix": "eslint . --fix", - "lint": "eslint .", "prepublishOnly": "pnpm build", "test:coverage": "vitest run --config vitest.config.unit.ts --coverage", "test:e2e": "vitest run --config vitest.config.e2e.ts", @@ -81,35 +79,21 @@ "@angular/platform-browser": "17.3.5", "@angular/platform-browser-dynamic": "17.3.5", "@angular/router": "17.3.5", - "@rollup/plugin-commonjs": "25.0.7", "@rollup/plugin-json": "6.1.0", "@rollup/plugin-node-resolve": "15.2.3", - "@rollup/plugin-terser": "0.4.4", - "@rollup/plugin-typescript": "11.1.6", "@types/cross-spawn": "6.0.6", "@types/express": "4.17.21", - "@types/node": "20.12.7", - "@vitest/coverage-v8": "1.5.0", "axios": "1.6.8", "cross-spawn": "7.0.3", "eslint": "9.1.0", - "eslint-config-prettier": "9.1.0", - "eslint-plugin-simple-import-sort": "12.1.0", - "eslint-plugin-sort-keys-fix": "1.1.2", "express": "4.19.2", "glob": "10.3.12", - "globals": "15.0.0", "node-fetch": "3.3.2", "prettier": "3.2.5", "puppeteer": "22.6.5", - "rimraf": "5.0.5", - "rollup": "4.16.1", - "rollup-plugin-dts": "6.1.0", "rxjs": "7.8.1", "ts-node": "10.9.2", "tslib": "2.6.2", - "typescript": "5.4.5", - "typescript-eslint": "7.7.0", - "vitest": "1.5.0" + "typescript": "5.4.5" } } diff --git a/packages/openapi-ts/rollup.config.ts b/packages/openapi-ts/rollup.config.ts index 95e56ce9c..5989e110c 100644 --- a/packages/openapi-ts/rollup.config.ts +++ b/packages/openapi-ts/rollup.config.ts @@ -58,8 +58,8 @@ const pkg = JSON.parse( const esmDependencies = ['camelcase']; export const externalDependencies = [ - ...Object.keys(pkg.dependencies), - ...Object.keys(pkg.peerDependencies), + ...Object.keys(pkg.dependencies ?? {}), + ...Object.keys(pkg.peerDependencies ?? {}), ].filter((dependency) => !esmDependencies.includes(dependency)); function createConfig(isProduction: boolean) { diff --git a/packages/openapi-ts/src/index.ts b/packages/openapi-ts/src/index.ts index 3401c297c..32e909c3c 100644 --- a/packages/openapi-ts/src/index.ts +++ b/packages/openapi-ts/src/index.ts @@ -21,6 +21,7 @@ type PackageDependencies = { // Dependencies used in each client. User must have installed these to use the generated client const clientDependencies: Record = { + '@hey-api': [], angular: ['@angular/common', '@angular/core', 'rxjs'], axios: ['axios'], fetch: [], @@ -92,8 +93,12 @@ const processOutput = (dependencies: Dependencies) => { }; const inferClient = (dependencies: Dependencies): Config['client'] => { - if (Object.keys(dependencies).some((d) => d.startsWith('@angular'))) { - return 'angular'; + if ( + dependencies['@hey-api/client-axios'] || + dependencies['@hey-api/client-fetch'] || + dependencies['@hey-api/client-nextjs'] + ) { + return '@hey-api'; } if (dependencies.axios) { return 'axios'; @@ -101,6 +106,9 @@ const inferClient = (dependencies: Dependencies): Config['client'] => { if (dependencies['node-fetch']) { return 'node'; } + if (Object.keys(dependencies).some((d) => d.startsWith('@angular'))) { + return 'angular'; + } return 'fetch'; }; @@ -289,7 +297,7 @@ const initConfig = async ( debug, dryRun, enums, - exportCore, + exportCore: client === '@hey-api' ? false : exportCore, format, input, lint, diff --git a/packages/openapi-ts/src/types/config.ts b/packages/openapi-ts/src/types/config.ts index 2074b6ecb..ae1fbf6e6 100644 --- a/packages/openapi-ts/src/types/config.ts +++ b/packages/openapi-ts/src/types/config.ts @@ -7,7 +7,7 @@ export interface UserConfig { * The selected HTTP client (fetch, xhr, node or axios) * @default 'fetch' */ - client?: 'angular' | 'axios' | 'fetch' | 'node' | 'xhr'; + client?: '@hey-api' | 'angular' | 'axios' | 'fetch' | 'node' | 'xhr'; /** * Run in debug mode? * @default false diff --git a/packages/openapi-ts/src/utils/getHttpRequestName.ts b/packages/openapi-ts/src/utils/getHttpRequestName.ts index 680a64a47..832bba38c 100644 --- a/packages/openapi-ts/src/utils/getHttpRequestName.ts +++ b/packages/openapi-ts/src/utils/getHttpRequestName.ts @@ -6,6 +6,8 @@ import type { Config } from '../types/config'; */ export const getHttpRequestName = (client: Config['client']): string => { switch (client) { + case '@hey-api': + return ''; case 'angular': return 'AngularHttpRequest'; case 'axios': diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index acb9287e4..7394419d3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,9 +11,39 @@ importers: '@changesets/cli': specifier: 2.27.1 version: 2.27.1 + '@rollup/plugin-commonjs': + specifier: 25.0.7 + version: 25.0.7(rollup@4.16.1) + '@rollup/plugin-terser': + specifier: 0.4.4 + version: 0.4.4(rollup@4.16.1) + '@rollup/plugin-typescript': + specifier: 11.1.6 + version: 11.1.6(rollup@4.16.1)(typescript@5.4.5) '@svitejs/changesets-changelog-github-compact': specifier: 1.1.0 version: 1.1.0 + '@types/node': + specifier: 20.12.7 + version: 20.12.7 + '@vitest/coverage-v8': + specifier: 1.5.0 + version: 1.5.0(vitest@1.5.0) + eslint: + specifier: 9.1.0 + version: 9.1.0 + eslint-config-prettier: + specifier: 9.1.0 + version: 9.1.0(eslint@9.1.0) + eslint-plugin-simple-import-sort: + specifier: 12.1.0 + version: 12.1.0(eslint@9.1.0) + eslint-plugin-sort-keys-fix: + specifier: 1.1.2 + version: 1.1.2 + globals: + specifier: 15.0.0 + version: 15.0.0 husky: specifier: 9.0.11 version: 9.0.11 @@ -23,12 +53,48 @@ importers: prettier: specifier: 3.2.5 version: 3.2.5 + rimraf: + specifier: 5.0.5 + version: 5.0.5 + rollup: + specifier: 4.16.1 + version: 4.16.1 + rollup-plugin-dts: + specifier: 6.1.0 + version: 6.1.0(rollup@4.16.1)(typescript@5.4.5) + typescript: + specifier: 5.4.5 + version: 5.4.5 + typescript-eslint: + specifier: 7.7.0 + version: 7.7.0(eslint@9.1.0)(typescript@5.4.5) + vitest: + specifier: 1.5.0 + version: 1.5.0(@types/node@20.12.7) docs: devDependencies: vitepress: specifier: 1.1.3 - version: 1.1.3(@algolia/client-search@4.23.3)(search-insights@2.13.0) + version: 1.1.3(@algolia/client-search@4.23.3)(@types/node@20.12.7)(search-insights@2.13.0)(typescript@5.4.5) + + packages/client-axios: + dependencies: + '@hey-api/client-core': + specifier: workspace:* + version: link:../client-core + devDependencies: + axios: + specifier: 1.6.8 + version: 1.6.8 + + packages/client-core: {} + + packages/client-fetch: + dependencies: + '@hey-api/client-core': + specifier: workspace:* + version: link:../client-core packages/openapi-ts: dependencies: @@ -81,33 +147,18 @@ importers: '@angular/router': specifier: 17.3.5 version: 17.3.5(@angular/common@17.3.5)(@angular/core@17.3.5)(@angular/platform-browser@17.3.5)(rxjs@7.8.1) - '@rollup/plugin-commonjs': - specifier: 25.0.7 - version: 25.0.7(rollup@4.16.1) '@rollup/plugin-json': specifier: 6.1.0 version: 6.1.0(rollup@4.16.1) '@rollup/plugin-node-resolve': specifier: 15.2.3 version: 15.2.3(rollup@4.16.1) - '@rollup/plugin-terser': - specifier: 0.4.4 - version: 0.4.4(rollup@4.16.1) - '@rollup/plugin-typescript': - specifier: 11.1.6 - version: 11.1.6(rollup@4.16.1)(tslib@2.6.2)(typescript@5.4.5) '@types/cross-spawn': specifier: 6.0.6 version: 6.0.6 '@types/express': specifier: 4.17.21 version: 4.17.21 - '@types/node': - specifier: 20.12.7 - version: 20.12.7 - '@vitest/coverage-v8': - specifier: 1.5.0 - version: 1.5.0(vitest@1.5.0) axios: specifier: 1.6.8 version: 1.6.8 @@ -117,24 +168,12 @@ importers: eslint: specifier: 9.1.0 version: 9.1.0 - eslint-config-prettier: - specifier: 9.1.0 - version: 9.1.0(eslint@9.1.0) - eslint-plugin-simple-import-sort: - specifier: 12.1.0 - version: 12.1.0(eslint@9.1.0) - eslint-plugin-sort-keys-fix: - specifier: 1.1.2 - version: 1.1.2 express: specifier: 4.19.2 version: 4.19.2 glob: specifier: 10.3.12 version: 10.3.12 - globals: - specifier: 15.0.0 - version: 15.0.0 node-fetch: specifier: 3.3.2 version: 3.3.2 @@ -144,15 +183,6 @@ importers: puppeteer: specifier: 22.6.5 version: 22.6.5(typescript@5.4.5) - rimraf: - specifier: 5.0.5 - version: 5.0.5 - rollup: - specifier: 4.16.1 - version: 4.16.1 - rollup-plugin-dts: - specifier: 6.1.0 - version: 6.1.0(rollup@4.16.1)(typescript@5.4.5) rxjs: specifier: 7.8.1 version: 7.8.1 @@ -165,12 +195,6 @@ importers: typescript: specifier: 5.4.5 version: 5.4.5 - typescript-eslint: - specifier: 7.7.0 - version: 7.7.0(eslint@9.1.0)(typescript@5.4.5) - vitest: - specifier: 1.5.0 - version: 1.5.0(@types/node@20.12.7)(less@4.2.0) packages: @@ -179,92 +203,81 @@ packages: engines: {node: '>=0.10.0'} dev: true - /@algolia/autocomplete-core@1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.2)(search-insights@2.13.0): + /@algolia/autocomplete-core@1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3)(search-insights@2.13.0): resolution: {integrity: sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==} dependencies: - '@algolia/autocomplete-plugin-algolia-insights': 1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.2)(search-insights@2.13.0) - '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.2) + '@algolia/autocomplete-plugin-algolia-insights': 1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3)(search-insights@2.13.0) + '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3) transitivePeerDependencies: - '@algolia/client-search' - algoliasearch - search-insights dev: true - /@algolia/autocomplete-plugin-algolia-insights@1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.2)(search-insights@2.13.0): + /@algolia/autocomplete-plugin-algolia-insights@1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3)(search-insights@2.13.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.23.3)(algoliasearch@4.23.2) + '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3) search-insights: 2.13.0 transitivePeerDependencies: - '@algolia/client-search' - algoliasearch dev: true - /@algolia/autocomplete-preset-algolia@1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.2): + /@algolia/autocomplete-preset-algolia@1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3): resolution: {integrity: sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==} peerDependencies: '@algolia/client-search': '>= 4.9.1 < 6' algoliasearch: '>= 4.9.1 < 6' dependencies: - '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.2) + '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3) '@algolia/client-search': 4.23.3 - algoliasearch: 4.23.2 + algoliasearch: 4.23.3 dev: true - /@algolia/autocomplete-shared@1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.2): + /@algolia/autocomplete-shared@1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3): resolution: {integrity: sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==} peerDependencies: '@algolia/client-search': '>= 4.9.1 < 6' algoliasearch: '>= 4.9.1 < 6' dependencies: '@algolia/client-search': 4.23.3 - algoliasearch: 4.23.2 + algoliasearch: 4.23.3 dev: true - /@algolia/cache-browser-local-storage@4.23.2: - resolution: {integrity: sha512-PvRQdCmtiU22dw9ZcTJkrVKgNBVAxKgD0/cfiqyxhA5+PHzA2WDt6jOmZ9QASkeM2BpyzClJb/Wr1yt2/t78Kw==} + /@algolia/cache-browser-local-storage@4.23.3: + resolution: {integrity: sha512-vRHXYCpPlTDE7i6UOy2xE03zHF2C8MEFjPN2v7fRbqVpcOvAUQK81x3Kc21xyb5aSIpYCjWCZbYZuz8Glyzyyg==} dependencies: - '@algolia/cache-common': 4.23.2 - dev: true - - /@algolia/cache-common@4.23.2: - resolution: {integrity: sha512-OUK/6mqr6CQWxzl/QY0/mwhlGvS6fMtvEPyn/7AHUx96NjqDA4X4+Ju7aXFQKh+m3jW9VPB0B9xvEQgyAnRPNw==} + '@algolia/cache-common': 4.23.3 dev: true /@algolia/cache-common@4.23.3: resolution: {integrity: sha512-h9XcNI6lxYStaw32pHpB1TMm0RuxphF+Ik4o7tcQiodEdpKK+wKufY6QXtba7t3k8eseirEMVB83uFFF3Nu54A==} dev: true - /@algolia/cache-in-memory@4.23.2: - resolution: {integrity: sha512-rfbi/SnhEa3MmlqQvgYz/9NNJ156NkU6xFxjbxBtLWnHbpj+qnlMoKd+amoiacHRITpajg6zYbLM9dnaD3Bczw==} - dependencies: - '@algolia/cache-common': 4.23.2 - dev: true - - /@algolia/client-account@4.23.2: - resolution: {integrity: sha512-VbrOCLIN/5I7iIdskSoSw3uOUPF516k4SjDD4Qz3BFwa3of7D9A0lzBMAvQEJJEPHWdVraBJlGgdJq/ttmquJQ==} + /@algolia/cache-in-memory@4.23.3: + resolution: {integrity: sha512-yvpbuUXg/+0rbcagxNT7un0eo3czx2Uf0y4eiR4z4SD7SiptwYTpbuS0IHxcLHG3lq22ukx1T6Kjtk/rT+mqNg==} dependencies: - '@algolia/client-common': 4.23.2 - '@algolia/client-search': 4.23.2 - '@algolia/transporter': 4.23.2 + '@algolia/cache-common': 4.23.3 dev: true - /@algolia/client-analytics@4.23.2: - resolution: {integrity: sha512-lLj7irsAztGhMoEx/SwKd1cwLY6Daf1Q5f2AOsZacpppSvuFvuBrmkzT7pap1OD/OePjLKxicJS8wNA0+zKtuw==} + /@algolia/client-account@4.23.3: + resolution: {integrity: sha512-hpa6S5d7iQmretHHF40QGq6hz0anWEHGlULcTIT9tbUssWUriN9AUXIFQ8Ei4w9azD0hc1rUok9/DeQQobhQMA==} dependencies: - '@algolia/client-common': 4.23.2 - '@algolia/client-search': 4.23.2 - '@algolia/requester-common': 4.23.2 - '@algolia/transporter': 4.23.2 + '@algolia/client-common': 4.23.3 + '@algolia/client-search': 4.23.3 + '@algolia/transporter': 4.23.3 dev: true - /@algolia/client-common@4.23.2: - resolution: {integrity: sha512-Q2K1FRJBern8kIfZ0EqPvUr3V29ICxCm/q42zInV+VJRjldAD9oTsMGwqUQ26GFMdFYmqkEfCbY4VGAiQhh22g==} + /@algolia/client-analytics@4.23.3: + resolution: {integrity: sha512-LBsEARGS9cj8VkTAVEZphjxTjMVCci+zIIiRhpFun9jGDUlS1XmhCW7CTrnaWeIuCQS/2iPyRqSy1nXPjcBLRA==} dependencies: - '@algolia/requester-common': 4.23.2 - '@algolia/transporter': 4.23.2 + '@algolia/client-common': 4.23.3 + '@algolia/client-search': 4.23.3 + '@algolia/requester-common': 4.23.3 + '@algolia/transporter': 4.23.3 dev: true /@algolia/client-common@4.23.3: @@ -274,20 +287,12 @@ packages: '@algolia/transporter': 4.23.3 dev: true - /@algolia/client-personalization@4.23.2: - resolution: {integrity: sha512-vwPsgnCGhUcHhhQG5IM27z8q7dWrN9itjdvgA6uKf2e9r7vB+WXt4OocK0CeoYQt3OGEAExryzsB8DWqdMK5wg==} + /@algolia/client-personalization@4.23.3: + resolution: {integrity: sha512-3E3yF3Ocr1tB/xOZiuC3doHQBQ2zu2MPTYZ0d4lpfWads2WTKG7ZzmGnsHmm63RflvDeLK/UVx7j2b3QuwKQ2g==} dependencies: - '@algolia/client-common': 4.23.2 - '@algolia/requester-common': 4.23.2 - '@algolia/transporter': 4.23.2 - dev: true - - /@algolia/client-search@4.23.2: - resolution: {integrity: sha512-CxSB29OVGSE7l/iyoHvamMonzq7Ev8lnk/OkzleODZ1iBcCs3JC/XgTIKzN/4RSTrJ9QybsnlrN/bYCGufo7qw==} - dependencies: - '@algolia/client-common': 4.23.2 - '@algolia/requester-common': 4.23.2 - '@algolia/transporter': 4.23.2 + '@algolia/client-common': 4.23.3 + '@algolia/requester-common': 4.23.3 + '@algolia/transporter': 4.23.3 dev: true /@algolia/client-search@4.23.3: @@ -298,62 +303,46 @@ packages: '@algolia/transporter': 4.23.3 dev: true - /@algolia/logger-common@4.23.2: - resolution: {integrity: sha512-jGM49Q7626cXZ7qRAWXn0jDlzvoA1FvN4rKTi1g0hxKsTTSReyYk0i1ADWjChDPl3Q+nSDhJuosM2bBUAay7xw==} - dev: true - /@algolia/logger-common@4.23.3: resolution: {integrity: sha512-y9kBtmJwiZ9ZZ+1Ek66P0M68mHQzKRxkW5kAAXYN/rdzgDN0d2COsViEFufxJ0pb45K4FRcfC7+33YB4BLrZ+g==} dev: true - /@algolia/logger-console@4.23.2: - resolution: {integrity: sha512-oo+lnxxEmlhTBTFZ3fGz1O8PJ+G+8FiAoMY2Qo3Q4w23xocQev6KqDTA1JQAGPDxAewNA2VBwWOsVXeXFjrI/Q==} + /@algolia/logger-console@4.23.3: + resolution: {integrity: sha512-8xoiseoWDKuCVnWP8jHthgaeobDLolh00KJAdMe9XPrWPuf1by732jSpgy2BlsLTaT9m32pHI8CRfrOqQzHv3A==} dependencies: - '@algolia/logger-common': 4.23.2 + '@algolia/logger-common': 4.23.3 dev: true - /@algolia/recommend@4.23.2: - resolution: {integrity: sha512-Q75CjnzRCDzgIlgWfPnkLtrfF4t82JCirhalXkSSwe/c1GH5pWh4xUyDOR3KTMo+YxxX3zTlrL/FjHmUJEWEcg==} + /@algolia/recommend@4.23.3: + resolution: {integrity: sha512-9fK4nXZF0bFkdcLBRDexsnGzVmu4TSYZqxdpgBW2tEyfuSSY54D4qSRkLmNkrrz4YFvdh2GM1gA8vSsnZPR73w==} dependencies: - '@algolia/cache-browser-local-storage': 4.23.2 - '@algolia/cache-common': 4.23.2 - '@algolia/cache-in-memory': 4.23.2 - '@algolia/client-common': 4.23.2 - '@algolia/client-search': 4.23.2 - '@algolia/logger-common': 4.23.2 - '@algolia/logger-console': 4.23.2 - '@algolia/requester-browser-xhr': 4.23.2 - '@algolia/requester-common': 4.23.2 - '@algolia/requester-node-http': 4.23.2 - '@algolia/transporter': 4.23.2 + '@algolia/cache-browser-local-storage': 4.23.3 + '@algolia/cache-common': 4.23.3 + '@algolia/cache-in-memory': 4.23.3 + '@algolia/client-common': 4.23.3 + '@algolia/client-search': 4.23.3 + '@algolia/logger-common': 4.23.3 + '@algolia/logger-console': 4.23.3 + '@algolia/requester-browser-xhr': 4.23.3 + '@algolia/requester-common': 4.23.3 + '@algolia/requester-node-http': 4.23.3 + '@algolia/transporter': 4.23.3 dev: true - /@algolia/requester-browser-xhr@4.23.2: - resolution: {integrity: sha512-TO9wLlp8+rvW9LnIfyHsu8mNAMYrqNdQ0oLF6eTWFxXfxG3k8F/Bh7nFYGk2rFAYty4Fw4XUtrv/YjeNDtM5og==} + /@algolia/requester-browser-xhr@4.23.3: + resolution: {integrity: sha512-jDWGIQ96BhXbmONAQsasIpTYWslyjkiGu0Quydjlowe+ciqySpiDUrJHERIRfELE5+wFc7hc1Q5hqjGoV7yghw==} dependencies: - '@algolia/requester-common': 4.23.2 - dev: true - - /@algolia/requester-common@4.23.2: - resolution: {integrity: sha512-3EfpBS0Hri0lGDB5H/BocLt7Vkop0bTTLVUBB844HH6tVycwShmsV6bDR7yXbQvFP1uNpgePRD3cdBCjeHmk6Q==} + '@algolia/requester-common': 4.23.3 dev: true /@algolia/requester-common@4.23.3: resolution: {integrity: sha512-xloIdr/bedtYEGcXCiF2muajyvRhwop4cMZo+K2qzNht0CMzlRkm8YsDdj5IaBhshqfgmBb3rTg4sL4/PpvLYw==} dev: true - /@algolia/requester-node-http@4.23.2: - resolution: {integrity: sha512-SVzgkZM/malo+2SB0NWDXpnT7nO5IZwuDTaaH6SjLeOHcya1o56LSWXk+3F3rNLz2GVH+I/rpYKiqmHhSOjerw==} + /@algolia/requester-node-http@4.23.3: + resolution: {integrity: sha512-zgu++8Uj03IWDEJM3fuNl34s746JnZOWn1Uz5taV1dFyJhVM/kTNw9Ik7YJWiUNHJQXcaD8IXD1eCb0nq/aByA==} dependencies: - '@algolia/requester-common': 4.23.2 - dev: true - - /@algolia/transporter@4.23.2: - resolution: {integrity: sha512-GY3aGKBy+8AK4vZh8sfkatDciDVKad5rTY2S10Aefyjh7e7UGBP4zigf42qVXwU8VOPwi7l/L7OACGMOFcjB0Q==} - dependencies: - '@algolia/cache-common': 4.23.2 - '@algolia/logger-common': 4.23.2 - '@algolia/requester-common': 4.23.2 + '@algolia/requester-common': 4.23.3 dev: true /@algolia/transporter@4.23.3: @@ -769,7 +758,7 @@ packages: dependencies: '@ampproject/remapping': 2.3.0 '@babel/code-frame': 7.24.2 - '@babel/generator': 7.24.4 + '@babel/generator': 7.23.6 '@babel/helper-compilation-targets': 7.23.6 '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0) '@babel/helpers': 7.24.4 @@ -1048,7 +1037,6 @@ packages: /@babel/highlight@7.24.2: resolution: {integrity: sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==} engines: {node: '>=6.9.0'} - requiresBuild: true dependencies: '@babel/helper-validator-identifier': 7.22.20 chalk: 2.4.2 @@ -1908,7 +1896,7 @@ packages: babel-plugin-polyfill-corejs2: 0.4.10(@babel/core@7.24.0) babel-plugin-polyfill-corejs3: 0.9.0(@babel/core@7.24.0) babel-plugin-polyfill-regenerator: 0.5.5(@babel/core@7.24.0) - core-js-compat: 3.36.1 + core-js-compat: 3.37.0 semver: 6.3.1 transitivePeerDependencies: - supports-color @@ -1936,8 +1924,8 @@ packages: regenerator-runtime: 0.14.1 dev: true - /@babel/runtime@7.24.1: - resolution: {integrity: sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==} + /@babel/runtime@7.24.4: + resolution: {integrity: sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==} engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.14.1 @@ -1986,7 +1974,7 @@ packages: /@changesets/apply-release-plan@7.0.0: resolution: {integrity: sha512-vfi69JR416qC9hWmFGSxj7N6wA5J222XNBmezSVATPWDVPIF7gkd4d8CpbEbXmRWbVrkoli3oerGS6dcL/BGsQ==} dependencies: - '@babel/runtime': 7.24.1 + '@babel/runtime': 7.24.4 '@changesets/config': 3.0.0 '@changesets/get-version-range-type': 0.4.0 '@changesets/git': 3.0.0 @@ -2004,7 +1992,7 @@ packages: /@changesets/assemble-release-plan@6.0.0: resolution: {integrity: sha512-4QG7NuisAjisbW4hkLCmGW2lRYdPrKzro+fCtZaILX+3zdUELSvYjpL4GTv0E4aM9Mef3PuIQp89VmHJ4y2bfw==} dependencies: - '@babel/runtime': 7.24.1 + '@babel/runtime': 7.24.4 '@changesets/errors': 0.2.0 '@changesets/get-dependents-graph': 2.0.0 '@changesets/types': 6.0.0 @@ -2022,7 +2010,7 @@ packages: resolution: {integrity: sha512-iJ91xlvRnnrJnELTp4eJJEOPjgpF3NOh4qeQehM6Ugiz9gJPRZ2t+TsXun6E3AMN4hScZKjqVXl0TX+C7AB3ZQ==} hasBin: true dependencies: - '@babel/runtime': 7.24.1 + '@babel/runtime': 7.24.4 '@changesets/apply-release-plan': 7.0.0 '@changesets/assemble-release-plan': 6.0.0 '@changesets/changelog-git': 0.2.0 @@ -2096,7 +2084,7 @@ packages: /@changesets/get-release-plan@4.0.0: resolution: {integrity: sha512-9L9xCUeD/Tb6L/oKmpm8nyzsOzhdNBBbt/ZNcjynbHC07WW4E1eX8NMGC5g5SbM5z/V+MOrYsJ4lRW41GCbg3w==} dependencies: - '@babel/runtime': 7.24.1 + '@babel/runtime': 7.24.4 '@changesets/assemble-release-plan': 6.0.0 '@changesets/config': 3.0.0 '@changesets/pre': 2.0.0 @@ -2112,7 +2100,7 @@ packages: /@changesets/git@3.0.0: resolution: {integrity: sha512-vvhnZDHe2eiBNRFHEgMiGd2CT+164dfYyrJDhwwxTVD/OW0FUD6G7+4DIx1dNwkwjHyzisxGAU96q0sVNBns0w==} dependencies: - '@babel/runtime': 7.24.1 + '@babel/runtime': 7.24.4 '@changesets/errors': 0.2.0 '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 @@ -2137,7 +2125,7 @@ packages: /@changesets/pre@2.0.0: resolution: {integrity: sha512-HLTNYX/A4jZxc+Sq8D1AMBsv+1qD6rmmJtjsCJa/9MSRybdxh0mjbTvE6JYZQ/ZiQ0mMlDOlGPXTm9KLTU3jyw==} dependencies: - '@babel/runtime': 7.24.1 + '@babel/runtime': 7.24.4 '@changesets/errors': 0.2.0 '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 @@ -2147,7 +2135,7 @@ packages: /@changesets/read@0.6.0: resolution: {integrity: sha512-ZypqX8+/im1Fm98K4YcZtmLKgjs1kDQ5zHpc2U1qdtNBmZZfo/IBiG162RoP0CUF05tvp2y4IspH11PLnPxuuw==} dependencies: - '@babel/runtime': 7.24.1 + '@babel/runtime': 7.24.4 '@changesets/git': 3.0.0 '@changesets/logger': 0.1.0 '@changesets/parse': 0.4.0 @@ -2168,7 +2156,7 @@ packages: /@changesets/write@0.3.0: resolution: {integrity: sha512-slGLb21fxZVUYbyea+94uFiD6ntQW0M2hIKNznFizDhZPDgn2c/fv1UzzlW43RVzh1BEDuIqW6hzlJ1OflNmcw==} dependencies: - '@babel/runtime': 7.24.1 + '@babel/runtime': 7.24.4 '@changesets/types': 6.0.0 fs-extra: 7.0.1 human-id: 1.0.2 @@ -2195,7 +2183,7 @@ packages: resolution: {integrity: sha512-QujhqINEElrkIfKwyyyTfbsfMAYCkylInLYMRqHy7PHc8xTBQCow73tlo/Kc7oIwBrCLf0P3YhjlOeV4v8hevQ==} dependencies: '@docsearch/react': 3.6.0(@algolia/client-search@4.23.3)(search-insights@2.13.0) - preact: 10.20.1 + preact: 10.20.2 transitivePeerDependencies: - '@algolia/client-search' - '@types/react' @@ -2221,10 +2209,10 @@ packages: search-insights: optional: true dependencies: - '@algolia/autocomplete-core': 1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.2)(search-insights@2.13.0) - '@algolia/autocomplete-preset-algolia': 1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.2) + '@algolia/autocomplete-core': 1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3)(search-insights@2.13.0) + '@algolia/autocomplete-preset-algolia': 1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3) '@docsearch/css': 3.6.0 - algoliasearch: 4.23.2 + algoliasearch: 4.23.3 search-insights: 2.13.0 transitivePeerDependencies: - '@algolia/client-search' @@ -3010,7 +2998,7 @@ packages: /@manypkg/find-root@1.1.0: resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} dependencies: - '@babel/runtime': 7.24.1 + '@babel/runtime': 7.24.4 '@types/node': 12.20.55 find-up: 4.1.0 fs-extra: 8.1.0 @@ -3019,7 +3007,7 @@ packages: /@manypkg/get-packages@1.1.3: resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} dependencies: - '@babel/runtime': 7.24.1 + '@babel/runtime': 7.24.4 '@changesets/types': 4.1.0 '@manypkg/find-root': 1.1.0 fs-extra: 8.1.0 @@ -3081,14 +3069,14 @@ packages: semver: 7.6.0 dev: true - /@npmcli/git@5.0.4: - resolution: {integrity: sha512-nr6/WezNzuYUppzXRaYu/W4aT5rLxdXqEFupbh6e/ovlYFQ8hpu1UUPV3Ir/YTl+74iXl2ZOMlGzudh9ZPUchQ==} + /@npmcli/git@5.0.6: + resolution: {integrity: sha512-4x/182sKXmQkf0EtXxT26GEsaOATpD7WVtza5hrYivWZeo6QefC6xq9KAXrnjtFKBZ4rZwR7aX/zClYYXgtwLw==} engines: {node: ^16.14.0 || >=18.0.0} dependencies: '@npmcli/promise-spawn': 7.0.1 lru-cache: 10.2.0 npm-pick-manifest: 9.0.0 - proc-log: 3.0.0 + proc-log: 4.2.0 promise-inflight: 1.0.1 promise-retry: 2.0.1 semver: 7.6.0 @@ -3111,16 +3099,16 @@ packages: engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} dev: true - /@npmcli/package-json@5.0.0: - resolution: {integrity: sha512-OI2zdYBLhQ7kpNPaJxiflofYIpkNLi+lnGdzqUOfRmCF3r2l1nadcjtCYMJKv/Utm/ZtlffaUuTiAktPHbc17g==} + /@npmcli/package-json@5.0.3: + resolution: {integrity: sha512-cgsjCvld2wMqkUqvY+SZI+1ZJ7umGBYc9IAKfqJRKJCcs7hCQYxScUgdsyrRINk3VmdCYf9TXiLBHQ6ECTxhtg==} engines: {node: ^16.14.0 || >=18.0.0} dependencies: - '@npmcli/git': 5.0.4 + '@npmcli/git': 5.0.6 glob: 10.3.12 hosted-git-info: 7.0.1 json-parse-even-better-errors: 3.0.1 normalize-package-data: 6.0.0 - proc-log: 3.0.0 + proc-log: 4.2.0 semver: 7.6.0 transitivePeerDependencies: - bluebird @@ -3143,7 +3131,7 @@ packages: engines: {node: ^16.14.0 || >=18.0.0} dependencies: '@npmcli/node-gyp': 3.0.0 - '@npmcli/package-json': 5.0.0 + '@npmcli/package-json': 5.0.3 '@npmcli/promise-spawn': 7.0.1 node-gyp: 10.1.0 which: 4.0.0 @@ -3190,7 +3178,7 @@ packages: estree-walker: 2.0.2 glob: 8.1.0 is-reference: 1.2.1 - magic-string: 0.30.8 + magic-string: 0.30.10 rollup: 4.16.1 dev: true @@ -3240,7 +3228,7 @@ packages: terser: 5.30.3 dev: true - /@rollup/plugin-typescript@11.1.6(rollup@4.16.1)(tslib@2.6.2)(typescript@5.4.5): + /@rollup/plugin-typescript@11.1.6(rollup@4.16.1)(typescript@5.4.5): resolution: {integrity: sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA==} engines: {node: '>=14.0.0'} peerDependencies: @@ -3256,7 +3244,6 @@ packages: '@rollup/pluginutils': 5.1.0(rollup@4.16.1) resolve: 1.22.8 rollup: 4.16.1 - tslib: 2.6.2 typescript: 5.4.5 dev: true @@ -3554,12 +3541,12 @@ packages: /@types/eslint-scope@3.7.7: resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} dependencies: - '@types/eslint': 8.56.7 + '@types/eslint': 8.56.10 '@types/estree': 1.0.5 dev: true - /@types/eslint@8.56.7: - resolution: {integrity: sha512-SjDvI/x3zsZnOkYZ3lCt9lOZWZLB2jIlNKz+LBgCtDurK0JZcwucxYHn1w2BJkD34dgX9Tjnak0txtq4WTggEA==} + /@types/eslint@8.56.10: + resolution: {integrity: sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==} dependencies: '@types/estree': 1.0.5 '@types/json-schema': 7.0.15 @@ -3573,7 +3560,7 @@ packages: resolution: {integrity: sha512-bGyep3JqPCRry1wq+O5n7oiBgGWmeIJXPjXXCo8EK0u8duZGSYar7cGqd3ML2JUsLGeB7fmc06KYo9fLGWqPvQ==} dependencies: '@types/node': 20.12.7 - '@types/qs': 6.9.14 + '@types/qs': 6.9.15 '@types/range-parser': 1.2.7 '@types/send': 0.17.4 dev: true @@ -3583,7 +3570,7 @@ packages: dependencies: '@types/body-parser': 1.19.5 '@types/express-serve-static-core': 4.19.0 - '@types/qs': 6.9.14 + '@types/qs': 6.9.15 '@types/serve-static': 1.15.7 dev: true @@ -3643,8 +3630,8 @@ packages: resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} dev: true - /@types/qs@6.9.14: - resolution: {integrity: sha512-5khscbd3SwWMhFqylJBLQ0zIu7c1K6Vz0uBIt915BI3zV0q1nfjRQD3RqSBcPaO6PHEF4ov/t9y89fSiyThlPA==} + /@types/qs@6.9.15: + resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==} dev: true /@types/range-parser@1.2.7: @@ -3849,15 +3836,15 @@ packages: vite: 5.1.7(@types/node@20.12.7)(less@4.2.0)(sass@1.71.1)(terser@5.29.1) dev: true - /@vitejs/plugin-vue@5.0.4(vite@5.2.9)(vue@3.4.23): + /@vitejs/plugin-vue@5.0.4(vite@5.2.10)(vue@3.4.23): resolution: {integrity: sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==} engines: {node: ^18.0.0 || >=20.0.0} peerDependencies: vite: ^5.0.0 vue: ^3.2.25 dependencies: - vite: 5.2.9(@types/node@20.12.7)(less@4.2.0) - vue: 3.4.23 + vite: 5.2.10(@types/node@20.12.7) + vue: 3.4.23(typescript@5.4.5) dev: true /@vitest/coverage-v8@1.5.0(vitest@1.5.0): @@ -3872,13 +3859,13 @@ packages: istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 5.0.4 istanbul-reports: 3.1.7 - magic-string: 0.30.9 - magicast: 0.3.3 + magic-string: 0.30.10 + magicast: 0.3.4 picocolors: 1.0.0 std-env: 3.7.0 strip-literal: 2.1.0 test-exclude: 6.0.0 - vitest: 1.5.0(@types/node@20.12.7)(less@4.2.0) + vitest: 1.5.0(@types/node@20.12.7) transitivePeerDependencies: - supports-color dev: true @@ -3902,7 +3889,7 @@ packages: /@vitest/snapshot@1.5.0: resolution: {integrity: sha512-qpv3fSEuNrhAO3FpH6YYRdaECnnRjg9VxbhdtPwPRnzSfHVXnNzzrpX4cJxqiwgRMo7uRMWDFBlsBq4Cr+rO3A==} dependencies: - magic-string: 0.30.9 + magic-string: 0.30.10 pathe: 1.1.2 pretty-format: 29.7.0 dev: true @@ -3948,7 +3935,7 @@ packages: '@vue/compiler-ssr': 3.4.23 '@vue/shared': 3.4.23 estree-walker: 2.0.2 - magic-string: 0.30.9 + magic-string: 0.30.10 postcss: 8.4.38 source-map-js: 1.2.0 dev: true @@ -3978,7 +3965,7 @@ packages: mitt: 3.0.1 perfect-debounce: 1.0.0 speakingurl: 14.0.1 - vue: 3.4.23 + vue: 3.4.23(typescript@5.4.5) dev: true /@vue/devtools-shared@7.0.27: @@ -4015,7 +4002,7 @@ packages: dependencies: '@vue/compiler-ssr': 3.4.23 '@vue/shared': 3.4.23 - vue: 3.4.23 + vue: 3.4.23(typescript@5.4.5) dev: true /@vue/shared@3.4.23: @@ -4339,24 +4326,24 @@ packages: uri-js: 4.4.1 dev: true - /algoliasearch@4.23.2: - resolution: {integrity: sha512-8aCl055IsokLuPU8BzLjwzXjb7ty9TPcUFFOk0pYOwsE5DMVhE3kwCMFtsCFKcnoPZK7oObm+H5mbnSO/9ioxQ==} + /algoliasearch@4.23.3: + resolution: {integrity: sha512-Le/3YgNvjW9zxIQMRhUHuhiUjAlKY/zsdZpfq4dlLqg6mEm0nL6yk+7f2hDOtLpxsgE4jSzDmvHL7nXdBp5feg==} dependencies: - '@algolia/cache-browser-local-storage': 4.23.2 - '@algolia/cache-common': 4.23.2 - '@algolia/cache-in-memory': 4.23.2 - '@algolia/client-account': 4.23.2 - '@algolia/client-analytics': 4.23.2 - '@algolia/client-common': 4.23.2 - '@algolia/client-personalization': 4.23.2 - '@algolia/client-search': 4.23.2 - '@algolia/logger-common': 4.23.2 - '@algolia/logger-console': 4.23.2 - '@algolia/recommend': 4.23.2 - '@algolia/requester-browser-xhr': 4.23.2 - '@algolia/requester-common': 4.23.2 - '@algolia/requester-node-http': 4.23.2 - '@algolia/transporter': 4.23.2 + '@algolia/cache-browser-local-storage': 4.23.3 + '@algolia/cache-common': 4.23.3 + '@algolia/cache-in-memory': 4.23.3 + '@algolia/client-account': 4.23.3 + '@algolia/client-analytics': 4.23.3 + '@algolia/client-common': 4.23.3 + '@algolia/client-personalization': 4.23.3 + '@algolia/client-search': 4.23.3 + '@algolia/logger-common': 4.23.3 + '@algolia/logger-console': 4.23.3 + '@algolia/recommend': 4.23.3 + '@algolia/requester-browser-xhr': 4.23.3 + '@algolia/requester-common': 4.23.3 + '@algolia/requester-node-http': 4.23.3 + '@algolia/transporter': 4.23.3 dev: true /ansi-colors@4.1.3: @@ -4505,7 +4492,7 @@ packages: postcss: ^8.1.0 dependencies: browserslist: 4.23.0 - caniuse-lite: 1.0.30001606 + caniuse-lite: 1.0.30001612 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.0.0 @@ -4580,7 +4567,7 @@ packages: dependencies: '@babel/core': 7.24.0 '@babel/helper-define-polyfill-provider': 0.5.0(@babel/core@7.24.0) - core-js-compat: 3.36.1 + core-js-compat: 3.37.0 transitivePeerDependencies: - supports-color dev: true @@ -4727,8 +4714,8 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001606 - electron-to-chromium: 1.4.729 + caniuse-lite: 1.0.30001612 + electron-to-chromium: 1.4.745 node-releases: 2.0.14 update-browserslist-db: 1.0.13(browserslist@4.23.0) dev: true @@ -4773,7 +4760,7 @@ packages: resolution: {integrity: sha512-0SsG7UDhoRWcuSvKWHaXmu5uNjDCDN3nkQLRL4Q42IlFy+ze58FcCoI3uPwINXinkz7ZinbhEgyzYFw9u9ZV8g==} dependencies: chokidar: 3.6.0 - confbox: 0.1.3 + confbox: 0.1.7 defu: 6.1.4 dotenv: 16.4.5 giget: 1.2.3 @@ -4782,8 +4769,8 @@ packages: ohash: 1.1.3 pathe: 1.1.2 perfect-debounce: 1.0.0 - pkg-types: 1.0.3 - rc9: 2.1.1 + pkg-types: 1.1.0 + rc9: 2.1.2 dev: false /cac@6.7.14: @@ -4844,8 +4831,8 @@ packages: engines: {node: '>=16'} dev: false - /caniuse-lite@1.0.30001606: - resolution: {integrity: sha512-LPbwnW4vfpJId225pwjZJOgX1m9sGfbw/RKJvw/t0QhYOOaTXHvkjVGFGPpvwEzufrjvTlsULnVTxdy4/6cqkg==} + /caniuse-lite@1.0.30001612: + resolution: {integrity: sha512-lFgnZ07UhaCcsSZgWW0K5j4e69dK1u/ltrL9lTUiFOwNHs12S3UMIEYgBV0Z6C6hRDev7iRnMzzYmKabYdXF9g==} dev: true /chai@4.4.1: @@ -5086,9 +5073,8 @@ packages: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} dev: true - /confbox@0.1.3: - resolution: {integrity: sha512-eH3ZxAihl1PhKfpr4VfEN6/vUd87fmgb6JkldHgg/YR6aEBhW63qUDgzP2Y6WM0UumdsYp5H3kibalXAdHfbgg==} - dev: false + /confbox@0.1.7: + resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} /connect-history-api-fallback@2.0.0: resolution: {integrity: sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==} @@ -5150,8 +5136,8 @@ packages: webpack: 5.90.3(esbuild@0.20.1) dev: true - /core-js-compat@3.36.1: - resolution: {integrity: sha512-Dk997v9ZCt3X/npqzyGdTlq6t7lDBhZwGvV94PKzDArjp7BTRm7WlDAXYd/OWdeFHO8OChQYRJNJvUCqCbrtKA==} + /core-js-compat@3.37.0: + resolution: {integrity: sha512-vYq4L+T8aS5UuFg4UwDhc7YNRWVeVZwltad9C/jV3R2LgVOpS9BDr7l/WL6BN0dbV3k1XejPTHqqEzJgsa0frA==} dependencies: browserslist: 4.23.0 dev: true @@ -5188,7 +5174,7 @@ packages: dom-serializer: 2.0.0 domhandler: 5.0.3 htmlparser2: 8.0.2 - postcss: 8.4.38 + postcss: 8.4.35 postcss-media-query-parser: 0.2.3 dev: true @@ -5220,12 +5206,12 @@ packages: webpack: optional: true dependencies: - icss-utils: 5.1.0(postcss@8.4.38) - postcss: 8.4.38 - postcss-modules-extract-imports: 3.1.0(postcss@8.4.38) - postcss-modules-local-by-default: 4.0.5(postcss@8.4.38) - postcss-modules-scope: 3.2.0(postcss@8.4.38) - postcss-modules-values: 4.0.0(postcss@8.4.38) + icss-utils: 5.1.0(postcss@8.4.35) + postcss: 8.4.35 + postcss-modules-extract-imports: 3.1.0(postcss@8.4.35) + postcss-modules-local-by-default: 4.0.5(postcss@8.4.35) + postcss-modules-scope: 3.2.0(postcss@8.4.35) + postcss-modules-values: 4.0.0(postcss@8.4.35) postcss-value-parser: 4.2.0 semver: 7.6.0 webpack: 5.90.3(esbuild@0.20.1) @@ -5520,8 +5506,8 @@ packages: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} dev: true - /electron-to-chromium@1.4.729: - resolution: {integrity: sha512-bx7+5Saea/qu14kmPTDHQxkp2UnziG3iajUQu3BxFvCOnpAJdDbMV4rSl+EqFDkkpNNVUFlR1kDfpL59xfy1HA==} + /electron-to-chromium@1.4.745: + resolution: {integrity: sha512-tRbzkaRI5gbUn5DEvF0dV4TQbMZ5CLkWeTAXmpC9IrYT+GE+x76i9p+o3RJ5l9XmdQlI1pPhVtE9uNcJJ0G0EA==} dev: true /emoji-regex@10.3.0: @@ -6254,6 +6240,7 @@ packages: /flat@5.0.2: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} hasBin: true + dev: true /flatted@3.3.1: resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} @@ -6811,18 +6798,17 @@ packages: /iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} - requiresBuild: true dependencies: safer-buffer: 2.1.2 dev: true - /icss-utils@5.1.0(postcss@8.4.38): + /icss-utils@5.1.0(postcss@8.4.35): resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 dependencies: - postcss: 8.4.38 + postcss: 8.4.35 dev: true /ieee754@1.2.1: @@ -6934,8 +6920,8 @@ packages: engines: {node: '>= 0.10'} dev: true - /ipaddr.js@2.1.0: - resolution: {integrity: sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==} + /ipaddr.js@2.2.0: + resolution: {integrity: sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==} engines: {node: '>= 10'} dev: true @@ -7263,7 +7249,6 @@ packages: /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - requiresBuild: true dev: true /js-tokens@9.0.0: @@ -7332,6 +7317,7 @@ packages: /jsonc-parser@3.2.1: resolution: {integrity: sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==} + dev: true /jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} @@ -7510,7 +7496,7 @@ packages: engines: {node: '>=14'} dependencies: mlly: 1.6.1 - pkg-types: 1.0.3 + pkg-types: 1.1.0 dev: true /locate-path@5.0.0: @@ -7548,7 +7534,6 @@ packages: /lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - requiresBuild: true dev: true /log-symbols@4.1.0: @@ -7606,22 +7591,21 @@ packages: engines: {node: '>=12'} dev: true - /magic-string@0.30.8: - resolution: {integrity: sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==} - engines: {node: '>=12'} + /magic-string@0.30.10: + resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} dependencies: '@jridgewell/sourcemap-codec': 1.4.15 dev: true - /magic-string@0.30.9: - resolution: {integrity: sha512-S1+hd+dIrC8EZqKyT9DstTH/0Z+f76kmmvZnkfQVmOpDEF9iVgdYif3Q/pIWHmCoo59bQVGW0kVL3e2nl+9+Sw==} + /magic-string@0.30.8: + resolution: {integrity: sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==} engines: {node: '>=12'} dependencies: '@jridgewell/sourcemap-codec': 1.4.15 dev: true - /magicast@0.3.3: - resolution: {integrity: sha512-ZbrP1Qxnpoes8sz47AM0z08U+jW6TyRgZzcWy3Ma3vDhJttwMwAFDMMQFobwdBxByBD46JYmxRzeF7w2+wJEuw==} + /magicast@0.3.4: + resolution: {integrity: sha512-TyDF/Pn36bBji9rWKHlZe+PZb6Mx5V8IHCSxk7X4aljM4e/vyDvZZYwHewdVaqiA0nb3ghfHU/6AUpDxWoER2Q==} dependencies: '@babel/parser': 7.24.4 '@babel/types': 7.24.0 @@ -7907,7 +7891,7 @@ packages: dependencies: acorn: 8.11.3 pathe: 1.1.2 - pkg-types: 1.0.3 + pkg-types: 1.1.0 ufo: 1.5.3 /mrmime@2.0.0: @@ -8137,8 +8121,8 @@ packages: semver: 7.6.0 dev: true - /npm-registry-fetch@16.2.0: - resolution: {integrity: sha512-zVH+G0q1O2hqgQBUvQ2LWp6ujr6VJAeDnmWxqiMlCguvLexEzBnuQIwC70r04vcvCMAcYEIpA/rO9YyVi+fmJQ==} + /npm-registry-fetch@16.2.1: + resolution: {integrity: sha512-8l+7jxhim55S85fjiDGJ1rZXBWGtRLi1OSb4Z3BPLObPuIaeKRlPRiYMSHU4/81ck3t71Z+UwDDl47gcpmfQQA==} engines: {node: ^16.14.0 || >=18.0.0} dependencies: '@npmcli/redact': 1.1.0 @@ -8148,7 +8132,7 @@ packages: minipass-json-stream: 1.0.1 minizlib: 2.1.2 npm-package-arg: 11.0.1 - proc-log: 3.0.0 + proc-log: 4.2.0 transitivePeerDependencies: - supports-color dev: true @@ -8397,7 +8381,7 @@ packages: engines: {node: ^16.14.0 || >=18.0.0} hasBin: true dependencies: - '@npmcli/git': 5.0.4 + '@npmcli/git': 5.0.6 '@npmcli/installed-package-contents': 2.0.2 '@npmcli/promise-spawn': 7.0.1 '@npmcli/run-script': 7.0.4 @@ -8407,7 +8391,7 @@ packages: npm-package-arg: 11.0.1 npm-packlist: 8.0.2 npm-pick-manifest: 9.0.0 - npm-registry-fetch: 16.2.0 + npm-registry-fetch: 16.2.1 proc-log: 3.0.0 promise-retry: 2.0.1 read-package-json: 7.0.0 @@ -8547,7 +8531,6 @@ packages: /pify@4.0.1: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} - requiresBuild: true dev: true /piscina@4.4.0: @@ -8570,10 +8553,10 @@ packages: find-up: 6.3.0 dev: true - /pkg-types@1.0.3: - resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} + /pkg-types@1.1.0: + resolution: {integrity: sha512-/RpmvKdxKf8uILTtoOhAgf30wYbP2Qw+L9p3Rvshx1JZVX+XQNZQFjlbmGHEGIm4CkVPlSn+NXmIM8+9oWQaSA==} dependencies: - jsonc-parser: 3.2.1 + confbox: 0.1.7 mlly: 1.6.1 pathe: 1.1.2 @@ -8608,45 +8591,45 @@ packages: resolution: {integrity: sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==} dev: true - /postcss-modules-extract-imports@3.1.0(postcss@8.4.38): + /postcss-modules-extract-imports@3.1.0(postcss@8.4.35): resolution: {integrity: sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 dependencies: - postcss: 8.4.38 + postcss: 8.4.35 dev: true - /postcss-modules-local-by-default@4.0.5(postcss@8.4.38): + /postcss-modules-local-by-default@4.0.5(postcss@8.4.35): resolution: {integrity: sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 dependencies: - icss-utils: 5.1.0(postcss@8.4.38) - postcss: 8.4.38 + icss-utils: 5.1.0(postcss@8.4.35) + postcss: 8.4.35 postcss-selector-parser: 6.0.16 postcss-value-parser: 4.2.0 dev: true - /postcss-modules-scope@3.2.0(postcss@8.4.38): + /postcss-modules-scope@3.2.0(postcss@8.4.35): resolution: {integrity: sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 dependencies: - postcss: 8.4.38 + postcss: 8.4.35 postcss-selector-parser: 6.0.16 dev: true - /postcss-modules-values@4.0.0(postcss@8.4.38): + /postcss-modules-values@4.0.0(postcss@8.4.35): resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 dependencies: - icss-utils: 5.1.0(postcss@8.4.38) - postcss: 8.4.38 + icss-utils: 5.1.0(postcss@8.4.35) + postcss: 8.4.35 dev: true /postcss-selector-parser@6.0.16: @@ -8679,8 +8662,8 @@ packages: source-map-js: 1.2.0 dev: true - /preact@10.20.1: - resolution: {integrity: sha512-JIFjgFg9B2qnOoGiYMVBtrcFxHqn+dNXbq76bVmcaHYJFYR4lW67AOcXgAYQQTDYXDOg/kTZrKPNCdRgJ2UJmw==} + /preact@10.20.2: + resolution: {integrity: sha512-S1d1ernz3KQ+Y2awUxKakpfOg2CEmJmwOP+6igPx6dgr6pgDvenqYviyokWso2rhHvGtTlWWnJDa7RaPbQerTg==} dev: true /preferred-pm@3.1.3: @@ -8724,6 +8707,11 @@ packages: engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} dev: true + /proc-log@4.2.0: + resolution: {integrity: sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + dev: true + /process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} dev: true @@ -8874,12 +8862,11 @@ packages: unpipe: 1.0.0 dev: true - /rc9@2.1.1: - resolution: {integrity: sha512-lNeOl38Ws0eNxpO3+wD1I9rkHGQyj1NU1jlzv4go2CtEnEQEUfqnIvZG7W+bC/aXdJ27n5x/yUjb6RoT9tko+Q==} + /rc9@2.1.2: + resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==} dependencies: defu: 6.1.4 destr: 2.0.3 - flat: 5.0.2 dev: false /react-is@18.2.0: @@ -8990,7 +8977,7 @@ packages: /regenerator-transform@0.15.2: resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} dependencies: - '@babel/runtime': 7.24.1 + '@babel/runtime': 7.24.0 dev: true /regex-parser@2.3.0: @@ -9066,7 +9053,7 @@ packages: adjust-sourcemap-loader: 4.0.0 convert-source-map: 1.9.0 loader-utils: 2.0.4 - postcss: 8.4.38 + postcss: 8.4.35 source-map: 0.6.1 dev: true @@ -9136,7 +9123,7 @@ packages: rollup: ^3.29.4 || ^4 typescript: ^4.5 || ^5.0 dependencies: - magic-string: 0.30.8 + magic-string: 0.30.10 rollup: 4.16.1 typescript: 5.4.5 optionalDependencies: @@ -9215,7 +9202,6 @@ packages: /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - requiresBuild: true dev: true /sass-loader@14.1.1(sass@1.71.1)(webpack@5.90.3): @@ -9298,7 +9284,6 @@ packages: /semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true - requiresBuild: true dev: true /semver@6.3.1: @@ -9539,13 +9524,13 @@ packages: dependencies: agent-base: 7.1.1 debug: 4.3.4 - socks: 2.8.1 + socks: 2.8.3 transitivePeerDependencies: - supports-color dev: true - /socks@2.8.1: - resolution: {integrity: sha512-B6w7tkwNid7ToxjZ08rQMT8M9BJAf8DKx8Ft4NivzH0zBUfd6jldGcisJn/RLgxcX3FPNDdNQCUEMMT79b+oCQ==} + /socks@2.8.3: + resolution: {integrity: sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==} engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} dependencies: ip-address: 9.0.5 @@ -9904,7 +9889,7 @@ packages: jest-worker: 27.5.1 schema-utils: 3.3.0 serialize-javascript: 6.0.2 - terser: 5.30.3 + terser: 5.29.1 webpack: 5.90.3(esbuild@0.20.1) dev: true @@ -9951,12 +9936,12 @@ packages: resolution: {integrity: sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==} dev: true - /tinybench@2.6.0: - resolution: {integrity: sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA==} + /tinybench@2.8.0: + resolution: {integrity: sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==} dev: true - /tinypool@0.8.3: - resolution: {integrity: sha512-Ud7uepAklqRH1bvwy22ynrliC7Dljz7Tm8M/0RBUW+YRa4YHhZ6e4PpgE+fu1zr/WqB1kbeuVrdfeuyIBpy4tw==} + /tinypool@0.8.4: + resolution: {integrity: sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==} engines: {node: '>=14.0.0'} dev: true @@ -10330,7 +10315,7 @@ packages: engines: {node: '>= 0.8'} dev: true - /vite-node@1.5.0(@types/node@20.12.7)(less@4.2.0): + /vite-node@1.5.0(@types/node@20.12.7): resolution: {integrity: sha512-tV8h6gMj6vPzVCa7l+VGq9lwoJjW8Y79vst8QZZGiuRAfijU+EEWuc0kFpmndQrWhMMhet1jdSF+40KSZUqIIw==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true @@ -10339,7 +10324,7 @@ packages: debug: 4.3.4 pathe: 1.1.2 picocolors: 1.0.0 - vite: 5.2.9(@types/node@20.12.7)(less@4.2.0) + vite: 5.2.10(@types/node@20.12.7) transitivePeerDependencies: - '@types/node' - less @@ -10382,7 +10367,7 @@ packages: '@types/node': 20.12.7 esbuild: 0.19.12 less: 4.2.0 - postcss: 8.4.38 + postcss: 8.4.35 rollup: 4.16.1 sass: 1.71.1 terser: 5.29.1 @@ -10390,8 +10375,8 @@ packages: fsevents: 2.3.3 dev: true - /vite@5.2.8(@types/node@20.12.7)(less@4.2.0): - resolution: {integrity: sha512-OyZR+c1CE8yeHw5V5t59aXsUPPVTHMDjEZz8MgguLL/Q7NblxhZUlTu9xSPqlsUO/y+X7dlU05jdhvyycD55DA==} + /vite@5.2.10(@types/node@20.12.7): + resolution: {integrity: sha512-PAzgUZbP7msvQvqdSD+ErD5qGnSFiGOoWmV5yAKUEI0kdhjbH6nMWVyZQC/hSc4aXwc0oJ9aEdIiF9Oje0JFCw==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -10420,51 +10405,13 @@ packages: dependencies: '@types/node': 20.12.7 esbuild: 0.20.2 - less: 4.2.0 postcss: 8.4.38 rollup: 4.16.1 optionalDependencies: fsevents: 2.3.3 dev: true - /vite@5.2.9(@types/node@20.12.7)(less@4.2.0): - resolution: {integrity: sha512-uOQWfuZBlc6Y3W/DTuQ1Sr+oIXWvqljLvS881SVmAj00d5RdgShLcuXWxseWPd4HXwiYBFW/vXHfKFeqj9uQnw==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || >=20.0.0 - 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.12.7 - esbuild: 0.20.2 - less: 4.2.0 - postcss: 8.4.38 - rollup: 4.16.1 - optionalDependencies: - fsevents: 2.3.3 - dev: true - - /vitepress@1.1.3(@algolia/client-search@4.23.3)(search-insights@2.13.0): + /vitepress@1.1.3(@algolia/client-search@4.23.3)(@types/node@20.12.7)(search-insights@2.13.0)(typescript@5.4.5): resolution: {integrity: sha512-hGrIYN0w9IHWs0NQSnlMjKV/v/HLfD+Ywv5QdvCSkiT32mpNOOwUrZjnqZv/JL/WBPpUc94eghTUvmipxw0xrA==} hasBin: true peerDependencies: @@ -10481,7 +10428,7 @@ packages: '@shikijs/core': 1.3.0 '@shikijs/transformers': 1.3.0 '@types/markdown-it': 14.0.1 - '@vitejs/plugin-vue': 5.0.4(vite@5.2.9)(vue@3.4.23) + '@vitejs/plugin-vue': 5.0.4(vite@5.2.10)(vue@3.4.23) '@vue/devtools-api': 7.0.27(vue@3.4.23) '@vueuse/core': 10.9.0(vue@3.4.23) '@vueuse/integrations': 10.9.0(focus-trap@7.5.4)(vue@3.4.23) @@ -10489,8 +10436,8 @@ packages: mark.js: 8.11.1 minisearch: 6.3.0 shiki: 1.3.0 - vite: 5.2.9(@types/node@20.12.7)(less@4.2.0) - vue: 3.4.23 + vite: 5.2.10(@types/node@20.12.7) + vue: 3.4.23(typescript@5.4.5) transitivePeerDependencies: - '@algolia/client-search' - '@types/node' @@ -10519,7 +10466,7 @@ packages: - universal-cookie dev: true - /vitest@1.5.0(@types/node@20.12.7)(less@4.2.0): + /vitest@1.5.0(@types/node@20.12.7): resolution: {integrity: sha512-d8UKgR0m2kjdxDWX6911uwxout6GHS0XaGH1cksSIVVG8kRlE7G7aBw7myKQCvDI5dT4j7ZMa+l706BIORMDLw==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true @@ -10555,15 +10502,15 @@ packages: debug: 4.3.4 execa: 8.0.1 local-pkg: 0.5.0 - magic-string: 0.30.9 + magic-string: 0.30.10 pathe: 1.1.2 picocolors: 1.0.0 std-env: 3.7.0 strip-literal: 2.1.0 - tinybench: 2.6.0 - tinypool: 0.8.3 - vite: 5.2.8(@types/node@20.12.7)(less@4.2.0) - vite-node: 1.5.0(@types/node@20.12.7)(less@4.2.0) + tinybench: 2.8.0 + tinypool: 0.8.4 + vite: 5.2.10(@types/node@20.12.7) + vite-node: 1.5.0(@types/node@20.12.7) why-is-node-running: 2.2.2 transitivePeerDependencies: - less @@ -10587,10 +10534,10 @@ packages: '@vue/composition-api': optional: true dependencies: - vue: 3.4.23 + vue: 3.4.23(typescript@5.4.5) dev: true - /vue@3.4.23: + /vue@3.4.23(typescript@5.4.5): resolution: {integrity: sha512-X1y6yyGJ28LMUBJ0k/qIeKHstGd+BlWQEOT40x3auJFTmpIhpbKLgN7EFsqalnJXq1Km5ybDEsp6BhuWKciUDg==} peerDependencies: typescript: '*' @@ -10603,6 +10550,7 @@ packages: '@vue/runtime-dom': 3.4.23 '@vue/server-renderer': 3.4.23(vue@3.4.23) '@vue/shared': 3.4.23 + typescript: 5.4.5 dev: true /watchpack@2.4.0: @@ -10696,7 +10644,7 @@ packages: graceful-fs: 4.2.11 html-entities: 2.5.2 http-proxy-middleware: 2.0.6(@types/express@4.17.21) - ipaddr.js: 2.1.0 + ipaddr.js: 2.2.0 launch-editor: 2.6.1 open: 8.4.2 p-retry: 4.6.2