pipework 0.252.0 → 0.253.0
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 +10 -0
- package/dist/infra/support/handle.d.ts +8 -1
- package/dist/infra/support/handle.d.ts.map +1 -1
- package/dist/infra/support/handle.js +9 -2
- package/dist/infra/support/handle.js.map +1 -1
- package/dist/infra/support/namespace.d.ts.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 +869 -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,261 @@
|
|
|
1
|
+
/** Bytes of a file that decide its type: PDF uses all 1024, every other signature the first 512. */
|
|
2
|
+
export const SNIFF_BYTES = 1024
|
|
3
|
+
const SIGNATURE_BYTES = 512
|
|
4
|
+
|
|
5
|
+
const ZIP = 'application/zip'
|
|
6
|
+
const CFB = 'application/x-cfb'
|
|
7
|
+
const MACHO = 'application/x-mach-binary'
|
|
8
|
+
const PE = 'application/x-msdownload'
|
|
9
|
+
|
|
10
|
+
const ZIP_REFINEMENTS = [
|
|
11
|
+
'application/vnd.openxmlformats-officedocument.',
|
|
12
|
+
'application/vnd.oasis.opendocument.',
|
|
13
|
+
'application/epub+zip',
|
|
14
|
+
'application/java-archive',
|
|
15
|
+
'application/vnd.android.package-archive',
|
|
16
|
+
]
|
|
17
|
+
const CFB_REFINEMENTS = [
|
|
18
|
+
'application/msword',
|
|
19
|
+
'application/vnd.ms-excel',
|
|
20
|
+
'application/vnd.ms-powerpoint',
|
|
21
|
+
'application/vnd.ms-outlook',
|
|
22
|
+
'application/x-msi',
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
const ZIP_EXTENSIONS: Readonly<Record<string, string>> = {
|
|
26
|
+
docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
27
|
+
xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
28
|
+
pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
|
29
|
+
odt: 'application/vnd.oasis.opendocument.text',
|
|
30
|
+
ods: 'application/vnd.oasis.opendocument.spreadsheet',
|
|
31
|
+
odp: 'application/vnd.oasis.opendocument.presentation',
|
|
32
|
+
epub: 'application/epub+zip',
|
|
33
|
+
jar: 'application/java-archive',
|
|
34
|
+
apk: 'application/vnd.android.package-archive',
|
|
35
|
+
}
|
|
36
|
+
const CFB_EXTENSIONS: Readonly<Record<string, string>> = {
|
|
37
|
+
doc: 'application/msword',
|
|
38
|
+
xls: 'application/vnd.ms-excel',
|
|
39
|
+
ppt: 'application/vnd.ms-powerpoint',
|
|
40
|
+
msg: 'application/vnd.ms-outlook',
|
|
41
|
+
msi: 'application/x-msi',
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
interface Signature { readonly bytes: readonly number[]; readonly offset?: number; readonly type: string }
|
|
45
|
+
|
|
46
|
+
const ascii = (s: string): number[] => [...s].map((c) => c.charCodeAt(0))
|
|
47
|
+
|
|
48
|
+
const SIGNATURES: readonly Signature[] = [
|
|
49
|
+
{ bytes: ascii('%PDF-'), type: 'application/pdf' },
|
|
50
|
+
{ bytes: [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a], type: 'image/png' },
|
|
51
|
+
{ bytes: [0xff, 0xd8, 0xff], type: 'image/jpeg' },
|
|
52
|
+
{ bytes: ascii('GIF87a'), type: 'image/gif' },
|
|
53
|
+
{ bytes: ascii('GIF89a'), type: 'image/gif' },
|
|
54
|
+
{ bytes: [0x49, 0x49, 0x2a, 0x00], type: 'image/tiff' },
|
|
55
|
+
{ bytes: [0x4d, 0x4d, 0x00, 0x2a], type: 'image/tiff' },
|
|
56
|
+
{ bytes: [0x00, 0x00, 0x01, 0x00], type: 'image/x-icon' },
|
|
57
|
+
{ bytes: [0x1a, 0x45, 0xdf, 0xa3], type: 'video/x-matroska' }, // webm refined below
|
|
58
|
+
{ bytes: ascii('OggS'), type: 'audio/ogg' },
|
|
59
|
+
{ bytes: ascii('ID3'), type: 'audio/mpeg' },
|
|
60
|
+
{ bytes: ascii('fLaC'), type: 'audio/flac' },
|
|
61
|
+
{ bytes: [0x50, 0x4b, 0x03, 0x04], type: ZIP },
|
|
62
|
+
{ bytes: [0x50, 0x4b, 0x05, 0x06], type: ZIP },
|
|
63
|
+
{ bytes: [0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1], type: CFB },
|
|
64
|
+
{ bytes: [0x1f, 0x8b], type: 'application/gzip' },
|
|
65
|
+
{ bytes: [0x37, 0x7a, 0xbc, 0xaf, 0x27, 0x1c], type: 'application/x-7z-compressed' },
|
|
66
|
+
{ bytes: [...ascii('Rar!'), 0x1a, 0x07], type: 'application/vnd.rar' },
|
|
67
|
+
{ bytes: ascii('%!PS'), type: 'application/postscript' },
|
|
68
|
+
{ bytes: ascii('{\\rtf'), type: 'application/rtf' },
|
|
69
|
+
{ bytes: ascii('8BPS'), type: 'image/vnd.adobe.photoshop' },
|
|
70
|
+
{ bytes: [0xff, 0x4f, 0xff, 0x51], type: 'image/jp2' }, // bare JPEG 2000 codestream
|
|
71
|
+
{ bytes: [0xff, 0x0a], type: 'image/jxl' }, // bare JPEG XL codestream
|
|
72
|
+
{ bytes: [0x00, 0x00, 0x00, 0x0c, 0x4a, 0x58, 0x4c, 0x20, 0x0d, 0x0a, 0x87, 0x0a], type: 'image/jxl' },
|
|
73
|
+
{ bytes: [0xfd, 0x37, 0x7a, 0x58, 0x5a, 0x00], type: 'application/x-xz' },
|
|
74
|
+
{ bytes: [0x28, 0xb5, 0x2f, 0xfd], type: 'application/zstd' },
|
|
75
|
+
{ bytes: [0x00, 0x61, 0x73, 0x6d], type: 'application/wasm' },
|
|
76
|
+
{ bytes: [...ascii('SQLite format 3'), 0x00], type: 'application/vnd.sqlite3' },
|
|
77
|
+
{ bytes: ascii('wOFF'), type: 'font/woff' },
|
|
78
|
+
{ bytes: ascii('wOF2'), type: 'font/woff2' },
|
|
79
|
+
{ bytes: ascii('OTTO'), type: 'font/otf' },
|
|
80
|
+
{ bytes: ascii('MThd'), type: 'audio/midi' },
|
|
81
|
+
{ bytes: [0x7f, 0x45, 0x4c, 0x46], type: 'application/x-elf' },
|
|
82
|
+
{ bytes: [0xfe, 0xed, 0xfa, 0xce], type: MACHO },
|
|
83
|
+
{ bytes: [0xfe, 0xed, 0xfa, 0xcf], type: MACHO },
|
|
84
|
+
{ bytes: [0xce, 0xfa, 0xed, 0xfe], type: MACHO },
|
|
85
|
+
{ bytes: [0xcf, 0xfa, 0xed, 0xfe], type: MACHO },
|
|
86
|
+
]
|
|
87
|
+
|
|
88
|
+
const JP2_SIGNATURE = [0x00, 0x00, 0x00, 0x0c, 0x6a, 0x50, 0x20, 0x20, 0x0d, 0x0a, 0x87, 0x0a]
|
|
89
|
+
const JP2_BRANDS: Readonly<Record<string, string>> = { 'jp2 ': 'image/jp2', 'jpx ': 'image/jpx', 'jpm ': 'image/jpm' }
|
|
90
|
+
|
|
91
|
+
const FTYP_BRANDS: Readonly<Record<string, string>> = {
|
|
92
|
+
heic: 'image/heic', heix: 'image/heic', hevc: 'image/heic', hevx: 'image/heic', heim: 'image/heic', heis: 'image/heic',
|
|
93
|
+
mif1: 'image/heif', msf1: 'image/heif',
|
|
94
|
+
avif: 'image/avif', avis: 'image/avif',
|
|
95
|
+
'M4A ': 'audio/mp4',
|
|
96
|
+
'qt ': 'video/quicktime',
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const RIFF_FORMS: Readonly<Record<string, string>> = {
|
|
100
|
+
WEBP: 'image/webp',
|
|
101
|
+
WAVE: 'audio/wav',
|
|
102
|
+
'AVI ': 'video/x-msvideo',
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Types whose files always show their signature. MP3 is left out: a file without an ID3 tag has none we detect. */
|
|
106
|
+
export const sniffable: ReadonlySet<string> = new Set([
|
|
107
|
+
...SIGNATURES.map((s) => s.type).filter((t) => t !== 'audio/mpeg'),
|
|
108
|
+
'image/bmp',
|
|
109
|
+
'video/webm',
|
|
110
|
+
...Object.values(RIFF_FORMS),
|
|
111
|
+
...Object.values(FTYP_BRANDS),
|
|
112
|
+
'video/3gpp',
|
|
113
|
+
'video/mp4',
|
|
114
|
+
...Object.values(JP2_BRANDS),
|
|
115
|
+
'font/ttf',
|
|
116
|
+
'audio/aiff',
|
|
117
|
+
'application/x-bzip2',
|
|
118
|
+
])
|
|
119
|
+
|
|
120
|
+
function matches(head: Buffer, sig: Signature): boolean {
|
|
121
|
+
const offset = sig.offset ?? 0
|
|
122
|
+
if (head.length < offset + sig.bytes.length) return false
|
|
123
|
+
return sig.bytes.every((b, i) => head[offset + i] === b)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const OOXML_DIRS: ReadonlyArray<readonly [string, string]> = [
|
|
127
|
+
['word/', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'],
|
|
128
|
+
['xl/', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'],
|
|
129
|
+
['ppt/', 'application/vnd.openxmlformats-officedocument.presentationml.presentation'],
|
|
130
|
+
]
|
|
131
|
+
const ZIP_MEMBER_TYPE = /^(application\/vnd\.oasis\.opendocument\.[a-z0-9.+-]+|application\/epub\+zip)$/
|
|
132
|
+
|
|
133
|
+
/** The subtype a zip's own first entries name, or null when they do not decide it. */
|
|
134
|
+
function zipSubtype(h: Buffer): string | null {
|
|
135
|
+
let offset = 0
|
|
136
|
+
let found: string | null = null
|
|
137
|
+
let first = true
|
|
138
|
+
while (h.length >= offset + 30 && h.readUInt32LE(offset) === 0x04034b50) {
|
|
139
|
+
const flags = h.readUInt16LE(offset + 6)
|
|
140
|
+
const method = h.readUInt16LE(offset + 8)
|
|
141
|
+
const size = h.readUInt32LE(offset + 18)
|
|
142
|
+
const nameLength = h.readUInt16LE(offset + 26)
|
|
143
|
+
const dataStart = offset + 30 + nameLength + h.readUInt16LE(offset + 28)
|
|
144
|
+
if (h.length < offset + 30 + nameLength) return found
|
|
145
|
+
const name = h.toString('latin1', offset + 30, offset + 30 + nameLength)
|
|
146
|
+
if (first && name === 'mimetype' && method === 0 && size > 0 && dataStart + size <= h.length) {
|
|
147
|
+
const content = h.toString('latin1', dataStart, dataStart + size)
|
|
148
|
+
return ZIP_MEMBER_TYPE.test(content) ? content : null
|
|
149
|
+
}
|
|
150
|
+
first = false
|
|
151
|
+
for (const [dir, type] of OOXML_DIRS) {
|
|
152
|
+
if (!name.startsWith(dir)) continue
|
|
153
|
+
if (found !== null && found !== type) return null
|
|
154
|
+
found = type
|
|
155
|
+
}
|
|
156
|
+
if ((flags & 0x08) !== 0 && size === 0) break
|
|
157
|
+
offset = dataStart + size
|
|
158
|
+
}
|
|
159
|
+
return found
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/** MPEG audio frame header at offset 0 with a valid version, layer, bitrate and sample rate. */
|
|
163
|
+
function isMpegFrame(h: Buffer): boolean {
|
|
164
|
+
if (h.length < 4 || h[0] !== 0xff || (h[1]! & 0xe0) !== 0xe0) return false
|
|
165
|
+
const version = (h[1]! >> 3) & 3
|
|
166
|
+
const layer = (h[1]! >> 1) & 3
|
|
167
|
+
const bitrate = h[2]! >> 4
|
|
168
|
+
const rate = (h[2]! >> 2) & 3
|
|
169
|
+
return version !== 1 && layer !== 0 && bitrate !== 0 && bitrate !== 15 && rate !== 3
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/** A PE image: 'MZ', and e_lfanew pointing inside the head at 'PE\0\0'. */
|
|
173
|
+
function isPortableExecutable(h: Buffer): boolean {
|
|
174
|
+
if (h.length < 0x40 || h[0] !== 0x4d || h[1] !== 0x5a) return false
|
|
175
|
+
const pe = h.readUInt32LE(0x3c)
|
|
176
|
+
return pe >= 0x40 && pe + 4 <= h.length && h.readUInt32BE(pe) === 0x50450000
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* The media type the first bytes of a file say it is, or null when no signature
|
|
181
|
+
* matches. A PDF is named when `%PDF-` starts anywhere in the first `SNIFF_BYTES`
|
|
182
|
+
* bytes, unless another signature matches first. Give it at least the first
|
|
183
|
+
* `SNIFF_BYTES` bytes; fewer may give null (or, for a zip, plain `application/zip`).
|
|
184
|
+
*/
|
|
185
|
+
export function detectMediaType(bytes: Uint8Array | Buffer): string | null {
|
|
186
|
+
const head = Buffer.isBuffer(bytes) ? bytes : Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength)
|
|
187
|
+
const h = head.length > SIGNATURE_BYTES ? head.subarray(0, SIGNATURE_BYTES) : head
|
|
188
|
+
if (h.length >= 12 && h.toString('latin1', 0, 4) === 'RIFF') {
|
|
189
|
+
const form = RIFF_FORMS[h.toString('latin1', 8, 12)]
|
|
190
|
+
if (form !== undefined) return form
|
|
191
|
+
}
|
|
192
|
+
if (h.length >= 12 && h.toString('latin1', 0, 4) === 'FORM') {
|
|
193
|
+
const form = h.toString('latin1', 8, 12)
|
|
194
|
+
if (form === 'AIFF' || form === 'AIFC') return 'audio/aiff'
|
|
195
|
+
}
|
|
196
|
+
if (matches(h, { bytes: JP2_SIGNATURE, type: '' })) {
|
|
197
|
+
const brand = h.length >= 24 && h.toString('latin1', 16, 20) === 'ftyp' ? JP2_BRANDS[h.toString('latin1', 20, 24)] : undefined
|
|
198
|
+
return brand ?? 'image/jp2'
|
|
199
|
+
}
|
|
200
|
+
if (h.length >= 12 && h.toString('latin1', 4, 8) === 'ftyp') {
|
|
201
|
+
const brand = h.toString('latin1', 8, 12)
|
|
202
|
+
const known = FTYP_BRANDS[brand]
|
|
203
|
+
if (known !== undefined) return known
|
|
204
|
+
return brand.startsWith('3gp') ? 'video/3gpp' : 'video/mp4'
|
|
205
|
+
}
|
|
206
|
+
// BM, reserved zeros at 6-9, and a known DIB header size at 14: 'BM' alone is common text.
|
|
207
|
+
if (h.length >= 18 && h.toString('latin1', 0, 2) === 'BM' && h.readUInt32LE(6) === 0 && [12, 40, 52, 56, 64, 108, 124].includes(h.readUInt32LE(14))) return 'image/bmp'
|
|
208
|
+
// A TrueType header starts 00 01 00 00; a plausible table count tells it from binary noise.
|
|
209
|
+
if (matches(h, { bytes: [0x00, 0x01, 0x00, 0x00], type: '' }) && h.length >= 12) {
|
|
210
|
+
const tables = h.readUInt16BE(4)
|
|
211
|
+
if (tables >= 1 && tables <= 64) return 'font/ttf'
|
|
212
|
+
}
|
|
213
|
+
if (isPortableExecutable(h)) return PE
|
|
214
|
+
// 'BZh' alone is common text: a level digit and the first block magic must follow.
|
|
215
|
+
if (h.length >= 10 && h.toString('latin1', 0, 3) === 'BZh' && h[3]! >= 0x31 && h[3]! <= 0x39 && h.toString('hex', 4, 10) === '314159265359') return 'application/x-bzip2'
|
|
216
|
+
for (const sig of SIGNATURES) {
|
|
217
|
+
if (!matches(h, sig)) continue
|
|
218
|
+
if (sig.type === 'video/x-matroska') return h.includes('webm', 4, 'latin1') ? 'video/webm' : sig.type
|
|
219
|
+
if (sig.type === ZIP) return zipSubtype(h) ?? ZIP
|
|
220
|
+
return sig.type
|
|
221
|
+
}
|
|
222
|
+
if (isMpegFrame(h)) return 'audio/mpeg'
|
|
223
|
+
const window = head.length > SNIFF_BYTES ? head.subarray(0, SNIFF_BYTES) : head
|
|
224
|
+
return window.indexOf('%PDF-', 0, 'latin1') >= 0 ? 'application/pdf' : null
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function refinedBy(refinements: readonly string[], declared: string): boolean {
|
|
228
|
+
return refinements.some((r) => (r.endsWith('.') ? declared.startsWith(r) : declared === r))
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* The type a file is treated as: what its bytes say, unless the bytes name a
|
|
233
|
+
* container (zip, compound file) that the declared type or the filename
|
|
234
|
+
* extension narrows. A zip whose own bytes name its subtype (OpenDocument, EPUB,
|
|
235
|
+
* OOXML) is that subtype whatever is declared. `mediaType` is '' (matches nothing) when the declared type
|
|
236
|
+
* is one a signature would show and the bytes do not show it.
|
|
237
|
+
*/
|
|
238
|
+
export function resolveMediaType(input: { head: Uint8Array | Buffer; declared: string; extension: string | null }): { detectedType: string | null; mediaType: string } {
|
|
239
|
+
const { head, declared, extension } = input
|
|
240
|
+
const detectedType = detectMediaType(head)
|
|
241
|
+
const containers: ReadonlyArray<readonly [string, readonly string[], Readonly<Record<string, string>>]> = [
|
|
242
|
+
[ZIP, ZIP_REFINEMENTS, ZIP_EXTENSIONS],
|
|
243
|
+
[CFB, CFB_REFINEMENTS, CFB_EXTENSIONS],
|
|
244
|
+
]
|
|
245
|
+
for (const [type, refinements, extensions] of containers) {
|
|
246
|
+
if (detectedType !== type) continue
|
|
247
|
+
if (refinedBy(refinements, declared)) return { detectedType, mediaType: declared }
|
|
248
|
+
const byExtension = extension === null ? undefined : extensions[extension]
|
|
249
|
+
if (byExtension !== undefined) return { detectedType, mediaType: byExtension }
|
|
250
|
+
}
|
|
251
|
+
if (detectedType !== null) return { detectedType, mediaType: detectedType }
|
|
252
|
+
return { detectedType, mediaType: sniffable.has(declared) ? '' : declared }
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/** The lowercase filename extension after the last dot, or null. */
|
|
256
|
+
export function extensionOf(filename: string | null): string | null {
|
|
257
|
+
if (filename === null) return null
|
|
258
|
+
const dot = filename.lastIndexOf('.')
|
|
259
|
+
const ext = dot < 0 ? '' : filename.slice(dot + 1).toLowerCase()
|
|
260
|
+
return ext === '' ? null : ext
|
|
261
|
+
}
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import type { AuthStrategy } from '../../auth/auth/types.js'
|
|
2
|
+
import type { AuthEnricher, TenantResolver } from '../../auth/auth/chain.js'
|
|
3
|
+
import type { Handler, HttpMethod } from '../di/types.js'
|
|
4
|
+
import type { HealthCheck } from '../../core/lifecycle/types.js'
|
|
5
|
+
import type { TenantConfig } from '../../auth/tenant/types.js'
|
|
6
|
+
import type { Rbac } from '../../auth/rbac/types.js'
|
|
7
|
+
import type { OpenAPIInfo } from '../openapi/generate.js'
|
|
8
|
+
import type { LoggingConfig } from '../../core/logging/types.js'
|
|
9
|
+
import type { PipeworkLogger } from '../../core/logging/types.js'
|
|
10
|
+
|
|
11
|
+
/** Fastify request with pipework extensions — req.id (UUID), typed headers, client address (`ip`, `ips`). */
|
|
12
|
+
export interface HttpRequest {
|
|
13
|
+
readonly headers: Readonly<Record<string, string | undefined>>
|
|
14
|
+
/** The client's address. With `trustProxy` off it is the socket's remote address, whatever `X-Forwarded-For` says; with `trustProxy` set it is the client address from `X-Forwarded-For` as far as the trusted proxies vouch for it. Pass it as `client` to `accessLinks` `resolve` and `beginUse` for the per-client limit. */
|
|
15
|
+
readonly ip: string
|
|
16
|
+
/** Every address in the chain, nearest first: `[ip]` with `trustProxy` off; with it on, the socket address followed by the `X-Forwarded-For` addresses read back through the trusted proxies, ending at `ip`. */
|
|
17
|
+
readonly ips: readonly string[]
|
|
18
|
+
readonly rawBody?: Buffer
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** Fastify reply with pipework extensions. */
|
|
22
|
+
export interface HttpResponse {
|
|
23
|
+
header(name: string, value: string | readonly string[]): void
|
|
24
|
+
/**
|
|
25
|
+
* Calls `cb` once the response is over: `'sent'` when the whole response has been
|
|
26
|
+
* handed to the connection (the raw response's `finish`), `'aborted'` when the
|
|
27
|
+
* connection closed first (the client went away mid-stream). Each callback runs once.
|
|
28
|
+
* It runs after the request's transaction has ended, so anything it does opens its
|
|
29
|
+
* own transaction. A callback that throws or rejects is logged and never reaches
|
|
30
|
+
* the response.
|
|
31
|
+
*/
|
|
32
|
+
onFinish(cb: (outcome: 'sent' | 'aborted') => void | Promise<void>): void
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** CORS configuration — origin, methods, headers, credentials, maxAge. */
|
|
36
|
+
export interface CorsConfig {
|
|
37
|
+
origin?: string | readonly string[] | boolean | RegExp | ((origin: string) => boolean)
|
|
38
|
+
methods?: readonly string[]
|
|
39
|
+
allowedHeaders?: readonly string[]
|
|
40
|
+
exposedHeaders?: readonly string[]
|
|
41
|
+
credentials?: boolean
|
|
42
|
+
maxAge?: number
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Security header configuration — passed to @fastify/helmet. */
|
|
46
|
+
export interface SecurityConfig {
|
|
47
|
+
contentSecurityPolicy?: boolean | Record<string, readonly string[]>
|
|
48
|
+
crossOriginEmbedderPolicy?: boolean
|
|
49
|
+
crossOriginOpenerPolicy?: boolean | { policy: string }
|
|
50
|
+
crossOriginResourcePolicy?: boolean | { policy: string }
|
|
51
|
+
dnsPrefetchControl?: boolean
|
|
52
|
+
frameguard?: boolean | { action: string }
|
|
53
|
+
hidePoweredBy?: boolean
|
|
54
|
+
hsts?: boolean | { maxAge: number; includeSubDomains?: boolean }
|
|
55
|
+
ieNoOpen?: boolean
|
|
56
|
+
noSniff?: boolean
|
|
57
|
+
referrerPolicy?: boolean | { policy: string }
|
|
58
|
+
xssFilter?: boolean
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Rate limiting configuration — max requests, time window, key generator. */
|
|
62
|
+
export interface RateLimitConfig {
|
|
63
|
+
max?: number
|
|
64
|
+
timeWindow?: string | number
|
|
65
|
+
keyGenerator?: (request: HttpRequest) => string
|
|
66
|
+
allowList?: readonly string[]
|
|
67
|
+
ban?: number
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** One fixed window: at most `max` requests per `windowSeconds`. */
|
|
71
|
+
export interface RateLimitWindow {
|
|
72
|
+
max: number
|
|
73
|
+
windowSeconds: number
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** The keys a limit class can count by; `total` counts every caller of the class together. */
|
|
77
|
+
export type RateLimitWindowName = 'perUser' | 'perTenant' | 'perAddress' | 'total'
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* A named limit class: any of a per-user, per-tenant, per-address and total window, each counted on its own.
|
|
81
|
+
* Each key takes one window or an array of windows (distinct `windowSeconds`); a request is counted against
|
|
82
|
+
* all of a key's windows and refused if any is over.
|
|
83
|
+
*/
|
|
84
|
+
export interface RateLimitClass {
|
|
85
|
+
perUser?: RateLimitWindow | readonly RateLimitWindow[]
|
|
86
|
+
perTenant?: RateLimitWindow | readonly RateLimitWindow[]
|
|
87
|
+
perAddress?: RateLimitWindow | readonly RateLimitWindow[]
|
|
88
|
+
total?: RateLimitWindow | readonly RateLimitWindow[]
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** What `onRefused` is told about one refused window of one request. */
|
|
92
|
+
export interface RateLimitRefusal {
|
|
93
|
+
class: string
|
|
94
|
+
limit: RateLimitWindowName
|
|
95
|
+
/** The user id, tenant id or address that was counted; '*' for `total`. */
|
|
96
|
+
key: string
|
|
97
|
+
/** The request's tenant, whichever window refused; null when it has none. */
|
|
98
|
+
tenantId: string | null
|
|
99
|
+
/** The signed-in user; null when signed out. */
|
|
100
|
+
userId: string | null
|
|
101
|
+
/** The id on the response's X-Request-Id and the request's log lines. */
|
|
102
|
+
requestId: string
|
|
103
|
+
/** The pipework trace row of the request; null when tracing is off. */
|
|
104
|
+
/** The request's trace row id; null with tracing off. */
|
|
105
|
+
traceId: string | null
|
|
106
|
+
count: number
|
|
107
|
+
max: number
|
|
108
|
+
windowSeconds: number
|
|
109
|
+
retryAfterSeconds: number
|
|
110
|
+
route: { method: string; url: string }
|
|
111
|
+
/** The route's params parsed by its schema as the handler gets them; the raw params with no schema; null when they fail it. */
|
|
112
|
+
params: unknown
|
|
113
|
+
/** The route's query, on the same terms as `params`. */
|
|
114
|
+
query: unknown
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Named limit classes, checked after auth and counted in Postgres (`pipework_rate_limit_counts`, opted in
|
|
119
|
+
* with the blueprint's `rateLimits: {}`), so every server process on the same database shares one count.
|
|
120
|
+
* Keys are counted perUser, perTenant, perAddress, total in turn, up to the first key with a window over its max, so one user's
|
|
121
|
+
* refused requests don't spend the tenant's budget. The 429's wait is the longest of the windows that refused, in both the Retry-After header and the body's `error.retryAfterSeconds`. A route is in `signedIn` (auth required, or optional with
|
|
122
|
+
* a user), `public` (no auth, or optional without a user) or the class its fitting names with `.rateLimit(name)`.
|
|
123
|
+
*/
|
|
124
|
+
export interface RateLimitClassesConfig {
|
|
125
|
+
classes: Record<string, RateLimitClass>
|
|
126
|
+
/**
|
|
127
|
+
* Called once per refused request (for the window that refused it), without delaying the 429; a throw is logged.
|
|
128
|
+
* Runs in the refused request's Flow with no transaction open: write with `pipe.system()`; those writes commit
|
|
129
|
+
* on their own and are kept although the request is refused.
|
|
130
|
+
*/
|
|
131
|
+
onRefused?: (event: RateLimitRefusal) => void | Promise<void>
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** Options for server.inject() — method, url, headers, payload for testing without HTTP. */
|
|
135
|
+
export interface InjectOptions {
|
|
136
|
+
method: string
|
|
137
|
+
url: string
|
|
138
|
+
headers?: Record<string, string | readonly string[] | undefined>
|
|
139
|
+
payload?: unknown
|
|
140
|
+
query?: Record<string, string | readonly string[]>
|
|
141
|
+
/** The socket address the request appears to come from (default `127.0.0.1`). Lets a test exercise `request.ip` and `trustProxy`. */
|
|
142
|
+
remoteAddress?: string
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/** Response from server.inject() — statusCode, headers, body, rawPayload, json() helper. */
|
|
146
|
+
export interface InjectResponse {
|
|
147
|
+
statusCode: number
|
|
148
|
+
headers: Record<string, string | number | string[] | undefined>
|
|
149
|
+
body: string
|
|
150
|
+
/** The exact bytes of the response body; use it for binary responses, where `body` is decoded as text. */
|
|
151
|
+
rawPayload: Buffer
|
|
152
|
+
json(): unknown
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** Configuration for http.createServer() — CORS, security headers, rate limiting, transaction timeout. */
|
|
156
|
+
export interface ServerConfig {
|
|
157
|
+
port?: number
|
|
158
|
+
host?: string
|
|
159
|
+
gracefulShutdownMs?: number
|
|
160
|
+
/**
|
|
161
|
+
* Which proxies to believe when reading the client address (`request.ip`) from `X-Forwarded-For`. Passed to Fastify unchanged.
|
|
162
|
+
* `false` (default): ignore forwarding headers, the address is the socket's.
|
|
163
|
+
* `true`: trust every hop, so a client can set its own address; only right when every request comes through your proxy.
|
|
164
|
+
* a string or string[] of addresses or CIDRs (e.g. `'10.0.0.0/8'`): trust only proxies at those addresses.
|
|
165
|
+
* A hop count (number) is not accepted: Fastify cannot check the immediate peer from a count alone, so it trusts no one.
|
|
166
|
+
*/
|
|
167
|
+
trustProxy?: boolean | string | readonly string[]
|
|
168
|
+
logger?: PipeworkLogger | false
|
|
169
|
+
health?: boolean
|
|
170
|
+
healthPath?: string
|
|
171
|
+
readyPath?: string
|
|
172
|
+
healthChecks?: readonly HealthCheck[]
|
|
173
|
+
transactionPerRequest?: boolean | readonly string[]
|
|
174
|
+
transactionTimeoutMs?: number
|
|
175
|
+
/** Maximum request body size in bytes. Forwarded to Fastify (default 1 MiB). A per-route `.route(m, p, { bodyLimit })` overrides this for that route. */
|
|
176
|
+
bodyLimit?: number
|
|
177
|
+
auth?: ServerAuthConfig
|
|
178
|
+
tenant?: TenantConfig | null
|
|
179
|
+
rbac?: Rbac
|
|
180
|
+
/**
|
|
181
|
+
* Default CORS grant for routes that declare no `.cors()` of their own. Unset or
|
|
182
|
+
* `false` grants nothing (closed); `{}` is an explicit object and allows all origins.
|
|
183
|
+
*/
|
|
184
|
+
cors?: CorsConfig | false
|
|
185
|
+
security?: SecurityConfig | false
|
|
186
|
+
rateLimit?: RateLimitConfig | false
|
|
187
|
+
/** Per-route-class limits keyed by user, tenant or address, counted in Postgres. Separate from the server-wide `rateLimit`. */
|
|
188
|
+
rateLimits?: RateLimitClassesConfig
|
|
189
|
+
openapi?: OpenAPIInfo
|
|
190
|
+
openApiPath?: string
|
|
191
|
+
logging?: LoggingConfig
|
|
192
|
+
managed?: boolean
|
|
193
|
+
exposeErrorDetails?: boolean
|
|
194
|
+
/**
|
|
195
|
+
* Called, and awaited, before the server sends a 5xx for a thrown error (an unhandled error, a
|
|
196
|
+
* PipeworkError with httpStatus >= 500, a failed screen or file response). Runs in the request's Flow
|
|
197
|
+
* with no transaction open. A throw or rejection is logged and the response is unchanged.
|
|
198
|
+
*/
|
|
199
|
+
onInternalError?: (fault: InternalErrorFault) => void | Promise<void>
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/** What `onInternalError` is told about one request that ended in an internal error. */
|
|
203
|
+
export interface InternalErrorFault {
|
|
204
|
+
error: unknown
|
|
205
|
+
method: string
|
|
206
|
+
/** The registered route pattern (`/things/:id`); the raw path where no route matched. */
|
|
207
|
+
route: string
|
|
208
|
+
requestId: string
|
|
209
|
+
tenantId: string | null
|
|
210
|
+
userId: string | null
|
|
211
|
+
/** The request's trace row id; null with tracing off. */
|
|
212
|
+
traceId: string | null
|
|
213
|
+
/**
|
|
214
|
+
* The route's params parsed by its schema as the handler gets them; the raw params with no schema;
|
|
215
|
+
* null when they fail it, and null when no route handler is known (an error raised outside a route, or no route matched).
|
|
216
|
+
*/
|
|
217
|
+
params: unknown
|
|
218
|
+
/** The route's query, on the same terms as `params`. */
|
|
219
|
+
query: unknown
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/** Server-level auth configuration — strategy, session config, optional enricher. */
|
|
223
|
+
export type ServerAuthConfig =
|
|
224
|
+
| { strategy: AuthStrategy<unknown>; optional?: boolean }
|
|
225
|
+
| { strategies: AuthStrategy<unknown>[]; enrichers?: AuthEnricher<unknown>[]; tenantResolver?: TenantResolver<unknown>; optional?: boolean }
|
|
226
|
+
|
|
227
|
+
/** Internal route registration record — used by OpenAPI generation to discover routes. */
|
|
228
|
+
export interface RouteRegistration {
|
|
229
|
+
method: HttpMethod
|
|
230
|
+
path: string
|
|
231
|
+
handler: Handler<Record<string, unknown>, unknown>
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/** Standard handler response shape — statusCode, headers, body. */
|
|
235
|
+
export interface HandlerResponse {
|
|
236
|
+
readonly status: number
|
|
237
|
+
readonly body?: unknown
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/** Standard error response shape — { error: { code, message }, statusCode }. */
|
|
241
|
+
export interface ErrorResponse {
|
|
242
|
+
error: {
|
|
243
|
+
code: string
|
|
244
|
+
message: string
|
|
245
|
+
fields?: Record<string, readonly string[]>
|
|
246
|
+
/** On a 429: whole seconds to wait; the same number as the Retry-After header. */
|
|
247
|
+
retryAfterSeconds?: number
|
|
248
|
+
details?: { name: string; message: string }
|
|
249
|
+
}
|
|
250
|
+
}
|