@blogic-cz/agent-tools 0.17.1 → 0.17.2
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/README.md +41 -0
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/types.d.ts +17 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/db-tool/service.d.ts +23 -0
- package/dist/db-tool/service.d.ts.map +1 -1
- package/dist/db-tool/types.d.ts +2 -0
- package/dist/db-tool/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/schemas/agent-tools.schema.json +8 -0
- package/src/config/loader.ts +2 -0
- package/src/config/types.ts +17 -0
- package/src/db-tool/service.ts +113 -1
- package/src/db-tool/types.ts +2 -0
package/README.md
CHANGED
|
@@ -436,6 +436,47 @@ Secrets are **never** stored in the config file. The `db-tool` config references
|
|
|
436
436
|
}
|
|
437
437
|
```
|
|
438
438
|
|
|
439
|
+
#### Endpoint overrides: `hostEnvVar` and `portEnvVar`
|
|
440
|
+
|
|
441
|
+
A database environment can also take its `host` and `port` from environment variables:
|
|
442
|
+
|
|
443
|
+
| Field | Effect |
|
|
444
|
+
| ------------ | -------------------------------------------------------------------------- |
|
|
445
|
+
| `hostEnvVar` | Name of an environment variable that overrides the literal `host` when set |
|
|
446
|
+
| `portEnvVar` | Name of an environment variable that overrides the literal `port` when set |
|
|
447
|
+
|
|
448
|
+
These are **overrides with fallback**, not requirements — the opposite of `passwordEnvVar`, which fails when its variable is unset:
|
|
449
|
+
|
|
450
|
+
- variable set to a value → that value wins over the literal in the config;
|
|
451
|
+
- variable unset or empty → the literal `host` / `port` in the config is used, and no error is raised;
|
|
452
|
+
- `portEnvVar` set to something that is not an integer between 1 and 65535 → the command **fails**. It never falls back to the literal, because that would query a different database while you believe the override applied.
|
|
453
|
+
|
|
454
|
+
The variable is read from the process environment first (Bun loads `.env` files into it), then from `~/.zshrc` exports.
|
|
455
|
+
|
|
456
|
+
The typical use is a repository where every git worktree runs its own database container on its own host port, published by that worktree's `.env`:
|
|
457
|
+
|
|
458
|
+
```json5
|
|
459
|
+
{
|
|
460
|
+
database: {
|
|
461
|
+
default: {
|
|
462
|
+
environments: {
|
|
463
|
+
local: {
|
|
464
|
+
host: "127.0.0.1",
|
|
465
|
+
port: 40543, // the main checkout's database
|
|
466
|
+
user: "app",
|
|
467
|
+
database: "app",
|
|
468
|
+
portEnvVar: "APP_POSTGRES_PORT", // a worktree's .env sets this to e.g. 40643
|
|
469
|
+
hostEnvVar: "APP_POSTGRES_HOST", // optional, same fallback rule
|
|
470
|
+
prerequisites: [],
|
|
471
|
+
},
|
|
472
|
+
},
|
|
473
|
+
},
|
|
474
|
+
},
|
|
475
|
+
}
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
Run from the main checkout, where `APP_POSTGRES_PORT` is unset, `db-tool` connects to `127.0.0.1:40543`. Run from a worktree whose `.env` sets `APP_POSTGRES_PORT=40643`, the same config connects to `127.0.0.1:40643` — so `db-tool` and `job-tool` inspect that worktree's own database instead of the main checkout's.
|
|
479
|
+
|
|
439
480
|
Database VPN prerequisites can be set at the database profile or environment level. If an environment declares `vpn` or `prerequisites`, that environment config replaces the profile prerequisites; `prerequisites: []` explicitly disables inherited VPN setup. DB commands try the query directly first and only connect VPN prerequisites if direct access fails. Package-managed VPNs remain reusable for `idleDisconnectMs` (default 30000) after the last lease; `0` restores immediate cleanup. Preconnected or `leave-running` connections are treated as external and never stopped automatically. If runtime state is corrupt, unknown, or contains legacy artifacts, first stop all agent-tools processes using the VPN, then remove that VPN state directory under `~/.agent-tools/runtime/vpn-prerequisites`.
|
|
440
481
|
|
|
441
482
|
```json5
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAgB,KAAK,EAAU,MAAM,QAAQ,CAAC;AAE9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAgB,KAAK,EAAU,MAAM,QAAQ,CAAC;AAE9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AA6NlE,wBAAgB,YAAY,CAC1B,MAAM,EAAE,OAAO,EACf,UAAU,GAAE,MAA4B,GACvC,gBAAgB,CAmClB;AAmFD,wBAAsB,UAAU,IAAI,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAcxE;;AAED,qBAAa,aAAc,SAAQ,kBAElC;CAAG;;;;AAEJ,qBAAa,eAAgB,SAAQ,qBAAoC;IACvE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB,CAAC;CAAG;AAEL,eAAO,MAAM,kBAAkB,oDAM9B,CAAC;AAEF,KAAK,eAAe,GAAG,MAAM,IAAI,CAC/B,gBAAgB,EAChB,OAAO,GAAG,YAAY,GAAG,UAAU,GAAG,eAAe,GAAG,MAAM,CAC/D,CAAC;AAEF,wBAAgB,aAAa,CAAC,CAAC,EAC7B,MAAM,EAAE,gBAAgB,GAAG,SAAS,EACpC,OAAO,EAAE,eAAe,EACxB,OAAO,CAAC,EAAE,MAAM,GACf,CAAC,GAAG,SAAS,CAkCf;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,gBAAgB,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAE9F;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,gBAAgB,GAAG,SAAS,EACpC,OAAO,CAAC,EAAE,MAAM,GACf,gBAAgB,GAAG,SAAS,CAc9B;AAED,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,gBAAgB,GAAG,SAAS,EACpC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GACrB,MAAM,GAAG,SAAS,CAqBpB"}
|
package/dist/config/types.d.ts
CHANGED
|
@@ -77,6 +77,23 @@ export type DbEnvConfig = ProfilePrerequisites & {
|
|
|
77
77
|
password?: string;
|
|
78
78
|
/** Name of environment variable holding the password, e.g. "DB_TEST_PWD" */
|
|
79
79
|
passwordEnvVar?: string;
|
|
80
|
+
/**
|
|
81
|
+
* Name of an environment variable that overrides `host`, e.g. "APP_POSTGRES_HOST".
|
|
82
|
+
*
|
|
83
|
+
* Override with fallback, deliberately unlike `passwordEnvVar`: an unset or empty variable is
|
|
84
|
+
* not an error, it keeps the literal `host` above. The variable usually exists only in a
|
|
85
|
+
* per-worktree environment, and the main checkout must keep working from the literal.
|
|
86
|
+
*/
|
|
87
|
+
hostEnvVar?: string;
|
|
88
|
+
/**
|
|
89
|
+
* Name of an environment variable that overrides `port`, e.g. "APP_POSTGRES_PORT".
|
|
90
|
+
*
|
|
91
|
+
* Same override-with-fallback rule as `hostEnvVar`: unset or empty keeps the literal `port`,
|
|
92
|
+
* because only a worktree environment publishes its own port. A variable that *is* set but is
|
|
93
|
+
* not an integer in 1..65535 fails instead of falling back — a silent fallback would query the
|
|
94
|
+
* wrong database while the caller believes the override applied.
|
|
95
|
+
*/
|
|
96
|
+
portEnvVar?: string;
|
|
80
97
|
};
|
|
81
98
|
/** SQL mutation operation that can be explicitly allowed for a database environment. */
|
|
82
99
|
export declare const DbMutationOperationSchema: Schema.Literals<readonly ["insert", "update", "delete"]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,yCAAyC;AACzC,MAAM,MAAM,WAAW,GAAG;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,eAAe,GAAG,iBAAiB,CAAC;AAEhE,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,KAAK,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,IAAI,EAAE,cAAc,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0FAA0F;IAC1F,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,IAAI,EAAE,aAAa,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,IAAI,EAAE,iBAAiB,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,eAAe,GACvB,0BAA0B,GAC1B,yBAAyB,GACzB,6BAA6B,CAAC;AAElC,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,mFAAmF;IACnF,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,cAAc,CAAC,EAAE,aAAa,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,6DAA6D;IAC7D,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,mGAAmG;IACnG,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,wFAAwF;IACxF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE;QACR,MAAM,CAAC,EAAE,0BAA0B,CAAC;QACpC,KAAK,CAAC,EAAE,yBAAyB,CAAC;QAClC,KAAK,CAAC,EAAE,6BAA6B,CAAC;KACvC,CAAC;IACF,uGAAuG;IACvG,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,aAAa,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IAC3C,4EAA4E;IAC5E,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,+CAA+C;AAC/C,MAAM,MAAM,SAAS,GAAG,oBAAoB,GAAG;IAC7C,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,qDAAqD;AACrD,MAAM,MAAM,WAAW,GAAG,oBAAoB,GAAG;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,mGAAmG;IACnG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,cAAc,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,29 @@ import { ConfigService } from "#config";
|
|
|
5
5
|
import { DbConfigService } from "./config-service";
|
|
6
6
|
import { DbSqlClient } from "./sql-client";
|
|
7
7
|
import { type DbError } from "./errors";
|
|
8
|
+
export type ResolvedPortOverride = {
|
|
9
|
+
readonly ok: true;
|
|
10
|
+
readonly port: number;
|
|
11
|
+
} | {
|
|
12
|
+
readonly ok: false;
|
|
13
|
+
readonly message: string;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Applies a `portEnvVar` override to the literal `port` of a database environment.
|
|
17
|
+
*
|
|
18
|
+
* Override with fallback: no variable name, or a variable that is unset or blank, keeps
|
|
19
|
+
* `literalPort`, because the variable exists only in environments that publish their own port
|
|
20
|
+
* (a per-repository worktree) while the main checkout runs from the literal. A variable that is
|
|
21
|
+
* set but does not hold an integer in 1..65535 fails instead of falling back, since falling back
|
|
22
|
+
* would silently query the main checkout's database while the caller believes the override applied.
|
|
23
|
+
*/
|
|
24
|
+
export declare function resolvePortOverride(env: string, literalPort: number, portEnvVar: string | undefined, value: string | undefined): ResolvedPortOverride;
|
|
25
|
+
/**
|
|
26
|
+
* Applies a `hostEnvVar` override to the literal `host` of a database environment.
|
|
27
|
+
* Unset or blank keeps `literalHost`; every non-blank value is a usable host, so there is no
|
|
28
|
+
* failure case here, unlike {@link resolvePortOverride}.
|
|
29
|
+
*/
|
|
30
|
+
export declare function resolveHostOverride(literalHost: string, hostEnvVar: string | undefined, value: string | undefined): string;
|
|
8
31
|
export declare function resolveDbAccessMode(env: string, host: string, hasKubectlConfig: boolean, allowedMutations?: readonly DbMutationOperation[]): Pick<DbConfig, "allowMutations" | "allowedMutations" | "host" | "needsTunnel">;
|
|
9
32
|
export declare function isFullyReadOnly(config: Pick<DbConfig, "allowMutations" | "allowedMutations" | "allowedMutationTargets">): boolean;
|
|
10
33
|
export { buildApiProbeArgs } from "#shared/k8s-probe";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/db-tool/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC5E,OAAO,EAAS,OAAO,EAAY,MAAM,EAAE,KAAK,EAAuB,MAAM,QAAQ,CAAC;AAEtF,OAAO,KAAK,EAAE,QAAQ,EAAE,mBAAmB,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEtF,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAOxC,OAAO,EAAE,eAAe,EAA4B,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EAAE,WAAW,EAAqB,MAAM,cAAc,CAAC;AAC9D,OAAO,EAKL,KAAK,OAAO,EACb,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/db-tool/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC5E,OAAO,EAAS,OAAO,EAAY,MAAM,EAAE,KAAK,EAAuB,MAAM,QAAQ,CAAC;AAEtF,OAAO,KAAK,EAAE,QAAQ,EAAE,mBAAmB,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEtF,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAOxC,OAAO,EAAE,eAAe,EAA4B,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EAAE,WAAW,EAAqB,MAAM,cAAc,CAAC;AAC9D,OAAO,EAKL,KAAK,OAAO,EACb,MAAM,UAAU,CAAC;AA8BlB,MAAM,MAAM,oBAAoB,GAC5B;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC5C;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAErD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,oBAAoB,CAqBtB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,MAAM,CAOR;AAED,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,gBAAgB,EAAE,OAAO,EACzB,gBAAgB,GAAE,SAAS,mBAAmB,EAAO,GACpD,IAAI,CAAC,QAAQ,EAAE,gBAAgB,GAAG,kBAAkB,GAAG,MAAM,GAAG,aAAa,CAAC,CAUhF;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,gBAAgB,GAAG,kBAAkB,GAAG,wBAAwB,CAAC,GACvF,OAAO,CAMT;AAGD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;;2BAK3B,CACrB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,KAAK,CAAC,EAAE,MAAM,KACX,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC;iCACX,CAC3B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,UAAU,EAChB,KAAK,CAAC,EAAE,MAAM,KACX,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC;;AAZ5C,qBAAa,SAAU,SAAQ,cAcF;IAC3B,MAAM,CAAC,QAAQ,CAAC,KAAK,yHAuuBnB;CACH"}
|
package/dist/db-tool/types.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/db-tool/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEzD,YAAY,EAAE,mBAAmB,EAAE,CAAC;AACpC,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;AAE1C,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,eAAe,CAAC;AAEzE,MAAM,MAAM,QAAQ,GAAG,oBAAoB,GAAG;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;IACrB,cAAc,EAAE,OAAO,CAAC;IACxB,gBAAgB,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACjD,sBAAsB,EAAE,wBAAwB,CAAC;CAClD,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,iBAAiB,GAAG,kBAAkB,GAAG,IAAI,CAAC;IACpD,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/db-tool/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEzD,YAAY,EAAE,mBAAmB,EAAE,CAAC;AACpC,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;AAE1C,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,eAAe,CAAC;AAEzE,MAAM,MAAM,QAAQ,GAAG,oBAAoB,GAAG;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;IACrB,cAAc,EAAE,OAAO,CAAC;IACxB,gBAAgB,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACjD,sBAAsB,EAAE,wBAAwB,CAAC;CAClD,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,iBAAiB,GAAG,kBAAkB,GAAG,IAAI,CAAC;IACpD,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC"}
|
package/package.json
CHANGED
|
@@ -209,6 +209,14 @@
|
|
|
209
209
|
"description": "Name of the environment variable holding the database password.",
|
|
210
210
|
"type": "string"
|
|
211
211
|
},
|
|
212
|
+
"hostEnvVar": {
|
|
213
|
+
"description": "Name of an environment variable that overrides host when it is set. Unset or empty keeps the literal host.",
|
|
214
|
+
"type": "string"
|
|
215
|
+
},
|
|
216
|
+
"portEnvVar": {
|
|
217
|
+
"description": "Name of an environment variable that overrides port when it is set. Unset or empty keeps the literal port; a value that is not an integer between 1 and 65535 is an error, never a silent fallback.",
|
|
218
|
+
"type": "string"
|
|
219
|
+
},
|
|
212
220
|
"prerequisites": {
|
|
213
221
|
"description": "Ordered prerequisite references for this database environment. Declaring this or vpn overrides profile-level database prerequisites; an empty array explicitly disables inherited prerequisites.",
|
|
214
222
|
"type": "array",
|
package/src/config/loader.ts
CHANGED
|
@@ -105,6 +105,8 @@ const DbEnvConfigSchema = Schema.Struct({
|
|
|
105
105
|
database: Schema.String,
|
|
106
106
|
password: Schema.optionalKey(Schema.String),
|
|
107
107
|
passwordEnvVar: Schema.optionalKey(Schema.String),
|
|
108
|
+
hostEnvVar: Schema.optionalKey(Schema.String),
|
|
109
|
+
portEnvVar: Schema.optionalKey(Schema.String),
|
|
108
110
|
prerequisites: Schema.optionalKey(PrerequisitesSchema),
|
|
109
111
|
vpn: Schema.optionalKey(Schema.String),
|
|
110
112
|
});
|
package/src/config/types.ts
CHANGED
|
@@ -91,6 +91,23 @@ export type DbEnvConfig = ProfilePrerequisites & {
|
|
|
91
91
|
password?: string;
|
|
92
92
|
/** Name of environment variable holding the password, e.g. "DB_TEST_PWD" */
|
|
93
93
|
passwordEnvVar?: string;
|
|
94
|
+
/**
|
|
95
|
+
* Name of an environment variable that overrides `host`, e.g. "APP_POSTGRES_HOST".
|
|
96
|
+
*
|
|
97
|
+
* Override with fallback, deliberately unlike `passwordEnvVar`: an unset or empty variable is
|
|
98
|
+
* not an error, it keeps the literal `host` above. The variable usually exists only in a
|
|
99
|
+
* per-worktree environment, and the main checkout must keep working from the literal.
|
|
100
|
+
*/
|
|
101
|
+
hostEnvVar?: string;
|
|
102
|
+
/**
|
|
103
|
+
* Name of an environment variable that overrides `port`, e.g. "APP_POSTGRES_PORT".
|
|
104
|
+
*
|
|
105
|
+
* Same override-with-fallback rule as `hostEnvVar`: unset or empty keeps the literal `port`,
|
|
106
|
+
* because only a worktree environment publishes its own port. A variable that *is* set but is
|
|
107
|
+
* not an integer in 1..65535 fails instead of falling back — a silent fallback would query the
|
|
108
|
+
* wrong database while the caller believes the override applied.
|
|
109
|
+
*/
|
|
110
|
+
portEnvVar?: string;
|
|
94
111
|
};
|
|
95
112
|
|
|
96
113
|
/** SQL mutation operation that can be explicitly allowed for a database environment. */
|
package/src/db-tool/service.ts
CHANGED
|
@@ -38,6 +38,75 @@ import { transformQueryResult } from "./transformers";
|
|
|
38
38
|
|
|
39
39
|
const LOCALHOST_HOSTS = new Set(["localhost", "127.0.0.1"]);
|
|
40
40
|
|
|
41
|
+
const MIN_TCP_PORT = 1;
|
|
42
|
+
const MAX_TCP_PORT = 65535;
|
|
43
|
+
const INTEGER_ONLY = /^\d+$/;
|
|
44
|
+
|
|
45
|
+
// Bun.env is the primary source: it carries the values Bun loads from a .env file, which is where
|
|
46
|
+
// a per-worktree host/port lives. It aliases process.env, which is also the only one that exists
|
|
47
|
+
// when this module runs outside Bun (the vitest runner).
|
|
48
|
+
const readProcessEnv = (envVar: string): string | undefined =>
|
|
49
|
+
(typeof Bun === "undefined" ? process.env : Bun.env)[envVar];
|
|
50
|
+
|
|
51
|
+
export type ResolvedPortOverride =
|
|
52
|
+
| { readonly ok: true; readonly port: number }
|
|
53
|
+
| { readonly ok: false; readonly message: string };
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Applies a `portEnvVar` override to the literal `port` of a database environment.
|
|
57
|
+
*
|
|
58
|
+
* Override with fallback: no variable name, or a variable that is unset or blank, keeps
|
|
59
|
+
* `literalPort`, because the variable exists only in environments that publish their own port
|
|
60
|
+
* (a per-repository worktree) while the main checkout runs from the literal. A variable that is
|
|
61
|
+
* set but does not hold an integer in 1..65535 fails instead of falling back, since falling back
|
|
62
|
+
* would silently query the main checkout's database while the caller believes the override applied.
|
|
63
|
+
*/
|
|
64
|
+
export function resolvePortOverride(
|
|
65
|
+
env: string,
|
|
66
|
+
literalPort: number,
|
|
67
|
+
portEnvVar: string | undefined,
|
|
68
|
+
value: string | undefined,
|
|
69
|
+
): ResolvedPortOverride {
|
|
70
|
+
if (!portEnvVar) {
|
|
71
|
+
return { ok: true, port: literalPort };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const trimmed = value?.trim() ?? "";
|
|
75
|
+
if (trimmed === "") {
|
|
76
|
+
return { ok: true, port: literalPort };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const parsed = Number(trimmed);
|
|
80
|
+
if (!INTEGER_ONLY.test(trimmed) || parsed < MIN_TCP_PORT || parsed > MAX_TCP_PORT) {
|
|
81
|
+
return {
|
|
82
|
+
ok: false,
|
|
83
|
+
message:
|
|
84
|
+
`Environment variable ${portEnvVar} (override for the 'port' config field) is set to ` +
|
|
85
|
+
`"${value}" in environment ${env}, which is not an integer port between ${MIN_TCP_PORT} and ${MAX_TCP_PORT}.`,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return { ok: true, port: parsed };
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Applies a `hostEnvVar` override to the literal `host` of a database environment.
|
|
94
|
+
* Unset or blank keeps `literalHost`; every non-blank value is a usable host, so there is no
|
|
95
|
+
* failure case here, unlike {@link resolvePortOverride}.
|
|
96
|
+
*/
|
|
97
|
+
export function resolveHostOverride(
|
|
98
|
+
literalHost: string,
|
|
99
|
+
hostEnvVar: string | undefined,
|
|
100
|
+
value: string | undefined,
|
|
101
|
+
): string {
|
|
102
|
+
if (!hostEnvVar) {
|
|
103
|
+
return literalHost;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const trimmed = value?.trim() ?? "";
|
|
107
|
+
return trimmed === "" ? literalHost : trimmed;
|
|
108
|
+
}
|
|
109
|
+
|
|
41
110
|
export function resolveDbAccessMode(
|
|
42
111
|
env: string,
|
|
43
112
|
host: string,
|
|
@@ -204,15 +273,56 @@ export class DbService extends Context.Service<
|
|
|
204
273
|
});
|
|
205
274
|
});
|
|
206
275
|
|
|
276
|
+
const lookupEnvOverride = (envVar: string, zshrcEnv: Record<string, string>) =>
|
|
277
|
+
readProcessEnv(envVar) ?? zshrcEnv[envVar];
|
|
278
|
+
|
|
207
279
|
const resolveDbConfig = Effect.fn("DbService.resolveDbConfig")(function* (
|
|
208
280
|
config: DbConfig,
|
|
209
281
|
env: string,
|
|
210
282
|
) {
|
|
211
283
|
const needsEnvResolution =
|
|
212
|
-
envTemplateRegex.test(config.user) ||
|
|
284
|
+
envTemplateRegex.test(config.user) ||
|
|
285
|
+
envTemplateRegex.test(config.database) ||
|
|
286
|
+
config.hostEnvVar !== undefined ||
|
|
287
|
+
config.portEnvVar !== undefined;
|
|
213
288
|
const zshrcEnv = needsEnvResolution ? yield* loadEnvFromZshrc() : {};
|
|
289
|
+
|
|
290
|
+
const host = resolveHostOverride(
|
|
291
|
+
config.host,
|
|
292
|
+
config.hostEnvVar,
|
|
293
|
+
config.hostEnvVar ? lookupEnvOverride(config.hostEnvVar, zshrcEnv) : undefined,
|
|
294
|
+
);
|
|
295
|
+
const portOverride = resolvePortOverride(
|
|
296
|
+
env,
|
|
297
|
+
config.port,
|
|
298
|
+
config.portEnvVar,
|
|
299
|
+
config.portEnvVar ? lookupEnvOverride(config.portEnvVar, zshrcEnv) : undefined,
|
|
300
|
+
);
|
|
301
|
+
|
|
302
|
+
if (!portOverride.ok) {
|
|
303
|
+
return yield* new DbConnectionError({
|
|
304
|
+
message: portOverride.message,
|
|
305
|
+
environment: env,
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// A host override can flip the tunnel decision (a forwarded localhost port vs a directly
|
|
310
|
+
// reachable host), so re-derive the access mode whenever the override changed the host.
|
|
311
|
+
const needsTunnel =
|
|
312
|
+
host === config.host
|
|
313
|
+
? config.needsTunnel
|
|
314
|
+
: resolveDbAccessMode(
|
|
315
|
+
env,
|
|
316
|
+
host,
|
|
317
|
+
dbConfig.kubectl !== undefined,
|
|
318
|
+
config.allowedMutations,
|
|
319
|
+
).needsTunnel;
|
|
320
|
+
|
|
214
321
|
return {
|
|
215
322
|
...config,
|
|
323
|
+
host,
|
|
324
|
+
port: portOverride.port,
|
|
325
|
+
needsTunnel,
|
|
216
326
|
user: yield* resolveConfigString(config.user, env, "user", zshrcEnv),
|
|
217
327
|
database: yield* resolveConfigString(config.database, env, "database", zshrcEnv),
|
|
218
328
|
};
|
|
@@ -646,6 +756,8 @@ export class DbService extends Context.Service<
|
|
|
646
756
|
database: envConfig.database,
|
|
647
757
|
password: envConfig.password,
|
|
648
758
|
passwordEnvVar: envConfig.passwordEnvVar,
|
|
759
|
+
hostEnvVar: envConfig.hostEnvVar,
|
|
760
|
+
portEnvVar: envConfig.portEnvVar,
|
|
649
761
|
...resolveEnvironmentScopedPrerequisites(dbConfig, envConfig),
|
|
650
762
|
port: envConfig.port,
|
|
651
763
|
needsTunnel: accessMode.needsTunnel,
|
package/src/db-tool/types.ts
CHANGED