equipped 5.1.10 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (230) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/cjs/dbs/mongo/changes.cjs +5 -1
  3. package/dist/cjs/dbs/mongo/changes.cjs.map +1 -1
  4. package/dist/cjs/dbs/mongo/changes.min.cjs +1 -1
  5. package/dist/cjs/dbs/mongo/changes.min.cjs.map +1 -1
  6. package/dist/cjs/errors/index.cjs +1 -2
  7. package/dist/cjs/errors/index.cjs.map +1 -1
  8. package/dist/cjs/errors/index.min.cjs +1 -1
  9. package/dist/cjs/errors/index.min.cjs.map +1 -1
  10. package/dist/cjs/errors/types/tokenExpired.cjs +12 -0
  11. package/dist/cjs/errors/types/tokenExpired.cjs.map +1 -0
  12. package/dist/cjs/errors/types/{refreshTokenMisusedError.min.cjs → tokenExpired.min.cjs} +2 -2
  13. package/dist/cjs/errors/types/tokenExpired.min.cjs.map +1 -0
  14. package/dist/cjs/events/types/kafka.cjs +13 -16
  15. package/dist/cjs/events/types/kafka.cjs.map +1 -1
  16. package/dist/cjs/events/types/kafka.min.cjs +1 -1
  17. package/dist/cjs/events/types/kafka.min.cjs.map +1 -1
  18. package/dist/cjs/instance/index.cjs.map +1 -1
  19. package/dist/cjs/instance/index.min.cjs.map +1 -1
  20. package/dist/cjs/server/impls/base.cjs +17 -17
  21. package/dist/cjs/server/impls/base.cjs.map +1 -1
  22. package/dist/cjs/server/impls/base.min.cjs +1 -1
  23. package/dist/cjs/server/impls/base.min.cjs.map +1 -1
  24. package/dist/cjs/server/impls/express.cjs +2 -13
  25. package/dist/cjs/server/impls/express.cjs.map +1 -1
  26. package/dist/cjs/server/impls/express.min.cjs +1 -1
  27. package/dist/cjs/server/impls/express.min.cjs.map +1 -1
  28. package/dist/cjs/server/impls/fastify.cjs +3 -14
  29. package/dist/cjs/server/impls/fastify.cjs.map +1 -1
  30. package/dist/cjs/server/impls/fastify.min.cjs +1 -1
  31. package/dist/cjs/server/impls/fastify.min.cjs.map +1 -1
  32. package/dist/cjs/server/index.cjs +1 -1
  33. package/dist/cjs/server/index.cjs.map +1 -1
  34. package/dist/cjs/server/index.min.cjs +1 -1
  35. package/dist/cjs/server/index.min.cjs.map +1 -1
  36. package/dist/cjs/server/middlewares/requireAuthUser.cjs +9 -52
  37. package/dist/cjs/server/middlewares/requireAuthUser.cjs.map +1 -1
  38. package/dist/cjs/server/middlewares/requireAuthUser.min.cjs +1 -1
  39. package/dist/cjs/server/middlewares/requireAuthUser.min.cjs.map +1 -1
  40. package/dist/cjs/server/pipes.cjs +23 -8
  41. package/dist/cjs/server/pipes.cjs.map +1 -1
  42. package/dist/cjs/server/pipes.min.cjs +1 -1
  43. package/dist/cjs/server/pipes.min.cjs.map +1 -1
  44. package/dist/cjs/server/requests-auth-methods/apiKeys.cjs +21 -0
  45. package/dist/cjs/server/requests-auth-methods/apiKeys.cjs.map +1 -0
  46. package/dist/cjs/server/requests-auth-methods/apiKeys.min.cjs +2 -0
  47. package/dist/cjs/server/requests-auth-methods/apiKeys.min.cjs.map +1 -0
  48. package/dist/cjs/server/requests-auth-methods/base.cjs +20 -0
  49. package/dist/cjs/server/requests-auth-methods/base.cjs.map +1 -0
  50. package/dist/cjs/server/requests-auth-methods/base.min.cjs +2 -0
  51. package/dist/cjs/server/requests-auth-methods/base.min.cjs.map +1 -0
  52. package/dist/cjs/server/{requests-auth → requests-auth-methods}/index.cjs +2 -1
  53. package/dist/cjs/server/requests-auth-methods/index.cjs.map +1 -0
  54. package/dist/cjs/server/{requests-auth → requests-auth-methods}/index.min.cjs +1 -1
  55. package/dist/cjs/server/requests-auth-methods/index.min.cjs.map +1 -0
  56. package/dist/cjs/server/requests-auth-methods/jwt.cjs +78 -0
  57. package/dist/cjs/server/requests-auth-methods/jwt.cjs.map +1 -0
  58. package/dist/cjs/server/requests-auth-methods/jwt.min.cjs +2 -0
  59. package/dist/cjs/server/requests-auth-methods/jwt.min.cjs.map +1 -0
  60. package/dist/cjs/server/requests.cjs +1 -9
  61. package/dist/cjs/server/requests.cjs.map +1 -1
  62. package/dist/cjs/server/requests.min.cjs +1 -1
  63. package/dist/cjs/server/requests.min.cjs.map +1 -1
  64. package/dist/cjs/server/routes.cjs +1 -2
  65. package/dist/cjs/server/routes.cjs.map +1 -1
  66. package/dist/cjs/server/routes.min.cjs +1 -1
  67. package/dist/cjs/server/routes.min.cjs.map +1 -1
  68. package/dist/cjs/server/sockets.cjs +2 -4
  69. package/dist/cjs/server/sockets.cjs.map +1 -1
  70. package/dist/cjs/server/sockets.min.cjs +1 -1
  71. package/dist/cjs/server/sockets.min.cjs.map +1 -1
  72. package/dist/cjs/server/types.cjs +1 -1
  73. package/dist/cjs/server/types.cjs.map +1 -1
  74. package/dist/cjs/server/types.min.cjs +1 -1
  75. package/dist/cjs/server/types.min.cjs.map +1 -1
  76. package/dist/esm/dbs/mongo/changes.min.mjs +1 -1
  77. package/dist/esm/dbs/mongo/changes.min.mjs.map +1 -1
  78. package/dist/esm/dbs/mongo/changes.mjs +5 -1
  79. package/dist/esm/dbs/mongo/changes.mjs.map +1 -1
  80. package/dist/esm/errors/index.min.mjs +1 -1
  81. package/dist/esm/errors/index.min.mjs.map +1 -1
  82. package/dist/esm/errors/index.mjs +1 -2
  83. package/dist/esm/errors/index.mjs.map +1 -1
  84. package/dist/esm/errors/types/tokenExpired.min.mjs +2 -0
  85. package/dist/esm/errors/types/tokenExpired.min.mjs.map +1 -0
  86. package/dist/esm/errors/types/tokenExpired.mjs +12 -0
  87. package/dist/esm/errors/types/tokenExpired.mjs.map +1 -0
  88. package/dist/esm/events/types/kafka.min.mjs +1 -1
  89. package/dist/esm/events/types/kafka.min.mjs.map +1 -1
  90. package/dist/esm/events/types/kafka.mjs +13 -16
  91. package/dist/esm/events/types/kafka.mjs.map +1 -1
  92. package/dist/esm/instance/index.min.mjs +1 -1
  93. package/dist/esm/instance/index.min.mjs.map +1 -1
  94. package/dist/esm/instance/index.mjs.map +1 -1
  95. package/dist/esm/server/impls/base.min.mjs +1 -1
  96. package/dist/esm/server/impls/base.min.mjs.map +1 -1
  97. package/dist/esm/server/impls/base.mjs +9 -9
  98. package/dist/esm/server/impls/base.mjs.map +1 -1
  99. package/dist/esm/server/impls/express.min.mjs +1 -1
  100. package/dist/esm/server/impls/express.min.mjs.map +1 -1
  101. package/dist/esm/server/impls/express.mjs +2 -13
  102. package/dist/esm/server/impls/express.mjs.map +1 -1
  103. package/dist/esm/server/impls/fastify.min.mjs +1 -1
  104. package/dist/esm/server/impls/fastify.min.mjs.map +1 -1
  105. package/dist/esm/server/impls/fastify.mjs +2 -13
  106. package/dist/esm/server/impls/fastify.mjs.map +1 -1
  107. package/dist/esm/server/index.min.mjs +1 -1
  108. package/dist/esm/server/index.min.mjs.map +1 -1
  109. package/dist/esm/server/index.mjs +1 -1
  110. package/dist/esm/server/index.mjs.map +1 -1
  111. package/dist/esm/server/middlewares/requireAuthUser.min.mjs +1 -1
  112. package/dist/esm/server/middlewares/requireAuthUser.min.mjs.map +1 -1
  113. package/dist/esm/server/middlewares/requireAuthUser.mjs +9 -52
  114. package/dist/esm/server/middlewares/requireAuthUser.mjs.map +1 -1
  115. package/dist/esm/server/pipes.min.mjs +1 -1
  116. package/dist/esm/server/pipes.min.mjs.map +1 -1
  117. package/dist/esm/server/pipes.mjs +23 -8
  118. package/dist/esm/server/pipes.mjs.map +1 -1
  119. package/dist/esm/server/requests-auth-methods/apiKeys.min.mjs +2 -0
  120. package/dist/esm/server/requests-auth-methods/apiKeys.min.mjs.map +1 -0
  121. package/dist/esm/server/requests-auth-methods/apiKeys.mjs +21 -0
  122. package/dist/esm/server/requests-auth-methods/apiKeys.mjs.map +1 -0
  123. package/dist/esm/server/requests-auth-methods/base.min.mjs +2 -0
  124. package/dist/esm/server/requests-auth-methods/base.min.mjs.map +1 -0
  125. package/dist/esm/server/requests-auth-methods/base.mjs +20 -0
  126. package/dist/esm/server/requests-auth-methods/base.mjs.map +1 -0
  127. package/dist/esm/server/requests-auth-methods/index.min.mjs +2 -0
  128. package/dist/esm/server/requests-auth-methods/index.min.mjs.map +1 -0
  129. package/dist/esm/server/requests-auth-methods/index.mjs +4 -0
  130. package/dist/esm/server/requests-auth-methods/index.mjs.map +1 -0
  131. package/dist/esm/server/requests-auth-methods/jwt.min.mjs +2 -0
  132. package/dist/esm/server/requests-auth-methods/jwt.min.mjs.map +1 -0
  133. package/dist/esm/server/requests-auth-methods/jwt.mjs +78 -0
  134. package/dist/esm/server/requests-auth-methods/jwt.mjs.map +1 -0
  135. package/dist/esm/server/requests.min.mjs +1 -1
  136. package/dist/esm/server/requests.min.mjs.map +1 -1
  137. package/dist/esm/server/requests.mjs +1 -9
  138. package/dist/esm/server/requests.mjs.map +1 -1
  139. package/dist/esm/server/routes.min.mjs +1 -1
  140. package/dist/esm/server/routes.min.mjs.map +1 -1
  141. package/dist/esm/server/routes.mjs +1 -2
  142. package/dist/esm/server/routes.mjs.map +1 -1
  143. package/dist/esm/server/sockets.min.mjs +1 -1
  144. package/dist/esm/server/sockets.min.mjs.map +1 -1
  145. package/dist/esm/server/sockets.mjs +2 -4
  146. package/dist/esm/server/sockets.mjs.map +1 -1
  147. package/dist/esm/server/types.min.mjs +1 -1
  148. package/dist/esm/server/types.min.mjs.map +1 -1
  149. package/dist/esm/server/types.mjs +1 -1
  150. package/dist/esm/server/types.mjs.map +1 -1
  151. package/dist/types/cache/index.d.ts +7 -1
  152. package/dist/types/dbs/mongo/changes.js +5 -1
  153. package/dist/types/errors/index.d.ts +7 -12
  154. package/dist/types/errors/index.js +1 -2
  155. package/dist/types/errors/types/tokenExpired.js +11 -0
  156. package/dist/types/events/types/kafka.js +13 -16
  157. package/dist/types/{fastify-CDJ2WuLy.d.ts → fastify-B6FUtYe9.d.ts} +5 -4
  158. package/dist/types/index.d.ts +4 -4
  159. package/dist/types/instance/index.d.ts +63 -16
  160. package/dist/types/{requestError-DqkM5BfW.d.ts → requestError-7N-ngghg.d.ts} +97 -80
  161. package/dist/types/server/impls/base.js +9 -9
  162. package/dist/types/server/impls/express.js +2 -13
  163. package/dist/types/server/impls/fastify.js +2 -13
  164. package/dist/types/server/index.d.ts +62 -20
  165. package/dist/types/server/index.js +1 -1
  166. package/dist/types/server/middlewares/requireAuthUser.js +9 -52
  167. package/dist/types/server/pipes.js +23 -8
  168. package/dist/types/server/requests-auth-methods/apiKeys.js +20 -0
  169. package/dist/types/server/requests-auth-methods/base.js +19 -0
  170. package/dist/types/server/requests-auth-methods/index.js +3 -0
  171. package/dist/types/server/requests-auth-methods/jwt.js +77 -0
  172. package/dist/types/server/requests.js +1 -9
  173. package/dist/types/server/routes.js +1 -2
  174. package/dist/types/server/sockets.js +2 -4
  175. package/dist/types/server/types.js +1 -1
  176. package/dist/types/{validationError-BMKfV51p.d.ts → validationError-BB4cfdZa.d.ts} +1 -1
  177. package/dist/types/validations/index.d.ts +3 -9
  178. package/package.json +13 -12
  179. package/dist/cjs/errors/types/authorizationExpired.cjs +0 -12
  180. package/dist/cjs/errors/types/authorizationExpired.cjs.map +0 -1
  181. package/dist/cjs/errors/types/authorizationExpired.min.cjs +0 -2
  182. package/dist/cjs/errors/types/authorizationExpired.min.cjs.map +0 -1
  183. package/dist/cjs/errors/types/refreshTokenMisusedError.cjs +0 -12
  184. package/dist/cjs/errors/types/refreshTokenMisusedError.cjs.map +0 -1
  185. package/dist/cjs/errors/types/refreshTokenMisusedError.min.cjs.map +0 -1
  186. package/dist/cjs/server/middlewares/parseAuthUser.cjs +0 -21
  187. package/dist/cjs/server/middlewares/parseAuthUser.cjs.map +0 -1
  188. package/dist/cjs/server/middlewares/parseAuthUser.min.cjs +0 -2
  189. package/dist/cjs/server/middlewares/parseAuthUser.min.cjs.map +0 -1
  190. package/dist/cjs/server/requests-auth/apiKeys.cjs +0 -6
  191. package/dist/cjs/server/requests-auth/apiKeys.cjs.map +0 -1
  192. package/dist/cjs/server/requests-auth/apiKeys.min.cjs +0 -2
  193. package/dist/cjs/server/requests-auth/apiKeys.min.cjs.map +0 -1
  194. package/dist/cjs/server/requests-auth/index.cjs.map +0 -1
  195. package/dist/cjs/server/requests-auth/index.min.cjs.map +0 -1
  196. package/dist/cjs/server/requests-auth/tokens.cjs +0 -92
  197. package/dist/cjs/server/requests-auth/tokens.cjs.map +0 -1
  198. package/dist/cjs/server/requests-auth/tokens.min.cjs +0 -2
  199. package/dist/cjs/server/requests-auth/tokens.min.cjs.map +0 -1
  200. package/dist/esm/errors/types/authorizationExpired.min.mjs +0 -2
  201. package/dist/esm/errors/types/authorizationExpired.min.mjs.map +0 -1
  202. package/dist/esm/errors/types/authorizationExpired.mjs +0 -12
  203. package/dist/esm/errors/types/authorizationExpired.mjs.map +0 -1
  204. package/dist/esm/errors/types/refreshTokenMisusedError.min.mjs +0 -2
  205. package/dist/esm/errors/types/refreshTokenMisusedError.min.mjs.map +0 -1
  206. package/dist/esm/errors/types/refreshTokenMisusedError.mjs +0 -12
  207. package/dist/esm/errors/types/refreshTokenMisusedError.mjs.map +0 -1
  208. package/dist/esm/server/middlewares/parseAuthUser.min.mjs +0 -2
  209. package/dist/esm/server/middlewares/parseAuthUser.min.mjs.map +0 -1
  210. package/dist/esm/server/middlewares/parseAuthUser.mjs +0 -21
  211. package/dist/esm/server/middlewares/parseAuthUser.mjs.map +0 -1
  212. package/dist/esm/server/requests-auth/apiKeys.min.mjs +0 -2
  213. package/dist/esm/server/requests-auth/apiKeys.min.mjs.map +0 -1
  214. package/dist/esm/server/requests-auth/apiKeys.mjs +0 -6
  215. package/dist/esm/server/requests-auth/apiKeys.mjs.map +0 -1
  216. package/dist/esm/server/requests-auth/index.min.mjs +0 -2
  217. package/dist/esm/server/requests-auth/index.min.mjs.map +0 -1
  218. package/dist/esm/server/requests-auth/index.mjs +0 -3
  219. package/dist/esm/server/requests-auth/index.mjs.map +0 -1
  220. package/dist/esm/server/requests-auth/tokens.min.mjs +0 -2
  221. package/dist/esm/server/requests-auth/tokens.min.mjs.map +0 -1
  222. package/dist/esm/server/requests-auth/tokens.mjs +0 -92
  223. package/dist/esm/server/requests-auth/tokens.mjs.map +0 -1
  224. package/dist/types/base-8yVXb67P.d.ts +0 -8
  225. package/dist/types/errors/types/authorizationExpired.js +0 -11
  226. package/dist/types/errors/types/refreshTokenMisusedError.js +0 -11
  227. package/dist/types/server/middlewares/parseAuthUser.js +0 -20
  228. package/dist/types/server/requests-auth/apiKeys.js +0 -5
  229. package/dist/types/server/requests-auth/index.js +0 -2
  230. package/dist/types/server/requests-auth/tokens.js +0 -91
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/instance/index.ts"],"sourcesContent":["import pino, { type Logger } from 'pino'\nimport { ulid } from 'ulid'\nimport { type ConditionalObjectKeys, type Pipe, type PipeInput, v } from 'valleyed'\n\nimport { EquippedError } from '../errors'\nimport { type HookCb, type HookEvent, type HookRecord, runHooks } from './hooks'\nimport {\n\tcachePipe,\n\ttype CacheTypes,\n\tdbPipe,\n\ttype DbTypes,\n\teventBusPipe,\n\ttype EventBusTypes,\n\tinstanceSettingsPipe,\n\tjobsPipe,\n\ttype JobTypes,\n\tserverTypePipe,\n\ttype ServerTypes,\n\ttype Settings,\n\ttype SettingsInput,\n} from './settings'\n\nexport class Instance {\n\tstatic #id: string | undefined\n\tstatic #instance: Instance\n\tstatic #hooks: Partial<Record<HookEvent, HookRecord[]>> = {}\n\treadonly settings: Readonly<Settings>\n\treadonly log: Logger<never>\n\n\tprivate constructor(settings: Settings) {\n\t\tInstance.#instance = this\n\t\tthis.settings = Object.freeze(settings)\n\t\tthis.log = pino<never>({\n\t\t\tlevel: this.settings.log.level,\n\t\t\tserializers: {\n\t\t\t\terr: pino.stdSerializers.err,\n\t\t\t\terror: pino.stdSerializers.err,\n\t\t\t\treq: pino.stdSerializers.req,\n\t\t\t\tres: pino.stdSerializers.res,\n\t\t\t},\n\t\t\tmixin: () => ({\n\t\t\t\tinstanceId: Instance.#id,\n\t\t\t}),\n\t\t})\n\t\tInstance.#registerOnExitHandler()\n\t}\n\n\talias(id: string) {\n\t\tif (Instance.#id !== undefined) return Instance.crash(new EquippedError('Instance already has an alias', {}))\n\t\tInstance.#id = id\n\t}\n\n\tget id() {\n\t\tif (Instance.#id === undefined) return Instance.crash(new EquippedError('Instance doesnt have an alias yet', {}))\n\t\treturn Instance.#id\n\t}\n\n\tgetScopedName(name: string, key = '.') {\n\t\treturn [this.settings.app.name, name].join(key)\n\t}\n\n\tcreateCache<T extends PipeInput<ReturnType<typeof cachePipe>>>(input: ConditionalObjectKeys<T>) {\n\t\treturn v.assert(cachePipe(), input) as CacheTypes[T['type']]\n\t}\n\n\tcreateJobs<T extends PipeInput<ReturnType<typeof jobsPipe>>>(input: ConditionalObjectKeys<T>) {\n\t\treturn v.assert(jobsPipe(), input) as JobTypes[T['type']]\n\t}\n\n\tcreateEventBus<T extends PipeInput<ReturnType<typeof eventBusPipe>>>(input: ConditionalObjectKeys<T>) {\n\t\treturn v.assert(eventBusPipe(), input) as EventBusTypes[T['type']]\n\t}\n\n\tcreateDb<T extends PipeInput<ReturnType<typeof dbPipe>>>(input: ConditionalObjectKeys<T>) {\n\t\treturn v.assert(dbPipe(), input) as DbTypes[T['db']['type']]\n\t}\n\n\tcreateServer<T extends PipeInput<ReturnType<typeof serverTypePipe>>>(input: ConditionalObjectKeys<T>) {\n\t\treturn v.assert(serverTypePipe(), input) as ServerTypes[T['type']]\n\t}\n\n\tasync start() {\n\t\ttry {\n\t\t\tawait runHooks(Instance.#hooks['setup'] ?? [])\n\t\t\tawait runHooks(Instance.#hooks['start'] ?? [])\n\t\t} catch (error) {\n\t\t\tInstance.crash(new EquippedError(`Error starting instance`, {}, error))\n\t\t}\n\t}\n\n\tstatic envs<E extends object>(envsPipe: Pipe<unknown, E>): E {\n\t\tconst envValidity = v.validate(envsPipe, process.env)\n\t\tif (!envValidity.valid) {\n\t\t\tInstance.crash(\n\t\t\t\tnew EquippedError(`Environment variables are not valid\\n${envValidity.error.toString()}`, {\n\t\t\t\t\tmessages: envValidity.error.messages,\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\t\treturn envValidity.value\n\t}\n\n\tstatic create(settings: SettingsInput) {\n\t\tif (Instance.#instance) return Instance.crash(new EquippedError('Instance has been initialized already', {}))\n\t\tconst settingsValidity = v.validate(instanceSettingsPipe(), settings)\n\t\tif (!settingsValidity.valid) {\n\t\t\tInstance.crash(\n\t\t\t\tnew EquippedError(`Settings are not valid\\n${settingsValidity.error.toString()}`, {\n\t\t\t\t\tmessages: settingsValidity.error.messages,\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\t\treturn new Instance(settingsValidity.value)\n\t}\n\n\tstatic get() {\n\t\tif (!Instance.#instance)\n\t\t\treturn Instance.crash(\n\t\t\t\tnew EquippedError('Has not been initialized. Make sure an instance has been created before you get an instance', {}),\n\t\t\t)\n\t\treturn Instance.#instance\n\t}\n\n\tstatic on(event: HookEvent, cb: HookCb, order: number) {\n\t\tInstance.#hooks[event] ??= []\n\t\tInstance.#hooks[event].push({ cb, order })\n\t}\n\n\tstatic #registerOnExitHandler() {\n\t\tconst signals = {\n\t\t\tSIGHUP: 1,\n\t\t\tSIGINT: 2,\n\t\t\tSIGTERM: 15,\n\t\t}\n\n\t\tObject.entries(signals).forEach(([signal, code]) => {\n\t\t\tprocess.on(signal, async () => {\n\t\t\t\tawait runHooks(Instance.#hooks['close'] ?? [], () => {})\n\t\t\t\tprocess.exit(128 + code)\n\t\t\t})\n\t\t})\n\t}\n\n\tstatic resolveBeforeCrash<T>(cb: () => Promise<T>) {\n\t\tconst value = cb()\n\t\tInstance.on('close', async () => await value, 10)\n\t\treturn value\n\t}\n\n\tstatic crash(error: EquippedError): never {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.error(error)\n\t\tprocess.exit(1)\n\t}\n\n\tstatic createId(opts?: { prefix?: string; time?: Date }) {\n\t\treturn `${opts?.prefix ?? ''}${ulid(opts?.time?.getTime())}`\n\t}\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/instance/index.ts"],"sourcesContent":["import pino, { type Logger } from 'pino'\nimport { ulid } from 'ulid'\nimport { type ConditionalObjectKeys, type Pipe, type PipeInput, v } from 'valleyed'\n\nimport { EquippedError } from '../errors'\nimport { type HookCb, type HookEvent, type HookRecord, runHooks } from './hooks'\nimport {\n\tcachePipe,\n\ttype CacheTypes,\n\tdbPipe,\n\ttype DbTypes,\n\teventBusPipe,\n\ttype EventBusTypes,\n\tinstanceSettingsPipe,\n\tjobsPipe,\n\ttype JobTypes,\n\tserverTypePipe,\n\ttype ServerTypes,\n\ttype Settings,\n\ttype SettingsInput,\n} from './settings'\n\nexport class Instance {\n\tstatic #id: string | undefined\n\tstatic #instance: Instance\n\tstatic #hooks: Partial<Record<HookEvent, HookRecord[]>> = {}\n\treadonly settings: Readonly<Settings>\n\treadonly log: Logger<never>\n\n\tprivate constructor(settings: Settings) {\n\t\tInstance.#instance = this\n\t\tthis.settings = Object.freeze(settings)\n\t\tthis.log = pino<never>({\n\t\t\tlevel: this.settings.log.level,\n\t\t\tserializers: {\n\t\t\t\terr: pino.stdSerializers.err,\n\t\t\t\terror: pino.stdSerializers.err,\n\t\t\t\treq: pino.stdSerializers.req,\n\t\t\t\tres: pino.stdSerializers.res,\n\t\t\t},\n\t\t\tmixin: () => ({\n\t\t\t\tinstanceId: Instance.#id,\n\t\t\t}),\n\t\t})\n\t\tInstance.#registerOnExitHandler()\n\t}\n\n\talias(id: string) {\n\t\tif (Instance.#id !== undefined) return Instance.crash(new EquippedError('Instance already has an alias', {}))\n\t\tInstance.#id = id\n\t}\n\n\tget id() {\n\t\tif (Instance.#id === undefined) return Instance.crash(new EquippedError('Instance doesnt have an alias yet', {}))\n\t\treturn Instance.#id\n\t}\n\n\tgetScopedName(name: string, key = '.') {\n\t\treturn [this.settings.app.name, name].join(key)\n\t}\n\n\tcreateCache<T extends keyof CacheTypes>(input: ConditionalObjectKeys<Extract<PipeInput<ReturnType<typeof cachePipe>>, { type: T }>>) {\n\t\treturn v.assert(cachePipe(), input) as CacheTypes[T]\n\t}\n\n\tcreateJobs<T extends keyof JobTypes>(input: ConditionalObjectKeys<Extract<PipeInput<ReturnType<typeof jobsPipe>>, { type: T }>>) {\n\t\treturn v.assert(jobsPipe(), input) as JobTypes[T]\n\t}\n\n\tcreateEventBus<T extends keyof EventBusTypes>(input: ConditionalObjectKeys<Extract<PipeInput<ReturnType<typeof eventBusPipe>>, { type: T }>>) {\n\t\treturn v.assert(eventBusPipe(), input) as EventBusTypes[T]\n\t}\n\n\tcreateDb<T extends keyof DbTypes>(input: ConditionalObjectKeys<Extract<PipeInput<ReturnType<typeof dbPipe>>, { db: { type: T } }>>) {\n\t\treturn v.assert(dbPipe(), input) as DbTypes[T]\n\t}\n\n\tcreateServer<T extends keyof ServerTypes>(input: ConditionalObjectKeys<Extract<PipeInput<ReturnType<typeof serverTypePipe>>, { type: T }>>) {\n\t\treturn v.assert(serverTypePipe(), input) as ServerTypes[T]\n\t}\n\n\tasync start() {\n\t\ttry {\n\t\t\tawait runHooks(Instance.#hooks['setup'] ?? [])\n\t\t\tawait runHooks(Instance.#hooks['start'] ?? [])\n\t\t} catch (error) {\n\t\t\tInstance.crash(new EquippedError(`Error starting instance`, {}, error))\n\t\t}\n\t}\n\n\tstatic envs<E extends object>(envsPipe: Pipe<unknown, E>): E {\n\t\tconst envValidity = v.validate(envsPipe, process.env)\n\t\tif (!envValidity.valid) {\n\t\t\tInstance.crash(\n\t\t\t\tnew EquippedError(`Environment variables are not valid\\n${envValidity.error.toString()}`, {\n\t\t\t\t\tmessages: envValidity.error.messages,\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\t\treturn envValidity.value\n\t}\n\n\tstatic create(settings: SettingsInput) {\n\t\tif (Instance.#instance) return Instance.crash(new EquippedError('Instance has been initialized already', {}))\n\t\tconst settingsValidity = v.validate(instanceSettingsPipe(), settings)\n\t\tif (!settingsValidity.valid) {\n\t\t\tInstance.crash(\n\t\t\t\tnew EquippedError(`Settings are not valid\\n${settingsValidity.error.toString()}`, {\n\t\t\t\t\tmessages: settingsValidity.error.messages,\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\t\treturn new Instance(settingsValidity.value)\n\t}\n\n\tstatic get() {\n\t\tif (!Instance.#instance)\n\t\t\treturn Instance.crash(\n\t\t\t\tnew EquippedError('Has not been initialized. Make sure an instance has been created before you get an instance', {}),\n\t\t\t)\n\t\treturn Instance.#instance\n\t}\n\n\tstatic on(event: HookEvent, cb: HookCb, order: number) {\n\t\tInstance.#hooks[event] ??= []\n\t\tInstance.#hooks[event].push({ cb, order })\n\t}\n\n\tstatic #registerOnExitHandler() {\n\t\tconst signals = {\n\t\t\tSIGHUP: 1,\n\t\t\tSIGINT: 2,\n\t\t\tSIGTERM: 15,\n\t\t}\n\n\t\tObject.entries(signals).forEach(([signal, code]) => {\n\t\t\tprocess.on(signal, async () => {\n\t\t\t\tawait runHooks(Instance.#hooks['close'] ?? [], () => {})\n\t\t\t\tprocess.exit(128 + code)\n\t\t\t})\n\t\t})\n\t}\n\n\tstatic resolveBeforeCrash<T>(cb: () => Promise<T>) {\n\t\tconst value = cb()\n\t\tInstance.on('close', async () => await value, 10)\n\t\treturn value\n\t}\n\n\tstatic crash(error: EquippedError): never {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.error(error)\n\t\tprocess.exit(1)\n\t}\n\n\tstatic createId(opts?: { prefix?: string; time?: Date }) {\n\t\treturn `${opts?.prefix ?? ''}${ulid(opts?.time?.getTime())}`\n\t}\n}\n"],"mappings":"AAAA,OAAO,cAA2B;AAClC,SAAS,YAAY;AACrB,SAAgE,SAAS;AAEzE,SAAS,qBAAqB;AAC9B,SAAuD,gBAAgB;AACvE;AAAA,EACC;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EACA;AAAA,EAEA;AAAA,OAIM;AAEA,MAAM,SAAS;AAAA,EACrB,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO,SAAmD,CAAC;AAAA,EAClD;AAAA,EACA;AAAA,EAED,YAAY,UAAoB;AACvC,aAAS,YAAY;AACrB,SAAK,WAAW,OAAO,OAAO,QAAQ;AACtC,SAAK,MAAM,KAAY;AAAA,MACtB,OAAO,KAAK,SAAS,IAAI;AAAA,MACzB,aAAa;AAAA,QACZ,KAAK,KAAK,eAAe;AAAA,QACzB,OAAO,KAAK,eAAe;AAAA,QAC3B,KAAK,KAAK,eAAe;AAAA,QACzB,KAAK,KAAK,eAAe;AAAA,MAC1B;AAAA,MACA,OAAO,OAAO;AAAA,QACb,YAAY,SAAS;AAAA,MACtB;AAAA,IACD,CAAC;AACD,aAAS,uBAAuB;AAAA,EACjC;AAAA,EAEA,MAAM,IAAY;AACjB,QAAI,SAAS,QAAQ,OAAW,QAAO,SAAS,MAAM,IAAI,cAAc,iCAAiC,CAAC,CAAC,CAAC;AAC5G,aAAS,MAAM;AAAA,EAChB;AAAA,EAEA,IAAI,KAAK;AACR,QAAI,SAAS,QAAQ,OAAW,QAAO,SAAS,MAAM,IAAI,cAAc,qCAAqC,CAAC,CAAC,CAAC;AAChH,WAAO,SAAS;AAAA,EACjB;AAAA,EAEA,cAAc,MAAc,MAAM,KAAK;AACtC,WAAO,CAAC,KAAK,SAAS,IAAI,MAAM,IAAI,EAAE,KAAK,GAAG;AAAA,EAC/C;AAAA,EAEA,YAAwC,OAA6F;AACpI,WAAO,EAAE,OAAO,UAAU,GAAG,KAAK;AAAA,EACnC;AAAA,EAEA,WAAqC,OAA4F;AAChI,WAAO,EAAE,OAAO,SAAS,GAAG,KAAK;AAAA,EAClC;AAAA,EAEA,eAA8C,OAAgG;AAC7I,WAAO,EAAE,OAAO,aAAa,GAAG,KAAK;AAAA,EACtC;AAAA,EAEA,SAAkC,OAAkG;AACnI,WAAO,EAAE,OAAO,OAAO,GAAG,KAAK;AAAA,EAChC;AAAA,EAEA,aAA0C,OAAkG;AAC3I,WAAO,EAAE,OAAO,eAAe,GAAG,KAAK;AAAA,EACxC;AAAA,EAEA,MAAM,QAAQ;AACb,QAAI;AACH,YAAM,SAAS,SAAS,OAAO,OAAO,KAAK,CAAC,CAAC;AAC7C,YAAM,SAAS,SAAS,OAAO,OAAO,KAAK,CAAC,CAAC;AAAA,IAC9C,SAAS,OAAO;AACf,eAAS,MAAM,IAAI,cAAc,2BAA2B,CAAC,GAAG,KAAK,CAAC;AAAA,IACvE;AAAA,EACD;AAAA,EAEA,OAAO,KAAuB,UAA+B;AAC5D,UAAM,cAAc,EAAE,SAAS,UAAU,QAAQ,GAAG;AACpD,QAAI,CAAC,YAAY,OAAO;AACvB,eAAS;AAAA,QACR,IAAI,cAAc;AAAA,EAAwC,YAAY,MAAM,SAAS,CAAC,IAAI;AAAA,UACzF,UAAU,YAAY,MAAM;AAAA,QAC7B,CAAC;AAAA,MACF;AAAA,IACD;AACA,WAAO,YAAY;AAAA,EACpB;AAAA,EAEA,OAAO,OAAO,UAAyB;AACtC,QAAI,SAAS,UAAW,QAAO,SAAS,MAAM,IAAI,cAAc,yCAAyC,CAAC,CAAC,CAAC;AAC5G,UAAM,mBAAmB,EAAE,SAAS,qBAAqB,GAAG,QAAQ;AACpE,QAAI,CAAC,iBAAiB,OAAO;AAC5B,eAAS;AAAA,QACR,IAAI,cAAc;AAAA,EAA2B,iBAAiB,MAAM,SAAS,CAAC,IAAI;AAAA,UACjF,UAAU,iBAAiB,MAAM;AAAA,QAClC,CAAC;AAAA,MACF;AAAA,IACD;AACA,WAAO,IAAI,SAAS,iBAAiB,KAAK;AAAA,EAC3C;AAAA,EAEA,OAAO,MAAM;AACZ,QAAI,CAAC,SAAS;AACb,aAAO,SAAS;AAAA,QACf,IAAI,cAAc,+FAA+F,CAAC,CAAC;AAAA,MACpH;AACD,WAAO,SAAS;AAAA,EACjB;AAAA,EAEA,OAAO,GAAG,OAAkB,IAAY,OAAe;AACtD,aAAS,OAAO,KAAK,MAAM,CAAC;AAC5B,aAAS,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,MAAM,CAAC;AAAA,EAC1C;AAAA,EAEA,OAAO,yBAAyB;AAC/B,UAAM,UAAU;AAAA,MACf,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,SAAS;AAAA,IACV;AAEA,WAAO,QAAQ,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,IAAI,MAAM;AACnD,cAAQ,GAAG,QAAQ,YAAY;AAC9B,cAAM,SAAS,SAAS,OAAO,OAAO,KAAK,CAAC,GAAG,MAAM;AAAA,QAAC,CAAC;AACvD,gBAAQ,KAAK,MAAM,IAAI;AAAA,MACxB,CAAC;AAAA,IACF,CAAC;AAAA,EACF;AAAA,EAEA,OAAO,mBAAsB,IAAsB;AAClD,UAAM,QAAQ,GAAG;AACjB,aAAS,GAAG,SAAS,YAAY,MAAM,OAAO,EAAE;AAChD,WAAO;AAAA,EACR;AAAA,EAEA,OAAO,MAAM,OAA6B;AAEzC,YAAQ,MAAM,KAAK;AACnB,YAAQ,KAAK,CAAC;AAAA,EACf;AAAA,EAEA,OAAO,SAAS,MAAyC;AACxD,WAAO,GAAG,MAAM,UAAU,EAAE,GAAG,KAAK,MAAM,MAAM,QAAQ,CAAC,CAAC;AAAA,EAC3D;AACD;","names":[]}
@@ -1,2 +1,2 @@
1
- import{Server as C}from"socket.io";import $ from"supertest";import{PipeError as j,v as a}from"valleyed";import{EquippedError as D,NotFoundError as O,RequestError as T}from "../../errors/index.min.mjs";import{Instance as b}from "../../instance/index.min.mjs";import{pipeErrorToValidationError as S}from "../../validations/index.min.mjs";import{requestLocalStorage as x,responseLocalStorage as H}from "../../validations/valleyed.min.mjs";import{parseAuthUser as A}from "../middlewares/parseAuthUser.min.mjs";import{OpenApi as M}from "../openapi.min.mjs";import{Response as h}from "../requests.min.mjs";import"../routes";import{SocketEmitter as V}from "../sockets.min.mjs";import{Methods as l,StatusCodes as k}from "../types.min.mjs";const U=Object.entries(k).filter(([,f])=>f>399).map(([f,s])=>({status:s,contentType:"application/json",pipe:a.meta(a.array(a.object({message:a.string(),field:a.optional(a.string())})),{$refId:`Errors.${f}Response`,description:`${f} Response`})}));class Z{constructor(s,t,i){this.config=t;this.implementations=i;this.server=s,this.#e=new M(t);const c=new C(s,{cors:this.cors});this.socket=new V(c,t),this.addRouter(this.#e.router())}#t=[];#s=new Map;#e;socket;server;cors={origin:"*",methods:Object.values(l).filter(s=>s!==l.options).map(s=>s.toUpperCase())};addRouter(...s){s.map(t=>t.routes).forEach(t=>this.addRoute(...t))}addRoute(...s){s.forEach(t=>{this.#t.push(async()=>{const{method:i,path:c,schema:o={},onError:d,middlewares:u=[]}=t,p=`(${i.toUpperCase()}) ${this.#e.cleanPath(c)}`;if(this.#s.get(p))throw new D(`Route key ${p} already registered. All route keys must be unique`,{route:t,key:p});u.unshift(A),u.forEach(m=>m.onSetup?.(t)),d?.onSetup?.(t);const{validateRequest:R,validateResponse:w,jsonSchema:v}=this.#o(i,o);this.#s.set(p,!0),await this.#e.register(t,v),this.implementations.registerRoute(i,this.#e.cleanPath(c),async(m,q)=>{const g=await R(await this.implementations.parseRequest(m));try{for(const n of u)await n.cb(g,this.config);const e=await t.handler(g,this.config),r=e instanceof h?e:new h({body:e,status:k.Ok,headers:{},piped:!1});return await this.implementations.handleResponse(q,await w(r))}catch(e){if(d?.cb){const r=await d.cb(g,this.config,e),n=r instanceof h?r:new h({body:r,status:k.BadRequest,headers:{}});return await this.implementations.handleResponse(q,await w(n))}throw e}})})})}#o(s,t){const i=t?.defaultStatusCode??k.Ok,c=t?.defaultContentType??"application/json";let o=i,d=c;const u={response:{},request:{}},p={},R={};[{key:"params",type:"request"},{key:"headers",type:"request"},{key:"cookies",type:"request"},{key:"query",type:"request"},{key:"body",type:"request",skip:![l.post,l.put,l.patch].includes(s)},{key:"response",type:"response"},{key:"responseHeaders",type:"response"},{key:"responseCookies",type:"response"}].forEach(e=>{const r=t[e.key]??a.any();if(!e.skip&&(e.type==="request"&&(p[e.key]=r,u.request[e.key]=a.schema(r)),e.type==="response")){const n=U.concat({status:i,contentType:d,pipe:r});R[e.key]=a.any().pipe(y=>{const E=n.find(P=>P.status===o)?.pipe;if(!E)throw j.root(`schema not defined for status code: ${o}`,y);return a.assert(E,y)}),u.response[e.key]=n.map(y=>({status:y.status,contentType:y.contentType,schema:a.schema(y.pipe)}))}});const v=a.object(p);a.compile(v,{allErrors:!0});const m=a.object(R);return a.compile(m,{allErrors:!0}),{jsonSchema:u,validateRequest:async e=>{if(!Object.keys(p))return e;const r=t.context?await t.context(e):{};e.context=r;const n=x.run(e,()=>a.validate(v,{params:e.params,headers:e.headers,query:e.query,body:e.body,cookies:e.cookies}));if(!n.valid)throw S(n.error);return e.params=n.value.params,e.headers=n.value.headers,e.query=n.value.query,e.body=n.value.body,e.cookies=n.value.cookies,e},validateResponse:async e=>{if(!Object.keys(R))return e;o=e.status,d=e.contentType;const r=H.run(e,()=>a.validate(m,{responseHeaders:e.headers,responseCookies:e.cookies,response:e.body}));if(!r.valid)throw S(r.error);return e.body=r.value.response,e.headers=r.value.responseHeaders,e.cookieValues=r.value.responseCookies,e}}}test(){return $(this.server)}async start(){const s=this.config.port,t=b.get(),{app:i}=t.settings;this.config.healthPath&&this.addRoute({method:l.get,path:this.config.healthPath,handler:async o=>o.res({body:`${t.id}(${i.name}) service running`,contentType:"text/plain"})}),this.implementations.registerNotFoundHandler(async o=>{const d=await this.implementations.parseRequest(o);throw new O(`Route ${d.path} not found`)}),this.implementations.registerErrorHandler(async(o,d,u)=>{b.get().log.error({error:o},"Uncaught error in route handler");const p=o instanceof T?new h({body:o.serializedErrors,status:o.statusCode}):new h({body:[{message:"Something went wrong",data:o.message}],status:k.BadRequest});return await this.implementations.handleResponse(u,p)}),await Promise.all(this.#t.map(o=>o()));const c=await this.implementations.start(s);return c&&b.get().log.info(`${t.id}(${i.name}) service listening on port ${s}`),c}}export{Z as Server};
1
+ import"cors";import{Server as C}from"socket.io";import j from"supertest";import{PipeError as O,v as a}from"valleyed";import{EquippedError as $,NotFoundError as D,RequestError as T}from "../../errors/index.min.mjs";import{Instance as b}from "../../instance/index.min.mjs";import{pipeErrorToValidationError as S}from "../../validations/index.min.mjs";import{requestLocalStorage as H,responseLocalStorage as A}from "../../validations/valleyed.min.mjs";import{OpenApi as M}from "../openapi.min.mjs";import{Response as y}from "../requests.min.mjs";import"../routes";import{SocketEmitter as V}from "../sockets.min.mjs";import{Methods as l,StatusCodes as k}from "../types.min.mjs";const x=Object.entries(k).filter(([,f])=>f>399).map(([f,o])=>({status:o,contentType:"application/json",pipe:a.meta(a.array(a.object({message:a.string(),field:a.optional(a.string())})),{$refId:`Errors.${f}Response`,description:`${f} Response`})}));class Y{constructor(o,s,n){this.config=s;this.implementations=n;this.server=o,this.#e=new M(s);const p=new C(o,{cors:this.cors});this.socket=new V(p,s),this.addRouter(this.#e.router())}#t=[];#s=new Map;#e;socket;server;get cors(){return{origin:this.config.cors?.origin,methods:(this.config.cors?.methods??Object.values(l)).filter(o=>o!==l.options).map(o=>o.toUpperCase()),credentials:this.config.cors?.credentials}}addRouter(...o){o.map(s=>s.routes).forEach(s=>this.addRoute(...s))}addRoute(...o){o.forEach(s=>{this.#t.push(async()=>{const{method:n,path:p,schema:r={},onError:c,middlewares:d=[]}=s,i=`(${n.toUpperCase()}) ${this.#e.cleanPath(p)}`;if(this.#s.get(i))throw new $(`Route key ${i} already registered. All route keys must be unique`,{route:s,key:i});d.forEach(h=>h.onSetup?.(s)),c?.onSetup?.(s);const{validateRequest:R,validateResponse:q,jsonSchema:v}=this.#o(n,r);this.#s.set(i,!0),await this.#e.register(s,v),this.implementations.registerRoute(n,this.#e.cleanPath(p),async(h,w)=>{const g=await R(await this.implementations.parseRequest(h));try{for(const u of d)await u.cb(g,this.config);const e=await s.handler(g,this.config),t=e instanceof y?e:new y({body:e,status:k.Ok,headers:{},piped:!1});return await this.implementations.handleResponse(w,await q(t))}catch(e){if(c?.cb){const t=await c.cb(g,this.config,e),u=t instanceof y?t:new y({body:t,status:k.BadRequest,headers:{}});return await this.implementations.handleResponse(w,await q(u))}throw e}})})})}#o(o,s){const n=s?.defaultStatusCode??k.Ok,p=s?.defaultContentType??"application/json";let r=n,c=p;const d={response:{},request:{}},i={},R={};[{key:"params",type:"request"},{key:"headers",type:"request"},{key:"cookies",type:"request"},{key:"query",type:"request"},{key:"body",type:"request",skip:![l.post,l.put,l.patch].includes(o)},{key:"response",type:"response"},{key:"responseHeaders",type:"response"},{key:"responseCookies",type:"response"}].forEach(e=>{const t=s[e.key]??a.any();if(!e.skip&&(e.type==="request"&&(i[e.key]=t,d.request[e.key]=a.schema(t)),e.type==="response")){const u=x.concat({status:n,contentType:c,pipe:t});R[e.key]=a.any().pipe(m=>{const E=u.find(P=>P.status===r)?.pipe;if(!E)throw O.root(`schema not defined for status code: ${r}`,m);return a.assert(E,m)}),d.response[e.key]=u.map(m=>({status:m.status,contentType:m.contentType,schema:a.schema(m.pipe)}))}});const v=a.object(i);a.compile(v,{allErrors:!0});const h=a.object(R);return a.compile(h,{allErrors:!0}),{jsonSchema:d,validateRequest:async e=>{if(!Object.keys(i))return e;const t=H.run(e,()=>a.validate(v,{params:e.params,headers:e.headers,query:e.query,body:e.body,cookies:e.cookies}));if(!t.valid)throw S(t.error);return e.params=t.value.params,e.headers=t.value.headers,e.query=t.value.query,e.body=t.value.body,e.cookies=t.value.cookies,e},validateResponse:async e=>{if(!Object.keys(R))return e;r=e.status,c=e.contentType;const t=A.run(e,()=>a.validate(h,{responseHeaders:e.headers,responseCookies:Object.fromEntries(Object.entries(e.cookies).map(([u,m])=>[u,m.value])),response:e.body}));if(!t.valid)throw S(t.error);return e.body=t.value.response,e.headers=t.value.responseHeaders,e.cookieValues=t.value.responseCookies,e}}}test(){return j(this.server)}async start(){const o=this.config.port,s=b.get(),{app:n}=s.settings;this.config.healthPath&&this.addRoute({method:l.get,path:this.config.healthPath,handler:async r=>r.res({body:`${s.id}(${n.name}) service running`,contentType:"text/plain"})}),this.implementations.registerNotFoundHandler(async r=>{const c=await this.implementations.parseRequest(r);throw new D(`Route ${c.path} not found`)}),this.implementations.registerErrorHandler(async(r,c,d)=>{b.get().log.error({error:r},"Uncaught error in route handler");const i=r instanceof T?new y({body:r.serializedErrors,status:r.statusCode}):new y({body:[{message:"Something went wrong",data:r.message}],status:k.BadRequest});return await this.implementations.handleResponse(d,i)}),await Promise.all(this.#t.map(r=>r()));const p=await this.implementations.start(o);return p&&b.get().log.info(`${s.id}(${n.name}) service listening on port ${o}`),p}}export{Y as Server};
2
2
  //# sourceMappingURL=base.min.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/server/impls/base.ts"],"sourcesContent":["import type http from 'http'\n\nimport { Server as SocketServer } from 'socket.io'\nimport supertest from 'supertest'\nimport { type Pipe, PipeError, v } from 'valleyed'\n\nimport { EquippedError, NotFoundError, RequestError } from '../../errors'\nimport { Instance } from '../../instance'\nimport { pipeErrorToValidationError } from '../../validations'\nimport { requestLocalStorage, responseLocalStorage } from '../../validations/valleyed'\nimport { parseAuthUser } from '../middlewares/parseAuthUser'\nimport { OpenApi, type OpenApiSchemaDef } from '../openapi'\nimport type { ServerConfig } from '../pipes'\nimport { type Request, Response } from '../requests'\nimport { Router } from '../routes'\nimport { SocketEmitter } from '../sockets'\nimport { Methods, type MethodsEnum, type RouteDef, StatusCodes, type Route } from '../types'\n\ntype RequestValidator = (req: Request<any>) => Promise<Request<any>>\ntype ResponseValidator = (res: Response<any>) => Promise<Response<any>>\n\nconst errorsSchemas = Object.entries(StatusCodes)\n\t.filter(([, value]) => value > 399)\n\t.map(([key, value]) => ({\n\t\tstatus: value,\n\t\tcontentType: 'application/json',\n\t\tpipe: v.meta(v.array(v.object({ message: v.string(), field: v.optional(v.string()) })), {\n\t\t\t$refId: `Errors.${key}Response`,\n\t\t\tdescription: `${key} Response`,\n\t\t}) as Pipe<any, any>,\n\t}))\n\nexport abstract class Server<Req = any, Res = any> {\n\t#queue: (() => void | Promise<void>)[] = []\n\t#routesByKey = new Map<string, boolean>()\n\t#openapi: OpenApi\n\tsocket: SocketEmitter\n\tprotected server: http.Server\n\tprotected cors = {\n\t\torigin: '*',\n\t\tmethods: Object.values(Methods)\n\t\t\t.filter((m) => m !== Methods.options)\n\t\t\t.map((m) => m.toUpperCase()),\n\t}\n\n\tconstructor(\n\t\tserver: http.Server,\n\t\tprivate config: ServerConfig,\n\t\tprivate implementations: {\n\t\t\tparseRequest: (req: Req) => Promise<Request<any>>\n\t\t\thandleResponse: (res: Res, response: Response<any>) => Promise<void>\n\t\t\tregisterRoute: (method: MethodsEnum, path: string, cb: (req: Req, res: Res) => Promise<void>) => void\n\t\t\tregisterErrorHandler: (cb: (error: Error, req: Req, res: Res) => Promise<void>) => void\n\t\t\tregisterNotFoundHandler: (cb: (req: Req, res: Res) => Promise<void>) => void\n\t\t\tstart: (port: number) => Promise<boolean>\n\t\t},\n\t) {\n\t\tthis.server = server\n\t\tthis.#openapi = new OpenApi(config)\n\t\tconst socketInstance = new SocketServer(server, { cors: this.cors })\n\t\tthis.socket = new SocketEmitter(socketInstance, config)\n\t\tthis.addRouter(this.#openapi.router())\n\t}\n\n\taddRouter(...routers: Router<any>[]) {\n\t\trouters.map((router) => router.routes).forEach((routes) => this.addRoute(...routes))\n\t}\n\n\taddRoute<T extends RouteDef>(...routes: Route<T>[]) {\n\t\troutes.forEach((route) => {\n\t\t\tthis.#queue.push(async () => {\n\t\t\t\tconst { method, path, schema = {}, onError, middlewares = [] } = route\n\n\t\t\t\tconst key = `(${method.toUpperCase()}) ${this.#openapi.cleanPath(path)}`\n\t\t\t\tif (this.#routesByKey.get(key))\n\t\t\t\t\tthrow new EquippedError(`Route key ${key} already registered. All route keys must be unique`, { route, key })\n\n\t\t\t\tmiddlewares.unshift(parseAuthUser as any)\n\t\t\t\tmiddlewares.forEach((m) => m.onSetup?.(route as any))\n\t\t\t\tonError?.onSetup?.(route as any)\n\n\t\t\t\tconst { validateRequest, validateResponse, jsonSchema } = this.#resolveSchema(method, schema)\n\n\t\t\t\tthis.#routesByKey.set(key, true)\n\t\t\t\tawait this.#openapi.register(route, jsonSchema)\n\t\t\t\tthis.implementations.registerRoute(method, this.#openapi.cleanPath(path), async (req: Req, res: Res) => {\n\t\t\t\t\tconst request = await validateRequest(await this.implementations.parseRequest(req))\n\t\t\t\t\ttry {\n\t\t\t\t\t\tfor (const middleware of middlewares) await middleware.cb(request, this.config)\n\t\t\t\t\t\tconst rawRes = await route.handler(request, this.config)\n\t\t\t\t\t\tconst response =\n\t\t\t\t\t\t\trawRes instanceof Response\n\t\t\t\t\t\t\t\t? rawRes\n\t\t\t\t\t\t\t\t: new Response({ body: rawRes, status: StatusCodes.Ok, headers: {}, piped: false })\n\t\t\t\t\t\treturn await this.implementations.handleResponse(res, await validateResponse(response))\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tif (onError?.cb) {\n\t\t\t\t\t\t\tconst rawResponse = await onError.cb(request, this.config, error as Error)\n\t\t\t\t\t\t\tconst response =\n\t\t\t\t\t\t\t\trawResponse instanceof Response\n\t\t\t\t\t\t\t\t\t? rawResponse\n\t\t\t\t\t\t\t\t\t: new Response({ body: rawResponse, status: StatusCodes.BadRequest, headers: {} })\n\t\t\t\t\t\t\treturn await this.implementations.handleResponse(res, await validateResponse(response))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthrow error\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\t}\n\n\t#resolveSchema(method: MethodsEnum, schema: RouteDef) {\n\t\tconst defaultStatusCode = schema?.defaultStatusCode ?? StatusCodes.Ok\n\t\tconst defaultContentType = schema?.defaultContentType ?? 'application/json'\n\t\tlet status = defaultStatusCode\n\t\tlet contentType = defaultContentType\n\t\tconst jsonSchema: OpenApiSchemaDef = { response: {}, request: {} }\n\t\tconst requestPipeDefs: Pick<RouteDef, 'body' | 'headers' | 'query' | 'params' | 'cookies'> = {}\n\t\tconst responsePipeDefs: Pick<RouteDef, 'response' | 'responseHeaders' | 'responseCookies'> = {}\n\n\t\tconst defs: {\n\t\t\tkey: Exclude<keyof RouteDef, `default${string}` | 'context'>\n\t\t\ttype: keyof OpenApiSchemaDef\n\t\t\tskip?: boolean\n\t\t}[] = [\n\t\t\t{ key: 'params', type: 'request' },\n\t\t\t{ key: 'headers', type: 'request' },\n\t\t\t{ key: 'cookies', type: 'request' },\n\t\t\t{ key: 'query', type: 'request' },\n\t\t\t{ key: 'body', type: 'request', skip: !(<MethodsEnum[]>[Methods.post, Methods.put, Methods.patch]).includes(method) },\n\t\t\t{ key: 'response', type: 'response' },\n\t\t\t{ key: 'responseHeaders', type: 'response' },\n\t\t\t{ key: 'responseCookies', type: 'response' },\n\t\t]\n\t\tdefs.forEach((def) => {\n\t\t\tconst pipe = schema[def.key] ?? v.any()\n\t\t\tif (def.skip) return\n\n\t\t\tif (def.type === 'request') {\n\t\t\t\trequestPipeDefs[def.key] = pipe\n\t\t\t\tjsonSchema.request[def.key as keyof typeof jsonSchema.request] = v.schema(pipe)\n\t\t\t}\n\t\t\tif (def.type === 'response') {\n\t\t\t\tconst pipeRecords = errorsSchemas.concat({ status: defaultStatusCode, contentType, pipe })\n\t\t\t\tresponsePipeDefs[def.key] = v.any().pipe((input) => {\n\t\t\t\t\tconst p = pipeRecords.find((r) => r.status === status)?.pipe\n\t\t\t\t\tif (!p) throw PipeError.root(`schema not defined for status code: ${status}`, input)\n\t\t\t\t\treturn v.assert(p, input)\n\t\t\t\t})\n\t\t\t\tjsonSchema.response[def.key as keyof typeof jsonSchema.response] = pipeRecords.map((record) => ({\n\t\t\t\t\tstatus: record.status,\n\t\t\t\t\tcontentType: record.contentType,\n\t\t\t\t\tschema: v.schema(record.pipe),\n\t\t\t\t}))\n\t\t\t}\n\t\t})\n\t\tconst requestPipe = v.object(requestPipeDefs)\n\t\tv.compile(requestPipe, { allErrors: true })\n\t\tconst responsePipe = v.object(responsePipeDefs)\n\t\tv.compile(responsePipe, { allErrors: true })\n\t\tconst validateRequest: RequestValidator = async (request) => {\n\t\t\tif (!Object.keys(requestPipeDefs)) return request\n\t\t\tconst context = schema.context ? await schema.context(request) : {}\n\t\t\trequest.context = context\n\t\t\tconst validity = requestLocalStorage.run(request, () =>\n\t\t\t\tv.validate(requestPipe, {\n\t\t\t\t\tparams: request.params,\n\t\t\t\t\theaders: request.headers,\n\t\t\t\t\tquery: request.query,\n\t\t\t\t\tbody: request.body,\n\t\t\t\t\tcookies: request.cookies,\n\t\t\t\t}),\n\t\t\t)\n\n\t\t\tif (!validity.valid) throw pipeErrorToValidationError(validity.error)\n\t\t\trequest.params = validity.value.params!\n\t\t\trequest.headers = validity.value.headers!\n\t\t\trequest.query = validity.value.query!\n\t\t\trequest.body = validity.value.body!\n\t\t\trequest.cookies = validity.value.cookies!\n\t\t\treturn request\n\t\t}\n\t\tconst validateResponse: ResponseValidator = async (response) => {\n\t\t\tif (!Object.keys(responsePipeDefs)) return response\n\t\t\tstatus = response.status\n\t\t\tcontentType = response.contentType\n\n\t\t\tconst validity = responseLocalStorage.run(response, () =>\n\t\t\t\tv.validate(responsePipe, {\n\t\t\t\t\tresponseHeaders: response.headers,\n\t\t\t\t\tresponseCookies: response.cookies,\n\t\t\t\t\tresponse: response.body,\n\t\t\t\t}),\n\t\t\t)\n\n\t\t\tif (!validity.valid) throw pipeErrorToValidationError(validity.error)\n\t\t\tresponse.body = validity.value.response!\n\t\t\tresponse.headers = validity.value.responseHeaders!\n\t\t\tresponse.cookieValues = validity.value.responseCookies!\n\t\t\treturn response\n\t\t}\n\t\treturn {\n\t\t\tjsonSchema,\n\t\t\tvalidateRequest,\n\t\t\tvalidateResponse,\n\t\t}\n\t}\n\n\ttest() {\n\t\treturn supertest(this.server)\n\t}\n\n\tasync start() {\n\t\tconst port = this.config.port\n\t\tconst instance = Instance.get()\n\t\tconst { app } = instance.settings\n\t\tif (this.config.healthPath)\n\t\t\tthis.addRoute({\n\t\t\t\tmethod: Methods.get,\n\t\t\t\tpath: this.config.healthPath,\n\t\t\t\thandler: async (req) =>\n\t\t\t\t\treq.res({\n\t\t\t\t\t\tbody: `${instance.id}(${app.name}) service running`,\n\t\t\t\t\t\tcontentType: 'text/plain',\n\t\t\t\t\t}),\n\t\t\t})\n\n\t\tthis.implementations.registerNotFoundHandler(async (req) => {\n\t\t\tconst request = await this.implementations.parseRequest(req)\n\t\t\tthrow new NotFoundError(`Route ${request.path} not found`)\n\t\t})\n\t\tthis.implementations.registerErrorHandler(async (error, _, res) => {\n\t\t\tInstance.get().log.error({ error }, 'Uncaught error in route handler')\n\t\t\tconst response =\n\t\t\t\terror instanceof RequestError\n\t\t\t\t\t? new Response({\n\t\t\t\t\t\t\tbody: error.serializedErrors,\n\t\t\t\t\t\t\tstatus: error.statusCode,\n\t\t\t\t\t\t})\n\t\t\t\t\t: new Response({\n\t\t\t\t\t\t\tbody: [{ message: 'Something went wrong', data: error.message }],\n\t\t\t\t\t\t\tstatus: StatusCodes.BadRequest,\n\t\t\t\t\t\t})\n\t\t\treturn await this.implementations.handleResponse(res, response)\n\t\t})\n\n\t\tawait Promise.all(this.#queue.map((cb) => cb()))\n\t\tconst started = await this.implementations.start(port)\n\t\tif (started) Instance.get().log.info(`${instance.id}(${app.name}) service listening on port ${port}`)\n\t\treturn started\n\t}\n}\n"],"mappings":"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","names":["SocketServer","supertest","PipeError","v","EquippedError","NotFoundError","RequestError","Instance","pipeErrorToValidationError","requestLocalStorage","responseLocalStorage","parseAuthUser","OpenApi","Response","SocketEmitter","Methods","StatusCodes","errorsSchemas","value","key","Server","server","config","implementations","#openapi","socketInstance","#queue","#routesByKey","m","routers","router","routes","route","method","path","schema","onError","middlewares","validateRequest","validateResponse","jsonSchema","#resolveSchema","req","res","request","middleware","rawRes","response","error","rawResponse","defaultStatusCode","defaultContentType","status","contentType","requestPipeDefs","responsePipeDefs","def","pipe","pipeRecords","input","p","r","record","requestPipe","responsePipe","context","validity","port","instance","app","_","cb","started"]}
1
+ {"version":3,"sources":["../../../../src/server/impls/base.ts"],"sourcesContent":["import type http from 'node:http'\n\nimport { type CorsOptions } from 'cors'\nimport { Server as SocketServer } from 'socket.io'\nimport supertest from 'supertest'\nimport { type Pipe, PipeError, v } from 'valleyed'\n\nimport { EquippedError, NotFoundError, RequestError } from '../../errors'\nimport { Instance } from '../../instance'\nimport { pipeErrorToValidationError } from '../../validations'\nimport { requestLocalStorage, responseLocalStorage } from '../../validations/valleyed'\nimport { OpenApi, type OpenApiSchemaDef } from '../openapi'\nimport type { ServerConfig } from '../pipes'\nimport { type Request, Response } from '../requests'\nimport { Router } from '../routes'\nimport { SocketEmitter } from '../sockets'\nimport { Methods, type MethodsEnum, type Route, type RouteDef, StatusCodes } from '../types'\n\ntype RequestValidator = (req: Request<any>) => Promise<Request<any>>\ntype ResponseValidator = (res: Response<any>) => Promise<Response<any>>\n\nconst errorsSchemas = Object.entries(StatusCodes)\n\t.filter(([, value]) => value > 399)\n\t.map(([key, value]) => ({\n\t\tstatus: value,\n\t\tcontentType: 'application/json',\n\t\tpipe: v.meta(v.array(v.object({ message: v.string(), field: v.optional(v.string()) })), {\n\t\t\t$refId: `Errors.${key}Response`,\n\t\t\tdescription: `${key} Response`,\n\t\t}) as Pipe<any, any>,\n\t}))\n\nexport abstract class Server<Req = any, Res = any> {\n\t#queue: (() => void | Promise<void>)[] = []\n\t#routesByKey = new Map<string, boolean>()\n\t#openapi: OpenApi\n\tsocket: SocketEmitter\n\tprotected server: http.Server\n\tprotected get cors() {\n\t\treturn {\n\t\t\torigin: this.config.cors?.origin,\n\t\t\tmethods: (this.config.cors?.methods ?? Object.values(Methods)).filter((m) => m !== Methods.options).map((m) => m.toUpperCase()),\n\t\t\tcredentials: this.config.cors?.credentials,\n\t\t} satisfies CorsOptions\n\t}\n\n\tconstructor(\n\t\tserver: http.Server,\n\t\tprivate config: ServerConfig,\n\t\tprivate implementations: {\n\t\t\tparseRequest: (req: Req) => Promise<Request<any>>\n\t\t\thandleResponse: (res: Res, response: Response<any>) => Promise<void>\n\t\t\tregisterRoute: (method: MethodsEnum, path: string, cb: (req: Req, res: Res) => Promise<void>) => void\n\t\t\tregisterErrorHandler: (cb: (error: Error, req: Req, res: Res) => Promise<void>) => void\n\t\t\tregisterNotFoundHandler: (cb: (req: Req, res: Res) => Promise<void>) => void\n\t\t\tstart: (port: number) => Promise<boolean>\n\t\t},\n\t) {\n\t\tthis.server = server\n\t\tthis.#openapi = new OpenApi(config)\n\t\tconst socketInstance = new SocketServer(server, { cors: this.cors })\n\t\tthis.socket = new SocketEmitter(socketInstance, config)\n\t\tthis.addRouter(this.#openapi.router())\n\t}\n\n\taddRouter(...routers: Router<any>[]) {\n\t\trouters.map((router) => router.routes).forEach((routes) => this.addRoute(...routes))\n\t}\n\n\taddRoute<T extends RouteDef>(...routes: Route<T>[]) {\n\t\troutes.forEach((route) => {\n\t\t\tthis.#queue.push(async () => {\n\t\t\t\tconst { method, path, schema = {}, onError, middlewares = [] } = route\n\n\t\t\t\tconst key = `(${method.toUpperCase()}) ${this.#openapi.cleanPath(path)}`\n\t\t\t\tif (this.#routesByKey.get(key))\n\t\t\t\t\tthrow new EquippedError(`Route key ${key} already registered. All route keys must be unique`, { route, key })\n\n\t\t\t\tmiddlewares.forEach((m) => m.onSetup?.(route as any))\n\t\t\t\tonError?.onSetup?.(route as any)\n\n\t\t\t\tconst { validateRequest, validateResponse, jsonSchema } = this.#resolveSchema(method, schema)\n\n\t\t\t\tthis.#routesByKey.set(key, true)\n\t\t\t\tawait this.#openapi.register(route, jsonSchema)\n\t\t\t\tthis.implementations.registerRoute(method, this.#openapi.cleanPath(path), async (req: Req, res: Res) => {\n\t\t\t\t\tconst request = await validateRequest(await this.implementations.parseRequest(req))\n\t\t\t\t\ttry {\n\t\t\t\t\t\tfor (const middleware of middlewares) await middleware.cb(request, this.config)\n\t\t\t\t\t\tconst rawRes = await route.handler(request, this.config)\n\t\t\t\t\t\tconst response =\n\t\t\t\t\t\t\trawRes instanceof Response\n\t\t\t\t\t\t\t\t? rawRes\n\t\t\t\t\t\t\t\t: new Response({ body: rawRes, status: StatusCodes.Ok, headers: {}, piped: false })\n\t\t\t\t\t\treturn await this.implementations.handleResponse(res, await validateResponse(response))\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tif (onError?.cb) {\n\t\t\t\t\t\t\tconst rawResponse = await onError.cb(request, this.config, error as Error)\n\t\t\t\t\t\t\tconst response =\n\t\t\t\t\t\t\t\trawResponse instanceof Response\n\t\t\t\t\t\t\t\t\t? rawResponse\n\t\t\t\t\t\t\t\t\t: new Response({ body: rawResponse, status: StatusCodes.BadRequest, headers: {} })\n\t\t\t\t\t\t\treturn await this.implementations.handleResponse(res, await validateResponse(response))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthrow error\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\t}\n\n\t#resolveSchema(method: MethodsEnum, schema: RouteDef) {\n\t\tconst defaultStatusCode = schema?.defaultStatusCode ?? StatusCodes.Ok\n\t\tconst defaultContentType = schema?.defaultContentType ?? 'application/json'\n\t\tlet status = defaultStatusCode\n\t\tlet contentType = defaultContentType\n\t\tconst jsonSchema: OpenApiSchemaDef = { response: {}, request: {} }\n\t\tconst requestPipeDefs: Pick<RouteDef, 'body' | 'headers' | 'query' | 'params' | 'cookies'> = {}\n\t\tconst responsePipeDefs: Pick<RouteDef, 'response' | 'responseHeaders' | 'responseCookies'> = {}\n\n\t\tconst defs: {\n\t\t\tkey: Exclude<keyof RouteDef, `default${string}` | 'context'>\n\t\t\ttype: keyof OpenApiSchemaDef\n\t\t\tskip?: boolean\n\t\t}[] = [\n\t\t\t{ key: 'params', type: 'request' },\n\t\t\t{ key: 'headers', type: 'request' },\n\t\t\t{ key: 'cookies', type: 'request' },\n\t\t\t{ key: 'query', type: 'request' },\n\t\t\t{ key: 'body', type: 'request', skip: !(<MethodsEnum[]>[Methods.post, Methods.put, Methods.patch]).includes(method) },\n\t\t\t{ key: 'response', type: 'response' },\n\t\t\t{ key: 'responseHeaders', type: 'response' },\n\t\t\t{ key: 'responseCookies', type: 'response' },\n\t\t]\n\t\tdefs.forEach((def) => {\n\t\t\tconst pipe = schema[def.key] ?? v.any()\n\t\t\tif (def.skip) return\n\n\t\t\tif (def.type === 'request') {\n\t\t\t\trequestPipeDefs[def.key] = pipe\n\t\t\t\tjsonSchema.request[def.key as keyof typeof jsonSchema.request] = v.schema(pipe)\n\t\t\t}\n\t\t\tif (def.type === 'response') {\n\t\t\t\tconst pipeRecords = errorsSchemas.concat({ status: defaultStatusCode, contentType, pipe })\n\t\t\t\tresponsePipeDefs[def.key] = v.any().pipe((input) => {\n\t\t\t\t\tconst p = pipeRecords.find((r) => r.status === status)?.pipe\n\t\t\t\t\tif (!p) throw PipeError.root(`schema not defined for status code: ${status}`, input)\n\t\t\t\t\treturn v.assert(p, input)\n\t\t\t\t})\n\t\t\t\tjsonSchema.response[def.key as keyof typeof jsonSchema.response] = pipeRecords.map((record) => ({\n\t\t\t\t\tstatus: record.status,\n\t\t\t\t\tcontentType: record.contentType,\n\t\t\t\t\tschema: v.schema(record.pipe),\n\t\t\t\t}))\n\t\t\t}\n\t\t})\n\t\tconst requestPipe = v.object(requestPipeDefs)\n\t\tv.compile(requestPipe, { allErrors: true })\n\t\tconst responsePipe = v.object(responsePipeDefs)\n\t\tv.compile(responsePipe, { allErrors: true })\n\t\tconst validateRequest: RequestValidator = async (request) => {\n\t\t\tif (!Object.keys(requestPipeDefs)) return request\n\t\t\tconst validity = requestLocalStorage.run(request, () =>\n\t\t\t\tv.validate(requestPipe, {\n\t\t\t\t\tparams: request.params,\n\t\t\t\t\theaders: request.headers,\n\t\t\t\t\tquery: request.query,\n\t\t\t\t\tbody: request.body,\n\t\t\t\t\tcookies: request.cookies,\n\t\t\t\t}),\n\t\t\t)\n\n\t\t\tif (!validity.valid) throw pipeErrorToValidationError(validity.error)\n\t\t\trequest.params = validity.value.params!\n\t\t\trequest.headers = validity.value.headers!\n\t\t\trequest.query = validity.value.query!\n\t\t\trequest.body = validity.value.body!\n\t\t\trequest.cookies = validity.value.cookies!\n\t\t\treturn request\n\t\t}\n\t\tconst validateResponse: ResponseValidator = async (response) => {\n\t\t\tif (!Object.keys(responsePipeDefs)) return response\n\t\t\tstatus = response.status\n\t\t\tcontentType = response.contentType\n\n\t\t\tconst validity = responseLocalStorage.run(response, () =>\n\t\t\t\tv.validate(responsePipe, {\n\t\t\t\t\tresponseHeaders: response.headers,\n\t\t\t\t\tresponseCookies: Object.fromEntries(Object.entries(response.cookies).map(([key, val]) => [key, val.value] as const)),\n\t\t\t\t\tresponse: response.body,\n\t\t\t\t}),\n\t\t\t)\n\n\t\t\tif (!validity.valid) throw pipeErrorToValidationError(validity.error)\n\t\t\tresponse.body = validity.value.response!\n\t\t\tresponse.headers = validity.value.responseHeaders!\n\t\t\tresponse.cookieValues = validity.value.responseCookies!\n\t\t\treturn response\n\t\t}\n\t\treturn {\n\t\t\tjsonSchema,\n\t\t\tvalidateRequest,\n\t\t\tvalidateResponse,\n\t\t}\n\t}\n\n\ttest() {\n\t\treturn supertest(this.server)\n\t}\n\n\tasync start() {\n\t\tconst port = this.config.port\n\t\tconst instance = Instance.get()\n\t\tconst { app } = instance.settings\n\t\tif (this.config.healthPath)\n\t\t\tthis.addRoute({\n\t\t\t\tmethod: Methods.get,\n\t\t\t\tpath: this.config.healthPath,\n\t\t\t\thandler: async (req) =>\n\t\t\t\t\treq.res({\n\t\t\t\t\t\tbody: `${instance.id}(${app.name}) service running`,\n\t\t\t\t\t\tcontentType: 'text/plain',\n\t\t\t\t\t}),\n\t\t\t})\n\n\t\tthis.implementations.registerNotFoundHandler(async (req) => {\n\t\t\tconst request = await this.implementations.parseRequest(req)\n\t\t\tthrow new NotFoundError(`Route ${request.path} not found`)\n\t\t})\n\t\tthis.implementations.registerErrorHandler(async (error, _, res) => {\n\t\t\tInstance.get().log.error({ error }, 'Uncaught error in route handler')\n\t\t\tconst response =\n\t\t\t\terror instanceof RequestError\n\t\t\t\t\t? new Response({\n\t\t\t\t\t\t\tbody: error.serializedErrors,\n\t\t\t\t\t\t\tstatus: error.statusCode,\n\t\t\t\t\t\t})\n\t\t\t\t\t: new Response({\n\t\t\t\t\t\t\tbody: [{ message: 'Something went wrong', data: error.message }],\n\t\t\t\t\t\t\tstatus: StatusCodes.BadRequest,\n\t\t\t\t\t\t})\n\t\t\treturn await this.implementations.handleResponse(res, response)\n\t\t})\n\n\t\tawait Promise.all(this.#queue.map((cb) => cb()))\n\t\tconst started = await this.implementations.start(port)\n\t\tif (started) Instance.get().log.info(`${instance.id}(${app.name}) service listening on port ${port}`)\n\t\treturn started\n\t}\n}\n"],"mappings":"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","names":["SocketServer","supertest","PipeError","v","EquippedError","NotFoundError","RequestError","Instance","pipeErrorToValidationError","requestLocalStorage","responseLocalStorage","OpenApi","Response","SocketEmitter","Methods","StatusCodes","errorsSchemas","value","key","Server","server","config","implementations","#openapi","socketInstance","#queue","#routesByKey","m","routers","router","routes","route","method","path","schema","onError","middlewares","validateRequest","validateResponse","jsonSchema","#resolveSchema","req","res","request","middleware","rawRes","response","error","rawResponse","defaultStatusCode","defaultContentType","status","contentType","requestPipeDefs","responsePipeDefs","def","pipe","pipeRecords","input","p","r","record","requestPipe","responsePipe","validity","val","port","instance","app","_","cb","started"]}
@@ -1,3 +1,4 @@
1
+ import {} from "cors";
1
2
  import { Server as SocketServer } from "socket.io";
2
3
  import supertest from "supertest";
3
4
  import { PipeError, v } from "valleyed";
@@ -5,7 +6,6 @@ import { EquippedError, NotFoundError, RequestError } from "../../errors/index.m
5
6
  import { Instance } from "../../instance/index.mjs";
6
7
  import { pipeErrorToValidationError } from "../../validations/index.mjs";
7
8
  import { requestLocalStorage, responseLocalStorage } from "../../validations/valleyed.mjs";
8
- import { parseAuthUser } from "../middlewares/parseAuthUser.mjs";
9
9
  import { OpenApi } from "../openapi.mjs";
10
10
  import { Response } from "../requests.mjs";
11
11
  import { Router } from "../routes.mjs";
@@ -34,10 +34,13 @@ class Server {
34
34
  #openapi;
35
35
  socket;
36
36
  server;
37
- cors = {
38
- origin: "*",
39
- methods: Object.values(Methods).filter((m) => m !== Methods.options).map((m) => m.toUpperCase())
40
- };
37
+ get cors() {
38
+ return {
39
+ origin: this.config.cors?.origin,
40
+ methods: (this.config.cors?.methods ?? Object.values(Methods)).filter((m) => m !== Methods.options).map((m) => m.toUpperCase()),
41
+ credentials: this.config.cors?.credentials
42
+ };
43
+ }
41
44
  addRouter(...routers) {
42
45
  routers.map((router) => router.routes).forEach((routes) => this.addRoute(...routes));
43
46
  }
@@ -48,7 +51,6 @@ class Server {
48
51
  const key = `(${method.toUpperCase()}) ${this.#openapi.cleanPath(path)}`;
49
52
  if (this.#routesByKey.get(key))
50
53
  throw new EquippedError(`Route key ${key} already registered. All route keys must be unique`, { route, key });
51
- middlewares.unshift(parseAuthUser);
52
54
  middlewares.forEach((m) => m.onSetup?.(route));
53
55
  onError?.onSetup?.(route);
54
56
  const { validateRequest, validateResponse, jsonSchema } = this.#resolveSchema(method, schema);
@@ -118,8 +120,6 @@ class Server {
118
120
  v.compile(responsePipe, { allErrors: true });
119
121
  const validateRequest = async (request) => {
120
122
  if (!Object.keys(requestPipeDefs)) return request;
121
- const context = schema.context ? await schema.context(request) : {};
122
- request.context = context;
123
123
  const validity = requestLocalStorage.run(
124
124
  request,
125
125
  () => v.validate(requestPipe, {
@@ -146,7 +146,7 @@ class Server {
146
146
  response,
147
147
  () => v.validate(responsePipe, {
148
148
  responseHeaders: response.headers,
149
- responseCookies: response.cookies,
149
+ responseCookies: Object.fromEntries(Object.entries(response.cookies).map(([key, val]) => [key, val.value])),
150
150
  response: response.body
151
151
  })
152
152
  );
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/server/impls/base.ts"],"sourcesContent":["import type http from 'http'\n\nimport { Server as SocketServer } from 'socket.io'\nimport supertest from 'supertest'\nimport { type Pipe, PipeError, v } from 'valleyed'\n\nimport { EquippedError, NotFoundError, RequestError } from '../../errors'\nimport { Instance } from '../../instance'\nimport { pipeErrorToValidationError } from '../../validations'\nimport { requestLocalStorage, responseLocalStorage } from '../../validations/valleyed'\nimport { parseAuthUser } from '../middlewares/parseAuthUser'\nimport { OpenApi, type OpenApiSchemaDef } from '../openapi'\nimport type { ServerConfig } from '../pipes'\nimport { type Request, Response } from '../requests'\nimport { Router } from '../routes'\nimport { SocketEmitter } from '../sockets'\nimport { Methods, type MethodsEnum, type RouteDef, StatusCodes, type Route } from '../types'\n\ntype RequestValidator = (req: Request<any>) => Promise<Request<any>>\ntype ResponseValidator = (res: Response<any>) => Promise<Response<any>>\n\nconst errorsSchemas = Object.entries(StatusCodes)\n\t.filter(([, value]) => value > 399)\n\t.map(([key, value]) => ({\n\t\tstatus: value,\n\t\tcontentType: 'application/json',\n\t\tpipe: v.meta(v.array(v.object({ message: v.string(), field: v.optional(v.string()) })), {\n\t\t\t$refId: `Errors.${key}Response`,\n\t\t\tdescription: `${key} Response`,\n\t\t}) as Pipe<any, any>,\n\t}))\n\nexport abstract class Server<Req = any, Res = any> {\n\t#queue: (() => void | Promise<void>)[] = []\n\t#routesByKey = new Map<string, boolean>()\n\t#openapi: OpenApi\n\tsocket: SocketEmitter\n\tprotected server: http.Server\n\tprotected cors = {\n\t\torigin: '*',\n\t\tmethods: Object.values(Methods)\n\t\t\t.filter((m) => m !== Methods.options)\n\t\t\t.map((m) => m.toUpperCase()),\n\t}\n\n\tconstructor(\n\t\tserver: http.Server,\n\t\tprivate config: ServerConfig,\n\t\tprivate implementations: {\n\t\t\tparseRequest: (req: Req) => Promise<Request<any>>\n\t\t\thandleResponse: (res: Res, response: Response<any>) => Promise<void>\n\t\t\tregisterRoute: (method: MethodsEnum, path: string, cb: (req: Req, res: Res) => Promise<void>) => void\n\t\t\tregisterErrorHandler: (cb: (error: Error, req: Req, res: Res) => Promise<void>) => void\n\t\t\tregisterNotFoundHandler: (cb: (req: Req, res: Res) => Promise<void>) => void\n\t\t\tstart: (port: number) => Promise<boolean>\n\t\t},\n\t) {\n\t\tthis.server = server\n\t\tthis.#openapi = new OpenApi(config)\n\t\tconst socketInstance = new SocketServer(server, { cors: this.cors })\n\t\tthis.socket = new SocketEmitter(socketInstance, config)\n\t\tthis.addRouter(this.#openapi.router())\n\t}\n\n\taddRouter(...routers: Router<any>[]) {\n\t\trouters.map((router) => router.routes).forEach((routes) => this.addRoute(...routes))\n\t}\n\n\taddRoute<T extends RouteDef>(...routes: Route<T>[]) {\n\t\troutes.forEach((route) => {\n\t\t\tthis.#queue.push(async () => {\n\t\t\t\tconst { method, path, schema = {}, onError, middlewares = [] } = route\n\n\t\t\t\tconst key = `(${method.toUpperCase()}) ${this.#openapi.cleanPath(path)}`\n\t\t\t\tif (this.#routesByKey.get(key))\n\t\t\t\t\tthrow new EquippedError(`Route key ${key} already registered. All route keys must be unique`, { route, key })\n\n\t\t\t\tmiddlewares.unshift(parseAuthUser as any)\n\t\t\t\tmiddlewares.forEach((m) => m.onSetup?.(route as any))\n\t\t\t\tonError?.onSetup?.(route as any)\n\n\t\t\t\tconst { validateRequest, validateResponse, jsonSchema } = this.#resolveSchema(method, schema)\n\n\t\t\t\tthis.#routesByKey.set(key, true)\n\t\t\t\tawait this.#openapi.register(route, jsonSchema)\n\t\t\t\tthis.implementations.registerRoute(method, this.#openapi.cleanPath(path), async (req: Req, res: Res) => {\n\t\t\t\t\tconst request = await validateRequest(await this.implementations.parseRequest(req))\n\t\t\t\t\ttry {\n\t\t\t\t\t\tfor (const middleware of middlewares) await middleware.cb(request, this.config)\n\t\t\t\t\t\tconst rawRes = await route.handler(request, this.config)\n\t\t\t\t\t\tconst response =\n\t\t\t\t\t\t\trawRes instanceof Response\n\t\t\t\t\t\t\t\t? rawRes\n\t\t\t\t\t\t\t\t: new Response({ body: rawRes, status: StatusCodes.Ok, headers: {}, piped: false })\n\t\t\t\t\t\treturn await this.implementations.handleResponse(res, await validateResponse(response))\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tif (onError?.cb) {\n\t\t\t\t\t\t\tconst rawResponse = await onError.cb(request, this.config, error as Error)\n\t\t\t\t\t\t\tconst response =\n\t\t\t\t\t\t\t\trawResponse instanceof Response\n\t\t\t\t\t\t\t\t\t? rawResponse\n\t\t\t\t\t\t\t\t\t: new Response({ body: rawResponse, status: StatusCodes.BadRequest, headers: {} })\n\t\t\t\t\t\t\treturn await this.implementations.handleResponse(res, await validateResponse(response))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthrow error\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\t}\n\n\t#resolveSchema(method: MethodsEnum, schema: RouteDef) {\n\t\tconst defaultStatusCode = schema?.defaultStatusCode ?? StatusCodes.Ok\n\t\tconst defaultContentType = schema?.defaultContentType ?? 'application/json'\n\t\tlet status = defaultStatusCode\n\t\tlet contentType = defaultContentType\n\t\tconst jsonSchema: OpenApiSchemaDef = { response: {}, request: {} }\n\t\tconst requestPipeDefs: Pick<RouteDef, 'body' | 'headers' | 'query' | 'params' | 'cookies'> = {}\n\t\tconst responsePipeDefs: Pick<RouteDef, 'response' | 'responseHeaders' | 'responseCookies'> = {}\n\n\t\tconst defs: {\n\t\t\tkey: Exclude<keyof RouteDef, `default${string}` | 'context'>\n\t\t\ttype: keyof OpenApiSchemaDef\n\t\t\tskip?: boolean\n\t\t}[] = [\n\t\t\t{ key: 'params', type: 'request' },\n\t\t\t{ key: 'headers', type: 'request' },\n\t\t\t{ key: 'cookies', type: 'request' },\n\t\t\t{ key: 'query', type: 'request' },\n\t\t\t{ key: 'body', type: 'request', skip: !(<MethodsEnum[]>[Methods.post, Methods.put, Methods.patch]).includes(method) },\n\t\t\t{ key: 'response', type: 'response' },\n\t\t\t{ key: 'responseHeaders', type: 'response' },\n\t\t\t{ key: 'responseCookies', type: 'response' },\n\t\t]\n\t\tdefs.forEach((def) => {\n\t\t\tconst pipe = schema[def.key] ?? v.any()\n\t\t\tif (def.skip) return\n\n\t\t\tif (def.type === 'request') {\n\t\t\t\trequestPipeDefs[def.key] = pipe\n\t\t\t\tjsonSchema.request[def.key as keyof typeof jsonSchema.request] = v.schema(pipe)\n\t\t\t}\n\t\t\tif (def.type === 'response') {\n\t\t\t\tconst pipeRecords = errorsSchemas.concat({ status: defaultStatusCode, contentType, pipe })\n\t\t\t\tresponsePipeDefs[def.key] = v.any().pipe((input) => {\n\t\t\t\t\tconst p = pipeRecords.find((r) => r.status === status)?.pipe\n\t\t\t\t\tif (!p) throw PipeError.root(`schema not defined for status code: ${status}`, input)\n\t\t\t\t\treturn v.assert(p, input)\n\t\t\t\t})\n\t\t\t\tjsonSchema.response[def.key as keyof typeof jsonSchema.response] = pipeRecords.map((record) => ({\n\t\t\t\t\tstatus: record.status,\n\t\t\t\t\tcontentType: record.contentType,\n\t\t\t\t\tschema: v.schema(record.pipe),\n\t\t\t\t}))\n\t\t\t}\n\t\t})\n\t\tconst requestPipe = v.object(requestPipeDefs)\n\t\tv.compile(requestPipe, { allErrors: true })\n\t\tconst responsePipe = v.object(responsePipeDefs)\n\t\tv.compile(responsePipe, { allErrors: true })\n\t\tconst validateRequest: RequestValidator = async (request) => {\n\t\t\tif (!Object.keys(requestPipeDefs)) return request\n\t\t\tconst context = schema.context ? await schema.context(request) : {}\n\t\t\trequest.context = context\n\t\t\tconst validity = requestLocalStorage.run(request, () =>\n\t\t\t\tv.validate(requestPipe, {\n\t\t\t\t\tparams: request.params,\n\t\t\t\t\theaders: request.headers,\n\t\t\t\t\tquery: request.query,\n\t\t\t\t\tbody: request.body,\n\t\t\t\t\tcookies: request.cookies,\n\t\t\t\t}),\n\t\t\t)\n\n\t\t\tif (!validity.valid) throw pipeErrorToValidationError(validity.error)\n\t\t\trequest.params = validity.value.params!\n\t\t\trequest.headers = validity.value.headers!\n\t\t\trequest.query = validity.value.query!\n\t\t\trequest.body = validity.value.body!\n\t\t\trequest.cookies = validity.value.cookies!\n\t\t\treturn request\n\t\t}\n\t\tconst validateResponse: ResponseValidator = async (response) => {\n\t\t\tif (!Object.keys(responsePipeDefs)) return response\n\t\t\tstatus = response.status\n\t\t\tcontentType = response.contentType\n\n\t\t\tconst validity = responseLocalStorage.run(response, () =>\n\t\t\t\tv.validate(responsePipe, {\n\t\t\t\t\tresponseHeaders: response.headers,\n\t\t\t\t\tresponseCookies: response.cookies,\n\t\t\t\t\tresponse: response.body,\n\t\t\t\t}),\n\t\t\t)\n\n\t\t\tif (!validity.valid) throw pipeErrorToValidationError(validity.error)\n\t\t\tresponse.body = validity.value.response!\n\t\t\tresponse.headers = validity.value.responseHeaders!\n\t\t\tresponse.cookieValues = validity.value.responseCookies!\n\t\t\treturn response\n\t\t}\n\t\treturn {\n\t\t\tjsonSchema,\n\t\t\tvalidateRequest,\n\t\t\tvalidateResponse,\n\t\t}\n\t}\n\n\ttest() {\n\t\treturn supertest(this.server)\n\t}\n\n\tasync start() {\n\t\tconst port = this.config.port\n\t\tconst instance = Instance.get()\n\t\tconst { app } = instance.settings\n\t\tif (this.config.healthPath)\n\t\t\tthis.addRoute({\n\t\t\t\tmethod: Methods.get,\n\t\t\t\tpath: this.config.healthPath,\n\t\t\t\thandler: async (req) =>\n\t\t\t\t\treq.res({\n\t\t\t\t\t\tbody: `${instance.id}(${app.name}) service running`,\n\t\t\t\t\t\tcontentType: 'text/plain',\n\t\t\t\t\t}),\n\t\t\t})\n\n\t\tthis.implementations.registerNotFoundHandler(async (req) => {\n\t\t\tconst request = await this.implementations.parseRequest(req)\n\t\t\tthrow new NotFoundError(`Route ${request.path} not found`)\n\t\t})\n\t\tthis.implementations.registerErrorHandler(async (error, _, res) => {\n\t\t\tInstance.get().log.error({ error }, 'Uncaught error in route handler')\n\t\t\tconst response =\n\t\t\t\terror instanceof RequestError\n\t\t\t\t\t? new Response({\n\t\t\t\t\t\t\tbody: error.serializedErrors,\n\t\t\t\t\t\t\tstatus: error.statusCode,\n\t\t\t\t\t\t})\n\t\t\t\t\t: new Response({\n\t\t\t\t\t\t\tbody: [{ message: 'Something went wrong', data: error.message }],\n\t\t\t\t\t\t\tstatus: StatusCodes.BadRequest,\n\t\t\t\t\t\t})\n\t\t\treturn await this.implementations.handleResponse(res, response)\n\t\t})\n\n\t\tawait Promise.all(this.#queue.map((cb) => cb()))\n\t\tconst started = await this.implementations.start(port)\n\t\tif (started) Instance.get().log.info(`${instance.id}(${app.name}) service listening on port ${port}`)\n\t\treturn started\n\t}\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/server/impls/base.ts"],"sourcesContent":["import type http from 'node:http'\n\nimport { type CorsOptions } from 'cors'\nimport { Server as SocketServer } from 'socket.io'\nimport supertest from 'supertest'\nimport { type Pipe, PipeError, v } from 'valleyed'\n\nimport { EquippedError, NotFoundError, RequestError } from '../../errors'\nimport { Instance } from '../../instance'\nimport { pipeErrorToValidationError } from '../../validations'\nimport { requestLocalStorage, responseLocalStorage } from '../../validations/valleyed'\nimport { OpenApi, type OpenApiSchemaDef } from '../openapi'\nimport type { ServerConfig } from '../pipes'\nimport { type Request, Response } from '../requests'\nimport { Router } from '../routes'\nimport { SocketEmitter } from '../sockets'\nimport { Methods, type MethodsEnum, type Route, type RouteDef, StatusCodes } from '../types'\n\ntype RequestValidator = (req: Request<any>) => Promise<Request<any>>\ntype ResponseValidator = (res: Response<any>) => Promise<Response<any>>\n\nconst errorsSchemas = Object.entries(StatusCodes)\n\t.filter(([, value]) => value > 399)\n\t.map(([key, value]) => ({\n\t\tstatus: value,\n\t\tcontentType: 'application/json',\n\t\tpipe: v.meta(v.array(v.object({ message: v.string(), field: v.optional(v.string()) })), {\n\t\t\t$refId: `Errors.${key}Response`,\n\t\t\tdescription: `${key} Response`,\n\t\t}) as Pipe<any, any>,\n\t}))\n\nexport abstract class Server<Req = any, Res = any> {\n\t#queue: (() => void | Promise<void>)[] = []\n\t#routesByKey = new Map<string, boolean>()\n\t#openapi: OpenApi\n\tsocket: SocketEmitter\n\tprotected server: http.Server\n\tprotected get cors() {\n\t\treturn {\n\t\t\torigin: this.config.cors?.origin,\n\t\t\tmethods: (this.config.cors?.methods ?? Object.values(Methods)).filter((m) => m !== Methods.options).map((m) => m.toUpperCase()),\n\t\t\tcredentials: this.config.cors?.credentials,\n\t\t} satisfies CorsOptions\n\t}\n\n\tconstructor(\n\t\tserver: http.Server,\n\t\tprivate config: ServerConfig,\n\t\tprivate implementations: {\n\t\t\tparseRequest: (req: Req) => Promise<Request<any>>\n\t\t\thandleResponse: (res: Res, response: Response<any>) => Promise<void>\n\t\t\tregisterRoute: (method: MethodsEnum, path: string, cb: (req: Req, res: Res) => Promise<void>) => void\n\t\t\tregisterErrorHandler: (cb: (error: Error, req: Req, res: Res) => Promise<void>) => void\n\t\t\tregisterNotFoundHandler: (cb: (req: Req, res: Res) => Promise<void>) => void\n\t\t\tstart: (port: number) => Promise<boolean>\n\t\t},\n\t) {\n\t\tthis.server = server\n\t\tthis.#openapi = new OpenApi(config)\n\t\tconst socketInstance = new SocketServer(server, { cors: this.cors })\n\t\tthis.socket = new SocketEmitter(socketInstance, config)\n\t\tthis.addRouter(this.#openapi.router())\n\t}\n\n\taddRouter(...routers: Router<any>[]) {\n\t\trouters.map((router) => router.routes).forEach((routes) => this.addRoute(...routes))\n\t}\n\n\taddRoute<T extends RouteDef>(...routes: Route<T>[]) {\n\t\troutes.forEach((route) => {\n\t\t\tthis.#queue.push(async () => {\n\t\t\t\tconst { method, path, schema = {}, onError, middlewares = [] } = route\n\n\t\t\t\tconst key = `(${method.toUpperCase()}) ${this.#openapi.cleanPath(path)}`\n\t\t\t\tif (this.#routesByKey.get(key))\n\t\t\t\t\tthrow new EquippedError(`Route key ${key} already registered. All route keys must be unique`, { route, key })\n\n\t\t\t\tmiddlewares.forEach((m) => m.onSetup?.(route as any))\n\t\t\t\tonError?.onSetup?.(route as any)\n\n\t\t\t\tconst { validateRequest, validateResponse, jsonSchema } = this.#resolveSchema(method, schema)\n\n\t\t\t\tthis.#routesByKey.set(key, true)\n\t\t\t\tawait this.#openapi.register(route, jsonSchema)\n\t\t\t\tthis.implementations.registerRoute(method, this.#openapi.cleanPath(path), async (req: Req, res: Res) => {\n\t\t\t\t\tconst request = await validateRequest(await this.implementations.parseRequest(req))\n\t\t\t\t\ttry {\n\t\t\t\t\t\tfor (const middleware of middlewares) await middleware.cb(request, this.config)\n\t\t\t\t\t\tconst rawRes = await route.handler(request, this.config)\n\t\t\t\t\t\tconst response =\n\t\t\t\t\t\t\trawRes instanceof Response\n\t\t\t\t\t\t\t\t? rawRes\n\t\t\t\t\t\t\t\t: new Response({ body: rawRes, status: StatusCodes.Ok, headers: {}, piped: false })\n\t\t\t\t\t\treturn await this.implementations.handleResponse(res, await validateResponse(response))\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tif (onError?.cb) {\n\t\t\t\t\t\t\tconst rawResponse = await onError.cb(request, this.config, error as Error)\n\t\t\t\t\t\t\tconst response =\n\t\t\t\t\t\t\t\trawResponse instanceof Response\n\t\t\t\t\t\t\t\t\t? rawResponse\n\t\t\t\t\t\t\t\t\t: new Response({ body: rawResponse, status: StatusCodes.BadRequest, headers: {} })\n\t\t\t\t\t\t\treturn await this.implementations.handleResponse(res, await validateResponse(response))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthrow error\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\t}\n\n\t#resolveSchema(method: MethodsEnum, schema: RouteDef) {\n\t\tconst defaultStatusCode = schema?.defaultStatusCode ?? StatusCodes.Ok\n\t\tconst defaultContentType = schema?.defaultContentType ?? 'application/json'\n\t\tlet status = defaultStatusCode\n\t\tlet contentType = defaultContentType\n\t\tconst jsonSchema: OpenApiSchemaDef = { response: {}, request: {} }\n\t\tconst requestPipeDefs: Pick<RouteDef, 'body' | 'headers' | 'query' | 'params' | 'cookies'> = {}\n\t\tconst responsePipeDefs: Pick<RouteDef, 'response' | 'responseHeaders' | 'responseCookies'> = {}\n\n\t\tconst defs: {\n\t\t\tkey: Exclude<keyof RouteDef, `default${string}` | 'context'>\n\t\t\ttype: keyof OpenApiSchemaDef\n\t\t\tskip?: boolean\n\t\t}[] = [\n\t\t\t{ key: 'params', type: 'request' },\n\t\t\t{ key: 'headers', type: 'request' },\n\t\t\t{ key: 'cookies', type: 'request' },\n\t\t\t{ key: 'query', type: 'request' },\n\t\t\t{ key: 'body', type: 'request', skip: !(<MethodsEnum[]>[Methods.post, Methods.put, Methods.patch]).includes(method) },\n\t\t\t{ key: 'response', type: 'response' },\n\t\t\t{ key: 'responseHeaders', type: 'response' },\n\t\t\t{ key: 'responseCookies', type: 'response' },\n\t\t]\n\t\tdefs.forEach((def) => {\n\t\t\tconst pipe = schema[def.key] ?? v.any()\n\t\t\tif (def.skip) return\n\n\t\t\tif (def.type === 'request') {\n\t\t\t\trequestPipeDefs[def.key] = pipe\n\t\t\t\tjsonSchema.request[def.key as keyof typeof jsonSchema.request] = v.schema(pipe)\n\t\t\t}\n\t\t\tif (def.type === 'response') {\n\t\t\t\tconst pipeRecords = errorsSchemas.concat({ status: defaultStatusCode, contentType, pipe })\n\t\t\t\tresponsePipeDefs[def.key] = v.any().pipe((input) => {\n\t\t\t\t\tconst p = pipeRecords.find((r) => r.status === status)?.pipe\n\t\t\t\t\tif (!p) throw PipeError.root(`schema not defined for status code: ${status}`, input)\n\t\t\t\t\treturn v.assert(p, input)\n\t\t\t\t})\n\t\t\t\tjsonSchema.response[def.key as keyof typeof jsonSchema.response] = pipeRecords.map((record) => ({\n\t\t\t\t\tstatus: record.status,\n\t\t\t\t\tcontentType: record.contentType,\n\t\t\t\t\tschema: v.schema(record.pipe),\n\t\t\t\t}))\n\t\t\t}\n\t\t})\n\t\tconst requestPipe = v.object(requestPipeDefs)\n\t\tv.compile(requestPipe, { allErrors: true })\n\t\tconst responsePipe = v.object(responsePipeDefs)\n\t\tv.compile(responsePipe, { allErrors: true })\n\t\tconst validateRequest: RequestValidator = async (request) => {\n\t\t\tif (!Object.keys(requestPipeDefs)) return request\n\t\t\tconst validity = requestLocalStorage.run(request, () =>\n\t\t\t\tv.validate(requestPipe, {\n\t\t\t\t\tparams: request.params,\n\t\t\t\t\theaders: request.headers,\n\t\t\t\t\tquery: request.query,\n\t\t\t\t\tbody: request.body,\n\t\t\t\t\tcookies: request.cookies,\n\t\t\t\t}),\n\t\t\t)\n\n\t\t\tif (!validity.valid) throw pipeErrorToValidationError(validity.error)\n\t\t\trequest.params = validity.value.params!\n\t\t\trequest.headers = validity.value.headers!\n\t\t\trequest.query = validity.value.query!\n\t\t\trequest.body = validity.value.body!\n\t\t\trequest.cookies = validity.value.cookies!\n\t\t\treturn request\n\t\t}\n\t\tconst validateResponse: ResponseValidator = async (response) => {\n\t\t\tif (!Object.keys(responsePipeDefs)) return response\n\t\t\tstatus = response.status\n\t\t\tcontentType = response.contentType\n\n\t\t\tconst validity = responseLocalStorage.run(response, () =>\n\t\t\t\tv.validate(responsePipe, {\n\t\t\t\t\tresponseHeaders: response.headers,\n\t\t\t\t\tresponseCookies: Object.fromEntries(Object.entries(response.cookies).map(([key, val]) => [key, val.value] as const)),\n\t\t\t\t\tresponse: response.body,\n\t\t\t\t}),\n\t\t\t)\n\n\t\t\tif (!validity.valid) throw pipeErrorToValidationError(validity.error)\n\t\t\tresponse.body = validity.value.response!\n\t\t\tresponse.headers = validity.value.responseHeaders!\n\t\t\tresponse.cookieValues = validity.value.responseCookies!\n\t\t\treturn response\n\t\t}\n\t\treturn {\n\t\t\tjsonSchema,\n\t\t\tvalidateRequest,\n\t\t\tvalidateResponse,\n\t\t}\n\t}\n\n\ttest() {\n\t\treturn supertest(this.server)\n\t}\n\n\tasync start() {\n\t\tconst port = this.config.port\n\t\tconst instance = Instance.get()\n\t\tconst { app } = instance.settings\n\t\tif (this.config.healthPath)\n\t\t\tthis.addRoute({\n\t\t\t\tmethod: Methods.get,\n\t\t\t\tpath: this.config.healthPath,\n\t\t\t\thandler: async (req) =>\n\t\t\t\t\treq.res({\n\t\t\t\t\t\tbody: `${instance.id}(${app.name}) service running`,\n\t\t\t\t\t\tcontentType: 'text/plain',\n\t\t\t\t\t}),\n\t\t\t})\n\n\t\tthis.implementations.registerNotFoundHandler(async (req) => {\n\t\t\tconst request = await this.implementations.parseRequest(req)\n\t\t\tthrow new NotFoundError(`Route ${request.path} not found`)\n\t\t})\n\t\tthis.implementations.registerErrorHandler(async (error, _, res) => {\n\t\t\tInstance.get().log.error({ error }, 'Uncaught error in route handler')\n\t\t\tconst response =\n\t\t\t\terror instanceof RequestError\n\t\t\t\t\t? new Response({\n\t\t\t\t\t\t\tbody: error.serializedErrors,\n\t\t\t\t\t\t\tstatus: error.statusCode,\n\t\t\t\t\t\t})\n\t\t\t\t\t: new Response({\n\t\t\t\t\t\t\tbody: [{ message: 'Something went wrong', data: error.message }],\n\t\t\t\t\t\t\tstatus: StatusCodes.BadRequest,\n\t\t\t\t\t\t})\n\t\t\treturn await this.implementations.handleResponse(res, response)\n\t\t})\n\n\t\tawait Promise.all(this.#queue.map((cb) => cb()))\n\t\tconst started = await this.implementations.start(port)\n\t\tif (started) Instance.get().log.info(`${instance.id}(${app.name}) service listening on port ${port}`)\n\t\treturn started\n\t}\n}\n"],"mappings":"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","names":[]}
@@ -1,2 +1,2 @@
1
- import y from"http";import h from"cookie-parser";import f from"cors";import m from"express";import g from"express-fileupload";import{rateLimit as b}from"express-rate-limit";import x from"helmet";import{pinoHttp as R}from"pino-http";import{Instance as u}from "../../instance/index.min.mjs";import{getMediaDuration as j}from "../../utilities/index.min.mjs";import{Request as E}from "../requests.min.mjs";import{StatusCodes as S}from "../types.min.mjs";import{Server as k}from "./base.min.mjs";class _ extends k{#e;constructor(a){const s=m(),c=u.get();super(y.createServer(s),a,{parseRequest:async e=>{const o={...Object.fromEntries(Object.entries(e.headers).map(([i,n])=>[i,n??null])),Authorization:e.get("authorization"),RefreshToken:e.get("x-refresh-token"),ApiKey:e.get("x-api-key"),ContentType:e.get("content-type"),Referer:e.get("referer"),UserAgent:e.get("user-agent")},r=Object.fromEntries(await Promise.all(Object.entries(e.files??{}).map(async([i,n])=>{const l=Array.isArray(n)?n:[n],d=await Promise.all(l.map(async p=>({name:p.name,type:p.mimetype,size:p.size,isTruncated:p.truncated,data:p.data,duration:await j(p.data)})));return[i,d]})));return new E({ip:e.ip,body:e.body??{},cookies:e.cookies??{},params:e.params??{},query:e.query??{},method:e.method,path:e.path,headers:o,files:r,context:{}})},handleResponse:async(e,t)=>{if(t.piped)t.body.pipe(e);else{Object.entries(t.headers).forEach(([r,i])=>e.header(r,i)),Object.entries(t.cookies).forEach(([r,{value:i,...n}])=>e.cookie(r,i,n));const o=t.body===null||t.body===void 0?"json":"send";e.status(t.status)[o](t.body).end()}},registerRoute:(e,t,o)=>{this.#e[e]?.(t,o)},registerErrorHandler:e=>{this.#e.use(async(t,o,r,i)=>e(t,o,r))},registerNotFoundHandler:e=>{this.#e.use(e)},start:async e=>new Promise((t,o)=>{try{const r=this.server.listen({host:"0.0.0.0",port:e},async()=>t(!0));u.on("close",r.close,1)}catch(r){o(r)}})}),this.#e=s,s.disable("x-powered-by"),a.requests.log&&s.use(R({logger:c.log})),s.use(m.json()),s.use(m.text()),s.use(h()),s.use(x({crossOriginResourcePolicy:{policy:"cross-origin"},contentSecurityPolicy:!1})),s.use(f(this.cors)),s.use(m.urlencoded({extended:!1})),a.publicPath&&s.use(m.static(a.publicPath)),s.use(g({limits:{fileSize:c.settings.utils.maxFileUploadSizeInMb*1024*1024},useTempFiles:!1})),a.requests.rateLimit.enabled&&s.use(b({windowMs:a.requests.rateLimit.periodInMs,limit:a.requests.rateLimit.limit,handler:(e,t)=>t.status(S.TooManyRequests).json([{message:"Too Many Requests"}])}))}}export{_ as ExpressServer};
1
+ import d from"http";import l from"cookie-parser";import y from"cors";import p from"express";import h from"express-fileupload";import{rateLimit as f}from"express-rate-limit";import b from"helmet";import{pinoHttp as x}from"pino-http";import{Instance as c}from "../../instance/index.min.mjs";import{getMediaDuration as g}from "../../utilities/index.min.mjs";import{Request as R}from "../requests.min.mjs";import{StatusCodes as S}from "../types.min.mjs";import{Server as v}from "./base.min.mjs";class C extends v{#e;constructor(i){const t=p(),u=c.get();super(d.createServer(t),i,{parseRequest:async e=>{const s=Object.fromEntries(await Promise.all(Object.entries(e.files??{}).map(async([o,r])=>{const a=Array.isArray(r)?r:[r],m=await Promise.all(a.map(async n=>({name:n.name,type:n.mimetype,size:n.size,isTruncated:n.truncated,data:n.data,duration:await g(n.data)})));return[o,m]})));return new R({ip:e.ip,body:e.body??{},cookies:e.cookies??{},params:e.params??{},query:e.query??{},method:e.method,path:e.path,headers:e.headers,files:s})},handleResponse:async(e,s)=>{if(s.piped)s.body.pipe(e);else{Object.entries(s.headers).forEach(([r,a])=>e.header(r,a)),Object.entries(s.cookies).forEach(([r,{value:a,...m}])=>e.cookie(r,a,m));const o=s.body===null||s.body===void 0?"json":"send";e.status(s.status)[o](s.body).end()}},registerRoute:(e,s,o)=>{this.#e[e]?.(s,o)},registerErrorHandler:e=>{this.#e.use(async(s,o,r,a)=>e(s,o,r))},registerNotFoundHandler:e=>{this.#e.use(e)},start:async e=>new Promise((s,o)=>{try{const r=this.server.listen({host:"0.0.0.0",port:e},async()=>s(!0));c.on("close",r.close,1)}catch(r){o(r)}})}),this.#e=t,t.disable("x-powered-by"),i.requests.log&&t.use(x({logger:u.log})),t.use(p.json()),t.use(p.text()),t.use(l()),t.use(b({crossOriginResourcePolicy:{policy:"cross-origin"},contentSecurityPolicy:!1})),t.use(y(this.cors)),t.use(p.urlencoded({extended:!1})),i.publicPath&&t.use(p.static(i.publicPath)),t.use(h({limits:{fileSize:u.settings.utils.maxFileUploadSizeInMb*1024*1024},useTempFiles:!1})),i.requests.rateLimit.enabled&&t.use(f({windowMs:i.requests.rateLimit.periodInMs,limit:i.requests.rateLimit.limit,handler:(e,s)=>s.status(S.TooManyRequests).json([{message:"Too Many Requests"}])}))}}export{C as ExpressServer};
2
2
  //# sourceMappingURL=express.min.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/server/impls/express.ts"],"sourcesContent":["import http from 'http'\n\nimport cookie from 'cookie-parser'\nimport cors from 'cors'\nimport express from 'express'\nimport fileUpload from 'express-fileupload'\nimport { rateLimit } from 'express-rate-limit'\n// import slowDown from 'express-slow-down'\nimport helmet from 'helmet'\nimport { pinoHttp } from 'pino-http'\n\nimport { Instance } from '../../instance'\nimport { getMediaDuration } from '../../utilities'\nimport type { ServerConfig } from '../pipes'\nimport { Request } from '../requests'\nimport { type IncomingFile, StatusCodes } from '../types'\nimport { Server } from './base'\n\nexport class ExpressServer extends Server<express.Request, express.Response> {\n\t#expressApp: express.Express\n\n\tconstructor(config: ServerConfig) {\n\t\tconst app = express()\n\t\tconst instance = Instance.get()\n\t\tsuper(http.createServer(app), config, {\n\t\t\tparseRequest: async (req) => {\n\t\t\t\tconst allHeaders = Object.fromEntries(Object.entries(req.headers).map(([key, val]) => [key, val ?? null]))\n\t\t\t\tconst headers = {\n\t\t\t\t\t...allHeaders,\n\t\t\t\t\tAuthorization: req.get('authorization'),\n\t\t\t\t\tRefreshToken: req.get('x-refresh-token'),\n\t\t\t\t\tApiKey: req.get('x-api-key'),\n\t\t\t\t\tContentType: req.get('content-type'),\n\t\t\t\t\tReferer: req.get('referer'),\n\t\t\t\t\tUserAgent: req.get('user-agent'),\n\t\t\t\t}\n\t\t\t\tconst files = Object.fromEntries(\n\t\t\t\t\tawait Promise.all(\n\t\t\t\t\t\tObject.entries(req.files ?? {}).map(async ([key, file]) => {\n\t\t\t\t\t\t\tconst uploads = Array.isArray(file) ? file : [file]\n\t\t\t\t\t\t\tconst fileArray: IncomingFile[] = await Promise.all(\n\t\t\t\t\t\t\t\tuploads.map(async (f) => ({\n\t\t\t\t\t\t\t\t\tname: f.name,\n\t\t\t\t\t\t\t\t\ttype: f.mimetype,\n\t\t\t\t\t\t\t\t\tsize: f.size,\n\t\t\t\t\t\t\t\t\tisTruncated: f.truncated,\n\t\t\t\t\t\t\t\t\tdata: f.data,\n\t\t\t\t\t\t\t\t\tduration: await getMediaDuration(f.data),\n\t\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\treturn <const>[key, fileArray]\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t)\n\n\t\t\t\treturn new Request<any>({\n\t\t\t\t\tip: req.ip,\n\t\t\t\t\tbody: req.body ?? {},\n\t\t\t\t\tcookies: req.cookies ?? {},\n\t\t\t\t\tparams: req.params ?? {},\n\t\t\t\t\tquery: req.query ?? {},\n\t\t\t\t\tmethod: <any>req.method,\n\t\t\t\t\tpath: req.path,\n\t\t\t\t\theaders,\n\t\t\t\t\tfiles,\n\t\t\t\t\tcontext: {},\n\t\t\t\t})\n\t\t\t},\n\t\t\thandleResponse: async (res, response) => {\n\t\t\t\tif (!response.piped) {\n\t\t\t\t\tObject.entries(response.headers).forEach(([key, value]) => res.header(key, value as string))\n\t\t\t\t\tObject.entries(response.cookies).forEach(([key, { value, ...opts }]) => res.cookie(key, value, opts))\n\t\t\t\t\tconst type = response.body === null || response.body === undefined ? 'json' : 'send'\n\t\t\t\t\tres.status(response.status)[type](response.body).end()\n\t\t\t\t} else {\n\t\t\t\t\tresponse.body.pipe(res)\n\t\t\t\t}\n\t\t\t},\n\t\t\tregisterRoute: (method, path, cb) => {\n\t\t\t\tthis.#expressApp[method]?.(path, cb)\n\t\t\t},\n\t\t\tregisterErrorHandler: (cb) => {\n\t\t\t\tthis.#expressApp.use(async (err, req, res, _next) => cb(err, req, res))\n\t\t\t},\n\t\t\tregisterNotFoundHandler: (cb) => {\n\t\t\t\tthis.#expressApp.use(cb)\n\t\t\t},\n\t\t\tstart: async (port) =>\n\t\t\t\tnew Promise((resolve: (s: boolean) => void, reject: (e: Error) => void) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst app = this.server.listen({ host: '0.0.0.0', port }, async () => resolve(true))\n\t\t\t\t\t\tInstance.on('close', app.close, 1)\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treject(<Error>err)\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t})\n\t\tthis.#expressApp = app\n\n\t\tapp.disable('x-powered-by')\n\t\tif (config.requests.log) app.use(pinoHttp({ logger: instance.log }))\n\t\tapp.use(express.json())\n\t\tapp.use(express.text())\n\t\tapp.use(cookie())\n\t\tapp.use(\n\t\t\thelmet({\n\t\t\t\tcrossOriginResourcePolicy: { policy: 'cross-origin' },\n\t\t\t\tcontentSecurityPolicy: false,\n\t\t\t}),\n\t\t)\n\t\tapp.use(cors(this.cors))\n\t\tapp.use(express.urlencoded({ extended: false }))\n\t\tif (config.publicPath) app.use(express.static(config.publicPath))\n\t\tapp.use(\n\t\t\tfileUpload({\n\t\t\t\tlimits: { fileSize: instance.settings.utils.maxFileUploadSizeInMb * 1024 * 1024 },\n\t\t\t\tuseTempFiles: false,\n\t\t\t}),\n\t\t)\n\t\tif (config.requests.rateLimit.enabled)\n\t\t\tapp.use(\n\t\t\t\trateLimit({\n\t\t\t\t\twindowMs: config.requests.rateLimit.periodInMs,\n\t\t\t\t\tlimit: config.requests.rateLimit.limit,\n\t\t\t\t\thandler: (_: express.Request, res: express.Response) =>\n\t\t\t\t\t\tres.status(StatusCodes.TooManyRequests).json([{ message: 'Too Many Requests' }]),\n\t\t\t\t}),\n\t\t\t)\n\t\t/* if (this.settings.slowdown.enabled) app.use(slowDown({\n\t\t\twindowMs: this.settings.slowdown.periodInMs,\n\t\t\tdelayAfter: this.settings.slowdown.delayAfter,\n\t\t\tdelayMs: this.settings.slowdown.delayInMs\n\t\t})) */\n\t}\n}\n"],"mappings":"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","names":["http","cookie","cors","express","fileUpload","rateLimit","helmet","pinoHttp","Instance","getMediaDuration","Request","StatusCodes","Server","ExpressServer","#expressApp","config","app","instance","req","headers","key","val","files","file","uploads","fileArray","f","res","response","value","opts","type","method","path","cb","err","_next","port","resolve","reject","_"]}
1
+ {"version":3,"sources":["../../../../src/server/impls/express.ts"],"sourcesContent":["import http from 'http'\n\nimport cookie from 'cookie-parser'\nimport cors from 'cors'\nimport express from 'express'\nimport fileUpload from 'express-fileupload'\nimport { rateLimit } from 'express-rate-limit'\n// import slowDown from 'express-slow-down'\nimport helmet from 'helmet'\nimport { pinoHttp } from 'pino-http'\n\nimport { Instance } from '../../instance'\nimport { getMediaDuration } from '../../utilities'\nimport type { ServerConfig } from '../pipes'\nimport { Request } from '../requests'\nimport { type IncomingFile, StatusCodes } from '../types'\nimport { Server } from './base'\n\nexport class ExpressServer extends Server<express.Request, express.Response> {\n\t#expressApp: express.Express\n\n\tconstructor(config: ServerConfig) {\n\t\tconst app = express()\n\t\tconst instance = Instance.get()\n\t\tsuper(http.createServer(app), config, {\n\t\t\tparseRequest: async (req) => {\n\t\t\t\tconst files = Object.fromEntries(\n\t\t\t\t\tawait Promise.all(\n\t\t\t\t\t\tObject.entries(req.files ?? {}).map(async ([key, file]) => {\n\t\t\t\t\t\t\tconst uploads = Array.isArray(file) ? file : [file]\n\t\t\t\t\t\t\tconst fileArray: IncomingFile[] = await Promise.all(\n\t\t\t\t\t\t\t\tuploads.map(async (f) => ({\n\t\t\t\t\t\t\t\t\tname: f.name,\n\t\t\t\t\t\t\t\t\ttype: f.mimetype,\n\t\t\t\t\t\t\t\t\tsize: f.size,\n\t\t\t\t\t\t\t\t\tisTruncated: f.truncated,\n\t\t\t\t\t\t\t\t\tdata: f.data,\n\t\t\t\t\t\t\t\t\tduration: await getMediaDuration(f.data),\n\t\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\treturn <const>[key, fileArray]\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t)\n\n\t\t\t\treturn new Request<any>({\n\t\t\t\t\tip: req.ip,\n\t\t\t\t\tbody: req.body ?? {},\n\t\t\t\t\tcookies: req.cookies ?? {},\n\t\t\t\t\tparams: req.params ?? {},\n\t\t\t\t\tquery: req.query ?? {},\n\t\t\t\t\tmethod: <any>req.method,\n\t\t\t\t\tpath: req.path,\n\t\t\t\t\theaders: req.headers,\n\t\t\t\t\tfiles,\n\t\t\t\t})\n\t\t\t},\n\t\t\thandleResponse: async (res, response) => {\n\t\t\t\tif (!response.piped) {\n\t\t\t\t\tObject.entries(response.headers).forEach(([key, value]) => res.header(key, value as string))\n\t\t\t\t\tObject.entries(response.cookies).forEach(([key, { value, ...opts }]) => res.cookie(key, value, opts))\n\t\t\t\t\tconst type = response.body === null || response.body === undefined ? 'json' : 'send'\n\t\t\t\t\tres.status(response.status)[type](response.body).end()\n\t\t\t\t} else {\n\t\t\t\t\tresponse.body.pipe(res)\n\t\t\t\t}\n\t\t\t},\n\t\t\tregisterRoute: (method, path, cb) => {\n\t\t\t\tthis.#expressApp[method]?.(path, cb)\n\t\t\t},\n\t\t\tregisterErrorHandler: (cb) => {\n\t\t\t\tthis.#expressApp.use(async (err, req, res, _next) => cb(err, req, res))\n\t\t\t},\n\t\t\tregisterNotFoundHandler: (cb) => {\n\t\t\t\tthis.#expressApp.use(cb)\n\t\t\t},\n\t\t\tstart: async (port) =>\n\t\t\t\tnew Promise((resolve: (s: boolean) => void, reject: (e: Error) => void) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst app = this.server.listen({ host: '0.0.0.0', port }, async () => resolve(true))\n\t\t\t\t\t\tInstance.on('close', app.close, 1)\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treject(<Error>err)\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t})\n\t\tthis.#expressApp = app\n\n\t\tapp.disable('x-powered-by')\n\t\tif (config.requests.log) app.use(pinoHttp({ logger: instance.log }))\n\t\tapp.use(express.json())\n\t\tapp.use(express.text())\n\t\tapp.use(cookie())\n\t\tapp.use(\n\t\t\thelmet({\n\t\t\t\tcrossOriginResourcePolicy: { policy: 'cross-origin' },\n\t\t\t\tcontentSecurityPolicy: false,\n\t\t\t}),\n\t\t)\n\t\tapp.use(cors(this.cors))\n\t\tapp.use(express.urlencoded({ extended: false }))\n\t\tif (config.publicPath) app.use(express.static(config.publicPath))\n\t\tapp.use(\n\t\t\tfileUpload({\n\t\t\t\tlimits: { fileSize: instance.settings.utils.maxFileUploadSizeInMb * 1024 * 1024 },\n\t\t\t\tuseTempFiles: false,\n\t\t\t}),\n\t\t)\n\t\tif (config.requests.rateLimit.enabled)\n\t\t\tapp.use(\n\t\t\t\trateLimit({\n\t\t\t\t\twindowMs: config.requests.rateLimit.periodInMs,\n\t\t\t\t\tlimit: config.requests.rateLimit.limit,\n\t\t\t\t\thandler: (_: express.Request, res: express.Response) =>\n\t\t\t\t\t\tres.status(StatusCodes.TooManyRequests).json([{ message: 'Too Many Requests' }]),\n\t\t\t\t}),\n\t\t\t)\n\t\t/* if (this.settings.slowdown.enabled) app.use(slowDown({\n\t\t\twindowMs: this.settings.slowdown.periodInMs,\n\t\t\tdelayAfter: this.settings.slowdown.delayAfter,\n\t\t\tdelayMs: this.settings.slowdown.delayInMs\n\t\t})) */\n\t}\n}\n"],"mappings":"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","names":["http","cookie","cors","express","fileUpload","rateLimit","helmet","pinoHttp","Instance","getMediaDuration","Request","StatusCodes","Server","ExpressServer","#expressApp","config","app","instance","req","files","key","file","uploads","fileArray","f","res","response","value","opts","type","method","path","cb","err","_next","port","resolve","reject","_"]}
@@ -18,16 +18,6 @@ class ExpressServer extends Server {
18
18
  const instance = Instance.get();
19
19
  super(http.createServer(app), config, {
20
20
  parseRequest: async (req) => {
21
- const allHeaders = Object.fromEntries(Object.entries(req.headers).map(([key, val]) => [key, val ?? null]));
22
- const headers = {
23
- ...allHeaders,
24
- Authorization: req.get("authorization"),
25
- RefreshToken: req.get("x-refresh-token"),
26
- ApiKey: req.get("x-api-key"),
27
- ContentType: req.get("content-type"),
28
- Referer: req.get("referer"),
29
- UserAgent: req.get("user-agent")
30
- };
31
21
  const files = Object.fromEntries(
32
22
  await Promise.all(
33
23
  Object.entries(req.files ?? {}).map(async ([key, file]) => {
@@ -54,9 +44,8 @@ class ExpressServer extends Server {
54
44
  query: req.query ?? {},
55
45
  method: req.method,
56
46
  path: req.path,
57
- headers,
58
- files,
59
- context: {}
47
+ headers: req.headers,
48
+ files
60
49
  });
61
50
  },
62
51
  handleResponse: async (res, response) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/server/impls/express.ts"],"sourcesContent":["import http from 'http'\n\nimport cookie from 'cookie-parser'\nimport cors from 'cors'\nimport express from 'express'\nimport fileUpload from 'express-fileupload'\nimport { rateLimit } from 'express-rate-limit'\n// import slowDown from 'express-slow-down'\nimport helmet from 'helmet'\nimport { pinoHttp } from 'pino-http'\n\nimport { Instance } from '../../instance'\nimport { getMediaDuration } from '../../utilities'\nimport type { ServerConfig } from '../pipes'\nimport { Request } from '../requests'\nimport { type IncomingFile, StatusCodes } from '../types'\nimport { Server } from './base'\n\nexport class ExpressServer extends Server<express.Request, express.Response> {\n\t#expressApp: express.Express\n\n\tconstructor(config: ServerConfig) {\n\t\tconst app = express()\n\t\tconst instance = Instance.get()\n\t\tsuper(http.createServer(app), config, {\n\t\t\tparseRequest: async (req) => {\n\t\t\t\tconst allHeaders = Object.fromEntries(Object.entries(req.headers).map(([key, val]) => [key, val ?? null]))\n\t\t\t\tconst headers = {\n\t\t\t\t\t...allHeaders,\n\t\t\t\t\tAuthorization: req.get('authorization'),\n\t\t\t\t\tRefreshToken: req.get('x-refresh-token'),\n\t\t\t\t\tApiKey: req.get('x-api-key'),\n\t\t\t\t\tContentType: req.get('content-type'),\n\t\t\t\t\tReferer: req.get('referer'),\n\t\t\t\t\tUserAgent: req.get('user-agent'),\n\t\t\t\t}\n\t\t\t\tconst files = Object.fromEntries(\n\t\t\t\t\tawait Promise.all(\n\t\t\t\t\t\tObject.entries(req.files ?? {}).map(async ([key, file]) => {\n\t\t\t\t\t\t\tconst uploads = Array.isArray(file) ? file : [file]\n\t\t\t\t\t\t\tconst fileArray: IncomingFile[] = await Promise.all(\n\t\t\t\t\t\t\t\tuploads.map(async (f) => ({\n\t\t\t\t\t\t\t\t\tname: f.name,\n\t\t\t\t\t\t\t\t\ttype: f.mimetype,\n\t\t\t\t\t\t\t\t\tsize: f.size,\n\t\t\t\t\t\t\t\t\tisTruncated: f.truncated,\n\t\t\t\t\t\t\t\t\tdata: f.data,\n\t\t\t\t\t\t\t\t\tduration: await getMediaDuration(f.data),\n\t\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\treturn <const>[key, fileArray]\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t)\n\n\t\t\t\treturn new Request<any>({\n\t\t\t\t\tip: req.ip,\n\t\t\t\t\tbody: req.body ?? {},\n\t\t\t\t\tcookies: req.cookies ?? {},\n\t\t\t\t\tparams: req.params ?? {},\n\t\t\t\t\tquery: req.query ?? {},\n\t\t\t\t\tmethod: <any>req.method,\n\t\t\t\t\tpath: req.path,\n\t\t\t\t\theaders,\n\t\t\t\t\tfiles,\n\t\t\t\t\tcontext: {},\n\t\t\t\t})\n\t\t\t},\n\t\t\thandleResponse: async (res, response) => {\n\t\t\t\tif (!response.piped) {\n\t\t\t\t\tObject.entries(response.headers).forEach(([key, value]) => res.header(key, value as string))\n\t\t\t\t\tObject.entries(response.cookies).forEach(([key, { value, ...opts }]) => res.cookie(key, value, opts))\n\t\t\t\t\tconst type = response.body === null || response.body === undefined ? 'json' : 'send'\n\t\t\t\t\tres.status(response.status)[type](response.body).end()\n\t\t\t\t} else {\n\t\t\t\t\tresponse.body.pipe(res)\n\t\t\t\t}\n\t\t\t},\n\t\t\tregisterRoute: (method, path, cb) => {\n\t\t\t\tthis.#expressApp[method]?.(path, cb)\n\t\t\t},\n\t\t\tregisterErrorHandler: (cb) => {\n\t\t\t\tthis.#expressApp.use(async (err, req, res, _next) => cb(err, req, res))\n\t\t\t},\n\t\t\tregisterNotFoundHandler: (cb) => {\n\t\t\t\tthis.#expressApp.use(cb)\n\t\t\t},\n\t\t\tstart: async (port) =>\n\t\t\t\tnew Promise((resolve: (s: boolean) => void, reject: (e: Error) => void) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst app = this.server.listen({ host: '0.0.0.0', port }, async () => resolve(true))\n\t\t\t\t\t\tInstance.on('close', app.close, 1)\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treject(<Error>err)\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t})\n\t\tthis.#expressApp = app\n\n\t\tapp.disable('x-powered-by')\n\t\tif (config.requests.log) app.use(pinoHttp({ logger: instance.log }))\n\t\tapp.use(express.json())\n\t\tapp.use(express.text())\n\t\tapp.use(cookie())\n\t\tapp.use(\n\t\t\thelmet({\n\t\t\t\tcrossOriginResourcePolicy: { policy: 'cross-origin' },\n\t\t\t\tcontentSecurityPolicy: false,\n\t\t\t}),\n\t\t)\n\t\tapp.use(cors(this.cors))\n\t\tapp.use(express.urlencoded({ extended: false }))\n\t\tif (config.publicPath) app.use(express.static(config.publicPath))\n\t\tapp.use(\n\t\t\tfileUpload({\n\t\t\t\tlimits: { fileSize: instance.settings.utils.maxFileUploadSizeInMb * 1024 * 1024 },\n\t\t\t\tuseTempFiles: false,\n\t\t\t}),\n\t\t)\n\t\tif (config.requests.rateLimit.enabled)\n\t\t\tapp.use(\n\t\t\t\trateLimit({\n\t\t\t\t\twindowMs: config.requests.rateLimit.periodInMs,\n\t\t\t\t\tlimit: config.requests.rateLimit.limit,\n\t\t\t\t\thandler: (_: express.Request, res: express.Response) =>\n\t\t\t\t\t\tres.status(StatusCodes.TooManyRequests).json([{ message: 'Too Many Requests' }]),\n\t\t\t\t}),\n\t\t\t)\n\t\t/* if (this.settings.slowdown.enabled) app.use(slowDown({\n\t\t\twindowMs: this.settings.slowdown.periodInMs,\n\t\t\tdelayAfter: this.settings.slowdown.delayAfter,\n\t\t\tdelayMs: this.settings.slowdown.delayInMs\n\t\t})) */\n\t}\n}\n"],"mappings":"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","names":["app"]}
1
+ {"version":3,"sources":["../../../../src/server/impls/express.ts"],"sourcesContent":["import http from 'http'\n\nimport cookie from 'cookie-parser'\nimport cors from 'cors'\nimport express from 'express'\nimport fileUpload from 'express-fileupload'\nimport { rateLimit } from 'express-rate-limit'\n// import slowDown from 'express-slow-down'\nimport helmet from 'helmet'\nimport { pinoHttp } from 'pino-http'\n\nimport { Instance } from '../../instance'\nimport { getMediaDuration } from '../../utilities'\nimport type { ServerConfig } from '../pipes'\nimport { Request } from '../requests'\nimport { type IncomingFile, StatusCodes } from '../types'\nimport { Server } from './base'\n\nexport class ExpressServer extends Server<express.Request, express.Response> {\n\t#expressApp: express.Express\n\n\tconstructor(config: ServerConfig) {\n\t\tconst app = express()\n\t\tconst instance = Instance.get()\n\t\tsuper(http.createServer(app), config, {\n\t\t\tparseRequest: async (req) => {\n\t\t\t\tconst files = Object.fromEntries(\n\t\t\t\t\tawait Promise.all(\n\t\t\t\t\t\tObject.entries(req.files ?? {}).map(async ([key, file]) => {\n\t\t\t\t\t\t\tconst uploads = Array.isArray(file) ? file : [file]\n\t\t\t\t\t\t\tconst fileArray: IncomingFile[] = await Promise.all(\n\t\t\t\t\t\t\t\tuploads.map(async (f) => ({\n\t\t\t\t\t\t\t\t\tname: f.name,\n\t\t\t\t\t\t\t\t\ttype: f.mimetype,\n\t\t\t\t\t\t\t\t\tsize: f.size,\n\t\t\t\t\t\t\t\t\tisTruncated: f.truncated,\n\t\t\t\t\t\t\t\t\tdata: f.data,\n\t\t\t\t\t\t\t\t\tduration: await getMediaDuration(f.data),\n\t\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\treturn <const>[key, fileArray]\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t)\n\n\t\t\t\treturn new Request<any>({\n\t\t\t\t\tip: req.ip,\n\t\t\t\t\tbody: req.body ?? {},\n\t\t\t\t\tcookies: req.cookies ?? {},\n\t\t\t\t\tparams: req.params ?? {},\n\t\t\t\t\tquery: req.query ?? {},\n\t\t\t\t\tmethod: <any>req.method,\n\t\t\t\t\tpath: req.path,\n\t\t\t\t\theaders: req.headers,\n\t\t\t\t\tfiles,\n\t\t\t\t})\n\t\t\t},\n\t\t\thandleResponse: async (res, response) => {\n\t\t\t\tif (!response.piped) {\n\t\t\t\t\tObject.entries(response.headers).forEach(([key, value]) => res.header(key, value as string))\n\t\t\t\t\tObject.entries(response.cookies).forEach(([key, { value, ...opts }]) => res.cookie(key, value, opts))\n\t\t\t\t\tconst type = response.body === null || response.body === undefined ? 'json' : 'send'\n\t\t\t\t\tres.status(response.status)[type](response.body).end()\n\t\t\t\t} else {\n\t\t\t\t\tresponse.body.pipe(res)\n\t\t\t\t}\n\t\t\t},\n\t\t\tregisterRoute: (method, path, cb) => {\n\t\t\t\tthis.#expressApp[method]?.(path, cb)\n\t\t\t},\n\t\t\tregisterErrorHandler: (cb) => {\n\t\t\t\tthis.#expressApp.use(async (err, req, res, _next) => cb(err, req, res))\n\t\t\t},\n\t\t\tregisterNotFoundHandler: (cb) => {\n\t\t\t\tthis.#expressApp.use(cb)\n\t\t\t},\n\t\t\tstart: async (port) =>\n\t\t\t\tnew Promise((resolve: (s: boolean) => void, reject: (e: Error) => void) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst app = this.server.listen({ host: '0.0.0.0', port }, async () => resolve(true))\n\t\t\t\t\t\tInstance.on('close', app.close, 1)\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treject(<Error>err)\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t})\n\t\tthis.#expressApp = app\n\n\t\tapp.disable('x-powered-by')\n\t\tif (config.requests.log) app.use(pinoHttp({ logger: instance.log }))\n\t\tapp.use(express.json())\n\t\tapp.use(express.text())\n\t\tapp.use(cookie())\n\t\tapp.use(\n\t\t\thelmet({\n\t\t\t\tcrossOriginResourcePolicy: { policy: 'cross-origin' },\n\t\t\t\tcontentSecurityPolicy: false,\n\t\t\t}),\n\t\t)\n\t\tapp.use(cors(this.cors))\n\t\tapp.use(express.urlencoded({ extended: false }))\n\t\tif (config.publicPath) app.use(express.static(config.publicPath))\n\t\tapp.use(\n\t\t\tfileUpload({\n\t\t\t\tlimits: { fileSize: instance.settings.utils.maxFileUploadSizeInMb * 1024 * 1024 },\n\t\t\t\tuseTempFiles: false,\n\t\t\t}),\n\t\t)\n\t\tif (config.requests.rateLimit.enabled)\n\t\t\tapp.use(\n\t\t\t\trateLimit({\n\t\t\t\t\twindowMs: config.requests.rateLimit.periodInMs,\n\t\t\t\t\tlimit: config.requests.rateLimit.limit,\n\t\t\t\t\thandler: (_: express.Request, res: express.Response) =>\n\t\t\t\t\t\tres.status(StatusCodes.TooManyRequests).json([{ message: 'Too Many Requests' }]),\n\t\t\t\t}),\n\t\t\t)\n\t\t/* if (this.settings.slowdown.enabled) app.use(slowDown({\n\t\t\twindowMs: this.settings.slowdown.periodInMs,\n\t\t\tdelayAfter: this.settings.slowdown.delayAfter,\n\t\t\tdelayMs: this.settings.slowdown.delayInMs\n\t\t})) */\n\t}\n}\n"],"mappings":"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","names":["app"]}
@@ -1,2 +1,2 @@
1
- import c from"@fastify/cookie";import p from"@fastify/cors";import y from"@fastify/formbody";import d from"@fastify/helmet";import g from"@fastify/multipart";import h from"@fastify/rate-limit";import S from"@fastify/static";import R from"fastify";import F from"qs";import{ValidationError as b}from "../../errors/index.min.mjs";import{Instance as f}from "../../instance/index.min.mjs";import{getMediaDuration as O}from "../../utilities/index.min.mjs";import{Request as T}from "../requests.min.mjs";import{StatusCodes as k}from "../types.min.mjs";import{Server as C}from "./base.min.mjs";class _ extends C{constructor(i){const o=f.get(),r=R({disableRequestLogging:!i.requests.log,loggerInstance:i.requests.log?o.log:void 0,ajv:{customOptions:{coerceTypes:!1}},routerOptions:{ignoreTrailingSlash:!0,caseSensitive:!1},schemaErrorFormatter:(e,t)=>new b(e.map(s=>({messages:[s.message??""],field:`${t}${s.instancePath}`.replaceAll("/",".")})))});super(r.server,i,{parseRequest:async e=>{const s={...Object.fromEntries(Object.entries(e.headers).map(([m,u])=>[m,u??null])),Authorization:e.headers.authorization?.toString(),RefreshToken:e.headers["x-refresh-token"]?.toString(),ApiKey:e.headers["x-api-key"]?.toString(),ContentType:e.headers["content-type"]?.toString(),Referer:e.headers.referer?.toString(),UserAgent:e.headers["user-agent"]?.toString()},{body:a,files:l}=w(e.body??{});return new T({ip:e.ip,body:a,cookies:e.cookies??{},params:e.params??{},query:e.query??{},method:e.method,path:e.url,headers:s,files:l,context:{}})},handleResponse:async(e,t)=>{for(const[s,{value:a,...l}]of Object.entries(t.cookies))e=e.setCookie(s,a,l);await e.status(t.status).headers(t.headers).send(t.body)},registerRoute:(e,t,s)=>{r.register(async a=>{a.route({url:t,method:e,handler:s})})},registerErrorHandler:e=>{r.setErrorHandler(e)},registerNotFoundHandler:e=>{r.setNotFoundHandler(e)},start:async e=>(await r.ready(),await r.listen({port:e,host:"0.0.0.0"}),f.on("close",r.close,1),!0)}),r.decorateRequest("savedReq",null),r.setValidatorCompiler(()=>()=>!0),r.setSerializerCompiler(()=>e=>JSON.stringify(e)),i.publicPath&&r.register(S,{root:i.publicPath}),r.register(c,{}),r.register(p,this.cors),r.register(y,{parser:e=>F.parse(e)}),r.register(d,{crossOriginResourcePolicy:{policy:"cross-origin"},contentSecurityPolicy:!1}),r.register(g,{attachFieldsToBody:"keyValues",throwFileSizeLimit:!1,limits:{fileSize:o.settings.utils.maxFileUploadSizeInMb*1024*1024},onFile:async e=>{const t=await e.toBuffer(),s={name:e.filename,type:e.mimetype,size:t.byteLength,isTruncated:e.file.truncated,data:t,duration:await O(t)};e.value=s}}),i.requests.rateLimit.enabled&&r.register(h,{max:i.requests.rateLimit.limit,timeWindow:i.requests.rateLimit.periodInMs,errorResponseBuilder:(e,t)=>({statusCode:k.TooManyRequests,message:JSON.stringify([{message:`Too Many Requests. Retry in ${t.after}`}])})})}}function w(n){if(typeof n!="object")return{body:n,files:{}};const i=Object.entries(n??{}),o=t=>Array.isArray(t)?o(t.at(0)):Buffer.isBuffer(t?.data),r=i.filter(([t,s])=>o(s)).map(([t,s])=>[t,Array.isArray(s)?s:[s]]),e=i.filter(([t,s])=>!o(s));return{body:Object.fromEntries(e),files:Object.fromEntries(r)}}export{_ as FastifyServer};
1
+ import l from"@fastify/cookie";import u from"@fastify/cors";import y from"@fastify/formbody";import p from"@fastify/helmet";import c from"@fastify/multipart";import d from"@fastify/rate-limit";import g from"@fastify/static";import h from"fastify";import F from"qs";import{ValidationError as R}from "../../errors/index.min.mjs";import{Instance as m}from "../../instance/index.min.mjs";import{getMediaDuration as S}from "../../utilities/index.min.mjs";import{Request as b}from "../requests.min.mjs";import{StatusCodes as q}from "../types.min.mjs";import{Server as w}from "./base.min.mjs";class N extends w{constructor(i){const o=m.get(),r=h({disableRequestLogging:!i.requests.log,loggerInstance:i.requests.log?o.log:void 0,ajv:{customOptions:{coerceTypes:!1}},routerOptions:{ignoreTrailingSlash:!0,caseSensitive:!1},schemaErrorFormatter:(e,t)=>new R(e.map(s=>({messages:[s.message??""],field:`${t}${s.instancePath}`.replaceAll("/",".")})))});super(r.server,i,{parseRequest:async e=>{const{body:t,files:s}=C(e.body??{});return new b({ip:e.ip,body:t,cookies:e.cookies??{},params:e.params??{},query:e.query??{},method:e.method,path:e.url,headers:e.headers,files:s})},handleResponse:async(e,t)=>{for(const[s,{value:n,...f}]of Object.entries(t.cookies))e=e.setCookie(s,n,f);await e.status(t.status).headers(t.headers).send(t.body)},registerRoute:(e,t,s)=>{r.register(async n=>{n.route({url:t,method:e,handler:s})})},registerErrorHandler:e=>{r.setErrorHandler(e)},registerNotFoundHandler:e=>{r.setNotFoundHandler(e)},start:async e=>(await r.ready(),await r.listen({port:e,host:"0.0.0.0"}),m.on("close",r.close,1),!0)}),r.decorateRequest("savedReq",null),r.setValidatorCompiler(()=>()=>!0),r.setSerializerCompiler(()=>e=>JSON.stringify(e)),i.publicPath&&r.register(g,{root:i.publicPath}),r.register(l,{}),r.register(u,this.cors),r.register(y,{parser:e=>F.parse(e)}),r.register(p,{crossOriginResourcePolicy:{policy:"cross-origin"},contentSecurityPolicy:!1}),r.register(c,{attachFieldsToBody:"keyValues",throwFileSizeLimit:!1,limits:{fileSize:o.settings.utils.maxFileUploadSizeInMb*1024*1024},onFile:async e=>{const t=await e.toBuffer(),s={name:e.filename,type:e.mimetype,size:t.byteLength,isTruncated:e.file.truncated,data:t,duration:await S(t)};e.value=s}}),i.requests.rateLimit.enabled&&r.register(d,{max:i.requests.rateLimit.limit,timeWindow:i.requests.rateLimit.periodInMs,errorResponseBuilder:(e,t)=>({statusCode:q.TooManyRequests,message:JSON.stringify([{message:`Too Many Requests. Retry in ${t.after}`}])})})}}function C(a){if(typeof a!="object")return{body:a,files:{}};const i=Object.entries(a??{}),o=t=>Array.isArray(t)?o(t.at(0)):Buffer.isBuffer(t?.data),r=i.filter(([t,s])=>o(s)).map(([t,s])=>[t,Array.isArray(s)?s:[s]]),e=i.filter(([t,s])=>!o(s));return{body:Object.fromEntries(e),files:Object.fromEntries(r)}}export{N as FastifyServer};
2
2
  //# sourceMappingURL=fastify.min.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/server/impls/fastify.ts"],"sourcesContent":["import fastifyCookie from '@fastify/cookie'\nimport fastifyCors from '@fastify/cors'\nimport fastifyFormBody from '@fastify/formbody'\nimport fastifyHelmet from '@fastify/helmet'\nimport fastifyMultipart from '@fastify/multipart'\nimport fastifyRateLimit from '@fastify/rate-limit'\nimport fastifyStatic from '@fastify/static'\nimport type { FastifyReply, FastifyRequest } from 'fastify'\nimport Fastify from 'fastify'\n// import fastifySlowDown from 'fastify-slow-down'\nimport qs from 'qs'\n\nimport { ValidationError } from '../../errors'\nimport { Instance } from '../../instance'\nimport { getMediaDuration } from '../../utilities'\nimport type { ServerConfig } from '../pipes'\nimport { Request } from '../requests'\nimport { type IncomingFile, StatusCodes } from '../types'\nimport { Server } from './base'\n\nexport class FastifyServer extends Server<FastifyRequest, FastifyReply> {\n\tconstructor(config: ServerConfig) {\n\t\tconst instance = Instance.get()\n\t\tconst app = Fastify({\n\t\t\tdisableRequestLogging: !config.requests.log,\n\t\t\tloggerInstance: config.requests.log ? instance.log : undefined,\n\t\t\tajv: { customOptions: { coerceTypes: false } },\n\t\t\trouterOptions: {\n\t\t\t\tignoreTrailingSlash: true,\n\t\t\t\tcaseSensitive: false,\n\t\t\t},\n\t\t\tschemaErrorFormatter: (errors, data) =>\n\t\t\t\tnew ValidationError(\n\t\t\t\t\terrors.map((error) => ({\n\t\t\t\t\t\tmessages: [error.message ?? ''],\n\t\t\t\t\t\tfield: `${data}${error.instancePath}`.replaceAll('/', '.'),\n\t\t\t\t\t})),\n\t\t\t\t),\n\t\t})\n\t\tsuper(app.server, config, {\n\t\t\tparseRequest: async (req) => {\n\t\t\t\tconst allHeaders = Object.fromEntries(Object.entries(req.headers).map(([key, val]) => [key, val ?? null]))\n\t\t\t\tconst headers = {\n\t\t\t\t\t...allHeaders,\n\t\t\t\t\tAuthorization: req.headers['authorization']?.toString(),\n\t\t\t\t\tRefreshToken: req.headers['x-refresh-token']?.toString(),\n\t\t\t\t\tApiKey: req.headers['x-api-key']?.toString(),\n\t\t\t\t\tContentType: req.headers['content-type']?.toString(),\n\t\t\t\t\tReferer: req.headers['referer']?.toString(),\n\t\t\t\t\tUserAgent: req.headers['user-agent']?.toString(),\n\t\t\t\t}\n\t\t\t\tconst { body, files } = excludeBufferKeys(req.body ?? {})\n\n\t\t\t\treturn new Request({\n\t\t\t\t\tip: req.ip,\n\t\t\t\t\tbody,\n\t\t\t\t\tcookies: req.cookies ?? {},\n\t\t\t\t\tparams: req.params ?? <any>{},\n\t\t\t\t\tquery: req.query ?? {},\n\t\t\t\t\tmethod: <any>req.method,\n\t\t\t\t\tpath: req.url,\n\t\t\t\t\theaders,\n\t\t\t\t\tfiles,\n\t\t\t\t\tcontext: {},\n\t\t\t\t})\n\t\t\t},\n\t\t\thandleResponse: async (res, response) => {\n\t\t\t\tfor (const [key, { value, ...opts }] of Object.entries(response.cookies)) res = res.setCookie(key, value, opts)\n\t\t\t\tawait res.status(response.status).headers(response.headers).send(response.body)\n\t\t\t},\n\t\t\tregisterRoute: (method, path, cb) => {\n\t\t\t\tapp.register(async (inst) => {\n\t\t\t\t\tinst.route({ url: path, method, handler: cb })\n\t\t\t\t})\n\t\t\t},\n\t\t\tregisterErrorHandler: (cb) => {\n\t\t\t\tapp.setErrorHandler(cb)\n\t\t\t},\n\t\t\tregisterNotFoundHandler: (cb) => {\n\t\t\t\tapp.setNotFoundHandler(cb)\n\t\t\t},\n\t\t\tstart: async (port) => {\n\t\t\t\tawait app.ready()\n\t\t\t\tawait app.listen({ port, host: '0.0.0.0' })\n\t\t\t\tInstance.on('close', app.close, 1)\n\t\t\t\treturn true\n\t\t\t},\n\t\t})\n\n\t\tapp.decorateRequest('savedReq', null)\n\t\tapp.setValidatorCompiler(() => () => true)\n\t\tapp.setSerializerCompiler(() => (data) => JSON.stringify(data))\n\t\tif (config.publicPath) app.register(fastifyStatic, { root: config.publicPath })\n\t\tapp.register(fastifyCookie, {})\n\t\tapp.register(fastifyCors, this.cors)\n\t\tapp.register(fastifyFormBody, { parser: (str) => qs.parse(str) })\n\t\tapp.register(fastifyHelmet, { crossOriginResourcePolicy: { policy: 'cross-origin' }, contentSecurityPolicy: false })\n\t\tapp.register(fastifyMultipart, {\n\t\t\tattachFieldsToBody: 'keyValues',\n\t\t\tthrowFileSizeLimit: false,\n\t\t\tlimits: { fileSize: instance.settings.utils.maxFileUploadSizeInMb * 1024 * 1024 },\n\t\t\tonFile: async (f) => {\n\t\t\t\tconst buffer = await f.toBuffer()\n\t\t\t\tconst parsed: IncomingFile = {\n\t\t\t\t\tname: f.filename,\n\t\t\t\t\ttype: f.mimetype,\n\t\t\t\t\tsize: buffer.byteLength,\n\t\t\t\t\tisTruncated: f.file.truncated,\n\t\t\t\t\tdata: buffer,\n\t\t\t\t\tduration: await getMediaDuration(buffer),\n\t\t\t\t}\n\t\t\t\t// @ts-ignore\n\t\t\t\tf.value = parsed\n\t\t\t},\n\t\t})\n\t\t/* if (this.settings.slowdown.enabled) app.register(fastifySlowDown, {\n\t\t\ttimeWindow: this.settings.slowdown.periodInMs,\n\t\t\tdelayAfter: this.settings.slowdown.delayAfter,\n\t\t\tdelay: this.settings.slowdown.delayInMs\n\t\t}) */\n\t\tif (config.requests.rateLimit.enabled)\n\t\t\tapp.register(fastifyRateLimit, {\n\t\t\t\tmax: config.requests.rateLimit.limit,\n\t\t\t\ttimeWindow: config.requests.rateLimit.periodInMs,\n\t\t\t\terrorResponseBuilder: (_, context) => ({\n\t\t\t\t\tstatusCode: StatusCodes.TooManyRequests,\n\t\t\t\t\tmessage: JSON.stringify([{ message: `Too Many Requests. Retry in ${context.after}` }]),\n\t\t\t\t}),\n\t\t\t})\n\t}\n}\n\nfunction excludeBufferKeys<T>(body: T) {\n\tif (typeof body !== 'object') return { body, files: {} }\n\tconst entries = Object.entries(body ?? {})\n\tconst isFile = (val: any) => (Array.isArray(val) ? isFile(val.at(0)) : Buffer.isBuffer(val?.data))\n\tconst fileEntries = entries.filter(([_, value]) => isFile(value)).map(([key, value]) => [key, Array.isArray(value) ? value : [value]])\n\tconst nonFileEntries = entries.filter(([_, value]) => !isFile(value))\n\treturn {\n\t\tbody: <T>Object.fromEntries(nonFileEntries),\n\t\tfiles: <Record<string, IncomingFile[]>>Object.fromEntries(fileEntries),\n\t}\n}\n"],"mappings":"AAAA,OAAOA,MAAmB,kBAC1B,OAAOC,MAAiB,gBACxB,OAAOC,MAAqB,oBAC5B,OAAOC,MAAmB,kBAC1B,OAAOC,MAAsB,qBAC7B,OAAOC,MAAsB,sBAC7B,OAAOC,MAAmB,kBAE1B,OAAOC,MAAa,UAEpB,OAAOC,MAAQ,KAEf,OAAS,mBAAAC,MAAuB,eAChC,OAAS,YAAAC,MAAgB,iBACzB,OAAS,oBAAAC,MAAwB,kBAEjC,OAAS,WAAAC,MAAe,cACxB,OAA4B,eAAAC,MAAmB,WAC/C,OAAS,UAAAC,MAAc,SAEhB,MAAMC,UAAsBD,CAAqC,CACvE,YAAYE,EAAsB,CACjC,MAAMC,EAAWP,EAAS,IAAI,EACxBQ,EAAMX,EAAQ,CACnB,sBAAuB,CAACS,EAAO,SAAS,IACxC,eAAgBA,EAAO,SAAS,IAAMC,EAAS,IAAM,OACrD,IAAK,CAAE,cAAe,CAAE,YAAa,EAAM,CAAE,EAC7C,cAAe,CACd,oBAAqB,GACrB,cAAe,EAChB,EACA,qBAAsB,CAACE,EAAQC,IAC9B,IAAIX,EACHU,EAAO,IAAKE,IAAW,CACtB,SAAU,CAACA,EAAM,SAAW,EAAE,EAC9B,MAAO,GAAGD,CAAI,GAAGC,EAAM,YAAY,GAAG,WAAW,IAAK,GAAG,CAC1D,EAAE,CACH,CACF,CAAC,EACD,MAAMH,EAAI,OAAQF,EAAQ,CACzB,aAAc,MAAOM,GAAQ,CAE5B,MAAMC,EAAU,CACf,GAFkB,OAAO,YAAY,OAAO,QAAQD,EAAI,OAAO,EAAE,IAAI,CAAC,CAACE,EAAKC,CAAG,IAAM,CAACD,EAAKC,GAAO,IAAI,CAAC,CAAC,EAGxG,cAAeH,EAAI,QAAQ,eAAkB,SAAS,EACtD,aAAcA,EAAI,QAAQ,iBAAiB,GAAG,SAAS,EACvD,OAAQA,EAAI,QAAQ,WAAW,GAAG,SAAS,EAC3C,YAAaA,EAAI,QAAQ,cAAc,GAAG,SAAS,EACnD,QAASA,EAAI,QAAQ,SAAY,SAAS,EAC1C,UAAWA,EAAI,QAAQ,YAAY,GAAG,SAAS,CAChD,EACM,CAAE,KAAAI,EAAM,MAAAC,CAAM,EAAIC,EAAkBN,EAAI,MAAQ,CAAC,CAAC,EAExD,OAAO,IAAIV,EAAQ,CAClB,GAAIU,EAAI,GACR,KAAAI,EACA,QAASJ,EAAI,SAAW,CAAC,EACzB,OAAQA,EAAI,QAAe,CAAC,EAC5B,MAAOA,EAAI,OAAS,CAAC,EACrB,OAAaA,EAAI,OACjB,KAAMA,EAAI,IACV,QAAAC,EACA,MAAAI,EACA,QAAS,CAAC,CACX,CAAC,CACF,EACA,eAAgB,MAAOE,EAAKC,IAAa,CACxC,SAAW,CAACN,EAAK,CAAE,MAAAO,EAAO,GAAGC,CAAK,CAAC,IAAK,OAAO,QAAQF,EAAS,OAAO,EAAGD,EAAMA,EAAI,UAAUL,EAAKO,EAAOC,CAAI,EAC9G,MAAMH,EAAI,OAAOC,EAAS,MAAM,EAAE,QAAQA,EAAS,OAAO,EAAE,KAAKA,EAAS,IAAI,CAC/E,EACA,cAAe,CAACG,EAAQC,EAAMC,IAAO,CACpCjB,EAAI,SAAS,MAAOkB,GAAS,CAC5BA,EAAK,MAAM,CAAE,IAAKF,EAAM,OAAAD,EAAQ,QAASE,CAAG,CAAC,CAC9C,CAAC,CACF,EACA,qBAAuBA,GAAO,CAC7BjB,EAAI,gBAAgBiB,CAAE,CACvB,EACA,wBAA0BA,GAAO,CAChCjB,EAAI,mBAAmBiB,CAAE,CAC1B,EACA,MAAO,MAAOE,IACb,MAAMnB,EAAI,MAAM,EAChB,MAAMA,EAAI,OAAO,CAAE,KAAAmB,EAAM,KAAM,SAAU,CAAC,EAC1C3B,EAAS,GAAG,QAASQ,EAAI,MAAO,CAAC,EAC1B,GAET,CAAC,EAEDA,EAAI,gBAAgB,WAAY,IAAI,EACpCA,EAAI,qBAAqB,IAAM,IAAM,EAAI,EACzCA,EAAI,sBAAsB,IAAOE,GAAS,KAAK,UAAUA,CAAI,CAAC,EAC1DJ,EAAO,YAAYE,EAAI,SAASZ,EAAe,CAAE,KAAMU,EAAO,UAAW,CAAC,EAC9EE,EAAI,SAASlB,EAAe,CAAC,CAAC,EAC9BkB,EAAI,SAASjB,EAAa,KAAK,IAAI,EACnCiB,EAAI,SAAShB,EAAiB,CAAE,OAASoC,GAAQ9B,EAAG,MAAM8B,CAAG,CAAE,CAAC,EAChEpB,EAAI,SAASf,EAAe,CAAE,0BAA2B,CAAE,OAAQ,cAAe,EAAG,sBAAuB,EAAM,CAAC,EACnHe,EAAI,SAASd,EAAkB,CAC9B,mBAAoB,YACpB,mBAAoB,GACpB,OAAQ,CAAE,SAAUa,EAAS,SAAS,MAAM,sBAAwB,KAAO,IAAK,EAChF,OAAQ,MAAOsB,GAAM,CACpB,MAAMC,EAAS,MAAMD,EAAE,SAAS,EAC1BE,EAAuB,CAC5B,KAAMF,EAAE,SACR,KAAMA,EAAE,SACR,KAAMC,EAAO,WACb,YAAaD,EAAE,KAAK,UACpB,KAAMC,EACN,SAAU,MAAM7B,EAAiB6B,CAAM,CACxC,EAEAD,EAAE,MAAQE,CACX,CACD,CAAC,EAMGzB,EAAO,SAAS,UAAU,SAC7BE,EAAI,SAASb,EAAkB,CAC9B,IAAKW,EAAO,SAAS,UAAU,MAC/B,WAAYA,EAAO,SAAS,UAAU,WACtC,qBAAsB,CAAC0B,EAAGC,KAAa,CACtC,WAAY9B,EAAY,gBACxB,QAAS,KAAK,UAAU,CAAC,CAAE,QAAS,+BAA+B8B,EAAQ,KAAK,EAAG,CAAC,CAAC,CACtF,EACD,CAAC,CACH,CACD,CAEA,SAASf,EAAqBF,EAAS,CACtC,GAAI,OAAOA,GAAS,SAAU,MAAO,CAAE,KAAAA,EAAM,MAAO,CAAC,CAAE,EACvD,MAAMkB,EAAU,OAAO,QAAQlB,GAAQ,CAAC,CAAC,EACnCmB,EAAUpB,GAAc,MAAM,QAAQA,CAAG,EAAIoB,EAAOpB,EAAI,GAAG,CAAC,CAAC,EAAI,OAAO,SAASA,GAAK,IAAI,EAC1FqB,EAAcF,EAAQ,OAAO,CAAC,CAACF,EAAGX,CAAK,IAAMc,EAAOd,CAAK,CAAC,EAAE,IAAI,CAAC,CAACP,EAAKO,CAAK,IAAM,CAACP,EAAK,MAAM,QAAQO,CAAK,EAAIA,EAAQ,CAACA,CAAK,CAAC,CAAC,EAC/HgB,EAAiBH,EAAQ,OAAO,CAAC,CAACF,EAAGX,CAAK,IAAM,CAACc,EAAOd,CAAK,CAAC,EACpE,MAAO,CACN,KAAS,OAAO,YAAYgB,CAAc,EAC1C,MAAuC,OAAO,YAAYD,CAAW,CACtE,CACD","names":["fastifyCookie","fastifyCors","fastifyFormBody","fastifyHelmet","fastifyMultipart","fastifyRateLimit","fastifyStatic","Fastify","qs","ValidationError","Instance","getMediaDuration","Request","StatusCodes","Server","FastifyServer","config","instance","app","errors","data","error","req","headers","key","val","body","files","excludeBufferKeys","res","response","value","opts","method","path","cb","inst","port","str","f","buffer","parsed","_","context","entries","isFile","fileEntries","nonFileEntries"]}
1
+ {"version":3,"sources":["../../../../src/server/impls/fastify.ts"],"sourcesContent":["import fastifyCookie from '@fastify/cookie'\nimport fastifyCors from '@fastify/cors'\nimport fastifyFormBody from '@fastify/formbody'\nimport fastifyHelmet from '@fastify/helmet'\nimport fastifyMultipart from '@fastify/multipart'\nimport fastifyRateLimit from '@fastify/rate-limit'\nimport fastifyStatic from '@fastify/static'\nimport type { FastifyReply, FastifyRequest } from 'fastify'\nimport Fastify from 'fastify'\n// import fastifySlowDown from 'fastify-slow-down'\nimport qs from 'qs'\n\nimport { ValidationError } from '../../errors'\nimport { Instance } from '../../instance'\nimport { getMediaDuration } from '../../utilities'\nimport type { ServerConfig } from '../pipes'\nimport { Request } from '../requests'\nimport { type IncomingFile, StatusCodes } from '../types'\nimport { Server } from './base'\n\nexport class FastifyServer extends Server<FastifyRequest, FastifyReply> {\n\tconstructor(config: ServerConfig) {\n\t\tconst instance = Instance.get()\n\t\tconst app = Fastify({\n\t\t\tdisableRequestLogging: !config.requests.log,\n\t\t\tloggerInstance: config.requests.log ? instance.log : undefined,\n\t\t\tajv: { customOptions: { coerceTypes: false } },\n\t\t\trouterOptions: {\n\t\t\t\tignoreTrailingSlash: true,\n\t\t\t\tcaseSensitive: false,\n\t\t\t},\n\t\t\tschemaErrorFormatter: (errors, data) =>\n\t\t\t\tnew ValidationError(\n\t\t\t\t\terrors.map((error) => ({\n\t\t\t\t\t\tmessages: [error.message ?? ''],\n\t\t\t\t\t\tfield: `${data}${error.instancePath}`.replaceAll('/', '.'),\n\t\t\t\t\t})),\n\t\t\t\t),\n\t\t})\n\t\tsuper(app.server, config, {\n\t\t\tparseRequest: async (req) => {\n\t\t\t\tconst { body, files } = excludeBufferKeys(req.body ?? {})\n\n\t\t\t\treturn new Request({\n\t\t\t\t\tip: req.ip,\n\t\t\t\t\tbody,\n\t\t\t\t\tcookies: req.cookies ?? {},\n\t\t\t\t\tparams: req.params ?? <any>{},\n\t\t\t\t\tquery: req.query ?? {},\n\t\t\t\t\tmethod: <any>req.method,\n\t\t\t\t\tpath: req.url,\n\t\t\t\t\theaders: req.headers,\n\t\t\t\t\tfiles,\n\t\t\t\t})\n\t\t\t},\n\t\t\thandleResponse: async (res, response) => {\n\t\t\t\tfor (const [key, { value, ...opts }] of Object.entries(response.cookies)) res = res.setCookie(key, value, opts)\n\t\t\t\tawait res.status(response.status).headers(response.headers).send(response.body)\n\t\t\t},\n\t\t\tregisterRoute: (method, path, cb) => {\n\t\t\t\tapp.register(async (inst) => {\n\t\t\t\t\tinst.route({ url: path, method, handler: cb })\n\t\t\t\t})\n\t\t\t},\n\t\t\tregisterErrorHandler: (cb) => {\n\t\t\t\tapp.setErrorHandler(cb)\n\t\t\t},\n\t\t\tregisterNotFoundHandler: (cb) => {\n\t\t\t\tapp.setNotFoundHandler(cb)\n\t\t\t},\n\t\t\tstart: async (port) => {\n\t\t\t\tawait app.ready()\n\t\t\t\tawait app.listen({ port, host: '0.0.0.0' })\n\t\t\t\tInstance.on('close', app.close, 1)\n\t\t\t\treturn true\n\t\t\t},\n\t\t})\n\n\t\tapp.decorateRequest('savedReq', null)\n\t\tapp.setValidatorCompiler(() => () => true)\n\t\tapp.setSerializerCompiler(() => (data) => JSON.stringify(data))\n\t\tif (config.publicPath) app.register(fastifyStatic, { root: config.publicPath })\n\t\tapp.register(fastifyCookie, {})\n\t\tapp.register(fastifyCors, this.cors)\n\t\tapp.register(fastifyFormBody, { parser: (str) => qs.parse(str) })\n\t\tapp.register(fastifyHelmet, { crossOriginResourcePolicy: { policy: 'cross-origin' }, contentSecurityPolicy: false })\n\t\tapp.register(fastifyMultipart, {\n\t\t\tattachFieldsToBody: 'keyValues',\n\t\t\tthrowFileSizeLimit: false,\n\t\t\tlimits: { fileSize: instance.settings.utils.maxFileUploadSizeInMb * 1024 * 1024 },\n\t\t\tonFile: async (f) => {\n\t\t\t\tconst buffer = await f.toBuffer()\n\t\t\t\tconst parsed: IncomingFile = {\n\t\t\t\t\tname: f.filename,\n\t\t\t\t\ttype: f.mimetype,\n\t\t\t\t\tsize: buffer.byteLength,\n\t\t\t\t\tisTruncated: f.file.truncated,\n\t\t\t\t\tdata: buffer,\n\t\t\t\t\tduration: await getMediaDuration(buffer),\n\t\t\t\t}\n\t\t\t\t// @ts-ignore\n\t\t\t\tf.value = parsed\n\t\t\t},\n\t\t})\n\t\t/* if (this.settings.slowdown.enabled) app.register(fastifySlowDown, {\n\t\t\ttimeWindow: this.settings.slowdown.periodInMs,\n\t\t\tdelayAfter: this.settings.slowdown.delayAfter,\n\t\t\tdelay: this.settings.slowdown.delayInMs\n\t\t}) */\n\t\tif (config.requests.rateLimit.enabled)\n\t\t\tapp.register(fastifyRateLimit, {\n\t\t\t\tmax: config.requests.rateLimit.limit,\n\t\t\t\ttimeWindow: config.requests.rateLimit.periodInMs,\n\t\t\t\terrorResponseBuilder: (_, context) => ({\n\t\t\t\t\tstatusCode: StatusCodes.TooManyRequests,\n\t\t\t\t\tmessage: JSON.stringify([{ message: `Too Many Requests. Retry in ${context.after}` }]),\n\t\t\t\t}),\n\t\t\t})\n\t}\n}\n\nfunction excludeBufferKeys<T>(body: T) {\n\tif (typeof body !== 'object') return { body, files: {} }\n\tconst entries = Object.entries(body ?? {})\n\tconst isFile = (val: any) => (Array.isArray(val) ? isFile(val.at(0)) : Buffer.isBuffer(val?.data))\n\tconst fileEntries = entries.filter(([_, value]) => isFile(value)).map(([key, value]) => [key, Array.isArray(value) ? value : [value]])\n\tconst nonFileEntries = entries.filter(([_, value]) => !isFile(value))\n\treturn {\n\t\tbody: <T>Object.fromEntries(nonFileEntries),\n\t\tfiles: <Record<string, IncomingFile[]>>Object.fromEntries(fileEntries),\n\t}\n}\n"],"mappings":"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","names":["fastifyCookie","fastifyCors","fastifyFormBody","fastifyHelmet","fastifyMultipart","fastifyRateLimit","fastifyStatic","Fastify","qs","ValidationError","Instance","getMediaDuration","Request","StatusCodes","Server","FastifyServer","config","instance","app","errors","data","error","req","body","files","excludeBufferKeys","res","response","key","value","opts","method","path","cb","inst","port","str","f","buffer","parsed","_","context","entries","isFile","val","fileEntries","nonFileEntries"]}
@@ -33,16 +33,6 @@ class FastifyServer extends Server {
33
33
  });
34
34
  super(app.server, config, {
35
35
  parseRequest: async (req) => {
36
- const allHeaders = Object.fromEntries(Object.entries(req.headers).map(([key, val]) => [key, val ?? null]));
37
- const headers = {
38
- ...allHeaders,
39
- Authorization: req.headers["authorization"]?.toString(),
40
- RefreshToken: req.headers["x-refresh-token"]?.toString(),
41
- ApiKey: req.headers["x-api-key"]?.toString(),
42
- ContentType: req.headers["content-type"]?.toString(),
43
- Referer: req.headers["referer"]?.toString(),
44
- UserAgent: req.headers["user-agent"]?.toString()
45
- };
46
36
  const { body, files } = excludeBufferKeys(req.body ?? {});
47
37
  return new Request({
48
38
  ip: req.ip,
@@ -52,9 +42,8 @@ class FastifyServer extends Server {
52
42
  query: req.query ?? {},
53
43
  method: req.method,
54
44
  path: req.url,
55
- headers,
56
- files,
57
- context: {}
45
+ headers: req.headers,
46
+ files
58
47
  });
59
48
  },
60
49
  handleResponse: async (res, response) => {