diff --git a/scripts/buildMaterials.mjs b/scripts/buildMaterials.mjs index 63f861945c..01e768b195 100644 --- a/scripts/buildMaterials.mjs +++ b/scripts/buildMaterials.mjs @@ -28,7 +28,7 @@ const write = (bundle) => { * 校验组件文件数据 * @param {string} file 组件文件路径 * @param {object} component 组件数据 - * @returns + * @returns */ const validateComponent = (file, component) => { const requiredFields = ['component'] @@ -54,7 +54,7 @@ const validateComponent = (file, component) => { * 校验区块文件数据 * @param {string} file 区块文件路径 * @param {object} block 区块数据 - * @returns + * @returns */ const validateBlock = (file, block) => { const requiredFields = ['label', 'assets'] @@ -79,7 +79,7 @@ const validateBlock = (file, block) => { const generateComponents = () => { try { fg([`${materialsDir}/**/*.json`]).then((files) => { - if(!files.length) { + if (!files.length) { logger.warn('物料文件夹为空,请先执行`pnpm splitMaterials`命令拆分物料资产包') } @@ -101,7 +101,9 @@ const generateComponents = () => { const material = fsExtra.readJsonSync(file, { throws: false }) if (!material) { - logger.error(`读取物料文件 ${file} 失败`) + const fileFullPath = path.join(process.cwd(), file) + + logger.error(`文件格式有误 (${fileFullPath})`) return } @@ -146,16 +148,16 @@ const generateComponents = () => { if (connection.connected) { connection.initDB(material) } - }) - appInfo.materialHistory.components = componentsMap + appInfo.materialHistory.components = componentsMap - write(bundle) + write(bundle) + }) }) - logger.success('构建物料资产包成功') + logger.success('物料资产包构建成功') } catch (error) { - logger.error(`构建物料资产包失败:${error}`) + logger.error(`物料资产包构建失败:${error}`) } } @@ -168,20 +170,21 @@ watcher.on('all', (event, file) => { change: '更新', unlink: '删除' } + const fileFullPath = path.join(process.cwd(), file) - logger.info(`${eventMap[event]}组件文件 ${file}`) + logger.info(`${eventMap[event]}组件文件 (${fileFullPath})`) // 监听物料文件变化,更新物料资产包 generateComponents() if (!connection.connected || event === 'unlink') return - const component = fsExtra.readJsonSync(path.join(process.cwd(), file)) + const component = fsExtra.readJsonSync(fileFullPath) if (event === 'change') { - connection.updateComponent(component) + connection.updateComponent(component, fileFullPath) } else if (event === 'add') { - connection.insertComponent(component) + connection.insertComponent(component, fileFullPath) } }) diff --git a/scripts/connection.mjs b/scripts/connection.mjs index 08b1a44fe5..016f856895 100644 --- a/scripts/connection.mjs +++ b/scripts/connection.mjs @@ -41,7 +41,7 @@ class MysqlConnection { logger.warn('未能连接到数据库,请查看数据库配置是否正确') reject() } else { - logger.success('连接数据库成功') + logger.success('数据库连接成功') this.connected = true resolve() } @@ -94,17 +94,74 @@ class MysqlConnection { return str.replace(/'/g, "\\'") } + /** + * 校验组件数据是否有效 + * @param {object} component 组件数据 + * @returns boolean 校验组件字段是否失败,false-有字段出错 + */ + isValid(component, file) { + const longtextFields = ['name', 'npm', 'snippets', 'schema_fragment', 'configure', 'component_metadata'] + + return Object.entries(component).every(([key, value]) => { + if (longtextFields.includes(key) && value !== null && typeof value !== 'object') { + logger.error(`"${key}" 的值不是有效的JSON (${file})`) + + return false + } + + return true + }) + } + /** * 生成更新组件的sql语句 * @param {object} component 组件数据 * @returns 更新组件的sql语句 */ - updateComponent(component) { + updateComponent(component, file) { + const valid = this.isValid(component, file) + + if (!valid) { + return + } + const values = [] let sqlContent = `update ${componentsTableName} set ` Object.keys(component).forEach((key) => { const { [key]: value } = component + const fields = [ + 'version', + 'name', + 'component', + 'icon', + 'description', + 'docUrl', + 'screenshot', + 'tags', + 'keywords', + 'devMode', + 'npm', + 'group', + 'category', + 'priority', + 'snippets', + 'schema', + 'configure', + 'public', + 'framework', + 'isOfficial', + 'isDefault', + 'tiny_reserved', + 'tenant', + 'createBy', + 'updatedBy' + ] + + if (!fields.includes(key)) { + return + } + const field = this.fieldTransform(key) let updateContent = '' @@ -136,10 +193,10 @@ class MysqlConnection { this.query(sqlContent, component.component) .then(() => { - logger.success(`更新组件 ${component.component} 成功`) + logger.success(`组件 ${component.component} 数据更新成功`) }) .catch((error) => { - logger.success(`更新组件 ${component.component} 失败:${error}`) + logger.error(`组件 ${component.component} 数据更新失败 ${error}`) }) } @@ -163,7 +220,16 @@ class MysqlConnection { * @param {object} component 组件数据 * @returns 新增组件的sql语句 */ - insertComponent(component) { + insertComponent(component, file) { + const valid = this.isValid(component, file) + + if (!valid) { + return + } + + const defaultName = { + zh_CN: component.component + } const defaultNpm = { package: '', exportName: '', @@ -195,7 +261,7 @@ class MysqlConnection { } const { version = '1.0.0', - name, + name = defaultName, component: componentName, icon, description, @@ -256,11 +322,11 @@ class MysqlConnection { .then((result) => { const id = result.insertId - logger.success(`新增组件 ${component.component} 成功`) + logger.success(`组件 ${component.component} 数据新增成功`) this.relationMaterialHistory(id) }) .catch((error) => { - logger.success(`新增组件 ${component.component} 失败:${error}`) + logger.success(`组件 ${component.component} 数据新增失败:${error}`) }) } @@ -329,11 +395,11 @@ class MysqlConnection { return new Promise((resolve, reject) => { this.query(sqlContent) .then((result) => { - logger.success(`创建表 ${componentsTableName} 成功`) + logger.success(`表 ${componentsTableName} 创建成功`) resolve(result) }) .catch((error) => { - logger.success(`创建表 ${componentsTableName} 失败:${error}`) + logger.success(`表 ${componentsTableName} 创建失败:${error}`) reject(error) }) }) diff --git a/scripts/logger.mjs b/scripts/logger.mjs index e7e8657565..7d7e3a276d 100644 --- a/scripts/logger.mjs +++ b/scripts/logger.mjs @@ -14,9 +14,9 @@ class Logger { success: 'green' } const time = new Date().toLocaleTimeString() - const colorMsg = colors[colorMap[type]](msg) + const colorMsg = colors[colorMap[type]](type) - return `[${this.command}] [${colors.dim(time)}] ${colorMsg}` + return `[${this.command}] [${colors.dim(time)}] ${colorMsg} ${msg}` } // eslint-disable-next-line no-console