@digimuza/saas-core 0.0.2

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 (474) hide show
  1. package/CLAUDE.md +1165 -0
  2. package/LICENSE +21 -0
  3. package/README.md +234 -0
  4. package/dist/api-keys/index.d.ts +9 -0
  5. package/dist/api-keys/index.d.ts.map +1 -0
  6. package/dist/api-keys/index.js +37 -0
  7. package/dist/api-keys/index.js.map +1 -0
  8. package/dist/api-keys/keys.d.ts +55 -0
  9. package/dist/api-keys/keys.d.ts.map +1 -0
  10. package/dist/api-keys/keys.js +92 -0
  11. package/dist/api-keys/keys.js.map +1 -0
  12. package/dist/api-keys/service.d.ts +111 -0
  13. package/dist/api-keys/service.d.ts.map +1 -0
  14. package/dist/api-keys/service.js +210 -0
  15. package/dist/api-keys/service.js.map +1 -0
  16. package/dist/audit/index.d.ts +5 -0
  17. package/dist/audit/index.d.ts.map +1 -0
  18. package/dist/audit/index.js +44 -0
  19. package/dist/audit/index.js.map +1 -0
  20. package/dist/audit/service.d.ts +88 -0
  21. package/dist/audit/service.d.ts.map +1 -0
  22. package/dist/audit/service.js +128 -0
  23. package/dist/audit/service.js.map +1 -0
  24. package/dist/auth/client.d.ts +5 -0
  25. package/dist/auth/client.d.ts.map +1 -0
  26. package/dist/auth/client.js +26 -0
  27. package/dist/auth/client.js.map +1 -0
  28. package/dist/auth/cookies.d.ts +51 -0
  29. package/dist/auth/cookies.d.ts.map +1 -0
  30. package/dist/auth/cookies.js +58 -0
  31. package/dist/auth/cookies.js.map +1 -0
  32. package/dist/auth/index.d.ts +14 -0
  33. package/dist/auth/index.d.ts.map +1 -0
  34. package/dist/auth/index.js +46 -0
  35. package/dist/auth/index.js.map +1 -0
  36. package/dist/auth/service.d.ts +67 -0
  37. package/dist/auth/service.d.ts.map +1 -0
  38. package/dist/auth/service.js +275 -0
  39. package/dist/auth/service.js.map +1 -0
  40. package/dist/auth/types.d.ts +56 -0
  41. package/dist/auth/types.d.ts.map +1 -0
  42. package/dist/auth/types.js +2 -0
  43. package/dist/auth/types.js.map +1 -0
  44. package/dist/authorization/index.d.ts +4 -0
  45. package/dist/authorization/index.d.ts.map +1 -0
  46. package/dist/authorization/index.js +24 -0
  47. package/dist/authorization/index.js.map +1 -0
  48. package/dist/authorization/service.d.ts +92 -0
  49. package/dist/authorization/service.d.ts.map +1 -0
  50. package/dist/authorization/service.js +254 -0
  51. package/dist/authorization/service.js.map +1 -0
  52. package/dist/billing/index.d.ts +16 -0
  53. package/dist/billing/index.d.ts.map +1 -0
  54. package/dist/billing/index.js +47 -0
  55. package/dist/billing/index.js.map +1 -0
  56. package/dist/billing/provider.d.ts +114 -0
  57. package/dist/billing/provider.d.ts.map +1 -0
  58. package/dist/billing/provider.js +2 -0
  59. package/dist/billing/provider.js.map +1 -0
  60. package/dist/billing/revolut.d.ts +68 -0
  61. package/dist/billing/revolut.d.ts.map +1 -0
  62. package/dist/billing/revolut.js +181 -0
  63. package/dist/billing/revolut.js.map +1 -0
  64. package/dist/billing/service.d.ts +124 -0
  65. package/dist/billing/service.d.ts.map +1 -0
  66. package/dist/billing/service.js +470 -0
  67. package/dist/billing/service.js.map +1 -0
  68. package/dist/cli/commands/dev.d.ts +43 -0
  69. package/dist/cli/commands/dev.d.ts.map +1 -0
  70. package/dist/cli/commands/dev.js +212 -0
  71. package/dist/cli/commands/dev.js.map +1 -0
  72. package/dist/cli/commands/project.d.ts +12 -0
  73. package/dist/cli/commands/project.d.ts.map +1 -0
  74. package/dist/cli/commands/project.js +49 -0
  75. package/dist/cli/commands/project.js.map +1 -0
  76. package/dist/cli/docker.d.ts +50 -0
  77. package/dist/cli/docker.d.ts.map +1 -0
  78. package/dist/cli/docker.js +84 -0
  79. package/dist/cli/docker.js.map +1 -0
  80. package/dist/cli/index.d.ts +6 -0
  81. package/dist/cli/index.d.ts.map +1 -0
  82. package/dist/cli/index.js +198 -0
  83. package/dist/cli/index.js.map +1 -0
  84. package/dist/cli/output.d.ts +30 -0
  85. package/dist/cli/output.d.ts.map +1 -0
  86. package/dist/cli/output.js +66 -0
  87. package/dist/cli/output.js.map +1 -0
  88. package/dist/cli/templates.d.ts +52 -0
  89. package/dist/cli/templates.d.ts.map +1 -0
  90. package/dist/cli/templates.js +225 -0
  91. package/dist/cli/templates.js.map +1 -0
  92. package/dist/config/client.d.ts +60 -0
  93. package/dist/config/client.d.ts.map +1 -0
  94. package/dist/config/client.js +94 -0
  95. package/dist/config/client.js.map +1 -0
  96. package/dist/config/config-loader.d.ts +2 -0
  97. package/dist/config/config-loader.d.ts.map +1 -0
  98. package/dist/config/config-loader.js +2 -0
  99. package/dist/config/config-loader.js.map +1 -0
  100. package/dist/config/env.d.ts +24 -0
  101. package/dist/config/env.d.ts.map +1 -0
  102. package/dist/config/env.js +40 -0
  103. package/dist/config/env.js.map +1 -0
  104. package/dist/config/errors.d.ts +17 -0
  105. package/dist/config/errors.d.ts.map +1 -0
  106. package/dist/config/errors.js +26 -0
  107. package/dist/config/errors.js.map +1 -0
  108. package/dist/config/index.d.ts +72 -0
  109. package/dist/config/index.d.ts.map +1 -0
  110. package/dist/config/index.js +106 -0
  111. package/dist/config/index.js.map +1 -0
  112. package/dist/config/runtime.d.ts +15 -0
  113. package/dist/config/runtime.d.ts.map +1 -0
  114. package/dist/config/runtime.js +22 -0
  115. package/dist/config/runtime.js.map +1 -0
  116. package/dist/config/sections.d.ts +226 -0
  117. package/dist/config/sections.d.ts.map +1 -0
  118. package/dist/config/sections.js +141 -0
  119. package/dist/config/sections.js.map +1 -0
  120. package/dist/db/client.d.ts +43 -0
  121. package/dist/db/client.d.ts.map +1 -0
  122. package/dist/db/client.js +77 -0
  123. package/dist/db/client.js.map +1 -0
  124. package/dist/db/errors.d.ts +39 -0
  125. package/dist/db/errors.d.ts.map +1 -0
  126. package/dist/db/errors.js +67 -0
  127. package/dist/db/errors.js.map +1 -0
  128. package/dist/db/index.d.ts +10 -0
  129. package/dist/db/index.d.ts.map +1 -0
  130. package/dist/db/index.js +10 -0
  131. package/dist/db/index.js.map +1 -0
  132. package/dist/db/migrate.d.ts +21 -0
  133. package/dist/db/migrate.d.ts.map +1 -0
  134. package/dist/db/migrate.js +28 -0
  135. package/dist/db/migrate.js.map +1 -0
  136. package/dist/db/schema/_shared.d.ts +30 -0
  137. package/dist/db/schema/_shared.d.ts.map +1 -0
  138. package/dist/db/schema/_shared.js +36 -0
  139. package/dist/db/schema/_shared.js.map +1 -0
  140. package/dist/db/schema/apikeys.d.ts +263 -0
  141. package/dist/db/schema/apikeys.d.ts.map +1 -0
  142. package/dist/db/schema/apikeys.js +70 -0
  143. package/dist/db/schema/apikeys.js.map +1 -0
  144. package/dist/db/schema/authorization.d.ts +465 -0
  145. package/dist/db/schema/authorization.d.ts.map +1 -0
  146. package/dist/db/schema/authorization.js +134 -0
  147. package/dist/db/schema/authorization.js.map +1 -0
  148. package/dist/db/schema/billing.d.ts +1100 -0
  149. package/dist/db/schema/billing.d.ts.map +1 -0
  150. package/dist/db/schema/billing.js +223 -0
  151. package/dist/db/schema/billing.js.map +1 -0
  152. package/dist/db/schema/events.d.ts +161 -0
  153. package/dist/db/schema/events.d.ts.map +1 -0
  154. package/dist/db/schema/events.js +66 -0
  155. package/dist/db/schema/events.js.map +1 -0
  156. package/dist/db/schema/features.d.ts +243 -0
  157. package/dist/db/schema/features.d.ts.map +1 -0
  158. package/dist/db/schema/features.js +87 -0
  159. package/dist/db/schema/features.js.map +1 -0
  160. package/dist/db/schema/files.d.ts +253 -0
  161. package/dist/db/schema/files.d.ts.map +1 -0
  162. package/dist/db/schema/files.js +74 -0
  163. package/dist/db/schema/files.js.map +1 -0
  164. package/dist/db/schema/index.d.ts +38 -0
  165. package/dist/db/schema/index.d.ts.map +1 -0
  166. package/dist/db/schema/index.js +38 -0
  167. package/dist/db/schema/index.js.map +1 -0
  168. package/dist/db/schema/invitations.d.ts +214 -0
  169. package/dist/db/schema/invitations.d.ts.map +1 -0
  170. package/dist/db/schema/invitations.js +80 -0
  171. package/dist/db/schema/invitations.js.map +1 -0
  172. package/dist/db/schema/messaging.d.ts +442 -0
  173. package/dist/db/schema/messaging.d.ts.map +1 -0
  174. package/dist/db/schema/messaging.js +120 -0
  175. package/dist/db/schema/messaging.js.map +1 -0
  176. package/dist/db/schema/users.d.ts +246 -0
  177. package/dist/db/schema/users.d.ts.map +1 -0
  178. package/dist/db/schema/users.js +60 -0
  179. package/dist/db/schema/users.js.map +1 -0
  180. package/dist/db/schema/webhooks.d.ts +693 -0
  181. package/dist/db/schema/webhooks.d.ts.map +1 -0
  182. package/dist/db/schema/webhooks.js +147 -0
  183. package/dist/db/schema/webhooks.js.map +1 -0
  184. package/dist/db/schema/workspaces.d.ts +196 -0
  185. package/dist/db/schema/workspaces.d.ts.map +1 -0
  186. package/dist/db/schema/workspaces.js +57 -0
  187. package/dist/db/schema/workspaces.js.map +1 -0
  188. package/dist/db/types.d.ts +18 -0
  189. package/dist/db/types.d.ts.map +1 -0
  190. package/dist/db/types.js +2 -0
  191. package/dist/db/types.js.map +1 -0
  192. package/dist/email/adapters.d.ts +29 -0
  193. package/dist/email/adapters.d.ts.map +1 -0
  194. package/dist/email/adapters.js +60 -0
  195. package/dist/email/adapters.js.map +1 -0
  196. package/dist/email/index.d.ts +20 -0
  197. package/dist/email/index.d.ts.map +1 -0
  198. package/dist/email/index.js +79 -0
  199. package/dist/email/index.js.map +1 -0
  200. package/dist/email/provider.d.ts +47 -0
  201. package/dist/email/provider.d.ts.map +1 -0
  202. package/dist/email/provider.js +7 -0
  203. package/dist/email/provider.js.map +1 -0
  204. package/dist/email/resend.d.ts +22 -0
  205. package/dist/email/resend.d.ts.map +1 -0
  206. package/dist/email/resend.js +51 -0
  207. package/dist/email/resend.js.map +1 -0
  208. package/dist/email/service.d.ts +55 -0
  209. package/dist/email/service.d.ts.map +1 -0
  210. package/dist/email/service.js +87 -0
  211. package/dist/email/service.js.map +1 -0
  212. package/dist/email/templates.d.ts +81 -0
  213. package/dist/email/templates.d.ts.map +1 -0
  214. package/dist/email/templates.js +84 -0
  215. package/dist/email/templates.js.map +1 -0
  216. package/dist/entitlements/index.d.ts +10 -0
  217. package/dist/entitlements/index.d.ts.map +1 -0
  218. package/dist/entitlements/index.js +28 -0
  219. package/dist/entitlements/index.js.map +1 -0
  220. package/dist/entitlements/service.d.ts +83 -0
  221. package/dist/entitlements/service.d.ts.map +1 -0
  222. package/dist/entitlements/service.js +158 -0
  223. package/dist/entitlements/service.js.map +1 -0
  224. package/dist/errors.d.ts +85 -0
  225. package/dist/errors.d.ts.map +1 -0
  226. package/dist/errors.js +95 -0
  227. package/dist/errors.js.map +1 -0
  228. package/dist/events/core-events.d.ts +120 -0
  229. package/dist/events/core-events.d.ts.map +1 -0
  230. package/dist/events/core-events.js +109 -0
  231. package/dist/events/core-events.js.map +1 -0
  232. package/dist/events/index.d.ts +15 -0
  233. package/dist/events/index.d.ts.map +1 -0
  234. package/dist/events/index.js +58 -0
  235. package/dist/events/index.js.map +1 -0
  236. package/dist/events/publisher.d.ts +46 -0
  237. package/dist/events/publisher.d.ts.map +1 -0
  238. package/dist/events/publisher.js +54 -0
  239. package/dist/events/publisher.js.map +1 -0
  240. package/dist/events/registry.d.ts +87 -0
  241. package/dist/events/registry.d.ts.map +1 -0
  242. package/dist/events/registry.js +34 -0
  243. package/dist/events/registry.js.map +1 -0
  244. package/dist/events/service.d.ts +78 -0
  245. package/dist/events/service.d.ts.map +1 -0
  246. package/dist/events/service.js +182 -0
  247. package/dist/events/service.js.map +1 -0
  248. package/dist/features/bucket.d.ts +22 -0
  249. package/dist/features/bucket.d.ts.map +1 -0
  250. package/dist/features/bucket.js +42 -0
  251. package/dist/features/bucket.js.map +1 -0
  252. package/dist/features/index.d.ts +15 -0
  253. package/dist/features/index.d.ts.map +1 -0
  254. package/dist/features/index.js +78 -0
  255. package/dist/features/index.js.map +1 -0
  256. package/dist/features/registry.d.ts +51 -0
  257. package/dist/features/registry.d.ts.map +1 -0
  258. package/dist/features/registry.js +52 -0
  259. package/dist/features/registry.js.map +1 -0
  260. package/dist/features/service.d.ts +78 -0
  261. package/dist/features/service.d.ts.map +1 -0
  262. package/dist/features/service.js +207 -0
  263. package/dist/features/service.js.map +1 -0
  264. package/dist/files/index.d.ts +6 -0
  265. package/dist/files/index.d.ts.map +1 -0
  266. package/dist/files/index.js +64 -0
  267. package/dist/files/index.js.map +1 -0
  268. package/dist/files/service.d.ts +92 -0
  269. package/dist/files/service.d.ts.map +1 -0
  270. package/dist/files/service.js +303 -0
  271. package/dist/files/service.js.map +1 -0
  272. package/dist/index.d.ts +33 -0
  273. package/dist/index.d.ts.map +1 -0
  274. package/dist/index.js +33 -0
  275. package/dist/index.js.map +1 -0
  276. package/dist/jobs/backend.d.ts +23 -0
  277. package/dist/jobs/backend.d.ts.map +1 -0
  278. package/dist/jobs/backend.js +23 -0
  279. package/dist/jobs/backend.js.map +1 -0
  280. package/dist/jobs/index.d.ts +29 -0
  281. package/dist/jobs/index.d.ts.map +1 -0
  282. package/dist/jobs/index.js +114 -0
  283. package/dist/jobs/index.js.map +1 -0
  284. package/dist/jobs/service.d.ts +67 -0
  285. package/dist/jobs/service.d.ts.map +1 -0
  286. package/dist/jobs/service.js +139 -0
  287. package/dist/jobs/service.js.map +1 -0
  288. package/dist/jobs/types.d.ts +78 -0
  289. package/dist/jobs/types.d.ts.map +1 -0
  290. package/dist/jobs/types.js +4 -0
  291. package/dist/jobs/types.js.map +1 -0
  292. package/dist/logger/default.d.ts +7 -0
  293. package/dist/logger/default.d.ts.map +1 -0
  294. package/dist/logger/default.js +28 -0
  295. package/dist/logger/default.js.map +1 -0
  296. package/dist/logger/index.d.ts +24 -0
  297. package/dist/logger/index.d.ts.map +1 -0
  298. package/dist/logger/index.js +90 -0
  299. package/dist/logger/index.js.map +1 -0
  300. package/dist/logger/redact.d.ts +40 -0
  301. package/dist/logger/redact.d.ts.map +1 -0
  302. package/dist/logger/redact.js +178 -0
  303. package/dist/logger/redact.js.map +1 -0
  304. package/dist/logger/service.d.ts +14 -0
  305. package/dist/logger/service.d.ts.map +1 -0
  306. package/dist/logger/service.js +56 -0
  307. package/dist/logger/service.js.map +1 -0
  308. package/dist/logger/sinks.d.ts +37 -0
  309. package/dist/logger/sinks.d.ts.map +1 -0
  310. package/dist/logger/sinks.js +135 -0
  311. package/dist/logger/sinks.js.map +1 -0
  312. package/dist/logger/types.d.ts +47 -0
  313. package/dist/logger/types.d.ts.map +1 -0
  314. package/dist/logger/types.js +8 -0
  315. package/dist/logger/types.js.map +1 -0
  316. package/dist/notifications/index.d.ts +8 -0
  317. package/dist/notifications/index.d.ts.map +1 -0
  318. package/dist/notifications/index.js +72 -0
  319. package/dist/notifications/index.js.map +1 -0
  320. package/dist/notifications/service.d.ts +79 -0
  321. package/dist/notifications/service.d.ts.map +1 -0
  322. package/dist/notifications/service.js +164 -0
  323. package/dist/notifications/service.js.map +1 -0
  324. package/dist/realtime/channels.d.ts +37 -0
  325. package/dist/realtime/channels.d.ts.map +1 -0
  326. package/dist/realtime/channels.js +58 -0
  327. package/dist/realtime/channels.js.map +1 -0
  328. package/dist/realtime/index.d.ts +19 -0
  329. package/dist/realtime/index.d.ts.map +1 -0
  330. package/dist/realtime/index.js +118 -0
  331. package/dist/realtime/index.js.map +1 -0
  332. package/dist/realtime/postgres.d.ts +48 -0
  333. package/dist/realtime/postgres.d.ts.map +1 -0
  334. package/dist/realtime/postgres.js +151 -0
  335. package/dist/realtime/postgres.js.map +1 -0
  336. package/dist/realtime/service.d.ts +75 -0
  337. package/dist/realtime/service.d.ts.map +1 -0
  338. package/dist/realtime/service.js +103 -0
  339. package/dist/realtime/service.js.map +1 -0
  340. package/dist/realtime/sse.d.ts +55 -0
  341. package/dist/realtime/sse.d.ts.map +1 -0
  342. package/dist/realtime/sse.js +123 -0
  343. package/dist/realtime/sse.js.map +1 -0
  344. package/dist/realtime/transport.d.ts +52 -0
  345. package/dist/realtime/transport.d.ts.map +1 -0
  346. package/dist/realtime/transport.js +2 -0
  347. package/dist/realtime/transport.js.map +1 -0
  348. package/dist/storage/index.d.ts +18 -0
  349. package/dist/storage/index.d.ts.map +1 -0
  350. package/dist/storage/index.js +89 -0
  351. package/dist/storage/index.js.map +1 -0
  352. package/dist/storage/keys.d.ts +50 -0
  353. package/dist/storage/keys.d.ts.map +1 -0
  354. package/dist/storage/keys.js +120 -0
  355. package/dist/storage/keys.js.map +1 -0
  356. package/dist/storage/memory.d.ts +32 -0
  357. package/dist/storage/memory.d.ts.map +1 -0
  358. package/dist/storage/memory.js +84 -0
  359. package/dist/storage/memory.js.map +1 -0
  360. package/dist/storage/provider.d.ts +93 -0
  361. package/dist/storage/provider.d.ts.map +1 -0
  362. package/dist/storage/provider.js +2 -0
  363. package/dist/storage/provider.js.map +1 -0
  364. package/dist/storage/s3.d.ts +34 -0
  365. package/dist/storage/s3.d.ts.map +1 -0
  366. package/dist/storage/s3.js +175 -0
  367. package/dist/storage/s3.js.map +1 -0
  368. package/dist/storage/service.d.ts +86 -0
  369. package/dist/storage/service.d.ts.map +1 -0
  370. package/dist/storage/service.js +107 -0
  371. package/dist/storage/service.js.map +1 -0
  372. package/dist/storage/sigv4.d.ts +58 -0
  373. package/dist/storage/sigv4.d.ts.map +1 -0
  374. package/dist/storage/sigv4.js +114 -0
  375. package/dist/storage/sigv4.js.map +1 -0
  376. package/dist/streams/client.d.ts +91 -0
  377. package/dist/streams/client.d.ts.map +1 -0
  378. package/dist/streams/client.js +128 -0
  379. package/dist/streams/client.js.map +1 -0
  380. package/dist/streams/events.d.ts +68 -0
  381. package/dist/streams/events.d.ts.map +1 -0
  382. package/dist/streams/events.js +81 -0
  383. package/dist/streams/events.js.map +1 -0
  384. package/dist/streams/index.d.ts +47 -0
  385. package/dist/streams/index.d.ts.map +1 -0
  386. package/dist/streams/index.js +47 -0
  387. package/dist/streams/index.js.map +1 -0
  388. package/dist/streams/realtime.d.ts +27 -0
  389. package/dist/streams/realtime.d.ts.map +1 -0
  390. package/dist/streams/realtime.js +50 -0
  391. package/dist/streams/realtime.js.map +1 -0
  392. package/dist/streams/state.d.ts +26 -0
  393. package/dist/streams/state.d.ts.map +1 -0
  394. package/dist/streams/state.js +34 -0
  395. package/dist/streams/state.js.map +1 -0
  396. package/dist/users/index.d.ts +9 -0
  397. package/dist/users/index.d.ts.map +1 -0
  398. package/dist/users/index.js +23 -0
  399. package/dist/users/index.js.map +1 -0
  400. package/dist/users/service.d.ts +43 -0
  401. package/dist/users/service.d.ts.map +1 -0
  402. package/dist/users/service.js +113 -0
  403. package/dist/users/service.js.map +1 -0
  404. package/dist/webhooks/inbound.d.ts +70 -0
  405. package/dist/webhooks/inbound.d.ts.map +1 -0
  406. package/dist/webhooks/inbound.js +146 -0
  407. package/dist/webhooks/inbound.js.map +1 -0
  408. package/dist/webhooks/index.d.ts +12 -0
  409. package/dist/webhooks/index.d.ts.map +1 -0
  410. package/dist/webhooks/index.js +65 -0
  411. package/dist/webhooks/index.js.map +1 -0
  412. package/dist/webhooks/outgoing.d.ts +89 -0
  413. package/dist/webhooks/outgoing.d.ts.map +1 -0
  414. package/dist/webhooks/outgoing.js +375 -0
  415. package/dist/webhooks/outgoing.js.map +1 -0
  416. package/dist/webhooks/signature.d.ts +40 -0
  417. package/dist/webhooks/signature.d.ts.map +1 -0
  418. package/dist/webhooks/signature.js +77 -0
  419. package/dist/webhooks/signature.js.map +1 -0
  420. package/dist/workspaces/context.d.ts +30 -0
  421. package/dist/workspaces/context.d.ts.map +1 -0
  422. package/dist/workspaces/context.js +12 -0
  423. package/dist/workspaces/context.js.map +1 -0
  424. package/dist/workspaces/index.d.ts +5 -0
  425. package/dist/workspaces/index.d.ts.map +1 -0
  426. package/dist/workspaces/index.js +21 -0
  427. package/dist/workspaces/index.js.map +1 -0
  428. package/dist/workspaces/service.d.ts +126 -0
  429. package/dist/workspaces/service.d.ts.map +1 -0
  430. package/dist/workspaces/service.js +495 -0
  431. package/dist/workspaces/service.js.map +1 -0
  432. package/docs/README.md +71 -0
  433. package/docs/api-keys.md +184 -0
  434. package/docs/audit.md +198 -0
  435. package/docs/auth.md +196 -0
  436. package/docs/authorization.md +225 -0
  437. package/docs/billing.md +293 -0
  438. package/docs/cli.md +238 -0
  439. package/docs/config.md +163 -0
  440. package/docs/db.md +219 -0
  441. package/docs/email.md +222 -0
  442. package/docs/entitlements.md +194 -0
  443. package/docs/errors.md +158 -0
  444. package/docs/events.md +279 -0
  445. package/docs/feature-flags.md +237 -0
  446. package/docs/files.md +229 -0
  447. package/docs/jobs.md +288 -0
  448. package/docs/logger.md +269 -0
  449. package/docs/notifications.md +179 -0
  450. package/docs/publishing.md +128 -0
  451. package/docs/realtime.md +360 -0
  452. package/docs/storage.md +279 -0
  453. package/docs/streams.md +296 -0
  454. package/docs/users.md +117 -0
  455. package/docs/webhooks.md +272 -0
  456. package/docs/workspaces.md +269 -0
  457. package/drizzle/0000_init_users.sql +21 -0
  458. package/drizzle/0001_workspaces_roles_permissions.sql +86 -0
  459. package/drizzle/0002_billing_entitlements.sql +97 -0
  460. package/drizzle/0003_events.sql +17 -0
  461. package/drizzle/0004_notifications_audit.sql +64 -0
  462. package/drizzle/0005_api_keys_webhooks.sql +77 -0
  463. package/drizzle/0006_feature_flags.sql +22 -0
  464. package/drizzle/0007_files.sql +23 -0
  465. package/drizzle/meta/0000_snapshot.json +160 -0
  466. package/drizzle/meta/0001_snapshot.json +837 -0
  467. package/drizzle/meta/0002_snapshot.json +1580 -0
  468. package/drizzle/meta/0003_snapshot.json +1751 -0
  469. package/drizzle/meta/0004_snapshot.json +2109 -0
  470. package/drizzle/meta/0005_snapshot.json +2719 -0
  471. package/drizzle/meta/0006_snapshot.json +2909 -0
  472. package/drizzle/meta/0007_snapshot.json +3113 -0
  473. package/drizzle/meta/_journal.json +62 -0
  474. package/package.json +180 -0
@@ -0,0 +1,92 @@
1
+ import type { FileRecord, FileStatus } from "../db/schema/index.ts";
2
+ import type { CoreDatabase } from "../db/types.ts";
3
+ import type { ObjectBody } from "../storage/provider.ts";
4
+ import type { StorageService, UrlOptions } from "../storage/service.ts";
5
+ import type { WorkspaceContext } from "../workspaces/context.ts";
6
+ /**
7
+ * Reduce a caller-supplied filename to something safe to store and echo back.
8
+ *
9
+ * The filename never becomes part of the storage key — that is derived from the
10
+ * row id — so this is not a traversal defence. It exists because the value is
11
+ * displayed, and put in a `Content-Disposition` header: path separators would be
12
+ * confusing, control characters can break a header, and an unbounded length is a
13
+ * denial-of-service on every UI that renders it.
14
+ */
15
+ export declare function sanitizeFilename(filename: string): string;
16
+ export interface CreateUploadInput {
17
+ readonly filename: string;
18
+ readonly contentType?: string;
19
+ /**
20
+ * Declared size, used to reject an oversized upload before issuing a URL.
21
+ *
22
+ * Advisory only — a presigned `PUT` cannot enforce it. The real figure is
23
+ * checked on {@link FilesService.confirmUpload}.
24
+ */
25
+ readonly sizeBytes?: number;
26
+ readonly metadata?: Record<string, unknown>;
27
+ readonly expiresInSeconds?: number;
28
+ /** Overrides the service default. */
29
+ readonly maxBytes?: number;
30
+ }
31
+ export interface DirectUpload {
32
+ readonly file: FileRecord;
33
+ /** Where the browser should `PUT` the bytes. */
34
+ readonly uploadUrl: string;
35
+ }
36
+ export interface ServerUploadInput {
37
+ readonly filename: string;
38
+ readonly body: ObjectBody;
39
+ readonly contentType?: string;
40
+ readonly metadata?: Record<string, unknown>;
41
+ readonly maxBytes?: number;
42
+ }
43
+ export interface ListFilesOptions {
44
+ readonly status?: FileStatus | readonly FileStatus[];
45
+ readonly limit?: number;
46
+ readonly before?: Date;
47
+ }
48
+ export interface FilesService {
49
+ /**
50
+ * Reserve a file and hand back a URL the browser can upload to.
51
+ *
52
+ * The row is created `pending`. Nothing treats the file as real until
53
+ * {@link confirmUpload} has verified the object exists.
54
+ */
55
+ createUpload(context: WorkspaceContext, input: CreateUploadInput): Promise<DirectUpload>;
56
+ /**
57
+ * Verify the object landed, record its true size, and mark the file ready.
58
+ *
59
+ * A client saying "done" is not evidence. This asks the store.
60
+ */
61
+ confirmUpload(context: WorkspaceContext, fileId: string): Promise<FileRecord>;
62
+ /** Upload from the server, in one step. The row is `ready` immediately. */
63
+ upload(context: WorkspaceContext, input: ServerUploadInput): Promise<FileRecord>;
64
+ get(context: WorkspaceContext, fileId: string): Promise<FileRecord>;
65
+ list(context: WorkspaceContext, options?: ListFilesOptions): Promise<FileRecord[]>;
66
+ /** A URL for reading the file, named with its original filename. */
67
+ getUrl(context: WorkspaceContext, fileId: string, options?: UrlOptions): Promise<string>;
68
+ /** Remove the object and the row. */
69
+ delete(context: WorkspaceContext, fileId: string): Promise<void>;
70
+ /** An existing ready file with the same content, for deduplication. */
71
+ findByChecksum(context: WorkspaceContext, checksum: string): Promise<FileRecord | undefined>;
72
+ /**
73
+ * Delete `pending` rows older than a cutoff, and any object they left behind.
74
+ *
75
+ * A presigned URL that is never used leaves a reservation forever. Run this
76
+ * from a scheduled job.
77
+ */
78
+ purgeAbandoned(options?: {
79
+ olderThan?: Date;
80
+ limit?: number;
81
+ }): Promise<number>;
82
+ }
83
+ export interface FilesServiceDeps {
84
+ readonly db: CoreDatabase;
85
+ readonly storage: StorageService;
86
+ readonly maxBytes?: number;
87
+ readonly now?: () => Date;
88
+ }
89
+ /** Where a file's bytes live. Derived from the row id, never from caller input. */
90
+ export declare function fileStoragePath(fileId: string): string;
91
+ export declare function createFilesService(deps: FilesServiceDeps): FilesService;
92
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/files/service.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAWjE;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAgBzD;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5C,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,qCAAqC;IACrC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,gDAAgD;IAChD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5C,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,UAAU,EAAE,CAAC;IACrD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B;;;;;OAKG;IACH,YAAY,CAAC,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAEzF;;;;OAIG;IACH,aAAa,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAE9E,2EAA2E;IAC3E,MAAM,CAAC,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAEjF,GAAG,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACpE,IAAI,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAEnF,oEAAoE;IACpE,MAAM,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEzF,qCAAqC;IACrC,MAAM,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjE,uEAAuE;IACvE,cAAc,CAAC,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;IAE7F;;;;;OAKG;IACH,cAAc,CAAC,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,IAAI,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACjF;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,EAAE,YAAY,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAED,mFAAmF;AACnF,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,GAAG,YAAY,CA8TvE"}
@@ -0,0 +1,303 @@
1
+ import { createHash } from "node:crypto";
2
+ import { and, desc, eq, inArray, lt } from "drizzle-orm";
3
+ import { files } from "../db/schema/index.js";
4
+ import { ConflictError, InvalidInputError, NotFoundError } from "../errors.js";
5
+ /** Control characters, built from escapes so none is ever a literal. */
6
+ const CONTROL_CHARACTERS = /[\u0000-\u001f\u007f]/g;
7
+ const MAX_FILENAME_LENGTH = 255;
8
+ const DEFAULT_UPLOAD_URL_SECONDS = 900;
9
+ const DEFAULT_MAX_BYTES = 25 * 1024 * 1024;
10
+ const DEFAULT_LIST_LIMIT = 50;
11
+ const MAX_LIST_LIMIT = 200;
12
+ /**
13
+ * Reduce a caller-supplied filename to something safe to store and echo back.
14
+ *
15
+ * The filename never becomes part of the storage key — that is derived from the
16
+ * row id — so this is not a traversal defence. It exists because the value is
17
+ * displayed, and put in a `Content-Disposition` header: path separators would be
18
+ * confusing, control characters can break a header, and an unbounded length is a
19
+ * denial-of-service on every UI that renders it.
20
+ */
21
+ export function sanitizeFilename(filename) {
22
+ const cleaned = filename
23
+ .replace(CONTROL_CHARACTERS, "")
24
+ // Collapse any path the browser included; only the leaf is meaningful.
25
+ .split(/[/\\]/)
26
+ .pop()
27
+ .replace(/^\.+/, "")
28
+ .trim();
29
+ if (cleaned.length === 0) {
30
+ throw new InvalidInputError("A filename is required.");
31
+ }
32
+ return cleaned.length > MAX_FILENAME_LENGTH
33
+ ? cleaned.slice(0, MAX_FILENAME_LENGTH)
34
+ : cleaned;
35
+ }
36
+ /** Where a file's bytes live. Derived from the row id, never from caller input. */
37
+ export function fileStoragePath(fileId) {
38
+ return `files/${fileId}`;
39
+ }
40
+ export function createFilesService(deps) {
41
+ const now = deps.now ?? (() => new Date());
42
+ const maxBytes = deps.maxBytes ?? DEFAULT_MAX_BYTES;
43
+ async function requireOwn(context, fileId) {
44
+ const rows = await deps.db
45
+ .select()
46
+ .from(files)
47
+ .where(and(eq(files.id, fileId),
48
+ // Scoped, so another tenant's file id is simply not found.
49
+ eq(files.workspaceId, context.workspaceId)))
50
+ .limit(1);
51
+ const file = rows[0];
52
+ if (file === undefined) {
53
+ throw new NotFoundError("File not found.");
54
+ }
55
+ return file;
56
+ }
57
+ const service = {
58
+ async createUpload(context, input) {
59
+ const filename = sanitizeFilename(input.filename);
60
+ const limit = input.maxBytes ?? maxBytes;
61
+ if (input.sizeBytes !== undefined) {
62
+ if (!Number.isInteger(input.sizeBytes) || input.sizeBytes < 0) {
63
+ throw new InvalidInputError("sizeBytes must be a non-negative integer.");
64
+ }
65
+ if (input.sizeBytes > limit) {
66
+ // Rejected before a URL is issued, so the bytes never travel.
67
+ throw new InvalidInputError(`Upload exceeds the ${limit} byte limit.`);
68
+ }
69
+ }
70
+ const scoped = deps.storage.forWorkspace(context);
71
+ /**
72
+ * The row is inserted first so its id can seed the storage key. That makes
73
+ * the key entirely server-derived: a filename may contain anything at all
74
+ * without ever becoming part of a path.
75
+ */
76
+ const [reserved] = await deps.db
77
+ .insert(files)
78
+ .values({
79
+ workspaceId: context.workspaceId,
80
+ // Replaced immediately below; a placeholder keeps the column not-null.
81
+ storageKey: `pending:${crypto.randomUUID()}`,
82
+ filename,
83
+ contentType: input.contentType ?? null,
84
+ sizeBytes: input.sizeBytes ?? null,
85
+ uploadedByUserId: context.userId,
86
+ status: "pending",
87
+ metadata: (input.metadata ?? null),
88
+ })
89
+ .returning();
90
+ const storageKey = scoped.keyFor(fileStoragePath(reserved.id));
91
+ const [file] = await deps.db
92
+ .update(files)
93
+ .set({ storageKey, updatedAt: now() })
94
+ .where(eq(files.id, reserved.id))
95
+ .returning();
96
+ const uploadUrl = await scoped.createUploadUrl(fileStoragePath(reserved.id), {
97
+ expiresInSeconds: input.expiresInSeconds ?? DEFAULT_UPLOAD_URL_SECONDS,
98
+ ...(input.contentType !== undefined ? { contentType: input.contentType } : {}),
99
+ });
100
+ return { file: file, uploadUrl };
101
+ },
102
+ async confirmUpload(context, fileId) {
103
+ const file = await requireOwn(context, fileId);
104
+ if (file.status === "ready") {
105
+ // Idempotent: a client retrying confirmation is not an error.
106
+ return file;
107
+ }
108
+ const provider = deps.storage.provider;
109
+ const at = now();
110
+ /**
111
+ * Ask the store. A client reporting success is not evidence — without this
112
+ * a caller could mark a file ready that was never uploaded, and every
113
+ * consumer downstream would then fail on a missing object.
114
+ */
115
+ const stat = provider.stat !== undefined
116
+ ? await provider.stat(file.storageKey)
117
+ : (await provider.exists(file.storageKey))
118
+ ? { size: file.sizeBytes ?? 0 }
119
+ : undefined;
120
+ if (stat === undefined) {
121
+ const [failed] = await deps.db
122
+ .update(files)
123
+ .set({ status: "failed", updatedAt: at })
124
+ .where(eq(files.id, file.id))
125
+ .returning();
126
+ throw new ConflictError("No uploaded object found for this file.", {
127
+ cause: new Error(`storage key ${failed.storageKey} is absent`),
128
+ });
129
+ }
130
+ /**
131
+ * A presigned PUT cannot cap the body, so this is where an oversized upload
132
+ * is caught. The object is removed rather than left billable.
133
+ */
134
+ if (stat.size > maxBytes) {
135
+ await provider.delete(file.storageKey);
136
+ await deps.db
137
+ .update(files)
138
+ .set({ status: "failed", sizeBytes: stat.size, updatedAt: at })
139
+ .where(eq(files.id, file.id));
140
+ throw new InvalidInputError(`Uploaded object exceeds the ${maxBytes} byte limit.`);
141
+ }
142
+ const [ready] = await deps.db
143
+ .update(files)
144
+ .set({
145
+ status: "ready",
146
+ // The store's figure, not the client's claim.
147
+ sizeBytes: stat.size,
148
+ ...(file.contentType === null && stat.contentType !== undefined
149
+ ? { contentType: stat.contentType }
150
+ : {}),
151
+ confirmedAt: at,
152
+ updatedAt: at,
153
+ })
154
+ .where(eq(files.id, file.id))
155
+ .returning();
156
+ return ready;
157
+ },
158
+ async upload(context, input) {
159
+ const filename = sanitizeFilename(input.filename);
160
+ const limit = input.maxBytes ?? maxBytes;
161
+ const bytes = typeof input.body === "string" ? new TextEncoder().encode(input.body) : input.body;
162
+ if (bytes.byteLength > limit) {
163
+ throw new InvalidInputError(`Upload exceeds the ${limit} byte limit.`);
164
+ }
165
+ const at = now();
166
+ const scoped = deps.storage.forWorkspace(context);
167
+ const [reserved] = await deps.db
168
+ .insert(files)
169
+ .values({
170
+ workspaceId: context.workspaceId,
171
+ storageKey: `pending:${crypto.randomUUID()}`,
172
+ filename,
173
+ contentType: input.contentType ?? null,
174
+ sizeBytes: bytes.byteLength,
175
+ uploadedByUserId: context.userId,
176
+ status: "pending",
177
+ metadata: (input.metadata ?? null),
178
+ })
179
+ .returning();
180
+ const path = fileStoragePath(reserved.id);
181
+ const storageKey = scoped.keyFor(path);
182
+ try {
183
+ await scoped.upload({
184
+ path,
185
+ body: bytes,
186
+ ...(input.contentType !== undefined ? { contentType: input.contentType } : {}),
187
+ maxBytes: limit,
188
+ });
189
+ }
190
+ catch (error) {
191
+ /**
192
+ * The row is removed rather than left `pending`. A server-side upload that
193
+ * failed has no object to collect later, so a reservation would be pure
194
+ * noise in the sweep.
195
+ */
196
+ await deps.db.delete(files).where(eq(files.id, reserved.id));
197
+ throw error;
198
+ }
199
+ const [ready] = await deps.db
200
+ .update(files)
201
+ .set({
202
+ storageKey,
203
+ status: "ready",
204
+ // The server saw the bytes, so the checksum is trustworthy here.
205
+ checksum: createHash("sha256").update(bytes).digest("hex"),
206
+ confirmedAt: at,
207
+ updatedAt: at,
208
+ })
209
+ .where(eq(files.id, reserved.id))
210
+ .returning();
211
+ return ready;
212
+ },
213
+ async get(context, fileId) {
214
+ return requireOwn(context, fileId);
215
+ },
216
+ async list(context, options = {}) {
217
+ const clauses = [eq(files.workspaceId, context.workspaceId)];
218
+ if (options.status !== undefined) {
219
+ const statuses = Array.isArray(options.status) ? options.status : [options.status];
220
+ clauses.push(inArray(files.status, [...statuses]));
221
+ }
222
+ if (options.before !== undefined) {
223
+ clauses.push(lt(files.createdAt, options.before));
224
+ }
225
+ return deps.db
226
+ .select()
227
+ .from(files)
228
+ .where(and(...clauses))
229
+ // Tie-broken on id so keyset pagination cannot loop on equal timestamps.
230
+ .orderBy(desc(files.createdAt), desc(files.id))
231
+ .limit(Math.min(options.limit ?? DEFAULT_LIST_LIMIT, MAX_LIST_LIMIT));
232
+ },
233
+ async getUrl(context, fileId, options = {}) {
234
+ const file = await requireOwn(context, fileId);
235
+ if (file.status !== "ready") {
236
+ // A pending file has no object behind it; a URL would 404.
237
+ throw new ConflictError("File is not ready.");
238
+ }
239
+ return deps.storage.forWorkspace(context).urlForKey(file.storageKey, {
240
+ ...options,
241
+ /**
242
+ * Defaults to the stored filename, so a download is named sensibly and
243
+ * served as an attachment — which is what makes user uploads safe to hand
244
+ * back. Pass `downloadFilename: undefined` explicitly to opt out.
245
+ */
246
+ downloadFilename: options.downloadFilename ?? file.filename,
247
+ });
248
+ },
249
+ async delete(context, fileId) {
250
+ const file = await requireOwn(context, fileId);
251
+ /**
252
+ * Object first. If the row went first and the delete failed, the object
253
+ * would be orphaned with nothing left pointing at it — unreachable and
254
+ * still billed.
255
+ */
256
+ await deps.storage.forWorkspace(context).deleteKey(file.storageKey);
257
+ await deps.db.delete(files).where(eq(files.id, file.id));
258
+ },
259
+ async findByChecksum(context, checksum) {
260
+ const rows = await deps.db
261
+ .select()
262
+ .from(files)
263
+ .where(and(eq(files.workspaceId, context.workspaceId), eq(files.checksum, checksum), eq(files.status, "ready")))
264
+ .limit(1);
265
+ return rows[0];
266
+ },
267
+ async purgeAbandoned(options = {}) {
268
+ /**
269
+ * Default cutoff is a day, comfortably beyond any upload URL's lifetime.
270
+ *
271
+ * Note the two clocks: this is computed from the injected `now`, while
272
+ * `created_at` defaults to PostgreSQL's. A day of slack makes any realistic
273
+ * skew between an application server and the database irrelevant — but pass
274
+ * `olderThan` if you need the cutoff to be exact.
275
+ */
276
+ const cutoff = options.olderThan ?? new Date(now().getTime() - 24 * 60 * 60 * 1000);
277
+ const abandoned = await deps.db
278
+ .select()
279
+ .from(files)
280
+ .where(and(eq(files.status, "pending"), lt(files.createdAt, cutoff)))
281
+ .limit(options.limit ?? 100);
282
+ let removed = 0;
283
+ for (const file of abandoned) {
284
+ /**
285
+ * A reservation may have a half-finished object behind it, so the store is
286
+ * asked to delete unconditionally — a missing key is not an error.
287
+ */
288
+ try {
289
+ await deps.storage.provider.delete(file.storageKey);
290
+ }
291
+ catch {
292
+ // Leave the row so the next sweep retries rather than losing the record.
293
+ continue;
294
+ }
295
+ await deps.db.delete(files).where(eq(files.id, file.id));
296
+ removed += 1;
297
+ }
298
+ return removed;
299
+ },
300
+ };
301
+ return service;
302
+ }
303
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/files/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAEzD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAG9C,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAK/E,wEAAwE;AACxE,MAAM,kBAAkB,GAAG,wBAAwB,CAAC;AAEpD,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAChC,MAAM,0BAA0B,GAAG,GAAG,CAAC;AACvC,MAAM,iBAAiB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAC3C,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAC9B,MAAM,cAAc,GAAG,GAAG,CAAC;AAE3B;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,MAAM,OAAO,GAAG,QAAQ;SACrB,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC;QAChC,uEAAuE;SACtE,KAAK,CAAC,OAAO,CAAC;SACd,GAAG,EAAG;SACN,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;SACnB,IAAI,EAAE,CAAC;IAEV,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,iBAAiB,CAAC,yBAAyB,CAAC,CAAC;IACzD,CAAC;IAED,OAAO,OAAO,CAAC,MAAM,GAAG,mBAAmB;QACzC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,mBAAmB,CAAC;QACvC,CAAC,CAAC,OAAO,CAAC;AACd,CAAC;AAqFD,mFAAmF;AACnF,MAAM,UAAU,eAAe,CAAC,MAAc;IAC5C,OAAO,SAAS,MAAM,EAAE,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAsB;IACvD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,iBAAiB,CAAC;IAEpD,KAAK,UAAU,UAAU,CAAC,OAAyB,EAAE,MAAc;QACjE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,EAAE;aACvB,MAAM,EAAE;aACR,IAAI,CAAC,KAAK,CAAC;aACX,KAAK,CACJ,GAAG,CACD,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,CAAC;QACpB,2DAA2D;QAC3D,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,CAC3C,CACF;aACA,KAAK,CAAC,CAAC,CAAC,CAAC;QAEZ,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACrB,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,MAAM,IAAI,aAAa,CAAC,iBAAiB,CAAC,CAAC;QAC7C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAiB;QAC5B,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,KAAK;YAC/B,MAAM,QAAQ,GAAG,gBAAgB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAClD,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,IAAI,QAAQ,CAAC;YAEzC,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;gBAClC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;oBAC9D,MAAM,IAAI,iBAAiB,CAAC,2CAA2C,CAAC,CAAC;gBAC3E,CAAC;gBACD,IAAI,KAAK,CAAC,SAAS,GAAG,KAAK,EAAE,CAAC;oBAC5B,8DAA8D;oBAC9D,MAAM,IAAI,iBAAiB,CAAC,sBAAsB,KAAK,cAAc,CAAC,CAAC;gBACzE,CAAC;YACH,CAAC;YAED,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;YAElD;;;;eAIG;YACH,MAAM,CAAC,QAAQ,CAAC,GAAG,MAAM,IAAI,CAAC,EAAE;iBAC7B,MAAM,CAAC,KAAK,CAAC;iBACb,MAAM,CAAC;gBACN,WAAW,EAAE,OAAO,CAAC,WAAW;gBAChC,uEAAuE;gBACvE,UAAU,EAAE,WAAW,MAAM,CAAC,UAAU,EAAE,EAAE;gBAC5C,QAAQ;gBACR,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,IAAI;gBACtC,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI;gBAClC,gBAAgB,EAAE,OAAO,CAAC,MAAM;gBAChC,MAAM,EAAE,SAAS;gBACjB,QAAQ,EAAE,CAAC,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAU;aAC5C,CAAC;iBACD,SAAS,EAAE,CAAC;YAEf,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,QAAS,CAAC,EAAE,CAAC,CAAC,CAAC;YAEhE,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC,EAAE;iBACzB,MAAM,CAAC,KAAK,CAAC;iBACb,GAAG,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,EAAE,EAAE,CAAC;iBACrC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,QAAS,CAAC,EAAE,CAAC,CAAC;iBACjC,SAAS,EAAE,CAAC;YAEf,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,eAAe,CAAC,QAAS,CAAC,EAAE,CAAC,EAAE;gBAC5E,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,IAAI,0BAA0B;gBACtE,GAAG,CAAC,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC/E,CAAC,CAAC;YAEH,OAAO,EAAE,IAAI,EAAE,IAAK,EAAE,SAAS,EAAE,CAAC;QACpC,CAAC;QAED,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM;YACjC,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAE/C,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;gBAC5B,8DAA8D;gBAC9D,OAAO,IAAI,CAAC;YACd,CAAC;YAED,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;YACvC,MAAM,EAAE,GAAG,GAAG,EAAE,CAAC;YAEjB;;;;eAIG;YACH,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,KAAK,SAAS;gBACtC,CAAC,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC;gBACtC,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;oBACxC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,IAAI,CAAC,EAAE;oBAC/B,CAAC,CAAC,SAAS,CAAC;YAEhB,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,EAAE;qBAC3B,MAAM,CAAC,KAAK,CAAC;qBACb,GAAG,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;qBACxC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;qBAC5B,SAAS,EAAE,CAAC;gBAEf,MAAM,IAAI,aAAa,CAAC,yCAAyC,EAAE;oBACjE,KAAK,EAAE,IAAI,KAAK,CAAC,eAAe,MAAO,CAAC,UAAU,YAAY,CAAC;iBAChE,CAAC,CAAC;YACL,CAAC;YAED;;;eAGG;YACH,IAAI,IAAI,CAAC,IAAI,GAAG,QAAQ,EAAE,CAAC;gBACzB,MAAM,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBACvC,MAAM,IAAI,CAAC,EAAE;qBACV,MAAM,CAAC,KAAK,CAAC;qBACb,GAAG,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;qBAC9D,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBAEhC,MAAM,IAAI,iBAAiB,CAAC,+BAA+B,QAAQ,cAAc,CAAC,CAAC;YACrF,CAAC;YAED,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC,EAAE;iBAC1B,MAAM,CAAC,KAAK,CAAC;iBACb,GAAG,CAAC;gBACH,MAAM,EAAE,OAAO;gBACf,8CAA8C;gBAC9C,SAAS,EAAE,IAAI,CAAC,IAAI;gBACpB,GAAG,CAAC,IAAI,CAAC,WAAW,KAAK,IAAI,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS;oBAC7D,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE;oBACnC,CAAC,CAAC,EAAE,CAAC;gBACP,WAAW,EAAE,EAAE;gBACf,SAAS,EAAE,EAAE;aACd,CAAC;iBACD,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;iBAC5B,SAAS,EAAE,CAAC;YAEf,OAAO,KAAM,CAAC;QAChB,CAAC;QAED,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK;YACzB,MAAM,QAAQ,GAAG,gBAAgB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAClD,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,IAAI,QAAQ,CAAC;YAEzC,MAAM,KAAK,GACT,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;YAErF,IAAI,KAAK,CAAC,UAAU,GAAG,KAAK,EAAE,CAAC;gBAC7B,MAAM,IAAI,iBAAiB,CAAC,sBAAsB,KAAK,cAAc,CAAC,CAAC;YACzE,CAAC;YAED,MAAM,EAAE,GAAG,GAAG,EAAE,CAAC;YACjB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;YAElD,MAAM,CAAC,QAAQ,CAAC,GAAG,MAAM,IAAI,CAAC,EAAE;iBAC7B,MAAM,CAAC,KAAK,CAAC;iBACb,MAAM,CAAC;gBACN,WAAW,EAAE,OAAO,CAAC,WAAW;gBAChC,UAAU,EAAE,WAAW,MAAM,CAAC,UAAU,EAAE,EAAE;gBAC5C,QAAQ;gBACR,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,IAAI;gBACtC,SAAS,EAAE,KAAK,CAAC,UAAU;gBAC3B,gBAAgB,EAAE,OAAO,CAAC,MAAM;gBAChC,MAAM,EAAE,SAAS;gBACjB,QAAQ,EAAE,CAAC,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAU;aAC5C,CAAC;iBACD,SAAS,EAAE,CAAC;YAEf,MAAM,IAAI,GAAG,eAAe,CAAC,QAAS,CAAC,EAAE,CAAC,CAAC;YAC3C,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAEvC,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,MAAM,CAAC;oBAClB,IAAI;oBACJ,IAAI,EAAE,KAAK;oBACX,GAAG,CAAC,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC9E,QAAQ,EAAE,KAAK;iBAChB,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf;;;;mBAIG;gBACH,MAAM,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,QAAS,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC9D,MAAM,KAAK,CAAC;YACd,CAAC;YAED,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC,EAAE;iBAC1B,MAAM,CAAC,KAAK,CAAC;iBACb,GAAG,CAAC;gBACH,UAAU;gBACV,MAAM,EAAE,OAAO;gBACf,iEAAiE;gBACjE,QAAQ,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;gBAC1D,WAAW,EAAE,EAAE;gBACf,SAAS,EAAE,EAAE;aACd,CAAC;iBACD,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,QAAS,CAAC,EAAE,CAAC,CAAC;iBACjC,SAAS,EAAE,CAAC;YAEf,OAAO,KAAM,CAAC;QAChB,CAAC;QAED,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM;YACvB,OAAO,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACrC,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,EAAE;YAC9B,MAAM,OAAO,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;YAE7D,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBACjC,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;gBACnF,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YACrD,CAAC;YACD,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBACjC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;YACpD,CAAC;YAED,OAAO,IAAI,CAAC,EAAE;iBACX,MAAM,EAAE;iBACR,IAAI,CAAC,KAAK,CAAC;iBACX,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC;gBACvB,yEAAyE;iBACxE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;iBAC9C,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,IAAI,kBAAkB,EAAE,cAAc,CAAC,CAAC,CAAC;QAC1E,CAAC;QAED,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,EAAE;YACxC,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAE/C,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;gBAC5B,2DAA2D;gBAC3D,MAAM,IAAI,aAAa,CAAC,oBAAoB,CAAC,CAAC;YAChD,CAAC;YAED,OAAO,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE;gBACnE,GAAG,OAAO;gBACV;;;;mBAIG;gBACH,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,IAAI,CAAC,QAAQ;aAC5D,CAAC,CAAC;QACL,CAAC;QAED,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM;YAC1B,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAE/C;;;;eAIG;YACH,MAAM,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACpE,MAAM,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3D,CAAC;QAED,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,QAAQ;YACpC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,EAAE;iBACvB,MAAM,EAAE;iBACR,IAAI,CAAC,KAAK,CAAC;iBACX,KAAK,CACJ,GAAG,CACD,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,EAC1C,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAC5B,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAC1B,CACF;iBACA,KAAK,CAAC,CAAC,CAAC,CAAC;YAEZ,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;QAED,KAAK,CAAC,cAAc,CAAC,OAAO,GAAG,EAAE;YAC/B;;;;;;;eAOG;YACH,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;YAEpF,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,EAAE;iBAC5B,MAAM,EAAE;iBACR,IAAI,CAAC,KAAK,CAAC;iBACX,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;iBACpE,KAAK,CAAC,OAAO,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC;YAE/B,IAAI,OAAO,GAAG,CAAC,CAAC;YAEhB,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;gBAC7B;;;mBAGG;gBACH,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBACtD,CAAC;gBAAC,MAAM,CAAC;oBACP,yEAAyE;oBACzE,SAAS;gBACX,CAAC;gBAED,MAAM,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBACzD,OAAO,IAAI,CAAC,CAAC;YACf,CAAC;YAED,OAAO,OAAO,CAAC;QACjB,CAAC;KACF,CAAC;IAEF,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @digimuza/saas-core
3
+ *
4
+ * The root entry point is intentionally almost empty. Import from a subpath so
5
+ * that server-only code (configuration, database, auth) is never reachable from
6
+ * a client bundle through a barrel file:
7
+ *
8
+ * ```ts
9
+ * import { config } from "@digimuza/saas-core/config";
10
+ * import { clientConfig } from "@digimuza/saas-core/config/client";
11
+ * import { getDatabase } from "@digimuza/saas-core/db";
12
+ * import { users } from "@digimuza/saas-core/db/schema";
13
+ * import { auth } from "@digimuza/saas-core/auth";
14
+ * import { workspaces } from "@digimuza/saas-core/workspaces";
15
+ * import { authorization } from "@digimuza/saas-core/authorization";
16
+ * import { billing } from "@digimuza/saas-core/billing";
17
+ * import { entitlements } from "@digimuza/saas-core/entitlements";
18
+ * import { events } from "@digimuza/saas-core/events";
19
+ * import { jobs } from "@digimuza/saas-core/jobs";
20
+ * import { realtime } from "@digimuza/saas-core/realtime";
21
+ * import { fromEvents } from "@digimuza/saas-core/streams";
22
+ * import { email } from "@digimuza/saas-core/email";
23
+ * import { notifications } from "@digimuza/saas-core/notifications";
24
+ * import { audit } from "@digimuza/saas-core/audit";
25
+ * ```
26
+ *
27
+ * Domain errors are re-exported here as well as from `/errors`, because route
28
+ * handlers map them to status codes and would otherwise need a second import
29
+ * just for the error classes.
30
+ */
31
+ export declare const VERSION = "0.14.0";
32
+ export { ConflictError, EntitlementRequiredError, ForbiddenError, InvalidInputError, LimitExceededError, NotFoundError, SaasCoreError, UnauthorizedError, type SaasCoreErrorCode, } from "./errors.ts";
33
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,eAAO,MAAM,OAAO,WAAW,CAAC;AAEhC,OAAO,EACL,aAAa,EACb,wBAAwB,EACxB,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,KAAK,iBAAiB,GACvB,MAAM,aAAa,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @digimuza/saas-core
3
+ *
4
+ * The root entry point is intentionally almost empty. Import from a subpath so
5
+ * that server-only code (configuration, database, auth) is never reachable from
6
+ * a client bundle through a barrel file:
7
+ *
8
+ * ```ts
9
+ * import { config } from "@digimuza/saas-core/config";
10
+ * import { clientConfig } from "@digimuza/saas-core/config/client";
11
+ * import { getDatabase } from "@digimuza/saas-core/db";
12
+ * import { users } from "@digimuza/saas-core/db/schema";
13
+ * import { auth } from "@digimuza/saas-core/auth";
14
+ * import { workspaces } from "@digimuza/saas-core/workspaces";
15
+ * import { authorization } from "@digimuza/saas-core/authorization";
16
+ * import { billing } from "@digimuza/saas-core/billing";
17
+ * import { entitlements } from "@digimuza/saas-core/entitlements";
18
+ * import { events } from "@digimuza/saas-core/events";
19
+ * import { jobs } from "@digimuza/saas-core/jobs";
20
+ * import { realtime } from "@digimuza/saas-core/realtime";
21
+ * import { fromEvents } from "@digimuza/saas-core/streams";
22
+ * import { email } from "@digimuza/saas-core/email";
23
+ * import { notifications } from "@digimuza/saas-core/notifications";
24
+ * import { audit } from "@digimuza/saas-core/audit";
25
+ * ```
26
+ *
27
+ * Domain errors are re-exported here as well as from `/errors`, because route
28
+ * handlers map them to status codes and would otherwise need a second import
29
+ * just for the error classes.
30
+ */
31
+ export const VERSION = "0.14.0";
32
+ export { ConflictError, EntitlementRequiredError, ForbiddenError, InvalidInputError, LimitExceededError, NotFoundError, SaasCoreError, UnauthorizedError, } from "./errors.js";
33
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,CAAC;AAEhC,OAAO,EACL,aAAa,EACb,wBAAwB,EACxB,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,iBAAiB,GAElB,MAAM,aAAa,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { JobTriggerOptions } from "./types.ts";
2
+ /**
3
+ * The slice of Trigger.dev the core calls.
4
+ *
5
+ * Narrow and injectable so the service is testable without a Trigger.dev
6
+ * account: the real backend is a thin adapter over `tasks.trigger`, and tests
7
+ * pass a recorder. It also keeps the SDK out of the service's imports, so the
8
+ * dependency stays in one file.
9
+ */
10
+ export interface JobBackend {
11
+ trigger(taskId: string, payload: unknown, options: JobTriggerOptions): Promise<{
12
+ readonly id: string;
13
+ }>;
14
+ }
15
+ /**
16
+ * Adapt the Trigger.dev SDK to {@link JobBackend}.
17
+ *
18
+ * The SDK is imported dynamically so that merely importing
19
+ * `@digimuza/saas-core/jobs` does not load it — a module that only needs the
20
+ * `JobPayload` type should not pull in the whole client.
21
+ */
22
+ export declare function createTriggerDevBackend(): JobBackend;
23
+ //# sourceMappingURL=backend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../src/jobs/backend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD;;;;;;;GAOG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,CACL,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACrC;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,IAAI,UAAU,CAmBpD"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Adapt the Trigger.dev SDK to {@link JobBackend}.
3
+ *
4
+ * The SDK is imported dynamically so that merely importing
5
+ * `@digimuza/saas-core/jobs` does not load it — a module that only needs the
6
+ * `JobPayload` type should not pull in the whole client.
7
+ */
8
+ export function createTriggerDevBackend() {
9
+ return {
10
+ async trigger(taskId, payload, options) {
11
+ const { tasks } = await import("@trigger.dev/sdk");
12
+ const handle = await tasks.trigger(taskId, payload,
13
+ /**
14
+ * Cast at the boundary: `JobTriggerOptions` mirrors Trigger.dev's own
15
+ * option names, but restating its full type here would couple the core's
16
+ * public surface to the SDK's internal generics.
17
+ */
18
+ options);
19
+ return { id: handle.id };
20
+ },
21
+ };
22
+ }
23
+ //# sourceMappingURL=backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend.js","sourceRoot":"","sources":["../../src/jobs/backend.ts"],"names":[],"mappings":"AAkBA;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB;IACrC,OAAO;QACL,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO;YACpC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;YAEnD,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,OAAO,CAChC,MAAM,EACN,OAAgB;YAChB;;;;eAIG;YACH,OAAgB,CACjB,CAAC;YAEF,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC;QAC3B,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,29 @@
1
+ import { type JobsService } from "./service.ts";
2
+ export { createTriggerDevBackend, type JobBackend } from "./backend.ts";
3
+ export { createJobsService, describeJobError, type JobProgress, type JobReporter, type JobsService, type JobsServiceDeps, } from "./service.ts";
4
+ export { ACTOR_TAG_PREFIX, WORKSPACE_TAG_PREFIX, type JobHandle, type JobPayload, type JobTenant, type JobTriggerOptions, type SystemJobPayload, type TriggerJobOptions, } from "./types.ts";
5
+ /**
6
+ * The Trigger.dev SDK, re-exported unchanged.
7
+ *
8
+ * Deliberate: the spec is explicit that advanced applications must be able to
9
+ * reach Trigger.dev's own capabilities. Wrapping `task`, `schedules` or `wait`
10
+ * would mean re-documenting and re-typing a mature API for no gain, and would
11
+ * lag behind it.
12
+ */
13
+ export { batch, configure as configureTriggerClient, idempotencyKeys, logger, metadata, queue, queues, retry, runs, schedules, schemaTask, tags, task, tasks, timeout, usage, wait, } from "@trigger.dev/sdk";
14
+ /**
15
+ * Point the Trigger.dev SDK at the configured credentials.
16
+ *
17
+ * Idempotent; call it from application startup and from the Trigger.dev config
18
+ * file. Reads the `jobs` configuration section, so it throws `ConfigError` if
19
+ * Trigger.dev is not configured.
20
+ */
21
+ export declare function configureJobs(): Promise<void>;
22
+ /**
23
+ * Default service, wired to Trigger.dev and the core event registry.
24
+ *
25
+ * The backend is built eagerly but imports the SDK lazily, so this module stays
26
+ * importable in a process that never queues anything.
27
+ */
28
+ export declare const jobs: JobsService;
29
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/jobs/index.ts"],"names":[],"mappings":"AA0EA,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAEnE,OAAO,EAAE,uBAAuB,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,eAAe,GACrB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,GACvB,MAAM,YAAY,CAAC;AAEpB;;;;;;;GAOG;AACH,OAAO,EACL,KAAK,EACL,SAAS,IAAI,sBAAsB,EACnC,eAAe,EACf,MAAM,EACN,QAAQ,EACR,KAAK,EACL,MAAM,EACN,KAAK,EACL,IAAI,EACJ,SAAS,EACT,UAAU,EACV,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,OAAO,EACP,KAAK,EACL,IAAI,GACL,MAAM,kBAAkB,CAAC;AAE1B;;;;;;GAMG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CASnD;AAED;;;;;GAKG;AACH,eAAO,MAAM,IAAI,EAAE,WAGjB,CAAC"}