@plitzi/sdk-server 0.37.1 → 0.37.3

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 (386) hide show
  1. package/CHANGELOG.md +1296 -0
  2. package/README.md +126 -7
  3. package/dist/actions.d.ts +20 -8
  4. package/dist/actions.js +11 -4
  5. package/dist/adapters/cloudAdapters.js +4 -3
  6. package/dist/adapters/jsonAdapters.js +28 -6
  7. package/dist/auth.d.ts +7 -4
  8. package/dist/auth.js +8 -6
  9. package/dist/core/auth/api.d.ts +29 -1
  10. package/dist/core/auth/api.js +47 -13
  11. package/dist/core/auth/createAuth.d.ts +4 -0
  12. package/dist/core/auth/createAuth.js +3 -3
  13. package/dist/core/auth/credentials.d.ts +3 -0
  14. package/dist/core/auth/credentials.js +1 -1
  15. package/dist/core/auth/csrf.d.ts +25 -1
  16. package/dist/core/auth/csrf.js +29 -4
  17. package/dist/core/auth/renewal.d.ts +26 -0
  18. package/dist/core/auth/renewal.js +24 -0
  19. package/dist/core/auth/routes.js +8 -6
  20. package/dist/core/auth/session.d.ts +45 -0
  21. package/dist/core/auth/session.js +47 -1
  22. package/dist/core/auth/sessionActivity.d.ts +11 -0
  23. package/dist/core/auth/sessionActivity.js +14 -0
  24. package/dist/core/auth/throttle.d.ts +15 -0
  25. package/dist/core/auth/throttle.js +29 -1
  26. package/dist/core/auth/totp.d.ts +9 -1
  27. package/dist/core/auth/totp.js +11 -6
  28. package/dist/core/createServer.actions.test.d.ts +1 -0
  29. package/dist/core/createServer.d.ts +14 -1
  30. package/dist/core/createServer.functions.test.d.ts +1 -0
  31. package/dist/core/createServer.js +22 -12
  32. package/dist/core/fontStore.js +1 -1
  33. package/dist/core/handlers/authRouteHandlers.d.ts +1 -1
  34. package/dist/core/handlers/authRouteHandlers.js +57 -21
  35. package/dist/core/handlers/csrfMiddleware.d.ts +23 -0
  36. package/dist/core/handlers/csrfMiddleware.js +31 -7
  37. package/dist/core/handlers/csrfMiddleware.test.d.ts +1 -0
  38. package/dist/core/handlers/oauthRouteHandlers.js +5 -3
  39. package/dist/core/handlers/socialRouteHandlers.d.ts +1 -1
  40. package/dist/core/handlers/socialRouteHandlers.js +2 -1
  41. package/dist/core/http/dispatcher.d.ts +9 -1
  42. package/dist/core/http/dispatcher.js +38 -11
  43. package/dist/core/http/navigation.d.ts +5 -2
  44. package/dist/core/http/navigation.js +7 -4
  45. package/dist/core/http/socketResponse.d.ts +18 -0
  46. package/dist/core/http/socketResponse.js +59 -0
  47. package/dist/core/http/sse.d.ts +26 -0
  48. package/dist/core/http/sse.js +78 -0
  49. package/dist/core/http/stages/authRoutes.js +3 -1
  50. package/dist/core/http/stages/exchangeRoute.test.d.ts +1 -0
  51. package/dist/core/http/stages/middlewares.d.ts +1 -1
  52. package/dist/core/http/stages/middlewares.js +16 -10
  53. package/dist/core/http/stages/middlewares.test.d.ts +1 -0
  54. package/dist/core/http/stages/oauth.js +2 -2
  55. package/dist/core/http/stages/sessionRenewal.d.ts +16 -0
  56. package/dist/core/http/stages/sessionRenewal.js +81 -0
  57. package/dist/core/http/stages/sessionRenewal.test.d.ts +1 -0
  58. package/dist/core/http/stages/signInRoute.d.ts +2 -0
  59. package/dist/core/http/stages/signInRoute.js +139 -0
  60. package/dist/core/http/stages/signInRoute.test.d.ts +1 -0
  61. package/dist/core/http/types.d.ts +9 -0
  62. package/dist/core/http/webExchange.d.ts +18 -0
  63. package/dist/core/http/webExchange.js +53 -0
  64. package/dist/core/oauth/authorize.js +37 -13
  65. package/dist/core/oauth/consentPage.js +11 -0
  66. package/dist/core/oauth/issueContext.d.ts +14 -0
  67. package/dist/core/oauth/issueContext.js +32 -0
  68. package/dist/core/oauth/records.d.ts +7 -0
  69. package/dist/core/oauth/register.d.ts +2 -0
  70. package/dist/core/oauth/register.js +32 -11
  71. package/dist/core/oauth/register.test.d.ts +1 -0
  72. package/dist/core/oauth/token.js +21 -6
  73. package/dist/core/oauth/token.test.d.ts +1 -0
  74. package/dist/core/requestParser.d.ts +4 -0
  75. package/dist/core/requestParser.js +14 -7
  76. package/dist/core/sdkAssets.js +1 -1
  77. package/dist/core/server/baseServer.d.ts +14 -1
  78. package/dist/core/server/baseServer.js +43 -11
  79. package/dist/core/server/closeOnSignals.d.ts +28 -0
  80. package/dist/core/server/closeOnSignals.js +47 -0
  81. package/dist/core/server/closeOnSignals.test.d.ts +1 -0
  82. package/dist/core/server/drain.d.ts +18 -0
  83. package/dist/core/server/drain.js +62 -0
  84. package/dist/core/server/drain.test.d.ts +1 -0
  85. package/dist/core/server/fleet/channel.d.ts +103 -0
  86. package/dist/core/server/fleet/channel.js +191 -0
  87. package/dist/core/server/fleet/channel.test.d.ts +1 -0
  88. package/dist/core/server/fleet/fixtures/fleetServer.d.ts +1 -0
  89. package/dist/core/server/fleet/fleet.integration.test.d.ts +1 -0
  90. package/dist/core/server/fleet/link.d.ts +23 -0
  91. package/dist/core/server/fleet/link.js +70 -0
  92. package/dist/core/server/fleet/relay.d.ts +11 -0
  93. package/dist/core/server/fleet/relay.js +104 -0
  94. package/dist/core/server/fleet/relay.test.d.ts +1 -0
  95. package/dist/core/server/fleet/role.d.ts +46 -0
  96. package/dist/core/server/fleet/role.js +59 -0
  97. package/dist/core/server/fleet/role.test.d.ts +1 -0
  98. package/dist/core/server/fleet/stores.d.ts +7 -0
  99. package/dist/core/server/fleet/stores.js +19 -0
  100. package/dist/core/server/fleet/supervisor.d.ts +26 -0
  101. package/dist/core/server/fleet/supervisor.js +108 -0
  102. package/dist/core/server/fleet/supervisor.test.d.ts +1 -0
  103. package/dist/core/server/pageServer.js +36 -5
  104. package/dist/core/services/action.js +10 -2
  105. package/dist/core/services/functionRoutes.d.ts +9 -0
  106. package/dist/core/services/functionRoutes.js +47 -0
  107. package/dist/core/services/realtime.d.ts +8 -0
  108. package/dist/core/services/realtime.js +57 -0
  109. package/dist/core/services/registry.js +6 -2
  110. package/dist/core/staticFiles.js +12 -4
  111. package/dist/core/staticFiles.test.d.ts +1 -0
  112. package/dist/core/transports.d.ts +13 -3
  113. package/dist/core/transports.js +14 -5
  114. package/dist/functions-api.d.ts +281 -0
  115. package/dist/functions.d.ts +19 -0
  116. package/dist/functions.js +5 -0
  117. package/dist/functionsRunner.d.ts +15 -0
  118. package/dist/functionsRunner.js +6 -0
  119. package/dist/handlers.d.ts +2 -2
  120. package/dist/handlers.js +2 -2
  121. package/dist/helpers/atomicFile.d.ts +10 -0
  122. package/dist/helpers/atomicFile.js +33 -0
  123. package/dist/helpers/atomicFile.test.d.ts +1 -0
  124. package/dist/helpers/buildResponseHelpers.js +35 -11
  125. package/dist/helpers/buildServerInfo.js +4 -2
  126. package/dist/helpers/buildServerInfo.test.d.ts +1 -0
  127. package/dist/helpers/cache/CompressedFileCache.d.ts +18 -0
  128. package/dist/helpers/cache/CompressedFileCache.js +44 -0
  129. package/dist/helpers/cache/CompressedFileCache.test.d.ts +1 -0
  130. package/dist/helpers/cache/cacheManager.d.ts +1 -1
  131. package/dist/helpers/cache/cacheManager.js +2 -1
  132. package/dist/helpers/cache/cacheManager.test.d.ts +1 -0
  133. package/dist/helpers/cache/index.d.ts +1 -1
  134. package/dist/helpers/cache/keys.d.ts +15 -1
  135. package/dist/helpers/cache/keys.js +47 -5
  136. package/dist/helpers/cache/serverCaches.d.ts +7 -1
  137. package/dist/helpers/compress.d.ts +3 -1
  138. package/dist/helpers/compress.js +11 -3
  139. package/dist/helpers/hydrationPayload.d.ts +11 -0
  140. package/dist/helpers/hydrationPayload.js +51 -0
  141. package/dist/helpers/hydrationPayload.test.d.ts +1 -0
  142. package/dist/helpers/metrics.d.ts +1 -1
  143. package/dist/helpers/metrics.js +3 -2
  144. package/dist/helpers/outboundGuard.d.ts +14 -6
  145. package/dist/helpers/outboundGuard.js +132 -8
  146. package/dist/helpers/paintedCookie.d.ts +8 -0
  147. package/dist/helpers/paintedCookie.js +13 -0
  148. package/dist/helpers/reportReactBuild.d.ts +9 -0
  149. package/dist/helpers/reportReactBuild.js +18 -0
  150. package/dist/helpers/reportReactBuild.test.d.ts +1 -0
  151. package/dist/helpers/serverLog.d.ts +25 -1
  152. package/dist/helpers/serverLog.js +68 -3
  153. package/dist/helpers/serverLog.test.d.ts +1 -0
  154. package/dist/helpers/wsFrame.d.ts +3 -0
  155. package/dist/helpers/wsFrame.js +5 -0
  156. package/dist/index.d.ts +8 -1
  157. package/dist/index.js +6 -2
  158. package/dist/kernel.d.ts +2 -1
  159. package/dist/kernel.js +3 -2
  160. package/dist/modules/actions/connectorWrite.js +2 -1
  161. package/dist/modules/actions/index.d.ts +41 -13
  162. package/dist/modules/actions/index.js +52 -9
  163. package/dist/modules/actions/jobs/failureStreak.d.ts +17 -0
  164. package/dist/modules/actions/jobs/failureStreak.js +47 -0
  165. package/dist/modules/actions/jobs/failureStreak.test.d.ts +1 -0
  166. package/dist/modules/actions/jobs/index.d.ts +33 -0
  167. package/dist/modules/actions/jobs/index.js +59 -0
  168. package/dist/modules/actions/jobs/memoryQueue.d.ts +33 -0
  169. package/dist/modules/actions/jobs/memoryQueue.js +194 -0
  170. package/dist/modules/actions/jobs/memoryStores.test.d.ts +1 -0
  171. package/dist/modules/actions/jobs/scheduler.d.ts +64 -0
  172. package/dist/modules/actions/jobs/scheduler.js +130 -0
  173. package/dist/modules/actions/jobs/scheduler.test.d.ts +1 -0
  174. package/dist/modules/actions/jobs/schedules.d.ts +23 -0
  175. package/dist/modules/actions/jobs/schedules.js +47 -0
  176. package/dist/modules/actions/jobs/storeClock.d.ts +16 -0
  177. package/dist/modules/actions/jobs/storeClock.js +32 -0
  178. package/dist/modules/actions/jobs/testing/jobQueueContract.d.ts +25 -0
  179. package/dist/modules/actions/jobs/worker.d.ts +64 -0
  180. package/dist/modules/actions/jobs/worker.js +267 -0
  181. package/dist/modules/actions/jobs/worker.test.d.ts +1 -0
  182. package/dist/modules/actions/moduleFor.js +6 -2
  183. package/dist/modules/actions/runtime/errors.d.ts +12 -0
  184. package/dist/modules/actions/runtime/errors.js +16 -1
  185. package/dist/modules/actions/runtime/kvChange.d.ts +27 -0
  186. package/dist/modules/actions/runtime/kvChange.js +23 -0
  187. package/dist/modules/actions/runtime/kvList.d.ts +51 -0
  188. package/dist/modules/actions/runtime/kvList.js +52 -0
  189. package/dist/modules/actions/runtime/kvStore.d.ts +8 -0
  190. package/dist/modules/actions/runtime/kvStore.js +46 -20
  191. package/dist/modules/actions/runtime/memoryKv.d.ts +3 -0
  192. package/dist/modules/actions/runtime/memoryKv.js +19 -1
  193. package/dist/modules/actions/runtime/namespaceKv.d.ts +4 -6
  194. package/dist/modules/actions/runtime/namespaceKv.js +15 -3
  195. package/dist/modules/actions/runtime/namespaceKv.test.d.ts +1 -0
  196. package/dist/modules/actions/runtime/precheck.js +5 -9
  197. package/dist/modules/actions/runtime/rateLimit.d.ts +19 -0
  198. package/dist/modules/actions/runtime/rateLimit.js +19 -0
  199. package/dist/modules/actions/runtime/redisKv.d.ts +27 -0
  200. package/dist/modules/actions/runtime/redisKv.integration.test.d.ts +1 -0
  201. package/dist/modules/actions/runtime/redisKv.js +46 -0
  202. package/dist/modules/actions/runtime/renderResolver.js +2 -2
  203. package/dist/modules/actions/runtime/report.js +2 -1
  204. package/dist/modules/actions/runtime/runAction.d.ts +10 -2
  205. package/dist/modules/actions/runtime/runAction.js +52 -116
  206. package/dist/modules/actions/runtime/runLogger.d.ts +5 -0
  207. package/dist/modules/actions/runtime/runLogger.js +8 -2
  208. package/dist/modules/actions/runtime/signing.d.ts +20 -0
  209. package/dist/modules/actions/runtime/signing.js +25 -0
  210. package/dist/modules/actions/runtime/signing.test.d.ts +1 -0
  211. package/dist/modules/actions/runtime/taskContext.d.ts +33 -0
  212. package/dist/modules/actions/runtime/taskContext.js +124 -0
  213. package/dist/modules/actions/tasks/builtins.js +5 -1
  214. package/dist/modules/actions/tasks/flow.js +81 -10
  215. package/dist/modules/actions/tasks/helpers.js +2 -2
  216. package/dist/modules/actions/tasks/http.js +2 -3
  217. package/dist/modules/actions/tasks/kv.js +39 -0
  218. package/dist/modules/actions/tasks/list.d.ts +2 -0
  219. package/dist/modules/actions/tasks/list.js +145 -0
  220. package/dist/modules/actions/tasks/realtime.d.ts +2 -0
  221. package/dist/modules/actions/tasks/realtime.js +104 -0
  222. package/dist/modules/actions/tasks/registry.d.ts +10 -1
  223. package/dist/modules/actions/tasks/registry.js +17 -6
  224. package/dist/modules/actions/transport/callHandler.js +6 -3
  225. package/dist/modules/actions/transport/catalogHandler.d.ts +5 -2
  226. package/dist/modules/actions/transport/catalogHandler.js +3 -2
  227. package/dist/modules/actions/transport/stream.d.ts +4 -5
  228. package/dist/modules/actions/transport/stream.js +12 -76
  229. package/dist/modules/actions/transport/webhookHandler.js +5 -4
  230. package/dist/modules/actions/types.d.ts +162 -4
  231. package/dist/modules/connectors/engine.js +3 -5
  232. package/dist/modules/functions/build.d.ts +22 -0
  233. package/dist/modules/functions/build.js +122 -0
  234. package/dist/modules/functions/build.test.d.ts +1 -0
  235. package/dist/modules/functions/capabilities.d.ts +22 -0
  236. package/dist/modules/functions/capabilities.js +228 -0
  237. package/dist/modules/functions/config.d.ts +34 -0
  238. package/dist/modules/functions/config.js +24 -0
  239. package/dist/modules/functions/context.d.ts +17 -0
  240. package/dist/modules/functions/context.js +88 -0
  241. package/dist/modules/functions/contract.d.ts +121 -0
  242. package/dist/modules/functions/contract.js +9 -0
  243. package/dist/modules/functions/driver.d.ts +36 -0
  244. package/dist/modules/functions/driver.js +150 -0
  245. package/dist/modules/functions/load.d.ts +15 -0
  246. package/dist/modules/functions/load.js +45 -0
  247. package/dist/modules/functions/load.test.d.ts +1 -0
  248. package/dist/modules/functions/local.d.ts +29 -0
  249. package/dist/modules/functions/local.js +61 -0
  250. package/dist/modules/functions/local.test.d.ts +1 -0
  251. package/dist/modules/functions/manifest.d.ts +24 -0
  252. package/dist/modules/functions/manifest.js +163 -0
  253. package/dist/modules/functions/manifest.test.d.ts +1 -0
  254. package/dist/modules/functions/native.d.ts +8 -0
  255. package/dist/modules/functions/native.js +21 -0
  256. package/dist/modules/functions/native.test.d.ts +1 -0
  257. package/dist/modules/functions/protocol.d.ts +216 -0
  258. package/dist/modules/functions/protocol.js +18 -0
  259. package/dist/modules/functions/routes.d.ts +36 -0
  260. package/dist/modules/functions/routes.js +181 -0
  261. package/dist/modules/functions/routes.test.d.ts +1 -0
  262. package/dist/modules/functions/runner/messages.d.ts +5 -0
  263. package/dist/modules/functions/runner/messages.js +188 -0
  264. package/dist/modules/functions/runner/remote.d.ts +19 -0
  265. package/dist/modules/functions/runner/remote.js +116 -0
  266. package/dist/modules/functions/runner/remote.test.d.ts +1 -0
  267. package/dist/modules/functions/runner/service.d.ts +32 -0
  268. package/dist/modules/functions/runner/service.js +209 -0
  269. package/dist/modules/functions/sandbox/guest.d.ts +45 -0
  270. package/dist/modules/functions/sandbox/guest.js +660 -0
  271. package/dist/modules/functions/sandbox/isolate.d.ts +37 -0
  272. package/dist/modules/functions/sandbox/isolate.js +347 -0
  273. package/dist/modules/functions/sandbox/isolate.test.d.ts +1 -0
  274. package/dist/modules/functions/sandbox/prelude.d.ts +2 -0
  275. package/dist/modules/functions/sandbox/prelude.js +49 -0
  276. package/dist/modules/functions/space.d.ts +40 -0
  277. package/dist/modules/functions/space.js +162 -0
  278. package/dist/modules/functions/testing/tasksOf.d.ts +4 -0
  279. package/dist/modules/functions/tryEntry.d.ts +9 -0
  280. package/dist/modules/functions/tryEntry.js +49 -0
  281. package/dist/modules/mongo/index.d.ts +4 -0
  282. package/dist/modules/mongo/jobQueue.d.ts +38 -0
  283. package/dist/modules/mongo/jobQueue.js +335 -0
  284. package/dist/modules/mongo/kv.d.ts +15 -0
  285. package/dist/modules/mongo/kv.js +129 -0
  286. package/dist/modules/mongo/stores.integration.test.d.ts +1 -0
  287. package/dist/modules/mysql/accounts.js +19 -9
  288. package/dist/modules/mysql/index.d.ts +2 -1
  289. package/dist/modules/mysql/jobs/index.d.ts +5 -0
  290. package/dist/modules/mysql/jobs/jobQueue.d.ts +40 -0
  291. package/dist/modules/mysql/jobs/jobQueue.js +375 -0
  292. package/dist/modules/mysql/jobs/kv.d.ts +18 -0
  293. package/dist/modules/mysql/jobs/kv.js +108 -0
  294. package/dist/modules/mysql/jobs/schema.d.ts +33 -0
  295. package/dist/modules/mysql/jobs/schema.js +113 -0
  296. package/dist/modules/mysql/jobs/stores.integration.test.d.ts +1 -0
  297. package/dist/modules/mysql/schema.js +25 -0
  298. package/dist/modules/mysql/sessions.d.ts +1 -11
  299. package/dist/modules/mysql/sessions.js +6 -1
  300. package/dist/modules/realtime/declarations.d.ts +11 -0
  301. package/dist/modules/realtime/declarations.js +26 -0
  302. package/dist/modules/realtime/grants.d.ts +23 -0
  303. package/dist/modules/realtime/grants.js +61 -0
  304. package/dist/modules/realtime/handlers.d.ts +74 -0
  305. package/dist/modules/realtime/handlers.js +224 -0
  306. package/dist/modules/realtime/hub.d.ts +62 -0
  307. package/dist/modules/realtime/hub.js +141 -0
  308. package/dist/modules/realtime/index.d.ts +51 -0
  309. package/dist/modules/realtime/index.js +62 -0
  310. package/dist/modules/realtime/memoryPubSub.d.ts +10 -0
  311. package/dist/modules/realtime/memoryPubSub.js +43 -0
  312. package/dist/modules/realtime/realtime.test.d.ts +1 -0
  313. package/dist/modules/realtime/redisPubSub.d.ts +24 -0
  314. package/dist/modules/realtime/redisPubSub.js +36 -0
  315. package/dist/modules/realtime/redisPubSub.test.d.ts +1 -0
  316. package/dist/modules/realtime/socket.d.ts +25 -0
  317. package/dist/modules/realtime/socket.js +122 -0
  318. package/dist/modules/realtime/socket.test.d.ts +1 -0
  319. package/dist/modules/rsc/handler.d.ts +16 -0
  320. package/dist/modules/rsc/handler.js +17 -10
  321. package/dist/modules/rsc/handler.test.d.ts +1 -0
  322. package/dist/modules/rsc/resolveRscData.js +2 -1
  323. package/dist/modules/runtime/bundle.d.ts +24 -0
  324. package/dist/modules/runtime/bundle.js +102 -0
  325. package/dist/modules/runtime/contract.d.ts +37 -0
  326. package/dist/modules/runtime/contract.js +21 -0
  327. package/dist/modules/runtime/entry.test.d.ts +1 -0
  328. package/dist/modules/runtime/host.d.ts +38 -0
  329. package/dist/modules/runtime/host.js +68 -0
  330. package/dist/modules/runtime/inside.d.ts +15 -0
  331. package/dist/modules/runtime/inside.js +47 -0
  332. package/dist/modules/runtime/inside.test.d.ts +1 -0
  333. package/dist/modules/runtime/runner.d.ts +11 -0
  334. package/dist/modules/runtime/runner.js +38 -0
  335. package/dist/modules/runtime/runtime.test.d.ts +1 -0
  336. package/dist/modules/runtime/stages.d.ts +50 -0
  337. package/dist/modules/runtime/stages.js +117 -0
  338. package/dist/modules/ssr/Component.d.ts +4 -5
  339. package/dist/modules/ssr/Component.js +2 -2
  340. package/dist/modules/ssr/handler.js +10 -2
  341. package/dist/modules/ssr/loadPluginComponents.js +2 -1
  342. package/dist/modules/ssr/prepareRender.js +39 -13
  343. package/dist/modules/ssr/preview.d.ts +3 -0
  344. package/dist/modules/ssr/preview.js +17 -7
  345. package/dist/modules/ssr/redirect.test.d.ts +1 -0
  346. package/dist/modules/ssr/registerExternalPlugins.d.ts +6 -1
  347. package/dist/modules/ssr/registerExternalPlugins.js +19 -16
  348. package/dist/modules/ssr/registerExternalPlugins.test.d.ts +1 -0
  349. package/dist/modules/ssr/reportMissingPlugins.d.ts +9 -0
  350. package/dist/modules/ssr/reportMissingPlugins.js +24 -0
  351. package/dist/modules/ssr/reportMissingPlugins.test.d.ts +1 -0
  352. package/dist/modules/ssr/streamBody.d.ts +2 -2
  353. package/dist/modules/ssr/streamBody.js +4 -1
  354. package/dist/modules/ssr/template.js +1 -1
  355. package/dist/modules/ssr/views/template.ejs +8 -5
  356. package/dist/mongo.d.ts +25 -0
  357. package/dist/mongo.js +3 -0
  358. package/dist/mysql.d.ts +11 -0
  359. package/dist/mysql.js +4 -1
  360. package/dist/oauth.js +2 -2
  361. package/dist/plugins/compile.js +9 -4
  362. package/dist/plugins/copy.js +3 -3
  363. package/dist/plugins/manager.d.ts +35 -3
  364. package/dist/plugins/manager.js +109 -38
  365. package/dist/runtime.d.ts +15 -0
  366. package/dist/runtime.js +7 -0
  367. package/package.json +52 -11
  368. package/skills/plitzi-authoring/SKILL.md +153 -263
  369. package/skills/plitzi-authoring/reference/accessibility.md +111 -0
  370. package/skills/plitzi-authoring/reference/authoring-errors.md +70 -0
  371. package/skills/plitzi-authoring/reference/data-and-visibility.md +180 -0
  372. package/skills/plitzi-authoring/reference/elements-and-styles.md +161 -0
  373. package/skills/plitzi-authoring/reference/flows.md +171 -0
  374. package/skills/plitzi-authoring/reference/layouts.md +140 -0
  375. package/skills/plitzi-authoring/reference/lists.md +74 -0
  376. package/skills/plitzi-authoring/reference/performance.md +67 -0
  377. package/skills/plitzi-authoring/reference/plugins.md +167 -0
  378. package/skills/plitzi-authoring/reference/review-checklist.md +67 -0
  379. package/skills/plitzi-authoring/reference/structure.md +83 -0
  380. package/skills/plitzi-authoring/reference/templates-and-export.md +54 -0
  381. package/skills/plitzi-authoring/reference/templates.md +109 -0
  382. package/skills/plitzi-authoring/reference/testing.md +119 -0
  383. package/skills/plitzi-authoring/reference/validation.md +73 -0
  384. package/dist/modules/actions/runtime/schedule.d.ts +0 -35
  385. package/dist/modules/actions/runtime/schedule.js +0 -76
  386. /package/dist/{modules/actions/runtime/schedule.test.d.ts → adapters/jsonAdapters.test.d.ts} +0 -0
package/README.md CHANGED
@@ -106,9 +106,12 @@ server.listen(3001, '127.0.0.1');
106
106
 
107
107
  ```bash
108
108
  yarn add @plitzi/sdk-server react react-dom
109
- yarn tsx server.ts # http://127.0.0.1:3001/
109
+ node server.ts # http://127.0.0.1:3001/ — Node 22.18+ runs TypeScript itself
110
110
  ```
111
111
 
112
+ No transpiler in front of it: Node strips the types. A loader such as `tsx` costs a page server more memory than the
113
+ server itself — on a 128 MB host, the difference between starting and being killed on boot.
114
+
112
115
  Both pages render server-side, with the CSS the space declared. `authorSpace` refuses to hand back a space that
113
116
  would not render — a CSS property the style editor could not read back, a class nothing declares, a binding
114
117
  pointing at an element that is not there — so a mistake is an error at the line that made it rather than a blank
@@ -158,26 +161,32 @@ serve it — worth running over anything that arrives as a file.
158
161
  |---|---|---|---|
159
162
  | `httpVersion` | `1 \| 2 \| 3` | `2` with `tls`, else `1` | HTTP protocol version. Falls back to the nearest available lower version. |
160
163
  | `tls` | `{ key, cert, minVersion? }` | — | TLS key and certificate. Required for versions 2 and 3; optional for version 1. |
161
- | `devMode` | `boolean` | `NODE_ENV !== 'production'` | Enables development mode: appends `?dev` to esm.sh CDN URLs for React, and activates per-request timing metrics (see [Dev metrics](#dev-metrics)). |
164
+ | `devMode` | `boolean` | `false` | Enables development mode: appends `?dev` to esm.sh CDN URLs for React, and activates per-request timing metrics (see [Dev metrics](#dev-metrics)). Off, the process must run with `NODE_ENV=production` or React renders with its development build; the server says so once, at `error`. |
162
165
  | `assetVersion` | `string` | — | Cache-buster appended as `?v=<assetVersion>` to all default SDK asset URLs. Compute from file mtime or package version at startup. |
163
166
  | `cacheTtlMs` | `number` | `300000` | TTL in milliseconds for the SSR render cache. Set to `0` to disable. |
164
167
  | `loginPath` | `string \| false` | `'/auth/login'` | Path for the built-in login endpoint. Set to `false` to disable it entirely. |
165
168
  | `logoutPath` | `string \| false` | `'/auth/logout'` | Path for the built-in logout endpoint. Set to `false` to disable it entirely. |
169
+ | `signIn` | `SSRSignInConfig` | — | Sign visitors in by redirect through an OAuth 2.1 authorization server: `GET /auth/sign-in?return=/x` registers this host as a client, sends the browser out with PKCE (state in a `__Host-` cookie), and `/auth/sign-in/callback` redeems the code server to server and hands the token to `exchangeCredential`, which makes the session here. Needs the `exchangeCredential` adapter. |
166
170
  | `templateFn` | `SSRTemplateFn` | built-in EJS template | Custom render function. Receives all template params and returns an HTML string. |
167
171
  | `plugins` | `Record<string, PluginSource>` | — | Named plugin definitions. Compiled or copied on first use and cached for `pluginsTtlMs`. |
168
172
  | `pluginsCacheDir` | `string` | `.sdk-plugins` | Directory where compiled plugin files are stored. |
169
173
  | `pluginsTtlMs` | `number` | `604800000` | TTL in milliseconds for compiled plugins (default: 1 week). |
170
174
  | `autoLoadSchemaPlugins` | `boolean` | `true` | Auto-download and cache plugins declared in the schema's `offlineData.plugins` list. Set to `false` to manage plugin loading manually. |
175
+ | `allowPrivatePluginHosts` | `boolean` | `false` | Read a schema plugin from a private address (`localhost`, this server's own network). A plugin's address is typed by whoever edits a space, so leave it off anywhere but a development machine whose bucket is local. |
171
176
  | `publicDir` | `string` | — | Absolute path to a directory served at the root URL level (e.g. `robots.txt`, `favicon.png`). Files are checked before `static` prefix routes. |
172
177
  | `static` | `Record<string, string>` | — | URL prefix → filesystem path mappings for static file serving. |
173
178
  | `ssrOnly` | `boolean` | `false` | Omit client-side JS from the rendered page. Useful for verifying SSR HTML without hydration. |
174
179
  | `streaming` | `boolean` | `false` | Stream HTML to the browser incrementally to reduce TTFB. See [Streaming](#streaming). |
175
180
  | `middlewares` | `SSRMiddleware[]` | — | Array of custom middleware functions executed before the SSR renderer on every request (see [Custom middlewares](#custom-middlewares)). |
176
181
  | `rsc` | `SSRRscConfig` | — | React Server Components endpoint configuration (see [RSC](#react-server-components-rsc)). |
182
+ | `realtime` | `{ pubsub?, path?, transport?, allowedOrigins? } \| false` | in memory, at `/_realtime`, `sse` | Realtime channels the space declares. `transport` is what pages connect with: `sse` (a stream, publishes over `POST`) or `websocket` (one socket both ways, HTTP/1.1 only; pages fall back to the stream where a socket cannot open). `allowedOrigins` lists the other origins whose pages may open a socket. `pubsub` is how messages reach other processes — `createMemoryPubSub()` (the default, across workers) or `createRedisPubSub({ publisher, subscriber })` for several replicas. `false` serves no endpoint. See [`docs/en/realtime.md`](../../docs/en/realtime.md). |
177
183
  | `compression` | `SSRCompressionConfig \| false` | Brotli, then gzip | Response compression (see [Compression](#compression)). `false` never compresses. |
178
184
  | `health` | `SSRHealthConfig` | identity payload | The `/health` endpoint. `check` adds live state per probe and turns it into a readiness probe (see [Health](#health)). |
179
185
  | `adapters` | `SSRAdapters` | — | Required. Adapter callbacks for data fetching. |
186
+ | `logLevel` | `'silent' \| 'error' \| 'warn' \| 'info' \| 'debug'` | `info` with `devMode`, else `error` | How much the server says, for the whole process (see [Logging](#logging)). |
187
+ | `logger` | `ServerLogger` | the console | Where it says it: one structured `ServerLogEvent` stream. `consoleLogger` prints each as one line. |
180
188
  | `onListenError` | `(error, { port, host, label }) => void` | exits non-zero | What to do when the server cannot take its port. By default it prints what went wrong and what to do about it, then exits — a process whose server never bound is not running. Supply this to keep it alive and decide yourself. |
189
+ | `workers` | `boolean \| number \| 'auto'` | `'auto'` under `NODE_ENV=production`, else `false` | How many processes serve the port: one per core, a number (lowered to the cores there are), or one. `SDK_SERVER_WORKERS` sets it when the config does not. See [Using every core](#using-every-core). |
181
190
 
182
191
  ### HTTP version behaviour
183
192
 
@@ -409,7 +418,8 @@ createServer({ compression: false, adapters });
409
418
  |---|---|---|---|
410
419
  | `encodings` | `('br' \| 'gzip')[]` | `['br', 'gzip']` | What this server offers, most preferred first; the first one the client accepts wins. `[]` disables compression. |
411
420
  | `threshold` | `number` | `1024` | Responses smaller than this many bytes go out uncompressed. |
412
- | `brotliQuality` | `number` | `4` | Brotli quality, 0–11. Past 4 the CPU cost outgrows the bytes saved on HTML. |
421
+ | `brotliQuality` | `number` | `2` | Brotli quality, 0–11, for a body compressed on every request (a page rendered for that request alone). Measured on a quarter core, 4 cost a tenth of the pages a second to save half a kilobyte each. |
422
+ | `keptBrotliQuality` | `number` | `6` | Brotli quality for a body compressed once and kept: a cached page, a static file such as the SDK bundle. Paid once; the bundle comes out 10% smaller than at 4, for the same memory. 9 needs ~40 MB more to compress the bundle, which a 128 MB server does not have. |
413
423
  | `gzipLevel` | `number` | `6` | Gzip level, 0–9. |
414
424
 
415
425
  A response that sets `Cache-Control: no-transform` is never compressed, whatever the settings say — that header is
@@ -546,7 +556,7 @@ const getSpaceDeployment = async (req): Promise<SSRSpaceDeployment> => {
546
556
  };
547
557
  ```
548
558
 
549
- Plugins listed in `pluginSources` are registered into the plugin manager on-the-fly using `ensure()`, which only triggers a rebuild if the plugin is new or its `version` has changed. Both `pluginNames` and `pluginSources` entries are resolved in parallel before the HTML is rendered.
559
+ Plugins listed in `pluginSources` — and the external plugins a space's schema lists — are registered into the plugin manager on-the-fly using `ensure()`, under a key that carries the source's identity as well as its name and version (`name@1.0.0+<digest>` of its `js`, `css`, `action` and `props`). A plugin published again under the same version, or another space's plugin with the same name and version, is therefore a source of its own rather than whichever this process met first, and is built only once. Both `pluginNames` and `pluginSources` entries are resolved in parallel before the HTML is rendered.
550
560
 
551
561
  ### Plugin sources
552
562
 
@@ -966,8 +976,8 @@ and every refusal names a machine-readable `reason`, so a client can tell "renew
966
976
  | `identity` | Your own hosts and origins — the floor for domain binding and framing |
967
977
  | `tokens.lifetimes` | How long each credential lives |
968
978
 
969
- Working examples are in [`examples/02-with-users`](../../examples/02-with-users): `01-sessions` over a store you
970
- write, `02-mysql` over one you do not.
979
+ Working examples are in [`examples/self-hosting`](../../examples/self-hosting): `03-sessions` over a store you
980
+ write, `04-mysql` over one you do not.
971
981
 
972
982
  ### Cross-site request forgery
973
983
 
@@ -1134,6 +1144,86 @@ A stage receives the `SSRContext` — the request, the config, and the render si
1134
1144
  **is** the decision to mount them: there is no config flag mirroring it, and a server that never passes them
1135
1145
  never loads them.
1136
1146
 
1147
+ ## Using every core
1148
+
1149
+ Node runs JavaScript on one thread, so one process renders on one core however many the machine has. With
1150
+ `workers`, the server runs one process per core and the connections are spread between them: more requests a second,
1151
+ and less time waiting behind another page's render.
1152
+
1153
+ ```ts
1154
+ createServer({ adapters, workers: 'auto' }); // one per core — the default under NODE_ENV=production
1155
+ createServer({ adapters, workers: 4 }); // at most four, and never more than the cores there are
1156
+ createServer({ adapters, workers: false }); // one process, exactly as before
1157
+ ```
1158
+
1159
+ `SDK_SERVER_WORKERS=auto|false|<n>` sets it from the environment. The cores are the ones the process may use: a
1160
+ container's CPU quota counts, so a pod limited to one CPU runs one process whatever the node has.
1161
+
1162
+ **One process is the server as it always was.** Workers off, one asked for, or one core to run on: nothing is forked,
1163
+ nothing is wrapped, and every in-memory default is this process's own.
1164
+
1165
+ **Several are still one server.** The process you started serves nothing itself; it starts the workers, restarts them
1166
+ and keeps what they must share:
1167
+
1168
+ - The in-memory defaults — an action's `kv`, the job queue, draft previews, the sign-in rate limit — are kept once, by
1169
+ that process, and every worker reaches the same copy. A counter counts every request once; a draft written through
1170
+ one worker is read through another. A store you supply (Redis, a table) is used as it is.
1171
+ - The scheduler and the job consumers run in one worker only: a schedule fires once, and `jobs.workers` is the whole
1172
+ server's concurrency.
1173
+ - `server.cache.invalidate()`, `server.plugins.register()` and `server.plugins.invalidate()` reach every worker,
1174
+ whichever process calls them — a publish webhook lands on one of them.
1175
+ - Plugins are built once, before the workers start.
1176
+
1177
+ Per worker: the rendered-page cache (each renders a page once), the plugin components, and the action caps
1178
+ (`action.concurrency`). A plugin registered with a `component` stays in the process that registered it — register
1179
+ those where the server is created.
1180
+
1181
+ **When a worker dies** — a crash, an uncaught error, the OOM killer — it is replaced, and its replacement takes over the
1182
+ jobs it carried (a claimed job goes back to the queue when its lease lapses). Past one death per worker a minute the
1183
+ replacements wait, doubling from half a second up to thirty, so a request that crashes every worker it reaches cannot
1184
+ turn the server into a fork loop. A replacement that fails to start is retried the same way while the rest keep
1185
+ serving. Two exceptions: a worker that dies before any has served stops the server with a non-zero exit (a port in use
1186
+ would fail the same way every time), and a server that is killed outright takes its workers with it.
1187
+
1188
+ `closeOnSignals(server)` stops them all on SIGTERM, each finishing what it is serving. The workers of one machine are
1189
+ one replica; several machines are several replicas, and what must hold across those still needs a shared store — see
1190
+ below.
1191
+
1192
+ A process that starts servers of its own beside this one (an Express app on another port) should say `workers:
1193
+ false`: each worker runs the whole entry file again.
1194
+
1195
+ ## Scheduled jobs across replicas
1196
+
1197
+ Server actions with a `schedule` trigger, and jobs queued for later, run with no configuration — over an in-process
1198
+ queue, which is right for one replica and wrong for two: each keeps its own schedules, and the jobs a replica holds
1199
+ leave with it. More than one replica needs a queue and a key/value store they share. They are adapters, so the jobs
1200
+ live in your database; for Mongo and MySQL they are already written, over the connection you already have:
1201
+
1202
+ ```ts
1203
+ import { closeOnSignals, createServer } from '@plitzi/sdk-server';
1204
+ import { createMongoJobQueue, createMongoKv } from '@plitzi/sdk-server/mongo';
1205
+
1206
+ const db = mongoClient.db('app');
1207
+ const server = createServer({
1208
+ adapters,
1209
+ action: { lookups, kv: createMongoKv({ db }), jobs: { queue: createMongoJobQueue({ db }) } }
1210
+ });
1211
+
1212
+ server.listen(3000);
1213
+ // On SIGTERM: finish the jobs this replica is running, leave the waiting ones for the next, then exit.
1214
+ closeOnSignals(server, { afterClose: () => mongoClient.close() });
1215
+ ```
1216
+
1217
+ `close()` does not wait for what never ends on its own: it stops taking connections, tells every realtime socket and
1218
+ stream to go (a WebSocket is closed with 1001, "going away", which the pages reconnect from once the server is back),
1219
+ ends any other event stream, lets what is being answered finish, and cuts whatever is still open after ten seconds
1220
+ (`SHUTDOWN_GRACE_MS`). A page left open on a board, or an agent's app listening, no longer holds a Ctrl+C or a
1221
+ SIGTERM until something kills the process.
1222
+
1223
+ `@plitzi/sdk-server/mysql` has the same pair over a `mysql2` pool (`createMysqlJobQueue`, `createMysqlKv`). Anything
1224
+ else is the `ActionJobQueue` contract written against your store — see
1225
+ [server actions § self-hosted](https://github.com/plitzi/plitzi-workspace/blob/main/docs/en/server-actions.md#13-for-a-self-hosted-deployment).
1226
+
1137
1227
  ## Running it locally
1138
1228
 
1139
1229
  The package ships a small harness in [`dev/`](./dev) — file-backed adapters over a sample space, three demo
@@ -1265,12 +1355,41 @@ How it works:
1265
1355
 
1266
1356
  **Compression**: streaming responses use chunked transfer encoding and skip Brotli/gzip compression. A `Content-Length` header cannot be set before the body is complete, so compression is intentionally bypassed for streaming responses.
1267
1357
 
1358
+ ## Logging
1359
+
1360
+ One stream and one threshold, the usual hierarchy: `silent` < `error` < `warn` < `info` < `debug`. In production the
1361
+ server says only what went wrong — a failed request, a failed run, a server that could not start — and everything
1362
+ below it is one `logLevel` away:
1363
+
1364
+ | Level | What it adds |
1365
+ |---|---|
1366
+ | `error` | Requests answered 5xx or that threw, runs that did not complete, anything the server could not do. |
1367
+ | `warn` | Refused actions (a bad webhook signature, a missing session), plugin manifests it could not fetch, HTTP/3 falling back. |
1368
+ | `info` | Every request line, every run, plugin builds, `listening on`. |
1369
+ | `debug` | The per-render phase breakdown of [Dev metrics](#dev-metrics). |
1370
+
1371
+ ```ts
1372
+ createServer({ adapters, logLevel: process.env.LOG_LEVEL === 'info' ? 'info' : 'error', logger: consoleLogger });
1373
+ ```
1374
+
1375
+ A request below the threshold is not even turned into an event, so a quiet server pays nothing per request. Everything goes to the `logger` —
1376
+ requests, MCP tool calls, runs, and the server's own messages as `kind: 'message'` events — and `logLevelOf(event)`
1377
+ tells a sink how severe each one is. The run and refusal loggers a deployment wires itself (`createRunLogger`,
1378
+ `createRejectLogger`) are held to the same threshold, and so is `serverLog`, the server's own voice, which a
1379
+ deployment's adapters can speak through too:
1380
+
1381
+ ```ts
1382
+ import { serverLog } from '@plitzi/sdk-server';
1383
+
1384
+ serverLog.warn('Adapters', 'space 12 has no deployment, serving main');
1385
+ ```
1386
+
1268
1387
  ## Dev metrics
1269
1388
 
1270
1389
  When `devMode: true`, per-phase timing is instrumented on every render and reported in two ways:
1271
1390
 
1272
1391
  - A `Server-Timing` header is set on the response, visible in the browser's DevTools under **Network → Timing**.
1273
- - A one-line summary is logged to stdout:
1392
+ - A one-line summary is logged at `debug` (see [Logging](#logging)):
1274
1393
 
1275
1394
  ```
1276
1395
  [SSR] GET / — schema=1ms rsc=0ms extPlugins=0ms plugins=0ms template=2ms react=16ms | total=19ms
package/dist/actions.d.ts CHANGED
@@ -12,18 +12,26 @@
12
12
  * Builds a runner outside a page server.
13
13
  *
14
14
  * The page server builds its own from `action.lookups`; this is for the deployment that needs to run an action
15
- * from somewhere else — a scheduler, a queue consumer, or the API role answering a builder's test run. Same
16
- * runner, same checks: a trigger that skipped them would be a weaker path to the same work.
15
+ * from somewhere else — a queue consumer, or the API role answering a builder's test run. Same runner, same
16
+ * checks: a trigger that skipped them would be a weaker path to the same work.
17
17
  */
18
- export { createActionsModule } from './modules/actions';
19
- export { createScheduleRunner } from './modules/actions/runtime/schedule';
18
+ export { createActionsModule, spaceKvPatterns } from './modules/actions';
19
+ /**
20
+ * Scheduled runs: a durable queue, a leaderless producer and the workers that drain it.
21
+ *
22
+ * `createActionsModule` already assembles these from `jobs` — a deployment reaches for them directly only to run a
23
+ * sweep from its own cron, to build a worker in a process that serves no pages, or to hold the queue itself for an
24
+ * operator's panel. The in-memory queue is the default and is correct for exactly one replica.
25
+ */
26
+ export { createActionJobs, createJobWorker, createMemoryJobQueue, createScheduler } from './modules/actions/jobs';
27
+ export { DEFAULT_MAX_ATTEMPTS, scheduleFor, scheduleJobId, schedulesFor } from './modules/actions/jobs';
20
28
  /**
21
29
  * Cron, straight from `sdk-shared`, where the parser lives because the validator needs it too.
22
30
  *
23
31
  * Re-exported HERE and nowhere in between: a deployment mounting its own scheduler reaches for one package, and
24
32
  * the file that used to sit in `runtime/` existed only so a neighbouring import could look local.
25
33
  */
26
- export { cronMatches, parseCron } from '@plitzi/sdk-shared/actions';
34
+ export { cronFiresBetween, cronMatches, cronNextFire, parseCron } from '@plitzi/sdk-shared/actions';
27
35
  /**
28
36
  * What only this deployment can answer about an action, before anybody runs it: a task it does not register, a
29
37
  * credential the space has not got, a key missing from the one it has, a connector that was deleted, an engine
@@ -31,7 +39,7 @@ export { cronMatches, parseCron } from '@plitzi/sdk-shared/actions';
31
39
  */
32
40
  export { checkAction } from './modules/actions/runtime/check';
33
41
  export type { ActionCheckDeps } from './modules/actions/runtime/check';
34
- export { ActionRunError } from './modules/actions/runtime/errors';
42
+ export { ActionRefusal, ActionRunError } from './modules/actions/runtime/errors';
35
43
  export { DEFAULT_LIMITS } from './modules/actions/runtime/limits';
36
44
  export { createTaskRegistry, taskName } from './modules/actions/tasks/registry';
37
45
  export { describeCatalog, describeTask } from './modules/actions/taskCatalog';
@@ -46,6 +54,10 @@ export { describeCatalog, describeTask } from './modules/actions/taskCatalog';
46
54
  */
47
55
  export { createMemoryKv } from './modules/actions/runtime/memoryKv';
48
56
  export { createKvStore } from './modules/actions/runtime/kvStore';
57
+ export { createRedisKv } from './modules/actions/runtime/redisKv';
58
+ export type { RedisKvClient, RedisKvOptions } from './modules/actions/runtime/redisKv';
59
+ export { MAX_LIST_BYTES, MAX_LIST_ENTRIES } from './modules/actions/runtime/kvList';
60
+ export type { KvListEntry, KvListPut, KvListPutOptions, KvListRange } from './modules/actions/runtime/kvList';
49
61
  /**
50
62
  * `onRun` and `onReject` for a deployment that wants to SEE its flows without building somewhere to keep them: a
51
63
  * run — and a request that never became one — becomes one more event on the log stream the server already
@@ -56,8 +68,8 @@ export { createKvStore } from './modules/actions/runtime/kvStore';
56
68
  */
57
69
  export { createRunLogger, createRejectLogger } from './modules/actions/runtime/runLogger';
58
70
  export type { TaskRegistryOptions } from './modules/actions/tasks/registry';
59
- export type { ActionCredential, ActionDbDriver, ActionEmailConfig, ActionEmailDelivery, ActionEmailMessage, ActionEmailTransport, ActionKvAdapter, ActionKvStore, ActionLookups, ActionRejectRecord, ActionRunRecord, ActionRunRequest, ActionRunResult, ActionsConfig, ActionTask, ActionTaskContext, ActionTaskRegistry, RegisteredTask, ResolvedConnector } from './modules/actions/types';
71
+ export type { ActionCredential, ActionDbDriver, ActionEmailConfig, ActionEmailDelivery, ActionEmailMessage, ActionEmailTransport, ActionJobsConfig, ActionKvAdapter, ActionKvStore, ActionLookups, ActionRejectRecord, ActionRunRecord, ActionRunRequest, ActionRunResult, ActionsConfig, ActionTask, ActionTaskContext, ActionTaskRegistry, RegisteredTask, ResolvedConnector } from './modules/actions/types';
60
72
  export type { ActionsModule } from './modules/actions';
73
+ export type { ActionJobs, JobWorker, JobWorkerOptions, MemoryJobQueueOptions, Scheduler, SchedulerOptions, SweepResult } from './modules/actions/jobs';
61
74
  export type { ActiveRun, RunGuards } from './modules/actions/runtime/guards';
62
- export type { ScheduleResult, ScheduleRunner, ScheduleTick } from './modules/actions/runtime/schedule';
63
75
  export type { ActionTaskDescriptor } from './modules/actions/taskCatalog';
package/dist/actions.js CHANGED
@@ -1,12 +1,19 @@
1
- import { ActionRunError } from "./modules/actions/runtime/errors.js";
1
+ import { createMemoryJobQueue } from "./modules/actions/jobs/memoryQueue.js";
2
+ import { DEFAULT_MAX_ATTEMPTS, scheduleFor, scheduleJobId, schedulesFor } from "./modules/actions/jobs/schedules.js";
3
+ import { createScheduler } from "./modules/actions/jobs/scheduler.js";
4
+ import { ActionRefusal, ActionRunError } from "./modules/actions/runtime/errors.js";
5
+ import { createJobWorker } from "./modules/actions/jobs/worker.js";
6
+ import { createActionJobs } from "./modules/actions/jobs/index.js";
7
+ import { MAX_LIST_BYTES, MAX_LIST_ENTRIES } from "./modules/actions/runtime/kvList.js";
2
8
  import { createKvStore } from "./modules/actions/runtime/kvStore.js";
3
9
  import { DEFAULT_LIMITS } from "./modules/actions/runtime/limits.js";
4
10
  import { createMemoryKv } from "./modules/actions/runtime/memoryKv.js";
11
+ import { spaceKvPatterns } from "./modules/actions/runtime/namespaceKv.js";
5
12
  import { createTaskRegistry, taskName } from "./modules/actions/tasks/registry.js";
6
13
  import { checkAction } from "./modules/actions/runtime/check.js";
7
- import { createScheduleRunner } from "./modules/actions/runtime/schedule.js";
8
14
  import { createRejectLogger, createRunLogger } from "./modules/actions/runtime/runLogger.js";
9
15
  import { describeCatalog, describeTask } from "./modules/actions/taskCatalog.js";
10
16
  import { createActionsModule } from "./modules/actions/index.js";
11
- import { cronMatches, parseCron } from "@plitzi/sdk-shared/actions";
12
- export { ActionRunError, DEFAULT_LIMITS, checkAction, createActionsModule, createKvStore, createMemoryKv, createRejectLogger, createRunLogger, createScheduleRunner, createTaskRegistry, cronMatches, describeCatalog, describeTask, parseCron, taskName };
17
+ import { createRedisKv } from "./modules/actions/runtime/redisKv.js";
18
+ import { cronFiresBetween, cronMatches, cronNextFire, parseCron } from "@plitzi/sdk-shared/actions";
19
+ export { ActionRefusal, ActionRunError, DEFAULT_LIMITS, DEFAULT_MAX_ATTEMPTS, MAX_LIST_BYTES, MAX_LIST_ENTRIES, checkAction, createActionJobs, createActionsModule, createJobWorker, createKvStore, createMemoryJobQueue, createMemoryKv, createRedisKv, createRejectLogger, createRunLogger, createScheduler, createTaskRegistry, cronFiresBetween, cronMatches, cronNextFire, describeCatalog, describeTask, parseCron, scheduleFor, scheduleJobId, schedulesFor, spaceKvPatterns, taskName };
@@ -1,3 +1,4 @@
1
+ import { serverLog } from "../helpers/serverLog.js";
1
2
  //#region src/adapters/cloudAdapters.ts
2
3
  /**
3
4
  * A space fetched from Plitzi, for a server that is not Plitzi's.
@@ -150,17 +151,17 @@ var createCloudAdapters = (config) => {
150
151
  })
151
152
  });
152
153
  if (!response.ok) {
153
- console.error(`[CloudAdapters] ${what} answered ${response.status}`);
154
+ serverLog.error("CloudAdapters", `${what} answered ${response.status}`);
154
155
  return;
155
156
  }
156
157
  const payload = await response.json();
157
158
  if (payload.errors?.length) {
158
- console.error(`[CloudAdapters] ${what}: ${payload.errors.map((error) => error.message).join("; ")}`);
159
+ serverLog.error("CloudAdapters", `${what}: ${payload.errors.map((error) => error.message).join("; ")}`);
159
160
  return;
160
161
  }
161
162
  return payload.data;
162
163
  } catch (error) {
163
- console.error(`[CloudAdapters] ${what} could not be reached:`, error.message);
164
+ serverLog.error("CloudAdapters", `${what} could not be reached`, error);
164
165
  return;
165
166
  }
166
167
  };
@@ -1,8 +1,29 @@
1
- import { readFileSync, writeFileSync } from "node:fs";
1
+ import { serverLog } from "../helpers/serverLog.js";
2
+ import { readFileSync, statSync, writeFileSync } from "node:fs";
2
3
  //#region src/adapters/jsonAdapters.ts
3
4
  var isDeploymentObject = (v) => typeof v === "object" && ("spaceId" in v || "environment" in v || "error" in v);
4
- var readJson = (filePath) => JSON.parse(readFileSync(filePath, "utf-8"));
5
+ var createJsonReader = () => {
6
+ const held = /* @__PURE__ */ new Map();
7
+ return {
8
+ read: (filePath) => {
9
+ const { mtimeMs, size } = statSync(filePath);
10
+ const hit = held.get(filePath);
11
+ if (hit?.mtimeMs === mtimeMs && hit.size === size) return hit.value;
12
+ const value = JSON.parse(readFileSync(filePath, "utf-8"));
13
+ held.set(filePath, {
14
+ mtimeMs,
15
+ size,
16
+ value
17
+ });
18
+ return value;
19
+ },
20
+ forget: (filePath) => {
21
+ held.delete(filePath);
22
+ }
23
+ };
24
+ };
5
25
  var createJsonAdapters = (config) => {
26
+ const json = createJsonReader();
6
27
  const pathFor = (spaceId, environment, revision) => {
7
28
  if (typeof config.offlineData === "function") return config.offlineData(spaceId, environment, revision);
8
29
  return typeof config.offlineData === "string" ? config.offlineData : void 0;
@@ -11,9 +32,9 @@ var createJsonAdapters = (config) => {
11
32
  try {
12
33
  const filePath = pathFor(spaceId, environment, revision);
13
34
  if (!filePath) return Promise.resolve(config.offlineData);
14
- return Promise.resolve(readJson(filePath));
35
+ return Promise.resolve(json.read(filePath));
15
36
  } catch (err) {
16
- console.error("[JsonAdapters] Failed to read offlineData:", err.message);
37
+ serverLog.error("JsonAdapters", "Failed to read offlineData", err);
17
38
  return Promise.resolve(void 0);
18
39
  }
19
40
  };
@@ -21,6 +42,7 @@ var createJsonAdapters = (config) => {
21
42
  const filePath = pathFor(spaceId, environment);
22
43
  if (!filePath) return Promise.resolve();
23
44
  writeFileSync(filePath, JSON.stringify(data, null, 2));
45
+ json.forget(filePath);
24
46
  return Promise.resolve();
25
47
  };
26
48
  const getSpaceDeployment = (req) => {
@@ -31,9 +53,9 @@ var createJsonAdapters = (config) => {
31
53
  revision: 0
32
54
  });
33
55
  if (typeof deployment === "string") try {
34
- return Promise.resolve(readJson(deployment));
56
+ return Promise.resolve(json.read(deployment));
35
57
  } catch (err) {
36
- console.error("[JsonAdapters] Failed to read deployment file:", err.message);
58
+ serverLog.error("JsonAdapters", "Failed to read deployment file", err);
37
59
  return Promise.resolve({ error: {
38
60
  code: 500,
39
61
  message: "Deployment config unreadable"
package/dist/auth.d.ts CHANGED
@@ -23,6 +23,7 @@
23
23
  export { createAuth } from './core/auth/createAuth';
24
24
  export { createAuthApi } from './core/auth/api';
25
25
  export { createCsrf, csrfFailureMessage } from './core/auth/csrf';
26
+ export { SESSION_ACTIVITY_RESOLUTION_SECONDS, activityDue } from './core/auth/sessionActivity';
26
27
  export { createAuthorizer, checkPermission, checkSpaceAccess, requirementFor } from './core/auth/authorize';
27
28
  export { createCarriers, presentedOrigin } from './core/auth/credentials';
28
29
  export { ANY_DOMAIN, corsOrigins, domainAllowed, frameAncestors, hostnameOf, normalizeDomain } from './core/auth/domains';
@@ -30,21 +31,23 @@ export { createIdentity } from './core/auth/identity';
30
31
  export { generateToken, hashPassword, verifyPassword } from './core/auth/passwords';
31
32
  export { BUILT_IN_PROVIDERS, OAuthFailure, createSocialAuth, requestProfileJson } from './core/auth/oauth';
32
33
  export { createRedirectPolicy } from './core/auth/redirects';
34
+ export { isDocumentNavigation, renewForNavigation } from './core/auth/renewal';
35
+ export type { RenewalOptions } from './core/auth/renewal';
33
36
  export type { RedirectPolicyConfig } from './core/auth/redirects';
34
37
  export { applySessionOutcome, authPolicyRules, authRoutes } from './core/auth/routes';
35
- export { appendCookies, clearFlowCookie, clearSessionCookies, createSessionCookies, isLocalHost, readFlowCookie, readRefreshToken, readSessionToken, sessionCookieParams, sessionHintValue, writeFlowCookie, writeSessionCookies } from './core/auth/session';
38
+ export { appendCookies, clearFlowCookie, clearSessionCookies, createSessionCookies, isLocalHost, parseSessionHint, readFlowCookie, readRefreshToken, readSessionHint, readSessionToken, sessionCookieParams, sessionHintValue, sessionReturnTarget, writeFlowCookie, writeSessionCookies } from './core/auth/session';
36
39
  export { createMemoryRateLimit } from './core/auth/throttle';
37
40
  export { createSpaceTokenApi } from './core/auth/spaceTokens';
38
41
  export { SCOPES, authFailureMessage, createTokens, userIdOf } from './core/auth/tokens';
39
- export { generateRecoveryCodes, generateTotpSecret, normalizeRecoveryCode, randomCode, totpCode, totpUri, verifyTotp } from './core/auth/totp';
42
+ export { generateRecoveryCodes, generateTotpSecret, normalizeRecoveryCode, randomCode, totpCode, totpStep, totpUri, verifyTotp } from './core/auth/totp';
40
43
  export type { Auth, AuthConfig } from './core/auth/createAuth';
41
- export type { AccountAccess, AccountAdapters, AccountQuery, AccountRecord, AccountStatus, AuthApi, AuthApiConfig, AuthOutcome, ExchangeResult, MfaRecord, PasswordPolicy, SecurityEvent, SessionClient, SessionContext, SessionSummary, ThrottleAttempt, ThrottledAction } from './core/auth/api';
44
+ export type { AccountAccess, AccountAdapters, AccountQuery, AccountRecord, AccountStatus, AuthApi, AuthApiConfig, AuthOutcome, ExchangeResult, MfaRecord, PasswordPolicy, SecurityEvent, SessionApp, SessionClient, SessionContext, SessionSummary, ThrottleAttempt, ThrottledAction } from './core/auth/api';
42
45
  export type { AuthPolicy, AuthorizeResult, Authorizer, MembershipFacts, PathMatcher, PermissionCheck, Requirement, SpaceAccessCheck } from './core/auth/authorize';
43
46
  export type { CredentialCarrier } from './core/auth/credentials';
44
47
  export type { Csrf, CsrfCarrier, CsrfConfig, CsrfFailure, CsrfResult, CsrfSubject } from './core/auth/csrf';
45
48
  export type { Actor, ActorResult, Grant, GrantOptions, GrantResult, Identity, IdentityAdapters, IdentityConfig, SpaceMembership, StoredSpaceToken } from './core/auth/identity';
46
49
  export type { CompletedFlow, OAuthFailureReason, OAuthProfile, OAuthProvider, OAuthProviderConfig, SocialAuth, SocialAuthAdapters, SocialAuthConfig, StartedFlow } from './core/auth/oauth';
47
50
  export type { AuthRequest, AuthRoute } from './core/auth/routes';
48
- export type { CookieCarrier, CookieSink, SessionCookieParams, SessionCookies } from './core/auth/session';
51
+ export type { CookieCarrier, CookieSink, SessionCookieParams, SessionCookies, SessionHint } from './core/auth/session';
49
52
  export type { SpaceTokenAdapters, SpaceTokenApi, SpaceTokenContext, SpaceTokenOutcome, SpaceTokenRecord, SpaceTokenSummary } from './core/auth/spaceTokens';
50
53
  export type { AuthFailure, MfaChallengePayload, RefreshTokenPayload, SpaceScope, SpaceTokenOptions, SpaceTokenPayload, TokenConfig, TokenScope, Tokens, UserTokenOptions, UserTokenPayload, VerifyResult, WidgetTokenPayload } from './core/auth/tokens';
package/dist/auth.js CHANGED
@@ -1,19 +1,21 @@
1
- import { appendCookies, clearFlowCookie, clearSessionCookies, createSessionCookies, isLocalHost, readFlowCookie, readRefreshToken, readSessionToken, sessionCookieParams, sessionHintValue, writeFlowCookie, writeSessionCookies } from "./core/auth/session.js";
1
+ import { appendCookies, clearFlowCookie, clearSessionCookies, createSessionCookies, isLocalHost, parseSessionHint, readFlowCookie, readRefreshToken, readSessionHint, readSessionToken, sessionCookieParams, sessionHintValue, sessionReturnTarget, writeFlowCookie, writeSessionCookies } from "./core/auth/session.js";
2
+ import { createCsrf, csrfFailureMessage } from "./core/auth/csrf.js";
3
+ import { applySessionOutcome, authPolicyRules, authRoutes } from "./core/auth/routes.js";
4
+ import { isDocumentNavigation, renewForNavigation } from "./core/auth/renewal.js";
5
+ import { createCarriers, presentedOrigin } from "./core/auth/credentials.js";
2
6
  import { ANY_DOMAIN, corsOrigins, domainAllowed, frameAncestors, hostnameOf, normalizeDomain } from "./core/auth/domains.js";
3
7
  import { checkPermission, checkSpaceAccess, createAuthorizer, requirementFor } from "./core/auth/authorize.js";
4
8
  import { generateToken, hashPassword, verifyPassword } from "./core/auth/passwords.js";
5
9
  import { createMemoryRateLimit } from "./core/auth/throttle.js";
6
10
  import { SCOPES, authFailureMessage, createTokens, userIdOf } from "./core/auth/tokens.js";
7
- import { generateRecoveryCodes, generateTotpSecret, normalizeRecoveryCode, randomCode, totpCode, totpUri, verifyTotp } from "./core/auth/totp.js";
11
+ import { generateRecoveryCodes, generateTotpSecret, normalizeRecoveryCode, randomCode, totpCode, totpStep, totpUri, verifyTotp } from "./core/auth/totp.js";
8
12
  import { createAuthApi } from "./core/auth/api.js";
9
- import { createCarriers, presentedOrigin } from "./core/auth/credentials.js";
10
- import { createCsrf, csrfFailureMessage } from "./core/auth/csrf.js";
11
13
  import { createIdentity } from "./core/auth/identity.js";
12
- import { applySessionOutcome, authPolicyRules, authRoutes } from "./core/auth/routes.js";
13
14
  import { createAuth } from "./core/auth/createAuth.js";
15
+ import { SESSION_ACTIVITY_RESOLUTION_SECONDS, activityDue } from "./core/auth/sessionActivity.js";
14
16
  import { OAuthFailure } from "./core/auth/oauth/types.js";
15
17
  import { requestProfileJson } from "./core/auth/oauth/client.js";
16
18
  import { createRedirectPolicy } from "./core/auth/redirects.js";
17
19
  import { BUILT_IN_PROVIDERS, createSocialAuth } from "./core/auth/oauth/index.js";
18
20
  import { createSpaceTokenApi } from "./core/auth/spaceTokens.js";
19
- export { ANY_DOMAIN, BUILT_IN_PROVIDERS, OAuthFailure, SCOPES, appendCookies, applySessionOutcome, authFailureMessage, authPolicyRules, authRoutes, checkPermission, checkSpaceAccess, clearFlowCookie, clearSessionCookies, corsOrigins, createAuth, createAuthApi, createAuthorizer, createCarriers, createCsrf, createIdentity, createMemoryRateLimit, createRedirectPolicy, createSessionCookies, createSocialAuth, createSpaceTokenApi, createTokens, csrfFailureMessage, domainAllowed, frameAncestors, generateRecoveryCodes, generateToken, generateTotpSecret, hashPassword, hostnameOf, isLocalHost, normalizeDomain, normalizeRecoveryCode, presentedOrigin, randomCode, readFlowCookie, readRefreshToken, readSessionToken, requestProfileJson, requirementFor, sessionCookieParams, sessionHintValue, totpCode, totpUri, userIdOf, verifyPassword, verifyTotp, writeFlowCookie, writeSessionCookies };
21
+ export { ANY_DOMAIN, BUILT_IN_PROVIDERS, OAuthFailure, SCOPES, SESSION_ACTIVITY_RESOLUTION_SECONDS, activityDue, appendCookies, applySessionOutcome, authFailureMessage, authPolicyRules, authRoutes, checkPermission, checkSpaceAccess, clearFlowCookie, clearSessionCookies, corsOrigins, createAuth, createAuthApi, createAuthorizer, createCarriers, createCsrf, createIdentity, createMemoryRateLimit, createRedirectPolicy, createSessionCookies, createSocialAuth, createSpaceTokenApi, createTokens, csrfFailureMessage, domainAllowed, frameAncestors, generateRecoveryCodes, generateToken, generateTotpSecret, hashPassword, hostnameOf, isDocumentNavigation, isLocalHost, normalizeDomain, normalizeRecoveryCode, parseSessionHint, presentedOrigin, randomCode, readFlowCookie, readRefreshToken, readSessionHint, readSessionToken, renewForNavigation, requestProfileJson, requirementFor, sessionCookieParams, sessionHintValue, sessionReturnTarget, totpCode, totpStep, totpUri, userIdOf, verifyPassword, verifyTotp, writeFlowCookie, writeSessionCookies };
@@ -36,6 +36,16 @@ export interface AccountAccess {
36
36
  export interface SessionClient {
37
37
  userAgent?: string;
38
38
  ip?: string;
39
+ /**
40
+ * The application holding it, when it is not a browser: a native client names itself when it registers
41
+ * (`Plitzi CLI on carlos-mbp`, software `plitzi-cli`). A user agent says which browser; this says which app.
42
+ */
43
+ app?: SessionApp;
44
+ }
45
+ export interface SessionApp {
46
+ name: string;
47
+ /** A stable name for the software, the same on every machine — what a list picks an icon by. */
48
+ softwareId?: string;
39
49
  }
40
50
  /**
41
51
  * What an account is allowed to be. `inactive` is the account's own doing (deactivated, never confirmed);
@@ -47,7 +57,10 @@ export interface SessionSummary {
47
57
  id: number;
48
58
  userAgent?: string;
49
59
  ip?: string;
60
+ app?: SessionApp;
50
61
  createdAt: number;
62
+ /** When it was last used, where the store keeps it; a session never seen since it was made has none. */
63
+ lastActiveAt?: number;
51
64
  expiresAt: number;
52
65
  /** The session asking. A device list without it invites someone to revoke the one they are using. */
53
66
  current: boolean;
@@ -58,6 +71,12 @@ export interface MfaRecord {
58
71
  /** Unix seconds the enrolment was proven with a real code. Absent means started and never finished. */
59
72
  confirmedAt?: number;
60
73
  recoveryCodes?: string[];
74
+ /**
75
+ * The time step of the last code that was accepted. A code of that step or an earlier one is refused: a code is valid
76
+ * for its whole window, and one watched over a shoulder or lifted from a phishing page would otherwise sign a second
77
+ * person in within that window (RFC 6238 §5.2).
78
+ */
79
+ lastUsedStep?: number;
61
80
  }
62
81
  /** Something worth writing down. Fed to an audit log, a webhook, a SIEM — whatever the deployment has. */
63
82
  export interface SecurityEvent {
@@ -138,6 +157,15 @@ export interface AccountAdapters {
138
157
  * session, which deleting the account's sessions does.
139
158
  */
140
159
  deleteAccount?: (userId: number) => Promise<void>;
160
+ /**
161
+ * What would be lost if this account were deleted now, in sentences its owner can act on — "“Studio” has 3 spaces;
162
+ * delete them or make somebody else an owner". Any at all and the deletion is refused, with the list.
163
+ *
164
+ * The account is what holds things a deployment cannot simply drop: a workspace nobody else owns, the spaces in it,
165
+ * a plan still being paid for. Deleting it anyway leaves them orphaned — unreachable by anyone, and possibly still
166
+ * billed. Optional, for a deployment whose accounts own nothing.
167
+ */
168
+ deletionBlockers?: (userId: number) => Promise<string[]>;
141
169
  /** Page through accounts, for an administrator. `total` is the count before the page was taken. */
142
170
  listAccounts?: (query: AccountQuery) => Promise<{
143
171
  accounts: AccountRecord[];
@@ -298,7 +326,7 @@ export interface AuthApiConfig {
298
326
  allowed: boolean;
299
327
  retryAfter?: number;
300
328
  }>;
301
- /** Where a failed delivery is reported. Defaults to `console.error`; it is never thrown — see `deliver`. */
329
+ /** Where a failed delivery is reported. Defaults to the server log at `error`; it is never thrown — see `deliver`. */
302
330
  onMailError?: (error: unknown, message: {
303
331
  to: string;
304
332
  template: string;