Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion designer-demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"build:alpha": "cross-env NODE_OPTIONS=--max-old-space-size=10240 vite build --mode alpha",
"build": "cross-env NODE_OPTIONS=--max-old-space-size=10240 vite build",
"test": "vitest run",
"test:watch": "vitest"
"test:watch": "vitest",
"uploadMaterials": "node ./scripts/uploadMaterials.mjs"
},
"dependencies": {
"@opentiny/tiny-engine": "workspace:^",
Expand All @@ -28,6 +29,9 @@
"@opentiny/tiny-engine-vite-config": "workspace:^",
"@vitejs/plugin-vue": "^5.1.2",
"cross-env": "^7.0.3",
"dotenv": "^16.6.1",
"fs-extra": "^11.3.2",
"picocolors": "^1.1.1",
"vite": "^5.4.2",
"vitest": "3.0.9"
}
Expand Down
43 changes: 43 additions & 0 deletions designer-demo/scripts/logger.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import colors from 'picocolors'

class Logger {
constructor(command) {
this.command = command
}

output(type, msg) {
const format = () => {
const colorMap = {
info: 'cyan',
warn: 'yellow',
error: 'red',
success: 'green'
}
const time = new Date().toLocaleTimeString()
const colorMsg = colors[colorMap[type]](type)

return `[${this.command}] [${colors.dim(time)}] ${colorMsg} ${msg}`
}
const _logger = console

return _logger.log(format())
}

info(msg) {
this.output('info', msg)
}

warn(msg) {
this.output('warn', msg)
}

error(msg) {
this.output('error', msg)
}

success(msg) {
this.output('success', msg)
}
}

export default Logger
Comment thread
lu-yg marked this conversation as resolved.
Outdated
67 changes: 67 additions & 0 deletions designer-demo/scripts/uploadMaterials.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { Buffer } from 'node:buffer'
import path from 'node:path'
import dotenv from 'dotenv'
import fs from 'fs-extra'
import Logger from './logger.mjs'


/**
* 同步物料资产包到后端数据库
* 1. 读取 env/.env.local 文件,获取后端地址。需要设置地址如:backend_url=http://localhost:9090
* 2. 读取 public/mock/bundle.json 文件,获取物料资产包数据
* 3. 将物料资产包数据通过 POST 请求上传到后端接口 /material-center/api/component/bundle/create
* 4. 检查数据库t_component表中数据是否更新成功
*
* 使用场景:
* 1. 本地已经将 bundle.json 文件进行修改,但是数据需要同步到后端数据库中。
* 2. 本地已经将 bundle.json 文件进行修改,但是出码仍然不正确。
* @returns
*/
async function main() {
const logger = new Logger('uploadMaterials')

// 先构造出.env*文件的绝对路径
const appDirectory = fs.realpathSync(process.cwd())
const resolveApp = (relativePath) => path.resolve(appDirectory, relativePath)
const pathsDotenv = resolveApp('env')
logger.info(`Start to load .env.local file from ${pathsDotenv}/.env.local`)
dotenv.config({ path: `${pathsDotenv}/.env.local` })
const { backend_url } = process.env

if (!backend_url) {
logger.error('backend_url is not set in .env.local file')
process.exit(1)
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

const bundlePath = path.join(process.cwd(), './public/mock/bundle.json')
logger.info(`Start to read bundle.json file from ${bundlePath}`)
const bundle = fs.readJSONSync(bundlePath)
const jsonBuffer = Buffer.from(JSON.stringify(bundle))

const requestUrl = (backend_url.endsWith('/') ? backend_url.slice(0, -1) : backend_url) + '/material-center/api/component/bundle/create'
logger.info(`Start to upload bundle.json file to ${requestUrl}`)
try {
const formData = new FormData()
formData.append('file', new Blob([jsonBuffer], { type: 'application/json'}), 'bundle.json')
const response = await fetch(requestUrl, {
method: 'POST',
body: formData
})

if (!response.ok) {
const errorText = await response.text()
throw new Error(`Upload failed with status ${response.status}: ${errorText}`)
}
const data = await response.json()
logger.success('File uploaded successfully:', data)
} catch (error) {
logger.error('Error uploading file:', error instanceof Error ? error.message : String(error))
}
Comment on lines +43 to +64
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Validate HTTP response status before parsing.

The script doesn't check if the request succeeded before parsing JSON. Non-2xx responses may cause parsing failures or silent errors.

Apply this diff:

     const response = await fetch(requestUrl, {
       method: 'POST',
       body: formData
     })
+    if (!response.ok) {
+      const errorText = await response.text()
+      throw new Error(`Upload failed with status ${response.status}: ${errorText}`)
+    }
     const data = await response.json()
-    logger.success('File uploaded successfully:', data)
+    logger.success(`File uploaded successfully: ${JSON.stringify(data)}`)
   } catch (error) {
🤖 Prompt for AI Agents
In designer-demo/scripts/uploadMaterials.mjs around lines 43 to 54, the code
parses response.json() without checking HTTP status which can throw or hide
errors on non-2xx responses; update the try block to first check response.ok (or
response.status) after fetch, and if not ok, read the response body (text or
json) and throw or log a descriptive error including status and body; only call
response.json() when response.ok is true and then proceed to logger.success with
the parsed data.

Comment thread
lu-yg marked this conversation as resolved.
}

main()
.catch((e) => {
const logger = new Logger('uploadMaterials')
logger.error('Error uploading file:', e instanceof Error ? e.message : String(e));
process.exit(1);
})
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"splitMaterials": "node ./scripts/splitMaterials.mjs",
"buildMaterials": "node ./scripts/buildMaterials.mjs",
"updateTemplate": "node ./scripts/updateTemplate.mjs",
"uploadMaterials": "node scripts/uploadMaterials.mjs"
"uploadMaterials": "pnpm --filter designer-demo uploadMaterials"
},
"devDependencies": {
"@eslint/js": "^8.57.1",
Expand Down
4 changes: 4 additions & 0 deletions packages/engine-cli/template/designer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"dev": "concurrently 'pnpm:serve:mock' 'pnpm:serve:frontend'",
"build:alpha": "cross-env NODE_OPTIONS=--max-old-space-size=10240 vite build --mode alpha",
"build": "cross-env NODE_OPTIONS=--max-old-space-size=10240 vite build",
"uploadMaterials": "node ./scripts/uploadMaterials.mjs",
"serve:frontend": "cross-env vite",
"serve:mock": "node node_modules/@opentiny/tiny-engine-mock/dist/app.js"
},
Expand All @@ -28,6 +29,9 @@
"@opentiny/tiny-engine-vite-config": "^2.8.0",
"@vitejs/plugin-vue": "^5.1.2",
"cross-env": "^7.0.3",
"dotenv": "^16.6.1",
"fs-extra": "^11.3.2",
"picocolors": "^1.1.1",
"vite": "^5.4.2",
"concurrently": "^8.2.0"
}
Expand Down
43 changes: 43 additions & 0 deletions packages/engine-cli/template/designer/scripts/logger.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import colors from 'picocolors'

class Logger {
constructor(command) {
this.command = command
}
Comment on lines +25 to +34
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify correct color package is imported.

Based on past review comments, the PR adds picocolors to devDependencies, but this code imports colors. If the dependency mismatch is real, the import will always fail and colors will never be available.

Run this script to verify which color package is actually in the dependencies:


🏁 Script executed:

#!/bin/bash
# Check which color packages are in package.json files

echo "=== Template designer package.json ==="
fd -t f '^package.json$' packages/engine-cli/template/designer --exec jq -r 'select(.devDependencies) | .devDependencies | to_entries | .[] | select(.key | contains("color")) | "\(.key): \(.value)"' {}

echo -e "\n=== Designer-demo package.json ==="
fd -t f '^package.json$' designer-demo --exec jq -r 'select(.devDependencies) | .devDependencies | to_entries | .[] | select(.key | contains("color")) | "\(.key): \(.value)"' {}

echo -e "\n=== Root package.json ==="
jq -r 'select(.devDependencies) | .devDependencies | to_entries | .[] | select(.key | contains("color")) | "\(.key): \(.value)"' package.json

Length of output: 158


Fix incorrect package import in logger.mjs.

The code imports colors (line 27) but the available dependency is picocolors. All package.json files in the repository specify only picocolors as available. Change the import statement to use the correct package:

const colorsModule = await import('picocolors')
🤖 Prompt for AI Agents
In packages/engine-cli/template/designer/scripts/logger.mjs around lines 25 to
34, the code attempts to dynamically import the non-existent 'colors' package;
replace that import with the correct package name 'picocolors' so it reads an
import for 'picocolors' instead, then continue to assign this.colors =
colorsModule.default || colorsModule and leave the existing hasColors/try-catch
behavior unchanged.


output(type, msg) {
const format = () => {
const colorMap = {
info: 'cyan',
warn: 'yellow',
error: 'red',
success: 'green'
}
const time = new Date().toLocaleTimeString()
const colorMsg = colors[colorMap[type]](type)

return `[${this.command}] [${colors.dim(time)}] ${colorMsg} ${msg}`
}
const _logger = console

return _logger.log(format())
}

info(msg) {
this.output('info', msg)
}

warn(msg) {
this.output('warn', msg)
}

error(msg) {
this.output('error', msg)
}

success(msg) {
this.output('success', msg)
}
}

export default Logger
62 changes: 62 additions & 0 deletions packages/engine-cli/template/designer/scripts/uploadMaterials.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { Buffer } from 'node:buffer'
import path from 'node:path'
import dotenv from 'dotenv'
import fs from 'fs-extra'
import Logger from './logger.mjs'

/**
* 同步物料资产包到后端数据库
* 1. 读取 env/.env.local 文件,获取后端地址。需要设置地址如:backend_url=http://localhost:9090
* 2. 读取 public/mock/bundle.json 文件,获取物料资产包数据
* 3. 将物料资产包数据通过 POST 请求上传到后端接口 /material-center/api/component/bundle/create
* 4. 检查数据库t_component表中数据是否更新成功
*
* 使用场景:
* 1. 本地已经将 bundle.json 文件进行修改,但是数据需要同步到后端数据库中。
* 2. 本地已经将 bundle.json 文件进行修改,但是出码仍然不正确。
* @returns
*/
async function main() {
const logger = new Logger('uploadMaterials')

// 先构造出.env*文件的绝对路径
const appDirectory = fs.realpathSync(process.cwd())
const resolveApp = (relativePath) => path.resolve(appDirectory, relativePath)
const pathsDotenv = resolveApp('env')
logger.info(`Start to load .env.local file from ${pathsDotenv}/.env.local`)
dotenv.config({ path: `${pathsDotenv}/.env.local` })
const { backend_url } = process.env

if (!backend_url) {
logger.error('backend_url is not set in .env.local file')
return
}
Comment thread
lu-yg marked this conversation as resolved.

const bundlePath = path.join(process.cwd(), './public/mock/bundle.json')
logger.info(`Start to read bundle.json file from ${bundlePath}`)
const bundle = fs.readJSONSync(bundlePath)
const jsonBuffer = Buffer.from(JSON.stringify(bundle))

const requestUrl =
(backend_url.endsWith('/') ? backend_url.slice(0, -1) : backend_url) +
'/material-center/api/component/bundle/create'
logger.info(`Start to upload bundle.json file to ${requestUrl}`)
try {
const formData = new FormData()
formData.append('file', new Blob([jsonBuffer], { type: 'application/json' }), 'bundle.json')
const response = await fetch(requestUrl, {
method: 'POST',
body: formData
})
const data = await response.json()
logger.success('File uploaded successfully:', data)
} catch (error) {
logger.error('Error uploading file:', error instanceof Error ? error.message : String(error))
}
Comment thread
lu-yg marked this conversation as resolved.
}

main().catch((e) => {
const logger = new Logger('uploadMaterials')
logger.error('Error uploading file:', e instanceof Error ? e.message : String(e))
process.exit(1)
})
2 changes: 1 addition & 1 deletion scripts/updateTemplate.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import fs from 'fs-extra'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import Logger from './logger.mjs'
import pkg from '../packages/design-core/package.json' assert { type: 'json' }
import pkg from '../packages/design-core/package.json' with { type: 'json' }

const logger = new Logger('updateTemplate')

Expand Down
40 changes: 0 additions & 40 deletions scripts/uploadMaterials.mjs

This file was deleted.