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
package/src/cli/index.ts
ADDED
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import { parseArgs } from 'node:util'
|
|
2
|
+
import { loadEnvFiles } from '../core/config/env.js'
|
|
3
|
+
import { bold, error } from './output.js'
|
|
4
|
+
import { handleError } from './errors.js'
|
|
5
|
+
|
|
6
|
+
const USAGE = `
|
|
7
|
+
${bold('pipework')} — TypeScript framework for multi-tenant SaaS
|
|
8
|
+
|
|
9
|
+
${bold('Commands:')}
|
|
10
|
+
init Scaffold pipework.config.ts and migrations directory
|
|
11
|
+
sync Generate workspace files (package.json, pnpm-workspace.yaml)
|
|
12
|
+
install Sync workspace + pnpm install
|
|
13
|
+
upgrade [ver] Upgrade pipework to a version (default: latest) + install
|
|
14
|
+
add <pkg@ver> Add dependency to config, sync, and install
|
|
15
|
+
remove <pkg> Remove dependency from config, sync, and install
|
|
16
|
+
generate Generate SQL migrations from Drizzle schema changes
|
|
17
|
+
migrate Run pending migrations for all databases
|
|
18
|
+
openapi Write an http surface's OpenAPI document (no database needed; --surface <name>, --out <file>)
|
|
19
|
+
run <script> Execute a script as a traced, audited flow (with --tenant: one transaction, rolled back if it throws)
|
|
20
|
+
test Run tests with automatic database setup
|
|
21
|
+
check Type-check, lint, and boundary enforcement
|
|
22
|
+
lint [eslint args] Lint the current module (the workspace at its root) with check's config; every argument goes to eslint
|
|
23
|
+
codemod Fill missing @downstream cardinality across the corpus
|
|
24
|
+
db Database lifecycle: setup, teardown, reset
|
|
25
|
+
alerts unit-fault Record an abnormal systemd stop (ExecStopPost=pipework alerts unit-fault --unit %n)
|
|
26
|
+
alerts stale Exit 1 and name any background loop that has stopped (run from a systemd timer; --max-age loop=5m)
|
|
27
|
+
dev Start all surfaces with file watching
|
|
28
|
+
serve Start all surfaces for production (no file watching)
|
|
29
|
+
|
|
30
|
+
${bold('Options:')}
|
|
31
|
+
--help, -h Show this help message
|
|
32
|
+
--version, -v Show version
|
|
33
|
+
--name Migration name (used with generate)
|
|
34
|
+
--confirm Required for production migrations
|
|
35
|
+
--tenant Tenant ID; the script runs in one transaction on the default database
|
|
36
|
+
--job-type Override job type (default: "script")
|
|
37
|
+
--port <n> Port for the http surface that declares none (also PORT; dev, serve)
|
|
38
|
+
--surface <name> openapi: the http surface to describe (default: the only one with openapi info)
|
|
39
|
+
--out <file> openapi: write the document here instead of stdout
|
|
40
|
+
--worker-only serve: run only the worker surfaces (no http port, no script surfaces: those belong to the main process)
|
|
41
|
+
|
|
42
|
+
${bold('Scoping (check, test):')}
|
|
43
|
+
--fast Affected-only (branch diff); test runs fast tiers only
|
|
44
|
+
--full All modules, all test tiers
|
|
45
|
+
--all Run against all modules
|
|
46
|
+
--staged Scope to staged changes (for pre-commit hooks)
|
|
47
|
+
--module <path> Scope to a specific module
|
|
48
|
+
--suite <name> Run a specific test suite/profile (test only)
|
|
49
|
+
--reap Drop orphan test databases and exit (test only)
|
|
50
|
+
--shard <i>/<n> Run part i of n disjoint parts of the selected run (test, check); the n parts together equal the unsharded run
|
|
51
|
+
|
|
52
|
+
${bold('Examples:')}
|
|
53
|
+
pipework init
|
|
54
|
+
pipework upgrade
|
|
55
|
+
pipework upgrade 0.8.0
|
|
56
|
+
pipework add stripe@^17.0.0
|
|
57
|
+
pipework remove stripe
|
|
58
|
+
pipework generate --name add-users
|
|
59
|
+
pipework generate --db app
|
|
60
|
+
pipework migrate --db app
|
|
61
|
+
pipework migrate --confirm # required in production
|
|
62
|
+
pipework dev
|
|
63
|
+
pipework dev --port 4000
|
|
64
|
+
pipework serve # production: bind every surface, no watcher
|
|
65
|
+
pipework serve --worker-only # an extra job worker against the same queue; opens no port
|
|
66
|
+
pipework dev --entry src/server.ts
|
|
67
|
+
pipework openapi --out openapi.json
|
|
68
|
+
pipework run ./scripts/seed.ts
|
|
69
|
+
pipework run ./scripts/backfill.ts --tenant t-123
|
|
70
|
+
pipework test
|
|
71
|
+
pipework test --all
|
|
72
|
+
pipework test --suite integration
|
|
73
|
+
pipework test --full --shard 2/4 # CI: part 2 of 4 across machines
|
|
74
|
+
pipework test --reap # drop orphan test databases
|
|
75
|
+
pipework check --staged
|
|
76
|
+
pipework check --all
|
|
77
|
+
pipework lint # the module you are in, exactly as check lints it
|
|
78
|
+
pipework lint --format json --output-file r.json src/a.ts # only src/a.ts
|
|
79
|
+
pipework codemod
|
|
80
|
+
pipework codemod --dry-run
|
|
81
|
+
pipework alerts unit-fault --unit subseam-core.service # reads $SERVICE_RESULT, $EXIT_CODE, $EXIT_STATUS
|
|
82
|
+
pipework alerts stale --max-age jobs.claim=5m # exit 1 with a line per stale loop; 0 and silent when none
|
|
83
|
+
`
|
|
84
|
+
|
|
85
|
+
export async function run(argv: string[]): Promise<void> {
|
|
86
|
+
// `lint` hands everything after it to eslint, flags included, so it is dispatched
|
|
87
|
+
// before parseArgs, which would refuse eslint's options.
|
|
88
|
+
if (argv[0] === 'lint') {
|
|
89
|
+
const cwd = process.cwd()
|
|
90
|
+
loadEnvFiles(cwd)
|
|
91
|
+
try {
|
|
92
|
+
const { lintCommand } = await import('./commands/lint.js')
|
|
93
|
+
process.exitCode = await lintCommand(cwd, argv.slice(1))
|
|
94
|
+
} catch (err) {
|
|
95
|
+
handleError(err)
|
|
96
|
+
}
|
|
97
|
+
return
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const { values, positionals } = parseArgs({
|
|
101
|
+
args: argv,
|
|
102
|
+
allowPositionals: true,
|
|
103
|
+
options: {
|
|
104
|
+
help: { type: 'boolean', short: 'h' },
|
|
105
|
+
version: { type: 'boolean', short: 'v' },
|
|
106
|
+
db: { type: 'string' },
|
|
107
|
+
unit: { type: 'string' },
|
|
108
|
+
database: { type: 'string' },
|
|
109
|
+
'max-age': { type: 'string', multiple: true },
|
|
110
|
+
name: { type: 'string' },
|
|
111
|
+
port: { type: 'string' },
|
|
112
|
+
surface: { type: 'string' },
|
|
113
|
+
out: { type: 'string' },
|
|
114
|
+
'worker-only': { type: 'boolean' },
|
|
115
|
+
entry: { type: 'string' },
|
|
116
|
+
confirm: { type: 'boolean' },
|
|
117
|
+
'allow-destructive': { type: 'boolean' },
|
|
118
|
+
'acknowledge-lock': { type: 'boolean' },
|
|
119
|
+
tenant: { type: 'string' },
|
|
120
|
+
'job-type': { type: 'string' },
|
|
121
|
+
all: { type: 'boolean' },
|
|
122
|
+
module: { type: 'string' },
|
|
123
|
+
staged: { type: 'boolean' },
|
|
124
|
+
fast: { type: 'boolean' },
|
|
125
|
+
full: { type: 'boolean' },
|
|
126
|
+
suite: { type: 'string' },
|
|
127
|
+
reap: { type: 'boolean' },
|
|
128
|
+
shard: { type: 'string' },
|
|
129
|
+
test: { type: 'boolean' },
|
|
130
|
+
'admin-url': { type: 'string' },
|
|
131
|
+
'dry-run': { type: 'boolean' },
|
|
132
|
+
},
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
if (values.help === true || positionals.length === 0) {
|
|
136
|
+
process.stderr.write(USAGE)
|
|
137
|
+
return
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (values.version === true) {
|
|
141
|
+
const { readFileSync } = await import('node:fs')
|
|
142
|
+
const { join, dirname } = await import('node:path')
|
|
143
|
+
const { fileURLToPath } = await import('node:url')
|
|
144
|
+
const pkgPath = join(dirname(fileURLToPath(import.meta.url)), '..', '..', 'package.json')
|
|
145
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as { version: string }
|
|
146
|
+
process.stdout.write(`${pkg.version}\n`)
|
|
147
|
+
return
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const command = positionals[0]
|
|
151
|
+
const cwd = process.cwd()
|
|
152
|
+
|
|
153
|
+
loadEnvFiles(cwd)
|
|
154
|
+
|
|
155
|
+
try {
|
|
156
|
+
switch (command) {
|
|
157
|
+
case 'init': {
|
|
158
|
+
const { init } = await import('./commands/init.js')
|
|
159
|
+
await init(cwd)
|
|
160
|
+
break
|
|
161
|
+
}
|
|
162
|
+
case 'sync': {
|
|
163
|
+
const { syncCommand } = await import('./commands/sync.js')
|
|
164
|
+
await syncCommand(cwd)
|
|
165
|
+
break
|
|
166
|
+
}
|
|
167
|
+
case 'install': {
|
|
168
|
+
const { install } = await import('./commands/install.js')
|
|
169
|
+
await install(cwd)
|
|
170
|
+
break
|
|
171
|
+
}
|
|
172
|
+
case 'upgrade': {
|
|
173
|
+
const targetVersion = positionals[1]
|
|
174
|
+
const { upgrade: upgradeCmd } = await import('./commands/upgrade.js')
|
|
175
|
+
await upgradeCmd(cwd, targetVersion)
|
|
176
|
+
break
|
|
177
|
+
}
|
|
178
|
+
case 'add': {
|
|
179
|
+
const pkgs = positionals.slice(1)
|
|
180
|
+
const { add: addCmd } = await import('./commands/add.js')
|
|
181
|
+
await addCmd(cwd, pkgs)
|
|
182
|
+
break
|
|
183
|
+
}
|
|
184
|
+
case 'remove': {
|
|
185
|
+
const pkgs = positionals.slice(1)
|
|
186
|
+
const { remove: removeCmd } = await import('./commands/remove.js')
|
|
187
|
+
await removeCmd(cwd, pkgs)
|
|
188
|
+
break
|
|
189
|
+
}
|
|
190
|
+
case 'generate': {
|
|
191
|
+
const { generate } = await import('./commands/generate.js')
|
|
192
|
+
await generate({
|
|
193
|
+
db: values.db,
|
|
194
|
+
name: values.name,
|
|
195
|
+
cwd,
|
|
196
|
+
})
|
|
197
|
+
break
|
|
198
|
+
}
|
|
199
|
+
case 'migrate': {
|
|
200
|
+
const { migrate } = await import('./commands/migrate.js')
|
|
201
|
+
await migrate({
|
|
202
|
+
db: values.db,
|
|
203
|
+
cwd,
|
|
204
|
+
confirm: values.confirm,
|
|
205
|
+
allowDestructive: values['allow-destructive'],
|
|
206
|
+
acknowledgeLock: values['acknowledge-lock'],
|
|
207
|
+
})
|
|
208
|
+
break
|
|
209
|
+
}
|
|
210
|
+
case 'openapi': {
|
|
211
|
+
const { openapi } = await import('./commands/openapi.js')
|
|
212
|
+
await openapi({ cwd, surface: values.surface, out: values.out })
|
|
213
|
+
break
|
|
214
|
+
}
|
|
215
|
+
case 'run': {
|
|
216
|
+
const scriptPath = positionals[1]
|
|
217
|
+
if (scriptPath === undefined || scriptPath === '') {
|
|
218
|
+
error('Missing script path.')
|
|
219
|
+
process.stderr.write(`\n Usage: ${bold('pipework run <script> [-- args...]')}\n\n`)
|
|
220
|
+
process.exit(1)
|
|
221
|
+
}
|
|
222
|
+
const { run: runScript } = await import('./commands/run.js')
|
|
223
|
+
await runScript({
|
|
224
|
+
script: scriptPath,
|
|
225
|
+
cwd,
|
|
226
|
+
tenant: values.tenant,
|
|
227
|
+
jobType: values['job-type'],
|
|
228
|
+
})
|
|
229
|
+
break
|
|
230
|
+
}
|
|
231
|
+
case 'test': {
|
|
232
|
+
const { parseScope: parseScopeTest } = await import('./commands/scope.js')
|
|
233
|
+
const parsedTest = parseScopeTest({ all: values.all, module: values.module, staged: values.staged, fast: values.fast, full: values.full, suite: values.suite })
|
|
234
|
+
const vitestArgs = positionals.slice(1)
|
|
235
|
+
const { parseShard } = await import('./commands/shard.js')
|
|
236
|
+
const shardTest = values.shard === undefined ? undefined : parseShard(values.shard)
|
|
237
|
+
if (shardTest !== undefined && values.reap === true) {
|
|
238
|
+
throw new Error('--shard cannot be combined with --reap.')
|
|
239
|
+
}
|
|
240
|
+
const { test: runTests } = await import('./commands/test.js')
|
|
241
|
+
await runTests({
|
|
242
|
+
cwd,
|
|
243
|
+
db: values.db,
|
|
244
|
+
vitestArgs,
|
|
245
|
+
scope: parsedTest.scope,
|
|
246
|
+
suite: parsedTest.suite,
|
|
247
|
+
fast: parsedTest.fast,
|
|
248
|
+
reap: values.reap,
|
|
249
|
+
shard: shardTest,
|
|
250
|
+
})
|
|
251
|
+
break
|
|
252
|
+
}
|
|
253
|
+
case 'check': {
|
|
254
|
+
const { parseScope: parseScopeCheck } = await import('./commands/scope.js')
|
|
255
|
+
const parsedCheck = parseScopeCheck({ all: values.all, module: values.module, staged: values.staged, fast: values.fast, full: values.full })
|
|
256
|
+
const { parseShard: parseShardCheck } = await import('./commands/shard.js')
|
|
257
|
+
const shardCheck = values.shard === undefined ? undefined : parseShardCheck(values.shard)
|
|
258
|
+
const { check } = await import('./commands/check.js')
|
|
259
|
+
await check(cwd, parsedCheck.scope, shardCheck)
|
|
260
|
+
break
|
|
261
|
+
}
|
|
262
|
+
case 'codemod': {
|
|
263
|
+
const { codemod } = await import('./commands/codemod.js')
|
|
264
|
+
await codemod({ cwd, dryRun: values['dry-run'] === true })
|
|
265
|
+
break
|
|
266
|
+
}
|
|
267
|
+
case 'db': {
|
|
268
|
+
const subcommand = positionals[1]
|
|
269
|
+
const { db: dbCmd } = await import('./commands/db.js')
|
|
270
|
+
await dbCmd({
|
|
271
|
+
cwd,
|
|
272
|
+
subcommand,
|
|
273
|
+
db: values.db,
|
|
274
|
+
test: values.test,
|
|
275
|
+
confirm: values.confirm,
|
|
276
|
+
adminUrl: values['admin-url'],
|
|
277
|
+
})
|
|
278
|
+
break
|
|
279
|
+
}
|
|
280
|
+
case 'alerts': {
|
|
281
|
+
const { alertsCommand } = await import('./commands/alerts.js')
|
|
282
|
+
await alertsCommand({ cwd, subcommand: positionals[1], unit: values.unit, database: values.database, maxAge: values['max-age'] })
|
|
283
|
+
break
|
|
284
|
+
}
|
|
285
|
+
case 'dev': {
|
|
286
|
+
const { dev } = await import('./commands/dev.js')
|
|
287
|
+
dev({ port: values.port, entry: values.entry, cwd })
|
|
288
|
+
break
|
|
289
|
+
}
|
|
290
|
+
case 'serve': {
|
|
291
|
+
const { serve } = await import('./commands/serve.js')
|
|
292
|
+
serve({ port: values.port, workerOnly: values['worker-only'] === true, cwd })
|
|
293
|
+
break
|
|
294
|
+
}
|
|
295
|
+
default:
|
|
296
|
+
error(`Unknown command: "${command}"`)
|
|
297
|
+
process.stderr.write(`\n Run ${bold('pipework --help')} to see available commands.\n\n`)
|
|
298
|
+
process.exit(1)
|
|
299
|
+
}
|
|
300
|
+
} catch (err) {
|
|
301
|
+
handleError(err)
|
|
302
|
+
}
|
|
303
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const BOLD = '\x1b[1m'
|
|
2
|
+
const RED = '\x1b[31m'
|
|
3
|
+
const GREEN = '\x1b[32m'
|
|
4
|
+
const YELLOW = '\x1b[33m'
|
|
5
|
+
const CYAN = '\x1b[36m'
|
|
6
|
+
const RESET = '\x1b[0m'
|
|
7
|
+
|
|
8
|
+
export function bold(text: string): string { return `${BOLD}${text}${RESET}` }
|
|
9
|
+
export function red(text: string): string { return `${RED}${text}${RESET}` }
|
|
10
|
+
export function green(text: string): string { return `${GREEN}${text}${RESET}` }
|
|
11
|
+
export function yellow(text: string): string { return `${YELLOW}${text}${RESET}` }
|
|
12
|
+
export function cyan(text: string): string { return `${CYAN}${text}${RESET}` }
|
|
13
|
+
|
|
14
|
+
export function info(msg: string): void { process.stderr.write(`${cyan('ℹ')} ${msg}\n`) }
|
|
15
|
+
export function success(msg: string): void { process.stderr.write(`${green('✓')} ${msg}\n`) }
|
|
16
|
+
export function warn(msg: string): void { process.stderr.write(`${yellow('⚠')} ${msg}\n`) }
|
|
17
|
+
export function error(msg: string): void { process.stderr.write(`${red('✗')} ${msg}\n`) }
|
package/src/cli/port.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ConfigError } from '../core/config/errors.js'
|
|
2
|
+
|
|
3
|
+
/** Parses the PORT variable: unset or empty is no port; otherwise an integer 0-65535. */
|
|
4
|
+
export function parsePort(value: string | undefined): number | undefined {
|
|
5
|
+
if (value === undefined || value.trim() === '') return undefined
|
|
6
|
+
const text = value.trim()
|
|
7
|
+
const n = Number(text)
|
|
8
|
+
if (!/^\d+$/.test(text) || !Number.isInteger(n) || n > 65535) {
|
|
9
|
+
throw new ConfigError(
|
|
10
|
+
`PORT is "${value}", which is not a port number.`,
|
|
11
|
+
'Set PORT to an integer from 0 to 65535, or unset it.',
|
|
12
|
+
)
|
|
13
|
+
}
|
|
14
|
+
return n
|
|
15
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ConfigError } from '../core/config/errors.js'
|
|
2
|
+
import type { SurfaceKind } from '../core/surface/types.js'
|
|
3
|
+
|
|
4
|
+
export const SURFACE_KINDS_ENV = 'PIPEWORK_SURFACE_KINDS'
|
|
5
|
+
|
|
6
|
+
const KINDS: readonly SurfaceKind[] = ['http', 'worker', 'script']
|
|
7
|
+
|
|
8
|
+
/** Parses PIPEWORK_SURFACE_KINDS, a comma list of surface kinds: unset or empty is every kind; an unknown kind is an error. */
|
|
9
|
+
export function parseSurfaceKinds(value: string | undefined): readonly SurfaceKind[] | undefined {
|
|
10
|
+
if (value === undefined || value.trim() === '') return undefined
|
|
11
|
+
const parts = value.split(',').map(p => p.trim()).filter(p => p !== '')
|
|
12
|
+
const bad = parts.filter(p => !(KINDS as readonly string[]).includes(p))
|
|
13
|
+
if (bad.length > 0 || parts.length === 0) {
|
|
14
|
+
throw new ConfigError(
|
|
15
|
+
`${SURFACE_KINDS_ENV} is "${value}"; ${bad.map(b => `"${b}"`).join(', ') || 'no kind'} is not a surface kind.`,
|
|
16
|
+
`Set ${SURFACE_KINDS_ENV} to a comma list of: ${KINDS.join(', ')}, or unset it.`,
|
|
17
|
+
)
|
|
18
|
+
}
|
|
19
|
+
return [...new Set(parts)] as SurfaceKind[]
|
|
20
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { reportClientFault, pageLeaving, LEAVING_HOLD_MS, CLIENT_FAULT_MESSAGE_MAX, CLIENT_FAULT_STACK_MAX } from './report-fault.js'
|
|
2
|
+
export type { ClientFaultReport, ReportClientFaultOptions } from './report-fault.js'
|
|
3
|
+
export { startPolling, waitFromResponse } from './poll.js'
|
|
4
|
+
export type { PollingOptions, PollingPage, PollAnswer } from './poll.js'
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
// Browser-safe: no node imports, no runtime dependencies.
|
|
2
|
+
|
|
3
|
+
/** What an ask may return to slow the next one: the next wait is at least `atLeastMs`. */
|
|
4
|
+
export type PollAnswer = { atLeastMs: number } | void
|
|
5
|
+
|
|
6
|
+
/** The part of `document` the poller uses. */
|
|
7
|
+
export interface PollingPage {
|
|
8
|
+
readonly hidden: boolean
|
|
9
|
+
addEventListener(type: 'visibilitychange', listener: () => void): void
|
|
10
|
+
removeEventListener(type: 'visibilitychange', listener: () => void): void
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface PollingOptions {
|
|
14
|
+
/** First wait in ms, before the first ask. Default 3000. */
|
|
15
|
+
firstMs?: number
|
|
16
|
+
/** Each wait is the last times `backOff`, up to this. Default 10000. */
|
|
17
|
+
longestMs?: number
|
|
18
|
+
/** At least 1; 1 is a fixed interval. Default 1.5. */
|
|
19
|
+
backOff?: number
|
|
20
|
+
/** Default true: nothing is asked while the page is hidden; visible again asks at once and the waits restart from `firstMs`. */
|
|
21
|
+
pauseWhenHidden?: boolean
|
|
22
|
+
/** An ask that throws or rejects stops nothing; the error is passed here and the next ask is scheduled. */
|
|
23
|
+
onError?: (error: unknown) => void
|
|
24
|
+
/** Default `document` when there is one. */
|
|
25
|
+
page?: PollingPage
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function check(name: string, ok: boolean, rule: string, value: unknown): void {
|
|
29
|
+
if (!ok) throw new Error(`[pipework] startPolling: ${name} must be ${rule}, got ${String(value)}.`)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Calls `ask` after `firstMs`, then again after each answer, waiting longer each time (`backOff`, up to `longestMs`).
|
|
34
|
+
* One ask at a time: the next wait starts when the last ask settled. An ask returning `{ atLeastMs }` makes the next
|
|
35
|
+
* wait at least that long; the back-off carries on as if it had not. While the page is hidden nothing is asked.
|
|
36
|
+
* Returns `stop`, which is idempotent; an ask still in flight when it is called schedules nothing and reports no error.
|
|
37
|
+
*/
|
|
38
|
+
export function startPolling(ask: () => Promise<PollAnswer>, options: PollingOptions = {}): () => void {
|
|
39
|
+
const firstMs = options.firstMs ?? 3000
|
|
40
|
+
const longestMs = options.longestMs ?? 10_000
|
|
41
|
+
const backOff = options.backOff ?? 1.5
|
|
42
|
+
check('firstMs', Number.isFinite(firstMs) && firstMs >= 0, 'a non-negative finite number of ms', firstMs)
|
|
43
|
+
check('longestMs', Number.isFinite(longestMs) && longestMs >= 0, 'a non-negative finite number of ms', longestMs)
|
|
44
|
+
check('backOff', Number.isFinite(backOff) && backOff >= 1, 'a finite number of at least 1', backOff)
|
|
45
|
+
check('firstMs', firstMs <= longestMs, `at most longestMs (${longestMs})`, firstMs)
|
|
46
|
+
|
|
47
|
+
const page = options.page ?? (globalThis as { document?: PollingPage }).document
|
|
48
|
+
const watched = options.pauseWhenHidden !== false ? page : undefined
|
|
49
|
+
|
|
50
|
+
let stopped = false
|
|
51
|
+
let inFlight = false
|
|
52
|
+
let timer: ReturnType<typeof setTimeout> | undefined
|
|
53
|
+
let base = firstMs
|
|
54
|
+
|
|
55
|
+
const nextWait = (): number => {
|
|
56
|
+
const wait = base
|
|
57
|
+
base = Math.min(base * backOff, longestMs)
|
|
58
|
+
return wait
|
|
59
|
+
}
|
|
60
|
+
const clear = (): void => {
|
|
61
|
+
if (timer !== undefined) clearTimeout(timer)
|
|
62
|
+
timer = undefined
|
|
63
|
+
}
|
|
64
|
+
const schedule = (ms: number): void => {
|
|
65
|
+
clear()
|
|
66
|
+
timer = setTimeout(due, ms)
|
|
67
|
+
}
|
|
68
|
+
const due = (): void => {
|
|
69
|
+
timer = undefined
|
|
70
|
+
if (stopped || watched?.hidden === true) return
|
|
71
|
+
void run()
|
|
72
|
+
}
|
|
73
|
+
const run = async (): Promise<void> => {
|
|
74
|
+
inFlight = true
|
|
75
|
+
let answer: { atLeastMs: number } | undefined
|
|
76
|
+
try {
|
|
77
|
+
answer = (await ask()) ?? undefined
|
|
78
|
+
} catch (error) {
|
|
79
|
+
if (!stopped) options.onError?.(error)
|
|
80
|
+
}
|
|
81
|
+
inFlight = false
|
|
82
|
+
if (stopped) return
|
|
83
|
+
const atLeast = answer !== undefined && Number.isFinite(answer.atLeastMs) ? answer.atLeastMs : 0
|
|
84
|
+
schedule(Math.max(nextWait(), atLeast))
|
|
85
|
+
}
|
|
86
|
+
const onVisibility = (): void => {
|
|
87
|
+
if (stopped || watched === undefined || watched.hidden) return
|
|
88
|
+
clear()
|
|
89
|
+
base = firstMs
|
|
90
|
+
if (!inFlight) void run()
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
watched?.addEventListener('visibilitychange', onVisibility)
|
|
94
|
+
schedule(nextWait())
|
|
95
|
+
|
|
96
|
+
return () => {
|
|
97
|
+
if (stopped) return
|
|
98
|
+
stopped = true
|
|
99
|
+
clear()
|
|
100
|
+
watched?.removeEventListener('visibilitychange', onVisibility)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function fromHeader(value: string | null): number | undefined {
|
|
105
|
+
if (value === null) return undefined
|
|
106
|
+
const text = value.trim()
|
|
107
|
+
if (/^\d+$/.test(text)) return Number(text) * 1000
|
|
108
|
+
const at = Date.parse(text)
|
|
109
|
+
return Number.isNaN(at) ? undefined : Math.max(0, at - Date.now())
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* For a 429 or 503: how long the server asked the client to wait, as `{ atLeastMs }` to return from an ask.
|
|
114
|
+
* Reads `Retry-After` (seconds or an HTTP date); when that is absent or unreadable (a cross-origin page cannot see it
|
|
115
|
+
* without CORS `exposedHeaders`), reads `error.retryAfterSeconds` from the JSON body. The response's own body stays unread.
|
|
116
|
+
* Any other status, or no wait found, gives undefined.
|
|
117
|
+
*/
|
|
118
|
+
export async function waitFromResponse(response: Response): Promise<{ atLeastMs: number } | undefined> {
|
|
119
|
+
if (response.status !== 429 && response.status !== 503) return undefined
|
|
120
|
+
const fromHead = fromHeader(response.headers.get('retry-after'))
|
|
121
|
+
if (fromHead !== undefined) return { atLeastMs: fromHead }
|
|
122
|
+
try {
|
|
123
|
+
const body = (await response.clone().json()) as { error?: { retryAfterSeconds?: unknown } } | null
|
|
124
|
+
const seconds = body?.error?.retryAfterSeconds
|
|
125
|
+
if (typeof seconds === 'number' && Number.isFinite(seconds) && seconds >= 0) return { atLeastMs: seconds * 1000 }
|
|
126
|
+
} catch {
|
|
127
|
+
// no readable body
|
|
128
|
+
}
|
|
129
|
+
return undefined
|
|
130
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
// Browser-safe: no node imports, no runtime dependencies.
|
|
2
|
+
|
|
3
|
+
/** A failure the browser reports to the route made by `alerts.clientFaults`. */
|
|
4
|
+
export interface ClientFaultReport {
|
|
5
|
+
/** A key of the route's `apps`. */
|
|
6
|
+
app: string
|
|
7
|
+
/** Where it happened: 1-100 characters of `A-Za-z0-9._:/-`, e.g. `checkout`. */
|
|
8
|
+
where: string
|
|
9
|
+
kind: 'error' | 'rejection' | 'render' | 'request'
|
|
10
|
+
/** Default `error`; a browser cannot raise `critical`. */
|
|
11
|
+
severity?: 'warning' | 'error'
|
|
12
|
+
/** At most 100 characters. */
|
|
13
|
+
code?: string
|
|
14
|
+
/** 1-500 characters; longer is cut by `reportClientFault`. */
|
|
15
|
+
message: string
|
|
16
|
+
/** At most 4096 characters; longer is cut by `reportClientFault`. */
|
|
17
|
+
stack?: string
|
|
18
|
+
/** A route pattern such as `/orders/:id`, at most 200 characters; never a page URL (no `?`, `#` or `://`). */
|
|
19
|
+
route?: string
|
|
20
|
+
/** At most 100 characters. */
|
|
21
|
+
release?: string
|
|
22
|
+
/** The trace id the page last saw: the `x-pipework-trace-id` header of an answer (expose it with CORS `exposedHeaders`). */
|
|
23
|
+
traceId?: string
|
|
24
|
+
/** The `x-request-id` of the answer the page last saw. At most 100 characters of `A-Za-z0-9._:-`. */
|
|
25
|
+
requestId?: string
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const CLIENT_FAULT_MESSAGE_MAX = 500
|
|
29
|
+
export const CLIENT_FAULT_STACK_MAX = 4096
|
|
30
|
+
|
|
31
|
+
/** How long a report made after `beforeunload` is held waiting for `pagehide` before the page is taken to be staying. */
|
|
32
|
+
export const LEAVING_HOLD_MS = 10_000
|
|
33
|
+
|
|
34
|
+
export interface ReportClientFaultOptions {
|
|
35
|
+
/** Default `hold`: a report made while the page is leaving waits, and is dropped if the page goes. `send` sends at once (a save cut off by leaving). */
|
|
36
|
+
whileLeaving?: 'hold' | 'send'
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
let leaving = false
|
|
40
|
+
let left = false
|
|
41
|
+
let timer: ReturnType<typeof setTimeout> | undefined
|
|
42
|
+
let held: Array<() => void> = []
|
|
43
|
+
|
|
44
|
+
function clearHold(): void {
|
|
45
|
+
if (timer !== undefined) clearTimeout(timer)
|
|
46
|
+
timer = undefined
|
|
47
|
+
held = []
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function stay(): void {
|
|
51
|
+
const pending = held
|
|
52
|
+
leaving = false
|
|
53
|
+
left = false
|
|
54
|
+
if (timer !== undefined) clearTimeout(timer)
|
|
55
|
+
timer = undefined
|
|
56
|
+
held = []
|
|
57
|
+
for (const send of pending) send()
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const win = globalThis as unknown as {
|
|
61
|
+
addEventListener?: (type: string, listener: (event: { persisted?: boolean }) => void, options?: { passive: boolean }) => void
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (typeof win.addEventListener === 'function') {
|
|
65
|
+
win.addEventListener('beforeunload', () => {
|
|
66
|
+
leaving = true
|
|
67
|
+
if (timer !== undefined) clearTimeout(timer)
|
|
68
|
+
timer = setTimeout(stay, LEAVING_HOLD_MS)
|
|
69
|
+
}, { passive: true })
|
|
70
|
+
win.addEventListener('pagehide', () => {
|
|
71
|
+
leaving = true
|
|
72
|
+
left = true
|
|
73
|
+
clearHold()
|
|
74
|
+
}, { passive: true })
|
|
75
|
+
win.addEventListener('pageshow', (event) => {
|
|
76
|
+
if (event.persisted === true) stay()
|
|
77
|
+
}, { passive: true })
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** True from `beforeunload` until the page stays again (the hold timer ran out or a bfcache restore); stays true after `pagehide`. */
|
|
81
|
+
export function pageLeaving(): boolean {
|
|
82
|
+
return leaving
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Sends a failure to the intake route at `url` with `keepalive`, so it survives a page unload.
|
|
87
|
+
* Cuts `message` and `stack` to their caps. A report made while the page is leaving is held and dropped on `pagehide`,
|
|
88
|
+
* unless `options.whileLeaving` is `send`. Never throws and never rejects: a report that cannot be sent is dropped.
|
|
89
|
+
*/
|
|
90
|
+
export function reportClientFault(url: string, report: ClientFaultReport, options?: ReportClientFaultOptions): void {
|
|
91
|
+
try {
|
|
92
|
+
const body: ClientFaultReport = { ...report, message: report.message.slice(0, CLIENT_FAULT_MESSAGE_MAX) }
|
|
93
|
+
if (body.stack !== undefined) body.stack = body.stack.slice(0, CLIENT_FAULT_STACK_MAX)
|
|
94
|
+
const send = (): void => {
|
|
95
|
+
try {
|
|
96
|
+
const sent = fetch(url, {
|
|
97
|
+
method: 'POST',
|
|
98
|
+
keepalive: true,
|
|
99
|
+
credentials: 'include',
|
|
100
|
+
headers: { 'content-type': 'application/json' },
|
|
101
|
+
body: JSON.stringify(body),
|
|
102
|
+
})
|
|
103
|
+
Promise.resolve(sent).catch(() => undefined)
|
|
104
|
+
} catch {
|
|
105
|
+
// dropped
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (options?.whileLeaving !== 'send') {
|
|
109
|
+
if (left) return
|
|
110
|
+
if (leaving) {
|
|
111
|
+
held.push(send)
|
|
112
|
+
return
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
send()
|
|
116
|
+
} catch {
|
|
117
|
+
// dropped
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { IsolationStrategy } from './schema.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Whether the test harness ever creates the app-role pool under `strategy`.
|
|
5
|
+
*
|
|
6
|
+
* Transaction isolation registers its single rolled-back connection as the pool
|
|
7
|
+
* override under the database's *base* key (`src/test/plugin.ts`), and
|
|
8
|
+
* `getOrCreate(config, 'app')` falls back to that base override when no
|
|
9
|
+
* role-specific one is registered (`src/core/pipework.ts`) — so the app-role
|
|
10
|
+
* pool is never constructed and `appUrl`/`appTestUrl` are never dialed by it.
|
|
11
|
+
* Every other strategy resolves roles normally (`appUrl ?? url`) and creates it.
|
|
12
|
+
*
|
|
13
|
+
* This is the single statement of that fact: both the app-pair value-identity
|
|
14
|
+
* carve-out (`resolveDbUrl`) and the RLS probe target (`rlsProbeTarget`) are
|
|
15
|
+
* expressed in terms of it, so the two cannot drift apart.
|
|
16
|
+
*/
|
|
17
|
+
export function appPoolCreated(strategy: IsolationStrategy): boolean {
|
|
18
|
+
return strategy !== 'transaction'
|
|
19
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** The environment variables AWS credential discovery reads. Empty strings count as unset. */
|
|
2
|
+
export interface AwsEnv {
|
|
3
|
+
readonly AWS_ACCESS_KEY_ID: string | undefined
|
|
4
|
+
readonly AWS_SECRET_ACCESS_KEY: string | undefined
|
|
5
|
+
readonly AWS_SESSION_TOKEN: string | undefined
|
|
6
|
+
readonly AWS_CONTAINER_CREDENTIALS_RELATIVE_URI: string | undefined
|
|
7
|
+
readonly AWS_CONTAINER_CREDENTIALS_FULL_URI: string | undefined
|
|
8
|
+
readonly AWS_CONTAINER_AUTHORIZATION_TOKEN: string | undefined
|
|
9
|
+
readonly AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE: string | undefined
|
|
10
|
+
readonly AWS_EC2_METADATA_DISABLED: string | undefined
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** Reads the AWS variables now; called on every resolve, never at import. */
|
|
14
|
+
export function readAwsEnv(): AwsEnv {
|
|
15
|
+
const get = (name: string): string | undefined => {
|
|
16
|
+
const v = process.env[name]
|
|
17
|
+
return v === undefined || v === '' ? undefined : v
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
AWS_ACCESS_KEY_ID: get('AWS_ACCESS_KEY_ID'),
|
|
21
|
+
AWS_SECRET_ACCESS_KEY: get('AWS_SECRET_ACCESS_KEY'),
|
|
22
|
+
AWS_SESSION_TOKEN: get('AWS_SESSION_TOKEN'),
|
|
23
|
+
AWS_CONTAINER_CREDENTIALS_RELATIVE_URI: get('AWS_CONTAINER_CREDENTIALS_RELATIVE_URI'),
|
|
24
|
+
AWS_CONTAINER_CREDENTIALS_FULL_URI: get('AWS_CONTAINER_CREDENTIALS_FULL_URI'),
|
|
25
|
+
AWS_CONTAINER_AUTHORIZATION_TOKEN: get('AWS_CONTAINER_AUTHORIZATION_TOKEN'),
|
|
26
|
+
AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE: get('AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE'),
|
|
27
|
+
AWS_EC2_METADATA_DISABLED: get('AWS_EC2_METADATA_DISABLED'),
|
|
28
|
+
}
|
|
29
|
+
}
|