pipework 0.252.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 +5 -0
- 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,535 @@
|
|
|
1
|
+
import type { Schema, Infer } from '../../data/schema/types.js'
|
|
2
|
+
import type { DB } from '../../data/db/index.js'
|
|
3
|
+
import { DEFAULT_DB } from './types.js'
|
|
4
|
+
import type { Handler, HandlerMeta, HttpMethod, RouteMeta, AuthRequirement, PermissionMeta, JobRetryConfig, JobTransactionMode, Checkpoint, RouteScreen, UploadConfig, BinaryUploadConfig, MultipartUploadConfig, BinaryUpload, MultipartUpload, FileConfig, RouteRefusedHook } from './types.js'
|
|
5
|
+
import type { ResourceOperations, Resource, PaginationConfig } from '../fixture/types.js'
|
|
6
|
+
import type { HttpRequest, HttpResponse, CorsConfig } from '../http/types.js'
|
|
7
|
+
import { buildResource } from '../fixture/builder.js'
|
|
8
|
+
|
|
9
|
+
interface BuilderState {
|
|
10
|
+
databases: string[]
|
|
11
|
+
requiresAuth: boolean
|
|
12
|
+
authRequirement: AuthRequirement
|
|
13
|
+
inputSchema: Schema | null
|
|
14
|
+
outputSchemas: Map<number, Schema>
|
|
15
|
+
querySchema: Schema | null
|
|
16
|
+
paramsSchema: Schema | null
|
|
17
|
+
route: RouteMeta | null
|
|
18
|
+
cors: CorsConfig | false | null
|
|
19
|
+
rateLimit: string | false | null
|
|
20
|
+
isJob: boolean
|
|
21
|
+
jobType: string | null
|
|
22
|
+
jobRetry: JobRetryConfig | null
|
|
23
|
+
jobTimeout: number | null
|
|
24
|
+
jobTransaction: JobTransactionMode
|
|
25
|
+
permission: PermissionMeta | null
|
|
26
|
+
pagination: PaginationConfig | null
|
|
27
|
+
wantsRequest: boolean
|
|
28
|
+
wantsResponse: boolean
|
|
29
|
+
wantsRawBody: boolean
|
|
30
|
+
ignoresBody: boolean
|
|
31
|
+
upload: UploadConfig | null
|
|
32
|
+
file: FileConfig | null
|
|
33
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
34
|
+
onRefused: RouteRefusedHook<any, any, any> | null
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Deps shape after `.transaction('manual')`: the databases the handler declared
|
|
39
|
+
* with `.use()` move out of the top-level deps (a non-transactional handle there
|
|
40
|
+
* would be a footgun) and into `checkpoint`'s callback, which binds them inside a
|
|
41
|
+
* fresh tenant-scoped transaction. `checkpoint` is added in their place.
|
|
42
|
+
*/
|
|
43
|
+
type ManualDeps<TDeps, TDb> = Omit<TDeps, keyof TDb> & { checkpoint: Checkpoint<TDb> }
|
|
44
|
+
|
|
45
|
+
type DepOf<TDeps, K extends string> = TDeps extends Record<K, infer V> ? V : unknown
|
|
46
|
+
|
|
47
|
+
export class Builder<
|
|
48
|
+
TDeps extends Record<string, unknown>,
|
|
49
|
+
TDb extends Record<string, DB> = Record<never, DB>,
|
|
50
|
+
> {
|
|
51
|
+
private readonly state: BuilderState
|
|
52
|
+
|
|
53
|
+
constructor(state?: Partial<BuilderState>) {
|
|
54
|
+
this.state = {
|
|
55
|
+
databases: state?.databases ?? [],
|
|
56
|
+
requiresAuth: state?.requiresAuth ?? false,
|
|
57
|
+
authRequirement: state?.authRequirement ?? 'none',
|
|
58
|
+
inputSchema: state?.inputSchema ?? null,
|
|
59
|
+
outputSchemas: state?.outputSchemas ?? new Map(),
|
|
60
|
+
querySchema: state?.querySchema ?? null,
|
|
61
|
+
paramsSchema: state?.paramsSchema ?? null,
|
|
62
|
+
route: state?.route ?? null,
|
|
63
|
+
cors: state?.cors ?? null,
|
|
64
|
+
rateLimit: state?.rateLimit ?? null,
|
|
65
|
+
isJob: state?.isJob ?? false,
|
|
66
|
+
jobType: state?.jobType ?? null,
|
|
67
|
+
jobRetry: state?.jobRetry ?? null,
|
|
68
|
+
jobTimeout: state?.jobTimeout ?? null,
|
|
69
|
+
jobTransaction: state?.jobTransaction ?? 'auto',
|
|
70
|
+
permission: state?.permission ?? null,
|
|
71
|
+
pagination: state?.pagination ?? null,
|
|
72
|
+
wantsRequest: state?.wantsRequest ?? false,
|
|
73
|
+
wantsResponse: state?.wantsResponse ?? false,
|
|
74
|
+
wantsRawBody: state?.wantsRawBody ?? false,
|
|
75
|
+
ignoresBody: state?.ignoresBody ?? false,
|
|
76
|
+
upload: state?.upload ?? null,
|
|
77
|
+
file: state?.file ?? null,
|
|
78
|
+
onRefused: state?.onRefused ?? null,
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
use(): Builder<TDeps & { db: DB }, TDb & { db: DB }>
|
|
83
|
+
use<N extends string>(name: N): Builder<TDeps & Record<N, DB>, TDb & Record<N, DB>>
|
|
84
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
85
|
+
use(name?: string): Builder<any, any> {
|
|
86
|
+
const sentinel = name ?? DEFAULT_DB
|
|
87
|
+
return new Builder({
|
|
88
|
+
...this.state,
|
|
89
|
+
databases: [...this.state.databases, sentinel],
|
|
90
|
+
})
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
auth<TAuth>(): Builder<TDeps & { auth: TAuth }, TDb> {
|
|
94
|
+
return new Builder<TDeps & { auth: TAuth }, TDb>({
|
|
95
|
+
...this.state,
|
|
96
|
+
requiresAuth: true,
|
|
97
|
+
authRequirement: 'required',
|
|
98
|
+
})
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
authOptional<TAuth>(): Builder<TDeps & { auth: TAuth | null }, TDb> {
|
|
102
|
+
return new Builder<TDeps & { auth: TAuth | null }, TDb>({
|
|
103
|
+
...this.state,
|
|
104
|
+
requiresAuth: false,
|
|
105
|
+
authRequirement: 'optional',
|
|
106
|
+
})
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
public(): Builder<TDeps, TDb> {
|
|
110
|
+
return new Builder<TDeps, TDb>({
|
|
111
|
+
...this.state,
|
|
112
|
+
requiresAuth: false,
|
|
113
|
+
authRequirement: 'none',
|
|
114
|
+
})
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
input<T extends Schema>(schema: T): Builder<TDeps & { input: Infer<T> }, TDb> {
|
|
118
|
+
return new Builder<TDeps & { input: Infer<T> }, TDb>({
|
|
119
|
+
...this.state,
|
|
120
|
+
inputSchema: schema,
|
|
121
|
+
})
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
query<T extends Schema>(schema: T): Builder<TDeps & { query: Infer<T> }, TDb> {
|
|
125
|
+
return new Builder<TDeps & { query: Infer<T> }, TDb>({
|
|
126
|
+
...this.state,
|
|
127
|
+
querySchema: schema,
|
|
128
|
+
})
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
params<T extends Schema>(schema: T): Builder<TDeps & { params: Infer<T> }, TDb> {
|
|
132
|
+
return new Builder<TDeps & { params: Infer<T> }, TDb>({
|
|
133
|
+
...this.state,
|
|
134
|
+
paramsSchema: schema,
|
|
135
|
+
})
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
output<T extends Schema>(schema: T): Builder<TDeps, TDb>
|
|
139
|
+
output<T extends Schema>(status: number, schema: T): Builder<TDeps, TDb>
|
|
140
|
+
output(statusOrSchema: number | Schema, maybeSchema?: Schema): Builder<TDeps, TDb> {
|
|
141
|
+
const schemas = new Map(this.state.outputSchemas)
|
|
142
|
+
const status = typeof statusOrSchema === 'number' ? statusOrSchema : 200
|
|
143
|
+
if (schemas.has(status)) {
|
|
144
|
+
const where = this.state.route ? ` on ${this.state.route.method} ${this.state.route.path}` : ''
|
|
145
|
+
throw new Error(
|
|
146
|
+
`[pipework] .output() declares status ${status} twice${where}.\n\n` +
|
|
147
|
+
` A status keeps one schema; the second would silently replace the first, and a body valid for the first would answer 422.\n` +
|
|
148
|
+
` Fix: declare ${status} once, with a schema that is a union of the bodies, e.g. .output(${status}, schema.check.union([a, b])).\n`,
|
|
149
|
+
)
|
|
150
|
+
}
|
|
151
|
+
schemas.set(status, typeof statusOrSchema === 'number' ? maybeSchema! : statusOrSchema)
|
|
152
|
+
return new Builder<TDeps, TDb>({
|
|
153
|
+
...this.state,
|
|
154
|
+
outputSchemas: schemas,
|
|
155
|
+
})
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
route(method: HttpMethod, path: string, options?: { bodyLimit?: number; screen?: RouteScreen }): Builder<TDeps, TDb> {
|
|
159
|
+
return new Builder<TDeps, TDb>({
|
|
160
|
+
...this.state,
|
|
161
|
+
route: {
|
|
162
|
+
method,
|
|
163
|
+
path,
|
|
164
|
+
...(options?.bodyLimit !== undefined ? { bodyLimit: options.bodyLimit } : {}),
|
|
165
|
+
...(options?.screen !== undefined ? { screen: options.screen } : {}),
|
|
166
|
+
},
|
|
167
|
+
})
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* This route's own CORS grant. It replaces the server-level `cors` for this route
|
|
172
|
+
* (no merge); `.cors(false)` closes the route under an open server. Preflight
|
|
173
|
+
* requests for the route's path and method are answered from the same grant.
|
|
174
|
+
*/
|
|
175
|
+
cors(grant: CorsConfig | false): Builder<TDeps, TDb> {
|
|
176
|
+
return new Builder<TDeps, TDb>({ ...this.state, cors: grant })
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Puts this route in a named class of `rateLimits.classes`; `false` exempts it. Without this, the
|
|
181
|
+
* class follows the auth requirement: `signedIn` for required, `public` for none, and for optional
|
|
182
|
+
* `signedIn` when a user is signed in, else `public`. A name the server config lacks is refused
|
|
183
|
+
* when the server is built.
|
|
184
|
+
*/
|
|
185
|
+
rateLimit(name: string | false): Builder<TDeps, TDb> {
|
|
186
|
+
return new Builder<TDeps, TDb>({ ...this.state, rateLimit: name })
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Marks this handler a job. Its deps gain `signal`: aborted when the job is no longer this
|
|
191
|
+
* handler's (returned to pending on shutdown, ...); check it before any outside effect.
|
|
192
|
+
*/
|
|
193
|
+
job(type?: string): Builder<TDeps & { signal: AbortSignal }, TDb> {
|
|
194
|
+
return new Builder<TDeps & { signal: AbortSignal }, TDb>({
|
|
195
|
+
...this.state,
|
|
196
|
+
isJob: true,
|
|
197
|
+
jobType: type ?? null,
|
|
198
|
+
})
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Selects how this handler's database transaction(s) are managed. Applies to
|
|
203
|
+
* a job and to a route alike.
|
|
204
|
+
*
|
|
205
|
+
* `'auto'` (default) keeps the single framework-owned outer transaction.
|
|
206
|
+
* `'manual'` opens no outer transaction; the handler instead receives a
|
|
207
|
+
* `checkpoint(fn)` primitive and owns its own commit boundaries — the
|
|
208
|
+
* databases declared with `.use()` move from the top-level deps into
|
|
209
|
+
* `checkpoint`'s callback.
|
|
210
|
+
*
|
|
211
|
+
* **What manual mode costs, on either surface.** Each checkpoint commits
|
|
212
|
+
* independently and durably. An error after one has committed leaves that
|
|
213
|
+
* state committed: for a job the contract shifts from atomic to
|
|
214
|
+
* at-least-once / idempotent-on-resume, and for a route the response status
|
|
215
|
+
* no longer describes what is in the database — a 500 can follow work that
|
|
216
|
+
* is already durable. The handler owns its own compensation. In exchange it
|
|
217
|
+
* holds no connection between checkpoints, which is what lets a route commit,
|
|
218
|
+
* make a network call, and write again under the request's own tenant.
|
|
219
|
+
*
|
|
220
|
+
* **Against `pipe.system()`, the row state is the same.** `pipe.system()` also
|
|
221
|
+
* runs outside the request transaction and also commits mid-request, so a
|
|
222
|
+
* route already written that way sees no change in what is committed or when.
|
|
223
|
+
* What changes is which mechanism enforces the tenancy: a hand-written `WHERE`
|
|
224
|
+
* on a connection that bypasses row-level security, versus the database under
|
|
225
|
+
* the request's own tenant. That is not observable in the rows, so a test that
|
|
226
|
+
* only reads them cannot tell the two apart — the difference shows up as a
|
|
227
|
+
* policy denial when the filter is wrong, which is the point.
|
|
228
|
+
*
|
|
229
|
+
* So a test that pins this property reads the handler's declaration next to
|
|
230
|
+
* the rows: `handler.meta.jobTransaction === 'manual'` and `handler.meta.databases`
|
|
231
|
+
* holding the databases `.use()` declared. (`jobTransaction` carries the mode
|
|
232
|
+
* for a route too; the name predates the route surface.) Half the property is
|
|
233
|
+
* in the rows and half is in the declaration, and only the pair of them
|
|
234
|
+
* catches a silent move back to `pipe.system()`.
|
|
235
|
+
*/
|
|
236
|
+
transaction(mode: 'auto'): Builder<TDeps, TDb>
|
|
237
|
+
transaction(mode: 'manual'): Builder<ManualDeps<TDeps, TDb>, TDb>
|
|
238
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
239
|
+
transaction(mode: JobTransactionMode): Builder<any, TDb> {
|
|
240
|
+
return new Builder({
|
|
241
|
+
...this.state,
|
|
242
|
+
jobTransaction: mode,
|
|
243
|
+
})
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
retry(config: JobRetryConfig): Builder<TDeps, TDb> {
|
|
247
|
+
return new Builder<TDeps, TDb>({
|
|
248
|
+
...this.state,
|
|
249
|
+
jobRetry: config,
|
|
250
|
+
})
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
timeout(ms: number): Builder<TDeps, TDb> {
|
|
254
|
+
return new Builder<TDeps, TDb>({
|
|
255
|
+
...this.state,
|
|
256
|
+
jobTimeout: ms,
|
|
257
|
+
})
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
permission(resource: string, action: string, scope?: string): Builder<TDeps, TDb> {
|
|
261
|
+
const perm: PermissionMeta = scope !== undefined
|
|
262
|
+
? { resource, action, scope }
|
|
263
|
+
: { resource, action }
|
|
264
|
+
return new Builder<TDeps, TDb>({
|
|
265
|
+
...this.state,
|
|
266
|
+
permission: perm,
|
|
267
|
+
})
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
paginate(config: { defaultLimit?: number; maxLimit?: number } = {}): Builder<TDeps, TDb> {
|
|
271
|
+
return new Builder<TDeps, TDb>({
|
|
272
|
+
...this.state,
|
|
273
|
+
pagination: {
|
|
274
|
+
defaultLimit: config.defaultLimit ?? 20,
|
|
275
|
+
maxLimit: config.maxLimit ?? 100,
|
|
276
|
+
},
|
|
277
|
+
})
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
request(): Builder<TDeps & { request: HttpRequest }, TDb> {
|
|
281
|
+
return new Builder<TDeps & { request: HttpRequest }, TDb>({
|
|
282
|
+
...this.state,
|
|
283
|
+
wantsRequest: true,
|
|
284
|
+
})
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
response(): Builder<TDeps & { response: HttpResponse }, TDb> {
|
|
288
|
+
return new Builder<TDeps & { response: HttpResponse }, TDb>({
|
|
289
|
+
...this.state,
|
|
290
|
+
wantsResponse: true,
|
|
291
|
+
})
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
rawBody(): Builder<TDeps & { rawBody: Buffer }, TDb> {
|
|
295
|
+
return new Builder<TDeps & { rawBody: Buffer }, TDb>({
|
|
296
|
+
...this.state,
|
|
297
|
+
wantsRawBody: true,
|
|
298
|
+
})
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Makes this route accept a body of any content type and never read it: the body is drained
|
|
303
|
+
* unparsed (a declared length over 64 KiB is refused with 413) and `input` is undefined.
|
|
304
|
+
* For a POST whose body carries nothing the handler needs, such as an RFC 8058 one-click
|
|
305
|
+
* unsubscribe (`List-Unsubscribe=One-Click` as form-urlencoded or multipart). This route only:
|
|
306
|
+
* no other route's parsing changes. Cannot be combined with `.input()`, `.rawBody()` or `.upload()`.
|
|
307
|
+
*/
|
|
308
|
+
ignoreBody(): Builder<TDeps, TDb> {
|
|
309
|
+
return new Builder<TDeps, TDb>({ ...this.state, ignoresBody: true })
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Makes this route accept a file upload and hands the handler the file as a
|
|
314
|
+
* stream in the `upload` dep. The body is never buffered whole.
|
|
315
|
+
*
|
|
316
|
+
* `{ kind: 'binary', mediaTypes, maxBytes }` takes the request body itself as
|
|
317
|
+
* the file: `upload` is `{ stream, length, mediaType, detectedType,
|
|
318
|
+
* declaredType, extension }` (`length` is the declared Content-Length, null
|
|
319
|
+
* when chunked). `{ kind: 'multipart', file, mediaTypes, maxBytes, fields? }`
|
|
320
|
+
* takes the part named `file` of a `multipart/form-data` body: `upload` is
|
|
321
|
+
* `{ stream, filename, fields, mediaType, detectedType, declaredType,
|
|
322
|
+
* extension }`.
|
|
323
|
+
*
|
|
324
|
+
* `mediaTypes` is matched against `mediaType`, the type found in the file's
|
|
325
|
+
* first 1024 bytes (`detectedType`; null when no signature matches). A zip or
|
|
326
|
+
* compound-file container takes the declared type or filename extension when
|
|
327
|
+
* that names an Office, OpenDocument, epub, jar or apk file. With no
|
|
328
|
+
* signature the declared type stands, except a type a signature would show
|
|
329
|
+
* (pdf, png, ...), which the bytes then contradict and is refused. Entries
|
|
330
|
+
* may be `type/*` wildcards, or a star on each side of the slash to take any
|
|
331
|
+
* type and refuse in the handler.
|
|
332
|
+
*
|
|
333
|
+
* A body (binary) or file (multipart) over `maxBytes` gets 413: refused before
|
|
334
|
+
* reading when the declared Content-Length is over, and while streaming
|
|
335
|
+
* otherwise (the handler's read of `upload.stream` rejects with
|
|
336
|
+
* `errors.PayloadTooLarge`). A media type outside `mediaTypes` gets 415. The
|
|
337
|
+
* route's `screen`, when set, still runs first, and auth runs before any body
|
|
338
|
+
* is read.
|
|
339
|
+
*
|
|
340
|
+
* `onRefuse(refusal)` runs once for each such 413 or 415, in the request's
|
|
341
|
+
* context, with the detected and declared types, extension, filename, sizes,
|
|
342
|
+
* accepted list, auth, and the route's `params` and `query` as the handler gets
|
|
343
|
+
* them (typed when `.params()` / `.query()` come before `.upload()`; the raw
|
|
344
|
+
* values on a route with no schema; null when they fail it). A non-empty string it returns becomes the error
|
|
345
|
+
* message; if it throws, the default message is sent. Nothing of the file is
|
|
346
|
+
* kept: only its first 1024 bytes are held, to detect the type.
|
|
347
|
+
*
|
|
348
|
+
* Multipart: text fields must come before the file part, only names listed in
|
|
349
|
+
* `fields` are accepted (another name gets 422), each at most 64 KiB; fields
|
|
350
|
+
* after the file part are not read, and only the first file part is handed
|
|
351
|
+
* over. A missing file part gets 422.
|
|
352
|
+
*
|
|
353
|
+
* The handler must consume or destroy `upload.stream`. If it returns with the
|
|
354
|
+
* stream unfinished the framework destroys it and closes the connection after
|
|
355
|
+
* the response. Errors from the stream reach the handler as rejected reads and
|
|
356
|
+
* become the response when the handler lets them propagate.
|
|
357
|
+
*
|
|
358
|
+
* In `'auto'` transaction mode the request transaction, and its pool
|
|
359
|
+
* connection, is held for the whole upload: for large files use
|
|
360
|
+
* `.transaction('manual')` and write to the database in a `checkpoint` after
|
|
361
|
+
* the bytes are stored.
|
|
362
|
+
*
|
|
363
|
+
* Cannot be combined with `.input()`, `.rawBody()` or `.job()`; each throws.
|
|
364
|
+
*/
|
|
365
|
+
upload(config: BinaryUploadConfig<DepOf<TDeps, 'params'>, DepOf<TDeps, 'query'>>): Builder<TDeps & { upload: BinaryUpload }, TDb>
|
|
366
|
+
upload(config: MultipartUploadConfig<DepOf<TDeps, 'params'>, DepOf<TDeps, 'query'>>): Builder<TDeps & { upload: MultipartUpload }, TDb>
|
|
367
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
368
|
+
upload(config: BinaryUploadConfig<any, any> | MultipartUploadConfig<any, any>): Builder<any, TDb> {
|
|
369
|
+
if (config.mediaTypes.length === 0) {
|
|
370
|
+
throw new Error('[pipework] .upload() needs at least one entry in mediaTypes (e.g. ["application/pdf"] or ["image/*"]).')
|
|
371
|
+
}
|
|
372
|
+
if (!Number.isInteger(config.maxBytes) || config.maxBytes <= 0) {
|
|
373
|
+
throw new Error(`[pipework] .upload() maxBytes must be a positive integer number of bytes, got ${String(config.maxBytes)}.`)
|
|
374
|
+
}
|
|
375
|
+
if (config.kind === 'multipart' && config.file === '') {
|
|
376
|
+
throw new Error('[pipework] .upload({ kind: "multipart" }) needs the form field name of the file in `file`.')
|
|
377
|
+
}
|
|
378
|
+
return new Builder({
|
|
379
|
+
...this.state,
|
|
380
|
+
upload: config,
|
|
381
|
+
})
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Declares that this route answers with a file, returned from the handler as
|
|
386
|
+
* `http.file({ body, mediaType, filename? ... })`. `mediaTypes` lists what the
|
|
387
|
+
* route may send (`type/*` wildcards allowed) and `status` (default 200) is the
|
|
388
|
+
* status of the file response. OpenAPI gets `responses.<status>.content.<type>`
|
|
389
|
+
* as `{ type: 'string', format: 'binary' }` for each media type.
|
|
390
|
+
*
|
|
391
|
+
* At the file's status the route must return `http.file(...)`: anything else,
|
|
392
|
+
* or a file whose `mediaType` is outside `mediaTypes`, is a 500 with the reason
|
|
393
|
+
* in the body. At any other status it answers as on any route: return
|
|
394
|
+
* `{ status, body? }` (declare the body with `.output(status, schema)`); a
|
|
395
|
+
* redirect is `{ status: 302 }` after `response.header('location', url)` on
|
|
396
|
+
* a `.response()` route. A Buffer is sent whole with Content-Length; a Readable is
|
|
397
|
+
* streamed (add `length` for Content-Length, else it is chunked). Content-
|
|
398
|
+
* Disposition carries an ASCII `filename=` fallback and the exact name in
|
|
399
|
+
* `filename*`, and the response sets `X-Content-Type-Options: nosniff`.
|
|
400
|
+
*
|
|
401
|
+
* The request transaction (auto mode) has committed before the body streams,
|
|
402
|
+
* so the stream must not need it. A stream that fails after the first byte
|
|
403
|
+
* destroys the connection and logs the error. Range requests are not supported.
|
|
404
|
+
*
|
|
405
|
+
* Cannot be combined with `.output()` for the same status, or with `.job()`;
|
|
406
|
+
* `fit()` throws.
|
|
407
|
+
*/
|
|
408
|
+
file(config: { mediaTypes: readonly string[]; status?: number }): Builder<TDeps, TDb> {
|
|
409
|
+
if (config.mediaTypes.length === 0) {
|
|
410
|
+
throw new Error('[pipework] .file() needs at least one entry in mediaTypes (e.g. ["application/pdf"] or ["image/*"]).')
|
|
411
|
+
}
|
|
412
|
+
const status = config.status ?? 200
|
|
413
|
+
if (!Number.isInteger(status) || status < 200 || status > 599) {
|
|
414
|
+
throw new Error(`[pipework] .file() status must be an HTTP status code, got ${String(config.status)}.`)
|
|
415
|
+
}
|
|
416
|
+
return new Builder<TDeps, TDb>({
|
|
417
|
+
...this.state,
|
|
418
|
+
file: { mediaTypes: [...config.mediaTypes], status },
|
|
419
|
+
})
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Runs `hook` once for every 4xx this route answers, including those made before
|
|
424
|
+
* the handler: the input/params/query 422, auth 401, permission 403, 429, upload
|
|
425
|
+
* 413/415 and the handler's own thrown 4xx. Never for a 5xx, nor the route's `screen`.
|
|
426
|
+
* It gets `{ status, code, message, fields, auth, params, query, request,
|
|
427
|
+
* requestId }`; `auth` is null where auth itself refused, `params`/`query` are null
|
|
428
|
+
* when they fail their schema. A plain object it returns is merged into the
|
|
429
|
+
* response's `error`; `code`, `message`, `fields` and `details` keep pipework's
|
|
430
|
+
* values (a hook that sets one is warned and dropped). A throw is logged and the
|
|
431
|
+
* refusal is sent as without the hook. Runs in the request's Flow as a trace step
|
|
432
|
+
* after the upload `onRefuse`, once the request transaction has rolled back: it has none.
|
|
433
|
+
*/
|
|
434
|
+
onRefused(hook: RouteRefusedHook<DepOf<TDeps, 'auth'>, DepOf<TDeps, 'params'>, DepOf<TDeps, 'query'>>): Builder<TDeps, TDb> {
|
|
435
|
+
return new Builder<TDeps, TDb>({ ...this.state, onRefused: hook })
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
fixture<TAuth>(name: string, operations: ResourceOperations<TAuth>): Resource<TAuth> {
|
|
439
|
+
const dbName = this.state.databases[0]
|
|
440
|
+
if (dbName === undefined) {
|
|
441
|
+
throw new Error(
|
|
442
|
+
`[pipework] .fixture("${name}") requires a database. Call .use("dbName") before .fixture().`,
|
|
443
|
+
)
|
|
444
|
+
}
|
|
445
|
+
return buildResource(name, operations, {
|
|
446
|
+
database: dbName,
|
|
447
|
+
authRequirement: this.state.authRequirement,
|
|
448
|
+
permission: this.state.permission,
|
|
449
|
+
pagination: this.state.pagination,
|
|
450
|
+
})
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
fit<TReturn>(fn: (deps: TDeps) => Promise<TReturn>): Handler<TDeps, TReturn> {
|
|
454
|
+
if (this.state.jobTransaction === 'manual' && this.state.databases.length === 0) {
|
|
455
|
+
throw new Error(
|
|
456
|
+
'[pipework] .transaction("manual") requires at least one database.\n\n' +
|
|
457
|
+
' A checkpointed handler commits database work incrementally, so it must\n' +
|
|
458
|
+
' declare which database(s) participate. Call .use("dbName") before\n' +
|
|
459
|
+
' .transaction("manual").\n'
|
|
460
|
+
)
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
if (this.state.upload !== null) {
|
|
464
|
+
const what = this.state.isJob ? '.job()' : this.state.inputSchema !== null ? '.input()' : this.state.wantsRawBody ? '.rawBody()' : null
|
|
465
|
+
if (what !== null) {
|
|
466
|
+
throw new Error(
|
|
467
|
+
`[pipework] .upload() cannot be combined with ${what}.\n\n` +
|
|
468
|
+
' An upload route\'s body is the file, delivered as a stream in the `upload` dep.\n' +
|
|
469
|
+
' Remove ' + what + (what === '.job()' ? ': a job has no request body to stream.' : ', or take the text fields from a multipart form (`fields`).') + '\n',
|
|
470
|
+
)
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
if (this.state.ignoresBody) {
|
|
475
|
+
const what = this.state.upload !== null ? '.upload()' : this.state.inputSchema !== null ? '.input()' : this.state.wantsRawBody ? '.rawBody()' : null
|
|
476
|
+
if (what !== null) {
|
|
477
|
+
throw new Error(`[pipework] .ignoreBody() cannot be combined with ${what}: the body is drained unread, so ${what} would have nothing to read. Remove one.`)
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
if (this.state.file !== null) {
|
|
482
|
+
if (this.state.isJob) {
|
|
483
|
+
throw new Error(
|
|
484
|
+
'[pipework] .file() cannot be combined with .job().\n\n' +
|
|
485
|
+
' A file response is sent to an HTTP client; a job has no response to send.\n' +
|
|
486
|
+
' Remove .file(), or remove .job().\n',
|
|
487
|
+
)
|
|
488
|
+
}
|
|
489
|
+
if (this.state.outputSchemas.has(this.state.file.status)) {
|
|
490
|
+
throw new Error(
|
|
491
|
+
`[pipework] .file() and .output(${this.state.file.status}, ...) both declare the ${this.state.file.status} response.\n\n` +
|
|
492
|
+
' A route answers each status with one body: a file or a JSON schema.\n' +
|
|
493
|
+
' Remove .output() for that status, or give .file({ status }) another one.\n',
|
|
494
|
+
)
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
const meta: HandlerMeta = {
|
|
499
|
+
databases: this.state.databases,
|
|
500
|
+
requiresAuth: this.state.requiresAuth,
|
|
501
|
+
authRequirement: this.state.authRequirement,
|
|
502
|
+
inputSchema: this.state.inputSchema,
|
|
503
|
+
outputSchemas: this.state.outputSchemas,
|
|
504
|
+
querySchema: this.state.querySchema,
|
|
505
|
+
paramsSchema: this.state.paramsSchema,
|
|
506
|
+
route: this.state.route,
|
|
507
|
+
cors: this.state.cors,
|
|
508
|
+
rateLimit: this.state.rateLimit,
|
|
509
|
+
isJob: this.state.isJob,
|
|
510
|
+
jobType: this.state.jobType,
|
|
511
|
+
jobRetry: this.state.jobRetry,
|
|
512
|
+
jobTimeout: this.state.jobTimeout,
|
|
513
|
+
jobTransaction: this.state.jobTransaction,
|
|
514
|
+
permission: this.state.permission,
|
|
515
|
+
wantsRequest: this.state.wantsRequest,
|
|
516
|
+
wantsResponse: this.state.wantsResponse,
|
|
517
|
+
wantsRawBody: this.state.wantsRawBody,
|
|
518
|
+
ignoresBody: this.state.ignoresBody,
|
|
519
|
+
upload: this.state.upload,
|
|
520
|
+
file: this.state.file,
|
|
521
|
+
onRefused: this.state.onRefused,
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
return {
|
|
525
|
+
async execute(deps: TDeps): Promise<TReturn> {
|
|
526
|
+
return fn(deps)
|
|
527
|
+
},
|
|
528
|
+
meta,
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
export function createBuilder(): Builder<Record<never, never>> {
|
|
534
|
+
return new Builder()
|
|
535
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { createBuilder } from './builder.js'
|
|
2
|
+
|
|
3
|
+
export const fitting = createBuilder()
|
|
4
|
+
|
|
5
|
+
export { createBuilder, Builder } from './builder.js'
|
|
6
|
+
export { resolveAndExecute, type ResolveOptions } from './resolve.js'
|
|
7
|
+
export { DEFAULT_DB } from './types.js'
|
|
8
|
+
export type { Handler, HandlerMeta, RouteMeta, HttpMethod, InferDeps, InferReturn, DatabaseDeps, JobTransactionMode, Checkpoint, UploadConfig, BinaryUploadConfig, MultipartUploadConfig, BinaryUpload, MultipartUpload, FileConfig } from './types.js'
|