@pikku/core 0.12.107 → 0.12.111
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 +344 -0
- package/dist/analytics/analytics.d.ts +6 -0
- package/dist/analytics/analytics.js +58 -0
- package/dist/analytics/analytics.types.d.ts +156 -0
- package/dist/analytics/analytics.types.js +1 -0
- package/dist/analytics/anonymous-analytics-identity.d.ts +23 -0
- package/dist/analytics/anonymous-analytics-identity.js +27 -0
- package/dist/analytics/compose-analytics-identity.d.ts +14 -0
- package/dist/analytics/compose-analytics-identity.js +33 -0
- package/dist/analytics/cookie-analytics-identity.d.ts +24 -0
- package/dist/analytics/cookie-analytics-identity.js +37 -0
- package/dist/analytics/define-analytics-events.d.ts +22 -0
- package/dist/analytics/define-analytics-events.js +9 -0
- package/dist/analytics/fan-out-analytics.d.ts +15 -0
- package/dist/analytics/fan-out-analytics.js +36 -0
- package/dist/analytics/index.d.ts +13 -0
- package/dist/analytics/index.js +8 -0
- package/dist/analytics/logger-analytics-service.d.ts +14 -0
- package/dist/analytics/logger-analytics-service.js +23 -0
- package/dist/analytics/mint-cookie.d.ts +44 -0
- package/dist/analytics/mint-cookie.js +55 -0
- package/dist/errors/errors.d.ts +7 -0
- package/dist/errors/errors.js +17 -0
- package/dist/function/function-meta.types.d.ts +2 -0
- package/dist/function/function-runner.js +29 -0
- package/dist/function/functions.types.d.ts +22 -3
- package/dist/middleware/auth-apikey.d.ts +1 -1
- package/dist/pikku-state.d.ts +1 -1
- package/dist/scopes.d.ts +11 -0
- package/dist/scopes.js +17 -0
- package/dist/services/credential-wire-service.d.ts +1 -1
- package/dist/services/feature-flag-service.d.ts +100 -0
- package/dist/services/feature-flag-service.js +1 -0
- package/dist/services/index.d.ts +1 -0
- package/dist/services/meta-service.d.ts +16 -0
- package/dist/services/meta-service.js +19 -0
- package/dist/services/webhook-service.d.ts +7 -2
- package/dist/services/webhook-service.js +11 -6
- package/dist/testing/service-tests/agent-run-service-tests.d.ts +2 -2
- package/dist/testing/service-tests/agent-storage-service-tests.d.ts +1 -1
- package/dist/testing/service-tests/channel-store-tests.d.ts +1 -1
- package/dist/testing/service-tests/credential-service-tests.d.ts +1 -1
- package/dist/testing/service-tests/deployment-service-tests.d.ts +1 -1
- package/dist/testing/service-tests/event-hub-store-tests.d.ts +1 -1
- package/dist/testing/service-tests/secret-service-tests.d.ts +1 -1
- package/dist/testing/service-tests/session-store-tests.d.ts +1 -1
- package/dist/testing/service-tests/workflow-run-service-tests.d.ts +1 -1
- package/dist/testing/service-tests/workflow-service-tests.d.ts +1 -1
- package/dist/types/core.types.d.ts +23 -0
- package/dist/wirings/agent/agent-rpc.d.ts +1 -1
- package/dist/wirings/agent/agent-turn.d.ts +1 -1
- package/dist/wirings/agent-scorer/agent-scorer-live.d.ts +1 -1
- package/dist/wirings/channel/channel-common.d.ts +1 -1
- package/dist/wirings/channel/channel-rpc-validators.d.ts +2 -2
- package/dist/wirings/channel/channel-runner.d.ts +1 -1
- package/dist/wirings/channel/local/local-channel-runner.d.ts +1 -1
- package/dist/wirings/channel/serverless/serverless-channel-runner.d.ts +1 -1
- package/dist/wirings/cli/channel/cli-approval.d.ts +2 -2
- package/dist/wirings/flag/assert-feature-available.d.ts +15 -0
- package/dist/wirings/flag/assert-feature-available.js +23 -0
- package/dist/wirings/flag/cached-flag-source.d.ts +73 -0
- package/dist/wirings/flag/cached-flag-source.js +96 -0
- package/dist/wirings/flag/define-feature-flags.d.ts +33 -0
- package/dist/wirings/flag/define-feature-flags.js +32 -0
- package/dist/wirings/flag/flag.types.d.ts +97 -0
- package/dist/wirings/flag/flag.types.js +1 -0
- package/dist/wirings/flag/index.d.ts +7 -0
- package/dist/wirings/flag/index.js +5 -0
- package/dist/wirings/flag/resolve-flag.d.ts +52 -0
- package/dist/wirings/flag/resolve-flag.js +90 -0
- package/dist/wirings/flag/validate-flag-definitions.d.ts +26 -0
- package/dist/wirings/flag/validate-flag-definitions.js +103 -0
- package/dist/wirings/virtual-user/virtual-user-scaffold.d.ts +8 -8
- package/dist/wirings/virtual-user/virtual-user-schedule.d.ts +1 -1
- package/dist/wirings/workflow/workflow-queue-routing.d.ts +1 -1
- package/package.json +11 -5
- package/run-tests.sh +17 -9
- package/src/public-surface.json +26 -0
- package/src/agent-naming.test.ts +0 -68
- package/src/api-report.test.ts +0 -138
- package/src/app-alias-surface.test.ts +0 -179
- package/src/app-leaf-surface.test.ts +0 -222
- package/src/bootstrap-compat/root.ts +0 -20
- package/src/classification/column-form.test.ts +0 -97
- package/src/classification/column-form.ts +0 -55
- package/src/classification/data-classification.ts +0 -73
- package/src/classification/index.ts +0 -40
- package/src/classification/key-ids.ts +0 -2
- package/src/classification/secret-value.test.ts +0 -204
- package/src/classification/secret-value.ts +0 -106
- package/src/crypto-utils.test.ts +0 -668
- package/src/crypto-utils.ts +0 -460
- package/src/dev/hot-reload.test.ts +0 -587
- package/src/dev/hot-reload.ts +0 -225
- package/src/dev/module-runner.test.ts +0 -235
- package/src/dev/module-runner.ts +0 -138
- package/src/dev/reload-meta.test.ts +0 -183
- package/src/dev/reload-meta.ts +0 -144
- package/src/ecosystem-tier-removed.test.ts +0 -72
- package/src/env.ts +0 -1
- package/src/errors/error-handler.ts +0 -77
- package/src/errors/error.test.ts +0 -229
- package/src/errors/errors.ts +0 -393
- package/src/errors/index.ts +0 -11
- package/src/errors/serialized-error.ts +0 -12
- package/src/factory-functions.test.ts +0 -111
- package/src/function/abort-scope.test.ts +0 -97
- package/src/function/abort-scope.ts +0 -80
- package/src/function/function-meta.types.ts +0 -151
- package/src/function/function-runner.test.ts +0 -1619
- package/src/function/function-runner.ts +0 -499
- package/src/function/functions.types.ts +0 -319
- package/src/function/index.ts +0 -40
- package/src/function/list.types.test.ts +0 -100
- package/src/function/list.types.ts +0 -69
- package/src/function/pikku-request.test.ts +0 -35
- package/src/function/pikku-request.ts +0 -17
- package/src/gopass-secrets-removed.test.ts +0 -51
- package/src/handle-error.test.ts +0 -532
- package/src/handle-error.ts +0 -64
- package/src/middleware/auth-apikey.test.ts +0 -362
- package/src/middleware/auth-apikey.ts +0 -39
- package/src/middleware/auth-bearer.test.ts +0 -566
- package/src/middleware/auth-bearer.ts +0 -83
- package/src/middleware/auth-cookie.test.ts +0 -572
- package/src/middleware/auth-cookie.ts +0 -107
- package/src/middleware/cors.test.ts +0 -579
- package/src/middleware/cors.ts +0 -103
- package/src/middleware/index.ts +0 -30
- package/src/middleware/middleware-factories.ts +0 -76
- package/src/middleware/middleware.types.ts +0 -61
- package/src/middleware/remote-auth.test.ts +0 -547
- package/src/middleware/remote-auth.ts +0 -95
- package/src/middleware/remote-jobs-secret.ts +0 -35
- package/src/middleware/require-origin.test.ts +0 -115
- package/src/middleware/require-origin.ts +0 -79
- package/src/middleware/telemetry.ts +0 -83
- package/src/middleware-runner.test.ts +0 -578
- package/src/middleware-runner.ts +0 -232
- package/src/no-any-casts.test.ts +0 -57
- package/src/no-root-barrel.test.ts +0 -122
- package/src/permissions.test.ts +0 -256
- package/src/permissions.ts +0 -217
- package/src/pikku-state.test.ts +0 -198
- package/src/pikku-state.ts +0 -206
- package/src/production-barrels-stay-lean.test.ts +0 -110
- package/src/public-surface.test.ts +0 -133
- package/src/remote.test.ts +0 -173
- package/src/remote.ts +0 -56
- package/src/removed-legacy-exports.test.ts +0 -66
- package/src/run-tests-script.test.ts +0 -67
- package/src/schema.test.ts +0 -430
- package/src/schema.ts +0 -204
- package/src/scopes.test.ts +0 -203
- package/src/scopes.ts +0 -67
- package/src/services/agent-run-state-service.ts +0 -37
- package/src/services/agent-runner-service.ts +0 -238
- package/src/services/agent-storage-service.ts +0 -39
- package/src/services/ai-embedding-service.ts +0 -9
- package/src/services/audit-service.test.ts +0 -44
- package/src/services/audit-service.ts +0 -280
- package/src/services/content-service.ts +0 -65
- package/src/services/credential-service.ts +0 -20
- package/src/services/credential-wire-service.test.ts +0 -235
- package/src/services/credential-wire-service.ts +0 -120
- package/src/services/deployment-service.ts +0 -32
- package/src/services/email-service.test.ts +0 -100
- package/src/services/email-service.ts +0 -60
- package/src/services/email-template.test.ts +0 -311
- package/src/services/email-template.ts +0 -254
- package/src/services/file-scenario-run-store.test.ts +0 -349
- package/src/services/file-scenario-run-store.ts +0 -282
- package/src/services/gateway-service.ts +0 -5
- package/src/services/http-personas-converse.test.ts +0 -274
- package/src/services/http-personas.test.ts +0 -379
- package/src/services/http-personas.ts +0 -508
- package/src/services/in-memory-agent-run-state-service.ts +0 -87
- package/src/services/in-memory-queue-service.test.ts +0 -162
- package/src/services/in-memory-queue-service.ts +0 -78
- package/src/services/in-memory-session-store.test.ts +0 -58
- package/src/services/in-memory-session-store.ts +0 -20
- package/src/services/in-memory-trigger-service.ts +0 -47
- package/src/services/in-memory-workflow-service.test.ts +0 -430
- package/src/services/in-memory-workflow-service.ts +0 -595
- package/src/services/index.ts +0 -192
- package/src/services/istanbul-coverage-service.test.ts +0 -66
- package/src/services/istanbul-coverage-service.ts +0 -59
- package/src/services/jwt-service.ts +0 -15
- package/src/services/local-content-request-handler.test.ts +0 -240
- package/src/services/local-content-request-handler.ts +0 -295
- package/src/services/local-content.test.ts +0 -186
- package/src/services/local-content.ts +0 -242
- package/src/services/local-credential-service.ts +0 -63
- package/src/services/local-email-service.test.ts +0 -182
- package/src/services/local-email-service.ts +0 -43
- package/src/services/local-gateway-service.ts +0 -51
- package/src/services/local-secrets.test.ts +0 -95
- package/src/services/local-secrets.ts +0 -71
- package/src/services/local-variables.test.ts +0 -61
- package/src/services/local-variables.ts +0 -45
- package/src/services/logger-console.test.ts +0 -117
- package/src/services/logger-console.ts +0 -174
- package/src/services/logger.ts +0 -48
- package/src/services/meta-service.test.ts +0 -75
- package/src/services/meta-service.ts +0 -767
- package/src/services/persona-actor-secret.test.ts +0 -68
- package/src/services/persona-actor-secret.ts +0 -70
- package/src/services/persona-sign-in.test.ts +0 -219
- package/src/services/persona-sign-in.ts +0 -238
- package/src/services/personas-service.ts +0 -191
- package/src/services/pikku-user-id.test.ts +0 -62
- package/src/services/pikku-user-id.ts +0 -13
- package/src/services/queue-webhook-service.test.ts +0 -409
- package/src/services/queue-webhook-service.ts +0 -150
- package/src/services/remote-jobs.test.ts +0 -106
- package/src/services/remote-jobs.ts +0 -92
- package/src/services/scheduler-service.ts +0 -37
- package/src/services/schema-service.ts +0 -10
- package/src/services/scope-service.ts +0 -91
- package/src/services/scoped-credential-service.test.ts +0 -86
- package/src/services/scoped-credential-service.ts +0 -63
- package/src/services/scoped-secret-service.test.ts +0 -93
- package/src/services/scoped-secret-service.ts +0 -40
- package/src/services/secret-host-binding.test.ts +0 -138
- package/src/services/secret-host-binding.ts +0 -51
- package/src/services/secret-service.ts +0 -25
- package/src/services/secretless.test.ts +0 -54
- package/src/services/secretless.ts +0 -29
- package/src/services/session-store.ts +0 -9
- package/src/services/stub-tracker.test.ts +0 -104
- package/src/services/stub-tracker.ts +0 -175
- package/src/services/system-role-guard.test.ts +0 -96
- package/src/services/system-role-guard.ts +0 -71
- package/src/services/temporary-file-service.ts +0 -76
- package/src/services/trigger-service.ts +0 -5
- package/src/services/typed-credential-service.ts +0 -83
- package/src/services/typed-secret-service.test.ts +0 -204
- package/src/services/typed-secret-service.ts +0 -132
- package/src/services/typed-variables-service.test.ts +0 -166
- package/src/services/typed-variables-service.ts +0 -166
- package/src/services/user-session-service.test.ts +0 -147
- package/src/services/user-session-service.ts +0 -85
- package/src/services/v8-coverage-service.test.ts +0 -69
- package/src/services/v8-coverage-service.ts +0 -163
- package/src/services/variables-service.ts +0 -13
- package/src/services/webhook-service.ts +0 -147
- package/src/services/workflow-service.ts +0 -120
- package/src/side-effects-are-declared.test.ts +0 -84
- package/src/source-files-stay-composable.test.ts +0 -41
- package/src/template-alias-surface.test.ts +0 -240
- package/src/test-utils.ts +0 -38
- package/src/testing/index.ts +0 -3
- package/src/testing/service-tests/agent-run-service-tests.ts +0 -98
- package/src/testing/service-tests/agent-storage-service-tests.ts +0 -379
- package/src/testing/service-tests/channel-store-tests.ts +0 -98
- package/src/testing/service-tests/credential-service-tests.ts +0 -143
- package/src/testing/service-tests/deployment-service-tests.ts +0 -33
- package/src/testing/service-tests/event-hub-store-tests.ts +0 -48
- package/src/testing/service-tests/secret-service-tests.ts +0 -105
- package/src/testing/service-tests/session-store-tests.ts +0 -62
- package/src/testing/service-tests/workflow-run-service-tests.ts +0 -59
- package/src/testing/service-tests/workflow-service-tests.ts +0 -308
- package/src/testing/service-tests.ts +0 -95
- package/src/time-utils.test.ts +0 -56
- package/src/time-utils.ts +0 -89
- package/src/types/core.types.ts +0 -446
- package/src/types/index.ts +0 -25
- package/src/types/state.types.ts +0 -226
- package/src/types/typed-credentials.test.ts +0 -72
- package/src/utils/hash.test.ts +0 -68
- package/src/utils/hash.ts +0 -26
- package/src/utils/hmac.ts +0 -21
- package/src/utils/node-host-resolver.ts +0 -20
- package/src/utils/safe-fetch.test.ts +0 -515
- package/src/utils/safe-fetch.ts +0 -347
- package/src/utils.test.ts +0 -359
- package/src/utils.ts +0 -165
- package/src/version.test.ts +0 -80
- package/src/version.ts +0 -25
- package/src/wirings/actor-flow/actor-flow.types.ts +0 -40
- package/src/wirings/actor-flow/index.ts +0 -10
- package/src/wirings/actor-flow/run-conversation.test.ts +0 -187
- package/src/wirings/actor-flow/run-conversation.ts +0 -280
- package/src/wirings/addon/addon-auth-tags.test.ts +0 -219
- package/src/wirings/addon/addon-runner.ts +0 -236
- package/src/wirings/addon/addon-scopes.test.ts +0 -225
- package/src/wirings/addon/addon-secrets.test.ts +0 -391
- package/src/wirings/addon/index.ts +0 -12
- package/src/wirings/addon/remote-addon-auth.ts +0 -65
- package/src/wirings/addon/wire-addon.test.ts +0 -102
- package/src/wirings/addon/wire-addon.ts +0 -202
- package/src/wirings/addon/wire-remote-addon.ts +0 -41
- package/src/wirings/agent/agent-agui.test.ts +0 -1213
- package/src/wirings/agent/agent-agui.ts +0 -405
- package/src/wirings/agent/agent-authorization.test.ts +0 -208
- package/src/wirings/agent/agent-finalize.test.ts +0 -187
- package/src/wirings/agent/agent-finalize.ts +0 -197
- package/src/wirings/agent/agent-helpers.test.ts +0 -215
- package/src/wirings/agent/agent-helpers.ts +0 -96
- package/src/wirings/agent/agent-interrupt.test.ts +0 -833
- package/src/wirings/agent/agent-interrupt.ts +0 -400
- package/src/wirings/agent/agent-memory.test.ts +0 -397
- package/src/wirings/agent/agent-memory.ts +0 -496
- package/src/wirings/agent/agent-middleware.types.test.ts +0 -41
- package/src/wirings/agent/agent-model-config.test.ts +0 -103
- package/src/wirings/agent/agent-model-config.ts +0 -59
- package/src/wirings/agent/agent-prepare.test.ts +0 -977
- package/src/wirings/agent/agent-prepare.ts +0 -1083
- package/src/wirings/agent/agent-registry.test.ts +0 -455
- package/src/wirings/agent/agent-registry.ts +0 -99
- package/src/wirings/agent/agent-resume-authorization.test.ts +0 -206
- package/src/wirings/agent/agent-rpc.ts +0 -116
- package/src/wirings/agent/agent-runner.test.ts +0 -1229
- package/src/wirings/agent/agent-runner.ts +0 -858
- package/src/wirings/agent/agent-stream-delegate.test.ts +0 -381
- package/src/wirings/agent/agent-stream-output-hooks.test.ts +0 -353
- package/src/wirings/agent/agent-stream.test.ts +0 -1800
- package/src/wirings/agent/agent-stream.ts +0 -1639
- package/src/wirings/agent/agent-thread-ownership.test.ts +0 -297
- package/src/wirings/agent/agent-turn.test.ts +0 -65
- package/src/wirings/agent/agent-turn.ts +0 -122
- package/src/wirings/agent/agent-utils.ts +0 -20
- package/src/wirings/agent/agent.types.ts +0 -676
- package/src/wirings/agent/index.ts +0 -58
- package/src/wirings/agent/voice-input.test.ts +0 -220
- package/src/wirings/agent/voice-input.ts +0 -180
- package/src/wirings/agent/voice-output.test.ts +0 -510
- package/src/wirings/agent/voice-output.ts +0 -311
- package/src/wirings/agent-scorer/agent-scorer-grade.test.ts +0 -106
- package/src/wirings/agent-scorer/agent-scorer-grade.ts +0 -55
- package/src/wirings/agent-scorer/agent-scorer-judge.test.ts +0 -285
- package/src/wirings/agent-scorer/agent-scorer-judge.ts +0 -180
- package/src/wirings/agent-scorer/agent-scorer-live.test.ts +0 -174
- package/src/wirings/agent-scorer/agent-scorer-live.ts +0 -56
- package/src/wirings/agent-scorer/agent-scorer-registry.ts +0 -66
- package/src/wirings/agent-scorer/agent-scorer-sampling.test.ts +0 -34
- package/src/wirings/agent-scorer/agent-scorer-sampling.ts +0 -36
- package/src/wirings/agent-scorer/agent-scorer-snapshots.test.ts +0 -49
- package/src/wirings/agent-scorer/agent-scorer-snapshots.ts +0 -46
- package/src/wirings/agent-scorer/agent-scorer-worker.test.ts +0 -122
- package/src/wirings/agent-scorer/agent-scorer-worker.ts +0 -71
- package/src/wirings/agent-scorer/agent-scorer.ts +0 -102
- package/src/wirings/agent-scorer/agent-scorer.types.ts +0 -128
- package/src/wirings/agent-scorer/index.ts +0 -23
- package/src/wirings/channel/channel-common.ts +0 -102
- package/src/wirings/channel/channel-handler-shapes.test.ts +0 -72
- package/src/wirings/channel/channel-handler.test.ts +0 -322
- package/src/wirings/channel/channel-handler.ts +0 -259
- package/src/wirings/channel/channel-host-rpc.test.ts +0 -150
- package/src/wirings/channel/channel-host-rpc.ts +0 -69
- package/src/wirings/channel/channel-middleware-runner.test.ts +0 -188
- package/src/wirings/channel/channel-middleware-runner.ts +0 -126
- package/src/wirings/channel/channel-rpc-registry.ts +0 -116
- package/src/wirings/channel/channel-rpc-responder.ts +0 -117
- package/src/wirings/channel/channel-rpc-service.ts +0 -132
- package/src/wirings/channel/channel-rpc-validators.ts +0 -65
- package/src/wirings/channel/channel-rpc.test.ts +0 -841
- package/src/wirings/channel/channel-rpc.ts +0 -5
- package/src/wirings/channel/channel-rpc.types.ts +0 -160
- package/src/wirings/channel/channel-runner.ts +0 -164
- package/src/wirings/channel/channel-store.ts +0 -35
- package/src/wirings/channel/channel.types.ts +0 -193
- package/src/wirings/channel/define-channel-routes.ts +0 -5
- package/src/wirings/channel/eventhub-service.ts +0 -16
- package/src/wirings/channel/eventhub-store.ts +0 -13
- package/src/wirings/channel/index.ts +0 -40
- package/src/wirings/channel/local/index.ts +0 -3
- package/src/wirings/channel/local/local-channel-handler.ts +0 -98
- package/src/wirings/channel/local/local-channel-runner.test.ts +0 -339
- package/src/wirings/channel/local/local-channel-runner.ts +0 -271
- package/src/wirings/channel/local/local-eventhub-service.test.ts +0 -77
- package/src/wirings/channel/local/local-eventhub-service.ts +0 -69
- package/src/wirings/channel/log-channels.ts +0 -16
- package/src/wirings/channel/pikku-abstract-channel-handler.test.ts +0 -135
- package/src/wirings/channel/pikku-abstract-channel-handler.ts +0 -60
- package/src/wirings/channel/serverless/index.ts +0 -6
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +0 -328
- package/src/wirings/cli/channel/cli-approval.test.ts +0 -177
- package/src/wirings/cli/channel/cli-approval.ts +0 -135
- package/src/wirings/cli/channel/cli-channel-runner.ts +0 -118
- package/src/wirings/cli/channel/cli-raw-channel-runner.test.ts +0 -192
- package/src/wirings/cli/channel/cli-raw-channel-runner.ts +0 -148
- package/src/wirings/cli/channel/cli-raw-client-runner.test.ts +0 -480
- package/src/wirings/cli/channel/cli-raw-client-runner.ts +0 -188
- package/src/wirings/cli/channel/index.ts +0 -6
- package/src/wirings/cli/cli-runner.test.ts +0 -969
- package/src/wirings/cli/cli-runner.ts +0 -538
- package/src/wirings/cli/cli.types.ts +0 -388
- package/src/wirings/cli/command-parser.test.ts +0 -1120
- package/src/wirings/cli/command-parser.ts +0 -713
- package/src/wirings/cli/define-cli-commands.ts +0 -13
- package/src/wirings/cli/format-cli-error.test.ts +0 -91
- package/src/wirings/cli/format-cli-error.ts +0 -96
- package/src/wirings/cli/index.ts +0 -19
- package/src/wirings/credential/credential.types.ts +0 -37
- package/src/wirings/credential/define-credential.ts +0 -49
- package/src/wirings/credential/index.ts +0 -7
- package/src/wirings/credential/validate-credential-definitions.ts +0 -63
- package/src/wirings/gateway/gateway-authorization.test.ts +0 -575
- package/src/wirings/gateway/gateway-channel-meta.test.ts +0 -44
- package/src/wirings/gateway/gateway-runner.test.ts +0 -581
- package/src/wirings/gateway/gateway-runner.ts +0 -411
- package/src/wirings/gateway/gateway.types.ts +0 -137
- package/src/wirings/gateway/index.ts +0 -15
- package/src/wirings/http/http-routes.test.ts +0 -318
- package/src/wirings/http/http-routes.ts +0 -111
- package/src/wirings/http/http-runner-addon-ref.test.ts +0 -238
- package/src/wirings/http/http-runner.test.ts +0 -503
- package/src/wirings/http/http-runner.ts +0 -462
- package/src/wirings/http/http.types.ts +0 -307
- package/src/wirings/http/index.ts +0 -27
- package/src/wirings/http/log-http-routes.ts +0 -18
- package/src/wirings/http/pikku-fetch-http-request.test.ts +0 -318
- package/src/wirings/http/pikku-fetch-http-request.ts +0 -260
- package/src/wirings/http/pikku-fetch-http-response.test.ts +0 -123
- package/src/wirings/http/pikku-fetch-http-response.ts +0 -149
- package/src/wirings/http/routers/http-router.ts +0 -13
- package/src/wirings/http/routers/path-to-regex.test.ts +0 -306
- package/src/wirings/http/routers/path-to-regex.ts +0 -115
- package/src/wirings/http/web-request.test.ts +0 -382
- package/src/wirings/http/web-request.ts +0 -162
- package/src/wirings/mcp/index.ts +0 -26
- package/src/wirings/mcp/mcp-endpoint-registry.test.ts +0 -388
- package/src/wirings/mcp/mcp-endpoint-registry.ts +0 -159
- package/src/wirings/mcp/mcp-runner.test.ts +0 -588
- package/src/wirings/mcp/mcp-runner.ts +0 -330
- package/src/wirings/mcp/mcp.types.ts +0 -199
- package/src/wirings/node/index.ts +0 -2
- package/src/wirings/node/node.types.ts +0 -23
- package/src/wirings/oauth2/index.ts +0 -1
- package/src/wirings/oauth2/oauth2.types.ts +0 -12
- package/src/wirings/persona/define-personas.ts +0 -33
- package/src/wirings/persona/index.ts +0 -75
- package/src/wirings/persona/persona-app-scopes.test.ts +0 -47
- package/src/wirings/persona/persona-app-scopes.ts +0 -74
- package/src/wirings/persona/persona-email.ts +0 -87
- package/src/wirings/persona/persona-environments.test.ts +0 -194
- package/src/wirings/persona/persona-environments.ts +0 -138
- package/src/wirings/persona/persona-mailbox.ts +0 -156
- package/src/wirings/persona/persona.test.ts +0 -230
- package/src/wirings/persona/persona.types.ts +0 -156
- package/src/wirings/persona/validate-personas.ts +0 -137
- package/src/wirings/queue/index.ts +0 -29
- package/src/wirings/queue/queue-identity.test.ts +0 -454
- package/src/wirings/queue/queue-identity.ts +0 -176
- package/src/wirings/queue/queue-runner.test.ts +0 -705
- package/src/wirings/queue/queue-runner.ts +0 -181
- package/src/wirings/queue/queue.types.ts +0 -161
- package/src/wirings/queue/register-queue-helper.ts +0 -46
- package/src/wirings/queue/signed-queue-service.ts +0 -60
- package/src/wirings/queue/validate-worker-config.test.ts +0 -108
- package/src/wirings/queue/validate-worker-config.ts +0 -90
- package/src/wirings/role/define-system-role.ts +0 -33
- package/src/wirings/role/index.ts +0 -13
- package/src/wirings/role/role.test.ts +0 -104
- package/src/wirings/role/role.types.ts +0 -47
- package/src/wirings/role/validate-role-definitions.ts +0 -93
- package/src/wirings/rpc/index.ts +0 -8
- package/src/wirings/rpc/rpc-runner.test.ts +0 -1130
- package/src/wirings/rpc/rpc-runner.ts +0 -569
- package/src/wirings/rpc/rpc-types.ts +0 -87
- package/src/wirings/scheduler/index.ts +0 -11
- package/src/wirings/scheduler/log-schedulers.ts +0 -16
- package/src/wirings/scheduler/scheduler-runner.test.ts +0 -835
- package/src/wirings/scheduler/scheduler-runner.ts +0 -138
- package/src/wirings/scheduler/scheduler.types.ts +0 -42
- package/src/wirings/scope/define-scope.ts +0 -33
- package/src/wirings/scope/index.ts +0 -15
- package/src/wirings/scope/scope.test.ts +0 -159
- package/src/wirings/scope/scope.types.ts +0 -42
- package/src/wirings/scope/validate-scope-definitions.ts +0 -107
- package/src/wirings/secret/index.ts +0 -9
- package/src/wirings/secret/secret.types.ts +0 -70
- package/src/wirings/secret/validate-secret-definitions.test.ts +0 -232
- package/src/wirings/secret/validate-secret-definitions.ts +0 -88
- package/src/wirings/trigger/index.ts +0 -9
- package/src/wirings/trigger/pikku-trigger-service.ts +0 -107
- package/src/wirings/trigger/trigger-runner.test.ts +0 -78
- package/src/wirings/trigger/trigger-runner.ts +0 -113
- package/src/wirings/trigger/trigger.types.ts +0 -100
- package/src/wirings/variable/index.ts +0 -8
- package/src/wirings/variable/validate-variable-definitions.test.ts +0 -115
- package/src/wirings/variable/validate-variable-definitions.ts +0 -71
- package/src/wirings/variable/variable.types.ts +0 -40
- package/src/wirings/virtual-user/index.ts +0 -107
- package/src/wirings/virtual-user/prepare-virtual-user-run.test.ts +0 -115
- package/src/wirings/virtual-user/prepare-virtual-user-run.ts +0 -95
- package/src/wirings/virtual-user/run-virtual-user.test.ts +0 -774
- package/src/wirings/virtual-user/run-virtual-user.ts +0 -684
- package/src/wirings/virtual-user/virtual-user-agents.test.ts +0 -72
- package/src/wirings/virtual-user/virtual-user-agents.ts +0 -62
- package/src/wirings/virtual-user/virtual-user-catalogue.test.ts +0 -215
- package/src/wirings/virtual-user/virtual-user-catalogue.ts +0 -184
- package/src/wirings/virtual-user/virtual-user-derive.test.ts +0 -426
- package/src/wirings/virtual-user/virtual-user-derive.ts +0 -161
- package/src/wirings/virtual-user/virtual-user-dispositions.test.ts +0 -68
- package/src/wirings/virtual-user/virtual-user-dispositions.ts +0 -210
- package/src/wirings/virtual-user/virtual-user-intents.test.ts +0 -218
- package/src/wirings/virtual-user/virtual-user-intents.ts +0 -185
- package/src/wirings/virtual-user/virtual-user-rng.test.ts +0 -72
- package/src/wirings/virtual-user/virtual-user-rng.ts +0 -50
- package/src/wirings/virtual-user/virtual-user-run-store.ts +0 -131
- package/src/wirings/virtual-user/virtual-user-scaffold.test.ts +0 -854
- package/src/wirings/virtual-user/virtual-user-scaffold.ts +0 -664
- package/src/wirings/virtual-user/virtual-user-schedule-store.ts +0 -93
- package/src/wirings/virtual-user/virtual-user-schedule.test.ts +0 -280
- package/src/wirings/virtual-user/virtual-user-schedule.ts +0 -156
- package/src/wirings/virtual-user/virtual-user-target.ts +0 -47
- package/src/wirings/virtual-user/virtual-user.types.ts +0 -215
- package/src/wirings/workflow/dsl/workflow-dsl.types.ts +0 -709
- package/src/wirings/workflow/dsl/workflow-runner.ts +0 -25
- package/src/wirings/workflow/feature.test.ts +0 -131
- package/src/wirings/workflow/feature.ts +0 -59
- package/src/wirings/workflow/graph/graph-foreach-queued.test.ts +0 -569
- package/src/wirings/workflow/graph/graph-foreach.test.ts +0 -626
- package/src/wirings/workflow/graph/graph-node.ts +0 -115
- package/src/wirings/workflow/graph/graph-runner.test.ts +0 -1049
- package/src/wirings/workflow/graph/graph-runner.ts +0 -1376
- package/src/wirings/workflow/graph/graph-validation.test.ts +0 -27
- package/src/wirings/workflow/graph/graph-validation.ts +0 -41
- package/src/wirings/workflow/graph/template.test.ts +0 -49
- package/src/wirings/workflow/graph/template.ts +0 -42
- package/src/wirings/workflow/graph/wire-workflow-graph.ts +0 -39
- package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -75
- package/src/wirings/workflow/index.ts +0 -107
- package/src/wirings/workflow/pikku-scenario-service.ts +0 -1013
- package/src/wirings/workflow/pikku-workflow-service.test.ts +0 -963
- package/src/wirings/workflow/pikku-workflow-service.ts +0 -1993
- package/src/wirings/workflow/run-timeline.test.ts +0 -199
- package/src/wirings/workflow/run-timeline.ts +0 -185
- package/src/wirings/workflow/scenario-cookie-jar.test.ts +0 -107
- package/src/wirings/workflow/scenario-cookie-jar.ts +0 -57
- package/src/wirings/workflow/scenario-expectations.test.ts +0 -238
- package/src/wirings/workflow/scenario-hooks.test.ts +0 -259
- package/src/wirings/workflow/scenario-poll.test.ts +0 -64
- package/src/wirings/workflow/scenario-poll.ts +0 -27
- package/src/wirings/workflow/scenario-prose.test.ts +0 -275
- package/src/wirings/workflow/scenario-prose.ts +0 -86
- package/src/wirings/workflow/scenario-run.types.ts +0 -193
- package/src/wirings/workflow/scenario-service.test.ts +0 -147
- package/src/wirings/workflow/scenario-step-guards.ts +0 -23
- package/src/wirings/workflow/scenario-step.test.ts +0 -800
- package/src/wirings/workflow/scenario-step.types.ts +0 -262
- package/src/wirings/workflow/scenario-surface.test.ts +0 -146
- package/src/wirings/workflow/scenario-surface.ts +0 -71
- package/src/wirings/workflow/scenario.types.ts +0 -63
- package/src/wirings/workflow/workflow-approval-audit.ts +0 -47
- package/src/wirings/workflow/workflow-approval-policy.test.ts +0 -594
- package/src/wirings/workflow/workflow-approval-policy.ts +0 -68
- package/src/wirings/workflow/workflow-approval.ts +0 -290
- package/src/wirings/workflow/workflow-child-run-session.test.ts +0 -168
- package/src/wirings/workflow/workflow-constants.ts +0 -66
- package/src/wirings/workflow/workflow-dispatch-durability.test.ts +0 -116
- package/src/wirings/workflow/workflow-dispatch-payload.test.ts +0 -55
- package/src/wirings/workflow/workflow-dispatch-relay.test.ts +0 -128
- package/src/wirings/workflow/workflow-errors.ts +0 -132
- package/src/wirings/workflow/workflow-inline-authority.test.ts +0 -175
- package/src/wirings/workflow/workflow-invocation-id.test.ts +0 -51
- package/src/wirings/workflow/workflow-invocation-id.ts +0 -28
- package/src/wirings/workflow/workflow-meta-resolver.ts +0 -45
- package/src/wirings/workflow/workflow-mirror.test.ts +0 -171
- package/src/wirings/workflow/workflow-missing-meta.test.ts +0 -92
- package/src/wirings/workflow/workflow-on-error.test.ts +0 -145
- package/src/wirings/workflow/workflow-queue-routing.ts +0 -129
- package/src/wirings/workflow/workflow-queue-wiring.ts +0 -149
- package/src/wirings/workflow/workflow-queue-workers.test.ts +0 -131
- package/src/wirings/workflow/workflow-queue-workers.ts +0 -66
- package/src/wirings/workflow/workflow-recovery.ts +0 -192
- package/src/wirings/workflow/workflow-replay-snapshot.test.ts +0 -140
- package/src/wirings/workflow/workflow-retry-policy.test.ts +0 -113
- package/src/wirings/workflow/workflow-run-authority.test.ts +0 -212
- package/src/wirings/workflow/workflow-run-context.test.ts +0 -172
- package/src/wirings/workflow/workflow-run-engine.types.ts +0 -92
- package/src/wirings/workflow/workflow-run-ownership.ts +0 -37
- package/src/wirings/workflow/workflow-run-polling.test.ts +0 -127
- package/src/wirings/workflow/workflow-stalled-recovery.test.ts +0 -152
- package/src/wirings/workflow/workflow-status-stream.test.ts +0 -354
- package/src/wirings/workflow/workflow-status-stream.ts +0 -144
- package/src/wirings/workflow/workflow-step-claim.ts +0 -46
- package/src/wirings/workflow/workflow-step-ordinal.test.ts +0 -94
- package/src/wirings/workflow/workflow-step-session.test.ts +0 -87
- package/src/wirings/workflow/workflow-suspend.ts +0 -61
- package/src/wirings/workflow/workflow-terminal-run-guard.test.ts +0 -105
- package/src/wirings/workflow/workflow.types.ts +0 -268
- package/src/wirings-stay-decoupled.test.ts +0 -130
- package/tsconfig.json +0 -14
- package/tsconfig.tsbuildinfo +0 -1
- package/tsconfig.type-tests.json +0 -15
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import { getSingletonServices } from '../pikku-state.js'
|
|
2
|
-
import { getDurationInMilliseconds } from '../time-utils.js'
|
|
3
|
-
import { safeFetch } from '../utils/safe-fetch.js'
|
|
4
|
-
import type { JobOptions, QueueService } from '../wirings/queue/queue.types.js'
|
|
5
|
-
import type { Logger } from './logger.js'
|
|
6
|
-
import {
|
|
7
|
-
DEFAULT_WEBHOOK_RETRIES,
|
|
8
|
-
DEFAULT_WEBHOOK_SIGNATURE_HEADER,
|
|
9
|
-
PIKKU_OUTGOING_WEBHOOK_QUEUE_NAME,
|
|
10
|
-
type SendWebhookInput,
|
|
11
|
-
type SendWebhookResult,
|
|
12
|
-
type WebhookJobData,
|
|
13
|
-
WebhookService,
|
|
14
|
-
} from './webhook-service.js'
|
|
15
|
-
|
|
16
|
-
const MAX_CAPTURED_RESPONSE_BODY = 2_000
|
|
17
|
-
|
|
18
|
-
// knowledge: decisions/security/webhook-bodies-are-signed-before-they-are-enqueued.md
|
|
19
|
-
export class QueueWebhookService extends WebhookService {
|
|
20
|
-
// knowledge: decisions/internals/webhook-service-collaborators-are-constructor-args-not-locator-lookups.md
|
|
21
|
-
constructor(protected queueService: QueueService) {
|
|
22
|
-
super()
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
public async send(input: SendWebhookInput): Promise<SendWebhookResult> {
|
|
26
|
-
const { jobData, options } = await this.prepareDelivery(input)
|
|
27
|
-
const jobId = await this.queueService.add(
|
|
28
|
-
PIKKU_OUTGOING_WEBHOOK_QUEUE_NAME,
|
|
29
|
-
jobData,
|
|
30
|
-
options
|
|
31
|
-
)
|
|
32
|
-
return { jobId }
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* `protected` so a store-backed subclass can persist a delivery row and attach
|
|
37
|
-
* its `deliveryId` without re-implementing signing or the retry policy.
|
|
38
|
-
*/
|
|
39
|
-
protected async prepareDelivery(
|
|
40
|
-
input: SendWebhookInput
|
|
41
|
-
): Promise<{ jobData: WebhookJobData; options: JobOptions }> {
|
|
42
|
-
const services = getSingletonServices()
|
|
43
|
-
const webhookConfig = services.config?.webhook
|
|
44
|
-
|
|
45
|
-
const body = JSON.stringify(input.data)
|
|
46
|
-
const headers: Record<string, string> = {
|
|
47
|
-
'Content-Type': 'application/json',
|
|
48
|
-
...(input.event ? { 'X-Pikku-Event': input.event } : {}),
|
|
49
|
-
...input.headers,
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
let secret = input.secret
|
|
53
|
-
if (secret === undefined && webhookConfig?.secret) {
|
|
54
|
-
// Naive read: caching is the secret service's concern, not ours.
|
|
55
|
-
secret = (await services.secrets.getSecret(webhookConfig.secret)).reveal()
|
|
56
|
-
if (!secret) {
|
|
57
|
-
services.logger.error(
|
|
58
|
-
`Webhook signing secret '${webhookConfig.secret}' (config.webhook.secret) resolved to nothing — outgoing webhooks will be sent UNSIGNED.`
|
|
59
|
-
)
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
if (secret) {
|
|
63
|
-
const signatureHeader =
|
|
64
|
-
webhookConfig?.signatureHeader ?? DEFAULT_WEBHOOK_SIGNATURE_HEADER
|
|
65
|
-
headers[signatureHeader] = this.sign(secret, body)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const jobData: WebhookJobData = {
|
|
69
|
-
url: input.url,
|
|
70
|
-
...(input.event ? { event: input.event } : {}),
|
|
71
|
-
body,
|
|
72
|
-
headers,
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return { jobData, options: this.resolveJobOptions(input) }
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// knowledge: decisions/internals/queue-jobs-always-carry-an-explicit-attempts-count.md
|
|
79
|
-
private resolveJobOptions(input: SendWebhookInput): JobOptions {
|
|
80
|
-
const webhookConfig = getSingletonServices().config?.webhook
|
|
81
|
-
const retries =
|
|
82
|
-
input.retries ?? webhookConfig?.retries ?? DEFAULT_WEBHOOK_RETRIES
|
|
83
|
-
const retryDelay = input.retryDelay ?? webhookConfig?.retryDelay
|
|
84
|
-
const backoff =
|
|
85
|
-
retryDelay !== undefined && retryDelay !== 'exponential'
|
|
86
|
-
? { type: 'fixed', delay: getDurationInMilliseconds(retryDelay) }
|
|
87
|
-
: retries > 0 || retryDelay === 'exponential'
|
|
88
|
-
? 'exponential'
|
|
89
|
-
: undefined
|
|
90
|
-
return { attempts: retries + 1, ...(backoff ? { backoff } : {}) }
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// knowledge: decisions/internals/webhook-delivery-history-records-every-attempt-best-effort.md
|
|
95
|
-
export async function pikkuWebhookWorkerFunc(
|
|
96
|
-
services: { logger: Logger; webhookService?: WebhookService },
|
|
97
|
-
{ url, body, headers, deliveryId }: WebhookJobData
|
|
98
|
-
): Promise<void> {
|
|
99
|
-
let statusCode: number | undefined
|
|
100
|
-
let responseBody: string | undefined
|
|
101
|
-
let error: string | undefined
|
|
102
|
-
let delivered = false
|
|
103
|
-
|
|
104
|
-
let allowedHosts: string[] | undefined
|
|
105
|
-
try {
|
|
106
|
-
allowedHosts = getSingletonServices().config?.webhook?.allowedHosts
|
|
107
|
-
} catch {
|
|
108
|
-
// Uninitialised singletons (a bare worker invocation): fall back to the
|
|
109
|
-
// default private-host block rather than failing the delivery.
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
try {
|
|
113
|
-
const response = await safeFetch(
|
|
114
|
-
url,
|
|
115
|
-
{
|
|
116
|
-
method: 'POST',
|
|
117
|
-
headers,
|
|
118
|
-
body,
|
|
119
|
-
signal: AbortSignal.timeout(30_000),
|
|
120
|
-
},
|
|
121
|
-
{ allowedHosts }
|
|
122
|
-
)
|
|
123
|
-
statusCode = response.status
|
|
124
|
-
delivered = response.status >= 200 && response.status < 300
|
|
125
|
-
if (!delivered) {
|
|
126
|
-
responseBody = (await response.text().catch(() => ''))?.slice(
|
|
127
|
-
0,
|
|
128
|
-
MAX_CAPTURED_RESPONSE_BODY
|
|
129
|
-
)
|
|
130
|
-
error = `Webhook delivery to ${url} failed with status ${response.status}`
|
|
131
|
-
}
|
|
132
|
-
} catch (e) {
|
|
133
|
-
error = e instanceof Error ? e.message : String(e)
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
if (deliveryId && services.webhookService) {
|
|
137
|
-
await services.webhookService
|
|
138
|
-
.recordAttempt(deliveryId, { statusCode, responseBody, error, delivered })
|
|
139
|
-
.catch((storeError) =>
|
|
140
|
-
services.logger.error(
|
|
141
|
-
`Failed to record webhook delivery attempt for ${deliveryId}`,
|
|
142
|
-
storeError
|
|
143
|
-
)
|
|
144
|
-
)
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (!delivered) {
|
|
148
|
-
throw new Error(error ?? `Webhook delivery to ${url} failed`)
|
|
149
|
-
}
|
|
150
|
-
}
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import { describe, test } from 'node:test'
|
|
2
|
-
import assert from 'node:assert/strict'
|
|
3
|
-
import { BadRequestError, UnauthorizedError } from '../errors/errors.js'
|
|
4
|
-
import { resetPikkuState, setSingletonServices } from '../pikku-state.js'
|
|
5
|
-
import { remoteJobsSecret } from '../middleware/remote-jobs-secret.js'
|
|
6
|
-
import {
|
|
7
|
-
REMOTE_JOBS_SECRET_HEADER,
|
|
8
|
-
pikkuRemoteScheduledJobFunc,
|
|
9
|
-
} from './remote-jobs.js'
|
|
10
|
-
|
|
11
|
-
const silentLogger = {
|
|
12
|
-
info: () => {},
|
|
13
|
-
warn: () => {},
|
|
14
|
-
error: () => {},
|
|
15
|
-
debug: () => {},
|
|
16
|
-
} as any
|
|
17
|
-
|
|
18
|
-
const wire = (header?: string) =>
|
|
19
|
-
({
|
|
20
|
-
http: { request: { header: () => header ?? null } },
|
|
21
|
-
}) as any
|
|
22
|
-
|
|
23
|
-
const services = (secret?: string) =>
|
|
24
|
-
({ variables: { get: async () => secret } }) as any
|
|
25
|
-
|
|
26
|
-
describe('remoteJobsSecret', () => {
|
|
27
|
-
test('lets a caller holding the secret through', async () => {
|
|
28
|
-
let reached = false
|
|
29
|
-
await remoteJobsSecret(services('s3cret'), wire('s3cret'), async () => {
|
|
30
|
-
reached = true
|
|
31
|
-
})
|
|
32
|
-
assert.equal(reached, true)
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
test('rejects a caller presenting the wrong secret', async () => {
|
|
36
|
-
await assert.rejects(
|
|
37
|
-
remoteJobsSecret(services('s3cret'), wire('nope'), async () => {}),
|
|
38
|
-
UnauthorizedError
|
|
39
|
-
)
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
test('rejects when the deployment configured no secret at all', async () => {
|
|
43
|
-
await assert.rejects(
|
|
44
|
-
remoteJobsSecret(services(undefined), wire('anything'), async () => {}),
|
|
45
|
-
UnauthorizedError
|
|
46
|
-
)
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
test('rejects a caller presenting no header', async () => {
|
|
50
|
-
await assert.rejects(
|
|
51
|
-
remoteJobsSecret(services('s3cret'), wire(), async () => {}),
|
|
52
|
-
UnauthorizedError
|
|
53
|
-
)
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
test('reads the header the dispatchers already send', async () => {
|
|
57
|
-
const seen: string[] = []
|
|
58
|
-
await assert.rejects(
|
|
59
|
-
remoteJobsSecret(
|
|
60
|
-
services('s3cret'),
|
|
61
|
-
{
|
|
62
|
-
http: {
|
|
63
|
-
request: {
|
|
64
|
-
header: (name: string) => {
|
|
65
|
-
seen.push(name)
|
|
66
|
-
return null
|
|
67
|
-
},
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
} as any,
|
|
71
|
-
async () => {}
|
|
72
|
-
),
|
|
73
|
-
UnauthorizedError
|
|
74
|
-
)
|
|
75
|
-
assert.deepEqual(seen, [REMOTE_JOBS_SECRET_HEADER])
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
test('awaits a variables service that resolves asynchronously', async () => {
|
|
79
|
-
let reached = false
|
|
80
|
-
await remoteJobsSecret(
|
|
81
|
-
{
|
|
82
|
-
variables: {
|
|
83
|
-
get: () => new Promise((resolve) => setTimeout(() => resolve('s3cret'), 1)),
|
|
84
|
-
},
|
|
85
|
-
} as any,
|
|
86
|
-
wire('s3cret'),
|
|
87
|
-
async () => {
|
|
88
|
-
reached = true
|
|
89
|
-
}
|
|
90
|
-
)
|
|
91
|
-
assert.equal(reached, true)
|
|
92
|
-
})
|
|
93
|
-
})
|
|
94
|
-
|
|
95
|
-
describe('pikkuRemoteScheduledJobFunc', () => {
|
|
96
|
-
test('acks a task this deployment does not have rather than asking for a retry', async () => {
|
|
97
|
-
resetPikkuState()
|
|
98
|
-
setSingletonServices({ logger: silentLogger } as any)
|
|
99
|
-
await assert.rejects(
|
|
100
|
-
pikkuRemoteScheduledJobFunc({ logger: silentLogger }, {
|
|
101
|
-
taskName: 'not-a-task',
|
|
102
|
-
}),
|
|
103
|
-
BadRequestError
|
|
104
|
-
)
|
|
105
|
-
})
|
|
106
|
-
})
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import { BadRequestError, PikkuMissingMetaError } from '../errors/errors.js'
|
|
2
|
-
import { QueueJobDiscardedError, runQueueJob } from '../wirings/queue/queue-runner.js'
|
|
3
|
-
import type { QueueJob, QueueJobStatus } from '../wirings/queue/queue.types.js'
|
|
4
|
-
import {
|
|
5
|
-
ScheduledTaskNotFoundError,
|
|
6
|
-
runScheduledTask,
|
|
7
|
-
} from '../wirings/scheduler/scheduler-runner.js'
|
|
8
|
-
import type { Logger } from './logger.js'
|
|
9
|
-
|
|
10
|
-
/** The variable holding the shared secret every remote job must present. */
|
|
11
|
-
export const REMOTE_JOBS_SECRET_VARIABLE = 'PIKKU_DISPATCH_SECRET'
|
|
12
|
-
|
|
13
|
-
export const REMOTE_JOBS_SECRET_HEADER = 'x-pikku-dispatch'
|
|
14
|
-
|
|
15
|
-
export const REMOTE_QUEUE_JOB_PATH = '/__pikku/queue-job'
|
|
16
|
-
|
|
17
|
-
export const REMOTE_SCHEDULER_JOB_PATH = '/__pikku/scheduler-job'
|
|
18
|
-
|
|
19
|
-
export interface RemoteQueueJobData {
|
|
20
|
-
queueName: string
|
|
21
|
-
data?: unknown
|
|
22
|
-
jobId?: string
|
|
23
|
-
traceId?: string
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export interface RemoteScheduledJobData {
|
|
27
|
-
taskName: string
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* A dispatched job is delivered, not owned: the sender retries, so a permanent
|
|
32
|
-
* failure has to read differently from a transient one. An unknown worker or a
|
|
33
|
-
* discarded job answers 4xx so the sender stops; anything else propagates and
|
|
34
|
-
* is delivered again.
|
|
35
|
-
*/
|
|
36
|
-
export async function pikkuRemoteQueueJobFunc(
|
|
37
|
-
{ logger }: { logger: Logger },
|
|
38
|
-
{ queueName, data, jobId, traceId }: RemoteQueueJobData
|
|
39
|
-
): Promise<void> {
|
|
40
|
-
const job: QueueJob = {
|
|
41
|
-
queueName,
|
|
42
|
-
data,
|
|
43
|
-
id: jobId ?? traceId ?? `remote-${Date.now()}`,
|
|
44
|
-
status: async (): Promise<QueueJobStatus> => 'active',
|
|
45
|
-
metadata: () => ({
|
|
46
|
-
processedAt: new Date(),
|
|
47
|
-
attemptsMade: 0,
|
|
48
|
-
maxAttempts: undefined,
|
|
49
|
-
result: undefined,
|
|
50
|
-
progress: 0,
|
|
51
|
-
createdAt: new Date(),
|
|
52
|
-
completedAt: undefined,
|
|
53
|
-
failedAt: undefined,
|
|
54
|
-
error: undefined,
|
|
55
|
-
}),
|
|
56
|
-
waitForCompletion: async () => {
|
|
57
|
-
throw new Error('remote jobs do not support waitForCompletion')
|
|
58
|
-
},
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
try {
|
|
62
|
-
await runQueueJob({ job, traceId })
|
|
63
|
-
} catch (error) {
|
|
64
|
-
if (
|
|
65
|
-
error instanceof PikkuMissingMetaError ||
|
|
66
|
-
error instanceof QueueJobDiscardedError
|
|
67
|
-
) {
|
|
68
|
-
throw new BadRequestError(error.message)
|
|
69
|
-
}
|
|
70
|
-
logger.error(
|
|
71
|
-
`remote-jobs: queue '${queueName}' failed: ${error instanceof Error ? error.message : String(error)}`
|
|
72
|
-
)
|
|
73
|
-
throw error
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export async function pikkuRemoteScheduledJobFunc(
|
|
78
|
-
{ logger }: { logger: Logger },
|
|
79
|
-
{ taskName }: RemoteScheduledJobData
|
|
80
|
-
): Promise<void> {
|
|
81
|
-
try {
|
|
82
|
-
await runScheduledTask({ name: taskName, traceId: `cron-${taskName}` })
|
|
83
|
-
} catch (error) {
|
|
84
|
-
if (error instanceof ScheduledTaskNotFoundError) {
|
|
85
|
-
throw new BadRequestError(error.message)
|
|
86
|
-
}
|
|
87
|
-
logger.error(
|
|
88
|
-
`remote-jobs: task '${taskName}' failed: ${error instanceof Error ? error.message : String(error)}`
|
|
89
|
-
)
|
|
90
|
-
throw error
|
|
91
|
-
}
|
|
92
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import type { CoreUserSession } from '../types/core.types.js'
|
|
2
|
-
|
|
3
|
-
export interface ScheduledTaskSummary {
|
|
4
|
-
taskId: string
|
|
5
|
-
rpcName: string
|
|
6
|
-
scheduledFor: Date
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export interface ScheduledTaskInfo extends ScheduledTaskSummary {
|
|
10
|
-
data?: any
|
|
11
|
-
session?: CoreUserSession
|
|
12
|
-
status?: 'scheduled' | 'active' | 'completed' | 'failed'
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export abstract class SchedulerService {
|
|
16
|
-
abstract init(): Promise<void>
|
|
17
|
-
|
|
18
|
-
/** `delay` is milliseconds as a number, or a duration string such as `"5h"` / `"30m"`. */
|
|
19
|
-
abstract scheduleRPC(
|
|
20
|
-
delay: number | string,
|
|
21
|
-
rpcName: string,
|
|
22
|
-
data?: any,
|
|
23
|
-
session?: CoreUserSession
|
|
24
|
-
): Promise<string>
|
|
25
|
-
|
|
26
|
-
abstract unschedule(taskId: string): Promise<boolean>
|
|
27
|
-
|
|
28
|
-
abstract getTask(taskId: string): Promise<ScheduledTaskInfo | null>
|
|
29
|
-
|
|
30
|
-
abstract getAllTasks(): Promise<ScheduledTaskSummary[]>
|
|
31
|
-
|
|
32
|
-
abstract close(): Promise<void>
|
|
33
|
-
|
|
34
|
-
async start(): Promise<void> {}
|
|
35
|
-
|
|
36
|
-
async stop(): Promise<void> {}
|
|
37
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export interface SchemaService {
|
|
2
|
-
compileSchema: (name: string, value: any) => Promise<void> | void
|
|
3
|
-
|
|
4
|
-
validateSchema: (schema: string, data: any) => Promise<void> | void
|
|
5
|
-
|
|
6
|
-
getSchemaNames: () => Set<string>
|
|
7
|
-
|
|
8
|
-
/** Empty when the schema is not registered. */
|
|
9
|
-
getSchemaKeys: (schemaName: string) => string[]
|
|
10
|
-
}
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import type { FlatScope } from '../wirings/scope/scope.types.js'
|
|
2
|
-
import type { SystemRole } from '../wirings/role/role.types.js'
|
|
3
|
-
|
|
4
|
-
export interface Role {
|
|
5
|
-
name: string
|
|
6
|
-
description?: string
|
|
7
|
-
scopes: string[]
|
|
8
|
-
/**
|
|
9
|
-
* True when the role was declared in code with `defineSystemRole` rather
|
|
10
|
-
* than composed by an admin. System roles may be granted, but not renamed,
|
|
11
|
-
* re-scoped or deleted — see {@link ScopeService.syncSystemRoles}.
|
|
12
|
-
*/
|
|
13
|
-
system?: boolean
|
|
14
|
-
/**
|
|
15
|
-
* False when a system role's declaration has been removed from code but its
|
|
16
|
-
* row survives: still held by whoever holds it, no longer offered for new
|
|
17
|
-
* grants, awaiting `pikku roles prune`.
|
|
18
|
-
*/
|
|
19
|
-
declared?: boolean
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// knowledge: decisions/security/scope-resolution-happens-at-the-session-boundary-and-sync-never-deletes.md
|
|
23
|
-
export interface ScopeService {
|
|
24
|
-
syncScopes(scopes: FlatScope[]): Promise<void>
|
|
25
|
-
|
|
26
|
-
/** The union of role-derived scopes and scopes granted directly. */
|
|
27
|
-
resolveScopes(userId: string): Promise<string[]>
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* The whole vocabulary a role can be composed from. `declared: false` marks a
|
|
31
|
-
* scope still in the store but no longer declared in code: inert, since no
|
|
32
|
-
* function can require it, and awaiting `pikku scopes prune`.
|
|
33
|
-
*/
|
|
34
|
-
listScopes(): Promise<Array<FlatScope & { declared: boolean }>>
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Registers the roles declared with `defineSystemRole`. Additive on the same
|
|
38
|
-
* terms as {@link syncScopes}: a removed declaration leaves the row in place,
|
|
39
|
-
* marked `declared: false`, rather than revoking everyone's grant on deploy.
|
|
40
|
-
*
|
|
41
|
-
* A role's scope set *is* re-synced, because that is the declaration's whole
|
|
42
|
-
* content — editing `defineSystemRole` is how you change what a system role
|
|
43
|
-
* means, and the deploy is when it takes effect.
|
|
44
|
-
*
|
|
45
|
-
* Called once during startup with the generated role list.
|
|
46
|
-
*/
|
|
47
|
-
syncSystemRoles(roles: SystemRole[]): Promise<void>
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Creates an admin-composed role.
|
|
51
|
-
*
|
|
52
|
-
* Must throw {@link SystemRoleShadowedError} when `role.name` matches a
|
|
53
|
-
* declared system role. Two rows answering to one name make "does this user
|
|
54
|
-
* hold `buyer`?" depend on which the store returns first.
|
|
55
|
-
*/
|
|
56
|
-
createRole(role: Role): Promise<void>
|
|
57
|
-
/** Must throw {@link SystemRoleImmutableError} for a system role. */
|
|
58
|
-
deleteRole(name: string): Promise<void>
|
|
59
|
-
/** Must throw {@link SystemRoleImmutableError} for a system role. */
|
|
60
|
-
setRoleScopes(name: string, scopes: string[]): Promise<void>
|
|
61
|
-
listRoles(): Promise<Role[]>
|
|
62
|
-
|
|
63
|
-
addUserToRole(userId: string, role: string, grantedBy?: string): Promise<void>
|
|
64
|
-
removeUserFromRole(userId: string, role: string): Promise<void>
|
|
65
|
-
listUserRoles(userId: string): Promise<string[]>
|
|
66
|
-
|
|
67
|
-
/** Grants outside of any role; additive with the user's role-derived scopes. */
|
|
68
|
-
addScopeToUser(
|
|
69
|
-
userId: string,
|
|
70
|
-
scope: string,
|
|
71
|
-
grantedBy?: string
|
|
72
|
-
): Promise<void>
|
|
73
|
-
removeScopeFromUser(userId: string, scope: string): Promise<void>
|
|
74
|
-
/** Only the scopes granted directly, not those inherited from roles. */
|
|
75
|
-
listUserScopes(userId: string): Promise<string[]>
|
|
76
|
-
|
|
77
|
-
/** Undeclared scopes with the roles that would lose them; powers `pikku scopes audit`. */
|
|
78
|
-
findStaleScopes(): Promise<Array<{ scope: string; roles: string[] }>>
|
|
79
|
-
|
|
80
|
-
/** Removes undeclared scopes, cascading them out of roles. */
|
|
81
|
-
pruneScopes(): Promise<string[]>
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* System roles in the store whose declaration has gone, with the number of
|
|
85
|
-
* users still holding each. Powers `pikku roles audit`.
|
|
86
|
-
*/
|
|
87
|
-
findStaleSystemRoles(): Promise<Array<{ role: string; users: number }>>
|
|
88
|
-
|
|
89
|
-
/** Removes undeclared system roles, cascading them out of user grants. */
|
|
90
|
-
pruneSystemRoles(): Promise<string[]>
|
|
91
|
-
}
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { describe, test } from 'node:test'
|
|
2
|
-
import assert from 'node:assert/strict'
|
|
3
|
-
|
|
4
|
-
import { ScopedCredentialService } from './scoped-credential-service.js'
|
|
5
|
-
import type { CredentialService } from './credential-service.js'
|
|
6
|
-
|
|
7
|
-
const createCredentialService = (): CredentialService => {
|
|
8
|
-
const store: Record<string, Record<string, unknown>> = {
|
|
9
|
-
'user-1': { slack: 'slack-token', stripe: 'stripe-key' },
|
|
10
|
-
'user-2': { slack: 'other-slack-token' },
|
|
11
|
-
}
|
|
12
|
-
return {
|
|
13
|
-
get: async (name, userId = 'user-1') =>
|
|
14
|
-
(store[userId]?.[name] ?? null) as never,
|
|
15
|
-
set: async (name, value, userId = 'user-1') => {
|
|
16
|
-
store[userId] = { ...store[userId], [name]: value }
|
|
17
|
-
},
|
|
18
|
-
delete: async (name, userId = 'user-1') => {
|
|
19
|
-
delete store[userId]?.[name]
|
|
20
|
-
},
|
|
21
|
-
has: async (name, userId = 'user-1') => name in (store[userId] ?? {}),
|
|
22
|
-
getAll: async (userId) => store[userId] ?? {},
|
|
23
|
-
getUsersWithCredential: async (name) =>
|
|
24
|
-
Object.keys(store).filter((userId) => name in store[userId]!),
|
|
25
|
-
getAllUsers: async () => Object.keys(store),
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const scoped = (names: string[]) =>
|
|
30
|
-
new ScopedCredentialService(createCredentialService(), new Set(names))
|
|
31
|
-
|
|
32
|
-
describe('ScopedCredentialService', () => {
|
|
33
|
-
test('a declared credential is readable and writable', async () => {
|
|
34
|
-
const credentials = scoped(['slack'])
|
|
35
|
-
|
|
36
|
-
assert.equal(await credentials.get('slack'), 'slack-token')
|
|
37
|
-
assert.equal(await credentials.has('slack'), true)
|
|
38
|
-
await credentials.set('slack', 'refreshed')
|
|
39
|
-
assert.equal(await credentials.get('slack'), 'refreshed')
|
|
40
|
-
await credentials.delete('slack')
|
|
41
|
-
assert.equal(await credentials.get('slack'), null)
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
test('an undeclared credential is denied on every accessor', async () => {
|
|
45
|
-
const credentials = scoped(['slack'])
|
|
46
|
-
|
|
47
|
-
await assert.rejects(() => credentials.get('stripe'), /denied/i)
|
|
48
|
-
await assert.rejects(() => credentials.has('stripe'), /denied/i)
|
|
49
|
-
await assert.rejects(() => credentials.set('stripe', 'x'), /denied/i)
|
|
50
|
-
await assert.rejects(() => credentials.delete('stripe'), /denied/i)
|
|
51
|
-
await assert.rejects(
|
|
52
|
-
() => credentials.getUsersWithCredential('stripe'),
|
|
53
|
-
/denied/i
|
|
54
|
-
)
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
test('getAll returns only the declared credentials, not the whole user', async () => {
|
|
58
|
-
const credentials = scoped(['slack'])
|
|
59
|
-
|
|
60
|
-
assert.deepEqual(await credentials.getAll('user-1'), {
|
|
61
|
-
slack: 'slack-token',
|
|
62
|
-
})
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
test('enumerating every user of the app is denied outright', async () => {
|
|
66
|
-
const credentials = scoped(['slack'])
|
|
67
|
-
|
|
68
|
-
await assert.rejects(() => credentials.getAllUsers(), /denied/i)
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
test('the users of a declared credential are still visible', async () => {
|
|
72
|
-
const credentials = scoped(['slack'])
|
|
73
|
-
|
|
74
|
-
assert.deepEqual(await credentials.getUsersWithCredential('slack'), [
|
|
75
|
-
'user-1',
|
|
76
|
-
'user-2',
|
|
77
|
-
])
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
test('an addon that declares nothing reaches nothing', async () => {
|
|
81
|
-
const credentials = scoped([])
|
|
82
|
-
|
|
83
|
-
await assert.rejects(() => credentials.get('slack'), /denied/i)
|
|
84
|
-
assert.deepEqual(await credentials.getAll('user-1'), {})
|
|
85
|
-
})
|
|
86
|
-
})
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import type { CredentialService } from './credential-service.js'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* A `CredentialService` narrowed to the credentials a package declared.
|
|
5
|
-
*
|
|
6
|
-
* Unlike `ScopedSecretService` this stays writable — an addon refreshing its
|
|
7
|
-
* own OAuth token is the normal case. What it cannot do is reach a credential
|
|
8
|
-
* it never declared, or enumerate the app's users.
|
|
9
|
-
*/
|
|
10
|
-
export class ScopedCredentialService implements CredentialService {
|
|
11
|
-
constructor(
|
|
12
|
-
private credentials: CredentialService,
|
|
13
|
-
private allowedNames: Set<string>
|
|
14
|
-
) {}
|
|
15
|
-
|
|
16
|
-
private assertAllowed(name: string): void {
|
|
17
|
-
if (!this.allowedNames.has(name)) {
|
|
18
|
-
throw new Error(`Access denied to credential: ${name}`)
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
async get<T = unknown>(name: string, userId?: string): Promise<T | null> {
|
|
23
|
-
this.assertAllowed(name)
|
|
24
|
-
return this.credentials.get<T>(name, userId)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
async set(name: string, value: unknown, userId?: string): Promise<void> {
|
|
28
|
-
this.assertAllowed(name)
|
|
29
|
-
return this.credentials.set(name, value, userId)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
async delete(name: string, userId?: string): Promise<void> {
|
|
33
|
-
this.assertAllowed(name)
|
|
34
|
-
return this.credentials.delete(name, userId)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
async has(name: string, userId?: string): Promise<boolean> {
|
|
38
|
-
this.assertAllowed(name)
|
|
39
|
-
return this.credentials.has(name, userId)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
async getAll(userId: string): Promise<Record<string, unknown>> {
|
|
43
|
-
const all = await this.credentials.getAll(userId)
|
|
44
|
-
const scoped: Record<string, unknown> = {}
|
|
45
|
-
for (const name of this.allowedNames) {
|
|
46
|
-
if (name in all) {
|
|
47
|
-
scoped[name] = all[name]
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
return scoped
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
async getUsersWithCredential(name: string): Promise<string[]> {
|
|
54
|
-
this.assertAllowed(name)
|
|
55
|
-
return this.credentials.getUsersWithCredential(name)
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
async getAllUsers(): Promise<string[]> {
|
|
59
|
-
throw new Error(
|
|
60
|
-
'Access denied: enumerating users is not allowed in a scoped credential service'
|
|
61
|
-
)
|
|
62
|
-
}
|
|
63
|
-
}
|