diff --git a/.umirc.ts b/.umirc.ts index 7ff3cc24..e19224cb 100644 --- a/.umirc.ts +++ b/.umirc.ts @@ -4,6 +4,7 @@ const CompressionPlugin = require('compression-webpack-plugin'); const baseUrl = process.env.QlBaseUrl || '/'; export default defineConfig({ hash: true, + jsMinifier: 'terser', antd: {}, locale: { antd: true, diff --git a/back/api/system.ts b/back/api/system.ts index f45ac035..c1d8c16a 100644 --- a/back/api/system.ts +++ b/back/api/system.ts @@ -249,4 +249,17 @@ export default (app: Router) => { } }, ); + + route.get( + '/log', + async (req: Request, res: Response, next: NextFunction) => { + try { + const systemService = Container.get(SystemService); + await systemService.getSystemLog(res); + } catch (e) { + return next(e); + } + }, + ); + }; diff --git a/back/app.ts b/back/app.ts index a6ae89d0..8e6ae90a 100644 --- a/back/app.ts +++ b/back/app.ts @@ -18,10 +18,12 @@ async function startServer() { const server = app .listen(config.port, () => { Logger.debug(`✌️ 后端服务启动成功!`); + console.debug(`✌️ 后端服务启动成功!`); process.send?.('ready'); }) .on('error', (err) => { Logger.error(err); + console.error(err); process.exit(1); }); diff --git a/back/config/index.ts b/back/config/index.ts index 3c7ac0d8..952324bf 100644 --- a/back/config/index.ts +++ b/back/config/index.ts @@ -30,6 +30,7 @@ const logPath = path.join(dataPath, 'log/'); const dbPath = path.join(dataPath, 'db/'); const uploadPath = path.join(dataPath, 'upload/'); const sshdPath = path.join(dataPath, 'ssh.d/'); +const systemLogPath = path.join(dataPath, 'syslog/'); const envFile = path.join(configPath, 'env.sh'); const confFile = path.join(configPath, 'config.sh'); @@ -110,4 +111,5 @@ export default { lastVersionFile, sqliteFile, sshdPath, + systemLogPath, }; diff --git a/back/config/util.ts b/back/config/util.ts index 952ebf89..0d50a34a 100644 --- a/back/config/util.ts +++ b/back/config/util.ts @@ -307,22 +307,28 @@ interface IFile { type: 'directory' | 'file'; parent: string; mtime: number; + size?: number; children?: IFile[]; } -export function dirSort(a: IFile, b: IFile) { - if (a.type !== b.type) return FileType[a.type] < FileType[b.type] ? -1 : 1; - else if (a.mtime !== b.mtime) return a.mtime > b.mtime ? -1 : 1; +export function dirSort(a: IFile, b: IFile): number { + if (a.type !== b.type) { + return FileType[a.type] < FileType[b.type] ? -1 : 1 + }else if (a.mtime !== b.mtime) { + return a.mtime > b.mtime ? -1 : 1 + } else { + return 0; + } } export function readDirs( dir: string, baseDir: string = '', blacklist: string[] = [], -) { +): IFile[] { const relativePath = path.relative(baseDir, dir); const files = fs.readdirSync(dir); - const result: any = files + const result: IFile[] = files .filter((x) => !blacklist.includes(x)) .map((file: string) => { const subPath = path.join(dir, file); @@ -344,6 +350,7 @@ export function readDirs( isLeaf: true, key, parent: relativePath, + size: stats.size, mtime: stats.mtime.getTime(), }; }); diff --git a/back/loaders/app.ts b/back/loaders/app.ts index 14ea2f22..4a1c16c1 100644 --- a/back/loaders/app.ts +++ b/back/loaders/app.ts @@ -10,20 +10,25 @@ export default async ({ expressApp }: { expressApp: Application }) => { try { depInjectorLoader(); Logger.info('✌️ Dependency Injector loaded'); + console.log('✌️ Dependency Injector loaded'); expressLoader({ app: expressApp }); Logger.info('✌️ Express loaded'); + console.log('✌️ Express loaded'); await initData(); Logger.info('✌️ init data loaded'); + console.log('✌️ init data loaded'); await linkDeps(); Logger.info('✌️ link deps loaded'); + console.log('✌️ link deps loaded'); initTask(); Logger.info('✌️ init task loaded'); + console.log('✌️ init task loaded'); } catch (error) { - Logger.info('✌️ depInjectorLoader expressLoader initData linkDeps failed'); - Logger.error(error); + Logger.error(`✌️ depInjectorLoader expressLoader initData linkDeps failed, ${error}`); + console.error(`✌️ depInjectorLoader expressLoader initData linkDeps failed ${error}`); } }; diff --git a/back/loaders/db.ts b/back/loaders/db.ts index 5cc16989..49f64f90 100644 --- a/back/loaders/db.ts +++ b/back/loaders/db.ts @@ -122,9 +122,10 @@ export default async () => { }); } + console.log('✌️ DB loaded'); Logger.info('✌️ DB loaded'); } catch (error) { - Logger.info('✌️ DB load failed'); + console.error('✌️ DB load failed'); Logger.error(error); } }; diff --git a/back/loaders/express.ts b/back/loaders/express.ts index 4c1ca5a1..3ae2450d 100644 --- a/back/loaders/express.ts +++ b/back/loaders/express.ts @@ -15,6 +15,7 @@ import { EnvModel } from '../data/env'; import { errors } from 'celebrate'; import { createProxyMiddleware } from 'http-proxy-middleware'; import { serveEnv } from '../config/serverEnv'; +import Logger from './logger'; export default ({ app }: { app: Application }) => { app.enable('trust proxy'); @@ -28,6 +29,7 @@ export default ({ app }: { app: Application }) => { target: `http://localhost:${config.publicPort}/api`, changeOrigin: true, pathRewrite: { '/api/public': '' }, + logProvider: () => Logger }), ); diff --git a/back/loaders/initFile.ts b/back/loaders/initFile.ts index ec0e03d8..65e7ed46 100644 --- a/back/loaders/initFile.ts +++ b/back/loaders/initFile.ts @@ -28,6 +28,7 @@ const TaskAfterFile = path.join(configPath, 'task_after.sh'); const homedir = os.homedir(); const sshPath = path.resolve(homedir, '.ssh'); const sshdPath = path.join(dataPath, 'ssh.d'); +const systemLogPath = path.join(dataPath, 'syslog'); export default async () => { const authFileExist = await fileExist(authConfigFile); @@ -39,6 +40,7 @@ export default async () => { const sshDirExist = await fileExist(sshPath); const bakDirExist = await fileExist(bakPath); const sshdDirExist = await fileExist(sshdPath); + const systemLogDirExist = await fileExist(systemLogPath); const tmpDirExist = await fileExist(tmpPath); const scriptNotifyJsFileExist = await fileExist(scriptNotifyJsFile); const scriptNotifyPyFileExist = await fileExist(scriptNotifyPyFile); @@ -77,6 +79,10 @@ export default async () => { fs.mkdirSync(sshdPath); } + if (!systemLogDirExist) { + fs.mkdirSync(systemLogPath); + } + // 初始化文件 if (!authFileExist) { fs.writeFileSync(authConfigFile, fs.readFileSync(sampleAuthFile)); @@ -105,4 +111,5 @@ export default async () => { dotenv.config({ path: confFile }); Logger.info('✌️ Init file down'); + console.log('✌️ Init file down'); }; diff --git a/back/loaders/logger.ts b/back/loaders/logger.ts index 7b65e3ca..73cc8782 100644 --- a/back/loaders/logger.ts +++ b/back/loaders/logger.ts @@ -1,32 +1,38 @@ import winston from 'winston'; +import 'winston-daily-rotate-file'; import config from '../config'; +import path from 'path'; -const transports = []; -if (process.env.NODE_ENV !== 'development') { - transports.push(new winston.transports.Console()); -} else { - transports.push( - new winston.transports.Console({ - format: winston.format.combine( - winston.format.cli(), - winston.format.splat(), - ), - }), - ); +const levelMap: Record = { + info: '🔵', + warn: '🟡', + error: '🔴', + debug: '🔶' } +const customFormat = winston.format.combine( + winston.format.splat(), + winston.format.timestamp({ format: "YYYY-MM-DD HH:mm:ss" }), + winston.format.align(), + winston.format.printf((i) => `[${levelMap[i.level]}${i.level}] [${[i.timestamp]}]: ${i.message}`), +); + +const defaultOptions = { + format: customFormat, + datePattern: "YYYY-MM-DD", + maxSize: "20m", + maxFiles: "7d", +}; + const LoggerInstance = winston.createLogger({ level: config.logs.level, levels: winston.config.npm.levels, - format: winston.format.combine( - winston.format.timestamp({ - format: 'YYYY-MM-DD HH:mm:ss', - }), - winston.format.errors({ stack: true }), - winston.format.splat(), - winston.format.json(), - ), - transports, + transports: [ + new winston.transports.DailyRotateFile({ + filename: path.join(config.systemLogPath, '%DATE%.log'), + ...defaultOptions, + }) + ], }); export default LoggerInstance; diff --git a/back/loaders/sentry.ts b/back/loaders/sentry.ts index 2a91d97f..53d1de88 100644 --- a/back/loaders/sentry.ts +++ b/back/loaders/sentry.ts @@ -29,4 +29,5 @@ export default async ({ expressApp }: { expressApp: Application }) => { expressApp.use(Sentry.Handlers.tracingHandler()); Logger.info('✌️ Sentry loaded'); + console.log('✌️ Sentry loaded'); }; diff --git a/back/loaders/server.ts b/back/loaders/server.ts index 31c3e387..f2de8b9e 100644 --- a/back/loaders/server.ts +++ b/back/loaders/server.ts @@ -10,9 +10,11 @@ export default async ({ server }: { server: Server }) => { process.on('SIGINT', (singal) => { Logger.warn(`Server need close, singal ${singal}`); + console.warn(`Server need close, singal ${singal}`); exitTime++; if (exitTime >= 3) { Logger.warn('Forcing server close'); + console.warn('Forcing server close'); clearTimeout(timer); process.exit(1); } @@ -28,11 +30,13 @@ export default async ({ server }: { server: Server }) => { process.on('uncaughtException', (error) => { Logger.error('Uncaught exception:', error); + console.error('Uncaught exception:', error); process.exit(1); }); process.on('unhandledRejection', (reason, promise) => { - Logger.error('Unhandled rejection:', reason); + Logger.error('Unhandled rejection:', reason, promise); + console.error('Unhandled rejection:', reason, promise); process.exit(1); }); }; diff --git a/back/public.ts b/back/public.ts index 094c99ea..2cc7174d 100644 --- a/back/public.ts +++ b/back/public.ts @@ -6,7 +6,7 @@ import { credentials } from '@grpc/grpc-js'; const app = express(); const client = new HealthClient( - `localhost:${config.cronPort}`, + `0.0.0.0:${config.cronPort}`, credentials.createInsecure(), ); @@ -25,9 +25,11 @@ app await require('./loaders/db').default(); Logger.debug(`✌️ 公共服务启动成功!`); + console.debug(`✌️ 公共服务启动成功!`); process.send?.('ready'); }) .on('error', (err) => { Logger.error(err); + console.error(err); process.exit(1); }); diff --git a/back/schedule/addCron.ts b/back/schedule/addCron.ts index a3f101ec..15f805ee 100644 --- a/back/schedule/addCron.ts +++ b/back/schedule/addCron.ts @@ -22,11 +22,18 @@ const addCron = ( cmdStr = `${TASK_PREFIX}${cmdStr}`; } + Logger.info( + '[schedule][创建定时任务], 任务ID: %s, cron: %s, 执行命令: %s', + id, + schedule, + command, + ); + scheduleStacks.set( id, nodeSchedule.scheduleJob(id, schedule, async () => { Logger.info( - `当前时间: ${dayjs().format( + `[schedule] 时间: ${dayjs().format( 'YYYY-MM-DD HH:mm:ss', )},运行命令: ${cmdStr}`, ); diff --git a/back/schedule/delCron.ts b/back/schedule/delCron.ts index 0582d1f3..0608a794 100644 --- a/back/schedule/delCron.ts +++ b/back/schedule/delCron.ts @@ -1,6 +1,7 @@ import { ServerUnaryCall, sendUnaryData } from '@grpc/grpc-js'; import { DeleteCronRequest, DeleteCronResponse } from '../protos/cron'; import { scheduleStacks } from './data'; +import Logger from '../loaders/logger'; const delCron = ( call: ServerUnaryCall, @@ -8,6 +9,10 @@ const delCron = ( ) => { for (const id of call.request.ids) { if (scheduleStacks.has(id)) { + Logger.info( + '[schedule][取消定时任务], 任务ID: %s', + id, + ); scheduleStacks.get(id)?.cancel(); scheduleStacks.delete(id); } diff --git a/back/schedule/index.ts b/back/schedule/index.ts index 71e00d81..caea567c 100644 --- a/back/schedule/index.ts +++ b/back/schedule/index.ts @@ -11,7 +11,7 @@ const server = new Server(); server.addService(HealthService, { check }); server.addService(CronService, { addCron, delCron }); server.bindAsync( - `localhost:${config.cronPort}`, + `0.0.0.0:${config.cronPort}`, ServerCredentials.createInsecure(), (err, port) => { if (err) { @@ -19,6 +19,7 @@ server.bindAsync( } server.start(); Logger.debug(`✌️ 定时服务启动成功!`); + console.debug(`✌️ 定时服务启动成功!`); process.send?.('ready'); }, ); diff --git a/back/services/cron.ts b/back/services/cron.ts index 1d915da4..ca2908e7 100644 --- a/back/services/cron.ts +++ b/back/services/cron.ts @@ -370,7 +370,7 @@ export default class CronService { try { await killTask(doc.pid); } catch (error) { - this.logger.silly(error); + this.logger.error(error); } } } @@ -530,7 +530,6 @@ export default class CronService { } }); - this.logger.silly(crontab_string); fs.writeFileSync(config.crontabFile, crontab_string); execSync(`crontab ${config.crontabFile}`); diff --git a/back/services/schedule.ts b/back/services/schedule.ts index 88574729..dbb341b1 100644 --- a/back/services/schedule.ts +++ b/back/services/schedule.ts @@ -66,7 +66,7 @@ export default class ScheduleService { cp.stderr.on('data', async (data) => { this.logger.info( - '[执行任务失败] %s,时间:%s, 错误信息:%j', + '[执行任务失败] %s, 时间: %s, 错误信息: %j', command, new Date().toLocaleString(), data.toString(), @@ -76,7 +76,7 @@ export default class ScheduleService { cp.on('error', async (err) => { this.logger.error( - '[创建任务失败] %s,时间:%s, 错误信息:%j', + '[创建任务失败] %s, 时间: %s, 错误信息: %j', command, new Date().toLocaleString(), err, @@ -86,7 +86,7 @@ export default class ScheduleService { cp.on('exit', async (code, signal) => { this.logger.info( - `[任务退出] ${command} 进程id: ${cp.pid},退出码 ${code}`, + `[任务退出] ${command} 进程id: ${cp.pid}, 退出码 ${code}`, ); }); @@ -101,7 +101,7 @@ export default class ScheduleService { }); } catch (error) { await this.logger.error( - '执行任务%s失败,时间:%s, 错误信息:%j', + '[执行任务失败] 命令: %s, 时间: %s, 错误信息: %j', command, new Date().toLocaleString(), error, @@ -119,7 +119,7 @@ export default class ScheduleService { ) { const _id = this.formatId(id); this.logger.info( - '[创建cron任务],任务ID: %s,cron: %s,任务名: %s,执行命令: %s', + '[创建cron任务], 任务ID: %s, cron: %s, 任务名: %s, 执行命令: %s', _id, schedule, name, @@ -140,7 +140,7 @@ export default class ScheduleService { async cancelCronTask({ id = 0, name }: ScheduleTaskType) { const _id = this.formatId(id); - this.logger.info('[取消定时任务],任务名:%s', name); + this.logger.info('[取消定时任务], 任务名: %s', name); if (this.scheduleStacks.has(_id)) { this.scheduleStacks.get(_id)?.cancel(); this.scheduleStacks.delete(_id); @@ -155,7 +155,7 @@ export default class ScheduleService { ) { const _id = this.formatId(id); this.logger.info( - '[创建interval任务],任务ID: %s,任务名: %s,执行命令: %s', + '[创建interval任务], 任务ID: %s, 任务名: %s, 执行命令: %s', _id, name, command, @@ -167,7 +167,7 @@ export default class ScheduleService { }, (err) => { this.logger.error( - '执行任务%s失败,时间:%s, 错误信息:%j', + '[执行任务失败] 命令: %s, 时间: %s, 错误信息: %j', command, new Date().toLocaleString(), err, @@ -190,7 +190,7 @@ export default class ScheduleService { async cancelIntervalTask({ id = 0, name }: ScheduleTaskType) { const _id = this.formatId(id); - this.logger.info('[取消interval任务],任务ID: %s,任务名:%s', _id, name); + this.logger.info('[取消interval任务], 任务ID: %s, 任务名: %s', _id, name); this.intervalSchedule.removeById(_id); } diff --git a/back/services/subscription.ts b/back/services/subscription.ts index 842977a2..008a5e91 100644 --- a/back/services/subscription.ts +++ b/back/services/subscription.ts @@ -301,7 +301,7 @@ export default class SubscriptionService { try { await killTask(doc.pid); } catch (error) { - this.logger.silly(error); + this.logger.error(error); } } const absolutePath = await handleLogPath(doc.log_path as string); diff --git a/back/services/system.ts b/back/services/system.ts index d36d5c72..d24c36e6 100644 --- a/back/services/system.ts +++ b/back/services/system.ts @@ -21,11 +21,14 @@ import { parseContentVersion, parseVersion, promiseExec, + readDirs, } from '../config/util'; import { TASK_COMMAND } from '../config/const'; import taskLimit from '../shared/pLimit'; import tar from 'tar'; import path from 'path'; +import fs from 'fs'; +import { sum } from 'lodash'; @Service() export default class SystemService { @@ -275,4 +278,29 @@ export default class SystemService { return { code: 400, message: error.message }; } } + + public async getSystemLog(res: Response) { + const result = readDirs(config.systemLogPath, config.systemLogPath); + const logs = result.reverse().filter((x) => x.title.endsWith('.log')); + res.set({ + 'Content-Length': sum(logs.map((x) => x.size)), + }); + (function sendFiles(res, fileNames) { + if (fileNames.length === 0) { + res.end(); + return; + } + + const currentLog = fileNames.shift(); + if (currentLog) { + const currentFileStream = fs.createReadStream( + path.join(config.systemLogPath, currentLog.title), + ); + currentFileStream.on('end', () => { + sendFiles(res, fileNames); + }); + currentFileStream.pipe(res, { end: false }); + } + })(res, logs); + } } diff --git a/back/shared/runCron.ts b/back/shared/runCron.ts index 63ad84e1..c6fdbde6 100644 --- a/back/shared/runCron.ts +++ b/back/shared/runCron.ts @@ -5,13 +5,13 @@ import Logger from '../loaders/logger'; export function runCron(cmd: string): Promise { return taskLimit.runWithCpuLimit(() => { return new Promise(async (resolve: any) => { - Logger.silly('运行命令: ' + cmd); + Logger.info(`[schedule][开始执行任务] 运行命令: ${cmd}`); const cp = spawn(cmd, { shell: '/bin/bash' }); cp.stderr.on('data', (data) => { Logger.info( - '[执行任务失败] %s,时间:%s, 错误信息:%j', + '[schedule][执行任务失败] %s, 时间: %s, 错误信息: %j', cmd, new Date().toLocaleString(), data.toString(), @@ -19,7 +19,7 @@ export function runCron(cmd: string): Promise { }); cp.on('error', (err) => { Logger.error( - '[创建任务失败] %s,时间:%s, 错误信息:%j', + '[schedule][创建任务失败] %s, 时间: %s, 错误信息: %j', cmd, new Date().toLocaleString(), err, @@ -27,7 +27,7 @@ export function runCron(cmd: string): Promise { }); cp.on('close', async (code) => { - Logger.info(`[任务退出] ${cmd} 进程id: ${cp.pid} 退出,退出码 ${code}`); + Logger.info(`[schedule][任务退出] ${cmd} 进程id: ${cp.pid} 退出, 退出码 ${code}`); resolve(); }); }); diff --git a/package.json b/package.json index 34cfc943..9afdc0d3 100644 --- a/package.json +++ b/package.json @@ -96,6 +96,7 @@ "typedi": "^0.10.0", "uuid": "^8.3.2", "winston": "^3.6.0", + "winston-daily-rotate-file": "^4.7.1", "yargs": "^17.3.1" }, "devDependencies": { @@ -127,6 +128,8 @@ "@types/sockjs-client": "^1.5.1", "@types/tar": "^6.1.5", "@types/uuid": "^8.3.4", + "@uiw/codemirror-extensions-langs": "^4.21.9", + "@uiw/react-codemirror": "^4.21.9", "@umijs/max": "^4.0.72", "@umijs/ssr-darkreader": "^4.9.45", "ahooks": "^3.7.8", @@ -134,7 +137,6 @@ "antd": "^4.24.8", "antd-img-crop": "^4.2.3", "axios": "^1.4.0", - "codemirror": "^5.65.2", "compression-webpack-plugin": "9.2.0", "concurrently": "^7.0.0", "file-saver": "^2.0.5", @@ -148,7 +150,6 @@ "rc-tween-one": "^3.0.6", "rc-virtual-list": "3.5.3", "react": "18.2.0", - "react-codemirror2": "^7.2.1", "react-copy-to-clipboard": "^5.1.0", "react-diff-viewer": "^3.1.1", "react-dnd": "^14.0.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ee1d5ee1..fb6b74c4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -124,6 +124,9 @@ dependencies: winston: specifier: ^3.6.0 version: 3.9.0 + winston-daily-rotate-file: + specifier: ^4.7.1 + version: 4.7.1(winston@3.9.0) yargs: specifier: ^17.3.1 version: 17.7.2 @@ -213,6 +216,12 @@ devDependencies: '@types/uuid': specifier: ^8.3.4 version: 8.3.4 + '@uiw/codemirror-extensions-langs': + specifier: ^4.21.9 + version: 4.21.9(@codemirror/autocomplete@6.9.0)(@codemirror/language-data@6.3.1)(@codemirror/language@6.9.0)(@codemirror/legacy-modes@6.3.3)(@codemirror/state@6.2.1)(@codemirror/view@6.16.0)(@lezer/common@1.0.4)(@lezer/highlight@1.1.6)(@lezer/javascript@1.4.5)(@lezer/lr@1.3.10) + '@uiw/react-codemirror': + specifier: ^4.21.9 + version: 4.21.9(@babel/runtime@7.22.3)(@codemirror/autocomplete@6.9.0)(@codemirror/language@6.9.0)(@codemirror/lint@6.4.0)(@codemirror/search@6.5.1)(@codemirror/state@6.2.1)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.16.0)(codemirror@6.0.1)(react-dom@18.2.0)(react@18.2.0) '@umijs/max': specifier: ^4.0.72 version: 4.0.72(@types/node@17.0.45)(@types/react-dom@18.2.4)(@types/react@18.2.8)(prettier@2.8.8)(react-dom@18.2.0)(react@18.2.0)(sockjs-client@1.6.1)(typescript@4.8.4)(webpack@5.85.1) @@ -234,9 +243,6 @@ devDependencies: axios: specifier: ^1.4.0 version: 1.4.0 - codemirror: - specifier: ^5.65.2 - version: 5.65.13 compression-webpack-plugin: specifier: 9.2.0 version: 9.2.0(webpack@5.85.1) @@ -276,9 +282,6 @@ devDependencies: react: specifier: 18.2.0 version: 18.2.0 - react-codemirror2: - specifier: ^7.2.1 - version: 7.2.1(codemirror@5.65.13)(react@18.2.0) react-copy-to-clipboard: specifier: ^5.1.0 version: 5.1.0(react@18.2.0) @@ -2762,6 +2765,298 @@ packages: tinycolor2: 1.6.0 dev: true + /@codemirror/autocomplete@6.9.0(@codemirror/language@6.9.0)(@codemirror/state@6.2.1)(@codemirror/view@6.16.0)(@lezer/common@1.0.4): + resolution: {integrity: sha512-Fbwm0V/Wn3BkEJZRhr0hi5BhCo5a7eBL6LYaliPjOSwCyfOpnjXY59HruSxOUNV+1OYer0Tgx1zRNQttjXyDog==} + peerDependencies: + '@codemirror/language': ^6.0.0 + '@codemirror/state': ^6.0.0 + '@codemirror/view': ^6.0.0 + '@lezer/common': ^1.0.0 + dependencies: + '@codemirror/language': 6.9.0 + '@codemirror/state': 6.2.1 + '@codemirror/view': 6.16.0 + '@lezer/common': 1.0.4 + dev: true + + /@codemirror/commands@6.2.4: + resolution: {integrity: sha512-42lmDqVH0ttfilLShReLXsDfASKLXzfyC36bzwcqzox9PlHulMcsUOfHXNo2X2aFMVNUoQ7j+d4q5bnfseYoOA==} + dependencies: + '@codemirror/language': 6.9.0 + '@codemirror/state': 6.2.1 + '@codemirror/view': 6.16.0 + '@lezer/common': 1.0.4 + dev: true + + /@codemirror/lang-angular@0.1.2: + resolution: {integrity: sha512-Nq7lmx9SU+JyoaRcs6SaJs7uAmW2W06HpgJVQYeZptVGNWDzDvzhjwVb/ZuG1rwTlOocY4Y9GwNOBuKCeJbKtw==} + dependencies: + '@codemirror/lang-html': 6.4.5 + '@codemirror/lang-javascript': 6.1.9 + '@codemirror/language': 6.9.0 + '@lezer/common': 1.0.4 + '@lezer/highlight': 1.1.6 + '@lezer/lr': 1.3.10 + dev: true + + /@codemirror/lang-cpp@6.0.2: + resolution: {integrity: sha512-6oYEYUKHvrnacXxWxYa6t4puTlbN3dgV662BDfSH8+MfjQjVmP697/KYTDOqpxgerkvoNm7q5wlFMBeX8ZMocg==} + dependencies: + '@codemirror/language': 6.9.0 + '@lezer/cpp': 1.1.1 + dev: true + + /@codemirror/lang-css@6.2.1(@codemirror/view@6.16.0): + resolution: {integrity: sha512-/UNWDNV5Viwi/1lpr/dIXJNWiwDxpw13I4pTUAsNxZdg6E0mI2kTQb0P2iHczg1Tu+H4EBgJR+hYhKiHKko7qg==} + dependencies: + '@codemirror/autocomplete': 6.9.0(@codemirror/language@6.9.0)(@codemirror/state@6.2.1)(@codemirror/view@6.16.0)(@lezer/common@1.0.4) + '@codemirror/language': 6.9.0 + '@codemirror/state': 6.2.1 + '@lezer/common': 1.0.4 + '@lezer/css': 1.1.3 + transitivePeerDependencies: + - '@codemirror/view' + dev: true + + /@codemirror/lang-html@6.4.5: + resolution: {integrity: sha512-dUCSxkIw2G+chaUfw3Gfu5kkN83vJQN8gfQDp9iEHsIZluMJA0YJveT12zg/28BJx+uPsbQ6VimKCgx3oJrZxA==} + dependencies: + '@codemirror/autocomplete': 6.9.0(@codemirror/language@6.9.0)(@codemirror/state@6.2.1)(@codemirror/view@6.16.0)(@lezer/common@1.0.4) + '@codemirror/lang-css': 6.2.1(@codemirror/view@6.16.0) + '@codemirror/lang-javascript': 6.1.9 + '@codemirror/language': 6.9.0 + '@codemirror/state': 6.2.1 + '@codemirror/view': 6.16.0 + '@lezer/common': 1.0.4 + '@lezer/css': 1.1.3 + '@lezer/html': 1.3.6 + dev: true + + /@codemirror/lang-java@6.0.1: + resolution: {integrity: sha512-OOnmhH67h97jHzCuFaIEspbmsT98fNdhVhmA3zCxW0cn7l8rChDhZtwiwJ/JOKXgfm4J+ELxQihxaI7bj7mJRg==} + dependencies: + '@codemirror/language': 6.9.0 + '@lezer/java': 1.0.4 + dev: true + + /@codemirror/lang-javascript@6.1.9: + resolution: {integrity: sha512-z3jdkcqOEBT2txn2a87A0jSy6Te3679wg/U8QzMeftFt+4KA6QooMwfdFzJiuC3L6fXKfTXZcDocoaxMYfGz0w==} + dependencies: + '@codemirror/autocomplete': 6.9.0(@codemirror/language@6.9.0)(@codemirror/state@6.2.1)(@codemirror/view@6.16.0)(@lezer/common@1.0.4) + '@codemirror/language': 6.9.0 + '@codemirror/lint': 6.4.0 + '@codemirror/state': 6.2.1 + '@codemirror/view': 6.16.0 + '@lezer/common': 1.0.4 + '@lezer/javascript': 1.4.5 + dev: true + + /@codemirror/lang-json@6.0.1: + resolution: {integrity: sha512-+T1flHdgpqDDlJZ2Lkil/rLiRy684WMLc74xUnjJH48GQdfJo/pudlTRreZmKwzP8/tGdKf83wlbAdOCzlJOGQ==} + dependencies: + '@codemirror/language': 6.9.0 + '@lezer/json': 1.0.1 + dev: true + + /@codemirror/lang-less@6.0.1(@codemirror/view@6.16.0): + resolution: {integrity: sha512-ABcsKBjLbyPZwPR5gePpc8jEKCQrFF4pby2WlMVdmJOOr7OWwwyz8DZonPx/cKDE00hfoSLc8F7yAcn/d6+rTQ==} + dependencies: + '@codemirror/lang-css': 6.2.1(@codemirror/view@6.16.0) + '@codemirror/language': 6.9.0 + '@lezer/highlight': 1.1.6 + '@lezer/lr': 1.3.10 + transitivePeerDependencies: + - '@codemirror/view' + dev: true + + /@codemirror/lang-lezer@6.0.1: + resolution: {integrity: sha512-WHwjI7OqKFBEfkunohweqA5B/jIlxaZso6Nl3weVckz8EafYbPZldQEKSDb4QQ9H9BUkle4PVELP4sftKoA0uQ==} + dependencies: + '@codemirror/language': 6.9.0 + '@codemirror/state': 6.2.1 + '@lezer/common': 1.0.4 + '@lezer/lezer': 1.1.2 + dev: true + + /@codemirror/lang-markdown@6.2.0: + resolution: {integrity: sha512-deKegEQVzfBAcLPqsJEa+IxotqPVwWZi90UOEvQbfa01NTAw8jNinrykuYPTULGUj+gha0ZG2HBsn4s5d64Qrg==} + dependencies: + '@codemirror/autocomplete': 6.9.0(@codemirror/language@6.9.0)(@codemirror/state@6.2.1)(@codemirror/view@6.16.0)(@lezer/common@1.0.4) + '@codemirror/lang-html': 6.4.5 + '@codemirror/language': 6.9.0 + '@codemirror/state': 6.2.1 + '@codemirror/view': 6.16.0 + '@lezer/common': 1.0.4 + '@lezer/markdown': 1.1.0 + dev: true + + /@codemirror/lang-php@6.0.1: + resolution: {integrity: sha512-ublojMdw/PNWa7qdN5TMsjmqkNuTBD3k6ndZ4Z0S25SBAiweFGyY68AS3xNcIOlb6DDFDvKlinLQ40vSLqf8xA==} + dependencies: + '@codemirror/lang-html': 6.4.5 + '@codemirror/language': 6.9.0 + '@codemirror/state': 6.2.1 + '@lezer/common': 1.0.4 + '@lezer/php': 1.0.1 + dev: true + + /@codemirror/lang-python@6.1.3(@codemirror/state@6.2.1)(@codemirror/view@6.16.0)(@lezer/common@1.0.4): + resolution: {integrity: sha512-S9w2Jl74hFlD5nqtUMIaXAq9t5WlM0acCkyuQWUUSvZclk1sV+UfnpFiZzuZSG+hfEaOmxKR5UxY/Uxswn7EhQ==} + dependencies: + '@codemirror/autocomplete': 6.9.0(@codemirror/language@6.9.0)(@codemirror/state@6.2.1)(@codemirror/view@6.16.0)(@lezer/common@1.0.4) + '@codemirror/language': 6.9.0 + '@lezer/python': 1.1.8 + transitivePeerDependencies: + - '@codemirror/state' + - '@codemirror/view' + - '@lezer/common' + dev: true + + /@codemirror/lang-rust@6.0.1: + resolution: {integrity: sha512-344EMWFBzWArHWdZn/NcgkwMvZIWUR1GEBdwG8FEp++6o6vT6KL9V7vGs2ONsKxxFUPXKI0SPcWhyYyl2zPYxQ==} + dependencies: + '@codemirror/language': 6.9.0 + '@lezer/rust': 1.0.1 + dev: true + + /@codemirror/lang-sass@6.0.2(@codemirror/view@6.16.0): + resolution: {integrity: sha512-l/bdzIABvnTo1nzdY6U+kPAC51czYQcOErfzQ9zSm9D8GmNPD0WTW8st/CJwBTPLO8jlrbyvlSEcN20dc4iL0Q==} + dependencies: + '@codemirror/lang-css': 6.2.1(@codemirror/view@6.16.0) + '@codemirror/language': 6.9.0 + '@codemirror/state': 6.2.1 + '@lezer/common': 1.0.4 + '@lezer/sass': 1.0.3 + transitivePeerDependencies: + - '@codemirror/view' + dev: true + + /@codemirror/lang-sql@6.5.4(@codemirror/view@6.16.0)(@lezer/common@1.0.4): + resolution: {integrity: sha512-5Gq7fYtT/5HbNyIG7a8vYaqOYQU3JbgtBe3+derkrFUXRVcjkf8WVgz++PIbMFAQsOFMDdDR+uiNM8ZRRuXH+w==} + dependencies: + '@codemirror/autocomplete': 6.9.0(@codemirror/language@6.9.0)(@codemirror/state@6.2.1)(@codemirror/view@6.16.0)(@lezer/common@1.0.4) + '@codemirror/language': 6.9.0 + '@codemirror/state': 6.2.1 + '@lezer/highlight': 1.1.6 + '@lezer/lr': 1.3.10 + transitivePeerDependencies: + - '@codemirror/view' + - '@lezer/common' + dev: true + + /@codemirror/lang-vue@0.1.2: + resolution: {integrity: sha512-D4YrefiRBAr+CfEIM4S3yvGSbYW+N69mttIfGMEf7diHpRbmygDxS+R/5xSqjgtkY6VO6qmUrre1GkRcWeZa9A==} + dependencies: + '@codemirror/lang-html': 6.4.5 + '@codemirror/lang-javascript': 6.1.9 + '@codemirror/language': 6.9.0 + '@lezer/common': 1.0.4 + '@lezer/highlight': 1.1.6 + '@lezer/lr': 1.3.10 + dev: true + + /@codemirror/lang-wast@6.0.1: + resolution: {integrity: sha512-sQLsqhRjl2MWG3rxZysX+2XAyed48KhLBHLgq9xcKxIJu3npH/G+BIXW5NM5mHeDUjG0jcGh9BcjP0NfMStuzA==} + dependencies: + '@codemirror/language': 6.9.0 + '@lezer/highlight': 1.1.6 + '@lezer/lr': 1.3.10 + dev: true + + /@codemirror/lang-xml@6.0.2(@codemirror/view@6.16.0): + resolution: {integrity: sha512-JQYZjHL2LAfpiZI2/qZ/qzDuSqmGKMwyApYmEUUCTxLM4MWS7sATUEfIguZQr9Zjx/7gcdnewb039smF6nC2zw==} + dependencies: + '@codemirror/autocomplete': 6.9.0(@codemirror/language@6.9.0)(@codemirror/state@6.2.1)(@codemirror/view@6.16.0)(@lezer/common@1.0.4) + '@codemirror/language': 6.9.0 + '@codemirror/state': 6.2.1 + '@lezer/common': 1.0.4 + '@lezer/xml': 1.0.2 + transitivePeerDependencies: + - '@codemirror/view' + dev: true + + /@codemirror/language-data@6.3.1(@codemirror/state@6.2.1)(@codemirror/view@6.16.0)(@lezer/common@1.0.4): + resolution: {integrity: sha512-p6jhJmvhGe1TG1EGNhwH7nFWWFSTJ8NDKnB2fVx5g3t+PpO0+63R7GJNxjS0TmmH3cdMxZbzejsik+rlEh1EyQ==} + dependencies: + '@codemirror/lang-angular': 0.1.2 + '@codemirror/lang-cpp': 6.0.2 + '@codemirror/lang-css': 6.2.1(@codemirror/view@6.16.0) + '@codemirror/lang-html': 6.4.5 + '@codemirror/lang-java': 6.0.1 + '@codemirror/lang-javascript': 6.1.9 + '@codemirror/lang-json': 6.0.1 + '@codemirror/lang-less': 6.0.1(@codemirror/view@6.16.0) + '@codemirror/lang-markdown': 6.2.0 + '@codemirror/lang-php': 6.0.1 + '@codemirror/lang-python': 6.1.3(@codemirror/state@6.2.1)(@codemirror/view@6.16.0)(@lezer/common@1.0.4) + '@codemirror/lang-rust': 6.0.1 + '@codemirror/lang-sass': 6.0.2(@codemirror/view@6.16.0) + '@codemirror/lang-sql': 6.5.4(@codemirror/view@6.16.0)(@lezer/common@1.0.4) + '@codemirror/lang-vue': 0.1.2 + '@codemirror/lang-wast': 6.0.1 + '@codemirror/lang-xml': 6.0.2(@codemirror/view@6.16.0) + '@codemirror/language': 6.9.0 + '@codemirror/legacy-modes': 6.3.3 + transitivePeerDependencies: + - '@codemirror/state' + - '@codemirror/view' + - '@lezer/common' + dev: true + + /@codemirror/language@6.9.0: + resolution: {integrity: sha512-nFu311/0ne/qGuGCL3oKuktBgzVOaxCHZPZv1tLSZkNjPYxxvkjSbzno3MlErG2tgw1Yw1yF8BxMCegeMXqpiw==} + dependencies: + '@codemirror/state': 6.2.1 + '@codemirror/view': 6.16.0 + '@lezer/common': 1.0.4 + '@lezer/highlight': 1.1.6 + '@lezer/lr': 1.3.10 + style-mod: 4.0.3 + dev: true + + /@codemirror/legacy-modes@6.3.3: + resolution: {integrity: sha512-X0Z48odJ0KIoh/HY8Ltz75/4tDYc9msQf1E/2trlxFaFFhgjpVHjZ/BCXe1Lk7s4Gd67LL/CeEEHNI+xHOiESg==} + dependencies: + '@codemirror/language': 6.9.0 + dev: true + + /@codemirror/lint@6.4.0: + resolution: {integrity: sha512-6VZ44Ysh/Zn07xrGkdtNfmHCbGSHZzFBdzWi0pbd7chAQ/iUcpLGX99NYRZTa7Ugqg4kEHCqiHhcZnH0gLIgSg==} + dependencies: + '@codemirror/state': 6.2.1 + '@codemirror/view': 6.16.0 + crelt: 1.0.6 + dev: true + + /@codemirror/search@6.5.1: + resolution: {integrity: sha512-4jupk4JwkeVbrN2pStY74q6OJEYqwosB4koA66nyLeVedadtX9MHI38j2vbYmnfDGurDApP3OZO46MrWalcjiQ==} + dependencies: + '@codemirror/state': 6.2.1 + '@codemirror/view': 6.16.0 + crelt: 1.0.6 + dev: true + + /@codemirror/state@6.2.1: + resolution: {integrity: sha512-RupHSZ8+OjNT38zU9fKH2sv+Dnlr8Eb8sl4NOnnqz95mCFTZUaiRP8Xv5MeeaG0px2b8Bnfe7YGwCV3nsBhbuw==} + dev: true + + /@codemirror/theme-one-dark@6.1.2: + resolution: {integrity: sha512-F+sH0X16j/qFLMAfbciKTxVOwkdAS336b7AXTKOZhy8BR3eH/RelsnLgLFINrpST63mmN2OuwUt0W2ndUgYwUA==} + dependencies: + '@codemirror/language': 6.9.0 + '@codemirror/state': 6.2.1 + '@codemirror/view': 6.16.0 + '@lezer/highlight': 1.1.6 + dev: true + + /@codemirror/view@6.16.0: + resolution: {integrity: sha512-1Z2HkvkC3KR/oEZVuW9Ivmp8TWLzGEd8T8TA04TTwPvqogfkHBdYSlflytDOqmkUxM2d1ywTg7X2dU5mC+SXvg==} + dependencies: + '@codemirror/state': 6.2.1 + style-mod: 4.0.3 + w3c-keyname: 2.2.8 + dev: true + /@colors/colors@1.5.0: resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} engines: {node: '>=0.1.90'} @@ -3562,6 +3857,114 @@ packages: resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==} dev: true + /@lezer/common@1.0.4: + resolution: {integrity: sha512-lZHlk8p67x4aIDtJl6UQrXSOP6oi7dQR3W/geFVrENdA1JDaAJWldnVqVjPMJupbTKbzDfFcePfKttqVidS/dg==} + dev: true + + /@lezer/cpp@1.1.1: + resolution: {integrity: sha512-eS1M3L3U2mDowoFVPG7tEp01SWu9/68Nx3HEBgLJVn3N9ku7g5S7WdFv0jzmcTipAyONYfZJ+7x4WRkfdB2Ung==} + dependencies: + '@lezer/highlight': 1.1.6 + '@lezer/lr': 1.3.10 + dev: true + + /@lezer/css@1.1.3: + resolution: {integrity: sha512-SjSM4pkQnQdJDVc80LYzEaMiNy9txsFbI7HsMgeVF28NdLaAdHNtQ+kB/QqDUzRBV/75NTXjJ/R5IdC8QQGxMg==} + dependencies: + '@lezer/highlight': 1.1.6 + '@lezer/lr': 1.3.10 + dev: true + + /@lezer/highlight@1.1.6: + resolution: {integrity: sha512-cmSJYa2us+r3SePpRCjN5ymCqCPv+zyXmDl0ciWtVaNiORT/MxM7ZgOMQZADD0o51qOaOg24qc/zBViOIwAjJg==} + dependencies: + '@lezer/common': 1.0.4 + dev: true + + /@lezer/html@1.3.6: + resolution: {integrity: sha512-Kk9HJARZTc0bAnMQUqbtuhFVsB4AnteR2BFUWfZV7L/x1H0aAKz6YabrfJ2gk/BEgjh9L3hg5O4y2IDZRBdzuQ==} + dependencies: + '@lezer/common': 1.0.4 + '@lezer/highlight': 1.1.6 + '@lezer/lr': 1.3.10 + dev: true + + /@lezer/java@1.0.4: + resolution: {integrity: sha512-POc53LHf2AuNeRXjqZbXNu88GKj0KZTjjSx0L7tYeXlrEHF+3NAQx+dEwKVuCbkl0ZMtpRy2VsDYOV7KKV0oyg==} + dependencies: + '@lezer/highlight': 1.1.6 + '@lezer/lr': 1.3.10 + dev: true + + /@lezer/javascript@1.4.5: + resolution: {integrity: sha512-FmBUHz8K1V22DgjTd6SrIG9owbzOYZ1t3rY6vGEmw+e2RVBd7sqjM8uXEVRFmfxKFn1Mx2ABJehHjrN3G2ZpmA==} + dependencies: + '@lezer/highlight': 1.1.6 + '@lezer/lr': 1.3.10 + dev: true + + /@lezer/json@1.0.1: + resolution: {integrity: sha512-nkVC27qiEZEjySbi6gQRuMwa2sDu2PtfjSgz0A4QF81QyRGm3kb2YRzLcOPcTEtmcwvrX/cej7mlhbwViA4WJw==} + dependencies: + '@lezer/highlight': 1.1.6 + '@lezer/lr': 1.3.10 + dev: true + + /@lezer/lezer@1.1.2: + resolution: {integrity: sha512-O8yw3CxPhzYHB1hvwbdozjnAslhhR8A5BH7vfEMof0xk3p+/DFDfZkA9Tde6J+88WgtwaHy4Sy6ThZSkaI0Evw==} + dependencies: + '@lezer/highlight': 1.1.6 + '@lezer/lr': 1.3.10 + dev: true + + /@lezer/lr@1.3.10: + resolution: {integrity: sha512-BZfVvf7Re5BIwJHlZXbJn9L8lus5EonxQghyn+ih8Wl36XMFBPTXC0KM0IdUtj9w/diPHsKlXVgL+AlX2jYJ0Q==} + dependencies: + '@lezer/common': 1.0.4 + dev: true + + /@lezer/markdown@1.1.0: + resolution: {integrity: sha512-JYOI6Lkqbl83semCANkO3CKbKc0pONwinyagBufWBm+k4yhIcqfCF8B8fpEpvJLmIy7CAfwiq7dQ/PzUZA340g==} + dependencies: + '@lezer/common': 1.0.4 + '@lezer/highlight': 1.1.6 + dev: true + + /@lezer/php@1.0.1: + resolution: {integrity: sha512-aqdCQJOXJ66De22vzdwnuC502hIaG9EnPK2rSi+ebXyUd+j7GAX1mRjWZOVOmf3GST1YUfUCu6WXDiEgDGOVwA==} + dependencies: + '@lezer/highlight': 1.1.6 + '@lezer/lr': 1.3.10 + dev: true + + /@lezer/python@1.1.8: + resolution: {integrity: sha512-1T/XsmeF57ijrjpC0Zmrf9YeO5mn2zC1XeSNrOnc0KB+6PgxJ5m7kWKt0CnwyS74oHQXbJxUUL+QDQJR26c1Gw==} + dependencies: + '@lezer/highlight': 1.1.6 + '@lezer/lr': 1.3.10 + dev: true + + /@lezer/rust@1.0.1: + resolution: {integrity: sha512-j+ToFKM6Wpglv3OQ4ebHYdYIMT2dh0ziCCV0rTf47AWiHOVhR0WjaKrBq+yuvDQNEhr5sxPxVI7+naJIgpqcsQ==} + dependencies: + '@lezer/highlight': 1.1.6 + '@lezer/lr': 1.3.10 + dev: true + + /@lezer/sass@1.0.3: + resolution: {integrity: sha512-n4l2nVOB7gWiGU/Cg2IVxpt2Ic9Hgfgy/7gk+p/XJibAsPXs0lSbsfGwQgwsAw9B/euYo3oS6lEFr9WytoqcZg==} + dependencies: + '@lezer/highlight': 1.1.6 + '@lezer/lr': 1.3.10 + dev: true + + /@lezer/xml@1.0.2: + resolution: {integrity: sha512-dlngsWceOtQBMuBPw5wtHpaxdPJ71aVntqjbpGkFtWsp4WtQmCnuTjQGocviymydN6M18fhj6UQX3oiEtSuY7w==} + dependencies: + '@lezer/highlight': 1.1.6 + '@lezer/lr': 1.3.10 + dev: true + /@loadable/component@5.15.2(react@18.1.0): resolution: {integrity: sha512-ryFAZOX5P2vFkUdzaAtTG88IGnr9qxSdvLRvJySXcUA4B4xVWurUNADu3AnKPksxOZajljqTrDEDcYjeL4lvLw==} engines: {node: '>=8'} @@ -3644,6 +4047,19 @@ packages: state-local: 1.0.7 dev: true + /@nextjournal/lang-clojure@1.0.0: + resolution: {integrity: sha512-gOCV71XrYD0DhwGoPMWZmZ0r92/lIHsqQu9QWdpZYYBwiChNwMO4sbVMP7eTuAqffFB2BTtCSC+1skSH9d3bNg==} + dependencies: + '@codemirror/language': 6.9.0 + '@nextjournal/lezer-clojure': 1.0.0 + dev: true + + /@nextjournal/lezer-clojure@1.0.0: + resolution: {integrity: sha512-VZyuGu4zw5mkTOwQBTaGVNWmsOZAPw5ZRxu1/Knk/Xfs7EDBIogwIs5UXTYkuECX5ZQB8eOB+wKA2pc7VyqaZQ==} + dependencies: + '@lezer/lr': 1.3.10 + dev: true + /@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents.3: resolution: {integrity: sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==} requiresBuild: true @@ -3878,6 +4294,82 @@ packages: react: 18.2.0 dev: true + /@replit/codemirror-lang-csharp@6.1.0(@codemirror/autocomplete@6.9.0)(@codemirror/language@6.9.0)(@codemirror/state@6.2.1)(@codemirror/view@6.16.0)(@lezer/common@1.0.4)(@lezer/highlight@1.1.6)(@lezer/lr@1.3.10): + resolution: {integrity: sha512-Dtyk9WVrdPPgkgTp8MUX9HyXd87O7UZnFrE647gjHUZY8p0UN+z0m6dPfk6rJMsTTvMcl7YbDUykxfeqB6EQOQ==} + peerDependencies: + '@codemirror/autocomplete': ^6.0.0 + '@codemirror/language': ^6.0.0 + '@codemirror/state': ^6.0.0 + '@codemirror/view': ^6.0.0 + '@lezer/common': ^1.0.0 + '@lezer/highlight': ^1.0.0 + '@lezer/lr': ^1.0.0 + dependencies: + '@codemirror/autocomplete': 6.9.0(@codemirror/language@6.9.0)(@codemirror/state@6.2.1)(@codemirror/view@6.16.0)(@lezer/common@1.0.4) + '@codemirror/language': 6.9.0 + '@codemirror/state': 6.2.1 + '@codemirror/view': 6.16.0 + '@lezer/common': 1.0.4 + '@lezer/highlight': 1.1.6 + '@lezer/lr': 1.3.10 + dev: true + + /@replit/codemirror-lang-nix@6.0.1(@codemirror/autocomplete@6.9.0)(@codemirror/language@6.9.0)(@codemirror/state@6.2.1)(@codemirror/view@6.16.0)(@lezer/common@1.0.4)(@lezer/highlight@1.1.6)(@lezer/lr@1.3.10): + resolution: {integrity: sha512-lvzjoYn9nfJzBD5qdm3Ut6G3+Or2wEacYIDJ49h9+19WSChVnxv4ojf+rNmQ78ncuxIt/bfbMvDLMeMP0xze6g==} + peerDependencies: + '@codemirror/autocomplete': ^6.0.0 + '@codemirror/language': ^6.0.0 + '@codemirror/state': ^6.0.0 + '@codemirror/view': ^6.0.0 + '@lezer/common': ^1.0.0 + '@lezer/highlight': ^1.0.0 + '@lezer/lr': ^1.0.0 + dependencies: + '@codemirror/autocomplete': 6.9.0(@codemirror/language@6.9.0)(@codemirror/state@6.2.1)(@codemirror/view@6.16.0)(@lezer/common@1.0.4) + '@codemirror/language': 6.9.0 + '@codemirror/state': 6.2.1 + '@codemirror/view': 6.16.0 + '@lezer/common': 1.0.4 + '@lezer/highlight': 1.1.6 + '@lezer/lr': 1.3.10 + dev: true + + /@replit/codemirror-lang-solidity@6.0.1(@codemirror/language@6.9.0): + resolution: {integrity: sha512-kDnak0xZelGmvzJwKTpMTl6gYSfFq9hnxrkbLaMV0CARq/MFvDQJmcmYon/k8uZqXy6DfzewKDV8tx9kY2WUZg==} + peerDependencies: + '@codemirror/language': ^6.0.0 + dependencies: + '@codemirror/language': 6.9.0 + dev: true + + /@replit/codemirror-lang-svelte@6.0.0(@codemirror/autocomplete@6.9.0)(@codemirror/lang-css@6.2.1)(@codemirror/lang-html@6.4.5)(@codemirror/lang-javascript@6.1.9)(@codemirror/language@6.9.0)(@codemirror/state@6.2.1)(@codemirror/view@6.16.0)(@lezer/common@1.0.4)(@lezer/highlight@1.1.6)(@lezer/javascript@1.4.5)(@lezer/lr@1.3.10): + resolution: {integrity: sha512-U2OqqgMM6jKelL0GNWbAmqlu1S078zZNoBqlJBW+retTc5M4Mha6/Y2cf4SVg6ddgloJvmcSpt4hHrVoM4ePRA==} + peerDependencies: + '@codemirror/autocomplete': ^6.0.0 + '@codemirror/lang-css': ^6.0.1 + '@codemirror/lang-html': ^6.2.0 + '@codemirror/lang-javascript': ^6.1.1 + '@codemirror/language': ^6.0.0 + '@codemirror/state': ^6.0.0 + '@codemirror/view': ^6.0.0 + '@lezer/common': ^1.0.0 + '@lezer/highlight': ^1.0.0 + '@lezer/javascript': ^1.2.0 + '@lezer/lr': ^1.0.0 + dependencies: + '@codemirror/autocomplete': 6.9.0(@codemirror/language@6.9.0)(@codemirror/state@6.2.1)(@codemirror/view@6.16.0)(@lezer/common@1.0.4) + '@codemirror/lang-css': 6.2.1(@codemirror/view@6.16.0) + '@codemirror/lang-html': 6.4.5 + '@codemirror/lang-javascript': 6.1.9 + '@codemirror/language': 6.9.0 + '@codemirror/state': 6.2.1 + '@codemirror/view': 6.16.0 + '@lezer/common': 1.0.4 + '@lezer/highlight': 1.1.6 + '@lezer/javascript': 1.4.5 + '@lezer/lr': 1.3.10 + dev: true + /@sentry-internal/tracing@7.54.0: resolution: {integrity: sha512-JsyhZ0wWZ+VqbHJg+azqRGdYJDkcI5R9+pnkO6SzbzxrRewqMAIwzkpPee3oI7vG99uhMEkOkMjHu0nQGwkOQw==} engines: {node: '>=8'} @@ -4828,6 +5320,101 @@ packages: eslint-visitor-keys: 3.4.1 dev: true + /@uiw/codemirror-extensions-basic-setup@4.21.9(@codemirror/autocomplete@6.9.0)(@codemirror/commands@6.2.4)(@codemirror/language@6.9.0)(@codemirror/lint@6.4.0)(@codemirror/search@6.5.1)(@codemirror/state@6.2.1)(@codemirror/view@6.16.0): + resolution: {integrity: sha512-TQT6aF8brxZpFnk/K4fm/K/9k9eF3PMav/KKjHlYrGUT8BTNk/qL+ximLtIzvTUhmBFchjM1lrqSJdvpVom7/w==} + peerDependencies: + '@codemirror/autocomplete': '>=6.0.0' + '@codemirror/commands': '>=6.0.0' + '@codemirror/language': '>=6.0.0' + '@codemirror/lint': '>=6.0.0' + '@codemirror/search': '>=6.0.0' + '@codemirror/state': '>=6.0.0' + '@codemirror/view': '>=6.0.0' + dependencies: + '@codemirror/autocomplete': 6.9.0(@codemirror/language@6.9.0)(@codemirror/state@6.2.1)(@codemirror/view@6.16.0)(@lezer/common@1.0.4) + '@codemirror/commands': 6.2.4 + '@codemirror/language': 6.9.0 + '@codemirror/lint': 6.4.0 + '@codemirror/search': 6.5.1 + '@codemirror/state': 6.2.1 + '@codemirror/view': 6.16.0 + dev: true + + /@uiw/codemirror-extensions-langs@4.21.9(@codemirror/autocomplete@6.9.0)(@codemirror/language-data@6.3.1)(@codemirror/language@6.9.0)(@codemirror/legacy-modes@6.3.3)(@codemirror/state@6.2.1)(@codemirror/view@6.16.0)(@lezer/common@1.0.4)(@lezer/highlight@1.1.6)(@lezer/javascript@1.4.5)(@lezer/lr@1.3.10): + resolution: {integrity: sha512-s1VT1rss0iyvrtRl7BZtC5H7U5uQtCKTaD8wxjQrgZz5un9wHVvy9twU97aJGQR0FwbKWqK8/1iiICRJTRCoZA==} + peerDependencies: + '@codemirror/language-data': '>=6.0.0' + '@codemirror/legacy-modes': '>=6.0.0' + dependencies: + '@codemirror/lang-angular': 0.1.2 + '@codemirror/lang-cpp': 6.0.2 + '@codemirror/lang-css': 6.2.1(@codemirror/view@6.16.0) + '@codemirror/lang-html': 6.4.5 + '@codemirror/lang-java': 6.0.1 + '@codemirror/lang-javascript': 6.1.9 + '@codemirror/lang-json': 6.0.1 + '@codemirror/lang-less': 6.0.1(@codemirror/view@6.16.0) + '@codemirror/lang-lezer': 6.0.1 + '@codemirror/lang-markdown': 6.2.0 + '@codemirror/lang-php': 6.0.1 + '@codemirror/lang-python': 6.1.3(@codemirror/state@6.2.1)(@codemirror/view@6.16.0)(@lezer/common@1.0.4) + '@codemirror/lang-rust': 6.0.1 + '@codemirror/lang-sass': 6.0.2(@codemirror/view@6.16.0) + '@codemirror/lang-sql': 6.5.4(@codemirror/view@6.16.0)(@lezer/common@1.0.4) + '@codemirror/lang-vue': 0.1.2 + '@codemirror/lang-wast': 6.0.1 + '@codemirror/lang-xml': 6.0.2(@codemirror/view@6.16.0) + '@codemirror/language-data': 6.3.1(@codemirror/state@6.2.1)(@codemirror/view@6.16.0)(@lezer/common@1.0.4) + '@codemirror/legacy-modes': 6.3.3 + '@nextjournal/lang-clojure': 1.0.0 + '@replit/codemirror-lang-csharp': 6.1.0(@codemirror/autocomplete@6.9.0)(@codemirror/language@6.9.0)(@codemirror/state@6.2.1)(@codemirror/view@6.16.0)(@lezer/common@1.0.4)(@lezer/highlight@1.1.6)(@lezer/lr@1.3.10) + '@replit/codemirror-lang-nix': 6.0.1(@codemirror/autocomplete@6.9.0)(@codemirror/language@6.9.0)(@codemirror/state@6.2.1)(@codemirror/view@6.16.0)(@lezer/common@1.0.4)(@lezer/highlight@1.1.6)(@lezer/lr@1.3.10) + '@replit/codemirror-lang-solidity': 6.0.1(@codemirror/language@6.9.0) + '@replit/codemirror-lang-svelte': 6.0.0(@codemirror/autocomplete@6.9.0)(@codemirror/lang-css@6.2.1)(@codemirror/lang-html@6.4.5)(@codemirror/lang-javascript@6.1.9)(@codemirror/language@6.9.0)(@codemirror/state@6.2.1)(@codemirror/view@6.16.0)(@lezer/common@1.0.4)(@lezer/highlight@1.1.6)(@lezer/javascript@1.4.5)(@lezer/lr@1.3.10) + codemirror-lang-mermaid: 0.2.2 + transitivePeerDependencies: + - '@codemirror/autocomplete' + - '@codemirror/language' + - '@codemirror/state' + - '@codemirror/view' + - '@lezer/common' + - '@lezer/highlight' + - '@lezer/javascript' + - '@lezer/lr' + dev: true + + /@uiw/react-codemirror@4.21.9(@babel/runtime@7.22.3)(@codemirror/autocomplete@6.9.0)(@codemirror/language@6.9.0)(@codemirror/lint@6.4.0)(@codemirror/search@6.5.1)(@codemirror/state@6.2.1)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.16.0)(codemirror@6.0.1)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-aeLegPz2iCvqJjhzXp2WUMqpMZDqxsTnF3rX9kGRlfY6vQLsrjoctj0cQ29uxEtFYJChOVjtCOtnQUlyIuNAHQ==} + peerDependencies: + '@babel/runtime': '>=7.11.0' + '@codemirror/state': '>=6.0.0' + '@codemirror/theme-one-dark': '>=6.0.0' + '@codemirror/view': '>=6.0.0' + codemirror: '>=6.0.0' + react: '>=16.8.0 || 18' + react-dom: '>=16.8.0 || 18' + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + dependencies: + '@babel/runtime': 7.22.3 + '@codemirror/commands': 6.2.4 + '@codemirror/state': 6.2.1 + '@codemirror/theme-one-dark': 6.1.2 + '@codemirror/view': 6.16.0 + '@uiw/codemirror-extensions-basic-setup': 4.21.9(@codemirror/autocomplete@6.9.0)(@codemirror/commands@6.2.4)(@codemirror/language@6.9.0)(@codemirror/lint@6.4.0)(@codemirror/search@6.5.1)(@codemirror/state@6.2.1)(@codemirror/view@6.16.0) + codemirror: 6.0.1(@lezer/common@1.0.4) + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + transitivePeerDependencies: + - '@codemirror/autocomplete' + - '@codemirror/language' + - '@codemirror/lint' + - '@codemirror/search' + dev: true + /@umijs/ast@4.0.72: resolution: {integrity: sha512-WatRvU09vsx4Hlu5hemPA7a+QK4pJvzmQz/9LxN/KVgn+wZXi717qHFLu5eoV6XO7HlFZaEBGq2aHpDj0ngA8w==} dependencies: @@ -6657,8 +7244,26 @@ packages: mimic-response: 1.0.1 dev: false - /codemirror@5.65.13: - resolution: {integrity: sha512-SVWEzKXmbHmTQQWaz03Shrh4nybG0wXx2MEu3FO4ezbPW8IbnZEd5iGHGEffSUaitKYa3i+pHpBsSvw8sPHtzg==} + /codemirror-lang-mermaid@0.2.2: + resolution: {integrity: sha512-AqSzkQgfWsjBbifio3dy/zDj6WXEw4g52Mq6bltIWLMWryWWRMpFwjQSlHtCGOol1FENYObUF5KI4ofiv8bjXA==} + dependencies: + '@codemirror/language': 6.9.0 + '@lezer/highlight': 1.1.6 + '@lezer/lr': 1.3.10 + dev: true + + /codemirror@6.0.1(@lezer/common@1.0.4): + resolution: {integrity: sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==} + dependencies: + '@codemirror/autocomplete': 6.9.0(@codemirror/language@6.9.0)(@codemirror/state@6.2.1)(@codemirror/view@6.16.0)(@lezer/common@1.0.4) + '@codemirror/commands': 6.2.4 + '@codemirror/language': 6.9.0 + '@codemirror/lint': 6.4.0 + '@codemirror/search': 6.5.1 + '@codemirror/state': 6.2.1 + '@codemirror/view': 6.16.0 + transitivePeerDependencies: + - '@lezer/common' dev: true /color-convert@1.9.3: @@ -6970,6 +7575,10 @@ packages: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} dev: true + /crelt@1.0.6: + resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==} + dev: true + /cron-parser@4.8.1: resolution: {integrity: sha512-jbokKWGcyU4gl6jAfX97E1gDpY12DJ1cLJZmoDzaAln/shZ+S3KBFBuA2Q6WeUN4gJf/8klnV1EfvhA2lK5IRQ==} engines: {node: '>=12.0.0'} @@ -8273,6 +8882,12 @@ packages: resolution: {integrity: sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==} dev: true + /file-stream-rotator@0.6.1: + resolution: {integrity: sha512-u+dBid4PvZw17PmDeRcNOtCP9CCK/9lRN2w+r1xIS7yOL9JFrIBKTvrYsxT4P0pGtThYTn++QS5ChHaUov3+zQ==} + dependencies: + moment: 2.29.4 + dev: false + /file-uri-to-path@2.0.0: resolution: {integrity: sha512-hjPFI8oE/2iQPVe4gbrJ73Pp+Xfub2+WI2LlXDbsaJBwT5wuMh35WNWVYYTpnz895shtwfyutMFLFywpQAFdLg==} engines: {node: '>= 6'} @@ -10787,6 +11402,11 @@ packages: engines: {node: '>= 0.10.0'} dev: true + /object-hash@2.2.0: + resolution: {integrity: sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==} + engines: {node: '>= 6'} + dev: false + /object-inspect@1.12.3: resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} @@ -12903,19 +13523,6 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: true - /react-codemirror2@7.2.1(codemirror@5.65.13)(react@18.2.0): - resolution: {integrity: sha512-t7YFmz1AXdlImgHXA9Ja0T6AWuopilub24jRaQdPVbzUJVNKIYuy3uCFZYa7CE5S3UW6SrSa5nAqVQvtzRF9gw==} - peerDependencies: - codemirror: 5.x - react: '>=15.5 <=16.x || 18' - peerDependenciesMeta: - react: - optional: true - dependencies: - codemirror: 5.65.13 - react: 18.2.0 - dev: true - /react-copy-to-clipboard@5.1.0(react@18.2.0): resolution: {integrity: sha512-k61RsNgAayIJNoy9yDsYzDe/yAZAzEbEgcz3DZMhF686LEyukcE1hzurxe85JandPUG+yTfGVFzuEw3xt8WP/A==} peerDependencies: @@ -14307,6 +14914,10 @@ packages: engines: {node: '>=8'} dev: true + /style-mod@4.0.3: + resolution: {integrity: sha512-78Jv8kYJdjbvRwwijtCevYADfsI0lGzYJe4mMFdceO8l75DFFDoqBhR1jVDicDRRaX4//g1u9wKeo+ztc2h1Rw==} + dev: true + /style-search@0.1.0: resolution: {integrity: sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==} dev: true @@ -15308,6 +15919,10 @@ packages: acorn-walk: 8.2.0 dev: true + /w3c-keyname@2.2.8: + resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} + dev: true + /walker@1.0.8: resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} dependencies: @@ -15489,6 +16104,19 @@ packages: semver: 5.7.1 dev: true + /winston-daily-rotate-file@4.7.1(winston@3.9.0): + resolution: {integrity: sha512-7LGPiYGBPNyGHLn9z33i96zx/bd71pjBn9tqQzO3I4Tayv94WPmBNwKC7CO1wPHdP9uvu+Md/1nr6VSH9h0iaA==} + engines: {node: '>=8'} + peerDependencies: + winston: ^3 + dependencies: + file-stream-rotator: 0.6.1 + object-hash: 2.2.0 + triple-beam: 1.3.0 + winston: 3.9.0 + winston-transport: 4.5.0 + dev: false + /winston-transport@4.5.0: resolution: {integrity: sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==} engines: {node: '>= 6.4.0'} diff --git a/shell/share.sh b/shell/share.sh index 52b4cab6..22e9d9d7 100755 --- a/shell/share.sh +++ b/shell/share.sh @@ -296,7 +296,7 @@ git_clone_scripts() { set_proxy "$proxy" - git clone --depth=1 $part_cmd $url $dir + git clone --depth=1 $part_cmd $url $dir 2>&1 exit_status=$? unset_proxy diff --git a/src/layouts/index.less b/src/layouts/index.less index ca35a932..3bb6050b 100644 --- a/src/layouts/index.less +++ b/src/layouts/index.less @@ -1,6 +1,5 @@ @import '~antd/es/style/themes/default.less'; @import '~@/styles/variable.less'; -@import '~codemirror/lib/codemirror.css'; @font-face { font-family: 'Source Code Pro'; diff --git a/src/layouts/index.tsx b/src/layouts/index.tsx index fa74f436..a307128f 100644 --- a/src/layouts/index.tsx +++ b/src/layouts/index.tsx @@ -32,9 +32,6 @@ import { import SockJS from 'sockjs-client'; import * as Sentry from '@sentry/react'; import { init } from '../utils/init'; -import 'codemirror/mode/javascript/javascript'; -import 'codemirror/mode/python/python'; -import 'codemirror/mode/shell/shell'; export interface SharedContext { headerStyle: React.CSSProperties; diff --git a/src/locales/en-US.json b/src/locales/en-US.json index 3376465e..26a1289f 100644 --- a/src/locales/en-US.json +++ b/src/locales/en-US.json @@ -448,5 +448,7 @@ "编辑订阅": "Edit Subscription", "Subscription表达式格式有误": "Incorrect Subscription Expression Format", "一对多推送的“群组编码”(一对多推送下面->您的群组(如无则新建)->群组编码,如果您是创建群组人。也需点击“查看二维码”扫描绑定,否则不能接受群组消息推送)": "The 'Group Code' for One-to-Many Push (Below One-to-Many Push->Your Group (if not, create one)->Group Code, if you are the creator of the group, you also need to click 'View QR Code' to scan and bind, otherwise you cannot receive group messages)", - "登录已过期,请重新登录": "Login session has expired, please log in again" + "登录已过期,请重新登录": "Login session has expired, please log in again", + "系统日志": "System Logs", + "主题": "Theme" } diff --git a/src/locales/zh-CN.json b/src/locales/zh-CN.json index 47606399..cac7fd91 100644 --- a/src/locales/zh-CN.json +++ b/src/locales/zh-CN.json @@ -448,5 +448,7 @@ "编辑订阅": "编辑订阅", "Subscription表达式格式有误": "Subscription表达式格式有误", "一对多推送的“群组编码”(一对多推送下面->您的群组(如无则新建)->群组编码,如果您是创建群组人。也需点击“查看二维码”扫描绑定,否则不能接受群组消息推送)": "一对多推送的“群组编码”(一对多推送下面->您的群组(如无则新建)->群组编码,如果您是创建群组人。也需点击“查看二维码”扫描绑定,否则不能接受群组消息推送)", - "登录已过期,请重新登录": "登录已过期,请重新登录" + "登录已过期,请重新登录": "登录已过期,请重新登录", + "系统日志": "系统日志", + "主题": "主题" } diff --git a/src/pages/config/index.tsx b/src/pages/config/index.tsx index 97059631..7fafd1ee 100644 --- a/src/pages/config/index.tsx +++ b/src/pages/config/index.tsx @@ -11,9 +11,10 @@ import config from '@/utils/config'; import { PageContainer } from '@ant-design/pro-layout'; import { request } from '@/utils/http'; import Editor from '@monaco-editor/react'; -import { Controlled as CodeMirror } from 'react-codemirror2'; +import CodeMirror from '@uiw/react-codemirror'; import { useOutletContext } from '@umijs/max'; import { SharedContext } from '@/layouts'; +import { langs } from '@uiw/codemirror-extensions-langs'; const Config = () => { const { headerStyle, isPhone, theme } = useOutletContext(); @@ -104,16 +105,11 @@ const Config = () => { {isPhone ? ( { + theme={theme.includes('dark') ? 'dark' : 'light'} + extensions={[langs.shell()]} + onChange={(value) => { setValue(value); }} - onChange={(editor, data, value) => {}} /> ) : ( { {isPhone && ( { + readOnly={true} + theme={theme.includes('dark') ? 'dark' : 'light'} + onChange={(value, viewUpdate) => { setValue(value); }} - onChange={(editor, data, value) => {}} /> )} diff --git a/src/pages/script/index.tsx b/src/pages/script/index.tsx index 5901cb1d..10d6d532 100644 --- a/src/pages/script/index.tsx +++ b/src/pages/script/index.tsx @@ -20,7 +20,7 @@ import Editor from '@monaco-editor/react'; import { request } from '@/utils/http'; import styles from './index.module.less'; import EditModal from './editModal'; -import { Controlled as CodeMirror } from 'react-codemirror2'; +import CodeMirror from '@uiw/react-codemirror'; import SplitPane from 'react-split-pane'; import { DeleteOutlined, @@ -43,6 +43,7 @@ import useFilterTreeData from '@/hooks/useFilterTreeData'; import uniq from 'lodash/uniq'; import IconFont from '@/components/iconfont'; import RenameModal from './renameModal'; +import { langs } from '@uiw/codemirror-extensions-langs'; const { Text } = Typography; @@ -580,18 +581,14 @@ const Script = () => { {isPhone && ( { + extensions={ + mode ? [langs[mode as keyof typeof langs]()] : undefined + } + theme={theme.includes('dark') ? 'dark' : 'light'} + readOnly={!isEditing} + onChange={(value) => { setValue(value); }} - onChange={(editor, data, value) => {}} /> )} { headerStyle, isPhone, user, + theme, reloadUser, reloadTheme, socketMessage, @@ -113,7 +115,9 @@ const Setting = () => { const [editedApp, setEditedApp] = useState(); const [tabActiveKey, setTabActiveKey] = useState('security'); const [loginLogData, setLoginLogData] = useState([]); + const [systemLogData, setSystemLogData] = useState(''); const [notificationInfo, setNotificationInfo] = useState(); + const systemLogRef = useRef(); const getApps = () => { setLoading(true); @@ -232,6 +236,19 @@ const Setting = () => { }); }; + const getSystemLog = () => { + request + .get(`${config.apiPrefix}system/log`, { + responseType: 'blob', + }) + .then(async (res) => { + setSystemLogData(await res.text()); + }) + .catch((error: any) => { + console.log(error); + }); + }; + const tabChange = (activeKey: string) => { setTabActiveKey(activeKey); if (activeKey === 'app') { @@ -240,6 +257,8 @@ const Setting = () => { getLoginLog(); } else if (activeKey === 'notification') { getNotification(); + } else if (activeKey === 'syslog') { + getSystemLog(); } }; @@ -332,6 +351,30 @@ const Setting = () => { /> ), }, + { + key: 'syslog', + label: intl.get('系统日志'), + children: ( + { + setTimeout(() => { + view.scrollDOM.scrollTo({ + top: view.scrollDOM.scrollHeight, + behavior: 'smooth', + }); + }, 300); + }} + readOnly={true} + theme={theme.includes('dark') ? 'dark' : 'light'} + /> + ), + }, { key: 'about', label: intl.get('关于'), diff --git a/src/pages/setting/loginLog.tsx b/src/pages/setting/loginLog.tsx index af5ca238..8484431f 100644 --- a/src/pages/setting/loginLog.tsx +++ b/src/pages/setting/loginLog.tsx @@ -19,7 +19,7 @@ enum LoginStatusColor { const columns = [ { title: intl.get('序号'), - width: 40, + width: 50, render: (text: string, record: any, index: number) => { return index + 1; }, @@ -75,7 +75,7 @@ const LoginLog = ({ data }: any) => { dataSource={data} rowKey="id" size="middle" - scroll={{ x: 768 }} + scroll={{ x: 1000 }} sticky />