@mostajs/setup 2.1.3 → 2.1.5

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/README.md CHANGED
@@ -1123,6 +1123,59 @@ Puis recompilez : `cd packages/mosta-setup && npx tsc`
1123
1123
  | [@mostajs/settings](https://www.npmjs.com/package/@mostajs/settings) | oui | non | Parametres cle-valeur |
1124
1124
  | [@mostajs/face](https://www.npmjs.com/package/@mostajs/face) | **non** | **oui** | Reconnaissance faciale (independant) |
1125
1125
 
1126
+ ## Catch-all Route Factory (createSetupRoutes)
1127
+
1128
+ Replace 6+ individual route files with a single `[...slug]` handler :
1129
+
1130
+ ```typescript
1131
+ // src/app/api/setup/[...slug]/route.ts — 7 lines replaces 6 files
1132
+ import { createSetupRoutes } from '@mostajs/setup'
1133
+ import { appNeedsSetup, getSetupConfig } from '@/lib/setup-config'
1134
+
1135
+ export const { GET, POST, DELETE, PATCH } = createSetupRoutes({
1136
+ needsSetup: appNeedsSetup,
1137
+ getSetupConfig,
1138
+ })
1139
+ ```
1140
+
1141
+ Handles all 11 setup endpoints : status, test-db, create-db, preflight, detect-modules, install-modules, setup-json, upload-jar, wire-module, reconfig, install.
1142
+
1143
+ ## createAdmin (auto-generated)
1144
+
1145
+ `loadSetupJson()` automatically generates a `createAdmin` callback that :
1146
+ 1. Gets the `user` repo via `repoFactory`
1147
+ 2. Gets the `role` repo to resolve the `admin` role
1148
+ 3. Creates the admin user with bcrypt-hashed password and admin role
1149
+
1150
+ No need to define `createAdmin` manually — it comes from `loadSetupJson()`.
1151
+
1152
+ ## lookupFields (cross-entity references in seeds)
1153
+
1154
+ Resolve a field value from another collection before inserting seed data :
1155
+
1156
+ ```json
1157
+ {
1158
+ "key": "demoClients",
1159
+ "collection": "client",
1160
+ "lookupFields": {
1161
+ "createdBy": { "collection": "user", "match": "status", "value": "active" }
1162
+ },
1163
+ "data": [
1164
+ { "firstName": "Samir", "lastName": "Boudjema", "phone": "0550100001" }
1165
+ ]
1166
+ }
1167
+ ```
1168
+
1169
+ `lookupFields.createdBy` : find the first `user` where `status = "active"`, inject its `id` as `createdBy` in every data item.
1170
+
1171
+ Useful for seeds that reference entities created by earlier seeds (RBAC roles, admin user, etc.).
1172
+
1173
+ ## Dynamic Seeds in SetupWizard
1174
+
1175
+ The wizard automatically loads available seeds from the `/api/setup/setup-json` endpoint and displays them as checkboxes. Seeds with `"default": true` in setup.json are pre-checked.
1176
+
1177
+ No need to hardcode seed checkboxes — add a seed to `setup.json` and it appears in the wizard automatically.
1178
+
1126
1179
  ## License
1127
1180
 
1128
- MIT — (c) 2025 Dr Hamid MADANI <drmdh@msn.com>
1181
+ MIT — (c) 2025-2026 Dr Hamid MADANI <drmdh@msn.com>
@@ -35,6 +35,11 @@ export interface SetupJsonSeed {
35
35
  hashField?: string;
36
36
  roleField?: string;
37
37
  defaults?: Record<string, unknown>;
38
+ lookupFields?: Record<string, {
39
+ collection: string;
40
+ match: string;
41
+ value: string;
42
+ }>;
38
43
  data: Record<string, unknown>[];
39
44
  }
40
45
  export interface SetupJson {
@@ -134,8 +134,18 @@ function buildSeedDefinition(seedDef, repoFactory) {
134
134
  run: async () => {
135
135
  const getRepo = repoFactory ?? defaultRepoFactory;
136
136
  const repo = await getRepo(seedDef.collection);
137
+ // Resolve lookupFields once (e.g. createdBy → user where email = admin@test.dz → userId)
138
+ const resolved = {};
139
+ if (seedDef.lookupFields) {
140
+ for (const [field, lookup] of Object.entries(seedDef.lookupFields)) {
141
+ const lookupRepo = await getRepo(lookup.collection);
142
+ const found = await lookupRepo.findOne({ [lookup.match]: lookup.value });
143
+ if (found)
144
+ resolved[field] = found.id;
145
+ }
146
+ }
137
147
  for (const rawItem of seedDef.data) {
138
- const item = { ...(seedDef.defaults ?? {}), ...rawItem };
148
+ const item = { ...(seedDef.defaults ?? {}), ...resolved, ...rawItem };
139
149
  // Hash field if configured (e.g. password)
140
150
  if (seedDef.hashField && item[seedDef.hashField]) {
141
151
  const bcryptModule = await import('bcryptjs');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mostajs/setup",
3
- "version": "2.1.3",
3
+ "version": "2.1.5",
4
4
  "description": "Reusable setup wizard module — multi-dialect DB configuration, .env.local writer, seed runner",
5
5
  "author": "Dr Hamid MADANI <drmdh@msn.com>",
6
6
  "license": "MIT",