diff --git a/.changeset/bright-carpets-relax.md b/.changeset/bright-carpets-relax.md new file mode 100644 index 000000000..90e1d291a --- /dev/null +++ b/.changeset/bright-carpets-relax.md @@ -0,0 +1,5 @@ +--- +"@logto/connector-postmark": major +--- + +add postmark connector diff --git a/packages/connectors/connector-postmark/README.md b/packages/connectors/connector-postmark/README.md new file mode 100644 index 000000000..f456741d7 --- /dev/null +++ b/packages/connectors/connector-postmark/README.md @@ -0,0 +1,61 @@ +# Postmark connector + +Logto connector for Postmark email service. + +## Get started + +Postmark is a mail platform for transactional and marketing email. We can use its email sending function to send a _verification code_. + +## Register Postmark account + +Create a new account at [Postmark website](https://postmark.com/). You may skip this step if you've already got an account. + +## Configure your connector + +Fill out the `serverToken` field with the Server Token you find under settings for your +server in Postmark. + +Fill out the `fromEmail` field with the senders' _From Address_. + +In order to enable full user flows, templates with usageType `Register`, `SignIn`, `ForgotPassword` and `Generic` are required + +Here is an example of Postmark connector template JSON. + +```jsonc +[ + { + "usageType": "Register", + "templateAlias": "logto-register" + }, + { + "usageType": "SignIn", + "templateAlias": "logto-sign-in" + }, + { + "usageType": "ForgotPassword", + "templateAlias": "logto-forgot-password" + }, + { + "usageType": "Generic", + "templateAlias": "logto-generic" + }, +] +``` + +## Test Postmark email connector + +You can type in an email address and click on "Send" to see whether the settings can work before "Save and Done". + +That's it. Don't forget to [Enable connector in sign-in experience](https://docs.logto.io/docs/tutorials/get-started/passwordless-sign-in-by-adding-connectors#enable-sms-or-email-passwordless-sign-in) + +## Config types + +| Name | Type | +|-------------|-------------------| +| serverToken | string | +| fromEmail | string | + +| Template Properties | Type | Enum values | +|---------------------|-------------|------------------------------------------------------| +| usageType | enum string | 'Register' \| 'SignIn' \| 'ForgotPassword' \| 'Generic' | +| templateAlias | string | N/A | diff --git a/packages/connectors/connector-postmark/logo.svg b/packages/connectors/connector-postmark/logo.svg new file mode 100644 index 000000000..782674874 --- /dev/null +++ b/packages/connectors/connector-postmark/logo.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/packages/connectors/connector-postmark/package.json b/packages/connectors/connector-postmark/package.json new file mode 100644 index 000000000..615e3a726 --- /dev/null +++ b/packages/connectors/connector-postmark/package.json @@ -0,0 +1,74 @@ +{ + "name": "@logto/connector-postmark", + "version": "1.0.0", + "description": "Postmark connector implementation.", + "author": "Sten Sandvik ", + "dependencies": { + "@logto/connector-kit": "workspace:^4.0.0", + "@silverhand/essentials": "^2.9.0", + "postmark": "^4.0.2", + "zod": "^3.22.4" + }, + "devDependencies": { + "@rollup/plugin-commonjs": "^25.0.7", + "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "^15.2.3", + "@rollup/plugin-typescript": "^11.1.6", + "@silverhand/eslint-config": "6.0.1", + "@silverhand/ts-config": "6.0.0", + "@types/node": "^20.11.20", + "@types/nodemailer": "^6.4.7", + "@types/supertest": "^6.0.2", + "@vitest/coverage-v8": "^1.4.0", + "eslint": "^8.56.0", + "lint-staged": "^15.0.2", + "nock": "^13.3.1", + "prettier": "^3.0.0", + "rollup": "^4.12.0", + "rollup-plugin-output-size": "^1.3.0", + "supertest": "^7.0.0", + "typescript": "^5.3.3", + "vitest": "^1.4.0" + }, + "main": "./lib/index.js", + "module": "./lib/index.js", + "exports": "./lib/index.js", + "license": "MPL-2.0", + "type": "module", + "files": [ + "lib", + "docs", + "logo.svg", + "logo-dark.svg" + ], + "scripts": { + "precommit": "lint-staged", + "check": "tsc --noEmit", + "build": "tsup", + "dev": "tsup --watch", + "lint": "eslint --ext .ts src", + "lint:report": "pnpm lint --format json --output-file report.json", + "test": "vitest src", + "test:ci": "pnpm run test --silent --coverage", + "prepublishOnly": "pnpm build" + }, + "engines": { + "node": "^20.9.0" + }, + "eslintConfig": { + "extends": "@silverhand", + "settings": { + "import/core-modules": [ + "@silverhand/essentials", + "got", + "nock", + "snakecase-keys", + "zod" + ] + } + }, + "prettier": "@silverhand/eslint-config/.prettierrc", + "publishConfig": { + "access": "public" + } +} diff --git a/packages/connectors/connector-postmark/src/constant.ts b/packages/connectors/connector-postmark/src/constant.ts new file mode 100644 index 000000000..694012e09 --- /dev/null +++ b/packages/connectors/connector-postmark/src/constant.ts @@ -0,0 +1,57 @@ +import type { ConnectorMetadata } from '@logto/connector-kit'; +import { ConnectorConfigFormItemType } from '@logto/connector-kit'; + +export const defaultMetadata: ConnectorMetadata = { + id: 'postmark-mail', + target: 'postmark-mail', + platform: null, + name: { + en: 'Postmark Mail', + }, + logo: './logo.svg', + logoDark: null, + description: { + en: 'Postmark is a mail sending platform.', + }, + readme: './README.md', + formItems: [ + { + key: 'serverToken', + label: 'Server Token', + type: ConnectorConfigFormItemType.Text, + required: true, + placeholder: '', + }, + { + key: 'fromEmail', + label: 'From Email', + type: ConnectorConfigFormItemType.Text, + required: true, + placeholder: '', + }, + { + key: 'templates', + label: 'Templates', + type: ConnectorConfigFormItemType.Json, + required: true, + defaultValue: [ + { + usageType: 'SignIn', + templateAlias: 'logto-sign-in', + }, + { + usageType: 'Register', + templateAlias: 'logto-register', + }, + { + usageType: 'ForgotPassword', + templateAlias: 'logto-forgot-password', + }, + { + usageType: 'Generic', + templateAlias: 'logto-generic', + }, + ], + }, + ], +}; diff --git a/packages/connectors/connector-postmark/src/index.test.ts b/packages/connectors/connector-postmark/src/index.test.ts new file mode 100644 index 000000000..634a0bdda --- /dev/null +++ b/packages/connectors/connector-postmark/src/index.test.ts @@ -0,0 +1,42 @@ +import { TemplateType } from '@logto/connector-kit'; + +import { mockedConfig } from './mock.js'; + +const getConfig = vi.fn().mockResolvedValue(mockedConfig); +const sendEmailWithTemplate = vi.fn(); +vi.mock('postmark', () => ({ + ServerClient: vi.fn(() => ({ + sendEmailWithTemplate, + })), +})); + +const { default: createConnector } = await import('./index.js'); + +describe('Postmark connector', () => { + it('init without throwing errors', async () => { + await expect(createConnector({ getConfig })).resolves.not.toThrow(); + }); + + describe('sendMessage()', () => { + afterEach(() => { + vi.clearAllMocks(); + }); + + it('should call sendEmailWithTemplate() with correct template and content', async () => { + const connector = await createConnector({ getConfig }); + await connector.sendMessage({ + to: 'to@email.com', + type: TemplateType.SignIn, + payload: { code: '1234' }, + }); + expect(sendEmailWithTemplate).toHaveBeenCalledWith( + expect.objectContaining({ + From: mockedConfig.fromEmail, + TemplateAlias: 'logto-sign-in', + To: 'to@email.com', + TemplateModel: { code: '1234' }, + }) + ); + }); + }); +}); diff --git a/packages/connectors/connector-postmark/src/index.ts b/packages/connectors/connector-postmark/src/index.ts new file mode 100644 index 000000000..6039796cd --- /dev/null +++ b/packages/connectors/connector-postmark/src/index.ts @@ -0,0 +1,65 @@ +import { assert } from '@silverhand/essentials'; + +import type { + GetConnectorConfig, + CreateConnector, + EmailConnector, + SendMessageFunction, +} from '@logto/connector-kit'; +import { + ConnectorError, + ConnectorErrorCodes, + validateConfig, + ConnectorType, +} from '@logto/connector-kit'; +import { ServerClient } from 'postmark'; + +import { defaultMetadata } from './constant.js'; +import { postmarkConfigGuard } from './types.js'; + +const sendMessage = + (getConfig: GetConnectorConfig): SendMessageFunction => + async (data, inputConfig) => { + const { to, type, payload } = data; + + const config = inputConfig ?? (await getConfig(defaultMetadata.id)); + validateConfig(config, postmarkConfigGuard); + + const { serverToken, fromEmail, templates } = config; + const template = templates.find((template) => template.usageType === type); + + assert( + template, + new ConnectorError( + ConnectorErrorCodes.TemplateNotFound, + `Template not found for type: ${type}` + ) + ); + + const client = new ServerClient(serverToken); + + try { + await client.sendEmailWithTemplate({ + From: fromEmail, + TemplateAlias: template.templateAlias, + To: to, + TemplateModel: payload, + }); + } catch (error: unknown) { + throw new ConnectorError( + ConnectorErrorCodes.General, + error instanceof Error ? error.message : '' + ); + } + }; + +const createPostmarkConnector: CreateConnector = async ({ getConfig }) => { + return { + metadata: defaultMetadata, + type: ConnectorType.Email, + configGuard: postmarkConfigGuard, + sendMessage: sendMessage(getConfig), + }; +}; + +export default createPostmarkConnector; diff --git a/packages/connectors/connector-postmark/src/mock.ts b/packages/connectors/connector-postmark/src/mock.ts new file mode 100644 index 000000000..457b541cc --- /dev/null +++ b/packages/connectors/connector-postmark/src/mock.ts @@ -0,0 +1,26 @@ +import type { PostmarkConfig } from './types.js'; + +export const mockedServerToken = 'serverToken'; + +export const mockedConfig: PostmarkConfig = { + serverToken: mockedServerToken, + fromEmail: 'noreply@logto.test.io', + templates: [ + { + usageType: 'SignIn', + templateAlias: 'logto-sign-in', + }, + { + usageType: 'Register', + templateAlias: 'logto-register', + }, + { + usageType: 'ForgotPassword', + templateAlias: 'logto-forgot-password', + }, + { + usageType: 'Generic', + templateAlias: 'logto-generic', + }, + ], +}; diff --git a/packages/connectors/connector-postmark/src/types.ts b/packages/connectors/connector-postmark/src/types.ts new file mode 100644 index 000000000..ff5a06cd6 --- /dev/null +++ b/packages/connectors/connector-postmark/src/types.ts @@ -0,0 +1,32 @@ +import { z } from 'zod'; + +/** + * UsageType here is used to specify the use case of the template, can be either + * 'Register', 'SignIn', 'ForgotPassword', 'Generic'. + */ +const requiredTemplateUsageTypes = ['Register', 'SignIn', 'ForgotPassword', 'Generic']; + +const templateGuard = z.object({ + usageType: z.string(), + templateAlias: z.string(), +}); + +export const postmarkConfigGuard = z.object({ + serverToken: z.string(), + fromEmail: z.string(), + templates: z.array(templateGuard).refine( + (templates) => + requiredTemplateUsageTypes.every((requiredType) => + templates.map((template) => template.usageType).includes(requiredType) + ), + (templates) => ({ + message: `Template with UsageType (${requiredTemplateUsageTypes + .filter( + (requiredType) => !templates.map((template) => template.usageType).includes(requiredType) + ) + .join(', ')}) should be provided!`, + }) + ), +}); + +export type PostmarkConfig = z.infer; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9958b0cb0..bacc3f74c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1796,6 +1796,79 @@ importers: specifier: ^2.0.0 version: 2.0.0(@types/node@20.11.20)(happy-dom@14.12.3)(jsdom@20.0.2)(lightningcss@1.25.1)(sass@1.77.8) + packages/connectors/connector-postmark: + dependencies: + '@logto/connector-kit': + specifier: workspace:^4.0.0 + version: link:../../toolkit/connector-kit + '@silverhand/essentials': + specifier: ^2.9.0 + version: 2.9.1 + postmark: + specifier: ^4.0.2 + version: 4.0.4 + zod: + specifier: ^3.22.4 + version: 3.23.8 + devDependencies: + '@rollup/plugin-commonjs': + specifier: ^25.0.7 + version: 25.0.8(rollup@4.14.3) + '@rollup/plugin-json': + specifier: ^6.1.0 + version: 6.1.0(rollup@4.14.3) + '@rollup/plugin-node-resolve': + specifier: ^15.2.3 + version: 15.2.3(rollup@4.14.3) + '@rollup/plugin-typescript': + specifier: ^11.1.6 + version: 11.1.6(rollup@4.14.3)(tslib@2.6.2)(typescript@5.5.3) + '@silverhand/eslint-config': + specifier: 6.0.1 + version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.5.3) + '@silverhand/ts-config': + specifier: 6.0.0 + version: 6.0.0(typescript@5.5.3) + '@types/node': + specifier: ^20.11.20 + version: 20.12.7 + '@types/nodemailer': + specifier: ^6.4.7 + version: 6.4.7 + '@types/supertest': + specifier: ^6.0.2 + version: 6.0.2 + '@vitest/coverage-v8': + specifier: ^1.4.0 + version: 1.6.0(vitest@1.6.0(@types/node@20.12.7)(happy-dom@14.12.3)(jsdom@20.0.2)(lightningcss@1.25.1)(sass@1.77.8)) + eslint: + specifier: ^8.56.0 + version: 8.57.0 + lint-staged: + specifier: ^15.0.2 + version: 15.0.2 + nock: + specifier: ^13.3.1 + version: 13.3.1 + prettier: + specifier: ^3.0.0 + version: 3.0.0 + rollup: + specifier: ^4.12.0 + version: 4.14.3 + rollup-plugin-output-size: + specifier: ^1.3.0 + version: 1.4.1(rollup@4.14.3) + supertest: + specifier: ^7.0.0 + version: 7.0.0 + typescript: + specifier: ^5.3.3 + version: 5.5.3 + vitest: + specifier: ^1.4.0 + version: 1.6.0(@types/node@20.12.7)(happy-dom@14.12.3)(jsdom@20.0.2)(lightningcss@1.25.1)(sass@1.77.8) + packages/connectors/connector-saml: dependencies: '@logto/connector-kit': @@ -5167,6 +5240,24 @@ packages: resolution: {integrity: sha512-bkUDCp8o1MvFO+qxkODcbhSqRa6P2GXgrGZVpt0dCXNW2HCSCqYI0ZoAqEOSAjRWmmlKcYgFvN4B4S+zo/f8kg==} engines: {node: '>=14'} + '@rollup/plugin-commonjs@25.0.8': + resolution: {integrity: sha512-ZEZWTK5n6Qde0to4vS9Mr5x/0UZoqCxPVR9KRUjU4kA2sO7GEUn1fop0DAwpO6z0Nw/kJON9bDmSxdWxO/TT1A==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.68.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-json@6.1.0': + resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + '@rollup/plugin-node-resolve@15.2.3': resolution: {integrity: sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==} engines: {node: '>=14.0.0'} @@ -5176,6 +5267,19 @@ packages: rollup: optional: true + '@rollup/plugin-typescript@11.1.6': + resolution: {integrity: sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.14.0||^3.0.0||^4.0.0 + tslib: '*' + typescript: '>=3.7.0' + peerDependenciesMeta: + rollup: + optional: true + tslib: + optional: true + '@rollup/pluginutils@5.1.0': resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} engines: {node: '>=14.0.0'} @@ -6163,23 +6267,43 @@ packages: peerDependencies: vite: ^4.2.0 || ^5.0.0 + '@vitest/coverage-v8@1.6.0': + resolution: {integrity: sha512-KvapcbMY/8GYIG0rlwwOKCVNRc0OL20rrhFkg/CHNzncV03TE2XWvO5w9uZYoxNiMEBacAJt3unSOiZ7svePew==} + peerDependencies: + vitest: 1.6.0 + '@vitest/coverage-v8@2.0.0': resolution: {integrity: sha512-k2OgMH8e4AyUVsmLk2P3vT++VVaUQbvVaP5NJQDgXgv1q4lG56Z4nb26QNcxgk4ZLypmOrfultAShMo+okIOYw==} peerDependencies: vitest: 2.0.0 + '@vitest/expect@1.6.0': + resolution: {integrity: sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==} + '@vitest/expect@2.0.0': resolution: {integrity: sha512-5BSfZ0+dAVmC6uPF7s+TcKx0i7oyYHb1WQQL5gg6G2c+Qkaa5BNrdRM74sxDfUIZUgYCr6bfCqmJp+X5bfcNxQ==} + '@vitest/runner@1.6.0': + resolution: {integrity: sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==} + '@vitest/runner@2.0.0': resolution: {integrity: sha512-OovFmlkfRmdhevbWImBUtn9IEM+CKac8O+m9p6W9jTATGVBnDJQ6/jb1gpHyWxsu0ALi5f+TLi+Uyst7AAimMw==} + '@vitest/snapshot@1.6.0': + resolution: {integrity: sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==} + '@vitest/snapshot@2.0.0': resolution: {integrity: sha512-B520cSAQwtWgocPpARadnNLslHCxFs5tf7SG2TT96qz+SZgsXqcB1xI3w3/S9kUzdqykEKrMLvW+sIIpMcuUdw==} + '@vitest/spy@1.6.0': + resolution: {integrity: sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==} + '@vitest/spy@2.0.0': resolution: {integrity: sha512-0g7ho4wBK09wq8iNZFtUcQZcUcbPmbLWFotL0GXel0fvk5yPi4nTEKpIvZ+wA5eRyqPUCIfIUl10AWzLr67cmA==} + '@vitest/utils@1.6.0': + resolution: {integrity: sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==} + '@vitest/utils@2.0.0': resolution: {integrity: sha512-t0jbx8VugWEP6A29NbyfQKVU68Vo6oUw0iX3a8BwO3nrZuivfHcFO4Y5UsqXlplX+83P9UaqEvC2YQhspC0JSA==} @@ -6446,6 +6570,9 @@ packages: resolution: {integrity: sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==} engines: {node: '>=12.0.0'} + assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} @@ -6497,6 +6624,9 @@ packages: axios@1.6.7: resolution: {integrity: sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==} + axios@1.7.2: + resolution: {integrity: sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==} + axobject-query@3.2.1: resolution: {integrity: sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==} @@ -6701,6 +6831,10 @@ packages: ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + chai@4.5.0: + resolution: {integrity: sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==} + engines: {node: '>=4'} + chai@5.1.1: resolution: {integrity: sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==} engines: {node: '>=12'} @@ -6749,6 +6883,9 @@ packages: chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + check-error@1.0.3: + resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + check-error@2.1.1: resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} engines: {node: '>= 16'} @@ -6908,6 +7045,9 @@ packages: resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} engines: {node: '>= 12'} + commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + compare-func@2.0.0: resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} @@ -6921,6 +7061,9 @@ packages: concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + confbox@0.1.7: + resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} + confusing-browser-globals@1.0.11: resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==} @@ -7342,6 +7485,10 @@ packages: babel-plugin-macros: optional: true + deep-eql@4.1.4: + resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} + engines: {node: '>=6'} + deep-eql@5.0.2: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} @@ -7508,6 +7655,9 @@ packages: resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} engines: {node: '>=12'} + duplexer@0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + duplexify@4.1.3: resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==} @@ -8270,6 +8420,11 @@ packages: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} deprecated: Glob versions prior to v9 are no longer supported + glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + deprecated: Glob versions prior to v9 are no longer supported + global-directory@4.0.1: resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} engines: {node: '>=18'} @@ -8353,6 +8508,10 @@ packages: resolution: {integrity: sha512-KcFVtoP1CVFtQu0aSk3AyAt2og66PFhZAlkUOuWKwzMLoulHXG5W5wE5xAnHb+yl3/wEFoqGW7/cDGMU8igDZQ==} engines: {node: '>=14.0.0'} + gzip-size@7.0.0: + resolution: {integrity: sha512-O1Ld7Dr+nqPnmGpdhzLmMTQ4vAsD+rHwMm1NLUmoUFFymBOMKxCCrtDxqdBRYXdeEPEi3SyoR4TizJLQrnKBNA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + happy-dom@14.12.3: resolution: {integrity: sha512-vsYlEs3E9gLwA1Hp+w3qzu+RUDFf4VTT8cyKqVICoZ2k7WM++Qyd2LwzyTi5bqMJFiIC/vNpTDYuxdreENRK/g==} engines: {node: '>=16.0.0'} @@ -8729,9 +8888,6 @@ packages: resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} hasBin: true - is-core-module@2.12.1: - resolution: {integrity: sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==} - is-core-module@2.13.1: resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} @@ -8853,6 +9009,9 @@ packages: is-proto-prop@2.0.0: resolution: {integrity: sha512-jl3NbQ/fGLv5Jhan4uX+Ge9ohnemqyblWVVCpAvtTQzNFvV2xhJq+esnkIbYQ9F1nITXoLfDDQLp7LBw/zzncg==} + is-reference@1.2.1: + resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} + is-reference@3.0.2: resolution: {integrity: sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==} @@ -9501,6 +9660,10 @@ packages: resolution: {integrity: sha512-HVl9ZqccQihZ7JM85dco1MvO9G+ONvxoGa9rkhzFsneGLKSUg1gJf9bWzhRhcvm2qChhWpebQhP44qxjKIUCaQ==} engines: {node: '>= 12.13.0'} + local-pkg@0.5.0: + resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} + engines: {node: '>=14'} + locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -9604,6 +9767,9 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true + loupe@2.3.7: + resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + loupe@3.1.1: resolution: {integrity: sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==} @@ -10001,6 +10167,10 @@ packages: minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + minimatch@9.0.4: resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} engines: {node: '>=16 || 14 >=14.17'} @@ -10048,6 +10218,9 @@ packages: engines: {node: '>=10'} hasBin: true + mlly@1.7.1: + resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} + module-details-from-path@1.0.3: resolution: {integrity: sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==} @@ -10361,6 +10534,10 @@ packages: resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + p-limit@5.0.0: + resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} + engines: {node: '>=18'} + p-limit@6.0.0: resolution: {integrity: sha512-Dx+NzOuILWwjJE9OYtEKuQRy0i3c5QVAmDsVrvvRSgyNnPuB27D2DyEjl6QTNyeePaAHjaPk+ya0yA0Frld8RA==} engines: {node: '>=18'} @@ -10496,6 +10673,9 @@ packages: pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + pathval@2.0.0: resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} engines: {node: '>= 14.16'} @@ -10606,6 +10786,9 @@ packages: resolution: {integrity: sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==} engines: {node: '>=10'} + pkg-types@1.1.3: + resolution: {integrity: sha512-+JrgthZG6m3ckicaOB74TwQ+tBWsFl3qVQg7mN8ulwSOElJ7gBhKzj2VkCPnZ4NlF6kEquYU+RIYNVAvzd54UA==} + pluralize@8.0.0: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} @@ -10743,6 +10926,9 @@ packages: postgres-range@1.1.2: resolution: {integrity: sha512-CmPJDSpd3/xYJrtw/tI0Cv029B0zMtnesUOHCZmgvypGBLn+eExXcjCS5OY7mpiw6imYEvd2IMD36sAOYA9U1w==} + postmark@4.0.4: + resolution: {integrity: sha512-Qme+i5nidpcySxPBaPT0Arqc15dKl9D+fk9qsHEV2s8mhTK13/213RRD2/uemp8H6/ZHjAfgKCTY9TfzThbCTQ==} + preferred-pm@3.0.3: resolution: {integrity: sha512-+wZgbxNES/KlJs9q40F/1sfOd/j7f1O9JaHcW5Dsn3aUUOZg3L2bjpVUcKV2jvtElYfoTuQiNeMfQJ4kwUAhCQ==} engines: {node: '>=10'} @@ -10765,6 +10951,10 @@ packages: engines: {node: '>=14'} hasBin: true + pretty-bytes@6.1.1: + resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==} + engines: {node: ^14.13.1 || >=16.0.0} + pretty-format@27.5.1: resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -11264,10 +11454,6 @@ packages: resolution: {integrity: sha512-OEJWVeimw8mgQuj3HfkNl4KqRevH7lzeQNaWRPfx0PPse7Jk6ozcsG4FKVgtzDsC1KUF+YlTHh17NcgHOPykLw==} engines: {node: '>=10'} - resolve@1.22.2: - resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==} - hasBin: true - resolve@1.22.8: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true @@ -11320,6 +11506,15 @@ packages: robust-predicates@3.0.2: resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} + rollup-plugin-output-size@1.4.1: + resolution: {integrity: sha512-tcKAerPXSVIPFrAr30+8lEEoVzbtZS1cmOrtTpVf+iI3x0qymzihiSu+ns/7yXKB48u77xUQ1By14+GVnv+u3A==} + engines: {node: '>=14.16.0'} + peerDependencies: + rollup: ^2.0.0 || ^3.0.0 || ^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + rollup@4.14.3: resolution: {integrity: sha512-ag5tTQKYsj1bhrFC9+OEWqb5O6VYgtQDO9hPDBMmIbePwhfSr+ExlcU741t8Dhw5DkPCQf6noz0jb36D6W9/hw==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -11898,10 +12093,18 @@ packages: tinybench@2.8.0: resolution: {integrity: sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==} + tinypool@0.8.4: + resolution: {integrity: sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==} + engines: {node: '>=14.0.0'} + tinypool@1.0.0: resolution: {integrity: sha512-KIKExllK7jp3uvrNtvRBYBWBOAXSX8ZvoaD8T+7KB/QHIuoJW3Pmr60zucywjAlMb5TeXUkcs/MWeWLu0qvuAQ==} engines: {node: ^18.0.0 || >=20.0.0} + tinyspy@2.2.1: + resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==} + engines: {node: '>=14.0.0'} + tinyspy@3.0.0: resolution: {integrity: sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA==} engines: {node: '>=14.0.0'} @@ -12050,6 +12253,10 @@ packages: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} engines: {node: '>=4'} + type-detect@4.1.0: + resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} + engines: {node: '>=4'} + type-fest@0.13.1: resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} engines: {node: '>=10'} @@ -12132,6 +12339,9 @@ packages: ua-parser-js@1.0.37: resolution: {integrity: sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ==} + ufo@1.5.4: + resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} @@ -12253,6 +12463,11 @@ packages: vfile@6.0.1: resolution: {integrity: sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==} + vite-node@1.6.0: + resolution: {integrity: sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + vite-node@2.0.0: resolution: {integrity: sha512-jZtezmjcgZTkMisIi68TdY8w/PqPTxK2pbfTU9/4Gqus1K3AVZqkwH0z7Vshe3CD6mq9rJq8SpqmuefDMIqkfQ==} engines: {node: ^18.0.0 || >=20.0.0} @@ -12303,6 +12518,31 @@ packages: terser: optional: true + vitest@1.6.0: + resolution: {integrity: sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 1.6.0 + '@vitest/ui': 1.6.0 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + vitest@2.0.0: resolution: {integrity: sha512-NvccE2tZhIoPSq3o3AoTBmItwhHNjzIxvOgfdzILIscyzSGOtw2+A1d/JJbS86HDVbc6TS5HnckQuCgTfp0HDQ==} engines: {node: ^18.0.0 || >=20.0.0} @@ -14838,6 +15078,23 @@ snapshots: '@remix-run/router@1.5.0': {} + '@rollup/plugin-commonjs@25.0.8(rollup@4.14.3)': + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@4.14.3) + commondir: 1.0.1 + estree-walker: 2.0.2 + glob: 8.1.0 + is-reference: 1.2.1 + magic-string: 0.30.10 + optionalDependencies: + rollup: 4.14.3 + + '@rollup/plugin-json@6.1.0(rollup@4.14.3)': + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@4.14.3) + optionalDependencies: + rollup: 4.14.3 + '@rollup/plugin-node-resolve@15.2.3(rollup@4.14.3)': dependencies: '@rollup/pluginutils': 5.1.0(rollup@4.14.3) @@ -14845,10 +15102,19 @@ snapshots: deepmerge: 4.3.1 is-builtin-module: 3.2.1 is-module: 1.0.0 - resolve: 1.22.2 + resolve: 1.22.8 optionalDependencies: rollup: 4.14.3 + '@rollup/plugin-typescript@11.1.6(rollup@4.14.3)(tslib@2.6.2)(typescript@5.5.3)': + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@4.14.3) + resolve: 1.22.8 + typescript: 5.5.3 + optionalDependencies: + rollup: 4.14.3 + tslib: 2.6.2 + '@rollup/pluginutils@5.1.0(rollup@4.14.3)': dependencies: '@types/estree': 1.0.5 @@ -14971,10 +15237,10 @@ snapshots: eslint-config-prettier: 9.1.0(eslint@8.57.0) eslint-config-xo: 0.44.0(eslint@8.57.0) eslint-config-xo-typescript: 4.0.0(@typescript-eslint/eslint-plugin@7.7.0(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0)(typescript@5.5.3))(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0)(typescript@5.5.3) - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1)(eslint@8.57.0) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0) eslint-plugin-consistent-default-export-name: 0.0.15 eslint-plugin-eslint-comments: 3.2.0(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) eslint-plugin-n: 17.2.1(eslint@8.57.0) eslint-plugin-no-use-extend-native: 0.5.0 eslint-plugin-prettier: 5.1.3(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.0.0) @@ -16090,6 +16356,25 @@ snapshots: transitivePeerDependencies: - supports-color + '@vitest/coverage-v8@1.6.0(vitest@1.6.0(@types/node@20.12.7)(happy-dom@14.12.3)(jsdom@20.0.2)(lightningcss@1.25.1)(sass@1.77.8))': + dependencies: + '@ampproject/remapping': 2.3.0 + '@bcoe/v8-coverage': 0.2.3 + debug: 4.3.5 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 5.0.6 + istanbul-reports: 3.1.7 + magic-string: 0.30.10 + magicast: 0.3.4 + picocolors: 1.0.1 + std-env: 3.7.0 + strip-literal: 2.1.0 + test-exclude: 6.0.0 + vitest: 1.6.0(@types/node@20.12.7)(happy-dom@14.12.3)(jsdom@20.0.2)(lightningcss@1.25.1)(sass@1.77.8) + transitivePeerDependencies: + - supports-color + '@vitest/coverage-v8@2.0.0(vitest@2.0.0(@types/node@20.10.4)(happy-dom@14.12.3)(jsdom@20.0.2)(lightningcss@1.25.1)(sass@1.77.8))': dependencies: '@ampproject/remapping': 2.3.0 @@ -16147,27 +16432,56 @@ snapshots: transitivePeerDependencies: - supports-color + '@vitest/expect@1.6.0': + dependencies: + '@vitest/spy': 1.6.0 + '@vitest/utils': 1.6.0 + chai: 4.5.0 + '@vitest/expect@2.0.0': dependencies: '@vitest/spy': 2.0.0 '@vitest/utils': 2.0.0 chai: 5.1.1 + '@vitest/runner@1.6.0': + dependencies: + '@vitest/utils': 1.6.0 + p-limit: 5.0.0 + pathe: 1.1.2 + '@vitest/runner@2.0.0': dependencies: '@vitest/utils': 2.0.0 pathe: 1.1.2 + '@vitest/snapshot@1.6.0': + dependencies: + magic-string: 0.30.10 + pathe: 1.1.2 + pretty-format: 29.7.0 + '@vitest/snapshot@2.0.0': dependencies: magic-string: 0.30.10 pathe: 1.1.2 pretty-format: 29.7.0 + '@vitest/spy@1.6.0': + dependencies: + tinyspy: 2.2.1 + '@vitest/spy@2.0.0': dependencies: tinyspy: 3.0.0 + '@vitest/utils@1.6.0': + dependencies: + diff-sequences: 29.6.3 + estree-walker: 3.0.3 + loupe: 2.3.7 + pretty-format: 29.7.0 + '@vitest/utils@2.0.0': dependencies: diff-sequences: 29.6.3 @@ -16525,6 +16839,8 @@ snapshots: pvutils: 1.1.3 tslib: 2.6.2 + assertion-error@1.1.0: {} + assertion-error@2.0.1: {} ast-types-flow@0.0.8: {} @@ -16572,6 +16888,14 @@ snapshots: transitivePeerDependencies: - debug + axios@1.7.2: + dependencies: + follow-redirects: 1.15.6 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + axobject-query@3.2.1: dependencies: dequal: 2.0.3 @@ -16801,6 +17125,16 @@ snapshots: ccount@2.0.1: {} + chai@4.5.0: + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.3 + deep-eql: 4.1.4 + get-func-name: 2.0.2 + loupe: 2.3.7 + pathval: 1.1.1 + type-detect: 4.1.0 + chai@5.1.1: dependencies: assertion-error: 2.0.1 @@ -16844,6 +17178,10 @@ snapshots: chardet@0.7.0: {} + check-error@1.0.3: + dependencies: + get-func-name: 2.0.2 + check-error@2.1.1: {} chokidar@3.5.3: @@ -16995,6 +17333,8 @@ snapshots: commander@8.3.0: {} + commondir@1.0.1: {} + compare-func@2.0.0: dependencies: array-ify: 1.0.0 @@ -17008,6 +17348,8 @@ snapshots: concat-map@0.0.1: {} + confbox@0.1.7: {} + confusing-browser-globals@1.0.11: {} content-disposition@0.5.4: @@ -17462,6 +17804,10 @@ snapshots: dedent@1.5.1: {} + deep-eql@4.1.4: + dependencies: + type-detect: 4.1.0 + deep-eql@5.0.2: {} deep-equal@1.0.1: {} @@ -17603,6 +17949,8 @@ snapshots: dotenv@16.4.5: {} + duplexer@0.1.2: {} + duplexify@4.1.3: dependencies: end-of-stream: 1.4.4 @@ -17900,13 +18248,13 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1)(eslint@8.57.0): + eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0): dependencies: debug: 4.3.4 enhanced-resolve: 5.16.0 eslint: 8.57.0 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) fast-glob: 3.3.2 get-tsconfig: 4.7.3 is-core-module: 2.13.1 @@ -17917,14 +18265,14 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0): + eslint-module-utils@2.8.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0): dependencies: debug: 3.2.7(supports-color@5.5.0) optionalDependencies: '@typescript-eslint/parser': 7.7.0(eslint@8.57.0)(typescript@5.5.3) eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1)(eslint@8.57.0) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0) transitivePeerDependencies: - supports-color @@ -17946,7 +18294,7 @@ snapshots: eslint: 8.57.0 ignore: 5.3.1 - eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): + eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0): dependencies: array-includes: 3.1.8 array.prototype.findlastindex: 1.2.5 @@ -17956,7 +18304,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) hasown: 2.0.2 is-core-module: 2.13.1 is-glob: 4.0.3 @@ -18619,6 +18967,14 @@ snapshots: once: 1.4.0 path-is-absolute: 1.0.1 + glob@8.1.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.6 + once: 1.4.0 + global-directory@4.0.1: dependencies: ini: 4.1.1 @@ -18736,6 +19092,10 @@ snapshots: - encoding - supports-color + gzip-size@7.0.0: + dependencies: + duplexer: 0.1.2 + happy-dom@14.12.3: dependencies: entities: 4.5.0 @@ -19154,10 +19514,6 @@ snapshots: dependencies: ci-info: 3.8.0 - is-core-module@2.12.1: - dependencies: - has: 1.0.3 - is-core-module@2.13.1: dependencies: hasown: 2.0.2 @@ -19251,6 +19607,10 @@ snapshots: lowercase-keys: 1.0.1 proto-props: 2.0.0 + is-reference@1.2.1: + dependencies: + '@types/estree': 1.0.5 + is-reference@3.0.2: dependencies: '@types/estree': 1.0.5 @@ -20319,6 +20679,11 @@ snapshots: loader-utils@3.2.0: {} + local-pkg@0.5.0: + dependencies: + mlly: 1.7.1 + pkg-types: 1.1.3 + locate-path@5.0.0: dependencies: p-locate: 4.1.0 @@ -20403,6 +20768,10 @@ snapshots: dependencies: js-tokens: 4.0.0 + loupe@2.3.7: + dependencies: + get-func-name: 2.0.2 + loupe@3.1.1: dependencies: get-func-name: 2.0.2 @@ -21157,6 +21526,10 @@ snapshots: dependencies: brace-expansion: 1.1.11 + minimatch@5.1.6: + dependencies: + brace-expansion: 2.0.1 + minimatch@9.0.4: dependencies: brace-expansion: 2.0.1 @@ -21192,6 +21565,13 @@ snapshots: mkdirp@3.0.1: {} + mlly@1.7.1: + dependencies: + acorn: 8.11.3 + pathe: 1.1.2 + pkg-types: 1.1.3 + ufo: 1.5.4 + module-details-from-path@1.0.3: {} monaco-editor@0.47.0: {} @@ -21534,6 +21914,10 @@ snapshots: dependencies: yocto-queue: 1.1.1 + p-limit@5.0.0: + dependencies: + yocto-queue: 1.1.1 + p-limit@6.0.0: dependencies: yocto-queue: 1.1.1 @@ -21672,6 +22056,8 @@ snapshots: pathe@1.1.2: {} + pathval@1.1.1: {} + pathval@2.0.0: {} pend@1.2.0: {} @@ -21776,6 +22162,12 @@ snapshots: dependencies: find-up: 5.0.0 + pkg-types@1.1.3: + dependencies: + confbox: 0.1.7 + mlly: 1.7.1 + pathe: 1.1.2 + pluralize@8.0.0: {} pngjs@5.0.0: {} @@ -21953,6 +22345,12 @@ snapshots: postgres-range@1.1.2: {} + postmark@4.0.4: + dependencies: + axios: 1.7.2 + transitivePeerDependencies: + - debug + preferred-pm@3.0.3: dependencies: find-up: 5.0.0 @@ -21970,6 +22368,8 @@ snapshots: prettier@3.0.0: {} + pretty-bytes@6.1.1: {} + pretty-format@27.5.1: dependencies: ansi-regex: 5.0.1 @@ -22546,12 +22946,6 @@ snapshots: resolve.exports@2.0.1: {} - resolve@1.22.2: - dependencies: - is-core-module: 2.12.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - resolve@1.22.8: dependencies: is-core-module: 2.13.1 @@ -22613,6 +23007,14 @@ snapshots: robust-predicates@3.0.2: {} + rollup-plugin-output-size@1.4.1(rollup@4.14.3): + dependencies: + colorette: 2.0.20 + gzip-size: 7.0.0 + pretty-bytes: 6.1.1 + optionalDependencies: + rollup: 4.14.3 + rollup@4.14.3: dependencies: '@types/estree': 1.0.5 @@ -23318,8 +23720,12 @@ snapshots: tinybench@2.8.0: {} + tinypool@0.8.4: {} + tinypool@1.0.0: {} + tinyspy@2.2.1: {} + tinyspy@3.0.0: {} tmp@0.0.33: @@ -23617,6 +24023,8 @@ snapshots: type-detect@4.0.8: {} + type-detect@4.1.0: {} + type-fest@0.13.1: {} type-fest@0.20.2: {} @@ -23684,6 +24092,8 @@ snapshots: ua-parser-js@1.0.37: {} + ufo@1.5.4: {} + unbox-primitive@1.0.2: dependencies: call-bind: 1.0.7 @@ -23821,6 +24231,23 @@ snapshots: unist-util-stringify-position: 4.0.0 vfile-message: 4.0.2 + vite-node@1.6.0(@types/node@20.12.7)(lightningcss@1.25.1)(sass@1.77.8): + dependencies: + cac: 6.7.14 + debug: 4.3.5 + pathe: 1.1.2 + picocolors: 1.0.1 + vite: 5.3.4(@types/node@20.12.7)(lightningcss@1.25.1)(sass@1.77.8) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + vite-node@2.0.0(@types/node@20.10.4)(lightningcss@1.25.1)(sass@1.77.8): dependencies: cac: 6.7.14 @@ -23935,6 +24362,41 @@ snapshots: lightningcss: 1.25.1 sass: 1.77.8 + vitest@1.6.0(@types/node@20.12.7)(happy-dom@14.12.3)(jsdom@20.0.2)(lightningcss@1.25.1)(sass@1.77.8): + dependencies: + '@vitest/expect': 1.6.0 + '@vitest/runner': 1.6.0 + '@vitest/snapshot': 1.6.0 + '@vitest/spy': 1.6.0 + '@vitest/utils': 1.6.0 + acorn-walk: 8.3.2 + chai: 4.5.0 + debug: 4.3.5 + execa: 8.0.1 + local-pkg: 0.5.0 + magic-string: 0.30.10 + pathe: 1.1.2 + picocolors: 1.0.1 + std-env: 3.7.0 + strip-literal: 2.1.0 + tinybench: 2.8.0 + tinypool: 0.8.4 + vite: 5.3.4(@types/node@20.12.7)(lightningcss@1.25.1)(sass@1.77.8) + vite-node: 1.6.0(@types/node@20.12.7)(lightningcss@1.25.1)(sass@1.77.8) + why-is-node-running: 2.2.2 + optionalDependencies: + '@types/node': 20.12.7 + happy-dom: 14.12.3 + jsdom: 20.0.2 + transitivePeerDependencies: + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + vitest@2.0.0(@types/node@20.10.4)(happy-dom@14.12.3)(jsdom@20.0.2)(lightningcss@1.25.1)(sass@1.77.8): dependencies: '@ampproject/remapping': 2.3.0