@nodefony/orm-core 10.0.0-alpha.2 → 10.0.0-alpha.3
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/dist/index.js +3 -1
- package/dist/nodefony/src/connectDeadline.js +67 -0
- package/dist/nodefony/src/connectionDiagnosis.js +112 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/nodefony/src/connectDeadline.d.ts +52 -0
- package/dist/types/nodefony/src/connectionDiagnosis.d.ts +58 -0
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -11,6 +11,8 @@ import { AbstractCrudService } from "./nodefony/src/AbstractCrudService.js";
|
|
|
11
11
|
import { queryFlowMonitor } from "./nodefony/src/QueryFlowMonitor.js";
|
|
12
12
|
import { buildConnectionHealth, buildOrmFlow, buildOrmGraph, createOrmAdminApi, registerOrmAdminApi, toDbml, toJsonSchema } from "./nodefony/src/OrmAdminApi.js";
|
|
13
13
|
import { buildOrmLeanHealth } from "./nodefony/src/buildOrmLeanHealth.js";
|
|
14
|
+
import { diagnoseConnectionFailure, parseConnectionTarget } from "./nodefony/src/connectionDiagnosis.js";
|
|
15
|
+
import { CONNECT_TIMEOUT_MS, withConnectDeadline } from "./nodefony/src/connectDeadline.js";
|
|
14
16
|
import { reportOrmBootLines, resolveOrmFlowEnabled, wireOrmAdminPlane } from "./nodefony/src/ormWiring.js";
|
|
15
17
|
import { isMigrationFailure } from "./nodefony/interfaces/IOrmMigrations.js";
|
|
16
18
|
import { getEntityMeta, getRepositoryMeta, hasEntityMeta, hasRepositoryMeta } from "./nodefony/src/decorators/metadataStore.js";
|
|
@@ -19,4 +21,4 @@ import { DEFAULT_CONNECTOR, entities } from "./nodefony/src/decorators/entitiesD
|
|
|
19
21
|
import { repository } from "./nodefony/src/decorators/repositoryDecorator.js";
|
|
20
22
|
import "./nodefony/src/decorators/index.js";
|
|
21
23
|
import { defineEntity } from "./nodefony/src/defineEntity.js";
|
|
22
|
-
export { AbstractCrudService, DEFAULT_CONNECTOR, Entity, EntityRegistry, InvalidOrderOption, LIKE_ESCAPE_CHAR, OPERATOR_KEYS, Orm, OrmRegistry, UPDATE_OPERATOR_KEYS, UnknownCriteriaField, assertOrderOption, buildConnectionHealth, buildOrmFlow, buildOrmGraph, buildOrmLeanHealth, connectionMonitor, createOrmAdminApi, defineEntity, entities, entity, entityRegistry, escapeLikeTerm, getEntityMeta, getRepositoryMeta, hasEntityMeta, hasRepositoryMeta, isFieldOperators, isMigrationFailure, isUpdateOperators, likePatternToRegExp, ormRegistry, paginate, queryFlowMonitor, registerOrmAdminApi, reportOrmBootLines, repository, resolveOrmFlowEnabled, searchCriteria, toDbml, toJsonSchema, wireOrmAdminPlane };
|
|
24
|
+
export { AbstractCrudService, CONNECT_TIMEOUT_MS, DEFAULT_CONNECTOR, Entity, EntityRegistry, InvalidOrderOption, LIKE_ESCAPE_CHAR, OPERATOR_KEYS, Orm, OrmRegistry, UPDATE_OPERATOR_KEYS, UnknownCriteriaField, assertOrderOption, buildConnectionHealth, buildOrmFlow, buildOrmGraph, buildOrmLeanHealth, connectionMonitor, createOrmAdminApi, defineEntity, diagnoseConnectionFailure, entities, entity, entityRegistry, escapeLikeTerm, getEntityMeta, getRepositoryMeta, hasEntityMeta, hasRepositoryMeta, isFieldOperators, isMigrationFailure, isUpdateOperators, likePatternToRegExp, ormRegistry, paginate, parseConnectionTarget, queryFlowMonitor, registerOrmAdminApi, reportOrmBootLines, repository, resolveOrmFlowEnabled, searchCriteria, toDbml, toJsonSchema, wireOrmAdminPlane, withConnectDeadline };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
//#region nodefony/src/connectDeadline.ts
|
|
2
|
+
/**
|
|
3
|
+
* Le DÉLAI DE GARDE d'une connexion à une base — une commande n'attend jamais
|
|
4
|
+
* sans fin.
|
|
5
|
+
*
|
|
6
|
+
* 🔴 Le cas est vécu, et il ne ressemble pas à une panne : `nodefony inspect
|
|
7
|
+
* config` restait suspendu, sans un mot, sans erreur, sans reprendre la main.
|
|
8
|
+
* Aucun driver ne borne l'établissement par défaut — `pg-pool` traite son
|
|
9
|
+
* `connectionTimeoutMillis` à `0` comme « attendre indéfiniment » — et un
|
|
10
|
+
* serveur qui accepte la connexion TCP sans jamais répondre (conteneur en
|
|
11
|
+
* train de mourir, port relayé vers rien, réseau qui avale les paquets) laisse
|
|
12
|
+
* l'appelant pendu.
|
|
13
|
+
*
|
|
14
|
+
* Une commande de diagnostic qui se bloque est pire qu'une commande qui
|
|
15
|
+
* échoue : l'échec nomme une cause, le blocage n'apprend rien et fait douter
|
|
16
|
+
* de l'outil plutôt que de l'infrastructure.
|
|
17
|
+
*
|
|
18
|
+
* @module
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Le temps qu'on accorde à une base pour ACCEPTER une connexion, en
|
|
22
|
+
* millisecondes.
|
|
23
|
+
*
|
|
24
|
+
* Dix secondes, et ce n'est pas un réglage de performance : c'est la frontière
|
|
25
|
+
* entre « lent » et « ne répondra pas ». Un serveur local répond en quelques
|
|
26
|
+
* millisecondes, un serveur infonuagique qui sort de veille en quelques
|
|
27
|
+
* secondes ; au-delà, ce qui se passe n'est plus une lenteur, et le dire vaut
|
|
28
|
+
* mieux que l'attendre.
|
|
29
|
+
*
|
|
30
|
+
* Volontairement NON configurable : le besoin n'est pas de choisir une durée,
|
|
31
|
+
* c'est de n'attendre jamais sans fin. Une clé de configuration serait une
|
|
32
|
+
* surface publique à porter pour toute une série majeure, au service d'un
|
|
33
|
+
* réglage que personne n'a demandé.
|
|
34
|
+
*/
|
|
35
|
+
const CONNECT_TIMEOUT_MS = 1e4;
|
|
36
|
+
/**
|
|
37
|
+
* Borne l'attente d'une promesse, et rejette avec une cause NOMMÉE au-delà.
|
|
38
|
+
*
|
|
39
|
+
* Le message importe autant que la borne : « délai dépassé » sans sujet
|
|
40
|
+
* envoie chercher partout. Celui-ci dit ce qu'on attendait, de qui, et
|
|
41
|
+
* combien de temps — c'est ce qui distingue un diagnostic d'un abandon.
|
|
42
|
+
*
|
|
43
|
+
* Le minuteur est `unref`é : il ne doit pas, à lui seul, retenir le processus
|
|
44
|
+
* en vie une fois la réponse arrivée.
|
|
45
|
+
*
|
|
46
|
+
* @param work - la promesse à borner (établissement, ping…).
|
|
47
|
+
* @param what - ce qu'on attend, à la première personne du sujet : « la
|
|
48
|
+
* réponse de postgres 127.0.0.1:5432 ».
|
|
49
|
+
* @param ms - la borne, en millisecondes.
|
|
50
|
+
* @returns la valeur de `work` si elle arrive à temps.
|
|
51
|
+
* @throws Error quand la borne est atteinte — jamais de résolution silencieuse.
|
|
52
|
+
*/
|
|
53
|
+
async function withConnectDeadline(work, what, ms = CONNECT_TIMEOUT_MS) {
|
|
54
|
+
let timer;
|
|
55
|
+
try {
|
|
56
|
+
return await Promise.race([work, new Promise((_, reject) => {
|
|
57
|
+
timer = setTimeout(() => {
|
|
58
|
+
reject(/* @__PURE__ */ new Error(`délai dépassé (${ms} ms) en attendant ${what} — le serveur a accepté la connexion sans répondre, ou n'a jamais répondu. Vérifier que le service visé est bien celui qui écoute, et qu'il est en état de servir.`));
|
|
59
|
+
}, ms);
|
|
60
|
+
timer.unref?.();
|
|
61
|
+
})]);
|
|
62
|
+
} finally {
|
|
63
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
//#endregion
|
|
67
|
+
export { CONNECT_TIMEOUT_MS, withConnectDeadline };
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
//#region nodefony/src/connectionDiagnosis.ts
|
|
2
|
+
/**
|
|
3
|
+
* Personne n'écoute : la couche transport a refusé ou n'a trouvé personne.
|
|
4
|
+
* Ces codes viennent du système, pas du serveur de base de données.
|
|
5
|
+
*/
|
|
6
|
+
const UNREACHABLE_CODES = /* @__PURE__ */ new Set([
|
|
7
|
+
"ECONNREFUSED",
|
|
8
|
+
"ENOTFOUND",
|
|
9
|
+
"EHOSTUNREACH",
|
|
10
|
+
"ENETUNREACH",
|
|
11
|
+
"EAI_AGAIN"
|
|
12
|
+
]);
|
|
13
|
+
/**
|
|
14
|
+
* Un serveur a répondu ET refusé. Chacun de ces codes est produit par le
|
|
15
|
+
* serveur lui-même — donc il a parlé, donc quelque chose tient le port.
|
|
16
|
+
*
|
|
17
|
+
* PostgreSQL rend des SQLSTATE : classe `28` = autorisation invalide,
|
|
18
|
+
* `3D000` = base inconnue, `53300` = trop de connexions. MySQL et MariaDB
|
|
19
|
+
* rendent des noms `ER_*`. MongoDB nomme ses refus (`AuthenticationFailed`).
|
|
20
|
+
*/
|
|
21
|
+
const ANSWERED_CODES = /* @__PURE__ */ new Set([
|
|
22
|
+
"28P01",
|
|
23
|
+
"28000",
|
|
24
|
+
"3D000",
|
|
25
|
+
"53300",
|
|
26
|
+
"ER_ACCESS_DENIED_ERROR",
|
|
27
|
+
"ER_DBACCESS_DENIED_ERROR",
|
|
28
|
+
"ER_BAD_DB_ERROR",
|
|
29
|
+
"ER_NOT_SUPPORTED_AUTH_MODE",
|
|
30
|
+
"ER_HOST_NOT_PRIVILEGED",
|
|
31
|
+
"AuthenticationFailed",
|
|
32
|
+
"Unauthorized"
|
|
33
|
+
]);
|
|
34
|
+
/** Lit le code que le driver a posé sur l'erreur, sans rien supposer de sa forme. */
|
|
35
|
+
function readCode(error) {
|
|
36
|
+
if (typeof error !== "object" || error === null) return null;
|
|
37
|
+
const carrier = error;
|
|
38
|
+
for (const raw of [carrier.code, carrier.codeName]) {
|
|
39
|
+
if (typeof raw === "string" && raw.length > 0) return raw;
|
|
40
|
+
if (typeof raw === "number") return String(raw);
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Extrait l'hôte et le port d'une URL de connexion, sans son secret.
|
|
46
|
+
*
|
|
47
|
+
* @param url - URL de connexion (`postgres://…`, `mysql://…`, `mongodb://…`).
|
|
48
|
+
* @returns l'adresse visée ; champs à `null` si l'URL est absente ou illisible.
|
|
49
|
+
*/
|
|
50
|
+
function parseConnectionTarget(url) {
|
|
51
|
+
if (!url) return {
|
|
52
|
+
host: null,
|
|
53
|
+
port: null
|
|
54
|
+
};
|
|
55
|
+
try {
|
|
56
|
+
const parsed = new URL(url);
|
|
57
|
+
const port = parsed.port ? Number(parsed.port) : null;
|
|
58
|
+
return {
|
|
59
|
+
host: parsed.hostname || null,
|
|
60
|
+
port: Number.isFinite(port) ? port : null
|
|
61
|
+
};
|
|
62
|
+
} catch {
|
|
63
|
+
return {
|
|
64
|
+
host: null,
|
|
65
|
+
port: null
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* La commande qui nomme QUI tient un port, sur la plateforme visée.
|
|
71
|
+
*
|
|
72
|
+
* La plateforme est un PARAMÈTRE et non une lecture de `process.platform` : la
|
|
73
|
+
* règle se vérifie alors pour les trois systèmes depuis n'importe lequel, sans
|
|
74
|
+
* machine Windows. `netstat` parce que `lsof` n'existe pas sous Windows, et
|
|
75
|
+
* qu'une commande introuvable est un second mystère à résoudre.
|
|
76
|
+
*/
|
|
77
|
+
function whoHoldsPort(port, platform) {
|
|
78
|
+
return platform === "win32" ? `netstat -ano | findstr :${port}` : `lsof -nP -iTCP:${port} -sTCP:LISTEN`;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Explique un échec de connexion en distinguant « personne n'écoute » de
|
|
82
|
+
* « quelqu'un a répondu et refuse ».
|
|
83
|
+
*
|
|
84
|
+
* @param error - l'erreur rendue par le driver.
|
|
85
|
+
* @param target - hôte et port visés (cf {@link parseConnectionTarget}).
|
|
86
|
+
* @param platform - plateforme pour laquelle rédiger le geste ; défaut : la courante.
|
|
87
|
+
* @returns le verdict, le code constaté et une explication déjà rédigée.
|
|
88
|
+
*/
|
|
89
|
+
function diagnoseConnectionFailure(error, target = {
|
|
90
|
+
host: null,
|
|
91
|
+
port: null
|
|
92
|
+
}, platform = process.platform) {
|
|
93
|
+
const code = readCode(error);
|
|
94
|
+
const where = target.host && target.port ? `${target.host}:${target.port}` : target.host ?? "l'adresse configurée";
|
|
95
|
+
if (code !== null && UNREACHABLE_CODES.has(code)) return {
|
|
96
|
+
verdict: "unreachable",
|
|
97
|
+
code,
|
|
98
|
+
explanation: `personne n'écoute sur ${where} (${code}) — la base n'est pas démarrée, ou l'adresse configurée n'est pas la sienne.`
|
|
99
|
+
};
|
|
100
|
+
if (code !== null && ANSWERED_CODES.has(code)) return {
|
|
101
|
+
verdict: "answered",
|
|
102
|
+
code,
|
|
103
|
+
explanation: `un serveur a RÉPONDU sur ${where} puis a refusé (${code}) — donc quelque chose tient bien ce port. Ce peut être la base attendue avec de mauvais identifiants, mais aussi UN AUTRE SERVEUR (le conteneur d'un autre projet, par exemple) : le refus vient alors d'une base qui n'est pas la vôtre, et vérifier les identifiants ne mène nulle part.${target.port !== null ? ` Pour savoir qui tient ce port : « docker ps --filter publish=${target.port} », ou « ${whoHoldsPort(target.port, platform)} ».` : ""}`
|
|
104
|
+
};
|
|
105
|
+
return {
|
|
106
|
+
verdict: "unknown",
|
|
107
|
+
code,
|
|
108
|
+
explanation: `échec de connexion à ${where}${code ? ` (${code})` : ""} — vérifier que l'infrastructure déclarée (NF_DATABASE_URL / connectors) désigne bien la base attendue, et qu'elle est démarrée.`
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
//#endregion
|
|
112
|
+
export { diagnoseConnectionFailure, parseConnectionTarget };
|
package/dist/types/index.d.ts
CHANGED
|
@@ -25,6 +25,9 @@ export { buildOrmGraph, buildConnectionHealth, buildOrmFlow, toDbml, toJsonSchem
|
|
|
25
25
|
export { queryFlowMonitor } from "./nodefony/src/QueryFlowMonitor.js";
|
|
26
26
|
export { connectionMonitor } from "./nodefony/src/ConnectionMonitor.js";
|
|
27
27
|
export { buildOrmLeanHealth } from "./nodefony/src/buildOrmLeanHealth.js";
|
|
28
|
+
export { diagnoseConnectionFailure, parseConnectionTarget, } from "./nodefony/src/connectionDiagnosis.js";
|
|
29
|
+
export type { ConnectionVerdict, IConnectionDiagnosis, IConnectionTarget, } from "./nodefony/src/connectionDiagnosis.js";
|
|
30
|
+
export { CONNECT_TIMEOUT_MS, withConnectDeadline, } from "./nodefony/src/connectDeadline.js";
|
|
28
31
|
export { wireOrmAdminPlane, resolveOrmFlowEnabled, reportOrmBootLines, } from "./nodefony/src/ormWiring.js";
|
|
29
32
|
export type { ISlowQuery, IQueryFlow, IOrmFlowReport, } from "./nodefony/interfaces/IOrmFlow.js";
|
|
30
33
|
export type { IColumnInfo, IConnectionInfo, IRelationInfo, IEntityGraphNode, IOrmSummary, IOrmGraph, IConnectionError, IConnectionHealth, } from "./nodefony/interfaces/IOrmGraph.js";
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Le DÉLAI DE GARDE d'une connexion à une base — une commande n'attend jamais
|
|
3
|
+
* sans fin.
|
|
4
|
+
*
|
|
5
|
+
* 🔴 Le cas est vécu, et il ne ressemble pas à une panne : `nodefony inspect
|
|
6
|
+
* config` restait suspendu, sans un mot, sans erreur, sans reprendre la main.
|
|
7
|
+
* Aucun driver ne borne l'établissement par défaut — `pg-pool` traite son
|
|
8
|
+
* `connectionTimeoutMillis` à `0` comme « attendre indéfiniment » — et un
|
|
9
|
+
* serveur qui accepte la connexion TCP sans jamais répondre (conteneur en
|
|
10
|
+
* train de mourir, port relayé vers rien, réseau qui avale les paquets) laisse
|
|
11
|
+
* l'appelant pendu.
|
|
12
|
+
*
|
|
13
|
+
* Une commande de diagnostic qui se bloque est pire qu'une commande qui
|
|
14
|
+
* échoue : l'échec nomme une cause, le blocage n'apprend rien et fait douter
|
|
15
|
+
* de l'outil plutôt que de l'infrastructure.
|
|
16
|
+
*
|
|
17
|
+
* @module
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Le temps qu'on accorde à une base pour ACCEPTER une connexion, en
|
|
21
|
+
* millisecondes.
|
|
22
|
+
*
|
|
23
|
+
* Dix secondes, et ce n'est pas un réglage de performance : c'est la frontière
|
|
24
|
+
* entre « lent » et « ne répondra pas ». Un serveur local répond en quelques
|
|
25
|
+
* millisecondes, un serveur infonuagique qui sort de veille en quelques
|
|
26
|
+
* secondes ; au-delà, ce qui se passe n'est plus une lenteur, et le dire vaut
|
|
27
|
+
* mieux que l'attendre.
|
|
28
|
+
*
|
|
29
|
+
* Volontairement NON configurable : le besoin n'est pas de choisir une durée,
|
|
30
|
+
* c'est de n'attendre jamais sans fin. Une clé de configuration serait une
|
|
31
|
+
* surface publique à porter pour toute une série majeure, au service d'un
|
|
32
|
+
* réglage que personne n'a demandé.
|
|
33
|
+
*/
|
|
34
|
+
export declare const CONNECT_TIMEOUT_MS = 10000;
|
|
35
|
+
/**
|
|
36
|
+
* Borne l'attente d'une promesse, et rejette avec une cause NOMMÉE au-delà.
|
|
37
|
+
*
|
|
38
|
+
* Le message importe autant que la borne : « délai dépassé » sans sujet
|
|
39
|
+
* envoie chercher partout. Celui-ci dit ce qu'on attendait, de qui, et
|
|
40
|
+
* combien de temps — c'est ce qui distingue un diagnostic d'un abandon.
|
|
41
|
+
*
|
|
42
|
+
* Le minuteur est `unref`é : il ne doit pas, à lui seul, retenir le processus
|
|
43
|
+
* en vie une fois la réponse arrivée.
|
|
44
|
+
*
|
|
45
|
+
* @param work - la promesse à borner (établissement, ping…).
|
|
46
|
+
* @param what - ce qu'on attend, à la première personne du sujet : « la
|
|
47
|
+
* réponse de postgres 127.0.0.1:5432 ».
|
|
48
|
+
* @param ms - la borne, en millisecondes.
|
|
49
|
+
* @returns la valeur de `work` si elle arrive à temps.
|
|
50
|
+
* @throws Error quand la borne est atteinte — jamais de résolution silencieuse.
|
|
51
|
+
*/
|
|
52
|
+
export declare function withConnectDeadline<T>(work: Promise<T>, what: string, ms?: number): Promise<T>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Diagnostic d'un échec de connexion à une base — **ce qui a été CONSTATÉ**,
|
|
3
|
+
* jamais seulement ce qu'on en déduit.
|
|
4
|
+
*
|
|
5
|
+
* Le message d'échec énumérait trois causes (infrastructure déclarée, base
|
|
6
|
+
* démarrée, entités portées) et aucune n'était la bonne dans un cas fréquent :
|
|
7
|
+
* **un AUTRE serveur occupe déjà le port**. Vécu sur une application fraîchement
|
|
8
|
+
* générée — son PostgreSQL n'était pas démarré, mais le conteneur d'un autre
|
|
9
|
+
* projet écoutait sur `127.0.0.1:5432`. L'application s'y est connectée et a reçu
|
|
10
|
+
* « password authentication failed ». Le message était EXACT, et c'est ce qui le
|
|
11
|
+
* rendait trompeur : il est cru, et il envoie vérifier des identifiants justes.
|
|
12
|
+
*
|
|
13
|
+
* La distinction qui tranche tient en une question : **quelqu'un a-t-il
|
|
14
|
+
* répondu ?** `ECONNREFUSED` dit que non — personne n'écoute, la base n'est pas
|
|
15
|
+
* démarrée. Un refus d'authentification dit que si : un serveur a parlé, donc le
|
|
16
|
+
* port est tenu, et la question devient « par QUI ? ».
|
|
17
|
+
*
|
|
18
|
+
* Vit dans `orm-core` parce que les deux adapters posent la même question : deux
|
|
19
|
+
* implémentations parallèles diraient deux choses différentes du même symptôme.
|
|
20
|
+
*/
|
|
21
|
+
/** Ce que l'échec permet d'affirmer sur l'autre bout du socket. */
|
|
22
|
+
export type ConnectionVerdict =
|
|
23
|
+
/** Personne n'a répondu — rien n'écoute à cette adresse. */
|
|
24
|
+
"unreachable"
|
|
25
|
+
/** Un serveur a répondu, et il refuse — le port est bien tenu par quelqu'un. */
|
|
26
|
+
| "answered"
|
|
27
|
+
/** L'erreur ne permet de trancher ni dans un sens ni dans l'autre. */
|
|
28
|
+
| "unknown";
|
|
29
|
+
/** Diagnostic rendu à l'appelant, qui compose le message final. */
|
|
30
|
+
export interface IConnectionDiagnosis {
|
|
31
|
+
verdict: ConnectionVerdict;
|
|
32
|
+
/** Code CONSTATÉ, tel que le driver l'a rendu (`ECONNREFUSED`, `28P01`, …). */
|
|
33
|
+
code: string | null;
|
|
34
|
+
/** Ce qu'on peut affirmer, et le geste qui tranche. Déjà rédigé. */
|
|
35
|
+
explanation: string;
|
|
36
|
+
}
|
|
37
|
+
/** Adresse visée, telle qu'on peut la dire sans divulguer de secret. */
|
|
38
|
+
export interface IConnectionTarget {
|
|
39
|
+
host: string | null;
|
|
40
|
+
port: number | null;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Extrait l'hôte et le port d'une URL de connexion, sans son secret.
|
|
44
|
+
*
|
|
45
|
+
* @param url - URL de connexion (`postgres://…`, `mysql://…`, `mongodb://…`).
|
|
46
|
+
* @returns l'adresse visée ; champs à `null` si l'URL est absente ou illisible.
|
|
47
|
+
*/
|
|
48
|
+
export declare function parseConnectionTarget(url?: string | null): IConnectionTarget;
|
|
49
|
+
/**
|
|
50
|
+
* Explique un échec de connexion en distinguant « personne n'écoute » de
|
|
51
|
+
* « quelqu'un a répondu et refuse ».
|
|
52
|
+
*
|
|
53
|
+
* @param error - l'erreur rendue par le driver.
|
|
54
|
+
* @param target - hôte et port visés (cf {@link parseConnectionTarget}).
|
|
55
|
+
* @param platform - plateforme pour laquelle rédiger le geste ; défaut : la courante.
|
|
56
|
+
* @returns le verdict, le code constaté et une explication déjà rédigée.
|
|
57
|
+
*/
|
|
58
|
+
export declare function diagnoseConnectionFailure(error: unknown, target?: IConnectionTarget, platform?: string): IConnectionDiagnosis;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nodefony/orm-core",
|
|
3
|
-
"version": "10.0.0-alpha.
|
|
3
|
+
"version": "10.0.0-alpha.3",
|
|
4
4
|
"description": "Un contrat de dépôt de données pour Nodefony, plusieurs moteurs : interfaces, registre et classes de base pour le support multi-ORM",
|
|
5
5
|
"contributors": [],
|
|
6
6
|
"type": "module",
|
|
@@ -36,11 +36,11 @@
|
|
|
36
36
|
"esm"
|
|
37
37
|
],
|
|
38
38
|
"peerDependencies": {
|
|
39
|
-
"nodefony": "^10.0.0-alpha.
|
|
39
|
+
"nodefony": "^10.0.0-alpha.3"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/node": "26.4.1",
|
|
43
|
-
"nodefony": "^10.0.0-alpha.
|
|
43
|
+
"nodefony": "^10.0.0-alpha.3",
|
|
44
44
|
"rimraf": "6.1.3",
|
|
45
45
|
"vitest": "5.0.0"
|
|
46
46
|
},
|