@owlmeans/postgres 0.1.18-rc.22 → 0.1.18-rc.24
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 +2 -2
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/postgres/SKILL.md +1 -1
- package/build/health.d.ts +40 -0
- package/build/health.d.ts.map +1 -0
- package/build/health.js +80 -0
- package/build/health.js.map +1 -0
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ provisioning, and an opt-in least-privilege bootstrap path.
|
|
|
14
14
|
## Installation
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
|
-
bun add @owlmeans/postgres@^0.1.18-rc.
|
|
17
|
+
bun add @owlmeans/postgres@^0.1.18-rc.23 @owlmeans/postgres-resource@^0.1.18-rc.22
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
## Usage
|
|
@@ -129,7 +129,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
|
|
|
129
129
|
your project's skill store (`.agents/skills/`):
|
|
130
130
|
|
|
131
131
|
```sh
|
|
132
|
-
npx @owlmeans/agent-skills@^0.1.18-rc.
|
|
132
|
+
npx @owlmeans/agent-skills@^0.1.18-rc.22
|
|
133
133
|
```
|
|
134
134
|
|
|
135
135
|
The embedded files are version-matched to this package release. Do not edit them
|
package/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
3
|
"package": "@owlmeans/postgres",
|
|
4
|
-
"version": "0.1.18-rc.
|
|
5
|
-
"generatedAt": "2026-09-
|
|
4
|
+
"version": "0.1.18-rc.24",
|
|
5
|
+
"generatedAt": "2026-09-15T12:38:15.244Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -8,7 +8,7 @@ user-invocable: false
|
|
|
8
8
|
# @owlmeans/postgres
|
|
9
9
|
|
|
10
10
|
**Layer:** Infra
|
|
11
|
-
**Install:** `"@owlmeans/postgres": "^0.1.18-rc.
|
|
11
|
+
**Install:** `"@owlmeans/postgres": "^0.1.18-rc.24"` in `dependencies`
|
|
12
12
|
|
|
13
13
|
Pooled `pg` connections for a server context, plus the admin path that provisions the role, database
|
|
14
14
|
and schema an app connects with. All DDL for application tables belongs to [[postgres-resource]] —
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { BasicConfig, BasicContext } from '@owlmeans/context';
|
|
2
|
+
export interface DbHealth {
|
|
3
|
+
ok: boolean;
|
|
4
|
+
/** One line fit for a boot log — states what was checked, not only whether it passed. */
|
|
5
|
+
summary: string;
|
|
6
|
+
error?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The outcome of the last {@link checkDbHealth} for the same pair of aliases.
|
|
10
|
+
*
|
|
11
|
+
* A request time handler wants the verdict of the boot check without paying for it again: the
|
|
12
|
+
* structure was reconciled once, at init, and re-asserting it per request buys nothing.
|
|
13
|
+
*/
|
|
14
|
+
export declare const getLastDbHealth: (alias?: string, configAlias?: string) => DbHealth | undefined;
|
|
15
|
+
/**
|
|
16
|
+
* Surface the Postgres fields (code/severity/detail/hint) an error carries — a bare `.message`
|
|
17
|
+
* hides the real FATAL/permission reason, and the cause chain is where the driver's error ends up
|
|
18
|
+
* once a resource wraps it.
|
|
19
|
+
*/
|
|
20
|
+
export declare const formatDbError: (error: unknown) => string;
|
|
21
|
+
/**
|
|
22
|
+
* Liveness only, through the context's own pool — no private client, no connection string, no
|
|
23
|
+
* migration journal. The service is looked up by alias exactly as any other consumer looks it up,
|
|
24
|
+
* so a health probe cannot end up connected differently from the app it reports on.
|
|
25
|
+
*
|
|
26
|
+
* The context arrives as an argument rather than as a module import: a handler is given the
|
|
27
|
+
* context that actually served the request (possibly an entity scoped derivative), and taking it
|
|
28
|
+
* as a parameter keeps this module out of the boot import cycle.
|
|
29
|
+
*/
|
|
30
|
+
export declare const pingDb: (context: BasicContext<BasicConfig>, alias?: string, configAlias?: string) => Promise<DbHealth>;
|
|
31
|
+
/**
|
|
32
|
+
* The boot gate check: wait for the service to be ready, then assert the connection still works.
|
|
33
|
+
*
|
|
34
|
+
* Structure is reconciled by the resources during the context's `init()`; if that succeeded the
|
|
35
|
+
* tables are correct by construction, and if it failed the process never got here. There is
|
|
36
|
+
* nothing left to assert beyond "the connection works", which is why this is a `SELECT 1` and not
|
|
37
|
+
* a schema walk. The result is cached for {@link getLastDbHealth}.
|
|
38
|
+
*/
|
|
39
|
+
export declare const checkDbHealth: (context: BasicContext<BasicConfig>, alias?: string, configAlias?: string) => Promise<DbHealth>;
|
|
40
|
+
//# sourceMappingURL=health.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../src/health.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAKlE,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,OAAO,CAAA;IACX,yFAAyF;IACzF,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAMD;;;;;GAKG;AACH,eAAO,MAAM,eAAe,WACnB,MAAM,gBAAgC,MAAM,KAClD,QAAQ,GAAG,SAAsD,CAAA;AAEpE;;;;GAIG;AACH,eAAO,MAAM,aAAa,UAAW,OAAO,KAAG,MAmB9C,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM,YACR,YAAY,CAAC,WAAW,CAAC,UAAS,MAAM,gBAAgC,MAAM,KACtF,OAAO,CAAC,QAAQ,CASlB,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,YACf,YAAY,CAAC,WAAW,CAAC,UAAS,MAAM,gBAAgC,MAAM,KACtF,OAAO,CAAC,QAAQ,CAelB,CAAA"}
|
package/build/health.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { DEFAULT_ALIAS } from './consts.js';
|
|
2
|
+
const lastHealth = new Map();
|
|
3
|
+
const keyOf = (alias, configAlias) => `${alias}:${configAlias ?? ''}`;
|
|
4
|
+
/**
|
|
5
|
+
* The outcome of the last {@link checkDbHealth} for the same pair of aliases.
|
|
6
|
+
*
|
|
7
|
+
* A request time handler wants the verdict of the boot check without paying for it again: the
|
|
8
|
+
* structure was reconciled once, at init, and re-asserting it per request buys nothing.
|
|
9
|
+
*/
|
|
10
|
+
export const getLastDbHealth = (alias = DEFAULT_ALIAS, configAlias) => lastHealth.get(keyOf(alias, configAlias));
|
|
11
|
+
/**
|
|
12
|
+
* Surface the Postgres fields (code/severity/detail/hint) an error carries — a bare `.message`
|
|
13
|
+
* hides the real FATAL/permission reason, and the cause chain is where the driver's error ends up
|
|
14
|
+
* once a resource wraps it.
|
|
15
|
+
*/
|
|
16
|
+
export const formatDbError = (error) => {
|
|
17
|
+
const parts = [];
|
|
18
|
+
const seen = new Set();
|
|
19
|
+
let current = error;
|
|
20
|
+
while (current != null && !seen.has(current)) {
|
|
21
|
+
seen.add(current);
|
|
22
|
+
const meta = [];
|
|
23
|
+
if (current.severity != null)
|
|
24
|
+
meta.push(`severity=${current.severity}`);
|
|
25
|
+
if (current.code != null)
|
|
26
|
+
meta.push(`code=${current.code}`);
|
|
27
|
+
if (current.detail != null)
|
|
28
|
+
meta.push(`detail=${current.detail}`);
|
|
29
|
+
if (current.hint != null)
|
|
30
|
+
meta.push(`hint=${current.hint}`);
|
|
31
|
+
const message = current.message ?? String(current);
|
|
32
|
+
parts.push(meta.length > 0 ? `${message} (${meta.join(', ')})` : message);
|
|
33
|
+
current = current.cause;
|
|
34
|
+
}
|
|
35
|
+
const joined = parts.join('; caused by: ');
|
|
36
|
+
return joined !== '' ? joined : String(error);
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Liveness only, through the context's own pool — no private client, no connection string, no
|
|
40
|
+
* migration journal. The service is looked up by alias exactly as any other consumer looks it up,
|
|
41
|
+
* so a health probe cannot end up connected differently from the app it reports on.
|
|
42
|
+
*
|
|
43
|
+
* The context arrives as an argument rather than as a module import: a handler is given the
|
|
44
|
+
* context that actually served the request (possibly an entity scoped derivative), and taking it
|
|
45
|
+
* as a parameter keeps this module out of the boot import cycle.
|
|
46
|
+
*/
|
|
47
|
+
export const pingDb = async (context, alias = DEFAULT_ALIAS, configAlias) => {
|
|
48
|
+
try {
|
|
49
|
+
const pool = await context.service(alias).client(configAlias);
|
|
50
|
+
await pool.query('SELECT 1');
|
|
51
|
+
return { ok: true, summary: 'DB reachable' };
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
return { ok: false, summary: 'DB unreachable', error: formatDbError(error) };
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* The boot gate check: wait for the service to be ready, then assert the connection still works.
|
|
59
|
+
*
|
|
60
|
+
* Structure is reconciled by the resources during the context's `init()`; if that succeeded the
|
|
61
|
+
* tables are correct by construction, and if it failed the process never got here. There is
|
|
62
|
+
* nothing left to assert beyond "the connection works", which is why this is a `SELECT 1` and not
|
|
63
|
+
* a schema walk. The result is cached for {@link getLastDbHealth}.
|
|
64
|
+
*/
|
|
65
|
+
export const checkDbHealth = async (context, alias = DEFAULT_ALIAS, configAlias) => {
|
|
66
|
+
let result;
|
|
67
|
+
try {
|
|
68
|
+
const service = context.service(alias);
|
|
69
|
+
await service.ready();
|
|
70
|
+
const pool = await service.client(configAlias);
|
|
71
|
+
await pool.query('SELECT 1');
|
|
72
|
+
result = { ok: true, summary: 'DB OK — connected; structure reconciled at init' };
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
result = { ok: false, summary: 'DB check failed', error: formatDbError(error) };
|
|
76
|
+
}
|
|
77
|
+
lastHealth.set(keyOf(alias, configAlias), result);
|
|
78
|
+
return result;
|
|
79
|
+
};
|
|
80
|
+
//# sourceMappingURL=health.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.js","sourceRoot":"","sources":["../src/health.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/postgres",
|
|
3
|
-
"version": "0.1.18-rc.
|
|
3
|
+
"version": "0.1.18-rc.24",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -22,17 +22,17 @@
|
|
|
22
22
|
}
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@owlmeans/basic-keys": "^0.1.18-rc.
|
|
26
|
-
"@owlmeans/context": "^0.1.18-rc.
|
|
27
|
-
"@owlmeans/postgres-resource": "^0.1.18-rc.
|
|
28
|
-
"@owlmeans/resource": "^0.1.18-rc.
|
|
29
|
-
"@owlmeans/server-context": "^0.1.18-rc.
|
|
25
|
+
"@owlmeans/basic-keys": "^0.1.18-rc.22",
|
|
26
|
+
"@owlmeans/context": "^0.1.18-rc.18",
|
|
27
|
+
"@owlmeans/postgres-resource": "^0.1.18-rc.23",
|
|
28
|
+
"@owlmeans/resource": "^0.1.18-rc.19",
|
|
29
|
+
"@owlmeans/server-context": "^0.1.18-rc.22",
|
|
30
30
|
"drizzle-orm": "~0.45.2",
|
|
31
31
|
"pg": "^8.22.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@owlmeans/dep-config": "workspace:*",
|
|
35
|
-
"@owlmeans/test-integration": "^0.1.18-rc.
|
|
35
|
+
"@owlmeans/test-integration": "^0.1.18-rc.18",
|
|
36
36
|
"@types/bun": "^1.4.0",
|
|
37
37
|
"@types/node": "^26.1.0",
|
|
38
38
|
"@types/pg": "^8.20.4",
|