@_tc/template-core 0.0.1-bate.52 → 0.0.1-bate.54

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.
@@ -119,6 +119,8 @@ When consuming the published TemplateCore package, `@_tc/template-core/fe/rc` re
119
119
  import { Button, DataTable, TableSearch } from '@_tc/template-core/fe/rc'
120
120
  ```
121
121
 
122
+ Inside this source repository, use `@tc/ui-react` for the raw UI workspace package. The `@_tc/template-core/fe/rc` path is a published TemplateCore package export generated into `dist/package.json`.
123
+
122
124
  Style entry:
123
125
 
124
126
  ```tsx
@@ -310,7 +310,7 @@ interface SchemaFormProps<T> {
310
310
  buttonClassName?: string
311
311
  submitButtonProps?: Omit<ButtonElementProps, 'type' | 'onClick' | 'children'>
312
312
  cancelButtonProps?: Omit<ButtonElementProps, 'onClick' | 'children'>
313
- preserve?: boolean // default: false
313
+ preserve?: boolean // passed through to rc-field-form; TemplateCore does not set a default
314
314
  }
315
315
  ```
316
316
 
@@ -709,8 +709,8 @@ Max 5 visible messages.
709
709
 
710
710
  ```typescript
711
711
  interface NotificationProps {
712
- type: 'info' | 'success' | 'warning' | 'error'
713
- title: ReactNode
712
+ type?: 'info' | 'success' | 'warning' | 'error' // default: 'info'
713
+ title?: ReactNode
714
714
  message?: ReactNode
715
715
  duration?: number
716
716
  closable?: boolean
@@ -350,10 +350,10 @@ import { Notification } from '@tc/ui-react'
350
350
 
351
351
  ## Compound Component Pattern
352
352
 
353
- Three components use compound patterns with Context:
353
+ Three component families use context-based composition:
354
354
 
355
355
  1. **Menu**: `<Menu>` + `<Menu.Item>` + `<Menu.SubMenu>` + `<Menu.CollapseToggle>`
356
- 2. **Radio**: `<Radio.Group>` + `<Radio>`
356
+ 2. **Radio**: `<RadioGroup>` + `<Radio>`
357
357
  3. **Breadcrumb**: `<Breadcrumb>` + `<BreadcrumbList>` + `<BreadcrumbItem>` + ...
358
358
 
359
359
  Children auto-detect parent via Context and inherit configuration.
@@ -9,7 +9,7 @@ import { AsyncSelect, LanguageSwitch, ThemeSwitch } from '@_tc/template-core/fe'
9
9
  import { Button, DataTable, TableSearch } from '@_tc/template-core/fe/rc'
10
10
  ```
11
11
 
12
- Inside this repository, `@tc/ui-react` is also valid for the raw UI library. In published business projects, prefer `@_tc/template-core/fe/rc` for UI components and `@_tc/template-core/fe` for frontend runtime helpers.
12
+ Inside this repository, use `@tc/ui-react` for the raw UI workspace package. In published business projects, prefer `@_tc/template-core/fe/rc` for UI components and `@_tc/template-core/fe` for frontend runtime helpers.
13
13
 
14
14
  ## LanguageSwitch
15
15
 
@@ -1,5 +1,7 @@
1
1
  module.exports = {
2
2
  name: "Default Product Project",
3
3
  desc: "Project-level overrides can be added here.",
4
+ // Single-project scaffolds can include projk directly. For shared multi-project
5
+ // models, prefer keeping mode.js project-neutral and override homePage per project.
4
6
  homePage: "/_sidebar_/product?projk=default",
5
7
  };
@@ -177,6 +177,8 @@ Import UI components from the published UI re-export:
177
177
  import { Button, DataTable, TableSearch } from '@_tc/template-core/fe/rc'
178
178
  ```
179
179
 
180
+ Inside this source repository, use `@tc/ui-react` for the raw UI workspace package. The `@_tc/template-core/fe/rc` path is for published TemplateCore consumers.
181
+
180
182
  `LanguageSwitch` updates the shared i18n language and persists through `tc_language`. `ThemeSwitch` toggles the root `dark` class and persists through `tc_theme`. `AsyncSelect` loads options from a `fetchConfig` endpoint returning `{ label, value, searchText? }[]`.
181
183
 
182
184
  ## SchemaForm Extensions
package/AGENT_README.md CHANGED
@@ -12,7 +12,7 @@ TemplateCore 是一个 TypeScript + Koa + React 的后台框架包。它提供
12
12
  - 前端构建 `buildFE()` 和消费方 Node/backend 构建 `buildBE()`。
13
13
  - 类型扩展机制,用于扩展 SchemaForm 字段、CallCom 组件和 Koa app 类型。
14
14
 
15
- 优先使用公开入口,不要从包内部源码路径导入。
15
+ 优先使用公开入口,不要从包内部源码路径导入。下面这些入口以 npm 发布产物为准;源码仓库根 `package.json` 的 `exports` 会在构建发布包时生成到 `dist/package.json`。
16
16
 
17
17
  | 入口 | 用途 |
18
18
  | --- | --- |
@@ -83,11 +83,11 @@ export default {
83
83
  http://localhost:9000/dash?projk=demo
84
84
  ```
85
85
 
86
- `projk` 对应 `model/{modelKey}/project/{projectKey}.ts`。
86
+ `projk` 对应 `model/{modelKey}/project/{projectKey}.ts` 里的 `projectKey`,运行时按 project key 全局查找,建议保持全局唯一。
87
87
 
88
88
  ## 3. 后端约定
89
89
 
90
- `serverStart({ baseDir })` 会按目录自动加载业务代码:
90
+ `serverStart({ baseDir })` 会按目录自动加载业务代码;`model/` 由内置 project service 通过 `modelLoader(app)` 读取,不会在 `serverStart` 阶段直接挂到 `app.model`:
91
91
 
92
92
  ```text
93
93
  app/controller/**/*.(js|ts) -> app.controller
@@ -99,7 +99,7 @@ app/router-schema/**/*.(js|ts) -> app.routerSchema
99
99
  app/extend/*.(js|ts) -> app.extends
100
100
  config/config.default.(js|ts) -> app.config
101
101
  config/config.{env}.(js|ts) -> app.config
102
- model/**/*.(js|ts) -> 项目模型配置
102
+ model/**/*.(js|ts) -> 内置 project service 读取的项目模型配置
103
103
  ```
104
104
 
105
105
  Controller 示例:
@@ -361,11 +361,64 @@ import { Button, DataTable, Form, Input, Modal, Select } from '@_tc/template-cor
361
361
  - 请求方法:`request`、`get`、`post`、`put`、`patch`、`del`。
362
362
  - Schema 通信:`schemaEventBus`、`eventsInfo`、`merge`。
363
363
  - 共享状态:`modeStore`、`schemaStore`、`apiFreezerStore` 及对应 hooks。
364
- - 多语言:`i18nStore.addResources()`,配置文案可写 `$i18n::...`。
364
+ - 多语言:`i18nStore.getState().addResources()`,配置文案可写 `$i18n::...`。
365
365
  - 主题:`ThemeSwitch` 会同步根节点 `dark` class 和 `localStorage`。
366
366
 
367
367
  不要直接依赖 `frontend/src/...`、`packages/react/ui/...` 这类包内部路径。
368
368
 
369
+ ### 自定义前端入口和 HTML 插槽
370
+
371
+ 前端入口必须命名为 `.entry.tsx`、`.entry.ts`、`.entry.jsx` 或 `.entry.js`,否则 `buildFE()` 不会扫描。
372
+
373
+ 最小入口:
374
+
375
+ ```tsx
376
+ // frontend/admin/admin.entry.tsx
377
+ import { initApp } from '@_tc/template-core/fe'
378
+ import type { ReactNode } from 'react'
379
+
380
+ const AdminApp = ({ children }: { children: ReactNode }) => (
381
+ <main>{children}</main>
382
+ )
383
+
384
+ initApp(AdminApp, {
385
+ initModeData: false,
386
+ })
387
+ ```
388
+
389
+ 如果需要给页面加额外 `meta`、预连接资源或启动脚本,可以在入口同目录放 `.html` 插槽文件。这个文件不是完整 HTML,只能包含 `tc-slot` 块:
390
+
391
+ ```html
392
+ <!-- frontend/admin/admin.html -->
393
+ <!-- tc-slot:head -->
394
+ <meta name="description" content="Admin Console" />
395
+ <link rel="preconnect" href="https://example.com" />
396
+ <!-- /tc-slot:head -->
397
+
398
+ <!-- tc-slot:body-before-root -->
399
+ <div id="boot-mask"></div>
400
+ <!-- /tc-slot:body-before-root -->
401
+
402
+ <!-- tc-slot:body-after-root -->
403
+ <script>
404
+ window.__ADMIN_BOOT_TIME__ = Date.now()
405
+ </script>
406
+ <!-- /tc-slot:body-after-root -->
407
+ ```
408
+
409
+ 命名规则:
410
+
411
+ ```text
412
+ frontend/admin/admin.entry.tsx
413
+ frontend/admin/admin.html yes
414
+
415
+ frontend/report/index.entry.tsx
416
+ frontend/report/index.html yes
417
+ frontend/report/report.html yes
418
+ ```
419
+
420
+ 不要在插槽文件里写 `<!DOCTYPE html>`、`<html>`、`<body>` 或 `<div id="root"></div>`。页面外壳由 TemplateCore 的 `app/view/entry.tpl` 统一生成,`window._basePath`、`window._projKey`、`window._signKey`、`window.appOptions` 也由它注入。构建器会把合成后的临时 HTML 写入 `.tc-entry-html/`,这个目录不要提交,也不要在业务代码中引用。
421
+
369
422
  ## 6. 构建
370
423
 
371
424
  前端资源构建:
@@ -495,8 +548,9 @@ chokidar
495
548
 
496
549
  1. 在业务 `frontend/` 下添加入口 `*.entry.tsx`。
497
550
  2. 需要样式时引入 `@_tc/template-core/fe/tailwind_ui.css`。
498
- 3. `model` 菜单中使用 `moduleType: 'custom'`,让 `customConfig.path` 指向页面路径。
499
- 4. 使用 `buildFE('dev')` `buildFE('prod')` 生成资源。
551
+ 3. 如需改 head root 前后内容,只添加入口同目录 `.html` 插槽文件,不要写完整 HTML。
552
+ 4. `model` 菜单中使用 `moduleType: 'custom'`,让 `customConfig.path` 指向页面路径。
553
+ 5. 使用 `buildFE('dev')` 或 `buildFE('prod')` 生成资源。
500
554
 
501
555
  扩展前端类型或组件:
502
556
 
@@ -513,11 +567,11 @@ chokidar
513
567
  | 任务 | 建议阅读 |
514
568
  | --- | --- |
515
569
  | 完整安装和使用说明 | npm 包根目录 `README.md` |
516
- | 生成项目、model、CRUD | `.skills/tc-generator/SKILL.md` |
517
- | 组件选型和用法 | `.skills/tc-component-usage-skills/SKILL.md` |
518
- | model/schema 配置细节 | `.skills/tc-generator/reference/model-schema.md` |
519
- | 完整 CRUD 示例 | `.skills/tc-generator/reference/example.md` |
520
- | 可复制项目骨架 | `.skills/tc-generator/reference/project-template/` |
570
+ | 生成项目、model、CRUD | npm 包:`.skills/tc-generator/SKILL.md`;源码仓库:`skills/tc-generator/SKILL.md` |
571
+ | 组件选型和用法 | npm 包:`.skills/tc-component-usage-skills/SKILL.md`;源码仓库:`skills/tc-component-usage-skills/SKILL.md` |
572
+ | model/schema 配置细节 | npm 包:`.skills/tc-generator/reference/model-schema.md`;源码仓库:`skills/tc-generator/reference/model-schema.md` |
573
+ | 完整 CRUD 示例 | npm 包:`.skills/tc-generator/reference/example.md`;源码仓库:`skills/tc-generator/reference/example.md` |
574
+ | 可复制项目骨架 | npm 包:`.skills/tc-generator/reference/project-template/`;源码仓库:`skills/tc-generator/reference/project-template/` |
521
575
  | UI 组件现场预览 | 启动服务后访问 `/ui-components` |
522
576
  | 已安装包的类型细节 | 查看对应公开入口的 `.d.ts` 文件 |
523
577
 
package/README.md CHANGED
@@ -12,7 +12,7 @@ pnpm add @_tc/template-core
12
12
 
13
13
  - Node.js >= 18
14
14
  - pnpm >= 8
15
- - 使用内置前端时,需要安装 React、Vite peer dependencies
15
+ - 使用内置前端时,需要安装 peer dependencies;完整清单以包内 `package.json` 的 `peerDependencies` 为准,包括 Koa、React、Vite、路由、状态、表单和 UI 相关依赖。
16
16
 
17
17
  ## 可选:给项目 AI 助手的文档与 Skill
18
18
 
@@ -28,9 +28,9 @@ pnpm add @_tc/template-core
28
28
  如果你的 Agent 支持本地 skills 目录,可以从已安装的 npm 包复制安装。以 Codex 为例:
29
29
 
30
30
  ```bash
31
- mkdir -p “${CODEX_HOME:-$HOME/.codex}/skills
32
- cp -R node_modules/@_tc/template-core/.skills/tc-generator “${CODEX_HOME:-$HOME/.codex}/skills/tc-generator
33
- cp -R node_modules/@_tc/template-core/.skills/tc-component-usage-skills “${CODEX_HOME:-$HOME/.codex}/skills/tc-component-usage-skills
31
+ mkdir -p "${CODEX_HOME:-$HOME/.codex}/skills"
32
+ cp -R node_modules/@_tc/template-core/.skills/tc-generator "${CODEX_HOME:-$HOME/.codex}/skills/tc-generator"
33
+ cp -R node_modules/@_tc/template-core/.skills/tc-component-usage-skills "${CODEX_HOME:-$HOME/.codex}/skills/tc-component-usage-skills"
34
34
  ```
35
35
 
36
36
  安装后重启对应 Agent,让新 skill 生效。使用时可以直接说”用 tc-generator 生成一个商品管理模块”或”用 tc-component-usage-skills 帮我写一个带搜索的分页表格”。
@@ -99,7 +99,6 @@ main().catch((error) => {
99
99
  | `baseDir` | `string` | 否 | - | 项目根目录,通常为 `join(__dirname, '.')` |
100
100
  | `pageBasePage` | `string` | 否 | `'/'` | 页面访问前缀,所有前端页面路由的基础路径 |
101
101
  | `homePage` | `string` | 否 | - | 应用首页路径 |
102
- | `frameBaseDir` | `string` | 否 | - | 框架根目录,通常不需要手动设置 |
103
102
  | `additionalPublicPaths` | `string | string[]` | 否 | - | 追加静态资源目录和 Nunjucks 模板查找目录,必须传绝对路径 |
104
103
 
105
104
  框架会自动读取 `config/config.default.ts` 中的配置(如 `port`、`env` 等)。
@@ -117,7 +116,7 @@ buildFE(mode: 'dev' | 'prod', options?: BuildFEOptions)
117
116
  - `'prod'`:生产模式,构建优化后的静态资源
118
117
 
119
118
  **options.output**:构建输出位置
120
- - `'frame'`(默认):输出到框架包内的 `node_modules/@_tc/template-core/app/public/dist`
119
+ - `'frame'`(默认):输出到当前导入格式对应的框架静态目录,例如 `node_modules/@_tc/template-core/esm/app/public/dist` 或 `node_modules/@_tc/template-core/cjs/app/public/dist`
121
120
  - `'run'`:输出到项目根目录的 `app/public/dist`,适合 TypeScript 编译后的项目
122
121
  - `() => string`:自定义函数,返回输出目录的绝对路径
123
122
 
@@ -153,7 +152,9 @@ http://localhost:9000/dash?projk=demo
153
152
 
154
153
  `projk` 对应 `model/{modelKey}/project/{projectKey}.ts` 里的 `projectKey`。
155
154
 
156
- ## 公开入口
155
+ ## 常用公开入口
156
+
157
+ 完整 exports 以发布包内 `package.json` 为准,除下表外还包含 `./fe/main`、`./fe/*`、`./fe/rc/*`、`./fe/rc/hooks/*` 等子路径。
157
158
 
158
159
  | 入口 | 用途 |
159
160
  | --- | --- |
@@ -292,12 +293,12 @@ import type {
292
293
 
293
294
  ### 前端多语言
294
295
 
295
- TemplateCore 前端复用 `@tc/ui-react/i18n`。框架内置中文、英文资源,项目可以继续追加自己的资源。
296
+ TemplateCore 前端通过 `@_tc/template-core/fe` 暴露 i18n 能力。框架内置中文、英文资源,项目可以继续追加自己的资源。
296
297
 
297
298
  **追加自定义语言资源**:
298
299
 
299
300
  ```ts
300
- import { i18nStore } from '@tc/ui-react/i18n'
301
+ import { i18nStore } from '@_tc/template-core/fe'
301
302
 
302
303
  i18nStore.getState().addResources('zh-CN', {
303
304
  business: {
@@ -383,7 +384,7 @@ const title = '$i18n::business.product.createTitle'
383
384
  **切换语言**:
384
385
 
385
386
  ```ts
386
- import { i18nStore } from '@tc/ui-react/i18n'
387
+ import { i18nStore } from '@_tc/template-core/fe'
387
388
 
388
389
  i18nStore.getState().setLanguage('en-US')
389
390
  i18nStore.getState().setLanguage('zh-CN')
@@ -582,7 +583,7 @@ try {
582
583
  | --- | --- | --- |
583
584
  | `Modal` | 模态框组件 | `@_tc/template-core/fe/rc` |
584
585
  | `Drawer` | 抽屉组件 | `@_tc/template-core/fe/rc` |
585
- | `Message` | 消息提示组件 | `@_tc/template-core/fe/rc` |
586
+ | `message` | 消息提示方法 | `@_tc/template-core/fe/rc` |
586
587
  | `Notification` | 通知组件 | `@_tc/template-core/fe/rc` |
587
588
  | `ConfirmDialog` | 确认对话框组件 | `@_tc/template-core/fe/rc` |
588
589
  | `Popup` | 弹出层组件 | `@_tc/template-core/fe/rc` |
@@ -1536,6 +1537,55 @@ frontend/admin/admin.entry.tsx
1536
1537
 
1537
1538
  入口文件名必须包含 `.entry.`,构建器才会扫描。
1538
1539
 
1540
+ 最小入口示例:
1541
+
1542
+ ```tsx
1543
+ // frontend/admin/admin.entry.tsx
1544
+ import { initApp } from '@_tc/template-core/fe'
1545
+ import type { ReactNode } from 'react'
1546
+
1547
+ const AdminApp = ({ children }: { children: ReactNode }) => (
1548
+ <main>{children}</main>
1549
+ )
1550
+
1551
+ initApp(AdminApp, {
1552
+ initModeData: false,
1553
+ })
1554
+ ```
1555
+
1556
+ 如果需要给页面加额外 `meta`、预连接资源或启动脚本,可以在入口同目录放 `.html` 插槽文件。这个文件不是完整 HTML,只能包含 `tc-slot` 块:
1557
+
1558
+ ```html
1559
+ <!-- frontend/admin/admin.html -->
1560
+ <!-- tc-slot:head -->
1561
+ <meta name="description" content="Admin Console" />
1562
+ <link rel="preconnect" href="https://example.com" />
1563
+ <!-- /tc-slot:head -->
1564
+
1565
+ <!-- tc-slot:body-before-root -->
1566
+ <div id="boot-mask"></div>
1567
+ <!-- /tc-slot:body-before-root -->
1568
+
1569
+ <!-- tc-slot:body-after-root -->
1570
+ <script>
1571
+ window.__ADMIN_BOOT_TIME__ = Date.now()
1572
+ </script>
1573
+ <!-- /tc-slot:body-after-root -->
1574
+ ```
1575
+
1576
+ 命名规则:
1577
+
1578
+ ```text
1579
+ frontend/admin/admin.entry.tsx
1580
+ frontend/admin/admin.html yes
1581
+
1582
+ frontend/report/index.entry.tsx
1583
+ frontend/report/index.html yes
1584
+ frontend/report/report.html yes
1585
+ ```
1586
+
1587
+ 不要在插槽文件里写 `<!DOCTYPE html>`、`<html>`、`<body>` 或 `<div id="root"></div>`。页面外壳由 TemplateCore 的 `app/view/entry.tpl` 统一生成,`window._basePath`、`window._projKey`、`window._signKey`、`window.appOptions` 也由它注入。
1588
+
1539
1589
  扩展 Dashboard 路由:
1540
1590
 
1541
1591
  ```tsx
@@ -1597,7 +1647,7 @@ buildFE('dev')
1597
1647
  buildFE('prod')
1598
1648
  ```
1599
1649
 
1600
- 默认输出到框架包的 `app/public/dist`。如果要输出到项目:
1650
+ 默认输出到当前导入格式对应的框架静态目录,例如 `esm/app/public/dist` 或 `cjs/app/public/dist`。如果要输出到项目:
1601
1651
 
1602
1652
  ```ts
1603
1653
  buildFE('prod', {
@@ -1768,4 +1818,4 @@ await buildBE({
1768
1818
  - Dashboard 登录守卫放在 `frontend/extended/dash/routeGuard.ts`;登录页通常不在 Dash 路由下,返回登录页 URL 即可。
1769
1819
  - 服务端兜底守卫放在业务 `app/router-guard.ts|js`,不是 `app/business` 子目录。
1770
1820
  - 前端入口必须命名为 `.entry.tsx`、`.entry.ts`、`.entry.jsx` 或 `.entry.js`。
1771
- - **使用方不建议在 `/frontend/apps/` 下保留 `html` 文件。** Vite 构建时会根据模板文件(`app/view/entry.tpl`)自动生成 html,如果保留 html 文件,可能与模板不同步而导致内容过时。
1821
+ - 入口同目录的 `.html` 只能作为插槽文件使用,不能写完整 HTML 文档;页面外壳始终由 `app/view/entry.tpl` 生成。
@@ -5,6 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <link rel="icon" type="image/x-icon" href="/static/logo.png" />
7
7
  <title>{{ name }}</title>
8
+ <!-- TC_HEAD_SLOT -->
8
9
  </head>
9
10
 
10
11
  <script id="input">
@@ -22,7 +23,9 @@
22
23
  </script>
23
24
 
24
25
  <body>
26
+ <!-- TC_BODY_BEFORE_ROOT_SLOT -->
25
27
  <div id="root"></div>
28
+ <!-- TC_BODY_AFTER_ROOT_SLOT -->
26
29
  </body>
27
30
 
28
31
  <!-- {{InsertScript}} -->
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./buildBE.js`),t=require(`../packages/common/log/index.js`),n=require(`./state.js`),r=require(`./dev.js`),i=require(`./prod.js`);var a=(e,a)=>{switch(n.setBuildFEOptions(a),e){case`dev`:r.dev();break;case`prod`:i.prod();break;default:t.logRed(`Usage: npx tsx scripts/index.ts [dev|prod]`)}};exports.buildBE=e.buildBE,exports.buildFE=a;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./buildBE.js`),t=require(`../packages/common/log/index.js`),n=require(`./state.js`),r=require(`./dev.js`),i=require(`./prod.js`);var a=(e,a)=>{switch(n.setBuildFEOptions(a),e){case`dev`:return r.dev();case`prod`:return i.prod();default:return t.logRed(`Usage: npx tsx scripts/index.ts [dev|prod]`),Promise.resolve()}};exports.buildBE=e.buildBE,exports.buildFE=a;
@@ -1 +1,3 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../_virtual/_rolldown/runtime.js`),t=require(`../packages/utils/path.js`);require(`../packages/utils/index.js`);const n=require(`../packages/common/log/index.js`),r=require(`./state.js`);let i=require(`path`);i=e.__toESM(i);let a=require(`glob`);a=e.__toESM(a);let o=require(`fs`),s=require(`vite`),c=require(`@tailwindcss/vite`);c=e.__toESM(c);let l=require(`module`),u=require(`url`);var d=typeof __filename==`string`?__filename:(0,u.fileURLToPath)({}.url),f=i.default.dirname(d),p=process.cwd(),m=(0,l.createRequire)(d),h=i.default.resolve(f,`../../`),g=i.default.resolve(f,`../`),_=i.default.resolve(h,`./fe/frontend`),v=i.default.resolve(p,`.`),y=i.default.resolve(v,`./frontend`),b=e=>i.default.dirname(m.resolve(`${e}/package.json`));function x(){n.logWhite(`frameFEPath: `+_),n.logWhite(`runFEPath: `+y);let e=[_,y].reduce((e,n)=>{let r=[`js`,`jsx`,`ts`,`tsx`].map(e=>t.resolve(n,`/**`,`/*.`+e)),i=a.sync(r).filter(e=>e.includes(`.entry.`)).filter(e=>!e.includes(`.d.ts`));return[...e,...i]},[]),r={};if(!e.length)return r;let s;for(let n=0;n<e.length;n++){let c=e[n],l=i.default.resolve(c,`../`),u=a.sync(t.resolve(l,`*.html`))[0];if(u){let e=i.default.basename(u,`.html`);r[e]=i.default.resolve(p,u)}else{s||=(0,o.readFileSync)(i.default.resolve(g,`./app/view/entry.tpl`),`utf-8`);let e=c.split(i.default.sep).at(-1),t=s.replace(`<!-- {{InsertScript}} -->`,`<script type="module" src="./${e}"><\/script>`),n=l.split(i.default.sep).at(-1),a=i.default.join(l,n+`.html`);(0,o.writeFileSync)(a,t),r[n]=a}}return r}function S(){let e=r.buildFESharedState.options.output??`frame`;return e!==`frame`&&n.logRed(`Please pay attention to the build output.`),e===`run`?i.default.join(v,`./app/public/dist`):typeof e==`function`?e():i.default.join(g,`./app/public/dist`)}var C=async e=>{let t=(await import(`chokidar`)).watch(y,{ignored:/(^|[\/\\])\../,persistent:!0,ignoreInitial:!0}),r=!1;t.on(`change`,async t=>{if(!r){r=!0,n.logYellow(`changed: ${t}`);try{await e?.()}catch(e){n.logRed(e)}finally{r=!1}}}),n.logYellow(`watching ${y}/...`)};function w(e=`.html`){let t=[...new Set(Array.isArray(e)?e:[e])];return{name:`flatten-html`,apply:`build`,closeBundle(){let e=S();if(!(0,o.existsSync)(e))return;let r=a.sync(`**/*.html`,{cwd:e,dot:!0});for(let n of r){let r=i.default.join(e,n),a=i.default.basename(n,`.html`),s=`.entry`;a.indexOf(s)===-1&&(a+=s);for(let n of t){let t=a+n,s=i.default.join(e,t);r!==s&&(0,o.copyFileSync)(r,s)}t.some(t=>r===i.default.join(e,a+t))||(0,o.unlinkSync)(r)}let s=[...new Set(r.map(e=>i.default.dirname(e)))].sort().reverse(),c=e=>{if(!((0,o.existsSync)(e)?(0,o.readdirSync)(e):[1]).length){(0,o.rmdirSync)(e);let t=e.split(i.default.sep).slice(0,-1);t.length&&c(t.join(i.default.sep))}};for(let t of s)t&&t!==`.`&&c(i.default.join(e,t));let l=t.flatMap(t=>a.sync(`**/*`+t,{cwd:e,dot:!0}));for(let e of l)n.logYellow(`final file path -----> `+e)}}}function T(e){let t=[``,`.ts`,`.tsx`,`.js`,`.jsx`];return e.reduce((e,[n,r,a=y,s=`./defaultAlias`])=>{let c=t.map(e=>i.default.resolve(a,r+e)).find(e=>(0,o.existsSync)(e)),l=i.default.resolve(f,s);return c&&(l=c),e[n]=l,e},{})}var E=(...e)=>new RegExp(e.join(`[\\/]`)),D=e=>`_${e}_tcC`,O=async(e,t)=>{try{await(0,s.build)({configFile:!1,base:`/dist`,plugins:[(await import(`@vitejs/plugin-react`)).default(),w([`.tpl`,`.html`]),(0,c.default)()],build:{outDir:S(),emptyOutDir:!0,sourcemap:t===`dev`?`inline`:`hidden`,rolldownOptions:{input:e,output:{codeSplitting:{groups:[{name:D(`__nm`),test:E(`node_modules`),maxSize:5e5,minShareCount:2,priority:1},{name:D(`r`),test:E(`node_modules`,`react`),minShareCount:2,maxSize:5e5,priority:5},{name:D(`r-d`),test:E(`node_modules`,`react-dom`),minShareCount:2,maxSize:2e5,priority:10},{name:D(`r-r-d`),test:E(`node_modules`,`react-router-dom`),minShareCount:2,maxSize:5e5,priority:10},{name:D(`ajv`),test:E(`node_modules`,`ajv`),minShareCount:2,maxSize:2e5,priority:10},{name:D(`ui-lib`),test:E(`components`),minShareCount:2,maxSize:2e5,priority:5},{name:D(`ui-f-lib`),test:E(`components`,`.*?[Ff]orm.*?`),minShareCount:2,maxSize:5e4,priority:10}]}}}},resolve:{alias:{react:b(`react`),"react-dom":b(`react-dom`),"@tc/ui-react/hooks":i.default.resolve(f,`../../fe/packages/react/hooks/`),"@tc/ui-react":i.default.resolve(f,`../../fe/packages/react/ui/`),...T([[`@tc/scalability/SchemaForm/frameData`,`./extended/SchemaForm/data`,_],[`@tc/scalability/SchemaForm/data`,`./extended/SchemaForm/data`],[`@tc/scalability/SchemaPage/CallCom/data`,`./extended/SchemaPage/CallCom/data`],[`@tc/scalability/dash/customRoutes`,`./extended/dash/customRoutes`],[`@tc/scalability/dash/components`,`./extended/dash/components`],[`@tc/scalability/dash/routeGuard`,`./extended/dash/routeGuard`,void 0,`./defaultRouteGuard`]])}}}),n.logJoinColorized(n.colorize(`builded`,`green`),n.colorize(` -> `,`white`),n.colorize(`time: `,`cyan`),n.colorize(new Date,`pink`))}catch(e){if(n.logRed(e),t!==`dev`)throw e}};exports.VBuildFE=O,exports.entries=x,exports.outDir=S,exports.watchFiles=C;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../_virtual/_rolldown/runtime.js`),t=require(`../packages/utils/path.js`);require(`../packages/utils/index.js`);const n=require(`../packages/common/log/index.js`),r=require(`./state.js`);let i=require(`path`);i=e.__toESM(i);let a=require(`glob`);a=e.__toESM(a);let o=require(`fs`),s=require(`vite`),c=require(`@tailwindcss/vite`);c=e.__toESM(c);let l=require(`module`),u=require(`url`);var d=typeof __filename==`string`?__filename:(0,u.fileURLToPath)({}.url),f=i.default.dirname(d),p=process.cwd(),m=(0,l.createRequire)(d),h=i.default.resolve(f,`../../`),g=i.default.resolve(f,`../`),_=i.default.resolve(h,`./fe/frontend`),v=i.default.resolve(p,`.`),y=i.default.resolve(v,`./frontend`),b=e=>i.default.dirname(m.resolve(`${e}/package.json`)),x=i.default.join(v,`.tc-entry-html`),S=`<!-- {{InsertScript}} -->`,C={head:`<!-- TC_HEAD_SLOT -->`,bodyBeforeRoot:`<!-- TC_BODY_BEFORE_ROOT_SLOT -->`,bodyAfterRoot:`<!-- TC_BODY_AFTER_ROOT_SLOT -->`},w=[`head`,`body-before-root`,`body-after-root`],T=()=>({head:``,"body-before-root":``,"body-after-root":``}),E=e=>e.split(i.default.sep).join(`/`),D=e=>{let t=E(e);return t.startsWith(`.`)||t.startsWith(`/`)?t:`./${t}`},O=e=>/<html[\s>]/i.test(e)&&e.includes(`window['_basePath']`)&&/<div\s+id=["']root["']\s*><\/div>/i.test(e),k=e=>{let t=T(),r=(0,o.readFileSync)(e,`utf-8`),i=/<!--\s*tc-slot:([\w-]+)\s*-->([\s\S]*?)<!--\s*\/tc-slot:\1\s*-->/g,a=!1,s=r;if(r.replace(i,(n,r,i)=>{if(a=!0,!w.includes(r))throw Error(`Invalid html slot "${r}" in ${e}. Allowed slots: ${w.join(`, `)}.`);return t[r]+=i.trim()?`${i}\n`:``,s=s.replace(n,``),n}),s.trim()){if(O(r))return n.logYellow(`ignored legacy generated entry html: ${e}`),T();throw Error([`Invalid custom entry html: ${e}.`,`Custom entry html can only contain tc-slot blocks, for example:`,`<!-- tc-slot:head -->`,`<meta name="description" content="..." />`,`<!-- /tc-slot:head -->`].join(`
2
+ `))}return a&&n.logYellow(`using custom entry html slots: ${e}`),t},A=(e,n)=>{let r=i.default.basename(e),s=[i.default.join(e,`${n}.html`),i.default.join(e,`${r}.html`)].find(e=>(0,o.existsSync)(e));if(s)return s;if(a.sync(t.resolve(e,`*.html`)).length)throw Error([`Entry html filename is not supported in ${e}.`,`Use ${n}.html or ${r}.html as a tc-slot file.`].join(`
3
+ `))},j=(e,t)=>e.replace(C.head,t.head).replace(C.bodyBeforeRoot,t[`body-before-root`]).replace(C.bodyAfterRoot,t[`body-after-root`]),M=(e,t,n,r)=>{let a=i.default.join(x,`${n}.html`),s=D(i.default.relative(i.default.dirname(a),t));return(0,o.writeFileSync)(a,j(e,r).replace(S,`<script type="module" src="${s}"><\/script>`)),a};function N(){n.logWhite(`frameFEPath: `+_),n.logWhite(`runFEPath: `+y);let e=[_,y].reduce((e,n)=>{let r=[`js`,`jsx`,`ts`,`tsx`].map(e=>t.resolve(n,`/**`,`/*.`+e)),i=a.sync(r).filter(e=>e.includes(`.entry.`)).filter(e=>!e.includes(`.d.ts`));return[...e,...i]},[]),r={};if(!e.length)return r;(0,o.rmSync)(x,{recursive:!0,force:!0}),(0,o.mkdirSync)(x,{recursive:!0});let s=(0,o.readFileSync)(i.default.resolve(g,`./app/view/entry.tpl`),`utf-8`);for(let t=0;t<e.length;t++){let n=e[t],a=i.default.resolve(n,`../`),o=A(a,i.default.basename(n).replace(/\.entry\.[^.]+$/,``)),c=o?i.default.basename(o,`.html`):a.split(i.default.sep).at(-1);r[c]=M(s,n,c,o?k(o):T())}return r}function P(){let e=r.buildFESharedState.options.output??`frame`;return e!==`frame`&&n.logRed(`Please pay attention to the build output.`),e===`run`?i.default.join(v,`./app/public/dist`):typeof e==`function`?e():i.default.join(g,`./app/public/dist`)}var F=async e=>{let t=(await import(`chokidar`)).watch(y,{ignored:/(^|[\/\\])\../,persistent:!0,ignoreInitial:!0}),r=!1;t.on(`change`,async t=>{if(!r){r=!0,n.logYellow(`changed: ${t}`);try{await e?.()}catch(e){n.logRed(e)}finally{r=!1}}}),n.logYellow(`watching ${y}/...`)};function I(e=`.html`){let t=[...new Set(Array.isArray(e)?e:[e])];return{name:`flatten-html`,apply:`build`,closeBundle(){let e=P();if(!(0,o.existsSync)(e))return;let r=a.sync(`**/*.html`,{cwd:e,dot:!0});for(let n of r){let r=i.default.join(e,n),a=i.default.basename(n,`.html`),s=`.entry`;a.indexOf(s)===-1&&(a+=s);for(let n of t){let t=a+n,s=i.default.join(e,t);r!==s&&(0,o.copyFileSync)(r,s)}t.some(t=>r===i.default.join(e,a+t))||(0,o.unlinkSync)(r)}let s=[...new Set(r.map(e=>i.default.dirname(e)))].sort().reverse(),c=e=>{if(!((0,o.existsSync)(e)?(0,o.readdirSync)(e):[1]).length){(0,o.rmdirSync)(e);let t=e.split(i.default.sep).slice(0,-1);t.length&&c(t.join(i.default.sep))}};for(let t of s)t&&t!==`.`&&c(i.default.join(e,t));let l=t.flatMap(t=>a.sync(`**/*`+t,{cwd:e,dot:!0}));for(let e of l)n.logYellow(`final file path -----> `+e)}}}function L(e){let t=[``,`.ts`,`.tsx`,`.js`,`.jsx`];return e.reduce((e,[n,r,a=y,s=`./defaultAlias`])=>{let c=t.map(e=>i.default.resolve(a,r+e)).find(e=>(0,o.existsSync)(e)),l=i.default.resolve(f,s);return c&&(l=c),e[n]=l,e},{})}var R=(...e)=>new RegExp(e.join(`[\\/]`)),z=e=>`_${e}_tcC`,B=async(e,t)=>{try{await(0,s.build)({configFile:!1,base:`/dist`,plugins:[(await import(`@vitejs/plugin-react`)).default(),I([`.tpl`,`.html`]),(0,c.default)()],build:{outDir:P(),emptyOutDir:!0,sourcemap:t===`dev`?`inline`:`hidden`,rolldownOptions:{input:e,output:{codeSplitting:{groups:[{name:z(`__nm`),test:R(`node_modules`),maxSize:5e5,minShareCount:2,priority:1},{name:z(`r`),test:R(`node_modules`,`react`),minShareCount:2,maxSize:5e5,priority:5},{name:z(`r-d`),test:R(`node_modules`,`react-dom`),minShareCount:2,maxSize:2e5,priority:10},{name:z(`r-r-d`),test:R(`node_modules`,`react-router-dom`),minShareCount:2,maxSize:5e5,priority:10},{name:z(`ajv`),test:R(`node_modules`,`ajv`),minShareCount:2,maxSize:2e5,priority:10},{name:z(`ui-lib`),test:R(`components`),minShareCount:2,maxSize:2e5,priority:5},{name:z(`ui-f-lib`),test:R(`components`,`.*?[Ff]orm.*?`),minShareCount:2,maxSize:5e4,priority:10}]}}}},resolve:{alias:{react:b(`react`),"react-dom":b(`react-dom`),"@tc/ui-react/hooks":i.default.resolve(f,`../../fe/packages/react/hooks/`),"@tc/ui-react":i.default.resolve(f,`../../fe/packages/react/ui/`),...L([[`@tc/scalability/SchemaForm/frameData`,`./extended/SchemaForm/data`,_],[`@tc/scalability/SchemaForm/data`,`./extended/SchemaForm/data`],[`@tc/scalability/SchemaPage/CallCom/data`,`./extended/SchemaPage/CallCom/data`],[`@tc/scalability/dash/customRoutes`,`./extended/dash/customRoutes`],[`@tc/scalability/dash/components`,`./extended/dash/components`],[`@tc/scalability/dash/routeGuard`,`./extended/dash/routeGuard`,void 0,`./defaultRouteGuard`]])}}}),n.logJoinColorized(n.colorize(`builded`,`green`),n.colorize(` -> `,`white`),n.colorize(`time: `,`cyan`),n.colorize(new Date,`pink`))}catch(e){if(n.logRed(e),t!==`dev`)throw e}};exports.VBuildFE=B,exports.entries=N,exports.outDir=P,exports.watchFiles=F;
@@ -5,6 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <link rel="icon" type="image/x-icon" href="/static/logo.png" />
7
7
  <title>{{ name }}</title>
8
+ <!-- TC_HEAD_SLOT -->
8
9
  </head>
9
10
 
10
11
  <script id="input">
@@ -22,7 +23,9 @@
22
23
  </script>
23
24
 
24
25
  <body>
26
+ <!-- TC_BODY_BEFORE_ROOT_SLOT -->
25
27
  <div id="root"></div>
28
+ <!-- TC_BODY_AFTER_ROOT_SLOT -->
26
29
  </body>
27
30
 
28
31
  <!-- {{InsertScript}} -->
@@ -6,13 +6,9 @@ import { prod as i } from "./prod.js";
6
6
  //#region bundler/index.ts
7
7
  var a = (e, a) => {
8
8
  switch (n(a), e) {
9
- case "dev":
10
- r();
11
- break;
12
- case "prod":
13
- i();
14
- break;
15
- default: t("Usage: npx tsx scripts/index.ts [dev|prod]");
9
+ case "dev": return r();
10
+ case "prod": return i();
11
+ default: return t("Usage: npx tsx scripts/index.ts [dev|prod]"), Promise.resolve();
16
12
  }
17
13
  };
18
14
  //#endregion
@@ -4,16 +4,54 @@ import { colorize as t, logJoinColorized as n, logRed as r, logWhite as i, logYe
4
4
  import { buildFESharedState as o } from "./state.js";
5
5
  import s from "path";
6
6
  import * as c from "glob";
7
- import { copyFileSync as l, existsSync as u, readFileSync as d, readdirSync as f, rmdirSync as p, unlinkSync as m, writeFileSync as h } from "fs";
8
- import { build as g } from "vite";
9
- import _ from "@tailwindcss/vite";
10
- import { createRequire as v } from "module";
11
- import { fileURLToPath as y } from "url";
7
+ import { copyFileSync as l, existsSync as u, mkdirSync as d, readFileSync as f, readdirSync as p, rmSync as m, rmdirSync as h, unlinkSync as g, writeFileSync as _ } from "fs";
8
+ import { build as v } from "vite";
9
+ import y from "@tailwindcss/vite";
10
+ import { createRequire as b } from "module";
11
+ import { fileURLToPath as x } from "url";
12
12
  //#region bundler/utils.ts
13
- var b = typeof __filename == "string" ? __filename : y(import.meta.url), x = s.dirname(b), S = process.cwd(), C = v(b), w = s.resolve(x, "../../"), T = s.resolve(x, "../"), E = s.resolve(w, "./fe/frontend"), D = s.resolve(S, "."), O = s.resolve(D, "./frontend"), k = (e) => s.dirname(C.resolve(`${e}/package.json`));
14
- function A() {
15
- i("frameFEPath: " + E), i("runFEPath: " + O);
16
- let t = [E, O].reduce((t, n) => {
13
+ var S = typeof __filename == "string" ? __filename : x(import.meta.url), C = s.dirname(S), w = process.cwd(), T = b(S), E = s.resolve(C, "../../"), D = s.resolve(C, "../"), O = s.resolve(E, "./fe/frontend"), k = s.resolve(w, "."), A = s.resolve(k, "./frontend"), j = (e) => s.dirname(T.resolve(`${e}/package.json`)), M = s.join(k, ".tc-entry-html"), N = "<!-- {{InsertScript}} -->", P = {
14
+ head: "<!-- TC_HEAD_SLOT -->",
15
+ bodyBeforeRoot: "<!-- TC_BODY_BEFORE_ROOT_SLOT -->",
16
+ bodyAfterRoot: "<!-- TC_BODY_AFTER_ROOT_SLOT -->"
17
+ }, F = [
18
+ "head",
19
+ "body-before-root",
20
+ "body-after-root"
21
+ ], I = () => ({
22
+ head: "",
23
+ "body-before-root": "",
24
+ "body-after-root": ""
25
+ }), L = (e) => e.split(s.sep).join("/"), R = (e) => {
26
+ let t = L(e);
27
+ return t.startsWith(".") || t.startsWith("/") ? t : `./${t}`;
28
+ }, z = (e) => /<html[\s>]/i.test(e) && e.includes("window['_basePath']") && /<div\s+id=["']root["']\s*><\/div>/i.test(e), B = (e) => {
29
+ let t = I(), n = f(e, "utf-8"), r = /<!--\s*tc-slot:([\w-]+)\s*-->([\s\S]*?)<!--\s*\/tc-slot:\1\s*-->/g, i = !1, o = n;
30
+ if (n.replace(r, (n, r, a) => {
31
+ if (i = !0, !F.includes(r)) throw Error(`Invalid html slot "${r}" in ${e}. Allowed slots: ${F.join(", ")}.`);
32
+ return t[r] += a.trim() ? `${a}\n` : "", o = o.replace(n, ""), n;
33
+ }), o.trim()) {
34
+ if (z(n)) return a(`ignored legacy generated entry html: ${e}`), I();
35
+ throw Error([
36
+ `Invalid custom entry html: ${e}.`,
37
+ "Custom entry html can only contain tc-slot blocks, for example:",
38
+ "<!-- tc-slot:head -->",
39
+ "<meta name=\"description\" content=\"...\" />",
40
+ "<!-- /tc-slot:head -->"
41
+ ].join("\n"));
42
+ }
43
+ return i && a(`using custom entry html slots: ${e}`), t;
44
+ }, V = (t, n) => {
45
+ let r = s.basename(t), i = [s.join(t, `${n}.html`), s.join(t, `${r}.html`)].find((e) => u(e));
46
+ if (i) return i;
47
+ if (c.sync(e(t, "*.html")).length) throw Error([`Entry html filename is not supported in ${t}.`, `Use ${n}.html or ${r}.html as a tc-slot file.`].join("\n"));
48
+ }, H = (e, t) => e.replace(P.head, t.head).replace(P.bodyBeforeRoot, t["body-before-root"]).replace(P.bodyAfterRoot, t["body-after-root"]), U = (e, t, n, r) => {
49
+ let i = s.join(M, `${n}.html`), a = R(s.relative(s.dirname(i), t));
50
+ return _(i, H(e, r).replace(N, `<script type="module" src="${a}"><\/script>`)), i;
51
+ };
52
+ function W() {
53
+ i("frameFEPath: " + O), i("runFEPath: " + A);
54
+ let t = [O, A].reduce((t, n) => {
17
55
  let r = [
18
56
  "js",
19
57
  "jsx",
@@ -23,26 +61,23 @@ function A() {
23
61
  return [...t, ...i];
24
62
  }, []), n = {};
25
63
  if (!t.length) return n;
26
- let r;
27
- for (let i = 0; i < t.length; i++) {
28
- let a = t[i], o = s.resolve(a, "../"), l = c.sync(e(o, "*.html"))[0];
29
- if (l) {
30
- let e = s.basename(l, ".html");
31
- n[e] = s.resolve(S, l);
32
- } else {
33
- r ||= d(s.resolve(T, "./app/view/entry.tpl"), "utf-8");
34
- let e = a.split(s.sep).at(-1), t = r.replace("<!-- {{InsertScript}} -->", `<script type="module" src="./${e}"><\/script>`), i = o.split(s.sep).at(-1), c = s.join(o, i + ".html");
35
- h(c, t), n[i] = c;
36
- }
64
+ m(M, {
65
+ recursive: !0,
66
+ force: !0
67
+ }), d(M, { recursive: !0 });
68
+ let r = f(s.resolve(D, "./app/view/entry.tpl"), "utf-8");
69
+ for (let e = 0; e < t.length; e++) {
70
+ let i = t[e], a = s.resolve(i, "../"), o = V(a, s.basename(i).replace(/\.entry\.[^.]+$/, "")), c = o ? s.basename(o, ".html") : a.split(s.sep).at(-1);
71
+ n[c] = U(r, i, c, o ? B(o) : I());
37
72
  }
38
73
  return n;
39
74
  }
40
- function j() {
75
+ function G() {
41
76
  let e = o.options.output ?? "frame";
42
- return e !== "frame" && r("Please pay attention to the build output."), e === "run" ? s.join(D, "./app/public/dist") : typeof e == "function" ? e() : s.join(T, "./app/public/dist");
77
+ return e !== "frame" && r("Please pay attention to the build output."), e === "run" ? s.join(k, "./app/public/dist") : typeof e == "function" ? e() : s.join(D, "./app/public/dist");
43
78
  }
44
- var M = async (e) => {
45
- let t = (await import("chokidar")).watch(O, {
79
+ var K = async (e) => {
80
+ let t = (await import("chokidar")).watch(A, {
46
81
  ignored: /(^|[\/\\])\../,
47
82
  persistent: !0,
48
83
  ignoreInitial: !0
@@ -58,15 +93,15 @@ var M = async (e) => {
58
93
  n = !1;
59
94
  }
60
95
  }
61
- }), a(`watching ${O}/...`);
96
+ }), a(`watching ${A}/...`);
62
97
  };
63
- function N(e = ".html") {
98
+ function q(e = ".html") {
64
99
  let t = [...new Set(Array.isArray(e) ? e : [e])];
65
100
  return {
66
101
  name: "flatten-html",
67
102
  apply: "build",
68
103
  closeBundle() {
69
- let e = j();
104
+ let e = G();
70
105
  if (!u(e)) return;
71
106
  let n = c.sync("**/*.html", {
72
107
  cwd: e,
@@ -79,11 +114,11 @@ function N(e = ".html") {
79
114
  let t = i + r, a = s.join(e, t);
80
115
  n !== a && l(n, a);
81
116
  }
82
- t.some((t) => n === s.join(e, i + t)) || m(n);
117
+ t.some((t) => n === s.join(e, i + t)) || g(n);
83
118
  }
84
119
  let r = [...new Set(n.map((e) => s.dirname(e)))].sort().reverse(), i = (e) => {
85
- if (!(u(e) ? f(e) : [1]).length) {
86
- p(e);
120
+ if (!(u(e) ? p(e) : [1]).length) {
121
+ h(e);
87
122
  let t = e.split(s.sep).slice(0, -1);
88
123
  t.length && i(t.join(s.sep));
89
124
  }
@@ -97,7 +132,7 @@ function N(e = ".html") {
97
132
  }
98
133
  };
99
134
  }
100
- function P(e) {
135
+ function J(e) {
101
136
  let t = [
102
137
  "",
103
138
  ".ts",
@@ -105,73 +140,73 @@ function P(e) {
105
140
  ".js",
106
141
  ".jsx"
107
142
  ];
108
- return e.reduce((e, [n, r, i = O, a = "./defaultAlias"]) => {
109
- let o = t.map((e) => s.resolve(i, r + e)).find((e) => u(e)), c = s.resolve(x, a);
143
+ return e.reduce((e, [n, r, i = A, a = "./defaultAlias"]) => {
144
+ let o = t.map((e) => s.resolve(i, r + e)).find((e) => u(e)), c = s.resolve(C, a);
110
145
  return o && (c = o), e[n] = c, e;
111
146
  }, {});
112
147
  }
113
- var F = (...e) => new RegExp(e.join("[\\/]")), I = (e) => `_${e}_tcC`, L = async (e, i) => {
148
+ var Y = (...e) => new RegExp(e.join("[\\/]")), X = (e) => `_${e}_tcC`, Z = async (e, i) => {
114
149
  try {
115
- await g({
150
+ await v({
116
151
  configFile: !1,
117
152
  base: "/dist",
118
153
  plugins: [
119
154
  (await import("@vitejs/plugin-react")).default(),
120
- N([".tpl", ".html"]),
121
- _()
155
+ q([".tpl", ".html"]),
156
+ y()
122
157
  ],
123
158
  build: {
124
- outDir: j(),
159
+ outDir: G(),
125
160
  emptyOutDir: !0,
126
161
  sourcemap: i === "dev" ? "inline" : "hidden",
127
162
  rolldownOptions: {
128
163
  input: e,
129
164
  output: { codeSplitting: { groups: [
130
165
  {
131
- name: I("__nm"),
132
- test: F("node_modules"),
166
+ name: X("__nm"),
167
+ test: Y("node_modules"),
133
168
  maxSize: 5e5,
134
169
  minShareCount: 2,
135
170
  priority: 1
136
171
  },
137
172
  {
138
- name: I("r"),
139
- test: F("node_modules", "react"),
173
+ name: X("r"),
174
+ test: Y("node_modules", "react"),
140
175
  minShareCount: 2,
141
176
  maxSize: 5e5,
142
177
  priority: 5
143
178
  },
144
179
  {
145
- name: I("r-d"),
146
- test: F("node_modules", "react-dom"),
180
+ name: X("r-d"),
181
+ test: Y("node_modules", "react-dom"),
147
182
  minShareCount: 2,
148
183
  maxSize: 2e5,
149
184
  priority: 10
150
185
  },
151
186
  {
152
- name: I("r-r-d"),
153
- test: F("node_modules", "react-router-dom"),
187
+ name: X("r-r-d"),
188
+ test: Y("node_modules", "react-router-dom"),
154
189
  minShareCount: 2,
155
190
  maxSize: 5e5,
156
191
  priority: 10
157
192
  },
158
193
  {
159
- name: I("ajv"),
160
- test: F("node_modules", "ajv"),
194
+ name: X("ajv"),
195
+ test: Y("node_modules", "ajv"),
161
196
  minShareCount: 2,
162
197
  maxSize: 2e5,
163
198
  priority: 10
164
199
  },
165
200
  {
166
- name: I("ui-lib"),
167
- test: F("components"),
201
+ name: X("ui-lib"),
202
+ test: Y("components"),
168
203
  minShareCount: 2,
169
204
  maxSize: 2e5,
170
205
  priority: 5
171
206
  },
172
207
  {
173
- name: I("ui-f-lib"),
174
- test: F("components", ".*?[Ff]orm.*?"),
208
+ name: X("ui-f-lib"),
209
+ test: Y("components", ".*?[Ff]orm.*?"),
175
210
  minShareCount: 2,
176
211
  maxSize: 5e4,
177
212
  priority: 10
@@ -180,15 +215,15 @@ var F = (...e) => new RegExp(e.join("[\\/]")), I = (e) => `_${e}_tcC`, L = async
180
215
  }
181
216
  },
182
217
  resolve: { alias: {
183
- react: k("react"),
184
- "react-dom": k("react-dom"),
185
- "@tc/ui-react/hooks": s.resolve(x, "../../fe/packages/react/hooks/"),
186
- "@tc/ui-react": s.resolve(x, "../../fe/packages/react/ui/"),
187
- ...P([
218
+ react: j("react"),
219
+ "react-dom": j("react-dom"),
220
+ "@tc/ui-react/hooks": s.resolve(C, "../../fe/packages/react/hooks/"),
221
+ "@tc/ui-react": s.resolve(C, "../../fe/packages/react/ui/"),
222
+ ...J([
188
223
  [
189
224
  "@tc/scalability/SchemaForm/frameData",
190
225
  "./extended/SchemaForm/data",
191
- E
226
+ O
192
227
  ],
193
228
  ["@tc/scalability/SchemaForm/data", "./extended/SchemaForm/data"],
194
229
  ["@tc/scalability/SchemaPage/CallCom/data", "./extended/SchemaPage/CallCom/data"],
@@ -208,4 +243,4 @@ var F = (...e) => new RegExp(e.join("[\\/]")), I = (e) => `_${e}_tcC`, L = async
208
243
  }
209
244
  };
210
245
  //#endregion
211
- export { L as VBuildFE, A as entries, j as outDir, M as watchFiles };
246
+ export { Z as VBuildFE, W as entries, G as outDir, K as watchFiles };
@@ -1,5 +1,5 @@
1
- import type { FormFieldType, FormItemProps, SchemaFormAllPropsMap } from "../../../packages/react/ui/index";
2
1
  import type { BuiltInCallComConfigMap } from "../../../frontend/src/defaultPages/SchemaPage/components/CallCom/builtIn";
2
+ import type { FormFieldType, FormItemProps, SchemaFormAllPropsMap } from "../../../packages/react/ui/index";
3
3
  export type { BuiltInCallComConfigMap, BuiltInCallComNames } from "../../../frontend/src/defaultPages/SchemaPage/components/CallCom/builtIn";
4
4
  export declare namespace CallComNamespace {
5
5
  interface ConfigMap {
@@ -11,7 +11,7 @@ export type ComponentConfig = BuiltInCallComConfigMap & Partial<CallComNamespace
11
11
  export type ComponentNames = Extract<keyof ComponentConfig, string>;
12
12
  type FormComponentOption = FormItemProps & {
13
13
  visible?: boolean;
14
- disbaled?: boolean;
14
+ disabled?: boolean;
15
15
  default?: any;
16
16
  } & ComponentOption;
17
17
  export type BuiltInCallComOptionMap = {
@@ -1,5 +1,5 @@
1
- import type { FormFieldType, FormItemProps, SchemaFormAllPropsMap } from "../../../../fe/packages/react/ui/index";
2
1
  import type { BuiltInCallComConfigMap } from "../../../../fe/frontend/src/defaultPages/SchemaPage/components/CallCom/builtIn";
2
+ import type { FormFieldType, FormItemProps, SchemaFormAllPropsMap } from "../../../../fe/packages/react/ui/index";
3
3
  export type { BuiltInCallComConfigMap, BuiltInCallComNames } from "../../../../fe/frontend/src/defaultPages/SchemaPage/components/CallCom/builtIn";
4
4
  export declare namespace CallComNamespace {
5
5
  interface ConfigMap {
@@ -11,7 +11,7 @@ export type ComponentConfig = BuiltInCallComConfigMap & Partial<CallComNamespace
11
11
  export type ComponentNames = Extract<keyof ComponentConfig, string>;
12
12
  type FormComponentOption = FormItemProps & {
13
13
  visible?: boolean;
14
- disbaled?: boolean;
14
+ disabled?: boolean;
15
15
  default?: any;
16
16
  } & ComponentOption;
17
17
  export type BuiltInCallComOptionMap = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@_tc/template-core",
3
- "version": "0.0.1-bate.52",
3
+ "version": "0.0.1-bate.54",
4
4
  "description": "A full-stack TypeScript admin framework powered by Koa, React, and Vite - monorepo root",
5
5
  "types": "./types/index.d.ts",
6
6
  "exports": {
@@ -46,7 +46,7 @@
46
46
  },
47
47
  "./fe/tailwind_ui.css": "./fe/frontend/src/main.css",
48
48
  "./model": {
49
- "types": "./model/index.d.ts"
49
+ "types": "./model/model/index.d.ts"
50
50
  }
51
51
  },
52
52
  "dependencies": {
@@ -1,4 +1,4 @@
1
1
  import type { BuildFEOptions } from "./state";
2
2
  export { buildBE } from "./buildBE";
3
3
  export type { BuildBEAlias, BuildBEFormat, BuildBEOptions, BuildBEResult } from "./buildBE";
4
- export declare const buildFE: (mode: "dev" | "prod", options?: BuildFEOptions) => void;
4
+ export declare const buildFE: (mode: "dev" | "prod", options?: BuildFEOptions) => Promise<void>;