schema-dsl 2.0.0 → 2.0.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.
Files changed (145) hide show
  1. package/CHANGELOG.md +130 -113
  2. package/LICENSE +21 -21
  3. package/README.md +628 -628
  4. package/dist/{DslBuilder-DkLaOo9Q.d.ts → DslBuilder-BIgQOAXp.d.ts} +2 -0
  5. package/dist/{DslBuilder-DQDN0ZxZ.d.cts → DslBuilder-CjHTucNQ.d.cts} +2 -0
  6. package/dist/{Validator-hFWKGxir.d.ts → Validator-CllRdrY0.d.ts} +1 -1
  7. package/dist/{Validator-C7GsVQOH.d.cts → Validator-D6okG9tr.d.cts} +1 -1
  8. package/dist/index.cjs +75 -29
  9. package/dist/index.d.cts +10 -4
  10. package/dist/index.d.ts +10 -4
  11. package/dist/index.js +75 -29
  12. package/dist/plugins/custom-format.cjs +33 -17
  13. package/dist/plugins/custom-format.d.cts +1 -1
  14. package/dist/plugins/custom-format.d.ts +1 -1
  15. package/dist/plugins/custom-format.js +33 -17
  16. package/dist/plugins/custom-type-example.cjs +33 -17
  17. package/dist/plugins/custom-type-example.d.cts +1 -1
  18. package/dist/plugins/custom-type-example.d.ts +1 -1
  19. package/dist/plugins/custom-type-example.js +33 -17
  20. package/dist/plugins/custom-validator.cjs +0 -2
  21. package/dist/plugins/custom-validator.d.cts +1 -1
  22. package/dist/plugins/custom-validator.d.ts +1 -1
  23. package/dist/plugins/custom-validator.js +0 -2
  24. package/docs/FEATURE-INDEX.md +553 -553
  25. package/docs/add-custom-locale.md +496 -496
  26. package/docs/add-keyword.md +24 -24
  27. package/docs/api-reference.md +1047 -1047
  28. package/docs/api.md +13 -13
  29. package/docs/best-practices-project-structure.md +417 -417
  30. package/docs/best-practices.md +712 -712
  31. package/docs/cache-manager.md +344 -344
  32. package/docs/compile.md +45 -45
  33. package/docs/conditional-api.md +1307 -1307
  34. package/docs/custom-extensions-guide.md +339 -339
  35. package/docs/design-philosophy.md +606 -606
  36. package/docs/doc-index.md +324 -324
  37. package/docs/dsl-syntax.md +714 -714
  38. package/docs/dynamic-locale.md +608 -608
  39. package/docs/enum.md +482 -482
  40. package/docs/error-handling.md +1975 -1975
  41. package/docs/export-guide.md +501 -501
  42. package/docs/export-limitations.md +567 -567
  43. package/docs/faq.md +596 -596
  44. package/docs/frontend-i18n-guide.md +307 -307
  45. package/docs/i18n-user-guide.md +487 -487
  46. package/docs/i18n.md +476 -476
  47. package/docs/index.md +48 -48
  48. package/docs/json-schema-basics.md +40 -40
  49. package/docs/label-vs-description.md +271 -271
  50. package/docs/markdown-exporter.md +406 -406
  51. package/docs/mongodb-exporter.md +302 -302
  52. package/docs/multi-language.md +26 -26
  53. package/docs/multi-type-support.md +322 -322
  54. package/docs/mysql-exporter.md +280 -280
  55. package/docs/number-operators.md +449 -449
  56. package/docs/optional-marker-guide.md +326 -326
  57. package/docs/performance-guide.md +49 -49
  58. package/docs/plugin-system.md +381 -381
  59. package/docs/plugin-type-registration.md +34 -34
  60. package/docs/postgresql-exporter.md +311 -311
  61. package/docs/public/favicon.svg +4 -4
  62. package/docs/quick-start.md +435 -435
  63. package/docs/runtime-locale-support.md +532 -532
  64. package/docs/schema-helper.md +345 -345
  65. package/docs/schema-utils-advanced-issues.md +23 -23
  66. package/docs/schema-utils-best-practices.md +20 -20
  67. package/docs/schema-utils-chaining.md +150 -150
  68. package/docs/schema-utils.md +524 -524
  69. package/docs/security-checklist.md +20 -20
  70. package/docs/string-extensions.md +488 -488
  71. package/docs/troubleshooting.md +486 -486
  72. package/docs/type-converter.md +310 -310
  73. package/docs/type-reference.md +242 -242
  74. package/docs/typescript-guide.md +584 -584
  75. package/docs/union-type-guide.md +157 -157
  76. package/docs/union-types.md +284 -284
  77. package/docs/validate-async.md +491 -491
  78. package/docs/validate-batch.md +49 -49
  79. package/docs/validate-dsl-object-support.md +578 -578
  80. package/docs/validate.md +506 -506
  81. package/docs/validation-guide.md +502 -502
  82. package/docs/validator.md +39 -39
  83. package/package.json +131 -131
  84. package/plugins/custom-format.cjs +8 -8
  85. package/plugins/custom-type-example.cjs +8 -8
  86. package/plugins/custom-validator.cjs +8 -8
  87. package/src/adapters/DslAdapter.ts +111 -111
  88. package/src/adapters/index.ts +1 -1
  89. package/src/config/constants.ts +83 -83
  90. package/src/config/index.ts +2 -2
  91. package/src/config/patterns.ts +77 -77
  92. package/src/core/CacheManager.ts +169 -159
  93. package/src/core/ConditionalBuilder.ts +382 -382
  94. package/src/core/ConditionalRuntime.ts +27 -27
  95. package/src/core/ConditionalValidator.ts +254 -254
  96. package/src/core/DslBuilder.ts +687 -677
  97. package/src/core/ErrorCodes.ts +38 -38
  98. package/src/core/ErrorFormatter.ts +271 -271
  99. package/src/core/JSONSchemaCore.ts +65 -65
  100. package/src/core/Locale.ts +187 -187
  101. package/src/core/MessageTemplate.ts +42 -42
  102. package/src/core/ObjectDslBuilder.ts +64 -64
  103. package/src/core/PluginManager.ts +326 -326
  104. package/src/core/StringExtensions.ts +140 -140
  105. package/src/core/TemplateEngine.ts +44 -44
  106. package/src/core/Validator.ts +448 -448
  107. package/src/errors/I18nError.ts +159 -159
  108. package/src/errors/ValidationError.ts +105 -105
  109. package/src/exporters/BaseExporter.ts +60 -60
  110. package/src/exporters/MarkdownExporter.ts +305 -305
  111. package/src/exporters/MongoDBExporter.ts +126 -126
  112. package/src/exporters/MySQLExporter.ts +156 -155
  113. package/src/exporters/PostgreSQLExporter.ts +222 -222
  114. package/src/exporters/index.ts +18 -18
  115. package/src/index.ts +651 -633
  116. package/src/locales/en-US.ts +160 -160
  117. package/src/locales/es-ES.ts +160 -160
  118. package/src/locales/fr-FR.ts +160 -160
  119. package/src/locales/index.ts +103 -103
  120. package/src/locales/ja-JP.ts +160 -160
  121. package/src/locales/types.ts +156 -156
  122. package/src/locales/zh-CN.ts +160 -160
  123. package/src/parser/ConstraintParser.ts +101 -101
  124. package/src/parser/DslParser.ts +470 -470
  125. package/src/parser/SchemaCompiler.ts +66 -66
  126. package/src/parser/TypeRegistry.ts +250 -250
  127. package/src/parser/index.ts +6 -6
  128. package/src/plugins/custom-format.ts +124 -126
  129. package/src/plugins/custom-type-example.ts +106 -108
  130. package/src/plugins/custom-validator.ts +138 -140
  131. package/src/types/conditional.ts +28 -28
  132. package/src/types/config.ts +59 -59
  133. package/src/types/dsl.ts +131 -131
  134. package/src/types/error.ts +60 -60
  135. package/src/types/index.ts +17 -17
  136. package/src/types/infer.ts +127 -127
  137. package/src/types/plugin.ts +58 -58
  138. package/src/types/safe-regex.d.ts +9 -9
  139. package/src/types/schema.ts +66 -66
  140. package/src/types/validate.ts +71 -71
  141. package/src/utils/SchemaHelper.ts +196 -196
  142. package/src/utils/SchemaUtils.ts +365 -346
  143. package/src/utils/TypeConverter.ts +215 -215
  144. package/src/utils/index.ts +10 -10
  145. package/src/validators/CustomKeywords.ts +477 -477
@@ -1,160 +1,160 @@
1
- import type { LocaleMessages } from './types.js'
2
-
3
- const enUS: LocaleMessages = {
4
- // Generic
5
- required: '{{#label}} is required',
6
- type: '{{#label}} should be {{#expected}}, got {{#actual}}',
7
- min: '{{#label}} length must be at least {{#limit}}',
8
- max: '{{#label}} length must be at most {{#limit}}',
9
- length: '{{#label}} length must be exactly {{#expected}}',
10
- pattern: '{{#label}} format is invalid',
11
- enum: '{{#label}} must be one of: {{#allowed}}',
12
- custom: '{{#label}} validation failed: {{#message}}',
13
- circular: 'Circular reference detected at {{#label}}',
14
- 'max-depth': 'Maximum recursion depth ({{#depth}}) exceeded at {{#label}}',
15
- exception: '{{#label}} validation exception: {{#message}}',
16
-
17
- // Conditional
18
- 'conditional.underAge': 'Minors cannot register',
19
- 'conditional.blocked': 'Account has been blocked',
20
- 'conditional.notAllowed': 'Registration not allowed',
21
-
22
- // I18nError — generic
23
- 'error.notFound': '{{#resource}} not found',
24
- 'error.forbidden': 'Access to {{#resource}} is forbidden',
25
- 'error.unauthorized': 'Unauthorized, please log in',
26
- 'error.invalid': 'Invalid {{#field}}',
27
- 'error.duplicate': '{{#resource}} already exists',
28
- 'error.conflict': 'Operation conflict: {{#reason}}',
29
-
30
- // Account
31
- 'account.notFound': { code: 'ACCOUNT_NOT_FOUND', message: 'Account not found' },
32
- 'account.inactive': 'Account is inactive',
33
- 'account.banned': 'Account has been banned',
34
- 'account.insufficientBalance': {
35
- code: 'INSUFFICIENT_BALANCE',
36
- message: 'Insufficient balance, current: {{#balance}}, required: {{#required}}',
37
- },
38
- 'account.insufficientCredits': 'Insufficient credits, current: {{#credits}}, required: {{#required}}',
39
-
40
- // User
41
- 'user.notFound': 'User not found',
42
- 'user.notVerified': 'User is not verified',
43
- 'user.noPermission': 'No admin permission',
44
-
45
- // Order
46
- 'order.notPaid': { code: 'ORDER_NOT_PAID', message: 'Order not paid' },
47
- 'order.paymentMissing': 'Payment information missing',
48
- 'order.addressMissing': 'Shipping address missing',
49
-
50
- // Format
51
- 'format.email': '{{#label}} must be a valid email address',
52
- 'format.url': '{{#label}} must be a valid URL',
53
- 'format.uuid': '{{#label}} must be a valid UUID',
54
- 'format.date': '{{#label}} must be a valid date (YYYY-MM-DD)',
55
- 'format.datetime': '{{#label}} must be a valid date-time (ISO 8601)',
56
- 'format.time': '{{#label}} must be a valid time (HH:mm:ss)',
57
- 'format.ipv4': '{{#label}} must be a valid IPv4 address',
58
- 'format.ipv6': '{{#label}} must be a valid IPv6 address',
59
- 'format.binary': '{{#label}} must be a valid base64 string',
60
-
61
- // String
62
- 'string.hostname': '{{#label}} must be a valid hostname',
63
- 'string.pattern': '{{#label}} format does not match required pattern',
64
- 'string.enum': '{{#label}} must be one of: {{#valids}}',
65
- 'string.length': '{{#label}} length must be exactly {{#limit}} characters',
66
- 'string.alphanum': '{{#label}} must only contain alphanumeric characters',
67
- 'string.trim': '{{#label}} must not have leading or trailing whitespace',
68
- 'string.lowercase': '{{#label}} must be lowercase',
69
- 'string.uppercase': '{{#label}} must be uppercase',
70
-
71
- // Number
72
- 'number.base': '{{#label}} must be a number',
73
- 'number.min': '{{#label}} must be greater than or equal to {{#limit}}',
74
- 'number.max': '{{#label}} must be less than or equal to {{#limit}}',
75
- 'number.integer': '{{#label}} must be an integer',
76
- 'number.positive': '{{#label}} must be a positive number',
77
- 'number.negative': '{{#label}} must be a negative number',
78
- 'number.precision': '{{#label}} must have at most {{#limit}} decimal places',
79
- 'number.port': '{{#label}} must be a valid port number (1-65535)',
80
-
81
- // Boolean
82
- 'boolean.base': '{{#label}} must be a boolean',
83
-
84
- // Object
85
- 'object.base': '{{#label}} must be an object',
86
- 'object.min': '{{#label}} must have at least {{#limit}} properties',
87
- 'object.max': '{{#label}} must have at most {{#limit}} properties',
88
- 'object.unknown': '{{#label}} contains unknown property: {{#key}}',
89
- 'object.missing': '{{#label}} is missing required properties',
90
- 'object.schema': '{{#label}} contains additional properties',
91
- 'additionalProperties': '{{#label}} must NOT have additional properties: {{#key}}',
92
-
93
- // Array
94
- 'array.base': '{{#label}} must be an array',
95
- 'array.min': '{{#label}} must have at least {{#limit}} items',
96
- 'array.max': '{{#label}} must have at most {{#limit}} items',
97
- 'array.length': '{{#label}} must have exactly {{#limit}} items',
98
- 'array.unique': '{{#label}} must not contain duplicate items',
99
- 'array.sparse': '{{#label}} must not be a sparse array',
100
- 'array.includesRequired': '{{#label}} must include required items',
101
-
102
- // Date
103
- 'date.base': '{{#label}} must be a valid date',
104
- 'date.min': '{{#label}} must be no earlier than {{#limit}}',
105
- 'date.max': '{{#label}} must be no later than {{#limit}}',
106
- 'date.format': '{{#label}} date format is invalid',
107
- 'date.greater': '{{#label}} must be after {{#limit}}',
108
- 'date.less': '{{#label}} must be before {{#limit}}',
109
-
110
- // Any
111
- 'any.required': '{{#label}} is required',
112
- 'any.invalid': '{{#label}} contains an invalid value',
113
- 'any.only': '{{#label}} must match {{#valids}}',
114
- 'any.unknown': 'Field {{#key}} is not allowed',
115
-
116
- // Patterns
117
- 'pattern.phone': 'Invalid phone number',
118
- 'pattern.phone.international': 'Invalid international phone number',
119
- 'pattern.idCard': 'Invalid ID card number',
120
- 'pattern.creditCard': 'Invalid credit card number',
121
- 'pattern.creditCard.visa': 'Invalid Visa card number',
122
- 'pattern.creditCard.mastercard': 'Invalid Mastercard number',
123
- 'pattern.creditCard.amex': 'Invalid American Express card number',
124
- 'pattern.creditCard.discover': 'Invalid Discover card number',
125
- 'pattern.creditCard.jcb': 'Invalid JCB card number',
126
- 'pattern.creditCard.unionpay': 'Invalid UnionPay card number',
127
- 'pattern.licensePlate': 'Invalid license plate number',
128
- 'pattern.postalCode': 'Invalid postal code',
129
- 'pattern.passport': 'Invalid passport number',
130
- 'pattern.objectId': 'Invalid ObjectId',
131
- 'pattern.hexColor': 'Invalid Hex Color',
132
- 'pattern.macAddress': 'Invalid MAC Address',
133
- 'pattern.cron': 'Invalid Cron Expression',
134
- 'pattern.slug': 'URL slug can only contain lowercase letters, numbers, and hyphens',
135
- 'pattern.domain': '{{#label}} must be a valid domain name',
136
- 'pattern.ip': '{{#label}} must be a valid IP address',
137
- 'pattern.base64': '{{#label}} must be a valid Base64 string',
138
- 'pattern.jwt': '{{#label}} must be a valid JWT token',
139
- 'pattern.json': '{{#label}} must be a valid JSON string',
140
- 'pattern.username': 'Username must start with a letter and contain only letters, numbers, and underscores',
141
- 'pattern.password.weak': 'Password must be at least 6 characters',
142
- 'pattern.password.medium': 'Password must be at least 8 characters and contain letters and numbers',
143
- 'pattern.password.strong': 'Password must be at least 8 characters and contain uppercase, lowercase letters and numbers',
144
- 'pattern.password.veryStrong': 'Password must be at least 10 characters and contain uppercase, lowercase letters, numbers and special characters',
145
- 'pattern.emailOrPhone': 'Must be an email or phone number',
146
- 'pattern.usernameOrEmail': 'Must be a username or email',
147
- 'pattern.httpOrHttps': 'Must be a URL starting with http or https',
148
-
149
- // oneOf
150
- oneOf: '{{#label}} must match one of the following types',
151
- 'oneOf.invalid': '{{#label}} value does not match any allowed type',
152
-
153
- // Error fallback
154
- UNKNOWN_ERROR: 'Unknown validation error',
155
- CUSTOM_VALIDATION_FAILED: 'Validation failed',
156
- ASYNC_VALIDATION_NOT_SUPPORTED: 'Async validation not supported in synchronous validate()',
157
- VALIDATE_MUST_BE_FUNCTION: 'validate must be a function',
158
- }
159
-
160
- export default enUS
1
+ import type { LocaleMessages } from './types.js'
2
+
3
+ const enUS: LocaleMessages = {
4
+ // Generic
5
+ required: '{{#label}} is required',
6
+ type: '{{#label}} should be {{#expected}}, got {{#actual}}',
7
+ min: '{{#label}} length must be at least {{#limit}}',
8
+ max: '{{#label}} length must be at most {{#limit}}',
9
+ length: '{{#label}} length must be exactly {{#expected}}',
10
+ pattern: '{{#label}} format is invalid',
11
+ enum: '{{#label}} must be one of: {{#allowed}}',
12
+ custom: '{{#label}} validation failed: {{#message}}',
13
+ circular: 'Circular reference detected at {{#label}}',
14
+ 'max-depth': 'Maximum recursion depth ({{#depth}}) exceeded at {{#label}}',
15
+ exception: '{{#label}} validation exception: {{#message}}',
16
+
17
+ // Conditional
18
+ 'conditional.underAge': 'Minors cannot register',
19
+ 'conditional.blocked': 'Account has been blocked',
20
+ 'conditional.notAllowed': 'Registration not allowed',
21
+
22
+ // I18nError — generic
23
+ 'error.notFound': '{{#resource}} not found',
24
+ 'error.forbidden': 'Access to {{#resource}} is forbidden',
25
+ 'error.unauthorized': 'Unauthorized, please log in',
26
+ 'error.invalid': 'Invalid {{#field}}',
27
+ 'error.duplicate': '{{#resource}} already exists',
28
+ 'error.conflict': 'Operation conflict: {{#reason}}',
29
+
30
+ // Account
31
+ 'account.notFound': { code: 'ACCOUNT_NOT_FOUND', message: 'Account not found' },
32
+ 'account.inactive': 'Account is inactive',
33
+ 'account.banned': 'Account has been banned',
34
+ 'account.insufficientBalance': {
35
+ code: 'INSUFFICIENT_BALANCE',
36
+ message: 'Insufficient balance, current: {{#balance}}, required: {{#required}}',
37
+ },
38
+ 'account.insufficientCredits': 'Insufficient credits, current: {{#credits}}, required: {{#required}}',
39
+
40
+ // User
41
+ 'user.notFound': 'User not found',
42
+ 'user.notVerified': 'User is not verified',
43
+ 'user.noPermission': 'No admin permission',
44
+
45
+ // Order
46
+ 'order.notPaid': { code: 'ORDER_NOT_PAID', message: 'Order not paid' },
47
+ 'order.paymentMissing': 'Payment information missing',
48
+ 'order.addressMissing': 'Shipping address missing',
49
+
50
+ // Format
51
+ 'format.email': '{{#label}} must be a valid email address',
52
+ 'format.url': '{{#label}} must be a valid URL',
53
+ 'format.uuid': '{{#label}} must be a valid UUID',
54
+ 'format.date': '{{#label}} must be a valid date (YYYY-MM-DD)',
55
+ 'format.datetime': '{{#label}} must be a valid date-time (ISO 8601)',
56
+ 'format.time': '{{#label}} must be a valid time (HH:mm:ss)',
57
+ 'format.ipv4': '{{#label}} must be a valid IPv4 address',
58
+ 'format.ipv6': '{{#label}} must be a valid IPv6 address',
59
+ 'format.binary': '{{#label}} must be a valid base64 string',
60
+
61
+ // String
62
+ 'string.hostname': '{{#label}} must be a valid hostname',
63
+ 'string.pattern': '{{#label}} format does not match required pattern',
64
+ 'string.enum': '{{#label}} must be one of: {{#valids}}',
65
+ 'string.length': '{{#label}} length must be exactly {{#limit}} characters',
66
+ 'string.alphanum': '{{#label}} must only contain alphanumeric characters',
67
+ 'string.trim': '{{#label}} must not have leading or trailing whitespace',
68
+ 'string.lowercase': '{{#label}} must be lowercase',
69
+ 'string.uppercase': '{{#label}} must be uppercase',
70
+
71
+ // Number
72
+ 'number.base': '{{#label}} must be a number',
73
+ 'number.min': '{{#label}} must be greater than or equal to {{#limit}}',
74
+ 'number.max': '{{#label}} must be less than or equal to {{#limit}}',
75
+ 'number.integer': '{{#label}} must be an integer',
76
+ 'number.positive': '{{#label}} must be a positive number',
77
+ 'number.negative': '{{#label}} must be a negative number',
78
+ 'number.precision': '{{#label}} must have at most {{#limit}} decimal places',
79
+ 'number.port': '{{#label}} must be a valid port number (1-65535)',
80
+
81
+ // Boolean
82
+ 'boolean.base': '{{#label}} must be a boolean',
83
+
84
+ // Object
85
+ 'object.base': '{{#label}} must be an object',
86
+ 'object.min': '{{#label}} must have at least {{#limit}} properties',
87
+ 'object.max': '{{#label}} must have at most {{#limit}} properties',
88
+ 'object.unknown': '{{#label}} contains unknown property: {{#key}}',
89
+ 'object.missing': '{{#label}} is missing required properties',
90
+ 'object.schema': '{{#label}} contains additional properties',
91
+ 'additionalProperties': '{{#label}} must NOT have additional properties: {{#key}}',
92
+
93
+ // Array
94
+ 'array.base': '{{#label}} must be an array',
95
+ 'array.min': '{{#label}} must have at least {{#limit}} items',
96
+ 'array.max': '{{#label}} must have at most {{#limit}} items',
97
+ 'array.length': '{{#label}} must have exactly {{#limit}} items',
98
+ 'array.unique': '{{#label}} must not contain duplicate items',
99
+ 'array.sparse': '{{#label}} must not be a sparse array',
100
+ 'array.includesRequired': '{{#label}} must include required items',
101
+
102
+ // Date
103
+ 'date.base': '{{#label}} must be a valid date',
104
+ 'date.min': '{{#label}} must be no earlier than {{#limit}}',
105
+ 'date.max': '{{#label}} must be no later than {{#limit}}',
106
+ 'date.format': '{{#label}} date format is invalid',
107
+ 'date.greater': '{{#label}} must be after {{#limit}}',
108
+ 'date.less': '{{#label}} must be before {{#limit}}',
109
+
110
+ // Any
111
+ 'any.required': '{{#label}} is required',
112
+ 'any.invalid': '{{#label}} contains an invalid value',
113
+ 'any.only': '{{#label}} must match {{#valids}}',
114
+ 'any.unknown': 'Field {{#key}} is not allowed',
115
+
116
+ // Patterns
117
+ 'pattern.phone': 'Invalid phone number',
118
+ 'pattern.phone.international': 'Invalid international phone number',
119
+ 'pattern.idCard': 'Invalid ID card number',
120
+ 'pattern.creditCard': 'Invalid credit card number',
121
+ 'pattern.creditCard.visa': 'Invalid Visa card number',
122
+ 'pattern.creditCard.mastercard': 'Invalid Mastercard number',
123
+ 'pattern.creditCard.amex': 'Invalid American Express card number',
124
+ 'pattern.creditCard.discover': 'Invalid Discover card number',
125
+ 'pattern.creditCard.jcb': 'Invalid JCB card number',
126
+ 'pattern.creditCard.unionpay': 'Invalid UnionPay card number',
127
+ 'pattern.licensePlate': 'Invalid license plate number',
128
+ 'pattern.postalCode': 'Invalid postal code',
129
+ 'pattern.passport': 'Invalid passport number',
130
+ 'pattern.objectId': 'Invalid ObjectId',
131
+ 'pattern.hexColor': 'Invalid Hex Color',
132
+ 'pattern.macAddress': 'Invalid MAC Address',
133
+ 'pattern.cron': 'Invalid Cron Expression',
134
+ 'pattern.slug': 'URL slug can only contain lowercase letters, numbers, and hyphens',
135
+ 'pattern.domain': '{{#label}} must be a valid domain name',
136
+ 'pattern.ip': '{{#label}} must be a valid IP address',
137
+ 'pattern.base64': '{{#label}} must be a valid Base64 string',
138
+ 'pattern.jwt': '{{#label}} must be a valid JWT token',
139
+ 'pattern.json': '{{#label}} must be a valid JSON string',
140
+ 'pattern.username': 'Username must start with a letter and contain only letters, numbers, and underscores',
141
+ 'pattern.password.weak': 'Password must be at least 6 characters',
142
+ 'pattern.password.medium': 'Password must be at least 8 characters and contain letters and numbers',
143
+ 'pattern.password.strong': 'Password must be at least 8 characters and contain uppercase, lowercase letters and numbers',
144
+ 'pattern.password.veryStrong': 'Password must be at least 10 characters and contain uppercase, lowercase letters, numbers and special characters',
145
+ 'pattern.emailOrPhone': 'Must be an email or phone number',
146
+ 'pattern.usernameOrEmail': 'Must be a username or email',
147
+ 'pattern.httpOrHttps': 'Must be a URL starting with http or https',
148
+
149
+ // oneOf
150
+ oneOf: '{{#label}} must match one of the following types',
151
+ 'oneOf.invalid': '{{#label}} value does not match any allowed type',
152
+
153
+ // Error fallback
154
+ UNKNOWN_ERROR: 'Unknown validation error',
155
+ CUSTOM_VALIDATION_FAILED: 'Validation failed',
156
+ ASYNC_VALIDATION_NOT_SUPPORTED: 'Async validation not supported in synchronous validate()',
157
+ VALIDATE_MUST_BE_FUNCTION: 'validate must be a function',
158
+ }
159
+
160
+ export default enUS