reliant-type 1.0.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 (345) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1305 -0
  3. package/dist/cjs/constants/SECURITY_CONSTANTS.js +49 -0
  4. package/dist/cjs/constants/SECURITY_CONSTANTS.js.map +1 -0
  5. package/dist/cjs/constants/VALIDATION_CONSTANTS.js +103 -0
  6. package/dist/cjs/constants/VALIDATION_CONSTANTS.js.map +1 -0
  7. package/dist/cjs/core/schema/extensions/SmartInference.js +200 -0
  8. package/dist/cjs/core/schema/extensions/SmartInference.js.map +1 -0
  9. package/dist/cjs/core/schema/extensions/components/AutoDocumentation/Docs.js +100 -0
  10. package/dist/cjs/core/schema/extensions/components/AutoDocumentation/Docs.js.map +1 -0
  11. package/dist/cjs/core/schema/extensions/components/AutoDocumentation/DocumentationGenerator.js +192 -0
  12. package/dist/cjs/core/schema/extensions/components/AutoDocumentation/DocumentationGenerator.js.map +1 -0
  13. package/dist/cjs/core/schema/extensions/components/AutoDocumentation/InteractiveDocumentationGenerator.js +174 -0
  14. package/dist/cjs/core/schema/extensions/components/AutoDocumentation/InteractiveDocumentationGenerator.js.map +1 -0
  15. package/dist/cjs/core/schema/extensions/components/AutoDocumentation/SchemaAnalyzer.js +54 -0
  16. package/dist/cjs/core/schema/extensions/components/AutoDocumentation/SchemaAnalyzer.js.map +1 -0
  17. package/dist/cjs/core/schema/extensions/components/AutoDocumentation/TypeScriptGenerator.js +50 -0
  18. package/dist/cjs/core/schema/extensions/components/AutoDocumentation/TypeScriptGenerator.js.map +1 -0
  19. package/dist/cjs/core/schema/extensions/components/AutoDocumentation/index.js +15 -0
  20. package/dist/cjs/core/schema/extensions/components/AutoDocumentation/index.js.map +1 -0
  21. package/dist/cjs/core/schema/extensions/components/ConditionalValidation/ConditionalBuilder.js +70 -0
  22. package/dist/cjs/core/schema/extensions/components/ConditionalValidation/ConditionalBuilder.js.map +1 -0
  23. package/dist/cjs/core/schema/extensions/components/ConditionalValidation/ConditionalElse.js +40 -0
  24. package/dist/cjs/core/schema/extensions/components/ConditionalValidation/ConditionalElse.js.map +1 -0
  25. package/dist/cjs/core/schema/extensions/components/ConditionalValidation/ConditionalThen.js +19 -0
  26. package/dist/cjs/core/schema/extensions/components/ConditionalValidation/ConditionalThen.js.map +1 -0
  27. package/dist/cjs/core/schema/extensions/components/ConditionalValidation/MultiConditionalBuilder.js +20 -0
  28. package/dist/cjs/core/schema/extensions/components/ConditionalValidation/MultiConditionalBuilder.js.map +1 -0
  29. package/dist/cjs/core/schema/extensions/components/ConditionalValidation/MultiConditionalThen.js +49 -0
  30. package/dist/cjs/core/schema/extensions/components/ConditionalValidation/MultiConditionalThen.js.map +1 -0
  31. package/dist/cjs/core/schema/extensions/components/ConditionalValidation/index.js +98 -0
  32. package/dist/cjs/core/schema/extensions/components/ConditionalValidation/index.js.map +1 -0
  33. package/dist/cjs/core/schema/extensions/components/RealtimeValidation/FormValidator.js +85 -0
  34. package/dist/cjs/core/schema/extensions/components/RealtimeValidation/FormValidator.js.map +1 -0
  35. package/dist/cjs/core/schema/extensions/components/RealtimeValidation/LiveValidator.js +133 -0
  36. package/dist/cjs/core/schema/extensions/components/RealtimeValidation/LiveValidator.js.map +1 -0
  37. package/dist/cjs/core/schema/extensions/components/RealtimeValidation/StreamValidator.js +351 -0
  38. package/dist/cjs/core/schema/extensions/components/RealtimeValidation/StreamValidator.js.map +1 -0
  39. package/dist/cjs/core/schema/extensions/components/RealtimeValidation/index.js +109 -0
  40. package/dist/cjs/core/schema/extensions/components/RealtimeValidation/index.js.map +1 -0
  41. package/dist/cjs/core/schema/extensions/index.js +61 -0
  42. package/dist/cjs/core/schema/extensions/index.js.map +1 -0
  43. package/dist/cjs/core/schema/extensions/mods/index.js +51 -0
  44. package/dist/cjs/core/schema/extensions/mods/index.js.map +1 -0
  45. package/dist/cjs/core/schema/extensions/mods/openapi-converter.js +227 -0
  46. package/dist/cjs/core/schema/extensions/mods/openapi-converter.js.map +1 -0
  47. package/dist/cjs/core/schema/extensions/mods/typescript-generator.js +287 -0
  48. package/dist/cjs/core/schema/extensions/mods/typescript-generator.js.map +1 -0
  49. package/dist/cjs/core/schema/extensions/mods/validation-engine.js +224 -0
  50. package/dist/cjs/core/schema/extensions/mods/validation-engine.js.map +1 -0
  51. package/dist/cjs/core/schema/mode/interfaces/Interface.js +277 -0
  52. package/dist/cjs/core/schema/mode/interfaces/Interface.js.map +1 -0
  53. package/dist/cjs/core/schema/mode/interfaces/InterfaceSchema.js +1431 -0
  54. package/dist/cjs/core/schema/mode/interfaces/InterfaceSchema.js.map +1 -0
  55. package/dist/cjs/core/schema/mode/interfaces/conditional/evaluator/ConditionalEvaluator.js +520 -0
  56. package/dist/cjs/core/schema/mode/interfaces/conditional/evaluator/ConditionalEvaluator.js.map +1 -0
  57. package/dist/cjs/core/schema/mode/interfaces/conditional/parser/ConditionalAST.js +624 -0
  58. package/dist/cjs/core/schema/mode/interfaces/conditional/parser/ConditionalAST.js.map +1 -0
  59. package/dist/cjs/core/schema/mode/interfaces/conditional/parser/ConditionalLexer.js +811 -0
  60. package/dist/cjs/core/schema/mode/interfaces/conditional/parser/ConditionalLexer.js.map +1 -0
  61. package/dist/cjs/core/schema/mode/interfaces/conditional/parser/ConditionalParser.js +599 -0
  62. package/dist/cjs/core/schema/mode/interfaces/conditional/parser/ConditionalParser.js.map +1 -0
  63. package/dist/cjs/core/schema/mode/interfaces/conditional/types/ConditionalTypes.js +89 -0
  64. package/dist/cjs/core/schema/mode/interfaces/conditional/types/ConditionalTypes.js.map +1 -0
  65. package/dist/cjs/core/schema/mode/interfaces/errors/ErrorHandler.js +356 -0
  66. package/dist/cjs/core/schema/mode/interfaces/errors/ErrorHandler.js.map +1 -0
  67. package/dist/cjs/core/schema/mode/interfaces/errors/types/errors.type.js +80 -0
  68. package/dist/cjs/core/schema/mode/interfaces/errors/types/errors.type.js.map +1 -0
  69. package/dist/cjs/core/schema/mode/interfaces/precompilation/FieldPrecompilers.js +778 -0
  70. package/dist/cjs/core/schema/mode/interfaces/precompilation/FieldPrecompilers.js.map +1 -0
  71. package/dist/cjs/core/schema/mode/interfaces/precompilation/SchemaPrecompiler.js +523 -0
  72. package/dist/cjs/core/schema/mode/interfaces/precompilation/SchemaPrecompiler.js.map +1 -0
  73. package/dist/cjs/core/schema/mode/interfaces/typescript/ConditionalTypes.js +681 -0
  74. package/dist/cjs/core/schema/mode/interfaces/typescript/ConditionalTypes.js.map +1 -0
  75. package/dist/cjs/core/schema/mode/interfaces/typescript/IDESupport.js +430 -0
  76. package/dist/cjs/core/schema/mode/interfaces/typescript/IDESupport.js.map +1 -0
  77. package/dist/cjs/core/schema/mode/interfaces/typescript/TypeInference.js +225 -0
  78. package/dist/cjs/core/schema/mode/interfaces/typescript/TypeInference.js.map +1 -0
  79. package/dist/cjs/core/schema/mode/interfaces/typescript/index.js +44 -0
  80. package/dist/cjs/core/schema/mode/interfaces/typescript/index.js.map +1 -0
  81. package/dist/cjs/core/schema/mode/interfaces/validators/ConstraintParser.js +1134 -0
  82. package/dist/cjs/core/schema/mode/interfaces/validators/ConstraintParser.js.map +1 -0
  83. package/dist/cjs/core/schema/mode/interfaces/validators/TypeGuards.js +256 -0
  84. package/dist/cjs/core/schema/mode/interfaces/validators/TypeGuards.js.map +1 -0
  85. package/dist/cjs/core/schema/mode/interfaces/validators/TypeValidators.js +429 -0
  86. package/dist/cjs/core/schema/mode/interfaces/validators/TypeValidators.js.map +1 -0
  87. package/dist/cjs/core/schema/mode/interfaces/validators/UnionCache.js +404 -0
  88. package/dist/cjs/core/schema/mode/interfaces/validators/UnionCache.js.map +1 -0
  89. package/dist/cjs/core/schema/mode/interfaces/validators/ValidationHelpers.js +851 -0
  90. package/dist/cjs/core/schema/mode/interfaces/validators/ValidationHelpers.js.map +1 -0
  91. package/dist/cjs/core/schema/mode/interfaces/validators/mods/passValidator.js +262 -0
  92. package/dist/cjs/core/schema/mode/interfaces/validators/mods/passValidator.js.map +1 -0
  93. package/dist/cjs/core/schema/mode/interfaces/validators/mods/securityValidator.js +887 -0
  94. package/dist/cjs/core/schema/mode/interfaces/validators/mods/securityValidator.js.map +1 -0
  95. package/dist/cjs/core/schema/mode/interfaces/validators/mods/urlValidation.js +191 -0
  96. package/dist/cjs/core/schema/mode/interfaces/validators/mods/urlValidation.js.map +1 -0
  97. package/dist/cjs/core/schema/optimization/ObjectValidationCache.js +462 -0
  98. package/dist/cjs/core/schema/optimization/ObjectValidationCache.js.map +1 -0
  99. package/dist/cjs/core/schema/optimization/PerformanceMonitor.js +773 -0
  100. package/dist/cjs/core/schema/optimization/PerformanceMonitor.js.map +1 -0
  101. package/dist/cjs/core/schema/optimization/SchemaCompiler.js +600 -0
  102. package/dist/cjs/core/schema/optimization/SchemaCompiler.js.map +1 -0
  103. package/dist/cjs/core/types/ValidatorTypes.js +70 -0
  104. package/dist/cjs/core/types/ValidatorTypes.js.map +1 -0
  105. package/dist/cjs/core/types/parser.type.js +12 -0
  106. package/dist/cjs/core/types/parser.type.js.map +1 -0
  107. package/dist/cjs/core/utils/Make.js +61 -0
  108. package/dist/cjs/core/utils/Make.js.map +1 -0
  109. package/dist/cjs/core/utils/Mod.js +1033 -0
  110. package/dist/cjs/core/utils/Mod.js.map +1 -0
  111. package/dist/cjs/core/utils/UrlArgs.js +102 -0
  112. package/dist/cjs/core/utils/UrlArgs.js.map +1 -0
  113. package/dist/cjs/core/utils/arrayToEnum.js +18 -0
  114. package/dist/cjs/core/utils/arrayToEnum.js.map +1 -0
  115. package/dist/cjs/core/utils/createUrlArgsEnumFArray.js +13 -0
  116. package/dist/cjs/core/utils/createUrlArgsEnumFArray.js.map +1 -0
  117. package/dist/cjs/core/utils/securityHelpers.js +215 -0
  118. package/dist/cjs/core/utils/securityHelpers.js.map +1 -0
  119. package/dist/cjs/core/utils/securityValidatorHelpers.js +65 -0
  120. package/dist/cjs/core/utils/securityValidatorHelpers.js.map +1 -0
  121. package/dist/cjs/index.js +31 -0
  122. package/dist/cjs/index.js.map +1 -0
  123. package/dist/cjs/package.json +3 -0
  124. package/dist/esm/constants/SECURITY_CONSTANTS.js +47 -0
  125. package/dist/esm/constants/SECURITY_CONSTANTS.js.map +1 -0
  126. package/dist/esm/constants/VALIDATION_CONSTANTS.js +98 -0
  127. package/dist/esm/constants/VALIDATION_CONSTANTS.js.map +1 -0
  128. package/dist/esm/core/schema/extensions/SmartInference.js +197 -0
  129. package/dist/esm/core/schema/extensions/SmartInference.js.map +1 -0
  130. package/dist/esm/core/schema/extensions/components/AutoDocumentation/Docs.js +98 -0
  131. package/dist/esm/core/schema/extensions/components/AutoDocumentation/Docs.js.map +1 -0
  132. package/dist/esm/core/schema/extensions/components/AutoDocumentation/DocumentationGenerator.js +190 -0
  133. package/dist/esm/core/schema/extensions/components/AutoDocumentation/DocumentationGenerator.js.map +1 -0
  134. package/dist/esm/core/schema/extensions/components/AutoDocumentation/InteractiveDocumentationGenerator.js +172 -0
  135. package/dist/esm/core/schema/extensions/components/AutoDocumentation/InteractiveDocumentationGenerator.js.map +1 -0
  136. package/dist/esm/core/schema/extensions/components/AutoDocumentation/SchemaAnalyzer.js +52 -0
  137. package/dist/esm/core/schema/extensions/components/AutoDocumentation/SchemaAnalyzer.js.map +1 -0
  138. package/dist/esm/core/schema/extensions/components/AutoDocumentation/TypeScriptGenerator.js +48 -0
  139. package/dist/esm/core/schema/extensions/components/AutoDocumentation/TypeScriptGenerator.js.map +1 -0
  140. package/dist/esm/core/schema/extensions/components/AutoDocumentation/index.js +12 -0
  141. package/dist/esm/core/schema/extensions/components/AutoDocumentation/index.js.map +1 -0
  142. package/dist/esm/core/schema/extensions/components/ConditionalValidation/ConditionalBuilder.js +68 -0
  143. package/dist/esm/core/schema/extensions/components/ConditionalValidation/ConditionalBuilder.js.map +1 -0
  144. package/dist/esm/core/schema/extensions/components/ConditionalValidation/ConditionalElse.js +38 -0
  145. package/dist/esm/core/schema/extensions/components/ConditionalValidation/ConditionalElse.js.map +1 -0
  146. package/dist/esm/core/schema/extensions/components/ConditionalValidation/ConditionalThen.js +17 -0
  147. package/dist/esm/core/schema/extensions/components/ConditionalValidation/ConditionalThen.js.map +1 -0
  148. package/dist/esm/core/schema/extensions/components/ConditionalValidation/MultiConditionalBuilder.js +18 -0
  149. package/dist/esm/core/schema/extensions/components/ConditionalValidation/MultiConditionalBuilder.js.map +1 -0
  150. package/dist/esm/core/schema/extensions/components/ConditionalValidation/MultiConditionalThen.js +45 -0
  151. package/dist/esm/core/schema/extensions/components/ConditionalValidation/MultiConditionalThen.js.map +1 -0
  152. package/dist/esm/core/schema/extensions/components/ConditionalValidation/index.js +92 -0
  153. package/dist/esm/core/schema/extensions/components/ConditionalValidation/index.js.map +1 -0
  154. package/dist/esm/core/schema/extensions/components/RealtimeValidation/FormValidator.js +83 -0
  155. package/dist/esm/core/schema/extensions/components/RealtimeValidation/FormValidator.js.map +1 -0
  156. package/dist/esm/core/schema/extensions/components/RealtimeValidation/LiveValidator.js +131 -0
  157. package/dist/esm/core/schema/extensions/components/RealtimeValidation/LiveValidator.js.map +1 -0
  158. package/dist/esm/core/schema/extensions/components/RealtimeValidation/StreamValidator.js +349 -0
  159. package/dist/esm/core/schema/extensions/components/RealtimeValidation/StreamValidator.js.map +1 -0
  160. package/dist/esm/core/schema/extensions/components/RealtimeValidation/index.js +103 -0
  161. package/dist/esm/core/schema/extensions/components/RealtimeValidation/index.js.map +1 -0
  162. package/dist/esm/core/schema/extensions/index.js +53 -0
  163. package/dist/esm/core/schema/extensions/index.js.map +1 -0
  164. package/dist/esm/core/schema/extensions/mods/index.js +47 -0
  165. package/dist/esm/core/schema/extensions/mods/index.js.map +1 -0
  166. package/dist/esm/core/schema/extensions/mods/openapi-converter.js +225 -0
  167. package/dist/esm/core/schema/extensions/mods/openapi-converter.js.map +1 -0
  168. package/dist/esm/core/schema/extensions/mods/typescript-generator.js +284 -0
  169. package/dist/esm/core/schema/extensions/mods/typescript-generator.js.map +1 -0
  170. package/dist/esm/core/schema/extensions/mods/validation-engine.js +222 -0
  171. package/dist/esm/core/schema/extensions/mods/validation-engine.js.map +1 -0
  172. package/dist/esm/core/schema/mode/interfaces/Interface.js +269 -0
  173. package/dist/esm/core/schema/mode/interfaces/Interface.js.map +1 -0
  174. package/dist/esm/core/schema/mode/interfaces/InterfaceSchema.js +1429 -0
  175. package/dist/esm/core/schema/mode/interfaces/InterfaceSchema.js.map +1 -0
  176. package/dist/esm/core/schema/mode/interfaces/conditional/evaluator/ConditionalEvaluator.js +518 -0
  177. package/dist/esm/core/schema/mode/interfaces/conditional/evaluator/ConditionalEvaluator.js.map +1 -0
  178. package/dist/esm/core/schema/mode/interfaces/conditional/parser/ConditionalAST.js +620 -0
  179. package/dist/esm/core/schema/mode/interfaces/conditional/parser/ConditionalAST.js.map +1 -0
  180. package/dist/esm/core/schema/mode/interfaces/conditional/parser/ConditionalLexer.js +809 -0
  181. package/dist/esm/core/schema/mode/interfaces/conditional/parser/ConditionalLexer.js.map +1 -0
  182. package/dist/esm/core/schema/mode/interfaces/conditional/parser/ConditionalParser.js +597 -0
  183. package/dist/esm/core/schema/mode/interfaces/conditional/parser/ConditionalParser.js.map +1 -0
  184. package/dist/esm/core/schema/mode/interfaces/conditional/types/ConditionalTypes.js +89 -0
  185. package/dist/esm/core/schema/mode/interfaces/conditional/types/ConditionalTypes.js.map +1 -0
  186. package/dist/esm/core/schema/mode/interfaces/errors/ErrorHandler.js +354 -0
  187. package/dist/esm/core/schema/mode/interfaces/errors/ErrorHandler.js.map +1 -0
  188. package/dist/esm/core/schema/mode/interfaces/errors/types/errors.type.js +80 -0
  189. package/dist/esm/core/schema/mode/interfaces/errors/types/errors.type.js.map +1 -0
  190. package/dist/esm/core/schema/mode/interfaces/precompilation/FieldPrecompilers.js +776 -0
  191. package/dist/esm/core/schema/mode/interfaces/precompilation/FieldPrecompilers.js.map +1 -0
  192. package/dist/esm/core/schema/mode/interfaces/precompilation/SchemaPrecompiler.js +521 -0
  193. package/dist/esm/core/schema/mode/interfaces/precompilation/SchemaPrecompiler.js.map +1 -0
  194. package/dist/esm/core/schema/mode/interfaces/typescript/ConditionalTypes.js +681 -0
  195. package/dist/esm/core/schema/mode/interfaces/typescript/ConditionalTypes.js.map +1 -0
  196. package/dist/esm/core/schema/mode/interfaces/typescript/IDESupport.js +428 -0
  197. package/dist/esm/core/schema/mode/interfaces/typescript/IDESupport.js.map +1 -0
  198. package/dist/esm/core/schema/mode/interfaces/typescript/TypeInference.js +223 -0
  199. package/dist/esm/core/schema/mode/interfaces/typescript/TypeInference.js.map +1 -0
  200. package/dist/esm/core/schema/mode/interfaces/typescript/index.js +35 -0
  201. package/dist/esm/core/schema/mode/interfaces/typescript/index.js.map +1 -0
  202. package/dist/esm/core/schema/mode/interfaces/validators/ConstraintParser.js +1132 -0
  203. package/dist/esm/core/schema/mode/interfaces/validators/ConstraintParser.js.map +1 -0
  204. package/dist/esm/core/schema/mode/interfaces/validators/TypeGuards.js +254 -0
  205. package/dist/esm/core/schema/mode/interfaces/validators/TypeGuards.js.map +1 -0
  206. package/dist/esm/core/schema/mode/interfaces/validators/TypeValidators.js +427 -0
  207. package/dist/esm/core/schema/mode/interfaces/validators/TypeValidators.js.map +1 -0
  208. package/dist/esm/core/schema/mode/interfaces/validators/UnionCache.js +400 -0
  209. package/dist/esm/core/schema/mode/interfaces/validators/UnionCache.js.map +1 -0
  210. package/dist/esm/core/schema/mode/interfaces/validators/ValidationHelpers.js +849 -0
  211. package/dist/esm/core/schema/mode/interfaces/validators/ValidationHelpers.js.map +1 -0
  212. package/dist/esm/core/schema/mode/interfaces/validators/mods/passValidator.js +260 -0
  213. package/dist/esm/core/schema/mode/interfaces/validators/mods/passValidator.js.map +1 -0
  214. package/dist/esm/core/schema/mode/interfaces/validators/mods/securityValidator.js +881 -0
  215. package/dist/esm/core/schema/mode/interfaces/validators/mods/securityValidator.js.map +1 -0
  216. package/dist/esm/core/schema/mode/interfaces/validators/mods/urlValidation.js +189 -0
  217. package/dist/esm/core/schema/mode/interfaces/validators/mods/urlValidation.js.map +1 -0
  218. package/dist/esm/core/schema/optimization/ObjectValidationCache.js +460 -0
  219. package/dist/esm/core/schema/optimization/ObjectValidationCache.js.map +1 -0
  220. package/dist/esm/core/schema/optimization/PerformanceMonitor.js +771 -0
  221. package/dist/esm/core/schema/optimization/PerformanceMonitor.js.map +1 -0
  222. package/dist/esm/core/schema/optimization/SchemaCompiler.js +598 -0
  223. package/dist/esm/core/schema/optimization/SchemaCompiler.js.map +1 -0
  224. package/dist/esm/core/types/ValidatorTypes.js +65 -0
  225. package/dist/esm/core/types/ValidatorTypes.js.map +1 -0
  226. package/dist/esm/core/types/parser.type.js +12 -0
  227. package/dist/esm/core/types/parser.type.js.map +1 -0
  228. package/dist/esm/core/utils/Make.js +59 -0
  229. package/dist/esm/core/utils/Make.js.map +1 -0
  230. package/dist/esm/core/utils/Mod.js +1031 -0
  231. package/dist/esm/core/utils/Mod.js.map +1 -0
  232. package/dist/esm/core/utils/UrlArgs.js +98 -0
  233. package/dist/esm/core/utils/UrlArgs.js.map +1 -0
  234. package/dist/esm/core/utils/arrayToEnum.js +16 -0
  235. package/dist/esm/core/utils/arrayToEnum.js.map +1 -0
  236. package/dist/esm/core/utils/createUrlArgsEnumFArray.js +11 -0
  237. package/dist/esm/core/utils/createUrlArgsEnumFArray.js.map +1 -0
  238. package/dist/esm/core/utils/securityHelpers.js +207 -0
  239. package/dist/esm/core/utils/securityHelpers.js.map +1 -0
  240. package/dist/esm/core/utils/securityValidatorHelpers.js +62 -0
  241. package/dist/esm/core/utils/securityValidatorHelpers.js.map +1 -0
  242. package/dist/esm/index.js +12 -0
  243. package/dist/esm/index.js.map +1 -0
  244. package/dist/esm/package.json +3 -0
  245. package/dist/schema.d.ts +2595 -0
  246. package/docs/ALL_TYPES.md +120 -0
  247. package/docs/API-STABILITY.md +336 -0
  248. package/docs/CONDITIONAL-VALIDATION.md +637 -0
  249. package/docs/EXAMPLES.md +876 -0
  250. package/docs/FIELD-TYPES.md +829 -0
  251. package/docs/GETTING-STARTED.md +394 -0
  252. package/docs/LIVE-UTILITY.md +1137 -0
  253. package/docs/QUICK-REFERENCE.md +346 -0
  254. package/docs/README.md +205 -0
  255. package/docs/VSCODE-EXTENSION.md +458 -0
  256. package/package.json +219 -0
  257. package/src/bench/BENCHMARK-RESULTS.md +211 -0
  258. package/src/bench/benchmark-results.json +148 -0
  259. package/src/bench/performance-comparison.ts +218 -0
  260. package/src/bench/precompilation-benchmark.ts +218 -0
  261. package/src/constants/SECURITY_CONSTANTS.ts +44 -0
  262. package/src/constants/VALIDATION_CONSTANTS.ts +176 -0
  263. package/src/core/README.md +395 -0
  264. package/src/core/compiler/SchemaTransformer.ts +279 -0
  265. package/src/core/compiler/TypeAnalyzer.ts +378 -0
  266. package/src/core/compiler/TypeScriptCompilerIntegration.ts +220 -0
  267. package/src/core/compiler/TypeToSchemaConverter.ts +288 -0
  268. package/src/core/index.ts +70 -0
  269. package/src/core/schema/extensions/AutoDocumentation.ts +572 -0
  270. package/src/core/schema/extensions/ConditionalValidation.ts +330 -0
  271. package/src/core/schema/extensions/README.md +171 -0
  272. package/src/core/schema/extensions/RealtimeValidation.ts +656 -0
  273. package/src/core/schema/extensions/SmartInference.ts +224 -0
  274. package/src/core/schema/extensions/components/AutoDocumentation/Docs.ts +98 -0
  275. package/src/core/schema/extensions/components/AutoDocumentation/DocumentationGenerator.ts +201 -0
  276. package/src/core/schema/extensions/components/AutoDocumentation/InteractiveDocumentationGenerator.ts +176 -0
  277. package/src/core/schema/extensions/components/AutoDocumentation/OpenAPIGenerator.ts +175 -0
  278. package/src/core/schema/extensions/components/AutoDocumentation/SchemaAnalyzer.ts +49 -0
  279. package/src/core/schema/extensions/components/AutoDocumentation/TypeScriptGenerator.ts +54 -0
  280. package/src/core/schema/extensions/components/AutoDocumentation/index.ts +17 -0
  281. package/src/core/schema/extensions/components/ConditionalValidation/ConditionalBuilder.ts +101 -0
  282. package/src/core/schema/extensions/components/ConditionalValidation/ConditionalElse.ts +65 -0
  283. package/src/core/schema/extensions/components/ConditionalValidation/ConditionalThen.ts +33 -0
  284. package/src/core/schema/extensions/components/ConditionalValidation/Extend.ts +75 -0
  285. package/src/core/schema/extensions/components/ConditionalValidation/MultiConditionalBuilder.ts +16 -0
  286. package/src/core/schema/extensions/components/ConditionalValidation/MultiConditionalThen.ts +50 -0
  287. package/src/core/schema/extensions/components/ConditionalValidation/index.ts +104 -0
  288. package/src/core/schema/extensions/components/RealtimeValidation/FormValidator.ts +88 -0
  289. package/src/core/schema/extensions/components/RealtimeValidation/LiveValidator.ts +171 -0
  290. package/src/core/schema/extensions/components/RealtimeValidation/StreamValidator.ts +397 -0
  291. package/src/core/schema/extensions/components/RealtimeValidation/index.ts +114 -0
  292. package/src/core/schema/extensions/index.ts +76 -0
  293. package/src/core/schema/extensions/mods/index.ts +131 -0
  294. package/src/core/schema/extensions/mods/openapi-converter.ts +338 -0
  295. package/src/core/schema/extensions/mods/typescript-generator.ts +379 -0
  296. package/src/core/schema/extensions/mods/validation-engine.ts +295 -0
  297. package/src/core/schema/mode/interfaces/Interface.ts +364 -0
  298. package/src/core/schema/mode/interfaces/InterfaceSchema.ts +1838 -0
  299. package/src/core/schema/mode/interfaces/README.md +278 -0
  300. package/src/core/schema/mode/interfaces/conditional/evaluator/ConditionalEvaluator.ts +657 -0
  301. package/src/core/schema/mode/interfaces/conditional/parser/ConditionalAST.ts +826 -0
  302. package/src/core/schema/mode/interfaces/conditional/parser/ConditionalLexer.ts +992 -0
  303. package/src/core/schema/mode/interfaces/conditional/parser/ConditionalParser.ts +803 -0
  304. package/src/core/schema/mode/interfaces/conditional/parser/readme.md +406 -0
  305. package/src/core/schema/mode/interfaces/conditional/types/ConditionalTypes.ts +273 -0
  306. package/src/core/schema/mode/interfaces/errors/ErrorHandler.ts +624 -0
  307. package/src/core/schema/mode/interfaces/errors/types/errors.type.ts +102 -0
  308. package/src/core/schema/mode/interfaces/precompilation/FieldPrecompilers.ts +962 -0
  309. package/src/core/schema/mode/interfaces/precompilation/SchemaPrecompiler.ts +667 -0
  310. package/src/core/schema/mode/interfaces/typescript/ConditionalTypes.ts +1534 -0
  311. package/src/core/schema/mode/interfaces/typescript/IDESupport.ts +534 -0
  312. package/src/core/schema/mode/interfaces/typescript/TypeInference.ts +737 -0
  313. package/src/core/schema/mode/interfaces/typescript/index.ts +92 -0
  314. package/src/core/schema/mode/interfaces/validators/ConstraintParser.ts +1438 -0
  315. package/src/core/schema/mode/interfaces/validators/EnhancedErrorReporting.ts +227 -0
  316. package/src/core/schema/mode/interfaces/validators/TypeGuards.ts +288 -0
  317. package/src/core/schema/mode/interfaces/validators/TypeValidators.ts +660 -0
  318. package/src/core/schema/mode/interfaces/validators/UnionCache.ts +508 -0
  319. package/src/core/schema/mode/interfaces/validators/ValidationHelpers.ts +1257 -0
  320. package/src/core/schema/mode/interfaces/validators/index.ts +21 -0
  321. package/src/core/schema/mode/interfaces/validators/mods/passValidator.ts +424 -0
  322. package/src/core/schema/mode/interfaces/validators/mods/securityValidator.ts +1634 -0
  323. package/src/core/schema/mode/interfaces/validators/mods/urlValidation.ts +333 -0
  324. package/src/core/schema/optimization/ObjectValidationCache.ts +560 -0
  325. package/src/core/schema/optimization/PerformanceInitializer.ts +188 -0
  326. package/src/core/schema/optimization/PerformanceMonitor.ts +898 -0
  327. package/src/core/schema/optimization/SchemaCompiler.ts +730 -0
  328. package/src/core/testing/TestDataGenerator.ts +590 -0
  329. package/src/core/types/SchemaValidator.type.ts +210 -0
  330. package/src/core/types/ValidatorTypes.ts +93 -0
  331. package/src/core/types/extension.type.ts +109 -0
  332. package/src/core/types/objValidationCache.ts +17 -0
  333. package/src/core/types/parser.type.ts +15 -0
  334. package/src/core/types/perfoMonitor.ts +37 -0
  335. package/src/core/types/scompiler.ts +22 -0
  336. package/src/core/types/securityValidator.type.ts +10 -0
  337. package/src/core/types/types.ts +154 -0
  338. package/src/core/utils/Make.ts +97 -0
  339. package/src/core/utils/Mod.ts +1168 -0
  340. package/src/core/utils/UrlArgs.ts +124 -0
  341. package/src/core/utils/arrayToEnum.ts +89 -0
  342. package/src/core/utils/createUrlArgsEnumFArray.ts +11 -0
  343. package/src/core/utils/securityHelpers.ts +341 -0
  344. package/src/core/utils/securityValidatorHelpers.ts +76 -0
  345. package/src/index.ts +124 -0
@@ -0,0 +1,1634 @@
1
+ import { SECURITY_CONSTANTS } from "../../../../../../constants/SECURITY_CONSTANTS";
2
+ import { MAX_OBJECT_DEPTH } from "../../../../../../constants/VALIDATION_CONSTANTS";
3
+ import { SchemaValidationResult } from "../../../../../types/types";
4
+ import {
5
+ validateJsonDeep,
6
+ validateJsonSchema,
7
+ validateIPv4,
8
+ validateIPv6,
9
+ normalizeIPv6,
10
+ validateObjectDeep,
11
+ validateObjectSchema,
12
+ } from "../../../../../utils/securityHelpers";
13
+ import Ajv from "ajv";
14
+ import addFormats from "ajv-formats";
15
+ import {
16
+ ValidationCache,
17
+ ValidationMetrics,
18
+ } from "../../../../../utils/securityValidatorHelpers";
19
+ import { ErrorHandler } from "../../errors/ErrorHandler";
20
+ import { ErrorCode } from "../../errors/types/errors.type";
21
+
22
+ export class SecurityValidators {
23
+ private static ajv: Ajv | null = null;
24
+ private static readonly ajvOptions = {
25
+ strict: false,
26
+ allErrors: true,
27
+ removeAdditional: false,
28
+ useDefaults: false,
29
+ coerceTypes: false,
30
+ validateFormats: true,
31
+ addUsedSchema: false,
32
+ verbose: false,
33
+ loadSchema: false, // Disable remote schema loading for security
34
+ } as const;
35
+
36
+ /**
37
+ * Initialize AJV instance with enhanced security configurations
38
+ */
39
+ private static getAjv(): Ajv {
40
+ if (!this.ajv) {
41
+ this.ajv = new Ajv(this.ajvOptions as any);
42
+ addFormats(this.ajv);
43
+
44
+ // security schema with more comprehensive protections
45
+ this.ajv.addSchema(
46
+ {
47
+ $id: "https://nehonix.space/lib/v/reliant-type",
48
+ type: ["object", "array", "string", "number", "boolean", "null"],
49
+ definitions: {
50
+ secureObject: {
51
+ type: "object",
52
+ not: {
53
+ anyOf: [
54
+ ...Array.from(SECURITY_CONSTANTS.DANGEROUS_PROPERTIES).map(
55
+ (prop) => ({
56
+ properties: { [prop]: {} },
57
+ required: [prop],
58
+ })
59
+ ),
60
+ { additionalProperties: { type: "function" } },
61
+ ],
62
+ },
63
+ patternProperties: {
64
+ "^(?!__|constructor|prototype).*": { $ref: "#" },
65
+ },
66
+ },
67
+ },
68
+ if: { type: "object" },
69
+ then: { $ref: "#/definitions/secureObject" },
70
+ else: {
71
+ if: { type: "array" },
72
+ then: { items: { $ref: "#" } },
73
+ },
74
+ },
75
+ "secure-json-v2"
76
+ );
77
+ }
78
+ return this.ajv;
79
+ }
80
+
81
+ /**
82
+ * Check for dangerous properties that could lead to prototype pollution
83
+ */
84
+ private static hasDangerousProperties(
85
+ obj: any,
86
+ visited = new WeakSet()
87
+ ): boolean {
88
+ if (!obj || typeof obj !== "object" || visited.has(obj)) {
89
+ return false;
90
+ }
91
+
92
+ visited.add(obj);
93
+
94
+ // Check current level
95
+ for (const key of Object.keys(obj)) {
96
+ if (SECURITY_CONSTANTS.DANGEROUS_PROPERTIES.has(key)) {
97
+ return true;
98
+ }
99
+ }
100
+
101
+ // Recursively check nested objects
102
+ for (const value of Object.values(obj)) {
103
+ if (this.hasDangerousProperties(value, visited)) {
104
+ return true;
105
+ }
106
+ }
107
+
108
+ return false;
109
+ }
110
+
111
+ /**
112
+ * Execute validation with timeout protection
113
+ */
114
+ private static async withTimeout<T>(
115
+ operation: () => T | Promise<T>,
116
+ timeoutMs: number = SECURITY_CONSTANTS.MAX_VALIDATION_TIME
117
+ ): Promise<T> {
118
+ return new Promise((resolve, reject) => {
119
+ const timer = setTimeout(() => {
120
+ reject(new Error(`Validation timeout after ${timeoutMs}ms`));
121
+ }, timeoutMs);
122
+
123
+ Promise.resolve(operation()).then(
124
+ (result) => {
125
+ clearTimeout(timer);
126
+ resolve(result);
127
+ },
128
+ (error) => {
129
+ clearTimeout(timer);
130
+ reject(error);
131
+ }
132
+ );
133
+ });
134
+ }
135
+
136
+ /**
137
+ * text validation with comprehensive security checks
138
+ */
139
+ static async validateText(
140
+ value: any,
141
+ options: {
142
+ minLength?: number;
143
+ maxLength?: number;
144
+ allowEmpty?: boolean;
145
+ trimWhitespace?: boolean;
146
+ allowedCharacters?: RegExp;
147
+ forbiddenPatterns?: RegExp[];
148
+ encoding?: "utf8" | "ascii" | "latin1";
149
+ preventXSS?: boolean;
150
+ preventSQLInjection?: boolean;
151
+ preventLDAPInjection?: boolean;
152
+ preventCommandInjection?: boolean;
153
+ normalizeUnicode?: boolean;
154
+ maxLines?: number;
155
+ requireAlphanumeric?: boolean;
156
+ allowHTML?: boolean;
157
+ stripHTML?: boolean;
158
+ timeout?: number;
159
+ enableMetrics?: boolean;
160
+ } = {}
161
+ ): Promise<SchemaValidationResult> {
162
+ const startTime = Date.now();
163
+ const operationName = "validateText";
164
+
165
+ try {
166
+ const result = await this.withTimeout(async () => {
167
+ return this.validateTextSync(value, options);
168
+ }, options.timeout);
169
+
170
+ if (options.enableMetrics) {
171
+ ValidationMetrics.record(
172
+ operationName,
173
+ Date.now() - startTime,
174
+ !result.success
175
+ );
176
+ }
177
+
178
+ return result;
179
+ } catch (error: any) {
180
+ if (options.enableMetrics) {
181
+ ValidationMetrics.record(operationName, Date.now() - startTime, true);
182
+ }
183
+ const msg = `${error instanceof Error ? error.message : "Unknown error"}`;
184
+ return {
185
+ success: false,
186
+ errors: [
187
+ ErrorHandler.createValidationError([], msg, ErrorCode.UNKNOWN_ERROR),
188
+ ],
189
+ warnings: [],
190
+ data: value,
191
+ };
192
+ }
193
+ }
194
+
195
+ static validateTextSync(value: any, options: any): SchemaValidationResult {
196
+ const result: SchemaValidationResult = {
197
+ success: true,
198
+ errors: [],
199
+ warnings: [],
200
+ data: value,
201
+ };
202
+
203
+ const {
204
+ minLength = 0,
205
+ maxLength = SECURITY_CONSTANTS.MAX_TEXT_LENGTH,
206
+ allowEmpty = true,
207
+ trimWhitespace = false,
208
+ allowedCharacters,
209
+ forbiddenPatterns = [],
210
+ encoding = "utf8",
211
+ preventXSS = true,
212
+ preventSQLInjection = true,
213
+ preventLDAPInjection = false,
214
+ preventCommandInjection = false,
215
+ normalizeUnicode = false,
216
+ maxLines = Infinity,
217
+ requireAlphanumeric = false,
218
+ allowHTML = false,
219
+ stripHTML = false,
220
+ } = options;
221
+
222
+ if (typeof value !== "string") {
223
+ result.success = false;
224
+ result.errors.push(ErrorHandler.createTypeError([], "string", value));
225
+ return result;
226
+ }
227
+
228
+ let text = value;
229
+
230
+ // Early size check to prevent DoS
231
+ if (text.length > maxLength) {
232
+ result.success = false;
233
+ result.errors.push(
234
+ ErrorHandler.createStringError(
235
+ [],
236
+ `Text exceeds maximum length of ${maxLength} characters`,
237
+ value,
238
+ ErrorCode.STRING_TOO_LONG
239
+ )
240
+ );
241
+ return result;
242
+ }
243
+
244
+ // Trim whitespace if requested
245
+ if (trimWhitespace) {
246
+ const trimmed = text.trim();
247
+ if (trimmed !== text) {
248
+ text = trimmed;
249
+ result.data = text;
250
+ result.warnings.push("Whitespace trimmed from text");
251
+ }
252
+ }
253
+
254
+ // Unicode normalization
255
+ if (normalizeUnicode) {
256
+ try {
257
+ const normalized = text.normalize("NFC");
258
+ if (normalized !== text) {
259
+ text = normalized;
260
+ result.data = text;
261
+ result.warnings.push("Unicode characters normalized");
262
+ }
263
+ } catch (error) {
264
+ result.warnings.push("Unicode normalization failed");
265
+ }
266
+ }
267
+
268
+ // Empty string validation
269
+ if (!allowEmpty && text.length === 0) {
270
+ result.success = false;
271
+ result.errors.push(
272
+ ErrorHandler.createStringError(
273
+ [],
274
+ "Text cannot be empty",
275
+ value,
276
+ ErrorCode.STRING_TOO_SHORT
277
+ )
278
+ );
279
+ return result;
280
+ }
281
+
282
+ // Length validation
283
+ if (text.length < minLength) {
284
+ result.success = false;
285
+ result.errors.push(
286
+ ErrorHandler.createStringError(
287
+ [],
288
+ `Text must be at least ${minLength} characters long`,
289
+ value,
290
+ ErrorCode.STRING_TOO_SHORT
291
+ )
292
+ );
293
+ }
294
+
295
+ // Line count validation
296
+ if (maxLines !== Infinity) {
297
+ const lineCount = text.split("\n").length;
298
+ if (lineCount > maxLines) {
299
+ result.success = false;
300
+ result.errors.push(
301
+ ErrorHandler.createStringError(
302
+ [],
303
+ `Text cannot exceed ${maxLines} lines`,
304
+ value,
305
+ ErrorCode.STRING_TOO_LONG
306
+ )
307
+ );
308
+ }
309
+ }
310
+
311
+ // Character encoding validation
312
+ if (encoding === "ascii" && !/^[\x00-\x7F]*$/.test(text)) {
313
+ result.success = false;
314
+ result.errors.push(
315
+ ErrorHandler.createStringError(
316
+ [],
317
+ "Text contains non-ASCII characters",
318
+ value,
319
+ ErrorCode.INVALID_STRING_FORMAT
320
+ )
321
+ );
322
+ }
323
+
324
+ // Alphanumeric requirement
325
+ if (requireAlphanumeric && !/^[a-zA-Z0-9\s]*$/.test(text)) {
326
+ result.success = false;
327
+ result.errors.push(
328
+ ErrorHandler.createStringError(
329
+ [],
330
+ "Text must contain only alphanumeric characters and spaces",
331
+ value,
332
+ ErrorCode.INVALID_STRING_FORMAT
333
+ )
334
+ );
335
+ }
336
+
337
+ // Allowed characters validation
338
+ if (allowedCharacters && !allowedCharacters.test(text)) {
339
+ result.success = false;
340
+ result.errors.push(
341
+ ErrorHandler.createStringError(
342
+ [],
343
+ "Text contains disallowed characters",
344
+ value,
345
+ ErrorCode.INVALID_STRING_FORMAT
346
+ )
347
+ );
348
+ }
349
+
350
+ // Forbidden patterns check
351
+ for (const pattern of forbiddenPatterns) {
352
+ if (pattern.test(text)) {
353
+ result.success = false;
354
+ result.errors.push(
355
+ ErrorHandler.createStringError(
356
+ [],
357
+ "Text contains forbidden pattern",
358
+ value,
359
+ ErrorCode.PATTERN_MISMATCH
360
+ )
361
+ );
362
+ break;
363
+ }
364
+ }
365
+
366
+ // XSS prevention
367
+ if (preventXSS && !allowHTML) {
368
+ for (const pattern of SECURITY_CONSTANTS.XSS_PATTERNS) {
369
+ if (pattern.test(text)) {
370
+ result.success = false;
371
+ result.errors.push(
372
+ ErrorHandler.createStringError(
373
+ [],
374
+ "Text contains potentially malicious content (XSS)",
375
+ value,
376
+ ErrorCode.INVALID_STRING_FORMAT
377
+ )
378
+ );
379
+ break;
380
+ }
381
+ }
382
+
383
+ // Additional XSS checks
384
+ if (text.includes("javascript:") || text.includes("data:text/html")) {
385
+ result.success = false;
386
+ result.errors.push(
387
+ ErrorHandler.createStringError(
388
+ [],
389
+ "Text contains dangerous URI schemes",
390
+ value,
391
+ ErrorCode.INVALID_STRING_FORMAT
392
+ )
393
+ );
394
+ }
395
+ }
396
+
397
+ // SQL injection prevention
398
+ if (preventSQLInjection) {
399
+ for (const pattern of SECURITY_CONSTANTS.SQL_PATTERNS) {
400
+ if (pattern.test(text)) {
401
+ result.warnings.push("Text contains SQL-like patterns");
402
+ break;
403
+ }
404
+ }
405
+ }
406
+
407
+ // LDAP injection prevention
408
+ if (preventLDAPInjection) {
409
+ for (const pattern of SECURITY_CONSTANTS.LDAP_PATTERNS) {
410
+ if (pattern.test(text)) {
411
+ result.success = false;
412
+ result.errors.push(
413
+ ErrorHandler.createStringError(
414
+ [],
415
+ "Text contains LDAP injection patterns",
416
+ value,
417
+ ErrorCode.INVALID_STRING_FORMAT
418
+ )
419
+ );
420
+ break;
421
+ }
422
+ }
423
+ }
424
+
425
+ // Command injection prevention
426
+ if (preventCommandInjection) {
427
+ for (const pattern of SECURITY_CONSTANTS.COMMAND_INJECTION_PATTERNS) {
428
+ if (pattern.test(text)) {
429
+ result.success = false;
430
+ result.errors.push(
431
+ ErrorHandler.createStringError(
432
+ [],
433
+ "Text contains command injection patterns",
434
+ value,
435
+ ErrorCode.INVALID_STRING_FORMAT
436
+ )
437
+ );
438
+ break;
439
+ }
440
+ }
441
+ }
442
+
443
+ // Control character detection
444
+ if (/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]/.test(text)) {
445
+ result.warnings.push("Text contains control characters");
446
+ }
447
+
448
+ // Null byte detection
449
+ if (text.includes("\0")) {
450
+ result.success = false;
451
+ result.errors.push(
452
+ ErrorHandler.createStringError(
453
+ [],
454
+ "Text contains null bytes",
455
+ value,
456
+ ErrorCode.INVALID_STRING_FORMAT
457
+ )
458
+ );
459
+ }
460
+
461
+ return result;
462
+ }
463
+
464
+ /**
465
+ * JSON validation with improved security and performance
466
+ */
467
+ static async validateJson(
468
+ value: any,
469
+ options: {
470
+ maxDepth?: number;
471
+ maxKeys?: number;
472
+ maxStringLength?: number;
473
+ maxArrayLength?: number;
474
+ allowedTypes?: string[];
475
+ forbiddenKeys?: string[];
476
+ schema?: any;
477
+ preventCircular?: boolean;
478
+ maxSize?: number;
479
+ securityMode?: "fast" | "secure" | "strict";
480
+ timeout?: number;
481
+ enableMetrics?: boolean;
482
+ useCache?: boolean;
483
+ } = {}
484
+ ): Promise<SchemaValidationResult> {
485
+ const startTime = Date.now();
486
+ const operationName = "validateJson";
487
+
488
+ // Generate cache key if caching is enabled
489
+ const cacheKey = options.useCache
490
+ ? `json_${JSON.stringify(value).substring(0, 100)}_${JSON.stringify(options)}`
491
+ : null;
492
+
493
+ if (cacheKey) {
494
+ const cached = ValidationCache.get(cacheKey);
495
+ if (cached) {
496
+ return cached;
497
+ }
498
+ }
499
+
500
+ try {
501
+ const result = await this.withTimeout(async () => {
502
+ return this.validateJsonSync(value, options);
503
+ }, options.timeout);
504
+
505
+ if (options.enableMetrics) {
506
+ ValidationMetrics.record(
507
+ operationName,
508
+ Date.now() - startTime,
509
+ !result.success
510
+ );
511
+ }
512
+
513
+ if (cacheKey && result.success) {
514
+ ValidationCache.set(cacheKey, result);
515
+ }
516
+
517
+ return result;
518
+ } catch (error: any) {
519
+ if (options.enableMetrics) {
520
+ ValidationMetrics.record(operationName, Date.now() - startTime, true);
521
+ }
522
+ const msg = `${error instanceof Error ? error.message : "Unknown error"}`;
523
+ const code =
524
+ error instanceof Error ? error.name : ErrorCode.UNKNOWN_ERROR;
525
+ return {
526
+ success: false,
527
+ errors: [ErrorHandler.createValidationError([], msg, code)],
528
+ warnings: [],
529
+ data: value,
530
+ };
531
+ }
532
+ }
533
+
534
+ static validateJsonSync(value: any, options: any): SchemaValidationResult {
535
+ const result: SchemaValidationResult = {
536
+ success: true,
537
+ errors: [],
538
+ warnings: [],
539
+ data: value,
540
+ };
541
+
542
+ const {
543
+ maxDepth = MAX_OBJECT_DEPTH,
544
+ maxKeys = 1000,
545
+ maxStringLength = 10000,
546
+ maxArrayLength = 1000,
547
+ allowedTypes = ["object", "array", "string", "number", "boolean", "null"],
548
+ forbiddenKeys = [],
549
+ schema,
550
+ preventCircular = true,
551
+ maxSize = SECURITY_CONSTANTS.MAX_JSON_SIZE,
552
+ securityMode = "secure",
553
+ } = options;
554
+
555
+ let parsedData: any;
556
+
557
+ if (typeof value === "string") {
558
+ // Size check for string
559
+ if (value.length > maxSize) {
560
+ result.success = false;
561
+ result.errors.push(
562
+ ErrorHandler.createStringError(
563
+ [],
564
+ `JSON string exceeds maximum size of ${maxSize} characters`,
565
+ value,
566
+ ErrorCode.STRING_TOO_LONG
567
+ )
568
+ );
569
+ return result;
570
+ }
571
+
572
+ try {
573
+ parsedData = JSON.parse(value);
574
+ } catch (error) {
575
+ result.success = false;
576
+ result.errors.push(
577
+ ErrorHandler.createValidationError(
578
+ [],
579
+ `Invalid JSON string: ${error instanceof Error ? error.message : "Parse error"}`,
580
+ ErrorCode.INVALID_JSON
581
+ )
582
+ );
583
+ return result;
584
+ }
585
+ } else if (typeof value === "object" && value !== null) {
586
+ parsedData = value;
587
+ } else {
588
+ result.success = false;
589
+ result.errors.push(
590
+ ErrorHandler.createTypeError([], "string or object", value)
591
+ );
592
+ return result;
593
+ }
594
+
595
+ // Security validations based on mode
596
+ if (securityMode === "secure" || securityMode === "strict") {
597
+ if (this.hasDangerousProperties(parsedData)) {
598
+ result.success = false;
599
+ result.errors.push(
600
+ ErrorHandler.createValidationError(
601
+ [],
602
+ "JSON contains dangerous properties (prototype pollution risk)",
603
+ ErrorCode.INVALID_JSON
604
+ )
605
+ );
606
+ return result;
607
+ }
608
+
609
+ if (securityMode === "strict") {
610
+ const ajv = this.getAjv();
611
+ const validate = ajv.getSchema("secure-json-v2");
612
+ if (validate && !validate(parsedData)) {
613
+ result.success = false;
614
+ result.errors.push(
615
+ ErrorHandler.createValidationError(
616
+ [],
617
+ "JSON failed strict security validation",
618
+ ErrorCode.INVALID_JSON
619
+ )
620
+ );
621
+ if (validate.errors) {
622
+ result.warnings.push(
623
+ `AJV errors: ${JSON.stringify(validate.errors)}`
624
+ );
625
+ }
626
+ return result;
627
+ }
628
+ }
629
+ }
630
+
631
+ // Circular reference detection
632
+ if (preventCircular) {
633
+ try {
634
+ JSON.stringify(parsedData);
635
+ } catch (error) {
636
+ result.success = false;
637
+ result.errors.push(
638
+ ErrorHandler.createValidationError(
639
+ [],
640
+ "JSON contains circular references",
641
+ ErrorCode.INVALID_JSON
642
+ )
643
+ );
644
+ return result;
645
+ }
646
+ }
647
+
648
+ // Deep validation
649
+ const validationResult = validateJsonDeep(parsedData, {
650
+ maxDepth,
651
+ maxKeys,
652
+ maxStringLength,
653
+ maxArrayLength,
654
+ allowedTypes,
655
+ forbiddenKeys,
656
+ currentDepth: 0,
657
+ keyCount: 0,
658
+ });
659
+
660
+ result.success = result.success && validationResult.success;
661
+ result.errors.push(...validationResult.errors);
662
+ result.warnings.push(...validationResult.warnings);
663
+ result.data = parsedData;
664
+
665
+ // Schema validation if provided
666
+ if (schema && result.success) {
667
+ const schemaResult = validateJsonSchema(parsedData, schema);
668
+ result.success = result.success && schemaResult.success;
669
+ result.errors.push(...schemaResult.errors);
670
+ result.warnings.push(...schemaResult.warnings);
671
+ }
672
+
673
+ return result;
674
+ }
675
+
676
+ /**
677
+ * IP validation with geographic and security checks
678
+ */
679
+ static validateIp(
680
+ value: any,
681
+ options: {
682
+ version?: "v4" | "v6" | "both";
683
+ allowPrivate?: boolean;
684
+ allowLoopback?: boolean;
685
+ allowMulticast?: boolean;
686
+ allowReserved?: boolean;
687
+ allowCIDR?: boolean;
688
+ strict?: boolean;
689
+ blockBogons?: boolean;
690
+ allowDocumentation?: boolean;
691
+ } = {}
692
+ ): SchemaValidationResult {
693
+ const result: SchemaValidationResult = {
694
+ success: true,
695
+ errors: [],
696
+ warnings: [],
697
+ data: value,
698
+ };
699
+
700
+ const {
701
+ version = "both",
702
+ allowPrivate = true,
703
+ allowLoopback = true,
704
+ allowMulticast = false,
705
+ allowReserved = true,
706
+ allowCIDR = false,
707
+ strict = true,
708
+ blockBogons = false,
709
+ allowDocumentation = true,
710
+ } = options;
711
+
712
+ if (typeof value !== "string") {
713
+ result.success = false;
714
+ result.errors.push(
715
+ ErrorHandler.createSimpleError(
716
+ "Expected string for IP address",
717
+ [],
718
+ "string"
719
+ )
720
+ );
721
+ return result;
722
+ }
723
+
724
+ const ip = value.trim();
725
+
726
+ // Basic format validation
727
+ if (!/^[\d\.:a-fA-F\/]+$/.test(ip)) {
728
+ result.success = false;
729
+ result.errors.push(
730
+ ErrorHandler.createValidationError(
731
+ [],
732
+ "IP address contains invalid characters",
733
+ ErrorCode.SECURITY_VIOLATION
734
+ )
735
+ );
736
+ return result;
737
+ }
738
+
739
+ let ipAddress = ip;
740
+ let cidrPrefix: number | null = null;
741
+ let isIPv4 = false;
742
+ let isIPv6 = false;
743
+
744
+ // Handle CIDR notation
745
+ if (ip.includes("/")) {
746
+ if (!allowCIDR) {
747
+ result.success = false;
748
+ result.errors.push(
749
+ ErrorHandler.createValidationError(
750
+ [],
751
+ "CIDR notation is not allowed",
752
+ ErrorCode.SECURITY_VIOLATION
753
+ )
754
+ );
755
+ return result;
756
+ }
757
+
758
+ const parts = ip.split("/");
759
+ if (parts.length !== 2) {
760
+ result.success = false;
761
+ result.errors.push(
762
+ ErrorHandler.createValidationError(
763
+ [],
764
+ "Invalid CIDR notation format",
765
+ ErrorCode.SECURITY_VIOLATION
766
+ )
767
+ );
768
+ return result;
769
+ }
770
+
771
+ ipAddress = parts[0];
772
+ const prefixStr = parts[1];
773
+
774
+ if (!/^\d+$/.test(prefixStr)) {
775
+ result.success = false;
776
+ result.errors.push(
777
+ ErrorHandler.createValidationError(
778
+ [],
779
+ "CIDR prefix must be numeric",
780
+ ErrorCode.SECURITY_VIOLATION
781
+ )
782
+ );
783
+ return result;
784
+ }
785
+
786
+ cidrPrefix = parseInt(prefixStr, 10);
787
+ }
788
+
789
+ // Validate IP format
790
+ const ipv4Result = validateIPv4(ipAddress, strict);
791
+ const ipv6Result = validateIPv6(ipAddress, strict);
792
+
793
+ isIPv4 = ipv4Result.valid;
794
+ isIPv6 = ipv6Result.valid;
795
+
796
+ // Version validation
797
+ if (version === "v4" && !isIPv4) {
798
+ result.success = false;
799
+ result.errors.push(
800
+ ErrorHandler.createValidationError(
801
+ [],
802
+ "Invalid IPv4 address format",
803
+ ErrorCode.SECURITY_VIOLATION
804
+ )
805
+ );
806
+ return result;
807
+ }
808
+
809
+ if (version === "v6" && !isIPv6) {
810
+ result.success = false;
811
+ result.errors.push(
812
+ ErrorHandler.createValidationError(
813
+ [],
814
+ "Invalid IPv6 address format",
815
+ ErrorCode.SECURITY_VIOLATION
816
+ )
817
+ );
818
+ return result;
819
+ }
820
+
821
+ if (version === "both" && !isIPv4 && !isIPv6) {
822
+ result.success = false;
823
+ result.errors.push(
824
+ ErrorHandler.createValidationError(
825
+ [],
826
+ "Invalid IP address format (must be valid IPv4 or IPv6)",
827
+ ErrorCode.SECURITY_VIOLATION
828
+ )
829
+ );
830
+ return result;
831
+ }
832
+
833
+ // CIDR prefix validation
834
+ if (cidrPrefix !== null) {
835
+ if (isIPv4 && (cidrPrefix < 0 || cidrPrefix > 32)) {
836
+ result.success = false;
837
+ result.errors.push(
838
+ ErrorHandler.createValidationError(
839
+ [],
840
+ "Invalid IPv4 CIDR prefix (must be 0-32)",
841
+ ErrorCode.SECURITY_VIOLATION
842
+ )
843
+ );
844
+ }
845
+ if (isIPv6 && (cidrPrefix < 0 || cidrPrefix > 128)) {
846
+ result.success = false;
847
+ result.errors.push(
848
+ ErrorHandler.createValidationError(
849
+ [],
850
+ "Invalid IPv6 CIDR prefix (must be 0-128)",
851
+ ErrorCode.SECURITY_VIOLATION
852
+ )
853
+ );
854
+ }
855
+ }
856
+
857
+ // IPv4 specific validations
858
+ if (isIPv4) {
859
+ const octets = ipAddress.split(".").map(Number);
860
+
861
+ // private IP detection
862
+ if (!allowPrivate) {
863
+ if (
864
+ octets[0] === 10 ||
865
+ (octets[0] === 172 && octets[1] >= 16 && octets[1] <= 31) ||
866
+ (octets[0] === 192 && octets[1] === 168) ||
867
+ (octets[0] === 169 && octets[1] === 254) // Link-local
868
+ ) {
869
+ result.success = false;
870
+ result.errors.push(
871
+ ErrorHandler.createValidationError(
872
+ [],
873
+ "Private IPv4 addresses not allowed",
874
+ ErrorCode.SECURITY_VIOLATION
875
+ )
876
+ );
877
+ }
878
+ }
879
+
880
+ // Loopback validation
881
+ if (!allowLoopback && octets[0] === 127) {
882
+ result.success = false;
883
+ result.errors.push(
884
+ ErrorHandler.createValidationError(
885
+ [],
886
+ "Loopback addresses not allowed",
887
+ ErrorCode.SECURITY_VIOLATION
888
+ )
889
+ );
890
+ }
891
+
892
+ // Multicast validation
893
+ if (!allowMulticast && octets[0] >= 224 && octets[0] <= 239) {
894
+ result.success = false;
895
+ result.errors.push(
896
+ ErrorHandler.createValidationError(
897
+ [],
898
+ "Multicast addresses not allowed",
899
+ ErrorCode.SECURITY_VIOLATION
900
+ )
901
+ );
902
+ }
903
+
904
+ // Documentation addresses (RFC 5737)
905
+ if (!allowDocumentation) {
906
+ if (
907
+ (octets[0] === 192 && octets[1] === 0 && octets[2] === 2) ||
908
+ (octets[0] === 198 && octets[1] === 51 && octets[2] === 100) ||
909
+ (octets[0] === 203 && octets[1] === 0 && octets[2] === 113)
910
+ ) {
911
+ result.success = false;
912
+ result.errors.push(
913
+ ErrorHandler.createValidationError(
914
+ [],
915
+ "Documentation addresses not allowed",
916
+ ErrorCode.SECURITY_VIOLATION
917
+ )
918
+ );
919
+ }
920
+ }
921
+
922
+ // Bogon detection
923
+ if (blockBogons) {
924
+ if (
925
+ octets[0] === 0 ||
926
+ octets[0] === 255 ||
927
+ (octets[0] >= 240 && octets[0] <= 255)
928
+ ) {
929
+ result.success = false;
930
+ result.errors.push(
931
+ ErrorHandler.createValidationError(
932
+ [],
933
+ "Bogon IP address detected",
934
+ ErrorCode.SECURITY_VIOLATION
935
+ )
936
+ );
937
+ }
938
+ }
939
+
940
+ // Reserved ranges
941
+ if (!allowReserved) {
942
+ if (octets[0] === 0 || octets[0] === 255) {
943
+ result.success = false;
944
+ result.errors.push(
945
+ ErrorHandler.createValidationError(
946
+ [],
947
+ "Reserved IPv4 addresses not allowed",
948
+ ErrorCode.SECURITY_VIOLATION
949
+ )
950
+ );
951
+ }
952
+ }
953
+ }
954
+
955
+ // IPv6 specific validations
956
+ if (isIPv6) {
957
+ const normalized = normalizeIPv6(ipAddress);
958
+
959
+ if (
960
+ !allowLoopback &&
961
+ normalized === "0000:0000:0000:0000:0000:0000:0000:0001"
962
+ ) {
963
+ result.success = false;
964
+ result.errors.push(
965
+ ErrorHandler.createValidationError(
966
+ [],
967
+ "IPv6 loopback address not allowed",
968
+ ErrorCode.SECURITY_VIOLATION
969
+ )
970
+ );
971
+ }
972
+
973
+ // Unique local addresses (RFC 4193)
974
+ if (
975
+ !allowPrivate &&
976
+ (normalized.startsWith("fc00:") || normalized.startsWith("fd00:"))
977
+ ) {
978
+ result.success = false;
979
+ result.errors.push(
980
+ ErrorHandler.createValidationError(
981
+ [],
982
+ "Private IPv6 addresses not allowed",
983
+ ErrorCode.SECURITY_VIOLATION
984
+ )
985
+ );
986
+ }
987
+
988
+ // Link-local addresses
989
+ if (!allowPrivate && normalized.startsWith("fe80:")) {
990
+ result.success = false;
991
+ result.errors.push(
992
+ ErrorHandler.createValidationError(
993
+ [],
994
+ "Link-local IPv6 addresses not allowed",
995
+ ErrorCode.SECURITY_VIOLATION
996
+ )
997
+ );
998
+ }
999
+
1000
+ if (!allowMulticast && normalized.startsWith("ff00:")) {
1001
+ result.success = false;
1002
+ result.errors.push(
1003
+ ErrorHandler.createValidationError(
1004
+ [],
1005
+ "IPv6 multicast addresses not allowed",
1006
+ ErrorCode.SECURITY_VIOLATION
1007
+ )
1008
+ );
1009
+ }
1010
+
1011
+ // Documentation prefix (RFC 3849)
1012
+ if (!allowDocumentation && normalized.startsWith("2001:0db8:")) {
1013
+ result.success = false;
1014
+ result.errors.push(
1015
+ ErrorHandler.createValidationError(
1016
+ [],
1017
+ "Documentation IPv6 addresses not allowed",
1018
+ ErrorCode.SECURITY_VIOLATION
1019
+ )
1020
+ );
1021
+ }
1022
+ }
1023
+
1024
+ return result;
1025
+ }
1026
+
1027
+ /**
1028
+ * object validation with better security and performance
1029
+ */
1030
+ static validateObject(
1031
+ value: any,
1032
+ options: {
1033
+ allowNull?: boolean;
1034
+ allowArray?: boolean;
1035
+ maxDepth?: number;
1036
+ maxKeys?: number;
1037
+ requiredKeys?: string[];
1038
+ allowedKeys?: string[];
1039
+ forbiddenKeys?: string[];
1040
+ keyPattern?: RegExp;
1041
+ schema?: any;
1042
+ strict?: boolean;
1043
+ preventPrototypePollution?: boolean;
1044
+ maxPropertyNameLength?: number;
1045
+ } = {}
1046
+ ): SchemaValidationResult {
1047
+ const result: SchemaValidationResult = {
1048
+ success: true,
1049
+ errors: [],
1050
+ warnings: [],
1051
+ data: value,
1052
+ };
1053
+
1054
+ const {
1055
+ allowNull = false,
1056
+ allowArray = false,
1057
+ maxDepth = MAX_OBJECT_DEPTH,
1058
+ maxKeys = 1000,
1059
+ requiredKeys = [],
1060
+ allowedKeys = [],
1061
+ forbiddenKeys = [],
1062
+ keyPattern,
1063
+ schema,
1064
+ strict = false,
1065
+ preventPrototypePollution = true,
1066
+ maxPropertyNameLength = 100,
1067
+ } = options;
1068
+
1069
+ // Null check
1070
+ if (value === null) {
1071
+ if (!allowNull) {
1072
+ result.success = false;
1073
+ result.errors.push(
1074
+ ErrorHandler.createValidationError(
1075
+ [],
1076
+ "Null values not allowed",
1077
+ ErrorCode.SECURITY_VIOLATION
1078
+ )
1079
+ );
1080
+ }
1081
+ return result;
1082
+ }
1083
+
1084
+ // Array check
1085
+ if (Array.isArray(value)) {
1086
+ if (!allowArray) {
1087
+ result.success = false;
1088
+ result.errors.push(
1089
+ ErrorHandler.createValidationError(
1090
+ [],
1091
+ "Arrays not allowed",
1092
+ ErrorCode.SECURITY_VIOLATION
1093
+ )
1094
+ );
1095
+ }
1096
+ return result;
1097
+ }
1098
+
1099
+ // Type check
1100
+ if (typeof value !== "object") {
1101
+ result.success = false;
1102
+ result.errors.push(ErrorHandler.createTypeError([], "object", value));
1103
+ return result;
1104
+ }
1105
+
1106
+ // Prototype pollution check
1107
+ if (preventPrototypePollution && this.hasDangerousProperties(value)) {
1108
+ result.success = false;
1109
+ result.errors.push(
1110
+ ErrorHandler.createValidationError(
1111
+ [],
1112
+ "Object contains dangerous properties that could lead to prototype pollution",
1113
+ ErrorCode.SECURITY_VIOLATION
1114
+ )
1115
+ );
1116
+ return result;
1117
+ }
1118
+
1119
+ const keys = Object.keys(value);
1120
+
1121
+ // Key count validation
1122
+ if (keys.length > maxKeys) {
1123
+ result.success = false;
1124
+ result.errors.push(
1125
+ ErrorHandler.createValidationError(
1126
+ [],
1127
+ `Object has too many keys (${keys.length}), maximum allowed: ${maxKeys}`,
1128
+ ErrorCode.SECURITY_VIOLATION
1129
+ )
1130
+ );
1131
+ }
1132
+
1133
+ // Required keys validation
1134
+ for (const requiredKey of requiredKeys) {
1135
+ if (!(requiredKey in value)) {
1136
+ result.success = false;
1137
+ result.errors.push(
1138
+ ErrorHandler.createValidationError(
1139
+ [],
1140
+ `Missing required key: ${requiredKey}`,
1141
+ ErrorCode.SECURITY_VIOLATION
1142
+ )
1143
+ );
1144
+ }
1145
+ }
1146
+
1147
+ // key validation
1148
+ for (const key of keys) {
1149
+ // Property name length check
1150
+ if (key.length > maxPropertyNameLength) {
1151
+ result.success = false;
1152
+ result.errors.push(
1153
+ ErrorHandler.createValidationError(
1154
+ [],
1155
+ `Property name '${key.substring(0, 20)}...' exceeds maximum length of ${maxPropertyNameLength}`,
1156
+ ErrorCode.SECURITY_VIOLATION
1157
+ )
1158
+ );
1159
+ continue;
1160
+ }
1161
+
1162
+ // Dangerous key detection
1163
+ if (SECURITY_CONSTANTS.DANGEROUS_PROPERTIES.has(key)) {
1164
+ result.success = false;
1165
+ result.errors.push(
1166
+ ErrorHandler.createValidationError(
1167
+ [],
1168
+ `Dangerous property name detected: '${key}'`,
1169
+ ErrorCode.SECURITY_VIOLATION
1170
+ )
1171
+ );
1172
+ continue;
1173
+ }
1174
+
1175
+ // Allowed keys check
1176
+ if (allowedKeys.length > 0 && !allowedKeys.includes(key)) {
1177
+ if (strict) {
1178
+ result.success = false;
1179
+ result.errors.push(
1180
+ ErrorHandler.createValidationError(
1181
+ [],
1182
+ `Key '${key}' is not in allowed keys list`,
1183
+ ErrorCode.SECURITY_VIOLATION
1184
+ )
1185
+ );
1186
+ } else {
1187
+ result.warnings.push(`Key '${key}' is not in allowed keys list`);
1188
+ }
1189
+ }
1190
+
1191
+ // Forbidden keys check
1192
+ if (forbiddenKeys.includes(key)) {
1193
+ result.success = false;
1194
+ result.errors.push(
1195
+ ErrorHandler.createValidationError(
1196
+ [],
1197
+ `Key '${key}' is forbidden`,
1198
+ ErrorCode.SECURITY_VIOLATION
1199
+ )
1200
+ );
1201
+ }
1202
+
1203
+ // Key pattern validation
1204
+ if (keyPattern && !keyPattern.test(key)) {
1205
+ result.success = false;
1206
+ result.errors.push(
1207
+ ErrorHandler.createValidationError(
1208
+ [],
1209
+ `Key '${key}' does not match required pattern`,
1210
+ ErrorCode.SECURITY_VIOLATION
1211
+ )
1212
+ );
1213
+ }
1214
+
1215
+ // Check for suspicious patterns in key names
1216
+ if (/^__|.*prototype.*|.*constructor.*$/i.test(key)) {
1217
+ result.warnings.push(`Suspicious property name detected: '${key}'`);
1218
+ }
1219
+ }
1220
+
1221
+ // Deep structure validation
1222
+ const deepResult = validateObjectDeep(value, maxDepth, 0);
1223
+ result.success = result.success && deepResult.success;
1224
+ result.errors.push(...deepResult.errors);
1225
+ result.warnings.push(...deepResult.warnings);
1226
+
1227
+ // Schema validation if provided
1228
+ if (schema && result.success) {
1229
+ const schemaResult = validateObjectSchema(value, schema);
1230
+ result.success = result.success && schemaResult.success;
1231
+ result.errors.push(...schemaResult.errors);
1232
+ result.warnings.push(...schemaResult.warnings);
1233
+ }
1234
+
1235
+ return result;
1236
+ }
1237
+
1238
+ /**
1239
+ * Validate email address with comprehensive checks
1240
+ */
1241
+ static validateEmail(
1242
+ value: any,
1243
+ options: {
1244
+ allowInternational?: boolean;
1245
+ maxLength?: number;
1246
+ allowedDomains?: string[];
1247
+ blockedDomains?: string[];
1248
+ requireMX?: boolean;
1249
+ strict?: boolean;
1250
+ } = {}
1251
+ ): SchemaValidationResult {
1252
+ const result: SchemaValidationResult = {
1253
+ success: true,
1254
+ errors: [],
1255
+ warnings: [],
1256
+ data: value,
1257
+ };
1258
+
1259
+ const {
1260
+ allowInternational = true,
1261
+ maxLength = 254,
1262
+ allowedDomains = [],
1263
+ blockedDomains = [],
1264
+ strict = true,
1265
+ } = options;
1266
+
1267
+ if (typeof value !== "string") {
1268
+ result.success = false;
1269
+ result.errors.push(ErrorHandler.createTypeError([], "string", value));
1270
+ return result;
1271
+ }
1272
+
1273
+ const email = value.trim().toLowerCase();
1274
+
1275
+ // Length check
1276
+ if (email.length > maxLength) {
1277
+ result.success = false;
1278
+ result.errors.push(
1279
+ ErrorHandler.createStringError(
1280
+ [],
1281
+ `Email exceeds maximum length of ${maxLength} characters`,
1282
+ value,
1283
+ ErrorCode.STRING_TOO_LONG
1284
+ )
1285
+ );
1286
+ return result;
1287
+ }
1288
+
1289
+ // Basic format check - must contain exactly one @
1290
+ const atSymbolCount = (email.match(/@/g) || []).length;
1291
+ if (atSymbolCount !== 1) {
1292
+ result.success = false;
1293
+ result.errors.push(
1294
+ ErrorHandler.createValidationError(
1295
+ [],
1296
+ "Email must contain exactly one @ symbol",
1297
+ ErrorCode.SECURITY_VIOLATION
1298
+ )
1299
+ );
1300
+ return result;
1301
+ }
1302
+
1303
+ const [localPart, domain] = email.split("@");
1304
+
1305
+ // Check for empty parts
1306
+ if (!localPart || !domain) {
1307
+ result.success = false;
1308
+ result.errors.push(
1309
+ ErrorHandler.createValidationError(
1310
+ [],
1311
+ "Email local part and domain cannot be empty",
1312
+ ErrorCode.SECURITY_VIOLATION
1313
+ )
1314
+ );
1315
+ return result;
1316
+ }
1317
+
1318
+ // Local part length validation
1319
+ if (localPart.length > 64) {
1320
+ result.success = false;
1321
+ result.errors.push(
1322
+ ErrorHandler.createValidationError(
1323
+ [],
1324
+ "Email local part exceeds 64 characters",
1325
+ ErrorCode.SECURITY_VIOLATION
1326
+ )
1327
+ );
1328
+ }
1329
+ // Plus addressing check - FIXED LOGIC
1330
+ if (localPart.includes("+")) {
1331
+ result.success = false;
1332
+ result.errors.push(
1333
+ ErrorHandler.createValidationError(
1334
+ [],
1335
+ "Plus addressing (+ symbols) is not allowed",
1336
+ ErrorCode.SECURITY_VIOLATION
1337
+ )
1338
+ );
1339
+ }
1340
+
1341
+ // Local part character validation - FIXED TO PROPERLY HANDLE INVALID CHARACTERS
1342
+ if (strict) {
1343
+ // Practical validation - common characters only (excludes # and other problematic chars)
1344
+ const validLocalPartRegex = /^[a-zA-Z0-9._+-]+$/;
1345
+ if (!validLocalPartRegex.test(localPart)) {
1346
+ result.success = false;
1347
+ result.errors.push(
1348
+ ErrorHandler.createValidationError(
1349
+ [],
1350
+ "Email local part contains invalid characters",
1351
+ ErrorCode.SECURITY_VIOLATION
1352
+ )
1353
+ );
1354
+ }
1355
+ } else {
1356
+ // RFC 5322 compliant - more permissive but excludes problematic chars like #
1357
+ const validLocalPartRegex =
1358
+ /^[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*$/;
1359
+ if (!validLocalPartRegex.test(localPart)) {
1360
+ result.success = false;
1361
+ result.errors.push(
1362
+ ErrorHandler.createValidationError(
1363
+ [],
1364
+ "Email local part contains invalid characters",
1365
+ ErrorCode.SECURITY_VIOLATION
1366
+ )
1367
+ );
1368
+ }
1369
+ }
1370
+
1371
+ // Check for consecutive dots
1372
+ if (localPart.includes("..")) {
1373
+ result.success = false;
1374
+ result.errors.push(
1375
+ ErrorHandler.createValidationError(
1376
+ [],
1377
+ "Email local part cannot contain consecutive dots",
1378
+ ErrorCode.SECURITY_VIOLATION
1379
+ )
1380
+ );
1381
+ }
1382
+
1383
+ // Check for dots at start or end
1384
+ if (localPart.startsWith(".") || localPart.endsWith(".")) {
1385
+ result.success = false;
1386
+ result.errors.push(
1387
+ ErrorHandler.createValidationError(
1388
+ [],
1389
+ "Email local part cannot start or end with a dot",
1390
+ ErrorCode.SECURITY_VIOLATION
1391
+ )
1392
+ );
1393
+ }
1394
+
1395
+ // Domain validation
1396
+ if (domain.length > 255) {
1397
+ result.success = false;
1398
+ result.errors.push(
1399
+ ErrorHandler.createValidationError(
1400
+ [],
1401
+ "Email domain exceeds 255 characters",
1402
+ ErrorCode.SECURITY_VIOLATION
1403
+ )
1404
+ );
1405
+ }
1406
+
1407
+ // Domain format validation
1408
+ if (strict) {
1409
+ // Basic domain validation - must have at least one dot and valid TLD
1410
+ const validDomainRegex = /^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
1411
+ if (!validDomainRegex.test(domain)) {
1412
+ result.success = false;
1413
+ result.errors.push(
1414
+ ErrorHandler.createValidationError(
1415
+ [],
1416
+ "Invalid domain format - must contain at least one dot and valid TLD",
1417
+ ErrorCode.SECURITY_VIOLATION
1418
+ )
1419
+ );
1420
+ }
1421
+ } else {
1422
+ // More strict domain validation
1423
+ const validDomainRegex =
1424
+ /^[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
1425
+ if (!validDomainRegex.test(domain)) {
1426
+ result.success = false;
1427
+ result.errors.push(
1428
+ ErrorHandler.createValidationError(
1429
+ [],
1430
+ "Invalid domain format",
1431
+ ErrorCode.SECURITY_VIOLATION
1432
+ )
1433
+ );
1434
+ }
1435
+ }
1436
+
1437
+ // Check for consecutive dots in domain
1438
+ if (domain.includes("..")) {
1439
+ result.success = false;
1440
+ result.errors.push(
1441
+ ErrorHandler.createValidationError(
1442
+ [],
1443
+ "Domain cannot contain consecutive dots",
1444
+ ErrorCode.SECURITY_VIOLATION
1445
+ )
1446
+ );
1447
+ }
1448
+
1449
+ // Check for dots at start or end of domain
1450
+ if (domain.startsWith(".") || domain.endsWith(".")) {
1451
+ result.success = false;
1452
+ result.errors.push(
1453
+ ErrorHandler.createValidationError(
1454
+ [],
1455
+ "Domain cannot start or end with a dot",
1456
+ ErrorCode.SECURITY_VIOLATION
1457
+ )
1458
+ );
1459
+ }
1460
+
1461
+ // International domain validation
1462
+ if (!allowInternational && /[^\x00-\x7F]/.test(domain)) {
1463
+ result.success = false;
1464
+ result.errors.push(
1465
+ ErrorHandler.createValidationError(
1466
+ [],
1467
+ "International domain names are not allowed",
1468
+ ErrorCode.SECURITY_VIOLATION
1469
+ )
1470
+ );
1471
+ }
1472
+
1473
+ // Domain whitelist/blacklist
1474
+ if (allowedDomains.length > 0 && !allowedDomains.includes(domain)) {
1475
+ result.success = false;
1476
+ result.errors.push(
1477
+ ErrorHandler.createValidationError(
1478
+ [],
1479
+ `Email domain '${domain}' is not allowed`,
1480
+ ErrorCode.SECURITY_VIOLATION
1481
+ )
1482
+ );
1483
+ }
1484
+
1485
+ if (blockedDomains.includes(domain)) {
1486
+ result.success = false;
1487
+ result.errors.push(
1488
+ ErrorHandler.createValidationError(
1489
+ [],
1490
+ `Email domain '${domain}' is blocked`,
1491
+ ErrorCode.SECURITY_VIOLATION
1492
+ )
1493
+ );
1494
+ }
1495
+
1496
+ // Additional validation for common invalid patterns
1497
+ const invalidCharsRegex = /[<>()[\]\\,;:\s@"]/;
1498
+ if (invalidCharsRegex.test(localPart)) {
1499
+ result.success = false;
1500
+ result.errors.push(
1501
+ ErrorHandler.createValidationError(
1502
+ [],
1503
+ "Email local part contains prohibited characters (spaces, quotes, brackets, etc.)",
1504
+ ErrorCode.SECURITY_VIOLATION
1505
+ )
1506
+ );
1507
+ }
1508
+
1509
+ // Suspicious patterns
1510
+ if (/test|temp|fake|spam|noreply/i.test(email)) {
1511
+ result.warnings.push("Email appears to be temporary or test address");
1512
+ }
1513
+
1514
+ // Set the cleaned data
1515
+ result.data = email;
1516
+
1517
+ return result;
1518
+ }
1519
+
1520
+ /**
1521
+ * Get validation performance metrics
1522
+ */
1523
+ static getMetrics(): Record<string, any> {
1524
+ return ValidationMetrics.getMetrics();
1525
+ }
1526
+
1527
+ /**
1528
+ * Reset validation metrics
1529
+ */
1530
+ static resetMetrics(): void {
1531
+ ValidationMetrics.reset();
1532
+ }
1533
+
1534
+ /**
1535
+ * Clear validation cache
1536
+ */
1537
+ static clearCache(): void {
1538
+ ValidationCache.clear();
1539
+ }
1540
+
1541
+ /**
1542
+ * Validate multiple values with batch processing
1543
+ */
1544
+ static async validateBatch<T>(
1545
+ values: T[],
1546
+ validator: (
1547
+ value: T
1548
+ ) => Promise<SchemaValidationResult> | SchemaValidationResult,
1549
+ options: {
1550
+ continueOnError?: boolean;
1551
+ maxConcurrency?: number;
1552
+ timeout?: number;
1553
+ } = {}
1554
+ ): Promise<{
1555
+ results: SchemaValidationResult[];
1556
+ summary: { total: number; passed: number; failed: number };
1557
+ }> {
1558
+ const {
1559
+ continueOnError = true,
1560
+ maxConcurrency = 10,
1561
+ timeout = 30000,
1562
+ } = options;
1563
+
1564
+ const results: SchemaValidationResult[] = [];
1565
+ const batches: T[][] = [];
1566
+
1567
+ // Create batches
1568
+ for (let i = 0; i < values.length; i += maxConcurrency) {
1569
+ batches.push(values.slice(i, i + maxConcurrency));
1570
+ }
1571
+
1572
+ try {
1573
+ await this.withTimeout(async () => {
1574
+ for (const batch of batches) {
1575
+ const batchPromises = batch.map(async (value) => {
1576
+ try {
1577
+ return await Promise.resolve(validator(value));
1578
+ } catch (error) {
1579
+ return {
1580
+ success: false,
1581
+ errors: [
1582
+ ErrorHandler.createValidationError(
1583
+ [],
1584
+ `Batch validation error: ${error instanceof Error ? error.message : "Unknown error"}`,
1585
+ ErrorCode.UNKNOWN_ERROR
1586
+ ),
1587
+ ],
1588
+ warnings: [],
1589
+ data: value,
1590
+ } as SchemaValidationResult;
1591
+ }
1592
+ });
1593
+
1594
+ const batchResults = await Promise.all(batchPromises);
1595
+ results.push(...batchResults);
1596
+
1597
+ // Stop on first error if continueOnError is false
1598
+ if (!continueOnError && batchResults.some((r) => !r.success)) {
1599
+ break;
1600
+ }
1601
+ }
1602
+ }, timeout);
1603
+ } catch (error) {
1604
+ // Add timeout error for remaining values
1605
+ const remaining = values.length - results.length;
1606
+ for (let i = 0; i < remaining; i++) {
1607
+ results.push({
1608
+ success: false,
1609
+ errors: [
1610
+ ErrorHandler.createValidationError(
1611
+ [],
1612
+ `Batch validation timeout: ${error instanceof Error ? error.message : "Unknown error"}`,
1613
+ ErrorCode.UNKNOWN_ERROR
1614
+ ),
1615
+ ],
1616
+ warnings: [],
1617
+ data: values[results.length + i],
1618
+ });
1619
+ }
1620
+ }
1621
+
1622
+ const summary = {
1623
+ total: results.length,
1624
+ passed: results.filter((r) => r.success).length,
1625
+ failed: results.filter((r) => !r.success).length,
1626
+ };
1627
+
1628
+ return { results, summary };
1629
+ }
1630
+ }
1631
+
1632
+ // Export additional utilities
1633
+ export { ValidationMetrics, ValidationCache, SECURITY_CONSTANTS };
1634
+ export { SecurityValidators as Security };