├── .editorconfig ├── .gitattributes ├── .github └── workflows │ └── main.yml ├── .gitignore ├── .prettierrc ├── LICENSE ├── README.md ├── assets └── dioma-logo.webp ├── package-lock.json ├── package.json ├── src ├── container.ts ├── errors.ts ├── index.ts ├── scopes.ts ├── token.ts └── types.ts ├── test └── dioma.test.ts ├── tsconfig.json └── vite.config.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | 7 | [*.{js,json,yml}] 8 | charset = utf-8 9 | indent_style = space 10 | indent_size = 2 11 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | /.yarn/** linguist-vendored 2 | /.yarn/releases/* binary 3 | /.yarn/plugins/**/* binary 4 | /.pnp.* binary linguist-generated 5 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | 6 | jobs: 7 | coverage: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Setup Node 11 | uses: actions/setup-node@v4 12 | with: 13 | node-version: '20.x' 14 | - name: Checkout 15 | uses: actions/checkout@v4.1.2 16 | - name: Install dependencies 17 | run: npm install 18 | - name: Run coverage report 19 | run: npm run test:coverage 20 | - name: Upload coverage reports to Codecov 21 | uses: codecov/codecov-action@v4.0.1 22 | with: 23 | token: ${{ secrets.CODECOV_TOKEN }} 24 | slug: zheksoon/dioma 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | .pnpm-debug.log* 9 | 10 | # Diagnostic reports (https://nodejs.org/api/report.html) 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | *.pid.lock 18 | 19 | # Directory for instrumented libs generated by jscoverage/JSCover 20 | lib-cov 21 | 22 | # Coverage directory used by tools like istanbul 23 | coverage 24 | *.lcov 25 | 26 | # nyc test coverage 27 | .nyc_output 28 | 29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 30 | .grunt 31 | 32 | # Bower dependency directory (https://bower.io/) 33 | bower_components 34 | 35 | # node-waf configuration 36 | .lock-wscript 37 | 38 | # Compiled binary addons (https://nodejs.org/api/addons.html) 39 | build/Release 40 | 41 | # Dependency directories 42 | node_modules/ 43 | jspm_packages/ 44 | 45 | # Snowpack dependency directory (https://snowpack.dev/) 46 | web_modules/ 47 | 48 | # TypeScript cache 49 | *.tsbuildinfo 50 | 51 | # Optional npm cache directory 52 | .npm 53 | 54 | # Optional eslint cache 55 | .eslintcache 56 | 57 | # Optional stylelint cache 58 | .stylelintcache 59 | 60 | # Microbundle cache 61 | .rpt2_cache/ 62 | .rts2_cache_cjs/ 63 | .rts2_cache_es/ 64 | .rts2_cache_umd/ 65 | 66 | # Optional REPL history 67 | .node_repl_history 68 | 69 | # Output of 'npm pack' 70 | *.tgz 71 | 72 | # Yarn Integrity file 73 | .yarn-integrity 74 | 75 | # dotenv environment variable files 76 | .env 77 | .env.development.local 78 | .env.test.local 79 | .env.production.local 80 | .env.local 81 | 82 | # parcel-bundler cache (https://parceljs.org/) 83 | .cache 84 | .parcel-cache 85 | 86 | # Next.js build output 87 | .next 88 | out 89 | 90 | # Nuxt.js build / generate output 91 | .nuxt 92 | dist 93 | 94 | # Gatsby files 95 | .cache/ 96 | # Comment in the public line in if your project uses Gatsby and not Next.js 97 | # https://nextjs.org/blog/next-9-1#public-directory-support 98 | # public 99 | 100 | # vuepress build output 101 | .vuepress/dist 102 | 103 | # vuepress v2.x temp and cache directory 104 | .temp 105 | .cache 106 | 107 | # Docusaurus cache and generated files 108 | .docusaurus 109 | 110 | # Serverless directories 111 | .serverless/ 112 | 113 | # FuseBox cache 114 | .fusebox/ 115 | 116 | # DynamoDB Local files 117 | .dynamodb/ 118 | 119 | # TernJS port file 120 | .tern-port 121 | 122 | # Stores VSCode versions used for testing VSCode extensions 123 | .vscode-test 124 | 125 | # yarn v2 126 | .yarn/cache 127 | .yarn/unplugged 128 | .yarn/build-state.yml 129 | .yarn/install-state.gz 130 | .pnp.* -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 90, 3 | "overrides": [ 4 | { 5 | "files": "*.md", 6 | "options": { 7 | "printWidth": 80 8 | } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Eugene Daragan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Dioma

2 | 3 |

4 | dioma 5 |

6 |

7 | Elegant dependency injection container for vanilla JavaScript and TypeScript 8 |

9 |

10 | NPM Version 11 | NPM package gzipped size 12 | Codecov 13 |

14 | 15 | ## Features 16 | 17 | - Just do it - no decorators, no annotations, no magic 18 | - Tokens for class, value, and factory injection 19 | - Async injection and dependency cycle detection 20 | - TypeScript support 21 | - No dependencies 22 | - Tiny size 23 | 24 | ## Installation 25 | 26 | ```sh 27 | npm install --save dioma 28 | 29 | yarn add dioma 30 | ``` 31 | 32 | ## Usage 33 | 34 | To start injecting dependencies, you just need to add the `static scope` property to your class and use the `inject` function to get the instance of it. By default, `inject` makes classes "stick" to the container where they were first injected (more details in the [Class registration](#Class-registration) section). 35 | 36 | Here's an example of using it for [Singleton](#singleton-scope) and [Transient](#transient-scope) scopes: 37 | 38 | ```typescript 39 | import { inject, Scopes } from "dioma"; 40 | 41 | class Garage { 42 | open() { 43 | console.log("garage opened"); 44 | } 45 | 46 | // Single instance of the class for the entire application 47 | static scope = Scopes.Singleton(); 48 | } 49 | 50 | class Car { 51 | // injects instance of Garage 52 | constructor(private garage = inject(Garage)) {} 53 | 54 | park() { 55 | this.garage.open(); 56 | console.log("car parked"); 57 | } 58 | 59 | // New instance of the class on every injection 60 | static scope = Scopes.Transient(); 61 | } 62 | 63 | // Creates a new Car and injects Garage 64 | const car = inject(Car); 65 | 66 | car.park(); 67 | ``` 68 | 69 | ## Scopes 70 | 71 | Dioma supports the following scopes: 72 | 73 | - `Scopes.Singleton()` - creates a single instance of the class 74 | - `Scopes.Transient()` - creates a new instance of the class on every injection 75 | - `Scopes.Container()` - creates a single instance of the class per container 76 | - `Scopes.Resolution()` - creates a new instance of the class every time, but the instance is the same for the entire resolution 77 | - `Scopes.Scoped()` is the same as `Scopes.Container()` 78 | 79 | ### Singleton scope 80 | 81 | Singleton scope creates a single instance of the class for the entire application. 82 | The instances are stored in the global container, so anyone can access them. 83 | If you want to isolate the class to a specific container, use the [Container](#Container-scope) scope. 84 | 85 | A simple example you can see in the [Usage](#Usage) section. 86 | 87 | Multiple singletons can be cross-referenced with each other using [async injection](#async-injection-and-circular-dependencies). 88 | 89 | ### Transient scope 90 | 91 | Transient scope creates a new instance of the class on every injection: 92 | 93 | ```typescript 94 | import { inject, Scopes } from "dioma"; 95 | 96 | class Engine { 97 | start() { 98 | console.log("Engine started"); 99 | } 100 | 101 | static scope = Scopes.Singleton(); 102 | } 103 | 104 | class Vehicle { 105 | constructor(private engine = inject(Engine)) {} 106 | 107 | drive() { 108 | this.engine.start(); 109 | console.log("Vehicle driving"); 110 | } 111 | 112 | static scope = Scopes.Transient(); 113 | } 114 | 115 | // New vehicle every time 116 | const vehicle = inject(Vehicle); 117 | 118 | vehicle.drive(); 119 | ``` 120 | 121 | Generally, transient scope instances can't be cross-referenced by the [async injection](#Async-injection-and-injection-cycles) with some exceptions. 122 | 123 | ### Container scope 124 | 125 | Container scope creates a single instance of the class per container. It's the same as the singleton, but relative to the custom container. 126 | 127 | The usage is the same as for the singleton scope, but you need to create a container first and use `container.inject` instead of `inject`: 128 | 129 | ```typescript 130 | import { Container, Scopes } from "dioma"; 131 | 132 | const container = new Container(); 133 | 134 | class Garage { 135 | open() { 136 | console.log("garage opened"); 137 | } 138 | 139 | // Single instance of the class for the container 140 | static scope = Scopes.Container(); 141 | } 142 | 143 | // Register Garage on the container 144 | container.register({ class: Garage }); 145 | 146 | class Car { 147 | // Use inject method of the container for Garage 148 | constructor(private garage = container.inject(Garage)) {} 149 | 150 | park() { 151 | this.garage.open(); 152 | console.log("car parked"); 153 | } 154 | 155 | // New instance on every injection 156 | static scope = Scopes.Transient(); 157 | } 158 | 159 | const car = container.inject(Car); 160 | 161 | car.park(); 162 | ``` 163 | 164 | Container-scoped classes usually are [registered in the container](#class-registration) first. Without it, the class will "stick" to the container it's used in. 165 | 166 | ### Resolution scope 167 | 168 | Resolution scope creates a new instance of the class every time, but the instance is the same for the entire resolution: 169 | 170 | ```typescript 171 | import { inject, Scopes } from "dioma"; 172 | 173 | class Query { 174 | static scope = Scopes.Resolution(); 175 | } 176 | 177 | class RequestHandler { 178 | constructor(public query = inject(Query)) {} 179 | 180 | static scope = Scopes.Resolution(); 181 | } 182 | 183 | class RequestUser { 184 | constructor( 185 | public request = inject(RequestHandler), 186 | public query = inject(Query) 187 | ) {} 188 | 189 | static scope = Scopes.Transient(); 190 | } 191 | 192 | const requestUser = inject(RequestUser); 193 | 194 | // The same instance of Query is used for each of them 195 | requestUser.query === requestUser.request.query; 196 | ``` 197 | 198 | Resolution scope instances can be cross-referenced by the [async injection](#async-injection-and-circular-dependencies) without any issues. 199 | 200 | ## Injection with arguments 201 | 202 | You can pass arguments to the constructor when injecting a class: 203 | 204 | ```typescript 205 | import { inject, Scopes } from "dioma"; 206 | 207 | class Owner { 208 | static scope = Scopes.Singleton(); 209 | 210 | petSomebody(pet: Pet) { 211 | console.log(`${pet.name} petted`); 212 | } 213 | } 214 | 215 | class Pet { 216 | constructor(public name: string, public owner = inject(Owner)) {} 217 | 218 | pet() { 219 | this.owner.petSomebody(this); 220 | } 221 | 222 | static scope = Scopes.Transient(); 223 | } 224 | 225 | const pet = inject(Pet, "Fluffy"); 226 | 227 | pet.pet(); // Fluffy petted 228 | ``` 229 | 230 | Only transient and resolution scopes support argument injection. 231 | Resolution scope instances are cached for the entire resolution, so the arguments are passed only once. 232 | 233 | ## Class registration 234 | 235 | By default, `Scopes.Container` class injection is "sticky" - the class sticks to the container where it was first injected. 236 | 237 | If you want to make a class save its instance in some specific parent container (see [Child containers](#Child-containers)), you can use class registration: 238 | 239 | ```typescript 240 | const container = new Container(); 241 | 242 | const child = container.childContainer(); 243 | 244 | class FooBar { 245 | static scope = Scopes.Container(); 246 | } 247 | 248 | // Register the Foo class in the parent container 249 | container.register({ class: FooBar }); 250 | 251 | // Returns and cache the instance on parent container 252 | const foo = container.inject(FooBar); 253 | 254 | // Returns the FooBar instance from the parent container 255 | const bar = child.inject(FooBar); 256 | 257 | foo === bar; // true 258 | ``` 259 | 260 | You can override the scope of the registered class: 261 | 262 | ```typescript 263 | container.register({ class: FooBar, scope: Scopes.Transient() }); 264 | ``` 265 | 266 | To unregister a class, use the `unregister` method: 267 | 268 | ```typescript 269 | container.unregister(FooBar); 270 | ``` 271 | 272 | After that, the class will be removed from the container and all its child containers, and the next injection will return a new instance. 273 | 274 | ## Injection with tokens 275 | 276 | Instead of passing a class to the `inject`, you can use **tokens** instead. 277 | The token injection can be used for **class, value, and factory** injection. 278 | Here's detailed information about each type. 279 | 280 | ### Class tokens 281 | 282 | Class tokens are useful to inject an abstract class or interface that has multiple implementations: 283 | 284 |
285 | 286 | Here is an example of injecting an abstract interface 287 | 288 | ```typescript 289 | import { Token, Scopes, globalContainer } from "dioma"; 290 | 291 | const wild = globalContainer.childContainer("Wild"); 292 | 293 | const zoo = wild.childContainer("Zoo"); 294 | 295 | interface IAnimal { 296 | speak(): void; 297 | } 298 | 299 | class Dog implements IAnimal { 300 | speak() { 301 | console.log("Woof"); 302 | } 303 | 304 | static scope = Scopes.Container(); 305 | } 306 | 307 | class Cat implements IAnimal { 308 | speak() { 309 | console.log("Meow"); 310 | } 311 | 312 | static scope = Scopes.Container(); 313 | } 314 | 315 | const animalToken = new Token("Animal"); 316 | 317 | // Register Dog class with the token 318 | wild.register({ token: animalToken, class: Dog }); 319 | 320 | // Register Cat class with the token 321 | zoo.register({ token: animalToken, class: Cat }); 322 | 323 | // Returns Dog instance 324 | const wildAnimal = wild.inject(animalToken); 325 | 326 | // Returns Cat instance 327 | const zooAnimal = zoo.inject(animalToken); 328 | ``` 329 | 330 |
331 | 332 | The class token registration can also override the scope of the class: 333 | 334 | ```typescript 335 | wild.register({ token: animalToken, class: Dog, scope: Scopes.Transient() }); 336 | ``` 337 | 338 | ### Value tokens 339 | 340 | Value tokens are useful to inject a constant value: 341 | 342 | ```typescript 343 | import { Token } from "dioma"; 344 | 345 | const token = new Token("Value token"); 346 | 347 | container.register({ token, value: "Value" }); 348 | 349 | const value = container.inject(token); 350 | 351 | console.log(value); // Value 352 | ``` 353 | 354 | ### Factory tokens 355 | 356 | Factory tokens are useful to inject a factory function. 357 | The factory takes the current container as the first argument and returns a value: 358 | 359 | ```typescript 360 | import { Token } from "dioma"; 361 | 362 | const token = new Token("Factory token"); 363 | 364 | container.register({ token, factory: (container) => "Value" }); 365 | 366 | const value = container.inject(token); 367 | 368 | console.log(value); // Value 369 | ``` 370 | 371 | Factory function can also take additional arguments: 372 | 373 | ```typescript 374 | const token = new Token("Factory token"); 375 | 376 | container.register({ 377 | token, 378 | factory: (container, a: string, b): string => a + b, 379 | }); 380 | 381 | const value = container.inject(token, "Hello, ", "world!"); 382 | 383 | console.log(value); // Hello, world! 384 | ``` 385 | 386 | As a usual function, a factory can contain any additional logic, conditions, or dependencies. 387 | 388 | ## Child containers 389 | 390 | You can create child containers to isolate the scope of the classes. 391 | Child containers have a hierarchical structure, so Dioma searches instances top-down from the current container to the root container. 392 | If the instance is not found, Dioma will create a new instance in the current container, or in the container where the class was registered. 393 | 394 | Here's an example: 395 | 396 | ```typescript 397 | import { Container, Scopes } from "dioma"; 398 | 399 | const container = new Container(null, "Parent"); 400 | 401 | const child = container.childContainer("Child"); 402 | 403 | class ParentClass { 404 | static scope = Scopes.Container(); 405 | } 406 | 407 | class ChildClass { 408 | static scope = Scopes.Container(); 409 | } 410 | 411 | container.register({ class: ParentClass }); 412 | 413 | child.register({ class: ChildClass }); 414 | 415 | // Returns ParentClass instance from the parent container 416 | const parentInstance = child.inject(ParentClass); 417 | 418 | // Returns ChildClass instance from the child container 419 | const childInstance = child.inject(ChildClass); 420 | ``` 421 | 422 | ## Injection hooks 423 | 424 | When registering a class, you can provide hooks that will be called before the instance is created or injected: 425 | 426 | ```typescript 427 | container.register({ 428 | class: MyClass, 429 | beforeInject: (container, descriptor, args) => { 430 | console.log("Before inject"); 431 | }, 432 | beforeCreate: (container, descriptor, args) => { 433 | console.log("Before create"); 434 | }, 435 | }); 436 | ``` 437 | 438 | ## Async injection and circular dependencies 439 | 440 | When you have a circular dependency, there will be an error `Circular dependency detected`. To solve this problem, you can use async injection. 441 | 442 |
443 | 444 | Here is an example: 445 | 446 | ```typescript 447 | import { inject, injectAsync, Scopes } from "dioma"; 448 | 449 | class A { 450 | constructor(private instanceB = inject(B)) {} 451 | 452 | doWork() { 453 | console.log("doing work A"); 454 | this.instanceB.help(); 455 | } 456 | 457 | static scope = Scopes.Singleton(); 458 | } 459 | 460 | class B { 461 | private declare instanceA: A; 462 | 463 | // injectAsync returns a promise of the A instance 464 | constructor(private promiseA = injectAsync(A)) { 465 | this.promiseA.then((instance) => { 466 | this.instanceA = instance; 467 | }); 468 | } 469 | 470 | help() { 471 | console.log("helping with work"); 472 | } 473 | 474 | doAnotherWork() { 475 | console.log("doing work B"); 476 | this.instanceA.doWork(); 477 | } 478 | 479 | static scope = Scopes.Singleton(); 480 | } 481 | 482 | const a = await injectAsync(A); 483 | const b = await injectAsync(B); 484 | 485 | // Wait until all promises are resolved 486 | await globalContainer.waitAsync(); 487 | 488 | a.doWork(); 489 | b.doAnotherWork(); 490 | ``` 491 | 492 |
493 | 494 | Async injection has an undefined behavior when there is a loop with transient dependencies. It may return an instance with an unexpected loop, or throw the `Circular dependency detected in async resolution` error, so it's better to avoid such cases. 495 | 496 | As defined in the code above, you need to use `container.waitAsync()` or **wait for the next tick** to get all instance promises resolved, even if you use `await injectAsync(...)`. 497 | 498 | Generally, if you expect your dependency to have an async resolution, it's better to inject it with `injectAsync`, as in the example above. But, you can also use `inject` for async injection as long as you wait for it as above. 499 | 500 | Tokens also can be used for async injection as well: 501 | 502 | ```typescript 503 | import { Token, Scopes } from "dioma"; 504 | 505 | const token = new Token("A"); 506 | 507 | class B { 508 | private declare instanceA: A; 509 | 510 | // token in used for async injection 511 | constructor(private promiseA = injectAsync(token)) { 512 | this.promiseA.then((instance) => { 513 | this.instanceA = instance; 514 | }); 515 | } 516 | } 517 | ``` 518 | 519 | ## TypeScript 520 | 521 | Dioma is written in TypeScript and provides type safety out of the box: 522 | 523 | ```typescript 524 | import { inject, Scopes, Injectable } from "dioma"; 525 | 526 | // Injectable interface makes sure the static scope is defined 527 | class Database implements Injectable { 528 | constructor(private url: string) {} 529 | 530 | connect() { 531 | console.log(`Connected to ${this.url}`); 532 | } 533 | 534 | static scope = Scopes.Singleton(); 535 | } 536 | 537 | // Error, scope is not specified 538 | class Repository implements Injectable { 539 | constructor(private db = inject(Database)) {} 540 | } 541 | 542 | inject(Repository); // Also type error, scope is not specified 543 | ``` 544 | 545 | Also, token and class injection infers the output types from the input types. 546 | If available, arguments are also checked and inferred. 547 | 548 | ## API Reference 549 | 550 | ### `new Container(parent?, name?)` 551 | 552 | Creates a new container with the specified parent container and name. 553 | 554 | ### `new Token(name?)` 555 | 556 | Creates a new token with the specified type and name. 557 | 558 | ### `container.inject(classOrToken, ...args)` 559 | 560 | Injects the instance of the class or token, and provides arguments to the constructor or factory function. 561 | 562 | ### `container.injectAsync(classOrToken, ...args)` 563 | 564 | Injects the promise of the instance of the class or token, and provides arguments to the constructor or factory function. 565 | 566 | ### `container.waitAsync()` 567 | 568 | Returns a promise that resolves when all current async injections are resolved. 569 | 570 | ### `container.register({ class, token?, scope? })` 571 | 572 | ### `container.register({ token, value })` 573 | 574 | ### `container.register({ token, factory })` 575 | 576 | Registers the class, value, or factory with the token in the container. 577 | 578 | ### `container.unregister(classOrToken)` 579 | 580 | Unregister the class or token from the container. 581 | 582 | ### `container.childContainer(name?)` 583 | 584 | Creates a new child container with the specified name. 585 | 586 | ### Global exports 587 | 588 | Global container: 589 | 590 | - `globalContainer` - the global container that is used by default for the `inject` function. 591 | - `inject` - the function to inject the instance of the class or token. 592 | - `injectAsync` - the function to inject the promise of the instance of the class or token. 593 | 594 | Errors: 595 | 596 | - `DependencyCycleError` - thrown when a circular dependency is detected. 597 | - `AsyncDependencyCycleError` - thrown when a circular dependency is detected in async resolution. 598 | - `ArgumentsError` - thrown when the arguments are passed to unsupported scopes. 599 | - `TokenNotRegisteredError` - thrown when the token is not registered in the container. 600 | 601 | ## Author 602 | 603 | Eugene Daragan 604 | 605 | ## License 606 | 607 | MIT 608 | -------------------------------------------------------------------------------- /assets/dioma-logo.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zheksoon/dioma/27eae24cfd7b4cc04a5e56ca59e5d7764a42cfad/assets/dioma-logo.webp -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dioma", 3 | "version": "0.3.4", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "dioma", 9 | "version": "0.3.4", 10 | "license": "MIT", 11 | "devDependencies": { 12 | "@vitest/coverage-v8": "^1.4.0", 13 | "vite": "^5.2.7", 14 | "vite-plugin-dts": "^3.8.1", 15 | "vitest": "^1.4.0" 16 | } 17 | }, 18 | "node_modules/@ampproject/remapping": { 19 | "version": "2.3.0", 20 | "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", 21 | "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", 22 | "dev": true, 23 | "dependencies": { 24 | "@jridgewell/gen-mapping": "^0.3.5", 25 | "@jridgewell/trace-mapping": "^0.3.24" 26 | }, 27 | "engines": { 28 | "node": ">=6.0.0" 29 | } 30 | }, 31 | "node_modules/@babel/helper-string-parser": { 32 | "version": "7.24.1", 33 | "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz", 34 | "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==", 35 | "dev": true, 36 | "engines": { 37 | "node": ">=6.9.0" 38 | } 39 | }, 40 | "node_modules/@babel/helper-validator-identifier": { 41 | "version": "7.22.20", 42 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", 43 | "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", 44 | "dev": true, 45 | "engines": { 46 | "node": ">=6.9.0" 47 | } 48 | }, 49 | "node_modules/@babel/parser": { 50 | "version": "7.24.1", 51 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.1.tgz", 52 | "integrity": "sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==", 53 | "dev": true, 54 | "bin": { 55 | "parser": "bin/babel-parser.js" 56 | }, 57 | "engines": { 58 | "node": ">=6.0.0" 59 | } 60 | }, 61 | "node_modules/@babel/types": { 62 | "version": "7.24.0", 63 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", 64 | "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", 65 | "dev": true, 66 | "dependencies": { 67 | "@babel/helper-string-parser": "^7.23.4", 68 | "@babel/helper-validator-identifier": "^7.22.20", 69 | "to-fast-properties": "^2.0.0" 70 | }, 71 | "engines": { 72 | "node": ">=6.9.0" 73 | } 74 | }, 75 | "node_modules/@bcoe/v8-coverage": { 76 | "version": "0.2.3", 77 | "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", 78 | "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", 79 | "dev": true 80 | }, 81 | "node_modules/@esbuild/aix-ppc64": { 82 | "version": "0.20.2", 83 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", 84 | "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", 85 | "cpu": [ 86 | "ppc64" 87 | ], 88 | "dev": true, 89 | "optional": true, 90 | "os": [ 91 | "aix" 92 | ], 93 | "engines": { 94 | "node": ">=12" 95 | } 96 | }, 97 | "node_modules/@esbuild/android-arm": { 98 | "version": "0.20.2", 99 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", 100 | "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", 101 | "cpu": [ 102 | "arm" 103 | ], 104 | "dev": true, 105 | "optional": true, 106 | "os": [ 107 | "android" 108 | ], 109 | "engines": { 110 | "node": ">=12" 111 | } 112 | }, 113 | "node_modules/@esbuild/android-arm64": { 114 | "version": "0.20.2", 115 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", 116 | "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", 117 | "cpu": [ 118 | "arm64" 119 | ], 120 | "dev": true, 121 | "optional": true, 122 | "os": [ 123 | "android" 124 | ], 125 | "engines": { 126 | "node": ">=12" 127 | } 128 | }, 129 | "node_modules/@esbuild/android-x64": { 130 | "version": "0.20.2", 131 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", 132 | "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", 133 | "cpu": [ 134 | "x64" 135 | ], 136 | "dev": true, 137 | "optional": true, 138 | "os": [ 139 | "android" 140 | ], 141 | "engines": { 142 | "node": ">=12" 143 | } 144 | }, 145 | "node_modules/@esbuild/darwin-arm64": { 146 | "version": "0.20.2", 147 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", 148 | "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", 149 | "cpu": [ 150 | "arm64" 151 | ], 152 | "dev": true, 153 | "optional": true, 154 | "os": [ 155 | "darwin" 156 | ], 157 | "engines": { 158 | "node": ">=12" 159 | } 160 | }, 161 | "node_modules/@esbuild/darwin-x64": { 162 | "version": "0.20.2", 163 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", 164 | "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", 165 | "cpu": [ 166 | "x64" 167 | ], 168 | "dev": true, 169 | "optional": true, 170 | "os": [ 171 | "darwin" 172 | ], 173 | "engines": { 174 | "node": ">=12" 175 | } 176 | }, 177 | "node_modules/@esbuild/freebsd-arm64": { 178 | "version": "0.20.2", 179 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", 180 | "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", 181 | "cpu": [ 182 | "arm64" 183 | ], 184 | "dev": true, 185 | "optional": true, 186 | "os": [ 187 | "freebsd" 188 | ], 189 | "engines": { 190 | "node": ">=12" 191 | } 192 | }, 193 | "node_modules/@esbuild/freebsd-x64": { 194 | "version": "0.20.2", 195 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", 196 | "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", 197 | "cpu": [ 198 | "x64" 199 | ], 200 | "dev": true, 201 | "optional": true, 202 | "os": [ 203 | "freebsd" 204 | ], 205 | "engines": { 206 | "node": ">=12" 207 | } 208 | }, 209 | "node_modules/@esbuild/linux-arm": { 210 | "version": "0.20.2", 211 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", 212 | "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", 213 | "cpu": [ 214 | "arm" 215 | ], 216 | "dev": true, 217 | "optional": true, 218 | "os": [ 219 | "linux" 220 | ], 221 | "engines": { 222 | "node": ">=12" 223 | } 224 | }, 225 | "node_modules/@esbuild/linux-arm64": { 226 | "version": "0.20.2", 227 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", 228 | "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", 229 | "cpu": [ 230 | "arm64" 231 | ], 232 | "dev": true, 233 | "optional": true, 234 | "os": [ 235 | "linux" 236 | ], 237 | "engines": { 238 | "node": ">=12" 239 | } 240 | }, 241 | "node_modules/@esbuild/linux-ia32": { 242 | "version": "0.20.2", 243 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", 244 | "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", 245 | "cpu": [ 246 | "ia32" 247 | ], 248 | "dev": true, 249 | "optional": true, 250 | "os": [ 251 | "linux" 252 | ], 253 | "engines": { 254 | "node": ">=12" 255 | } 256 | }, 257 | "node_modules/@esbuild/linux-loong64": { 258 | "version": "0.20.2", 259 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", 260 | "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", 261 | "cpu": [ 262 | "loong64" 263 | ], 264 | "dev": true, 265 | "optional": true, 266 | "os": [ 267 | "linux" 268 | ], 269 | "engines": { 270 | "node": ">=12" 271 | } 272 | }, 273 | "node_modules/@esbuild/linux-mips64el": { 274 | "version": "0.20.2", 275 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", 276 | "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", 277 | "cpu": [ 278 | "mips64el" 279 | ], 280 | "dev": true, 281 | "optional": true, 282 | "os": [ 283 | "linux" 284 | ], 285 | "engines": { 286 | "node": ">=12" 287 | } 288 | }, 289 | "node_modules/@esbuild/linux-ppc64": { 290 | "version": "0.20.2", 291 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", 292 | "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", 293 | "cpu": [ 294 | "ppc64" 295 | ], 296 | "dev": true, 297 | "optional": true, 298 | "os": [ 299 | "linux" 300 | ], 301 | "engines": { 302 | "node": ">=12" 303 | } 304 | }, 305 | "node_modules/@esbuild/linux-riscv64": { 306 | "version": "0.20.2", 307 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", 308 | "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", 309 | "cpu": [ 310 | "riscv64" 311 | ], 312 | "dev": true, 313 | "optional": true, 314 | "os": [ 315 | "linux" 316 | ], 317 | "engines": { 318 | "node": ">=12" 319 | } 320 | }, 321 | "node_modules/@esbuild/linux-s390x": { 322 | "version": "0.20.2", 323 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", 324 | "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", 325 | "cpu": [ 326 | "s390x" 327 | ], 328 | "dev": true, 329 | "optional": true, 330 | "os": [ 331 | "linux" 332 | ], 333 | "engines": { 334 | "node": ">=12" 335 | } 336 | }, 337 | "node_modules/@esbuild/linux-x64": { 338 | "version": "0.20.2", 339 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", 340 | "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", 341 | "cpu": [ 342 | "x64" 343 | ], 344 | "dev": true, 345 | "optional": true, 346 | "os": [ 347 | "linux" 348 | ], 349 | "engines": { 350 | "node": ">=12" 351 | } 352 | }, 353 | "node_modules/@esbuild/netbsd-x64": { 354 | "version": "0.20.2", 355 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", 356 | "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", 357 | "cpu": [ 358 | "x64" 359 | ], 360 | "dev": true, 361 | "optional": true, 362 | "os": [ 363 | "netbsd" 364 | ], 365 | "engines": { 366 | "node": ">=12" 367 | } 368 | }, 369 | "node_modules/@esbuild/openbsd-x64": { 370 | "version": "0.20.2", 371 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", 372 | "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", 373 | "cpu": [ 374 | "x64" 375 | ], 376 | "dev": true, 377 | "optional": true, 378 | "os": [ 379 | "openbsd" 380 | ], 381 | "engines": { 382 | "node": ">=12" 383 | } 384 | }, 385 | "node_modules/@esbuild/sunos-x64": { 386 | "version": "0.20.2", 387 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", 388 | "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", 389 | "cpu": [ 390 | "x64" 391 | ], 392 | "dev": true, 393 | "optional": true, 394 | "os": [ 395 | "sunos" 396 | ], 397 | "engines": { 398 | "node": ">=12" 399 | } 400 | }, 401 | "node_modules/@esbuild/win32-arm64": { 402 | "version": "0.20.2", 403 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", 404 | "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", 405 | "cpu": [ 406 | "arm64" 407 | ], 408 | "dev": true, 409 | "optional": true, 410 | "os": [ 411 | "win32" 412 | ], 413 | "engines": { 414 | "node": ">=12" 415 | } 416 | }, 417 | "node_modules/@esbuild/win32-ia32": { 418 | "version": "0.20.2", 419 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", 420 | "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", 421 | "cpu": [ 422 | "ia32" 423 | ], 424 | "dev": true, 425 | "optional": true, 426 | "os": [ 427 | "win32" 428 | ], 429 | "engines": { 430 | "node": ">=12" 431 | } 432 | }, 433 | "node_modules/@esbuild/win32-x64": { 434 | "version": "0.20.2", 435 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", 436 | "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", 437 | "cpu": [ 438 | "x64" 439 | ], 440 | "dev": true, 441 | "optional": true, 442 | "os": [ 443 | "win32" 444 | ], 445 | "engines": { 446 | "node": ">=12" 447 | } 448 | }, 449 | "node_modules/@istanbuljs/schema": { 450 | "version": "0.1.3", 451 | "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", 452 | "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", 453 | "dev": true, 454 | "engines": { 455 | "node": ">=8" 456 | } 457 | }, 458 | "node_modules/@jest/schemas": { 459 | "version": "29.6.3", 460 | "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", 461 | "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", 462 | "dev": true, 463 | "dependencies": { 464 | "@sinclair/typebox": "^0.27.8" 465 | }, 466 | "engines": { 467 | "node": "^14.15.0 || ^16.10.0 || >=18.0.0" 468 | } 469 | }, 470 | "node_modules/@jridgewell/gen-mapping": { 471 | "version": "0.3.5", 472 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", 473 | "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", 474 | "dev": true, 475 | "dependencies": { 476 | "@jridgewell/set-array": "^1.2.1", 477 | "@jridgewell/sourcemap-codec": "^1.4.10", 478 | "@jridgewell/trace-mapping": "^0.3.24" 479 | }, 480 | "engines": { 481 | "node": ">=6.0.0" 482 | } 483 | }, 484 | "node_modules/@jridgewell/resolve-uri": { 485 | "version": "3.1.2", 486 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", 487 | "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", 488 | "dev": true, 489 | "engines": { 490 | "node": ">=6.0.0" 491 | } 492 | }, 493 | "node_modules/@jridgewell/set-array": { 494 | "version": "1.2.1", 495 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", 496 | "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", 497 | "dev": true, 498 | "engines": { 499 | "node": ">=6.0.0" 500 | } 501 | }, 502 | "node_modules/@jridgewell/sourcemap-codec": { 503 | "version": "1.4.15", 504 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", 505 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", 506 | "dev": true 507 | }, 508 | "node_modules/@jridgewell/trace-mapping": { 509 | "version": "0.3.25", 510 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", 511 | "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", 512 | "dev": true, 513 | "dependencies": { 514 | "@jridgewell/resolve-uri": "^3.1.0", 515 | "@jridgewell/sourcemap-codec": "^1.4.14" 516 | } 517 | }, 518 | "node_modules/@microsoft/api-extractor": { 519 | "version": "7.43.0", 520 | "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.43.0.tgz", 521 | "integrity": "sha512-GFhTcJpB+MI6FhvXEI9b2K0snulNLWHqC/BbcJtyNYcKUiw7l3Lgis5ApsYncJ0leALX7/of4XfmXk+maT111w==", 522 | "dev": true, 523 | "dependencies": { 524 | "@microsoft/api-extractor-model": "7.28.13", 525 | "@microsoft/tsdoc": "0.14.2", 526 | "@microsoft/tsdoc-config": "~0.16.1", 527 | "@rushstack/node-core-library": "4.0.2", 528 | "@rushstack/rig-package": "0.5.2", 529 | "@rushstack/terminal": "0.10.0", 530 | "@rushstack/ts-command-line": "4.19.1", 531 | "lodash": "~4.17.15", 532 | "minimatch": "~3.0.3", 533 | "resolve": "~1.22.1", 534 | "semver": "~7.5.4", 535 | "source-map": "~0.6.1", 536 | "typescript": "5.4.2" 537 | }, 538 | "bin": { 539 | "api-extractor": "bin/api-extractor" 540 | } 541 | }, 542 | "node_modules/@microsoft/api-extractor-model": { 543 | "version": "7.28.13", 544 | "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.13.tgz", 545 | "integrity": "sha512-39v/JyldX4MS9uzHcdfmjjfS6cYGAoXV+io8B5a338pkHiSt+gy2eXQ0Q7cGFJ7quSa1VqqlMdlPrB6sLR/cAw==", 546 | "dev": true, 547 | "dependencies": { 548 | "@microsoft/tsdoc": "0.14.2", 549 | "@microsoft/tsdoc-config": "~0.16.1", 550 | "@rushstack/node-core-library": "4.0.2" 551 | } 552 | }, 553 | "node_modules/@microsoft/api-extractor/node_modules/minimatch": { 554 | "version": "3.0.8", 555 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", 556 | "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", 557 | "dev": true, 558 | "dependencies": { 559 | "brace-expansion": "^1.1.7" 560 | }, 561 | "engines": { 562 | "node": "*" 563 | } 564 | }, 565 | "node_modules/@microsoft/api-extractor/node_modules/semver": { 566 | "version": "7.5.4", 567 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", 568 | "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", 569 | "dev": true, 570 | "dependencies": { 571 | "lru-cache": "^6.0.0" 572 | }, 573 | "bin": { 574 | "semver": "bin/semver.js" 575 | }, 576 | "engines": { 577 | "node": ">=10" 578 | } 579 | }, 580 | "node_modules/@microsoft/tsdoc": { 581 | "version": "0.14.2", 582 | "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz", 583 | "integrity": "sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==", 584 | "dev": true 585 | }, 586 | "node_modules/@microsoft/tsdoc-config": { 587 | "version": "0.16.2", 588 | "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.16.2.tgz", 589 | "integrity": "sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==", 590 | "dev": true, 591 | "dependencies": { 592 | "@microsoft/tsdoc": "0.14.2", 593 | "ajv": "~6.12.6", 594 | "jju": "~1.4.0", 595 | "resolve": "~1.19.0" 596 | } 597 | }, 598 | "node_modules/@microsoft/tsdoc-config/node_modules/resolve": { 599 | "version": "1.19.0", 600 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", 601 | "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", 602 | "dev": true, 603 | "dependencies": { 604 | "is-core-module": "^2.1.0", 605 | "path-parse": "^1.0.6" 606 | }, 607 | "funding": { 608 | "url": "https://github.com/sponsors/ljharb" 609 | } 610 | }, 611 | "node_modules/@nodelib/fs.scandir": { 612 | "version": "2.1.5", 613 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", 614 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", 615 | "dev": true, 616 | "optional": true, 617 | "peer": true, 618 | "dependencies": { 619 | "@nodelib/fs.stat": "2.0.5", 620 | "run-parallel": "^1.1.9" 621 | }, 622 | "engines": { 623 | "node": ">= 8" 624 | } 625 | }, 626 | "node_modules/@nodelib/fs.stat": { 627 | "version": "2.0.5", 628 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", 629 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", 630 | "dev": true, 631 | "optional": true, 632 | "peer": true, 633 | "engines": { 634 | "node": ">= 8" 635 | } 636 | }, 637 | "node_modules/@nodelib/fs.walk": { 638 | "version": "1.2.8", 639 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", 640 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", 641 | "dev": true, 642 | "optional": true, 643 | "peer": true, 644 | "dependencies": { 645 | "@nodelib/fs.scandir": "2.1.5", 646 | "fastq": "^1.6.0" 647 | }, 648 | "engines": { 649 | "node": ">= 8" 650 | } 651 | }, 652 | "node_modules/@polka/url": { 653 | "version": "1.0.0-next.25", 654 | "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.25.tgz", 655 | "integrity": "sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==", 656 | "dev": true, 657 | "optional": true, 658 | "peer": true 659 | }, 660 | "node_modules/@rollup/pluginutils": { 661 | "version": "5.1.0", 662 | "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", 663 | "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", 664 | "dev": true, 665 | "dependencies": { 666 | "@types/estree": "^1.0.0", 667 | "estree-walker": "^2.0.2", 668 | "picomatch": "^2.3.1" 669 | }, 670 | "engines": { 671 | "node": ">=14.0.0" 672 | }, 673 | "peerDependencies": { 674 | "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" 675 | }, 676 | "peerDependenciesMeta": { 677 | "rollup": { 678 | "optional": true 679 | } 680 | } 681 | }, 682 | "node_modules/@rollup/pluginutils/node_modules/estree-walker": { 683 | "version": "2.0.2", 684 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", 685 | "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", 686 | "dev": true 687 | }, 688 | "node_modules/@rollup/rollup-android-arm-eabi": { 689 | "version": "4.13.0", 690 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.0.tgz", 691 | "integrity": "sha512-5ZYPOuaAqEH/W3gYsRkxQATBW3Ii1MfaT4EQstTnLKViLi2gLSQmlmtTpGucNP3sXEpOiI5tdGhjdE111ekyEg==", 692 | "cpu": [ 693 | "arm" 694 | ], 695 | "dev": true, 696 | "optional": true, 697 | "os": [ 698 | "android" 699 | ] 700 | }, 701 | "node_modules/@rollup/rollup-android-arm64": { 702 | "version": "4.13.0", 703 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.13.0.tgz", 704 | "integrity": "sha512-BSbaCmn8ZadK3UAQdlauSvtaJjhlDEjS5hEVVIN3A4bbl3X+otyf/kOJV08bYiRxfejP3DXFzO2jz3G20107+Q==", 705 | "cpu": [ 706 | "arm64" 707 | ], 708 | "dev": true, 709 | "optional": true, 710 | "os": [ 711 | "android" 712 | ] 713 | }, 714 | "node_modules/@rollup/rollup-darwin-arm64": { 715 | "version": "4.13.0", 716 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.13.0.tgz", 717 | "integrity": "sha512-Ovf2evVaP6sW5Ut0GHyUSOqA6tVKfrTHddtmxGQc1CTQa1Cw3/KMCDEEICZBbyppcwnhMwcDce9ZRxdWRpVd6g==", 718 | "cpu": [ 719 | "arm64" 720 | ], 721 | "dev": true, 722 | "optional": true, 723 | "os": [ 724 | "darwin" 725 | ] 726 | }, 727 | "node_modules/@rollup/rollup-darwin-x64": { 728 | "version": "4.13.0", 729 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.13.0.tgz", 730 | "integrity": "sha512-U+Jcxm89UTK592vZ2J9st9ajRv/hrwHdnvyuJpa5A2ngGSVHypigidkQJP+YiGL6JODiUeMzkqQzbCG3At81Gg==", 731 | "cpu": [ 732 | "x64" 733 | ], 734 | "dev": true, 735 | "optional": true, 736 | "os": [ 737 | "darwin" 738 | ] 739 | }, 740 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": { 741 | "version": "4.13.0", 742 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.13.0.tgz", 743 | "integrity": "sha512-8wZidaUJUTIR5T4vRS22VkSMOVooG0F4N+JSwQXWSRiC6yfEsFMLTYRFHvby5mFFuExHa/yAp9juSphQQJAijQ==", 744 | "cpu": [ 745 | "arm" 746 | ], 747 | "dev": true, 748 | "optional": true, 749 | "os": [ 750 | "linux" 751 | ] 752 | }, 753 | "node_modules/@rollup/rollup-linux-arm64-gnu": { 754 | "version": "4.13.0", 755 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.13.0.tgz", 756 | "integrity": "sha512-Iu0Kno1vrD7zHQDxOmvweqLkAzjxEVqNhUIXBsZ8hu8Oak7/5VTPrxOEZXYC1nmrBVJp0ZcL2E7lSuuOVaE3+w==", 757 | "cpu": [ 758 | "arm64" 759 | ], 760 | "dev": true, 761 | "optional": true, 762 | "os": [ 763 | "linux" 764 | ] 765 | }, 766 | "node_modules/@rollup/rollup-linux-arm64-musl": { 767 | "version": "4.13.0", 768 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.13.0.tgz", 769 | "integrity": "sha512-C31QrW47llgVyrRjIwiOwsHFcaIwmkKi3PCroQY5aVq4H0A5v/vVVAtFsI1nfBngtoRpeREvZOkIhmRwUKkAdw==", 770 | "cpu": [ 771 | "arm64" 772 | ], 773 | "dev": true, 774 | "optional": true, 775 | "os": [ 776 | "linux" 777 | ] 778 | }, 779 | "node_modules/@rollup/rollup-linux-riscv64-gnu": { 780 | "version": "4.13.0", 781 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.13.0.tgz", 782 | "integrity": "sha512-Oq90dtMHvthFOPMl7pt7KmxzX7E71AfyIhh+cPhLY9oko97Zf2C9tt/XJD4RgxhaGeAraAXDtqxvKE1y/j35lA==", 783 | "cpu": [ 784 | "riscv64" 785 | ], 786 | "dev": true, 787 | "optional": true, 788 | "os": [ 789 | "linux" 790 | ] 791 | }, 792 | "node_modules/@rollup/rollup-linux-x64-gnu": { 793 | "version": "4.13.0", 794 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.13.0.tgz", 795 | "integrity": "sha512-yUD/8wMffnTKuiIsl6xU+4IA8UNhQ/f1sAnQebmE/lyQ8abjsVyDkyRkWop0kdMhKMprpNIhPmYlCxgHrPoXoA==", 796 | "cpu": [ 797 | "x64" 798 | ], 799 | "dev": true, 800 | "optional": true, 801 | "os": [ 802 | "linux" 803 | ] 804 | }, 805 | "node_modules/@rollup/rollup-linux-x64-musl": { 806 | "version": "4.13.0", 807 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.13.0.tgz", 808 | "integrity": "sha512-9RyNqoFNdF0vu/qqX63fKotBh43fJQeYC98hCaf89DYQpv+xu0D8QFSOS0biA7cGuqJFOc1bJ+m2rhhsKcw1hw==", 809 | "cpu": [ 810 | "x64" 811 | ], 812 | "dev": true, 813 | "optional": true, 814 | "os": [ 815 | "linux" 816 | ] 817 | }, 818 | "node_modules/@rollup/rollup-win32-arm64-msvc": { 819 | "version": "4.13.0", 820 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.13.0.tgz", 821 | "integrity": "sha512-46ue8ymtm/5PUU6pCvjlic0z82qWkxv54GTJZgHrQUuZnVH+tvvSP0LsozIDsCBFO4VjJ13N68wqrKSeScUKdA==", 822 | "cpu": [ 823 | "arm64" 824 | ], 825 | "dev": true, 826 | "optional": true, 827 | "os": [ 828 | "win32" 829 | ] 830 | }, 831 | "node_modules/@rollup/rollup-win32-ia32-msvc": { 832 | "version": "4.13.0", 833 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.13.0.tgz", 834 | "integrity": "sha512-P5/MqLdLSlqxbeuJ3YDeX37srC8mCflSyTrUsgbU1c/U9j6l2g2GiIdYaGD9QjdMQPMSgYm7hgg0551wHyIluw==", 835 | "cpu": [ 836 | "ia32" 837 | ], 838 | "dev": true, 839 | "optional": true, 840 | "os": [ 841 | "win32" 842 | ] 843 | }, 844 | "node_modules/@rollup/rollup-win32-x64-msvc": { 845 | "version": "4.13.0", 846 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.13.0.tgz", 847 | "integrity": "sha512-UKXUQNbO3DOhzLRwHSpa0HnhhCgNODvfoPWv2FCXme8N/ANFfhIPMGuOT+QuKd16+B5yxZ0HdpNlqPvTMS1qfw==", 848 | "cpu": [ 849 | "x64" 850 | ], 851 | "dev": true, 852 | "optional": true, 853 | "os": [ 854 | "win32" 855 | ] 856 | }, 857 | "node_modules/@rushstack/node-core-library": { 858 | "version": "4.0.2", 859 | "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.0.2.tgz", 860 | "integrity": "sha512-hyES82QVpkfQMeBMteQUnrhASL/KHPhd7iJ8euduwNJG4mu2GSOKybf0rOEjOm1Wz7CwJEUm9y0yD7jg2C1bfg==", 861 | "dev": true, 862 | "dependencies": { 863 | "fs-extra": "~7.0.1", 864 | "import-lazy": "~4.0.0", 865 | "jju": "~1.4.0", 866 | "resolve": "~1.22.1", 867 | "semver": "~7.5.4", 868 | "z-schema": "~5.0.2" 869 | }, 870 | "peerDependencies": { 871 | "@types/node": "*" 872 | }, 873 | "peerDependenciesMeta": { 874 | "@types/node": { 875 | "optional": true 876 | } 877 | } 878 | }, 879 | "node_modules/@rushstack/node-core-library/node_modules/semver": { 880 | "version": "7.5.4", 881 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", 882 | "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", 883 | "dev": true, 884 | "dependencies": { 885 | "lru-cache": "^6.0.0" 886 | }, 887 | "bin": { 888 | "semver": "bin/semver.js" 889 | }, 890 | "engines": { 891 | "node": ">=10" 892 | } 893 | }, 894 | "node_modules/@rushstack/rig-package": { 895 | "version": "0.5.2", 896 | "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.2.tgz", 897 | "integrity": "sha512-mUDecIJeH3yYGZs2a48k+pbhM6JYwWlgjs2Ca5f2n1G2/kgdgP9D/07oglEGf6mRyXEnazhEENeYTSNDRCwdqA==", 898 | "dev": true, 899 | "dependencies": { 900 | "resolve": "~1.22.1", 901 | "strip-json-comments": "~3.1.1" 902 | } 903 | }, 904 | "node_modules/@rushstack/terminal": { 905 | "version": "0.10.0", 906 | "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.10.0.tgz", 907 | "integrity": "sha512-UbELbXnUdc7EKwfH2sb8ChqNgapUOdqcCIdQP4NGxBpTZV2sQyeekuK3zmfQSa/MN+/7b4kBogl2wq0vpkpYGw==", 908 | "dev": true, 909 | "dependencies": { 910 | "@rushstack/node-core-library": "4.0.2", 911 | "supports-color": "~8.1.1" 912 | }, 913 | "peerDependencies": { 914 | "@types/node": "*" 915 | }, 916 | "peerDependenciesMeta": { 917 | "@types/node": { 918 | "optional": true 919 | } 920 | } 921 | }, 922 | "node_modules/@rushstack/terminal/node_modules/supports-color": { 923 | "version": "8.1.1", 924 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", 925 | "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", 926 | "dev": true, 927 | "dependencies": { 928 | "has-flag": "^4.0.0" 929 | }, 930 | "engines": { 931 | "node": ">=10" 932 | }, 933 | "funding": { 934 | "url": "https://github.com/chalk/supports-color?sponsor=1" 935 | } 936 | }, 937 | "node_modules/@rushstack/ts-command-line": { 938 | "version": "4.19.1", 939 | "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.19.1.tgz", 940 | "integrity": "sha512-J7H768dgcpG60d7skZ5uSSwyCZs/S2HrWP1Ds8d1qYAyaaeJmpmmLr9BVw97RjFzmQPOYnoXcKA4GkqDCkduQg==", 941 | "dev": true, 942 | "dependencies": { 943 | "@rushstack/terminal": "0.10.0", 944 | "@types/argparse": "1.0.38", 945 | "argparse": "~1.0.9", 946 | "string-argv": "~0.3.1" 947 | } 948 | }, 949 | "node_modules/@sinclair/typebox": { 950 | "version": "0.27.8", 951 | "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", 952 | "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", 953 | "dev": true 954 | }, 955 | "node_modules/@types/argparse": { 956 | "version": "1.0.38", 957 | "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz", 958 | "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==", 959 | "dev": true 960 | }, 961 | "node_modules/@types/estree": { 962 | "version": "1.0.5", 963 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", 964 | "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", 965 | "dev": true 966 | }, 967 | "node_modules/@types/istanbul-lib-coverage": { 968 | "version": "2.0.6", 969 | "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", 970 | "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", 971 | "dev": true 972 | }, 973 | "node_modules/@types/node": { 974 | "version": "20.11.30", 975 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.30.tgz", 976 | "integrity": "sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw==", 977 | "dev": true, 978 | "optional": true, 979 | "peer": true, 980 | "dependencies": { 981 | "undici-types": "~5.26.4" 982 | } 983 | }, 984 | "node_modules/@vitest/coverage-v8": { 985 | "version": "1.4.0", 986 | "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-1.4.0.tgz", 987 | "integrity": "sha512-4hDGyH1SvKpgZnIByr9LhGgCEuF9DKM34IBLCC/fVfy24Z3+PZ+Ii9hsVBsHvY1umM1aGPEjceRkzxCfcQ10wg==", 988 | "dev": true, 989 | "dependencies": { 990 | "@ampproject/remapping": "^2.2.1", 991 | "@bcoe/v8-coverage": "^0.2.3", 992 | "debug": "^4.3.4", 993 | "istanbul-lib-coverage": "^3.2.2", 994 | "istanbul-lib-report": "^3.0.1", 995 | "istanbul-lib-source-maps": "^5.0.4", 996 | "istanbul-reports": "^3.1.6", 997 | "magic-string": "^0.30.5", 998 | "magicast": "^0.3.3", 999 | "picocolors": "^1.0.0", 1000 | "std-env": "^3.5.0", 1001 | "strip-literal": "^2.0.0", 1002 | "test-exclude": "^6.0.0", 1003 | "v8-to-istanbul": "^9.2.0" 1004 | }, 1005 | "funding": { 1006 | "url": "https://opencollective.com/vitest" 1007 | }, 1008 | "peerDependencies": { 1009 | "vitest": "1.4.0" 1010 | } 1011 | }, 1012 | "node_modules/@vitest/expect": { 1013 | "version": "1.4.0", 1014 | "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.4.0.tgz", 1015 | "integrity": "sha512-Jths0sWCJZ8BxjKe+p+eKsoqev1/T8lYcrjavEaz8auEJ4jAVY0GwW3JKmdVU4mmNPLPHixh4GNXP7GFtAiDHA==", 1016 | "dev": true, 1017 | "dependencies": { 1018 | "@vitest/spy": "1.4.0", 1019 | "@vitest/utils": "1.4.0", 1020 | "chai": "^4.3.10" 1021 | }, 1022 | "funding": { 1023 | "url": "https://opencollective.com/vitest" 1024 | } 1025 | }, 1026 | "node_modules/@vitest/runner": { 1027 | "version": "1.4.0", 1028 | "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.4.0.tgz", 1029 | "integrity": "sha512-EDYVSmesqlQ4RD2VvWo3hQgTJ7ZrFQ2VSJdfiJiArkCerDAGeyF1i6dHkmySqk573jLp6d/cfqCN+7wUB5tLgg==", 1030 | "dev": true, 1031 | "dependencies": { 1032 | "@vitest/utils": "1.4.0", 1033 | "p-limit": "^5.0.0", 1034 | "pathe": "^1.1.1" 1035 | }, 1036 | "funding": { 1037 | "url": "https://opencollective.com/vitest" 1038 | } 1039 | }, 1040 | "node_modules/@vitest/snapshot": { 1041 | "version": "1.4.0", 1042 | "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.4.0.tgz", 1043 | "integrity": "sha512-saAFnt5pPIA5qDGxOHxJ/XxhMFKkUSBJmVt5VgDsAqPTX6JP326r5C/c9UuCMPoXNzuudTPsYDZCoJ5ilpqG2A==", 1044 | "dev": true, 1045 | "dependencies": { 1046 | "magic-string": "^0.30.5", 1047 | "pathe": "^1.1.1", 1048 | "pretty-format": "^29.7.0" 1049 | }, 1050 | "funding": { 1051 | "url": "https://opencollective.com/vitest" 1052 | } 1053 | }, 1054 | "node_modules/@vitest/spy": { 1055 | "version": "1.4.0", 1056 | "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.4.0.tgz", 1057 | "integrity": "sha512-Ywau/Qs1DzM/8Uc+yA77CwSegizMlcgTJuYGAi0jujOteJOUf1ujunHThYo243KG9nAyWT3L9ifPYZ5+As/+6Q==", 1058 | "dev": true, 1059 | "dependencies": { 1060 | "tinyspy": "^2.2.0" 1061 | }, 1062 | "funding": { 1063 | "url": "https://opencollective.com/vitest" 1064 | } 1065 | }, 1066 | "node_modules/@vitest/ui": { 1067 | "version": "1.4.0", 1068 | "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-1.4.0.tgz", 1069 | "integrity": "sha512-XC6CMhN1gzYcGbpn6/Oanj4Au2EXwQEX6vpcOeLlZv8dy7g11Ukx8zwtYQbwxs9duK2s9j2o5rbQiCP5DPAcmw==", 1070 | "dev": true, 1071 | "optional": true, 1072 | "peer": true, 1073 | "dependencies": { 1074 | "@vitest/utils": "1.4.0", 1075 | "fast-glob": "^3.3.2", 1076 | "fflate": "^0.8.1", 1077 | "flatted": "^3.2.9", 1078 | "pathe": "^1.1.1", 1079 | "picocolors": "^1.0.0", 1080 | "sirv": "^2.0.4" 1081 | }, 1082 | "funding": { 1083 | "url": "https://opencollective.com/vitest" 1084 | }, 1085 | "peerDependencies": { 1086 | "vitest": "1.4.0" 1087 | } 1088 | }, 1089 | "node_modules/@vitest/utils": { 1090 | "version": "1.4.0", 1091 | "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.4.0.tgz", 1092 | "integrity": "sha512-mx3Yd1/6e2Vt/PUC98DcqTirtfxUyAZ32uK82r8rZzbtBeBo+nqgnjx/LvqQdWsrvNtm14VmurNgcf4nqY5gJg==", 1093 | "dev": true, 1094 | "dependencies": { 1095 | "diff-sequences": "^29.6.3", 1096 | "estree-walker": "^3.0.3", 1097 | "loupe": "^2.3.7", 1098 | "pretty-format": "^29.7.0" 1099 | }, 1100 | "funding": { 1101 | "url": "https://opencollective.com/vitest" 1102 | } 1103 | }, 1104 | "node_modules/@volar/language-core": { 1105 | "version": "1.11.1", 1106 | "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-1.11.1.tgz", 1107 | "integrity": "sha512-dOcNn3i9GgZAcJt43wuaEykSluAuOkQgzni1cuxLxTV0nJKanQztp7FxyswdRILaKH+P2XZMPRp2S4MV/pElCw==", 1108 | "dev": true, 1109 | "dependencies": { 1110 | "@volar/source-map": "1.11.1" 1111 | } 1112 | }, 1113 | "node_modules/@volar/source-map": { 1114 | "version": "1.11.1", 1115 | "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-1.11.1.tgz", 1116 | "integrity": "sha512-hJnOnwZ4+WT5iupLRnuzbULZ42L7BWWPMmruzwtLhJfpDVoZLjNBxHDi2sY2bgZXCKlpU5XcsMFoYrsQmPhfZg==", 1117 | "dev": true, 1118 | "dependencies": { 1119 | "muggle-string": "^0.3.1" 1120 | } 1121 | }, 1122 | "node_modules/@volar/typescript": { 1123 | "version": "1.11.1", 1124 | "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-1.11.1.tgz", 1125 | "integrity": "sha512-iU+t2mas/4lYierSnoFOeRFQUhAEMgsFuQxoxvwn5EdQopw43j+J27a4lt9LMInx1gLJBC6qL14WYGlgymaSMQ==", 1126 | "dev": true, 1127 | "dependencies": { 1128 | "@volar/language-core": "1.11.1", 1129 | "path-browserify": "^1.0.1" 1130 | } 1131 | }, 1132 | "node_modules/@vue/compiler-core": { 1133 | "version": "3.4.21", 1134 | "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.21.tgz", 1135 | "integrity": "sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==", 1136 | "dev": true, 1137 | "dependencies": { 1138 | "@babel/parser": "^7.23.9", 1139 | "@vue/shared": "3.4.21", 1140 | "entities": "^4.5.0", 1141 | "estree-walker": "^2.0.2", 1142 | "source-map-js": "^1.0.2" 1143 | } 1144 | }, 1145 | "node_modules/@vue/compiler-core/node_modules/estree-walker": { 1146 | "version": "2.0.2", 1147 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", 1148 | "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", 1149 | "dev": true 1150 | }, 1151 | "node_modules/@vue/compiler-dom": { 1152 | "version": "3.4.21", 1153 | "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.21.tgz", 1154 | "integrity": "sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==", 1155 | "dev": true, 1156 | "dependencies": { 1157 | "@vue/compiler-core": "3.4.21", 1158 | "@vue/shared": "3.4.21" 1159 | } 1160 | }, 1161 | "node_modules/@vue/language-core": { 1162 | "version": "1.8.27", 1163 | "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-1.8.27.tgz", 1164 | "integrity": "sha512-L8Kc27VdQserNaCUNiSFdDl9LWT24ly8Hpwf1ECy3aFb9m6bDhBGQYOujDm21N7EW3moKIOKEanQwe1q5BK+mA==", 1165 | "dev": true, 1166 | "dependencies": { 1167 | "@volar/language-core": "~1.11.1", 1168 | "@volar/source-map": "~1.11.1", 1169 | "@vue/compiler-dom": "^3.3.0", 1170 | "@vue/shared": "^3.3.0", 1171 | "computeds": "^0.0.1", 1172 | "minimatch": "^9.0.3", 1173 | "muggle-string": "^0.3.1", 1174 | "path-browserify": "^1.0.1", 1175 | "vue-template-compiler": "^2.7.14" 1176 | }, 1177 | "peerDependencies": { 1178 | "typescript": "*" 1179 | }, 1180 | "peerDependenciesMeta": { 1181 | "typescript": { 1182 | "optional": true 1183 | } 1184 | } 1185 | }, 1186 | "node_modules/@vue/language-core/node_modules/brace-expansion": { 1187 | "version": "2.0.1", 1188 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", 1189 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", 1190 | "dev": true, 1191 | "dependencies": { 1192 | "balanced-match": "^1.0.0" 1193 | } 1194 | }, 1195 | "node_modules/@vue/language-core/node_modules/minimatch": { 1196 | "version": "9.0.4", 1197 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", 1198 | "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", 1199 | "dev": true, 1200 | "dependencies": { 1201 | "brace-expansion": "^2.0.1" 1202 | }, 1203 | "engines": { 1204 | "node": ">=16 || 14 >=14.17" 1205 | }, 1206 | "funding": { 1207 | "url": "https://github.com/sponsors/isaacs" 1208 | } 1209 | }, 1210 | "node_modules/@vue/shared": { 1211 | "version": "3.4.21", 1212 | "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.21.tgz", 1213 | "integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==", 1214 | "dev": true 1215 | }, 1216 | "node_modules/acorn": { 1217 | "version": "8.11.3", 1218 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", 1219 | "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", 1220 | "dev": true, 1221 | "bin": { 1222 | "acorn": "bin/acorn" 1223 | }, 1224 | "engines": { 1225 | "node": ">=0.4.0" 1226 | } 1227 | }, 1228 | "node_modules/acorn-walk": { 1229 | "version": "8.3.2", 1230 | "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", 1231 | "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", 1232 | "dev": true, 1233 | "engines": { 1234 | "node": ">=0.4.0" 1235 | } 1236 | }, 1237 | "node_modules/ajv": { 1238 | "version": "6.12.6", 1239 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 1240 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 1241 | "dev": true, 1242 | "dependencies": { 1243 | "fast-deep-equal": "^3.1.1", 1244 | "fast-json-stable-stringify": "^2.0.0", 1245 | "json-schema-traverse": "^0.4.1", 1246 | "uri-js": "^4.2.2" 1247 | }, 1248 | "funding": { 1249 | "type": "github", 1250 | "url": "https://github.com/sponsors/epoberezkin" 1251 | } 1252 | }, 1253 | "node_modules/ansi-styles": { 1254 | "version": "5.2.0", 1255 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", 1256 | "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", 1257 | "dev": true, 1258 | "engines": { 1259 | "node": ">=10" 1260 | }, 1261 | "funding": { 1262 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 1263 | } 1264 | }, 1265 | "node_modules/argparse": { 1266 | "version": "1.0.10", 1267 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 1268 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 1269 | "dev": true, 1270 | "dependencies": { 1271 | "sprintf-js": "~1.0.2" 1272 | } 1273 | }, 1274 | "node_modules/assertion-error": { 1275 | "version": "1.1.0", 1276 | "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", 1277 | "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", 1278 | "dev": true, 1279 | "engines": { 1280 | "node": "*" 1281 | } 1282 | }, 1283 | "node_modules/balanced-match": { 1284 | "version": "1.0.2", 1285 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 1286 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 1287 | "dev": true 1288 | }, 1289 | "node_modules/brace-expansion": { 1290 | "version": "1.1.11", 1291 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 1292 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 1293 | "dev": true, 1294 | "dependencies": { 1295 | "balanced-match": "^1.0.0", 1296 | "concat-map": "0.0.1" 1297 | } 1298 | }, 1299 | "node_modules/braces": { 1300 | "version": "3.0.2", 1301 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 1302 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 1303 | "dev": true, 1304 | "optional": true, 1305 | "peer": true, 1306 | "dependencies": { 1307 | "fill-range": "^7.0.1" 1308 | }, 1309 | "engines": { 1310 | "node": ">=8" 1311 | } 1312 | }, 1313 | "node_modules/cac": { 1314 | "version": "6.7.14", 1315 | "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", 1316 | "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", 1317 | "dev": true, 1318 | "engines": { 1319 | "node": ">=8" 1320 | } 1321 | }, 1322 | "node_modules/chai": { 1323 | "version": "4.4.1", 1324 | "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", 1325 | "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", 1326 | "dev": true, 1327 | "dependencies": { 1328 | "assertion-error": "^1.1.0", 1329 | "check-error": "^1.0.3", 1330 | "deep-eql": "^4.1.3", 1331 | "get-func-name": "^2.0.2", 1332 | "loupe": "^2.3.6", 1333 | "pathval": "^1.1.1", 1334 | "type-detect": "^4.0.8" 1335 | }, 1336 | "engines": { 1337 | "node": ">=4" 1338 | } 1339 | }, 1340 | "node_modules/check-error": { 1341 | "version": "1.0.3", 1342 | "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", 1343 | "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", 1344 | "dev": true, 1345 | "dependencies": { 1346 | "get-func-name": "^2.0.2" 1347 | }, 1348 | "engines": { 1349 | "node": "*" 1350 | } 1351 | }, 1352 | "node_modules/commander": { 1353 | "version": "9.5.0", 1354 | "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", 1355 | "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", 1356 | "dev": true, 1357 | "optional": true, 1358 | "engines": { 1359 | "node": "^12.20.0 || >=14" 1360 | } 1361 | }, 1362 | "node_modules/computeds": { 1363 | "version": "0.0.1", 1364 | "resolved": "https://registry.npmjs.org/computeds/-/computeds-0.0.1.tgz", 1365 | "integrity": "sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==", 1366 | "dev": true 1367 | }, 1368 | "node_modules/concat-map": { 1369 | "version": "0.0.1", 1370 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 1371 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 1372 | "dev": true 1373 | }, 1374 | "node_modules/convert-source-map": { 1375 | "version": "2.0.0", 1376 | "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", 1377 | "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", 1378 | "dev": true 1379 | }, 1380 | "node_modules/cross-spawn": { 1381 | "version": "7.0.3", 1382 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", 1383 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", 1384 | "dev": true, 1385 | "dependencies": { 1386 | "path-key": "^3.1.0", 1387 | "shebang-command": "^2.0.0", 1388 | "which": "^2.0.1" 1389 | }, 1390 | "engines": { 1391 | "node": ">= 8" 1392 | } 1393 | }, 1394 | "node_modules/de-indent": { 1395 | "version": "1.0.2", 1396 | "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", 1397 | "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", 1398 | "dev": true 1399 | }, 1400 | "node_modules/debug": { 1401 | "version": "4.3.4", 1402 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 1403 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 1404 | "dev": true, 1405 | "dependencies": { 1406 | "ms": "2.1.2" 1407 | }, 1408 | "engines": { 1409 | "node": ">=6.0" 1410 | }, 1411 | "peerDependenciesMeta": { 1412 | "supports-color": { 1413 | "optional": true 1414 | } 1415 | } 1416 | }, 1417 | "node_modules/deep-eql": { 1418 | "version": "4.1.3", 1419 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", 1420 | "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", 1421 | "dev": true, 1422 | "dependencies": { 1423 | "type-detect": "^4.0.0" 1424 | }, 1425 | "engines": { 1426 | "node": ">=6" 1427 | } 1428 | }, 1429 | "node_modules/diff-sequences": { 1430 | "version": "29.6.3", 1431 | "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", 1432 | "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", 1433 | "dev": true, 1434 | "engines": { 1435 | "node": "^14.15.0 || ^16.10.0 || >=18.0.0" 1436 | } 1437 | }, 1438 | "node_modules/entities": { 1439 | "version": "4.5.0", 1440 | "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", 1441 | "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", 1442 | "dev": true, 1443 | "engines": { 1444 | "node": ">=0.12" 1445 | }, 1446 | "funding": { 1447 | "url": "https://github.com/fb55/entities?sponsor=1" 1448 | } 1449 | }, 1450 | "node_modules/esbuild": { 1451 | "version": "0.20.2", 1452 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", 1453 | "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", 1454 | "dev": true, 1455 | "hasInstallScript": true, 1456 | "bin": { 1457 | "esbuild": "bin/esbuild" 1458 | }, 1459 | "engines": { 1460 | "node": ">=12" 1461 | }, 1462 | "optionalDependencies": { 1463 | "@esbuild/aix-ppc64": "0.20.2", 1464 | "@esbuild/android-arm": "0.20.2", 1465 | "@esbuild/android-arm64": "0.20.2", 1466 | "@esbuild/android-x64": "0.20.2", 1467 | "@esbuild/darwin-arm64": "0.20.2", 1468 | "@esbuild/darwin-x64": "0.20.2", 1469 | "@esbuild/freebsd-arm64": "0.20.2", 1470 | "@esbuild/freebsd-x64": "0.20.2", 1471 | "@esbuild/linux-arm": "0.20.2", 1472 | "@esbuild/linux-arm64": "0.20.2", 1473 | "@esbuild/linux-ia32": "0.20.2", 1474 | "@esbuild/linux-loong64": "0.20.2", 1475 | "@esbuild/linux-mips64el": "0.20.2", 1476 | "@esbuild/linux-ppc64": "0.20.2", 1477 | "@esbuild/linux-riscv64": "0.20.2", 1478 | "@esbuild/linux-s390x": "0.20.2", 1479 | "@esbuild/linux-x64": "0.20.2", 1480 | "@esbuild/netbsd-x64": "0.20.2", 1481 | "@esbuild/openbsd-x64": "0.20.2", 1482 | "@esbuild/sunos-x64": "0.20.2", 1483 | "@esbuild/win32-arm64": "0.20.2", 1484 | "@esbuild/win32-ia32": "0.20.2", 1485 | "@esbuild/win32-x64": "0.20.2" 1486 | } 1487 | }, 1488 | "node_modules/estree-walker": { 1489 | "version": "3.0.3", 1490 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", 1491 | "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", 1492 | "dev": true, 1493 | "dependencies": { 1494 | "@types/estree": "^1.0.0" 1495 | } 1496 | }, 1497 | "node_modules/execa": { 1498 | "version": "8.0.1", 1499 | "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", 1500 | "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", 1501 | "dev": true, 1502 | "dependencies": { 1503 | "cross-spawn": "^7.0.3", 1504 | "get-stream": "^8.0.1", 1505 | "human-signals": "^5.0.0", 1506 | "is-stream": "^3.0.0", 1507 | "merge-stream": "^2.0.0", 1508 | "npm-run-path": "^5.1.0", 1509 | "onetime": "^6.0.0", 1510 | "signal-exit": "^4.1.0", 1511 | "strip-final-newline": "^3.0.0" 1512 | }, 1513 | "engines": { 1514 | "node": ">=16.17" 1515 | }, 1516 | "funding": { 1517 | "url": "https://github.com/sindresorhus/execa?sponsor=1" 1518 | } 1519 | }, 1520 | "node_modules/fast-deep-equal": { 1521 | "version": "3.1.3", 1522 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 1523 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 1524 | "dev": true 1525 | }, 1526 | "node_modules/fast-glob": { 1527 | "version": "3.3.2", 1528 | "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", 1529 | "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", 1530 | "dev": true, 1531 | "optional": true, 1532 | "peer": true, 1533 | "dependencies": { 1534 | "@nodelib/fs.stat": "^2.0.2", 1535 | "@nodelib/fs.walk": "^1.2.3", 1536 | "glob-parent": "^5.1.2", 1537 | "merge2": "^1.3.0", 1538 | "micromatch": "^4.0.4" 1539 | }, 1540 | "engines": { 1541 | "node": ">=8.6.0" 1542 | } 1543 | }, 1544 | "node_modules/fast-json-stable-stringify": { 1545 | "version": "2.1.0", 1546 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 1547 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 1548 | "dev": true 1549 | }, 1550 | "node_modules/fastq": { 1551 | "version": "1.17.1", 1552 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", 1553 | "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", 1554 | "dev": true, 1555 | "optional": true, 1556 | "peer": true, 1557 | "dependencies": { 1558 | "reusify": "^1.0.4" 1559 | } 1560 | }, 1561 | "node_modules/fflate": { 1562 | "version": "0.8.2", 1563 | "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", 1564 | "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", 1565 | "dev": true, 1566 | "optional": true, 1567 | "peer": true 1568 | }, 1569 | "node_modules/fill-range": { 1570 | "version": "7.0.1", 1571 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 1572 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 1573 | "dev": true, 1574 | "optional": true, 1575 | "peer": true, 1576 | "dependencies": { 1577 | "to-regex-range": "^5.0.1" 1578 | }, 1579 | "engines": { 1580 | "node": ">=8" 1581 | } 1582 | }, 1583 | "node_modules/flatted": { 1584 | "version": "3.3.1", 1585 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", 1586 | "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", 1587 | "dev": true, 1588 | "optional": true, 1589 | "peer": true 1590 | }, 1591 | "node_modules/fs-extra": { 1592 | "version": "7.0.1", 1593 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", 1594 | "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", 1595 | "dev": true, 1596 | "dependencies": { 1597 | "graceful-fs": "^4.1.2", 1598 | "jsonfile": "^4.0.0", 1599 | "universalify": "^0.1.0" 1600 | }, 1601 | "engines": { 1602 | "node": ">=6 <7 || >=8" 1603 | } 1604 | }, 1605 | "node_modules/fs.realpath": { 1606 | "version": "1.0.0", 1607 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 1608 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", 1609 | "dev": true 1610 | }, 1611 | "node_modules/fsevents": { 1612 | "version": "2.3.3", 1613 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 1614 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 1615 | "dev": true, 1616 | "hasInstallScript": true, 1617 | "optional": true, 1618 | "os": [ 1619 | "darwin" 1620 | ], 1621 | "engines": { 1622 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 1623 | } 1624 | }, 1625 | "node_modules/function-bind": { 1626 | "version": "1.1.2", 1627 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 1628 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 1629 | "dev": true, 1630 | "funding": { 1631 | "url": "https://github.com/sponsors/ljharb" 1632 | } 1633 | }, 1634 | "node_modules/get-func-name": { 1635 | "version": "2.0.2", 1636 | "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", 1637 | "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", 1638 | "dev": true, 1639 | "engines": { 1640 | "node": "*" 1641 | } 1642 | }, 1643 | "node_modules/get-stream": { 1644 | "version": "8.0.1", 1645 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", 1646 | "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", 1647 | "dev": true, 1648 | "engines": { 1649 | "node": ">=16" 1650 | }, 1651 | "funding": { 1652 | "url": "https://github.com/sponsors/sindresorhus" 1653 | } 1654 | }, 1655 | "node_modules/glob": { 1656 | "version": "7.2.3", 1657 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", 1658 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", 1659 | "dev": true, 1660 | "dependencies": { 1661 | "fs.realpath": "^1.0.0", 1662 | "inflight": "^1.0.4", 1663 | "inherits": "2", 1664 | "minimatch": "^3.1.1", 1665 | "once": "^1.3.0", 1666 | "path-is-absolute": "^1.0.0" 1667 | }, 1668 | "engines": { 1669 | "node": "*" 1670 | }, 1671 | "funding": { 1672 | "url": "https://github.com/sponsors/isaacs" 1673 | } 1674 | }, 1675 | "node_modules/glob-parent": { 1676 | "version": "5.1.2", 1677 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 1678 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 1679 | "dev": true, 1680 | "optional": true, 1681 | "peer": true, 1682 | "dependencies": { 1683 | "is-glob": "^4.0.1" 1684 | }, 1685 | "engines": { 1686 | "node": ">= 6" 1687 | } 1688 | }, 1689 | "node_modules/graceful-fs": { 1690 | "version": "4.2.11", 1691 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", 1692 | "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", 1693 | "dev": true 1694 | }, 1695 | "node_modules/has-flag": { 1696 | "version": "4.0.0", 1697 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 1698 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 1699 | "dev": true, 1700 | "engines": { 1701 | "node": ">=8" 1702 | } 1703 | }, 1704 | "node_modules/hasown": { 1705 | "version": "2.0.2", 1706 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", 1707 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 1708 | "dev": true, 1709 | "dependencies": { 1710 | "function-bind": "^1.1.2" 1711 | }, 1712 | "engines": { 1713 | "node": ">= 0.4" 1714 | } 1715 | }, 1716 | "node_modules/he": { 1717 | "version": "1.2.0", 1718 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", 1719 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", 1720 | "dev": true, 1721 | "bin": { 1722 | "he": "bin/he" 1723 | } 1724 | }, 1725 | "node_modules/html-escaper": { 1726 | "version": "2.0.2", 1727 | "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", 1728 | "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", 1729 | "dev": true 1730 | }, 1731 | "node_modules/human-signals": { 1732 | "version": "5.0.0", 1733 | "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", 1734 | "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", 1735 | "dev": true, 1736 | "engines": { 1737 | "node": ">=16.17.0" 1738 | } 1739 | }, 1740 | "node_modules/import-lazy": { 1741 | "version": "4.0.0", 1742 | "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", 1743 | "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", 1744 | "dev": true, 1745 | "engines": { 1746 | "node": ">=8" 1747 | } 1748 | }, 1749 | "node_modules/inflight": { 1750 | "version": "1.0.6", 1751 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 1752 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 1753 | "dev": true, 1754 | "dependencies": { 1755 | "once": "^1.3.0", 1756 | "wrappy": "1" 1757 | } 1758 | }, 1759 | "node_modules/inherits": { 1760 | "version": "2.0.4", 1761 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1762 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 1763 | "dev": true 1764 | }, 1765 | "node_modules/is-core-module": { 1766 | "version": "2.13.1", 1767 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", 1768 | "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", 1769 | "dev": true, 1770 | "dependencies": { 1771 | "hasown": "^2.0.0" 1772 | }, 1773 | "funding": { 1774 | "url": "https://github.com/sponsors/ljharb" 1775 | } 1776 | }, 1777 | "node_modules/is-extglob": { 1778 | "version": "2.1.1", 1779 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 1780 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 1781 | "dev": true, 1782 | "optional": true, 1783 | "peer": true, 1784 | "engines": { 1785 | "node": ">=0.10.0" 1786 | } 1787 | }, 1788 | "node_modules/is-glob": { 1789 | "version": "4.0.3", 1790 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 1791 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 1792 | "dev": true, 1793 | "optional": true, 1794 | "peer": true, 1795 | "dependencies": { 1796 | "is-extglob": "^2.1.1" 1797 | }, 1798 | "engines": { 1799 | "node": ">=0.10.0" 1800 | } 1801 | }, 1802 | "node_modules/is-number": { 1803 | "version": "7.0.0", 1804 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 1805 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 1806 | "dev": true, 1807 | "optional": true, 1808 | "peer": true, 1809 | "engines": { 1810 | "node": ">=0.12.0" 1811 | } 1812 | }, 1813 | "node_modules/is-stream": { 1814 | "version": "3.0.0", 1815 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", 1816 | "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", 1817 | "dev": true, 1818 | "engines": { 1819 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0" 1820 | }, 1821 | "funding": { 1822 | "url": "https://github.com/sponsors/sindresorhus" 1823 | } 1824 | }, 1825 | "node_modules/isexe": { 1826 | "version": "2.0.0", 1827 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1828 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 1829 | "dev": true 1830 | }, 1831 | "node_modules/istanbul-lib-coverage": { 1832 | "version": "3.2.2", 1833 | "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", 1834 | "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", 1835 | "dev": true, 1836 | "engines": { 1837 | "node": ">=8" 1838 | } 1839 | }, 1840 | "node_modules/istanbul-lib-report": { 1841 | "version": "3.0.1", 1842 | "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", 1843 | "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", 1844 | "dev": true, 1845 | "dependencies": { 1846 | "istanbul-lib-coverage": "^3.0.0", 1847 | "make-dir": "^4.0.0", 1848 | "supports-color": "^7.1.0" 1849 | }, 1850 | "engines": { 1851 | "node": ">=10" 1852 | } 1853 | }, 1854 | "node_modules/istanbul-lib-source-maps": { 1855 | "version": "5.0.4", 1856 | "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.4.tgz", 1857 | "integrity": "sha512-wHOoEsNJTVltaJp8eVkm8w+GVkVNHT2YDYo53YdzQEL2gWm1hBX5cGFR9hQJtuGLebidVX7et3+dmDZrmclduw==", 1858 | "dev": true, 1859 | "dependencies": { 1860 | "@jridgewell/trace-mapping": "^0.3.23", 1861 | "debug": "^4.1.1", 1862 | "istanbul-lib-coverage": "^3.0.0" 1863 | }, 1864 | "engines": { 1865 | "node": ">=10" 1866 | } 1867 | }, 1868 | "node_modules/istanbul-reports": { 1869 | "version": "3.1.7", 1870 | "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", 1871 | "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", 1872 | "dev": true, 1873 | "dependencies": { 1874 | "html-escaper": "^2.0.0", 1875 | "istanbul-lib-report": "^3.0.0" 1876 | }, 1877 | "engines": { 1878 | "node": ">=8" 1879 | } 1880 | }, 1881 | "node_modules/jju": { 1882 | "version": "1.4.0", 1883 | "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", 1884 | "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==", 1885 | "dev": true 1886 | }, 1887 | "node_modules/js-tokens": { 1888 | "version": "8.0.3", 1889 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-8.0.3.tgz", 1890 | "integrity": "sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==", 1891 | "dev": true 1892 | }, 1893 | "node_modules/json-schema-traverse": { 1894 | "version": "0.4.1", 1895 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 1896 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 1897 | "dev": true 1898 | }, 1899 | "node_modules/jsonc-parser": { 1900 | "version": "3.2.1", 1901 | "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", 1902 | "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", 1903 | "dev": true 1904 | }, 1905 | "node_modules/jsonfile": { 1906 | "version": "4.0.0", 1907 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", 1908 | "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", 1909 | "dev": true, 1910 | "optionalDependencies": { 1911 | "graceful-fs": "^4.1.6" 1912 | } 1913 | }, 1914 | "node_modules/kolorist": { 1915 | "version": "1.8.0", 1916 | "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", 1917 | "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", 1918 | "dev": true 1919 | }, 1920 | "node_modules/local-pkg": { 1921 | "version": "0.5.0", 1922 | "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", 1923 | "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", 1924 | "dev": true, 1925 | "dependencies": { 1926 | "mlly": "^1.4.2", 1927 | "pkg-types": "^1.0.3" 1928 | }, 1929 | "engines": { 1930 | "node": ">=14" 1931 | }, 1932 | "funding": { 1933 | "url": "https://github.com/sponsors/antfu" 1934 | } 1935 | }, 1936 | "node_modules/lodash": { 1937 | "version": "4.17.21", 1938 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 1939 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", 1940 | "dev": true 1941 | }, 1942 | "node_modules/lodash.get": { 1943 | "version": "4.4.2", 1944 | "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", 1945 | "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", 1946 | "dev": true 1947 | }, 1948 | "node_modules/lodash.isequal": { 1949 | "version": "4.5.0", 1950 | "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", 1951 | "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", 1952 | "dev": true 1953 | }, 1954 | "node_modules/loupe": { 1955 | "version": "2.3.7", 1956 | "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", 1957 | "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", 1958 | "dev": true, 1959 | "dependencies": { 1960 | "get-func-name": "^2.0.1" 1961 | } 1962 | }, 1963 | "node_modules/lru-cache": { 1964 | "version": "6.0.0", 1965 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 1966 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 1967 | "dev": true, 1968 | "dependencies": { 1969 | "yallist": "^4.0.0" 1970 | }, 1971 | "engines": { 1972 | "node": ">=10" 1973 | } 1974 | }, 1975 | "node_modules/magic-string": { 1976 | "version": "0.30.8", 1977 | "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", 1978 | "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", 1979 | "dev": true, 1980 | "dependencies": { 1981 | "@jridgewell/sourcemap-codec": "^1.4.15" 1982 | }, 1983 | "engines": { 1984 | "node": ">=12" 1985 | } 1986 | }, 1987 | "node_modules/magicast": { 1988 | "version": "0.3.3", 1989 | "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.3.tgz", 1990 | "integrity": "sha512-ZbrP1Qxnpoes8sz47AM0z08U+jW6TyRgZzcWy3Ma3vDhJttwMwAFDMMQFobwdBxByBD46JYmxRzeF7w2+wJEuw==", 1991 | "dev": true, 1992 | "dependencies": { 1993 | "@babel/parser": "^7.23.6", 1994 | "@babel/types": "^7.23.6", 1995 | "source-map-js": "^1.0.2" 1996 | } 1997 | }, 1998 | "node_modules/make-dir": { 1999 | "version": "4.0.0", 2000 | "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", 2001 | "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", 2002 | "dev": true, 2003 | "dependencies": { 2004 | "semver": "^7.5.3" 2005 | }, 2006 | "engines": { 2007 | "node": ">=10" 2008 | }, 2009 | "funding": { 2010 | "url": "https://github.com/sponsors/sindresorhus" 2011 | } 2012 | }, 2013 | "node_modules/merge-stream": { 2014 | "version": "2.0.0", 2015 | "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", 2016 | "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", 2017 | "dev": true 2018 | }, 2019 | "node_modules/merge2": { 2020 | "version": "1.4.1", 2021 | "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", 2022 | "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", 2023 | "dev": true, 2024 | "optional": true, 2025 | "peer": true, 2026 | "engines": { 2027 | "node": ">= 8" 2028 | } 2029 | }, 2030 | "node_modules/micromatch": { 2031 | "version": "4.0.5", 2032 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", 2033 | "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", 2034 | "dev": true, 2035 | "optional": true, 2036 | "peer": true, 2037 | "dependencies": { 2038 | "braces": "^3.0.2", 2039 | "picomatch": "^2.3.1" 2040 | }, 2041 | "engines": { 2042 | "node": ">=8.6" 2043 | } 2044 | }, 2045 | "node_modules/mimic-fn": { 2046 | "version": "4.0.0", 2047 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", 2048 | "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", 2049 | "dev": true, 2050 | "engines": { 2051 | "node": ">=12" 2052 | }, 2053 | "funding": { 2054 | "url": "https://github.com/sponsors/sindresorhus" 2055 | } 2056 | }, 2057 | "node_modules/minimatch": { 2058 | "version": "3.1.2", 2059 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 2060 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 2061 | "dev": true, 2062 | "dependencies": { 2063 | "brace-expansion": "^1.1.7" 2064 | }, 2065 | "engines": { 2066 | "node": "*" 2067 | } 2068 | }, 2069 | "node_modules/mlly": { 2070 | "version": "1.6.1", 2071 | "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.6.1.tgz", 2072 | "integrity": "sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==", 2073 | "dev": true, 2074 | "dependencies": { 2075 | "acorn": "^8.11.3", 2076 | "pathe": "^1.1.2", 2077 | "pkg-types": "^1.0.3", 2078 | "ufo": "^1.3.2" 2079 | } 2080 | }, 2081 | "node_modules/mrmime": { 2082 | "version": "2.0.0", 2083 | "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", 2084 | "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", 2085 | "dev": true, 2086 | "optional": true, 2087 | "peer": true, 2088 | "engines": { 2089 | "node": ">=10" 2090 | } 2091 | }, 2092 | "node_modules/ms": { 2093 | "version": "2.1.2", 2094 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 2095 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 2096 | "dev": true 2097 | }, 2098 | "node_modules/muggle-string": { 2099 | "version": "0.3.1", 2100 | "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.3.1.tgz", 2101 | "integrity": "sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==", 2102 | "dev": true 2103 | }, 2104 | "node_modules/nanoid": { 2105 | "version": "3.3.7", 2106 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", 2107 | "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", 2108 | "dev": true, 2109 | "funding": [ 2110 | { 2111 | "type": "github", 2112 | "url": "https://github.com/sponsors/ai" 2113 | } 2114 | ], 2115 | "bin": { 2116 | "nanoid": "bin/nanoid.cjs" 2117 | }, 2118 | "engines": { 2119 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 2120 | } 2121 | }, 2122 | "node_modules/npm-run-path": { 2123 | "version": "5.3.0", 2124 | "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", 2125 | "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", 2126 | "dev": true, 2127 | "dependencies": { 2128 | "path-key": "^4.0.0" 2129 | }, 2130 | "engines": { 2131 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0" 2132 | }, 2133 | "funding": { 2134 | "url": "https://github.com/sponsors/sindresorhus" 2135 | } 2136 | }, 2137 | "node_modules/npm-run-path/node_modules/path-key": { 2138 | "version": "4.0.0", 2139 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", 2140 | "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", 2141 | "dev": true, 2142 | "engines": { 2143 | "node": ">=12" 2144 | }, 2145 | "funding": { 2146 | "url": "https://github.com/sponsors/sindresorhus" 2147 | } 2148 | }, 2149 | "node_modules/once": { 2150 | "version": "1.4.0", 2151 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 2152 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 2153 | "dev": true, 2154 | "dependencies": { 2155 | "wrappy": "1" 2156 | } 2157 | }, 2158 | "node_modules/onetime": { 2159 | "version": "6.0.0", 2160 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", 2161 | "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", 2162 | "dev": true, 2163 | "dependencies": { 2164 | "mimic-fn": "^4.0.0" 2165 | }, 2166 | "engines": { 2167 | "node": ">=12" 2168 | }, 2169 | "funding": { 2170 | "url": "https://github.com/sponsors/sindresorhus" 2171 | } 2172 | }, 2173 | "node_modules/p-limit": { 2174 | "version": "5.0.0", 2175 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", 2176 | "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", 2177 | "dev": true, 2178 | "dependencies": { 2179 | "yocto-queue": "^1.0.0" 2180 | }, 2181 | "engines": { 2182 | "node": ">=18" 2183 | }, 2184 | "funding": { 2185 | "url": "https://github.com/sponsors/sindresorhus" 2186 | } 2187 | }, 2188 | "node_modules/path-browserify": { 2189 | "version": "1.0.1", 2190 | "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", 2191 | "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", 2192 | "dev": true 2193 | }, 2194 | "node_modules/path-is-absolute": { 2195 | "version": "1.0.1", 2196 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 2197 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 2198 | "dev": true, 2199 | "engines": { 2200 | "node": ">=0.10.0" 2201 | } 2202 | }, 2203 | "node_modules/path-key": { 2204 | "version": "3.1.1", 2205 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 2206 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 2207 | "dev": true, 2208 | "engines": { 2209 | "node": ">=8" 2210 | } 2211 | }, 2212 | "node_modules/path-parse": { 2213 | "version": "1.0.7", 2214 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 2215 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", 2216 | "dev": true 2217 | }, 2218 | "node_modules/pathe": { 2219 | "version": "1.1.2", 2220 | "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", 2221 | "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", 2222 | "dev": true 2223 | }, 2224 | "node_modules/pathval": { 2225 | "version": "1.1.1", 2226 | "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", 2227 | "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", 2228 | "dev": true, 2229 | "engines": { 2230 | "node": "*" 2231 | } 2232 | }, 2233 | "node_modules/picocolors": { 2234 | "version": "1.0.0", 2235 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", 2236 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", 2237 | "dev": true 2238 | }, 2239 | "node_modules/picomatch": { 2240 | "version": "2.3.1", 2241 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 2242 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 2243 | "dev": true, 2244 | "engines": { 2245 | "node": ">=8.6" 2246 | }, 2247 | "funding": { 2248 | "url": "https://github.com/sponsors/jonschlinkert" 2249 | } 2250 | }, 2251 | "node_modules/pkg-types": { 2252 | "version": "1.0.3", 2253 | "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.3.tgz", 2254 | "integrity": "sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==", 2255 | "dev": true, 2256 | "dependencies": { 2257 | "jsonc-parser": "^3.2.0", 2258 | "mlly": "^1.2.0", 2259 | "pathe": "^1.1.0" 2260 | } 2261 | }, 2262 | "node_modules/postcss": { 2263 | "version": "8.4.38", 2264 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", 2265 | "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", 2266 | "dev": true, 2267 | "funding": [ 2268 | { 2269 | "type": "opencollective", 2270 | "url": "https://opencollective.com/postcss/" 2271 | }, 2272 | { 2273 | "type": "tidelift", 2274 | "url": "https://tidelift.com/funding/github/npm/postcss" 2275 | }, 2276 | { 2277 | "type": "github", 2278 | "url": "https://github.com/sponsors/ai" 2279 | } 2280 | ], 2281 | "dependencies": { 2282 | "nanoid": "^3.3.7", 2283 | "picocolors": "^1.0.0", 2284 | "source-map-js": "^1.2.0" 2285 | }, 2286 | "engines": { 2287 | "node": "^10 || ^12 || >=14" 2288 | } 2289 | }, 2290 | "node_modules/pretty-format": { 2291 | "version": "29.7.0", 2292 | "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", 2293 | "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", 2294 | "dev": true, 2295 | "dependencies": { 2296 | "@jest/schemas": "^29.6.3", 2297 | "ansi-styles": "^5.0.0", 2298 | "react-is": "^18.0.0" 2299 | }, 2300 | "engines": { 2301 | "node": "^14.15.0 || ^16.10.0 || >=18.0.0" 2302 | } 2303 | }, 2304 | "node_modules/punycode": { 2305 | "version": "2.3.1", 2306 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 2307 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 2308 | "dev": true, 2309 | "engines": { 2310 | "node": ">=6" 2311 | } 2312 | }, 2313 | "node_modules/queue-microtask": { 2314 | "version": "1.2.3", 2315 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", 2316 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", 2317 | "dev": true, 2318 | "funding": [ 2319 | { 2320 | "type": "github", 2321 | "url": "https://github.com/sponsors/feross" 2322 | }, 2323 | { 2324 | "type": "patreon", 2325 | "url": "https://www.patreon.com/feross" 2326 | }, 2327 | { 2328 | "type": "consulting", 2329 | "url": "https://feross.org/support" 2330 | } 2331 | ], 2332 | "optional": true, 2333 | "peer": true 2334 | }, 2335 | "node_modules/react-is": { 2336 | "version": "18.2.0", 2337 | "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", 2338 | "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", 2339 | "dev": true 2340 | }, 2341 | "node_modules/resolve": { 2342 | "version": "1.22.8", 2343 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", 2344 | "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", 2345 | "dev": true, 2346 | "dependencies": { 2347 | "is-core-module": "^2.13.0", 2348 | "path-parse": "^1.0.7", 2349 | "supports-preserve-symlinks-flag": "^1.0.0" 2350 | }, 2351 | "bin": { 2352 | "resolve": "bin/resolve" 2353 | }, 2354 | "funding": { 2355 | "url": "https://github.com/sponsors/ljharb" 2356 | } 2357 | }, 2358 | "node_modules/reusify": { 2359 | "version": "1.0.4", 2360 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", 2361 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", 2362 | "dev": true, 2363 | "optional": true, 2364 | "peer": true, 2365 | "engines": { 2366 | "iojs": ">=1.0.0", 2367 | "node": ">=0.10.0" 2368 | } 2369 | }, 2370 | "node_modules/rollup": { 2371 | "version": "4.13.0", 2372 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.13.0.tgz", 2373 | "integrity": "sha512-3YegKemjoQnYKmsBlOHfMLVPPA5xLkQ8MHLLSw/fBrFaVkEayL51DilPpNNLq1exr98F2B1TzrV0FUlN3gWRPg==", 2374 | "dev": true, 2375 | "dependencies": { 2376 | "@types/estree": "1.0.5" 2377 | }, 2378 | "bin": { 2379 | "rollup": "dist/bin/rollup" 2380 | }, 2381 | "engines": { 2382 | "node": ">=18.0.0", 2383 | "npm": ">=8.0.0" 2384 | }, 2385 | "optionalDependencies": { 2386 | "@rollup/rollup-android-arm-eabi": "4.13.0", 2387 | "@rollup/rollup-android-arm64": "4.13.0", 2388 | "@rollup/rollup-darwin-arm64": "4.13.0", 2389 | "@rollup/rollup-darwin-x64": "4.13.0", 2390 | "@rollup/rollup-linux-arm-gnueabihf": "4.13.0", 2391 | "@rollup/rollup-linux-arm64-gnu": "4.13.0", 2392 | "@rollup/rollup-linux-arm64-musl": "4.13.0", 2393 | "@rollup/rollup-linux-riscv64-gnu": "4.13.0", 2394 | "@rollup/rollup-linux-x64-gnu": "4.13.0", 2395 | "@rollup/rollup-linux-x64-musl": "4.13.0", 2396 | "@rollup/rollup-win32-arm64-msvc": "4.13.0", 2397 | "@rollup/rollup-win32-ia32-msvc": "4.13.0", 2398 | "@rollup/rollup-win32-x64-msvc": "4.13.0", 2399 | "fsevents": "~2.3.2" 2400 | } 2401 | }, 2402 | "node_modules/run-parallel": { 2403 | "version": "1.2.0", 2404 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", 2405 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", 2406 | "dev": true, 2407 | "funding": [ 2408 | { 2409 | "type": "github", 2410 | "url": "https://github.com/sponsors/feross" 2411 | }, 2412 | { 2413 | "type": "patreon", 2414 | "url": "https://www.patreon.com/feross" 2415 | }, 2416 | { 2417 | "type": "consulting", 2418 | "url": "https://feross.org/support" 2419 | } 2420 | ], 2421 | "optional": true, 2422 | "peer": true, 2423 | "dependencies": { 2424 | "queue-microtask": "^1.2.2" 2425 | } 2426 | }, 2427 | "node_modules/semver": { 2428 | "version": "7.6.0", 2429 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", 2430 | "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", 2431 | "dev": true, 2432 | "dependencies": { 2433 | "lru-cache": "^6.0.0" 2434 | }, 2435 | "bin": { 2436 | "semver": "bin/semver.js" 2437 | }, 2438 | "engines": { 2439 | "node": ">=10" 2440 | } 2441 | }, 2442 | "node_modules/shebang-command": { 2443 | "version": "2.0.0", 2444 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 2445 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 2446 | "dev": true, 2447 | "dependencies": { 2448 | "shebang-regex": "^3.0.0" 2449 | }, 2450 | "engines": { 2451 | "node": ">=8" 2452 | } 2453 | }, 2454 | "node_modules/shebang-regex": { 2455 | "version": "3.0.0", 2456 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 2457 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 2458 | "dev": true, 2459 | "engines": { 2460 | "node": ">=8" 2461 | } 2462 | }, 2463 | "node_modules/siginfo": { 2464 | "version": "2.0.0", 2465 | "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", 2466 | "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", 2467 | "dev": true 2468 | }, 2469 | "node_modules/signal-exit": { 2470 | "version": "4.1.0", 2471 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", 2472 | "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", 2473 | "dev": true, 2474 | "engines": { 2475 | "node": ">=14" 2476 | }, 2477 | "funding": { 2478 | "url": "https://github.com/sponsors/isaacs" 2479 | } 2480 | }, 2481 | "node_modules/sirv": { 2482 | "version": "2.0.4", 2483 | "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", 2484 | "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", 2485 | "dev": true, 2486 | "optional": true, 2487 | "peer": true, 2488 | "dependencies": { 2489 | "@polka/url": "^1.0.0-next.24", 2490 | "mrmime": "^2.0.0", 2491 | "totalist": "^3.0.0" 2492 | }, 2493 | "engines": { 2494 | "node": ">= 10" 2495 | } 2496 | }, 2497 | "node_modules/source-map": { 2498 | "version": "0.6.1", 2499 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 2500 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 2501 | "dev": true, 2502 | "engines": { 2503 | "node": ">=0.10.0" 2504 | } 2505 | }, 2506 | "node_modules/source-map-js": { 2507 | "version": "1.2.0", 2508 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", 2509 | "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", 2510 | "dev": true, 2511 | "engines": { 2512 | "node": ">=0.10.0" 2513 | } 2514 | }, 2515 | "node_modules/sprintf-js": { 2516 | "version": "1.0.3", 2517 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 2518 | "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", 2519 | "dev": true 2520 | }, 2521 | "node_modules/stackback": { 2522 | "version": "0.0.2", 2523 | "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", 2524 | "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", 2525 | "dev": true 2526 | }, 2527 | "node_modules/std-env": { 2528 | "version": "3.7.0", 2529 | "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", 2530 | "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", 2531 | "dev": true 2532 | }, 2533 | "node_modules/string-argv": { 2534 | "version": "0.3.2", 2535 | "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", 2536 | "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", 2537 | "dev": true, 2538 | "engines": { 2539 | "node": ">=0.6.19" 2540 | } 2541 | }, 2542 | "node_modules/strip-final-newline": { 2543 | "version": "3.0.0", 2544 | "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", 2545 | "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", 2546 | "dev": true, 2547 | "engines": { 2548 | "node": ">=12" 2549 | }, 2550 | "funding": { 2551 | "url": "https://github.com/sponsors/sindresorhus" 2552 | } 2553 | }, 2554 | "node_modules/strip-json-comments": { 2555 | "version": "3.1.1", 2556 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 2557 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 2558 | "dev": true, 2559 | "engines": { 2560 | "node": ">=8" 2561 | }, 2562 | "funding": { 2563 | "url": "https://github.com/sponsors/sindresorhus" 2564 | } 2565 | }, 2566 | "node_modules/strip-literal": { 2567 | "version": "2.0.0", 2568 | "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.0.0.tgz", 2569 | "integrity": "sha512-f9vHgsCWBq2ugHAkGMiiYY+AYG0D/cbloKKg0nhaaaSNsujdGIpVXCNsrJpCKr5M0f4aI31mr13UjY6GAuXCKA==", 2570 | "dev": true, 2571 | "dependencies": { 2572 | "js-tokens": "^8.0.2" 2573 | }, 2574 | "funding": { 2575 | "url": "https://github.com/sponsors/antfu" 2576 | } 2577 | }, 2578 | "node_modules/supports-color": { 2579 | "version": "7.2.0", 2580 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 2581 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 2582 | "dev": true, 2583 | "dependencies": { 2584 | "has-flag": "^4.0.0" 2585 | }, 2586 | "engines": { 2587 | "node": ">=8" 2588 | } 2589 | }, 2590 | "node_modules/supports-preserve-symlinks-flag": { 2591 | "version": "1.0.0", 2592 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", 2593 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", 2594 | "dev": true, 2595 | "engines": { 2596 | "node": ">= 0.4" 2597 | }, 2598 | "funding": { 2599 | "url": "https://github.com/sponsors/ljharb" 2600 | } 2601 | }, 2602 | "node_modules/test-exclude": { 2603 | "version": "6.0.0", 2604 | "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", 2605 | "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", 2606 | "dev": true, 2607 | "dependencies": { 2608 | "@istanbuljs/schema": "^0.1.2", 2609 | "glob": "^7.1.4", 2610 | "minimatch": "^3.0.4" 2611 | }, 2612 | "engines": { 2613 | "node": ">=8" 2614 | } 2615 | }, 2616 | "node_modules/tinybench": { 2617 | "version": "2.6.0", 2618 | "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.6.0.tgz", 2619 | "integrity": "sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA==", 2620 | "dev": true 2621 | }, 2622 | "node_modules/tinypool": { 2623 | "version": "0.8.2", 2624 | "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.2.tgz", 2625 | "integrity": "sha512-SUszKYe5wgsxnNOVlBYO6IC+8VGWdVGZWAqUxp3UErNBtptZvWbwyUOyzNL59zigz2rCA92QiL3wvG+JDSdJdQ==", 2626 | "dev": true, 2627 | "engines": { 2628 | "node": ">=14.0.0" 2629 | } 2630 | }, 2631 | "node_modules/tinyspy": { 2632 | "version": "2.2.1", 2633 | "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", 2634 | "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", 2635 | "dev": true, 2636 | "engines": { 2637 | "node": ">=14.0.0" 2638 | } 2639 | }, 2640 | "node_modules/to-fast-properties": { 2641 | "version": "2.0.0", 2642 | "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", 2643 | "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", 2644 | "dev": true, 2645 | "engines": { 2646 | "node": ">=4" 2647 | } 2648 | }, 2649 | "node_modules/to-regex-range": { 2650 | "version": "5.0.1", 2651 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 2652 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 2653 | "dev": true, 2654 | "optional": true, 2655 | "peer": true, 2656 | "dependencies": { 2657 | "is-number": "^7.0.0" 2658 | }, 2659 | "engines": { 2660 | "node": ">=8.0" 2661 | } 2662 | }, 2663 | "node_modules/totalist": { 2664 | "version": "3.0.1", 2665 | "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", 2666 | "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", 2667 | "dev": true, 2668 | "optional": true, 2669 | "peer": true, 2670 | "engines": { 2671 | "node": ">=6" 2672 | } 2673 | }, 2674 | "node_modules/type-detect": { 2675 | "version": "4.0.8", 2676 | "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", 2677 | "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", 2678 | "dev": true, 2679 | "engines": { 2680 | "node": ">=4" 2681 | } 2682 | }, 2683 | "node_modules/typescript": { 2684 | "version": "5.4.2", 2685 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", 2686 | "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", 2687 | "dev": true, 2688 | "bin": { 2689 | "tsc": "bin/tsc", 2690 | "tsserver": "bin/tsserver" 2691 | }, 2692 | "engines": { 2693 | "node": ">=14.17" 2694 | } 2695 | }, 2696 | "node_modules/ufo": { 2697 | "version": "1.5.3", 2698 | "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz", 2699 | "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==", 2700 | "dev": true 2701 | }, 2702 | "node_modules/undici-types": { 2703 | "version": "5.26.5", 2704 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", 2705 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", 2706 | "dev": true, 2707 | "optional": true, 2708 | "peer": true 2709 | }, 2710 | "node_modules/universalify": { 2711 | "version": "0.1.2", 2712 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", 2713 | "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", 2714 | "dev": true, 2715 | "engines": { 2716 | "node": ">= 4.0.0" 2717 | } 2718 | }, 2719 | "node_modules/uri-js": { 2720 | "version": "4.4.1", 2721 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 2722 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 2723 | "dev": true, 2724 | "dependencies": { 2725 | "punycode": "^2.1.0" 2726 | } 2727 | }, 2728 | "node_modules/v8-to-istanbul": { 2729 | "version": "9.2.0", 2730 | "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", 2731 | "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", 2732 | "dev": true, 2733 | "dependencies": { 2734 | "@jridgewell/trace-mapping": "^0.3.12", 2735 | "@types/istanbul-lib-coverage": "^2.0.1", 2736 | "convert-source-map": "^2.0.0" 2737 | }, 2738 | "engines": { 2739 | "node": ">=10.12.0" 2740 | } 2741 | }, 2742 | "node_modules/validator": { 2743 | "version": "13.11.0", 2744 | "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", 2745 | "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", 2746 | "dev": true, 2747 | "engines": { 2748 | "node": ">= 0.10" 2749 | } 2750 | }, 2751 | "node_modules/vite": { 2752 | "version": "5.2.7", 2753 | "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.7.tgz", 2754 | "integrity": "sha512-k14PWOKLI6pMaSzAuGtT+Cf0YmIx12z9YGon39onaJNy8DLBfBJrzg9FQEmkAM5lpHBZs9wksWAsyF/HkpEwJA==", 2755 | "dev": true, 2756 | "dependencies": { 2757 | "esbuild": "^0.20.1", 2758 | "postcss": "^8.4.38", 2759 | "rollup": "^4.13.0" 2760 | }, 2761 | "bin": { 2762 | "vite": "bin/vite.js" 2763 | }, 2764 | "engines": { 2765 | "node": "^18.0.0 || >=20.0.0" 2766 | }, 2767 | "funding": { 2768 | "url": "https://github.com/vitejs/vite?sponsor=1" 2769 | }, 2770 | "optionalDependencies": { 2771 | "fsevents": "~2.3.3" 2772 | }, 2773 | "peerDependencies": { 2774 | "@types/node": "^18.0.0 || >=20.0.0", 2775 | "less": "*", 2776 | "lightningcss": "^1.21.0", 2777 | "sass": "*", 2778 | "stylus": "*", 2779 | "sugarss": "*", 2780 | "terser": "^5.4.0" 2781 | }, 2782 | "peerDependenciesMeta": { 2783 | "@types/node": { 2784 | "optional": true 2785 | }, 2786 | "less": { 2787 | "optional": true 2788 | }, 2789 | "lightningcss": { 2790 | "optional": true 2791 | }, 2792 | "sass": { 2793 | "optional": true 2794 | }, 2795 | "stylus": { 2796 | "optional": true 2797 | }, 2798 | "sugarss": { 2799 | "optional": true 2800 | }, 2801 | "terser": { 2802 | "optional": true 2803 | } 2804 | } 2805 | }, 2806 | "node_modules/vite-node": { 2807 | "version": "1.4.0", 2808 | "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.4.0.tgz", 2809 | "integrity": "sha512-VZDAseqjrHgNd4Kh8icYHWzTKSCZMhia7GyHfhtzLW33fZlG9SwsB6CEhgyVOWkJfJ2pFLrp/Gj1FSfAiqH9Lw==", 2810 | "dev": true, 2811 | "dependencies": { 2812 | "cac": "^6.7.14", 2813 | "debug": "^4.3.4", 2814 | "pathe": "^1.1.1", 2815 | "picocolors": "^1.0.0", 2816 | "vite": "^5.0.0" 2817 | }, 2818 | "bin": { 2819 | "vite-node": "vite-node.mjs" 2820 | }, 2821 | "engines": { 2822 | "node": "^18.0.0 || >=20.0.0" 2823 | }, 2824 | "funding": { 2825 | "url": "https://opencollective.com/vitest" 2826 | } 2827 | }, 2828 | "node_modules/vite-plugin-dts": { 2829 | "version": "3.8.1", 2830 | "resolved": "https://registry.npmjs.org/vite-plugin-dts/-/vite-plugin-dts-3.8.1.tgz", 2831 | "integrity": "sha512-zEYyQxH7lKto1VTKZHF3ZZeOPkkJgnMrePY4VxDHfDSvDjmYMMfWjZxYmNwW8QxbaItWJQhhXY+geAbyNphI7g==", 2832 | "dev": true, 2833 | "dependencies": { 2834 | "@microsoft/api-extractor": "7.43.0", 2835 | "@rollup/pluginutils": "^5.1.0", 2836 | "@vue/language-core": "^1.8.27", 2837 | "debug": "^4.3.4", 2838 | "kolorist": "^1.8.0", 2839 | "magic-string": "^0.30.8", 2840 | "vue-tsc": "^1.8.27" 2841 | }, 2842 | "engines": { 2843 | "node": "^14.18.0 || >=16.0.0" 2844 | }, 2845 | "peerDependencies": { 2846 | "typescript": "*", 2847 | "vite": "*" 2848 | }, 2849 | "peerDependenciesMeta": { 2850 | "vite": { 2851 | "optional": true 2852 | } 2853 | } 2854 | }, 2855 | "node_modules/vitest": { 2856 | "version": "1.4.0", 2857 | "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.4.0.tgz", 2858 | "integrity": "sha512-gujzn0g7fmwf83/WzrDTnncZt2UiXP41mHuFYFrdwaLRVQ6JYQEiME2IfEjU3vcFL3VKa75XhI3lFgn+hfVsQw==", 2859 | "dev": true, 2860 | "dependencies": { 2861 | "@vitest/expect": "1.4.0", 2862 | "@vitest/runner": "1.4.0", 2863 | "@vitest/snapshot": "1.4.0", 2864 | "@vitest/spy": "1.4.0", 2865 | "@vitest/utils": "1.4.0", 2866 | "acorn-walk": "^8.3.2", 2867 | "chai": "^4.3.10", 2868 | "debug": "^4.3.4", 2869 | "execa": "^8.0.1", 2870 | "local-pkg": "^0.5.0", 2871 | "magic-string": "^0.30.5", 2872 | "pathe": "^1.1.1", 2873 | "picocolors": "^1.0.0", 2874 | "std-env": "^3.5.0", 2875 | "strip-literal": "^2.0.0", 2876 | "tinybench": "^2.5.1", 2877 | "tinypool": "^0.8.2", 2878 | "vite": "^5.0.0", 2879 | "vite-node": "1.4.0", 2880 | "why-is-node-running": "^2.2.2" 2881 | }, 2882 | "bin": { 2883 | "vitest": "vitest.mjs" 2884 | }, 2885 | "engines": { 2886 | "node": "^18.0.0 || >=20.0.0" 2887 | }, 2888 | "funding": { 2889 | "url": "https://opencollective.com/vitest" 2890 | }, 2891 | "peerDependencies": { 2892 | "@edge-runtime/vm": "*", 2893 | "@types/node": "^18.0.0 || >=20.0.0", 2894 | "@vitest/browser": "1.4.0", 2895 | "@vitest/ui": "1.4.0", 2896 | "happy-dom": "*", 2897 | "jsdom": "*" 2898 | }, 2899 | "peerDependenciesMeta": { 2900 | "@edge-runtime/vm": { 2901 | "optional": true 2902 | }, 2903 | "@types/node": { 2904 | "optional": true 2905 | }, 2906 | "@vitest/browser": { 2907 | "optional": true 2908 | }, 2909 | "@vitest/ui": { 2910 | "optional": true 2911 | }, 2912 | "happy-dom": { 2913 | "optional": true 2914 | }, 2915 | "jsdom": { 2916 | "optional": true 2917 | } 2918 | } 2919 | }, 2920 | "node_modules/vue-template-compiler": { 2921 | "version": "2.7.16", 2922 | "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz", 2923 | "integrity": "sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==", 2924 | "dev": true, 2925 | "dependencies": { 2926 | "de-indent": "^1.0.2", 2927 | "he": "^1.2.0" 2928 | } 2929 | }, 2930 | "node_modules/vue-tsc": { 2931 | "version": "1.8.27", 2932 | "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.8.27.tgz", 2933 | "integrity": "sha512-WesKCAZCRAbmmhuGl3+VrdWItEvfoFIPXOvUJkjULi+x+6G/Dy69yO3TBRJDr9eUlmsNAwVmxsNZxvHKzbkKdg==", 2934 | "dev": true, 2935 | "dependencies": { 2936 | "@volar/typescript": "~1.11.1", 2937 | "@vue/language-core": "1.8.27", 2938 | "semver": "^7.5.4" 2939 | }, 2940 | "bin": { 2941 | "vue-tsc": "bin/vue-tsc.js" 2942 | }, 2943 | "peerDependencies": { 2944 | "typescript": "*" 2945 | } 2946 | }, 2947 | "node_modules/which": { 2948 | "version": "2.0.2", 2949 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 2950 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 2951 | "dev": true, 2952 | "dependencies": { 2953 | "isexe": "^2.0.0" 2954 | }, 2955 | "bin": { 2956 | "node-which": "bin/node-which" 2957 | }, 2958 | "engines": { 2959 | "node": ">= 8" 2960 | } 2961 | }, 2962 | "node_modules/why-is-node-running": { 2963 | "version": "2.2.2", 2964 | "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz", 2965 | "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==", 2966 | "dev": true, 2967 | "dependencies": { 2968 | "siginfo": "^2.0.0", 2969 | "stackback": "0.0.2" 2970 | }, 2971 | "bin": { 2972 | "why-is-node-running": "cli.js" 2973 | }, 2974 | "engines": { 2975 | "node": ">=8" 2976 | } 2977 | }, 2978 | "node_modules/wrappy": { 2979 | "version": "1.0.2", 2980 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 2981 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 2982 | "dev": true 2983 | }, 2984 | "node_modules/yallist": { 2985 | "version": "4.0.0", 2986 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 2987 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", 2988 | "dev": true 2989 | }, 2990 | "node_modules/yocto-queue": { 2991 | "version": "1.0.0", 2992 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", 2993 | "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", 2994 | "dev": true, 2995 | "engines": { 2996 | "node": ">=12.20" 2997 | }, 2998 | "funding": { 2999 | "url": "https://github.com/sponsors/sindresorhus" 3000 | } 3001 | }, 3002 | "node_modules/z-schema": { 3003 | "version": "5.0.5", 3004 | "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-5.0.5.tgz", 3005 | "integrity": "sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==", 3006 | "dev": true, 3007 | "dependencies": { 3008 | "lodash.get": "^4.4.2", 3009 | "lodash.isequal": "^4.5.0", 3010 | "validator": "^13.7.0" 3011 | }, 3012 | "bin": { 3013 | "z-schema": "bin/z-schema" 3014 | }, 3015 | "engines": { 3016 | "node": ">=8.0.0" 3017 | }, 3018 | "optionalDependencies": { 3019 | "commander": "^9.4.1" 3020 | } 3021 | } 3022 | } 3023 | } 3024 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dioma", 3 | "version": "0.4.6", 4 | "description": "Elegant dependency injection container for vanilla JavaScript and TypeScript", 5 | "license": "MIT", 6 | "repository": { 7 | "type": "git", 8 | "url": "git@github.com:zheksoon/dioma.git" 9 | }, 10 | "homepage": "https://github.com/zheksoon/dioma", 11 | "author": { 12 | "name": "Eugene Daragan", 13 | "email": "zheksoon@gmail.com" 14 | }, 15 | "keywords": [ 16 | "di", 17 | "dependency injection", 18 | "di container", 19 | "inversion of control", 20 | "ioc", 21 | "ioc container", 22 | "javascript", 23 | "typescript", 24 | "dioma", 25 | "inversify", 26 | "awilix", 27 | "tsyringe" 28 | ], 29 | "type": "module", 30 | "main": "dist/dioma.js", 31 | "module": "dist/dioma.js", 32 | "types": "dist/index.d.ts", 33 | "exports": { 34 | ".": { 35 | "import": { 36 | "types": "./dist/index.d.ts", 37 | "default": "./dist/dioma.js" 38 | }, 39 | "require": { 40 | "types": "./dist/index.d.cts", 41 | "default": "./dist/dioma.cjs" 42 | } 43 | } 44 | }, 45 | "files": [ 46 | "src", 47 | "dist", 48 | "README.md", 49 | "LICENSE", 50 | "package.json" 51 | ], 52 | "scripts": { 53 | "build": "vite build --minify=false --sourcemap=true && cp dist/index.d.ts dist/index.d.cts", 54 | "test": "vitest", 55 | "test:coverage": "vitest --coverage" 56 | }, 57 | "devDependencies": { 58 | "@vitest/coverage-v8": "^1.4.0", 59 | "vite": "^5.2.7", 60 | "vitest": "^1.4.0", 61 | "vite-plugin-dts": "^3.8.1" 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/container.ts: -------------------------------------------------------------------------------- 1 | import { 2 | AsyncDependencyCycleError, 3 | DependencyCycleError, 4 | TokenNotRegisteredError, 5 | } from "./errors"; 6 | import { Scopes } from "./scopes"; 7 | import { Token } from "./token"; 8 | import type { 9 | AnyDescriptor, 10 | ArgsOf, 11 | InstanceOf, 12 | ScopeHandler, 13 | ScopedClass, 14 | TokenClassDescriptor, 15 | TokenFactoryDescriptor, 16 | TokenOrClass, 17 | TokenValueDescriptor, 18 | } from "./types"; 19 | 20 | type DescriptorWithContainer = AnyDescriptor & { 21 | container: Container; 22 | }; 23 | 24 | const MAX_LOOP_COUNT = 100; 25 | 26 | export class Container { 27 | private instances = new WeakMap(); 28 | 29 | private resolutionContainer: Container | null = null; 30 | 31 | private resolutionSet = new Set(); 32 | 33 | private pendingPromiseMap = new Map>>(); 34 | 35 | private tokenDescriptorMap = new Map(); 36 | 37 | private resolutionsLoopCounter = 0; 38 | 39 | constructor(private parentContainer: Container | null = null, public name?: string) { 40 | this.register = this.register.bind(this); 41 | } 42 | 43 | childContainer = (name?: string) => { 44 | return new Container(this, name); 45 | }; 46 | 47 | public $getInstance( 48 | descriptor: TokenClassDescriptor, 49 | args: any[] = [], 50 | cache = true 51 | ) { 52 | let instance = null; 53 | let container: Container | null = this; 54 | 55 | const cls = descriptor.class; 56 | 57 | while (!instance && container) { 58 | instance = container.instances.get(cls); 59 | container = container.parentContainer; 60 | } 61 | 62 | if (!instance) { 63 | if (descriptor.beforeCreate) { 64 | descriptor.beforeCreate(this, descriptor, args); 65 | } 66 | 67 | instance = new cls(...args); 68 | 69 | if (cache) { 70 | this.instances.set(cls, instance); 71 | } 72 | } 73 | 74 | return instance; 75 | } 76 | 77 | private getTokenDescriptor( 78 | clsOrToken: TokenOrClass 79 | ): DescriptorWithContainer | undefined { 80 | let tokenDescriptor; 81 | let container: Container | null = this; 82 | 83 | while (!tokenDescriptor && container) { 84 | tokenDescriptor = container.tokenDescriptorMap.get(clsOrToken); 85 | container = container.parentContainer; 86 | } 87 | 88 | return tokenDescriptor; 89 | } 90 | 91 | private injectImpl>( 92 | clsOrToken: T, 93 | args: Args, 94 | resolutionContainer = this.resolutionContainer 95 | ): InstanceOf { 96 | this.resolutionContainer = resolutionContainer || new Container(); 97 | 98 | try { 99 | if (this.resolutionSet.has(clsOrToken)) { 100 | throw new DependencyCycleError(); 101 | } 102 | 103 | let cls = clsOrToken as TokenOrClass; 104 | 105 | let scope: ScopeHandler; 106 | 107 | let container: Container = this; 108 | 109 | let descriptor = this.getTokenDescriptor(clsOrToken); 110 | 111 | this.resolutionSet.add(clsOrToken); 112 | 113 | if (!descriptor) { 114 | if (clsOrToken instanceof Token) { 115 | throw new TokenNotRegisteredError(); 116 | } 117 | 118 | cls = clsOrToken; 119 | scope = cls.scope || Scopes.Transient(); 120 | container = this; 121 | descriptor = { class: cls, container: this }; 122 | } else { 123 | if (descriptor.beforeInject) { 124 | descriptor.beforeInject(container, descriptor, args); 125 | } 126 | 127 | if ("class" in descriptor) { 128 | cls = descriptor.class as ScopedClass; 129 | scope = descriptor.scope || cls.scope || Scopes.Transient(); 130 | container = descriptor.container; 131 | } else if ("value" in descriptor) { 132 | return descriptor.value; 133 | } else if ("factory" in descriptor) { 134 | // @ts-ignore 135 | return descriptor.factory(container, ...args); 136 | } else { 137 | throw new Error("Invalid descriptor"); 138 | } 139 | } 140 | 141 | return scope(descriptor, args, container, this.resolutionContainer); 142 | } finally { 143 | this.resolutionSet.delete(clsOrToken); 144 | this.resolutionContainer = resolutionContainer; 145 | 146 | if (!resolutionContainer) { 147 | this.resolutionsLoopCounter = 0; 148 | } 149 | } 150 | } 151 | 152 | inject = >( 153 | cls: T, 154 | ...args: Args 155 | ): InstanceOf => { 156 | return this.injectImpl(cls, args, undefined); 157 | }; 158 | 159 | injectAsync = >( 160 | cls: T, 161 | ...args: Args 162 | ): Promise> => { 163 | const resolutionContainer = this.resolutionContainer; 164 | 165 | this.resolutionsLoopCounter += 1; 166 | 167 | if (this.resolutionsLoopCounter > MAX_LOOP_COUNT) { 168 | throw new AsyncDependencyCycleError(); 169 | } 170 | 171 | if (this.pendingPromiseMap.has(cls)) { 172 | return this.pendingPromiseMap.get(cls) as Promise>; 173 | } 174 | 175 | if (this.instances.has(cls)) { 176 | return Promise.resolve(this.instances.get(cls)); 177 | } 178 | 179 | const promise = Promise.resolve().then(() => { 180 | try { 181 | return this.injectImpl(cls, args, resolutionContainer); 182 | } finally { 183 | this.pendingPromiseMap.delete(cls); 184 | } 185 | }); 186 | 187 | this.pendingPromiseMap.set(cls, promise); 188 | 189 | return promise; 190 | }; 191 | 192 | waitAsync = async () => { 193 | // // The solution doesn't work correctly in all cases 194 | // // because at the moment of the call not all promises are in the map 195 | // await Promise.all(this.pendingPromiseMap.values()); 196 | return new Promise((resolve) => setTimeout(resolve, 0)); 197 | }; 198 | 199 | register>(descriptor: TokenValueDescriptor): void; 200 | 201 | register>(descriptor: TokenFactoryDescriptor): void; 202 | 203 | register>(descriptor: TokenClassDescriptor): void; 204 | 205 | register(tokenDescriptor: any): void { 206 | const token = tokenDescriptor.token || tokenDescriptor.class; 207 | 208 | const descriptorWithContainer = { ...tokenDescriptor, container: this }; 209 | 210 | this.tokenDescriptorMap.set(token, descriptorWithContainer); 211 | 212 | if (tokenDescriptor.class) { 213 | this.tokenDescriptorMap.set(token.class, descriptorWithContainer); 214 | } 215 | } 216 | 217 | unregister = (token: TokenOrClass): void => { 218 | const descriptor = this.getTokenDescriptor(token); 219 | 220 | this.tokenDescriptorMap.delete(token); 221 | this.instances.delete(token); 222 | 223 | if (descriptor && "class" in descriptor) { 224 | this.tokenDescriptorMap.delete(descriptor.class as ScopedClass); 225 | this.instances.delete(descriptor.class); 226 | } 227 | }; 228 | 229 | reset = (): void => { 230 | this.instances = new WeakMap(); 231 | this.resolutionSet.clear(); 232 | this.pendingPromiseMap.clear(); 233 | this.tokenDescriptorMap.clear(); 234 | this.resolutionContainer = null; 235 | this.resolutionsLoopCounter = 0; 236 | }; 237 | } 238 | 239 | export const globalContainer = new Container(null, "Global container"); 240 | 241 | export const inject = globalContainer.inject; 242 | 243 | export const injectAsync = globalContainer.injectAsync; 244 | 245 | export const childContainer = globalContainer.childContainer; 246 | -------------------------------------------------------------------------------- /src/errors.ts: -------------------------------------------------------------------------------- 1 | export class DependencyCycleError extends Error { 2 | constructor() { 3 | super("Circular dependency detected"); 4 | } 5 | } 6 | 7 | export class AsyncDependencyCycleError extends Error { 8 | constructor() { 9 | super("Circular dependency detected in async resolution"); 10 | } 11 | } 12 | 13 | export class ArgumentsError extends Error { 14 | constructor(scope: string, className: string) { 15 | super(`Arguments are not supported for ${scope} of ${className}`); 16 | } 17 | } 18 | 19 | export class TokenNotRegisteredError extends Error { 20 | constructor() { 21 | super("Token is not registered in the container"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export { 2 | Container, 3 | childContainer, 4 | globalContainer, 5 | inject, 6 | injectAsync, 7 | } from "./container"; 8 | export { 9 | ArgumentsError, 10 | AsyncDependencyCycleError, 11 | DependencyCycleError, 12 | TokenNotRegisteredError, 13 | } from "./errors"; 14 | export { Scopes } from "./scopes"; 15 | export { Token } from "./token"; 16 | export type { 17 | Injectable, 18 | ScopedClass, 19 | TokenClassDescriptor, 20 | TokenFactoryDescriptor, 21 | TokenValueDescriptor, 22 | } from "./types"; 23 | -------------------------------------------------------------------------------- /src/scopes.ts: -------------------------------------------------------------------------------- 1 | import { globalContainer } from "./container"; 2 | import { ArgumentsError } from "./errors"; 3 | import type { ScopeHandler } from "./types"; 4 | 5 | export class Scopes { 6 | public static Singleton(): ScopeHandler { 7 | return function SingletonScope(descriptor, args) { 8 | if (args.length > 0) { 9 | throw new ArgumentsError(SingletonScope.name, descriptor.class.name); 10 | } 11 | 12 | return globalContainer.$getInstance(descriptor); 13 | }; 14 | } 15 | 16 | public static Transient(): ScopeHandler { 17 | return function TransientScope(descriptor, args, container) { 18 | return container.$getInstance(descriptor, args, false); 19 | }; 20 | } 21 | 22 | public static Container(): ScopeHandler { 23 | return function ContainerScope(descriptor, args, container) { 24 | if (args.length > 0) { 25 | throw new ArgumentsError(ContainerScope.name, descriptor.class.name); 26 | } 27 | 28 | return container.$getInstance(descriptor); 29 | }; 30 | } 31 | 32 | public static Resolution(): ScopeHandler { 33 | return function ResolutionScope(descriptor, args, _, resolutionContainer) { 34 | return resolutionContainer.$getInstance(descriptor, args); 35 | }; 36 | } 37 | 38 | public static Scoped = Scopes.Container; 39 | } 40 | -------------------------------------------------------------------------------- /src/token.ts: -------------------------------------------------------------------------------- 1 | export class Token { 2 | constructor(public readonly name?: string) {} 3 | } 4 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | import type { Container } from "./container"; 2 | import type { Token } from "./token"; 3 | 4 | export type ScopeHandler = ( 5 | cls: any, 6 | args: any[], 7 | container: Container, 8 | resolutionContainer: Container 9 | ) => any; 10 | 11 | export interface ScopedClass { 12 | new (...args: any[]): any; 13 | 14 | scope: ScopeHandler; 15 | } 16 | 17 | export type Injectable< 18 | C extends I, 19 | I extends ScopedClass = ScopedClass 20 | > = InstanceType; 21 | 22 | type Newable = new (...args: any[]) => T; 23 | 24 | type OptionalArgs> = R extends readonly [...infer Rest, infer Last] 25 | ? R | OptionalArgs 26 | : []; 27 | 28 | type TokenType = T extends Token ? U : R; 29 | 30 | type BaseDescriptor = { 31 | beforeInject?: (container: Container, descriptor: AnyDescriptor, args: any[]) => any; 32 | beforeCreate?: (container: Container, descriptor: AnyDescriptor, args: any[]) => any; 33 | }; 34 | 35 | export type TokenValueDescriptor> = BaseDescriptor & { 36 | token: T; 37 | value: TokenType; 38 | }; 39 | 40 | export type TokenFactoryDescriptor> = BaseDescriptor & { 41 | token: T; 42 | factory: (container: Container, ...args: any[]) => TokenType; 43 | }; 44 | 45 | export type TokenClassDescriptor> = BaseDescriptor & { 46 | token?: T; 47 | class: Newable>; 48 | scope?: ScopeHandler; 49 | }; 50 | 51 | export type AnyDescriptor = 52 | | TokenValueDescriptor 53 | | TokenFactoryDescriptor 54 | | TokenClassDescriptor; 55 | 56 | export type TokenOrClass = Token | ScopedClass; 57 | 58 | export type InstanceOf> = C extends Newable ? InstanceType : C; 59 | 60 | export type ArgsOf> = C extends Newable 61 | ? OptionalArgs> 62 | : any[]; 63 | -------------------------------------------------------------------------------- /test/dioma.test.ts: -------------------------------------------------------------------------------- 1 | import { beforeEach, describe, expect, it } from "vitest"; 2 | import { 3 | ArgumentsError, 4 | AsyncDependencyCycleError, 5 | // AsyncDependencyCycleError, 6 | Container, 7 | DependencyCycleError, 8 | ScopedClass, 9 | Scopes, 10 | Token, 11 | globalContainer, 12 | inject, 13 | injectAsync, 14 | } from "../src"; 15 | import { AnyDescriptor } from "../src/types"; 16 | 17 | describe("Dioma", () => { 18 | beforeEach(() => { 19 | globalContainer.reset(); 20 | }); 21 | 22 | it("should be able to create container", () => { 23 | const container = new Container(); 24 | 25 | expect(container).toBeInstanceOf(Container); 26 | }); 27 | 28 | describe("child container", () => { 29 | it("should be able to create child container", () => { 30 | const container = new Container(); 31 | 32 | const childContainer = container.childContainer(); 33 | 34 | expect(childContainer).toBeInstanceOf(Container); 35 | }); 36 | 37 | it("should be able to create grandchild container", () => { 38 | const container = new Container(); 39 | 40 | const childContainer = container.childContainer(); 41 | 42 | const grandchildContainer = childContainer.childContainer(); 43 | 44 | expect(grandchildContainer).toBeInstanceOf(Container); 45 | }); 46 | 47 | it("should be able to inject instance from parent container", () => { 48 | class ParentClass { 49 | static scope = Scopes.Container(); 50 | } 51 | 52 | const parentContainer = new Container(); 53 | 54 | const instance1 = parentContainer.inject(ParentClass); 55 | 56 | const childContainer = parentContainer.childContainer(); 57 | 58 | const instance2 = childContainer.inject(ParentClass); 59 | 60 | expect(instance1).toBeInstanceOf(ParentClass); 61 | 62 | expect(instance2).toBe(instance1); 63 | }); 64 | 65 | it("should handle multiple child containers", () => { 66 | class ParentClass { 67 | static scope = Scopes.Scoped(); 68 | } 69 | 70 | const parentContainer = new Container(); 71 | 72 | const childContainer1 = parentContainer.childContainer(); 73 | 74 | const childContainer2 = parentContainer.childContainer(); 75 | 76 | const instance1 = childContainer1.inject(ParentClass); 77 | 78 | const instance2 = childContainer2.inject(ParentClass); 79 | 80 | expect(instance1).toBeInstanceOf(ParentClass); 81 | 82 | expect(instance2).toBeInstanceOf(ParentClass); 83 | 84 | expect(instance1).not.toBe(instance2); 85 | }); 86 | 87 | it("should use parent container if instance is not found in child container", () => { 88 | class ParentClass { 89 | static scope = Scopes.Scoped(); 90 | } 91 | 92 | const parentContainer = new Container(); 93 | 94 | parentContainer.inject(ParentClass); 95 | 96 | const instance1 = parentContainer.inject(ParentClass); 97 | 98 | const childContainer = parentContainer.childContainer(); 99 | 100 | const instance2 = childContainer.inject(ParentClass); 101 | 102 | expect(instance1).toBeInstanceOf(ParentClass); 103 | 104 | expect(instance2).toBe(instance1); 105 | }); 106 | }); 107 | 108 | describe("Singleton", () => { 109 | it("should be able to inject singleton", () => { 110 | class SingletonClass { 111 | static scope = Scopes.Singleton(); 112 | } 113 | 114 | const singleton = inject(SingletonClass); 115 | 116 | expect(singleton).toBeInstanceOf(SingletonClass); 117 | 118 | const singleton2 = inject(SingletonClass); 119 | 120 | expect(singleton2).toBe(singleton); 121 | }); 122 | }); 123 | 124 | describe("Transient", () => { 125 | it("should be able to inject transient", () => { 126 | class TransientClass { 127 | static scope = Scopes.Transient(); 128 | } 129 | 130 | const transient = inject(TransientClass); 131 | 132 | expect(transient).toBeInstanceOf(TransientClass); 133 | 134 | const transient2 = inject(TransientClass); 135 | 136 | expect(transient2).not.toBe(transient); 137 | }); 138 | 139 | it("uses transient scope by default", () => { 140 | class DefaultClass {} 141 | 142 | const instance1 = inject(DefaultClass as ScopedClass); 143 | 144 | const instance2 = inject(DefaultClass as ScopedClass); 145 | 146 | expect(instance1).toBeInstanceOf(DefaultClass); 147 | 148 | expect(instance2).not.toBe(instance1); 149 | }); 150 | }); 151 | 152 | describe("Scoped", () => { 153 | it("should be able to inject scoped", () => { 154 | class ScopedClass { 155 | static scope = Scopes.Scoped(); 156 | } 157 | 158 | const container = new Container(); 159 | 160 | const scoped = container.inject(ScopedClass); 161 | 162 | const scoped2 = container.inject(ScopedClass); 163 | 164 | expect(scoped).toBeInstanceOf(ScopedClass); 165 | 166 | expect(scoped2).toBe(scoped); 167 | }); 168 | }); 169 | 170 | describe("Resolution", () => { 171 | it("should be able to return the same instance in resolution scope", () => { 172 | class ResolutionClassA { 173 | constructor( 174 | public instanceB = inject(ResolutionClassB), 175 | public instanceC = inject(ResolutionClassC) 176 | ) {} 177 | 178 | static scope = Scopes.Transient(); 179 | } 180 | 181 | class ResolutionClassB { 182 | constructor(public instanceC = inject(ResolutionClassC)) {} 183 | 184 | static scope = Scopes.Transient(); 185 | } 186 | 187 | class ResolutionClassC { 188 | static scope = Scopes.Resolution(); 189 | } 190 | 191 | const instanceA = inject(ResolutionClassA); 192 | 193 | const instanceA2 = inject(ResolutionClassA); 194 | 195 | expect(instanceA).toBeInstanceOf(ResolutionClassA); 196 | 197 | expect(instanceA.instanceB).toBeInstanceOf(ResolutionClassB); 198 | 199 | expect(instanceA.instanceC).toBeInstanceOf(ResolutionClassC); 200 | 201 | expect(instanceA.instanceB.instanceC).toBeInstanceOf(ResolutionClassC); 202 | 203 | expect(instanceA.instanceB.instanceC).toBe(instanceA.instanceC); 204 | 205 | expect(instanceA2).not.toBe(instanceA); 206 | 207 | expect(instanceA2.instanceB.instanceC).toBe(instanceA2.instanceC); 208 | 209 | expect(instanceA2.instanceC).not.toBe(instanceA.instanceC); 210 | }); 211 | }); 212 | 213 | describe("Complex dependency", () => { 214 | it("should be able to inject complex dependency", () => { 215 | class DependencyA { 216 | constructor(public instanceB = inject(DependencyB)) {} 217 | 218 | static scope = Scopes.Transient(); 219 | } 220 | 221 | class DependencyB { 222 | constructor(public instanceC = inject(DependencyC)) {} 223 | 224 | static scope = Scopes.Transient(); 225 | } 226 | 227 | class DependencyC { 228 | constructor(public instanceD = inject(DependencyD)) {} 229 | 230 | static scope = Scopes.Transient(); 231 | } 232 | 233 | class DependencyD { 234 | constructor() {} 235 | 236 | static scope = Scopes.Transient(); 237 | } 238 | 239 | const instanceA = inject(DependencyA); 240 | 241 | expect(instanceA).toBeInstanceOf(DependencyA); 242 | 243 | expect(instanceA.instanceB).toBeInstanceOf(DependencyB); 244 | 245 | expect(instanceA.instanceB.instanceC).toBeInstanceOf(DependencyC); 246 | 247 | expect(instanceA.instanceB.instanceC.instanceD).toBeInstanceOf(DependencyD); 248 | }); 249 | 250 | it("should be able to inject complex dependency with resolution scope", () => { 251 | class DependencyZ { 252 | constructor( 253 | public instanceA = inject(DependencyA), 254 | public instanceB = inject(DependencyB) 255 | ) {} 256 | 257 | static scope = Scopes.Transient(); 258 | } 259 | 260 | class DependencyA { 261 | constructor( 262 | public instanceB = inject(DependencyB), 263 | public instanceC = inject(DependencyC) 264 | ) {} 265 | 266 | static scope = Scopes.Transient(); 267 | } 268 | 269 | class DependencyB { 270 | constructor(public instanceC = inject(DependencyC)) {} 271 | 272 | static scope = Scopes.Transient(); 273 | } 274 | 275 | class DependencyC { 276 | constructor() {} 277 | 278 | static scope = Scopes.Resolution(); 279 | } 280 | 281 | const instanceZ = inject(DependencyZ); 282 | 283 | expect(instanceZ).toBeInstanceOf(DependencyZ); 284 | 285 | expect(instanceZ.instanceA).toBeInstanceOf(DependencyA); 286 | 287 | expect(instanceZ.instanceB).toBeInstanceOf(DependencyB); 288 | 289 | expect(instanceZ.instanceA.instanceB).toBeInstanceOf(DependencyB); 290 | 291 | expect(instanceZ.instanceA.instanceC).toBeInstanceOf(DependencyC); 292 | 293 | expect(instanceZ.instanceB.instanceC).toBeInstanceOf(DependencyC); 294 | 295 | expect(instanceZ.instanceA.instanceC).toBe(instanceZ.instanceB.instanceC); 296 | }); 297 | }); 298 | 299 | describe("Circular dependency", () => { 300 | it("should throw error when circular dependency is detected for transient scope", () => { 301 | class CircularDependencyA { 302 | constructor(public instanceB = inject(CircularDependencyB)) {} 303 | 304 | static scope = Scopes.Transient(); 305 | } 306 | 307 | class CircularDependencyB { 308 | constructor(public instanceA = inject(CircularDependencyA)) {} 309 | 310 | static scope = Scopes.Transient(); 311 | } 312 | 313 | expect(() => inject(CircularDependencyA)).toThrowError(DependencyCycleError); 314 | }); 315 | 316 | it("should throw error when circular dependency is detected for container scope", () => { 317 | const container = new Container(); 318 | 319 | class CircularDependencyA { 320 | constructor(public instanceB = container.inject(CircularDependencyB)) {} 321 | 322 | static scope = Scopes.Scoped(); 323 | } 324 | 325 | class CircularDependencyB { 326 | constructor(public instanceA = container.inject(CircularDependencyA)) {} 327 | 328 | static scope = Scopes.Scoped(); 329 | } 330 | 331 | expect(() => container.inject(CircularDependencyA)).toThrowError( 332 | DependencyCycleError 333 | ); 334 | }); 335 | 336 | it("should throw error when circular dependency is detected for resolution scope", () => { 337 | class CircularDependencyA { 338 | constructor(public instanceB = inject(CircularDependencyB)) {} 339 | 340 | static scope = Scopes.Resolution(); 341 | } 342 | 343 | class CircularDependencyB { 344 | constructor(public instanceA = inject(CircularDependencyA)) {} 345 | 346 | static scope = Scopes.Resolution(); 347 | } 348 | 349 | const container = new Container(); 350 | 351 | expect(() => container.inject(CircularDependencyA)).toThrowError( 352 | DependencyCycleError 353 | ); 354 | }); 355 | 356 | it("should throw error when circular dependency is detected for singleton scope", () => { 357 | class CircularDependencyA { 358 | constructor(public instanceB = inject(CircularDependencyB)) {} 359 | 360 | static scope = Scopes.Singleton(); 361 | } 362 | 363 | class CircularDependencyB { 364 | constructor(public instanceA = inject(CircularDependencyA)) {} 365 | 366 | static scope = Scopes.Singleton(); 367 | } 368 | 369 | expect(() => inject(CircularDependencyA)).toThrowError(DependencyCycleError); 370 | }); 371 | 372 | it("should throw error when circular dependency is detected for multiple classes", () => { 373 | class CircularDependencyA { 374 | constructor(public instanceB = inject(CircularDependencyB)) {} 375 | 376 | static scope = Scopes.Transient(); 377 | } 378 | 379 | class CircularDependencyB { 380 | constructor(public instanceC = inject(CircularDependencyC)) {} 381 | 382 | static scope = Scopes.Transient(); 383 | } 384 | 385 | class CircularDependencyC { 386 | constructor(public instanceA = inject(CircularDependencyA)) {} 387 | 388 | static scope = Scopes.Transient(); 389 | } 390 | 391 | expect(() => inject(CircularDependencyA)).toThrowError(DependencyCycleError); 392 | 393 | expect(() => inject(CircularDependencyB)).toThrowError(DependencyCycleError); 394 | 395 | expect(() => inject(CircularDependencyC)).toThrowError(DependencyCycleError); 396 | }); 397 | }); 398 | 399 | describe("Async", () => { 400 | it("should be able to inject async", async () => { 401 | class AsyncClass { 402 | static scope = Scopes.Transient(); 403 | } 404 | 405 | const instance = await injectAsync(AsyncClass); 406 | 407 | expect(instance).toBeInstanceOf(AsyncClass); 408 | }); 409 | 410 | it("should be able to inject async for singleton scope ", async () => { 411 | class CircularDependencyA { 412 | constructor(public instanceB = inject(CircularDependencyB)) {} 413 | 414 | static scope = Scopes.Singleton(); 415 | } 416 | 417 | class CircularDependencyB { 418 | declare instanceA: CircularDependencyA; 419 | 420 | constructor(private promiseA = injectAsync(CircularDependencyA)) { 421 | this.promiseA.then((instance) => { 422 | this.instanceA = instance; 423 | }); 424 | } 425 | 426 | static scope = Scopes.Singleton(); 427 | } 428 | 429 | const instance = inject(CircularDependencyA); 430 | 431 | await globalContainer.waitAsync(); 432 | 433 | expect(instance).toBeInstanceOf(CircularDependencyA); 434 | expect(instance.instanceB).toBeInstanceOf(CircularDependencyB); 435 | expect(instance.instanceB.instanceA).toBeInstanceOf(CircularDependencyA); 436 | expect(instance.instanceB.instanceA).toBe(instance); 437 | 438 | const instance2 = inject(CircularDependencyB); 439 | 440 | await globalContainer.waitAsync(); 441 | 442 | expect(instance2).toBeInstanceOf(CircularDependencyB); 443 | expect(instance2.instanceA).toBeInstanceOf(CircularDependencyA); 444 | expect(instance2.instanceA.instanceB).toBeInstanceOf(CircularDependencyB); 445 | expect(instance2.instanceA.instanceB).toBe(instance2); 446 | }); 447 | 448 | it("should be able to inject async for singleton scope (both async)", async () => { 449 | class CircularDependencyA { 450 | public instanceB: CircularDependencyB; 451 | 452 | constructor(private promiseB = injectAsync(CircularDependencyB)) { 453 | this.promiseB.then((instance) => { 454 | this.instanceB = instance; 455 | }); 456 | } 457 | 458 | static scope = Scopes.Singleton(); 459 | } 460 | 461 | class CircularDependencyB { 462 | public instanceA: CircularDependencyA; 463 | 464 | constructor(private promiseA = injectAsync(CircularDependencyA)) { 465 | this.promiseA.then((instance) => { 466 | this.instanceA = instance; 467 | }); 468 | } 469 | 470 | static scope = Scopes.Singleton(); 471 | } 472 | 473 | const instance = inject(CircularDependencyA); 474 | 475 | await globalContainer.waitAsync(); 476 | 477 | expect(instance).toBeInstanceOf(CircularDependencyA); 478 | expect(instance.instanceB).toBeInstanceOf(CircularDependencyB); 479 | expect(instance.instanceB.instanceA).toBeInstanceOf(CircularDependencyA); 480 | expect(instance.instanceB.instanceA).toBe(instance); 481 | 482 | const instance2 = inject(CircularDependencyB); 483 | 484 | await globalContainer.waitAsync(); 485 | 486 | expect(instance2).toBeInstanceOf(CircularDependencyB); 487 | expect(instance2.instanceA).toBeInstanceOf(CircularDependencyA); 488 | expect(instance2.instanceA.instanceB).toBeInstanceOf(CircularDependencyB); 489 | expect(instance2.instanceA.instanceB).toBe(instance2); 490 | }); 491 | 492 | it("should be able to inject async for singleton scope (async cycle of 3)", async () => { 493 | class CircularDependencyA { 494 | public instanceB: CircularDependencyB; 495 | 496 | constructor(private promiseB = injectAsync(CircularDependencyB)) { 497 | this.promiseB.then((instance) => { 498 | this.instanceB = instance; 499 | }); 500 | } 501 | 502 | static scope = Scopes.Singleton(); 503 | } 504 | 505 | class CircularDependencyB { 506 | public instanceC: CircularDependencyC; 507 | 508 | constructor(private promiseC = injectAsync(CircularDependencyC)) { 509 | this.promiseC.then((instance) => { 510 | this.instanceC = instance; 511 | }); 512 | } 513 | 514 | static scope = Scopes.Singleton(); 515 | } 516 | 517 | class CircularDependencyC { 518 | public instanceA: CircularDependencyA; 519 | 520 | constructor(private promiseA = injectAsync(CircularDependencyA)) { 521 | this.promiseA.then((instance) => { 522 | this.instanceA = instance; 523 | }); 524 | } 525 | 526 | static scope = Scopes.Singleton(); 527 | } 528 | 529 | const instance = inject(CircularDependencyA); 530 | 531 | await new Promise((resolve) => setTimeout(resolve, 0)); 532 | 533 | expect(instance).toBeInstanceOf(CircularDependencyA); 534 | expect(instance.instanceB).toBeInstanceOf(CircularDependencyB); 535 | expect(instance.instanceB.instanceC).toBeInstanceOf(CircularDependencyC); 536 | expect(instance.instanceB.instanceC.instanceA).toBeInstanceOf(CircularDependencyA); 537 | 538 | expect(instance.instanceB.instanceC.instanceA).toBe(instance); 539 | expect(instance.instanceB.instanceC.instanceA.instanceB).toBe(instance.instanceB); 540 | expect(instance.instanceB.instanceC.instanceA.instanceB.instanceC).toBe( 541 | instance.instanceB.instanceC 542 | ); 543 | }); 544 | 545 | it("should be able to inject async for singleton scope (star schema)", async () => { 546 | class CircularDependencyA { 547 | public instanceB: CircularDependencyB; 548 | public instanceC: CircularDependencyC; 549 | 550 | constructor( 551 | private promiseB = injectAsync(CircularDependencyB), 552 | private promiseC = injectAsync(CircularDependencyC) 553 | ) { 554 | Promise.all([this.promiseB, this.promiseC]).then(([instanceB, instanceC]) => { 555 | this.instanceB = instanceB; 556 | this.instanceC = instanceC; 557 | }); 558 | } 559 | 560 | static scope = Scopes.Singleton(); 561 | } 562 | 563 | class CircularDependencyB { 564 | public instanceA: CircularDependencyA; 565 | public instanceC: CircularDependencyC; 566 | 567 | constructor( 568 | private promiseC = injectAsync(CircularDependencyC), 569 | private promiseA = injectAsync(CircularDependencyA) 570 | ) { 571 | Promise.all([this.promiseC, this.promiseA]).then(([instanceC, instanceA]) => { 572 | this.instanceC = instanceC; 573 | this.instanceA = instanceA; 574 | }); 575 | } 576 | 577 | static scope = Scopes.Singleton(); 578 | } 579 | 580 | class CircularDependencyC { 581 | public instanceA: CircularDependencyA; 582 | public instanceB: CircularDependencyB; 583 | 584 | constructor( 585 | private promiseA = injectAsync(CircularDependencyA), 586 | private promiseB = injectAsync(CircularDependencyB) 587 | ) { 588 | Promise.all([this.promiseA, this.promiseB]).then(([instanceA, instanceB]) => { 589 | this.instanceA = instanceA; 590 | this.instanceB = instanceB; 591 | }); 592 | } 593 | 594 | static scope = Scopes.Singleton(); 595 | } 596 | 597 | const instance = inject(CircularDependencyA); 598 | 599 | await new Promise((resolve) => setTimeout(resolve, 0)); 600 | 601 | expect(instance).toBeInstanceOf(CircularDependencyA); 602 | expect(instance.instanceB).toBeInstanceOf(CircularDependencyB); 603 | expect(instance.instanceC).toBeInstanceOf(CircularDependencyC); 604 | expect(instance.instanceB.instanceA).toBeInstanceOf(CircularDependencyA); 605 | expect(instance.instanceB.instanceC).toBeInstanceOf(CircularDependencyC); 606 | expect(instance.instanceC.instanceA).toBeInstanceOf(CircularDependencyA); 607 | expect(instance.instanceC.instanceB).toBeInstanceOf(CircularDependencyB); 608 | 609 | expect(instance.instanceC.instanceA).toBe(instance); 610 | expect(instance.instanceB.instanceA).toBe(instance); 611 | expect(instance.instanceC.instanceB).toBe(instance.instanceB); 612 | expect(instance.instanceB.instanceC).toBe(instance.instanceC); 613 | }); 614 | 615 | it("should be able to inject async for resolution scope", async () => { 616 | class CircularDependencyA { 617 | constructor(public instanceB = inject(CircularDependencyB)) {} 618 | 619 | static scope = Scopes.Resolution(); 620 | } 621 | 622 | class CircularDependencyB { 623 | declare instanceA: CircularDependencyA; 624 | 625 | constructor(private promiseA = injectAsync(CircularDependencyA)) { 626 | this.promiseA.then((instance) => { 627 | this.instanceA = instance; 628 | }); 629 | } 630 | 631 | static scope = Scopes.Resolution(); 632 | } 633 | 634 | const instance = inject(CircularDependencyA); 635 | 636 | await globalContainer.waitAsync(); 637 | 638 | expect(instance).toBeInstanceOf(CircularDependencyA); 639 | expect(instance.instanceB).toBeInstanceOf(CircularDependencyB); 640 | expect(instance.instanceB.instanceA).toBeInstanceOf(CircularDependencyA); 641 | expect(instance.instanceB.instanceA).toBe(instance); 642 | 643 | const instance2 = inject(CircularDependencyB); 644 | 645 | await globalContainer.waitAsync(); 646 | 647 | expect(instance2).toBeInstanceOf(CircularDependencyB); 648 | expect(instance2.instanceA).toBeInstanceOf(CircularDependencyA); 649 | expect(instance2.instanceA.instanceB).toBeInstanceOf(CircularDependencyB); 650 | expect(instance2.instanceA.instanceB).toBe(instance2); 651 | }); 652 | 653 | it("should be able to inject async for resolution scope (both async)", async () => { 654 | class CircularDependencyA { 655 | public instanceB: CircularDependencyB; 656 | 657 | constructor(private promiseB = injectAsync(CircularDependencyB)) { 658 | this.promiseB.then((instance) => { 659 | this.instanceB = instance; 660 | }); 661 | } 662 | 663 | static scope = Scopes.Resolution(); 664 | } 665 | 666 | class CircularDependencyB { 667 | declare instanceA: CircularDependencyA; 668 | 669 | constructor(private promiseA = injectAsync(CircularDependencyA)) { 670 | this.promiseA.then((instance) => { 671 | this.instanceA = instance; 672 | }); 673 | } 674 | 675 | static scope = Scopes.Resolution(); 676 | } 677 | 678 | const instance = inject(CircularDependencyA); 679 | 680 | await globalContainer.waitAsync(); 681 | 682 | expect(instance).toBeInstanceOf(CircularDependencyA); 683 | expect(instance.instanceB).toBeInstanceOf(CircularDependencyB); 684 | expect(instance.instanceB.instanceA).toBeInstanceOf(CircularDependencyA); 685 | expect(instance.instanceB.instanceA).toBe(instance); 686 | 687 | const instance2 = inject(CircularDependencyB); 688 | 689 | await globalContainer.waitAsync(); 690 | 691 | expect(instance2).toBeInstanceOf(CircularDependencyB); 692 | expect(instance2.instanceA).toBeInstanceOf(CircularDependencyA); 693 | expect(instance2.instanceA.instanceB).toBeInstanceOf(CircularDependencyB); 694 | expect(instance2.instanceA.instanceB).toBe(instance2); 695 | }); 696 | 697 | it("should be able to inject async for transient scope", async () => { 698 | class CircularDependencyA { 699 | constructor(public instanceB = inject(CircularDependencyB)) {} 700 | 701 | static scope = Scopes.Transient(); 702 | } 703 | 704 | class CircularDependencyB { 705 | declare instanceA: CircularDependencyA; 706 | 707 | constructor(private promiseA = injectAsync(CircularDependencyA)) { 708 | this.promiseA.then((instance) => { 709 | this.instanceA = instance; 710 | }); 711 | } 712 | 713 | static scope = Scopes.Transient(); 714 | } 715 | 716 | const instance = inject(CircularDependencyA); 717 | 718 | await globalContainer.waitAsync(); 719 | 720 | expect(instance).toBeInstanceOf(CircularDependencyA); 721 | expect(instance.instanceB).toBeInstanceOf(CircularDependencyB); 722 | expect(instance.instanceB.instanceA).toBeInstanceOf(CircularDependencyA); 723 | 724 | expect(instance.instanceB).not.toBe(instance.instanceB.instanceA.instanceB); 725 | expect(instance.instanceB.instanceA).not.toBe(instance); 726 | 727 | const instance2 = inject(CircularDependencyB); 728 | 729 | expect(instance).not.toBe(instance2); 730 | 731 | await globalContainer.waitAsync(); 732 | 733 | expect(instance2).toBeInstanceOf(CircularDependencyB); 734 | expect(instance2.instanceA).toBeInstanceOf(CircularDependencyA); 735 | expect(instance2.instanceA.instanceB).toBeInstanceOf(CircularDependencyB); 736 | expect(instance2.instanceA.instanceB).not.toBe(instance2); 737 | }); 738 | 739 | it("should be able to inject async for multiple transient classes (with unexpected loop)", async () => { 740 | class CircularDependencyA { 741 | constructor(public instanceB = inject(CircularDependencyB)) {} 742 | 743 | static scope = Scopes.Transient(); 744 | } 745 | 746 | class CircularDependencyB { 747 | constructor(public instanceC = inject(CircularDependencyC)) {} 748 | 749 | static scope = Scopes.Transient(); 750 | } 751 | 752 | class CircularDependencyC { 753 | public instanceA: CircularDependencyA; 754 | 755 | constructor(private promiseA = injectAsync(CircularDependencyA)) { 756 | this.promiseA.then((instance) => { 757 | this.instanceA = instance; 758 | }); 759 | } 760 | 761 | static scope = Scopes.Transient(); 762 | } 763 | 764 | const instance = await injectAsync(CircularDependencyA); 765 | 766 | await globalContainer.waitAsync(); 767 | 768 | expect(instance).toBeInstanceOf(CircularDependencyA); 769 | expect(instance.instanceB).toBeInstanceOf(CircularDependencyB); 770 | expect(instance.instanceB.instanceC).toBeInstanceOf(CircularDependencyC); 771 | expect(instance.instanceB.instanceC.instanceA).toBeInstanceOf(CircularDependencyA); 772 | 773 | // unexpected loops 774 | expect(instance.instanceB.instanceC.instanceA).toBe(instance); 775 | expect(instance.instanceB.instanceC.instanceA.instanceB).toBe(instance.instanceB); 776 | expect(instance.instanceB.instanceC.instanceA.instanceB.instanceC).toBe( 777 | instance.instanceB.instanceC 778 | ); 779 | }); 780 | 781 | it("should have unexpected result when trying to inject transients with async only loop", async () => { 782 | let errorA: Error | null = null; 783 | let errorB: Error | null = null; 784 | 785 | class CircularDependencyA { 786 | public instanceB: CircularDependencyB; 787 | 788 | constructor(private promiseB = injectAsync(CircularDependencyB)) { 789 | this.promiseB 790 | .then((instance) => { 791 | this.instanceB = instance; 792 | }) 793 | .catch((error) => { 794 | errorA = error; 795 | }); 796 | } 797 | 798 | static scope = Scopes.Transient(); 799 | } 800 | 801 | class CircularDependencyB { 802 | public instanceA: CircularDependencyA; 803 | 804 | constructor(private promiseA = injectAsync(CircularDependencyA)) { 805 | this.promiseA 806 | .then((instance) => { 807 | this.instanceA = instance; 808 | }) 809 | .catch((error) => { 810 | errorB = error; 811 | }); 812 | } 813 | 814 | static scope = Scopes.Transient(); 815 | } 816 | 817 | const instance = await injectAsync(CircularDependencyA); 818 | 819 | await globalContainer.waitAsync(); 820 | 821 | expect(errorA).toBeInstanceOf(AsyncDependencyCycleError); 822 | expect(errorB).toBe(null); 823 | }); 824 | 825 | it("should be able to inject async for container scope", async () => { 826 | const container = new Container(); 827 | 828 | class CircularDependencyA { 829 | constructor(public instanceB = container.inject(CircularDependencyB)) {} 830 | 831 | static scope = Scopes.Container(); 832 | } 833 | 834 | class CircularDependencyB { 835 | declare instanceA: CircularDependencyA; 836 | 837 | constructor(public promiseA = container.injectAsync(CircularDependencyA)) { 838 | promiseA.then((instance) => { 839 | this.instanceA = instance; 840 | }); 841 | } 842 | 843 | static scope = Scopes.Container(); 844 | } 845 | 846 | const instance = container.inject(CircularDependencyA); 847 | 848 | await container.waitAsync(); 849 | 850 | expect(instance).toBeInstanceOf(CircularDependencyA); 851 | expect(instance.instanceB).toBeInstanceOf(CircularDependencyB); 852 | expect(instance.instanceB.instanceA).toBe(instance); 853 | 854 | const instance2 = container.inject(CircularDependencyB); 855 | 856 | await container.waitAsync(); 857 | 858 | expect(instance2).toBeInstanceOf(CircularDependencyB); 859 | expect(instance2.instanceA).toBeInstanceOf(CircularDependencyA); 860 | expect(instance2.instanceA.instanceB).toBe(instance2); 861 | }); 862 | 863 | it("should resolve async self-dependency correctly", async () => { 864 | class CircularDependencyA { 865 | public instanceA: CircularDependencyA; 866 | 867 | constructor(private promiseA = injectAsync(CircularDependencyA)) { 868 | this.promiseA.then((instance) => { 869 | this.instanceA = instance; 870 | }); 871 | } 872 | 873 | static scope = Scopes.Transient(); 874 | } 875 | 876 | const instance = await injectAsync(CircularDependencyA); 877 | 878 | await globalContainer.waitAsync(); 879 | 880 | expect(instance).toBeInstanceOf(CircularDependencyA); 881 | expect(instance.instanceA).toBe(instance); 882 | }); 883 | }); 884 | 885 | describe("Arguments", () => { 886 | it("should be able to inject transient with arguments", () => { 887 | class ArgumentClass { 888 | constructor(public value: string) {} 889 | 890 | static scope = Scopes.Transient(); 891 | } 892 | 893 | const instance = inject(ArgumentClass, "test"); 894 | 895 | expect(instance).toBeInstanceOf(ArgumentClass); 896 | expect(instance.value).toBe("test"); 897 | }); 898 | 899 | it("should be able to inject multiple transient with arguments", () => { 900 | class ArgumentClass { 901 | constructor(public value: string) {} 902 | 903 | static scope = Scopes.Transient(); 904 | } 905 | 906 | const instance = inject(ArgumentClass, "test"); 907 | 908 | expect(instance).toBeInstanceOf(ArgumentClass); 909 | expect(instance.value).toBe("test"); 910 | 911 | const instance2 = inject(ArgumentClass, "test2"); 912 | 913 | expect(instance2).toBeInstanceOf(ArgumentClass); 914 | expect(instance2.value).toBe("test2"); 915 | }); 916 | 917 | it("should be able to inject resolution with arguments", () => { 918 | class ArgumentClass { 919 | constructor(public value: string) {} 920 | 921 | static scope = Scopes.Resolution(); 922 | } 923 | 924 | const instance = inject(ArgumentClass, "test"); 925 | 926 | expect(instance).toBeInstanceOf(ArgumentClass); 927 | expect(instance.value).toBe("test"); 928 | }); 929 | 930 | it("should cache first instance of resolution with arguments", () => { 931 | class ArgumentClass { 932 | constructor(public value: string) {} 933 | 934 | static scope = Scopes.Resolution(); 935 | } 936 | 937 | class InjectClass { 938 | constructor( 939 | public instance1 = inject(ArgumentClass, "test"), 940 | public instance2 = inject(ArgumentClass, "test2") 941 | ) {} 942 | 943 | static scope = Scopes.Transient(); 944 | } 945 | 946 | const instance = inject(InjectClass); 947 | 948 | expect(instance).toBeInstanceOf(InjectClass); 949 | 950 | expect(instance.instance1).toBeInstanceOf(ArgumentClass); 951 | expect(instance.instance1.value).toBe("test"); 952 | 953 | expect(instance.instance2).toBeInstanceOf(ArgumentClass); 954 | expect(instance.instance2.value).toBe("test"); 955 | }); 956 | 957 | it("should throw error for singleton with arguments", () => { 958 | class ArgumentClass { 959 | constructor(public value: string) {} 960 | 961 | static scope = Scopes.Singleton(); 962 | } 963 | 964 | expect(() => inject(ArgumentClass, "test")).toThrowError(ArgumentsError); 965 | }); 966 | 967 | it("should throw error for container with arguments", () => { 968 | const container = new Container(); 969 | 970 | class ArgumentClass { 971 | constructor(public value: string) {} 972 | 973 | static scope = Scopes.Container(); 974 | } 975 | 976 | expect(() => container.inject(ArgumentClass, "test")).toThrowError(ArgumentsError); 977 | }); 978 | 979 | it("should be able to inject async with arguments", async () => { 980 | class ArgumentClass { 981 | constructor(public value: string) {} 982 | 983 | static scope = Scopes.Transient(); 984 | } 985 | 986 | const instance = await injectAsync(ArgumentClass, "test"); 987 | 988 | expect(instance).toBeInstanceOf(ArgumentClass); 989 | expect(instance.value).toBe("test"); 990 | }); 991 | 992 | it("should be able to inject async with arguments (loop)", async () => { 993 | class ClassA { 994 | constructor(public number: number, public instanceB = inject(ClassB, "hello")) {} 995 | 996 | static scope = Scopes.Resolution(); 997 | } 998 | 999 | class ClassB { 1000 | public instanceA: ClassA; 1001 | 1002 | constructor( 1003 | public value: string, 1004 | aPromise: Promise = injectAsync(ClassA, 123) 1005 | ) { 1006 | aPromise.then((instance) => { 1007 | this.instanceA = instance; 1008 | }); 1009 | } 1010 | 1011 | static scope = Scopes.Transient(); 1012 | } 1013 | 1014 | const instanceB = inject(ClassB, "test"); 1015 | 1016 | await globalContainer.waitAsync(); 1017 | 1018 | expect(instanceB).toBeInstanceOf(ClassB); 1019 | expect(instanceB.value).toBe("test"); 1020 | 1021 | expect(instanceB.instanceA).toBeInstanceOf(ClassA); 1022 | expect(instanceB.instanceA.number).toBe(123); 1023 | }); 1024 | }); 1025 | 1026 | describe(".register", () => { 1027 | it("should be able to register class", () => { 1028 | class RegisterClass { 1029 | constructor() {} 1030 | 1031 | static scope = Scopes.Transient(); 1032 | } 1033 | 1034 | globalContainer.register({ class: RegisterClass }); 1035 | 1036 | const instance = inject(RegisterClass); 1037 | 1038 | expect(instance).toBeInstanceOf(RegisterClass); 1039 | }); 1040 | 1041 | it("should throw when invalid descriptor is injected", () => { 1042 | const token = new Token(); 1043 | 1044 | // @ts-expect-error 1045 | globalContainer.register({ token, something: "invalid" }); 1046 | 1047 | expect(() => inject(token)).toThrowError(); 1048 | }); 1049 | 1050 | it("should use registration scope if provided", () => { 1051 | class RegisterClass { 1052 | constructor() {} 1053 | 1054 | static scope = Scopes.Transient(); 1055 | } 1056 | 1057 | globalContainer.register({ class: RegisterClass, scope: Scopes.Singleton() }); 1058 | 1059 | const instance = inject(RegisterClass); 1060 | const instance2 = inject(RegisterClass); 1061 | 1062 | expect(instance).toBe(instance2); 1063 | }); 1064 | 1065 | it("should use class scope if registration scope is not provided", () => { 1066 | class RegisterClass { 1067 | constructor() {} 1068 | 1069 | static scope = Scopes.Singleton(); 1070 | } 1071 | 1072 | globalContainer.register({ class: RegisterClass }); 1073 | 1074 | const instance = inject(RegisterClass); 1075 | const instance2 = inject(RegisterClass); 1076 | 1077 | expect(instance).toBe(instance2); 1078 | }); 1079 | 1080 | describe("Token injection", () => { 1081 | let container = new Container(null, "parent"); 1082 | 1083 | beforeEach(() => { 1084 | container = new Container(null, "parent"); 1085 | }); 1086 | 1087 | describe("Class Tokens", () => { 1088 | it("should be able to inject token", () => { 1089 | class TokenClass { 1090 | constructor() {} 1091 | 1092 | static scope = Scopes.Transient(); 1093 | } 1094 | 1095 | const token = new Token(); 1096 | 1097 | container.register({ token, class: TokenClass }); 1098 | 1099 | const instance = container.inject(token); 1100 | 1101 | expect(instance).toBeInstanceOf(TokenClass); 1102 | }); 1103 | 1104 | it("should be able to inject token with arguments", () => { 1105 | class TokenClass { 1106 | constructor(public value: string) {} 1107 | 1108 | static scope = Scopes.Transient(); 1109 | } 1110 | 1111 | const token = new Token(); 1112 | 1113 | container.register({ token, class: TokenClass }); 1114 | 1115 | const instance = container.inject(token, "test"); 1116 | 1117 | expect(instance).toBeInstanceOf(TokenClass); 1118 | expect(instance.value).toBe("test"); 1119 | }); 1120 | 1121 | it("should throw error when token is not registered", () => { 1122 | const token = new Token(); 1123 | 1124 | expect(() => container.inject(token)).toThrowError(); 1125 | }); 1126 | 1127 | it("should be able to inject token from base class", () => { 1128 | class TokenClass { 1129 | static scope = Scopes.Container(); 1130 | } 1131 | 1132 | const token = new Token(); 1133 | 1134 | container.register({ token, class: TokenClass }); 1135 | 1136 | const childContainer = container.childContainer("child"); 1137 | 1138 | const instance = childContainer.inject(token); 1139 | 1140 | const instance2 = container.inject(token); 1141 | 1142 | expect(instance).toBeInstanceOf(TokenClass); 1143 | 1144 | expect(instance2).toBe(instance); 1145 | 1146 | container.unregister(token); 1147 | 1148 | const instance3 = childContainer.inject(TokenClass); 1149 | 1150 | expect(instance3).toBeInstanceOf(TokenClass); 1151 | 1152 | expect(instance3).not.toBe(instance); 1153 | }); 1154 | 1155 | it("should be able to inject registered class", () => { 1156 | class RegisterClass { 1157 | constructor() {} 1158 | 1159 | static scope = Scopes.Container(); 1160 | } 1161 | 1162 | container.register({ class: RegisterClass }); 1163 | 1164 | const instance = container.inject(RegisterClass); 1165 | 1166 | expect(instance).toBeInstanceOf(RegisterClass); 1167 | }); 1168 | 1169 | it("should be able to inject registered class on parent container", () => { 1170 | class RegisterClass { 1171 | constructor() {} 1172 | 1173 | static scope = Scopes.Container(); 1174 | } 1175 | 1176 | container.register({ class: RegisterClass }); 1177 | 1178 | const childContainer = container.childContainer("child"); 1179 | 1180 | const instance = childContainer.inject(RegisterClass); 1181 | 1182 | expect(instance).toBeInstanceOf(RegisterClass); 1183 | 1184 | const instance2 = container.inject(RegisterClass); 1185 | 1186 | expect(instance2).toBe(instance); 1187 | 1188 | container.unregister(RegisterClass); 1189 | 1190 | const instance3 = childContainer.inject(RegisterClass); 1191 | 1192 | expect(instance3).toBeInstanceOf(RegisterClass); 1193 | 1194 | expect(instance3).not.toBe(instance); 1195 | }); 1196 | 1197 | it("should be able to inject token in async loop", async () => { 1198 | class A { 1199 | constructor(public instanceB = container.inject(B)) {} 1200 | 1201 | static scope = Scopes.Container(); 1202 | } 1203 | 1204 | class B { 1205 | declare instanceA: A; 1206 | 1207 | constructor(private promiseA = container.injectAsync(A)) { 1208 | this.promiseA.then((instance) => { 1209 | this.instanceA = instance; 1210 | }); 1211 | } 1212 | 1213 | static scope = Scopes.Container(); 1214 | } 1215 | 1216 | const tokenA = new Token(); 1217 | const tokenB = new Token(); 1218 | 1219 | container.register({ token: tokenA, class: A }); 1220 | container.register({ token: tokenB, class: B }); 1221 | 1222 | const instance = container.inject(tokenA); 1223 | 1224 | expect(instance).toBeInstanceOf(A); 1225 | 1226 | await container.waitAsync(); 1227 | 1228 | expect(instance.instanceB).toBeInstanceOf(B); 1229 | expect(instance.instanceB.instanceA).toBeInstanceOf(A); 1230 | expect(instance.instanceB.instanceA).toBe(instance); 1231 | 1232 | const instance2 = container.inject(tokenB); 1233 | 1234 | expect(instance2).toBeInstanceOf(B); 1235 | 1236 | await container.waitAsync(); 1237 | 1238 | expect(instance2.instanceA).toBeInstanceOf(A); 1239 | expect(instance2.instanceA.instanceB).toBeInstanceOf(B); 1240 | expect(instance2.instanceA.instanceB).toBe(instance2); 1241 | }); 1242 | 1243 | it("should be able to injectAsync token in async loop", async () => { 1244 | class A { 1245 | constructor(public instanceB = container.inject(B)) {} 1246 | 1247 | static scope = Scopes.Container(); 1248 | } 1249 | 1250 | class B { 1251 | declare instanceA: A; 1252 | 1253 | constructor(private promiseA = container.injectAsync(A)) { 1254 | this.promiseA.then((instance) => { 1255 | this.instanceA = instance; 1256 | }); 1257 | } 1258 | 1259 | static scope = Scopes.Container(); 1260 | } 1261 | 1262 | const tokenA = new Token(); 1263 | const tokenB = new Token(); 1264 | 1265 | container.register({ token: tokenA, class: A }); 1266 | container.register({ token: tokenB, class: B }); 1267 | 1268 | const instance = await container.injectAsync(tokenA); 1269 | 1270 | expect(instance).toBeInstanceOf(A); 1271 | 1272 | await container.waitAsync(); 1273 | 1274 | expect(instance.instanceB).toBeInstanceOf(B); 1275 | expect(instance.instanceB.instanceA).toBeInstanceOf(A); 1276 | expect(instance.instanceB.instanceA).toBe(instance); 1277 | 1278 | const instance2 = await container.injectAsync(tokenB); 1279 | 1280 | expect(instance2).toBeInstanceOf(B); 1281 | 1282 | await container.waitAsync(); 1283 | 1284 | expect(instance2.instanceA).toBeInstanceOf(A); 1285 | expect(instance2.instanceA.instanceB).toBeInstanceOf(B); 1286 | expect(instance2.instanceA.instanceB).toBe(instance2); 1287 | }); 1288 | 1289 | it("should be able to inject token in async loop", async () => { 1290 | class A { 1291 | constructor(public instanceB = container.inject(tokenB)) {} 1292 | 1293 | static scope = Scopes.Container(); 1294 | } 1295 | 1296 | class B { 1297 | declare instanceA: A; 1298 | 1299 | constructor(private promiseA = container.injectAsync(tokenA)) { 1300 | promiseA.then((instance) => { 1301 | this.instanceA = instance; 1302 | }); 1303 | } 1304 | 1305 | static scope = Scopes.Container(); 1306 | } 1307 | 1308 | const tokenA = new Token(); 1309 | const tokenB = new Token(); 1310 | 1311 | container.register({ token: tokenA, class: A }); 1312 | container.register({ token: tokenB, class: B }); 1313 | 1314 | const instance = container.inject(tokenA); 1315 | 1316 | expect(instance).toBeInstanceOf(A); 1317 | 1318 | await container.waitAsync(); 1319 | 1320 | expect(instance.instanceB).toBeInstanceOf(B); 1321 | expect(instance.instanceB.instanceA).toBeInstanceOf(A); 1322 | expect(instance.instanceB.instanceA).toBe(instance); 1323 | }); 1324 | 1325 | it("should get the same instance of inject token and class", () => { 1326 | class TokenClass { 1327 | constructor() {} 1328 | 1329 | static scope = Scopes.Container(); 1330 | } 1331 | 1332 | const token = new Token(); 1333 | 1334 | container.register({ token, class: TokenClass }); 1335 | 1336 | const instance = container.inject(token); 1337 | const instance2 = container.inject(TokenClass); 1338 | 1339 | expect(instance).toBe(instance2); 1340 | }); 1341 | 1342 | it("should unregister token", () => { 1343 | class TokenClass { 1344 | constructor() {} 1345 | 1346 | static scope = Scopes.Container(); 1347 | } 1348 | 1349 | const token = new Token(); 1350 | 1351 | container.register({ token, class: TokenClass }); 1352 | 1353 | const instance = container.inject(token); 1354 | 1355 | expect(instance).toBeInstanceOf(TokenClass); 1356 | 1357 | container.unregister(token); 1358 | 1359 | expect(() => container.inject(token)).toThrowError(); 1360 | }); 1361 | 1362 | it("should unregister token from parent container", () => { 1363 | class TokenClass { 1364 | constructor() {} 1365 | 1366 | static scope = Scopes.Container(); 1367 | } 1368 | 1369 | const token = new Token(); 1370 | 1371 | container.register({ token, class: TokenClass }); 1372 | 1373 | const childContainer = container.childContainer("child"); 1374 | 1375 | const instance = childContainer.inject(token); 1376 | 1377 | expect(instance).toBeInstanceOf(TokenClass); 1378 | 1379 | container.unregister(token); 1380 | 1381 | expect(() => childContainer.inject(token)).toThrowError(); 1382 | }); 1383 | }); 1384 | 1385 | describe("Value Tokens", () => { 1386 | it("should be able to inject token with value", () => { 1387 | const token = new Token(); 1388 | 1389 | container.register({ token, value: "test" }); 1390 | 1391 | const value = container.inject(token); 1392 | 1393 | expect(value).toBe("test"); 1394 | }); 1395 | 1396 | it("should be able to inject token with value (object)", () => { 1397 | const token = new Token<{ value: string }>(); 1398 | 1399 | const value = { value: "test" }; 1400 | 1401 | container.register({ token, value }); 1402 | 1403 | const injected = container.inject(token); 1404 | 1405 | expect(injected).toBe(value); 1406 | }); 1407 | 1408 | it("should be able to inject token with value from parent container", () => { 1409 | const token = new Token(); 1410 | 1411 | container.register({ token, value: "test" }); 1412 | 1413 | const childContainer = container.childContainer("child"); 1414 | 1415 | const value = childContainer.inject(token); 1416 | 1417 | expect(value).toBe("test"); 1418 | }); 1419 | 1420 | it("should be able to unregister value token", () => { 1421 | const token = new Token(); 1422 | 1423 | container.register({ token, value: "test" }); 1424 | 1425 | const value = container.inject(token); 1426 | 1427 | expect(value).toBe("test"); 1428 | 1429 | container.unregister(token); 1430 | 1431 | expect(() => container.inject(token)).toThrowError(); 1432 | }); 1433 | }); 1434 | 1435 | describe("Factory Tokens", () => { 1436 | it("should be able to inject token with factory", () => { 1437 | const token = new Token(); 1438 | 1439 | container.register({ token, factory: () => "test" }); 1440 | 1441 | const value = container.inject(token); 1442 | 1443 | expect(value).toBe("test"); 1444 | }); 1445 | 1446 | it("should be able to inject token with factory (object)", () => { 1447 | const token = new Token<{ value: string }>(); 1448 | 1449 | const value = { value: "test" }; 1450 | 1451 | container.register({ token, factory: () => value }); 1452 | 1453 | const injected = container.inject(token); 1454 | 1455 | expect(injected).toBe(value); 1456 | }); 1457 | 1458 | it("should be able to inject token with factory from parent container", () => { 1459 | const token = new Token(); 1460 | 1461 | container.register({ token, factory: () => "test" }); 1462 | 1463 | const childContainer = container.childContainer("child"); 1464 | 1465 | const value = childContainer.inject(token); 1466 | 1467 | expect(value).toBe("test"); 1468 | }); 1469 | 1470 | it("should be able to inject token with factory with arguments", () => { 1471 | const token = new Token(); 1472 | 1473 | container.register({ token, factory: (container, value: string) => value }); 1474 | 1475 | const value = container.inject(token, "test"); 1476 | 1477 | expect(value).toBe("test"); 1478 | }); 1479 | 1480 | it("should be able to inject token with factory with arguments from parent container", () => { 1481 | const token = new Token(); 1482 | 1483 | container.register({ token, factory: (container, value: string) => value }); 1484 | 1485 | const childContainer = container.childContainer("child"); 1486 | 1487 | const value = childContainer.inject(token, "test"); 1488 | 1489 | expect(value).toBe("test"); 1490 | }); 1491 | 1492 | it("should be able to unregister factory token", () => { 1493 | const token = new Token(); 1494 | 1495 | container.register({ token, factory: () => "test" }); 1496 | 1497 | const value = container.inject(token); 1498 | 1499 | expect(value).toBe("test"); 1500 | 1501 | container.unregister(token); 1502 | 1503 | expect(() => container.inject(token)).toThrowError(); 1504 | }); 1505 | 1506 | it("should be able to inject factory when factory injects something else", () => { 1507 | class TokenClass { 1508 | constructor() {} 1509 | 1510 | static scope = Scopes.Container(); 1511 | } 1512 | 1513 | // TODO: fix types 1514 | const token = new Token(); 1515 | 1516 | container.register({ 1517 | token, 1518 | factory: (container) => container.inject(TokenClass), 1519 | }); 1520 | 1521 | const value = container.inject(token); 1522 | 1523 | expect(value).toBeInstanceOf(TokenClass); 1524 | }); 1525 | 1526 | it("should throw error when there is a circular dependency", () => { 1527 | const token = new Token(); 1528 | 1529 | container.register({ 1530 | token, 1531 | factory: (container, value: string) => container.inject(token), 1532 | }); 1533 | 1534 | expect(() => container.inject(token, "test")).toThrowError( 1535 | DependencyCycleError 1536 | ); 1537 | }); 1538 | }); 1539 | 1540 | describe("beforeInject", () => { 1541 | it("should be able to use beforeInject for class injection with token", () => { 1542 | class TokenClass { 1543 | constructor(public value: string) {} 1544 | 1545 | static scope = Scopes.Transient(); 1546 | } 1547 | 1548 | const token = new Token(); 1549 | 1550 | let called = false; 1551 | let containerArg: Container | null = null; 1552 | let descriptorArg: AnyDescriptor | null = null; 1553 | let argsArg: any[] | null = null; 1554 | 1555 | container.register({ 1556 | token, 1557 | class: TokenClass, 1558 | beforeInject: (container, descriptor, args) => { 1559 | called = true; 1560 | containerArg = container; 1561 | descriptorArg = descriptor; 1562 | argsArg = args; 1563 | }, 1564 | }); 1565 | 1566 | const instance = container.inject(token, "test"); 1567 | 1568 | expect(called).toBe(true); 1569 | expect(containerArg).toBe(container); 1570 | // @ts-expect-error 1571 | expect(descriptorArg.class).toBe(TokenClass); 1572 | expect(argsArg).toEqual(["test"]); 1573 | }); 1574 | 1575 | it("should be able to use beforeInject for class injection with class", () => { 1576 | class TokenClass { 1577 | constructor(public value: string) {} 1578 | 1579 | static scope = Scopes.Transient(); 1580 | } 1581 | 1582 | let called = false; 1583 | let containerArg: Container | null = null; 1584 | let descriptorArg: AnyDescriptor | null = null; 1585 | let argsArg: any[] | null = null; 1586 | 1587 | container.register({ 1588 | class: TokenClass, 1589 | beforeInject: (container, descriptor, args) => { 1590 | called = true; 1591 | containerArg = container; 1592 | descriptorArg = descriptor; 1593 | argsArg = args; 1594 | }, 1595 | }); 1596 | 1597 | const instance = container.inject(TokenClass, "test"); 1598 | 1599 | expect(called).toBe(true); 1600 | expect(containerArg).toBe(container); 1601 | // @ts-expect-error 1602 | expect(descriptorArg.class).toBe(TokenClass); 1603 | expect(argsArg).toEqual(["test"]); 1604 | }); 1605 | 1606 | it("should be able to use beforeInject for value injection", () => { 1607 | const token = new Token(); 1608 | 1609 | let called = false; 1610 | let containerArg: Container | null = null; 1611 | let descriptorArg: AnyDescriptor | null = null; 1612 | let argsArg: any[] | null = null; 1613 | 1614 | container.register({ 1615 | token, 1616 | value: "test", 1617 | beforeInject: (container, descriptor, args) => { 1618 | called = true; 1619 | containerArg = container; 1620 | descriptorArg = descriptor; 1621 | argsArg = args; 1622 | }, 1623 | }); 1624 | 1625 | const value = container.inject(token); 1626 | 1627 | expect(called).toBe(true); 1628 | expect(containerArg).toBe(container); 1629 | // @ts-expect-error 1630 | expect(descriptorArg.value).toBe("test"); 1631 | expect(argsArg).toEqual([]); 1632 | }); 1633 | 1634 | it("should be able to use beforeInject for factory injection", () => { 1635 | const token = new Token(); 1636 | 1637 | let called = false; 1638 | let containerArg: Container | null = null; 1639 | let descriptorArg: AnyDescriptor | null = null; 1640 | let argsArg: any[] | null = null; 1641 | 1642 | container.register({ 1643 | token, 1644 | factory: (container, a: string) => a + "!", 1645 | beforeInject: (container, descriptor, args) => { 1646 | called = true; 1647 | containerArg = container; 1648 | descriptorArg = descriptor; 1649 | argsArg = args; 1650 | }, 1651 | }); 1652 | 1653 | const value = container.inject(token, "test"); 1654 | 1655 | expect(called).toBe(true); 1656 | expect(containerArg).toBe(container); 1657 | // @ts-expect-error 1658 | expect(descriptorArg.factory).toBeDefined(); 1659 | expect(argsArg).toEqual(["test"]); 1660 | }); 1661 | }); 1662 | 1663 | describe("beforeConstruct", () => { 1664 | it("should be able to use beforeConstruct for class injection (transient scope)", () => { 1665 | class TokenClass { 1666 | constructor(public value: string) {} 1667 | 1668 | static scope = Scopes.Transient(); 1669 | } 1670 | 1671 | let called = false; 1672 | let containerArg: Container | null = null; 1673 | let descriptorArg: AnyDescriptor | null = null; 1674 | let argsArg: any[] | null = null; 1675 | 1676 | container.register({ 1677 | class: TokenClass, 1678 | beforeCreate: (container, descriptor, args) => { 1679 | called = true; 1680 | containerArg = container; 1681 | descriptorArg = descriptor; 1682 | argsArg = args; 1683 | }, 1684 | }); 1685 | 1686 | const instance = container.inject(TokenClass, "test"); 1687 | 1688 | expect(called).toBe(true); 1689 | expect(containerArg).toBe(container); 1690 | // @ts-expect-error 1691 | expect(descriptorArg.class).toBe(TokenClass); 1692 | expect(argsArg).toEqual(["test"]); 1693 | 1694 | const instance2 = container.inject(TokenClass, "test2"); 1695 | expect(instance2).not.toBe(instance); 1696 | expect(argsArg).toEqual(["test2"]); 1697 | }); 1698 | 1699 | it("should be able to use beforeConstruct for class injection (singleton scope)", () => { 1700 | class TokenClass { 1701 | constructor(public value: string) {} 1702 | 1703 | static scope = Scopes.Singleton(); 1704 | } 1705 | 1706 | let called = 0; 1707 | let containerArg: Container | null = null; 1708 | let descriptorArg: AnyDescriptor | null = null; 1709 | let argsArg: any[] | null = null; 1710 | 1711 | container.register({ 1712 | class: TokenClass, 1713 | beforeCreate: (container, descriptor, args) => { 1714 | called += 1; 1715 | containerArg = container; 1716 | descriptorArg = descriptor; 1717 | argsArg = args; 1718 | }, 1719 | }); 1720 | 1721 | const instance = container.inject(TokenClass); 1722 | 1723 | expect(called).toBe(1); 1724 | expect(containerArg).toBe(globalContainer); 1725 | // @ts-expect-error 1726 | expect(descriptorArg.class).toBe(TokenClass); 1727 | expect(argsArg).toEqual([]); 1728 | 1729 | const instance2 = container.inject(TokenClass); 1730 | expect(instance2).toBe(instance); 1731 | expect(called).toBe(1); 1732 | }); 1733 | 1734 | it("should be able to use beforeConstruct for class injection (container scope)", () => { 1735 | class TokenClass { 1736 | constructor(public value: string) {} 1737 | 1738 | static scope = Scopes.Container(); 1739 | } 1740 | 1741 | let called = 0; 1742 | let containerArg: Container | null = null; 1743 | let descriptorArg: AnyDescriptor | null = null; 1744 | let argsArg: any[] | null = null; 1745 | 1746 | container.register({ 1747 | class: TokenClass, 1748 | beforeCreate: (container, descriptor, args) => { 1749 | called += 1; 1750 | containerArg = container; 1751 | descriptorArg = descriptor; 1752 | argsArg = args; 1753 | }, 1754 | }); 1755 | 1756 | const instance = container.inject(TokenClass); 1757 | 1758 | expect(called).toBe(1); 1759 | expect(containerArg).toBe(container); 1760 | // @ts-expect-error 1761 | expect(descriptorArg.class).toBe(TokenClass); 1762 | expect(argsArg).toEqual([]); 1763 | 1764 | const instance2 = container.inject(TokenClass); 1765 | expect(instance2).toBe(instance); 1766 | expect(called).toBe(1); 1767 | }); 1768 | 1769 | it("should be able to use beforeConstruct for class injection (resolution scope)", () => { 1770 | class TokenClass { 1771 | constructor(public value: string) {} 1772 | 1773 | static scope = Scopes.Resolution(); 1774 | } 1775 | 1776 | let called = 0; 1777 | let containerArg: Container | null = null; 1778 | let descriptorArg: AnyDescriptor | null = null; 1779 | let argsArg: any[] | null = null; 1780 | 1781 | container.register({ 1782 | class: TokenClass, 1783 | beforeCreate: (container, descriptor, args) => { 1784 | called += 1; 1785 | containerArg = container; 1786 | descriptorArg = descriptor; 1787 | argsArg = args; 1788 | }, 1789 | }); 1790 | 1791 | const instance = container.inject(TokenClass, "test"); 1792 | 1793 | expect(called).toBe(1); 1794 | expect(containerArg).toBeInstanceOf(Container); // child resolution container is expected 1795 | expect(containerArg).not.toBe(container); 1796 | // @ts-expect-error 1797 | expect(descriptorArg.class).toBe(TokenClass); 1798 | expect(argsArg).toEqual(["test"]); 1799 | 1800 | const instance2 = container.inject(TokenClass, "test2"); 1801 | expect(instance2).not.toBe(instance); 1802 | expect(argsArg).toEqual(["test2"]); 1803 | }); 1804 | }); 1805 | }); 1806 | }); 1807 | }); 1808 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "strict": true, 5 | "moduleResolution": "node", 6 | "sourceMap": true 7 | }, 8 | "exclude": ["node_modules", "dist", "test"] 9 | } 10 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import { resolve } from "path"; 2 | import { defineConfig } from "vite"; 3 | import dts from "vite-plugin-dts"; 4 | 5 | export default defineConfig({ 6 | plugins: [dts({ rollupTypes: true })], 7 | build: { 8 | lib: { 9 | // Could also be a dictionary or array of multiple entry points 10 | entry: resolve(__dirname, "src/index.ts"), 11 | name: "dioma", 12 | // the proper extensions will be added 13 | fileName: "dioma", 14 | formats: ["umd", "es", "cjs"], 15 | }, 16 | }, 17 | }); 18 | --------------------------------------------------------------------------------