blendsdk 5.33.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 (538) hide show
  1. package/README.md +125 -0
  2. package/dist/cmdline/cmdline.d.ts +144 -0
  3. package/dist/cmdline/cmdline.d.ts.map +1 -0
  4. package/dist/cmdline/cmdline.js +683 -0
  5. package/dist/cmdline/cmdline.js.map +1 -0
  6. package/dist/cmdline/errors.d.ts +105 -0
  7. package/dist/cmdline/errors.d.ts.map +1 -0
  8. package/dist/cmdline/errors.js +153 -0
  9. package/dist/cmdline/errors.js.map +1 -0
  10. package/dist/cmdline/index.d.ts +5 -0
  11. package/dist/cmdline/index.d.ts.map +1 -0
  12. package/dist/cmdline/index.js +5 -0
  13. package/dist/cmdline/index.js.map +1 -0
  14. package/dist/cmdline/types.d.ts +260 -0
  15. package/dist/cmdline/types.d.ts.map +1 -0
  16. package/dist/cmdline/types.js +9 -0
  17. package/dist/cmdline/types.js.map +1 -0
  18. package/dist/cmdline/validators.d.ts +28 -0
  19. package/dist/cmdline/validators.d.ts.map +1 -0
  20. package/dist/cmdline/validators.js +211 -0
  21. package/dist/cmdline/validators.js.map +1 -0
  22. package/dist/codegen/database/index.d.ts +3 -0
  23. package/dist/codegen/database/index.d.ts.map +1 -0
  24. package/dist/codegen/database/index.js +3 -0
  25. package/dist/codegen/database/index.js.map +1 -0
  26. package/dist/codegen/database/introspect/index.d.ts +3 -0
  27. package/dist/codegen/database/introspect/index.d.ts.map +1 -0
  28. package/dist/codegen/database/introspect/index.js +3 -0
  29. package/dist/codegen/database/introspect/index.js.map +1 -0
  30. package/dist/codegen/database/introspect/introspect-query.d.ts +2 -0
  31. package/dist/codegen/database/introspect/introspect-query.d.ts.map +1 -0
  32. package/dist/codegen/database/introspect/introspect-query.js +416 -0
  33. package/dist/codegen/database/introspect/introspect-query.js.map +1 -0
  34. package/dist/codegen/database/introspect/introspect-types.d.ts +45 -0
  35. package/dist/codegen/database/introspect/introspect-types.d.ts.map +1 -0
  36. package/dist/codegen/database/introspect/introspect-types.js +2 -0
  37. package/dist/codegen/database/introspect/introspect-types.js.map +1 -0
  38. package/dist/codegen/database/introspect/introspect.d.ts +21 -0
  39. package/dist/codegen/database/introspect/introspect.d.ts.map +1 -0
  40. package/dist/codegen/database/introspect/introspect.js +223 -0
  41. package/dist/codegen/database/introspect/introspect.js.map +1 -0
  42. package/dist/codegen/database/schema/check-constraint.d.ts +8 -0
  43. package/dist/codegen/database/schema/check-constraint.d.ts.map +1 -0
  44. package/dist/codegen/database/schema/check-constraint.js +12 -0
  45. package/dist/codegen/database/schema/check-constraint.js.map +1 -0
  46. package/dist/codegen/database/schema/column-schema.d.ts +7 -0
  47. package/dist/codegen/database/schema/column-schema.d.ts.map +1 -0
  48. package/dist/codegen/database/schema/column-schema.js +9 -0
  49. package/dist/codegen/database/schema/column-schema.js.map +1 -0
  50. package/dist/codegen/database/schema/constraint-base.d.ts +13 -0
  51. package/dist/codegen/database/schema/constraint-base.d.ts.map +1 -0
  52. package/dist/codegen/database/schema/constraint-base.js +32 -0
  53. package/dist/codegen/database/schema/constraint-base.js.map +1 -0
  54. package/dist/codegen/database/schema/database-schema.d.ts +19 -0
  55. package/dist/codegen/database/schema/database-schema.d.ts.map +1 -0
  56. package/dist/codegen/database/schema/database-schema.js +48 -0
  57. package/dist/codegen/database/schema/database-schema.js.map +1 -0
  58. package/dist/codegen/database/schema/dataobject-schema.d.ts +9 -0
  59. package/dist/codegen/database/schema/dataobject-schema.d.ts.map +1 -0
  60. package/dist/codegen/database/schema/dataobject-schema.js +18 -0
  61. package/dist/codegen/database/schema/dataobject-schema.js.map +1 -0
  62. package/dist/codegen/database/schema/fkey-constraints.d.ts +21 -0
  63. package/dist/codegen/database/schema/fkey-constraints.d.ts.map +1 -0
  64. package/dist/codegen/database/schema/fkey-constraints.js +58 -0
  65. package/dist/codegen/database/schema/fkey-constraints.js.map +1 -0
  66. package/dist/codegen/database/schema/index-constraint.d.ts +34 -0
  67. package/dist/codegen/database/schema/index-constraint.d.ts.map +1 -0
  68. package/dist/codegen/database/schema/index-constraint.js +79 -0
  69. package/dist/codegen/database/schema/index-constraint.js.map +1 -0
  70. package/dist/codegen/database/schema/index.d.ts +5 -0
  71. package/dist/codegen/database/schema/index.d.ts.map +1 -0
  72. package/dist/codegen/database/schema/index.js +5 -0
  73. package/dist/codegen/database/schema/index.js.map +1 -0
  74. package/dist/codegen/database/schema/primarykey-constraint.d.ts +4 -0
  75. package/dist/codegen/database/schema/primarykey-constraint.d.ts.map +1 -0
  76. package/dist/codegen/database/schema/primarykey-constraint.js +4 -0
  77. package/dist/codegen/database/schema/primarykey-constraint.js.map +1 -0
  78. package/dist/codegen/database/schema/relation-schema.d.ts +16 -0
  79. package/dist/codegen/database/schema/relation-schema.d.ts.map +1 -0
  80. package/dist/codegen/database/schema/relation-schema.js +32 -0
  81. package/dist/codegen/database/schema/relation-schema.js.map +1 -0
  82. package/dist/codegen/database/schema/table-column-schema.d.ts +59 -0
  83. package/dist/codegen/database/schema/table-column-schema.d.ts.map +1 -0
  84. package/dist/codegen/database/schema/table-column-schema.js +137 -0
  85. package/dist/codegen/database/schema/table-column-schema.js.map +1 -0
  86. package/dist/codegen/database/schema/table-schema.d.ts +48 -0
  87. package/dist/codegen/database/schema/table-schema.d.ts.map +1 -0
  88. package/dist/codegen/database/schema/table-schema.js +219 -0
  89. package/dist/codegen/database/schema/table-schema.js.map +1 -0
  90. package/dist/codegen/database/schema/types.d.ts +13 -0
  91. package/dist/codegen/database/schema/types.d.ts.map +1 -0
  92. package/dist/codegen/database/schema/types.js +175 -0
  93. package/dist/codegen/database/schema/types.js.map +1 -0
  94. package/dist/codegen/database/schema/unique-constraint.d.ts +4 -0
  95. package/dist/codegen/database/schema/unique-constraint.d.ts.map +1 -0
  96. package/dist/codegen/database/schema/unique-constraint.js +4 -0
  97. package/dist/codegen/database/schema/unique-constraint.js.map +1 -0
  98. package/dist/codegen/database/schema/view-schema.d.ts +14 -0
  99. package/dist/codegen/database/schema/view-schema.d.ts.map +1 -0
  100. package/dist/codegen/database/schema/view-schema.js +32 -0
  101. package/dist/codegen/database/schema/view-schema.js.map +1 -0
  102. package/dist/codegen/generator/ctype-generator.d.ts +5 -0
  103. package/dist/codegen/generator/ctype-generator.d.ts.map +1 -0
  104. package/dist/codegen/generator/ctype-generator.js +26 -0
  105. package/dist/codegen/generator/ctype-generator.js.map +1 -0
  106. package/dist/codegen/generator/generator.d.ts +17 -0
  107. package/dist/codegen/generator/generator.d.ts.map +1 -0
  108. package/dist/codegen/generator/generator.js +57 -0
  109. package/dist/codegen/generator/generator.js.map +1 -0
  110. package/dist/codegen/generator/index.d.ts +8 -0
  111. package/dist/codegen/generator/index.d.ts.map +1 -0
  112. package/dist/codegen/generator/index.js +8 -0
  113. package/dist/codegen/generator/index.js.map +1 -0
  114. package/dist/codegen/generator/openapi-generator.d.ts +239 -0
  115. package/dist/codegen/generator/openapi-generator.d.ts.map +1 -0
  116. package/dist/codegen/generator/openapi-generator.js +434 -0
  117. package/dist/codegen/generator/openapi-generator.js.map +1 -0
  118. package/dist/codegen/generator/openapi-types.d.ts +263 -0
  119. package/dist/codegen/generator/openapi-types.d.ts.map +1 -0
  120. package/dist/codegen/generator/openapi-types.js +11 -0
  121. package/dist/codegen/generator/openapi-types.js.map +1 -0
  122. package/dist/codegen/generator/postgres-schema-generator.d.ts +48 -0
  123. package/dist/codegen/generator/postgres-schema-generator.d.ts.map +1 -0
  124. package/dist/codegen/generator/postgres-schema-generator.js +339 -0
  125. package/dist/codegen/generator/postgres-schema-generator.js.map +1 -0
  126. package/dist/codegen/generator/type-generator.d.ts +113 -0
  127. package/dist/codegen/generator/type-generator.d.ts.map +1 -0
  128. package/dist/codegen/generator/type-generator.js +249 -0
  129. package/dist/codegen/generator/type-generator.js.map +1 -0
  130. package/dist/codegen/generator/zod-generator.d.ts +15 -0
  131. package/dist/codegen/generator/zod-generator.d.ts.map +1 -0
  132. package/dist/codegen/generator/zod-generator.js +86 -0
  133. package/dist/codegen/generator/zod-generator.js.map +1 -0
  134. package/dist/codegen/generator/zod-to-openapi.d.ts +69 -0
  135. package/dist/codegen/generator/zod-to-openapi.d.ts.map +1 -0
  136. package/dist/codegen/generator/zod-to-openapi.js +480 -0
  137. package/dist/codegen/generator/zod-to-openapi.js.map +1 -0
  138. package/dist/codegen/index.d.ts +4 -0
  139. package/dist/codegen/index.d.ts.map +1 -0
  140. package/dist/codegen/index.js +4 -0
  141. package/dist/codegen/index.js.map +1 -0
  142. package/dist/codegen/schema/any-schema.d.ts +6 -0
  143. package/dist/codegen/schema/any-schema.d.ts.map +1 -0
  144. package/dist/codegen/schema/any-schema.js +12 -0
  145. package/dist/codegen/schema/any-schema.js.map +1 -0
  146. package/dist/codegen/schema/boolean-schema.d.ts +6 -0
  147. package/dist/codegen/schema/boolean-schema.d.ts.map +1 -0
  148. package/dist/codegen/schema/boolean-schema.js +12 -0
  149. package/dist/codegen/schema/boolean-schema.js.map +1 -0
  150. package/dist/codegen/schema/date-schema.d.ts +6 -0
  151. package/dist/codegen/schema/date-schema.d.ts.map +1 -0
  152. package/dist/codegen/schema/date-schema.js +12 -0
  153. package/dist/codegen/schema/date-schema.js.map +1 -0
  154. package/dist/codegen/schema/index.d.ts +10 -0
  155. package/dist/codegen/schema/index.d.ts.map +1 -0
  156. package/dist/codegen/schema/index.js +10 -0
  157. package/dist/codegen/schema/index.js.map +1 -0
  158. package/dist/codegen/schema/object-schema.d.ts +10 -0
  159. package/dist/codegen/schema/object-schema.d.ts.map +1 -0
  160. package/dist/codegen/schema/object-schema.js +21 -0
  161. package/dist/codegen/schema/object-schema.js.map +1 -0
  162. package/dist/codegen/schema/primitive-schema.d.ts +20 -0
  163. package/dist/codegen/schema/primitive-schema.d.ts.map +1 -0
  164. package/dist/codegen/schema/primitive-schema.js +48 -0
  165. package/dist/codegen/schema/primitive-schema.js.map +1 -0
  166. package/dist/codegen/schema/ref-schema.d.ts +6 -0
  167. package/dist/codegen/schema/ref-schema.d.ts.map +1 -0
  168. package/dist/codegen/schema/ref-schema.js +11 -0
  169. package/dist/codegen/schema/ref-schema.js.map +1 -0
  170. package/dist/codegen/schema/schema-container.d.ts +14 -0
  171. package/dist/codegen/schema/schema-container.d.ts.map +1 -0
  172. package/dist/codegen/schema/schema-container.js +38 -0
  173. package/dist/codegen/schema/schema-container.js.map +1 -0
  174. package/dist/codegen/schema/schema-object.d.ts +42 -0
  175. package/dist/codegen/schema/schema-object.d.ts.map +1 -0
  176. package/dist/codegen/schema/schema-object.js +90 -0
  177. package/dist/codegen/schema/schema-object.js.map +1 -0
  178. package/dist/codegen/schema/schema-scope.d.ts +23 -0
  179. package/dist/codegen/schema/schema-scope.d.ts.map +1 -0
  180. package/dist/codegen/schema/schema-scope.js +67 -0
  181. package/dist/codegen/schema/schema-scope.js.map +1 -0
  182. package/dist/codegen/schema/utils.d.ts +17 -0
  183. package/dist/codegen/schema/utils.d.ts.map +1 -0
  184. package/dist/codegen/schema/utils.js +47 -0
  185. package/dist/codegen/schema/utils.js.map +1 -0
  186. package/dist/dbcore/crud-statement.d.ts +67 -0
  187. package/dist/dbcore/crud-statement.d.ts.map +1 -0
  188. package/dist/dbcore/crud-statement.js +75 -0
  189. package/dist/dbcore/crud-statement.js.map +1 -0
  190. package/dist/dbcore/database.d.ts +272 -0
  191. package/dist/dbcore/database.d.ts.map +1 -0
  192. package/dist/dbcore/database.js +53 -0
  193. package/dist/dbcore/database.js.map +1 -0
  194. package/dist/dbcore/dataservice-base.d.ts +18 -0
  195. package/dist/dbcore/dataservice-base.d.ts.map +1 -0
  196. package/dist/dbcore/dataservice-base.js +19 -0
  197. package/dist/dbcore/dataservice-base.js.map +1 -0
  198. package/dist/dbcore/delete-statement.d.ts +29 -0
  199. package/dist/dbcore/delete-statement.d.ts.map +1 -0
  200. package/dist/dbcore/delete-statement.js +30 -0
  201. package/dist/dbcore/delete-statement.js.map +1 -0
  202. package/dist/dbcore/filterable-statement.d.ts +126 -0
  203. package/dist/dbcore/filterable-statement.d.ts.map +1 -0
  204. package/dist/dbcore/filterable-statement.js +178 -0
  205. package/dist/dbcore/filterable-statement.js.map +1 -0
  206. package/dist/dbcore/from-statement.d.ts +120 -0
  207. package/dist/dbcore/from-statement.d.ts.map +1 -0
  208. package/dist/dbcore/from-statement.js +150 -0
  209. package/dist/dbcore/from-statement.js.map +1 -0
  210. package/dist/dbcore/index.d.ts +21 -0
  211. package/dist/dbcore/index.d.ts.map +1 -0
  212. package/dist/dbcore/index.js +21 -0
  213. package/dist/dbcore/index.js.map +1 -0
  214. package/dist/dbcore/insert-statement.d.ts +48 -0
  215. package/dist/dbcore/insert-statement.d.ts.map +1 -0
  216. package/dist/dbcore/insert-statement.js +52 -0
  217. package/dist/dbcore/insert-statement.js.map +1 -0
  218. package/dist/dbcore/query-dataservice.d.ts +144 -0
  219. package/dist/dbcore/query-dataservice.d.ts.map +1 -0
  220. package/dist/dbcore/query-dataservice.js +144 -0
  221. package/dist/dbcore/query-dataservice.js.map +1 -0
  222. package/dist/dbcore/statement.d.ts +133 -0
  223. package/dist/dbcore/statement.d.ts.map +1 -0
  224. package/dist/dbcore/statement.js +138 -0
  225. package/dist/dbcore/statement.js.map +1 -0
  226. package/dist/dbcore/update-statement.d.ts +48 -0
  227. package/dist/dbcore/update-statement.d.ts.map +1 -0
  228. package/dist/dbcore/update-statement.js +52 -0
  229. package/dist/dbcore/update-statement.js.map +1 -0
  230. package/dist/expression/builders/comparison-builder.d.ts +47 -0
  231. package/dist/expression/builders/comparison-builder.d.ts.map +1 -0
  232. package/dist/expression/builders/comparison-builder.js +197 -0
  233. package/dist/expression/builders/comparison-builder.js.map +1 -0
  234. package/dist/expression/builders/query-builder.d.ts +80 -0
  235. package/dist/expression/builders/query-builder.d.ts.map +1 -0
  236. package/dist/expression/builders/query-builder.js +229 -0
  237. package/dist/expression/builders/query-builder.js.map +1 -0
  238. package/dist/expression/compiler/postgresql-compiler.d.ts +56 -0
  239. package/dist/expression/compiler/postgresql-compiler.d.ts.map +1 -0
  240. package/dist/expression/compiler/postgresql-compiler.js +217 -0
  241. package/dist/expression/compiler/postgresql-compiler.js.map +1 -0
  242. package/dist/expression/core/ast-node.d.ts +47 -0
  243. package/dist/expression/core/ast-node.d.ts.map +1 -0
  244. package/dist/expression/core/ast-node.js +154 -0
  245. package/dist/expression/core/ast-node.js.map +1 -0
  246. package/dist/expression/core/parameter-manager.d.ts +84 -0
  247. package/dist/expression/core/parameter-manager.d.ts.map +1 -0
  248. package/dist/expression/core/parameter-manager.js +164 -0
  249. package/dist/expression/core/parameter-manager.js.map +1 -0
  250. package/dist/expression/core/query-builder-interfaces.d.ts +188 -0
  251. package/dist/expression/core/query-builder-interfaces.d.ts.map +1 -0
  252. package/dist/expression/core/query-builder-interfaces.js +6 -0
  253. package/dist/expression/core/query-builder-interfaces.js.map +1 -0
  254. package/dist/expression/core/types.d.ts +239 -0
  255. package/dist/expression/core/types.d.ts.map +1 -0
  256. package/dist/expression/core/types.js +121 -0
  257. package/dist/expression/core/types.js.map +1 -0
  258. package/dist/expression/index.d.ts +11 -0
  259. package/dist/expression/index.d.ts.map +1 -0
  260. package/dist/expression/index.js +11 -0
  261. package/dist/expression/index.js.map +1 -0
  262. package/dist/i18n/content-file-source.d.ts +109 -0
  263. package/dist/i18n/content-file-source.d.ts.map +1 -0
  264. package/dist/i18n/content-file-source.js +218 -0
  265. package/dist/i18n/content-file-source.js.map +1 -0
  266. package/dist/i18n/index.d.ts +19 -0
  267. package/dist/i18n/index.d.ts.map +1 -0
  268. package/dist/i18n/index.js +21 -0
  269. package/dist/i18n/index.js.map +1 -0
  270. package/dist/i18n/json-file-source.d.ts +96 -0
  271. package/dist/i18n/json-file-source.d.ts.map +1 -0
  272. package/dist/i18n/json-file-source.js +258 -0
  273. package/dist/i18n/json-file-source.js.map +1 -0
  274. package/dist/i18n/merge-catalogs.d.ts +20 -0
  275. package/dist/i18n/merge-catalogs.d.ts.map +1 -0
  276. package/dist/i18n/merge-catalogs.js +34 -0
  277. package/dist/i18n/merge-catalogs.js.map +1 -0
  278. package/dist/i18n/node.d.ts +20 -0
  279. package/dist/i18n/node.d.ts.map +1 -0
  280. package/dist/i18n/node.js +19 -0
  281. package/dist/i18n/node.js.map +1 -0
  282. package/dist/i18n/translation-source.d.ts +35 -0
  283. package/dist/i18n/translation-source.d.ts.map +1 -0
  284. package/dist/i18n/translation-source.js +2 -0
  285. package/dist/i18n/translation-source.js.map +1 -0
  286. package/dist/i18n/translator.d.ts +162 -0
  287. package/dist/i18n/translator.d.ts.map +1 -0
  288. package/dist/i18n/translator.js +259 -0
  289. package/dist/i18n/translator.js.map +1 -0
  290. package/dist/i18n/types.d.ts +80 -0
  291. package/dist/i18n/types.d.ts.map +1 -0
  292. package/dist/i18n/types.js +2 -0
  293. package/dist/i18n/types.js.map +1 -0
  294. package/dist/postgresql/database.d.ts +204 -0
  295. package/dist/postgresql/database.d.ts.map +1 -0
  296. package/dist/postgresql/database.js +321 -0
  297. package/dist/postgresql/database.js.map +1 -0
  298. package/dist/postgresql/delete-statement.d.ts +36 -0
  299. package/dist/postgresql/delete-statement.d.ts.map +1 -0
  300. package/dist/postgresql/delete-statement.js +54 -0
  301. package/dist/postgresql/delete-statement.js.map +1 -0
  302. package/dist/postgresql/index.d.ts +12 -0
  303. package/dist/postgresql/index.d.ts.map +1 -0
  304. package/dist/postgresql/index.js +12 -0
  305. package/dist/postgresql/index.js.map +1 -0
  306. package/dist/postgresql/insert-statement.d.ts +34 -0
  307. package/dist/postgresql/insert-statement.d.ts.map +1 -0
  308. package/dist/postgresql/insert-statement.js +48 -0
  309. package/dist/postgresql/insert-statement.js.map +1 -0
  310. package/dist/postgresql/update-statement.d.ts +38 -0
  311. package/dist/postgresql/update-statement.d.ts.map +1 -0
  312. package/dist/postgresql/update-statement.js +75 -0
  313. package/dist/postgresql/update-statement.js.map +1 -0
  314. package/dist/stdlib/formatString.d.ts +52 -0
  315. package/dist/stdlib/formatString.d.ts.map +1 -0
  316. package/dist/stdlib/formatString.js +118 -0
  317. package/dist/stdlib/formatString.js.map +1 -0
  318. package/dist/stdlib/index.d.ts +8 -0
  319. package/dist/stdlib/index.d.ts.map +1 -0
  320. package/dist/stdlib/index.js +8 -0
  321. package/dist/stdlib/index.js.map +1 -0
  322. package/dist/stdlib/isBoolean.d.ts +15 -0
  323. package/dist/stdlib/isBoolean.d.ts.map +1 -0
  324. package/dist/stdlib/isBoolean.js +17 -0
  325. package/dist/stdlib/isBoolean.js.map +1 -0
  326. package/dist/stdlib/isNullOrUndef.d.ts +24 -0
  327. package/dist/stdlib/isNullOrUndef.d.ts.map +1 -0
  328. package/dist/stdlib/isNullOrUndef.js +28 -0
  329. package/dist/stdlib/isNullOrUndef.js.map +1 -0
  330. package/dist/stdlib/isNumeric.d.ts +20 -0
  331. package/dist/stdlib/isNumeric.d.ts.map +1 -0
  332. package/dist/stdlib/isNumeric.js +39 -0
  333. package/dist/stdlib/isNumeric.js.map +1 -0
  334. package/dist/stdlib/isString.d.ts +15 -0
  335. package/dist/stdlib/isString.d.ts.map +1 -0
  336. package/dist/stdlib/isString.js +17 -0
  337. package/dist/stdlib/isString.js.map +1 -0
  338. package/dist/stdlib/isTemplateString.d.ts +18 -0
  339. package/dist/stdlib/isTemplateString.d.ts.map +1 -0
  340. package/dist/stdlib/isTemplateString.js +38 -0
  341. package/dist/stdlib/isTemplateString.js.map +1 -0
  342. package/dist/stdlib/wrapInArray.d.ts +14 -0
  343. package/dist/stdlib/wrapInArray.d.ts.map +1 -0
  344. package/dist/stdlib/wrapInArray.js +17 -0
  345. package/dist/stdlib/wrapInArray.js.map +1 -0
  346. package/dist/webafx/application/application-settings.d.ts +129 -0
  347. package/dist/webafx/application/application-settings.d.ts.map +1 -0
  348. package/dist/webafx/application/application-settings.js +162 -0
  349. package/dist/webafx/application/application-settings.js.map +1 -0
  350. package/dist/webafx/application/base-controller.d.ts +128 -0
  351. package/dist/webafx/application/base-controller.d.ts.map +1 -0
  352. package/dist/webafx/application/base-controller.js +122 -0
  353. package/dist/webafx/application/base-controller.js.map +1 -0
  354. package/dist/webafx/application/console-logger.d.ts +81 -0
  355. package/dist/webafx/application/console-logger.d.ts.map +1 -0
  356. package/dist/webafx/application/console-logger.js +111 -0
  357. package/dist/webafx/application/console-logger.js.map +1 -0
  358. package/dist/webafx/application/controller-registry.d.ts +34 -0
  359. package/dist/webafx/application/controller-registry.d.ts.map +1 -0
  360. package/dist/webafx/application/controller-registry.js +32 -0
  361. package/dist/webafx/application/controller-registry.js.map +1 -0
  362. package/dist/webafx/application/error-handler-middleware.d.ts +22 -0
  363. package/dist/webafx/application/error-handler-middleware.d.ts.map +1 -0
  364. package/dist/webafx/application/error-handler-middleware.js +70 -0
  365. package/dist/webafx/application/error-handler-middleware.js.map +1 -0
  366. package/dist/webafx/application/index.d.ts +13 -0
  367. package/dist/webafx/application/index.d.ts.map +1 -0
  368. package/dist/webafx/application/index.js +13 -0
  369. package/dist/webafx/application/index.js.map +1 -0
  370. package/dist/webafx/application/logger.d.ts +2 -0
  371. package/dist/webafx/application/logger.d.ts.map +1 -0
  372. package/dist/webafx/application/logger.js +2 -0
  373. package/dist/webafx/application/logger.js.map +1 -0
  374. package/dist/webafx/application/plugin.d.ts +73 -0
  375. package/dist/webafx/application/plugin.d.ts.map +1 -0
  376. package/dist/webafx/application/plugin.js +90 -0
  377. package/dist/webafx/application/plugin.js.map +1 -0
  378. package/dist/webafx/application/rate-limiter.d.ts +35 -0
  379. package/dist/webafx/application/rate-limiter.d.ts.map +1 -0
  380. package/dist/webafx/application/rate-limiter.js +74 -0
  381. package/dist/webafx/application/rate-limiter.js.map +1 -0
  382. package/dist/webafx/application/request-context.d.ts +62 -0
  383. package/dist/webafx/application/request-context.d.ts.map +1 -0
  384. package/dist/webafx/application/request-context.js +54 -0
  385. package/dist/webafx/application/request-context.js.map +1 -0
  386. package/dist/webafx/application/request-id-middleware.d.ts +30 -0
  387. package/dist/webafx/application/request-id-middleware.d.ts.map +1 -0
  388. package/dist/webafx/application/request-id-middleware.js +57 -0
  389. package/dist/webafx/application/request-id-middleware.js.map +1 -0
  390. package/dist/webafx/application/route-builder.d.ts +231 -0
  391. package/dist/webafx/application/route-builder.d.ts.map +1 -0
  392. package/dist/webafx/application/route-builder.js +182 -0
  393. package/dist/webafx/application/route-builder.js.map +1 -0
  394. package/dist/webafx/application/service-container.d.ts +144 -0
  395. package/dist/webafx/application/service-container.d.ts.map +1 -0
  396. package/dist/webafx/application/service-container.js +192 -0
  397. package/dist/webafx/application/service-container.js.map +1 -0
  398. package/dist/webafx/application/services.d.ts +27 -0
  399. package/dist/webafx/application/services.d.ts.map +1 -0
  400. package/dist/webafx/application/services.js +33 -0
  401. package/dist/webafx/application/services.js.map +1 -0
  402. package/dist/webafx/application/structured-logger.d.ts +99 -0
  403. package/dist/webafx/application/structured-logger.d.ts.map +1 -0
  404. package/dist/webafx/application/structured-logger.js +132 -0
  405. package/dist/webafx/application/structured-logger.js.map +1 -0
  406. package/dist/webafx/application/type.d.ts +29 -0
  407. package/dist/webafx/application/type.d.ts.map +1 -0
  408. package/dist/webafx/application/type.js +2 -0
  409. package/dist/webafx/application/type.js.map +1 -0
  410. package/dist/webafx/application/web-application.d.ts +257 -0
  411. package/dist/webafx/application/web-application.d.ts.map +1 -0
  412. package/dist/webafx/application/web-application.js +611 -0
  413. package/dist/webafx/application/web-application.js.map +1 -0
  414. package/dist/webafx/errors/api-error.d.ts +21 -0
  415. package/dist/webafx/errors/api-error.d.ts.map +1 -0
  416. package/dist/webafx/errors/api-error.js +38 -0
  417. package/dist/webafx/errors/api-error.js.map +1 -0
  418. package/dist/webafx/errors/http-errors.d.ts +56 -0
  419. package/dist/webafx/errors/http-errors.d.ts.map +1 -0
  420. package/dist/webafx/errors/http-errors.js +74 -0
  421. package/dist/webafx/errors/http-errors.js.map +1 -0
  422. package/dist/webafx/errors/index.d.ts +4 -0
  423. package/dist/webafx/errors/index.d.ts.map +1 -0
  424. package/dist/webafx/errors/index.js +4 -0
  425. package/dist/webafx/errors/index.js.map +1 -0
  426. package/dist/webafx/errors/types.d.ts +42 -0
  427. package/dist/webafx/errors/types.d.ts.map +1 -0
  428. package/dist/webafx/errors/types.js +2 -0
  429. package/dist/webafx/errors/types.js.map +1 -0
  430. package/dist/webafx/index.d.ts +3 -0
  431. package/dist/webafx/index.d.ts.map +1 -0
  432. package/dist/webafx/index.js +3 -0
  433. package/dist/webafx/index.js.map +1 -0
  434. package/dist/webafx-auth/abstract-auth-provider.d.ts +178 -0
  435. package/dist/webafx-auth/abstract-auth-provider.d.ts.map +1 -0
  436. package/dist/webafx-auth/abstract-auth-provider.js +240 -0
  437. package/dist/webafx-auth/abstract-auth-provider.js.map +1 -0
  438. package/dist/webafx-auth/index.d.ts +27 -0
  439. package/dist/webafx-auth/index.d.ts.map +1 -0
  440. package/dist/webafx-auth/index.js +32 -0
  441. package/dist/webafx-auth/index.js.map +1 -0
  442. package/dist/webafx-auth/jwt-auth-provider.d.ts +100 -0
  443. package/dist/webafx-auth/jwt-auth-provider.d.ts.map +1 -0
  444. package/dist/webafx-auth/jwt-auth-provider.js +154 -0
  445. package/dist/webafx-auth/jwt-auth-provider.js.map +1 -0
  446. package/dist/webafx-auth/memory-auth-provider.d.ts +100 -0
  447. package/dist/webafx-auth/memory-auth-provider.d.ts.map +1 -0
  448. package/dist/webafx-auth/memory-auth-provider.js +122 -0
  449. package/dist/webafx-auth/memory-auth-provider.js.map +1 -0
  450. package/dist/webafx-auth/types.d.ts +333 -0
  451. package/dist/webafx-auth/types.d.ts.map +1 -0
  452. package/dist/webafx-auth/types.js +24 -0
  453. package/dist/webafx-auth/types.js.map +1 -0
  454. package/dist/webafx-cache/abstract-cache-provider.d.ts +185 -0
  455. package/dist/webafx-cache/abstract-cache-provider.d.ts.map +1 -0
  456. package/dist/webafx-cache/abstract-cache-provider.js +133 -0
  457. package/dist/webafx-cache/abstract-cache-provider.js.map +1 -0
  458. package/dist/webafx-cache/abstract-pubsub-provider.d.ts +170 -0
  459. package/dist/webafx-cache/abstract-pubsub-provider.d.ts.map +1 -0
  460. package/dist/webafx-cache/abstract-pubsub-provider.js +132 -0
  461. package/dist/webafx-cache/abstract-pubsub-provider.js.map +1 -0
  462. package/dist/webafx-cache/cache-plugin.d.ts +114 -0
  463. package/dist/webafx-cache/cache-plugin.d.ts.map +1 -0
  464. package/dist/webafx-cache/cache-plugin.js +176 -0
  465. package/dist/webafx-cache/cache-plugin.js.map +1 -0
  466. package/dist/webafx-cache/index.d.ts +33 -0
  467. package/dist/webafx-cache/index.d.ts.map +1 -0
  468. package/dist/webafx-cache/index.js +44 -0
  469. package/dist/webafx-cache/index.js.map +1 -0
  470. package/dist/webafx-cache/memory-cache-provider.d.ts +99 -0
  471. package/dist/webafx-cache/memory-cache-provider.d.ts.map +1 -0
  472. package/dist/webafx-cache/memory-cache-provider.js +251 -0
  473. package/dist/webafx-cache/memory-cache-provider.js.map +1 -0
  474. package/dist/webafx-cache/memory-pubsub-provider.d.ts +124 -0
  475. package/dist/webafx-cache/memory-pubsub-provider.d.ts.map +1 -0
  476. package/dist/webafx-cache/memory-pubsub-provider.js +195 -0
  477. package/dist/webafx-cache/memory-pubsub-provider.js.map +1 -0
  478. package/dist/webafx-cache/pubsub-plugin.d.ts +128 -0
  479. package/dist/webafx-cache/pubsub-plugin.d.ts.map +1 -0
  480. package/dist/webafx-cache/pubsub-plugin.js +182 -0
  481. package/dist/webafx-cache/pubsub-plugin.js.map +1 -0
  482. package/dist/webafx-cache/redis-cache-provider.d.ts +81 -0
  483. package/dist/webafx-cache/redis-cache-provider.d.ts.map +1 -0
  484. package/dist/webafx-cache/redis-cache-provider.js +209 -0
  485. package/dist/webafx-cache/redis-cache-provider.js.map +1 -0
  486. package/dist/webafx-cache/redis-pubsub-provider.d.ts +164 -0
  487. package/dist/webafx-cache/redis-pubsub-provider.d.ts.map +1 -0
  488. package/dist/webafx-cache/redis-pubsub-provider.js +329 -0
  489. package/dist/webafx-cache/redis-pubsub-provider.js.map +1 -0
  490. package/dist/webafx-cache/types.d.ts +206 -0
  491. package/dist/webafx-cache/types.d.ts.map +1 -0
  492. package/dist/webafx-cache/types.js +27 -0
  493. package/dist/webafx-cache/types.js.map +1 -0
  494. package/dist/webafx-i18n/i18n-plugin.d.ts +29 -0
  495. package/dist/webafx-i18n/i18n-plugin.d.ts.map +1 -0
  496. package/dist/webafx-i18n/i18n-plugin.js +145 -0
  497. package/dist/webafx-i18n/i18n-plugin.js.map +1 -0
  498. package/dist/webafx-i18n/index.d.ts +12 -0
  499. package/dist/webafx-i18n/index.d.ts.map +1 -0
  500. package/dist/webafx-i18n/index.js +12 -0
  501. package/dist/webafx-i18n/index.js.map +1 -0
  502. package/dist/webafx-i18n/locale-resolver.d.ts +33 -0
  503. package/dist/webafx-i18n/locale-resolver.d.ts.map +1 -0
  504. package/dist/webafx-i18n/locale-resolver.js +67 -0
  505. package/dist/webafx-i18n/locale-resolver.js.map +1 -0
  506. package/dist/webafx-i18n/postgresql-source.d.ts +101 -0
  507. package/dist/webafx-i18n/postgresql-source.d.ts.map +1 -0
  508. package/dist/webafx-i18n/postgresql-source.js +101 -0
  509. package/dist/webafx-i18n/postgresql-source.js.map +1 -0
  510. package/dist/webafx-i18n/types.d.ts +70 -0
  511. package/dist/webafx-i18n/types.d.ts.map +1 -0
  512. package/dist/webafx-i18n/types.js +2 -0
  513. package/dist/webafx-i18n/types.js.map +1 -0
  514. package/dist/webafx-mailer/abstract-mail-provider.d.ts +55 -0
  515. package/dist/webafx-mailer/abstract-mail-provider.d.ts.map +1 -0
  516. package/dist/webafx-mailer/abstract-mail-provider.js +37 -0
  517. package/dist/webafx-mailer/abstract-mail-provider.js.map +1 -0
  518. package/dist/webafx-mailer/index.d.ts +24 -0
  519. package/dist/webafx-mailer/index.d.ts.map +1 -0
  520. package/dist/webafx-mailer/index.js +34 -0
  521. package/dist/webafx-mailer/index.js.map +1 -0
  522. package/dist/webafx-mailer/mail-plugin.d.ts +98 -0
  523. package/dist/webafx-mailer/mail-plugin.d.ts.map +1 -0
  524. package/dist/webafx-mailer/mail-plugin.js +155 -0
  525. package/dist/webafx-mailer/mail-plugin.js.map +1 -0
  526. package/dist/webafx-mailer/memory-mail-provider.d.ts +85 -0
  527. package/dist/webafx-mailer/memory-mail-provider.d.ts.map +1 -0
  528. package/dist/webafx-mailer/memory-mail-provider.js +111 -0
  529. package/dist/webafx-mailer/memory-mail-provider.js.map +1 -0
  530. package/dist/webafx-mailer/smtp-mail-provider.d.ts +65 -0
  531. package/dist/webafx-mailer/smtp-mail-provider.d.ts.map +1 -0
  532. package/dist/webafx-mailer/smtp-mail-provider.js +113 -0
  533. package/dist/webafx-mailer/smtp-mail-provider.js.map +1 -0
  534. package/dist/webafx-mailer/types.d.ts +136 -0
  535. package/dist/webafx-mailer/types.d.ts.map +1 -0
  536. package/dist/webafx-mailer/types.js +13 -0
  537. package/dist/webafx-mailer/types.js.map +1 -0
  538. package/package.json +159 -0
@@ -0,0 +1,164 @@
1
+ /**
2
+ * Redis-backed pub/sub provider using ioredis.
3
+ *
4
+ * Production-grade implementation with:
5
+ * - Two dedicated ioredis connections (publisher + subscriber)
6
+ * - Automatic JSON serialization/deserialization
7
+ * - Channel prefix support for namespace isolation
8
+ * - Multiple handlers per channel (fan-out)
9
+ * - Handler error isolation via safeInvoke
10
+ * - Connection health monitoring via PING on both connections
11
+ * - Graceful shutdown: unsubscribe all, then close both connections
12
+ *
13
+ * Redis pub/sub requires a dedicated connection for subscribing — once a
14
+ * client enters subscriber mode (SUBSCRIBE/PSUBSCRIBE), it can only execute
15
+ * subscriber commands. Regular commands like PUBLISH must use a separate connection.
16
+ *
17
+ * @packageDocumentation
18
+ */
19
+ import { Redis } from "ioredis";
20
+ import { PubSubProvider } from "./abstract-pubsub-provider.js";
21
+ import type { RedisPubSubConfig, MessageHandler } from "./types.js";
22
+ /**
23
+ * Redis-backed pub/sub provider using ioredis.
24
+ *
25
+ * Creates two ioredis connections:
26
+ * - `publisher` for PUBLISH commands
27
+ * - `subscriber` for SUBSCRIBE/PSUBSCRIBE (enters subscriber mode)
28
+ *
29
+ * Handler maps use user-facing channel names (without prefix) so that
30
+ * `activeSubscriptions()` returns clean names and handler lookup is simple.
31
+ * Redis subscribe/unsubscribe is only called on the first/last handler for
32
+ * a given channel — multiple in-process handlers share a single Redis subscription.
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * const pubsub = new RedisPubSubProvider({
37
+ * channelPrefix: 'MyApp',
38
+ * host: 'localhost',
39
+ * port: 6379,
40
+ * });
41
+ *
42
+ * await pubsub.subscribe<OrderEvent>('order:new', (msg) => {
43
+ * console.log('New order:', msg.data);
44
+ * });
45
+ *
46
+ * await pubsub.publish('order:new', { orderId: 123, total: 49.99 });
47
+ * await pubsub.shutdown();
48
+ * ```
49
+ */
50
+ export declare class RedisPubSubProvider extends PubSubProvider {
51
+ /** Dedicated connection for PUBLISH commands */
52
+ protected publisher: Redis;
53
+ /** Dedicated connection for SUBSCRIBE/PSUBSCRIBE (enters subscriber mode) */
54
+ protected subscriber: Redis;
55
+ /** Exact channel handlers: Map<userChannel, Set<MessageHandler>> */
56
+ protected handlers: Map<string, Set<MessageHandler>>;
57
+ /** Pattern handlers: Map<userPattern, Set<MessageHandler>> */
58
+ protected patternHandlers: Map<string, Set<MessageHandler>>;
59
+ /**
60
+ * Create a new Redis pub/sub provider.
61
+ *
62
+ * Two ioredis connections are created immediately and begin connecting
63
+ * in the background. The subscriber connection has ioredis message
64
+ * event listeners wired up for routing incoming messages to handlers.
65
+ *
66
+ * @param config - Redis pub/sub configuration with connection details
67
+ */
68
+ constructor(config: RedisPubSubConfig);
69
+ /**
70
+ * Publish a message to a channel.
71
+ *
72
+ * The data is JSON-serialized and sent via the publisher connection.
73
+ * The channel prefix is applied automatically.
74
+ *
75
+ * @param channel - Channel name (prefix applied automatically)
76
+ * @param data - Message payload (will be JSON-serialized)
77
+ * @returns Number of Redis subscribers that received the message
78
+ */
79
+ publish<T>(channel: string, data: T): Promise<number>;
80
+ /**
81
+ * Subscribe to an exact channel with a typed handler.
82
+ *
83
+ * Multiple handlers can be registered for the same channel.
84
+ * The Redis SUBSCRIBE command is only sent on the first handler
85
+ * registration for a channel — subsequent handlers share the
86
+ * same Redis subscription.
87
+ *
88
+ * @param channel - Exact channel name (prefix applied automatically)
89
+ * @param handler - Function called when a message is received
90
+ */
91
+ subscribe<T = unknown>(channel: string, handler: MessageHandler<T>): Promise<void>;
92
+ /**
93
+ * Unsubscribe from an exact channel.
94
+ * Removes all handlers and unsubscribes from Redis.
95
+ *
96
+ * @param channel - Channel name to unsubscribe from
97
+ */
98
+ unsubscribe(channel: string): Promise<void>;
99
+ /**
100
+ * Subscribe to a channel pattern with a typed handler.
101
+ *
102
+ * Multiple handlers can be registered for the same pattern.
103
+ * The Redis PSUBSCRIBE command is only sent on the first handler
104
+ * registration for a pattern.
105
+ *
106
+ * @param pattern - Glob pattern (e.g., 'order:*')
107
+ * @param handler - Function called when a matching message is received
108
+ */
109
+ psubscribe<T = unknown>(pattern: string, handler: MessageHandler<T>): Promise<void>;
110
+ /**
111
+ * Unsubscribe from a channel pattern.
112
+ * Removes all handlers and unsubscribes from Redis.
113
+ *
114
+ * @param pattern - Pattern to unsubscribe from
115
+ */
116
+ punsubscribe(pattern: string): Promise<void>;
117
+ /**
118
+ * Get currently active subscriptions.
119
+ * Returns user-facing channel/pattern names (without prefix).
120
+ *
121
+ * @returns Object with exact `channels` and glob `patterns` arrays
122
+ */
123
+ activeSubscriptions(): {
124
+ channels: string[];
125
+ patterns: string[];
126
+ };
127
+ /**
128
+ * Health check — pings both publisher and subscriber connections.
129
+ * Returns true only if both connections respond with PONG.
130
+ */
131
+ health(): Promise<boolean>;
132
+ /**
133
+ * Graceful shutdown — unsubscribe all, clear handlers, close both connections.
134
+ *
135
+ * Unsubscribes from all channels and patterns before closing to ensure
136
+ * clean disconnection. Both connections are closed via quit() which
137
+ * waits for pending commands to complete.
138
+ */
139
+ shutdown(): Promise<void>;
140
+ /**
141
+ * Create an ioredis client from config.
142
+ *
143
+ * URL takes precedence over individual host/port/password/db settings.
144
+ * This is the same pattern used by RedisCacheProvider.
145
+ *
146
+ * @param config - Redis connection configuration
147
+ * @returns A new ioredis Redis client
148
+ */
149
+ protected createRedisClient(config: RedisPubSubConfig): Redis;
150
+ /**
151
+ * Wire up ioredis event listeners on the subscriber connection.
152
+ *
153
+ * ioredis emits two events for pub/sub messages:
154
+ * - `message(channel, message)` for exact channel subscriptions
155
+ * - `pmessage(pattern, channel, message)` for pattern subscriptions
156
+ *
157
+ * This method sets up listeners that:
158
+ * 1. Strip the channel prefix from the full Redis channel name
159
+ * 2. JSON-deserialize the message payload
160
+ * 3. Fan out to all registered handlers via safeInvoke
161
+ */
162
+ protected setupMessageHandlers(): void;
163
+ }
164
+ //# sourceMappingURL=redis-pubsub-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-pubsub-provider.d.ts","sourceRoot":"","sources":["../src/redis-pubsub-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAiB,MAAM,YAAY,CAAC;AAyBnF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,mBAAoB,SAAQ,cAAc;IACnD,gDAAgD;IAChD,SAAS,CAAC,SAAS,EAAE,KAAK,CAAC;IAE3B,6EAA6E;IAC7E,SAAS,CAAC,UAAU,EAAE,KAAK,CAAC;IAE5B,oEAAoE;IACpE,SAAS,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC;IAErD,8DAA8D;IAC9D,SAAS,CAAC,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC;IAE5D;;;;;;;;OAQG;gBACS,MAAM,EAAE,iBAAiB;IAkBrC;;;;;;;;;OASG;IACG,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAO3D;;;;;;;;;;OAUG;IACG,SAAS,CAAC,CAAC,GAAG,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAcxF;;;;;OAKG;IACG,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMjD;;;;;;;;;OASG;IACG,UAAU,CAAC,CAAC,GAAG,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAazF;;;;;OAKG;IACG,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMlD;;;;;OAKG;IACH,mBAAmB,IAAI;QAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;KAAE;IAWjE;;;OAGG;IACG,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;IAYhC;;;;;;OAMG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAyB/B;;;;;;;;OAQG;IACH,SAAS,CAAC,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,KAAK;IAyB7D;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,oBAAoB,IAAI,IAAI;CAsDzC"}
@@ -0,0 +1,329 @@
1
+ /**
2
+ * Redis-backed pub/sub provider using ioredis.
3
+ *
4
+ * Production-grade implementation with:
5
+ * - Two dedicated ioredis connections (publisher + subscriber)
6
+ * - Automatic JSON serialization/deserialization
7
+ * - Channel prefix support for namespace isolation
8
+ * - Multiple handlers per channel (fan-out)
9
+ * - Handler error isolation via safeInvoke
10
+ * - Connection health monitoring via PING on both connections
11
+ * - Graceful shutdown: unsubscribe all, then close both connections
12
+ *
13
+ * Redis pub/sub requires a dedicated connection for subscribing — once a
14
+ * client enters subscriber mode (SUBSCRIBE/PSUBSCRIBE), it can only execute
15
+ * subscriber commands. Regular commands like PUBLISH must use a separate connection.
16
+ *
17
+ * @packageDocumentation
18
+ */
19
+ import { Redis } from "ioredis";
20
+ import { PubSubProvider } from "./abstract-pubsub-provider.js";
21
+ // ---------------------------------------------------------------------------
22
+ // Default Constants
23
+ // ---------------------------------------------------------------------------
24
+ /** Default connection timeout in milliseconds */
25
+ const DEFAULT_CONNECT_TIMEOUT = 5000;
26
+ /** Default max retries per request */
27
+ const DEFAULT_MAX_RETRIES = 3;
28
+ /** Default Redis host */
29
+ const DEFAULT_HOST = "localhost";
30
+ /** Default Redis port */
31
+ const DEFAULT_PORT = 6379;
32
+ /** Default Redis database index */
33
+ const DEFAULT_DB = 0;
34
+ // ---------------------------------------------------------------------------
35
+ // RedisPubSubProvider
36
+ // ---------------------------------------------------------------------------
37
+ /**
38
+ * Redis-backed pub/sub provider using ioredis.
39
+ *
40
+ * Creates two ioredis connections:
41
+ * - `publisher` for PUBLISH commands
42
+ * - `subscriber` for SUBSCRIBE/PSUBSCRIBE (enters subscriber mode)
43
+ *
44
+ * Handler maps use user-facing channel names (without prefix) so that
45
+ * `activeSubscriptions()` returns clean names and handler lookup is simple.
46
+ * Redis subscribe/unsubscribe is only called on the first/last handler for
47
+ * a given channel — multiple in-process handlers share a single Redis subscription.
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * const pubsub = new RedisPubSubProvider({
52
+ * channelPrefix: 'MyApp',
53
+ * host: 'localhost',
54
+ * port: 6379,
55
+ * });
56
+ *
57
+ * await pubsub.subscribe<OrderEvent>('order:new', (msg) => {
58
+ * console.log('New order:', msg.data);
59
+ * });
60
+ *
61
+ * await pubsub.publish('order:new', { orderId: 123, total: 49.99 });
62
+ * await pubsub.shutdown();
63
+ * ```
64
+ */
65
+ export class RedisPubSubProvider extends PubSubProvider {
66
+ /** Dedicated connection for PUBLISH commands */
67
+ publisher;
68
+ /** Dedicated connection for SUBSCRIBE/PSUBSCRIBE (enters subscriber mode) */
69
+ subscriber;
70
+ /** Exact channel handlers: Map<userChannel, Set<MessageHandler>> */
71
+ handlers;
72
+ /** Pattern handlers: Map<userPattern, Set<MessageHandler>> */
73
+ patternHandlers;
74
+ /**
75
+ * Create a new Redis pub/sub provider.
76
+ *
77
+ * Two ioredis connections are created immediately and begin connecting
78
+ * in the background. The subscriber connection has ioredis message
79
+ * event listeners wired up for routing incoming messages to handlers.
80
+ *
81
+ * @param config - Redis pub/sub configuration with connection details
82
+ */
83
+ constructor(config) {
84
+ super(config);
85
+ // Create TWO connections with the same Redis config
86
+ this.publisher = this.createRedisClient(config);
87
+ this.subscriber = this.createRedisClient(config);
88
+ this.handlers = new Map();
89
+ this.patternHandlers = new Map();
90
+ // Wire up ioredis message events for routing to handlers
91
+ this.setupMessageHandlers();
92
+ }
93
+ // -------------------------------------------------------------------
94
+ // Core Operations
95
+ // -------------------------------------------------------------------
96
+ /**
97
+ * Publish a message to a channel.
98
+ *
99
+ * The data is JSON-serialized and sent via the publisher connection.
100
+ * The channel prefix is applied automatically.
101
+ *
102
+ * @param channel - Channel name (prefix applied automatically)
103
+ * @param data - Message payload (will be JSON-serialized)
104
+ * @returns Number of Redis subscribers that received the message
105
+ */
106
+ async publish(channel, data) {
107
+ const fullChannel = this.buildChannel(channel);
108
+ const serialized = JSON.stringify(data);
109
+ // PUBLISH returns the number of clients that received the message
110
+ return await this.publisher.publish(fullChannel, serialized);
111
+ }
112
+ /**
113
+ * Subscribe to an exact channel with a typed handler.
114
+ *
115
+ * Multiple handlers can be registered for the same channel.
116
+ * The Redis SUBSCRIBE command is only sent on the first handler
117
+ * registration for a channel — subsequent handlers share the
118
+ * same Redis subscription.
119
+ *
120
+ * @param channel - Exact channel name (prefix applied automatically)
121
+ * @param handler - Function called when a message is received
122
+ */
123
+ async subscribe(channel, handler) {
124
+ // Add handler to local map
125
+ if (!this.handlers.has(channel)) {
126
+ this.handlers.set(channel, new Set());
127
+ }
128
+ this.handlers.get(channel).add(handler);
129
+ // Only subscribe to Redis on the first handler for this channel
130
+ if (this.handlers.get(channel).size === 1) {
131
+ const fullChannel = this.buildChannel(channel);
132
+ await this.subscriber.subscribe(fullChannel);
133
+ }
134
+ }
135
+ /**
136
+ * Unsubscribe from an exact channel.
137
+ * Removes all handlers and unsubscribes from Redis.
138
+ *
139
+ * @param channel - Channel name to unsubscribe from
140
+ */
141
+ async unsubscribe(channel) {
142
+ const fullChannel = this.buildChannel(channel);
143
+ await this.subscriber.unsubscribe(fullChannel);
144
+ this.handlers.delete(channel);
145
+ }
146
+ /**
147
+ * Subscribe to a channel pattern with a typed handler.
148
+ *
149
+ * Multiple handlers can be registered for the same pattern.
150
+ * The Redis PSUBSCRIBE command is only sent on the first handler
151
+ * registration for a pattern.
152
+ *
153
+ * @param pattern - Glob pattern (e.g., 'order:*')
154
+ * @param handler - Function called when a matching message is received
155
+ */
156
+ async psubscribe(pattern, handler) {
157
+ if (!this.patternHandlers.has(pattern)) {
158
+ this.patternHandlers.set(pattern, new Set());
159
+ }
160
+ this.patternHandlers.get(pattern).add(handler);
161
+ // Only psubscribe to Redis on the first handler for this pattern
162
+ if (this.patternHandlers.get(pattern).size === 1) {
163
+ const fullPattern = this.buildChannelPattern(pattern);
164
+ await this.subscriber.psubscribe(fullPattern);
165
+ }
166
+ }
167
+ /**
168
+ * Unsubscribe from a channel pattern.
169
+ * Removes all handlers and unsubscribes from Redis.
170
+ *
171
+ * @param pattern - Pattern to unsubscribe from
172
+ */
173
+ async punsubscribe(pattern) {
174
+ const fullPattern = this.buildChannelPattern(pattern);
175
+ await this.subscriber.punsubscribe(fullPattern);
176
+ this.patternHandlers.delete(pattern);
177
+ }
178
+ /**
179
+ * Get currently active subscriptions.
180
+ * Returns user-facing channel/pattern names (without prefix).
181
+ *
182
+ * @returns Object with exact `channels` and glob `patterns` arrays
183
+ */
184
+ activeSubscriptions() {
185
+ return {
186
+ channels: Array.from(this.handlers.keys()),
187
+ patterns: Array.from(this.patternHandlers.keys()),
188
+ };
189
+ }
190
+ // -------------------------------------------------------------------
191
+ // Lifecycle
192
+ // -------------------------------------------------------------------
193
+ /**
194
+ * Health check — pings both publisher and subscriber connections.
195
+ * Returns true only if both connections respond with PONG.
196
+ */
197
+ async health() {
198
+ try {
199
+ const [pubResult, subResult] = await Promise.all([
200
+ this.publisher.ping(),
201
+ this.subscriber.ping(),
202
+ ]);
203
+ return pubResult === "PONG" && subResult === "PONG";
204
+ }
205
+ catch {
206
+ return false;
207
+ }
208
+ }
209
+ /**
210
+ * Graceful shutdown — unsubscribe all, clear handlers, close both connections.
211
+ *
212
+ * Unsubscribes from all channels and patterns before closing to ensure
213
+ * clean disconnection. Both connections are closed via quit() which
214
+ * waits for pending commands to complete.
215
+ */
216
+ async shutdown() {
217
+ // Unsubscribe all exact channels
218
+ for (const channel of this.handlers.keys()) {
219
+ const fullChannel = this.buildChannel(channel);
220
+ await this.subscriber.unsubscribe(fullChannel);
221
+ }
222
+ // Unsubscribe all patterns
223
+ for (const pattern of this.patternHandlers.keys()) {
224
+ const fullPattern = this.buildChannelPattern(pattern);
225
+ await this.subscriber.punsubscribe(fullPattern);
226
+ }
227
+ // Clear all handler maps
228
+ this.handlers.clear();
229
+ this.patternHandlers.clear();
230
+ // Close both connections gracefully — waits for pending commands
231
+ await Promise.all([this.publisher.quit(), this.subscriber.quit()]);
232
+ }
233
+ // -------------------------------------------------------------------
234
+ // Internal: Redis Client Factory
235
+ // -------------------------------------------------------------------
236
+ /**
237
+ * Create an ioredis client from config.
238
+ *
239
+ * URL takes precedence over individual host/port/password/db settings.
240
+ * This is the same pattern used by RedisCacheProvider.
241
+ *
242
+ * @param config - Redis connection configuration
243
+ * @returns A new ioredis Redis client
244
+ */
245
+ createRedisClient(config) {
246
+ if (config.url) {
247
+ // URL-based connection — pass additional options alongside
248
+ return new Redis(config.url, {
249
+ db: config.db,
250
+ connectTimeout: config.connectTimeout ?? DEFAULT_CONNECT_TIMEOUT,
251
+ maxRetriesPerRequest: config.maxRetriesPerRequest ?? DEFAULT_MAX_RETRIES,
252
+ });
253
+ }
254
+ // Individual field connection
255
+ return new Redis({
256
+ host: config.host ?? DEFAULT_HOST,
257
+ port: config.port ?? DEFAULT_PORT,
258
+ password: config.password,
259
+ db: config.db ?? DEFAULT_DB,
260
+ connectTimeout: config.connectTimeout ?? DEFAULT_CONNECT_TIMEOUT,
261
+ maxRetriesPerRequest: config.maxRetriesPerRequest ?? DEFAULT_MAX_RETRIES,
262
+ });
263
+ }
264
+ // -------------------------------------------------------------------
265
+ // Internal: Message Routing
266
+ // -------------------------------------------------------------------
267
+ /**
268
+ * Wire up ioredis event listeners on the subscriber connection.
269
+ *
270
+ * ioredis emits two events for pub/sub messages:
271
+ * - `message(channel, message)` for exact channel subscriptions
272
+ * - `pmessage(pattern, channel, message)` for pattern subscriptions
273
+ *
274
+ * This method sets up listeners that:
275
+ * 1. Strip the channel prefix from the full Redis channel name
276
+ * 2. JSON-deserialize the message payload
277
+ * 3. Fan out to all registered handlers via safeInvoke
278
+ */
279
+ setupMessageHandlers() {
280
+ // Handle exact channel messages (from SUBSCRIBE)
281
+ this.subscriber.on("message", (fullChannel, message) => {
282
+ const userChannel = this.stripPrefix(fullChannel);
283
+ const handlers = this.handlers.get(userChannel);
284
+ if (!handlers || handlers.size === 0)
285
+ return;
286
+ // Deserialize the JSON payload
287
+ let data;
288
+ try {
289
+ data = JSON.parse(message);
290
+ }
291
+ catch {
292
+ console.error(`[PubSub] Failed to parse message on "${userChannel}"`);
293
+ return;
294
+ }
295
+ const envelope = { channel: userChannel, data };
296
+ // Fan out to all handlers — errors isolated per handler
297
+ for (const handler of handlers) {
298
+ void this.safeInvoke(handler, envelope);
299
+ }
300
+ });
301
+ // Handle pattern messages (from PSUBSCRIBE)
302
+ this.subscriber.on("pmessage", (fullPattern, fullChannel, message) => {
303
+ const userChannel = this.stripPrefix(fullChannel);
304
+ const userPattern = this.stripPrefix(fullPattern);
305
+ const handlers = this.patternHandlers.get(userPattern);
306
+ if (!handlers || handlers.size === 0)
307
+ return;
308
+ // Deserialize the JSON payload
309
+ let data;
310
+ try {
311
+ data = JSON.parse(message);
312
+ }
313
+ catch {
314
+ console.error(`[PubSub] Failed to parse message on "${userChannel}" (pattern: "${userPattern}")`);
315
+ return;
316
+ }
317
+ const envelope = {
318
+ channel: userChannel,
319
+ data,
320
+ pattern: userPattern,
321
+ };
322
+ // Fan out to all handlers — errors isolated per handler
323
+ for (const handler of handlers) {
324
+ void this.safeInvoke(handler, envelope);
325
+ }
326
+ });
327
+ }
328
+ }
329
+ //# sourceMappingURL=redis-pubsub-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-pubsub-provider.js","sourceRoot":"","sources":["../src/redis-pubsub-provider.ts"],"names":[],"mappings":"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"}