@elysiumjs/core 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.ts CHANGED
@@ -12,7 +12,10 @@
12
12
  // See the License for the specific language governing permissions and
13
13
  // limitations under the License.
14
14
 
15
- export { type AppContext, Application } from './src/app';
15
+ import './macros';
16
+
17
+ export { type Elysia, t } from 'elysia';
18
+ export { type AppContext, type ElysiumPlugin, Application } from './src/app';
16
19
  export { Cache } from './src/cache';
17
20
  export {
18
21
  type CommandArgumentProps,
@@ -22,6 +25,7 @@ export {
22
25
  } from './src/command';
23
26
  export { ConsoleFormat, InteractsWithConsole } from './src/console';
24
27
  export { Database } from './src/database';
28
+ export { Env } from './src/env';
25
29
  export { type EventData, type EventHandler, Event } from './src/event';
26
30
  export { type Context, type Route, HttpControllerScope, Http } from './src/http';
27
31
  export { Job } from './src/job';
package/macros.ts ADDED
@@ -0,0 +1,16 @@
1
+ // Copyright (c) 2025-present Workbud Technologies Inc. All rights reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ // Disable build mode by default
16
+ global.ELYSIUM_BUILD = typeof ELYSIUM_BUILD !== 'undefined';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elysiumjs/core",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "license": "Apache-2.0",
5
5
  "description": "A super-charged web framework for Bun, built on top of ElysiaJS.",
6
6
  "private": false,
@@ -29,7 +29,7 @@
29
29
  "@elysiajs/swagger": "^1.2.2",
30
30
  "cache-manager": "^6.4.2",
31
31
  "cacheable": "^1.8.10",
32
- "drizzle-orm": "^0.42.0",
32
+ "drizzle-orm": "^0.43.1",
33
33
  "elysia": "latest",
34
34
  "radash": "^12.1.0",
35
35
  "reflect-metadata": "^0.2.2",
@@ -37,7 +37,7 @@
37
37
  },
38
38
  "devDependencies": {
39
39
  "@ianvs/prettier-plugin-sort-imports": "^4.4.1",
40
- "type-fest": "^4.40.0",
40
+ "type-fest": "^4.40.1",
41
41
  "@types/bun": "latest"
42
42
  },
43
43
  "peerDependencies": {
package/src/app.ts CHANGED
@@ -13,10 +13,10 @@
13
13
  // limitations under the License.
14
14
 
15
15
  import type { ElysiaSwaggerConfig } from '@elysiajs/swagger';
16
- import type { ElysiaConfig, ErrorContext, PreContext } from 'elysia';
16
+ import type { AnyElysia, ElysiaConfig, ErrorContext, TSchema } from 'elysia';
17
17
  import type { CommandClass } from './command';
18
18
  import type { DatabaseConnectionProps } from './database';
19
- import type { Route, Singleton } from './http';
19
+ import type { Route } from './http';
20
20
  import type { ModuleClass } from './module';
21
21
  import type { RedisConnectionProps } from './redis';
22
22
 
@@ -24,16 +24,23 @@ import { AsyncLocalStorage } from 'node:async_hooks';
24
24
  import { parseArgs } from 'node:util';
25
25
 
26
26
  import { swagger as swaggerPlugin } from '@elysiajs/swagger';
27
+ import { Value } from '@sinclair/typebox/value';
27
28
  import { Elysia } from 'elysia';
28
- import { assign } from 'radash';
29
29
 
30
30
  import { ConsoleFormat, InteractsWithConsole } from './console';
31
31
  import { Database } from './database';
32
+ import { initEnv } from './env';
32
33
  import { Event } from './event';
33
34
  import { applyMiddlewares } from './middleware';
34
35
  import { Redis } from './redis';
35
36
  import { Service } from './service';
36
- import { Symbols } from './utils';
37
+ import { deepMerge, Symbols } from './utils';
38
+
39
+ /**
40
+ * An application plugin, consisting of a function that returns an Elysia instance.
41
+ * @author Axel Nana <axel.nana@workbud.com>
42
+ */
43
+ export type ElysiumPlugin = (app: Application) => Promise<AnyElysia>;
37
44
 
38
45
  /**
39
46
  * Properties required when declaring an app using the `@app()` decorator.
@@ -101,6 +108,16 @@ export type AppProps = {
101
108
  * Set it to `false` to disable Swagger documentation.
102
109
  */
103
110
  swagger?: ElysiaSwaggerConfig<Route> | false;
111
+
112
+ /**
113
+ * The validation schema for the application environment.
114
+ */
115
+ env?: TSchema;
116
+
117
+ /**
118
+ * The list of plugins to load.
119
+ */
120
+ plugins?: ElysiumPlugin[];
104
121
  };
105
122
 
106
123
  /**
@@ -140,8 +157,35 @@ export abstract class Application extends InteractsWithConsole {
140
157
  */
141
158
  public static register(props: AppProps = {}): ClassDecorator {
142
159
  return function (target) {
143
- props = assign<AppProps>({ modules: [], database: undefined, swagger: false }, props);
144
- props = assign<AppProps>(Reflect.getMetadata(Symbols.app, target) ?? {}, props);
160
+ // Get metadata from the prototype chain
161
+ let parentMetadata: AppProps | undefined;
162
+ let proto = Object.getPrototypeOf(target);
163
+
164
+ // Traverse up the prototype chain to find metadata
165
+ while (proto && proto !== Object.prototype) {
166
+ const metadata = Reflect.getMetadata(Symbols.app, proto);
167
+ if (metadata) {
168
+ parentMetadata = metadata;
169
+ break;
170
+ }
171
+ proto = Object.getPrototypeOf(proto);
172
+ }
173
+
174
+ // Merge with parent metadata if found, then with current metadata
175
+ if (parentMetadata) {
176
+ props = deepMerge<AppProps>(parentMetadata, props);
177
+ }
178
+
179
+ // Merge with existing metadata on the current class (if any)
180
+ const currentMetadata = Reflect.getMetadata(Symbols.app, target);
181
+ if (currentMetadata) {
182
+ props = deepMerge<AppProps>(currentMetadata, props);
183
+ }
184
+
185
+ // Default props
186
+ props = deepMerge<AppProps>({ modules: [], swagger: false }, props);
187
+
188
+ // Store the merged metadata
145
189
  Reflect.defineMetadata(Symbols.app, props, target);
146
190
  };
147
191
  }
@@ -152,14 +196,25 @@ export abstract class Application extends InteractsWithConsole {
152
196
  public constructor() {
153
197
  super();
154
198
 
155
- Service.instance('elysium.app', this);
199
+ const { env, debug }: AppProps = Reflect.getMetadata(Symbols.app, this.constructor) ?? {};
200
+ this.#debug = debug ?? false;
156
201
 
157
- const { debug, database, redis } = Reflect.getMetadata(
158
- Symbols.app,
159
- this.constructor
160
- ) as AppProps;
202
+ if (env) {
203
+ const rawEnv = Value.Convert(env, Value.Clone(Bun.env));
161
204
 
162
- this.#debug = debug ?? false;
205
+ if (this.#debug && !Value.Check(env, rawEnv)) {
206
+ const error = Value.Errors(env, rawEnv).First();
207
+ this.trace(error! as unknown as Error, 'Invalid environment configuration');
208
+ }
209
+
210
+ initEnv(Value.Clean(env, rawEnv) as Record<string, unknown>);
211
+ } else {
212
+ initEnv(Bun.env);
213
+ }
214
+
215
+ Service.instance('elysium.app', this);
216
+
217
+ const { database, redis } = Reflect.getMetadata(Symbols.app, this.constructor) as AppProps;
163
218
 
164
219
  if (redis) {
165
220
  for (const connectionName in redis.connections) {
@@ -182,7 +237,13 @@ export abstract class Application extends InteractsWithConsole {
182
237
  }
183
238
 
184
239
  // Run the application
185
- this.run().then(() => Event.emit('elysium:app:launched', this, this));
240
+ this.run()
241
+ .then(() => Event.emit('elysium:app:launched', this, this))
242
+ .catch((error) => {
243
+ Event.emit('elysium:error', error);
244
+ this.trace(error, 'An error occurred while launching the application');
245
+ process.exit(1);
246
+ });
186
247
  }
187
248
 
188
249
  /**
@@ -386,27 +447,114 @@ export abstract class Application extends InteractsWithConsole {
386
447
  * Starts the server on the specified port.
387
448
  */
388
449
  private async commandServe(): Promise<void> {
389
- const { server, modules, swagger } = Reflect.getMetadata(
450
+ const { server, modules, swagger, plugins } = Reflect.getMetadata(
390
451
  Symbols.app,
391
452
  this.constructor
392
453
  ) as AppProps;
393
454
 
455
+ this.#elysia = new Elysia(server).onRequest((c) => {
456
+ if (this.isDebug) {
457
+ // TODO: Use the logger service here
458
+ console.log(c.request.method, c.request.url);
459
+ }
460
+ });
461
+
394
462
  Event.emit('elysium:server:before-init', this, this);
395
463
 
396
- this.#elysia = new Elysia(server);
464
+ this.#elysia.resolve({ as: 'global' }, ({ request }) => ({
465
+ tenant: request.headers.get('x-tenant-id') ?? 'public'
466
+ }));
397
467
 
398
- this.#elysia
399
- .onRequest((c: PreContext<Singleton>) => {
400
- c.tenant = c.request.headers.get('x-tenant-id') ?? 'public';
468
+ if (swagger) {
469
+ this.#elysia.use(await swaggerPlugin(swagger));
470
+ }
401
471
 
402
- if (this.isDebug) {
403
- // TODO: Use the logger service here
404
- console.log(c.request.method, c.request.url);
405
- }
406
- })
407
- .onError(async (e) => {
472
+ if (plugins && plugins.length > 0) {
473
+ this.debug('Registering plugins...');
474
+ for (const plugin of plugins) {
475
+ this.#elysia.use(await plugin(this));
476
+ }
477
+ }
478
+
479
+ this.#elysia
480
+ .onError({ as: 'global' }, async (e) => {
408
481
  if (await this.onError(e)) {
409
482
  Event.emit('elysium:error', e);
483
+
484
+ let data = {};
485
+
486
+ if (typeof e.code === 'number') {
487
+ data = {
488
+ message: e.error.response
489
+ };
490
+ } else {
491
+ switch (e.code) {
492
+ case 'VALIDATION': {
493
+ data = {
494
+ scope: e.error.type,
495
+ code: e.error.message
496
+ };
497
+ break;
498
+ }
499
+ case 'INTERNAL_SERVER_ERROR': {
500
+ data = {
501
+ message: e.error.message
502
+ };
503
+ break;
504
+ }
505
+ }
506
+ }
507
+
508
+ const type = (() => {
509
+ if (typeof e.code === 'string') return e.code;
510
+ else {
511
+ switch (e.code) {
512
+ case 500:
513
+ return 'INTERNAL_SERVER_ERROR';
514
+ case 400:
515
+ return 'BAD_REQUEST';
516
+ case 401:
517
+ return 'UNAUTHORIZED';
518
+ case 403:
519
+ return 'FORBIDDEN';
520
+ case 404:
521
+ return 'NOT_FOUND';
522
+ case 405:
523
+ return 'METHOD_NOT_ALLOWED';
524
+ case 409:
525
+ return 'CONFLICT';
526
+ case 429:
527
+ return 'TOO_MANY_REQUESTS';
528
+ case 422:
529
+ return 'UNPROCESSABLE_ENTITY';
530
+ case 426:
531
+ return 'UPGRADE_REQUIRED';
532
+ case 428:
533
+ return 'PRECONDITION_REQUIRED';
534
+ case 431:
535
+ return 'REQUEST_HEADER_FIELDS_TOO_LARGE';
536
+ case 451:
537
+ return 'UNAVAILABLE_FOR_LEGAL_REASONS';
538
+ case 501:
539
+ return 'NOT_IMPLEMENTED';
540
+ case 502:
541
+ return 'BAD_GATEWAY';
542
+ case 503:
543
+ return 'SERVICE_UNAVAILABLE';
544
+ case 504:
545
+ return 'GATEWAY_TIMEOUT';
546
+ case 505:
547
+ return 'HTTP_VERSION_NOT_SUPPORTED';
548
+ }
549
+ }
550
+
551
+ return 'UNKNOWN';
552
+ })();
553
+
554
+ return {
555
+ type,
556
+ data
557
+ };
410
558
  }
411
559
  })
412
560
  .onStart(async (elysia) => {
@@ -419,12 +567,6 @@ export abstract class Application extends InteractsWithConsole {
419
567
  this._appContextStorage.disable();
420
568
  });
421
569
 
422
- Event.emit('elysium:server:after-init', this, this);
423
-
424
- if (swagger) {
425
- this.#elysia.use(await swaggerPlugin(swagger));
426
- }
427
-
428
570
  const middlewares = Reflect.getMetadata(Symbols.middlewares, this.constructor) ?? [];
429
571
  applyMiddlewares(middlewares, this.#elysia);
430
572
 
@@ -445,12 +587,13 @@ export abstract class Application extends InteractsWithConsole {
445
587
  module.afterRegister();
446
588
  }
447
589
 
590
+ Event.emit('elysium:server:after-init', this, this);
591
+
448
592
  // Register the server
449
593
  this.#elysia.listen(server?.port ?? (parseInt(process.env.PORT!, 10) || 3000));
450
594
 
451
595
  process.on('SIGINT', () => {
452
- this.#elysia.stop();
453
- return process.exit(0);
596
+ this.#elysia.stop().then(() => process.exit(0));
454
597
  });
455
598
  }
456
599
 
package/src/console.ts CHANGED
@@ -166,7 +166,7 @@ export class InteractsWithConsole {
166
166
  this.write(this.format('Additional Information:', ConsoleFormat.BOLD));
167
167
  Object.keys(customProps).forEach((prop) => {
168
168
  const value = error[prop];
169
- this.write(`\t${prop}: ${JSON.stringify(value)}`, false);
169
+ this.write(`\t${prop}: ${JSON.stringify(value)}`);
170
170
  });
171
171
  }
172
172
  }
package/src/env.ts ADDED
@@ -0,0 +1,58 @@
1
+ // Copyright (c) 2025-present Workbud Technologies Inc. All rights reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ import type { AppEnv } from '@elysiumjs/core';
16
+
17
+ const env: Map<string, unknown> = new Map();
18
+
19
+ /**
20
+ * Initializes the environment variables.
21
+ * @author Axel Nana <axel.nana@workbud.com>
22
+ * @param vars The environment variables to initialize.
23
+ */
24
+ export const initEnv = (vars: Record<string, unknown>) => {
25
+ for (const [key, value] of Object.entries(vars)) {
26
+ env.set(key, value);
27
+ }
28
+ };
29
+
30
+ export namespace Env {
31
+ /**
32
+ * Gets the value of an environment variable.
33
+ * @author Axel Nana <axel.nana@workbud.com>
34
+ * @param name The name of the environment variable.
35
+ * @returns The value of the environment variable.
36
+ */
37
+ export const get = <TKey extends keyof AppEnv>(name: TKey): AppEnv[TKey] => {
38
+ return env.get(name) as AppEnv[TKey];
39
+ };
40
+
41
+ /**
42
+ * Checks if an environment variable exists.
43
+ * @author Axel Nana <axel.nana@workbud.com>
44
+ * @param name The name of the environment variable.
45
+ * @returns `true` if the environment variable exists, `false` otherwise.
46
+ */
47
+ export const exists = <TKey extends keyof AppEnv>(name: TKey): boolean => {
48
+ return env.has(name);
49
+ };
50
+
51
+ /**
52
+ * Clears the environment variables.
53
+ * @author Axel Nana <axel.nana@workbud.com>
54
+ */
55
+ export const clear = () => {
56
+ env.clear();
57
+ };
58
+ }
package/src/http.ts CHANGED
@@ -12,15 +12,9 @@
12
12
  // See the License for the specific language governing permissions and
13
13
  // limitations under the License.
14
14
 
15
- import type {
16
- Context as ElysiaContext,
17
- Handler,
18
- HTTPMethod,
19
- PreContext,
20
- SingletonBase,
21
- TSchema
22
- } from 'elysia';
23
- import type { Class } from 'type-fest';
15
+ import type { AppHttpContext } from '@elysiumjs/core';
16
+ import type { Context as ElysiaContext, Handler, HTTPMethod, PreContext, TSchema } from 'elysia';
17
+ import type { Class, MergeDeep } from 'type-fest';
24
18
  import type { Middleware } from './middleware';
25
19
  import type { Module } from './module';
26
20
 
@@ -140,22 +134,31 @@ type HttpRequestHandlerRegistrationProps = Pick<
140
134
  * Metadata for the HTTP context.
141
135
  * @author Axel Nana <axel.nana@workbud.com>
142
136
  */
143
- export type Singleton<TController = unknown, TModule extends Module = Module> = SingletonBase & {
144
- /**
145
- * The controller instance.
146
- */
147
- controller: TController;
148
-
149
- /**
150
- * The module instance.
151
- */
152
- module: TModule;
137
+ export type Singleton<TController = unknown, TModule extends Module = Module> = MergeDeep<
138
+ AppHttpContext,
139
+ {
140
+ decorator: {
141
+ [key: string]: unknown;
142
+
143
+ /**
144
+ * The controller instance.
145
+ */
146
+ controller: () => TController;
147
+
148
+ /**
149
+ * The module instance.
150
+ */
151
+ module: TModule;
152
+ };
153
153
 
154
- /**
155
- * The tenant ID.
156
- */
157
- tenant: string;
158
- };
154
+ resolve: {
155
+ /**
156
+ * The tenant ID.
157
+ */
158
+ readonly tenant: string;
159
+ };
160
+ }
161
+ >;
159
162
 
160
163
  /**
161
164
  * The Elysia context with the controller injected.
@@ -166,6 +169,8 @@ export type Context<TController = unknown, TModule extends Module = Module> = El
166
169
  Singleton<TController, TModule>
167
170
  >;
168
171
 
172
+ export type ElysiaApp = Elysia<Route, Singleton>;
173
+
169
174
  const registerHttpRequestHandler = (props: HttpRequestHandlerRegistrationProps) => {
170
175
  const body = Reflect.getMetadata('http:body', props.target, props.propertyKey);
171
176
  const params = Reflect.getMetadata('http:params', props.target, props.propertyKey) ?? [];
@@ -295,32 +300,30 @@ export namespace Http {
295
300
  */
296
301
  export const controller = (props: HttpControllerProps = { path: '/' }) => {
297
302
  return function (target: Class<any>) {
298
- async function handleHttp(): Promise<Elysia<Route>> {
303
+ async function handleHttp(): Promise<ElysiaApp> {
299
304
  // TODO: Use the logger service here
300
305
  console.log(`Registering HTTP route for ${props.path} using ${target.name}`);
301
306
  await nextTick();
302
307
 
303
308
  props = assign({ path: '/', scope: HttpControllerScope.SERVER, tags: [] }, props);
304
309
 
305
- const app = new Elysia({
310
+ const app: ElysiaApp = new Elysia({
306
311
  prefix: props.path,
307
312
  name: target.name
308
313
  });
309
314
 
310
315
  if (props.scope === HttpControllerScope.SERVER) {
311
- app.decorate('controller', Service.make(target));
316
+ const controller = Service.make(target);
317
+ app.decorate('controller', () => controller);
312
318
  } else if (props.scope === HttpControllerScope.REQUEST) {
313
- app.resolve({ as: 'scoped' }, () => ({
314
- controller: Service.make(target)
315
- }));
319
+ app.decorate('controller', () => Service.make(target));
316
320
  }
317
321
 
318
322
  const onRequest = Reflect.getMetadata('http:onRequest', target) ?? {};
319
323
  if (onRequest.handler) {
320
- app.onRequest((c: PreContext<SingletonBase & { controller: any }>) => {
321
- const controller = c.controller;
322
- const handler = onRequest.handler.bind(controller);
323
- return handler(c);
324
+ app.onRequest((c: PreContext<Singleton>) => {
325
+ const controller = c.controller();
326
+ return onRequest.handler.call(controller, c);
324
327
  });
325
328
  }
326
329
 
@@ -375,20 +378,18 @@ export namespace Http {
375
378
 
376
379
  const getHandler = () => {
377
380
  const initTransactedHandler = (c: Context) => {
378
- const controller = c.controller;
379
-
380
381
  if (isTransactional) {
381
382
  return function (...args: unknown[]) {
382
383
  return Database.getDefaultConnection().transaction((tx) => {
383
384
  return Application.context.run(
384
385
  new Map([
385
- ['tenant', c.tenant],
386
+ ['tenant', c.tenant as unknown],
386
387
  ['http:context', c],
387
388
  ['db:tx', tx]
388
389
  ]),
389
390
  () => {
390
391
  try {
391
- return route.handler.call(controller, ...args) as Promise<unknown>;
392
+ return route.handler.call(c.controller(), ...args) as Promise<unknown>;
392
393
  } catch (e) {
393
394
  tx.rollback();
394
395
  throw e;
@@ -402,10 +403,10 @@ export namespace Http {
402
403
  return function (...args: unknown[]) {
403
404
  return Application.context.run(
404
405
  new Map([
405
- ['tenant', c.tenant],
406
+ ['tenant', c.tenant as unknown],
406
407
  ['http:context', c]
407
408
  ]),
408
- () => route.handler.call(controller, ...args) as Promise<unknown>
409
+ () => route.handler.call(c.controller(), ...args) as Promise<unknown>
409
410
  );
410
411
  };
411
412
  };
@@ -455,13 +456,13 @@ export namespace Http {
455
456
  app.route(route.method, route.path, getHandler(), {
456
457
  // @ts-ignore
457
458
  config: {},
458
- beforeHandle(c: Context) {
459
+ beforeHandle(c) {
459
460
  return executeMiddlewareChain(mi, c, 'onBeforeHandle');
460
461
  },
461
- afterHandle(c: Context) {
462
+ afterHandle(c) {
462
463
  return executeMiddlewareChain(mi, c, 'onAfterHandle');
463
464
  },
464
- afterResponse(c: Context) {
465
+ afterResponse(c) {
465
466
  return executeMiddlewareChain(mi, c, 'onAfterResponse');
466
467
  },
467
468
  detail: {
package/src/middleware.ts CHANGED
@@ -12,9 +12,9 @@
12
12
  // See the License for the specific language governing permissions and
13
13
  // limitations under the License.
14
14
 
15
- import type { Elysia } from 'elysia';
15
+ import type { AnyElysia } from 'elysia';
16
16
  import type { Class } from 'type-fest';
17
- import type { Context, Route } from './http';
17
+ import type { Context } from './http';
18
18
 
19
19
  import { Application } from './app';
20
20
  import { Service } from './service';
@@ -27,9 +27,9 @@ import { Symbols } from './utils';
27
27
  * @param context The context to pass to each middleware.
28
28
  * @param method The method to call on each middleware.
29
29
  */
30
- export const executeMiddlewareChain = <T extends Context>(
30
+ export const executeMiddlewareChain = (
31
31
  middlewares: Middleware[],
32
- context: T,
32
+ context: any,
33
33
  method: keyof Middleware
34
34
  ): Promise<any> => {
35
35
  return Application.context.run(
@@ -58,7 +58,7 @@ export const executeMiddlewareChain = <T extends Context>(
58
58
  * @param middlewares The list of middlewares to apply.
59
59
  * @param plugin The Elysia plugin instance.
60
60
  */
61
- export const applyMiddlewares = (middlewares: Class<Middleware>[], plugin: Elysia<Route>) => {
61
+ export const applyMiddlewares = (middlewares: Class<Middleware>[], plugin: AnyElysia) => {
62
62
  const mi = middlewares.map((middleware) => Service.make<Middleware>(middleware));
63
63
 
64
64
  plugin.onBeforeHandle((c) => {
package/src/model.ts CHANGED
@@ -278,21 +278,21 @@ export namespace Tenancy {
278
278
  >(
279
279
  tenant: string,
280
280
  model: T
281
- ) => {
281
+ ): ReturnType<typeof pgTable<string, TColumnsMap>> => {
282
282
  if (tenant === 'public') {
283
283
  return pgTable(model.tableName, model.columns);
284
284
  }
285
285
 
286
286
  const tableName = `${tenant}.${model.tableName}`;
287
287
  if (tenantSchemas.has(tableName)) {
288
- return tenantSchemas.get(tableName)!;
288
+ return tenantSchemas.get(tableName)! as ReturnType<typeof pgTable<string, TColumnsMap>>;
289
289
  }
290
290
 
291
291
  const tenantSchema = getTenantSchema(tenant);
292
292
  const schemaTable = tenantSchema.table(model.tableName, model.columns);
293
293
  tenantSchemas.set(tableName, schemaTable);
294
294
 
295
- return schemaTable;
295
+ return schemaTable as unknown as ReturnType<typeof pgTable<string, TColumnsMap>>;
296
296
  };
297
297
 
298
298
  /**
package/src/repository.ts CHANGED
@@ -181,7 +181,7 @@ export const Repository = <
181
181
  /**
182
182
  * The drizzle's table schema wrapped by this repository.
183
183
  */
184
- public static get table() {
184
+ public static get table(): ReturnType<typeof pgTable<string, TColumnsMap>> {
185
185
  if (model.supportTenancy) {
186
186
  const tenant = Tenancy.getCurrentTenant() ?? 'public';
187
187
  return Tenancy.withTenant(tenant, model);
package/src/utils.ts CHANGED
@@ -14,6 +14,8 @@
14
14
 
15
15
  import type { Elysia } from 'elysia';
16
16
 
17
+ import { isObject, isPrimitive } from 'radash';
18
+
17
19
  export namespace Symbols {
18
20
  export const app = Symbol('app');
19
21
 
@@ -39,3 +41,53 @@ export namespace Symbols {
39
41
  export const nextTick = () => new Promise((resolve) => process.nextTick(resolve));
40
42
 
41
43
  export type ElysiaPlugin = () => Promise<Elysia>;
44
+
45
+ /**
46
+ * Deeply merges objects from right to left
47
+ * Arrays are also merged if they are found in child objects
48
+ *
49
+ * @param target The target object to merge into
50
+ * @param sources One or more source objects to merge from
51
+ * @returns The merged object (same reference as target)
52
+ */
53
+ export function deepMerge<T extends Record<string, any | any[]>>(target: T, ...sources: T[]): T {
54
+ if (!sources.length) return target;
55
+
56
+ const source = sources.shift();
57
+ if (source === undefined) return target;
58
+
59
+ if (isObject(target) && isObject(source)) {
60
+ for (const key in source) {
61
+ if (isObject(source[key])) {
62
+ if (!target[key]) {
63
+ Object.assign(target, { [key]: source[key] });
64
+ }
65
+ } else if (Array.isArray(source[key])) {
66
+ if (!Array.isArray(target[key])) {
67
+ target[key] = [] as any;
68
+ }
69
+ // Merge arrays by concatenating and removing duplicates for primitive values
70
+ if (source[key].length > 0 && !isObject(source[key][0])) {
71
+ target[key] = [...new Set([...target[key], ...source[key]])] as any;
72
+ } else {
73
+ // For arrays of objects, merge each item
74
+ source[key].forEach((item: any, index: number) => {
75
+ if (isObject(item) && target[key][index]) {
76
+ target[key][index] = deepMerge(target[key][index], item);
77
+ } else {
78
+ if (!target[key].includes(item)) {
79
+ target[key].push(item);
80
+ }
81
+ }
82
+ });
83
+ }
84
+ } else if (isPrimitive(source[key])) {
85
+ target[key] ??= source[key];
86
+ } else {
87
+ deepMerge(target[key], source[key]);
88
+ }
89
+ }
90
+ }
91
+
92
+ return deepMerge(target, ...sources);
93
+ }
package/src/wamp.ts CHANGED
@@ -223,43 +223,47 @@ export namespace Wamp {
223
223
  onReconnectSuccess: metadata.reconnectSuccess?.bind(controller)
224
224
  });
225
225
 
226
- const registrations: WampRegistration[] = metadata.registrations ?? [];
227
- const subscriptions: WampSubscription[] = metadata.subscriptions ?? [];
228
-
229
- for (const registration of registrations) {
230
- w.register(
231
- registration.topic,
232
- registration.handler.bind(controller),
233
- registration.options
234
- ).then((r: { topic: string; requestId: string; registrationId: string }) => {
235
- // TODO: Use the logger service here
236
- console.log(`Registered ${registration.topic} with id ${r.registrationId}`);
237
- });
238
- }
239
-
240
- for (const subscription of subscriptions) {
241
- w.subscribe(
242
- subscription.topic,
243
- subscription.handler.bind(controller),
244
- subscription.options
245
- ).then(
246
- (s: {
247
- topic: string;
248
- requestId: string;
249
- subscriptionId: string;
250
- subscriptionKey: string;
251
- }) => {
252
- // TODO: Use the logger service here
253
- console.log(`Subscribed ${subscription.topic} with id ${s.subscriptionId}`);
254
- }
255
- );
256
- }
257
-
258
226
  const app = new Elysia();
259
227
 
260
228
  app.onStart(async (_) => {
261
- await w.connect();
262
- metadata.open?.call(controller);
229
+ try {
230
+ await w.connect();
231
+ metadata.open?.call(controller);
232
+
233
+ const registrations: WampRegistration[] = metadata.registrations ?? [];
234
+ const subscriptions: WampSubscription[] = metadata.subscriptions ?? [];
235
+
236
+ for (const registration of registrations) {
237
+ w.register(
238
+ registration.topic,
239
+ registration.handler.bind(controller),
240
+ registration.options
241
+ ).then((r: { topic: string; requestId: string; registrationId: string }) => {
242
+ // TODO: Use the logger service here
243
+ console.log(`Registered ${registration.topic} with id ${r.registrationId}`);
244
+ });
245
+ }
246
+
247
+ for (const subscription of subscriptions) {
248
+ w.subscribe(
249
+ subscription.topic,
250
+ subscription.handler.bind(controller),
251
+ subscription.options
252
+ ).then(
253
+ (s: {
254
+ topic: string;
255
+ requestId: string;
256
+ subscriptionId: string;
257
+ subscriptionKey: string;
258
+ }) => {
259
+ // TODO: Use the logger service here
260
+ console.log(`Subscribed ${subscription.topic} with id ${s.subscriptionId}`);
261
+ }
262
+ );
263
+ }
264
+ } catch (error) {
265
+ // noop
266
+ }
263
267
  });
264
268
 
265
269
  return app;
package/src/websocket.ts CHANGED
@@ -108,10 +108,11 @@ export namespace Websocket {
108
108
 
109
109
  /**
110
110
  * Marks a method as the websocket "open" event handler.
111
- * @author Axel Nana <axel.nana@workbud.com>
112
111
  *
113
112
  * This decorator should be used on a websocket controller method. Only one "open" event handler
114
113
  * can be defined per websocket controller.
114
+ *
115
+ * @author Axel Nana <axel.nana@workbud.com>
115
116
  */
116
117
  export const onOpen = (): MethodDecorator => {
117
118
  return function (target, propertyKey, descriptor) {
@@ -123,10 +124,11 @@ export namespace Websocket {
123
124
 
124
125
  /**
125
126
  * Marks a method as the websocket "close" event handler.
126
- * @author Axel Nana <axel.nana@workbud.com>
127
127
  *
128
128
  * This decorator should be used on a websocket controller method. Only one "close" event handler
129
129
  * can be defined per websocket controller.
130
+ *
131
+ * @author Axel Nana <axel.nana@workbud.com>
130
132
  */
131
133
  export const onClose = (): MethodDecorator => {
132
134
  return function (target, propertyKey, descriptor) {
@@ -138,14 +140,15 @@ export namespace Websocket {
138
140
 
139
141
  /**
140
142
  * Marks a method as the websocket "message" event handler.
141
- * @author Axel Nana <axel.nana@workbud.com>
142
143
  *
143
144
  * This decorator should be used on a websocket controller method. Only one "message" event handler
144
145
  * can be defined per websocket controller.
145
146
  *
147
+ * @author Axel Nana <axel.nana@workbud.com>
148
+ *
146
149
  * @param schema The schema of the message body.
147
150
  */
148
- export const onMessage = (schema: TSchema): MethodDecorator => {
151
+ export const onMessage = (schema?: TSchema): MethodDecorator => {
149
152
  return function (target, propertyKey, descriptor) {
150
153
  const metadata = Reflect.getMetadata(Symbols.websocket, target.constructor) ?? {};
151
154
  metadata.message = descriptor.value;
@@ -156,10 +159,11 @@ export namespace Websocket {
156
159
 
157
160
  /**
158
161
  * Marks a method as the websocket "drain" event handler.
159
- * @author Axel Nana <axel.nana@workbud.com>
160
162
  *
161
163
  * This decorator should be used on a websocket controller method. Only one "drain" event handler
162
164
  * can be defined per websocket controller.
165
+ *
166
+ * @author Axel Nana <axel.nana@workbud.com>
163
167
  */
164
168
  export const onDrain = (): MethodDecorator => {
165
169
  return function (target, propertyKey, descriptor) {
@@ -171,10 +175,11 @@ export namespace Websocket {
171
175
 
172
176
  /**
173
177
  * Marks a method as the websocket "error" event handler.
174
- * @author Axel Nana <axel.nana@workbud.com>
175
178
  *
176
179
  * This decorator should be used on a websocket controller method. Only one "error" event handler
177
180
  * can be defined per websocket controller.
181
+ *
182
+ * @author Axel Nana <axel.nana@workbud.com>
178
183
  */
179
184
  export const onError = (): MethodDecorator => {
180
185
  return function (target, propertyKey, descriptor) {
package/src/worker.ts CHANGED
@@ -665,8 +665,6 @@ export class Worker extends InteractsWithConsole {
665
665
  * @author Axel Nana <axel.nana@workbud.com>
666
666
  */
667
667
  export class WorkerPool extends InteractsWithConsole {
668
- #jobFiles: string[] = [];
669
-
670
668
  private workers: BunWorker[] = [];
671
669
  private currentWorkerIndex = 0;
672
670
  private queueWorkerMap: Map<string, BunWorker[]> = new Map();
@@ -681,9 +679,7 @@ export class WorkerPool extends InteractsWithConsole {
681
679
  * Initialize the worker pool.
682
680
  */
683
681
  public async init() {
684
- // Preload all job files to make them available in worker thread.
685
- this.#jobFiles = await Array.fromAsync(new Bun.Glob('./src/**/*.job.ts').scan());
686
- this.debug(`WorkerPool initialized: found ${this.#jobFiles.length} job files`);
682
+ // noop for now
687
683
  }
688
684
 
689
685
  /**
@@ -691,10 +687,21 @@ export class WorkerPool extends InteractsWithConsole {
691
687
  * @param queues The queues to listen from the worker.
692
688
  */
693
689
  public async addWorker(queues: string[] = []): Promise<void> {
694
- const worker = new BunWorker('./styx', {
695
- preload: this.#jobFiles,
696
- argv: ['work', ...queues.map((queue) => `--queue=${queue}`)]
697
- });
690
+ let worker: BunWorker;
691
+
692
+ if (ELYSIUM_BUILD) {
693
+ worker = new BunWorker('./index.js', {
694
+ argv: ['work', ...queues.map((queue) => `--queue=${queue}`)]
695
+ });
696
+ } else {
697
+ // Preload all job files to make them available in worker thread.
698
+ const jobFiles = await Array.fromAsync(new Bun.Glob('./src/**/*.job.ts').scan());
699
+
700
+ worker = new BunWorker('./index.ts', {
701
+ preload: jobFiles,
702
+ argv: ['work', ...queues.map((queue) => `--queue=${queue}`)]
703
+ });
704
+ }
698
705
 
699
706
  worker.addEventListener('error', (e) => {
700
707
  this.trace({
package/types.d.ts ADDED
@@ -0,0 +1,35 @@
1
+ // Copyright (c) 2025-present Workbud Technologies Inc. All rights reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ declare namespace globalThis {
16
+ /**
17
+ * A macro indicating if the code is running from a build.
18
+ * @author Axel Nana <axel.nana@workbud.com>
19
+ */
20
+ var ELYSIUM_BUILD: boolean;
21
+ }
22
+
23
+ declare module '@elysiumjs/core' {
24
+ /**
25
+ * The type for all registered environment variables.
26
+ * @author Axel Nana <axel.nana@workbud.com>
27
+ */
28
+ type AppEnv = Record<string, unknown>;
29
+
30
+ /**
31
+ * The type for the context of the application.
32
+ * @author Axel Nana <axel.nana@workbud.com>
33
+ */
34
+ type AppHttpContext = import('elysia').SingletonBase;
35
+ }
package/.prettierignore DELETED
@@ -1,5 +0,0 @@
1
- # Package Managers
2
- package-lock.json
3
- pnpm-lock.yaml
4
- yarn.lock
5
- bun.lock
package/.prettierrc DELETED
@@ -1,25 +0,0 @@
1
- {
2
- "useTabs": true,
3
- "singleQuote": true,
4
- "trailingComma": "none",
5
- "printWidth": 100,
6
- "plugins": [
7
- "@ianvs/prettier-plugin-sort-imports"
8
- ],
9
- "importOrder": [
10
- "<TYPES>^(node:)",
11
- "<TYPES>",
12
- "<TYPES>^[.]",
13
- "",
14
- "<BUILTIN_MODULES>",
15
- "",
16
- "<THIRD_PARTY_MODULES>",
17
- "",
18
- "^\\$",
19
- "",
20
- "^[.]"
21
- ],
22
- "importOrderParserPlugins": ["typescript", "decorators-legacy"],
23
- "importOrderTypeScriptVersion": "5.8.0",
24
- "overrides": []
25
- }
package/bun.lock DELETED
@@ -1,262 +0,0 @@
1
- {
2
- "lockfileVersion": 1,
3
- "workspaces": {
4
- "": {
5
- "name": "@elysiumjs/core",
6
- "dependencies": {
7
- "@elysiajs/swagger": "^1.2.2",
8
- "cache-manager": "^6.4.2",
9
- "cacheable": "^1.8.10",
10
- "drizzle-orm": "^0.42.0",
11
- "elysia": "latest",
12
- "radash": "^12.1.0",
13
- "reflect-metadata": "^0.2.2",
14
- "wampy": "^7.1.1",
15
- },
16
- "devDependencies": {
17
- "@ianvs/prettier-plugin-sort-imports": "^4.4.1",
18
- "@types/bun": "latest",
19
- "type-fest": "^4.40.0",
20
- },
21
- "peerDependencies": {
22
- "typescript": "^5",
23
- },
24
- },
25
- },
26
- "trustedDependencies": [
27
- "es5-ext",
28
- ],
29
- "packages": {
30
- "@babel/code-frame": ["@babel/code-frame@7.26.2", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.25.9", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" } }, "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ=="],
31
-
32
- "@babel/generator": ["@babel/generator@7.27.0", "", { "dependencies": { "@babel/parser": "^7.27.0", "@babel/types": "^7.27.0", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" } }, "sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw=="],
33
-
34
- "@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.9", "", {}, "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA=="],
35
-
36
- "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.9", "", {}, "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ=="],
37
-
38
- "@babel/parser": ["@babel/parser@7.27.0", "", { "dependencies": { "@babel/types": "^7.27.0" }, "bin": "./bin/babel-parser.js" }, "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg=="],
39
-
40
- "@babel/template": ["@babel/template@7.27.0", "", { "dependencies": { "@babel/code-frame": "^7.26.2", "@babel/parser": "^7.27.0", "@babel/types": "^7.27.0" } }, "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA=="],
41
-
42
- "@babel/traverse": ["@babel/traverse@7.27.0", "", { "dependencies": { "@babel/code-frame": "^7.26.2", "@babel/generator": "^7.27.0", "@babel/parser": "^7.27.0", "@babel/template": "^7.27.0", "@babel/types": "^7.27.0", "debug": "^4.3.1", "globals": "^11.1.0" } }, "sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA=="],
43
-
44
- "@babel/types": ["@babel/types@7.27.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.9", "@babel/helper-validator-identifier": "^7.25.9" } }, "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg=="],
45
-
46
- "@cbor-extract/cbor-extract-darwin-arm64": ["@cbor-extract/cbor-extract-darwin-arm64@2.2.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-P7swiOAdF7aSi0H+tHtHtr6zrpF3aAq/W9FXx5HektRvLTM2O89xCyXF3pk7pLc7QpaY7AoaE8UowVf9QBdh3w=="],
47
-
48
- "@cbor-extract/cbor-extract-darwin-x64": ["@cbor-extract/cbor-extract-darwin-x64@2.2.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-1liF6fgowph0JxBbYnAS7ZlqNYLf000Qnj4KjqPNW4GViKrEql2MgZnAsExhY9LSy8dnvA4C0qHEBgPrll0z0w=="],
49
-
50
- "@cbor-extract/cbor-extract-linux-arm": ["@cbor-extract/cbor-extract-linux-arm@2.2.0", "", { "os": "linux", "cpu": "arm" }, "sha512-QeBcBXk964zOytiedMPQNZr7sg0TNavZeuUCD6ON4vEOU/25+pLhNN6EDIKJ9VLTKaZ7K7EaAriyYQ1NQ05s/Q=="],
51
-
52
- "@cbor-extract/cbor-extract-linux-arm64": ["@cbor-extract/cbor-extract-linux-arm64@2.2.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-rQvhNmDuhjTVXSPFLolmQ47/ydGOFXtbR7+wgkSY0bdOxCFept1hvg59uiLPT2fVDuJFuEy16EImo5tE2x3RsQ=="],
53
-
54
- "@cbor-extract/cbor-extract-linux-x64": ["@cbor-extract/cbor-extract-linux-x64@2.2.0", "", { "os": "linux", "cpu": "x64" }, "sha512-cWLAWtT3kNLHSvP4RKDzSTX9o0wvQEEAj4SKvhWuOVZxiDAeQazr9A+PSiRILK1VYMLeDml89ohxCnUNQNQNCw=="],
55
-
56
- "@cbor-extract/cbor-extract-win32-x64": ["@cbor-extract/cbor-extract-win32-x64@2.2.0", "", { "os": "win32", "cpu": "x64" }, "sha512-l2M+Z8DO2vbvADOBNLbbh9y5ST1RY5sqkWOg/58GkUPBYou/cuNZ68SGQ644f1CvZ8kcOxyZtw06+dxWHIoN/w=="],
57
-
58
- "@elysiajs/swagger": ["@elysiajs/swagger@1.2.2", "", { "dependencies": { "@scalar/themes": "^0.9.52", "@scalar/types": "^0.0.12", "openapi-types": "^12.1.3", "pathe": "^1.1.2" }, "peerDependencies": { "elysia": ">= 1.2.0" } }, "sha512-DG0PbX/wzQNQ6kIpFFPCvmkkWTIbNWDS7lVLv3Puy6ONklF14B4NnbDfpYjX1hdSYKeCqKBBOuenh6jKm8tbYA=="],
59
-
60
- "@ianvs/prettier-plugin-sort-imports": ["@ianvs/prettier-plugin-sort-imports@4.4.1", "", { "dependencies": { "@babel/generator": "^7.26.2", "@babel/parser": "^7.26.2", "@babel/traverse": "^7.25.9", "@babel/types": "^7.26.0", "semver": "^7.5.2" }, "peerDependencies": { "@vue/compiler-sfc": "2.7.x || 3.x", "prettier": "2 || 3" }, "optionalPeers": ["@vue/compiler-sfc"] }, "sha512-F0/Hrcfpy8WuxlQyAWJTEren/uxKhYonOGY4OyWmwRdeTvkh9mMSCxowZLjNkhwi/2ipqCgtXwwOk7tW0mWXkA=="],
61
-
62
- "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.8", "", { "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA=="],
63
-
64
- "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
65
-
66
- "@jridgewell/set-array": ["@jridgewell/set-array@1.2.1", "", {}, "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A=="],
67
-
68
- "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.0", "", {}, "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="],
69
-
70
- "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="],
71
-
72
- "@keyv/serialize": ["@keyv/serialize@1.0.3", "", { "dependencies": { "buffer": "^6.0.3" } }, "sha512-qnEovoOp5Np2JDGonIDL6Ayihw0RhnRh6vxPuHo4RDn1UOzwEo4AeIfpL6UGIrsceWrCMiVPgwRjbHu4vYFc3g=="],
73
-
74
- "@msgpackr-extract/msgpackr-extract-darwin-arm64": ["@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw=="],
75
-
76
- "@msgpackr-extract/msgpackr-extract-darwin-x64": ["@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw=="],
77
-
78
- "@msgpackr-extract/msgpackr-extract-linux-arm": ["@msgpackr-extract/msgpackr-extract-linux-arm@3.0.3", "", { "os": "linux", "cpu": "arm" }, "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw=="],
79
-
80
- "@msgpackr-extract/msgpackr-extract-linux-arm64": ["@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg=="],
81
-
82
- "@msgpackr-extract/msgpackr-extract-linux-x64": ["@msgpackr-extract/msgpackr-extract-linux-x64@3.0.3", "", { "os": "linux", "cpu": "x64" }, "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg=="],
83
-
84
- "@msgpackr-extract/msgpackr-extract-win32-x64": ["@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3", "", { "os": "win32", "cpu": "x64" }, "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ=="],
85
-
86
- "@scalar/openapi-types": ["@scalar/openapi-types@0.1.1", "", {}, "sha512-NMy3QNk6ytcCoPUGJH0t4NNr36OWXgZhA3ormr3TvhX1NDgoF95wFyodGVH8xiHeUyn2/FxtETm8UBLbB5xEmg=="],
87
-
88
- "@scalar/themes": ["@scalar/themes@0.9.86", "", { "dependencies": { "@scalar/types": "0.1.7" } }, "sha512-QUHo9g5oSWi+0Lm1vJY9TaMZRau8LHg+vte7q5BVTBnu6NuQfigCaN+ouQ73FqIVd96TwMO6Db+dilK1B+9row=="],
89
-
90
- "@scalar/types": ["@scalar/types@0.0.12", "", { "dependencies": { "@scalar/openapi-types": "0.1.1", "@unhead/schema": "^1.9.5" } }, "sha512-XYZ36lSEx87i4gDqopQlGCOkdIITHHEvgkuJFrXFATQs9zHARop0PN0g4RZYWj+ZpCUclOcaOjbCt8JGe22mnQ=="],
91
-
92
- "@sinclair/typebox": ["@sinclair/typebox@0.34.33", "", {}, "sha512-5HAV9exOMcXRUxo+9iYB5n09XxzCXnfy4VTNW4xnDv+FgjzAGY989C28BIdljKqmF+ZltUwujE3aossvcVtq6g=="],
93
-
94
- "@types/bun": ["@types/bun@1.2.10", "", { "dependencies": { "bun-types": "1.2.10" } }, "sha512-eilv6WFM3M0c9ztJt7/g80BDusK98z/FrFwseZgT4bXCq2vPhXD4z8R3oddmAn+R/Nmz9vBn4kweJKmGTZj+lg=="],
95
-
96
- "@types/node": ["@types/node@22.14.1", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw=="],
97
-
98
- "@unhead/schema": ["@unhead/schema@1.11.20", "", { "dependencies": { "hookable": "^5.5.3", "zhead": "^2.2.4" } }, "sha512-0zWykKAaJdm+/Y7yi/Yds20PrUK7XabLe9c3IRcjnwYmSWY6z0Cr19VIs3ozCj8P+GhR+/TI2mwtGlueCEYouA=="],
99
-
100
- "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
101
-
102
- "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
103
-
104
- "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
105
-
106
- "buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="],
107
-
108
- "bufferutil": ["bufferutil@4.0.9", "", { "dependencies": { "node-gyp-build": "^4.3.0" } }, "sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw=="],
109
-
110
- "bun-types": ["bun-types@1.2.10", "", { "dependencies": { "@types/node": "*" } }, "sha512-b5ITZMnVdf3m1gMvJHG+gIfeJHiQPJak0f7925Hxu6ZN5VKA8AGy4GZ4lM+Xkn6jtWxg5S3ldWvfmXdvnkp3GQ=="],
111
-
112
- "cache-manager": ["cache-manager@6.4.2", "", { "dependencies": { "keyv": "^5.3.2" } }, "sha512-oT0d1cGWZAlqEGDPjOfhmldTS767jT6kBT3KIdn7MX5OevlRVYqJT+LxRv5WY4xW9heJtYxeRRXaoKlEW+Biew=="],
113
-
114
- "cacheable": ["cacheable@1.8.10", "", { "dependencies": { "hookified": "^1.8.1", "keyv": "^5.3.2" } }, "sha512-0ZnbicB/N2R6uziva8l6O6BieBklArWyiGx4GkwAhLKhSHyQtRfM9T1nx7HHuHDKkYB/efJQhz3QJ6x/YqoZzA=="],
115
-
116
- "cbor-extract": ["cbor-extract@2.2.0", "", { "dependencies": { "node-gyp-build-optional-packages": "5.1.1" }, "optionalDependencies": { "@cbor-extract/cbor-extract-darwin-arm64": "2.2.0", "@cbor-extract/cbor-extract-darwin-x64": "2.2.0", "@cbor-extract/cbor-extract-linux-arm": "2.2.0", "@cbor-extract/cbor-extract-linux-arm64": "2.2.0", "@cbor-extract/cbor-extract-linux-x64": "2.2.0", "@cbor-extract/cbor-extract-win32-x64": "2.2.0" }, "bin": { "download-cbor-prebuilds": "bin/download-prebuilds.js" } }, "sha512-Ig1zM66BjLfTXpNgKpvBePq271BPOvu8MR0Jl080yG7Jsl+wAZunfrwiwA+9ruzm/WEdIV5QF/bjDZTqyAIVHA=="],
117
-
118
- "cbor-x": ["cbor-x@1.6.0", "", { "optionalDependencies": { "cbor-extract": "^2.2.0" } }, "sha512-0kareyRwHSkL6ws5VXHEf8uY1liitysCVJjlmhaLG+IXLqhSaOO+t63coaso7yjwEzWZzLy8fJo06gZDVQM9Qg=="],
119
-
120
- "cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="],
121
-
122
- "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
123
-
124
- "color-json": ["color-json@3.0.5", "", {}, "sha512-DG4zae1GmHDBNsYTUe+GJiDnuKutxs2vVSkPRQqbeA6oEGBRQyRixV+HmIByasCfyf9L0CwHo8vOoiHqe7Lzng=="],
125
-
126
- "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
127
-
128
- "cookie": ["cookie@1.0.2", "", {}, "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA=="],
129
-
130
- "crypto-js": ["crypto-js@4.2.0", "", {}, "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="],
131
-
132
- "d": ["d@1.0.2", "", { "dependencies": { "es5-ext": "^0.10.64", "type": "^2.7.2" } }, "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw=="],
133
-
134
- "debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
135
-
136
- "detect-libc": ["detect-libc@2.0.3", "", {}, "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw=="],
137
-
138
- "drizzle-orm": ["drizzle-orm@0.42.0", "", { "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=4", "@electric-sql/pglite": ">=0.2.0", "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", "@neondatabase/serverless": ">=0.10.0", "@op-engineering/op-sqlite": ">=2", "@opentelemetry/api": "^1.4.1", "@planetscale/database": ">=1.13", "@prisma/client": "*", "@tidbcloud/serverless": "*", "@types/better-sqlite3": "*", "@types/pg": "*", "@types/sql.js": "*", "@vercel/postgres": ">=0.8.0", "@xata.io/client": "*", "better-sqlite3": ">=7", "bun-types": "*", "expo-sqlite": ">=14.0.0", "gel": ">=2", "knex": "*", "kysely": "*", "mysql2": ">=2", "pg": ">=8", "postgres": ">=3", "sql.js": ">=1", "sqlite3": ">=5" }, "optionalPeers": ["@aws-sdk/client-rds-data", "@cloudflare/workers-types", "@electric-sql/pglite", "@libsql/client", "@libsql/client-wasm", "@neondatabase/serverless", "@op-engineering/op-sqlite", "@opentelemetry/api", "@planetscale/database", "@prisma/client", "@tidbcloud/serverless", "@types/better-sqlite3", "@types/pg", "@types/sql.js", "@vercel/postgres", "@xata.io/client", "better-sqlite3", "bun-types", "expo-sqlite", "gel", "knex", "kysely", "mysql2", "pg", "postgres", "sql.js", "sqlite3"] }, "sha512-pS8nNJm2kBNZwrOjTHJfdKkaU+KuUQmV/vk5D57NojDq4FG+0uAYGMulXtYT///HfgsMF0hnFFvu1ezI3OwOkg=="],
139
-
140
- "elysia": ["elysia@1.2.25", "", { "dependencies": { "@sinclair/typebox": "^0.34.27", "cookie": "^1.0.2", "memoirist": "^0.3.0", "openapi-types": "^12.1.3" }, "peerDependencies": { "typescript": ">= 5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-WsdQpORJvb4uszzeqYT0lg97knw1iBW1NTzJ1Jm57tiHg+DfAotlWXYbjmvQ039ssV0fYELDHinLLoUazZkEHg=="],
141
-
142
- "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
143
-
144
- "es5-ext": ["es5-ext@0.10.64", "", { "dependencies": { "es6-iterator": "^2.0.3", "es6-symbol": "^3.1.3", "esniff": "^2.0.1", "next-tick": "^1.1.0" } }, "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg=="],
145
-
146
- "es6-iterator": ["es6-iterator@2.0.3", "", { "dependencies": { "d": "1", "es5-ext": "^0.10.35", "es6-symbol": "^3.1.1" } }, "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g=="],
147
-
148
- "es6-symbol": ["es6-symbol@3.1.4", "", { "dependencies": { "d": "^1.0.2", "ext": "^1.7.0" } }, "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg=="],
149
-
150
- "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
151
-
152
- "esniff": ["esniff@2.0.1", "", { "dependencies": { "d": "^1.0.1", "es5-ext": "^0.10.62", "event-emitter": "^0.3.5", "type": "^2.7.2" } }, "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg=="],
153
-
154
- "event-emitter": ["event-emitter@0.3.5", "", { "dependencies": { "d": "1", "es5-ext": "~0.10.14" } }, "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA=="],
155
-
156
- "ext": ["ext@1.7.0", "", { "dependencies": { "type": "^2.7.2" } }, "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw=="],
157
-
158
- "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="],
159
-
160
- "globals": ["globals@11.12.0", "", {}, "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="],
161
-
162
- "hookable": ["hookable@5.5.3", "", {}, "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="],
163
-
164
- "hookified": ["hookified@1.8.2", "", {}, "sha512-5nZbBNP44sFCDjSoB//0N7m508APCgbQ4mGGo1KJGBYyCKNHfry1Pvd0JVHZIxjdnqn8nFRBAN/eFB6Rk/4w5w=="],
165
-
166
- "ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
167
-
168
- "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
169
-
170
- "is-typedarray": ["is-typedarray@1.0.0", "", {}, "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA=="],
171
-
172
- "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
173
-
174
- "jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="],
175
-
176
- "keyv": ["keyv@5.3.3", "", { "dependencies": { "@keyv/serialize": "^1.0.3" } }, "sha512-Rwu4+nXI9fqcxiEHtbkvoes2X+QfkTRo1TMkPfwzipGsJlJO/z69vqB4FNl9xJ3xCpAcbkvmEabZfPzrwN3+gQ=="],
177
-
178
- "memoirist": ["memoirist@0.3.0", "", {}, "sha512-wR+4chMgVPq+T6OOsk40u9Wlpw1Pjx66NMNiYxCQQ4EUJ7jDs3D9kTCeKdBOkvAiqXlHLVJlvYL01PvIJ1MPNg=="],
179
-
180
- "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
181
-
182
- "msgpackr": ["msgpackr@1.11.2", "", { "optionalDependencies": { "msgpackr-extract": "^3.0.2" } }, "sha512-F9UngXRlPyWCDEASDpTf6c9uNhGPTqnTeLVt7bN+bU1eajoR/8V9ys2BRaV5C/e5ihE6sJ9uPIKaYt6bFuO32g=="],
183
-
184
- "msgpackr-extract": ["msgpackr-extract@3.0.3", "", { "dependencies": { "node-gyp-build-optional-packages": "5.2.2" }, "optionalDependencies": { "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" }, "bin": { "download-msgpackr-prebuilds": "bin/download-prebuilds.js" } }, "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA=="],
185
-
186
- "nanoid": ["nanoid@5.1.5", "", { "bin": { "nanoid": "bin/nanoid.js" } }, "sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw=="],
187
-
188
- "next-tick": ["next-tick@1.1.0", "", {}, "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ=="],
189
-
190
- "node-gyp-build": ["node-gyp-build@4.8.4", "", { "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", "node-gyp-build-test": "build-test.js" } }, "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ=="],
191
-
192
- "node-gyp-build-optional-packages": ["node-gyp-build-optional-packages@5.1.1", "", { "dependencies": { "detect-libc": "^2.0.1" }, "bin": { "node-gyp-build-optional-packages": "bin.js", "node-gyp-build-optional-packages-test": "build-test.js", "node-gyp-build-optional-packages-optional": "optional.js" } }, "sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw=="],
193
-
194
- "openapi-types": ["openapi-types@12.1.3", "", {}, "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw=="],
195
-
196
- "pathe": ["pathe@1.1.2", "", {}, "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ=="],
197
-
198
- "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
199
-
200
- "prettier": ["prettier@3.5.3", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw=="],
201
-
202
- "radash": ["radash@12.1.0", "", {}, "sha512-b0Zcf09AhqKS83btmUeYBS8tFK7XL2e3RvLmZcm0sTdF1/UUlHSsjXdCcWNxe7yfmAlPve5ym0DmKGtTzP6kVQ=="],
203
-
204
- "reflect-metadata": ["reflect-metadata@0.2.2", "", {}, "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q=="],
205
-
206
- "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="],
207
-
208
- "semver": ["semver@7.7.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA=="],
209
-
210
- "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
211
-
212
- "strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
213
-
214
- "tweetnacl": ["tweetnacl@1.0.3", "", {}, "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw=="],
215
-
216
- "type": ["type@2.7.3", "", {}, "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ=="],
217
-
218
- "type-fest": ["type-fest@4.40.0", "", {}, "sha512-ABHZ2/tS2JkvH1PEjxFDTUWC8dB5OsIGZP4IFLhR293GqT5Y5qB1WwL2kMPYhQW9DVgVD8Hd7I8gjwPIf5GFkw=="],
219
-
220
- "typedarray-to-buffer": ["typedarray-to-buffer@3.1.5", "", { "dependencies": { "is-typedarray": "^1.0.0" } }, "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q=="],
221
-
222
- "typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
223
-
224
- "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
225
-
226
- "utf-8-validate": ["utf-8-validate@5.0.10", "", { "dependencies": { "node-gyp-build": "^4.3.0" } }, "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ=="],
227
-
228
- "wampy": ["wampy@7.1.1", "", { "dependencies": { "cbor-x": "^1.5.3", "color-json": "^3.0.5", "msgpackr": "^1.9.7", "tweetnacl": "^1.0.3", "wampy-cra": "^0.2.0", "wampy-cryptosign": "^0.1.0", "websocket": "^1.0.34", "ws": "^8.13.0", "yargs": "^17.7.2" }, "bin": { "wampy": "cmd/cli.js" } }, "sha512-1/OWER8Fxrhw9KlazeH9zvTAbosI/Df1dU9CCjwCg1X3ta4RgASVp/rdEwxjjewYJSCNPQLwE3jplbAD8QHLkw=="],
229
-
230
- "wampy-cra": ["wampy-cra@0.2.0", "", { "dependencies": { "crypto-js": "^4.1.1" } }, "sha512-Z9zcDem35VXe0tTjPSWh40O6pc/WBqxVCnFsSzj+6qvbpdLWXWpWD3/3a+J89ruMJnpgmmnmhPHhewH2nsYOBw=="],
231
-
232
- "wampy-cryptosign": ["wampy-cryptosign@0.1.0", "", { "dependencies": { "tweetnacl": "^1.0.3" } }, "sha512-BrL8UEpydxYnPBvz46HHacnXqkbaE0cejxFHAbxjdYah/I2x7i7v4pCnnM/b8OQLe9cmf8CubeuXzN8BwEEDkg=="],
233
-
234
- "websocket": ["websocket@1.0.35", "", { "dependencies": { "bufferutil": "^4.0.1", "debug": "^2.2.0", "es5-ext": "^0.10.63", "typedarray-to-buffer": "^3.1.5", "utf-8-validate": "^5.0.2", "yaeti": "^0.0.6" } }, "sha512-/REy6amwPZl44DDzvRCkaI1q1bIiQB0mEFQLUrhz3z2EK91cp3n72rAjUlrTP0zV22HJIUOVHQGPxhFRjxjt+Q=="],
235
-
236
- "wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
237
-
238
- "ws": ["ws@8.18.1", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w=="],
239
-
240
- "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="],
241
-
242
- "yaeti": ["yaeti@0.0.6", "", {}, "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug=="],
243
-
244
- "yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="],
245
-
246
- "yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="],
247
-
248
- "zhead": ["zhead@2.2.4", "", {}, "sha512-8F0OI5dpWIA5IGG5NHUg9staDwz/ZPxZtvGVf01j7vHqSyZ0raHY+78atOVxRqb73AotX22uV1pXt3gYSstGag=="],
249
-
250
- "zod": ["zod@3.24.3", "", {}, "sha512-HhY1oqzWCQWuUqvBFnsyrtZRhyPeR7SUGv+C4+MsisMuVfSPx8HpwWqH8tRahSlt6M3PiFAcoeFhZAqIXTxoSg=="],
251
-
252
- "@scalar/themes/@scalar/types": ["@scalar/types@0.1.7", "", { "dependencies": { "@scalar/openapi-types": "0.2.0", "@unhead/schema": "^1.11.11", "nanoid": "^5.1.5", "type-fest": "^4.20.0", "zod": "^3.23.8" } }, "sha512-irIDYzTQG2KLvFbuTI8k2Pz/R4JR+zUUSykVTbEMatkzMmVFnn1VzNSMlODbadycwZunbnL2tA27AXed9URVjw=="],
253
-
254
- "msgpackr-extract/node-gyp-build-optional-packages": ["node-gyp-build-optional-packages@5.2.2", "", { "dependencies": { "detect-libc": "^2.0.1" }, "bin": { "node-gyp-build-optional-packages": "bin.js", "node-gyp-build-optional-packages-optional": "optional.js", "node-gyp-build-optional-packages-test": "build-test.js" } }, "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw=="],
255
-
256
- "websocket/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
257
-
258
- "@scalar/themes/@scalar/types/@scalar/openapi-types": ["@scalar/openapi-types@0.2.0", "", { "dependencies": { "zod": "^3.23.8" } }, "sha512-waiKk12cRCqyUCWTOX0K1WEVX46+hVUK+zRPzAahDJ7G0TApvbNkuy5wx7aoUyEk++HHde0XuQnshXnt8jsddA=="],
259
-
260
- "websocket/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
261
- }
262
- }