@lark-apaas/coding-templates 0.1.35 → 0.1.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/template-apex/README.md +11 -9
- package/template-apex/client/src/app.tsx +7 -9
- package/template-apex/client/src/main.tsx +6 -4
- package/template-apex/package.json +8 -5
- package/template-apex/server/db/schema.ts +1 -11
- package/template-apex/server/index.ts +3 -21
- package/template-apex/server/routes/index.ts +6 -2
- package/template-apex/server/routes/view.ts +16 -0
- package/template-apex/tsconfig.server.json +0 -2
- package/template-vite-react/client/src/app.tsx +7 -9
- package/template-vite-react/client/src/main.tsx +6 -4
- package/template-vite-react/package.json +5 -7
- package/template-apex/_env.local.example +0 -1
- package/template-apex/package-lock.json +0 -11958
- package/template-vite-react/package-lock.json +0 -10316
package/package.json
CHANGED
package/template-apex/README.md
CHANGED
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
|
|
20
20
|
```
|
|
21
21
|
├── client/src/ # 前端代码
|
|
22
|
-
│ ├──
|
|
22
|
+
│ ├── main.tsx # 入口(Provider 层级 + 样式引入,勿修改)
|
|
23
|
+
│ ├── app.tsx # 路由配置
|
|
23
24
|
│ ├── index.css # 全局样式 + 主题变量
|
|
24
25
|
│ ├── api/ # API 请求封装
|
|
25
26
|
│ │ └── index.ts
|
|
@@ -34,12 +35,12 @@
|
|
|
34
35
|
│ ├── hooks/ # 自定义 Hooks
|
|
35
36
|
│ └── lib/ # 工具函数(cn() 等)
|
|
36
37
|
├── server/ # 后端代码
|
|
37
|
-
│ ├── index.ts # Express
|
|
38
|
-
│ ├── routes/ #
|
|
39
|
-
│ │
|
|
38
|
+
│ ├── index.ts # Express 入口
|
|
39
|
+
│ ├── routes/ # 路由
|
|
40
|
+
│ │ ├── index.ts # 路由注册
|
|
41
|
+
│ │ └── view.ts # 页面渲染(catch-all HTML 响应,勿修改)
|
|
40
42
|
│ └── db/ # 数据库层
|
|
41
|
-
│ ├── schema.ts # Drizzle schema
|
|
42
|
-
│ └── index.ts # 数据库连接
|
|
43
|
+
│ ├── schema.ts # Drizzle schema 定义(工具自动生成,勿手动修改)
|
|
43
44
|
├── shared/ # 前后端共享(不依赖 client 或 server)
|
|
44
45
|
│ ├── types.ts # 数据模型类型
|
|
45
46
|
│ └── api.interface.ts # zod schema + API 入参/出参类型
|
|
@@ -76,7 +77,7 @@ export type ListPostsResponse = Post[];
|
|
|
76
77
|
|
|
77
78
|
### 2. server/ — 数据库和路由
|
|
78
79
|
|
|
79
|
-
`server/db/schema.ts`
|
|
80
|
+
`server/db/schema.ts` 由 `npm run gen:db-schema` 自动生成,无需手动编写。运行命令后会根据数据库表结构自动生成如下定义:
|
|
80
81
|
|
|
81
82
|
```typescript
|
|
82
83
|
export const posts = pgTable("posts", {
|
|
@@ -91,7 +92,7 @@ export const posts = pgTable("posts", {
|
|
|
91
92
|
|
|
92
93
|
```typescript
|
|
93
94
|
import { Router } from "express";
|
|
94
|
-
import { db } from "
|
|
95
|
+
import { db } from "@lark-apaas/express-core";
|
|
95
96
|
import { posts } from "../db/schema";
|
|
96
97
|
import { createPostSchema } from "@shared/api.interface";
|
|
97
98
|
|
|
@@ -120,11 +121,12 @@ app.use("/api/posts", postsRouter);
|
|
|
120
121
|
|
|
121
122
|
> ⚠️ **客户端所有 HTTP 请求必须使用 `axiosForBackend`**
|
|
122
123
|
>
|
|
123
|
-
> `axiosForBackend` 由 `@lark-apaas/client-toolkit-lite`
|
|
124
|
+
> `axiosForBackend` 由 `@lark-apaas/client-toolkit-lite` 提供,内置平台鉴权、CSRF token 注入和请求上下文。**禁止使用** `fetch`、`axios`、`XMLHttpRequest` 或其他 HTTP 客户端直接发起请求。
|
|
124
125
|
|
|
125
126
|
`client/src/api/index.ts` 增加封装:
|
|
126
127
|
|
|
127
128
|
```typescript
|
|
129
|
+
import { axiosForBackend } from "@lark-apaas/client-toolkit-lite";
|
|
128
130
|
import type { ListPostsResponse } from "@shared/api.interface";
|
|
129
131
|
|
|
130
132
|
export async function listPosts(): Promise<ListPostsResponse> {
|
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Routes, Route } from "react-router-dom";
|
|
2
2
|
import { Layout } from "@/components/layout";
|
|
3
3
|
import HomePage from "@/pages/HomePage/HomePage";
|
|
4
4
|
import NotFoundPage from "@/pages/NotFoundPage/NotFoundPage";
|
|
5
5
|
|
|
6
6
|
export default function App() {
|
|
7
7
|
return (
|
|
8
|
-
<
|
|
9
|
-
<
|
|
10
|
-
<Route element={<
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
</Routes>
|
|
15
|
-
</BrowserRouter>
|
|
8
|
+
<Routes>
|
|
9
|
+
<Route element={<Layout />}>
|
|
10
|
+
<Route index element={<HomePage />} />
|
|
11
|
+
<Route path="*" element={<NotFoundPage />} />
|
|
12
|
+
</Route>
|
|
13
|
+
</Routes>
|
|
16
14
|
);
|
|
17
15
|
}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { StrictMode } from "react";
|
|
2
2
|
import { createRoot } from "react-dom/client";
|
|
3
|
+
import { BrowserRouter } from "react-router-dom";
|
|
3
4
|
import { AppContainer } from "@lark-apaas/client-toolkit-lite";
|
|
4
|
-
import "@lark-apaas/client-toolkit-lite/styles.css";
|
|
5
5
|
import App from "./app";
|
|
6
6
|
import "./index.css";
|
|
7
7
|
|
|
8
8
|
createRoot(document.getElementById("root")!).render(
|
|
9
9
|
<StrictMode>
|
|
10
|
-
<
|
|
11
|
-
<
|
|
12
|
-
|
|
10
|
+
<BrowserRouter basename={process.env.CLIENT_BASE_PATH || "/"}>
|
|
11
|
+
<AppContainer>
|
|
12
|
+
<App />
|
|
13
|
+
</AppContainer>
|
|
14
|
+
</BrowserRouter>
|
|
13
15
|
</StrictMode>,
|
|
14
16
|
);
|
|
@@ -11,11 +11,11 @@
|
|
|
11
11
|
]
|
|
12
12
|
},
|
|
13
13
|
"scripts": {
|
|
14
|
-
"dev": "tsx --watch --watch-path server --watch-path shared server/index.ts",
|
|
15
14
|
"build": "bash scripts/build.sh",
|
|
16
|
-
"typecheck": "npm
|
|
15
|
+
"typecheck": "concurrently npm:typecheck:client npm:typecheck:server",
|
|
17
16
|
"typecheck:client": "tsc -p tsconfig.app.json",
|
|
18
|
-
"
|
|
17
|
+
"typecheck:server": "tsc --noEmit -p tsconfig.server.json",
|
|
18
|
+
"lint": "concurrently npm:typecheck npm:lint:client npm:lint:server",
|
|
19
19
|
"lint:client": "eslint client/src",
|
|
20
20
|
"lint:server": "eslint server",
|
|
21
21
|
"gen:db-schema": "npx -y @lark-apaas/db-schema-sync@latest --output server/db/schema.ts"
|
|
@@ -48,8 +48,8 @@
|
|
|
48
48
|
"@radix-ui/react-toggle": "^1.1.9",
|
|
49
49
|
"@radix-ui/react-toggle-group": "^1.1.10",
|
|
50
50
|
"@radix-ui/react-tooltip": "^1.1.18",
|
|
51
|
-
"@lark-apaas/client-toolkit-lite": "^1.
|
|
52
|
-
"@lark-apaas/express-core": "^0.0
|
|
51
|
+
"@lark-apaas/client-toolkit-lite": "^1.1.0",
|
|
52
|
+
"@lark-apaas/express-core": "^1.0.0",
|
|
53
53
|
"@formkit/auto-animate": "^0.9.0",
|
|
54
54
|
"framer-motion": "^12.38.0",
|
|
55
55
|
"class-variance-authority": "^0.7.1",
|
|
@@ -57,6 +57,8 @@
|
|
|
57
57
|
"cmdk": "^1.1.1",
|
|
58
58
|
"date-fns": "^4.1.0",
|
|
59
59
|
"drizzle-orm": "0.44.6",
|
|
60
|
+
"echarts": "~5.6.0",
|
|
61
|
+
"echarts-for-react": "~3.0.2",
|
|
60
62
|
"embla-carousel-react": "^8.6.0",
|
|
61
63
|
"express": "^5.1.0",
|
|
62
64
|
"hbs": "^4.2.0",
|
|
@@ -85,6 +87,7 @@
|
|
|
85
87
|
"@types/node": "^24",
|
|
86
88
|
"@types/react": "^19",
|
|
87
89
|
"@types/react-dom": "^19",
|
|
90
|
+
"concurrently": "^9",
|
|
88
91
|
"eslint": "^9",
|
|
89
92
|
"tsc-alias": "^1.8.15",
|
|
90
93
|
"tsx": "^4",
|
|
@@ -1,11 +1 @@
|
|
|
1
|
-
|
|
2
|
-
//
|
|
3
|
-
// import { pgTable, serial, text, timestamp } from "drizzle-orm/pg-core";
|
|
4
|
-
//
|
|
5
|
-
// 使用示例:
|
|
6
|
-
// export const posts = pgTable("posts", {
|
|
7
|
-
// id: serial("id").primaryKey(),
|
|
8
|
-
// title: text("title").notNull(),
|
|
9
|
-
// content: text("content"),
|
|
10
|
-
// createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
11
|
-
// });
|
|
1
|
+
/* 该文件通过 npm run gen:db-schema 自动生成*/
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
import express
|
|
2
|
-
import
|
|
3
|
-
import fs from "fs";
|
|
4
|
-
import hbs from "hbs";
|
|
5
|
-
import { setup, createViewContextMiddleware } from "@lark-apaas/express-core";
|
|
6
|
-
import * as schema from "./db/schema";
|
|
1
|
+
import express from "express";
|
|
2
|
+
import { setup } from "@lark-apaas/express-core";
|
|
7
3
|
import { registerRoutes } from "./routes/index";
|
|
8
4
|
|
|
9
5
|
const port = Number(process.env.FORCE_SERVER_PORT) || 3000;
|
|
@@ -13,26 +9,12 @@ const basePath = process.env.CLIENT_BASE_PATH || "/";
|
|
|
13
9
|
const app = express();
|
|
14
10
|
|
|
15
11
|
// Platform middleware
|
|
16
|
-
const { close } = setup(app
|
|
17
|
-
database: { schema },
|
|
18
|
-
csrf: { enabled: false },
|
|
19
|
-
viewContext: { enabled: false },
|
|
20
|
-
});
|
|
12
|
+
const { close } = setup(app);
|
|
21
13
|
|
|
22
14
|
// All routes under basePath
|
|
23
15
|
const router = express.Router();
|
|
24
16
|
registerRoutes(router);
|
|
25
17
|
|
|
26
|
-
const templatePath = path.resolve(__dirname, "../index.html");
|
|
27
|
-
const template = hbs.compile(fs.readFileSync(templatePath, "utf-8"));
|
|
28
|
-
|
|
29
|
-
router.get("/{*path}", createViewContextMiddleware(), (_req: Request, res: Response) => {
|
|
30
|
-
const html = template({
|
|
31
|
-
...res.locals,
|
|
32
|
-
});
|
|
33
|
-
res.type("html").send(html);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
18
|
app.use(basePath, router);
|
|
37
19
|
|
|
38
20
|
const server = app.listen(port, host, () => {
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import type { Router } from "express";
|
|
2
|
+
import { registerViewRoute } from "./view";
|
|
2
3
|
// import postsRouter from "./posts";
|
|
3
4
|
|
|
4
|
-
export function registerRoutes(
|
|
5
|
+
export function registerRoutes(router: Router) {
|
|
5
6
|
// 在此注册 API 路由
|
|
6
7
|
//
|
|
7
8
|
// 使用示例:
|
|
8
|
-
//
|
|
9
|
+
// router.use("/api/posts", postsRouter);
|
|
10
|
+
|
|
11
|
+
// HTML 页面渲染(catch-all,必须放在最后)
|
|
12
|
+
registerViewRoute(router);
|
|
9
13
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import hbs from "hbs";
|
|
4
|
+
import type { Request, Response, Router } from "express";
|
|
5
|
+
|
|
6
|
+
const templatePath = path.resolve(__dirname, "../../index.html");
|
|
7
|
+
const template = hbs.compile(fs.readFileSync(templatePath, "utf-8"));
|
|
8
|
+
|
|
9
|
+
export function registerViewRoute(router: Router) {
|
|
10
|
+
router.get("/{*path}", (_req: Request, res: Response) => {
|
|
11
|
+
const html = template({
|
|
12
|
+
...res.locals,
|
|
13
|
+
});
|
|
14
|
+
res.type("html").send(html);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
@@ -5,11 +5,9 @@
|
|
|
5
5
|
"rootDir": ".",
|
|
6
6
|
"module": "commonjs",
|
|
7
7
|
"moduleResolution": "node",
|
|
8
|
-
"verbatimModuleSyntax": false,
|
|
9
8
|
"esModuleInterop": true,
|
|
10
9
|
"noEmit": false,
|
|
11
10
|
"allowImportingTsExtensions": false,
|
|
12
|
-
"noUnusedParameters": false,
|
|
13
11
|
"baseUrl": ".",
|
|
14
12
|
"paths": {
|
|
15
13
|
"@shared/*": ["./shared/*"]
|
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Routes, Route } from "react-router-dom";
|
|
2
2
|
import { Layout } from "@/components/layout";
|
|
3
3
|
import HomePage from "@/pages/HomePage/HomePage";
|
|
4
4
|
import NotFoundPage from "@/pages/NotFoundPage/NotFoundPage";
|
|
5
5
|
|
|
6
6
|
export default function App() {
|
|
7
7
|
return (
|
|
8
|
-
<
|
|
9
|
-
<
|
|
10
|
-
<Route element={<
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
</Routes>
|
|
15
|
-
</BrowserRouter>
|
|
8
|
+
<Routes>
|
|
9
|
+
<Route element={<Layout />}>
|
|
10
|
+
<Route index element={<HomePage />} />
|
|
11
|
+
<Route path="*" element={<NotFoundPage />} />
|
|
12
|
+
</Route>
|
|
13
|
+
</Routes>
|
|
16
14
|
);
|
|
17
15
|
}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { StrictMode } from "react";
|
|
2
2
|
import { createRoot } from "react-dom/client";
|
|
3
|
+
import { BrowserRouter } from "react-router-dom";
|
|
3
4
|
import { AppContainer } from "@lark-apaas/client-toolkit-lite";
|
|
4
|
-
import "@lark-apaas/client-toolkit-lite/styles.css";
|
|
5
5
|
import App from "./app";
|
|
6
6
|
import "./index.css";
|
|
7
7
|
|
|
8
8
|
createRoot(document.getElementById("root")!).render(
|
|
9
9
|
<StrictMode>
|
|
10
|
-
<
|
|
11
|
-
<
|
|
12
|
-
|
|
10
|
+
<BrowserRouter basename={process.env.CLIENT_BASE_PATH || "/"}>
|
|
11
|
+
<AppContainer>
|
|
12
|
+
<App />
|
|
13
|
+
</AppContainer>
|
|
14
|
+
</BrowserRouter>
|
|
13
15
|
</StrictMode>,
|
|
14
16
|
);
|
|
@@ -10,13 +10,10 @@
|
|
|
10
10
|
]
|
|
11
11
|
},
|
|
12
12
|
"scripts": {
|
|
13
|
-
"dev": "vite",
|
|
14
13
|
"build": "bash scripts/build.sh",
|
|
15
|
-
"typecheck": "
|
|
16
|
-
"
|
|
17
|
-
"lint": "
|
|
18
|
-
"lint:client": "eslint client/src",
|
|
19
|
-
"preview": "vite preview"
|
|
14
|
+
"typecheck": "tsc -p tsconfig.app.json",
|
|
15
|
+
"lint": "concurrently npm:typecheck npm:lint:eslint",
|
|
16
|
+
"lint:eslint": "eslint client/src"
|
|
20
17
|
},
|
|
21
18
|
"dependencies": {
|
|
22
19
|
"@hookform/resolvers": "^5.2.2",
|
|
@@ -46,7 +43,7 @@
|
|
|
46
43
|
"@radix-ui/react-toggle": "^1.1.9",
|
|
47
44
|
"@radix-ui/react-toggle-group": "^1.1.10",
|
|
48
45
|
"@radix-ui/react-tooltip": "^1.1.18",
|
|
49
|
-
"@lark-apaas/client-toolkit-lite": "^1.
|
|
46
|
+
"@lark-apaas/client-toolkit-lite": "^1.1.0",
|
|
50
47
|
"@formkit/auto-animate": "^0.9.0",
|
|
51
48
|
"framer-motion": "^12.38.0",
|
|
52
49
|
"class-variance-authority": "^0.7.1",
|
|
@@ -80,6 +77,7 @@
|
|
|
80
77
|
"@types/react-dom": "^19",
|
|
81
78
|
"@lark-apaas/coding-presets": "^1.0.0",
|
|
82
79
|
"@lark-apaas/coding-vite-preset": "^1.0.0",
|
|
80
|
+
"concurrently": "^9",
|
|
83
81
|
"eslint": "^9",
|
|
84
82
|
"eslint-plugin-react-hooks": "^7",
|
|
85
83
|
"eslint-plugin-react-refresh": "^0.5",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/openclaw
|