@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
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { createEmailSender } from './email';
|
|
2
|
+
import { createRedactor } from './scope';
|
|
3
|
+
import { createSigning } from './signing';
|
|
4
|
+
import { ActionKvStore, ActionRunRequest, ActionsConfig, ActionTaskContext, ResolvedActionLimits } from '../types';
|
|
5
|
+
/**
|
|
6
|
+
* Counts outbound calls, refuses past the budget, caps what one answer may carry back, and stamps the run's
|
|
7
|
+
* lineage on every one of them.
|
|
8
|
+
*
|
|
9
|
+
* The budget stops a loop from turning one run into a hundred requests. The lineage header is what makes the
|
|
10
|
+
* OTHER loop detectable: an action whose HTTP step reaches its own space's webhook arrives carrying the chain
|
|
11
|
+
* that led there, and the run it would start refuses itself. It names the space's own actions to a backend that
|
|
12
|
+
* space configured, which is the cost of catching a cycle nothing else can see.
|
|
13
|
+
*
|
|
14
|
+
* Every ceiling lives HERE rather than in each task, because this is the only door a task has to the outside
|
|
15
|
+
* world — a task that had to remember to count its own bytes is a task that will forget.
|
|
16
|
+
*/
|
|
17
|
+
export declare const createRunFetch: (base: typeof fetch, signal: AbortSignal, limits: ResolvedActionLimits, lineage: string[]) => typeof fetch;
|
|
18
|
+
/** What a task's context is made of that outlives one run: the server's stores and the run's redactor. */
|
|
19
|
+
export type TaskContextDeps = {
|
|
20
|
+
kv: ActionKvStore;
|
|
21
|
+
email: ReturnType<typeof createEmailSender>;
|
|
22
|
+
redactor: ReturnType<typeof createRedactor>;
|
|
23
|
+
/** Absent when the deployment gave no `signingSecret`: its spaces then sign nothing. */
|
|
24
|
+
signing?: ReturnType<typeof createSigning>;
|
|
25
|
+
};
|
|
26
|
+
/** Who and what the context is for — a run's request, or anything shaped like one (a function's route). */
|
|
27
|
+
export type TaskContextRequest = Pick<ActionRunRequest, 'runId' | 'spaceId' | 'environment' | 'trigger' | 'user' | 'callerId' | 'at' | 'emit'>;
|
|
28
|
+
/**
|
|
29
|
+
* What a task runs with — the one place it is made, for a step of a run and for a function answering a route alike:
|
|
30
|
+
* every secret it resolves registered with the redactor, the space's `kv` namespace, the run's outbound budget, the
|
|
31
|
+
* space's channels. Everything but `log`, which is the STEP's: each step keeps what it logged.
|
|
32
|
+
*/
|
|
33
|
+
export declare const taskContextFor: (config: ActionsConfig, { kv, email, redactor, signing }: TaskContextDeps, request: TaskContextRequest, signal: AbortSignal, runFetch: typeof fetch) => (scope: Record<string, unknown>) => Omit<ActionTaskContext, "log">;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { ActionRunError } from "./errors.js";
|
|
2
|
+
import { namespaceKv } from "./namespaceKv.js";
|
|
3
|
+
//#region src/modules/actions/runtime/taskContext.ts
|
|
4
|
+
/**
|
|
5
|
+
* Holds an answer to what the run is allowed to carry.
|
|
6
|
+
*
|
|
7
|
+
* Two checks rather than one, because a body arrives in two ways. `Content-Length` is refused before a byte is
|
|
8
|
+
* read, which is the cheap half; a chunked answer that declares nothing is counted AS it streams and errored the
|
|
9
|
+
* moment it goes over — so the ceiling holds for a backend that lies about its size or never states one.
|
|
10
|
+
*
|
|
11
|
+
* The cap is on one response and not on the run: it exists so that a single answer cannot be unbounded, which is
|
|
12
|
+
* a different failure from a flow that makes many small calls (that is `maxRequests`).
|
|
13
|
+
*/
|
|
14
|
+
var capped = (response, maxBytes) => {
|
|
15
|
+
const declared = Number(response.headers.get("content-length") ?? "");
|
|
16
|
+
if (Number.isFinite(declared) && declared > maxBytes) throw new ActionRunError("over_capacity", `Response is larger than the ${maxBytes} byte budget`);
|
|
17
|
+
if (!response.body) return response;
|
|
18
|
+
let seen = 0;
|
|
19
|
+
const counted = response.body.pipeThrough(new TransformStream({ transform: (chunk, controller) => {
|
|
20
|
+
seen += chunk.byteLength;
|
|
21
|
+
if (seen > maxBytes) {
|
|
22
|
+
controller.error(new ActionRunError("over_capacity", `Response exceeded the ${maxBytes} byte budget`));
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
controller.enqueue(chunk);
|
|
26
|
+
} }));
|
|
27
|
+
return new Response(counted, {
|
|
28
|
+
status: response.status,
|
|
29
|
+
statusText: response.statusText,
|
|
30
|
+
headers: response.headers
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Counts outbound calls, refuses past the budget, caps what one answer may carry back, and stamps the run's
|
|
35
|
+
* lineage on every one of them.
|
|
36
|
+
*
|
|
37
|
+
* The budget stops a loop from turning one run into a hundred requests. The lineage header is what makes the
|
|
38
|
+
* OTHER loop detectable: an action whose HTTP step reaches its own space's webhook arrives carrying the chain
|
|
39
|
+
* that led there, and the run it would start refuses itself. It names the space's own actions to a backend that
|
|
40
|
+
* space configured, which is the cost of catching a cycle nothing else can see.
|
|
41
|
+
*
|
|
42
|
+
* Every ceiling lives HERE rather than in each task, because this is the only door a task has to the outside
|
|
43
|
+
* world — a task that had to remember to count its own bytes is a task that will forget.
|
|
44
|
+
*/
|
|
45
|
+
var createRunFetch = (base, signal, limits, lineage) => {
|
|
46
|
+
let issued = 0;
|
|
47
|
+
return async (input, init) => {
|
|
48
|
+
issued += 1;
|
|
49
|
+
if (issued > limits.maxRequests) throw new ActionRunError("over_capacity", `Action exceeded its ${limits.maxRequests} outbound request budget`);
|
|
50
|
+
const headers = new Headers(init?.headers);
|
|
51
|
+
headers.set("X-Plitzi-Action-Lineage", lineage.join(","));
|
|
52
|
+
return capped(await base(input, {
|
|
53
|
+
...init,
|
|
54
|
+
headers,
|
|
55
|
+
signal: init?.signal ?? signal
|
|
56
|
+
}), limits.maxResponseBytes);
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* What a task runs with — the one place it is made, for a step of a run and for a function answering a route alike:
|
|
61
|
+
* every secret it resolves registered with the redactor, the space's `kv` namespace, the run's outbound budget, the
|
|
62
|
+
* space's channels. Everything but `log`, which is the STEP's: each step keeps what it logged.
|
|
63
|
+
*/
|
|
64
|
+
var taskContextFor = (config, { kv, email, redactor, signing }, request, signal, runFetch) => (scope) => {
|
|
65
|
+
const { realtime } = config;
|
|
66
|
+
return {
|
|
67
|
+
runId: request.runId,
|
|
68
|
+
spaceId: request.spaceId,
|
|
69
|
+
environment: request.environment,
|
|
70
|
+
trigger: request.trigger,
|
|
71
|
+
user: request.user,
|
|
72
|
+
callerId: request.callerId,
|
|
73
|
+
signal,
|
|
74
|
+
scope,
|
|
75
|
+
/**
|
|
76
|
+
* The secret a STEP asked for, resolved inside that step and never in the flow scope.
|
|
77
|
+
*
|
|
78
|
+
* There is no allow-list to check it against, deliberately: an action is authored by someone who may edit
|
|
79
|
+
* every action in the space, so a list they can edit is not a boundary — it only ever told the redactor what
|
|
80
|
+
* to look for, and the redactor now learns from what was actually resolved. What IS a boundary is that a
|
|
81
|
+
* credential reaches only the params of the step that named it, which is `renderTaskParams`' whole job.
|
|
82
|
+
*/
|
|
83
|
+
credential: async (identifier) => {
|
|
84
|
+
const credential = await config.lookups.getCredential?.(request.spaceId, identifier);
|
|
85
|
+
if (credential) redactor.add(credential);
|
|
86
|
+
return credential;
|
|
87
|
+
},
|
|
88
|
+
connector: async (connectorId) => {
|
|
89
|
+
const manifest = await config.lookups.getConnector?.(request.spaceId, connectorId, request.at);
|
|
90
|
+
if (!manifest) return;
|
|
91
|
+
const credential = manifest.credential ? await config.lookups.getCredential?.(request.spaceId, manifest.credential) : void 0;
|
|
92
|
+
if (credential) redactor.add(credential);
|
|
93
|
+
return {
|
|
94
|
+
manifest,
|
|
95
|
+
credential
|
|
96
|
+
};
|
|
97
|
+
},
|
|
98
|
+
fetch: runFetch,
|
|
99
|
+
kv: namespaceKv(kv, request.spaceId),
|
|
100
|
+
dbDrivers: config.dbDrivers ?? [],
|
|
101
|
+
email,
|
|
102
|
+
emit: (chunk) => request.emit?.(redactor.redact(chunk)),
|
|
103
|
+
...signing?.({
|
|
104
|
+
spaceId: request.spaceId,
|
|
105
|
+
environment: request.environment
|
|
106
|
+
}),
|
|
107
|
+
...realtime ? {
|
|
108
|
+
publish: (topic, type, data) => realtime.publish({
|
|
109
|
+
spaceId: request.spaceId,
|
|
110
|
+
environment: request.environment
|
|
111
|
+
}, topic, type, data),
|
|
112
|
+
grant: (topic, ttlSeconds) => realtime.grant({
|
|
113
|
+
spaceId: request.spaceId,
|
|
114
|
+
environment: request.environment
|
|
115
|
+
}, topic, ttlSeconds),
|
|
116
|
+
revoke: (topic, grant) => realtime.revoke({
|
|
117
|
+
spaceId: request.spaceId,
|
|
118
|
+
environment: request.environment
|
|
119
|
+
}, topic, grant)
|
|
120
|
+
} : {}
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
//#endregion
|
|
124
|
+
export { createRunFetch, taskContextFor };
|
|
@@ -4,6 +4,8 @@ import { emailTasks } from "./email.js";
|
|
|
4
4
|
import { flowTasks, streamTasks } from "./flow.js";
|
|
5
5
|
import { httpTasks } from "./http.js";
|
|
6
6
|
import { kvTasks } from "./kv.js";
|
|
7
|
+
import { listTasks } from "./list.js";
|
|
8
|
+
import { realtimeTasks } from "./realtime.js";
|
|
7
9
|
import { transformTasks } from "./transform.js";
|
|
8
10
|
//#region src/modules/actions/tasks/builtins.ts
|
|
9
11
|
/**
|
|
@@ -21,8 +23,10 @@ var builtinTasks = [
|
|
|
21
23
|
...connectorTasks,
|
|
22
24
|
...authTasks,
|
|
23
25
|
...kvTasks,
|
|
26
|
+
...listTasks,
|
|
24
27
|
...emailTasks,
|
|
25
|
-
...streamTasks
|
|
28
|
+
...streamTasks,
|
|
29
|
+
...realtimeTasks
|
|
26
30
|
];
|
|
27
31
|
//#endregion
|
|
28
32
|
export { builtinTasks };
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { ActionRefusal } from "../runtime/errors.js";
|
|
1
2
|
import onAbort from "../../../helpers/onAbort.js";
|
|
3
|
+
import { countRate } from "../runtime/rateLimit.js";
|
|
2
4
|
//#region src/modules/actions/tasks/flow.ts
|
|
3
5
|
var MAX_DELAY_MS = 5e3;
|
|
4
6
|
/**
|
|
@@ -30,19 +32,31 @@ var delay = {
|
|
|
30
32
|
return { waited: waitMs };
|
|
31
33
|
}
|
|
32
34
|
};
|
|
33
|
-
/**
|
|
35
|
+
/**
|
|
36
|
+
* Ends the run as failed, on purpose. The message reaches the trace — and, with `tellCaller`, the caller too, as the
|
|
37
|
+
* run's `error`: a guard whose reason the page should show ("that name is taken") rather than a generic failure.
|
|
38
|
+
*/
|
|
34
39
|
var fail = {
|
|
35
40
|
namespace: "flow",
|
|
36
41
|
action: "fail",
|
|
37
42
|
title: "Fail",
|
|
38
|
-
params: {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
params: {
|
|
44
|
+
message: {
|
|
45
|
+
type: "text",
|
|
46
|
+
canBind: true,
|
|
47
|
+
defaultValue: "",
|
|
48
|
+
label: "Message"
|
|
49
|
+
},
|
|
50
|
+
tellCaller: {
|
|
51
|
+
type: "boolean",
|
|
52
|
+
canBind: true,
|
|
53
|
+
defaultValue: false,
|
|
54
|
+
label: "Tell the caller why"
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
run: ({ message, tellCaller }) => {
|
|
58
|
+
const text = message || "Action failed";
|
|
59
|
+
throw tellCaller === true || tellCaller === "true" ? new ActionRefusal(text) : new Error(text);
|
|
46
60
|
}
|
|
47
61
|
};
|
|
48
62
|
/**
|
|
@@ -121,7 +135,64 @@ var flowTasks = [
|
|
|
121
135
|
delay,
|
|
122
136
|
fail,
|
|
123
137
|
output,
|
|
124
|
-
onFailure
|
|
138
|
+
onFailure,
|
|
139
|
+
{
|
|
140
|
+
namespace: "flow",
|
|
141
|
+
action: "rateLimit",
|
|
142
|
+
title: "Rate Limit",
|
|
143
|
+
params: {
|
|
144
|
+
bucket: {
|
|
145
|
+
type: "text",
|
|
146
|
+
canBind: true,
|
|
147
|
+
defaultValue: "",
|
|
148
|
+
label: "Name (what is counted — \"comments\")"
|
|
149
|
+
},
|
|
150
|
+
limit: {
|
|
151
|
+
type: "text",
|
|
152
|
+
canBind: true,
|
|
153
|
+
defaultValue: "10",
|
|
154
|
+
label: "At most"
|
|
155
|
+
},
|
|
156
|
+
windowSeconds: {
|
|
157
|
+
type: "text",
|
|
158
|
+
canBind: true,
|
|
159
|
+
defaultValue: "60",
|
|
160
|
+
label: "Every (seconds)"
|
|
161
|
+
},
|
|
162
|
+
per: {
|
|
163
|
+
type: "select",
|
|
164
|
+
canBind: true,
|
|
165
|
+
defaultValue: "caller",
|
|
166
|
+
label: "Counted",
|
|
167
|
+
options: [{
|
|
168
|
+
label: "For each person",
|
|
169
|
+
value: "caller"
|
|
170
|
+
}, {
|
|
171
|
+
label: "For everyone together",
|
|
172
|
+
value: "everyone"
|
|
173
|
+
}]
|
|
174
|
+
},
|
|
175
|
+
message: {
|
|
176
|
+
type: "text",
|
|
177
|
+
canBind: true,
|
|
178
|
+
defaultValue: "",
|
|
179
|
+
label: "Refusal (what the caller is told)"
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
run: async ({ bucket, limit, windowSeconds, per, message }, ctx) => {
|
|
183
|
+
const perSeconds = Number(windowSeconds);
|
|
184
|
+
const { allowed, count, remaining } = await countRate(ctx.kv, ctx.callerId, bucket, {
|
|
185
|
+
most: Number(limit),
|
|
186
|
+
perSeconds,
|
|
187
|
+
per: per === "everyone" ? "everyone" : "caller"
|
|
188
|
+
});
|
|
189
|
+
if (!allowed) throw new ActionRefusal(message || `Too many at once — try again in ${String(perSeconds)} seconds`);
|
|
190
|
+
return {
|
|
191
|
+
count,
|
|
192
|
+
remaining
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
}
|
|
125
196
|
];
|
|
126
197
|
var streamTasks = [emit];
|
|
127
198
|
//#endregion
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { processTwigParam } from "@plitzi/sdk-shared/helpers/twigWrapper";
|
|
2
2
|
//#region src/modules/actions/tasks/helpers.ts
|
|
3
3
|
/**
|
|
4
4
|
* Renders a task's own params, with its own credential in scope.
|
|
@@ -22,7 +22,7 @@ var renderTaskParams = async (params, ctx, credentialId) => {
|
|
|
22
22
|
...credential ? { credential } : {}
|
|
23
23
|
};
|
|
24
24
|
return Object.entries(params).reduce((acum, [key, value]) => {
|
|
25
|
-
acum[key] = typeof value === "string" ?
|
|
25
|
+
acum[key] = typeof value === "string" ? processTwigParam(value, scope) : value;
|
|
26
26
|
return acum;
|
|
27
27
|
}, {});
|
|
28
28
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { fetchOutbound } from "../../../helpers/outboundGuard.js";
|
|
2
2
|
import { renderTaskParams } from "./helpers.js";
|
|
3
3
|
//#region src/modules/actions/tasks/http.ts
|
|
4
4
|
var BODYLESS = ["GET", "HEAD"];
|
|
@@ -81,7 +81,6 @@ var httpTasks = [{
|
|
|
81
81
|
} catch {
|
|
82
82
|
throw new Error("Request URL is not a valid absolute URL");
|
|
83
83
|
}
|
|
84
|
-
await assertOutboundAllowed(url);
|
|
85
84
|
const headers = Object.entries(parseJsonParam(params.headers, "Headers")).reduce((acum, [key, value]) => {
|
|
86
85
|
acum[key] = typeof value === "string" ? value : JSON.stringify(value);
|
|
87
86
|
return acum;
|
|
@@ -89,7 +88,7 @@ var httpTasks = [{
|
|
|
89
88
|
const hasBody = !BODYLESS.includes(method) && params.body !== "";
|
|
90
89
|
const declaresContentType = Object.keys(headers).some((name) => name.toLowerCase() === "content-type");
|
|
91
90
|
if (hasBody && !declaresContentType) headers["Content-Type"] = "application/json";
|
|
92
|
-
const response = await ctx.fetch
|
|
91
|
+
const response = await fetchOutbound(ctx.fetch, url, {
|
|
93
92
|
method,
|
|
94
93
|
headers,
|
|
95
94
|
body: hasBody ? JSON.stringify(parseJsonParam(params.body, "Body")) : void 0,
|
|
@@ -50,6 +50,45 @@ var kvTasks = [
|
|
|
50
50
|
};
|
|
51
51
|
}
|
|
52
52
|
},
|
|
53
|
+
{
|
|
54
|
+
namespace: "kv",
|
|
55
|
+
action: "setIf",
|
|
56
|
+
title: "Write Value If Unchanged",
|
|
57
|
+
params: {
|
|
58
|
+
key: {
|
|
59
|
+
type: "text",
|
|
60
|
+
canBind: true,
|
|
61
|
+
defaultValue: "",
|
|
62
|
+
label: "Key"
|
|
63
|
+
},
|
|
64
|
+
expected: {
|
|
65
|
+
type: "codemirror-text",
|
|
66
|
+
canBind: true,
|
|
67
|
+
defaultValue: "",
|
|
68
|
+
label: "Only if it holds (the value read; empty = only if it holds nothing)"
|
|
69
|
+
},
|
|
70
|
+
value: {
|
|
71
|
+
type: "codemirror-text",
|
|
72
|
+
canBind: true,
|
|
73
|
+
defaultValue: "",
|
|
74
|
+
label: "Value"
|
|
75
|
+
},
|
|
76
|
+
ttlSeconds: {
|
|
77
|
+
type: "text",
|
|
78
|
+
canBind: true,
|
|
79
|
+
defaultValue: "",
|
|
80
|
+
label: "TTL (seconds)"
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
run: async ({ key, expected, value, ttlSeconds }, ctx) => {
|
|
84
|
+
const ttl = ttlSeconds === "" ? void 0 : toNumber(ttlSeconds, 0) || void 0;
|
|
85
|
+
return {
|
|
86
|
+
key,
|
|
87
|
+
written: await ctx.kv.swap(key, expected === "" || expected === null ? void 0 : expected, value, ttl),
|
|
88
|
+
value: await ctx.kv.get(key) ?? null
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
},
|
|
53
92
|
{
|
|
54
93
|
namespace: "kv",
|
|
55
94
|
action: "increment",
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import "../runtime/kvList.js";
|
|
2
|
+
//#region src/modules/actions/tasks/list.ts
|
|
3
|
+
var toNumber = (value, fallback) => {
|
|
4
|
+
if (value === void 0 || value === "") return fallback;
|
|
5
|
+
const parsed = typeof value === "number" ? value : Number(value);
|
|
6
|
+
return Number.isFinite(parsed) ? parsed : fallback;
|
|
7
|
+
};
|
|
8
|
+
/** What a typed value means: JSON when it reads as JSON, the text itself when it does not. A bound value as it is. */
|
|
9
|
+
var valueOf = (value) => {
|
|
10
|
+
if (typeof value !== "string") return value ?? null;
|
|
11
|
+
if (value === "") return null;
|
|
12
|
+
try {
|
|
13
|
+
return JSON.parse(value);
|
|
14
|
+
} catch {
|
|
15
|
+
return value;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
var nameParam = {
|
|
19
|
+
type: "text",
|
|
20
|
+
canBind: true,
|
|
21
|
+
defaultValue: "",
|
|
22
|
+
label: "List"
|
|
23
|
+
};
|
|
24
|
+
var listTasks = [
|
|
25
|
+
{
|
|
26
|
+
namespace: "list",
|
|
27
|
+
action: "put",
|
|
28
|
+
title: "Add To List",
|
|
29
|
+
params: {
|
|
30
|
+
list: nameParam,
|
|
31
|
+
id: {
|
|
32
|
+
type: "text",
|
|
33
|
+
canBind: true,
|
|
34
|
+
defaultValue: "",
|
|
35
|
+
label: "Entry id"
|
|
36
|
+
},
|
|
37
|
+
score: {
|
|
38
|
+
type: "text",
|
|
39
|
+
canBind: true,
|
|
40
|
+
defaultValue: "0",
|
|
41
|
+
label: "Score (highest first)"
|
|
42
|
+
},
|
|
43
|
+
value: {
|
|
44
|
+
type: "codemirror-json",
|
|
45
|
+
canBind: true,
|
|
46
|
+
defaultValue: "",
|
|
47
|
+
label: "Value"
|
|
48
|
+
},
|
|
49
|
+
keep: {
|
|
50
|
+
type: "text",
|
|
51
|
+
canBind: true,
|
|
52
|
+
defaultValue: "",
|
|
53
|
+
label: `Keep at most (≤ 500)`
|
|
54
|
+
},
|
|
55
|
+
higherOnly: {
|
|
56
|
+
type: "boolean",
|
|
57
|
+
canBind: true,
|
|
58
|
+
defaultValue: false,
|
|
59
|
+
label: "Only replace a lower score (a best score, the latest of two writes)"
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
run: async ({ list, id, score, value, keep, higherOnly }, ctx) => {
|
|
63
|
+
const sorted = toNumber(score, void 0);
|
|
64
|
+
if (sorted === void 0) throw new Error(`A score is a number, and "${String(score)}" is not one`);
|
|
65
|
+
const put = await ctx.kv.listPut(list, {
|
|
66
|
+
id,
|
|
67
|
+
score: sorted,
|
|
68
|
+
value: valueOf(value)
|
|
69
|
+
}, {
|
|
70
|
+
keep: toNumber(keep, void 0),
|
|
71
|
+
higherOnly: higherOnly === true || higherOnly === "true"
|
|
72
|
+
});
|
|
73
|
+
return {
|
|
74
|
+
list,
|
|
75
|
+
id,
|
|
76
|
+
stored: put.stored,
|
|
77
|
+
dropped: put.dropped.map((entry) => entry.id)
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
namespace: "list",
|
|
83
|
+
action: "range",
|
|
84
|
+
title: "Read List",
|
|
85
|
+
params: {
|
|
86
|
+
list: nameParam,
|
|
87
|
+
offset: {
|
|
88
|
+
type: "text",
|
|
89
|
+
canBind: true,
|
|
90
|
+
defaultValue: "0",
|
|
91
|
+
label: "Skip"
|
|
92
|
+
},
|
|
93
|
+
limit: {
|
|
94
|
+
type: "text",
|
|
95
|
+
canBind: true,
|
|
96
|
+
defaultValue: "20",
|
|
97
|
+
label: "How many"
|
|
98
|
+
},
|
|
99
|
+
order: {
|
|
100
|
+
type: "select",
|
|
101
|
+
canBind: true,
|
|
102
|
+
defaultValue: "desc",
|
|
103
|
+
label: "Order",
|
|
104
|
+
options: [{
|
|
105
|
+
label: "Highest score first",
|
|
106
|
+
value: "desc"
|
|
107
|
+
}, {
|
|
108
|
+
label: "Lowest score first",
|
|
109
|
+
value: "asc"
|
|
110
|
+
}]
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
run: async ({ list, offset, limit, order }, ctx) => {
|
|
114
|
+
return {
|
|
115
|
+
list,
|
|
116
|
+
entries: await ctx.kv.listRange(list, {
|
|
117
|
+
offset: toNumber(offset, 0),
|
|
118
|
+
limit: toNumber(limit, void 0),
|
|
119
|
+
order: order === "asc" ? "asc" : "desc"
|
|
120
|
+
})
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
namespace: "list",
|
|
126
|
+
action: "remove",
|
|
127
|
+
title: "Remove From List",
|
|
128
|
+
params: {
|
|
129
|
+
list: nameParam,
|
|
130
|
+
id: {
|
|
131
|
+
type: "text",
|
|
132
|
+
canBind: true,
|
|
133
|
+
defaultValue: "",
|
|
134
|
+
label: "Entry id"
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
run: async ({ list, id }, ctx) => ({
|
|
138
|
+
list,
|
|
139
|
+
id,
|
|
140
|
+
removed: await ctx.kv.listRemove(list, id)
|
|
141
|
+
})
|
|
142
|
+
}
|
|
143
|
+
];
|
|
144
|
+
//#endregion
|
|
145
|
+
export { listTasks };
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { DEFAULT_GRANT_SECONDS, MAX_GRANT_SECONDS } from "../../realtime/grants.js";
|
|
2
|
+
//#region src/modules/actions/tasks/realtime.ts
|
|
3
|
+
var parse = (value) => {
|
|
4
|
+
if (typeof value !== "string") return value;
|
|
5
|
+
try {
|
|
6
|
+
return JSON.parse(value);
|
|
7
|
+
} catch {
|
|
8
|
+
return value;
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
var realtimeTasks = [
|
|
12
|
+
{
|
|
13
|
+
namespace: "realtime",
|
|
14
|
+
action: "publish",
|
|
15
|
+
title: "Publish On Channel",
|
|
16
|
+
description: "Sends a message to every page subscribed to a topic of one of the space’s channels.",
|
|
17
|
+
params: {
|
|
18
|
+
topic: {
|
|
19
|
+
type: "text",
|
|
20
|
+
canBind: true,
|
|
21
|
+
defaultValue: "",
|
|
22
|
+
label: "Topic (board:{{ input.board }})"
|
|
23
|
+
},
|
|
24
|
+
type: {
|
|
25
|
+
type: "text",
|
|
26
|
+
canBind: true,
|
|
27
|
+
defaultValue: "",
|
|
28
|
+
label: "Type"
|
|
29
|
+
},
|
|
30
|
+
data: {
|
|
31
|
+
type: "codemirror-json",
|
|
32
|
+
canBind: true,
|
|
33
|
+
defaultValue: "{}",
|
|
34
|
+
label: "Data"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
run: async ({ topic, type, data }, ctx) => {
|
|
38
|
+
if (!ctx.publish) throw new Error("This server has no realtime channels");
|
|
39
|
+
await ctx.publish(topic, type, parse(data));
|
|
40
|
+
return {
|
|
41
|
+
topic,
|
|
42
|
+
published: true
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
namespace: "realtime",
|
|
48
|
+
action: "grant",
|
|
49
|
+
title: "Grant Channel",
|
|
50
|
+
description: "Answers a grant that lets this visitor’s page open one topic of a private (`grant: true`) channel.",
|
|
51
|
+
params: {
|
|
52
|
+
topic: {
|
|
53
|
+
type: "text",
|
|
54
|
+
canBind: true,
|
|
55
|
+
defaultValue: "",
|
|
56
|
+
label: "Topic (room:{{ input.room }})"
|
|
57
|
+
},
|
|
58
|
+
ttlSeconds: {
|
|
59
|
+
type: "text",
|
|
60
|
+
canBind: true,
|
|
61
|
+
defaultValue: String(DEFAULT_GRANT_SECONDS),
|
|
62
|
+
label: `For how long (seconds, at most ${String(MAX_GRANT_SECONDS)})`
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
run: async ({ topic, ttlSeconds }, ctx) => {
|
|
66
|
+
if (!ctx.grant) throw new Error("This server has no realtime channels");
|
|
67
|
+
const seconds = ttlSeconds === "" ? void 0 : Number(ttlSeconds);
|
|
68
|
+
return {
|
|
69
|
+
topic,
|
|
70
|
+
grant: await ctx.grant(topic, Number.isFinite(seconds) ? seconds : void 0)
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
namespace: "realtime",
|
|
76
|
+
action: "revoke",
|
|
77
|
+
title: "Revoke Channel Grant",
|
|
78
|
+
description: "Takes back one grant to a private channel’s topic — or all of them — and lets go whoever is on it with one.",
|
|
79
|
+
params: {
|
|
80
|
+
topic: {
|
|
81
|
+
type: "text",
|
|
82
|
+
canBind: true,
|
|
83
|
+
defaultValue: "",
|
|
84
|
+
label: "Topic (room:{{ input.room }})"
|
|
85
|
+
},
|
|
86
|
+
grant: {
|
|
87
|
+
type: "text",
|
|
88
|
+
canBind: true,
|
|
89
|
+
defaultValue: "",
|
|
90
|
+
label: "Grant (empty = every grant for the topic)"
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
run: async ({ topic, grant }, ctx) => {
|
|
94
|
+
if (!ctx.revoke) throw new Error("This server has no realtime channels");
|
|
95
|
+
await ctx.revoke(topic, grant ? grant : void 0);
|
|
96
|
+
return {
|
|
97
|
+
topic,
|
|
98
|
+
revoked: grant ? "one" : "all"
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
];
|
|
103
|
+
//#endregion
|
|
104
|
+
export { realtimeTasks };
|
|
@@ -1,5 +1,14 @@
|
|
|
1
|
+
import { FunctionsDefinition } from '../../functions/contract';
|
|
1
2
|
import { ActionTask, ActionTaskRegistry } from '../types';
|
|
2
3
|
export declare const taskName: (task: Pick<ActionTask, "namespace" | "action">) => string;
|
|
4
|
+
/** The namespaces the platform's own tasks use: nobody else's task may take one. */
|
|
5
|
+
export declare const RESERVED_NAMESPACES: ReadonlySet<string>;
|
|
6
|
+
/**
|
|
7
|
+
* 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
|
|
8
|
+
* functions are built. A malformed name is unreachable from any document; one in a namespace taken by another task
|
|
9
|
+
* set silently changes what every action using that set does.
|
|
10
|
+
*/
|
|
11
|
+
export declare const taskNameProblem: (task: Pick<ActionTask, "namespace" | "action">, reserved?: ReadonlySet<string>) => string | undefined;
|
|
3
12
|
/** The shipped tasks that are only real when the deployment supplied what they run through. */
|
|
4
13
|
export type TaskRegistryOptions = {
|
|
5
14
|
/** At least one database driver is registered, so `db.query` has an engine to run against. */
|
|
@@ -12,4 +21,4 @@ export type TaskRegistryOptions = {
|
|
|
12
21
|
* name is unreachable from any document, and one shadowing a built-in silently changes what every existing action
|
|
13
22
|
* in that deployment does. Both are invisible until a run misbehaves in production.
|
|
14
23
|
*/
|
|
15
|
-
export declare const createTaskRegistry: (
|
|
24
|
+
export declare const createTaskRegistry: (functions?: readonly FunctionsDefinition[], { db }?: TaskRegistryOptions) => ActionTaskRegistry;
|