@mostajs/setup 2.1.9 → 2.1.10
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/dist/lib/setup.js +87 -15
- package/package.json +1 -1
package/dist/lib/setup.js
CHANGED
|
@@ -142,20 +142,61 @@ async function runNetInstall(installConfig, setupConfig) {
|
|
|
142
142
|
if (!health.entities?.length) {
|
|
143
143
|
return { ok: false, error: 'Serveur NET accessible mais aucun schema chargé', needsRestart: false };
|
|
144
144
|
}
|
|
145
|
-
// 3. Seed RBAC via REST
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
145
|
+
// 3. Seed RBAC via NET REST
|
|
146
|
+
// Read setup.json directly to get RBAC definitions
|
|
147
|
+
const fs = await import('fs');
|
|
148
|
+
const path = await import('path');
|
|
149
|
+
let setupJson = null;
|
|
150
|
+
const setupJsonPath = path.resolve(process.cwd(), 'setup.json');
|
|
151
|
+
if (fs.existsSync(setupJsonPath)) {
|
|
152
|
+
try {
|
|
153
|
+
setupJson = JSON.parse(fs.readFileSync(setupJsonPath, 'utf-8'));
|
|
154
|
+
}
|
|
155
|
+
catch { }
|
|
156
|
+
}
|
|
157
|
+
if (setupJson?.rbac) {
|
|
158
|
+
const rbac = setupJson.rbac;
|
|
159
|
+
// 3a. Upsert categories
|
|
160
|
+
if (rbac.categories?.length) {
|
|
161
|
+
for (const cat of rbac.categories) {
|
|
162
|
+
await net.upsert('permission_categories', { name: cat.name }, {
|
|
163
|
+
name: cat.name, label: cat.label, description: cat.description ?? '',
|
|
164
|
+
icon: cat.icon ?? '', order: cat.order ?? 0, system: cat.system ?? true,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
seeded.push('categories');
|
|
168
|
+
}
|
|
169
|
+
// 3b. Upsert permissions — build code→ID map
|
|
170
|
+
const permissionMap = {};
|
|
171
|
+
if (rbac.permissions?.length) {
|
|
172
|
+
for (const pDef of rbac.permissions) {
|
|
173
|
+
const displayName = pDef.name ?? pDef.code;
|
|
174
|
+
const perm = await net.upsert('permissions', { name: displayName }, {
|
|
175
|
+
name: displayName, description: pDef.description, category: pDef.category,
|
|
176
|
+
});
|
|
177
|
+
permissionMap[pDef.code] = perm.id;
|
|
178
|
+
}
|
|
179
|
+
seeded.push('permissions');
|
|
180
|
+
}
|
|
181
|
+
// 3c. Upsert roles with permission IDs
|
|
182
|
+
if (rbac.roles?.length) {
|
|
183
|
+
const allPermIds = Object.values(permissionMap);
|
|
184
|
+
for (const roleDef of rbac.roles) {
|
|
185
|
+
const permissionIds = roleDef.permissions.includes('*')
|
|
186
|
+
? allPermIds
|
|
187
|
+
: roleDef.permissions.map((code) => permissionMap[code]).filter(Boolean);
|
|
188
|
+
await net.upsert('roles', { name: roleDef.name }, {
|
|
189
|
+
name: roleDef.name, description: roleDef.description ?? '', permissions: permissionIds,
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
seeded.push('roles');
|
|
193
|
+
}
|
|
152
194
|
}
|
|
153
|
-
// 4. Create admin user via REST
|
|
195
|
+
// 4. Create admin user via NET REST
|
|
154
196
|
if (installConfig.admin.email) {
|
|
155
197
|
const bcryptModule = await import('bcryptjs');
|
|
156
198
|
const bcrypt = bcryptModule.default || bcryptModule;
|
|
157
199
|
const hashedPassword = await bcrypt.hash(installConfig.admin.password, 12);
|
|
158
|
-
// Find admin role
|
|
159
200
|
const adminRole = await net.findOne('roles', { name: 'admin' });
|
|
160
201
|
await net.create('users', {
|
|
161
202
|
email: installConfig.admin.email,
|
|
@@ -167,13 +208,44 @@ async function runNetInstall(installConfig, setupConfig) {
|
|
|
167
208
|
});
|
|
168
209
|
seeded.push('admin');
|
|
169
210
|
}
|
|
170
|
-
// 5. Optional seeds via REST
|
|
171
|
-
if (
|
|
172
|
-
for (const seedDef of
|
|
173
|
-
if (installConfig.seed[seedDef.key])
|
|
174
|
-
|
|
175
|
-
|
|
211
|
+
// 5. Optional seeds via NET REST
|
|
212
|
+
if (setupJson?.seeds && installConfig.seed) {
|
|
213
|
+
for (const seedDef of setupJson.seeds) {
|
|
214
|
+
if (!installConfig.seed[seedDef.key])
|
|
215
|
+
continue;
|
|
216
|
+
// Resolve lookupFields
|
|
217
|
+
const resolved = {};
|
|
218
|
+
if (seedDef.lookupFields) {
|
|
219
|
+
for (const [field, lookup] of Object.entries(seedDef.lookupFields)) {
|
|
220
|
+
const found = await net.findOne(lookup.collection, { [lookup.match]: lookup.value });
|
|
221
|
+
if (found)
|
|
222
|
+
resolved[field] = found.id;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
for (const rawItem of seedDef.data) {
|
|
226
|
+
const item = { ...(seedDef.defaults ?? {}), ...resolved, ...rawItem };
|
|
227
|
+
// Hash field if configured
|
|
228
|
+
if (seedDef.hashField && item[seedDef.hashField]) {
|
|
229
|
+
const bcryptModule = await import('bcryptjs');
|
|
230
|
+
const bcrypt = bcryptModule.default || bcryptModule;
|
|
231
|
+
item[seedDef.hashField] = await bcrypt.hash(String(item[seedDef.hashField]), 12);
|
|
232
|
+
}
|
|
233
|
+
// Resolve role name → role ID
|
|
234
|
+
if (seedDef.roleField && item[seedDef.roleField]) {
|
|
235
|
+
const role = await net.findOne('roles', { name: String(item[seedDef.roleField]) });
|
|
236
|
+
if (role)
|
|
237
|
+
item.roles = [role.id];
|
|
238
|
+
delete item[seedDef.roleField];
|
|
239
|
+
}
|
|
240
|
+
// Upsert or create
|
|
241
|
+
if (seedDef.match) {
|
|
242
|
+
await net.upsert(seedDef.collection, { [seedDef.match]: item[seedDef.match] }, item);
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
await net.create(seedDef.collection, item);
|
|
246
|
+
}
|
|
176
247
|
}
|
|
248
|
+
seeded.push(seedDef.key);
|
|
177
249
|
}
|
|
178
250
|
}
|
|
179
251
|
return { ok: true, needsRestart: false, seeded };
|
package/package.json
CHANGED