@nodefony/orm-core 10.0.0-beta.2 → 10.0.0-beta.4
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/nodefony/interfaces/IOrmMigrations.js +1 -2
- package/dist/nodefony/src/AbstractCrudService.js +1 -2
- package/dist/nodefony/src/ConnectionMonitor.js +1 -2
- package/dist/nodefony/src/Entity.js +1 -2
- package/dist/nodefony/src/EntityRegistry.js +1 -2
- package/dist/nodefony/src/Orm.js +1 -2
- package/dist/nodefony/src/OrmAdminApi.js +4 -5
- package/dist/nodefony/src/OrmRegistry.js +1 -2
- package/dist/nodefony/src/QueryFlowMonitor.js +1 -2
- package/dist/nodefony/src/buildOrmLeanHealth.js +1 -2
- package/dist/nodefony/src/connectDeadline.js +1 -2
- package/dist/nodefony/src/connectionDiagnosis.js +72 -15
- package/dist/nodefony/src/criteria.js +1 -2
- package/dist/nodefony/src/decorators/entitiesDecorator.js +1 -2
- package/dist/nodefony/src/decorators/entityDecorator.js +1 -2
- package/dist/nodefony/src/decorators/metadataStore.js +3 -4
- package/dist/nodefony/src/decorators/repositoryDecorator.js +1 -2
- package/dist/nodefony/src/defineEntity.js +1 -2
- package/dist/nodefony/src/errors.js +1 -2
- package/dist/nodefony/src/omitUndefined.js +1 -2
- package/dist/nodefony/src/ormWiring.js +1 -2
- package/dist/nodefony/src/orphanEntities.js +1 -2
- package/dist/nodefony/src/paginate.js +1 -2
- package/dist/nodefony/src/readOptions.js +1 -2
- package/dist/types/nodefony/src/connectionDiagnosis.d.ts +9 -1
- package/docs/index.md +133 -133
- package/docs/tutorial-entity.md +87 -80
- package/package.json +6 -6
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// nodefony/interfaces/IOrmMigrations.ts
|
|
2
2
|
/**
|
|
3
3
|
* Y a-t-il un empêchement plutôt qu'un état ?
|
|
4
4
|
*
|
|
@@ -8,5 +8,4 @@
|
|
|
8
8
|
function isMigrationFailure(reply) {
|
|
9
9
|
return "error" in reply;
|
|
10
10
|
}
|
|
11
|
-
//#endregion
|
|
12
11
|
export { isMigrationFailure };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { omitUndefined } from "./omitUndefined.js";
|
|
2
2
|
import { paginate } from "./paginate.js";
|
|
3
3
|
import { Service } from "nodefony";
|
|
4
|
-
|
|
4
|
+
// nodefony/src/AbstractCrudService.ts
|
|
5
5
|
/**
|
|
6
6
|
* Service CRUD **générique** — socle réutilisable au-dessus d'un {@link IRepository}.
|
|
7
7
|
*
|
|
@@ -199,5 +199,4 @@ var AbstractCrudService = class extends Service {
|
|
|
199
199
|
/** Effet de bord après suppression (ex. nettoyer un cache). */
|
|
200
200
|
afterDelete(_criteria, _removed) {}
|
|
201
201
|
};
|
|
202
|
-
//#endregion
|
|
203
202
|
export { AbstractCrudService };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// nodefony/src/ConnectionMonitor.ts
|
|
2
2
|
/** Taille max du ring d'erreurs récentes (borne mémoire). */
|
|
3
3
|
const MAX_RECENT_ERRORS = 12;
|
|
4
4
|
/** Taille max de la chronologie pertes/reprises (borne mémoire). */
|
|
@@ -209,5 +209,4 @@ var ConnectionMonitor = class {
|
|
|
209
209
|
};
|
|
210
210
|
/** Singleton process-wide du moniteur de connexions. */
|
|
211
211
|
const connectionMonitor = new ConnectionMonitor();
|
|
212
|
-
//#endregion
|
|
213
212
|
export { connectionMonitor };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { entityRegistry } from "./EntityRegistry.js";
|
|
2
|
-
|
|
2
|
+
// nodefony/src/Entity.ts
|
|
3
3
|
/**
|
|
4
4
|
* Classe de base abstraite d'une entité, indépendante du driver ORM.
|
|
5
5
|
*
|
|
@@ -38,5 +38,4 @@ var Entity = class {
|
|
|
38
38
|
return this;
|
|
39
39
|
}
|
|
40
40
|
};
|
|
41
|
-
//#endregion
|
|
42
41
|
export { Entity };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// nodefony/src/EntityRegistry.ts
|
|
2
2
|
/**
|
|
3
3
|
* Registre cross-ORM des entités, indexé par nom logique puis par connecteur.
|
|
4
4
|
*
|
|
@@ -111,5 +111,4 @@ var EntityRegistry = class {
|
|
|
111
111
|
* (tests).
|
|
112
112
|
*/
|
|
113
113
|
const entityRegistry = new EntityRegistry();
|
|
114
|
-
//#endregion
|
|
115
114
|
export { EntityRegistry, entityRegistry };
|
package/dist/nodefony/src/Orm.js
CHANGED
|
@@ -2,7 +2,7 @@ import { ormRegistry } from "./OrmRegistry.js";
|
|
|
2
2
|
import { connectionMonitor } from "./ConnectionMonitor.js";
|
|
3
3
|
import { Service } from "nodefony";
|
|
4
4
|
import { performance } from "node:perf_hooks";
|
|
5
|
-
|
|
5
|
+
// nodefony/src/Orm.ts
|
|
6
6
|
/**
|
|
7
7
|
* Période du battement, réglable par l'environnement (`0` le désactive).
|
|
8
8
|
*
|
|
@@ -309,5 +309,4 @@ var Orm = class extends Service {
|
|
|
309
309
|
return { driver: "" };
|
|
310
310
|
}
|
|
311
311
|
};
|
|
312
|
-
//#endregion
|
|
313
312
|
export { Orm };
|
|
@@ -4,7 +4,7 @@ import { connectionMonitor } from "./ConnectionMonitor.js";
|
|
|
4
4
|
import { queryFlowMonitor } from "./QueryFlowMonitor.js";
|
|
5
5
|
import { Nodefony } from "nodefony";
|
|
6
6
|
import { performance } from "node:perf_hooks";
|
|
7
|
-
|
|
7
|
+
// nodefony/src/OrmAdminApi.ts
|
|
8
8
|
/**
|
|
9
9
|
* Producteur `IAdminApi` du **modèle de données ORM** — exposé sous
|
|
10
10
|
* `/nodefony/orm/api/*`. Fondation « IA-first » : construit le graphe canonique
|
|
@@ -109,7 +109,7 @@ function buildOrmSummaries() {
|
|
|
109
109
|
const names = ormRegistry.list();
|
|
110
110
|
const carrier = storeCarrier(Nodefony.getKernel()?.storeResolutions ?? [], names);
|
|
111
111
|
return names.map((name) => {
|
|
112
|
-
let connected
|
|
112
|
+
let connected;
|
|
113
113
|
let vendor = "";
|
|
114
114
|
let connection;
|
|
115
115
|
try {
|
|
@@ -136,7 +136,7 @@ function buildOrmSummaries() {
|
|
|
136
136
|
*/
|
|
137
137
|
function buildEntityNode(connector, name) {
|
|
138
138
|
const entity = entityRegistry.get(name, connector);
|
|
139
|
-
let columns
|
|
139
|
+
let columns;
|
|
140
140
|
try {
|
|
141
141
|
columns = ormRegistry.get(connector).describeEntity?.(name) ?? [];
|
|
142
142
|
} catch {
|
|
@@ -275,7 +275,7 @@ async function buildConnectionHealth(filter) {
|
|
|
275
275
|
*/
|
|
276
276
|
function buildOrmFlow(filter) {
|
|
277
277
|
const connectors = ormRegistry.list().filter((n) => !filter || n === filter).map((name) => {
|
|
278
|
-
let vendor
|
|
278
|
+
let vendor;
|
|
279
279
|
try {
|
|
280
280
|
vendor = vendorOf(ormRegistry.get(name));
|
|
281
281
|
} catch {
|
|
@@ -529,5 +529,4 @@ function registerOrmAdminApi(registry) {
|
|
|
529
529
|
if (registry.has("orm")) return;
|
|
530
530
|
registry.register(createOrmAdminApi());
|
|
531
531
|
}
|
|
532
|
-
//#endregion
|
|
533
532
|
export { buildConnectionHealth, buildOrmFlow, buildOrmGraph, createOrmAdminApi, registerOrmAdminApi, storeCarrier, toDbml, toJsonSchema };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// nodefony/src/OrmRegistry.ts
|
|
2
2
|
/**
|
|
3
3
|
* Registre process-wide des instances ORM enregistrées sous un nom unique.
|
|
4
4
|
*
|
|
@@ -71,5 +71,4 @@ var OrmRegistry = class {
|
|
|
71
71
|
* instanciable séparément pour des registres isolés (tests).
|
|
72
72
|
*/
|
|
73
73
|
const ormRegistry = new OrmRegistry();
|
|
74
|
-
//#endregion
|
|
75
74
|
export { OrmRegistry, ormRegistry };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// nodefony/src/QueryFlowMonitor.ts
|
|
2
2
|
/** Taille max du ring de requêtes lentes (borne mémoire). */
|
|
3
3
|
const MAX_SLOW = 20;
|
|
4
4
|
/** Facteur de lissage EWMA (0–1) : plus haut = suit plus vite les variations. */
|
|
@@ -124,5 +124,4 @@ var QueryFlowMonitor = class {
|
|
|
124
124
|
};
|
|
125
125
|
/** Singleton process-wide de la sonde de flux ORM. */
|
|
126
126
|
const queryFlowMonitor = new QueryFlowMonitor();
|
|
127
|
-
//#endregion
|
|
128
127
|
export { queryFlowMonitor };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ormRegistry } from "./OrmRegistry.js";
|
|
2
2
|
import { connectionMonitor } from "./ConnectionMonitor.js";
|
|
3
3
|
import { queryFlowMonitor } from "./QueryFlowMonitor.js";
|
|
4
|
-
|
|
4
|
+
// nodefony/src/buildOrmLeanHealth.ts
|
|
5
5
|
/**
|
|
6
6
|
* **Santé ORM lean per-instance** — somme process-wide de tous les connecteurs enregistrés,
|
|
7
7
|
* destinée à voyager dans le report de sonde cluster (« ORM par worker »). C'est la fonction
|
|
@@ -50,5 +50,4 @@ function buildOrmLeanHealth() {
|
|
|
50
50
|
maxEwmaMs
|
|
51
51
|
};
|
|
52
52
|
}
|
|
53
|
-
//#endregion
|
|
54
53
|
export { buildOrmLeanHealth, buildOrmLeanHealth as default };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// nodefony/src/connectDeadline.ts
|
|
2
2
|
/**
|
|
3
3
|
* Le DÉLAI DE GARDE d'une connexion à une base — une commande n'attend jamais
|
|
4
4
|
* sans fin.
|
|
@@ -63,5 +63,4 @@ async function withConnectDeadline(work, what, ms = CONNECT_TIMEOUT_MS) {
|
|
|
63
63
|
if (timer !== void 0) clearTimeout(timer);
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
|
-
//#endregion
|
|
67
66
|
export { CONNECT_TIMEOUT_MS, withConnectDeadline };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// nodefony/src/connectionDiagnosis.ts
|
|
2
2
|
/**
|
|
3
3
|
* Personne n'écoute : la couche transport a refusé ou n'a trouvé personne.
|
|
4
4
|
* Ces codes viennent du système, pas du serveur de base de données.
|
|
@@ -68,29 +68,78 @@ function readCode(error) {
|
|
|
68
68
|
return typeof carrier.code === "number" ? String(carrier.code) : null;
|
|
69
69
|
}
|
|
70
70
|
/**
|
|
71
|
-
* Extrait l'hôte et le
|
|
71
|
+
* Extrait l'hôte, le port, la base et le compte d'une URL de connexion, sans
|
|
72
|
+
* son secret.
|
|
72
73
|
*
|
|
73
74
|
* @param url - URL de connexion (`postgres://…`, `mysql://…`, `mongodb://…`).
|
|
74
75
|
* @returns l'adresse visée ; champs à `null` si l'URL est absente ou illisible.
|
|
75
76
|
*/
|
|
76
77
|
function parseConnectionTarget(url) {
|
|
77
|
-
|
|
78
|
+
const none = {
|
|
78
79
|
host: null,
|
|
79
|
-
port: null
|
|
80
|
+
port: null,
|
|
81
|
+
database: null,
|
|
82
|
+
user: null
|
|
80
83
|
};
|
|
84
|
+
if (!url) return none;
|
|
81
85
|
try {
|
|
82
86
|
const parsed = new URL(url);
|
|
83
87
|
const port = parsed.port ? Number(parsed.port) : null;
|
|
88
|
+
const database = decodeURIComponent(parsed.pathname.slice(1));
|
|
89
|
+
const user = decodeURIComponent(parsed.username);
|
|
84
90
|
return {
|
|
85
91
|
host: parsed.hostname || null,
|
|
86
|
-
port: Number.isFinite(port) ? port : null
|
|
92
|
+
port: Number.isFinite(port) ? port : null,
|
|
93
|
+
database: database || null,
|
|
94
|
+
user: user || null
|
|
87
95
|
};
|
|
88
96
|
} catch {
|
|
89
|
-
return
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
97
|
+
return none;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Identifiant PostgreSQL entre guillemets — un nom de base peut porter un
|
|
102
|
+
* tiret ou une majuscule, que PostgreSQL plierait ou refuserait nu.
|
|
103
|
+
*/
|
|
104
|
+
function quotePgIdent(name) {
|
|
105
|
+
return `"${name.replaceAll("\"", "\"\"")}"`;
|
|
106
|
+
}
|
|
107
|
+
/** Identifiant MySQL/MariaDB entre accents graves. */
|
|
108
|
+
function quoteMysqlIdent(name) {
|
|
109
|
+
return `\`${name.replaceAll("`", "``")}\``;
|
|
110
|
+
}
|
|
111
|
+
/** Chaîne SQL MySQL/MariaDB entre apostrophes (nom de compte d'un `GRANT`). */
|
|
112
|
+
function quoteMysqlString(value) {
|
|
113
|
+
return `'${value.replaceAll("'", "''")}'`;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* La base désignée manque — ou, sous MySQL/MariaDB, le compte n'y a aucun
|
|
117
|
+
* droit, ce que le serveur ne distingue pas.
|
|
118
|
+
*
|
|
119
|
+
* Les trois codes ne sortent qu'APRÈS l'acceptation du mot de passe (constaté :
|
|
120
|
+
* un mauvais mot de passe rend `28P01` ou `ER_ACCESS_DENIED_ERROR`, même sur
|
|
121
|
+
* une base absente). Vérifier les identifiants n'est donc pas le geste : il
|
|
122
|
+
* faut créer la base, avec un compte qui en a le droit — l'application ne la
|
|
123
|
+
* crée jamais, un compte capable de créer des bases l'est aussi d'en supprimer.
|
|
124
|
+
*
|
|
125
|
+
* @returns l'explication rédigée, ou `null` si le code n'est pas celui d'une
|
|
126
|
+
* base absente ou si l'URL ne nomme pas la base.
|
|
127
|
+
*/
|
|
128
|
+
function describeMissingDatabase(code, target, where, portHint) {
|
|
129
|
+
const database = target.database;
|
|
130
|
+
if (!database) return null;
|
|
131
|
+
const account = target.user ? ` « ${target.user} »` : "";
|
|
132
|
+
const how = "La créer avec un compte qui en a le droit (administrateur du serveur, ou celui du conteneur dans le décor docker), puis relancer : ";
|
|
133
|
+
const elsewhere = portHint ? ` Si cette base devrait déjà exister, vérifier que ce port est bien tenu par VOTRE serveur.${portHint}` : "";
|
|
134
|
+
if (code === "3D000") {
|
|
135
|
+
const owner = target.user ? ` OWNER ${quotePgIdent(target.user)}` : "";
|
|
136
|
+
return `la base « ${database} » n'existe pas sur le serveur ${where} (${code}) — le serveur a répondu et accepté le compte${account}, mais l'application ne crée jamais sa base (CREATE DATABASE est un privilège d'administration). ${how}CREATE DATABASE ${quotePgIdent(database)}${owner};${elsewhere}`;
|
|
93
137
|
}
|
|
138
|
+
if (code === "ER_BAD_DB_ERROR" || code === "ER_DBACCESS_DENIED_ERROR") {
|
|
139
|
+
const grant = target.user ? ` GRANT ALL PRIVILEGES ON ${quoteMysqlIdent(database)}.* TO ${quoteMysqlString(target.user)}@'%';` : "";
|
|
140
|
+
return `${code === "ER_DBACCESS_DENIED_ERROR" ? `le compte${account} n'a accès à aucune base « ${database} » sur le serveur ${where} (${code}) : soit elle n'existe pas, soit elle existe sans droit pour ce compte — MySQL ne dit pas lequel. ` : `la base « ${database} » n'existe pas sur le serveur ${where} (${code}). `}Le mot de passe a été accepté, et l'application ne crée jamais sa base (privilège d'administration). ${how}CREATE DATABASE IF NOT EXISTS ${quoteMysqlIdent(database)};${grant}` + elsewhere;
|
|
141
|
+
}
|
|
142
|
+
return null;
|
|
94
143
|
}
|
|
95
144
|
/**
|
|
96
145
|
* La commande qui nomme QUI tient un port, sur la plateforme visée.
|
|
@@ -123,11 +172,20 @@ function diagnoseConnectionFailure(error, target = {
|
|
|
123
172
|
code,
|
|
124
173
|
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.`
|
|
125
174
|
};
|
|
126
|
-
if (code !== null && ANSWERED_CODES.has(code))
|
|
127
|
-
|
|
128
|
-
code,
|
|
129
|
-
|
|
130
|
-
|
|
175
|
+
if (code !== null && ANSWERED_CODES.has(code)) {
|
|
176
|
+
const portHint = target.port !== null ? ` Pour savoir qui tient ce port : « docker ps --filter publish=${target.port} », ou « ${whoHoldsPort(target.port, platform)} ».` : "";
|
|
177
|
+
const missing = describeMissingDatabase(code, target, where, portHint);
|
|
178
|
+
if (missing !== null) return {
|
|
179
|
+
verdict: "answered",
|
|
180
|
+
code,
|
|
181
|
+
explanation: missing
|
|
182
|
+
};
|
|
183
|
+
return {
|
|
184
|
+
verdict: "answered",
|
|
185
|
+
code,
|
|
186
|
+
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.${portHint}`
|
|
187
|
+
};
|
|
188
|
+
}
|
|
131
189
|
if (code !== null && provesEstablished(code)) return {
|
|
132
190
|
verdict: "rejected",
|
|
133
191
|
code,
|
|
@@ -168,5 +226,4 @@ function describeConnectFailure(subject, diagnosis, cause, advice = "") {
|
|
|
168
226
|
}
|
|
169
227
|
return `${subject} n'a pas pu se connecter — ${diagnosis.explanation}${advice} Cause : ${cause}`;
|
|
170
228
|
}
|
|
171
|
-
//#endregion
|
|
172
229
|
export { REJECTED_MARKER, describeConnectFailure, diagnoseConnectionFailure, parseConnectionTarget };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// nodefony/src/criteria.ts
|
|
2
2
|
/**
|
|
3
3
|
* Liste figée des opérateurs riches reconnus dans un critère portable.
|
|
4
4
|
*
|
|
@@ -173,5 +173,4 @@ function searchCriteria(q, fields) {
|
|
|
173
173
|
if (only !== void 0) return { [only]: { $like: likePattern } };
|
|
174
174
|
return { $or: fields.map((f) => ({ [f]: { $like: likePattern } })) };
|
|
175
175
|
}
|
|
176
|
-
//#endregion
|
|
177
176
|
export { LIKE_ESCAPE_CHAR, OPERATOR_KEYS, UPDATE_OPERATOR_KEYS, escapeLikeTerm, isFieldOperators, isUpdateOperators, likePatternToRegExp, searchCriteria };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { entityRegistry } from "../EntityRegistry.js";
|
|
2
|
-
|
|
2
|
+
// nodefony/src/decorators/entitiesDecorator.ts
|
|
3
3
|
/** Connecteur retenu quand ni l'entité ni le décorateur n'en nomment un. */
|
|
4
4
|
const DEFAULT_CONNECTOR = "default";
|
|
5
5
|
/**
|
|
@@ -63,5 +63,4 @@ function entities(list, options = {}) {
|
|
|
63
63
|
return NewConstructorEntities;
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
|
-
//#endregion
|
|
67
66
|
export { DEFAULT_CONNECTOR, entities };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { entityRegistry } from "../EntityRegistry.js";
|
|
2
2
|
import { setEntityMeta } from "./metadataStore.js";
|
|
3
|
-
|
|
3
|
+
// nodefony/src/decorators/entityDecorator.ts
|
|
4
4
|
/**
|
|
5
5
|
* Décore une classe comme entité multi-ORM et l'enregistre au chargement.
|
|
6
6
|
*
|
|
@@ -47,5 +47,4 @@ function entity(options) {
|
|
|
47
47
|
return target;
|
|
48
48
|
};
|
|
49
49
|
}
|
|
50
|
-
//#endregion
|
|
51
50
|
export { entity };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
// nodefony/src/decorators/metadataStore.ts
|
|
2
2
|
/**
|
|
3
3
|
* Stockage des métadonnées de décorateurs SANS `reflect-metadata`.
|
|
4
4
|
*
|
|
5
5
|
* orm-core est une lib pure : aucune dépendance runtime hors `nodefony`. Les
|
|
6
|
-
* décorateurs `@entity`/`@repository` ne lisent jamais les
|
|
7
|
-
*
|
|
6
|
+
* décorateurs `@entity`/`@repository` ne lisent jamais les métadonnées de type
|
|
7
|
+
* émises par le compilateur, donc un `WeakMap<classe, métadonnée>` process-wide
|
|
8
8
|
* suffit — clé = constructeur, GC-friendly (pas de fuite si la classe est
|
|
9
9
|
* déréférencée). Aucun polyfill Reflect requis.
|
|
10
10
|
*/
|
|
@@ -34,5 +34,4 @@ function getRepositoryMeta(target) {
|
|
|
34
34
|
function hasRepositoryMeta(target) {
|
|
35
35
|
return REPOSITORY_META.has(target);
|
|
36
36
|
}
|
|
37
|
-
//#endregion
|
|
38
37
|
export { getEntityMeta, getRepositoryMeta, hasEntityMeta, hasRepositoryMeta, setEntityMeta, setRepositoryMeta };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { setRepositoryMeta } from "./metadataStore.js";
|
|
2
|
-
|
|
2
|
+
// nodefony/src/decorators/repositoryDecorator.ts
|
|
3
3
|
/**
|
|
4
4
|
* Décore une classe comme repository d'une entité (tag métadonnée pur).
|
|
5
5
|
*
|
|
@@ -31,5 +31,4 @@ function repository(name, options) {
|
|
|
31
31
|
return target;
|
|
32
32
|
};
|
|
33
33
|
}
|
|
34
|
-
//#endregion
|
|
35
34
|
export { repository };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// nodefony/src/defineEntity.ts
|
|
2
2
|
/**
|
|
3
3
|
* Déclare une entité applicative. Fonction d'**identité typée** : elle ne fait
|
|
4
4
|
* qu'attacher le type — aucun effet de bord, aucun enregistrement.
|
|
@@ -23,5 +23,4 @@
|
|
|
23
23
|
function defineEntity(definition) {
|
|
24
24
|
return definition;
|
|
25
25
|
}
|
|
26
|
-
//#endregion
|
|
27
26
|
export { defineEntity };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// nodefony/src/errors.ts
|
|
2
2
|
/**
|
|
3
3
|
* Erreurs typées du socle ORM — **data-level uniquement** (aucun couplage à une
|
|
4
4
|
* couche API/transport : ces erreurs décrivent des fautes sur les données, pas
|
|
@@ -130,5 +130,4 @@ var SavepointNotSupportedError = class extends Error {
|
|
|
130
130
|
this.driver = driver;
|
|
131
131
|
}
|
|
132
132
|
};
|
|
133
|
-
//#endregion
|
|
134
133
|
export { InvalidOrderOption, ReferencedEntityError, SavepointNotSupportedError, UnknownCriteriaField };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// nodefony/src/omitUndefined.ts
|
|
2
2
|
/**
|
|
3
3
|
* Retire les clés qui valent `undefined` d'une donnée d'écriture partielle.
|
|
4
4
|
*
|
|
@@ -26,5 +26,4 @@ function omitUndefined(data) {
|
|
|
26
26
|
}
|
|
27
27
|
return data;
|
|
28
28
|
}
|
|
29
|
-
//#endregion
|
|
30
29
|
export { omitUndefined };
|
|
@@ -2,7 +2,7 @@ import { ormRegistry } from "./OrmRegistry.js";
|
|
|
2
2
|
import { buildConnectionHealth, buildOrmFlow, registerOrmAdminApi } from "./OrmAdminApi.js";
|
|
3
3
|
import { buildOrmLeanHealth } from "./buildOrmLeanHealth.js";
|
|
4
4
|
import { setOrmHealthProvider, setOrmRichProvider } from "nodefony";
|
|
5
|
-
|
|
5
|
+
// nodefony/src/ormWiring.ts
|
|
6
6
|
/**
|
|
7
7
|
* Branche le « plan d'administration » ORM dans le kernel — montage **idempotent**
|
|
8
8
|
* appelé par CHAQUE driver à son `onKernelBoot`. Factorise la dette C5 : le bloc
|
|
@@ -74,5 +74,4 @@ function resolveOrmFlowEnabled(kernel) {
|
|
|
74
74
|
const flag = process.env.NF_ORM_FLOW;
|
|
75
75
|
return flag !== void 0 ? flag === "1" || flag === "true" : kernel?.environment !== "production";
|
|
76
76
|
}
|
|
77
|
-
//#endregion
|
|
78
77
|
export { reportOrmBootLines, resolveOrmFlowEnabled, wireOrmAdminPlane };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ormRegistry } from "./OrmRegistry.js";
|
|
2
2
|
import { entityRegistry } from "./EntityRegistry.js";
|
|
3
|
-
|
|
3
|
+
// nodefony/src/orphanEntities.ts
|
|
4
4
|
/**
|
|
5
5
|
* Entités inscrites sur un connecteur qu'aucun ORM n'a ouvert.
|
|
6
6
|
*
|
|
@@ -59,5 +59,4 @@ function reportOrphanEntities(log, owner, declared = []) {
|
|
|
59
59
|
if (message !== null) log(message, "WARNING");
|
|
60
60
|
return message;
|
|
61
61
|
}
|
|
62
|
-
//#endregion
|
|
63
62
|
export { describeOrphanEntities, findOrphanEntities, reportOrphanEntities };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { searchCriteria } from "./criteria.js";
|
|
2
2
|
import { PageQueryError } from "nodefony";
|
|
3
|
-
|
|
3
|
+
// nodefony/src/paginate.ts
|
|
4
4
|
/**
|
|
5
5
|
* Pagine un {@link IRepository} de façon **portable** — au-dessus des primitives
|
|
6
6
|
* natives `find(criteria, { limit, offset, order })` et `count(criteria)` que tout
|
|
@@ -51,5 +51,4 @@ async function paginate(repo, page, options = {}) {
|
|
|
51
51
|
total: withTotal ? await repo.count(criteria) : void 0
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
|
-
//#endregion
|
|
55
54
|
export { paginate };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { InvalidOrderOption } from "./errors.js";
|
|
2
|
-
|
|
2
|
+
// nodefony/src/readOptions.ts
|
|
3
3
|
/**
|
|
4
4
|
* Décrit la FORME d'une valeur reçue, sans jamais en révéler le contenu.
|
|
5
5
|
*
|
|
@@ -48,5 +48,4 @@ function assertOrderOption(order, entity) {
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
-
//#endregion
|
|
52
51
|
export { assertOrderOption };
|
|
@@ -44,9 +44,17 @@ export interface IConnectionDiagnosis {
|
|
|
44
44
|
export interface IConnectionTarget {
|
|
45
45
|
host: string | null;
|
|
46
46
|
port: number | null;
|
|
47
|
+
/**
|
|
48
|
+
* Nom de la base désignée par l'URL — de quoi NOMMER une base absente et
|
|
49
|
+
* écrire la commande qui la crée. Absent : la phrase n'en parle pas.
|
|
50
|
+
*/
|
|
51
|
+
database?: string | null;
|
|
52
|
+
/** Compte de connexion (jamais son mot de passe) — propriétaire de la base à créer. */
|
|
53
|
+
user?: string | null;
|
|
47
54
|
}
|
|
48
55
|
/**
|
|
49
|
-
* Extrait l'hôte et le
|
|
56
|
+
* Extrait l'hôte, le port, la base et le compte d'une URL de connexion, sans
|
|
57
|
+
* son secret.
|
|
50
58
|
*
|
|
51
59
|
* @param url - URL de connexion (`postgres://…`, `mysql://…`, `mongodb://…`).
|
|
52
60
|
* @returns l'adresse visée ; champs à `null` si l'URL est absente ou illisible.
|