equipped 5.0.8 → 5.0.9

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.
Files changed (52) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/cjs/cache.cjs +2 -2
  3. package/dist/cjs/{chunk-UBQPLHM4.cjs → chunk-46TJFKXX.cjs} +3 -3
  4. package/dist/cjs/chunk-46TJFKXX.cjs.map +1 -0
  5. package/dist/cjs/dbs.cjs +2 -2
  6. package/dist/cjs/errors.cjs +2 -2
  7. package/dist/cjs/events.cjs +2 -2
  8. package/dist/cjs/index.cjs +2 -2
  9. package/dist/cjs/jobs.cjs +2 -2
  10. package/dist/cjs/server.cjs +2 -2
  11. package/dist/cjs/utilities.cjs +2 -2
  12. package/dist/cjs/validations.cjs +2 -2
  13. package/dist/esm/cache.min.mjs +1 -1
  14. package/dist/esm/cache.mjs +1 -1
  15. package/dist/esm/chunk-7LLFKFXJ.min.mjs +32 -0
  16. package/dist/esm/chunk-7LLFKFXJ.min.mjs.map +1 -0
  17. package/dist/esm/{chunk-SHJLDB4M.mjs → chunk-DXTIVHEC.mjs} +3 -3
  18. package/dist/esm/chunk-DXTIVHEC.mjs.map +1 -0
  19. package/dist/esm/dbs.min.mjs +1 -1
  20. package/dist/esm/dbs.mjs +1 -1
  21. package/dist/esm/errors.min.mjs +1 -1
  22. package/dist/esm/errors.mjs +1 -1
  23. package/dist/esm/events.min.mjs +1 -1
  24. package/dist/esm/events.mjs +1 -1
  25. package/dist/esm/index.min.mjs +1 -1
  26. package/dist/esm/index.mjs +1 -1
  27. package/dist/esm/jobs.min.mjs +1 -1
  28. package/dist/esm/jobs.mjs +1 -1
  29. package/dist/esm/server.min.mjs +1 -1
  30. package/dist/esm/server.mjs +1 -1
  31. package/dist/esm/utilities.min.mjs +1 -1
  32. package/dist/esm/utilities.mjs +1 -1
  33. package/dist/esm/validations.min.mjs +1 -1
  34. package/dist/esm/validations.mjs +1 -1
  35. package/dist/types/cache.js +1 -1
  36. package/dist/types/{chunk-XNSFFTXR.js → chunk-SK64OMPG.js} +2 -2
  37. package/dist/types/dbs.js +1 -1
  38. package/dist/types/errors.js +1 -1
  39. package/dist/types/events.js +1 -1
  40. package/dist/types/{index-D-NoC-on.d.ts → index-DNvs4IZN.d.ts} +3 -3
  41. package/dist/types/index.d.ts +1 -1
  42. package/dist/types/index.js +1 -1
  43. package/dist/types/jobs.js +1 -1
  44. package/dist/types/server.d.ts +2 -2
  45. package/dist/types/server.js +1 -1
  46. package/dist/types/utilities.js +1 -1
  47. package/dist/types/validations.js +1 -1
  48. package/package.json +1 -1
  49. package/dist/cjs/chunk-UBQPLHM4.cjs.map +0 -1
  50. package/dist/esm/chunk-SHJLDB4M.mjs.map +0 -1
  51. package/dist/esm/chunk-WKZT3EQO.min.mjs +0 -32
  52. package/dist/esm/chunk-WKZT3EQO.min.mjs.map +0 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [5.0.9](https://github.com/kevinand11/equipped/compare/v5.0.8...v5.0.9) (2025-06-27)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * sockets not importable in esm ([d28dc81](https://github.com/kevinand11/equipped/commit/d28dc811d48582bc194367c7ef8e6fdaae754168))
11
+
5
12
  ### [5.0.8](https://github.com/kevinand11/equipped/compare/v5.0.7...v5.0.8) (2025-06-27)
6
13
 
7
14
  ### [5.0.7](https://github.com/kevinand11/equipped/compare/v5.0.6...v5.0.7) (2025-06-27)
@@ -2,10 +2,10 @@
2
2
 
3
3
 
4
4
 
5
- var _chunkUBQPLHM4cjs = require('./chunk-UBQPLHM4.cjs');
5
+ var _chunk46TJFKXXcjs = require('./chunk-46TJFKXX.cjs');
6
6
 
7
7
 
8
8
 
9
9
 
10
- exports.Cache = _chunkUBQPLHM4cjs.Cache; exports.RedisCache = _chunkUBQPLHM4cjs.RedisCache; exports.redisConfigPipe = _chunkUBQPLHM4cjs.redisConfigPipe;
10
+ exports.Cache = _chunk46TJFKXXcjs.Cache; exports.RedisCache = _chunk46TJFKXXcjs.RedisCache; exports.redisConfigPipe = _chunk46TJFKXXcjs.redisConfigPipe;
11
11
  //# sourceMappingURL=cache.cjs.map
@@ -92,7 +92,7 @@ var RequestError = class extends EquippedError {
92
92
  };
93
93
 
94
94
  // src/server/impls/base.ts
95
- var _socketio = require('socket.io'); var _socketio2 = _interopRequireDefault(_socketio);
95
+ var _socketio = require('socket.io');
96
96
  var _supertest = require('supertest'); var _supertest2 = _interopRequireDefault(_supertest);
97
97
 
98
98
 
@@ -716,7 +716,7 @@ var Server = (_class3 = class {
716
716
  this.implementations = implementations;
717
717
  this.server = server;
718
718
  this.#openapi = new OpenApi(this.config);
719
- const socketInstance = new _socketio2.default.Server(server, { cors: this.cors });
719
+ const socketInstance = new (0, _socketio.Server)(server, { cors: this.cors });
720
720
  this.socket = new SocketEmitter(socketInstance, config.eventBus);
721
721
  this.addRouter(this.#openapi.router());
722
722
  }
@@ -2504,4 +2504,4 @@ function validate(pipe, value) {
2504
2504
 
2505
2505
 
2506
2506
  exports.Cache = Cache; exports.redisConfigPipe = redisConfigPipe; exports.EquippedError = EquippedError; exports.RequestError = RequestError; exports.valleyed_exports = valleyed_exports; exports.pipeErrorToValidationError = pipeErrorToValidationError; exports.validate = validate; exports.Methods = Methods; exports.StatusCodes = StatusCodes; exports.makeMiddleware = makeMiddleware; exports.makeErrorMiddleware = makeErrorMiddleware; exports.Router = Router; exports.authProviders_exports = authProviders_exports; exports.hash_exports = hash_exports; exports.parseJSONValue = parseJSONValue; exports.parseJSONObject = parseJSONObject; exports.getMediaDuration = getMediaDuration; exports.sleep = sleep; exports.retry = retry; exports.random_exports = random_exports; exports.Request = Request; exports.Response = Response; exports.Server = Server; exports.ExpressServer = ExpressServer; exports.FastifyServer = FastifyServer; exports.requireAuthUser = requireAuthUser; exports.requireAuthorizationUser = requireAuthorizationUser; exports.requireApiKeyUser = requireApiKeyUser; exports.requireRefreshTokenUser = requireRefreshTokenUser; exports.BaseApiKeysUtility = BaseApiKeysUtility; exports.BaseTokensUtility = BaseTokensUtility; exports.CacheTokensUtility = CacheTokensUtility; exports.serverPipe = serverPipe; exports.AuthorizationExpired = AuthorizationExpired; exports.BadRequestError = BadRequestError; exports.NotAuthenticatedError = NotAuthenticatedError; exports.NotAuthorizedError = NotAuthorizedError; exports.NotFoundError = NotFoundError; exports.RefreshTokenMisusedError = RefreshTokenMisusedError; exports.ValidationError = ValidationError; exports.RedisCache = RedisCache; exports.TopicPrefix = TopicPrefix; exports.Db = Db; exports.DbChange = DbChange; exports.MongoDbChange = MongoDbChange; exports.QueryKeys = QueryKeys; exports.Conditions = Conditions; exports.queryParamsPipe = queryParamsPipe; exports.queryResultsPipe = queryResultsPipe; exports.wrapQueryParams = wrapQueryParams; exports.mongoDbConfigPipe = mongoDbConfigPipe; exports.MongoDb = MongoDb; exports.EventBus = EventBus; exports.DefaultSubscribeOptions = DefaultSubscribeOptions; exports.rabbitmqConfigPipe = rabbitmqConfigPipe; exports.kafkaConfigPipe = kafkaConfigPipe; exports.KafkaEventBus = KafkaEventBus; exports.RabbitMQEventBus = RabbitMQEventBus; exports.redisJobsConfigPipe = redisJobsConfigPipe; exports.RedisJob = RedisJob; exports.Instance = Instance;
2507
- //# sourceMappingURL=chunk-UBQPLHM4.cjs.map
2507
+ //# sourceMappingURL=chunk-46TJFKXX.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/equipped/equipped/dist/cjs/chunk-46TJFKXX.cjs","../../src/validations/index.ts","../../src/validations/valleyed.ts","../../src/instance/index.ts","../../src/instance/hooks.ts","../../src/instance/settings.ts","../../src/cache/base.ts","../../src/cache/pipes.ts","../../src/cache/types/redis.ts","../../src/errors/equippedError.ts","../../src/errors/requestError.ts","../../src/server/impls/base.ts","../../src/server/types.ts","../../src/server/middlewares/parseAuthUser.ts","../../src/server/openapi.ts","../../src/server/routes.ts","../../src/utilities/authProviders.ts","../../src/utilities/hash.ts","../../src/utilities/json.ts","../../src/utilities/media.ts","../../src/utilities/retry.ts","../../src/utilities/random.ts","../../src/server/requests.ts","../../src/server/sockets.ts","../../src/server/impls/express.ts","../../src/server/impls/fastify.ts","../../src/server/middlewares/requireAuthUser.ts","../../src/server/pipes.ts","../../src/server/requests-auth/apiKeys.ts","../../src/server/requests-auth/tokens.ts","../../src/errors/types/authorizationExpired.ts","../../src/errors/types/badRequestError.ts","../../src/errors/types/notAuthenticatedError.ts","../../src/errors/types/notAuthorizedError.ts","../../src/errors/types/notFoundError.ts","../../src/errors/types/refreshTokenMisusedError.ts","../../src/errors/types/validationError.ts","../../src/dbs/base/_instance.ts","../../src/dbs/mongo/changes.ts","../../src/dbs/mongo/index.ts","../../src/dbs/mongo/api.ts","../../src/dbs/pipes.ts","../../src/dbs/mongo/query.ts","../../src/events/base.ts","../../src/events/pipes.ts","../../src/events/types/kafka.ts","../../src/events/types/rabbitmq.ts","../../src/jobs/pipes.ts","../../src/jobs/types/redis.ts"],"names":["compare","hash","QueryKeys","Conditions","v"],"mappings":"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A,IAAA;AACA,IAAA;AACA,IAAA;AACD,EAAA;AACD;AAE6E;AACrC,EAAA;AAChC,EAAA;AACR;AL4kEqE;AACA;AGnwEwC;AACrG,EAAA;AACoD,EAAA;AAClD,EAAA;AACA,EAAA;AAEiC,EAAA;AACG,IAAA;AACvB,IAAA;AACS,IAAA;AACQ,IAAA;AACN,IAAA;AACjC,EAAA;AAEuC,EAAA;AACQ,IAAA;AAC/C,EAAA;AAEc,EAAA;AACT,IAAA;AAC0C,MAAA;AACA,MAAA;AAC9B,IAAA;AAC8C,MAAA;AAC9D,IAAA;AACD,EAAA;AAEoH,EAAA;AACpD,IAAA;AACX,IAAA;AAC5B,IAAA;AACd,MAAA;AACU,QAAA;AAAwE;AAC7D,UAAA;AAC5B,QAAA;AACF,MAAA;AACD,IAAA;AAC4D,IAAA;AAC/B,IAAA;AACnB,MAAA;AACU,QAAA;AAAgE;AAChD,UAAA;AACjC,QAAA;AACF,MAAA;AACD,IAAA;AACwE,IAAA;AACzE,EAAA;AAEa,EAAA;AACE,IAAA;AACG,MAAA;AACG,QAAA;AACnB,MAAA;AACe,IAAA;AACjB,EAAA;AAEuD,EAAA;AAC1B,IAAA;AACa,IAAA;AAC1C,EAAA;AAEgC,EAAA;AACf,IAAA;AACP,MAAA;AACA,MAAA;AACC,MAAA;AACV,IAAA;AAEoD,IAAA;AACpB,MAAA;AACuB,QAAA;AAAE,QAAA;AAChC,QAAA;AACvB,MAAA;AACD,IAAA;AACF,EAAA;AAEmD,EAAA;AACjC,IAAA;AAC+B,IAAA;AACzC,IAAA;AACR,EAAA;AAE0C,EAAA;AAEtB,IAAA;AACL,IAAA;AACf,EAAA;AACD;AH6vEqE;AACA;AEn1ElE;AACyC,EAAA;AACqB,IAAA;AACnB,IAAA;AACzB,IAAA;AACa,IAAA;AAC/B,EAAA;AACF;AAGE;AAEE,EAAA;AAGO,IAAA;AACR,IAAA;AACD,EAAA;AACsD,EAAA;AACxD;AAGkE;AACf,EAAA;AAClD;AAE4F;AACE;AAG3C;AACV,EAAA;AACsB,EAAA;AACjC,EAAA;AAC9B;AAGmD;AACT,EAAA;AACsB,EAAA;AAClC,EAAA;AAC9B;AFy0EmE;AACA;ACz3EtB;AAIc;AACyD,EAAA;AACtE,IAAA;AACM,IAAA;AAC7C,IAAA;AACH,EAAA;AAEiD,EAAA;AACvD;AAEwG;AAChE,EAAA;AACH,EAAA;AACW,EAAA;AAChD;ADs3EqE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/home/runner/work/equipped/equipped/dist/cjs/chunk-46TJFKXX.cjs","sourcesContent":[null,"export * from 'valleyed'\nexport * as ve from './valleyed'\nimport { Pipe, PipeError, PipeOutput, v } from 'valleyed'\n\nimport { ValidationError } from '../errors'\n\nexport function pipeErrorToValidationError(error: PipeError) {\n\tconst errorsObject = error.messages.reduce<Record<string, { field: string; messages: string[] }>>((acc, { path = '', message }) => {\n\t\tif (acc[path]) acc[path].messages.push(message)\n\t\telse acc[path] = { field: path, messages: [message] }\n\t\treturn acc\n\t}, {})\n\n\treturn new ValidationError(Object.values(errorsObject))\n}\n\nexport function validate<T extends Pipe<unknown, unknown, any>>(pipe: T, value: unknown): PipeOutput<T> {\n\tconst validity = v.validate(pipe, value)\n\tif (validity.valid) return validity.value as PipeOutput<T>\n\tthrow pipeErrorToValidationError(validity.error)\n}\n","import { AsyncLocalStorage } from 'node:async_hooks'\n\nimport { Pipe, PipeError, PipeInput, PipeOutput, v } from 'valleyed'\n\nimport { Instance } from '../instance'\nimport type { IncomingFile, Response, Request, RouteDef, RouteDefToReqRes } from '../server'\n\nconst filePipe = (err?: string) =>\n\tv.array(\n\t\tv.file<IncomingFile>(err).pipe((input) => {\n\t\t\tconst err = `is larger than allowed limit of ${Instance.get().settings.server?.requests.maxFileUploadSizeInMb}mb`\n\t\t\tconst valid = input ? !input.isTruncated : true\n\t\t\tif (valid) return input\n\t\t\tthrow PipeError.root(err, input)\n\t\t}),\n\t)\n\nexport const incomingFile = (err?: string) =>\n\tv.pipe<unknown, IncomingFile, any>(\n\t\t(input) =>\n\t\t\tv.assert(\n\t\t\t\tfilePipe(err)\n\t\t\t\t\t.pipe(v.min(1, 'no file provided'))\n\t\t\t\t\t.pipe((files) => files[0]),\n\t\t\t\tinput,\n\t\t\t),\n\t\t{ schema: () => ({ type: 'string', format: 'binary' }) },\n\t)\n\nexport const incomingFiles = (err?: string) =>\n\tv.pipe<unknown, IncomingFile[], any>((input) => v.assert(filePipe(err), input), {\n\t\tschema: () => ({ type: 'string', format: 'binary' }),\n\t})\n\nexport const requestLocalStorage = new AsyncLocalStorage<Request<RouteDefToReqRes<RouteDef>>>()\nexport const responseLocalStorage = new AsyncLocalStorage<Response<RouteDefToReqRes<RouteDef>>>()\n\nexport const withRequest = <T extends Pipe<any, any, any>>(fn: (req: Request<RouteDefToReqRes<RouteDef>>) => T) =>\n\tv.pipe<PipeInput<T>, PipeOutput<T>, any>((input) => {\n\t\tconst req = requestLocalStorage.getStore()\n\t\tif (!req) throw PipeError.root('Request not found in context', input)\n\t\treturn v.assert(fn(req), input)\n\t})\n\nexport const withResponse = <T extends Pipe<any, any, any>>(fn: (req: Response<RouteDefToReqRes<RouteDef>>) => T) =>\n\tv.pipe<PipeInput<T>, PipeOutput<T>, any>((input) => {\n\t\tconst res = responseLocalStorage.getStore()\n\t\tif (!res) throw PipeError.root('Response not found in context', input)\n\t\treturn v.assert(fn(res), input)\n\t})\n","import { DataClass, Pipe, v } from 'valleyed'\n\nimport { HookCb, HookEvent, HookRecord, runHooks } from './hooks'\nimport { instanceSettingsPipe, mapSettingsToInstance, MapSettingsToInstance, Settings, SettingsInput } from './settings'\nimport { EquippedError } from '../errors'\n\nexport class Instance<E extends object, S extends SettingsInput> extends DataClass<MapSettingsToInstance<S>> {\n\tstatic #instance: Instance<object, SettingsInput>\n\tstatic #hooks: Partial<Record<HookEvent, HookRecord[]>> = {}\n\treadonly envs: Readonly<E>\n\treadonly settings: Readonly<Settings>\n\n\tprivate constructor(envs: E, settings: S) {\n\t\tsuper(mapSettingsToInstance(settings as any))\n\t\tInstance.#instance = this as any\n\t\tthis.envs = Object.freeze(envs)\n\t\tthis.settings = Object.freeze(settings) as any\n\t\tInstance.#registerOnExitHandler()\n\t}\n\n\tgetScopedName(name: string, key = '.') {\n\t\treturn [this.settings.app.name, name].join(key)\n\t}\n\n\tasync start() {\n\t\ttry {\n\t\t\tawait runHooks(Instance.#hooks['setup'] ?? [])\n\t\t\tawait runHooks(Instance.#hooks['start'] ?? [])\n\t\t} catch (error) {\n\t\t\tInstance.crash(new EquippedError(`Error starting instance`, {}, error))\n\t\t}\n\t}\n\n\tstatic create<E extends object, S extends SettingsInput>(envsPipe: Pipe<unknown, E, any>, settings: (envs: E) => S) {\n\t\tif (Instance.#instance) throw Instance.crash(new EquippedError('An instance has already been created. Use that instead', {}))\n\t\tconst envValidity = v.validate(envsPipe, process.env)\n\t\tif (!envValidity.valid) {\n\t\t\tInstance.crash(\n\t\t\t\tnew EquippedError(`Environment variables are not valid\\n${envValidity.error.toString()}`, {\n\t\t\t\t\tmessages: envValidity.error.messages,\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\t\tconst settingsValidity = v.validate(instanceSettingsPipe(), settings(envValidity.value))\n\t\tif (!settingsValidity.valid) {\n\t\t\tInstance.crash(\n\t\t\t\tnew EquippedError(`Settings are not valid\\n${settingsValidity.error.toString()}`, {\n\t\t\t\t\tmessages: settingsValidity.error.messages,\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\t\treturn new Instance<E, S>(envValidity.value, settingsValidity.value as S)\n\t}\n\n\tstatic get() {\n\t\tif (!Instance.#instance)\n\t\t\treturn Instance.crash(\n\t\t\t\tnew EquippedError('Has not been initialized. Make sure an instance has been created before you get an instance', {}),\n\t\t\t)\n\t\treturn Instance.#instance\n\t}\n\n\tstatic on(event: HookEvent, cb: HookCb, order: number) {\n\t\tInstance.#hooks[event] ??= []\n\t\tInstance.#hooks[event].push({ cb, order })\n\t}\n\n\tstatic #registerOnExitHandler() {\n\t\tconst signals = {\n\t\t\tSIGHUP: 1,\n\t\t\tSIGINT: 2,\n\t\t\tSIGTERM: 15,\n\t\t}\n\n\t\tObject.entries(signals).forEach(([signal, code]) => {\n\t\t\tprocess.on(signal, async () => {\n\t\t\t\tawait runHooks(Instance.#hooks['close'] ?? [], () => {})\n\t\t\t\tprocess.exit(128 + code)\n\t\t\t})\n\t\t})\n\t}\n\n\tstatic resolveBeforeCrash<T>(cb: () => Promise<T>) {\n\t\tconst value = cb()\n\t\tInstance.on('close', async () => await value, 10)\n\t\treturn value\n\t}\n\n\tstatic crash(error: EquippedError): never {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.error(error)\n\t\tprocess.exit(1)\n\t}\n}\n","export type HookEvent = 'setup' | 'start' | 'close'\nexport type HookCb = Promise<unknown | void> | (() => void | unknown | Promise<void | unknown>)\nexport type HookRecord = { cb: HookCb; order: number }\n\nexport async function runHooks(\n\thooks: HookRecord[],\n\tonError: (error: Error) => void = (error) => {\n\t\tthrow error\n\t},\n) {\n\tconst grouped = hooks.reduce<Record<string, HookRecord[]>>((acc, cur) => {\n\t\tconst key = cur.order.toString()\n\t\tif (!acc[key]) acc[key] = []\n\t\tacc[key].push(cur)\n\t\treturn acc\n\t}, {})\n\tconst groups = Object.keys(grouped)\n\t\t.sort((a, b) => parseInt(a) - parseInt(b))\n\t\t.map((key) => grouped[key])\n\tfor (const group of groups)\n\t\tawait Promise.all(\n\t\t\tgroup.map(async (h) => {\n\t\t\t\ttry {\n\t\t\t\t\tif (typeof h.cb === 'function') return await h.cb()\n\t\t\t\t\treturn await h.cb\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn onError(error instanceof Error ? error : new Error(`${error}`))\n\t\t\t\t}\n\t\t\t}),\n\t\t)\n}\n","import pino, { Logger } from 'pino'\nimport { ConditionalObjectKeys, IsInTypeList, PipeInput, PipeOutput, v } from 'valleyed'\n\nimport { Cache, RedisCache, redisConfigPipe } from '../cache'\nimport { MongoDb, mongoDbConfigPipe } from '../dbs'\nimport { EventBus, KafkaEventBus, RabbitMQEventBus, kafkaConfigPipe, rabbitmqConfigPipe } from '../events'\nimport { RedisJob, redisJobsConfigPipe } from '../jobs'\nimport { BaseApiKeysUtility, BaseTokensUtility, ExpressServer, FastifyServer, Server } from '../server'\n\nexport const instanceSettingsPipe = () =>\n\tv.object({\n\t\tapp: v.object({\n\t\t\tid: v.string(),\n\t\t\tname: v.string(),\n\t\t}),\n\t\tlog: v.defaults(\n\t\t\tv.object({\n\t\t\t\tlevel: v.defaults(v.in(['fatal', 'error', 'warn', 'info', 'debug', 'trace', 'silent'] as const), 'info'),\n\t\t\t}),\n\t\t\t{},\n\t\t),\n\t\tdbs: v.optional(\n\t\t\tv.object({\n\t\t\t\ttypes: v.record(\n\t\t\t\t\tv.string(),\n\t\t\t\t\tv.discriminate((e) => e?.type, {\n\t\t\t\t\t\tmongo: v.merge(mongoDbConfigPipe, v.object({ type: v.is('mongo' as const) })),\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t\tchanges: v.optional(\n\t\t\t\t\tv.object({\n\t\t\t\t\t\tdebeziumUrl: v.string(),\n\t\t\t\t\t\tkafkaConfig: kafkaConfigPipe,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t}),\n\t\t),\n\t\teventBus: v.optional(\n\t\t\tv.discriminate((e: any) => e?.type, {\n\t\t\t\tkafka: v.merge(kafkaConfigPipe, v.object({ type: v.is('kafka' as const) })),\n\t\t\t\trabbitmq: v.merge(rabbitmqConfigPipe, v.object({ type: v.is('rabbitmq' as const) })),\n\t\t\t}),\n\t\t),\n\t\tcache: v.discriminate((e: any) => e?.type, {\n\t\t\tredis: v.merge(redisConfigPipe, v.object({ type: v.is('redis' as const) })),\n\t\t}),\n\t\tjobs: v.optional(v.merge(redisJobsConfigPipe, v.object({ type: v.is('redis' as const) }))),\n\t\tserver: v.optional(\n\t\t\tv.object({\n\t\t\t\ttype: v.in(['fastify', 'express'] as const),\n\t\t\t\tport: v.number(),\n\t\t\t\tpublicPath: v.optional(v.string()),\n\t\t\t\thealthPath: v.optional(v.string()),\n\t\t\t\topenapi: v.defaults(\n\t\t\t\t\tv.object({\n\t\t\t\t\t\tdocsVersion: v.defaults(v.string(), '1.0.0'),\n\t\t\t\t\t\tdocsBaseUrl: v.defaults(v.array(v.string()), ['/']),\n\t\t\t\t\t\tdocsPath: v.defaults(v.string(), '/__docs'),\n\t\t\t\t\t}),\n\t\t\t\t\t{},\n\t\t\t\t),\n\t\t\t\trequests: v.defaults(\n\t\t\t\t\tv.object({\n\t\t\t\t\t\tlog: v.defaults(v.boolean(), true),\n\t\t\t\t\t\tpaginationDefaultLimit: v.defaults(v.number(), 100),\n\t\t\t\t\t\tmaxFileUploadSizeInMb: v.defaults(v.number(), 500),\n\t\t\t\t\t\trateLimit: v.defaults(\n\t\t\t\t\t\t\tv.object({\n\t\t\t\t\t\t\t\tenabled: v.defaults(v.boolean(), false),\n\t\t\t\t\t\t\t\tperiodInMs: v.defaults(v.number(), 60 * 60 * 1000),\n\t\t\t\t\t\t\t\tlimit: v.defaults(v.number(), 5000),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t{},\n\t\t\t\t\t\t),\n\t\t\t\t\t\tslowdown: v.defaults(\n\t\t\t\t\t\t\tv.object({\n\t\t\t\t\t\t\t\tenabled: v.defaults(v.boolean(), false),\n\t\t\t\t\t\t\t\tperiodInMs: v.defaults(v.number(), 10 * 60 * 1000),\n\t\t\t\t\t\t\t\tdelayAfter: v.defaults(v.number(), 2000),\n\t\t\t\t\t\t\t\tdelayInMs: v.defaults(v.number(), 500),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t{},\n\t\t\t\t\t\t),\n\t\t\t\t\t}),\n\t\t\t\t\t{},\n\t\t\t\t),\n\t\t\t\trequestsAuth: v.defaults(\n\t\t\t\t\tv.object({\n\t\t\t\t\t\ttokens: v.optional(v.instanceOf(BaseTokensUtility)),\n\t\t\t\t\t\tapiKey: v.optional(v.instanceOf(BaseApiKeysUtility)),\n\t\t\t\t\t}),\n\t\t\t\t\t{},\n\t\t\t\t),\n\t\t\t}),\n\t\t),\n\t\tutils: v.defaults(\n\t\t\tv.object({\n\t\t\t\thashSaltRounds: v.defaults(v.number(), 10),\n\t\t\t}),\n\t\t\t{},\n\t\t),\n\t})\n\nexport type Settings = PipeOutput<ReturnType<typeof instanceSettingsPipe>>\nexport type SettingsInput = ConditionalObjectKeys<PipeInput<ReturnType<typeof instanceSettingsPipe>>>\n\ntype DbTypesMap = { mongo: MongoDb }\ntype ReshapeDbs<T extends SettingsInput> =\n\tIsInTypeList<NonNullable<T['dbs']>['types'], [unknown]> extends true\n\t\t? {}\n\t\t: {\n\t\t\t\t[K in keyof NonNullable<T['dbs']>['types']]: NonNullable<T['dbs']>['types'][K] extends { type: keyof DbTypesMap }\n\t\t\t\t\t? DbTypesMap[NonNullable<T['dbs']>['types'][K]['type']]\n\t\t\t\t\t: never\n\t\t\t}\n\ntype AddUndefined<T, C> = IsInTypeList<C, [undefined, unknown]> extends true ? undefined : T\nexport type MapSettingsToInstance<T extends SettingsInput> = {\n\tapp: T['app']\n\tlog: Logger<any, boolean>\n\teventBus: AddUndefined<EventBus, T['eventBus']>\n\tcache: AddUndefined<Cache, T['cache']>\n\tjobs: AddUndefined<RedisJob, T['jobs']>\n\tserver: AddUndefined<Server, T['server']>\n\tdbs: ReshapeDbs<T>\n\tutils: T['utils']\n}\n\nexport function mapSettingsToInstance<T extends Settings>(settings: T): MapSettingsToInstance<T> {\n\tconst log = pino<any>({\n\t\tlevel: settings.log.level,\n\t\tserializers: {\n\t\t\terr: pino.stdSerializers.err,\n\t\t\terror: pino.stdSerializers.err,\n\t\t\treq: pino.stdSerializers.req,\n\t\t\tres: pino.stdSerializers.res,\n\t\t},\n\t})\n\tconst cache = new RedisCache(settings.cache)\n\tconst jobs = settings.jobs ? new RedisJob(settings.jobs) : undefined\n\tconst eventBus =\n\t\tsettings.eventBus?.type === 'kafka'\n\t\t\t? new KafkaEventBus(deleteKeys(settings.eventBus, ['type']))\n\t\t\t: settings.eventBus?.type === 'rabbitmq'\n\t\t\t\t? new RabbitMQEventBus(deleteKeys(settings.eventBus, ['type']))\n\t\t\t\t: undefined\n\n\tconst serverConfig = {\n\t\tapp: settings.app,\n\t\tlog,\n\t\teventBus,\n\t}\n\tconst server =\n\t\tsettings.server?.type === 'express'\n\t\t\t? new ExpressServer({ ...serverConfig, config: settings.server })\n\t\t\t: settings.server?.type === 'fastify'\n\t\t\t\t? new FastifyServer({ ...serverConfig, config: settings.server })\n\t\t\t\t: undefined\n\n\tconst changesConfig = settings.dbs?.changes\n\t\t? {\n\t\t\t\tdebeziumUrl: settings.dbs.changes.debeziumUrl,\n\t\t\t\teventBus: new KafkaEventBus(settings.dbs.changes.kafkaConfig),\n\t\t\t}\n\t\t: undefined\n\n\tconst dbs = Object.fromEntries(\n\t\tObject.entries(settings.dbs?.types ?? {}).map(([key, config]) => [\n\t\t\tkey,\n\t\t\tconfig.type === 'mongo' ? new MongoDb(config, { changes: changesConfig }) : undefined,\n\t\t]),\n\t)\n\n\treturn {\n\t\tapp: settings.app,\n\t\tutils: settings.utils,\n\t\tlog,\n\t\teventBus: eventBus as any,\n\t\tcache: cache as any,\n\t\tjobs: jobs as any,\n\t\tserver: server as any,\n\t\tdbs: dbs as any,\n\t}\n}\n\nfunction deleteKeys<T extends object, K extends keyof T>(data: T, keys: K[]) {\n\tfor (const key of keys) delete data[key]\n\treturn data\n}\n","export abstract class Cache {\n\tabstract set(key: string, data: string, ttlInSecs: number): Promise<void>\n\n\tabstract get(key: string): Promise<string | null>\n\n\tabstract delete(key: string): Promise<void>\n\n\tabstract getOrSet<T>(key: string, fn: () => Promise<T>, ttlInSecs: number): Promise<T>\n}\n","import { v, PipeOutput } from 'valleyed'\n\nexport const redisConfigPipe = v.meta(\n\tv.object({\n\t\thost: v.string(),\n\t\tport: v.optional(v.number()),\n\t\tpassword: v.optional(v.string()),\n\t\tusername: v.optional(v.string()),\n\t\ttls: v.optional(v.boolean()),\n\t\tcluster: v.optional(v.boolean()),\n\t}),\n\t{ title: 'Redis Config', $refId: 'RedisConfig' },\n)\n\nexport type RedisConfig = PipeOutput<typeof redisConfigPipe>\n","import { Cluster, Redis, RedisOptions } from 'ioredis'\n\nimport { EquippedError } from '../../errors'\nimport { Instance } from '../../instance'\nimport { Cache } from '../base'\nimport { RedisConfig } from '../pipes'\n\nexport class RedisCache extends Cache {\n\tclient: Redis | Cluster\n\n\tconstructor(settings: RedisConfig, extraConfig?: Partial<RedisOptions>) {\n\t\tsuper()\n\t\tconst node = {\n\t\t\t...(settings.host ? { host: settings.host } : {}),\n\t\t\t...(settings.port ? { port: settings.port } : {}),\n\t\t}\n\t\tconst common = {\n\t\t\t...extraConfig,\n\t\t\t...(settings.password ? { password: settings.password } : {}),\n\t\t\t...(settings.username ? { username: settings.username } : {}),\n\t\t\t...(settings.tls ? { tls: {} } : {}),\n\t\t\tlazyConnect: true,\n\t\t}\n\t\tthis.client = settings.cluster\n\t\t\t? new Cluster([node], {\n\t\t\t\t\t...extraConfig,\n\t\t\t\t\tredisOptions: common,\n\t\t\t\t\tlazyConnect: true,\n\t\t\t\t})\n\t\t\t: new Redis({ ...common, ...node })\n\t\tthis.client.on('error', async (error) => {\n\t\t\tInstance.crash(new EquippedError(`Redis failed with error`, {}, error))\n\t\t})\n\t\tif (!extraConfig) Instance.on('start', async () => this.client.connect(), 1)\n\t\tInstance.on('close', async () => this.client.quit(), 1)\n\t}\n\n\tasync delete(key: string) {\n\t\tawait this.client.del(Instance.get().getScopedName(key, ':'))\n\t}\n\n\tasync get(key: string) {\n\t\treturn await this.client.get(Instance.get().getScopedName(key, ':'))\n\t}\n\n\tasync set(key: string, data: string, ttlInSecs: number) {\n\t\tif (ttlInSecs > 0) await this.client.setex(Instance.get().getScopedName(key, ':'), ttlInSecs, data)\n\t\telse this.client.set(Instance.get().getScopedName(key), data)\n\t}\n\n\tasync getOrSet<T>(key: string, fn: () => Promise<T>, ttlInSecs: number) {\n\t\tconst cached = await this.get(Instance.get().getScopedName(key, ':'))\n\t\tif (cached) return JSON.parse(cached)\n\n\t\tconst result = await fn()\n\t\tawait this.set(Instance.get().getScopedName(key, ':'), JSON.stringify(result), ttlInSecs)\n\t}\n}\n","export class EquippedError extends Error {\n\tconstructor(\n\t\tpublic readonly message: string,\n\t\tpublic readonly context: Record<string, unknown>,\n\t\tpublic readonly cause?: unknown,\n\t) {\n\t\tsuper(message, { cause })\n\t}\n}\n","import type { StatusCodesEnum } from '../server'\nimport { EquippedError } from './equippedError'\n\nexport abstract class RequestError extends EquippedError {\n\tabstract readonly statusCode: StatusCodesEnum\n\n\tprotected constructor(\n\t\tpublic readonly message: string,\n\t\tpublic readonly serializedErrors: { message: string; field?: string }[],\n\t\tcause?: unknown,\n\t) {\n\t\tsuper(message, { serializedErrors }, cause)\n\t}\n}\n","import type http from 'http'\n\nimport { Server as SocketServer } from 'socket.io'\nimport supertest from 'supertest'\nimport { Pipe, PipeError, v } from 'valleyed'\n\nimport { EquippedError, NotFoundError, RequestError } from '../../errors'\nimport { Instance } from '../../instance'\nimport { pipeErrorToValidationError } from '../../validations'\nimport { requestLocalStorage, responseLocalStorage } from '../../validations/valleyed'\nimport { parseAuthUser } from '../middlewares/parseAuthUser'\nimport { OpenApi, OpenApiSchemaDef } from '../openapi'\nimport { ServerConfig } from '../pipes'\nimport { type Request, Response } from '../requests'\nimport { Router } from '../routes'\nimport { SocketEmitter } from '../sockets'\nimport { Methods, MethodsEnum, RouteDef, StatusCodes, type Route } from '../types'\n\ntype RequestValidator = (req: Request<any>) => Promise<Request<any>>\ntype ResponseValidator = (res: Response<any>) => Promise<Response<any>>\n\nconst errorsSchemas = Object.entries(StatusCodes)\n\t.filter(([, value]) => value > 399)\n\t.map(([key, value]) => ({\n\t\tstatus: value,\n\t\tcontentType: 'application/json',\n\t\tpipe: v.meta(v.array(v.object({ message: v.string(), field: v.optional(v.string()) })), {\n\t\t\t$refId: `Errors.${key}Response`,\n\t\t\tdescription: `${key} Response`,\n\t\t}) as Pipe<any, any, any>,\n\t}))\n\nexport abstract class Server<Req = any, Res = any> {\n\t#queue: (() => void | Promise<void>)[] = []\n\t#routesByKey = new Map<string, boolean>()\n\t#openapi: OpenApi\n\tsocket: SocketEmitter\n\tprotected server: http.Server\n\tprotected cors = {\n\t\torigin: '*',\n\t\tmethods: Object.values(Methods)\n\t\t\t.filter((m) => m !== Methods.options)\n\t\t\t.map((m) => m.toUpperCase()),\n\t}\n\n\tconstructor(\n\t\tserver: http.Server,\n\t\tprivate config: ServerConfig,\n\t\tprotected implementations: {\n\t\t\tparseRequest: (req: Req) => Promise<Request<any>>\n\t\t\thandleResponse: (res: Res, response: Response<any>) => Promise<void>\n\t\t\tregisterRoute: (method: MethodsEnum, path: string, cb: (req: Req, res: Res) => Promise<void>) => void\n\t\t\tregisterErrorHandler: (cb: (error: Error, req: Req, res: Res) => Promise<void>) => void\n\t\t\tregisterNotFoundHandler: (cb: (req: Req, res: Res) => Promise<void>) => void\n\t\t\tstart: (port: number) => Promise<boolean>\n\t\t},\n\t) {\n\t\tthis.server = server\n\t\tthis.#openapi = new OpenApi(this.config)\n\t\tconst socketInstance = new SocketServer(server, { cors: this.cors })\n\t\tthis.socket = new SocketEmitter(socketInstance, config.eventBus)\n\t\tthis.addRouter(this.#openapi.router())\n\t}\n\n\taddRouter(...routers: Router<any>[]) {\n\t\trouters.map((router) => router.routes).forEach((routes) => this.addRoute(...routes))\n\t}\n\n\taddRoute<T extends RouteDef>(...routes: Route<T>[]) {\n\t\troutes.forEach((route) => {\n\t\t\tthis.#queue.push(async () => {\n\t\t\t\tconst { method, path, schema = {}, onError, middlewares = [] } = route\n\n\t\t\t\tconst key = `(${method.toUpperCase()}) ${this.#openapi.cleanPath(path)}`\n\t\t\t\tif (this.#routesByKey.get(key))\n\t\t\t\t\tthrow new EquippedError(`Route key ${key} already registered. All route keys must be unique`, { route, key })\n\n\t\t\t\tmiddlewares.unshift(parseAuthUser as any)\n\t\t\t\tmiddlewares.forEach((m) => m.onSetup?.(route as any))\n\t\t\t\tonError?.onSetup?.(route as any)\n\n\t\t\t\tconst { validateRequest, validateResponse, jsonSchema } = this.#resolveSchema(method, schema)\n\n\t\t\t\tthis.#routesByKey.set(key, true)\n\t\t\t\tawait this.#openapi.register(route, jsonSchema)\n\t\t\t\tthis.implementations.registerRoute(method, this.#openapi.cleanPath(path), async (req: Req, res: Res) => {\n\t\t\t\t\tconst request = await validateRequest(await this.implementations.parseRequest(req))\n\t\t\t\t\ttry {\n\t\t\t\t\t\tfor (const middleware of middlewares) await middleware.cb(request)\n\t\t\t\t\t\tconst rawRes = await route.handler(request)\n\t\t\t\t\t\tconst response =\n\t\t\t\t\t\t\trawRes instanceof Response\n\t\t\t\t\t\t\t\t? rawRes\n\t\t\t\t\t\t\t\t: new Response({ body: rawRes, status: StatusCodes.Ok, headers: {}, piped: false })\n\t\t\t\t\t\treturn await this.implementations.handleResponse(res, await validateResponse(response))\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tif (onError?.cb) {\n\t\t\t\t\t\t\tconst rawResponse = await onError.cb(request, error as Error)\n\t\t\t\t\t\t\tconst response =\n\t\t\t\t\t\t\t\trawResponse instanceof Response\n\t\t\t\t\t\t\t\t\t? rawResponse\n\t\t\t\t\t\t\t\t\t: new Response({ body: rawResponse, status: StatusCodes.BadRequest, headers: {} })\n\t\t\t\t\t\t\treturn await this.implementations.handleResponse(res, await validateResponse(response))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthrow error\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\t}\n\n\t#resolveSchema(method: MethodsEnum, schema: RouteDef) {\n\t\tconst defaultStatusCode = schema?.defaultStatusCode ?? StatusCodes.Ok\n\t\tconst defaultContentType = schema?.defaultContentType ?? 'application/json'\n\t\tlet status = defaultStatusCode\n\t\tlet contentType = defaultContentType\n\t\tconst jsonSchema: OpenApiSchemaDef = { response: {}, request: {} }\n\t\tconst requestPipe: Pick<RouteDef, 'body' | 'headers' | 'query' | 'params'> = {}\n\t\tconst responsePipe: Pick<RouteDef, 'response' | 'responseHeaders'> = {}\n\n\t\tconst defs: {\n\t\t\tkey: Exclude<keyof RouteDef, `default${string}` | 'context'>\n\t\t\ttype: keyof OpenApiSchemaDef\n\t\t\tskip?: boolean\n\t\t}[] = [\n\t\t\t{ key: 'params', type: 'request' },\n\t\t\t{ key: 'headers', type: 'request' },\n\t\t\t{ key: 'query', type: 'request' },\n\t\t\t{ key: 'body', type: 'request', skip: !(<MethodsEnum[]>[Methods.post, Methods.put, Methods.patch]).includes(method) },\n\t\t\t{ key: 'response', type: 'response' },\n\t\t\t{ key: 'responseHeaders', type: 'response' },\n\t\t]\n\t\tdefs.forEach((def) => {\n\t\t\tconst pipe = schema[def.key] ?? v.any()\n\t\t\tif (def.skip) return\n\n\t\t\tif (def.type === 'request') {\n\t\t\t\trequestPipe[def.key] = pipe\n\t\t\t\tjsonSchema.request[def.key as keyof typeof jsonSchema.request] = v.schema(pipe)\n\t\t\t}\n\t\t\tif (def.type === 'response') {\n\t\t\t\tconst pipeRecords = errorsSchemas.concat({ status: defaultStatusCode, contentType, pipe })\n\t\t\t\tresponsePipe[def.key] = v.any().pipe((input) => {\n\t\t\t\t\tconst p = pipeRecords.find((r) => r.status === status)?.pipe\n\t\t\t\t\tif (!p) throw PipeError.root(`schema not defined for status code: ${status}`, input)\n\t\t\t\t\treturn v.assert(p, input)\n\t\t\t\t})\n\t\t\t\tjsonSchema.response[def.key as keyof typeof jsonSchema.response] = pipeRecords.map((record) => ({\n\t\t\t\t\tstatus: record.status,\n\t\t\t\t\tcontentType: record.contentType,\n\t\t\t\t\tschema: v.schema(record.pipe),\n\t\t\t\t}))\n\t\t\t}\n\t\t})\n\t\tconst validateRequest: RequestValidator = async (request) => {\n\t\t\tif (!Object.keys(requestPipe)) return request\n\t\t\tconst context = schema.context ? await schema.context(request) : {}\n\t\t\trequest.context = context\n\t\t\tconst validity = requestLocalStorage.run(request, () =>\n\t\t\t\tv.validate(v.object(requestPipe), {\n\t\t\t\t\tparams: request.params,\n\t\t\t\t\theaders: request.headers,\n\t\t\t\t\tquery: request.query,\n\t\t\t\t\tbody: request.body,\n\t\t\t\t}),\n\t\t\t)\n\n\t\t\tif (!validity.valid) throw pipeErrorToValidationError(validity.error)\n\t\t\trequest.params = validity.value.params\n\t\t\trequest.headers = validity.value.headers\n\t\t\trequest.query = validity.value.query\n\t\t\trequest.body = validity.value.body\n\t\t\treturn request\n\t\t}\n\t\tconst validateResponse: ResponseValidator = async (response) => {\n\t\t\tif (!Object.keys(responsePipe)) return response\n\t\t\tstatus = response.status\n\t\t\tcontentType = response.contentType\n\t\t\tcontentType\n\n\t\t\tconst validity = responseLocalStorage.run(response, () =>\n\t\t\t\tv.validate(v.object(responsePipe), {\n\t\t\t\t\tresponseHeaders: response.headers,\n\t\t\t\t\tresponse: response.body,\n\t\t\t\t}),\n\t\t\t)\n\n\t\t\tif (!validity.valid) throw pipeErrorToValidationError(validity.error)\n\t\t\tresponse.body = validity.value.response\n\t\t\tresponse.headers = validity.value.responseHeaders\n\t\t\treturn response\n\t\t}\n\t\treturn {\n\t\t\tjsonSchema,\n\t\t\tvalidateRequest,\n\t\t\tvalidateResponse,\n\t\t}\n\t}\n\n\ttest() {\n\t\treturn supertest(this.server)\n\t}\n\n\tasync start() {\n\t\tconst port = this.config.config.port\n\t\tif (this.config.config.healthPath)\n\t\t\tthis.addRoute({\n\t\t\t\tmethod: Methods.get,\n\t\t\t\tpath: this.config.config.healthPath,\n\t\t\t\thandler: async (req) =>\n\t\t\t\t\treq.res({\n\t\t\t\t\t\tbody: `${this.config.app.id}(${this.config.app.name}) service running`,\n\t\t\t\t\t\tcontentType: 'text/plain',\n\t\t\t\t\t}),\n\t\t\t})\n\n\t\tthis.implementations.registerNotFoundHandler(async (req) => {\n\t\t\tconst request = await this.implementations.parseRequest(req)\n\t\t\tthrow new NotFoundError(`Route ${request.path} not found`)\n\t\t})\n\t\tthis.implementations.registerErrorHandler(async (error, _, res) => {\n\t\t\tInstance.get().log.error(error)\n\t\t\tconst response =\n\t\t\t\terror instanceof RequestError\n\t\t\t\t\t? new Response({\n\t\t\t\t\t\t\tbody: error.serializedErrors,\n\t\t\t\t\t\t\tstatus: error.statusCode,\n\t\t\t\t\t\t})\n\t\t\t\t\t: new Response({\n\t\t\t\t\t\t\tbody: [{ message: 'Something went wrong', data: error.message }],\n\t\t\t\t\t\t\tstatus: StatusCodes.BadRequest,\n\t\t\t\t\t\t})\n\t\t\treturn await this.implementations.handleResponse(res, response)\n\t\t})\n\n\t\tawait Promise.all(this.#queue.map((cb) => cb()))\n\t\tconst started = await this.implementations.start(port)\n\t\tif (started) Instance.get().log.info(`${this.config.app.id}(${this.config.app.name}) service listening on port ${port}`)\n\t\treturn started\n\t}\n}\n","import { IsInTypeList, Pipe, PipeContext, PipeInput, PipeOutput, Prettify } from 'valleyed'\n\nimport type { Request, Response } from './requests'\nimport type { RequestError } from '../errors'\nimport { Enum } from '../types'\n\nexport const Methods = {\n\thead: 'head',\n\tget: 'get',\n\tpost: 'post',\n\tput: 'put',\n\tpatch: 'patch',\n\tdelete: 'delete',\n\toptions: 'options',\n} as const\n\nexport const StatusCodes = {\n\tOk: 200,\n\tFound: 302,\n\tBadRequest: 400,\n\tNotAuthenticated: 401,\n\tNotAuthorized: 403,\n\tNotFound: 404,\n\tValidationError: 422,\n\tTooManyRequests: 429,\n\tAuthorizationExpired: 461,\n} as const\n\nexport type MethodsEnum = Enum<typeof Methods>\nexport type StatusCodesEnum = Enum<typeof StatusCodes>\n\nexport type DefaultHeaders = Record<string, ArrayOrValue<string>>\n\ntype ArrayOrValue<T> = T | T[] | undefined\n\nexport type IncomingFile = {\n\tname: string\n\ttype: string\n\tsize: number\n\tisTruncated: boolean\n\tdata: Buffer\n\tduration: number\n}\n\nexport type RouteDef = {\n\tparams?: Pipe<Record<string, ArrayOrValue<string>>, Record<string, ArrayOrValue<string>>, any>\n\tquery?: Pipe<Record<string, ArrayOrValue<unknown>>, Record<string, ArrayOrValue<unknown>>, any>\n\theaders?: Pipe<DefaultHeaders, DefaultHeaders, any>\n\tbody?: Pipe<Record<string, unknown>, Record<string, unknown>, any>\n\tresponse?: Pipe<unknown, unknown, any>\n\tresponseHeaders?: Pipe<DefaultHeaders, DefaultHeaders, any>\n\tdefaultStatusCode?: StatusCodesEnum\n\tdefaultContentType?: string\n\tcontext?: (req: Request<RouteDefToReqRes<RouteDef>>) => Awaitable<Record<string, unknown>>\n}\n\ntype RouteGroup = { name: string; description?: string }\ntype HandlerSetup<T extends RouteDef> = (route: Route<T>) => void\n\nexport type RouteConfig<T extends RouteDef> = {\n\tmiddlewares?: ReturnType<typeof makeMiddleware<RouteDef>>[]\n\tonError?: ReturnType<typeof makeErrorMiddleware<RouteDef>>\n\tgroups?: (RouteGroup | RouteGroup['name'])[]\n\ttitle?: string\n\tdescriptions?: string[]\n\tsecurity?: Record<string, string[]>[]\n\tschema?: T\n\thide?: boolean\n}\n\nexport type RouterConfig<T extends RouteDef> = RouteConfig<T> & { path: string }\nexport type Route<T extends RouteDef> = RouteConfig<T> & {\n\tpath: string\n\tmethod: MethodsEnum\n\thandler: RouteDefHandler<T>\n}\n\ntype GetApiPart<T extends RouteDef, K extends keyof RouteDef> = NonNullable<IsInTypeList<T[K], [unknown]> extends true ? RouteDef[K] : T[K]>\n\ntype ArePipes<A, B> = A extends Pipe<any, any, any> ? (B extends Pipe<any, any, any> ? true : false) : false\ntype Compare<K extends keyof RouteDef, A, B> =\n\tIsInTypeList<B, [unknown]> extends true\n\t\t? A\n\t\t: IsInTypeList<A, [unknown]> extends true\n\t\t\t? B\n\t\t\t: K extends `default${string}` | 'context'\n\t\t\t\t? B\n\t\t\t\t: ArePipes<A, B> extends true\n\t\t\t\t\t? Pipe<PipeInput<A> & PipeInput<B>, PipeOutput<A> & PipeOutput<B>, PipeContext<A> & PipeContext<B>>\n\t\t\t\t\t: B\n\nexport type MergeRouteDefs<A extends RouteDef, B extends RouteDef> = {\n\t[K in keyof RouteDef]: Compare<K, A[K], B[K]>\n}\n\nexport type RouteDefToReqRes<T extends RouteDef> = Prettify<{\n\tbody: PipeOutput<GetApiPart<T, 'body'>>\n\tparams: PipeOutput<GetApiPart<T, 'params'>>\n\trequestHeaders: PipeOutput<GetApiPart<T, 'headers'>>\n\tquery: PipeOutput<GetApiPart<T, 'query'>>\n\tresponse: PipeOutput<GetApiPart<T, 'response'>>\n\tresponseHeaders: PipeOutput<GetApiPart<T, 'responseHeaders'>>\n\tstatusCode: GetApiPart<T, 'defaultStatusCode'>\n\tcontentType: GetApiPart<T, 'defaultContentType'>\n\tcontext: Awaited<ReturnType<GetApiPart<T, 'context'>>>\n}>\n\ntype Awaitable<T> = Promise<T> | T\ntype Res<T extends RouteDefToReqRes<any>> = Awaitable<\n\tIsInTypeList<T['statusCode'], [StatusCodesEnum, 200]> extends true\n\t\t? IsInTypeList<T['responseHeaders'], [DefaultHeaders]> extends true\n\t\t\t? Response<T> | T['response']\n\t\t\t: Response<T>\n\t\t: Response<T>\n>\nexport type RouteDefHandler<Def extends RouteDef> = (req: Request<RouteDefToReqRes<Def>>) => Res<RouteDefToReqRes<Def>>\ntype RouteMiddlewareHandler<_Def extends RouteDef> = (req: Request<RouteDefToReqRes<RouteDef>>) => Awaitable<void>\ntype ErrorHandler<Def extends RouteDef> = (\n\treq: Request<RouteDefToReqRes<Def>>,\n\terr: Error,\n) => Res<\n\tOmit<RouteDefToReqRes<Def>, 'response' | 'statusCode' | 'responseHeaders'> & {\n\t\tresponse: RequestError['serializedErrors']\n\t\tstatusCode: RequestError['statusCode']\n\t\tresponseHeaders: DefaultHeaders\n\t}\n>\n\nfunction makeMiddlewareHandler<Cb extends Function, T extends RouteDef>(cb: Cb, onSetup?: HandlerSetup<T>) {\n\treturn { cb, onSetup }\n}\n\nexport const makeMiddleware = <Def extends RouteDef>(...args: Parameters<typeof makeMiddlewareHandler<RouteMiddlewareHandler<Def>, Def>>) =>\n\tmakeMiddlewareHandler(...args)\nexport const makeErrorMiddleware = <Def extends RouteDef>(...args: Parameters<typeof makeMiddlewareHandler<ErrorHandler<Def>, Def>>) =>\n\tmakeMiddlewareHandler(...args)\n","import { BadRequestError, RequestError } from '../../errors'\nimport { Instance } from '../../instance'\nimport { makeMiddleware } from '../types'\n\nexport const parseAuthUser = makeMiddleware(async (request) => {\n\tconst requestsAuth = Instance.get().settings.server?.requestsAuth\n\tif (!requestsAuth) return\n\tconst { Authorization, ApiKey } = request.headers\n\tfunction makeErrorHandler(key: 'access' | 'apiKey') {\n\t\treturn function (err: any) {\n\t\t\trequest.users[key].error = err instanceof RequestError ? err : new BadRequestError('failed to parse auth user', err)\n\t\t\trequest.users[key].error.context[key] = key\n\t\t\treturn undefined\n\t\t}\n\t}\n\tif (requestsAuth.tokens && Authorization)\n\t\trequest.users.access.value = await requestsAuth.tokens.verifyAccessToken(Authorization).catch(makeErrorHandler('access'))\n\telse if (requestsAuth.apiKey && ApiKey)\n\t\trequest.users.apiKey.value = await requestsAuth.apiKey.verifyApiKey(ApiKey).catch(makeErrorHandler('apiKey'))\n})\n","import { convert } from '@openapi-contrib/json-schema-to-openapi-schema'\nimport { OpenAPIV3_1 } from 'openapi-types'\nimport { capitalize, JsonSchema } from 'valleyed'\n\nimport { ServerConfig } from './pipes'\nimport { Router } from './routes'\nimport { Route } from './types'\n\ndeclare module 'openapi-types' {\n\tnamespace OpenAPIV3 {\n\t\tinterface Document {\n\t\t\t'x-tagGroups': { name: string; tags: string[] }[]\n\t\t}\n\t\tinterface TagObject {\n\t\t\t'x-displayName': string\n\t\t}\n\t}\n}\n\nexport type OpenApiSchemaDef = {\n\trequest: Partial<Record<'body' | 'query' | 'params' | 'headers' | 'response', JsonSchema>>\n\tresponse: Partial<Record<'response' | 'responseHeaders', { status: number; schema: JsonSchema; contentType: string }[]>>\n}\n\nexport class OpenApi {\n\t#registeredTags: Record<string, boolean> = {}\n\t#registeredTagGroups: Record<string, { name: string; tags: string[] }> = {}\n\t#baseOpenapiDoc: OpenAPIV3_1.Document\n\n\tconstructor(private config: ServerConfig) {\n\t\tthis.#baseOpenapiDoc = {\n\t\t\topenapi: '3.0.0',\n\t\t\tinfo: {\n\t\t\t\ttitle: `${config.app.name} ${config.app.id}`,\n\t\t\t\tversion: config.config.openapi.docsVersion ?? '',\n\t\t\t},\n\t\t\tservers: config.config.openapi.docsBaseUrl?.map((url) => ({ url })),\n\t\t\tpaths: {},\n\t\t\tcomponents: {\n\t\t\t\tschemas: {},\n\t\t\t\tsecuritySchemes: {\n\t\t\t\t\tAuthorization: {\n\t\t\t\t\t\ttype: 'apiKey',\n\t\t\t\t\t\tname: 'authorization',\n\t\t\t\t\t\tin: 'header',\n\t\t\t\t\t},\n\t\t\t\t\tRefreshToken: {\n\t\t\t\t\t\ttype: 'apiKey',\n\t\t\t\t\t\tname: 'x-refresh-token',\n\t\t\t\t\t\tin: 'header',\n\t\t\t\t\t},\n\t\t\t\t\tApiKey: {\n\t\t\t\t\t\ttype: 'apiKey',\n\t\t\t\t\t\tname: 'x-api-key',\n\t\t\t\t\t\tin: 'header',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\ttags: [],\n\t\t\t'x-tagGroups': [],\n\t\t}\n\t}\n\n\tcleanPath(path: string) {\n\t\tlet cleaned = path.replace(/(\\/\\s*)+/g, '/')\n\t\tif (!cleaned.startsWith('/')) cleaned = `/${cleaned}`\n\t\tif (cleaned !== '/' && cleaned.endsWith('/')) cleaned = cleaned.slice(0, -1)\n\t\treturn cleaned\n\t}\n\n\tasync register(route: Route<any>, def: OpenApiSchemaDef) {\n\t\tif (route.hide) return\n\n\t\tconst tag = this.#buildTag(route.groups ?? [])\n\n\t\tconst cleanPath = this.cleanPath(route.path)\n\t\tconst operationId = `(${route.method.toUpperCase()}) ${cleanPath}`\n\t\tawait this.#addRouteToOpenApiDoc(cleanPath, route.method.toLowerCase(), def, {\n\t\t\toperationId,\n\t\t\tsummary: route.title ?? cleanPath,\n\t\t\tdescription: route.descriptions?.join('\\n\\n'),\n\t\t\ttags: tag ? [tag] : undefined,\n\t\t\tsecurity: route.security,\n\t\t})\n\t}\n\n\tasync #addRouteToOpenApiDoc(path: string, method: string, def: OpenApiSchemaDef, methodObj: OpenAPIV3_1.OperationObject) {\n\t\tif (def.response.response?.length) {\n\t\t\tmethodObj.responses ??= {}\n\t\t\tfor (const resp of def.response.response) {\n\t\t\t\tmethodObj.responses[resp.status] ??= { description: '', content: {} }\n\t\t\t\tconst res = methodObj.responses[resp.status] as OpenAPIV3_1.ResponseObject\n\t\t\t\tres.content![resp.contentType] = { schema: await convert(this.#visit(resp.schema)) }\n\t\t\t}\n\t\t}\n\n\t\tif (def.response.responseHeaders?.length) {\n\t\t\tmethodObj.responses ??= {}\n\t\t\tfor (const resp of def.response.responseHeaders) {\n\t\t\t\tmethodObj.responses[resp.status] ??= { description: '', content: {} }\n\t\t\t\tmethodObj.responses[resp.status] as OpenAPIV3_1.ResponseObject\n\t\t\t\tconst res = methodObj.responses[resp.status] as OpenAPIV3_1.ResponseObject\n\t\t\t\tres.headers = { schema: (await convert(this.#visit(resp.schema))) as any }\n\t\t\t}\n\t\t}\n\n\t\tif (def.request.body)\n\t\t\tmethodObj.requestBody = {\n\t\t\t\trequired: true,\n\t\t\t\tcontent: {\n\t\t\t\t\t'application/json': { schema: await convert(this.#visit(def.request.body)) },\n\t\t\t\t},\n\t\t\t}\n\n\t\tconst parameters: OpenAPIV3_1.ParameterObject[] = []\n\n\t\tconst addParams = async (location: 'query' | 'path' | 'header', schema: JsonSchema | undefined) => {\n\t\t\tif (!schema) return\n\t\t\tconst flat = this.#flattenForParameters(schema)\n\t\t\tfor (const schema of flat) {\n\t\t\t\tif (!schema.properties) continue\n\t\t\t\tfor (const [name, value] of Object.entries(schema.properties))\n\t\t\t\t\tparameters.push({\n\t\t\t\t\t\tname,\n\t\t\t\t\t\tin: location,\n\t\t\t\t\t\tschema: await convert(this.#visit(value)),\n\t\t\t\t\t\trequired: (schema.required || []).includes(name),\n\t\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tawait Promise.all([\n\t\t\taddParams('query', def.request.query),\n\t\t\taddParams('path', def.request.params),\n\t\t\taddParams('header', def.request.headers),\n\t\t])\n\t\tif (parameters.length) methodObj.parameters = parameters\n\n\t\tconst base = this.#baseOpenapiDoc\n\t\tif (!base.paths) base.paths = {}\n\t\tif (!base.paths[path]) base.paths[path] = {}\n\t\tbase.paths[path]![method] = methodObj\n\t}\n\n\trouter() {\n\t\tconst jsonPath = '/openapi.json'\n\t\tconst router = new Router({ path: this.config.config.openapi.docsPath ?? '/', hide: true })\n\t\trouter.get('/')((req) => req.res({ body: this.#html(`.${jsonPath}`), contentType: 'text/html' }))\n\t\trouter.get(jsonPath)((req) => req.res({ body: this.#baseOpenapiDoc }))\n\t\treturn router\n\t}\n\n\t#flattenForParameters(node: JsonSchema): JsonSchema[] {\n\t\tconst { allOf, oneOf, anyOf, ...schema } = node\n\t\tif (allOf) return allOf.flatMap((n) => this.#flattenForParameters(n))\n\t\treturn [schema]\n\t}\n\n\t#visit(node: JsonSchema) {\n\t\tif (!node || typeof node !== 'object') return node\n\t\tif (typeof node.$refId === 'string') {\n\t\t\tconst { $refId: id, ...rest } = node\n\t\t\tconst res = this.#visit(rest)\n\t\t\tif (this.#baseOpenapiDoc.components?.schemas) {\n\t\t\t\tthis.#baseOpenapiDoc.components.schemas[id] = res\n\t\t\t\treturn { $ref: `#/components/schemas/${id}` }\n\t\t\t} else return res\n\t\t}\n\n\t\tif (Array.isArray(node)) return node.map((n) => this.#visit(n)) as any\n\t\treturn Object.fromEntries(Object.entries(node).map(([key, value]) => [key, this.#visit(value as any)]))\n\t}\n\n\t#buildTag(groups: NonNullable<Route<any>['groups']>) {\n\t\tif (!groups.length) return undefined\n\t\tconst parsed = groups.map((g) => (typeof g === 'string' ? { name: g } : g))\n\t\tconst name = parsed.map((g) => g.name).join(' > ')\n\t\tconst displayName = parsed.at(-1)?.name ?? ''\n\t\tconst description = parsed\n\t\t\t.map((g) => g.description?.trim() ?? '')\n\t\t\t.filter(Boolean)\n\t\t\t.join('\\n\\n\\n\\n')\n\n\t\tif (!this.#registeredTags[name]) {\n\t\t\tthis.#registeredTags[name] = true\n\t\t\tthis.#baseOpenapiDoc.tags!.push({ name, 'x-displayName': displayName, description })\n\n\t\t\tconst tagGroups = parsed.slice(0, -1)\n\t\t\tconst groupName = tagGroups.map((g) => g.name).join(' > ') || 'default'\n\t\t\tif (!this.#registeredTagGroups[groupName]) {\n\t\t\t\tconst group = { name: groupName, tags: [] }\n\t\t\t\tthis.#baseOpenapiDoc['x-tagGroups'].push(group)\n\t\t\t\tthis.#registeredTagGroups[groupName] = group\n\t\t\t}\n\t\t\tthis.#registeredTagGroups[groupName].tags = [...new Set([...this.#registeredTagGroups[groupName].tags, name])]\n\t\t}\n\n\t\treturn name\n\t}\n\n\t#html(jsonPath: string) {\n\t\tconst title = capitalize(`${this.config.app.name} ${this.config.app.id}`)\n\t\treturn `\n<!doctype html>\n<html>\n <head>\n <title>${title}</title>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n\t<style>\n .darklight-reference {\n display: none;\n }\n </style>\n </head>\n <body>\n <script id=\"api-reference\" data-url=\"${jsonPath}\"></script>\n <script>\n const configuration = { theme: 'purple' };\n document.getElementById('api-reference').dataset.configuration = JSON.stringify(configuration);\n </script>\n <script src=\"https://cdn.jsdelivr.net/npm/@scalar/api-reference@1.28.33\"></script>\n </body>\n</html>\n`\n\t}\n}\n","import { v } from 'valleyed'\n\nimport { Methods, RouteDefHandler, RouterConfig, Route, MethodsEnum, RouteConfig, RouteDef, MergeRouteDefs } from './types'\n\nfunction mergeSchemas(...schemas: RouteDef[]) {\n\ttype Keys = Record<keyof RouteDef, string>\n\tconst k: Keys = {\n\t\tparams: '',\n\t\theaders: '',\n\t\tquery: '',\n\t\tbody: '',\n\t\tresponse: '',\n\t\tresponseHeaders: '',\n\t\tdefaultStatusCode: '',\n\t\tdefaultContentType: '',\n\t\tcontext: '',\n\t}\n\tfunction merge<T extends RouteDef[keyof Keys]>(acc: T | null, cur: T) {\n\t\tif (!acc) return cur\n\t\tif (!cur) return acc\n\t\tif (typeof acc === 'number') return cur\n\t\tif (typeof acc === 'string') return cur\n\t\tif (typeof acc === 'function') return cur\n\t\treturn v.merge(acc, cur as any)\n\t}\n\treturn Object.fromEntries(\n\t\tObject.keys(k).map((key) => [\n\t\t\tkey,\n\t\t\tschemas.map((s) => s[key] as RouteDef[keyof Keys]).reduce<RouteDef[keyof Keys] | null>(merge, null),\n\t\t]),\n\t) as RouteDef\n}\n\nconst groupRoutes = <T extends RouteDef, R extends RouteDef>(config: RouterConfig<T>, routes: Route<R>[]) =>\n\troutes.map((route) => ({\n\t\t...config,\n\t\t...route,\n\t\tpath: `${config.path}/${route.path}`,\n\t\tgroups: [...(config.groups ?? []), ...(route.groups ?? [])],\n\t\tmiddlewares: [...(config.middlewares ?? []), ...(route.middlewares ?? [])],\n\t\tschema: mergeSchemas(config.schema ?? {}, route.schema ?? {}),\n\t\tsecurity: [...(config.security ?? []), ...(route.security ?? [])],\n\t})) as Route<MergeRouteDefs<T, R>>[]\n\nexport class Router<T extends RouteDef> {\n\t#config: RouterConfig<T> = { path: '' }\n\t#routes: Route<any>[] = []\n\t#children: Router<any>[] = []\n\n\tconstructor(config: RouterConfig<T> = { path: '' }) {\n\t\tthis.#config = config\n\t}\n\n\t#wrap(method: MethodsEnum) {\n\t\treturn <R extends RouteDef>(path: string, config: RouteConfig<R> = {}) =>\n\t\t\t(handler: RouteDefHandler<MergeRouteDefs<T, R>>) => {\n\t\t\t\tconst route = groupRoutes(this.#config, [{ ...config, path, method, handler: handler as any }])[0]\n\t\t\t\tthis.#routes.push(route)\n\t\t\t\treturn route\n\t\t\t}\n\t}\n\n\thead = this.#wrap(Methods.head)\n\tget = this.#wrap(Methods.get)\n\tpost = this.#wrap(Methods.post)\n\tput = this.#wrap(Methods.put)\n\tpatch = this.#wrap(Methods.patch)\n\tdelete = this.#wrap(Methods.delete)\n\toptions = this.#wrap(Methods.options)\n\n\tnest(...routers: Router<any>[]) {\n\t\trouters.forEach((router) => this.#children.push(router))\n\t}\n\n\tget routes() {\n\t\treturn [...this.#routes].concat(this.#children.flatMap((child) => groupRoutes(this.#config, child.routes)))\n\t}\n}\n","import axios from 'axios'\nimport jwt from 'jsonwebtoken'\nimport jwksClient from 'jwks-rsa'\n\nimport { EquippedError } from '../errors'\n\nexport const signinWithGoogle = async (idToken: string) => {\n\tconst authUrl = `https://oauth2.googleapis.com/tokeninfo?id_token=${idToken}`\n\tconst { data } = await axios.get(authUrl).catch((err) => {\n\t\tthrow new EquippedError('Failed to sign in with google', { idToken }, err)\n\t})\n\tdata.first_name = data.given_name\n\tdata.last_name = data.family_name\n\treturn data as {\n\t\temail: string\n\t\temail_verified: 'true' | 'false'\n\t\tfirst_name: string\n\t\tlast_name: string\n\t\tpicture: string\n\t\tsub: string\n\t} & Record<string, any>\n}\n\nexport const signinWithApple = async (idToken: string) => {\n\ttry {\n\t\tconst APPLE_BASE = 'https://appleid.apple.com'\n\t\tconst json = jwt.decode(idToken, { complete: true })\n\t\tif (!json?.header) throw new Error('')\n\t\tconst { kid, alg } = json.header\n\t\tconst publicKey = await jwksClient({ jwksUri: `${APPLE_BASE}/auth/keys`, cache: true })\n\t\t\t.getSigningKey(kid)\n\t\t\t.then((key) => key.getPublicKey())\n\t\t\t.catch(() => null)\n\t\tif (!publicKey) throw new EquippedError('no publicKey', { idToken, publicKey, json })\n\t\tconst data = jwt.verify(idToken, publicKey, { algorithms: [alg as any] }) as Record<string, any>\n\t\tif (!data) throw new EquippedError('no data', { idToken, data })\n\t\tif (data.iss !== APPLE_BASE) throw new EquippedError('iss doesnt match', { idToken, data })\n\t\tif (data.exp * 1000 < Date.now()) throw new EquippedError('expired idToken', { idToken, data })\n\t\t// TODO: Find out how to get profile data from api\n\t\treturn data as {\n\t\t\temail?: string\n\t\t\tsub: string\n\t\t\temail_verified?: 'true' | 'false'\n\t\t\tis_private_email?: 'true' | 'false'\n\t\t} & Record<string, any>\n\t} catch (err) {\n\t\tthrow new EquippedError('Failed to sign in with apple', { idToken }, err)\n\t}\n}\n\nexport const signinWithFacebook = async (accessToken: string, fields = [] as string[]) => {\n\tfields = [...new Set([...fields, 'name', 'picture', 'email'])]\n\tconst { data } = await axios\n\t\t.request({\n\t\t\tmethod: 'get',\n\t\t\turl: 'https://graph.facebook.com/v15.0/me',\n\t\t\tparams: {\n\t\t\t\tfields: fields.join(','),\n\t\t\t\taccess_token: accessToken,\n\t\t\t},\n\t\t})\n\t\t.catch((err) => {\n\t\t\tthrow new EquippedError('Failed to sign in with facebook', { accessToken, fields }, err)\n\t\t})\n\tconst isValidData = fields.every((key) => key in data)\n\tif (!isValidData) throw new Error('Incomplete scope for access token')\n\tdata.email_verified = 'true'\n\treturn data as {\n\t\tid: string\n\t\temail: string\n\t\temail_verified: 'true' | 'false'\n\t\tname: string\n\t\tpicture: {\n\t\t\tdata: { height: number; is_silhouette: boolean; url: string; width: number }\n\t\t}\n\t} & Record<string, any>\n}\n","import * as bcrypt from 'bcryptjs'\n\nimport { Instance } from '../instance'\n\nexport const hash = async (password: string) => {\n\tpassword = password.trim()\n\tif (!password) return ''\n\treturn await bcrypt.hash(password, Instance.get().settings.utils.hashSaltRounds)\n}\n\nexport const compare = async (plainPassword: string, hashed: string) => {\n\tplainPassword = plainPassword.trim()\n\tif (!plainPassword && plainPassword === hashed) return true\n\treturn await bcrypt.compare(plainPassword, hashed)\n}\n","export const parseJSONValue = (data: any) => {\n\ttry {\n\t\tif (data?.constructor?.name !== 'String') return data\n\t\treturn JSON.parse(data)\n\t} catch {\n\t\treturn data\n\t}\n}\n\nexport function parseJSONObject<T extends object>(data: T) {\n\treturn Object.fromEntries(Object.entries(data).map(([key, value]) => [key, parseJSONValue(value)])) as T\n}\n","import { parseBuffer } from 'music-metadata'\n\nexport const getMediaDuration = async (buffer: Buffer) => {\n\ttry {\n\t\tconst meta = await parseBuffer(buffer)\n\t\treturn meta.format.duration ?? 0\n\t} catch {\n\t\treturn 0\n\t}\n}\n","import { EquippedError } from '../errors'\n\nexport const sleep = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms))\n\nexport const retry = async <T>(cb: () => Promise<{ done: true; value: T } | { done: false }>, tries: number, waitTimeInMs: number) => {\n\tif (tries <= 0) throw new EquippedError('out of tries', { tries, waitTimeInMs })\n\tconst result = await cb()\n\tif (result.done === true) return result.value\n\tawait sleep(waitTimeInMs)\n\treturn await retry(cb, tries - 1, waitTimeInMs)\n}\n","import crypto from 'crypto'\n\nexport function string(length = 20) {\n\treturn crypto.randomBytes(length).toString('hex').slice(0, length)\n}\n\nexport function number(min = 0, max = 2 ** 48 - 1) {\n\treturn crypto.randomInt(min, max)\n}\n","import type { Readable } from 'stream'\n\nimport { DistributiveOmit, IsInTypeList } from 'valleyed'\n\nimport type { RequestError } from '../errors'\nimport type { DefaultHeaders, IncomingFile, MethodsEnum, RouteDef, RouteDefToReqRes } from './types'\nimport type { AuthUser, RefreshUser } from '../types'\nimport { parseJSONObject } from '../utilities'\n\ntype HeaderKeys = 'Authorization' | 'RefreshToken' | 'ApiKey' | 'Referer' | 'ContentType' | 'UserAgent'\ntype ReqUser<T> = { error?: RequestError; value?: T }\ntype FallbackHeadersType = Record<string, string | string[] | undefined>\n\nexport class Request<Def extends RouteDefToReqRes<any>> {\n\treadonly ip: string | undefined\n\treadonly method: MethodsEnum\n\treadonly path: string\n\tbody: Def['body']\n\tparams: Def['params']\n\tquery: Def['query']\n\theaders: Record<HeaderKeys, string | undefined> & Def['requestHeaders'] & FallbackHeadersType\n\tcontext: Def['context']\n\treadonly cookies: Record<string, any>\n\tusers: {\n\t\taccess: ReqUser<AuthUser>\n\t\trefresh: ReqUser<RefreshUser>\n\t\tapiKey: ReqUser<AuthUser>\n\t} = {\n\t\taccess: {},\n\t\trefresh: {},\n\t\tapiKey: {},\n\t}\n\tauthUser?: AuthUser\n\n\tconstructor({\n\t\tip,\n\t\tbody,\n\t\tcookies,\n\t\tparams,\n\t\tquery,\n\t\tmethod,\n\t\tpath,\n\t\tcontext,\n\t\theaders,\n\t\tfiles,\n\t}: {\n\t\tip: string | undefined\n\t\tbody: Def['body']\n\t\tparams: Def['params']\n\t\tquery: Def['query']\n\t\tcookies: Record<string, any>\n\t\theaders: Record<HeaderKeys, string | undefined> & Def['requestHeaders'] & FallbackHeadersType\n\t\tfiles: Record<string, IncomingFile[]>\n\t\tmethod: MethodsEnum\n\t\tpath: string\n\t\tcontext: Def['context']\n\t}) {\n\t\tthis.ip = ip\n\t\tthis.method = method\n\t\tthis.path = path\n\t\tthis.params = params\n\t\tthis.cookies = cookies\n\t\tthis.headers = headers\n\t\tthis.query = parseJSONObject(query)\n\t\tthis.body = <any>Object.assign(parseJSONObject(body), files)\n\t\tthis.context = context\n\t}\n\n\tpipe(stream: Readable, opts: { headers?: Def['responseHeaders']; status?: Def['statusCode'] } = {}) {\n\t\treturn new Response<Omit<Def, 'response'> & { response: Readable }>(<any>{ ...opts, piped: true, body: stream })\n\t}\n\n\tres(params: DistributiveOmit<RequestParams<Def>, 'piped'>) {\n\t\treturn new Response<Def>(<any>{ ...params, piped: false })\n\t}\n\n\terror<\n\t\tT extends Omit<Def, 'response' | 'statusCode' | 'responseHeaders' | 'contentType'> & {\n\t\t\tresponse: RequestError['serializedErrors']\n\t\t\tstatusCode: RequestError['statusCode']\n\t\t\tresponseHeaders: DefaultHeaders\n\t\t\tcontentType: 'application/json'\n\t\t},\n\t>(params: DistributiveOmit<RequestParams<T>, 'piped'>) {\n\t\treturn new Response<T>(<any>{ ...params, piped: false })\n\t}\n}\n\ntype RequestParams<Def extends RouteDefToReqRes<any>, T = Def['response']> = { body: T; piped?: boolean } & (IsInTypeList<\n\tDef['statusCode'],\n\t[NonNullable<RouteDef['defaultStatusCode']>, 200]\n> extends true\n\t? { status?: Def['statusCode'] }\n\t: { status: Def['statusCode'] }) &\n\t(IsInTypeList<Def['contentType'], [NonNullable<RouteDef['defaultContentType']>, 'application/json']> extends true\n\t\t? { contentType?: Def['contentType'] }\n\t\t: { contentType: Def['contentType'] }) &\n\t(IsInTypeList<Def['responseHeaders'], [DefaultHeaders]> extends true\n\t\t? { headers?: Def['responseHeaders'] }\n\t\t: { headers: Def['responseHeaders'] })\n\nexport class Response<Def extends RouteDefToReqRes<any>> {\n\tbody: Def['response'] | undefined\n\theaders: Def['responseHeaders']\n\treadonly status: Def['statusCode']\n\treadonly contentType: Def['contentType']\n\treadonly piped: boolean\n\n\tconstructor({ body, status = <any>200, headers = <any>{}, piped = false, contentType = <any>'application/json' }: RequestParams<Def>) {\n\t\tthis.body = body\n\t\tthis.status = status\n\t\tthis.contentType = contentType\n\t\tthis.headers = headers\n\t\tthis.piped = piped\n\n\t\tif (!this.piped) {\n\t\t\t// @ts-expect-error indexing on generic\n\t\t\tthis.headers['Content-Type'] = contentType\n\t\t}\n\t}\n}\n","import { match as Match } from 'path-to-regexp'\nimport type { Server } from 'socket.io'\n\nimport { Entity } from '../dbs/base/core'\nimport { EventBus } from '../events'\nimport { Instance } from '../instance'\nimport { StatusCodes, StatusCodesEnum } from './types'\nimport type { AuthUser } from '../types'\n\nenum EmitTypes {\n\tcreated = 'created',\n\tupdated = 'updated',\n\tdeleted = 'deleted',\n}\n\nconst EmitterEvent = '__listener_emitter'\ntype EmitData = { channel: string; type: EmitTypes; after: any; before: any }\ntype LeaveRoomParams = { channel: string }\ntype JoinRoomParams = { channel: string; token?: string; query: Record<string, any> }\ntype Callback = (params: { code: StatusCodesEnum; message: string; channel: string }) => void\nexport type OnJoinFn = (\n\tdata: { channel: string; user: AuthUser | null },\n\tparams: Record<string, any>,\n\tquery: Record<string, any>,\n) => Promise<string | null>\nexport type SocketCallbacks = {\n\tonConnect: (userId: string, socketId: string) => Promise<void>\n\tonDisconnect: (userId: string, socketId: string) => Promise<void>\n}\n\nconst defaultTo = '*'\n\nexport class SocketEmitter {\n\treadonly socketInstance: Server\n\t#connectionCallbacks: SocketCallbacks = { onConnect: async () => {}, onDisconnect: async () => {} }\n\t#routes = {} as Record<string, OnJoinFn>\n\t#publish: (data: EmitData) => Promise<void> = async () => {}\n\n\tconstructor(socket: Server, eventBus?: EventBus) {\n\t\tthis.socketInstance = socket\n\t\tthis.#setupSocketConnection()\n\t\tInstance.on(\n\t\t\t'setup',\n\t\t\t() => {\n\t\t\t\tthis.#publish = eventBus\n\t\t\t\t\t? (eventBus.createPublisher(EmitterEvent as never) as unknown as (data: EmitData) => Promise<void>)\n\t\t\t\t\t: async (data: EmitData) => {\n\t\t\t\t\t\t\tsocket.to(data.channel).emit(data.channel, data)\n\t\t\t\t\t\t}\n\t\t\t\teventBus?.createSubscriber(\n\t\t\t\t\tEmitterEvent as never,\n\t\t\t\t\tasync (data: EmitData) => {\n\t\t\t\t\t\tsocket.to(data.channel).emit(data.channel, data)\n\t\t\t\t\t},\n\t\t\t\t\t{ fanout: true },\n\t\t\t\t)\n\t\t\t},\n\t\t\t1,\n\t\t)\n\t}\n\n\tasync created<T extends Entity>(channels: string[], data: T, to: string | string[] | null) {\n\t\tawait this.#emit(channels, EmitTypes.created, { after: data.toJSON(), before: null }, to)\n\t}\n\n\tasync updated<T extends Entity>(channels: string[], { after, before }: { after: T; before: T }, to: string | string[] | null) {\n\t\tawait this.#emit(channels, EmitTypes.updated, { after: after.toJSON(), before: before.toJSON() }, to)\n\t}\n\n\tasync deleted<T extends Entity>(channels: string[], data: T, to: string | string[] | null) {\n\t\tawait this.#emit(channels, EmitTypes.deleted, { before: data.toJSON(), after: null }, to)\n\t}\n\n\tasync #emit(channels: string[], type: EmitTypes, { before, after }: { after: any; before: any }, to: string | string[] | null) {\n\t\tconst toArray = Array.isArray(to) ? to : [to ?? defaultTo]\n\t\tconst channelMap = channels.flatMap((c) => toArray.map((to) => `${to}:${c}`))\n\t\tawait Promise.all(channelMap.map(async (channel) => this.#publish({ channel, type, before, after })))\n\t}\n\n\tset connectionCallbacks(callbacks: SocketCallbacks) {\n\t\tthis.#connectionCallbacks = callbacks\n\t\tthis.#setupSocketConnection()\n\t}\n\n\tregister(channel: string, onJoin: OnJoinFn) {\n\t\tthis.#routes[channel] = onJoin\n\t\tthis.#routes[channel + '/:id'] = onJoin\n\t\treturn this\n\t}\n\n\t#getConfig(channel: string) {\n\t\tconst matcher = (key: string) => Match(key)(channel)\n\t\tconst matchedChannel = Object.keys(this.#routes).find(matcher) ?? null\n\t\tif (!matchedChannel) return null\n\t\tconst match = matcher(matchedChannel)\n\t\tif (!match) return null\n\t\treturn {\n\t\t\tconfig: this.#routes[matchedChannel],\n\t\t\tparams: match.params,\n\t\t}\n\t}\n\n\t#setupSocketConnection = () => {\n\t\tthis.socketInstance.removeAllListeners('connection')\n\t\tthis.socketInstance.on('connection', async (socket) => {\n\t\t\tconst socketId = socket.id\n\t\t\tlet user = null as AuthUser | null\n\t\t\tconst tokensUtil = Instance.get().settings.server?.requestsAuth.tokens\n\t\t\tif (socket.handshake.auth.authorization && tokensUtil)\n\t\t\t\tuser = await tokensUtil.verifyAccessToken(socket.handshake.auth.authorization ?? '').catch(() => null)\n\t\t\tsocket.on('leave', async (data: LeaveRoomParams, callback: Callback) => {\n\t\t\t\tif (!data.channel)\n\t\t\t\t\treturn (\n\t\t\t\t\t\ttypeof callback === 'function' &&\n\t\t\t\t\t\tcallback({\n\t\t\t\t\t\t\tcode: StatusCodes.ValidationError,\n\t\t\t\t\t\t\tmessage: 'channel is required',\n\t\t\t\t\t\t\tchannel: '',\n\t\t\t\t\t\t})\n\t\t\t\t\t)\n\t\t\t\tsocket.leave(data.channel)\n\t\t\t\treturn (\n\t\t\t\t\ttypeof callback === 'function' &&\n\t\t\t\t\tcallback({\n\t\t\t\t\t\tcode: StatusCodes.Ok,\n\t\t\t\t\t\tmessage: '',\n\t\t\t\t\t\tchannel: data.channel,\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t\t})\n\t\t\tsocket.on('join', async (data: JoinRoomParams, callback: Callback) => {\n\t\t\t\tif (!data.channel)\n\t\t\t\t\treturn (\n\t\t\t\t\t\ttypeof callback === 'function' &&\n\t\t\t\t\t\tcallback({\n\t\t\t\t\t\t\tcode: StatusCodes.ValidationError,\n\t\t\t\t\t\t\tmessage: 'channel is required',\n\t\t\t\t\t\t\tchannel: '',\n\t\t\t\t\t\t})\n\t\t\t\t\t)\n\t\t\t\tconst channel = data.channel\n\t\t\t\tconst route = this.#getConfig(channel) ?? null\n\t\t\t\tif (!route)\n\t\t\t\t\treturn (\n\t\t\t\t\t\ttypeof callback === 'function' &&\n\t\t\t\t\t\tcallback({\n\t\t\t\t\t\t\tcode: StatusCodes.BadRequest,\n\t\t\t\t\t\t\tmessage: 'unknown channel',\n\t\t\t\t\t\t\tchannel,\n\t\t\t\t\t\t})\n\t\t\t\t\t)\n\t\t\t\tconst to = await route.config({ channel, user }, route.params, data.query ?? {})\n\t\t\t\tconst newChannel = `${to ?? defaultTo}:${channel}`\n\t\t\t\tsocket.join(newChannel)\n\t\t\t\treturn (\n\t\t\t\t\ttypeof callback === 'function' &&\n\t\t\t\t\tcallback({\n\t\t\t\t\t\tcode: StatusCodes.Ok,\n\t\t\t\t\t\tmessage: '',\n\t\t\t\t\t\tchannel: newChannel,\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t\t})\n\t\t\tif (user) await this.#connectionCallbacks.onConnect(user.id, socketId)\n\t\t\tsocket.on('disconnect', async () => {\n\t\t\t\tif (user) await this.#connectionCallbacks.onDisconnect(user.id, socketId)\n\t\t\t})\n\t\t})\n\t}\n}\n","import http from 'http'\n\nimport cookie from 'cookie-parser'\nimport cors from 'cors'\nimport express from 'express'\nimport fileUpload from 'express-fileupload'\nimport { rateLimit } from 'express-rate-limit'\n// import slowDown from 'express-slow-down'\nimport helmet from 'helmet'\nimport { pinoHttp } from 'pino-http'\n\nimport { Instance } from '../../instance'\nimport { getMediaDuration } from '../../utilities'\nimport { ServerConfig } from '../pipes'\nimport { Request } from '../requests'\nimport { IncomingFile, StatusCodes } from '../types'\nimport { Server } from './base'\n\nexport class ExpressServer extends Server<express.Request, express.Response> {\n\t#expressApp: express.Express\n\n\tconstructor(config: ServerConfig) {\n\t\tconst app = express()\n\t\tsuper(http.createServer(app), config, {\n\t\t\tparseRequest: async (req) => {\n\t\t\t\tconst allHeaders = Object.fromEntries(Object.entries(req.headers).map(([key, val]) => [key, val ?? null]))\n\t\t\t\tconst headers = {\n\t\t\t\t\t...allHeaders,\n\t\t\t\t\tAuthorization: req.get('authorization'),\n\t\t\t\t\tRefreshToken: req.get('x-refresh-token'),\n\t\t\t\t\tApiKey: req.get('x-api-key'),\n\t\t\t\t\tContentType: req.get('content-type'),\n\t\t\t\t\tReferer: req.get('referer'),\n\t\t\t\t\tUserAgent: req.get('user-agent'),\n\t\t\t\t}\n\t\t\t\tconst files = Object.fromEntries(\n\t\t\t\t\tawait Promise.all(\n\t\t\t\t\t\tObject.entries(req.files ?? {}).map(async ([key, file]) => {\n\t\t\t\t\t\t\tconst uploads = Array.isArray(file) ? file : [file]\n\t\t\t\t\t\t\tconst fileArray: IncomingFile[] = await Promise.all(\n\t\t\t\t\t\t\t\tuploads.map(async (f) => ({\n\t\t\t\t\t\t\t\t\tname: f.name,\n\t\t\t\t\t\t\t\t\ttype: f.mimetype,\n\t\t\t\t\t\t\t\t\tsize: f.size,\n\t\t\t\t\t\t\t\t\tisTruncated: f.truncated,\n\t\t\t\t\t\t\t\t\tdata: f.data,\n\t\t\t\t\t\t\t\t\tduration: await getMediaDuration(f.data),\n\t\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\treturn <const>[key, fileArray]\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t)\n\n\t\t\t\treturn new Request<any>({\n\t\t\t\t\tip: req.ip,\n\t\t\t\t\tbody: req.body ?? {},\n\t\t\t\t\tcookies: req.cookies ?? {},\n\t\t\t\t\tparams: req.params ?? {},\n\t\t\t\t\tquery: req.query ?? {},\n\t\t\t\t\tmethod: <any>req.method,\n\t\t\t\t\tpath: req.path,\n\t\t\t\t\theaders,\n\t\t\t\t\tfiles,\n\t\t\t\t\tcontext: {},\n\t\t\t\t})\n\t\t\t},\n\t\t\thandleResponse: async (res, response) => {\n\t\t\t\tif (!response.piped) {\n\t\t\t\t\tObject.entries(<object>response.headers).forEach(([key, value]) => res.header(key, value))\n\t\t\t\t\tconst type = response.body === null || response.body === undefined ? 'json' : 'send'\n\t\t\t\t\tres.status(response.status)[type](response.body).end()\n\t\t\t\t} else {\n\t\t\t\t\tresponse.body.pipe(res)\n\t\t\t\t}\n\t\t\t},\n\t\t\tregisterRoute: (method, path, cb) => {\n\t\t\t\tthis.#expressApp[method]?.(path, cb)\n\t\t\t},\n\t\t\tregisterErrorHandler: (cb) => {\n\t\t\t\tthis.#expressApp.use(async (err, req, res, _next) => cb(err, req, res))\n\t\t\t},\n\t\t\tregisterNotFoundHandler: (cb) => {\n\t\t\t\tthis.#expressApp.use(cb)\n\t\t\t},\n\t\t\tstart: async (port) =>\n\t\t\t\tnew Promise((resolve: (s: boolean) => void, reject: (e: Error) => void) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst app = this.server.listen({ host: '0.0.0.0', port }, async () => resolve(true))\n\t\t\t\t\t\tInstance.on('close', app.close, 1)\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treject(<Error>err)\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t})\n\t\tthis.#expressApp = app\n\n\t\tapp.disable('x-powered-by')\n\t\tif (config.config.requests.log) app.use(pinoHttp({ logger: config.log }))\n\t\tapp.use(express.json())\n\t\tapp.use(express.text())\n\t\tapp.use(cookie())\n\t\tapp.use(\n\t\t\thelmet({\n\t\t\t\tcrossOriginResourcePolicy: { policy: 'cross-origin' },\n\t\t\t\tcontentSecurityPolicy: false,\n\t\t\t}),\n\t\t)\n\t\tapp.use(cors(this.cors))\n\t\tapp.use(express.urlencoded({ extended: false }))\n\t\tif (config.config.publicPath) app.use(express.static(config.config.publicPath))\n\t\tapp.use(\n\t\t\tfileUpload({\n\t\t\t\tlimits: { fileSize: config.config.requests.maxFileUploadSizeInMb * 1024 * 1024 },\n\t\t\t\tuseTempFiles: false,\n\t\t\t}),\n\t\t)\n\t\tif (config.config.requests.rateLimit.enabled)\n\t\t\tapp.use(\n\t\t\t\trateLimit({\n\t\t\t\t\twindowMs: config.config.requests.rateLimit.periodInMs,\n\t\t\t\t\tlimit: config.config.requests.rateLimit.limit,\n\t\t\t\t\thandler: (_: express.Request, res: express.Response) =>\n\t\t\t\t\t\tres.status(StatusCodes.TooManyRequests).json([{ message: 'Too Many Requests' }]),\n\t\t\t\t}),\n\t\t\t)\n\t\t/* if (this.settings.slowdown.enabled) app.use(slowDown({\n\t\t\twindowMs: this.settings.slowdown.periodInMs,\n\t\t\tdelayAfter: this.settings.slowdown.delayAfter,\n\t\t\tdelayMs: this.settings.slowdown.delayInMs\n\t\t})) */\n\t}\n}\n","import fastifyCookie from '@fastify/cookie'\nimport fastifyCors from '@fastify/cors'\nimport fastifyFormBody from '@fastify/formbody'\nimport fastifyHelmet from '@fastify/helmet'\nimport fastifyMultipart from '@fastify/multipart'\nimport fastifyRateLimit from '@fastify/rate-limit'\nimport fastifyStatic from '@fastify/static'\nimport type { FastifyReply, FastifyRequest } from 'fastify'\nimport Fastify from 'fastify'\n// import fastifySlowDown from 'fastify-slow-down'\nimport qs from 'qs'\n\nimport { ValidationError } from '../../errors'\nimport { Instance } from '../../instance'\nimport { getMediaDuration } from '../../utilities'\nimport { ServerConfig } from '../pipes'\nimport { Request } from '../requests'\nimport { IncomingFile, StatusCodes } from '../types'\nimport { Server } from './base'\n\nexport class FastifyServer extends Server<FastifyRequest, FastifyReply> {\n\tconstructor(config: ServerConfig) {\n\t\tconst app = Fastify({\n\t\t\tignoreTrailingSlash: true,\n\t\t\tcaseSensitive: false,\n\t\t\tdisableRequestLogging: !config.config.requests.log,\n\t\t\tloggerInstance: config.config.requests.log ? config.log : undefined,\n\t\t\tajv: { customOptions: { coerceTypes: false } },\n\t\t\tschemaErrorFormatter: (errors, data) =>\n\t\t\t\tnew ValidationError(\n\t\t\t\t\terrors.map((error) => ({\n\t\t\t\t\t\tmessages: [error.message ?? ''],\n\t\t\t\t\t\tfield: `${data}${error.instancePath}`.replaceAll('/', '.'),\n\t\t\t\t\t})),\n\t\t\t\t),\n\t\t})\n\t\tsuper(app.server, config, {\n\t\t\tparseRequest: async (req) => {\n\t\t\t\tconst allHeaders = Object.fromEntries(Object.entries(req.headers).map(([key, val]) => [key, val ?? null]))\n\t\t\t\tconst headers = {\n\t\t\t\t\t...allHeaders,\n\t\t\t\t\tAuthorization: req.headers['authorization']?.toString(),\n\t\t\t\t\tRefreshToken: req.headers['x-refresh-token']?.toString(),\n\t\t\t\t\tApiKey: req.headers['x-api-key']?.toString(),\n\t\t\t\t\tContentType: req.headers['content-type']?.toString(),\n\t\t\t\t\tReferer: req.headers['referer']?.toString(),\n\t\t\t\t\tUserAgent: req.headers['user-agent']?.toString(),\n\t\t\t\t}\n\t\t\t\tconst { body, files } = excludeBufferKeys(req.body ?? {})\n\n\t\t\t\treturn new Request({\n\t\t\t\t\tip: req.ip,\n\t\t\t\t\tbody,\n\t\t\t\t\tcookies: req.cookies ?? {},\n\t\t\t\t\tparams: req.params ?? <any>{},\n\t\t\t\t\tquery: req.query ?? {},\n\t\t\t\t\tmethod: <any>req.method,\n\t\t\t\t\tpath: req.url,\n\t\t\t\t\theaders,\n\t\t\t\t\tfiles,\n\t\t\t\t\tcontext: {},\n\t\t\t\t})\n\t\t\t},\n\t\t\thandleResponse: async (res, response) => {\n\t\t\t\tawait res.status(response.status).headers(response.headers).send(response.body)\n\t\t\t},\n\t\t\tregisterRoute: (method, path, cb) => {\n\t\t\t\tapp.register(async (inst) => {\n\t\t\t\t\tinst.route({ url: path, method, handler: cb })\n\t\t\t\t})\n\t\t\t},\n\t\t\tregisterErrorHandler: (cb) => {\n\t\t\t\tapp.setErrorHandler(cb)\n\t\t\t},\n\t\t\tregisterNotFoundHandler: (cb) => {\n\t\t\t\tapp.setNotFoundHandler(cb)\n\t\t\t},\n\t\t\tstart: async (port) => {\n\t\t\t\tawait app.ready()\n\t\t\t\tawait app.listen({ port, host: '0.0.0.0' })\n\t\t\t\tInstance.on('close', app.close, 1)\n\t\t\t\treturn true\n\t\t\t},\n\t\t})\n\n\t\tapp.decorateRequest('savedReq', null)\n\t\tapp.setValidatorCompiler(() => () => true)\n\t\tapp.setSerializerCompiler(() => (data) => JSON.stringify(data))\n\t\tif (config.config.publicPath) app.register(fastifyStatic, { root: config.config.publicPath })\n\t\tapp.register(fastifyCookie, {})\n\t\tapp.register(fastifyCors, this.cors)\n\t\tapp.register(fastifyFormBody, { parser: (str) => qs.parse(str) })\n\t\tapp.register(fastifyHelmet, { crossOriginResourcePolicy: { policy: 'cross-origin' }, contentSecurityPolicy: false })\n\t\tapp.register(fastifyMultipart, {\n\t\t\tattachFieldsToBody: 'keyValues',\n\t\t\tthrowFileSizeLimit: false,\n\t\t\tlimits: { fileSize: config.config.requests.maxFileUploadSizeInMb * 1024 * 1024 },\n\t\t\tonFile: async (f) => {\n\t\t\t\tconst buffer = await f.toBuffer()\n\t\t\t\tconst parsed: IncomingFile = {\n\t\t\t\t\tname: f.filename,\n\t\t\t\t\ttype: f.mimetype,\n\t\t\t\t\tsize: buffer.byteLength,\n\t\t\t\t\tisTruncated: f.file.truncated,\n\t\t\t\t\tdata: buffer,\n\t\t\t\t\tduration: await getMediaDuration(buffer),\n\t\t\t\t}\n\t\t\t\t// @ts-ignore\n\t\t\t\tf.value = parsed\n\t\t\t},\n\t\t})\n\t\t/* if (this.settings.slowdown.enabled) app.register(fastifySlowDown, {\n\t\t\ttimeWindow: this.settings.slowdown.periodInMs,\n\t\t\tdelayAfter: this.settings.slowdown.delayAfter,\n\t\t\tdelay: this.settings.slowdown.delayInMs\n\t\t}) */\n\t\tif (config.config.requests.rateLimit.enabled)\n\t\t\tapp.register(fastifyRateLimit, {\n\t\t\t\tmax: config.config.requests.rateLimit.limit,\n\t\t\t\ttimeWindow: config.config.requests.rateLimit.periodInMs,\n\t\t\t\terrorResponseBuilder: (_, context) => ({\n\t\t\t\t\tstatusCode: StatusCodes.TooManyRequests,\n\t\t\t\t\tmessage: JSON.stringify([{ message: `Too Many Requests. Retry in ${context.after}` }]),\n\t\t\t\t}),\n\t\t\t})\n\t}\n}\n\nfunction excludeBufferKeys<T>(body: T) {\n\tif (typeof body !== 'object') return { body, files: {} }\n\tconst entries = Object.entries(body ?? {})\n\tconst isFile = (val: any) => (Array.isArray(val) ? isFile(val.at(0)) : Buffer.isBuffer(val?.data))\n\tconst fileEntries = entries.filter(([_, value]) => isFile(value)).map(([key, value]) => [key, Array.isArray(value) ? value : [value]])\n\tconst nonFileEntries = entries.filter(([_, value]) => !isFile(value))\n\treturn {\n\t\tbody: <T>Object.fromEntries(nonFileEntries),\n\t\tfiles: <Record<string, IncomingFile[]>>Object.fromEntries(fileEntries),\n\t}\n}\n","import { NotAuthenticatedError, NotAuthorizedError } from '../../errors'\nimport { Instance } from '../../instance'\nimport { makeMiddleware } from '../types'\n\nexport const requireAuthUser = makeMiddleware(\n\tasync (request) => {\n\t\tconst user = request.users.access.value || request.users.apiKey.value\n\t\tconst error = request.users.access.error || request.users.apiKey.error\n\t\tif (!user && error) throw error\n\t\trequest.authUser = user\n\t\tif (!request.authUser) throw new NotAuthenticatedError()\n\t},\n\t(route) => {\n\t\troute.security ??= []\n\t\troute.security.push({ Authorization: [] }, { ApiKey: [] })\n\t\troute.descriptions ??= []\n\t\troute.descriptions.push('Requires a valid means of authentication.')\n\t},\n)\n\nexport const requireAuthorizationUser = makeMiddleware(\n\tasync (request) => {\n\t\tif (request.users.access.error) throw request.users.access.error\n\t\trequest.authUser = request.users.access.value\n\t\tif (!request.authUser) throw new NotAuthenticatedError()\n\t},\n\t(route) => {\n\t\troute.security ??= []\n\t\troute.security.push({ Authorization: [] })\n\t\troute.descriptions ??= []\n\t\troute.descriptions.push('Requires a valid authorization header.')\n\t},\n)\n\nexport const requireApiKeyUser = makeMiddleware(\n\tasync (request) => {\n\t\tif (request.users.apiKey.error) throw request.users.apiKey.error\n\t\trequest.authUser = request.users.apiKey.value\n\t\tif (!request.authUser) throw new NotAuthenticatedError()\n\t},\n\t(route) => {\n\t\troute.security ??= []\n\t\troute.security.push({ ApiKey: [] })\n\t\troute.descriptions ??= []\n\t\troute.descriptions.push('Requires a valid x-api-key header.')\n\t},\n)\n\nexport const requireRefreshTokenUser = makeMiddleware(\n\tasync (request) => {\n\t\tif (request.users.refresh.error) throw request.users.refresh.error\n\t\tconst refreshToken = request.headers.RefreshToken\n\t\tif (!refreshToken) throw new NotAuthorizedError('x-refresh-token header missing')\n\t\trequest.users.refresh.value = await Instance.get().settings.server?.requestsAuth.tokens?.verifyRefreshToken(refreshToken)\n\t\tif (!request.users.refresh.value) throw new NotAuthorizedError()\n\t},\n\t(route) => {\n\t\troute.security ??= []\n\t\troute.security.push({ RefreshToken: [] })\n\t\troute.descriptions ??= []\n\t\troute.descriptions.push('Requires a valid x-refresh-token header.')\n\t},\n)\n","import { PipeOutput, v } from 'valleyed'\n\nimport { BaseApiKeysUtility, BaseTokensUtility } from './requests-auth'\nimport { EventBus } from '../events'\nimport { Instance } from '../instance'\n\nexport const serverPipe = v.object({\n\ttype: v.in(['fastify', 'express'] as const),\n\tport: v.number(),\n\tpublicPath: v.optional(v.string()),\n\thealthPath: v.optional(v.string()),\n\topenapi: v.defaults(\n\t\tv.object({\n\t\t\tdocsVersion: v.defaults(v.string(), '1.0.0'),\n\t\t\tdocsBaseUrl: v.defaults(v.array(v.string()), ['/']),\n\t\t\tdocsPath: v.defaults(v.string(), '/__docs'),\n\t\t}),\n\t\t{},\n\t),\n\trequests: v.defaults(\n\t\tv.object({\n\t\t\tlog: v.defaults(v.boolean(), true),\n\t\t\tpaginationDefaultLimit: v.defaults(v.number(), 100),\n\t\t\tmaxFileUploadSizeInMb: v.defaults(v.number(), 500),\n\t\t\trateLimit: v.defaults(\n\t\t\t\tv.object({\n\t\t\t\t\tenabled: v.defaults(v.boolean(), false),\n\t\t\t\t\tperiodInMs: v.defaults(v.number(), 60 * 60 * 1000),\n\t\t\t\t\tlimit: v.defaults(v.number(), 5000),\n\t\t\t\t}),\n\t\t\t\t{},\n\t\t\t),\n\t\t\tslowdown: v.defaults(\n\t\t\t\tv.object({\n\t\t\t\t\tenabled: v.defaults(v.boolean(), false),\n\t\t\t\t\tperiodInMs: v.defaults(v.number(), 10 * 60 * 1000),\n\t\t\t\t\tdelayAfter: v.defaults(v.number(), 2000),\n\t\t\t\t\tdelayInMs: v.defaults(v.number(), 500),\n\t\t\t\t}),\n\t\t\t\t{},\n\t\t\t),\n\t\t}),\n\t\t{},\n\t),\n\trequestsAuth: v.defaults(\n\t\tv.object({\n\t\t\ttokens: v.optional(v.instanceOf(BaseTokensUtility)),\n\t\t\tapiKey: v.optional(v.instanceOf(BaseApiKeysUtility)),\n\t\t}),\n\t\t{},\n\t),\n})\n\nexport type ServerConfig = {\n\tconfig: PipeOutput<typeof serverPipe>\n\tapp: { id: string; name: string }\n\tlog: Instance<any, any>['log']\n\teventBus?: EventBus\n}\n","import type { AuthUser } from '../../types'\n\nexport abstract class BaseApiKeysUtility {\n\tabstract verifyApiKey(apiKey: string): Promise<AuthUser>\n}\n","import jwt from 'jsonwebtoken'\n\nimport type { RequestError } from '../../errors'\nimport { AuthorizationExpired, EquippedError, NotAuthenticatedError } from '../../errors'\nimport { Instance } from '../../instance'\nimport type { AuthUser, RefreshUser } from '../../types'\nimport { StatusCodes } from '../types'\n\nexport abstract class BaseTokensUtility {\n\tabstract createAccessToken(payload: AuthUser): Promise<string>\n\tabstract createRefreshToken(payload: RefreshUser): Promise<string>\n\tabstract verifyAccessToken(token: string): Promise<AuthUser>\n\tabstract verifyRefreshToken(token: string): Promise<RefreshUser>\n\tabstract retrieveAccessTokenFor(userId: string): Promise<string | null>\n\tabstract retrieveRefreshTokenFor(userId: string): Promise<string | null>\n\tabstract deleteAccessTokenFor(userId: string): Promise<void>\n\tabstract deleteRefreshTokenFor(userId: string): Promise<void>\n\n\textractAccessTokenValue(headerValue: string) {\n\t\tif (!headerValue.startsWith('Bearer ')) throw new EquippedError(`authorization header must begin with 'Bearer '`, { headerValue })\n\t\treturn headerValue.slice(7)\n\t}\n\n\tasync exchangeTokens(\n\t\ttokens: {\n\t\t\taccessToken: string\n\t\t\trefreshToken: string\n\t\t},\n\t\tgetPayload: (id: string) => Promise<{ access: AuthUser; refresh: RefreshUser }>,\n\t): Promise<{\n\t\taccessToken: string\n\t\trefreshToken: string\n\t}> {\n\t\tconst authUser = await this.verifyAccessToken(tokens.accessToken).catch((err) => {\n\t\t\tconst error = err as RequestError\n\t\t\tif (error.statusCode === StatusCodes.AuthorizationExpired) return null\n\t\t\telse throw err\n\t\t})\n\t\tif (authUser) return tokens\n\n\t\tconst refreshUser = await this.verifyRefreshToken(tokens.refreshToken)\n\t\t// const cachedRefreshToken = await getCachedRefreshToken(refreshUser.id)\n\n\t\t// If no cached value, means someone used your old token for a second time, so current one got deleted from cache\n\t\t// if (!cachedRefreshToken) throw new NotAuthenticatedError()\n\n\t\t// If cached value is not equal, means someone is trying to use an old token for a second time\n\t\t// if (refreshToken !== cachedRefreshToken) {\n\t\t// await deleteCachedAccessToken(refreshUser.id)\n\t\t// await deleteCachedRefreshToken(refreshUser.id)\n\t\t// throw new RefreshTokenMisusedError()\n\t\t// }\n\n\t\tconst payloads = await getPayload(refreshUser.id)\n\t\treturn {\n\t\t\taccessToken: await this.createAccessToken(payloads.access),\n\t\t\trefreshToken: await this.createRefreshToken(payloads.refresh),\n\t\t}\n\t}\n}\n\ntype CacheTokensUtilityOptions = {\n\taccessTokenKey: string\n\trefreshTokenKey: string\n\taccessTokenTTL: number\n\trefreshTokenTTL: number\n\taccessTokenPrefix: string\n\trefreshTokenPrefix: string\n}\n\nexport class CacheTokensUtility extends BaseTokensUtility {\n\t#getAccessTokenKey: (userId: string) => string\n\t#getRefreshTokenKey: (userId: string) => string\n\tprivate options: CacheTokensUtilityOptions\n\tconstructor(options?: Partial<CacheTokensUtilityOptions>) {\n\t\tsuper()\n\t\tthis.options = {\n\t\t\taccessTokenKey: 'accessTokenKey',\n\t\t\trefreshTokenKey: 'refreshTokenKey',\n\t\t\taccessTokenTTL: 60 * 60,\n\t\t\trefreshTokenTTL: 14 * 24 * 60 * 60,\n\t\t\taccessTokenPrefix: 'tokens:access:',\n\t\t\trefreshTokenPrefix: 'tokens:refresh:',\n\t\t\t...options,\n\t\t}\n\t\tthis.#getAccessTokenKey = (userId: string) => `${this.options.accessTokenPrefix}${userId}`\n\t\tthis.#getRefreshTokenKey = (userId: string) => `${this.options.refreshTokenPrefix}${userId}`\n\t}\n\n\tasync createAccessToken(payload: AuthUser) {\n\t\tconst token = jwt.sign(payload, this.options.accessTokenKey, { expiresIn: this.options.accessTokenTTL })\n\t\tawait Instance.get().cache.set(this.#getAccessTokenKey(payload.id), token, this.options.accessTokenTTL)\n\t\treturn token\n\t}\n\n\tasync createRefreshToken(payload: RefreshUser) {\n\t\tconst token = jwt.sign(payload, this.options.refreshTokenKey, { expiresIn: this.options.refreshTokenTTL })\n\t\tawait Instance.get().cache.set(this.#getRefreshTokenKey(payload.id), token, this.options.refreshTokenTTL)\n\t\treturn token\n\t}\n\n\tasync verifyAccessToken(authHeader: string) {\n\t\ttry {\n\t\t\tconst accessToken = this.extractAccessTokenValue(authHeader)\n\t\t\tconst user = jwt.verify(accessToken, this.options.accessTokenKey) as AuthUser\n\t\t\tif (!user) throw new NotAuthenticatedError()\n\t\t\tconst cachedToken = await this.retrieveAccessTokenFor(user.id)\n\t\t\t// Cached access token was deleted, e.g. by user roles being modified, so token needs to be treated as expired\n\t\t\tif (accessToken && accessToken !== cachedToken) throw new AuthorizationExpired()\n\t\t\treturn user\n\t\t} catch (err) {\n\t\t\tif (err instanceof AuthorizationExpired) throw err\n\t\t\tif (err instanceof jwt.TokenExpiredError) throw new AuthorizationExpired(undefined, err)\n\t\t\telse throw new NotAuthenticatedError(undefined, err)\n\t\t}\n\t}\n\n\tasync verifyRefreshToken(token: string) {\n\t\ttry {\n\t\t\tconst user = jwt.verify(token, this.options.refreshTokenKey) as RefreshUser\n\t\t\tif (!user) throw new NotAuthenticatedError()\n\t\t\treturn user\n\t\t} catch (err) {\n\t\t\tthrow new NotAuthenticatedError(undefined, err)\n\t\t}\n\t}\n\n\tasync retrieveAccessTokenFor(userId: string) {\n\t\treturn Instance.get().cache.get(this.#getAccessTokenKey(userId))\n\t}\n\n\tasync retrieveRefreshTokenFor(userId: string) {\n\t\treturn Instance.get().cache.get(this.#getRefreshTokenKey(userId))\n\t}\n\n\tasync deleteAccessTokenFor(userId: string) {\n\t\tawait Instance.get().cache.delete(this.#getAccessTokenKey(userId))\n\t}\n\n\tasync deleteRefreshTokenFor(userId: string) {\n\t\tawait Instance.get().cache.delete(this.#getRefreshTokenKey(userId))\n\t}\n}\n","import { StatusCodes } from '../../server'\nimport { RequestError } from '../requestError'\n\nexport class AuthorizationExpired extends RequestError {\n\tstatusCode = StatusCodes.AuthorizationExpired\n\n\tconstructor(message = 'Access token expired', cause?: unknown) {\n\t\tsuper(message, [{ message }], cause)\n\t}\n}\n","import { StatusCodes } from '../../server'\nimport { RequestError } from '../requestError'\n\nexport class BadRequestError extends RequestError {\n\tstatusCode = StatusCodes.BadRequest\n\n\tconstructor(message: string, cause?: unknown) {\n\t\tsuper(message, [{ message }], cause)\n\t}\n}\n","import { StatusCodes } from '../../server'\nimport { RequestError } from '../requestError'\n\nexport class NotAuthenticatedError extends RequestError {\n\tstatusCode = StatusCodes.NotAuthenticated\n\n\tconstructor(message = 'Not authenticated', cause?: unknown) {\n\t\tsuper(message, [{ message }], cause)\n\t}\n}\n","import { StatusCodes } from '../../server'\nimport { RequestError } from '../requestError'\n\nexport class NotAuthorizedError extends RequestError {\n\tstatusCode = StatusCodes.NotAuthorized\n\n\tconstructor(message = 'Not authorized', cause?: unknown) {\n\t\tsuper(message, [{ message }], cause)\n\t}\n}\n","import { StatusCodes } from '../../server'\nimport { RequestError } from '../requestError'\n\nexport class NotFoundError extends RequestError {\n\tstatusCode = StatusCodes.NotFound\n\n\tconstructor(message = 'Not found', cause?: unknown) {\n\t\tsuper(message, [{ message }], cause)\n\t}\n}\n","import { StatusCodes } from '../../server'\nimport { RequestError } from '../requestError'\n\nexport class RefreshTokenMisusedError extends RequestError {\n\tstatusCode = StatusCodes.NotAuthenticated\n\n\tconstructor(message = 'Refresh token misused', cause?: unknown) {\n\t\tsuper(message, [{ message }], cause)\n\t}\n}\n","import { StatusCodes } from '../../server'\nimport { RequestError } from '../requestError'\n\ntype ValidError = {\n\tmessages: string[]\n\tfield: string\n}\n\nexport class ValidationError extends RequestError {\n\tstatusCode = StatusCodes.ValidationError\n\n\tconstructor(errors: ValidError[], cause?: unknown) {\n\t\tsuper(\n\t\t\t'Unprocessable Entity',\n\t\t\terrors.flatMap(({ field, messages }) => messages.map((message) => ({ message, field }))),\n\t\t\tcause,\n\t\t)\n\t}\n}\n","import axios from 'axios'\n\nimport * as core from './core'\nimport { DbChangeConfig, DbConfig } from './types'\nimport { EquippedError } from '../../errors'\nimport { Instance } from '../../instance'\n\nexport const TopicPrefix = 'db-changes'\n\nexport type TableOptions = { skipAudit?: boolean }\n\nexport abstract class Db<IdKey extends core.IdType> {\n\tconstructor(protected config: DbConfig) {}\n\n\tprotected getScopedDb(db: string) {\n\t\treturn Instance.get().getScopedName(db).replaceAll('.', '-')\n\t}\n\n\tabstract use<Model extends core.Model<IdKey>, Entity extends core.Entity>(\n\t\tconfig: core.Config<Model, Entity>,\n\t): core.Table<IdKey, Model, Entity>\n}\n\nexport abstract class DbChange<Model extends core.Model<core.IdType>, Entity extends core.Entity> {\n\t#callbacks: core.DbChangeCallbacks<Model, Entity> = {}\n\t#mapper: (model: Model) => Entity\n\n\tconstructor(\n\t\tprivate config: DbChangeConfig,\n\t\tcallbacks: core.DbChangeCallbacks<Model, Entity>,\n\t\tmapper: (model: Model) => Entity,\n\t) {\n\t\tthis.#callbacks = callbacks\n\t\tthis.#mapper = mapper\n\t}\n\n\tget callbacks() {\n\t\treturn Object.freeze(this.#callbacks)\n\t}\n\n\tget mapper() {\n\t\treturn this.#mapper\n\t}\n\n\tprotected async configureConnector(key: string, data: Record<string, string>) {\n\t\tconst instance = axios.create({ baseURL: this.config.debeziumUrl })\n\t\treturn await instance\n\t\t\t.put(`/connectors/${key}/config`, {\n\t\t\t\t'topic.prefix': TopicPrefix,\n\t\t\t\t'topic.creation.enable': 'false',\n\t\t\t\t'topic.creation.default.replication.factor': `-1`,\n\t\t\t\t'topic.creation.default.partitions': '-1',\n\t\t\t\t'key.converter': 'org.apache.kafka.connect.json.JsonConverter',\n\t\t\t\t'key.converter.schemas.enable': 'false',\n\t\t\t\t'value.converter': 'org.apache.kafka.connect.json.JsonConverter',\n\t\t\t\t'value.converter.schemas.enable': 'false',\n\t\t\t\t...data,\n\t\t\t})\n\t\t\t.then(async () => {\n\t\t\t\tconst topics = await instance.get(`/connectors/${key}/topics`)\n\t\t\t\treturn topics.data[key]?.topics?.includes?.(key) ?? false\n\t\t\t})\n\t\t\t.catch((err) => {\n\t\t\t\tthrow new EquippedError(`Failed to configure watcher`, { key }, err)\n\t\t\t})\n\t}\n}\n","import { Filter, MongoClient, ObjectId } from 'mongodb'\nimport { differ } from 'valleyed'\n\nimport { EquippedError } from '../../errors'\nimport { Instance } from '../../instance'\nimport { retry } from '../../utilities'\nimport { DbChange, TopicPrefix } from '../base/_instance'\nimport * as core from '../base/core'\nimport { DbChangeConfig } from '../base/types'\nimport { MongoDbConfig } from '../pipes'\n\nexport class MongoDbChange<Model extends core.Model<{ _id: string }>, Entity extends core.Entity> extends DbChange<Model, Entity> {\n\t#started = false\n\n\tconstructor(\n\t\tconfig: MongoDbConfig,\n\t\tchange: DbChangeConfig,\n\t\tclient: MongoClient,\n\t\tdbName: string,\n\t\tcolName: string,\n\t\tcallbacks: core.DbChangeCallbacks<Model, Entity>,\n\t\tmapper: (model: Model) => Entity,\n\t) {\n\t\tsuper(change, callbacks, mapper)\n\n\t\tconst hydrate = (data: any) =>\n\t\t\tdata._id\n\t\t\t\t? {\n\t\t\t\t\t\t...data,\n\t\t\t\t\t\t_id: makeId(data._id['$oid'] ?? data._id),\n\t\t\t\t\t}\n\t\t\t\t: undefined\n\n\t\tconst dbColName = `${dbName}.${colName}`\n\t\tconst topic = `${TopicPrefix}.${dbColName}`\n\n\t\tconst hexId = '5f5f65717569707065645f5f' // __equipped__\n\t\tconst TestId = makeId(hexId)\n\t\tconst condition = { _id: TestId } as Filter<Model>\n\n\t\tchange.eventBus.createSubscriber(\n\t\t\ttopic as never,\n\t\t\tasync (data: DbDocumentChange) => {\n\t\t\t\tconst op = data.op\n\n\t\t\t\tlet before = JSON.parse(data.before ?? 'null')\n\t\t\t\tlet after = JSON.parse(data.after ?? 'null')\n\n\t\t\t\tif (before) before = hydrate(before)\n\t\t\t\tif (after) after = hydrate(after)\n\t\t\t\tif (before?.__id === TestId || after?.__id === TestId) return\n\n\t\t\t\tif (op === 'c' && this.callbacks.created && after)\n\t\t\t\t\tawait this.callbacks.created({\n\t\t\t\t\t\tbefore: null,\n\t\t\t\t\t\tafter: this.mapper(after)!,\n\t\t\t\t\t})\n\t\t\t\telse if (op === 'u' && this.callbacks.updated && before && after)\n\t\t\t\t\tawait this.callbacks.updated({\n\t\t\t\t\t\tbefore: this.mapper(before)!,\n\t\t\t\t\t\tafter: this.mapper(after)!,\n\t\t\t\t\t\tchanges: differ.from(differ.diff(before, after)),\n\t\t\t\t\t})\n\t\t\t\telse if (op === 'd' && this.callbacks.deleted && before)\n\t\t\t\t\tawait this.callbacks.deleted({\n\t\t\t\t\t\tbefore: this.mapper(before)!,\n\t\t\t\t\t\tafter: null,\n\t\t\t\t\t})\n\t\t\t},\n\t\t\t{ skipScope: true },\n\t\t)\n\n\t\tInstance.on(\n\t\t\t'start',\n\t\t\tasync () => {\n\t\t\t\tif (this.#started) return\n\t\t\t\tthis.#started = true\n\n\t\t\t\tconst collection = client.db(dbName).collection<Model>(colName)\n\n\t\t\t\tawait retry(\n\t\t\t\t\tasync () => {\n\t\t\t\t\t\tconst started = await this.configureConnector(topic, {\n\t\t\t\t\t\t\t'connector.class': 'io.debezium.connector.mongodb.MongoDbConnector',\n\t\t\t\t\t\t\t'capture.mode': 'change_streams_update_full_with_pre_image',\n\t\t\t\t\t\t\t'mongodb.connection.string': config.uri,\n\t\t\t\t\t\t\t'collection.include.list': dbColName,\n\t\t\t\t\t\t\t'snapshot.mode': 'when_needed',\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\tif (started) return { done: true, value: true }\n\t\t\t\t\t\tawait collection.findOneAndUpdate(condition, { $set: { colName } as any }, { upsert: true })\n\t\t\t\t\t\tawait collection.findOneAndDelete(condition)\n\t\t\t\t\t\tInstance.get().log.warn(`Waiting for db changes for ${dbColName} to start...`)\n\t\t\t\t\t\treturn { done: false }\n\t\t\t\t\t},\n\t\t\t\t\t6,\n\t\t\t\t\t10_000,\n\t\t\t\t).catch((err) => Instance.crash(new EquippedError(`Failed to start db changes`, { dbColName }, err)))\n\t\t\t},\n\t\t\t10,\n\t\t)\n\t}\n}\n\ntype DbDocumentChange = {\n\tbefore: string | null\n\tafter: string | null\n\top: 'c' | 'u' | 'd'\n}\n\nconst makeId = (id: string) => {\n\ttry {\n\t\treturn new ObjectId(id)\n\t} catch {\n\t\treturn id\n\t}\n}\n","import { ClientSession, CollectionInfo, MongoClient, ObjectId } from 'mongodb'\n\nimport { getTable } from './api'\nimport { MongoDbConfig } from '../pipes'\nimport { MongoDbChange } from './changes'\nimport { EquippedError } from '../../errors'\nimport { Instance } from '../../instance'\nimport { Db } from '../base/_instance'\nimport * as core from '../base/core'\nimport { DbConfig } from '../base/types'\n\nexport class MongoDb extends Db<{ _id: string }> {\n\t#client: MongoClient\n\t#cols: { db: string; col: string }[] = []\n\n\tconstructor(\n\t\tprivate mongoConfig: MongoDbConfig,\n\t\tdbConfig: DbConfig,\n\t) {\n\t\tsuper(dbConfig)\n\t\tthis.#client = new MongoClient(mongoConfig.uri)\n\t\tInstance.on(\n\t\t\t'start',\n\t\t\tasync () => {\n\t\t\t\tawait this.#client.connect()\n\n\t\t\t\tconst grouped = this.#cols.reduce<Record<string, string[]>>((acc, cur) => {\n\t\t\t\t\tif (!acc[cur.db]) acc[cur.db] = []\n\t\t\t\t\tacc[cur.db].push(cur.col)\n\t\t\t\t\treturn acc\n\t\t\t\t}, {})\n\n\t\t\t\tconst options = {\n\t\t\t\t\tchangeStreamPreAndPostImages: { enabled: true },\n\t\t\t\t}\n\t\t\t\tawait Promise.all(\n\t\t\t\t\tObject.entries(grouped).map(async ([dbName, colNames]) => {\n\t\t\t\t\t\tconst db = this.#client.db(dbName)\n\t\t\t\t\t\tconst collections = await db.listCollections<CollectionInfo>().toArray()\n\t\t\t\t\t\treturn colNames.map(async (colName) => {\n\t\t\t\t\t\t\tconst existing = collections.find((collection) => collection.name === colName)\n\t\t\t\t\t\t\tif (existing) {\n\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\texisting.options?.changeStreamPreAndPostImages?.enabled !== options.changeStreamPreAndPostImages.enabled\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\tawait db.command({ collMod: colName, ...options })\n\t\t\t\t\t\t\t} else await db.createCollection(colName, options)\n\t\t\t\t\t\t})\n\t\t\t\t\t}),\n\t\t\t\t)\n\t\t\t},\n\t\t\t3,\n\t\t)\n\t\tInstance.on('close', async () => this.#client.close(), 1)\n\t}\n\n\tasync session<T>(callback: (session: ClientSession) => Promise<T>) {\n\t\treturn this.#client.withSession(callback)\n\t}\n\n\tid() {\n\t\treturn new ObjectId()\n\t}\n\n\tuse<Model extends core.Model<{ _id: string }>, Entity extends core.Entity>(config: core.Config<Model, Entity>) {\n\t\tif (config.change) {\n\t\t\tif (!this.config.changes) Instance.crash(new EquippedError('Db changes are not enabled in the configuration.', { config }))\n\t\t\tnew MongoDbChange<Model, Entity>(\n\t\t\t\tthis.mongoConfig,\n\t\t\t\tthis.config.changes,\n\t\t\t\tthis.#client,\n\t\t\t\tthis.getScopedDb(config.db),\n\t\t\t\tconfig.col,\n\t\t\t\tconfig.change,\n\t\t\t\tconfig.mapper,\n\t\t\t)\n\t\t}\n\t\tthis.#cols.push({ db: this.getScopedDb(config.db), col: config.col })\n\t\tconst collection = this.#client.db(this.getScopedDb(config.db)).collection<Model>(config.col)\n\t\treturn getTable(config, collection)\n\t}\n}\n","import { Collection, ObjectId, OptionalUnlessRequiredId, SortDirection, WithId } from 'mongodb'\n\nimport { QueryParams } from '../pipes'\nimport { parseMongodbQueryParams } from './query'\nimport { EquippedError } from '../../errors'\nimport * as core from '../base/core'\n\nconst idKey = '_id'\ntype IdType = { _id: string }\n\nexport function getTable<Model extends core.Model<IdType>, Entity extends core.Entity>(\n\tconfig: core.Config<Model, Entity>,\n\tcollection: Collection<Model>,\n) {\n\ttype WI = Model | WithId<Model>\n\tasync function transform(doc: WI): Promise<Entity>\n\t// eslint-disable-next-line no-redeclare\n\tasync function transform(doc: WI[]): Promise<Entity[]>\n\t// eslint-disable-next-line no-redeclare\n\tasync function transform(doc: WI | WI[]) {\n\t\tconst docs = Array.isArray(doc) ? doc : [doc]\n\t\tconst mapped = docs.map((d) => config.mapper(d as Model))\n\t\treturn Array.isArray(doc) ? mapped : mapped[0]\n\t}\n\n\tfunction prepInsertValue(value: core.CreateInput<Model>, id: string, now: Date, skipUpdate?: boolean) {\n\t\tconst base: core.Model<IdType> = {\n\t\t\t[idKey]: id,\n\t\t\t...(config.options?.skipAudit\n\t\t\t\t? {}\n\t\t\t\t: {\n\t\t\t\t\t\tcreatedAt: now.getTime(),\n\t\t\t\t\t\t...(skipUpdate ? {} : { updatedAt: now.getTime() }),\n\t\t\t\t\t}),\n\t\t}\n\t\treturn {\n\t\t\t...value,\n\t\t\t...base,\n\t\t} as unknown as OptionalUnlessRequiredId<Model>\n\t}\n\n\tfunction prepUpdateValue(value: core.UpdateInput<Model>, now: Date) {\n\t\treturn {\n\t\t\t...value,\n\t\t\t$set: {\n\t\t\t\t...value.$set,\n\t\t\t\t...(Object.keys(value).length > 0 && !config.options?.skipAudit\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tupdatedAt: now.getTime(),\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}),\n\t\t\t},\n\t\t}\n\t}\n\n\tconst table: core.Table<IdType, Model, Entity, { collection: Collection<Model> }> = {\n\t\tconfig,\n\t\textras: { collection },\n\n\t\tquery: async (params: QueryParams) => {\n\t\t\tconst results = await parseMongodbQueryParams(collection, params)\n\t\t\treturn {\n\t\t\t\t...results,\n\t\t\t\tresults: (await transform(results.results as any)) as any,\n\t\t\t}\n\t\t},\n\n\t\tfindMany: async (filter, options = {}) => {\n\t\t\tconst sortArray = Array.isArray(options.sort) ? options.sort : options.sort ? [options.sort] : []\n\t\t\tconst sort = sortArray.map((p) => [p.field, p.desc ? 'desc' : 'asc'] as [string, SortDirection])\n\t\t\tconst docs = await collection\n\t\t\t\t.find(filter, {\n\t\t\t\t\tsession: options.session,\n\t\t\t\t\tlimit: options.limit,\n\t\t\t\t\tsort,\n\t\t\t\t})\n\t\t\t\t.toArray()\n\t\t\treturn transform(docs)\n\t\t},\n\n\t\tfindOne: async (filter, options = {}) => {\n\t\t\tconst result = await table.findMany(filter, { ...options, limit: 1 })\n\t\t\treturn result.at(0) ?? null\n\t\t},\n\n\t\tfindById: async (id, options = {}) => {\n\t\t\tconst result = await table.findOne({ [idKey]: id } as core.Filter<Model>, options)\n\t\t\treturn result\n\t\t},\n\n\t\tinsertMany: async (values, options = {}) => {\n\t\t\tconst now = options.getTime?.() ?? new Date()\n\t\t\tconst payload = values.map((value, i) => prepInsertValue(value, options.makeId?.(i) ?? new ObjectId().toString(), now))\n\t\t\tawait collection.insertMany(payload, { session: options.session })\n\n\t\t\tconst insertedData = await Promise.all(payload.map(async (data) => await table.findById(data[idKey] as any, options)))\n\t\t\treturn insertedData.filter((value) => !!value)\n\t\t},\n\n\t\tinsertOne: async (values, options = {}) => {\n\t\t\tconst result = await table.insertMany([values], options)\n\t\t\treturn result[0]\n\t\t},\n\n\t\tupdateMany: async (filter, values, options = {}) => {\n\t\t\tconst now = options.getTime?.() ?? new Date()\n\t\t\tawait collection.updateMany(filter, prepUpdateValue(values, now), { session: options.session })\n\t\t\treturn table.findMany(filter, options)\n\t\t},\n\n\t\tupdateOne: async (filter, values, options = {}) => {\n\t\t\tconst now = options.getTime?.() ?? new Date()\n\t\t\tconst doc = await collection.findOneAndUpdate(filter, prepUpdateValue(values, now), {\n\t\t\t\treturnDocument: 'after',\n\t\t\t\tsession: options.session,\n\t\t\t})\n\t\t\treturn doc ? transform(doc) : null\n\t\t},\n\n\t\tupdateById: async (id, values, options = {}) => {\n\t\t\tconst result = await table.updateOne({ [idKey]: id } as core.Filter<Model>, values, options)\n\t\t\treturn result\n\t\t},\n\n\t\tupsertOne: async (filter, values, options = {}) => {\n\t\t\tconst now = options.getTime?.() ?? new Date()\n\n\t\t\tconst doc = await collection.findOneAndUpdate(\n\t\t\t\tfilter,\n\t\t\t\t{\n\t\t\t\t\t...prepUpdateValue('update' in values ? values.update : {}, now),\n\t\t\t\t\t// @ts-expect-error fighting ts\n\t\t\t\t\t$setOnInsert: prepInsertValue(values.insert, options.makeId?.() ?? new ObjectId().toString(), now, true),\n\t\t\t\t},\n\t\t\t\t{ returnDocument: 'after', session: options.session, upsert: true },\n\t\t\t)\n\n\t\t\treturn transform(doc)\n\t\t},\n\n\t\tdeleteMany: async (filter, options = {}) => {\n\t\t\tconst docs = await table.findMany(filter, options)\n\t\t\tawait collection.deleteMany(filter, { session: options.session })\n\t\t\treturn docs\n\t\t},\n\n\t\tdeleteOne: async (filter, options) => {\n\t\t\tconst doc = await collection.findOneAndDelete(filter, { session: options?.session })\n\t\t\treturn doc ? transform(doc) : null\n\t\t},\n\n\t\tdeleteById: async (id, options) => {\n\t\t\tconst result = await table.deleteOne({ [idKey]: id } as core.Filter<Model>, options)\n\t\t\treturn result\n\t\t},\n\n\t\tbulkWrite: async (operations, options = {}) => {\n\t\t\tconst bulk = collection.initializeUnorderedBulkOp({ session: options.session })\n\t\t\tconst now = options.getTime?.() ?? new Date()\n\t\t\toperations.forEach((operation, i) => {\n\t\t\t\tswitch (operation.op) {\n\t\t\t\t\tcase 'insert':\n\t\t\t\t\t\tbulk.insert(prepInsertValue(operation.value, operation.makeId?.(i) ?? new ObjectId().toString(), now))\n\t\t\t\t\t\tbreak\n\t\t\t\t\tcase 'delete':\n\t\t\t\t\t\tbulk.find(operation.filter).delete()\n\t\t\t\t\t\tbreak\n\t\t\t\t\tcase 'update':\n\t\t\t\t\t\tbulk.find(operation.filter).update(prepUpdateValue(operation.value, now))\n\t\t\t\t\t\tbreak\n\t\t\t\t\tcase 'upsert':\n\t\t\t\t\t\tbulk.find(operation.filter)\n\t\t\t\t\t\t\t.upsert()\n\t\t\t\t\t\t\t.update({\n\t\t\t\t\t\t\t\t...prepUpdateValue('update' in operation ? operation.update : {}, now),\n\t\t\t\t\t\t\t\t$setOnInsert: prepInsertValue(\n\t\t\t\t\t\t\t\t\toperation.insert as any,\n\t\t\t\t\t\t\t\t\toperation.makeId?.(i) ?? new ObjectId().toString(),\n\t\t\t\t\t\t\t\t\tnow,\n\t\t\t\t\t\t\t\t\ttrue,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\tbreak\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new EquippedError(`Unknown bulkWrite operation`, { operation })\n\t\t\t\t}\n\t\t\t})\n\t\t\tawait bulk.execute({ session: options.session })\n\t\t},\n\t}\n\n\treturn table\n}\n","import { ConditionalObjectKeys, Pipe, PipeInput, PipeOutput, v } from 'valleyed'\n\nimport { Instance } from '../instance'\n\nexport enum QueryKeys {\n\tand = 'and',\n\tor = 'or',\n}\n\nexport enum Conditions {\n\tlt = 'lt',\n\tlte = 'lte',\n\tgt = 'gt',\n\tgte = 'gte',\n\teq = 'eq',\n\tne = 'ne',\n\tin = 'in',\n\tnin = 'nin',\n\texists = 'exists',\n}\n\nconst queryKeys = v.catch(v.defaults(v.in([QueryKeys.and, QueryKeys.or]), QueryKeys.and), QueryKeys.and)\n\nconst queryWhere = v.object({\n\tfield: v.string(),\n\tvalue: v.any(),\n\tcondition: v.catch(v.defaults(v.in(Object.values(Conditions)), Conditions.eq), Conditions.eq),\n})\n\nconst queryWhereBlock = v.object({\n\tcondition: queryKeys,\n\tvalue: v.array(queryWhere),\n})\n\nconst queryWhereClause = v.defaults(v.array(v.or([queryWhere, queryWhereBlock])), [])\n\nexport function queryParamsPipe() {\n\tconst pagLimit = Instance.get().settings.server?.requests.paginationDefaultLimit ?? 100\n\treturn v.meta(\n\t\tv\n\t\t\t.object({\n\t\t\t\tall: v.defaults(v.boolean(), false),\n\t\t\t\tlimit: v.catch(v.defaults(v.number().pipe(v.lte(pagLimit)), pagLimit), pagLimit),\n\t\t\t\tpage: v.catch(v.defaults(v.number().pipe(v.gte(1)), 1), 1),\n\t\t\t\tsearch: v.defaults(\n\t\t\t\t\tv.nullish(\n\t\t\t\t\t\tv.object({\n\t\t\t\t\t\t\tvalue: v.string(),\n\t\t\t\t\t\t\tfields: v.array(v.string()),\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t\tnull,\n\t\t\t\t),\n\t\t\t\tsort: v.defaults(\n\t\t\t\t\tv.array(\n\t\t\t\t\t\tv.object({\n\t\t\t\t\t\t\tfield: v.string(),\n\t\t\t\t\t\t\tdesc: v.defaults(v.boolean(), false),\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t\t[],\n\t\t\t\t),\n\t\t\t\twhereType: queryKeys,\n\t\t\t\twhere: queryWhereClause,\n\t\t\t})\n\t\t\t.pipe((p) => ({ ...p, auth: <(typeof p)['where']>[], authType: QueryKeys.and })),\n\t\t{ title: 'Query Params', $refId: 'QueryParams' },\n\t)\n}\n\nexport function queryResultsPipe<T>(model: Pipe<any, T, any>) {\n\treturn v.object({\n\t\tpages: v.object({\n\t\t\tcurrent: v.number(),\n\t\t\tstart: v.number(),\n\t\t\tlast: v.number(),\n\t\t\tprevious: v.nullable(v.number()),\n\t\t\tnext: v.nullable(v.number()),\n\t\t}),\n\t\tdocs: v.object({\n\t\t\tlimit: v.number(),\n\t\t\ttotal: v.number(),\n\t\t\tcount: v.number(),\n\t\t}),\n\t\tresults: v.array(model),\n\t})\n}\n\nexport function wrapQueryParams(params: QueryParamsInput): QueryParams {\n\treturn v.assert(queryParamsPipe(), params)\n}\n\nexport type QueryParams = PipeOutput<ReturnType<typeof queryParamsPipe>>\nexport type QueryParamsInput = ConditionalObjectKeys<PipeInput<ReturnType<typeof queryParamsPipe>>>\nexport type QueryWhereClause = QueryParams['where'][number]\nexport type QueryWhere = Extract<QueryWhereClause, { field: string }>\nexport type QueryWhereBlock = Exclude<QueryWhereClause, { field: string }>\nexport type QueryResults<T> = PipeOutput<ReturnType<typeof queryResultsPipe<T>>>\n\nexport const mongoDbConfigPipe = v.meta(\n\tv.object({\n\t\turi: v.string(),\n\t}),\n\t{ title: 'Mongodb Config', $refId: 'MongodbConfig' },\n)\n\nexport type MongoDbConfig = PipeOutput<typeof mongoDbConfigPipe>\n","import { Collection } from 'mongodb'\n\nimport * as core from '../base/core'\nimport { QueryKeys, type QueryParams, type QueryResults, type QueryWhereBlock, type QueryWhereClause } from '../pipes'\n\nexport const parseMongodbQueryParams = async <Model extends core.Model<{ _id: string }>>(\n\tcollection: Collection<Model>,\n\tparams: QueryParams,\n): Promise<QueryResults<Model>> => {\n\t// Handle where/search clauses\n\tconst query = <ReturnType<typeof buildWhereQuery>[]>[]\n\tconst where = buildWhereQuery(params.where, params.whereType)\n\tif (where) query.push(where)\n\tconst auth = buildWhereQuery(params.auth, params.authType)\n\tif (auth) query.push(auth)\n\tif (params.search && params.search.fields.length > 0) {\n\t\tconst search = params.search.fields.map((field) => ({\n\t\t\t[field]: {\n\t\t\t\t$regex: new RegExp(params.search!.value, 'i'),\n\t\t\t},\n\t\t}))\n\t\tquery.push({ $or: search })\n\t}\n\tconst totalClause = {}\n\tif (query.length > 0) totalClause['$and'] = query\n\n\t// Handle sort clauses\n\tconst sort = params.sort.map((p) => [p.field, p.desc ? 'desc' : 'asc'])\n\n\t// Handle limit/offest clause\n\tconst all = params.all ?? false\n\tconst limit = params.limit\n\tconst page = params.page\n\n\tconst total = await collection.countDocuments(totalClause)\n\n\tlet builtQuery = collection.find(totalClause)\n\tif (sort.length) builtQuery = builtQuery.sort(Object.fromEntries(sort))\n\tif (!all && limit) {\n\t\tbuiltQuery = builtQuery.limit(limit)\n\t\tif (page) builtQuery = builtQuery.skip((page - 1) * limit)\n\t}\n\n\tconst results = await builtQuery.toArray()\n\tconst start = 1\n\tconst last = Math.ceil(total / limit) || 1\n\tconst next = page >= last ? null : page + 1\n\tconst previous = page <= start ? null : page - 1\n\n\treturn {\n\t\tpages: { start, last, next, previous, current: page },\n\t\tdocs: { limit, total, count: results.length },\n\t\tresults: results as any[],\n\t} satisfies QueryResults<Model>\n}\n\nfunction isWhereBlock(param: QueryWhereClause): param is QueryWhereBlock {\n\treturn Object.values(QueryKeys).includes(param.condition as QueryKeys)\n}\n\nconst buildWhereQuery = (params: QueryWhereClause[], key: QueryKeys = QueryKeys.and): Record<string, Record<string, any>> | null => {\n\tconst where = (Array.isArray(params) ? params : [])\n\t\t.map((param) => {\n\t\t\tif (isWhereBlock(param)) return buildWhereQuery(param.value, param.condition)\n\t\t\tconst { field } = param\n\t\t\tconst checkedField = field === 'id' ? '_id' : (field ?? '')\n\t\t\tconst checkedValue = param.value === undefined ? '' : param.value\n\t\t\treturn {\n\t\t\t\tfield: checkedField,\n\t\t\t\tvalue: checkedValue,\n\t\t\t\tcondition: param.condition,\n\t\t\t\tisWhere: true,\n\t\t\t}\n\t\t})\n\t\t.filter((c) => !!c)\n\t\t.map((c) => {\n\t\t\tif (c.isWhere) return { [`${c.field}`]: { [`$${c.condition}`]: c.value } }\n\t\t\telse return c\n\t\t})\n\n\treturn where.length > 0 ? { [`$${key}`]: where } : null\n}\n","import { Events } from '../types'\n\nexport type PublishOptions = { skipScope?: boolean }\nexport type SubscribeOptions = PublishOptions & { fanout: boolean }\n\nexport abstract class EventBus {\n\tabstract createPublisher<Event extends Events[keyof Events]>(\n\t\ttopic: Event['topic'],\n\t\toptions?: Partial<SubscribeOptions>,\n\t): (data: Event['data']) => Promise<boolean>\n\n\tabstract createSubscriber<Event extends Events[keyof Events]>(\n\t\ttopic: Event['topic'],\n\t\tonMessage: (data: Event['data']) => Promise<void>,\n\t\toptions?: Partial<SubscribeOptions>,\n\t): void\n}\n\nexport const DefaultSubscribeOptions = {\n\tfanout: false,\n}\n","import { PipeOutput, v } from 'valleyed'\n\nexport const rabbitmqConfigPipe = v.meta(\n\tv.object({\n\t\turi: v.string(),\n\t\teventColumnName: v.string(),\n\t}),\n\t{ title: 'Rabbitmq Config', $refId: 'RabbitmqConfig' },\n)\n\nexport const kafkaConfigPipe = v.meta(\n\tv.object({\n\t\tbrokers: v.array(v.string()),\n\t\tssl: v.optional(v.boolean()),\n\t\tsasl: v.optional(\n\t\t\tv.object({\n\t\t\t\tmechanism: v.is('plain' as const),\n\t\t\t\tusername: v.string(),\n\t\t\t\tpassword: v.string(),\n\t\t\t}),\n\t\t),\n\t\tconfluent: v.optional(v.boolean()),\n\t\tclientId: v.optional(v.string()),\n\t}),\n\t{ title: 'Kafka Config', $refId: 'KafkaConfig' },\n)\n\nexport type KafkaConfig = PipeOutput<typeof kafkaConfigPipe>\nexport type RabbitMQConfig = PipeOutput<typeof rabbitmqConfigPipe>\n","import Confluent from '@confluentinc/kafka-javascript'\nimport Kafka from 'kafkajs'\n\nimport { Instance } from '../../instance'\nimport type { Events } from '../../types'\nimport { Random, parseJSONValue } from '../../utilities'\nimport { DefaultSubscribeOptions, EventBus, PublishOptions, SubscribeOptions } from '../base'\nimport { KafkaConfig } from '../pipes'\n\nexport class KafkaEventBus extends EventBus {\n\t#client: Kafka.Kafka | Confluent.KafkaJS.Kafka\n\t#confluent: boolean\n\t#admin: Kafka.Admin | Confluent.KafkaJS.Admin | undefined\n\tconstructor(config: KafkaConfig) {\n\t\tsuper()\n\t\tconst { confluent = false, ...kafkaSettings } = config\n\t\tthis.#confluent = confluent\n\t\tthis.#client = confluent\n\t\t\t? new Confluent.KafkaJS.Kafka({\n\t\t\t\t\tkafkaJS: { ...kafkaSettings, logLevel: Confluent.KafkaJS.logLevel.NOTHING },\n\t\t\t\t})\n\t\t\t: new Kafka.Kafka({ ...kafkaSettings, logLevel: Kafka.logLevel.NOTHING })\n\t}\n\n\tcreatePublisher<Event extends Events[keyof Events]>(topicName: Event['topic'], options: Partial<PublishOptions> = {}) {\n\t\tconst topic = options.skipScope ? topicName : Instance.get().getScopedName(topicName)\n\t\treturn async (data: Event['data']) => {\n\t\t\ttry {\n\t\t\t\tconst producer = this.#client.producer()\n\t\t\t\tawait producer.connect()\n\t\t\t\tawait producer.send({\n\t\t\t\t\ttopic,\n\t\t\t\t\tmessages: [{ value: JSON.stringify(data) }],\n\t\t\t\t})\n\t\t\t\treturn true\n\t\t\t} catch {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\n\tcreateSubscriber<Event extends Events[keyof Events]>(\n\t\ttopicName: Event['topic'],\n\t\tonMessage: (data: Event['data']) => Promise<void>,\n\t\toptions: Partial<SubscribeOptions> = {},\n\t) {\n\t\toptions = { ...DefaultSubscribeOptions, ...options }\n\t\tconst topic = options.skipScope ? topicName : Instance.get().getScopedName(topicName)\n\t\tconst subscribe = async () => {\n\t\t\tawait this.#createTopic(topic)\n\t\t\tconst groupId = options.fanout\n\t\t\t\t? Instance.get().getScopedName(`${Instance.get().settings.app.id}-fanout-${Random.string(10)}`)\n\t\t\t\t: topic\n\t\t\tconst consumer = this.#client.consumer(this.#confluent ? ({ kafkaJS: { groupId } } as any) : { groupId })\n\n\t\t\tawait consumer.connect()\n\t\t\tawait consumer.subscribe({ topic })\n\n\t\t\tawait consumer.run({\n\t\t\t\teachMessage: async ({ message }) => {\n\t\t\t\t\tInstance.resolveBeforeCrash(async () => {\n\t\t\t\t\t\tif (!message.value) return\n\t\t\t\t\t\tawait onMessage(parseJSONValue(message.value.toString()))\n\t\t\t\t\t})\n\t\t\t\t},\n\t\t\t})\n\n\t\t\tif (options.fanout)\n\t\t\t\tInstance.on(\n\t\t\t\t\t'close',\n\t\t\t\t\tasync () => {\n\t\t\t\t\t\tawait consumer.disconnect()\n\t\t\t\t\t\tawait this.#deleteGroup(groupId)\n\t\t\t\t\t},\n\t\t\t\t\t10,\n\t\t\t\t)\n\t\t}\n\t\tInstance.on('start', subscribe, 2)\n\t}\n\n\tasync #getAdmin() {\n\t\tif (!this.#admin) {\n\t\t\tthis.#admin = this.#client.admin()\n\t\t\tawait this.#admin.connect()\n\t\t}\n\t\treturn this.#admin\n\t}\n\n\tasync #createTopic(topic: string) {\n\t\tconst admin = await this.#getAdmin()\n\t\tawait admin.createTopics({ topics: [{ topic }], timeout: 5000 })\n\t}\n\n\tasync #deleteGroup(groupId: string) {\n\t\tconst admin = await this.#getAdmin()\n\t\tawait admin.deleteGroups([groupId]).catch(() => {})\n\t}\n}\n","import type { ChannelWrapper } from 'amqp-connection-manager'\nimport { connect } from 'amqp-connection-manager'\nimport type { ConfirmChannel } from 'amqplib'\n\nimport { Instance } from '../../instance'\nimport type { Events } from '../../types'\nimport { Random, parseJSONValue } from '../../utilities'\nimport { DefaultSubscribeOptions, EventBus, PublishOptions, SubscribeOptions } from '../base'\nimport { RabbitMQConfig } from '../pipes'\n\nexport class RabbitMQEventBus extends EventBus {\n\t#client: ChannelWrapper\n\t#columnName: string\n\n\tconstructor(config: RabbitMQConfig) {\n\t\tsuper()\n\t\tthis.#columnName = config.eventColumnName\n\t\tthis.#client = connect([config.uri]).createChannel({\n\t\t\tjson: false,\n\t\t\tsetup: async (channel: ConfirmChannel) => {\n\t\t\t\tawait channel.assertExchange(this.#columnName, 'direct', { durable: true })\n\t\t\t\tawait channel.prefetch(1)\n\t\t\t},\n\t\t})\n\t}\n\n\tcreatePublisher<Event extends Events[keyof Events]>(topicName: Event['topic'], options: Partial<PublishOptions> = {}) {\n\t\tconst topic = options.skipScope ? topicName : Instance.get().getScopedName(topicName)\n\t\treturn async (data: Event['data']) =>\n\t\t\tawait this.#client.publish(this.#columnName, topic, JSON.stringify(data), { persistent: true })\n\t}\n\n\tcreateSubscriber<Event extends Events[keyof Events]>(\n\t\ttopicName: Event['topic'],\n\t\tonMessage: (data: Event['data']) => Promise<void>,\n\t\toptions: Partial<SubscribeOptions> = {},\n\t) {\n\t\toptions = { ...DefaultSubscribeOptions, ...options }\n\t\tconst topic = options.skipScope ? topicName : Instance.get().getScopedName(topicName)\n\t\tconst subscribe = async () => {\n\t\t\tawait this.#client.addSetup(async (channel: ConfirmChannel) => {\n\t\t\t\tconst queueName = options.fanout\n\t\t\t\t\t? Instance.get().getScopedName(`${Instance.get().settings.app.id}-fanout-${Random.string(10)}`)\n\t\t\t\t\t: topic\n\t\t\t\tconst { queue } = await channel.assertQueue(queueName, { durable: !options.fanout, exclusive: options.fanout })\n\t\t\t\tawait channel.bindQueue(queue, this.#columnName, topic)\n\t\t\t\tchannel.consume(\n\t\t\t\t\tqueue,\n\t\t\t\t\tasync (msg) => {\n\t\t\t\t\t\tInstance.resolveBeforeCrash(async () => {\n\t\t\t\t\t\t\tif (!msg) return\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tawait onMessage(parseJSONValue(msg.content.toString()))\n\t\t\t\t\t\t\t\tchannel.ack(msg)\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\tchannel.nack(msg)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t},\n\t\t\t\t\t{ noAck: false },\n\t\t\t\t)\n\t\t\t})\n\t\t}\n\n\t\tInstance.on('start', subscribe, 2)\n\t}\n}\n","import { PipeOutput, v } from 'valleyed'\n\nimport { redisConfigPipe } from '../cache'\n\nexport const redisJobsConfigPipe = v.meta(\n\tv.object({\n\t\tredisConfig: redisConfigPipe,\n\t\tqueueName: v.string(),\n\t}),\n\t{ title: 'Redis Jobs Config', $refId: 'RedisJobsConfig' },\n)\n\nexport type RedisJobConfig = PipeOutput<typeof redisJobsConfigPipe>\n","import Bull from 'bull'\n\nimport { RedisCache } from '../../cache/types/redis'\nimport { Instance } from '../../instance'\nimport { CronTypes, DelayedJobs, RepeatableJobs } from '../../types'\nimport { Random } from '../../utilities'\nimport { RedisJobConfig } from '../pipes'\n\nenum JobNames {\n\tCronJob = 'CronJob',\n\tRepeatableJob = 'RepeatableJob',\n\tDelayedJob = 'DelayedJob',\n}\n\ntype Cron = CronTypes[keyof CronTypes]\ntype DelayedJobEvent = DelayedJobs[keyof DelayedJobs]\ntype RepeatableJobEvent = RepeatableJobs[keyof RepeatableJobs]\ntype DelayedJobCallback = (data: DelayedJobEvent) => Promise<void> | void\ntype CronJobCallback = (name: CronTypes[keyof CronTypes]) => Promise<void> | void\ntype RepeatableJobCallback = (data: RepeatableJobEvent) => Promise<void> | void\n\ntype JobCallbacks = { onDelayed?: DelayedJobCallback; onCron?: CronJobCallback; onRepeatable?: RepeatableJobCallback }\n\nexport class RedisJob {\n\t#queue: Bull.Queue\n\t#callbacks: JobCallbacks = {}\n\t#crons: { name: Cron; cron: string }[] = []\n\n\tconstructor(config: RedisJobConfig) {\n\t\tconst redisCache = new RedisCache(config.redisConfig, {\n\t\t\tmaxRetriesPerRequest: null,\n\t\t\tenableReadyCheck: false,\n\t\t})\n\t\tthis.#queue = new Bull(config.queueName, { createClient: () => redisCache.client })\n\n\t\tInstance.on(\n\t\t\t'start',\n\t\t\tasync () => {\n\t\t\t\tawait this.#cleanup()\n\t\t\t\tawait Promise.all(this.#crons.map(({ cron, name }) => this.#addCron(name, cron)))\n\t\t\t\tPromise.all([\n\t\t\t\t\tthis.#queue.process(JobNames.DelayedJob, async (job) => await (this.#callbacks.onDelayed as any)?.(job.data)),\n\t\t\t\t\tthis.#queue.process(JobNames.CronJob, async (job) => await (this.#callbacks.onCron as any)?.(job.data.type)),\n\t\t\t\t\tthis.#queue.process(JobNames.RepeatableJob, async (job) => await (this.#callbacks.onRepeatable as any)?.(job.data)),\n\t\t\t\t])\n\t\t\t},\n\t\t\t10,\n\t\t)\n\t}\n\n\tset callbacks(callbacks: JobCallbacks) {\n\t\tthis.#callbacks = callbacks\n\t}\n\n\tset crons(crons: { name: Cron; cron: string }[]) {\n\t\tthis.#crons = crons\n\t}\n\n\tstatic #getNewId() {\n\t\treturn [Date.now(), Random.string()].join(':')\n\t}\n\n\tasync addDelayed(data: DelayedJobEvent, delayInMs: number): Promise<string> {\n\t\tconst job = await this.#queue.add(JobNames.DelayedJob, data, {\n\t\t\tjobId: RedisJob.#getNewId(),\n\t\t\tdelay: delayInMs,\n\t\t\tremoveOnComplete: true,\n\t\t\tbackoff: 1000,\n\t\t\tattempts: 3,\n\t\t})\n\t\treturn job.id.toString()\n\t}\n\n\tasync addRepeatable(data: RepeatableJobEvent, cron: string, tz?: string): Promise<string> {\n\t\tconst job = await this.#queue.add(JobNames.RepeatableJob, data, {\n\t\t\tjobId: RedisJob.#getNewId(),\n\t\t\trepeat: { cron, ...(tz ? { tz } : {}) },\n\t\t\tremoveOnComplete: true,\n\t\t\tbackoff: 1000,\n\t\t\tattempts: 3,\n\t\t})\n\t\treturn job.opts?.repeat?.key ?? ''\n\t}\n\n\tasync removeDelayed(jobId: string) {\n\t\tconst job = await this.#queue.getJob(jobId)\n\t\tif (job) await job.discard()\n\t}\n\n\tasync removeRepeatable(jobKey: string) {\n\t\tawait this.#queue.removeRepeatableByKey(jobKey)\n\t}\n\n\tasync retryAllFailedJobs() {\n\t\tconst failedJobs = await this.#queue.getFailed()\n\t\tawait Promise.all(failedJobs.map((job) => job.retry()))\n\t}\n\n\tasync #addCron(type: Cron | string, cron: string): Promise<string> {\n\t\tconst job = await this.#queue.add(\n\t\t\tJobNames.CronJob,\n\t\t\t{ type },\n\t\t\t{\n\t\t\t\tjobId: RedisJob.#getNewId(),\n\t\t\t\trepeat: { cron },\n\t\t\t\tremoveOnComplete: true,\n\t\t\t\tbackoff: 1000,\n\t\t\t\tattempts: 3,\n\t\t\t},\n\t\t)\n\t\treturn job.id.toString()\n\t}\n\n\tasync #cleanup() {\n\t\tawait this.retryAllFailedJobs()\n\t\tconst repeatableJobs = await this.#queue.getRepeatableJobs()\n\t\tawait Promise.all(\n\t\t\trepeatableJobs.filter((job) => job.name === JobNames.CronJob).map((job) => this.#queue.removeRepeatableByKey(job.key)),\n\t\t)\n\t}\n}\n"]}
package/dist/cjs/dbs.cjs CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
 
12
12
 
13
- var _chunkUBQPLHM4cjs = require('./chunk-UBQPLHM4.cjs');
13
+ var _chunk46TJFKXXcjs = require('./chunk-46TJFKXX.cjs');
14
14
 
15
15
 
16
16
 
@@ -23,5 +23,5 @@ var _chunkUBQPLHM4cjs = require('./chunk-UBQPLHM4.cjs');
23
23
 
24
24
 
25
25
 
26
- exports.Conditions = _chunkUBQPLHM4cjs.Conditions; exports.Db = _chunkUBQPLHM4cjs.Db; exports.DbChange = _chunkUBQPLHM4cjs.DbChange; exports.MongoDb = _chunkUBQPLHM4cjs.MongoDb; exports.MongoDbChange = _chunkUBQPLHM4cjs.MongoDbChange; exports.QueryKeys = _chunkUBQPLHM4cjs.QueryKeys; exports.TopicPrefix = _chunkUBQPLHM4cjs.TopicPrefix; exports.mongoDbConfigPipe = _chunkUBQPLHM4cjs.mongoDbConfigPipe; exports.queryParamsPipe = _chunkUBQPLHM4cjs.queryParamsPipe; exports.queryResultsPipe = _chunkUBQPLHM4cjs.queryResultsPipe; exports.wrapQueryParams = _chunkUBQPLHM4cjs.wrapQueryParams;
26
+ exports.Conditions = _chunk46TJFKXXcjs.Conditions; exports.Db = _chunk46TJFKXXcjs.Db; exports.DbChange = _chunk46TJFKXXcjs.DbChange; exports.MongoDb = _chunk46TJFKXXcjs.MongoDb; exports.MongoDbChange = _chunk46TJFKXXcjs.MongoDbChange; exports.QueryKeys = _chunk46TJFKXXcjs.QueryKeys; exports.TopicPrefix = _chunk46TJFKXXcjs.TopicPrefix; exports.mongoDbConfigPipe = _chunk46TJFKXXcjs.mongoDbConfigPipe; exports.queryParamsPipe = _chunk46TJFKXXcjs.queryParamsPipe; exports.queryResultsPipe = _chunk46TJFKXXcjs.queryResultsPipe; exports.wrapQueryParams = _chunk46TJFKXXcjs.wrapQueryParams;
27
27
  //# sourceMappingURL=dbs.cjs.map
@@ -8,7 +8,7 @@
8
8
 
9
9
 
10
10
 
11
- var _chunkUBQPLHM4cjs = require('./chunk-UBQPLHM4.cjs');
11
+ var _chunk46TJFKXXcjs = require('./chunk-46TJFKXX.cjs');
12
12
 
13
13
 
14
14
 
@@ -19,5 +19,5 @@ var _chunkUBQPLHM4cjs = require('./chunk-UBQPLHM4.cjs');
19
19
 
20
20
 
21
21
 
22
- exports.AuthorizationExpired = _chunkUBQPLHM4cjs.AuthorizationExpired; exports.BadRequestError = _chunkUBQPLHM4cjs.BadRequestError; exports.EquippedError = _chunkUBQPLHM4cjs.EquippedError; exports.NotAuthenticatedError = _chunkUBQPLHM4cjs.NotAuthenticatedError; exports.NotAuthorizedError = _chunkUBQPLHM4cjs.NotAuthorizedError; exports.NotFoundError = _chunkUBQPLHM4cjs.NotFoundError; exports.RefreshTokenMisusedError = _chunkUBQPLHM4cjs.RefreshTokenMisusedError; exports.RequestError = _chunkUBQPLHM4cjs.RequestError; exports.ValidationError = _chunkUBQPLHM4cjs.ValidationError;
22
+ exports.AuthorizationExpired = _chunk46TJFKXXcjs.AuthorizationExpired; exports.BadRequestError = _chunk46TJFKXXcjs.BadRequestError; exports.EquippedError = _chunk46TJFKXXcjs.EquippedError; exports.NotAuthenticatedError = _chunk46TJFKXXcjs.NotAuthenticatedError; exports.NotAuthorizedError = _chunk46TJFKXXcjs.NotAuthorizedError; exports.NotFoundError = _chunk46TJFKXXcjs.NotFoundError; exports.RefreshTokenMisusedError = _chunk46TJFKXXcjs.RefreshTokenMisusedError; exports.RequestError = _chunk46TJFKXXcjs.RequestError; exports.ValidationError = _chunk46TJFKXXcjs.ValidationError;
23
23
  //# sourceMappingURL=errors.cjs.map
@@ -5,7 +5,7 @@
5
5
 
6
6
 
7
7
 
8
- var _chunkUBQPLHM4cjs = require('./chunk-UBQPLHM4.cjs');
8
+ var _chunk46TJFKXXcjs = require('./chunk-46TJFKXX.cjs');
9
9
 
10
10
 
11
11
 
@@ -13,5 +13,5 @@ var _chunkUBQPLHM4cjs = require('./chunk-UBQPLHM4.cjs');
13
13
 
14
14
 
15
15
 
16
- exports.DefaultSubscribeOptions = _chunkUBQPLHM4cjs.DefaultSubscribeOptions; exports.EventBus = _chunkUBQPLHM4cjs.EventBus; exports.KafkaEventBus = _chunkUBQPLHM4cjs.KafkaEventBus; exports.RabbitMQEventBus = _chunkUBQPLHM4cjs.RabbitMQEventBus; exports.kafkaConfigPipe = _chunkUBQPLHM4cjs.kafkaConfigPipe; exports.rabbitmqConfigPipe = _chunkUBQPLHM4cjs.rabbitmqConfigPipe;
16
+ exports.DefaultSubscribeOptions = _chunk46TJFKXXcjs.DefaultSubscribeOptions; exports.EventBus = _chunk46TJFKXXcjs.EventBus; exports.KafkaEventBus = _chunk46TJFKXXcjs.KafkaEventBus; exports.RabbitMQEventBus = _chunk46TJFKXXcjs.RabbitMQEventBus; exports.kafkaConfigPipe = _chunk46TJFKXXcjs.kafkaConfigPipe; exports.rabbitmqConfigPipe = _chunk46TJFKXXcjs.rabbitmqConfigPipe;
17
17
  //# sourceMappingURL=events.cjs.map
@@ -1,7 +1,7 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
- var _chunkUBQPLHM4cjs = require('./chunk-UBQPLHM4.cjs');
3
+ var _chunk46TJFKXXcjs = require('./chunk-46TJFKXX.cjs');
4
4
 
5
5
 
6
- exports.Instance = _chunkUBQPLHM4cjs.Instance;
6
+ exports.Instance = _chunk46TJFKXXcjs.Instance;
7
7
  //# sourceMappingURL=index.cjs.map
package/dist/cjs/jobs.cjs CHANGED
@@ -1,9 +1,9 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
3
 
4
- var _chunkUBQPLHM4cjs = require('./chunk-UBQPLHM4.cjs');
4
+ var _chunk46TJFKXXcjs = require('./chunk-46TJFKXX.cjs');
5
5
 
6
6
 
7
7
 
8
- exports.RedisJob = _chunkUBQPLHM4cjs.RedisJob; exports.redisJobsConfigPipe = _chunkUBQPLHM4cjs.redisJobsConfigPipe;
8
+ exports.RedisJob = _chunk46TJFKXXcjs.RedisJob; exports.redisJobsConfigPipe = _chunk46TJFKXXcjs.redisJobsConfigPipe;
9
9
  //# sourceMappingURL=jobs.cjs.map
@@ -17,7 +17,7 @@
17
17
 
18
18
 
19
19
 
20
- var _chunkUBQPLHM4cjs = require('./chunk-UBQPLHM4.cjs');
20
+ var _chunk46TJFKXXcjs = require('./chunk-46TJFKXX.cjs');
21
21
 
22
22
 
23
23
 
@@ -37,5 +37,5 @@ var _chunkUBQPLHM4cjs = require('./chunk-UBQPLHM4.cjs');
37
37
 
38
38
 
39
39
 
40
- exports.BaseApiKeysUtility = _chunkUBQPLHM4cjs.BaseApiKeysUtility; exports.BaseTokensUtility = _chunkUBQPLHM4cjs.BaseTokensUtility; exports.CacheTokensUtility = _chunkUBQPLHM4cjs.CacheTokensUtility; exports.ExpressServer = _chunkUBQPLHM4cjs.ExpressServer; exports.FastifyServer = _chunkUBQPLHM4cjs.FastifyServer; exports.Methods = _chunkUBQPLHM4cjs.Methods; exports.Request = _chunkUBQPLHM4cjs.Request; exports.Response = _chunkUBQPLHM4cjs.Response; exports.Router = _chunkUBQPLHM4cjs.Router; exports.Server = _chunkUBQPLHM4cjs.Server; exports.StatusCodes = _chunkUBQPLHM4cjs.StatusCodes; exports.makeErrorMiddleware = _chunkUBQPLHM4cjs.makeErrorMiddleware; exports.makeMiddleware = _chunkUBQPLHM4cjs.makeMiddleware; exports.requireApiKeyUser = _chunkUBQPLHM4cjs.requireApiKeyUser; exports.requireAuthUser = _chunkUBQPLHM4cjs.requireAuthUser; exports.requireAuthorizationUser = _chunkUBQPLHM4cjs.requireAuthorizationUser; exports.requireRefreshTokenUser = _chunkUBQPLHM4cjs.requireRefreshTokenUser; exports.serverPipe = _chunkUBQPLHM4cjs.serverPipe;
40
+ exports.BaseApiKeysUtility = _chunk46TJFKXXcjs.BaseApiKeysUtility; exports.BaseTokensUtility = _chunk46TJFKXXcjs.BaseTokensUtility; exports.CacheTokensUtility = _chunk46TJFKXXcjs.CacheTokensUtility; exports.ExpressServer = _chunk46TJFKXXcjs.ExpressServer; exports.FastifyServer = _chunk46TJFKXXcjs.FastifyServer; exports.Methods = _chunk46TJFKXXcjs.Methods; exports.Request = _chunk46TJFKXXcjs.Request; exports.Response = _chunk46TJFKXXcjs.Response; exports.Router = _chunk46TJFKXXcjs.Router; exports.Server = _chunk46TJFKXXcjs.Server; exports.StatusCodes = _chunk46TJFKXXcjs.StatusCodes; exports.makeErrorMiddleware = _chunk46TJFKXXcjs.makeErrorMiddleware; exports.makeMiddleware = _chunk46TJFKXXcjs.makeMiddleware; exports.requireApiKeyUser = _chunk46TJFKXXcjs.requireApiKeyUser; exports.requireAuthUser = _chunk46TJFKXXcjs.requireAuthUser; exports.requireAuthorizationUser = _chunk46TJFKXXcjs.requireAuthorizationUser; exports.requireRefreshTokenUser = _chunk46TJFKXXcjs.requireRefreshTokenUser; exports.serverPipe = _chunk46TJFKXXcjs.serverPipe;
41
41
  //# sourceMappingURL=server.cjs.map
@@ -7,7 +7,7 @@
7
7
 
8
8
 
9
9
 
10
- var _chunkUBQPLHM4cjs = require('./chunk-UBQPLHM4.cjs');
10
+ var _chunk46TJFKXXcjs = require('./chunk-46TJFKXX.cjs');
11
11
 
12
12
 
13
13
 
@@ -17,5 +17,5 @@ var _chunkUBQPLHM4cjs = require('./chunk-UBQPLHM4.cjs');
17
17
 
18
18
 
19
19
 
20
- exports.AuthProviders = _chunkUBQPLHM4cjs.authProviders_exports; exports.Hash = _chunkUBQPLHM4cjs.hash_exports; exports.Random = _chunkUBQPLHM4cjs.random_exports; exports.getMediaDuration = _chunkUBQPLHM4cjs.getMediaDuration; exports.parseJSONObject = _chunkUBQPLHM4cjs.parseJSONObject; exports.parseJSONValue = _chunkUBQPLHM4cjs.parseJSONValue; exports.retry = _chunkUBQPLHM4cjs.retry; exports.sleep = _chunkUBQPLHM4cjs.sleep;
20
+ exports.AuthProviders = _chunk46TJFKXXcjs.authProviders_exports; exports.Hash = _chunk46TJFKXXcjs.hash_exports; exports.Random = _chunk46TJFKXXcjs.random_exports; exports.getMediaDuration = _chunk46TJFKXXcjs.getMediaDuration; exports.parseJSONObject = _chunk46TJFKXXcjs.parseJSONObject; exports.parseJSONValue = _chunk46TJFKXXcjs.parseJSONValue; exports.retry = _chunk46TJFKXXcjs.retry; exports.sleep = _chunk46TJFKXXcjs.sleep;
21
21
  //# sourceMappingURL=utilities.cjs.map
@@ -2,10 +2,10 @@
2
2
 
3
3
 
4
4
 
5
- var _chunkUBQPLHM4cjs = require('./chunk-UBQPLHM4.cjs');
5
+ var _chunk46TJFKXXcjs = require('./chunk-46TJFKXX.cjs');
6
6
 
7
7
 
8
8
 
9
9
 
10
- exports.pipeErrorToValidationError = _chunkUBQPLHM4cjs.pipeErrorToValidationError; exports.validate = _chunkUBQPLHM4cjs.validate; exports.ve = _chunkUBQPLHM4cjs.valleyed_exports;
10
+ exports.pipeErrorToValidationError = _chunk46TJFKXXcjs.pipeErrorToValidationError; exports.validate = _chunk46TJFKXXcjs.validate; exports.ve = _chunk46TJFKXXcjs.valleyed_exports;
11
11
  //# sourceMappingURL=validations.cjs.map
@@ -1,2 +1,2 @@
1
- import{O as c,a,b}from"./chunk-WKZT3EQO.min.mjs";export{a as Cache,c as RedisCache,b as redisConfigPipe};
1
+ import{O as c,a,b}from"./chunk-7LLFKFXJ.min.mjs";export{a as Cache,c as RedisCache,b as redisConfigPipe};
2
2
  //# sourceMappingURL=cache.min.mjs.map
@@ -2,7 +2,7 @@ import {
2
2
  Cache,
3
3
  RedisCache,
4
4
  redisConfigPipe
5
- } from "./chunk-SHJLDB4M.mjs";
5
+ } from "./chunk-DXTIVHEC.mjs";
6
6
  export {
7
7
  Cache,
8
8
  RedisCache,