@openlup/platform 0.0.0 → 0.16.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 (395) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/LICENSE +204 -0
  3. package/README.md +471 -1
  4. package/dist/bff/dispatch.d.ts +27 -0
  5. package/dist/bff/dispatch.js +47 -0
  6. package/dist/bff/envelope.d.ts +46 -0
  7. package/dist/bff/envelope.js +80 -0
  8. package/dist/bff/health.d.ts +24 -0
  9. package/dist/bff/health.js +19 -0
  10. package/dist/bff/index.d.ts +6 -0
  11. package/dist/bff/index.js +6 -0
  12. package/dist/bff/lazyRoute.d.ts +4 -0
  13. package/dist/bff/lazyRoute.js +13 -0
  14. package/dist/bff/requestContext.d.ts +17 -0
  15. package/dist/bff/requestContext.js +26 -0
  16. package/dist/bff/routerRewrite.d.ts +2 -0
  17. package/dist/bff/routerRewrite.js +31 -0
  18. package/dist/blob/binding.d.ts +16 -0
  19. package/dist/blob/binding.js +37 -0
  20. package/dist/blob/filesystem.d.ts +8 -0
  21. package/dist/blob/filesystem.js +71 -0
  22. package/dist/blob/index.d.ts +6 -0
  23. package/dist/blob/index.js +6 -0
  24. package/dist/blob/s3.d.ts +32 -0
  25. package/dist/blob/s3.js +56 -0
  26. package/dist/blob/s3Client.d.ts +25 -0
  27. package/dist/blob/s3Client.js +76 -0
  28. package/dist/blob/supabase.d.ts +40 -0
  29. package/dist/blob/supabase.js +59 -0
  30. package/dist/blob/vercel.d.ts +63 -0
  31. package/dist/blob/vercel.js +69 -0
  32. package/dist/composition/composeBundle.d.ts +47 -0
  33. package/dist/composition/composeBundle.js +45 -0
  34. package/dist/composition/httpBinding.d.ts +8 -0
  35. package/dist/composition/httpBinding.js +18 -0
  36. package/dist/composition/index.d.ts +3 -0
  37. package/dist/composition/index.js +3 -0
  38. package/dist/composition/nodeHost.d.ts +103 -0
  39. package/dist/composition/nodeHost.js +145 -0
  40. package/dist/data/binding.d.ts +34 -0
  41. package/dist/data/binding.js +92 -0
  42. package/dist/data/index.d.ts +5 -0
  43. package/dist/data/index.js +5 -0
  44. package/dist/data/postgresGateway.d.ts +42 -0
  45. package/dist/data/postgresGateway.js +135 -0
  46. package/dist/data/queryBuilder.d.ts +54 -0
  47. package/dist/data/queryBuilder.js +240 -0
  48. package/dist/data/queryBuilderSql.d.ts +76 -0
  49. package/dist/data/queryBuilderSql.js +145 -0
  50. package/dist/data/supabaseClientFactory.d.ts +34 -0
  51. package/dist/data/supabaseClientFactory.js +56 -0
  52. package/dist/data/supabaseGateway.d.ts +22 -0
  53. package/dist/data/supabaseGateway.js +49 -0
  54. package/dist/http/deadline.d.ts +20 -0
  55. package/dist/http/deadline.js +93 -0
  56. package/dist/http/index.d.ts +6 -0
  57. package/dist/http/index.js +5 -0
  58. package/dist/http/requestAdapter.d.ts +38 -0
  59. package/dist/http/requestAdapter.js +203 -0
  60. package/dist/http/runtime.d.ts +83 -0
  61. package/dist/http/runtime.js +199 -0
  62. package/dist/http/security.d.ts +44 -0
  63. package/dist/http/security.js +114 -0
  64. package/dist/http/staticAssets.d.ts +3 -0
  65. package/dist/http/staticAssets.js +42 -0
  66. package/dist/http/types.d.ts +23 -0
  67. package/dist/http/types.js +6 -0
  68. package/dist/identity/adminAuthBinding.d.ts +28 -0
  69. package/dist/identity/adminAuthBinding.js +66 -0
  70. package/dist/identity/adminAuthorization.d.ts +34 -0
  71. package/dist/identity/adminAuthorization.js +72 -0
  72. package/dist/identity/adminContracts.d.ts +70 -0
  73. package/dist/identity/adminContracts.js +43 -0
  74. package/dist/identity/adminMagicLinkHandler.d.ts +39 -0
  75. package/dist/identity/adminMagicLinkHandler.js +94 -0
  76. package/dist/identity/adminMeHandler.d.ts +15 -0
  77. package/dist/identity/adminMeHandler.js +49 -0
  78. package/dist/identity/adminPreflight.d.ts +16 -0
  79. package/dist/identity/adminPreflight.js +38 -0
  80. package/dist/identity/adminUserActionPorts.d.ts +31 -0
  81. package/dist/identity/adminUserActionPorts.js +51 -0
  82. package/dist/identity/adminUserHandlers.d.ts +38 -0
  83. package/dist/identity/adminUserHandlers.js +140 -0
  84. package/dist/identity/authVerifyUrl.d.ts +6 -0
  85. package/dist/identity/authVerifyUrl.js +54 -0
  86. package/dist/identity/contracts/contracts.d.ts +8 -0
  87. package/dist/identity/contracts/contracts.js +2 -0
  88. package/dist/identity/contracts/emailTrust.d.ts +3 -0
  89. package/dist/identity/contracts/emailTrust.js +4 -0
  90. package/dist/identity/contracts/index.d.ts +8 -0
  91. package/dist/identity/contracts/index.js +8 -0
  92. package/dist/identity/contracts/oidc.d.ts +3 -0
  93. package/dist/identity/contracts/oidc.js +9 -0
  94. package/dist/identity/contracts/operatorAuth.d.ts +35 -0
  95. package/dist/identity/contracts/operatorAuth.js +53 -0
  96. package/dist/identity/contracts/operatorInvitations.d.ts +37 -0
  97. package/dist/identity/contracts/operatorInvitations.js +1 -0
  98. package/dist/identity/contracts/ports.d.ts +22 -0
  99. package/dist/identity/contracts/ports.js +1 -0
  100. package/dist/identity/contracts/privacy.d.ts +62 -0
  101. package/dist/identity/contracts/privacy.js +99 -0
  102. package/dist/identity/contracts/providerList.d.ts +3 -0
  103. package/dist/identity/contracts/providerList.js +11 -0
  104. package/dist/identity/contracts/types.d.ts +16 -0
  105. package/dist/identity/contracts/types.js +4 -0
  106. package/dist/identity/contribution.d.ts +8 -0
  107. package/dist/identity/contribution.js +22 -0
  108. package/dist/identity/customerAuth.d.ts +8 -0
  109. package/dist/identity/customerAuth.js +1 -0
  110. package/dist/identity/customerAuthorization.d.ts +5 -0
  111. package/dist/identity/customerAuthorization.js +22 -0
  112. package/dist/identity/customerContracts.d.ts +42 -0
  113. package/dist/identity/customerContracts.js +43 -0
  114. package/dist/identity/customerIdentityBinding.d.ts +44 -0
  115. package/dist/identity/customerIdentityBinding.js +60 -0
  116. package/dist/identity/customerIdentityVerifier.d.ts +8 -0
  117. package/dist/identity/customerIdentityVerifier.js +101 -0
  118. package/dist/identity/customerMagicLinkHandler.d.ts +38 -0
  119. package/dist/identity/customerMagicLinkHandler.js +115 -0
  120. package/dist/identity/customerMeHandler.d.ts +11 -0
  121. package/dist/identity/customerMeHandler.js +46 -0
  122. package/dist/identity/customerPorts.d.ts +4 -0
  123. package/dist/identity/customerPorts.js +1 -0
  124. package/dist/identity/customerSessionBinding.d.ts +38 -0
  125. package/dist/identity/customerSessionBinding.js +80 -0
  126. package/dist/identity/customerSessionIssuer.d.ts +10 -0
  127. package/dist/identity/customerSessionIssuer.js +57 -0
  128. package/dist/identity/customerVerifyOtpHandler.d.ts +8 -0
  129. package/dist/identity/customerVerifyOtpHandler.js +41 -0
  130. package/dist/identity/directOperatorInvitationStore.d.ts +19 -0
  131. package/dist/identity/directOperatorInvitationStore.js +193 -0
  132. package/dist/identity/emailTrustPolicy.d.ts +14 -0
  133. package/dist/identity/emailTrustPolicy.js +16 -0
  134. package/dist/identity/identityPersonalDataContributor.d.ts +7 -0
  135. package/dist/identity/identityPersonalDataContributor.js +46 -0
  136. package/dist/identity/identityReadiness.d.ts +10 -0
  137. package/dist/identity/identityReadiness.js +25 -0
  138. package/dist/identity/index.d.ts +67 -0
  139. package/dist/identity/index.js +66 -0
  140. package/dist/identity/inviteAdminUserUseCase.d.ts +89 -0
  141. package/dist/identity/inviteAdminUserUseCase.js +75 -0
  142. package/dist/identity/jwtLibrary.d.ts +54 -0
  143. package/dist/identity/jwtLibrary.js +1 -0
  144. package/dist/identity/machineActorWriteFence.d.ts +4 -0
  145. package/dist/identity/machineActorWriteFence.js +13 -0
  146. package/dist/identity/magicLinkPorts.d.ts +28 -0
  147. package/dist/identity/magicLinkPorts.js +1 -0
  148. package/dist/identity/managedAccountLinkStore.d.ts +2 -0
  149. package/dist/identity/managedAccountLinkStore.js +93 -0
  150. package/dist/identity/managedAdminAuthVerifier.d.ts +7 -0
  151. package/dist/identity/managedAdminAuthVerifier.js +27 -0
  152. package/dist/identity/managedAdminUserGateways.d.ts +123 -0
  153. package/dist/identity/managedAdminUserGateways.js +127 -0
  154. package/dist/identity/managedClient.d.ts +90 -0
  155. package/dist/identity/managedClient.js +10 -0
  156. package/dist/identity/managedClientAuthLink.d.ts +3 -0
  157. package/dist/identity/managedClientAuthLink.js +115 -0
  158. package/dist/identity/managedCustomerMe.d.ts +13 -0
  159. package/dist/identity/managedCustomerMe.js +30 -0
  160. package/dist/identity/managedEmailTrustPolicy.d.ts +11 -0
  161. package/dist/identity/managedEmailTrustPolicy.js +105 -0
  162. package/dist/identity/managedIdentityVerifier.d.ts +2 -0
  163. package/dist/identity/managedIdentityVerifier.js +16 -0
  164. package/dist/identity/managedPrivacy.d.ts +4 -0
  165. package/dist/identity/managedPrivacy.js +39 -0
  166. package/dist/identity/messages.d.ts +29 -0
  167. package/dist/identity/messages.js +39 -0
  168. package/dist/identity/oidcIdentityVerifier.d.ts +45 -0
  169. package/dist/identity/oidcIdentityVerifier.js +309 -0
  170. package/dist/identity/oidcPrincipal.d.ts +2 -0
  171. package/dist/identity/oidcPrincipal.js +10 -0
  172. package/dist/identity/operatorAdminAuth.d.ts +6 -0
  173. package/dist/identity/operatorAdminAuth.js +13 -0
  174. package/dist/identity/operatorAuthHandlers.d.ts +18 -0
  175. package/dist/identity/operatorAuthHandlers.js +71 -0
  176. package/dist/identity/operatorIdentityVerifier.d.ts +8 -0
  177. package/dist/identity/operatorIdentityVerifier.js +19 -0
  178. package/dist/identity/operatorInvitationLifecycle.d.ts +7 -0
  179. package/dist/identity/operatorInvitationLifecycle.js +15 -0
  180. package/dist/identity/operatorInvitationPorts.d.ts +31 -0
  181. package/dist/identity/operatorInvitationPorts.js +1 -0
  182. package/dist/identity/operatorPorts.d.ts +37 -0
  183. package/dist/identity/operatorPorts.js +1 -0
  184. package/dist/identity/operatorSession.d.ts +13 -0
  185. package/dist/identity/operatorSession.js +31 -0
  186. package/dist/identity/operatorTokenAdminAuth.d.ts +15 -0
  187. package/dist/identity/operatorTokenAdminAuth.js +50 -0
  188. package/dist/identity/personalDataRegistry.d.ts +4 -0
  189. package/dist/identity/personalDataRegistry.js +11 -0
  190. package/dist/identity/platformAdminAuth.d.ts +15 -0
  191. package/dist/identity/platformAdminAuth.js +1 -0
  192. package/dist/identity/ports.d.ts +127 -0
  193. package/dist/identity/ports.js +38 -0
  194. package/dist/identity/postgresAccountLinkStore.d.ts +7 -0
  195. package/dist/identity/postgresAccountLinkStore.js +52 -0
  196. package/dist/identity/postgresCustomerMe.d.ts +3 -0
  197. package/dist/identity/postgresCustomerMe.js +21 -0
  198. package/dist/identity/postgresCustomerRecovery.d.ts +11 -0
  199. package/dist/identity/postgresCustomerRecovery.js +57 -0
  200. package/dist/identity/postgresOperatorIdentity.d.ts +5 -0
  201. package/dist/identity/postgresOperatorIdentity.js +137 -0
  202. package/dist/identity/postgresPrivacy.d.ts +7 -0
  203. package/dist/identity/postgresPrivacy.js +126 -0
  204. package/dist/identity/privacyHandlers.d.ts +10 -0
  205. package/dist/identity/privacyHandlers.js +35 -0
  206. package/dist/identity/privacyPorts.d.ts +72 -0
  207. package/dist/identity/privacyPorts.js +8 -0
  208. package/dist/identity/privacyUseCases.d.ts +5 -0
  209. package/dist/identity/privacyUseCases.js +55 -0
  210. package/dist/identity/reconcileAccountForPrincipal.d.ts +20 -0
  211. package/dist/identity/reconcileAccountForPrincipal.js +66 -0
  212. package/dist/identity/reconcileAccountHandler.d.ts +11 -0
  213. package/dist/identity/reconcileAccountHandler.js +30 -0
  214. package/dist/identity/removeAdminUserUseCase.d.ts +31 -0
  215. package/dist/identity/removeAdminUserUseCase.js +60 -0
  216. package/dist/identity/response.d.ts +3 -0
  217. package/dist/identity/response.js +2 -0
  218. package/dist/identity/sql.d.ts +44 -0
  219. package/dist/identity/sql.js +10 -0
  220. package/dist/job-ledger/index.d.ts +5 -0
  221. package/dist/job-ledger/index.js +3 -0
  222. package/dist/job-ledger/ports.d.ts +10 -0
  223. package/dist/job-ledger/ports.js +7 -0
  224. package/dist/job-ledger/postgres.d.ts +10 -0
  225. package/dist/job-ledger/postgres.js +101 -0
  226. package/dist/job-ledger/sql.d.ts +7 -0
  227. package/dist/job-ledger/sql.js +10 -0
  228. package/dist/job-ledger/supabase.d.ts +77 -0
  229. package/dist/job-ledger/supabase.js +202 -0
  230. package/dist/kernel/index.d.ts +1 -0
  231. package/dist/kernel/index.js +1 -0
  232. package/dist/kernel/platformKernel.d.ts +34 -0
  233. package/dist/kernel/platformKernel.js +115 -0
  234. package/dist/migrations/index.d.ts +1 -0
  235. package/dist/migrations/index.js +1 -0
  236. package/dist/migrations/postgresRunner.d.ts +50 -0
  237. package/dist/migrations/postgresRunner.js +176 -0
  238. package/dist/scheduler/advisoryLock.d.ts +44 -0
  239. package/dist/scheduler/advisoryLock.js +114 -0
  240. package/dist/scheduler/cronGuard.d.ts +10 -0
  241. package/dist/scheduler/cronGuard.js +19 -0
  242. package/dist/scheduler/cronSecret.d.ts +5 -0
  243. package/dist/scheduler/cronSecret.js +23 -0
  244. package/dist/scheduler/handlers.d.ts +9 -0
  245. package/dist/scheduler/handlers.js +10 -0
  246. package/dist/scheduler/httpEntry.d.ts +16 -0
  247. package/dist/scheduler/httpEntry.js +31 -0
  248. package/dist/scheduler/index.d.ts +9 -0
  249. package/dist/scheduler/index.js +9 -0
  250. package/dist/scheduler/jobRegistry.d.ts +21 -0
  251. package/dist/scheduler/jobRegistry.js +39 -0
  252. package/dist/scheduler/jobs.d.ts +48 -0
  253. package/dist/scheduler/jobs.js +92 -0
  254. package/dist/scheduler/nodeScheduler.d.ts +42 -0
  255. package/dist/scheduler/nodeScheduler.js +73 -0
  256. package/dist/scheduler/vercelScheduler.d.ts +29 -0
  257. package/dist/scheduler/vercelScheduler.js +51 -0
  258. package/package.json +116 -3
  259. package/release-gates.json +143 -0
  260. package/sql/20260809150000_job_run_ledger.sql +301 -0
  261. package/sql/20260809150001_job_run_ledger_v3.sql +70 -0
  262. package/sql/20260810180001_self_host_actor_auth.sql +40 -0
  263. package/sql/20260810204057_customer_identity_read.sql +31 -0
  264. package/sql/20260814090000_customer_selfservice_recovery.sql +477 -0
  265. package/sql/20260901143000_admin_membership_authority_foundation.sql +234 -0
  266. package/sql/20261018120000_identity_operator_invitations.sql +42 -0
  267. package/sql/20261018180000_identity_operator_challenges.sql +56 -0
  268. package/sql/20261018190000_identity_privacy_erasures.sql +15 -0
  269. package/src/bff/dispatch.ts +81 -0
  270. package/src/bff/envelope.ts +142 -0
  271. package/src/bff/health.ts +37 -0
  272. package/src/bff/index.ts +30 -0
  273. package/src/bff/lazyRoute.ts +28 -0
  274. package/src/bff/requestContext.ts +48 -0
  275. package/src/bff/routerRewrite.ts +38 -0
  276. package/src/blob/binding.ts +55 -0
  277. package/src/blob/filesystem.ts +86 -0
  278. package/src/blob/index.ts +17 -0
  279. package/src/blob/s3.ts +87 -0
  280. package/src/blob/s3Client.ts +91 -0
  281. package/src/blob/supabase.ts +88 -0
  282. package/src/blob/vercel.ts +127 -0
  283. package/src/composition/composeBundle.ts +109 -0
  284. package/src/composition/httpBinding.ts +30 -0
  285. package/src/composition/index.ts +17 -0
  286. package/src/composition/nodeHost.ts +289 -0
  287. package/src/data/binding.ts +157 -0
  288. package/src/data/index.ts +33 -0
  289. package/src/data/postgresGateway.ts +186 -0
  290. package/src/data/queryBuilder.ts +300 -0
  291. package/src/data/queryBuilderSql.ts +183 -0
  292. package/src/data/supabaseClientFactory.ts +92 -0
  293. package/src/data/supabaseGateway.ts +76 -0
  294. package/src/http/deadline.ts +117 -0
  295. package/src/http/index.ts +36 -0
  296. package/src/http/requestAdapter.ts +215 -0
  297. package/src/http/runtime.ts +319 -0
  298. package/src/http/security.ts +155 -0
  299. package/src/http/staticAssets.ts +42 -0
  300. package/src/http/types.ts +31 -0
  301. package/src/identity/adminAuthBinding.ts +76 -0
  302. package/src/identity/adminAuthorization.ts +106 -0
  303. package/src/identity/adminContracts.ts +52 -0
  304. package/src/identity/adminMagicLinkHandler.ts +132 -0
  305. package/src/identity/adminMeHandler.ts +64 -0
  306. package/src/identity/adminPreflight.ts +46 -0
  307. package/src/identity/adminUserActionPorts.ts +78 -0
  308. package/src/identity/adminUserHandlers.ts +174 -0
  309. package/src/identity/authVerifyUrl.ts +56 -0
  310. package/src/identity/contracts/contracts.ts +15 -0
  311. package/src/identity/contracts/emailTrust.ts +5 -0
  312. package/src/identity/contracts/index.ts +8 -0
  313. package/src/identity/contracts/oidc.ts +10 -0
  314. package/src/identity/contracts/operatorAuth.ts +61 -0
  315. package/src/identity/contracts/operatorInvitations.ts +32 -0
  316. package/src/identity/contracts/ports.ts +25 -0
  317. package/src/identity/contracts/privacy.ts +86 -0
  318. package/src/identity/contracts/providerList.ts +13 -0
  319. package/src/identity/contracts/types.ts +25 -0
  320. package/src/identity/contribution.ts +29 -0
  321. package/src/identity/customerAuth.ts +3 -0
  322. package/src/identity/customerAuthorization.ts +38 -0
  323. package/src/identity/customerContracts.ts +52 -0
  324. package/src/identity/customerIdentityBinding.ts +125 -0
  325. package/src/identity/customerIdentityVerifier.ts +141 -0
  326. package/src/identity/customerMagicLinkHandler.ts +171 -0
  327. package/src/identity/customerMeHandler.ts +64 -0
  328. package/src/identity/customerPorts.ts +2 -0
  329. package/src/identity/customerSessionBinding.ts +114 -0
  330. package/src/identity/customerSessionIssuer.ts +71 -0
  331. package/src/identity/customerVerifyOtpHandler.ts +44 -0
  332. package/src/identity/directOperatorInvitationStore.ts +178 -0
  333. package/src/identity/emailTrustPolicy.ts +16 -0
  334. package/src/identity/identityPersonalDataContributor.ts +48 -0
  335. package/src/identity/identityReadiness.ts +26 -0
  336. package/src/identity/index.ts +69 -0
  337. package/src/identity/inviteAdminUserUseCase.ts +134 -0
  338. package/src/identity/jwtLibrary.ts +24 -0
  339. package/src/identity/machineActorWriteFence.ts +19 -0
  340. package/src/identity/magicLinkPorts.ts +7 -0
  341. package/src/identity/managedAccountLinkStore.ts +105 -0
  342. package/src/identity/managedAdminAuthVerifier.ts +40 -0
  343. package/src/identity/managedAdminUserGateways.ts +164 -0
  344. package/src/identity/managedClient.ts +58 -0
  345. package/src/identity/managedClientAuthLink.ts +120 -0
  346. package/src/identity/managedCustomerMe.ts +52 -0
  347. package/src/identity/managedEmailTrustPolicy.ts +90 -0
  348. package/src/identity/managedIdentityVerifier.ts +20 -0
  349. package/src/identity/managedPrivacy.ts +37 -0
  350. package/src/identity/messages.ts +41 -0
  351. package/src/identity/oidcIdentityVerifier.ts +229 -0
  352. package/src/identity/oidcPrincipal.ts +10 -0
  353. package/src/identity/operatorAdminAuth.ts +14 -0
  354. package/src/identity/operatorAuthHandlers.ts +52 -0
  355. package/src/identity/operatorIdentityVerifier.ts +19 -0
  356. package/src/identity/operatorInvitationLifecycle.ts +14 -0
  357. package/src/identity/operatorInvitationPorts.ts +11 -0
  358. package/src/identity/operatorPorts.ts +11 -0
  359. package/src/identity/operatorSession.ts +30 -0
  360. package/src/identity/operatorTokenAdminAuth.ts +79 -0
  361. package/src/identity/personalDataRegistry.ts +8 -0
  362. package/src/identity/platformAdminAuth.ts +7 -0
  363. package/src/identity/ports.ts +158 -0
  364. package/src/identity/postgresAccountLinkStore.ts +49 -0
  365. package/src/identity/postgresCustomerMe.ts +33 -0
  366. package/src/identity/postgresCustomerRecovery.ts +72 -0
  367. package/src/identity/postgresOperatorIdentity.ts +123 -0
  368. package/src/identity/postgresPrivacy.ts +117 -0
  369. package/src/identity/privacyHandlers.ts +33 -0
  370. package/src/identity/privacyPorts.ts +52 -0
  371. package/src/identity/privacyUseCases.ts +48 -0
  372. package/src/identity/reconcileAccountForPrincipal.ts +99 -0
  373. package/src/identity/reconcileAccountHandler.ts +36 -0
  374. package/src/identity/removeAdminUserUseCase.ts +85 -0
  375. package/src/identity/response.ts +3 -0
  376. package/src/identity/sql.ts +10 -0
  377. package/src/job-ledger/index.ts +25 -0
  378. package/src/job-ledger/ports.ts +27 -0
  379. package/src/job-ledger/postgres.ts +121 -0
  380. package/src/job-ledger/sql.ts +12 -0
  381. package/src/job-ledger/supabase.ts +294 -0
  382. package/src/kernel/index.ts +17 -0
  383. package/src/kernel/platformKernel.ts +153 -0
  384. package/src/migrations/index.ts +10 -0
  385. package/src/migrations/postgresRunner.ts +255 -0
  386. package/src/scheduler/advisoryLock.ts +145 -0
  387. package/src/scheduler/cronGuard.ts +30 -0
  388. package/src/scheduler/cronSecret.ts +26 -0
  389. package/src/scheduler/handlers.ts +24 -0
  390. package/src/scheduler/httpEntry.ts +49 -0
  391. package/src/scheduler/index.ts +47 -0
  392. package/src/scheduler/jobRegistry.ts +57 -0
  393. package/src/scheduler/jobs.ts +119 -0
  394. package/src/scheduler/nodeScheduler.ts +123 -0
  395. package/src/scheduler/vercelScheduler.ts +71 -0
@@ -0,0 +1,145 @@
1
+ // Vanilla-Postgres query-builder SQL primitives.
2
+ //
3
+ // Extracted from queryBuilder.ts (300-LOC cap) — the pure, stateless SQL-fragment layer the builder
4
+ // composes: result/error shapes, the injection-safety chokepoint (ParamAccumulator), identifier
5
+ // quoting (allowlist), column projection, and filter rendering. VALUES ARE NEVER string-interpolated;
6
+ // they flow through ParamAccumulator as $N placeholders. Identifiers (table/column names) are validated
7
+ // against a strict allowlist regex and double-quoted, so they cannot smuggle SQL either.
8
+ // Identifiers (table + column names) are NEVER parameterizable in SQL, so they are validated against
9
+ // a strict allowlist and quoted. Consumers only ever pass static, code-literal identifiers; this
10
+ // guard turns any attempt to pass a crafted identifier into a thrown error rather than injected SQL.
11
+ const IDENTIFIER_RE = /^[a-z_][a-z0-9_]*$/i;
12
+ export function quoteIdent(raw) {
13
+ if (!IDENTIFIER_RE.test(raw)) {
14
+ throw new Error(`pg-shim: unsafe identifier ${JSON.stringify(raw)}`);
15
+ }
16
+ return `"${raw}"`;
17
+ }
18
+ // `select("a, b")` etc. — a comma list of identifiers or "*". Each segment is validated; "*" passes
19
+ // through. PostgREST embedding syntax (foo(bar)) is NOT used by any consumer, so it is rejected
20
+ // (fail-closed) rather than silently mistranslated.
21
+ export function renderColumns(columns) {
22
+ const trimmed = columns.trim();
23
+ if (trimmed === "" || trimmed === "*")
24
+ return "*";
25
+ return trimmed
26
+ .split(",")
27
+ .map((c) => c.trim())
28
+ .map((c) => (c === "*" ? "*" : quoteIdent(c)))
29
+ .join(", ");
30
+ }
31
+ export function renderFilter(filter, params) {
32
+ const col = quoteIdent(filter.column);
33
+ switch (filter.kind) {
34
+ case "eq":
35
+ return `${col} = ${params.add(filter.value)}`;
36
+ case "gt":
37
+ return `${col} > ${params.add(filter.value)}`;
38
+ case "gte":
39
+ return `${col} >= ${params.add(filter.value)}`;
40
+ case "lte":
41
+ return `${col} <= ${params.add(filter.value)}`;
42
+ case "ilike":
43
+ return `${col} ILIKE ${params.add(filter.value)}`;
44
+ case "in": {
45
+ // Empty IN () is invalid SQL; PostgREST treats `.in([])` as matching nothing.
46
+ if (filter.values.length === 0)
47
+ return "false";
48
+ const placeholders = filter.values.map((v) => params.add(v)).join(", ");
49
+ return `${col} IN (${placeholders})`;
50
+ }
51
+ case "is":
52
+ // .is(col, null) → IS NULL; .is(col, true/false) → IS TRUE/FALSE. Value is a literal keyword,
53
+ // not user data (consumers only pass null/true/false), so it is rendered, not parameterized.
54
+ if (filter.value === null)
55
+ return `${col} IS NULL`;
56
+ if (filter.value === true)
57
+ return `${col} IS TRUE`;
58
+ if (filter.value === false)
59
+ return `${col} IS FALSE`;
60
+ throw new Error("pg-shim: .is() only supports null/true/false");
61
+ }
62
+ }
63
+ /**
64
+ * PostgREST `count=exact` rendered as a SEPARATE aggregate over the same FROM/WHERE — deliberately
65
+ * NOT a `COUNT(*) OVER()` folded into the row query. PostgREST's exact count ignores limit/offset,
66
+ * and a window function emits no row at all for an empty page, so an offset past the end would
67
+ * report 0 instead of the true total. Keeping it separate also leaves the row projection
68
+ * byte-identical: there is no synthetic column to strip before cardinality shaping.
69
+ */
70
+ export function renderCountQuery(table, filters, params) {
71
+ const where = filters.length === 0
72
+ ? ""
73
+ : `WHERE ${filters.map((filter) => renderFilter(filter, params)).join(" AND ")}`;
74
+ return joinParts([`SELECT count(*) AS exact_count FROM ${quoteIdent(table)}`, where]);
75
+ }
76
+ /**
77
+ * PostgREST refuses an out-of-bounds page instead of answering an empty one -- but ONLY when it
78
+ * knows the total, i.e. when an exact count was requested; without one it answers 200 and `[]`,
79
+ * which is what this shim already did. The boundary is strict: offset === total is a legal empty
80
+ * page, offset === total + 1 is not. Measured against PostgREST 14.10 before this was written,
81
+ * including the `details` sentence, which carries the two numbers a caller pages on.
82
+ */
83
+ export function rangeNotSatisfiable(offset, total) {
84
+ if (offset === null || total === null || offset <= total)
85
+ return null;
86
+ return {
87
+ code: "PGRST103",
88
+ message: "Requested range not satisfiable",
89
+ details: `An offset of ${offset} was requested, but there are only ${total} rows.`,
90
+ };
91
+ }
92
+ /**
93
+ * INSERT ... VALUES ... RETURNING, with the column list taken from the FIRST row and every later
94
+ * row required to carry the same key set. Deriving the columns from row 0 alone and binding the
95
+ * rest positionally is how a batch used to lose a column silently: an extra key vanished, a missing
96
+ * one bound NULL over a DEFAULT. PostgREST answers PGRST102 "All object keys must match" to exactly
97
+ * this payload -- and keeps answering it under `Prefer: missing=default`, measured -- so the shim
98
+ * refuses too. Refusal, not union: parity is the point, and this builder exposes no Prefer header
99
+ * through which a caller could ask for anything else.
100
+ */
101
+ export function renderInsertStatement(table, rows, projection, params) {
102
+ if (rows.length === 0)
103
+ throw new Error("pg-shim: insert requires at least one row");
104
+ const columns = Object.keys(rows[0]);
105
+ const signature = [...columns].sort().join("\u0000");
106
+ for (const row of rows) {
107
+ if ([...Object.keys(row)].sort().join("\u0000") !== signature) {
108
+ throw Object.assign(new Error("All object keys must match"), { code: "PGRST102" });
109
+ }
110
+ }
111
+ const tuples = rows.map((row) => `(${columns.map((column) => params.add(row[column])).join(", ")})`).join(", ");
112
+ return `INSERT INTO ${quoteIdent(table)} (${columns.map(quoteIdent).join(", ")}) VALUES ${tuples} `
113
+ + `RETURNING ${renderColumns(projection)}`;
114
+ }
115
+ // supabase-js rpc() returns the function's return value directly: a scalar/json function yields that
116
+ // value; a TABLE/SETOF function yields the row array. Heuristic mirrors that: 1 row × 1 column whose
117
+ // name equals the function → the scalar; otherwise the rows array (TABLE-returning).
118
+ export function unwrapRpcRows(rows, functionName) {
119
+ if (rows.length === 1) {
120
+ const keys = Object.keys(rows[0]);
121
+ if (keys.length === 1 && keys[0] === functionName)
122
+ return rows[0][functionName];
123
+ }
124
+ return rows;
125
+ }
126
+ /** Accumulates values and hands back $1,$2,… placeholders — the single injection-safety chokepoint. */
127
+ export class ParamAccumulator {
128
+ values = [];
129
+ add(value) {
130
+ this.values.push(value);
131
+ return `$${this.values.length}`;
132
+ }
133
+ }
134
+ export function joinParts(parts) {
135
+ return parts.filter((p) => p.trim() !== "").join(" ");
136
+ }
137
+ export function toShimError(error) {
138
+ const e = error;
139
+ return {
140
+ code: e?.code,
141
+ message: e?.message ?? "query failed",
142
+ details: e?.detail,
143
+ hint: e?.hint,
144
+ };
145
+ }
@@ -0,0 +1,34 @@
1
+ /** Structural shape of the supabase-js `createClient` we depend on (injection seam for tests). */
2
+ export type SupabaseCreateClient = (url: string, key: string, options?: {
3
+ auth?: {
4
+ persistSession?: boolean;
5
+ autoRefreshToken?: boolean;
6
+ };
7
+ global?: {
8
+ headers?: Record<string, string>;
9
+ };
10
+ }) => unknown;
11
+ export interface SupabaseDataGatewayEnv {
12
+ /** Project URL (SUPABASE_URL / VITE_SUPABASE_URL). */
13
+ url: string;
14
+ /** Anon/publishable key — used for actor (RLS-bound) clients. */
15
+ anonKey: string;
16
+ /** Service-role key — used for elevated (RLS-bypassing) clients. */
17
+ serviceRoleKey: string;
18
+ }
19
+ /** Read the gateway env using the same precedence the inline sites use today. */
20
+ export declare function readSupabaseDataGatewayEnv(env: Record<string, string | undefined>): SupabaseDataGatewayEnv | null;
21
+ /** Read env for actor-only gateway consumers. Does not require the elevated service-role key. */
22
+ export declare function readSupabaseActorDataGatewayEnv(env: Record<string, string | undefined>): SupabaseDataGatewayEnv | null;
23
+ /**
24
+ * Build an elevated (service-role) supabase client — byte-identical to the inline
25
+ * `createClient(env.url, env.serviceRoleKey, { auth: { persistSession: false, autoRefreshToken: false } })`
26
+ * shape the BFF handlers use today.
27
+ */
28
+ export declare function createServiceClient(env: SupabaseDataGatewayEnv, factory: SupabaseCreateClient): unknown;
29
+ /**
30
+ * Build an actor (RLS-bound) supabase client — anon key + the actor's Bearer access token, matching
31
+ * the inline `createAdminAuthClient` / `createCustomerClient` shape. When no token is supplied the
32
+ * global Authorization header is omitted (identical to the inline `accessToken ? {...} : {}`).
33
+ */
34
+ export declare function createActorClient(env: SupabaseDataGatewayEnv, accessToken: string | null, factory: SupabaseCreateClient): unknown;
@@ -0,0 +1,56 @@
1
+ // Supabase client factory for the DataGatewayPort.
2
+ //
3
+ // ONE canonical definition of the two supabase-js client shapes BFF handlers need:
4
+ // - SERVICE-ROLE client (elevated, RLS-bypassing) — `createClient(url, serviceRoleKey, {auth:{...}})`
5
+ // - ACTOR client (RLS-bound via a Bearer access token) — anon key + `Authorization: Bearer <jwt>`
6
+ // Both use one exact option shape
7
+ // (`auth: { persistSession: false, autoRefreshToken: false }`, plus the actor's global Authorization
8
+ // header). The supabase-js `createClient`
9
+ // is always supplied by the application's composition root, so this package carries no SDK import
10
+ // and the adapter stays unit-testable without network.
11
+ /** Read the gateway env using the same precedence the inline sites use today. */
12
+ export function readSupabaseDataGatewayEnv(env) {
13
+ const url = env.SUPABASE_URL ?? env.VITE_SUPABASE_URL;
14
+ const anonKey = env.VITE_SUPABASE_PUBLISHABLE_KEY ??
15
+ env.VITE_SUPABASE_ANON_KEY ??
16
+ env.SUPABASE_ANON_KEY;
17
+ const serviceRoleKey = env.SUPABASE_SERVICE_ROLE_KEY;
18
+ // anonKey is only needed for actor clients; service-role work needs only url + serviceRoleKey.
19
+ // We require url + serviceRoleKey (the elevated path the default bundle uses); anonKey may be
20
+ // empty for service-only deployments and is validated lazily when an actor client is requested.
21
+ return url && serviceRoleKey ? { url, anonKey: anonKey ?? "", serviceRoleKey } : null;
22
+ }
23
+ /** Read env for actor-only gateway consumers. Does not require the elevated service-role key. */
24
+ export function readSupabaseActorDataGatewayEnv(env) {
25
+ const url = env.SUPABASE_URL ?? env.VITE_SUPABASE_URL;
26
+ const anonKey = env.VITE_SUPABASE_PUBLISHABLE_KEY ??
27
+ env.VITE_SUPABASE_ANON_KEY ??
28
+ env.SUPABASE_ANON_KEY;
29
+ return url && anonKey ? { url, anonKey, serviceRoleKey: env.SUPABASE_SERVICE_ROLE_KEY ?? "" } : null;
30
+ }
31
+ /**
32
+ * Build an elevated (service-role) supabase client — byte-identical to the inline
33
+ * `createClient(env.url, env.serviceRoleKey, { auth: { persistSession: false, autoRefreshToken: false } })`
34
+ * shape the BFF handlers use today.
35
+ */
36
+ export function createServiceClient(env, factory) {
37
+ return factory(env.url, env.serviceRoleKey, {
38
+ auth: { persistSession: false, autoRefreshToken: false },
39
+ });
40
+ }
41
+ /**
42
+ * Build an actor (RLS-bound) supabase client — anon key + the actor's Bearer access token, matching
43
+ * the inline `createAdminAuthClient` / `createCustomerClient` shape. When no token is supplied the
44
+ * global Authorization header is omitted (identical to the inline `accessToken ? {...} : {}`).
45
+ */
46
+ export function createActorClient(env, accessToken, factory) {
47
+ if (!env.anonKey) {
48
+ throw new Error("supabase_data_gateway_actor_requires_anon_key");
49
+ }
50
+ return factory(env.url, env.anonKey, {
51
+ auth: { persistSession: false, autoRefreshToken: false },
52
+ global: {
53
+ headers: accessToken ? { Authorization: `Bearer ${accessToken}` } : {},
54
+ },
55
+ });
56
+ }
@@ -0,0 +1,22 @@
1
+ import type { DataGatewayPort } from "@openlup/core/platform-runtime";
2
+ import { type SupabaseCreateClient, type SupabaseDataGatewayEnv } from "./supabaseClientFactory.js";
3
+ type ActorClaims = {
4
+ sub?: string;
5
+ role?: string;
6
+ } | null;
7
+ export interface SupabaseDataGatewayOptions {
8
+ /** The supabase-js `createClient` (tests pass a stub). */
9
+ createClientImpl: SupabaseCreateClient;
10
+ /**
11
+ * Resolve an actor's Bearer access token from their claims. The port contract carries only
12
+ * `{ sub, role }`, but RLS needs the raw JWT; call sites that have the request token bind it here.
13
+ * Returns null → anon (RLS-bound but unauthenticated) client.
14
+ */
15
+ resolveAccessToken?: (claims: ActorClaims) => string | null;
16
+ }
17
+ /**
18
+ * Build a supabase-backed DataGatewayPort from resolved env. Pure: no client is created until a
19
+ * port method runs work (matches the per-request creation the inline sites do today).
20
+ */
21
+ export declare function createSupabaseDataGateway(env: SupabaseDataGatewayEnv, options: SupabaseDataGatewayOptions): DataGatewayPort;
22
+ export {};
@@ -0,0 +1,49 @@
1
+ // Supabase adapter for the platform-runtime DataGatewayPort.
2
+ //
3
+ // Centralizes the two persistence access modes the BFF handlers build inline today:
4
+ // - asService(work): elevated, RLS-bypassing — a service-role client (the default bundle's path).
5
+ // - asActor(claims, work): RLS-bound — an anon client carrying the actor's Bearer access token, so
6
+ // RLS evaluates the request as that principal (UUID-keep: claims.sub IS the supabase auth uuid).
7
+ // The work callback receives the concrete supabase client (typed `unknown` per the port contract;
8
+ // consumers cast to their narrow read/write surface). Behavior is byte-identical to the inline
9
+ // `createClient(...)` sites this replaces — same option shape, same Authorization header — so the
10
+ // default vercel-supabase bundle stays unchanged (golden-master byte-identical).
11
+ //
12
+ // POOLING SEMANTICS (documented, no behavior change):
13
+ // - Serverless (vercel-supabase): each invocation is short-lived; supabase-js talks to PostgREST
14
+ // over HTTP (PgBouncer in transaction-mode behind the scenes), so there is no long-lived pool to
15
+ // manage — a fresh client per asActor/asService call matches the current per-request creation and
16
+ // is correct for transaction-pooled connections (no session-level state assumed).
17
+ // - Long-running Node (node-supabase): the same supabase-js HTTP path applies; a direct-PG gateway
18
+ // (node-postgres) would instead hold a standard `pg.Pool` and run asActor work inside a
19
+ // `BEGIN; SET LOCAL request.jwt.claims = ...; ... COMMIT` tx-per-request for RLS. That is the
20
+ // MigrationRunner/postgres band's concern; this supabase adapter stays HTTP-pooled either way.
21
+ //
22
+ // asActor honors the access token supplied via `options.resolveAccessToken(claims)` (defaults to the
23
+ // claims' own bearer if present) so RLS is enforced; when no token resolves it falls back to an anon
24
+ // client (RLS still applies, just unauthenticated) rather than silently elevating — fail-safe.
25
+ import { createActorClient, createServiceClient, } from "./supabaseClientFactory.js";
26
+ /**
27
+ * Build a supabase-backed DataGatewayPort from resolved env. Pure: no client is created until a
28
+ * port method runs work (matches the per-request creation the inline sites do today).
29
+ */
30
+ export function createSupabaseDataGateway(env, options) {
31
+ const resolveAccessToken = options.resolveAccessToken ?? defaultResolveAccessToken;
32
+ return {
33
+ async asService(work) {
34
+ const client = createServiceClient(env, options.createClientImpl);
35
+ return work(client);
36
+ },
37
+ async asActor(claims, work) {
38
+ const accessToken = resolveAccessToken(claims);
39
+ const client = createActorClient(env, accessToken, options.createClientImpl);
40
+ return work(client);
41
+ },
42
+ };
43
+ }
44
+ // Default token resolver: the port's claims shape doesn't carry a raw JWT, so without an injected
45
+ // resolver an actor request maps to an anon (unauthenticated, still RLS-bound) client. Call sites
46
+ // that hold the request bearer inject `resolveAccessToken` to make RLS see the real principal.
47
+ function defaultResolveAccessToken(_claims) {
48
+ return null;
49
+ }
@@ -0,0 +1,20 @@
1
+ import type { HttpRequest, HttpResponse } from "./types.js";
2
+ export declare const NODE_HTTP_TIMEOUT_CODE = "NODE_HTTP_TIMEOUT";
3
+ export interface HttpDeadlineOptions {
4
+ req: HttpRequest;
5
+ res: HttpResponse;
6
+ durationMs: number;
7
+ run: () => Promise<unknown> | unknown;
8
+ onLateError?: (error: unknown) => void;
9
+ }
10
+ /**
11
+ * Run one Node HTTP admission from the instant before lazy loading/adaptation.
12
+ *
13
+ * A timeout before headers commit gets one minimal JSON 504. After headers are
14
+ * committed we cannot change the status safely, so the response is destroyed.
15
+ * The invocation promise remains observed, preventing a late rejection from
16
+ * becoming an unhandled rejection or a second response.
17
+ */
18
+ export declare function runWithHttpDeadline(options: HttpDeadlineOptions): Promise<void>;
19
+ /** Send a response before closing its request input, so the status is deliverable. */
20
+ export declare function closeInputAfterResponse(req: HttpRequest, res: HttpResponse): void;
@@ -0,0 +1,93 @@
1
+ // Bounded request/response lifecycle for the Node HTTP adapter.
2
+ //
3
+ // This owns transport cancellation only. It gives handlers a cooperative
4
+ // AbortSignal, but cannot roll back downstream work that ignores it.
5
+ export const NODE_HTTP_TIMEOUT_CODE = "NODE_HTTP_TIMEOUT";
6
+ /**
7
+ * Run one Node HTTP admission from the instant before lazy loading/adaptation.
8
+ *
9
+ * A timeout before headers commit gets one minimal JSON 504. After headers are
10
+ * committed we cannot change the status safely, so the response is destroyed.
11
+ * The invocation promise remains observed, preventing a late rejection from
12
+ * becoming an unhandled rejection or a second response.
13
+ */
14
+ export async function runWithHttpDeadline(options) {
15
+ const { req, res, durationMs, run, onLateError } = options;
16
+ if (!Number.isSafeInteger(durationMs) || durationMs <= 0 || durationMs > 2_147_483_647) {
17
+ throw new Error("invalid_node_http_deadline");
18
+ }
19
+ const controller = new AbortController();
20
+ // Node 24 exposes IncomingMessage.signal as a getter without a setter. Keep
21
+ // that host-native property untouched and use the portable adapter seam.
22
+ req.abortSignal = controller.signal;
23
+ const eventedReq = req;
24
+ const eventedRes = res;
25
+ const abortForClose = () => controller.abort();
26
+ eventedReq.once?.("aborted", abortForClose);
27
+ eventedRes.once?.("close", abortForClose);
28
+ let expired = false;
29
+ let finishTimeout;
30
+ const timeout = new Promise((resolve) => { finishTimeout = resolve; });
31
+ const timer = setTimeout(() => {
32
+ expired = true;
33
+ controller.abort();
34
+ if (res.destroyed || res.writableEnded) {
35
+ destroyInput(req);
36
+ return finishTimeout?.();
37
+ }
38
+ if (!res.headersSent && !res.writableEnded) {
39
+ closeInputAfterResponse(req, res);
40
+ res.statusCode = 504;
41
+ res.setHeader("content-type", "application/json; charset=utf-8");
42
+ res.end(JSON.stringify({ ok: false, error: { code: NODE_HTTP_TIMEOUT_CODE, message: "Request timed out" } }));
43
+ sealLateWrites(res);
44
+ }
45
+ else if (!res.writableEnded) {
46
+ sealLateWrites(res);
47
+ res.destroy?.();
48
+ destroyInput(req);
49
+ }
50
+ finishTimeout?.();
51
+ }, durationMs);
52
+ const invocation = Promise.resolve().then(run);
53
+ // Keep a late completion/rejection observed after timeout. It must never get a
54
+ // chance to write a second envelope, and its raw value is not client output.
55
+ void invocation.catch((error) => {
56
+ if (expired)
57
+ onLateError?.(error);
58
+ });
59
+ try {
60
+ await Promise.race([invocation.then(() => undefined), timeout]);
61
+ }
62
+ finally {
63
+ clearTimeout(timer);
64
+ eventedReq.removeListener?.("aborted", abortForClose);
65
+ eventedRes.removeListener?.("close", abortForClose);
66
+ }
67
+ }
68
+ /** Send a response before closing its request input, so the status is deliverable. */
69
+ export function closeInputAfterResponse(req, res) {
70
+ const evented = res;
71
+ let closed = false;
72
+ const destroy = () => {
73
+ if (closed)
74
+ return;
75
+ closed = true;
76
+ evented.removeListener?.("finish", destroy);
77
+ evented.removeListener?.("close", destroy);
78
+ destroyInput(req);
79
+ };
80
+ evented.once?.("finish", destroy);
81
+ evented.once?.("close", destroy);
82
+ }
83
+ function destroyInput(req) {
84
+ req.destroy?.();
85
+ }
86
+ /** Refuse late handler writes after a deadline response has committed. */
87
+ function sealLateWrites(res) {
88
+ const mutable = res;
89
+ mutable.write = () => false;
90
+ mutable.writeHead = () => mutable;
91
+ mutable.end = () => mutable;
92
+ mutable.setHeader = () => mutable;
93
+ }
@@ -0,0 +1,6 @@
1
+ export type { EntrypointLoader, HttpHandler, HttpRequest, HttpResponse } from "./types.js";
2
+ export { DEFAULT_NODE_BUFFERED_BODY_LIMIT_BYTES, NodeRequestAbortedError, NodeRequestBodyTooLargeError, adaptRequest, decorateRequest, decorateResponse, isRawStreamEntrypoint, isWebhookPath, pathnameOf, } from "./requestAdapter.js";
3
+ export { NODE_HTTP_TIMEOUT_CODE, closeInputAfterResponse, runWithHttpDeadline, type HttpDeadlineOptions, } from "./deadline.js";
4
+ export { applySecurityHeaders, contentTypeFor, looksLikeAsset, serveSpaStatic, type NodeSecurityHeaderPolicy, type StaticAssetReader, } from "./security.js";
5
+ export { createDistStaticReader } from "./staticAssets.js";
6
+ export { createNodeHttpRuntime, createRequestHandler, type HttpEntrypointRegistration, type HttpPathEntrypoint, type NodeCsrFallback, type NodeHttpRuntimeOptions, type NodeLegacyRedirect, } from "./runtime.js";
@@ -0,0 +1,5 @@
1
+ export { DEFAULT_NODE_BUFFERED_BODY_LIMIT_BYTES, NodeRequestAbortedError, NodeRequestBodyTooLargeError, adaptRequest, decorateRequest, decorateResponse, isRawStreamEntrypoint, isWebhookPath, pathnameOf, } from "./requestAdapter.js";
2
+ export { NODE_HTTP_TIMEOUT_CODE, closeInputAfterResponse, runWithHttpDeadline, } from "./deadline.js";
3
+ export { applySecurityHeaders, contentTypeFor, looksLikeAsset, serveSpaStatic, } from "./security.js";
4
+ export { createDistStaticReader } from "./staticAssets.js";
5
+ export { createNodeHttpRuntime, createRequestHandler, } from "./runtime.js";
@@ -0,0 +1,38 @@
1
+ import type { IncomingMessage, ServerResponse } from "node:http";
2
+ import type { HttpRequest, HttpResponse } from "./types.js";
3
+ export declare const DEFAULT_NODE_BUFFERED_BODY_LIMIT_BYTES = 1048576;
4
+ export declare class NodeRequestBodyTooLargeError extends Error {
5
+ constructor();
6
+ }
7
+ export declare class NodeRequestAbortedError extends Error {
8
+ constructor();
9
+ }
10
+ /** A path is a webhook iff it contains a `/webhooks/` segment. */
11
+ export declare function isWebhookPath(pathname: string): boolean;
12
+ /**
13
+ * The PLATFORM's stream-first standalone entrypoints: they read the raw stream
14
+ * themselves, so the runtime must never pre-parse their body.
15
+ *
16
+ * A deployment's own stream-first endpoint is NOT listed here. It declares
17
+ * `rawStream: true` on its `HttpEntrypointRegistration` and the runtime passes that
18
+ * decision to `adaptRequest` directly — which is what stops this publishable list
19
+ * from having to name a path only that deployment owns.
20
+ */
21
+ export declare function isRawStreamEntrypoint(pathname: string): boolean;
22
+ export declare function pathnameOf(req: IncomingMessage): string;
23
+ /**
24
+ * Decorate a Node response with Vercel's status/json/send/redirect sugar (productionized from the
25
+ * dev shim's decorateResponse — identical semantics).
26
+ */
27
+ export declare function decorateResponse(res: ServerResponse): HttpResponse;
28
+ /**
29
+ * Adapt a Node IncomingMessage into the Vercel request shape, honoring the raw-body invariant:
30
+ * - raw-stream entrypoints (process/csp/feedback): stream left intact, NO req.body;
31
+ * - everything else: raw bytes buffered + re-exposed as async-iterable (so readRawBody sees the
32
+ * EXACT bytes for any signature-verifying route, webhook-segment or not) AND req.body = parsed JSON.
33
+ */
34
+ export declare function adaptRequest(req: IncomingMessage, pathname: string,
35
+ /** Explicit override for a caller that knows the entrypoint's body contract (see above). */
36
+ rawStream?: boolean, bufferedBodyLimitBytes?: number): Promise<HttpRequest>;
37
+ /** Narrow a raw IncomingMessage to HttpRequest at the server boundary (query/cookies set in adapt). */
38
+ export declare function decorateRequest(req: IncomingMessage): HttpRequest;