@yorha2b-lab/autodev 3.1.3 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yorha2b-lab/autodev",
3
- "version": "3.1.3",
3
+ "version": "3.2.0",
4
4
  "description": "基于视觉大模型的前端(react+Antd)全自动 CRUD 代码生成器",
5
5
  "bin": {
6
6
  "autodev": "bin/autodev.js"
@@ -2,12 +2,12 @@ const fs = require('fs')
2
2
  const ora = require('ora')
3
3
  const chalk = require('chalk')
4
4
  const stringify = require('json-stringify-pretty-compact')
5
- const { cleanCode, formatFormItemAndColumns } = require('../../utils/utils')
6
5
 
7
6
  module.exports = async filePath => {
8
7
 
9
8
  const { get } = require('../../core/context')
10
9
  const { language, partPrompt, recognizePage } = get()
10
+ const { cleanCode, formatFormItemAndColumns } = require('../../utils/utils')
11
11
 
12
12
  const startTime = Date.now()
13
13
 
@@ -4,12 +4,12 @@ const chalk = require('chalk')
4
4
  const chokidar = require('chokidar')
5
5
  const stringify = require('json-stringify-pretty-compact')
6
6
 
7
- const { get } = require('../core/context')
8
- const { copyTemplateDir } = require('../utils/utils.js')
9
- const { createTaskQueue } = require('../core/task-queue.js')
10
-
11
7
  const watch = () => {
12
8
 
9
+ const { get } = require('../core/context')
10
+ const { copyTemplateDir } = require('../utils/utils.js')
11
+ const { createTaskQueue } = require('../core/task-queue.js')
12
+
13
13
  const { menus, config, options, template, language, apiHandler, pageHandler, partHandler } = get()
14
14
 
15
15
  const compilerPath = path.join(__dirname, `../core/${template}-compiler.js`)
@@ -1,11 +1,10 @@
1
1
  const fs = require('fs')
2
2
  const path = require('path')
3
3
  const Handlebars = require('handlebars')
4
- const apiHandler = require('../commands/handlers/api-handler')
5
- const pageHandler = require('../commands/handlers/page-handler')
6
- const partHandler = require('../commands/handlers/part-handler')
7
- const { recognizePage, generateMock, alignResponseFields } = require('../services/llm')
8
- const { language, getConfig, unwrapSignal, isQuerySignal, getExistingMenus } = require('../utils/utils')
4
+ const stringify = require('json-stringify-pretty-compact')
5
+
6
+ Handlebars.registerHelper('raw', options => options.fn())
7
+ Handlebars.registerHelper('stringify', (context, maxLength = 200) => context ? new Handlebars.SafeString(stringify.default(context, { indent: 4, maxLength })) : '[]')
9
8
 
10
9
  let instance = null // 💡 物理封存的全局实例
11
10
 
@@ -15,16 +14,29 @@ module.exports = {
15
14
  */
16
15
  init: options => {
17
16
 
17
+ const { recognizePage, generateMock, alignResponseFields } = require('../services/llm')
18
+ const { language, getConfig, unwrapSignal, isQuerySignal, getExistingMenus } = require('../utils/utils')
19
+
18
20
  const config = getConfig()
19
21
  const menus = getExistingMenus()
20
22
  const template = options.template
23
+ const apiHandler = require('../commands/handlers/api-handler')
24
+ const pageHandler = require('../commands/handlers/page-handler')
25
+ const partHandler = require('../commands/handlers/part-handler')
26
+ const tplDir = config.hbsDir !== '' ? path.join(process.cwd(), config.hbsDir) : path.join(__dirname, `../../templates/${template}`)
21
27
 
22
28
  const compilerPath = path.join(__dirname, `./${template}-compiler.js`)
23
29
  const { index, resource } = require(compilerPath)
24
30
 
25
- const tplDir = config.hbsDir !== ''
26
- ? path.join(process.cwd(), config.hbsDir)
27
- : path.join(__dirname, `../../templates/${template}`)
31
+ // 💡 物理扫描:把目录下所有的 .hbs 文件全部识别并自动注册
32
+ const partialsDir = path.join(__dirname, `../../templates/${template}/handlebars`)
33
+ fs.readdirSync(partialsDir).forEach(file => {
34
+ if (file.endsWith('.hbs')) {
35
+ const name = path.basename(file, '.hbs') // 去掉后缀拿名字
36
+ const content = fs.readFileSync(path.join(partialsDir, file), 'utf-8')
37
+ Handlebars.registerPartial(name, `${content}\n`)
38
+ }
39
+ })
28
40
 
29
41
  instance = {
30
42
  resource, index, template,
@@ -1,12 +1,5 @@
1
- const fs = require('fs')
2
- const path = require('path')
3
- const Handlebars = require('handlebars')
4
- const stringify = require('json-stringify-pretty-compact')
5
1
  const { cleanCode, generateSmartImports, formatFormItemAndColumns } = require('../utils/utils.js')
6
2
 
7
- Handlebars.registerHelper('raw', options => options.fn())
8
- Handlebars.registerHelper('stringify', (context, maxLength = 200) => context ? new Handlebars.SafeString(stringify.default(context, { indent: 4, maxLength })) : '[]')
9
-
10
3
  /**
11
4
  * 生成 resource.js 文件(表格列配置、表单配置、字典等)
12
5
  * @param {Object} param0 - 函数参数
@@ -64,36 +57,15 @@ const index = ({ config, fileName, indexTpl, pageConfig }) => {
64
57
  functionButtons,
65
58
  tabs: pageConfig.tabs,
66
59
  responseSuccess: config.responseSuccess,
67
- hasStaticInfo: pageConfig.staticInfo?.has,
68
60
  hasExpandable: pageConfig.table.expandable,
69
61
  hasPagination: pageConfig.table.pagination,
62
+ staticInfoText: pageConfig.staticInfo?.text,
70
63
  operations: pageConfig.table.operation || [],
71
64
  hasRowSelection: pageConfig.table.rowSelection,
72
65
  formItems: hasFormItems ? (hasTabs ? 'formItems[activeKey]' : 'formItems') : '[]',
73
66
  pageStruct: hasFunctionButtons ? pageStruct : pageStruct.filter(item => item !== 'FunctionButtonsBlock'),
74
67
  }
75
68
 
76
- if (viewData.hasOperate) {
77
- Handlebars.registerPartial('tableOperate', `${fs.readFileSync(path.join(__dirname, '../../templates/react/handlebars/tableOperate.hbs'), 'utf-8')}\n`)
78
- }
79
-
80
- if (viewData.hasFormItems) {
81
- Handlebars.registerPartial('MySearchForm', `${fs.readFileSync(path.join(__dirname, '../../templates/react/handlebars/MySearchForm.hbs'), 'utf-8')}\n`)
82
- }
83
-
84
- if (hasFunctionButtons) {
85
- Handlebars.registerPartial('FunctionButtonsBlock', `${fs.readFileSync(path.join(__dirname, '../../templates/react/handlebars/functionButtonsBlock.hbs'), 'utf-8')}\n`)
86
- }
87
-
88
- if (viewData.hasStaticInfo) {
89
- Handlebars.registerPartial('AlertInfo', `{{{{raw}}}}<Alert showIcon title='${pageConfig.staticInfo?.text}' type='info' style={{ marginBottom: 16 }} />\n{{{{/raw}}}}`)
90
- }
91
-
92
- Handlebars.registerPartial('MyTable', `${fs.readFileSync(path.join(__dirname, '../../templates/react/handlebars/MyTable.hbs'), 'utf-8')}\n`)
93
- Handlebars.registerPartial('hookBlock', `${fs.readFileSync(path.join(__dirname, '../../templates/react/handlebars/hookBlock.hbs'), 'utf-8')}\n`)
94
- Handlebars.registerPartial('stateBlock', `${fs.readFileSync(path.join(__dirname, '../../templates/react/handlebars/stateBlock.hbs'), 'utf-8')}\n`)
95
- Handlebars.registerPartial('handleBlock', `${fs.readFileSync(path.join(__dirname, '../../templates/react/handlebars/handleBlock.hbs'), 'utf-8')}\n`)
96
-
97
69
  const bodyCode = indexTpl(viewData)
98
70
  const importsStr = generateSmartImports({ bodyCode, hasTabs, hasFormItems })
99
71
  return cleanCode(`${importsStr}\n\n${bodyCode}`)
@@ -2,7 +2,6 @@ const http = require('http')
2
2
  const zlib = require('zlib')
3
3
  const chalk = require('chalk')
4
4
  const httpProxy = require('http-proxy')
5
- const { get } = require('../core/context')
6
5
 
7
6
  /**
8
7
  * @function startProxyTower
@@ -11,6 +10,7 @@ const { get } = require('../core/context')
11
10
  */
12
11
  module.exports = () => {
13
12
 
13
+ const { get } = require('../core/context')
14
14
  const { config, language, apiHandler, unwrapSignal, isQuerySignal } = get()
15
15
 
16
16
  const TOWER_PORT = 42153
@@ -24,57 +24,55 @@ module.exports = () => {
24
24
  return Object.keys(Array.isArray(obj) ? (obj[0] || {}) : obj).sort().join(',')
25
25
  }
26
26
 
27
- const server = http.createServer((req, res) => {
27
+ // 💡 物理监控:劫持响应流
28
+ proxy.on('proxyRes', function (proxyRes, req, res) {
29
+ let body = []
30
+ proxyRes.on('data', chunk => body.push(chunk))
31
+ proxyRes.on('end', async () => {
32
+ const buffer = Buffer.concat(body)
33
+ const encoding = proxyRes.headers['content-encoding']
34
+ try {
35
+ const rawBody = encoding === 'gzip' ? zlib.gunzipSync(buffer) : buffer
36
+ const json = JSON.parse(rawBody.toString())
37
+
38
+ const coreData = unwrapSignal(json) // 先脱水
39
+
40
+ // 💡 这一步就是地堡的“火控系统”
41
+ if (!isQuerySignal(req, json, coreData)) {
42
+ return // 增删改信号,直接丢弃,保持静默
43
+ }
28
44
 
29
- const target = config.proxyTarget
45
+ const referer = req.headers.referer || ''
46
+ const fileName = referer.split('?')[0].split('/').filter(Boolean).at(-1)
47
+
48
+ const fingerprint = getJsonFingerprint(unwrapSignal(json)) // 获取数据指纹
49
+ const lastFingerprint = hackedRegistry.get(fileName)
50
+
51
+ // 如果指纹没变,说明字段结构是一样的,无需再次骇入
52
+ if (lastFingerprint === fingerprint) {
53
+ return
54
+ }
30
55
 
56
+ console.log(chalk.cyan(language(
57
+ `\n📡 Pod 153: 截获运行时信号 [${fileName}]。执行自动对齐协议...`,
58
+ `\n📡 Pod 153: Captured runtime signal [${fileName}]. Executing semantic alignment protocol...`
59
+ )))
60
+ // 💡 直接调用 api-handler 物理更新 resource.js
61
+ await apiHandler(null, { fileName, data: json })
62
+ hackedRegistry.set(fileName, fingerprint)
63
+ } catch (e) {
64
+ console.log(e)
65
+ // 非 JSON 信号,保持静默
66
+ }
67
+ })
68
+ })
69
+
70
+ const server = http.createServer((req, res) => {
71
+ const target = config.proxyTarget
31
72
  if (!target) {
32
73
  // 静默模式:如果不配置 proxyTarget,拦截塔只转发不处理(或报错提示)
33
74
  return
34
75
  }
35
-
36
- // 💡 物理监控:劫持响应流
37
- proxy.on('proxyRes', function (proxyRes, req, res) {
38
- let body = []
39
- proxyRes.on('data', chunk => body.push(chunk))
40
- proxyRes.on('end', async () => {
41
- const buffer = Buffer.concat(body)
42
- const encoding = proxyRes.headers['content-encoding']
43
- try {
44
- const rawBody = encoding === 'gzip' ? zlib.gunzipSync(buffer) : buffer
45
- const json = JSON.parse(rawBody.toString())
46
-
47
- const coreData = unwrapSignal(json) // 先脱水
48
-
49
- // 💡 这一步就是地堡的“火控系统”
50
- if (!isQuerySignal(req, json, coreData)) {
51
- return // 增删改信号,直接丢弃,保持静默
52
- }
53
-
54
- const referer = req.headers.referer || ''
55
- const fileName = referer.split('?')[0].split('/').filter(Boolean).at(-1)
56
-
57
- const fingerprint = getJsonFingerprint(unwrapSignal(json)) // 获取数据指纹
58
- const lastFingerprint = hackedRegistry.get(fileName)
59
-
60
- // 如果指纹没变,说明字段结构是一样的,无需再次骇入
61
- if (lastFingerprint === fingerprint) {
62
- return
63
- }
64
-
65
- console.log(chalk.cyan(language(
66
- `\n📡 Pod 153: 截获运行时信号 [${fileName}]。执行自动对齐协议...`,
67
- `\n📡 Pod 153: Captured runtime signal [${fileName}]. Executing semantic alignment protocol...`
68
- )))
69
- // 💡 直接调用 api-handler 物理更新 resource.js
70
- await apiHandler(null, { fileName, data: json })
71
- hackedRegistry.set(fileName, fingerprint)
72
- } catch (e) {
73
- console.log(e)
74
- // 非 JSON 信号,保持静默
75
- }
76
- })
77
- })
78
76
  // 转发至真实后端
79
77
  proxy.web(req, res, { target, changeOrigin: true })
80
78
  })
@@ -0,0 +1 @@
1
+ <Alert showIcon message={'{{staticInfoText}}'} type='info' {{{{raw}}}}style={{ marginBottom: 16 }}{{{{/raw}}}} />