@mostajs/setup 1.0.0 → 1.1.0
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 +895 -37
- package/dist/api/detect-modules.route.d.ts +3 -0
- package/dist/api/detect-modules.route.js +10 -0
- package/dist/api/install-modules.route.d.ts +7 -0
- package/dist/api/install-modules.route.js +112 -0
- package/dist/api/install.route.d.ts +2 -10
- package/dist/api/install.route.js +5 -9
- package/dist/api/status.route.d.ts +1 -4
- package/dist/api/status.route.js +2 -6
- package/dist/api/test-db.route.d.ts +1 -7
- package/dist/api/test-db.route.js +6 -10
- package/dist/data/dialects.d.ts +1 -1
- package/dist/data/dialects.js +2 -5
- package/dist/data/module-definitions.d.ts +18 -0
- package/dist/data/module-definitions.js +105 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +13 -21
- package/dist/lib/compose-uri.d.ts +1 -1
- package/dist/lib/compose-uri.js +1 -4
- package/dist/lib/db-test.d.ts +1 -1
- package/dist/lib/db-test.js +6 -42
- package/dist/lib/discover-modules.d.ts +13 -0
- package/dist/lib/discover-modules.js +69 -0
- package/dist/lib/env-writer.d.ts +1 -1
- package/dist/lib/env-writer.js +7 -46
- package/dist/lib/setup.d.ts +1 -1
- package/dist/lib/setup.js +13 -46
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.js +1 -2
- package/package.json +22 -20
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// @mosta/setup — Detect modules API route factory
|
|
2
|
+
// Author: Dr Hamid MADANI drmdh@msn.com
|
|
3
|
+
import { discoverNpmModules } from '../lib/discover-modules';
|
|
4
|
+
export function createDetectModulesHandler() {
|
|
5
|
+
async function GET() {
|
|
6
|
+
const result = await discoverNpmModules();
|
|
7
|
+
return Response.json(result);
|
|
8
|
+
}
|
|
9
|
+
return { GET };
|
|
10
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Factory for POST /api/setup/install-modules
|
|
3
|
+
* @param needsSetup - async function checking if app still needs setup
|
|
4
|
+
*/
|
|
5
|
+
export declare function createInstallModulesHandler(needsSetup: () => Promise<boolean>): {
|
|
6
|
+
POST: (req: Request) => Promise<Response>;
|
|
7
|
+
};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// @mosta/setup — Install modules API route factory
|
|
2
|
+
// Author: Dr Hamid MADANI drmdh@msn.com
|
|
3
|
+
import { exec } from 'child_process';
|
|
4
|
+
import { promisify } from 'util';
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import { MODULES, resolveModuleDependencies } from '../data/module-definitions';
|
|
8
|
+
const execAsync = promisify(exec);
|
|
9
|
+
/**
|
|
10
|
+
* Factory for POST /api/setup/install-modules
|
|
11
|
+
* @param needsSetup - async function checking if app still needs setup
|
|
12
|
+
*/
|
|
13
|
+
export function createInstallModulesHandler(needsSetup) {
|
|
14
|
+
async function POST(req) {
|
|
15
|
+
const setupNeeded = await needsSetup();
|
|
16
|
+
if (!setupNeeded) {
|
|
17
|
+
return Response.json({ error: { code: 'FORBIDDEN', message: 'Installation deja effectuee' } }, { status: 403 });
|
|
18
|
+
}
|
|
19
|
+
let body;
|
|
20
|
+
try {
|
|
21
|
+
body = await req.json();
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return Response.json({ error: { code: 'VALIDATION_ERROR', message: 'JSON invalide' } }, { status: 400 });
|
|
25
|
+
}
|
|
26
|
+
if (!body.modules || !Array.isArray(body.modules) || body.modules.length === 0) {
|
|
27
|
+
return Response.json({ error: { code: 'VALIDATION_ERROR', message: 'modules[] requis' } }, { status: 400 });
|
|
28
|
+
}
|
|
29
|
+
// Resolve dependencies
|
|
30
|
+
const allModules = resolveModuleDependencies(body.modules);
|
|
31
|
+
const moduleMap = new Map(MODULES.map((m) => [m.key, m]));
|
|
32
|
+
const packagesDir = path.resolve(process.cwd(), 'packages');
|
|
33
|
+
const results = [];
|
|
34
|
+
// Build install specifiers — hybrid: local file: if dir exists, npm registry otherwise
|
|
35
|
+
// Skip packages already installed in node_modules/ to avoid triggering Next.js hot-reload
|
|
36
|
+
const nodeModulesBase = path.resolve(process.cwd(), 'node_modules', '@mostajs');
|
|
37
|
+
const toInstall = [];
|
|
38
|
+
for (const key of allModules) {
|
|
39
|
+
const mod = moduleMap.get(key);
|
|
40
|
+
const npmSubdir = (mod?.packageName || `@mostajs/${key}`).replace('@mostajs/', '');
|
|
41
|
+
// Already in node_modules? Skip to avoid unnecessary npm install
|
|
42
|
+
if (fs.existsSync(path.join(nodeModulesBase, npmSubdir))) {
|
|
43
|
+
results.push({ key, ok: true });
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (mod?.localDir) {
|
|
47
|
+
const localPath = path.join(packagesDir, mod.localDir);
|
|
48
|
+
if (fs.existsSync(localPath)) {
|
|
49
|
+
toInstall.push(`file:./packages/${mod.localDir}`);
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// Fallback to npm registry (published or discovered package)
|
|
54
|
+
const packageName = mod?.packageName || `@mostajs/${key}`;
|
|
55
|
+
toInstall.push(packageName);
|
|
56
|
+
}
|
|
57
|
+
if (toInstall.length > 0) {
|
|
58
|
+
try {
|
|
59
|
+
const cmd = `npm install ${toInstall.join(' ')} --save`;
|
|
60
|
+
await execAsync(cmd, { cwd: process.cwd(), timeout: 120_000 });
|
|
61
|
+
// Mark all remaining modules as ok
|
|
62
|
+
for (const key of allModules) {
|
|
63
|
+
if (!results.some((r) => r.key === key)) {
|
|
64
|
+
results.push({ key, ok: true });
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
const message = err instanceof Error ? err.message : 'npm install failed';
|
|
70
|
+
for (const key of allModules) {
|
|
71
|
+
if (!results.some((r) => r.key === key)) {
|
|
72
|
+
results.push({ key, ok: false, error: message });
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return Response.json({ error: { code: 'INSTALL_ERROR', message }, results }, { status: 500 });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
// All already installed — fill results for any missing
|
|
80
|
+
for (const key of allModules) {
|
|
81
|
+
if (!results.some((r) => r.key === key)) {
|
|
82
|
+
results.push({ key, ok: true });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// Write MOSTAJS_MODULES to .env.local
|
|
87
|
+
try {
|
|
88
|
+
const envPath = path.resolve(process.cwd(), '.env.local');
|
|
89
|
+
let content = '';
|
|
90
|
+
try {
|
|
91
|
+
content = fs.readFileSync(envPath, 'utf-8');
|
|
92
|
+
}
|
|
93
|
+
catch { /* file doesn't exist yet */ }
|
|
94
|
+
const modulesValue = allModules.join(',');
|
|
95
|
+
const regex = /^MOSTAJS_MODULES=.*$/m;
|
|
96
|
+
if (regex.test(content)) {
|
|
97
|
+
content = content.replace(regex, `MOSTAJS_MODULES=${modulesValue}`);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
content = content.trimEnd() + `\n\n# Modules actives\nMOSTAJS_MODULES=${modulesValue}\n`;
|
|
101
|
+
}
|
|
102
|
+
fs.writeFileSync(envPath, content, 'utf-8');
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
// Non-fatal: env write can fail at this stage if .env.local not yet created
|
|
106
|
+
}
|
|
107
|
+
return Response.json({
|
|
108
|
+
data: { ok: true, modules: allModules, results },
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
return { POST };
|
|
112
|
+
}
|
|
@@ -1,17 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { MostaSetupConfig } from '../types';
|
|
1
|
+
import type { MostaSetupConfig } from '../types/index';
|
|
3
2
|
type NeedsSetupFn = () => Promise<boolean>;
|
|
4
3
|
/**
|
|
5
4
|
* Creates a POST handler for running the installation.
|
|
6
5
|
*/
|
|
7
6
|
export declare function createInstallHandler(needsSetup: NeedsSetupFn, setupConfig: MostaSetupConfig): {
|
|
8
|
-
POST: (req: Request) => Promise<
|
|
9
|
-
error: string;
|
|
10
|
-
}> | NextResponse<{
|
|
11
|
-
ok: boolean;
|
|
12
|
-
error?: string;
|
|
13
|
-
needsRestart: boolean;
|
|
14
|
-
seeded?: string[];
|
|
15
|
-
}>>;
|
|
7
|
+
POST: (req: Request) => Promise<Response>;
|
|
16
8
|
};
|
|
17
9
|
export {};
|
|
@@ -1,23 +1,19 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
// @mosta/setup — API Route template for install
|
|
3
2
|
// Author: Dr Hamid MADANI drmdh@msn.com
|
|
4
3
|
//
|
|
5
4
|
// Copy to: src/app/api/setup/install/route.ts
|
|
6
|
-
|
|
7
|
-
exports.createInstallHandler = createInstallHandler;
|
|
8
|
-
const server_1 = require("next/server");
|
|
9
|
-
const setup_1 = require("../lib/setup");
|
|
5
|
+
import { runInstall } from '../lib/setup';
|
|
10
6
|
/**
|
|
11
7
|
* Creates a POST handler for running the installation.
|
|
12
8
|
*/
|
|
13
|
-
function createInstallHandler(needsSetup, setupConfig) {
|
|
9
|
+
export function createInstallHandler(needsSetup, setupConfig) {
|
|
14
10
|
async function POST(req) {
|
|
15
11
|
if (!(await needsSetup())) {
|
|
16
|
-
return
|
|
12
|
+
return Response.json({ error: 'Already installed' }, { status: 400 });
|
|
17
13
|
}
|
|
18
14
|
const body = await req.json();
|
|
19
|
-
const result = await
|
|
20
|
-
return
|
|
15
|
+
const result = await runInstall(body, setupConfig);
|
|
16
|
+
return Response.json(result);
|
|
21
17
|
}
|
|
22
18
|
return { POST };
|
|
23
19
|
}
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
import { NextResponse } from 'next/server';
|
|
2
1
|
type NeedsSetupFn = () => Promise<boolean>;
|
|
3
2
|
/**
|
|
4
3
|
* Creates a GET handler for checking setup status.
|
|
5
4
|
*/
|
|
6
5
|
export declare function createStatusHandler(needsSetup: NeedsSetupFn): {
|
|
7
|
-
GET: () => Promise<
|
|
8
|
-
needsSetup: boolean;
|
|
9
|
-
}>>;
|
|
6
|
+
GET: () => Promise<Response>;
|
|
10
7
|
};
|
|
11
8
|
export {};
|
package/dist/api/status.route.js
CHANGED
|
@@ -1,18 +1,14 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
// @mosta/setup — API Route template for status check
|
|
3
2
|
// Author: Dr Hamid MADANI drmdh@msn.com
|
|
4
3
|
//
|
|
5
4
|
// Copy to: src/app/api/setup/status/route.ts
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.createStatusHandler = createStatusHandler;
|
|
8
|
-
const server_1 = require("next/server");
|
|
9
5
|
/**
|
|
10
6
|
* Creates a GET handler for checking setup status.
|
|
11
7
|
*/
|
|
12
|
-
function createStatusHandler(needsSetup) {
|
|
8
|
+
export function createStatusHandler(needsSetup) {
|
|
13
9
|
async function GET() {
|
|
14
10
|
const needed = await needsSetup();
|
|
15
|
-
return
|
|
11
|
+
return Response.json({ needsSetup: needed });
|
|
16
12
|
}
|
|
17
13
|
return { GET };
|
|
18
14
|
}
|
|
@@ -1,14 +1,8 @@
|
|
|
1
|
-
import { NextResponse } from 'next/server';
|
|
2
1
|
type NeedsSetupFn = () => Promise<boolean>;
|
|
3
2
|
/**
|
|
4
3
|
* Creates a POST handler for testing DB connections.
|
|
5
4
|
*/
|
|
6
5
|
export declare function createTestDbHandler(needsSetup: NeedsSetupFn): {
|
|
7
|
-
POST: (req: Request) => Promise<
|
|
8
|
-
error: string;
|
|
9
|
-
}> | NextResponse<{
|
|
10
|
-
ok: boolean;
|
|
11
|
-
error?: string;
|
|
12
|
-
}>>;
|
|
6
|
+
POST: (req: Request) => Promise<Response>;
|
|
13
7
|
};
|
|
14
8
|
export {};
|
|
@@ -1,26 +1,22 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
// @mosta/setup — API Route template for test-db
|
|
3
2
|
// Author: Dr Hamid MADANI drmdh@msn.com
|
|
4
3
|
//
|
|
5
4
|
// Copy to: src/app/api/setup/test-db/route.ts
|
|
6
|
-
|
|
7
|
-
exports.createTestDbHandler = createTestDbHandler;
|
|
8
|
-
const server_1 = require("next/server");
|
|
9
|
-
const db_test_1 = require("../lib/db-test");
|
|
5
|
+
import { testDbConnection } from '../lib/db-test';
|
|
10
6
|
/**
|
|
11
7
|
* Creates a POST handler for testing DB connections.
|
|
12
8
|
*/
|
|
13
|
-
function createTestDbHandler(needsSetup) {
|
|
9
|
+
export function createTestDbHandler(needsSetup) {
|
|
14
10
|
async function POST(req) {
|
|
15
11
|
if (!(await needsSetup())) {
|
|
16
|
-
return
|
|
12
|
+
return Response.json({ error: 'Already installed' }, { status: 400 });
|
|
17
13
|
}
|
|
18
14
|
const body = await req.json();
|
|
19
15
|
const { dialect, host, port, name, user, password } = body;
|
|
20
16
|
if (!dialect || !name) {
|
|
21
|
-
return
|
|
17
|
+
return Response.json({ error: 'Missing required fields' }, { status: 400 });
|
|
22
18
|
}
|
|
23
|
-
const result = await
|
|
19
|
+
const result = await testDbConnection({
|
|
24
20
|
dialect: dialect,
|
|
25
21
|
host: host || 'localhost',
|
|
26
22
|
port: port || 27017,
|
|
@@ -28,7 +24,7 @@ function createTestDbHandler(needsSetup) {
|
|
|
28
24
|
user: user || '',
|
|
29
25
|
password: password || '',
|
|
30
26
|
});
|
|
31
|
-
return
|
|
27
|
+
return Response.json(result);
|
|
32
28
|
}
|
|
33
29
|
return { POST };
|
|
34
30
|
}
|
package/dist/data/dialects.d.ts
CHANGED
package/dist/data/dialects.js
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ALL_DIALECTS = exports.DIALECT_INFO = void 0;
|
|
4
|
-
exports.DIALECT_INFO = {
|
|
1
|
+
export const DIALECT_INFO = {
|
|
5
2
|
mongodb: {
|
|
6
3
|
name: 'MongoDB',
|
|
7
4
|
icon: '🍃',
|
|
@@ -133,4 +130,4 @@ exports.DIALECT_INFO = {
|
|
|
133
130
|
category: 'legacy',
|
|
134
131
|
},
|
|
135
132
|
};
|
|
136
|
-
|
|
133
|
+
export const ALL_DIALECTS = Object.keys(DIALECT_INFO);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface ModuleDefinition {
|
|
2
|
+
key: string;
|
|
3
|
+
packageName: string;
|
|
4
|
+
localDir?: string;
|
|
5
|
+
label: string;
|
|
6
|
+
description: string;
|
|
7
|
+
icon: string;
|
|
8
|
+
required?: boolean;
|
|
9
|
+
default?: boolean;
|
|
10
|
+
dependsOn?: string[];
|
|
11
|
+
discovered?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare const MODULES: ModuleDefinition[];
|
|
14
|
+
/**
|
|
15
|
+
* Given a set of selected module keys, returns the full set including
|
|
16
|
+
* all transitive dependencies. Works with both static and discovered modules.
|
|
17
|
+
*/
|
|
18
|
+
export declare function resolveModuleDependencies(selected: string[], modules?: ModuleDefinition[]): string[];
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// @mosta/setup — Module definitions registry
|
|
2
|
+
// Author: Dr Hamid MADANI drmdh@msn.com
|
|
3
|
+
export const MODULES = [
|
|
4
|
+
{
|
|
5
|
+
key: 'orm',
|
|
6
|
+
packageName: '@mostajs/orm',
|
|
7
|
+
localDir: 'mosta-orm',
|
|
8
|
+
label: 'ORM (Data Access Layer)',
|
|
9
|
+
description: 'Couche d\'acces aux donnees multi-dialecte',
|
|
10
|
+
icon: '🗄️',
|
|
11
|
+
required: true,
|
|
12
|
+
default: true,
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
key: 'auth',
|
|
16
|
+
packageName: '@mostajs/auth',
|
|
17
|
+
localDir: 'mosta-auth',
|
|
18
|
+
label: 'Authentification',
|
|
19
|
+
description: 'NextAuth, sessions, gestion des mots de passe',
|
|
20
|
+
icon: '🔐',
|
|
21
|
+
required: true,
|
|
22
|
+
default: true,
|
|
23
|
+
dependsOn: ['orm'],
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
key: 'audit',
|
|
27
|
+
packageName: '@mostajs/audit',
|
|
28
|
+
localDir: 'mosta-audit',
|
|
29
|
+
label: 'Audit & Logs',
|
|
30
|
+
description: 'Journalisation des actions, tracabilite',
|
|
31
|
+
icon: '📋',
|
|
32
|
+
default: true,
|
|
33
|
+
dependsOn: ['orm'],
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
key: 'rbac',
|
|
37
|
+
packageName: '@mostajs/rbac',
|
|
38
|
+
localDir: 'mosta-rbac',
|
|
39
|
+
label: 'Roles & Permissions',
|
|
40
|
+
description: 'Gestion RBAC : roles, permissions, matrice',
|
|
41
|
+
icon: '🛡️',
|
|
42
|
+
default: true,
|
|
43
|
+
dependsOn: ['auth', 'audit'],
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
key: 'settings',
|
|
47
|
+
packageName: '@mostajs/settings',
|
|
48
|
+
localDir: 'mosta-settings',
|
|
49
|
+
label: 'Parametres',
|
|
50
|
+
description: 'Parametres cle-valeur, formulaire auto, provider React',
|
|
51
|
+
icon: '⚙️',
|
|
52
|
+
default: true,
|
|
53
|
+
dependsOn: ['orm'],
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
key: 'face',
|
|
57
|
+
packageName: '@mostajs/face',
|
|
58
|
+
localDir: 'mosta-face',
|
|
59
|
+
label: 'Reconnaissance faciale',
|
|
60
|
+
description: 'Detection de visage, extraction descripteurs, matching 1:N',
|
|
61
|
+
icon: '👤',
|
|
62
|
+
default: false,
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
key: 'setup',
|
|
66
|
+
packageName: '@mostajs/setup',
|
|
67
|
+
localDir: 'mosta-setup',
|
|
68
|
+
label: 'Setup Wizard',
|
|
69
|
+
description: 'Assistant d\'installation, test connexion, seed DB',
|
|
70
|
+
icon: '🧙',
|
|
71
|
+
required: true,
|
|
72
|
+
default: true,
|
|
73
|
+
dependsOn: ['orm'],
|
|
74
|
+
},
|
|
75
|
+
];
|
|
76
|
+
/**
|
|
77
|
+
* Given a set of selected module keys, returns the full set including
|
|
78
|
+
* all transitive dependencies. Works with both static and discovered modules.
|
|
79
|
+
*/
|
|
80
|
+
export function resolveModuleDependencies(selected, modules = MODULES) {
|
|
81
|
+
const resolved = new Set(selected);
|
|
82
|
+
const moduleMap = new Map(modules.map((m) => [m.key, m]));
|
|
83
|
+
let changed = true;
|
|
84
|
+
while (changed) {
|
|
85
|
+
changed = false;
|
|
86
|
+
for (const key of resolved) {
|
|
87
|
+
const mod = moduleMap.get(key);
|
|
88
|
+
if (mod?.dependsOn) {
|
|
89
|
+
for (const dep of mod.dependsOn) {
|
|
90
|
+
if (!resolved.has(dep)) {
|
|
91
|
+
resolved.add(dep);
|
|
92
|
+
changed = true;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// Always include required modules
|
|
99
|
+
for (const mod of modules) {
|
|
100
|
+
if (mod.required && !resolved.has(mod.key)) {
|
|
101
|
+
resolved.add(mod.key);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return Array.from(resolved);
|
|
105
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,11 @@ export { testDbConnection } from './lib/db-test';
|
|
|
3
3
|
export { composeDbUri } from './lib/compose-uri';
|
|
4
4
|
export { writeEnvLocal } from './lib/env-writer';
|
|
5
5
|
export { DIALECT_INFO, ALL_DIALECTS } from './data/dialects';
|
|
6
|
+
export { MODULES, resolveModuleDependencies } from './data/module-definitions';
|
|
7
|
+
export { discoverNpmModules } from './lib/discover-modules';
|
|
6
8
|
export { createTestDbHandler } from './api/test-db.route';
|
|
7
9
|
export { createInstallHandler } from './api/install.route';
|
|
8
10
|
export { createStatusHandler } from './api/status.route';
|
|
9
|
-
export
|
|
11
|
+
export { createDetectModulesHandler } from './api/detect-modules.route';
|
|
12
|
+
export { createInstallModulesHandler } from './api/install-modules.route';
|
|
13
|
+
export type { DialectType, DialectInfo, DbConfig, InstallConfig, SeedOptions, SeedDefinition, MostaSetupConfig, ModuleDefinition, } from './types/index';
|
package/dist/index.js
CHANGED
|
@@ -1,26 +1,18 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
// @mosta/setup — Barrel exports
|
|
3
2
|
// Author: Dr Hamid MADANI drmdh@msn.com
|
|
4
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
-
exports.createStatusHandler = exports.createInstallHandler = exports.createTestDbHandler = exports.ALL_DIALECTS = exports.DIALECT_INFO = exports.writeEnvLocal = exports.composeDbUri = exports.testDbConnection = exports.runInstall = exports.needsSetup = void 0;
|
|
6
3
|
// Core
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
Object.defineProperty(exports, "testDbConnection", { enumerable: true, get: function () { return db_test_1.testDbConnection; } });
|
|
12
|
-
var compose_uri_1 = require("./lib/compose-uri");
|
|
13
|
-
Object.defineProperty(exports, "composeDbUri", { enumerable: true, get: function () { return compose_uri_1.composeDbUri; } });
|
|
14
|
-
var env_writer_1 = require("./lib/env-writer");
|
|
15
|
-
Object.defineProperty(exports, "writeEnvLocal", { enumerable: true, get: function () { return env_writer_1.writeEnvLocal; } });
|
|
4
|
+
export { needsSetup, runInstall } from './lib/setup';
|
|
5
|
+
export { testDbConnection } from './lib/db-test';
|
|
6
|
+
export { composeDbUri } from './lib/compose-uri';
|
|
7
|
+
export { writeEnvLocal } from './lib/env-writer';
|
|
16
8
|
// Data
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
9
|
+
export { DIALECT_INFO, ALL_DIALECTS } from './data/dialects';
|
|
10
|
+
export { MODULES, resolveModuleDependencies } from './data/module-definitions';
|
|
11
|
+
// Lib
|
|
12
|
+
export { discoverNpmModules } from './lib/discover-modules';
|
|
20
13
|
// API route factories
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
Object.defineProperty(exports, "createStatusHandler", { enumerable: true, get: function () { return status_route_1.createStatusHandler; } });
|
|
14
|
+
export { createTestDbHandler } from './api/test-db.route';
|
|
15
|
+
export { createInstallHandler } from './api/install.route';
|
|
16
|
+
export { createStatusHandler } from './api/status.route';
|
|
17
|
+
export { createDetectModulesHandler } from './api/detect-modules.route';
|
|
18
|
+
export { createInstallModulesHandler } from './api/install-modules.route';
|
package/dist/lib/compose-uri.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.composeDbUri = composeDbUri;
|
|
4
1
|
/**
|
|
5
2
|
* Compose a database connection URI from individual fields.
|
|
6
3
|
*/
|
|
7
|
-
function composeDbUri(dialect, config) {
|
|
4
|
+
export function composeDbUri(dialect, config) {
|
|
8
5
|
const { host, port, name, user, password } = config;
|
|
9
6
|
const eu = encodeURIComponent(user);
|
|
10
7
|
const ep = encodeURIComponent(password);
|
package/dist/lib/db-test.d.ts
CHANGED
package/dist/lib/db-test.js
CHANGED
|
@@ -1,50 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.testDbConnection = testDbConnection;
|
|
37
|
-
const compose_uri_1 = require("./compose-uri");
|
|
1
|
+
import { composeDbUri } from './compose-uri';
|
|
38
2
|
/**
|
|
39
3
|
* Test a database connection without affecting the global dialect singleton.
|
|
40
4
|
*/
|
|
41
|
-
async function testDbConnection(params) {
|
|
5
|
+
export async function testDbConnection(params) {
|
|
42
6
|
const { dialect, ...dbConfig } = params;
|
|
43
7
|
try {
|
|
44
8
|
switch (dialect) {
|
|
45
9
|
case 'mongodb': {
|
|
46
|
-
const uri =
|
|
47
|
-
const mongoose = await
|
|
10
|
+
const uri = composeDbUri('mongodb', dbConfig);
|
|
11
|
+
const mongoose = await import('mongoose');
|
|
48
12
|
const conn = mongoose.default.createConnection(uri, {
|
|
49
13
|
serverSelectionTimeoutMS: 5000,
|
|
50
14
|
connectTimeoutMS: 5000,
|
|
@@ -60,8 +24,8 @@ async function testDbConnection(params) {
|
|
|
60
24
|
case 'sqlite':
|
|
61
25
|
return { ok: true };
|
|
62
26
|
default: {
|
|
63
|
-
const uri =
|
|
64
|
-
const { testConnection } = await
|
|
27
|
+
const uri = composeDbUri(dialect, dbConfig);
|
|
28
|
+
const { testConnection } = await import('@mostajs/orm');
|
|
65
29
|
const ok = await testConnection({ dialect, uri, schemaStrategy: 'none' });
|
|
66
30
|
return { ok };
|
|
67
31
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type ModuleDefinition } from '../data/module-definitions';
|
|
2
|
+
/**
|
|
3
|
+
* Discover @mostajs packages from npm registry and merge with static list.
|
|
4
|
+
*
|
|
5
|
+
* - Known modules keep their rich metadata (required, dependsOn, icon)
|
|
6
|
+
* - New packages found on npm are added with `discovered: true`
|
|
7
|
+
* - Detects which packages are already installed in node_modules/
|
|
8
|
+
* - Falls back to static list if npm search fails (offline, timeout)
|
|
9
|
+
*/
|
|
10
|
+
export declare function discoverNpmModules(): Promise<{
|
|
11
|
+
modules: ModuleDefinition[];
|
|
12
|
+
installed: string[];
|
|
13
|
+
}>;
|