koatty_validation 1.6.0 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [1.6.1](https://github.com/koatty/koatty_validation/compare/v1.6.0...v1.6.1) (2025-10-23)
6
+
5
7
  ## [1.6.0](https://github.com/koatty/koatty_validation/compare/v1.5.0...v1.6.0) (2025-10-22)
6
8
 
7
9
 
package/README.md CHANGED
@@ -36,10 +36,16 @@ export class Controller {
36
36
  // 业务逻辑
37
37
  }
38
38
 
39
- // DTO 验证
39
+ // DTO 验证 - 异步模式(默认,适用于 Koatty 框架)
40
40
  @Validated()
41
41
  TestDto(user: UserDTO) {
42
- // 自动验证 UserDTO
42
+ // 框架会在异步获取参数后自动验证 UserDTO
43
+ }
44
+
45
+ // DTO 验证 - 同步模式(适用于参数已准备好的场景)
46
+ @Validated(false)
47
+ TestDtoSync(user: UserDTO) {
48
+ // 方法执行前立即验证 UserDTO
43
49
  }
44
50
  }
45
51
 
@@ -101,11 +107,107 @@ export class UserDTO {
101
107
 
102
108
  ```typescript
103
109
  @Valid(rule, options) // 参数验证
104
- @Validated() // DTO验证
110
+ @Validated() // DTO验证 (默认异步模式)
111
+ @Validated(true) // DTO验证 (异步模式)
112
+ @Validated(false) // DTO验证 (同步模式)
105
113
  @Expose() // 暴露属性
106
114
  @IsDefined() // 已定义(Expose别名)
107
115
  ```
108
116
 
117
+ ## 🎭 Validated 装饰器
118
+
119
+ `@Validated` 装饰器支持同步和异步两种验证模式,以适应不同的应用场景。
120
+
121
+ ### 异步模式(默认)
122
+
123
+ 适用于 **Koatty 框架**中,控制器方法的参数需要异步获取的场景。
124
+
125
+ ```typescript
126
+ import { Validated, checkValidated } from 'koatty_validation';
127
+
128
+ class UserController {
129
+ // 默认异步模式
130
+ @Validated()
131
+ async register(user: UserDTO) {
132
+ // 框架流程:
133
+ // 1. 框架接收 HTTP 请求
134
+ // 2. 框架异步解析请求体,构造 UserDTO 实例
135
+ // 3. 框架检测到 @Validated() 元数据
136
+ // 4. 框架调用 checkValidated() 验证参数
137
+ // 5. 验证通过后调用此方法
138
+ return { success: true };
139
+ }
140
+
141
+ // 显式指定异步模式
142
+ @Validated(true)
143
+ async update(id: number, user: UserDTO) {
144
+ return { success: true };
145
+ }
146
+ }
147
+ ```
148
+
149
+ **异步模式特点:**
150
+ - ✅ 装饰器保存验证元数据到 IOC 容器
151
+ - ✅ 由框架在异步获取参数后执行验证
152
+ - ✅ 适用于参数值需要异步获取的场景
153
+ - ✅ 是 Koatty 框架的推荐模式
154
+
155
+ ### 同步模式
156
+
157
+ 适用于**单元测试**或参数值已经准备好的场景。
158
+
159
+ ```typescript
160
+ class UserService {
161
+ // 同步模式 - 立即验证
162
+ @Validated(false)
163
+ async createUser(user: UserDTO) {
164
+ // 方法执行前已经完成验证
165
+ return { success: true };
166
+ }
167
+
168
+ // 适用于多个参数的场景
169
+ @Validated(false)
170
+ async updateUser(id: number, user: UserDTO) {
171
+ // 只验证类类型参数(UserDTO),基础类型(number)不验证
172
+ return { success: true };
173
+ }
174
+ }
175
+ ```
176
+
177
+ **同步模式特点:**
178
+ - ✅ 装饰器包装原方法,在调用时立即执行验证
179
+ - ✅ 适用于单元测试场景
180
+ - ✅ 适用于参数已准备好的场景
181
+ - ✅ 验证失败立即抛出错误
182
+
183
+ ### 手动调用 checkValidated
184
+
185
+ 在框架拦截器或中间件中,可以手动调用 `checkValidated` 函数:
186
+
187
+ ```typescript
188
+ import { checkValidated } from 'koatty_validation';
189
+
190
+ async function validateInMiddleware(args: any[], paramTypes: any[]) {
191
+ try {
192
+ const { validatedArgs, validationTargets } = await checkValidated(args, paramTypes);
193
+ console.log('验证通过');
194
+ return validationTargets;
195
+ } catch (error) {
196
+ console.error('验证失败:', error);
197
+ throw error;
198
+ }
199
+ }
200
+ ```
201
+
202
+ ### 选择合适的模式
203
+
204
+ | 场景 | 推荐模式 | 原因 |
205
+ |------|---------|------|
206
+ | Koatty 框架控制器 | 异步 `@Validated()` | 参数需要异步获取 |
207
+ | 单元测试 | 同步 `@Validated(false)` | 参数已准备好,立即验证 |
208
+ | 独立服务/工具 | 同步 `@Validated(false)` | 不依赖框架,立即验证 |
209
+ | 框架拦截器 | 手动 `checkValidated()` | 完全控制验证时机 |
210
+
109
211
  ## 🔧 自定义装饰器
110
212
 
111
213
  ### 使用装饰器工厂创建自定义验证器
@@ -310,6 +412,7 @@ const validatedData = await ClassValidator.valid(UserSchema, rawData, true);
310
412
  - [基础用法示例](./examples/basic-usage.ts)
311
413
  - [自定义装饰器示例](./examples/custom-decorators-example.ts)
312
414
  - [完整使用示例](./examples/usage-example.ts)
415
+ - [Validated 异步/同步模式示例](./examples/validated-async-sync-example.ts)
313
416
 
314
417
  ## 🔍 可用验证函数
315
418
 
package/dist/README.md CHANGED
@@ -36,10 +36,16 @@ export class Controller {
36
36
  // 业务逻辑
37
37
  }
38
38
 
39
- // DTO 验证
39
+ // DTO 验证 - 异步模式(默认,适用于 Koatty 框架)
40
40
  @Validated()
41
41
  TestDto(user: UserDTO) {
42
- // 自动验证 UserDTO
42
+ // 框架会在异步获取参数后自动验证 UserDTO
43
+ }
44
+
45
+ // DTO 验证 - 同步模式(适用于参数已准备好的场景)
46
+ @Validated(false)
47
+ TestDtoSync(user: UserDTO) {
48
+ // 方法执行前立即验证 UserDTO
43
49
  }
44
50
  }
45
51
 
@@ -101,11 +107,107 @@ export class UserDTO {
101
107
 
102
108
  ```typescript
103
109
  @Valid(rule, options) // 参数验证
104
- @Validated() // DTO验证
110
+ @Validated() // DTO验证 (默认异步模式)
111
+ @Validated(true) // DTO验证 (异步模式)
112
+ @Validated(false) // DTO验证 (同步模式)
105
113
  @Expose() // 暴露属性
106
114
  @IsDefined() // 已定义(Expose别名)
107
115
  ```
108
116
 
117
+ ## 🎭 Validated 装饰器
118
+
119
+ `@Validated` 装饰器支持同步和异步两种验证模式,以适应不同的应用场景。
120
+
121
+ ### 异步模式(默认)
122
+
123
+ 适用于 **Koatty 框架**中,控制器方法的参数需要异步获取的场景。
124
+
125
+ ```typescript
126
+ import { Validated, checkValidated } from 'koatty_validation';
127
+
128
+ class UserController {
129
+ // 默认异步模式
130
+ @Validated()
131
+ async register(user: UserDTO) {
132
+ // 框架流程:
133
+ // 1. 框架接收 HTTP 请求
134
+ // 2. 框架异步解析请求体,构造 UserDTO 实例
135
+ // 3. 框架检测到 @Validated() 元数据
136
+ // 4. 框架调用 checkValidated() 验证参数
137
+ // 5. 验证通过后调用此方法
138
+ return { success: true };
139
+ }
140
+
141
+ // 显式指定异步模式
142
+ @Validated(true)
143
+ async update(id: number, user: UserDTO) {
144
+ return { success: true };
145
+ }
146
+ }
147
+ ```
148
+
149
+ **异步模式特点:**
150
+ - ✅ 装饰器保存验证元数据到 IOC 容器
151
+ - ✅ 由框架在异步获取参数后执行验证
152
+ - ✅ 适用于参数值需要异步获取的场景
153
+ - ✅ 是 Koatty 框架的推荐模式
154
+
155
+ ### 同步模式
156
+
157
+ 适用于**单元测试**或参数值已经准备好的场景。
158
+
159
+ ```typescript
160
+ class UserService {
161
+ // 同步模式 - 立即验证
162
+ @Validated(false)
163
+ async createUser(user: UserDTO) {
164
+ // 方法执行前已经完成验证
165
+ return { success: true };
166
+ }
167
+
168
+ // 适用于多个参数的场景
169
+ @Validated(false)
170
+ async updateUser(id: number, user: UserDTO) {
171
+ // 只验证类类型参数(UserDTO),基础类型(number)不验证
172
+ return { success: true };
173
+ }
174
+ }
175
+ ```
176
+
177
+ **同步模式特点:**
178
+ - ✅ 装饰器包装原方法,在调用时立即执行验证
179
+ - ✅ 适用于单元测试场景
180
+ - ✅ 适用于参数已准备好的场景
181
+ - ✅ 验证失败立即抛出错误
182
+
183
+ ### 手动调用 checkValidated
184
+
185
+ 在框架拦截器或中间件中,可以手动调用 `checkValidated` 函数:
186
+
187
+ ```typescript
188
+ import { checkValidated } from 'koatty_validation';
189
+
190
+ async function validateInMiddleware(args: any[], paramTypes: any[]) {
191
+ try {
192
+ const { validatedArgs, validationTargets } = await checkValidated(args, paramTypes);
193
+ console.log('验证通过');
194
+ return validationTargets;
195
+ } catch (error) {
196
+ console.error('验证失败:', error);
197
+ throw error;
198
+ }
199
+ }
200
+ ```
201
+
202
+ ### 选择合适的模式
203
+
204
+ | 场景 | 推荐模式 | 原因 |
205
+ |------|---------|------|
206
+ | Koatty 框架控制器 | 异步 `@Validated()` | 参数需要异步获取 |
207
+ | 单元测试 | 同步 `@Validated(false)` | 参数已准备好,立即验证 |
208
+ | 独立服务/工具 | 同步 `@Validated(false)` | 不依赖框架,立即验证 |
209
+ | 框架拦截器 | 手动 `checkValidated()` | 完全控制验证时机 |
210
+
109
211
  ## 🔧 自定义装饰器
110
212
 
111
213
  ### 使用装饰器工厂创建自定义验证器
@@ -310,6 +412,7 @@ const validatedData = await ClassValidator.valid(UserSchema, rawData, true);
310
412
  - [基础用法示例](./examples/basic-usage.ts)
311
413
  - [自定义装饰器示例](./examples/custom-decorators-example.ts)
312
414
  - [完整使用示例](./examples/usage-example.ts)
415
+ - [Validated 异步/同步模式示例](./examples/validated-async-sync-example.ts)
313
416
 
314
417
  ## 🔍 可用验证函数
315
418
 
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * @Author: richen
3
- * @Date: 2025-10-23 01:25:11
3
+ * @Date: 2025-10-23 20:54:44
4
4
  * @License: BSD (3-Clause)
5
5
  * @Copyright (c) - <richenlin(at)gmail.com>
6
6
  * @HomePage: https://koatty.org/
@@ -14,7 +14,7 @@ import { ValidationOptions } from 'class-validator';
14
14
  export declare function cached(validator: string, ttl?: number): (target: any, propertyName: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
15
15
 
16
16
  /**
17
- * 缓存配置选项
17
+ * Cache configuration options
18
18
  */
19
19
  export declare interface CacheOptions {
20
20
  max?: number;
@@ -32,6 +32,17 @@ export declare interface CacheOptions {
32
32
  */
33
33
  export declare function checkParamsType(value: any, type: string): any;
34
34
 
35
+ /**
36
+ * Synchronous validation function - Executes the actual validation logic
37
+ * @param args Method parameters
38
+ * @param paramTypes Parameter type metadata
39
+ * @returns Validated parameters and validation targets
40
+ */
41
+ export declare function checkValidated(args: any[], paramTypes: any[]): Promise<{
42
+ validatedArgs: any[];
43
+ validationTargets: any[];
44
+ }>;
45
+
35
46
  /**
36
47
  * ClassValidator for manual
37
48
  */
@@ -71,37 +82,37 @@ export declare function convertDtoParamsType(clazz: any, cls: any): any;
71
82
  export declare function convertParamsType(param: any, type: string): any;
72
83
 
73
84
  /**
74
- * 创建带参数的验证装饰器
75
- * @param name 装饰器名称
76
- * @param validator 验证函数
77
- * @param defaultMessage 默认错误信息
78
- * @returns 装饰器工厂函数
85
+ * Create parameterized validation decorator
86
+ * @param name Decorator name
87
+ * @param validator Validation function
88
+ * @param defaultMessage Default error message
89
+ * @returns Decorator factory function
79
90
  */
80
91
  export declare function createParameterizedDecorator(name: string, validator: ValidatorFunction, defaultMessage?: string): (...args: any[]) => (object: Object, propertyName: string) => void;
81
92
 
82
93
  /**
83
- * 创建简单验证装饰器(不需要额外参数)
84
- * @param name 装饰器名称
85
- * @param validator 验证函数
86
- * @param defaultMessage 默认错误信息
87
- * @returns 装饰器函数
94
+ * Create simple validation decorator (no additional parameters required)
95
+ * @param name Decorator name
96
+ * @param validator Validation function
97
+ * @param defaultMessage Default error message
98
+ * @returns Decorator function
88
99
  */
89
100
  export declare function createSimpleDecorator(name: string, validator: ValidatorFunction, defaultMessage?: string): (...args: any[]) => (object: Object, propertyName: string) => void;
90
101
 
91
102
  /**
92
- * 创建验证装饰器的工厂函数
93
- * @param options 装饰器配置选项
94
- * @returns 装饰器工厂函数
103
+ * Factory function to create validation decorators
104
+ * @param options Decorator configuration options
105
+ * @returns Decorator factory function
95
106
  */
96
107
  export declare function createValidationDecorator(options: DecoratorOptions): (...args: any[]) => (object: Object, propertyName: string) => void;
97
108
 
98
109
  /**
99
- * 创建验证错误
110
+ * Create validation error
100
111
  */
101
112
  export declare function createValidationError(field: string, value: any, constraint: string, customMessage?: string, context?: Record<string, any>): ValidationErrorDetail;
102
113
 
103
114
  /**
104
- * 批量创建验证错误
115
+ * Create validation errors in batch
105
116
  */
106
117
  export declare function createValidationErrors(errors: Array<{
107
118
  field: string;
@@ -112,7 +123,7 @@ export declare function createValidationErrors(errors: Array<{
112
123
  }>): KoattyValidationError;
113
124
 
114
125
  /**
115
- * 装饰器选项
126
+ * Decorator options
116
127
  */
117
128
  export declare interface DecoratorOptions {
118
129
  name: string;
@@ -126,7 +137,7 @@ export declare const ENABLE_VALIDATED = "ENABLE_VALIDATED";
126
137
  export declare const Equals: (...args: any[]) => (object: Object, propertyName: string) => void;
127
138
 
128
139
  /**
129
- * 错误信息国际化
140
+ * Error message internationalization
130
141
  */
131
142
  export declare const ERROR_MESSAGES: {
132
143
  readonly zh: {
@@ -182,31 +193,31 @@ export declare const ERROR_MESSAGES: {
182
193
  };
183
194
 
184
195
  /**
185
- * 全局错误信息格式化器实例
196
+ * Global error message formatter instance
186
197
  */
187
198
  export declare const errorFormatter: ErrorMessageFormatter;
188
199
 
189
200
  /**
190
- * 错误信息格式化器
201
+ * Error message formatter
191
202
  */
192
203
  export declare class ErrorMessageFormatter {
193
204
  constructor(language?: SupportedLanguage);
194
205
  /**
195
- * 设置语言
206
+ * Set language
196
207
  */
197
208
  setLanguage(language: SupportedLanguage): void;
198
209
  /**
199
- * 格式化错误消息
210
+ * Format error message
200
211
  */
201
212
  formatMessage(constraint: string, field: string, value?: any, context?: Record<string, any>): string;
202
213
  /**
203
- * 格式化值用于消息显示
214
+ * Format value for message display
204
215
  * @private
205
216
  */
206
217
  }
207
218
 
208
219
  /**
209
- * 标记属性为可导出
220
+ * Mark property as exportable
210
221
  */
211
222
  export declare function Expose(): PropertyDecorator;
212
223
 
@@ -272,7 +283,7 @@ export declare const Gt: (...args: any[]) => (object: Object, propertyName: stri
272
283
  export declare const Gte: (...args: any[]) => (object: Object, propertyName: string) => void;
273
284
 
274
285
  /**
275
- * 哈希算法类型
286
+ * Hash algorithm type
276
287
  */
277
288
  export declare type HashAlgorithm = "md4" | "md5" | "sha1" | "sha256" | "sha384" | "sha512" | "ripemd128" | "ripemd160" | "tiger128" | "tiger160" | "tiger192" | "crc32" | "crc32b";
278
289
 
@@ -281,20 +292,20 @@ export declare const IsCnName: (...args: any[]) => (object: Object, propertyName
281
292
  export declare const IsDate: (...args: any[]) => (object: Object, propertyName: string) => void;
282
293
 
283
294
  /**
284
- * Expose的别名
295
+ * Alias for Expose
285
296
  */
286
297
  export declare function IsDefined(): PropertyDecorator;
287
298
 
288
299
  export declare function IsEmail(options?: IsEmailOptions, validationOptions?: ValidationOptions): (object: Object, propertyName: string) => void;
289
300
 
290
301
  /**
291
- * koatty_validation 类型定义
302
+ * koatty_validation type definitions
292
303
  * @author richen
293
304
  * @copyright Copyright (c) - <richenlin(at)gmail.com>
294
305
  * @license MIT
295
306
  */
296
307
  /**
297
- * 邮箱验证选项
308
+ * Email validation options
298
309
  */
299
310
  export declare interface IsEmailOptions {
300
311
  allow_display_name?: boolean;
@@ -324,7 +335,7 @@ export declare const IsPlateNumber: (...args: any[]) => (object: Object, propert
324
335
  export declare function IsUrl(options?: IsURLOptions, validationOptions?: ValidationOptions): (object: Object, propertyName: string) => void;
325
336
 
326
337
  /**
327
- * URL验证选项
338
+ * URL validation options
328
339
  */
329
340
  export declare interface IsURLOptions {
330
341
  protocols?: string[];
@@ -343,7 +354,7 @@ export declare interface IsURLOptions {
343
354
  export declare const IsZipCode: (...args: any[]) => (object: Object, propertyName: string) => void;
344
355
 
345
356
  /**
346
- * 增强的验证错误类
357
+ * Enhanced validation error class
347
358
  */
348
359
  export declare class KoattyValidationError extends Error {
349
360
  readonly errors: ValidationErrorDetail[];
@@ -351,15 +362,15 @@ export declare class KoattyValidationError extends Error {
351
362
  readonly timestamp: Date;
352
363
  constructor(errors: ValidationErrorDetail[], message?: string);
353
364
  /**
354
- * 获取第一个错误信息
365
+ * Get the first error message
355
366
  */
356
367
  getFirstError(): ValidationErrorDetail | undefined;
357
368
  /**
358
- * 获取指定字段的错误
369
+ * Get errors for a specific field
359
370
  */
360
371
  getFieldErrors(field: string): ValidationErrorDetail[];
361
372
  /**
362
- * 转换为JSON格式
373
+ * Convert to JSON format
363
374
  */
364
375
  toJSON(): {
365
376
  name: string;
@@ -375,28 +386,28 @@ export declare const Lt: (...args: any[]) => (object: Object, propertyName: stri
375
386
  export declare const Lte: (...args: any[]) => (object: Object, propertyName: string) => void;
376
387
 
377
388
  /**
378
- * 元数据缓存
389
+ * Metadata cache
379
390
  */
380
391
  declare class MetadataCache {
381
392
  static getInstance(): MetadataCache;
382
393
  /**
383
- * 获取类的元数据缓存
394
+ * Get metadata cache for a class
384
395
  */
385
396
  getClassCache(target: Function): Map<string, any>;
386
397
  /**
387
- * 缓存元数据
398
+ * Cache metadata
388
399
  */
389
400
  setMetadata(target: Function, key: string, value: any): void;
390
401
  /**
391
- * 获取缓存的元数据
402
+ * Get cached metadata
392
403
  */
393
404
  getMetadata(target: Function, key: string): any;
394
405
  /**
395
- * 检查是否已缓存
406
+ * Check if metadata is cached
396
407
  */
397
408
  hasMetadata(target: Function, key: string): boolean;
398
409
  /**
399
- * 清空指定类的缓存
410
+ * Clear cache for a specific class
400
411
  */
401
412
  clearClassCache(target: Function): void;
402
413
  }
@@ -410,7 +421,7 @@ export declare const PARAM_CHECK_KEY = "PARAM_CHECK_KEY";
410
421
  export declare const PARAM_RULE_KEY = "PARAM_RULE_KEY";
411
422
 
412
423
  /**
413
- * 参数类型键常量
424
+ * Parameter type key constant
414
425
  */
415
426
  export declare const PARAM_TYPE_KEY = "PARAM_TYPE_KEY";
416
427
 
@@ -524,21 +535,21 @@ declare class RegexCache {
524
535
  export declare const regexCache: RegexCache;
525
536
 
526
537
  /**
527
- * 设置全局语言
538
+ * Set global language
528
539
  */
529
540
  export declare function setValidationLanguage(language: SupportedLanguage): void;
530
541
 
531
542
  /**
532
- * 改进的错误处理机制
543
+ * Improved error handling mechanism
533
544
  * @author richen
534
545
  */
535
546
  /**
536
- * 支持的语言
547
+ * Supported languages
537
548
  */
538
549
  export declare type SupportedLanguage = 'zh' | 'en';
539
550
 
540
551
  /**
541
- * 参数验证装饰器
552
+ * Parameter validation decorator
542
553
  */
543
554
  export declare function Valid(rule: ValidRules | ValidRules[] | Function, options?: string | ValidOtpions): ParameterDecorator;
544
555
 
@@ -564,13 +575,16 @@ declare class ValidateClass {
564
575
  }
565
576
 
566
577
  /**
567
- * 方法验证装饰器
568
- * 自动验证方法参数中的 DTO 对象
578
+ * Method validation decorator
579
+ * Automatically validates DTO objects in method parameters
580
+ * @param isAsync Whether to use async validation mode, default is true
581
+ * - true: Async mode, validation is handled by IOC container in the framework (suitable for scenarios where parameter values need to be obtained asynchronously)
582
+ * - false: Sync mode, validation is performed immediately when the method is called (suitable for scenarios where parameter values are already prepared)
569
583
  */
570
- export declare function Validated(): MethodDecorator;
584
+ export declare function Validated(isAsync?: boolean): MethodDecorator;
571
585
 
572
586
  /**
573
- * 验证结果缓存
587
+ * Validation result cache
574
588
  */
575
589
  declare class ValidationCache {
576
590
  constructor(options?: CacheOptions);
@@ -623,7 +637,7 @@ declare class ValidationCache {
623
637
  export declare const validationCache: ValidationCache;
624
638
 
625
639
  /**
626
- * 验证错误详情
640
+ * Validation error details
627
641
  */
628
642
  export declare interface ValidationErrorDetail {
629
643
  field: string;
@@ -634,7 +648,7 @@ export declare interface ValidationErrorDetail {
634
648
  }
635
649
 
636
650
  /**
637
- * 验证函数类型定义
651
+ * Validator function type definition
638
652
  */
639
653
  export declare type ValidatorFunction = (value: any, ...args: any[]) => boolean;
640
654
 
@@ -736,7 +750,7 @@ export declare const ValidFuncs: {
736
750
  };
737
751
 
738
752
  /**
739
- * 验证选项
753
+ * Validation options
740
754
  */
741
755
  export declare type ValidOtpions = {
742
756
  message: string;