@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,9 @@
1
+ //#region \0@oxc-project+runtime@0.148.0/helpers/esm/decorate.js
2
+ function __decorate(decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ }
8
+ //#endregion
9
+ export { __decorate as default };
@@ -0,0 +1,6 @@
1
+ //#region \0@oxc-project+runtime@0.148.0/helpers/esm/decorateMetadata.js
2
+ function __decorateMetadata(k, v) {
3
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4
+ }
5
+ //#endregion
6
+ export { __decorateMetadata as default };
package/dist/index.js ADDED
@@ -0,0 +1,105 @@
1
+ import config, { DDL_MODES, DIVERGENCE_MODES, MIGRATION_CHECK_MODES, drizzleConfigSchema } from "./nodefony/config/config.js";
2
+ import { defineDrizzleConfig, drizzleConfigJsonSchema } from "./nodefony/config/defineModuleConfig.js";
3
+ import { FORMAT_MARKER, HISTORY_TABLE, MIGRATE_URL_ENV, MigrationVerdictError } from "./nodefony/src/migrator/types.js";
4
+ import { EXIT, MIGRATION_FORMAT_VERSION, action, buildReport, exitCodeOf, meaningOf, renderRefusal, renderStatus, styleFor, verdictOf } from "./nodefony/src/migrator/explain.js";
5
+ import { MYSQL_LOCK_NAME_SQL } from "./nodefony/src/migrator/drivers/mysqlDriver.js";
6
+ import { PG_LOCK_KEY } from "./nodefony/src/migrator/drivers/postgresDriver.js";
7
+ import { openMigrationDriver } from "./nodefony/src/migrator/drivers/index.js";
8
+ import { APP_RANK, APP_SOURCE, FRAMEWORK_RANK, FRAMEWORK_SOURCE, defaultMigrationSources, frameworkMigrationsDir } from "./nodefony/src/migrator/paths.js";
9
+ import { migrationHash } from "./nodefony/src/migrator/hash.js";
10
+ import { loadSources, orderSources } from "./nodefony/src/migrator/sources.js";
11
+ import { DEFAULT_LOCK_TIMEOUT_MS, DrizzleMigrator } from "./nodefony/src/migrator/DrizzleMigrator.js";
12
+ import { appMigrationsDir, buildMigrator, knownConnectors, readMigrationEnv, resetAllowed, resolveCheckMode, resolveConnector, resolveDdlMode, resolveDivergenceMode } from "./nodefony/src/migrator/resolve.js";
13
+ import { DrizzleRepository } from "./nodefony/src/orm-core/DrizzleRepository.js";
14
+ import { DrizzleTransaction } from "./nodefony/src/orm-core/DrizzleTransaction.js";
15
+ import { DrizzleOrm } from "./nodefony/src/orm-core/DrizzleOrm.js";
16
+ import "./nodefony/src/orm-core/index.js";
17
+ import DrizzleService from "./nodefony/service/DrizzleService.js";
18
+ import { TOKEN_ENTITY_NAMES, accessTokenTable, createAccessTokenTable, createDeniedJtiTable, createSubjectRevocationTable, createTokenEntities, deniedJtiTable, registerTokenEntities, subjectRevocationTable } from "./nodefony/entity/tokenEntity.js";
19
+ import { AUDIT_ENTITY_NAMES, auditEventTable, createAuditEntities, createAuditEventTable, registerAuditEntities } from "./nodefony/entity/auditEventEntity.js";
20
+ import { WEBAUTHN_CREDENTIAL_ENTITY, createWebAuthnCredentialEntity, createWebAuthnCredentialTable, registerWebAuthnCredentialEntity, webAuthnCredentialTable } from "./nodefony/entity/webAuthnCredentialEntity.js";
21
+ import { TOTP_SECRET_ENTITY, createTotpSecretEntity, createTotpSecretTable, registerTotpSecretEntity, totpSecretTable } from "./nodefony/entity/totpSecretEntity.js";
22
+ import { WEBHOOK_ENDPOINT_ENTITY, createWebhookEndpointEntity, createWebhookEndpointTable, registerWebhookEndpointEntity, webhookEndpointTable } from "./nodefony/entity/webhookEndpointEntity.js";
23
+ import { IDEMPOTENCY_ENTITY_NAME, createIdempotencyEntities, createIdempotencyTable, idempotencyKeyTable, registerIdempotencyEntities } from "./nodefony/entity/idempotencyEntity.js";
24
+ import { SESSION_CONNECTOR, SESSION_ENTITY_NAME, createSessionEntity, createSessionTable, registerSessionEntity, sessionTable } from "./nodefony/entity/sessionEntity.js";
25
+ import { createUserEntity, createUserTable, registerUserEntity, userTable } from "./nodefony/entity/userTable.js";
26
+ import { DrizzleTokenStore } from "./nodefony/src/DrizzleTokenStore.js";
27
+ import { DrizzleAuditStore } from "./nodefony/src/DrizzleAuditStore.js";
28
+ import { DrizzleWebAuthnCredentialStore } from "./nodefony/src/DrizzleWebAuthnCredentialStore.js";
29
+ import { DrizzleTotpSecretStore } from "./nodefony/src/DrizzleTotpSecretStore.js";
30
+ import { DrizzleWebhookStore } from "./nodefony/src/DrizzleWebhookStore.js";
31
+ import { DrizzleIdempotencyStore } from "./nodefony/src/DrizzleIdempotencyStore.js";
32
+ import { FRAMEWORK_CONNECTOR, isFrameworkFallbackEntity, registerDrizzleFrameworkStores } from "./nodefony/registerStores.js";
33
+ import OrmGenerate from "./nodefony/command/orm-generate.js";
34
+ import OrmMigrate from "./nodefony/command/orm-migrate.js";
35
+ import OrmMigrateStatus from "./nodefony/command/orm-migrate-status.js";
36
+ import OrmMigrateBaseline from "./nodefony/command/orm-migrate-baseline.js";
37
+ import OrmMigrateRepair from "./nodefony/command/orm-migrate-repair.js";
38
+ import OrmReset from "./nodefony/command/orm-reset.js";
39
+ import __decorateMetadata from "./_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/decorateMetadata.js";
40
+ import __decorate from "./_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/decorate.js";
41
+ import SessionStorage from "./nodefony/src/SessionStorage.js";
42
+ import "./nodefony/src/migrator/index.js";
43
+ import { DrizzleUserRepository } from "./nodefony/src/DrizzleUserRepository.js";
44
+ import { Kernel, Module, services } from "nodefony";
45
+ import { wireOrmAdminPlane } from "@nodefony/orm-core";
46
+ import { registerUserStore } from "@nodefony/user";
47
+ //#region index.ts
48
+ /**
49
+ * `@nodefony/drizzle` — module Drizzle ORM (driver `better-sqlite3`) sur
50
+ * `@nodefony/orm-core`.
51
+ *
52
+ * **Module bootable** : enregistré dans `@modules()`, son {@link DrizzleService}
53
+ * connecte au boot un {@link DrizzleOrm} par connecteur configuré (ORM par défaut
54
+ * SQL recommandé). Expose aussi les **classes adapter** (orm-core) pour un usage
55
+ * direct/banc-test. driver concret du socle multi-ORM (avec Mongoose) ; type-safe-first (a figé la forme des opérateurs riches, ADR-0003 #3).
56
+ */
57
+ let Drizzle = class Drizzle extends Module {
58
+ constructor(kernel) {
59
+ super("drizzle", kernel, import.meta.url, config);
60
+ this.addCommand(OrmGenerate);
61
+ this.addCommand(OrmMigrate);
62
+ this.addCommand(OrmMigrateStatus);
63
+ this.addCommand(OrmMigrateBaseline);
64
+ this.addCommand(OrmMigrateRepair);
65
+ this.addCommand(OrmReset);
66
+ }
67
+ /** JSON Schema de la config drizzle → data plane admin (config riche Studio). */
68
+ configSchema() {
69
+ return drizzleConfigJsonSchema();
70
+ }
71
+ /**
72
+ * Valide la config (défauts + `module.options` + surcharge env) au boot via
73
+ * `defineDrizzleConfig`, et l'expose au container sous `drizzleConfig` pour que
74
+ * le `DrizzleService` la consomme. Plante propre si la config est invalide
75
+ * (convention Zod, alignée sur `@nodefony/mongoose` — audit config ORM 2026-06).
76
+ */
77
+ async onKernelRegister() {
78
+ const validated = defineDrizzleConfig(this.options ?? {});
79
+ this.options = validated;
80
+ registerUserStore("drizzle");
81
+ if (validated.frameworkEntities !== false) {
82
+ const dialect = validated.connectors?.default?.dialect ?? "sqlite";
83
+ const report = registerDrizzleFrameworkStores(dialect);
84
+ if (report.unported.length) this.log(`schéma framework : entités non portées sur "${dialect}" → stores drizzle indisponibles pour [${report.unported.join(", ")}] (chantier multi-dialecte Ph.2.1)`, "WARNING");
85
+ if (report.appOwned.length) this.log(`schéma framework : entités déjà enregistrées par l'app [${report.appOwned.join(", ")}] — auto-register respecte l'app`, "DEBUG");
86
+ if (report.registered.length) this.log(`schéma framework déclaré sur "${FRAMEWORK_CONNECTOR}" (${dialect}) : [${report.registered.join(", ")}]`, "DEBUG");
87
+ }
88
+ return this;
89
+ }
90
+ /**
91
+ * Monte le data plane ORM (`/nodefony/orm/api/*` + providers santé/flux pour la
92
+ * sonde cluster et le drill Studio) via {@link wireOrmAdminPlane}. Branchement
93
+ * GLOBAL (couvre tous les ORM) et idempotent — factorisé en orm-core (C5), chaque
94
+ * driver l'invoque à l'identique. orm-core étant une lib pure, c'est un module
95
+ * driver qui le déclenche (avant le `mountAll` de framework à `onKernelReady`).
96
+ */
97
+ async onKernelBoot() {
98
+ wireOrmAdminPlane(this.kernel);
99
+ return this;
100
+ }
101
+ };
102
+ Drizzle = __decorate([services([DrizzleService]), __decorateMetadata("design:paramtypes", [typeof Kernel === "undefined" ? Object : Kernel])], Drizzle);
103
+ var drizzle_default = Drizzle;
104
+ //#endregion
105
+ export { APP_RANK, APP_SOURCE, AUDIT_ENTITY_NAMES, DDL_MODES, DEFAULT_LOCK_TIMEOUT_MS, DIVERGENCE_MODES, DrizzleAuditStore, DrizzleIdempotencyStore, DrizzleMigrator, DrizzleOrm, DrizzleRepository, DrizzleService, DrizzleTokenStore, DrizzleTotpSecretStore, DrizzleTransaction, DrizzleUserRepository, DrizzleWebAuthnCredentialStore, DrizzleWebhookStore, EXIT, FORMAT_MARKER, FRAMEWORK_CONNECTOR, FRAMEWORK_RANK, FRAMEWORK_SOURCE, HISTORY_TABLE, IDEMPOTENCY_ENTITY_NAME, MIGRATE_URL_ENV, MIGRATION_CHECK_MODES, MIGRATION_FORMAT_VERSION, MYSQL_LOCK_NAME_SQL, MigrationVerdictError, PG_LOCK_KEY, SESSION_CONNECTOR, SESSION_ENTITY_NAME, SessionStorage, TOKEN_ENTITY_NAMES, TOTP_SECRET_ENTITY, WEBAUTHN_CREDENTIAL_ENTITY, WEBHOOK_ENDPOINT_ENTITY, accessTokenTable, action, appMigrationsDir, auditEventTable, buildMigrator, buildReport, createAccessTokenTable, createAuditEntities, createAuditEventTable, createDeniedJtiTable, createIdempotencyEntities, createIdempotencyTable, createSessionEntity, createSessionTable, createSubjectRevocationTable, createTokenEntities, createTotpSecretEntity, createTotpSecretTable, createUserEntity, createUserTable, createWebAuthnCredentialEntity, createWebAuthnCredentialTable, createWebhookEndpointEntity, createWebhookEndpointTable, drizzle_default as default, defaultMigrationSources, defineDrizzleConfig, deniedJtiTable, drizzleConfigJsonSchema, drizzleConfigSchema, exitCodeOf, frameworkMigrationsDir, idempotencyKeyTable, isFrameworkFallbackEntity, knownConnectors, loadSources, meaningOf, migrationHash, openMigrationDriver, orderSources, readMigrationEnv, registerAuditEntities, registerDrizzleFrameworkStores, registerIdempotencyEntities, registerSessionEntity, registerTokenEntities, registerTotpSecretEntity, registerUserEntity, registerWebAuthnCredentialEntity, registerWebhookEndpointEntity, renderRefusal, renderStatus, resetAllowed, resolveCheckMode, resolveConnector, resolveDdlMode, resolveDivergenceMode, sessionTable, styleFor, subjectRevocationTable, totpSecretTable, userTable, verdictOf, webAuthnCredentialTable, webhookEndpointTable };
@@ -0,0 +1,247 @@
1
+ import { HISTORY_TABLE, MigrationVerdictError } from "../src/migrator/types.js";
2
+ import { EXIT, action, describeDiscovery, refusalInMode, renderRefusal, styleFor } from "../src/migrator/explain.js";
3
+ import { missingHistoryColumn } from "../src/migrator/history.js";
4
+ import { buildMigrator, readMigrationEnv, resolveConnector } from "../src/migrator/resolve.js";
5
+ import { MigrationToolError, describeResolutionRefusal, moduleAbsent } from "../src/migrator/refusals.js";
6
+ import { composeReport } from "../src/migrator/status.js";
7
+ import { Command, resolveColorEnabled } from "nodefony";
8
+ //#region nodefony/command/migrateShared.ts
9
+ /**
10
+ * Socle commun des commandes `orm:*` — ce qui garantit qu'aucune d'elles ne
11
+ * laisse l'utilisateur, humain ou agent, devant une sortie muette.
12
+ *
13
+ * ## Les quatre garanties, et pourquoi elles vivent ICI
14
+ *
15
+ * 1. **Toute sortie porte un geste.** Succès, attente, refus ou panne : la
16
+ * commande écrit le fait, ce qu'il signifie, et la ligne exacte à copier.
17
+ * Écrites dans chaque commande, ces trois parties finiraient par manquer
18
+ * dans celle qu'on écrit un jour de fatigue — c'est justement celle qu'on
19
+ * rencontre en incident.
20
+ * 2. **`--json` est un flux PUR.** La sortie standard n'appartient qu'aux
21
+ * données : un objet, une ligne, rien d'autre. Y compris en échec — un agent
22
+ * qui a demandé du JSON doit pouvoir lire l'échec comme il lit le succès. Le
23
+ * journal du démarrage, lui, est déjà écarté vers la sortie d'erreur par le
24
+ * cœur, qui reconnaît `--json` dans les arguments avant même de brancher le
25
+ * journal.
26
+ * 3. **Aucune exception ne remonte nue.** Une pile d'appels n'est pas un
27
+ * message : elle ne dit ni ce qui s'est passé, ni quoi faire. Tout est
28
+ * rattrapé et traduit.
29
+ * 4. **La grille des codes de sortie est tenue en un seul endroit** — `0` à
30
+ * jour ou appliqué, `1` action requise, `2` la commande n'a pas pu faire son
31
+ * travail. Cette grille part chez l'utilisateur dans des passes
32
+ * d'intégration continue et des travaux de déploiement : la réaffecter plus
33
+ * tard casserait des contrôles qu'on ne voit pas.
34
+ */
35
+ /** Nom du module qui porte la configuration des connecteurs SQL. */
36
+ const MODULE_NAME = "drizzle";
37
+ /**
38
+ * Classe de base des commandes `orm:*`.
39
+ *
40
+ * Elle n'impose rien du verbe : chaque commande écrit son `generate`. Elle
41
+ * impose la FORME de ce qui sort, parce que c'est cette forme qui fait la
42
+ * différence entre un outil qu'on sait utiliser et un outil qu'on subit.
43
+ */
44
+ var OrmMigrateCommand = class extends Command {
45
+ /**
46
+ * Faut-il colorer la sortie ?
47
+ *
48
+ * 🔴 La question n'est PAS « est-ce un terminal ? », et la confondre avec ça
49
+ * a deux conséquences que personne ne signale :
50
+ *
51
+ * - **`NO_COLOR` est ignoré.** C'est une convention publique
52
+ * (no-color.org) qu'un utilisateur pose une fois pour toutes ses commandes ;
53
+ * la manquer rend une sortie illisible sur un terminal à palette
54
+ * inhabituelle, et le framework passe pour cassé.
55
+ * - **`FORCE_COLOR` est ignoré.** Sans lui, aucune sortie colorée n'est
56
+ * CAPTURABLE : ni dans un fichier, ni dans une passe d'intégration continue
57
+ * qui sait rendre les couleurs, ni dans un rapport de validation. On ne peut
58
+ * alors pas relire ce que l'exploitant voit vraiment.
59
+ *
60
+ * La règle vit au CŒUR (`resolveColorEnabled`), qui sert déjà les journaux :
61
+ * la réécrire ici en ferait une SECONDE implémentation, et les deux
62
+ * divergeraient — le journal obéirait à `NO_COLOR`, la commande non.
63
+ */
64
+ get tty() {
65
+ return resolveColorEnabled(process.stdout.isTTY === true);
66
+ }
67
+ /** Mise en forme, neutralisée hors terminal. */
68
+ get style() {
69
+ return styleFor(this.tty);
70
+ }
71
+ /**
72
+ * Configuration validée du module qui porte les connecteurs SQL.
73
+ *
74
+ * @returns la configuration, ou `null` si le module n'est pas chargé.
75
+ */
76
+ drizzleConfig() {
77
+ const mod = (this.kernel?.modules)?.[MODULE_NAME];
78
+ return mod ? mod.config : null;
79
+ }
80
+ /**
81
+ * Écrit une charge utile sur la sortie standard et pose le code de sortie.
82
+ *
83
+ * `process.exitCode` et jamais `process.exit()` : couper le processus laisse
84
+ * la sortie standard non vidée, et un `| jq` reçoit alors un objet tronqué —
85
+ * un échec qui ressemble à un défaut de la commande.
86
+ *
87
+ * @param payload - l'objet, en mode machine.
88
+ * @param human - le texte, en mode humain.
89
+ * @param exitCode - `0`, `1` ou `2`.
90
+ * @param json - la commande a-t-elle reçu `--json` ?
91
+ */
92
+ respond(payload, human, exitCode, json) {
93
+ if (json === true) process.stdout.write(`${JSON.stringify(payload)}\n`);
94
+ else process.stdout.write(human.endsWith("\n") ? human : `${human}\n`);
95
+ if (exitCode !== 0) process.exitCode = exitCode;
96
+ }
97
+ /**
98
+ * Arrête la commande en disant le fait, la cause et le geste.
99
+ *
100
+ * @param connector - connecteur concerné (ou le nom demandé).
101
+ * @param code - code d'arrêt stable, lu par les machines.
102
+ * @param summary - le fait, en français.
103
+ * @param meaning - ce que ça veut dire.
104
+ * @param actions - les commandes exactes à copier.
105
+ * @param json - la commande a-t-elle reçu `--json` ?
106
+ * @param exitCode - `2` par défaut : la commande n'a pas pu travailler.
107
+ * @param discovery - ce que la découverte des entités a vu, quand le refus
108
+ * peut avoir pour cause un schéma déclaré amputé.
109
+ */
110
+ fail(connector, code, summary, meaning, actions, json, exitCode = EXIT.error, discovery) {
111
+ const style = this.style;
112
+ const payload = {
113
+ formatVersion: 1,
114
+ connector,
115
+ exitCode,
116
+ error: {
117
+ code,
118
+ summary,
119
+ meaning,
120
+ nextActions: actions,
121
+ ...discovery ? { discovery } : {}
122
+ }
123
+ };
124
+ let human = `${style.red(style.bold("Impossible"))} ${style.dim(`[${code}]`)}\n\n${summary}\n`;
125
+ if (meaning) human += `\n${style.dim(meaning)}\n`;
126
+ if (discovery) human += describeDiscovery(discovery, style);
127
+ if (actions.length > 0) {
128
+ human += `\n${style.bold("À faire :")}\n`;
129
+ for (const a of actions) human += ` ${style.green(a.command)}\n`;
130
+ }
131
+ if (json === true) process.stdout.write(`${JSON.stringify(payload)}\n`);
132
+ else process.stderr.write(human);
133
+ process.exitCode = exitCode;
134
+ }
135
+ /**
136
+ * Résout le connecteur demandé, ou ARRÊTE la commande en le disant.
137
+ *
138
+ * Les **trois** réponses sont un contrat public, et elles restent distinctes :
139
+ * un connecteur inconnu, un connecteur porté par un ORM sans migrations, un
140
+ * connecteur prêt. Le jour où un second ORM apporte ses propres migrations,
141
+ * seule la deuxième cesse de sortir pour ses connecteurs — répondre « ne
142
+ * porte pas de migrations » à un connecteur qui en porte serait un message
143
+ * FAUX, et un message faux publié est appris par les scripts qui le lisent.
144
+ *
145
+ * @param opts - options de la commande (connecteur, mode machine).
146
+ * @param allowMigrateUrl - la commande honore-t-elle {@link MIGRATE_URL_ENV} ?
147
+ * @returns le connecteur prêt, ou `null` si la commande est déjà arrêtée.
148
+ */
149
+ resolveOrFail(opts, allowMigrateUrl) {
150
+ const wanted = opts.connector ?? "default";
151
+ const config = this.drizzleConfig();
152
+ if (!config) {
153
+ const refusal = moduleAbsent();
154
+ this.fail(wanted, refusal.code, refusal.summary, refusal.meaning, refusal.nextActions, opts.json, refusal.exitCode);
155
+ return null;
156
+ }
157
+ const resolution = resolveConnector(wanted, config, readMigrationEnv(this.kernel), this.kernel, { allowMigrateUrl });
158
+ if (resolution.kind !== "ready") {
159
+ const refusal = describeResolutionRefusal(wanted, resolution, config);
160
+ this.fail(wanted, refusal.code, refusal.summary, refusal.meaning, refusal.nextActions, opts.json, refusal.exitCode);
161
+ return null;
162
+ }
163
+ return {
164
+ resolution,
165
+ config
166
+ };
167
+ }
168
+ /**
169
+ * Construit l'applicateur d'un connecteur résolu.
170
+ *
171
+ * @param resolution - connecteur prêt.
172
+ * @param config - configuration validée.
173
+ * @returns l'applicateur, sources chargées.
174
+ */
175
+ async migrator(resolution, config) {
176
+ return buildMigrator(resolution, config, this.kernel);
177
+ }
178
+ /**
179
+ * Compose la charge utile d'un état.
180
+ *
181
+ * L'assemblage lui-même vit dans `migrator/status.ts` : le plan
182
+ * d'administration publie le MÊME objet, et deux assemblages divergeaient
183
+ * d'un champ à l'autre sans qu'aucun test ne le voie.
184
+ *
185
+ * @param plan - plan calculé par l'applicateur, en lecture seule.
186
+ * @param resolution - connecteur prêt (porte le mode de schéma effectif).
187
+ * @param config - configuration validée du module.
188
+ * @returns la charge utile, prête pour `--json` comme pour l'écran.
189
+ */
190
+ async report(plan, resolution, config) {
191
+ return composeReport(plan, resolution, config, this.kernel);
192
+ }
193
+ failFrom(e, connector, json, ddl) {
194
+ if (e instanceof MigrationVerdictError) {
195
+ const style = this.style;
196
+ const enMode = ddl ? refusalInMode(e.verdict.code, ddl, connector) : null;
197
+ const payload = {
198
+ formatVersion: 1,
199
+ connector,
200
+ exitCode: e.verdict.code === "NF_MIGRATE_LOCK_TIMEOUT" ? EXIT.error : EXIT.actionRequired,
201
+ error: {
202
+ code: e.verdict.code,
203
+ summary: e.message,
204
+ meaning: enMode?.meaning ?? "",
205
+ nextActions: enMode?.actions ?? [...e.verdict.nextActions]
206
+ }
207
+ };
208
+ if (json === true) process.stdout.write(`${JSON.stringify(payload)}\n`);
209
+ else process.stderr.write(renderRefusal(e.verdict, e.message, style, ddl));
210
+ process.exitCode = payload.exitCode;
211
+ return;
212
+ }
213
+ if (e instanceof MigrationToolError) {
214
+ const { code, summary, meaning, nextActions, exitCode } = e.refusal;
215
+ this.fail(connector, code, summary, meaning, nextActions, json, exitCode);
216
+ return;
217
+ }
218
+ const cause = e instanceof Error ? e.message : String(e);
219
+ const column = missingHistoryColumn(cause);
220
+ if (column !== null) {
221
+ this.fail(connector, "NF_MIGRATE_HISTORY_FOREIGN", `La table « ${HISTORY_TABLE} » de cette base n'est pas celle du framework : la colonne « ${column} » y manque. Rien n'a été appliqué.`, `Une table de ce nom existe déjà, avec d'autres colonnes — le framework ne la remplace jamais, et ne peut pas la lire. Deux provenances, deux gestes. Base d'ESSAI fabriquée à la main : ne pas écrire l'historique soi-même, mais COPIER la base d'origine (le fichier en sqlite, un export « pg_dump » / « mysqldump » ailleurs) — c'est cette copie qui porte déjà le bon historique. Base RÉELLE venue d'un autre outil de migration : la table porte le même nom par coïncidence ; la renommer, ou faire porter le framework sur une autre base. Dans tous les cas la base n'est PAS en cause : elle a répondu, et ce n'est pas une question de droits.`, [action("nodefony orm:migrate:status --json"), action("nodefony inspect config --json")], json, EXIT.actionRequired);
222
+ return;
223
+ }
224
+ this.fail(connector, "NF_MIGRATE_UNAVAILABLE", `La commande n'a pas pu travailler sur le connecteur « ${connector} » : ${cause}`, "La commande s'est arrêtée sans avoir pu nommer la cause. Les deux explications les plus fréquentes : la base n'a pas répondu, ou le compte utilisé n'a pas les droits nécessaires — celui qui migre a besoin de pouvoir créer et modifier des tables, ce que le compte qui sert le trafic n'a normalement pas. Avant de reprendre, CONSTATER l'état : `orm:migrate:status` dit ce que la base porte et ce que l'historique en dit.", [action("nodefony orm:migrate:status --json"), action("nodefony inspect config --json")], json);
225
+ }
226
+ /**
227
+ * Écrit un état lu et pose son code de sortie.
228
+ *
229
+ * @param report - charge utile complète.
230
+ * @param human - rendu humain déjà composé.
231
+ * @param json - la commande a-t-elle reçu `--json` ?
232
+ */
233
+ emitReport(report, human, json) {
234
+ this.respond(report, human, report.exitCode, json);
235
+ }
236
+ /** Déclare les deux options que toutes les commandes de migration portent. */
237
+ addSharedOptions() {
238
+ this.addOption("-c, --connector <nom>", "connecteur SQL visé (défaut : default) — c'est une clé de `connectors` dans la configuration");
239
+ this.addOption("-j, --json", "sortie machine : un objet sur la sortie standard, le journal sur la sortie d'erreur (`| jq` sûr)");
240
+ }
241
+ /** Le CLI courant, typé — utilisé pour les réglages de boot silencieux. */
242
+ get cliKernel() {
243
+ return this.cli;
244
+ }
245
+ };
246
+ //#endregion
247
+ export { OrmMigrateCommand };