pipework 0.251.0 → 0.252.1
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 +11 -0
- package/dist/core/config/load.d.ts +2 -0
- package/dist/core/config/load.d.ts.map +1 -1
- package/dist/core/config/load.js +1 -0
- package/dist/core/config/load.js.map +1 -1
- package/dist/core/config/namespace.d.ts +1 -0
- package/dist/core/config/namespace.d.ts.map +1 -1
- package/dist/core/config/schema.d.ts +2 -0
- package/dist/core/config/schema.d.ts.map +1 -1
- package/dist/core/config/schema.js +1 -0
- package/dist/core/config/schema.js.map +1 -1
- package/dist/core/surface/types.d.ts +1 -0
- package/dist/core/surface/types.d.ts.map +1 -1
- package/dist/data/db/namespace.d.ts +3 -0
- package/dist/data/db/namespace.d.ts.map +1 -1
- package/dist/data/db/namespace.js +3 -0
- package/dist/data/db/namespace.js.map +1 -1
- package/dist/data/db/pool.d.ts.map +1 -1
- package/dist/data/db/pool.js +6 -1
- package/dist/data/db/pool.js.map +1 -1
- package/dist/data/db/query-label.d.ts +5 -0
- package/dist/data/db/query-label.d.ts.map +1 -0
- package/dist/data/db/query-label.js +11 -0
- package/dist/data/db/query-label.js.map +1 -0
- package/dist/data/db/query-watch.d.ts +21 -0
- package/dist/data/db/query-watch.d.ts.map +1 -0
- package/dist/data/db/query-watch.js +90 -0
- package/dist/data/db/query-watch.js.map +1 -0
- package/dist/data/query/postgres-js/driver.js +1 -1
- package/dist/data/query/postgres-js/driver.js.map +1 -1
- package/dist/data/query/postgres-js/session.d.ts +5 -1
- package/dist/data/query/postgres-js/session.d.ts.map +1 -1
- package/dist/data/query/postgres-js/session.js +16 -11
- package/dist/data/query/postgres-js/session.js.map +1 -1
- package/dist/data/query/utils.d.ts +2 -0
- package/dist/data/query/utils.d.ts.map +1 -1
- package/dist/data/query/utils.js.map +1 -1
- package/dist/infra/credits/schema.d.ts +1 -1
- package/dist/test/plugin.d.ts.map +1 -1
- package/dist/test/plugin.js +10 -4
- package/dist/test/plugin.js.map +1 -1
- package/package.json +4 -3
- package/src/async/jobs/abortable-delay.ts +18 -0
- package/src/async/jobs/claims.ts +52 -0
- package/src/async/jobs/cron.ts +179 -0
- package/src/async/jobs/errors.ts +56 -0
- package/src/async/jobs/exclusion.ts +117 -0
- package/src/async/jobs/execute.ts +219 -0
- package/src/async/jobs/index.ts +10 -0
- package/src/async/jobs/listener.ts +135 -0
- package/src/async/jobs/namespace.ts +20 -0
- package/src/async/jobs/queue-door.ts +44 -0
- package/src/async/jobs/queue.ts +1012 -0
- package/src/async/jobs/run-script.ts +67 -0
- package/src/async/jobs/scheduler.ts +218 -0
- package/src/async/jobs/schedules-table.ts +37 -0
- package/src/async/jobs/serialize-error.ts +48 -0
- package/src/async/jobs/table.ts +191 -0
- package/src/async/pipeline/define.ts +53 -0
- package/src/async/pipeline/errors.ts +35 -0
- package/src/async/pipeline/execute.ts +53 -0
- package/src/async/pipeline/index.ts +13 -0
- package/src/async/pipeline/namespace.ts +12 -0
- package/src/async/pipeline/resume.ts +67 -0
- package/src/async/pipeline/run-steps.ts +98 -0
- package/src/async/pipeline/types.ts +57 -0
- package/src/async/state-machine/define.ts +64 -0
- package/src/async/state-machine/errors.ts +29 -0
- package/src/async/state-machine/index.ts +3 -0
- package/src/async/state-machine/namespace.ts +12 -0
- package/src/async/state-machine/transition.ts +90 -0
- package/src/async/state-machine/types.ts +37 -0
- package/src/async/steps/errors.ts +31 -0
- package/src/async/steps/graph.ts +1214 -0
- package/src/async/steps/hash.ts +40 -0
- package/src/async/steps/index.ts +7 -0
- package/src/async/steps/namespace.ts +7 -0
- package/src/async/steps/table.ts +97 -0
- package/src/async/steps/types.ts +318 -0
- package/src/audit/chain/index.ts +9 -0
- package/src/audit/chain/install.ts +113 -0
- package/src/audit/chain/retire.ts +52 -0
- package/src/audit/chain/verify.ts +257 -0
- package/src/audit/query/cursor.ts +37 -0
- package/src/audit/query/index.ts +9 -0
- package/src/audit/query/query.ts +223 -0
- package/src/audit/schema/audit-record-fields.ts +68 -0
- package/src/audit/schema/audit-record.ts +23 -0
- package/src/auth/auth/audit.ts +31 -0
- package/src/auth/auth/chain.ts +84 -0
- package/src/auth/auth/cookie.ts +136 -0
- package/src/auth/auth/email-links.ts +311 -0
- package/src/auth/auth/guard.ts +128 -0
- package/src/auth/auth/index.ts +18 -0
- package/src/auth/auth/multi-org.ts +337 -0
- package/src/auth/auth/namespace.ts +34 -0
- package/src/auth/auth/parse-expiry.ts +13 -0
- package/src/auth/auth/passwords.ts +110 -0
- package/src/auth/auth/schema.ts +110 -0
- package/src/auth/auth/sessions.ts +565 -0
- package/src/auth/auth/sign-in.ts +156 -0
- package/src/auth/auth/signing-keys.ts +69 -0
- package/src/auth/auth/types.ts +26 -0
- package/src/auth/auth/uuid.ts +10 -0
- package/src/auth/rbac/cache.ts +55 -0
- package/src/auth/rbac/check.ts +30 -0
- package/src/auth/rbac/create.ts +35 -0
- package/src/auth/rbac/index.ts +5 -0
- package/src/auth/rbac/middleware.ts +20 -0
- package/src/auth/rbac/namespace.ts +15 -0
- package/src/auth/rbac/resolve.ts +31 -0
- package/src/auth/rbac/schema.sql +31 -0
- package/src/auth/rbac/seed.ts +67 -0
- package/src/auth/rbac/tables.ts +32 -0
- package/src/auth/rbac/types.ts +65 -0
- package/src/auth/tenant/extract.ts +33 -0
- package/src/auth/tenant/in-tenant.ts +49 -0
- package/src/auth/tenant/index.ts +7 -0
- package/src/auth/tenant/namespace.ts +23 -0
- package/src/auth/tenant/propagate.ts +20 -0
- package/src/auth/tenant/rls.ts +120 -0
- package/src/auth/tenant/scope.ts +33 -0
- package/src/auth/tenant/scoped-db.ts +581 -0
- package/src/auth/tenant/types.ts +14 -0
- package/src/auth/tenant/validate.ts +27 -0
- package/src/cli/commands/add.ts +158 -0
- package/src/cli/commands/alerts.ts +98 -0
- package/src/cli/commands/check.ts +1418 -0
- package/src/cli/commands/codemod.ts +78 -0
- package/src/cli/commands/db.ts +356 -0
- package/src/cli/commands/dev.ts +101 -0
- package/src/cli/commands/generate.ts +75 -0
- package/src/cli/commands/init.ts +36 -0
- package/src/cli/commands/install.ts +28 -0
- package/src/cli/commands/lint.ts +62 -0
- package/src/cli/commands/migrate.ts +132 -0
- package/src/cli/commands/openapi.ts +63 -0
- package/src/cli/commands/remove.ts +72 -0
- package/src/cli/commands/run.ts +50 -0
- package/src/cli/commands/scope.ts +54 -0
- package/src/cli/commands/serve.ts +68 -0
- package/src/cli/commands/shard.ts +31 -0
- package/src/cli/commands/shared/config-pipework-version.ts +28 -0
- package/src/cli/commands/shared/find-config.ts +22 -0
- package/src/cli/commands/shared/load-config.ts +35 -0
- package/src/cli/commands/shared/pnpm-install.ts +95 -0
- package/src/cli/commands/shared/report-removed.ts +8 -0
- package/src/cli/commands/sync.ts +32 -0
- package/src/cli/commands/test.ts +307 -0
- package/src/cli/commands/upgrade.ts +48 -0
- package/src/cli/dev-bootstrap.ts +24 -0
- package/src/cli/errors.ts +10 -0
- package/src/cli/index.ts +303 -0
- package/src/cli/output.ts +17 -0
- package/src/cli/port.ts +15 -0
- package/src/cli/surface-kinds.ts +20 -0
- package/src/client/index.ts +4 -0
- package/src/client/poll.ts +130 -0
- package/src/client/report-fault.ts +119 -0
- package/src/core/config/app-pool.ts +19 -0
- package/src/core/config/aws-env.ts +29 -0
- package/src/core/config/base-dir.ts +24 -0
- package/src/core/config/discover.ts +64 -0
- package/src/core/config/env-resolve.ts +87 -0
- package/src/core/config/env-types.ts +116 -0
- package/src/core/config/env.ts +55 -0
- package/src/core/config/errors.ts +9 -0
- package/src/core/config/import-config.ts +40 -0
- package/src/core/config/index.ts +8 -0
- package/src/core/config/load.ts +417 -0
- package/src/core/config/namespace.ts +14 -0
- package/src/core/config/resolve.ts +195 -0
- package/src/core/config/schema.ts +488 -0
- package/src/core/config/statement-observer.ts +48 -0
- package/src/core/config/ts-inline-hooks.ts +75 -0
- package/src/core/config/ts-register.ts +4 -0
- package/src/core/config/ts-resolve-hooks.ts +101 -0
- package/src/core/errors/base.ts +49 -0
- package/src/core/errors/http.ts +146 -0
- package/src/core/errors/index.ts +2 -0
- package/src/core/errors/namespace.ts +31 -0
- package/src/core/lifecycle/drain.ts +33 -0
- package/src/core/lifecycle/health.ts +72 -0
- package/src/core/lifecycle/index.ts +4 -0
- package/src/core/lifecycle/namespace.ts +7 -0
- package/src/core/lifecycle/startup.ts +102 -0
- package/src/core/lifecycle/types.ts +36 -0
- package/src/core/logging/context.ts +60 -0
- package/src/core/logging/error-chain.ts +68 -0
- package/src/core/logging/index.ts +5 -0
- package/src/core/logging/logger.ts +65 -0
- package/src/core/logging/namespace.ts +16 -0
- package/src/core/logging/proxy.ts +22 -0
- package/src/core/logging/redact-match.ts +24 -0
- package/src/core/logging/types.ts +47 -0
- package/src/core/pipework.ts +566 -0
- package/src/core/runtime/broker.ts +69 -0
- package/src/core/surface/http.ts +133 -0
- package/src/core/surface/index.ts +11 -0
- package/src/core/surface/job-timeout.ts +40 -0
- package/src/core/surface/namespace.ts +13 -0
- package/src/core/surface/script.ts +33 -0
- package/src/core/surface/start.ts +142 -0
- package/src/core/surface/types.ts +225 -0
- package/src/core/surface/validate.ts +88 -0
- package/src/core/surface/worker.ts +528 -0
- package/src/core/validation/connectivity.ts +49 -0
- package/src/core/validation/domain.ts +99 -0
- package/src/core/validation/index.ts +5 -0
- package/src/core/validation/queue-tables.ts +312 -0
- package/src/core/validation/rls-role.ts +138 -0
- package/src/core/validation/startup.ts +51 -0
- package/src/core/validation/surfaces.ts +65 -0
- package/src/core/validation/types.ts +25 -0
- package/src/data/db/advisory-lock.ts +55 -0
- package/src/data/db/aggregates.ts +172 -0
- package/src/data/db/array-elements.ts +111 -0
- package/src/data/db/bulk-set.ts +53 -0
- package/src/data/db/col/index.ts +14 -0
- package/src/data/db/composed.ts +53 -0
- package/src/data/db/db.ts +276 -0
- package/src/data/db/excluded.ts +16 -0
- package/src/data/db/expressions.ts +473 -0
- package/src/data/db/filter.ts +90 -0
- package/src/data/db/function-source.ts +114 -0
- package/src/data/db/identifiers.ts +16 -0
- package/src/data/db/idx/index.ts +9 -0
- package/src/data/db/in-list.ts +49 -0
- package/src/data/db/index.ts +9 -0
- package/src/data/db/insert-split.ts +137 -0
- package/src/data/db/instrumentation.ts +82 -0
- package/src/data/db/maintenance.ts +28 -0
- package/src/data/db/namespace.ts +107 -0
- package/src/data/db/owner-labels.ts +9 -0
- package/src/data/db/pool.ts +187 -0
- package/src/data/db/query-label.ts +13 -0
- package/src/data/db/query-watch.ts +116 -0
- package/src/data/db/raw-client-warning.ts +37 -0
- package/src/data/db/readonly.ts +23 -0
- package/src/data/db/reservation.ts +151 -0
- package/src/data/db/schema-features.ts +14 -0
- package/src/data/db/serializable.ts +83 -0
- package/src/data/db/sql.ts +1 -0
- package/src/data/db/timeouts.ts +76 -0
- package/src/data/db/types.ts +18 -0
- package/src/data/db/unbound.ts +33 -0
- package/src/data/db/values.ts +29 -0
- package/src/data/domain/brand.ts +15 -0
- package/src/data/domain/build-factory.ts +193 -0
- package/src/data/domain/build-schema.ts +161 -0
- package/src/data/domain/build-table.ts +355 -0
- package/src/data/domain/define.ts +239 -0
- package/src/data/domain/external-registry.ts +34 -0
- package/src/data/domain/external.ts +77 -0
- package/src/data/domain/field.ts +279 -0
- package/src/data/domain/index.ts +13 -0
- package/src/data/domain/naming.ts +6 -0
- package/src/data/domain/projections.ts +57 -0
- package/src/data/domain/trace-safe-projection.ts +31 -0
- package/src/data/domain/traits.ts +108 -0
- package/src/data/domain/types.ts +289 -0
- package/src/data/jsonb/composed.ts +18 -0
- package/src/data/jsonb/index.ts +1 -0
- package/src/data/jsonb/namespace.ts +30 -0
- package/src/data/jsonb/query.ts +86 -0
- package/src/data/migrate/append-only-generate.ts +47 -0
- package/src/data/migrate/applied.ts +47 -0
- package/src/data/migrate/apply.ts +309 -0
- package/src/data/migrate/check.ts +119 -0
- package/src/data/migrate/diff.ts +357 -0
- package/src/data/migrate/door-generate.ts +130 -0
- package/src/data/migrate/framework-rls.ts +58 -0
- package/src/data/migrate/generate.ts +201 -0
- package/src/data/migrate/history.ts +215 -0
- package/src/data/migrate/index.ts +9 -0
- package/src/data/migrate/internal-definitions.ts +175 -0
- package/src/data/migrate/post-process.ts +73 -0
- package/src/data/migrate/pragma.ts +73 -0
- package/src/data/migrate/provision-framework.ts +147 -0
- package/src/data/migrate/rls-generate.ts +61 -0
- package/src/data/migrate/run.ts +124 -0
- package/src/data/migrate/safety.ts +167 -0
- package/src/data/migrate/snapshot.ts +368 -0
- package/src/data/migrate/sql-emit.ts +392 -0
- package/src/data/migrate/statements.ts +312 -0
- package/src/data/query/alias.ts +126 -0
- package/src/data/query/batch.ts +8 -0
- package/src/data/query/cache/core/cache.ts +78 -0
- package/src/data/query/cache/core/index.ts +1 -0
- package/src/data/query/cache/core/types.ts +29 -0
- package/src/data/query/cache/readme.md +230 -0
- package/src/data/query/casing.ts +76 -0
- package/src/data/query/collation.ts +11 -0
- package/src/data/query/column-builder.ts +370 -0
- package/src/data/query/column.ts +150 -0
- package/src/data/query/entity.ts +42 -0
- package/src/data/query/errors.ts +33 -0
- package/src/data/query/index.ts +14 -0
- package/src/data/query/logger.ts +47 -0
- package/src/data/query/operations.ts +45 -0
- package/src/data/query/pg-core/alias.ts +12 -0
- package/src/data/query/pg-core/checks.ts +32 -0
- package/src/data/query/pg-core/columns/all.ts +71 -0
- package/src/data/query/pg-core/columns/bigint.ts +110 -0
- package/src/data/query/pg-core/columns/bigserial.ts +128 -0
- package/src/data/query/pg-core/columns/boolean.ts +43 -0
- package/src/data/query/pg-core/columns/char.ts +85 -0
- package/src/data/query/pg-core/columns/cidr.ts +43 -0
- package/src/data/query/pg-core/columns/common.ts +366 -0
- package/src/data/query/pg-core/columns/custom.ts +232 -0
- package/src/data/query/pg-core/columns/date.common.ts +15 -0
- package/src/data/query/pg-core/columns/date.ts +112 -0
- package/src/data/query/pg-core/columns/double-precision.ts +55 -0
- package/src/data/query/pg-core/columns/enum.ts +201 -0
- package/src/data/query/pg-core/columns/index.ts +35 -0
- package/src/data/query/pg-core/columns/inet.ts +43 -0
- package/src/data/query/pg-core/columns/int.common.ts +57 -0
- package/src/data/query/pg-core/columns/integer.ts +53 -0
- package/src/data/query/pg-core/columns/interval.ts +83 -0
- package/src/data/query/pg-core/columns/json.ts +58 -0
- package/src/data/query/pg-core/columns/jsonb.ts +56 -0
- package/src/data/query/pg-core/columns/line.ts +117 -0
- package/src/data/query/pg-core/columns/macaddr.ts +43 -0
- package/src/data/query/pg-core/columns/macaddr8.ts +43 -0
- package/src/data/query/pg-core/columns/numeric.ts +227 -0
- package/src/data/query/pg-core/columns/point.ts +127 -0
- package/src/data/query/pg-core/columns/postgis_extension/geometry.ts +119 -0
- package/src/data/query/pg-core/columns/postgis_extension/utils.ts +47 -0
- package/src/data/query/pg-core/columns/real.ts +58 -0
- package/src/data/query/pg-core/columns/serial.ts +55 -0
- package/src/data/query/pg-core/columns/smallint.ts +53 -0
- package/src/data/query/pg-core/columns/smallserial.ts +60 -0
- package/src/data/query/pg-core/columns/text.ts +67 -0
- package/src/data/query/pg-core/columns/time.ts +72 -0
- package/src/data/query/pg-core/columns/timestamp.ts +163 -0
- package/src/data/query/pg-core/columns/uuid.ts +51 -0
- package/src/data/query/pg-core/columns/varchar.ts +89 -0
- package/src/data/query/pg-core/columns/vector_extension/bit.ts +68 -0
- package/src/data/query/pg-core/columns/vector_extension/halfvec.ts +80 -0
- package/src/data/query/pg-core/columns/vector_extension/sparsevec.ts +67 -0
- package/src/data/query/pg-core/columns/vector_extension/vector.ts +80 -0
- package/src/data/query/pg-core/db.ts +674 -0
- package/src/data/query/pg-core/dialect.ts +1404 -0
- package/src/data/query/pg-core/expressions.ts +25 -0
- package/src/data/query/pg-core/foreign-keys.ts +130 -0
- package/src/data/query/pg-core/index.ts +21 -0
- package/src/data/query/pg-core/indexes.ts +276 -0
- package/src/data/query/pg-core/policies.ts +56 -0
- package/src/data/query/pg-core/primary-keys.ts +62 -0
- package/src/data/query/pg-core/query-builders/count.ts +86 -0
- package/src/data/query/pg-core/query-builders/delete.ts +293 -0
- package/src/data/query/pg-core/query-builders/index.ts +7 -0
- package/src/data/query/pg-core/query-builders/insert.ts +452 -0
- package/src/data/query/pg-core/query-builders/query-builder.ts +123 -0
- package/src/data/query/pg-core/query-builders/query.ts +157 -0
- package/src/data/query/pg-core/query-builders/raw.ts +49 -0
- package/src/data/query/pg-core/query-builders/refresh-materialized-view.ts +108 -0
- package/src/data/query/pg-core/query-builders/select.ts +1346 -0
- package/src/data/query/pg-core/query-builders/select.types.ts +437 -0
- package/src/data/query/pg-core/query-builders/update.ts +626 -0
- package/src/data/query/pg-core/roles.ts +41 -0
- package/src/data/query/pg-core/schema.ts +72 -0
- package/src/data/query/pg-core/sequence.ts +41 -0
- package/src/data/query/pg-core/session.ts +292 -0
- package/src/data/query/pg-core/subquery.ts +46 -0
- package/src/data/query/pg-core/table.ts +252 -0
- package/src/data/query/pg-core/unique-constraint.ts +73 -0
- package/src/data/query/pg-core/utils/array.ts +95 -0
- package/src/data/query/pg-core/utils/index.ts +1 -0
- package/src/data/query/pg-core/utils.ts +104 -0
- package/src/data/query/pg-core/view-base.ts +14 -0
- package/src/data/query/pg-core/view-common.ts +1 -0
- package/src/data/query/pg-core/view.ts +435 -0
- package/src/data/query/pg-core/with-builder.ts +41 -0
- package/src/data/query/postgres-js/README.md +46 -0
- package/src/data/query/postgres-js/array-parser.ts +45 -0
- package/src/data/query/postgres-js/driver-error-boundary.ts +149 -0
- package/src/data/query/postgres-js/driver.ts +163 -0
- package/src/data/query/postgres-js/index.ts +2 -0
- package/src/data/query/postgres-js/session.ts +234 -0
- package/src/data/query/primary-key.ts +11 -0
- package/src/data/query/query-builders/query-builder.ts +19 -0
- package/src/data/query/query-builders/select.types.ts +175 -0
- package/src/data/query/query-promise.ts +35 -0
- package/src/data/query/relations.ts +725 -0
- package/src/data/query/runnable-query.ts +12 -0
- package/src/data/query/selection-proxy.ts +121 -0
- package/src/data/query/session.ts +8 -0
- package/src/data/query/sql/expressions/conditions.ts +741 -0
- package/src/data/query/sql/expressions/index.ts +2 -0
- package/src/data/query/sql/expressions/select.ts +45 -0
- package/src/data/query/sql/functions/aggregate.ts +129 -0
- package/src/data/query/sql/functions/index.ts +2 -0
- package/src/data/query/sql/functions/vector.ts +178 -0
- package/src/data/query/sql/index.ts +3 -0
- package/src/data/query/sql/sql.ts +794 -0
- package/src/data/query/subquery.ts +53 -0
- package/src/data/query/table.ts +208 -0
- package/src/data/query/table.utils.ts +2 -0
- package/src/data/query/tracing-utils.ts +3 -0
- package/src/data/query/tracing.ts +11 -0
- package/src/data/query/utils.ts +357 -0
- package/src/data/query/version.ts +4 -0
- package/src/data/query/view-common.ts +1 -0
- package/src/data/schema/branded.ts +13 -0
- package/src/data/schema/generated/coerce.ts +5 -0
- package/src/data/schema/generated/combinator.ts +6 -0
- package/src/data/schema/generated/encoding.ts +5 -0
- package/src/data/schema/generated/error.ts +6 -0
- package/src/data/schema/generated/format.ts +5 -0
- package/src/data/schema/generated/type-constructor.ts +10 -0
- package/src/data/schema/generated/type.ts +6 -0
- package/src/data/schema/index.ts +6 -0
- package/src/data/schema/json-schema.ts +33 -0
- package/src/data/schema/namespace.ts +55 -0
- package/src/data/schema/parse.ts +39 -0
- package/src/data/schema/types.ts +39 -0
- package/src/data/temporal/append-only.ts +134 -0
- package/src/data/temporal/close.ts +27 -0
- package/src/data/temporal/columns.ts +10 -0
- package/src/data/temporal/definition-queries.ts +70 -0
- package/src/data/temporal/errors.ts +10 -0
- package/src/data/temporal/get-current.ts +22 -0
- package/src/data/temporal/index.ts +9 -0
- package/src/data/temporal/namespace.ts +36 -0
- package/src/data/temporal/query.ts +25 -0
- package/src/data/temporal/resolve.ts +17 -0
- package/src/data/temporal/revise.ts +67 -0
- package/src/data/temporal/types.ts +22 -0
- package/src/data/valve/artifact.ts +33 -0
- package/src/data/valve/contract-diff.ts +21 -0
- package/src/data/valve/cross.ts +57 -0
- package/src/data/valve/crossing-ledger.ts +50 -0
- package/src/data/valve/decision.ts +44 -0
- package/src/data/valve/durable-crossing.ts +52 -0
- package/src/data/valve/execute-crossing.ts +77 -0
- package/src/data/valve/faucet.ts +56 -0
- package/src/data/valve/gate.ts +114 -0
- package/src/data/valve/graph.ts +77 -0
- package/src/data/valve/index.ts +53 -0
- package/src/data/valve/namespace.ts +57 -0
- package/src/data/valve/registry.ts +50 -0
- package/src/data/valve/schema/valve-crossing-fields.ts +23 -0
- package/src/data/valve/schema/valve-crossing.ts +9 -0
- package/src/data/valve/supply.ts +154 -0
- package/src/data/valve/types.ts +143 -0
- package/src/data/vector/columns.ts +27 -0
- package/src/data/vector/index.ts +4 -0
- package/src/data/vector/namespace.ts +33 -0
- package/src/data/vector/query.ts +85 -0
- package/src/data/vector/validate.ts +16 -0
- package/src/data/write/audit/actor.ts +15 -0
- package/src/data/write/audit/audit-columns.ts +18 -0
- package/src/data/write/audit/audit-select.ts +111 -0
- package/src/data/write/audit/bound-transaction.ts +14 -0
- package/src/data/write/audit/cte-compile.ts +32 -0
- package/src/data/write/audit/decode-returning.ts +47 -0
- package/src/data/write/audit/final-select.ts +43 -0
- package/src/data/write/audit/infra-audit.ts +36 -0
- package/src/data/write/audit/primary-key.ts +65 -0
- package/src/data/write/audit/projection.ts +41 -0
- package/src/data/write/audit/read-touches.ts +86 -0
- package/src/data/write/audit/touch-match.ts +78 -0
- package/src/data/write/audit/verb-delete.ts +62 -0
- package/src/data/write/audit/verb-insert.ts +36 -0
- package/src/data/write/audit/verb-select.ts +47 -0
- package/src/data/write/audit/verb-update.ts +60 -0
- package/src/data/write/audit/verb-upsert.ts +104 -0
- package/src/data/write/conflict.ts +43 -0
- package/src/data/write/delete.ts +38 -0
- package/src/data/write/execute.ts +243 -0
- package/src/data/write/index.ts +11 -0
- package/src/data/write/insert.ts +63 -0
- package/src/data/write/state.ts +43 -0
- package/src/data/write/update.ts +54 -0
- package/src/data/write/upsert.ts +58 -0
- package/src/data/write/values.ts +19 -0
- package/src/index.ts +230 -0
- package/src/infra/access-links/code.ts +70 -0
- package/src/infra/access-links/handle.ts +892 -0
- package/src/infra/access-links/index.ts +9 -0
- package/src/infra/access-links/namespace.ts +30 -0
- package/src/infra/access-links/person-check.ts +177 -0
- package/src/infra/access-links/schema.ts +71 -0
- package/src/infra/alerts/async-sources.ts +231 -0
- package/src/infra/alerts/audit.ts +36 -0
- package/src/infra/alerts/beat.ts +123 -0
- package/src/infra/alerts/client-faults.ts +111 -0
- package/src/infra/alerts/faults.ts +156 -0
- package/src/infra/alerts/handle.ts +778 -0
- package/src/infra/alerts/http.ts +192 -0
- package/src/infra/alerts/index.ts +12 -0
- package/src/infra/alerts/infra-sources.ts +180 -0
- package/src/infra/alerts/namespace.ts +81 -0
- package/src/infra/alerts/redact.ts +21 -0
- package/src/infra/alerts/request-faults.ts +41 -0
- package/src/infra/alerts/schema.ts +124 -0
- package/src/infra/alerts/sinks.ts +125 -0
- package/src/infra/alerts/source-options.ts +26 -0
- package/src/infra/alerts/sources.ts +503 -0
- package/src/infra/alerts/subsystem-sources.ts +137 -0
- package/src/infra/audit/emit.ts +87 -0
- package/src/infra/audit/index.ts +2 -0
- package/src/infra/audit/namespace.ts +22 -0
- package/src/infra/audit/schema.sql +35 -0
- package/src/infra/audit/types.ts +18 -0
- package/src/infra/aws/credentials.ts +147 -0
- package/src/infra/aws/sigv4.ts +140 -0
- package/src/infra/cache/create.ts +58 -0
- package/src/infra/cache/entry.ts +81 -0
- package/src/infra/cache/index.ts +4 -0
- package/src/infra/cache/namespace.ts +10 -0
- package/src/infra/cache/tenant.ts +93 -0
- package/src/infra/cache/types.ts +24 -0
- package/src/infra/crawl/audit.ts +35 -0
- package/src/infra/crawl/errors.ts +25 -0
- package/src/infra/crawl/handle.ts +693 -0
- package/src/infra/crawl/index.ts +9 -0
- package/src/infra/crawl/links.ts +160 -0
- package/src/infra/crawl/namespace.ts +36 -0
- package/src/infra/crawl/robots.ts +100 -0
- package/src/infra/crawl/schema.ts +89 -0
- package/src/infra/credit-line/handle.ts +883 -0
- package/src/infra/credit-line/index.ts +6 -0
- package/src/infra/credit-line/namespace.ts +7 -0
- package/src/infra/credit-line/schema.ts +96 -0
- package/src/infra/credits/handle.ts +706 -0
- package/src/infra/credits/index.ts +5 -0
- package/src/infra/credits/namespace.ts +7 -0
- package/src/infra/credits/schema.ts +83 -0
- package/src/infra/email/audit.ts +36 -0
- package/src/infra/email/inbound.ts +622 -0
- package/src/infra/email/index.ts +11 -0
- package/src/infra/email/mail.ts +517 -0
- package/src/infra/email/mime.ts +447 -0
- package/src/infra/email/namespace.ts +22 -0
- package/src/infra/email/providers.ts +111 -0
- package/src/infra/email/schema.ts +96 -0
- package/src/infra/email/sns.ts +200 -0
- package/src/infra/email/unsubscribe.ts +44 -0
- package/src/infra/fetch/address.ts +88 -0
- package/src/infra/fetch/connect-retry.ts +87 -0
- package/src/infra/fetch/handle.ts +329 -0
- package/src/infra/fetch/index.ts +7 -0
- package/src/infra/fetch/namespace.ts +70 -0
- package/src/infra/idempotency/index.ts +3 -0
- package/src/infra/idempotency/middleware.ts +87 -0
- package/src/infra/idempotency/store.ts +92 -0
- package/src/infra/idempotency/types.ts +30 -0
- package/src/infra/join-requests/handle.ts +312 -0
- package/src/infra/join-requests/index.ts +2 -0
- package/src/infra/join-requests/namespace.ts +7 -0
- package/src/infra/join-requests/schema.ts +33 -0
- package/src/infra/outbox/core.ts +165 -0
- package/src/infra/quota/errors.ts +32 -0
- package/src/infra/quota/handle.ts +215 -0
- package/src/infra/quota/index.ts +5 -0
- package/src/infra/quota/namespace.ts +7 -0
- package/src/infra/quota/schema.ts +15 -0
- package/src/infra/storage/backend.ts +34 -0
- package/src/infra/storage/handle.ts +513 -0
- package/src/infra/storage/index.ts +9 -0
- package/src/infra/storage/local.ts +104 -0
- package/src/infra/storage/namespace.ts +13 -0
- package/src/infra/storage/s3.ts +257 -0
- package/src/infra/storage/schema.ts +24 -0
- package/src/infra/support/handle.ts +854 -0
- package/src/infra/support/http.ts +229 -0
- package/src/infra/support/index.ts +7 -0
- package/src/infra/support/namespace.ts +12 -0
- package/src/infra/support/schema.ts +96 -0
- package/src/infra/webhook/inbound.ts +45 -0
- package/src/infra/webhook/index.ts +5 -0
- package/src/infra/webhook/namespace.ts +24 -0
- package/src/infra/webhook/outbound.ts +315 -0
- package/src/infra/webhook/sign.ts +32 -0
- package/src/infra/webhook/verify.ts +82 -0
- package/src/invariants/assert.ts +26 -0
- package/src/invariants/index.ts +1 -0
- package/src/lint/config.ts +56 -0
- package/src/lint/doctrine.ts +163 -0
- package/src/lint/include.ts +97 -0
- package/src/lint/index.ts +3 -0
- package/src/lint/preset.ts +10 -0
- package/src/lint/resolver.ts +218 -0
- package/src/lint/rules/no-reexports.ts +46 -0
- package/src/request/behavior/audited.ts +85 -0
- package/src/request/behavior/cached.ts +62 -0
- package/src/request/behavior/compose.ts +28 -0
- package/src/request/behavior/index.ts +5 -0
- package/src/request/behavior/namespace.ts +16 -0
- package/src/request/behavior/types.ts +26 -0
- package/src/request/behavior/versioned.ts +54 -0
- package/src/request/context/create.ts +103 -0
- package/src/request/context/guard.ts +49 -0
- package/src/request/context/index.ts +4 -0
- package/src/request/context/run-in-transaction.ts +200 -0
- package/src/request/context/store.ts +28 -0
- package/src/request/context/types.ts +50 -0
- package/src/request/di/builder.ts +535 -0
- package/src/request/di/index.ts +8 -0
- package/src/request/di/resolve.ts +271 -0
- package/src/request/di/types.ts +262 -0
- package/src/request/fitting/namespace.ts +7 -0
- package/src/request/fixture/batch.ts +71 -0
- package/src/request/fixture/builder.ts +26 -0
- package/src/request/fixture/errors.ts +10 -0
- package/src/request/fixture/index.ts +8 -0
- package/src/request/fixture/namespace.ts +23 -0
- package/src/request/fixture/paginate.ts +44 -0
- package/src/request/fixture/to-handlers.ts +260 -0
- package/src/request/fixture/types.ts +79 -0
- package/src/request/flow/act-as.ts +78 -0
- package/src/request/flow/namespace.ts +17 -0
- package/src/request/http/error-step.ts +42 -0
- package/src/request/http/file.ts +141 -0
- package/src/request/http/index.ts +4 -0
- package/src/request/http/middleware.ts +141 -0
- package/src/request/http/namespace.ts +5 -0
- package/src/request/http/rate-limit-classes.ts +170 -0
- package/src/request/http/response.ts +82 -0
- package/src/request/http/server.ts +916 -0
- package/src/request/http/sniff.ts +261 -0
- package/src/request/http/types.ts +250 -0
- package/src/request/http/upload.ts +284 -0
- package/src/request/internal/text.ts +6 -0
- package/src/request/openapi/generate.ts +205 -0
- package/src/request/openapi/index.ts +2 -0
- package/src/request/openapi/namespace.ts +7 -0
- package/src/test/auth.ts +13 -0
- package/src/test/auto-setup.ts +45 -0
- package/src/test/context.ts +91 -0
- package/src/test/crawl-fixture.ts +157 -0
- package/src/test/discover-fork.ts +17 -0
- package/src/test/fingerprint.ts +135 -0
- package/src/test/globals.d.ts +7 -0
- package/src/test/index.ts +19 -0
- package/src/test/namespace.ts +87 -0
- package/src/test/plugin.ts +189 -0
- package/src/test/progress.ts +185 -0
- package/src/test/reap-after-run.ts +28 -0
- package/src/test/reap.ts +286 -0
- package/src/test/reset.ts +253 -0
- package/src/test/savepoints.ts +172 -0
- package/src/test/setup.ts +1422 -0
- package/src/test/system-channel.ts +50 -0
- package/src/test/vitest-plugin.ts +142 -0
- package/src/test/vitest-workspace.ts +507 -0
- package/src/test/vitest.ts +333 -0
- package/src/test/watch.ts +105 -0
- package/src/trace/capture/bounded-serializer.ts +146 -0
- package/src/trace/cardinality/analyze.ts +173 -0
- package/src/trace/cardinality/branch-context.ts +214 -0
- package/src/trace/cardinality/check.ts +33 -0
- package/src/trace/cardinality/classify-edge.ts +64 -0
- package/src/trace/cardinality/structural-max.ts +107 -0
- package/src/trace/check/coverage-check.ts +188 -0
- package/src/trace/check/flow-check.ts +103 -0
- package/src/trace/check/flow-step-site.ts +234 -0
- package/src/trace/check/io-pattern.ts +116 -0
- package/src/trace/codemod/add-cardinality.ts +152 -0
- package/src/trace/codemod/run.ts +80 -0
- package/src/trace/entry/child-trace.ts +21 -0
- package/src/trace/entry/close-trace.ts +87 -0
- package/src/trace/entry/finalize-trace.ts +28 -0
- package/src/trace/entry/open-trace.ts +138 -0
- package/src/trace/entry/parent-trace.ts +20 -0
- package/src/trace/entry/parse-traceparent.ts +39 -0
- package/src/trace/entry/process-start.ts +38 -0
- package/src/trace/entry/trace-context.ts +26 -0
- package/src/trace/entry/tracing-enabled.ts +10 -0
- package/src/trace/external/record.ts +195 -0
- package/src/trace/external/report.ts +66 -0
- package/src/trace/namespace.ts +19 -0
- package/src/trace/partition/day.ts +47 -0
- package/src/trace/partition/index.ts +14 -0
- package/src/trace/partition/partition-name.ts +23 -0
- package/src/trace/partition/plan.ts +82 -0
- package/src/trace/partition/schedule.ts +26 -0
- package/src/trace/partition/startup-hook.ts +39 -0
- package/src/trace/partition/sync.ts +154 -0
- package/src/trace/partition/tables.ts +53 -0
- package/src/trace/read/tree.ts +83 -0
- package/src/trace/retain/copy-on-error.ts +76 -0
- package/src/trace/runtime/expire-stale-traces.ts +54 -0
- package/src/trace/runtime/flow-step.ts +147 -0
- package/src/trace/runtime/flush-steps.ts +31 -0
- package/src/trace/runtime/pending-writes.ts +54 -0
- package/src/trace/runtime/step-buffer.ts +298 -0
- package/src/trace/runtime/step-error.ts +21 -0
- package/src/trace/runtime/step-meta.ts +55 -0
- package/src/trace/runtime/thenable.ts +12 -0
- package/src/trace/runtime/truncate-trace.ts +62 -0
- package/src/trace/schema/trace-fields.ts +52 -0
- package/src/trace/schema/trace-retained.ts +22 -0
- package/src/trace/schema/trace-step-fields.ts +44 -0
- package/src/trace/schema/trace-step-retained.ts +25 -0
- package/src/trace/schema/trace-step.ts +18 -0
- package/src/trace/schema/trace.ts +12 -0
- package/src/trace/transformer/apply.ts +79 -0
- package/src/trace/transformer/build-meta-literal.ts +30 -0
- package/src/trace/transformer/find-flow-step-sites.ts +85 -0
- package/src/trace/transformer/inject-flow-step-import.ts +39 -0
- package/src/trace/transformer/transform-error.ts +14 -0
- package/src/trace/transformer/transform-flow-steps.ts +123 -0
- package/src/trace/transformer/wrap-function-declaration.ts +62 -0
- package/src/trace/transformer/wrap-variable-declaration.ts +67 -0
- package/src/workspace/affected.ts +110 -0
- package/src/workspace/changed-files.ts +163 -0
- package/src/workspace/check-deps.ts +213 -0
- package/src/workspace/checksum.ts +20 -0
- package/src/workspace/dependency-graph.ts +67 -0
- package/src/workspace/detect-pipework-copies.ts +93 -0
- package/src/workspace/discover.ts +206 -0
- package/src/workspace/generate.ts +401 -0
- package/src/workspace/index.ts +7 -0
- package/src/workspace/module-imports-pipework.ts +39 -0
- package/src/workspace/module-package-name.ts +12 -0
- package/src/workspace/scrub-git-env.ts +23 -0
- package/src/workspace/source-paths.ts +36 -0
- package/src/workspace/sync.ts +182 -0
- package/dist/REFERENCE.md +0 -1477
- package/dist/infra/access-links/rate-limit.d.ts +0 -10
- package/dist/infra/access-links/rate-limit.d.ts.map +0 -1
- package/dist/infra/access-links/rate-limit.js +0 -28
- package/dist/infra/access-links/rate-limit.js.map +0 -1
- package/dist/infra/email/sigv4.d.ts +0 -24
- package/dist/infra/email/sigv4.d.ts.map +0 -1
- package/dist/infra/email/sigv4.js +0 -55
- package/dist/infra/email/sigv4.js.map +0 -1
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import type { Manifold } from '../pipework.js'
|
|
2
|
+
import type { HttpSurfaceBuilder, SurfaceHandle, HttpSurfaceConfig, SurfaceContext, SurfaceStartOptions, TestClient } from './types.js'
|
|
3
|
+
import type { ServerConfig } from '../../request/http/types.js'
|
|
4
|
+
import { DEFAULT_DB } from '../../request/di/types.js'
|
|
5
|
+
import { createServer } from '../../request/http/server.js'
|
|
6
|
+
import { resourceToHandlers } from '../../request/fixture/to-handlers.js'
|
|
7
|
+
import { generateOpenAPI } from '../../request/openapi/generate.js'
|
|
8
|
+
import type { RouteRegistration } from '../../request/http/types.js'
|
|
9
|
+
import { ConfigError } from '../config/errors.js'
|
|
10
|
+
|
|
11
|
+
export function createHttpSurface(config: HttpSurfaceConfig): HttpSurfaceBuilder {
|
|
12
|
+
const databases = collectHttpDatabases(config)
|
|
13
|
+
const deps: Record<string, string> = {}
|
|
14
|
+
|
|
15
|
+
const surface: HttpSurfaceBuilder = {
|
|
16
|
+
kind: 'http',
|
|
17
|
+
port: config.port,
|
|
18
|
+
manifest: { databases, jobTypes: [], dependencies: deps },
|
|
19
|
+
|
|
20
|
+
openapi() {
|
|
21
|
+
if (config.openapi === undefined) {
|
|
22
|
+
throw new ConfigError(
|
|
23
|
+
'This http surface declares no `openapi` info, so there is no OpenAPI document to build.',
|
|
24
|
+
'Add `openapi: { title, version }` to the surface config, e.g. surface.http({ openapi: { title: \'My API\', version: \'1.0.0\' }, ... }).',
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
return generateOpenAPI(config.openapi, surfaceRoutes(config), { rateLimited: config.rateLimit !== false || config.rateLimits !== undefined })
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
dependencies(d: Record<string, string>) {
|
|
31
|
+
Object.assign(deps, d)
|
|
32
|
+
return surface
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
async start(context: SurfaceContext, options?: SurfaceStartOptions): Promise<SurfaceHandle> {
|
|
36
|
+
const serverConfig = buildServerConfig(config)
|
|
37
|
+
if (config.port === undefined && options?.port !== undefined) (serverConfig as { port: number }).port = options.port
|
|
38
|
+
const server = createServer(context as unknown as Manifold, serverConfig)
|
|
39
|
+
|
|
40
|
+
registerSurfaceHandlers(server, config)
|
|
41
|
+
|
|
42
|
+
const address = await server.listen()
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
kind: 'http',
|
|
46
|
+
address,
|
|
47
|
+
async stop(force) {
|
|
48
|
+
await server.stop(force)
|
|
49
|
+
},
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
async test(context: SurfaceContext): Promise<TestClient> {
|
|
54
|
+
const serverConfig = buildServerConfig(config)
|
|
55
|
+
serverConfig.managed = false
|
|
56
|
+
if (serverConfig.logger === undefined) {
|
|
57
|
+
serverConfig.logger = false
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const server = createServer(context as unknown as Manifold, serverConfig)
|
|
61
|
+
|
|
62
|
+
registerSurfaceHandlers(server, config)
|
|
63
|
+
|
|
64
|
+
await server.ready()
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
inject: (opts) => server.inject(opts),
|
|
68
|
+
close: () => server.close(),
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return surface
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** The routes a server registers for this surface, in registration order: handlers, then each resource's handlers. */
|
|
77
|
+
export function surfaceRoutes(config: HttpSurfaceConfig): RouteRegistration[] {
|
|
78
|
+
const routes: RouteRegistration[] = []
|
|
79
|
+
const add = (handlers: readonly RouteRegistration['handler'][]): void => {
|
|
80
|
+
for (const handler of handlers) {
|
|
81
|
+
if (handler.meta.route) {
|
|
82
|
+
routes.push({ method: handler.meta.route.method, path: handler.meta.route.path, handler })
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
add(config.handlers ?? [])
|
|
87
|
+
for (const resource of config.resources ?? []) add(resourceToHandlers(resource))
|
|
88
|
+
return routes
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function registerSurfaceHandlers(server: ReturnType<typeof createServer>, config: HttpSurfaceConfig): void {
|
|
92
|
+
const handlers = surfaceRoutes(config).map((r) => r.handler)
|
|
93
|
+
if (handlers.length > 0) server.registerHandlers(handlers)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function buildServerConfig(config: HttpSurfaceConfig): ServerConfig {
|
|
97
|
+
const sc: ServerConfig = { managed: true }
|
|
98
|
+
|
|
99
|
+
if (config.port !== undefined) (sc as { port: number }).port = config.port
|
|
100
|
+
if (config.host !== undefined) (sc as { host: string }).host = config.host
|
|
101
|
+
if (config.gracefulShutdownMs !== undefined) (sc as { gracefulShutdownMs: number }).gracefulShutdownMs = config.gracefulShutdownMs
|
|
102
|
+
if (config.auth !== undefined) (sc as { auth: ServerConfig['auth'] }).auth = config.auth
|
|
103
|
+
if (config.tenant !== undefined) (sc as { tenant: ServerConfig['tenant'] }).tenant = config.tenant
|
|
104
|
+
if (config.cors !== undefined) (sc as { cors: ServerConfig['cors'] }).cors = config.cors
|
|
105
|
+
if (config.security !== undefined) (sc as { security: ServerConfig['security'] }).security = config.security
|
|
106
|
+
if (config.rateLimit !== undefined) (sc as { rateLimit: ServerConfig['rateLimit'] }).rateLimit = config.rateLimit
|
|
107
|
+
if (config.rateLimits !== undefined) (sc as { rateLimits: ServerConfig['rateLimits'] }).rateLimits = config.rateLimits
|
|
108
|
+
if (config.openapi !== undefined) (sc as { openapi: ServerConfig['openapi'] }).openapi = config.openapi
|
|
109
|
+
if (config.rbac !== undefined) (sc as { rbac: ServerConfig['rbac'] }).rbac = config.rbac
|
|
110
|
+
if (config.transactionPerRequest !== undefined) (sc as { transactionPerRequest: ServerConfig['transactionPerRequest'] }).transactionPerRequest = config.transactionPerRequest
|
|
111
|
+
if (config.transactionTimeoutMs !== undefined) (sc as { transactionTimeoutMs: ServerConfig['transactionTimeoutMs'] }).transactionTimeoutMs = config.transactionTimeoutMs
|
|
112
|
+
if (config.healthChecks !== undefined) (sc as { healthChecks: ServerConfig['healthChecks'] }).healthChecks = config.healthChecks
|
|
113
|
+
if (config.logging !== undefined) (sc as { logging: ServerConfig['logging'] }).logging = config.logging
|
|
114
|
+
if (config.logger !== undefined) (sc as { logger: ServerConfig['logger'] }).logger = config.logger
|
|
115
|
+
if (config.trustProxy !== undefined) (sc as { trustProxy: ServerConfig['trustProxy'] }).trustProxy = config.trustProxy
|
|
116
|
+
if (config.bodyLimit !== undefined) (sc as { bodyLimit: ServerConfig['bodyLimit'] }).bodyLimit = config.bodyLimit
|
|
117
|
+
if (config.onInternalError !== undefined) (sc as { onInternalError: ServerConfig['onInternalError'] }).onInternalError = config.onInternalError
|
|
118
|
+
|
|
119
|
+
return sc
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function collectHttpDatabases(config: HttpSurfaceConfig): string[] {
|
|
123
|
+
const dbs = new Set<string>()
|
|
124
|
+
for (const h of config.handlers ?? []) {
|
|
125
|
+
for (const db of h.meta.databases) {
|
|
126
|
+
dbs.add(db === DEFAULT_DB ? DEFAULT_DB : db)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
for (const r of config.resources ?? []) {
|
|
130
|
+
dbs.add(r.meta.database)
|
|
131
|
+
}
|
|
132
|
+
return [...dbs]
|
|
133
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { createHttpSurface } from './http.js'
|
|
2
|
+
export { createWorkerSurface } from './worker.js'
|
|
3
|
+
export { createScriptSurface } from './script.js'
|
|
4
|
+
export { validateSurfaces, validateNoJobTypeDuplicates } from './validate.js'
|
|
5
|
+
export { startSurfaces, type StartResult } from './start.js'
|
|
6
|
+
export type {
|
|
7
|
+
SurfaceKind, SurfaceManifest, SurfaceHandle, Surface, SurfaceBuilder, SurfaceContext,
|
|
8
|
+
HttpSurfaceConfig, HttpSurfaceBuilder, TestClient,
|
|
9
|
+
WorkerSurfaceConfig, JobEvent, JobEventJob, ScriptSurfaceConfig, ScriptContext,
|
|
10
|
+
RetryConfig, SurfaceMap,
|
|
11
|
+
} from './types.js'
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runs the job under a deadline that CANCELS it rather than merely giving up on
|
|
3
|
+
* it: the signal reaches `executeJob`, which cancels the in-flight query and
|
|
4
|
+
* rolls back, so a timed-out job stops holding its transaction and its backend.
|
|
5
|
+
* The abort reason is the timeout error, so that is what the job fails with.
|
|
6
|
+
*
|
|
7
|
+
* The deadline still holds for a handler that ignores its signal: the wait ends
|
|
8
|
+
* on abort either way, so the worker slot is freed on time and the job is
|
|
9
|
+
* recorded as failed — the signal is what additionally frees the backend.
|
|
10
|
+
*/
|
|
11
|
+
export async function executeWithTimeout<T>(
|
|
12
|
+
fn: (signal?: AbortSignal) => Promise<T>,
|
|
13
|
+
timeoutMs: number | undefined,
|
|
14
|
+
jobType: string,
|
|
15
|
+
jobId: string,
|
|
16
|
+
): Promise<T> {
|
|
17
|
+
if (timeoutMs === undefined) return fn()
|
|
18
|
+
|
|
19
|
+
const controller = new AbortController()
|
|
20
|
+
const timer = setTimeout(() => {
|
|
21
|
+
controller.abort(new Error(
|
|
22
|
+
`[pipework] Job "${jobType}" (${jobId}) timed out after ${timeoutMs}ms.\n\n` +
|
|
23
|
+
' The job handler did not complete within the configured timeout.\n' +
|
|
24
|
+
' Increase the timeout with .timeout(ms) or optimize the handler.\n'
|
|
25
|
+
))
|
|
26
|
+
}, timeoutMs)
|
|
27
|
+
timer.unref()
|
|
28
|
+
|
|
29
|
+
const expired = new Promise<never>((_, reject) => {
|
|
30
|
+
controller.signal.addEventListener('abort', () => { reject(controller.signal.reason as Error) }, { once: true })
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
const work = fn(controller.signal)
|
|
35
|
+
work.catch(() => {})
|
|
36
|
+
return await Promise.race([work, expired])
|
|
37
|
+
} finally {
|
|
38
|
+
clearTimeout(timer)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createHttpSurface } from './http.js'
|
|
2
|
+
import { createWorkerSurface } from './worker.js'
|
|
3
|
+
import { createScriptSurface } from './script.js'
|
|
4
|
+
|
|
5
|
+
/** Surface namespace — declarative entry points that define how the app runs (HTTP server, background worker, one-shot script). */
|
|
6
|
+
export const surface = {
|
|
7
|
+
/** Creates an HTTP surface — a Fastify server with routes, middleware, and production validation. Returns an HttpSurfaceBuilder with a .test() method for inject()-based integration tests. */
|
|
8
|
+
http: createHttpSurface,
|
|
9
|
+
/** Creates a worker surface — a long-running process that claims and executes jobs from queues. */
|
|
10
|
+
worker: createWorkerSurface,
|
|
11
|
+
/** Creates a script surface — a one-shot process that runs and exits (migrations, seeds, CLI tools). The run is traced as a job-kind trace that names the surface. */
|
|
12
|
+
script: createScriptSurface,
|
|
13
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { SurfaceBuilder, SurfaceHandle, ScriptSurfaceConfig, SurfaceContext, SurfaceStartOptions } from './types.js'
|
|
2
|
+
import type { Manifold } from '../pipework.js'
|
|
3
|
+
import { runScript } from '../../async/jobs/run-script.js'
|
|
4
|
+
|
|
5
|
+
export function createScriptSurface(config: ScriptSurfaceConfig): SurfaceBuilder {
|
|
6
|
+
const deps: Record<string, string> = {}
|
|
7
|
+
|
|
8
|
+
const surface: SurfaceBuilder = {
|
|
9
|
+
kind: 'script',
|
|
10
|
+
manifest: { databases: config.databases ?? [], jobTypes: [], dependencies: deps },
|
|
11
|
+
|
|
12
|
+
dependencies(d: Record<string, string>) {
|
|
13
|
+
Object.assign(deps, d)
|
|
14
|
+
return surface
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
async start(context: SurfaceContext, options?: SurfaceStartOptions): Promise<SurfaceHandle> {
|
|
18
|
+
const instance = context as unknown as Manifold
|
|
19
|
+
await runScript(instance, () => config.run({
|
|
20
|
+
config: context.config,
|
|
21
|
+
env: context.env,
|
|
22
|
+
pool: context.pool,
|
|
23
|
+
}), { jobType: 'script', process: { phase: 'script', surfaces: [options?.name ?? 'script'] } })
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
kind: 'script',
|
|
27
|
+
async stop() {},
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return surface
|
|
33
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import type { SurfaceContext, SurfaceKind, SurfaceHandle, SurfaceMap, SurfaceStartOptions } from './types.js'
|
|
2
|
+
import { validateSurfaces, validateNoJobTypeDuplicates } from './validate.js'
|
|
3
|
+
import type { ResolvedConfig } from '../config/load.js'
|
|
4
|
+
import { ConfigError } from '../config/errors.js'
|
|
5
|
+
import { getBaseLogger } from '../logging/index.js'
|
|
6
|
+
|
|
7
|
+
export interface StartResult {
|
|
8
|
+
readonly handles: ReadonlyMap<string, SurfaceHandle>
|
|
9
|
+
/** Tells every surface to stop at once, concurrently, with one shared `force` signal. */
|
|
10
|
+
stop(force?: AbortSignal): Promise<void>
|
|
11
|
+
/** Names of surfaces whose stop has not returned. */
|
|
12
|
+
pending(): readonly string[]
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export async function startSurfaces(
|
|
16
|
+
context: SurfaceContext,
|
|
17
|
+
config: ResolvedConfig,
|
|
18
|
+
surfaces: SurfaceMap,
|
|
19
|
+
options: SurfaceStartOptions = {},
|
|
20
|
+
): Promise<StartResult> {
|
|
21
|
+
const logger = getBaseLogger()
|
|
22
|
+
|
|
23
|
+
validateSurfaces(config, surfaces)
|
|
24
|
+
validateNoJobTypeDuplicates(surfaces)
|
|
25
|
+
|
|
26
|
+
const selected = selectSurfaces(surfaces, options.kinds, logger)
|
|
27
|
+
checkStartPort(selected, options.port, logger)
|
|
28
|
+
|
|
29
|
+
const handles = new Map<string, SurfaceHandle>()
|
|
30
|
+
const startOrder: string[] = []
|
|
31
|
+
|
|
32
|
+
const entries = Object.entries(selected)
|
|
33
|
+
const scripts = entries.filter(([, s]) => s.kind === 'script')
|
|
34
|
+
const workers = entries.filter(([, s]) => s.kind === 'worker')
|
|
35
|
+
const httpSurfaces = entries.filter(([, s]) => s.kind === 'http')
|
|
36
|
+
|
|
37
|
+
const ordered = [...scripts, ...workers, ...httpSurfaces]
|
|
38
|
+
|
|
39
|
+
for (const [name, surface] of ordered) {
|
|
40
|
+
logger.info({ surface: name, kind: surface.kind }, `Starting surface "${name}"`)
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
const handle = await surface.start(context, { ...(options.port === undefined ? {} : { port: options.port }), name })
|
|
44
|
+
handles.set(name, handle)
|
|
45
|
+
startOrder.push(name)
|
|
46
|
+
|
|
47
|
+
if (handle.address !== undefined) {
|
|
48
|
+
logger.info({ surface: name, address: handle.address }, `Surface "${name}" listening`)
|
|
49
|
+
}
|
|
50
|
+
} catch (err) {
|
|
51
|
+
logger.error({ surface: name, err }, `Failed to start surface "${name}"`)
|
|
52
|
+
|
|
53
|
+
const abandoned = AbortSignal.abort()
|
|
54
|
+
for (const started of startOrder.reverse()) {
|
|
55
|
+
try {
|
|
56
|
+
await handles.get(started)!.stop(abandoned)
|
|
57
|
+
} catch (stopErr) {
|
|
58
|
+
logger.error({ surface: started, err: stopErr }, `Failed to stop surface "${started}" during rollback`)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
throw new Error(
|
|
63
|
+
`[pipework] Failed to start surface "${name}".\n\n` +
|
|
64
|
+
` ${err instanceof Error ? err.message : String(err)}\n\n` +
|
|
65
|
+
` Surfaces that were started have been stopped.\n`,
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const stopping = new Set<string>()
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
handles,
|
|
74
|
+
pending: () => [...stopping],
|
|
75
|
+
async stop(force = new AbortController().signal) {
|
|
76
|
+
const stopOrder = [...startOrder].reverse()
|
|
77
|
+
const errors: Array<{ name: string; error: unknown }> = []
|
|
78
|
+
|
|
79
|
+
await Promise.all(stopOrder.map(async (name) => {
|
|
80
|
+
const handle = handles.get(name)
|
|
81
|
+
if (handle === undefined) return
|
|
82
|
+
|
|
83
|
+
logger.info({ surface: name }, `Stopping surface "${name}"`)
|
|
84
|
+
stopping.add(name)
|
|
85
|
+
try {
|
|
86
|
+
await handle.stop(force)
|
|
87
|
+
} catch (err) {
|
|
88
|
+
logger.error({ surface: name, err }, `Error stopping surface "${name}"`)
|
|
89
|
+
errors.push({ name, error: err })
|
|
90
|
+
} finally {
|
|
91
|
+
stopping.delete(name)
|
|
92
|
+
}
|
|
93
|
+
}))
|
|
94
|
+
|
|
95
|
+
if (errors.length > 0) {
|
|
96
|
+
const details = errors.map(e => ` - ${e.name}: ${e.error instanceof Error ? e.error.message : String(e.error)}`).join('\n')
|
|
97
|
+
throw new Error(
|
|
98
|
+
`[pipework] Errors occurred while stopping surfaces:\n\n${details}\n`,
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function selectSurfaces(surfaces: SurfaceMap, kinds: readonly SurfaceKind[] | undefined, logger: ReturnType<typeof getBaseLogger>): SurfaceMap {
|
|
106
|
+
if (kinds === undefined) return surfaces
|
|
107
|
+
const entries = Object.entries(surfaces)
|
|
108
|
+
const chosen = entries.filter(([, s]) => kinds.includes(s.kind))
|
|
109
|
+
if (chosen.length === 0) {
|
|
110
|
+
const declared = entries.map(([n, s]) => `${n} (${s.kind})`).join(', ')
|
|
111
|
+
throw new ConfigError(
|
|
112
|
+
`kinds [${kinds.join(', ')}] matched no surface; declared: ${declared === '' ? 'none' : declared}.`,
|
|
113
|
+
'Declare a surface of one of those kinds, or start without a kinds filter.',
|
|
114
|
+
)
|
|
115
|
+
}
|
|
116
|
+
const skipped = entries.filter(([, s]) => !kinds.includes(s.kind))
|
|
117
|
+
if (skipped.length > 0) {
|
|
118
|
+
logger.info(
|
|
119
|
+
{ skipped: skipped.map(([n]) => n), kinds },
|
|
120
|
+
`Skipping surfaces not of kind [${kinds.join(', ')}]: ${skipped.map(([n, s]) => `"${n}" (${s.kind})`).join(', ')}`,
|
|
121
|
+
)
|
|
122
|
+
}
|
|
123
|
+
return Object.fromEntries(chosen)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function checkStartPort(surfaces: SurfaceMap, port: number | undefined, logger: ReturnType<typeof getBaseLogger>): void {
|
|
127
|
+
if (port === undefined) return
|
|
128
|
+
const http = Object.entries(surfaces).filter(([, s]) => s.kind === 'http')
|
|
129
|
+
const bare = http.filter(([, s]) => s.port === undefined).map(([n]) => n)
|
|
130
|
+
if (bare.length > 1) {
|
|
131
|
+
throw new ConfigError(
|
|
132
|
+
`Start port ${port} would be bound by ${bare.length} http surfaces that declare no port: ${bare.map(n => `"${n}"`).join(', ')}.`,
|
|
133
|
+
'Give each http surface its own `port`, or start without --port / PORT.',
|
|
134
|
+
)
|
|
135
|
+
}
|
|
136
|
+
for (const [name, s] of http) {
|
|
137
|
+
const own = s.port
|
|
138
|
+
if (own !== undefined && own !== port) {
|
|
139
|
+
logger.warn({ surface: name, port: own, startPort: port }, `Surface "${name}" declares port ${own}; the start port ${port} does not apply to it`)
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import type { Handler } from '../../request/di/types.js'
|
|
2
|
+
import type { Resource } from '../../request/fixture/types.js'
|
|
3
|
+
import type { ServerConfig } from '../../request/http/types.js'
|
|
4
|
+
import type { OpenAPIDocument } from '../../request/openapi/index.js'
|
|
5
|
+
import type { QueueConfig, BackoffConfig } from '../../async/jobs/queue.js'
|
|
6
|
+
import type { GraphSelection, StepGraph } from '../../async/steps/types.js'
|
|
7
|
+
|
|
8
|
+
export type SurfaceKind = 'http' | 'worker' | 'script'
|
|
9
|
+
|
|
10
|
+
export interface SurfaceManifest {
|
|
11
|
+
readonly databases: readonly string[]
|
|
12
|
+
readonly jobTypes: readonly string[]
|
|
13
|
+
readonly dependencies: Readonly<Record<string, string>>
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface SurfaceHandle {
|
|
17
|
+
readonly kind: SurfaceKind
|
|
18
|
+
readonly address?: string
|
|
19
|
+
/**
|
|
20
|
+
* Stops accepting new work at once, then drains what is in flight. When `force` aborts, abandons the
|
|
21
|
+
* drain (aborting in-flight work) and returns promptly. Without `force` the drain is not bounded.
|
|
22
|
+
*/
|
|
23
|
+
stop(force?: AbortSignal): Promise<void>
|
|
24
|
+
/** Worker surface only: enqueues the declared schedule for `job` now, without waiting for the clock and without moving its next run. Resolves with the job id. */
|
|
25
|
+
fireSchedule?(job: string): Promise<string>
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface Surface {
|
|
29
|
+
readonly kind: SurfaceKind
|
|
30
|
+
readonly manifest: SurfaceManifest
|
|
31
|
+
/** Http surface only: the port it declares, if any. */
|
|
32
|
+
readonly port?: number | undefined
|
|
33
|
+
/** `options.port` is the start port; only the http surface reads it. */
|
|
34
|
+
start(context: SurfaceContext, options?: SurfaceStartOptions): Promise<SurfaceHandle>
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface SurfaceStartOptions {
|
|
38
|
+
readonly port?: number
|
|
39
|
+
/**
|
|
40
|
+
* Start only the surfaces of these kinds; the rest are skipped. Unset starts every surface.
|
|
41
|
+
* Read by `startSurfaces`; a surface ignores it.
|
|
42
|
+
*/
|
|
43
|
+
readonly kinds?: readonly SurfaceKind[]
|
|
44
|
+
/** The name this surface is registered under. */
|
|
45
|
+
readonly name?: string
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface SurfaceBuilder extends Surface {
|
|
49
|
+
dependencies(d: Record<string, string>): SurfaceBuilder
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface HttpSurfaceBuilder extends SurfaceBuilder {
|
|
53
|
+
/** The OpenAPI document the running surface serves, built from its declarations alone. Throws ConfigError without `openapi` info. */
|
|
54
|
+
openapi(): OpenAPIDocument
|
|
55
|
+
test(context: SurfaceContext): Promise<TestClient>
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface TestClient {
|
|
59
|
+
inject(opts: import('../../request/http/types.js').InjectOptions): Promise<import('../../request/http/types.js').InjectResponse>
|
|
60
|
+
close(): Promise<void>
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface SurfaceContext {
|
|
64
|
+
readonly config: {
|
|
65
|
+
readonly environment: string
|
|
66
|
+
database(name?: string): { readonly name: string; readonly url: string }
|
|
67
|
+
databases(): ReadonlyMap<string, { readonly name: string }>
|
|
68
|
+
databaseNames(): readonly string[]
|
|
69
|
+
defaultDatabaseName(): string
|
|
70
|
+
readonly observability: {
|
|
71
|
+
readonly slowQueryMs: number
|
|
72
|
+
readonly inFlightQueryMs?: number | undefined
|
|
73
|
+
readonly logAllQueries: boolean
|
|
74
|
+
readonly poolMetricsInterval: number
|
|
75
|
+
readonly onStatement: import('../config/statement-observer.js').StatementObserver | undefined
|
|
76
|
+
}
|
|
77
|
+
readonly raw: unknown
|
|
78
|
+
}
|
|
79
|
+
readonly env: Readonly<Record<string, unknown>>
|
|
80
|
+
readonly pool: {
|
|
81
|
+
getOrCreate(config: { readonly name: string; readonly url: string }): { readonly drizzle: import('../../data/db/index.js').DB; close(): Promise<void> }
|
|
82
|
+
get(name: string): { readonly drizzle: import('../../data/db/index.js').DB; close(): Promise<void> } | undefined
|
|
83
|
+
closeAll(): Promise<void>
|
|
84
|
+
count(): number
|
|
85
|
+
}
|
|
86
|
+
readonly isolation: {
|
|
87
|
+
markBegin(): void
|
|
88
|
+
markEnd(): void
|
|
89
|
+
assertClean(): void
|
|
90
|
+
}
|
|
91
|
+
readonly connections: {
|
|
92
|
+
track(id: string, name: string, context: string): void
|
|
93
|
+
release(id: string): void
|
|
94
|
+
activeCount(): number
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export interface HttpSurfaceConfig {
|
|
99
|
+
readonly handlers?: readonly Handler<Record<string, unknown>, unknown>[]
|
|
100
|
+
readonly resources?: readonly Resource<unknown>[]
|
|
101
|
+
readonly port?: number
|
|
102
|
+
readonly host?: string
|
|
103
|
+
readonly auth?: ServerConfig['auth']
|
|
104
|
+
readonly tenant?: ServerConfig['tenant']
|
|
105
|
+
/** Default CORS grant for routes without `.cors()`. Unset or `false` grants nothing; `{}` allows all origins. */
|
|
106
|
+
readonly cors?: ServerConfig['cors']
|
|
107
|
+
readonly security?: ServerConfig['security']
|
|
108
|
+
readonly rateLimit?: ServerConfig['rateLimit']
|
|
109
|
+
readonly rateLimits?: ServerConfig['rateLimits']
|
|
110
|
+
readonly openapi?: ServerConfig['openapi']
|
|
111
|
+
readonly rbac?: ServerConfig['rbac']
|
|
112
|
+
readonly transactionPerRequest?: ServerConfig['transactionPerRequest']
|
|
113
|
+
readonly transactionTimeoutMs?: ServerConfig['transactionTimeoutMs']
|
|
114
|
+
readonly healthChecks?: ServerConfig['healthChecks']
|
|
115
|
+
readonly logging?: ServerConfig['logging']
|
|
116
|
+
readonly logger?: ServerConfig['logger']
|
|
117
|
+
readonly trustProxy?: ServerConfig['trustProxy']
|
|
118
|
+
readonly gracefulShutdownMs?: number
|
|
119
|
+
readonly bodyLimit?: ServerConfig['bodyLimit']
|
|
120
|
+
/** Called before each internal 5xx is sent, as `ServerConfig.onInternalError`; `alerts.requestFaults(handle)` is such a hook. */
|
|
121
|
+
readonly onInternalError?: ServerConfig['onInternalError']
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export interface RetryConfig {
|
|
125
|
+
readonly attempts: number
|
|
126
|
+
readonly backoff?: BackoffConfig
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** The job an event is about. `attempt` is the 1-based attempt that was running when it ended. */
|
|
130
|
+
export interface JobEventJob {
|
|
131
|
+
readonly id: string
|
|
132
|
+
readonly type: string
|
|
133
|
+
readonly attempt: number
|
|
134
|
+
readonly maxAttempts: number
|
|
135
|
+
readonly tenant: string | null
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* A job ended without its handler finishing it: its worker was lost and the
|
|
140
|
+
* reaper took it (`outcome`: tried again, or dead-lettered), the worker is
|
|
141
|
+
* stopping and handed it back to the queue, this worker lost its claim, or this
|
|
142
|
+
* worker's attempt failed and the job was dead-lettered (`error` as stored in the job's `error_payload`).
|
|
143
|
+
*/
|
|
144
|
+
export type JobEvent =
|
|
145
|
+
| { readonly kind: 'reaped'; readonly outcome: 'retry' | 'dead_letter' | 'superseded'; readonly job: JobEventJob }
|
|
146
|
+
| {
|
|
147
|
+
readonly kind: 'dead-lettered'
|
|
148
|
+
readonly cause: 'failed' | 'timeout' | 'permanent' | 'no-handler'
|
|
149
|
+
readonly error: unknown
|
|
150
|
+
readonly job: JobEventJob
|
|
151
|
+
}
|
|
152
|
+
| { readonly kind: 'handed-back'; readonly job: JobEventJob }
|
|
153
|
+
| { readonly kind: 'claim-lost'; readonly job: JobEventJob }
|
|
154
|
+
|
|
155
|
+
export interface WorkerSurfaceConfig {
|
|
156
|
+
readonly jobs: readonly Handler<Record<string, unknown>, unknown>[]
|
|
157
|
+
/**
|
|
158
|
+
* Step graphs whose jobs this worker runs: a graph takes every worker class, `graph.workers('model')` only the named
|
|
159
|
+
* classes. Each taken class's step jobs (type `pipework.step.<name>[:<class>]`) are handled here, and a step job that dead-letters through this worker's queue fails its run. The worker's `queue` must use the
|
|
160
|
+
* table of the graph's queue.
|
|
161
|
+
*/
|
|
162
|
+
readonly graphs?: readonly (StepGraph | GraphSelection)[]
|
|
163
|
+
readonly database?: string
|
|
164
|
+
readonly concurrency?: number
|
|
165
|
+
readonly pollIntervalMs?: number
|
|
166
|
+
readonly queue?: QueueConfig
|
|
167
|
+
readonly listen?: boolean
|
|
168
|
+
/** Reclaims jobs whose claim went stale. Default off, except on when the worker declares `schedules` (a stale claim would otherwise block its schedule); `false` turns it off. */
|
|
169
|
+
readonly reaper?: ReaperConfig | boolean
|
|
170
|
+
/** How long `stop()` waits for in-flight jobs; those still running then are aborted and handed back to the queue. Default 30000. */
|
|
171
|
+
readonly shutdownDeadlineMs?: number
|
|
172
|
+
/** How often a running job's claim is renewed, and noticed lost. Default 30000; keep it well under the queue's `staleTimeoutMs`. */
|
|
173
|
+
readonly heartbeatIntervalMs?: number
|
|
174
|
+
/**
|
|
175
|
+
* Called for each job the reaper took, each job handed back at stop, and each
|
|
176
|
+
* job whose claim this worker lost, and each job this worker's failed attempt dead-lettered (`error` as stored
|
|
177
|
+
* in the job's `error_payload`, called after the dead-lettering transaction commits). Runs in the job's tenant Flow (`pipe()` works as
|
|
178
|
+
* that tenant, in its own transaction), traced as a child of the job's trace. A throw is
|
|
179
|
+
* logged and never reaches the reaper, the stop or the claim loop.
|
|
180
|
+
*/
|
|
181
|
+
readonly onJobEvent?: (event: JobEvent) => void | Promise<void>
|
|
182
|
+
/** Consecutive failing claims that end the worker surface (fatal log, non-zero exit code). Default 10. */
|
|
183
|
+
readonly maxConsecutiveClaimFailures?: number
|
|
184
|
+
readonly timeouts?: Readonly<Record<number, number>>
|
|
185
|
+
/**
|
|
186
|
+
* Cron schedules this worker runs. Each `job` must be a job type in `jobs`.
|
|
187
|
+
* At start the worker upserts these (an unchanged schedule keeps its next
|
|
188
|
+
* run), removes schedules for its job types that are no longer declared (`[]`
|
|
189
|
+
* removes them all; omitting the key leaves the table alone), and fires each
|
|
190
|
+
* due schedule once across every worker process on the database. Each run is
|
|
191
|
+
* a root trace with `entryKind: 'cron'` and no tenant. Needs the
|
|
192
|
+
* `pipework_schedules` table: run `pipework generate`.
|
|
193
|
+
*/
|
|
194
|
+
readonly schedules?: readonly WorkerSchedule[]
|
|
195
|
+
/** How often the worker looks for due schedules. Default 15000. */
|
|
196
|
+
readonly schedulerIntervalMs?: number
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export interface WorkerSchedule {
|
|
200
|
+
/** The job type to enqueue; also the schedule's name. */
|
|
201
|
+
readonly job: string
|
|
202
|
+
/** Five-field cron expression. */
|
|
203
|
+
readonly cron: string
|
|
204
|
+
/** IANA time zone. Default `UTC`. */
|
|
205
|
+
readonly timezone?: string
|
|
206
|
+
/** Payload of each scheduled job. Default `{}`. */
|
|
207
|
+
readonly payload?: unknown
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export interface ReaperConfig {
|
|
211
|
+
readonly intervalMs?: number
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export interface ScriptSurfaceConfig {
|
|
215
|
+
readonly databases?: readonly string[]
|
|
216
|
+
readonly run: (context: ScriptContext) => Promise<void>
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export interface ScriptContext {
|
|
220
|
+
readonly config: SurfaceContext['config']
|
|
221
|
+
readonly env: SurfaceContext['env']
|
|
222
|
+
readonly pool: SurfaceContext['pool']
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
export type SurfaceMap = Record<string, Surface>
|