From 32b63ee739d93023f87320cf69ff88ac34e24ee9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C6=B0=C6=A1ng=20T=E1=BA=A5n=20Hu=E1=BB=B3nh=20Phong?= Date: Tue, 2 Jul 2024 01:28:08 +0700 Subject: [PATCH] [core]: build simple ioc container for di --- .gitignore | 1 + package.json | 3 +- packages/@config/tsconfig/tsconfig.base.json | 4 +- packages/@core/package.json | 10 +- .../src/__tests__/constants/metadata.spec.ts | 21 +- .../__tests__/decorators/injection.spec.ts | 127 +++++++++ .../src/__tests__/utils/metadataUtils.spec.ts | 261 ++++++++++++++---- packages/@core/src/constants/injection.ts | 1 + packages/@core/src/constants/metadata.ts | 6 + packages/@core/src/core/IoC.ts | 1 + packages/@core/src/decorators/injection.ts | 35 +++ packages/@core/src/index.ts | 1 + packages/@core/src/utils/metadataUtils.ts | 99 ++++++- pnpm-lock.yaml | 170 +++++++++++- 14 files changed, 661 insertions(+), 79 deletions(-) create mode 100644 packages/@core/src/__tests__/decorators/injection.spec.ts create mode 100644 packages/@core/src/constants/injection.ts create mode 100644 packages/@core/src/core/IoC.ts create mode 100644 packages/@core/src/decorators/injection.ts diff --git a/.gitignore b/.gitignore index 1d4f15f..28054d7 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,6 @@ node_modules .turbo lib +dist docs/.vitepress/cache docs/.vitepress/dist diff --git a/package.json b/package.json index b336a63..de4a593 100644 --- a/package.json +++ b/package.json @@ -33,9 +33,10 @@ "devDependencies": { "@biomejs/biome": "^1.8.3", "@config/tsconfig": "workspace:^", + "@swc/core": "^1.6.6", "@types/globals": "workspace:^", "@vitest/coverage-istanbul": "^1.6.0", - "globals": "^15.6.0", + "globals": "^15.7.0", "husky": "^9.0.11", "lint-staged": "^15.2.7", "rimraf": "^5.0.7", diff --git a/packages/@config/tsconfig/tsconfig.base.json b/packages/@config/tsconfig/tsconfig.base.json index 99ce4e3..2e78ec3 100644 --- a/packages/@config/tsconfig/tsconfig.base.json +++ b/packages/@config/tsconfig/tsconfig.base.json @@ -2,14 +2,14 @@ "compilerOptions": { "allowJs": true, "allowSyntheticDefaultImports": true, + "emitDecoratorMetadata": true, "esModuleInterop": true, "experimentalDecorators": true, "forceConsistentCasingInFileNames": true, "importHelpers": true, "isolatedModules": true, "module": "ESNext", - "moduleResolution": "node", - "noEmit": true, + "moduleResolution": "Node", "noUncheckedIndexedAccess": true, "removeComments": true, "resolveJsonModule": true, diff --git a/packages/@core/package.json b/packages/@core/package.json index cfe485f..a889e35 100644 --- a/packages/@core/package.json +++ b/packages/@core/package.json @@ -1,6 +1,6 @@ { "name": "@abyss.ts/core", - "version": "0.0.1", + "version": "0.0.2", "author": "Alpha", "repository": { "type": "git", @@ -8,8 +8,12 @@ }, "license": "MIT", "type": "module", - "main": "lib/index.js", - "types": "lib/index.d.ts", + "main": "src/index.ts", + "types": "src/index.ts", + "publishConfig": { + "main": "lib/index.js", + "types": "lib/index.d.ts" + }, "keywords": ["abyss", "abyssts", "abyssjs", "abyss.js", "abyss.ts", "node"], "scripts": { "prepublish": "pnpm build", diff --git a/packages/@core/src/__tests__/constants/metadata.spec.ts b/packages/@core/src/__tests__/constants/metadata.spec.ts index 3d9bd9f..ffed76a 100644 --- a/packages/@core/src/__tests__/constants/metadata.spec.ts +++ b/packages/@core/src/__tests__/constants/metadata.spec.ts @@ -1,6 +1,13 @@ import { describe, expect, it } from 'vitest'; -import { ACTIONS, CONTROLLER, PARAMS } from '../../constants/metadata'; +import { + INJECT, + PARAMS, + ACTIONS, + INJECTABLE, + CONTROLLER, + IOC_CONTAINER, +} from '../../constants/metadata'; describe('[constants]: metadata', () => { it('has CONTROLLER as __controllerMetadata__', () => { @@ -14,4 +21,16 @@ describe('[constants]: metadata', () => { it('has PARAMS as __actionParamsMetadata__', () => { expect(PARAMS).toBe('__actionParamsMetadata__'); }); + + it('has INJECT as __injectMetadata__', () => { + expect(INJECT).toBe('__injectMetadata__'); + }); + + it('has INJECTABLE as __injectableMetadata__', () => { + expect(INJECTABLE).toBe('__injectableMetadata__'); + }); + + it('has IOC_CONTAINER as __iocContainer__', () => { + expect(IOC_CONTAINER).toBe('__iocContainer__'); + }); }); diff --git a/packages/@core/src/__tests__/decorators/injection.spec.ts b/packages/@core/src/__tests__/decorators/injection.spec.ts new file mode 100644 index 0000000..aea101b --- /dev/null +++ b/packages/@core/src/__tests__/decorators/injection.spec.ts @@ -0,0 +1,127 @@ +import { describe, expect, it, suite, afterEach } from 'vitest'; + +import { IoC } from '../../core/IoC'; +import { INJECT, INJECTABLE } from '../../constants/metadata'; +import { Inject, Injectable } from '../../decorators/injection'; + +describe('[decorators]: injection', () => { + suite('Injectable', () => { + afterEach(() => { + Reflect.deleteMetadata(INJECTABLE, IoC); + }); + + suite('without scope', () => { + it('sets metadata for MyService class', () => { + @Injectable() + class MyService {} + + expect(Reflect.getMetadata(INJECTABLE, IoC)).toStrictEqual([ + { + scope: 'singleton', + target: MyService, + }, + ]); + }); + }); + + suite('with scope scoped', () => { + it('sets metadata for MyService class', () => { + @Injectable({ + scope: 'scoped', + }) + class MyService {} + + expect(Reflect.getMetadata(INJECTABLE, IoC)).toStrictEqual([ + { + scope: 'scoped', + target: MyService, + }, + ]); + }); + }); + + suite('with scope singleton', () => { + it('sets metadata for MyService class', () => { + @Injectable({ + scope: 'singleton', + }) + class MyService {} + + expect(Reflect.getMetadata(INJECTABLE, IoC)).toStrictEqual([ + { + scope: 'singleton', + target: MyService, + }, + ]); + }); + }); + + suite('with scope transient', () => { + it('sets metadata for MyService class', () => { + @Injectable({ + scope: 'transient', + }) + class MyService {} + + expect(Reflect.getMetadata(INJECTABLE, IoC)).toStrictEqual([ + { + scope: 'transient', + target: MyService, + }, + ]); + }); + }); + }); + + suite('Inject', () => { + class InjectService {} + + class AnotherInjectService {} + + suite('with one param', () => { + it("sets metadata for MyService class's constructor", () => { + class MyService { + constructor( + @Inject(InjectService) + // biome-ignore lint/correctness/noUnusedPrivateClassMembers: + private readonly injectService: InjectService, + ) {} + } + + expect( + Reflect.getMetadata(INJECT, MyService, 'constructor'), + ).toStrictEqual([ + { + extractor: InjectService, + }, + ]); + }); + }); + + suite('with two params', () => { + it("sets metadata for MyService class's constructor", () => { + class MyService { + constructor( + @Inject(InjectService) + // biome-ignore lint/correctness/noUnusedPrivateClassMembers: + private readonly injectService: InjectService, + @Inject(AnotherInjectService) + // biome-ignore lint/correctness/noUnusedPrivateClassMembers: + private readonly anotherInjectService: AnotherInjectService, + ) {} + } + + expect( + Reflect.getMetadata(INJECT, MyService, 'constructor'), + ).toStrictEqual([ + { + extractor: InjectService, + }, + { + extractor: AnotherInjectService, + }, + ]); + }); + }); + }); +}); diff --git a/packages/@core/src/__tests__/utils/metadataUtils.spec.ts b/packages/@core/src/__tests__/utils/metadataUtils.spec.ts index 5c28a57..47fd182 100644 --- a/packages/@core/src/__tests__/utils/metadataUtils.spec.ts +++ b/packages/@core/src/__tests__/utils/metadataUtils.spec.ts @@ -1,7 +1,18 @@ -import { describe, expect, it, suite } from 'vitest'; +import { afterEach, describe, expect, it, suite } from 'vitest'; -import { ACTIONS, CONTROLLER, PARAMS } from '../../constants/metadata'; +import { IoC } from '../../core/IoC'; import { + PARAMS, + ACTIONS, + CONTROLLER, + INJECTABLE, + IOC_CONTAINER, +} from '../../constants/metadata'; +import { + pushToIoCContainer, + getFromIoCContainer, + getInjectionMetadata, + setInjectionMetadata, getControllerMetadata, setControllerMetadata, getActionParamMetadata, @@ -28,21 +39,31 @@ describe('[utils]: metadataUtils', () => { }); suite('getControllerMetadata', () => { - it('gets metadata from MyController class', () => { - class MyController {} + suite('set before use', () => { + it('gets metadata from MyController class', () => { + class MyController {} - Reflect.defineMetadata( - CONTROLLER, - { - type: 'controller', + Reflect.defineMetadata( + CONTROLLER, + { + type: 'controller', + route: 'test', + }, + MyController, + ); + + expect(getControllerMetadata(MyController)).toStrictEqual({ route: 'test', - }, - MyController, - ); + type: 'controller', + }); + }); + }); - expect(getControllerMetadata(MyController)).toStrictEqual({ - route: 'test', - type: 'controller', + suite('use without being set', () => { + it('gets {}', () => { + class MyController {} + + expect(getControllerMetadata(MyController)).toStrictEqual({}); }); }); }); @@ -76,16 +97,29 @@ describe('[utils]: metadataUtils', () => { }); suite('getControllerActionMetadata', () => { - it('gets metadata from MyController class', () => { - class MyController { - index(): string { - return 'Test'; + suite('set before use', () => { + it('gets metadata from MyController class', () => { + class MyController { + index(): string { + return 'Test'; + } } - } - Reflect.defineMetadata( - ACTIONS, - [ + Reflect.defineMetadata( + ACTIONS, + [ + { + route: 'test', + type: 'action', + httpMethod: 'get', + propertyKey: 'index', + exec: MyController.prototype.index, + }, + ], + MyController, + ); + + expect(getControllerActionMetadata(MyController)).toStrictEqual([ { route: 'test', type: 'action', @@ -93,19 +127,20 @@ describe('[utils]: metadataUtils', () => { propertyKey: 'index', exec: MyController.prototype.index, }, - ], - MyController, - ); + ]); + }); + }); - expect(getControllerActionMetadata(MyController)).toStrictEqual([ - { - route: 'test', - type: 'action', - httpMethod: 'get', - propertyKey: 'index', - exec: MyController.prototype.index, - }, - ]); + suite('use without being set', () => { + it('gets []', () => { + class MyController { + index(): string { + return 'Test'; + } + } + + expect(getControllerActionMetadata(MyController)).toStrictEqual([]); + }); }); }); @@ -135,36 +170,154 @@ describe('[utils]: metadataUtils', () => { }); suite('getActionParamMetadata', () => { - it('gets metadata from MyController class', () => { - class MyController { - index(): string { - return 'Test'; + suite('set before use', () => { + it('gets metadata from MyController class', () => { + class MyController { + index(): string { + return 'Test'; + } } - } - Reflect.defineMetadata( - PARAMS, - [ + Reflect.defineMetadata( + PARAMS, + [ + { + type: 'query', + extractor: 'test', + }, + ], + MyController, + 'index', + ); + + expect( + getActionParamMetadata({ + propertyKey: 'index', + controller: MyController, + }), + ).toStrictEqual([ { type: 'query', extractor: 'test', }, - ], - MyController, - 'index', - ); + ]); + }); + }); - expect( - getActionParamMetadata({ - propertyKey: 'index', - controller: MyController, - }), - ).toStrictEqual([ + suite('use without being set', () => { + it('gets []', () => { + class MyController { + index(): string { + return 'Test'; + } + } + + expect( + getActionParamMetadata({ + propertyKey: 'index', + controller: MyController, + }), + ).toStrictEqual([]); + }); + }); + }); + + suite('setInjectionMetadata', () => { + it('sets metadata for MyController class', () => { + class MyController { + index(): string { + return 'Test'; + } + } + + setInjectionMetadata({ + scope: 'singleton', + target: MyController, + }); + + expect(Reflect.getMetadata(INJECTABLE, IoC)).toStrictEqual([ { - type: 'query', - extractor: 'test', + scope: 'singleton', + target: MyController, }, ]); }); }); + + suite('getInjectionMetadata', () => { + afterEach(() => { + Reflect.deleteMetadata(INJECTABLE, IoC); + }); + + suite('set before use', () => { + it('gets metadata from MyController class', () => { + class MyController { + index(): string { + return 'Test'; + } + } + + Reflect.defineMetadata( + INJECTABLE, + [ + { + scope: 'singleton', + target: MyController, + }, + ], + IoC, + ); + + expect(getInjectionMetadata()).toStrictEqual([ + { + scope: 'singleton', + target: MyController, + }, + ]); + }); + }); + + suite('use without being set', () => { + it('gets []', () => { + expect(getInjectionMetadata()).toStrictEqual([]); + }); + }); + }); + + suite('pushToIoCContainer', () => { + it('sets metadata for MyService class', () => { + class MyService { + index(): string { + return 'Test'; + } + } + + const instance = new MyService(); + + pushToIoCContainer({ + instance, + target: MyService, + }); + + expect(Reflect.getMetadata(IOC_CONTAINER, MyService)).toStrictEqual( + instance, + ); + }); + }); + + suite('getFromIoCContainer', () => { + it('gets metadata from MyService class', () => { + class MyService { + index(): string { + return 'Test'; + } + } + + const instance = new MyService(); + + Reflect.defineMetadata(IOC_CONTAINER, instance, MyService); + + expect(getFromIoCContainer(MyService)).toStrictEqual(instance); + }); + }); }); diff --git a/packages/@core/src/constants/injection.ts b/packages/@core/src/constants/injection.ts new file mode 100644 index 0000000..13faa37 --- /dev/null +++ b/packages/@core/src/constants/injection.ts @@ -0,0 +1 @@ +export type TInjectionScopes = 'scoped' | 'singleton' | 'transient'; diff --git a/packages/@core/src/constants/metadata.ts b/packages/@core/src/constants/metadata.ts index e2bcc0b..adaf86b 100644 --- a/packages/@core/src/constants/metadata.ts +++ b/packages/@core/src/constants/metadata.ts @@ -3,3 +3,9 @@ export const CONTROLLER = '__controllerMetadata__'; export const ACTIONS = '__actionsMetadata__'; export const PARAMS = '__actionParamsMetadata__'; + +export const INJECTABLE = '__injectableMetadata__'; + +export const INJECT = '__injectMetadata__'; + +export const IOC_CONTAINER = '__iocContainer__'; diff --git a/packages/@core/src/core/IoC.ts b/packages/@core/src/core/IoC.ts new file mode 100644 index 0000000..864a827 --- /dev/null +++ b/packages/@core/src/core/IoC.ts @@ -0,0 +1 @@ +export class IoC {} diff --git a/packages/@core/src/decorators/injection.ts b/packages/@core/src/decorators/injection.ts new file mode 100644 index 0000000..e5c6867 --- /dev/null +++ b/packages/@core/src/decorators/injection.ts @@ -0,0 +1,35 @@ +import { + setInjectionMetadata, + setInjectParamMetadata, +} from '../utils/metadataUtils'; + +import type { TInjectionScopes } from '../constants/injection'; + +interface IInjectableParams { + scope?: TInjectionScopes; +} + +export function Injectable({ + scope = 'singleton', +}: IInjectableParams = {}): ClassDecorator { + return (target: TAny) => { + setInjectionMetadata({ + scope, + target, + }); + }; +} + +export function Inject(injectable: TAny): ParameterDecorator { + return ( + target: TAny, + _propertyKey: string | symbol | undefined, + parameterIndex: number, + ) => { + setInjectParamMetadata({ + target, + parameterIndex, + extractor: injectable, + }); + }; +} diff --git a/packages/@core/src/index.ts b/packages/@core/src/index.ts index a4768f1..7b767ba 100644 --- a/packages/@core/src/index.ts +++ b/packages/@core/src/index.ts @@ -2,6 +2,7 @@ export * from './core/AbyssApplication'; export * from './decorators/controller'; export * from './decorators/httpMethods'; +export * from './decorators/injection'; export * from './decorators/parameters'; export * from './utils/controllerUtils'; diff --git a/packages/@core/src/utils/metadataUtils.ts b/packages/@core/src/utils/metadataUtils.ts index eb3008d..8d6751a 100644 --- a/packages/@core/src/utils/metadataUtils.ts +++ b/packages/@core/src/utils/metadataUtils.ts @@ -1,8 +1,18 @@ import 'reflect-metadata'; +import { IoC } from '../core/IoC'; import { push } from './arrayUtils'; import { sanitize } from './routeUtils'; -import { ACTIONS, CONTROLLER, PARAMS } from '../constants/metadata'; +import { + PARAMS, + INJECT, + ACTIONS, + INJECTABLE, + CONTROLLER, + IOC_CONTAINER, +} from '../constants/metadata'; + +import type { TInjectionScopes } from '../constants/injection'; export type THttpMethod = 'get' | 'post' | 'put' | 'delete' | 'patch'; @@ -30,7 +40,7 @@ export function setControllerMetadata({ } export function getControllerMetadata(controller: TAny): IControllerProps { - return Reflect.getMetadata(CONTROLLER, controller); + return Reflect.getMetadata(CONTROLLER, controller) || {}; } interface IControllerActionProps { @@ -68,7 +78,12 @@ export function getControllerActionMetadata( return Reflect.getMetadata(ACTIONS, controller) || []; } -export type TBaseActionParam = 'query' | 'param' | 'body' | 'request'; +export type TBaseActionParam = + | 'body' + | 'query' + | 'param' + | 'request' + | 'injection'; export interface IActionParamProps { extractor?: string; @@ -114,5 +129,81 @@ export function getActionParamMetadata({ controller, propertyKey, }: IGetActionParamMetadataParams): IActionParamProps[] { - return Reflect.getMetadata(PARAMS, controller, propertyKey); + return Reflect.getMetadata(PARAMS, controller, propertyKey) || []; +} + +export interface IInjectionProps { + target: TAny; + scope: TInjectionScopes; +} + +export function setInjectionMetadata({ scope, target }: IInjectionProps): void { + const injections = getInjectionMetadata(); + + push(injections, { + scope, + target, + }); + + Reflect.defineMetadata(INJECTABLE, injections, IoC); +} + +export function getInjectionMetadata(): IInjectionProps[] { + return Reflect.getMetadata(INJECTABLE, IoC) || []; +} + +interface IInjectProps { + extractor: TAny; +} + +interface ISetInjectParamMetadataParams { + target: TAny; + extractor: TAny; + parameterIndex: number; +} + +export function setInjectParamMetadata({ + target, + extractor, + parameterIndex, +}: ISetInjectParamMetadataParams): void { + let params = getInjectParamMetadata({ + target, + }); + + params = push( + params, + { + extractor, + }, + parameterIndex, + ); + + Reflect.defineMetadata(INJECT, params, target, 'constructor'); +} + +interface IGetInjectParamMetadataParams { + target: TAny; +} + +export function getInjectParamMetadata({ + target, +}: IGetInjectParamMetadataParams): IInjectProps[] { + return Reflect.getMetadata(INJECT, target, 'constructor') || []; +} + +interface IPushToIoCContainerParams { + target: TAny; + instance: TAny; +} + +export function pushToIoCContainer({ + target, + instance, +}: IPushToIoCContainerParams): void { + Reflect.defineMetadata(IOC_CONTAINER, instance, target); +} + +export function getFromIoCContainer(target: TAny): TAny { + return Reflect.getMetadata(IOC_CONTAINER, target); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ac1db6c..c78cdd2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,6 +18,9 @@ importers: '@config/tsconfig': specifier: workspace:^ version: link:packages/@config/tsconfig + '@swc/core': + specifier: ^1.6.6 + version: 1.6.6 '@types/globals': specifier: workspace:^ version: link:packages/@types @@ -25,8 +28,8 @@ importers: specifier: ^1.6.0 version: 1.6.0(vitest@1.6.0(@types/node@20.14.9)) globals: - specifier: ^15.6.0 - version: 15.6.0 + specifier: ^15.7.0 + version: 15.7.0 husky: specifier: ^9.0.11 version: 9.0.11 @@ -38,7 +41,7 @@ importers: version: 5.0.7 tsup: specifier: ^8.1.0 - version: 8.1.0(postcss@8.4.38)(typescript@5.5.2) + version: 8.1.0(@swc/core@1.6.6)(postcss@8.4.39)(typescript@5.5.2) turbo: specifier: ^2.0.6 version: 2.0.6 @@ -50,7 +53,7 @@ importers: version: 5.3.2(@types/node@20.14.9) vitepress: specifier: ^1.2.3 - version: 1.2.3(@algolia/client-search@4.24.0)(@types/node@20.14.9)(postcss@8.4.38)(search-insights@2.14.0)(typescript@5.5.2) + version: 1.2.3(@algolia/client-search@4.24.0)(@types/node@20.14.9)(postcss@8.4.39)(search-insights@2.14.0)(typescript@5.5.2) vitest: specifier: ^1.6.0 version: 1.6.0(@types/node@20.14.9) @@ -625,6 +628,81 @@ packages: '@sinclair/typebox@0.27.8': resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + '@swc/core-darwin-arm64@1.6.6': + resolution: {integrity: sha512-5DA8NUGECcbcK1YLKJwNDKqdtTYDVnkfDU1WvQSXq/rU+bjYCLtn5gCe8/yzL7ISXA6rwqPU1RDejhbNt4ARLQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + + '@swc/core-darwin-x64@1.6.6': + resolution: {integrity: sha512-2nbh/RHpweNRsJiYDFk1KcX7UtaKgzzTNUjwtvK5cp0wWrpbXmPvdlWOx3yzwoiSASDFx78242JHHXCIOlEdsw==} + engines: {node: '>=10'} + cpu: [x64] + os: [darwin] + + '@swc/core-linux-arm-gnueabihf@1.6.6': + resolution: {integrity: sha512-YgytuyUfR7b0z0SRHKV+ylr83HmgnROgeT7xryEkth6JGpAEHooCspQ4RrWTU8+WKJ7aXiZlGXPgybQ4TiS+TA==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + + '@swc/core-linux-arm64-gnu@1.6.6': + resolution: {integrity: sha512-yGwx9fddzEE0iURqRVwKBQ4IwRHE6hNhl15WliHpi/PcYhzmYkUIpcbRXjr0dssubXAVPVnx6+jZVDSbutvnfg==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-arm64-musl@1.6.6': + resolution: {integrity: sha512-a6fMbqzSAsS5KCxFJyg1mD5kwN3ZFO8qQLyJ75R/htZP/eCt05jrhmOI7h2n+1HjiG332jLnZ9S8lkVE5O8Nqw==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-x64-gnu@1.6.6': + resolution: {integrity: sha512-hRGsUKNzzZle28YF0dYIpN0bt9PceR9LaVBq7x8+l9TAaDLFbgksSxcnU/ubTtsy+WsYSYGn+A83w3xWC0O8CQ==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-linux-x64-musl@1.6.6': + resolution: {integrity: sha512-NokIUtFxJDVv3LzGeEtYMTV3j2dnGKLac59luTeq36DQLZdJQawQIdTbzzWl2jE7lxxTZme+dhsVOH9LxE3ceg==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-win32-arm64-msvc@1.6.6': + resolution: {integrity: sha512-lzYdI4qb4k1dFG26yv+9Jaq/bUMAhgs/2JsrLncGjLof86+uj74wKYCQnbzKAsq2hDtS5DqnHnl+//J+miZfGA==} + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] + + '@swc/core-win32-ia32-msvc@1.6.6': + resolution: {integrity: sha512-bvl7FMaXIJQ76WZU0ER4+RyfKIMGb6S2MgRkBhJOOp0i7VFx4WLOnrmMzaeoPJaJSkityVKAftfNh7NBzTIydQ==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + + '@swc/core-win32-x64-msvc@1.6.6': + resolution: {integrity: sha512-WAP0JoCTfgeYKgOeYJoJV4ZS0sQUmU3OwvXa2dYYtMLF7zsNqOiW4niU7QlThBHgUv/qNZm2p6ITEgh3w1cltw==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + + '@swc/core@1.6.6': + resolution: {integrity: sha512-sHfmIUPUXNrQTwFMVCY5V5Ena2GTOeaWjS2GFUpjLhAgVfP90OP67DWow7+cYrfFtqBdILHuWnjkTcd0+uPKlg==} + engines: {node: '>=10'} + peerDependencies: + '@swc/helpers': '*' + peerDependenciesMeta: + '@swc/helpers': + optional: true + + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + + '@swc/types@0.1.9': + resolution: {integrity: sha512-qKnCno++jzcJ4lM4NTfYifm1EFSCeIfKiAHAfkENZAV5Kl9PjJIyd2yeeVv6c/2CckuLyv2NmRC5pv6pm2WQBg==} + '@types/body-parser@1.19.5': resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} @@ -1208,8 +1286,8 @@ packages: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} - globals@15.6.0: - resolution: {integrity: sha512-UzcJi88Hw//CurUIRa9Jxb0vgOCcuD/MNjwmXp633cyaRKkCWACkoqHCtfZv43b1kqXGg/fpOa8bwgacCeXsVg==} + globals@15.7.0: + resolution: {integrity: sha512-ivatRXWwKC6ImcdKO7dOwXuXR5XFrdwo45qFwD7D0qOkEPzzJdLXC3BHceBdyrPOD3p1suPaWi4Y4NMm2D++AQ==} engines: {node: '>=18'} globby@11.1.0: @@ -1630,6 +1708,10 @@ packages: resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} engines: {node: ^10 || ^12 || >=14} + postcss@8.4.39: + resolution: {integrity: sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==} + engines: {node: ^10 || ^12 || >=14} + preact@10.22.0: resolution: {integrity: sha512-RRurnSjJPj4rp5K6XoP45Ui33ncb7e4H7WiOHVpjbkvqvA3U+N8Z6Qbo0AE6leGYBV66n8EhEaFixvIu3SkxFw==} @@ -2597,6 +2679,58 @@ snapshots: '@sinclair/typebox@0.27.8': {} + '@swc/core-darwin-arm64@1.6.6': + optional: true + + '@swc/core-darwin-x64@1.6.6': + optional: true + + '@swc/core-linux-arm-gnueabihf@1.6.6': + optional: true + + '@swc/core-linux-arm64-gnu@1.6.6': + optional: true + + '@swc/core-linux-arm64-musl@1.6.6': + optional: true + + '@swc/core-linux-x64-gnu@1.6.6': + optional: true + + '@swc/core-linux-x64-musl@1.6.6': + optional: true + + '@swc/core-win32-arm64-msvc@1.6.6': + optional: true + + '@swc/core-win32-ia32-msvc@1.6.6': + optional: true + + '@swc/core-win32-x64-msvc@1.6.6': + optional: true + + '@swc/core@1.6.6': + dependencies: + '@swc/counter': 0.1.3 + '@swc/types': 0.1.9 + optionalDependencies: + '@swc/core-darwin-arm64': 1.6.6 + '@swc/core-darwin-x64': 1.6.6 + '@swc/core-linux-arm-gnueabihf': 1.6.6 + '@swc/core-linux-arm64-gnu': 1.6.6 + '@swc/core-linux-arm64-musl': 1.6.6 + '@swc/core-linux-x64-gnu': 1.6.6 + '@swc/core-linux-x64-musl': 1.6.6 + '@swc/core-win32-arm64-msvc': 1.6.6 + '@swc/core-win32-ia32-msvc': 1.6.6 + '@swc/core-win32-x64-msvc': 1.6.6 + + '@swc/counter@0.1.3': {} + + '@swc/types@0.1.9': + dependencies: + '@swc/counter': 0.1.3 + '@types/body-parser@1.19.5': dependencies: '@types/connect': 3.4.38 @@ -3290,7 +3424,7 @@ snapshots: globals@11.12.0: {} - globals@15.6.0: {} + globals@15.7.0: {} globby@11.1.0: dependencies: @@ -3641,12 +3775,12 @@ snapshots: mlly: 1.7.1 pathe: 1.1.2 - postcss-load-config@4.0.2(postcss@8.4.38): + postcss-load-config@4.0.2(postcss@8.4.39): dependencies: lilconfig: 3.1.2 yaml: 2.4.5 optionalDependencies: - postcss: 8.4.38 + postcss: 8.4.39 postcss@8.4.38: dependencies: @@ -3654,6 +3788,13 @@ snapshots: picocolors: 1.0.1 source-map-js: 1.2.0 + postcss@8.4.39: + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.1 + source-map-js: 1.2.0 + optional: true + preact@10.22.0: {} pretty-format@29.7.0: @@ -3930,7 +4071,7 @@ snapshots: tslib@2.6.3: {} - tsup@8.1.0(postcss@8.4.38)(typescript@5.5.2): + tsup@8.1.0(@swc/core@1.6.6)(postcss@8.4.39)(typescript@5.5.2): dependencies: bundle-require: 4.2.1(esbuild@0.21.5) cac: 6.7.14 @@ -3940,14 +4081,15 @@ snapshots: execa: 5.1.1 globby: 11.1.0 joycon: 3.1.1 - postcss-load-config: 4.0.2(postcss@8.4.38) + postcss-load-config: 4.0.2(postcss@8.4.39) resolve-from: 5.0.0 rollup: 4.18.0 source-map: 0.8.0-beta.0 sucrase: 3.35.0 tree-kill: 1.2.2 optionalDependencies: - postcss: 8.4.38 + '@swc/core': 1.6.6 + postcss: 8.4.39 typescript: 5.5.2 transitivePeerDependencies: - supports-color @@ -4038,7 +4180,7 @@ snapshots: '@types/node': 20.14.9 fsevents: 2.3.3 - vitepress@1.2.3(@algolia/client-search@4.24.0)(@types/node@20.14.9)(postcss@8.4.38)(search-insights@2.14.0)(typescript@5.5.2): + vitepress@1.2.3(@algolia/client-search@4.24.0)(@types/node@20.14.9)(postcss@8.4.39)(search-insights@2.14.0)(typescript@5.5.2): dependencies: '@docsearch/css': 3.6.0 '@docsearch/js': 3.6.0(@algolia/client-search@4.24.0)(search-insights@2.14.0) @@ -4057,7 +4199,7 @@ snapshots: vite: 5.3.2(@types/node@20.14.9) vue: 3.4.31(typescript@5.5.2) optionalDependencies: - postcss: 8.4.38 + postcss: 8.4.39 transitivePeerDependencies: - '@algolia/client-search' - '@types/node'