@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.
- package/LICENSE +544 -0
- package/README.md +162 -0
- package/dist/_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/decorate.js +9 -0
- package/dist/_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/decorateMetadata.js +6 -0
- package/dist/index.js +105 -0
- package/dist/nodefony/command/migrateShared.js +247 -0
- package/dist/nodefony/command/orm-generate.js +356 -0
- package/dist/nodefony/command/orm-migrate-baseline.js +208 -0
- package/dist/nodefony/command/orm-migrate-repair.js +114 -0
- package/dist/nodefony/command/orm-migrate-status.js +67 -0
- package/dist/nodefony/command/orm-migrate.js +141 -0
- package/dist/nodefony/command/orm-reset.js +166 -0
- package/dist/nodefony/config/config.js +107 -0
- package/dist/nodefony/config/defineModuleConfig.js +63 -0
- package/dist/nodefony/entity/auditEventEntity.js +93 -0
- package/dist/nodefony/entity/colKit.js +260 -0
- package/dist/nodefony/entity/idempotencyEntity.js +74 -0
- package/dist/nodefony/entity/sessionEntity.js +75 -0
- package/dist/nodefony/entity/tokenEntity.js +198 -0
- package/dist/nodefony/entity/totpSecretEntity.js +98 -0
- package/dist/nodefony/entity/userTable.js +141 -0
- package/dist/nodefony/entity/webAuthnCredentialEntity.js +114 -0
- package/dist/nodefony/entity/webhookEndpointEntity.js +106 -0
- package/dist/nodefony/interfaces/IDrizzleConfig.js +1 -0
- package/dist/nodefony/interfaces/index.js +1 -0
- package/dist/nodefony/migrations-schema/mysql.js +48 -0
- package/dist/nodefony/migrations-schema/postgres.js +48 -0
- package/dist/nodefony/migrations-schema/sqlite.js +48 -0
- package/dist/nodefony/registerStores.js +218 -0
- package/dist/nodefony/service/DrizzleService.js +282 -0
- package/dist/nodefony/src/DrizzleAuditStore.js +203 -0
- package/dist/nodefony/src/DrizzleIdempotencyStore.js +278 -0
- package/dist/nodefony/src/DrizzleTokenStore.js +244 -0
- package/dist/nodefony/src/DrizzleTotpSecretStore.js +151 -0
- package/dist/nodefony/src/DrizzleUserRepository.js +217 -0
- package/dist/nodefony/src/DrizzleWebAuthnCredentialStore.js +159 -0
- package/dist/nodefony/src/DrizzleWebhookStore.js +169 -0
- package/dist/nodefony/src/SessionStorage.js +259 -0
- package/dist/nodefony/src/connectorTarget.js +59 -0
- package/dist/nodefony/src/likeSql.js +50 -0
- package/dist/nodefony/src/migrator/DrizzleMigrator.js +775 -0
- package/dist/nodefony/src/migrator/adopt.js +553 -0
- package/dist/nodefony/src/migrator/appSchema.js +414 -0
- package/dist/nodefony/src/migrator/catalog.js +76 -0
- package/dist/nodefony/src/migrator/destructive.js +213 -0
- package/dist/nodefony/src/migrator/divergence.js +84 -0
- package/dist/nodefony/src/migrator/drivers/index.js +39 -0
- package/dist/nodefony/src/migrator/drivers/mysqlDriver.js +147 -0
- package/dist/nodefony/src/migrator/drivers/postgresDriver.js +151 -0
- package/dist/nodefony/src/migrator/drivers/sqliteDriver.js +121 -0
- package/dist/nodefony/src/migrator/explain.js +565 -0
- package/dist/nodefony/src/migrator/hash.js +47 -0
- package/dist/nodefony/src/migrator/history.js +219 -0
- package/dist/nodefony/src/migrator/index.js +16 -0
- package/dist/nodefony/src/migrator/kit.js +296 -0
- package/dist/nodefony/src/migrator/name.js +68 -0
- package/dist/nodefony/src/migrator/paths.js +88 -0
- package/dist/nodefony/src/migrator/refusals.js +143 -0
- package/dist/nodefony/src/migrator/resolve.js +281 -0
- package/dist/nodefony/src/migrator/schemaDiff.js +86 -0
- package/dist/nodefony/src/migrator/sources.js +419 -0
- package/dist/nodefony/src/migrator/status.js +231 -0
- package/dist/nodefony/src/migrator/types.js +91 -0
- package/dist/nodefony/src/orm-core/DrizzleOrm.js +1154 -0
- package/dist/nodefony/src/orm-core/DrizzleRepository.js +610 -0
- package/dist/nodefony/src/orm-core/DrizzleTransaction.js +106 -0
- package/dist/nodefony/src/orm-core/index.js +4 -0
- package/dist/nodefony/src/queryKit.js +318 -0
- package/dist/nodefony/src/safeTarget.js +55 -0
- package/dist/types/index.d.ts +76 -0
- package/dist/types/nodefony/command/migrateShared.d.ts +137 -0
- package/dist/types/nodefony/command/orm-generate.d.ts +53 -0
- package/dist/types/nodefony/command/orm-migrate-baseline.d.ts +87 -0
- package/dist/types/nodefony/command/orm-migrate-repair.d.ts +66 -0
- package/dist/types/nodefony/command/orm-migrate-status.d.ts +38 -0
- package/dist/types/nodefony/command/orm-migrate.d.ts +65 -0
- package/dist/types/nodefony/command/orm-reset.d.ts +55 -0
- package/dist/types/nodefony/config/config.d.ts +110 -0
- package/dist/types/nodefony/config/defineModuleConfig.d.ts +24 -0
- package/dist/types/nodefony/entity/auditEventEntity.d.ts +56 -0
- package/dist/types/nodefony/entity/colKit.d.ts +130 -0
- package/dist/types/nodefony/entity/idempotencyEntity.d.ts +52 -0
- package/dist/types/nodefony/entity/sessionEntity.d.ts +50 -0
- package/dist/types/nodefony/entity/tokenEntity.d.ts +53 -0
- package/dist/types/nodefony/entity/totpSecretEntity.d.ts +61 -0
- package/dist/types/nodefony/entity/userTable.d.ts +65 -0
- package/dist/types/nodefony/entity/webAuthnCredentialEntity.d.ts +57 -0
- package/dist/types/nodefony/entity/webhookEndpointEntity.d.ts +58 -0
- package/dist/types/nodefony/interfaces/IDrizzleConfig.d.ts +17 -0
- package/dist/types/nodefony/interfaces/index.d.ts +1 -0
- package/dist/types/nodefony/migrations-schema/mysql.d.ts +9 -0
- package/dist/types/nodefony/migrations-schema/postgres.d.ts +9 -0
- package/dist/types/nodefony/migrations-schema/sqlite.d.ts +9 -0
- package/dist/types/nodefony/registerStores.d.ts +52 -0
- package/dist/types/nodefony/service/DrizzleService.d.ts +27 -0
- package/dist/types/nodefony/src/DrizzleAuditStore.d.ts +65 -0
- package/dist/types/nodefony/src/DrizzleIdempotencyStore.d.ts +129 -0
- package/dist/types/nodefony/src/DrizzleTokenStore.d.ts +146 -0
- package/dist/types/nodefony/src/DrizzleTotpSecretStore.d.ts +60 -0
- package/dist/types/nodefony/src/DrizzleUserRepository.d.ts +67 -0
- package/dist/types/nodefony/src/DrizzleWebAuthnCredentialStore.d.ts +62 -0
- package/dist/types/nodefony/src/DrizzleWebhookStore.d.ts +79 -0
- package/dist/types/nodefony/src/SessionStorage.d.ts +72 -0
- package/dist/types/nodefony/src/connectorTarget.d.ts +48 -0
- package/dist/types/nodefony/src/likeSql.d.ts +29 -0
- package/dist/types/nodefony/src/migrator/DrizzleMigrator.d.ts +94 -0
- package/dist/types/nodefony/src/migrator/adopt.d.ts +280 -0
- package/dist/types/nodefony/src/migrator/appSchema.d.ts +223 -0
- package/dist/types/nodefony/src/migrator/catalog.d.ts +100 -0
- package/dist/types/nodefony/src/migrator/destructive.d.ts +123 -0
- package/dist/types/nodefony/src/migrator/divergence.d.ts +61 -0
- package/dist/types/nodefony/src/migrator/drivers/index.d.ts +26 -0
- package/dist/types/nodefony/src/migrator/drivers/mysqlDriver.d.ts +83 -0
- package/dist/types/nodefony/src/migrator/drivers/postgresDriver.d.ts +81 -0
- package/dist/types/nodefony/src/migrator/drivers/sqliteDriver.d.ts +53 -0
- package/dist/types/nodefony/src/migrator/explain.d.ts +424 -0
- package/dist/types/nodefony/src/migrator/hash.d.ts +39 -0
- package/dist/types/nodefony/src/migrator/history.d.ts +139 -0
- package/dist/types/nodefony/src/migrator/index.d.ts +20 -0
- package/dist/types/nodefony/src/migrator/kit.d.ts +141 -0
- package/dist/types/nodefony/src/migrator/name.d.ts +52 -0
- package/dist/types/nodefony/src/migrator/paths.d.ts +54 -0
- package/dist/types/nodefony/src/migrator/refusals.d.ts +170 -0
- package/dist/types/nodefony/src/migrator/resolve.d.ts +201 -0
- package/dist/types/nodefony/src/migrator/schemaDiff.d.ts +112 -0
- package/dist/types/nodefony/src/migrator/sources.d.ts +119 -0
- package/dist/types/nodefony/src/migrator/status.d.ts +132 -0
- package/dist/types/nodefony/src/migrator/types.d.ts +273 -0
- package/dist/types/nodefony/src/orm-core/DrizzleOrm.d.ts +241 -0
- package/dist/types/nodefony/src/orm-core/DrizzleRepository.d.ts +98 -0
- package/dist/types/nodefony/src/orm-core/DrizzleTransaction.d.ts +71 -0
- package/dist/types/nodefony/src/orm-core/index.d.ts +11 -0
- package/dist/types/nodefony/src/queryKit.d.ts +136 -0
- package/dist/types/nodefony/src/safeTarget.d.ts +42 -0
- package/docs/index.md +954 -0
- package/docs/migrations.md +691 -0
- package/migrations/mysql/0000_framework_init.sql +137 -0
- package/migrations/mysql/meta/_journal.json +13 -0
- package/migrations/postgres/0000_framework_init.sql +128 -0
- package/migrations/postgres/meta/_journal.json +13 -0
- package/migrations/sqlite/0000_framework_init.sql +127 -0
- package/migrations/sqlite/meta/_journal.json +13 -0
- package/package.json +126 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { createFrameworkTableFactory } from "./colKit.js";
|
|
2
|
+
import { entityRegistry } from "@nodefony/orm-core";
|
|
3
|
+
/**
|
|
4
|
+
* Factory de la table de secrets TOTP pour un dialecte donné (mémoïsée — une
|
|
5
|
+
* instance par dialecte). **Les trois dialectes sont portés** (`TOTP_PORTED =
|
|
6
|
+
* ALL_DIALECTS`, `registerStores.ts:92`) : sqlite, postgres et mysql.
|
|
7
|
+
*/
|
|
8
|
+
const createTotpSecretTable = createFrameworkTableFactory({
|
|
9
|
+
name: "totp_secret",
|
|
10
|
+
columns: {
|
|
11
|
+
/** Propriétaire du secret (clé naturelle — un seul secret par utilisateur). */
|
|
12
|
+
userId: {
|
|
13
|
+
kind: "text",
|
|
14
|
+
primaryKey: true
|
|
15
|
+
},
|
|
16
|
+
/** Secret partagé `K` **chiffré** (blob opaque `iv.tag.ciphertext` base64url). */
|
|
17
|
+
secretEnc: {
|
|
18
|
+
kind: "text",
|
|
19
|
+
notNull: true
|
|
20
|
+
},
|
|
21
|
+
/** Fonction HMAC du code (`SHA1`|`SHA256`|`SHA512`). */
|
|
22
|
+
algorithm: {
|
|
23
|
+
kind: "text",
|
|
24
|
+
notNull: true
|
|
25
|
+
},
|
|
26
|
+
/** Nombre de chiffres du code. */
|
|
27
|
+
digits: {
|
|
28
|
+
kind: "int",
|
|
29
|
+
notNull: true
|
|
30
|
+
},
|
|
31
|
+
/** Période d'un code en secondes. */
|
|
32
|
+
period: {
|
|
33
|
+
kind: "int",
|
|
34
|
+
notNull: true
|
|
35
|
+
},
|
|
36
|
+
/** Condensats `sha256` des codes de récupération non encore consommés. */
|
|
37
|
+
recoveryCodes: {
|
|
38
|
+
kind: "json",
|
|
39
|
+
notNull: true,
|
|
40
|
+
defaultFn: () => []
|
|
41
|
+
},
|
|
42
|
+
/** Confirmation de l'enrôlement (epoch ms) ou `null` (anti-lock-out). */
|
|
43
|
+
confirmedAt: { kind: "epochMs" },
|
|
44
|
+
/**
|
|
45
|
+
* Dernière tranche `T` validée (RFC 6238 §5.2, anti-rejeu) ou `null`.
|
|
46
|
+
*
|
|
47
|
+
* `int64` : `T = floor(epochSeconds / period)`, et `period` n'a pas de
|
|
48
|
+
* borne basse (schéma Zod : `positive()`). À `period` = 1 la tranche vaut
|
|
49
|
+
* l'horodatage Unix lui-même, qui dépasse l'entier 32 bits signé en 2038 —
|
|
50
|
+
* l'anti-rejeu cesserait alors de retenir, en silence.
|
|
51
|
+
*/
|
|
52
|
+
lastUsedStep: { kind: "int64" },
|
|
53
|
+
/** Création (epoch ms). */
|
|
54
|
+
createdAt: {
|
|
55
|
+
kind: "epochMs",
|
|
56
|
+
notNull: true
|
|
57
|
+
},
|
|
58
|
+
/** Dernier usage réussi (epoch ms) ou `null`. */
|
|
59
|
+
lastUsedAt: { kind: "epochMs" }
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
/**
|
|
63
|
+
* Variante SQLite de la table de secrets TOTP (dialecte par défaut) — export
|
|
64
|
+
* conservé pour l'usage direct/banc-test.
|
|
65
|
+
*/
|
|
66
|
+
const totpSecretTable = createTotpSecretTable("sqlite");
|
|
67
|
+
/** Nom logique de l'entité (clé de lookup `getRepository`). */
|
|
68
|
+
const TOTP_SECRET_ENTITY = "totp_secret";
|
|
69
|
+
/**
|
|
70
|
+
* Construit le descripteur d'entité du store de secrets TOTP pour un ORM nommé.
|
|
71
|
+
* Le `connector` est **dynamique** (nom du connecteur de l'app) et la variante de table
|
|
72
|
+
* suit le dialecte du connecteur (auto-register `registerStores.ts`). À enregistrer
|
|
73
|
+
* **avant** `orm.connect()`. `module: "security"` → regroupé sous @nodefony/security
|
|
74
|
+
* dans l'ERD Studio.
|
|
75
|
+
*
|
|
76
|
+
* @param orm - clé de l'ORM cible dans le `ormRegistry`.
|
|
77
|
+
* @param dialect - dialecte SQL du connecteur (sélectionne la variante de table).
|
|
78
|
+
*/
|
|
79
|
+
function createTotpSecretEntity(connector, dialect = "sqlite") {
|
|
80
|
+
return {
|
|
81
|
+
connector,
|
|
82
|
+
name: TOTP_SECRET_ENTITY,
|
|
83
|
+
module: "security",
|
|
84
|
+
schema: createTotpSecretTable(dialect)
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Enregistre l'entité du store de secrets TOTP dans le `entityRegistry` pour un ORM
|
|
89
|
+
* donné. À appeler **avant** `orm.connect()` (l'adapter crée la table au connect).
|
|
90
|
+
*
|
|
91
|
+
* @param connector - nom de la connexion cible (clé du registre).
|
|
92
|
+
* @param dialect - dialecte SQL du connecteur (variante de table — défaut `sqlite`).
|
|
93
|
+
*/
|
|
94
|
+
function registerTotpSecretEntity(connector, dialect = "sqlite") {
|
|
95
|
+
entityRegistry.register(createTotpSecretEntity(connector, dialect));
|
|
96
|
+
}
|
|
97
|
+
//#endregion
|
|
98
|
+
export { TOTP_SECRET_ENTITY, createTotpSecretEntity, createTotpSecretTable, registerTotpSecretEntity, totpSecretTable };
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { createFrameworkTableFactory } from "./colKit.js";
|
|
2
|
+
import { entityRegistry } from "@nodefony/orm-core";
|
|
3
|
+
import { USER_COLUMNS, USER_TABLE_NAME } from "@nodefony/user";
|
|
4
|
+
import { getTableConfig } from "drizzle-orm/sqlite-core";
|
|
5
|
+
import { getTableConfig as getTableConfig$1 } from "drizzle-orm/pg-core";
|
|
6
|
+
import { getTableConfig as getTableConfig$2 } from "drizzle-orm/mysql-core";
|
|
7
|
+
import { randomUUID } from "node:crypto";
|
|
8
|
+
//#region nodefony/entity/userTable.ts
|
|
9
|
+
/**
|
|
10
|
+
* Traduction d'un type LOGIQUE du contrat utilisateur vers le type du colKit.
|
|
11
|
+
*
|
|
12
|
+
* C'est le seul endroit du module SQL qui connaisse ce vocabulaire : le contrat
|
|
13
|
+
* dit ce que la donnée EST, le colKit dit comment chaque dialecte la range.
|
|
14
|
+
*/
|
|
15
|
+
const KIND_BY_TYPE = {
|
|
16
|
+
uuid: "text",
|
|
17
|
+
string: "text",
|
|
18
|
+
"string[]": "json",
|
|
19
|
+
boolean: "bool",
|
|
20
|
+
object: "json",
|
|
21
|
+
"object[]": "json",
|
|
22
|
+
date: "dateMs"
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Construit la spec colKit d'une colonne du contrat utilisateur.
|
|
26
|
+
*
|
|
27
|
+
* Les trois origines ne se déclarent pas pareil en SQL : la clé primaire reçoit
|
|
28
|
+
* l'UUID applicatif, un horodatage reçoit l'heure courante (et se régénère si le
|
|
29
|
+
* contrat le dit), une colonne ordinaire reçoit son défaut déclaré.
|
|
30
|
+
*
|
|
31
|
+
* ⚠️ Les défauts restent **JS-level** (`$defaultFn`) : le DDL dérivé n'émet pas
|
|
32
|
+
* de `DEFAULT` SQL (règle du colKit). Une valeur absente à l'insertion est donc
|
|
33
|
+
* comblée par le pilote, pas par le serveur.
|
|
34
|
+
*/
|
|
35
|
+
function toColSpec(column) {
|
|
36
|
+
const kind = KIND_BY_TYPE[column.type];
|
|
37
|
+
switch (column.origin) {
|
|
38
|
+
case "identity": return {
|
|
39
|
+
kind,
|
|
40
|
+
primaryKey: true,
|
|
41
|
+
defaultFn: () => randomUUID()
|
|
42
|
+
};
|
|
43
|
+
case "audit": return {
|
|
44
|
+
kind,
|
|
45
|
+
notNull: true,
|
|
46
|
+
defaultFn: () => /* @__PURE__ */ new Date(),
|
|
47
|
+
...column.refreshedOnWrite ? { onUpdateFn: () => /* @__PURE__ */ new Date() } : {}
|
|
48
|
+
};
|
|
49
|
+
case "column": return {
|
|
50
|
+
kind,
|
|
51
|
+
...column.nullable ? {} : { notNull: true },
|
|
52
|
+
...column.unique ? { unique: true } : {},
|
|
53
|
+
...column.makeDefault ? { defaultFn: column.makeDefault } : {}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Entité de l'utilisateur Nodefony (schema-as-code) — implémentation SQL
|
|
59
|
+
* **par défaut** du contrat `@nodefony/user`, **dérivée** de `USER_COLUMNS` et
|
|
60
|
+
* déclinée par le `colKit` : une spec logique, la table du dialecte du
|
|
61
|
+
* connecteur.
|
|
62
|
+
*
|
|
63
|
+
* Rien n'est recopié : les noms, les types logiques, les défauts et les
|
|
64
|
+
* contraintes viennent du contrat. Ce fichier ne décide que de la traduction
|
|
65
|
+
* vers SQL — ce qui est exactement ce qu'un adaptateur doit savoir, et rien de
|
|
66
|
+
* plus. Une colonne ajoutée au contrat apparaît donc ici sans qu'on y touche,
|
|
67
|
+
* et `tests/unit/userContractParity.test.ts` refuse le contraire.
|
|
68
|
+
*
|
|
69
|
+
* Les horodatages sont des colonnes EXPLICITES (kind `dateMs`, exposé `Date`) —
|
|
70
|
+
* à la différence de Mongoose, qui les gère au niveau du schéma.
|
|
71
|
+
*/
|
|
72
|
+
const USER_TABLE_SPEC = {
|
|
73
|
+
name: USER_TABLE_NAME,
|
|
74
|
+
columns: Object.fromEntries(USER_COLUMNS.map((column) => [column.name, toColSpec(column)]))
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Factory de la table `User` pour un dialecte donné (mémoïsée — une instance
|
|
78
|
+
* par dialecte). Les trois dialectes sont portés (`sqlite` par défaut).
|
|
79
|
+
*/
|
|
80
|
+
const createUserTable = createFrameworkTableFactory(USER_TABLE_SPEC);
|
|
81
|
+
/**
|
|
82
|
+
* Variante SQLite de la table `User` (dialecte par défaut) — export conservé
|
|
83
|
+
* pour l'usage direct/banc-test (ex. module mediasoup).
|
|
84
|
+
*/
|
|
85
|
+
const userTable = createUserTable("sqlite");
|
|
86
|
+
/**
|
|
87
|
+
* Construit le descripteur d'entité `User` Drizzle pour un ORM nommé.
|
|
88
|
+
*
|
|
89
|
+
* Le `connector` est **dynamique** (nom du connecteur de l'app, ex. `"default"`) et la
|
|
90
|
+
* variante de table suit le dialecte du connecteur (auto-register
|
|
91
|
+
* `registerStores.ts` à `onKernelRegister`). À enregistrer dans `entityRegistry`
|
|
92
|
+
* **avant** `orm.connect()` (cf {@link registerUserEntity}).
|
|
93
|
+
*
|
|
94
|
+
* @param orm - clé de l'ORM cible dans le `ormRegistry`.
|
|
95
|
+
* @param dialect - dialecte SQL du connecteur (sélectionne la variante de table).
|
|
96
|
+
* @returns descripteur {@link IEntity} (`name: "User"`).
|
|
97
|
+
*/
|
|
98
|
+
function createUserEntity(connector, dialect = "sqlite") {
|
|
99
|
+
return {
|
|
100
|
+
connector,
|
|
101
|
+
name: "User",
|
|
102
|
+
module: "user",
|
|
103
|
+
schema: createUserTable(dialect)
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Enregistre l'entité `User` Drizzle dans le `entityRegistry` pour un ORM donné.
|
|
108
|
+
* À appeler **avant** `orm.connect()` (l'adapter compile/crée les tables au connect).
|
|
109
|
+
*
|
|
110
|
+
* @param connector - nom de la connexion cible (clé du registre).
|
|
111
|
+
* @param dialect - dialecte SQL du connecteur (variante de table — défaut `sqlite`).
|
|
112
|
+
*/
|
|
113
|
+
function registerUserEntity(connector, dialect = "sqlite") {
|
|
114
|
+
entityRegistry.register(createUserEntity(connector, dialect));
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Colonnes d'une table Drizzle, lues dans la GRAMMAIRE de son dialecte.
|
|
118
|
+
*
|
|
119
|
+
* L'extraction n'a rien d'anodin : `getTableConfig` n'est pas la même fonction
|
|
120
|
+
* selon le dialecte, et la mauvaise appliquée à une table LÈVE un
|
|
121
|
+
* `TypeError: Cannot convert undefined or null to object` — mesuré sur les six
|
|
122
|
+
* croisements, aucun ne rend un objet vide ni un résultat partiel. La
|
|
123
|
+
* conséquence est la même dans les deux lectures qu'on pourrait en faire : un
|
|
124
|
+
* appelant qui ne route pas par dialecte n'obtient RIEN d'exploitable. D'où un
|
|
125
|
+
* seul point de lecture, partagé par le contrôle de démarrage et par le banc de
|
|
126
|
+
* parité — et un dialecte qui doit suivre l'entité jusqu'ici.
|
|
127
|
+
*
|
|
128
|
+
* @param table - la table Drizzle, telle que l'entité la rend (`schema`).
|
|
129
|
+
* @param dialect - dialecte du connecteur qui la porte.
|
|
130
|
+
* @returns les colonnes indexées par nom SQL.
|
|
131
|
+
*/
|
|
132
|
+
function userTableColumns(table, dialect) {
|
|
133
|
+
const columns = dialect === "postgres" ? getTableConfig$1(table).columns : dialect === "mysql" ? getTableConfig$2(table).columns : getTableConfig(table).columns;
|
|
134
|
+
return new Map(columns.map((column) => [column.name, {
|
|
135
|
+
notNull: column.notNull,
|
|
136
|
+
isUnique: column.isUnique ?? false,
|
|
137
|
+
primary: column.primary
|
|
138
|
+
}]));
|
|
139
|
+
}
|
|
140
|
+
//#endregion
|
|
141
|
+
export { createUserEntity, createUserTable, registerUserEntity, userTable, userTableColumns };
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { createFrameworkTableFactory } from "./colKit.js";
|
|
2
|
+
import { entityRegistry } from "@nodefony/orm-core";
|
|
3
|
+
/**
|
|
4
|
+
* Factory de la table de credentials pour un dialecte donné (mémoïsée — une
|
|
5
|
+
* instance par dialecte). `sqlite` (défaut) et `postgres` sont portés ;
|
|
6
|
+
* `mysql` jette (S4).
|
|
7
|
+
*/
|
|
8
|
+
const createWebAuthnCredentialTable = createFrameworkTableFactory({
|
|
9
|
+
name: "webauthn_credential",
|
|
10
|
+
columns: {
|
|
11
|
+
/** Identifiant du credential (base64url) — clé fournie par l'authenticator. */
|
|
12
|
+
id: {
|
|
13
|
+
kind: "text",
|
|
14
|
+
primaryKey: true
|
|
15
|
+
},
|
|
16
|
+
/** Propriétaire (sub / userHandle applicatif). */
|
|
17
|
+
userId: {
|
|
18
|
+
kind: "text",
|
|
19
|
+
notNull: true
|
|
20
|
+
},
|
|
21
|
+
/** Clé publique COSE encodée base64url. */
|
|
22
|
+
publicKey: {
|
|
23
|
+
kind: "text",
|
|
24
|
+
notNull: true
|
|
25
|
+
},
|
|
26
|
+
/**
|
|
27
|
+
* Compteur de signatures (anti-clone, §6.1.1).
|
|
28
|
+
*
|
|
29
|
+
* `int64` et non `int` : WebAuthn définit ce compteur comme un **uint32**
|
|
30
|
+
* (jusqu'à 4 294 967 295), qui déborde l'entier 32 bits SIGNÉ des trois
|
|
31
|
+
* dialectes. Un authenticator réel n'y arrivera pas, mais la valeur est
|
|
32
|
+
* fournie par le périphérique et rien ne la borne côté serveur.
|
|
33
|
+
*/
|
|
34
|
+
signCount: {
|
|
35
|
+
kind: "int64",
|
|
36
|
+
notNull: true
|
|
37
|
+
},
|
|
38
|
+
/** Transports annoncés (`usb`|`nfc`|`ble`|`internal`|`hybrid`). */
|
|
39
|
+
transports: {
|
|
40
|
+
kind: "json",
|
|
41
|
+
notNull: true,
|
|
42
|
+
defaultFn: () => []
|
|
43
|
+
},
|
|
44
|
+
/** BE flag (Backup Eligibility) — fixé à l'enregistrement. */
|
|
45
|
+
backupEligible: {
|
|
46
|
+
kind: "bool",
|
|
47
|
+
notNull: true
|
|
48
|
+
},
|
|
49
|
+
/** BS flag (Backup State) — peut évoluer. */
|
|
50
|
+
backupState: {
|
|
51
|
+
kind: "bool",
|
|
52
|
+
notNull: true
|
|
53
|
+
},
|
|
54
|
+
/** UV réalisée au moins une fois (base du step-up MFA). */
|
|
55
|
+
uvInitialized: {
|
|
56
|
+
kind: "bool",
|
|
57
|
+
notNull: true
|
|
58
|
+
},
|
|
59
|
+
/** Surnom choisi par l'utilisateur ; `null` = aucun. */
|
|
60
|
+
nickname: { kind: "text" },
|
|
61
|
+
/** Création (epoch ms). */
|
|
62
|
+
createdAt: {
|
|
63
|
+
kind: "epochMs",
|
|
64
|
+
notNull: true
|
|
65
|
+
},
|
|
66
|
+
/** Dernière authentification réussie (epoch ms) ou `null`. */
|
|
67
|
+
lastUsedAt: { kind: "epochMs" }
|
|
68
|
+
},
|
|
69
|
+
indexes: [{
|
|
70
|
+
name: "webauthn_credential_userId_idx",
|
|
71
|
+
on: ["userId"]
|
|
72
|
+
}]
|
|
73
|
+
});
|
|
74
|
+
/**
|
|
75
|
+
* Variante SQLite de la table de credentials (dialecte par défaut) — export
|
|
76
|
+
* conservé pour l'usage direct/banc-test.
|
|
77
|
+
*/
|
|
78
|
+
const webAuthnCredentialTable = createWebAuthnCredentialTable("sqlite");
|
|
79
|
+
/** Nom logique de l'entité (clé de lookup `getRepository`). */
|
|
80
|
+
const WEBAUTHN_CREDENTIAL_ENTITY = "webauthn_credential";
|
|
81
|
+
/**
|
|
82
|
+
* Construit le descripteur d'entité du store de credentials pour un ORM nommé.
|
|
83
|
+
*
|
|
84
|
+
* Le `connector` est **dynamique** (nom du connecteur de l'app, ex. `"default"`) et la
|
|
85
|
+
* variante de table suit le dialecte du connecteur (auto-register
|
|
86
|
+
* `registerStores.ts` à `onKernelRegister`). À enregistrer **avant**
|
|
87
|
+
* `orm.connect()` (cf {@link registerWebAuthnCredentialEntity}).
|
|
88
|
+
*
|
|
89
|
+
* `module: "security"` → la table est regroupée sous @nodefony/security dans l'ERD
|
|
90
|
+
* Studio (le store est une feature security, hébergée par l'ORM de l'app).
|
|
91
|
+
*
|
|
92
|
+
* @param orm - clé de l'ORM cible dans le `ormRegistry`.
|
|
93
|
+
* @param dialect - dialecte SQL du connecteur (sélectionne la variante de table).
|
|
94
|
+
*/
|
|
95
|
+
function createWebAuthnCredentialEntity(connector, dialect = "sqlite") {
|
|
96
|
+
return {
|
|
97
|
+
connector,
|
|
98
|
+
name: WEBAUTHN_CREDENTIAL_ENTITY,
|
|
99
|
+
module: "security",
|
|
100
|
+
schema: createWebAuthnCredentialTable(dialect)
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Enregistre l'entité du store de credentials dans le `entityRegistry` pour un
|
|
105
|
+
* ORM donné. À appeler **avant** `orm.connect()` (l'adapter crée la table au connect).
|
|
106
|
+
*
|
|
107
|
+
* @param connector - nom de la connexion cible (clé du registre).
|
|
108
|
+
* @param dialect - dialecte SQL du connecteur (variante de table — défaut `sqlite`).
|
|
109
|
+
*/
|
|
110
|
+
function registerWebAuthnCredentialEntity(connector, dialect = "sqlite") {
|
|
111
|
+
entityRegistry.register(createWebAuthnCredentialEntity(connector, dialect));
|
|
112
|
+
}
|
|
113
|
+
//#endregion
|
|
114
|
+
export { WEBAUTHN_CREDENTIAL_ENTITY, createWebAuthnCredentialEntity, createWebAuthnCredentialTable, registerWebAuthnCredentialEntity, webAuthnCredentialTable };
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { createFrameworkTableFactory } from "./colKit.js";
|
|
2
|
+
import { entityRegistry } from "@nodefony/orm-core";
|
|
3
|
+
/** Factory de la table des endpoints (mémoïsée — une instance par dialecte). */
|
|
4
|
+
const createWebhookEndpointTable = createFrameworkTableFactory({
|
|
5
|
+
name: "webhook_endpoint",
|
|
6
|
+
columns: {
|
|
7
|
+
/** Identifiant public stable (`wh_<random>`). */
|
|
8
|
+
id: {
|
|
9
|
+
kind: "text",
|
|
10
|
+
primaryKey: true
|
|
11
|
+
},
|
|
12
|
+
/** URL de destination (validée anti-SSRF à l'enregistrement). */
|
|
13
|
+
url: {
|
|
14
|
+
kind: "text",
|
|
15
|
+
notNull: true
|
|
16
|
+
},
|
|
17
|
+
/** Secret de signature **chiffré** au repos (blob `gcm1.…`). Jamais en clair. */
|
|
18
|
+
secretEnc: {
|
|
19
|
+
kind: "text",
|
|
20
|
+
notNull: true
|
|
21
|
+
},
|
|
22
|
+
/** Actions d'audit souscrites (`"*"` = toutes). */
|
|
23
|
+
events: {
|
|
24
|
+
kind: "json",
|
|
25
|
+
notNull: true,
|
|
26
|
+
defaultFn: () => []
|
|
27
|
+
},
|
|
28
|
+
/** Endpoint actif ? (désactivé = aucune livraison). */
|
|
29
|
+
enabled: {
|
|
30
|
+
kind: "bool",
|
|
31
|
+
notNull: true
|
|
32
|
+
},
|
|
33
|
+
/** Libellé humain optionnel (console admin) ; `null` = aucun. */
|
|
34
|
+
description: { kind: "text" },
|
|
35
|
+
/** Slot multi-tenant (réservé P17) — `null` = global. */
|
|
36
|
+
tenantId: { kind: "text" },
|
|
37
|
+
/** Identité de l'admin créateur (soft ref, traçabilité) ; `null` = inconnu. */
|
|
38
|
+
createdBy: { kind: "text" },
|
|
39
|
+
createdAt: {
|
|
40
|
+
kind: "epochMs",
|
|
41
|
+
notNull: true
|
|
42
|
+
},
|
|
43
|
+
updatedAt: {
|
|
44
|
+
kind: "epochMs",
|
|
45
|
+
notNull: true
|
|
46
|
+
},
|
|
47
|
+
/** Dernière tentative de livraison (epoch ms) ou `null`. */
|
|
48
|
+
lastDeliveryAt: { kind: "epochMs" },
|
|
49
|
+
/** Code HTTP de la dernière livraison, ou `null`. */
|
|
50
|
+
lastDeliveryStatus: { kind: "int" },
|
|
51
|
+
/** Message d'erreur de la dernière livraison, ou `null`. */
|
|
52
|
+
lastDeliveryError: { kind: "text" },
|
|
53
|
+
/** Échecs consécutifs (auto-désactivation au-delà d'un seuil). */
|
|
54
|
+
failureCount: {
|
|
55
|
+
kind: "int",
|
|
56
|
+
notNull: true
|
|
57
|
+
},
|
|
58
|
+
/** Métadonnées extensibles (jamais de secret). */
|
|
59
|
+
metadata: {
|
|
60
|
+
kind: "json",
|
|
61
|
+
notNull: true,
|
|
62
|
+
defaultFn: () => ({})
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
/**
|
|
67
|
+
* Variante SQLite de la table (dialecte par défaut) — export conservé pour
|
|
68
|
+
* l'usage direct/banc-test.
|
|
69
|
+
*/
|
|
70
|
+
const webhookEndpointTable = createWebhookEndpointTable("sqlite");
|
|
71
|
+
/** Nom logique de l'entité (clé de lookup `getRepository`). */
|
|
72
|
+
const WEBHOOK_ENDPOINT_ENTITY = "webhook_endpoint";
|
|
73
|
+
/**
|
|
74
|
+
* Construit le descripteur d'entité du store webhook pour un ORM nommé.
|
|
75
|
+
*
|
|
76
|
+
* Le `connector` est **dynamique** (nom du connecteur de l'app, ex. `"default"`) et la
|
|
77
|
+
* variante de table suit le dialecte du connecteur (auto-register
|
|
78
|
+
* `registerStores.ts` à `onKernelRegister`). À enregistrer **avant**
|
|
79
|
+
* `orm.connect()`.
|
|
80
|
+
*
|
|
81
|
+
* `module: "security"` → la table est regroupée sous @nodefony/security dans
|
|
82
|
+
* l'ERD Studio (le store est une feature security, hébergée par l'ORM de l'app).
|
|
83
|
+
*
|
|
84
|
+
* @param orm - clé de l'ORM cible dans le `ormRegistry`.
|
|
85
|
+
* @param dialect - dialecte SQL du connecteur (sélectionne la variante de table).
|
|
86
|
+
*/
|
|
87
|
+
function createWebhookEndpointEntity(connector, dialect = "sqlite") {
|
|
88
|
+
return {
|
|
89
|
+
connector,
|
|
90
|
+
name: WEBHOOK_ENDPOINT_ENTITY,
|
|
91
|
+
module: "security",
|
|
92
|
+
schema: createWebhookEndpointTable(dialect)
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Enregistre l'entité du store webhook dans le `entityRegistry` pour un ORM
|
|
97
|
+
* donné. À appeler **avant** `orm.connect()` (l'adapter crée la table au connect).
|
|
98
|
+
*
|
|
99
|
+
* @param connector - nom de la connexion cible (clé du registre).
|
|
100
|
+
* @param dialect - dialecte SQL du connecteur (variante de table — défaut `sqlite`).
|
|
101
|
+
*/
|
|
102
|
+
function registerWebhookEndpointEntity(connector, dialect = "sqlite") {
|
|
103
|
+
entityRegistry.register(createWebhookEndpointEntity(connector, dialect));
|
|
104
|
+
}
|
|
105
|
+
//#endregion
|
|
106
|
+
export { WEBHOOK_ENDPOINT_ENTITY, createWebhookEndpointEntity, createWebhookEndpointTable, registerWebhookEndpointEntity, webhookEndpointTable };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { createAccessTokenTable, createDeniedJtiTable, createSubjectRevocationTable } from "../entity/tokenEntity.js";
|
|
2
|
+
import { createAuditEventTable } from "../entity/auditEventEntity.js";
|
|
3
|
+
import { createWebAuthnCredentialTable } from "../entity/webAuthnCredentialEntity.js";
|
|
4
|
+
import { createTotpSecretTable } from "../entity/totpSecretEntity.js";
|
|
5
|
+
import { createWebhookEndpointTable } from "../entity/webhookEndpointEntity.js";
|
|
6
|
+
import { createIdempotencyTable } from "../entity/idempotencyEntity.js";
|
|
7
|
+
import { createSessionTable } from "../entity/sessionEntity.js";
|
|
8
|
+
//#region nodefony/migrations-schema/mysql.ts
|
|
9
|
+
/**
|
|
10
|
+
* Schéma **matérialisé** des tables du framework pour le dialecte `mysql` — la
|
|
11
|
+
* seule entrée que `drizzle-kit` sait lire pour produire les migrations.
|
|
12
|
+
*
|
|
13
|
+
* ⚠️ **Trois contraintes de forme, mesurées, qu'une « factorisation » casserait
|
|
14
|
+
* en silence** :
|
|
15
|
+
*
|
|
16
|
+
* 1. **Un fichier PAR dialecte.** Le dialecte est figé dans la configuration de
|
|
17
|
+
* `drizzle-kit`, pas passé en argument : il ne peut pas y avoir de fichier
|
|
18
|
+
* unique paramétré.
|
|
19
|
+
* 2. **Des ré-exports PLATS.** `drizzle-kit` ne collecte que les tables exportées
|
|
20
|
+
* directement ; une table nichée dans un objet exporté est **ignorée sans un
|
|
21
|
+
* mot** (vérifié : un fichier exportant une table plate et une table nichée
|
|
22
|
+
* rend « 1 tables »). Regrouper ces dix constantes dans un objet ferait donc
|
|
23
|
+
* une migration VIDE, verte.
|
|
24
|
+
* 3. **Rien d'autre que ces exports.** Toute constante supplémentaire de type
|
|
25
|
+
* table entrerait dans la migration.
|
|
26
|
+
*
|
|
27
|
+
* ⚠️ **`User` n'y figure pas, et c'est une décision.** L'identité est du DOMAINE :
|
|
28
|
+
* la table appartient à l'APPLICATION, qui y ajoute ses champs et en porte les
|
|
29
|
+
* migrations. La livrer ici la rendrait « table du framework » — donc exclue du
|
|
30
|
+
* diff que l'application génère, en silence.
|
|
31
|
+
*
|
|
32
|
+
* Les trois fichiers sont volontairement identiques au dialecte près : ils ne
|
|
33
|
+
* portent aucune décision, seulement l'application des fabriques du `colKit`.
|
|
34
|
+
* La source de vérité reste la spécification de chaque entité — c'est elle qu'on
|
|
35
|
+
* modifie, jamais ce fichier, et le contrôle de dérive le vérifie.
|
|
36
|
+
*/
|
|
37
|
+
const DIALECT = "mysql";
|
|
38
|
+
const accessToken = createAccessTokenTable(DIALECT);
|
|
39
|
+
const deniedJti = createDeniedJtiTable(DIALECT);
|
|
40
|
+
const subjectRevocation = createSubjectRevocationTable(DIALECT);
|
|
41
|
+
const session = createSessionTable(DIALECT);
|
|
42
|
+
const idempotencyKey = createIdempotencyTable(DIALECT);
|
|
43
|
+
const auditEvent = createAuditEventTable(DIALECT);
|
|
44
|
+
const totpSecret = createTotpSecretTable(DIALECT);
|
|
45
|
+
const webAuthnCredential = createWebAuthnCredentialTable(DIALECT);
|
|
46
|
+
const webhookEndpoint = createWebhookEndpointTable(DIALECT);
|
|
47
|
+
//#endregion
|
|
48
|
+
export { accessToken, auditEvent, deniedJti, idempotencyKey, session, subjectRevocation, totpSecret, webAuthnCredential, webhookEndpoint };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { createAccessTokenTable, createDeniedJtiTable, createSubjectRevocationTable } from "../entity/tokenEntity.js";
|
|
2
|
+
import { createAuditEventTable } from "../entity/auditEventEntity.js";
|
|
3
|
+
import { createWebAuthnCredentialTable } from "../entity/webAuthnCredentialEntity.js";
|
|
4
|
+
import { createTotpSecretTable } from "../entity/totpSecretEntity.js";
|
|
5
|
+
import { createWebhookEndpointTable } from "../entity/webhookEndpointEntity.js";
|
|
6
|
+
import { createIdempotencyTable } from "../entity/idempotencyEntity.js";
|
|
7
|
+
import { createSessionTable } from "../entity/sessionEntity.js";
|
|
8
|
+
//#region nodefony/migrations-schema/postgres.ts
|
|
9
|
+
/**
|
|
10
|
+
* Schéma **matérialisé** des tables du framework pour le dialecte `postgres` — la
|
|
11
|
+
* seule entrée que `drizzle-kit` sait lire pour produire les migrations.
|
|
12
|
+
*
|
|
13
|
+
* ⚠️ **Trois contraintes de forme, mesurées, qu'une « factorisation » casserait
|
|
14
|
+
* en silence** :
|
|
15
|
+
*
|
|
16
|
+
* 1. **Un fichier PAR dialecte.** Le dialecte est figé dans la configuration de
|
|
17
|
+
* `drizzle-kit`, pas passé en argument : il ne peut pas y avoir de fichier
|
|
18
|
+
* unique paramétré.
|
|
19
|
+
* 2. **Des ré-exports PLATS.** `drizzle-kit` ne collecte que les tables exportées
|
|
20
|
+
* directement ; une table nichée dans un objet exporté est **ignorée sans un
|
|
21
|
+
* mot** (vérifié : un fichier exportant une table plate et une table nichée
|
|
22
|
+
* rend « 1 tables »). Regrouper ces dix constantes dans un objet ferait donc
|
|
23
|
+
* une migration VIDE, verte.
|
|
24
|
+
* 3. **Rien d'autre que ces exports.** Toute constante supplémentaire de type
|
|
25
|
+
* table entrerait dans la migration.
|
|
26
|
+
*
|
|
27
|
+
* ⚠️ **`User` n'y figure pas, et c'est une décision.** L'identité est du DOMAINE :
|
|
28
|
+
* la table appartient à l'APPLICATION, qui y ajoute ses champs et en porte les
|
|
29
|
+
* migrations. La livrer ici la rendrait « table du framework » — donc exclue du
|
|
30
|
+
* diff que l'application génère, en silence.
|
|
31
|
+
*
|
|
32
|
+
* Les trois fichiers sont volontairement identiques au dialecte près : ils ne
|
|
33
|
+
* portent aucune décision, seulement l'application des fabriques du `colKit`.
|
|
34
|
+
* La source de vérité reste la spécification de chaque entité — c'est elle qu'on
|
|
35
|
+
* modifie, jamais ce fichier, et le contrôle de dérive le vérifie.
|
|
36
|
+
*/
|
|
37
|
+
const DIALECT = "postgres";
|
|
38
|
+
const accessToken = createAccessTokenTable(DIALECT);
|
|
39
|
+
const deniedJti = createDeniedJtiTable(DIALECT);
|
|
40
|
+
const subjectRevocation = createSubjectRevocationTable(DIALECT);
|
|
41
|
+
const session = createSessionTable(DIALECT);
|
|
42
|
+
const idempotencyKey = createIdempotencyTable(DIALECT);
|
|
43
|
+
const auditEvent = createAuditEventTable(DIALECT);
|
|
44
|
+
const totpSecret = createTotpSecretTable(DIALECT);
|
|
45
|
+
const webAuthnCredential = createWebAuthnCredentialTable(DIALECT);
|
|
46
|
+
const webhookEndpoint = createWebhookEndpointTable(DIALECT);
|
|
47
|
+
//#endregion
|
|
48
|
+
export { accessToken, auditEvent, deniedJti, idempotencyKey, session, subjectRevocation, totpSecret, webAuthnCredential, webhookEndpoint };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { createAccessTokenTable, createDeniedJtiTable, createSubjectRevocationTable } from "../entity/tokenEntity.js";
|
|
2
|
+
import { createAuditEventTable } from "../entity/auditEventEntity.js";
|
|
3
|
+
import { createWebAuthnCredentialTable } from "../entity/webAuthnCredentialEntity.js";
|
|
4
|
+
import { createTotpSecretTable } from "../entity/totpSecretEntity.js";
|
|
5
|
+
import { createWebhookEndpointTable } from "../entity/webhookEndpointEntity.js";
|
|
6
|
+
import { createIdempotencyTable } from "../entity/idempotencyEntity.js";
|
|
7
|
+
import { createSessionTable } from "../entity/sessionEntity.js";
|
|
8
|
+
//#region nodefony/migrations-schema/sqlite.ts
|
|
9
|
+
/**
|
|
10
|
+
* Schéma **matérialisé** des tables du framework pour le dialecte `sqlite` — la
|
|
11
|
+
* seule entrée que `drizzle-kit` sait lire pour produire les migrations.
|
|
12
|
+
*
|
|
13
|
+
* ⚠️ **Trois contraintes de forme, mesurées, qu'une « factorisation » casserait
|
|
14
|
+
* en silence** :
|
|
15
|
+
*
|
|
16
|
+
* 1. **Un fichier PAR dialecte.** Le dialecte est figé dans la configuration de
|
|
17
|
+
* `drizzle-kit`, pas passé en argument : il ne peut pas y avoir de fichier
|
|
18
|
+
* unique paramétré.
|
|
19
|
+
* 2. **Des ré-exports PLATS.** `drizzle-kit` ne collecte que les tables exportées
|
|
20
|
+
* directement ; une table nichée dans un objet exporté est **ignorée sans un
|
|
21
|
+
* mot** (vérifié : un fichier exportant une table plate et une table nichée
|
|
22
|
+
* rend « 1 tables »). Regrouper ces dix constantes dans un objet ferait donc
|
|
23
|
+
* une migration VIDE, verte.
|
|
24
|
+
* 3. **Rien d'autre que ces exports.** Toute constante supplémentaire de type
|
|
25
|
+
* table entrerait dans la migration.
|
|
26
|
+
*
|
|
27
|
+
* ⚠️ **`User` n'y figure pas, et c'est une décision.** L'identité est du DOMAINE :
|
|
28
|
+
* la table appartient à l'APPLICATION, qui y ajoute ses champs et en porte les
|
|
29
|
+
* migrations. La livrer ici la rendrait « table du framework » — donc exclue du
|
|
30
|
+
* diff que l'application génère, en silence.
|
|
31
|
+
*
|
|
32
|
+
* Les trois fichiers sont volontairement identiques au dialecte près : ils ne
|
|
33
|
+
* portent aucune décision, seulement l'application des fabriques du `colKit`.
|
|
34
|
+
* La source de vérité reste la spécification de chaque entité — c'est elle qu'on
|
|
35
|
+
* modifie, jamais ce fichier, et le contrôle de dérive le vérifie.
|
|
36
|
+
*/
|
|
37
|
+
const DIALECT = "sqlite";
|
|
38
|
+
const accessToken = createAccessTokenTable(DIALECT);
|
|
39
|
+
const deniedJti = createDeniedJtiTable(DIALECT);
|
|
40
|
+
const subjectRevocation = createSubjectRevocationTable(DIALECT);
|
|
41
|
+
const session = createSessionTable(DIALECT);
|
|
42
|
+
const idempotencyKey = createIdempotencyTable(DIALECT);
|
|
43
|
+
const auditEvent = createAuditEventTable(DIALECT);
|
|
44
|
+
const totpSecret = createTotpSecretTable(DIALECT);
|
|
45
|
+
const webAuthnCredential = createWebAuthnCredentialTable(DIALECT);
|
|
46
|
+
const webhookEndpoint = createWebhookEndpointTable(DIALECT);
|
|
47
|
+
//#endregion
|
|
48
|
+
export { accessToken, auditEvent, deniedJti, idempotencyKey, session, subjectRevocation, totpSecret, webAuthnCredential, webhookEndpoint };
|