create-meridian-app 0.1.1 → 0.1.3
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/{chunk-FNFHDPFG.js → chunk-AVRGW4UO.js} +41 -5
- package/dist/cli.js +29 -9
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -4,7 +4,7 @@ import { existsSync as existsSync2 } from "fs";
|
|
|
4
4
|
import ora from "ora";
|
|
5
5
|
import chalk from "chalk";
|
|
6
6
|
import prompts from "prompts";
|
|
7
|
-
import { execa } from "execa";
|
|
7
|
+
import { execa as execa2 } from "execa";
|
|
8
8
|
|
|
9
9
|
// src/templates/index.ts
|
|
10
10
|
function renderPackageJson(vars) {
|
|
@@ -81,6 +81,9 @@ export default defineConfig({
|
|
|
81
81
|
httpPort: Number(process.env.PORT) || ${vars.httpPort},
|
|
82
82
|
jwtSecret: process.env.JWT_SECRET ?? "changeme-replace-in-production",
|
|
83
83
|
},
|
|
84
|
+
admin: {
|
|
85
|
+
port: Number(process.env.DASHBOARD_PORT) || ${vars.dashboardPort},
|
|
86
|
+
},
|
|
84
87
|
modules: [
|
|
85
88
|
{ resolve: "@meridianjs/event-bus-local" },
|
|
86
89
|
{ resolve: "@meridianjs/user" },
|
|
@@ -163,7 +166,8 @@ function renderEnvExample(vars) {
|
|
|
163
166
|
DATABASE_URL=${vars.databaseUrl}
|
|
164
167
|
PORT=${vars.httpPort}
|
|
165
168
|
JWT_SECRET=changeme-replace-in-production
|
|
166
|
-
|
|
169
|
+
${vars.dashboard ? `DASHBOARD_PORT=${vars.dashboardPort}` : ""}
|
|
170
|
+
`.trimEnd() + "\n";
|
|
167
171
|
}
|
|
168
172
|
function renderReadme(vars) {
|
|
169
173
|
return `# ${vars.name}
|
|
@@ -317,6 +321,7 @@ export const ${camelName}Workflow = createWorkflow(
|
|
|
317
321
|
import path from "path";
|
|
318
322
|
import fs from "fs/promises";
|
|
319
323
|
import { existsSync } from "fs";
|
|
324
|
+
import { execa } from "execa";
|
|
320
325
|
function toPascalCase(str) {
|
|
321
326
|
return str.replace(/[-_](.)/g, (_, c) => c.toUpperCase()).replace(/^(.)/, (_, c) => c.toUpperCase());
|
|
322
327
|
}
|
|
@@ -345,6 +350,29 @@ function findProjectRoot(startDir = process.cwd()) {
|
|
|
345
350
|
dir = parent;
|
|
346
351
|
}
|
|
347
352
|
}
|
|
353
|
+
async function readProjectPorts(rootDir) {
|
|
354
|
+
const defaults = { apiPort: 9e3, dashboardPort: 5174 };
|
|
355
|
+
const configPath = path.join(rootDir, "meridian.config.ts");
|
|
356
|
+
if (!existsSync(configPath)) return defaults;
|
|
357
|
+
const script = `
|
|
358
|
+
import cfg from "${configPath.replace(/\\/g, "/")}"
|
|
359
|
+
const c = cfg.default ?? cfg
|
|
360
|
+
process.stdout.write(JSON.stringify({
|
|
361
|
+
apiPort: c?.projectConfig?.httpPort ?? 9000,
|
|
362
|
+
dashboardPort: c?.admin?.port ?? 5174,
|
|
363
|
+
}))
|
|
364
|
+
`;
|
|
365
|
+
const scriptPath = path.join(rootDir, ".meridian-ports-tmp.mjs");
|
|
366
|
+
await fs.writeFile(scriptPath, script, "utf-8");
|
|
367
|
+
try {
|
|
368
|
+
const result = await execa("node", ["--import", "tsx/esm", scriptPath], { cwd: rootDir });
|
|
369
|
+
return JSON.parse(result.stdout);
|
|
370
|
+
} catch {
|
|
371
|
+
return defaults;
|
|
372
|
+
} finally {
|
|
373
|
+
await fs.unlink(scriptPath).catch(() => null);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
348
376
|
|
|
349
377
|
// src/commands/new.ts
|
|
350
378
|
async function runNew(projectName) {
|
|
@@ -392,7 +420,7 @@ async function runNew(projectName) {
|
|
|
392
420
|
{
|
|
393
421
|
type: "number",
|
|
394
422
|
name: "httpPort",
|
|
395
|
-
message: "
|
|
423
|
+
message: "API port",
|
|
396
424
|
initial: 9e3
|
|
397
425
|
},
|
|
398
426
|
{
|
|
@@ -401,6 +429,12 @@ async function runNew(projectName) {
|
|
|
401
429
|
message: "Install admin dashboard?",
|
|
402
430
|
initial: true
|
|
403
431
|
},
|
|
432
|
+
{
|
|
433
|
+
type: (prev) => prev ? "number" : null,
|
|
434
|
+
name: "dashboardPort",
|
|
435
|
+
message: "Dashboard port",
|
|
436
|
+
initial: 5174
|
|
437
|
+
},
|
|
404
438
|
{
|
|
405
439
|
type: "confirm",
|
|
406
440
|
name: "installDeps",
|
|
@@ -414,7 +448,8 @@ async function runNew(projectName) {
|
|
|
414
448
|
name,
|
|
415
449
|
databaseUrl: answers.databaseUrl,
|
|
416
450
|
httpPort: answers.httpPort,
|
|
417
|
-
dashboard: answers.dashboard
|
|
451
|
+
dashboard: answers.dashboard,
|
|
452
|
+
dashboardPort: answers.dashboardPort ?? 5174
|
|
418
453
|
};
|
|
419
454
|
const spinner = ora("Scaffolding project...").start();
|
|
420
455
|
try {
|
|
@@ -443,7 +478,7 @@ async function runNew(projectName) {
|
|
|
443
478
|
if (answers.installDeps) {
|
|
444
479
|
const installSpinner = ora("Installing dependencies...").start();
|
|
445
480
|
try {
|
|
446
|
-
await
|
|
481
|
+
await execa2("npm", ["install"], { cwd: targetDir, stdio: "pipe" });
|
|
447
482
|
installSpinner.succeed("Dependencies installed");
|
|
448
483
|
} catch (err) {
|
|
449
484
|
installSpinner.warn("npm install failed \u2014 run it manually");
|
|
@@ -472,5 +507,6 @@ export {
|
|
|
472
507
|
toKebabCase,
|
|
473
508
|
writeFile,
|
|
474
509
|
findProjectRoot,
|
|
510
|
+
readProjectPorts,
|
|
475
511
|
runNew
|
|
476
512
|
};
|
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
findProjectRoot,
|
|
4
|
+
readProjectPorts,
|
|
4
5
|
renderModuleIndex,
|
|
5
6
|
renderModuleLoader,
|
|
6
7
|
renderModuleModel,
|
|
@@ -10,7 +11,7 @@ import {
|
|
|
10
11
|
toKebabCase,
|
|
11
12
|
toPascalCase,
|
|
12
13
|
writeFile
|
|
13
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-AVRGW4UO.js";
|
|
14
15
|
|
|
15
16
|
// src/cli.ts
|
|
16
17
|
import { Command } from "commander";
|
|
@@ -40,7 +41,8 @@ var MIME_TYPES = {
|
|
|
40
41
|
".woff": "font/woff",
|
|
41
42
|
".woff2": "font/woff2"
|
|
42
43
|
};
|
|
43
|
-
function startDashboardServer(distDir, port) {
|
|
44
|
+
function startDashboardServer(distDir, port, apiPort, apiHost = "localhost") {
|
|
45
|
+
const configScript = `<script>window.__MERIDIAN_CONFIG__ = { apiUrl: "http://${apiHost}:${apiPort}" };</script>`;
|
|
44
46
|
return new Promise((resolve, reject) => {
|
|
45
47
|
const server = http.createServer((req, res) => {
|
|
46
48
|
const urlPath = (req.url ?? "/").split("?")[0];
|
|
@@ -49,6 +51,19 @@ function startDashboardServer(distDir, port) {
|
|
|
49
51
|
filePath = path.join(distDir, "index.html");
|
|
50
52
|
}
|
|
51
53
|
const ext = path.extname(filePath);
|
|
54
|
+
if (ext === ".html") {
|
|
55
|
+
try {
|
|
56
|
+
const html = fs.readFileSync(filePath, "utf-8");
|
|
57
|
+
const injected = html.replace("<head>", `<head>
|
|
58
|
+
${configScript}`);
|
|
59
|
+
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
60
|
+
res.end(injected);
|
|
61
|
+
} catch {
|
|
62
|
+
res.writeHead(404);
|
|
63
|
+
res.end("Not found");
|
|
64
|
+
}
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
52
67
|
const contentType = MIME_TYPES[ext] ?? "application/octet-stream";
|
|
53
68
|
fs.readFile(filePath, (err, data) => {
|
|
54
69
|
if (err) {
|
|
@@ -64,7 +79,7 @@ function startDashboardServer(distDir, port) {
|
|
|
64
79
|
server.on("error", reject);
|
|
65
80
|
});
|
|
66
81
|
}
|
|
67
|
-
async function runServeDashboard(
|
|
82
|
+
async function runServeDashboard(portOverride) {
|
|
68
83
|
const rootDir = findProjectRoot();
|
|
69
84
|
if (!rootDir) {
|
|
70
85
|
console.error(chalk.red(" \u2716 Could not find meridian.config.ts. Are you inside a Meridian project?"));
|
|
@@ -76,8 +91,11 @@ async function runServeDashboard(port = 5174) {
|
|
|
76
91
|
console.error(chalk.dim(" Run: npm install @meridianjs/admin-dashboard"));
|
|
77
92
|
process.exit(1);
|
|
78
93
|
}
|
|
79
|
-
const
|
|
80
|
-
|
|
94
|
+
const { apiPort, dashboardPort } = await readProjectPorts(rootDir);
|
|
95
|
+
const port = portOverride ?? dashboardPort;
|
|
96
|
+
const server = await startDashboardServer(distDir, port, apiPort);
|
|
97
|
+
console.log(chalk.green(" \u2714 Admin dashboard: ") + chalk.cyan(`http://localhost:${port}`));
|
|
98
|
+
console.log(chalk.dim(` \u2192 API: http://localhost:${apiPort}`));
|
|
81
99
|
const shutdown = () => {
|
|
82
100
|
server.close();
|
|
83
101
|
process.exit(0);
|
|
@@ -100,13 +118,15 @@ async function runDev() {
|
|
|
100
118
|
}
|
|
101
119
|
const dashboardDist = path2.join(rootDir, "node_modules", "@meridianjs", "admin-dashboard", "dist");
|
|
102
120
|
const hasDashboard = existsSync2(dashboardDist);
|
|
103
|
-
const
|
|
121
|
+
const { apiPort, dashboardPort } = await readProjectPorts(rootDir);
|
|
104
122
|
let dashServer = null;
|
|
105
123
|
if (hasDashboard) {
|
|
106
|
-
dashServer = await startDashboardServer(dashboardDist,
|
|
107
|
-
console.log(
|
|
124
|
+
dashServer = await startDashboardServer(dashboardDist, dashboardPort, apiPort);
|
|
125
|
+
console.log(
|
|
126
|
+
chalk2.dim(" \u2192 API: ") + chalk2.cyan(`http://localhost:${apiPort}`) + chalk2.dim(" dashboard: ") + chalk2.cyan(`http://localhost:${dashboardPort}`)
|
|
127
|
+
);
|
|
108
128
|
} else {
|
|
109
|
-
console.log(chalk2.dim(` \u2192
|
|
129
|
+
console.log(chalk2.dim(` \u2192 API: http://localhost:${apiPort}`));
|
|
110
130
|
}
|
|
111
131
|
console.log();
|
|
112
132
|
const apiProc = execa(
|
package/dist/index.js
CHANGED