@airpower/transformer 2.0.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +292 -31
  2. package/package.json +3 -6
package/README.md CHANGED
@@ -17,70 +17,331 @@
17
17
  <a href="https://www.npmjs.com/package/@airpower/transformer">NPM</a>
18
18
  </p>
19
19
 
20
- # 🎉 项目介绍
20
+ # 🎉 AirPower-Transformer 项目介绍
21
21
 
22
- **AirPower-Transformer** 是一个基于 `TypeScript` 的数据转换器,提供了从 `JSON` 对象到 `类实例` 对象之间互相转换的系列装饰器和方法。
22
+ **AirPower-Transformer** 是一个功能强大且易于使用的 TypeScript 数据转换库,专为简化 JSON
23
+ 对象与类实例之间的双向转换而设计。该库通过装饰器提供了一种声明式的方式来控制数据转换过程,使开发者能够轻松处理复杂的嵌套对象、数组以及具有特定格式要求的数据结构。
23
24
 
24
- # 💻 如何安装
25
+ ## 主要特性
26
+
27
+ - **双向转换**:支持从 JSON 对象到类实例的转换,以及从类实例到 JSON 对象的转换
28
+ - **装饰器驱动**:使用 TypeScript 装饰器来配置转换行为,代码清晰易懂
29
+ - **前缀支持**:可以为整个类或特定字段设置前缀,适应不同 API 的命名规范
30
+ - **字段别名**:支持字段别名映射,解决前后端字段名不一致的问题
31
+ - **类型安全**:完全基于 TypeScript,提供完整的类型检查和智能提示
32
+ - **嵌套对象处理**:自动处理嵌套对象和数组的转换
33
+ - **自定义转换逻辑**:支持自定义转换函数,满足特殊转换需求
34
+ - **零依赖**:不依赖任何外部库,轻量级解决方案
35
+
36
+ ## 💻 安装
25
37
 
26
38
  ```shell
27
39
  npm install @airpower/transformer
28
40
  # or
29
41
  yarn add @airpower/transformer
30
42
  # or
31
- cnpm install @airpower/transformer
32
- # or ...
43
+ pnpm add @airpower/transformer
33
44
  ```
34
45
 
35
- # 📖 使用说明
46
+ ## 📖 使用指南
36
47
 
37
- ```ts
38
- import { IgnorePrefix, Prefix, Transformer, Type } from '@airpower/transformer'
48
+ ### 基础用法
39
49
 
40
- @Prefix('role____')
41
- class Role extends Transformer {
50
+ ```typescript
51
+ import { Transformer } from '@airpower/transformer'
52
+
53
+ class User extends Transformer {
42
54
  id!: number
43
55
  name!: string
56
+ email!: string
44
57
  }
45
58
 
59
+ // 从 JSON 创建实例
60
+ const userData = { id: 1, name: 'John', email: 'john@example.com' }
61
+ const user = User.fromJson(userData)
62
+
63
+ // 将实例转换为 JSON
64
+ const json = user.toJson()
65
+ ```
66
+
67
+ ### 装饰器详解
68
+
69
+ #### 1. `@Prefix(prefix: string)`
70
+
71
+ 为类的所有字段设置统一前缀:
72
+
73
+ ```typescript
74
+ import { Prefix, Transformer } from '@airpower/transformer'
75
+
46
76
  @Prefix('user_')
77
+ class User extends Transformer {
78
+ id!: number // JSON 中对应 'user_id'
79
+ name!: string // JSON 中对应 'user_name'
80
+ email!: string // JSON 中对应 'user_email'
81
+ }
82
+
83
+ const user = User.fromJson({ user_id: 1, user_name: 'John', user_email: 'john@example.com' })
84
+ console.log(user.id) // 输出: 1
85
+ console.log(user.name) // 输出: 'John'
86
+ ```
87
+
88
+ #### 2. `@Alias(alias: string)`
89
+
90
+ 为字段设置别名:
91
+
92
+ ```typescript
93
+ import { Alias, Transformer } from '@airpower/transformer'
94
+
95
+ class User extends Transformer {
96
+ id!: number
97
+
98
+ @Alias('full_name')
99
+ name!: string // JSON 中对应 'full_name'
100
+
101
+ @Alias('user_email')
102
+ email!: string // JSON 中对应 'user_email'
103
+ }
104
+
105
+ const user = User.fromJson({ id: 1, full_name: 'John Doe', user_email: 'john@example.com' })
106
+ console.log(user.name) // 输出: 'John Doe'
107
+ console.log(user.email) // 输出: 'john@example.com'
108
+ ```
109
+
110
+ #### 3. `@IgnorePrefix()`
111
+
112
+ 让特定字段忽略类级别的前缀:
113
+
114
+ ```typescript
115
+ import { IgnorePrefix, Prefix, Transformer } from '@airpower/transformer'
116
+
117
+ @Prefix('api_')
118
+ class User extends Transformer {
119
+ id!: number // JSON 中对应 'api_id'
120
+
121
+ @IgnorePrefix()
122
+ temporaryId!: string // JSON 中对应 'temporaryId',不带前缀
123
+ }
124
+
125
+ const user = User.fromJson({ api_id: 1, temporaryId: 'temp123' })
126
+ console.log(user.id) // 输出: 1
127
+ console.log(user.temporaryId) // 输出: 'temp123'
128
+ ```
129
+
130
+ #### 4. `@Type(constructor: Class, isArray: boolean)`
131
+
132
+ 指定字段的类型,支持嵌套对象和数组:
133
+
134
+ ```typescript
135
+ import { Transformer, Type } from '@airpower/transformer'
136
+
137
+ class Address extends Transformer {
138
+ street!: string
139
+ city!: string
140
+ zipCode!: string
141
+ }
142
+
47
143
  class User extends Transformer {
48
144
  id!: number
49
145
  name!: string
50
146
 
147
+ @Type(Address)
148
+ address!: Address // 嵌套对象
149
+
150
+ @Type(Address, true)
151
+ addresses: Address[] = [] // 对象数组
152
+ }
153
+
154
+ const userData = {
155
+ id: 1,
156
+ name: 'John',
157
+ address: { street: '123 Main St', city: 'New York', zipCode: '10001' },
158
+ addresses: [
159
+ { street: '456 Oak Ave', city: 'Boston', zipCode: '02101' },
160
+ { street: '789 Pine Rd', city: 'Chicago', zipCode: '60601' }
161
+ ]
162
+ }
163
+
164
+ const user = User.fromJson(userData)
165
+ console.log(user.address.city) // 输出: 'New York'
166
+ console.log(user.addresses.length) // 输出: 2
167
+ console.log(user.addresses[0].city) // 输出: 'Boston'
168
+ ```
169
+
170
+ #### 5. `@ToClass(func: (json) => any)` 和 `@ToJson(func: (instance) => any)`
171
+
172
+ 自定义转换逻辑:
173
+
174
+ ```typescript
175
+ import { ToClass, ToJson, Transformer } from '@airpower/transformer'
176
+
177
+ class User extends Transformer {
178
+ id!: number
179
+ name!: string
180
+
181
+ @ToClass(json => new Date(json.birthday_timestamp * 1000))
182
+ birthday!: Date
183
+
184
+ @ToJson(instance => Math.floor(instance.birthday.getTime() / 1000))
185
+ birthdayTimestamp!: number
186
+ }
187
+
188
+ const userData = {
189
+ id: 1,
190
+ name: 'John',
191
+ birthday_timestamp: 1609459200 // 2021-01-01
192
+ }
193
+
194
+ const user = User.fromJson(userData)
195
+ console.log(user.birthday) // 输出: Date 对象 (2021-01-01)
196
+ ```
197
+
198
+ ### 完整示例
199
+
200
+ ```typescript
201
+ import { Alias, IgnorePrefix, Prefix, Transformer, Type } from '@airpower/transformer'
202
+
203
+ // 定义嵌套类
204
+ @Prefix('addr_')
205
+ class Address extends Transformer {
206
+ id!: number
207
+ @Alias('street_address')
208
+ street!: string
209
+
210
+ city!: string
211
+ country!: string
212
+ }
213
+
214
+ @Prefix('role_')
215
+ class Role extends Transformer {
216
+ id!: number
217
+ name!: string
218
+ @IgnorePrefix()
219
+ permissions: string[] = []
220
+ }
221
+
222
+ // 主类
223
+ @Prefix('usr_')
224
+ class User extends Transformer {
225
+ id!: number
226
+ @Alias('full_name')
227
+ name!: string
228
+
229
+ email!: string
230
+
51
231
  @IgnorePrefix()
52
- age!: number
232
+ temporaryToken!: string
53
233
 
54
- @Type(Role)
55
- role!: Role
234
+ @Type(Address)
235
+ homeAddress!: Address
56
236
 
57
237
  @Type(Role, true)
58
- roleList: Role[] = []
238
+ roles: Role[] = []
239
+
240
+ createdAt!: Date
59
241
  }
60
242
 
61
- const user = new User()
62
- user.id = 1
63
- user.name = 'Hamm'
64
- user.age = 18
243
+ // 使用示例
244
+ const jsonData = {
245
+ usr_id: 1,
246
+ full_name: 'John Doe',
247
+ usr_email: 'john@example.com',
248
+ temporaryToken: 'abc123',
249
+ homeAddress: {
250
+ addr_id: 1,
251
+ street_address: '123 Main St',
252
+ addr_city: 'New York',
253
+ addr_country: 'USA'
254
+ },
255
+ roles: [
256
+ {
257
+ role_id: 1,
258
+ role_name: 'Admin',
259
+ permissions: ['read', 'write', 'delete']
260
+ },
261
+ {
262
+ role_id: 2,
263
+ role_name: 'User',
264
+ permissions: ['read']
265
+ }
266
+ ],
267
+ usr_createdAt: '2023-01-01T00:00:00Z'
268
+ }
65
269
 
66
- const role = new Role()
67
- role.name = 'Admin'
68
- user.role = role
270
+ // JSON 创建实例
271
+ const user = User.fromJson(jsonData)
272
+ console.log(user.name) // 'John Doe'
273
+ console.log(user.temporaryToken) // 'abc123'
274
+ console.log(user.homeAddress.street) // '123 Main St'
275
+ console.log(user.roles.length) // 2
276
+ console.log(user.roles[0].permissions) // ['read', 'write', 'delete']
69
277
 
70
- const roleItem = new Role()
71
- roleItem.name = 'User'
72
- user.roleList.push(roleItem)
278
+ // 转换回 JSON
279
+ const jsonOutput = user.toJson()
280
+ console.log(JSON.stringify(jsonOutput, null, 2))
281
+ ```
73
282
 
74
- const json = user.copy().toJson()
75
- console.warn('json', JSON.stringify(json))
283
+ ## 🚀 常见使用场景
76
284
 
77
- json.name = '???' // 无效
78
- const user2 = User.fromJson(json)
79
- console.warn('user2', user2)
80
- ```
285
+ ### 1. API 数据适配
286
+
287
+ 当后端 API 返回的数据格式与前端模型不匹配时,使用装饰器可以轻松完成数据转换。
288
+
289
+ ### 2. 数据验证和清洗
290
+
291
+ 在数据进入应用之前,通过转换过程进行初步的验证和清洗。
292
+
293
+ ### 3. 不同系统间的数据交换
294
+
295
+ 在微服务架构中,不同服务可能使用不同的数据格式,此库可以帮助统一数据格式。
296
+
297
+ ### 4. 前后端数据格式差异
298
+
299
+ 解决前端和后端开发团队使用不同命名约定的问题。
81
300
 
82
- # 欢迎反馈
301
+ ## 🛠️ API 参考
302
+
303
+ ### Transformer 类方法
304
+
305
+ | 方法 | 描述 |
306
+ |-----------------------------|---------------------------|
307
+ | `fromJson(json)` | 从 JSON 对象创建类实例 |
308
+ | `fromJsonArray(jsonArray)` | 从 JSON 数组创建类实例数组 |
309
+ | `newInstance(Class, json?)` | 创建类的新实例,可选择性地用 JSON 数据初始化 |
310
+ | `copy()` | 复制当前实例 |
311
+ | `expose(...fields)` | 只保留指定的字段 |
312
+ | `exclude(...fields)` | 排除指定的字段 |
313
+ | `recoverBy(json)` | 用 JSON 数据恢复实例状态 |
314
+ | `toJson()` | 将实例转换为 JSON |
315
+
316
+ ### 装饰器
317
+
318
+ | 装饰器 | 参数 | 描述 |
319
+ |-----------------------------------------------|-------------|-------------------|
320
+ | `@Prefix(prefix: string)` | 前缀字符串 | 为类的所有字段设置统一前缀 |
321
+ | `@Alias(alias: string)` | 别名字符串 | 为字段设置别名 |
322
+ | `@IgnorePrefix()` | 无 | 让字段忽略类级别的前缀 |
323
+ | `@Type(constructor: Class, isArray: boolean)` | 类构造函数和是否为数组 | 指定字段的类型 |
324
+ | `@ToClass(func: (json) => any)` | 自定义转换函数 | 自定义从 JSON 到类的转换逻辑 |
325
+ | `@ToJson(func: (instance) => any)` | 自定义转换函数 | 自定义从类到 JSON 的转换逻辑 |
326
+
327
+ ## 🤝 贡献
328
+
329
+ 欢迎提交 Issue 和 Pull Request 来帮助改进这个项目!
330
+
331
+ ## ⏰ 支持与反馈
83
332
 
84
333
  如有疑问,可以通过本仓库的 **Issues** 与我们联系,如果你有一些代码贡献,可以通过 **Pull Request** 将代码贡献,为这个项目添砖加瓦。
85
334
 
86
335
  如果有更多的需求和建议,欢迎通过本仓库的 `Issues` 提出,也欢迎加入 QQ群 555156313 与我们及时反馈。
336
+
337
+ ## 📄 许可证
338
+
339
+ MIT License
340
+
341
+ ---
342
+
343
+ <p align="center">
344
+ <a href="https://github.com/AirPowerTeam/AirPower-Transformer">Github</a> /
345
+ <a href="https://gitee.com/air-power/AirPower-Transformer">Gitee</a> /
346
+ <a href="https://www.npmjs.com/package/@airpower/transformer">NPM</a>
347
+ </p>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@airpower/transformer",
3
3
  "type": "module",
4
- "version": "2.0.1",
4
+ "version": "2.1.0",
5
5
  "description": "AirPower-Transformer 是一个基于 TypeScript 的数据转换器,提供了从 JSON 对象到 类实例 对象之间互相转换的系列装饰器和方法。",
6
6
  "author": {
7
7
  "name": "Hamm",
@@ -35,12 +35,9 @@
35
35
  "dist"
36
36
  ],
37
37
  "scripts": {
38
- "build": "eslint && tsc && vite build",
39
- "lint": "eslint src --ext .ts",
40
- "preview": "vite preview"
41
- },
42
- "dependencies": {
38
+ "build": "eslint && tsc && vite build"
43
39
  },
40
+ "dependencies": {},
44
41
  "devDependencies": {
45
42
  "@antfu/eslint-config": "^6.2.0",
46
43
  "@types/node": "^24.10.0",