@signal24/dk-server-foundation 26.213.615

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 (666) hide show
  1. package/.gitattributes +2 -0
  2. package/.gitlab-ci.yml +49 -0
  3. package/.oxlintrc.json +40 -0
  4. package/.prettierignore +3 -0
  5. package/.prettierrc.json +15 -0
  6. package/.serena/project.yml +111 -0
  7. package/.vscode/launch.json +15 -0
  8. package/.vscode/settings.json +12 -0
  9. package/.yarnrc.yml +5 -0
  10. package/CLAUDE.md +279 -0
  11. package/LICENSE +21 -0
  12. package/README.md +439 -0
  13. package/TEST_MIGRATION_GUIDE.md +348 -0
  14. package/dist/resources/proto/generated/test/test.d.ts +224 -0
  15. package/dist/resources/proto/generated/test/test.d.ts.map +1 -0
  16. package/dist/resources/proto/generated/test/test.js +2376 -0
  17. package/dist/resources/proto/generated/test/test.js.map +1 -0
  18. package/dist/src/app/base.d.ts +37 -0
  19. package/dist/src/app/base.d.ts.map +1 -0
  20. package/dist/src/app/base.js +244 -0
  21. package/dist/src/app/base.js.map +1 -0
  22. package/dist/src/app/config.d.ts +91 -0
  23. package/dist/src/app/config.d.ts.map +1 -0
  24. package/dist/src/app/config.js +33 -0
  25. package/dist/src/app/config.js.map +1 -0
  26. package/dist/src/app/config.loader.d.ts +14 -0
  27. package/dist/src/app/config.loader.d.ts.map +1 -0
  28. package/dist/src/app/config.loader.js +67 -0
  29. package/dist/src/app/config.loader.js.map +1 -0
  30. package/dist/src/app/const.d.ts +3 -0
  31. package/dist/src/app/const.d.ts.map +1 -0
  32. package/dist/src/app/const.js +6 -0
  33. package/dist/src/app/const.js.map +1 -0
  34. package/dist/src/app/dev.d.ts +6 -0
  35. package/dist/src/app/dev.d.ts.map +1 -0
  36. package/dist/src/app/dev.js +78 -0
  37. package/dist/src/app/dev.js.map +1 -0
  38. package/dist/src/app/index.d.ts +7 -0
  39. package/dist/src/app/index.d.ts.map +1 -0
  40. package/dist/src/app/index.js +12 -0
  41. package/dist/src/app/index.js.map +1 -0
  42. package/dist/src/app/openapi.d.ts +4 -0
  43. package/dist/src/app/openapi.d.ts.map +1 -0
  44. package/dist/src/app/openapi.js +6 -0
  45. package/dist/src/app/openapi.js.map +1 -0
  46. package/dist/src/app/resolver.d.ts +11 -0
  47. package/dist/src/app/resolver.d.ts.map +1 -0
  48. package/dist/src/app/resolver.js +60 -0
  49. package/dist/src/app/resolver.js.map +1 -0
  50. package/dist/src/app/shutdown.d.ts +12 -0
  51. package/dist/src/app/shutdown.d.ts.map +1 -0
  52. package/dist/src/app/shutdown.js +63 -0
  53. package/dist/src/app/shutdown.js.map +1 -0
  54. package/dist/src/app/state.d.ts +16 -0
  55. package/dist/src/app/state.d.ts.map +1 -0
  56. package/dist/src/app/state.js +12 -0
  57. package/dist/src/app/state.js.map +1 -0
  58. package/dist/src/auth/index.d.ts +3 -0
  59. package/dist/src/auth/index.d.ts.map +1 -0
  60. package/dist/src/auth/index.js +6 -0
  61. package/dist/src/auth/index.js.map +1 -0
  62. package/dist/src/auth/jwt.d.ts +76 -0
  63. package/dist/src/auth/jwt.d.ts.map +1 -0
  64. package/dist/src/auth/jwt.js +218 -0
  65. package/dist/src/auth/jwt.js.map +1 -0
  66. package/dist/src/auth/provider.d.ts +15 -0
  67. package/dist/src/auth/provider.d.ts.map +1 -0
  68. package/dist/src/auth/provider.js +50 -0
  69. package/dist/src/auth/provider.js.map +1 -0
  70. package/dist/src/cli/dksf-dev.d.ts +3 -0
  71. package/dist/src/cli/dksf-dev.d.ts.map +1 -0
  72. package/dist/src/cli/dksf-dev.js +359 -0
  73. package/dist/src/cli/dksf-dev.js.map +1 -0
  74. package/dist/src/cli/dksf-gen-proto.d.ts +3 -0
  75. package/dist/src/cli/dksf-gen-proto.d.ts.map +1 -0
  76. package/dist/src/cli/dksf-gen-proto.js +164 -0
  77. package/dist/src/cli/dksf-gen-proto.js.map +1 -0
  78. package/dist/src/cli/dksf-install.d.ts +3 -0
  79. package/dist/src/cli/dksf-install.d.ts.map +1 -0
  80. package/dist/src/cli/dksf-install.js +10 -0
  81. package/dist/src/cli/dksf-install.js.map +1 -0
  82. package/dist/src/cli/dksf-test.d.ts +3 -0
  83. package/dist/src/cli/dksf-test.d.ts.map +1 -0
  84. package/dist/src/cli/dksf-test.js +91 -0
  85. package/dist/src/cli/dksf-test.js.map +1 -0
  86. package/dist/src/cli/dksf-update.d.ts +3 -0
  87. package/dist/src/cli/dksf-update.d.ts.map +1 -0
  88. package/dist/src/cli/dksf-update.js +86 -0
  89. package/dist/src/cli/dksf-update.js.map +1 -0
  90. package/dist/src/database/common.d.ts +84 -0
  91. package/dist/src/database/common.d.ts.map +1 -0
  92. package/dist/src/database/common.js +380 -0
  93. package/dist/src/database/common.js.map +1 -0
  94. package/dist/src/database/dialect.d.ts +10 -0
  95. package/dist/src/database/dialect.d.ts.map +1 -0
  96. package/dist/src/database/dialect.js +56 -0
  97. package/dist/src/database/dialect.js.map +1 -0
  98. package/dist/src/database/entity.d.ts +62 -0
  99. package/dist/src/database/entity.d.ts.map +1 -0
  100. package/dist/src/database/entity.js +198 -0
  101. package/dist/src/database/entity.js.map +1 -0
  102. package/dist/src/database/index.d.ts +8 -0
  103. package/dist/src/database/index.d.ts.map +1 -0
  104. package/dist/src/database/index.js +15 -0
  105. package/dist/src/database/index.js.map +1 -0
  106. package/dist/src/database/migration/MigrationResetCommand.d.ts +11 -0
  107. package/dist/src/database/migration/MigrationResetCommand.d.ts.map +1 -0
  108. package/dist/src/database/migration/MigrationResetCommand.js +149 -0
  109. package/dist/src/database/migration/MigrationResetCommand.js.map +1 -0
  110. package/dist/src/database/migration/MigrationRunCommand.d.ts +11 -0
  111. package/dist/src/database/migration/MigrationRunCommand.d.ts.map +1 -0
  112. package/dist/src/database/migration/MigrationRunCommand.js +118 -0
  113. package/dist/src/database/migration/MigrationRunCommand.js.map +1 -0
  114. package/dist/src/database/migration/characters.d.ts +14 -0
  115. package/dist/src/database/migration/characters.d.ts.map +1 -0
  116. package/dist/src/database/migration/characters.js +56 -0
  117. package/dist/src/database/migration/characters.js.map +1 -0
  118. package/dist/src/database/migration/create/MigrationCreateCommand.d.ts +11 -0
  119. package/dist/src/database/migration/create/MigrationCreateCommand.d.ts.map +1 -0
  120. package/dist/src/database/migration/create/MigrationCreateCommand.js +104 -0
  121. package/dist/src/database/migration/create/MigrationCreateCommand.js.map +1 -0
  122. package/dist/src/database/migration/create/comparator.d.ts +3 -0
  123. package/dist/src/database/migration/create/comparator.d.ts.map +1 -0
  124. package/dist/src/database/migration/create/comparator.js +408 -0
  125. package/dist/src/database/migration/create/comparator.js.map +1 -0
  126. package/dist/src/database/migration/create/db-reader.d.ts +5 -0
  127. package/dist/src/database/migration/create/db-reader.d.ts.map +1 -0
  128. package/dist/src/database/migration/create/db-reader.js +473 -0
  129. package/dist/src/database/migration/create/db-reader.js.map +1 -0
  130. package/dist/src/database/migration/create/ddl-generator.d.ts +3 -0
  131. package/dist/src/database/migration/create/ddl-generator.d.ts.map +1 -0
  132. package/dist/src/database/migration/create/ddl-generator.js +725 -0
  133. package/dist/src/database/migration/create/ddl-generator.js.map +1 -0
  134. package/dist/src/database/migration/create/entity-reader.d.ts +4 -0
  135. package/dist/src/database/migration/create/entity-reader.d.ts.map +1 -0
  136. package/dist/src/database/migration/create/entity-reader.js +408 -0
  137. package/dist/src/database/migration/create/entity-reader.js.map +1 -0
  138. package/dist/src/database/migration/create/file-generator.d.ts +2 -0
  139. package/dist/src/database/migration/create/file-generator.d.ts.map +1 -0
  140. package/dist/src/database/migration/create/file-generator.js +55 -0
  141. package/dist/src/database/migration/create/file-generator.js.map +1 -0
  142. package/dist/src/database/migration/create/prompt.d.ts +4 -0
  143. package/dist/src/database/migration/create/prompt.d.ts.map +1 -0
  144. package/dist/src/database/migration/create/prompt.js +55 -0
  145. package/dist/src/database/migration/create/prompt.js.map +1 -0
  146. package/dist/src/database/migration/create/schema-model.d.ts +109 -0
  147. package/dist/src/database/migration/create/schema-model.d.ts.map +1 -0
  148. package/dist/src/database/migration/create/schema-model.js +24 -0
  149. package/dist/src/database/migration/create/schema-model.js.map +1 -0
  150. package/dist/src/database/migration/helpers.d.ts +2 -0
  151. package/dist/src/database/migration/helpers.d.ts.map +1 -0
  152. package/dist/src/database/migration/helpers.js +8 -0
  153. package/dist/src/database/migration/helpers.js.map +1 -0
  154. package/dist/src/database/migration/index.d.ts +9 -0
  155. package/dist/src/database/migration/index.d.ts.map +1 -0
  156. package/dist/src/database/migration/index.js +43 -0
  157. package/dist/src/database/migration/index.js.map +1 -0
  158. package/dist/src/database/migration/migration.entity.d.ts +8 -0
  159. package/dist/src/database/migration/migration.entity.d.ts.map +1 -0
  160. package/dist/src/database/migration/migration.entity.js +16 -0
  161. package/dist/src/database/migration/migration.entity.js.map +1 -0
  162. package/dist/src/database/mysql.d.ts +16 -0
  163. package/dist/src/database/mysql.d.ts.map +1 -0
  164. package/dist/src/database/mysql.js +140 -0
  165. package/dist/src/database/mysql.js.map +1 -0
  166. package/dist/src/database/postgres.d.ts +16 -0
  167. package/dist/src/database/postgres.d.ts.map +1 -0
  168. package/dist/src/database/postgres.js +91 -0
  169. package/dist/src/database/postgres.js.map +1 -0
  170. package/dist/src/database/types.d.ts +21 -0
  171. package/dist/src/database/types.d.ts.map +1 -0
  172. package/dist/src/database/types.js +27 -0
  173. package/dist/src/database/types.js.map +1 -0
  174. package/dist/src/health/health.module.d.ts +6 -0
  175. package/dist/src/health/health.module.d.ts.map +1 -0
  176. package/dist/src/health/health.module.js +32 -0
  177. package/dist/src/health/health.module.js.map +1 -0
  178. package/dist/src/health/healthcheck.controller.d.ts +10 -0
  179. package/dist/src/health/healthcheck.controller.d.ts.map +1 -0
  180. package/dist/src/health/healthcheck.controller.js +30 -0
  181. package/dist/src/health/healthcheck.controller.js.map +1 -0
  182. package/dist/src/health/healthcheck.service.d.ts +8 -0
  183. package/dist/src/health/healthcheck.service.d.ts.map +1 -0
  184. package/dist/src/health/healthcheck.service.js +20 -0
  185. package/dist/src/health/healthcheck.service.js.map +1 -0
  186. package/dist/src/health/index.d.ts +3 -0
  187. package/dist/src/health/index.d.ts.map +1 -0
  188. package/dist/src/health/index.js +6 -0
  189. package/dist/src/health/index.js.map +1 -0
  190. package/dist/src/helpers/async/context.d.ts +11 -0
  191. package/dist/src/helpers/async/context.d.ts.map +1 -0
  192. package/dist/src/helpers/async/context.js +75 -0
  193. package/dist/src/helpers/async/context.js.map +1 -0
  194. package/dist/src/helpers/async/process.d.ts +16 -0
  195. package/dist/src/helpers/async/process.d.ts.map +1 -0
  196. package/dist/src/helpers/async/process.js +44 -0
  197. package/dist/src/helpers/async/process.js.map +1 -0
  198. package/dist/src/helpers/async/promise.d.ts +5 -0
  199. package/dist/src/helpers/async/promise.d.ts.map +1 -0
  200. package/dist/src/helpers/async/promise.js +27 -0
  201. package/dist/src/helpers/async/promise.js.map +1 -0
  202. package/dist/src/helpers/data/array.d.ts +3 -0
  203. package/dist/src/helpers/data/array.d.ts.map +1 -0
  204. package/dist/src/helpers/data/array.js +17 -0
  205. package/dist/src/helpers/data/array.js.map +1 -0
  206. package/dist/src/helpers/data/objects.d.ts +12 -0
  207. package/dist/src/helpers/data/objects.d.ts.map +1 -0
  208. package/dist/src/helpers/data/objects.js +75 -0
  209. package/dist/src/helpers/data/objects.js.map +1 -0
  210. package/dist/src/helpers/data/serialization.d.ts +4 -0
  211. package/dist/src/helpers/data/serialization.d.ts.map +1 -0
  212. package/dist/src/helpers/data/serialization.js +15 -0
  213. package/dist/src/helpers/data/serialization.js.map +1 -0
  214. package/dist/src/helpers/data/transformer.d.ts +13 -0
  215. package/dist/src/helpers/data/transformer.d.ts.map +1 -0
  216. package/dist/src/helpers/data/transformer.js +55 -0
  217. package/dist/src/helpers/data/transformer.js.map +1 -0
  218. package/dist/src/helpers/framework/decorators.d.ts +5 -0
  219. package/dist/src/helpers/framework/decorators.d.ts.map +1 -0
  220. package/dist/src/helpers/framework/decorators.js +39 -0
  221. package/dist/src/helpers/framework/decorators.js.map +1 -0
  222. package/dist/src/helpers/framework/event.d.ts +3 -0
  223. package/dist/src/helpers/framework/event.d.ts.map +1 -0
  224. package/dist/src/helpers/framework/event.js +20 -0
  225. package/dist/src/helpers/framework/event.js.map +1 -0
  226. package/dist/src/helpers/framework/injection.d.ts +7 -0
  227. package/dist/src/helpers/framework/injection.d.ts.map +1 -0
  228. package/dist/src/helpers/framework/injection.js +52 -0
  229. package/dist/src/helpers/framework/injection.js.map +1 -0
  230. package/dist/src/helpers/index.d.ts +22 -0
  231. package/dist/src/helpers/index.d.ts.map +1 -0
  232. package/dist/src/helpers/index.js +32 -0
  233. package/dist/src/helpers/index.js.map +1 -0
  234. package/dist/src/helpers/io/package.d.ts +5 -0
  235. package/dist/src/helpers/io/package.d.ts.map +1 -0
  236. package/dist/src/helpers/io/package.js +31 -0
  237. package/dist/src/helpers/io/package.js.map +1 -0
  238. package/dist/src/helpers/io/stream.d.ts +18 -0
  239. package/dist/src/helpers/io/stream.d.ts.map +1 -0
  240. package/dist/src/helpers/io/stream.js +91 -0
  241. package/dist/src/helpers/io/stream.js.map +1 -0
  242. package/dist/src/helpers/redis/broadcast.d.ts +12 -0
  243. package/dist/src/helpers/redis/broadcast.d.ts.map +1 -0
  244. package/dist/src/helpers/redis/broadcast.js +99 -0
  245. package/dist/src/helpers/redis/broadcast.js.map +1 -0
  246. package/dist/src/helpers/redis/cache.d.ts +7 -0
  247. package/dist/src/helpers/redis/cache.d.ts.map +1 -0
  248. package/dist/src/helpers/redis/cache.js +28 -0
  249. package/dist/src/helpers/redis/cache.js.map +1 -0
  250. package/dist/src/helpers/redis/mutex.d.ts +24 -0
  251. package/dist/src/helpers/redis/mutex.d.ts.map +1 -0
  252. package/dist/src/helpers/redis/mutex.js +240 -0
  253. package/dist/src/helpers/redis/mutex.js.map +1 -0
  254. package/dist/src/helpers/redis/redis.d.ts +11 -0
  255. package/dist/src/helpers/redis/redis.d.ts.map +1 -0
  256. package/dist/src/helpers/redis/redis.js +59 -0
  257. package/dist/src/helpers/redis/redis.js.map +1 -0
  258. package/dist/src/helpers/security/crypto.d.ts +26 -0
  259. package/dist/src/helpers/security/crypto.d.ts.map +1 -0
  260. package/dist/src/helpers/security/crypto.js +121 -0
  261. package/dist/src/helpers/security/crypto.js.map +1 -0
  262. package/dist/src/helpers/security/validation.d.ts +4 -0
  263. package/dist/src/helpers/security/validation.d.ts.map +1 -0
  264. package/dist/src/helpers/security/validation.js +25 -0
  265. package/dist/src/helpers/security/validation.js.map +1 -0
  266. package/dist/src/helpers/utils/date.d.ts +4 -0
  267. package/dist/src/helpers/utils/date.d.ts.map +1 -0
  268. package/dist/src/helpers/utils/date.js +23 -0
  269. package/dist/src/helpers/utils/date.js.map +1 -0
  270. package/dist/src/helpers/utils/error.d.ts +24 -0
  271. package/dist/src/helpers/utils/error.d.ts.map +1 -0
  272. package/dist/src/helpers/utils/error.js +168 -0
  273. package/dist/src/helpers/utils/error.js.map +1 -0
  274. package/dist/src/helpers/utils/jsx.d.ts +3 -0
  275. package/dist/src/helpers/utils/jsx.d.ts.map +1 -0
  276. package/dist/src/helpers/utils/jsx.js +13 -0
  277. package/dist/src/helpers/utils/jsx.js.map +1 -0
  278. package/dist/src/helpers/utils/uuid.d.ts +3 -0
  279. package/dist/src/helpers/utils/uuid.d.ts.map +1 -0
  280. package/dist/src/helpers/utils/uuid.js +14 -0
  281. package/dist/src/helpers/utils/uuid.js.map +1 -0
  282. package/dist/src/http/auth.d.ts +46 -0
  283. package/dist/src/http/auth.d.ts.map +1 -0
  284. package/dist/src/http/auth.js +162 -0
  285. package/dist/src/http/auth.js.map +1 -0
  286. package/dist/src/http/context.d.ts +5 -0
  287. package/dist/src/http/context.d.ts.map +1 -0
  288. package/dist/src/http/context.js +22 -0
  289. package/dist/src/http/context.js.map +1 -0
  290. package/dist/src/http/cors.d.ts +36 -0
  291. package/dist/src/http/cors.d.ts.map +1 -0
  292. package/dist/src/http/cors.js +171 -0
  293. package/dist/src/http/cors.js.map +1 -0
  294. package/dist/src/http/errors.d.ts +3 -0
  295. package/dist/src/http/errors.d.ts.map +1 -0
  296. package/dist/src/http/errors.js +10 -0
  297. package/dist/src/http/errors.js.map +1 -0
  298. package/dist/src/http/index.d.ts +24 -0
  299. package/dist/src/http/index.d.ts.map +1 -0
  300. package/dist/src/http/index.js +25 -0
  301. package/dist/src/http/index.js.map +1 -0
  302. package/dist/src/http/kernel.d.ts +17 -0
  303. package/dist/src/http/kernel.d.ts.map +1 -0
  304. package/dist/src/http/kernel.js +133 -0
  305. package/dist/src/http/kernel.js.map +1 -0
  306. package/dist/src/http/middleware.d.ts +12 -0
  307. package/dist/src/http/middleware.d.ts.map +1 -0
  308. package/dist/src/http/middleware.js +61 -0
  309. package/dist/src/http/middleware.js.map +1 -0
  310. package/dist/src/http/overrides.d.ts +2 -0
  311. package/dist/src/http/overrides.d.ts.map +1 -0
  312. package/dist/src/http/overrides.js +19 -0
  313. package/dist/src/http/overrides.js.map +1 -0
  314. package/dist/src/http/store.d.ts +33 -0
  315. package/dist/src/http/store.d.ts.map +1 -0
  316. package/dist/src/http/store.js +102 -0
  317. package/dist/src/http/store.js.map +1 -0
  318. package/dist/src/http/uploads.d.ts +7 -0
  319. package/dist/src/http/uploads.d.ts.map +1 -0
  320. package/dist/src/http/uploads.js +8 -0
  321. package/dist/src/http/uploads.js.map +1 -0
  322. package/dist/src/http/workflow.d.ts +18 -0
  323. package/dist/src/http/workflow.d.ts.map +1 -0
  324. package/dist/src/http/workflow.js +181 -0
  325. package/dist/src/http/workflow.js.map +1 -0
  326. package/dist/src/index.d.ts +13 -0
  327. package/dist/src/index.d.ts.map +1 -0
  328. package/dist/src/index.js +25 -0
  329. package/dist/src/index.js.map +1 -0
  330. package/dist/src/services/cli/invoke.d.ts +5 -0
  331. package/dist/src/services/cli/invoke.d.ts.map +1 -0
  332. package/dist/src/services/cli/invoke.js +45 -0
  333. package/dist/src/services/cli/invoke.js.map +1 -0
  334. package/dist/src/services/cli/repl.d.ts +5 -0
  335. package/dist/src/services/cli/repl.d.ts.map +1 -0
  336. package/dist/src/services/cli/repl.js +71 -0
  337. package/dist/src/services/cli/repl.js.map +1 -0
  338. package/dist/src/services/cli.d.ts +12 -0
  339. package/dist/src/services/cli.d.ts.map +1 -0
  340. package/dist/src/services/cli.js +76 -0
  341. package/dist/src/services/cli.js.map +1 -0
  342. package/dist/src/services/index.d.ts +7 -0
  343. package/dist/src/services/index.d.ts.map +1 -0
  344. package/dist/src/services/index.js +10 -0
  345. package/dist/src/services/index.js.map +1 -0
  346. package/dist/src/services/leader.d.ts +32 -0
  347. package/dist/src/services/leader.d.ts.map +1 -0
  348. package/dist/src/services/leader.js +174 -0
  349. package/dist/src/services/leader.js.map +1 -0
  350. package/dist/src/services/logger.d.ts +35 -0
  351. package/dist/src/services/logger.d.ts.map +1 -0
  352. package/dist/src/services/logger.js +245 -0
  353. package/dist/src/services/logger.js.map +1 -0
  354. package/dist/src/services/mail/index.d.ts +61 -0
  355. package/dist/src/services/mail/index.d.ts.map +1 -0
  356. package/dist/src/services/mail/index.js +90 -0
  357. package/dist/src/services/mail/index.js.map +1 -0
  358. package/dist/src/services/mail/postmark.d.ts +11 -0
  359. package/dist/src/services/mail/postmark.d.ts.map +1 -0
  360. package/dist/src/services/mail/postmark.js +42 -0
  361. package/dist/src/services/mail/postmark.js.map +1 -0
  362. package/dist/src/services/mail/smtp.d.ts +11 -0
  363. package/dist/src/services/mail/smtp.d.ts.map +1 -0
  364. package/dist/src/services/mail/smtp.js +61 -0
  365. package/dist/src/services/mail/smtp.js.map +1 -0
  366. package/dist/src/services/mesh.d.ts +65 -0
  367. package/dist/src/services/mesh.d.ts.map +1 -0
  368. package/dist/src/services/mesh.js +422 -0
  369. package/dist/src/services/mesh.js.map +1 -0
  370. package/dist/src/services/worker/bootstrap.d.ts +3 -0
  371. package/dist/src/services/worker/bootstrap.d.ts.map +1 -0
  372. package/dist/src/services/worker/bootstrap.js +70 -0
  373. package/dist/src/services/worker/bootstrap.js.map +1 -0
  374. package/dist/src/services/worker/cli.d.ts +23 -0
  375. package/dist/src/services/worker/cli.d.ts.map +1 -0
  376. package/dist/src/services/worker/cli.js +81 -0
  377. package/dist/src/services/worker/cli.js.map +1 -0
  378. package/dist/src/services/worker/entity.d.ts +18 -0
  379. package/dist/src/services/worker/entity.d.ts.map +1 -0
  380. package/dist/src/services/worker/entity.js +16 -0
  381. package/dist/src/services/worker/entity.js.map +1 -0
  382. package/dist/src/services/worker/index.d.ts +9 -0
  383. package/dist/src/services/worker/index.d.ts.map +1 -0
  384. package/dist/src/services/worker/index.js +40 -0
  385. package/dist/src/services/worker/index.js.map +1 -0
  386. package/dist/src/services/worker/observer.d.ts +18 -0
  387. package/dist/src/services/worker/observer.d.ts.map +1 -0
  388. package/dist/src/services/worker/observer.js +172 -0
  389. package/dist/src/services/worker/observer.js.map +1 -0
  390. package/dist/src/services/worker/queue.d.ts +8 -0
  391. package/dist/src/services/worker/queue.d.ts.map +1 -0
  392. package/dist/src/services/worker/queue.js +31 -0
  393. package/dist/src/services/worker/queue.js.map +1 -0
  394. package/dist/src/services/worker/runner.d.ts +17 -0
  395. package/dist/src/services/worker/runner.d.ts.map +1 -0
  396. package/dist/src/services/worker/runner.js +131 -0
  397. package/dist/src/services/worker/runner.js.map +1 -0
  398. package/dist/src/services/worker/types.d.ts +26 -0
  399. package/dist/src/services/worker/types.d.ts.map +1 -0
  400. package/dist/src/services/worker/types.js +29 -0
  401. package/dist/src/services/worker/types.js.map +1 -0
  402. package/dist/src/srpc/SrpcByteStream.d.ts +67 -0
  403. package/dist/src/srpc/SrpcByteStream.d.ts.map +1 -0
  404. package/dist/src/srpc/SrpcByteStream.js +319 -0
  405. package/dist/src/srpc/SrpcByteStream.js.map +1 -0
  406. package/dist/src/srpc/SrpcClient.d.ts +75 -0
  407. package/dist/src/srpc/SrpcClient.d.ts.map +1 -0
  408. package/dist/src/srpc/SrpcClient.js +445 -0
  409. package/dist/src/srpc/SrpcClient.js.map +1 -0
  410. package/dist/src/srpc/SrpcServer.d.ts +54 -0
  411. package/dist/src/srpc/SrpcServer.d.ts.map +1 -0
  412. package/dist/src/srpc/SrpcServer.js +456 -0
  413. package/dist/src/srpc/SrpcServer.js.map +1 -0
  414. package/dist/src/srpc/index.d.ts +7 -0
  415. package/dist/src/srpc/index.d.ts.map +1 -0
  416. package/dist/src/srpc/index.js +12 -0
  417. package/dist/src/srpc/index.js.map +1 -0
  418. package/dist/src/srpc/types.d.ts +129 -0
  419. package/dist/src/srpc/types.d.ts.map +1 -0
  420. package/dist/src/srpc/types.js +65 -0
  421. package/dist/src/srpc/types.js.map +1 -0
  422. package/dist/src/telemetry/index.d.ts +2 -0
  423. package/dist/src/telemetry/index.d.ts.map +1 -0
  424. package/dist/src/telemetry/index.js +5 -0
  425. package/dist/src/telemetry/index.js.map +1 -0
  426. package/dist/src/telemetry/otel/MariaDBInstrumentation.d.ts +22 -0
  427. package/dist/src/telemetry/otel/MariaDBInstrumentation.d.ts.map +1 -0
  428. package/dist/src/telemetry/otel/MariaDBInstrumentation.js +248 -0
  429. package/dist/src/telemetry/otel/MariaDBInstrumentation.js.map +1 -0
  430. package/dist/src/telemetry/otel/helpers.d.ts +27 -0
  431. package/dist/src/telemetry/otel/helpers.d.ts.map +1 -0
  432. package/dist/src/telemetry/otel/helpers.js +126 -0
  433. package/dist/src/telemetry/otel/helpers.js.map +1 -0
  434. package/dist/src/telemetry/otel/index.d.ts +14 -0
  435. package/dist/src/telemetry/otel/index.d.ts.map +1 -0
  436. package/dist/src/telemetry/otel/index.js +132 -0
  437. package/dist/src/telemetry/otel/index.js.map +1 -0
  438. package/dist/src/telemetry/otel/metrics.controller.d.ts +6 -0
  439. package/dist/src/telemetry/otel/metrics.controller.d.ts.map +1 -0
  440. package/dist/src/telemetry/otel/metrics.controller.js +63 -0
  441. package/dist/src/telemetry/otel/metrics.controller.js.map +1 -0
  442. package/dist/src/telemetry/sentry.d.ts +9 -0
  443. package/dist/src/telemetry/sentry.d.ts.map +1 -0
  444. package/dist/src/telemetry/sentry.js +62 -0
  445. package/dist/src/telemetry/sentry.js.map +1 -0
  446. package/dist/src/testapp/bootstrap.d.ts +1 -0
  447. package/dist/src/testapp/bootstrap.d.ts.map +1 -0
  448. package/dist/src/testapp/bootstrap.js +18 -0
  449. package/dist/src/testapp/bootstrap.js.map +1 -0
  450. package/dist/src/testapp/sample.d.ts +6 -0
  451. package/dist/src/testapp/sample.d.ts.map +1 -0
  452. package/dist/src/testapp/sample.js +228 -0
  453. package/dist/src/testapp/sample.js.map +1 -0
  454. package/dist/src/testapp/srpc-test.d.ts +27 -0
  455. package/dist/src/testapp/srpc-test.d.ts.map +1 -0
  456. package/dist/src/testapp/srpc-test.js +570 -0
  457. package/dist/src/testapp/srpc-test.js.map +1 -0
  458. package/dist/src/testing/expect.d.ts +25 -0
  459. package/dist/src/testing/expect.d.ts.map +1 -0
  460. package/dist/src/testing/expect.js +151 -0
  461. package/dist/src/testing/expect.js.map +1 -0
  462. package/dist/src/testing/fixtures.d.ts +19 -0
  463. package/dist/src/testing/fixtures.d.ts.map +1 -0
  464. package/dist/src/testing/fixtures.js +69 -0
  465. package/dist/src/testing/fixtures.js.map +1 -0
  466. package/dist/src/testing/index.d.ts +260 -0
  467. package/dist/src/testing/index.d.ts.map +1 -0
  468. package/dist/src/testing/index.js +345 -0
  469. package/dist/src/testing/index.js.map +1 -0
  470. package/dist/src/testing/requests.d.ts +10 -0
  471. package/dist/src/testing/requests.d.ts.map +1 -0
  472. package/dist/src/testing/requests.js +56 -0
  473. package/dist/src/testing/requests.js.map +1 -0
  474. package/dist/src/testing/sql.d.ts +11 -0
  475. package/dist/src/testing/sql.d.ts.map +1 -0
  476. package/dist/src/testing/sql.js +55 -0
  477. package/dist/src/testing/sql.js.map +1 -0
  478. package/dist/src/types/index.d.ts +57 -0
  479. package/dist/src/types/index.d.ts.map +1 -0
  480. package/dist/src/types/index.js +73 -0
  481. package/dist/src/types/index.js.map +1 -0
  482. package/dist/src/types/phone.d.ts +11 -0
  483. package/dist/src/types/phone.d.ts.map +1 -0
  484. package/dist/src/types/phone.js +73 -0
  485. package/dist/src/types/phone.js.map +1 -0
  486. package/dist/tsconfig.tsbuildinfo +1 -0
  487. package/docs/README.md +38 -0
  488. package/docs/authentication.md +215 -0
  489. package/docs/cli.md +302 -0
  490. package/docs/configuration.md +176 -0
  491. package/docs/database.md +422 -0
  492. package/docs/getting-started.md +154 -0
  493. package/docs/health.md +53 -0
  494. package/docs/helpers.md +436 -0
  495. package/docs/http.md +253 -0
  496. package/docs/leader-service.md +98 -0
  497. package/docs/logging.md +150 -0
  498. package/docs/mail.md +161 -0
  499. package/docs/mesh-service.md +204 -0
  500. package/docs/srpc.md +261 -0
  501. package/docs/telemetry.md +166 -0
  502. package/docs/testing.md +222 -0
  503. package/docs/types.md +215 -0
  504. package/docs/worker.md +174 -0
  505. package/lefthook.yml +12 -0
  506. package/openapi.yaml +109 -0
  507. package/package.json +133 -0
  508. package/patches/@deepkit+type+1.0.19.patch +38 -0
  509. package/resources/proto/generated/test/test.ts +2721 -0
  510. package/resources/proto/sample.proto +85 -0
  511. package/resources/proto/test.proto +178 -0
  512. package/src/app/base.ts +257 -0
  513. package/src/app/config.loader.ts +66 -0
  514. package/src/app/config.ts +120 -0
  515. package/src/app/const.ts +4 -0
  516. package/src/app/dev.ts +70 -0
  517. package/src/app/index.ts +6 -0
  518. package/src/app/openapi.ts +3 -0
  519. package/src/app/resolver.ts +49 -0
  520. package/src/app/shutdown.ts +55 -0
  521. package/src/app/state.ts +19 -0
  522. package/src/auth/index.ts +2 -0
  523. package/src/auth/jwt.ts +275 -0
  524. package/src/auth/provider.ts +57 -0
  525. package/src/cli/dksf-dev.ts +363 -0
  526. package/src/cli/dksf-gen-proto.ts +176 -0
  527. package/src/cli/dksf-install.ts +11 -0
  528. package/src/cli/dksf-test.ts +95 -0
  529. package/src/cli/dksf-update.ts +101 -0
  530. package/src/database/CLAUDE.md +390 -0
  531. package/src/database/common.ts +385 -0
  532. package/src/database/dialect.ts +43 -0
  533. package/src/database/entity.ts +285 -0
  534. package/src/database/index.ts +7 -0
  535. package/src/database/migration/MigrationResetCommand.ts +152 -0
  536. package/src/database/migration/MigrationRunCommand.ts +118 -0
  537. package/src/database/migration/characters.ts +53 -0
  538. package/src/database/migration/create/MigrationCreateCommand.ts +94 -0
  539. package/src/database/migration/create/comparator.ts +467 -0
  540. package/src/database/migration/create/db-reader.ts +510 -0
  541. package/src/database/migration/create/ddl-generator.ts +755 -0
  542. package/src/database/migration/create/entity-reader.ts +462 -0
  543. package/src/database/migration/create/file-generator.ts +52 -0
  544. package/src/database/migration/create/prompt.ts +49 -0
  545. package/src/database/migration/create/schema-model.ts +102 -0
  546. package/src/database/migration/helpers.ts +3 -0
  547. package/src/database/migration/index.ts +35 -0
  548. package/src/database/migration/migration.entity.ts +10 -0
  549. package/src/database/mysql.ts +140 -0
  550. package/src/database/postgres.ts +97 -0
  551. package/src/database/types.ts +18 -0
  552. package/src/health/health.module.ts +30 -0
  553. package/src/health/healthcheck.controller.ts +17 -0
  554. package/src/health/healthcheck.service.ts +15 -0
  555. package/src/health/index.ts +2 -0
  556. package/src/helpers/CLAUDE.md +71 -0
  557. package/src/helpers/async/context.ts +67 -0
  558. package/src/helpers/async/process.ts +49 -0
  559. package/src/helpers/async/promise.ts +16 -0
  560. package/src/helpers/data/array.ts +11 -0
  561. package/src/helpers/data/objects.ts +64 -0
  562. package/src/helpers/data/serialization.ts +11 -0
  563. package/src/helpers/data/transformer.ts +54 -0
  564. package/src/helpers/framework/decorators.ts +27 -0
  565. package/src/helpers/framework/event.ts +11 -0
  566. package/src/helpers/framework/injection.ts +47 -0
  567. package/src/helpers/index.ts +34 -0
  568. package/src/helpers/io/package.ts +26 -0
  569. package/src/helpers/io/stream.ts +79 -0
  570. package/src/helpers/redis/broadcast.ts +94 -0
  571. package/src/helpers/redis/cache.ts +28 -0
  572. package/src/helpers/redis/mutex.ts +260 -0
  573. package/src/helpers/redis/redis.ts +60 -0
  574. package/src/helpers/security/crypto.ts +133 -0
  575. package/src/helpers/security/validation.ts +16 -0
  576. package/src/helpers/utils/date.ts +13 -0
  577. package/src/helpers/utils/error.ts +155 -0
  578. package/src/helpers/utils/jsx.ts +8 -0
  579. package/src/helpers/utils/uuid.ts +8 -0
  580. package/src/http/auth.ts +156 -0
  581. package/src/http/context.ts +15 -0
  582. package/src/http/cors.ts +159 -0
  583. package/src/http/errors.ts +9 -0
  584. package/src/http/index.ts +19 -0
  585. package/src/http/kernel.ts +138 -0
  586. package/src/http/middleware.ts +59 -0
  587. package/src/http/overrides.ts +20 -0
  588. package/src/http/store.ts +86 -0
  589. package/src/http/uploads.ts +6 -0
  590. package/src/http/workflow.ts +167 -0
  591. package/src/index.ts +19 -0
  592. package/src/services/cli/invoke.ts +39 -0
  593. package/src/services/cli/repl.ts +67 -0
  594. package/src/services/cli.ts +74 -0
  595. package/src/services/index.ts +6 -0
  596. package/src/services/leader.ts +201 -0
  597. package/src/services/logger.ts +258 -0
  598. package/src/services/mail/index.ts +117 -0
  599. package/src/services/mail/postmark.ts +37 -0
  600. package/src/services/mail/smtp.ts +46 -0
  601. package/src/services/mesh.ts +508 -0
  602. package/src/services/worker/CLAUDE.md +77 -0
  603. package/src/services/worker/bootstrap.ts +58 -0
  604. package/src/services/worker/cli.ts +63 -0
  605. package/src/services/worker/entity.ts +22 -0
  606. package/src/services/worker/index.ts +30 -0
  607. package/src/services/worker/observer.ts +180 -0
  608. package/src/services/worker/queue.ts +34 -0
  609. package/src/services/worker/runner.ts +146 -0
  610. package/src/services/worker/types.ts +32 -0
  611. package/src/srpc/CLAUDE.md +194 -0
  612. package/src/srpc/SRPC_MIGRATION_GUIDE.md +348 -0
  613. package/src/srpc/SrpcByteStream.ts +382 -0
  614. package/src/srpc/SrpcClient.ts +512 -0
  615. package/src/srpc/SrpcServer.ts +575 -0
  616. package/src/srpc/index.ts +15 -0
  617. package/src/srpc/types.ts +144 -0
  618. package/src/telemetry/index.ts +1 -0
  619. package/src/telemetry/otel/MariaDBInstrumentation.ts +297 -0
  620. package/src/telemetry/otel/helpers.ts +117 -0
  621. package/src/telemetry/otel/index.ts +150 -0
  622. package/src/telemetry/otel/metrics.controller.ts +50 -0
  623. package/src/telemetry/sentry.ts +58 -0
  624. package/src/testapp/bootstrap.ts +17 -0
  625. package/src/testapp/sample.ts +220 -0
  626. package/src/testapp/srpc-test.ts +684 -0
  627. package/src/testing/expect.ts +148 -0
  628. package/src/testing/fixtures.ts +62 -0
  629. package/src/testing/index.ts +355 -0
  630. package/src/testing/requests.ts +68 -0
  631. package/src/testing/sql.ts +50 -0
  632. package/src/types/index.ts +64 -0
  633. package/src/types/phone.ts +64 -0
  634. package/tests/app/app.spec.ts +53 -0
  635. package/tests/app/type.spec.ts +22 -0
  636. package/tests/auth/jwt.spec.ts +90 -0
  637. package/tests/database/entity.spec.ts +382 -0
  638. package/tests/database/locks.spec.ts +142 -0
  639. package/tests/database/migration-create-integration.spec.ts +234 -0
  640. package/tests/database/migration-create-unit.spec.ts +3896 -0
  641. package/tests/helpers/array.spec.ts +80 -0
  642. package/tests/helpers/cache.spec.ts +202 -0
  643. package/tests/helpers/crypto.spec.ts +236 -0
  644. package/tests/helpers/date.spec.ts +94 -0
  645. package/tests/helpers/error.spec.ts +233 -0
  646. package/tests/helpers/mutex.spec.ts +354 -0
  647. package/tests/helpers/objects.spec.ts +212 -0
  648. package/tests/helpers/package.spec.ts +90 -0
  649. package/tests/helpers/promise.spec.ts +119 -0
  650. package/tests/helpers/redis.spec.ts +50 -0
  651. package/tests/helpers/serialization.spec.ts +150 -0
  652. package/tests/helpers/stream.spec.ts +225 -0
  653. package/tests/helpers/validation.spec.ts +133 -0
  654. package/tests/services/leader.spec.ts +257 -0
  655. package/tests/services/logger.spec.ts +269 -0
  656. package/tests/services/mesh.spec.ts +814 -0
  657. package/tests/shared/db.ts +105 -0
  658. package/tests/shared/globalSetup.ts +48 -0
  659. package/tests/shared/helpers.ts +40 -0
  660. package/tests/srpc/SrpcByteStream.spec.ts +542 -0
  661. package/tests/tsconfig.json +4 -0
  662. package/tests/types/index.spec.ts +60 -0
  663. package/tests/types/phone.spec.ts +140 -0
  664. package/tsconfig.json +106 -0
  665. package/tsconfig.test.json +8 -0
  666. package/types.d.ts +6 -0
@@ -0,0 +1,684 @@
1
+ import { ScopedLogger } from '@deepkit/logger';
2
+ import { createHmac } from 'crypto';
3
+ import { Readable } from 'stream';
4
+ import WebSocket from 'ws';
5
+
6
+ import { ApplicationServer } from '@deepkit/framework';
7
+
8
+ import { ClientMessage, ServerMessage } from '../../resources/proto/generated/test/test';
9
+ import { AutoStart, BaseAppConfig } from '../app';
10
+ import { sleepSecs, uuid7 } from '../helpers';
11
+ import { SrpcByteStream, SrpcClient, SrpcError, SrpcMeta, SrpcServer, SrpcStream } from '../srpc';
12
+
13
+ const TEST_WS_PATH = '/srpc-test';
14
+
15
+ type TestClientOutput = ClientMessage;
16
+ type TestServerOutput = ServerMessage;
17
+
18
+ @AutoStart()
19
+ export class SrpcTesterService {
20
+ private server: SrpcServer<SrpcMeta, TestClientOutput, TestServerOutput>;
21
+ private connectedStream: SrpcStream | undefined;
22
+ public testsCompleted = false;
23
+ public testsFailed = false;
24
+
25
+ constructor(
26
+ private logger: ScopedLogger,
27
+ private appConfig: BaseAppConfig,
28
+ private appServer: ApplicationServer
29
+ ) {
30
+ // Expand clock drift to keep tests stable on slower systems
31
+ this.appConfig.SRPC_AUTH_CLOCK_DRIFT_MS = 60_000;
32
+
33
+ // Debug: Log what secrets are available via config (not env)
34
+ this.logger.info('Configuration check:', {
35
+ SRPC_AUTH_SECRET: this.appConfig.SRPC_AUTH_SECRET ? '***set***' : 'NOT SET'
36
+ });
37
+
38
+ // Create and configure server
39
+ this.logger.info('Bootstrapping SrpcServer transport', { wsPath: TEST_WS_PATH });
40
+ this.server = new SrpcServer<SrpcMeta, TestClientOutput, TestServerOutput>({
41
+ logger: this.logger.scoped('SrpcServer'),
42
+ clientMessage: ClientMessage,
43
+ serverMessage: ServerMessage,
44
+ wsPath: TEST_WS_PATH,
45
+ debug: false
46
+ });
47
+
48
+ // Use custom key fetcher to read from app config
49
+ this.server.setClientKeyFetcher(async clientId => {
50
+ const secret = this.getServerSecret();
51
+ this.logger.info('Server fetching key for client:', { clientId, hasSecret: !!secret });
52
+ return secret || false;
53
+ });
54
+
55
+ this.setupServerHandlers();
56
+
57
+ // Track connected streams for server-to-client tests
58
+ this.server.registerConnectionHandler(stream => {
59
+ this.connectedStream = stream;
60
+ });
61
+
62
+ // Run tests after a short delay to ensure server is ready
63
+ setTimeout(
64
+ () =>
65
+ this.runTests()
66
+ .then(() => {
67
+ this.logger.info('SRPC tests completed successfully!');
68
+ this.testsCompleted = true;
69
+ })
70
+ .catch(err => {
71
+ this.logger.error('SRPC tests failed:', err);
72
+ this.testsFailed = true;
73
+ throw err;
74
+ }),
75
+ 1000
76
+ );
77
+ }
78
+
79
+ private get httpPort(): number {
80
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
81
+ return (this.appServer.getHttpWorker()['server']!.address() as any).port;
82
+ }
83
+
84
+ private setupServerHandlers() {
85
+ // Echo handler
86
+ this.server.registerMessageHandler('uEcho', async (_stream, data) => {
87
+ return { message: `Echo: ${data.message}` };
88
+ });
89
+
90
+ // Complex data types handler
91
+ this.server.registerMessageHandler('uComplex', async (_stream, data) => {
92
+ const result = `Processed: ${data.stringField}, ${data.intField}, ${data.boolField}`;
93
+ const count = data.arrayField.length + Object.keys(data.mapField).length;
94
+ return { result, count };
95
+ });
96
+
97
+ // Error handler
98
+ this.server.registerMessageHandler('uError', async (_stream, data) => {
99
+ throw new SrpcError(data.errorMessage, data.userError);
100
+ });
101
+
102
+ // Upload handler (client to server byte stream)
103
+ this.server.registerMessageHandler('uUpload', async (stream, data) => {
104
+ const receiver = SrpcByteStream.createReceiver(stream, data.streamId);
105
+ const chunks: Buffer[] = [];
106
+
107
+ for await (const chunk of receiver) {
108
+ chunks.push(chunk);
109
+ }
110
+
111
+ const totalBytes = Buffer.concat(chunks).length;
112
+ return { message: `Uploaded ${data.filename}`, bytesReceived: totalBytes };
113
+ });
114
+
115
+ // Download handler (server to client byte stream)
116
+ this.server.registerMessageHandler('uDownload', async (stream, data) => {
117
+ const testData = Buffer.from(`Test file contents for ${data.filename}`, 'utf-8');
118
+ const sender = SrpcByteStream.createSender(stream);
119
+
120
+ setTimeout(() => {
121
+ sender.write(testData);
122
+ sender.end();
123
+ }, 10);
124
+
125
+ return { streamId: sender.id, bytesTotal: testData.length };
126
+ });
127
+
128
+ // Slow request handler
129
+ this.server.registerMessageHandler('uSlow', async (_stream, data) => {
130
+ const start = Date.now();
131
+ await new Promise(resolve => setTimeout(resolve, data.delayMs));
132
+ const actualDelay = Date.now() - start;
133
+ return { message: 'Completed', actualDelayMs: actualDelay };
134
+ });
135
+ }
136
+
137
+ private createClient(clientId: string, autoConnect = true): Promise<SrpcClient<TestClientOutput, TestServerOutput>> {
138
+ const secret = this.getServerSecret();
139
+
140
+ const client = new SrpcClient<TestClientOutput, TestServerOutput>(
141
+ this.logger.scoped('WsClient'),
142
+ `ws://localhost:${this.httpPort}${TEST_WS_PATH}`,
143
+ ClientMessage,
144
+ ServerMessage,
145
+ clientId,
146
+ { testEnv: 'testapp' },
147
+ secret,
148
+ { enableReconnect: false }
149
+ );
150
+
151
+ if (!autoConnect) {
152
+ return Promise.resolve(client);
153
+ }
154
+
155
+ return new Promise<SrpcClient<TestClientOutput, TestServerOutput>>(resolve => {
156
+ client.registerConnectionHandler(() => resolve(client));
157
+ client.connect();
158
+ });
159
+ }
160
+
161
+ private async runTests() {
162
+ this.logger.info('Starting SRPC tests...');
163
+
164
+ // Give server time to start
165
+ await sleepSecs(0.5);
166
+
167
+ await this.testConnectionAndAuthentication();
168
+ await this.testClientToServerRPC();
169
+ await this.testServerToClientRPC();
170
+ await this.testByteStreams();
171
+ await this.testConnectionLifecycle();
172
+ await this.testCustomMetadata();
173
+
174
+ // Run legacy raw WebSocket test for backwards compatibility
175
+ await this.testRawWebsocketClient();
176
+
177
+ this.logger.info('All SRPC tests passed!');
178
+ }
179
+
180
+ private async testConnectionAndAuthentication() {
181
+ this.logger.info('[Test Start] Connection and Authentication');
182
+
183
+ // Test: Valid connection
184
+ this.logger.info('Creating SRPC client with valid credentials');
185
+ const client = await this.createClient(`test-ws-${Date.now()}`);
186
+ if (!client.isConnected) {
187
+ throw new Error('Client should be connected');
188
+ }
189
+ this.logger.info(' ✓ Valid credentials connection');
190
+
191
+ // Clean up for next test
192
+ this.logger.info('Disconnecting valid client before invalid auth test');
193
+ client.disconnect();
194
+ await sleepSecs(0.2);
195
+
196
+ // Test: Invalid signature
197
+ this.logger.info('Attempting connection with invalid signature to ensure rejection');
198
+
199
+ let connectedWithBadSecret = false;
200
+ const badClient = new SrpcClient<TestClientOutput, TestServerOutput>(
201
+ this.logger.scoped('BadWsClient'),
202
+ `ws://localhost:${this.httpPort}${TEST_WS_PATH}`,
203
+ ClientMessage,
204
+ ServerMessage,
205
+ 'bad-client',
206
+ {},
207
+ 'wrong-secret',
208
+ { enableReconnect: false }
209
+ );
210
+
211
+ badClient.registerConnectionHandler(() => {
212
+ connectedWithBadSecret = true;
213
+ });
214
+
215
+ badClient.connect();
216
+ await sleepSecs(1);
217
+
218
+ if (connectedWithBadSecret) {
219
+ throw new Error('Should not connect with invalid signature');
220
+ }
221
+ this.logger.info('Bad client was rejected as expected');
222
+ this.logger.info(' ✓ Invalid signature rejection');
223
+
224
+ badClient.disconnect();
225
+ this.logger.info('[Test End] Connection and Authentication');
226
+ }
227
+
228
+ private async testClientToServerRPC() {
229
+ this.logger.info('[Test Start] Client-to-Server RPC');
230
+
231
+ const client = await this.createClient(`test-rpc-ws-${Date.now()}`);
232
+
233
+ // Test: Simple echo (using simplified invoke syntax)
234
+ this.logger.info('Sending uEchoRequest payload');
235
+ const echoResponse = await client.invoke('uEcho', {
236
+ message: 'Hello, SRPC!'
237
+ });
238
+ if (echoResponse.message !== 'Echo: Hello, SRPC!') {
239
+ throw new Error('Echo response mismatch');
240
+ }
241
+ this.logger.info('Received expected uEchoResponse payload');
242
+ this.logger.info(' ✓ Simple echo request');
243
+
244
+ // Test: Complex data types (using simplified invoke syntax)
245
+ this.logger.info('Sending uComplexRequest payload');
246
+ const complexResponse = await client.invoke('uComplex', {
247
+ stringField: 'test',
248
+ intField: 42,
249
+ doubleField: 3.14,
250
+ boolField: true,
251
+ arrayField: ['a', 'b', 'c'],
252
+ mapField: { key1: 'value1', key2: 'value2' }
253
+ });
254
+ if (!complexResponse.result?.includes('test') || complexResponse.count !== 5) {
255
+ throw new Error('Complex data type handling failed');
256
+ }
257
+ this.logger.info('Complex response validated', { response: complexResponse });
258
+ this.logger.info(' ✓ Complex data types');
259
+
260
+ // Test: Error propagation
261
+ this.logger.info('Triggering uErrorRequest to confirm error propagation');
262
+ try {
263
+ await client.invoke('uError', {
264
+ errorMessage: 'Test error',
265
+ userError: false
266
+ });
267
+ throw new Error('Should have thrown error');
268
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
269
+ } catch (err: any) {
270
+ const errorMsg = err?.message || String(err);
271
+ if (!errorMsg || !errorMsg.includes('Test error')) {
272
+ throw new Error(`Error message not propagated correctly. Got: ${errorMsg}`);
273
+ }
274
+ }
275
+ this.logger.info(' ✓ Application error propagation');
276
+
277
+ // Test: Async request completion
278
+ this.logger.info('Invoking uSlowRequest with 100ms delay');
279
+ const asyncResponse = await client.invoke('uSlow', { delayMs: 100 }, 5000);
280
+ if (asyncResponse.message !== 'Completed') {
281
+ throw new Error(`Async request failed: expected message 'Completed' but got '${asyncResponse.message}'`);
282
+ }
283
+ if (asyncResponse.actualDelayMs < 90) {
284
+ throw new Error(`Async request failed: expected delay >= 90ms but got ${asyncResponse.actualDelayMs}ms`);
285
+ }
286
+ this.logger.info(' ✓ Async request completion');
287
+
288
+ // Test: Request timeout
289
+ this.logger.info('Invoking uSlowRequest with 2000ms delay and 500ms timeout');
290
+ try {
291
+ await client.invoke('uSlow', { delayMs: 2000 }, 500);
292
+ throw new Error('Request should have timed out');
293
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
294
+ } catch (err: any) {
295
+ const errorMsg = err?.message || String(err);
296
+ if (!errorMsg.toLowerCase().includes('timeout') && !errorMsg.includes('Request should have timed out')) {
297
+ throw new Error(`Expected timeout error but got: ${errorMsg}`);
298
+ }
299
+ if (errorMsg.includes('Request should have timed out')) {
300
+ throw new Error('Request did not timeout as expected');
301
+ }
302
+ }
303
+ this.logger.info(' ✓ Request timeout');
304
+
305
+ // Test: Concurrent requests
306
+ this.logger.info('Scheduling 10 concurrent uEchoRequest invocations');
307
+ const requests = Array.from({ length: 10 }, (_, i) => client.invoke('uEcho', { message: `Message ${i}` }));
308
+ const responses = await Promise.all(requests);
309
+ if (responses.length !== 10) {
310
+ throw new Error('Concurrent requests failed');
311
+ }
312
+ this.logger.info('All concurrent responses received');
313
+ this.logger.info(' ✓ Concurrent requests (10)');
314
+
315
+ client.disconnect();
316
+ await sleepSecs(0.2);
317
+ this.logger.info('[Test End] Client-to-Server RPC');
318
+ }
319
+
320
+ private async testServerToClientRPC() {
321
+ this.logger.info('[Test Start] Server-to-Client RPC');
322
+
323
+ const client = await this.createClient(`test-s2c-ws-${Date.now()}`);
324
+
325
+ // Wait for server to register the stream
326
+ this.logger.info('Waiting for server to register inbound stream');
327
+ await sleepSecs(0.2);
328
+
329
+ if (!this.connectedStream) {
330
+ throw new Error('Server should have registered connected stream');
331
+ }
332
+
333
+ // Test: Server invoking client
334
+ this.logger.info('Registering notify handler on client for server invocation');
335
+ client.registerMessageHandler('dNotify', async data => {
336
+ if (data.notification !== 'Test notification') {
337
+ throw new Error('Notification content mismatch');
338
+ }
339
+ return { acknowledged: true };
340
+ });
341
+
342
+ this.logger.info('Invoking server->client notify workflow (using simplified invoke syntax)');
343
+ const notifyResponse = await this.server.invoke(this.connectedStream, 'dNotify', {
344
+ notification: 'Test notification'
345
+ });
346
+ if (!notifyResponse.acknowledged) {
347
+ throw new Error('Server-to-client invocation failed');
348
+ }
349
+ this.logger.info(' ✓ Server invoking client');
350
+
351
+ // Test: Client computation (using simplified invoke syntax)
352
+ this.logger.info('Registering compute handler on client');
353
+ client.registerMessageHandler('dCompute', async data => {
354
+ let result = data.number;
355
+ if (data.operation === 'square') result = data.number * data.number;
356
+ if (data.operation === 'double') result = data.number * 2;
357
+ return { result };
358
+ });
359
+
360
+ this.logger.info('Invoking compute handler from server');
361
+ const squareResponse = await this.server.invoke(this.connectedStream, 'dCompute', {
362
+ number: 5,
363
+ operation: 'square'
364
+ });
365
+ if (squareResponse.result !== 25) {
366
+ throw new Error('Client computation failed');
367
+ }
368
+ this.logger.info(' ✓ Client computation requests');
369
+
370
+ client.disconnect();
371
+ await sleepSecs(0.2);
372
+ this.logger.info('[Test End] Server-to-Client RPC');
373
+ }
374
+
375
+ private async testByteStreams() {
376
+ this.logger.info('[Test Start] Byte Streams');
377
+
378
+ const client = await this.createClient(`test-bytes-ws-${Date.now()}`);
379
+
380
+ // Test: Upload (client to server)
381
+ this.logger.info('Starting client->server byte stream upload');
382
+ const uploadData = Buffer.from('Hello from client byte stream!', 'utf-8');
383
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
384
+ const sender = SrpcByteStream.createSender(client as any);
385
+ const uploadPromise = client.invoke('uUpload', {
386
+ streamId: sender.id,
387
+ filename: 'test.txt'
388
+ });
389
+ this.logger.info('Sending upload payload to server');
390
+ sender.write(uploadData);
391
+ sender.end();
392
+ const uploadResponse = await uploadPromise;
393
+ if (uploadResponse.bytesReceived !== uploadData.length) {
394
+ throw new Error('Upload byte count mismatch');
395
+ }
396
+ this.logger.info(' ✓ Upload via byte stream');
397
+
398
+ // Test: Download (server to client)
399
+ this.logger.info('Requesting server->client byte stream download');
400
+ const downloadResponse = await client.invoke('uDownload', {
401
+ filename: 'download.txt'
402
+ });
403
+
404
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
405
+ const receiver = SrpcByteStream.createReceiver(client as any, downloadResponse.streamId);
406
+ const downloadChunks: Buffer[] = [];
407
+ for await (const chunk of receiver) {
408
+ downloadChunks.push(chunk);
409
+ }
410
+
411
+ const receivedData = Buffer.concat(downloadChunks);
412
+ if (receivedData.length !== downloadResponse.bytesTotal) {
413
+ throw new Error('Download byte count mismatch');
414
+ }
415
+ this.logger.info(' ✓ Download via byte stream');
416
+
417
+ // Test: Large stream (1MB)
418
+ const largeData = Buffer.alloc(1024 * 1024);
419
+ for (let i = 0; i < largeData.length; i++) {
420
+ largeData[i] = i % 256;
421
+ }
422
+
423
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
424
+ const largeSender = SrpcByteStream.createSender(client as any);
425
+ const largeUploadPromise = client.invoke('uUpload', {
426
+ streamId: largeSender.id,
427
+ filename: 'large.bin'
428
+ });
429
+ this.logger.info('Streaming 1MB payload to server for stress test');
430
+ largeSender.write(largeData);
431
+ largeSender.end();
432
+ const largeResponse = await largeUploadPromise;
433
+ if (largeResponse.bytesReceived !== largeData.length) {
434
+ throw new Error('Large stream byte count mismatch');
435
+ }
436
+ this.logger.info(' ✓ Large byte stream (1MB)');
437
+
438
+ // Test: Chunked streaming
439
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
440
+ const chunkSender = SrpcByteStream.createSender(client as any);
441
+ const textChunks = ['Hello ', 'from ', 'chunked ', 'stream!'];
442
+ const chunkUploadPromise = client.invoke('uUpload', {
443
+ streamId: chunkSender.id,
444
+ filename: 'chunked.txt'
445
+ });
446
+ this.logger.info('Writing text chunks sequentially');
447
+ for (const chunk of textChunks) {
448
+ chunkSender.write(Buffer.from(chunk, 'utf-8'));
449
+ }
450
+ chunkSender.end();
451
+ const chunkResponse = await chunkUploadPromise;
452
+ if (chunkResponse.bytesReceived !== textChunks.join('').length) {
453
+ throw new Error('Chunked stream byte count mismatch');
454
+ }
455
+ this.logger.info(' ✓ Chunked streaming');
456
+
457
+ // Test: Node.js Readable stream
458
+ const readableData = 'Stream from Readable!';
459
+ const readable = Readable.from([Buffer.from(readableData, 'utf-8')]);
460
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
461
+ const pipedSender = SrpcByteStream.createSender(client as any);
462
+ const pipedUploadPromise = client.invoke('uUpload', {
463
+ streamId: pipedSender.id,
464
+ filename: 'piped.txt'
465
+ });
466
+
467
+ readable.pipe(pipedSender);
468
+ this.logger.info('Piping readable stream into SRPC sender');
469
+ await new Promise((resolve, reject) => {
470
+ pipedSender.on('finish', resolve);
471
+ pipedSender.on('error', reject);
472
+ });
473
+
474
+ const pipedResponse = await pipedUploadPromise;
475
+ if (pipedResponse.bytesReceived !== readableData.length) {
476
+ throw new Error('Piped stream byte count mismatch');
477
+ }
478
+ this.logger.info(' ✓ Node.js Readable stream integration');
479
+
480
+ client.disconnect();
481
+ await sleepSecs(0.2);
482
+ this.logger.info('[Test End] Byte Streams');
483
+ }
484
+
485
+ private async testConnectionLifecycle() {
486
+ this.logger.info('[Test Start] Connection Lifecycle');
487
+
488
+ const events: string[] = [];
489
+ const clientId = `test-lifecycle-ws-${Date.now()}`;
490
+
491
+ this.server.registerConnectionHandler(stream => {
492
+ events.push(`server-connected:${stream.clientId}`);
493
+ });
494
+
495
+ this.server.registerDisconnectHandler((stream, cause) => {
496
+ events.push(`server-disconnected:${stream.clientId}:${cause}`);
497
+ });
498
+
499
+ const client = await this.createClient(clientId, false);
500
+
501
+ client.registerConnectionHandler(() => {
502
+ events.push('client-connected');
503
+ });
504
+
505
+ client.registerDisconnectHandler(() => {
506
+ events.push('client-disconnected');
507
+ });
508
+
509
+ client.connect();
510
+ this.logger.info('Connection lifecycle client initiated', { clientId });
511
+ await this.waitForEvent(() => events.includes('client-connected'), 2_000, 'Client connection event not fired');
512
+ await this.waitForEvent(() => events.some(e => e === `server-connected:${clientId}`), 2_000, 'Server connection event not fired');
513
+ this.logger.info(' ✓ Connection handlers');
514
+
515
+ client.disconnect();
516
+ await this.waitForEvent(() => events.includes('client-disconnected'), 2_000, 'Client disconnection event not fired');
517
+ await this.waitForEvent(
518
+ () => events.some(e => e.startsWith(`server-disconnected:${clientId}:`)),
519
+ 2_000,
520
+ 'Server disconnection event not fired'
521
+ );
522
+ this.logger.info(' ✓ Disconnection handlers');
523
+ this.logger.info('[Test End] Connection Lifecycle');
524
+ }
525
+
526
+ private async testCustomMetadata() {
527
+ this.logger.info('[Test Start] Custom Metadata');
528
+
529
+ const customMeta = { appVersion: '1.2.3', userId: 'test-user' };
530
+ const clientId = `custom-meta-ws-${Date.now()}`;
531
+
532
+ const metaPromise = new Promise<SrpcMeta>((resolve, reject) => {
533
+ const timeout = setTimeout(() => reject(new Error('Timeout waiting for metadata')), 3000);
534
+ this.server.registerConnectionHandler(stream => {
535
+ if (stream.clientId === clientId) {
536
+ clearTimeout(timeout);
537
+ resolve(stream.meta);
538
+ }
539
+ });
540
+ });
541
+
542
+ const customClient = new SrpcClient<TestClientOutput, TestServerOutput>(
543
+ this.logger.scoped('CustomMetaWsClient'),
544
+ `ws://localhost:${this.httpPort}${TEST_WS_PATH}`,
545
+ ClientMessage,
546
+ ServerMessage,
547
+ clientId,
548
+ customMeta,
549
+ this.getServerSecret(),
550
+ { enableReconnect: false }
551
+ );
552
+
553
+ this.logger.info('Connecting custom metadata client');
554
+ await new Promise<void>(resolve => {
555
+ customClient.registerConnectionHandler(() => resolve());
556
+ customClient.connect();
557
+ });
558
+
559
+ this.logger.info('Awaiting metadata capture from server-side connection handler');
560
+ const receivedMeta = await metaPromise;
561
+ const normalizedMeta = Object.fromEntries(Object.entries(receivedMeta).map(([key, value]) => [key.toLowerCase(), value]));
562
+ if (normalizedMeta.appversion !== '1.2.3' || normalizedMeta.userid !== 'test-user') {
563
+ throw new Error(`Custom metadata not passed correctly. Got: ${JSON.stringify(normalizedMeta)}`);
564
+ }
565
+ this.logger.info(' ✓ Custom metadata passing');
566
+
567
+ customClient.disconnect();
568
+ await sleepSecs(0.2);
569
+ this.logger.info('[Test End] Custom Metadata');
570
+ }
571
+
572
+ private async testRawWebsocketClient() {
573
+ this.logger.info('[Test Start] Raw WebSocket Client (backwards compatibility)');
574
+
575
+ const secret = this.getServerSecret();
576
+ const clientId = `ws-raw-${Date.now()}`;
577
+ const streamId = uuid7();
578
+ const authv = 1;
579
+ const appv = '0.0.0';
580
+ const ts = Date.now().toString();
581
+
582
+ const signable = `${authv}\n${appv}\n${ts}\n${streamId}\n${clientId}\n`;
583
+ const signature = createHmac('sha256', secret).update(signable).digest('hex');
584
+
585
+ const params = new URLSearchParams({
586
+ authv: String(authv),
587
+ appv,
588
+ ts,
589
+ id: streamId,
590
+ cid: clientId,
591
+ signature
592
+ });
593
+ params.set('m--testEnv', 'testapp-ws');
594
+
595
+ const requestId = uuid7();
596
+ const requestBuffer = ClientMessage.encode({
597
+ requestId,
598
+ reply: false,
599
+ uEchoRequest: { message: 'Hello via raw WS' }
600
+ }).finish();
601
+
602
+ const pongBuffer = ClientMessage.encode({ requestId: '', reply: false, pingPong: {} }).finish();
603
+
604
+ await new Promise<void>((resolve, reject) => {
605
+ const wsUrl = `ws://localhost:${this.httpPort}${TEST_WS_PATH}?${params.toString()}`;
606
+ const ws = new WebSocket(wsUrl);
607
+
608
+ const finish = (err?: Error) => {
609
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
610
+ if ((ws as any)._finished) return;
611
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
612
+ (ws as any)._finished = true;
613
+ clearTimeout(timeout);
614
+ if (err) {
615
+ reject(err);
616
+ } else {
617
+ resolve();
618
+ }
619
+ };
620
+
621
+ ws.once('error', err => {
622
+ finish(err instanceof Error ? err : new Error(String(err)));
623
+ });
624
+
625
+ ws.on('close', code => {
626
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
627
+ if (!(ws as any)._finished) {
628
+ finish(new Error(`WebSocket closed prematurely (code: ${code})`));
629
+ }
630
+ });
631
+
632
+ let requestSent = false;
633
+
634
+ ws.on('message', data => {
635
+ if (!(data instanceof Buffer)) return;
636
+ const message = ServerMessage.decode(data);
637
+
638
+ if (message.pingPong) {
639
+ ws.send(pongBuffer);
640
+ if (!requestSent) {
641
+ ws.send(requestBuffer);
642
+ requestSent = true;
643
+ }
644
+ return;
645
+ }
646
+
647
+ if (message.reply && message.uEchoResponse) {
648
+ if (message.uEchoResponse.message !== 'Echo: Hello via raw WS') {
649
+ finish(new Error(`Unexpected WebSocket echo response: ${message.uEchoResponse.message}`));
650
+ ws.close();
651
+ return;
652
+ }
653
+ ws.close(1000);
654
+ finish();
655
+ }
656
+ });
657
+
658
+ const timeout = setTimeout(() => {
659
+ ws.close();
660
+ finish(new Error('WebSocket SRPC test timed out'));
661
+ }, 5000);
662
+ });
663
+
664
+ this.logger.info(' ✓ Raw WebSocket echo request');
665
+ this.logger.info('[Test End] Raw WebSocket Client (backwards compatibility)');
666
+ }
667
+
668
+ private getServerSecret() {
669
+ const secret = this.appConfig.SRPC_AUTH_SECRET;
670
+ if (!secret) {
671
+ throw new Error('SRPC authentication secret is not configured in AppConfig');
672
+ }
673
+ return secret;
674
+ }
675
+
676
+ private async waitForEvent(predicate: () => boolean, timeoutMs: number, errorMessage: string) {
677
+ const deadline = Date.now() + timeoutMs;
678
+ while (Date.now() < deadline) {
679
+ if (predicate()) return;
680
+ await sleepSecs(0.05);
681
+ }
682
+ throw new Error(errorMessage);
683
+ }
684
+ }