@nodefony/mongoose 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 +97 -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 +90 -0
- package/dist/nodefony/config/config.js +57 -0
- package/dist/nodefony/config/defineModuleConfig.js +60 -0
- package/dist/nodefony/entity/sessionEntity.js +63 -0
- package/dist/nodefony/entity/tokenEntity.js +184 -0
- package/dist/nodefony/entity/userEntity.js +106 -0
- package/dist/nodefony/entity/webAuthnCredentialEntity.js +97 -0
- package/dist/nodefony/entity/webhookEndpointEntity.js +109 -0
- package/dist/nodefony/interfaces/IMongooseConfig.js +1 -0
- package/dist/nodefony/interfaces/index.js +1 -0
- package/dist/nodefony/registerStores.js +89 -0
- package/dist/nodefony/service/MongooseService.js +95 -0
- package/dist/nodefony/src/MongooseTokenStore.js +237 -0
- package/dist/nodefony/src/MongooseUserRepository.js +205 -0
- package/dist/nodefony/src/MongooseWebAuthnCredentialStore.js +144 -0
- package/dist/nodefony/src/MongooseWebhookStore.js +181 -0
- package/dist/nodefony/src/SessionStorage.js +241 -0
- package/dist/nodefony/src/mongoOrder.js +49 -0
- package/dist/nodefony/src/orm-core/MongooseOrm.js +440 -0
- package/dist/nodefony/src/orm-core/MongooseRepository.js +300 -0
- package/dist/nodefony/src/orm-core/MongooseTransaction.js +53 -0
- package/dist/nodefony/src/orm-core/index.js +4 -0
- package/dist/types/index.d.ts +74 -0
- package/dist/types/nodefony/config/config.d.ts +21 -0
- package/dist/types/nodefony/config/defineModuleConfig.d.ts +26 -0
- package/dist/types/nodefony/entity/sessionEntity.d.ts +42 -0
- package/dist/types/nodefony/entity/tokenEntity.d.ts +59 -0
- package/dist/types/nodefony/entity/userEntity.d.ts +54 -0
- package/dist/types/nodefony/entity/webAuthnCredentialEntity.d.ts +61 -0
- package/dist/types/nodefony/entity/webhookEndpointEntity.d.ts +62 -0
- package/dist/types/nodefony/interfaces/IMongooseConfig.d.ts +17 -0
- package/dist/types/nodefony/interfaces/index.d.ts +1 -0
- package/dist/types/nodefony/registerStores.d.ts +37 -0
- package/dist/types/nodefony/service/MongooseService.d.ts +48 -0
- package/dist/types/nodefony/src/MongooseTokenStore.d.ts +126 -0
- package/dist/types/nodefony/src/MongooseUserRepository.d.ts +82 -0
- package/dist/types/nodefony/src/MongooseWebAuthnCredentialStore.d.ts +52 -0
- package/dist/types/nodefony/src/MongooseWebhookStore.d.ts +72 -0
- package/dist/types/nodefony/src/SessionStorage.d.ts +63 -0
- package/dist/types/nodefony/src/mongoOrder.d.ts +40 -0
- package/dist/types/nodefony/src/orm-core/MongooseOrm.d.ts +132 -0
- package/dist/types/nodefony/src/orm-core/MongooseRepository.d.ts +51 -0
- package/dist/types/nodefony/src/orm-core/MongooseTransaction.d.ts +37 -0
- package/dist/types/nodefony/src/orm-core/index.d.ts +9 -0
- package/docs/configuration.md +776 -0
- package/docs/index.md +881 -0
- package/package.json +97 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import config, { mongooseConfigSchema } from "./nodefony/config/config.js";
|
|
2
|
+
import { defineMongooseConfig, mongooseConfigJsonSchema } from "./nodefony/config/defineModuleConfig.js";
|
|
3
|
+
import { MongooseRepository } from "./nodefony/src/orm-core/MongooseRepository.js";
|
|
4
|
+
import { MongooseTransaction } from "./nodefony/src/orm-core/MongooseTransaction.js";
|
|
5
|
+
import { MongooseOrm } from "./nodefony/src/orm-core/MongooseOrm.js";
|
|
6
|
+
import MongooseService from "./nodefony/service/MongooseService.js";
|
|
7
|
+
import "./nodefony/src/orm-core/index.js";
|
|
8
|
+
import { TOKEN_ENTITY_NAMES, accessTokenSchema, createTokenEntities, deniedJtiSchema, registerTokenEntities, subjectRevocationSchema } from "./nodefony/entity/tokenEntity.js";
|
|
9
|
+
import { WEBAUTHN_CREDENTIAL_ENTITY, createWebAuthnCredentialEntity, registerWebAuthnCredentialEntity, webAuthnCredentialSchema } from "./nodefony/entity/webAuthnCredentialEntity.js";
|
|
10
|
+
import { WEBHOOK_ENDPOINT_ENTITY, createWebhookEndpointEntity, registerWebhookEndpointEntity, webhookEndpointSchema } from "./nodefony/entity/webhookEndpointEntity.js";
|
|
11
|
+
import { MongooseTokenStore } from "./nodefony/src/MongooseTokenStore.js";
|
|
12
|
+
import { MongooseWebAuthnCredentialStore } from "./nodefony/src/MongooseWebAuthnCredentialStore.js";
|
|
13
|
+
import { MongooseWebhookStore } from "./nodefony/src/MongooseWebhookStore.js";
|
|
14
|
+
import { FRAMEWORK_CONNECTOR, registerMongooseFrameworkStores } from "./nodefony/registerStores.js";
|
|
15
|
+
import __decorateMetadata from "./_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/decorateMetadata.js";
|
|
16
|
+
import __decorate from "./_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/decorate.js";
|
|
17
|
+
import sessionEntity_default, { SESSION_CONNECTOR, sessionSchema as schema } from "./nodefony/entity/sessionEntity.js";
|
|
18
|
+
import SessionStorage from "./nodefony/src/SessionStorage.js";
|
|
19
|
+
import { createUserEntity, registerUserEntity, userSchema } from "./nodefony/entity/userEntity.js";
|
|
20
|
+
import { MongooseUserRepository } from "./nodefony/src/MongooseUserRepository.js";
|
|
21
|
+
import mongoose from "mongoose";
|
|
22
|
+
import { Kernel, Module, registerErrorAdapter, services } from "nodefony";
|
|
23
|
+
import { wireOrmAdminPlane } from "@nodefony/orm-core";
|
|
24
|
+
import { registerUserStore } from "@nodefony/user";
|
|
25
|
+
//#region index.ts
|
|
26
|
+
/**
|
|
27
|
+
* `@nodefony/mongoose` — module Mongoose ORM (driver NoSQL) sur `@nodefony/orm-core`.
|
|
28
|
+
*
|
|
29
|
+
* **Module bootable** : enregistré dans le manifeste `modules`, son
|
|
30
|
+
* {@link MongooseService} connecte au boot un {@link MongooseOrm} par connecteur
|
|
31
|
+
* configuré. Refonte 2026-06-08 (Ph.2 virage ORM) : ne dérive plus de l'`Orm`
|
|
32
|
+
* legacy du core — le service `extends Service` et orchestre des adapters
|
|
33
|
+
* orm-core autonomes (modèle `DrizzleService`). Le core ne connaît plus l'ORM.
|
|
34
|
+
*
|
|
35
|
+
* Config = source de vérité Zod (`nodefony/config/config.ts`), validée au boot
|
|
36
|
+
* via {@link defineMongooseConfig} (style `@nodefony/redis`/`@nodefony/realtime`).
|
|
37
|
+
*/
|
|
38
|
+
let Mongoose = class Mongoose extends Module {
|
|
39
|
+
/**
|
|
40
|
+
* Module **optionnel** (driver NoSQL externe, opt-in) : un échec de son boot
|
|
41
|
+
* (Mongo injoignable) ne tue jamais le process — le store de session dégrade
|
|
42
|
+
* gracieusement (`#repo()` → null). Résilience cloud-native (l'orchestrateur
|
|
43
|
+
* relèvera Mongo). Convention-frère `@nodefony/redis`.
|
|
44
|
+
*/
|
|
45
|
+
static critical = false;
|
|
46
|
+
constructor(kernel) {
|
|
47
|
+
super("mongoose", kernel, import.meta.url, config);
|
|
48
|
+
}
|
|
49
|
+
/** JSON Schema de la config mongoose → data plane admin (config riche Studio). */
|
|
50
|
+
configSchema() {
|
|
51
|
+
return mongooseConfigJsonSchema();
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Valide la config (défauts + `module.options` + surcharge env) au boot via
|
|
55
|
+
* `defineMongooseConfig`, et l'expose au container sous `mongooseConfig` pour
|
|
56
|
+
* que le `MongooseService` la consomme sans redupliquer la validation. Plante
|
|
57
|
+
* propre avec messages clairs si la config est invalide (convention Zod).
|
|
58
|
+
*/
|
|
59
|
+
async onKernelRegister() {
|
|
60
|
+
const validated = defineMongooseConfig(this.options ?? {});
|
|
61
|
+
this.options = validated;
|
|
62
|
+
registerUserStore("mongoose");
|
|
63
|
+
if (validated.frameworkEntities !== false) {
|
|
64
|
+
const report = registerMongooseFrameworkStores();
|
|
65
|
+
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");
|
|
66
|
+
if (report.registered.length) this.log(`schéma framework déclaré sur "${FRAMEWORK_CONNECTOR}" : [${report.registered.join(", ")}]`, "DEBUG");
|
|
67
|
+
}
|
|
68
|
+
return this;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Monte le data plane ORM (`/nodefony/orm/api/*` + providers santé/flux) via
|
|
72
|
+
* {@link wireOrmAdminPlane} — branchement GLOBAL et idempotent factorisé en
|
|
73
|
+
* orm-core (C5), identique à Drizzle. Avant la factorisation, ce wiring était
|
|
74
|
+
* déclenché par le seul module Drizzle → une app Mongoose-only avait un Studio
|
|
75
|
+
* ORM muet ; chaque driver l'invoque désormais. En plus, enregistre l'adapter
|
|
76
|
+
* d'erreurs Mongoose (spécifique au driver, hors plan d'administration).
|
|
77
|
+
*/
|
|
78
|
+
async onKernelBoot() {
|
|
79
|
+
wireOrmAdminPlane(this.kernel);
|
|
80
|
+
registerErrorAdapter("mongoose", {
|
|
81
|
+
isError: (e) => e instanceof mongoose.Error,
|
|
82
|
+
errorToString: (e) => String(e?.message ?? e)
|
|
83
|
+
});
|
|
84
|
+
return this;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
Mongoose = __decorate([services([MongooseService]), __decorateMetadata("design:paramtypes", [typeof Kernel === "undefined" ? Object : Kernel])], Mongoose);
|
|
88
|
+
var mongoose_default = Mongoose;
|
|
89
|
+
//#endregion
|
|
90
|
+
export { FRAMEWORK_CONNECTOR, MongooseOrm, MongooseRepository, MongooseService, MongooseTokenStore, MongooseTransaction, MongooseUserRepository, MongooseWebAuthnCredentialStore, MongooseWebhookStore, SESSION_CONNECTOR, sessionEntity_default as SessionEntity, SessionStorage, TOKEN_ENTITY_NAMES, WEBAUTHN_CREDENTIAL_ENTITY, WEBHOOK_ENDPOINT_ENTITY, accessTokenSchema, createTokenEntities, createUserEntity, createWebAuthnCredentialEntity, createWebhookEndpointEntity, mongoose_default as default, defineMongooseConfig, deniedJtiSchema, mongoose, mongooseConfigJsonSchema, mongooseConfigSchema, registerMongooseFrameworkStores, registerTokenEntities, registerUserEntity, registerWebAuthnCredentialEntity, registerWebhookEndpointEntity, schema as sessionSchema, subjectRevocationSchema, userSchema, webAuthnCredentialSchema, webhookEndpointSchema };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
//#region nodefony/config/config.ts
|
|
3
|
+
/**
|
|
4
|
+
* @nodefony/mongoose — CONFIGURATION DU MODULE (schéma Zod = source unique).
|
|
5
|
+
*
|
|
6
|
+
* ⭐ TL;DR : CE SCHÉMA EST LA CONFIG. Chaque `.default(...)` = la valeur d'usine ;
|
|
7
|
+
* changer un défaut du module = ÉDITER ICI (et nulle part ailleurs). L'app, elle,
|
|
8
|
+
* surcharge via `use("@nodefony/...", { … })` dans SON `nodefony.config.ts`.
|
|
9
|
+
*
|
|
10
|
+
* RÈGLE D'OR (ADR-0006) : ce fichier porte le **schéma Zod commenté** (type +
|
|
11
|
+
* validation + défaut + doc) ET matérialise les défauts via `parse({})`. Aucune
|
|
12
|
+
* valeur n'est re-tapée ailleurs. Le builder (`defineMongooseConfig`) et les types
|
|
13
|
+
* (`interfaces/IMongooseConfig.ts`) importent le schéma D'ICI (nœud bas : ce fichier
|
|
14
|
+
* n'importe que `zod` → pas de cycle).
|
|
15
|
+
*
|
|
16
|
+
* Le type TS est dérivé via `z.infer<>` ({@link MongooseConfig}), et la config est
|
|
17
|
+
* validée au boot du Module class (hook `onKernelRegister`, via le builder
|
|
18
|
+
* {@link defineMongooseConfig}) → plante propre avec messages clairs si la config
|
|
19
|
+
* est invalide, plutôt qu'un `undefined.x` silencieux en runtime.
|
|
20
|
+
*
|
|
21
|
+
* Convention figée (cf `feedback_config_validation_zod` + audit config ORM
|
|
22
|
+
* 2026-06), alignée sur `@nodefony/drizzle` (adapter SQL frère, référence).
|
|
23
|
+
*
|
|
24
|
+
* ⚠️ ENV : ce schéma reste **PUR** (aucune lecture `process.env` ici, sinon il
|
|
25
|
+
* devient non déterministe et non sérialisable en JSON Schema). La surcharge par
|
|
26
|
+
* variables d'environnement (`MONGODB_URI`, `NF_MONGODB_DEBUG`) est appliquée dans
|
|
27
|
+
* {@link defineMongooseConfig}, APRÈS le parse.
|
|
28
|
+
*
|
|
29
|
+
* SURCHARGE (précédence croissante — cf ADR-0006) :
|
|
30
|
+
* • App (typé) : `use("@nodefony/mongoose", { debug: true, connectors: { … } })` ;
|
|
31
|
+
* • Par environnement : `MONGODB_URI` · `NF_MONGODB_DEBUG` (appliqués dans
|
|
32
|
+
* `defineMongooseConfig`).
|
|
33
|
+
*
|
|
34
|
+
* ⚠️ NE PAS éditer les défauts matérialisés en bas de fichier : modifier les
|
|
35
|
+
* `.default(...)` du schéma. La validation + le merge env finaux sont faits dans
|
|
36
|
+
* `index.ts` au hook `onKernelRegister` via `defineMongooseConfig`.
|
|
37
|
+
*/
|
|
38
|
+
const connectorSchema = z.strictObject({
|
|
39
|
+
uri: z.string().min(1).optional().describe("URI de connexion complète (`mongodb://…` ou `mongodb+srv://…`). Si fournie, elle PRIME sur `host`/`port`/`dbname`. Pratique pour les PaaS / Atlas. ⚠️ Zero Trust : un secret (user:pass) NE doit JAMAIS être committé — passer par l'env. Pour la poser par variable : `MONGODB_URI` (ou l'infra `NF_DATABASE_URL` de famille mongo). `NF__MONGOOSE__CONNECTORS__<NOM>__URI` ne marche QUE si la clé `uri` existe déjà dans la config de l'application : la surcharge par chemin remplace une valeur, elle n'en crée pas (elle avertit sinon)."),
|
|
40
|
+
host: z.string().min(1).default("localhost").describe("Hôte du serveur MongoDB. Défaut `localhost` (jamais d'hôte d'infra hardcodé). Ignoré si `uri` est fournie. Reco prod : hôte managé + TLS."),
|
|
41
|
+
port: z.number().int().min(1).max(65535).default(27017).describe("Port TCP du serveur. Défaut 27017. Ignoré si `uri` fournie."),
|
|
42
|
+
dbname: z.string().min(1).default("nodefony").describe("Nom de la base. Défaut `nodefony`. Ignoré si `uri` fournie."),
|
|
43
|
+
autoIndex: z.boolean().optional().describe("Construire les index déclarés au démarrage (défaut mongoose : true). Mongoose recommande `false` en production : la construction bloque les opérations sur une grosse collection. ⚠️ À `false`, un index manquant N'EST PAS créé — il est seulement CONSTATÉ et journalisé en CRITIC ; le poser devient un geste d'exploitation. Prime sur une clé `autoIndex` écrite dans `options` (canal typé > fourre-tout)."),
|
|
44
|
+
options: z.record(z.string(), z.unknown()).optional().describe("Options de connexion Mongoose (`ConnectOptions` : `user`/`pass`/`maxPoolSize`/`serverSelectionTimeoutMS`/`socketTimeoutMS`…). NON re-modélisées ici (validées par Mongoose lui-même). ⚠️ Les credentials (`user`/`pass`) doivent venir de l'env, jamais du dépôt.")
|
|
45
|
+
}).describe("Définition d'une connexion Mongoose nommée.");
|
|
46
|
+
const mongooseConfigSchema = z.strictObject({
|
|
47
|
+
debug: z.boolean().default(false).describe("Active la trace Mongoose des requêtes (`mongoose.set('debug')`). Défaut false. Mettre true en dev pour voir chaque opération. Surchargé par l'env `NF_MONGODB_DEBUG` (1/true). Reco prod : false."),
|
|
48
|
+
connectors: z.record(z.string(), connectorSchema).default(() => ({ nodefony: connectorSchema.parse({}) })).describe("Connexions indexées par nom (= clé dans le `ormRegistry`). Défaut : un connecteur `nodefony` sur `localhost:27017/nodefony`. Le nom `nodefony` (≠ `default` de Drizzle) évite toute collision d'entité dans le `entityRegistry` (process-wide) si les deux ORM cohabitent."),
|
|
49
|
+
frameworkEntities: z.boolean().default(true).describe("Déclare le schéma framework sur le connecteur `nodefony` (tokens, webauthn, webhooks — modèles compilés au connect) et rend les stores correspondants sélectionnables par nom (`mongoose`). Couverture partielle assumée : PAS d'audit ni d'idempotence mongoose. `false` = module data-only.")
|
|
50
|
+
}).describe("Configuration de @nodefony/mongoose.");
|
|
51
|
+
/**
|
|
52
|
+
* Défauts du module, matérialisés depuis le schéma (source unique). Toujours
|
|
53
|
+
* valides par construction ; passés au `super(..., config)` du Module class.
|
|
54
|
+
*/
|
|
55
|
+
const config = mongooseConfigSchema.parse({});
|
|
56
|
+
//#endregion
|
|
57
|
+
export { config as default, mongooseConfigSchema };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { mongooseConfigSchema } from "./config.js";
|
|
2
|
+
import { parseModuleConfig, resolveInfra } from "nodefony";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
//#region nodefony/config/defineModuleConfig.ts
|
|
5
|
+
/**
|
|
6
|
+
* Applique la surcharge par variables d'environnement APRÈS le parse Zod.
|
|
7
|
+
*
|
|
8
|
+
* Le schéma reste pur (déterministe, sérialisable en JSON Schema) ; l'env est une
|
|
9
|
+
* couche explicite par-dessus. Précédence : env > config app > défauts.
|
|
10
|
+
*
|
|
11
|
+
* - `MONGODB_URI`, sinon infra database `NF_DATABASE_URL`/`DATABASE_URL` de
|
|
12
|
+
* famille mongo (`mongodb://`/`mongodb+srv://` — une URL SQL est IGNORÉE ici,
|
|
13
|
+
* elle appartient à `@nodefony/drizzle`) → `uri` du connecteur primaire
|
|
14
|
+
* (`nodefony`, sinon le premier). ⚠️ La place pour le secret de connexion
|
|
15
|
+
* (user:pass) — JAMAIS dans le dépôt.
|
|
16
|
+
* - `NF_MONGODB_DEBUG` (1/true) → `debug`.
|
|
17
|
+
*/
|
|
18
|
+
function applyEnvOverrides(config) {
|
|
19
|
+
const env = process.env;
|
|
20
|
+
const database = resolveInfra(env).database;
|
|
21
|
+
const uri = env.MONGODB_URI ?? (database && database.family === "mongo" ? database.url : void 0);
|
|
22
|
+
if (uri) {
|
|
23
|
+
const target = config.connectors.nodefony ? "nodefony" : Object.keys(config.connectors)[0];
|
|
24
|
+
if (target && config.connectors[target]) config.connectors[target].uri = uri;
|
|
25
|
+
}
|
|
26
|
+
if (env.NF_MONGODB_DEBUG === "1" || env.NF_MONGODB_DEBUG === "true") config.debug = true;
|
|
27
|
+
return config;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Builder type-safe de la configuration de `@nodefony/mongoose`.
|
|
31
|
+
*
|
|
32
|
+
* ⭐ TL;DR : MACHINERIE DE BOOT — on n'édite (presque) jamais ce fichier. Même
|
|
33
|
+
* pattern que `nodefony.config.ts` ↔ `defineConfig()` du core : `config.ts` PORTE
|
|
34
|
+
* la config (schéma + défauts), `define<X>Config()` la VALIDE au boot (parse +
|
|
35
|
+
* env + freeze) et publie le JSON Schema Studio.
|
|
36
|
+
*
|
|
37
|
+
* Principes (alignés sur `defineRedisConfig` / `defineRealtimeConfig`) :
|
|
38
|
+
* - **Source unique** : `./config.ts` (Zod). Le builder VALIDE, applique l'ENV,
|
|
39
|
+
* puis GÈLE — il ne dévie jamais du schéma.
|
|
40
|
+
* - **Auto-documenté** : chaque champ Zod porte un `.describe()` →
|
|
41
|
+
* {@link mongooseConfigJsonSchema} produit un JSON Schema qu'un formulaire Studio
|
|
42
|
+
* (futur) consommera pour générer son UI d'édition.
|
|
43
|
+
*
|
|
44
|
+
* @param config - configuration brute (sections omises = défauts sûrs).
|
|
45
|
+
* @returns config validée, surchargée par l'env, et gelée.
|
|
46
|
+
* @throws ZodError si la config est invalide.
|
|
47
|
+
*/
|
|
48
|
+
function defineMongooseConfig(config = {}) {
|
|
49
|
+
const parsed = parseModuleConfig(mongooseConfigSchema, config, "@nodefony/mongoose");
|
|
50
|
+
return Object.freeze(applyEnvOverrides(parsed));
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* JSON Schema introspectable de la config Mongoose — destiné au formulaire
|
|
54
|
+
* d'édition Studio (futur) et à la documentation générée.
|
|
55
|
+
*/
|
|
56
|
+
function mongooseConfigJsonSchema() {
|
|
57
|
+
return z.toJSONSchema(mongooseConfigSchema);
|
|
58
|
+
}
|
|
59
|
+
//#endregion
|
|
60
|
+
export { defineMongooseConfig, mongooseConfigJsonSchema };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import __decorate from "../../_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/decorate.js";
|
|
2
|
+
import { entity } from "@nodefony/orm-core";
|
|
3
|
+
//#region nodefony/entity/sessionEntity.ts
|
|
4
|
+
/** ORM cible du stockage de session (connecteur par défaut du module). */
|
|
5
|
+
const SESSION_CONNECTOR = "nodefony";
|
|
6
|
+
/**
|
|
7
|
+
* Schéma Mongoose de stockage des sessions (compilé par `MongooseOrm` au boot).
|
|
8
|
+
*
|
|
9
|
+
* Équivalent portable de l'entité session legacy : mêmes champs logiques
|
|
10
|
+
* (`session_id` PK applicative, sacs `Attributes`/`flashBag`/`metaBag`,
|
|
11
|
+
* `user`). Les horodatages sont des **nombres** (ms epoch), comme l'adapter
|
|
12
|
+
* Drizzle, pour que `SessionStorage` reste strictement portable entre les ORM
|
|
13
|
+
* (cutoff GC = `updatedAt < now - ttl`, opérateur riche `$lt` natif Mongo).
|
|
14
|
+
*/
|
|
15
|
+
const schema = {
|
|
16
|
+
session_id: {
|
|
17
|
+
type: String,
|
|
18
|
+
index: true,
|
|
19
|
+
unique: true
|
|
20
|
+
},
|
|
21
|
+
Attributes: {
|
|
22
|
+
type: Object,
|
|
23
|
+
default: {}
|
|
24
|
+
},
|
|
25
|
+
flashBag: {
|
|
26
|
+
type: Object,
|
|
27
|
+
default: {}
|
|
28
|
+
},
|
|
29
|
+
metaBag: {
|
|
30
|
+
type: Object,
|
|
31
|
+
default: {}
|
|
32
|
+
},
|
|
33
|
+
user: {
|
|
34
|
+
type: String,
|
|
35
|
+
default: null
|
|
36
|
+
},
|
|
37
|
+
createdAt: { type: Number },
|
|
38
|
+
updatedAt: { type: Number }
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Entité session enregistrée dans le `entityRegistry` pour le connecteur
|
|
42
|
+
* `nodefony` — `MongooseOrm` compile le modèle à la connexion (au boot).
|
|
43
|
+
*
|
|
44
|
+
* ⚠️ **`frameworkEntities: false` ne la coupe PAS.** Ce commutateur gouverne les
|
|
45
|
+
* entités déclarées dans le flux de boot (tokens, webauthn, webhooks) ; la
|
|
46
|
+
* session, elle, s'enregistre à l'**import** de ce fichier — le décorateur
|
|
47
|
+
* `@entity` s'exécute au chargement du barrel, avant que la moindre config soit
|
|
48
|
+
* lue. Même chose pour son store (`SessionStorage.ts`, `registerStorage`).
|
|
49
|
+
*
|
|
50
|
+
* Conséquence pratique : couper `frameworkEntities` retire les autres entités,
|
|
51
|
+
* pas la collection `session`. Pour ne pas avoir de session Mongo du tout, il
|
|
52
|
+
* faut ne pas router le store session vers mongoose (`session.store`), pas
|
|
53
|
+
* baisser ce drapeau.
|
|
54
|
+
*/
|
|
55
|
+
let SessionEntity = class SessionEntity {};
|
|
56
|
+
SessionEntity = __decorate([entity({
|
|
57
|
+
connector: SESSION_CONNECTOR,
|
|
58
|
+
name: "session",
|
|
59
|
+
schema
|
|
60
|
+
})], SessionEntity);
|
|
61
|
+
var sessionEntity_default = SessionEntity;
|
|
62
|
+
//#endregion
|
|
63
|
+
export { SESSION_CONNECTOR, sessionEntity_default as default, schema as sessionSchema };
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { entityRegistry } from "@nodefony/orm-core";
|
|
2
|
+
//#region nodefony/entity/tokenEntity.ts
|
|
3
|
+
/**
|
|
4
|
+
* Schémas Mongoose du **store de jetons** `@nodefony/security` (pendant
|
|
5
|
+
* documentaire des tables Drizzle) — implémentation NoSQL d'`ITokenStore` (PAT,
|
|
6
|
+
* refresh, denylist `jti`, seuil de révocation en masse).
|
|
7
|
+
*
|
|
8
|
+
* ⚠️ **`_id` = clé naturelle (String), PAS un ObjectId auto** : le contrat
|
|
9
|
+
* `IRepository` traduit le critère `{ id }` en `{ _id }` (cf `MongooseRepository`).
|
|
10
|
+
* Comme l'`id` d'un jeton est un **jti fourni par l'appelant** (pas généré par
|
|
11
|
+
* Mongo), on force `_id: String` → le jti EST la clé primaire (gratuit : unique +
|
|
12
|
+
* éligible à un TTL index natif). Le virtuel `id` (activé par `MongooseOrm`,
|
|
13
|
+
* `toObject:{virtuals:true}`) renvoie `String(_id)` = le jti.
|
|
14
|
+
*
|
|
15
|
+
* ⚠️ **Horodatages = `Number` (epoch ms), `timestamps:false`** : `IAccessTokenRecord`
|
|
16
|
+
* porte des `number` (`Date.now()`) et l'appelant fournit `createdAt` → pas de
|
|
17
|
+
* gestion auto Mongoose. Le `gc()` applicatif reste portable (`$lte` exclut les
|
|
18
|
+
* `null` par type bracketing Mongo, comme Drizzle exclut `NULL`).
|
|
19
|
+
*/
|
|
20
|
+
const accessTokenSchema = {
|
|
21
|
+
_id: { type: String },
|
|
22
|
+
kind: {
|
|
23
|
+
type: String,
|
|
24
|
+
required: true
|
|
25
|
+
},
|
|
26
|
+
name: {
|
|
27
|
+
type: String,
|
|
28
|
+
required: true
|
|
29
|
+
},
|
|
30
|
+
prefix: {
|
|
31
|
+
type: String,
|
|
32
|
+
default: null
|
|
33
|
+
},
|
|
34
|
+
subjectId: {
|
|
35
|
+
type: String,
|
|
36
|
+
required: true,
|
|
37
|
+
index: true
|
|
38
|
+
},
|
|
39
|
+
subjectType: {
|
|
40
|
+
type: String,
|
|
41
|
+
required: true
|
|
42
|
+
},
|
|
43
|
+
tenantId: {
|
|
44
|
+
type: String,
|
|
45
|
+
default: null
|
|
46
|
+
},
|
|
47
|
+
scopes: {
|
|
48
|
+
type: [String],
|
|
49
|
+
default: []
|
|
50
|
+
},
|
|
51
|
+
audience: {
|
|
52
|
+
type: [String],
|
|
53
|
+
default: []
|
|
54
|
+
},
|
|
55
|
+
resources: {
|
|
56
|
+
type: Object,
|
|
57
|
+
default: null
|
|
58
|
+
},
|
|
59
|
+
secretHash: {
|
|
60
|
+
type: String,
|
|
61
|
+
required: true,
|
|
62
|
+
unique: true,
|
|
63
|
+
index: true
|
|
64
|
+
},
|
|
65
|
+
hashAlg: {
|
|
66
|
+
type: String,
|
|
67
|
+
required: true
|
|
68
|
+
},
|
|
69
|
+
clientId: {
|
|
70
|
+
type: String,
|
|
71
|
+
default: null
|
|
72
|
+
},
|
|
73
|
+
cnf: {
|
|
74
|
+
type: String,
|
|
75
|
+
default: null
|
|
76
|
+
},
|
|
77
|
+
family: {
|
|
78
|
+
type: String,
|
|
79
|
+
default: null,
|
|
80
|
+
index: true
|
|
81
|
+
},
|
|
82
|
+
replacedBy: {
|
|
83
|
+
type: String,
|
|
84
|
+
default: null
|
|
85
|
+
},
|
|
86
|
+
createdAt: {
|
|
87
|
+
type: Number,
|
|
88
|
+
required: true
|
|
89
|
+
},
|
|
90
|
+
expiresAt: {
|
|
91
|
+
type: Number,
|
|
92
|
+
default: null
|
|
93
|
+
},
|
|
94
|
+
lastUsedAt: {
|
|
95
|
+
type: Number,
|
|
96
|
+
default: null
|
|
97
|
+
},
|
|
98
|
+
lastUsedIp: {
|
|
99
|
+
type: String,
|
|
100
|
+
default: null
|
|
101
|
+
},
|
|
102
|
+
lastUsedUserAgent: {
|
|
103
|
+
type: String,
|
|
104
|
+
default: null
|
|
105
|
+
},
|
|
106
|
+
revokedAt: {
|
|
107
|
+
type: Number,
|
|
108
|
+
default: null
|
|
109
|
+
},
|
|
110
|
+
revokedReason: {
|
|
111
|
+
type: String,
|
|
112
|
+
default: null
|
|
113
|
+
},
|
|
114
|
+
metadata: {
|
|
115
|
+
type: Object,
|
|
116
|
+
default: {}
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
/** Denylist des access tokens (`jti` = `_id`) révoqués avant leur `exp`. */
|
|
120
|
+
const deniedJtiSchema = {
|
|
121
|
+
_id: { type: String },
|
|
122
|
+
expiresAt: {
|
|
123
|
+
type: Number,
|
|
124
|
+
required: true
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
/** Seuil de révocation en masse par porteur (`subjectId` = `_id`). */
|
|
128
|
+
const subjectRevocationSchema = {
|
|
129
|
+
_id: { type: String },
|
|
130
|
+
invalidBefore: {
|
|
131
|
+
type: Number,
|
|
132
|
+
required: true
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
/** Noms logiques des entités du store (clés de lookup `getRepository`). */
|
|
136
|
+
const TOKEN_ENTITY_NAMES = {
|
|
137
|
+
records: "access_token",
|
|
138
|
+
denied: "denied_jti",
|
|
139
|
+
revocations: "subject_revocation"
|
|
140
|
+
};
|
|
141
|
+
/**
|
|
142
|
+
* Construit les descripteurs d'entités du store de jetons pour un ORM nommé.
|
|
143
|
+
*
|
|
144
|
+
* Le `connector` est **dynamique** (nom du connecteur de l'app, ex. `"nodefony"`) : les
|
|
145
|
+
* schémas sont statiques mais leur liaison à un ORM dépend de la config → pas
|
|
146
|
+
* d'`@entity` figé (parité `createUserEntity`). `timestamps:false` (l'appelant
|
|
147
|
+
* gère `createdAt`). À enregistrer **avant** `orm.connect()`.
|
|
148
|
+
*
|
|
149
|
+
* @param orm - clé de l'ORM cible dans le `ormRegistry`.
|
|
150
|
+
* @returns les trois descripteurs {@link IEntity} (records / denylist / seuils).
|
|
151
|
+
*/
|
|
152
|
+
function createTokenEntities(connector) {
|
|
153
|
+
return [
|
|
154
|
+
{
|
|
155
|
+
connector,
|
|
156
|
+
name: TOKEN_ENTITY_NAMES.records,
|
|
157
|
+
module: "security",
|
|
158
|
+
schema: accessTokenSchema
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
connector,
|
|
162
|
+
name: TOKEN_ENTITY_NAMES.denied,
|
|
163
|
+
module: "security",
|
|
164
|
+
schema: deniedJtiSchema
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
connector,
|
|
168
|
+
name: TOKEN_ENTITY_NAMES.revocations,
|
|
169
|
+
module: "security",
|
|
170
|
+
schema: subjectRevocationSchema
|
|
171
|
+
}
|
|
172
|
+
];
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Enregistre les entités du store de jetons dans le `entityRegistry` pour un ORM
|
|
176
|
+
* donné. À appeler **avant** `orm.connect()` (le modèle est compilé au connect).
|
|
177
|
+
*
|
|
178
|
+
* @param connector - nom de la connexion cible (clé du registre).
|
|
179
|
+
*/
|
|
180
|
+
function registerTokenEntities(connector) {
|
|
181
|
+
for (const entity of createTokenEntities(connector)) entityRegistry.register(entity);
|
|
182
|
+
}
|
|
183
|
+
//#endregion
|
|
184
|
+
export { TOKEN_ENTITY_NAMES, accessTokenSchema, createTokenEntities, deniedJtiSchema, registerTokenEntities, subjectRevocationSchema };
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { entityRegistry } from "@nodefony/orm-core";
|
|
2
|
+
import { USER_COLUMNS } from "@nodefony/user";
|
|
3
|
+
//#region nodefony/entity/userEntity.ts
|
|
4
|
+
/**
|
|
5
|
+
* Traduction d'un type LOGIQUE du contrat utilisateur vers un type Mongoose.
|
|
6
|
+
*
|
|
7
|
+
* C'est le seul endroit du module document qui connaisse ce vocabulaire : le
|
|
8
|
+
* contrat dit ce que la donnée EST, ce fichier dit comment un document la range.
|
|
9
|
+
* `object[]` reste un `Array` LIBRE — pas un sous-schéma : c'est ce qui permet
|
|
10
|
+
* d'accueillir un nouveau fournisseur d'identité sans migration.
|
|
11
|
+
*/
|
|
12
|
+
const TYPE_BY_COLUMN = {
|
|
13
|
+
uuid: String,
|
|
14
|
+
string: String,
|
|
15
|
+
"string[]": [String],
|
|
16
|
+
boolean: Boolean,
|
|
17
|
+
object: Object,
|
|
18
|
+
"object[]": Array,
|
|
19
|
+
date: Date
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Construit la définition Mongoose d'une colonne du contrat utilisateur.
|
|
23
|
+
*
|
|
24
|
+
* Un défaut structuré est passé en FABRIQUE, jamais en valeur : Mongoose
|
|
25
|
+
* partagerait sinon le même tableau entre tous les documents. Une colonne
|
|
26
|
+
* facultative reçoit `null` explicite plutôt que rien, pour qu'un document
|
|
27
|
+
* ancien et un document neuf se lisent pareil. Une colonne obligatoire QUI A un
|
|
28
|
+
* défaut n'est pas `required` : la valeur ne peut pas manquer, l'exiger de
|
|
29
|
+
* l'appelant n'ajouterait qu'un refus.
|
|
30
|
+
*/
|
|
31
|
+
function toFieldDefinition(column) {
|
|
32
|
+
const base = {
|
|
33
|
+
type: TYPE_BY_COLUMN[column.type],
|
|
34
|
+
...column.nullable || column.makeDefault ? {} : { required: true },
|
|
35
|
+
...column.unique ? {
|
|
36
|
+
unique: true,
|
|
37
|
+
index: true
|
|
38
|
+
} : {}
|
|
39
|
+
};
|
|
40
|
+
if (column.makeDefault) return {
|
|
41
|
+
...base,
|
|
42
|
+
default: column.makeDefault
|
|
43
|
+
};
|
|
44
|
+
if (column.nullable) return {
|
|
45
|
+
...base,
|
|
46
|
+
default: null
|
|
47
|
+
};
|
|
48
|
+
return base;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Schéma Mongoose de l'utilisateur Nodefony — implémentation NoSQL du contrat
|
|
52
|
+
* `@nodefony/user`, **dérivée** de `USER_COLUMNS` (pendant documentaire de
|
|
53
|
+
* `userTable`).
|
|
54
|
+
*
|
|
55
|
+
* Rien n'est recopié : noms, types logiques, défauts et unicité viennent du
|
|
56
|
+
* contrat, et `tests/unit/userContractParity.test.ts` refuse le contraire.
|
|
57
|
+
*
|
|
58
|
+
* Deux origines du contrat ne sont pas déclarées ici, et c'est voulu : la clé
|
|
59
|
+
* primaire est `_id` (ObjectId), servie au contrat `id: string` par le
|
|
60
|
+
* **virtuel `id`** activé à la sérialisation par `MongooseOrm`
|
|
61
|
+
* (`toObject/toJSON: { virtuals: true }`) ; les horodatages sont gérés par
|
|
62
|
+
* l'option `timestamps: true` du descripteur. Le moteur les fournit — les
|
|
63
|
+
* redéclarer les mettrait en concurrence avec lui.
|
|
64
|
+
*/
|
|
65
|
+
const userSchema = Object.fromEntries(USER_COLUMNS.filter((column) => column.origin === "column").map((column) => [column.name, toFieldDefinition(column)]));
|
|
66
|
+
/**
|
|
67
|
+
* Les colonnes du contrat qu'un schéma DOCUMENT porte EN PROPRE.
|
|
68
|
+
*
|
|
69
|
+
* Dérivée de {@link userSchema}, jamais recopiée : ce que le framework exige de
|
|
70
|
+
* l'entité d'une application est exactement ce qu'il produit pour la sienne. La
|
|
71
|
+
* clé (`_id` + virtuel `id`) et les horodatages (option `timestamps`) restent
|
|
72
|
+
* donc hors de cette liste — les exiger comme chemins refuserait une entité
|
|
73
|
+
* parfaitement correcte, et un refus faux apprend à passer outre les refus.
|
|
74
|
+
*/
|
|
75
|
+
const DOCUMENT_USER_COLUMNS = USER_COLUMNS.filter((column) => Object.prototype.hasOwnProperty.call(userSchema, column.name));
|
|
76
|
+
/**
|
|
77
|
+
* Construit le descripteur d'entité `User` Mongoose pour un ORM nommé.
|
|
78
|
+
*
|
|
79
|
+
* Le `connector` est **dynamique** (nom du connecteur de l'app, ex. `"nodefony"`) : le
|
|
80
|
+
* schéma est statique mais sa liaison à un ORM dépend de la config → pas d'`@entity`
|
|
81
|
+
* figé (parité avec `createUserEntity` Drizzle). À enregistrer **avant**
|
|
82
|
+
* `orm.connect()` (le modèle est compilé à la connexion par `MongooseOrm`).
|
|
83
|
+
*
|
|
84
|
+
* @param orm - clé de l'ORM cible dans le `ormRegistry`.
|
|
85
|
+
* @returns descripteur {@link IEntity} (`name: "User"`, `timestamps: true`).
|
|
86
|
+
*/
|
|
87
|
+
function createUserEntity(connector) {
|
|
88
|
+
return {
|
|
89
|
+
connector,
|
|
90
|
+
name: "User",
|
|
91
|
+
module: "user",
|
|
92
|
+
schema: userSchema,
|
|
93
|
+
timestamps: true
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Enregistre l'entité `User` Mongoose dans le `entityRegistry` pour un ORM donné.
|
|
98
|
+
* À appeler **avant** `orm.connect()` (le modèle est compilé au connect).
|
|
99
|
+
*
|
|
100
|
+
* @param connector - nom de la connexion cible (clé du registre).
|
|
101
|
+
*/
|
|
102
|
+
function registerUserEntity(connector) {
|
|
103
|
+
entityRegistry.register(createUserEntity(connector));
|
|
104
|
+
}
|
|
105
|
+
//#endregion
|
|
106
|
+
export { DOCUMENT_USER_COLUMNS, createUserEntity, registerUserEntity, userSchema };
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { entityRegistry } from "@nodefony/orm-core";
|
|
2
|
+
//#region nodefony/entity/webAuthnCredentialEntity.ts
|
|
3
|
+
/**
|
|
4
|
+
* Schéma Mongoose du **store de credentials WebAuthn** `@nodefony/security`
|
|
5
|
+
* (pendant documentaire de la table Drizzle) — implémentation NoSQL d'
|
|
6
|
+
* `IWebAuthnCredentialStore` (passkeys).
|
|
7
|
+
*
|
|
8
|
+
* ⚠️ **`_id` = clé naturelle (String), PAS un ObjectId auto** : le contrat
|
|
9
|
+
* `IRepository` traduit le critère `{ id }` en `{ _id }` (cf `MongooseRepository`).
|
|
10
|
+
* Comme l'`id` d'un credential est un **identifiant base64url fourni par
|
|
11
|
+
* l'authenticator** (pas généré par Mongo), on force `_id: String` → le
|
|
12
|
+
* credentialId EST la clé primaire. Le virtuel `id` (activé par `MongooseOrm`,
|
|
13
|
+
* `toObject:{virtuals:true}`) renvoie `String(_id)` = le credentialId.
|
|
14
|
+
*
|
|
15
|
+
* ⚠️ **Horodatages = `Number` (epoch ms), `timestamps:false`** : `IWebAuthnCredential`
|
|
16
|
+
* porte des `number` (`Date.now()`) et l'appelant fournit `createdAt`.
|
|
17
|
+
*
|
|
18
|
+
* Le store ne lit/écrit JAMAIS `IWebAuthnCredential` directement : il traduit via
|
|
19
|
+
* {@link WebAuthnCredentialRow} (forme plate, `nickname: string | null`) — le
|
|
20
|
+
* contrat porte un `nickname?` optionnel et des champs `readonly`, que la
|
|
21
|
+
* frontière de persistance normalise.
|
|
22
|
+
*/
|
|
23
|
+
const webAuthnCredentialSchema = {
|
|
24
|
+
_id: { type: String },
|
|
25
|
+
userId: {
|
|
26
|
+
type: String,
|
|
27
|
+
required: true,
|
|
28
|
+
index: true
|
|
29
|
+
},
|
|
30
|
+
publicKey: {
|
|
31
|
+
type: String,
|
|
32
|
+
required: true
|
|
33
|
+
},
|
|
34
|
+
signCount: {
|
|
35
|
+
type: Number,
|
|
36
|
+
required: true
|
|
37
|
+
},
|
|
38
|
+
transports: {
|
|
39
|
+
type: [String],
|
|
40
|
+
default: []
|
|
41
|
+
},
|
|
42
|
+
backupEligible: {
|
|
43
|
+
type: Boolean,
|
|
44
|
+
required: true
|
|
45
|
+
},
|
|
46
|
+
backupState: {
|
|
47
|
+
type: Boolean,
|
|
48
|
+
required: true
|
|
49
|
+
},
|
|
50
|
+
uvInitialized: {
|
|
51
|
+
type: Boolean,
|
|
52
|
+
required: true
|
|
53
|
+
},
|
|
54
|
+
nickname: {
|
|
55
|
+
type: String,
|
|
56
|
+
default: null
|
|
57
|
+
},
|
|
58
|
+
createdAt: {
|
|
59
|
+
type: Number,
|
|
60
|
+
required: true
|
|
61
|
+
},
|
|
62
|
+
lastUsedAt: {
|
|
63
|
+
type: Number,
|
|
64
|
+
default: null
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
/** Nom logique de l'entité (clé de lookup `getRepository`). */
|
|
68
|
+
const WEBAUTHN_CREDENTIAL_ENTITY = "webauthn_credential";
|
|
69
|
+
/**
|
|
70
|
+
* Construit le descripteur d'entité du store de credentials pour un ORM nommé.
|
|
71
|
+
*
|
|
72
|
+
* Le `connector` est **dynamique** (nom du connecteur de l'app, ex. `"nodefony"`) : le
|
|
73
|
+
* schéma est statique mais sa liaison à un ORM dépend de la config → pas d'`@entity`
|
|
74
|
+
* figé (parité `createTokenEntities`). `timestamps:false`. À enregistrer **avant**
|
|
75
|
+
* `orm.connect()`.
|
|
76
|
+
*
|
|
77
|
+
* @param orm - clé de l'ORM cible dans le `ormRegistry`.
|
|
78
|
+
*/
|
|
79
|
+
function createWebAuthnCredentialEntity(connector) {
|
|
80
|
+
return {
|
|
81
|
+
connector,
|
|
82
|
+
name: WEBAUTHN_CREDENTIAL_ENTITY,
|
|
83
|
+
module: "security",
|
|
84
|
+
schema: webAuthnCredentialSchema
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Enregistre l'entité du store de credentials dans le `entityRegistry` pour un
|
|
89
|
+
* ORM donné. À appeler **avant** `orm.connect()` (le modèle est compilé au connect).
|
|
90
|
+
*
|
|
91
|
+
* @param connector - nom de la connexion cible (clé du registre).
|
|
92
|
+
*/
|
|
93
|
+
function registerWebAuthnCredentialEntity(connector) {
|
|
94
|
+
entityRegistry.register(createWebAuthnCredentialEntity(connector));
|
|
95
|
+
}
|
|
96
|
+
//#endregion
|
|
97
|
+
export { WEBAUTHN_CREDENTIAL_ENTITY, createWebAuthnCredentialEntity, registerWebAuthnCredentialEntity, webAuthnCredentialSchema };
|