Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"scripts": {
"dev": "pnpm -F tiny-pro-vue start",
"dev:backend": "pnpm -F tinyui-nestjs-server start",
"dev:designer": "pnpm -F template/lowcode-designer dev",
"describe": "npm-scripts-info",
"build": "run-s build:*",
"build:main": "tsc -p tsconfig.json",
Expand Down
70 changes: 69 additions & 1 deletion template/lowcode-designer/src/composable/http/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { HttpService } from '@opentiny/tiny-engine'
import { useBroadcastChannel } from '@vueuse/core'
import { constants } from '@opentiny/tiny-engine-utils'
import Login from './Login.vue'
import mockConfig from './mockConfig'

const LOGIN_EXPIRED_CODE = 401
const { BROADCAST_CHANNEL } = constants
Expand Down Expand Up @@ -36,6 +37,71 @@ const preRequest = (config) => {
config.baseURL = ''
}

// 检查是否需要 mock - 纯前端项目,拦截 /api/user/me 接口
const fullUrl = (config.baseURL || '') + (config.url || '')
const urlToCheck = config.url || ''

// 检查是否是 /api/user/me 或 /user/me 请求
const isMeRequest = /\/api\/user\/me$|\/user\/me$/.test(fullUrl) ||
/\/api\/user\/me$|\/user\/me$/.test(urlToCheck)

if (isMeRequest && (config.method || 'GET').toUpperCase() === 'GET') {

// 找到对应的 mock 配置
const mockRoute = mockConfig.find((route) => {
const urlMatch = typeof route.url === 'string'
? fullUrl.includes(route.url) || urlToCheck.includes(route.url)
: route.url.test(fullUrl) || route.url.test(urlToCheck)
const methodMatch = !route.method ||
route.method.toUpperCase() === (config.method || 'GET').toUpperCase()
return urlMatch && methodMatch
})

if (mockRoute) {
// 直接调用 mock 的 response 函数
const mockResult = mockRoute.response(config)

// 如果返回的是 Promise,等待 resolve
if (mockResult && typeof mockResult.then === 'function') {
return mockResult.then(([status, data]) => {
// 返回一个模拟的响应对象
// 注意:axios 请求拦截器返回的应该是 config,但我们可以通过返回一个特殊对象来阻止请求
// 实际上,我们需要修改 config,让它不会发送真实请求
config.adapter = () => {
// 返回一个 Promise,resolve 一个模拟的响应
return Promise.resolve({
data: {
data,
error: null
},
status,
statusText: 'OK',
headers: {},
config
})
}
return config
})
} else {
// 如果 response 不是异步的,直接处理
const [status, data] = mockResult
config.adapter = () => {
return Promise.resolve({
data: {
data,
error: null
},
status,
statusText: 'OK',
headers: {},
config
})
}
return config
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
}
}

return config
}

Expand Down Expand Up @@ -124,7 +190,9 @@ const customizeHttpService = () => {
interceptors: {
request: [preRequest],
response: [[preResponse, errorResponse]]
}
},
mockConfig,
enableMock: true
}

HttpService.apis.setOptions(options)
Expand Down
45 changes: 45 additions & 0 deletions template/lowcode-designer/src/composable/http/mockConfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* Mock 路由配置
* 用于纯前端项目的接口 mock
*/

// Mock 用户数据(真实接口返回格式)
const mockUserData = {
data: {
id: 1,
username: '开发者',
email: 'developer@lowcode.com',
provider: null,
password: null,
confirmationToken: 'uuid~dfafasdfasdfa',
confirmed: true,
blocked: false,
created_by: null,
updated_by: null,
created_at: '2021-11-11T13:52:21.000Z',
updated_at: '2022-11-01T01:39:30.000Z',
block: false,
is_admin: true,
is_public: false,
},
locale: 'zh-cn',
};
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

// 格式化响应数据
const getResponseData = (data) => {
return {
data,
error: null,
};
};

export default [
// 获取用户信息
{
url: /\/api\/user\/me$|\/user\/me$/, // 使用正则表达式匹配
method: 'GET',
response: async () => {
return [200, getResponseData(mockUserData)];
},
},
];
Copy link
Copy Markdown

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

🏁 Script executed:

# Search for enableMock configuration and environment checks
rg -n 'enableMock' --type=js --type=json -g '!node_modules'

Repository: opentiny/tiny-pro

Length of output: 140


🏁 Script executed:

# Search for environment-based conditionals related to mocking
rg -n -B3 -A3 'NODE_ENV|VITE_|VUE_APP_' template/lowcode-designer/src/composable/http/ --type=js

Repository: opentiny/tiny-pro

Length of output: 642


🏁 Script executed:

# Find where mockConfig.js is imported
rg -n 'mockConfig|from.*mockConfig' template/lowcode-designer/src/composable/http/ --type=js

Repository: opentiny/tiny-pro

Length of output: 339


🏁 Script executed:

# Look at the index.js file in the same directory
cat -n template/lowcode-designer/src/composable/http/index.js | head -50

Repository: opentiny/tiny-pro

Length of output: 1743


🏁 Script executed:

# Get context around line 195 where enableMock is set
cat -n template/lowcode-designer/src/composable/http/index.js | sed -n '180,210p'

Repository: opentiny/tiny-pro

Length of output: 676


🏁 Script executed:

# Also check if there's any conditional logic around where the config is used/applied
cat -n template/lowcode-designer/src/composable/http/index.js | sed -n '40,70p'

Repository: opentiny/tiny-pro

Length of output: 1508


🏁 Script executed:

# Search for how enableMock is used in the codebase
rg -n 'enableMock' --type=js -B5 -A5

Repository: opentiny/tiny-pro

Length of output: 915


🏁 Script executed:

# Check if there's a build-time check or other safeguard for mocking in production
rg -n -i 'production|prod.*mock|mock.*prod' template/lowcode-designer/src/composable/http/ --type=js

Repository: opentiny/tiny-pro

Length of output: 43


🏁 Script executed:

# Check the getConfig function more completely to see full environment logic
cat -n template/lowcode-designer/src/composable/http/index.js | sed -n '170,186p'

Repository: opentiny/tiny-pro

Length of output: 587


Gate enableMock by development environment.

The enableMock: true setting at line 195 of index.js is hardcoded without environment checks. While getConfig() properly gates development-only features using env.MODE?.includes('dev') (line 173), the mock configuration is unconditionally enabled. Change line 195 to:

enableMock: getConfig().enableMock ?? import.meta.env.MODE?.includes('dev')

Or pass the environment check explicitly:

const isDev = import.meta.env.MODE?.includes('dev')
// ...
enableMock: isDev

This ensures mocks never run in production builds.

🤖 Prompt for AI Agents
In @template/lowcode-designer/src/composable/http/mockConfig.js around lines 36
- 45, The enableMock flag is currently hardcoded to true in index.js; change the
enableMock assignment (symbol: enableMock in index.js) to be gated by
environment by using getConfig().enableMock with a fallback to the dev check
(import.meta.env.MODE?.includes('dev')) or compute an isDev boolean and use that
instead so mocks only run in development; update the enableMock assignment
accordingly to reference getConfig() or the isDev check rather than the literal
true.

Loading