@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.
- package/CHANGELOG.md +1296 -0
- package/README.md +126 -7
- package/dist/actions.d.ts +20 -8
- package/dist/actions.js +11 -4
- package/dist/adapters/cloudAdapters.js +4 -3
- package/dist/adapters/jsonAdapters.js +28 -6
- package/dist/auth.d.ts +7 -4
- package/dist/auth.js +8 -6
- package/dist/core/auth/api.d.ts +29 -1
- package/dist/core/auth/api.js +47 -13
- package/dist/core/auth/createAuth.d.ts +4 -0
- package/dist/core/auth/createAuth.js +3 -3
- package/dist/core/auth/credentials.d.ts +3 -0
- package/dist/core/auth/credentials.js +1 -1
- package/dist/core/auth/csrf.d.ts +25 -1
- package/dist/core/auth/csrf.js +29 -4
- package/dist/core/auth/renewal.d.ts +26 -0
- package/dist/core/auth/renewal.js +24 -0
- package/dist/core/auth/routes.js +8 -6
- package/dist/core/auth/session.d.ts +45 -0
- package/dist/core/auth/session.js +47 -1
- package/dist/core/auth/sessionActivity.d.ts +11 -0
- package/dist/core/auth/sessionActivity.js +14 -0
- package/dist/core/auth/throttle.d.ts +15 -0
- package/dist/core/auth/throttle.js +29 -1
- package/dist/core/auth/totp.d.ts +9 -1
- package/dist/core/auth/totp.js +11 -6
- package/dist/core/createServer.actions.test.d.ts +1 -0
- package/dist/core/createServer.d.ts +14 -1
- package/dist/core/createServer.functions.test.d.ts +1 -0
- package/dist/core/createServer.js +22 -12
- package/dist/core/fontStore.js +1 -1
- package/dist/core/handlers/authRouteHandlers.d.ts +1 -1
- package/dist/core/handlers/authRouteHandlers.js +57 -21
- package/dist/core/handlers/csrfMiddleware.d.ts +23 -0
- package/dist/core/handlers/csrfMiddleware.js +31 -7
- package/dist/core/handlers/csrfMiddleware.test.d.ts +1 -0
- package/dist/core/handlers/oauthRouteHandlers.js +5 -3
- package/dist/core/handlers/socialRouteHandlers.d.ts +1 -1
- package/dist/core/handlers/socialRouteHandlers.js +2 -1
- package/dist/core/http/dispatcher.d.ts +9 -1
- package/dist/core/http/dispatcher.js +38 -11
- package/dist/core/http/navigation.d.ts +5 -2
- package/dist/core/http/navigation.js +7 -4
- package/dist/core/http/socketResponse.d.ts +18 -0
- package/dist/core/http/socketResponse.js +59 -0
- package/dist/core/http/sse.d.ts +26 -0
- package/dist/core/http/sse.js +78 -0
- package/dist/core/http/stages/authRoutes.js +3 -1
- package/dist/core/http/stages/exchangeRoute.test.d.ts +1 -0
- package/dist/core/http/stages/middlewares.d.ts +1 -1
- package/dist/core/http/stages/middlewares.js +16 -10
- package/dist/core/http/stages/middlewares.test.d.ts +1 -0
- package/dist/core/http/stages/oauth.js +2 -2
- package/dist/core/http/stages/sessionRenewal.d.ts +16 -0
- package/dist/core/http/stages/sessionRenewal.js +81 -0
- package/dist/core/http/stages/sessionRenewal.test.d.ts +1 -0
- package/dist/core/http/stages/signInRoute.d.ts +2 -0
- package/dist/core/http/stages/signInRoute.js +139 -0
- package/dist/core/http/stages/signInRoute.test.d.ts +1 -0
- package/dist/core/http/types.d.ts +9 -0
- package/dist/core/http/webExchange.d.ts +18 -0
- package/dist/core/http/webExchange.js +53 -0
- package/dist/core/oauth/authorize.js +37 -13
- package/dist/core/oauth/consentPage.js +11 -0
- package/dist/core/oauth/issueContext.d.ts +14 -0
- package/dist/core/oauth/issueContext.js +32 -0
- package/dist/core/oauth/records.d.ts +7 -0
- package/dist/core/oauth/register.d.ts +2 -0
- package/dist/core/oauth/register.js +32 -11
- package/dist/core/oauth/register.test.d.ts +1 -0
- package/dist/core/oauth/token.js +21 -6
- package/dist/core/oauth/token.test.d.ts +1 -0
- package/dist/core/requestParser.d.ts +4 -0
- package/dist/core/requestParser.js +14 -7
- package/dist/core/sdkAssets.js +1 -1
- package/dist/core/server/baseServer.d.ts +14 -1
- package/dist/core/server/baseServer.js +43 -11
- package/dist/core/server/closeOnSignals.d.ts +28 -0
- package/dist/core/server/closeOnSignals.js +47 -0
- package/dist/core/server/closeOnSignals.test.d.ts +1 -0
- package/dist/core/server/drain.d.ts +18 -0
- package/dist/core/server/drain.js +62 -0
- package/dist/core/server/drain.test.d.ts +1 -0
- package/dist/core/server/fleet/channel.d.ts +103 -0
- package/dist/core/server/fleet/channel.js +191 -0
- package/dist/core/server/fleet/channel.test.d.ts +1 -0
- package/dist/core/server/fleet/fixtures/fleetServer.d.ts +1 -0
- package/dist/core/server/fleet/fleet.integration.test.d.ts +1 -0
- package/dist/core/server/fleet/link.d.ts +23 -0
- package/dist/core/server/fleet/link.js +70 -0
- package/dist/core/server/fleet/relay.d.ts +11 -0
- package/dist/core/server/fleet/relay.js +104 -0
- package/dist/core/server/fleet/relay.test.d.ts +1 -0
- package/dist/core/server/fleet/role.d.ts +46 -0
- package/dist/core/server/fleet/role.js +59 -0
- package/dist/core/server/fleet/role.test.d.ts +1 -0
- package/dist/core/server/fleet/stores.d.ts +7 -0
- package/dist/core/server/fleet/stores.js +19 -0
- package/dist/core/server/fleet/supervisor.d.ts +26 -0
- package/dist/core/server/fleet/supervisor.js +108 -0
- package/dist/core/server/fleet/supervisor.test.d.ts +1 -0
- package/dist/core/server/pageServer.js +36 -5
- package/dist/core/services/action.js +10 -2
- package/dist/core/services/functionRoutes.d.ts +9 -0
- package/dist/core/services/functionRoutes.js +47 -0
- package/dist/core/services/realtime.d.ts +8 -0
- package/dist/core/services/realtime.js +57 -0
- package/dist/core/services/registry.js +6 -2
- package/dist/core/staticFiles.js +12 -4
- package/dist/core/staticFiles.test.d.ts +1 -0
- package/dist/core/transports.d.ts +13 -3
- package/dist/core/transports.js +14 -5
- package/dist/functions-api.d.ts +281 -0
- package/dist/functions.d.ts +19 -0
- package/dist/functions.js +5 -0
- package/dist/functionsRunner.d.ts +15 -0
- package/dist/functionsRunner.js +6 -0
- package/dist/handlers.d.ts +2 -2
- package/dist/handlers.js +2 -2
- package/dist/helpers/atomicFile.d.ts +10 -0
- package/dist/helpers/atomicFile.js +33 -0
- package/dist/helpers/atomicFile.test.d.ts +1 -0
- package/dist/helpers/buildResponseHelpers.js +35 -11
- package/dist/helpers/buildServerInfo.js +4 -2
- package/dist/helpers/buildServerInfo.test.d.ts +1 -0
- package/dist/helpers/cache/CompressedFileCache.d.ts +18 -0
- package/dist/helpers/cache/CompressedFileCache.js +44 -0
- package/dist/helpers/cache/CompressedFileCache.test.d.ts +1 -0
- package/dist/helpers/cache/cacheManager.d.ts +1 -1
- package/dist/helpers/cache/cacheManager.js +2 -1
- package/dist/helpers/cache/cacheManager.test.d.ts +1 -0
- package/dist/helpers/cache/index.d.ts +1 -1
- package/dist/helpers/cache/keys.d.ts +15 -1
- package/dist/helpers/cache/keys.js +47 -5
- package/dist/helpers/cache/serverCaches.d.ts +7 -1
- package/dist/helpers/compress.d.ts +3 -1
- package/dist/helpers/compress.js +11 -3
- package/dist/helpers/hydrationPayload.d.ts +11 -0
- package/dist/helpers/hydrationPayload.js +51 -0
- package/dist/helpers/hydrationPayload.test.d.ts +1 -0
- package/dist/helpers/metrics.d.ts +1 -1
- package/dist/helpers/metrics.js +3 -2
- package/dist/helpers/outboundGuard.d.ts +14 -6
- package/dist/helpers/outboundGuard.js +132 -8
- package/dist/helpers/paintedCookie.d.ts +8 -0
- package/dist/helpers/paintedCookie.js +13 -0
- package/dist/helpers/reportReactBuild.d.ts +9 -0
- package/dist/helpers/reportReactBuild.js +18 -0
- package/dist/helpers/reportReactBuild.test.d.ts +1 -0
- package/dist/helpers/serverLog.d.ts +25 -1
- package/dist/helpers/serverLog.js +68 -3
- package/dist/helpers/serverLog.test.d.ts +1 -0
- package/dist/helpers/wsFrame.d.ts +3 -0
- package/dist/helpers/wsFrame.js +5 -0
- package/dist/index.d.ts +8 -1
- package/dist/index.js +6 -2
- package/dist/kernel.d.ts +2 -1
- package/dist/kernel.js +3 -2
- package/dist/modules/actions/connectorWrite.js +2 -1
- package/dist/modules/actions/index.d.ts +41 -13
- package/dist/modules/actions/index.js +52 -9
- package/dist/modules/actions/jobs/failureStreak.d.ts +17 -0
- package/dist/modules/actions/jobs/failureStreak.js +47 -0
- package/dist/modules/actions/jobs/failureStreak.test.d.ts +1 -0
- package/dist/modules/actions/jobs/index.d.ts +33 -0
- package/dist/modules/actions/jobs/index.js +59 -0
- package/dist/modules/actions/jobs/memoryQueue.d.ts +33 -0
- package/dist/modules/actions/jobs/memoryQueue.js +194 -0
- package/dist/modules/actions/jobs/memoryStores.test.d.ts +1 -0
- package/dist/modules/actions/jobs/scheduler.d.ts +64 -0
- package/dist/modules/actions/jobs/scheduler.js +130 -0
- package/dist/modules/actions/jobs/scheduler.test.d.ts +1 -0
- package/dist/modules/actions/jobs/schedules.d.ts +23 -0
- package/dist/modules/actions/jobs/schedules.js +47 -0
- package/dist/modules/actions/jobs/storeClock.d.ts +16 -0
- package/dist/modules/actions/jobs/storeClock.js +32 -0
- package/dist/modules/actions/jobs/testing/jobQueueContract.d.ts +25 -0
- package/dist/modules/actions/jobs/worker.d.ts +64 -0
- package/dist/modules/actions/jobs/worker.js +267 -0
- package/dist/modules/actions/jobs/worker.test.d.ts +1 -0
- package/dist/modules/actions/moduleFor.js +6 -2
- package/dist/modules/actions/runtime/errors.d.ts +12 -0
- package/dist/modules/actions/runtime/errors.js +16 -1
- package/dist/modules/actions/runtime/kvChange.d.ts +27 -0
- package/dist/modules/actions/runtime/kvChange.js +23 -0
- package/dist/modules/actions/runtime/kvList.d.ts +51 -0
- package/dist/modules/actions/runtime/kvList.js +52 -0
- package/dist/modules/actions/runtime/kvStore.d.ts +8 -0
- package/dist/modules/actions/runtime/kvStore.js +46 -20
- package/dist/modules/actions/runtime/memoryKv.d.ts +3 -0
- package/dist/modules/actions/runtime/memoryKv.js +19 -1
- package/dist/modules/actions/runtime/namespaceKv.d.ts +4 -6
- package/dist/modules/actions/runtime/namespaceKv.js +15 -3
- package/dist/modules/actions/runtime/namespaceKv.test.d.ts +1 -0
- package/dist/modules/actions/runtime/precheck.js +5 -9
- package/dist/modules/actions/runtime/rateLimit.d.ts +19 -0
- package/dist/modules/actions/runtime/rateLimit.js +19 -0
- package/dist/modules/actions/runtime/redisKv.d.ts +27 -0
- package/dist/modules/actions/runtime/redisKv.integration.test.d.ts +1 -0
- package/dist/modules/actions/runtime/redisKv.js +46 -0
- package/dist/modules/actions/runtime/renderResolver.js +2 -2
- package/dist/modules/actions/runtime/report.js +2 -1
- package/dist/modules/actions/runtime/runAction.d.ts +10 -2
- package/dist/modules/actions/runtime/runAction.js +52 -116
- package/dist/modules/actions/runtime/runLogger.d.ts +5 -0
- package/dist/modules/actions/runtime/runLogger.js +8 -2
- package/dist/modules/actions/runtime/signing.d.ts +20 -0
- package/dist/modules/actions/runtime/signing.js +25 -0
- package/dist/modules/actions/runtime/signing.test.d.ts +1 -0
- package/dist/modules/actions/runtime/taskContext.d.ts +33 -0
- package/dist/modules/actions/runtime/taskContext.js +124 -0
- package/dist/modules/actions/tasks/builtins.js +5 -1
- package/dist/modules/actions/tasks/flow.js +81 -10
- package/dist/modules/actions/tasks/helpers.js +2 -2
- package/dist/modules/actions/tasks/http.js +2 -3
- package/dist/modules/actions/tasks/kv.js +39 -0
- package/dist/modules/actions/tasks/list.d.ts +2 -0
- package/dist/modules/actions/tasks/list.js +145 -0
- package/dist/modules/actions/tasks/realtime.d.ts +2 -0
- package/dist/modules/actions/tasks/realtime.js +104 -0
- package/dist/modules/actions/tasks/registry.d.ts +10 -1
- package/dist/modules/actions/tasks/registry.js +17 -6
- package/dist/modules/actions/transport/callHandler.js +6 -3
- package/dist/modules/actions/transport/catalogHandler.d.ts +5 -2
- package/dist/modules/actions/transport/catalogHandler.js +3 -2
- package/dist/modules/actions/transport/stream.d.ts +4 -5
- package/dist/modules/actions/transport/stream.js +12 -76
- package/dist/modules/actions/transport/webhookHandler.js +5 -4
- package/dist/modules/actions/types.d.ts +162 -4
- package/dist/modules/connectors/engine.js +3 -5
- package/dist/modules/functions/build.d.ts +22 -0
- package/dist/modules/functions/build.js +122 -0
- package/dist/modules/functions/build.test.d.ts +1 -0
- package/dist/modules/functions/capabilities.d.ts +22 -0
- package/dist/modules/functions/capabilities.js +228 -0
- package/dist/modules/functions/config.d.ts +34 -0
- package/dist/modules/functions/config.js +24 -0
- package/dist/modules/functions/context.d.ts +17 -0
- package/dist/modules/functions/context.js +88 -0
- package/dist/modules/functions/contract.d.ts +121 -0
- package/dist/modules/functions/contract.js +9 -0
- package/dist/modules/functions/driver.d.ts +36 -0
- package/dist/modules/functions/driver.js +150 -0
- package/dist/modules/functions/load.d.ts +15 -0
- package/dist/modules/functions/load.js +45 -0
- package/dist/modules/functions/load.test.d.ts +1 -0
- package/dist/modules/functions/local.d.ts +29 -0
- package/dist/modules/functions/local.js +61 -0
- package/dist/modules/functions/local.test.d.ts +1 -0
- package/dist/modules/functions/manifest.d.ts +24 -0
- package/dist/modules/functions/manifest.js +163 -0
- package/dist/modules/functions/manifest.test.d.ts +1 -0
- package/dist/modules/functions/native.d.ts +8 -0
- package/dist/modules/functions/native.js +21 -0
- package/dist/modules/functions/native.test.d.ts +1 -0
- package/dist/modules/functions/protocol.d.ts +216 -0
- package/dist/modules/functions/protocol.js +18 -0
- package/dist/modules/functions/routes.d.ts +36 -0
- package/dist/modules/functions/routes.js +181 -0
- package/dist/modules/functions/routes.test.d.ts +1 -0
- package/dist/modules/functions/runner/messages.d.ts +5 -0
- package/dist/modules/functions/runner/messages.js +188 -0
- package/dist/modules/functions/runner/remote.d.ts +19 -0
- package/dist/modules/functions/runner/remote.js +116 -0
- package/dist/modules/functions/runner/remote.test.d.ts +1 -0
- package/dist/modules/functions/runner/service.d.ts +32 -0
- package/dist/modules/functions/runner/service.js +209 -0
- package/dist/modules/functions/sandbox/guest.d.ts +45 -0
- package/dist/modules/functions/sandbox/guest.js +660 -0
- package/dist/modules/functions/sandbox/isolate.d.ts +37 -0
- package/dist/modules/functions/sandbox/isolate.js +347 -0
- package/dist/modules/functions/sandbox/isolate.test.d.ts +1 -0
- package/dist/modules/functions/sandbox/prelude.d.ts +2 -0
- package/dist/modules/functions/sandbox/prelude.js +49 -0
- package/dist/modules/functions/space.d.ts +40 -0
- package/dist/modules/functions/space.js +162 -0
- package/dist/modules/functions/testing/tasksOf.d.ts +4 -0
- package/dist/modules/functions/tryEntry.d.ts +9 -0
- package/dist/modules/functions/tryEntry.js +49 -0
- package/dist/modules/mongo/index.d.ts +4 -0
- package/dist/modules/mongo/jobQueue.d.ts +38 -0
- package/dist/modules/mongo/jobQueue.js +335 -0
- package/dist/modules/mongo/kv.d.ts +15 -0
- package/dist/modules/mongo/kv.js +129 -0
- package/dist/modules/mongo/stores.integration.test.d.ts +1 -0
- package/dist/modules/mysql/accounts.js +19 -9
- package/dist/modules/mysql/index.d.ts +2 -1
- package/dist/modules/mysql/jobs/index.d.ts +5 -0
- package/dist/modules/mysql/jobs/jobQueue.d.ts +40 -0
- package/dist/modules/mysql/jobs/jobQueue.js +375 -0
- package/dist/modules/mysql/jobs/kv.d.ts +18 -0
- package/dist/modules/mysql/jobs/kv.js +108 -0
- package/dist/modules/mysql/jobs/schema.d.ts +33 -0
- package/dist/modules/mysql/jobs/schema.js +113 -0
- package/dist/modules/mysql/jobs/stores.integration.test.d.ts +1 -0
- package/dist/modules/mysql/schema.js +25 -0
- package/dist/modules/mysql/sessions.d.ts +1 -11
- package/dist/modules/mysql/sessions.js +6 -1
- package/dist/modules/realtime/declarations.d.ts +11 -0
- package/dist/modules/realtime/declarations.js +26 -0
- package/dist/modules/realtime/grants.d.ts +23 -0
- package/dist/modules/realtime/grants.js +61 -0
- package/dist/modules/realtime/handlers.d.ts +74 -0
- package/dist/modules/realtime/handlers.js +224 -0
- package/dist/modules/realtime/hub.d.ts +62 -0
- package/dist/modules/realtime/hub.js +141 -0
- package/dist/modules/realtime/index.d.ts +51 -0
- package/dist/modules/realtime/index.js +62 -0
- package/dist/modules/realtime/memoryPubSub.d.ts +10 -0
- package/dist/modules/realtime/memoryPubSub.js +43 -0
- package/dist/modules/realtime/realtime.test.d.ts +1 -0
- package/dist/modules/realtime/redisPubSub.d.ts +24 -0
- package/dist/modules/realtime/redisPubSub.js +36 -0
- package/dist/modules/realtime/redisPubSub.test.d.ts +1 -0
- package/dist/modules/realtime/socket.d.ts +25 -0
- package/dist/modules/realtime/socket.js +122 -0
- package/dist/modules/realtime/socket.test.d.ts +1 -0
- package/dist/modules/rsc/handler.d.ts +16 -0
- package/dist/modules/rsc/handler.js +17 -10
- package/dist/modules/rsc/handler.test.d.ts +1 -0
- package/dist/modules/rsc/resolveRscData.js +2 -1
- package/dist/modules/runtime/bundle.d.ts +24 -0
- package/dist/modules/runtime/bundle.js +102 -0
- package/dist/modules/runtime/contract.d.ts +37 -0
- package/dist/modules/runtime/contract.js +21 -0
- package/dist/modules/runtime/entry.test.d.ts +1 -0
- package/dist/modules/runtime/host.d.ts +38 -0
- package/dist/modules/runtime/host.js +68 -0
- package/dist/modules/runtime/inside.d.ts +15 -0
- package/dist/modules/runtime/inside.js +47 -0
- package/dist/modules/runtime/inside.test.d.ts +1 -0
- package/dist/modules/runtime/runner.d.ts +11 -0
- package/dist/modules/runtime/runner.js +38 -0
- package/dist/modules/runtime/runtime.test.d.ts +1 -0
- package/dist/modules/runtime/stages.d.ts +50 -0
- package/dist/modules/runtime/stages.js +117 -0
- package/dist/modules/ssr/Component.d.ts +4 -5
- package/dist/modules/ssr/Component.js +2 -2
- package/dist/modules/ssr/handler.js +10 -2
- package/dist/modules/ssr/loadPluginComponents.js +2 -1
- package/dist/modules/ssr/prepareRender.js +39 -13
- package/dist/modules/ssr/preview.d.ts +3 -0
- package/dist/modules/ssr/preview.js +17 -7
- package/dist/modules/ssr/redirect.test.d.ts +1 -0
- package/dist/modules/ssr/registerExternalPlugins.d.ts +6 -1
- package/dist/modules/ssr/registerExternalPlugins.js +19 -16
- package/dist/modules/ssr/registerExternalPlugins.test.d.ts +1 -0
- package/dist/modules/ssr/reportMissingPlugins.d.ts +9 -0
- package/dist/modules/ssr/reportMissingPlugins.js +24 -0
- package/dist/modules/ssr/reportMissingPlugins.test.d.ts +1 -0
- package/dist/modules/ssr/streamBody.d.ts +2 -2
- package/dist/modules/ssr/streamBody.js +4 -1
- package/dist/modules/ssr/template.js +1 -1
- package/dist/modules/ssr/views/template.ejs +8 -5
- package/dist/mongo.d.ts +25 -0
- package/dist/mongo.js +3 -0
- package/dist/mysql.d.ts +11 -0
- package/dist/mysql.js +4 -1
- package/dist/oauth.js +2 -2
- package/dist/plugins/compile.js +9 -4
- package/dist/plugins/copy.js +3 -3
- package/dist/plugins/manager.d.ts +35 -3
- package/dist/plugins/manager.js +109 -38
- package/dist/runtime.d.ts +15 -0
- package/dist/runtime.js +7 -0
- package/package.json +52 -11
- package/skills/plitzi-authoring/SKILL.md +153 -263
- package/skills/plitzi-authoring/reference/accessibility.md +111 -0
- package/skills/plitzi-authoring/reference/authoring-errors.md +70 -0
- package/skills/plitzi-authoring/reference/data-and-visibility.md +180 -0
- package/skills/plitzi-authoring/reference/elements-and-styles.md +161 -0
- package/skills/plitzi-authoring/reference/flows.md +171 -0
- package/skills/plitzi-authoring/reference/layouts.md +140 -0
- package/skills/plitzi-authoring/reference/lists.md +74 -0
- package/skills/plitzi-authoring/reference/performance.md +67 -0
- package/skills/plitzi-authoring/reference/plugins.md +167 -0
- package/skills/plitzi-authoring/reference/review-checklist.md +67 -0
- package/skills/plitzi-authoring/reference/structure.md +83 -0
- package/skills/plitzi-authoring/reference/templates-and-export.md +54 -0
- package/skills/plitzi-authoring/reference/templates.md +109 -0
- package/skills/plitzi-authoring/reference/testing.md +119 -0
- package/skills/plitzi-authoring/reference/validation.md +73 -0
- package/dist/modules/actions/runtime/schedule.d.ts +0 -35
- package/dist/modules/actions/runtime/schedule.js +0 -76
- /package/dist/{modules/actions/runtime/schedule.test.d.ts → adapters/jsonAdapters.test.d.ts} +0 -0
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
import { builtinTasks } from "./builtins.js";
|
|
2
2
|
import { dbTasks } from "./db.js";
|
|
3
|
+
import { nativeTasks } from "../../functions/native.js";
|
|
3
4
|
//#region src/modules/actions/tasks/registry.ts
|
|
4
5
|
var NAME_PATTERN = /^[a-z][a-zA-Z0-9]*$/;
|
|
5
6
|
var taskName = (task) => `${task.namespace}.${task.action}`;
|
|
6
|
-
|
|
7
|
+
/** The namespaces the platform's own tasks use: nobody else's task may take one. */
|
|
8
|
+
var RESERVED_NAMESPACES = new Set([...builtinTasks, ...dbTasks].map((task) => task.namespace));
|
|
9
|
+
/**
|
|
10
|
+
* What is wrong with a task's name, or nothing — one rule for a deployment's tasks at boot and a space's own when its
|
|
11
|
+
* functions are built. A malformed name is unreachable from any document; one in a namespace taken by another task
|
|
12
|
+
* set silently changes what every action using that set does.
|
|
13
|
+
*/
|
|
14
|
+
var taskNameProblem = (task, reserved = RESERVED_NAMESPACES) => {
|
|
15
|
+
if (!NAME_PATTERN.test(task.namespace) || !NAME_PATTERN.test(task.action)) return `Invalid task name "${taskName(task)}": expected camelCase namespace and action`;
|
|
16
|
+
if (reserved.has(task.namespace)) return `Namespace "${task.namespace}" is reserved by another task set`;
|
|
17
|
+
};
|
|
7
18
|
/**
|
|
8
19
|
* Builds the set of tasks this server can run.
|
|
9
20
|
*
|
|
@@ -11,15 +22,15 @@ var reservedNamespaces = new Set([...builtinTasks, ...dbTasks].map((task) => tas
|
|
|
11
22
|
* name is unreachable from any document, and one shadowing a built-in silently changes what every existing action
|
|
12
23
|
* in that deployment does. Both are invisible until a run misbehaves in production.
|
|
13
24
|
*/
|
|
14
|
-
var createTaskRegistry = (
|
|
25
|
+
var createTaskRegistry = (functions = [], { db = false } = {}) => {
|
|
15
26
|
const tasks = /* @__PURE__ */ new Map();
|
|
16
27
|
(db ? [...builtinTasks, ...dbTasks] : builtinTasks).forEach((task) => tasks.set(taskName(task), {
|
|
17
28
|
...task,
|
|
18
29
|
name: taskName(task)
|
|
19
30
|
}));
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if (
|
|
31
|
+
nativeTasks(functions).forEach((task) => {
|
|
32
|
+
const problem = taskNameProblem(task);
|
|
33
|
+
if (problem) throw new Error(`[Actions] ${problem}`);
|
|
23
34
|
const name = taskName(task);
|
|
24
35
|
if (tasks.has(name)) throw new Error(`[Actions] Task "${name}" is registered twice`);
|
|
25
36
|
tasks.set(name, {
|
|
@@ -33,4 +44,4 @@ var createTaskRegistry = (custom = [], { db = false } = {}) => {
|
|
|
33
44
|
};
|
|
34
45
|
};
|
|
35
46
|
//#endregion
|
|
36
|
-
export { createTaskRegistry, taskName };
|
|
47
|
+
export { RESERVED_NAMESPACES, createTaskRegistry, taskName, taskNameProblem };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { serverLog } from "../../../helpers/serverLog.js";
|
|
2
2
|
import { triggerParams } from "../runtime/triggers.js";
|
|
3
|
+
import { ActionRunError } from "../runtime/errors.js";
|
|
3
4
|
import { precheckRun } from "../runtime/precheck.js";
|
|
4
5
|
import onAbort from "../../../helpers/onAbort.js";
|
|
5
6
|
import { openStream, wantsStream } from "./stream.js";
|
|
@@ -215,6 +216,7 @@ var handleActionCall = async (deps) => {
|
|
|
215
216
|
runId: result.runId,
|
|
216
217
|
status: result.status,
|
|
217
218
|
output: result.output,
|
|
219
|
+
...result.error === void 0 ? {} : { error: result.error },
|
|
218
220
|
...outline ? { steps: result.steps } : {}
|
|
219
221
|
}
|
|
220
222
|
});
|
|
@@ -224,7 +226,8 @@ var handleActionCall = async (deps) => {
|
|
|
224
226
|
const payload = {
|
|
225
227
|
runId: result.runId,
|
|
226
228
|
status: result.status,
|
|
227
|
-
output: result.output
|
|
229
|
+
output: result.output,
|
|
230
|
+
...result.error === void 0 ? {} : { error: result.error }
|
|
228
231
|
};
|
|
229
232
|
if (outline) payload.steps = result.steps;
|
|
230
233
|
if (fullTrace) payload.trace = result.trace;
|
|
@@ -232,7 +235,7 @@ var handleActionCall = async (deps) => {
|
|
|
232
235
|
} catch (error) {
|
|
233
236
|
const reason = error instanceof ActionRunError ? error.reason : "failed";
|
|
234
237
|
const message = error instanceof ActionRunError ? error.message : "Action failed";
|
|
235
|
-
if (!(error instanceof ActionRunError))
|
|
238
|
+
if (!(error instanceof ActionRunError)) serverLog.error("Actions", "run failed", error);
|
|
236
239
|
const steps = error instanceof ActionRunError && error.steps && await showsOutline() ? error.steps : void 0;
|
|
237
240
|
if (stream) {
|
|
238
241
|
stream.send({
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { ActionsModule } from '../index';
|
|
2
|
-
import { SSRResponseHelpers } from '@plitzi/sdk-shared';
|
|
2
|
+
import { SpaceRevision, SSRResponseHelpers } from '@plitzi/sdk-shared';
|
|
3
3
|
export type ActionCatalogDeps = {
|
|
4
4
|
res: SSRResponseHelpers;
|
|
5
5
|
module: ActionsModule;
|
|
6
|
+
/** The space asking, as of the revision it is serving: its own functions are part of what it can run. */
|
|
7
|
+
spaceId?: number;
|
|
8
|
+
at?: SpaceRevision;
|
|
6
9
|
};
|
|
7
10
|
/**
|
|
8
11
|
* Serves the tasks this server can run.
|
|
@@ -15,4 +18,4 @@ export type ActionCatalogDeps = {
|
|
|
15
18
|
* Session-gated by the pipeline: the catalog names a deployment's server-side capabilities, which is not something
|
|
16
19
|
* to hand an anonymous visitor.
|
|
17
20
|
*/
|
|
18
|
-
export declare const handleActionCatalog: ({ res, module }: ActionCatalogDeps) => void
|
|
21
|
+
export declare const handleActionCatalog: ({ res, module, spaceId, at }: ActionCatalogDeps) => Promise<void>;
|
|
@@ -11,11 +11,12 @@ import { describeCatalog } from "../taskCatalog.js";
|
|
|
11
11
|
* Session-gated by the pipeline: the catalog names a deployment's server-side capabilities, which is not something
|
|
12
12
|
* to hand an anonymous visitor.
|
|
13
13
|
*/
|
|
14
|
-
var handleActionCatalog = ({ res, module }) => {
|
|
14
|
+
var handleActionCatalog = async ({ res, module, spaceId, at }) => {
|
|
15
|
+
const registry = spaceId === void 0 ? module.registry : await module.registryFor(spaceId, at);
|
|
15
16
|
res.setStatus(200);
|
|
16
17
|
res.setHeader("Content-Type", "application/json; charset=utf-8");
|
|
17
18
|
res.setHeader("Cache-Control", "no-store");
|
|
18
|
-
res.send(JSON.stringify({ tasks: describeCatalog(
|
|
19
|
+
res.send(JSON.stringify({ tasks: describeCatalog(registry) }));
|
|
19
20
|
};
|
|
20
21
|
//#endregion
|
|
21
22
|
export { handleActionCatalog };
|
|
@@ -10,12 +10,11 @@ export type ActionStream = {
|
|
|
10
10
|
isOpen: () => boolean;
|
|
11
11
|
};
|
|
12
12
|
/**
|
|
13
|
-
* Opens a Server-Sent Events response.
|
|
13
|
+
* Opens a run's Server-Sent Events response.
|
|
14
14
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* until its buffer fills and turns a live stream into one late burst.
|
|
15
|
+
* The run's id travels on the response head rather than in a frame: a streaming step returns as soon as the stream
|
|
16
|
+
* OPENS — that is what makes it a stream — so anything it learns from a frame arrives after the flow has already
|
|
17
|
+
* carried on. The head is the one place a caller can read the id in time to cancel the run it just started.
|
|
19
18
|
*/
|
|
20
19
|
export declare const openStream: (raw: RawResponse, onAbort: () => void, runId: string) => ActionStream;
|
|
21
20
|
/** Whether this caller asked for a stream. The negotiation is the client's, so a page that cannot read one never
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
+
import { openEventStream } from "../../../core/http/sse.js";
|
|
1
2
|
//#region src/modules/actions/transport/stream.ts
|
|
2
|
-
/** How often a comment frame goes out. Short enough that a dead peer is noticed in seconds, long enough that an
|
|
3
|
-
* idle stream costs nothing worth counting. */
|
|
4
|
-
var HEARTBEAT_MS = 15e3;
|
|
5
3
|
/**
|
|
6
4
|
* How long a hand-rolled `EventSource` waits before reconnecting, if one ever gets here.
|
|
7
5
|
*
|
|
@@ -11,84 +9,22 @@ var HEARTBEAT_MS = 15e3;
|
|
|
11
9
|
*/
|
|
12
10
|
var RETRY_MS = 864e5;
|
|
13
11
|
/**
|
|
14
|
-
*
|
|
12
|
+
* Opens a run's Server-Sent Events response.
|
|
15
13
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*/
|
|
20
|
-
var MAX_BUFFERED_BYTES = 1e6;
|
|
21
|
-
var encode = (frame) => `event: ${frame.event}\ndata: ${JSON.stringify(frame.data)}\n\n`;
|
|
22
|
-
/** What the host has written but not yet handed to the socket. Node's own response reports it; the minimum raw
|
|
23
|
-
* response this server accepts does not have to, and a host that cannot say simply never trips the cap. */
|
|
24
|
-
var bufferedBytes = (raw) => {
|
|
25
|
-
const { writableLength } = raw;
|
|
26
|
-
return typeof writableLength === "number" ? writableLength : 0;
|
|
27
|
-
};
|
|
28
|
-
/**
|
|
29
|
-
* Opens a Server-Sent Events response.
|
|
30
|
-
*
|
|
31
|
-
* Written straight to the RAW response, never through the response helpers: those compress the body, set a
|
|
32
|
-
* Content-Length and end it in one go, which is precisely what a stream cannot do. `no-transform` says the same
|
|
33
|
-
* thing to every proxy in between, and `X-Accel-Buffering: no` says it to nginx, which otherwise holds frames
|
|
34
|
-
* until its buffer fills and turns a live stream into one late burst.
|
|
14
|
+
* The run's id travels on the response head rather than in a frame: a streaming step returns as soon as the stream
|
|
15
|
+
* OPENS — that is what makes it a stream — so anything it learns from a frame arrives after the flow has already
|
|
16
|
+
* carried on. The head is the one place a caller can read the id in time to cancel the run it just started.
|
|
35
17
|
*/
|
|
36
18
|
var openStream = (raw, onAbort, runId) => {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
"
|
|
40
|
-
|
|
41
|
-
Connection: "keep-alive",
|
|
42
|
-
"X-Accel-Buffering": "no",
|
|
43
|
-
/**
|
|
44
|
-
* The run's id, on the response head rather than in a frame.
|
|
45
|
-
*
|
|
46
|
-
* A streaming step returns as soon as the stream OPENS — that is what makes it a stream — so anything it
|
|
47
|
-
* learns from a frame arrives after the flow has already carried on. The head is the one place a caller can
|
|
48
|
-
* read the id in time to cancel the run it just started.
|
|
49
|
-
*/
|
|
50
|
-
"X-Plitzi-Run-Id": runId
|
|
19
|
+
const stream = openEventStream(raw, {
|
|
20
|
+
onAbort,
|
|
21
|
+
headers: { "X-Plitzi-Run-Id": runId },
|
|
22
|
+
retryMs: RETRY_MS
|
|
51
23
|
});
|
|
52
|
-
raw.write(`retry: ${RETRY_MS}\n\n`);
|
|
53
|
-
const heartbeat = setInterval(() => {
|
|
54
|
-
if (!open) return;
|
|
55
|
-
try {
|
|
56
|
-
raw.write(": ping\n\n");
|
|
57
|
-
} catch {
|
|
58
|
-
open = false;
|
|
59
|
-
clearInterval(heartbeat);
|
|
60
|
-
onAbort();
|
|
61
|
-
}
|
|
62
|
-
}, HEARTBEAT_MS);
|
|
63
|
-
const close = () => {
|
|
64
|
-
if (!open) return;
|
|
65
|
-
open = false;
|
|
66
|
-
clearInterval(heartbeat);
|
|
67
|
-
try {
|
|
68
|
-
raw.end();
|
|
69
|
-
} catch {}
|
|
70
|
-
};
|
|
71
24
|
return {
|
|
72
|
-
send: (frame) =>
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
raw.write(encode(frame));
|
|
76
|
-
if (bufferedBytes(raw) > MAX_BUFFERED_BYTES) {
|
|
77
|
-
open = false;
|
|
78
|
-
clearInterval(heartbeat);
|
|
79
|
-
onAbort();
|
|
80
|
-
try {
|
|
81
|
-
raw.end();
|
|
82
|
-
} catch {}
|
|
83
|
-
}
|
|
84
|
-
} catch {
|
|
85
|
-
open = false;
|
|
86
|
-
clearInterval(heartbeat);
|
|
87
|
-
onAbort();
|
|
88
|
-
}
|
|
89
|
-
},
|
|
90
|
-
close,
|
|
91
|
-
isOpen: () => open
|
|
25
|
+
send: (frame) => stream.send(frame.event, frame.data),
|
|
26
|
+
close: stream.close,
|
|
27
|
+
isOpen: stream.isOpen
|
|
92
28
|
};
|
|
93
29
|
};
|
|
94
30
|
/** Whether this caller asked for a stream. The negotiation is the client's, so a page that cannot read one never
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { serverLog } from "../../../helpers/serverLog.js";
|
|
2
2
|
import { findTriggerNode, triggerParams } from "../runtime/triggers.js";
|
|
3
|
+
import { ActionRunError } from "../runtime/errors.js";
|
|
3
4
|
import { precheckRun } from "../runtime/precheck.js";
|
|
4
5
|
import onAbort from "../../../helpers/onAbort.js";
|
|
5
6
|
import { reportReject } from "../runtime/report.js";
|
|
@@ -75,7 +76,7 @@ var handleActionWebhook = async (deps) => {
|
|
|
75
76
|
* one without a single line of it changing. Fail closed, and say which document to fix.
|
|
76
77
|
*/
|
|
77
78
|
if (triggerHasStaleVerify(stepParams)) {
|
|
78
|
-
|
|
79
|
+
serverLog.error("Actions", `webhook "${actionId}" in space ${spaceId} carries a signature check in a format nothing reads any more, so it is refused. Name the signing credential on the trigger step.`);
|
|
79
80
|
await reject("unverifiable", "The signature check is in a format nothing reads any more; name the signing credential on the trigger step");
|
|
80
81
|
send(res, 503, { error: "Unavailable" });
|
|
81
82
|
return;
|
|
@@ -99,7 +100,7 @@ var handleActionWebhook = async (deps) => {
|
|
|
99
100
|
const secret = await resolveSecret(verify, spaceId, config.action?.lookups?.getCredential);
|
|
100
101
|
const check = verifySignature(verify, secret, req.headers, rawBody);
|
|
101
102
|
if (!check.ok) {
|
|
102
|
-
|
|
103
|
+
serverLog.warn("Actions", `webhook "${actionId}" rejected: ${check.reason}`);
|
|
103
104
|
await reject("invalid_signature", check.reason);
|
|
104
105
|
send(res, 401, { error: "Invalid signature" });
|
|
105
106
|
return;
|
|
@@ -182,7 +183,7 @@ var handleActionWebhook = async (deps) => {
|
|
|
182
183
|
status: result.status
|
|
183
184
|
});
|
|
184
185
|
} catch (error) {
|
|
185
|
-
|
|
186
|
+
serverLog.error("Actions", "webhook run failed", error);
|
|
186
187
|
send(res, 500, { accepted: false });
|
|
187
188
|
} finally {
|
|
188
189
|
releaseAbort();
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { ActionEmailSender } from './runtime/email';
|
|
2
|
-
import {
|
|
2
|
+
import { FunctionsConfig } from '../functions/config';
|
|
3
|
+
import { SpaceFunctions } from '../functions/protocol';
|
|
4
|
+
import { KvChangeLifetime } from './runtime/kvChange';
|
|
5
|
+
import { KvListEntry, KvListPut, KvListPutOptions, KvListRange } from './runtime/kvList';
|
|
6
|
+
import { SpaceSigning } from './runtime/signing';
|
|
7
|
+
import { ActionEmailConfig, ActionJobQueue, ActionEntry, ActionLimits, ActionRejectRecord, ActionRunRecord, ActionRunStatus, ActionRunStep, ActionTriggerType, ConnectorManifest, Environment, InteractionCallbackParam, InteractionNode, InteractionNodeStatus, SpaceRevision, SSRUser } from '@plitzi/sdk-shared';
|
|
3
8
|
/** Resolved secret material, as the connector engine already models it. */
|
|
4
9
|
export type ActionCredential = Record<string, string>;
|
|
5
10
|
/**
|
|
@@ -31,7 +36,7 @@ export type ActionDbDriver = {
|
|
|
31
36
|
/**
|
|
32
37
|
* Where a deployment keeps the `kv` tasks' data — Redis, Memcached, a table, whatever it already runs.
|
|
33
38
|
*
|
|
34
|
-
* Deliberately the DUMBEST possible surface:
|
|
39
|
+
* Deliberately the DUMBEST possible surface: six operations over strings, with no rule to obey. Everything that
|
|
35
40
|
* decides how a counter behaves — the key prefixing, the JSON round trip, and the one rule a rate limit lives or
|
|
36
41
|
* dies by — is `createKvStore`'s, above this. An adapter that had to remember "extend the TTL only when the
|
|
37
42
|
* counter did not exist" would be an adapter each deployment gets to write that rule wrongly in.
|
|
@@ -48,6 +53,12 @@ export type ActionKvAdapter = {
|
|
|
48
53
|
increment: (key: string, amount: number) => Promise<number>;
|
|
49
54
|
/** Sets a lifetime on a key that already exists. When to call it is decided above, never here. */
|
|
50
55
|
expire: (key: string, ttlSeconds: number) => Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Writes `next` only if the key still holds `expected` — or, with `expected` undefined, only if it holds nothing (a
|
|
58
|
+
* key past its lifetime holds nothing). Answers whether it wrote. Must be atomic: it is what lets two writers
|
|
59
|
+
* read, change and write the same value without one of them silently undoing the other.
|
|
60
|
+
*/
|
|
61
|
+
swap: (key: string, expected: string | undefined, next: string, ttlSeconds?: number) => Promise<boolean>;
|
|
51
62
|
};
|
|
52
63
|
/**
|
|
53
64
|
* The `kv` tasks' own view: values rather than strings, and a TTL that means what a caller expects.
|
|
@@ -60,6 +71,27 @@ export type ActionKvStore = {
|
|
|
60
71
|
set: (key: string, value: unknown, ttlSeconds?: number) => Promise<void>;
|
|
61
72
|
delete: (key: string) => Promise<void>;
|
|
62
73
|
increment: (key: string, amount: number, ttlSeconds?: number) => Promise<number>;
|
|
74
|
+
/**
|
|
75
|
+
* Writes `next` only if the key still holds `expected` — the value `get` answered — or, with `expected` undefined,
|
|
76
|
+
* only if it holds nothing. Answers whether it wrote: read, change, and write back with this, and a writer that
|
|
77
|
+
* lost the race is told so instead of undoing the other.
|
|
78
|
+
*/
|
|
79
|
+
swap: (key: string, expected: unknown, next: unknown, ttlSeconds?: number) => Promise<boolean>;
|
|
80
|
+
/**
|
|
81
|
+
* Puts `entry` in the list — replacing the one with its id — keeping the highest `keep` by score, and answers what
|
|
82
|
+
* that dropped, for whatever it named to be let go of too. A list has no lifetime: it lives until its entries are
|
|
83
|
+
* removed.
|
|
84
|
+
*/
|
|
85
|
+
listPut: (list: string, entry: KvListEntry, options?: KvListPutOptions) => Promise<KvListPut>;
|
|
86
|
+
listRange: (list: string, range?: KvListRange) => Promise<KvListEntry[]>;
|
|
87
|
+
/** Takes the entry with `id` out of the list, and answers whether it was there. */
|
|
88
|
+
listRemove: (list: string, id: string) => Promise<boolean>;
|
|
89
|
+
/**
|
|
90
|
+
* Reads the key, hands its value to `change` and writes back what that answers — reading and asking again when
|
|
91
|
+
* somebody wrote in between, so no writer undoes another. `change` answering `undefined` writes nothing. Answers what
|
|
92
|
+
* was written. `lifetime` is seconds, or worked out from the value written.
|
|
93
|
+
*/
|
|
94
|
+
change: <T>(key: string, change: (current: unknown) => T | undefined | Promise<T | undefined>, lifetime?: KvChangeLifetime<T>) => Promise<T | undefined>;
|
|
63
95
|
};
|
|
64
96
|
/** Re-exported so the module's files import one place. One type for actions and connectors: it is one concept. */
|
|
65
97
|
export type { SpaceRevision } from '@plitzi/sdk-shared';
|
|
@@ -71,8 +103,23 @@ export type ActionLookups = {
|
|
|
71
103
|
getAction: (spaceId: number, actionId: string, at?: SpaceRevision) => Promise<ActionEntry | undefined>;
|
|
72
104
|
/** Only the builder's catalog, the MCP and the scheduler need the list; a page call never asks for it. */
|
|
73
105
|
listActions?: (spaceId: number, at?: SpaceRevision) => Promise<ActionEntry[]>;
|
|
106
|
+
/**
|
|
107
|
+
* Which spaces have something scheduled, for the periodic reconcile.
|
|
108
|
+
*
|
|
109
|
+
* Optional, and a safety net rather than the mechanism: a deployment keeps the schedule rows current by calling
|
|
110
|
+
* `reconcile` whenever a space's actions change, and this is what catches the write that did not happen — a
|
|
111
|
+
* restore from backup, a row edited by hand, a deploy that missed a save. Absent, nothing reconciles on a timer
|
|
112
|
+
* and the rows are exactly as correct as the calls that wrote them.
|
|
113
|
+
*/
|
|
114
|
+
listScheduledSpaces?: () => Promise<number[]>;
|
|
74
115
|
getCredential?: (spaceId: number, identifier: string) => Promise<ActionCredential | undefined>;
|
|
75
116
|
getConnector?: (spaceId: number, connectorId: string, at?: SpaceRevision) => Promise<ConnectorManifest | undefined>;
|
|
117
|
+
/**
|
|
118
|
+
* The space's own functions as of that revision — the bundle and what it declared when saved, run by the deployment's
|
|
119
|
+
* sandbox (`functions.runner`), or by the space's own runtime when it answers one with a `runner` of its own. Only
|
|
120
|
+
* asked when a run names a task the deployment does not have, or a request a path under `/api/`.
|
|
121
|
+
*/
|
|
122
|
+
getFunctions?: (spaceId: number, at?: SpaceRevision) => Promise<SpaceFunctions | undefined>;
|
|
76
123
|
};
|
|
77
124
|
/**
|
|
78
125
|
* The only door a task has to the outside world.
|
|
@@ -114,6 +161,41 @@ export type ActionTaskContext = {
|
|
|
114
161
|
email: ActionEmailSender;
|
|
115
162
|
/** Pushes a `data` frame to a streaming caller. A no-op when nobody negotiated a stream. */
|
|
116
163
|
emit: (chunk: unknown) => void;
|
|
164
|
+
/**
|
|
165
|
+
* A line for whoever reads the run: kept on the step that said it (`logs`), redacted like the rest of it, and shown
|
|
166
|
+
* wherever the run is — the builder's Try, the run history.
|
|
167
|
+
*/
|
|
168
|
+
log: (line: string) => void;
|
|
169
|
+
/**
|
|
170
|
+
* Publishes on one of this space's realtime channels, as the server — `undefined` when the server has none. What
|
|
171
|
+
* the `realtime.publish` task sends through.
|
|
172
|
+
*/
|
|
173
|
+
publish?: (topic: string, type: string, data: unknown) => Promise<void>;
|
|
174
|
+
/**
|
|
175
|
+
* A grant for one topic of a `grant: true` channel of this space — what `realtime.grant` hands the page, once the
|
|
176
|
+
* flow has decided the visitor may be there. `undefined` when the server has no realtime channels.
|
|
177
|
+
*/
|
|
178
|
+
grant?: (topic: string, ttlSeconds?: number) => Promise<string>;
|
|
179
|
+
/** Revokes `grant` for `topic` — or every grant for it, naming none — and lets go whoever is on it with one. */
|
|
180
|
+
revoke?: (topic: string, grant?: string) => Promise<void>;
|
|
181
|
+
/** Signs with the space's own key (`ActionsConfig.signingSecret`) — `undefined` when the deployment gave none. */
|
|
182
|
+
sign?: SpaceSigning['sign'];
|
|
183
|
+
verify?: SpaceSigning['verify'];
|
|
184
|
+
};
|
|
185
|
+
/** How the actions module reaches the server's realtime channels. Set by `createServer`, never by a deployment. */
|
|
186
|
+
export type ActionRealtime = {
|
|
187
|
+
publish: (space: {
|
|
188
|
+
spaceId: number;
|
|
189
|
+
environment: string;
|
|
190
|
+
}, topic: string, type: string, data: unknown) => Promise<void>;
|
|
191
|
+
grant: (space: {
|
|
192
|
+
spaceId: number;
|
|
193
|
+
environment: string;
|
|
194
|
+
}, topic: string, ttlSeconds?: number) => Promise<string>;
|
|
195
|
+
revoke: (space: {
|
|
196
|
+
spaceId: number;
|
|
197
|
+
environment: string;
|
|
198
|
+
}, topic: string, grant?: string) => Promise<void>;
|
|
117
199
|
};
|
|
118
200
|
/**
|
|
119
201
|
* One step a server action can take.
|
|
@@ -147,8 +229,8 @@ export type ActionTaskRegistry = {
|
|
|
147
229
|
/** What a deployment hands to `createServer` under `actions`. Absent → the module is never constructed. */
|
|
148
230
|
export type ActionsConfig = {
|
|
149
231
|
lookups: ActionLookups;
|
|
150
|
-
/**
|
|
151
|
-
|
|
232
|
+
/** Code of the server's own, and the sandbox for the spaces' — see `FunctionsConfig`. */
|
|
233
|
+
functions?: FunctionsConfig;
|
|
152
234
|
/** Ceilings a per-action document may tighten but never exceed. */
|
|
153
235
|
limits?: ActionLimits;
|
|
154
236
|
/** How many runs may be in flight at once. Counted per space and for the process as a whole. */
|
|
@@ -159,6 +241,15 @@ export type ActionsConfig = {
|
|
|
159
241
|
};
|
|
160
242
|
/** Where the `kv` tasks keep things. Omitted → an in-process Map, which is per-replica by definition. */
|
|
161
243
|
kv?: ActionKvAdapter;
|
|
244
|
+
/**
|
|
245
|
+
* Scheduled runs, and the durable queue they go through. See {@link ActionJobsConfig}.
|
|
246
|
+
*
|
|
247
|
+
* On by default wherever `lookups.listActions` is answerable, because a deployment that can list its actions can
|
|
248
|
+
* schedule them and the old behaviour — a `schedule` trigger that silently did nothing unless the deployment
|
|
249
|
+
* built a timer and a lock of its own — was a trigger the editor offered and the server did not honour. `false`
|
|
250
|
+
* turns it off for a replica that must only serve pages.
|
|
251
|
+
*/
|
|
252
|
+
jobs?: ActionJobsConfig | false;
|
|
162
253
|
/** Inbound webhooks are public, so they are counted per caller per minute. Default 60. */
|
|
163
254
|
rateLimit?: {
|
|
164
255
|
webhookPerMinute?: number;
|
|
@@ -199,6 +290,71 @@ export type ActionsConfig = {
|
|
|
199
290
|
replayTtlMs?: number;
|
|
200
291
|
};
|
|
201
292
|
fetchImpl?: typeof fetch;
|
|
293
|
+
/** The server's realtime channels, for the `realtime.publish` task. Set by `createServer`. */
|
|
294
|
+
realtime?: ActionRealtime;
|
|
295
|
+
/**
|
|
296
|
+
* What each space's signatures are made from (`ctx.sign` / `ctx.verify` in its functions): at least 32 characters,
|
|
297
|
+
* the SAME on every replica — a key one signed is checked by whichever the next request reaches. Each space and
|
|
298
|
+
* environment signs with a key derived from it, so none can vouch for another. Absent, spaces sign nothing.
|
|
299
|
+
*/
|
|
300
|
+
signingSecret?: string;
|
|
301
|
+
};
|
|
302
|
+
/**
|
|
303
|
+
* Scheduled runs: how they are produced, how many run at once, and where they are kept while they wait.
|
|
304
|
+
*
|
|
305
|
+
* Supplying nothing still schedules — over an in-process queue, which is correct for one replica and silently
|
|
306
|
+
* wrong for two, since each gets its own copy of every schedule. A deployment with more than one supplies a
|
|
307
|
+
* {@link ActionJobQueue} over a store they share.
|
|
308
|
+
*/
|
|
309
|
+
export type ActionJobsConfig = {
|
|
310
|
+
/**
|
|
311
|
+
* Where jobs and schedules live. Omitted → this process's memory: nothing survives a restart, and a second
|
|
312
|
+
* replica produces the same fires all over again.
|
|
313
|
+
*/
|
|
314
|
+
queue?: ActionJobQueue;
|
|
315
|
+
/**
|
|
316
|
+
* How many jobs this replica runs at once. Default 4; `0` makes it a producer that never consumes.
|
|
317
|
+
*
|
|
318
|
+
* The number that decides whether a backlog drains in minutes or hours, and it belongs to the deployment because
|
|
319
|
+
* only it knows what its flows do — a queue of five hundred HTTP calls wants a far higher number than a queue of
|
|
320
|
+
* five hundred renders. It never widens the run guards: `concurrency.perSpace` still caps one space's runs per
|
|
321
|
+
* replica, and jobs over that ceiling go back to the queue rather than failing.
|
|
322
|
+
*/
|
|
323
|
+
workers?: number;
|
|
324
|
+
/** Whether this replica sweeps schedules into the queue at all. Default true. */
|
|
325
|
+
produce?: boolean;
|
|
326
|
+
/**
|
|
327
|
+
* The spaces this server schedules for, when it serves a known few.
|
|
328
|
+
*
|
|
329
|
+
* The self-hosted shape: one space, named once. A multi-tenant deployment answers the same question with
|
|
330
|
+
* {@link ActionLookups.listScheduledSpaces} instead, which wins when both are given. With neither, nothing tells
|
|
331
|
+
* the scheduler where to look and it says so at boot rather than sitting silent — a schedule that never fires is
|
|
332
|
+
* indistinguishable from a cron expression that is wrong.
|
|
333
|
+
*/
|
|
334
|
+
spaces?: number[];
|
|
335
|
+
/** How often a free worker looks for a job. Default 1s. */
|
|
336
|
+
pollMs?: number;
|
|
337
|
+
/** How often this replica looks for due schedules. Default 15s. */
|
|
338
|
+
schedulePollMs?: number;
|
|
339
|
+
/**
|
|
340
|
+
* How long a claim is held before another replica may take the job over — the failover window. Default 30s,
|
|
341
|
+
* renewed every third of it while a job runs.
|
|
342
|
+
*/
|
|
343
|
+
leaseMs?: number;
|
|
344
|
+
/** Attempts a scheduled job gets before it is left for an operator as `dead`. Default 3. */
|
|
345
|
+
maxAttempts?: number;
|
|
346
|
+
/** First retry delay, doubling per attempt, up to `maxMs`. Defaults to 30s and 15 minutes. */
|
|
347
|
+
backoff?: {
|
|
348
|
+
baseMs?: number;
|
|
349
|
+
maxMs?: number;
|
|
350
|
+
};
|
|
351
|
+
/** Which environment scheduled runs execute in. Default `main`. */
|
|
352
|
+
environment?: Environment;
|
|
353
|
+
/** How often schedules are re-derived from documents, where `listScheduledSpaces` allows it. Default 15 min. */
|
|
354
|
+
reconcileMs?: number;
|
|
355
|
+
/** Names this replica in the job history. Defaults to the pid and a random suffix. */
|
|
356
|
+
workerId?: string;
|
|
357
|
+
onError?: (error: unknown) => void;
|
|
202
358
|
};
|
|
203
359
|
/** Re-exported so the module's own files import one place, and a deployment writing an `onRun` or an `onReject`
|
|
204
360
|
* sees the same shapes the module emits. */
|
|
@@ -241,4 +397,6 @@ export type ActionRunResult = {
|
|
|
241
397
|
* anybody allowed to debug the page. The trace above is for authoring and development servers alone.
|
|
242
398
|
*/
|
|
243
399
|
steps: ActionRunStep[];
|
|
400
|
+
/** Why the run failed, when a step said so for the caller (`ActionRefusal`). Absent for every other failure. */
|
|
401
|
+
error?: string;
|
|
244
402
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { fetchOutbound } from "../../helpers/outboundGuard.js";
|
|
2
2
|
import { getByPath } from "./getByPath.js";
|
|
3
3
|
import { processTwig } from "@plitzi/sdk-shared/helpers/twigWrapper";
|
|
4
4
|
import { BODYLESS_METHODS, DEFAULT_READ_ENDPOINT, EMPTY_RESPONSE_METHODS } from "@plitzi/sdk-shared/connectors";
|
|
@@ -150,7 +150,6 @@ var fetchConnectorRecords = async ({ manifest, endpoint = DEFAULT_READ_ENDPOINT,
|
|
|
150
150
|
...renderEntries(read.query ?? {}, variables),
|
|
151
151
|
...renderFilters(resolved, connection.operators, variables)
|
|
152
152
|
}).forEach(([key, value]) => url.searchParams.set(key, value));
|
|
153
|
-
await assertOutboundAllowed(url);
|
|
154
153
|
const method = read.method ?? "GET";
|
|
155
154
|
const headers = {
|
|
156
155
|
...applyAuth(connection, variables, url),
|
|
@@ -158,7 +157,7 @@ var fetchConnectorRecords = async ({ manifest, endpoint = DEFAULT_READ_ENDPOINT,
|
|
|
158
157
|
};
|
|
159
158
|
const sendsBody = !BODYLESS_METHODS.includes(method);
|
|
160
159
|
if (sendsBody) headers["Content-Type"] = "application/json";
|
|
161
|
-
const response = await fetchImpl
|
|
160
|
+
const response = await fetchOutbound(fetchImpl, url, {
|
|
162
161
|
method,
|
|
163
162
|
headers,
|
|
164
163
|
body: sendsBody ? JSON.stringify(renderEntries(read.body ?? {}, variables)) : void 0
|
|
@@ -202,13 +201,12 @@ var writeConnectorRecord = async ({ manifest, credential = {}, action, resource,
|
|
|
202
201
|
};
|
|
203
202
|
const url = new URL(render(operation.path, variables), connection.baseUrl);
|
|
204
203
|
Object.entries(renderEntries(operation.query ?? {}, variables)).forEach(([key, value]) => url.searchParams.set(key, value));
|
|
205
|
-
await assertOutboundAllowed(url);
|
|
206
204
|
const headers = {
|
|
207
205
|
...applyAuth(connection, variables, url),
|
|
208
206
|
...renderEntries(operation.headers ?? {}, variables)
|
|
209
207
|
};
|
|
210
208
|
headers["Content-Type"] = "application/json";
|
|
211
|
-
const response = await fetchImpl
|
|
209
|
+
const response = await fetchOutbound(fetchImpl, url, {
|
|
212
210
|
method: operation.method,
|
|
213
211
|
headers,
|
|
214
212
|
body: BODYLESS_METHODS.includes(operation.method) ? void 0 : JSON.stringify(wrapBody(values, operation.bodyPath))
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { FunctionsProblem } from '@plitzi/sdk-shared';
|
|
2
|
+
/** A space's functions source: its files under `functions/`, by path (`index.ts`, `lib/feed.ts`). */
|
|
3
|
+
export type FunctionsSource = Record<string, string>;
|
|
4
|
+
/** One bundle, built from a source: a single web-standard ES module whose default export is the definition. */
|
|
5
|
+
export type FunctionsBuild = {
|
|
6
|
+
code: string;
|
|
7
|
+
bytes: number;
|
|
8
|
+
};
|
|
9
|
+
export declare class FunctionsBuildError extends Error {
|
|
10
|
+
readonly problems: FunctionsProblem[];
|
|
11
|
+
constructor(problems: FunctionsProblem[]);
|
|
12
|
+
}
|
|
13
|
+
/** The file a space's functions start from. */
|
|
14
|
+
export declare const FUNCTIONS_ENTRY = "index.ts";
|
|
15
|
+
/** The most a bundle may weigh: well under the smallest provider a runner may be (Workers take 3 MB compressed). */
|
|
16
|
+
export declare const MAX_FUNCTIONS_BYTES = 1000000;
|
|
17
|
+
/**
|
|
18
|
+
* Builds a space's functions into one bundle — the only way code reaches a runner, so what runs is always what the
|
|
19
|
+
* source says. Web-standard and self-contained: the space's own files, and the contract; a Node built-in or any other
|
|
20
|
+
* package is refused with where it was imported, because no runner could provide it.
|
|
21
|
+
*/
|
|
22
|
+
export declare const buildFunctions: (source: FunctionsSource) => Promise<FunctionsBuild>;
|