@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,71 @@
1
+ import type { ITransaction } from "@nodefony/orm-core";
2
+ import type { DrizzleDb } from "./DrizzleRepository.js";
3
+ /**
4
+ * Pilotage transactionnel d'**une connexion**, abstrait du driver (INTERNE).
5
+ *
6
+ * Existe parce que les trois drivers pilotent une transaction différemment :
7
+ * `better-sqlite3` est synchrone sur une connexion unique (rien à rendre), là
8
+ * où `pg` et `mysql2` empruntent une connexion DÉDIÉE à leur pool — qu'il faut
9
+ * impérativement rendre, sous peine d'épuiser le pool en quelques transactions.
10
+ * {@link DrizzleTransaction} ne connaît que ce contrat : le choix du driver
11
+ * appartient à la fabrique posée au connect (cf `DrizzleOrm`).
12
+ */
13
+ export interface ITxDriver {
14
+ /** Exécute une instruction de contrôle (`COMMIT`, `SAVEPOINT …`). */
15
+ exec(sql: string): Promise<void>;
16
+ /**
17
+ * Cite un identifiant SQL (nom de savepoint) — **trait de dialecte** :
18
+ * `"x"` est l'identifiant standard (postgres, sqlite) mais désigne une CHAÎNE
19
+ * en mysql/mariadb hors mode `ANSI_QUOTES`, qui veut des backticks. D'où la
20
+ * délégation au driver plutôt qu'un quoting en dur ici.
21
+ */
22
+ quoteIdent(name: string): string;
23
+ /**
24
+ * Rend la connexion. **`err` renseigné → la connexion est DÉTRUITE**, jamais
25
+ * recyclée : après un `COMMIT`/`ROLLBACK` en échec, son état transactionnel
26
+ * est inconnu — la rendre au pool contaminerait l'emprunteur suivant avec une
27
+ * transaction ouverte. No-op sur une connexion unique (sqlite).
28
+ */
29
+ release(err?: unknown): void;
30
+ }
31
+ /**
32
+ * Adapte une transaction SQL au contrat portable {@link ITransaction}, sur les
33
+ * trois dialectes (sqlite, postgres, mysql).
34
+ *
35
+ * **Pourquoi une transaction manuelle (`BEGIN`/`COMMIT`/`ROLLBACK`) et pas le
36
+ * helper `db.transaction()` de Drizzle** : `better-sqlite3` est **synchrone** ;
37
+ * son helper attend un callback synchrone et committe au `return` — donc *avant*
38
+ * que les `await` du contrat async (`IRepository`) ne s'exécutent. Encadrer le
39
+ * travail par `BEGIN`…`COMMIT` garantit que toutes les opérations (ordonnées par
40
+ * les `await`) tombent dans la même transaction.
41
+ *
42
+ * **Une transaction vit sur UNE connexion** : {@link DrizzleTransaction.getNative}
43
+ * rend le db Drizzle lié à cette connexion précise (la connexion unique en
44
+ * sqlite ; une connexion empruntée au pool en postgres/mysql). Un repository
45
+ * n'entre dans la transaction que lié par `withTransaction(tx)` — celui rendu par
46
+ * `orm.getRepository()` passe, lui, par le pool, donc HORS transaction.
47
+ *
48
+ * Mode managé (cf `DrizzleOrm.transaction`) : commit auto si la closure résout,
49
+ * rollback auto si elle rejette. `commit`/`rollback` exposés (idempotents via le
50
+ * drapeau interne) pour un pilotage manuel éventuel.
51
+ */
52
+ export declare class DrizzleTransaction implements ITransaction {
53
+ #private;
54
+ /**
55
+ * @param db - handle Drizzle lié à la connexion **déjà en `BEGIN`**.
56
+ * @param driver - pilotage transactionnel de cette connexion.
57
+ */
58
+ constructor(db: DrizzleDb, driver: ITxDriver);
59
+ /** Indique si la transaction est déjà terminée (commit ou rollback). */
60
+ isDone(): boolean;
61
+ /** Valide la transaction (no-op si déjà terminée). */
62
+ commit(): Promise<void>;
63
+ /** Annule la transaction (no-op si déjà terminée). */
64
+ rollback(): Promise<void>;
65
+ /** Crée un savepoint nommé (nom validé — anti-injection, cf {@link assertSavepointName}). */
66
+ savepoint(name: string): Promise<void>;
67
+ /** Annule jusqu'au savepoint sans terminer la transaction (nom validé). */
68
+ rollbackTo(name: string): Promise<void>;
69
+ /** Expose le handle Drizzle lié à la connexion encadrée par la transaction. */
70
+ getNative<C = unknown>(): C;
71
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Adapter Drizzle (driver `better-sqlite3`) sur `@nodefony/orm-core` (P7.4).
3
+ *
4
+ * adapter du banc multi-ORM ; valide le contrat
5
+ * sur un ORM type-safe-first et la forme finale des opérateurs riches (ADR-0003).
6
+ */
7
+ export { DrizzleOrm } from "./DrizzleOrm.js";
8
+ export type { DrizzleOrmOptions } from "./DrizzleOrm.js";
9
+ export { DrizzleRepository } from "./DrizzleRepository.js";
10
+ export type { DrizzleDb, DrizzleTable, DrizzleColumn, DrizzleResolvedRelation, } from "./DrizzleRepository.js";
11
+ export { DrizzleTransaction } from "./DrizzleTransaction.js";
@@ -0,0 +1,136 @@
1
+ import type { IPageQuery } from "nodefony";
2
+ import type { SqlDialect } from "../interfaces/IDrizzleConfig.js";
3
+ import type { DrizzleDb } from "./orm-core/DrizzleRepository.js";
4
+ /**
5
+ * Cherche l'`id` du user dont le tableau JSON `socialProviders` contient un
6
+ * lien `{provider, providerId}` — le finder du pattern **Shadow User** OAuth
7
+ * (`DrizzleUserRepository.findBySocialProvider`).
8
+ *
9
+ * Sémantique IDENTIQUE sur tous les dialectes : « il EXISTE un élément du
10
+ * tableau dont `provider` ET `providerId` valent exactement ces valeurs »
11
+ * (les autres clés de l'élément, ex. `createdAt`, sont ignorées) :
12
+ * - **sqlite** : `EXISTS (SELECT 1 FROM json_each(col) WHERE json_extract…)`
13
+ * — scan du tableau, valeurs bindées ;
14
+ * - **postgres** : `col @> '[{"provider":…,"providerId":…}]'::jsonb` —
15
+ * containment jsonb natif (indexable GIN), le motif est UN paramètre bindé
16
+ * sérialisé JSON ;
17
+ * - **mysql** : `JSON_CONTAINS(col, <motif>)` — containment JSON natif (même
18
+ * sémantique partielle que `@>` : un objet candidat est contenu dans un
19
+ * élément du tableau si toutes SES clés y matchent), motif = UN paramètre
20
+ * bindé sérialisé JSON, casté par MySQL.
21
+ *
22
+ * @param db - handle Drizzle natif (racine ou transaction) du dialecte.
23
+ * @param dialect - dialecte SQL du connecteur.
24
+ * @param provider - fournisseur d'identité (`"github"`, `"google"`…).
25
+ * @param providerId - identifiant du compte CHEZ le fournisseur.
26
+ * @returns l'`id` du user lié, ou `null` si aucun lien.
27
+ */
28
+ export declare function findUserIdBySocialProvider(db: DrizzleDb, dialect: SqlDialect, provider: string, providerId: string): Promise<string | null>;
29
+ /**
30
+ * Réservation **atomique** d'une clé d'idempotence en **MySQL** — l'équivalent
31
+ * du `INSERT … ON CONFLICT DO UPDATE … WHERE expiré RETURNING` des dialectes
32
+ * sqlite/pg (cf `DrizzleIdempotencyStore.begin`), reconstruit avec les moyens
33
+ * du dialecte : MySQL n'a **ni `RETURNING` ni `WHERE` sur le `ON DUPLICATE KEY
34
+ * UPDATE`** — et le verdict `affectedRows` d'un ODKU est AMBIGU sous mysql2
35
+ * (flag `CLIENT_FOUND_ROWS` par défaut : ligne « matched inchangée » = 1,
36
+ * indistinguable d'un INSERT — prouvé sur serveur réel). D'où DEUX
37
+ * instructions, chacune atomique et au verdict non-ambigu :
38
+ *
39
+ * 1. **`INSERT IGNORE`** — clé neuve : `affectedRows = 1` ⇒ réservation
40
+ * acquise ; clé existante : TOUJOURS `0` (`FOUND_ROWS` ne concerne pas les
41
+ * doublons d'INSERT). L'unicité de la PK garantit UN seul gagnant sous
42
+ * concurrence. (`IGNORE` downgrade aussi le mode strict en warnings — sans
43
+ * enjeu ici : la clé est bornée en amont, `IDEMPOTENCY_KEY_MAX` 255 ≪
44
+ * varchar(512).)
45
+ * 2. **Vol d'une entrée MORTE** : `UPDATE … WHERE key = ? AND expiresAt < now`
46
+ * — le WHERE porte la condition « morte » ; l'UPDATE change TOUJOURS
47
+ * `expiresAt` (nouveau > now > ancien) donc `affectedRows = 1` ⇔ vol acquis,
48
+ * quel que soit le flag. Deux voleurs concurrents se sérialisent sur le
49
+ * verrou de ligne InnoDB : le second ré-évalue le WHERE sur la version
50
+ * committée (current read) → 0 ligne. Jamais de double-vol.
51
+ *
52
+ * Course résiduelle INSERT(0) → UPDATE(0) alors que la clé vient d'être
53
+ * supprimée (gc/abort) : verdict « contention » → le SELECT de `begin` ne la
54
+ * trouve plus → `in-flight` prudent (jamais `fresh` hors réservation atomique,
55
+ * l'invariant anti double-effet du contrat).
56
+ *
57
+ * @param db - handle Drizzle natif mysql.
58
+ * @param args - clé scopée, empreinte payload, horloge et échéance du bail.
59
+ * @returns `true` si la réservation est acquise (= le `fresh` du contrat).
60
+ */
61
+ export declare function reserveIdempotencyKeyMysql(db: DrizzleDb, args: {
62
+ key: string;
63
+ fingerprint: string;
64
+ now: number;
65
+ leaseExpiresAt: number;
66
+ }): Promise<boolean>;
67
+ /** Filtres du listing utilisateur (sous-ensemble non portable de `IUserListQuery`). */
68
+ export interface UserListFilters {
69
+ role?: string;
70
+ enabled?: boolean;
71
+ locked?: boolean;
72
+ hasSocial?: boolean;
73
+ q?: string;
74
+ }
75
+ /** Fenêtre + tri résolus (le défaut `identifier ASC` est posé par l'appelant). */
76
+ export interface UserPageWindow {
77
+ limit: number;
78
+ offset: number;
79
+ order: Array<[string, "ASC" | "DESC"]>;
80
+ }
81
+ /**
82
+ * Sélectionne les `id` d'une **page** d'utilisateurs (filtres + tri + `LIMIT/
83
+ * OFFSET`), sans matérialiser les lignes. `limit + 1` → `hasNext` sans `COUNT`.
84
+ *
85
+ * @returns les `id` de la page (au plus `window.limit`, dans l'ordre du tri) et
86
+ * `hasNext`.
87
+ */
88
+ export declare function listUserIdsPage(db: DrizzleDb, dialect: SqlDialect, filters: UserListFilters, window: UserPageWindow): Promise<{
89
+ ids: string[];
90
+ hasNext: boolean;
91
+ }>;
92
+ /** Filtres du listing d'endpoints (sous-ensemble non portable d'`IWebhookListQuery`). */
93
+ export interface WebhookListFilters {
94
+ enabled?: boolean;
95
+ event?: string;
96
+ failing?: boolean;
97
+ q?: string;
98
+ }
99
+ /**
100
+ * Sélectionne les `id` d'une **page** d'endpoints webhook (filtres + tri +
101
+ * `LIMIT/OFFSET`), sans matérialiser les lignes. `limit + 1` → `hasNext` sans
102
+ * `COUNT`.
103
+ *
104
+ * Le tri descend dans le `ORDER BY` — jamais appliqué après découpe, sinon la
105
+ * 2ᵉ page recommencerait au lieu de continuer la 1ʳᵉ. À défaut d'`order`
106
+ * recevable, l'ordre par défaut `createdAt DESC, id ASC` rend l'offset
107
+ * déterministe quand deux endpoints partagent la même milliseconde de création.
108
+ *
109
+ * @param window - fenêtre de page **et** tri demandé (déjà en noms publics ; il
110
+ * est re-filtré ici par l'allowlist, cf {@link orderBySql}).
111
+ * @returns les `id` de la page (au plus `limit`, dans l'ordre) et `hasNext`.
112
+ */
113
+ export declare function listWebhookIdsPage(db: DrizzleDb, dialect: SqlDialect, filters: WebhookListFilters, window: {
114
+ limit: number;
115
+ offset: number;
116
+ order?: IPageQuery["order"];
117
+ sortable?: readonly string[];
118
+ }): Promise<{
119
+ ids: string[];
120
+ hasNext: boolean;
121
+ }>;
122
+ /**
123
+ * Compte les endpoints qui matchent les filtres (`COUNT(*)` natif filtré) —
124
+ * base du `total` d'une page d'endpoints.
125
+ *
126
+ * @returns le nombre de lignes correspondantes.
127
+ */
128
+ export declare function countWebhookEndpoints(db: DrizzleDb, dialect: SqlDialect, filters: WebhookListFilters): Promise<number>;
129
+ /**
130
+ * Compte les utilisateurs qui matchent les filtres (`COUNT(*)` natif filtré) —
131
+ * base commune du `total` de la page ET du garde-fou `countActiveAdmins`
132
+ * (`{ enabled: true, role: adminRole }`).
133
+ *
134
+ * @returns le nombre de lignes correspondantes.
135
+ */
136
+ export declare function countUsers(db: DrizzleDb, dialect: SqlDialect, filters: UserListFilters): Promise<number>;
@@ -0,0 +1,42 @@
1
+ import path from "node:path";
2
+ import type { SqlDialect } from "../config/config.js";
3
+ /**
4
+ * Comment DÉSIGNER la base d'un connecteur sans rien faire fuiter.
5
+ *
6
+ * **Pourquoi une règle à part, et pourquoi elle est PURE.** Trois endroits
7
+ * doivent nommer la même base — l'adaptateur, qui la publie au plan
8
+ * d'administration ; les commandes de migration, qui doivent dire sur QUOI
9
+ * elles ont travaillé ; et le rapport d'état, que lisent un humain, un script
10
+ * et une console. Trois rendus recopiés divergeraient, et la divergence serait
11
+ * silencieuse : chacun passerait ses propres tests. Écrite ici, la règle
12
+ * s'éprouve sans base, sans kernel et sans variable d'environnement.
13
+ *
14
+ * Deux familles, deux dangers différents :
15
+ *
16
+ * - **une base FICHIER** (sqlite) : le danger est l'arborescence du serveur —
17
+ * le nom de l'utilisateur, la structure du disque. Le chemin est donc rendu
18
+ * RELATIF au répertoire de travail, et se réduit au nom de fichier dès qu'il
19
+ * sort du projet ;
20
+ * - **une base RÉSEAU** (PostgreSQL, MySQL) : le danger est le compte. Une URL
21
+ * de migration porte l'identifiant et le mot de passe du seul compte autorisé
22
+ * à modifier un schéma de production. Seuls l'hôte, le port et le nom de la
23
+ * base sont rendus — jamais la partie qui précède l'arobase.
24
+ *
25
+ * ⚠️ `redactSecrets` ne couvre PAS ce cas : aucune de ses familles ne masque un
26
+ * mot de passe d'URL. C'est pourquoi cette fonction ne masque pas, elle
27
+ * RECONSTRUIT — on ne publie que les morceaux dont on a décidé qu'ils sont
28
+ * publiables, ce qui reste vrai pour une URL dont la forme nous surprendrait.
29
+ *
30
+ * @param target - dialecte et coordonnées, telles que la résolution les rend.
31
+ * @param cwd - répertoire de référence pour relativiser un chemin de fichier.
32
+ * @param grammar - grammaire de chemins à employer. Injectée pour une seule
33
+ * raison : une fonction qui lit `path` global ne s'éprouve que sur la
34
+ * plateforme qu'elle décrit, c'est-à-dire jamais ici. Avec `path.win32`, le
35
+ * cas Windows se joue sur n'importe quel système.
36
+ * @returns une désignation affichable, sans identifiant ni mot de passe.
37
+ */
38
+ export declare function describeTargetSafely(target: {
39
+ dialect: SqlDialect;
40
+ filename?: string;
41
+ url?: string;
42
+ }, cwd?: string, grammar?: typeof path): string;