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,239 @@
|
|
|
1
|
+
import type { z } from 'zod/v4'
|
|
2
|
+
import type { FieldDescriptor, DefineOptions, DefinedTable, DefinitionMethods, EffectiveDatedFields, AppendOnlyVersionsFields, AuditedFields, SoftDeletedFields } from './types.js'
|
|
3
|
+
import type { AcceptReadonly } from '../db/readonly.js'
|
|
4
|
+
import type { InsertProjection, SelectProjection, UpdateProjection } from './projections.js'
|
|
5
|
+
import type { InferSelect } from './brand.js'
|
|
6
|
+
import { projectTable } from './build-table.js'
|
|
7
|
+
import { projectInsertShape, projectSelectShape, projectUpdateShape } from './build-schema.js'
|
|
8
|
+
import { projectFactory } from './build-factory.js'
|
|
9
|
+
import { applyTrait, effectiveDatedTrait, appendOnlyVersionsTrait, auditedTrait, softDeletedTrait } from './traits.js'
|
|
10
|
+
import { hasExternalName, clearExternalNames } from './external-registry.js'
|
|
11
|
+
import { scopeTable } from '../../auth/tenant/scope.js'
|
|
12
|
+
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- registry erases field-level generics; concrete types flow through define()'s return type
|
|
14
|
+
const registry = new Map<string, DefinedTable<any>>()
|
|
15
|
+
|
|
16
|
+
export function define<TFields extends Record<string, FieldDescriptor>, TName extends string = string>(
|
|
17
|
+
name: TName,
|
|
18
|
+
initialFields: TFields,
|
|
19
|
+
options?: DefineOptions,
|
|
20
|
+
): DefinedTable<TFields, TName> {
|
|
21
|
+
if (hasExternalName(name)) {
|
|
22
|
+
throw new Error(
|
|
23
|
+
`[pipework] Duplicate domain definition: "${name}" is already declared with pipe.external.\n\n` +
|
|
24
|
+
' Each definition, external or not, must have a unique name.\n' +
|
|
25
|
+
' Fix: rename one of them.\n',
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
if (registry.has(name)) {
|
|
29
|
+
throw new Error(
|
|
30
|
+
`[pipework] Duplicate domain definition: "${name}" is already registered.\n\n` +
|
|
31
|
+
' Each definition must have a unique name.\n' +
|
|
32
|
+
` Existing: ${registry.get(name)!.$options.virtual === true ? 'virtual' : 'database table'}\n` +
|
|
33
|
+
` Duplicate: ${options?.virtual === true ? 'virtual' : 'database table'}\n`,
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const result = buildDefinedTable(name, initialFields, options ?? {}, [])
|
|
38
|
+
registry.set(name, result)
|
|
39
|
+
return result
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function buildDefinedTable<TFields extends Record<string, FieldDescriptor>, TName extends string>(
|
|
43
|
+
name: TName,
|
|
44
|
+
fields: TFields,
|
|
45
|
+
opts: DefineOptions,
|
|
46
|
+
traits: string[],
|
|
47
|
+
): DefinedTable<TFields, TName> {
|
|
48
|
+
if (opts.virtual === true) {
|
|
49
|
+
return buildVirtualDefinition(name, fields, opts, traits)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const table = projectTable(name, fields as Record<string, FieldDescriptor>, opts)
|
|
53
|
+
|
|
54
|
+
const tenantFieldKey = Object.keys(fields).find(
|
|
55
|
+
(key) => (fields[key] as FieldDescriptor)._meta.tenant === true,
|
|
56
|
+
)
|
|
57
|
+
if (tenantFieldKey !== undefined) {
|
|
58
|
+
scopeTable(table, tenantFieldKey)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
let cachedInsertShape: z.ZodType<InsertProjection<TFields>> | undefined
|
|
62
|
+
let cachedSelectShape: z.ZodType<SelectProjection<TFields>> | undefined
|
|
63
|
+
let cachedUpdateShape: z.ZodType<UpdateProjection<TFields>> | undefined
|
|
64
|
+
|
|
65
|
+
const methods: DefinitionMethods<TFields, TName> = {
|
|
66
|
+
$name: name,
|
|
67
|
+
get $fields() { return fields },
|
|
68
|
+
$options: opts,
|
|
69
|
+
get $traits() { return traits as readonly string[] },
|
|
70
|
+
|
|
71
|
+
table() { return table },
|
|
72
|
+
|
|
73
|
+
insertShape() {
|
|
74
|
+
if (cachedInsertShape === undefined) {
|
|
75
|
+
cachedInsertShape = projectInsertShape(fields)
|
|
76
|
+
}
|
|
77
|
+
return cachedInsertShape
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
selectShape() {
|
|
81
|
+
if (cachedSelectShape === undefined) {
|
|
82
|
+
cachedSelectShape = projectSelectShape(fields)
|
|
83
|
+
}
|
|
84
|
+
return cachedSelectShape
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
updateShape() {
|
|
88
|
+
if (cachedUpdateShape === undefined) {
|
|
89
|
+
cachedUpdateShape = projectUpdateShape(fields)
|
|
90
|
+
}
|
|
91
|
+
return cachedUpdateShape
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
factory() {
|
|
95
|
+
return projectFactory(result)
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
effectiveDated() {
|
|
99
|
+
const applied = applyTrait(name, fields as Record<string, FieldDescriptor>, traits, effectiveDatedTrait)
|
|
100
|
+
const rebuilt = buildDefinedTable(name, applied.fields as TFields & EffectiveDatedFields, opts, applied.traits)
|
|
101
|
+
registry.set(name, rebuilt)
|
|
102
|
+
return rebuilt
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
appendOnlyVersions() {
|
|
106
|
+
const applied = applyTrait(name, fields as Record<string, FieldDescriptor>, traits, appendOnlyVersionsTrait)
|
|
107
|
+
const rebuilt = buildDefinedTable(name, applied.fields as TFields & AppendOnlyVersionsFields, opts, applied.traits)
|
|
108
|
+
registry.set(name, rebuilt)
|
|
109
|
+
return rebuilt
|
|
110
|
+
},
|
|
111
|
+
|
|
112
|
+
audited() {
|
|
113
|
+
const applied = applyTrait(name, fields as Record<string, FieldDescriptor>, traits, auditedTrait)
|
|
114
|
+
const rebuilt = buildDefinedTable(name, applied.fields as TFields & AuditedFields, opts, applied.traits)
|
|
115
|
+
registry.set(name, rebuilt)
|
|
116
|
+
return rebuilt
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
softDeleted() {
|
|
120
|
+
const applied = applyTrait(name, fields as Record<string, FieldDescriptor>, traits, softDeletedTrait)
|
|
121
|
+
const rebuilt = buildDefinedTable(name, applied.fields as TFields & SoftDeletedFields, opts, applied.traits)
|
|
122
|
+
registry.set(name, rebuilt)
|
|
123
|
+
return rebuilt
|
|
124
|
+
},
|
|
125
|
+
|
|
126
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- phantom type marker, never accessed at runtime
|
|
127
|
+
get Select(): InferSelect<TFields> { return undefined as any },
|
|
128
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- phantom type marker, never accessed at runtime
|
|
129
|
+
get Insert(): AcceptReadonly<InsertProjection<TFields>> { return undefined as any },
|
|
130
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- phantom type marker, never accessed at runtime
|
|
131
|
+
get Update(): AcceptReadonly<UpdateProjection<TFields>> { return undefined as any },
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const result = Object.assign(table, methods) as unknown as DefinedTable<TFields, TName>
|
|
135
|
+
return result
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function buildVirtualDefinition<TFields extends Record<string, FieldDescriptor>, TName extends string>(
|
|
139
|
+
name: TName,
|
|
140
|
+
fields: TFields,
|
|
141
|
+
opts: DefineOptions,
|
|
142
|
+
traits: string[],
|
|
143
|
+
): DefinedTable<TFields, TName> {
|
|
144
|
+
let cachedInsertShape: z.ZodType<InsertProjection<TFields>> | undefined
|
|
145
|
+
let cachedSelectShape: z.ZodType<SelectProjection<TFields>> | undefined
|
|
146
|
+
let cachedUpdateShape: z.ZodType<UpdateProjection<TFields>> | undefined
|
|
147
|
+
|
|
148
|
+
const definition = {
|
|
149
|
+
$name: name,
|
|
150
|
+
get $fields() { return fields },
|
|
151
|
+
$options: opts,
|
|
152
|
+
get $traits() { return traits as readonly string[] },
|
|
153
|
+
|
|
154
|
+
table() {
|
|
155
|
+
throw new Error(
|
|
156
|
+
`[pipework] "${name}" is a virtual definition — no database table.\n\n` +
|
|
157
|
+
' Virtual definitions have no .table() projection.\n' +
|
|
158
|
+
' Remove { virtual: true } if this definition needs a database table.\n',
|
|
159
|
+
)
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
insertShape() {
|
|
163
|
+
if (cachedInsertShape === undefined) {
|
|
164
|
+
cachedInsertShape = projectInsertShape(fields)
|
|
165
|
+
}
|
|
166
|
+
return cachedInsertShape
|
|
167
|
+
},
|
|
168
|
+
|
|
169
|
+
selectShape() {
|
|
170
|
+
if (cachedSelectShape === undefined) {
|
|
171
|
+
cachedSelectShape = projectSelectShape(fields)
|
|
172
|
+
}
|
|
173
|
+
return cachedSelectShape
|
|
174
|
+
},
|
|
175
|
+
|
|
176
|
+
updateShape() {
|
|
177
|
+
if (cachedUpdateShape === undefined) {
|
|
178
|
+
cachedUpdateShape = projectUpdateShape(fields)
|
|
179
|
+
}
|
|
180
|
+
return cachedUpdateShape
|
|
181
|
+
},
|
|
182
|
+
|
|
183
|
+
factory() {
|
|
184
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- registry erases field-level generics
|
|
185
|
+
return projectFactory(definition as unknown as DefinedTable<any>)
|
|
186
|
+
},
|
|
187
|
+
|
|
188
|
+
effectiveDated() {
|
|
189
|
+
const applied = applyTrait(name, fields as Record<string, FieldDescriptor>, traits, effectiveDatedTrait)
|
|
190
|
+
const rebuilt = buildVirtualDefinition(name, applied.fields as TFields & EffectiveDatedFields, opts, applied.traits)
|
|
191
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- registry erases field-level generics
|
|
192
|
+
registry.set(name, rebuilt as unknown as DefinedTable<any>)
|
|
193
|
+
return rebuilt
|
|
194
|
+
},
|
|
195
|
+
|
|
196
|
+
appendOnlyVersions() {
|
|
197
|
+
const applied = applyTrait(name, fields as Record<string, FieldDescriptor>, traits, appendOnlyVersionsTrait)
|
|
198
|
+
const rebuilt = buildVirtualDefinition(name, applied.fields as TFields & AppendOnlyVersionsFields, opts, applied.traits)
|
|
199
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- registry erases field-level generics
|
|
200
|
+
registry.set(name, rebuilt as unknown as DefinedTable<any>)
|
|
201
|
+
return rebuilt
|
|
202
|
+
},
|
|
203
|
+
|
|
204
|
+
audited() {
|
|
205
|
+
const applied = applyTrait(name, fields as Record<string, FieldDescriptor>, traits, auditedTrait)
|
|
206
|
+
const rebuilt = buildVirtualDefinition(name, applied.fields as TFields & AuditedFields, opts, applied.traits)
|
|
207
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- registry erases field-level generics
|
|
208
|
+
registry.set(name, rebuilt as unknown as DefinedTable<any>)
|
|
209
|
+
return rebuilt
|
|
210
|
+
},
|
|
211
|
+
|
|
212
|
+
softDeleted() {
|
|
213
|
+
const applied = applyTrait(name, fields as Record<string, FieldDescriptor>, traits, softDeletedTrait)
|
|
214
|
+
const rebuilt = buildVirtualDefinition(name, applied.fields as TFields & SoftDeletedFields, opts, applied.traits)
|
|
215
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- registry erases field-level generics
|
|
216
|
+
registry.set(name, rebuilt as unknown as DefinedTable<any>)
|
|
217
|
+
return rebuilt
|
|
218
|
+
},
|
|
219
|
+
|
|
220
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- phantom type marker, never accessed at runtime
|
|
221
|
+
get Select(): InferSelect<TFields> { return undefined as any },
|
|
222
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- phantom type marker, never accessed at runtime
|
|
223
|
+
get Insert(): AcceptReadonly<InsertProjection<TFields>> { return undefined as any },
|
|
224
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- phantom type marker, never accessed at runtime
|
|
225
|
+
get Update(): AcceptReadonly<UpdateProjection<TFields>> { return undefined as any },
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return definition as unknown as DefinedTable<TFields, TName>
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- registry erases field-level generics
|
|
232
|
+
export function definitions(): ReadonlyMap<string, DefinedTable<any>> {
|
|
233
|
+
return registry
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export function clearRegistry(): void {
|
|
237
|
+
registry.clear()
|
|
238
|
+
clearExternalNames()
|
|
239
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Names and table objects of relations declared with pipe.external. Kept apart
|
|
2
|
+
// from the definitions() registry so RLS, audit and startup validation never see them.
|
|
3
|
+
|
|
4
|
+
const names = new Set<string>()
|
|
5
|
+
const tables = new WeakSet<object>()
|
|
6
|
+
|
|
7
|
+
export function hasExternalName(name: string): boolean {
|
|
8
|
+
return names.has(name)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function registerExternal(name: string, table: object): void {
|
|
12
|
+
names.add(name)
|
|
13
|
+
tables.add(table)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function clearExternalNames(): void {
|
|
17
|
+
names.clear()
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** True for a table declared with pipe.external. */
|
|
21
|
+
export function isExternal(table: unknown): boolean {
|
|
22
|
+
return typeof table === 'object' && table !== null && tables.has(table)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Throws the [pipework] error a write gets when handed an external relation. */
|
|
26
|
+
export function assertNotExternal(table: unknown, verb: string): void {
|
|
27
|
+
if (!isExternal(table)) return
|
|
28
|
+
const name = (table as { $name?: string }).$name ?? 'external relation'
|
|
29
|
+
throw new Error(
|
|
30
|
+
`[pipework] pipe.${verb}: "${name}" is external and read-only.\n\n` +
|
|
31
|
+
' A relation declared with pipe.external is owned by another service; pipework never writes to it.\n' +
|
|
32
|
+
' Fix: write through the owning service, or declare the table with pipe.define if this app owns it.\n',
|
|
33
|
+
)
|
|
34
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { FieldDescriptor, ExternalTable } from './types.js'
|
|
2
|
+
import { pgTable, pgSchema } from '../query/pg-core/index.js'
|
|
3
|
+
import { buildColumns } from './build-table.js'
|
|
4
|
+
import { camelToSnake } from './naming.js'
|
|
5
|
+
import { definitions } from './define.js'
|
|
6
|
+
import { projectSelectShape } from './build-schema.js'
|
|
7
|
+
import { hasExternalName, registerExternal } from './external-registry.js'
|
|
8
|
+
|
|
9
|
+
export { isExternal, clearExternalNames } from './external-registry.js'
|
|
10
|
+
|
|
11
|
+
const IDENT = /^[a-z_][a-z0-9_]*$/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Declares a table or view that another service owns, so this app can read it with
|
|
15
|
+
* typed columns and the normal query operators.
|
|
16
|
+
*
|
|
17
|
+
* Contract: read-only (pipe.insert/update/delete/upsert reject it at compile time and
|
|
18
|
+
* at runtime), never migrated (a schema module exporting it produces no statements),
|
|
19
|
+
* not tenant-scoped (filter by the tenant column in the query), and not in the
|
|
20
|
+
* definitions() registry. Tables and views read the same way, so either works.
|
|
21
|
+
* `schema` is required; `table` defaults to the snake_case of `name`.
|
|
22
|
+
*/
|
|
23
|
+
export function external<TFields extends Record<string, FieldDescriptor>, TName extends string = string>(
|
|
24
|
+
name: TName,
|
|
25
|
+
fields: TFields,
|
|
26
|
+
options: { schema: string; table?: string },
|
|
27
|
+
): ExternalTable<TFields, TName> {
|
|
28
|
+
const schema = options.schema
|
|
29
|
+
const table = options.table ?? camelToSnake(name)
|
|
30
|
+
|
|
31
|
+
if (typeof schema !== 'string' || !IDENT.test(schema)) {
|
|
32
|
+
throw new Error(
|
|
33
|
+
`[pipework] "${name}" is external but its schema ${JSON.stringify(schema)} is not a plain identifier.\n\n` +
|
|
34
|
+
' Fix: pass { schema: "owner_schema" } using lowercase letters, digits and underscores.\n',
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
if (!IDENT.test(table)) {
|
|
38
|
+
throw new Error(
|
|
39
|
+
`[pipework] "${name}" is external but its table ${JSON.stringify(table)} is not a plain identifier.\n\n` +
|
|
40
|
+
' Fix: pass { table: "relation_name" } using lowercase letters, digits and underscores.\n',
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
if (hasExternalName(name) || definitions().has(name)) {
|
|
44
|
+
throw new Error(
|
|
45
|
+
`[pipework] Duplicate domain definition: "${name}" is already registered.\n\n` +
|
|
46
|
+
' Each definition, external or not, must have a unique name.\n' +
|
|
47
|
+
' Fix: rename one of them.\n',
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
for (const [key, descriptor] of Object.entries(fields)) {
|
|
51
|
+
if (descriptor._meta.tenant === true) {
|
|
52
|
+
throw new Error(
|
|
53
|
+
`[pipework] "${name}" is external: pipework does not scope it by tenant. ` +
|
|
54
|
+
`Fix: remove .tenant() from "${key}", and filter by the tenant column in the query.`,
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const { columns } = buildColumns(fields as Record<string, FieldDescriptor>, true)
|
|
60
|
+
const base = schema === 'public' ? pgTable(table, columns) : pgSchema(schema).table(table, columns)
|
|
61
|
+
|
|
62
|
+
let cachedSelect: ReturnType<typeof projectSelectShape> | undefined
|
|
63
|
+
const methods = {
|
|
64
|
+
$name: name,
|
|
65
|
+
get $fields() { return fields },
|
|
66
|
+
$external: { schema, table },
|
|
67
|
+
selectShape() {
|
|
68
|
+
cachedSelect ??= projectSelectShape(fields)
|
|
69
|
+
return cachedSelect
|
|
70
|
+
},
|
|
71
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- phantom type marker, never accessed at runtime
|
|
72
|
+
get Select(): any { return undefined },
|
|
73
|
+
}
|
|
74
|
+
const result = Object.assign(base, methods) as unknown as ExternalTable<TFields, TName>
|
|
75
|
+
registerExternal(name, result)
|
|
76
|
+
return result
|
|
77
|
+
}
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
import type { z } from 'zod/v4'
|
|
2
|
+
import type { FieldDescriptor, FieldMeta, FieldFlags, FieldKind, DefinedTable } from './types.js'
|
|
3
|
+
import type { CollationName } from '../query/collation.js'
|
|
4
|
+
import type { SQL } from '../db/types.js'
|
|
5
|
+
import type { Branded, InferFieldOutput } from './brand.js'
|
|
6
|
+
|
|
7
|
+
/** The one place a list column's refusals live: `.array()` against keys, tenant, generated ids and references, in either order. */
|
|
8
|
+
function refuseArray(meta: FieldMeta, modifier: string, order: 'before' | 'after'): void {
|
|
9
|
+
const other = order === 'before'
|
|
10
|
+
? (meta.primaryKey ? 'primaryKey' : meta.tenant ? 'tenant' : meta.defaultRandom ? 'defaultRandom'
|
|
11
|
+
: meta.kind === 'serial' ? 'serial' : meta.reference !== undefined ? 'references' : undefined)
|
|
12
|
+
: (meta.array ? 'array' : undefined)
|
|
13
|
+
if (other === undefined) return
|
|
14
|
+
throw new Error(
|
|
15
|
+
`[pipework] .${modifier}() cannot follow .${other}(): a list column cannot be a key, a tenant column, a generated id or a reference.\n\n` +
|
|
16
|
+
` Fix: keep the list in its own field without .${modifier === 'array' ? other : 'array'}(), and put the key or reference on a scalar field.\n`,
|
|
17
|
+
)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** A generated column is computed by Postgres: it takes no default, key, tenant role or reference, in either order. */
|
|
21
|
+
function refuseGenerated(meta: FieldMeta, modifier: string, order: 'before' | 'after'): void {
|
|
22
|
+
const other = order === 'before'
|
|
23
|
+
? (meta.hasDefault ? 'default' : meta.primaryKey ? 'primaryKey' : meta.tenant ? 'tenant' : meta.reference !== undefined ? 'references' : undefined)
|
|
24
|
+
: (meta.generated !== undefined ? 'generatedAlwaysAs' : undefined)
|
|
25
|
+
if (other === undefined) return
|
|
26
|
+
const [first, second] = order === 'before' ? [other, modifier] : [modifier, other]
|
|
27
|
+
throw new Error(
|
|
28
|
+
`[pipework] .${first}() and .${second}() cannot be combined on one field: a generated column is computed by Postgres and takes no default, key, tenant role or reference.\n\n` +
|
|
29
|
+
` Fix: keep the generated column in its own field, and put the default, key, tenant or reference on another field.\n`,
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function createField<TOutput = unknown, TFlags extends FieldFlags = {}>(meta: FieldMeta): FieldDescriptor<TOutput, TFlags> & FieldModifiers<TOutput, TFlags> {
|
|
34
|
+
const self: Record<string, unknown> = {
|
|
35
|
+
_meta: meta,
|
|
36
|
+
|
|
37
|
+
nullable() {
|
|
38
|
+
return createField<TOutput | null, TFlags & { nullable: true }>({ ...meta, nullable: true })
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
default(value: unknown) {
|
|
42
|
+
refuseGenerated(meta, 'default', 'after')
|
|
43
|
+
return createField<TOutput, TFlags & { hasDefault: true }>({ ...meta, hasDefault: true, defaultValue: value })
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
primaryKey() {
|
|
47
|
+
refuseArray(meta, 'primaryKey', 'after')
|
|
48
|
+
refuseGenerated(meta, 'primaryKey', 'after')
|
|
49
|
+
return createField<TOutput, TFlags & { primaryKey: true }>({ ...meta, primaryKey: true })
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
defaultRandom() {
|
|
53
|
+
refuseArray(meta, 'defaultRandom', 'after')
|
|
54
|
+
refuseGenerated(meta, 'defaultRandom', 'after')
|
|
55
|
+
return createField<TOutput, TFlags & { defaultRandom: true; hasDefault: true }>({ ...meta, defaultRandom: true, hasDefault: true })
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
unique() {
|
|
59
|
+
return createField<TOutput, TFlags>({ ...meta, unique: true })
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
readOnly() {
|
|
63
|
+
return createField<TOutput, TFlags & { readOnly: true }>({ ...meta, readOnly: true })
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
tenant() {
|
|
67
|
+
refuseArray(meta, 'tenant', 'after')
|
|
68
|
+
refuseGenerated(meta, 'tenant', 'after')
|
|
69
|
+
return createField<TOutput, TFlags & { tenant: true }>({ ...meta, tenant: true })
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
generatedAlwaysAs(as: SQL | (() => SQL)) {
|
|
73
|
+
refuseGenerated(meta, 'generatedAlwaysAs', 'before')
|
|
74
|
+
return createField<TOutput, TFlags & { generated: true }>({ ...meta, generated: { as } })
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
collate(name: CollationName) {
|
|
78
|
+
if (meta.kind !== 'text') {
|
|
79
|
+
throw new Error(
|
|
80
|
+
`[pipework] .collate() applies to text fields; this field is "${meta.kind}".\n\n` +
|
|
81
|
+
' Fix: declare the collation on a field.text() column.\n',
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
return createField<TOutput, TFlags>({ ...meta, collation: name })
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
traceSafe() {
|
|
88
|
+
return createField<TOutput, TFlags>({ ...meta, traceSafe: true })
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
brand(name: string) {
|
|
92
|
+
return createField({ ...meta, brand: name })
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
references(
|
|
96
|
+
definition: DefinedTable | (() => DefinedTable),
|
|
97
|
+
fieldName: string,
|
|
98
|
+
options?: { enforced?: boolean },
|
|
99
|
+
) {
|
|
100
|
+
refuseArray(meta, 'references', 'after')
|
|
101
|
+
refuseGenerated(meta, 'references', 'after')
|
|
102
|
+
const enforced = options?.enforced ?? true
|
|
103
|
+
// Eager form: infer brand from the referenced field at construction.
|
|
104
|
+
// Thunk form: can't resolve yet — the caller must chain .brand()
|
|
105
|
+
// explicitly. The validator still recognises brand reuse as intentional
|
|
106
|
+
// because it resolves the thunk at validation time and compares.
|
|
107
|
+
const inferredBrand = typeof definition === 'function'
|
|
108
|
+
? undefined
|
|
109
|
+
: definition.$fields[fieldName]?._meta.brand
|
|
110
|
+
return createField({
|
|
111
|
+
...meta,
|
|
112
|
+
reference: { definition, field: fieldName, ...(enforced ? {} : { enforced: false }) },
|
|
113
|
+
...(inferredBrand !== undefined && meta.brand === undefined ? { brand: inferredBrand } : {}),
|
|
114
|
+
})
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
array() {
|
|
118
|
+
if (meta.nullable) {
|
|
119
|
+
throw new Error('[pipework] .array() cannot follow .nullable(): the list may be null, its elements may not.\n\n Fix: write .array().nullable().\n')
|
|
120
|
+
}
|
|
121
|
+
refuseArray(meta, 'array', 'before')
|
|
122
|
+
return createField<readonly TOutput[], TFlags>({ ...meta, array: true })
|
|
123
|
+
},
|
|
124
|
+
|
|
125
|
+
min(value: number) {
|
|
126
|
+
return createField<TOutput, TFlags>({ ...meta, min: value })
|
|
127
|
+
},
|
|
128
|
+
|
|
129
|
+
max(value: number) {
|
|
130
|
+
return createField<TOutput, TFlags>({ ...meta, max: value })
|
|
131
|
+
},
|
|
132
|
+
|
|
133
|
+
email() {
|
|
134
|
+
return createField<TOutput, TFlags>({ ...meta, email: true })
|
|
135
|
+
},
|
|
136
|
+
|
|
137
|
+
url() {
|
|
138
|
+
return createField<TOutput, TFlags>({ ...meta, url: true })
|
|
139
|
+
},
|
|
140
|
+
|
|
141
|
+
regex(pattern: RegExp) {
|
|
142
|
+
return createField<TOutput, TFlags>({ ...meta, regex: pattern })
|
|
143
|
+
},
|
|
144
|
+
|
|
145
|
+
precision(p: number, s: number) {
|
|
146
|
+
return createField<TOutput, TFlags>({ ...meta, precision: { p, s } })
|
|
147
|
+
},
|
|
148
|
+
|
|
149
|
+
serializedAs(_format: 'string') {
|
|
150
|
+
return createField<string, TFlags>({ ...meta, serializedAs: _format })
|
|
151
|
+
},
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return self as unknown as FieldDescriptor<TOutput, TFlags> & FieldModifiers<TOutput, TFlags>
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export interface FieldModifiers<TOutput = unknown, TFlags extends FieldFlags = {}> {
|
|
158
|
+
nullable(): FieldDescriptor<TOutput | null, TFlags & { nullable: true }> & FieldModifiers<TOutput | null, TFlags & { nullable: true }>
|
|
159
|
+
default(value: unknown): FieldDescriptor<TOutput, TFlags & { hasDefault: true }> & FieldModifiers<TOutput, TFlags & { hasDefault: true }>
|
|
160
|
+
primaryKey(): FieldDescriptor<TOutput, TFlags & { primaryKey: true }> & FieldModifiers<TOutput, TFlags & { primaryKey: true }>
|
|
161
|
+
defaultRandom(): FieldDescriptor<TOutput, TFlags & { defaultRandom: true; hasDefault: true }> & FieldModifiers<TOutput, TFlags & { defaultRandom: true; hasDefault: true }>
|
|
162
|
+
unique(): FieldDescriptor<TOutput, TFlags> & FieldModifiers<TOutput, TFlags>
|
|
163
|
+
readOnly(): FieldDescriptor<TOutput, TFlags & { readOnly: true }> & FieldModifiers<TOutput, TFlags & { readOnly: true }>
|
|
164
|
+
tenant(): FieldDescriptor<TOutput, TFlags & { tenant: true }> & FieldModifiers<TOutput, TFlags & { tenant: true }>
|
|
165
|
+
/** A stored generated column: Postgres writes `GENERATED ALWAYS AS (expr) STORED`; insert and update shapes omit it, and it can be indexed and used as a conflict target. */
|
|
166
|
+
generatedAlwaysAs(as: SQL | (() => SQL)): FieldDescriptor<TOutput, TFlags & { generated: true }> & FieldModifiers<TOutput, TFlags & { generated: true }>
|
|
167
|
+
/** The column's collation (text fields only): `"col" text COLLATE "name"`; a string is one identifier (`'en_US.utf8'`), `['pg_catalog', 'C']` is schema-qualified. Changing it later alters the column's collation. */
|
|
168
|
+
collate(name: CollationName): FieldDescriptor<TOutput, TFlags> & FieldModifiers<TOutput, TFlags>
|
|
169
|
+
traceSafe(): FieldDescriptor<TOutput, TFlags> & FieldModifiers<TOutput, TFlags>
|
|
170
|
+
brand<B extends string>(name: B): FieldDescriptor<Branded<TOutput, B>, TFlags> & FieldModifiers<Branded<TOutput, B>, TFlags>
|
|
171
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- `any` avoids index-signature mismatch under exactOptionalPropertyTypes
|
|
172
|
+
references<TDef extends { readonly $fields: any }, TField extends string & keyof TDef['$fields']>(
|
|
173
|
+
definition: TDef,
|
|
174
|
+
field: TField,
|
|
175
|
+
options?: { enforced?: boolean },
|
|
176
|
+
): FieldDescriptor<InferFieldOutput<TDef['$fields'][TField]>, TFlags> & FieldModifiers<InferFieldOutput<TDef['$fields'][TField]>, TFlags>
|
|
177
|
+
/**
|
|
178
|
+
* Thunk form — defers resolution past an import cycle. Brand is NOT
|
|
179
|
+
* inferred from the referenced field (the cycle prevents it); the caller
|
|
180
|
+
* must `.brand()` the field explicitly. Existing TOutput is preserved.
|
|
181
|
+
*/
|
|
182
|
+
references(
|
|
183
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- thunk target type can't be reached without re-entering the cycle
|
|
184
|
+
definition: () => DefinedTable<any>,
|
|
185
|
+
field: string,
|
|
186
|
+
options?: { enforced?: boolean },
|
|
187
|
+
): FieldDescriptor<TOutput, TFlags> & FieldModifiers<TOutput, TFlags>
|
|
188
|
+
/** A list of this field's type: `uuid[]` / `text[]` column, validated element by element. */
|
|
189
|
+
array(): FieldDescriptor<readonly TOutput[], TFlags> & FieldModifiers<readonly TOutput[], TFlags>
|
|
190
|
+
min(value: number): FieldDescriptor<TOutput, TFlags> & FieldModifiers<TOutput, TFlags>
|
|
191
|
+
max(value: number): FieldDescriptor<TOutput, TFlags> & FieldModifiers<TOutput, TFlags>
|
|
192
|
+
email(): FieldDescriptor<TOutput, TFlags> & FieldModifiers<TOutput, TFlags>
|
|
193
|
+
url(): FieldDescriptor<TOutput, TFlags> & FieldModifiers<TOutput, TFlags>
|
|
194
|
+
regex(pattern: RegExp): FieldDescriptor<TOutput, TFlags> & FieldModifiers<TOutput, TFlags>
|
|
195
|
+
precision(p: number, s: number): FieldDescriptor<TOutput, TFlags> & FieldModifiers<TOutput, TFlags>
|
|
196
|
+
serializedAs(format: 'string'): FieldDescriptor<string, TFlags> & FieldModifiers<string, TFlags>
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function baseMeta(kind: FieldKind): FieldMeta {
|
|
200
|
+
return {
|
|
201
|
+
kind,
|
|
202
|
+
nullable: false,
|
|
203
|
+
hasDefault: false,
|
|
204
|
+
primaryKey: false,
|
|
205
|
+
defaultRandom: false,
|
|
206
|
+
unique: false,
|
|
207
|
+
readOnly: false,
|
|
208
|
+
tenant: false,
|
|
209
|
+
array: false,
|
|
210
|
+
traceSafe: false,
|
|
211
|
+
autoManaged: false,
|
|
212
|
+
email: false,
|
|
213
|
+
url: false,
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export const field = {
|
|
218
|
+
uuid(): FieldDescriptor<string, {}> & FieldModifiers<string, {}> {
|
|
219
|
+
return createField<string>(baseMeta('uuid'))
|
|
220
|
+
},
|
|
221
|
+
|
|
222
|
+
text(): FieldDescriptor<string, {}> & FieldModifiers<string, {}> {
|
|
223
|
+
return createField<string>(baseMeta('text'))
|
|
224
|
+
},
|
|
225
|
+
|
|
226
|
+
integer(): FieldDescriptor<number, {}> & FieldModifiers<number, {}> {
|
|
227
|
+
return createField<number>(baseMeta('integer'))
|
|
228
|
+
},
|
|
229
|
+
|
|
230
|
+
serial(): FieldDescriptor<number, { hasDefault: true; serial: true }> & FieldModifiers<number, { hasDefault: true; serial: true }> {
|
|
231
|
+
return createField<number, { hasDefault: true; serial: true }>({ ...baseMeta('serial'), hasDefault: true })
|
|
232
|
+
},
|
|
233
|
+
|
|
234
|
+
bigint(): FieldDescriptor<bigint, {}> & FieldModifiers<bigint, {}> {
|
|
235
|
+
return createField<bigint>(baseMeta('bigint'))
|
|
236
|
+
},
|
|
237
|
+
|
|
238
|
+
boolean(): FieldDescriptor<boolean, {}> & FieldModifiers<boolean, {}> {
|
|
239
|
+
return createField<boolean>(baseMeta('boolean'))
|
|
240
|
+
},
|
|
241
|
+
|
|
242
|
+
timestamp(): FieldDescriptor<Date, {}> & FieldModifiers<Date, {}> {
|
|
243
|
+
return createField<Date>(baseMeta('timestamp'))
|
|
244
|
+
},
|
|
245
|
+
|
|
246
|
+
date(): FieldDescriptor<string, {}> & FieldModifiers<string, {}> {
|
|
247
|
+
return createField<string>(baseMeta('date'))
|
|
248
|
+
},
|
|
249
|
+
|
|
250
|
+
enum<const V extends readonly [string, ...string[]]>(values: V): FieldDescriptor<V[number], {}> & FieldModifiers<V[number], {}> {
|
|
251
|
+
return createField<V[number]>({ ...baseMeta('enum'), enumValues: values })
|
|
252
|
+
},
|
|
253
|
+
|
|
254
|
+
jsonb<S extends z.ZodType>(shape: S): FieldDescriptor<z.infer<S>, {}> & FieldModifiers<z.infer<S>, {}> {
|
|
255
|
+
return createField<z.infer<S>>({ ...baseMeta('jsonb'), jsonbShape: shape })
|
|
256
|
+
},
|
|
257
|
+
|
|
258
|
+
decimal(): FieldDescriptor<string, {}> & FieldModifiers<string, {}> {
|
|
259
|
+
return createField<string>(baseMeta('decimal'))
|
|
260
|
+
},
|
|
261
|
+
|
|
262
|
+
money(p?: number, s?: number): FieldDescriptor<string, {}> & FieldModifiers<string, {}> {
|
|
263
|
+
const precision = { p: p ?? 18, s: s ?? 4 }
|
|
264
|
+
return createField<string>({ ...baseMeta('money'), precision })
|
|
265
|
+
},
|
|
266
|
+
|
|
267
|
+
/** PostgreSQL `pg_lsn` column — a WAL log sequence number (`'0/16B3748'`). `.default('currentWal')` emits `DEFAULT pg_current_wal_lsn()`. */
|
|
268
|
+
pgLsn(): FieldDescriptor<string, {}> & FieldModifiers<string, {}> {
|
|
269
|
+
return createField<string>(baseMeta('pgLsn'))
|
|
270
|
+
},
|
|
271
|
+
|
|
272
|
+
custom<S extends z.ZodType>(column: unknown, validator: S): FieldDescriptor<z.infer<S>, {}> & FieldModifiers<z.infer<S>, {}> {
|
|
273
|
+
return createField<z.infer<S>>({
|
|
274
|
+
...baseMeta('custom'),
|
|
275
|
+
customColumn: column,
|
|
276
|
+
customValidator: validator,
|
|
277
|
+
})
|
|
278
|
+
},
|
|
279
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { field, type FieldModifiers } from './field.js'
|
|
2
|
+
export { define, definitions, clearRegistry } from './define.js'
|
|
3
|
+
export { external, isExternal } from './external.js'
|
|
4
|
+
export { camelToSnake } from './naming.js'
|
|
5
|
+
export { resetFactoryCounter } from './build-factory.js'
|
|
6
|
+
export { appendOnlyScopeField, effectiveDatedTrait, appendOnlyVersionsTrait, auditedTrait, softDeletedTrait } from './traits.js'
|
|
7
|
+
export type { Branded, Brand, InferSelect, InferFieldOutput } from './brand.js'
|
|
8
|
+
export type { InsertProjection, SelectProjection, UpdateProjection } from './projections.js'
|
|
9
|
+
export type { FieldKind, FieldFlags, ForeignKeyAction, CompositeForeignKey, PartitionSpec,
|
|
10
|
+
FieldDescriptor, FieldRecord, FieldMeta, DomainDefinition, DefinedTable, ExternalTable, DefinitionMethods,
|
|
11
|
+
DefineOptions, FactoryBuilder, FactoryOptions, TraitDefinition,
|
|
12
|
+
FieldColumn, ProjectedColumns,
|
|
13
|
+
EffectiveDatedFields, AppendOnlyVersionsFields, AuditedFields, SoftDeletedFields } from './types.js'
|