schema-dsl 1.1.4 → 1.1.5

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.
@@ -688,16 +688,261 @@ if (!result.valid) {
688
688
 
689
689
  ---
690
690
 
691
+ ## v1.1.5 新功能:对象格式错误配置
692
+
693
+ ### 概述
694
+
695
+ 从 v1.1.5 开始,语言包支持对象格式 `{ code, message }`,实现统一的错误代码管理。
696
+
697
+ ### 基础用法
698
+
699
+ **语言包配置**:
700
+ ```javascript
701
+ // lib/locales/zh-CN.js (或自定义语言包)
702
+ module.exports = {
703
+ // 字符串格式(向后兼容)
704
+ 'user.notFound': '用户不存在',
705
+
706
+ // 对象格式(v1.1.5 新增)✨ - 使用数字错误码
707
+ 'account.notFound': {
708
+ code: 40001,
709
+ message: '账户不存在'
710
+ },
711
+ 'account.insufficientBalance': {
712
+ code: 40002,
713
+ message: '余额不足,当前余额{{#balance}},需要{{#required}}'
714
+ },
715
+ 'order.notPaid': {
716
+ code: 50001,
717
+ message: '订单未支付'
718
+ }
719
+ };
720
+ ```
721
+
722
+ **使用示例**:
723
+ ```javascript
724
+ const { dsl } = require('schema-dsl');
725
+
726
+ try {
727
+ dsl.error.throw('account.notFound');
728
+ } catch (error) {
729
+ console.log(error.originalKey); // 'account.notFound'
730
+ console.log(error.code); // 40001 ✨ 数字错误码
731
+ console.log(error.message); // '账户不存在'
732
+ }
733
+ ```
734
+
735
+ ### 核心特性
736
+
737
+ #### 1. originalKey 字段(新增)
738
+
739
+ 保留原始的 key,便于调试和日志追踪:
740
+
741
+ ```javascript
742
+ try {
743
+ dsl.error.throw('account.notFound');
744
+ } catch (error) {
745
+ error.originalKey // 'account.notFound' (原始 key)
746
+ error.code // 40001 (数字错误码)
747
+ }
748
+ ```
749
+
750
+ #### 2. 多语言共享 code
751
+
752
+ 不同语言使用相同的数字 `code`,便于前端统一处理:
753
+
754
+ ```javascript
755
+ // zh-CN.js
756
+ 'account.notFound': {
757
+ code: 40001, // ← 数字 code 一致
758
+ message: '账户不存在'
759
+ }
760
+
761
+ // en-US.js
762
+ 'account.notFound': {
763
+ code: 40001, // ← 数字 code 一致
764
+ message: 'Account not found'
765
+ }
766
+
767
+ // 前端处理 - 不受语言影响
768
+ switch (error.code) {
769
+ case 40001:
770
+ redirectToLogin();
771
+ break;
772
+ case 40002:
773
+ showTopUpDialog();
774
+ break;
775
+ case 50001:
776
+ showPaymentDialog();
777
+ break;
778
+ }
779
+ #### 3. 增强的 error.is() 方法
780
+
781
+ 同时支持 `originalKey` 和数字 `code` 判断:
782
+
783
+ ```javascript
784
+ try {
785
+ dsl.error.throw('account.notFound');
786
+ } catch (error) {
787
+ // 两种方式都可以
788
+ if (error.is('account.notFound')) { } // ✅ 使用 originalKey
789
+ if (error.is(40001)) { } // ✅ 使用数字 code
790
+ }
791
+ ```
792
+
793
+ #### 4. toJSON 包含 originalKey
794
+
795
+ ```javascript
796
+ const json = error.toJSON();
797
+ // {
798
+ // error: 'I18nError',
799
+ // originalKey: 'account.notFound', // ✨ v1.1.5 新增
800
+ // code: 'ACCOUNT_NOT_FOUND',
801
+ // message: '账户不存在',
802
+ // params: {},
803
+ // statusCode: 400,
804
+ // locale: 'zh-CN'
805
+ // }
806
+ ```
807
+
808
+ ### 向后兼容
809
+
810
+ **完全向后兼容** ✅ - 字符串格式自动转换:
811
+
812
+ ```javascript
813
+ // 字符串格式(原有)
814
+ 'user.notFound': '用户不存在'
815
+
816
+ // 自动转换为对象
817
+ dsl.error.throw('user.notFound');
818
+ // error.code = 'user.notFound' (使用 key 作为 code)
819
+ // error.originalKey = 'user.notFound'
820
+ // error.message = '用户不存在'
821
+ ```
822
+
823
+ ### 最佳实践
824
+
825
+ #### 1. 何时使用对象格式
826
+
827
+ **推荐使用对象格式**:
828
+ - ✅ 需要在多语言中统一处理的错误
829
+ - ✅ 需要前端统一判断的错误
830
+ - ✅ 核心业务错误(账户、订单、支付等)
831
+
832
+ **可以使用字符串格式**:
833
+ - ✅ 简单的验证错误
834
+ - ✅ 内部错误(不暴露给前端)
835
+ - ✅ 不需要统一处理的错误
836
+
837
+ #### 2. 错误代码命名规范
838
+
839
+ 推荐使用**数字错误码**,按模块分段:
840
+
841
+ ```javascript
842
+ // 错误码规范(5位数字)
843
+ // 4xxxx - 客户端错误
844
+ // 5xxxx - 业务逻辑错误
845
+ // 6xxxx - 系统错误
846
+
847
+ 'account.notFound': {
848
+ code: 40001, // ✅ 推荐:账户模块,序号001
849
+ message: '账户不存在'
850
+ }
851
+
852
+ 'account.insufficientBalance': {
853
+ code: 40002, // 账户模块,序号002
854
+ message: '余额不足'
855
+ }
856
+
857
+ 'order.notPaid': {
858
+ code: 50001, // ✅ 订单模块,序号001
859
+ message: '订单未支付'
860
+ }
861
+
862
+ 'order.cancelled': {
863
+ code: 50002, // 订单模块,序号002
864
+ message: '订单已取消'
865
+ }
866
+
867
+ 'database.connectionError': {
868
+ code: 60001, // ✅ 系统错误
869
+ message: '数据库连接失败'
870
+ }
871
+ ```
872
+
873
+ **错误码分段建议**:
874
+ - `40001-49999` - 客户端错误(账户、权限、参数验证等)
875
+ - `50001-59999` - 业务逻辑错误(订单、支付、库存等)
876
+ - `60001-69999` - 系统错误(数据库、服务不可用等)
877
+
878
+ #### 3. 前端统一错误处理
879
+
880
+ ```javascript
881
+ // API 调用
882
+ try {
883
+ const response = await fetch('/api/account');
884
+ const data = await response.json();
885
+ } catch (error) {
886
+ // 使用数字 code 统一处理,不受语言影响
887
+ switch (error.code) {
888
+ case 40001: // ACCOUNT_NOT_FOUND
889
+ showNotFoundPage();
890
+ break;
891
+ case 40002: // INSUFFICIENT_BALANCE
892
+ showTopUpDialog(error.params);
893
+ break;
894
+ case 50001: // ORDER_NOT_PAID
895
+ showPaymentDialog();
896
+ break;
897
+ case 60001: // SYSTEM_ERROR
898
+ showSystemErrorPage();
899
+ break;
900
+ default:
901
+ showGenericError(error.message);
902
+ }
903
+ }
904
+ ```
905
+
906
+ **更优雅的方式 - 错误码映射**:
907
+ ```javascript
908
+ // errorCodeMap.js
909
+ const ERROR_HANDLERS = {
910
+ 40001: () => router.push('/account-not-found'),
911
+ 40002: (error) => showDialog('topup', error.params),
912
+ 50001: (error) => showDialog('payment', error.params),
913
+ 60001: () => showSystemErrorPage(),
914
+ };
915
+
916
+ // 统一错误处理
917
+ function handleError(error) {
918
+ const handler = ERROR_HANDLERS[error.code];
919
+ if (handler) {
920
+ handler(error);
921
+ } else {
922
+ showGenericError(error.message);
923
+ }
924
+ }
925
+ ```
926
+
927
+ ### 更多信息
928
+
929
+ - [v1.1.5 完整变更日志](../changelogs/v1.1.5.md)
930
+ - [升级指南](../changelogs/v1.1.5.md#升级指南)
931
+ - [最佳实践](../changelogs/v1.1.5.md#最佳实践)
932
+
933
+ ---
934
+
691
935
  ## 相关文档
692
936
 
693
937
  - [API 参考文档](./api-reference.md)
694
938
  - [DSL 语法指南](./dsl-syntax.md)
695
939
  - [String 扩展文档](./string-extensions.md)
696
940
  - [多语言配置](./dynamic-locale.md)
941
+ - [v1.1.5 变更日志](../changelogs/v1.1.5.md)
697
942
 
698
943
  ---
699
944
 
700
-
701
- **最后更新**: 2025-12-25
945
+ **最后更新**: 2026-01-17
946
+ **版本**: v1.1.5
702
947
 
703
948
 
@@ -11,6 +11,33 @@ schema-dsl 的 `dsl.error` 和 `I18nError` 现在支持**运行时指定语言**
11
11
 
12
12
  这对于 **API 开发**特别有用,可以根据每个请求的语言偏好(如 `Accept-Language` 请求头)动态返回对应语言的错误消息。
13
13
 
14
+ ### 🎨 支持的模板语法(v1.1.4+)
15
+
16
+ schema-dsl 现在支持**多种模板语法格式**,提供更好的兼容性:
17
+
18
+ | 语法格式 | 示例 | 说明 | 版本 |
19
+ |---------|------|------|------|
20
+ | `{{#variable}}` | `余额{{#balance}}元` | 井号格式(现有) | v1.0.0+ |
21
+ | `{{variable}}` | `余额{{balance}}元` | 无井号格式(新增) | v1.1.4+ |
22
+ | `{variable}` | `余额{balance}元` | 单花括号(新增) | v1.1.4+ |
23
+ | 混合格式 | `{{#user}}在{date}购买{{product}}` | 可混用多种格式 | v1.1.4+ |
24
+
25
+ **示例**:
26
+ ```javascript
27
+ // 所有格式都支持
28
+ Locale.addLocale('zh-CN', {
29
+ 'msg1': '余额不足,当前{{#balance}}元', // {{#}} 格式
30
+ 'msg2': '用户{{name}}已登录', // {{}} 格式
31
+ 'msg3': '订单{orderId}已支付', // {} 格式
32
+ 'msg4': '{{#user}}在{date}购买了{{product}}' // 混合格式
33
+ });
34
+ ```
35
+
36
+ **向后兼容**:
37
+ - ✅ 现有的 `{{#variable}}` 格式完全兼容
38
+ - ✅ 所有单元测试通过(921个测试)
39
+ - ✅ 无破坏性变更
40
+
14
41
  ---
15
42
 
16
43
  ## 🎯 两种使用方式
package/index.d.ts CHANGED
@@ -1,9 +1,64 @@
1
- // Type definitions for schema-dsl v1.1.2
1
+ // Type definitions for schema-dsl v1.1.5
2
2
  // Project: https://github.com/vextjs/schema-dsl
3
3
  // Definitions by: schema-dsl Team
4
4
 
5
5
  // ========== 核心类型 ==========
6
6
 
7
+ /**
8
+ * 错误消息配置(字符串或对象)
9
+ *
10
+ * @description v1.1.5 新增:支持对象格式配置错误代码和消息
11
+ *
12
+ * @example 字符串格式(向后兼容)
13
+ * ```typescript
14
+ * const messages = {
15
+ * 'user.notFound': '用户不存在'
16
+ * };
17
+ * ```
18
+ *
19
+ * @example 对象格式(v1.1.5 新增)
20
+ * ```typescript
21
+ * const messages = {
22
+ * 'account.notFound': {
23
+ * code: 'ACCOUNT_NOT_FOUND',
24
+ * message: '账户不存在'
25
+ * }
26
+ * };
27
+ * ```
28
+ *
29
+ * @since v1.1.5
30
+ */
31
+ export type ErrorMessageConfig =
32
+ | string // 向后兼容:'账户不存在'
33
+ | { // 新格式:{ code, message }
34
+ /** 错误代码(可选,默认使用 key) */
35
+ code?: string;
36
+ /** 错误消息(必需) */
37
+ message: string;
38
+ };
39
+
40
+ /**
41
+ * 语言包定义
42
+ *
43
+ * @description 语言包对象,key 为错误代码,value 为错误消息配置
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * const zhCN: LocaleMessages = {
48
+ * 'user.notFound': '用户不存在',
49
+ * 'account.notFound': {
50
+ * code: 'ACCOUNT_NOT_FOUND',
51
+ * message: '账户不存在'
52
+ * }
53
+ * };
54
+ * ```
55
+ *
56
+ * @since v1.1.5
57
+ */
58
+ export interface LocaleMessages {
59
+ [key: string]: ErrorMessageConfig;
60
+ }
61
+
7
62
  /**
8
63
  * JSON Schema 对象
9
64
  *
@@ -1700,7 +1755,10 @@ export class I18nError extends Error {
1700
1755
  /** 错误消息(已翻译) */
1701
1756
  message: string;
1702
1757
 
1703
- /** 错误代码(多语言 key */
1758
+ /** 原始 key(v1.1.5 新增) */
1759
+ originalKey: string;
1760
+
1761
+ /** 错误代码(从对象提取或使用 key) */
1704
1762
  code: string;
1705
1763
 
1706
1764
  /** 错误参数(用于插值) */
@@ -1841,9 +1899,26 @@ export class I18nError extends Error {
1841
1899
  /**
1842
1900
  * 转为 JSON 格式(用于 API 响应)
1843
1901
  * @returns JSON 对象
1902
+ *
1903
+ * @example
1904
+ * ```typescript
1905
+ * const json = error.toJSON();
1906
+ * // {
1907
+ * // error: 'I18nError',
1908
+ * // originalKey: 'account.notFound', // v1.1.5 新增
1909
+ * // code: 'ACCOUNT_NOT_FOUND',
1910
+ * // message: '账户不存在',
1911
+ * // params: {},
1912
+ * // statusCode: 400,
1913
+ * // locale: 'zh-CN'
1914
+ * // }
1915
+ * ```
1916
+ *
1917
+ * @since v1.1.5 - 新增 originalKey 字段
1844
1918
  */
1845
1919
  toJSON(): {
1846
1920
  error: string;
1921
+ originalKey: string; // v1.1.5 新增
1847
1922
  code: string;
1848
1923
  message: string;
1849
1924
  params: Record<string, any>;
@@ -62,11 +62,12 @@ class Locale {
62
62
  }
63
63
 
64
64
  /**
65
- * 获取错误消息模板
65
+ * 获取错误消息配置
66
66
  * @param {string} type - 错误类型或消息字符串
67
67
  * @param {Object} [customMessages] - 自定义消息
68
68
  * @param {string} [locale] - 指定语言(可选,默认使用当前语言)
69
- * @returns {string} 消息模板
69
+ * @returns {Object|string} 消息配置对象 { code, message } 或字符串(向后兼容)
70
+ * @version 1.1.5 - 支持对象格式
70
71
  */
71
72
  static getMessage(type, customMessages = {}, locale = null) {
72
73
  // 使用指定的语言或当前全局语言
@@ -74,32 +75,37 @@ class Locale {
74
75
 
75
76
  // 优先级: 自定义消息 > 全局自定义消息 > 语言包 > ErrorCodes > 原字符串
76
77
 
77
- // 1. 自定义消息
78
- if (customMessages[type]) {
79
- return customMessages[type];
78
+ // 1. 查找消息配置
79
+ let messageConfig = customMessages[type]
80
+ || this.customMessages[type]
81
+ || (this.locales[targetLocale] && this.locales[targetLocale][type]);
82
+
83
+ // 2. 如果未找到,尝试从 ErrorCodes 获取
84
+ if (!messageConfig) {
85
+ const errorInfo = getErrorInfo(type);
86
+ if (errorInfo.code === 'UNKNOWN_ERROR') {
87
+ // ✅ 向后兼容:直接返回原字符串(支持硬编码消息)
88
+ return type;
89
+ }
90
+ messageConfig = errorInfo.message;
80
91
  }
81
92
 
82
- // 2. 全局自定义消息
83
- if (this.customMessages[type]) {
84
- return this.customMessages[type];
93
+ // 3. 规范化为对象格式(v1.1.5 新增)
94
+ if (typeof messageConfig === 'string') {
95
+ // 字符串格式 → 转换为对象格式(向后兼容)
96
+ return { code: type, message: messageConfig };
85
97
  }
86
98
 
87
- // 3. 语言包(使用指定的语言)
88
- const localeMessages = this.locales[targetLocale];
89
- if (localeMessages && localeMessages[type]) {
90
- return localeMessages[type];
99
+ if (typeof messageConfig === 'object' && messageConfig !== null && messageConfig.message) {
100
+ // 对象格式 直接使用
101
+ return {
102
+ code: messageConfig.code || type, // 无 code 时使用 type 作为 code
103
+ message: messageConfig.message
104
+ };
91
105
  }
92
106
 
93
- // 4. 默认消息(从ErrorCodes获取)
94
- const errorInfo = getErrorInfo(type);
95
-
96
- // 5. 如果是未知错误,说明不是预定义的错误码
97
- if (errorInfo.code === 'UNKNOWN_ERROR') {
98
- // ✅ 向后兼容:直接返回原字符串(支持硬编码消息)
99
- return type;
100
- }
101
-
102
- return errorInfo.message;
107
+ // 4. 降级处理(边界情况)
108
+ return { code: type, message: type };
103
109
  }
104
110
 
105
111
  /**
@@ -29,32 +29,41 @@ class MessageTemplate {
29
29
  render(context = {}) {
30
30
  let message = this.template;
31
31
 
32
- // 替换所有模板变量
33
- message = message.replace(/\{\{#(\w+)\}\}/g, (match, key) => {
34
- const value = context[key];
32
+ // 定义支持的模板格式(按优先级)
33
+ const patterns = [
34
+ /\{\{#(\w+)\}\}/g, // {{#variable}} - 优先级1(现有格式)
35
+ /\{\{(\w+)\}\}/g, // {{variable}} - 优先级2(无井号)
36
+ /\{(\w+)\}/g // {variable} - 优先级3(单花括号)
37
+ ];
35
38
 
36
- // 特殊处理
37
- if (value === undefined || value === null) {
38
- return match; // 保留原样
39
- }
39
+ // 按优先级依次替换
40
+ for (const pattern of patterns) {
41
+ message = message.replace(pattern, (match, key) => {
42
+ const value = context[key];
40
43
 
41
- // 数组转字符串
42
- if (Array.isArray(value)) {
43
- return value.join(', ');
44
- }
44
+ // 特殊处理
45
+ if (value === undefined || value === null) {
46
+ return match; // 保留原样
47
+ }
45
48
 
46
- // RegExp转字符串
47
- if (value instanceof RegExp) {
48
- return value.toString();
49
- }
49
+ // 数组转字符串
50
+ if (Array.isArray(value)) {
51
+ return value.join(', ');
52
+ }
50
53
 
51
- // Date转字符串
52
- if (value instanceof Date) {
53
- return value.toISOString();
54
- }
54
+ // RegExp转字符串
55
+ if (value instanceof RegExp) {
56
+ return value.toString();
57
+ }
55
58
 
56
- return String(value);
57
- });
59
+ // Date转字符串
60
+ if (value instanceof Date) {
61
+ return value.toISOString();
62
+ }
63
+
64
+ return String(value);
65
+ });
66
+ }
58
67
 
59
68
  return message;
60
69
  }
@@ -477,7 +477,12 @@ class Validator {
477
477
  const errorMsg = failedMessage || cond.message;
478
478
  // 支持多语言:如果 message 是 key(如 'conditional.underAge'),从语言包获取翻译
479
479
  // 传递 locale 参数以支持动态语言切换
480
- const errorMessage = Locale.getMessage(errorMsg, options.messages || {}, locale);
480
+ const messageConfig = Locale.getMessage(errorMsg, options.messages || {}, locale);
481
+
482
+ // v1.1.5: Locale.getMessage 返回对象 { code, message },需要提取 message
483
+ const errorMessage = typeof messageConfig === 'object' && messageConfig.message
484
+ ? messageConfig.message
485
+ : messageConfig;
481
486
 
482
487
  return {
483
488
  valid: false,
@@ -61,15 +61,34 @@ const MessageTemplate = require('../core/MessageTemplate');
61
61
  class I18nError extends Error {
62
62
  /**
63
63
  * 构造函数
64
- * @param {string} code - 错误代码(多语言 key)
64
+ * @param {string} key - 错误代码(多语言 key)
65
65
  * @param {Object} params - 错误参数(用于插值)
66
66
  * @param {number} statusCode - HTTP 状态码(默认 400)
67
67
  * @param {string} locale - 语言环境(默认使用当前语言)
68
+ * @version 1.1.5 - 支持对象格式配置
68
69
  */
69
- constructor(code, params = {}, statusCode = 400, locale = null) {
70
- // 获取翻译后的消息模板
70
+ constructor(key, params = {}, statusCode = 400, locale = null) {
71
+ // 获取语言环境
71
72
  const actualLocale = locale || Locale.getLocale();
72
- const template = Locale.getMessage(code, {}, actualLocale);
73
+
74
+ // 获取消息配置(v1.1.5: 返回对象 { code, message })
75
+ const messageConfig = Locale.getMessage(key, {}, actualLocale);
76
+
77
+ // 判断返回类型(向后兼容)
78
+ let errorCode, template;
79
+ if (typeof messageConfig === 'object' && messageConfig.code && messageConfig.message) {
80
+ // 对象格式:提取 code 和 message
81
+ errorCode = messageConfig.code;
82
+ template = messageConfig.message;
83
+ } else if (typeof messageConfig === 'string') {
84
+ // 字符串格式(向后兼容)
85
+ errorCode = key;
86
+ template = messageConfig;
87
+ } else {
88
+ // 降级处理
89
+ errorCode = key;
90
+ template = key;
91
+ }
73
92
 
74
93
  // 使用 MessageTemplate 进行参数插值
75
94
  const messageTemplate = new MessageTemplate(template);
@@ -78,7 +97,8 @@ class I18nError extends Error {
78
97
  super(message);
79
98
 
80
99
  this.name = 'I18nError';
81
- this.code = code;
100
+ this.originalKey = key; // v1.1.5 新增:保留原始 key
101
+ this.code = errorCode; // v1.1.5 修改:从对象提取或使用 key
82
102
  this.params = params || {};
83
103
  this.statusCode = statusCode;
84
104
  this.locale = actualLocale;
@@ -169,7 +189,7 @@ class I18nError extends Error {
169
189
  /**
170
190
  * 检查错误是否为指定代码
171
191
  *
172
- * @param {string} code - 错误代码
192
+ * @param {string} codeOrKey - 错误代码或原始 key
173
193
  * @returns {boolean} 是否匹配
174
194
  *
175
195
  * @example
@@ -179,10 +199,16 @@ class I18nError extends Error {
179
199
  * if (error instanceof I18nError && error.is('account.notFound')) {
180
200
  * // 处理账户不存在的情况
181
201
  * }
202
+ *
203
+ * // v1.1.5: 也可以用 code 判断
204
+ * if (error instanceof I18nError && error.is('ACCOUNT_NOT_FOUND')) {
205
+ * // 也能匹配
206
+ * }
182
207
  * }
183
208
  */
184
- is(code) {
185
- return this.code === code;
209
+ is(codeOrKey) {
210
+ // v1.1.5: 同时比较 code originalKey(向后兼容)
211
+ return this.code === codeOrKey || this.originalKey === codeOrKey;
186
212
  }
187
213
 
188
214
  /**
@@ -190,6 +216,7 @@ class I18nError extends Error {
190
216
  *
191
217
  * @returns {Object} JSON 对象
192
218
  * @returns {string} return.error - 错误名称
219
+ * @returns {string} return.originalKey - 原始 key(v1.1.5 新增)
193
220
  * @returns {string} return.code - 错误代码
194
221
  * @returns {string} return.message - 错误消息(已翻译)
195
222
  * @returns {Object} return.params - 错误参数
@@ -201,7 +228,8 @@ class I18nError extends Error {
201
228
  * res.status(error.statusCode).json(json);
202
229
  * // {
203
230
  * // error: 'I18nError',
204
- * // code: 'account.notFound',
231
+ * // originalKey: 'account.notFound', // v1.1.5 新增
232
+ * // code: 'ACCOUNT_NOT_FOUND',
205
233
  * // message: '找不到账户',
206
234
  * // params: { accountId: '123' },
207
235
  * // statusCode: 404,
@@ -211,6 +239,7 @@ class I18nError extends Error {
211
239
  toJSON() {
212
240
  return {
213
241
  error: this.name,
242
+ originalKey: this.originalKey, // v1.1.5 新增
214
243
  code: this.code,
215
244
  message: this.message,
216
245
  params: this.params,
@@ -26,10 +26,17 @@ module.exports = {
26
26
  'error.conflict': 'Operation conflict: {{#reason}}',
27
27
 
28
28
  // I18nError - Account related (v1.1.1)
29
- 'account.notFound': 'Account not found',
29
+ // v1.1.5: Using object format for some examples
30
+ 'account.notFound': {
31
+ code: 'ACCOUNT_NOT_FOUND',
32
+ message: 'Account not found'
33
+ },
30
34
  'account.inactive': 'Account is inactive',
31
35
  'account.banned': 'Account has been banned',
32
- 'account.insufficientBalance': 'Insufficient balance, current: {{#balance}}, required: {{#required}}',
36
+ 'account.insufficientBalance': {
37
+ code: 'INSUFFICIENT_BALANCE',
38
+ message: 'Insufficient balance, current: {{#balance}}, required: {{#required}}'
39
+ },
33
40
  'account.insufficientCredits': 'Insufficient credits, current: {{#credits}}, required: {{#required}}',
34
41
 
35
42
  // I18nError - User related (v1.1.1)
@@ -38,7 +45,10 @@ module.exports = {
38
45
  'user.noPermission': 'No admin permission',
39
46
 
40
47
  // I18nError - Order related (v1.1.1)
41
- 'order.notPaid': 'Order not paid',
48
+ 'order.notPaid': {
49
+ code: 'ORDER_NOT_PAID',
50
+ message: 'Order not paid'
51
+ },
42
52
  'order.paymentMissing': 'Payment information missing',
43
53
  'order.addressMissing': 'Shipping address missing',
44
54