arkos 1.7.4-rc → 1.7.5-rc

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 (36) hide show
  1. package/dist/cjs/components/arkos-gateway/arkos-gateway.js +8 -3
  2. package/dist/cjs/components/arkos-gateway/arkos-gateway.js.map +1 -1
  3. package/dist/cjs/components/arkos-gateway/types.js.map +1 -1
  4. package/dist/cjs/exports/websockets.js.map +1 -1
  5. package/dist/cjs/modules/auth/auth.router.js +2 -1
  6. package/dist/cjs/modules/auth/auth.router.js.map +1 -1
  7. package/dist/cjs/modules/file-upload/file-upload.router.js +2 -1
  8. package/dist/cjs/modules/file-upload/file-upload.router.js.map +1 -1
  9. package/dist/cjs/utils/arkos-router/arkos-router-openapi-manager.js.map +1 -1
  10. package/dist/cjs/utils/arkos-router/route-config-validator.js +5 -5
  11. package/dist/cjs/utils/arkos-router/route-config-validator.js.map +1 -1
  12. package/dist/cjs/utils/cli/generate.js +8 -3
  13. package/dist/cjs/utils/cli/generate.js.map +1 -1
  14. package/dist/cjs/utils/cli/utils/cli.helpers.js +1 -1
  15. package/dist/cjs/utils/dynamic-loader.js +2 -2
  16. package/dist/cjs/utils/dynamic-loader.js.map +1 -1
  17. package/dist/esm/components/arkos-gateway/arkos-gateway.js +8 -3
  18. package/dist/esm/components/arkos-gateway/arkos-gateway.js.map +1 -1
  19. package/dist/esm/components/arkos-gateway/types.js.map +1 -1
  20. package/dist/esm/exports/websockets.js.map +1 -1
  21. package/dist/esm/modules/auth/auth.router.js +2 -1
  22. package/dist/esm/modules/auth/auth.router.js.map +1 -1
  23. package/dist/esm/modules/file-upload/file-upload.router.js +2 -1
  24. package/dist/esm/modules/file-upload/file-upload.router.js.map +1 -1
  25. package/dist/esm/utils/arkos-router/arkos-router-openapi-manager.js.map +1 -1
  26. package/dist/esm/utils/arkos-router/route-config-validator.js +5 -5
  27. package/dist/esm/utils/arkos-router/route-config-validator.js.map +1 -1
  28. package/dist/esm/utils/cli/generate.js +8 -3
  29. package/dist/esm/utils/cli/generate.js.map +1 -1
  30. package/dist/esm/utils/cli/utils/cli.helpers.js +1 -1
  31. package/dist/esm/utils/dynamic-loader.js +2 -2
  32. package/dist/esm/utils/dynamic-loader.js.map +1 -1
  33. package/dist/types/components/arkos-gateway/arkos-gateway.d.ts +6 -5
  34. package/dist/types/components/arkos-gateway/types.d.ts +7 -0
  35. package/dist/types/exports/websockets.d.ts +1 -1
  36. package/package.json +1 -1
@@ -23,6 +23,7 @@ class IArkosGateway {
23
23
  constructor(config) {
24
24
  this.events = [];
25
25
  this.pipes = [];
26
+ this.middlewares = [];
26
27
  this.gateways = [];
27
28
  this.hooks = [];
28
29
  this.config = config;
@@ -39,7 +40,7 @@ class IArkosGateway {
39
40
  this.gateways.push(item);
40
41
  }
41
42
  else if (typeof item === "function") {
42
- this.pipes.push(item);
43
+ this.middlewares.push(item);
43
44
  }
44
45
  else {
45
46
  throw new Error(`Invalid value for gateway.use() — expected an ArkosGateway instance or a middleware function but received "${typeof item}".`);
@@ -106,7 +107,7 @@ class IArkosGateway {
106
107
  io._arkosGatewayRegistered = true;
107
108
  this._register(io, undefined, this.hooks || [], this.pipes || [], options);
108
109
  }
109
- _register(io, parentConfig, inheritedHooks = [], inheritedPipes = [], options = {}) {
110
+ _register(io, parentConfig, inheritedHooks = [], inheritedPipes = [], options = {}, inheritedMiddlewares = []) {
110
111
  options.store = options.store ?? memory_gateway_store_1.defaultGatewayStore;
111
112
  const { store } = options;
112
113
  const parentName = parentConfig?.name;
@@ -125,6 +126,7 @@ class IArkosGateway {
125
126
  parentConfig?.authentication !== false;
126
127
  const resolvedRateLimit = this.config.rateLimit ?? parentConfig?.rateLimit;
127
128
  const resolvedHooks = [...inheritedHooks, ...this.hooks];
129
+ const resolvedMiddlewares = [...inheritedMiddlewares, ...this.middlewares];
128
130
  const connectHandlers = resolvedHooks
129
131
  .filter((h) => h.type === "connection")
130
132
  .map((h) => h.handler);
@@ -134,6 +136,9 @@ class IArkosGateway {
134
136
  const errorHandlers = resolvedHooks
135
137
  .filter((h) => h.type === "error")
136
138
  .map((h) => h.handler);
139
+ for (const middleware of resolvedMiddlewares) {
140
+ ns.use((socket, next) => middleware(socket, next));
141
+ }
137
142
  if (resolvedAuth && (0, arkos_config_helpers_1.isAuthenticationEnabled)()) {
138
143
  ns.use(async (socket, next) => {
139
144
  socket = socket;
@@ -338,7 +343,7 @@ For further help see https://www.arkosjs.com/docs/core-concepts/authentication/s
338
343
  name: namespaceName,
339
344
  authentication: resolvedAuth,
340
345
  rateLimit: resolvedRateLimit,
341
- }, resolvedHooks, inheritedPipes, options);
346
+ }, resolvedHooks, inheritedPipes, options, resolvedMiddlewares);
342
347
  }
343
348
  }
344
349
  }
@@ -1 +1 @@
1
- {"version":3,"file":"arkos-gateway.js","sourceRoot":"","sources":["../../../../src/components/arkos-gateway/arkos-gateway.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ArkosGatewayConfig,\n ArkosGatewayErrorHandler,\n ArkosGatewayEventConfig,\n ArkosGatewayEventEntry,\n ArkosGatewayHandler,\n ArkosGatewayHookHandler,\n ArkosGatewayHookType,\n ArkosGatewayPipe,\n ArkosGatewayConnectionHandler,\n ArkosSocket,\n ArkosGatewayRegisterOptions,\n ArkosBroadcastOperator,\n ArkosEmitTarget,\n} from \"./types\";\nimport { Validator } from \"../../types/validation/validator\";\nimport { BroadcastOperator, Namespace, Server } from \"socket.io\";\nimport { authActionService, authService } from \"../../exports/services\";\nimport { checkRateLimit, clearRateLimitForSocket } from \"./utils/rate-limiter\";\nimport {\n handleArkosGatewayErrors,\n runArkosGatewayPipes,\n handleGatewayEventLog,\n handleGatewayLifecycleLog,\n} from \"./utils/helpers\";\nimport authHookManager from \"../../modules/auth/utils/auth-hooks-manager\";\nimport { getArkosConfig } from \"../../server\";\nimport validationManager from \"../../types/validation/validation-manager\";\nimport { loginRequiredError } from \"../../modules/auth/utils/auth-error-objects\";\nimport errorPrettifier from \"../../modules/base/utils/error-prettifier\";\nimport deepmerge from \"../../utils/helpers/deepmerge.helper\";\nimport { defaultGatewayStore } from \"./utils/memory-gateway-store\";\nimport { ArkosBroadcastOperatorImpl, mountArkosSocketExtensions } from \"./socket-extensions\";\nimport {\n isAuthenticationEnabled,\n isUsingAuthentication,\n} from \"../../utils/helpers/arkos-config.helpers\";\nimport ExitError from \"../../utils/helpers/exit-error\";\nimport { getUserFileExtension } from \"../../utils/helpers/fs.helpers\";\nimport {\n BadRequestError,\n TooManyRequestsError,\n} from \"../../modules/error-handler/utils/errors\";\n\nexport class IArkosGateway {\n private config: ArkosGatewayConfig;\n private events: ArkosGatewayEventEntry[] = [];\n private pipes: ArkosGatewayPipe[] = [];\n private gateways: IArkosGateway[] = [];\n private hooks: {\n type: ArkosGatewayHookType;\n handler: ArkosGatewayHookHandler;\n }[] = [];\n private _nsp!: Namespace\n\n constructor(config: ArkosGatewayConfig) {\n this.config = config;\n this.config.name = config.name ?? \"web-socket\";\n }\n\n get nsp(): Omit<Namespace, keyof ArkosEmitTarget | keyof BroadcastOperator<any, any>> & ArkosBroadcastOperator {\n if (!this._nsp) throw new Error(`gateway.nsp accessed before register()`);\n return new ArkosBroadcastOperatorImpl(this._nsp.sockets, this._nsp) as any;\n }\n\n /**\n * Register a Socket.io connection-level middleware — runs before a socket\n * is accepted into this gateway's namespace. Also accepts a child\n * `ArkosGateway` which will inherit this gateway's name as prefix along\n * with its auth, rateLimit, and pipes.\n *\n * @example\n * chatGateway.use((socket, next) => {\n * console.log(\"incoming connection\", socket.id)\n * })\n *\n * // nested gateway\n * chatGateway.use(notificationsGateway)\n */\n use(...middlewareOrGateway: Array<ArkosGatewayPipe | IArkosGateway>): this {\n for (const item of middlewareOrGateway) {\n if (item instanceof IArkosGateway) {\n this.gateways.push(item);\n } else if (typeof item === \"function\") {\n this.pipes.push(item as ArkosGatewayPipe);\n } else {\n throw new Error(\n `Invalid value for gateway.use() — expected an ArkosGateway instance or a middleware function but received \"${typeof item}\".`\n );\n }\n }\n return this;\n }\n\n /**\n * Register a pipe — middleware that runs before event handlers.\n *\n * When called with a function only, the pipe runs before every event\n * handler in this gateway and drills down to child gateways.\n *\n * When called with an event config object, the pipe runs only for that\n * specific event.\n *\n * @example\n * // runs before every event in this gateway\n * chatGateway.pipe((socket, data) => {\n * })\n *\n * // runs only before \"send_message\"\n * chatGateway.pipe({ event: \"send_message\" }, (socket, data) => {\n * })\n */\n pipe(fn: ArkosGatewayPipe): this;\n pipe<TSchema extends Validator = any>(\n eventConfig: { event: string },\n fn: ArkosGatewayPipe\n ): this;\n pipe<TSchema extends Validator = any>(\n fnOrConfig: ArkosGatewayPipe | ArkosGatewayEventConfig<TSchema>,\n fn?: ArkosGatewayPipe\n ): this {\n if (typeof fnOrConfig === \"function\") {\n this.pipes.push(fnOrConfig);\n } else if (fnOrConfig && typeof fnOrConfig === \"object\" && fn) {\n const entry = this.events.find(\n (e) => e.config.event === fnOrConfig.event\n );\n if (entry) {\n entry.pipes = entry.pipes ?? [];\n entry.pipes.push(fn);\n } else {\n this.events.push({\n config: { event: fnOrConfig.event, _pipeOnly: true } as any,\n handler: null as any,\n pipes: [fn],\n });\n }\n } else {\n throw new Error(\n `Invalid arguments for gateway.pipe() — pass a middleware function, or an event config object followed by a middleware function.`\n );\n }\n return this;\n }\n\n /**\n * Register an event handler.\n *\n * @example\n * chatGateway.on(\n * { event: \"send_message\", validation: MessageSchema, ack: true },\n * (socket, data, ack) => {\n * socket.to(data.room).emit(\"receive_message\", data)\n * ack?.({ status: \"ok\" })\n * }\n * )\n */\n on<TSchema extends Validator = any>(\n eventConfig: ArkosGatewayEventConfig<TSchema>,\n handler: ArkosGatewayHandler\n ): this {\n if (eventConfig.disabled) return this;\n\n if (eventConfig.authorization && this.config.authentication === false) {\n throw new Error(\n `Event \"${eventConfig.event}\" on \"${this.config.name}\" gateway defines authorization rules ` +\n `but the gateway has authentication: false. Enable authentication on the gateway to use per-event authentication.`\n );\n }\n\n const deferred = this.events.find(\n (e) => (e.config as any)._pipeOnly && e.config.event === eventConfig.event\n );\n\n const entry: ArkosGatewayEventEntry = {\n config: eventConfig,\n handler,\n pipes: [...this.pipes, ...(deferred?.pipes ?? [])],\n };\n\n if (deferred) {\n const idx = this.events.indexOf(deferred);\n this.events.splice(idx, 1, entry);\n } else {\n this.events.push(entry);\n }\n\n if (typeof eventConfig?.authorization == \"object\")\n // To reuse later on\n (eventConfig.authorization as any)._authAction = authActionService.add(\n eventConfig.authorization!.action,\n eventConfig.authorization!.resource,\n {\n [eventConfig.authorization!.action]: eventConfig.authorization?.rule,\n }\n );\n\n return this;\n }\n\n /**\n * Register a lifecycle hook.\n *\n * - `\"connection\"` — called after a socket successfully connects and passes authentication.\n * - `\"disconnect\"` — called when a socket disconnects.\n * - `\"error\"` — called when an error is thrown inside any event handler.\n * If not registered, Arkos emits a default `\"error\"` event to the socket.\n *\n * @example\n * chatGateway.hook(\"connection\", (socket) => {\n * console.log(\"connected\", socket.user.id)\n * })\n *\n * chatGateway.hook(\"error\", (err, socket) => {\n * socket.emit(\"error\", { message: err.message })\n * })\n */\n hook(type: \"connection\", handler: ArkosGatewayConnectionHandler): this;\n hook(type: \"disconnect\", handler: ArkosGatewayConnectionHandler): this;\n hook(type: \"error\", handler: ArkosGatewayErrorHandler): this;\n hook(\n type: ArkosGatewayHookType,\n handler: ArkosGatewayConnectionHandler | ArkosGatewayErrorHandler\n ): this {\n this.hooks.push({ type, handler });\n return this;\n }\n\n /**\n * Wire this gateway into a Socket.io `Server` instance.\n * Registers the namespace, auth middleware, rate limiting, pipes,\n * and all event handlers — then recurses into child gateways.\n *\n * @example\n * const io = new Server(server)\n * chatGateway.register(io)\n */\n register(io: Server, options: ArkosGatewayRegisterOptions = {}): void {\n if ((io as any)._arkosGatewayRegistered)\n throw new Error(\n `The method gateway.register() can only be called once per io server instance. Use gateway.use() to compose gateways, see https://www.arkosjs.com/docs/guides/web-sockets/setup.`\n );\n (io as any)._arkosGatewayRegistered = true;\n this._register(io, undefined, this.hooks || [], this.pipes || [], options);\n }\n\n private _register(\n io: Server,\n parentConfig?: ArkosGatewayConfig,\n inheritedHooks: {\n type: ArkosGatewayHookType;\n handler: ArkosGatewayHookHandler;\n }[] = [],\n inheritedPipes: ArkosGatewayPipe[] = [],\n options: ArkosGatewayRegisterOptions = {}\n ): void {\n options.store = options.store ?? defaultGatewayStore;\n const { store } = options;\n\n const parentName = parentConfig?.name;\n const ownName = this.config.name;\n this.config = deepmerge(parentConfig || {}, this.config, {\n arrayMerge: (_, sourceArray) => sourceArray,\n });\n this.config.name = ownName;\n const localConfig = this.config;\n\n const namespaceName = parentName\n ? `${parentName.replace(/\\/$/, \"\")}/${ownName.replace(/^\\//, \"\")}`\n : (ownName ?? \"\");\n\n const ns = io.of(namespaceName);\n this._nsp = ns;\n\n const resolvedAuth =\n this.config.authentication !== false &&\n parentConfig?.authentication !== false;\n\n const resolvedRateLimit = this.config.rateLimit ?? parentConfig?.rateLimit;\n const resolvedHooks = [...inheritedHooks, ...this.hooks];\n\n const connectHandlers = resolvedHooks\n .filter((h) => h.type === \"connection\")\n .map((h) => h.handler as ArkosGatewayConnectionHandler);\n\n const disconnectHandlers = resolvedHooks\n .filter((h) => h.type === \"disconnect\")\n .map((h) => h.handler as ArkosGatewayConnectionHandler);\n\n const errorHandlers = resolvedHooks\n .filter((h) => h.type === \"error\")\n .map((h) => h.handler as ArkosGatewayErrorHandler);\n\n if (resolvedAuth && isAuthenticationEnabled()) {\n ns.use(async (socket: any, next) => {\n socket = socket as ArkosSocket;\n const startTime = new Date().getTime();\n try {\n await authHookManager.runAuthenticate(\n {\n context: socket,\n done: (err?: any) => {\n if (err) throw err;\n next();\n },\n },\n async (socket) => {\n const user = await authService.getAuthenticatedUser(socket);\n if (!user) throw loginRequiredError;\n return user;\n },\n \"currentUser\"\n );\n } catch (err: any) {\n handleArkosGatewayErrors(err, socket, errorHandlers, {\n startTime,\n namespace: this.config.name,\n event: \"authentication\",\n });\n next(err);\n }\n });\n } else if (\n (this.config.authentication || parentConfig?.authentication) &&\n !isUsingAuthentication()\n )\n throw ExitError(\n `Trying to authenticate gateway ${this.config.name ? `${this.config.name}` : \"\"} without choosing an authentication mode under arkos.config.${getUserFileExtension()}.\n\nFor further help see https://www.arkosjs.com/docs/core-concepts/authentication/setup.`\n );\n\n ns.on(\"connection\", async (s) => {\n const socket = s as ArkosSocket;\n socket.locals = {};\n\n socket._arkos = { store, gatewayConfig: localConfig };\n mountArkosSocketExtensions(socket);\n\n handleGatewayLifecycleLog(this.config.name, \"connected\", socket.id);\n const connectionStartTime = new Date().getTime();\n\n if (socket.currentUser?.id)\n socket.join(`arkos::user:${socket.currentUser.id}`);\n\n try {\n for (const handler of connectHandlers) await handler(socket);\n } catch (err: any) {\n handleArkosGatewayErrors(err, socket, [], {\n startTime: connectionStartTime,\n namespace: this.config.name,\n event: \"connection\",\n });\n return;\n }\n\n socket.on(\"disconnect\", async () => {\n handleGatewayLifecycleLog(this.config.name, \"disconnected\", socket.id);\n\n await clearRateLimitForSocket(socket.id, store);\n try {\n for (const handler of disconnectHandlers) await handler(socket);\n } catch (err) {\n handleArkosGatewayErrors(err, socket, [], {\n startTime: connectionStartTime,\n namespace: this.config.name,\n event: \"disconnection\",\n });\n }\n });\n\n for (const entry of this.events) {\n if ((entry.config as any)._pipeOnly || !entry.handler) continue;\n\n const { config: eventConfig, handler, pipes: eventPipes = [] } = entry;\n\n if (\n (this.config.authentication || parentConfig?.authentication) &&\n !isUsingAuthentication()\n )\n throw ExitError(\n `Trying to use authorization gateway.on(\"${eventConfig.event}\") without choosing an authentication mode under arkos.config.${getUserFileExtension()}.\n\nFor further help see https://www.arkosjs.com/docs/core-concepts/authentication/setup.`\n );\n\n socket.on(eventConfig.event, async (...args: any[]) => {\n socket.locals = {};\n const startTime = new Date().getTime();\n let data = args[0];\n\n const ack =\n typeof args[args.length - 1] === \"function\"\n ? args[args.length - 1]\n : undefined;\n\n let ackCalled = false;\n const wrappedAck = ack\n ? (...response: any) => {\n ackCalled = true;\n ack(...response);\n }\n : undefined;\n\n function resolveDedup() {\n if (\n eventConfig.dedup === false ||\n localConfig.dedup === false ||\n parentConfig?.dedup === false\n )\n return null;\n\n return {\n enabled: true,\n ttl: 3600,\n ...parentConfig?.dedup,\n ...localConfig?.dedup,\n ...eventConfig?.dedup,\n };\n }\n\n const dedupOpt = resolveDedup();\n\n try {\n const meta = data?._meta || {};\n const resolvedMaxAge =\n eventConfig.maxAge ?? localConfig.maxAge ?? parentConfig?.maxAge;\n\n if (resolvedMaxAge && !meta.timestamp)\n throw new BadRequestError(\n \"Missing _meta.timestamp for maxAge deduplication\"\n );\n\n if (meta.timestamp !== undefined) {\n const timestamp = new Date(meta.timestamp);\n\n if (isNaN(timestamp.getTime())) {\n throw new BadRequestError(\n \"Invalid data._meta.timestamp\",\n \"InvalidTimestamp\"\n );\n }\n\n const age = Date.now() - timestamp.getTime();\n\n if (age + 1000 < 0)\n throw new BadRequestError(\n \"Timestamp is in the future\",\n \"FutureTimestamp\"\n );\n\n if (resolvedMaxAge && age > resolvedMaxAge) {\n throw new BadRequestError(\"Message is too old\", \"StaleMessage\");\n }\n }\n\n if (dedupOpt && dedupOpt?.enabled !== false) {\n if (!meta?.mid)\n throw new BadRequestError(\n \"Missing data._meta.mid in your payload for deduplication\",\n \"MissingDedupMessageId\",\n { data }\n );\n\n if (typeof meta.mid !== \"string\" || meta.mid.trim() === \"\")\n throw new BadRequestError(\n \"Invalid data._meta.mid, it must be a non-empty string\",\n \"InvalidMessageId\"\n );\n\n const key = `arkos::dedup:${eventConfig.event}:${meta.mid}`;\n const ttl = dedupOpt?.ttl ?? 3600;\n\n const acquired = await store.setIfNotExists(key, ttl);\n\n if (acquired === false)\n return wrappedAck?.({\n success: true,\n duplicate: true,\n });\n\n const { _meta, ...payload } = data;\n data = payload;\n\n socket.meta = meta;\n }\n\n const rateLimitOptions = eventConfig.rateLimit ?? resolvedRateLimit;\n if (rateLimitOptions !== false) {\n const { allowed, retryAfter } = await checkRateLimit(\n socket.id,\n eventConfig.event,\n rateLimitOptions || {},\n options.store!\n );\n if (!allowed) {\n throw new TooManyRequestsError(undefined, undefined, {\n retryAfter,\n });\n }\n }\n\n if (\n typeof eventConfig.authorization === \"object\" &&\n resolvedAuth &&\n isAuthenticationEnabled()\n ) {\n await authHookManager.runAuthorize(\n { context: socket, done: () => { } },\n (eventConfig?.authorization as any)?._authAction,\n \"currentUser\"\n );\n }\n\n if (eventConfig.validation) {\n const arkosConfig = getArkosConfig();\n const {\n validationFn,\n isValidValidator,\n validatorName,\n validatorNameType,\n } = validationManager;\n\n if (!isValidValidator(eventConfig.validation))\n throw new Error(\n `Your validation resolver is set to ${arkosConfig.validation!.resolver}, ` +\n `please provide a valid ${validatorName} in order to use { validation: ${validatorNameType} } ` +\n `under event handler \"${eventConfig.event}\" in \"${this.config.name}\" gateway.`\n );\n\n const shouldValidate = validationManager.shouldValidate(\n eventConfig.validation,\n data\n );\n\n if (shouldValidate === \"prohibit\")\n throw new BadRequestError(\n \"Event data is not allowed for this event.\",\n \"EventDataNotAllowed\",\n { data }\n );\n else if (shouldValidate === \"passthrough\") data = data;\n else {\n try {\n data = await (validationFn as any)(\n eventConfig.validation,\n data\n );\n } catch (err: any) {\n const { validationConfig } = validationManager;\n\n const resolver = validationConfig?.resolver;\n const isZod = validationConfig?.resolver === \"zod\";\n\n const prettifiedError = errorPrettifier.prettify(\n resolver as any,\n err\n );\n const error = prettifiedError[0];\n\n throw new BadRequestError(\n error.message,\n `InvalidData`,\n isZod ? err.format() : err\n );\n }\n }\n }\n\n socket.data = data;\n\n await runArkosGatewayPipes(\n [...inheritedPipes, ...eventPipes],\n socket,\n data\n );\n\n await handler(socket, data, wrappedAck);\n\n handleGatewayEventLog(\n this.config.name,\n eventConfig.event,\n 200,\n startTime\n );\n\n if (eventConfig.ack && ack && !ackCalled) {\n ack({ success: true });\n }\n } catch (err: any) {\n handleArkosGatewayErrors(\n err,\n socket,\n errorHandlers,\n {\n startTime,\n namespace: this.config.name,\n event: eventConfig.event,\n },\n ack\n );\n }\n });\n }\n });\n\n for (const child of this.gateways) {\n child._register(\n io,\n {\n name: namespaceName,\n authentication: resolvedAuth,\n rateLimit: resolvedRateLimit,\n },\n resolvedHooks,\n inheritedPipes,\n options\n );\n }\n }\n}\n\n/**\n * Creates an Arkos WebSocket Gateway backed by Socket.io.\n *\n * Handles authentication, validation, rate limiting, pipes,\n * error handling, and nested gateways — all declaratively.\n * Enhances every connected socket with `socket.user()`, `socket.peer()`,\n * `socket.retry()`, and automatic `_meta` injection on outgoing emits.\n *\n * @example\n * ```ts\n * const chatGateway = ArkosGateway({\n * name: \"chat\",\n * authentication: true,\n * rateLimit: { windowMs: 60_000, max: 200 },\n * })\n *\n * chatGateway.on(\n * { event: \"send_message\", validation: MessageSchema, ack: true },\n * (socket, data, ack) => {\n * socket.to(data.room).emit(\"receive_message\", data)\n * ack?.({ status: \"ok\" })\n * }\n * )\n * ```\n * @since 1.7.0-canary.18\n * @see {@link https://www.arkosjs.com/docs/core-concepts/components/gateways}\n */\nfunction ArkosGateway(config: ArkosGatewayConfig) {\n return new IArkosGateway(config);\n}\n\nexport default ArkosGateway;\n"]}
1
+ {"version":3,"file":"arkos-gateway.js","sourceRoot":"","sources":["../../../../src/components/arkos-gateway/arkos-gateway.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ArkosGatewayConfig,\n ArkosGatewayErrorHandler,\n ArkosGatewayEventConfig,\n ArkosGatewayEventEntry,\n ArkosGatewayHandler,\n ArkosGatewayHookHandler,\n ArkosGatewayHookType,\n ArkosGatewayPipe,\n ArkosGatewayMiddleware,\n ArkosGatewayConnectionHandler,\n ArkosSocket,\n ArkosGatewayRegisterOptions,\n ArkosBroadcastOperator,\n ArkosEmitTarget,\n} from \"./types\";\nimport { Validator } from \"../../types/validation/validator\";\nimport { BroadcastOperator, Namespace, Server } from \"socket.io\";\nimport { authActionService, authService } from \"../../exports/services\";\nimport { checkRateLimit, clearRateLimitForSocket } from \"./utils/rate-limiter\";\nimport {\n handleArkosGatewayErrors,\n runArkosGatewayPipes,\n handleGatewayEventLog,\n handleGatewayLifecycleLog,\n} from \"./utils/helpers\";\nimport authHookManager from \"../../modules/auth/utils/auth-hooks-manager\";\nimport { getArkosConfig } from \"../../server\";\nimport validationManager from \"../../types/validation/validation-manager\";\nimport { loginRequiredError } from \"../../modules/auth/utils/auth-error-objects\";\nimport errorPrettifier from \"../../modules/base/utils/error-prettifier\";\nimport deepmerge from \"../../utils/helpers/deepmerge.helper\";\nimport { defaultGatewayStore } from \"./utils/memory-gateway-store\";\nimport { ArkosBroadcastOperatorImpl, mountArkosSocketExtensions } from \"./socket-extensions\";\nimport {\n isAuthenticationEnabled,\n isUsingAuthentication,\n} from \"../../utils/helpers/arkos-config.helpers\";\nimport ExitError from \"../../utils/helpers/exit-error\";\nimport { getUserFileExtension } from \"../../utils/helpers/fs.helpers\";\nimport {\n BadRequestError,\n TooManyRequestsError,\n} from \"../../modules/error-handler/utils/errors\";\n\nexport class IArkosGateway {\n private config: ArkosGatewayConfig;\n private events: ArkosGatewayEventEntry[] = [];\n private pipes: ArkosGatewayPipe[] = [];\n private middlewares: ArkosGatewayMiddleware[] = [];\n private gateways: IArkosGateway[] = [];\n private hooks: {\n type: ArkosGatewayHookType;\n handler: ArkosGatewayHookHandler;\n }[] = [];\n private _nsp!: Namespace\n\n constructor(config: ArkosGatewayConfig) {\n this.config = config;\n this.config.name = config.name ?? \"web-socket\";\n }\n\n get nsp(): Omit<Namespace, keyof ArkosEmitTarget | keyof BroadcastOperator<any, any>> & ArkosBroadcastOperator {\n if (!this._nsp) throw new Error(`gateway.nsp accessed before register()`);\n return new ArkosBroadcastOperatorImpl(this._nsp.sockets, this._nsp) as any;\n }\n\n /**\n * Register a Socket.io connection-level middleware — runs before a socket\n * is accepted into this gateway's namespace, and before authentication.\n * Also accepts a child `ArkosGateway` which will inherit this gateway's\n * name as prefix along with its auth, rateLimit, and pipes.\n *\n * @example\n * chatGateway.use((socket, next) => {\n * console.log(\"incoming connection\", socket.id)\n * })\n *\n * // nested gateway\n * chatGateway.use(notificationsGateway)\n */\n use(...middlewareOrGateway: Array<ArkosGatewayMiddleware | IArkosGateway>): this {\n for (const item of middlewareOrGateway) {\n if (item instanceof IArkosGateway) {\n this.gateways.push(item);\n } else if (typeof item === \"function\") {\n this.middlewares.push(item as ArkosGatewayMiddleware);\n } else {\n throw new Error(\n `Invalid value for gateway.use() — expected an ArkosGateway instance or a middleware function but received \"${typeof item}\".`\n );\n }\n }\n return this;\n }\n\n /**\n * Register a pipe — middleware that runs before event handlers.\n *\n * When called with a function only, the pipe runs before every event\n * handler in this gateway and drills down to child gateways.\n *\n * When called with an event config object, the pipe runs only for that\n * specific event.\n *\n * @example\n * // runs before every event in this gateway\n * chatGateway.pipe((socket, data) => {\n * })\n *\n * // runs only before \"send_message\"\n * chatGateway.pipe({ event: \"send_message\" }, (socket, data) => {\n * })\n */\n pipe(fn: ArkosGatewayPipe): this;\n pipe<TSchema extends Validator = any>(\n eventConfig: { event: string },\n fn: ArkosGatewayPipe\n ): this;\n pipe<TSchema extends Validator = any>(\n fnOrConfig: ArkosGatewayPipe | ArkosGatewayEventConfig<TSchema>,\n fn?: ArkosGatewayPipe\n ): this {\n if (typeof fnOrConfig === \"function\") {\n this.pipes.push(fnOrConfig);\n } else if (fnOrConfig && typeof fnOrConfig === \"object\" && fn) {\n const entry = this.events.find(\n (e) => e.config.event === fnOrConfig.event\n );\n if (entry) {\n entry.pipes = entry.pipes ?? [];\n entry.pipes.push(fn);\n } else {\n this.events.push({\n config: { event: fnOrConfig.event, _pipeOnly: true } as any,\n handler: null as any,\n pipes: [fn],\n });\n }\n } else {\n throw new Error(\n `Invalid arguments for gateway.pipe() — pass a middleware function, or an event config object followed by a middleware function.`\n );\n }\n return this;\n }\n\n /**\n * Register an event handler.\n *\n * @example\n * chatGateway.on(\n * { event: \"send_message\", validation: MessageSchema, ack: true },\n * (socket, data, ack) => {\n * socket.to(data.room).emit(\"receive_message\", data)\n * ack?.({ status: \"ok\" })\n * }\n * )\n */\n on<TSchema extends Validator = any>(\n eventConfig: ArkosGatewayEventConfig<TSchema>,\n handler: ArkosGatewayHandler\n ): this {\n if (eventConfig.disabled) return this;\n\n if (eventConfig.authorization && this.config.authentication === false) {\n throw new Error(\n `Event \"${eventConfig.event}\" on \"${this.config.name}\" gateway defines authorization rules ` +\n `but the gateway has authentication: false. Enable authentication on the gateway to use per-event authentication.`\n );\n }\n\n const deferred = this.events.find(\n (e) => (e.config as any)._pipeOnly && e.config.event === eventConfig.event\n );\n\n const entry: ArkosGatewayEventEntry = {\n config: eventConfig,\n handler,\n pipes: [...this.pipes, ...(deferred?.pipes ?? [])],\n };\n\n if (deferred) {\n const idx = this.events.indexOf(deferred);\n this.events.splice(idx, 1, entry);\n } else {\n this.events.push(entry);\n }\n\n if (typeof eventConfig?.authorization == \"object\")\n // To reuse later on\n (eventConfig.authorization as any)._authAction = authActionService.add(\n eventConfig.authorization!.action,\n eventConfig.authorization!.resource,\n {\n [eventConfig.authorization!.action]: eventConfig.authorization?.rule,\n }\n );\n\n return this;\n }\n\n /**\n * Register a lifecycle hook.\n *\n * - `\"connection\"` — called after a socket successfully connects and passes authentication.\n * - `\"disconnect\"` — called when a socket disconnects.\n * - `\"error\"` — called when an error is thrown inside any event handler.\n * If not registered, Arkos emits a default `\"error\"` event to the socket.\n *\n * @example\n * chatGateway.hook(\"connection\", (socket) => {\n * console.log(\"connected\", socket.user.id)\n * })\n *\n * chatGateway.hook(\"error\", (err, socket) => {\n * socket.emit(\"error\", { message: err.message })\n * })\n */\n hook(type: \"connection\", handler: ArkosGatewayConnectionHandler): this;\n hook(type: \"disconnect\", handler: ArkosGatewayConnectionHandler): this;\n hook(type: \"error\", handler: ArkosGatewayErrorHandler): this;\n hook(\n type: ArkosGatewayHookType,\n handler: ArkosGatewayConnectionHandler | ArkosGatewayErrorHandler\n ): this {\n this.hooks.push({ type, handler });\n return this;\n }\n\n /**\n * Wire this gateway into a Socket.io `Server` instance.\n * Registers the namespace, auth middleware, rate limiting, pipes,\n * and all event handlers — then recurses into child gateways.\n *\n * @example\n * const io = new Server(server)\n * chatGateway.register(io)\n */\n register(io: Server, options: ArkosGatewayRegisterOptions = {}): void {\n if ((io as any)._arkosGatewayRegistered)\n throw new Error(\n `The method gateway.register() can only be called once per io server instance. Use gateway.use() to compose gateways, see https://www.arkosjs.com/docs/guides/web-sockets/setup.`\n );\n (io as any)._arkosGatewayRegistered = true;\n this._register(io, undefined, this.hooks || [], this.pipes || [], options);\n }\n\n private _register(\n io: Server,\n parentConfig?: ArkosGatewayConfig,\n inheritedHooks: {\n type: ArkosGatewayHookType;\n handler: ArkosGatewayHookHandler;\n }[] = [],\n inheritedPipes: ArkosGatewayPipe[] = [],\n options: ArkosGatewayRegisterOptions = {},\n inheritedMiddlewares: ArkosGatewayMiddleware[] = []\n ): void {\n options.store = options.store ?? defaultGatewayStore;\n const { store } = options;\n\n const parentName = parentConfig?.name;\n const ownName = this.config.name;\n this.config = deepmerge(parentConfig || {}, this.config, {\n arrayMerge: (_, sourceArray) => sourceArray,\n });\n this.config.name = ownName;\n const localConfig = this.config;\n\n const namespaceName = parentName\n ? `${parentName.replace(/\\/$/, \"\")}/${ownName.replace(/^\\//, \"\")}`\n : (ownName ?? \"\");\n\n const ns = io.of(namespaceName);\n this._nsp = ns;\n\n const resolvedAuth =\n this.config.authentication !== false &&\n parentConfig?.authentication !== false;\n\n const resolvedRateLimit = this.config.rateLimit ?? parentConfig?.rateLimit;\n const resolvedHooks = [...inheritedHooks, ...this.hooks];\n const resolvedMiddlewares = [...inheritedMiddlewares, ...this.middlewares];\n\n const connectHandlers = resolvedHooks\n .filter((h) => h.type === \"connection\")\n .map((h) => h.handler as ArkosGatewayConnectionHandler);\n\n const disconnectHandlers = resolvedHooks\n .filter((h) => h.type === \"disconnect\")\n .map((h) => h.handler as ArkosGatewayConnectionHandler);\n\n const errorHandlers = resolvedHooks\n .filter((h) => h.type === \"error\")\n .map((h) => h.handler as ArkosGatewayErrorHandler);\n\n for (const middleware of resolvedMiddlewares) {\n ns.use((socket, next) => middleware(socket as ArkosSocket, next));\n }\n\n if (resolvedAuth && isAuthenticationEnabled()) {\n ns.use(async (socket: any, next) => {\n socket = socket as ArkosSocket;\n const startTime = new Date().getTime();\n try {\n await authHookManager.runAuthenticate(\n {\n context: socket,\n done: (err?: any) => {\n if (err) throw err;\n next();\n },\n },\n async (socket) => {\n const user = await authService.getAuthenticatedUser(socket);\n if (!user) throw loginRequiredError;\n return user;\n },\n \"currentUser\"\n );\n } catch (err: any) {\n handleArkosGatewayErrors(err, socket, errorHandlers, {\n startTime,\n namespace: this.config.name,\n event: \"authentication\",\n });\n next(err);\n }\n });\n } else if (\n (this.config.authentication || parentConfig?.authentication) &&\n !isUsingAuthentication()\n )\n throw ExitError(\n `Trying to authenticate gateway ${this.config.name ? `${this.config.name}` : \"\"} without choosing an authentication mode under arkos.config.${getUserFileExtension()}.\n\nFor further help see https://www.arkosjs.com/docs/core-concepts/authentication/setup.`\n );\n\n ns.on(\"connection\", async (s) => {\n const socket = s as ArkosSocket;\n socket.locals = {};\n\n socket._arkos = { store, gatewayConfig: localConfig };\n mountArkosSocketExtensions(socket);\n\n handleGatewayLifecycleLog(this.config.name, \"connected\", socket.id);\n const connectionStartTime = new Date().getTime();\n\n if (socket.currentUser?.id)\n socket.join(`arkos::user:${socket.currentUser.id}`);\n\n try {\n for (const handler of connectHandlers) await handler(socket);\n } catch (err: any) {\n handleArkosGatewayErrors(err, socket, [], {\n startTime: connectionStartTime,\n namespace: this.config.name,\n event: \"connection\",\n });\n return;\n }\n\n socket.on(\"disconnect\", async () => {\n handleGatewayLifecycleLog(this.config.name, \"disconnected\", socket.id);\n\n await clearRateLimitForSocket(socket.id, store);\n try {\n for (const handler of disconnectHandlers) await handler(socket);\n } catch (err) {\n handleArkosGatewayErrors(err, socket, [], {\n startTime: connectionStartTime,\n namespace: this.config.name,\n event: \"disconnection\",\n });\n }\n });\n\n for (const entry of this.events) {\n if ((entry.config as any)._pipeOnly || !entry.handler) continue;\n\n const { config: eventConfig, handler, pipes: eventPipes = [] } = entry;\n\n if (\n (this.config.authentication || parentConfig?.authentication) &&\n !isUsingAuthentication()\n )\n throw ExitError(\n `Trying to use authorization gateway.on(\"${eventConfig.event}\") without choosing an authentication mode under arkos.config.${getUserFileExtension()}.\n\nFor further help see https://www.arkosjs.com/docs/core-concepts/authentication/setup.`\n );\n\n socket.on(eventConfig.event, async (...args: any[]) => {\n socket.locals = {};\n const startTime = new Date().getTime();\n let data = args[0];\n\n const ack =\n typeof args[args.length - 1] === \"function\"\n ? args[args.length - 1]\n : undefined;\n\n let ackCalled = false;\n const wrappedAck = ack\n ? (...response: any) => {\n ackCalled = true;\n ack(...response);\n }\n : undefined;\n\n function resolveDedup() {\n if (\n eventConfig.dedup === false ||\n localConfig.dedup === false ||\n parentConfig?.dedup === false\n )\n return null;\n\n return {\n enabled: true,\n ttl: 3600,\n ...parentConfig?.dedup,\n ...localConfig?.dedup,\n ...eventConfig?.dedup,\n };\n }\n\n const dedupOpt = resolveDedup();\n\n try {\n const meta = data?._meta || {};\n const resolvedMaxAge =\n eventConfig.maxAge ?? localConfig.maxAge ?? parentConfig?.maxAge;\n\n if (resolvedMaxAge && !meta.timestamp)\n throw new BadRequestError(\n \"Missing _meta.timestamp for maxAge deduplication\"\n );\n\n if (meta.timestamp !== undefined) {\n const timestamp = new Date(meta.timestamp);\n\n if (isNaN(timestamp.getTime())) {\n throw new BadRequestError(\n \"Invalid data._meta.timestamp\",\n \"InvalidTimestamp\"\n );\n }\n\n const age = Date.now() - timestamp.getTime();\n\n if (age + 1000 < 0)\n throw new BadRequestError(\n \"Timestamp is in the future\",\n \"FutureTimestamp\"\n );\n\n if (resolvedMaxAge && age > resolvedMaxAge) {\n throw new BadRequestError(\"Message is too old\", \"StaleMessage\");\n }\n }\n\n if (dedupOpt && dedupOpt?.enabled !== false) {\n if (!meta?.mid)\n throw new BadRequestError(\n \"Missing data._meta.mid in your payload for deduplication\",\n \"MissingDedupMessageId\",\n { data }\n );\n\n if (typeof meta.mid !== \"string\" || meta.mid.trim() === \"\")\n throw new BadRequestError(\n \"Invalid data._meta.mid, it must be a non-empty string\",\n \"InvalidMessageId\"\n );\n\n const key = `arkos::dedup:${eventConfig.event}:${meta.mid}`;\n const ttl = dedupOpt?.ttl ?? 3600;\n\n const acquired = await store.setIfNotExists(key, ttl);\n\n if (acquired === false)\n return wrappedAck?.({\n success: true,\n duplicate: true,\n });\n\n const { _meta, ...payload } = data;\n data = payload;\n\n socket.meta = meta;\n }\n\n const rateLimitOptions = eventConfig.rateLimit ?? resolvedRateLimit;\n if (rateLimitOptions !== false) {\n const { allowed, retryAfter } = await checkRateLimit(\n socket.id,\n eventConfig.event,\n rateLimitOptions || {},\n options.store!\n );\n if (!allowed) {\n throw new TooManyRequestsError(undefined, undefined, {\n retryAfter,\n });\n }\n }\n\n if (\n typeof eventConfig.authorization === \"object\" &&\n resolvedAuth &&\n isAuthenticationEnabled()\n ) {\n await authHookManager.runAuthorize(\n { context: socket, done: () => { } },\n (eventConfig?.authorization as any)?._authAction,\n \"currentUser\"\n );\n }\n\n if (eventConfig.validation) {\n const arkosConfig = getArkosConfig();\n const {\n validationFn,\n isValidValidator,\n validatorName,\n validatorNameType,\n } = validationManager;\n\n if (!isValidValidator(eventConfig.validation))\n throw new Error(\n `Your validation resolver is set to ${arkosConfig.validation!.resolver}, ` +\n `please provide a valid ${validatorName} in order to use { validation: ${validatorNameType} } ` +\n `under event handler \"${eventConfig.event}\" in \"${this.config.name}\" gateway.`\n );\n\n const shouldValidate = validationManager.shouldValidate(\n eventConfig.validation,\n data\n );\n\n if (shouldValidate === \"prohibit\")\n throw new BadRequestError(\n \"Event data is not allowed for this event.\",\n \"EventDataNotAllowed\",\n { data }\n );\n else if (shouldValidate === \"passthrough\") data = data;\n else {\n try {\n data = await (validationFn as any)(\n eventConfig.validation,\n data\n );\n } catch (err: any) {\n const { validationConfig } = validationManager;\n\n const resolver = validationConfig?.resolver;\n const isZod = validationConfig?.resolver === \"zod\";\n\n const prettifiedError = errorPrettifier.prettify(\n resolver as any,\n err\n );\n const error = prettifiedError[0];\n\n throw new BadRequestError(\n error.message,\n `InvalidData`,\n isZod ? err.format() : err\n );\n }\n }\n }\n\n socket.data = data;\n\n await runArkosGatewayPipes(\n [...inheritedPipes, ...eventPipes],\n socket,\n data\n );\n\n await handler(socket, data, wrappedAck);\n\n handleGatewayEventLog(\n this.config.name,\n eventConfig.event,\n 200,\n startTime\n );\n\n if (eventConfig.ack && ack && !ackCalled) {\n ack({ success: true });\n }\n } catch (err: any) {\n handleArkosGatewayErrors(\n err,\n socket,\n errorHandlers,\n {\n startTime,\n namespace: this.config.name,\n event: eventConfig.event,\n },\n ack\n );\n }\n });\n }\n });\n\n for (const child of this.gateways) {\n child._register(\n io,\n {\n name: namespaceName,\n authentication: resolvedAuth,\n rateLimit: resolvedRateLimit,\n },\n resolvedHooks,\n inheritedPipes,\n options,\n resolvedMiddlewares\n );\n }\n }\n}\n\n/**\n * Creates an Arkos WebSocket Gateway backed by Socket.io.\n *\n * Handles authentication, validation, rate limiting, pipes,\n * error handling, and nested gateways — all declaratively.\n * Enhances every connected socket with `socket.user()`, `socket.peer()`,\n * `socket.retry()`, and automatic `_meta` injection on outgoing emits.\n *\n * @example\n * ```ts\n * const chatGateway = ArkosGateway({\n * name: \"chat\",\n * authentication: true,\n * rateLimit: { windowMs: 60_000, max: 200 },\n * })\n *\n * chatGateway.on(\n * { event: \"send_message\", validation: MessageSchema, ack: true },\n * (socket, data, ack) => {\n * socket.to(data.room).emit(\"receive_message\", data)\n * ack?.({ status: \"ok\" })\n * }\n * )\n * ```\n * @since 1.7.0-canary.18\n * @see {@link https://www.arkosjs.com/docs/core-concepts/components/gateways}\n */\nfunction ArkosGateway(config: ArkosGatewayConfig) {\n return new IArkosGateway(config);\n}\n\nexport default ArkosGateway;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/components/arkos-gateway/types.ts"],"names":[],"mappings":";;;AA4jBA,MAAa,sBAAsB;CAAI;AAAvC,wDAAuC","sourcesContent":["import { BroadcastOperator, Socket } from \"socket.io\";\nimport { User } from \"../../types\";\nimport { DefaultEventsMap } from \"socket.io\";\nimport { Validator } from \"../../types/validation/validator\";\nimport { Options as RateLimitOptions } from \"express-rate-limit\";\nimport { DetailedAccessControlRule } from \"../../types/auth\";\n///@ts-ignore\nimport {\n AllButLast,\n DecorateAcknowledgements,\n DecorateAcknowledgementsWithMultipleResponses,\n EventNames,\n EventNamesWithAck,\n EventNamesWithError,\n EventParams,\n FirstNonErrorArg,\n Last,\n ///@ts-ignore\n} from \"socket.io/dist/typed-events\";\n\nexport interface EventsMap {\n [event: string]: any;\n}\n\nexport interface ArkosSocket<\n ListenEvents extends EventsMap = DefaultEventsMap,\n EmitEvents extends EventsMap = ListenEvents,\n ServerSideEvents extends EventsMap = DefaultEventsMap,\n SocketData extends Validator = any,\n SocketLocals extends Record<string, any> = Record<string, any>,\n> extends Socket<ListenEvents, EmitEvents, ServerSideEvents, SocketData> {\n /**\n * Populated by Arkos after successful authentication on connection.\n * Available in all event handlers when `authentication: true` on the gateway.\n */\n currentUser?: User;\n\n /**\n * Populated by Arkos after successful validation.\n * Typed to the event's validation schema when using TypeScript.\n */\n data: SocketData;\n\n /** User access token. */\n accessToken?: string;\n\n /**\n * Metadata from the incoming message, extracted from `_meta` by Arkos.\n *\n * - `mid`: Unique message ID used for deduplication.\n * - `timestamp`: When the message was sent by the client.\n */\n meta?: {\n mid?: string;\n timestamp?: string | number | Date;\n };\n\n /**\n * Per-event local storage, scoped to the current event pipeline.\n * Use to pass data between pipes and the event handler — like Express's `res.locals`.\n * Reset automatically on each event.\n *\n * @example\n * chatGateway.pipe((socket, data) => {\n * socket.locals.enriched = enrichUser(socket.currentUser)\n * })\n *\n * chatGateway.on({ event: \"send_message\" }, (socket, data) => {\n * console.log(socket.locals.enriched)\n * })\n */\n locals?: SocketLocals;\n\n /**\n * Internal Arkos context injected by the gateway at connection time.\n *\n * @internal\n */\n _arkos: {\n store: ArkosGatewayStore;\n gatewayConfig: ArkosGatewayConfig;\n };\n\n /**\n * Targets all active socket connections of a user by their user ID.\n * Uses the internal `arkos::user:{userId}` room convention.\n *\n * Supports emit, management, and exclusion operations across all of the\n * user's active connections.\n *\n * @example\n * socket.user(userId).emit(\"notification\", data)\n * socket.user(userId).except({ user: otherUserId }).emit(\"sync\", data)\n * const sockets = await socket.user(userId).fetchSockets()\n * const online = await socket.user(userId).isOnline()\n *\n * @since 1.7.0-canary.29\n */\n user(userId: string): ArkosUserTarget;\n\n /**\n * Wraps the next `emit` or `emitWithAck` with exponential backoff retry logic.\n * Chain `.timeout(ms)` before `.emitWithAck()` as usual.\n *\n * @example\n * socket.retry(3).emit(\"event\", data)\n * socket.retry(3).timeout(5000).emitWithAck(\"event\", data)\n *\n * @since 1.7.0-canary.29\n */\n retry(\n times: number,\n initialDelay?: number,\n multiplier?: number\n ): ArkosRetryTarget;\n\n /**\n * Emits an event to this client.\n * Arkos automatically injects `_meta` (`mid` + `timestamp`) into every outgoing payload\n * for client-side deduplication and freshness checks.\n *\n * @example\n * socket.emit(\"message\", { text: \"hello\" })\n * socket.emit(\"notification\", { title: \"New order\" })\n */\n emit<Ev extends EventNames<EmitEvents>>(\n ev: Ev,\n ...args: EventParams<EmitEvents, Ev>\n ): true;\n\n /**\n * Emits an event and waits for an acknowledgement from the client.\n * Arkos injects `_meta` automatically. Use `.timeout(ms)` to avoid hanging indefinitely.\n *\n * @example\n * const response = await socket.timeout(5000).emitWithAck(\"confirm\", data)\n */\n emitWithAck<Ev extends EventNamesWithAck<EmitEvents>>(\n ev: Ev,\n ...args: AllButLast<EventParams<EmitEvents, Ev>>\n ): Promise<FirstNonErrorArg<Last<EventParams<EmitEvents, Ev>>>>;\n\n /**\n * Targets a room when broadcasting — excludes the sender.\n * Returns an {@link ArkosBroadcastOperator} with enhanced `.except({ user })` support\n * and automatic `_meta` injection on every `.emit()`.\n *\n * @example\n * socket.to(\"room-101\").emit(\"message\", data)\n * socket.to(\"room-101\").except({ user: userId }).emit(\"message\", data)\n * socket.to(\"room-101\").volatile.emit(\"typing\", data)\n * await socket.to(\"room-101\").timeout(3000).emitWithAck(\"confirm\", data)\n *\n * @since 1.7.0-canary.29\n */\n to(\n room: string | string[]\n ): ArkosBroadcastOperator<\n DecorateAcknowledgementsWithMultipleResponses<EmitEvents>,\n SocketData\n > &\n BroadcastOperator<EmitEvents, SocketData>;\n /**\n * Broadcasts to all connected clients except the sender.\n * Returns an {@link ArkosBroadcastOperator} with enhanced `.except({ user })` support\n * and automatic `_meta` injection on every `.emit()`.\n *\n * @example\n * socket.broadcast.emit(\"announcement\", data)\n * socket.broadcast.except({ user: userId }).emit(\"announcement\", data)\n * socket.broadcast.volatile.emit(\"ping\", data)\n *\n * @since 1.7.0-canary.29\n */\n get broadcast(): ArkosBroadcastOperator<\n DecorateAcknowledgementsWithMultipleResponses<EmitEvents>,\n SocketData\n > &\n BroadcastOperator<EmitEvents, SocketData>;\n}\n\n/**\n * Enhanced broadcast/room target returned by `socket.to()` and `socket.broadcast`.\n * Extends the native `BroadcastOperator` with `{ user }` exclusion support\n * and automatic `_meta` injection on emit.\n *\n * @since 1.7.0-canary.29\n */\nexport interface ArkosBroadcastOperator<\n EmitEvents extends EventsMap = DefaultEventsMap,\n SocketData extends Validator = any,\n> extends BroadcastOperator<EmitEvents, SocketData> {\n /**\n * Exclude sockets from the broadcast.\n * Accepts a room name, socket ID, or `{ user: string | string[] }` to exclude\n * all sockets belonging to one or more users.\n *\n * @example\n * socket.to(\"room-101\").except(\"room-102\").emit(\"foo\", data)\n * socket.broadcast.except({ user: userId }).emit(\"foo\", data)\n * socket.broadcast.except({ user: [userId1, userId2] }).emit(\"foo\", data)\n */\n except(\n room: string | string[] | { user: string | string[] }\n ): ArkosBroadcastOperator<EmitEvents, SocketData>;\n\n /**\n * Emits to all clients,`_meta` is injected automatically.\n *\n * @example\n * // the “foo” event will be broadcast to all connected clients\n * io.emit(\"foo\", \"bar\");\n *\n * // the “foo” event will be broadcast to all connected clients in the “room-101” room\n * io.to(\"room-101\").emit(\"foo\", \"bar\");\n *\n * // with an acknowledgement expected from all connected clients\n * io.timeout(1000).emit(\"some-event\", (err, responses) => {\n * if (err) {\n * // some clients did not acknowledge the event in the given delay\n * } else {\n * console.log(responses); // one response per client\n * }\n * });\n *\n * @return Always true\n */\n emit<Ev extends EventNames<EmitEvents>>(\n ev: Ev,\n ...args: EventParams<EmitEvents, Ev>\n ): true;\n\n /** Chain volatile flag — event may be lost if client is not ready. */\n get volatile(): ArkosBroadcastOperator<EmitEvents, SocketData>;\n\n /** Chain compress flag. */\n compress(value: boolean): ArkosBroadcastOperator<EmitEvents, SocketData>;\n\n /** Chain timeout for `emitWithAck`. */\n timeout(\n ms: number\n ): ArkosBroadcastOperator<DecorateAcknowledgements<EmitEvents>, SocketData>;\n\n /**\n * Emits an event and waits for an acknowledgement from all clients.\n * `_meta` is injected automatically\n * @example\n * try {\n * const responses = await io.timeout(1000).emitWithAck(\"some-event\");\n * console.log(responses); // one response per client\n * } catch (e) {\n * // some clients did not acknowledge the event in the given delay\n * }\n *\n * @return a Promise that will be fulfilled when all clients have acknowledged the event\n */\n emitWithAck<Ev extends EventNamesWithError<EmitEvents>>(\n ev: Ev,\n ...args: AllButLast<EventParams<EmitEvents, Ev>>\n ): Promise<FirstNonErrorArg<Last<EventParams<EmitEvents, Ev>>>>;\n\n /**\n * Targets all active socket connections of a user by their user ID.\n * Uses the internal `arkos::user:{userId}` room convention.\n *\n * Supports emit, management, and exclusion operations across all of the\n * user's active connections.\n *\n * @example\n * socket.user(userId).emit(\"notification\", data)\n * socket.user(userId).except({ user: otherUserId }).emit(\"sync\", data)\n * const sockets = await socket.user(userId).fetchSockets()\n * const online = await socket.user(userId).isOnline()\n *\n * @since 1.7.0-canary.29\n */\n user(userId: string): ArkosUserTarget;\n /**\n * Returns all unique user IDs currently in the target room(s).\n *\n * @example\n * const users = await socket.to(\"room-123\").users()\n */\n users(): Promise<string[]>;\n}\n\n/**\n * Returned by `socket.retry(n)`. Wraps `emit` and `emitWithAck`\n * with exponential backoff. Chain `.timeout(ms)` before `.emitWithAck()` as usual.\n *\n * @since 1.7.0-canary.29\n */\nexport interface ArkosRetryTarget {\n /** Emit with ack and retry. `_meta` is injected automatically. */\n emitWithAck(event: string, data: any, ...rest: any[]): Promise<any>;\n\n /**\n * Chain a timeout before `emitWithAck`.\n *\n * @example\n * socket.retry(3).timeout(5000).emitWithAck(\"event\", data)\n */\n timeout(ms: number): ArkosRetryTarget;\n}\n\n/**\n * Returned by `socket.user(userId)`.\n * Targets all active socket connections of a user.\n *\n * @since 1.7.0-canary.29\n */\nexport interface ArkosUserTarget extends ArkosBroadcastOperator {\n /**\n * Returns all active rooms for this user.\n *\n * @example\n * const rooms = await socket.user(userId).activeRooms()\n * console.log(rooms.length) // number of active tabs/connections\n */\n activeRooms(): Promise<string[]>;\n}\n\nexport type ArkosGatewayPipe = (\n socket: ArkosSocket,\n data: any\n) => void | Promise<void>;\n\nexport type ArkosGatewayEventConfig<TSchema extends Validator = any> = {\n /** The Socket.io event name to listen for. */\n event: string;\n\n /** Zod schema or class-validator DTO to validate the incoming event payload. */\n validation?: TSchema;\n\n /** Per-event rate limiting. Overrides gateway-level `rateLimit` for this event. */\n rateLimit?: Partial<RateLimitOptions> | false;\n\n /**\n * Authorization configuration.\n *\n * @remarks Gateway `authentication` must NOT be `false` or this throws at registration time.\n */\n authorization?: {\n resource: string;\n action: string;\n rule?: DetailedAccessControlRule | string[] | \"*\";\n };\n\n /**\n * When `true`, Arkos automatically calls `ack({ success: true })` after the handler\n * finishes, unless the handler already called ack manually.\n */\n ack?: boolean;\n\n /** Disables this event handler without removing it. */\n disabled?: boolean;\n\n /**\n * Maximum age in milliseconds for incoming messages.\n * Requires `data._meta.timestamp`. Events older than this are rejected.\n */\n maxAge?: number;\n\n /** Per-event deduplication. Overrides gateway-level `dedup`. */\n dedup?:\n | {\n /** @default true */\n enabled?: boolean;\n /** Time-to-live in seconds for the dedup key. @default 3600 */\n ttl?: number;\n }\n | false;\n};\n\nexport type ArkosGatewayAckFn = (response: any) => void;\n\nexport type ArkosGatewayHandler<TData = any> = (\n socket: ArkosSocket,\n data: TData,\n ack?: ArkosGatewayAckFn\n) => void | Promise<void>;\n\nexport type ArkosGatewayEventEntry = {\n config: ArkosGatewayEventConfig;\n handler: ArkosGatewayHandler;\n pipes: ArkosGatewayPipe[];\n};\n\nexport type ArkosGatewayConnectionHandler = (\n socket: ArkosSocket\n) => void | Promise<void>;\n\nexport type ArkosGatewayHookHandler =\n | ArkosGatewayConnectionHandler\n | ArkosGatewayErrorHandler;\n\nexport type ArkosGatewayErrorHandler = (\n error: any,\n socket: ArkosSocket\n) => void | Promise<void>;\n\nexport type ArkosGatewayHookType = \"connection\" | \"disconnect\" | \"error\";\n\nexport type ArkosGatewayConfig = {\n /**\n * Socket.io namespace for this gateway.\n *\n * @example\n * name: \"/chat\"\n */\n name: string;\n\n /**\n * When `true`, Arkos runs auth middleware on connection and populates `socket.currentUser`.\n * Unauthenticated sockets are rejected.\n *\n * @default false\n */\n authentication?: boolean;\n\n /** Gateway-level rate limiting, applied per socket. Can be overridden per event. */\n rateLimit?: Partial<RateLimitOptions>;\n\n /**\n * Gateway-level deduplication. Drills down to child gateways and can be overridden\n * per child or per event listener.\n */\n dedup?:\n | {\n /** @default true */\n enabled?: boolean;\n /** @default 3600 */\n ttl?: number;\n }\n | false;\n\n /**\n * Maximum age in milliseconds for incoming messages.\n * Can be overridden per event via `maxAge` in `gateway.on()`.\n */\n maxAge?: number;\n};\n\n/**\n * Options for `gateway.register()`.\n * Passed once at the root — applies to all child gateways.\n */\nexport type ArkosGatewayRegisterOptions = {\n /**\n * Unified store for rate limiting and deduplication.\n * Defaults to an in-memory store — zero config for single-instance deployments.\n * For distributed deployments plug in a Redis-backed store.\n *\n * @example\n * store: new RedisArkosStore(redis)\n */\n store?: ArkosGatewayStore;\n};\n\n/**\n * Unified store interface for rate limiting and deduplication.\n * Implement this to plug in Redis, Valkey, or any distributed store.\n *\n * @example\n * class RedisArkosStore implements ArkosGatewayStore {\n * async increment(key, windowMs) { ... }\n * async clear(prefix) { ... }\n * async has(key) { ... }\n * async set(key, ttl) { ... }\n * async setIfNotExists(key, ttl) { ... }\n * }\n */\nexport interface ArkosGatewayStore {\n /** Increment a rate limit counter. Key format: `arkos::rl:{socketId}:{event}` */\n increment(\n key: string,\n windowMs: number\n ): Promise<{ count: number; resetAt: number }>;\n\n /** Clear all rate limit entries matching a prefix. Key format: `arkos::rl:{socketId}` */\n clear(prefix: string): Promise<void>;\n\n /** Check if a dedup key exists. */\n has(key: string): Promise<boolean>;\n\n /** Store a dedup key with TTL in seconds. */\n set(key: string, ttl: number): Promise<void>;\n\n /**\n * Atomically store a dedup key only if it does not already exist.\n * Returns `true` if created (process the message), `false` if duplicate (skip).\n */\n setIfNotExists(key: string, ttl: number): Promise<boolean>;\n}\n\n/**\n * Minimal broadcast/emit contract that {@link ArkosBroadcastOperatorImpl} wraps.\n * Deliberately narrower than socket.io's `BroadcastOperator` — only the methods\n * Arkos actually calls, so both a `BroadcastOperator` (from `socket.to()`) and a\n * raw `Namespace` (from `gateway.nsp`) satisfy it structurally.\n *\n * @since 1.7.1-canary.3\n */\nexport interface ArkosEmitTarget<EmitEvents extends EventsMap = DefaultEventsMap> {\n /**\n * Emits an event to the target. `_meta` (`mid` + `timestamp`) is injected automatically.\n *\n * @example\n * socket.to(\"room-101\").emit(\"message\", { text: \"hello\" })\n * socket.broadcast.emit(\"announcement\", data)\n */\n emit(event: string, ...args: any[]): boolean;\n\n /**\n * Emits an event and waits for an acknowledgement from all matched clients.\n * `_meta` is injected automatically.\n *\n * Optional — not every target supports ack collection directly (e.g. a raw\n * `Namespace` requires `.timeout(ms)` first). Throws at runtime if called on\n * a target that doesn't implement it natively.\n *\n * @example\n * const responses = await socket.to(\"room-101\").timeout(3000).emitWithAck(\"confirm\", data)\n */\n emitWithAck?(event: string, ...args: any[]): Promise<any>;\n\n /**\n * Excludes sockets from the broadcast.\n * Accepts a room name, socket ID, or array of rooms/IDs.\n * For `{ user }` exclusion, see {@link ArkosBroadcastOperatorImpl.except}.\n *\n * @example\n * socket.to(\"room-101\").except(\"room-102\").emit(\"foo\", data)\n */\n except(room: string | string[]): ArkosEmitTarget<EmitEvents>;\n\n /**\n * Sets the compress flag for the next emission.\n *\n * @example\n * socket.broadcast.compress(false).emit(\"ping\", data)\n */\n compress(value: boolean): ArkosEmitTarget<EmitEvents>;\n\n /**\n * Sets a timeout in milliseconds for `emitWithAck`.\n * Rejects the promise if no client acknowledges within the given delay.\n *\n * @example\n * socket.to(\"room-101\").timeout(3000).emitWithAck(\"confirm\", data)\n */\n timeout(ms: number): ArkosEmitTarget\n\n /**\n * Returns all sockets currently matched by this target.\n *\n * @example\n * const sockets = await socket.to(\"room-101\").fetchSockets()\n */\n fetchSockets(): Promise<any[]>;\n\n to(room: string | string[]): ArkosEmitTarget\n\n /**\n * Sets the volatile flag — the event may be dropped if the client is not ready.\n * Useful for high-frequency non-critical events like cursor positions or typing indicators.\n *\n * @example\n * socket.to(\"room-101\").volatile.emit(\"cursor\", position)\n */\n readonly volatile: ArkosEmitTarget<EmitEvents>;\n}\nexport class ArkosGatewayController { }\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/components/arkos-gateway/types.ts"],"names":[],"mappings":";;;AAukBA,MAAa,sBAAsB;CAAI;AAAvC,wDAAuC","sourcesContent":["import { BroadcastOperator, Socket } from \"socket.io\";\nimport { User } from \"../../types\";\nimport { DefaultEventsMap } from \"socket.io\";\nimport { Validator } from \"../../types/validation/validator\";\nimport { Options as RateLimitOptions } from \"express-rate-limit\";\nimport { DetailedAccessControlRule } from \"../../types/auth\";\n///@ts-ignore\nimport {\n AllButLast,\n DecorateAcknowledgements,\n DecorateAcknowledgementsWithMultipleResponses,\n EventNames,\n EventNamesWithAck,\n EventNamesWithError,\n EventParams,\n FirstNonErrorArg,\n Last,\n ///@ts-ignore\n} from \"socket.io/dist/typed-events\";\n\nexport interface EventsMap {\n [event: string]: any;\n}\n\nexport interface ArkosSocket<\n ListenEvents extends EventsMap = DefaultEventsMap,\n EmitEvents extends EventsMap = ListenEvents,\n ServerSideEvents extends EventsMap = DefaultEventsMap,\n SocketData extends Validator = any,\n SocketLocals extends Record<string, any> = Record<string, any>,\n> extends Socket<ListenEvents, EmitEvents, ServerSideEvents, SocketData> {\n /**\n * Populated by Arkos after successful authentication on connection.\n * Available in all event handlers when `authentication: true` on the gateway.\n */\n currentUser?: User;\n\n /**\n * Populated by Arkos after successful validation.\n * Typed to the event's validation schema when using TypeScript.\n */\n data: SocketData;\n\n /** User access token. */\n accessToken?: string;\n\n /**\n * Metadata from the incoming message, extracted from `_meta` by Arkos.\n *\n * - `mid`: Unique message ID used for deduplication.\n * - `timestamp`: When the message was sent by the client.\n */\n meta?: {\n mid?: string;\n timestamp?: string | number | Date;\n };\n\n /**\n * Per-event local storage, scoped to the current event pipeline.\n * Use to pass data between pipes and the event handler — like Express's `res.locals`.\n * Reset automatically on each event.\n *\n * @example\n * chatGateway.pipe((socket, data) => {\n * socket.locals.enriched = enrichUser(socket.currentUser)\n * })\n *\n * chatGateway.on({ event: \"send_message\" }, (socket, data) => {\n * console.log(socket.locals.enriched)\n * })\n */\n locals?: SocketLocals;\n\n /**\n * Internal Arkos context injected by the gateway at connection time.\n *\n * @internal\n */\n _arkos: {\n store: ArkosGatewayStore;\n gatewayConfig: ArkosGatewayConfig;\n };\n\n /**\n * Targets all active socket connections of a user by their user ID.\n * Uses the internal `arkos::user:{userId}` room convention.\n *\n * Supports emit, management, and exclusion operations across all of the\n * user's active connections.\n *\n * @example\n * socket.user(userId).emit(\"notification\", data)\n * socket.user(userId).except({ user: otherUserId }).emit(\"sync\", data)\n * const sockets = await socket.user(userId).fetchSockets()\n * const online = await socket.user(userId).isOnline()\n *\n * @since 1.7.0-canary.29\n */\n user(userId: string): ArkosUserTarget;\n\n /**\n * Wraps the next `emit` or `emitWithAck` with exponential backoff retry logic.\n * Chain `.timeout(ms)` before `.emitWithAck()` as usual.\n *\n * @example\n * socket.retry(3).emit(\"event\", data)\n * socket.retry(3).timeout(5000).emitWithAck(\"event\", data)\n *\n * @since 1.7.0-canary.29\n */\n retry(\n times: number,\n initialDelay?: number,\n multiplier?: number\n ): ArkosRetryTarget;\n\n /**\n * Emits an event to this client.\n * Arkos automatically injects `_meta` (`mid` + `timestamp`) into every outgoing payload\n * for client-side deduplication and freshness checks.\n *\n * @example\n * socket.emit(\"message\", { text: \"hello\" })\n * socket.emit(\"notification\", { title: \"New order\" })\n */\n emit<Ev extends EventNames<EmitEvents>>(\n ev: Ev,\n ...args: EventParams<EmitEvents, Ev>\n ): true;\n\n /**\n * Emits an event and waits for an acknowledgement from the client.\n * Arkos injects `_meta` automatically. Use `.timeout(ms)` to avoid hanging indefinitely.\n *\n * @example\n * const response = await socket.timeout(5000).emitWithAck(\"confirm\", data)\n */\n emitWithAck<Ev extends EventNamesWithAck<EmitEvents>>(\n ev: Ev,\n ...args: AllButLast<EventParams<EmitEvents, Ev>>\n ): Promise<FirstNonErrorArg<Last<EventParams<EmitEvents, Ev>>>>;\n\n /**\n * Targets a room when broadcasting — excludes the sender.\n * Returns an {@link ArkosBroadcastOperator} with enhanced `.except({ user })` support\n * and automatic `_meta` injection on every `.emit()`.\n *\n * @example\n * socket.to(\"room-101\").emit(\"message\", data)\n * socket.to(\"room-101\").except({ user: userId }).emit(\"message\", data)\n * socket.to(\"room-101\").volatile.emit(\"typing\", data)\n * await socket.to(\"room-101\").timeout(3000).emitWithAck(\"confirm\", data)\n *\n * @since 1.7.0-canary.29\n */\n to(\n room: string | string[]\n ): ArkosBroadcastOperator<\n DecorateAcknowledgementsWithMultipleResponses<EmitEvents>,\n SocketData\n > &\n BroadcastOperator<EmitEvents, SocketData>;\n /**\n * Broadcasts to all connected clients except the sender.\n * Returns an {@link ArkosBroadcastOperator} with enhanced `.except({ user })` support\n * and automatic `_meta` injection on every `.emit()`.\n *\n * @example\n * socket.broadcast.emit(\"announcement\", data)\n * socket.broadcast.except({ user: userId }).emit(\"announcement\", data)\n * socket.broadcast.volatile.emit(\"ping\", data)\n *\n * @since 1.7.0-canary.29\n */\n get broadcast(): ArkosBroadcastOperator<\n DecorateAcknowledgementsWithMultipleResponses<EmitEvents>,\n SocketData\n > &\n BroadcastOperator<EmitEvents, SocketData>;\n}\n\n/**\n * Enhanced broadcast/room target returned by `socket.to()` and `socket.broadcast`.\n * Extends the native `BroadcastOperator` with `{ user }` exclusion support\n * and automatic `_meta` injection on emit.\n *\n * @since 1.7.0-canary.29\n */\nexport interface ArkosBroadcastOperator<\n EmitEvents extends EventsMap = DefaultEventsMap,\n SocketData extends Validator = any,\n> extends BroadcastOperator<EmitEvents, SocketData> {\n /**\n * Exclude sockets from the broadcast.\n * Accepts a room name, socket ID, or `{ user: string | string[] }` to exclude\n * all sockets belonging to one or more users.\n *\n * @example\n * socket.to(\"room-101\").except(\"room-102\").emit(\"foo\", data)\n * socket.broadcast.except({ user: userId }).emit(\"foo\", data)\n * socket.broadcast.except({ user: [userId1, userId2] }).emit(\"foo\", data)\n */\n except(\n room: string | string[] | { user: string | string[] }\n ): ArkosBroadcastOperator<EmitEvents, SocketData>;\n\n /**\n * Emits to all clients,`_meta` is injected automatically.\n *\n * @example\n * // the “foo” event will be broadcast to all connected clients\n * io.emit(\"foo\", \"bar\");\n *\n * // the “foo” event will be broadcast to all connected clients in the “room-101” room\n * io.to(\"room-101\").emit(\"foo\", \"bar\");\n *\n * // with an acknowledgement expected from all connected clients\n * io.timeout(1000).emit(\"some-event\", (err, responses) => {\n * if (err) {\n * // some clients did not acknowledge the event in the given delay\n * } else {\n * console.log(responses); // one response per client\n * }\n * });\n *\n * @return Always true\n */\n emit<Ev extends EventNames<EmitEvents>>(\n ev: Ev,\n ...args: EventParams<EmitEvents, Ev>\n ): true;\n\n /** Chain volatile flag — event may be lost if client is not ready. */\n get volatile(): ArkosBroadcastOperator<EmitEvents, SocketData>;\n\n /** Chain compress flag. */\n compress(value: boolean): ArkosBroadcastOperator<EmitEvents, SocketData>;\n\n /** Chain timeout for `emitWithAck`. */\n timeout(\n ms: number\n ): ArkosBroadcastOperator<DecorateAcknowledgements<EmitEvents>, SocketData>;\n\n /**\n * Emits an event and waits for an acknowledgement from all clients.\n * `_meta` is injected automatically\n * @example\n * try {\n * const responses = await io.timeout(1000).emitWithAck(\"some-event\");\n * console.log(responses); // one response per client\n * } catch (e) {\n * // some clients did not acknowledge the event in the given delay\n * }\n *\n * @return a Promise that will be fulfilled when all clients have acknowledged the event\n */\n emitWithAck<Ev extends EventNamesWithError<EmitEvents>>(\n ev: Ev,\n ...args: AllButLast<EventParams<EmitEvents, Ev>>\n ): Promise<FirstNonErrorArg<Last<EventParams<EmitEvents, Ev>>>>;\n\n /**\n * Targets all active socket connections of a user by their user ID.\n * Uses the internal `arkos::user:{userId}` room convention.\n *\n * Supports emit, management, and exclusion operations across all of the\n * user's active connections.\n *\n * @example\n * socket.user(userId).emit(\"notification\", data)\n * socket.user(userId).except({ user: otherUserId }).emit(\"sync\", data)\n * const sockets = await socket.user(userId).fetchSockets()\n * const online = await socket.user(userId).isOnline()\n *\n * @since 1.7.0-canary.29\n */\n user(userId: string): ArkosUserTarget;\n /**\n * Returns all unique user IDs currently in the target room(s).\n *\n * @example\n * const users = await socket.to(\"room-123\").users()\n */\n users(): Promise<string[]>;\n}\n\n/**\n * Returned by `socket.retry(n)`. Wraps `emit` and `emitWithAck`\n * with exponential backoff. Chain `.timeout(ms)` before `.emitWithAck()` as usual.\n *\n * @since 1.7.0-canary.29\n */\nexport interface ArkosRetryTarget {\n /** Emit with ack and retry. `_meta` is injected automatically. */\n emitWithAck(event: string, data: any, ...rest: any[]): Promise<any>;\n\n /**\n * Chain a timeout before `emitWithAck`.\n *\n * @example\n * socket.retry(3).timeout(5000).emitWithAck(\"event\", data)\n */\n timeout(ms: number): ArkosRetryTarget;\n}\n\n/**\n * Returned by `socket.user(userId)`.\n * Targets all active socket connections of a user.\n *\n * @since 1.7.0-canary.29\n */\nexport interface ArkosUserTarget extends ArkosBroadcastOperator {\n /**\n * Returns all active rooms for this user.\n *\n * @example\n * const rooms = await socket.user(userId).activeRooms()\n * console.log(rooms.length) // number of active tabs/connections\n */\n activeRooms(): Promise<string[]>;\n}\n\nexport type ArkosGatewayPipe = (\n socket: ArkosSocket,\n data: any\n) => void | Promise<void>;\n\n/**\n * Connection-level middleware registered with `gateway.use()`.\n * Same `(socket, next)` contract as Socket.io namespace middleware.\n * Runs before the namespace's authentication middleware and is inherited\n * by nested gateways.\n */\nexport type ArkosGatewayMiddleware = (\n socket: ArkosSocket,\n next: (err?: any) => void\n) => void | Promise<void>;\n\nexport type ArkosGatewayEventConfig<TSchema extends Validator = any> = {\n /** The Socket.io event name to listen for. */\n event: string;\n\n /** Zod schema or class-validator DTO to validate the incoming event payload. */\n validation?: TSchema;\n\n /** Per-event rate limiting. Overrides gateway-level `rateLimit` for this event. */\n rateLimit?: Partial<RateLimitOptions> | false;\n\n /**\n * Authorization configuration.\n *\n * @remarks Gateway `authentication` must NOT be `false` or this throws at registration time.\n */\n authorization?: {\n resource: string;\n action: string;\n rule?: DetailedAccessControlRule | string[] | \"*\";\n };\n\n /**\n * When `true`, Arkos automatically calls `ack({ success: true })` after the handler\n * finishes, unless the handler already called ack manually.\n */\n ack?: boolean;\n\n /** Disables this event handler without removing it. */\n disabled?: boolean;\n\n /**\n * Maximum age in milliseconds for incoming messages.\n * Requires `data._meta.timestamp`. Events older than this are rejected.\n */\n maxAge?: number;\n\n /** Per-event deduplication. Overrides gateway-level `dedup`. */\n dedup?:\n | {\n /** @default true */\n enabled?: boolean;\n /** Time-to-live in seconds for the dedup key. @default 3600 */\n ttl?: number;\n }\n | false;\n};\n\nexport type ArkosGatewayAckFn = (response: any) => void;\n\nexport type ArkosGatewayHandler<TData = any> = (\n socket: ArkosSocket,\n data: TData,\n ack?: ArkosGatewayAckFn\n) => void | Promise<void>;\n\nexport type ArkosGatewayEventEntry = {\n config: ArkosGatewayEventConfig;\n handler: ArkosGatewayHandler;\n pipes: ArkosGatewayPipe[];\n};\n\nexport type ArkosGatewayConnectionHandler = (\n socket: ArkosSocket\n) => void | Promise<void>;\n\nexport type ArkosGatewayHookHandler =\n | ArkosGatewayConnectionHandler\n | ArkosGatewayErrorHandler;\n\nexport type ArkosGatewayErrorHandler = (\n error: any,\n socket: ArkosSocket\n) => void | Promise<void>;\n\nexport type ArkosGatewayHookType = \"connection\" | \"disconnect\" | \"error\";\n\nexport type ArkosGatewayConfig = {\n /**\n * Socket.io namespace for this gateway.\n *\n * @example\n * name: \"/chat\"\n */\n name: string;\n\n /**\n * When `true`, Arkos runs auth middleware on connection and populates `socket.currentUser`.\n * Unauthenticated sockets are rejected.\n *\n * @default false\n */\n authentication?: boolean;\n\n /** Gateway-level rate limiting, applied per socket. Can be overridden per event. */\n rateLimit?: Partial<RateLimitOptions>;\n\n /**\n * Gateway-level deduplication. Drills down to child gateways and can be overridden\n * per child or per event listener.\n */\n dedup?:\n | {\n /** @default true */\n enabled?: boolean;\n /** @default 3600 */\n ttl?: number;\n }\n | false;\n\n /**\n * Maximum age in milliseconds for incoming messages.\n * Can be overridden per event via `maxAge` in `gateway.on()`.\n */\n maxAge?: number;\n};\n\n/**\n * Options for `gateway.register()`.\n * Passed once at the root — applies to all child gateways.\n */\nexport type ArkosGatewayRegisterOptions = {\n /**\n * Unified store for rate limiting and deduplication.\n * Defaults to an in-memory store — zero config for single-instance deployments.\n * For distributed deployments plug in a Redis-backed store.\n *\n * @example\n * store: new RedisArkosStore(redis)\n */\n store?: ArkosGatewayStore;\n};\n\n/**\n * Unified store interface for rate limiting and deduplication.\n * Implement this to plug in Redis, Valkey, or any distributed store.\n *\n * @example\n * class RedisArkosStore implements ArkosGatewayStore {\n * async increment(key, windowMs) { ... }\n * async clear(prefix) { ... }\n * async has(key) { ... }\n * async set(key, ttl) { ... }\n * async setIfNotExists(key, ttl) { ... }\n * }\n */\nexport interface ArkosGatewayStore {\n /** Increment a rate limit counter. Key format: `arkos::rl:{socketId}:{event}` */\n increment(\n key: string,\n windowMs: number\n ): Promise<{ count: number; resetAt: number }>;\n\n /** Clear all rate limit entries matching a prefix. Key format: `arkos::rl:{socketId}` */\n clear(prefix: string): Promise<void>;\n\n /** Check if a dedup key exists. */\n has(key: string): Promise<boolean>;\n\n /** Store a dedup key with TTL in seconds. */\n set(key: string, ttl: number): Promise<void>;\n\n /**\n * Atomically store a dedup key only if it does not already exist.\n * Returns `true` if created (process the message), `false` if duplicate (skip).\n */\n setIfNotExists(key: string, ttl: number): Promise<boolean>;\n}\n\n/**\n * Minimal broadcast/emit contract that {@link ArkosBroadcastOperatorImpl} wraps.\n * Deliberately narrower than socket.io's `BroadcastOperator` — only the methods\n * Arkos actually calls, so both a `BroadcastOperator` (from `socket.to()`) and a\n * raw `Namespace` (from `gateway.nsp`) satisfy it structurally.\n *\n * @since 1.7.1-canary.3\n */\nexport interface ArkosEmitTarget<EmitEvents extends EventsMap = DefaultEventsMap> {\n /**\n * Emits an event to the target. `_meta` (`mid` + `timestamp`) is injected automatically.\n *\n * @example\n * socket.to(\"room-101\").emit(\"message\", { text: \"hello\" })\n * socket.broadcast.emit(\"announcement\", data)\n */\n emit(event: string, ...args: any[]): boolean;\n\n /**\n * Emits an event and waits for an acknowledgement from all matched clients.\n * `_meta` is injected automatically.\n *\n * Optional — not every target supports ack collection directly (e.g. a raw\n * `Namespace` requires `.timeout(ms)` first). Throws at runtime if called on\n * a target that doesn't implement it natively.\n *\n * @example\n * const responses = await socket.to(\"room-101\").timeout(3000).emitWithAck(\"confirm\", data)\n */\n emitWithAck?(event: string, ...args: any[]): Promise<any>;\n\n /**\n * Excludes sockets from the broadcast.\n * Accepts a room name, socket ID, or array of rooms/IDs.\n * For `{ user }` exclusion, see {@link ArkosBroadcastOperatorImpl.except}.\n *\n * @example\n * socket.to(\"room-101\").except(\"room-102\").emit(\"foo\", data)\n */\n except(room: string | string[]): ArkosEmitTarget<EmitEvents>;\n\n /**\n * Sets the compress flag for the next emission.\n *\n * @example\n * socket.broadcast.compress(false).emit(\"ping\", data)\n */\n compress(value: boolean): ArkosEmitTarget<EmitEvents>;\n\n /**\n * Sets a timeout in milliseconds for `emitWithAck`.\n * Rejects the promise if no client acknowledges within the given delay.\n *\n * @example\n * socket.to(\"room-101\").timeout(3000).emitWithAck(\"confirm\", data)\n */\n timeout(ms: number): ArkosEmitTarget\n\n /**\n * Returns all sockets currently matched by this target.\n *\n * @example\n * const sockets = await socket.to(\"room-101\").fetchSockets()\n */\n fetchSockets(): Promise<any[]>;\n\n to(room: string | string[]): ArkosEmitTarget\n\n /**\n * Sets the volatile flag — the event may be dropped if the client is not ready.\n * Useful for high-frequency non-critical events like cursor positions or typing indicators.\n *\n * @example\n * socket.to(\"room-101\").volatile.emit(\"cursor\", position)\n */\n readonly volatile: ArkosEmitTarget<EmitEvents>;\n}\nexport class ArkosGatewayController { }\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"websockets.js","sourceRoot":"","sources":["../../../src/exports/websockets.ts"],"names":[],"mappings":";;;;;;AAAA,8FAAqE;AAgB5D,uBAhBF,uBAAY,CAgBE;AAdrB,2EAA0E;AAAjE,8GAAA,aAAa,OAAA;AACtB,2DAA2E;AAAlE,+GAAA,sBAAsB,OAAA","sourcesContent":["import ArkosGateway from \"../components/arkos-gateway/arkos-gateway\";\n\nexport { IArkosGateway } from \"../components/arkos-gateway/arkos-gateway\";\nexport { ArkosGatewayController } from \"../components/arkos-gateway/types\";\nexport type {\n ArkosSocket,\n ArkosGatewayConfig,\n ArkosGatewayEventConfig,\n ArkosGatewayHandler,\n ArkosGatewayPipe,\n ArkosGatewayConnectionHandler,\n ArkosGatewayErrorHandler,\n ArkosGatewayAckFn,\n ArkosBroadcastOperator,\n} from \"../components/arkos-gateway/types\";\n\nexport { ArkosGateway };\n"]}
1
+ {"version":3,"file":"websockets.js","sourceRoot":"","sources":["../../../src/exports/websockets.ts"],"names":[],"mappings":";;;;;;AAAA,8FAAqE;AAiB5D,uBAjBF,uBAAY,CAiBE;AAfrB,2EAA0E;AAAjE,8GAAA,aAAa,OAAA;AACtB,2DAA2E;AAAlE,+GAAA,sBAAsB,OAAA","sourcesContent":["import ArkosGateway from \"../components/arkos-gateway/arkos-gateway\";\n\nexport { IArkosGateway } from \"../components/arkos-gateway/arkos-gateway\";\nexport { ArkosGatewayController } from \"../components/arkos-gateway/types\";\nexport type {\n ArkosSocket,\n ArkosGatewayConfig,\n ArkosGatewayEventConfig,\n ArkosGatewayHandler,\n ArkosGatewayPipe,\n ArkosGatewayMiddleware,\n ArkosGatewayConnectionHandler,\n ArkosGatewayErrorHandler,\n ArkosGatewayAckFn,\n ArkosBroadcastOperator,\n} from \"../components/arkos-gateway/types\";\n\nexport { ArkosGateway };\n"]}
@@ -17,6 +17,7 @@ const fs_helpers_1 = require("../../utils/helpers/fs.helpers.js");
17
17
  const arkos_router_1 = __importDefault(require("../../utils/arkos-router/index.js"));
18
18
  const auth_openapi_generator_1 = __importDefault(require("./utils/auth-openapi-generator.js"));
19
19
  const prisma_helpers_1 = require("../../utils/helpers/prisma.helpers.js");
20
+ const exit_error_1 = __importDefault(require("../../utils/helpers/exit-error.js"));
20
21
  const router = (0, arkos_router_1.default)();
21
22
  function getAuthRouter(arkosConfig) {
22
23
  if (!(0, prisma_helpers_1.getPrismaInstance)())
@@ -28,7 +29,7 @@ function getAuthRouter(arkosConfig) {
28
29
  if (router_validator_1.default.isExpressRouter(customRouter))
29
30
  router.use({ path: "/auth" }, customRouter);
30
31
  else
31
- throw Error(`ValidationError: The exported router from auth.router.${(0, fs_helpers_1.getUserFileExtension)()} is not a valid express or arkos Router.`);
32
+ throw (0, exit_error_1.default)(`ValidationError: The exported router from auth.router.${(0, fs_helpers_1.getUserFileExtension)()} is not a valid express or arkos Router.`);
32
33
  }
33
34
  const authController = (0, auth_controller_1.authControllerFactory)(interceptors);
34
35
  if (routerConfig?.disable === true)
@@ -1 +1 @@
1
- {"version":3,"file":"auth.router.js","sourceRoot":"","sources":["../../../../src/modules/auth/auth.router.ts"],"names":[],"mappings":"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","sourcesContent":["import { Router } from \"express\";\nimport { authControllerFactory } from \"./auth.controller\";\nimport rateLimit from \"express-rate-limit\";\nimport { getModuleComponents } from \"../../utils/dynamic-loader\";\nimport {\n addPrismaQueryOptionsToRequest,\n sendResponse,\n} from \"../base/base.middlewares\";\nimport deepmerge from \"../../utils/helpers/deepmerge.helper\";\nimport { AuthPrismaQueryOptions } from \"../../types\";\nimport {\n processMiddleware,\n createRouteConfig,\n} from \"../../utils/helpers/routers.helpers\";\nimport { isEndpointDisabled } from \"../base/utils/helpers/base.router.helpers\";\nimport debuggerService from \"../debugger/debugger.service\";\nimport routerValidator from \"../base/utils/router-validator\";\nimport { getUserFileExtension } from \"../../utils/helpers/fs.helpers\";\nimport ArkosRouter from \"../../utils/arkos-router\";\nimport { UserArkosConfig } from \"../../utils/define-config\";\nimport authOpenAPIGenerator from \"./utils/auth-openapi-generator\";\nimport { AuthRouterEndpoint, RouteHook } from \"../../types/router-config\";\nimport { getPrismaInstance } from \"../../utils/helpers/prisma.helpers\";\n\nconst router = ArkosRouter();\n\nexport function getAuthRouter(arkosConfig: UserArkosConfig) {\n if (!getPrismaInstance()) return router;\n\n const {\n interceptors,\n dtos,\n schemas,\n prismaQueryOptions,\n router: customRouterModule,\n authConfigs,\n } = getModuleComponents(\"auth\") || {};\n\n const routerConfig: RouteHook<\"auth\"> =\n (customRouterModule?.config as any) || {};\n const customRouter = customRouterModule?.default as Router;\n\n if (customRouter && customRouterModule) {\n if (routerValidator.isExpressRouter(customRouter))\n router.use({ path: \"/auth\" }, customRouter);\n else\n throw Error(\n `ValidationError: The exported router from auth.router.${getUserFileExtension()} is not a valid express or arkos Router.`\n );\n }\n\n const authController = authControllerFactory(interceptors);\n\n if (routerConfig?.disable === true) return router;\n\n const getValidationSchemaOrDto = (\n key: \"updateMe\" | \"updatePassword\" | \"login\" | \"signup\"\n ) => {\n const validationConfigs = arkosConfig?.validation;\n if (validationConfigs?.resolver === \"class-validator\") return dtos?.[key];\n else if (validationConfigs?.resolver === \"zod\") return schemas?.[key];\n\n return undefined;\n };\n\n const endpoints: AuthRouterEndpoint[] = [\n \"login\",\n \"logout\",\n \"signup\",\n \"updatePassword\",\n \"getMe\",\n \"updateMe\",\n \"deleteMe\",\n \"findManyAuthAction\",\n \"findOneAuthAction\",\n ];\n\n for (const endpoint of endpoints) {\n let endpointConfig = routerConfig[endpoint] || {};\n\n const schema = getValidationSchemaOrDto(endpoint as any);\n if (\n schema &&\n endpointConfig?.validation !== false &&\n endpointConfig?.validation?.body !== false\n )\n endpointConfig = {\n ...(endpointConfig || {}),\n validation: {\n ...(endpointConfig?.validation || {}),\n body: schema,\n },\n };\n\n if (endpointConfig?.experimental?.openapi !== false)\n endpointConfig = {\n ...(endpointConfig || {}),\n experimental: {\n ...(endpointConfig?.experimental || {}),\n openapi: authOpenAPIGenerator.getOpenApiConfig(\n endpointConfig,\n endpoint\n ),\n },\n };\n\n routerConfig[endpoint] = endpointConfig;\n }\n\n // GET /users/me - Get current user\n if (!isEndpointDisabled(routerConfig, \"getMe\")) {\n router.get(\n createRouteConfig(\n arkosConfig,\n \"getMe\",\n \"users\",\n \"/me\",\n routerConfig,\n \"auth\",\n true\n ),\n addPrismaQueryOptionsToRequest<any>(\n prismaQueryOptions as AuthPrismaQueryOptions<any>,\n \"getMe\"\n ),\n ...processMiddleware(interceptors?.beforeGetMe),\n authController.getMe,\n ...processMiddleware(interceptors?.afterGetMe),\n sendResponse,\n ...processMiddleware(interceptors?.onGetMeError, { type: \"error\" })\n );\n }\n\n // PATCH /users/me - Update current user\n if (!isEndpointDisabled(routerConfig, \"updateMe\")) {\n router.patch(\n createRouteConfig(\n arkosConfig,\n \"updateMe\",\n \"users\",\n \"/me\",\n routerConfig,\n \"auth\",\n true\n ),\n addPrismaQueryOptionsToRequest<any>(\n prismaQueryOptions as AuthPrismaQueryOptions<any>,\n \"updateMe\"\n ),\n ...processMiddleware(interceptors?.beforeUpdateMe),\n authController.updateMe,\n ...processMiddleware(interceptors?.afterUpdateMe),\n sendResponse,\n ...processMiddleware(interceptors?.onUpdateMeError, { type: \"error\" })\n );\n }\n\n // DELETE /users/me - Delete current user\n if (!isEndpointDisabled(routerConfig, \"deleteMe\")) {\n router.delete(\n createRouteConfig(\n arkosConfig,\n \"deleteMe\",\n \"users\",\n \"/me\",\n routerConfig,\n \"auth\",\n true\n ),\n addPrismaQueryOptionsToRequest<any>(\n prismaQueryOptions as AuthPrismaQueryOptions<any>,\n \"deleteMe\"\n ),\n ...processMiddleware(interceptors?.beforeDeleteMe),\n authController.deleteMe,\n ...processMiddleware(interceptors?.afterDeleteMe),\n sendResponse,\n ...processMiddleware(interceptors?.onDeleteMeError, { type: \"error\" })\n );\n }\n\n // Apply rate limiting to auth routes\n if (\n !isEndpointDisabled(routerConfig, \"login\") ||\n !isEndpointDisabled(routerConfig, \"logout\") ||\n !isEndpointDisabled(routerConfig, \"signup\") ||\n !isEndpointDisabled(routerConfig, \"updatePassword\")\n ) {\n router.use(\n { path: \"/auth\" },\n rateLimit(\n deepmerge(\n {\n windowMs: 5000,\n limit: 10,\n standardHeaders: \"draft-7\",\n legacyHeaders: false,\n handler: (_, res) => {\n res.status(429).json({\n message: \"Too many requests, please try again later\",\n });\n },\n },\n arkosConfig?.authentication?.rateLimit || {}\n )\n )\n );\n }\n\n // POST /auth/login - Login\n if (!isEndpointDisabled(routerConfig, \"login\")) {\n router.post(\n createRouteConfig(\n arkosConfig,\n \"login\",\n \"auth\",\n \"/login\",\n routerConfig,\n \"auth\",\n false\n ),\n addPrismaQueryOptionsToRequest<any>(\n prismaQueryOptions as AuthPrismaQueryOptions<any>,\n \"login\"\n ),\n ...processMiddleware(interceptors?.beforeLogin),\n authController.login,\n ...processMiddleware(interceptors?.afterLogin),\n sendResponse,\n ...processMiddleware(interceptors?.onLoginError, { type: \"error\" })\n );\n }\n\n // DELETE /auth/logout - Logout\n if (!isEndpointDisabled(routerConfig, \"logout\")) {\n router.delete(\n createRouteConfig(\n arkosConfig,\n \"logout\",\n \"auth\",\n \"/logout\",\n routerConfig,\n \"auth\",\n true\n ),\n ...processMiddleware(interceptors?.beforeLogout),\n authController.logout,\n ...processMiddleware(interceptors?.afterLogout),\n sendResponse,\n ...processMiddleware(interceptors?.onLogoutError, { type: \"error\" })\n );\n }\n\n // POST /auth/signup - Signup\n if (!isEndpointDisabled(routerConfig, \"signup\")) {\n router.post(\n createRouteConfig(\n arkosConfig,\n \"signup\",\n \"auth\",\n \"/signup\",\n routerConfig,\n \"auth\",\n false\n ),\n addPrismaQueryOptionsToRequest<any>(\n prismaQueryOptions as AuthPrismaQueryOptions<any>,\n \"signup\"\n ),\n ...processMiddleware(interceptors?.beforeSignup),\n authController.signup,\n ...processMiddleware(interceptors?.afterSignup),\n sendResponse,\n ...processMiddleware(interceptors?.onSignupError, { type: \"error\" })\n );\n }\n\n // POST /auth/update-password - Update password\n if (!isEndpointDisabled(routerConfig, \"updatePassword\")) {\n router.post(\n createRouteConfig(\n arkosConfig,\n \"updatePassword\",\n \"auth\",\n \"/update-password\",\n routerConfig,\n \"auth\",\n true\n ),\n addPrismaQueryOptionsToRequest<any>(\n prismaQueryOptions as AuthPrismaQueryOptions<any>,\n \"updatePassword\"\n ),\n ...processMiddleware(interceptors?.beforeUpdatePassword),\n authController.updatePassword,\n ...processMiddleware(interceptors?.afterUpdatePassword),\n sendResponse,\n ...processMiddleware(interceptors?.onUpdatePasswordError, {\n type: \"error\",\n })\n );\n }\n\n // GET /auth-actions - Find many auth actions\n if (!isEndpointDisabled(routerConfig, \"findManyAuthAction\")) {\n router.get(\n createRouteConfig(\n arkosConfig,\n \"findManyAuthAction\",\n \"auth-actions\",\n \"\",\n routerConfig,\n \"auth\",\n authConfigs\n ),\n ...processMiddleware(interceptors?.beforeFindManyAuthAction),\n authController.findManyAuthAction,\n ...processMiddleware(interceptors?.afterFindManyAuthAction),\n sendResponse,\n ...processMiddleware(interceptors?.onFindManyAuthActionError, {\n type: \"error\",\n })\n );\n }\n\n // GET /auth-actions/:resourceName - Find one auth action\n if (!isEndpointDisabled(routerConfig, \"findOneAuthAction\")) {\n router.get(\n createRouteConfig(\n arkosConfig,\n \"findOneAuthAction\",\n \"auth-actions\",\n \"/:resourceName\",\n routerConfig,\n \"auth\",\n authConfigs\n ),\n ...processMiddleware(interceptors?.beforeFindOneAuthAction),\n authController.findOneAuthAction,\n ...processMiddleware(interceptors?.afterFindOneAuthAction),\n sendResponse,\n ...processMiddleware(interceptors?.onFindOneAuthActionError, {\n type: \"error\",\n })\n );\n }\n\n debuggerService.logModuleFinalRouter(\"auth\", router as any);\n return router;\n}\n"]}
1
+ {"version":3,"file":"auth.router.js","sourceRoot":"","sources":["../../../../src/modules/auth/auth.router.ts"],"names":[],"mappings":"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","sourcesContent":["import { Router } from \"express\";\nimport { authControllerFactory } from \"./auth.controller\";\nimport rateLimit from \"express-rate-limit\";\nimport { getModuleComponents } from \"../../utils/dynamic-loader\";\nimport {\n addPrismaQueryOptionsToRequest,\n sendResponse,\n} from \"../base/base.middlewares\";\nimport deepmerge from \"../../utils/helpers/deepmerge.helper\";\nimport { AuthPrismaQueryOptions } from \"../../types\";\nimport {\n processMiddleware,\n createRouteConfig,\n} from \"../../utils/helpers/routers.helpers\";\nimport { isEndpointDisabled } from \"../base/utils/helpers/base.router.helpers\";\nimport debuggerService from \"../debugger/debugger.service\";\nimport routerValidator from \"../base/utils/router-validator\";\nimport { getUserFileExtension } from \"../../utils/helpers/fs.helpers\";\nimport ArkosRouter from \"../../utils/arkos-router\";\nimport { UserArkosConfig } from \"../../utils/define-config\";\nimport authOpenAPIGenerator from \"./utils/auth-openapi-generator\";\nimport { AuthRouterEndpoint, RouteHook } from \"../../types/router-config\";\nimport { getPrismaInstance } from \"../../utils/helpers/prisma.helpers\";\nimport ExitError from \"../../utils/helpers/exit-error\";\n\nconst router = ArkosRouter();\n\nexport function getAuthRouter(arkosConfig: UserArkosConfig) {\n if (!getPrismaInstance()) return router;\n\n const {\n interceptors,\n dtos,\n schemas,\n prismaQueryOptions,\n router: customRouterModule,\n authConfigs,\n } = getModuleComponents(\"auth\") || {};\n\n const routerConfig: RouteHook<\"auth\"> =\n (customRouterModule?.config as any) || {};\n const customRouter = customRouterModule?.default as Router;\n\n if (customRouter && customRouterModule) {\n if (routerValidator.isExpressRouter(customRouter))\n router.use({ path: \"/auth\" }, customRouter);\n else\n throw ExitError(\n `ValidationError: The exported router from auth.router.${getUserFileExtension()} is not a valid express or arkos Router.`\n );\n }\n\n const authController = authControllerFactory(interceptors);\n\n if (routerConfig?.disable === true) return router;\n\n const getValidationSchemaOrDto = (\n key: \"updateMe\" | \"updatePassword\" | \"login\" | \"signup\"\n ) => {\n const validationConfigs = arkosConfig?.validation;\n if (validationConfigs?.resolver === \"class-validator\") return dtos?.[key];\n else if (validationConfigs?.resolver === \"zod\") return schemas?.[key];\n\n return undefined;\n };\n\n const endpoints: AuthRouterEndpoint[] = [\n \"login\",\n \"logout\",\n \"signup\",\n \"updatePassword\",\n \"getMe\",\n \"updateMe\",\n \"deleteMe\",\n \"findManyAuthAction\",\n \"findOneAuthAction\",\n ];\n\n for (const endpoint of endpoints) {\n let endpointConfig = routerConfig[endpoint] || {};\n\n const schema = getValidationSchemaOrDto(endpoint as any);\n if (\n schema &&\n endpointConfig?.validation !== false &&\n endpointConfig?.validation?.body !== false\n )\n endpointConfig = {\n ...(endpointConfig || {}),\n validation: {\n ...(endpointConfig?.validation || {}),\n body: schema,\n },\n };\n\n if (endpointConfig?.experimental?.openapi !== false)\n endpointConfig = {\n ...(endpointConfig || {}),\n experimental: {\n ...(endpointConfig?.experimental || {}),\n openapi: authOpenAPIGenerator.getOpenApiConfig(\n endpointConfig,\n endpoint\n ),\n },\n };\n\n routerConfig[endpoint] = endpointConfig;\n }\n\n // GET /users/me - Get current user\n if (!isEndpointDisabled(routerConfig, \"getMe\")) {\n router.get(\n createRouteConfig(\n arkosConfig,\n \"getMe\",\n \"users\",\n \"/me\",\n routerConfig,\n \"auth\",\n true\n ),\n addPrismaQueryOptionsToRequest<any>(\n prismaQueryOptions as AuthPrismaQueryOptions<any>,\n \"getMe\"\n ),\n ...processMiddleware(interceptors?.beforeGetMe),\n authController.getMe,\n ...processMiddleware(interceptors?.afterGetMe),\n sendResponse,\n ...processMiddleware(interceptors?.onGetMeError, { type: \"error\" })\n );\n }\n\n // PATCH /users/me - Update current user\n if (!isEndpointDisabled(routerConfig, \"updateMe\")) {\n router.patch(\n createRouteConfig(\n arkosConfig,\n \"updateMe\",\n \"users\",\n \"/me\",\n routerConfig,\n \"auth\",\n true\n ),\n addPrismaQueryOptionsToRequest<any>(\n prismaQueryOptions as AuthPrismaQueryOptions<any>,\n \"updateMe\"\n ),\n ...processMiddleware(interceptors?.beforeUpdateMe),\n authController.updateMe,\n ...processMiddleware(interceptors?.afterUpdateMe),\n sendResponse,\n ...processMiddleware(interceptors?.onUpdateMeError, { type: \"error\" })\n );\n }\n\n // DELETE /users/me - Delete current user\n if (!isEndpointDisabled(routerConfig, \"deleteMe\")) {\n router.delete(\n createRouteConfig(\n arkosConfig,\n \"deleteMe\",\n \"users\",\n \"/me\",\n routerConfig,\n \"auth\",\n true\n ),\n addPrismaQueryOptionsToRequest<any>(\n prismaQueryOptions as AuthPrismaQueryOptions<any>,\n \"deleteMe\"\n ),\n ...processMiddleware(interceptors?.beforeDeleteMe),\n authController.deleteMe,\n ...processMiddleware(interceptors?.afterDeleteMe),\n sendResponse,\n ...processMiddleware(interceptors?.onDeleteMeError, { type: \"error\" })\n );\n }\n\n // Apply rate limiting to auth routes\n if (\n !isEndpointDisabled(routerConfig, \"login\") ||\n !isEndpointDisabled(routerConfig, \"logout\") ||\n !isEndpointDisabled(routerConfig, \"signup\") ||\n !isEndpointDisabled(routerConfig, \"updatePassword\")\n ) {\n router.use(\n { path: \"/auth\" },\n rateLimit(\n deepmerge(\n {\n windowMs: 5000,\n limit: 10,\n standardHeaders: \"draft-7\",\n legacyHeaders: false,\n handler: (_, res) => {\n res.status(429).json({\n message: \"Too many requests, please try again later\",\n });\n },\n },\n arkosConfig?.authentication?.rateLimit || {}\n )\n )\n );\n }\n\n // POST /auth/login - Login\n if (!isEndpointDisabled(routerConfig, \"login\")) {\n router.post(\n createRouteConfig(\n arkosConfig,\n \"login\",\n \"auth\",\n \"/login\",\n routerConfig,\n \"auth\",\n false\n ),\n addPrismaQueryOptionsToRequest<any>(\n prismaQueryOptions as AuthPrismaQueryOptions<any>,\n \"login\"\n ),\n ...processMiddleware(interceptors?.beforeLogin),\n authController.login,\n ...processMiddleware(interceptors?.afterLogin),\n sendResponse,\n ...processMiddleware(interceptors?.onLoginError, { type: \"error\" })\n );\n }\n\n // DELETE /auth/logout - Logout\n if (!isEndpointDisabled(routerConfig, \"logout\")) {\n router.delete(\n createRouteConfig(\n arkosConfig,\n \"logout\",\n \"auth\",\n \"/logout\",\n routerConfig,\n \"auth\",\n true\n ),\n ...processMiddleware(interceptors?.beforeLogout),\n authController.logout,\n ...processMiddleware(interceptors?.afterLogout),\n sendResponse,\n ...processMiddleware(interceptors?.onLogoutError, { type: \"error\" })\n );\n }\n\n // POST /auth/signup - Signup\n if (!isEndpointDisabled(routerConfig, \"signup\")) {\n router.post(\n createRouteConfig(\n arkosConfig,\n \"signup\",\n \"auth\",\n \"/signup\",\n routerConfig,\n \"auth\",\n false\n ),\n addPrismaQueryOptionsToRequest<any>(\n prismaQueryOptions as AuthPrismaQueryOptions<any>,\n \"signup\"\n ),\n ...processMiddleware(interceptors?.beforeSignup),\n authController.signup,\n ...processMiddleware(interceptors?.afterSignup),\n sendResponse,\n ...processMiddleware(interceptors?.onSignupError, { type: \"error\" })\n );\n }\n\n // POST /auth/update-password - Update password\n if (!isEndpointDisabled(routerConfig, \"updatePassword\")) {\n router.post(\n createRouteConfig(\n arkosConfig,\n \"updatePassword\",\n \"auth\",\n \"/update-password\",\n routerConfig,\n \"auth\",\n true\n ),\n addPrismaQueryOptionsToRequest<any>(\n prismaQueryOptions as AuthPrismaQueryOptions<any>,\n \"updatePassword\"\n ),\n ...processMiddleware(interceptors?.beforeUpdatePassword),\n authController.updatePassword,\n ...processMiddleware(interceptors?.afterUpdatePassword),\n sendResponse,\n ...processMiddleware(interceptors?.onUpdatePasswordError, {\n type: \"error\",\n })\n );\n }\n\n // GET /auth-actions - Find many auth actions\n if (!isEndpointDisabled(routerConfig, \"findManyAuthAction\")) {\n router.get(\n createRouteConfig(\n arkosConfig,\n \"findManyAuthAction\",\n \"auth-actions\",\n \"\",\n routerConfig,\n \"auth\",\n authConfigs\n ),\n ...processMiddleware(interceptors?.beforeFindManyAuthAction),\n authController.findManyAuthAction,\n ...processMiddleware(interceptors?.afterFindManyAuthAction),\n sendResponse,\n ...processMiddleware(interceptors?.onFindManyAuthActionError, {\n type: \"error\",\n })\n );\n }\n\n // GET /auth-actions/:resourceName - Find one auth action\n if (!isEndpointDisabled(routerConfig, \"findOneAuthAction\")) {\n router.get(\n createRouteConfig(\n arkosConfig,\n \"findOneAuthAction\",\n \"auth-actions\",\n \"/:resourceName\",\n routerConfig,\n \"auth\",\n authConfigs\n ),\n ...processMiddleware(interceptors?.beforeFindOneAuthAction),\n authController.findOneAuthAction,\n ...processMiddleware(interceptors?.afterFindOneAuthAction),\n sendResponse,\n ...processMiddleware(interceptors?.onFindOneAuthActionError, {\n type: \"error\",\n })\n );\n }\n\n debuggerService.logModuleFinalRouter(\"auth\", router as any);\n return router;\n}\n"]}
@@ -19,6 +19,7 @@ const path_1 = __importDefault(require("path"));
19
19
  const arkos_router_1 = __importDefault(require("../../utils/arkos-router/index.js"));
20
20
  const file_upload_json_schema_generator_1 = __importDefault(require("./utils/file-upload-json-schema-generator.js"));
21
21
  const app_error_1 = __importDefault(require("../error-handler/utils/app-error.js"));
22
+ const exit_error_1 = __importDefault(require("../../utils/helpers/exit-error.js"));
22
23
  function getFileUploadRouter(arkosConfig) {
23
24
  const router = (0, arkos_router_1.default)();
24
25
  const { fileUpload, globalPrefix } = arkosConfig;
@@ -46,7 +47,7 @@ function getFileUploadRouter(arkosConfig) {
46
47
  if (router_validator_1.default.isExpressRouter(customRouter))
47
48
  router.use({ path: basePathname }, customRouter);
48
49
  else
49
- throw Error(`ValidationError: The exported router from file-upload.router.${(0, fs_helpers_1.getUserFileExtension)()} is not a valid express or arkos Router.`);
50
+ throw (0, exit_error_1.default)(`ValidationError: The exported router from file-upload.router.${(0, fs_helpers_1.getUserFileExtension)()} is not a valid express or arkos Router.`);
50
51
  }
51
52
  const endpoints = [
52
53
  "findFile",
@@ -1 +1 @@
1
- {"version":3,"file":"file-upload.router.js","sourceRoot":"","sources":["../../../../src/modules/file-upload/file-upload.router.ts"],"names":[],"mappings":"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","sourcesContent":["import { Router } from \"express\";\nimport { getModuleComponents } from \"../../utils/dynamic-loader\";\nimport fileUploadController from \"./file-upload.controller\";\nimport express from \"express\";\nimport deepmerge from \"../../utils/helpers/deepmerge.helper\";\nimport { AuthConfigs } from \"../../types/auth\";\nimport { sendResponse } from \"../base/base.middlewares\";\nimport {\n createRouteConfig,\n processMiddleware,\n} from \"../../utils/helpers/routers.helpers\";\nimport { adjustRequestUrl } from \"./utils/helpers/file-upload.helpers\";\nimport { isEndpointDisabled } from \"../base/utils/helpers/base.router.helpers\";\nimport debuggerService from \"../debugger/debugger.service\";\nimport routerValidator from \"../base/utils/router-validator\";\nimport { getUserFileExtension } from \"../../utils/helpers/fs.helpers\";\nimport { ArkosNextFunction, ArkosRequest, ArkosResponse } from \"../../exports\";\nimport path from \"path\";\nimport ArkosRouter from \"../../utils/arkos-router\";\nimport { UserArkosConfig } from \"../../utils/define-config\";\nimport { FileUploadRouterEndpoint } from \"../../types/router-config\";\nimport fileUploadJsonSchemaGenerator from \"./utils/file-upload-json-schema-generator\";\nimport AppError from \"../error-handler/utils/app-error\";\n\nexport function getFileUploadRouter(arkosConfig: UserArkosConfig) {\n const router = ArkosRouter();\n const { fileUpload, globalPrefix } = arkosConfig;\n\n if (!fileUpload?.enabled === false) return router;\n\n const moduleComponents = getModuleComponents(\"file-upload\");\n let {\n interceptors = {} as any,\n authConfigs = {} as AuthConfigs,\n router: customRouterModule,\n }: any = {};\n\n if (moduleComponents)\n ({\n interceptors = {},\n authConfigs = {},\n router: customRouterModule,\n } = moduleComponents);\n\n const routerConfig = customRouterModule?.config || {};\n if (routerConfig?.disable === true) return router;\n\n const customRouter = customRouterModule?.default as Router;\n let basePathname = fileUpload?.baseRoute || \"/api/uploads/\";\n\n if (!basePathname.startsWith(\"/\")) basePathname = \"/\" + basePathname;\n if (!basePathname.endsWith(\"/\")) basePathname = basePathname + \"/\";\n\n // Strip leading slash so createRouteConfig can prepend its own \"/\"\n // e.g. \"/api/uploads/\" → \"api/uploads/\" → createRouteConfig builds \"/api/uploads/*\"\n const baseRoutePrefix = basePathname.slice(1);\n\n if (customRouter && customRouterModule) {\n if (routerValidator.isExpressRouter(customRouter))\n router.use({ path: basePathname }, customRouter);\n else\n throw Error(\n `ValidationError: The exported router from file-upload.router.${getUserFileExtension()} is not a valid express or arkos Router.`\n );\n }\n\n const endpoints: FileUploadRouterEndpoint[] = [\n \"findFile\",\n \"uploadFile\",\n \"updateFile\",\n \"deleteFile\",\n ];\n\n for (const endpoint of endpoints) {\n const endpointConfig = routerConfig[endpoint];\n if (endpointConfig?.experimental?.openapi === false) continue;\n routerConfig[endpoint] = {\n ...(endpointConfig || {}),\n experimental: {\n ...(endpointConfig?.experimental || {}),\n openapi: fileUploadJsonSchemaGenerator.getOpenApiConfig(\n endpointConfig,\n endpoint\n ),\n },\n };\n }\n\n if (!isEndpointDisabled(routerConfig, \"findFile\")) {\n const baseUploadDirFullPath = path.resolve(\n path\n .join(process.cwd(), fileUpload?.baseUploadDir || \"uploads\")\n .replaceAll(\"//\", \"/\")\n );\n router.get(\n createRouteConfig(\n arkosConfig,\n \"findFile\",\n baseRoutePrefix,\n `*`,\n routerConfig,\n \"file-upload\",\n authConfigs\n ),\n ...processMiddleware(interceptors?.beforeFindFile),\n adjustRequestUrl,\n express.static(\n baseUploadDirFullPath,\n deepmerge(\n {\n maxAge: \"1y\",\n etag: true,\n lastModified: true,\n dotfiles: \"ignore\",\n fallthrough: false,\n index: false,\n cacheControl: true,\n },\n fileUpload?.expressStatic || {}\n )\n ),\n (\n err: any,\n req: ArkosRequest,\n _res: ArkosResponse,\n next: ArkosNextFunction\n ) => {\n if (err.code === \"ENOENT\") {\n const filepath = req.path.replace(\n `${globalPrefix}/${arkosConfig.fileUpload?.baseRoute}`.replace(\"//\", \"/\"),\n \"\"\n );\n throw new AppError(\n `File ${filepath} was not found`,\n 404,\n \"FileNotFound\",\n { filepath }\n );\n }\n\n next(err);\n },\n ...processMiddleware(interceptors?.onFindFileError, { type: \"error\" })\n );\n }\n\n if (!isEndpointDisabled(routerConfig, \"uploadFile\")) {\n router.post(\n createRouteConfig(\n arkosConfig,\n \"uploadFile\",\n baseRoutePrefix,\n `:fileType`,\n routerConfig,\n \"file-upload\",\n authConfigs\n ),\n ...processMiddleware(interceptors?.beforeUploadFile),\n fileUploadController.uploadFile,\n ...processMiddleware(interceptors?.afterUploadFile),\n sendResponse,\n ...processMiddleware(interceptors?.onUploadFileError, { type: \"error\" })\n );\n }\n\n if (!isEndpointDisabled(routerConfig, \"updateFile\")) {\n router.patch(\n createRouteConfig(\n arkosConfig,\n \"updateFile\",\n baseRoutePrefix,\n `:fileType/:fileName`,\n routerConfig,\n \"file-upload\",\n authConfigs\n ),\n ...processMiddleware(interceptors?.beforeUpdateFile),\n fileUploadController.updateFile,\n ...processMiddleware(interceptors?.afterUpdateFile),\n sendResponse,\n ...processMiddleware(interceptors?.onUpdateFileError, { type: \"error\" })\n );\n }\n\n if (!isEndpointDisabled(routerConfig, \"deleteFile\")) {\n router.delete(\n createRouteConfig(\n arkosConfig,\n \"deleteFile\",\n baseRoutePrefix,\n `:fileType/:fileName`,\n routerConfig,\n \"file-upload\",\n authConfigs\n ),\n ...processMiddleware(interceptors?.beforeDeleteFile),\n fileUploadController.deleteFile,\n ...processMiddleware(interceptors?.afterDeleteFile),\n sendResponse,\n ...processMiddleware(interceptors?.onDeleteFileError, { type: \"error\" })\n );\n }\n\n debuggerService.logModuleFinalRouter(\"file-upload\", router);\n return router;\n}\n"]}
1
+ {"version":3,"file":"file-upload.router.js","sourceRoot":"","sources":["../../../../src/modules/file-upload/file-upload.router.ts"],"names":[],"mappings":"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","sourcesContent":["import { Router } from \"express\";\nimport { getModuleComponents } from \"../../utils/dynamic-loader\";\nimport fileUploadController from \"./file-upload.controller\";\nimport express from \"express\";\nimport deepmerge from \"../../utils/helpers/deepmerge.helper\";\nimport { AuthConfigs } from \"../../types/auth\";\nimport { sendResponse } from \"../base/base.middlewares\";\nimport {\n createRouteConfig,\n processMiddleware,\n} from \"../../utils/helpers/routers.helpers\";\nimport { adjustRequestUrl } from \"./utils/helpers/file-upload.helpers\";\nimport { isEndpointDisabled } from \"../base/utils/helpers/base.router.helpers\";\nimport debuggerService from \"../debugger/debugger.service\";\nimport routerValidator from \"../base/utils/router-validator\";\nimport { getUserFileExtension } from \"../../utils/helpers/fs.helpers\";\nimport { ArkosNextFunction, ArkosRequest, ArkosResponse } from \"../../exports\";\nimport path from \"path\";\nimport ArkosRouter from \"../../utils/arkos-router\";\nimport { UserArkosConfig } from \"../../utils/define-config\";\nimport { FileUploadRouterEndpoint } from \"../../types/router-config\";\nimport fileUploadJsonSchemaGenerator from \"./utils/file-upload-json-schema-generator\";\nimport AppError from \"../error-handler/utils/app-error\";\nimport ExitError from \"../../utils/helpers/exit-error\";\n\nexport function getFileUploadRouter(arkosConfig: UserArkosConfig) {\n const router = ArkosRouter();\n const { fileUpload, globalPrefix } = arkosConfig;\n\n if (!fileUpload?.enabled === false) return router;\n\n const moduleComponents = getModuleComponents(\"file-upload\");\n let {\n interceptors = {} as any,\n authConfigs = {} as AuthConfigs,\n router: customRouterModule,\n }: any = {};\n\n if (moduleComponents)\n ({\n interceptors = {},\n authConfigs = {},\n router: customRouterModule,\n } = moduleComponents);\n\n const routerConfig = customRouterModule?.config || {};\n if (routerConfig?.disable === true) return router;\n\n const customRouter = customRouterModule?.default as Router;\n let basePathname = fileUpload?.baseRoute || \"/api/uploads/\";\n\n if (!basePathname.startsWith(\"/\")) basePathname = \"/\" + basePathname;\n if (!basePathname.endsWith(\"/\")) basePathname = basePathname + \"/\";\n\n // Strip leading slash so createRouteConfig can prepend its own \"/\"\n // e.g. \"/api/uploads/\" → \"api/uploads/\" → createRouteConfig builds \"/api/uploads/*\"\n const baseRoutePrefix = basePathname.slice(1);\n\n if (customRouter && customRouterModule) {\n if (routerValidator.isExpressRouter(customRouter))\n router.use({ path: basePathname }, customRouter);\n else\n throw ExitError(\n `ValidationError: The exported router from file-upload.router.${getUserFileExtension()} is not a valid express or arkos Router.`\n );\n }\n\n const endpoints: FileUploadRouterEndpoint[] = [\n \"findFile\",\n \"uploadFile\",\n \"updateFile\",\n \"deleteFile\",\n ];\n\n for (const endpoint of endpoints) {\n const endpointConfig = routerConfig[endpoint];\n if (endpointConfig?.experimental?.openapi === false) continue;\n routerConfig[endpoint] = {\n ...(endpointConfig || {}),\n experimental: {\n ...(endpointConfig?.experimental || {}),\n openapi: fileUploadJsonSchemaGenerator.getOpenApiConfig(\n endpointConfig,\n endpoint\n ),\n },\n };\n }\n\n if (!isEndpointDisabled(routerConfig, \"findFile\")) {\n const baseUploadDirFullPath = path.resolve(\n path\n .join(process.cwd(), fileUpload?.baseUploadDir || \"uploads\")\n .replaceAll(\"//\", \"/\")\n );\n router.get(\n createRouteConfig(\n arkosConfig,\n \"findFile\",\n baseRoutePrefix,\n `*`,\n routerConfig,\n \"file-upload\",\n authConfigs\n ),\n ...processMiddleware(interceptors?.beforeFindFile),\n adjustRequestUrl,\n express.static(\n baseUploadDirFullPath,\n deepmerge(\n {\n maxAge: \"1y\",\n etag: true,\n lastModified: true,\n dotfiles: \"ignore\",\n fallthrough: false,\n index: false,\n cacheControl: true,\n },\n fileUpload?.expressStatic || {}\n )\n ),\n (\n err: any,\n req: ArkosRequest,\n _res: ArkosResponse,\n next: ArkosNextFunction\n ) => {\n if (err.code === \"ENOENT\") {\n const filepath = req.path.replace(\n `${globalPrefix}/${arkosConfig.fileUpload?.baseRoute}`.replace(\"//\", \"/\"),\n \"\"\n );\n throw new AppError(\n `File ${filepath} was not found`,\n 404,\n \"FileNotFound\",\n { filepath }\n );\n }\n\n next(err);\n },\n ...processMiddleware(interceptors?.onFindFileError, { type: \"error\" })\n );\n }\n\n if (!isEndpointDisabled(routerConfig, \"uploadFile\")) {\n router.post(\n createRouteConfig(\n arkosConfig,\n \"uploadFile\",\n baseRoutePrefix,\n `:fileType`,\n routerConfig,\n \"file-upload\",\n authConfigs\n ),\n ...processMiddleware(interceptors?.beforeUploadFile),\n fileUploadController.uploadFile,\n ...processMiddleware(interceptors?.afterUploadFile),\n sendResponse,\n ...processMiddleware(interceptors?.onUploadFileError, { type: \"error\" })\n );\n }\n\n if (!isEndpointDisabled(routerConfig, \"updateFile\")) {\n router.patch(\n createRouteConfig(\n arkosConfig,\n \"updateFile\",\n baseRoutePrefix,\n `:fileType/:fileName`,\n routerConfig,\n \"file-upload\",\n authConfigs\n ),\n ...processMiddleware(interceptors?.beforeUpdateFile),\n fileUploadController.updateFile,\n ...processMiddleware(interceptors?.afterUpdateFile),\n sendResponse,\n ...processMiddleware(interceptors?.onUpdateFileError, { type: \"error\" })\n );\n }\n\n if (!isEndpointDisabled(routerConfig, \"deleteFile\")) {\n router.delete(\n createRouteConfig(\n arkosConfig,\n \"deleteFile\",\n baseRoutePrefix,\n `:fileType/:fileName`,\n routerConfig,\n \"file-upload\",\n authConfigs\n ),\n ...processMiddleware(interceptors?.beforeDeleteFile),\n fileUploadController.deleteFile,\n ...processMiddleware(interceptors?.afterDeleteFile),\n sendResponse,\n ...processMiddleware(interceptors?.onDeleteFileError, { type: \"error\" })\n );\n }\n\n debuggerService.logModuleFinalRouter(\"file-upload\", router);\n return router;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"arkos-router-openapi-manager.js","sourceRoot":"","sources":["../../../../src/utils/arkos-router/arkos-router-openapi-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { OpenAPIV3 } from \"openapi-types\";\nimport deepmerge from \"../helpers/deepmerge.helper\";\nimport {\n ArkosRouterBaseUploadConfig,\n UploadConfig,\n UploadConfigFieldEntry,\n} from \"./types/upload-config\";\n\nclass ArkosRouterOpenAPIManager {\n private resolveSchemaFieldName(name: string): string {\n return name.replace(/\\[\\]/g, \"[0]\");\n }\n /**\n * Generates OpenAPI schema for file upload fields in multipart/form-data requests.\n * Converts upload configuration into OpenAPI-compliant schema and merges with existing body schema.\n *\n * @param {UploadConfig} uploadConfig - The upload configuration from config.experimental.uploads\n * @param {any} existingSchema - Existing JSON schema from config.validation.body (optional)\n * @returns {{ schema: any }} OpenAPI schema object for multipart/form-data content type\n *\n * @example\n * // Single file upload\n * addUploadFields({ type: 'single', field: 'avatar', maxSize: 5242880 })\n * // Returns: { schema: { type: 'object', properties: { avatar: { type: 'string', format: 'binary' } } } }\n *\n * @example\n * // Array file upload\n * addUploadFields({ type: 'array', field: 'gallery', maxCount: 10 })\n *\n * @example\n * // Multiple fields upload\n * addUploadFields({\n * type: 'fields',\n * fields: [\n * { name: 'avatar', type: 'single', uploadDir: 'images' },\n * { name: 'gallery', type: 'array', maxCount: 6, uploadDir: 'gallery' },\n * { name: 'banners[][images]', type: 'array', maxCount: 5, uploadDir: 'banners' }\n * ]\n * })\n */\n addUploadFields(\n uploadConfig: UploadConfig,\n existingSchema: OpenAPIV3.SchemaObject = {}\n ): OpenAPIV3.SchemaObject {\n const uploadSchema: any = {\n type: \"object\",\n properties: {},\n required: [],\n };\n\n if (uploadConfig.type === \"single\") {\n const schemaKey = this.resolveSchemaFieldName(uploadConfig.field);\n uploadSchema.properties[schemaKey] = {\n type: \"string\",\n format: \"binary\",\n description:\n uploadConfig.description ||\n `Single file field${uploadConfig.maxSize ? `, max size: ${uploadConfig.maxSize} bytes` : \"\"}`,\n };\n if (uploadConfig.required !== false) {\n uploadSchema.required.push(schemaKey);\n }\n } else if (uploadConfig.type === \"array\") {\n const schemaKey = this.resolveSchemaFieldName(uploadConfig.field);\n uploadSchema.properties[schemaKey] = {\n type: \"array\",\n items: {\n type: \"string\",\n format: \"binary\",\n },\n ...(uploadConfig.maxCount && { maxItems: uploadConfig.maxCount }),\n ...(uploadConfig.minCount && { minItems: uploadConfig.minCount }),\n description:\n uploadConfig.description ||\n `Array file field${uploadConfig.maxSize ? `, max size per file: ${uploadConfig.maxSize} bytes` : \"\"}`,\n };\n if (uploadConfig.required !== false) {\n uploadSchema.required.push(schemaKey);\n }\n } else if (uploadConfig.type === \"fields\") {\n for (const field of uploadConfig.fields) {\n uploadSchema.properties[this.resolveSchemaFieldName(field.name)] =\n this.buildFieldSchema(field, uploadConfig);\n\n // legacy shape has no type and no required — default to required\n const isRequired =\n (field as any).type === undefined\n ? (uploadConfig as any).required !== false\n : (field as any).required !== false;\n\n if (isRequired) {\n uploadSchema.required.push(this.resolveSchemaFieldName(field.name));\n }\n }\n }\n\n // Clean up empty required array\n if (uploadSchema.required.length === 0) delete uploadSchema.required;\n\n return deepmerge(existingSchema as any, uploadSchema);\n }\n\n /**\n * Builds the OpenAPI property schema for a single field entry.\n * Legacy entries (no type) are treated as array.\n */\n private buildFieldSchema(\n field: UploadConfigFieldEntry,\n config: ArkosRouterBaseUploadConfig\n ): object {\n const maxSize = field.maxSize ?? config.maxSize;\n\n if (field.type === \"single\") {\n return {\n type: \"string\",\n format: \"binary\",\n description:\n field.description ||\n `Single file field${maxSize ? `, max size: ${maxSize} bytes` : \"\"}`,\n };\n }\n\n // type === \"array\" or legacy (no type) — both produce array schema\n return {\n type: \"array\",\n items: {\n type: \"string\",\n format: \"binary\",\n },\n ...(field.maxCount && { maxItems: field.maxCount }),\n ...(field.type === \"array\" &&\n field.minCount && { minItems: field.minCount }),\n description:\n (field.type === \"array\" && field.description) ||\n `Array file field${maxSize ? `, max size per file: ${maxSize} bytes` : \"\"}`,\n };\n }\n\n /**\n * Validates that a user-defined multipart/form-data schema includes all required upload fields\n * with correct types, formats, and required flags.\n *\n * @param {any} userDefinedMultipartSchema - The schema object from openapi.requestBody.content['multipart/form-data'].schema\n * @param {UploadConfig} uploadConfig - The upload configuration from config.experimental.uploads\n * @param {string} routePath - The route path for error context\n * @throws {Error} If upload fields are missing or incorrectly defined\n *\n * @example\n * validateMultipartFormDocs(\n * { type: 'object', properties: { avatar: { type: 'string', format: 'binary' } } },\n * { type: 'single', field: 'avatar', required: true },\n * '/users/:id/avatar'\n * )\n */\n validateMultipartFormDocs(\n userDefinedMultipartSchema: any,\n routePath: string,\n uploadConfig?: UploadConfig\n ): void {\n const errors: string[] = [];\n const properties = userDefinedMultipartSchema?.properties || {};\n const requiredFields = userDefinedMultipartSchema?.required || [];\n\n const expectedFields: Array<{\n name: string;\n required: boolean;\n expectedType: \"single\" | \"array\";\n }> = [];\n\n if (uploadConfig?.type === \"single\") {\n expectedFields.push({\n name: uploadConfig.field,\n required: uploadConfig.required !== false,\n expectedType: \"single\",\n });\n } else if (uploadConfig?.type === \"array\") {\n expectedFields.push({\n name: uploadConfig.field,\n required: uploadConfig.required !== false,\n expectedType: \"array\",\n });\n } else if (uploadConfig?.type === \"fields\") {\n for (const field of uploadConfig.fields) {\n if (!(\"type\" in field)) {\n expectedFields.push({\n name: field.name,\n // legacy shape has no type and no required — default to required\n required:\n (uploadConfig as ArkosRouterBaseUploadConfig).required ===\n undefined\n ? true\n : ((uploadConfig as ArkosRouterBaseUploadConfig)\n .required as boolean),\n expectedType: \"array\",\n });\n } else if (field.type)\n expectedFields.push({\n name: field.name,\n required:\n field.type === undefined ? true : field.required !== false,\n expectedType: field.type ?? \"array\",\n });\n }\n }\n\n for (const { name, required, expectedType } of expectedFields) {\n const schemaKey = this.resolveSchemaFieldName(name);\n const fieldSchema = properties[schemaKey];\n\n if (!fieldSchema) {\n errors.push(\n `Missing upload field '${name}' in multipart/form-data schema`\n );\n continue;\n }\n\n if (expectedType === \"single\") {\n if (fieldSchema.type !== \"string\")\n errors.push(\n `Upload field '${name}' must have type 'string', got '${fieldSchema.type}'`\n );\n\n if (fieldSchema.format !== \"binary\")\n errors.push(\n `Upload field '${name}' must have format 'binary', got '${fieldSchema.format || \"undefined\"}'`\n );\n } else if (expectedType === \"array\") {\n if (fieldSchema.type !== \"array\") {\n errors.push(\n `Upload field '${name}' must have type 'array', got '${fieldSchema.type}'`\n );\n } else if (\n !fieldSchema.items ||\n fieldSchema.items.type !== \"string\" ||\n fieldSchema.items.format !== \"binary\"\n )\n errors.push(\n `Upload field '${name}' must have items with type 'string' and format 'binary'`\n );\n }\n\n const isMarkedRequired = requiredFields.includes(schemaKey);\n if (required && !isMarkedRequired)\n errors.push(\n `Upload field '${name}' is required in config but not marked as required in schema`\n );\n\n if (!required && isMarkedRequired)\n errors.push(\n `Upload field '${name}' is not required in config but marked as required in schema`\n );\n }\n\n if (errors.length > 0) {\n throw new Error(\n `ValidationError: Invalid multipart/form-data schema for route '${routePath}':\\n${errors.map((e) => ` - ${e}`).join(\"\\n\")}`\n );\n }\n }\n}\n\nconst arkosRouterOpenApiManager = new ArkosRouterOpenAPIManager();\n\nexport default arkosRouterOpenApiManager;\n"]}
1
+ {"version":3,"file":"arkos-router-openapi-manager.js","sourceRoot":"","sources":["../../../../src/utils/arkos-router/arkos-router-openapi-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { OpenAPIV3 } from \"openapi-types\";\nimport deepmerge from \"../helpers/deepmerge.helper\";\nimport {\n ArkosRouterBaseUploadConfig,\n UploadConfig,\n UploadConfigFieldEntry,\n} from \"./types/upload-config\";\nclass ArkosRouterOpenAPIManager {\n private resolveSchemaFieldName(name: string): string {\n return name.replace(/\\[\\]/g, \"[0]\");\n }\n /**\n * Generates OpenAPI schema for file upload fields in multipart/form-data requests.\n * Converts upload configuration into OpenAPI-compliant schema and merges with existing body schema.\n *\n * @param {UploadConfig} uploadConfig - The upload configuration from config.experimental.uploads\n * @param {any} existingSchema - Existing JSON schema from config.validation.body (optional)\n * @returns {{ schema: any }} OpenAPI schema object for multipart/form-data content type\n *\n * @example\n * // Single file upload\n * addUploadFields({ type: 'single', field: 'avatar', maxSize: 5242880 })\n * // Returns: { schema: { type: 'object', properties: { avatar: { type: 'string', format: 'binary' } } } }\n *\n * @example\n * // Array file upload\n * addUploadFields({ type: 'array', field: 'gallery', maxCount: 10 })\n *\n * @example\n * // Multiple fields upload\n * addUploadFields({\n * type: 'fields',\n * fields: [\n * { name: 'avatar', type: 'single', uploadDir: 'images' },\n * { name: 'gallery', type: 'array', maxCount: 6, uploadDir: 'gallery' },\n * { name: 'banners[][images]', type: 'array', maxCount: 5, uploadDir: 'banners' }\n * ]\n * })\n */\n addUploadFields(\n uploadConfig: UploadConfig,\n existingSchema: OpenAPIV3.SchemaObject = {}\n ): OpenAPIV3.SchemaObject {\n const uploadSchema: any = {\n type: \"object\",\n properties: {},\n required: [],\n };\n\n if (uploadConfig.type === \"single\") {\n const schemaKey = this.resolveSchemaFieldName(uploadConfig.field);\n uploadSchema.properties[schemaKey] = {\n type: \"string\",\n format: \"binary\",\n description:\n uploadConfig.description ||\n `Single file field${uploadConfig.maxSize ? `, max size: ${uploadConfig.maxSize} bytes` : \"\"}`,\n };\n if (uploadConfig.required !== false) {\n uploadSchema.required.push(schemaKey);\n }\n } else if (uploadConfig.type === \"array\") {\n const schemaKey = this.resolveSchemaFieldName(uploadConfig.field);\n uploadSchema.properties[schemaKey] = {\n type: \"array\",\n items: {\n type: \"string\",\n format: \"binary\",\n },\n ...(uploadConfig.maxCount && { maxItems: uploadConfig.maxCount }),\n ...(uploadConfig.minCount && { minItems: uploadConfig.minCount }),\n description:\n uploadConfig.description ||\n `Array file field${uploadConfig.maxSize ? `, max size per file: ${uploadConfig.maxSize} bytes` : \"\"}`,\n };\n if (uploadConfig.required !== false) {\n uploadSchema.required.push(schemaKey);\n }\n } else if (uploadConfig.type === \"fields\") {\n for (const field of uploadConfig.fields) {\n uploadSchema.properties[this.resolveSchemaFieldName(field.name)] =\n this.buildFieldSchema(field, uploadConfig);\n\n // legacy shape has no type and no required — default to required\n const isRequired =\n (field as any).type === undefined\n ? (uploadConfig as any).required !== false\n : (field as any).required !== false;\n\n if (isRequired) {\n uploadSchema.required.push(this.resolveSchemaFieldName(field.name));\n }\n }\n }\n\n // Clean up empty required array\n if (uploadSchema.required.length === 0) delete uploadSchema.required;\n\n return deepmerge(existingSchema as any, uploadSchema);\n }\n\n /**\n * Builds the OpenAPI property schema for a single field entry.\n * Legacy entries (no type) are treated as array.\n */\n private buildFieldSchema(\n field: UploadConfigFieldEntry,\n config: ArkosRouterBaseUploadConfig\n ): object {\n const maxSize = field.maxSize ?? config.maxSize;\n\n if (field.type === \"single\") {\n return {\n type: \"string\",\n format: \"binary\",\n description:\n field.description ||\n `Single file field${maxSize ? `, max size: ${maxSize} bytes` : \"\"}`,\n };\n }\n\n // type === \"array\" or legacy (no type) — both produce array schema\n return {\n type: \"array\",\n items: {\n type: \"string\",\n format: \"binary\",\n },\n ...(field.maxCount && { maxItems: field.maxCount }),\n ...(field.type === \"array\" &&\n field.minCount && { minItems: field.minCount }),\n description:\n (field.type === \"array\" && field.description) ||\n `Array file field${maxSize ? `, max size per file: ${maxSize} bytes` : \"\"}`,\n };\n }\n\n /**\n * Validates that a user-defined multipart/form-data schema includes all required upload fields\n * with correct types, formats, and required flags.\n *\n * @param {any} userDefinedMultipartSchema - The schema object from openapi.requestBody.content['multipart/form-data'].schema\n * @param {UploadConfig} uploadConfig - The upload configuration from config.experimental.uploads\n * @param {string} routePath - The route path for error context\n * @throws {Error} If upload fields are missing or incorrectly defined\n *\n * @example\n * validateMultipartFormDocs(\n * { type: 'object', properties: { avatar: { type: 'string', format: 'binary' } } },\n * { type: 'single', field: 'avatar', required: true },\n * '/users/:id/avatar'\n * )\n */\n validateMultipartFormDocs(\n userDefinedMultipartSchema: any,\n routePath: string,\n uploadConfig?: UploadConfig\n ): void {\n const errors: string[] = [];\n const properties = userDefinedMultipartSchema?.properties || {};\n const requiredFields = userDefinedMultipartSchema?.required || [];\n\n const expectedFields: Array<{\n name: string;\n required: boolean;\n expectedType: \"single\" | \"array\";\n }> = [];\n\n if (uploadConfig?.type === \"single\") {\n expectedFields.push({\n name: uploadConfig.field,\n required: uploadConfig.required !== false,\n expectedType: \"single\",\n });\n } else if (uploadConfig?.type === \"array\") {\n expectedFields.push({\n name: uploadConfig.field,\n required: uploadConfig.required !== false,\n expectedType: \"array\",\n });\n } else if (uploadConfig?.type === \"fields\") {\n for (const field of uploadConfig.fields) {\n if (!(\"type\" in field)) {\n expectedFields.push({\n name: field.name,\n // legacy shape has no type and no required — default to required\n required:\n (uploadConfig as ArkosRouterBaseUploadConfig).required ===\n undefined\n ? true\n : ((uploadConfig as ArkosRouterBaseUploadConfig)\n .required as boolean),\n expectedType: \"array\",\n });\n } else if (field.type)\n expectedFields.push({\n name: field.name,\n required:\n field.type === undefined ? true : field.required !== false,\n expectedType: field.type ?? \"array\",\n });\n }\n }\n\n for (const { name, required, expectedType } of expectedFields) {\n const schemaKey = this.resolveSchemaFieldName(name);\n const fieldSchema = properties[schemaKey];\n\n if (!fieldSchema) {\n errors.push(\n `Missing upload field '${name}' in multipart/form-data schema`\n );\n continue;\n }\n\n if (expectedType === \"single\") {\n if (fieldSchema.type !== \"string\")\n errors.push(\n `Upload field '${name}' must have type 'string', got '${fieldSchema.type}'`\n );\n\n if (fieldSchema.format !== \"binary\")\n errors.push(\n `Upload field '${name}' must have format 'binary', got '${fieldSchema.format || \"undefined\"}'`\n );\n } else if (expectedType === \"array\") {\n if (fieldSchema.type !== \"array\") {\n errors.push(\n `Upload field '${name}' must have type 'array', got '${fieldSchema.type}'`\n );\n } else if (\n !fieldSchema.items ||\n fieldSchema.items.type !== \"string\" ||\n fieldSchema.items.format !== \"binary\"\n )\n errors.push(\n `Upload field '${name}' must have items with type 'string' and format 'binary'`\n );\n }\n\n const isMarkedRequired = requiredFields.includes(schemaKey);\n if (required && !isMarkedRequired)\n errors.push(\n `Upload field '${name}' is required in config but not marked as required in schema`\n );\n\n if (!required && isMarkedRequired)\n errors.push(\n `Upload field '${name}' is not required in config but marked as required in schema`\n );\n }\n\n if (errors.length > 0) {\n throw new Error(\n `ValidationError: Invalid multipart/form-data schema for route '${routePath}':\\n${errors.map((e) => ` - ${e}`).join(\"\\n\")}`\n );\n }\n }\n}\n\nconst arkosRouterOpenApiManager = new ArkosRouterOpenAPIManager();\n\nexport default arkosRouterOpenApiManager;\n"]}