pipework 0.15.0 → 0.17.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.
Files changed (97) hide show
  1. package/CHANGELOG.md +27 -1
  2. package/REFERENCE.md +191 -2
  3. package/dist/cli/commands/generate.d.ts.map +1 -1
  4. package/dist/cli/commands/generate.js +12 -10
  5. package/dist/cli/commands/generate.js.map +1 -1
  6. package/dist/core/config/base-dir.d.ts +6 -0
  7. package/dist/core/config/base-dir.d.ts.map +1 -0
  8. package/dist/core/config/base-dir.js +21 -0
  9. package/dist/core/config/base-dir.js.map +1 -0
  10. package/dist/core/config/discover.d.ts.map +1 -1
  11. package/dist/core/config/discover.js +2 -15
  12. package/dist/core/config/discover.js.map +1 -1
  13. package/dist/core/config/env-types.d.ts +70 -0
  14. package/dist/core/config/env-types.d.ts.map +1 -1
  15. package/dist/core/config/env.d.ts.map +1 -1
  16. package/dist/core/config/env.js +10 -6
  17. package/dist/core/config/env.js.map +1 -1
  18. package/dist/core/config/import-config.d.ts +3 -0
  19. package/dist/core/config/import-config.d.ts.map +1 -0
  20. package/dist/core/config/import-config.js +34 -0
  21. package/dist/core/config/import-config.js.map +1 -0
  22. package/dist/core/config/load.d.ts +7 -0
  23. package/dist/core/config/load.d.ts.map +1 -1
  24. package/dist/core/config/load.js +15 -5
  25. package/dist/core/config/load.js.map +1 -1
  26. package/dist/core/config/namespace.d.ts +1 -0
  27. package/dist/core/config/namespace.d.ts.map +1 -1
  28. package/dist/core/config/resolve.d.ts.map +1 -1
  29. package/dist/core/config/resolve.js +23 -1
  30. package/dist/core/config/resolve.js.map +1 -1
  31. package/dist/core/config/schema.d.ts +3 -0
  32. package/dist/core/config/schema.d.ts.map +1 -1
  33. package/dist/core/config/schema.js +7 -0
  34. package/dist/core/config/schema.js.map +1 -1
  35. package/dist/core/config/statement-observer.d.ts +48 -0
  36. package/dist/core/config/statement-observer.d.ts.map +1 -0
  37. package/dist/core/config/statement-observer.js +2 -0
  38. package/dist/core/config/statement-observer.js.map +1 -0
  39. package/dist/core/pipework.d.ts +19 -0
  40. package/dist/core/pipework.d.ts.map +1 -1
  41. package/dist/core/pipework.js +25 -0
  42. package/dist/core/pipework.js.map +1 -1
  43. package/dist/core/surface/types.d.ts +1 -0
  44. package/dist/core/surface/types.d.ts.map +1 -1
  45. package/dist/core/validation/queue-tables.d.ts +8 -0
  46. package/dist/core/validation/queue-tables.d.ts.map +1 -0
  47. package/dist/core/validation/queue-tables.js +53 -0
  48. package/dist/core/validation/queue-tables.js.map +1 -0
  49. package/dist/core/validation/rls-role.d.ts +16 -0
  50. package/dist/core/validation/rls-role.d.ts.map +1 -0
  51. package/dist/core/validation/rls-role.js +54 -0
  52. package/dist/core/validation/rls-role.js.map +1 -0
  53. package/dist/core/validation/startup.d.ts +2 -0
  54. package/dist/core/validation/startup.d.ts.map +1 -1
  55. package/dist/core/validation/startup.js +6 -0
  56. package/dist/core/validation/startup.js.map +1 -1
  57. package/dist/data/db/instrumentation.d.ts +17 -1
  58. package/dist/data/db/instrumentation.d.ts.map +1 -1
  59. package/dist/data/db/instrumentation.js +31 -1
  60. package/dist/data/db/instrumentation.js.map +1 -1
  61. package/dist/data/db/pool.d.ts +16 -0
  62. package/dist/data/db/pool.d.ts.map +1 -1
  63. package/dist/data/db/pool.js +18 -2
  64. package/dist/data/db/pool.js.map +1 -1
  65. package/dist/data/db/raw-client-warning.d.ts +19 -0
  66. package/dist/data/db/raw-client-warning.d.ts.map +1 -0
  67. package/dist/data/db/raw-client-warning.js +32 -0
  68. package/dist/data/db/raw-client-warning.js.map +1 -0
  69. package/dist/data/migrate/generate.d.ts +1 -1
  70. package/dist/data/migrate/generate.d.ts.map +1 -1
  71. package/dist/data/migrate/generate.js +15 -8
  72. package/dist/data/migrate/generate.js.map +1 -1
  73. package/dist/data/query/postgres-js/driver-error-boundary.d.ts +47 -0
  74. package/dist/data/query/postgres-js/driver-error-boundary.d.ts.map +1 -0
  75. package/dist/data/query/postgres-js/driver-error-boundary.js +144 -0
  76. package/dist/data/query/postgres-js/driver-error-boundary.js.map +1 -0
  77. package/dist/data/query/postgres-js/session.d.ts.map +1 -1
  78. package/dist/data/query/postgres-js/session.js +15 -12
  79. package/dist/data/query/postgres-js/session.js.map +1 -1
  80. package/dist/index.d.ts +1 -0
  81. package/dist/index.d.ts.map +1 -1
  82. package/dist/index.js.map +1 -1
  83. package/dist/lint/resolver.d.ts.map +1 -1
  84. package/dist/lint/resolver.js +2 -11
  85. package/dist/lint/resolver.js.map +1 -1
  86. package/dist/test/plugin.d.ts +2 -1
  87. package/dist/test/plugin.d.ts.map +1 -1
  88. package/dist/test/plugin.js +13 -5
  89. package/dist/test/plugin.js.map +1 -1
  90. package/dist/test/setup.d.ts.map +1 -1
  91. package/dist/test/setup.js +33 -0
  92. package/dist/test/setup.js.map +1 -1
  93. package/dist/test/vitest-workspace.d.ts.map +1 -1
  94. package/dist/test/vitest-workspace.js +2 -11
  95. package/dist/test/vitest-workspace.js.map +1 -1
  96. package/package.json +1 -1
  97. package/dist/REFERENCE.md +0 -1033
package/CHANGELOG.md CHANGED
@@ -1,6 +1,32 @@
1
1
  # Changelog
2
2
 
3
- ## 0.15.0
3
+ ## 0.17.0
4
+
5
+ - **Feature: `observability.onStatement` — a caller-supplied observer that fires once per statement written to the wire, on every connection the manifold owns.** The callback receives `{ connectionId, query, parameters }` and is pure observation: the return value is discarded, the statement is never mutated, and nothing is installed when the option is unset. It exists for exact wire-level statement accounting, which no application-level hook can do — the driver issues its own `BEGIN`/`SAVEPOINT`/`COMMIT`/`ROLLBACK`, and those are observed too.
6
+ - **Honored on both connection arms.** Pooled connections (`createManagedConnection`) *and* the test harness's own connections — both the per-test rolled-back connection and the setup connection behind `useSetupDb()`. The test harness builds its postgres.js clients directly rather than through the pool, so a config-only hook would have been silently dead under `pipework test`; that arm is wired explicitly and covered by its own tests.
7
+ - **Composes with `logAllQueries`.** Either alone installs the driver hook; with both configured both fire. Query logging keeps its 500-character truncation; the observer receives the query untruncated, because a counter must not see mangled SQL.
8
+ - **`connectionId` is the driver's process-local connection ordinal, not the PostgreSQL backend pid.** Unique and stable per connection for that connection's lifetime within the process, meaningless across processes. Correct for per-connection accounting — every statement of one transaction carries the same id, which is asserted by a test — and wrong for correlating with `pg_stat_activity`.
9
+ - **Counts wire truth, not application intent.** Two things a total will include that callers should expect: driver-issued transaction control, and one `pg_catalog.pg_type` lookup per connection the first time that connection is used.
10
+ - Admitted through zod with `z.custom`, deliberately not `z.function()` — in zod 4 the latter returns a validating wrapper, so the parsed value is not the function the caller passed (identity is lost) and every call pays argument validation, on a hook that fires once per statement.
11
+
12
+ - **Observation adds no leak surface: a driver error boundary keeps the observer from widening what query errors serialize.** postgres.js defines `stack`/`query`/`parameters`/`args`/`types` on every query error and marks them **enumerable** exactly when its `debug` option is truthy — and installing an observer requires turning `debug` on. Without a boundary, merely observing statements would start leaking bind parameters into every log drain that serializes errors. Errors from observed connections are now put back to their unobserved shape: observed and unobserved errors have identical own-key sets, and the values stay reachable by property access so debugging is unaffected. `instanceof`, `message`, `code` and every server field survive. Applies to every statement path pipework mediates — `pipe()`, every `pipe.*` write, `connection.drizzle`, transactions and savepoints. `logAllQueries: true` is untouched and behaves exactly as before; that mode already opted into verbose errors.
13
+ - **The one gap, deliberate and announced: `ManagedConnection.client`.** The raw driver door stays raw — that is what it is for — so queries issued through it are outside the boundary and their errors do serialize bind parameters. Reading `.client` on an observed connection now logs a warning saying so, once per database, and the contract is stated on `StatementObserver` and on `ManagedConnection.client`.
14
+ - **Wrapping the `Sql` client to close that gap was considered and rejected.** It would mean proxying a callable tagged-template whose `begin`/`savepoint` hand out fresh client instances needing recursive re-wrapping, on the hottest path in the system — more risk than the narrow, documented gap it closes. Recorded here so it is not re-proposed as cleanup.
15
+
16
+ - **Fix: the migration safety tests no longer depend on a virgin database.** `migrateOne` integration tests assert on hazards in *pending* migrations, but their migration tags are fixed while the tracker outlives the run — so from the second run onward those tags read as already-applied, dropped out of the pending set, and `hasDestructive` flipped to false. The tracker is now dropped before each of those tests. (Surfaced by 0.16.0's move to tag membership; under the old timestamp high-water mark the stale rows were inert.)
17
+
18
+ - **Fix: `docker-compose.test.yml`'s published port is parameterized (`PIPEWORK_TEST_PORT`, default 5432).** Where 5432 is already held, compose silently failed to publish and the suite ran against whatever else answered there — which matters because the harness creates and drops databases and provisions BYPASSRLS fixture roles, so it must talk to a disposable cluster where its own role is the superuser. Stock machines are unaffected.
19
+
20
+ ## 0.16.0
21
+
22
+ - **Fix: a queue registered by a module reached only through the schema glob now makes it into `pipework generate`'s output.** The CLI used to snapshot internal definitions (including registered queues) *before* the schema files were imported, so a `createQueue()` living in a glob-matched module — with no side-effect import in the config — was silently dropped from the migration, and consumers worked around it by importing the queue module from `pipework.config.ts`. Internal definitions are now collected after the schema-file imports. Breaking for API consumers: `generateForDatabase`'s `internalDefinitions` parameter is now a thunk (`() => Promise<Record<string, unknown>>`).
23
+ - **Feature: a registered queue whose table is missing from the database is now a loud, actionable failure at startup and at test bootstrap — not a crash at first insert.** Startup validation (`pipework serve`/`dev`, `manifold.start()`) and the test harness's template provisioning both verify every `createQueue()`-registered table exists in the default database (`to_regclass` probe), and refuse with a message naming the table, the schema-glob rule, and the fix (`pipework generate`, then `pipework migrate`).
24
+ - **Behavior change: a database whose `testUrl` resolves to the same connection string as its `url` is refused at config resolution in the test environment.** Identical values mean "tests" run against the real database: the test harness creates/drops databases and rolls back transactions on what it assumes is a dedicated instance, and RLS-inertness goes unnoticed — with zero signal from the framework. The refusal names both env vars and the fix (point the test var at a separate database); `testUrl` naming the *same env var* as `url` is reported as its own case. Applies to both the url/testUrl and appUrl/appTestUrl pairs.
25
+ - **Fix: `pipework generate` surfaces the real config-load error instead of misreporting every failure as "No pipework.config.ts found".**
26
+ - **Behavior change: a database with `rls` configured whose runtime role is SUPERUSER or BYPASSRLS now fails startup validation and test bootstrap.** RLS policies never apply to such a role, so the entire tenant-isolation policy set is silently inert — the framework now says so, naming the database, the role, the flag, and the fix (provision a non-bypassing application role; point the runtime connection at it). At startup the probed connection is `appUrl ?? url`; at test bootstrap it is the connection tests actually execute on — transaction isolation collapses every role onto the resolved `url`, database/container isolation resolves roles normally. Consumers whose test role is the compose superuser are refused until they provision a non-bypassing test role — deliberate: that is exactly the world where an RLS test suite proves nothing.
27
+ - **Feature: `.env.local` and `.env.test.local` are loaded alongside `.env`/`.env.test`, with the `.local` (machine-local, never-committed) variant taking precedence** — the standard dotenv convention.
28
+ - **Docs: the `env` config field is now a first-class section in REFERENCE.md** — every declaration shape (`string`/`number`/`boolean`/`string[]`), `required`/`default`/per-environment `defaults`/`sensitive`, typed `manifold.env` access, and a complete `createManifold` example. Previously it appeared only inside a type signature, leaving the feature undiscoverable while consumers accumulated ad-hoc `process.env` reads. The reference generator now renders multi-line JSDoc and `@example` blocks as fenced code instead of flattening them to one line.
29
+ - **Behavior change: relative `migrations`/`schema` paths now resolve against the directory of `pipework.config.ts`, never against the process working directory.** Previously every consumer of these fields (`pipework generate`, `pipework migrate`'s safety gate, test template provisioning) resolved them against cwd — so `pnpm --filter <module> test` (which cd's into the module) failed at `beforeAll` with "No migration journal found", and the only workaround was hand-absolutizing the paths with `import.meta.url`. `ResolvedDatabase.migrations` is now absolute (resolved once, at config load), `ResolvedDatabase` carries the new `baseDir` field (the config file's directory), and schema globs are matched against `baseDir`. Already-absolute consumer paths are unchanged (`resolve(base, abs) === abs`). Breaking for API consumers: `generateForDatabase` loses its `cwd` parameter — the resolved config is the single source of path truth.
4
30
 
5
31
  - **Fix: the migration tracker now records WHICH migrations have been applied (tag membership), replacing the `max(created_at)` timestamp high-water mark that silently skipped any unapplied migration dated earlier than the newest applied one.** Two real production hits of the old model: (1) two manifolds sharing one physical database under the same tracker table name (both declared database key `app`) — the second manifold's entire journal predated the first's newest entry, so its migrations were silently skipped and its schema never materialized; (2) a migration merged from a branch with an earlier date than migrations already applied was silently skipped ("relation does not exist" at runtime, in CI). The tracker table gains a `tag` column (unique) and `applyMigrations` decides "already applied" by membership: tag recorded → skip (after verifying the recorded content hash still matches — see below), tag absent → apply, in journal order. Existing deployed tracker tables are upgraded in place on the next `migrate`: the `tag` column is added and each legacy row's identity is recovered by matching its recorded content hash against the journal's files; rows matching no current journal entry keep a NULL tag and never participate in membership.
6
32
  - **Fix: editing an already-applied migration file is now a loud error instead of silently ignored.** Membership verifies the recorded sha256 against the file: a tag recorded with a different hash aborts with an error naming the migration, the two hashes, and the fix (put schema changes in a NEW migration; if two manifolds share a database and collide on a tag, that is a schema-level collision no tracker can reconcile — separate databases or distinct `migrationTable` names).
package/REFERENCE.md CHANGED
@@ -1,11 +1,12 @@
1
1
  # Pipework API Reference
2
2
 
3
3
  > Auto-generated from source JSDoc. Do not edit manually.
4
- > Generated: 2026-06-29
4
+ > Generated: 2026-07-19
5
5
 
6
6
  ## Contents
7
7
 
8
8
  - [Core](#core)
9
+ - [env — Environment Variables](#env-environment-variables)
9
10
  - [jobs — Background Jobs](#jobs-background-jobs)
10
11
  - [pipeline — Multi-Step Pipelines](#pipeline-multi-step-pipelines)
11
12
  - [state — State Machines](#state-state-machines)
@@ -33,6 +34,7 @@
33
34
  - [http — Server](#http-server)
34
35
  - [openapi — API Documentation](#openapi-api-documentation)
35
36
  - [test](#test)
37
+ - [data](#data)
36
38
  - [trace](#trace)
37
39
 
38
40
  ## Core
@@ -41,7 +43,29 @@ Application instance and foundational types.
41
43
 
42
44
  ### `createManifold`
43
45
 
44
- Creates the Pipework application instance. This is the entry point for every Pipework app. Define in `pipework.config.ts` and export as default. /
46
+ Creates the Pipework application instance. This is the entry point for every Pipework app.
47
+ Define in `pipework.config.ts` and export as default.
48
+
49
+ The `env` field declares the app's environment variables — the canonical
50
+ home for runtime config (ports, service tokens, bucket names, flags) in
51
+ place of scattered `process.env` reads. Each variable is read once at config
52
+ load, validated and coerced to its declared type (loud error on a bad or
53
+ missing-required value), and exposed typed on `manifold.env`.
54
+
55
+
56
+ ```typescript
57
+ const manifold = createManifold({
58
+ databases: { app: { url: 'DATABASE_URL', testUrl: 'DATABASE_URL_TEST' } },
59
+ env: {
60
+ PORT: { type: 'number', defaults: { development: '3000', test: '0' } },
61
+ S3_BUCKET: { type: 'string', required: true },
62
+ API_TOKEN: { type: 'string', required: true, sensitive: true },
63
+ },
64
+ })
65
+ manifold.env.PORT // number — from process.env.PORT, or the per-environment default
66
+ manifold.env.S3_BUCKET // string — startup fails loudly if unset
67
+ export default manifold
68
+ ```
45
69
 
46
70
  ```typescript
47
71
  function createManifold<const TEnv extends EnvDefs = EnvDefs>( raw: Omit<BlueprintInput, 'env'> &
@@ -79,6 +103,114 @@ interface IsolationState
79
103
  interface ConnectionTracker
80
104
  ```
81
105
 
106
+ ## env — Environment Variables
107
+
108
+ Declared environment variables — the canonical home for runtime config (ports, service tokens, bucket names, feature flags). Declare them under the `env` blueprint field; each is read once at config load, validated and coerced to its declared type (loud error on a bad or missing-required value), and exposed typed on `manifold.env` — in place of scattered ad-hoc `process.env` reads.
109
+
110
+ ### Types
111
+
112
+ **`StringEnvVar`**
113
+
114
+ A string environment variable — resolved verbatim.
115
+
116
+
117
+ ```typescript
118
+ S3_BUCKET: { type: 'string', required: true }
119
+ ```
120
+
121
+ ```typescript
122
+ interface StringEnvVar extends EnvVarBase
123
+ ```
124
+
125
+ **`NumberEnvVar`**
126
+
127
+ A number environment variable — parsed with a loud error on a non-numeric value.
128
+
129
+
130
+ ```typescript
131
+ PORT: { type: 'number', default: 3000 }
132
+ ```
133
+
134
+ ```typescript
135
+ interface NumberEnvVar extends EnvVarBase
136
+ ```
137
+
138
+ **`BooleanEnvVar`**
139
+
140
+ A boolean environment variable — accepts true/false/1/0, loud error otherwise.
141
+
142
+
143
+ ```typescript
144
+ FEATURE_GRAPH: { type: 'boolean', default: false }
145
+ ```
146
+
147
+ ```typescript
148
+ interface BooleanEnvVar extends EnvVarBase
149
+ ```
150
+
151
+ **`StringArrayEnvVar`**
152
+
153
+ A string-array environment variable — the raw value split on `separator`
154
+ (default `,`), each element trimmed.
155
+
156
+
157
+ ```typescript
158
+ CORS_ORIGINS: { type: 'string[]', separator: ',', default: [] }
159
+ ```
160
+
161
+ ```typescript
162
+ interface StringArrayEnvVar extends EnvVarBase
163
+ ```
164
+
165
+ **`EnvVarDef`**
166
+
167
+ One declared environment variable: its type, whether it is required, its
168
+ fallbacks, and whether the value is sensitive. Declared under the `env`
169
+ blueprint field; resolved once at config load and exposed typed on
170
+ `manifold.env` — the canonical replacement for ad-hoc `process.env` reads.
171
+
172
+ ```typescript
173
+ type EnvVarDef = StringEnvVar | NumberEnvVar | BooleanEnvVar | StringArrayEnvVar
174
+ ```
175
+
176
+ **`EnvDefs`**
177
+
178
+ The `env` blueprint field: environment-variable declarations keyed by
179
+ variable name. Passing this map to `createManifold` is what types
180
+ `manifold.env`.
181
+
182
+
183
+ ```typescript
184
+ export default createManifold({
185
+ databases: { app: { url: 'DATABASE_URL', testUrl: 'DATABASE_URL_TEST' } },
186
+ env: {
187
+ PORT: { type: 'number', defaults: { development: '3000', test: '0' } },
188
+ S3_BUCKET: { type: 'string', required: true },
189
+ API_TOKEN: { type: 'string', required: true, sensitive: true },
190
+ CORS_ORIGINS: { type: 'string[]', default: [] },
191
+ },
192
+ })
193
+ // manifold.env.PORT → number
194
+ // manifold.env.S3_BUCKET → string
195
+ // manifold.env.CORS_ORIGINS → string[]
196
+ ```
197
+
198
+ ```typescript
199
+ type EnvDefs = Record<string, EnvVarDef>
200
+ ```
201
+
202
+ **`ResolvedEnvType`** — The resolved runtime type of one declaration: 'string' → string, 'number' → number, 'boolean' → boolean, 'string[]' → string[].
203
+
204
+ ```typescript
205
+ type ResolvedEnvType<T extends EnvVarDef> =
206
+ ```
207
+
208
+ **`ResolveEnvDefs`** — Maps a declaration map to the shape of `manifold.env` — each key typed by its declared `type`.
209
+
210
+ ```typescript
211
+ type ResolveEnvDefs<T extends EnvDefs> =
212
+ ```
213
+
82
214
  ## jobs — Background Jobs
83
215
 
84
216
  Background job queue namespace — Postgres-backed with SKIP LOCKED, LISTEN/NOTIFY, cron scheduling.
@@ -367,6 +499,38 @@ The zod schema for Blueprint validation — useful for custom config tooling.
367
499
 
368
500
  Thrown for configuration problems — includes a suggestion for how to fix.
369
501
 
502
+ ### Types
503
+
504
+ **`StatementEvent`**
505
+
506
+ One statement as it is handed to the driver for writing to the wire —
507
+ including the transaction-control statements the driver issues on its own
508
+ (`BEGIN`, `SAVEPOINT`, `COMMIT`, `ROLLBACK`), which no application-level hook
509
+ can see.
510
+
511
+ ```typescript
512
+ interface StatementEvent
513
+ ```
514
+
515
+ **`StatementObserver`**
516
+
517
+ Caller-supplied per-statement observer. Fires once per statement written to
518
+ the wire, on every connection the manifold owns — pooled connections and the
519
+ test harness's own connections alike.
520
+
521
+ Pure observation: the return value is discarded and the statement is never
522
+ mutated. It runs synchronously on the driver's write path, so it must be
523
+ cheap and must not throw.
524
+
525
+ Counts wire truth, not application intent. Two consequences worth knowing
526
+ before you assert on a total: the driver issues its own transaction control
527
+ (`BEGIN`/`SAVEPOINT`/`COMMIT`/`ROLLBACK`), and it issues one `pg_catalog.pg_type`
528
+ lookup per connection the first time that connection is used.
529
+
530
+ ```typescript
531
+ type StatementObserver = (event: StatementEvent) => void
532
+ ```
533
+
370
534
  ## errors — Error Classes
371
535
 
372
536
  Standard error classes — all extend PipeworkError with structured error codes and actionable messages.
@@ -564,6 +728,18 @@ interface ValueColumnDef
564
728
  interface SerializableOptions
565
729
  ```
566
730
 
731
+ **`ManagedConnection`** — A standalone pooled connection: the raw postgres.js client, its drizzle handle, and a `close()` that ends the pool.
732
+
733
+ ```typescript
734
+ interface ManagedConnection
735
+ ```
736
+
737
+ **`ConnectOptions`** — Options for `tap()` — pool size (default 1) and idle timeout in seconds.
738
+
739
+ ```typescript
740
+ interface ConnectOptions
741
+ ```
742
+
567
743
  ## jsonb — JSONB Column Helpers
568
744
 
569
745
  JSONB query operators — typed helpers for PostgreSQL JSONB containment, key checks, and field extraction.
@@ -1022,6 +1198,19 @@ Generates an OpenAPI 3.1 document from route registrations — schemas derived f
1022
1198
 
1023
1199
  ## test
1024
1200
 
1201
+ ## data
1202
+
1203
+ ### `tap`
1204
+
1205
+ Opens a standalone managed connection outside the manifold's pools — the
1206
+ sanctioned door for contexts where `pipe()` structurally cannot resolve:
1207
+ `worker_threads`, detached monitors, one-off scripts. Callers own the
1208
+ lifecycle: always `await conn.close()`.
1209
+
1210
+ ```typescript
1211
+ function tap(url: string, options?: ConnectOptions): ManagedConnection
1212
+ ```
1213
+
1025
1214
  ## trace
1026
1215
 
1027
1216
  ### `__flowStep`
@@ -1 +1 @@
1
- {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/generate.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,GAAG,SAAS,CAAA;IACtB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAA;IACxB,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,wBAAsB,QAAQ,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsD7E"}
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/generate.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,GAAG,SAAS,CAAA;IACtB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAA;IACxB,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,wBAAsB,QAAQ,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0D7E"}
@@ -1,26 +1,28 @@
1
1
  import { info, success, warn, error as logError } from '../output.js';
2
2
  export async function generate(options) {
3
- const { discoverInstance } = await import('../../core/config/discover.js');
3
+ const { discoverInstance, findConfig } = await import('../../core/config/discover.js');
4
4
  const { generateForDatabase } = await import('../../data/migrate/generate.js');
5
5
  const { loadInternalDefinitions } = await import('../../data/migrate/internal-definitions.js');
6
- let instance;
7
- try {
8
- instance = await discoverInstance(options.cwd);
9
- }
10
- catch {
6
+ if (findConfig(options.cwd) === null) {
11
7
  logError('No pipework.config.ts found.\n\n' +
12
8
  ' Run `pipework init` to create one.\n');
13
9
  process.exit(1);
14
10
  }
11
+ // A config that exists but fails to load (missing env var, refused
12
+ // url/testUrl identity, …) must surface its real error, not be misreported
13
+ // as a missing config.
14
+ const instance = await discoverInstance(options.cwd);
15
15
  const defaultDbName = instance.config.defaultDatabaseName();
16
16
  try {
17
17
  if (options.db !== undefined) {
18
18
  const dbConfig = instance.config.database(options.db);
19
19
  info(`Generating migration for database: ${options.db}`);
20
- const internal = await loadInternalDefinitions(instance.config.raw, {
20
+ // Passed as a thunk so queue registrations made by glob-imported schema
21
+ // modules (inside generateForDatabase) are visible when it runs.
22
+ const internal = () => loadInternalDefinitions(instance.config.raw, {
21
23
  isDefaultDatabase: options.db === defaultDbName,
22
24
  });
23
- const result = await generateForDatabase(dbConfig, options.cwd, options.name, internal);
25
+ const result = await generateForDatabase(dbConfig, options.name, internal);
24
26
  if (result.migrationFile === null) {
25
27
  warn(`${options.db}: no schema changes detected`);
26
28
  }
@@ -34,10 +36,10 @@ export async function generate(options) {
34
36
  for (const [, dbConfig] of instance.config.databases()) {
35
37
  if (dbConfig.schema === undefined)
36
38
  continue;
37
- const internal = await loadInternalDefinitions(instance.config.raw, {
39
+ const internal = () => loadInternalDefinitions(instance.config.raw, {
38
40
  isDefaultDatabase: dbConfig.name === defaultDbName,
39
41
  });
40
- const result = await generateForDatabase(dbConfig, options.cwd, options.name, internal);
42
+ const result = await generateForDatabase(dbConfig, options.name, internal);
41
43
  if (result.migrationFile === null) {
42
44
  warn(`${dbConfig.name}: no schema changes detected`);
43
45
  }
@@ -1 +1 @@
1
- {"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../src/cli/commands/generate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../src/cli/commands/generate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export declare function setConfigBaseDir(dir: string): void;
2
+ /** Read-and-clear. Undefined when no config import is in flight — directly-constructed configs resolve against process.cwd(). */
3
+ export declare function consumeConfigBaseDir(): string | undefined;
4
+ /** Cleared in the importer's finally: an ESM cache hit skips loadConfig, and the stale slot must not leak into a later directly-constructed loadConfig. */
5
+ export declare function clearConfigBaseDir(): void;
6
+ //# sourceMappingURL=base-dir.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-dir.d.ts","sourceRoot":"","sources":["../../../src/core/config/base-dir.ts"],"names":[],"mappings":"AASA,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAElD;AAED,iIAAiI;AACjI,wBAAgB,oBAAoB,IAAI,MAAM,GAAG,SAAS,CAIzD;AAED,2JAA2J;AAC3J,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC"}
@@ -0,0 +1,21 @@
1
+ // The directory relative `migrations`/`schema` paths resolve against (D1,
2
+ // subseam audit 2026-07-16). Set from the config file's directory immediately
3
+ // before the config module is imported; consumed exactly once by loadConfig.
4
+ // A module-level slot rather than a parameter because the config file itself
5
+ // calls createManifold() during its own import — there is no call chain to
6
+ // thread the value through.
7
+ let configBaseDir;
8
+ export function setConfigBaseDir(dir) {
9
+ configBaseDir = dir;
10
+ }
11
+ /** Read-and-clear. Undefined when no config import is in flight — directly-constructed configs resolve against process.cwd(). */
12
+ export function consumeConfigBaseDir() {
13
+ const dir = configBaseDir;
14
+ configBaseDir = undefined;
15
+ return dir;
16
+ }
17
+ /** Cleared in the importer's finally: an ESM cache hit skips loadConfig, and the stale slot must not leak into a later directly-constructed loadConfig. */
18
+ export function clearConfigBaseDir() {
19
+ configBaseDir = undefined;
20
+ }
21
+ //# sourceMappingURL=base-dir.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-dir.js","sourceRoot":"","sources":["../../../src/core/config/base-dir.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,8EAA8E;AAC9E,6EAA6E;AAC7E,6EAA6E;AAC7E,2EAA2E;AAC3E,4BAA4B;AAE5B,IAAI,aAAiC,CAAA;AAErC,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,aAAa,GAAG,GAAG,CAAA;AACrB,CAAC;AAED,iIAAiI;AACjI,MAAM,UAAU,oBAAoB;IAClC,MAAM,GAAG,GAAG,aAAa,CAAA;IACzB,aAAa,GAAG,SAAS,CAAA;IACzB,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,2JAA2J;AAC3J,MAAM,UAAU,kBAAkB;IAChC,aAAa,GAAG,SAAS,CAAA;AAC3B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../../../src/core/config/discover.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAK9C,wBAAgB,sBAAsB,IAAI,IAAI,CAsD7C;AAED,wBAAsB,gBAAgB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CA6BtE;AAMD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAYtD"}
1
+ {"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../../../src/core/config/discover.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAM9C,wBAAgB,sBAAsB,IAAI,IAAI,CAsD7C;AAED,wBAAsB,gBAAgB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CActE;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAYtD"}
@@ -1,8 +1,8 @@
1
1
  import { resolve, dirname } from 'node:path';
2
2
  import { existsSync } from 'node:fs';
3
- import { pathToFileURL } from 'node:url';
4
3
  import { register } from 'node:module';
5
4
  import { ConfigError } from './errors.js';
5
+ import { importConfig } from './import-config.js';
6
6
  const CONFIG_FILENAME = 'pipework.config.ts';
7
7
  export function registerTsResolveHooks() {
8
8
  {
@@ -66,20 +66,7 @@ export async function discoverInstance(cwd) {
66
66
  throw new ConfigError(`No ${CONFIG_FILENAME} found in ${start} or any parent directory.`, `Create one with \`pipework init\`, or see the getting-started guide.`);
67
67
  }
68
68
  registerTsResolveHooks();
69
- const configUrl = pathToFileURL(configPath).href;
70
- const mod = await import(configUrl);
71
- const exported = mod['default'] ?? mod;
72
- if (!isManifold(exported)) {
73
- throw new ConfigError(`${CONFIG_FILENAME} must export a Pipework instance as its default export.`, `Your config should look like:\n\n` +
74
- ` import { createManifold } from 'pipework'\n\n` +
75
- ` export default createManifold({\n` +
76
- ` databases: { app: { url: 'DATABASE_URL' } },\n` +
77
- ` })\n`);
78
- }
79
- return exported;
80
- }
81
- function isManifold(v) {
82
- return typeof v === 'object' && v !== null && 'pool' in v && 'config' in v;
69
+ return importConfig(configPath);
83
70
  }
84
71
  export function findConfig(from) {
85
72
  let dir = resolve(from);
@@ -1 +1 @@
1
- {"version":3,"file":"discover.js","sourceRoot":"","sources":["../../../src/core/config/discover.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAEtC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAEzC,MAAM,eAAe,GAAG,oBAAoB,CAAA;AAE5C,MAAM,UAAU,sBAAsB;IACpC,CAAC;QACC,+EAA+E;QAC/E,qEAAqE;QACrE,8EAA8E;QAC9E,+EAA+E;QAC/E,+DAA+D;QAC/D,gFAAgF;QAChF,qEAAqE;QACrE,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA0CZ,CAAA;QACD,QAAQ,CAAC,wBAAwB,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAC9D,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,GAAY;IACjD,MAAM,KAAK,GAAG,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAA;IAClC,MAAM,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,CAAA;IAEpC,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QACxB,MAAM,IAAI,WAAW,CACnB,MAAM,eAAe,aAAa,KAAK,2BAA2B,EAClE,sEAAsE,CACvE,CAAA;IACH,CAAC;IAED,sBAAsB,EAAE,CAAA;IAExB,MAAM,SAAS,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC,IAAI,CAAA;IAChD,MAAM,GAAG,GAA4B,MAAM,MAAM,CAAC,SAAS,CAAC,CAAA;IAC5D,MAAM,QAAQ,GAAY,GAAG,CAAC,SAAS,CAAC,IAAI,GAAG,CAAA;IAE/C,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,WAAW,CACnB,GAAG,eAAe,yDAAyD,EAC3E,mCAAmC;YACnC,iDAAiD;YACjD,qCAAqC;YACrC,oDAAoD;YACpD,QAAQ,CACT,CAAA;IACH,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,SAAS,UAAU,CAAC,CAAU;IAC5B,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,MAAM,IAAI,CAAC,IAAI,QAAQ,IAAI,CAAC,CAAA;AAC5E,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,IAAI,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACvB,IAAI,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;IACzB,OAAO,GAAG,KAAK,MAAM,EAAE,CAAC;QACtB,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,EAAE,eAAe,CAAC,CAAA;QAC/C,IAAI,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAA;QAC3C,GAAG,GAAG,MAAM,CAAA;QACZ,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;IACvB,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,eAAe,CAAC,CAAA;IAC1C,IAAI,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAA;IACjC,OAAO,IAAI,CAAA;AACb,CAAC"}
1
+ {"version":3,"file":"discover.js","sourceRoot":"","sources":["../../../src/core/config/discover.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAEtC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEjD,MAAM,eAAe,GAAG,oBAAoB,CAAA;AAE5C,MAAM,UAAU,sBAAsB;IACpC,CAAC;QACC,+EAA+E;QAC/E,qEAAqE;QACrE,8EAA8E;QAC9E,+EAA+E;QAC/E,+DAA+D;QAC/D,gFAAgF;QAChF,qEAAqE;QACrE,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA0CZ,CAAA;QACD,QAAQ,CAAC,wBAAwB,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAC9D,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,GAAY;IACjD,MAAM,KAAK,GAAG,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAA;IAClC,MAAM,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,CAAA;IAEpC,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QACxB,MAAM,IAAI,WAAW,CACnB,MAAM,eAAe,aAAa,KAAK,2BAA2B,EAClE,sEAAsE,CACvE,CAAA;IACH,CAAC;IAED,sBAAsB,EAAE,CAAA;IAExB,OAAO,YAAY,CAAC,UAAU,CAAC,CAAA;AACjC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,IAAI,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACvB,IAAI,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;IACzB,OAAO,GAAG,KAAK,MAAM,EAAE,CAAC;QACtB,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,EAAE,eAAe,CAAC,CAAA;QAC/C,IAAI,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAA;QAC3C,GAAG,GAAG,MAAM,CAAA;QACZ,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;IACvB,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,eAAe,CAAC,CAAA;IAC1C,IAAI,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAA;IACjC,OAAO,IAAI,CAAA;AACb,CAAC"}
@@ -1,31 +1,100 @@
1
1
  import type { Environment } from './schema.js';
2
2
  interface EnvVarBase {
3
+ /** Redact the resolved value from logs and error messages (tokens, secrets). */
3
4
  readonly sensitive?: boolean | undefined;
5
+ /**
6
+ * Per-environment fallback values, keyed by environment name. Always given
7
+ * as strings (they take the same parse path as a real environment variable);
8
+ * a variable that is set in the environment wins over any default here.
9
+ *
10
+ * @example
11
+ * PORT: { type: 'number', defaults: { development: '3000', test: '0' } }
12
+ */
4
13
  readonly defaults?: Partial<Record<Environment, string>> | undefined;
5
14
  }
15
+ /**
16
+ * A string environment variable — resolved verbatim.
17
+ *
18
+ * @example
19
+ * S3_BUCKET: { type: 'string', required: true }
20
+ */
6
21
  export interface StringEnvVar extends EnvVarBase {
7
22
  readonly type: 'string';
23
+ /** Fail startup when unset and no default applies. */
8
24
  readonly required?: boolean | undefined;
25
+ /** Environment-independent fallback; `defaults` (per-environment) wins over this. */
9
26
  readonly default?: string | undefined;
10
27
  }
28
+ /**
29
+ * A number environment variable — parsed with a loud error on a non-numeric value.
30
+ *
31
+ * @example
32
+ * PORT: { type: 'number', default: 3000 }
33
+ */
11
34
  export interface NumberEnvVar extends EnvVarBase {
12
35
  readonly type: 'number';
36
+ /** Fail startup when unset and no default applies. */
13
37
  readonly required?: boolean | undefined;
38
+ /** Environment-independent fallback; `defaults` (per-environment) wins over this. */
14
39
  readonly default?: number | undefined;
15
40
  }
41
+ /**
42
+ * A boolean environment variable — accepts true/false/1/0, loud error otherwise.
43
+ *
44
+ * @example
45
+ * FEATURE_GRAPH: { type: 'boolean', default: false }
46
+ */
16
47
  export interface BooleanEnvVar extends EnvVarBase {
17
48
  readonly type: 'boolean';
49
+ /** Fail startup when unset and no default applies. */
18
50
  readonly required?: boolean | undefined;
51
+ /** Environment-independent fallback; `defaults` (per-environment) wins over this. */
19
52
  readonly default?: boolean | undefined;
20
53
  }
54
+ /**
55
+ * A string-array environment variable — the raw value split on `separator`
56
+ * (default `,`), each element trimmed.
57
+ *
58
+ * @example
59
+ * CORS_ORIGINS: { type: 'string[]', separator: ',', default: [] }
60
+ */
21
61
  export interface StringArrayEnvVar extends EnvVarBase {
22
62
  readonly type: 'string[]';
63
+ /** Split character for the raw value (default ','). */
23
64
  readonly separator?: string | undefined;
65
+ /** Fail startup when unset and no default applies. */
24
66
  readonly required?: boolean | undefined;
67
+ /** Environment-independent fallback; `defaults` (per-environment) wins over this. */
25
68
  readonly default?: readonly string[] | undefined;
26
69
  }
70
+ /**
71
+ * One declared environment variable: its type, whether it is required, its
72
+ * fallbacks, and whether the value is sensitive. Declared under the `env`
73
+ * blueprint field; resolved once at config load and exposed typed on
74
+ * `manifold.env` — the canonical replacement for ad-hoc `process.env` reads.
75
+ */
27
76
  export type EnvVarDef = StringEnvVar | NumberEnvVar | BooleanEnvVar | StringArrayEnvVar;
77
+ /**
78
+ * The `env` blueprint field: environment-variable declarations keyed by
79
+ * variable name. Passing this map to `createManifold` is what types
80
+ * `manifold.env`.
81
+ *
82
+ * @example
83
+ * export default createManifold({
84
+ * databases: { app: { url: 'DATABASE_URL', testUrl: 'DATABASE_URL_TEST' } },
85
+ * env: {
86
+ * PORT: { type: 'number', defaults: { development: '3000', test: '0' } },
87
+ * S3_BUCKET: { type: 'string', required: true },
88
+ * API_TOKEN: { type: 'string', required: true, sensitive: true },
89
+ * CORS_ORIGINS: { type: 'string[]', default: [] },
90
+ * },
91
+ * })
92
+ * // manifold.env.PORT → number
93
+ * // manifold.env.S3_BUCKET → string
94
+ * // manifold.env.CORS_ORIGINS → string[]
95
+ */
28
96
  export type EnvDefs = Record<string, EnvVarDef>;
97
+ /** The resolved runtime type of one declaration: 'string' → string, 'number' → number, 'boolean' → boolean, 'string[]' → string[]. */
29
98
  export type ResolvedEnvType<T extends EnvVarDef> = T extends {
30
99
  readonly type: 'string';
31
100
  } ? string : T extends {
@@ -35,6 +104,7 @@ export type ResolvedEnvType<T extends EnvVarDef> = T extends {
35
104
  } ? boolean : T extends {
36
105
  readonly type: 'string[]';
37
106
  } ? string[] : never;
107
+ /** Maps a declaration map to the shape of `manifold.env` — each key typed by its declared `type`. */
38
108
  export type ResolveEnvDefs<T extends EnvDefs> = {
39
109
  readonly [K in keyof T]: ResolvedEnvType<T[K]>;
40
110
  };
@@ -1 +1 @@
1
- {"version":3,"file":"env-types.d.ts","sourceRoot":"","sources":["../../../src/core/config/env-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAE9C,UAAU,UAAU;IAClB,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACxC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS,CAAA;CACrE;AAED,MAAM,WAAW,YAAa,SAAQ,UAAU;IAC9C,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACvC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACtC;AAED,MAAM,WAAW,YAAa,SAAQ,UAAU;IAC9C,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACvC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACtC;AAED,MAAM,WAAW,aAAc,SAAQ,UAAU;IAC/C,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACvC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CACvC;AAED,MAAM,WAAW,iBAAkB,SAAQ,UAAU;IACnD,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACvC,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAA;CACjD;AAED,MAAM,MAAM,SAAS,GAAG,YAAY,GAAG,YAAY,GAAG,aAAa,GAAG,iBAAiB,CAAA;AAEvF,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;AAE/C,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,SAAS,IAC7C,CAAC,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GAAG,MAAM,GAC9C,CAAC,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GAAG,MAAM,GAC9C,CAAC,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE,GAAG,OAAO,GAChD,CAAC,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GAAG,MAAM,EAAE,GAClD,KAAK,CAAA;AAEP,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,OAAO,IAAI;IAC9C,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAC/C,CAAA"}
1
+ {"version":3,"file":"env-types.d.ts","sourceRoot":"","sources":["../../../src/core/config/env-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAE9C,UAAU,UAAU;IAClB,gFAAgF;IAChF,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACxC;;;;;;;OAOG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS,CAAA;CACrE;AAED;;;;;GAKG;AACH,MAAM,WAAW,YAAa,SAAQ,UAAU;IAC9C,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;IACvB,sDAAsD;IACtD,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACvC,qFAAqF;IACrF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACtC;AAED;;;;;GAKG;AACH,MAAM,WAAW,YAAa,SAAQ,UAAU;IAC9C,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;IACvB,sDAAsD;IACtD,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACvC,qFAAqF;IACrF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACtC;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAc,SAAQ,UAAU;IAC/C,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,sDAAsD;IACtD,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACvC,qFAAqF;IACrF,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CACvC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,iBAAkB,SAAQ,UAAU;IACnD,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;IACzB,uDAAuD;IACvD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,sDAAsD;IACtD,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACvC,qFAAqF;IACrF,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAA;CACjD;AAED;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,YAAY,GAAG,YAAY,GAAG,aAAa,GAAG,iBAAiB,CAAA;AAEvF;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;AAE/C,sIAAsI;AACtI,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,SAAS,IAC7C,CAAC,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GAAG,MAAM,GAC9C,CAAC,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GAAG,MAAM,GAC9C,CAAC,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE,GAAG,OAAO,GAChD,CAAC,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GAAG,MAAM,EAAE,GAClD,KAAK,CAAA;AAEP,qGAAqG;AACrG,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,OAAO,IAAI;IAC9C,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAC/C,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../../src/core/config/env.ts"],"names":[],"mappings":"AAGA,wBAAgB,YAAY,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAM/C"}
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../../src/core/config/env.ts"],"names":[],"mappings":"AAKA,wBAAgB,YAAY,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAU/C"}
@@ -1,24 +1,28 @@
1
1
  import { readFileSync, existsSync } from 'node:fs';
2
2
  import { resolve, dirname } from 'node:path';
3
+ const ENV_FILES = ['.env.test.local', '.env.test', '.env.local', '.env'];
3
4
  export function loadEnvFiles(cwd) {
4
5
  const start = cwd ?? process.cwd();
5
6
  const envDir = findEnvDir(start) ?? start;
6
- loadFile(resolve(envDir, '.env.test'));
7
- loadFile(resolve(envDir, '.env'));
7
+ // First-set wins (loadFile never overwrites), so the machine-local,
8
+ // never-committed `.local` variant of each tier takes precedence over the
9
+ // committed file — the standard dotenv convention.
10
+ for (const file of ENV_FILES) {
11
+ loadFile(resolve(envDir, file));
12
+ }
8
13
  }
9
14
  function findEnvDir(from) {
15
+ const hasEnvFile = (dir) => ENV_FILES.some(f => existsSync(resolve(dir, f)));
10
16
  let dir = resolve(from);
11
17
  let parent = dirname(dir);
12
18
  while (dir !== parent) {
13
- if (existsSync(resolve(dir, '.env')) || existsSync(resolve(dir, '.env.test'))) {
19
+ if (hasEnvFile(dir))
14
20
  return dir;
15
- }
16
21
  dir = parent;
17
22
  parent = dirname(dir);
18
23
  }
19
- if (existsSync(resolve(dir, '.env')) || existsSync(resolve(dir, '.env.test'))) {
24
+ if (hasEnvFile(dir))
20
25
  return dir;
21
- }
22
26
  return null;
23
27
  }
24
28
  function loadFile(path) {
@@ -1 +1 @@
1
- {"version":3,"file":"env.js","sourceRoot":"","sources":["../../../src/core/config/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAE5C,MAAM,UAAU,YAAY,CAAC,GAAY;IACvC,MAAM,KAAK,GAAG,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAA;IAClC,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,KAAK,CAAA;IAEzC,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAA;IACtC,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;AACnC,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,IAAI,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACvB,IAAI,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;IACzB,OAAO,GAAG,KAAK,MAAM,EAAE,CAAC;QACtB,IAAI,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,IAAI,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC;YAC9E,OAAO,GAAG,CAAA;QACZ,CAAC;QACD,GAAG,GAAG,MAAM,CAAA;QACZ,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;IACvB,CAAC;IACD,IAAI,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,IAAI,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC;QAC9E,OAAO,GAAG,CAAA;IACZ,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC5B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAM;IAE7B,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IAC3C,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;QAC3B,IAAI,OAAO,KAAK,EAAE,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAQ;QAEvD,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAClC,IAAI,KAAK,KAAK,CAAC,CAAC;YAAE,SAAQ;QAE1B,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,CAAA;QAC1C,IAAI,GAAG,KAAK,EAAE;YAAE,SAAQ;QAExB,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,SAAS;YAAE,SAAQ;QAE5C,IAAI,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;QAC3C,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC9C,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACnD,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QAC5B,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;IAC1B,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../../src/core/config/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAE5C,MAAM,SAAS,GAAG,CAAC,iBAAiB,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,CAAC,CAAA;AAExE,MAAM,UAAU,YAAY,CAAC,GAAY;IACvC,MAAM,KAAK,GAAG,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAA;IAClC,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,KAAK,CAAA;IAEzC,oEAAoE;IACpE,0EAA0E;IAC1E,mDAAmD;IACnD,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAA;IACjC,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,MAAM,UAAU,GAAG,CAAC,GAAW,EAAW,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;IAC7F,IAAI,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACvB,IAAI,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;IACzB,OAAO,GAAG,KAAK,MAAM,EAAE,CAAC;QACtB,IAAI,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,GAAG,CAAA;QAC/B,GAAG,GAAG,MAAM,CAAA;QACZ,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;IACvB,CAAC;IACD,IAAI,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAA;IAC/B,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC5B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAM;IAE7B,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IAC3C,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;QAC3B,IAAI,OAAO,KAAK,EAAE,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAQ;QAEvD,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAClC,IAAI,KAAK,KAAK,CAAC,CAAC;YAAE,SAAQ;QAE1B,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,CAAA;QAC1C,IAAI,GAAG,KAAK,EAAE;YAAE,SAAQ;QAExB,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,SAAS;YAAE,SAAQ;QAE5C,IAAI,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;QAC3C,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC9C,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACnD,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QAC5B,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;IAC1B,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Manifold } from '../pipework.js';
2
+ export declare function importConfig(configPath: string): Promise<Manifold>;
3
+ //# sourceMappingURL=import-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import-config.d.ts","sourceRoot":"","sources":["../../../src/core/config/import-config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAS9C,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAwBxE"}