@fecommunity/reactpress 4.0.0-beta.11 → 4.0.0-beta.13
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 +2 -1
- package/admin-dist/apple-touch-icon.png +0 -0
- package/admin-dist/assets/abap-08VXUWAP.js +1 -0
- package/admin-dist/assets/admin-BifGpl6Y.css +1 -0
- package/admin-dist/assets/admin-CrL6Xc9b.js +1 -0
- package/admin-dist/assets/admin-ZWBL0q2y.css +1 -0
- package/admin-dist/assets/admin-bamoE2Tn.js +1 -0
- package/admin-dist/assets/apex-BWPQTe0t.js +1 -0
- package/admin-dist/assets/azcli-Bc_sGQ0U.js +1 -0
- package/admin-dist/assets/bat-i0X4ZdIN.js +1 -0
- package/admin-dist/assets/bicep-B5-_aFwp.js +2 -0
- package/admin-dist/assets/cameligo-DMUM7wLl.js +1 -0
- package/admin-dist/assets/clojure-Cm7r79vr.js +1 -0
- package/admin-dist/assets/codicon-DCmgc-ay.ttf +0 -0
- package/admin-dist/assets/coffee-Ba7i2nA0.js +1 -0
- package/admin-dist/assets/cpp-C7h46wYY.js +1 -0
- package/admin-dist/assets/csharp-BKxtCVv1.js +1 -0
- package/admin-dist/assets/csp-bTuwJoIa.js +1 -0
- package/admin-dist/assets/css-DIMkf-bt.js +3 -0
- package/admin-dist/assets/cssMode-J2cfgFkq.js +4 -0
- package/admin-dist/assets/cypher-CVaqCwHa.js +1 -0
- package/admin-dist/assets/dart-onAF5SnQ.js +1 -0
- package/admin-dist/assets/dashicons-DDlWl2tg.eot +0 -0
- package/admin-dist/assets/dashicons-MbROV69l.ttf +0 -0
- package/admin-dist/assets/dockerfile-DZFCIeNp.js +1 -0
- package/admin-dist/assets/ecl-D05T4iGw.js +1 -0
- package/admin-dist/assets/elixir-6RTg0lbw.js +1 -0
- package/admin-dist/assets/flow9-C5_-GSwl.js +1 -0
- package/admin-dist/assets/freemarker2-L_gr_Wq4.js +3 -0
- package/admin-dist/assets/fsharp-C8Ef5oNN.js +1 -0
- package/admin-dist/assets/github-dark.min-Z5exjX_n.css +1 -0
- package/admin-dist/assets/github.min-D2BCvnWf.css +1 -0
- package/admin-dist/assets/go-C-y9NEjX.js +1 -0
- package/admin-dist/assets/graphql-fmXr3nnJ.js +1 -0
- package/admin-dist/assets/handlebars-D81kzUDC.js +1 -0
- package/admin-dist/assets/hcl-CpzslTdj.js +1 -0
- package/admin-dist/assets/html-Cung-Yr0.js +1 -0
- package/admin-dist/assets/htmlMode-C6QemWl2.js +4 -0
- package/admin-dist/assets/index-BNrD3O4x.css +1 -0
- package/admin-dist/assets/index-DXTkTQ21.js +1184 -0
- package/admin-dist/assets/ini-sBoK_t0W.js +1 -0
- package/admin-dist/assets/java-BEtHBSE6.js +1 -0
- package/admin-dist/assets/javascript-WUcGtCKt.js +1 -0
- package/admin-dist/assets/jsonMode-Dp0R9P1F.js +10 -0
- package/admin-dist/assets/julia-Bri6UV-V.js +1 -0
- package/admin-dist/assets/kotlin-B0qVs-E9.js +1 -0
- package/admin-dist/assets/less-B9JPFI3C.js +2 -0
- package/admin-dist/assets/lexon-CfSJPG6W.js +1 -0
- package/admin-dist/assets/liquid-OFb9c-6B.js +1 -0
- package/admin-dist/assets/lua-CsQS60Ue.js +1 -0
- package/admin-dist/assets/m3-D-oSqn_W.js +1 -0
- package/admin-dist/assets/markdown-Cimd5fb3.js +1 -0
- package/admin-dist/assets/mdx-CUfjLxA3.js +1 -0
- package/admin-dist/assets/mips-CIPQ_RoX.js +1 -0
- package/admin-dist/assets/msdax-DauUninz.js +1 -0
- package/admin-dist/assets/mysql-SOo6toE5.js +1 -0
- package/admin-dist/assets/objective-c-FvmIjYaQ.js +1 -0
- package/admin-dist/assets/pascal-DrH0SRf2.js +1 -0
- package/admin-dist/assets/pascaligo-D-ptJ9y-.js +1 -0
- package/admin-dist/assets/perl-oz_6vUea.js +1 -0
- package/admin-dist/assets/pgsql-DTj74zXo.js +1 -0
- package/admin-dist/assets/php-nr791fC2.js +1 -0
- package/admin-dist/assets/pla-CopQ2nXW.js +1 -0
- package/admin-dist/assets/postiats-43DmfD33.js +1 -0
- package/admin-dist/assets/powerquery-D3hlyOfw.js +1 -0
- package/admin-dist/assets/powershell-DmHpPYUd.js +1 -0
- package/admin-dist/assets/protobuf-C531GsRP.js +2 -0
- package/admin-dist/assets/pug-Z5eAx3Zn.js +1 -0
- package/admin-dist/assets/python-zxEYY77U.js +1 -0
- package/admin-dist/assets/qsharp-DkqhCAOL.js +1 -0
- package/admin-dist/assets/r-BwWrilGY.js +1 -0
- package/admin-dist/assets/razor-DJrSr4ly.js +1 -0
- package/admin-dist/assets/redis-ClamHrr6.js +1 -0
- package/admin-dist/assets/redshift-DT7zqm-g.js +1 -0
- package/admin-dist/assets/restructuredtext-BYgofb2h.js +1 -0
- package/admin-dist/assets/rolldown-runtime-Cyuzqnbw.js +1 -0
- package/admin-dist/assets/ruby-DezsRK8O.js +1 -0
- package/admin-dist/assets/rust-DdL9SqIa.js +1 -0
- package/admin-dist/assets/sb-CcwsVR0C.js +1 -0
- package/admin-dist/assets/scala-DHpiXF5c.js +1 -0
- package/admin-dist/assets/scheme-BeGwcela.js +1 -0
- package/admin-dist/assets/scss-gp-XZpBa.js +3 -0
- package/admin-dist/assets/shell-CC2rA5mh.js +1 -0
- package/admin-dist/assets/solidity-BEEn4gHE.js +1 -0
- package/admin-dist/assets/sophia-CRfGWb83.js +1 -0
- package/admin-dist/assets/sparql-D_Lu-MrJ.js +1 -0
- package/admin-dist/assets/sql-NEE52Syq.js +1 -0
- package/admin-dist/assets/st-DbInun42.js +1 -0
- package/admin-dist/assets/swift-Bxkupp3x.js +1 -0
- package/admin-dist/assets/systemverilog-Bz4Y3fRF.js +1 -0
- package/admin-dist/assets/tcl-DISqw1ZD.js +1 -0
- package/admin-dist/assets/tsMode-Dtxx1cRn.js +11 -0
- package/admin-dist/assets/twig-De2hgUGE.js +1 -0
- package/admin-dist/assets/typescript-DT11gl4K.js +1 -0
- package/admin-dist/assets/typespec-B8J7ngcE.js +1 -0
- package/admin-dist/assets/vb-DV3o63ZY.js +1 -0
- package/admin-dist/assets/vendor-antd-854Wnkhp.js +334 -0
- package/admin-dist/assets/vendor-tanstack-CUgEbs6-.js +1 -0
- package/admin-dist/assets/vendor-ui-BosneugM.js +1 -0
- package/admin-dist/assets/wgsl-DpFanUEy.js +298 -0
- package/admin-dist/assets/xml-BIbLvdwx.js +1 -0
- package/admin-dist/assets/yaml-BEeUZskE.js +1 -0
- package/admin-dist/favicon-16.png +0 -0
- package/admin-dist/favicon-32.png +0 -0
- package/admin-dist/favicon-48.png +0 -0
- package/admin-dist/favicon.ico +0 -0
- package/admin-dist/favicon.png +0 -0
- package/admin-dist/icon-192.png +0 -0
- package/admin-dist/icon-512.png +0 -0
- package/admin-dist/index.html +26 -0
- package/admin-dist/logo-200.png +0 -0
- package/admin-dist/logo-400.png +0 -0
- package/admin-dist/logo-wordmark.svg +10 -0
- package/admin-dist/logo.png +0 -0
- package/admin-dist/logo.svg +7 -0
- package/admin-dist/mockServiceWorker.js +336 -0
- package/admin-dist/showcase/undraw_around_the_world.svg +1 -0
- package/admin-dist/showcase/undraw_docusaurus_mountain.svg +54 -0
- package/admin-dist/showcase/undraw_docusaurus_react.svg +51 -0
- package/admin-dist/showcase/undraw_docusaurus_tree.svg +40 -0
- package/admin-dist/showcase/undraw_react.svg +1 -0
- package/admin-dist/showcase/undraw_typewriter.svg +1 -0
- package/admin-dist/showcase/undraw_version_control.svg +1 -0
- package/out/bin/reactpress-theme-client.js +4 -39
- package/out/bin/reactpress.js +42 -10
- package/out/core/services/admin-static.js +136 -0
- package/out/lib/doctor.js +9 -1
- package/out/lib/i18n/strings.js +44 -2
- package/out/lib/lifecycle.js +5 -0
- package/out/lib/project-logs.js +197 -0
- package/package.json +2 -1
- package/server/dist/modules/extension/extension.module.js +3 -1
- package/server/dist/modules/extension/theme-registry.bridge.js +23 -1
- package/server/package-lock.json +3 -32
- package/server/package.json +1 -1
- package/toolkit/package.json +1 -1
package/out/lib/i18n/strings.js
CHANGED
|
@@ -70,6 +70,12 @@ const STRINGS = {
|
|
|
70
70
|
'cli.help.nginx': ' reactpress nginx up Start reverse proxy (:80)',
|
|
71
71
|
'cli.status.description': 'Project, API, frontend, and Docker status',
|
|
72
72
|
'cli.doctor.description': 'Diagnose Node, Docker, ports, database, and API health',
|
|
73
|
+
'cli.doctor.showLogs': 'Show recent API error logs after diagnostics',
|
|
74
|
+
'cli.doctor.logs.description': 'View recent API logs (error, request, response)',
|
|
75
|
+
'cli.doctor.logs.tailOption': 'Number of lines to show per log file',
|
|
76
|
+
'cli.doctor.logs.sourceOption': 'Log source: error, request, response, or all',
|
|
77
|
+
'cli.doctor.logs.grepOption': 'Filter log lines by regex',
|
|
78
|
+
'cli.doctor.logs.listOption': 'List available log files only',
|
|
73
79
|
'cli.db.description': 'Database operations',
|
|
74
80
|
'cli.db.backup': 'Backup current project database with mysqldump',
|
|
75
81
|
'cli.db.backup.output': 'Output SQL file path',
|
|
@@ -78,8 +84,9 @@ const STRINGS = {
|
|
|
78
84
|
'cli.publish.publish': 'Publish core packages to npm',
|
|
79
85
|
'cli.start.description': 'Start ReactPress (SQLite API + admin + theme)',
|
|
80
86
|
'cli.help.examples': 'Usage:',
|
|
81
|
-
'cli.help.init': ' reactpress init
|
|
87
|
+
'cli.help.init': ' reactpress init [dir] Initialize project',
|
|
82
88
|
'cli.help.doctor': ' reactpress doctor Diagnose environment issues',
|
|
89
|
+
'cli.help.doctorLogs': ' reactpress doctor logs Tail API logs for quick debugging',
|
|
83
90
|
'cli.help.zeroDep': ' Zero deps: Node.js 18+ only — no Docker, nginx, or MySQL',
|
|
84
91
|
'cli.plugin.description': 'Manage ReactPress plugins',
|
|
85
92
|
'cli.plugin.install.description': 'Install a local plugin into .reactpress/plugins',
|
|
@@ -408,6 +415,20 @@ const STRINGS = {
|
|
|
408
415
|
'doctor.checking': 'Checking {name}…',
|
|
409
416
|
'doctor.summary': '{passed} passed · {failed} failed · {total} total',
|
|
410
417
|
'doctor.fixesHeader': 'Suggested fixes',
|
|
418
|
+
'doctor.logsHint': 'Tip: run reactpress doctor logs --tail 100 to inspect API error logs',
|
|
419
|
+
'doctor.logs.title': 'ReactPress Doctor · Logs',
|
|
420
|
+
'doctor.logs.subtitle': 'API log viewer',
|
|
421
|
+
'doctor.logs.dir': 'Log dir {path}',
|
|
422
|
+
'doctor.logs.empty': 'No API log files found yet.',
|
|
423
|
+
'doctor.logs.emptyHint': 'Start the API with reactpress init — logs are written to .reactpress/logs/server/',
|
|
424
|
+
'doctor.logs.listHeader': 'Available log files',
|
|
425
|
+
'doctor.logs.fileHeader': '{file} (showing {count} line(s))',
|
|
426
|
+
'doctor.logs.noMatchingLines': 'No matching log lines.',
|
|
427
|
+
'doctor.logs.badPattern': 'Invalid grep pattern: {pattern}',
|
|
428
|
+
'doctor.logs.noPid': 'No API pid file at {path}',
|
|
429
|
+
'doctor.logs.pidRunning': 'API pid {pid} (recorded in {path})',
|
|
430
|
+
'doctor.logs.pidStale': 'Stale pid {pid} in {path} — process not running',
|
|
431
|
+
'doctor.logs.moreHint': 'Use --tail, --source, --grep, or --list for more control (see reactpress doctor logs --help)',
|
|
411
432
|
'status.title': 'ReactPress project status',
|
|
412
433
|
'status.dir': 'Project {path}',
|
|
413
434
|
'status.apiSource': 'API source {source}',
|
|
@@ -703,6 +724,12 @@ const STRINGS = {
|
|
|
703
724
|
'cli.help.nginx': ' reactpress nginx up 启动反向代理 (:80)',
|
|
704
725
|
'cli.status.description': '查看项目、API、前端、Docker 综合状态',
|
|
705
726
|
'cli.doctor.description': '诊断环境:Node、Docker、端口、数据库、API 健康',
|
|
727
|
+
'cli.doctor.showLogs': '诊断结束后显示最近的 API 错误日志',
|
|
728
|
+
'cli.doctor.logs.description': '查看 API 日志(error / request / response)',
|
|
729
|
+
'cli.doctor.logs.tailOption': '每个日志文件显示的行数',
|
|
730
|
+
'cli.doctor.logs.sourceOption': '日志类型:error、request、response 或 all',
|
|
731
|
+
'cli.doctor.logs.grepOption': '用正则过滤日志行',
|
|
732
|
+
'cli.doctor.logs.listOption': '仅列出可用日志文件',
|
|
706
733
|
'cli.db.description': '数据库运维',
|
|
707
734
|
'cli.db.backup': '使用 mysqldump 备份当前项目数据库',
|
|
708
735
|
'cli.db.backup.output': '输出 SQL 文件路径',
|
|
@@ -711,8 +738,9 @@ const STRINGS = {
|
|
|
711
738
|
'cli.publish.publish': '发布核心 npm 包',
|
|
712
739
|
'cli.start.description': '启动 ReactPress(SQLite API + 管理后台 + 主题)',
|
|
713
740
|
'cli.help.examples': '用法:',
|
|
714
|
-
'cli.help.init': ' reactpress init
|
|
741
|
+
'cli.help.init': ' reactpress init [dir] 初始化项目',
|
|
715
742
|
'cli.help.doctor': ' reactpress doctor 诊断环境问题',
|
|
743
|
+
'cli.help.doctorLogs': ' reactpress doctor logs 查看 API 日志,快速定位问题',
|
|
716
744
|
'cli.help.zeroDep': ' 零依赖:仅需 Node.js 18+,无需 Docker、nginx 或 MySQL',
|
|
717
745
|
'cli.plugin.description': '管理 ReactPress 插件',
|
|
718
746
|
'cli.plugin.install.description': '安装本地插件到 .reactpress/plugins',
|
|
@@ -1040,6 +1068,20 @@ const STRINGS = {
|
|
|
1040
1068
|
'doctor.checking': '正在检查 {name}…',
|
|
1041
1069
|
'doctor.summary': '通过 {passed} · 失败 {failed} · 共 {total} 项',
|
|
1042
1070
|
'doctor.fixesHeader': '修复建议',
|
|
1071
|
+
'doctor.logsHint': '提示:运行 reactpress doctor logs --tail 100 查看 API 错误日志',
|
|
1072
|
+
'doctor.logs.title': 'ReactPress Doctor · 日志',
|
|
1073
|
+
'doctor.logs.subtitle': 'API 日志查看',
|
|
1074
|
+
'doctor.logs.dir': '日志目录 {path}',
|
|
1075
|
+
'doctor.logs.empty': '尚未找到 API 日志文件。',
|
|
1076
|
+
'doctor.logs.emptyHint': '运行 reactpress init 启动 API 后,日志会写入 .reactpress/logs/server/',
|
|
1077
|
+
'doctor.logs.listHeader': '可用日志文件',
|
|
1078
|
+
'doctor.logs.fileHeader': '{file}(显示 {count} 行)',
|
|
1079
|
+
'doctor.logs.noMatchingLines': '没有匹配的日志行。',
|
|
1080
|
+
'doctor.logs.badPattern': 'grep 正则无效:{pattern}',
|
|
1081
|
+
'doctor.logs.noPid': '未找到 API pid 文件:{path}',
|
|
1082
|
+
'doctor.logs.pidRunning': 'API 进程 pid {pid}(记录在 {path})',
|
|
1083
|
+
'doctor.logs.pidStale': 'pid 文件 {path} 中的 {pid} 已失效(进程未运行)',
|
|
1084
|
+
'doctor.logs.moreHint': '可用 --tail、--source、--grep、--list 进一步筛选(见 reactpress doctor logs --help)',
|
|
1043
1085
|
'status.title': 'ReactPress 项目状态',
|
|
1044
1086
|
'status.dir': '项目目录 {path}',
|
|
1045
1087
|
'status.apiSource': 'API 来源 {source}',
|
package/out/lib/lifecycle.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
// @ts-nocheck
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
4
6
|
const { spawn } = require('child_process');
|
|
5
7
|
const ora = require('ora');
|
|
6
8
|
const { ensureProjectEnvironment } = require('./bootstrap');
|
|
@@ -92,6 +94,8 @@ async function startApi(projectRoot, { wait = true } = {}) {
|
|
|
92
94
|
else {
|
|
93
95
|
console.log(t('lifecycle.startingBundledApi'));
|
|
94
96
|
}
|
|
97
|
+
const serverLogDir = path.join(projectRoot, '.reactpress', 'logs', 'server');
|
|
98
|
+
fs.mkdirSync(serverLogDir, { recursive: true });
|
|
95
99
|
const child = spawn(process.execPath, [getServerBin(projectRoot)], {
|
|
96
100
|
cwd: getServerDir(projectRoot),
|
|
97
101
|
detached: true,
|
|
@@ -99,6 +103,7 @@ async function startApi(projectRoot, { wait = true } = {}) {
|
|
|
99
103
|
env: {
|
|
100
104
|
...process.env,
|
|
101
105
|
REACTPRESS_ORIGINAL_CWD: projectRoot,
|
|
106
|
+
REACTPRESS_SERVER_LOG_DIR: serverLogDir,
|
|
102
107
|
},
|
|
103
108
|
});
|
|
104
109
|
child.unref();
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
// @ts-nocheck
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const { brand, divider, gradientText, palette, sectionHeader } = require('../ui/theme');
|
|
7
|
+
const { getServerDir, getPidFile } = require('./paths');
|
|
8
|
+
const { readPid, isProcessRunning } = require('./process');
|
|
9
|
+
const { t } = require('./i18n');
|
|
10
|
+
const LOG_SOURCES = ['error', 'request', 'response'];
|
|
11
|
+
function getProjectServerLogDir(projectRoot) {
|
|
12
|
+
const preferred = path.join(projectRoot, '.reactpress', 'logs', 'server');
|
|
13
|
+
if (fs.existsSync(preferred)) {
|
|
14
|
+
return preferred;
|
|
15
|
+
}
|
|
16
|
+
const bundled = path.join(getServerDir(projectRoot), 'logs');
|
|
17
|
+
if (fs.existsSync(bundled)) {
|
|
18
|
+
return bundled;
|
|
19
|
+
}
|
|
20
|
+
return preferred;
|
|
21
|
+
}
|
|
22
|
+
function normalizeSource(source) {
|
|
23
|
+
const value = String(source || 'error').toLowerCase();
|
|
24
|
+
if (value === 'all')
|
|
25
|
+
return 'all';
|
|
26
|
+
if (LOG_SOURCES.includes(value))
|
|
27
|
+
return value;
|
|
28
|
+
return 'error';
|
|
29
|
+
}
|
|
30
|
+
function listLogFiles(logDir, source = 'error') {
|
|
31
|
+
const normalized = normalizeSource(source);
|
|
32
|
+
const sources = normalized === 'all' ? LOG_SOURCES : [normalized];
|
|
33
|
+
const files = [];
|
|
34
|
+
for (const name of sources) {
|
|
35
|
+
const dir = path.join(logDir, name);
|
|
36
|
+
if (!fs.existsSync(dir))
|
|
37
|
+
continue;
|
|
38
|
+
for (const entry of fs.readdirSync(dir)) {
|
|
39
|
+
if (!entry.endsWith('.log'))
|
|
40
|
+
continue;
|
|
41
|
+
const fullPath = path.join(dir, entry);
|
|
42
|
+
let stat;
|
|
43
|
+
try {
|
|
44
|
+
stat = fs.statSync(fullPath);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (!stat.isFile())
|
|
50
|
+
continue;
|
|
51
|
+
files.push({
|
|
52
|
+
source: name,
|
|
53
|
+
path: fullPath,
|
|
54
|
+
name: entry,
|
|
55
|
+
mtimeMs: stat.mtimeMs,
|
|
56
|
+
size: stat.size,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
files.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
61
|
+
return files;
|
|
62
|
+
}
|
|
63
|
+
function readTailLines(filePath, lineCount = 50) {
|
|
64
|
+
const maxLines = Math.max(1, Math.min(Number(lineCount) || 50, 5000));
|
|
65
|
+
let content;
|
|
66
|
+
try {
|
|
67
|
+
content = fs.readFileSync(filePath, 'utf8');
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
if (!content)
|
|
73
|
+
return [];
|
|
74
|
+
const lines = content.split(/\r?\n/);
|
|
75
|
+
if (lines.length && lines[lines.length - 1] === '') {
|
|
76
|
+
lines.pop();
|
|
77
|
+
}
|
|
78
|
+
if (lines.length <= maxLines)
|
|
79
|
+
return lines;
|
|
80
|
+
return lines.slice(-maxLines);
|
|
81
|
+
}
|
|
82
|
+
function filterLines(lines, pattern) {
|
|
83
|
+
if (!pattern)
|
|
84
|
+
return lines;
|
|
85
|
+
let re;
|
|
86
|
+
try {
|
|
87
|
+
re = new RegExp(pattern, 'i');
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
const err = new Error(t('doctor.logs.badPattern', { pattern }));
|
|
91
|
+
err.code = 'REACTPRESS_LOG_BAD_PATTERN';
|
|
92
|
+
throw err;
|
|
93
|
+
}
|
|
94
|
+
return lines.filter((line) => re.test(line));
|
|
95
|
+
}
|
|
96
|
+
function formatBytes(size) {
|
|
97
|
+
if (size < 1024)
|
|
98
|
+
return `${size} B`;
|
|
99
|
+
if (size < 1024 * 1024)
|
|
100
|
+
return `${(size / 1024).toFixed(1)} KB`;
|
|
101
|
+
return `${(size / (1024 * 1024)).toFixed(1)} MB`;
|
|
102
|
+
}
|
|
103
|
+
function formatTimestamp(ms) {
|
|
104
|
+
return new Date(ms).toISOString().replace('T', ' ').slice(0, 19);
|
|
105
|
+
}
|
|
106
|
+
function printProcessHint(projectRoot) {
|
|
107
|
+
const pid = readPid(projectRoot);
|
|
108
|
+
const pidFile = getPidFile(projectRoot);
|
|
109
|
+
if (!pid) {
|
|
110
|
+
console.log(` ${brand.dim(t('doctor.logs.noPid', { path: pidFile }))}`);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const alive = isProcessRunning(pid);
|
|
114
|
+
console.log(` ${brand.dim(alive
|
|
115
|
+
? t('doctor.logs.pidRunning', { pid, path: pidFile })
|
|
116
|
+
: t('doctor.logs.pidStale', { pid, path: pidFile }))}`);
|
|
117
|
+
}
|
|
118
|
+
async function runDoctorLogs(projectRoot, options = {}) {
|
|
119
|
+
const tail = Math.max(1, Math.min(parseInt(String(options.tail ?? '50'), 10) || 50, 5000));
|
|
120
|
+
const source = normalizeSource(options.source);
|
|
121
|
+
const logDir = getProjectServerLogDir(projectRoot);
|
|
122
|
+
const files = listLogFiles(logDir, source);
|
|
123
|
+
const w = 56;
|
|
124
|
+
console.log('');
|
|
125
|
+
console.log(` ${gradientText(t('doctor.logs.title'), [palette.primary, palette.accent], { bold: true })} ${brand.dim(t('doctor.logs.subtitle'))}`);
|
|
126
|
+
console.log(` ${brand.dim(t('doctor.project', { path: projectRoot }))}`);
|
|
127
|
+
console.log(` ${brand.dim(t('doctor.logs.dir', { path: logDir }))}`);
|
|
128
|
+
printProcessHint(projectRoot);
|
|
129
|
+
console.log(` ${divider(w)}`);
|
|
130
|
+
if (options.list) {
|
|
131
|
+
if (!files.length) {
|
|
132
|
+
console.log(` ${brand.warn(t('doctor.logs.empty'))}`);
|
|
133
|
+
console.log(` ${brand.dim(t('doctor.logs.emptyHint'))}`);
|
|
134
|
+
console.log('');
|
|
135
|
+
return 1;
|
|
136
|
+
}
|
|
137
|
+
console.log(sectionHeader(t('doctor.logs.listHeader')));
|
|
138
|
+
for (const file of files) {
|
|
139
|
+
const rel = path.join(file.source, file.name);
|
|
140
|
+
console.log(` ${brand.primary(rel)} ${brand.dim(`${formatBytes(file.size)} ${formatTimestamp(file.mtimeMs)}`)}`);
|
|
141
|
+
}
|
|
142
|
+
console.log('');
|
|
143
|
+
return 0;
|
|
144
|
+
}
|
|
145
|
+
if (!files.length) {
|
|
146
|
+
console.log(` ${brand.warn(t('doctor.logs.empty'))}`);
|
|
147
|
+
console.log(` ${brand.dim(t('doctor.logs.emptyHint'))}`);
|
|
148
|
+
console.log('');
|
|
149
|
+
return 1;
|
|
150
|
+
}
|
|
151
|
+
const grouped = new Map();
|
|
152
|
+
for (const file of files) {
|
|
153
|
+
if (!grouped.has(file.source))
|
|
154
|
+
grouped.set(file.source, file);
|
|
155
|
+
}
|
|
156
|
+
let printed = 0;
|
|
157
|
+
for (const name of source === 'all' ? LOG_SOURCES : [source]) {
|
|
158
|
+
const file = grouped.get(name);
|
|
159
|
+
if (!file)
|
|
160
|
+
continue;
|
|
161
|
+
let lines = readTailLines(file.path, tail);
|
|
162
|
+
lines = filterLines(lines, options.grep);
|
|
163
|
+
const rel = path.join(file.source, file.name);
|
|
164
|
+
console.log('');
|
|
165
|
+
console.log(sectionHeader(t('doctor.logs.fileHeader', {
|
|
166
|
+
file: rel,
|
|
167
|
+
count: lines.length,
|
|
168
|
+
})));
|
|
169
|
+
if (!lines.length) {
|
|
170
|
+
console.log(` ${brand.dim(t('doctor.logs.noMatchingLines'))}`);
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
for (const line of lines) {
|
|
174
|
+
const isError = /\[ERROR\]/i.test(line) || name === 'error';
|
|
175
|
+
console.log(` ${isError ? brand.warn(line) : brand.dim(line)}`);
|
|
176
|
+
}
|
|
177
|
+
printed += lines.length;
|
|
178
|
+
}
|
|
179
|
+
if (!printed) {
|
|
180
|
+
console.log(` ${brand.warn(t('doctor.logs.noMatchingLines'))}`);
|
|
181
|
+
console.log('');
|
|
182
|
+
return 1;
|
|
183
|
+
}
|
|
184
|
+
console.log('');
|
|
185
|
+
console.log(` ${brand.dim(t('doctor.logs.moreHint'))}`);
|
|
186
|
+
console.log('');
|
|
187
|
+
return 0;
|
|
188
|
+
}
|
|
189
|
+
module.exports = {
|
|
190
|
+
LOG_SOURCES,
|
|
191
|
+
getProjectServerLogDir,
|
|
192
|
+
listLogFiles,
|
|
193
|
+
readTailLines,
|
|
194
|
+
filterLines,
|
|
195
|
+
runDoctorLogs,
|
|
196
|
+
};
|
|
197
|
+
//# sourceMappingURL=project-logs.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fecommunity/reactpress",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.13",
|
|
4
4
|
"description": "ReactPress 4 — zero-dependency publishing platform. Commands: reactpress init, reactpress doctor",
|
|
5
5
|
"author": "fecommunity",
|
|
6
6
|
"license": "MIT",
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"dist",
|
|
30
30
|
"server",
|
|
31
31
|
"toolkit",
|
|
32
|
+
"admin-dist",
|
|
32
33
|
"templates",
|
|
33
34
|
"scripts/install-bundled-runtime.mjs",
|
|
34
35
|
"README.md",
|
|
@@ -27,7 +27,9 @@ let ExtensionModule = class ExtensionModule {
|
|
|
27
27
|
this.pluginLoader = pluginLoader;
|
|
28
28
|
}
|
|
29
29
|
onModuleInit() {
|
|
30
|
-
void this.themeService.ensureDefaultTheme()
|
|
30
|
+
void this.themeService.ensureDefaultTheme().catch((err) => {
|
|
31
|
+
console.warn('[ThemeService] ensureDefaultTheme skipped:', err instanceof Error ? err.message : err);
|
|
32
|
+
});
|
|
31
33
|
void this.pluginLoader.loadActivePlugins();
|
|
32
34
|
}
|
|
33
35
|
};
|
|
@@ -5,11 +5,33 @@ const fs = require("fs");
|
|
|
5
5
|
const path = require("path");
|
|
6
6
|
const project_root_util_1 = require("../../utils/project-root.util");
|
|
7
7
|
let cached = null;
|
|
8
|
+
function resolveBundledCliPackageRoot() {
|
|
9
|
+
const serverRoot = path.join(__dirname, '..', '..', '..');
|
|
10
|
+
const cliRoot = path.dirname(serverRoot);
|
|
11
|
+
const registryPath = path.join(cliRoot, 'out', 'lib', 'theme-registry.js');
|
|
12
|
+
if (fs.existsSync(registryPath)) {
|
|
13
|
+
return cliRoot;
|
|
14
|
+
}
|
|
15
|
+
try {
|
|
16
|
+
const pkgPath = path.join(cliRoot, 'package.json');
|
|
17
|
+
if (!fs.existsSync(pkgPath))
|
|
18
|
+
return null;
|
|
19
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
20
|
+
if (pkg.name === '@fecommunity/reactpress') {
|
|
21
|
+
return cliRoot;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
catch (_a) {
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
8
28
|
function resolveThemeRegistryPath(monorepoRoot) {
|
|
29
|
+
const bundledCliRoot = resolveBundledCliPackageRoot();
|
|
9
30
|
const candidates = [
|
|
31
|
+
bundledCliRoot ? path.join(bundledCliRoot, 'out', 'lib', 'theme-registry.js') : null,
|
|
10
32
|
path.join(monorepoRoot, 'cli', 'out', 'lib', 'theme-registry.js'),
|
|
11
33
|
path.join(monorepoRoot, 'cli', 'lib', 'theme-registry.js'),
|
|
12
|
-
];
|
|
34
|
+
].filter(Boolean);
|
|
13
35
|
for (const candidate of candidates) {
|
|
14
36
|
if (fs.existsSync(candidate))
|
|
15
37
|
return candidate;
|
package/server/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fecommunity/reactpress-server",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.13",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@fecommunity/reactpress-server",
|
|
9
|
-
"version": "4.0.0-beta.
|
|
9
|
+
"version": "4.0.0-beta.13",
|
|
10
10
|
"deprecated": "Use the built-in API in @fecommunity/reactpress (CLI). Standalone server publishing stopped from 3.1.",
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"dependencies": {
|
|
@@ -47,8 +47,6 @@
|
|
|
47
47
|
"passport": "^0.4.1",
|
|
48
48
|
"passport-jwt": "^4.0.0",
|
|
49
49
|
"pm2": "^5.2.0",
|
|
50
|
-
"react": "^19.2.7",
|
|
51
|
-
"react-dom": "^19.2.7",
|
|
52
50
|
"reflect-metadata": "^0.1.13",
|
|
53
51
|
"rimraf": "^3.0.0",
|
|
54
52
|
"rxjs": "^6.5.3",
|
|
@@ -93,7 +91,7 @@
|
|
|
93
91
|
},
|
|
94
92
|
"../toolkit": {
|
|
95
93
|
"name": "@fecommunity/reactpress-toolkit",
|
|
96
|
-
"version": "4.0.0-beta.
|
|
94
|
+
"version": "4.0.0-beta.13",
|
|
97
95
|
"dependencies": {
|
|
98
96
|
"ajv": "^8.17.1",
|
|
99
97
|
"axios": "^1.12.2",
|
|
@@ -15827,27 +15825,6 @@
|
|
|
15827
15825
|
"node": ">=0.10.0"
|
|
15828
15826
|
}
|
|
15829
15827
|
},
|
|
15830
|
-
"node_modules/react": {
|
|
15831
|
-
"version": "19.2.7",
|
|
15832
|
-
"resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz",
|
|
15833
|
-
"integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==",
|
|
15834
|
-
"license": "MIT",
|
|
15835
|
-
"engines": {
|
|
15836
|
-
"node": ">=0.10.0"
|
|
15837
|
-
}
|
|
15838
|
-
},
|
|
15839
|
-
"node_modules/react-dom": {
|
|
15840
|
-
"version": "19.2.7",
|
|
15841
|
-
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz",
|
|
15842
|
-
"integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==",
|
|
15843
|
-
"license": "MIT",
|
|
15844
|
-
"dependencies": {
|
|
15845
|
-
"scheduler": "^0.27.0"
|
|
15846
|
-
},
|
|
15847
|
-
"peerDependencies": {
|
|
15848
|
-
"react": "^19.2.7"
|
|
15849
|
-
}
|
|
15850
|
-
},
|
|
15851
15828
|
"node_modules/react-is": {
|
|
15852
15829
|
"version": "16.13.1",
|
|
15853
15830
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
|
@@ -16762,12 +16739,6 @@
|
|
|
16762
16739
|
"node": ">=11.0.0"
|
|
16763
16740
|
}
|
|
16764
16741
|
},
|
|
16765
|
-
"node_modules/scheduler": {
|
|
16766
|
-
"version": "0.27.0",
|
|
16767
|
-
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
|
|
16768
|
-
"integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==",
|
|
16769
|
-
"license": "MIT"
|
|
16770
|
-
},
|
|
16771
16742
|
"node_modules/schema-utils": {
|
|
16772
16743
|
"version": "1.0.0",
|
|
16773
16744
|
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
|
package/server/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fecommunity/reactpress-server",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.13",
|
|
4
4
|
"deprecated": "Use the built-in API in @fecommunity/reactpress (CLI). Standalone server publishing stopped from 3.1.",
|
|
5
5
|
"description": "ReactPress NestJS CMS API — headless REST for the publishing platform (MySQL or SQLite)",
|
|
6
6
|
"author": "fecommunity",
|