@_tc/template-core 0.0.3 → 0.1.1

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.
Files changed (177) hide show
  1. package/.skills/tc-generator/SKILL.md +62 -0
  2. package/.skills/tc-generator/reference/example.md +357 -0
  3. package/.skills/tc-generator/reference/model-schema.md +326 -0
  4. package/.skills/tc-generator/reference/project-template/app/controller/product.js +73 -0
  5. package/.skills/tc-generator/reference/project-template/app/router/product.js +9 -0
  6. package/.skills/tc-generator/reference/project-template/config/config.default.js +3 -0
  7. package/.skills/tc-generator/reference/project-template/index.js +17 -0
  8. package/.skills/tc-generator/reference/project-template/model/product/mode.js +179 -0
  9. package/.skills/tc-generator/reference/project-template/model/product/project/default.js +4 -0
  10. package/.skills/tc-generator/reference/project-template/package.json +10 -0
  11. package/README.md +239 -17
  12. package/cjs/_virtual/_rolldown/runtime.js +1 -1
  13. package/cjs/app/controller/base.js +1 -1
  14. package/cjs/app/controller/project.js +1 -1
  15. package/cjs/app/controller/view.js +1 -1
  16. package/cjs/app/extend/$fetch.js +1 -1
  17. package/cjs/app/extend/db.js +1 -1
  18. package/cjs/app/extend/generateErrorMessage.js +1 -1
  19. package/cjs/app/extend/logger.js +1 -1
  20. package/cjs/app/extend/parsingParamsOnUrl.js +1 -1
  21. package/cjs/app/middleware/api-sign-verify.js +1 -1
  22. package/cjs/app/middleware/error-handle.js +1 -1
  23. package/cjs/app/middleware/project-handler.js +1 -1
  24. package/cjs/app/middleware.js +1 -1
  25. package/cjs/app/router/project.js +1 -1
  26. package/cjs/app/router/view.js +1 -1
  27. package/cjs/app/router-schema/project.js +1 -1
  28. package/cjs/app/service/base.js +1 -1
  29. package/cjs/app/service/project.js +1 -1
  30. package/cjs/app/type.js +0 -1
  31. package/cjs/app/typings.js +0 -1
  32. package/cjs/app/view/entry.tpl +27 -28
  33. package/cjs/bundler/defaultAlias.js +1 -1
  34. package/cjs/bundler/dev.js +1 -1
  35. package/cjs/bundler/index.js +1 -1
  36. package/cjs/bundler/prod.js +1 -1
  37. package/cjs/bundler/state.js +1 -1
  38. package/cjs/config/config.default.js +1 -0
  39. package/cjs/index.js +1 -1
  40. package/cjs/packages/common/LRUCache.js +1 -1
  41. package/cjs/packages/common/array/index.js +1 -1
  42. package/cjs/packages/common/cache/LRUCache.js +1 -1
  43. package/cjs/packages/common/cache/index.js +1 -1
  44. package/cjs/packages/common/guards/index.js +1 -1
  45. package/cjs/packages/common/http/index.js +1 -1
  46. package/cjs/packages/common/i18n/default.js +1 -1
  47. package/cjs/packages/common/i18n/en-US.js +1 -1
  48. package/cjs/packages/common/i18n/index.js +1 -1
  49. package/cjs/packages/common/i18n/locales.js +1 -1
  50. package/cjs/packages/common/i18n/types.js +0 -1
  51. package/cjs/packages/common/index.js +1 -1
  52. package/cjs/packages/common/log/index.js +1 -1
  53. package/cjs/packages/common/number/index.js +1 -1
  54. package/cjs/packages/common/object/filterEmpty.js +1 -1
  55. package/cjs/packages/common/object/filtereEmpty.js +1 -1
  56. package/cjs/packages/common/object/index.js +1 -1
  57. package/cjs/packages/common/string/index.js +1 -1
  58. package/cjs/packages/common/types/index.js +0 -1
  59. package/cjs/packages/core/env.js +1 -1
  60. package/cjs/packages/core/index.js +1 -1
  61. package/cjs/packages/core/loader/config.js +1 -1
  62. package/cjs/packages/core/loader/controller.js +1 -1
  63. package/cjs/packages/core/loader/extend.js +1 -1
  64. package/cjs/packages/core/loader/middleware.js +1 -1
  65. package/cjs/packages/core/loader/router-schema.js +1 -1
  66. package/cjs/packages/core/loader/service.js +1 -1
  67. package/cjs/packages/core/paths.js +1 -1
  68. package/cjs/packages/core/types.js +0 -1
  69. package/cjs/packages/utils/getAllFnReturnValue.js +0 -1
  70. package/cjs/packages/utils/index.js +1 -1
  71. package/esm/_virtual/_rolldown/runtime.js +2 -15
  72. package/esm/app/controller/view.js +13 -11
  73. package/esm/app/middleware/api-sign-verify.js +9 -11
  74. package/esm/app/middleware.js +6 -6
  75. package/esm/app/view/entry.tpl +27 -28
  76. package/esm/config/config.default.js +9 -0
  77. package/esm/index.js +1 -1
  78. package/esm/packages/core/index.js +24 -26
  79. package/esm/packages/core/loader/config.js +11 -10
  80. package/esm/packages/core/loader/extend.js +13 -8
  81. package/fe/frontend/apps/dash/Dashboard.js +100 -1
  82. package/fe/frontend/apps/dash/dash.entry.js +2 -2
  83. package/fe/frontend/apps/ui-components/index.js +8 -0
  84. package/fe/frontend/apps/ui-components/ui-components.entry.d.ts +2 -0
  85. package/fe/frontend/src/api/baseInfo.d.ts +2 -2
  86. package/fe/frontend/src/common/fetchErrorShow.js +2 -1
  87. package/fe/frontend/src/common/generateMenuData.js +2 -1
  88. package/fe/frontend/src/common/importComponent.js +5 -2
  89. package/fe/frontend/src/common/language.d.ts +2 -1
  90. package/fe/frontend/src/common/language.js +7 -5
  91. package/fe/frontend/src/common/logFn/index.js +6 -4
  92. package/fe/frontend/src/common/request.js +6 -4
  93. package/fe/frontend/src/components/BasePage/HeaderView.d.ts +2 -1
  94. package/fe/frontend/src/components/BasePage/HeaderView.js +9 -4
  95. package/fe/frontend/src/defaultPages/Iframe/index.js +1 -7
  96. package/fe/frontend/src/defaultPages/NotFoundPage/index.d.ts +3 -0
  97. package/fe/frontend/src/defaultPages/NotFoundPage/index.js +7 -0
  98. package/fe/frontend/src/defaultPages/SchemaPage/components/CallCom/DetailPanel.js +3 -2
  99. package/fe/frontend/src/defaultPages/SchemaPage/components/CallCom/PopFrom.js +8 -2
  100. package/fe/frontend/src/defaultPages/SchemaPage/components/SchemaTable/index.js +4 -3
  101. package/fe/frontend/src/defaultPages/SchemaPage/index.css +0 -55
  102. package/fe/frontend/src/defaultPages/SchemaPage/index.js +3 -1
  103. package/fe/frontend/src/defaultPages/SchemaPage/utils/validator.d.ts +5 -1
  104. package/fe/frontend/src/defaultPages/SchemaPage/utils/validator.js +142 -7
  105. package/fe/frontend/src/defaultPages/SidebarSlotPage/index.js +2 -1
  106. package/fe/frontend/src/defaultPages/SidebarSlotPageTmp.js +1 -1
  107. package/fe/frontend/src/defaultPages/SlotPage/index.js +2 -1
  108. package/fe/frontend/src/hooks/useCurrentMenuData.js +1 -1
  109. package/fe/frontend/src/index.d.ts +4 -0
  110. package/fe/frontend/src/index.js +4 -0
  111. package/fe/frontend/src/language/en-US.d.ts +76 -0
  112. package/fe/frontend/src/language/en-US.js +75 -0
  113. package/fe/frontend/src/language/index.d.ts +66 -0
  114. package/fe/frontend/src/language/index.js +69 -0
  115. package/fe/frontend/src/language/zh-CN.d.ts +76 -0
  116. package/fe/frontend/src/language/zh-CN.js +75 -0
  117. package/fe/frontend/src/typing/window.d.ts +2 -0
  118. package/fe/model/types/data/button.d.ts +2 -2
  119. package/fe/model/types/data/button.js +1 -1
  120. package/fe/model/types/model.d.ts +19 -12
  121. package/fe/packages/ui/react/components/Card/Card.d.ts +10 -0
  122. package/fe/packages/ui/react/components/Card/Card.js +8 -0
  123. package/fe/packages/ui/react/components/Card/index.d.ts +2 -0
  124. package/fe/packages/ui/react/components/Card/index.js +1 -0
  125. package/fe/packages/ui/react/components/DataTable/index.js +7 -3
  126. package/fe/packages/ui/react/components/ImagePreview/ImagePreview.js +3 -3
  127. package/fe/packages/ui/react/components/Layout/Layout.d.ts +11 -0
  128. package/fe/packages/ui/react/components/Layout/Layout.js +8 -0
  129. package/fe/packages/ui/react/components/Layout/index.d.ts +2 -0
  130. package/fe/packages/ui/react/components/Layout/index.js +1 -0
  131. package/fe/packages/ui/react/components/Loading/Loading.d.ts +9 -0
  132. package/fe/packages/ui/react/components/Loading/Loading.js +13 -0
  133. package/fe/packages/ui/react/components/Loading/index.d.ts +2 -0
  134. package/fe/packages/ui/react/components/Loading/index.js +1 -0
  135. package/fe/packages/ui/react/components/Menu/Menu.js +3 -2
  136. package/fe/packages/ui/react/components/Notification/Notification.d.ts +14 -0
  137. package/fe/packages/ui/react/components/Notification/Notification.js +29 -0
  138. package/fe/packages/ui/react/components/Notification/index.d.ts +2 -0
  139. package/fe/packages/ui/react/components/Notification/index.js +1 -0
  140. package/fe/packages/ui/react/components/Radio/Radio.d.ts +9 -0
  141. package/fe/packages/ui/react/components/Radio/Radio.js +20 -0
  142. package/fe/packages/ui/react/components/Radio/RadioGroup.d.ts +19 -0
  143. package/fe/packages/ui/react/components/Radio/RadioGroup.js +21 -0
  144. package/fe/packages/ui/react/components/Radio/index.d.ts +3 -0
  145. package/fe/packages/ui/react/components/Radio/index.js +2 -0
  146. package/fe/packages/ui/react/components/Search/Search.d.ts +1 -1
  147. package/fe/packages/ui/react/components/Search/Search.js +1 -5
  148. package/fe/packages/ui/react/components/Tabs/Tabs.d.ts +16 -0
  149. package/fe/packages/ui/react/components/Tabs/Tabs.js +19 -0
  150. package/fe/packages/ui/react/components/Tabs/index.d.ts +2 -0
  151. package/fe/packages/ui/react/components/Tabs/index.js +1 -0
  152. package/fe/packages/ui/react/components/hooks/useInputController.js +0 -1
  153. package/fe/packages/ui/react/components/index.d.ts +6 -0
  154. package/fe/packages/ui/react/components/index.js +6 -0
  155. package/fe/packages/ui/react/components/table/table.d.ts +3 -0
  156. package/fe/packages/ui/react/components/table/table.js +6 -6
  157. package/fe/packages/ui/react/components/testPage/index.js +54 -11
  158. package/fe/packages/ui/react/index.css +4 -0
  159. package/model/index.d.ts +1 -1
  160. package/model/types/data/button.d.ts +2 -2
  161. package/model/types/index.d.ts +1 -1
  162. package/model/types/model.d.ts +19 -12
  163. package/package.json +15 -16
  164. package/types/app/typings.d.ts +1 -1
  165. package/types/config/config.default.d.ts +3 -2
  166. package/types/index.d.ts +1 -1
  167. package/types/packages/core/index.d.ts +3 -3
  168. package/types/packages/core/loader/extend.d.ts +1 -1
  169. package/types/packages/core/paths.d.ts +4 -7
  170. package/types/packages/core/types.d.ts +31 -6
  171. package/cjs/app/data/signKey.js +0 -1
  172. package/esm/app/data/signKey.js +0 -8
  173. package/fe/frontend/apps/testPage/index.js +0 -6
  174. package/fe/frontend/apps/testPage/testPage.entry.d.ts +0 -2
  175. package/types/app/data/signKey.d.ts +0 -1
  176. /package/fe/frontend/apps/{testPage → ui-components}/index.d.ts +0 -0
  177. /package/fe/frontend/apps/{testPage/testPage.entry.js → ui-components/ui-components.entry.js} +0 -0
package/README.md CHANGED
@@ -14,6 +14,21 @@ pnpm add @_tc/template-core
14
14
  - pnpm >= 8
15
15
  - 使用内置前端时,需要安装 React、Vite 等 peer dependencies
16
16
 
17
+ ## 可选:AI Agent Skill
18
+
19
+ 包内附带 `tc-generator` skill,本质是一份可复用的 Agent 指令包,用来按 TemplateCore 约定生成业务项目、model 配置、Schema CRUD、controller 和 router。
20
+
21
+ 如果你的 Agent 支持本地 skills 目录,可以从已安装的 npm 包复制安装。以 Codex 为例:
22
+
23
+ ```bash
24
+ mkdir -p "${CODEX_HOME:-$HOME/.codex}/skills"
25
+ cp -R node_modules/@_tc/template-core/.skills/tc-generator "${CODEX_HOME:-$HOME/.codex}/skills/tc-generator"
26
+ ```
27
+
28
+ 安装后重启对应 Agent,让新 skill 生效。使用时可以直接说“用 tc-generator 生成一个商品管理模块”。
29
+
30
+ 其他 Agent 如果不支持自动安装 skill,也可以直接读取 `.skills/tc-generator/SKILL.md`,再按需读取 `.skills/tc-generator/reference/` 下的参考文件。
31
+
17
32
  ## 快速使用
18
33
 
19
34
  项目建议结构:
@@ -49,13 +64,21 @@ import { join } from 'path'
49
64
  import { serverStart } from '@_tc/template-core'
50
65
  import { buildFE } from '@_tc/template-core/bundler'
51
66
 
52
- serverStart({
53
- name: 'my-admin',
54
- baseDir: join(__dirname, '.'),
55
- pageBasePage: '/',
56
- })
67
+ async function main() {
68
+ await serverStart({
69
+ name: 'my-admin',
70
+ baseDir: join(__dirname, '.'),
71
+ pageBasePage: '/',
72
+ additionalPublicPaths: join(__dirname, 'dist/public'),
73
+ })
57
74
 
58
- buildFE('dev')
75
+ await buildFE('dev')
76
+ }
77
+
78
+ main().catch((error) => {
79
+ console.error(error)
80
+ process.exit(1)
81
+ })
59
82
  ```
60
83
 
61
84
  只用后端能力时,可以不调用 `buildFE('dev')`。
@@ -69,8 +92,11 @@ buildFE('dev')
69
92
  | `pageBasePage` | `string` | 否 | `'/'` | 页面访问前缀,所有前端页面路由的基础路径 |
70
93
  | `homePage` | `string` | 否 | - | 应用首页路径 |
71
94
  | `frameBaseDir` | `string` | 否 | - | 框架根目录,通常不需要手动设置 |
95
+ | `additionalPublicPaths` | `string | string[]` | 否 | - | 追加静态资源目录,必须传绝对路径 |
96
+
97
+ 框架会自动读取 `config/config.default.ts` 中的配置(如 `port`、`env` 等)。
72
98
 
73
- 框架会自动读取 `config/config.default.ts` 中的配置(如 `port`、`host`、`env` 等)。
99
+ 静态资源挂载顺序为:框架 `app/public`、业务 `app/public`、`additionalPublicPaths`。当 `buildFE` 输出到自定义目录时,可以用 `additionalPublicPaths` 把该目录交给 Koa 提供访问。
74
100
 
75
101
  ### buildFE 参数说明
76
102
 
@@ -108,7 +134,6 @@ buildFE('prod', {
108
134
  // config/config.default.ts
109
135
  export default {
110
136
  port: 9000,
111
- host: '0.0.0.0',
112
137
  }
113
138
  ```
114
139
 
@@ -195,7 +220,7 @@ VS Code 建议安装官方 Tailwind CSS IntelliSense 插件,并在工作区 `.
195
220
  - `GET /api/project/list`
196
221
  - `GET /api/project/:key`
197
222
  - React Dashboard:内置 `/dash` 页面入口。
198
- - 组件预览页面:内置 `/testPage` 页面,用于查看和测试框架内置的 UI 组件。
223
+ - 组件预览页面:内置 `/ui-components` 页面,用于查看和测试框架内置的 UI 组件。
199
224
  - 菜单渲染:支持 `schema`、`custom`、`iframe`、`sidebar`。
200
225
  - Schema CRUD:根据 `model` 中的 `schemaConfig` 生成搜索、表格、新增、编辑、详情。
201
226
  - 内置 UI 组件:提供丰富的 React 组件库,详见下方"内置 UI 组件"章节。
@@ -251,6 +276,119 @@ import type {
251
276
 
252
277
  `modeStore` 管项目模型和当前项目数据,`schemaStore` 管当前 Schema 页面的 schema/cache,`schemaEventBus` 用来在 Search、Table、CallCom 之间通信。
253
278
 
279
+ ### 前端多语言
280
+
281
+ TemplateCore 前端复用 `@tc/ui-react/i18n`。框架内置中文、英文资源,业务项目可以继续追加自己的资源。
282
+
283
+ **追加业务语言资源**:
284
+
285
+ ```ts
286
+ import { i18nStore } from '@tc/ui-react/i18n'
287
+
288
+ i18nStore.getState().addResources('zh-CN', {
289
+ business: {
290
+ product: {
291
+ menu: '商品管理',
292
+ name: '商品名称',
293
+ create: '新增商品',
294
+ createTitle: '新增商品',
295
+ },
296
+ },
297
+ })
298
+
299
+ i18nStore.getState().addResources('en-US', {
300
+ business: {
301
+ product: {
302
+ menu: 'Products',
303
+ name: 'Product name',
304
+ create: 'Create product',
305
+ createTitle: 'Create product',
306
+ },
307
+ },
308
+ })
309
+ ```
310
+
311
+ 资源注册时不写 `$i18n::` 前缀,配置中使用时才写:
312
+
313
+ ```ts
314
+ const title = '$i18n::business.product.createTitle'
315
+ ```
316
+
317
+ **在 model / Schema 配置中使用**:
318
+
319
+ ```ts
320
+ {
321
+ name: '$i18n::business.product.menu',
322
+ moduleType: 'schema',
323
+ schemaConfig: {
324
+ schema: {
325
+ type: 'object',
326
+ properties: {
327
+ name: {
328
+ type: 'string',
329
+ label: '$i18n::business.product.name',
330
+ minLength: 2,
331
+ createFormOption: {
332
+ comType: 'input',
333
+ },
334
+ tableOption: {},
335
+ searchOption: {},
336
+ },
337
+ },
338
+ required: ['name'],
339
+ },
340
+ tableConfig: {
341
+ headerButtons: [
342
+ {
343
+ label: '$i18n::business.product.create',
344
+ eventKey: 'callComponent',
345
+ eventOption: { comName: 'createForm' },
346
+ },
347
+ ],
348
+ },
349
+ componentConfig: {
350
+ createForm: {
351
+ title: '$i18n::business.product.createTitle',
352
+ saveBtnText: '$i18n::common.submit',
353
+ },
354
+ },
355
+ },
356
+ }
357
+ ```
358
+
359
+ 已支持 `$i18n::...` 的常用位置:
360
+
361
+ - 菜单名:`menu.name`
362
+ - 项目标题:`projectInfo.desc` 或回退的 `projectInfo.name`
363
+ - Schema 字段名:`schema.properties.*.label`
364
+ - 表格按钮和行按钮:`headerButtons.*.label`、`rowButtons.*.label`
365
+ - 弹窗、抽屉标题:`componentConfig.*.title`
366
+ - 表单保存按钮:`componentConfig.*.saveBtnText`
367
+ - 接口错误提示:`BaseResponse.message`
368
+
369
+ **切换语言**:
370
+
371
+ ```ts
372
+ import { i18nStore } from '@tc/ui-react/i18n'
373
+
374
+ i18nStore.getState().setLanguage('en-US')
375
+ i18nStore.getState().setLanguage('zh-CN')
376
+ ```
377
+
378
+ 默认会写入 localStorage,key 是 `tc_language`。刷新页面后会继续使用上次语言。
379
+
380
+ **AJV 校验文案**:
381
+
382
+ Schema 表单校验会把 AJV keyword 映射到内置语言 key,覆盖 `required`、`type`、`format`、`minimum`、`maximum`、`minLength`、`maxLength`、`pattern`、`enum`、`oneOf`、`anyOf` 等常见规则。
383
+
384
+ 非必填字段为空时会跳过 AJV 校验,空值包括 `undefined`、`null`、空字符串、空数组和空对象。
385
+
386
+ 如果需要扩展更多 AJV 文案,在源码项目中同步增加:
387
+
388
+ 1. `frontend/src/defaultPages/SchemaPage/utils/validator.ts` 的 `formatError()` 映射。
389
+ 2. `frontend/src/language/zh-CN.ts` 和 `frontend/src/language/en-US.ts` 文案。
390
+ 3. `frontend/src/language/index.ts` 的 `frontendLangKeys`。
391
+
254
392
  ### 前端请求封装详解
255
393
 
256
394
  框架内置的请求封装基于 `@tc/common/http`,底层使用原生 `fetch` API,实现了类似 Axios 的接口和拦截器机制,提供了签名、鉴权、错误处理等能力。
@@ -259,6 +397,7 @@ import type {
259
397
  - `BASE_URL`:固定为 `/api`
260
398
  - `timeout`:15000ms(15秒)
261
399
  - `credentials`:`'include'`,支持跨域携带 cookie
400
+ - `window._signKey`:由服务端页面模板从 `app.config.signKey` 注入
262
401
 
263
402
  **请求拦截器**:
264
403
 
@@ -274,7 +413,7 @@ import type {
274
413
  ```
275
414
 
276
415
  **签名机制**:
277
- - 签名密钥:`sakjdfnkjwjfnfkjkjldljksndf`(前后端需保持一致)
416
+ - 签名密钥:服务端从 `app.config.signKey` 读取,并在页面渲染时注入为 `window._signKey`
278
417
  - 签名算法:`md5(签名密钥_${时间戳})`
279
418
  - 服务端会在非 local 环境下校验签名和时间戳
280
419
 
@@ -282,8 +421,8 @@ import type {
282
421
 
283
422
  - **401 处理**:自动清空 token 并跳转到 `/login`
284
423
  - **错误提取**:自动从响应中提取 `message`、`msg` 或 `errors` 字段
285
- - **超时处理**:请求超时会返回 "Request timed out"
286
- - **网络错误**:网络异常会返回 "Network error"
424
+ - **超时处理**:请求超时会返回当前语言的超时提示
425
+ - **网络错误**:网络异常会返回当前语言的网络错误提示
287
426
 
288
427
  **使用示例**:
289
428
 
@@ -351,9 +490,17 @@ try {
351
490
  | --- | --- | --- |
352
491
  | `Button` | 按钮组件,支持多种样式和尺寸 | `@_tc/template-core/fe/rc` |
353
492
  | `Input` | 输入框组件 | `@_tc/template-core/fe/rc` |
493
+ | `InputNumber` | 数字输入框组件 | `@_tc/template-core/fe/rc` |
494
+ | `Textarea` | 多行文本输入框组件 | `@_tc/template-core/fe/rc` |
354
495
  | `Select` | 下拉选择组件,支持单选和多选 | `@_tc/template-core/fe/rc` |
496
+ | `Search` | 搜索输入组件 | `@_tc/template-core/fe/rc` |
497
+ | `TreeSelect` | 树形选择组件 | `@_tc/template-core/fe/rc` |
498
+ | `Dropdown` | 下拉菜单组件 | `@_tc/template-core/fe/rc` |
355
499
  | `DatePicker` | 日期选择器 | `@_tc/template-core/fe/rc` |
356
500
  | `Upload` | 文件上传组件 | `@_tc/template-core/fe/rc` |
501
+ | `FileUpload` | 通用文件上传组件 | `@_tc/template-core/fe/rc` |
502
+ | `ImageUpload` | 图片上传组件 | `@_tc/template-core/fe/rc` |
503
+ | `ImagePreview` | 图片预览组件 | `@_tc/template-core/fe/rc` |
357
504
  | `Checkbox` | 复选框组件 | `@_tc/template-core/fe/rc` |
358
505
  | `Radio` | 单选框组件 | `@_tc/template-core/fe/rc` |
359
506
  | `Switch` | 开关组件 | `@_tc/template-core/fe/rc` |
@@ -371,8 +518,13 @@ try {
371
518
  | 组件 | 用途 | 导入路径 |
372
519
  | --- | --- | --- |
373
520
  | `DataTable` | 数据表格组件,支持分页、排序、筛选 | `@_tc/template-core/fe/rc` |
521
+ | `Table` | 表格组件(含表头、列配置等子组件) | `@_tc/template-core/fe/rc` |
374
522
  | `TableSearch` | 表格搜索组件,配合 DataTable 使用 | `@_tc/template-core/fe/rc` |
375
523
  | `Pagination` | 分页组件 | `@_tc/template-core/fe/rc` |
524
+ | `Breadcrumb` | 面包屑导航组件 | `@_tc/template-core/fe/rc` |
525
+ | `Calendar` | 日历组件 | `@_tc/template-core/fe/rc` |
526
+ | `TimePicker` | 时间选择器组件 | `@_tc/template-core/fe/rc` |
527
+ | `Skeleton` | 骨架屏加载占位组件 | `@_tc/template-core/fe/rc` |
376
528
 
377
529
  ### 反馈组件
378
530
 
@@ -382,6 +534,10 @@ try {
382
534
  | `Drawer` | 抽屉组件 | `@_tc/template-core/fe/rc` |
383
535
  | `Message` | 消息提示组件 | `@_tc/template-core/fe/rc` |
384
536
  | `Notification` | 通知组件 | `@_tc/template-core/fe/rc` |
537
+ | `ConfirmDialog` | 确认对话框组件 | `@_tc/template-core/fe/rc` |
538
+ | `Popup` | 弹出层组件 | `@_tc/template-core/fe/rc` |
539
+ | `Tooltip` | 文字提示组件 | `@_tc/template-core/fe/rc` |
540
+ | `Overlay` | 页面遮罩层组件 | `@_tc/template-core/fe/rc` |
385
541
  | `Loading` | 加载状态组件 | `@_tc/template-core/fe/rc` |
386
542
 
387
543
  ### 布局组件
@@ -391,6 +547,17 @@ try {
391
547
  | `Layout` | 页面布局组件 | `@_tc/template-core/fe/rc` |
392
548
  | `Card` | 卡片容器组件 | `@_tc/template-core/fe/rc` |
393
549
  | `Tabs` | 标签页组件 | `@_tc/template-core/fe/rc` |
550
+ | `Menu` | 菜单组件(含 MenuItem 等子组件) | `@_tc/template-core/fe/rc` |
551
+ | `Label` | 标签组件 | `@_tc/template-core/fe/rc` |
552
+
553
+ ### 按钮组件
554
+
555
+ | 组件 | 用途 | 导入路径 |
556
+ | --- | --- | --- |
557
+ | `Button` | 通用按钮组件 | `@_tc/template-core/fe/rc` |
558
+ | `AsynchronousButton` | 异步按钮组件,支持加载状态 | `@_tc/template-core/fe/rc` |
559
+ | `SubmitButton` | 表单提交按钮组件 | `@_tc/template-core/fe/rc` |
560
+ | `ActionBtn` | 操作按钮组件 | `@_tc/template-core/fe/rc` |
394
561
 
395
562
  ### 使用示例
396
563
 
@@ -420,7 +587,7 @@ function MyComponent() {
420
587
  **注意**:
421
588
  - 所有组件都支持 TypeScript 类型提示
422
589
  - 组件样式基于 Tailwind CSS V4
423
- - 详细的组件 API 和示例可以访问 `/testPage` 页面查看
590
+ - 详细的组件 API 和示例可以访问 `/ui-components` 页面查看
424
591
 
425
592
  ## 后端约定
426
593
 
@@ -494,7 +661,7 @@ const model: ModelDataType = {
494
661
  name: '商品后台',
495
662
  desc: '商品管理',
496
663
  icon: '',
497
- homePage: '/dash?projk=demo',
664
+ homePage: '/_sidebar_/product?projk=demo',
498
665
  menuLayout: 'left',
499
666
  menu: [
500
667
  {
@@ -577,7 +744,7 @@ const model: ModelDataType = {
577
744
  eventKey: 'remove',
578
745
  eventOption: {
579
746
  params: {
580
- product_id: 'schema::product_id',
747
+ product_id: '$schema::product_id',
581
748
  },
582
749
  },
583
750
  },
@@ -591,13 +758,15 @@ const model: ModelDataType = {
591
758
  export default model
592
759
  ```
593
760
 
761
+ `name`、`desc`、`icon`、`homePage` 都是可选项。Dashboard 页头标题优先使用 `desc`,没有时回退到 `name`;`icon` 可以是图片地址、图片路径、data image 或普通文本。未配置 `homePage` 时会自动跳到第一个可用菜单;配置时必须命中菜单生成的真实路由,左侧布局通常是 `/_sidebar_/{menuKey}`,顶部布局通常是 `/{menuKey}`。
762
+
594
763
  `project/demo.ts` 定义项目覆盖:
595
764
 
596
765
  ```ts
597
766
  export default {
598
767
  name: 'Demo 企业',
599
768
  desc: 'Demo 企业商品后台',
600
- homePage: '/dash?projk=demo',
769
+ homePage: '/_sidebar_/product?projk=demo',
601
770
  }
602
771
  ```
603
772
 
@@ -747,7 +916,7 @@ PUT {api} -> 编辑
747
916
  DELETE {api} -> 删除
748
917
  ```
749
918
 
750
- `schema::字段名` 表示从当前表格行读取字段值,常用于删除按钮参数。
919
+ `$schema::字段名` 表示从当前表格行读取字段值,常用于删除按钮参数。
751
920
 
752
921
  ## 如何扩展组件
753
922
 
@@ -948,6 +1117,59 @@ declare module '@_tc/template-core/fe/rc' {
948
1117
  - `PropsMap` 用来绑定该字段的 props 类型。
949
1118
  - 类型声明只负责 TS 校验,运行时还必须在 `frontend/extended/SchemaForm/data.ts` 注册组件。
950
1119
 
1120
+ ### Model mode 类型扩展
1121
+
1122
+ `mode` 和对应的数据结构一起扩展。内置 `MB` 对应管理后台菜单结构 `MBMenuType`。
1123
+
1124
+ ```ts
1125
+ // typing/template-core.d.ts
1126
+ import '@_tc/template-core/model'
1127
+
1128
+ declare module '@_tc/template-core/model' {
1129
+ interface ModelModeMap {
1130
+ portal: {
1131
+ portalConfig: {
1132
+ title: string
1133
+ theme?: 'light' | 'dark'
1134
+ }
1135
+ }
1136
+ }
1137
+ }
1138
+ ```
1139
+
1140
+ 使用新 `mode`:
1141
+
1142
+ ```ts
1143
+ import type { ModelDataType } from '@_tc/template-core/model'
1144
+
1145
+ const model: ModelDataType<'portal'> = {
1146
+ mode: 'portal',
1147
+ name: '门户',
1148
+ desc: '门户配置',
1149
+ homePage: '/',
1150
+ portalConfig: {
1151
+ title: 'Portal',
1152
+ theme: 'light',
1153
+ },
1154
+ }
1155
+
1156
+ export default model
1157
+ ```
1158
+
1159
+ 继续使用内置管理后台时:
1160
+
1161
+ ```ts
1162
+ import type { ModelDataType } from '@_tc/template-core/model'
1163
+
1164
+ const model: ModelDataType<'MB'> = {
1165
+ mode: 'MB',
1166
+ name: '商品后台',
1167
+ desc: '商品管理',
1168
+ homePage: '/_sidebar_/product?projk=demo',
1169
+ menu: [],
1170
+ }
1171
+ ```
1172
+
951
1173
  ### CallCom 类型扩展
952
1174
 
953
1175
  扩展目标:
@@ -1 +1 @@
1
- var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(e&&(t=e(e=0)),t),s=(e,n)=>{let r={};for(var i in e)t(r,i,{get:e[i],enumerable:!0});return n||t(r,Symbol.toStringTag,{value:`Module`}),r},c=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},l=(n,r,a)=>(a=n==null?{}:e(i(n)),c(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n)),u=e=>a.call(e,`module.exports`)?e[`module.exports`]:c(t({},`__esModule`,{value:!0}),e);exports.__esmMin=o,exports.__exportAll=s,exports.__toCommonJS=u,exports.__toESM=l;
1
+ var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));exports.__toESM=s;
@@ -1 +1 @@
1
- require(`../../_virtual/_rolldown/runtime.js`);var e=(e=>class{app;config;constructor(){this.app=e,this.config=e.config}get service(){return e.service}success(e,t){this.sendData(e,t)}fail(e,t,n){this.sendData(e,null,t,n)}sendData(e,t=null,n=0,r=null,i=200){e.status=i,e.body={data:t,code:n,message:r??`ok`}}});module.exports=e;
1
+ var e=(e=>class{app;config;constructor(){this.app=e,this.config=e.config}get service(){return e.service}success(e,t){this.sendData(e,t)}fail(e,t,n){this.sendData(e,null,t,n)}sendData(e,t=null,n=0,r=null,i=200){e.status=i,e.body={data:t,code:n,message:r??`ok`}}});module.exports=e;
@@ -1 +1 @@
1
- require(`../../_virtual/_rolldown/runtime.js`);const e=require(`./base.js`);var t=(t=>{let n=e(t);return class extends n{getModelList=async e=>{let t=(await this.service.project.getModelList()).reduce((e,t)=>{let{model:n,project:r}=t,{key:i,name:a,desc:o}=n,s={key:i,name:a,desc:o},c=Object.keys(r).reduce((e,t)=>{let{key:n,name:i,desc:a,homePage:o}=r[t];return e[t]={key:n,name:i,desc:a,homePage:o},e},{});return e.push({model:s,project:c}),e},[]);this.success(e,t)};getProjectList=async e=>{let{projk:t}=e.query,n=(await this.service.project.getList(t))?.map(e=>{let{modelKey:t,key:n,name:r,desc:i,homePage:a}=e;return{modelKey:t,key:n,name:r,desc:i,homePage:a}});this.success(e,n)};getProject=async e=>{let{key:t}=e.params,n=this.service.project.getProject(t);if(!n){this.fail(e,10001,`获取项目异常`);return}this.success(e,n)}}});module.exports=t;
1
+ const e=require(`./base.js`);var t=(t=>{let n=e(t);return class extends n{getModelList=async e=>{let t=(await this.service.project.getModelList()).reduce((e,t)=>{let{model:n,project:r}=t,{key:i,name:a,desc:o}=n,s={key:i,name:a,desc:o},c=Object.keys(r).reduce((e,t)=>{let{key:n,name:i,desc:a,homePage:o}=r[t];return e[t]={key:n,name:i,desc:a,homePage:o},e},{});return e.push({model:s,project:c}),e},[]);this.success(e,t)};getProjectList=async e=>{let{projk:t}=e.query,n=(await this.service.project.getList(t))?.map(e=>{let{modelKey:t,key:n,name:r,desc:i,homePage:a}=e;return{modelKey:t,key:n,name:r,desc:i,homePage:a}});this.success(e,n)};getProject=async e=>{let{key:t}=e.params,n=this.service.project.getProject(t);if(!n){this.fail(e,10001,`获取项目异常`);return}this.success(e,n)}}});module.exports=t;
@@ -1 +1 @@
1
- require(`../../_virtual/_rolldown/runtime.js`);var e=(e=>class{async renderPage(t){e.extends.logger.log(` - render page: `+t.params.page);try{e.extends.renderView(`dist/${t.params.page}.entry.tpl`,t,{projKey:t.query.projk,name:e.options?.name,env:e.envs.get(),basePath:`${e.options.pageBasePage}${t.params.page}`,options:JSON.stringify(e.options)})}catch{e.extends.generateErrorMessage(`template not found`,{status:404,showError:!0,code:0})}}});module.exports=e;
1
+ var e=e=>JSON.stringify(e).replace(/</g,`\\u003c`).replace(/>/g,`\\u003e`).replace(/&/g,`\\u0026`).replace(/\u2028/g,`\\u2028`).replace(/\u2029/g,`\\u2029`),t=(t=>class{async renderPage(n){t.extends.logger.log(` - render page: `+n.params.page);try{t.extends.renderView(`dist/${n.params.page}.entry.tpl`,n,{projKey:n.query.projk,name:t.options?.name,env:t.envs.get(),basePath:e(`${t.options.pageBasePage}${n.params.page}`),projKeyJson:e(String(n.query.projk??``)),signKey:e(t.config.signKey),options:e(t.options)})}catch{t.extends.generateErrorMessage(`template not found`,{status:404,showError:!0,code:0})}}});module.exports=t;
@@ -1 +1 @@
1
- require(`../../_virtual/_rolldown/runtime.js`);const e=require(`../../packages/common/http/index.js`);var t=t=>{let n=new e.FetchAxios({timeout:15e3,validateStatus:e=>e>=200&&e<300});return n.create=(t={})=>new e.FetchAxios({timeout:15e3,validateStatus:e=>e>=200&&e<300,...t}),n};module.exports=t;
1
+ const e=require(`../../packages/common/http/index.js`);var t=t=>{let n=new e.FetchAxios({timeout:15e3,validateStatus:e=>e>=200&&e<300});return n.create=(t={})=>new e.FetchAxios({timeout:15e3,validateStatus:e=>e>=200&&e<300,...t}),n};module.exports=t;
@@ -1 +1 @@
1
- require(`../../_virtual/_rolldown/runtime.js`);async function e(e){return console.log(e),{}}module.exports=e;
1
+ async function e(e){return console.log(e),{}}module.exports=e;
@@ -1 +1 @@
1
- require(`../../_virtual/_rolldown/runtime.js`);var e=()=>(e,t)=>{let n=Error(e);throw n.status=t?.status,n.code=t?.code,n.returnError=t?.showError,n};module.exports=e;
1
+ var e=()=>(e,t)=>{let n=Error(e);throw n.status=t?.status,n.code=t?.code,n.returnError=t?.showError,n};module.exports=e;
@@ -1 +1 @@
1
- require(`../../_virtual/_rolldown/runtime.js`);var e=async e=>{let t=console;if(e.envs.get()!==`local`){let n=await import(`log4js`);n.configure({appenders:{console:{type:`console`},dateFile:{type:`dateFile`,filename:`./log/application.log`,pattern:`.yyyy-MM-dd`}},categories:{default:{appenders:[`console`,`dateFile`],level:`trace`}}});let r=n.getLogger();(e.options.overwriteOriginalLogs??process.env.overwriteOriginalLogs!==`false`)&&(console.log=r.info.bind(r),console.info=r.info.bind(r),console.warn=r.warn.bind(r),console.error=r.error.bind(r),console.debug=r.debug.bind(r),console.trace=r.trace.bind(r)),t=r}return t};module.exports=e;
1
+ var e=async e=>{let t=console;if(e.envs.get()!==`local`){let n=await import(`log4js`);n.configure({appenders:{console:{type:`console`},dateFile:{type:`dateFile`,filename:`./log/application.log`,pattern:`.yyyy-MM-dd`}},categories:{default:{appenders:[`console`,`dateFile`],level:`trace`}}});let r=n.getLogger();(e.options.overwriteOriginalLogs??process.env.overwriteOriginalLogs!==`false`)&&(console.log=r.info.bind(r),console.info=r.info.bind(r),console.warn=r.warn.bind(r),console.error=r.error.bind(r),console.debug=r.debug.bind(r),console.trace=r.trace.bind(r)),t=r}return t};module.exports=e;
@@ -1 +1 @@
1
- require(`../../_virtual/_rolldown/runtime.js`);var e=()=>(e,t)=>{let n=e.split(`/`),r=t.split(`/`);if(n.length!==r.length)return null;let i={};return n.forEach((e,t)=>{if(e.indexOf(`:`)>=0){let n=e.slice(1);i[n]=t}}),Object.entries(i).reduce((e,[t,n])=>(e[t]=r[n]??``,e),{})};module.exports=e;
1
+ var e=()=>(e,t)=>{let n=e.split(`/`),r=t.split(`/`);if(n.length!==r.length)return null;let i={};return n.forEach((e,t)=>{if(e.indexOf(`:`)>=0){let n=e.slice(1);i[n]=t}}),Object.entries(i).reduce((e,[t,n])=>(e[t]=r[n]??``,e),{})};module.exports=e;
@@ -1 +1 @@
1
- const e=require(`../../_virtual/_rolldown/runtime.js`),t=require(`../data/signKey.js`);let n=require(`md5`);n=e.__toESM(n);var r=1e3*60*10,i=i=>async(a,o)=>{let{path:s,method:c}=a;if(s.includes(`api`)&&!i.config?.apiSignVerify?.whiteList?.includes(s)){i.extends.logger?.info(`--[api-sign-verify]--`);let{s_sign:o,s_t:l}=a.request.header,{signKey:u}=(t.init_signKey(),e.__toCommonJS(t.signKey_exports)),d=(0,n.default)(`${u}_${l}`);i.extends.logger?.info(`[${c} ${s}] signature: ${d}`),(!l||!o||o.toLowerCase()!==d||Date.now()-Number(l)>r)&&i.extends.generateErrorMessage(`signature not correct or api timeout`,{showError:!0,code:100014})}await o()};module.exports=i;
1
+ const e=require(`../../_virtual/_rolldown/runtime.js`);let t=require(`md5`);t=e.__toESM(t);var n=1e3*60*10,r=e=>async(r,i)=>{let{path:a,method:o}=r;if(a.includes(`api`)&&!e.config?.apiSignVerify?.whiteList?.includes(a)){e.extends.logger?.info(`--[api-sign-verify]--`);let{s_sign:i,s_t:s}=r.request.header,{signKey:c}=e.config,l=(0,t.default)(`${c}_${s}`);e.extends.logger?.info(`[${o} ${a}] signature: ${l}`),(!s||!i||i.toLowerCase()!==l||Date.now()-Number(s)>n)&&e.extends.generateErrorMessage(`signature not correct or api timeout`,{showError:!0,code:100014})}await i()};module.exports=r;
@@ -1 +1 @@
1
- require(`../../_virtual/_rolldown/runtime.js`);var e={},t=t=>async(n,r)=>{try{await r()}catch(r){let{status:i=200,message:a,detail:o,code:s=5e4,returnError:c}=r;if(t.extends.logger?.info(`error info -> ${JSON.stringify(r)}`),t.extends.logger?.error(`-- [excption] --`,r),t.extends.logger?.error(`-- [excption] info --`,i,a,o),a?.includes(`template not found`)){let r=n.req.url;if(e[r]===void 0?e[r]=0:e[r]+=1,e[r]<t.config.notFoundRedirectCount){n.status=302,n.redirect(t.options?.homePage??`/`);return}else e[r]=0}c?(n.status=i,n.body={code:s,message:a}):(n.status=200,n.body={code:5e4,message:`网络错误`})}};module.exports=t;
1
+ var e={},t=t=>async(n,r)=>{try{await r()}catch(r){let{status:i=200,message:a,detail:o,code:s=5e4,returnError:c}=r;if(t.extends.logger?.info(`error info -> ${JSON.stringify(r)}`),t.extends.logger?.error(`-- [excption] --`,r),t.extends.logger?.error(`-- [excption] info --`,i,a,o),a?.includes(`template not found`)){let r=n.req.url;if(e[r]===void 0?e[r]=0:e[r]+=1,e[r]<t.config.notFoundRedirectCount){n.status=302,n.redirect(t.options?.homePage??`/`);return}else e[r]=0}c?(n.status=i,n.body={code:s,message:a}):(n.status=200,n.body={code:5e4,message:`网络错误`})}};module.exports=t;
@@ -1 +1 @@
1
- require(`../../_virtual/_rolldown/runtime.js`);var e=()=>async(e,t)=>{let n=e.headers.projk,{path:r}=e;if(r.indexOf(`/api/proj/`)!==-1&&(!n||[`undefined`,`null`].includes(n))){e.status=200,e.body={code:110,data:null,message:`请求不合法`};return}e.extInfo={key:n},await t()};module.exports=e;
1
+ var e=()=>async(e,t)=>{let n=e.headers.projk,{path:r}=e;if(r.indexOf(`/api/proj/`)!==-1&&(!n||[`undefined`,`null`].includes(n))){e.status=200,e.body={code:110,data:null,message:`请求不合法`};return}e.extInfo={key:n},await t()};module.exports=e;
@@ -1 +1 @@
1
- const e=require(`../_virtual/_rolldown/runtime.js`);let t=require(`path`),n=require(`koa-compress`);n=e.__toESM(n);let r=require(`koa-static`);r=e.__toESM(r);let i=require(`koa-bodyparser`);i=e.__toESM(i);var a=(0,i.default)({formLimit:`1000mb`,enableTypes:[`form`,`json`,`text`]}),o=e=>{let i={...e.envs.isLocal()?{maxage:60*1e3}:{maxage:365*24*60*60*1e3}},o=(0,t.resolve)(e.baseDir,`./app/public`),s=(0,t.resolve)(e.frameBaseDir,`./app/public`);e.use(e.middlewares.errorHandle),e.use((0,n.default)({threshold:2048})),e.use((0,r.default)(s,i)),e.use((0,r.default)(o,i)),e.use(a),e.use(e.middlewares.projectHandler),!e.envs.isLocal()&&e.use(e.middlewares.apiSignVerify),e.use(e.middlewares.apiParamsVerify)};module.exports=o;
1
+ const e=require(`../_virtual/_rolldown/runtime.js`);let t=require(`path`),n=require(`koa-compress`);n=e.__toESM(n);let r=require(`koa-bodyparser`);r=e.__toESM(r);let i=require(`koa-static`);i=e.__toESM(i);var a=(0,r.default)({formLimit:`1000mb`,enableTypes:[`form`,`json`,`text`]}),o=e=>{let r={...e.envs.isLocal()?{maxage:60*1e3}:{maxage:365*24*60*60*1e3}},o=(0,t.resolve)(e.baseDir,`./app/public`),s=(0,t.resolve)(e.frameBaseDir,`./app/public`),c=e.options.additionalPublicPaths??[];c=Array.isArray(c)?c:[c],e.use(e.middlewares.errorHandle),e.use((0,n.default)({threshold:2048})),e.use((0,i.default)(s,r)),e.use((0,i.default)(o,r)),c.forEach(t=>e.use((0,i.default)(t,r))),e.use(a),e.use(e.middlewares.projectHandler),!e.envs.isLocal()&&e.use(e.middlewares.apiSignVerify),e.use(e.middlewares.apiParamsVerify)};module.exports=o;
@@ -1 +1 @@
1
- require(`../../_virtual/_rolldown/runtime.js`);var e=(e,t)=>{let{project:n}=e.controller;t.get(`/api/project/model_list`,n.getModelList),t.get(`/api/project/list`,n.getProjectList),t.get(`/api/project/:key`,n.getProject)};module.exports=e;
1
+ var e=(e,t)=>{let{project:n}=e.controller;t.get(`/api/project/model_list`,n.getModelList),t.get(`/api/project/list`,n.getProjectList),t.get(`/api/project/:key`,n.getProject)};module.exports=e;
@@ -1 +1 @@
1
- require(`../../_virtual/_rolldown/runtime.js`);var e=(e,t)=>{let{pageBasePage:n}=e.options;t.level=2,t.get([`${n}:page`,`${n}:page/:r(.*)`],e.controller.view.renderPage.bind(e.controller.view))};module.exports=e;
1
+ var e=(e,t)=>{let{pageBasePage:n}=e.options;t.level=2,t.get([`${n}:page`,`${n}:page/:r(.*)`],e.controller.view.renderPage.bind(e.controller.view))};module.exports=e;
@@ -1 +1 @@
1
- require(`../../_virtual/_rolldown/runtime.js`);var e={"/api/project/:key":{get:{params:{type:`object`,properties:{key:{type:`string`}},required:[`key`]}}},"/api/project/list":{get:{query:{type:`object`,properties:{projk:{type:`string`}}}}},"/api/project/model_list":{get:{}}};module.exports=e;
1
+ var e={"/api/project/:key":{get:{params:{type:`object`,properties:{key:{type:`string`}},required:[`key`]}}},"/api/project/list":{get:{query:{type:`object`,properties:{projk:{type:`string`}}}}},"/api/project/model_list":{get:{}}};module.exports=e;
@@ -1 +1 @@
1
- require(`../../_virtual/_rolldown/runtime.js`);var e=(e=>class{get app(){return e}get config(){return e.config}get curl(){return e.extends.$fetch}});module.exports=e;
1
+ var e=(e=>class{get app(){return e}get config(){return e.config}get curl(){return e.extends.$fetch}});module.exports=e;
@@ -1 +1 @@
1
- require(`../../_virtual/_rolldown/runtime.js`);const e=require(`./base.js`),t=require(`../../packages/core/index.js`);var n=(n=>{let r=e(n),i=t.loaderModel(n);return class extends r{async getModelList(){return i}getList=e=>i.reduce((t,n)=>{let{project:r}=n;if(e&&!r[e])return t;for(let e in r){let n=r[e];n&&t.push(n)}return t},[]);getProject=e=>i.reduce((t,n)=>n.project[e]||t,null)}});module.exports=n;
1
+ const e=require(`./base.js`),t=require(`../../packages/core/index.js`);var n=(n=>{let r=e(n),i=t.loaderModel(n);return class extends r{async getModelList(){return i}getList=e=>i.reduce((t,n)=>{let{project:r}=n;if(e&&!r[e])return t;for(let e in r){let n=r[e];n&&t.push(n)}return t},[]);getProject=e=>i.reduce((t,n)=>n.project[e]||t,null)}});module.exports=n;
package/cjs/app/type.js CHANGED
@@ -1 +0,0 @@
1
- require(`../_virtual/_rolldown/runtime.js`);
@@ -1 +0,0 @@
1
- require(`../_virtual/_rolldown/runtime.js`);
@@ -1,30 +1,29 @@
1
1
  <!DOCTYPE html>
2
2
  <html lang="en" class="dark">
3
-
4
- <head>
5
- <meta charset="UTF-8">
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
- <link rel="icon" type="image/x-icon" href="/static/logo.png">
8
- <title>{{name}}</title>
9
- </head>
10
-
11
- <script id="input">
12
- window['_basePath'] = '{{basePath}}';
13
- window['_projKey'] = '{{projKey}}';
14
-
15
- const tmpDom = document.createElement('div')
16
-
17
- tmpDom.innerHTML = `{{options}}`;
18
-
19
- window['appOptions'] = JSON.parse(tmpDom.innerText || tmpDom.textContent);
20
- const s = document.getElementById('input');
21
- s.parentElement.removeChild(s)
22
- </script>
23
-
24
- <body>
25
- <div id="root"></div>
26
- </body>
27
-
28
- <!-- {{InsertScript}} -->
29
-
30
- </html>
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <link rel="icon" type="image/x-icon" href="/static/logo.png" />
7
+ <title>{{ name }}</title>
8
+ </head>
9
+
10
+ <script id="input">
11
+ window['_basePath'] = {{basePath | safe}}
12
+ window['_projKey'] = {{projKeyJson | safe}}
13
+ window['_signKey'] = {{signKey | safe}}
14
+ const s = document.getElementById('input')
15
+ s.parentElement.removeChild(s)
16
+ </script>
17
+ <script type="application/json" id="app-options-data">{{ options | safe }}</script>
18
+ <script>
19
+ const appOptionsScript = document.getElementById('app-options-data')
20
+ window['appOptions'] = JSON.parse(appOptionsScript.textContent || '{}')
21
+ appOptionsScript.parentElement.removeChild(appOptionsScript)
22
+ </script>
23
+
24
+ <body>
25
+ <div id="root"></div>
26
+ </body>
27
+
28
+ <!-- {{InsertScript}} -->
29
+ </html>
@@ -1 +1 @@
1
- require(`../_virtual/_rolldown/runtime.js`);var e={};module.exports=e;
1
+ var e={};module.exports=e;
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.js`);const e=require(`../packages/common/log/index.js`),t=require(`./utils.js`);var n=async()=>{let n=t.entries();e.logGreen(n),Object.keys(n).length||(e.logRed(`no entry found`),process.exit(1)),await t.VBuildFE(n,`dev`)};async function r(){await n(),t.watchFiles(async()=>n())}exports.dev=r;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../packages/common/log/index.js`),t=require(`./utils.js`);var n=async()=>{let n=t.entries();e.logGreen(n),Object.keys(n).length||(e.logRed(`no entry found`),process.exit(1)),await t.VBuildFE(n,`dev`)};async function r(){await n(),t.watchFiles(async()=>n())}exports.dev=r;
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.js`);const e=require(`../packages/common/log/index.js`),t=require(`./state.js`),n=require(`./dev.js`),r=require(`./prod.js`);var i=(i,a)=>{switch(t.setBuildFEOptions(a),i){case`dev`:n.dev();break;case`prod`:r.prod();break;default:e.logRed(`Usage: npx tsx scripts/index.ts [dev|prod]`)}};exports.buildFE=i;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../packages/common/log/index.js`),t=require(`./state.js`),n=require(`./dev.js`),r=require(`./prod.js`);var i=(i,a)=>{switch(t.setBuildFEOptions(a),i){case`dev`:n.dev();break;case`prod`:r.prod();break;default:e.logRed(`Usage: npx tsx scripts/index.ts [dev|prod]`)}};exports.buildFE=i;
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.js`);const e=require(`../packages/common/log/index.js`),t=require(`./utils.js`);async function n(){let n=t.entries();Object.keys(n).length||(e.logRed(`no entry found`),process.exit(1));try{await t.VBuildFE(n),e.logGreen(`build done`)}catch(t){e.logRed(String(t)),process.exit(1)}}exports.prod=n;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../packages/common/log/index.js`),t=require(`./utils.js`);async function n(){let n=t.entries();Object.keys(n).length||(e.logRed(`no entry found`),process.exit(1));try{await t.VBuildFE(n),e.logGreen(`build done`)}catch(t){e.logRed(String(t)),process.exit(1)}}exports.prod=n;
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.js`);var e={options:{output:`frame`}};function t(t){e.options={output:`frame`,...t}}exports.buildFESharedState=e,exports.setBuildFEOptions=t;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e={options:{output:`frame`}};function t(t){e.options={output:`frame`,...t}}exports.buildFESharedState=e,exports.setBuildFEOptions=t;
@@ -0,0 +1 @@
1
+ var e={frameName:`TemplateCore`,signKey:`sakjdfnkjwjfnfkjkjldljksndf`,apiSignVerify:{whiteList:[]},notFoundRedirectCount:5};module.exports=e;
package/cjs/index.js CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.js`);const e=require(`./app/controller/base.js`),t=require(`./app/service/base.js`),n=require(`./packages/utils/path.js`);require(`./packages/utils/index.js`);const r=require(`./packages/core/loader/model.js`),i=require(`./packages/core/index.js`);var a=e=>i.start({...e,frameBaseDir:n.resolve(__dirname,`.`)}),o={baseControllerFn:e,baseServiceFn:t};exports.baseFn=o,exports.modelLoader=r,exports.serverStart=a;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./app/controller/base.js`),t=require(`./app/service/base.js`),n=require(`./packages/utils/path.js`);require(`./packages/utils/index.js`);const r=require(`./packages/core/loader/model.js`),i=require(`./packages/core/index.js`);var a=async e=>i.start({...e,frameBaseDir:n.resolve(__dirname,`.`)}),o={baseControllerFn:e,baseServiceFn:t};exports.baseFn=o,exports.modelLoader=r,exports.serverStart=a;
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../../_virtual/_rolldown/runtime.js`);const e=require(`./cache/LRUCache.js`);exports.LRUCache=e.LRUCache;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./cache/LRUCache.js`);exports.LRUCache=e.LRUCache;
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../../../_virtual/_rolldown/runtime.js`);const e=require(`../guards/index.js`);function t(e){return e==null?[]:Array.isArray(e)?[...e]:[e]}var n=t=>t.filter(e.isNonNullable),r=(e,t)=>{let n=new Set,r=[];for(let i of e){let e=t(i);n.has(e)||(n.add(e),r.push(i))}return r},i=(e,t)=>{let n={};for(let r of e){let e=t(r);n[e]=n[e]??[],n[e].push(r)}return n},a=(e,t)=>{if(!Number.isInteger(t)||t<=0)throw RangeError(`chunk size must be a positive integer`);let n=[];for(let r=0;r<e.length;r+=t)n.push(e.slice(r,r+t));return n};exports.chunk=a,exports.compact=n,exports.groupBy=i,exports.toArray=t,exports.uniqueBy=r;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../guards/index.js`);function t(e){return e==null?[]:Array.isArray(e)?[...e]:[e]}var n=t=>t.filter(e.isNonNullable),r=(e,t)=>{let n=new Set,r=[];for(let i of e){let e=t(i);n.has(e)||(n.add(e),r.push(i))}return r},i=(e,t)=>{let n={};for(let r of e){let e=t(r);n[e]=n[e]??[],n[e].push(r)}return n},a=(e,t)=>{if(!Number.isInteger(t)||t<=0)throw RangeError(`chunk size must be a positive integer`);let n=[];for(let r=0;r<e.length;r+=t)n.push(e.slice(r,r+t));return n};exports.chunk=a,exports.compact=n,exports.groupBy=i,exports.toArray=t,exports.uniqueBy=r;
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../../../_virtual/_rolldown/runtime.js`);var e=class{limit;data;constructor(e){if(!Number.isInteger(e)||e<=0)throw Error(`LRUCache limit must be a positive integer`);this.limit=e,this.data=new Map}get size(){return this.data.size}has(e){return this.data.has(e)}get(e){if(!this.data.has(e))return;let t=this.data.get(e);return this.updateSorting(e,t),t}set(e,t){if(this.data.has(e)){this.updateSorting(e,t);return}this.data.size>=this.limit&&this.deleteFirstKey(),this.data.set(e,t)}push(e,t){this.set(e,t)}deleteFirstKey(){let e=this.data.keys().next().value;e!==void 0&&this.data.delete(e)}updateSorting(e,t){this.data.delete(e),this.data.set(e,t)}};exports.LRUCache=e;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=class{limit;data;constructor(e){if(!Number.isInteger(e)||e<=0)throw Error(`LRUCache limit must be a positive integer`);this.limit=e,this.data=new Map}get size(){return this.data.size}has(e){return this.data.has(e)}get(e){if(!this.data.has(e))return;let t=this.data.get(e);return this.updateSorting(e,t),t}set(e,t){if(this.data.has(e)){this.updateSorting(e,t);return}this.data.size>=this.limit&&this.deleteFirstKey(),this.data.set(e,t)}push(e,t){this.set(e,t)}deleteFirstKey(){let e=this.data.keys().next().value;e!==void 0&&this.data.delete(e)}updateSorting(e,t){this.data.delete(e),this.data.set(e,t)}};exports.LRUCache=e;
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../../../_virtual/_rolldown/runtime.js`);const e=require(`./LRUCache.js`);exports.LRUCache=e.LRUCache;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./LRUCache.js`);exports.LRUCache=e.LRUCache;
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../../../_virtual/_rolldown/runtime.js`);var e=e=>e==null,t=e=>e!=null,n=e=>typeof e==`string`,r=e=>typeof e==`number`&&Number.isFinite(e),i=e=>typeof e==`boolean`,a=e=>typeof e==`function`,o=e=>{if(typeof e!=`object`||!e)return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null};exports.isBoolean=i,exports.isFunction=a,exports.isNil=e,exports.isNonNullable=t,exports.isNumber=r,exports.isPlainObject=o,exports.isString=n;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=e=>e==null,t=e=>e!=null,n=e=>typeof e==`string`,r=e=>typeof e==`number`&&Number.isFinite(e),i=e=>typeof e==`boolean`,a=e=>typeof e==`function`,o=e=>{if(typeof e!=`object`||!e)return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null};exports.isBoolean=i,exports.isFunction=a,exports.isNil=e,exports.isNonNullable=t,exports.isNumber=r,exports.isPlainObject=o,exports.isString=n;