@nodefony/drizzle 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.
Files changed (143) hide show
  1. package/LICENSE +544 -0
  2. package/README.md +162 -0
  3. package/dist/_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/decorate.js +9 -0
  4. package/dist/_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/decorateMetadata.js +6 -0
  5. package/dist/index.js +105 -0
  6. package/dist/nodefony/command/migrateShared.js +247 -0
  7. package/dist/nodefony/command/orm-generate.js +356 -0
  8. package/dist/nodefony/command/orm-migrate-baseline.js +208 -0
  9. package/dist/nodefony/command/orm-migrate-repair.js +114 -0
  10. package/dist/nodefony/command/orm-migrate-status.js +67 -0
  11. package/dist/nodefony/command/orm-migrate.js +141 -0
  12. package/dist/nodefony/command/orm-reset.js +166 -0
  13. package/dist/nodefony/config/config.js +107 -0
  14. package/dist/nodefony/config/defineModuleConfig.js +63 -0
  15. package/dist/nodefony/entity/auditEventEntity.js +93 -0
  16. package/dist/nodefony/entity/colKit.js +260 -0
  17. package/dist/nodefony/entity/idempotencyEntity.js +74 -0
  18. package/dist/nodefony/entity/sessionEntity.js +75 -0
  19. package/dist/nodefony/entity/tokenEntity.js +198 -0
  20. package/dist/nodefony/entity/totpSecretEntity.js +98 -0
  21. package/dist/nodefony/entity/userTable.js +141 -0
  22. package/dist/nodefony/entity/webAuthnCredentialEntity.js +114 -0
  23. package/dist/nodefony/entity/webhookEndpointEntity.js +106 -0
  24. package/dist/nodefony/interfaces/IDrizzleConfig.js +1 -0
  25. package/dist/nodefony/interfaces/index.js +1 -0
  26. package/dist/nodefony/migrations-schema/mysql.js +48 -0
  27. package/dist/nodefony/migrations-schema/postgres.js +48 -0
  28. package/dist/nodefony/migrations-schema/sqlite.js +48 -0
  29. package/dist/nodefony/registerStores.js +218 -0
  30. package/dist/nodefony/service/DrizzleService.js +282 -0
  31. package/dist/nodefony/src/DrizzleAuditStore.js +203 -0
  32. package/dist/nodefony/src/DrizzleIdempotencyStore.js +278 -0
  33. package/dist/nodefony/src/DrizzleTokenStore.js +244 -0
  34. package/dist/nodefony/src/DrizzleTotpSecretStore.js +151 -0
  35. package/dist/nodefony/src/DrizzleUserRepository.js +217 -0
  36. package/dist/nodefony/src/DrizzleWebAuthnCredentialStore.js +159 -0
  37. package/dist/nodefony/src/DrizzleWebhookStore.js +169 -0
  38. package/dist/nodefony/src/SessionStorage.js +259 -0
  39. package/dist/nodefony/src/connectorTarget.js +59 -0
  40. package/dist/nodefony/src/likeSql.js +50 -0
  41. package/dist/nodefony/src/migrator/DrizzleMigrator.js +775 -0
  42. package/dist/nodefony/src/migrator/adopt.js +553 -0
  43. package/dist/nodefony/src/migrator/appSchema.js +414 -0
  44. package/dist/nodefony/src/migrator/catalog.js +76 -0
  45. package/dist/nodefony/src/migrator/destructive.js +213 -0
  46. package/dist/nodefony/src/migrator/divergence.js +84 -0
  47. package/dist/nodefony/src/migrator/drivers/index.js +39 -0
  48. package/dist/nodefony/src/migrator/drivers/mysqlDriver.js +147 -0
  49. package/dist/nodefony/src/migrator/drivers/postgresDriver.js +151 -0
  50. package/dist/nodefony/src/migrator/drivers/sqliteDriver.js +121 -0
  51. package/dist/nodefony/src/migrator/explain.js +565 -0
  52. package/dist/nodefony/src/migrator/hash.js +47 -0
  53. package/dist/nodefony/src/migrator/history.js +219 -0
  54. package/dist/nodefony/src/migrator/index.js +16 -0
  55. package/dist/nodefony/src/migrator/kit.js +296 -0
  56. package/dist/nodefony/src/migrator/name.js +68 -0
  57. package/dist/nodefony/src/migrator/paths.js +88 -0
  58. package/dist/nodefony/src/migrator/refusals.js +143 -0
  59. package/dist/nodefony/src/migrator/resolve.js +281 -0
  60. package/dist/nodefony/src/migrator/schemaDiff.js +86 -0
  61. package/dist/nodefony/src/migrator/sources.js +419 -0
  62. package/dist/nodefony/src/migrator/status.js +231 -0
  63. package/dist/nodefony/src/migrator/types.js +91 -0
  64. package/dist/nodefony/src/orm-core/DrizzleOrm.js +1154 -0
  65. package/dist/nodefony/src/orm-core/DrizzleRepository.js +610 -0
  66. package/dist/nodefony/src/orm-core/DrizzleTransaction.js +106 -0
  67. package/dist/nodefony/src/orm-core/index.js +4 -0
  68. package/dist/nodefony/src/queryKit.js +318 -0
  69. package/dist/nodefony/src/safeTarget.js +55 -0
  70. package/dist/types/index.d.ts +76 -0
  71. package/dist/types/nodefony/command/migrateShared.d.ts +137 -0
  72. package/dist/types/nodefony/command/orm-generate.d.ts +53 -0
  73. package/dist/types/nodefony/command/orm-migrate-baseline.d.ts +87 -0
  74. package/dist/types/nodefony/command/orm-migrate-repair.d.ts +66 -0
  75. package/dist/types/nodefony/command/orm-migrate-status.d.ts +38 -0
  76. package/dist/types/nodefony/command/orm-migrate.d.ts +65 -0
  77. package/dist/types/nodefony/command/orm-reset.d.ts +55 -0
  78. package/dist/types/nodefony/config/config.d.ts +110 -0
  79. package/dist/types/nodefony/config/defineModuleConfig.d.ts +24 -0
  80. package/dist/types/nodefony/entity/auditEventEntity.d.ts +56 -0
  81. package/dist/types/nodefony/entity/colKit.d.ts +130 -0
  82. package/dist/types/nodefony/entity/idempotencyEntity.d.ts +52 -0
  83. package/dist/types/nodefony/entity/sessionEntity.d.ts +50 -0
  84. package/dist/types/nodefony/entity/tokenEntity.d.ts +53 -0
  85. package/dist/types/nodefony/entity/totpSecretEntity.d.ts +61 -0
  86. package/dist/types/nodefony/entity/userTable.d.ts +65 -0
  87. package/dist/types/nodefony/entity/webAuthnCredentialEntity.d.ts +57 -0
  88. package/dist/types/nodefony/entity/webhookEndpointEntity.d.ts +58 -0
  89. package/dist/types/nodefony/interfaces/IDrizzleConfig.d.ts +17 -0
  90. package/dist/types/nodefony/interfaces/index.d.ts +1 -0
  91. package/dist/types/nodefony/migrations-schema/mysql.d.ts +9 -0
  92. package/dist/types/nodefony/migrations-schema/postgres.d.ts +9 -0
  93. package/dist/types/nodefony/migrations-schema/sqlite.d.ts +9 -0
  94. package/dist/types/nodefony/registerStores.d.ts +52 -0
  95. package/dist/types/nodefony/service/DrizzleService.d.ts +27 -0
  96. package/dist/types/nodefony/src/DrizzleAuditStore.d.ts +65 -0
  97. package/dist/types/nodefony/src/DrizzleIdempotencyStore.d.ts +129 -0
  98. package/dist/types/nodefony/src/DrizzleTokenStore.d.ts +146 -0
  99. package/dist/types/nodefony/src/DrizzleTotpSecretStore.d.ts +60 -0
  100. package/dist/types/nodefony/src/DrizzleUserRepository.d.ts +67 -0
  101. package/dist/types/nodefony/src/DrizzleWebAuthnCredentialStore.d.ts +62 -0
  102. package/dist/types/nodefony/src/DrizzleWebhookStore.d.ts +79 -0
  103. package/dist/types/nodefony/src/SessionStorage.d.ts +72 -0
  104. package/dist/types/nodefony/src/connectorTarget.d.ts +48 -0
  105. package/dist/types/nodefony/src/likeSql.d.ts +29 -0
  106. package/dist/types/nodefony/src/migrator/DrizzleMigrator.d.ts +94 -0
  107. package/dist/types/nodefony/src/migrator/adopt.d.ts +280 -0
  108. package/dist/types/nodefony/src/migrator/appSchema.d.ts +223 -0
  109. package/dist/types/nodefony/src/migrator/catalog.d.ts +100 -0
  110. package/dist/types/nodefony/src/migrator/destructive.d.ts +123 -0
  111. package/dist/types/nodefony/src/migrator/divergence.d.ts +61 -0
  112. package/dist/types/nodefony/src/migrator/drivers/index.d.ts +26 -0
  113. package/dist/types/nodefony/src/migrator/drivers/mysqlDriver.d.ts +83 -0
  114. package/dist/types/nodefony/src/migrator/drivers/postgresDriver.d.ts +81 -0
  115. package/dist/types/nodefony/src/migrator/drivers/sqliteDriver.d.ts +53 -0
  116. package/dist/types/nodefony/src/migrator/explain.d.ts +424 -0
  117. package/dist/types/nodefony/src/migrator/hash.d.ts +39 -0
  118. package/dist/types/nodefony/src/migrator/history.d.ts +139 -0
  119. package/dist/types/nodefony/src/migrator/index.d.ts +20 -0
  120. package/dist/types/nodefony/src/migrator/kit.d.ts +141 -0
  121. package/dist/types/nodefony/src/migrator/name.d.ts +52 -0
  122. package/dist/types/nodefony/src/migrator/paths.d.ts +54 -0
  123. package/dist/types/nodefony/src/migrator/refusals.d.ts +170 -0
  124. package/dist/types/nodefony/src/migrator/resolve.d.ts +201 -0
  125. package/dist/types/nodefony/src/migrator/schemaDiff.d.ts +112 -0
  126. package/dist/types/nodefony/src/migrator/sources.d.ts +119 -0
  127. package/dist/types/nodefony/src/migrator/status.d.ts +132 -0
  128. package/dist/types/nodefony/src/migrator/types.d.ts +273 -0
  129. package/dist/types/nodefony/src/orm-core/DrizzleOrm.d.ts +241 -0
  130. package/dist/types/nodefony/src/orm-core/DrizzleRepository.d.ts +98 -0
  131. package/dist/types/nodefony/src/orm-core/DrizzleTransaction.d.ts +71 -0
  132. package/dist/types/nodefony/src/orm-core/index.d.ts +11 -0
  133. package/dist/types/nodefony/src/queryKit.d.ts +136 -0
  134. package/dist/types/nodefony/src/safeTarget.d.ts +42 -0
  135. package/docs/index.md +954 -0
  136. package/docs/migrations.md +691 -0
  137. package/migrations/mysql/0000_framework_init.sql +137 -0
  138. package/migrations/mysql/meta/_journal.json +13 -0
  139. package/migrations/postgres/0000_framework_init.sql +128 -0
  140. package/migrations/postgres/meta/_journal.json +13 -0
  141. package/migrations/sqlite/0000_framework_init.sql +127 -0
  142. package/migrations/sqlite/meta/_journal.json +13 -0
  143. package/package.json +126 -0
@@ -0,0 +1,201 @@
1
+ import type { Kernel } from "nodefony";
2
+ import type { DdlMode, DivergenceMode, MigrationCheckMode, SqlDialect } from "../../config/config.js";
3
+ import type { IDrizzleConfig } from "../../interfaces/IDrizzleConfig.js";
4
+ import { DrizzleMigrator } from "./DrizzleMigrator.js";
5
+ import type { IMigrationTarget } from "./drivers/index.js";
6
+ /**
7
+ * Résolution du décor d'une commande de migration : QUI possède le connecteur,
8
+ * OÙ se trouve sa base, QUEL mode de schéma s'applique.
9
+ *
10
+ * **Pourquoi un fichier à part, et pourquoi il ne fait aucune entrée-sortie** :
11
+ * ces règles sont lues par cinq commandes, par le démarrage du module et par la
12
+ * sonde de disponibilité. Une seule d'entre elles recopiée ailleurs
13
+ * divergerait — et une divergence de mode `ddl` entre le démarrage et la ligne
14
+ * de commande, c'est une base que l'un croit à jour et que l'autre migre.
15
+ *
16
+ * Les fonctions de décision sont **pures** : on leur INJECTE l'environnement
17
+ * constaté au lieu de le lire ici. C'est ce qui les rend éprouvables sans
18
+ * kernel, sans base et sans variable d'environnement à poser.
19
+ */
20
+ import { MIGRATE_URL_ENV } from "./types.js";
21
+ export { MIGRATE_URL_ENV };
22
+ /** L'environnement tel qu'on le CONSTATE — jamais déduit à l'intérieur. */
23
+ export interface IMigrationEnv {
24
+ /** Mode moteur normalisé du kernel : `development` ou `production`. */
25
+ runtime: "development" | "production";
26
+ /** `NODE_ENV` brut — seul porteur de la valeur `test`. */
27
+ nodeEnv?: string | undefined;
28
+ }
29
+ /**
30
+ * Constate l'environnement depuis le kernel et le processus.
31
+ *
32
+ * @param kernel - kernel courant, ou `null` hors application.
33
+ * @returns l'environnement constaté, prêt à être injecté aux règles pures.
34
+ */
35
+ export declare function readMigrationEnv(kernel: Kernel | null): IMigrationEnv;
36
+ /**
37
+ * L'effacement d'une base est-il ACCEPTÉ dans cet environnement ?
38
+ *
39
+ * **Liste blanche, jamais liste noire** : seul `development` passe. Un
40
+ * `staging`, un `test`, un environnement que personne n'a pensé à nommer sont
41
+ * refusés — c'est exactement ce qu'une garde écrite « si production » laisserait
42
+ * passer, et c'est là que l'accident se produit.
43
+ *
44
+ * Écrite ici parce qu'elle a DEUX lecteurs qui doivent dire la même chose :
45
+ * `orm:reset`, qui refuse ; et le rendu des migrations, qui ne doit pas proposer
46
+ * un geste que l'autre va rejeter. Deux copies de cette règle divergeraient, et
47
+ * la sortie promettrait alors une commande impossible.
48
+ *
49
+ * @param env - environnement constaté.
50
+ * @returns `true` si `orm:reset` est recevable.
51
+ */
52
+ export declare function resetAllowed(env: IMigrationEnv): boolean;
53
+ /**
54
+ * Le mode de schéma qui s'applique à un connecteur.
55
+ *
56
+ * Règle des défauts, et son pourquoi : **appliquer des migrations au démarrage
57
+ * n'est jamais un défaut**. C'est la norme unanime des outils de migration, et
58
+ * elle tient à un fait simple — au démarrage, plusieurs exemplaires partent en
59
+ * même temps. `migrate` est donc toujours un choix écrit, jamais une déduction.
60
+ *
61
+ * - développement et test → `auto` : le schéma suit le code, sans rien taper ;
62
+ * - tout le reste → `none` : personne ne touche au schéma au démarrage, un
63
+ * travail externe applique les migrations avant que le trafic n'arrive.
64
+ *
65
+ * @param explicit - valeur écrite dans la configuration du connecteur, si elle l'est.
66
+ * @param env - environnement constaté.
67
+ * @returns le mode effectif.
68
+ */
69
+ export declare function resolveDdlMode(explicit: DdlMode | undefined, env: IMigrationEnv): DdlMode;
70
+ /**
71
+ * La conduite de la sonde de disponibilité face à un schéma en retard.
72
+ *
73
+ * En production, un exemplaire dont le schéma est en retard ne doit pas
74
+ * recevoir de trafic : il répondrait des erreurs de colonne inconnue à des
75
+ * utilisateurs réels. Ailleurs, le retenir gênerait plus qu'il n'aiderait — un
76
+ * avertissement suffit.
77
+ *
78
+ * @param explicit - valeur écrite dans `migrations.check`, si elle l'est.
79
+ * @param env - environnement constaté.
80
+ * @returns la conduite effective.
81
+ */
82
+ export declare function resolveCheckMode(explicit: MigrationCheckMode | undefined, env: IMigrationEnv): MigrationCheckMode;
83
+ /** Ce qu'un connecteur est, du point de vue des migrations. */
84
+ export type IConnectorResolution = {
85
+ /** Le connecteur existe et son propriétaire sait migrer. */
86
+ kind: "ready";
87
+ connector: string;
88
+ dialect: SqlDialect;
89
+ target: IMigrationTarget;
90
+ /** `true` quand la cible vient de {@link MIGRATE_URL_ENV}. */
91
+ fromMigrateUrl: boolean;
92
+ ddl: DdlMode;
93
+ } | {
94
+ /**
95
+ * Le connecteur est enregistré, mais la commande ne peut pas travailler
96
+ * dessus. Deux causes bien distinctes, et il ne faut JAMAIS les
97
+ * confondre — `sqlLike` les sépare.
98
+ */
99
+ kind: "unsupported";
100
+ connector: string;
101
+ /** Ce qui porte ce connecteur, tel que l'ORM se décrit lui-même. */
102
+ owner: string;
103
+ /**
104
+ * Sa base est-elle une base SQL ?
105
+ *
106
+ * `true` — c'est un connecteur SQL qui n'est simplement pas déclaré dans
107
+ * la configuration du module : la commande n'a pas ses coordonnées de
108
+ * connexion. Lui répondre « ne porte pas de migrations » serait FAUX, et
109
+ * un message faux publié est appris par les scripts qui le lisent.
110
+ *
111
+ * `false` — sa base résorbe l'écart entre le code et le schéma autrement
112
+ * (index synchronisés plutôt que fichiers versionnés) : il n'y a rien à
113
+ * migrer ici, aujourd'hui.
114
+ */
115
+ sqlLike: boolean;
116
+ /** Base sous-jacente telle que l'ORM la nomme (`mongodb`, `sqlite`…). */
117
+ driver: string;
118
+ } | {
119
+ /**
120
+ * La variable de migration désigne une AUTRE base que le connecteur.
121
+ *
122
+ * Refuser est le seul comportement sûr : on ne peut ni appliquer du SQL
123
+ * d'un dialecte avec le pilote d'un autre, ni deviner laquelle des deux
124
+ * bases l'exploitant visait. L'ignorer produisait un faux succès de
125
+ * déploiement — la pire sortie possible d'une commande de migration.
126
+ */
127
+ kind: "url-mismatch";
128
+ connector: string;
129
+ /** Dialecte du connecteur déclaré. */
130
+ dialect: SqlDialect;
131
+ /** Dialecte que désigne la variable, ou `null` si elle est illisible. */
132
+ urlDialect: SqlDialect | null;
133
+ } | {
134
+ /** Aucun connecteur de ce nom, nulle part. */
135
+ kind: "unknown";
136
+ connector: string;
137
+ /** Tous les noms qui existent, tous ORM confondus, triés. */
138
+ known: string[];
139
+ };
140
+ /**
141
+ * Tous les noms de connecteurs qui existent, tous ORM confondus.
142
+ *
143
+ * L'union du registre et de la configuration : le registre porte ce qui est
144
+ * connecté, la configuration ce qui est déclaré. Un connecteur déclaré mais non
145
+ * connecté doit apparaître dans la liste — sinon un utilisateur qui a fait une
146
+ * faute de frappe se voit répondre que son connecteur n'existe pas ET ne le
147
+ * voit pas dans la liste, alors qu'il est bien écrit dans son fichier.
148
+ *
149
+ * @param config - configuration validée du module drizzle.
150
+ * @returns les noms, triés, sans doublon.
151
+ */
152
+ export declare function knownConnectors(config: IDrizzleConfig): string[];
153
+ /**
154
+ * Résout un nom de connecteur en l'une des **trois** réponses possibles.
155
+ *
156
+ * Ces trois réponses sont un contrat, pas un détail d'implémentation : le jour
157
+ * où un second ORM apporte ses propres migrations, c'est `unsupported` qui doit
158
+ * cesser de sortir pour ses connecteurs — et rien d'autre ne bouge. Répondre
159
+ * « ne porte pas de migrations » à un connecteur qui en porterait serait un
160
+ * message FAUX, appris par les scripts qui le lisent.
161
+ *
162
+ * La propriété se **constate** sur la configuration du module, jamais par un
163
+ * test d'instance : à la frontière npm, deux copies du même paquet font échouer
164
+ * `instanceof` sans un mot.
165
+ *
166
+ * @param connector - nom demandé.
167
+ * @param config - configuration validée du module drizzle.
168
+ * @param env - environnement constaté.
169
+ * @param kernel - kernel courant, indispensable au chemin SQLite par défaut.
170
+ * @param options - `allowMigrateUrl` autorise {@link MIGRATE_URL_ENV} à primer.
171
+ * @returns la réponse, discriminée par `kind`.
172
+ */
173
+ export declare function resolveConnector(connector: string, config: IDrizzleConfig, env: IMigrationEnv, kernel: Kernel | null, options?: {
174
+ allowMigrateUrl?: boolean;
175
+ }): IConnectorResolution;
176
+ /**
177
+ * Dossier de migrations de l'application, résolu depuis la racine que le kernel
178
+ * connaît.
179
+ *
180
+ * Jamais depuis le répertoire courant du processus : un espace de travail en a
181
+ * plusieurs, et la commande serait juste ou fausse selon l'endroit d'où on la
182
+ * tape — le pire des comportements, parce qu'il marche une fois sur deux.
183
+ *
184
+ * @param kernel - kernel courant.
185
+ * @param dir - valeur de `migrations.dir` (relative, ou absolue si l'app le veut).
186
+ * @returns le chemin absolu, ou `undefined` sans kernel.
187
+ */
188
+ export declare function appMigrationsDir(kernel: Kernel | null, dir: string): string | undefined;
189
+ /**
190
+ * Construit l'applicateur d'un connecteur résolu.
191
+ *
192
+ * @param resolution - réponse `ready` de {@link resolveConnector}.
193
+ * @param config - configuration validée du module drizzle.
194
+ * @param kernel - kernel courant (racine de l'application).
195
+ * @returns l'applicateur, sources du framework et de l'application chargées.
196
+ */
197
+ export declare function buildMigrator(resolution: Extract<IConnectorResolution, {
198
+ kind: "ready";
199
+ }>, config: IDrizzleConfig, kernel: Kernel | null): Promise<DrizzleMigrator>;
200
+ /** Conduite face à la divergence, telle que la configuration la déclare. */
201
+ export declare function resolveDivergenceMode(config: IDrizzleConfig): DivergenceMode;
@@ -0,0 +1,112 @@
1
+ import type { IColumnInfo } from "@nodefony/orm-core";
2
+ import type { SqlDialect } from "../../config/config.js";
3
+ import type { ISchemaReader } from "./catalog.js";
4
+ /**
5
+ * L'écart entre le schéma DÉCLARÉ dans le code et le schéma RÉELLEMENT en base.
6
+ *
7
+ * ## Pourquoi ce calcul existe, et ce qu'il permet que personne d'autre ne fait
8
+ *
9
+ * Les outils de migration connaissent **deux** choses : les fichiers et
10
+ * l'historique. Ils en déduisent « tout est appliqué » et s'arrêtent là. Ils ne
11
+ * regardent jamais la base elle-même.
12
+ *
13
+ * Croiser une **troisième** source rend visible un incident courant et coûteux :
14
+ * *l'historique est complet, aucune migration n'est en attente — et pourtant la
15
+ * base ne correspond pas au code*. Quelqu'un a modifié la base à la main, un
16
+ * correctif d'urgence n'a pas été reporté, deux environnements ont divergé.
17
+ *
18
+ * Le même calcul sert deux usages qui n'ont l'air d'avoir aucun rapport :
19
+ *
20
+ * - en développement, il **répare tout seul** le cas de loin le plus fréquent —
21
+ * le back a ajouté un champ, la table existe déjà, et la colonne manque ;
22
+ * - en production, il **signale** la divergence, sans jamais rien réparer.
23
+ *
24
+ * ## Deux règles non négociables
25
+ *
26
+ * **1. Ce qui est EN PLUS est ignoré.** Le diff signale ce qui MANQUE, jamais
27
+ * ce qu'il trouve en trop. Ce n'est pas de la prudence, c'est une condition
28
+ * d'existence : toute application qui écrit des migrations libres (une vue, un
29
+ * déclencheur, une colonne ajoutée à une table d'entité) a une base
30
+ * légitimement et en permanence différente du schéma déclaré. Signaler le
31
+ * surplus allumerait le voyant à vie chez ces utilisateurs — donc il serait
32
+ * appris comme du bruit, donc il serait mort.
33
+ *
34
+ * **2. Le rattrapage est STRICTEMENT additif.** Il ajoute une colonne absente,
35
+ * et seulement si elle accepte le vide. Jamais de suppression, jamais de
36
+ * changement de type, jamais de passage en obligatoire — et jamais de valeur
37
+ * inventée pour remplir une colonne obligatoire. Tout le reste est publié comme
38
+ * un écart, avec le geste, et attend une décision humaine.
39
+ */
40
+ /** Une colonne attendue par le code et absente de la base. */
41
+ export interface ISchemaGap {
42
+ /** Table concernée, telle qu'elle s'appelle en base. */
43
+ table: string;
44
+ /** Colonne attendue. */
45
+ column: string;
46
+ /** Type SQL attendu, dans le dialecte du connecteur. */
47
+ type: string;
48
+ /** La colonne accepte-t-elle le vide ? (seules celles-ci se rattrapent) */
49
+ nullable: boolean;
50
+ }
51
+ /** Ce que la comparaison a trouvé. */
52
+ export interface ISchemaComparison {
53
+ /**
54
+ * Colonnes manquantes qui acceptent le vide — rattrapables sans rien
55
+ * inventer. C'est le cas fréquent : un champ ajouté par le back.
56
+ */
57
+ additive: ISchemaGap[];
58
+ /**
59
+ * Colonnes manquantes et OBLIGATOIRES — jamais rattrapées : les poser
60
+ * exigerait d'inventer une valeur pour les lignes existantes, ce qui est une
61
+ * décision métier, pas une décision d'outil.
62
+ */
63
+ blocking: ISchemaGap[];
64
+ /** Tables entièrement absentes de la base. */
65
+ missingTables: string[];
66
+ }
67
+ /**
68
+ * Nomme ce qui manque, en trois mots plutôt qu'en trois lignes.
69
+ *
70
+ * Un refus qui dit « la base diverge » sans dire OÙ oblige à rouvrir un client
71
+ * SQL — c'est-à-dire exactement le geste que ces commandes existent pour éviter.
72
+ *
73
+ * Écrite ici parce qu'elle a DEUX lecteurs, et qu'ils doivent nommer l'écart de
74
+ * la même façon : l'adoption d'une base existante, et le générateur quand il
75
+ * n'a rien à écrire. Deux formulations pour un même fait apprendraient à leurs
76
+ * lecteurs qu'il s'agit de deux problèmes.
77
+ *
78
+ * @param c - les écarts, tels que la comparaison les rend.
79
+ * @returns une énumération courte, prête à entrer dans une phrase.
80
+ */
81
+ export declare function summarizeGap(c: ISchemaComparison): string;
82
+ /** La base s'écarte-t-elle du code ? */
83
+ export declare function hasGap(c: ISchemaComparison): boolean;
84
+ /** Le schéma attendu d'une table, tel que le code le déclare. */
85
+ export interface IExpectedTable {
86
+ table: string;
87
+ columns: IColumnInfo[];
88
+ }
89
+ /**
90
+ * Compare le schéma déclaré au schéma réel, table par table.
91
+ *
92
+ * Une requête par table, et **au démarrage uniquement** : rien de ceci n'existe
93
+ * dans le chemin d'une requête.
94
+ *
95
+ * @param reader - lecteur de catalogue du porteur (ORM connecté, ou pilote).
96
+ * @param expected - schéma attendu (cf `DrizzleOrm.describeTables`).
97
+ * @returns les écarts, séparés selon qu'ils se rattrapent ou non.
98
+ */
99
+ export declare function compareSchema(reader: ISchemaReader, expected: readonly IExpectedTable[]): Promise<ISchemaComparison>;
100
+ /**
101
+ * Le `ALTER TABLE` qui pose une colonne manquante.
102
+ *
103
+ * Aucune valeur par défaut n'est émise, et aucune contrainte : la colonne est
104
+ * ajoutée telle que le code la déclare, nullable. Ajouter un défaut ici
105
+ * reviendrait à inventer la donnée des lignes existantes.
106
+ *
107
+ * @param gap - la colonne manquante (elle DOIT accepter le vide).
108
+ * @param dialect - dialecte du connecteur.
109
+ * @returns le SQL, prêt à exécuter.
110
+ * @throws Error si l'on tente de rattraper une colonne obligatoire.
111
+ */
112
+ export declare function additiveSql(gap: ISchemaGap, dialect: SqlDialect): string;
@@ -0,0 +1,119 @@
1
+ import type { SqlDialect } from "../../config/config.js";
2
+ import { type IMigrationFile, type IMigrationSource } from "./types.js";
3
+ /**
4
+ * Version du journal drizzle-kit que cet applicateur sait lire.
5
+ *
6
+ * On adopte le format d'un outil tiers : le lire « au mieux » reviendrait à
7
+ * découvrir un défaut de découpe APRÈS publication, quand le corriger
8
+ * changerait le sens de fichiers déjà livrés chez des utilisateurs.
9
+ */
10
+ export declare const SUPPORTED_JOURNAL_VERSIONS: readonly string[];
11
+ /**
12
+ * Résultat du chargement d'un registre de sources.
13
+ *
14
+ * Les sources **absentes** ne sont pas une erreur : désinstaller un module ne
15
+ * doit pas bloquer la migration à jamais. Elles sont nommées ici pour que
16
+ * l'appelant puisse le DIRE, ce qui n'est pas la même chose que de s'arrêter.
17
+ */
18
+ export interface ILoadedSources {
19
+ /** Fichiers de toutes les sources présentes, dans l'ordre d'application. */
20
+ files: IMigrationFile[];
21
+ /** Noms des sources déclarées dont le dossier n'existe pas. */
22
+ absent: string[];
23
+ }
24
+ /**
25
+ * Ordonne un registre de sources : rang croissant, nom en départage.
26
+ *
27
+ * `framework` porte le rang 0 (les entités d'application peuvent référencer ses
28
+ * tables), `app` le rang le plus élevé. Entre les deux, les modules à leur
29
+ * ordre de chargement. Le nom départage à rang égal pour que l'ordre soit
30
+ * **déterministe** : deux pods qui liraient le même registre dans deux ordres
31
+ * différents appliqueraient deux plans différents.
32
+ *
33
+ * @param sources - registre, dans n'importe quel ordre.
34
+ * @returns le même registre, trié.
35
+ */
36
+ export declare function orderSources(sources: readonly IMigrationSource[]): IMigrationSource[];
37
+ /**
38
+ * Charge toutes les sources d'un registre pour un dialecte donné.
39
+ *
40
+ * @param sources - registre de sources (espace de noms ouvert).
41
+ * @param dialect - dialecte du connecteur ; sélectionne le sous-dossier.
42
+ * @returns les fichiers ordonnés et les sources absentes, nommées.
43
+ * @throws MigrationVerdictError si un fichier ne porte pas le format attendu.
44
+ */
45
+ export declare function loadSources(sources: readonly IMigrationSource[], dialect: SqlDialect): Promise<ILoadedSources>;
46
+ /**
47
+ * Découpe un fichier de migration en statements exécutables.
48
+ *
49
+ * ## Le séparateur EST un commentaire SQL — et c'est tout le problème
50
+ *
51
+ * `--> statement-breakpoint` commence par deux tirets : pour le moteur, c'est
52
+ * un commentaire, et rien ne le distingue d'un autre à l'œil nu. Deux ordres
53
+ * naïfs échouent donc, chacun pour sa raison, et les deux ont été constatés :
54
+ *
55
+ * - **découper puis retirer les commentaires** fait d'un séparateur écrit DANS
56
+ * un commentaire un vrai séparateur. La ligne est coupée en deux, et le
57
+ * fragment de droite — qui ne commence plus par deux tirets — part au pilote
58
+ * comme une instruction. Le produit se le faisait à lui-même : le gabarit
59
+ * qu'écrit `orm:generate --custom` porte la phrase qui NOMME le séparateur,
60
+ * si bien que toute migration libre écrite en suivant son aide échouait sur
61
+ * une erreur de syntaxe, en laissant dans l'historique une migration `failed`
62
+ * — c'est-à-dire une base bloquée, à réparer à la main ;
63
+ * - **retirer les commentaires puis découper** emporte les séparateurs
64
+ * eux-mêmes, et fond toutes les instructions du fichier en une seule.
65
+ *
66
+ * Il n'y a donc pas d'ordre à trouver : les deux décisions se prennent au MÊME
67
+ * moment, ligne par ligne, en sachant si l'on est dans une chaîne littérale.
68
+ * Un commentaire ne peut pas ouvrir un commentaire : dès que la ligne commence
69
+ * par deux tirets sans être le séparateur, tout ce qu'elle porte est du texte.
70
+ *
71
+ * Le séparateur n'est pas reconnu « ligne entière » pour autant : drizzle-kit
72
+ * le colle en fin d'instruction (`CREATE INDEX …;--> statement-breakpoint`), et
73
+ * l'exiger seul sur sa ligne ferait fusionner toutes les instructions d'une
74
+ * migration du framework.
75
+ *
76
+ * ## La grammaire de chaîne est celle du MOTEUR, pas une moyenne des trois
77
+ *
78
+ * Savoir si l'on est dans une chaîne n'a pas la même réponse partout : MySQL
79
+ * échappe l'apostrophe par une contre-oblique, PostgreSQL délimite les corps
80
+ * par `$tag$`. Une grammaire fausse ne lève AUCUNE erreur — le scanner croit
81
+ * sortir d'une chaîne où il est encore, la ligne suivante commençant par deux
82
+ * tirets est retirée comme un commentaire alors qu'elle est de la DONNÉE, ou
83
+ * un séparateur porté par un texte coupe l'instruction en deux. La migration
84
+ * s'inscrit ensuite en succès avec l'empreinte du fichier entier : plus aucun
85
+ * verdict ne peut le voir. Le dialecte est donc un paramètre REQUIS, jamais un
86
+ * défaut — le fichier vit déjà sous `<source>/<dialecte>/`, l'appelant l'a.
87
+ *
88
+ * @param normalized - contenu normalisé (fins de ligne en LF).
89
+ * @param dialect - dialecte du connecteur ; choisit la grammaire de chaîne.
90
+ * @returns les statements non vides, dans l'ordre du fichier.
91
+ */
92
+ export declare function splitStatements(normalized: string, dialect: SqlDialect): string[];
93
+ /**
94
+ * Noms des tables qu'un lot de migrations CRÉE.
95
+ *
96
+ * Sert la garde d'adoption : un historique vide alors que ces tables existent
97
+ * déjà signale une base antérieure aux migrations, pas une base neuve. La
98
+ * liste est DÉRIVÉE des fichiers — une liste codée en dur mentirait dès la
99
+ * première migration livrée par un module tiers.
100
+ *
101
+ * @param files - fichiers de migration chargés.
102
+ * @returns les noms de tables, sans doublon.
103
+ */
104
+ export declare function createdTables(files: readonly IMigrationFile[]): string[];
105
+ /**
106
+ * Tables que le FRAMEWORK construit — dérivées de ses fichiers de migration.
107
+ *
108
+ * Dérivées, jamais listées à la main : une liste codée en dur mentirait dès la
109
+ * première migration livrée par une version suivante.
110
+ *
111
+ * Une seule implémentation, parce que deux appelants en dépendent pour la même
112
+ * décision — le générateur les exclut de ce qu'il écrit, l'adoption les exclut
113
+ * de ce qu'elle lit. Deux copies divergeraient en silence, chacune verte dans
114
+ * son propre test.
115
+ *
116
+ * @param dialect - dialecte du connecteur visé.
117
+ * @returns les noms de tables du framework.
118
+ */
119
+ export declare function frameworkTables(dialect: SqlDialect): Promise<string[]>;
@@ -0,0 +1,132 @@
1
+ import type { Kernel } from "nodefony";
2
+ import type { IDrizzleConfig } from "../../interfaces/IDrizzleConfig.js";
3
+ import { MIGRATION_FORMAT_VERSION } from "./explain.js";
4
+ import type { IMigrationReport } from "./explain.js";
5
+ import type { IMigrationPlan } from "./types.js";
6
+ import type { IConnectorResolution } from "./resolve.js";
7
+ import type { ICommandFailure, IResolutionRefusal } from "./refusals.js";
8
+ /**
9
+ * L'état des migrations d'un connecteur, rendu en VALEUR — un producteur, deux
10
+ * portes.
11
+ *
12
+ * La ligne de commande et le plan d'administration de la console posent la même
13
+ * question et doivent recevoir le même objet. Le recalculer d'un côté — ne
14
+ * serait-ce que « à jour ou non » — ferait coexister deux vérités : l'écran
15
+ * dirait vert pendant que `orm:migrate:status` sortirait en 1, et c'est
16
+ * précisément le jour d'un déploiement raté qu'on s'en apercevrait.
17
+ *
18
+ * Ce module ne rend donc AUCUN verdict propre : il assemble ce que
19
+ * l'applicateur a calculé, et traduit les refus par la prose unique de
20
+ * {@link describeResolutionRefusal}.
21
+ */
22
+ /** Le plan avec son SQL, ou le refus. */
23
+ export type IMigrationPlanResult = {
24
+ ok: true;
25
+ plan: IMigrationPlanPayload;
26
+ } | {
27
+ ok: false;
28
+ failure: ICommandFailure;
29
+ };
30
+ /** Ce qui s'appliquerait, avec le SQL de chaque migration en attente. */
31
+ export interface IMigrationPlanPayload {
32
+ formatVersion: typeof MIGRATION_FORMAT_VERSION;
33
+ connector: string;
34
+ pending: {
35
+ source: string;
36
+ tag: string;
37
+ statements: string[];
38
+ }[];
39
+ }
40
+ /** Ce qu'une application a fait, ou le refus. */
41
+ export type IMigrationApplyResult = {
42
+ ok: true;
43
+ run: IMigrationRunPayload;
44
+ } | {
45
+ ok: false;
46
+ failure: ICommandFailure;
47
+ };
48
+ /** Le compte rendu d'une application. */
49
+ export interface IMigrationRunPayload {
50
+ formatVersion: typeof MIGRATION_FORMAT_VERSION;
51
+ connector: string;
52
+ runId: string;
53
+ applied: {
54
+ source: string;
55
+ tag: string;
56
+ executionMs: number;
57
+ }[];
58
+ }
59
+ /** Le rapport, ou le refus — jamais les deux, jamais rien. */
60
+ export type IMigrationStatusResult = {
61
+ ok: true;
62
+ report: IMigrationReport;
63
+ } | {
64
+ ok: false;
65
+ failure: ICommandFailure;
66
+ };
67
+ /**
68
+ * Habille un refus en charge utile publiée — la MÊME que celle de `--json`.
69
+ *
70
+ * @param connector - connecteur demandé.
71
+ * @param refusal - ce qu'il y a à en dire.
72
+ * @returns la charge utile d'arrêt.
73
+ */
74
+ export declare function failureFrom(connector: string, refusal: IResolutionRefusal): ICommandFailure;
75
+ /**
76
+ * Compose la charge utile d'un état — le SEUL endroit où le contexte du rendu
77
+ * est assemblé.
78
+ *
79
+ * Les quatre commandes de migration ET le plan d'administration publient le
80
+ * même objet ; recopier son assemblage les faisait déjà diverger d'un champ à
81
+ * l'autre, et le prochain consommateur à naître aurait oublié celui du jour.
82
+ * La troisième source ne se paie qu'ici, une fois : `describeDivergence`
83
+ * s'abstient toute seule quand le verdict est déjà décidé.
84
+ *
85
+ * @param plan - plan calculé par l'applicateur, en lecture seule.
86
+ * @param resolution - connecteur prêt (porte le mode de schéma effectif).
87
+ * @param config - configuration validée du module.
88
+ * @param kernel - kernel courant, pour constater l'environnement.
89
+ * @returns la charge utile, prête pour `--json` comme pour l'écran.
90
+ */
91
+ export declare function composeReport(plan: IMigrationPlan, resolution: Extract<IConnectorResolution, {
92
+ kind: "ready";
93
+ }>, config: IDrizzleConfig, kernel: Kernel | null): Promise<IMigrationReport>;
94
+ /**
95
+ * Lit l'état des migrations d'un connecteur, sans rien appliquer.
96
+ *
97
+ * @param wanted - connecteur demandé (`default` quand rien n'est précisé).
98
+ * @param config - configuration validée du module, `null` s'il n'est pas chargé.
99
+ * @param kernel - kernel courant.
100
+ * @returns l'état, ou le refus qui explique pourquoi il n'y en a pas.
101
+ */
102
+ export declare function migrationStatusFor(wanted: string, config: IDrizzleConfig | null, kernel: Kernel | null): Promise<IMigrationStatusResult>;
103
+ /**
104
+ * Ce qui S'APPLIQUERAIT, avec son SQL — lecture seule.
105
+ *
106
+ * Sert la confirmation d'un geste d'application : une modification de schéma
107
+ * ne se confirme pas sur une promesse, elle se confirme sur les instructions
108
+ * qui vont être exécutées.
109
+ *
110
+ * @param wanted - connecteur demandé.
111
+ * @param config - configuration validée du module, `null` s'il n'est pas chargé.
112
+ * @param kernel - kernel courant.
113
+ * @returns le plan, ou le refus.
114
+ */
115
+ export declare function migrationPlanFor(wanted: string, config: IDrizzleConfig | null, kernel: Kernel | null): Promise<IMigrationPlanResult>;
116
+ /**
117
+ * Applique les migrations en attente — **DÉVELOPPEMENT seulement**.
118
+ *
119
+ * 🔴 Le refus hors développement n'est pas une précaution d'interface, c'est la
120
+ * doctrine : en production, les migrations s'appliquent dans un travail
121
+ * d'orchestrateur qui se termine AVANT que le premier nouvel exemplaire ne
122
+ * démarre. Les appliquer au clic de quelqu'un qui regarde une console pendant
123
+ * que le trafic passe, c'est modifier un schéma sous les pieds des exemplaires
124
+ * en service. La garde vit ICI, dans le produit — jamais dans l'écran, qui ne
125
+ * protège que celui qui le regarde.
126
+ *
127
+ * @param wanted - connecteur demandé.
128
+ * @param config - configuration validée du module, `null` s'il n'est pas chargé.
129
+ * @param kernel - kernel courant.
130
+ * @returns ce qui a été appliqué, ou le refus.
131
+ */
132
+ export declare function applyMigrationsFor(wanted: string, config: IDrizzleConfig | null, kernel: Kernel | null): Promise<IMigrationApplyResult>;