@mostajs/setup 2.1.10 → 2.1.12
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/index.js +1 -1
- package/dist/lib/net-client.d.ts +5 -0
- package/dist/lib/net-client.js +30 -4
- package/dist/lib/setup.js +43 -5
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -13,7 +13,7 @@ export { discoverNpmModules } from './lib/discover-modules.js';
|
|
|
13
13
|
export { loadSetupJson } from './lib/load-setup-json.js';
|
|
14
14
|
// Catch-all route factory (replaces individual route files in host app)
|
|
15
15
|
export { createSetupRoutes } from './api/routes.js';
|
|
16
|
-
// NET client (
|
|
16
|
+
// NET client (setup-specific, with loadCollectionMap + resolveCollection)
|
|
17
17
|
export { NetClient } from './lib/net-client.js';
|
|
18
18
|
// API route factories (individual — still available for granular use)
|
|
19
19
|
export { createTestDbHandler } from './api/test-db.route.js';
|
package/dist/lib/net-client.d.ts
CHANGED
|
@@ -14,7 +14,12 @@ export interface NetHealthResponse {
|
|
|
14
14
|
export declare class NetClient {
|
|
15
15
|
private baseUrl;
|
|
16
16
|
private headers;
|
|
17
|
+
private collectionMap;
|
|
17
18
|
constructor(config: NetClientConfig);
|
|
19
|
+
/** Load schema config and build collection name mapping */
|
|
20
|
+
loadCollectionMap(): Promise<void>;
|
|
21
|
+
/** Resolve a seed collection name to the actual REST collection */
|
|
22
|
+
private resolveCollection;
|
|
18
23
|
/** Test connectivity to the NET server */
|
|
19
24
|
health(): Promise<NetHealthResponse>;
|
|
20
25
|
/** Test database connection via NET */
|
package/dist/lib/net-client.js
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
export class NetClient {
|
|
9
9
|
baseUrl;
|
|
10
10
|
headers;
|
|
11
|
+
collectionMap = {}; // seedName → REST collection
|
|
11
12
|
constructor(config) {
|
|
12
13
|
this.baseUrl = config.url.replace(/\/$/, '');
|
|
13
14
|
this.headers = { 'Content-Type': 'application/json' };
|
|
@@ -15,6 +16,27 @@ export class NetClient {
|
|
|
15
16
|
this.headers['Authorization'] = `Bearer ${config.apiKey}`;
|
|
16
17
|
}
|
|
17
18
|
}
|
|
19
|
+
/** Load schema config and build collection name mapping */
|
|
20
|
+
async loadCollectionMap() {
|
|
21
|
+
try {
|
|
22
|
+
const config = await this.getSchemasConfig();
|
|
23
|
+
for (const s of config.schemas || []) {
|
|
24
|
+
// Map: entity name lowercase → actual collection
|
|
25
|
+
// e.g. "Experience" → "experiences", "PermissionCategory" → "permission_categories"
|
|
26
|
+
this.collectionMap[s.name.toLowerCase()] = s.collection;
|
|
27
|
+
// Also map collection without trailing 's' → actual collection
|
|
28
|
+
// e.g. "experience" → "experiences", "passenger" → "passengers"
|
|
29
|
+
const singular = s.collection.replace(/s$/, '').replace(/ies$/, 'y');
|
|
30
|
+
this.collectionMap[singular] = s.collection;
|
|
31
|
+
this.collectionMap[s.collection] = s.collection;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch { }
|
|
35
|
+
}
|
|
36
|
+
/** Resolve a seed collection name to the actual REST collection */
|
|
37
|
+
resolveCollection(name) {
|
|
38
|
+
return this.collectionMap[name] || this.collectionMap[name.toLowerCase()] || name;
|
|
39
|
+
}
|
|
18
40
|
// ── Health & Status ──────────────────────────────
|
|
19
41
|
/** Test connectivity to the NET server */
|
|
20
42
|
async health() {
|
|
@@ -47,7 +69,8 @@ export class NetClient {
|
|
|
47
69
|
// ── CRUD ─────────────────────────────────────────
|
|
48
70
|
/** Create an entity via REST */
|
|
49
71
|
async create(collection, data) {
|
|
50
|
-
const
|
|
72
|
+
const col = this.resolveCollection(collection);
|
|
73
|
+
const res = await fetch(`${this.baseUrl}/api/v1/${col}`, {
|
|
51
74
|
method: 'POST',
|
|
52
75
|
headers: this.headers,
|
|
53
76
|
body: JSON.stringify(data),
|
|
@@ -59,8 +82,9 @@ export class NetClient {
|
|
|
59
82
|
}
|
|
60
83
|
/** Find one entity by filter */
|
|
61
84
|
async findOne(collection, filter) {
|
|
85
|
+
const col = this.resolveCollection(collection);
|
|
62
86
|
const params = new URLSearchParams({ filter: JSON.stringify(filter), limit: '1' });
|
|
63
|
-
const res = await fetch(`${this.baseUrl}/api/v1/${
|
|
87
|
+
const res = await fetch(`${this.baseUrl}/api/v1/${col}?${params}`, { headers: this.headers });
|
|
64
88
|
const json = await res.json();
|
|
65
89
|
if (json.status === 'error')
|
|
66
90
|
return null;
|
|
@@ -69,9 +93,10 @@ export class NetClient {
|
|
|
69
93
|
}
|
|
70
94
|
/** Upsert: find by filter, update if exists, create if not */
|
|
71
95
|
async upsert(collection, filter, data) {
|
|
96
|
+
const col = this.resolveCollection(collection);
|
|
72
97
|
const existing = await this.findOne(collection, filter);
|
|
73
98
|
if (existing) {
|
|
74
|
-
const res = await fetch(`${this.baseUrl}/api/v1/${
|
|
99
|
+
const res = await fetch(`${this.baseUrl}/api/v1/${col}/${existing.id}`, {
|
|
75
100
|
method: 'PUT',
|
|
76
101
|
headers: this.headers,
|
|
77
102
|
body: JSON.stringify(data),
|
|
@@ -85,8 +110,9 @@ export class NetClient {
|
|
|
85
110
|
}
|
|
86
111
|
/** Count entities in a collection */
|
|
87
112
|
async count(collection, filter) {
|
|
113
|
+
const col = this.resolveCollection(collection);
|
|
88
114
|
const params = filter ? new URLSearchParams({ filter: JSON.stringify(filter) }) : '';
|
|
89
|
-
const res = await fetch(`${this.baseUrl}/api/v1/${
|
|
115
|
+
const res = await fetch(`${this.baseUrl}/api/v1/${col}/count${params ? '?' + params : ''}`, { headers: this.headers });
|
|
90
116
|
const json = await res.json();
|
|
91
117
|
return json.data ?? 0;
|
|
92
118
|
}
|
package/dist/lib/setup.js
CHANGED
|
@@ -139,11 +139,7 @@ async function runNetInstall(installConfig, setupConfig) {
|
|
|
139
139
|
const seeded = [];
|
|
140
140
|
// 2. Verify NET server is reachable
|
|
141
141
|
const health = await net.health();
|
|
142
|
-
|
|
143
|
-
return { ok: false, error: 'Serveur NET accessible mais aucun schema chargé', needsRestart: false };
|
|
144
|
-
}
|
|
145
|
-
// 3. Seed RBAC via NET REST
|
|
146
|
-
// Read setup.json directly to get RBAC definitions
|
|
142
|
+
// 3. Read setup.json for RBAC definitions
|
|
147
143
|
const fs = await import('fs');
|
|
148
144
|
const path = await import('path');
|
|
149
145
|
let setupJson = null;
|
|
@@ -154,6 +150,48 @@ async function runNetInstall(installConfig, setupConfig) {
|
|
|
154
150
|
}
|
|
155
151
|
catch { }
|
|
156
152
|
}
|
|
153
|
+
// 4. If server has no entities, try sending schemas via POST /api/upload-schemas-json
|
|
154
|
+
if (!health.entities?.length) {
|
|
155
|
+
let schemasToSend = [];
|
|
156
|
+
// Try schemas.json local
|
|
157
|
+
const schemasJsonPath = path.resolve(process.cwd(), 'schemas.json');
|
|
158
|
+
if (fs.existsSync(schemasJsonPath)) {
|
|
159
|
+
try {
|
|
160
|
+
schemasToSend = JSON.parse(fs.readFileSync(schemasJsonPath, 'utf-8'));
|
|
161
|
+
}
|
|
162
|
+
catch { }
|
|
163
|
+
}
|
|
164
|
+
// Fallback: ORM registry
|
|
165
|
+
if (schemasToSend.length === 0) {
|
|
166
|
+
try {
|
|
167
|
+
const { getAllSchemas } = await import('@mostajs/orm');
|
|
168
|
+
schemasToSend = getAllSchemas();
|
|
169
|
+
}
|
|
170
|
+
catch { }
|
|
171
|
+
}
|
|
172
|
+
if (schemasToSend.length > 0) {
|
|
173
|
+
// Send schemas to NET server so it can register + create tables
|
|
174
|
+
try {
|
|
175
|
+
const res = await fetch(`${installConfig.net.url}/api/upload-schemas-json`, {
|
|
176
|
+
method: 'POST',
|
|
177
|
+
headers: { 'Content-Type': 'application/json' },
|
|
178
|
+
body: JSON.stringify({ schemas: schemasToSend }),
|
|
179
|
+
});
|
|
180
|
+
const result = await res.json();
|
|
181
|
+
if (result.ok)
|
|
182
|
+
seeded.push(`schemas (${schemasToSend.length})`);
|
|
183
|
+
}
|
|
184
|
+
catch (e) {
|
|
185
|
+
console.error('[Setup] Failed to upload schemas to NET server:', e);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// Re-check
|
|
189
|
+
const health2 = await net.health();
|
|
190
|
+
if (!health2.entities?.length) {
|
|
191
|
+
return { ok: false, error: 'Serveur NET accessible mais aucun schema charge. Placez un schemas.json dans le repertoire du serveur NET et redemarrez-le.', needsRestart: false };
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
await net.loadCollectionMap();
|
|
157
195
|
if (setupJson?.rbac) {
|
|
158
196
|
const rbac = setupJson.rbac;
|
|
159
197
|
// 3a. Upsert categories
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mostajs/setup",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.12",
|
|
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",
|
|
@@ -104,7 +104,8 @@
|
|
|
104
104
|
"prepublishOnly": "npm run build"
|
|
105
105
|
},
|
|
106
106
|
"dependencies": {
|
|
107
|
-
"@mostajs/
|
|
107
|
+
"@mostajs/net": "^2.0.0",
|
|
108
|
+
"@mostajs/orm": "^1.7.0",
|
|
108
109
|
"bcryptjs": "^2.4.3"
|
|
109
110
|
},
|
|
110
111
|
"devDependencies": {
|