@lark-apaas/fullstack-nestjs-core 1.0.3-alpha.9 → 1.0.3
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/README.md +239 -124
- package/dist/index.cjs +65 -29
- package/dist/index.d.cts +34 -12
- package/dist/index.d.ts +34 -12
- package/dist/index.js +52 -17
- package/package.json +4 -8
package/README.md
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
# @lark-apaas/fullstack-nestjs-core
|
|
2
2
|
|
|
3
|
-
FullStack NestJS Core 是一个为 NestJS
|
|
3
|
+
FullStack NestJS Core 是一个为 NestJS 全栈应用提供核心功能的工具包,包括平台集成、CSRF 保护、用户上下文管理和开发工具等。
|
|
4
4
|
|
|
5
5
|
## 特性
|
|
6
6
|
|
|
7
|
+
- **平台模块**: 一站式集成 Config、Logger、Database、Auth 等核心功能
|
|
7
8
|
- **CSRF 保护**: 提供完整的 CSRF Token 生成和验证机制
|
|
8
9
|
- **用户上下文**: 自动从请求头中提取并注入用户上下文信息
|
|
9
|
-
-
|
|
10
|
+
- **视图上下文**: 将用户信息和 CSRF Token 注入到模板渲染上下文
|
|
11
|
+
- **开发工具**: 自动生成 Swagger 文档、OpenAPI JSON 和 TypeScript 客户端 SDK
|
|
12
|
+
- **应用配置**: 一键配置 Logger、Cookie Parser、全局前缀等
|
|
10
13
|
|
|
11
14
|
## 安装
|
|
12
15
|
|
|
@@ -27,226 +30,330 @@ yarn add @lark-apaas/fullstack-nestjs-core
|
|
|
27
30
|
|
|
28
31
|
## 快速开始
|
|
29
32
|
|
|
30
|
-
### 1
|
|
33
|
+
### 方案 1: 使用 PlatformModule(推荐)
|
|
31
34
|
|
|
32
|
-
|
|
35
|
+
最简单的方式是使用 `PlatformModule`,它会自动集成所有核心功能:
|
|
33
36
|
|
|
34
|
-
|
|
37
|
+
```typescript
|
|
38
|
+
import { Module } from '@nestjs/common';
|
|
39
|
+
import { PlatformModule } from '@lark-apaas/fullstack-nestjs-core';
|
|
40
|
+
|
|
41
|
+
@Module({
|
|
42
|
+
imports: [
|
|
43
|
+
PlatformModule.forRoot({
|
|
44
|
+
enableCsrf: true, // 是否启用 CSRF 保护,默认 true
|
|
45
|
+
csrfRoutes: '/api/*', // CSRF 保护的路由,默认 '/api/*'
|
|
46
|
+
alwaysNeedLogin: true, // 是否所有路由都需要登录,默认 true
|
|
47
|
+
}),
|
|
48
|
+
],
|
|
49
|
+
})
|
|
50
|
+
export class AppModule {}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`PlatformModule` 自动集成:
|
|
54
|
+
- ✅ ConfigModule (环境变量配置)
|
|
55
|
+
- ✅ LoggerModule (日志系统)
|
|
56
|
+
- ✅ DataPaasModule (数据库连接)
|
|
57
|
+
- ✅ AuthNPaasModule (认证系统)
|
|
58
|
+
- ✅ UserContextMiddleware (用户上下文)
|
|
59
|
+
- ✅ CsrfTokenMiddleware + CsrfMiddleware (CSRF 保护)
|
|
60
|
+
- ✅ ViewContextMiddleware (视图上下文)
|
|
61
|
+
- ✅ ValidationPipe (全局验证管道)
|
|
62
|
+
|
|
63
|
+
### 方案 2: 使用 configureApp 辅助函数
|
|
64
|
+
|
|
65
|
+
在 `main.ts` 中使用 `configureApp` 快速配置应用:
|
|
35
66
|
|
|
36
67
|
```typescript
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
68
|
+
import { NestFactory } from '@nestjs/core';
|
|
69
|
+
import { NestExpressApplication } from '@nestjs/platform-express';
|
|
70
|
+
import { configureApp } from '@lark-apaas/fullstack-nestjs-core';
|
|
71
|
+
import { AppModule } from './app.module';
|
|
39
72
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
configure(consumer: MiddlewareConsumer) {
|
|
43
|
-
// 直接应用中间件,使用默认配置
|
|
44
|
-
consumer
|
|
45
|
-
.apply(CsrfTokenMiddleware)
|
|
46
|
-
.forRoutes('*'); // 所有路由都生成 token
|
|
73
|
+
async function bootstrap() {
|
|
74
|
+
const app = await NestFactory.create<NestExpressApplication>(AppModule);
|
|
47
75
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
76
|
+
// 一键配置:Logger、CookieParser、GlobalPrefix、DevTools
|
|
77
|
+
await configureApp(app);
|
|
78
|
+
|
|
79
|
+
await app.listen(3000);
|
|
52
80
|
}
|
|
81
|
+
bootstrap();
|
|
53
82
|
```
|
|
54
83
|
|
|
55
|
-
|
|
84
|
+
`configureApp` 会自动:
|
|
85
|
+
- ✅ 注册 AppLogger
|
|
86
|
+
- ✅ 注册 cookie-parser 中间件
|
|
87
|
+
- ✅ 根据 `CLIENT_BASE_PATH` 环境变量设置全局前缀
|
|
88
|
+
- ✅ 在非生产环境自动挂载 `DevToolsV2Module`
|
|
89
|
+
|
|
90
|
+
### 方案 3: 手动配置各个模块
|
|
56
91
|
|
|
57
|
-
|
|
92
|
+
如果需要更细粒度的控制,可以单独使用各个模块:
|
|
58
93
|
|
|
59
94
|
```typescript
|
|
60
95
|
import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
|
|
61
|
-
import {
|
|
96
|
+
import {
|
|
97
|
+
CsrfTokenMiddleware,
|
|
98
|
+
CsrfMiddleware,
|
|
99
|
+
UserContextMiddleware,
|
|
100
|
+
ViewContextMiddleware,
|
|
101
|
+
} from '@lark-apaas/fullstack-nestjs-core';
|
|
62
102
|
|
|
63
103
|
@Module({})
|
|
64
104
|
export class AppModule implements NestModule {
|
|
65
105
|
configure(consumer: MiddlewareConsumer) {
|
|
66
|
-
//
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
cookiePath: '/', // 默认: '/'
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
// 自定义配置 CSRF 验证中间件
|
|
74
|
-
CsrfMiddleware.configure({
|
|
75
|
-
headerKey: 'X-CSRF-TOKEN', // 默认: 'x-suda-csrf-token'
|
|
76
|
-
cookieKey: 'CSRF-TOKEN', // 默认: 'suda-csrf-token'
|
|
77
|
-
});
|
|
106
|
+
// 用户上下文中间件
|
|
107
|
+
consumer
|
|
108
|
+
.apply(UserContextMiddleware)
|
|
109
|
+
.forRoutes('*');
|
|
78
110
|
|
|
79
|
-
//
|
|
111
|
+
// CSRF Token 生成(用于视图渲染)
|
|
80
112
|
consumer
|
|
81
113
|
.apply(CsrfTokenMiddleware)
|
|
114
|
+
.exclude('/api/(.*)')
|
|
82
115
|
.forRoutes('*');
|
|
83
116
|
|
|
117
|
+
// 视图上下文注入
|
|
84
118
|
consumer
|
|
85
|
-
.apply(
|
|
119
|
+
.apply(ViewContextMiddleware)
|
|
120
|
+
.exclude('/api/(.*)')
|
|
86
121
|
.forRoutes('*');
|
|
122
|
+
|
|
123
|
+
// CSRF 验证(用于 API 保护)
|
|
124
|
+
consumer
|
|
125
|
+
.apply(CsrfMiddleware)
|
|
126
|
+
.forRoutes('/api/*');
|
|
87
127
|
}
|
|
88
128
|
}
|
|
89
129
|
```
|
|
90
130
|
|
|
91
|
-
|
|
131
|
+
## 核心模块
|
|
92
132
|
|
|
93
|
-
###
|
|
133
|
+
### PlatformModule
|
|
94
134
|
|
|
95
|
-
|
|
135
|
+
全局平台模块,集成了所有核心功能。
|
|
96
136
|
|
|
97
|
-
|
|
98
|
-
import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
|
|
99
|
-
import { UserContextMiddleware } from '@lark-apaas/fullstack-nestjs-core';
|
|
137
|
+
#### 配置选项
|
|
100
138
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
.forRoutes('*');
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
```
|
|
139
|
+
| 选项 | 类型 | 默认值 | 描述 |
|
|
140
|
+
|------|------|--------|------|
|
|
141
|
+
| enableCsrf | boolean | `true` | 是否启用 CSRF 保护 |
|
|
142
|
+
| csrfRoutes | string \| string[] | `'/api/*'` | CSRF 保护应用的路由 |
|
|
143
|
+
| alwaysNeedLogin | boolean | `true` | 是否所有路由都需要登录 |
|
|
110
144
|
|
|
111
|
-
|
|
145
|
+
#### 使用示例
|
|
112
146
|
|
|
113
147
|
```typescript
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
}
|
|
125
|
-
}
|
|
148
|
+
@Module({
|
|
149
|
+
imports: [
|
|
150
|
+
PlatformModule.forRoot({
|
|
151
|
+
enableCsrf: true,
|
|
152
|
+
csrfRoutes: ['/api/*', '/admin/*'],
|
|
153
|
+
alwaysNeedLogin: false,
|
|
154
|
+
}),
|
|
155
|
+
],
|
|
156
|
+
})
|
|
157
|
+
export class AppModule {}
|
|
126
158
|
```
|
|
127
159
|
|
|
128
|
-
###
|
|
160
|
+
### DevToolsV2Module(推荐)
|
|
161
|
+
|
|
162
|
+
使用 `@hey-api/openapi-ts` 生成高质量的 TypeScript 客户端 SDK。
|
|
163
|
+
|
|
164
|
+
**新特性:**
|
|
165
|
+
- ✅ 使用最新的 `@hey-api/openapi-ts` 生成器
|
|
166
|
+
- ✅ 自动注入 `baseURL` 配置到生成的客户端
|
|
167
|
+
- ✅ 自动给所有生成的文件添加 `// @ts-nocheck` 注释
|
|
168
|
+
|
|
169
|
+
#### 配置选项
|
|
129
170
|
|
|
130
|
-
|
|
171
|
+
| 选项 | 类型 | 默认值 | 描述 |
|
|
172
|
+
|------|------|--------|------|
|
|
173
|
+
| basePath | string | `'/'` | API 基础路径 |
|
|
174
|
+
| docsPath | string | `'/api/docs'` | Swagger UI 的挂载路径 |
|
|
175
|
+
| openapiOut | string | `'./client/src/api/gen/openapi.json'` | OpenAPI JSON 输出路径 |
|
|
176
|
+
| needSetupServer | boolean | `false` | 是否挂载 Swagger UI 服务器 |
|
|
177
|
+
| needGenerateClientSdk | boolean | `true` | 是否生成客户端 SDK |
|
|
178
|
+
| clientSdkOut | string | `'./client/src/api/gen'` | 客户端 SDK 输出目录 |
|
|
179
|
+
| swaggerOptions | object | - | Swagger 文档配置 |
|
|
180
|
+
|
|
181
|
+
#### 使用示例
|
|
131
182
|
|
|
132
183
|
```typescript
|
|
133
184
|
import { NestFactory } from '@nestjs/core';
|
|
134
|
-
import {
|
|
185
|
+
import { DevToolsV2Module } from '@lark-apaas/fullstack-nestjs-core';
|
|
135
186
|
import { AppModule } from './app.module';
|
|
136
187
|
|
|
137
188
|
async function bootstrap() {
|
|
138
189
|
const app = await NestFactory.create(AppModule);
|
|
139
190
|
|
|
140
|
-
//
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
}
|
|
152
|
-
}
|
|
191
|
+
// 在开发环境挂载开发工具
|
|
192
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
193
|
+
await DevToolsV2Module.mount(app, {
|
|
194
|
+
basePath: '/app',
|
|
195
|
+
docsPath: '/api_docs',
|
|
196
|
+
needSetupServer: true,
|
|
197
|
+
needGenerateClientSdk: true,
|
|
198
|
+
swaggerOptions: {
|
|
199
|
+
title: 'My API',
|
|
200
|
+
version: '1.0.0',
|
|
201
|
+
},
|
|
202
|
+
});
|
|
203
|
+
}
|
|
153
204
|
|
|
154
205
|
await app.listen(3000);
|
|
155
206
|
}
|
|
156
207
|
bootstrap();
|
|
157
208
|
```
|
|
158
209
|
|
|
159
|
-
|
|
210
|
+
#### 生成的文件
|
|
211
|
+
|
|
212
|
+
```
|
|
213
|
+
client/src/api/gen/
|
|
214
|
+
├── openapi.json # OpenAPI 规范文件
|
|
215
|
+
├── client.config.ts # 客户端配置(自动生成 baseURL)
|
|
216
|
+
├── types.gen.ts # TypeScript 类型定义
|
|
217
|
+
├── sdk.gen.ts # SDK 函数
|
|
218
|
+
└── client/
|
|
219
|
+
└── client.gen.ts # Axios 客户端
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
所有生成的 `.ts` 文件都会自动添加 `// @ts-nocheck` 注释,避免类型检查错误。
|
|
223
|
+
|
|
224
|
+
### DevToolsModule(旧版)
|
|
225
|
+
|
|
226
|
+
使用 `openapi-typescript-codegen` 生成客户端 SDK(不推荐,建议迁移到 `DevToolsV2Module`)。
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
import { DevToolsModule } from '@lark-apaas/fullstack-nestjs-core';
|
|
230
|
+
|
|
231
|
+
await DevToolsModule.mount(app, {
|
|
232
|
+
docsPath: 'api-docs',
|
|
233
|
+
openapiOut: './openapi.json',
|
|
234
|
+
needSetupServer: true,
|
|
235
|
+
needGenerateClientSdk: true,
|
|
236
|
+
clientSdkOut: './src/sdk',
|
|
237
|
+
});
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## 中间件
|
|
160
241
|
|
|
161
242
|
### CsrfTokenMiddleware
|
|
162
243
|
|
|
163
|
-
生成 CSRF Token 并设置到 Cookie
|
|
244
|
+
生成 CSRF Token 并设置到 Cookie 中,用于视图渲染场景。
|
|
164
245
|
|
|
165
|
-
#### 配置选项
|
|
246
|
+
#### 配置选项
|
|
166
247
|
|
|
167
248
|
| 选项 | 类型 | 默认值 | 描述 |
|
|
168
249
|
|------|------|--------|------|
|
|
169
|
-
| cookieKey | string | `'suda-csrf-token'` | Cookie 中存储
|
|
170
|
-
| cookieMaxAge | number | `2592000000` (30天) | Cookie
|
|
171
|
-
| cookiePath | string | `'/'` | Cookie
|
|
250
|
+
| cookieKey | string | `'suda-csrf-token'` | Cookie 中存储 Token 的键名 |
|
|
251
|
+
| cookieMaxAge | number | `2592000000` (30天) | Cookie 过期时间(毫秒) |
|
|
252
|
+
| cookiePath | string | `'/'` | Cookie 路径 |
|
|
172
253
|
|
|
173
|
-
####
|
|
254
|
+
#### 使用示例
|
|
174
255
|
|
|
175
|
-
|
|
256
|
+
```typescript
|
|
257
|
+
CsrfTokenMiddleware.configure({
|
|
258
|
+
cookieKey: 'my-csrf-token',
|
|
259
|
+
cookieMaxAge: 86400000, // 1天
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
consumer
|
|
263
|
+
.apply(CsrfTokenMiddleware)
|
|
264
|
+
.exclude('/api/(.*)')
|
|
265
|
+
.forRoutes('*');
|
|
266
|
+
```
|
|
176
267
|
|
|
177
268
|
### CsrfMiddleware
|
|
178
269
|
|
|
179
|
-
验证请求中的 CSRF Token
|
|
270
|
+
验证请求中的 CSRF Token,用于保护 API 接口。
|
|
180
271
|
|
|
181
|
-
#### 配置选项
|
|
272
|
+
#### 配置选项
|
|
182
273
|
|
|
183
274
|
| 选项 | 类型 | 默认值 | 描述 |
|
|
184
275
|
|------|------|--------|------|
|
|
185
|
-
| headerKey | string | `'x-suda-csrf-token'` | 请求头中
|
|
186
|
-
| cookieKey | string | `'suda-csrf-token'` | Cookie 中
|
|
276
|
+
| headerKey | string | `'x-suda-csrf-token'` | 请求头中 Token 的键名 |
|
|
277
|
+
| cookieKey | string | `'suda-csrf-token'` | Cookie 中 Token 的键名 |
|
|
187
278
|
|
|
188
|
-
####
|
|
279
|
+
#### 使用示例
|
|
189
280
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
281
|
+
```typescript
|
|
282
|
+
CsrfMiddleware.configure({
|
|
283
|
+
headerKey: 'x-my-csrf-token',
|
|
284
|
+
cookieKey: 'my-csrf-token',
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
consumer
|
|
288
|
+
.apply(CsrfMiddleware)
|
|
289
|
+
.forRoutes('/api/*');
|
|
290
|
+
```
|
|
197
291
|
|
|
198
|
-
|
|
292
|
+
**注意**: 确保 `CsrfTokenMiddleware` 和 `CsrfMiddleware` 的 `cookieKey` 配置一致。
|
|
199
293
|
|
|
200
294
|
### UserContextMiddleware
|
|
201
295
|
|
|
202
|
-
|
|
296
|
+
从请求头中提取用户上下文信息并注入到 `req.userContext`。
|
|
203
297
|
|
|
204
298
|
#### 注入的上下文
|
|
205
299
|
|
|
206
300
|
```typescript
|
|
207
301
|
req.userContext = {
|
|
208
|
-
userId: string | undefined; // 用户 ID
|
|
209
|
-
tenantId: string | undefined; // 租户 ID
|
|
210
|
-
appId: string; // 应用 ID
|
|
302
|
+
userId: string | undefined; // 用户 ID(来自 x-user-id 请求头)
|
|
303
|
+
tenantId: string | undefined; // 租户 ID(来自 x-tenant-id 请求头)
|
|
304
|
+
appId: string; // 应用 ID(来自 x-app-id 请求头)
|
|
305
|
+
}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
#### 使用示例
|
|
309
|
+
|
|
310
|
+
```typescript
|
|
311
|
+
@Controller()
|
|
312
|
+
export class AppController {
|
|
313
|
+
@Get('profile')
|
|
314
|
+
getProfile(@Req() req: Request) {
|
|
315
|
+
const { userId, tenantId, appId } = req.userContext;
|
|
316
|
+
return { userId, tenantId, appId };
|
|
317
|
+
}
|
|
211
318
|
}
|
|
212
319
|
```
|
|
213
320
|
|
|
214
|
-
###
|
|
321
|
+
### ViewContextMiddleware
|
|
215
322
|
|
|
216
|
-
|
|
323
|
+
将用户上下文和 CSRF Token 注入到 `res.locals`,用于模板渲染。
|
|
217
324
|
|
|
218
|
-
####
|
|
325
|
+
#### 注入的变量
|
|
219
326
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
| swaggerOptions | object | - | Swagger 文档配置 |
|
|
229
|
-
| swaggerOptions.title | string | - | Swagger 文档标题 |
|
|
230
|
-
| swaggerOptions.version | string | - | API 版本号 |
|
|
231
|
-
| swaggerOptions.customSiteTitle | string | - | 自定义站点标题 |
|
|
232
|
-
| swaggerOptions.customCss | string | - | 自定义 CSS 样式 |
|
|
327
|
+
```typescript
|
|
328
|
+
res.locals = {
|
|
329
|
+
csrfToken: string; // CSRF Token
|
|
330
|
+
userId: string; // 用户 ID
|
|
331
|
+
tenantId: string; // 租户 ID
|
|
332
|
+
appId: string; // 应用 ID
|
|
333
|
+
}
|
|
334
|
+
```
|
|
233
335
|
|
|
234
|
-
####
|
|
336
|
+
#### 使用示例
|
|
235
337
|
|
|
236
|
-
|
|
338
|
+
```typescript
|
|
339
|
+
// 在模板引擎中可以直接使用这些变量
|
|
340
|
+
// EJS 示例:
|
|
341
|
+
<input type="hidden" name="_csrf" value="<%= csrfToken %>">
|
|
342
|
+
<div>User ID: <%= userId %></div>
|
|
343
|
+
```
|
|
237
344
|
|
|
238
345
|
## TypeScript 支持
|
|
239
346
|
|
|
240
347
|
本包完全使用 TypeScript 编写,并提供完整的类型定义。
|
|
241
348
|
|
|
242
|
-
扩展 Express Request
|
|
349
|
+
### 扩展 Express Request 类型
|
|
243
350
|
|
|
244
351
|
```typescript
|
|
245
352
|
declare global {
|
|
246
353
|
namespace Express {
|
|
247
354
|
interface Request {
|
|
248
355
|
csrfToken?: string;
|
|
249
|
-
userContext
|
|
356
|
+
userContext: {
|
|
250
357
|
userId?: string;
|
|
251
358
|
tenantId?: string;
|
|
252
359
|
appId: string;
|
|
@@ -256,6 +363,13 @@ declare global {
|
|
|
256
363
|
}
|
|
257
364
|
```
|
|
258
365
|
|
|
366
|
+
## 环境变量
|
|
367
|
+
|
|
368
|
+
| 变量名 | 描述 | 默认值 |
|
|
369
|
+
|--------|------|--------|
|
|
370
|
+
| CLIENT_BASE_PATH | 应用的全局路径前缀 | - |
|
|
371
|
+
| NODE_ENV | 运行环境 | - |
|
|
372
|
+
|
|
259
373
|
## 许可证
|
|
260
374
|
|
|
261
375
|
MIT
|
|
@@ -266,3 +380,4 @@ MIT
|
|
|
266
380
|
- nestjs
|
|
267
381
|
- server
|
|
268
382
|
- typescript
|
|
383
|
+
- fullstack
|
package/dist/index.cjs
CHANGED
|
@@ -35,6 +35,7 @@ __export(index_exports, {
|
|
|
35
35
|
CsrfMiddleware: () => CsrfMiddleware,
|
|
36
36
|
CsrfTokenMiddleware: () => CsrfTokenMiddleware,
|
|
37
37
|
DevToolsModule: () => DevToolsModule,
|
|
38
|
+
DevToolsV2Module: () => DevToolsV2Module,
|
|
38
39
|
PlatformModule: () => PlatformModule,
|
|
39
40
|
UserContextMiddleware: () => UserContextMiddleware,
|
|
40
41
|
ViewContextMiddleware: () => ViewContextMiddleware,
|
|
@@ -89,7 +90,8 @@ var UserContextMiddleware = class {
|
|
|
89
90
|
req.userContext = {
|
|
90
91
|
userId: webUser?.user_id,
|
|
91
92
|
tenantId: webUser?.tenant_id,
|
|
92
|
-
appId: webUser?.app_id ?? ""
|
|
93
|
+
appId: webUser?.app_id ?? "",
|
|
94
|
+
loginUrl: webUser?.login_url ?? ""
|
|
93
95
|
};
|
|
94
96
|
next();
|
|
95
97
|
}
|
|
@@ -170,6 +172,12 @@ var ViewContextMiddleware = class {
|
|
|
170
172
|
use(req, res, next) {
|
|
171
173
|
const { userId, tenantId, appId } = req.userContext;
|
|
172
174
|
const csrfToken = req.csrfToken;
|
|
175
|
+
req.__platform_data__ = {
|
|
176
|
+
csrfToken: csrfToken ?? "",
|
|
177
|
+
userId: userId ?? "",
|
|
178
|
+
appId: appId ?? "",
|
|
179
|
+
tenantId
|
|
180
|
+
};
|
|
173
181
|
res.locals = {
|
|
174
182
|
...res.locals ?? {},
|
|
175
183
|
csrfToken: csrfToken ?? "",
|
|
@@ -317,9 +325,7 @@ var PlatformModule = class _PlatformModule {
|
|
|
317
325
|
};
|
|
318
326
|
}, "useFactory")
|
|
319
327
|
}),
|
|
320
|
-
import_nestjs_authnpaas.AuthNPaasModule.forRoot(
|
|
321
|
-
alwaysNeedLogin: options.alwaysNeedLogin ?? true
|
|
322
|
-
})
|
|
328
|
+
import_nestjs_authnpaas.AuthNPaasModule.forRoot()
|
|
323
329
|
],
|
|
324
330
|
providers: [
|
|
325
331
|
{
|
|
@@ -363,14 +369,12 @@ PlatformModule = _ts_decorate5([
|
|
|
363
369
|
|
|
364
370
|
// src/setup.ts
|
|
365
371
|
var import_nestjs_logger2 = require("@lark-apaas/nestjs-logger");
|
|
366
|
-
var import_path = require("path");
|
|
367
|
-
var import_hbs = require("hbs");
|
|
368
372
|
var import_cookie_parser = __toESM(require("cookie-parser"), 1);
|
|
369
373
|
|
|
370
374
|
// src/modules/devtool-v2/index.ts
|
|
371
375
|
var import_swagger = require("@nestjs/swagger");
|
|
372
|
-
var
|
|
373
|
-
var
|
|
376
|
+
var import_node_fs4 = require("fs");
|
|
377
|
+
var import_node_path4 = require("path");
|
|
374
378
|
|
|
375
379
|
// src/modules/devtool-v2/helper.ts
|
|
376
380
|
var import_node_path = require("path");
|
|
@@ -426,6 +430,39 @@ export const createClientConfig: CreateClientConfig = (config) => ({
|
|
|
426
430
|
}
|
|
427
431
|
__name(generateClientConfig, "generateClientConfig");
|
|
428
432
|
|
|
433
|
+
// src/modules/devtool-v2/plugins/add-ts-nocheck.ts
|
|
434
|
+
var import_node_fs3 = require("fs");
|
|
435
|
+
var import_node_path3 = require("path");
|
|
436
|
+
function addTsNocheckToGeneratedFiles(outputPath) {
|
|
437
|
+
const files = getAllTsFiles(outputPath);
|
|
438
|
+
for (const filePath of files) {
|
|
439
|
+
addTsNocheckToFile(filePath);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
__name(addTsNocheckToGeneratedFiles, "addTsNocheckToGeneratedFiles");
|
|
443
|
+
function getAllTsFiles(dirPath) {
|
|
444
|
+
const files = [];
|
|
445
|
+
const entries = (0, import_node_fs3.readdirSync)(dirPath);
|
|
446
|
+
for (const entry of entries) {
|
|
447
|
+
const fullPath = (0, import_node_path3.join)(dirPath, entry);
|
|
448
|
+
const stat = (0, import_node_fs3.statSync)(fullPath);
|
|
449
|
+
if (stat.isDirectory()) {
|
|
450
|
+
files.push(...getAllTsFiles(fullPath));
|
|
451
|
+
} else if (stat.isFile() && entry.endsWith(".ts")) {
|
|
452
|
+
files.push(fullPath);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
return files;
|
|
456
|
+
}
|
|
457
|
+
__name(getAllTsFiles, "getAllTsFiles");
|
|
458
|
+
function addTsNocheckToFile(filePath) {
|
|
459
|
+
const content = (0, import_node_fs3.readFileSync)(filePath, "utf-8");
|
|
460
|
+
const newContent = `// @ts-nocheck
|
|
461
|
+
${content}`;
|
|
462
|
+
(0, import_node_fs3.writeFileSync)(filePath, newContent, "utf-8");
|
|
463
|
+
}
|
|
464
|
+
__name(addTsNocheckToFile, "addTsNocheckToFile");
|
|
465
|
+
|
|
429
466
|
// src/modules/devtool-v2/index.ts
|
|
430
467
|
var DevToolsV2Module = class {
|
|
431
468
|
static {
|
|
@@ -446,16 +483,13 @@ var DevToolsV2Module = class {
|
|
|
446
483
|
});
|
|
447
484
|
console.log(`[OpenAPI] Swagger UI \u5DF2\u6302\u8F7D\u81F3 ${options.docsPath}`);
|
|
448
485
|
}
|
|
449
|
-
const openapiPath = (0,
|
|
486
|
+
const openapiPath = (0, import_node_path4.resolve)(baseDirname, options.openapiOut);
|
|
450
487
|
ensureDirAndWrite(openapiPath, JSON.stringify(document, null, 2));
|
|
451
488
|
if (options.needGenerateClientSdk) {
|
|
452
|
-
const clientSdkOutPath = (0,
|
|
453
|
-
(0,
|
|
489
|
+
const clientSdkOutPath = (0, import_node_path4.resolve)(baseDirname, options.clientSdkOut);
|
|
490
|
+
(0, import_node_fs4.mkdirSync)(clientSdkOutPath, {
|
|
454
491
|
recursive: true
|
|
455
492
|
});
|
|
456
|
-
generateClientConfig({
|
|
457
|
-
outputPath: clientSdkOutPath
|
|
458
|
-
});
|
|
459
493
|
const { createClient } = await import("@hey-api/openapi-ts");
|
|
460
494
|
await createClient({
|
|
461
495
|
input: openapiPath,
|
|
@@ -467,26 +501,27 @@ var DevToolsV2Module = class {
|
|
|
467
501
|
"@hey-api/sdk",
|
|
468
502
|
{
|
|
469
503
|
name: "@hey-api/client-axios",
|
|
470
|
-
runtimeConfigPath: (0,
|
|
504
|
+
runtimeConfigPath: (0, import_node_path4.join)(clientSdkOutPath, "./client.config.ts")
|
|
471
505
|
}
|
|
472
506
|
]
|
|
473
507
|
});
|
|
508
|
+
addTsNocheckToGeneratedFiles(clientSdkOutPath);
|
|
474
509
|
ensureDirAndWrite(openapiPath, JSON.stringify(document, null, 2));
|
|
510
|
+
generateClientConfig({
|
|
511
|
+
outputPath: clientSdkOutPath
|
|
512
|
+
});
|
|
475
513
|
console.log("[OpenAPI] \u5BFC\u51FA openapi.json \u5E76\u751F\u6210 axios SDK \u2705");
|
|
476
514
|
}
|
|
477
515
|
}
|
|
478
516
|
};
|
|
479
517
|
|
|
480
518
|
// src/setup.ts
|
|
481
|
-
async function configureApp(app
|
|
519
|
+
async function configureApp(app) {
|
|
482
520
|
app.useLogger(app.get(import_nestjs_logger2.AppLogger));
|
|
483
521
|
app.flushLogs();
|
|
484
522
|
app.use((0, import_cookie_parser.default)());
|
|
485
523
|
const globalPrefix = process.env.CLIENT_BASE_PATH ?? "";
|
|
486
524
|
app.setGlobalPrefix(globalPrefix);
|
|
487
|
-
app.setBaseViewsDir((0, import_path.join)(process.cwd(), options?.viewsDir ?? "dist/client"));
|
|
488
|
-
app.setViewEngine("html");
|
|
489
|
-
app.engine("html", import_hbs.__express);
|
|
490
525
|
if (process.env.NODE_ENV !== "production") {
|
|
491
526
|
await DevToolsV2Module.mount(app, {
|
|
492
527
|
basePath: process.env.CLIENT_BASE_PATH,
|
|
@@ -498,12 +533,12 @@ __name(configureApp, "configureApp");
|
|
|
498
533
|
|
|
499
534
|
// src/modules/devtool/index.ts
|
|
500
535
|
var import_swagger2 = require("@nestjs/swagger");
|
|
501
|
-
var
|
|
502
|
-
var
|
|
536
|
+
var import_node_fs6 = require("fs");
|
|
537
|
+
var import_node_path6 = require("path");
|
|
503
538
|
|
|
504
539
|
// src/modules/devtool/helper.ts
|
|
505
|
-
var
|
|
506
|
-
var
|
|
540
|
+
var import_node_path5 = require("path");
|
|
541
|
+
var import_node_fs5 = require("fs");
|
|
507
542
|
function normalizeBasePath2(rawBasePath) {
|
|
508
543
|
const normalizedBasePath = rawBasePath.startsWith("/") ? rawBasePath : `/${rawBasePath}`;
|
|
509
544
|
return normalizedBasePath.endsWith("/") ? normalizedBasePath.slice(0, -1) : normalizedBasePath;
|
|
@@ -530,11 +565,11 @@ function resolveOptsWithDefaultValue2(options) {
|
|
|
530
565
|
}
|
|
531
566
|
__name(resolveOptsWithDefaultValue2, "resolveOptsWithDefaultValue");
|
|
532
567
|
function ensureDirAndWrite2(filePath, content) {
|
|
533
|
-
const dir = (0,
|
|
534
|
-
(0,
|
|
568
|
+
const dir = (0, import_node_path5.dirname)(filePath);
|
|
569
|
+
(0, import_node_fs5.mkdirSync)(dir, {
|
|
535
570
|
recursive: true
|
|
536
571
|
});
|
|
537
|
-
(0,
|
|
572
|
+
(0, import_node_fs5.writeFileSync)(filePath, content);
|
|
538
573
|
}
|
|
539
574
|
__name(ensureDirAndWrite2, "ensureDirAndWrite");
|
|
540
575
|
|
|
@@ -560,11 +595,11 @@ var DevToolsModule = class {
|
|
|
560
595
|
});
|
|
561
596
|
console.log(`[OpenAPI] Swagger UI \u5DF2\u6302\u8F7D\u81F3 ${options.docsPath}`);
|
|
562
597
|
}
|
|
563
|
-
const openapiPath = (0,
|
|
598
|
+
const openapiPath = (0, import_node_path6.resolve)(baseDirname, options.openapiOut);
|
|
564
599
|
ensureDirAndWrite2(openapiPath, JSON.stringify(document, null, 2));
|
|
565
600
|
if (options.needGenerateClientSdk) {
|
|
566
|
-
const clientSdkOutPath = (0,
|
|
567
|
-
(0,
|
|
601
|
+
const clientSdkOutPath = (0, import_node_path6.resolve)(baseDirname, options.clientSdkOut);
|
|
602
|
+
(0, import_node_fs6.mkdirSync)(clientSdkOutPath, {
|
|
568
603
|
recursive: true
|
|
569
604
|
});
|
|
570
605
|
const { generate } = await import("openapi-typescript-codegen");
|
|
@@ -588,6 +623,7 @@ __reExport(index_exports, require("@lark-apaas/nestjs-datapaas"), module.exports
|
|
|
588
623
|
CsrfMiddleware,
|
|
589
624
|
CsrfTokenMiddleware,
|
|
590
625
|
DevToolsModule,
|
|
626
|
+
DevToolsV2Module,
|
|
591
627
|
PlatformModule,
|
|
592
628
|
UserContextMiddleware,
|
|
593
629
|
ViewContextMiddleware,
|
package/dist/index.d.cts
CHANGED
|
@@ -7,12 +7,19 @@ export * from '@lark-apaas/nestjs-datapaas';
|
|
|
7
7
|
declare global {
|
|
8
8
|
namespace Express {
|
|
9
9
|
interface Request {
|
|
10
|
-
|
|
10
|
+
__platform_data__?: {
|
|
11
|
+
userId?: string;
|
|
12
|
+
tenantId?: number;
|
|
13
|
+
csrfToken?: string;
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
};
|
|
11
16
|
userContext: {
|
|
12
17
|
userId?: string;
|
|
13
18
|
tenantId?: number;
|
|
14
19
|
appId?: string;
|
|
15
|
-
|
|
20
|
+
loginUrl?: string;
|
|
21
|
+
},
|
|
22
|
+
csrfToken?: string;
|
|
16
23
|
}
|
|
17
24
|
}
|
|
18
25
|
}
|
|
@@ -31,11 +38,6 @@ interface PlatformModuleOptions {
|
|
|
31
38
|
* 默认: '/api/*'
|
|
32
39
|
*/
|
|
33
40
|
csrfRoutes?: string | string[];
|
|
34
|
-
/**
|
|
35
|
-
* AuthN 能力,是否全部依赖登录
|
|
36
|
-
* 默认:true
|
|
37
|
-
*/
|
|
38
|
-
alwaysNeedLogin?: boolean;
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
declare class PlatformModule implements NestModule {
|
|
@@ -47,11 +49,9 @@ declare class PlatformModule implements NestModule {
|
|
|
47
49
|
configure(consumer: MiddlewareConsumer): void;
|
|
48
50
|
}
|
|
49
51
|
|
|
50
|
-
declare function configureApp(app: NestExpressApplication
|
|
51
|
-
viewsDir?: string;
|
|
52
|
-
}): Promise<void>;
|
|
52
|
+
declare function configureApp(app: NestExpressApplication): Promise<void>;
|
|
53
53
|
|
|
54
|
-
interface DevToolsOptions {
|
|
54
|
+
interface DevToolsOptions$1 {
|
|
55
55
|
basePath?: string;
|
|
56
56
|
docsPath?: string;
|
|
57
57
|
openapiOut?: string;
|
|
@@ -66,7 +66,29 @@ interface DevToolsOptions {
|
|
|
66
66
|
};
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
/**
|
|
70
|
+
* @deprecated 该模块已被废弃,不建议使用,建议使用 DevToolsV2Module
|
|
71
|
+
*/
|
|
69
72
|
declare class DevToolsModule {
|
|
73
|
+
static mount(app: INestApplication, opts?: DevToolsOptions$1): Promise<void>;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
interface DevToolsOptions {
|
|
77
|
+
basePath?: string;
|
|
78
|
+
docsPath?: string;
|
|
79
|
+
openapiOut?: string;
|
|
80
|
+
needSetupServer?: boolean;
|
|
81
|
+
needGenerateClientSdk?: boolean;
|
|
82
|
+
clientSdkOut?: string;
|
|
83
|
+
swaggerOptions?: {
|
|
84
|
+
title?: string;
|
|
85
|
+
version?: string;
|
|
86
|
+
customSiteTitle?: string;
|
|
87
|
+
customCss?: string;
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
declare class DevToolsV2Module {
|
|
70
92
|
static mount(app: INestApplication, opts?: DevToolsOptions): Promise<void>;
|
|
71
93
|
}
|
|
72
94
|
|
|
@@ -101,4 +123,4 @@ declare class ViewContextMiddleware implements NestMiddleware {
|
|
|
101
123
|
use(req: Request, res: Response, next: NextFunction): void;
|
|
102
124
|
}
|
|
103
125
|
|
|
104
|
-
export { CsrfMiddleware, CsrfTokenMiddleware, DevToolsModule, PlatformModule, type PlatformModuleOptions, UserContextMiddleware, ViewContextMiddleware, configureApp };
|
|
126
|
+
export { CsrfMiddleware, CsrfTokenMiddleware, DevToolsModule, DevToolsV2Module, PlatformModule, type PlatformModuleOptions, UserContextMiddleware, ViewContextMiddleware, configureApp };
|
package/dist/index.d.ts
CHANGED
|
@@ -7,12 +7,19 @@ export * from '@lark-apaas/nestjs-datapaas';
|
|
|
7
7
|
declare global {
|
|
8
8
|
namespace Express {
|
|
9
9
|
interface Request {
|
|
10
|
-
|
|
10
|
+
__platform_data__?: {
|
|
11
|
+
userId?: string;
|
|
12
|
+
tenantId?: number;
|
|
13
|
+
csrfToken?: string;
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
};
|
|
11
16
|
userContext: {
|
|
12
17
|
userId?: string;
|
|
13
18
|
tenantId?: number;
|
|
14
19
|
appId?: string;
|
|
15
|
-
|
|
20
|
+
loginUrl?: string;
|
|
21
|
+
},
|
|
22
|
+
csrfToken?: string;
|
|
16
23
|
}
|
|
17
24
|
}
|
|
18
25
|
}
|
|
@@ -31,11 +38,6 @@ interface PlatformModuleOptions {
|
|
|
31
38
|
* 默认: '/api/*'
|
|
32
39
|
*/
|
|
33
40
|
csrfRoutes?: string | string[];
|
|
34
|
-
/**
|
|
35
|
-
* AuthN 能力,是否全部依赖登录
|
|
36
|
-
* 默认:true
|
|
37
|
-
*/
|
|
38
|
-
alwaysNeedLogin?: boolean;
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
declare class PlatformModule implements NestModule {
|
|
@@ -47,11 +49,9 @@ declare class PlatformModule implements NestModule {
|
|
|
47
49
|
configure(consumer: MiddlewareConsumer): void;
|
|
48
50
|
}
|
|
49
51
|
|
|
50
|
-
declare function configureApp(app: NestExpressApplication
|
|
51
|
-
viewsDir?: string;
|
|
52
|
-
}): Promise<void>;
|
|
52
|
+
declare function configureApp(app: NestExpressApplication): Promise<void>;
|
|
53
53
|
|
|
54
|
-
interface DevToolsOptions {
|
|
54
|
+
interface DevToolsOptions$1 {
|
|
55
55
|
basePath?: string;
|
|
56
56
|
docsPath?: string;
|
|
57
57
|
openapiOut?: string;
|
|
@@ -66,7 +66,29 @@ interface DevToolsOptions {
|
|
|
66
66
|
};
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
/**
|
|
70
|
+
* @deprecated 该模块已被废弃,不建议使用,建议使用 DevToolsV2Module
|
|
71
|
+
*/
|
|
69
72
|
declare class DevToolsModule {
|
|
73
|
+
static mount(app: INestApplication, opts?: DevToolsOptions$1): Promise<void>;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
interface DevToolsOptions {
|
|
77
|
+
basePath?: string;
|
|
78
|
+
docsPath?: string;
|
|
79
|
+
openapiOut?: string;
|
|
80
|
+
needSetupServer?: boolean;
|
|
81
|
+
needGenerateClientSdk?: boolean;
|
|
82
|
+
clientSdkOut?: string;
|
|
83
|
+
swaggerOptions?: {
|
|
84
|
+
title?: string;
|
|
85
|
+
version?: string;
|
|
86
|
+
customSiteTitle?: string;
|
|
87
|
+
customCss?: string;
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
declare class DevToolsV2Module {
|
|
70
92
|
static mount(app: INestApplication, opts?: DevToolsOptions): Promise<void>;
|
|
71
93
|
}
|
|
72
94
|
|
|
@@ -101,4 +123,4 @@ declare class ViewContextMiddleware implements NestMiddleware {
|
|
|
101
123
|
use(req: Request, res: Response, next: NextFunction): void;
|
|
102
124
|
}
|
|
103
125
|
|
|
104
|
-
export { CsrfMiddleware, CsrfTokenMiddleware, DevToolsModule, PlatformModule, type PlatformModuleOptions, UserContextMiddleware, ViewContextMiddleware, configureApp };
|
|
126
|
+
export { CsrfMiddleware, CsrfTokenMiddleware, DevToolsModule, DevToolsV2Module, PlatformModule, type PlatformModuleOptions, UserContextMiddleware, ViewContextMiddleware, configureApp };
|
package/dist/index.js
CHANGED
|
@@ -48,7 +48,8 @@ var UserContextMiddleware = class {
|
|
|
48
48
|
req.userContext = {
|
|
49
49
|
userId: webUser?.user_id,
|
|
50
50
|
tenantId: webUser?.tenant_id,
|
|
51
|
-
appId: webUser?.app_id ?? ""
|
|
51
|
+
appId: webUser?.app_id ?? "",
|
|
52
|
+
loginUrl: webUser?.login_url ?? ""
|
|
52
53
|
};
|
|
53
54
|
next();
|
|
54
55
|
}
|
|
@@ -129,6 +130,12 @@ var ViewContextMiddleware = class {
|
|
|
129
130
|
use(req, res, next) {
|
|
130
131
|
const { userId, tenantId, appId } = req.userContext;
|
|
131
132
|
const csrfToken = req.csrfToken;
|
|
133
|
+
req.__platform_data__ = {
|
|
134
|
+
csrfToken: csrfToken ?? "",
|
|
135
|
+
userId: userId ?? "",
|
|
136
|
+
appId: appId ?? "",
|
|
137
|
+
tenantId
|
|
138
|
+
};
|
|
132
139
|
res.locals = {
|
|
133
140
|
...res.locals ?? {},
|
|
134
141
|
csrfToken: csrfToken ?? "",
|
|
@@ -276,9 +283,7 @@ var PlatformModule = class _PlatformModule {
|
|
|
276
283
|
};
|
|
277
284
|
}, "useFactory")
|
|
278
285
|
}),
|
|
279
|
-
AuthNPaasModule.forRoot(
|
|
280
|
-
alwaysNeedLogin: options.alwaysNeedLogin ?? true
|
|
281
|
-
})
|
|
286
|
+
AuthNPaasModule.forRoot()
|
|
282
287
|
],
|
|
283
288
|
providers: [
|
|
284
289
|
{
|
|
@@ -322,14 +327,12 @@ PlatformModule = _ts_decorate5([
|
|
|
322
327
|
|
|
323
328
|
// src/setup.ts
|
|
324
329
|
import { AppLogger as AppLogger2 } from "@lark-apaas/nestjs-logger";
|
|
325
|
-
import { join as join2 } from "path";
|
|
326
|
-
import { __express as hbsExpressEngine } from "hbs";
|
|
327
330
|
import cookieParser from "cookie-parser";
|
|
328
331
|
|
|
329
332
|
// src/modules/devtool-v2/index.ts
|
|
330
333
|
import { SwaggerModule, DocumentBuilder } from "@nestjs/swagger";
|
|
331
334
|
import { mkdirSync as mkdirSync2 } from "fs";
|
|
332
|
-
import { resolve as resolve2, join } from "path";
|
|
335
|
+
import { resolve as resolve2, join as join2 } from "path";
|
|
333
336
|
|
|
334
337
|
// src/modules/devtool-v2/helper.ts
|
|
335
338
|
import { dirname } from "path";
|
|
@@ -385,6 +388,39 @@ export const createClientConfig: CreateClientConfig = (config) => ({
|
|
|
385
388
|
}
|
|
386
389
|
__name(generateClientConfig, "generateClientConfig");
|
|
387
390
|
|
|
391
|
+
// src/modules/devtool-v2/plugins/add-ts-nocheck.ts
|
|
392
|
+
import { readdirSync, readFileSync, writeFileSync as writeFileSync3, statSync } from "fs";
|
|
393
|
+
import { join } from "path";
|
|
394
|
+
function addTsNocheckToGeneratedFiles(outputPath) {
|
|
395
|
+
const files = getAllTsFiles(outputPath);
|
|
396
|
+
for (const filePath of files) {
|
|
397
|
+
addTsNocheckToFile(filePath);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
__name(addTsNocheckToGeneratedFiles, "addTsNocheckToGeneratedFiles");
|
|
401
|
+
function getAllTsFiles(dirPath) {
|
|
402
|
+
const files = [];
|
|
403
|
+
const entries = readdirSync(dirPath);
|
|
404
|
+
for (const entry of entries) {
|
|
405
|
+
const fullPath = join(dirPath, entry);
|
|
406
|
+
const stat = statSync(fullPath);
|
|
407
|
+
if (stat.isDirectory()) {
|
|
408
|
+
files.push(...getAllTsFiles(fullPath));
|
|
409
|
+
} else if (stat.isFile() && entry.endsWith(".ts")) {
|
|
410
|
+
files.push(fullPath);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
return files;
|
|
414
|
+
}
|
|
415
|
+
__name(getAllTsFiles, "getAllTsFiles");
|
|
416
|
+
function addTsNocheckToFile(filePath) {
|
|
417
|
+
const content = readFileSync(filePath, "utf-8");
|
|
418
|
+
const newContent = `// @ts-nocheck
|
|
419
|
+
${content}`;
|
|
420
|
+
writeFileSync3(filePath, newContent, "utf-8");
|
|
421
|
+
}
|
|
422
|
+
__name(addTsNocheckToFile, "addTsNocheckToFile");
|
|
423
|
+
|
|
388
424
|
// src/modules/devtool-v2/index.ts
|
|
389
425
|
var DevToolsV2Module = class {
|
|
390
426
|
static {
|
|
@@ -412,9 +448,6 @@ var DevToolsV2Module = class {
|
|
|
412
448
|
mkdirSync2(clientSdkOutPath, {
|
|
413
449
|
recursive: true
|
|
414
450
|
});
|
|
415
|
-
generateClientConfig({
|
|
416
|
-
outputPath: clientSdkOutPath
|
|
417
|
-
});
|
|
418
451
|
const { createClient } = await import("@hey-api/openapi-ts");
|
|
419
452
|
await createClient({
|
|
420
453
|
input: openapiPath,
|
|
@@ -426,26 +459,27 @@ var DevToolsV2Module = class {
|
|
|
426
459
|
"@hey-api/sdk",
|
|
427
460
|
{
|
|
428
461
|
name: "@hey-api/client-axios",
|
|
429
|
-
runtimeConfigPath:
|
|
462
|
+
runtimeConfigPath: join2(clientSdkOutPath, "./client.config.ts")
|
|
430
463
|
}
|
|
431
464
|
]
|
|
432
465
|
});
|
|
466
|
+
addTsNocheckToGeneratedFiles(clientSdkOutPath);
|
|
433
467
|
ensureDirAndWrite(openapiPath, JSON.stringify(document, null, 2));
|
|
468
|
+
generateClientConfig({
|
|
469
|
+
outputPath: clientSdkOutPath
|
|
470
|
+
});
|
|
434
471
|
console.log("[OpenAPI] \u5BFC\u51FA openapi.json \u5E76\u751F\u6210 axios SDK \u2705");
|
|
435
472
|
}
|
|
436
473
|
}
|
|
437
474
|
};
|
|
438
475
|
|
|
439
476
|
// src/setup.ts
|
|
440
|
-
async function configureApp(app
|
|
477
|
+
async function configureApp(app) {
|
|
441
478
|
app.useLogger(app.get(AppLogger2));
|
|
442
479
|
app.flushLogs();
|
|
443
480
|
app.use(cookieParser());
|
|
444
481
|
const globalPrefix = process.env.CLIENT_BASE_PATH ?? "";
|
|
445
482
|
app.setGlobalPrefix(globalPrefix);
|
|
446
|
-
app.setBaseViewsDir(join2(process.cwd(), options?.viewsDir ?? "dist/client"));
|
|
447
|
-
app.setViewEngine("html");
|
|
448
|
-
app.engine("html", hbsExpressEngine);
|
|
449
483
|
if (process.env.NODE_ENV !== "production") {
|
|
450
484
|
await DevToolsV2Module.mount(app, {
|
|
451
485
|
basePath: process.env.CLIENT_BASE_PATH,
|
|
@@ -462,7 +496,7 @@ import { resolve as resolve3 } from "path";
|
|
|
462
496
|
|
|
463
497
|
// src/modules/devtool/helper.ts
|
|
464
498
|
import { dirname as dirname2 } from "path";
|
|
465
|
-
import { writeFileSync as
|
|
499
|
+
import { writeFileSync as writeFileSync4, mkdirSync as mkdirSync3 } from "fs";
|
|
466
500
|
function normalizeBasePath2(rawBasePath) {
|
|
467
501
|
const normalizedBasePath = rawBasePath.startsWith("/") ? rawBasePath : `/${rawBasePath}`;
|
|
468
502
|
return normalizedBasePath.endsWith("/") ? normalizedBasePath.slice(0, -1) : normalizedBasePath;
|
|
@@ -493,7 +527,7 @@ function ensureDirAndWrite2(filePath, content) {
|
|
|
493
527
|
mkdirSync3(dir, {
|
|
494
528
|
recursive: true
|
|
495
529
|
});
|
|
496
|
-
|
|
530
|
+
writeFileSync4(filePath, content);
|
|
497
531
|
}
|
|
498
532
|
__name(ensureDirAndWrite2, "ensureDirAndWrite");
|
|
499
533
|
|
|
@@ -546,6 +580,7 @@ export {
|
|
|
546
580
|
CsrfMiddleware,
|
|
547
581
|
CsrfTokenMiddleware,
|
|
548
582
|
DevToolsModule,
|
|
583
|
+
DevToolsV2Module,
|
|
549
584
|
PlatformModule,
|
|
550
585
|
UserContextMiddleware,
|
|
551
586
|
ViewContextMiddleware,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lark-apaas/fullstack-nestjs-core",
|
|
3
|
-
"version": "1.0.3
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "FullStack Nestjs Core",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -19,9 +19,7 @@
|
|
|
19
19
|
"node": ">=18.0.0"
|
|
20
20
|
},
|
|
21
21
|
"files": [
|
|
22
|
-
"dist"
|
|
23
|
-
"templates",
|
|
24
|
-
"postinstall.config.mjs"
|
|
22
|
+
"dist"
|
|
25
23
|
],
|
|
26
24
|
"exports": {
|
|
27
25
|
".": {
|
|
@@ -40,13 +38,12 @@
|
|
|
40
38
|
"lint:fix": "eslint src --ext .ts --fix"
|
|
41
39
|
},
|
|
42
40
|
"dependencies": {
|
|
43
|
-
"@hey-api/openapi-ts": "^0.
|
|
44
|
-
"openapi-typescript-codegen": "^0.29.0",
|
|
41
|
+
"@hey-api/openapi-ts": "^0.87.0",
|
|
45
42
|
"@lark-apaas/nestjs-authnpaas": "^1.0.0",
|
|
46
43
|
"@lark-apaas/nestjs-datapaas": "^1.0.1",
|
|
47
44
|
"@lark-apaas/nestjs-logger": "^1.0.0",
|
|
48
45
|
"cookie-parser": "^1.4.7",
|
|
49
|
-
"
|
|
46
|
+
"openapi-typescript-codegen": "^0.29.0"
|
|
50
47
|
},
|
|
51
48
|
"devDependencies": {
|
|
52
49
|
"@nestjs/common": "^10.4.20",
|
|
@@ -54,7 +51,6 @@
|
|
|
54
51
|
"@nestjs/swagger": "^7.4.2",
|
|
55
52
|
"@types/cookie-parser": "^1.4.9",
|
|
56
53
|
"@types/express": "^5.0.3",
|
|
57
|
-
"@types/hbs": "^4.0.5",
|
|
58
54
|
"class-transformer": "^0.5.1",
|
|
59
55
|
"class-validator": "^0.14.2",
|
|
60
56
|
"drizzle-orm": "0.44.6",
|