diff --git a/packages/code-less/README.md b/packages/code-less/README.md index 2aff98c23..63910bb1c 100644 --- a/packages/code-less/README.md +++ b/packages/code-less/README.md @@ -1 +1,107 @@ -订单系统前端低代码构建组件 \ No newline at end of file +# 低代码开发系统 + +订单系统前端低代码构建组件,提供可视化页面搭建能力。 + +## 功能特性 + +- 📦 **组件库** - 预置多种常用组件(表单、表格、按钮等) +- 🎨 **可视化编辑** - 拖拽式页面设计器 +- 👁️ **实时预览** - 所见即所得的预览体验 +- 💾 **页面管理** - 创建、编辑、复制、发布页面 + +## 技术架构 + +### 后端 +- Express.js 服务框架 +- SQLite 数据库(better-sqlite3) +- RESTful API 设计 + +### 前端 +- Vue 2 + Element UI +- 拖拽组件设计 +- 动态组件渲染 + +## 快速开始 + +### 1. 安装依赖 + +```bash +# 在项目根目录 +yarn install + +# 或单独安装 code-less 依赖 +cd packages/code-less +npm install +``` + +### 2. 启动后端服务 + +```bash +# 在 packages/code-less 目录 +npm start + +# 服务将在 http://localhost:3100 启动 +``` + +### 3. 访问系统 + +在订单系统中,点击右上角用户名 → 低代码开发 + +## API 接口 + +### 页面管理 + +| 方法 | 路径 | 描述 | +|------|------|------| +| GET | /api/codeless/pages | 获取页面列表 | +| GET | /api/codeless/pages/:id | 获取单个页面 | +| POST | /api/codeless/pages | 创建页面 | +| PUT | /api/codeless/pages/:id | 更新页面 | +| DELETE | /api/codeless/pages/:id | 删除页面 | +| POST | /api/codeless/pages/:id/copy | 复制页面 | + +### 组件管理 + +| 方法 | 路径 | 描述 | +|------|------|------| +| GET | /api/codeless/components | 获取组件列表 | +| GET | /api/codeless/components/categories | 获取组件分类 | + +## 目录结构 + +``` +packages/code-less/ +├── server/ # 后端服务 +│ ├── app.js # Express 入口 +│ ├── db.js # 数据库初始化 +│ └── routes/ # API 路由 +│ ├── pages.js # 页面管理 +│ └── components.js # 组件管理 +├── src/ # 前端源码 +│ ├── api/ # API 封装 +│ ├── components/ # 公共组件 +│ └── views/ # 页面视图 +│ ├── index.vue # 首页 +│ ├── editor.vue # 编辑器 +│ └── preview.vue # 预览 +├── data/ # SQLite 数据文件 +├── package.json +└── README.md +``` + +## 预置组件 + +### 基础组件 +- **文本** - 静态文本展示 +- **按钮** - 操作按钮 + +### 表单组件 +- **输入框** - 单行文本输入 +- **多行文本** - 多行文本输入 +- **下拉选择** - 单选/多选下拉 +- **日期选择** - 日期选择器 +- **单选框** - 单选选项 +- **多选框** - 多选选项 + +### 数据组件 +- **表格** - 数据表格展示 diff --git a/packages/code-less/data/codeless.db b/packages/code-less/data/codeless.db new file mode 100644 index 000000000..3f452669a Binary files /dev/null and b/packages/code-less/data/codeless.db differ diff --git a/packages/code-less/package.json b/packages/code-less/package.json new file mode 100644 index 000000000..a20d20050 --- /dev/null +++ b/packages/code-less/package.json @@ -0,0 +1,16 @@ +{ + "name": "@order-system/code-less", + "version": "1.0.0", + "description": "低代码开发系统 - 可视化页面构建工具", + "main": "server/app.js", + "scripts": { + "start": "node server/app.js", + "dev": "node server/app.js" + }, + "dependencies": { + "better-sqlite3": "^9.4.3", + "cors": "^2.8.5", + "express": "^4.21.2", + "uuid": "^9.0.0" + } +} diff --git a/packages/code-less/server/app.js b/packages/code-less/server/app.js new file mode 100644 index 000000000..1e671b6b0 --- /dev/null +++ b/packages/code-less/server/app.js @@ -0,0 +1,48 @@ +/** + * 低代码系统后端服务 + */ +const express = require('express'); +const cors = require('cors'); +const path = require('path'); +const fs = require('fs'); +const { initDatabase } = require('./db'); + +const app = express(); +const PORT = process.env.CODELESS_PORT || 3100; + +// 确保数据目录存在 +const dataDir = path.join(__dirname, '../data'); +if (!fs.existsSync(dataDir)) { + fs.mkdirSync(dataDir, { recursive: true }); +} + +// 初始化数据库 +initDatabase(); + +// 中间件 +app.use(cors()); +app.use(express.json({ limit: '10mb' })); + +// 路由 +app.use('/api/codeless/pages', require('./routes/pages')); +app.use('/api/codeless/components', require('./routes/components')); + +// 健康检查 +app.get('/api/codeless/health', (req, res) => { + res.json({ code: 200, msg: '低代码服务运行正常', timestamp: new Date().toISOString() }); +}); + +// 错误处理 +app.use((err, req, res, next) => { + console.error('服务错误:', err); + res.status(500).json({ code: 500, msg: '服务器内部错误' }); +}); + +app.listen(PORT, () => { + console.log(`\n🚀 低代码系统后端服务已启动`); + console.log(`📍 地址: http://localhost:${PORT}`); + console.log(`📖 API 文档:`); + console.log(` - 页面管理: GET/POST /api/codeless/pages`); + console.log(` - 组件列表: GET /api/codeless/components`); + console.log(` - 健康检查: GET /api/codeless/health\n`); +}); diff --git a/packages/code-less/server/db.js b/packages/code-less/server/db.js new file mode 100644 index 000000000..48be8c972 --- /dev/null +++ b/packages/code-less/server/db.js @@ -0,0 +1,257 @@ +/** + * SQLite 数据库初始化 + */ +const Database = require('better-sqlite3'); +const path = require('path'); + +const dbPath = path.join(__dirname, '../data/codeless.db'); +const db = new Database(dbPath); + +// 初始化数据库表 +function initDatabase() { + // 页面表 + db.exec(` + CREATE TABLE IF NOT EXISTS pages ( + id TEXT PRIMARY KEY, + name TEXT NOT NULL, + path TEXT UNIQUE, + description TEXT, + schema TEXT DEFAULT '[]', + status INTEGER DEFAULT 0, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP + ) + `); + + // 组件表 + db.exec(` + CREATE TABLE IF NOT EXISTS components ( + id TEXT PRIMARY KEY, + type TEXT NOT NULL, + name TEXT NOT NULL, + icon TEXT, + category TEXT DEFAULT 'basic', + props_schema TEXT DEFAULT '{}', + default_props TEXT DEFAULT '{}', + template TEXT, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP + ) + `); + + // 初始化预设组件 + initPresetComponents(); +} + +// 初始化预设组件 +function initPresetComponents() { + const count = db.prepare('SELECT COUNT(*) as count FROM components').get(); + if (count.count > 0) return; + + const presetComponents = [ + { + id: 'input', + type: 'input', + name: '输入框', + icon: 'el-icon-edit', + category: 'form', + props_schema: JSON.stringify({ + label: { type: 'string', default: '输入框', title: '标签' }, + placeholder: { type: 'string', default: '请输入', title: '占位符' }, + field: { type: 'string', default: '', title: '字段名' }, + required: { type: 'boolean', default: false, title: '是否必填' }, + disabled: { type: 'boolean', default: false, title: '是否禁用' }, + maxlength: { type: 'number', default: null, title: '最大长度' } + }), + default_props: JSON.stringify({ + label: '输入框', + placeholder: '请输入', + field: '', + required: false, + disabled: false + }) + }, + { + id: 'select', + type: 'select', + name: '下拉选择', + icon: 'el-icon-arrow-down', + category: 'form', + props_schema: JSON.stringify({ + label: { type: 'string', default: '下拉选择', title: '标签' }, + placeholder: { type: 'string', default: '请选择', title: '占位符' }, + field: { type: 'string', default: '', title: '字段名' }, + required: { type: 'boolean', default: false, title: '是否必填' }, + options: { type: 'array', default: [], title: '选项列表' }, + multiple: { type: 'boolean', default: false, title: '是否多选' } + }), + default_props: JSON.stringify({ + label: '下拉选择', + placeholder: '请选择', + field: '', + required: false, + options: [ + { label: '选项1', value: '1' }, + { label: '选项2', value: '2' } + ], + multiple: false + }) + }, + { + id: 'datepicker', + type: 'datepicker', + name: '日期选择', + icon: 'el-icon-date', + category: 'form', + props_schema: JSON.stringify({ + label: { type: 'string', default: '日期选择', title: '标签' }, + placeholder: { type: 'string', default: '请选择日期', title: '占位符' }, + field: { type: 'string', default: '', title: '字段名' }, + required: { type: 'boolean', default: false, title: '是否必填' }, + type: { type: 'string', default: 'date', title: '类型' } + }), + default_props: JSON.stringify({ + label: '日期选择', + placeholder: '请选择日期', + field: '', + required: false, + type: 'date' + }) + }, + { + id: 'button', + type: 'button', + name: '按钮', + icon: 'el-icon-thumb', + category: 'basic', + props_schema: JSON.stringify({ + text: { type: 'string', default: '按钮', title: '按钮文字' }, + type: { type: 'string', default: 'primary', title: '按钮类型' }, + size: { type: 'string', default: 'medium', title: '尺寸' }, + action: { type: 'string', default: '', title: '点击事件' } + }), + default_props: JSON.stringify({ + text: '按钮', + type: 'primary', + size: 'medium', + action: '' + }) + }, + { + id: 'table', + type: 'table', + name: '表格', + icon: 'el-icon-s-grid', + category: 'data', + props_schema: JSON.stringify({ + columns: { type: 'array', default: [], title: '列配置' }, + dataSource: { type: 'string', default: '', title: '数据源' }, + border: { type: 'boolean', default: true, title: '显示边框' }, + stripe: { type: 'boolean', default: true, title: '斑马纹' } + }), + default_props: JSON.stringify({ + columns: [ + { prop: 'name', label: '名称', width: '' }, + { prop: 'value', label: '值', width: '' } + ], + dataSource: '', + border: true, + stripe: true + }) + }, + { + id: 'text', + type: 'text', + name: '文本', + icon: 'el-icon-document', + category: 'basic', + props_schema: JSON.stringify({ + content: { type: 'string', default: '文本内容', title: '文本内容' }, + fontSize: { type: 'number', default: 14, title: '字体大小' }, + color: { type: 'string', default: '#333', title: '文字颜色' }, + fontWeight: { type: 'string', default: 'normal', title: '字体粗细' } + }), + default_props: JSON.stringify({ + content: '文本内容', + fontSize: 14, + color: '#333', + fontWeight: 'normal' + }) + }, + { + id: 'textarea', + type: 'textarea', + name: '多行文本', + icon: 'el-icon-tickets', + category: 'form', + props_schema: JSON.stringify({ + label: { type: 'string', default: '多行文本', title: '标签' }, + placeholder: { type: 'string', default: '请输入', title: '占位符' }, + field: { type: 'string', default: '', title: '字段名' }, + required: { type: 'boolean', default: false, title: '是否必填' }, + rows: { type: 'number', default: 3, title: '行数' } + }), + default_props: JSON.stringify({ + label: '多行文本', + placeholder: '请输入', + field: '', + required: false, + rows: 3 + }) + }, + { + id: 'radio', + type: 'radio', + name: '单选框', + icon: 'el-icon-circle-check', + category: 'form', + props_schema: JSON.stringify({ + label: { type: 'string', default: '单选框', title: '标签' }, + field: { type: 'string', default: '', title: '字段名' }, + required: { type: 'boolean', default: false, title: '是否必填' }, + options: { type: 'array', default: [], title: '选项列表' } + }), + default_props: JSON.stringify({ + label: '单选框', + field: '', + required: false, + options: [ + { label: '选项1', value: '1' }, + { label: '选项2', value: '2' } + ] + }) + }, + { + id: 'checkbox', + type: 'checkbox', + name: '多选框', + icon: 'el-icon-finished', + category: 'form', + props_schema: JSON.stringify({ + label: { type: 'string', default: '多选框', title: '标签' }, + field: { type: 'string', default: '', title: '字段名' }, + required: { type: 'boolean', default: false, title: '是否必填' }, + options: { type: 'array', default: [], title: '选项列表' } + }), + default_props: JSON.stringify({ + label: '多选框', + field: '', + required: false, + options: [ + { label: '选项1', value: '1' }, + { label: '选项2', value: '2' } + ] + }) + } + ]; + + const stmt = db.prepare(` + INSERT INTO components (id, type, name, icon, category, props_schema, default_props) + VALUES (@id, @type, @name, @icon, @category, @props_schema, @default_props) + `); + + for (const comp of presetComponents) { + stmt.run(comp); + } +} + +module.exports = { db, initDatabase }; diff --git a/packages/code-less/server/routes/components.js b/packages/code-less/server/routes/components.js new file mode 100644 index 000000000..ea6070ebb --- /dev/null +++ b/packages/code-less/server/routes/components.js @@ -0,0 +1,73 @@ +/** + * 组件管理 API + */ +const express = require('express'); +const router = express.Router(); +const { db } = require('../db'); + +// 获取组件列表 +router.get('/', (req, res) => { + try { + const { category } = req.query; + let sql = 'SELECT * FROM components WHERE 1=1'; + const params = []; + + if (category) { + sql += ' AND category = ?'; + params.push(category); + } + + sql += ' ORDER BY category, name'; + + const components = db.prepare(sql).all(...params); + res.json({ + code: 200, + data: components.map(c => ({ + ...c, + props_schema: JSON.parse(c.props_schema || '{}'), + default_props: JSON.parse(c.default_props || '{}') + })), + msg: '获取成功' + }); + } catch (error) { + res.status(500).json({ code: 500, msg: error.message }); + } +}); + +// 获取组件分类 +router.get('/categories', (req, res) => { + try { + const categories = [ + { key: 'basic', name: '基础组件', icon: 'el-icon-s-grid' }, + { key: 'form', name: '表单组件', icon: 'el-icon-document' }, + { key: 'data', name: '数据组件', icon: 'el-icon-s-data' }, + { key: 'layout', name: '布局组件', icon: 'el-icon-s-operation' } + ]; + res.json({ code: 200, data: categories, msg: '获取成功' }); + } catch (error) { + res.status(500).json({ code: 500, msg: error.message }); + } +}); + +// 获取单个组件 +router.get('/:id', (req, res) => { + try { + const component = db.prepare('SELECT * FROM components WHERE id = ?').get(req.params.id); + if (!component) { + return res.status(404).json({ code: 404, msg: '组件不存在' }); + } + res.json({ + code: 200, + data: { + ...component, + props_schema: JSON.parse(component.props_schema || '{}'), + default_props: JSON.parse(component.default_props || '{}') + }, + msg: '获取成功' + }); + } catch (error) { + res.status(500).json({ code: 500, msg: error.message }); + } +}); + +module.exports = router; diff --git a/packages/code-less/server/routes/pages.js b/packages/code-less/server/routes/pages.js new file mode 100644 index 000000000..82dec11f4 --- /dev/null +++ b/packages/code-less/server/routes/pages.js @@ -0,0 +1,172 @@ +/** + * 页面管理 API + */ +const express = require('express'); +const router = express.Router(); +const { v4: uuidv4 } = require('uuid'); +const { db } = require('../db'); + +// 获取页面列表 +router.get('/', (req, res) => { + try { + const { status, keyword } = req.query; + let sql = 'SELECT * FROM pages WHERE 1=1'; + const params = []; + + if (status !== undefined && status !== '') { + sql += ' AND status = ?'; + params.push(parseInt(status)); + } + + if (keyword) { + sql += ' AND (name LIKE ? OR description LIKE ?)'; + params.push(`%${keyword}%`, `%${keyword}%`); + } + + sql += ' ORDER BY updated_at DESC'; + + const pages = db.prepare(sql).all(...params); + res.json({ + code: 200, + data: pages.map(p => ({ + ...p, + schema: JSON.parse(p.schema || '[]') + })), + msg: '获取成功' + }); + } catch (error) { + res.status(500).json({ code: 500, msg: error.message }); + } +}); + +// 获取单个页面 +router.get('/:id', (req, res) => { + try { + const page = db.prepare('SELECT * FROM pages WHERE id = ?').get(req.params.id); + if (!page) { + return res.status(404).json({ code: 404, msg: '页面不存在' }); + } + res.json({ + code: 200, + data: { + ...page, + schema: JSON.parse(page.schema || '[]') + }, + msg: '获取成功' + }); + } catch (error) { + res.status(500).json({ code: 500, msg: error.message }); + } +}); + +// 创建页面 +router.post('/', (req, res) => { + try { + const { name, path, description, schema } = req.body; + if (!name) { + return res.status(400).json({ code: 400, msg: '页面名称不能为空' }); + } + + const id = uuidv4(); + const schemaStr = JSON.stringify(schema || []); + + db.prepare( + ` + INSERT INTO pages (id, name, path, description, schema) + VALUES (?, ?, ?, ?, ?) + ` + ).run(id, name, path || `/${id}`, description || '', schemaStr); + + res.json({ code: 200, data: { id }, msg: '创建成功' }); + } catch (error) { + if (error.message.includes('UNIQUE constraint failed')) { + return res.status(400).json({ code: 400, msg: '页面路径已存在' }); + } + res.status(500).json({ code: 500, msg: error.message }); + } +}); + +// 更新页面 +router.put('/:id', (req, res) => { + try { + const { name, path, description, schema, status } = req.body; + const page = db.prepare('SELECT * FROM pages WHERE id = ?').get(req.params.id); + + if (!page) { + return res.status(404).json({ code: 404, msg: '页面不存在' }); + } + + const updates = []; + const params = []; + + if (name !== undefined) { + updates.push('name = ?'); + params.push(name); + } + if (path !== undefined) { + updates.push('path = ?'); + params.push(path); + } + if (description !== undefined) { + updates.push('description = ?'); + params.push(description); + } + if (schema !== undefined) { + updates.push('schema = ?'); + params.push(JSON.stringify(schema)); + } + if (status !== undefined) { + updates.push('status = ?'); + params.push(status); + } + + updates.push('updated_at = CURRENT_TIMESTAMP'); + params.push(req.params.id); + + db.prepare(`UPDATE pages SET ${updates.join(', ')} WHERE id = ?`).run(...params); + + res.json({ code: 200, msg: '更新成功' }); + } catch (error) { + if (error.message.includes('UNIQUE constraint failed')) { + return res.status(400).json({ code: 400, msg: '页面路径已存在' }); + } + res.status(500).json({ code: 500, msg: error.message }); + } +}); + +// 删除页面 +router.delete('/:id', (req, res) => { + try { + const result = db.prepare('DELETE FROM pages WHERE id = ?').run(req.params.id); + if (result.changes === 0) { + return res.status(404).json({ code: 404, msg: '页面不存在' }); + } + res.json({ code: 200, msg: '删除成功' }); + } catch (error) { + res.status(500).json({ code: 500, msg: error.message }); + } +}); + +// 复制页面 +router.post('/:id/copy', (req, res) => { + try { + const page = db.prepare('SELECT * FROM pages WHERE id = ?').get(req.params.id); + if (!page) { + return res.status(404).json({ code: 404, msg: '页面不存在' }); + } + + const newId = uuidv4(); + db.prepare( + ` + INSERT INTO pages (id, name, path, description, schema) + VALUES (?, ?, ?, ?, ?) + ` + ).run(newId, `${page.name}_副本`, `/${newId}`, page.description, page.schema); + + res.json({ code: 200, data: { id: newId }, msg: '复制成功' }); + } catch (error) { + res.status(500).json({ code: 500, msg: error.message }); + } +}); + +module.exports = router; diff --git a/packages/code-less/src/api/index.js b/packages/code-less/src/api/index.js new file mode 100644 index 000000000..3d3d74799 --- /dev/null +++ b/packages/code-less/src/api/index.js @@ -0,0 +1,90 @@ +/** + * 低代码系统 API + */ +import request from '@/utils/request'; + +const BASE_URL = 'http://localhost:3100/api/codeless'; + +// 页面管理 API +export const pageApi = { + // 获取页面列表 + getList(params) { + return request({ + url: `${BASE_URL}/pages`, + method: 'get', + params + }); + }, + + // 获取单个页面 + getById(id) { + return request({ + url: `${BASE_URL}/pages/${id}`, + method: 'get' + }); + }, + + // 创建页面 + create(data) { + return request({ + url: `${BASE_URL}/pages`, + method: 'post', + data + }); + }, + + // 更新页面 + update(id, data) { + return request({ + url: `${BASE_URL}/pages/${id}`, + method: 'put', + data + }); + }, + + // 删除页面 + delete(id) { + return request({ + url: `${BASE_URL}/pages/${id}`, + method: 'delete' + }); + }, + + // 复制页面 + copy(id) { + return request({ + url: `${BASE_URL}/pages/${id}/copy`, + method: 'post' + }); + } +}; + +// 组件管理 API +export const componentApi = { + // 获取组件列表 + getList(params) { + return request({ + url: `${BASE_URL}/components`, + method: 'get', + params + }); + }, + + // 获取组件分类 + getCategories() { + return request({ + url: `${BASE_URL}/components/categories`, + method: 'get' + }); + }, + + // 获取单个组件 + getById(id) { + return request({ + url: `${BASE_URL}/components/${id}`, + method: 'get' + }); + } +}; + +export default { pageApi, componentApi }; diff --git a/packages/code-less/src/components/ComponentRender.vue b/packages/code-less/src/components/ComponentRender.vue new file mode 100644 index 000000000..178d7d502 --- /dev/null +++ b/packages/code-less/src/components/ComponentRender.vue @@ -0,0 +1,142 @@ + + + + + diff --git a/packages/code-less/src/views/editor.vue b/packages/code-less/src/views/editor.vue new file mode 100644 index 000000000..fec77994c --- /dev/null +++ b/packages/code-less/src/views/editor.vue @@ -0,0 +1,413 @@ + + + + + diff --git a/packages/code-less/src/views/index.vue b/packages/code-less/src/views/index.vue new file mode 100644 index 000000000..a465fd397 --- /dev/null +++ b/packages/code-less/src/views/index.vue @@ -0,0 +1,287 @@ + + + + + diff --git a/packages/code-less/src/views/preview.vue b/packages/code-less/src/views/preview.vue new file mode 100644 index 000000000..055ae95fc --- /dev/null +++ b/packages/code-less/src/views/preview.vue @@ -0,0 +1,102 @@ + + + + + diff --git a/packages/order-system/src/layout/components/Navbar.vue b/packages/order-system/src/layout/components/Navbar.vue index c872309a8..13458ca27 100644 --- a/packages/order-system/src/layout/components/Navbar.vue +++ b/packages/order-system/src/layout/components/Navbar.vue @@ -20,6 +20,12 @@ 个人中心 + + + + 低代码开发 + + diff --git a/packages/order-system/src/router/index.js b/packages/order-system/src/router/index.js index 73588eba3..1f93e7fbd 100644 --- a/packages/order-system/src/router/index.js +++ b/packages/order-system/src/router/index.js @@ -94,6 +94,33 @@ export const constantRoutes = [ meta: { title: '个人中心', icon: 'user' } } ] + }, + // 低代码开发系统 + { + path: '/codeless', + component: Layout, + hidden: true, + redirect: '/codeless/index', + children: [ + { + path: 'index', + component: () => import('@order-system/code-less/src/views/index.vue'), + name: 'CodelessIndex', + meta: { title: '低代码开发', icon: 'component' } + }, + { + path: 'editor', + component: () => import('@order-system/code-less/src/views/editor.vue'), + name: 'CodelessEditor', + meta: { title: '页面编辑器', icon: 'edit' } + }, + { + path: 'preview', + component: () => import('@order-system/code-less/src/views/preview.vue'), + name: 'CodelessPreview', + meta: { title: '页面预览', icon: 'eye-open' } + } + ] } ]; diff --git a/packages/order-system/vue.config.js b/packages/order-system/vue.config.js index 2d2f91225..5cf44de6a 100644 --- a/packages/order-system/vue.config.js +++ b/packages/order-system/vue.config.js @@ -58,7 +58,8 @@ module.exports = { // 支持引用共享包 '@shared': resolve(__dirname, '../shared'), '@ui-components': resolve(__dirname, '../ui-components'), - '@config': resolve(__dirname, '../config') + '@config': resolve(__dirname, '../config'), + '@order-system/code-less': resolve(__dirname, '../code-less') } }, plugins: [ diff --git a/yarn.lock b/yarn.lock index c9bb70537..f82bc5bdd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3127,6 +3127,14 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" +better-sqlite3@^9.4.3: + version "9.6.0" + resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-9.6.0.tgz#b01e58ba7c48abcdc0383b8301206ee2ab81d271" + integrity sha512-yR5HATnqeYNVnkaUTf4bOP2dJSnyhP4puJN/QPRyx4YkBEEUxib422n2XzPqDEHjQQqazoYoADdAm5vE15+dAQ== + dependencies: + bindings "^1.5.0" + prebuild-install "^7.1.1" + bfj@^6.1.1: version "6.1.2" resolved "https://mirrors.tencent.com/npm/bfj/-/bfj-6.1.2.tgz#325c861a822bcb358a41c78a33b8e6e2086dde7f" @@ -3169,7 +3177,7 @@ bindings@^1.5.0: dependencies: file-uri-to-path "1.0.0" -bl@^4.1.0: +bl@^4.0.3, bl@^4.1.0: version "4.1.0" resolved "https://mirrors.tencent.com/npm/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== @@ -4637,6 +4645,13 @@ decode-uri-component@^0.2.0: resolved "https://mirrors.tencent.com/npm/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + dedent@^0.7.0: version "0.7.0" resolved "https://mirrors.tencent.com/npm/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" @@ -4659,6 +4674,11 @@ deep-equal@^1.0.1: object-keys "^1.1.1" regexp.prototype.flags "^1.5.1" +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + deep-is@^0.1.3: version "0.1.4" resolved "https://mirrors.tencent.com/npm/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" @@ -4797,6 +4817,11 @@ detect-indent@^5.0.0: resolved "https://mirrors.tencent.com/npm/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" integrity sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g== +detect-libc@^2.0.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.1.2.tgz#689c5dcdc1900ef5583a4cb9f6d7b473742074ad" + integrity sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ== + detect-newline@^3.0.0: version "3.1.0" resolved "https://mirrors.tencent.com/npm/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" @@ -5195,7 +5220,7 @@ encodeurl@~2.0.0: resolved "https://mirrors.tencent.com/npm/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== -end-of-stream@^1.0.0, end-of-stream@^1.1.0: +end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: version "1.4.5" resolved "https://mirrors.tencent.com/npm/end-of-stream/-/end-of-stream-1.4.5.tgz#7344d711dea40e0b74abc2ed49778743ccedb08c" integrity sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg== @@ -5830,6 +5855,11 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" +expand-template@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" + integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== + expect@^29.7.0: version "29.7.0" resolved "https://mirrors.tencent.com/npm/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc" @@ -6252,6 +6282,11 @@ from2@^2.1.0: inherits "^2.0.1" readable-stream "^2.0.0" +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + fs-extra@^11.1.1, fs-extra@^11.2.0: version "11.3.2" resolved "http://mirrors.cloud.tencent.com/npm/fs-extra/-/fs-extra-11.3.2.tgz#c838aeddc6f4a8c74dd15f85e11fe5511bfe02a4" @@ -6449,6 +6484,11 @@ gh-pages@^6.1.1: fs-extra "^11.1.1" globby "^11.1.0" +github-from-package@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" + integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw== + glob-parent@^3.1.0: version "3.1.0" resolved "https://mirrors.tencent.com/npm/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" @@ -7167,7 +7207,7 @@ inherits@2.0.3: resolved "https://mirrors.tencent.com/npm/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== -ini@^1.3.4: +ini@^1.3.4, ini@~1.3.0: version "1.3.8" resolved "https://mirrors.tencent.com/npm/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== @@ -8957,6 +8997,11 @@ mimic-fn@^2.1.0: resolved "https://mirrors.tencent.com/npm/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + mini-css-extract-plugin@^0.9.0: version "0.9.0" resolved "https://mirrors.tencent.com/npm/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz#47f2cf07aa165ab35733b1fc97d4c46c0564339e" @@ -8991,7 +9036,7 @@ minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" -minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: +minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6: version "1.2.8" resolved "https://mirrors.tencent.com/npm/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== @@ -9066,6 +9111,11 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" +mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + mkdirp@0.3.0: version "0.3.0" resolved "https://mirrors.tencent.com/npm/mkdirp/-/mkdirp-0.3.0.tgz#1bbf5ab1ba827af23575143490426455f481fe1e" @@ -9179,6 +9229,11 @@ nanopop@^2.1.0: resolved "https://mirrors.tencent.com/npm/nanopop/-/nanopop-2.4.2.tgz#b55482135be7e64f2d0f5aa8ef51a58104ac7b13" integrity sha512-NzOgmMQ+elxxHeIha+OG/Pv3Oc3p4RU2aBhwWwAqDpXrdTbtRylbRLQztLy8dMMwfl6pclznBdfUhccEn9ZIzw== +napi-build-utils@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-2.0.0.tgz#13c22c0187fcfccce1461844136372a47ddc027e" + integrity sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA== + natural-compare@^1.4.0: version "1.4.0" resolved "https://mirrors.tencent.com/npm/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -9219,6 +9274,13 @@ no-case@^3.0.4: lower-case "^2.0.2" tslib "^2.0.3" +node-abi@^3.3.0: + version "3.85.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.85.0.tgz#b115d575e52b2495ef08372b058e13d202875a7d" + integrity sha512-zsFhmbkAzwhTft6nd3VxcG0cvJsT70rL+BIGHWVq5fi6MwGrHwzqKaxXE+Hl2GmnGItnDKPPkO5/LQqjVkIdFg== + dependencies: + semver "^7.3.5" + node-emoji@^1.10.0: version "1.11.0" resolved "https://mirrors.tencent.com/npm/node-emoji/-/node-emoji-1.11.0.tgz#69a0150e6946e2f115e9d7ea4df7971e2628301c" @@ -10427,6 +10489,24 @@ posthtml@^0.9.2: posthtml-parser "^0.2.0" posthtml-render "^1.0.5" +prebuild-install@^7.1.1: + version "7.1.3" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.3.tgz#d630abad2b147443f20a212917beae68b8092eec" + integrity sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug== + dependencies: + detect-libc "^2.0.0" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.3" + mkdirp-classic "^0.5.3" + napi-build-utils "^2.0.0" + node-abi "^3.3.0" + pump "^3.0.0" + rc "^1.2.7" + simple-get "^4.0.0" + tar-fs "^2.0.0" + tunnel-agent "^0.6.0" + prelude-ls@^1.2.1: version "1.2.1" resolved "https://mirrors.tencent.com/npm/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -10708,6 +10788,16 @@ raw-body@2.5.2: iconv-lite "0.4.24" unpipe "1.0.0" +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + react-is@^16.13.1: version "16.13.1" resolved "https://mirrors.tencent.com/npm/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" @@ -11509,6 +11599,20 @@ signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: resolved "https://mirrors.tencent.com/npm/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== +simple-concat@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" + integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== + +simple-get@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543" + integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA== + dependencies: + decompress-response "^6.0.0" + once "^1.3.1" + simple-concat "^1.0.0" + simple-swizzle@^0.2.2: version "0.2.4" resolved "https://mirrors.tencent.com/npm/simple-swizzle/-/simple-swizzle-0.2.4.tgz#a8d11a45a11600d6a1ecdff6363329e3648c3667" @@ -12039,6 +12143,11 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: resolved "https://mirrors.tencent.com/npm/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== + strip-outer@^1.0.1: version "1.0.1" resolved "http://mirrors.cloud.tencent.com/npm/strip-outer/-/strip-outer-1.0.1.tgz#b2fd2abf6604b9d1e6013057195df836b8a9d631" @@ -12200,6 +12309,27 @@ tapable@^2.0.0, tapable@^2.2.0, tapable@^2.3.0: resolved "https://mirrors.tencent.com/npm/tapable/-/tapable-2.3.0.tgz#7e3ea6d5ca31ba8e078b560f0d83ce9a14aa8be6" integrity sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg== +tar-fs@^2.0.0: + version "2.1.4" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.4.tgz#800824dbf4ef06ded9afea4acafe71c67c76b930" + integrity sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.1.4" + +tar-stream@^2.1.4: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" + integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== + dependencies: + bl "^4.0.3" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + tar@^6.0.2: version "6.2.1" resolved "https://mirrors.tencent.com/npm/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a" @@ -12886,6 +13016,11 @@ uuid@^8.3.2: resolved "https://mirrors.tencent.com/npm/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== +uuid@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" + integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== + v-code-diff@^1.13.1: version "1.13.1" resolved "https://mirrors.tencent.com/npm/v-code-diff/-/v-code-diff-1.13.1.tgz#acead9aeec90ecf0769fdd23dc2e6ca2ecaa631f"