pipework 0.17.0 → 0.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/dist/core/config/app-pool.d.ts +17 -0
- package/dist/core/config/app-pool.d.ts.map +1 -0
- package/dist/core/config/app-pool.js +18 -0
- package/dist/core/config/app-pool.js.map +1 -0
- package/dist/core/config/load.js +5 -5
- package/dist/core/config/load.js.map +1 -1
- package/dist/core/config/resolve.d.ts +12 -2
- package/dist/core/config/resolve.d.ts.map +1 -1
- package/dist/core/config/resolve.js +27 -9
- package/dist/core/config/resolve.js.map +1 -1
- package/dist/core/validation/rls-role.d.ts.map +1 -1
- package/dist/core/validation/rls-role.js +2 -1
- package/dist/core/validation/rls-role.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.17.1
|
|
4
|
+
|
|
5
|
+
- **Fix: 0.16.0's identity refusal no longer fires on an `appUrl`/`appTestUrl` value that transaction isolation never dials.** The refusal's claim — "test isolation is defeated" — was untrue for that arm under the default strategy: transaction isolation registers its single rolled-back connection as the pool override under the database's *base* key, and `getOrCreate(config, 'app')` falls back to that base override when no role-specific one is registered, so **the app-role pool is never created** and the app-test value only ever has to satisfy config resolution. Refusing a provably-inert value is a false positive, and it blocked consumers whose committed `.env.example` deliberately sets the app-test var equal to the app var for exactly this reason. Identical app-role values now resolve when the strategy never creates that pool, and are refused wherever it does — the refusal message then names the carve-out and the strategy that voided it, so a reader can see why the other case passes.
|
|
6
|
+
- **Scoped to the app-role pair's *value* identity.** The owner `url`/`testUrl` pair has no carve-out — that connection is dialed under every strategy — and **name**-identity (one env var serving both fields) still refuses in every mode, for both pairs: a single var carries no statement of intent and cannot be told from a typo, where two vars deliberately set equal is a documented decision.
|
|
7
|
+
- **The config layer catching up to a boundary the validation layer already drew.** 0.16.0 shipped `rlsProbeTarget`, which picks the RLS probe target by the same fact ("transaction isolation collapses every role onto the resolved `url`"). That fact is now named once, as `appPoolCreated(strategy)`, and both the new carve-out and `rlsProbeTarget` are expressed in terms of it so the two spellings cannot drift.
|
|
8
|
+
- **Nothing is claimed here about runtime dialing under `database`/`container` isolation.** Those strategies are declared in the config schema and are not yet honored by the test harness; the refusal they keep is the config-level one, which is what config resolution enforces. Relaxing only the provably-inert case is the conservative direction on purpose.
|
|
9
|
+
- **Known edge, named rather than left silent: `validateRlsRoles` is strategy-blind.** The *startup* leg (`manifold.start()`) probes `appUrl ?? url` unconditionally, so with `rls` configured under `PIPEWORK_ENV=test` it does open a connection to the app URL even under transaction isolation — for an identical value, that reaches the database `appUrl` points at. It is a read-only `pg_roles` probe, and the asymmetry is the one 0.16.0 stated from the other side ("At startup the probed connection is `appUrl ?? url`; at test bootstrap it is the connection tests actually execute on"). Making the startup leg strategy-aware is tracked separately.
|
|
10
|
+
- **These are the first `pnpm test` pins on either identity refusal.** 0.16.0 shipped both with no unit or contract coverage — the only assertion lived in `scripts/accept-demand-signals.sh`, which is not part of `pnpm test` and covers the owner pair alone. Both refusals, the carve-out, and its boundaries are now pinned at the `resolveDbUrl` and `loadConfig` levels.
|
|
11
|
+
|
|
12
|
+
- **Fix: config refusals on the app-role pair now name `appUrl`/`appTestUrl` instead of always saying `url`/`testUrl`.** The missing-test-var and name-identity messages hardcoded the owner field names, so a reader whose `appTestUrl` was wrong was told to go edit `testUrl` — including the code sample in the hint. The relaxation above makes deliberate app-var configuration more common, so these refusals get read more often.
|
|
13
|
+
|
|
3
14
|
## 0.17.0
|
|
4
15
|
|
|
5
16
|
- **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.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { IsolationStrategy } from './schema.js';
|
|
2
|
+
/**
|
|
3
|
+
* Whether the test harness ever creates the app-role pool under `strategy`.
|
|
4
|
+
*
|
|
5
|
+
* Transaction isolation registers its single rolled-back connection as the pool
|
|
6
|
+
* override under the database's *base* key (`src/test/plugin.ts`), and
|
|
7
|
+
* `getOrCreate(config, 'app')` falls back to that base override when no
|
|
8
|
+
* role-specific one is registered (`src/core/pipework.ts`) — so the app-role
|
|
9
|
+
* pool is never constructed and `appUrl`/`appTestUrl` are never dialed by it.
|
|
10
|
+
* Every other strategy resolves roles normally (`appUrl ?? url`) and creates it.
|
|
11
|
+
*
|
|
12
|
+
* This is the single statement of that fact: both the app-pair value-identity
|
|
13
|
+
* carve-out (`resolveDbUrl`) and the RLS probe target (`rlsProbeTarget`) are
|
|
14
|
+
* expressed in terms of it, so the two cannot drift apart.
|
|
15
|
+
*/
|
|
16
|
+
export declare function appPoolCreated(strategy: IsolationStrategy): boolean;
|
|
17
|
+
//# sourceMappingURL=app-pool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-pool.d.ts","sourceRoot":"","sources":["../../../src/core/config/app-pool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAEpD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAEnE"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether the test harness ever creates the app-role pool under `strategy`.
|
|
3
|
+
*
|
|
4
|
+
* Transaction isolation registers its single rolled-back connection as the pool
|
|
5
|
+
* override under the database's *base* key (`src/test/plugin.ts`), and
|
|
6
|
+
* `getOrCreate(config, 'app')` falls back to that base override when no
|
|
7
|
+
* role-specific one is registered (`src/core/pipework.ts`) — so the app-role
|
|
8
|
+
* pool is never constructed and `appUrl`/`appTestUrl` are never dialed by it.
|
|
9
|
+
* Every other strategy resolves roles normally (`appUrl ?? url`) and creates it.
|
|
10
|
+
*
|
|
11
|
+
* This is the single statement of that fact: both the app-pair value-identity
|
|
12
|
+
* carve-out (`resolveDbUrl`) and the RLS probe target (`rlsProbeTarget`) are
|
|
13
|
+
* expressed in terms of it, so the two cannot drift apart.
|
|
14
|
+
*/
|
|
15
|
+
export function appPoolCreated(strategy) {
|
|
16
|
+
return strategy !== 'transaction';
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=app-pool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-pool.js","sourceRoot":"","sources":["../../../src/core/config/app-pool.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,cAAc,CAAC,QAA2B;IACxD,OAAO,QAAQ,KAAK,aAAa,CAAA;AACnC,CAAC"}
|
package/dist/core/config/load.js
CHANGED
|
@@ -19,10 +19,13 @@ export function loadConfig(raw) {
|
|
|
19
19
|
}
|
|
20
20
|
function buildResolved(config, environment, baseDir) {
|
|
21
21
|
const dbMap = new Map();
|
|
22
|
+
// Defined here, not inline in the accessor, so the app-pair carve-out below
|
|
23
|
+
// and `isolationStrategy()` cannot answer the same question differently.
|
|
24
|
+
const isolationStrategyFor = (dbName) => config.test?.databases?.[dbName]?.isolation ?? config.test?.isolation ?? 'transaction';
|
|
22
25
|
for (const [name, dbConfig] of Object.entries(config.databases)) {
|
|
23
26
|
const url = resolveDbUrl(dbConfig.url, dbConfig.testUrl, environment, name);
|
|
24
27
|
const appUrl = dbConfig.appUrl !== undefined
|
|
25
|
-
? resolveDbUrl(dbConfig.appUrl, dbConfig.appTestUrl, environment, name)
|
|
28
|
+
? resolveDbUrl(dbConfig.appUrl, dbConfig.appTestUrl, environment, name, { strategy: isolationStrategyFor(name) })
|
|
26
29
|
: undefined;
|
|
27
30
|
dbMap.set(name, resolveDatabase(name, dbConfig, url, appUrl, baseDir));
|
|
28
31
|
}
|
|
@@ -101,10 +104,7 @@ function buildResolved(config, environment, baseDir) {
|
|
|
101
104
|
throw new ConfigError('Multiple databases configured — you must specify which one.', `Declared databases: ${declaredNames.join(', ')}\n\n Set defaultDatabase in pipework.config.ts to pick one.`);
|
|
102
105
|
},
|
|
103
106
|
isolationStrategy(dbName) {
|
|
104
|
-
|
|
105
|
-
if (perDb)
|
|
106
|
-
return perDb;
|
|
107
|
-
return config.test?.isolation ?? 'transaction';
|
|
107
|
+
return isolationStrategyFor(dbName);
|
|
108
108
|
},
|
|
109
109
|
};
|
|
110
110
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load.js","sourceRoot":"","sources":["../../../src/core/config/load.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,iBAAiB,EAAiF,MAAM,aAAa,CAAA;AAC9H,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AAsEpD,MAAM,UAAU,UAAU,CAAC,GAAY;IACrC,6EAA6E;IAC7E,2BAA2B;IAC3B,MAAM,OAAO,GAAG,oBAAoB,EAAE,IAAI,OAAO,CAAC,GAAG,EAAE,CAAA;IACvD,MAAM,MAAM,GAAG,iBAAiB,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;IAC/C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC/F,MAAM,IAAI,WAAW,CACnB,gCAAgC,MAAM,EAAE,EACxC,4DAA4D,CAC7D,CAAA;IACH,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAA;IAC1B,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,kBAAkB,EAAE,CAAA;IAC9D,OAAO,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,CAAA;AACpD,CAAC;AAED,SAAS,aAAa,CAAC,MAAiB,EAAE,WAAwB,EAAE,OAAe;IACjF,MAAM,KAAK,GAAG,IAAI,GAAG,EAA4B,CAAA;IAEjD,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;QAChE,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,CAAC,CAAA;QAC3E,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,KAAK,SAAS;YAC1C,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,UAAU,EAAE,WAAW,EAAE,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"load.js","sourceRoot":"","sources":["../../../src/core/config/load.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
import type { Environment } from './schema.js';
|
|
1
|
+
import type { Environment, IsolationStrategy } from './schema.js';
|
|
2
|
+
/**
|
|
3
|
+
* Passed when resolving the app-role pair (`appUrl`/`appTestUrl`), which carries
|
|
4
|
+
* the transaction-isolation carve-out on value-identity. Absent when resolving
|
|
5
|
+
* the owner pair (`url`/`testUrl`), which has no carve-out: that connection is
|
|
6
|
+
* dialed under every strategy.
|
|
7
|
+
*/
|
|
8
|
+
export interface AppRolePair {
|
|
9
|
+
/** This database's resolved test-isolation strategy. */
|
|
10
|
+
readonly strategy: IsolationStrategy;
|
|
11
|
+
}
|
|
2
12
|
export declare function resolveEnvironment(): Environment;
|
|
3
|
-
export declare function resolveDbUrl(envVarName: string, testEnvVarName: string | undefined, environment: Environment, dbName?: string): string;
|
|
13
|
+
export declare function resolveDbUrl(envVarName: string, testEnvVarName: string | undefined, environment: Environment, dbName?: string, appRolePair?: AppRolePair): string;
|
|
4
14
|
//# sourceMappingURL=resolve.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../../src/core/config/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../../src/core/config/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAIjE;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,wDAAwD;IACxD,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAA;CACrC;AAED,wBAAgB,kBAAkB,IAAI,WAAW,CAWhD;AAED,wBAAgB,YAAY,CAC1B,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,WAAW,EAAE,WAAW,EACxB,MAAM,CAAC,EAAE,MAAM,EACf,WAAW,CAAC,EAAE,WAAW,GACxB,MAAM,CAgFR"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ConfigError } from './errors.js';
|
|
2
|
+
import { appPoolCreated } from './app-pool.js';
|
|
2
3
|
export function resolveEnvironment() {
|
|
3
4
|
const explicit = process.env['PIPEWORK_ENV'];
|
|
4
5
|
if (explicit === 'test' || explicit === 'development' || explicit === 'production') {
|
|
@@ -11,14 +12,18 @@ export function resolveEnvironment() {
|
|
|
11
12
|
return 'production';
|
|
12
13
|
return 'development';
|
|
13
14
|
}
|
|
14
|
-
export function resolveDbUrl(envVarName, testEnvVarName, environment, dbName) {
|
|
15
|
+
export function resolveDbUrl(envVarName, testEnvVarName, environment, dbName, appRolePair) {
|
|
15
16
|
if (environment === 'test') {
|
|
17
|
+
// The pair being resolved, so every refusal below names the fields the
|
|
18
|
+
// reader actually has to edit rather than always saying url/testUrl.
|
|
19
|
+
const urlField = appRolePair !== undefined ? 'appUrl' : 'url';
|
|
20
|
+
const testUrlField = appRolePair !== undefined ? 'appTestUrl' : 'testUrl';
|
|
16
21
|
if (testEnvVarName === undefined) {
|
|
17
|
-
throw new ConfigError(`Database "${dbName ?? envVarName}" has no
|
|
22
|
+
throw new ConfigError(`Database "${dbName ?? envVarName}" has no ${testUrlField} configured, but environment is "test".`, `Add ${testUrlField} to your database config:\n\n` +
|
|
18
23
|
` databases: {\n` +
|
|
19
24
|
` ${dbName ?? 'app'}: {\n` +
|
|
20
|
-
`
|
|
21
|
-
`
|
|
25
|
+
` ${urlField}: '${envVarName}',\n` +
|
|
26
|
+
` ${testUrlField}: '${envVarName}_TEST', // <-- add this\n` +
|
|
22
27
|
` },\n` +
|
|
23
28
|
` }\n\n` +
|
|
24
29
|
`Then set ${envVarName}_TEST in your environment.`);
|
|
@@ -30,11 +35,11 @@ export function resolveDbUrl(envVarName, testEnvVarName, environment, dbName) {
|
|
|
30
35
|
// first: both fields reading one variable is a config-shape defect,
|
|
31
36
|
// regardless of what the variable holds.
|
|
32
37
|
if (testEnvVarName === envVarName) {
|
|
33
|
-
throw new ConfigError(`Database "${dbName ?? envVarName}" uses the same environment variable "${envVarName}" for
|
|
38
|
+
throw new ConfigError(`Database "${dbName ?? envVarName}" uses the same environment variable "${envVarName}" for ${urlField} and ${testUrlField} — test isolation is defeated.`, `${testUrlField} must be its own variable pointing at a separate database:\n\n` +
|
|
34
39
|
` databases: {\n` +
|
|
35
40
|
` ${dbName ?? 'app'}: {\n` +
|
|
36
|
-
`
|
|
37
|
-
`
|
|
41
|
+
` ${urlField}: '${envVarName}',\n` +
|
|
42
|
+
` ${testUrlField}: '${envVarName}_TEST', // <-- its own variable\n` +
|
|
38
43
|
` },\n` +
|
|
39
44
|
` }\n\n` +
|
|
40
45
|
`Then set ${envVarName}_TEST to a separate database's connection string.`);
|
|
@@ -42,9 +47,22 @@ export function resolveDbUrl(envVarName, testEnvVarName, environment, dbName) {
|
|
|
42
47
|
const value = process.env[testEnvVarName];
|
|
43
48
|
if (value !== undefined && value !== '') {
|
|
44
49
|
const urlValue = process.env[envVarName];
|
|
45
|
-
|
|
50
|
+
// 0.17.1: value-identity on the app-role pair is a false positive under a
|
|
51
|
+
// strategy that never creates the app-role pool — the value satisfies
|
|
52
|
+
// config resolution and is then never dialed by it. The refusal stands
|
|
53
|
+
// wherever the pool IS created, and for the owner pair in every mode.
|
|
54
|
+
// Name-identity above is NOT carved out: one env var serving both fields
|
|
55
|
+
// carries no intent and cannot be told from a typo.
|
|
56
|
+
const inert = appRolePair !== undefined && !appPoolCreated(appRolePair.strategy);
|
|
57
|
+
if (!inert && urlValue !== undefined && urlValue !== '' && urlValue === value) {
|
|
46
58
|
throw new ConfigError(`Database "${dbName ?? envVarName}": "${testEnvVarName}" and "${envVarName}" hold the identical connection string — test isolation is defeated.`, `Tests would run against the same database "${envVarName}" points at. ` +
|
|
47
|
-
`Point ${testEnvVarName} at a separate database.`
|
|
59
|
+
`Point ${testEnvVarName} at a separate database.` +
|
|
60
|
+
(appRolePair !== undefined
|
|
61
|
+
? `\n\nIdentical app-role values are accepted only under "transaction" isolation, ` +
|
|
62
|
+
`where the harness overrides every role onto one rolled-back connection and the ` +
|
|
63
|
+
`app-role pool is never created. This database resolves to "${appRolePair.strategy}" ` +
|
|
64
|
+
`isolation, which creates it — so ${testEnvVarName} is genuinely dialed here.`
|
|
65
|
+
: ''));
|
|
48
66
|
}
|
|
49
67
|
return value;
|
|
50
68
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../../src/core/config/resolve.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../../src/core/config/resolve.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAa9C,MAAM,UAAU,kBAAkB;IAChC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;IAC5C,IAAI,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,aAAa,IAAI,QAAQ,KAAK,YAAY,EAAE,CAAC;QACnF,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;IACvC,IAAI,OAAO,KAAK,MAAM;QAAE,OAAO,MAAM,CAAA;IACrC,IAAI,OAAO,KAAK,YAAY;QAAE,OAAO,YAAY,CAAA;IAEjD,OAAO,aAAa,CAAA;AACtB,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,UAAkB,EAClB,cAAkC,EAClC,WAAwB,EACxB,MAAe,EACf,WAAyB;IAEzB,IAAI,WAAW,KAAK,MAAM,EAAE,CAAC;QAC3B,uEAAuE;QACvE,qEAAqE;QACrE,MAAM,QAAQ,GAAG,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAA;QAC7D,MAAM,YAAY,GAAG,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAA;QAEzE,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;YACjC,MAAM,IAAI,WAAW,CACnB,aAAa,MAAM,IAAI,UAAU,YAAY,YAAY,yCAAyC,EAClG,OAAO,YAAY,+BAA+B;gBAClD,kBAAkB;gBAClB,OAAO,MAAM,IAAI,KAAK,OAAO;gBAC7B,SAAS,QAAQ,MAAM,UAAU,MAAM;gBACvC,SAAS,YAAY,MAAM,UAAU,4BAA4B;gBACjE,UAAU;gBACV,SAAS;gBACT,YAAY,UAAU,4BAA4B,CACnD,CAAA;QACH,CAAC;QAED,sEAAsE;QACtE,8DAA8D;QAC9D,yEAAyE;QACzE,2EAA2E;QAC3E,oEAAoE;QACpE,yCAAyC;QACzC,IAAI,cAAc,KAAK,UAAU,EAAE,CAAC;YAClC,MAAM,IAAI,WAAW,CACnB,aAAa,MAAM,IAAI,UAAU,yCAAyC,UAAU,SAAS,QAAQ,QAAQ,YAAY,gCAAgC,EACzJ,GAAG,YAAY,gEAAgE;gBAC/E,kBAAkB;gBAClB,OAAO,MAAM,IAAI,KAAK,OAAO;gBAC7B,SAAS,QAAQ,MAAM,UAAU,MAAM;gBACvC,SAAS,YAAY,MAAM,UAAU,oCAAoC;gBACzE,UAAU;gBACV,SAAS;gBACT,YAAY,UAAU,mDAAmD,CAC1E,CAAA;QACH,CAAC;QAED,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;QACzC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;YACxC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;YACxC,0EAA0E;YAC1E,sEAAsE;YACtE,uEAAuE;YACvE,sEAAsE;YACtE,yEAAyE;YACzE,oDAAoD;YACpD,MAAM,KAAK,GAAG,WAAW,KAAK,SAAS,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAA;YAChF,IAAI,CAAC,KAAK,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,EAAE,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;gBAC9E,MAAM,IAAI,WAAW,CACnB,aAAa,MAAM,IAAI,UAAU,OAAO,cAAc,UAAU,UAAU,sEAAsE,EAChJ,8CAA8C,UAAU,eAAe;oBACvE,SAAS,cAAc,0BAA0B;oBACjD,CAAC,WAAW,KAAK,SAAS;wBACxB,CAAC,CAAC,iFAAiF;4BACjF,iFAAiF;4BACjF,8DAA8D,WAAW,CAAC,QAAQ,IAAI;4BACtF,oCAAoC,cAAc,4BAA4B;wBAChF,CAAC,CAAC,EAAE,CAAC,CACR,CAAA;YACH,CAAC;YACD,OAAO,KAAK,CAAA;QACd,CAAC;QAED,MAAM,IAAI,WAAW,CACnB,oDAAoD,cAAc,eAAe,EACjF,OAAO,cAAc,oCAAoC,CAC1D,CAAA;IACH,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;IACrC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,KAAK,CAAA;IAErD,MAAM,IAAI,WAAW,CACnB,+CAA+C,UAAU,eAAe,EACxE,OAAO,UAAU,oCAAoC,CACtD,CAAA;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rls-role.d.ts","sourceRoot":"","sources":["../../../src/core/validation/rls-role.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"rls-role.d.ts","sourceRoot":"","sources":["../../../src/core/validation/rls-role.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAQ5D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;IAC3B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;CAC5B;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,MAAM,CAQ5E;AAED,oOAAoO;AACpO,wBAAgB,cAAc,CAAC,EAAE,EAAE,gBAAgB,EAAE,QAAQ,EAAE,iBAAiB,GAAG,MAAM,CAExF;AAED,4GAA4G;AAC5G,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,SAAO,GAAG,OAAO,CAAC,YAAY,CAAC,CAmBvF;AAED,4IAA4I;AAC5I,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,EAChD,SAAS,SAAO,GACf,OAAO,CAAC,eAAe,EAAE,CAAC,CAoB5B"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { appPoolCreated } from '../config/app-pool.js';
|
|
1
2
|
export function rlsRoleMessage(database, probe) {
|
|
2
3
|
const flag = probe.superuser ? 'SUPERUSER' : 'BYPASSRLS';
|
|
3
4
|
return (`database "${database}" has rls configured, but its runtime role "${probe.role}" is ${flag} — ` +
|
|
@@ -7,7 +8,7 @@ export function rlsRoleMessage(database, probe) {
|
|
|
7
8
|
}
|
|
8
9
|
/** The connection whose role actually executes queries under the harness: transaction isolation collapses every role onto the resolved `url` connection; database/container isolation resolves roles normally (`appUrl ?? url`). */
|
|
9
10
|
export function rlsProbeTarget(db, strategy) {
|
|
10
|
-
return strategy
|
|
11
|
+
return appPoolCreated(strategy) ? (db.appUrl ?? db.url) : db.url;
|
|
11
12
|
}
|
|
12
13
|
/** Role flags for `current_user` at `url`. Short-lived probe connection, mirroring validateConnectivity. */
|
|
13
14
|
export async function probeRlsRole(url, timeoutMs = 5000) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rls-role.js","sourceRoot":"","sources":["../../../src/core/validation/rls-role.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rls-role.js","sourceRoot":"","sources":["../../../src/core/validation/rls-role.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAatD,MAAM,UAAU,cAAc,CAAC,QAAgB,EAAE,KAAmB;IAClE,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAA;IACxD,OAAO,CACL,aAAa,QAAQ,+CAA+C,KAAK,CAAC,IAAI,QAAQ,IAAI,KAAK;QAC/F,+EAA+E;QAC/E,mGAAmG;QACnG,4EAA4E,CAC7E,CAAA;AACH,CAAC;AAED,oOAAoO;AACpO,MAAM,UAAU,cAAc,CAAC,EAAoB,EAAE,QAA2B;IAC9E,OAAO,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAA;AAClE,CAAC;AAED,4GAA4G;AAC5G,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAW,EAAE,SAAS,GAAG,IAAI;IAC9D,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAA;IACtD,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,EAAE;QACxB,GAAG,EAAE,CAAC;QACN,YAAY,EAAE,CAAC;QACf,eAAe,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QAC5C,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC;KACnB,CAAC,CAAA;IAEF,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,GAAG,CAAA,gGAAgG,CAAA;QACtH,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAA2E,CAAA;QAC7F,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAA;QACvD,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,CAAC,YAAY,EAAE,CAAA;IACjF,CAAC;YAAS,CAAC;QACT,MAAM,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAA;IAC/B,CAAC;AACH,CAAC;AAED,4IAA4I;AAC5I,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,SAAgD,EAChD,SAAS,GAAG,IAAI;IAEhB,MAAM,MAAM,GAAsB,EAAE,CAAA;IAEpC,MAAM,MAAM,GAAG,CAAC,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC;SACpC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,KAAK,SAAS,CAAC;SACxC,GAAG,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;QACxB,IAAI,KAAmB,CAAA;QACvB,IAAI,CAAC;YACH,KAAK,GAAG,MAAM,YAAY,CAAC,EAAE,CAAC,MAAM,IAAI,EAAE,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;QAC5D,CAAC;QAAC,MAAM,CAAC;YACP,6DAA6D;YAC7D,OAAM;QACR,CAAC;QACD,IAAI,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YACvC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,CAAA;QAC1E,CAAC;IACH,CAAC,CAAC,CAAA;IAEJ,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IACzB,OAAO,MAAM,CAAA;AACf,CAAC"}
|