pipework 0.251.0 → 0.252.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/dist/core/config/load.d.ts +2 -0
- package/dist/core/config/load.d.ts.map +1 -1
- package/dist/core/config/load.js +1 -0
- package/dist/core/config/load.js.map +1 -1
- package/dist/core/config/namespace.d.ts +1 -0
- package/dist/core/config/namespace.d.ts.map +1 -1
- package/dist/core/config/schema.d.ts +2 -0
- package/dist/core/config/schema.d.ts.map +1 -1
- package/dist/core/config/schema.js +1 -0
- package/dist/core/config/schema.js.map +1 -1
- package/dist/core/surface/types.d.ts +1 -0
- package/dist/core/surface/types.d.ts.map +1 -1
- package/dist/data/db/namespace.d.ts +3 -0
- package/dist/data/db/namespace.d.ts.map +1 -1
- package/dist/data/db/namespace.js +3 -0
- package/dist/data/db/namespace.js.map +1 -1
- package/dist/data/db/pool.d.ts.map +1 -1
- package/dist/data/db/pool.js +6 -1
- package/dist/data/db/pool.js.map +1 -1
- package/dist/data/db/query-label.d.ts +5 -0
- package/dist/data/db/query-label.d.ts.map +1 -0
- package/dist/data/db/query-label.js +11 -0
- package/dist/data/db/query-label.js.map +1 -0
- package/dist/data/db/query-watch.d.ts +21 -0
- package/dist/data/db/query-watch.d.ts.map +1 -0
- package/dist/data/db/query-watch.js +90 -0
- package/dist/data/db/query-watch.js.map +1 -0
- package/dist/data/query/postgres-js/driver.js +1 -1
- package/dist/data/query/postgres-js/driver.js.map +1 -1
- package/dist/data/query/postgres-js/session.d.ts +5 -1
- package/dist/data/query/postgres-js/session.d.ts.map +1 -1
- package/dist/data/query/postgres-js/session.js +16 -11
- package/dist/data/query/postgres-js/session.js.map +1 -1
- package/dist/data/query/utils.d.ts +2 -0
- package/dist/data/query/utils.d.ts.map +1 -1
- package/dist/data/query/utils.js.map +1 -1
- package/dist/infra/credits/schema.d.ts +1 -1
- package/dist/test/plugin.d.ts.map +1 -1
- package/dist/test/plugin.js +10 -4
- package/dist/test/plugin.js.map +1 -1
- package/package.json +4 -3
- package/src/async/jobs/abortable-delay.ts +18 -0
- package/src/async/jobs/claims.ts +52 -0
- package/src/async/jobs/cron.ts +179 -0
- package/src/async/jobs/errors.ts +56 -0
- package/src/async/jobs/exclusion.ts +117 -0
- package/src/async/jobs/execute.ts +219 -0
- package/src/async/jobs/index.ts +10 -0
- package/src/async/jobs/listener.ts +135 -0
- package/src/async/jobs/namespace.ts +20 -0
- package/src/async/jobs/queue-door.ts +44 -0
- package/src/async/jobs/queue.ts +1012 -0
- package/src/async/jobs/run-script.ts +67 -0
- package/src/async/jobs/scheduler.ts +218 -0
- package/src/async/jobs/schedules-table.ts +37 -0
- package/src/async/jobs/serialize-error.ts +48 -0
- package/src/async/jobs/table.ts +191 -0
- package/src/async/pipeline/define.ts +53 -0
- package/src/async/pipeline/errors.ts +35 -0
- package/src/async/pipeline/execute.ts +53 -0
- package/src/async/pipeline/index.ts +13 -0
- package/src/async/pipeline/namespace.ts +12 -0
- package/src/async/pipeline/resume.ts +67 -0
- package/src/async/pipeline/run-steps.ts +98 -0
- package/src/async/pipeline/types.ts +57 -0
- package/src/async/state-machine/define.ts +64 -0
- package/src/async/state-machine/errors.ts +29 -0
- package/src/async/state-machine/index.ts +3 -0
- package/src/async/state-machine/namespace.ts +12 -0
- package/src/async/state-machine/transition.ts +90 -0
- package/src/async/state-machine/types.ts +37 -0
- package/src/async/steps/errors.ts +31 -0
- package/src/async/steps/graph.ts +1214 -0
- package/src/async/steps/hash.ts +40 -0
- package/src/async/steps/index.ts +7 -0
- package/src/async/steps/namespace.ts +7 -0
- package/src/async/steps/table.ts +97 -0
- package/src/async/steps/types.ts +318 -0
- package/src/audit/chain/index.ts +9 -0
- package/src/audit/chain/install.ts +113 -0
- package/src/audit/chain/retire.ts +52 -0
- package/src/audit/chain/verify.ts +257 -0
- package/src/audit/query/cursor.ts +37 -0
- package/src/audit/query/index.ts +9 -0
- package/src/audit/query/query.ts +223 -0
- package/src/audit/schema/audit-record-fields.ts +68 -0
- package/src/audit/schema/audit-record.ts +23 -0
- package/src/auth/auth/audit.ts +31 -0
- package/src/auth/auth/chain.ts +84 -0
- package/src/auth/auth/cookie.ts +136 -0
- package/src/auth/auth/email-links.ts +311 -0
- package/src/auth/auth/guard.ts +128 -0
- package/src/auth/auth/index.ts +18 -0
- package/src/auth/auth/multi-org.ts +337 -0
- package/src/auth/auth/namespace.ts +34 -0
- package/src/auth/auth/parse-expiry.ts +13 -0
- package/src/auth/auth/passwords.ts +110 -0
- package/src/auth/auth/schema.ts +110 -0
- package/src/auth/auth/sessions.ts +565 -0
- package/src/auth/auth/sign-in.ts +156 -0
- package/src/auth/auth/signing-keys.ts +69 -0
- package/src/auth/auth/types.ts +26 -0
- package/src/auth/auth/uuid.ts +10 -0
- package/src/auth/rbac/cache.ts +55 -0
- package/src/auth/rbac/check.ts +30 -0
- package/src/auth/rbac/create.ts +35 -0
- package/src/auth/rbac/index.ts +5 -0
- package/src/auth/rbac/middleware.ts +20 -0
- package/src/auth/rbac/namespace.ts +15 -0
- package/src/auth/rbac/resolve.ts +31 -0
- package/src/auth/rbac/schema.sql +31 -0
- package/src/auth/rbac/seed.ts +67 -0
- package/src/auth/rbac/tables.ts +32 -0
- package/src/auth/rbac/types.ts +65 -0
- package/src/auth/tenant/extract.ts +33 -0
- package/src/auth/tenant/in-tenant.ts +49 -0
- package/src/auth/tenant/index.ts +7 -0
- package/src/auth/tenant/namespace.ts +23 -0
- package/src/auth/tenant/propagate.ts +20 -0
- package/src/auth/tenant/rls.ts +120 -0
- package/src/auth/tenant/scope.ts +33 -0
- package/src/auth/tenant/scoped-db.ts +581 -0
- package/src/auth/tenant/types.ts +14 -0
- package/src/auth/tenant/validate.ts +27 -0
- package/src/cli/commands/add.ts +158 -0
- package/src/cli/commands/alerts.ts +98 -0
- package/src/cli/commands/check.ts +1418 -0
- package/src/cli/commands/codemod.ts +78 -0
- package/src/cli/commands/db.ts +356 -0
- package/src/cli/commands/dev.ts +101 -0
- package/src/cli/commands/generate.ts +75 -0
- package/src/cli/commands/init.ts +36 -0
- package/src/cli/commands/install.ts +28 -0
- package/src/cli/commands/lint.ts +62 -0
- package/src/cli/commands/migrate.ts +132 -0
- package/src/cli/commands/openapi.ts +63 -0
- package/src/cli/commands/remove.ts +72 -0
- package/src/cli/commands/run.ts +50 -0
- package/src/cli/commands/scope.ts +54 -0
- package/src/cli/commands/serve.ts +68 -0
- package/src/cli/commands/shard.ts +31 -0
- package/src/cli/commands/shared/config-pipework-version.ts +28 -0
- package/src/cli/commands/shared/find-config.ts +22 -0
- package/src/cli/commands/shared/load-config.ts +35 -0
- package/src/cli/commands/shared/pnpm-install.ts +95 -0
- package/src/cli/commands/shared/report-removed.ts +8 -0
- package/src/cli/commands/sync.ts +32 -0
- package/src/cli/commands/test.ts +307 -0
- package/src/cli/commands/upgrade.ts +48 -0
- package/src/cli/dev-bootstrap.ts +24 -0
- package/src/cli/errors.ts +10 -0
- package/src/cli/index.ts +303 -0
- package/src/cli/output.ts +17 -0
- package/src/cli/port.ts +15 -0
- package/src/cli/surface-kinds.ts +20 -0
- package/src/client/index.ts +4 -0
- package/src/client/poll.ts +130 -0
- package/src/client/report-fault.ts +119 -0
- package/src/core/config/app-pool.ts +19 -0
- package/src/core/config/aws-env.ts +29 -0
- package/src/core/config/base-dir.ts +24 -0
- package/src/core/config/discover.ts +64 -0
- package/src/core/config/env-resolve.ts +87 -0
- package/src/core/config/env-types.ts +116 -0
- package/src/core/config/env.ts +55 -0
- package/src/core/config/errors.ts +9 -0
- package/src/core/config/import-config.ts +40 -0
- package/src/core/config/index.ts +8 -0
- package/src/core/config/load.ts +417 -0
- package/src/core/config/namespace.ts +14 -0
- package/src/core/config/resolve.ts +195 -0
- package/src/core/config/schema.ts +488 -0
- package/src/core/config/statement-observer.ts +48 -0
- package/src/core/config/ts-inline-hooks.ts +75 -0
- package/src/core/config/ts-register.ts +4 -0
- package/src/core/config/ts-resolve-hooks.ts +101 -0
- package/src/core/errors/base.ts +49 -0
- package/src/core/errors/http.ts +146 -0
- package/src/core/errors/index.ts +2 -0
- package/src/core/errors/namespace.ts +31 -0
- package/src/core/lifecycle/drain.ts +33 -0
- package/src/core/lifecycle/health.ts +72 -0
- package/src/core/lifecycle/index.ts +4 -0
- package/src/core/lifecycle/namespace.ts +7 -0
- package/src/core/lifecycle/startup.ts +102 -0
- package/src/core/lifecycle/types.ts +36 -0
- package/src/core/logging/context.ts +60 -0
- package/src/core/logging/error-chain.ts +68 -0
- package/src/core/logging/index.ts +5 -0
- package/src/core/logging/logger.ts +65 -0
- package/src/core/logging/namespace.ts +16 -0
- package/src/core/logging/proxy.ts +22 -0
- package/src/core/logging/redact-match.ts +24 -0
- package/src/core/logging/types.ts +47 -0
- package/src/core/pipework.ts +566 -0
- package/src/core/runtime/broker.ts +69 -0
- package/src/core/surface/http.ts +133 -0
- package/src/core/surface/index.ts +11 -0
- package/src/core/surface/job-timeout.ts +40 -0
- package/src/core/surface/namespace.ts +13 -0
- package/src/core/surface/script.ts +33 -0
- package/src/core/surface/start.ts +142 -0
- package/src/core/surface/types.ts +225 -0
- package/src/core/surface/validate.ts +88 -0
- package/src/core/surface/worker.ts +528 -0
- package/src/core/validation/connectivity.ts +49 -0
- package/src/core/validation/domain.ts +99 -0
- package/src/core/validation/index.ts +5 -0
- package/src/core/validation/queue-tables.ts +312 -0
- package/src/core/validation/rls-role.ts +138 -0
- package/src/core/validation/startup.ts +51 -0
- package/src/core/validation/surfaces.ts +65 -0
- package/src/core/validation/types.ts +25 -0
- package/src/data/db/advisory-lock.ts +55 -0
- package/src/data/db/aggregates.ts +172 -0
- package/src/data/db/array-elements.ts +111 -0
- package/src/data/db/bulk-set.ts +53 -0
- package/src/data/db/col/index.ts +14 -0
- package/src/data/db/composed.ts +53 -0
- package/src/data/db/db.ts +276 -0
- package/src/data/db/excluded.ts +16 -0
- package/src/data/db/expressions.ts +473 -0
- package/src/data/db/filter.ts +90 -0
- package/src/data/db/function-source.ts +114 -0
- package/src/data/db/identifiers.ts +16 -0
- package/src/data/db/idx/index.ts +9 -0
- package/src/data/db/in-list.ts +49 -0
- package/src/data/db/index.ts +9 -0
- package/src/data/db/insert-split.ts +137 -0
- package/src/data/db/instrumentation.ts +82 -0
- package/src/data/db/maintenance.ts +28 -0
- package/src/data/db/namespace.ts +107 -0
- package/src/data/db/owner-labels.ts +9 -0
- package/src/data/db/pool.ts +187 -0
- package/src/data/db/query-label.ts +13 -0
- package/src/data/db/query-watch.ts +116 -0
- package/src/data/db/raw-client-warning.ts +37 -0
- package/src/data/db/readonly.ts +23 -0
- package/src/data/db/reservation.ts +151 -0
- package/src/data/db/schema-features.ts +14 -0
- package/src/data/db/serializable.ts +83 -0
- package/src/data/db/sql.ts +1 -0
- package/src/data/db/timeouts.ts +76 -0
- package/src/data/db/types.ts +18 -0
- package/src/data/db/unbound.ts +33 -0
- package/src/data/db/values.ts +29 -0
- package/src/data/domain/brand.ts +15 -0
- package/src/data/domain/build-factory.ts +193 -0
- package/src/data/domain/build-schema.ts +161 -0
- package/src/data/domain/build-table.ts +355 -0
- package/src/data/domain/define.ts +239 -0
- package/src/data/domain/external-registry.ts +34 -0
- package/src/data/domain/external.ts +77 -0
- package/src/data/domain/field.ts +279 -0
- package/src/data/domain/index.ts +13 -0
- package/src/data/domain/naming.ts +6 -0
- package/src/data/domain/projections.ts +57 -0
- package/src/data/domain/trace-safe-projection.ts +31 -0
- package/src/data/domain/traits.ts +108 -0
- package/src/data/domain/types.ts +289 -0
- package/src/data/jsonb/composed.ts +18 -0
- package/src/data/jsonb/index.ts +1 -0
- package/src/data/jsonb/namespace.ts +30 -0
- package/src/data/jsonb/query.ts +86 -0
- package/src/data/migrate/append-only-generate.ts +47 -0
- package/src/data/migrate/applied.ts +47 -0
- package/src/data/migrate/apply.ts +309 -0
- package/src/data/migrate/check.ts +119 -0
- package/src/data/migrate/diff.ts +357 -0
- package/src/data/migrate/door-generate.ts +130 -0
- package/src/data/migrate/framework-rls.ts +58 -0
- package/src/data/migrate/generate.ts +201 -0
- package/src/data/migrate/history.ts +215 -0
- package/src/data/migrate/index.ts +9 -0
- package/src/data/migrate/internal-definitions.ts +175 -0
- package/src/data/migrate/post-process.ts +73 -0
- package/src/data/migrate/pragma.ts +73 -0
- package/src/data/migrate/provision-framework.ts +147 -0
- package/src/data/migrate/rls-generate.ts +61 -0
- package/src/data/migrate/run.ts +124 -0
- package/src/data/migrate/safety.ts +167 -0
- package/src/data/migrate/snapshot.ts +368 -0
- package/src/data/migrate/sql-emit.ts +392 -0
- package/src/data/migrate/statements.ts +312 -0
- package/src/data/query/alias.ts +126 -0
- package/src/data/query/batch.ts +8 -0
- package/src/data/query/cache/core/cache.ts +78 -0
- package/src/data/query/cache/core/index.ts +1 -0
- package/src/data/query/cache/core/types.ts +29 -0
- package/src/data/query/cache/readme.md +230 -0
- package/src/data/query/casing.ts +76 -0
- package/src/data/query/collation.ts +11 -0
- package/src/data/query/column-builder.ts +370 -0
- package/src/data/query/column.ts +150 -0
- package/src/data/query/entity.ts +42 -0
- package/src/data/query/errors.ts +33 -0
- package/src/data/query/index.ts +14 -0
- package/src/data/query/logger.ts +47 -0
- package/src/data/query/operations.ts +45 -0
- package/src/data/query/pg-core/alias.ts +12 -0
- package/src/data/query/pg-core/checks.ts +32 -0
- package/src/data/query/pg-core/columns/all.ts +71 -0
- package/src/data/query/pg-core/columns/bigint.ts +110 -0
- package/src/data/query/pg-core/columns/bigserial.ts +128 -0
- package/src/data/query/pg-core/columns/boolean.ts +43 -0
- package/src/data/query/pg-core/columns/char.ts +85 -0
- package/src/data/query/pg-core/columns/cidr.ts +43 -0
- package/src/data/query/pg-core/columns/common.ts +366 -0
- package/src/data/query/pg-core/columns/custom.ts +232 -0
- package/src/data/query/pg-core/columns/date.common.ts +15 -0
- package/src/data/query/pg-core/columns/date.ts +112 -0
- package/src/data/query/pg-core/columns/double-precision.ts +55 -0
- package/src/data/query/pg-core/columns/enum.ts +201 -0
- package/src/data/query/pg-core/columns/index.ts +35 -0
- package/src/data/query/pg-core/columns/inet.ts +43 -0
- package/src/data/query/pg-core/columns/int.common.ts +57 -0
- package/src/data/query/pg-core/columns/integer.ts +53 -0
- package/src/data/query/pg-core/columns/interval.ts +83 -0
- package/src/data/query/pg-core/columns/json.ts +58 -0
- package/src/data/query/pg-core/columns/jsonb.ts +56 -0
- package/src/data/query/pg-core/columns/line.ts +117 -0
- package/src/data/query/pg-core/columns/macaddr.ts +43 -0
- package/src/data/query/pg-core/columns/macaddr8.ts +43 -0
- package/src/data/query/pg-core/columns/numeric.ts +227 -0
- package/src/data/query/pg-core/columns/point.ts +127 -0
- package/src/data/query/pg-core/columns/postgis_extension/geometry.ts +119 -0
- package/src/data/query/pg-core/columns/postgis_extension/utils.ts +47 -0
- package/src/data/query/pg-core/columns/real.ts +58 -0
- package/src/data/query/pg-core/columns/serial.ts +55 -0
- package/src/data/query/pg-core/columns/smallint.ts +53 -0
- package/src/data/query/pg-core/columns/smallserial.ts +60 -0
- package/src/data/query/pg-core/columns/text.ts +67 -0
- package/src/data/query/pg-core/columns/time.ts +72 -0
- package/src/data/query/pg-core/columns/timestamp.ts +163 -0
- package/src/data/query/pg-core/columns/uuid.ts +51 -0
- package/src/data/query/pg-core/columns/varchar.ts +89 -0
- package/src/data/query/pg-core/columns/vector_extension/bit.ts +68 -0
- package/src/data/query/pg-core/columns/vector_extension/halfvec.ts +80 -0
- package/src/data/query/pg-core/columns/vector_extension/sparsevec.ts +67 -0
- package/src/data/query/pg-core/columns/vector_extension/vector.ts +80 -0
- package/src/data/query/pg-core/db.ts +674 -0
- package/src/data/query/pg-core/dialect.ts +1404 -0
- package/src/data/query/pg-core/expressions.ts +25 -0
- package/src/data/query/pg-core/foreign-keys.ts +130 -0
- package/src/data/query/pg-core/index.ts +21 -0
- package/src/data/query/pg-core/indexes.ts +276 -0
- package/src/data/query/pg-core/policies.ts +56 -0
- package/src/data/query/pg-core/primary-keys.ts +62 -0
- package/src/data/query/pg-core/query-builders/count.ts +86 -0
- package/src/data/query/pg-core/query-builders/delete.ts +293 -0
- package/src/data/query/pg-core/query-builders/index.ts +7 -0
- package/src/data/query/pg-core/query-builders/insert.ts +452 -0
- package/src/data/query/pg-core/query-builders/query-builder.ts +123 -0
- package/src/data/query/pg-core/query-builders/query.ts +157 -0
- package/src/data/query/pg-core/query-builders/raw.ts +49 -0
- package/src/data/query/pg-core/query-builders/refresh-materialized-view.ts +108 -0
- package/src/data/query/pg-core/query-builders/select.ts +1346 -0
- package/src/data/query/pg-core/query-builders/select.types.ts +437 -0
- package/src/data/query/pg-core/query-builders/update.ts +626 -0
- package/src/data/query/pg-core/roles.ts +41 -0
- package/src/data/query/pg-core/schema.ts +72 -0
- package/src/data/query/pg-core/sequence.ts +41 -0
- package/src/data/query/pg-core/session.ts +292 -0
- package/src/data/query/pg-core/subquery.ts +46 -0
- package/src/data/query/pg-core/table.ts +252 -0
- package/src/data/query/pg-core/unique-constraint.ts +73 -0
- package/src/data/query/pg-core/utils/array.ts +95 -0
- package/src/data/query/pg-core/utils/index.ts +1 -0
- package/src/data/query/pg-core/utils.ts +104 -0
- package/src/data/query/pg-core/view-base.ts +14 -0
- package/src/data/query/pg-core/view-common.ts +1 -0
- package/src/data/query/pg-core/view.ts +435 -0
- package/src/data/query/pg-core/with-builder.ts +41 -0
- package/src/data/query/postgres-js/README.md +46 -0
- package/src/data/query/postgres-js/array-parser.ts +45 -0
- package/src/data/query/postgres-js/driver-error-boundary.ts +149 -0
- package/src/data/query/postgres-js/driver.ts +163 -0
- package/src/data/query/postgres-js/index.ts +2 -0
- package/src/data/query/postgres-js/session.ts +234 -0
- package/src/data/query/primary-key.ts +11 -0
- package/src/data/query/query-builders/query-builder.ts +19 -0
- package/src/data/query/query-builders/select.types.ts +175 -0
- package/src/data/query/query-promise.ts +35 -0
- package/src/data/query/relations.ts +725 -0
- package/src/data/query/runnable-query.ts +12 -0
- package/src/data/query/selection-proxy.ts +121 -0
- package/src/data/query/session.ts +8 -0
- package/src/data/query/sql/expressions/conditions.ts +741 -0
- package/src/data/query/sql/expressions/index.ts +2 -0
- package/src/data/query/sql/expressions/select.ts +45 -0
- package/src/data/query/sql/functions/aggregate.ts +129 -0
- package/src/data/query/sql/functions/index.ts +2 -0
- package/src/data/query/sql/functions/vector.ts +178 -0
- package/src/data/query/sql/index.ts +3 -0
- package/src/data/query/sql/sql.ts +794 -0
- package/src/data/query/subquery.ts +53 -0
- package/src/data/query/table.ts +208 -0
- package/src/data/query/table.utils.ts +2 -0
- package/src/data/query/tracing-utils.ts +3 -0
- package/src/data/query/tracing.ts +11 -0
- package/src/data/query/utils.ts +357 -0
- package/src/data/query/version.ts +4 -0
- package/src/data/query/view-common.ts +1 -0
- package/src/data/schema/branded.ts +13 -0
- package/src/data/schema/generated/coerce.ts +5 -0
- package/src/data/schema/generated/combinator.ts +6 -0
- package/src/data/schema/generated/encoding.ts +5 -0
- package/src/data/schema/generated/error.ts +6 -0
- package/src/data/schema/generated/format.ts +5 -0
- package/src/data/schema/generated/type-constructor.ts +10 -0
- package/src/data/schema/generated/type.ts +6 -0
- package/src/data/schema/index.ts +6 -0
- package/src/data/schema/json-schema.ts +33 -0
- package/src/data/schema/namespace.ts +55 -0
- package/src/data/schema/parse.ts +39 -0
- package/src/data/schema/types.ts +39 -0
- package/src/data/temporal/append-only.ts +134 -0
- package/src/data/temporal/close.ts +27 -0
- package/src/data/temporal/columns.ts +10 -0
- package/src/data/temporal/definition-queries.ts +70 -0
- package/src/data/temporal/errors.ts +10 -0
- package/src/data/temporal/get-current.ts +22 -0
- package/src/data/temporal/index.ts +9 -0
- package/src/data/temporal/namespace.ts +36 -0
- package/src/data/temporal/query.ts +25 -0
- package/src/data/temporal/resolve.ts +17 -0
- package/src/data/temporal/revise.ts +67 -0
- package/src/data/temporal/types.ts +22 -0
- package/src/data/valve/artifact.ts +33 -0
- package/src/data/valve/contract-diff.ts +21 -0
- package/src/data/valve/cross.ts +57 -0
- package/src/data/valve/crossing-ledger.ts +50 -0
- package/src/data/valve/decision.ts +44 -0
- package/src/data/valve/durable-crossing.ts +52 -0
- package/src/data/valve/execute-crossing.ts +77 -0
- package/src/data/valve/faucet.ts +56 -0
- package/src/data/valve/gate.ts +114 -0
- package/src/data/valve/graph.ts +77 -0
- package/src/data/valve/index.ts +53 -0
- package/src/data/valve/namespace.ts +57 -0
- package/src/data/valve/registry.ts +50 -0
- package/src/data/valve/schema/valve-crossing-fields.ts +23 -0
- package/src/data/valve/schema/valve-crossing.ts +9 -0
- package/src/data/valve/supply.ts +154 -0
- package/src/data/valve/types.ts +143 -0
- package/src/data/vector/columns.ts +27 -0
- package/src/data/vector/index.ts +4 -0
- package/src/data/vector/namespace.ts +33 -0
- package/src/data/vector/query.ts +85 -0
- package/src/data/vector/validate.ts +16 -0
- package/src/data/write/audit/actor.ts +15 -0
- package/src/data/write/audit/audit-columns.ts +18 -0
- package/src/data/write/audit/audit-select.ts +111 -0
- package/src/data/write/audit/bound-transaction.ts +14 -0
- package/src/data/write/audit/cte-compile.ts +32 -0
- package/src/data/write/audit/decode-returning.ts +47 -0
- package/src/data/write/audit/final-select.ts +43 -0
- package/src/data/write/audit/infra-audit.ts +36 -0
- package/src/data/write/audit/primary-key.ts +65 -0
- package/src/data/write/audit/projection.ts +41 -0
- package/src/data/write/audit/read-touches.ts +86 -0
- package/src/data/write/audit/touch-match.ts +78 -0
- package/src/data/write/audit/verb-delete.ts +62 -0
- package/src/data/write/audit/verb-insert.ts +36 -0
- package/src/data/write/audit/verb-select.ts +47 -0
- package/src/data/write/audit/verb-update.ts +60 -0
- package/src/data/write/audit/verb-upsert.ts +104 -0
- package/src/data/write/conflict.ts +43 -0
- package/src/data/write/delete.ts +38 -0
- package/src/data/write/execute.ts +243 -0
- package/src/data/write/index.ts +11 -0
- package/src/data/write/insert.ts +63 -0
- package/src/data/write/state.ts +43 -0
- package/src/data/write/update.ts +54 -0
- package/src/data/write/upsert.ts +58 -0
- package/src/data/write/values.ts +19 -0
- package/src/index.ts +230 -0
- package/src/infra/access-links/code.ts +70 -0
- package/src/infra/access-links/handle.ts +892 -0
- package/src/infra/access-links/index.ts +9 -0
- package/src/infra/access-links/namespace.ts +30 -0
- package/src/infra/access-links/person-check.ts +177 -0
- package/src/infra/access-links/schema.ts +71 -0
- package/src/infra/alerts/async-sources.ts +231 -0
- package/src/infra/alerts/audit.ts +36 -0
- package/src/infra/alerts/beat.ts +123 -0
- package/src/infra/alerts/client-faults.ts +111 -0
- package/src/infra/alerts/faults.ts +156 -0
- package/src/infra/alerts/handle.ts +778 -0
- package/src/infra/alerts/http.ts +192 -0
- package/src/infra/alerts/index.ts +12 -0
- package/src/infra/alerts/infra-sources.ts +180 -0
- package/src/infra/alerts/namespace.ts +81 -0
- package/src/infra/alerts/redact.ts +21 -0
- package/src/infra/alerts/request-faults.ts +41 -0
- package/src/infra/alerts/schema.ts +124 -0
- package/src/infra/alerts/sinks.ts +125 -0
- package/src/infra/alerts/source-options.ts +26 -0
- package/src/infra/alerts/sources.ts +503 -0
- package/src/infra/alerts/subsystem-sources.ts +137 -0
- package/src/infra/audit/emit.ts +87 -0
- package/src/infra/audit/index.ts +2 -0
- package/src/infra/audit/namespace.ts +22 -0
- package/src/infra/audit/schema.sql +35 -0
- package/src/infra/audit/types.ts +18 -0
- package/src/infra/aws/credentials.ts +147 -0
- package/src/infra/aws/sigv4.ts +140 -0
- package/src/infra/cache/create.ts +58 -0
- package/src/infra/cache/entry.ts +81 -0
- package/src/infra/cache/index.ts +4 -0
- package/src/infra/cache/namespace.ts +10 -0
- package/src/infra/cache/tenant.ts +93 -0
- package/src/infra/cache/types.ts +24 -0
- package/src/infra/crawl/audit.ts +35 -0
- package/src/infra/crawl/errors.ts +25 -0
- package/src/infra/crawl/handle.ts +693 -0
- package/src/infra/crawl/index.ts +9 -0
- package/src/infra/crawl/links.ts +160 -0
- package/src/infra/crawl/namespace.ts +36 -0
- package/src/infra/crawl/robots.ts +100 -0
- package/src/infra/crawl/schema.ts +89 -0
- package/src/infra/credit-line/handle.ts +883 -0
- package/src/infra/credit-line/index.ts +6 -0
- package/src/infra/credit-line/namespace.ts +7 -0
- package/src/infra/credit-line/schema.ts +96 -0
- package/src/infra/credits/handle.ts +706 -0
- package/src/infra/credits/index.ts +5 -0
- package/src/infra/credits/namespace.ts +7 -0
- package/src/infra/credits/schema.ts +83 -0
- package/src/infra/email/audit.ts +36 -0
- package/src/infra/email/inbound.ts +622 -0
- package/src/infra/email/index.ts +11 -0
- package/src/infra/email/mail.ts +517 -0
- package/src/infra/email/mime.ts +447 -0
- package/src/infra/email/namespace.ts +22 -0
- package/src/infra/email/providers.ts +111 -0
- package/src/infra/email/schema.ts +96 -0
- package/src/infra/email/sns.ts +200 -0
- package/src/infra/email/unsubscribe.ts +44 -0
- package/src/infra/fetch/address.ts +88 -0
- package/src/infra/fetch/connect-retry.ts +87 -0
- package/src/infra/fetch/handle.ts +329 -0
- package/src/infra/fetch/index.ts +7 -0
- package/src/infra/fetch/namespace.ts +70 -0
- package/src/infra/idempotency/index.ts +3 -0
- package/src/infra/idempotency/middleware.ts +87 -0
- package/src/infra/idempotency/store.ts +92 -0
- package/src/infra/idempotency/types.ts +30 -0
- package/src/infra/join-requests/handle.ts +312 -0
- package/src/infra/join-requests/index.ts +2 -0
- package/src/infra/join-requests/namespace.ts +7 -0
- package/src/infra/join-requests/schema.ts +33 -0
- package/src/infra/outbox/core.ts +165 -0
- package/src/infra/quota/errors.ts +32 -0
- package/src/infra/quota/handle.ts +215 -0
- package/src/infra/quota/index.ts +5 -0
- package/src/infra/quota/namespace.ts +7 -0
- package/src/infra/quota/schema.ts +15 -0
- package/src/infra/storage/backend.ts +34 -0
- package/src/infra/storage/handle.ts +513 -0
- package/src/infra/storage/index.ts +9 -0
- package/src/infra/storage/local.ts +104 -0
- package/src/infra/storage/namespace.ts +13 -0
- package/src/infra/storage/s3.ts +257 -0
- package/src/infra/storage/schema.ts +24 -0
- package/src/infra/support/handle.ts +854 -0
- package/src/infra/support/http.ts +229 -0
- package/src/infra/support/index.ts +7 -0
- package/src/infra/support/namespace.ts +12 -0
- package/src/infra/support/schema.ts +96 -0
- package/src/infra/webhook/inbound.ts +45 -0
- package/src/infra/webhook/index.ts +5 -0
- package/src/infra/webhook/namespace.ts +24 -0
- package/src/infra/webhook/outbound.ts +315 -0
- package/src/infra/webhook/sign.ts +32 -0
- package/src/infra/webhook/verify.ts +82 -0
- package/src/invariants/assert.ts +26 -0
- package/src/invariants/index.ts +1 -0
- package/src/lint/config.ts +56 -0
- package/src/lint/doctrine.ts +163 -0
- package/src/lint/include.ts +97 -0
- package/src/lint/index.ts +3 -0
- package/src/lint/preset.ts +10 -0
- package/src/lint/resolver.ts +218 -0
- package/src/lint/rules/no-reexports.ts +46 -0
- package/src/request/behavior/audited.ts +85 -0
- package/src/request/behavior/cached.ts +62 -0
- package/src/request/behavior/compose.ts +28 -0
- package/src/request/behavior/index.ts +5 -0
- package/src/request/behavior/namespace.ts +16 -0
- package/src/request/behavior/types.ts +26 -0
- package/src/request/behavior/versioned.ts +54 -0
- package/src/request/context/create.ts +103 -0
- package/src/request/context/guard.ts +49 -0
- package/src/request/context/index.ts +4 -0
- package/src/request/context/run-in-transaction.ts +200 -0
- package/src/request/context/store.ts +28 -0
- package/src/request/context/types.ts +50 -0
- package/src/request/di/builder.ts +535 -0
- package/src/request/di/index.ts +8 -0
- package/src/request/di/resolve.ts +271 -0
- package/src/request/di/types.ts +262 -0
- package/src/request/fitting/namespace.ts +7 -0
- package/src/request/fixture/batch.ts +71 -0
- package/src/request/fixture/builder.ts +26 -0
- package/src/request/fixture/errors.ts +10 -0
- package/src/request/fixture/index.ts +8 -0
- package/src/request/fixture/namespace.ts +23 -0
- package/src/request/fixture/paginate.ts +44 -0
- package/src/request/fixture/to-handlers.ts +260 -0
- package/src/request/fixture/types.ts +79 -0
- package/src/request/flow/act-as.ts +78 -0
- package/src/request/flow/namespace.ts +17 -0
- package/src/request/http/error-step.ts +42 -0
- package/src/request/http/file.ts +141 -0
- package/src/request/http/index.ts +4 -0
- package/src/request/http/middleware.ts +141 -0
- package/src/request/http/namespace.ts +5 -0
- package/src/request/http/rate-limit-classes.ts +170 -0
- package/src/request/http/response.ts +82 -0
- package/src/request/http/server.ts +916 -0
- package/src/request/http/sniff.ts +261 -0
- package/src/request/http/types.ts +250 -0
- package/src/request/http/upload.ts +284 -0
- package/src/request/internal/text.ts +6 -0
- package/src/request/openapi/generate.ts +205 -0
- package/src/request/openapi/index.ts +2 -0
- package/src/request/openapi/namespace.ts +7 -0
- package/src/test/auth.ts +13 -0
- package/src/test/auto-setup.ts +45 -0
- package/src/test/context.ts +91 -0
- package/src/test/crawl-fixture.ts +157 -0
- package/src/test/discover-fork.ts +17 -0
- package/src/test/fingerprint.ts +135 -0
- package/src/test/globals.d.ts +7 -0
- package/src/test/index.ts +19 -0
- package/src/test/namespace.ts +87 -0
- package/src/test/plugin.ts +189 -0
- package/src/test/progress.ts +185 -0
- package/src/test/reap-after-run.ts +28 -0
- package/src/test/reap.ts +286 -0
- package/src/test/reset.ts +253 -0
- package/src/test/savepoints.ts +172 -0
- package/src/test/setup.ts +1422 -0
- package/src/test/system-channel.ts +50 -0
- package/src/test/vitest-plugin.ts +142 -0
- package/src/test/vitest-workspace.ts +507 -0
- package/src/test/vitest.ts +333 -0
- package/src/test/watch.ts +105 -0
- package/src/trace/capture/bounded-serializer.ts +146 -0
- package/src/trace/cardinality/analyze.ts +173 -0
- package/src/trace/cardinality/branch-context.ts +214 -0
- package/src/trace/cardinality/check.ts +33 -0
- package/src/trace/cardinality/classify-edge.ts +64 -0
- package/src/trace/cardinality/structural-max.ts +107 -0
- package/src/trace/check/coverage-check.ts +188 -0
- package/src/trace/check/flow-check.ts +103 -0
- package/src/trace/check/flow-step-site.ts +234 -0
- package/src/trace/check/io-pattern.ts +116 -0
- package/src/trace/codemod/add-cardinality.ts +152 -0
- package/src/trace/codemod/run.ts +80 -0
- package/src/trace/entry/child-trace.ts +21 -0
- package/src/trace/entry/close-trace.ts +87 -0
- package/src/trace/entry/finalize-trace.ts +28 -0
- package/src/trace/entry/open-trace.ts +138 -0
- package/src/trace/entry/parent-trace.ts +20 -0
- package/src/trace/entry/parse-traceparent.ts +39 -0
- package/src/trace/entry/process-start.ts +38 -0
- package/src/trace/entry/trace-context.ts +26 -0
- package/src/trace/entry/tracing-enabled.ts +10 -0
- package/src/trace/external/record.ts +195 -0
- package/src/trace/external/report.ts +66 -0
- package/src/trace/namespace.ts +19 -0
- package/src/trace/partition/day.ts +47 -0
- package/src/trace/partition/index.ts +14 -0
- package/src/trace/partition/partition-name.ts +23 -0
- package/src/trace/partition/plan.ts +82 -0
- package/src/trace/partition/schedule.ts +26 -0
- package/src/trace/partition/startup-hook.ts +39 -0
- package/src/trace/partition/sync.ts +154 -0
- package/src/trace/partition/tables.ts +53 -0
- package/src/trace/read/tree.ts +83 -0
- package/src/trace/retain/copy-on-error.ts +76 -0
- package/src/trace/runtime/expire-stale-traces.ts +54 -0
- package/src/trace/runtime/flow-step.ts +147 -0
- package/src/trace/runtime/flush-steps.ts +31 -0
- package/src/trace/runtime/pending-writes.ts +54 -0
- package/src/trace/runtime/step-buffer.ts +298 -0
- package/src/trace/runtime/step-error.ts +21 -0
- package/src/trace/runtime/step-meta.ts +55 -0
- package/src/trace/runtime/thenable.ts +12 -0
- package/src/trace/runtime/truncate-trace.ts +62 -0
- package/src/trace/schema/trace-fields.ts +52 -0
- package/src/trace/schema/trace-retained.ts +22 -0
- package/src/trace/schema/trace-step-fields.ts +44 -0
- package/src/trace/schema/trace-step-retained.ts +25 -0
- package/src/trace/schema/trace-step.ts +18 -0
- package/src/trace/schema/trace.ts +12 -0
- package/src/trace/transformer/apply.ts +79 -0
- package/src/trace/transformer/build-meta-literal.ts +30 -0
- package/src/trace/transformer/find-flow-step-sites.ts +85 -0
- package/src/trace/transformer/inject-flow-step-import.ts +39 -0
- package/src/trace/transformer/transform-error.ts +14 -0
- package/src/trace/transformer/transform-flow-steps.ts +123 -0
- package/src/trace/transformer/wrap-function-declaration.ts +62 -0
- package/src/trace/transformer/wrap-variable-declaration.ts +67 -0
- package/src/workspace/affected.ts +110 -0
- package/src/workspace/changed-files.ts +163 -0
- package/src/workspace/check-deps.ts +213 -0
- package/src/workspace/checksum.ts +20 -0
- package/src/workspace/dependency-graph.ts +67 -0
- package/src/workspace/detect-pipework-copies.ts +93 -0
- package/src/workspace/discover.ts +206 -0
- package/src/workspace/generate.ts +401 -0
- package/src/workspace/index.ts +7 -0
- package/src/workspace/module-imports-pipework.ts +39 -0
- package/src/workspace/module-package-name.ts +12 -0
- package/src/workspace/scrub-git-env.ts +23 -0
- package/src/workspace/source-paths.ts +36 -0
- package/src/workspace/sync.ts +182 -0
- package/dist/REFERENCE.md +0 -1477
- package/dist/infra/access-links/rate-limit.d.ts +0 -10
- package/dist/infra/access-links/rate-limit.d.ts.map +0 -1
- package/dist/infra/access-links/rate-limit.js +0 -28
- package/dist/infra/access-links/rate-limit.js.map +0 -1
- package/dist/infra/email/sigv4.d.ts +0 -24
- package/dist/infra/email/sigv4.d.ts.map +0 -1
- package/dist/infra/email/sigv4.js +0 -55
- package/dist/infra/email/sigv4.js.map +0 -1
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type postgres from 'postgres'
|
|
2
|
+
import { drizzle, type PostgresJsDatabase } from '../data/query/postgres-js/index.js'
|
|
3
|
+
|
|
4
|
+
/** The setting the test-only policy `pipework_test_system` reads. */
|
|
5
|
+
export const TEST_SYSTEM_SETTING = 'pipework.test_system'
|
|
6
|
+
|
|
7
|
+
/** The setting a door's generated policy reads. */
|
|
8
|
+
export const DOOR_SETTING = 'pipework.door'
|
|
9
|
+
|
|
10
|
+
const ON = `SELECT set_config('${TEST_SYSTEM_SETTING}', 'on', true)`
|
|
11
|
+
const OFF = `SELECT set_config('${TEST_SYSTEM_SETTING}', 'off', true)`
|
|
12
|
+
const quoted = (value: string): string => `'${value.replace(/'/g, "''")}'`
|
|
13
|
+
const noop = (): void => {}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A handle over the test's own connection whose every statement runs with the
|
|
17
|
+
* test-only escape policy open: the statement is sent between two
|
|
18
|
+
* `set_config` queries enqueued in the same tick, so on this single
|
|
19
|
+
* connection no other query can land between them. The escape is never left
|
|
20
|
+
* on for a span of time. A statement that fails leaves the transaction
|
|
21
|
+
* aborted; the closing query then fails too, and its failure is swallowed.
|
|
22
|
+
*/
|
|
23
|
+
export function createSystemHandle(client: postgres.Sql, door?: string): PostgresJsDatabase {
|
|
24
|
+
// A door's statement also names the door, so the door policy is open too
|
|
25
|
+
// wherever the connection's role is the platform role.
|
|
26
|
+
const on = door === undefined ? ON : `${ON}, set_config('${DOOR_SETTING}', ${quoted(door)}, true)`
|
|
27
|
+
const off = door === undefined ? OFF : `${OFF}, set_config('${DOOR_SETTING}', '', true)`
|
|
28
|
+
const bracketed = new Proxy(client, {
|
|
29
|
+
get(target, prop, receiver) {
|
|
30
|
+
if (prop !== 'unsafe') return Reflect.get(target, prop, receiver)
|
|
31
|
+
// Read at call time: the connection's `unsafe` is patched after this handle is built.
|
|
32
|
+
const send = (target as { unsafe: (...args: unknown[]) => unknown }).unsafe.bind(target)
|
|
33
|
+
return (query: string, params?: unknown[], ...rest: unknown[]): unknown => {
|
|
34
|
+
const middle = send(query, params, ...rest) as { handle(): Promise<void>; executed: boolean }
|
|
35
|
+
const start = middle.handle
|
|
36
|
+
middle.handle = function (this: typeof middle): Promise<void> {
|
|
37
|
+
if (this.executed) return Promise.resolve()
|
|
38
|
+
const open = send(on) as { execute(): { catch(f: () => void): unknown } }
|
|
39
|
+
open.execute().catch(noop)
|
|
40
|
+
const result = start.call(this)
|
|
41
|
+
const close = send(off) as { execute(): { catch(f: () => void): unknown } }
|
|
42
|
+
close.execute().catch(noop)
|
|
43
|
+
return result
|
|
44
|
+
}
|
|
45
|
+
return middle
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
})
|
|
49
|
+
return drizzle(bracketed)
|
|
50
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs'
|
|
2
|
+
import { isAbsolute, sep } from 'node:path'
|
|
3
|
+
import { fileURLToPath } from 'node:url'
|
|
4
|
+
import type { Plugin } from 'vitest/config'
|
|
5
|
+
|
|
6
|
+
import { applyFlowStepTransform } from '../trace/transformer/apply.js'
|
|
7
|
+
|
|
8
|
+
export interface PipeworkVitestOptions {
|
|
9
|
+
globals?: boolean
|
|
10
|
+
isolate?: boolean
|
|
11
|
+
/** Set to `false` to skip auto-setup (manifold discovery, DB provisioning, per-test isolation). Use this for pure unit test configs that never call `pipe()` or `withFlow()`. */
|
|
12
|
+
database?: boolean
|
|
13
|
+
/**
|
|
14
|
+
* Absolute path to the project (package) root. When set, any module that
|
|
15
|
+
* Vite would resolve to `<root>/dist/*.js` is rewritten to its `<root>/src/*.ts`
|
|
16
|
+
* (or `.tsx`) source so `vi.mock` matches the file handlers actually import
|
|
17
|
+
* — without this, a built workspace package gets split into two module
|
|
18
|
+
* identities (dist + src), and mock interception silently fails. Issue #274.
|
|
19
|
+
*/
|
|
20
|
+
packageRoot?: string
|
|
21
|
+
/**
|
|
22
|
+
* Map of bare cross-package workspace specifier → absolute source file.
|
|
23
|
+
* vitest does not honour tsconfig `paths`, so an import of `@scope/pkg` (or
|
|
24
|
+
* one of its export subpaths) resolves through the package's `exports` field
|
|
25
|
+
* to `dist/`, which is not built during `pipework test`. This routes those
|
|
26
|
+
* specifiers to `src/` instead. Issue #301.
|
|
27
|
+
*
|
|
28
|
+
* A wildcard export subpath contributes a single `*` entry — key and value
|
|
29
|
+
* both contain one `*` (e.g. `@scope/pkg/events/*` → `<abs>/pkg/src/events/*.ts`).
|
|
30
|
+
* The resolver substitutes the matched segment into the value. Issue #311.
|
|
31
|
+
*/
|
|
32
|
+
workspacePackages?: Record<string, string>
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* A wildcard workspace entry split at its single `*`: a specifier matches when
|
|
37
|
+
* it starts with `prefix` and ends with `suffix`, and the segment between them
|
|
38
|
+
* is substituted into the value at `valuePrefix`/`valueSuffix`. Issue #311.
|
|
39
|
+
*/
|
|
40
|
+
interface WildcardPackage {
|
|
41
|
+
prefix: string
|
|
42
|
+
suffix: string
|
|
43
|
+
valuePrefix: string
|
|
44
|
+
valueSuffix: string
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function splitWorkspacePackages(workspacePackages: Record<string, string>): {
|
|
48
|
+
exact: Record<string, string>
|
|
49
|
+
wildcard: WildcardPackage[]
|
|
50
|
+
} {
|
|
51
|
+
const exact: Record<string, string> = {}
|
|
52
|
+
const wildcard: WildcardPackage[] = []
|
|
53
|
+
for (const [specifier, value] of Object.entries(workspacePackages)) {
|
|
54
|
+
const star = specifier.indexOf('*')
|
|
55
|
+
const valueStar = value.indexOf('*')
|
|
56
|
+
// A wildcard specifier must map to a wildcard value — otherwise every
|
|
57
|
+
// matched subpath would collapse onto one file. Treat a mismatched entry
|
|
58
|
+
// as exact so a malformed map degrades to a miss rather than misresolving.
|
|
59
|
+
if (star === -1 || valueStar === -1) {
|
|
60
|
+
exact[specifier] = value
|
|
61
|
+
continue
|
|
62
|
+
}
|
|
63
|
+
wildcard.push({
|
|
64
|
+
prefix: specifier.slice(0, star),
|
|
65
|
+
suffix: specifier.slice(star + 1),
|
|
66
|
+
valuePrefix: value.slice(0, valueStar),
|
|
67
|
+
valueSuffix: value.slice(valueStar + 1),
|
|
68
|
+
})
|
|
69
|
+
}
|
|
70
|
+
return { exact, wildcard }
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Wraps `@flow_step` functions in consumer source so they run as trace steps
|
|
74
|
+
// under test. Runs before Vite strips types; the printer reflows the file, so
|
|
75
|
+
// stack-trace lines inside an annotated file can shift.
|
|
76
|
+
const flowStepTransform: NonNullable<Plugin['transform']> = function (code, id) {
|
|
77
|
+
const file = id.split('?')[0] ?? id
|
|
78
|
+
if (!/\.tsx?$/.test(file) || file.includes('/node_modules/') || !isAbsolute(file)) return null
|
|
79
|
+
const applied = applyFlowStepTransform(code, file)
|
|
80
|
+
return applied === null ? null : { code: applied.code, map: null }
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Forked workers are SIGTERMed right after vitest's `stop` handshake, so their
|
|
84
|
+
// last queued clone drops never run. This module's teardown runs in the parent
|
|
85
|
+
// once every worker is gone and drops what they left (#810).
|
|
86
|
+
const REAP_AFTER_RUN = fileURLToPath(new URL(`./reap-after-run${import.meta.url.slice(import.meta.url.lastIndexOf('.'))}`, import.meta.url))
|
|
87
|
+
|
|
88
|
+
export function pipework(options?: PipeworkVitestOptions): Plugin {
|
|
89
|
+
const reapConfig: Pick<Plugin, 'config'> =
|
|
90
|
+
options?.database === false ? {} : { config: () => ({ test: { globalSetup: [REAP_AFTER_RUN] } }) }
|
|
91
|
+
const packageRoot = options?.packageRoot
|
|
92
|
+
const workspacePackages = options?.workspacePackages
|
|
93
|
+
if (packageRoot === undefined && workspacePackages === undefined) {
|
|
94
|
+
return { name: 'pipework', enforce: 'pre', transform: flowStepTransform, ...reapConfig }
|
|
95
|
+
}
|
|
96
|
+
const distPrefix = packageRoot !== undefined ? packageRoot + sep + 'dist' + sep : undefined
|
|
97
|
+
const srcPrefix = packageRoot !== undefined ? packageRoot + sep + 'src' + sep : undefined
|
|
98
|
+
const { exact, wildcard } =
|
|
99
|
+
workspacePackages !== undefined
|
|
100
|
+
? splitWorkspacePackages(workspacePackages)
|
|
101
|
+
: { exact: {}, wildcard: [] }
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
name: 'pipework',
|
|
105
|
+
enforce: 'pre',
|
|
106
|
+
transform: flowStepTransform,
|
|
107
|
+
...reapConfig,
|
|
108
|
+
async resolveId(source, importer) {
|
|
109
|
+
// Cross-package (#301): a bare workspace specifier resolves straight to src/.
|
|
110
|
+
if (workspacePackages !== undefined) {
|
|
111
|
+
const mapped = exact[source]
|
|
112
|
+
if (mapped !== undefined) return mapped
|
|
113
|
+
// Wildcard export subpath (#311): match `prefix*suffix`, substitute the
|
|
114
|
+
// captured segment, and resolve only when the source file exists — a
|
|
115
|
+
// miss falls through so Vite reports its own error.
|
|
116
|
+
for (const w of wildcard) {
|
|
117
|
+
if (
|
|
118
|
+
source.length > w.prefix.length + w.suffix.length &&
|
|
119
|
+
source.startsWith(w.prefix) &&
|
|
120
|
+
source.endsWith(w.suffix)
|
|
121
|
+
) {
|
|
122
|
+
const matched = source.slice(w.prefix.length, source.length - w.suffix.length)
|
|
123
|
+
const candidate = w.valuePrefix + matched + w.valueSuffix
|
|
124
|
+
if (existsSync(candidate)) return candidate
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// Intra-package (#274): a built dist/*.js is rewritten to its src/*.ts.
|
|
129
|
+
if (distPrefix === undefined || srcPrefix === undefined) return null
|
|
130
|
+
const resolved = await this.resolve(source, importer, { skipSelf: true })
|
|
131
|
+
if (resolved === null) return null
|
|
132
|
+
const id = resolved.id
|
|
133
|
+
if (!id.startsWith(distPrefix) || !id.endsWith('.js')) return null
|
|
134
|
+
const relative = id.slice(distPrefix.length, -3)
|
|
135
|
+
for (const ext of ['.ts', '.tsx']) {
|
|
136
|
+
const candidate = srcPrefix + relative + ext
|
|
137
|
+
if (existsSync(candidate)) return candidate
|
|
138
|
+
}
|
|
139
|
+
return null
|
|
140
|
+
},
|
|
141
|
+
}
|
|
142
|
+
}
|
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
import { resolve, dirname } from 'node:path'
|
|
2
|
+
import { configDefaults } from 'vitest/config'
|
|
3
|
+
import type { ViteUserConfig, UserWorkspaceConfig } from 'vitest/config'
|
|
4
|
+
import type { VitestConfig, VitestModuleConfig, VitestProfileConfig, CoverageConfig } from '../core/config/schema.js'
|
|
5
|
+
import type { ResolvedModule } from '../workspace/discover.js'
|
|
6
|
+
import type { Manifold } from '../core/pipework.js'
|
|
7
|
+
import { findConfig, registerTsResolveHooks } from '../core/config/discover.js'
|
|
8
|
+
import { importConfig } from '../core/config/import-config.js'
|
|
9
|
+
import { loadEnvFiles } from '../core/config/env.js'
|
|
10
|
+
import { resolveModules } from '../workspace/discover.js'
|
|
11
|
+
import { workspaceSourcePaths } from '../workspace/source-paths.js'
|
|
12
|
+
import { pipework as pipeworkPlugin } from './vitest-plugin.js'
|
|
13
|
+
|
|
14
|
+
const DEFAULT_TEST_TIMEOUT = 30_000
|
|
15
|
+
export const DEFAULT_HOOK_TIMEOUT = 60_000
|
|
16
|
+
|
|
17
|
+
// Pipework's own defaults, overridable per workspace, module and profile via
|
|
18
|
+
// `vitest.pool` / `vitest.isolate`. `forks` because a test that sets a process-wide
|
|
19
|
+
// Postgres session must not share a worker; `isolate: false` because pipework's
|
|
20
|
+
// per-test database isolation already separates test state and re-isolating the
|
|
21
|
+
// worker costs a process spawn per file.
|
|
22
|
+
const DEFAULT_POOL = 'forks'
|
|
23
|
+
const DEFAULT_ISOLATE = false
|
|
24
|
+
|
|
25
|
+
type PoolName = NonNullable<VitestConfig['pool']>
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Consumer excludes on TOP of vitest's defaults, not in place of them.
|
|
29
|
+
*
|
|
30
|
+
* Vitest replaces `exclude` outright, so a config that adds one glob silently stops
|
|
31
|
+
* excluding `node_modules` and `.git` — the suite then tries to run every test in every
|
|
32
|
+
* installed package. Merging is the behaviour a consumer means (#394).
|
|
33
|
+
*/
|
|
34
|
+
function mergeExclude(configured: string[] | undefined): string[] {
|
|
35
|
+
if (configured === undefined) return [...configDefaults.exclude]
|
|
36
|
+
return [...new Set([...configDefaults.exclude, ...configured])]
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Build the full vitest UserConfig from pipework.config.ts.
|
|
41
|
+
*
|
|
42
|
+
* The generated `vitest.config.ts` is a single line: `defineConfig(await resolveVitestConfig())`.
|
|
43
|
+
* Everything that would normally live in `vitest.config.ts` — projects, reporters, sequencer,
|
|
44
|
+
* outer-level Vite options — flows through `pipework.config.ts` so pipework remains the single
|
|
45
|
+
* source of truth and the generated file stays byte-stable for `pipework check`.
|
|
46
|
+
*
|
|
47
|
+
* Shape:
|
|
48
|
+
* - `vitest.extra.test.*` → spread into `test` (reporters, sequence, cache, bail, ...)
|
|
49
|
+
* - `vitest.extra.*` (anything outside `test`) → spread at the top level (resolve, plugins, ...)
|
|
50
|
+
* - `test.projects` is owned by pipework — defining it in `extra` throws.
|
|
51
|
+
*/
|
|
52
|
+
export async function resolveVitestConfig(cwd?: string): Promise<ViteUserConfig> {
|
|
53
|
+
const start = cwd ?? process.cwd()
|
|
54
|
+
const configPath = findConfig(start)
|
|
55
|
+
|
|
56
|
+
if (configPath === null) {
|
|
57
|
+
throw new Error(
|
|
58
|
+
`[pipework] No pipework.config.ts found in ${start} or any parent directory.\n\n` +
|
|
59
|
+
' The vitest config resolver needs pipework.config.ts to discover modules.\n' +
|
|
60
|
+
' Create one with `pipework init`.\n',
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const configDir = dirname(configPath)
|
|
65
|
+
loadEnvFiles(configDir)
|
|
66
|
+
registerTsResolveHooks()
|
|
67
|
+
|
|
68
|
+
let manifold: Manifold
|
|
69
|
+
try {
|
|
70
|
+
manifold = await importConfig(configPath)
|
|
71
|
+
} catch (err: unknown) {
|
|
72
|
+
const message = err instanceof Error ? err.message : String(err)
|
|
73
|
+
throw new Error(
|
|
74
|
+
`[pipework] Failed to load pipework.config.ts for vitest config resolution.\n\n` +
|
|
75
|
+
` ${message}\n\n` +
|
|
76
|
+
' This usually means database environment variables are missing.\n' +
|
|
77
|
+
' Ensure your .env file exists and contains DATABASE_URL (or equivalent).\n\n' +
|
|
78
|
+
' The vitest config resolver imports your config to read module definitions.\n' +
|
|
79
|
+
' It does not connect to any database.\n',
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const blueprint = manifold.config.raw
|
|
84
|
+
if (blueprint.vitest === undefined) {
|
|
85
|
+
return { test: { projects: [] } }
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const resolvedModules = resolveModules(blueprint.modules, configDir)
|
|
89
|
+
const workspacePackages: Record<string, string> = {}
|
|
90
|
+
for (const [specifier, relPath] of workspaceSourcePaths(resolvedModules, blueprint.name ?? 'app')) {
|
|
91
|
+
workspacePackages[specifier] = resolve(configDir, relPath)
|
|
92
|
+
}
|
|
93
|
+
const projects = resolveVitestModules(blueprint.vitest, resolvedModules, configDir, workspacePackages)
|
|
94
|
+
return mergeExtraWithProjects(blueprint.vitest.extra, projects, blueprint.vitest.coverage)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Merge consumer-supplied top-level vitest config (from `vitest.extra`) with the
|
|
99
|
+
* pipework-controlled `test.projects`. Splits `extra` into outer-level keys (Vite-level:
|
|
100
|
+
* `resolve`, `plugins`, ...) and `test`-level keys (`reporters`, `sequence`, ...),
|
|
101
|
+
* spreading each at the right depth. Throws if the consumer tries to override `projects`.
|
|
102
|
+
*/
|
|
103
|
+
function mergeExtraWithProjects(
|
|
104
|
+
extra: Record<string, unknown> | undefined,
|
|
105
|
+
projects: UserWorkspaceConfig[],
|
|
106
|
+
coverage: CoverageConfig | undefined,
|
|
107
|
+
): ViteUserConfig {
|
|
108
|
+
// Vitest reads coverage at the root only. It used to be written into each project,
|
|
109
|
+
// where it did nothing — including `coverage.enabled`, which had no schema entry at
|
|
110
|
+
// all, so an env-gated preset was unreachable except through `extra.test` (#394).
|
|
111
|
+
const root = coverage !== undefined ? { coverage: rootCoverage(coverage) } : {}
|
|
112
|
+
|
|
113
|
+
if (extra === undefined) {
|
|
114
|
+
return { test: { ...root, projects } }
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const { test: extraTest, ...extraOuter } = extra
|
|
118
|
+
|
|
119
|
+
if (extraTest !== undefined && (typeof extraTest !== 'object' || extraTest === null || Array.isArray(extraTest))) {
|
|
120
|
+
throw new Error(
|
|
121
|
+
`[pipework] vitest.extra.test must be an object — got ${describe(extraTest)}.\n\n` +
|
|
122
|
+
' vitest.extra mirrors the shape of `defineConfig({...})`:\n' +
|
|
123
|
+
' - test-level keys (reporters, sequence, ...) go under `extra.test`\n' +
|
|
124
|
+
' - outer Vite keys (resolve, plugins, ...) go at the top of `extra`\n',
|
|
125
|
+
)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const testRecord = (extraTest ?? {}) as Record<string, unknown>
|
|
129
|
+
|
|
130
|
+
if ('projects' in testRecord) {
|
|
131
|
+
throw new Error(
|
|
132
|
+
`[pipework] vitest.extra.test.projects is owned by pipework — \n` +
|
|
133
|
+
' define modules in `vitest.modules` (in pipework.config.ts) instead.\n' +
|
|
134
|
+
' The generated vitest.config.ts wires `projects` through `resolveVitestConfig()`.\n',
|
|
135
|
+
)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return {
|
|
139
|
+
...extraOuter,
|
|
140
|
+
test: {
|
|
141
|
+
...root,
|
|
142
|
+
...testRecord,
|
|
143
|
+
projects,
|
|
144
|
+
},
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// `exactOptionalPropertyTypes` makes an explicit `undefined` a different thing from an
|
|
149
|
+
// absent key, and vitest's InlineConfig accepts only the latter. Drop the unset ones.
|
|
150
|
+
function rootCoverage(coverage: CoverageConfig): Record<string, unknown> {
|
|
151
|
+
const out: Record<string, unknown> = {}
|
|
152
|
+
for (const [key, value] of Object.entries(coverage)) {
|
|
153
|
+
if (value !== undefined) out[key] = value
|
|
154
|
+
}
|
|
155
|
+
return out
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function describe(v: unknown): string {
|
|
159
|
+
if (v === null) return 'null'
|
|
160
|
+
if (Array.isArray(v)) return 'array'
|
|
161
|
+
return typeof v
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Refuse a `coverage` key on a module or profile.
|
|
166
|
+
*
|
|
167
|
+
* Vitest treats coverage as a root-level option, so one written into a project is
|
|
168
|
+
* discarded without a word — the exact silent-no-op #394 was filed for. Naming the
|
|
169
|
+
* module beats accepting a setting that cannot take effect.
|
|
170
|
+
*/
|
|
171
|
+
function refuseProjectCoverage(where: string, config: { coverage?: unknown }): void {
|
|
172
|
+
if (config.coverage === undefined) return
|
|
173
|
+
throw new Error(
|
|
174
|
+
`[pipework] vitest coverage is a root-level option — remove it from \`${where}\`.\n\n` +
|
|
175
|
+
' Vitest reads `coverage` at the config root; inside a project it is ignored.\n' +
|
|
176
|
+
' Move the settings to the top-level `vitest.coverage` in pipework.config.ts.\n' +
|
|
177
|
+
' Gate collection with `vitest.coverage.enabled` (compute the boolean there to\n' +
|
|
178
|
+
' key it off an environment variable).\n',
|
|
179
|
+
)
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export function resolveVitestModules(
|
|
183
|
+
vitestConfig: VitestConfig,
|
|
184
|
+
resolvedModules: ResolvedModule[],
|
|
185
|
+
configDir: string,
|
|
186
|
+
workspacePackages: Record<string, string>,
|
|
187
|
+
): UserWorkspaceConfig[] {
|
|
188
|
+
// A repo with no declared modules is a single-package project: the repo root
|
|
189
|
+
// is the one implicit module, addressed as '.'. The centralized vitest model
|
|
190
|
+
// must be able to express this layout — otherwise single-package projects
|
|
191
|
+
// have no in-config home for their test setup.
|
|
192
|
+
const effectiveModules: ResolvedModule[] = resolvedModules.length === 0
|
|
193
|
+
? [{ key: '.', relativePath: '.', config: {} }]
|
|
194
|
+
: resolvedModules
|
|
195
|
+
const moduleMap = new Map(effectiveModules.map(m => [m.relativePath, m]))
|
|
196
|
+
const included = resolveIncludedModules(vitestConfig, moduleMap)
|
|
197
|
+
|
|
198
|
+
const projects: UserWorkspaceConfig[] = []
|
|
199
|
+
|
|
200
|
+
for (const [modulePath, moduleConfig] of [...included.entries()].sort(([a], [b]) => a.localeCompare(b))) {
|
|
201
|
+
refuseProjectCoverage(`vitest.modules["${modulePath}"].coverage`, moduleConfig)
|
|
202
|
+
const project = buildProjectConfig(modulePath, moduleConfig, vitestConfig, configDir, workspacePackages)
|
|
203
|
+
projects.push(project)
|
|
204
|
+
|
|
205
|
+
if (moduleConfig.profiles !== undefined) {
|
|
206
|
+
for (const [profileName, profileConfig] of Object.entries(moduleConfig.profiles).sort(([a], [b]) => a.localeCompare(b))) {
|
|
207
|
+
refuseProjectCoverage(`vitest.modules["${modulePath}"].profiles["${profileName}"].coverage`, profileConfig)
|
|
208
|
+
const profileProject = buildProfileConfig(modulePath, profileName, moduleConfig, profileConfig, vitestConfig, configDir, workspacePackages)
|
|
209
|
+
projects.push(profileProject)
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return projects
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function resolveIncludedModules(
|
|
218
|
+
vitestConfig: VitestConfig,
|
|
219
|
+
moduleMap: Map<string, ResolvedModule>,
|
|
220
|
+
): Map<string, VitestModuleConfig> {
|
|
221
|
+
if (vitestConfig.modules === undefined) {
|
|
222
|
+
const result = new Map<string, VitestModuleConfig>()
|
|
223
|
+
for (const key of moduleMap.keys()) {
|
|
224
|
+
result.set(key, {})
|
|
225
|
+
}
|
|
226
|
+
return result
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const globs: Array<{ pattern: string; config: VitestModuleConfig }> = []
|
|
230
|
+
const explicit: Array<{ key: string; config: VitestModuleConfig }> = []
|
|
231
|
+
|
|
232
|
+
for (const [key, config] of Object.entries(vitestConfig.modules)) {
|
|
233
|
+
if (key.includes('*')) {
|
|
234
|
+
globs.push({ pattern: key, config })
|
|
235
|
+
} else {
|
|
236
|
+
explicit.push({ key, config })
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const result = new Map<string, VitestModuleConfig>()
|
|
241
|
+
|
|
242
|
+
for (const { pattern, config } of globs) {
|
|
243
|
+
for (const modulePath of matchGlob(pattern, moduleMap)) {
|
|
244
|
+
result.set(modulePath, config)
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
for (const { key, config } of explicit) {
|
|
249
|
+
if (!moduleMap.has(key)) {
|
|
250
|
+
const known = [...moduleMap.keys()]
|
|
251
|
+
const suggestion = closestMatch(key, known)
|
|
252
|
+
const knownList = known.join(', ')
|
|
253
|
+
const hint = suggestion !== null
|
|
254
|
+
? `Did you mean "${suggestion}"? Known modules: ${knownList}`
|
|
255
|
+
: `Known modules: ${knownList}`
|
|
256
|
+
throw new Error(
|
|
257
|
+
`[pipework] Unknown module "${key}" in vitest.modules.\n\n ${hint}\n`,
|
|
258
|
+
)
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const existing = result.get(key)
|
|
262
|
+
if (existing !== undefined) {
|
|
263
|
+
result.set(key, mergeModuleConfigs(existing, config))
|
|
264
|
+
} else {
|
|
265
|
+
result.set(key, config)
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return result
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
function matchGlob(pattern: string, moduleMap: Map<string, ResolvedModule>): string[] {
|
|
273
|
+
const parts = pattern.split('/')
|
|
274
|
+
const starIndex = parts.indexOf('*')
|
|
275
|
+
if (starIndex === -1) return []
|
|
276
|
+
|
|
277
|
+
const prefix = parts.slice(0, starIndex).join('/')
|
|
278
|
+
const suffix = parts.slice(starIndex + 1).join('/')
|
|
279
|
+
|
|
280
|
+
const matches: string[] = []
|
|
281
|
+
for (const key of moduleMap.keys()) {
|
|
282
|
+
const keyParts = key.split('/')
|
|
283
|
+
if (keyParts.length !== parts.length) continue
|
|
284
|
+
|
|
285
|
+
const keyPrefix = keyParts.slice(0, starIndex).join('/')
|
|
286
|
+
const keySuffix = keyParts.slice(starIndex + 1).join('/')
|
|
287
|
+
|
|
288
|
+
if (keyPrefix === prefix && keySuffix === suffix) {
|
|
289
|
+
matches.push(key)
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return matches.sort()
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
function mergeModuleConfigs(base: VitestModuleConfig, override: VitestModuleConfig): VitestModuleConfig {
|
|
296
|
+
return {
|
|
297
|
+
...override,
|
|
298
|
+
coverage: override.coverage !== undefined || base.coverage !== undefined
|
|
299
|
+
? { ...base.coverage, ...override.coverage }
|
|
300
|
+
: undefined,
|
|
301
|
+
env: override.env !== undefined || base.env !== undefined
|
|
302
|
+
? { ...base.env, ...override.env }
|
|
303
|
+
: undefined,
|
|
304
|
+
extra: override.extra !== undefined || base.extra !== undefined
|
|
305
|
+
? { ...base.extra, ...override.extra }
|
|
306
|
+
: undefined,
|
|
307
|
+
profiles: override.profiles !== undefined || base.profiles !== undefined
|
|
308
|
+
? { ...base.profiles, ...override.profiles }
|
|
309
|
+
: undefined,
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
function buildProjectConfig(
|
|
314
|
+
modulePath: string,
|
|
315
|
+
moduleConfig: VitestModuleConfig,
|
|
316
|
+
workspace: VitestConfig,
|
|
317
|
+
configDir: string,
|
|
318
|
+
workspacePackages: Record<string, string>,
|
|
319
|
+
): UserWorkspaceConfig {
|
|
320
|
+
const database = moduleConfig.database ?? workspace.database ?? true
|
|
321
|
+
const testTimeout = moduleConfig.testTimeout ?? workspace.testTimeout ?? DEFAULT_TEST_TIMEOUT
|
|
322
|
+
const hookTimeout = moduleConfig.hookTimeout ?? workspace.hookTimeout ?? DEFAULT_HOOK_TIMEOUT
|
|
323
|
+
const include = moduleConfig.include ?? workspace.include
|
|
324
|
+
const exclude = moduleConfig.exclude ?? workspace.exclude
|
|
325
|
+
|
|
326
|
+
const setupFiles = buildSetupFiles(database, moduleConfig.setupFiles)
|
|
327
|
+
const inlineDeps = buildInlineDeps(workspace.inlineDeps)
|
|
328
|
+
|
|
329
|
+
const extra = moduleConfig.extra ?? {}
|
|
330
|
+
|
|
331
|
+
return buildProject({
|
|
332
|
+
name: modulePath,
|
|
333
|
+
root: resolve(configDir, modulePath),
|
|
334
|
+
database,
|
|
335
|
+
testTimeout,
|
|
336
|
+
hookTimeout,
|
|
337
|
+
include,
|
|
338
|
+
exclude,
|
|
339
|
+
setupFiles,
|
|
340
|
+
inlineDeps,
|
|
341
|
+
pool: moduleConfig.pool ?? workspace.pool,
|
|
342
|
+
isolate: moduleConfig.isolate ?? workspace.isolate,
|
|
343
|
+
env: moduleConfig.env,
|
|
344
|
+
extra,
|
|
345
|
+
workspacePackages,
|
|
346
|
+
})
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
function buildProfileConfig(
|
|
350
|
+
modulePath: string,
|
|
351
|
+
profileName: string,
|
|
352
|
+
moduleConfig: VitestModuleConfig,
|
|
353
|
+
profileConfig: VitestProfileConfig,
|
|
354
|
+
workspace: VitestConfig,
|
|
355
|
+
configDir: string,
|
|
356
|
+
workspacePackages: Record<string, string>,
|
|
357
|
+
): UserWorkspaceConfig {
|
|
358
|
+
const database = profileConfig.database ?? moduleConfig.database ?? workspace.database ?? true
|
|
359
|
+
const testTimeout = profileConfig.testTimeout ?? moduleConfig.testTimeout ?? workspace.testTimeout ?? DEFAULT_TEST_TIMEOUT
|
|
360
|
+
const hookTimeout = profileConfig.hookTimeout ?? moduleConfig.hookTimeout ?? workspace.hookTimeout ?? DEFAULT_HOOK_TIMEOUT
|
|
361
|
+
const include = profileConfig.include ?? moduleConfig.include ?? workspace.include
|
|
362
|
+
const exclude = profileConfig.exclude ?? moduleConfig.exclude ?? workspace.exclude
|
|
363
|
+
|
|
364
|
+
const profileSetupFiles = profileConfig.setupFiles ?? moduleConfig.setupFiles
|
|
365
|
+
const setupFiles = buildSetupFiles(database, profileSetupFiles)
|
|
366
|
+
const inlineDeps = buildInlineDeps(workspace.inlineDeps)
|
|
367
|
+
|
|
368
|
+
const moduleExtra = moduleConfig.extra ?? {}
|
|
369
|
+
const extra = profileConfig.extra !== undefined
|
|
370
|
+
? { ...moduleExtra, ...profileConfig.extra }
|
|
371
|
+
: moduleExtra
|
|
372
|
+
|
|
373
|
+
const env = profileConfig.env !== undefined || moduleConfig.env !== undefined
|
|
374
|
+
? { ...moduleConfig.env, ...profileConfig.env }
|
|
375
|
+
: undefined
|
|
376
|
+
|
|
377
|
+
return buildProject({
|
|
378
|
+
name: `${modulePath}:${profileName}`,
|
|
379
|
+
root: resolve(configDir, modulePath),
|
|
380
|
+
database,
|
|
381
|
+
testTimeout,
|
|
382
|
+
hookTimeout,
|
|
383
|
+
include,
|
|
384
|
+
exclude,
|
|
385
|
+
setupFiles,
|
|
386
|
+
inlineDeps,
|
|
387
|
+
pool: profileConfig.pool ?? moduleConfig.pool ?? workspace.pool,
|
|
388
|
+
isolate: profileConfig.isolate ?? moduleConfig.isolate ?? workspace.isolate,
|
|
389
|
+
env,
|
|
390
|
+
extra,
|
|
391
|
+
workspacePackages,
|
|
392
|
+
})
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
interface ProjectBuildInput {
|
|
396
|
+
name: string
|
|
397
|
+
root: string
|
|
398
|
+
database: boolean
|
|
399
|
+
testTimeout: number
|
|
400
|
+
hookTimeout: number
|
|
401
|
+
include: string[] | undefined
|
|
402
|
+
exclude: string[] | undefined
|
|
403
|
+
setupFiles: string[]
|
|
404
|
+
inlineDeps: string[]
|
|
405
|
+
pool: PoolName | undefined
|
|
406
|
+
isolate: boolean | undefined
|
|
407
|
+
env: Record<string, string> | undefined
|
|
408
|
+
extra: Record<string, unknown>
|
|
409
|
+
workspacePackages: Record<string, string>
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
function buildProject(input: ProjectBuildInput): UserWorkspaceConfig {
|
|
413
|
+
return {
|
|
414
|
+
...input.extra,
|
|
415
|
+
plugins: [
|
|
416
|
+
pipeworkPlugin({ database: input.database, packageRoot: input.root, workspacePackages: input.workspacePackages }),
|
|
417
|
+
],
|
|
418
|
+
test: {
|
|
419
|
+
// Pipework defaults — overridable via `extra.test` below (#260).
|
|
420
|
+
pool: DEFAULT_POOL,
|
|
421
|
+
isolate: DEFAULT_ISOLATE,
|
|
422
|
+
...('test' in input.extra ? input.extra['test'] as Record<string, unknown> : {}),
|
|
423
|
+
// Dedicated config fields and project identity — these win over
|
|
424
|
+
// `extra.test`. `name`/`root` are the project's identity (changing them
|
|
425
|
+
// breaks `--project` matching and module rooting); `setupFiles` and the
|
|
426
|
+
// inline-deps `server` config are load-bearing for test isolation.
|
|
427
|
+
name: input.name,
|
|
428
|
+
root: input.root,
|
|
429
|
+
testTimeout: input.testTimeout,
|
|
430
|
+
hookTimeout: input.hookTimeout,
|
|
431
|
+
server: {
|
|
432
|
+
deps: {
|
|
433
|
+
inline: input.inlineDeps,
|
|
434
|
+
},
|
|
435
|
+
},
|
|
436
|
+
setupFiles: input.setupFiles,
|
|
437
|
+
// `vitest.pool` / `vitest.isolate` are dedicated fields, so an explicitly
|
|
438
|
+
// configured one wins over `extra.test`; unset, the default above stands and
|
|
439
|
+
// `extra.test` still overrides it as it always did.
|
|
440
|
+
...(input.pool !== undefined ? { pool: input.pool } : {}),
|
|
441
|
+
...(input.isolate !== undefined ? { isolate: input.isolate } : {}),
|
|
442
|
+
...(input.include !== undefined ? { include: input.include } : {}),
|
|
443
|
+
exclude: mergeExclude(input.exclude),
|
|
444
|
+
...(input.env !== undefined ? { env: input.env } : {}),
|
|
445
|
+
},
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
function buildSetupFiles(database: boolean, userSetupFiles: string[] | undefined): string[] {
|
|
450
|
+
const files: string[] = []
|
|
451
|
+
if (database) {
|
|
452
|
+
files.push('pipework/test/setup')
|
|
453
|
+
}
|
|
454
|
+
if (userSetupFiles !== undefined) {
|
|
455
|
+
files.push(...userSetupFiles)
|
|
456
|
+
}
|
|
457
|
+
return files
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
function buildInlineDeps(workspaceInlineDeps: string[] | undefined): string[] {
|
|
461
|
+
const deps = new Set<string>(['pipework'])
|
|
462
|
+
if (workspaceInlineDeps !== undefined) {
|
|
463
|
+
for (const dep of workspaceInlineDeps) {
|
|
464
|
+
deps.add(dep)
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
return [...deps]
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
function closestMatch(input: string, candidates: string[]): string | null {
|
|
471
|
+
if (candidates.length === 0) return null
|
|
472
|
+
|
|
473
|
+
let best: string | null = null
|
|
474
|
+
let bestDistance = Infinity
|
|
475
|
+
|
|
476
|
+
for (const candidate of candidates) {
|
|
477
|
+
const d = levenshtein(input.toLowerCase(), candidate.toLowerCase())
|
|
478
|
+
if (d < bestDistance && d <= Math.max(input.length, candidate.length) * 0.6) {
|
|
479
|
+
bestDistance = d
|
|
480
|
+
best = candidate
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
return best
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
function levenshtein(a: string, b: string): number {
|
|
488
|
+
const m = a.length
|
|
489
|
+
const n = b.length
|
|
490
|
+
const dp: number[][] = Array.from({ length: m + 1 }, () => Array.from({ length: n + 1 }, () => 0))
|
|
491
|
+
|
|
492
|
+
for (let i = 0; i <= m; i++) dp[i]![0] = i
|
|
493
|
+
for (let j = 0; j <= n; j++) dp[0]![j] = j
|
|
494
|
+
|
|
495
|
+
for (let i = 1; i <= m; i++) {
|
|
496
|
+
for (let j = 1; j <= n; j++) {
|
|
497
|
+
const cost = a[i - 1] === b[j - 1] ? 0 : 1
|
|
498
|
+
dp[i]![j] = Math.min(
|
|
499
|
+
dp[i - 1]![j]! + 1,
|
|
500
|
+
dp[i]![j - 1]! + 1,
|
|
501
|
+
dp[i - 1]![j - 1]! + cost,
|
|
502
|
+
)
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
return dp[m]![n]!
|
|
507
|
+
}
|