├── .github
└── workflows
│ └── main.yml
├── .gitignore
├── .npmignore
├── .prettierrc
├── README.MD
├── lib
├── cache.module.ts
├── cache.service.ts
├── cache.ts
├── constants.ts
├── default.storage.ts
├── guard.ts
├── index.ts
├── test
│ ├── cache.decorator.ts
│ ├── controller.ts
│ ├── in-memory.e2e.test.ts
│ ├── runner.ts
│ ├── service.ts
│ └── util.ts
├── time.constants.ts
└── types.ts
├── package-lock.json
├── package.json
└── tsconfig.json
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: Omacahce Package
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 |
8 | jobs:
9 | build:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: actions/checkout@v4
13 | - uses: actions/setup-node@v4
14 | with:
15 | node-version: 20
16 | - run: npm ci
17 | - run: npm test
18 |
19 | publish-npm:
20 | needs: build
21 | runs-on: ubuntu-latest
22 | environment: publish
23 | steps:
24 | - uses: actions/checkout@v4
25 | - uses: actions/setup-node@v4
26 | with:
27 | node-version: 20
28 | registry-url: https://registry.npmjs.org/
29 | - run: npm ci
30 | - run: npm publish
31 | - run: npm run build
32 | env:
33 | NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
34 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | test.*
4 | .idea
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | lib
2 | **/test
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BJS-kr/nestjs-omacache/21eed8497e2f75cd12c6d335b6824d10aabc2dc5/.prettierrc
--------------------------------------------------------------------------------
/README.MD:
--------------------------------------------------------------------------------
1 | # NestJS-Omacache
2 |
3 |
4 |
5 |
6 | by talented designer, kdh0178@gmail.com
7 |
8 |
9 | ## Motivation
10 |
11 | Nest's cache-manager has limitations and inconveniences(i.e. cache decorator applied for controller only).
12 | this problem arises from the fact that @nestjs/cache-manager implements features using interceptor, so its capabilities limited within interceptor's.
13 |
14 | This package provides you full capabilities for most caching strategy on server.
15 |
16 | 1. can be applied to both controllers and services(Injectable)
17 | 2. set-on-start caching(persistent, and can be refreshed)
18 | 3. other utilites (i.e. cache invalidation with related caches)
19 |
20 | Cache option type automatically switched by 'kind' option(persistent or temporal)
21 |
22 | ## Usage
23 |
24 | ### Import CacheModule
25 |
26 | ```typescript
27 | // root module
28 | import { CacheModule } from 'nestjs-omacache'
29 |
30 | @Module({
31 | // this import enables set-on-start caching
32 | imports: [CacheModule],
33 | ...
34 | })
35 | export class AppModule {}
36 | ```
37 |
38 | ### Build your own Cache Decorator with storage
39 |
40 | ```typescript
41 | // imported 'Cache' is factory to receive storage that implements ICacheStorage
42 | import { Cache, ICacheStorage } from "nestjs-omacache";
43 |
44 | // for example, we can use redis for storage
45 | // What ever your implementation is, it must satisfies ICacheStorage interface.
46 | // set() ttl param is optional, but implementing signature including ttl is strongly recommended
47 | class RedisStorage implements ICacheStorage {
48 | get(key: string) {...}
49 | set(key: string, val: any, ttl: number) {...}
50 | has(key: string) {...}
51 | delete(key: string) {...}
52 | }
53 |
54 | // Then you can make External Redis Cache!
55 | const ExternalCache = Cache({ storage: new RedisStorage() })
56 |
57 | // ...or
58 | // you can just initialize it using default storage(in-memory cache)
59 | // default storage is based on lru-cache package, so it can handle TTL and cache eviction
60 | // default max size is 10000
61 | // make sure you are not making memory overhead by using default in-memory storage
62 | const InMemoryCache = Cache();
63 |
64 | // you can implement your custom in-memory cache, which is more configurable.
65 | ```
66 |
67 | ### Use it anywhere
68 |
69 | ```typescript
70 | // regardless class is Controller or Injectable, you can use produced cache decorator
71 | @Controller()
72 | class AppController {
73 | @Get()
74 | @ExternalCache({
75 | // persistent cache also needs key to control cache internally
76 | key: 'some key',
77 | // persistent cache sets cache automatically on server start
78 | kind: 'persistent',
79 | // refresh interval is optional
80 | // use it if you want cache refreshing
81 | refreshIntervalSec: 60 * 60 * 3 // 3 hours
82 | })
83 | async noParameterMethod() {
84 | ...
85 | }
86 |
87 | @Get('/:id')
88 | @ExternalCache({
89 | key: 'other key',
90 | kind: 'temporal',
91 | ttl: 10 * MIN, // 10 mins
92 | // You have to specify parameter indexes which will be referenced dynamically
93 | // In this case, cache key will be concatenated string of key, id param, q2 query
94 | paramIndex: [0, 2]
95 | })
96 | async haveParametersMethod(
97 | @Param('id') id: number,
98 | // q1 will not affect cache key because paramIndex is specified to refer param index 0 and 2
99 | @Query('query_1') q1: string,
100 | @Query('query_2') q2: string
101 | ) {
102 | ...
103 | }
104 | }
105 | ```
106 |
107 | ### Partial Caching
108 |
109 | #### partial caching is particularly useful when an operation combined with cacheable and not cacheable jobs
110 |
111 | ```typescript
112 | // let's say SomeService have three methods: taskA, taskB, taskC
113 | // assume that taskA and taskC can be cached, but taskB not
114 | // each of task takes 1 second to complete
115 |
116 | // in this scenario, @Nestjs/cache-manager can't handle caching because it's stick with interceptor
117 | // but we can cover this case using partial caching
118 | @Injectable()
119 | class SomeService {
120 |
121 | @InMemoryCache(...)
122 | taskA() {} // originally takes 1 second
123 |
124 | // not cacheable
125 | taskB() {} // takes 1 second
126 |
127 | @InMemoryCache(...)
128 | taskC() {} // originally takes 1 second
129 | }
130 |
131 |
132 | @Controller()
133 | class SomeController {
134 | constructor(
135 | private someService: SomeService
136 | ) {}
137 |
138 | // this route can take slightest time because taskA and taskC is partially cached
139 | // execution time can be reduced 3 seconds to 1 second
140 | @Get()
141 | route1() {
142 | someService.taskA(); // takes no time
143 | someService.taskB(); // still takes 1 second
144 | someService.taskC(); // takes no time
145 | }
146 | }
147 | ```
148 |
149 | ### Cache Busting
150 |
151 | ```typescript
152 | // we need to set same key to set & unset cache
153 | // keep in mind that cache control by parameters is supported for temporal cache only
154 | @Controller()
155 | class SomeController {
156 | @Get()
157 | @InMemoryCache({
158 | key: 'hello',
159 | kind: 'persistent',
160 | })
161 | getSomethingHeavy() {
162 | ...
163 | }
164 |
165 | @Put()
166 | // in this case, we are busting persistent cache
167 | // after busting persistent cache, when busting method is done,
168 | // persistent cached method(getSomethingHeavy in this case) will invoked immediately
169 | // so you can still get the updated cache from persistent cache route!
170 | @InMemoryCache({
171 | key: 'hello',
172 | kind: 'bust',
173 | })
174 | updateSomethingHeavy() {
175 | ...
176 | }
177 |
178 |
179 | // this route sets cache for key 'some'
180 | @Get('/some')
181 | @InMemoryCache({
182 | key: 'some',
183 | kind:'temporal',
184 | ttl: 30 * SECOND, // 30 seconds
185 | })
186 | getSome() {
187 | ...
188 | }
189 |
190 | // and this route will unset cache for key 'some', before the 'some' cache's ttl expires
191 | @Patch('/some')
192 | @InMemoryCache({
193 | key: 'some',
194 | kind: 'bust',
195 | })
196 | updateSome() {
197 | ...
198 | }
199 |
200 | // above operation also can handle parameter based cache
201 | @Get('/:p1/:p2')
202 | @ExternalCache({
203 | key: 'some',
204 | kind:'temporal',
205 | ttl: 30 * SECOND, // 30 seconds
206 | paramIndex: [0, 1]
207 | })
208 | getSomeOther(@Param('p1') p1: string, @Param('p2') p2: string) {
209 | ...
210 | }
211 |
212 | // will unset cache of some + p1 + p2
213 | @Patch('/:p1/:p2')
214 | @ExternalCache({
215 | key: 'some',
216 | kind: 'bust',
217 | paramIndex: [0, 1]
218 | })
219 | updateSomeOther(@Param('p1') p1: string, @Param('p2') p2: string) {
220 | ...
221 | }
222 |
223 | // if you want to unset all cache based on a key, you can use bustAllChildren option.
224 | // this will only work for temporal cache.
225 | @Get('/foo')
226 | @ExternalCache({
227 | key: 'foo',
228 | kind: 'temporal',
229 | ttl: 30 * SECOND,
230 | })
231 | getFoo() {
232 | ...
233 | }
234 |
235 | @Get('foo/:p1/:p2')
236 | @ExternalCache({
237 | key: 'foo',
238 | kind: 'temporal',
239 | ttl: 30 * SECOND,
240 | paramIndex: [0, 1]
241 | })
242 | getFooOther(@Param('p1') p1: string, @Param('p2') p2: string) {
243 | ...
244 | }
245 |
246 | @Patch('/foo')
247 | @ExternalCache({
248 | key: 'foo',
249 | kind: 'bust',
250 | bustAllChildren: true
251 | })
252 | updateFoo() {
253 | ...
254 | }
255 | }
256 | ```
257 |
258 | #### Additional Busting within one route
259 |
260 | In many cases, change to a single data affects multiple outputs. For example, if you modify "User" data, you have to remove caches of "User", "MyPage", "Friends". So, Omacache provide capability to remove all related caches at once.
261 |
262 | ```typescript
263 | @Put("/users/:userId")
264 | @InMemoryCache({
265 | kind: "bust",
266 | key: "user",
267 | paramIndex:[0],
268 | // additional bustings
269 | // It's same type of "bust" but except kind & addition
270 | addition: [
271 | {
272 | key: "my_page",
273 | // this would not remove cache if
274 | // route that sets "my_page" cache construct cache key with different parameter poisition
275 | paramIndex:[0]
276 | },
277 | {
278 | key: "friends",
279 | bustAllChildren: true
280 | }
281 | ]
282 | })
283 | modifyUser(@Param("userId") userId: string, @Body() body: any) {
284 | ...
285 | }
286 | ```
287 |
288 | ## Caution
289 |
290 | 1. persistent cache must used on method without parameters, otherwise, it will throw error that presents persistent cache cannot applied to method that have parameters.
291 | 2. cache set does not awaited internally for not interrupting business logics. only when integrity matters, it awaits(i.e. 'has' method). If you implemented all ICacheStorage signatures synchronously, you don't have to concern about it.
292 |
--------------------------------------------------------------------------------
/lib/cache.module.ts:
--------------------------------------------------------------------------------
1 | import { Module } from '@nestjs/common';
2 | import { DiscoveryModule } from '@nestjs/core';
3 | import { CacheService } from './cache.service';
4 |
5 | @Module({
6 | imports: [DiscoveryModule],
7 | providers: [CacheService],
8 | })
9 | export class CacheModule {}
10 |
--------------------------------------------------------------------------------
/lib/cache.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable, OnModuleInit } from "@nestjs/common";
2 | import { DiscoveryService, MetadataScanner, Reflector } from "@nestjs/core";
3 | import { InstanceWrapper } from "@nestjs/core/injector/instance-wrapper";
4 | import { CACHE } from "./constants";
5 | import { CacheKind, CacheOptions } from "./types";
6 | import { cacheEventEmitter } from "./cache";
7 |
8 | @Injectable()
9 | export class CacheService implements OnModuleInit {
10 | constructor(
11 | private readonly discoveryService: DiscoveryService,
12 | private readonly scanner: MetadataScanner,
13 | private readonly reflector: Reflector
14 | ) {}
15 |
16 | private getAllInstances() {
17 | return [
18 | ...this.discoveryService.getControllers(),
19 | ...this.discoveryService.getProviders(),
20 | ];
21 | }
22 |
23 | private canExplore(instance: InstanceWrapper) {
24 | return (
25 | instance.isDependencyTreeStatic() &&
26 | instance.metatype &&
27 | instance.instance
28 | );
29 | }
30 |
31 | private extractCacheMetadata(instances: InstanceWrapper[]) {
32 | return instances
33 | .filter(this.canExplore)
34 | .map(({ instance }) => ({
35 | instance,
36 | methodNames: [
37 | ...new Set(
38 | this.scanner.getAllMethodNames(Object.getPrototypeOf(instance))
39 | ),
40 | ],
41 | }))
42 | .map(({ instance, methodNames }) => ({
43 | instance,
44 | methods: methodNames
45 | .map((methodName) => ({
46 | method: instance[methodName],
47 | methodName,
48 | }))
49 | .filter(({ method }) => this.reflector.get(CACHE, method)),
50 | }))
51 | .filter(({ methods }) => methods.length)
52 | .flatMap(({ instance, methods }) =>
53 | methods.map(({ method, methodName }) => ({
54 | instance,
55 | cacheOptions: this.reflector.get>(
56 | CACHE,
57 | method
58 | ),
59 | methodName,
60 | }))
61 | );
62 | }
63 |
64 | private initializeAllPersistentCache() {
65 | this.extractCacheMetadata(this.getAllInstances()).forEach(
66 | ({ instance, cacheOptions }) => {
67 | const { kind, key } = cacheOptions;
68 | if (kind === "persistent") cacheEventEmitter.emit(key, instance);
69 | }
70 | );
71 | }
72 |
73 | onModuleInit() {
74 | this.initializeAllPersistentCache();
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/lib/cache.ts:
--------------------------------------------------------------------------------
1 | import { SetMetadata } from "@nestjs/common";
2 | import { EventEmitter } from "events";
3 | import { CACHE } from "./constants";
4 | import { CacheKind, CacheOptions, ICacheStorage, INTERNAL_KIND } from "./types";
5 | import { isBust, isPersistent, isTemporal } from "./guard";
6 | import "reflect-metadata";
7 | import { DefaultStorage } from "./default.storage";
8 |
9 | export const cacheEventEmitter = new EventEmitter();
10 | export const intervalTimerMap = new Map();
11 | export const intervals: NodeJS.Timeout[] = [];
12 |
13 | type RootKey = `${string}${typeof ROOT_KEY_SUFFIX}`;
14 | const ROOT_KEY_SUFFIX = "__ROOT_KEY__" as const;
15 |
16 | const makeRootKey = (key: string): RootKey => `${key}${ROOT_KEY_SUFFIX}`;
17 | export const makeParamBasedCacheKey = (
18 | key: string,
19 | args: any[],
20 | paramIndex: number[] | undefined
21 | ) =>
22 | !paramIndex
23 | ? key
24 | : paramIndex.reduce(
25 | (cacheKey, pidx) => `${cacheKey}:${JSON.stringify(args[pidx])}`,
26 | key
27 | );
28 |
29 | const setChildCacheKey = async (
30 | storage: ICacheStorage,
31 | cacheKey: string,
32 | rootKey: RootKey
33 | ) => {
34 | if (!(await storage.has(rootKey))) {
35 | storage.set(rootKey, { [cacheKey]: 1 });
36 | return;
37 | }
38 | const children = await getChildrenObject(storage, rootKey);
39 | if (children[cacheKey]) return;
40 | children[cacheKey] = 1;
41 | storage.set(rootKey, children);
42 | };
43 |
44 | const deleteChildCacheKey = async (
45 | storage: ICacheStorage,
46 | cacheKey: string,
47 | rootKey: RootKey
48 | ) => {
49 | if (await storage.has(rootKey)) {
50 | const children = await getChildrenObject(storage, rootKey);
51 | delete children[cacheKey];
52 | storage.set(rootKey, children);
53 | }
54 | };
55 |
56 | const deleteAllChildrenByRootKey = async (
57 | storage: ICacheStorage,
58 | rootKey: RootKey,
59 | originalKey: string
60 | ) => {
61 | if (await storage.has(rootKey)) {
62 | const children = await getChildrenObject(storage, rootKey);
63 | for (const key in children) {
64 | storage.delete(key);
65 | }
66 | storage.delete(rootKey);
67 | storage.delete(originalKey);
68 | }
69 | };
70 |
71 | const getChildrenObject = async (storage, rootKey) => {
72 | if (!rootKey.endsWith(ROOT_KEY_SUFFIX)) {
73 | throw new Error("Invalid root key");
74 | }
75 | try {
76 | return await storage.get(rootKey);
77 | } catch (e) {
78 | throw new Error("cannot parse children object");
79 | }
80 | };
81 |
82 | function copyOriginalMetadataToCacheDescriptor(
83 | metadataKeys: any[],
84 | originalMethod: any,
85 | descriptor: PropertyDescriptor
86 | ) {
87 | metadataKeys.forEach((key) => {
88 | const metadataValue = Reflect.getMetadata(key, originalMethod);
89 | Reflect.defineMetadata(key, metadataValue, descriptor.value);
90 | });
91 | }
92 |
93 | export const Cache =
94 | (
95 | { storage }: { storage: ICacheStorage } = { storage: new DefaultStorage() }
96 | ) =>
97 | (cacheOptions: CacheOptions) => {
98 | return (
99 | target: any,
100 | _propertyKey: string,
101 | descriptor: PropertyDescriptor
102 | ) => {
103 | const originalMethod = descriptor.value;
104 | const originalMethodMetadataKeys =
105 | Reflect.getMetadataKeys(originalMethod);
106 | const { key } = cacheOptions;
107 |
108 | if (isPersistent(cacheOptions)) {
109 | const { refreshIntervalSec } = cacheOptions;
110 |
111 | Reflect.defineMetadata(key, INTERNAL_KIND.PERSISTENT, target);
112 |
113 | descriptor.value = async function () {
114 | if (arguments.length)
115 | throw new Error("arguments are not supported for persistent cache");
116 |
117 | if (await storage.has(key)) return storage.get(key);
118 |
119 | const result = await originalMethod.call(this);
120 | storage.set(key, result);
121 |
122 | if (refreshIntervalSec && !intervalTimerMap.has(key)) {
123 | const interval = setInterval(() => {
124 | const result = originalMethod.call(this);
125 |
126 | result instanceof Promise
127 | ? result.then((result) => {
128 | storage.set(key, result);
129 | })
130 | : storage.set(key, result);
131 | }, refreshIntervalSec * 1000);
132 |
133 | intervals.push(interval);
134 | intervalTimerMap.set(key, true);
135 | }
136 |
137 | return result;
138 | };
139 |
140 | cacheEventEmitter.once(key, (instance) => {
141 | descriptor.value.call(instance);
142 |
143 | cacheEventEmitter.on(
144 | `__${INTERNAL_KIND.PERSISTENT}=>${key}__`,
145 | () => {
146 | descriptor.value.call(instance);
147 | }
148 | );
149 | });
150 | }
151 |
152 | if (isTemporal(cacheOptions)) {
153 | const { ttl, paramIndex } = cacheOptions;
154 |
155 | Reflect.defineMetadata(key, INTERNAL_KIND.TEMPORAL, target);
156 |
157 | descriptor.value = async function (...args: any[]) {
158 | const cacheKey = makeParamBasedCacheKey(key, args, paramIndex);
159 | const rootKey = makeRootKey(key);
160 | if (paramIndex?.length) {
161 | setChildCacheKey(storage, cacheKey, rootKey);
162 | }
163 |
164 | if (await storage.has(cacheKey)) return storage.get(cacheKey);
165 |
166 | const result = await originalMethod.apply(this, args);
167 |
168 | storage.set(cacheKey, result, ttl);
169 |
170 | return result;
171 | };
172 | }
173 |
174 | if (isBust(cacheOptions)) {
175 | descriptor.value = async function (...args: any[]) {
176 | const { paramIndex, bustAllChildren, addition } = cacheOptions;
177 | const rootKey = makeRootKey(key);
178 | if (bustAllChildren && (await storage.has(rootKey))) {
179 | deleteAllChildrenByRootKey(storage, rootKey, key);
180 | } else {
181 | const cacheKey = makeParamBasedCacheKey(key, args, paramIndex);
182 |
183 | await storage.delete(cacheKey);
184 | if (await storage.has(rootKey)) {
185 | deleteChildCacheKey(storage, cacheKey, rootKey);
186 | }
187 | }
188 |
189 | for (const additionalBusting of addition || []) {
190 | const additionalRootKey = makeRootKey(additionalBusting.key);
191 | if (
192 | additionalBusting.bustAllChildren &&
193 | (await storage.has(additionalRootKey))
194 | ) {
195 | deleteAllChildrenByRootKey(
196 | storage,
197 | additionalRootKey,
198 | additionalBusting.key
199 | );
200 | } else {
201 | const cacheKey = makeParamBasedCacheKey(
202 | additionalBusting.key,
203 | args,
204 | additionalBusting.paramIndex
205 | );
206 | storage.delete(cacheKey);
207 |
208 | if (await storage.has(additionalRootKey)) {
209 | deleteChildCacheKey(storage, cacheKey, additionalRootKey);
210 | }
211 | }
212 | }
213 |
214 | const result = await originalMethod.apply(this, args);
215 |
216 | if (Reflect.getMetadata(key, target) === INTERNAL_KIND.PERSISTENT) {
217 | cacheEventEmitter.emit(`__${INTERNAL_KIND.PERSISTENT}=>${key}__`);
218 | }
219 |
220 | return result;
221 | };
222 | }
223 | copyOriginalMetadataToCacheDescriptor(
224 | originalMethodMetadataKeys,
225 | originalMethod,
226 | descriptor
227 | );
228 |
229 | SetMetadata(CACHE, cacheOptions)(descriptor.value);
230 |
231 | return descriptor;
232 | };
233 | };
234 |
--------------------------------------------------------------------------------
/lib/constants.ts:
--------------------------------------------------------------------------------
1 | export const CACHE = Symbol('cache');
2 |
--------------------------------------------------------------------------------
/lib/default.storage.ts:
--------------------------------------------------------------------------------
1 | import { LRUCache } from "lru-cache";
2 | import { ICacheStorage } from "./types";
3 |
4 | export class DefaultStorage implements ICacheStorage {
5 | constructor(size: number = 10000) {
6 | this.#storage = new LRUCache({
7 | max: size,
8 | });
9 | }
10 | #storage: LRUCache;
11 |
12 | get(key: string) {
13 | return this.#storage.get(key);
14 | }
15 |
16 | set(key: string, value: any, ttl?: number) {
17 | this.#storage.set(key, value, {
18 | ttl,
19 | });
20 | }
21 |
22 | delete(key: string) {
23 | return this.#storage.delete(key);
24 | }
25 |
26 | has(key: string) {
27 | return this.#storage.has(key);
28 | }
29 |
30 | clear() {
31 | this.#storage.clear();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/lib/guard.ts:
--------------------------------------------------------------------------------
1 | import { CacheKind, CacheOptions } from './types';
2 |
3 | export const isPersistent = (
4 | cacheOptions: CacheOptions,
5 | ): cacheOptions is CacheOptions<'persistent'> => {
6 | return cacheOptions.kind === 'persistent';
7 | };
8 | export const isTemporal = (
9 | cacheOptions: CacheOptions,
10 | ): cacheOptions is CacheOptions<'temporal'> => {
11 | return cacheOptions.kind === 'temporal';
12 | };
13 | export const isBust = (
14 | cacheOptions: CacheOptions,
15 | ): cacheOptions is CacheOptions<'bust'> => {
16 | return cacheOptions.kind === 'bust';
17 | };
18 |
--------------------------------------------------------------------------------
/lib/index.ts:
--------------------------------------------------------------------------------
1 | export { CacheModule } from "./cache.module";
2 | export { Cache } from "./cache";
3 | export { ICacheStorage } from "./types";
4 | export * from "./time.constants";
5 |
--------------------------------------------------------------------------------
/lib/test/cache.decorator.ts:
--------------------------------------------------------------------------------
1 | import { Cache } from "../cache";
2 | import { DefaultStorage } from "../default.storage";
3 |
4 | export const defaultStorage = new DefaultStorage();
5 | export const InMemCache = Cache({ storage: defaultStorage });
6 |
--------------------------------------------------------------------------------
/lib/test/controller.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Body,
3 | Controller,
4 | Get,
5 | Param,
6 | Patch,
7 | Post,
8 | Query,
9 | } from "@nestjs/common";
10 | import { sleep, startTime } from "./util";
11 | import { InMemCache } from "./cache.decorator";
12 | import { InMemTestService } from "./service";
13 | import { SECOND } from "../time.constants";
14 | @Controller()
15 | export class InMemTestController {
16 | constructor(private readonly testService: InMemTestService) {}
17 | @Get("test1")
18 | @InMemCache({
19 | key: "test1",
20 | kind: "persistent",
21 | })
22 | async test1() {
23 | await sleep(1000);
24 |
25 | return "test1";
26 | }
27 |
28 | @Get("test2")
29 | @InMemCache({
30 | key: "test2",
31 | kind: "persistent",
32 | refreshIntervalSec: 2,
33 | })
34 | async test2() {
35 | await sleep(1000);
36 |
37 | if (Date.now() - startTime > 3000) {
38 | return "modified test2";
39 | } else {
40 | return "test2";
41 | }
42 | }
43 |
44 | @Get("test2/bust")
45 | @InMemCache({
46 | key: "test2",
47 | kind: "bust",
48 | })
49 | async test2bust() {}
50 |
51 | @Get("test3/noParam")
52 | @InMemCache({
53 | key: "test3",
54 | kind: "temporal",
55 | ttl: 300 * SECOND,
56 | })
57 | async test3() {
58 | await sleep(1000);
59 |
60 | return "test3";
61 | }
62 |
63 | @Get("test3/withParam/:param")
64 | @InMemCache({
65 | key: "test3",
66 | kind: "temporal",
67 | ttl: 300 * SECOND,
68 | paramIndex: [0, 1],
69 | })
70 | async test3param(
71 | @Param("param") param: string,
72 | @Query("query") query: string
73 | ) {
74 | await sleep(1000);
75 |
76 | return "test3" + param + query;
77 | }
78 |
79 | @Post("test3")
80 | @InMemCache({
81 | key: "test3",
82 | kind: "temporal",
83 | ttl: 300 * SECOND,
84 | paramIndex: [0],
85 | })
86 | async test3post(@Body() body: { [key: string]: any }) {
87 | await sleep(1000);
88 |
89 | return "test3" + Object.keys(body).join("");
90 | }
91 |
92 | @Get("test3/bust")
93 | @InMemCache({
94 | key: "test3",
95 | kind: "bust",
96 | })
97 | async test3bust() {}
98 |
99 | @Get("test3/rootKeyBust")
100 | @InMemCache({
101 | key: "test3",
102 | kind: "bust",
103 | bustAllChildren: true,
104 | })
105 | async test3RootKeyBust() {}
106 |
107 | @Get("test4")
108 | async partiallyCached() {
109 | await this.testService.cacheableTask1();
110 | await this.testService.notCacheableTask();
111 | await this.testService.cacheableTask2();
112 |
113 | return "test4";
114 | }
115 |
116 | @InMemCache({
117 | key: "test5",
118 | kind: "persistent",
119 | })
120 | @Get("test5")
121 | async reverseOrderDecorator() {
122 | await sleep(1000);
123 |
124 | return "test5";
125 | }
126 |
127 | @InMemCache({
128 | key: "test6",
129 | kind: "temporal",
130 | ttl: 300 * SECOND,
131 | })
132 | @Get("test6")
133 | async test6() {
134 | await sleep(1000);
135 |
136 | return "test6";
137 | }
138 |
139 | @InMemCache({
140 | key: "under_test6",
141 | kind: "temporal",
142 | ttl: 300 * SECOND,
143 | })
144 | @Get("under_test6")
145 | async underTest6() {
146 | await sleep(1000);
147 |
148 | return "under_test6";
149 | }
150 |
151 | @Patch("test6/bust")
152 | @InMemCache({
153 | key: "test6",
154 | kind: "bust",
155 | addition: [
156 | {
157 | key: "under_test6",
158 | },
159 | ],
160 | })
161 | async test6bust() {}
162 | }
163 |
--------------------------------------------------------------------------------
/lib/test/in-memory.e2e.test.ts:
--------------------------------------------------------------------------------
1 | import request from "supertest";
2 | import { describe, it, before, after } from "node:test";
3 | import { equal } from "node:assert/strict";
4 | import { Test } from "@nestjs/testing";
5 | import { InMemTestService } from "./service";
6 | import { INestApplication } from "@nestjs/common";
7 | import { biggerThan, lessThan, sleep } from "./util";
8 | import { CacheModule } from "../cache.module";
9 | import { InMemTestController } from "./controller";
10 | import { intervals } from "../cache";
11 | import { defaultStorage } from "./cache.decorator";
12 | import { App } from "supertest/types";
13 |
14 | let httpServer: App;
15 | let app: INestApplication;
16 | let service: InMemTestService;
17 |
18 | const requestBody = {
19 | stringValue: "Hello, world!",
20 | numberValue: 123,
21 | objectValue: {
22 | nestedString: "This is a string inside an object",
23 | nestedNumber: 456,
24 | nestedObject: {
25 | anotherKey: "Another string",
26 | },
27 | },
28 | arrayValue: ["string in array", 789, true, null, { objectInArray: "value" }],
29 | booleanValue: true,
30 | nullValue: null,
31 | };
32 |
33 | describe("e2e-in-memory", () => {
34 | before(async () => {
35 | // start server
36 | const moduleRef = await Test.createTestingModule({
37 | imports: [CacheModule],
38 | controllers: [InMemTestController],
39 | providers: [InMemTestService],
40 | }).compile();
41 |
42 | app = moduleRef.createNestApplication();
43 |
44 | await app.init();
45 |
46 | httpServer = app.getHttpServer();
47 | service = app.get(InMemTestService);
48 | });
49 |
50 | after(async () => {
51 | await app.close();
52 | intervals.forEach(clearInterval);
53 | defaultStorage.clear();
54 | });
55 |
56 | it("should return immediately(set on start). test1 route", async () => {
57 | // give time to server execute and set cache...
58 | await sleep(1000);
59 |
60 | const start = Date.now();
61 | const response = await request(httpServer).get("/test1");
62 | const diff = Date.now() - start;
63 |
64 | equal(response.status, 200);
65 | equal(response.text, "test1");
66 | lessThan(diff, 50);
67 | });
68 |
69 | it("should return immediately(set on start) modified value. test2 route", async () => {
70 | // give time to server refresh cache...
71 | await sleep(3000);
72 |
73 | const start = Date.now();
74 | const response = await request(httpServer).get("/test2");
75 | const diff = Date.now() - start;
76 |
77 | equal(response.status, 200);
78 | equal(response.text, "modified test2");
79 | lessThan(diff, 50);
80 | });
81 |
82 | it("should return deferred value. because persistent cache busted", async () => {
83 | await request(httpServer).get("/test2/bust");
84 | const start = Date.now();
85 | const response = await request(httpServer).get("/test2");
86 | const diff = Date.now() - start;
87 |
88 | biggerThan(diff, 1000);
89 | equal(response.text, "modified test2");
90 | });
91 |
92 | it("even if cache value busted, it will automatically invoked internally, so request can get cached value", async () => {
93 | await request(httpServer).get("/test2/bust");
94 | await sleep(1050); // execution time 1 second + invoking time 50ms
95 |
96 | const start = Date.now();
97 | const response = await request(httpServer).get("/test2");
98 | const diff = Date.now() - start;
99 |
100 | lessThan(diff, 50);
101 | equal(response.text, "modified test2");
102 | });
103 |
104 | it("should return deferred value at first, then return cached value immediately", async () => {
105 | const start = Date.now();
106 | const response = await request(httpServer).get(
107 | "/test3/withParam/paramValue?query=queryValue"
108 | );
109 | const diff = Date.now() - start;
110 |
111 | biggerThan(diff, 1000);
112 | equal(response.text, "test3paramValuequeryValue");
113 |
114 | const start2 = Date.now();
115 | const response2 = await request(httpServer).get(
116 | "/test3/withParam/paramValue?query=queryValue"
117 | );
118 | const diff2 = Date.now() - start2;
119 |
120 | lessThan(diff2, 50);
121 | equal(response2.text, "test3paramValuequeryValue");
122 | });
123 |
124 | it("should return both deferred value if referenced value is different(parameter combined cache)", async () => {
125 | const start = Date.now();
126 | const response = await request(httpServer).get(
127 | "/test3/withParam/param1?query=query1"
128 | );
129 | const diff = Date.now() - start;
130 |
131 | biggerThan(diff, 1000);
132 | equal(response.text, "test3param1query1");
133 |
134 | const start2 = Date.now();
135 | const response2 = await request(httpServer).get(
136 | "/test3/withParam/param2?query=query1"
137 | );
138 | const diff2 = Date.now() - start2;
139 |
140 | biggerThan(diff2, 1000);
141 | equal(response2.text, "test3param2query1");
142 | });
143 |
144 | it("should bust all param based cache with a key if bustAllChildren is true", async () => {
145 | /* first request */
146 | // no param
147 | const start = Date.now();
148 | const response = await request(httpServer).get("/test3/noParam");
149 | const diff = Date.now() - start;
150 |
151 | biggerThan(diff, 1000);
152 | equal(response.text, "test3");
153 |
154 | // p1, q1
155 | const start1 = Date.now();
156 | const response1 = await request(httpServer).get(
157 | "/test3/withParam/_p1?query=_q1"
158 | );
159 | const diff1 = Date.now() - start1;
160 |
161 | biggerThan(diff1, 1000);
162 | equal(response1.text, "test3_p1_q1");
163 |
164 | // p2, q1
165 | const start2 = Date.now();
166 | const response2 = await request(httpServer).get(
167 | "/test3/withParam/_p2?query=_q1"
168 | );
169 | const diff2 = Date.now() - start2;
170 |
171 | biggerThan(diff2, 1000);
172 | equal(response2.text, "test3_p2_q1");
173 |
174 | /* second request */
175 | // no param
176 | const start3 = Date.now();
177 | const response3 = await request(httpServer).get("/test3/noParam");
178 | const diff3 = Date.now() - start3;
179 |
180 | lessThan(diff3, 50);
181 | equal(response3.text, "test3");
182 |
183 | // p1, q1
184 | const start4 = Date.now();
185 | const response4 = await request(httpServer).get(
186 | "/test3/withParam/_p1?query=_q1"
187 | );
188 | const diff4 = Date.now() - start4;
189 |
190 | lessThan(diff4, 50);
191 | equal(response4.text, "test3_p1_q1");
192 |
193 | // p2, q1
194 | const start5 = Date.now();
195 | ``;
196 | const response5 = await request(httpServer).get(
197 | "/test3/withParam/_p2?query=_q1"
198 | );
199 | const diff5 = Date.now() - start5;
200 |
201 | lessThan(diff5, 50);
202 | equal(response5.text, "test3_p2_q1");
203 |
204 | /* bust all cache */
205 | await request(httpServer).get("/test3/rootKeyBust");
206 | sleep(1000);
207 | /* third request */
208 | // no param
209 | const start6 = Date.now();
210 | const response6 = await request(httpServer).get("/test3/noParam");
211 | const diff6 = Date.now() - start6;
212 |
213 | biggerThan(diff6, 1000);
214 | equal(response6.text, "test3");
215 |
216 | // p1, q1
217 | const start7 = Date.now();
218 | const response7 = await request(httpServer).get(
219 | "/test3/withParam/_p1?query=_q1"
220 | );
221 | const diff7 = Date.now() - start7;
222 |
223 | biggerThan(diff7, 1000);
224 | equal(response7.text, "test3_p1_q1");
225 |
226 | // p2, q1
227 | const start8 = Date.now();
228 | const response8 = await request(httpServer).get(
229 | "/test3/withParam/_p2?query=_q1"
230 | );
231 | const diff8 = Date.now() - start8;
232 |
233 | biggerThan(diff8, 1000);
234 | equal(response8.text, "test3_p2_q1");
235 | });
236 |
237 | it("should work with object parameters", async () => {
238 | const start = Date.now();
239 | const response = await request(httpServer).post("/test3").send(requestBody);
240 | const diff = Date.now() - start;
241 |
242 | biggerThan(diff, 1000);
243 | equal(response.text, "test3" + Object.keys(requestBody).join(""));
244 |
245 | const start2 = Date.now();
246 | const response2 = await request(httpServer)
247 | .post("/test3")
248 | .send(requestBody);
249 | const diff2 = Date.now() - start2;
250 |
251 | lessThan(diff2, 50);
252 | equal(response2.text, "test3" + Object.keys(requestBody).join(""));
253 |
254 | const start3 = Date.now();
255 | const modifiedRequestBody = { ...requestBody, stringValue: "modified" };
256 | const response3 = await request(httpServer)
257 | .post("/test3")
258 | .send(modifiedRequestBody);
259 | const diff3 = Date.now() - start3;
260 |
261 | biggerThan(diff3, 1000);
262 | equal(response3.text, "test3" + Object.keys(modifiedRequestBody).join(""));
263 | });
264 |
265 | it("should work with array parameters", async () => {
266 | const array = [1, "hi", true, { a: 1 }, [1, 2], null];
267 | const start = Date.now();
268 | const result = await service.cacheableTaskWithArrayParam(array);
269 | const diff = Date.now() - start;
270 |
271 | biggerThan(diff, 900);
272 | equal(result, array.join(""));
273 |
274 | const start2 = Date.now();
275 | const result2 = await service.cacheableTaskWithArrayParam(array);
276 | const diff2 = Date.now() - start2;
277 |
278 | lessThan(diff2, 50);
279 | equal(result2, array.join(""));
280 |
281 | const start3 = Date.now();
282 | const modifiedArray = [...array, "modified"];
283 | const result3 = await service.cacheableTaskWithArrayParam(modifiedArray);
284 | const diff3 = Date.now() - start3;
285 |
286 | biggerThan(diff3, 900);
287 | equal(result3, modifiedArray.join(""));
288 | });
289 |
290 | it("should cache injectable partially so whole Request-Response cycle can divided into optimizable sections", async () => {
291 | const rawStart = Date.now();
292 | const response = await request(httpServer).get("/test4");
293 | const diff = Date.now() - rawStart;
294 |
295 | biggerThan(diff, 3000);
296 | equal(response.text, "test4");
297 |
298 | const start = Date.now();
299 | const response2 = await request(httpServer).get("/test4");
300 | const diff2 = Date.now() - start;
301 |
302 | biggerThan(diff2, 1000);
303 | lessThan(diff2, 1100);
304 | equal(response2.text, "test4");
305 | });
306 |
307 | it('should bust all addition cache if "addition" option is specified when bust', async () => {
308 | await request(httpServer).get("/test6");
309 | await request(httpServer).get("/under_test6");
310 | await request(httpServer).patch("/test6/bust");
311 |
312 | const start = Date.now();
313 | await request(httpServer).get("/test6");
314 | const diff = Date.now() - start;
315 |
316 | biggerThan(diff, 1000);
317 | });
318 | });
319 |
--------------------------------------------------------------------------------
/lib/test/runner.ts:
--------------------------------------------------------------------------------
1 | import { run } from "node:test";
2 | import { tap } from "node:test/reporters";
3 |
4 | let notOk = 0;
5 |
6 | run({ files: ["lib/test/in-memory.e2e.test.ts"] })
7 | .on("test:fail", () => {
8 | // test always fails at the end even if all e2e suites pass
9 | // so I counted the fail count. if 1, it is normal. if greater than 1, it is fail
10 | notOk++;
11 | console.warn("not ok count:", notOk);
12 | if (notOk > 1) {
13 | process.exitCode = 1;
14 | }
15 | })
16 | .compose(tap)
17 | .pipe(process.stdout);
18 |
--------------------------------------------------------------------------------
/lib/test/service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from "@nestjs/common";
2 | import { sleep } from "./util";
3 | import { InMemCache } from "./cache.decorator";
4 | import { SECOND } from "../time.constants";
5 |
6 | @Injectable()
7 | export class InMemTestService {
8 | @InMemCache({
9 | key: "cacheableTask1",
10 | kind: "temporal",
11 | ttl: 3 * SECOND,
12 | })
13 | async cacheableTask1() {
14 | await sleep(1000);
15 | return true;
16 | }
17 |
18 | @InMemCache({
19 | key: "cacheableTask2",
20 | kind: "temporal",
21 | ttl: 3 * SECOND,
22 | })
23 | async cacheableTask2() {
24 | await sleep(1000);
25 | return true;
26 | }
27 |
28 | async notCacheableTask() {
29 | await sleep(1000);
30 | return true;
31 | }
32 |
33 | @InMemCache({
34 | key: "test3",
35 | kind: "temporal",
36 | ttl: 3 * SECOND,
37 | paramIndex: [0],
38 | })
39 | async cacheableTaskWithArrayParam(param: any[]) {
40 | await sleep(1000);
41 | return param.join("");
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/lib/test/util.ts:
--------------------------------------------------------------------------------
1 | import { equal } from "node:assert/strict";
2 |
3 | export const startTime = Date.now();
4 | export const sleep = (ms: number) =>
5 | new Promise((resolve) => {
6 | setTimeout(resolve, ms);
7 | });
8 | export const lessThan = (input: number, expected: number) => {
9 | console.log("input: ", input, "expected: ", expected);
10 | equal(input < expected, true);
11 | };
12 | export const biggerThan = (input: number, expected: number) => {
13 | console.log("input: ", input, "expected: ", expected);
14 | equal(input > expected, true);
15 | };
16 |
--------------------------------------------------------------------------------
/lib/time.constants.ts:
--------------------------------------------------------------------------------
1 | export const SECOND = 1000;
2 | export const MINUTE = 60 * SECOND;
3 | export const HOUR = 60 * MINUTE;
4 | export const DAY = 24 * HOUR;
5 | export const WEEK = 7 * DAY;
6 | export const MONTH = 30 * DAY;
7 | export const YEAR = 12 * MONTH;
8 |
--------------------------------------------------------------------------------
/lib/types.ts:
--------------------------------------------------------------------------------
1 | type CacheOptionSchema = {
2 | temporal: { ttl: number; paramIndex?: number[] };
3 | persistent: {
4 | refreshIntervalSec?: number;
5 | };
6 | bust: {
7 | paramIndex?: number[];
8 | bustAllChildren?: boolean;
9 | addition?: Omit, "additon" | "kind">[];
10 | };
11 | };
12 |
13 | export const enum INTERNAL_KIND {
14 | PERSISTENT = 0,
15 | TEMPORAL = 1,
16 | BUST = 2,
17 | }
18 | export type CacheKind = "persistent" | "temporal" | "bust";
19 | export type CacheOptions = CacheOptionSchema[Kind] & {
20 | key: string;
21 | kind: Kind;
22 | };
23 | export interface ICacheStorage {
24 | get(key: string): any;
25 | set(key: string, value: any): any;
26 | set(key: string, value: any, ttl?: number): any;
27 | delete(key: string): boolean | Promise;
28 | has(key: string): boolean | Promise;
29 | }
30 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nestjs-omacache",
3 | "version": "1.1.7",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "nestjs-omacache",
9 | "version": "1.1.7",
10 | "license": "ISC",
11 | "dependencies": {
12 | "lru-cache": "^10.2.2"
13 | },
14 | "devDependencies": {
15 | "@nestjs/common": "10.3.9",
16 | "@nestjs/core": "10.3.9",
17 | "@nestjs/platform-express": "10.3.9",
18 | "@nestjs/testing": "^10.3.9",
19 | "@types/jest": "29.5.12",
20 | "@types/node": "20.14.2",
21 | "@types/supertest": "6.0.2",
22 | "reflect-metadata": "0.2.2",
23 | "rimraf": "5.0.7",
24 | "rxjs": "7.8.1",
25 | "supertest": "7.0.0",
26 | "ts-node": "^10.9.2",
27 | "typescript": "5.4.5"
28 | },
29 | "peerDependencies": {
30 | "@nestjs/common": ">=10",
31 | "@nestjs/core": ">=10",
32 | "reflect-metadata": "^0.2.0"
33 | }
34 | },
35 | "node_modules/@babel/code-frame": {
36 | "version": "7.23.5",
37 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
38 | "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==",
39 | "dev": true,
40 | "dependencies": {
41 | "@babel/highlight": "^7.23.4",
42 | "chalk": "^2.4.2"
43 | },
44 | "engines": {
45 | "node": ">=6.9.0"
46 | }
47 | },
48 | "node_modules/@babel/code-frame/node_modules/ansi-styles": {
49 | "version": "3.2.1",
50 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
51 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
52 | "dev": true,
53 | "dependencies": {
54 | "color-convert": "^1.9.0"
55 | },
56 | "engines": {
57 | "node": ">=4"
58 | }
59 | },
60 | "node_modules/@babel/code-frame/node_modules/chalk": {
61 | "version": "2.4.2",
62 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
63 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
64 | "dev": true,
65 | "dependencies": {
66 | "ansi-styles": "^3.2.1",
67 | "escape-string-regexp": "^1.0.5",
68 | "supports-color": "^5.3.0"
69 | },
70 | "engines": {
71 | "node": ">=4"
72 | }
73 | },
74 | "node_modules/@babel/code-frame/node_modules/color-convert": {
75 | "version": "1.9.3",
76 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
77 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
78 | "dev": true,
79 | "dependencies": {
80 | "color-name": "1.1.3"
81 | }
82 | },
83 | "node_modules/@babel/code-frame/node_modules/color-name": {
84 | "version": "1.1.3",
85 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
86 | "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
87 | "dev": true
88 | },
89 | "node_modules/@babel/code-frame/node_modules/escape-string-regexp": {
90 | "version": "1.0.5",
91 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
92 | "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
93 | "dev": true,
94 | "engines": {
95 | "node": ">=0.8.0"
96 | }
97 | },
98 | "node_modules/@babel/code-frame/node_modules/has-flag": {
99 | "version": "3.0.0",
100 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
101 | "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
102 | "dev": true,
103 | "engines": {
104 | "node": ">=4"
105 | }
106 | },
107 | "node_modules/@babel/code-frame/node_modules/supports-color": {
108 | "version": "5.5.0",
109 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
110 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
111 | "dev": true,
112 | "dependencies": {
113 | "has-flag": "^3.0.0"
114 | },
115 | "engines": {
116 | "node": ">=4"
117 | }
118 | },
119 | "node_modules/@babel/helper-validator-identifier": {
120 | "version": "7.22.20",
121 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
122 | "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
123 | "dev": true,
124 | "engines": {
125 | "node": ">=6.9.0"
126 | }
127 | },
128 | "node_modules/@babel/highlight": {
129 | "version": "7.23.4",
130 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz",
131 | "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==",
132 | "dev": true,
133 | "dependencies": {
134 | "@babel/helper-validator-identifier": "^7.22.20",
135 | "chalk": "^2.4.2",
136 | "js-tokens": "^4.0.0"
137 | },
138 | "engines": {
139 | "node": ">=6.9.0"
140 | }
141 | },
142 | "node_modules/@babel/highlight/node_modules/ansi-styles": {
143 | "version": "3.2.1",
144 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
145 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
146 | "dev": true,
147 | "dependencies": {
148 | "color-convert": "^1.9.0"
149 | },
150 | "engines": {
151 | "node": ">=4"
152 | }
153 | },
154 | "node_modules/@babel/highlight/node_modules/chalk": {
155 | "version": "2.4.2",
156 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
157 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
158 | "dev": true,
159 | "dependencies": {
160 | "ansi-styles": "^3.2.1",
161 | "escape-string-regexp": "^1.0.5",
162 | "supports-color": "^5.3.0"
163 | },
164 | "engines": {
165 | "node": ">=4"
166 | }
167 | },
168 | "node_modules/@babel/highlight/node_modules/color-convert": {
169 | "version": "1.9.3",
170 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
171 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
172 | "dev": true,
173 | "dependencies": {
174 | "color-name": "1.1.3"
175 | }
176 | },
177 | "node_modules/@babel/highlight/node_modules/color-name": {
178 | "version": "1.1.3",
179 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
180 | "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
181 | "dev": true
182 | },
183 | "node_modules/@babel/highlight/node_modules/escape-string-regexp": {
184 | "version": "1.0.5",
185 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
186 | "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
187 | "dev": true,
188 | "engines": {
189 | "node": ">=0.8.0"
190 | }
191 | },
192 | "node_modules/@babel/highlight/node_modules/has-flag": {
193 | "version": "3.0.0",
194 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
195 | "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
196 | "dev": true,
197 | "engines": {
198 | "node": ">=4"
199 | }
200 | },
201 | "node_modules/@babel/highlight/node_modules/supports-color": {
202 | "version": "5.5.0",
203 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
204 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
205 | "dev": true,
206 | "dependencies": {
207 | "has-flag": "^3.0.0"
208 | },
209 | "engines": {
210 | "node": ">=4"
211 | }
212 | },
213 | "node_modules/@cspotcode/source-map-support": {
214 | "version": "0.8.1",
215 | "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
216 | "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
217 | "dev": true,
218 | "dependencies": {
219 | "@jridgewell/trace-mapping": "0.3.9"
220 | },
221 | "engines": {
222 | "node": ">=12"
223 | }
224 | },
225 | "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": {
226 | "version": "0.3.9",
227 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
228 | "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
229 | "dev": true,
230 | "dependencies": {
231 | "@jridgewell/resolve-uri": "^3.0.3",
232 | "@jridgewell/sourcemap-codec": "^1.4.10"
233 | }
234 | },
235 | "node_modules/@isaacs/cliui": {
236 | "version": "8.0.2",
237 | "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
238 | "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
239 | "dev": true,
240 | "dependencies": {
241 | "string-width": "^5.1.2",
242 | "string-width-cjs": "npm:string-width@^4.2.0",
243 | "strip-ansi": "^7.0.1",
244 | "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
245 | "wrap-ansi": "^8.1.0",
246 | "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
247 | },
248 | "engines": {
249 | "node": ">=12"
250 | }
251 | },
252 | "node_modules/@isaacs/cliui/node_modules/ansi-regex": {
253 | "version": "6.0.1",
254 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
255 | "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
256 | "dev": true,
257 | "engines": {
258 | "node": ">=12"
259 | },
260 | "funding": {
261 | "url": "https://github.com/chalk/ansi-regex?sponsor=1"
262 | }
263 | },
264 | "node_modules/@isaacs/cliui/node_modules/ansi-styles": {
265 | "version": "6.2.1",
266 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
267 | "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
268 | "dev": true,
269 | "engines": {
270 | "node": ">=12"
271 | },
272 | "funding": {
273 | "url": "https://github.com/chalk/ansi-styles?sponsor=1"
274 | }
275 | },
276 | "node_modules/@isaacs/cliui/node_modules/emoji-regex": {
277 | "version": "9.2.2",
278 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
279 | "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
280 | "dev": true
281 | },
282 | "node_modules/@isaacs/cliui/node_modules/string-width": {
283 | "version": "5.1.2",
284 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
285 | "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
286 | "dev": true,
287 | "dependencies": {
288 | "eastasianwidth": "^0.2.0",
289 | "emoji-regex": "^9.2.2",
290 | "strip-ansi": "^7.0.1"
291 | },
292 | "engines": {
293 | "node": ">=12"
294 | },
295 | "funding": {
296 | "url": "https://github.com/sponsors/sindresorhus"
297 | }
298 | },
299 | "node_modules/@isaacs/cliui/node_modules/strip-ansi": {
300 | "version": "7.1.0",
301 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
302 | "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
303 | "dev": true,
304 | "dependencies": {
305 | "ansi-regex": "^6.0.1"
306 | },
307 | "engines": {
308 | "node": ">=12"
309 | },
310 | "funding": {
311 | "url": "https://github.com/chalk/strip-ansi?sponsor=1"
312 | }
313 | },
314 | "node_modules/@isaacs/cliui/node_modules/wrap-ansi": {
315 | "version": "8.1.0",
316 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
317 | "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
318 | "dev": true,
319 | "dependencies": {
320 | "ansi-styles": "^6.1.0",
321 | "string-width": "^5.0.1",
322 | "strip-ansi": "^7.0.1"
323 | },
324 | "engines": {
325 | "node": ">=12"
326 | },
327 | "funding": {
328 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
329 | }
330 | },
331 | "node_modules/@jest/expect-utils": {
332 | "version": "29.7.0",
333 | "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz",
334 | "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==",
335 | "dev": true,
336 | "dependencies": {
337 | "jest-get-type": "^29.6.3"
338 | },
339 | "engines": {
340 | "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
341 | }
342 | },
343 | "node_modules/@jest/schemas": {
344 | "version": "29.6.3",
345 | "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
346 | "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
347 | "dev": true,
348 | "dependencies": {
349 | "@sinclair/typebox": "^0.27.8"
350 | },
351 | "engines": {
352 | "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
353 | }
354 | },
355 | "node_modules/@jest/types": {
356 | "version": "29.6.3",
357 | "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
358 | "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
359 | "dev": true,
360 | "dependencies": {
361 | "@jest/schemas": "^29.6.3",
362 | "@types/istanbul-lib-coverage": "^2.0.0",
363 | "@types/istanbul-reports": "^3.0.0",
364 | "@types/node": "*",
365 | "@types/yargs": "^17.0.8",
366 | "chalk": "^4.0.0"
367 | },
368 | "engines": {
369 | "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
370 | }
371 | },
372 | "node_modules/@jridgewell/resolve-uri": {
373 | "version": "3.1.1",
374 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
375 | "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
376 | "dev": true,
377 | "engines": {
378 | "node": ">=6.0.0"
379 | }
380 | },
381 | "node_modules/@jridgewell/sourcemap-codec": {
382 | "version": "1.4.15",
383 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
384 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
385 | "dev": true
386 | },
387 | "node_modules/@lukeed/csprng": {
388 | "version": "1.1.0",
389 | "resolved": "https://registry.npmjs.org/@lukeed/csprng/-/csprng-1.1.0.tgz",
390 | "integrity": "sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==",
391 | "dev": true,
392 | "engines": {
393 | "node": ">=8"
394 | }
395 | },
396 | "node_modules/@nestjs/common": {
397 | "version": "10.3.9",
398 | "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-10.3.9.tgz",
399 | "integrity": "sha512-JAQONPagMa+sy/fcIqh/Hn3rkYQ9pQM51vXCFNOM5ujefxUVqn3gwFRMN8Y1+MxdUHipV+8daEj2jEm0IqJzOA==",
400 | "dev": true,
401 | "dependencies": {
402 | "iterare": "1.2.1",
403 | "tslib": "2.6.2",
404 | "uid": "2.0.2"
405 | },
406 | "funding": {
407 | "type": "opencollective",
408 | "url": "https://opencollective.com/nest"
409 | },
410 | "peerDependencies": {
411 | "class-transformer": "*",
412 | "class-validator": "*",
413 | "reflect-metadata": "^0.1.12 || ^0.2.0",
414 | "rxjs": "^7.1.0"
415 | },
416 | "peerDependenciesMeta": {
417 | "class-transformer": {
418 | "optional": true
419 | },
420 | "class-validator": {
421 | "optional": true
422 | }
423 | }
424 | },
425 | "node_modules/@nestjs/core": {
426 | "version": "10.3.9",
427 | "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-10.3.9.tgz",
428 | "integrity": "sha512-NzZUfWAmaf8sqhhwoRA+CuqxQe+P4Rz8PZp5U7CdCbjyeB9ZVGcBkihcJC9wMdtiOWHRndB2J8zRfs5w06jK3w==",
429 | "dev": true,
430 | "hasInstallScript": true,
431 | "dependencies": {
432 | "@nuxtjs/opencollective": "0.3.2",
433 | "fast-safe-stringify": "2.1.1",
434 | "iterare": "1.2.1",
435 | "path-to-regexp": "3.2.0",
436 | "tslib": "2.6.2",
437 | "uid": "2.0.2"
438 | },
439 | "funding": {
440 | "type": "opencollective",
441 | "url": "https://opencollective.com/nest"
442 | },
443 | "peerDependencies": {
444 | "@nestjs/common": "^10.0.0",
445 | "@nestjs/microservices": "^10.0.0",
446 | "@nestjs/platform-express": "^10.0.0",
447 | "@nestjs/websockets": "^10.0.0",
448 | "reflect-metadata": "^0.1.12 || ^0.2.0",
449 | "rxjs": "^7.1.0"
450 | },
451 | "peerDependenciesMeta": {
452 | "@nestjs/microservices": {
453 | "optional": true
454 | },
455 | "@nestjs/platform-express": {
456 | "optional": true
457 | },
458 | "@nestjs/websockets": {
459 | "optional": true
460 | }
461 | }
462 | },
463 | "node_modules/@nestjs/platform-express": {
464 | "version": "10.3.9",
465 | "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.3.9.tgz",
466 | "integrity": "sha512-si/UzobP6YUtYtCT1cSyQYHHzU3yseqYT6l7OHSMVvfG1+TqxaAqI6nmrix02LO+l1YntHRXEs3p+v9a7EfrSQ==",
467 | "dev": true,
468 | "dependencies": {
469 | "body-parser": "1.20.2",
470 | "cors": "2.8.5",
471 | "express": "4.19.2",
472 | "multer": "1.4.4-lts.1",
473 | "tslib": "2.6.2"
474 | },
475 | "funding": {
476 | "type": "opencollective",
477 | "url": "https://opencollective.com/nest"
478 | },
479 | "peerDependencies": {
480 | "@nestjs/common": "^10.0.0",
481 | "@nestjs/core": "^10.0.0"
482 | }
483 | },
484 | "node_modules/@nestjs/testing": {
485 | "version": "10.3.9",
486 | "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-10.3.9.tgz",
487 | "integrity": "sha512-z24SdpZIRtYyM5s2vnu7rbBosXJY/KcAP7oJlwgFa/h/z/wg8gzyoKy5lhibH//OZNO+pYKajV5wczxuy5WeAg==",
488 | "dev": true,
489 | "license": "MIT",
490 | "dependencies": {
491 | "tslib": "2.6.2"
492 | },
493 | "funding": {
494 | "type": "opencollective",
495 | "url": "https://opencollective.com/nest"
496 | },
497 | "peerDependencies": {
498 | "@nestjs/common": "^10.0.0",
499 | "@nestjs/core": "^10.0.0",
500 | "@nestjs/microservices": "^10.0.0",
501 | "@nestjs/platform-express": "^10.0.0"
502 | },
503 | "peerDependenciesMeta": {
504 | "@nestjs/microservices": {
505 | "optional": true
506 | },
507 | "@nestjs/platform-express": {
508 | "optional": true
509 | }
510 | }
511 | },
512 | "node_modules/@nuxtjs/opencollective": {
513 | "version": "0.3.2",
514 | "resolved": "https://registry.npmjs.org/@nuxtjs/opencollective/-/opencollective-0.3.2.tgz",
515 | "integrity": "sha512-um0xL3fO7Mf4fDxcqx9KryrB7zgRM5JSlvGN5AGkP6JLM5XEKyjeAiPbNxdXVXQ16isuAhYpvP88NgL2BGd6aA==",
516 | "dev": true,
517 | "dependencies": {
518 | "chalk": "^4.1.0",
519 | "consola": "^2.15.0",
520 | "node-fetch": "^2.6.1"
521 | },
522 | "bin": {
523 | "opencollective": "bin/opencollective.js"
524 | },
525 | "engines": {
526 | "node": ">=8.0.0",
527 | "npm": ">=5.0.0"
528 | }
529 | },
530 | "node_modules/@pkgjs/parseargs": {
531 | "version": "0.11.0",
532 | "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
533 | "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
534 | "dev": true,
535 | "optional": true,
536 | "engines": {
537 | "node": ">=14"
538 | }
539 | },
540 | "node_modules/@sinclair/typebox": {
541 | "version": "0.27.8",
542 | "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
543 | "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
544 | "dev": true
545 | },
546 | "node_modules/@tsconfig/node10": {
547 | "version": "1.0.9",
548 | "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
549 | "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
550 | "dev": true
551 | },
552 | "node_modules/@tsconfig/node12": {
553 | "version": "1.0.11",
554 | "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
555 | "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
556 | "dev": true
557 | },
558 | "node_modules/@tsconfig/node14": {
559 | "version": "1.0.3",
560 | "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
561 | "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
562 | "dev": true
563 | },
564 | "node_modules/@tsconfig/node16": {
565 | "version": "1.0.4",
566 | "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
567 | "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
568 | "dev": true
569 | },
570 | "node_modules/@types/cookiejar": {
571 | "version": "2.1.5",
572 | "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.5.tgz",
573 | "integrity": "sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==",
574 | "dev": true
575 | },
576 | "node_modules/@types/istanbul-lib-coverage": {
577 | "version": "2.0.6",
578 | "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
579 | "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
580 | "dev": true
581 | },
582 | "node_modules/@types/istanbul-lib-report": {
583 | "version": "3.0.3",
584 | "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz",
585 | "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==",
586 | "dev": true,
587 | "dependencies": {
588 | "@types/istanbul-lib-coverage": "*"
589 | }
590 | },
591 | "node_modules/@types/istanbul-reports": {
592 | "version": "3.0.4",
593 | "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
594 | "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
595 | "dev": true,
596 | "dependencies": {
597 | "@types/istanbul-lib-report": "*"
598 | }
599 | },
600 | "node_modules/@types/jest": {
601 | "version": "29.5.12",
602 | "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz",
603 | "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==",
604 | "dev": true,
605 | "dependencies": {
606 | "expect": "^29.0.0",
607 | "pretty-format": "^29.0.0"
608 | }
609 | },
610 | "node_modules/@types/methods": {
611 | "version": "1.1.4",
612 | "resolved": "https://registry.npmjs.org/@types/methods/-/methods-1.1.4.tgz",
613 | "integrity": "sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==",
614 | "dev": true
615 | },
616 | "node_modules/@types/node": {
617 | "version": "20.14.2",
618 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz",
619 | "integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==",
620 | "dev": true,
621 | "dependencies": {
622 | "undici-types": "~5.26.4"
623 | }
624 | },
625 | "node_modules/@types/stack-utils": {
626 | "version": "2.0.3",
627 | "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
628 | "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==",
629 | "dev": true
630 | },
631 | "node_modules/@types/superagent": {
632 | "version": "8.1.7",
633 | "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-8.1.7.tgz",
634 | "integrity": "sha512-NmIsd0Yj4DDhftfWvvAku482PZum4DBW7U51OvS8gvOkDDY0WT1jsVyDV3hK+vplrsYw8oDwi9QxOM7U68iwww==",
635 | "dev": true,
636 | "dependencies": {
637 | "@types/cookiejar": "^2.1.5",
638 | "@types/methods": "^1.1.4",
639 | "@types/node": "*"
640 | }
641 | },
642 | "node_modules/@types/supertest": {
643 | "version": "6.0.2",
644 | "resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-6.0.2.tgz",
645 | "integrity": "sha512-137ypx2lk/wTQbW6An6safu9hXmajAifU/s7szAHLN/FeIm5w7yR0Wkl9fdJMRSHwOn4HLAI0DaB2TOORuhPDg==",
646 | "dev": true,
647 | "dependencies": {
648 | "@types/methods": "^1.1.4",
649 | "@types/superagent": "^8.1.0"
650 | }
651 | },
652 | "node_modules/@types/yargs": {
653 | "version": "17.0.32",
654 | "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz",
655 | "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==",
656 | "dev": true,
657 | "dependencies": {
658 | "@types/yargs-parser": "*"
659 | }
660 | },
661 | "node_modules/@types/yargs-parser": {
662 | "version": "21.0.3",
663 | "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz",
664 | "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==",
665 | "dev": true
666 | },
667 | "node_modules/accepts": {
668 | "version": "1.3.8",
669 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
670 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
671 | "dev": true,
672 | "dependencies": {
673 | "mime-types": "~2.1.34",
674 | "negotiator": "0.6.3"
675 | },
676 | "engines": {
677 | "node": ">= 0.6"
678 | }
679 | },
680 | "node_modules/acorn": {
681 | "version": "8.11.3",
682 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
683 | "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
684 | "dev": true,
685 | "bin": {
686 | "acorn": "bin/acorn"
687 | },
688 | "engines": {
689 | "node": ">=0.4.0"
690 | }
691 | },
692 | "node_modules/acorn-walk": {
693 | "version": "8.3.2",
694 | "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz",
695 | "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==",
696 | "dev": true,
697 | "engines": {
698 | "node": ">=0.4.0"
699 | }
700 | },
701 | "node_modules/ansi-regex": {
702 | "version": "5.0.1",
703 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
704 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
705 | "dev": true,
706 | "engines": {
707 | "node": ">=8"
708 | }
709 | },
710 | "node_modules/ansi-styles": {
711 | "version": "4.3.0",
712 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
713 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
714 | "dev": true,
715 | "dependencies": {
716 | "color-convert": "^2.0.1"
717 | },
718 | "engines": {
719 | "node": ">=8"
720 | },
721 | "funding": {
722 | "url": "https://github.com/chalk/ansi-styles?sponsor=1"
723 | }
724 | },
725 | "node_modules/append-field": {
726 | "version": "1.0.0",
727 | "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz",
728 | "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==",
729 | "dev": true
730 | },
731 | "node_modules/arg": {
732 | "version": "4.1.3",
733 | "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
734 | "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
735 | "dev": true
736 | },
737 | "node_modules/array-flatten": {
738 | "version": "1.1.1",
739 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
740 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
741 | "dev": true
742 | },
743 | "node_modules/asap": {
744 | "version": "2.0.6",
745 | "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
746 | "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
747 | "dev": true
748 | },
749 | "node_modules/asynckit": {
750 | "version": "0.4.0",
751 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
752 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
753 | "dev": true
754 | },
755 | "node_modules/balanced-match": {
756 | "version": "1.0.2",
757 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
758 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
759 | "dev": true
760 | },
761 | "node_modules/body-parser": {
762 | "version": "1.20.2",
763 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz",
764 | "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==",
765 | "dev": true,
766 | "dependencies": {
767 | "bytes": "3.1.2",
768 | "content-type": "~1.0.5",
769 | "debug": "2.6.9",
770 | "depd": "2.0.0",
771 | "destroy": "1.2.0",
772 | "http-errors": "2.0.0",
773 | "iconv-lite": "0.4.24",
774 | "on-finished": "2.4.1",
775 | "qs": "6.11.0",
776 | "raw-body": "2.5.2",
777 | "type-is": "~1.6.18",
778 | "unpipe": "1.0.0"
779 | },
780 | "engines": {
781 | "node": ">= 0.8",
782 | "npm": "1.2.8000 || >= 1.4.16"
783 | }
784 | },
785 | "node_modules/braces": {
786 | "version": "3.0.2",
787 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
788 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
789 | "dev": true,
790 | "dependencies": {
791 | "fill-range": "^7.0.1"
792 | },
793 | "engines": {
794 | "node": ">=8"
795 | }
796 | },
797 | "node_modules/buffer-from": {
798 | "version": "1.1.2",
799 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
800 | "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
801 | "dev": true
802 | },
803 | "node_modules/busboy": {
804 | "version": "1.6.0",
805 | "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
806 | "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==",
807 | "dev": true,
808 | "dependencies": {
809 | "streamsearch": "^1.1.0"
810 | },
811 | "engines": {
812 | "node": ">=10.16.0"
813 | }
814 | },
815 | "node_modules/bytes": {
816 | "version": "3.1.2",
817 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
818 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
819 | "dev": true,
820 | "engines": {
821 | "node": ">= 0.8"
822 | }
823 | },
824 | "node_modules/call-bind": {
825 | "version": "1.0.5",
826 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz",
827 | "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==",
828 | "dev": true,
829 | "dependencies": {
830 | "function-bind": "^1.1.2",
831 | "get-intrinsic": "^1.2.1",
832 | "set-function-length": "^1.1.1"
833 | },
834 | "funding": {
835 | "url": "https://github.com/sponsors/ljharb"
836 | }
837 | },
838 | "node_modules/chalk": {
839 | "version": "4.1.2",
840 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
841 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
842 | "dev": true,
843 | "dependencies": {
844 | "ansi-styles": "^4.1.0",
845 | "supports-color": "^7.1.0"
846 | },
847 | "engines": {
848 | "node": ">=10"
849 | },
850 | "funding": {
851 | "url": "https://github.com/chalk/chalk?sponsor=1"
852 | }
853 | },
854 | "node_modules/ci-info": {
855 | "version": "3.9.0",
856 | "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
857 | "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
858 | "dev": true,
859 | "funding": [
860 | {
861 | "type": "github",
862 | "url": "https://github.com/sponsors/sibiraj-s"
863 | }
864 | ],
865 | "engines": {
866 | "node": ">=8"
867 | }
868 | },
869 | "node_modules/color-convert": {
870 | "version": "2.0.1",
871 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
872 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
873 | "dev": true,
874 | "dependencies": {
875 | "color-name": "~1.1.4"
876 | },
877 | "engines": {
878 | "node": ">=7.0.0"
879 | }
880 | },
881 | "node_modules/color-name": {
882 | "version": "1.1.4",
883 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
884 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
885 | "dev": true
886 | },
887 | "node_modules/combined-stream": {
888 | "version": "1.0.8",
889 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
890 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
891 | "dev": true,
892 | "dependencies": {
893 | "delayed-stream": "~1.0.0"
894 | },
895 | "engines": {
896 | "node": ">= 0.8"
897 | }
898 | },
899 | "node_modules/component-emitter": {
900 | "version": "1.3.1",
901 | "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz",
902 | "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==",
903 | "dev": true,
904 | "funding": {
905 | "url": "https://github.com/sponsors/sindresorhus"
906 | }
907 | },
908 | "node_modules/concat-stream": {
909 | "version": "1.6.2",
910 | "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
911 | "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
912 | "dev": true,
913 | "engines": [
914 | "node >= 0.8"
915 | ],
916 | "dependencies": {
917 | "buffer-from": "^1.0.0",
918 | "inherits": "^2.0.3",
919 | "readable-stream": "^2.2.2",
920 | "typedarray": "^0.0.6"
921 | }
922 | },
923 | "node_modules/consola": {
924 | "version": "2.15.3",
925 | "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz",
926 | "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==",
927 | "dev": true
928 | },
929 | "node_modules/content-disposition": {
930 | "version": "0.5.4",
931 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
932 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
933 | "dev": true,
934 | "dependencies": {
935 | "safe-buffer": "5.2.1"
936 | },
937 | "engines": {
938 | "node": ">= 0.6"
939 | }
940 | },
941 | "node_modules/content-type": {
942 | "version": "1.0.5",
943 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
944 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
945 | "dev": true,
946 | "engines": {
947 | "node": ">= 0.6"
948 | }
949 | },
950 | "node_modules/cookie": {
951 | "version": "0.6.0",
952 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
953 | "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
954 | "dev": true,
955 | "engines": {
956 | "node": ">= 0.6"
957 | }
958 | },
959 | "node_modules/cookie-signature": {
960 | "version": "1.0.6",
961 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
962 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
963 | "dev": true
964 | },
965 | "node_modules/cookiejar": {
966 | "version": "2.1.4",
967 | "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz",
968 | "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==",
969 | "dev": true
970 | },
971 | "node_modules/core-util-is": {
972 | "version": "1.0.3",
973 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
974 | "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
975 | "dev": true
976 | },
977 | "node_modules/cors": {
978 | "version": "2.8.5",
979 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
980 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
981 | "dev": true,
982 | "dependencies": {
983 | "object-assign": "^4",
984 | "vary": "^1"
985 | },
986 | "engines": {
987 | "node": ">= 0.10"
988 | }
989 | },
990 | "node_modules/create-require": {
991 | "version": "1.1.1",
992 | "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
993 | "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
994 | "dev": true
995 | },
996 | "node_modules/cross-spawn": {
997 | "version": "7.0.3",
998 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
999 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
1000 | "dev": true,
1001 | "dependencies": {
1002 | "path-key": "^3.1.0",
1003 | "shebang-command": "^2.0.0",
1004 | "which": "^2.0.1"
1005 | },
1006 | "engines": {
1007 | "node": ">= 8"
1008 | }
1009 | },
1010 | "node_modules/debug": {
1011 | "version": "2.6.9",
1012 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
1013 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
1014 | "dev": true,
1015 | "dependencies": {
1016 | "ms": "2.0.0"
1017 | }
1018 | },
1019 | "node_modules/define-data-property": {
1020 | "version": "1.1.1",
1021 | "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz",
1022 | "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==",
1023 | "dev": true,
1024 | "dependencies": {
1025 | "get-intrinsic": "^1.2.1",
1026 | "gopd": "^1.0.1",
1027 | "has-property-descriptors": "^1.0.0"
1028 | },
1029 | "engines": {
1030 | "node": ">= 0.4"
1031 | }
1032 | },
1033 | "node_modules/delayed-stream": {
1034 | "version": "1.0.0",
1035 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
1036 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
1037 | "dev": true,
1038 | "engines": {
1039 | "node": ">=0.4.0"
1040 | }
1041 | },
1042 | "node_modules/depd": {
1043 | "version": "2.0.0",
1044 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
1045 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
1046 | "dev": true,
1047 | "engines": {
1048 | "node": ">= 0.8"
1049 | }
1050 | },
1051 | "node_modules/destroy": {
1052 | "version": "1.2.0",
1053 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
1054 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
1055 | "dev": true,
1056 | "engines": {
1057 | "node": ">= 0.8",
1058 | "npm": "1.2.8000 || >= 1.4.16"
1059 | }
1060 | },
1061 | "node_modules/dezalgo": {
1062 | "version": "1.0.4",
1063 | "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz",
1064 | "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==",
1065 | "dev": true,
1066 | "dependencies": {
1067 | "asap": "^2.0.0",
1068 | "wrappy": "1"
1069 | }
1070 | },
1071 | "node_modules/diff": {
1072 | "version": "4.0.2",
1073 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
1074 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
1075 | "dev": true,
1076 | "engines": {
1077 | "node": ">=0.3.1"
1078 | }
1079 | },
1080 | "node_modules/diff-sequences": {
1081 | "version": "29.6.3",
1082 | "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz",
1083 | "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==",
1084 | "dev": true,
1085 | "engines": {
1086 | "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
1087 | }
1088 | },
1089 | "node_modules/eastasianwidth": {
1090 | "version": "0.2.0",
1091 | "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
1092 | "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
1093 | "dev": true
1094 | },
1095 | "node_modules/ee-first": {
1096 | "version": "1.1.1",
1097 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
1098 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
1099 | "dev": true
1100 | },
1101 | "node_modules/emoji-regex": {
1102 | "version": "8.0.0",
1103 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
1104 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
1105 | "dev": true
1106 | },
1107 | "node_modules/encodeurl": {
1108 | "version": "1.0.2",
1109 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
1110 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
1111 | "dev": true,
1112 | "engines": {
1113 | "node": ">= 0.8"
1114 | }
1115 | },
1116 | "node_modules/escape-html": {
1117 | "version": "1.0.3",
1118 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
1119 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
1120 | "dev": true
1121 | },
1122 | "node_modules/escape-string-regexp": {
1123 | "version": "2.0.0",
1124 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
1125 | "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
1126 | "dev": true,
1127 | "engines": {
1128 | "node": ">=8"
1129 | }
1130 | },
1131 | "node_modules/etag": {
1132 | "version": "1.8.1",
1133 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
1134 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
1135 | "dev": true,
1136 | "engines": {
1137 | "node": ">= 0.6"
1138 | }
1139 | },
1140 | "node_modules/expect": {
1141 | "version": "29.7.0",
1142 | "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz",
1143 | "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==",
1144 | "dev": true,
1145 | "dependencies": {
1146 | "@jest/expect-utils": "^29.7.0",
1147 | "jest-get-type": "^29.6.3",
1148 | "jest-matcher-utils": "^29.7.0",
1149 | "jest-message-util": "^29.7.0",
1150 | "jest-util": "^29.7.0"
1151 | },
1152 | "engines": {
1153 | "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
1154 | }
1155 | },
1156 | "node_modules/express": {
1157 | "version": "4.19.2",
1158 | "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz",
1159 | "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==",
1160 | "dev": true,
1161 | "dependencies": {
1162 | "accepts": "~1.3.8",
1163 | "array-flatten": "1.1.1",
1164 | "body-parser": "1.20.2",
1165 | "content-disposition": "0.5.4",
1166 | "content-type": "~1.0.4",
1167 | "cookie": "0.6.0",
1168 | "cookie-signature": "1.0.6",
1169 | "debug": "2.6.9",
1170 | "depd": "2.0.0",
1171 | "encodeurl": "~1.0.2",
1172 | "escape-html": "~1.0.3",
1173 | "etag": "~1.8.1",
1174 | "finalhandler": "1.2.0",
1175 | "fresh": "0.5.2",
1176 | "http-errors": "2.0.0",
1177 | "merge-descriptors": "1.0.1",
1178 | "methods": "~1.1.2",
1179 | "on-finished": "2.4.1",
1180 | "parseurl": "~1.3.3",
1181 | "path-to-regexp": "0.1.7",
1182 | "proxy-addr": "~2.0.7",
1183 | "qs": "6.11.0",
1184 | "range-parser": "~1.2.1",
1185 | "safe-buffer": "5.2.1",
1186 | "send": "0.18.0",
1187 | "serve-static": "1.15.0",
1188 | "setprototypeof": "1.2.0",
1189 | "statuses": "2.0.1",
1190 | "type-is": "~1.6.18",
1191 | "utils-merge": "1.0.1",
1192 | "vary": "~1.1.2"
1193 | },
1194 | "engines": {
1195 | "node": ">= 0.10.0"
1196 | }
1197 | },
1198 | "node_modules/express/node_modules/path-to-regexp": {
1199 | "version": "0.1.7",
1200 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
1201 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==",
1202 | "dev": true
1203 | },
1204 | "node_modules/fast-safe-stringify": {
1205 | "version": "2.1.1",
1206 | "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
1207 | "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==",
1208 | "dev": true
1209 | },
1210 | "node_modules/fill-range": {
1211 | "version": "7.0.1",
1212 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
1213 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
1214 | "dev": true,
1215 | "dependencies": {
1216 | "to-regex-range": "^5.0.1"
1217 | },
1218 | "engines": {
1219 | "node": ">=8"
1220 | }
1221 | },
1222 | "node_modules/finalhandler": {
1223 | "version": "1.2.0",
1224 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
1225 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
1226 | "dev": true,
1227 | "dependencies": {
1228 | "debug": "2.6.9",
1229 | "encodeurl": "~1.0.2",
1230 | "escape-html": "~1.0.3",
1231 | "on-finished": "2.4.1",
1232 | "parseurl": "~1.3.3",
1233 | "statuses": "2.0.1",
1234 | "unpipe": "~1.0.0"
1235 | },
1236 | "engines": {
1237 | "node": ">= 0.8"
1238 | }
1239 | },
1240 | "node_modules/foreground-child": {
1241 | "version": "3.1.1",
1242 | "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz",
1243 | "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==",
1244 | "dev": true,
1245 | "dependencies": {
1246 | "cross-spawn": "^7.0.0",
1247 | "signal-exit": "^4.0.1"
1248 | },
1249 | "engines": {
1250 | "node": ">=14"
1251 | },
1252 | "funding": {
1253 | "url": "https://github.com/sponsors/isaacs"
1254 | }
1255 | },
1256 | "node_modules/foreground-child/node_modules/signal-exit": {
1257 | "version": "4.1.0",
1258 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
1259 | "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
1260 | "dev": true,
1261 | "engines": {
1262 | "node": ">=14"
1263 | },
1264 | "funding": {
1265 | "url": "https://github.com/sponsors/isaacs"
1266 | }
1267 | },
1268 | "node_modules/form-data": {
1269 | "version": "4.0.0",
1270 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
1271 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
1272 | "dev": true,
1273 | "dependencies": {
1274 | "asynckit": "^0.4.0",
1275 | "combined-stream": "^1.0.8",
1276 | "mime-types": "^2.1.12"
1277 | },
1278 | "engines": {
1279 | "node": ">= 6"
1280 | }
1281 | },
1282 | "node_modules/formidable": {
1283 | "version": "3.5.1",
1284 | "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.1.tgz",
1285 | "integrity": "sha512-WJWKelbRHN41m5dumb0/k8TeAx7Id/y3a+Z7QfhxP/htI9Js5zYaEDtG8uMgG0vM0lOlqnmjE99/kfpOYi/0Og==",
1286 | "dev": true,
1287 | "dependencies": {
1288 | "dezalgo": "^1.0.4",
1289 | "hexoid": "^1.0.0",
1290 | "once": "^1.4.0"
1291 | },
1292 | "funding": {
1293 | "url": "https://ko-fi.com/tunnckoCore/commissions"
1294 | }
1295 | },
1296 | "node_modules/forwarded": {
1297 | "version": "0.2.0",
1298 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
1299 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
1300 | "dev": true,
1301 | "engines": {
1302 | "node": ">= 0.6"
1303 | }
1304 | },
1305 | "node_modules/fresh": {
1306 | "version": "0.5.2",
1307 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
1308 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
1309 | "dev": true,
1310 | "engines": {
1311 | "node": ">= 0.6"
1312 | }
1313 | },
1314 | "node_modules/function-bind": {
1315 | "version": "1.1.2",
1316 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
1317 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
1318 | "dev": true,
1319 | "funding": {
1320 | "url": "https://github.com/sponsors/ljharb"
1321 | }
1322 | },
1323 | "node_modules/get-intrinsic": {
1324 | "version": "1.2.2",
1325 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz",
1326 | "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==",
1327 | "dev": true,
1328 | "dependencies": {
1329 | "function-bind": "^1.1.2",
1330 | "has-proto": "^1.0.1",
1331 | "has-symbols": "^1.0.3",
1332 | "hasown": "^2.0.0"
1333 | },
1334 | "funding": {
1335 | "url": "https://github.com/sponsors/ljharb"
1336 | }
1337 | },
1338 | "node_modules/gopd": {
1339 | "version": "1.0.1",
1340 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
1341 | "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
1342 | "dev": true,
1343 | "dependencies": {
1344 | "get-intrinsic": "^1.1.3"
1345 | },
1346 | "funding": {
1347 | "url": "https://github.com/sponsors/ljharb"
1348 | }
1349 | },
1350 | "node_modules/graceful-fs": {
1351 | "version": "4.2.11",
1352 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
1353 | "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
1354 | "dev": true
1355 | },
1356 | "node_modules/has-flag": {
1357 | "version": "4.0.0",
1358 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
1359 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
1360 | "dev": true,
1361 | "engines": {
1362 | "node": ">=8"
1363 | }
1364 | },
1365 | "node_modules/has-property-descriptors": {
1366 | "version": "1.0.1",
1367 | "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz",
1368 | "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==",
1369 | "dev": true,
1370 | "dependencies": {
1371 | "get-intrinsic": "^1.2.2"
1372 | },
1373 | "funding": {
1374 | "url": "https://github.com/sponsors/ljharb"
1375 | }
1376 | },
1377 | "node_modules/has-proto": {
1378 | "version": "1.0.1",
1379 | "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
1380 | "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
1381 | "dev": true,
1382 | "engines": {
1383 | "node": ">= 0.4"
1384 | },
1385 | "funding": {
1386 | "url": "https://github.com/sponsors/ljharb"
1387 | }
1388 | },
1389 | "node_modules/has-symbols": {
1390 | "version": "1.0.3",
1391 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
1392 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
1393 | "dev": true,
1394 | "engines": {
1395 | "node": ">= 0.4"
1396 | },
1397 | "funding": {
1398 | "url": "https://github.com/sponsors/ljharb"
1399 | }
1400 | },
1401 | "node_modules/hasown": {
1402 | "version": "2.0.0",
1403 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz",
1404 | "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==",
1405 | "dev": true,
1406 | "dependencies": {
1407 | "function-bind": "^1.1.2"
1408 | },
1409 | "engines": {
1410 | "node": ">= 0.4"
1411 | }
1412 | },
1413 | "node_modules/hexoid": {
1414 | "version": "1.0.0",
1415 | "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz",
1416 | "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==",
1417 | "dev": true,
1418 | "engines": {
1419 | "node": ">=8"
1420 | }
1421 | },
1422 | "node_modules/http-errors": {
1423 | "version": "2.0.0",
1424 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
1425 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
1426 | "dev": true,
1427 | "dependencies": {
1428 | "depd": "2.0.0",
1429 | "inherits": "2.0.4",
1430 | "setprototypeof": "1.2.0",
1431 | "statuses": "2.0.1",
1432 | "toidentifier": "1.0.1"
1433 | },
1434 | "engines": {
1435 | "node": ">= 0.8"
1436 | }
1437 | },
1438 | "node_modules/iconv-lite": {
1439 | "version": "0.4.24",
1440 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
1441 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
1442 | "dev": true,
1443 | "dependencies": {
1444 | "safer-buffer": ">= 2.1.2 < 3"
1445 | },
1446 | "engines": {
1447 | "node": ">=0.10.0"
1448 | }
1449 | },
1450 | "node_modules/inherits": {
1451 | "version": "2.0.4",
1452 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
1453 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
1454 | "dev": true
1455 | },
1456 | "node_modules/ipaddr.js": {
1457 | "version": "1.9.1",
1458 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
1459 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
1460 | "dev": true,
1461 | "engines": {
1462 | "node": ">= 0.10"
1463 | }
1464 | },
1465 | "node_modules/is-fullwidth-code-point": {
1466 | "version": "3.0.0",
1467 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
1468 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
1469 | "dev": true,
1470 | "engines": {
1471 | "node": ">=8"
1472 | }
1473 | },
1474 | "node_modules/is-number": {
1475 | "version": "7.0.0",
1476 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
1477 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
1478 | "dev": true,
1479 | "engines": {
1480 | "node": ">=0.12.0"
1481 | }
1482 | },
1483 | "node_modules/isarray": {
1484 | "version": "1.0.0",
1485 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
1486 | "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
1487 | "dev": true
1488 | },
1489 | "node_modules/isexe": {
1490 | "version": "2.0.0",
1491 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
1492 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
1493 | "dev": true
1494 | },
1495 | "node_modules/iterare": {
1496 | "version": "1.2.1",
1497 | "resolved": "https://registry.npmjs.org/iterare/-/iterare-1.2.1.tgz",
1498 | "integrity": "sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==",
1499 | "dev": true,
1500 | "engines": {
1501 | "node": ">=6"
1502 | }
1503 | },
1504 | "node_modules/jackspeak": {
1505 | "version": "2.3.6",
1506 | "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz",
1507 | "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==",
1508 | "dev": true,
1509 | "dependencies": {
1510 | "@isaacs/cliui": "^8.0.2"
1511 | },
1512 | "engines": {
1513 | "node": ">=14"
1514 | },
1515 | "funding": {
1516 | "url": "https://github.com/sponsors/isaacs"
1517 | },
1518 | "optionalDependencies": {
1519 | "@pkgjs/parseargs": "^0.11.0"
1520 | }
1521 | },
1522 | "node_modules/jest-diff": {
1523 | "version": "29.7.0",
1524 | "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz",
1525 | "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==",
1526 | "dev": true,
1527 | "dependencies": {
1528 | "chalk": "^4.0.0",
1529 | "diff-sequences": "^29.6.3",
1530 | "jest-get-type": "^29.6.3",
1531 | "pretty-format": "^29.7.0"
1532 | },
1533 | "engines": {
1534 | "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
1535 | }
1536 | },
1537 | "node_modules/jest-get-type": {
1538 | "version": "29.6.3",
1539 | "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz",
1540 | "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==",
1541 | "dev": true,
1542 | "engines": {
1543 | "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
1544 | }
1545 | },
1546 | "node_modules/jest-matcher-utils": {
1547 | "version": "29.7.0",
1548 | "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz",
1549 | "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==",
1550 | "dev": true,
1551 | "dependencies": {
1552 | "chalk": "^4.0.0",
1553 | "jest-diff": "^29.7.0",
1554 | "jest-get-type": "^29.6.3",
1555 | "pretty-format": "^29.7.0"
1556 | },
1557 | "engines": {
1558 | "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
1559 | }
1560 | },
1561 | "node_modules/jest-message-util": {
1562 | "version": "29.7.0",
1563 | "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz",
1564 | "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==",
1565 | "dev": true,
1566 | "dependencies": {
1567 | "@babel/code-frame": "^7.12.13",
1568 | "@jest/types": "^29.6.3",
1569 | "@types/stack-utils": "^2.0.0",
1570 | "chalk": "^4.0.0",
1571 | "graceful-fs": "^4.2.9",
1572 | "micromatch": "^4.0.4",
1573 | "pretty-format": "^29.7.0",
1574 | "slash": "^3.0.0",
1575 | "stack-utils": "^2.0.3"
1576 | },
1577 | "engines": {
1578 | "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
1579 | }
1580 | },
1581 | "node_modules/jest-util": {
1582 | "version": "29.7.0",
1583 | "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz",
1584 | "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==",
1585 | "dev": true,
1586 | "dependencies": {
1587 | "@jest/types": "^29.6.3",
1588 | "@types/node": "*",
1589 | "chalk": "^4.0.0",
1590 | "ci-info": "^3.2.0",
1591 | "graceful-fs": "^4.2.9",
1592 | "picomatch": "^2.2.3"
1593 | },
1594 | "engines": {
1595 | "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
1596 | }
1597 | },
1598 | "node_modules/js-tokens": {
1599 | "version": "4.0.0",
1600 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
1601 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
1602 | "dev": true
1603 | },
1604 | "node_modules/lru-cache": {
1605 | "version": "10.2.2",
1606 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz",
1607 | "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==",
1608 | "engines": {
1609 | "node": "14 || >=16.14"
1610 | }
1611 | },
1612 | "node_modules/make-error": {
1613 | "version": "1.3.6",
1614 | "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
1615 | "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
1616 | "dev": true
1617 | },
1618 | "node_modules/media-typer": {
1619 | "version": "0.3.0",
1620 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
1621 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
1622 | "dev": true,
1623 | "engines": {
1624 | "node": ">= 0.6"
1625 | }
1626 | },
1627 | "node_modules/merge-descriptors": {
1628 | "version": "1.0.1",
1629 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
1630 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==",
1631 | "dev": true
1632 | },
1633 | "node_modules/methods": {
1634 | "version": "1.1.2",
1635 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
1636 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
1637 | "dev": true,
1638 | "engines": {
1639 | "node": ">= 0.6"
1640 | }
1641 | },
1642 | "node_modules/micromatch": {
1643 | "version": "4.0.5",
1644 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
1645 | "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
1646 | "dev": true,
1647 | "dependencies": {
1648 | "braces": "^3.0.2",
1649 | "picomatch": "^2.3.1"
1650 | },
1651 | "engines": {
1652 | "node": ">=8.6"
1653 | }
1654 | },
1655 | "node_modules/mime": {
1656 | "version": "1.6.0",
1657 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
1658 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
1659 | "dev": true,
1660 | "bin": {
1661 | "mime": "cli.js"
1662 | },
1663 | "engines": {
1664 | "node": ">=4"
1665 | }
1666 | },
1667 | "node_modules/mime-db": {
1668 | "version": "1.52.0",
1669 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
1670 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
1671 | "dev": true,
1672 | "engines": {
1673 | "node": ">= 0.6"
1674 | }
1675 | },
1676 | "node_modules/mime-types": {
1677 | "version": "2.1.35",
1678 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
1679 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
1680 | "dev": true,
1681 | "dependencies": {
1682 | "mime-db": "1.52.0"
1683 | },
1684 | "engines": {
1685 | "node": ">= 0.6"
1686 | }
1687 | },
1688 | "node_modules/minimist": {
1689 | "version": "1.2.8",
1690 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
1691 | "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
1692 | "dev": true,
1693 | "funding": {
1694 | "url": "https://github.com/sponsors/ljharb"
1695 | }
1696 | },
1697 | "node_modules/minipass": {
1698 | "version": "7.0.4",
1699 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz",
1700 | "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==",
1701 | "dev": true,
1702 | "engines": {
1703 | "node": ">=16 || 14 >=14.17"
1704 | }
1705 | },
1706 | "node_modules/mkdirp": {
1707 | "version": "0.5.6",
1708 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
1709 | "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
1710 | "dev": true,
1711 | "dependencies": {
1712 | "minimist": "^1.2.6"
1713 | },
1714 | "bin": {
1715 | "mkdirp": "bin/cmd.js"
1716 | }
1717 | },
1718 | "node_modules/ms": {
1719 | "version": "2.0.0",
1720 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
1721 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
1722 | "dev": true
1723 | },
1724 | "node_modules/multer": {
1725 | "version": "1.4.4-lts.1",
1726 | "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.4-lts.1.tgz",
1727 | "integrity": "sha512-WeSGziVj6+Z2/MwQo3GvqzgR+9Uc+qt8SwHKh3gvNPiISKfsMfG4SvCOFYlxxgkXt7yIV2i1yczehm0EOKIxIg==",
1728 | "dev": true,
1729 | "dependencies": {
1730 | "append-field": "^1.0.0",
1731 | "busboy": "^1.0.0",
1732 | "concat-stream": "^1.5.2",
1733 | "mkdirp": "^0.5.4",
1734 | "object-assign": "^4.1.1",
1735 | "type-is": "^1.6.4",
1736 | "xtend": "^4.0.0"
1737 | },
1738 | "engines": {
1739 | "node": ">= 6.0.0"
1740 | }
1741 | },
1742 | "node_modules/negotiator": {
1743 | "version": "0.6.3",
1744 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
1745 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
1746 | "dev": true,
1747 | "engines": {
1748 | "node": ">= 0.6"
1749 | }
1750 | },
1751 | "node_modules/node-fetch": {
1752 | "version": "2.7.0",
1753 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
1754 | "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
1755 | "dev": true,
1756 | "dependencies": {
1757 | "whatwg-url": "^5.0.0"
1758 | },
1759 | "engines": {
1760 | "node": "4.x || >=6.0.0"
1761 | },
1762 | "peerDependencies": {
1763 | "encoding": "^0.1.0"
1764 | },
1765 | "peerDependenciesMeta": {
1766 | "encoding": {
1767 | "optional": true
1768 | }
1769 | }
1770 | },
1771 | "node_modules/object-assign": {
1772 | "version": "4.1.1",
1773 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
1774 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
1775 | "dev": true,
1776 | "engines": {
1777 | "node": ">=0.10.0"
1778 | }
1779 | },
1780 | "node_modules/object-inspect": {
1781 | "version": "1.13.1",
1782 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz",
1783 | "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==",
1784 | "dev": true,
1785 | "funding": {
1786 | "url": "https://github.com/sponsors/ljharb"
1787 | }
1788 | },
1789 | "node_modules/on-finished": {
1790 | "version": "2.4.1",
1791 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
1792 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
1793 | "dev": true,
1794 | "dependencies": {
1795 | "ee-first": "1.1.1"
1796 | },
1797 | "engines": {
1798 | "node": ">= 0.8"
1799 | }
1800 | },
1801 | "node_modules/once": {
1802 | "version": "1.4.0",
1803 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
1804 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
1805 | "dev": true,
1806 | "dependencies": {
1807 | "wrappy": "1"
1808 | }
1809 | },
1810 | "node_modules/parseurl": {
1811 | "version": "1.3.3",
1812 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
1813 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
1814 | "dev": true,
1815 | "engines": {
1816 | "node": ">= 0.8"
1817 | }
1818 | },
1819 | "node_modules/path-key": {
1820 | "version": "3.1.1",
1821 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
1822 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
1823 | "dev": true,
1824 | "engines": {
1825 | "node": ">=8"
1826 | }
1827 | },
1828 | "node_modules/path-scurry": {
1829 | "version": "1.10.1",
1830 | "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz",
1831 | "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==",
1832 | "dev": true,
1833 | "dependencies": {
1834 | "lru-cache": "^9.1.1 || ^10.0.0",
1835 | "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
1836 | },
1837 | "engines": {
1838 | "node": ">=16 || 14 >=14.17"
1839 | },
1840 | "funding": {
1841 | "url": "https://github.com/sponsors/isaacs"
1842 | }
1843 | },
1844 | "node_modules/path-to-regexp": {
1845 | "version": "3.2.0",
1846 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.2.0.tgz",
1847 | "integrity": "sha512-jczvQbCUS7XmS7o+y1aEO9OBVFeZBQ1MDSEqmO7xSoPgOPoowY/SxLpZ6Vh97/8qHZOteiCKb7gkG9gA2ZUxJA==",
1848 | "dev": true
1849 | },
1850 | "node_modules/picomatch": {
1851 | "version": "2.3.1",
1852 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
1853 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
1854 | "dev": true,
1855 | "engines": {
1856 | "node": ">=8.6"
1857 | },
1858 | "funding": {
1859 | "url": "https://github.com/sponsors/jonschlinkert"
1860 | }
1861 | },
1862 | "node_modules/pretty-format": {
1863 | "version": "29.7.0",
1864 | "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
1865 | "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
1866 | "dev": true,
1867 | "dependencies": {
1868 | "@jest/schemas": "^29.6.3",
1869 | "ansi-styles": "^5.0.0",
1870 | "react-is": "^18.0.0"
1871 | },
1872 | "engines": {
1873 | "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
1874 | }
1875 | },
1876 | "node_modules/pretty-format/node_modules/ansi-styles": {
1877 | "version": "5.2.0",
1878 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
1879 | "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
1880 | "dev": true,
1881 | "engines": {
1882 | "node": ">=10"
1883 | },
1884 | "funding": {
1885 | "url": "https://github.com/chalk/ansi-styles?sponsor=1"
1886 | }
1887 | },
1888 | "node_modules/process-nextick-args": {
1889 | "version": "2.0.1",
1890 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
1891 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
1892 | "dev": true
1893 | },
1894 | "node_modules/proxy-addr": {
1895 | "version": "2.0.7",
1896 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
1897 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
1898 | "dev": true,
1899 | "dependencies": {
1900 | "forwarded": "0.2.0",
1901 | "ipaddr.js": "1.9.1"
1902 | },
1903 | "engines": {
1904 | "node": ">= 0.10"
1905 | }
1906 | },
1907 | "node_modules/qs": {
1908 | "version": "6.11.0",
1909 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
1910 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
1911 | "dev": true,
1912 | "dependencies": {
1913 | "side-channel": "^1.0.4"
1914 | },
1915 | "engines": {
1916 | "node": ">=0.6"
1917 | },
1918 | "funding": {
1919 | "url": "https://github.com/sponsors/ljharb"
1920 | }
1921 | },
1922 | "node_modules/range-parser": {
1923 | "version": "1.2.1",
1924 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
1925 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
1926 | "dev": true,
1927 | "engines": {
1928 | "node": ">= 0.6"
1929 | }
1930 | },
1931 | "node_modules/raw-body": {
1932 | "version": "2.5.2",
1933 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
1934 | "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
1935 | "dev": true,
1936 | "dependencies": {
1937 | "bytes": "3.1.2",
1938 | "http-errors": "2.0.0",
1939 | "iconv-lite": "0.4.24",
1940 | "unpipe": "1.0.0"
1941 | },
1942 | "engines": {
1943 | "node": ">= 0.8"
1944 | }
1945 | },
1946 | "node_modules/react-is": {
1947 | "version": "18.2.0",
1948 | "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
1949 | "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
1950 | "dev": true
1951 | },
1952 | "node_modules/readable-stream": {
1953 | "version": "2.3.8",
1954 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
1955 | "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
1956 | "dev": true,
1957 | "dependencies": {
1958 | "core-util-is": "~1.0.0",
1959 | "inherits": "~2.0.3",
1960 | "isarray": "~1.0.0",
1961 | "process-nextick-args": "~2.0.0",
1962 | "safe-buffer": "~5.1.1",
1963 | "string_decoder": "~1.1.1",
1964 | "util-deprecate": "~1.0.1"
1965 | }
1966 | },
1967 | "node_modules/readable-stream/node_modules/safe-buffer": {
1968 | "version": "5.1.2",
1969 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
1970 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
1971 | "dev": true
1972 | },
1973 | "node_modules/reflect-metadata": {
1974 | "version": "0.2.2",
1975 | "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz",
1976 | "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==",
1977 | "dev": true
1978 | },
1979 | "node_modules/rimraf": {
1980 | "version": "5.0.7",
1981 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.7.tgz",
1982 | "integrity": "sha512-nV6YcJo5wbLW77m+8KjH8aB/7/rxQy9SZ0HY5shnwULfS+9nmTtVXAJET5NdZmCzA4fPI/Hm1wo/Po/4mopOdg==",
1983 | "dev": true,
1984 | "dependencies": {
1985 | "glob": "^10.3.7"
1986 | },
1987 | "bin": {
1988 | "rimraf": "dist/esm/bin.mjs"
1989 | },
1990 | "engines": {
1991 | "node": ">=14.18"
1992 | },
1993 | "funding": {
1994 | "url": "https://github.com/sponsors/isaacs"
1995 | }
1996 | },
1997 | "node_modules/rimraf/node_modules/brace-expansion": {
1998 | "version": "2.0.1",
1999 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
2000 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
2001 | "dev": true,
2002 | "dependencies": {
2003 | "balanced-match": "^1.0.0"
2004 | }
2005 | },
2006 | "node_modules/rimraf/node_modules/glob": {
2007 | "version": "10.3.10",
2008 | "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz",
2009 | "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==",
2010 | "dev": true,
2011 | "dependencies": {
2012 | "foreground-child": "^3.1.0",
2013 | "jackspeak": "^2.3.5",
2014 | "minimatch": "^9.0.1",
2015 | "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0",
2016 | "path-scurry": "^1.10.1"
2017 | },
2018 | "bin": {
2019 | "glob": "dist/esm/bin.mjs"
2020 | },
2021 | "engines": {
2022 | "node": ">=16 || 14 >=14.17"
2023 | },
2024 | "funding": {
2025 | "url": "https://github.com/sponsors/isaacs"
2026 | }
2027 | },
2028 | "node_modules/rimraf/node_modules/minimatch": {
2029 | "version": "9.0.3",
2030 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
2031 | "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
2032 | "dev": true,
2033 | "dependencies": {
2034 | "brace-expansion": "^2.0.1"
2035 | },
2036 | "engines": {
2037 | "node": ">=16 || 14 >=14.17"
2038 | },
2039 | "funding": {
2040 | "url": "https://github.com/sponsors/isaacs"
2041 | }
2042 | },
2043 | "node_modules/rxjs": {
2044 | "version": "7.8.1",
2045 | "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
2046 | "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
2047 | "dev": true,
2048 | "dependencies": {
2049 | "tslib": "^2.1.0"
2050 | }
2051 | },
2052 | "node_modules/safe-buffer": {
2053 | "version": "5.2.1",
2054 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
2055 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
2056 | "dev": true,
2057 | "funding": [
2058 | {
2059 | "type": "github",
2060 | "url": "https://github.com/sponsors/feross"
2061 | },
2062 | {
2063 | "type": "patreon",
2064 | "url": "https://www.patreon.com/feross"
2065 | },
2066 | {
2067 | "type": "consulting",
2068 | "url": "https://feross.org/support"
2069 | }
2070 | ]
2071 | },
2072 | "node_modules/safer-buffer": {
2073 | "version": "2.1.2",
2074 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
2075 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
2076 | "dev": true
2077 | },
2078 | "node_modules/send": {
2079 | "version": "0.18.0",
2080 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
2081 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
2082 | "dev": true,
2083 | "dependencies": {
2084 | "debug": "2.6.9",
2085 | "depd": "2.0.0",
2086 | "destroy": "1.2.0",
2087 | "encodeurl": "~1.0.2",
2088 | "escape-html": "~1.0.3",
2089 | "etag": "~1.8.1",
2090 | "fresh": "0.5.2",
2091 | "http-errors": "2.0.0",
2092 | "mime": "1.6.0",
2093 | "ms": "2.1.3",
2094 | "on-finished": "2.4.1",
2095 | "range-parser": "~1.2.1",
2096 | "statuses": "2.0.1"
2097 | },
2098 | "engines": {
2099 | "node": ">= 0.8.0"
2100 | }
2101 | },
2102 | "node_modules/send/node_modules/ms": {
2103 | "version": "2.1.3",
2104 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
2105 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
2106 | "dev": true
2107 | },
2108 | "node_modules/serve-static": {
2109 | "version": "1.15.0",
2110 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
2111 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
2112 | "dev": true,
2113 | "dependencies": {
2114 | "encodeurl": "~1.0.2",
2115 | "escape-html": "~1.0.3",
2116 | "parseurl": "~1.3.3",
2117 | "send": "0.18.0"
2118 | },
2119 | "engines": {
2120 | "node": ">= 0.8.0"
2121 | }
2122 | },
2123 | "node_modules/set-function-length": {
2124 | "version": "1.1.1",
2125 | "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz",
2126 | "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==",
2127 | "dev": true,
2128 | "dependencies": {
2129 | "define-data-property": "^1.1.1",
2130 | "get-intrinsic": "^1.2.1",
2131 | "gopd": "^1.0.1",
2132 | "has-property-descriptors": "^1.0.0"
2133 | },
2134 | "engines": {
2135 | "node": ">= 0.4"
2136 | }
2137 | },
2138 | "node_modules/setprototypeof": {
2139 | "version": "1.2.0",
2140 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
2141 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
2142 | "dev": true
2143 | },
2144 | "node_modules/shebang-command": {
2145 | "version": "2.0.0",
2146 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
2147 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
2148 | "dev": true,
2149 | "dependencies": {
2150 | "shebang-regex": "^3.0.0"
2151 | },
2152 | "engines": {
2153 | "node": ">=8"
2154 | }
2155 | },
2156 | "node_modules/shebang-regex": {
2157 | "version": "3.0.0",
2158 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
2159 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
2160 | "dev": true,
2161 | "engines": {
2162 | "node": ">=8"
2163 | }
2164 | },
2165 | "node_modules/side-channel": {
2166 | "version": "1.0.4",
2167 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
2168 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
2169 | "dev": true,
2170 | "dependencies": {
2171 | "call-bind": "^1.0.0",
2172 | "get-intrinsic": "^1.0.2",
2173 | "object-inspect": "^1.9.0"
2174 | },
2175 | "funding": {
2176 | "url": "https://github.com/sponsors/ljharb"
2177 | }
2178 | },
2179 | "node_modules/slash": {
2180 | "version": "3.0.0",
2181 | "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
2182 | "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
2183 | "dev": true,
2184 | "engines": {
2185 | "node": ">=8"
2186 | }
2187 | },
2188 | "node_modules/stack-utils": {
2189 | "version": "2.0.6",
2190 | "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
2191 | "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==",
2192 | "dev": true,
2193 | "dependencies": {
2194 | "escape-string-regexp": "^2.0.0"
2195 | },
2196 | "engines": {
2197 | "node": ">=10"
2198 | }
2199 | },
2200 | "node_modules/statuses": {
2201 | "version": "2.0.1",
2202 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
2203 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
2204 | "dev": true,
2205 | "engines": {
2206 | "node": ">= 0.8"
2207 | }
2208 | },
2209 | "node_modules/streamsearch": {
2210 | "version": "1.1.0",
2211 | "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
2212 | "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==",
2213 | "dev": true,
2214 | "engines": {
2215 | "node": ">=10.0.0"
2216 | }
2217 | },
2218 | "node_modules/string_decoder": {
2219 | "version": "1.1.1",
2220 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
2221 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
2222 | "dev": true,
2223 | "dependencies": {
2224 | "safe-buffer": "~5.1.0"
2225 | }
2226 | },
2227 | "node_modules/string_decoder/node_modules/safe-buffer": {
2228 | "version": "5.1.2",
2229 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
2230 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
2231 | "dev": true
2232 | },
2233 | "node_modules/string-width": {
2234 | "version": "4.2.3",
2235 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
2236 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
2237 | "dev": true,
2238 | "dependencies": {
2239 | "emoji-regex": "^8.0.0",
2240 | "is-fullwidth-code-point": "^3.0.0",
2241 | "strip-ansi": "^6.0.1"
2242 | },
2243 | "engines": {
2244 | "node": ">=8"
2245 | }
2246 | },
2247 | "node_modules/string-width-cjs": {
2248 | "name": "string-width",
2249 | "version": "4.2.3",
2250 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
2251 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
2252 | "dev": true,
2253 | "dependencies": {
2254 | "emoji-regex": "^8.0.0",
2255 | "is-fullwidth-code-point": "^3.0.0",
2256 | "strip-ansi": "^6.0.1"
2257 | },
2258 | "engines": {
2259 | "node": ">=8"
2260 | }
2261 | },
2262 | "node_modules/strip-ansi": {
2263 | "version": "6.0.1",
2264 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
2265 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
2266 | "dev": true,
2267 | "dependencies": {
2268 | "ansi-regex": "^5.0.1"
2269 | },
2270 | "engines": {
2271 | "node": ">=8"
2272 | }
2273 | },
2274 | "node_modules/strip-ansi-cjs": {
2275 | "name": "strip-ansi",
2276 | "version": "6.0.1",
2277 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
2278 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
2279 | "dev": true,
2280 | "dependencies": {
2281 | "ansi-regex": "^5.0.1"
2282 | },
2283 | "engines": {
2284 | "node": ">=8"
2285 | }
2286 | },
2287 | "node_modules/superagent": {
2288 | "version": "9.0.2",
2289 | "resolved": "https://registry.npmjs.org/superagent/-/superagent-9.0.2.tgz",
2290 | "integrity": "sha512-xuW7dzkUpcJq7QnhOsnNUgtYp3xRwpt2F7abdRYIpCsAt0hhUqia0EdxyXZQQpNmGtsCzYHryaKSV3q3GJnq7w==",
2291 | "dev": true,
2292 | "dependencies": {
2293 | "component-emitter": "^1.3.0",
2294 | "cookiejar": "^2.1.4",
2295 | "debug": "^4.3.4",
2296 | "fast-safe-stringify": "^2.1.1",
2297 | "form-data": "^4.0.0",
2298 | "formidable": "^3.5.1",
2299 | "methods": "^1.1.2",
2300 | "mime": "2.6.0",
2301 | "qs": "^6.11.0"
2302 | },
2303 | "engines": {
2304 | "node": ">=14.18.0"
2305 | }
2306 | },
2307 | "node_modules/superagent/node_modules/debug": {
2308 | "version": "4.3.5",
2309 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
2310 | "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
2311 | "dev": true,
2312 | "dependencies": {
2313 | "ms": "2.1.2"
2314 | },
2315 | "engines": {
2316 | "node": ">=6.0"
2317 | },
2318 | "peerDependenciesMeta": {
2319 | "supports-color": {
2320 | "optional": true
2321 | }
2322 | }
2323 | },
2324 | "node_modules/superagent/node_modules/mime": {
2325 | "version": "2.6.0",
2326 | "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
2327 | "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
2328 | "dev": true,
2329 | "bin": {
2330 | "mime": "cli.js"
2331 | },
2332 | "engines": {
2333 | "node": ">=4.0.0"
2334 | }
2335 | },
2336 | "node_modules/superagent/node_modules/ms": {
2337 | "version": "2.1.2",
2338 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
2339 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
2340 | "dev": true
2341 | },
2342 | "node_modules/supertest": {
2343 | "version": "7.0.0",
2344 | "resolved": "https://registry.npmjs.org/supertest/-/supertest-7.0.0.tgz",
2345 | "integrity": "sha512-qlsr7fIC0lSddmA3tzojvzubYxvlGtzumcdHgPwbFWMISQwL22MhM2Y3LNt+6w9Yyx7559VW5ab70dgphm8qQA==",
2346 | "dev": true,
2347 | "dependencies": {
2348 | "methods": "^1.1.2",
2349 | "superagent": "^9.0.1"
2350 | },
2351 | "engines": {
2352 | "node": ">=14.18.0"
2353 | }
2354 | },
2355 | "node_modules/supports-color": {
2356 | "version": "7.2.0",
2357 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
2358 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
2359 | "dev": true,
2360 | "dependencies": {
2361 | "has-flag": "^4.0.0"
2362 | },
2363 | "engines": {
2364 | "node": ">=8"
2365 | }
2366 | },
2367 | "node_modules/to-regex-range": {
2368 | "version": "5.0.1",
2369 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
2370 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
2371 | "dev": true,
2372 | "dependencies": {
2373 | "is-number": "^7.0.0"
2374 | },
2375 | "engines": {
2376 | "node": ">=8.0"
2377 | }
2378 | },
2379 | "node_modules/toidentifier": {
2380 | "version": "1.0.1",
2381 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
2382 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
2383 | "dev": true,
2384 | "engines": {
2385 | "node": ">=0.6"
2386 | }
2387 | },
2388 | "node_modules/tr46": {
2389 | "version": "0.0.3",
2390 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
2391 | "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
2392 | "dev": true
2393 | },
2394 | "node_modules/ts-node": {
2395 | "version": "10.9.2",
2396 | "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
2397 | "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
2398 | "dev": true,
2399 | "dependencies": {
2400 | "@cspotcode/source-map-support": "^0.8.0",
2401 | "@tsconfig/node10": "^1.0.7",
2402 | "@tsconfig/node12": "^1.0.7",
2403 | "@tsconfig/node14": "^1.0.0",
2404 | "@tsconfig/node16": "^1.0.2",
2405 | "acorn": "^8.4.1",
2406 | "acorn-walk": "^8.1.1",
2407 | "arg": "^4.1.0",
2408 | "create-require": "^1.1.0",
2409 | "diff": "^4.0.1",
2410 | "make-error": "^1.1.1",
2411 | "v8-compile-cache-lib": "^3.0.1",
2412 | "yn": "3.1.1"
2413 | },
2414 | "bin": {
2415 | "ts-node": "dist/bin.js",
2416 | "ts-node-cwd": "dist/bin-cwd.js",
2417 | "ts-node-esm": "dist/bin-esm.js",
2418 | "ts-node-script": "dist/bin-script.js",
2419 | "ts-node-transpile-only": "dist/bin-transpile.js",
2420 | "ts-script": "dist/bin-script-deprecated.js"
2421 | },
2422 | "peerDependencies": {
2423 | "@swc/core": ">=1.2.50",
2424 | "@swc/wasm": ">=1.2.50",
2425 | "@types/node": "*",
2426 | "typescript": ">=2.7"
2427 | },
2428 | "peerDependenciesMeta": {
2429 | "@swc/core": {
2430 | "optional": true
2431 | },
2432 | "@swc/wasm": {
2433 | "optional": true
2434 | }
2435 | }
2436 | },
2437 | "node_modules/tslib": {
2438 | "version": "2.6.2",
2439 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
2440 | "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
2441 | "dev": true
2442 | },
2443 | "node_modules/type-is": {
2444 | "version": "1.6.18",
2445 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
2446 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
2447 | "dev": true,
2448 | "dependencies": {
2449 | "media-typer": "0.3.0",
2450 | "mime-types": "~2.1.24"
2451 | },
2452 | "engines": {
2453 | "node": ">= 0.6"
2454 | }
2455 | },
2456 | "node_modules/typedarray": {
2457 | "version": "0.0.6",
2458 | "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
2459 | "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==",
2460 | "dev": true
2461 | },
2462 | "node_modules/typescript": {
2463 | "version": "5.4.5",
2464 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
2465 | "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
2466 | "dev": true,
2467 | "bin": {
2468 | "tsc": "bin/tsc",
2469 | "tsserver": "bin/tsserver"
2470 | },
2471 | "engines": {
2472 | "node": ">=14.17"
2473 | }
2474 | },
2475 | "node_modules/uid": {
2476 | "version": "2.0.2",
2477 | "resolved": "https://registry.npmjs.org/uid/-/uid-2.0.2.tgz",
2478 | "integrity": "sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==",
2479 | "dev": true,
2480 | "dependencies": {
2481 | "@lukeed/csprng": "^1.0.0"
2482 | },
2483 | "engines": {
2484 | "node": ">=8"
2485 | }
2486 | },
2487 | "node_modules/undici-types": {
2488 | "version": "5.26.5",
2489 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
2490 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
2491 | "dev": true
2492 | },
2493 | "node_modules/unpipe": {
2494 | "version": "1.0.0",
2495 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
2496 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
2497 | "dev": true,
2498 | "engines": {
2499 | "node": ">= 0.8"
2500 | }
2501 | },
2502 | "node_modules/util-deprecate": {
2503 | "version": "1.0.2",
2504 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
2505 | "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
2506 | "dev": true
2507 | },
2508 | "node_modules/utils-merge": {
2509 | "version": "1.0.1",
2510 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
2511 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
2512 | "dev": true,
2513 | "engines": {
2514 | "node": ">= 0.4.0"
2515 | }
2516 | },
2517 | "node_modules/v8-compile-cache-lib": {
2518 | "version": "3.0.1",
2519 | "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
2520 | "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
2521 | "dev": true
2522 | },
2523 | "node_modules/vary": {
2524 | "version": "1.1.2",
2525 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
2526 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
2527 | "dev": true,
2528 | "engines": {
2529 | "node": ">= 0.8"
2530 | }
2531 | },
2532 | "node_modules/webidl-conversions": {
2533 | "version": "3.0.1",
2534 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
2535 | "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
2536 | "dev": true
2537 | },
2538 | "node_modules/whatwg-url": {
2539 | "version": "5.0.0",
2540 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
2541 | "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
2542 | "dev": true,
2543 | "dependencies": {
2544 | "tr46": "~0.0.3",
2545 | "webidl-conversions": "^3.0.0"
2546 | }
2547 | },
2548 | "node_modules/which": {
2549 | "version": "2.0.2",
2550 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
2551 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
2552 | "dev": true,
2553 | "dependencies": {
2554 | "isexe": "^2.0.0"
2555 | },
2556 | "bin": {
2557 | "node-which": "bin/node-which"
2558 | },
2559 | "engines": {
2560 | "node": ">= 8"
2561 | }
2562 | },
2563 | "node_modules/wrap-ansi-cjs": {
2564 | "name": "wrap-ansi",
2565 | "version": "7.0.0",
2566 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
2567 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
2568 | "dev": true,
2569 | "dependencies": {
2570 | "ansi-styles": "^4.0.0",
2571 | "string-width": "^4.1.0",
2572 | "strip-ansi": "^6.0.0"
2573 | },
2574 | "engines": {
2575 | "node": ">=10"
2576 | },
2577 | "funding": {
2578 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
2579 | }
2580 | },
2581 | "node_modules/wrappy": {
2582 | "version": "1.0.2",
2583 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
2584 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
2585 | "dev": true
2586 | },
2587 | "node_modules/xtend": {
2588 | "version": "4.0.2",
2589 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
2590 | "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
2591 | "dev": true,
2592 | "engines": {
2593 | "node": ">=0.4"
2594 | }
2595 | },
2596 | "node_modules/yn": {
2597 | "version": "3.1.1",
2598 | "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
2599 | "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
2600 | "dev": true,
2601 | "engines": {
2602 | "node": ">=6"
2603 | }
2604 | }
2605 | }
2606 | }
2607 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nestjs-omacache",
3 | "version": "1.1.7",
4 | "description": "simple, flexible and powerful cache decorator factory for NestJS",
5 | "main": "dist/index.js",
6 | "types": "dist/index.d.ts",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/BJS-kr/nestjs-omacache.git"
10 | },
11 | "directories": {
12 | "lib": "lib"
13 | },
14 | "scripts": {
15 | "test": "ts-node lib/test/runner.ts",
16 | "build": "rimraf dist && tsc"
17 | },
18 | "devDependencies": {
19 | "@nestjs/common": "^10.3.9",
20 | "@nestjs/core": "^10.3.9",
21 | "@nestjs/platform-express": "^10.3.9",
22 | "@nestjs/testing": "^10.3.9",
23 | "@types/jest": "29.5.12",
24 | "@types/node": "20.14.2",
25 | "@types/supertest": "6.0.2",
26 | "reflect-metadata": "0.2.2",
27 | "rimraf": "5.0.7",
28 | "rxjs": "7.8.1",
29 | "supertest": "7.0.0",
30 | "ts-node": "^10.9.2",
31 | "typescript": "5.4.5"
32 | },
33 | "peerDependencies": {
34 | "@nestjs/common": ">=10",
35 | "@nestjs/core": ">=10",
36 | "reflect-metadata": "^0.2.0"
37 | },
38 | "keywords": [
39 | "nest",
40 | "nestjs",
41 | "cache",
42 | "optimization",
43 | "server"
44 | ],
45 | "author": "hahajeng1234@gmail.com",
46 | "license": "ISC",
47 | "dependencies": {
48 | "lru-cache": "^10.2.2"
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "declaration": true,
5 | "removeComments": true,
6 | "noLib": false,
7 | "emitDecoratorMetadata": true,
8 | "esModuleInterop": true,
9 | "experimentalDecorators": true,
10 | "target": "ES2021",
11 | "sourceMap": false,
12 | "outDir": "./dist",
13 | "rootDir": "./lib",
14 | "skipLibCheck": true
15 | },
16 | "include": ["lib/**/*", "dist/index.d.ts", "lib/test"],
17 | "exclude": ["node_modules", "**/*.spec.ts", "tests"]
18 | }
19 |
--------------------------------------------------------------------------------