@vandenberghinc/volt 1.2.5 → 1.2.6

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 (489) hide show
  1. package/frontend/assets/admin/admin.png +0 -0
  2. package/frontend/assets/admin/password.webp +0 -0
  3. package/frontend/assets/icons/arrow.v1.webp +0 -0
  4. package/frontend/assets/icons/copy.webp +0 -0
  5. package/frontend/assets/payments/arrow.long.webp +0 -0
  6. package/frontend/assets/payments/arrow.long2.webp +0 -0
  7. package/frontend/assets/payments/cancelled.webp +0 -0
  8. package/frontend/assets/payments/check.sign.webp +0 -0
  9. package/frontend/assets/payments/check.webp +0 -0
  10. package/frontend/assets/payments/close.webp +0 -0
  11. package/frontend/assets/payments/error.webp +0 -0
  12. package/frontend/assets/payments/exclamation.webp +0 -0
  13. package/frontend/assets/payments/minus.webp +0 -0
  14. package/frontend/assets/payments/party.webp +0 -0
  15. package/frontend/assets/payments/plus.webp +0 -0
  16. package/frontend/assets/payments/shopping_cart.webp +0 -0
  17. package/frontend/assets/payments/trash.webp +0 -0
  18. package/package.json +5 -1
  19. package/.libris/config.json +0 -82
  20. package/backend/dist/cjs/backend/src/blacklist.d.ts +0 -12
  21. package/backend/dist/cjs/backend/src/blacklist.js +0 -78
  22. package/backend/dist/cjs/backend/src/cli.d.ts +0 -2
  23. package/backend/dist/cjs/backend/src/cli.js +0 -198
  24. package/backend/dist/cjs/backend/src/database/collection.d.ts +0 -1765
  25. package/backend/dist/cjs/backend/src/database/collection.js +0 -3301
  26. package/backend/dist/cjs/backend/src/database/database.d.ts +0 -92
  27. package/backend/dist/cjs/backend/src/database/database.js +0 -170
  28. package/backend/dist/cjs/backend/src/database/document.d.ts +0 -1
  29. package/backend/dist/cjs/backend/src/database/document.js +0 -15
  30. package/backend/dist/cjs/backend/src/database/filters/filters.d.ts +0 -6
  31. package/backend/dist/cjs/backend/src/database/filters/filters.js +0 -15
  32. package/backend/dist/cjs/backend/src/database/filters/strict_filter.d.ts +0 -223
  33. package/backend/dist/cjs/backend/src/database/filters/strict_filter.js +0 -15
  34. package/backend/dist/cjs/backend/src/database/filters/strict_filter_test.d.ts +0 -1
  35. package/backend/dist/cjs/backend/src/database/filters/strict_filter_test.js +0 -443
  36. package/backend/dist/cjs/backend/src/database/filters/strict_filter_test_v0.d.ts +0 -1
  37. package/backend/dist/cjs/backend/src/database/filters/strict_filter_test_v0.js +0 -15
  38. package/backend/dist/cjs/backend/src/database/filters/strict_filter_v0.d.ts +0 -50
  39. package/backend/dist/cjs/backend/src/database/filters/strict_filter_v0.js +0 -15
  40. package/backend/dist/cjs/backend/src/database/filters/strict_filter_v1.d.ts +0 -76
  41. package/backend/dist/cjs/backend/src/database/filters/strict_filter_v1.js +0 -15
  42. package/backend/dist/cjs/backend/src/database/filters/strict_filter_v2.d.ts +0 -75
  43. package/backend/dist/cjs/backend/src/database/filters/strict_filter_v2.js +0 -15
  44. package/backend/dist/cjs/backend/src/database/filters/strict_filter_v3.d.ts +0 -219
  45. package/backend/dist/cjs/backend/src/database/filters/strict_filter_v3.js +0 -15
  46. package/backend/dist/cjs/backend/src/database/filters/strict_update_filter.d.ts +0 -165
  47. package/backend/dist/cjs/backend/src/database/filters/strict_update_filter.js +0 -15
  48. package/backend/dist/cjs/backend/src/database/filters/strict_update_filter_test.d.ts +0 -5
  49. package/backend/dist/cjs/backend/src/database/filters/strict_update_filter_test.js +0 -355
  50. package/backend/dist/cjs/backend/src/database/flatten.d.ts +0 -78
  51. package/backend/dist/cjs/backend/src/database/flatten.js +0 -53
  52. package/backend/dist/cjs/backend/src/database/flatten_test.d.ts +0 -1
  53. package/backend/dist/cjs/backend/src/database/flatten_test.js +0 -175
  54. package/backend/dist/cjs/backend/src/database/quota/quoata_v2.d.ts +0 -533
  55. package/backend/dist/cjs/backend/src/database/quota/quoata_v2.js +0 -1046
  56. package/backend/dist/cjs/backend/src/database/quota/quota.d.ts +0 -551
  57. package/backend/dist/cjs/backend/src/database/quota/quota.js +0 -1108
  58. package/backend/dist/cjs/backend/src/database/quota/quota_v1.d.ts +0 -534
  59. package/backend/dist/cjs/backend/src/database/quota/quota_v1.js +0 -1087
  60. package/backend/dist/cjs/backend/src/database/quota/safe_int.d.ts +0 -412
  61. package/backend/dist/cjs/backend/src/database/quota/safe_int.js +0 -745
  62. package/backend/dist/cjs/backend/src/endpoint.d.ts +0 -346
  63. package/backend/dist/cjs/backend/src/endpoint.js +0 -468
  64. package/backend/dist/cjs/backend/src/errors/index.d.ts +0 -7
  65. package/backend/dist/cjs/backend/src/errors/index.js +0 -25
  66. package/backend/dist/cjs/backend/src/errors/internal_external.d.ts +0 -52
  67. package/backend/dist/cjs/backend/src/errors/internal_external.js +0 -95
  68. package/backend/dist/cjs/backend/src/errors/invalid_usage_error.d.ts +0 -41
  69. package/backend/dist/cjs/backend/src/errors/invalid_usage_error.js +0 -47
  70. package/backend/dist/cjs/backend/src/errors/system_error.d.ts +0 -261
  71. package/backend/dist/cjs/backend/src/errors/system_error.js +0 -436
  72. package/backend/dist/cjs/backend/src/events.d.ts +0 -97
  73. package/backend/dist/cjs/backend/src/events.js +0 -15
  74. package/backend/dist/cjs/backend/src/frontend.d.ts +0 -11
  75. package/backend/dist/cjs/backend/src/frontend.js +0 -37
  76. package/backend/dist/cjs/backend/src/image_endpoint.d.ts +0 -44
  77. package/backend/dist/cjs/backend/src/image_endpoint.js +0 -185
  78. package/backend/dist/cjs/backend/src/index.d.ts +0 -23
  79. package/backend/dist/cjs/backend/src/index.js +0 -70
  80. package/backend/dist/cjs/backend/src/logger.d.ts +0 -5
  81. package/backend/dist/cjs/backend/src/logger.js +0 -15
  82. package/backend/dist/cjs/backend/src/meta.d.ts +0 -112
  83. package/backend/dist/cjs/backend/src/meta.js +0 -181
  84. package/backend/dist/cjs/backend/src/payments/paddle.d.ts +0 -329
  85. package/backend/dist/cjs/backend/src/payments/paddle.js +0 -1996
  86. package/backend/dist/cjs/backend/src/payments/stripe/checkout.d.ts +0 -113
  87. package/backend/dist/cjs/backend/src/payments/stripe/checkout.js +0 -295
  88. package/backend/dist/cjs/backend/src/payments/stripe/customers.d.ts +0 -17
  89. package/backend/dist/cjs/backend/src/payments/stripe/customers.js +0 -164
  90. package/backend/dist/cjs/backend/src/payments/stripe/error.d.ts +0 -74
  91. package/backend/dist/cjs/backend/src/payments/stripe/error.js +0 -64
  92. package/backend/dist/cjs/backend/src/payments/stripe/events.d.ts +0 -155
  93. package/backend/dist/cjs/backend/src/payments/stripe/events.js +0 -15
  94. package/backend/dist/cjs/backend/src/payments/stripe/meters.d.ts +0 -105
  95. package/backend/dist/cjs/backend/src/payments/stripe/meters.js +0 -230
  96. package/backend/dist/cjs/backend/src/payments/stripe/payment_methods.d.ts +0 -58
  97. package/backend/dist/cjs/backend/src/payments/stripe/payment_methods.js +0 -109
  98. package/backend/dist/cjs/backend/src/payments/stripe/products.d.ts +0 -519
  99. package/backend/dist/cjs/backend/src/payments/stripe/products.js +0 -650
  100. package/backend/dist/cjs/backend/src/payments/stripe/stripe.d.ts +0 -215
  101. package/backend/dist/cjs/backend/src/payments/stripe/stripe.js +0 -468
  102. package/backend/dist/cjs/backend/src/payments/stripe/subscriptions.d.ts +0 -172
  103. package/backend/dist/cjs/backend/src/payments/stripe/subscriptions.js +0 -557
  104. package/backend/dist/cjs/backend/src/payments/stripe/utils.d.ts +0 -63
  105. package/backend/dist/cjs/backend/src/payments/stripe/utils.js +0 -118
  106. package/backend/dist/cjs/backend/src/payments/stripe/webhooks.d.ts +0 -105
  107. package/backend/dist/cjs/backend/src/payments/stripe/webhooks.js +0 -627
  108. package/backend/dist/cjs/backend/src/plugins/browser.d.ts +0 -1
  109. package/backend/dist/cjs/backend/src/plugins/browser.js +0 -15
  110. package/backend/dist/cjs/backend/src/plugins/communication.d.ts +0 -70
  111. package/backend/dist/cjs/backend/src/plugins/communication.js +0 -196
  112. package/backend/dist/cjs/backend/src/plugins/mail/mail.d.ts +0 -255
  113. package/backend/dist/cjs/backend/src/plugins/mail/mail.js +0 -381
  114. package/backend/dist/cjs/backend/src/plugins/mail/ui.d.ts +0 -297
  115. package/backend/dist/cjs/backend/src/plugins/mail/ui.js +0 -1370
  116. package/backend/dist/cjs/backend/src/plugins/pdf.d.ts +0 -1
  117. package/backend/dist/cjs/backend/src/plugins/pdf.js +0 -1456
  118. package/backend/dist/cjs/backend/src/plugins/thread_monitor.d.ts +0 -18
  119. package/backend/dist/cjs/backend/src/plugins/thread_monitor.js +0 -116
  120. package/backend/dist/cjs/backend/src/rate_limit.d.ts +0 -148
  121. package/backend/dist/cjs/backend/src/rate_limit.js +0 -543
  122. package/backend/dist/cjs/backend/src/route.d.ts +0 -39
  123. package/backend/dist/cjs/backend/src/route.js +0 -172
  124. package/backend/dist/cjs/backend/src/server.d.ts +0 -502
  125. package/backend/dist/cjs/backend/src/server.js +0 -1713
  126. package/backend/dist/cjs/backend/src/server.old.d.ts +0 -594
  127. package/backend/dist/cjs/backend/src/server.old.js +0 -2058
  128. package/backend/dist/cjs/backend/src/splash_screen.d.ts +0 -93
  129. package/backend/dist/cjs/backend/src/splash_screen.js +0 -119
  130. package/backend/dist/cjs/backend/src/status.d.ts +0 -89
  131. package/backend/dist/cjs/backend/src/status.js +0 -211
  132. package/backend/dist/cjs/backend/src/stream.d.ts +0 -494
  133. package/backend/dist/cjs/backend/src/stream.js +0 -1370
  134. package/backend/dist/cjs/backend/src/users.d.ts +0 -926
  135. package/backend/dist/cjs/backend/src/users.js +0 -2223
  136. package/backend/dist/cjs/backend/src/utils.d.ts +0 -22
  137. package/backend/dist/cjs/backend/src/utils.js +0 -626
  138. package/backend/dist/cjs/backend/src/view.d.ts +0 -115
  139. package/backend/dist/cjs/backend/src/view.js +0 -519
  140. package/backend/dist/cjs/backend/src/vinc.d.ts +0 -6
  141. package/backend/dist/cjs/backend/src/vinc.js +0 -40
  142. package/backend/dist/cjs/backend/src/volt.d.ts +0 -24
  143. package/backend/dist/cjs/backend/src/volt.js +0 -72
  144. package/backend/dist/cjs/frontend/src/modules/request.d.ts +0 -70
  145. package/backend/dist/cjs/frontend/src/modules/request.js +0 -99
  146. package/backend/dist/cjs/package.json +0 -1
  147. package/backend/dist/esm/backend/src/blacklist.d.ts +0 -12
  148. package/backend/dist/esm/backend/src/blacklist.js +0 -52
  149. package/backend/dist/esm/backend/src/cli.d.ts +0 -2
  150. package/backend/dist/esm/backend/src/cli.js +0 -211
  151. package/backend/dist/esm/backend/src/database/collection.d.ts +0 -1765
  152. package/backend/dist/esm/backend/src/database/collection.js +0 -3779
  153. package/backend/dist/esm/backend/src/database/database.d.ts +0 -92
  154. package/backend/dist/esm/backend/src/database/database.js +0 -214
  155. package/backend/dist/esm/backend/src/database/document.d.ts +0 -1
  156. package/backend/dist/esm/backend/src/database/document.js +0 -558
  157. package/backend/dist/esm/backend/src/database/filters/filters.d.ts +0 -6
  158. package/backend/dist/esm/backend/src/database/filters/filters.js +0 -1
  159. package/backend/dist/esm/backend/src/database/filters/strict_filter.d.ts +0 -223
  160. package/backend/dist/esm/backend/src/database/filters/strict_filter.js +0 -3
  161. package/backend/dist/esm/backend/src/database/filters/strict_filter_test.d.ts +0 -1
  162. package/backend/dist/esm/backend/src/database/filters/strict_filter_test.js +0 -505
  163. package/backend/dist/esm/backend/src/database/filters/strict_filter_test_v0.d.ts +0 -1
  164. package/backend/dist/esm/backend/src/database/filters/strict_filter_test_v0.js +0 -712
  165. package/backend/dist/esm/backend/src/database/filters/strict_filter_v0.d.ts +0 -50
  166. package/backend/dist/esm/backend/src/database/filters/strict_filter_v0.js +0 -5
  167. package/backend/dist/esm/backend/src/database/filters/strict_filter_v1.d.ts +0 -76
  168. package/backend/dist/esm/backend/src/database/filters/strict_filter_v1.js +0 -44
  169. package/backend/dist/esm/backend/src/database/filters/strict_filter_v2.d.ts +0 -75
  170. package/backend/dist/esm/backend/src/database/filters/strict_filter_v2.js +0 -5
  171. package/backend/dist/esm/backend/src/database/filters/strict_filter_v3.d.ts +0 -219
  172. package/backend/dist/esm/backend/src/database/filters/strict_filter_v3.js +0 -1
  173. package/backend/dist/esm/backend/src/database/filters/strict_update_filter.d.ts +0 -165
  174. package/backend/dist/esm/backend/src/database/filters/strict_update_filter.js +0 -5
  175. package/backend/dist/esm/backend/src/database/filters/strict_update_filter_test.d.ts +0 -5
  176. package/backend/dist/esm/backend/src/database/filters/strict_update_filter_test.js +0 -415
  177. package/backend/dist/esm/backend/src/database/flatten.d.ts +0 -78
  178. package/backend/dist/esm/backend/src/database/flatten.js +0 -22
  179. package/backend/dist/esm/backend/src/database/flatten_test.d.ts +0 -1
  180. package/backend/dist/esm/backend/src/database/flatten_test.js +0 -174
  181. package/backend/dist/esm/backend/src/database/quota/quoata_v2.d.ts +0 -533
  182. package/backend/dist/esm/backend/src/database/quota/quoata_v2.js +0 -1155
  183. package/backend/dist/esm/backend/src/database/quota/quota.d.ts +0 -551
  184. package/backend/dist/esm/backend/src/database/quota/quota.js +0 -1219
  185. package/backend/dist/esm/backend/src/database/quota/quota_v1.d.ts +0 -534
  186. package/backend/dist/esm/backend/src/database/quota/quota_v1.js +0 -1242
  187. package/backend/dist/esm/backend/src/database/quota/safe_int.d.ts +0 -412
  188. package/backend/dist/esm/backend/src/database/quota/safe_int.js +0 -810
  189. package/backend/dist/esm/backend/src/endpoint.d.ts +0 -346
  190. package/backend/dist/esm/backend/src/endpoint.js +0 -479
  191. package/backend/dist/esm/backend/src/errors/index.d.ts +0 -7
  192. package/backend/dist/esm/backend/src/errors/index.js +0 -7
  193. package/backend/dist/esm/backend/src/errors/internal_external.d.ts +0 -52
  194. package/backend/dist/esm/backend/src/errors/internal_external.js +0 -86
  195. package/backend/dist/esm/backend/src/errors/invalid_usage_error.d.ts +0 -41
  196. package/backend/dist/esm/backend/src/errors/invalid_usage_error.js +0 -33
  197. package/backend/dist/esm/backend/src/errors/system_error.d.ts +0 -261
  198. package/backend/dist/esm/backend/src/errors/system_error.js +0 -444
  199. package/backend/dist/esm/backend/src/events.d.ts +0 -97
  200. package/backend/dist/esm/backend/src/events.js +0 -5
  201. package/backend/dist/esm/backend/src/frontend.d.ts +0 -11
  202. package/backend/dist/esm/backend/src/frontend.js +0 -12
  203. package/backend/dist/esm/backend/src/image_endpoint.d.ts +0 -44
  204. package/backend/dist/esm/backend/src/image_endpoint.js +0 -196
  205. package/backend/dist/esm/backend/src/index.d.ts +0 -23
  206. package/backend/dist/esm/backend/src/index.js +0 -26
  207. package/backend/dist/esm/backend/src/logger.d.ts +0 -5
  208. package/backend/dist/esm/backend/src/logger.js +0 -8
  209. package/backend/dist/esm/backend/src/meta.d.ts +0 -112
  210. package/backend/dist/esm/backend/src/meta.js +0 -152
  211. package/backend/dist/esm/backend/src/payments/paddle.d.ts +0 -329
  212. package/backend/dist/esm/backend/src/payments/paddle.js +0 -2276
  213. package/backend/dist/esm/backend/src/payments/stripe/checkout.d.ts +0 -113
  214. package/backend/dist/esm/backend/src/payments/stripe/checkout.js +0 -356
  215. package/backend/dist/esm/backend/src/payments/stripe/customers.d.ts +0 -17
  216. package/backend/dist/esm/backend/src/payments/stripe/customers.js +0 -193
  217. package/backend/dist/esm/backend/src/payments/stripe/error.d.ts +0 -74
  218. package/backend/dist/esm/backend/src/payments/stripe/error.js +0 -51
  219. package/backend/dist/esm/backend/src/payments/stripe/events.d.ts +0 -155
  220. package/backend/dist/esm/backend/src/payments/stripe/events.js +0 -5
  221. package/backend/dist/esm/backend/src/payments/stripe/meters.d.ts +0 -105
  222. package/backend/dist/esm/backend/src/payments/stripe/meters.js +0 -318
  223. package/backend/dist/esm/backend/src/payments/stripe/payment_methods.d.ts +0 -58
  224. package/backend/dist/esm/backend/src/payments/stripe/payment_methods.js +0 -135
  225. package/backend/dist/esm/backend/src/payments/stripe/products.d.ts +0 -519
  226. package/backend/dist/esm/backend/src/payments/stripe/products.js +0 -896
  227. package/backend/dist/esm/backend/src/payments/stripe/stripe.d.ts +0 -215
  228. package/backend/dist/esm/backend/src/payments/stripe/stripe.js +0 -464
  229. package/backend/dist/esm/backend/src/payments/stripe/subscriptions.d.ts +0 -172
  230. package/backend/dist/esm/backend/src/payments/stripe/subscriptions.js +0 -754
  231. package/backend/dist/esm/backend/src/payments/stripe/utils.d.ts +0 -63
  232. package/backend/dist/esm/backend/src/payments/stripe/utils.js +0 -131
  233. package/backend/dist/esm/backend/src/payments/stripe/webhooks.d.ts +0 -105
  234. package/backend/dist/esm/backend/src/payments/stripe/webhooks.js +0 -752
  235. package/backend/dist/esm/backend/src/plugins/browser.d.ts +0 -1
  236. package/backend/dist/esm/backend/src/plugins/browser.js +0 -170
  237. package/backend/dist/esm/backend/src/plugins/communication.d.ts +0 -70
  238. package/backend/dist/esm/backend/src/plugins/communication.js +0 -169
  239. package/backend/dist/esm/backend/src/plugins/mail/mail.d.ts +0 -255
  240. package/backend/dist/esm/backend/src/plugins/mail/mail.js +0 -396
  241. package/backend/dist/esm/backend/src/plugins/mail/ui.d.ts +0 -297
  242. package/backend/dist/esm/backend/src/plugins/mail/ui.js +0 -1400
  243. package/backend/dist/esm/backend/src/plugins/pdf.d.ts +0 -1
  244. package/backend/dist/esm/backend/src/plugins/pdf.js +0 -1694
  245. package/backend/dist/esm/backend/src/plugins/thread_monitor.d.ts +0 -18
  246. package/backend/dist/esm/backend/src/plugins/thread_monitor.js +0 -120
  247. package/backend/dist/esm/backend/src/rate_limit.d.ts +0 -148
  248. package/backend/dist/esm/backend/src/rate_limit.js +0 -667
  249. package/backend/dist/esm/backend/src/route.d.ts +0 -39
  250. package/backend/dist/esm/backend/src/route.js +0 -222
  251. package/backend/dist/esm/backend/src/server.d.ts +0 -502
  252. package/backend/dist/esm/backend/src/server.js +0 -2034
  253. package/backend/dist/esm/backend/src/server.old.d.ts +0 -594
  254. package/backend/dist/esm/backend/src/server.old.js +0 -2630
  255. package/backend/dist/esm/backend/src/splash_screen.d.ts +0 -93
  256. package/backend/dist/esm/backend/src/splash_screen.js +0 -156
  257. package/backend/dist/esm/backend/src/status.d.ts +0 -89
  258. package/backend/dist/esm/backend/src/status.js +0 -213
  259. package/backend/dist/esm/backend/src/stream.d.ts +0 -494
  260. package/backend/dist/esm/backend/src/stream.js +0 -1611
  261. package/backend/dist/esm/backend/src/users.d.ts +0 -926
  262. package/backend/dist/esm/backend/src/users.js +0 -2423
  263. package/backend/dist/esm/backend/src/utils.d.ts +0 -22
  264. package/backend/dist/esm/backend/src/utils.js +0 -463
  265. package/backend/dist/esm/backend/src/view.d.ts +0 -115
  266. package/backend/dist/esm/backend/src/view.js +0 -584
  267. package/backend/dist/esm/backend/src/vinc.d.ts +0 -6
  268. package/backend/dist/esm/backend/src/vinc.js +0 -6
  269. package/backend/dist/esm/backend/src/volt.d.ts +0 -24
  270. package/backend/dist/esm/backend/src/volt.js +0 -27
  271. package/backend/dist/esm/frontend/src/modules/request.d.ts +0 -70
  272. package/backend/dist/esm/frontend/src/modules/request.js +0 -117
  273. package/backend/old/file_watcher.ts +0 -359
  274. package/backend/old/request.deprc.js +0 -626
  275. package/backend/old/response.deprc.js +0 -354
  276. package/frontend/dist/backend/src/database/collection.d.ts +0 -1765
  277. package/frontend/dist/backend/src/database/collection.js +0 -3779
  278. package/frontend/dist/backend/src/database/database.d.ts +0 -92
  279. package/frontend/dist/backend/src/database/database.js +0 -214
  280. package/frontend/dist/backend/src/database/filters/filters.d.ts +0 -6
  281. package/frontend/dist/backend/src/database/filters/filters.js +0 -1
  282. package/frontend/dist/backend/src/database/filters/strict_filter.d.ts +0 -223
  283. package/frontend/dist/backend/src/database/filters/strict_filter.js +0 -3
  284. package/frontend/dist/backend/src/database/filters/strict_update_filter.d.ts +0 -165
  285. package/frontend/dist/backend/src/database/filters/strict_update_filter.js +0 -5
  286. package/frontend/dist/backend/src/database/flatten.d.ts +0 -78
  287. package/frontend/dist/backend/src/database/flatten.js +0 -22
  288. package/frontend/dist/backend/src/endpoint.d.ts +0 -346
  289. package/frontend/dist/backend/src/endpoint.js +0 -479
  290. package/frontend/dist/backend/src/errors/index.d.ts +0 -7
  291. package/frontend/dist/backend/src/errors/index.js +0 -7
  292. package/frontend/dist/backend/src/errors/internal_external.d.ts +0 -52
  293. package/frontend/dist/backend/src/errors/internal_external.js +0 -86
  294. package/frontend/dist/backend/src/errors/invalid_usage_error.d.ts +0 -41
  295. package/frontend/dist/backend/src/errors/invalid_usage_error.js +0 -33
  296. package/frontend/dist/backend/src/errors/system_error.d.ts +0 -261
  297. package/frontend/dist/backend/src/errors/system_error.js +0 -444
  298. package/frontend/dist/backend/src/events.d.ts +0 -97
  299. package/frontend/dist/backend/src/events.js +0 -5
  300. package/frontend/dist/backend/src/frontend.d.ts +0 -11
  301. package/frontend/dist/backend/src/frontend.js +0 -12
  302. package/frontend/dist/backend/src/image_endpoint.d.ts +0 -44
  303. package/frontend/dist/backend/src/image_endpoint.js +0 -196
  304. package/frontend/dist/backend/src/meta.d.ts +0 -112
  305. package/frontend/dist/backend/src/meta.js +0 -152
  306. package/frontend/dist/backend/src/payments/paddle.d.ts +0 -329
  307. package/frontend/dist/backend/src/payments/paddle.js +0 -2276
  308. package/frontend/dist/backend/src/payments/stripe/checkout.d.ts +0 -113
  309. package/frontend/dist/backend/src/payments/stripe/checkout.js +0 -356
  310. package/frontend/dist/backend/src/payments/stripe/customers.d.ts +0 -17
  311. package/frontend/dist/backend/src/payments/stripe/customers.js +0 -193
  312. package/frontend/dist/backend/src/payments/stripe/error.d.ts +0 -74
  313. package/frontend/dist/backend/src/payments/stripe/error.js +0 -51
  314. package/frontend/dist/backend/src/payments/stripe/events.d.ts +0 -155
  315. package/frontend/dist/backend/src/payments/stripe/events.js +0 -5
  316. package/frontend/dist/backend/src/payments/stripe/meters.d.ts +0 -105
  317. package/frontend/dist/backend/src/payments/stripe/meters.js +0 -318
  318. package/frontend/dist/backend/src/payments/stripe/payment_methods.d.ts +0 -58
  319. package/frontend/dist/backend/src/payments/stripe/payment_methods.js +0 -135
  320. package/frontend/dist/backend/src/payments/stripe/products.d.ts +0 -519
  321. package/frontend/dist/backend/src/payments/stripe/products.js +0 -896
  322. package/frontend/dist/backend/src/payments/stripe/stripe.d.ts +0 -215
  323. package/frontend/dist/backend/src/payments/stripe/stripe.js +0 -464
  324. package/frontend/dist/backend/src/payments/stripe/subscriptions.d.ts +0 -172
  325. package/frontend/dist/backend/src/payments/stripe/subscriptions.js +0 -754
  326. package/frontend/dist/backend/src/payments/stripe/utils.d.ts +0 -63
  327. package/frontend/dist/backend/src/payments/stripe/utils.js +0 -131
  328. package/frontend/dist/backend/src/payments/stripe/webhooks.d.ts +0 -105
  329. package/frontend/dist/backend/src/payments/stripe/webhooks.js +0 -752
  330. package/frontend/dist/backend/src/plugins/mail/mail.d.ts +0 -255
  331. package/frontend/dist/backend/src/plugins/mail/mail.js +0 -396
  332. package/frontend/dist/backend/src/plugins/mail/ui.d.ts +0 -297
  333. package/frontend/dist/backend/src/plugins/mail/ui.js +0 -1400
  334. package/frontend/dist/backend/src/rate_limit.d.ts +0 -148
  335. package/frontend/dist/backend/src/rate_limit.js +0 -667
  336. package/frontend/dist/backend/src/route.d.ts +0 -39
  337. package/frontend/dist/backend/src/route.js +0 -222
  338. package/frontend/dist/backend/src/server.d.ts +0 -502
  339. package/frontend/dist/backend/src/server.js +0 -2034
  340. package/frontend/dist/backend/src/splash_screen.d.ts +0 -93
  341. package/frontend/dist/backend/src/splash_screen.js +0 -156
  342. package/frontend/dist/backend/src/status.d.ts +0 -89
  343. package/frontend/dist/backend/src/status.js +0 -213
  344. package/frontend/dist/backend/src/stream.d.ts +0 -494
  345. package/frontend/dist/backend/src/stream.js +0 -1611
  346. package/frontend/dist/backend/src/users.d.ts +0 -926
  347. package/frontend/dist/backend/src/users.js +0 -2423
  348. package/frontend/dist/backend/src/utils.d.ts +0 -22
  349. package/frontend/dist/backend/src/utils.js +0 -463
  350. package/frontend/dist/backend/src/view.d.ts +0 -115
  351. package/frontend/dist/backend/src/view.js +0 -584
  352. package/frontend/dist/frontend/src/elements/base.d.ts +0 -3743
  353. package/frontend/dist/frontend/src/elements/base.js +0 -12151
  354. package/frontend/dist/frontend/src/elements/module.d.ts +0 -95
  355. package/frontend/dist/frontend/src/elements/module.js +0 -216
  356. package/frontend/dist/frontend/src/elements/register_element.d.ts +0 -3
  357. package/frontend/dist/frontend/src/elements/register_element.js +0 -22
  358. package/frontend/dist/frontend/src/elements/resize_query_manager.d.ts +0 -0
  359. package/frontend/dist/frontend/src/elements/resize_query_manager.js +0 -150
  360. package/frontend/dist/frontend/src/elements/types.d.ts +0 -52
  361. package/frontend/dist/frontend/src/elements/types.js +0 -5
  362. package/frontend/dist/frontend/src/index.d.ts +0 -21
  363. package/frontend/dist/frontend/src/index.js +0 -29
  364. package/frontend/dist/frontend/src/modules/attachment.d.ts +0 -126
  365. package/frontend/dist/frontend/src/modules/attachment.js +0 -306
  366. package/frontend/dist/frontend/src/modules/auth.d.ts +0 -44
  367. package/frontend/dist/frontend/src/modules/auth.js +0 -80
  368. package/frontend/dist/frontend/src/modules/color.d.ts +0 -160
  369. package/frontend/dist/frontend/src/modules/color.js +0 -316
  370. package/frontend/dist/frontend/src/modules/compression.d.ts +0 -39
  371. package/frontend/dist/frontend/src/modules/compression.js +0 -102
  372. package/frontend/dist/frontend/src/modules/cookies.d.ts +0 -44
  373. package/frontend/dist/frontend/src/modules/cookies.js +0 -143
  374. package/frontend/dist/frontend/src/modules/events.d.ts +0 -31
  375. package/frontend/dist/frontend/src/modules/events.js +0 -79
  376. package/frontend/dist/frontend/src/modules/google.d.ts +0 -23
  377. package/frontend/dist/frontend/src/modules/google.js +0 -52
  378. package/frontend/dist/frontend/src/modules/meta.d.ts +0 -14
  379. package/frontend/dist/frontend/src/modules/meta.js +0 -48
  380. package/frontend/dist/frontend/src/modules/paddle.d.ts +0 -1207
  381. package/frontend/dist/frontend/src/modules/paddle.js +0 -2594
  382. package/frontend/dist/frontend/src/modules/request.d.ts +0 -70
  383. package/frontend/dist/frontend/src/modules/request.js +0 -117
  384. package/frontend/dist/frontend/src/modules/settings.d.ts +0 -3
  385. package/frontend/dist/frontend/src/modules/settings.js +0 -5
  386. package/frontend/dist/frontend/src/modules/statics.d.ts +0 -21
  387. package/frontend/dist/frontend/src/modules/statics.js +0 -43
  388. package/frontend/dist/frontend/src/modules/stripe/cart.d.ts +0 -112
  389. package/frontend/dist/frontend/src/modules/stripe/cart.js +0 -321
  390. package/frontend/dist/frontend/src/modules/stripe/checkout.d.ts +0 -7
  391. package/frontend/dist/frontend/src/modules/stripe/checkout.js +0 -37
  392. package/frontend/dist/frontend/src/modules/stripe/index.m.d.ts +0 -6
  393. package/frontend/dist/frontend/src/modules/stripe/index.m.js +0 -6
  394. package/frontend/dist/frontend/src/modules/stripe/payments.d.ts +0 -58
  395. package/frontend/dist/frontend/src/modules/stripe/payments.js +0 -92
  396. package/frontend/dist/frontend/src/modules/support.d.ts +0 -30
  397. package/frontend/dist/frontend/src/modules/support.js +0 -53
  398. package/frontend/dist/frontend/src/modules/theme.d.ts +0 -133
  399. package/frontend/dist/frontend/src/modules/theme.js +0 -406
  400. package/frontend/dist/frontend/src/modules/themes.d.ts +0 -12
  401. package/frontend/dist/frontend/src/modules/themes.js +0 -22
  402. package/frontend/dist/frontend/src/modules/user.d.ts +0 -164
  403. package/frontend/dist/frontend/src/modules/user.js +0 -270
  404. package/frontend/dist/frontend/src/modules/utils.d.ts +0 -176
  405. package/frontend/dist/frontend/src/modules/utils.js +0 -569
  406. package/frontend/dist/frontend/src/types/gradient.d.ts +0 -29
  407. package/frontend/dist/frontend/src/types/gradient.js +0 -79
  408. package/frontend/dist/frontend/src/ui/border_button.d.ts +0 -94
  409. package/frontend/dist/frontend/src/ui/border_button.js +0 -228
  410. package/frontend/dist/frontend/src/ui/button.d.ts +0 -241
  411. package/frontend/dist/frontend/src/ui/button.js +0 -682
  412. package/frontend/dist/frontend/src/ui/canvas.d.ts +0 -138
  413. package/frontend/dist/frontend/src/ui/canvas.js +0 -444
  414. package/frontend/dist/frontend/src/ui/checkbox.d.ts +0 -74
  415. package/frontend/dist/frontend/src/ui/checkbox.js +0 -321
  416. package/frontend/dist/frontend/src/ui/code.d.ts +0 -235
  417. package/frontend/dist/frontend/src/ui/code.js +0 -1007
  418. package/frontend/dist/frontend/src/ui/context_menu.d.ts +0 -36
  419. package/frontend/dist/frontend/src/ui/context_menu.js +0 -205
  420. package/frontend/dist/frontend/src/ui/css.d.ts +0 -16
  421. package/frontend/dist/frontend/src/ui/css.js +0 -48
  422. package/frontend/dist/frontend/src/ui/divider.d.ts +0 -15
  423. package/frontend/dist/frontend/src/ui/divider.js +0 -78
  424. package/frontend/dist/frontend/src/ui/dropdown.d.ts +0 -176
  425. package/frontend/dist/frontend/src/ui/dropdown.js +0 -481
  426. package/frontend/dist/frontend/src/ui/for_each.d.ts +0 -37
  427. package/frontend/dist/frontend/src/ui/for_each.js +0 -92
  428. package/frontend/dist/frontend/src/ui/form.d.ts +0 -34
  429. package/frontend/dist/frontend/src/ui/form.js +0 -233
  430. package/frontend/dist/frontend/src/ui/frame_modes.d.ts +0 -37
  431. package/frontend/dist/frontend/src/ui/frame_modes.js +0 -108
  432. package/frontend/dist/frontend/src/ui/google_map.d.ts +0 -24
  433. package/frontend/dist/frontend/src/ui/google_map.js +0 -106
  434. package/frontend/dist/frontend/src/ui/gradient.d.ts +0 -25
  435. package/frontend/dist/frontend/src/ui/gradient.js +0 -131
  436. package/frontend/dist/frontend/src/ui/image.d.ts +0 -111
  437. package/frontend/dist/frontend/src/ui/image.js +0 -576
  438. package/frontend/dist/frontend/src/ui/input.d.ts +0 -392
  439. package/frontend/dist/frontend/src/ui/input.js +0 -1201
  440. package/frontend/dist/frontend/src/ui/link.d.ts +0 -25
  441. package/frontend/dist/frontend/src/ui/link.js +0 -140
  442. package/frontend/dist/frontend/src/ui/list.d.ts +0 -37
  443. package/frontend/dist/frontend/src/ui/list.js +0 -170
  444. package/frontend/dist/frontend/src/ui/loader_button.d.ts +0 -80
  445. package/frontend/dist/frontend/src/ui/loader_button.js +0 -193
  446. package/frontend/dist/frontend/src/ui/loaders.d.ts +0 -57
  447. package/frontend/dist/frontend/src/ui/loaders.js +0 -157
  448. package/frontend/dist/frontend/src/ui/popup.d.ts +0 -94
  449. package/frontend/dist/frontend/src/ui/popup.js +0 -510
  450. package/frontend/dist/frontend/src/ui/pseudo.d.ts +0 -44
  451. package/frontend/dist/frontend/src/ui/pseudo.js +0 -154
  452. package/frontend/dist/frontend/src/ui/scroller.d.ts +0 -105
  453. package/frontend/dist/frontend/src/ui/scroller.js +0 -1253
  454. package/frontend/dist/frontend/src/ui/slider.d.ts +0 -45
  455. package/frontend/dist/frontend/src/ui/slider.js +0 -217
  456. package/frontend/dist/frontend/src/ui/spacer.d.ts +0 -15
  457. package/frontend/dist/frontend/src/ui/spacer.js +0 -78
  458. package/frontend/dist/frontend/src/ui/span.d.ts +0 -15
  459. package/frontend/dist/frontend/src/ui/span.js +0 -73
  460. package/frontend/dist/frontend/src/ui/stack.d.ts +0 -66
  461. package/frontend/dist/frontend/src/ui/stack.js +0 -335
  462. package/frontend/dist/frontend/src/ui/steps.d.ts +0 -131
  463. package/frontend/dist/frontend/src/ui/steps.js +0 -308
  464. package/frontend/dist/frontend/src/ui/style.d.ts +0 -17
  465. package/frontend/dist/frontend/src/ui/style.js +0 -73
  466. package/frontend/dist/frontend/src/ui/switch.d.ts +0 -69
  467. package/frontend/dist/frontend/src/ui/switch.js +0 -357
  468. package/frontend/dist/frontend/src/ui/table.d.ts +0 -100
  469. package/frontend/dist/frontend/src/ui/table.js +0 -405
  470. package/frontend/dist/frontend/src/ui/tabs.d.ts +0 -111
  471. package/frontend/dist/frontend/src/ui/tabs.js +0 -424
  472. package/frontend/dist/frontend/src/ui/text.d.ts +0 -15
  473. package/frontend/dist/frontend/src/ui/text.js +0 -83
  474. package/frontend/dist/frontend/src/ui/title.d.ts +0 -91
  475. package/frontend/dist/frontend/src/ui/title.js +0 -272
  476. package/frontend/dist/frontend/src/ui/ui.d.ts +0 -35
  477. package/frontend/dist/frontend/src/ui/ui.js +0 -38
  478. package/frontend/dist/frontend/src/ui/view.d.ts +0 -15
  479. package/frontend/dist/frontend/src/ui/view.js +0 -88
  480. package/frontend/dist/frontend/src/volt.d.ts +0 -20
  481. package/frontend/dist/frontend/src/volt.js +0 -27
  482. package/frontend/examples/theme/theme.ts +0 -58
  483. package/frontend/tools/bundle_d_ts.js +0 -71
  484. package/frontend/tools/convert_to_jsdoc_input.txt +0 -9452
  485. package/frontend/tools/convert_to_jsdoc_output.txt +0 -7626
  486. package/frontend/tools/convert_to_jsdoc_tmp.js +0 -345
  487. package/frontend/tools/scan_mixed_imports.js +0 -69
  488. /package/frontend/{dist/frontend/src/css → css}/adyen.css +0 -0
  489. /package/frontend/{dist/frontend/src/css → css}/volt.css +0 -0
@@ -1,1611 +0,0 @@
1
- /**
2
- * @author Daan van den Bergh
3
- * @copyright © 2025 - 2025 Daan van den Bergh. All rights reserved.
4
- */
5
- // ---------------------------------------------------------
6
- // Imports.
7
- import * as vlib from "@vandenberghinc/vlib";
8
- import { Transform } from "node:stream";
9
- import * as fs from "node:fs";
10
- import { pipeline } from "node:stream";
11
- import * as zlib from "node:zlib";
12
- import RateLimits from './rate_limit.js';
13
- import { Utils } from "./utils.js";
14
- const { debug } = vlib;
15
- // ---------------------------------------------------------
16
- // Request object.
17
- /**
18
- * The http2 stream wrapper object.
19
- *
20
- * @property headers The request headers.
21
- *
22
- * @nav Stream
23
- * @docs
24
- */
25
- export class Stream {
26
- /** The request headers. */
27
- headers;
28
- /** Whether this stream is an HTTP/2 stream. */
29
- http2;
30
- /** Whether this stream is an HTTP/1.1 stream (when false, it's an HTTP/2 stream). */
31
- http1;
32
- /** The status code of the sent response. */
33
- status_code;
34
- /** Whether the response has been finished. */
35
- finished;
36
- /** The received body potentially decompressed as string. */
37
- body;
38
- /** The raw body as a Buffer, potentially decompressed. */
39
- raw_body;
40
- /** The body wired exactly as is, not decompressed etc. */
41
- wire_body;
42
- /** The internal promise that resolves when the body is fully received. */
43
- promise;
44
- /** The cached value of {@link normalize_ip} */
45
- _normalized_ip;
46
- s;
47
- req;
48
- res;
49
- _ip;
50
- _port;
51
- _method;
52
- _params;
53
- _is_query_params;
54
- _endpoint;
55
- _query_string;
56
- _cookies;
57
- _uid;
58
- res_cookies;
59
- res_headers;
60
- /**
61
- * Create a new Stream wrapper for HTTP/1.1 or HTTP/2.
62
- *
63
- * @param stream The HTTP/2 stream (when using HTTP/2).
64
- * @param headers The request headers.
65
- * @param req The HTTP/1.1 request (when using HTTP/1.1).
66
- * @param res The HTTP/1.1/HTTP/2 response object.
67
- */
68
- constructor(stream, headers, req, res) {
69
- // Parameters.
70
- this.s = stream;
71
- this.headers = (headers ?? {});
72
- this.req = req;
73
- this.res = res;
74
- this.http2 = req == null;
75
- this.http1 = req != null;
76
- // HTTP1.
77
- if (this.http1) {
78
- this.headers = this.req.headers;
79
- }
80
- // Request attributes.
81
- this._ip = this.http2 ? this.s.session.socket.remoteAddress : this.req.socket.remoteAddress;
82
- this._port = this.http2 ? this.s.session.socket.remotePort : this.req.socket.remotePort;
83
- this._method = this.http2 ? this.headers[':method'] : this.req.method;
84
- this._params = undefined;
85
- this._is_query_params = false;
86
- this._endpoint = undefined;
87
- this._query_string = undefined;
88
- this._cookies = undefined;
89
- this._uid = undefined;
90
- // Response attributes
91
- this.status_code = undefined;
92
- this.finished = false;
93
- this.res_cookies = [];
94
- this.res_headers = this.http1 ? [] : {};
95
- // Read body.
96
- this.body = "";
97
- this.raw_body = Buffer.alloc(0);
98
- this.wire_body = Buffer.alloc(0);
99
- this.promise = undefined;
100
- this._recv_body();
101
- }
102
- /**
103
- * Receive and buffer the request body, handling optional gzip/deflate decompression.
104
- * Sets {@link body} and resolves the internal promise used by {@link join}.
105
- */
106
- _recv_body() {
107
- this.promise = new Promise((resolve, reject) => {
108
- // Buffers: decoded + wire.
109
- const buffs = [];
110
- const wire_buffs = [];
111
- // Get decompress stream.
112
- let decompress_stream;
113
- const content_encoding = this.headers['content-encoding'];
114
- if (content_encoding === 'gzip') {
115
- decompress_stream = zlib.createGunzip();
116
- }
117
- else if (content_encoding === 'deflate') {
118
- decompress_stream = zlib.createInflate();
119
- }
120
- const cleanup = () => {
121
- if (decompress_stream) {
122
- decompress_stream.close();
123
- }
124
- };
125
- const on_error = (e) => {
126
- cleanup();
127
- reject(e);
128
- };
129
- // -------------------------
130
- // HTTP2
131
- // -------------------------
132
- if (this.http2) {
133
- const source = this.s;
134
- // 1) Buffer wire bytes from the source stream (exact on-the-wire chunks).
135
- source.on("data", (chunk) => {
136
- wire_buffs.push(chunk);
137
- });
138
- // 2) Create decoded stream (maybe decompressed).
139
- let decoded = source;
140
- if (decompress_stream) {
141
- decoded = source.pipe(decompress_stream);
142
- }
143
- source.on("error", on_error);
144
- decoded.on("error", on_error);
145
- // 3) Buffer decoded bytes.
146
- decoded.on("data", (chunk) => {
147
- buffs.push(chunk);
148
- });
149
- // IMPORTANT: resolve on *decoded* end, because that’s when decoded body is complete.
150
- decoded.on("end", () => {
151
- try {
152
- this.wire_body = Buffer.concat(wire_buffs);
153
- this.raw_body = Buffer.concat(buffs);
154
- this.body = this.raw_body.toString("utf8");
155
- cleanup();
156
- resolve();
157
- }
158
- catch (e) {
159
- on_error(e);
160
- }
161
- });
162
- return;
163
- }
164
- // -------------------------
165
- // HTTP1
166
- // -------------------------
167
- const source = this.req;
168
- // 1) Buffer wire bytes from the source request.
169
- source.on("data", (chunk) => {
170
- wire_buffs.push(chunk);
171
- });
172
- // 2) Create decoded stream (maybe decompressed).
173
- let decoded = source;
174
- if (decompress_stream) {
175
- decoded = source.pipe(decompress_stream);
176
- }
177
- source.on("error", on_error);
178
- decoded.on("error", on_error);
179
- // 3) Buffer decoded bytes.
180
- decoded.on("data", (chunk) => {
181
- buffs.push(chunk);
182
- });
183
- decoded.on("end", () => {
184
- try {
185
- this.wire_body = Buffer.concat(wire_buffs);
186
- this.raw_body = Buffer.concat(buffs);
187
- this.body = this.raw_body.toString("utf8");
188
- cleanup();
189
- resolve();
190
- }
191
- catch (e) {
192
- on_error(e);
193
- }
194
- });
195
- });
196
- }
197
- /**
198
- * Parse and cache the request endpoint and query string.
199
- * Populates {@link _endpoint} and {@link _query_string}.
200
- * @private
201
- */
202
- _parse_endoint() {
203
- if (this._endpoint !== undefined) {
204
- return;
205
- }
206
- this._endpoint = this.http2 ? this.headers[":path"] : this.req.url;
207
- let index;
208
- if ((index = this._endpoint.indexOf("?")) !== -1) {
209
- this._query_string = this._endpoint.substr(index + 1);
210
- this._endpoint = this._endpoint.substr(0, index);
211
- }
212
- this._endpoint = this._endpoint.replace(/\/\//g, "/");
213
- if (this._endpoint.length > 1 && this._endpoint.charAt(this._endpoint.length - 1) === "/") {
214
- this._endpoint = this._endpoint.substr(0, this._endpoint.length - 1);
215
- }
216
- }
217
- /**
218
- * Parse and cache request parameters from the query string or JSON body.
219
- * Returns the parsed params map.
220
- */
221
- _parse_params() {
222
- // Parse query string.
223
- this._parse_endoint();
224
- // Already parsed.
225
- if (this._params !== undefined) {
226
- return;
227
- }
228
- // Initialize.
229
- this._params = {};
230
- // By query string.
231
- if (this._query_string !== undefined) {
232
- // As encoded json.
233
- if (this._query_string.charAt(0) === "{") {
234
- try {
235
- this._params = JSON.parse(decodeURIComponent(this._query_string));
236
- }
237
- catch (err) {
238
- throw Error(`Invalid json request query: ${err}.`);
239
- }
240
- }
241
- // As query string.
242
- else {
243
- // Assign.
244
- this._is_query_params = true;
245
- // Variables.
246
- let is_key = true, key = "", value = "";
247
- const number_regex = /^-?\d+(\.\d+)?$/;
248
- // Callback.
249
- const add_value = () => {
250
- let output_value;
251
- switch (value) {
252
- case "true":
253
- case "True":
254
- output_value = true;
255
- break;
256
- case "false":
257
- case "False":
258
- output_value = false;
259
- break;
260
- case "null":
261
- case "None":
262
- case "undefined":
263
- output_value = null;
264
- break;
265
- default:
266
- output_value = decodeURIComponent(value.replaceAll("+", " "));
267
- if (number_regex.test(output_value)) {
268
- if (output_value.indexOf(".") !== -1) {
269
- output_value = parseFloat(output_value);
270
- }
271
- else {
272
- output_value = parseInt(output_value);
273
- }
274
- }
275
- break;
276
- }
277
- this._params[decodeURIComponent(key.replaceAll("+", " "))] = output_value;
278
- key = "";
279
- value = "";
280
- is_key = true;
281
- };
282
- // Iterate
283
- for (let i = 0; i < this._query_string.length; i++) {
284
- const c = this._query_string.charAt(i);
285
- if (is_key && c === "=") {
286
- is_key = false;
287
- continue;
288
- }
289
- else if (is_key === false && c === "&") {
290
- add_value();
291
- continue;
292
- }
293
- if (is_key) {
294
- key += c;
295
- }
296
- else {
297
- value += c;
298
- }
299
- }
300
- if (key.length > 0) {
301
- add_value();
302
- }
303
- }
304
- }
305
- // By body.
306
- else if (this.body.trim().charAt(0) === "{") {
307
- try {
308
- this._params = JSON.parse(this.body);
309
- }
310
- catch (err) {
311
- throw Error(`Invalid json request body: ${err}.`);
312
- }
313
- }
314
- // Handler.
315
- return this._params;
316
- }
317
- /**
318
- * Parses & returns the cookies cookies,
319
- * while assigning it to {@link _cookies}
320
- *
321
- * @warning On subsequent calls cookies will be parsed again.
322
- */
323
- _parse_cookies() {
324
- // Reset cookies.
325
- this._cookies = {};
326
- // Vars.
327
- const cookie_str = this.http2 ? this.headers["cookie"] : this.req.headers.cookie;
328
- if (cookie_str == null) {
329
- return this._cookies;
330
- }
331
- let key = "";
332
- let value = "";
333
- let cookie = {};
334
- let cookie_length = 0;
335
- let cookie_key = null;
336
- let is_value = false;
337
- let is_str = null;
338
- // Append to cookie.
339
- const append_to_cookie = () => {
340
- if (key.length > 0) {
341
- if (cookie_length === 0) {
342
- cookie.value = value;
343
- }
344
- else {
345
- cookie[key] = value;
346
- }
347
- ++cookie_length;
348
- }
349
- key = "";
350
- value = "";
351
- is_value = false;
352
- is_str = null;
353
- };
354
- // Append cookie.
355
- const append_cookie = () => {
356
- if (cookie_key != null) {
357
- this._cookies[cookie_key] = cookie;
358
- cookie_key = null;
359
- cookie = {};
360
- cookie_length = 0;
361
- }
362
- };
363
- // Iterate.
364
- for (let x = 0; x < cookie_str.length; x++) {
365
- const c = cookie_str.charAt(x);
366
- // Add char to value.
367
- if (is_value) {
368
- // End of cookie string.
369
- if (is_str === c) {
370
- value = value.substr(1, value.length - 1);
371
- append_to_cookie();
372
- }
373
- // Cookie seperator.
374
- else if (is_str == null && c === " ") {
375
- append_to_cookie();
376
- }
377
- // End of cookie.
378
- else if (is_str == null && c === ";") {
379
- append_to_cookie();
380
- append_cookie();
381
- }
382
- // Append to value.
383
- else {
384
- value += c;
385
- if (value.length === 1 && (c === "\"" || c === "'")) {
386
- is_str = c;
387
- }
388
- }
389
- }
390
- // Skip whitespace in keys.
391
- else if (c == " " || c == "\t") {
392
- continue;
393
- }
394
- // End of cookie key.
395
- else if (c == "=") {
396
- if (cookie_key == null) {
397
- cookie_key = key;
398
- }
399
- is_value = true;
400
- }
401
- // Add char to key.
402
- else {
403
- key += c;
404
- }
405
- }
406
- append_to_cookie();
407
- append_cookie();
408
- return this._cookies;
409
- }
410
- // ---------------------------------------------------------
411
- // Functions.
412
- /**
413
- * Wait until the request body is fully received.
414
- * Resolves when the internal receive promise completes.
415
- */
416
- async join() {
417
- await this.promise;
418
- }
419
- // Get the requests ip.
420
- /**
421
- * Get the request's ip.
422
- *
423
- * @example
424
- * ```ts
425
- * const ip = stream.ip;
426
- * ```
427
- * @docs
428
- */
429
- get ip() {
430
- return this._ip;
431
- }
432
- /**
433
- * Retrieve the normalized IP address, suitable for rate limiting and logging.
434
- * @throws {Error} If the IP is invalid.
435
- * @returns The normalized IP.
436
- * @docs
437
- */
438
- normalized_ip() {
439
- if (this._normalized_ip != null) {
440
- return this._normalized_ip;
441
- }
442
- return this._normalized_ip = RateLimits.normalize_ip(this._ip);
443
- }
444
- // Get the requests port.
445
- /**
446
- * Get the request's port.
447
- *
448
- * @example
449
- * ```ts
450
- * const port = stream.port;
451
- * ```
452
- * @docs
453
- */
454
- get port() {
455
- return this._port;
456
- }
457
- // Get the method.
458
- /**
459
- * Get the request method.
460
- *
461
- * @example
462
- * ```ts
463
- * const method = stream.method;
464
- * ```
465
- * @docs
466
- */
467
- get method() {
468
- return this._method;
469
- }
470
- // Get the endpoint.
471
- /**
472
- * Get the request's endpoint. This will not include the query string.
473
- *
474
- * @example
475
- * ```ts
476
- * const endpoint = stream.endpoint;
477
- * ```
478
- * @docs
479
- */
480
- get endpoint() {
481
- if (this._endpoint !== undefined) {
482
- return this._endpoint;
483
- }
484
- this._parse_endoint();
485
- return this._endpoint;
486
- }
487
- // Get the params.
488
- /**
489
- * Get the request's query or body params.
490
- *
491
- * @example
492
- * ```ts
493
- * const params = stream.params;
494
- * ```
495
- * @docs
496
- */
497
- get params() {
498
- if (this._params !== undefined) {
499
- return this._params;
500
- }
501
- this._parse_params();
502
- return this._params;
503
- }
504
- /** Add a param (used by the server backend for path parameters). */
505
- add_param(name, value) {
506
- if (!this._params) {
507
- this._params = {};
508
- }
509
- this._params[name] = value;
510
- }
511
- // Get a param by name and optionally by type.
512
- /**
513
- * Get a single query or body parameter with an optional type cast.
514
- *
515
- * @warning Throws an error when the parameter does not exist or when the type is different from the specified type(s), unless parameter `def` is defined.
516
- *
517
- * @param name The name of the parameter.
518
- * @param type The type cast of the parameters, valid types are `[null, "boolean", "number", "string", "array", "object"]`.
519
- * @param def
520
- * The default value to return when the parameter does not exist.
521
- *
522
- * If the parameter is not defined and `def` is `undefined` then this function will throw an error.
523
- * When `def` is `undefined` errors will be thrown, when `def` is `null` and the parameter is undefined then `null` will be returned as the default value.
524
- *
525
- * Errors will always be thrown when the incorrect type has been sent by the user.
526
- * @example
527
- * ```ts
528
- * const param = stream.param("myparameter", "number", 10);
529
- * ```
530
- * @docs
531
- */
532
- param(name, type = null, def = undefined) {
533
- // Parse params.
534
- this._parse_params();
535
- // Get value.
536
- let value = this._params[name];
537
- // Check type.
538
- if (type != null) {
539
- // Vars.
540
- let is_type_array = Array.isArray(type);
541
- // Wrapper funcs.
542
- const type_str = () => {
543
- let str = "";
544
- if (type != null) {
545
- str += " type ";
546
- if (is_type_array) {
547
- let i = 0, one_but_last_i = type.length - 2;
548
- type.forEach((item, i) => {
549
- str += `"${item}"`;
550
- if (i < one_but_last_i) {
551
- str += ", ";
552
- }
553
- else if (i === one_but_last_i) {
554
- str += " or ";
555
- }
556
- });
557
- }
558
- else {
559
- str += `"${type}"`;
560
- }
561
- }
562
- return str;
563
- };
564
- const type_eq_or_includes = (match) => {
565
- if (is_type_array) {
566
- return type.includes(match);
567
- }
568
- return match === type;
569
- };
570
- // Check undefined.
571
- if (value == null || value === "") {
572
- if (def !== undefined) {
573
- return def;
574
- }
575
- throw Error(`Define parameter "${name}"${type_str()}.`);
576
- }
577
- // Cast the value to another type when a query string was used.
578
- if (this._is_query_params && type_eq_or_includes("string") === false) {
579
- if (is_type_array === false) {
580
- type = [type];
581
- }
582
- const success = type.some((type) => {
583
- // Convert to string.
584
- if (type === "string") {
585
- return true;
586
- }
587
- // Convert to null.
588
- if (type === "null" && value === "null") {
589
- value = null;
590
- return true;
591
- }
592
- // Convert to boolean.
593
- const is_boolean = type === "boolean";
594
- if (is_boolean && value === "true") {
595
- value = true;
596
- return true;
597
- }
598
- if (is_boolean && value === "false") {
599
- value = false;
600
- return true;
601
- }
602
- // Convert to array.
603
- if (type === "array") {
604
- value = value.split(",");
605
- return true;
606
- }
607
- // Convert to object.
608
- if (type === "object") {
609
- const split = value.split(",");
610
- value = {};
611
- split.forEach((item) => {
612
- const pair = item.split(":");
613
- value[pair[0]] = pair[1];
614
- });
615
- return true;
616
- }
617
- // Convert to numeric.
618
- if (type === "number" && /^-?\d+(\.\d+)?$/.test(value)) {
619
- value = parseFloat(value);
620
- return true;
621
- }
622
- });
623
- if (!success) {
624
- throw Error(`Parameter "${name}" should be of${type_str()}.`);
625
- }
626
- }
627
- // Check the type when no query params are defined since JSON.parse already parsed the types.
628
- else if (!this._is_query_params) {
629
- const value_type = typeof value;
630
- if (!is_type_array) {
631
- type = [type];
632
- }
633
- const success = type.some((type) => {
634
- const l_is_array = type === "array";
635
- const l_is_null = type === "null";
636
- // Same type.
637
- if (!l_is_array && !l_is_null && type === value_type) {
638
- return true;
639
- }
640
- // Check to null.
641
- if (l_is_null && value == null) {
642
- return true;
643
- }
644
- // Convert to array.
645
- if (l_is_array && Array.isArray(value)) {
646
- return true;
647
- }
648
- });
649
- if (!success) {
650
- throw Error(`Parameter "${name}" should be of${type_str()}.`);
651
- }
652
- }
653
- }
654
- // Check undefined.
655
- else if (value == null || value === "") {
656
- if (def !== undefined) {
657
- return def;
658
- }
659
- throw Error(`Define parameter "${name}".`);
660
- }
661
- // Return value.
662
- return value;
663
- }
664
- // Get the request cookies.
665
- /**
666
- * Get the request's cookies
667
- *
668
- * @example
669
- * ```ts
670
- * const cookies = stream.cookies;
671
- * ```
672
- * @docs
673
- */
674
- get cookies() {
675
- if (this._cookies != null)
676
- return this._cookies;
677
- return this._parse_cookies();
678
- }
679
- // DEPRECATED since its only available for http2.
680
- // /**
681
- // * Check if the stream is closed.
682
- // *
683
- // * @example
684
- // * ```ts
685
- // * const ip = stream.closed;
686
- // * ```
687
- // * @docs
688
- // */
689
- // get closed(): boolean {
690
- // if (!this.http2) { throw new Error("This function is only supported for http2 streams."); }
691
- // return this.s!.closed;
692
- // }
693
- // Check if the stream is destroyed
694
- /**
695
- * Check if the stream is destroyed.
696
- *
697
- * @example
698
- * ```ts
699
- * const ip = stream.destroyed;
700
- * ```
701
- * @docs
702
- */
703
- get destroyed() {
704
- if (this.http2) {
705
- return this.s.destroyed;
706
- }
707
- else {
708
- return this.req.destroyed;
709
- }
710
- }
711
- // ---------------------------------------------------------
712
- // Functions.
713
- // Get the authenticated uid.
714
- /**
715
- * Get the authenticated uid; `undefined` when the request was not authenticated.
716
- *
717
- * @example
718
- * ```ts
719
- * const uid = stream.uid;
720
- * ```
721
- * @docs
722
- */
723
- get uid() {
724
- return this._uid;
725
- }
726
- set uid(value) {
727
- this._uid = value;
728
- }
729
- /**
730
- * Apply templates to an in-memory body.
731
- * Only applies to string bodies to avoid corrupting binary payloads.
732
- */
733
- apply_templates_to_body(input, templates) {
734
- // Skip when there are no templates.
735
- if (templates == null || Object.keys(templates).length === 0) {
736
- return input;
737
- }
738
- // Only apply templates to string bodies.
739
- if (typeof input !== "string") {
740
- return input;
741
- }
742
- // Replace all template keys with their stringified values.
743
- let out = input;
744
- for (const key of Object.keys(templates)) {
745
- const value = templates[key];
746
- // Convert non-string template values to a string.
747
- const value_str = typeof value === "string" ? value : JSON.stringify(value);
748
- // Replace all occurrences of the key.
749
- out = out.split(`{{${key}}}`).join(value_str);
750
- }
751
- return out;
752
- }
753
- /**
754
- * Create a transform stream that applies templates across chunk boundaries.
755
- * This avoids missing replacements when a template key is split between chunks.
756
- */
757
- create_template_replace_transform(templates) {
758
- // Precompute keys and the longest key length for boundary-safe streaming.
759
- const keys = Object.keys(templates);
760
- const max_key_len = keys.reduce((max, k) => Math.max(max, k.length), 0);
761
- // Keep enough tail bytes to cover a key split between chunks.
762
- const keep_len = Math.max(0, max_key_len - 1);
763
- // Carry tail across chunks.
764
- let carry = "";
765
- return new Transform({
766
- transform(chunk, _enc, cb) {
767
- try {
768
- // Merge with carry to handle split keys across chunks.
769
- const str = carry + chunk.toString("utf8");
770
- // Keep a tail so we don't split a key.
771
- const cut_idx = Math.max(0, str.length - keep_len);
772
- const safe_head = str.slice(0, cut_idx);
773
- // Persist the tail for the next chunk.
774
- carry = str.slice(cut_idx);
775
- // Replace templates in the safe head.
776
- let out = safe_head;
777
- for (const key of keys) {
778
- const value = templates[key];
779
- const value_str = typeof value === "string" ? value : JSON.stringify(value);
780
- out = out.split(`{{${key}}}`).join(value_str);
781
- }
782
- cb(null, out);
783
- }
784
- catch (err) {
785
- cb(err);
786
- }
787
- },
788
- flush(cb) {
789
- try {
790
- // Flush remaining carry.
791
- let out = carry;
792
- for (const key of keys) {
793
- const value = templates[key];
794
- const value_str = typeof value === "string" ? value : JSON.stringify(value);
795
- out = out.split(`{{${key}}}`).join(value_str);
796
- }
797
- cb(null, out);
798
- }
799
- catch (err) {
800
- cb(err);
801
- }
802
- },
803
- });
804
- }
805
- /** Create output headers for http2. */
806
- create_http2_headers(status, new_headers) {
807
- // Convert ResponseHeaderValue to Node-compatible header values.
808
- const normalize_header_value = (v) => {
809
- if (v == null)
810
- return undefined;
811
- if (typeof v === "boolean")
812
- return v ? "true" : "false";
813
- if (typeof v === "number")
814
- return v;
815
- if (typeof v === "string")
816
- return v;
817
- return String(v);
818
- };
819
- // Start with any headers set earlier via set_header/set_headers.
820
- const out_headers = {
821
- ":status": status,
822
- };
823
- // Merge previously queued headers for http2.
824
- if (!Array.isArray(this.res_headers)) {
825
- for (const [k, v] of Object.entries(this.res_headers)) {
826
- const nv = normalize_header_value(v);
827
- if (nv !== undefined)
828
- out_headers[k.toLowerCase()] = nv;
829
- }
830
- }
831
- // Merge call-specific headers last so they win.
832
- for (const [k, v] of Object.entries(new_headers)) {
833
- const nv = normalize_header_value(v);
834
- if (nv !== undefined)
835
- out_headers[k.toLowerCase()] = nv;
836
- }
837
- // Attach any cookies staged via set_cookie/set_cookies.
838
- if (this.res_cookies.length > 0) {
839
- out_headers["set-cookie"] = this.res_cookies;
840
- }
841
- return out_headers;
842
- }
843
- /** Assign http headers to response. */
844
- set_http1_headers(status, headers) {
845
- if (!this.res) {
846
- throw new Error("HTTP/1.1 response is missing.");
847
- }
848
- // Set status code.
849
- this.res.statusCode = status;
850
- // Set headers.
851
- for (let i = 0; i < this.res_headers.length; i++) {
852
- this.res.setHeader(this.res_headers[i][0].toLowerCase(), this.res_headers[i][1]);
853
- }
854
- Object.keys(headers).forEach((key) => {
855
- const v = headers[key];
856
- if (v != null) {
857
- this.res?.setHeader(key.toLowerCase(), typeof v === "boolean" ? v.toString() : v);
858
- }
859
- });
860
- }
861
- /**
862
- * Send a response.
863
- * @example
864
- * ```ts
865
- * stream.send({status: 200, data: "Hello World!"});
866
- * ```
867
- * @docs
868
- */
869
- send({ status = 200, headers = {}, data, compress = false, from_file, templates, }) {
870
- // Assign sent status code.
871
- this.status_code = status;
872
- // The body to send as non `ResponseBody` type.
873
- let body = data;
874
- // Convert body primitivies to string.
875
- if (typeof body === "boolean" || typeof body === "number") {
876
- body = body.toString();
877
- }
878
- // -----------------------------------------
879
- // Helpers.
880
- /** Get the accept-encoding header from the request. */
881
- const get_accept_encoding = () => {
882
- // Prefer the cached request headers on the stream wrapper.
883
- // For http2 these are the real pseudo/header map; for http1 this is req.headers.
884
- const accept_encoding = this.headers?.["accept-encoding"];
885
- if (typeof accept_encoding === "string") {
886
- return accept_encoding;
887
- }
888
- // Node can sometimes provide a string[] header shape.
889
- if (Array.isArray(accept_encoding) && accept_encoding.length > 0) {
890
- return accept_encoding.join(", ");
891
- }
892
- // Fallback to the raw http1 request headers if present.
893
- const req_accept_encoding = this.req?.headers?.["accept-encoding"];
894
- if (typeof req_accept_encoding === "string") {
895
- return req_accept_encoding;
896
- }
897
- if (Array.isArray(req_accept_encoding) && req_accept_encoding.length > 0) {
898
- return req_accept_encoding.join(", ");
899
- }
900
- // Default when header is absent.
901
- return "";
902
- };
903
- // Apply templates to in-memory bodies before any compression.
904
- body = this.apply_templates_to_body(body, templates);
905
- // -----------------------------------------
906
- // HTTP2
907
- // -----------------------------------------
908
- if (this.http2) {
909
- const stream = this.s;
910
- // Create http headers.
911
- const out_headers = this.create_http2_headers(status, headers);
912
- // -------------------------------------------------------
913
- // From_file fast path (http2)
914
- // -------------------------------------------------------
915
- if (from_file) {
916
- const from_path = from_file instanceof vlib.Path ? from_file : new vlib.Path(from_file);
917
- // Only apply templates when defined.
918
- const needs_template_replace = templates != null && Object.keys(templates).length > 0;
919
- const should_gzip = compress
920
- && get_accept_encoding().includes("gzip")
921
- && !(Utils.is_compressed_extension(from_path.extension()) ?? false);
922
- // Add content type.
923
- const content_type = Utils.mime_type(from_path.extension());
924
- if (content_type && out_headers["content-type"] == null) {
925
- out_headers["content-type"] = content_type;
926
- }
927
- // Only apply templates to text-like responses.
928
- const is_text_response = typeof content_type === "string"
929
- && (content_type.startsWith("text/")
930
- || content_type === "application/javascript"
931
- || content_type === "application/json"
932
- || content_type === "image/svg+xml"
933
- || content_type === "application/xml"
934
- || content_type === "text/xml");
935
- const should_apply_templates = needs_template_replace && is_text_response;
936
- // Only set gzip headers if we actually gzip.
937
- if (should_gzip) {
938
- out_headers["content-encoding"] = "gzip";
939
- out_headers["vary"] = "Accept-Encoding";
940
- // Do not set content-length when streaming gzip.
941
- delete out_headers["content-length"];
942
- }
943
- // Do not set content-length when template replacement is enabled.
944
- if (should_apply_templates) {
945
- delete out_headers["content-length"];
946
- }
947
- // If we are NOT gzipping and NOT replacing, use respondWithFile for best performance.
948
- if (!should_gzip && !should_apply_templates && typeof stream.respondWithFile === "function") {
949
- // respondWithFile handles opening/streaming internally.
950
- stream.respondWithFile(from_path.toString(), out_headers, {});
951
- if (debug.on(3))
952
- debug("Sending http2 file response: ", status, " - file: ", from_path.toString());
953
- this.finished = true;
954
- return this;
955
- }
956
- // Manual stream for gzip and/or template replacement.
957
- stream.respond(out_headers);
958
- const file_read_stream = fs.createReadStream(from_path.toString());
959
- const transforms = [];
960
- // Replace templates on-the-fly for text-like responses.
961
- if (should_apply_templates) {
962
- transforms.push(this.create_template_replace_transform(templates));
963
- }
964
- // Stream gzip to avoid blocking the event loop.
965
- if (should_gzip) {
966
- transforms.push(zlib.createGzip({ level: zlib.constants.Z_BEST_COMPRESSION }));
967
- }
968
- // Pipe: file -> (template_replace?) -> (gzip?) -> http2 stream.
969
- pipeline(file_read_stream, ...transforms, stream, (err) => {
970
- if (err) {
971
- // Close the stream to avoid leaking resources on pipeline error.
972
- try {
973
- stream.close();
974
- }
975
- catch { }
976
- }
977
- });
978
- if (debug.on(3))
979
- debug("Sending http2 streamed file response: ", status, " - file: ", from_path.toString());
980
- this.finished = true;
981
- return this;
982
- }
983
- // -------------------------------------------------------
984
- // Normal body path (http2)
985
- // -------------------------------------------------------
986
- else {
987
- // Is json.
988
- if (body && typeof body === "object" && Buffer.isBuffer(body) === false && (body instanceof Uint8Array) === false) {
989
- out_headers["content-type"] = "application/json";
990
- body = JSON.stringify(body);
991
- // Apply templates after stringify, since body just became a string.
992
- body = this.apply_templates_to_body(body, templates);
993
- }
994
- // Convert objects to string (kept from your logic).
995
- if (body
996
- && typeof body === "object"
997
- && !(body instanceof Buffer)
998
- && !(body instanceof Uint8Array)) {
999
- body = JSON.stringify(body);
1000
- // Apply templates after stringify.
1001
- body = this.apply_templates_to_body(body, templates);
1002
- }
1003
- const should_gzip_body = compress
1004
- && !!body
1005
- && get_accept_encoding().includes("gzip");
1006
- if (should_gzip_body) {
1007
- out_headers["content-encoding"] = "gzip";
1008
- out_headers["vary"] = "Accept-Encoding";
1009
- // No content-length if we compress asynchronously.
1010
- delete out_headers["content-length"];
1011
- }
1012
- // Respond.
1013
- stream.respond(out_headers);
1014
- // End.
1015
- if (debug.on(3))
1016
- debug("Sending response: ", status, " - has body: ", !!body);
1017
- if (!body) {
1018
- stream.end();
1019
- this.finished = true;
1020
- return this;
1021
- }
1022
- // gzip async (non-blocking) for in-memory bodies.
1023
- else if (should_gzip_body) {
1024
- const raw_buffer = (typeof body === "string")
1025
- ? Buffer.from(body)
1026
- : (Buffer.isBuffer(body) || body instanceof Uint8Array)
1027
- ? Buffer.from(body)
1028
- : Buffer.from(JSON.stringify(body));
1029
- zlib.gzip(raw_buffer, { level: zlib.constants.Z_BEST_COMPRESSION }, (err, gz_buffer) => {
1030
- if (err) {
1031
- // Fallback: send uncompressed if gzip fails.
1032
- stream.end(raw_buffer);
1033
- return;
1034
- }
1035
- stream.end(gz_buffer);
1036
- });
1037
- this.finished = true;
1038
- return this;
1039
- }
1040
- // Non-gzipped body path.
1041
- else {
1042
- if (Buffer.isBuffer(body) || body instanceof Uint8Array) {
1043
- stream.end(body);
1044
- }
1045
- else {
1046
- stream.end(Buffer.from(body));
1047
- }
1048
- this.finished = true;
1049
- return this;
1050
- }
1051
- }
1052
- }
1053
- // -----------------------------------------
1054
- // HTTP1
1055
- // -----------------------------------------
1056
- else {
1057
- const req = this.req;
1058
- const res = this.res;
1059
- // Set http1 headers.
1060
- this.set_http1_headers(status, headers);
1061
- // -------------------------------------------------------
1062
- // From_file path (http1)
1063
- // -------------------------------------------------------
1064
- if (from_file) {
1065
- // Ensure we dont create a new path if not needed, to use caching.
1066
- const from_path = from_file instanceof vlib.Path ? from_file : new vlib.Path(from_file);
1067
- // Add content type.
1068
- const content_type = Utils.mime_type(from_path.extension());
1069
- if (content_type) {
1070
- res.setHeader("Content-Type", content_type);
1071
- }
1072
- // Only apply templates when defined.
1073
- const needs_template_replace = templates != null && Object.keys(templates).length > 0;
1074
- // Only apply templates to text-like responses.
1075
- const is_text_response = typeof content_type === "string"
1076
- && (content_type.startsWith("text/")
1077
- || content_type === "application/javascript"
1078
- || content_type === "application/json"
1079
- || content_type === "image/svg+xml"
1080
- || content_type === "application/xml"
1081
- || content_type === "text/xml");
1082
- const should_apply_templates = needs_template_replace && is_text_response;
1083
- const should_gzip = compress
1084
- && get_accept_encoding().includes("gzip")
1085
- && !(Utils.is_compressed_extension(from_path.extension()) ?? false);
1086
- // If we gzip, do not set content-length (streaming).
1087
- if (should_gzip) {
1088
- res.setHeader("Content-Encoding", "gzip");
1089
- res.setHeader("Vary", "Accept-Encoding");
1090
- res.removeHeader("Content-Length");
1091
- }
1092
- else if (!should_apply_templates) {
1093
- // Only set content-length when no transforms are applied.
1094
- try {
1095
- if (from_path.is_file()) {
1096
- res.setHeader("Content-Length", from_path.size);
1097
- }
1098
- }
1099
- catch {
1100
- // Ignore stat errors, stream will error if file missing.
1101
- }
1102
- }
1103
- // If we replace templates, content-length is not reliable.
1104
- if (should_apply_templates) {
1105
- res.removeHeader("Content-Length");
1106
- }
1107
- const file_read_stream = fs.createReadStream(from_path.toString());
1108
- const transforms = [];
1109
- // Replace templates on-the-fly for text-like responses.
1110
- if (should_apply_templates) {
1111
- transforms.push(this.create_template_replace_transform(templates));
1112
- }
1113
- // Stream gzip to avoid blocking event loop.
1114
- if (should_gzip) {
1115
- transforms.push(zlib.createGzip({ level: zlib.constants.Z_BEST_COMPRESSION }));
1116
- }
1117
- // Pipe: file -> (template_replace?) -> (gzip?) -> http1 response.
1118
- pipeline(file_read_stream, ...transforms, res, (err) => {
1119
- if (err) {
1120
- // Destroy the response to stop work on error.
1121
- try {
1122
- res.destroy(err);
1123
- }
1124
- catch { }
1125
- }
1126
- });
1127
- if (debug.on(3))
1128
- debug("Sending http1 streamed file response: ", status, " - file: ", from_path.toString());
1129
- this.finished = true;
1130
- return this;
1131
- }
1132
- // -------------------------------------------------------
1133
- // Normal body path (http1)
1134
- // -------------------------------------------------------
1135
- else {
1136
- // Convert data.
1137
- if (body && typeof body === "object" && Buffer.isBuffer(body) === false && (body instanceof Uint8Array) === false) {
1138
- res.setHeader("Content-Type", "application/json");
1139
- body = JSON.stringify(body);
1140
- // Apply templates after stringify.
1141
- body = this.apply_templates_to_body(body, templates);
1142
- }
1143
- const should_gzip_body = compress
1144
- && !!body
1145
- && get_accept_encoding().includes("gzip");
1146
- // gzip async (non-blocking)
1147
- if (should_gzip_body) {
1148
- res.setHeader("Content-Encoding", "gzip");
1149
- res.setHeader("Vary", "Accept-Encoding");
1150
- res.removeHeader("Content-Length");
1151
- const raw_buffer = (typeof body === "string")
1152
- ? Buffer.from(body)
1153
- : (Buffer.isBuffer(body) || body instanceof Uint8Array)
1154
- ? Buffer.from(body)
1155
- : Buffer.from(JSON.stringify(body));
1156
- zlib.gzip(raw_buffer, { level: zlib.constants.Z_BEST_COMPRESSION }, (err, gz_buffer) => {
1157
- if (err) {
1158
- res.end(raw_buffer);
1159
- return;
1160
- }
1161
- res.end(gz_buffer);
1162
- });
1163
- if (debug.on(3))
1164
- debug("Sending http1 response: ", status, " - has body: ", !!body, " - gzip: true");
1165
- }
1166
- // Set data.
1167
- else if (body) {
1168
- res.end(body); // Do not use toString() here or it will cause issues with writing binary data.
1169
- }
1170
- else {
1171
- res.end();
1172
- }
1173
- // Set as finished.
1174
- this.finished = true;
1175
- return this;
1176
- }
1177
- }
1178
- }
1179
- // Send a successs response.
1180
- /**
1181
- * Send a response
1182
- *
1183
- * @param options The response options.
1184
- * @param options.status The response status.
1185
- * @param options.headers The response headers.
1186
- * @param options.data The data of the response body to send.
1187
- * @param options.compress Whether the response should be gzip-compressed.
1188
- * @example
1189
- * ```ts
1190
- * stream.success({data: "Hello World!"});
1191
- * ```
1192
- * @docs
1193
- */
1194
- success({ status = 200, headers = {}, data, from_file, compress = false } = {}) {
1195
- if (debug.on(3))
1196
- debug("Sending [success] response: ", status, " - body: ", data);
1197
- return this.send({ status, headers, data, compress, from_file });
1198
- }
1199
- // Send an error response.
1200
- /**
1201
- * Send an error response
1202
- *
1203
- * @param options The error response options.
1204
- * @param options.message The error message.
1205
- * @param options.type The error type.
1206
- * @param options.invalid_fields The invalid fields when validation fails.
1207
- * @param options.status The response status.
1208
- * @param options.headers The response headers.
1209
- * @param options.compress Whether the response should be gzip-compressed.
1210
- * @param options.data Optional data to include in the error response, nested in the JSON response under field `data`.
1211
- * @example
1212
- * ```ts
1213
- * stream.error({ message: "Some error occurred", status: 400 });
1214
- * ```
1215
- * @docs
1216
- */
1217
- error({ message, type = "APIError", invalid_fields = {}, status = 500, headers = {}, compress = false, data, }) {
1218
- if (debug.on(3))
1219
- debug("Sending [error] response: ", status, " - message: ", message);
1220
- const api_error = {
1221
- error: {
1222
- type,
1223
- message,
1224
- status,
1225
- invalid_fields,
1226
- },
1227
- data,
1228
- };
1229
- return this.send({ status, headers, compress, data: api_error });
1230
- }
1231
- /**
1232
- * Stream a response through a transform pipeline with an optional gzip step and a hard byte limit.
1233
- *
1234
- * @param options Pipeline options.
1235
- * @param options.status The HTTP status code to send.
1236
- * @param options.headers The response headers to send.
1237
- * @param options.body The readable stream to pipe into the response.
1238
- * @param options.transforms Optional transform streams applied in order.
1239
- * @param options.compress When true, gzip-compresses the streamed response if the client supports it.
1240
- * @param options.max_bytes The maximum number of bytes allowed to be written to the client.
1241
- * Set to `-1` for unlimited (use with caution).
1242
- */
1243
- pipeline({ status = 200, headers = {}, body, transforms = [], compress = false, max_bytes = 10 * 1024 * 1024, }) {
1244
- // Prevent double-sending on the same stream wrapper.
1245
- if (this.finished) {
1246
- throw new Error("Cannot pipeline a response that has already been finished.");
1247
- }
1248
- // Validate the status code early for predictable responses.
1249
- if (!Number.isInteger(status) || status < 100 || status > 599) {
1250
- throw new Error("Invalid status code.");
1251
- }
1252
- // Validate the max_bytes limit to prevent unbounded streaming.
1253
- if (!Number.isFinite(max_bytes)) {
1254
- throw new Error("Invalid max_bytes value.");
1255
- }
1256
- // Validate transform list to avoid accidental misuse and runaway pipelines.
1257
- if (!Array.isArray(transforms) || transforms.length > 32) {
1258
- throw new Error("Invalid transforms configuration.");
1259
- }
1260
- // Assign the sent status code for bookkeeping.
1261
- this.status_code = status;
1262
- // Mark as finished once we start writing headers and streaming.
1263
- this.finished = true;
1264
- // Create all streams list in the order they should be applied.
1265
- const all_streams = [body, ...transforms];
1266
- // Resolve accept-encoding from request headers for gzip negotiation.
1267
- const accept_encoding_header = this.headers?.["accept-encoding"];
1268
- const accept_encoding = typeof accept_encoding_header === "string"
1269
- ? accept_encoding_header
1270
- : Array.isArray(accept_encoding_header)
1271
- ? accept_encoding_header.join(", ")
1272
- : "";
1273
- // Detect if a content-encoding is already set to avoid double-compressing.
1274
- const has_content_encoding = (() => {
1275
- for (const k of Object.keys(headers ?? {})) {
1276
- if (k.toLowerCase() === "content-encoding")
1277
- return true;
1278
- }
1279
- const existing = this.get_header("content-encoding");
1280
- return existing != null;
1281
- })();
1282
- // Decide whether to gzip based on client support and existing encoding.
1283
- const should_gzip = compress === true && accept_encoding.includes("gzip") && !has_content_encoding;
1284
- // Append gzip as a transform so we stream-compress without buffering.
1285
- if (should_gzip) {
1286
- all_streams.push(zlib.createGzip({ level: zlib.constants.Z_BEST_COMPRESSION }));
1287
- }
1288
- // Create a hard byte limiter to protect memory/bandwidth and stop abuse.
1289
- if (max_bytes >= 0) {
1290
- let written = 0;
1291
- const limiter = new Transform({
1292
- transform(chunk, _enc, cb) {
1293
- written += chunk.length;
1294
- if (written > max_bytes) {
1295
- cb(new Error("Response exceeded max_bytes."));
1296
- return;
1297
- }
1298
- cb(null, chunk);
1299
- },
1300
- });
1301
- all_streams.push(limiter);
1302
- }
1303
- // Prepare a cleanup routine to stop work when the client disconnects or a stream errors.
1304
- const cleanup = (err) => {
1305
- for (const s of all_streams) {
1306
- if ("destroy" in s && typeof s.destroy === "function") {
1307
- s.destroy(err);
1308
- }
1309
- }
1310
- };
1311
- // Send headers and start piping depending on protocol.
1312
- if (this.http2) {
1313
- // Ensure the underlying HTTP/2 stream exists.
1314
- const h2 = this.s;
1315
- if (!h2) {
1316
- throw new Error("HTTP/2 stream is missing.");
1317
- }
1318
- // Start with any headers set earlier via set_header/set_headers.
1319
- const out_headers = this.create_http2_headers(status, headers);
1320
- // Set gzip headers only when we actually gzip.
1321
- if (should_gzip) {
1322
- out_headers["content-encoding"] = "gzip";
1323
- out_headers["vary"] = "Accept-Encoding";
1324
- }
1325
- // Strip content-length because streaming/transforms make it unreliable.
1326
- delete out_headers["content-length"];
1327
- // Write headers once, before streaming data.
1328
- h2.respond(out_headers);
1329
- // Abort work when the client disconnects.
1330
- h2.once("close", () => { cleanup(new Error("Client disconnected.")); });
1331
- // Pipe: body -> transforms... -> (gzip?) -> (limiter?) -> http2 stream.
1332
- pipeline(...all_streams, h2, (err) => {
1333
- if (err) {
1334
- // Destroy the stream to stop further writes on error.
1335
- cleanup(err instanceof Error ? err : new Error("Pipeline failed."));
1336
- try {
1337
- h2.close();
1338
- }
1339
- catch { }
1340
- }
1341
- });
1342
- return this;
1343
- }
1344
- else {
1345
- // HTTP/1.1 response path.
1346
- const res = this.res;
1347
- if (!res) {
1348
- throw new Error("HTTP/1.1 response is missing.");
1349
- }
1350
- // Set http1 headers.
1351
- this.set_http1_headers(status, headers);
1352
- // Set gzip headers only when we actually gzip.
1353
- if (should_gzip) {
1354
- res.setHeader("Content-Encoding", "gzip");
1355
- res.setHeader("Vary", "Accept-Encoding");
1356
- }
1357
- // Strip content-length because streaming/transforms make it unreliable.
1358
- res.removeHeader("Content-Length");
1359
- // Abort work when the client disconnects.
1360
- res.once("close", () => { cleanup(new Error("Client disconnected.")); });
1361
- // Pipe: body -> transforms... -> (gzip?) -> (limiter?) -> http1 response.
1362
- pipeline(...all_streams, res, (err) => {
1363
- if (err) {
1364
- // Destroy the response to stop further writes on error.
1365
- cleanup(err instanceof Error ? err : new Error("Pipeline failed."));
1366
- try {
1367
- res.destroy();
1368
- }
1369
- catch { }
1370
- }
1371
- });
1372
- }
1373
- return this;
1374
- }
1375
- // Set headers.
1376
- /**
1377
- * Add a new header to the response data.
1378
- *
1379
- * @param name The header name.
1380
- * @param value The header value.
1381
- * @example
1382
- * ```ts
1383
- * stream.set_header("Connection", "close");
1384
- * ```
1385
- * @docs
1386
- */
1387
- set_header(name, value) {
1388
- name = name.toLowerCase();
1389
- if (this.http2) {
1390
- this.res_headers[name] = value;
1391
- }
1392
- else {
1393
- this.res_headers.append([name, value]);
1394
- }
1395
- return this;
1396
- }
1397
- // Set headers.
1398
- /**
1399
- * Add new headers to the response data.
1400
- *
1401
- * @param headers The new response headers.
1402
- * @example
1403
- * ```ts
1404
- * stream.set_headers({"Connection": "close"});
1405
- * ```
1406
- * @docs
1407
- */
1408
- set_headers(headers = {}) {
1409
- if (headers == null) {
1410
- return this;
1411
- }
1412
- if (this.http2) {
1413
- Object.keys(headers).forEach((key) => {
1414
- this.res_headers[key.toLowerCase()] = headers[key];
1415
- });
1416
- }
1417
- else {
1418
- Object.keys(headers).forEach((key) => {
1419
- this.res_headers.append([key.toLowerCase(), headers[key]]);
1420
- });
1421
- }
1422
- return this;
1423
- }
1424
- /**
1425
- * Get an added response header.
1426
- *
1427
- * @param name The header name.
1428
- * @example
1429
- * ```ts
1430
- * stream.get_header("Connection");
1431
- * ```
1432
- * @docs
1433
- */
1434
- get_header(name) {
1435
- name = name.toLowerCase();
1436
- if (this.http2) {
1437
- return this.res_headers[name];
1438
- }
1439
- else {
1440
- return this.res_headers.find((h) => h[0] === name)?.[1];
1441
- }
1442
- }
1443
- /**
1444
- * Remove header names from the response data.
1445
- *
1446
- * @param names The header names to remove.
1447
- * @example
1448
- * ```ts
1449
- * stream.remove_header("Connection", "User-Agent");
1450
- * ```
1451
- * @docs
1452
- */
1453
- remove_header(...names) {
1454
- // Normalize header names.
1455
- names = names.map((n) => n.toLowerCase());
1456
- if (this.http1) {
1457
- const headers = [];
1458
- for (let i = 0; i < this.res_headers.length; i++) {
1459
- if (!names.includes(this.res_headers[i][0])) {
1460
- headers.push(this.res_headers[i]);
1461
- }
1462
- }
1463
- this.res_headers = headers;
1464
- }
1465
- else {
1466
- for (let i = 0; i < names.length; i++) {
1467
- delete this.res_headers[names[i]];
1468
- }
1469
- }
1470
- return this;
1471
- }
1472
- /**
1473
- * Alias of {@link remove_header}.
1474
- *
1475
- * @param names The header names to remove.
1476
- */
1477
- remove_headers(...names) {
1478
- return this.remove_header(...names);
1479
- }
1480
- /**
1481
- * Set a cookie to be sent with the response.
1482
- *
1483
- * Accepts either:
1484
- * 1) a pre-built cookie header string (used as-is, no validation), or
1485
- * 2) a structured object describing the cookie, from which a standards-compliant
1486
- * cookie string will be generated.
1487
- *
1488
- * If a cookie with the same name already exists in the pending response list,
1489
- * it will be replaced.
1490
- *
1491
- * @warning Cookies are only included in the response when using `send()`,
1492
- * `success()` or `error()`.
1493
- *
1494
- * @example
1495
- * ```ts
1496
- * stream.set_cookie("sid=abc123; Path=/; SameSite=Lax; Secure; HttpOnly");
1497
- *
1498
- * stream.set_cookie({
1499
- * name: "sid",
1500
- * value: session_id,
1501
- * http_only: true,
1502
- * secure: true,
1503
- * same_site: "Lax",
1504
- * path: "/",
1505
- * max_age: 60 * 60 * 24 * 14,
1506
- * });
1507
- * ```
1508
- */
1509
- set_cookie(cookie) {
1510
- // If the user provided a raw cookie string, trust it and use it as-is.
1511
- if (typeof cookie === "string") {
1512
- const cookie_str = cookie.trim();
1513
- const name_end = cookie_str.indexOf("=");
1514
- if (name_end !== -1) {
1515
- const name = cookie_str.substring(0, name_end);
1516
- for (let i = 0; i < this.res_cookies.length; i++) {
1517
- if (this.res_cookies[i].startsWith(name)) {
1518
- this.res_cookies[i] = cookie_str;
1519
- return this;
1520
- }
1521
- }
1522
- }
1523
- this.res_cookies.push(cookie_str);
1524
- return this;
1525
- }
1526
- // Structured cookie path (commercial-grade, predictable, minimal validation)
1527
- const { name, value, path = "/", domain, max_age, expires, secure, http_only, same_site, prefix, extra, } = cookie;
1528
- if (!name || typeof name !== "string") {
1529
- throw new Error("set_cookie: cookie.name must be a non-empty string");
1530
- }
1531
- const full_name = `${prefix ?? ""}${name}`;
1532
- // Enforce prefix rules (light but correct)
1533
- if (prefix === "__Host-") {
1534
- if (domain) {
1535
- throw new Error("__Host- cookies must not include a domain attribute");
1536
- }
1537
- if (path !== "/") {
1538
- throw new Error("__Host- cookies must have path='/'");
1539
- }
1540
- if (!secure) {
1541
- throw new Error("__Host- cookies require secure=true");
1542
- }
1543
- }
1544
- if (prefix === "__Secure-" && !secure) {
1545
- throw new Error("__Secure- cookies require secure=true");
1546
- }
1547
- const encoded_value = value === null || typeof value === "undefined"
1548
- ? ""
1549
- : encodeURIComponent(String(value));
1550
- const parts = [];
1551
- parts.push(`${full_name}=${encoded_value}`);
1552
- if (path)
1553
- parts.push(`Path=${path}`);
1554
- if (domain)
1555
- parts.push(`Domain=${domain}`);
1556
- if (typeof max_age === "number" && Number.isFinite(max_age)) {
1557
- parts.push(`Max-Age=${Math.trunc(max_age)}`);
1558
- }
1559
- if (expires) {
1560
- const exp = expires instanceof Date ? expires.toUTCString() : String(expires).trim();
1561
- if (exp)
1562
- parts.push(`Expires=${exp}`);
1563
- }
1564
- if (secure)
1565
- parts.push("Secure");
1566
- if (http_only)
1567
- parts.push("HttpOnly");
1568
- if (same_site)
1569
- parts.push(`SameSite=${same_site}`);
1570
- if (extra && Array.isArray(extra)) {
1571
- for (const attr of extra) {
1572
- const trimmed = String(attr).trim();
1573
- if (trimmed)
1574
- parts.push(trimmed);
1575
- }
1576
- }
1577
- const cookie_str = parts.join("; ");
1578
- const name_end = cookie_str.indexOf("=");
1579
- if (name_end !== -1) {
1580
- const existing_name = cookie_str.substring(0, name_end);
1581
- for (let i = 0; i < this.res_cookies.length; i++) {
1582
- if (this.res_cookies[i].startsWith(existing_name)) {
1583
- this.res_cookies[i] = cookie_str;
1584
- return this;
1585
- }
1586
- }
1587
- }
1588
- this.res_cookies.push(cookie_str);
1589
- return this;
1590
- }
1591
- // Set cookies.
1592
- /**
1593
- * Set cookies that will be sent with the response.
1594
- *
1595
- * @warning Will only be added to the response when the user uses `send()`, `success()` or `error()`.
1596
- * @param cookies The cookie strings.
1597
- * @example
1598
- * ```ts
1599
- * stream.set_cookies("MyCookie1=Hello World;", "MyCookie2=Hello Universe;");
1600
- * ```
1601
- * @docs
1602
- */
1603
- set_cookies(...cookies) {
1604
- for (let i = 0; i < cookies.length; i++) {
1605
- this.set_cookie(cookies[i]);
1606
- }
1607
- return this;
1608
- }
1609
- }
1610
- ;
1611
- ;