@mostajs/setup 2.1.24 → 2.1.27

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.
@@ -8,10 +8,11 @@ import { runInstall } from '../lib/setup.js';
8
8
  */
9
9
  export function createInstallHandler(needsSetup, setupConfig) {
10
10
  async function POST(req) {
11
- if (!(await needsSetup())) {
12
- return Response.json({ error: 'Already installed' }, { status: 400 });
13
- }
14
11
  const body = await req.json();
12
+ // Skip needsSetup check if admin was already created (wizard creates admin before seed)
13
+ if (!body.skipCheck && !(await needsSetup())) {
14
+ return Response.json({ ok: false, error: 'Installation deja effectuee' }, { status: 400 });
15
+ }
15
16
  const result = await runInstall(body, setupConfig);
16
17
  return Response.json(result);
17
18
  }
@@ -749,6 +749,7 @@ export default function SetupWizard({ t: tProp, onComplete, endpoints = {}, dbNa
749
749
  admin: { email: adminConfig.email, password: adminConfig.password, firstName: adminConfig.firstName, lastName: adminConfig.lastName },
750
750
  seed: seedOptions,
751
751
  modules: selectedModules,
752
+ skipCheck: adminSaveResult?.ok || false, // Skip needsSetup check if admin was created via wizard
752
753
  }),
753
754
  });
754
755
  const data = await safeJson(res);
package/dist/lib/setup.js CHANGED
@@ -73,14 +73,50 @@ export async function runInstall(installConfig, setupConfig) {
73
73
  // 4. Disconnect existing dialect singleton
74
74
  const { disconnectDialect } = await import('@mostajs/orm');
75
75
  await disconnectDialect();
76
- // 4. Seed RBAC
77
76
  const seeded = [];
78
- if (setupConfig.seedRBAC) {
79
- await setupConfig.seedRBAC();
80
- seeded.push('categories', 'permissions', 'roles');
77
+ // 4. Discover modules and seed RBAC
78
+ const { discoverModules } = await import('./module-registry.js');
79
+ const modules = await discoverModules(installConfig.modules);
80
+ // 4a. Read setup.json for RBAC + seed data
81
+ const fs = await import('fs');
82
+ const path = await import('path');
83
+ let setupJson = null;
84
+ const setupJsonPath = path.resolve(process.cwd(), 'setup.json');
85
+ if (fs.existsSync(setupJsonPath)) {
86
+ try {
87
+ setupJson = JSON.parse(fs.readFileSync(setupJsonPath, 'utf-8'));
88
+ }
89
+ catch { }
90
+ }
91
+ // 4b. Seed each module (RBAC gets setup.json.rbac data from Studio)
92
+ for (const mod of modules) {
93
+ try {
94
+ const seedData = setupJson?.[mod.name] || {};
95
+ await mod.seed(seedData);
96
+ seeded.push(mod.name);
97
+ }
98
+ catch (err) {
99
+ console.error(`[Setup] Module "${mod.name}" seed failed:`, err);
100
+ }
101
+ }
102
+ // 5. Create admin via rbac module (not setup — rbac handles hash + role)
103
+ const rbacModule = modules.find(m => m.createAdmin);
104
+ if (rbacModule && installConfig.admin?.email) {
105
+ try {
106
+ await rbacModule.createAdmin({
107
+ email: installConfig.admin.email,
108
+ password: installConfig.admin.password,
109
+ firstName: installConfig.admin.firstName,
110
+ lastName: installConfig.admin.lastName,
111
+ });
112
+ seeded.push('admin');
113
+ }
114
+ catch (err) {
115
+ console.error('[Setup] createAdmin failed:', err);
116
+ }
81
117
  }
82
- // 5. Create admin user
83
- if (setupConfig.createAdmin) {
118
+ else if (setupConfig.createAdmin) {
119
+ // Legacy fallback — app provides its own createAdmin
84
120
  const bcryptModule = await import('bcryptjs');
85
121
  const bcrypt = bcryptModule.default || bcryptModule;
86
122
  const hashedPassword = await bcrypt.hash(installConfig.admin.password, 12);
@@ -92,16 +128,17 @@ export async function runInstall(installConfig, setupConfig) {
92
128
  });
93
129
  seeded.push('admin');
94
130
  }
95
- // 6. Optional seeds (runtime registry or legacy)
96
- if (setupConfig.runModuleSeeds) {
97
- await setupConfig.runModuleSeeds(installConfig.modules);
98
- seeded.push('module-seeds');
99
- }
100
- else if (setupConfig.optionalSeeds && installConfig.seed) {
131
+ // 6. Optional seeds from setup.json (app-specific: activities, clients, plans)
132
+ if (setupConfig.optionalSeeds && installConfig.seed) {
101
133
  for (const seedDef of setupConfig.optionalSeeds) {
102
134
  if (installConfig.seed[seedDef.key]) {
103
- await seedDef.run({});
104
- seeded.push(seedDef.key);
135
+ try {
136
+ await seedDef.run({});
137
+ seeded.push(seedDef.key);
138
+ }
139
+ catch (err) {
140
+ console.error(`[Setup] Seed "${seedDef.key}" failed:`, err);
141
+ }
105
142
  }
106
143
  }
107
144
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mostajs/setup",
3
- "version": "2.1.24",
3
+ "version": "2.1.27",
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",