@nodefony/drizzle 10.0.0-alpha.9 → 10.0.0-beta.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/README.md +19 -19
- package/dist/index.js +3 -3
- package/dist/nodefony/command/orm-generate.js +3 -3
- package/dist/nodefony/config/defineModuleConfig.js +2 -2
- package/dist/nodefony/entity/userTable.js +1 -1
- package/dist/nodefony/registerStores.js +2 -2
- package/dist/nodefony/service/DrizzleService.js +26 -12
- package/dist/nodefony/src/DrizzleAuditStore.js +1 -1
- package/dist/nodefony/src/connectorTarget.js +1 -1
- package/dist/nodefony/src/migrator/DrizzleMigrator.js +3 -3
- package/dist/nodefony/src/migrator/adopt.js +1 -1
- package/dist/nodefony/src/migrator/destructive.js +2 -3
- package/dist/nodefony/src/migrator/drivers/mysqlDriver.js +1 -1
- package/dist/nodefony/src/migrator/drivers/postgresDriver.js +1 -1
- package/dist/nodefony/src/migrator/explain.js +7 -10
- package/dist/nodefony/src/migrator/history.js +25 -2
- package/dist/nodefony/src/migrator/kit.js +23 -9
- package/dist/nodefony/src/migrator/rebuildCopy.js +6 -6
- package/dist/nodefony/src/migrator/resolve.js +4 -4
- package/dist/nodefony/src/migrator/sources.js +13 -8
- package/dist/nodefony/src/orm-core/DrizzleOrm.js +49 -29
- package/dist/nodefony/src/orm-core/DrizzleRepository.js +38 -26
- package/dist/nodefony/src/queryKit.js +5 -5
- package/dist/types/nodefony/src/DrizzleUserRepository.d.ts +1 -1
- package/dist/types/nodefony/src/connectorTarget.d.ts +1 -1
- package/dist/types/nodefony/src/migrator/DrizzleMigrator.d.ts +4 -4
- package/dist/types/nodefony/src/migrator/destructive.d.ts +1 -1
- package/dist/types/nodefony/src/migrator/drivers/index.d.ts +2 -2
- package/dist/types/nodefony/src/migrator/explain.d.ts +9 -9
- package/dist/types/nodefony/src/migrator/name.d.ts +1 -1
- package/dist/types/nodefony/src/migrator/types.d.ts +2 -2
- package/dist/types/nodefony/src/orm-core/DrizzleOrm.d.ts +3 -3
- package/dist/types/nodefony/src/orm-core/DrizzleRepository.d.ts +1 -1
- package/dist/types/nodefony/src/orm-core/ddlPlan.d.ts +2 -2
- package/dist/types/nodefony/src/queryKit.d.ts +9 -9
- package/dist/types/nodefony/src/safeTarget.d.ts +2 -2
- package/docs/index.md +13 -13
- package/docs/migrations.md +1 -1
- package/package.json +14 -14
|
@@ -66,11 +66,11 @@ export declare function reserveIdempotencyKeyMysql(db: DrizzleDb, args: {
|
|
|
66
66
|
}): Promise<boolean>;
|
|
67
67
|
/** Filtres du listing utilisateur (sous-ensemble non portable de `IUserListQuery`). */
|
|
68
68
|
export interface UserListFilters {
|
|
69
|
-
role?: string;
|
|
70
|
-
enabled?: boolean;
|
|
71
|
-
locked?: boolean;
|
|
72
|
-
hasSocial?: boolean;
|
|
73
|
-
q?: string;
|
|
69
|
+
role?: string | undefined;
|
|
70
|
+
enabled?: boolean | undefined;
|
|
71
|
+
locked?: boolean | undefined;
|
|
72
|
+
hasSocial?: boolean | undefined;
|
|
73
|
+
q?: string | undefined;
|
|
74
74
|
}
|
|
75
75
|
/** Fenêtre + tri résolus (le défaut `identifier ASC` est posé par l'appelant). */
|
|
76
76
|
export interface UserPageWindow {
|
|
@@ -91,10 +91,10 @@ export declare function listUserIdsPage(db: DrizzleDb, dialect: SqlDialect, filt
|
|
|
91
91
|
}>;
|
|
92
92
|
/** Filtres du listing d'endpoints (sous-ensemble non portable d'`IWebhookListQuery`). */
|
|
93
93
|
export interface WebhookListFilters {
|
|
94
|
-
enabled?: boolean;
|
|
95
|
-
event?: string;
|
|
96
|
-
failing?: boolean;
|
|
97
|
-
q?: string;
|
|
94
|
+
enabled?: boolean | undefined;
|
|
95
|
+
event?: string | undefined;
|
|
96
|
+
failing?: boolean | undefined;
|
|
97
|
+
q?: string | undefined;
|
|
98
98
|
}
|
|
99
99
|
/**
|
|
100
100
|
* Sélectionne les `id` d'une **page** d'endpoints webhook (filtres + tri +
|
|
@@ -37,6 +37,6 @@ import type { SqlDialect } from "../config/config.js";
|
|
|
37
37
|
*/
|
|
38
38
|
export declare function describeTargetSafely(target: {
|
|
39
39
|
dialect: SqlDialect;
|
|
40
|
-
filename?: string;
|
|
41
|
-
url?: string;
|
|
40
|
+
filename?: string | undefined;
|
|
41
|
+
url?: string | undefined;
|
|
42
42
|
}, cwd?: string, grammar?: typeof path): string;
|
package/docs/index.md
CHANGED
|
@@ -365,7 +365,7 @@ Table dérivée de `drizzleConfigSchema` (`config.ts:136`) et de `SQL_DIALECTS`
|
|
|
365
365
|
|
|
366
366
|
**`filename` est volontairement sans défaut.** Le chemin dépend du kernel, qui n'existe pas quand le
|
|
367
367
|
schéma est évalué. Il est résolu **au démarrage** par `DrizzleService.#defaultFilename()`
|
|
368
|
-
(`DrizzleService.ts:
|
|
368
|
+
(`DrizzleService.ts:230`) vers `<app>/var/databases/nodefony-<connecteur>.db` — sous `var/`, le dossier
|
|
369
369
|
commun des données runtime : « où sont mes données ? » a une réponse unique, un seul chemin à
|
|
370
370
|
sauvegarder et à ignorer dans git.
|
|
371
371
|
|
|
@@ -406,13 +406,13 @@ use("@nodefony/drizzle", {
|
|
|
406
406
|
|
|
407
407
|
> [!WARNING]
|
|
408
408
|
> Une URL de connexion **porte un mot de passe**. Le module ne la journalise jamais telle quelle :
|
|
409
|
-
> `redactUrl()` (`DrizzleService.ts:
|
|
409
|
+
> `redactUrl()` (`DrizzleService.ts:99`) remplace le mot de passe par `***` avant tout log de
|
|
410
410
|
> démarrage, et la sonde d'administration applique la même règle.
|
|
411
411
|
|
|
412
412
|
### Quand la connexion échoue, le démarrage échoue
|
|
413
413
|
|
|
414
414
|
Un connecteur **déclaré** qui ne se connecte pas lève une `BootConfigurationError`
|
|
415
|
-
(`DrizzleService.ts:
|
|
415
|
+
(`DrizzleService.ts:368`) — en développement **comme** en production. Ce n'est pas une sévérité
|
|
416
416
|
gratuite : une infrastructure déclarée mais injoignable ne se répare pas en continuant. Un serveur qui
|
|
417
417
|
démarrerait « vivant » avec ses stores morts accepterait des requêtes pour échouer plus tard, la cause
|
|
418
418
|
noyée dans un avertissement. Le message d'erreur nomme le connecteur, le dialecte, la cible rédigée et
|
|
@@ -420,7 +420,7 @@ la piste à vérifier.
|
|
|
420
420
|
|
|
421
421
|
Pour les dialectes réseau, la connexion fait un **ping réel** au démarrage : les pools `pg` et `mysql2`
|
|
422
422
|
sont paresseux, sans ce `SELECT 1` une base morte « se connecterait » et n'échouerait qu'à la première
|
|
423
|
-
requête métier (`#connectPostgres()`, `DrizzleOrm.ts:1193` · `#connectMysql()`, `DrizzleOrm.ts:
|
|
423
|
+
requête métier (`#connectPostgres()`, `DrizzleOrm.ts:1193` · `#connectMysql()`, `DrizzleOrm.ts:1514`).
|
|
424
424
|
|
|
425
425
|
## Dialectes — une base par déploiement, un seul code
|
|
426
426
|
|
|
@@ -467,7 +467,7 @@ En MySQL, les verbes « qui rendent la ligne écrite » (`create`, `updateOne`,
|
|
|
467
467
|
`findOneAndDelete`) se décomposent en sélection de la cible → mutation bornée par la clé primaire **avec
|
|
468
468
|
le critère revérifié dans le `WHERE`** → relecture. Deux à trois allers-retours au lieu d'un : c'est le
|
|
469
469
|
prix du dialecte, payé **uniquement** en MySQL. Une course perdue rend `null`, jamais une mutation hors
|
|
470
|
-
critère (`#mysqlInsertReturning()`, `DrizzleRepository.ts:
|
|
470
|
+
critère (`#mysqlInsertReturning()`, `DrizzleRepository.ts:1105`).
|
|
471
471
|
|
|
472
472
|
Le SQL brut nécessaire aux entités du framework est lui aussi routé par dialecte, dans un seul fichier
|
|
473
473
|
(`queryKit.ts`) : recherche dans une colonne JSON (`findUserIdBySocialProvider()`, `queryKit.ts:76`),
|
|
@@ -507,7 +507,7 @@ connexion**, donc leurs tables sont créées au moment où l'ORM s'ouvre.
|
|
|
507
507
|
| Pièce | Rôle | Ancre |
|
|
508
508
|
| ---------------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------ |
|
|
509
509
|
| `Drizzle` (le module) | valide la config, déclare le schéma framework, monte le data plane | `index.ts` du module |
|
|
510
|
-
| `DrizzleService` | ouvre un ORM par connecteur au boot, ferme tout à l'arrêt | `connectAll()`, `DrizzleService.ts:
|
|
510
|
+
| `DrizzleService` | ouvre un ORM par connecteur au boot, ferme tout à l'arrêt | `connectAll()`, `DrizzleService.ts:214` |
|
|
511
511
|
| `DrizzleOrm` | la connexion : DDL dérivé, repositories, transactions, sonde | `DrizzleOrm.ts:214` |
|
|
512
512
|
| `DrizzleRepository<T>` | le CRUD portable, les opérateurs riches, l'eager-load | `DrizzleRepository.ts:146` |
|
|
513
513
|
| `DrizzleTransaction` | `BEGIN`/`COMMIT`/`ROLLBACK` pilotés à la main, sur les trois dialectes | `DrizzleTransaction.ts:70` |
|
|
@@ -559,7 +559,7 @@ await posts.count({ views: { $gte: 10 } });
|
|
|
559
559
|
|
|
560
560
|
Les opérateurs (`$eq $ne $gt $gte $lt $lte $in $nin $like`) sont **ceux d'orm-core**, identiques sur
|
|
561
561
|
tous les drivers ; la traduction en `eq()`/`inArray()` se fait dans `#where()`
|
|
562
|
-
(`DrizzleRepository.ts:
|
|
562
|
+
(`DrizzleRepository.ts:445`). Leur référence complète est dans
|
|
563
563
|
[la page d'orm-core](../../orm-core/docs/index.md).
|
|
564
564
|
|
|
565
565
|
`$like` est émis avec sa clause `ESCAPE '\'` (`likeSql.ts`), ce qui rend un `%` ou un `_` **littéral**
|
|
@@ -571,7 +571,7 @@ Deux points de comportement qui évitent des surprises :
|
|
|
571
571
|
|
|
572
572
|
- **« au plus une ligne »** est garanti par construction pour `updateOne`/`deleteOne`/`increment` :
|
|
573
573
|
la mutation est bornée par la clé primaire découverte de la table, jamais par un `LIMIT` sur un
|
|
574
|
-
`UPDATE` (`#pickOne()`, `DrizzleRepository.ts:
|
|
574
|
+
`UPDATE` (`#pickOne()`, `DrizzleRepository.ts:284`). C'est ce qui rend ces verbes portables — MySQL
|
|
575
575
|
interdit la forme naïve.
|
|
576
576
|
- **l'eager-load est manuel** : une requête `IN (…)` par relation déclarée, puis regroupement en
|
|
577
577
|
mémoire (`#populate()`, `DrizzleRepository.ts:694`). Choix assumé — pas de couche de relations à
|
|
@@ -627,7 +627,7 @@ const rows = await db.all(sql`
|
|
|
627
627
|
`);
|
|
628
628
|
```
|
|
629
629
|
|
|
630
|
-
C'est l'**anti-blocage** du modèle Repository (`getNativeConnection()`, `DrizzleOrm.ts:
|
|
630
|
+
C'est l'**anti-blocage** du modèle Repository (`getNativeConnection()`, `DrizzleOrm.ts:1783`) : CTE,
|
|
631
631
|
fonctions de fenêtre, sous-requêtes corrélées, jointures arbitraires. Deux contreparties assumées :
|
|
632
632
|
ce SQL n'est plus portable entre dialectes, et il **ne passe pas** par la sonde de profilage des
|
|
633
633
|
requêtes.
|
|
@@ -718,7 +718,7 @@ le framework résout ses stores avant que l'ORM ne soit connecté — et parce q
|
|
|
718
718
|
l'arrêt** avant que les serveurs HTTP n'aient fini de vider leurs requêtes en vol. Handle absent =
|
|
719
719
|
dégradation annoncée, pas un plantage : le `SessionStorage` rend une session vide et ignore les
|
|
720
720
|
écritures (`#repo()`, `SessionStorage.ts:86`), le store d'idempotence laisse passer la mutation sans
|
|
721
|
-
dédup (`begin()`, `DrizzleIdempotencyStore.ts:
|
|
721
|
+
dédup (`begin()`, `DrizzleIdempotencyStore.ts:225`).
|
|
722
722
|
|
|
723
723
|
**SQL n'a pas de TTL.** Contrairement à Redis, rien n'expire tout seul : chaque store expose un `gc()`
|
|
724
724
|
applicatif qui supprime les lignes échues, déclenché par un minuteur hors du chemin chaud —
|
|
@@ -735,7 +735,7 @@ c'est ce qui interdit de conclure « nouvelle mutation » hors d'une réservatio
|
|
|
735
735
|
en deux instructions au verdict non ambigu (`reserveIdempotencyKeyMysql()`, `queryKit.ts:152`).
|
|
736
736
|
|
|
737
737
|
**Le journal d'audit** pagine par un curseur **composite auto-portant** `<horodatage>:<id>` sur un ordre
|
|
738
|
-
total, plutôt que par un identifiant seul (`listPage()`, `DrizzleAuditStore.ts:
|
|
738
|
+
total, plutôt que par un identifiant seul (`listPage()`, `DrizzleAuditStore.ts:175`). Deux gains : plus
|
|
739
739
|
d'aller-retour pour résoudre le curseur, et une pagination qui ne rembobine pas à la première page si
|
|
740
740
|
l'événement de référence a été purgé entre deux appels.
|
|
741
741
|
|
|
@@ -834,7 +834,7 @@ faire lui-même).
|
|
|
834
834
|
Côté écrans : **Database**, **ORM (vue d'ensemble et par entité)** et **Stores** — ce dernier répond à
|
|
835
835
|
la question « où sont écrites mes données ? » pour chaque brique.
|
|
836
836
|
|
|
837
|
-
La sonde d'un connecteur s'adapte au dialecte (`probe()`, `DrizzleOrm.ts:
|
|
837
|
+
La sonde d'un connecteur s'adapte au dialecte (`probe()`, `DrizzleOrm.ts:1873`) :
|
|
838
838
|
|
|
839
839
|
- **SQLite** → `storage` : taille du fichier, mode de journal, pages libres (lus par `PRAGMA`) ;
|
|
840
840
|
- **PostgreSQL / MySQL** → `pool` : taille, connexions libres, empruntées, en attente — **compteurs en
|
|
@@ -851,7 +851,7 @@ l'emplacement **est** l'infra déclarée, déjà affichée ailleurs (`location`,
|
|
|
851
851
|
## ⚡ Performance & mémoire
|
|
852
852
|
|
|
853
853
|
**La sonde de requêtes ne coûte rien quand elle est éteinte.** Chaque exécution passe par un point de
|
|
854
|
-
mesure unique (`#prof()`, `DrizzleRepository.ts:
|
|
854
|
+
mesure unique (`#prof()`, `DrizzleRepository.ts:355`) qui alimente deux consommateurs — le profileur
|
|
855
855
|
par requête (barre de debug) et l'agrégat de flux. Les deux sont gardés par un drapeau : si aucun n'est
|
|
856
856
|
actif, la fonction rend le constructeur de requête tel quel, sans allocation. Le flux est **désactivé
|
|
857
857
|
en production** par défaut.
|
package/docs/migrations.md
CHANGED
|
@@ -426,7 +426,7 @@ Trois propriétés en découlent, et elles valent d'être nommées :
|
|
|
426
426
|
- **Rien n'est appliqué deux fois.** L'historique (`nodefony_migrations`, `types.ts:23`) est écrit
|
|
427
427
|
dans la même transaction que le DDL, là où le moteur le permet.
|
|
428
428
|
- **Un pod en retard ne reçoit pas de trafic.** En `none` comme en `migrate`, l'état du schéma est
|
|
429
|
-
publié à la sonde de disponibilité (`#publishReadiness()`, `DrizzleService.ts:
|
|
429
|
+
publié à la sonde de disponibilité (`#publishReadiness()`, `DrizzleService.ts:557`) : `/readyz`
|
|
430
430
|
répond 503, l'orchestrateur sort l'exemplaire du répartiteur de charge, et l'ancien continue de
|
|
431
431
|
servir. `/livez` n'est jamais touché — un schéma en retard n'est pas un processus malade, et le
|
|
432
432
|
redémarrer ne réparerait rien. La vérification est rejouée toutes les 15 secondes : dès que le
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nodefony/drizzle",
|
|
3
|
-
"version": "10.0.0-
|
|
3
|
+
"version": "10.0.0-beta.1",
|
|
4
4
|
"description": "Moteur SQL de Nodefony sur Drizzle ORM (SQLite, PostgreSQL, MySQL) : dépôts typés, migrations de schéma et adoption d'une base existante",
|
|
5
5
|
"nodefony": {
|
|
6
6
|
"storeKind": "durable",
|
|
@@ -60,29 +60,29 @@
|
|
|
60
60
|
"zod": "^4.6.5"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
|
-
"@nodefony/framework": "^10.0.0-
|
|
64
|
-
"@nodefony/http": "^10.0.0-
|
|
65
|
-
"@nodefony/orm-core": "^10.0.0-
|
|
66
|
-
"@nodefony/security": "^10.0.0-
|
|
67
|
-
"@nodefony/user": "^10.0.0-
|
|
63
|
+
"@nodefony/framework": "^10.0.0-beta.1",
|
|
64
|
+
"@nodefony/http": "^10.0.0-beta.1",
|
|
65
|
+
"@nodefony/orm-core": "^10.0.0-beta.1",
|
|
66
|
+
"@nodefony/security": "^10.0.0-beta.1",
|
|
67
|
+
"@nodefony/user": "^10.0.0-beta.1",
|
|
68
68
|
"@types/better-sqlite3": "9.6.0",
|
|
69
|
-
"@types/node": "26.6.
|
|
69
|
+
"@types/node": "26.6.3",
|
|
70
70
|
"@types/pg": "8.23.1",
|
|
71
71
|
"better-sqlite3": "13.0.3",
|
|
72
72
|
"drizzle-kit": "0.31.11",
|
|
73
73
|
"mysql2": "3.24.4",
|
|
74
|
-
"nodefony": "^10.0.0-
|
|
74
|
+
"nodefony": "^10.0.0-beta.1",
|
|
75
75
|
"pg": "8.23.0"
|
|
76
76
|
},
|
|
77
77
|
"peerDependencies": {
|
|
78
|
-
"@nodefony/framework": "^10.0.0-
|
|
79
|
-
"@nodefony/http": "^10.0.0-
|
|
80
|
-
"@nodefony/orm-core": "^10.0.0-
|
|
81
|
-
"@nodefony/security": "^10.0.0-
|
|
82
|
-
"@nodefony/user": "^10.0.0-
|
|
78
|
+
"@nodefony/framework": "^10.0.0-beta.1",
|
|
79
|
+
"@nodefony/http": "^10.0.0-beta.1",
|
|
80
|
+
"@nodefony/orm-core": "^10.0.0-beta.1",
|
|
81
|
+
"@nodefony/security": "^10.0.0-beta.1",
|
|
82
|
+
"@nodefony/user": "^10.0.0-beta.1",
|
|
83
83
|
"better-sqlite3": "^13.0.0",
|
|
84
84
|
"mysql2": "^3.24.0",
|
|
85
|
-
"nodefony": "^10.0.0-
|
|
85
|
+
"nodefony": "^10.0.0-beta.1",
|
|
86
86
|
"pg": "^8.23.0"
|
|
87
87
|
},
|
|
88
88
|
"repository": {
|