@volontariapp/health-check 0.0.0-snap-398faec

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 (43) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/README.md +121 -0
  3. package/dist/index.d.ts +7 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +7 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/services/bridges/neo4j-bridge-health-provider.d.ts +7 -0
  8. package/dist/services/bridges/neo4j-bridge-health-provider.d.ts.map +1 -0
  9. package/dist/services/bridges/neo4j-bridge-health-provider.js +15 -0
  10. package/dist/services/bridges/neo4j-bridge-health-provider.js.map +1 -0
  11. package/dist/services/bridges/postgres-bridge-health-provider.d.ts +7 -0
  12. package/dist/services/bridges/postgres-bridge-health-provider.d.ts.map +1 -0
  13. package/dist/services/bridges/postgres-bridge-health-provider.js +15 -0
  14. package/dist/services/bridges/postgres-bridge-health-provider.js.map +1 -0
  15. package/dist/services/bridges/redis-bridge-health-provider.d.ts +7 -0
  16. package/dist/services/bridges/redis-bridge-health-provider.d.ts.map +1 -0
  17. package/dist/services/bridges/redis-bridge-health-provider.js +15 -0
  18. package/dist/services/bridges/redis-bridge-health-provider.js.map +1 -0
  19. package/dist/services/database-health-types.d.ts +9 -0
  20. package/dist/services/database-health-types.d.ts.map +1 -0
  21. package/dist/services/database-health-types.js +2 -0
  22. package/dist/services/database-health-types.js.map +1 -0
  23. package/dist/services/database-health.orchestrator.d.ts +12 -0
  24. package/dist/services/database-health.orchestrator.d.ts.map +1 -0
  25. package/dist/services/database-health.orchestrator.js +15 -0
  26. package/dist/services/database-health.orchestrator.js.map +1 -0
  27. package/dist/services/database-health.provider.d.ts +10 -0
  28. package/dist/services/database-health.provider.d.ts.map +1 -0
  29. package/dist/services/database-health.provider.js +40 -0
  30. package/dist/services/database-health.provider.js.map +1 -0
  31. package/dist/test/int/config.example.d.ts +5 -0
  32. package/dist/test/int/config.example.d.ts.map +1 -0
  33. package/dist/test/int/config.example.js +66 -0
  34. package/dist/test/int/config.example.js.map +1 -0
  35. package/dist/test/int/database-health.int.spec.d.ts +2 -0
  36. package/dist/test/int/database-health.int.spec.d.ts.map +1 -0
  37. package/dist/test/int/database-health.int.spec.js +42 -0
  38. package/dist/test/int/database-health.int.spec.js.map +1 -0
  39. package/dist/test/unit/database-health.unit.spec.d.ts +2 -0
  40. package/dist/test/unit/database-health.unit.spec.d.ts.map +1 -0
  41. package/dist/test/unit/database-health.unit.spec.js +52 -0
  42. package/dist/test/unit/database-health.unit.spec.js.map +1 -0
  43. package/package.json +50 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,72 @@
1
+ # Changelog
2
+
3
+ ## 0.1.7
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies []:
8
+ - @volontariapp/bridge@0.2.5
9
+ - @volontariapp/config@1.1.2
10
+
11
+ ## 0.1.6
12
+
13
+ ### Patch Changes
14
+
15
+ - Standardize test and coverage scripts across packages. Add test:coverage with json-summary reporter for CI reporting.
16
+
17
+ - Updated dependencies []:
18
+ - @volontariapp/bridge@0.2.4
19
+ - @volontariapp/config@1.1.1
20
+ - @volontariapp/errors@0.4.4
21
+
22
+ ## 0.1.5
23
+
24
+ ### Patch Changes
25
+
26
+ - Updated dependencies []:
27
+ - @volontariapp/errors@0.4.3
28
+
29
+ ## 0.1.4
30
+
31
+ ### Patch Changes
32
+
33
+ - Updated dependencies []:
34
+ - @volontariapp/config@1.1.0
35
+
36
+ ## 0.1.3
37
+
38
+ ### Patch Changes
39
+
40
+ - bump global version
41
+
42
+ - Updated dependencies []:
43
+ - @volontariapp/bridge@0.2.3
44
+ - @volontariapp/config@1.0.2
45
+ - @volontariapp/errors@0.4.2
46
+
47
+ ## 0.1.2
48
+
49
+ ### Patch Changes
50
+
51
+ - bump ci
52
+
53
+ - Updated dependencies []:
54
+ - @volontariapp/bridge@0.2.2
55
+ - @volontariapp/config@1.0.1
56
+ - @volontariapp/errors@0.4.1
57
+
58
+ ## 0.1.1
59
+
60
+ ### Patch Changes
61
+
62
+ - Updated dependencies []:
63
+ - @volontariapp/errors@0.4.0
64
+ - @volontariapp/bridge@0.2.1
65
+
66
+ All notable changes to this project will be documented in this file.
67
+
68
+ ## 0.1.0
69
+
70
+ ### Minor Changes
71
+
72
+ - Initial package scaffold.
package/README.md ADDED
@@ -0,0 +1,121 @@
1
+ # @volontariapp/health-check
2
+
3
+ Bibliothèque Node.js pure pour vérifier la santé des connexions base de données déjà instanciées.
4
+
5
+ Objectif principal:
6
+ - Bridge crée et gère la connexion
7
+ - Health-check vérifie cette connexion
8
+
9
+ Cette lib ne doit pas instancier de base de données.
10
+
11
+ ## Ce que fait la librairie
12
+
13
+ - Fournit un contrat standard de résultat de santé
14
+ - Fournit un provider abstrait pour implémenter un check
15
+ - Fournit un orchestrateur pour agréger plusieurs checks
16
+ - Fournit des providers prêts à l'emploi branchés sur @volontariapp/bridge:
17
+ - PostgresBridgeHealthProvider
18
+ - RedisBridgeHealthProvider
19
+ - Neo4jBridgeHealthProvider
20
+
21
+ ## Installation
22
+
23
+ Depuis le monorepo:
24
+ - dépendance workspace déjà disponible
25
+
26
+ Depuis un projet externe:
27
+ - installer @volontariapp/health-check
28
+ - installer aussi @volontariapp/bridge
29
+
30
+ ## Utilisation rapide (Node pur)
31
+
32
+ ~~~ts
33
+ import {
34
+ DatabaseHealthOrchestrator,
35
+ PostgresBridgeHealthProvider,
36
+ RedisBridgeHealthProvider,
37
+ Neo4jBridgeHealthProvider,
38
+ } from '@volontariapp/health-check';
39
+ import {
40
+ PostgresProvider,
41
+ RedisProvider,
42
+ Neo4jProvider,
43
+ } from '@volontariapp/bridge';
44
+
45
+ const postgres = new PostgresProvider({
46
+ host: 'localhost',
47
+ port: 5432,
48
+ username: 'app',
49
+ password: 'app',
50
+ database: 'app_db',
51
+ entities: [],
52
+ synchronize: false,
53
+ });
54
+
55
+ const redis = new RedisProvider({
56
+ host: 'localhost',
57
+ port: 6379,
58
+ });
59
+
60
+ const neo4j = new Neo4jProvider({
61
+ url: 'bolt://localhost:7687',
62
+ authToken: {
63
+ principal: 'neo4j',
64
+ credentials: 'password',
65
+ },
66
+ });
67
+
68
+ await postgres.connect();
69
+ await redis.connect();
70
+ await neo4j.connect();
71
+
72
+ const orchestrator = new DatabaseHealthOrchestrator([
73
+ new PostgresBridgeHealthProvider(postgres),
74
+ new RedisBridgeHealthProvider(redis),
75
+ new Neo4jBridgeHealthProvider(neo4j),
76
+ ]);
77
+
78
+ const health = await orchestrator.run();
79
+ console.log(health);
80
+
81
+ await Promise.all([
82
+ postgres.disconnect(),
83
+ redis.disconnect(),
84
+ neo4j.disconnect(),
85
+ ]);
86
+ ~~~
87
+
88
+ ## Résultat attendu
89
+
90
+ Le résultat retourné par run() suit ce format:
91
+
92
+ ~~~ts
93
+ type OrchestratedHealthResult = {
94
+ status: 'ok' | 'error';
95
+ checks: Array<{
96
+ name: string;
97
+ status: 'up' | 'down';
98
+ message: string;
99
+ error?: {
100
+ name: string;
101
+ message: string;
102
+ };
103
+ }>;
104
+ };
105
+ ~~~
106
+
107
+ ## API exportée
108
+
109
+ - AbstractDatabaseHealthProvider
110
+ - DatabaseHealthOrchestrator
111
+ - PostgresBridgeHealthProvider
112
+ - RedisBridgeHealthProvider
113
+ - Neo4jBridgeHealthProvider
114
+
115
+ ## Bonnes pratiques
116
+
117
+ - Construire les connexions ailleurs (bridge, bridge-nest, bootstrap applicatif)
118
+ - Garder health-check focalisé sur la vérification
119
+ - Configurer host, port, credentials dans bridge, pas ici
120
+ - Réutiliser les mêmes instances pour l'app métier et le health endpoint
121
+
@@ -0,0 +1,7 @@
1
+ export * from './services/bridges/neo4j-bridge-health-provider.js';
2
+ export * from './services/bridges/postgres-bridge-health-provider.js';
3
+ export * from './services/bridges/redis-bridge-health-provider.js';
4
+ export * from './services/database-health-types.js';
5
+ export * from './services/database-health.provider.js';
6
+ export * from './services/database-health.orchestrator.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oDAAoD,CAAC;AACnE,cAAc,uDAAuD,CAAC;AACtE,cAAc,oDAAoD,CAAC;AAEnE,cAAc,qCAAqC,CAAC;AACpD,cAAc,wCAAwC,CAAC;AACvD,cAAc,4CAA4C,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export * from './services/bridges/neo4j-bridge-health-provider.js';
2
+ export * from './services/bridges/postgres-bridge-health-provider.js';
3
+ export * from './services/bridges/redis-bridge-health-provider.js';
4
+ export * from './services/database-health-types.js';
5
+ export * from './services/database-health.provider.js';
6
+ export * from './services/database-health.orchestrator.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oDAAoD,CAAC;AACnE,cAAc,uDAAuD,CAAC;AACtE,cAAc,oDAAoD,CAAC;AAEnE,cAAc,qCAAqC,CAAC;AACpD,cAAc,wCAAwC,CAAC;AACvD,cAAc,4CAA4C,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { type Neo4jProvider } from "@volontariapp/bridge";
2
+ import { AbstractDatabaseHealthProvider } from "../database-health.provider.js";
3
+ export declare class Neo4jBridgeHealthProvider extends AbstractDatabaseHealthProvider<Neo4jProvider> {
4
+ constructor(provider: Neo4jProvider);
5
+ protected pingDb(): Promise<void>;
6
+ }
7
+ //# sourceMappingURL=neo4j-bridge-health-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"neo4j-bridge-health-provider.d.ts","sourceRoot":"","sources":["../../../src/services/bridges/neo4j-bridge-health-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAM,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,8BAA8B,EAAE,MAAM,gCAAgC,CAAC;AAGhF,qBAAa,yBAA0B,SAAQ,8BAA8B,CAAC,aAAa,CAAC;gBAC9E,QAAQ,EAAE,aAAa;cAInB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;CAWxC"}
@@ -0,0 +1,15 @@
1
+ import { AbstractDatabaseHealthProvider } from "../database-health.provider.js";
2
+ import { InternalServerError } from "@volontariapp/errors";
3
+ export class Neo4jBridgeHealthProvider extends AbstractDatabaseHealthProvider {
4
+ constructor(provider) {
5
+ super('neo4j', provider);
6
+ }
7
+ async pingDb() {
8
+ if (!this.client.isConnected()) {
9
+ throw new InternalServerError('Neo4j provider is not connected', 'HEALTH_CHECK_NEO4J_NOT_CONNECTED');
10
+ }
11
+ const driver = this.client.getDriver();
12
+ await driver.verifyConnectivity();
13
+ }
14
+ }
15
+ //# sourceMappingURL=neo4j-bridge-health-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"neo4j-bridge-health-provider.js","sourceRoot":"","sources":["../../../src/services/bridges/neo4j-bridge-health-provider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,8BAA8B,EAAE,MAAM,gCAAgC,CAAC;AAChF,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3D,MAAM,OAAO,yBAA0B,SAAQ,8BAA6C;IAC1F,YAAY,QAAuB;QACjC,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC3B,CAAC;IAES,KAAK,CAAC,MAAM;QACpB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;YAC/B,MAAM,IAAI,mBAAmB,CAC3B,iCAAiC,EACjC,kCAAkC,CACnC,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACvC,MAAM,MAAM,CAAC,kBAAkB,EAAE,CAAC;IACpC,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ import { AbstractDatabaseHealthProvider } from "../database-health.provider.js";
2
+ import { type PostgresProvider } from "@volontariapp/bridge";
3
+ export declare class PostgresBridgeHealthProvider extends AbstractDatabaseHealthProvider<PostgresProvider> {
4
+ constructor(provider: PostgresProvider);
5
+ protected pingDb(): Promise<void>;
6
+ }
7
+ //# sourceMappingURL=postgres-bridge-health-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres-bridge-health-provider.d.ts","sourceRoot":"","sources":["../../../src/services/bridges/postgres-bridge-health-provider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,8BAA8B,EAAE,MAAM,gCAAgC,CAAC;AAChF,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,qBAAa,4BAA6B,SAAQ,8BAA8B,CAAC,gBAAgB,CAAC;gBACpF,QAAQ,EAAE,gBAAgB;cAItB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;CAWxC"}
@@ -0,0 +1,15 @@
1
+ import { InternalServerError } from "@volontariapp/errors";
2
+ import { AbstractDatabaseHealthProvider } from "../database-health.provider.js";
3
+ export class PostgresBridgeHealthProvider extends AbstractDatabaseHealthProvider {
4
+ constructor(provider) {
5
+ super('postgres', provider);
6
+ }
7
+ async pingDb() {
8
+ if (!this.client.isConnected()) {
9
+ throw new InternalServerError('Postgres provider is not connected', 'HEALTH_CHECK_POSTGRES_NOT_CONNECTED');
10
+ }
11
+ const driver = this.client.getDriver();
12
+ await driver.query('SELECT 1');
13
+ }
14
+ }
15
+ //# sourceMappingURL=postgres-bridge-health-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres-bridge-health-provider.js","sourceRoot":"","sources":["../../../src/services/bridges/postgres-bridge-health-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,8BAA8B,EAAE,MAAM,gCAAgC,CAAC;AAGhF,MAAM,OAAO,4BAA6B,SAAQ,8BAAgD;IAChG,YAAY,QAA0B;QACpC,KAAK,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAC9B,CAAC;IAES,KAAK,CAAC,MAAM;QACpB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;YAC/B,MAAM,IAAI,mBAAmB,CAC3B,oCAAoC,EACpC,qCAAqC,CACtC,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACvC,MAAM,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACjC,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ import { type RedisProvider } from "@volontariapp/bridge";
2
+ import { AbstractDatabaseHealthProvider } from "../database-health.provider.js";
3
+ export declare class RedisBridgeHealthProvider extends AbstractDatabaseHealthProvider<RedisProvider> {
4
+ constructor(provider: RedisProvider);
5
+ protected pingDb(): Promise<void>;
6
+ }
7
+ //# sourceMappingURL=redis-bridge-health-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-bridge-health-provider.d.ts","sourceRoot":"","sources":["../../../src/services/bridges/redis-bridge-health-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,8BAA8B,EAAE,MAAM,gCAAgC,CAAC;AAGhF,qBAAa,yBAA0B,SAAQ,8BAA8B,CAAC,aAAa,CAAC;gBAC9E,QAAQ,EAAE,aAAa;cAInB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;CAWxC"}
@@ -0,0 +1,15 @@
1
+ import { AbstractDatabaseHealthProvider } from "../database-health.provider.js";
2
+ import { InternalServerError } from "@volontariapp/errors";
3
+ export class RedisBridgeHealthProvider extends AbstractDatabaseHealthProvider {
4
+ constructor(provider) {
5
+ super('redis', provider);
6
+ }
7
+ async pingDb() {
8
+ if (!this.client.isConnected()) {
9
+ throw new InternalServerError('Redis provider is not connected', 'HEALTH_CHECK_REDIS_NOT_CONNECTED');
10
+ }
11
+ const driver = this.client.getDriver();
12
+ await driver.ping();
13
+ }
14
+ }
15
+ //# sourceMappingURL=redis-bridge-health-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-bridge-health-provider.js","sourceRoot":"","sources":["../../../src/services/bridges/redis-bridge-health-provider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,8BAA8B,EAAE,MAAM,gCAAgC,CAAC;AAChF,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3D,MAAM,OAAO,yBAA0B,SAAQ,8BAA6C;IAC1F,YAAY,QAAuB;QACjC,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC3B,CAAC;IAES,KAAK,CAAC,MAAM;QACpB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;YAC/B,MAAM,IAAI,mBAAmB,CAC3B,iCAAiC,EACjC,kCAAkC,CACnC,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACvC,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;IACtB,CAAC;CACF"}
@@ -0,0 +1,9 @@
1
+ import { type DatabaseHealthError } from '@volontariapp/errors';
2
+ export type DatabaseHealthStatus = 'up' | 'down';
3
+ export interface DatabaseHealthResult {
4
+ name: string;
5
+ status: DatabaseHealthStatus;
6
+ message: string;
7
+ error?: DatabaseHealthError;
8
+ }
9
+ //# sourceMappingURL=database-health-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database-health-types.d.ts","sourceRoot":"","sources":["../../src/services/database-health-types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAEhE,MAAM,MAAM,oBAAoB,GAAG,IAAI,GAAG,MAAM,CAAC;AAEjD,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,oBAAoB,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,mBAAmB,CAAC;CAC7B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=database-health-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database-health-types.js","sourceRoot":"","sources":["../../src/services/database-health-types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,12 @@
1
+ import type { DatabaseHealthResult } from './database-health-types.js';
2
+ import type { AbstractDatabaseHealthProvider } from './database-health.provider.js';
3
+ export interface OrchestratedHealthResult {
4
+ status: 'ok' | 'error';
5
+ checks: DatabaseHealthResult[];
6
+ }
7
+ export declare class DatabaseHealthOrchestrator {
8
+ private readonly providers;
9
+ constructor(providers: ReadonlyArray<AbstractDatabaseHealthProvider>);
10
+ run(): Promise<OrchestratedHealthResult>;
11
+ }
12
+ //# sourceMappingURL=database-health.orchestrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database-health.orchestrator.d.ts","sourceRoot":"","sources":["../../src/services/database-health.orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,+BAA+B,CAAC;AAEpF,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,IAAI,GAAG,OAAO,CAAC;IACvB,MAAM,EAAE,oBAAoB,EAAE,CAAC;CAChC;AAED,qBAAa,0BAA0B;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,aAAa,CAAC,8BAA8B,CAAC;IAE/E,GAAG,IAAI,OAAO,CAAC,wBAAwB,CAAC;CAS/C"}
@@ -0,0 +1,15 @@
1
+ export class DatabaseHealthOrchestrator {
2
+ providers;
3
+ constructor(providers) {
4
+ this.providers = providers;
5
+ }
6
+ async run() {
7
+ const checks = await Promise.all(this.providers.map((provider) => provider.health()));
8
+ const isHealthy = checks.every((check) => check.status === 'up');
9
+ return {
10
+ status: isHealthy ? 'ok' : 'error',
11
+ checks,
12
+ };
13
+ }
14
+ }
15
+ //# sourceMappingURL=database-health.orchestrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database-health.orchestrator.js","sourceRoot":"","sources":["../../src/services/database-health.orchestrator.ts"],"names":[],"mappings":"AAQA,MAAM,OAAO,0BAA0B;IACR;IAA7B,YAA6B,SAAwD;QAAxD,cAAS,GAAT,SAAS,CAA+C;IAAG,CAAC;IAEzF,KAAK,CAAC,GAAG;QACP,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACtF,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC;QAEjE,OAAO;YACL,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO;YAClC,MAAM;SACP,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,10 @@
1
+ import type { DatabaseHealthResult } from './database-health-types.js';
2
+ export declare abstract class AbstractDatabaseHealthProvider<TClient = unknown> {
3
+ readonly name: string;
4
+ protected readonly client: TClient;
5
+ protected constructor(name: string, client: TClient);
6
+ protected abstract pingDb(): Promise<void>;
7
+ health(): Promise<DatabaseHealthResult>;
8
+ private normalizeError;
9
+ }
10
+ //# sourceMappingURL=database-health.provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database-health.provider.d.ts","sourceRoot":"","sources":["../../src/services/database-health.provider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAEvE,8BAAsB,8BAA8B,CAAC,OAAO,GAAG,OAAO;aAElD,IAAI,EAAE,MAAM;IAC5B,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO;IAFpC,SAAS,aACS,IAAI,EAAE,MAAM,EACT,MAAM,EAAE,OAAO;IAGpC,SAAS,CAAC,QAAQ,CAAC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAEpC,MAAM,IAAI,OAAO,CAAC,oBAAoB,CAAC;IAmB7C,OAAO,CAAC,cAAc;CAavB"}
@@ -0,0 +1,40 @@
1
+ import { DatabaseHealthError } from '@volontariapp/errors';
2
+ export class AbstractDatabaseHealthProvider {
3
+ name;
4
+ client;
5
+ constructor(name, client) {
6
+ this.name = name;
7
+ this.client = client;
8
+ }
9
+ async health() {
10
+ try {
11
+ await this.pingDb();
12
+ return {
13
+ name: this.name,
14
+ status: 'up',
15
+ message: `${this.name} connection is healthy`,
16
+ };
17
+ }
18
+ catch (error) {
19
+ const normalizedError = this.normalizeError(error);
20
+ return {
21
+ name: this.name,
22
+ status: 'down',
23
+ message: `${this.name} connection failed`,
24
+ error: normalizedError,
25
+ };
26
+ }
27
+ }
28
+ normalizeError(error) {
29
+ if (error instanceof Error) {
30
+ return new DatabaseHealthError(error.message, 'DATABASE_HEALTH_ERROR', {
31
+ causeName: error.name,
32
+ });
33
+ }
34
+ if (typeof error === 'string') {
35
+ return new DatabaseHealthError(error);
36
+ }
37
+ return new DatabaseHealthError('Unknown error while pinging database');
38
+ }
39
+ }
40
+ //# sourceMappingURL=database-health.provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database-health.provider.js","sourceRoot":"","sources":["../../src/services/database-health.provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAG3D,MAAM,OAAgB,8BAA8B;IAEhC;IACG;IAFrB,YACkB,IAAY,EACT,MAAe;QADlB,SAAI,GAAJ,IAAI,CAAQ;QACT,WAAM,GAAN,MAAM,CAAS;IACjC,CAAC;IAIJ,KAAK,CAAC,MAAM;QACV,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;YACpB,OAAO;gBACL,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,MAAM,EAAE,IAAI;gBACZ,OAAO,EAAE,GAAG,IAAI,CAAC,IAAI,wBAAwB;aAC9C,CAAC;QACJ,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,MAAM,eAAe,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;YACnD,OAAO;gBACL,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,GAAG,IAAI,CAAC,IAAI,oBAAoB;gBACzC,KAAK,EAAE,eAAe;aACvB,CAAC;QACJ,CAAC;IACH,CAAC;IAEO,cAAc,CAAC,KAAc;QACnC,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,OAAO,IAAI,mBAAmB,CAAC,KAAK,CAAC,OAAO,EAAE,uBAAuB,EAAE;gBACrE,SAAS,EAAE,KAAK,CAAC,IAAI;aACtB,CAAC,CAAC;QACL,CAAC;QAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,IAAI,mBAAmB,CAAC,KAAK,CAAC,CAAC;QACxC,CAAC;QAED,OAAO,IAAI,mBAAmB,CAAC,sCAAsC,CAAC,CAAC;IACzE,CAAC;CACF"}
@@ -0,0 +1,5 @@
1
+ import type { IPostgresConfig, INeo4jConfig, IRedisConfig } from '@volontariapp/bridge';
2
+ export declare const postgresConfig: IPostgresConfig;
3
+ export declare const neo4jConfig: INeo4jConfig;
4
+ export declare const redisConfig: IRedisConfig;
5
+ //# sourceMappingURL=config.example.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.example.d.ts","sourceRoot":"","sources":["../../../src/test/int/config.example.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AA8BxF,eAAO,MAAM,cAAc,EAAE,eAQ5B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,YAOzB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,YAOzB,CAAC"}
@@ -0,0 +1,66 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { dirname, resolve } from 'node:path';
11
+ import { fileURLToPath } from 'node:url';
12
+ import { Type } from 'class-transformer';
13
+ import { IsDefined, ValidateNested } from 'class-validator';
14
+ import { BaseConfig, Neo4jConfig, PostgresConfig, RedisConfig, loadConfig, } from '@volontariapp/config';
15
+ class IntegrationConfig extends BaseConfig {
16
+ postgres;
17
+ neo4j;
18
+ redis;
19
+ }
20
+ __decorate([
21
+ IsDefined(),
22
+ ValidateNested(),
23
+ Type(() => PostgresConfig),
24
+ __metadata("design:type", PostgresConfig)
25
+ ], IntegrationConfig.prototype, "postgres", void 0);
26
+ __decorate([
27
+ IsDefined(),
28
+ ValidateNested(),
29
+ Type(() => Neo4jConfig),
30
+ __metadata("design:type", Neo4jConfig)
31
+ ], IntegrationConfig.prototype, "neo4j", void 0);
32
+ __decorate([
33
+ IsDefined(),
34
+ ValidateNested(),
35
+ Type(() => RedisConfig),
36
+ __metadata("design:type", RedisConfig)
37
+ ], IntegrationConfig.prototype, "redis", void 0);
38
+ const currentDir = dirname(fileURLToPath(import.meta.url));
39
+ const configDir = resolve(currentDir, '../config');
40
+ const config = loadConfig(configDir, IntegrationConfig);
41
+ export const postgresConfig = {
42
+ host: config.postgres.host,
43
+ port: config.postgres.port,
44
+ username: config.postgres.username,
45
+ password: config.postgres.password,
46
+ database: config.postgres.database,
47
+ synchronize: true,
48
+ ssl: config.postgres.ssl,
49
+ };
50
+ export const neo4jConfig = {
51
+ url: `${config.neo4j.scheme}://${config.neo4j.host}:${String(config.neo4j.port)}`,
52
+ authToken: {
53
+ scheme: config.neo4j.scheme,
54
+ principal: config.neo4j.username,
55
+ credentials: config.neo4j.password,
56
+ },
57
+ };
58
+ export const redisConfig = {
59
+ host: config.redis.host,
60
+ port: config.redis.port,
61
+ username: config.redis.username,
62
+ password: config.redis.password,
63
+ db: config.redis.dbIndex,
64
+ keyPrefix: config.redis.keyPrefix,
65
+ };
66
+ //# sourceMappingURL=config.example.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.example.js","sourceRoot":"","sources":["../../../src/test/int/config.example.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAE5D,OAAO,EACL,UAAU,EACV,WAAW,EACX,cAAc,EACd,WAAW,EACX,UAAU,GACX,MAAM,sBAAsB,CAAC;AAE9B,MAAM,iBAAkB,SAAQ,UAAU;IAIxC,QAAQ,CAAkB;IAK1B,KAAK,CAAe;IAKpB,KAAK,CAAe;CACrB;AAXC;IAHC,SAAS,EAAE;IACX,cAAc,EAAE;IAChB,IAAI,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC;8BAChB,cAAc;mDAAC;AAK1B;IAHC,SAAS,EAAE;IACX,cAAc,EAAE;IAChB,IAAI,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC;8BAChB,WAAW;gDAAC;AAKpB;IAHC,SAAS,EAAE;IACX,cAAc,EAAE;IAChB,IAAI,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC;8BAChB,WAAW;gDAAC;AAGtB,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC3D,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;AACnD,MAAM,MAAM,GAAG,UAAU,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;AAExD,MAAM,CAAC,MAAM,cAAc,GAAoB;IAC7C,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI;IAC1B,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI;IAC1B,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ;IAClC,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ;IAClC,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ;IAClC,WAAW,EAAE,IAAI;IACjB,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,GAAG;CACzB,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAiB;IACvC,GAAG,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,MAAM,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;IACjF,SAAS,EAAE;QACT,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM;QAC3B,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ;QAChC,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ;KACnC;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAiB;IACvC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI;IACvB,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI;IACvB,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ;IAC/B,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ;IAC/B,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO;IACxB,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS;CAClC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=database-health.int.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database-health.int.spec.d.ts","sourceRoot":"","sources":["../../../src/test/int/database-health.int.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,42 @@
1
+ import { describe, it, expect, beforeAll, afterAll } from '@jest/globals';
2
+ import { Neo4jProvider, PostgresProvider, RedisProvider } from '@volontariapp/bridge';
3
+ import { DatabaseHealthOrchestrator, Neo4jBridgeHealthProvider, PostgresBridgeHealthProvider, RedisBridgeHealthProvider, } from '../../index.js';
4
+ import { neo4jConfig, postgresConfig, redisConfig } from './config.example.js';
5
+ describe('Database health (Integration)', () => {
6
+ let postgresProvider;
7
+ let neo4jProvider;
8
+ let redisProvider;
9
+ beforeAll(async () => {
10
+ postgresProvider = new PostgresProvider(postgresConfig);
11
+ neo4jProvider = new Neo4jProvider(neo4jConfig);
12
+ redisProvider = new RedisProvider(redisConfig);
13
+ await postgresProvider.connect();
14
+ await neo4jProvider.connect();
15
+ await redisProvider.connect();
16
+ });
17
+ afterAll(async () => {
18
+ if (postgresProvider.isConnected()) {
19
+ await postgresProvider.disconnect();
20
+ }
21
+ if (neo4jProvider.isConnected()) {
22
+ await neo4jProvider.disconnect();
23
+ }
24
+ if (redisProvider.isConnected()) {
25
+ await redisProvider.disconnect();
26
+ }
27
+ });
28
+ it('should report postgres, neo4j and redis as healthy', async () => {
29
+ const orchestrator = new DatabaseHealthOrchestrator([
30
+ new PostgresBridgeHealthProvider(postgresProvider),
31
+ new Neo4jBridgeHealthProvider(neo4jProvider),
32
+ new RedisBridgeHealthProvider(redisProvider),
33
+ ]);
34
+ const result = await orchestrator.run();
35
+ expect(result.status).toBe('ok');
36
+ expect(result.checks).toHaveLength(3);
37
+ expect(result.checks.find((check) => check.name === 'postgres')?.status).toBe('up');
38
+ expect(result.checks.find((check) => check.name === 'neo4j')?.status).toBe('up');
39
+ expect(result.checks.find((check) => check.name === 'redis')?.status).toBe('up');
40
+ });
41
+ });
42
+ //# sourceMappingURL=database-health.int.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database-health.int.spec.js","sourceRoot":"","sources":["../../../src/test/int/database-health.int.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACtF,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,4BAA4B,EAC5B,yBAAyB,GAC1B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAE/E,QAAQ,CAAC,+BAA+B,EAAE,GAAG,EAAE;IAC7C,IAAI,gBAAkC,CAAC;IACvC,IAAI,aAA4B,CAAC;IACjC,IAAI,aAA4B,CAAC;IAEjC,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,gBAAgB,GAAG,IAAI,gBAAgB,CAAC,cAAc,CAAC,CAAC;QACxD,aAAa,GAAG,IAAI,aAAa,CAAC,WAAW,CAAC,CAAC;QAC/C,aAAa,GAAG,IAAI,aAAa,CAAC,WAAW,CAAC,CAAC;QAE/C,MAAM,gBAAgB,CAAC,OAAO,EAAE,CAAC;QACjC,MAAM,aAAa,CAAC,OAAO,EAAE,CAAC;QAC9B,MAAM,aAAa,CAAC,OAAO,EAAE,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,KAAK,IAAI,EAAE;QAClB,IAAI,gBAAgB,CAAC,WAAW,EAAE,EAAE,CAAC;YACnC,MAAM,gBAAgB,CAAC,UAAU,EAAE,CAAC;QACtC,CAAC;QAED,IAAI,aAAa,CAAC,WAAW,EAAE,EAAE,CAAC;YAChC,MAAM,aAAa,CAAC,UAAU,EAAE,CAAC;QACnC,CAAC;QAED,IAAI,aAAa,CAAC,WAAW,EAAE,EAAE,CAAC;YAChC,MAAM,aAAa,CAAC,UAAU,EAAE,CAAC;QACnC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;QAClE,MAAM,YAAY,GAAG,IAAI,0BAA0B,CAAC;YAClD,IAAI,4BAA4B,CAAC,gBAAgB,CAAC;YAClD,IAAI,yBAAyB,CAAC,aAAa,CAAC;YAC5C,IAAI,yBAAyB,CAAC,aAAa,CAAC;SAC7C,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,CAAC;QAExC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACtC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,UAAU,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpF,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjF,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=database-health.unit.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database-health.unit.spec.d.ts","sourceRoot":"","sources":["../../../src/test/unit/database-health.unit.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,52 @@
1
+ import { describe, expect, it } from '@jest/globals';
2
+ import { DatabaseHealthError } from '@volontariapp/errors';
3
+ import { AbstractDatabaseHealthProvider, DatabaseHealthOrchestrator, } from '../../index.js';
4
+ class TestProvider extends AbstractDatabaseHealthProvider {
5
+ pingFn;
6
+ constructor(name, pingFn) {
7
+ super(name, {});
8
+ this.pingFn = pingFn;
9
+ }
10
+ async pingDb() {
11
+ await this.pingFn();
12
+ }
13
+ }
14
+ describe('Database health core', () => {
15
+ it('returns up when ping succeeds', async () => {
16
+ const provider = new TestProvider('postgres', async () => Promise.resolve());
17
+ await expect(provider.health()).resolves.toEqual({
18
+ name: 'postgres',
19
+ status: 'up',
20
+ message: 'postgres connection is healthy',
21
+ });
22
+ });
23
+ it('normalizes error when ping fails', async () => {
24
+ const provider = new TestProvider('redis', () => Promise.reject(new Error('boom')));
25
+ const result = await provider.health();
26
+ expect(result).toMatchObject({
27
+ name: 'redis',
28
+ status: 'down',
29
+ message: 'redis connection failed',
30
+ });
31
+ expect(result.error).toBeInstanceOf(DatabaseHealthError);
32
+ expect(result.error).toMatchObject({
33
+ name: 'DatabaseHealthError',
34
+ message: 'boom',
35
+ code: 'DATABASE_HEALTH_ERROR',
36
+ details: {
37
+ causeName: 'Error',
38
+ },
39
+ });
40
+ });
41
+ it('aggregates providers status in orchestrator', async () => {
42
+ const healthyProvider = new TestProvider('postgres', async () => Promise.resolve());
43
+ const failingProvider = new TestProvider('neo4j', () => Promise.reject(new Error('neo4j unavailable')));
44
+ const orchestrator = new DatabaseHealthOrchestrator([healthyProvider, failingProvider]);
45
+ const result = await orchestrator.run();
46
+ expect(result.status).toBe('error');
47
+ expect(result.checks).toHaveLength(2);
48
+ expect(result.checks.find((check) => check.name === 'postgres')?.status).toBe('up');
49
+ expect(result.checks.find((check) => check.name === 'neo4j')?.status).toBe('down');
50
+ });
51
+ });
52
+ //# sourceMappingURL=database-health.unit.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database-health.unit.spec.js","sourceRoot":"","sources":["../../../src/test/unit/database-health.unit.spec.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@volontariapp/health-check",
3
+ "version": "0.0.0-snap-398faec",
4
+ "publishConfig": {
5
+ "access": "public",
6
+ "provenance": true
7
+ },
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/Volontariapp/npm-packages.git"
11
+ },
12
+ "description": "",
13
+ "license": "UNLICENSED",
14
+ "type": "module",
15
+ "main": "./dist/index.js",
16
+ "types": "./dist/index.d.ts",
17
+ "exports": {
18
+ ".": {
19
+ "types": "./dist/index.d.ts",
20
+ "import": "./dist/index.js"
21
+ }
22
+ },
23
+ "files": [
24
+ "dist"
25
+ ],
26
+ "engines": {
27
+ "node": ">=24.14.0"
28
+ },
29
+ "scripts": {
30
+ "build": "tsc -p tsconfig.json",
31
+ "lint": "eslint src/",
32
+ "test": "node --experimental-vm-modules $(yarn bin jest)",
33
+ "test:coverage": "node --experimental-vm-modules $(yarn bin jest) --coverage --coverageReporters=\"text\" --coverageReporters=\"json-summary\" --coverageReporters=\"lcov\"",
34
+ "test:watch": "node --experimental-vm-modules $(yarn bin jest) --watch"
35
+ },
36
+ "devDependencies": {
37
+ "@jest/globals": "^30.3.0",
38
+ "@types/jest": "^30.0.0",
39
+ "eslint": "9.18.0",
40
+ "jest": "^30.3.0",
41
+ "ts-jest": "^29.4.9",
42
+ "ts-node": "^10.9.2",
43
+ "typescript": "5.7.3"
44
+ },
45
+ "dependencies": {
46
+ "@volontariapp/bridge": "0.0.0-snap-398faec",
47
+ "@volontariapp/config": "0.0.0-snap-398faec",
48
+ "@volontariapp/errors": "0.4.4"
49
+ }
50
+ }