@nodefony/orm-core 10.0.0-alpha.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/LICENSE +544 -0
- package/README.md +131 -0
- package/dist/index.js +22 -0
- package/dist/nodefony/interfaces/IEntity.js +1 -0
- package/dist/nodefony/interfaces/IOrm.js +1 -0
- package/dist/nodefony/interfaces/IOrmFlow.js +1 -0
- package/dist/nodefony/interfaces/IOrmGraph.js +1 -0
- package/dist/nodefony/interfaces/IOrmMigrations.js +12 -0
- package/dist/nodefony/interfaces/IOrmProbe.js +1 -0
- package/dist/nodefony/interfaces/IPage.js +1 -0
- package/dist/nodefony/interfaces/IRepository.js +1 -0
- package/dist/nodefony/interfaces/ITransaction.js +1 -0
- package/dist/nodefony/interfaces/index.js +1 -0
- package/dist/nodefony/src/AbstractCrudService.js +199 -0
- package/dist/nodefony/src/ConnectionMonitor.js +181 -0
- package/dist/nodefony/src/Entity.js +42 -0
- package/dist/nodefony/src/EntityRegistry.js +109 -0
- package/dist/nodefony/src/Orm.js +297 -0
- package/dist/nodefony/src/OrmAdminApi.js +491 -0
- package/dist/nodefony/src/OrmRegistry.js +75 -0
- package/dist/nodefony/src/QueryFlowMonitor.js +128 -0
- package/dist/nodefony/src/buildOrmLeanHealth.js +54 -0
- package/dist/nodefony/src/criteria.js +176 -0
- package/dist/nodefony/src/decorators/entitiesDecorator.js +67 -0
- package/dist/nodefony/src/decorators/entityDecorator.js +51 -0
- package/dist/nodefony/src/decorators/index.js +5 -0
- package/dist/nodefony/src/decorators/metadataStore.js +38 -0
- package/dist/nodefony/src/decorators/repositoryDecorator.js +35 -0
- package/dist/nodefony/src/defineEntity.js +27 -0
- package/dist/nodefony/src/errors.js +76 -0
- package/dist/nodefony/src/ormWiring.js +78 -0
- package/dist/nodefony/src/paginate.js +55 -0
- package/dist/nodefony/src/readOptions.js +52 -0
- package/dist/nodefony/src/serviceWiring.js +1 -0
- package/dist/types/index.d.ts +39 -0
- package/dist/types/nodefony/interfaces/IEntity.d.ts +65 -0
- package/dist/types/nodefony/interfaces/IOrm.d.ts +136 -0
- package/dist/types/nodefony/interfaces/IOrmFlow.d.ts +71 -0
- package/dist/types/nodefony/interfaces/IOrmGraph.d.ts +165 -0
- package/dist/types/nodefony/interfaces/IOrmMigrations.d.ts +145 -0
- package/dist/types/nodefony/interfaces/IOrmProbe.d.ts +70 -0
- package/dist/types/nodefony/interfaces/IPage.d.ts +24 -0
- package/dist/types/nodefony/interfaces/IRepository.d.ts +369 -0
- package/dist/types/nodefony/interfaces/ITransaction.d.ts +31 -0
- package/dist/types/nodefony/interfaces/index.d.ts +7 -0
- package/dist/types/nodefony/src/AbstractCrudService.d.ts +158 -0
- package/dist/types/nodefony/src/ConnectionMonitor.d.ts +86 -0
- package/dist/types/nodefony/src/Entity.d.ts +44 -0
- package/dist/types/nodefony/src/EntityRegistry.d.ts +60 -0
- package/dist/types/nodefony/src/Orm.d.ts +197 -0
- package/dist/types/nodefony/src/OrmAdminApi.d.ts +84 -0
- package/dist/types/nodefony/src/OrmRegistry.d.ts +58 -0
- package/dist/types/nodefony/src/QueryFlowMonitor.d.ts +53 -0
- package/dist/types/nodefony/src/buildOrmLeanHealth.d.ts +15 -0
- package/dist/types/nodefony/src/criteria.d.ts +131 -0
- package/dist/types/nodefony/src/decorators/entitiesDecorator.d.ts +48 -0
- package/dist/types/nodefony/src/decorators/entityDecorator.d.ts +49 -0
- package/dist/types/nodefony/src/decorators/index.d.ts +10 -0
- package/dist/types/nodefony/src/decorators/metadataStore.d.ts +54 -0
- package/dist/types/nodefony/src/decorators/repositoryDecorator.d.ts +30 -0
- package/dist/types/nodefony/src/defineEntity.d.ts +43 -0
- package/dist/types/nodefony/src/errors.d.ts +62 -0
- package/dist/types/nodefony/src/ormWiring.d.ts +48 -0
- package/dist/types/nodefony/src/paginate.d.ts +43 -0
- package/dist/types/nodefony/src/readOptions.d.ts +21 -0
- package/dist/types/nodefony/src/serviceWiring.d.ts +24 -0
- package/docs/index.md +791 -0
- package/docs/tutorial-entity.md +577 -0
- package/package.json +73 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* L'état des migrations d'un connecteur, vu du CŒUR — la forme que tout ORM
|
|
3
|
+
* capable de migrer doit rendre, quel que soit son pilote.
|
|
4
|
+
*
|
|
5
|
+
* **Pourquoi cette vue existe ici et pas dans le module qui migre** : l'URL
|
|
6
|
+
* d'administration est générique (`/nodefony/orm/api/migrations?connector=…`),
|
|
7
|
+
* et son écran l'est aussi. Si la forme appartenait au pilote SQL, le premier
|
|
8
|
+
* autre ORM à porter des migrations obligerait à réécrire l'écran — ou pire, à
|
|
9
|
+
* en ajouter un second qui dirait presque la même chose.
|
|
10
|
+
*
|
|
11
|
+
* Ce que la vue fixe : le cœur NEUTRE (verdict, sources, gestes) et rien
|
|
12
|
+
* d'autre. Tout ce qui est propre à un pilote vit sous `driver`, dont la forme
|
|
13
|
+
* n'est pas décrite ici — un consommateur générique n'a pas à la connaître, et
|
|
14
|
+
* un `jq` d'utilisateur ne doit pas avoir gravé un chemin qui passe par le nom
|
|
15
|
+
* d'un pilote.
|
|
16
|
+
*
|
|
17
|
+
* ⚠️ Ce n'est PAS une seconde définition du rapport : c'est sa vue minimale. Le
|
|
18
|
+
* producteur reste le module qui migre, et un test de conformité chez lui
|
|
19
|
+
* prouve que son objet est assignable à cette interface. Recopier ses champs
|
|
20
|
+
* ici en ferait deux contrats à maintenir, dont un mentirait.
|
|
21
|
+
*/
|
|
22
|
+
/** Une commande à taper, telle que le produit la propose. */
|
|
23
|
+
export interface IOrmMigrationAction {
|
|
24
|
+
/** La ligne complète, prête à copier. */
|
|
25
|
+
command: string;
|
|
26
|
+
/** Ses arguments, pour qui l'exécute au lieu de l'afficher. */
|
|
27
|
+
args: string[];
|
|
28
|
+
}
|
|
29
|
+
/** Une migration, telle que l'historique et les fichiers la décrivent. */
|
|
30
|
+
export interface IOrmMigrationEntry {
|
|
31
|
+
/** Identifiant immuable une fois publié. */
|
|
32
|
+
tag: string;
|
|
33
|
+
/** Où en est cette migration pour CE connecteur. */
|
|
34
|
+
status: string;
|
|
35
|
+
/** Déploiement qui l'a portée — groupe les migrations d'un même passage. */
|
|
36
|
+
runId?: string | undefined;
|
|
37
|
+
/** Quand elle a été appliquée — absent tant qu'elle ne l'est pas. */
|
|
38
|
+
appliedAt?: number | undefined;
|
|
39
|
+
/** Ce qui l'a appliquée, tel que l'historique l'a retenu. */
|
|
40
|
+
appliedBy?: string | undefined;
|
|
41
|
+
/** Durée d'application, en millisecondes. */
|
|
42
|
+
durationMs?: number | undefined;
|
|
43
|
+
/** Motif de l'échec, quand elle a échoué. */
|
|
44
|
+
error?: string | undefined;
|
|
45
|
+
}
|
|
46
|
+
/** Les migrations d'une origine — le framework, l'application, un module. */
|
|
47
|
+
export interface IOrmMigrationSource {
|
|
48
|
+
/** Nom de l'origine, tel qu'il s'affiche. */
|
|
49
|
+
name: string;
|
|
50
|
+
/** Combien sont passées. */
|
|
51
|
+
applied: number;
|
|
52
|
+
/** Combien restent à appliquer. */
|
|
53
|
+
pending: number;
|
|
54
|
+
/** Combien ont échoué. */
|
|
55
|
+
failed: number;
|
|
56
|
+
/** Ses migrations, dans l'ordre d'application. */
|
|
57
|
+
entries: IOrmMigrationEntry[];
|
|
58
|
+
}
|
|
59
|
+
/** L'état complet, cœur neutre — la charge utile de l'écran et de `--json`. */
|
|
60
|
+
export interface IOrmMigrationStatus {
|
|
61
|
+
/**
|
|
62
|
+
* Version du format, pour qu'un lecteur sache ce qu'il lit — un ENTIER, qui
|
|
63
|
+
* ne s'incrémente que sur une rupture.
|
|
64
|
+
*/
|
|
65
|
+
formatVersion: number;
|
|
66
|
+
/** Connecteur observé. */
|
|
67
|
+
connector: string;
|
|
68
|
+
/** Situation d'ensemble (`ok`, `pending`, `divergent`, `failed`…). */
|
|
69
|
+
verdict: string;
|
|
70
|
+
/** Le fait constaté, en une phrase. */
|
|
71
|
+
summary: string;
|
|
72
|
+
/** Ce qu'il faut faire, du plus direct au plus assumé. */
|
|
73
|
+
nextActions: IOrmMigrationAction[];
|
|
74
|
+
/** Une origine par entrée. */
|
|
75
|
+
sources: IOrmMigrationSource[];
|
|
76
|
+
/** Tout ce qui est propre au pilote, et rien d'autre ailleurs. */
|
|
77
|
+
driver: {
|
|
78
|
+
kind: string;
|
|
79
|
+
[key: string]: unknown;
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Ce qu'un ORM répond quand il ne PEUT pas rendre d'état.
|
|
84
|
+
*
|
|
85
|
+
* La même forme que l'arrêt publié par la ligne de commande : un écran qui
|
|
86
|
+
* reçoit ceci doit MONTRER l'empêchement, jamais un tableau vide qui ressemble
|
|
87
|
+
* à « tout va bien ».
|
|
88
|
+
*/
|
|
89
|
+
export interface IOrmMigrationFailure {
|
|
90
|
+
formatVersion: number;
|
|
91
|
+
connector: string;
|
|
92
|
+
error: {
|
|
93
|
+
/** Code stable — les scripts le lisent. */
|
|
94
|
+
code: string;
|
|
95
|
+
summary: string;
|
|
96
|
+
meaning: string;
|
|
97
|
+
nextActions: IOrmMigrationAction[];
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/** Une migration en attente, avec le SQL qu'elle exécuterait. */
|
|
101
|
+
export interface IOrmPendingMigration {
|
|
102
|
+
/** Origine — le framework, l'application, un module. */
|
|
103
|
+
source: string;
|
|
104
|
+
/** Identité immuable une fois publiée. */
|
|
105
|
+
tag: string;
|
|
106
|
+
/** Les instructions, dans l'ordre d'exécution. */
|
|
107
|
+
statements: string[];
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Ce qui S'APPLIQUERAIT — le plan, avec son SQL.
|
|
111
|
+
*
|
|
112
|
+
* Sert la confirmation avant application : un geste qui modifie un schéma ne
|
|
113
|
+
* se confirme pas sur une promesse, il se confirme sur ce qu'il va exécuter.
|
|
114
|
+
*/
|
|
115
|
+
export interface IOrmMigrationPlan {
|
|
116
|
+
formatVersion: number;
|
|
117
|
+
connector: string;
|
|
118
|
+
pending: IOrmPendingMigration[];
|
|
119
|
+
}
|
|
120
|
+
/** Ce qu'une application a fait — ou l'empêchement qui l'a arrêtée. */
|
|
121
|
+
export interface IOrmMigrationApplied {
|
|
122
|
+
formatVersion: number;
|
|
123
|
+
connector: string;
|
|
124
|
+
/** Identifiant du passage — groupe les migrations d'un même déploiement. */
|
|
125
|
+
runId: string;
|
|
126
|
+
/** Ce qui a été appliqué, dans l'ordre. */
|
|
127
|
+
applied: {
|
|
128
|
+
source: string;
|
|
129
|
+
tag: string;
|
|
130
|
+
executionMs: number;
|
|
131
|
+
}[];
|
|
132
|
+
}
|
|
133
|
+
/** L'état, ou l'empêchement — jamais les deux. */
|
|
134
|
+
export type IOrmMigrationReply = IOrmMigrationStatus | IOrmMigrationFailure;
|
|
135
|
+
/** Le plan, ou l'empêchement. */
|
|
136
|
+
export type IOrmMigrationPlanReply = IOrmMigrationPlan | IOrmMigrationFailure;
|
|
137
|
+
/** Le compte rendu d'application, ou l'empêchement. */
|
|
138
|
+
export type IOrmMigrationApplyReply = IOrmMigrationApplied | IOrmMigrationFailure;
|
|
139
|
+
/**
|
|
140
|
+
* Y a-t-il un empêchement plutôt qu'un état ?
|
|
141
|
+
*
|
|
142
|
+
* @param reply - ce que l'ORM a rendu.
|
|
143
|
+
* @returns `true` si c'est un empêchement.
|
|
144
|
+
*/
|
|
145
|
+
export declare function isMigrationFailure(reply: IOrmMigrationReply | IOrmMigrationPlanReply | IOrmMigrationApplyReply): reply is IOrmMigrationFailure;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sondes ORM — métriques d'observabilité profonde d'un connecteur, poussées via
|
|
3
|
+
* le hub temps réel (`nodefony:orm:health`) pour un **contrôle total** des ORM.
|
|
4
|
+
*
|
|
5
|
+
* Deux niveaux :
|
|
6
|
+
* - **générique** (porté par {@link ConnectionMonitor}) : latence, cycle de vie,
|
|
7
|
+
* erreurs — calculé pareil pour tout adapter.
|
|
8
|
+
* - **driver-spécifique** ({@link IOrmProbe}, via {@link IOrm.probe}) : stockage,
|
|
9
|
+
* pool… que seul l'adapter sait extraire (SQLite PRAGMA, pool Mongo…).
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Fenêtre glissante de latence de ping — `min`/`avg`/`max` sur les N derniers
|
|
13
|
+
* échantillons (révèle les pics, pas seulement l'instantané). `null` tant
|
|
14
|
+
* qu'aucun ping n'a été mesuré.
|
|
15
|
+
*/
|
|
16
|
+
export interface ILatencyWindow {
|
|
17
|
+
/** Dernière latence mesurée (ms). */
|
|
18
|
+
last: number | null;
|
|
19
|
+
/** Minimum sur la fenêtre (ms). */
|
|
20
|
+
min: number | null;
|
|
21
|
+
/** Moyenne sur la fenêtre (ms). */
|
|
22
|
+
avg: number | null;
|
|
23
|
+
/** Maximum sur la fenêtre (ms). */
|
|
24
|
+
max: number | null;
|
|
25
|
+
/** Nombre d'échantillons dans la fenêtre. */
|
|
26
|
+
samples: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Sonde de stockage — driver-spécifique. Pour SQLite : dérivée des PRAGMA
|
|
30
|
+
* (`page_count`, `page_size`, `journal_mode`, `freelist_count`). Pour un serveur :
|
|
31
|
+
* taille logique de la base si l'adapter sait l'obtenir.
|
|
32
|
+
*/
|
|
33
|
+
export interface IOrmStorageProbe {
|
|
34
|
+
/** Taille de la base (octets) — `pages × pageSize` (SQLite). */
|
|
35
|
+
sizeBytes?: number;
|
|
36
|
+
/** Nombre de pages allouées. */
|
|
37
|
+
pages?: number;
|
|
38
|
+
/** Taille d'une page (octets). */
|
|
39
|
+
pageSize?: number;
|
|
40
|
+
/** Mode de journalisation (SQLite : `wal`, `delete`, `memory`…). */
|
|
41
|
+
journalMode?: string;
|
|
42
|
+
/** Pages libres (fragmentation / espace récupérable au VACUUM). */
|
|
43
|
+
freePages?: number;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Sonde de pool de connexions — pertinente pour les bases serveur (Mongo,
|
|
47
|
+
* Postgres, MySQL). SQLite (better-sqlite3) = mono-connexion → non renseigné.
|
|
48
|
+
*/
|
|
49
|
+
export interface IOrmPoolProbe {
|
|
50
|
+
/** Taille max configurée du pool. */
|
|
51
|
+
size?: number;
|
|
52
|
+
/** Connexions disponibles (idle). */
|
|
53
|
+
available?: number;
|
|
54
|
+
/** Connexions en cours d'utilisation. */
|
|
55
|
+
borrowed?: number;
|
|
56
|
+
/** Demandes en attente d'une connexion. */
|
|
57
|
+
pending?: number;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Sonde profonde driver-spécifique retournée par {@link IOrm.probe}. Tous les
|
|
61
|
+
* champs sont optionnels : un adapter ne rapporte que ce qu'il sait mesurer.
|
|
62
|
+
*/
|
|
63
|
+
export interface IOrmProbe {
|
|
64
|
+
/** Métriques de stockage (taille, pages, journal…). */
|
|
65
|
+
storage?: IOrmStorageProbe;
|
|
66
|
+
/** Métriques de pool de connexions (serveurs). */
|
|
67
|
+
pool?: IOrmPoolProbe;
|
|
68
|
+
/** Métriques libres clé→valeur (extensible par adapter, jamais de credential). */
|
|
69
|
+
extra?: Record<string, string | number | boolean>;
|
|
70
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Criteria } from "./IRepository.js";
|
|
2
|
+
import type { IPageQuery } from "nodefony";
|
|
3
|
+
export type { IPage, IPageQuery } from "nodefony";
|
|
4
|
+
/**
|
|
5
|
+
* Requête de page pour un {@link IRepository} — le contrat de page core
|
|
6
|
+
* ({@link IPageQuery}) enrichi du `criteria` typé de l'ORM. C'est la forme que
|
|
7
|
+
* {@link paginate} consomme.
|
|
8
|
+
*
|
|
9
|
+
* **Offset-first** : `cursor` reste disponible mais n'est pas lu par le helper
|
|
10
|
+
* offset générique — les stores à curseur ont leur propre implémentation, et
|
|
11
|
+
* `assertPageQuery(query, "offset")` refuse un `cursor` reçu par erreur.
|
|
12
|
+
*
|
|
13
|
+
* `q` **est** honoré, mais seulement si l'appelant déclare où chercher
|
|
14
|
+
* (`paginate(repo, page, { searchable })`) ; sans cette déclaration il est
|
|
15
|
+
* refusé en `400`. Il a longtemps traversé ce type sans être lu une seule fois :
|
|
16
|
+
* un paramètre accepté puis jeté rend la collection entière à qui croit lire un
|
|
17
|
+
* résultat de recherche.
|
|
18
|
+
*
|
|
19
|
+
* @typeParam T - type de l'entité paginée (type le `criteria`).
|
|
20
|
+
*/
|
|
21
|
+
export interface PageQuery<T = unknown> extends IPageQuery {
|
|
22
|
+
/** Filtre typé optionnel appliqué avant la pagination (toutes les lignes si omis). */
|
|
23
|
+
criteria?: Criteria<T>;
|
|
24
|
+
}
|
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
import type { ITransaction } from "./ITransaction.js";
|
|
2
|
+
/**
|
|
3
|
+
* Critère de filtre brut passé aux opérations d'un repository.
|
|
4
|
+
*
|
|
5
|
+
* Volontairement abstrait (`Record<string, unknown>`) : chaque adapter ORM
|
|
6
|
+
* traduit ce critère dans sa syntaxe native (clause `WHERE` SQL, query Mongo,
|
|
7
|
+
* conditions Drizzle...). Le socle reste portable cross-ORM.
|
|
8
|
+
*/
|
|
9
|
+
export type OrmCriteria = Record<string, unknown>;
|
|
10
|
+
/**
|
|
11
|
+
* Opérateurs de comparaison riches applicables à **un** champ, façon MongoDB.
|
|
12
|
+
*
|
|
13
|
+
* Forme tranchée en P7.4 (ADR-0003 risque #3) : objet d'opérateurs `$`-préfixés.
|
|
14
|
+
* Raison : (1) familier (convention Mongo) ; (2) mappable par les **trois**
|
|
15
|
+
* drivers — Mongoose en (quasi) identité (`$gt`/`$in` natifs, `$like`→`$regex`),
|
|
16
|
+
* Drizzle via `gt()`/`inArray()`/`like()` (selon l'adapter). Le sous-ensemble
|
|
17
|
+
* est volontairement minimal = intersection portable des 3 ORM.
|
|
18
|
+
*
|
|
19
|
+
* Plusieurs opérateurs sur le même champ se combinent en `AND`
|
|
20
|
+
* (ex. `{ age: { $gte: 18, $lt: 65 } }`).
|
|
21
|
+
*
|
|
22
|
+
* @typeParam V - type de la valeur du champ ciblé.
|
|
23
|
+
*/
|
|
24
|
+
export interface FieldOperators<V> {
|
|
25
|
+
/** Égalité stricte (équivalent à passer la valeur nue). */
|
|
26
|
+
$eq?: V;
|
|
27
|
+
/** Différent de. */
|
|
28
|
+
$ne?: V;
|
|
29
|
+
/** Strictement supérieur à. */
|
|
30
|
+
$gt?: V;
|
|
31
|
+
/** Supérieur ou égal à. */
|
|
32
|
+
$gte?: V;
|
|
33
|
+
/** Strictement inférieur à. */
|
|
34
|
+
$lt?: V;
|
|
35
|
+
/** Inférieur ou égal à. */
|
|
36
|
+
$lte?: V;
|
|
37
|
+
/** Appartient à l'ensemble. */
|
|
38
|
+
$in?: readonly V[];
|
|
39
|
+
/** N'appartient pas à l'ensemble. */
|
|
40
|
+
$nin?: readonly V[];
|
|
41
|
+
/** Motif SQL `LIKE` (`%`/`_`) — pertinent pour les champs texte uniquement. */
|
|
42
|
+
$like?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Teste l'**absence de valeur** : `true` → `IS NULL`, `false` → `IS NOT NULL`
|
|
45
|
+
* (Mongo : `$eq`/`$ne null`, qui couvre aussi le champ absent).
|
|
46
|
+
*
|
|
47
|
+
* Indispensable parce qu'une comparaison d'égalité à `NULL` est **fausse** en
|
|
48
|
+
* SQL (`col = NULL` ne matche rien, jamais) : sans cet opérateur, filtrer « la
|
|
49
|
+
* colonne est vide » n'est pas exprimable. Forme équivalente à la valeur nue
|
|
50
|
+
* `{ champ: null }` (cf {@link Criteria}), à préférer quand le `null` vient
|
|
51
|
+
* d'une variable et qu'on veut dire explicitement « IS NULL ».
|
|
52
|
+
*
|
|
53
|
+
* **Exclusif avec `$eq`/`$ne` sur le même champ** : les deux expriment la même
|
|
54
|
+
* comparaison à `null` et l'adapter Mongo les traduit vers la même clé — il
|
|
55
|
+
* lève plutôt que d'en écraser une en silence.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* // les jetons pas encore révoqués
|
|
59
|
+
* repo.find({ revokedAt: { $null: true } });
|
|
60
|
+
* // les PAT qui ont une expiration
|
|
61
|
+
* repo.find({ expiresAt: { $null: false } });
|
|
62
|
+
*/
|
|
63
|
+
$null?: boolean;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Opérateurs d'**écriture** applicables à un champ dans le `update` d'un
|
|
67
|
+
* {@link IRepository.upsert} — par opposition aux {@link FieldOperators}, qui
|
|
68
|
+
* filtrent en lecture.
|
|
69
|
+
*
|
|
70
|
+
* Ils existent parce qu'un upsert **ne peut pas porter de condition** : son
|
|
71
|
+
* `DO UPDATE` s'applique dès qu'il y a conflit de clé. Pour une valeur dont la
|
|
72
|
+
* progression est **monotone** (un seuil qui ne doit jamais reculer), la
|
|
73
|
+
* condition doit donc vivre dans la valeur écrite elle-même. Le résultat tient
|
|
74
|
+
* en **une seule instruction atomique** sur les quatre backends (`MAX()` sqlite,
|
|
75
|
+
* `GREATEST()` postgres/mysql, `$max` natif Mongo) — là où une clause `WHERE`
|
|
76
|
+
* sur le `DO UPDATE` n'existe pas en MySQL et imposerait plusieurs requêtes,
|
|
77
|
+
* donc une course entre elles.
|
|
78
|
+
*
|
|
79
|
+
* À l'INSERT, la valeur est posée telle quelle (rien à comparer).
|
|
80
|
+
*
|
|
81
|
+
* Inutiles pour faire progresser une ligne dont on sait qu'elle **existe** :
|
|
82
|
+
* `updateMany({ k, seuil: { $lt: v } }, { seuil: v })` l'exprime déjà, et de
|
|
83
|
+
* façon tout aussi atomique.
|
|
84
|
+
*
|
|
85
|
+
* @typeParam V - type de la valeur du champ ciblé.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* // le seuil de révocation ne recule jamais, même sur deux logouts simultanés
|
|
89
|
+
* repo.upsert({ subjectId }, { invalidBefore: { $max: now } });
|
|
90
|
+
*/
|
|
91
|
+
export interface UpdateOperators<V> {
|
|
92
|
+
/** Écrit la valeur seulement si elle est **supérieure** à celle en base. */
|
|
93
|
+
$max?: V;
|
|
94
|
+
/** Écrit la valeur seulement si elle est **inférieure** à celle en base. */
|
|
95
|
+
$min?: V;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Données d'écriture d'un {@link IRepository.upsert} : chaque champ accepte soit
|
|
99
|
+
* sa valeur nue (écriture directe), soit un objet d'{@link UpdateOperators}.
|
|
100
|
+
*
|
|
101
|
+
* @typeParam T - type de l'entité gérée.
|
|
102
|
+
*/
|
|
103
|
+
export type UpdateData<T> = {
|
|
104
|
+
[K in keyof T]?: T[K] | UpdateOperators<NonNullable<T[K]>>;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Valeur de critère pour un champ : soit l'**égalité** directe (valeur nue),
|
|
108
|
+
* soit un objet d'{@link FieldOperators} riche.
|
|
109
|
+
*
|
|
110
|
+
* La valeur nue **`null`** signifie `IS NULL` — et non l'égalité `col = NULL`,
|
|
111
|
+
* qui en SQL est toujours fausse et ferait disparaître le filtre en silence
|
|
112
|
+
* (donc `{ revokedAt: null }` ≡ `{ revokedAt: { $null: true } }`). Contrat
|
|
113
|
+
* identique sur tous les adapters.
|
|
114
|
+
*
|
|
115
|
+
* Cette forme n'est ouverte que si le champ est **typé nullable** (`V` contient
|
|
116
|
+
* `null`) : sur un champ non-nullable, chercher `IS NULL` est une erreur de
|
|
117
|
+
* raisonnement, et le typage la refuse. {@link FieldOperators.$null} reste
|
|
118
|
+
* disponible sur tout champ — y compris optionnel (`champ?: T`), où il exprime
|
|
119
|
+
* « pas de valeur » (Mongo : champ absent).
|
|
120
|
+
*
|
|
121
|
+
* @typeParam V - type de la valeur du champ.
|
|
122
|
+
*/
|
|
123
|
+
export type FieldCriteria<V> = V | FieldOperators<NonNullable<V>>;
|
|
124
|
+
/**
|
|
125
|
+
* Critère **typé par champ** d'une entité `T`.
|
|
126
|
+
*
|
|
127
|
+
* Chaque champ connu accepte soit son égalité (`{ email }` doit être un `string`
|
|
128
|
+
* si `T.email` l'est), soit un objet d'opérateurs riches typé sur la valeur du
|
|
129
|
+
* champ (`{ age: { $gt: 18 } }`). L'intersection avec {@link OrmCriteria}
|
|
130
|
+
* conserve une échappatoire pour les clés non typées (champ calculé, opérateur
|
|
131
|
+
* natif non couvert). Chaque adapter traduit ce critère dans sa syntaxe native.
|
|
132
|
+
*
|
|
133
|
+
* @typeParam T - type de l'entité gérée.
|
|
134
|
+
*/
|
|
135
|
+
export type Criteria<T> = {
|
|
136
|
+
[K in keyof T]?: FieldCriteria<T[K]>;
|
|
137
|
+
} & {
|
|
138
|
+
/**
|
|
139
|
+
* **Disjonction** : au moins une des branches doit être vraie. Les champs
|
|
140
|
+
* posés à côté restent en `ET` avec l'ensemble (`{a: 1, $or: [x, y]}` =
|
|
141
|
+
* `a = 1 AND (x OR y)`).
|
|
142
|
+
*
|
|
143
|
+
* Existe parce que certaines questions du domaine ne sont PAS des
|
|
144
|
+
* conjonctions : « un jeton utilisable » = *sans échéance* **ou** *échéance à
|
|
145
|
+
* venir*. Sans elle, la seule issue était de descendre au SQL/Mongo natif dans
|
|
146
|
+
* chaque store — donc d'écrire la même règle autant de fois qu'il y a de
|
|
147
|
+
* backends, avec la divergence pour seule perspective.
|
|
148
|
+
*
|
|
149
|
+
* Volontairement limitée à `$or` : `$and` est déjà le comportement par défaut
|
|
150
|
+
* d'un critère, et `$not` demanderait de définir la négation d'un `NULL` sur
|
|
151
|
+
* trois dialectes — un piège pour zéro usage démontré.
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* // les clés encore utilisables
|
|
155
|
+
* repo.count({ revokedAt: null, $or: [{ expiresAt: null }, { expiresAt: { $gt: now } }] });
|
|
156
|
+
*/
|
|
157
|
+
$or?: ReadonlyArray<Criteria<T>>;
|
|
158
|
+
} & OrmCriteria;
|
|
159
|
+
/**
|
|
160
|
+
* Options de lecture (`find`/`findOne`) portables cross-ORM.
|
|
161
|
+
*
|
|
162
|
+
* `relations` charge des associations **déclarées** dans `@entity` (eager-load :
|
|
163
|
+
* `populate` Mongoose / `with` Drizzle) sans descendre au
|
|
164
|
+
* natif pour le cas commun. Les jointures arbitraires restent du ressort de
|
|
165
|
+
* `IOrm.getNativeConnection()`.
|
|
166
|
+
*/
|
|
167
|
+
export interface RepositoryReadOptions {
|
|
168
|
+
/** Noms logiques des relations déclarées à charger (eager-load). */
|
|
169
|
+
relations?: string[];
|
|
170
|
+
/** Nombre maximum de lignes. */
|
|
171
|
+
limit?: number;
|
|
172
|
+
/** Décalage (pagination). */
|
|
173
|
+
offset?: number;
|
|
174
|
+
/**
|
|
175
|
+
* Tri : couples `[champ, sens]`, ex. `[["createdAt", "DESC"]]`.
|
|
176
|
+
*
|
|
177
|
+
* **Forme vérifiée à l'exécution** : toute autre forme lève `InvalidOrderOption`
|
|
178
|
+
* au lieu d'être ignorée — un objet (`{ age: "asc" }`) ou une casse basse
|
|
179
|
+
* (`"desc"`) faisait auparavant partir la requête sans tri, ou triait à
|
|
180
|
+
* l'envers, sans un mot. La normalisation d'une entrée utilisateur appartient à
|
|
181
|
+
* la frontière qui la reçoit (`parsePageQuery` accepte `champ:sens` en casse
|
|
182
|
+
* libre), jamais au repository.
|
|
183
|
+
*/
|
|
184
|
+
order?: Array<[string, "ASC" | "DESC"]>;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Contrat CRUD minimal exposé par un repository, indépendant de l'ORM sous-jacent.
|
|
188
|
+
*
|
|
189
|
+
* Un repository est obtenu via `IOrm.getRepository(name)` et manipule des entités
|
|
190
|
+
* de type `T`. Les sémantiques fines (cascade, hooks) sont déléguées à
|
|
191
|
+
* l'adapter concret ; ce contrat garantit uniquement le socle portable.
|
|
192
|
+
*
|
|
193
|
+
* @typeParam T - type de l'entité gérée par le repository.
|
|
194
|
+
*/
|
|
195
|
+
export interface IRepository<T = unknown> {
|
|
196
|
+
/**
|
|
197
|
+
* Retourne toutes les entités correspondant au critère (toutes si omis).
|
|
198
|
+
*
|
|
199
|
+
* @param criteria - filtre optionnel (partiellement typé).
|
|
200
|
+
* @param options - eager-load / pagination / tri portables.
|
|
201
|
+
* @returns la liste des entités trouvées (vide si aucune).
|
|
202
|
+
* @throws UnknownCriteriaField si un champ du critère est inconnu de l'entité.
|
|
203
|
+
* @throws InvalidOrderOption si `options.order` n'est pas un tableau de couples.
|
|
204
|
+
*/
|
|
205
|
+
find(criteria?: Criteria<T>, options?: RepositoryReadOptions): Promise<T[]>;
|
|
206
|
+
/**
|
|
207
|
+
* Retourne la première entité correspondant au critère, ou `null`.
|
|
208
|
+
*
|
|
209
|
+
* Le tri (`options.order`) décide LAQUELLE des lignes revient : il est honoré par
|
|
210
|
+
* tous les adapters, sans quoi le même appel rendrait un document différent selon
|
|
211
|
+
* l'ORM.
|
|
212
|
+
*
|
|
213
|
+
* @param criteria - filtre de sélection (partiellement typé).
|
|
214
|
+
* @param options - eager-load portable (`relations`) et tri (`order`).
|
|
215
|
+
* @throws UnknownCriteriaField si un champ du critère est inconnu de l'entité.
|
|
216
|
+
* @throws InvalidOrderOption si `options.order` n'est pas un tableau de couples.
|
|
217
|
+
*/
|
|
218
|
+
findOne(criteria: Criteria<T>, options?: RepositoryReadOptions): Promise<T | null>;
|
|
219
|
+
/**
|
|
220
|
+
* Persiste une nouvelle entité et retourne sa version persistée (id généré, valeurs par défaut).
|
|
221
|
+
*
|
|
222
|
+
* @param data - champs de l'entité à créer.
|
|
223
|
+
*/
|
|
224
|
+
create(data: Partial<T>): Promise<T>;
|
|
225
|
+
/**
|
|
226
|
+
* Insère **plusieurs** entités en **une seule** requête (`INSERT … VALUES
|
|
227
|
+
* (…),(…)` SQL / `insertMany` Mongo) et retourne leurs versions persistées
|
|
228
|
+
* (ids générés, défauts appliqués), dans l'ordre. Un tableau vide est un
|
|
229
|
+
* **no-op** (`[]`, aucune requête). Préférer à N appels `create` (N round-trips)
|
|
230
|
+
* pour le seed / l'import / l'ingestion par lots.
|
|
231
|
+
*
|
|
232
|
+
* @param data - entités à créer.
|
|
233
|
+
* @returns les entités persistées, dans le même ordre.
|
|
234
|
+
*/
|
|
235
|
+
createMany(data: Partial<T>[]): Promise<T[]>;
|
|
236
|
+
/**
|
|
237
|
+
* Met à jour **au plus une** entité correspondant au critère, de façon
|
|
238
|
+
* **atomique**, et retourne sa version persistée (ou `null` si aucune ne
|
|
239
|
+
* correspond).
|
|
240
|
+
*
|
|
241
|
+
* Atomicité : une **seule** requête (`UPDATE … RETURNING` SQL /
|
|
242
|
+
* `findOneAndUpdate` Mongo), jamais un `UPDATE` suivi d'une relecture séparée
|
|
243
|
+
* — cette dernière renverrait `null` à tort dès que le critère porte sur un
|
|
244
|
+
* champ modifié (ex. `updateOne({ status: "pending" }, { status: "done" })`).
|
|
245
|
+
*
|
|
246
|
+
* @param criteria - filtre de sélection. Un champ inconnu de l'entité lève
|
|
247
|
+
* `UnknownCriteriaField` (mêmes règles que `find`).
|
|
248
|
+
* @param data - champs à modifier.
|
|
249
|
+
* @returns l'entité mise à jour, ou `null` si le critère ne matche rien.
|
|
250
|
+
*/
|
|
251
|
+
updateOne(criteria: Criteria<T>, data: Partial<T>): Promise<T | null>;
|
|
252
|
+
/**
|
|
253
|
+
* Insère **ou** met à jour atomiquement l'entité identifiée par `criteria`
|
|
254
|
+
* (clé unique), en **une seule** requête (`INSERT … ON CONFLICT DO UPDATE …
|
|
255
|
+
* RETURNING` SQL / `findOneAndUpdate({ upsert })` Mongo) — jamais un `SELECT`
|
|
256
|
+
* d'existence suivi d'un `INSERT`/`UPDATE` séparé (2 round-trips + une race
|
|
257
|
+
* insert/update entre les deux).
|
|
258
|
+
*
|
|
259
|
+
* - **INSERT** (clé absente) : la ligne créée = `{ ...criteria, ...insertOnly,
|
|
260
|
+
* ...update }`.
|
|
261
|
+
* - **UPDATE** (conflit de clé) : seul `update` est ré-appliqué (`SET`) ;
|
|
262
|
+
* `criteria` et `insertOnly` ne touchent PAS la ligne existante (ex.
|
|
263
|
+
* `createdAt` posé à la création est préservé).
|
|
264
|
+
*
|
|
265
|
+
* Le `DO UPDATE` est **inconditionnel** (aucun `WHERE` : MySQL n'en accepte
|
|
266
|
+
* pas sur son `ON DUPLICATE KEY UPDATE`) — pour une valeur qui ne doit jamais
|
|
267
|
+
* régresser, poser la condition DANS la valeur via {@link UpdateOperators}
|
|
268
|
+
* (`{ seuil: { $max: v } }`), ce qui reste une instruction unique.
|
|
269
|
+
*
|
|
270
|
+
* @param criteria - clé de conflit (colonnes **uniques**, égalité simple — pas
|
|
271
|
+
* d'opérateurs riches `$`). Sert aussi de valeurs d'insertion.
|
|
272
|
+
* @param update - champs posés à l'insertion ET ré-appliqués en cas de conflit.
|
|
273
|
+
* Accepte une valeur nue ou un {@link UpdateOperators} (`$max`/`$min`).
|
|
274
|
+
* @param insertOnly - champs posés **uniquement** à l'insertion (ex. `createdAt`).
|
|
275
|
+
* @returns l'entité persistée (ligne réelle via `RETURNING` / `returnDocument`).
|
|
276
|
+
*/
|
|
277
|
+
upsert(criteria: Criteria<T>, update: UpdateData<T>, insertOnly?: Partial<T>): Promise<T>;
|
|
278
|
+
/**
|
|
279
|
+
* Met à jour **toutes** les entités correspondant au critère et retourne le
|
|
280
|
+
* **nombre** de lignes modifiées (parité de signature avec
|
|
281
|
+
* {@link IRepository.delete}).
|
|
282
|
+
*
|
|
283
|
+
* @param criteria - filtre de sélection. Un champ inconnu lève
|
|
284
|
+
* `UnknownCriteriaField`.
|
|
285
|
+
* @param data - champs à modifier.
|
|
286
|
+
* @returns le nombre d'entités mises à jour.
|
|
287
|
+
*/
|
|
288
|
+
updateMany(criteria: Criteria<T>, data: Partial<T>): Promise<number>;
|
|
289
|
+
/**
|
|
290
|
+
* Incrémente **atomiquement** des champs numériques d'**au plus une** entité
|
|
291
|
+
* (`SET f = f + ?` SQL / `$inc` Mongo), sans read-modify-write (donc sans race)
|
|
292
|
+
* — pour les compteurs (stats, usage/tokens, rate-limit). Un delta négatif
|
|
293
|
+
* décrémente. Retourne l'entité après modification, ou `null` si le critère ne
|
|
294
|
+
* matche rien.
|
|
295
|
+
*
|
|
296
|
+
* @param criteria - filtre de sélection (au plus une entité affectée).
|
|
297
|
+
* @param changes - deltas par champ (`{ hits: 1, credits: -5 }`).
|
|
298
|
+
* @returns l'entité mise à jour, ou `null`.
|
|
299
|
+
*/
|
|
300
|
+
increment(criteria: Criteria<T>, changes: Partial<Record<keyof T, number>>): Promise<T | null>;
|
|
301
|
+
/**
|
|
302
|
+
* Supprime les entités correspondant au critère.
|
|
303
|
+
*
|
|
304
|
+
* @param criteria - filtre de sélection.
|
|
305
|
+
* @returns nombre d'entités supprimées.
|
|
306
|
+
*/
|
|
307
|
+
delete(criteria: Criteria<T>): Promise<number>;
|
|
308
|
+
/**
|
|
309
|
+
* Supprime **au plus une** entité de façon **atomique** (symétrique
|
|
310
|
+
* d'{@link IRepository.updateOne} ; `DELETE … LIMIT 1` SQL / `deleteOne` Mongo).
|
|
311
|
+
*
|
|
312
|
+
* @param criteria - filtre de sélection.
|
|
313
|
+
* @returns `true` si une entité a été supprimée, `false` sinon.
|
|
314
|
+
*/
|
|
315
|
+
deleteOne(criteria: Criteria<T>): Promise<boolean>;
|
|
316
|
+
/**
|
|
317
|
+
* Supprime **au plus une** entité et **retourne** sa valeur supprimée (ou
|
|
318
|
+
* `null`), de façon atomique (`DELETE … RETURNING` SQL / `findOneAndDelete`
|
|
319
|
+
* Mongo) — claim-and-remove (file de jobs, outbox, pop atomique).
|
|
320
|
+
*
|
|
321
|
+
* @param criteria - filtre de sélection.
|
|
322
|
+
* @returns l'entité supprimée, ou `null` si aucune ne correspond.
|
|
323
|
+
*/
|
|
324
|
+
findOneAndDelete(criteria: Criteria<T>): Promise<T | null>;
|
|
325
|
+
/**
|
|
326
|
+
* Compte les entités correspondant au critère (toutes si omis).
|
|
327
|
+
*
|
|
328
|
+
* @param criteria - filtre optionnel.
|
|
329
|
+
*/
|
|
330
|
+
count(criteria?: Criteria<T>): Promise<number>;
|
|
331
|
+
/**
|
|
332
|
+
* Compte les **valeurs distinctes** d'un champ parmi les entités qui
|
|
333
|
+
* correspondent au critère (`COUNT(DISTINCT col)` SQL / agrégation Mongo).
|
|
334
|
+
*
|
|
335
|
+
* Répond à une question que `count` ne sait pas poser : « combien de personnes
|
|
336
|
+
* distinctes derrière ces sessions ? », « combien de comptes touchés par ces
|
|
337
|
+
* échecs ? ». La compter côté appelant supposerait de rapatrier la colonne
|
|
338
|
+
* entière pour la dédupliquer en mémoire — soit exactement l'énumération que
|
|
339
|
+
* ces compteurs existent pour éviter.
|
|
340
|
+
*
|
|
341
|
+
* Les valeurs nulles ne sont pas comptées, comme en SQL : l'absence de valeur
|
|
342
|
+
* n'est pas une valeur distincte de plus.
|
|
343
|
+
*
|
|
344
|
+
* @param field - champ dont on compte les valeurs distinctes.
|
|
345
|
+
* @param criteria - filtre optionnel, appliqué avant la déduplication.
|
|
346
|
+
* @returns le nombre de valeurs distinctes et non nulles.
|
|
347
|
+
*/
|
|
348
|
+
countDistinct(field: keyof T & string, criteria?: Criteria<T>): Promise<number>;
|
|
349
|
+
/**
|
|
350
|
+
* Indique si **au moins une** entité correspond au critère, sans rapatrier la
|
|
351
|
+
* ligne (`SELECT 1 … LIMIT 1` SQL / `exists` Mongo). Préférer à
|
|
352
|
+
* `findOne(...) !== null` (aucune colonne chargée) et à `count(...) > 0` (pas de
|
|
353
|
+
* comptage complet) pour un simple test d'existence.
|
|
354
|
+
*
|
|
355
|
+
* @param criteria - filtre de sélection.
|
|
356
|
+
* @returns `true` si une entité correspond, `false` sinon.
|
|
357
|
+
*/
|
|
358
|
+
exists(criteria: Criteria<T>): Promise<boolean>;
|
|
359
|
+
/**
|
|
360
|
+
* Retourne une **vue de ce repository liée à une transaction** : toutes ses
|
|
361
|
+
* opérations s'exécutent dans `tx` (commit/rollback gérés par
|
|
362
|
+
* `IOrm.transaction()`). Résout la fuite « repository non tx-aware » (ADR-0003
|
|
363
|
+
* risque #4) sans état global ni CLS.
|
|
364
|
+
*
|
|
365
|
+
* @param tx - transaction active (issue du callback de `IOrm.transaction`).
|
|
366
|
+
* @returns un repository équivalent dont les écritures/lectures portent sur `tx`.
|
|
367
|
+
*/
|
|
368
|
+
withTransaction(tx: ITransaction): IRepository<T>;
|
|
369
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unité de travail transactionnelle abstraite (commit / rollback / savepoint).
|
|
3
|
+
*
|
|
4
|
+
* Obtenue dans le callback de `IOrm.transaction()`. Les transactions cross-ORM
|
|
5
|
+
* (2PC) ne sont PAS garanties : une transaction porte sur un seul ORM/connexion.
|
|
6
|
+
* La sémantique des savepoints dépend du driver (peut être un no-op).
|
|
7
|
+
*/
|
|
8
|
+
export interface ITransaction {
|
|
9
|
+
/** Valide définitivement les opérations de la transaction. */
|
|
10
|
+
commit(): Promise<void>;
|
|
11
|
+
/** Annule toutes les opérations depuis le début de la transaction. */
|
|
12
|
+
rollback(): Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* Crée un point de sauvegarde nommé pour un rollback partiel ultérieur.
|
|
15
|
+
*
|
|
16
|
+
* @param name - identifiant du savepoint.
|
|
17
|
+
*/
|
|
18
|
+
savepoint(name: string): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Annule jusqu'à un savepoint sans terminer la transaction.
|
|
21
|
+
*
|
|
22
|
+
* @param name - savepoint cible.
|
|
23
|
+
*/
|
|
24
|
+
rollbackTo(name: string): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Expose l'objet transaction natif du driver (trappe bas niveau).
|
|
27
|
+
*
|
|
28
|
+
* @typeParam C - type natif attendu (ex. `Transaction` de l'ORM).
|
|
29
|
+
*/
|
|
30
|
+
getNative<C = unknown>(): C;
|
|
31
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type { IOrm } from "./IOrm.js";
|
|
2
|
+
export type { IEntity, IEntityRelation } from "./IEntity.js";
|
|
3
|
+
export type { IRepository, OrmCriteria, Criteria, FieldCriteria, FieldOperators, UpdateData, UpdateOperators, RepositoryReadOptions, } from "./IRepository.js";
|
|
4
|
+
export type { ITransaction } from "./ITransaction.js";
|
|
5
|
+
export type { IPage, IPageQuery, PageQuery } from "./IPage.js";
|
|
6
|
+
export type { IColumnInfo, IConnectionInfo, IRelationInfo, IEntityGraphNode, IOrmSummary, IOrmGraph, IConnectionError, IConnectionHealth, } from "./IOrmGraph.js";
|
|
7
|
+
export type { ILatencyWindow, IOrmStorageProbe, IOrmPoolProbe, IOrmProbe, } from "./IOrmProbe.js";
|