boltstore 0.5.1 → 0.6.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 (423) hide show
  1. package/README.md +65 -23
  2. package/dist/admin/api-keys.d.ts +87 -0
  3. package/dist/admin/api-keys.d.ts.map +1 -0
  4. package/dist/admin/api-keys.js +267 -0
  5. package/dist/admin/api-keys.js.map +1 -0
  6. package/dist/admin/backup.d.ts +76 -0
  7. package/dist/admin/backup.d.ts.map +1 -0
  8. package/dist/admin/backup.js +255 -0
  9. package/dist/admin/backup.js.map +1 -0
  10. package/dist/admin/import-export/csv.d.ts +4 -0
  11. package/dist/admin/import-export/csv.d.ts.map +1 -0
  12. package/dist/admin/import-export/csv.js +123 -0
  13. package/dist/admin/import-export/csv.js.map +1 -0
  14. package/dist/admin/import-export/export.d.ts +4 -0
  15. package/dist/admin/import-export/export.d.ts.map +1 -0
  16. package/dist/admin/import-export/export.js +66 -0
  17. package/dist/admin/import-export/export.js.map +1 -0
  18. package/dist/admin/import-export/import.d.ts +4 -0
  19. package/dist/admin/import-export/import.d.ts.map +1 -0
  20. package/dist/admin/import-export/import.js +253 -0
  21. package/dist/admin/import-export/import.js.map +1 -0
  22. package/dist/admin/import-export/index.d.ts +7 -0
  23. package/dist/admin/import-export/index.d.ts.map +1 -0
  24. package/dist/admin/import-export/index.js +7 -0
  25. package/dist/admin/import-export/index.js.map +1 -0
  26. package/dist/admin/import-export/json-input.d.ts +2 -0
  27. package/dist/admin/import-export/json-input.d.ts.map +1 -0
  28. package/dist/admin/import-export/json-input.js +42 -0
  29. package/dist/admin/import-export/json-input.js.map +1 -0
  30. package/dist/admin/import-export/schema-inference.d.ts +6 -0
  31. package/dist/admin/import-export/schema-inference.d.ts.map +1 -0
  32. package/dist/admin/import-export/schema-inference.js +34 -0
  33. package/dist/admin/import-export/schema-inference.js.map +1 -0
  34. package/dist/admin/import-export/types.d.ts +40 -0
  35. package/dist/admin/import-export/types.d.ts.map +1 -0
  36. package/dist/admin/import-export/types.js +2 -0
  37. package/dist/admin/import-export/types.js.map +1 -0
  38. package/dist/admin/oauth/github.d.ts +12 -0
  39. package/dist/admin/oauth/github.d.ts.map +1 -0
  40. package/dist/admin/oauth/github.js +78 -0
  41. package/dist/admin/oauth/github.js.map +1 -0
  42. package/dist/admin/oauth/google.d.ts +12 -0
  43. package/dist/admin/oauth/google.d.ts.map +1 -0
  44. package/dist/admin/oauth/google.js +55 -0
  45. package/dist/admin/oauth/google.js.map +1 -0
  46. package/dist/admin/oauth/handler.d.ts +5 -0
  47. package/dist/admin/oauth/handler.d.ts.map +1 -0
  48. package/dist/admin/oauth/handler.js +37 -0
  49. package/dist/admin/oauth/handler.js.map +1 -0
  50. package/dist/admin/oauth/index.d.ts +5 -0
  51. package/dist/admin/oauth/index.d.ts.map +1 -0
  52. package/dist/admin/oauth/index.js +5 -0
  53. package/dist/admin/oauth/index.js.map +1 -0
  54. package/dist/admin/oauth/registry.d.ts +16 -0
  55. package/dist/admin/oauth/registry.d.ts.map +1 -0
  56. package/dist/admin/oauth/registry.js +37 -0
  57. package/dist/admin/oauth/registry.js.map +1 -0
  58. package/dist/admin/oauth/types.d.ts +14 -0
  59. package/dist/admin/oauth/types.d.ts.map +1 -0
  60. package/dist/admin/oauth/types.js +2 -0
  61. package/dist/admin/oauth/types.js.map +1 -0
  62. package/dist/admin/oauth/user.d.ts +12 -0
  63. package/dist/admin/oauth/user.d.ts.map +1 -0
  64. package/dist/admin/oauth/user.js +28 -0
  65. package/dist/admin/oauth/user.js.map +1 -0
  66. package/dist/admin/query.d.ts +54 -0
  67. package/dist/admin/query.d.ts.map +1 -0
  68. package/dist/admin/query.js +168 -0
  69. package/dist/admin/query.js.map +1 -0
  70. package/dist/admin/transaction.d.ts +46 -0
  71. package/dist/admin/transaction.d.ts.map +1 -0
  72. package/dist/admin/transaction.js +52 -0
  73. package/dist/admin/transaction.js.map +1 -0
  74. package/dist/admin/views.d.ts +64 -0
  75. package/dist/admin/views.d.ts.map +1 -0
  76. package/dist/admin/views.js +197 -0
  77. package/dist/admin/views.js.map +1 -0
  78. package/dist/audit.d.ts +36 -0
  79. package/dist/audit.d.ts.map +1 -0
  80. package/dist/audit.js +92 -0
  81. package/dist/audit.js.map +1 -0
  82. package/dist/auth/jwt.d.ts +8 -0
  83. package/dist/auth/jwt.d.ts.map +1 -0
  84. package/dist/auth/jwt.js +81 -0
  85. package/dist/auth/jwt.js.map +1 -0
  86. package/dist/auth/password.d.ts +4 -0
  87. package/dist/auth/password.d.ts.map +1 -0
  88. package/dist/auth/password.js +15 -0
  89. package/dist/auth/password.js.map +1 -0
  90. package/dist/auth/tables.d.ts +5 -0
  91. package/dist/auth/tables.d.ts.map +1 -0
  92. package/dist/auth/tables.js +65 -0
  93. package/dist/auth/tables.js.map +1 -0
  94. package/dist/auth/tokens.d.ts +16 -0
  95. package/dist/auth/tokens.d.ts.map +1 -0
  96. package/dist/auth/tokens.js +126 -0
  97. package/dist/auth/tokens.js.map +1 -0
  98. package/dist/auth/types.d.ts +36 -0
  99. package/dist/auth/types.d.ts.map +1 -0
  100. package/dist/auth/types.js +2 -0
  101. package/dist/auth/types.js.map +1 -0
  102. package/dist/auth/users.d.ts +9 -0
  103. package/dist/auth/users.d.ts.map +1 -0
  104. package/dist/auth/users.js +83 -0
  105. package/dist/auth/users.js.map +1 -0
  106. package/dist/auth/validation.d.ts +5 -0
  107. package/dist/auth/validation.d.ts.map +1 -0
  108. package/dist/auth/validation.js +25 -0
  109. package/dist/auth/validation.js.map +1 -0
  110. package/dist/auth.d.ts +9 -0
  111. package/dist/auth.d.ts.map +1 -0
  112. package/dist/auth.js +9 -0
  113. package/dist/auth.js.map +1 -0
  114. package/dist/cli.d.ts +12 -0
  115. package/dist/cli.d.ts.map +1 -0
  116. package/dist/cli.js +322 -0
  117. package/dist/cli.js.map +1 -0
  118. package/dist/collections/ddl.d.ts +25 -0
  119. package/dist/collections/ddl.d.ts.map +1 -0
  120. package/dist/collections/ddl.js +83 -0
  121. package/dist/collections/ddl.js.map +1 -0
  122. package/dist/collections/management.d.ts +57 -0
  123. package/dist/collections/management.d.ts.map +1 -0
  124. package/dist/collections/management.js +289 -0
  125. package/dist/collections/management.js.map +1 -0
  126. package/dist/collections.d.ts +3 -0
  127. package/dist/collections.d.ts.map +1 -0
  128. package/dist/collections.js +3 -0
  129. package/dist/collections.js.map +1 -0
  130. package/dist/config.d.ts +47 -0
  131. package/dist/config.d.ts.map +1 -0
  132. package/dist/config.js +274 -0
  133. package/dist/config.js.map +1 -0
  134. package/dist/db/cast.d.ts +15 -0
  135. package/dist/db/cast.d.ts.map +1 -0
  136. package/dist/db/cast.js +16 -0
  137. package/dist/db/cast.js.map +1 -0
  138. package/dist/db/manager.d.ts +93 -0
  139. package/dist/db/manager.d.ts.map +1 -0
  140. package/dist/db/manager.js +209 -0
  141. package/dist/db/manager.js.map +1 -0
  142. package/dist/db/pool.d.ts +99 -0
  143. package/dist/db/pool.d.ts.map +1 -0
  144. package/dist/db/pool.js +232 -0
  145. package/dist/db/pool.js.map +1 -0
  146. package/dist/entry.d.ts +11 -0
  147. package/dist/entry.d.ts.map +1 -0
  148. package/dist/entry.js +80 -0
  149. package/dist/entry.js.map +1 -0
  150. package/dist/index.d.ts +10 -0
  151. package/dist/index.d.ts.map +1 -0
  152. package/dist/index.js +47 -0
  153. package/dist/index.js.map +1 -0
  154. package/dist/indexes.d.ts +61 -0
  155. package/dist/indexes.d.ts.map +1 -0
  156. package/dist/indexes.js +174 -0
  157. package/dist/indexes.js.map +1 -0
  158. package/dist/logger.d.ts +40 -0
  159. package/dist/logger.d.ts.map +1 -0
  160. package/dist/logger.js +147 -0
  161. package/dist/logger.js.map +1 -0
  162. package/dist/middleware/auth.d.ts +43 -0
  163. package/dist/middleware/auth.d.ts.map +1 -0
  164. package/dist/middleware/auth.js +87 -0
  165. package/dist/middleware/auth.js.map +1 -0
  166. package/dist/middleware/cors.d.ts +28 -0
  167. package/dist/middleware/cors.d.ts.map +1 -0
  168. package/dist/middleware/cors.js +71 -0
  169. package/dist/middleware/cors.js.map +1 -0
  170. package/dist/middleware/proxy.d.ts +10 -0
  171. package/dist/middleware/proxy.d.ts.map +1 -0
  172. package/dist/middleware/proxy.js +31 -0
  173. package/dist/middleware/proxy.js.map +1 -0
  174. package/dist/middleware/rate-limit.d.ts +64 -0
  175. package/dist/middleware/rate-limit.d.ts.map +1 -0
  176. package/dist/middleware/rate-limit.js +130 -0
  177. package/dist/middleware/rate-limit.js.map +1 -0
  178. package/dist/migrations.d.ts +56 -0
  179. package/dist/migrations.d.ts.map +1 -0
  180. package/dist/migrations.js +133 -0
  181. package/dist/migrations.js.map +1 -0
  182. package/dist/query/builder.d.ts +6 -0
  183. package/dist/query/builder.d.ts.map +1 -0
  184. package/dist/query/builder.js +97 -0
  185. package/dist/query/builder.js.map +1 -0
  186. package/dist/query/executor.d.ts +3 -0
  187. package/dist/query/executor.d.ts.map +1 -0
  188. package/dist/query/executor.js +64 -0
  189. package/dist/query/executor.js.map +1 -0
  190. package/dist/query/filter-builder.d.ts +8 -0
  191. package/dist/query/filter-builder.d.ts.map +1 -0
  192. package/dist/query/filter-builder.js +128 -0
  193. package/dist/query/filter-builder.js.map +1 -0
  194. package/dist/query/search.d.ts +4 -0
  195. package/dist/query/search.d.ts.map +1 -0
  196. package/dist/query/search.js +28 -0
  197. package/dist/query/search.js.map +1 -0
  198. package/dist/query/types.d.ts +45 -0
  199. package/dist/query/types.d.ts.map +1 -0
  200. package/dist/query/types.js +2 -0
  201. package/dist/query/types.js.map +1 -0
  202. package/dist/query.d.ts +6 -0
  203. package/dist/query.d.ts.map +1 -0
  204. package/dist/query.js +6 -0
  205. package/dist/query.js.map +1 -0
  206. package/dist/records/batch.d.ts +13 -0
  207. package/dist/records/batch.d.ts.map +1 -0
  208. package/dist/records/batch.js +113 -0
  209. package/dist/records/batch.js.map +1 -0
  210. package/dist/records/count.d.ts +5 -0
  211. package/dist/records/count.d.ts.map +1 -0
  212. package/dist/records/count.js +34 -0
  213. package/dist/records/count.js.map +1 -0
  214. package/dist/records/crud.d.ts +8 -0
  215. package/dist/records/crud.d.ts.map +1 -0
  216. package/dist/records/crud.js +121 -0
  217. package/dist/records/crud.js.map +1 -0
  218. package/dist/records/distinct.d.ts +5 -0
  219. package/dist/records/distinct.d.ts.map +1 -0
  220. package/dist/records/distinct.js +22 -0
  221. package/dist/records/distinct.js.map +1 -0
  222. package/dist/records/helpers.d.ts +4 -0
  223. package/dist/records/helpers.d.ts.map +1 -0
  224. package/dist/records/helpers.js +9 -0
  225. package/dist/records/helpers.js.map +1 -0
  226. package/dist/records/list.d.ts +44 -0
  227. package/dist/records/list.d.ts.map +1 -0
  228. package/dist/records/list.js +133 -0
  229. package/dist/records/list.js.map +1 -0
  230. package/dist/records/schema-cache.d.ts +8 -0
  231. package/dist/records/schema-cache.d.ts.map +1 -0
  232. package/dist/records/schema-cache.js +64 -0
  233. package/dist/records/schema-cache.js.map +1 -0
  234. package/dist/records.d.ts +8 -0
  235. package/dist/records.d.ts.map +1 -0
  236. package/dist/records.js +8 -0
  237. package/dist/records.js.map +1 -0
  238. package/dist/relations.d.ts +50 -0
  239. package/dist/relations.d.ts.map +1 -0
  240. package/dist/relations.js +179 -0
  241. package/dist/relations.js.map +1 -0
  242. package/dist/rls.d.ts +63 -0
  243. package/dist/rls.d.ts.map +1 -0
  244. package/dist/rls.js +146 -0
  245. package/dist/rls.js.map +1 -0
  246. package/dist/router.d.ts +53 -0
  247. package/dist/router.d.ts.map +1 -0
  248. package/dist/router.js +104 -0
  249. package/dist/router.js.map +1 -0
  250. package/dist/routes/admin-query.d.ts +5 -0
  251. package/dist/routes/admin-query.d.ts.map +1 -0
  252. package/dist/routes/admin-query.js +57 -0
  253. package/dist/routes/admin-query.js.map +1 -0
  254. package/dist/routes/api-keys.d.ts +12 -0
  255. package/dist/routes/api-keys.d.ts.map +1 -0
  256. package/dist/routes/api-keys.js +114 -0
  257. package/dist/routes/api-keys.js.map +1 -0
  258. package/dist/routes/auth.d.ts +10 -0
  259. package/dist/routes/auth.d.ts.map +1 -0
  260. package/dist/routes/auth.js +116 -0
  261. package/dist/routes/auth.js.map +1 -0
  262. package/dist/routes/backup.d.ts +5 -0
  263. package/dist/routes/backup.d.ts.map +1 -0
  264. package/dist/routes/backup.js +88 -0
  265. package/dist/routes/backup.js.map +1 -0
  266. package/dist/routes/collections.d.ts +5 -0
  267. package/dist/routes/collections.d.ts.map +1 -0
  268. package/dist/routes/collections.js +110 -0
  269. package/dist/routes/collections.js.map +1 -0
  270. package/dist/routes/databases.d.ts +5 -0
  271. package/dist/routes/databases.d.ts.map +1 -0
  272. package/dist/routes/databases.js +90 -0
  273. package/dist/routes/databases.js.map +1 -0
  274. package/dist/routes/health.d.ts +9 -0
  275. package/dist/routes/health.d.ts.map +1 -0
  276. package/dist/routes/health.js +34 -0
  277. package/dist/routes/health.js.map +1 -0
  278. package/dist/routes/import-export.d.ts +8 -0
  279. package/dist/routes/import-export.d.ts.map +1 -0
  280. package/dist/routes/import-export.js +173 -0
  281. package/dist/routes/import-export.js.map +1 -0
  282. package/dist/routes/indexes.d.ts +5 -0
  283. package/dist/routes/indexes.d.ts.map +1 -0
  284. package/dist/routes/indexes.js +94 -0
  285. package/dist/routes/indexes.js.map +1 -0
  286. package/dist/routes/migrations.d.ts +5 -0
  287. package/dist/routes/migrations.d.ts.map +1 -0
  288. package/dist/routes/migrations.js +87 -0
  289. package/dist/routes/migrations.js.map +1 -0
  290. package/dist/routes/oauth.d.ts +5 -0
  291. package/dist/routes/oauth.d.ts.map +1 -0
  292. package/dist/routes/oauth.js +35 -0
  293. package/dist/routes/oauth.js.map +1 -0
  294. package/dist/routes/query.d.ts +5 -0
  295. package/dist/routes/query.d.ts.map +1 -0
  296. package/dist/routes/query.js +36 -0
  297. package/dist/routes/query.js.map +1 -0
  298. package/dist/routes/records.d.ts +5 -0
  299. package/dist/routes/records.d.ts.map +1 -0
  300. package/dist/routes/records.js +181 -0
  301. package/dist/routes/records.js.map +1 -0
  302. package/dist/routes/transactions.d.ts +5 -0
  303. package/dist/routes/transactions.d.ts.map +1 -0
  304. package/dist/routes/transactions.js +43 -0
  305. package/dist/routes/transactions.js.map +1 -0
  306. package/dist/routes/views.d.ts +5 -0
  307. package/dist/routes/views.d.ts.map +1 -0
  308. package/dist/routes/views.js +123 -0
  309. package/dist/routes/views.js.map +1 -0
  310. package/dist/server.d.ts +80 -0
  311. package/dist/server.d.ts.map +1 -0
  312. package/dist/server.js +271 -0
  313. package/dist/server.js.map +1 -0
  314. package/package.json +20 -40
  315. package/bin/cli.ts +0 -185
  316. package/src/admin/assets.ts +0 -134
  317. package/src/admin/serve.ts +0 -447
  318. package/src/admin-ui/App.vue +0 -71
  319. package/src/admin-ui/api/client.ts +0 -179
  320. package/src/admin-ui/components/Icon.vue +0 -85
  321. package/src/admin-ui/components/Sidebar.vue +0 -275
  322. package/src/admin-ui/components/StatCard.vue +0 -40
  323. package/src/admin-ui/dist/assets/ApiKeys.css +0 -1
  324. package/src/admin-ui/dist/assets/ApiKeys.js +0 -1
  325. package/src/admin-ui/dist/assets/AppDashboard.css +0 -1
  326. package/src/admin-ui/dist/assets/AppDashboard.js +0 -1
  327. package/src/admin-ui/dist/assets/Backups.js +0 -1
  328. package/src/admin-ui/dist/assets/Dashboard.css +0 -1
  329. package/src/admin-ui/dist/assets/Dashboard.js +0 -3
  330. package/src/admin-ui/dist/assets/DataBrowser.css +0 -1
  331. package/src/admin-ui/dist/assets/DataBrowser.js +0 -1
  332. package/src/admin-ui/dist/assets/Docs.css +0 -1
  333. package/src/admin-ui/dist/assets/Docs.js +0 -1
  334. package/src/admin-ui/dist/assets/FileBrowser.css +0 -1
  335. package/src/admin-ui/dist/assets/FileBrowser.js +0 -1
  336. package/src/admin-ui/dist/assets/HookEditor.css +0 -1
  337. package/src/admin-ui/dist/assets/HookEditor.js +0 -2
  338. package/src/admin-ui/dist/assets/LogViewer.css +0 -1
  339. package/src/admin-ui/dist/assets/LogViewer.js +0 -1
  340. package/src/admin-ui/dist/assets/Login.css +0 -1
  341. package/src/admin-ui/dist/assets/Login.js +0 -1
  342. package/src/admin-ui/dist/assets/SchemaBuilder.css +0 -1
  343. package/src/admin-ui/dist/assets/SchemaBuilder.js +0 -1
  344. package/src/admin-ui/dist/assets/Settings.js +0 -1
  345. package/src/admin-ui/dist/assets/Setup.css +0 -1
  346. package/src/admin-ui/dist/assets/Setup.js +0 -1
  347. package/src/admin-ui/dist/assets/StatCard.css +0 -1
  348. package/src/admin-ui/dist/assets/StatCard.js +0 -1
  349. package/src/admin-ui/dist/assets/main.css +0 -1
  350. package/src/admin-ui/dist/assets/main.js +0 -30
  351. package/src/admin-ui/dist/index.html +0 -49
  352. package/src/admin-ui/index.html +0 -48
  353. package/src/admin-ui/main.ts +0 -25
  354. package/src/admin-ui/pages/ApiKeys.vue +0 -198
  355. package/src/admin-ui/pages/AppDashboard.vue +0 -274
  356. package/src/admin-ui/pages/Applications.vue +0 -123
  357. package/src/admin-ui/pages/Backups.vue +0 -140
  358. package/src/admin-ui/pages/Dashboard.vue +0 -293
  359. package/src/admin-ui/pages/DataBrowser.vue +0 -310
  360. package/src/admin-ui/pages/Docs.vue +0 -40
  361. package/src/admin-ui/pages/FileBrowser.vue +0 -587
  362. package/src/admin-ui/pages/HookEditor.vue +0 -258
  363. package/src/admin-ui/pages/LogViewer.vue +0 -109
  364. package/src/admin-ui/pages/Login.vue +0 -229
  365. package/src/admin-ui/pages/SchemaBuilder.vue +0 -501
  366. package/src/admin-ui/pages/Settings.vue +0 -251
  367. package/src/admin-ui/pages/Setup.vue +0 -275
  368. package/src/admin-ui/router.ts +0 -169
  369. package/src/admin-ui/stores/application.ts +0 -68
  370. package/src/admin-ui/stores/auth.ts +0 -109
  371. package/src/admin-ui/style.css +0 -530
  372. package/src/admin-ui/tsconfig.json +0 -21
  373. package/src/admin-ui/version.ts +0 -3
  374. package/src/admin-ui/vite.config.ts +0 -35
  375. package/src/api/admin-config.ts +0 -596
  376. package/src/api/admin.ts +0 -8
  377. package/src/api/aggregate.ts +0 -104
  378. package/src/api/applications.ts +0 -148
  379. package/src/api/auth.ts +0 -690
  380. package/src/api/backups.ts +0 -173
  381. package/src/api/batch.ts +0 -135
  382. package/src/api/collections.ts +0 -354
  383. package/src/api/files.ts +0 -801
  384. package/src/api/health.ts +0 -48
  385. package/src/api/helpers.ts +0 -86
  386. package/src/api/middleware/auth.ts +0 -202
  387. package/src/api/middleware/cors.ts +0 -37
  388. package/src/api/middleware/logging.ts +0 -27
  389. package/src/api/middleware/ratelimit.ts +0 -142
  390. package/src/api/middleware/rls.ts +0 -37
  391. package/src/api/records.ts +0 -563
  392. package/src/api/router.ts +0 -296
  393. package/src/app.ts +0 -617
  394. package/src/auth/apikey.ts +0 -73
  395. package/src/auth/jwt.ts +0 -210
  396. package/src/auth/oauth2.ts +0 -144
  397. package/src/auth/password.ts +0 -68
  398. package/src/backup/manager.ts +0 -227
  399. package/src/config/yaml.ts +0 -78
  400. package/src/config.ts +0 -240
  401. package/src/db/application-migrations.ts +0 -112
  402. package/src/db/application-schema.ts +0 -297
  403. package/src/db/migrations.ts +0 -54
  404. package/src/db/pool.ts +0 -143
  405. package/src/db/system-schema.ts +0 -153
  406. package/src/hooks/api.ts +0 -157
  407. package/src/hooks/loader.ts +0 -263
  408. package/src/hooks/runner.ts +0 -76
  409. package/src/index.ts +0 -17
  410. package/src/logging/logger.ts +0 -131
  411. package/src/realtime/broadcast.ts +0 -132
  412. package/src/realtime/subscriptions.ts +0 -124
  413. package/src/security/rls-engine.ts +0 -183
  414. package/src/security/sanitizer.ts +0 -72
  415. package/src/storage/interface.ts +0 -48
  416. package/src/storage/local.ts +0 -189
  417. package/src/storage/mime-types.ts +0 -32
  418. package/src/storage/s3.ts +0 -213
  419. package/src/sync/changelog.ts +0 -247
  420. package/src/sync/engine.ts +0 -159
  421. package/src/sync/lamport.ts +0 -48
  422. package/src/sync/protocol.ts +0 -234
  423. package/src/version.ts +0 -2
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Structured JSON logger with levels, request ID tracing, and asynchronous batched flushing.
3
+ *
4
+ * Logs are buffered in memory and flushed asynchronously on a short interval or when the
5
+ * buffer reaches a size threshold. This keeps the hot path non-blocking while still ensuring
6
+ * logs are written in order within each flush.
7
+ *
8
+ * @module boltstore/logger
9
+ */
10
+ export type LogLevel = "debug" | "info" | "warn" | "error";
11
+ export interface LogEntry {
12
+ level: LogLevel;
13
+ message: string;
14
+ timestamp: string;
15
+ request_id?: string;
16
+ method?: string;
17
+ path?: string;
18
+ client_ip?: string;
19
+ user_agent?: string;
20
+ status?: number;
21
+ duration_ms?: number;
22
+ error?: string;
23
+ [key: string]: unknown;
24
+ }
25
+ /**
26
+ * Generate a unique request ID for tracing.
27
+ */
28
+ export declare function generateRequestId(): string;
29
+ /** Force an immediate flush of all buffered logs. */
30
+ export declare function flushLogger(): Promise<void>;
31
+ /** Stop the background flush timer. */
32
+ export declare function stopLogger(): void;
33
+ export declare const logger: {
34
+ debug(message: string, meta?: Partial<LogEntry>): void;
35
+ info(message: string, meta?: Partial<LogEntry>): void;
36
+ warn(message: string, meta?: Partial<LogEntry>): void;
37
+ error(message: string, meta?: Partial<LogEntry>): void;
38
+ };
39
+ export default logger;
40
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAuB3D,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,QAAQ,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAID;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAM1C;AAgFD,qDAAqD;AACrD,wBAAgB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAE3C;AAED,uCAAuC;AACvC,wBAAgB,UAAU,IAAI,IAAI,CAKjC;AAED,eAAO,MAAM,MAAM;mBACF,MAAM,SAAS,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI;kBAIxC,MAAM,SAAS,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI;kBAIvC,MAAM,SAAS,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI;mBAItC,MAAM,SAAS,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI;CAGvD,CAAC;AAEF,eAAe,MAAM,CAAC"}
package/dist/logger.js ADDED
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Structured JSON logger with levels, request ID tracing, and asynchronous batched flushing.
3
+ *
4
+ * Logs are buffered in memory and flushed asynchronously on a short interval or when the
5
+ * buffer reaches a size threshold. This keeps the hot path non-blocking while still ensuring
6
+ * logs are written in order within each flush.
7
+ *
8
+ * @module boltstore/logger
9
+ */
10
+ import { openSync, writeSync, closeSync } from "node:fs";
11
+ const LEVEL_PRIORITY = {
12
+ debug: 0,
13
+ info: 1,
14
+ warn: 2,
15
+ error: 3,
16
+ };
17
+ const LOG_LEVEL = (Bun.env.LOG_LEVEL || "info").toLowerCase();
18
+ /** Output destination: "stderr" | "stdout" | a file path. */
19
+ const LOG_OUTPUT = Bun.env.LOG_OUTPUT || "stderr";
20
+ /** Maximum number of entries to buffer before flushing. */
21
+ const LOG_BUFFER_LIMIT = Math.max(1, Math.min(1000, parseInt(Bun.env.LOG_BUFFER_LIMIT || "100", 10) || 100));
22
+ /** Flush interval in milliseconds. */
23
+ const LOG_FLUSH_MS = Math.max(10, parseInt(Bun.env.LOG_FLUSH_MS || "100", 10) || 100);
24
+ /** Optional sampling rate (0-1) applied to info-level logs. Error/warn are always logged. */
25
+ const LOG_SAMPLE_RATE = Math.max(0, Math.min(1, parseFloat(Bun.env.LOG_SAMPLE_RATE || "1")));
26
+ let requestCounter = 0;
27
+ /**
28
+ * Generate a unique request ID for tracing.
29
+ */
30
+ export function generateRequestId() {
31
+ requestCounter++;
32
+ const random = new Uint8Array(6);
33
+ crypto.getRandomValues(random);
34
+ const rnd = Buffer.from(random).toString("base64url").replace(/=+$/, "");
35
+ return `req-${Date.now()}-${requestCounter}-${rnd}`;
36
+ }
37
+ // ---------------------------------------------------------------------------
38
+ // Async batched log writer
39
+ // ---------------------------------------------------------------------------
40
+ let logBuffer = [];
41
+ let flushTimer = null;
42
+ let flushPromise = null;
43
+ function shouldDrop(level) {
44
+ if (level === "error" || level === "warn")
45
+ return false;
46
+ if (level === "info" && LOG_SAMPLE_RATE >= 1)
47
+ return false;
48
+ if (level === "info" && Math.random() > LOG_SAMPLE_RATE)
49
+ return true;
50
+ return false;
51
+ }
52
+ function writeEntries(entries) {
53
+ if (entries.length === 0)
54
+ return;
55
+ const chunk = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
56
+ try {
57
+ if (LOG_OUTPUT === "stdout") {
58
+ process.stdout.write(chunk);
59
+ }
60
+ else if (LOG_OUTPUT === "stderr") {
61
+ process.stderr.write(chunk);
62
+ }
63
+ else {
64
+ const fd = openSync(LOG_OUTPUT, "a");
65
+ try {
66
+ writeSync(fd, chunk);
67
+ }
68
+ finally {
69
+ closeSync(fd);
70
+ }
71
+ }
72
+ }
73
+ catch {
74
+ // Logging failures must not break the request.
75
+ }
76
+ }
77
+ async function flushLogs() {
78
+ if (flushPromise)
79
+ return flushPromise;
80
+ const batch = logBuffer;
81
+ logBuffer = [];
82
+ if (batch.length === 0)
83
+ return;
84
+ flushPromise = new Promise((resolve) => {
85
+ // Defer actual I/O to next tick to avoid blocking the event loop.
86
+ setTimeout(() => {
87
+ writeEntries(batch);
88
+ flushPromise = null;
89
+ resolve();
90
+ }, 0);
91
+ });
92
+ return flushPromise;
93
+ }
94
+ function scheduleFlush() {
95
+ if (!flushTimer) {
96
+ flushTimer = setInterval(() => {
97
+ flushLogs();
98
+ }, LOG_FLUSH_MS);
99
+ // Ensure the timer does not keep the process alive if it's the only remaining work.
100
+ if (typeof flushTimer.unref === "function")
101
+ flushTimer.unref();
102
+ }
103
+ }
104
+ /**
105
+ * Buffer a structured JSON log entry for asynchronous batched flushing.
106
+ */
107
+ function writeLog(entry) {
108
+ if (LEVEL_PRIORITY[entry.level] < LEVEL_PRIORITY[LOG_LEVEL]) {
109
+ return;
110
+ }
111
+ if (shouldDrop(entry.level))
112
+ return;
113
+ logBuffer.push(entry);
114
+ if (logBuffer.length >= LOG_BUFFER_LIMIT) {
115
+ flushLogs();
116
+ }
117
+ else {
118
+ scheduleFlush();
119
+ }
120
+ }
121
+ /** Force an immediate flush of all buffered logs. */
122
+ export function flushLogger() {
123
+ return flushLogs();
124
+ }
125
+ /** Stop the background flush timer. */
126
+ export function stopLogger() {
127
+ if (flushTimer) {
128
+ clearInterval(flushTimer);
129
+ flushTimer = null;
130
+ }
131
+ }
132
+ export const logger = {
133
+ debug(message, meta) {
134
+ writeLog({ level: "debug", message, timestamp: new Date().toISOString(), ...meta });
135
+ },
136
+ info(message, meta) {
137
+ writeLog({ level: "info", message, timestamp: new Date().toISOString(), ...meta });
138
+ },
139
+ warn(message, meta) {
140
+ writeLog({ level: "warn", message, timestamp: new Date().toISOString(), ...meta });
141
+ },
142
+ error(message, meta) {
143
+ writeLog({ level: "error", message, timestamp: new Date().toISOString(), ...meta });
144
+ },
145
+ };
146
+ export default logger;
147
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Authentication/authorization middleware for Boltstore.
3
+ *
4
+ * Extracts a Bearer JWT token or an API key secret from the incoming request,
5
+ * verifies it against the database, and returns an auth context. Admin-only
6
+ * routes must additionally ensure the principal has role "admin" (or a valid
7
+ * API key with admin-scoped permissions).
8
+ *
9
+ * @module boltstore/middleware/auth
10
+ */
11
+ import { DatabaseManager } from "../db/manager";
12
+ import { type AuthConfig } from "../auth";
13
+ export { type AuthConfig } from "../auth";
14
+ import { type ApiKeyContext } from "../admin/api-keys";
15
+ /** Authenticated principal returned by the middleware. */
16
+ export interface AuthContext {
17
+ /** User ID (JWT) or API key ID (API key). */
18
+ principalId: string;
19
+ /** Email when authenticated via JWT. */
20
+ email?: string;
21
+ /** Role when authenticated via JWT. */
22
+ role?: "user" | "admin";
23
+ /** API key context when authenticated via API key. */
24
+ apiKey?: ApiKeyContext;
25
+ /** True if the principal was resolved from an API key. */
26
+ isApiKey: boolean;
27
+ }
28
+ /** Result of authentication: context on success, Response on failure. */
29
+ export type AuthResult = AuthContext | Response;
30
+ /**
31
+ * Authenticate the request against the given database.
32
+ *
33
+ * Returns an `AuthContext` on success or a 401/403 Response on failure.
34
+ */
35
+ export declare function authenticateRequest(request: Request, manager: DatabaseManager, database: string, authConfig: AuthConfig): Promise<AuthResult>;
36
+ /**
37
+ * Require an authenticated admin principal.
38
+ *
39
+ * JWT users must have role "admin". API keys are not allowed for admin
40
+ * routes unless the key explicitly includes the "admin" operation.
41
+ */
42
+ export declare function requireAdmin(auth: AuthContext): Response | null;
43
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAEL,KAAK,UAAU,EAChB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAErE,0DAA0D;AAC1D,MAAM,WAAW,WAAW;IAC1B,6CAA6C;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACxB,sDAAsD;IACtD,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,0DAA0D;IAC1D,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,yEAAyE;AACzE,MAAM,MAAM,UAAU,GAAG,WAAW,GAAG,QAAQ,CAAC;AAoBhD;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,UAAU,CAAC,CA4CrB;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,WAAW,GAAG,QAAQ,GAAG,IAAI,CAoB/D"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Authentication/authorization middleware for Boltstore.
3
+ *
4
+ * Extracts a Bearer JWT token or an API key secret from the incoming request,
5
+ * verifies it against the database, and returns an auth context. Admin-only
6
+ * routes must additionally ensure the principal has role "admin" (or a valid
7
+ * API key with admin-scoped permissions).
8
+ *
9
+ * @module boltstore/middleware/auth
10
+ */
11
+ import { verifyAccessToken, } from "../auth";
12
+ import { verifyApiKey } from "../admin/api-keys";
13
+ /** Extract a Bearer token or API key secret from request headers. */
14
+ function extractCredentials(request) {
15
+ const auth = request.headers.get("Authorization");
16
+ if (auth?.startsWith("Bearer ")) {
17
+ const value = auth.slice(7).trim();
18
+ // API keys always start with "blt_"
19
+ if (value.startsWith("blt_")) {
20
+ return { apiKey: value };
21
+ }
22
+ return { token: value };
23
+ }
24
+ const apiKey = request.headers.get("X-API-Key") || request.headers.get("x-api-key");
25
+ if (apiKey)
26
+ return { apiKey: apiKey.trim() };
27
+ return {};
28
+ }
29
+ /**
30
+ * Authenticate the request against the given database.
31
+ *
32
+ * Returns an `AuthContext` on success or a 401/403 Response on failure.
33
+ */
34
+ export async function authenticateRequest(request, manager, database, authConfig) {
35
+ const { token, apiKey } = extractCredentials(request);
36
+ if (!token && !apiKey) {
37
+ return new Response(JSON.stringify({ error: { code: "UNAUTHORIZED", message: "Authentication required." } }), { status: 401, headers: { "Content-Type": "application/json" } });
38
+ }
39
+ const pool = database === "_system" ? manager.getMetaPool() : manager.get(database);
40
+ if (apiKey) {
41
+ try {
42
+ const ctx = await verifyApiKey(pool, apiKey);
43
+ return {
44
+ principalId: ctx.keyId,
45
+ apiKey: ctx,
46
+ isApiKey: true,
47
+ };
48
+ }
49
+ catch (err) {
50
+ const message = err instanceof Error ? err.message : "Invalid API key";
51
+ return new Response(JSON.stringify({ error: { code: "UNAUTHORIZED", message } }), { status: 401, headers: { "Content-Type": "application/json" } });
52
+ }
53
+ }
54
+ try {
55
+ const ctx = verifyAccessToken(pool, token, authConfig);
56
+ return {
57
+ principalId: ctx.userId,
58
+ email: ctx.email,
59
+ role: ctx.role,
60
+ isApiKey: false,
61
+ };
62
+ }
63
+ catch (err) {
64
+ const message = err instanceof Error ? err.message : "Invalid token";
65
+ return new Response(JSON.stringify({ error: { code: "UNAUTHORIZED", message } }), { status: 401, headers: { "Content-Type": "application/json" } });
66
+ }
67
+ }
68
+ /**
69
+ * Require an authenticated admin principal.
70
+ *
71
+ * JWT users must have role "admin". API keys are not allowed for admin
72
+ * routes unless the key explicitly includes the "admin" operation.
73
+ */
74
+ export function requireAdmin(auth) {
75
+ if (auth.isApiKey) {
76
+ const ops = auth.apiKey?.permissions.operations ?? [];
77
+ if (!ops.includes("admin")) {
78
+ return new Response(JSON.stringify({ error: { code: "FORBIDDEN", message: "Admin access required." } }), { status: 403, headers: { "Content-Type": "application/json" } });
79
+ }
80
+ return null;
81
+ }
82
+ if (auth.role !== "admin") {
83
+ return new Response(JSON.stringify({ error: { code: "FORBIDDEN", message: "Admin access required." } }), { status: 403, headers: { "Content-Type": "application/json" } });
84
+ }
85
+ return null;
86
+ }
87
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * CORS middleware — handles cross-origin requests.
3
+ *
4
+ * Configurable via environment variables:
5
+ * - CORS_ORIGINS: comma-separated list of allowed origins (default: "*")
6
+ * - CORS_METHODS: comma-separated list of allowed methods (default: "GET,POST,PATCH,DELETE,OPTIONS")
7
+ * - CORS_HEADERS: comma-separated list of allowed headers (default: "Content-Type,Authorization")
8
+ *
9
+ * @module boltstore/middleware/cors
10
+ */
11
+ export interface CorsConfig {
12
+ origins: string[];
13
+ methods: string[];
14
+ headers: string[];
15
+ }
16
+ declare const defaultConfig: CorsConfig;
17
+ /**
18
+ * Apply CORS headers to a Response object.
19
+ * Returns the response with CORS headers set, or a 204 for preflight requests.
20
+ */
21
+ export declare function applyCors(response: Response, requestOrigin: string | null, config?: CorsConfig): Response;
22
+ /**
23
+ * Handle an OPTIONS preflight request.
24
+ * Returns a 204 No Content response with appropriate CORS headers.
25
+ */
26
+ export declare function handlePreflight(requestOrigin: string | null, config?: CorsConfig): Response;
27
+ export { defaultConfig };
28
+ //# sourceMappingURL=cors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../../src/middleware/cors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,QAAA,MAAM,aAAa,EAAE,UAMpB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,SAAS,CACvB,QAAQ,EAAE,QAAQ,EAClB,aAAa,EAAE,MAAM,GAAG,IAAI,EAC5B,MAAM,GAAE,UAA0B,GACjC,QAAQ,CAwBV;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,GAAE,UAA0B,GAAG,QAAQ,CAsB1G;AAED,OAAO,EAAE,aAAa,EAAE,CAAC"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * CORS middleware — handles cross-origin requests.
3
+ *
4
+ * Configurable via environment variables:
5
+ * - CORS_ORIGINS: comma-separated list of allowed origins (default: "*")
6
+ * - CORS_METHODS: comma-separated list of allowed methods (default: "GET,POST,PATCH,DELETE,OPTIONS")
7
+ * - CORS_HEADERS: comma-separated list of allowed headers (default: "Content-Type,Authorization")
8
+ *
9
+ * @module boltstore/middleware/cors
10
+ */
11
+ const defaultConfig = {
12
+ origins: Bun.env.CORS_ORIGINS
13
+ ? Bun.env.CORS_ORIGINS.split(",").map((s) => s.trim()).filter(Boolean)
14
+ : ["*"],
15
+ methods: (Bun.env.CORS_METHODS || "GET,POST,PATCH,DELETE,OPTIONS").split(",").map((s) => s.trim()),
16
+ headers: (Bun.env.CORS_HEADERS || "Content-Type,Authorization").split(",").map((s) => s.trim()),
17
+ };
18
+ /**
19
+ * Apply CORS headers to a Response object.
20
+ * Returns the response with CORS headers set, or a 204 for preflight requests.
21
+ */
22
+ export function applyCors(response, requestOrigin, config = defaultConfig) {
23
+ let origin = null;
24
+ if (config.origins.includes("*")) {
25
+ // When wildcard is explicitly configured, send wildcard (do not echo).
26
+ origin = "*";
27
+ }
28
+ else if (requestOrigin && config.origins.includes(requestOrigin)) {
29
+ origin = requestOrigin;
30
+ }
31
+ // No matching origin — return response unchanged.
32
+ if (!origin)
33
+ return response;
34
+ const headers = new Headers(response.headers);
35
+ headers.set("Access-Control-Allow-Origin", origin);
36
+ headers.set("Access-Control-Allow-Methods", config.methods.join(", "));
37
+ headers.set("Access-Control-Allow-Headers", config.headers.join(", "));
38
+ headers.set("Access-Control-Max-Age", "86400");
39
+ return new Response(response.body, {
40
+ status: response.status,
41
+ statusText: response.statusText,
42
+ headers,
43
+ });
44
+ }
45
+ /**
46
+ * Handle an OPTIONS preflight request.
47
+ * Returns a 204 No Content response with appropriate CORS headers.
48
+ */
49
+ export function handlePreflight(requestOrigin, config = defaultConfig) {
50
+ let origin = null;
51
+ if (config.origins.includes("*")) {
52
+ origin = "*";
53
+ }
54
+ else if (requestOrigin && config.origins.includes(requestOrigin)) {
55
+ origin = requestOrigin;
56
+ }
57
+ if (!origin) {
58
+ return new Response(null, { status: 204 });
59
+ }
60
+ return new Response(null, {
61
+ status: 204,
62
+ headers: {
63
+ "Access-Control-Allow-Origin": origin,
64
+ "Access-Control-Allow-Methods": config.methods.join(", "),
65
+ "Access-Control-Allow-Headers": config.headers.join(", "),
66
+ "Access-Control-Max-Age": "86400",
67
+ },
68
+ });
69
+ }
70
+ export { defaultConfig };
71
+ //# sourceMappingURL=cors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cors.js","sourceRoot":"","sources":["../../src/middleware/cors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Trusted proxy helper for Boltstore.
3
+ *
4
+ * @module boltstore/middleware/proxy
5
+ */
6
+ /** Check whether the immediate connection IP is a trusted proxy. */
7
+ export declare function isTrustedProxy(remoteAddress: string, trusted: string[]): boolean;
8
+ /** Resolve the client IP from request headers, respecting trusted proxies. */
9
+ export declare function resolveClientIp(request: Request, trustedProxies: string[], remoteAddress?: string): string;
10
+ //# sourceMappingURL=proxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/middleware/proxy.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,oEAAoE;AACpE,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAIhF;AAED,8EAA8E;AAC9E,wBAAgB,eAAe,CAC7B,OAAO,EAAE,OAAO,EAChB,cAAc,EAAE,MAAM,EAAE,EACxB,aAAa,CAAC,EAAE,MAAM,GACrB,MAAM,CAgBR"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Trusted proxy helper for Boltstore.
3
+ *
4
+ * @module boltstore/middleware/proxy
5
+ */
6
+ /** Check whether the immediate connection IP is a trusted proxy. */
7
+ export function isTrustedProxy(remoteAddress, trusted) {
8
+ if (trusted.length === 0)
9
+ return false;
10
+ if (trusted.includes("*"))
11
+ return true;
12
+ return trusted.includes(remoteAddress) || trusted.includes("127.0.0.1") && remoteAddress === "127.0.0.1";
13
+ }
14
+ /** Resolve the client IP from request headers, respecting trusted proxies. */
15
+ export function resolveClientIp(request, trustedProxies, remoteAddress) {
16
+ const remote = remoteAddress || "127.0.0.1";
17
+ if (!isTrustedProxy(remote, trustedProxies)) {
18
+ return remote;
19
+ }
20
+ const forwarded = request.headers.get("X-Forwarded-For");
21
+ if (forwarded) {
22
+ const first = forwarded.split(",")[0]?.trim();
23
+ if (first)
24
+ return first;
25
+ }
26
+ const realIp = request.headers.get("X-Real-IP");
27
+ if (realIp)
28
+ return realIp.trim();
29
+ return remote;
30
+ }
31
+ //# sourceMappingURL=proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.js","sourceRoot":"","sources":["../../src/middleware/proxy.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,oEAAoE;AACpE,MAAM,UAAU,cAAc,CAAC,aAAqB,EAAE,OAAiB;IACrE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACvC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACvC,OAAO,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,aAAa,KAAK,WAAW,CAAC;AAC3G,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,eAAe,CAC7B,OAAgB,EAChB,cAAwB,EACxB,aAAsB;IAEtB,MAAM,MAAM,GAAG,aAAa,IAAI,WAAW,CAAC;IAC5C,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,cAAc,CAAC,EAAE,CAAC;QAC5C,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACzD,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;QAC9C,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;IAC1B,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAChD,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;IAEjC,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Rate limiting middleware for Boltstore.
3
+ *
4
+ * Uses a sliding-window counter approach with per-IP, per-endpoint,
5
+ * per-tier tracking. All state is in-memory (no SQLite dependency) for
6
+ * speed — resets on server restart.
7
+ *
8
+ * Three tiers:
9
+ * - **public**: Unauthenticated endpoints (health, login, register)
10
+ * - **auth**: Authenticated endpoints (CRUD, queries)
11
+ * - **admin**: Admin endpoints under `/api/admin/*`
12
+ *
13
+ * Configurable via `BoltstoreConfig.rateLimitPublic` and `rateLimitAuth`,
14
+ * or set explicitly in `ServerConfig.rateLimit`.
15
+ *
16
+ * @module boltstore/middleware/rate-limit
17
+ */
18
+ export type RateLimitTier = "public" | "auth" | "admin";
19
+ export interface RateLimitConfig {
20
+ /** Requests per window for public endpoints. Default: 100. */
21
+ public: number;
22
+ /** Requests per window for authenticated endpoints. Default: 1000. */
23
+ auth: number;
24
+ /** Requests per window for admin endpoints. Default: 500. */
25
+ admin: number;
26
+ /** Window size in seconds. Default: 60 (1 minute). */
27
+ windowSeconds: number;
28
+ }
29
+ export interface RateLimitResult {
30
+ allowed: boolean;
31
+ /** How many requests remain in this window. */
32
+ remaining: number;
33
+ /** Total limit for this tier. */
34
+ limit: number;
35
+ /** Unix timestamp (seconds) when the window resets. */
36
+ reset: number;
37
+ /** Seconds until the window resets (only set when rate-limited). */
38
+ retryAfter: number;
39
+ }
40
+ export declare const DEFAULT_RATE_LIMIT_CONFIG: RateLimitConfig;
41
+ /**
42
+ * Stop the cleanup timer. Call during server shutdown.
43
+ */
44
+ export declare function stopRateLimitCleanup(): void;
45
+ /**
46
+ * Check if a request should be rate-limited.
47
+ *
48
+ * @param clientIp - The client's IP address (or "127.0.0.1" as fallback).
49
+ * @param pathname - The request path (used as part of the rate limit key).
50
+ * @param tier - The rate limit tier for this request.
51
+ * @param config - Rate limit configuration.
52
+ * @returns A result indicating whether the request is allowed.
53
+ */
54
+ export declare function checkRateLimit(clientIp: string, pathname: string, tier: RateLimitTier, config: RateLimitConfig): RateLimitResult;
55
+ /**
56
+ * Get the current rate limit status for a client without incrementing.
57
+ * Useful for informational endpoints.
58
+ */
59
+ export declare function getRateLimitStatus(clientIp: string, pathname: string, tier: RateLimitTier, config: RateLimitConfig): RateLimitResult;
60
+ /**
61
+ * Reset all rate limit counters. Useful for testing.
62
+ */
63
+ export declare function resetRateLimits(): void;
64
+ //# sourceMappingURL=rate-limit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../src/middleware/rate-limit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAQH,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AAExD,MAAM,WAAW,eAAe;IAC9B,8DAA8D;IAC9D,MAAM,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAC;IACd,sDAAsD;IACtD,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,yBAAyB,EAAE,eAKvC,CAAC;AAsCF;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAK3C;AAMD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,eAAe,GACtB,eAAe,CAiCjB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,eAAe,GACtB,eAAe,CA4BjB;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAEtC"}