@lowerdeck/validation 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 (250) hide show
  1. package/.turbo/turbo-build.log +11 -0
  2. package/.turbo/turbo-test.log +144 -0
  3. package/README.md +158 -0
  4. package/dist/index.cjs +2 -0
  5. package/dist/index.cjs.map +1 -0
  6. package/dist/index.d.ts +119 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.modern.js +2 -0
  9. package/dist/index.modern.js.map +1 -0
  10. package/dist/index.module.js +2 -0
  11. package/dist/index.module.js.map +1 -0
  12. package/dist/index.umd.js +2 -0
  13. package/dist/index.umd.js.map +1 -0
  14. package/dist/lib/introspect.d.ts +13 -0
  15. package/dist/lib/introspect.d.ts.map +1 -0
  16. package/dist/lib/result.d.ts +4 -0
  17. package/dist/lib/result.d.ts.map +1 -0
  18. package/dist/lib/result.test.d.ts +2 -0
  19. package/dist/lib/result.test.d.ts.map +1 -0
  20. package/dist/lib/types.d.ts +48 -0
  21. package/dist/lib/types.d.ts.map +1 -0
  22. package/dist/lib/validator.d.ts +3 -0
  23. package/dist/lib/validator.d.ts.map +1 -0
  24. package/dist/lib/validator.test.d.ts +2 -0
  25. package/dist/lib/validator.test.d.ts.map +1 -0
  26. package/dist/modifiers/color.d.ts +5 -0
  27. package/dist/modifiers/color.d.ts.map +1 -0
  28. package/dist/modifiers/color.test.d.ts +2 -0
  29. package/dist/modifiers/color.test.d.ts.map +1 -0
  30. package/dist/modifiers/email.d.ts +5 -0
  31. package/dist/modifiers/email.d.ts.map +1 -0
  32. package/dist/modifiers/email.test.d.ts +2 -0
  33. package/dist/modifiers/email.test.d.ts.map +1 -0
  34. package/dist/modifiers/emoji.d.ts +5 -0
  35. package/dist/modifiers/emoji.d.ts.map +1 -0
  36. package/dist/modifiers/emoji.test.d.ts +2 -0
  37. package/dist/modifiers/emoji.test.d.ts.map +1 -0
  38. package/dist/modifiers/endsWith.d.ts +5 -0
  39. package/dist/modifiers/endsWith.d.ts.map +1 -0
  40. package/dist/modifiers/endsWith.test.d.ts +2 -0
  41. package/dist/modifiers/endsWith.test.d.ts.map +1 -0
  42. package/dist/modifiers/equals.d.ts +8 -0
  43. package/dist/modifiers/equals.d.ts.map +1 -0
  44. package/dist/modifiers/equals.test.d.ts +2 -0
  45. package/dist/modifiers/equals.test.d.ts.map +1 -0
  46. package/dist/modifiers/includes.d.ts +8 -0
  47. package/dist/modifiers/includes.d.ts.map +1 -0
  48. package/dist/modifiers/includes.test.d.ts +2 -0
  49. package/dist/modifiers/includes.test.d.ts.map +1 -0
  50. package/dist/modifiers/index.d.ts +18 -0
  51. package/dist/modifiers/index.d.ts.map +1 -0
  52. package/dist/modifiers/integer.d.ts +5 -0
  53. package/dist/modifiers/integer.d.ts.map +1 -0
  54. package/dist/modifiers/integer.test.d.ts +2 -0
  55. package/dist/modifiers/integer.test.d.ts.map +1 -0
  56. package/dist/modifiers/ip.d.ts +11 -0
  57. package/dist/modifiers/ip.d.ts.map +1 -0
  58. package/dist/modifiers/ip.test.d.ts +2 -0
  59. package/dist/modifiers/ip.test.d.ts.map +1 -0
  60. package/dist/modifiers/isoDate.d.ts +11 -0
  61. package/dist/modifiers/isoDate.d.ts.map +1 -0
  62. package/dist/modifiers/isoDate.test.d.ts +2 -0
  63. package/dist/modifiers/isoDate.test.d.ts.map +1 -0
  64. package/dist/modifiers/length.d.ts +9 -0
  65. package/dist/modifiers/length.d.ts.map +1 -0
  66. package/dist/modifiers/length.test.d.ts +2 -0
  67. package/dist/modifiers/length.test.d.ts.map +1 -0
  68. package/dist/modifiers/multipleOf.d.ts +5 -0
  69. package/dist/modifiers/multipleOf.d.ts.map +1 -0
  70. package/dist/modifiers/multipleOf.test.d.ts +2 -0
  71. package/dist/modifiers/multipleOf.test.d.ts.map +1 -0
  72. package/dist/modifiers/oneOf.d.ts +5 -0
  73. package/dist/modifiers/oneOf.d.ts.map +1 -0
  74. package/dist/modifiers/oneOf.test.d.ts +2 -0
  75. package/dist/modifiers/oneOf.test.d.ts.map +1 -0
  76. package/dist/modifiers/positive.d.ts +8 -0
  77. package/dist/modifiers/positive.d.ts.map +1 -0
  78. package/dist/modifiers/positive.test.d.ts +2 -0
  79. package/dist/modifiers/positive.test.d.ts.map +1 -0
  80. package/dist/modifiers/regex.d.ts +5 -0
  81. package/dist/modifiers/regex.d.ts.map +1 -0
  82. package/dist/modifiers/regex.test.d.ts +2 -0
  83. package/dist/modifiers/regex.test.d.ts.map +1 -0
  84. package/dist/modifiers/size.d.ts +8 -0
  85. package/dist/modifiers/size.d.ts.map +1 -0
  86. package/dist/modifiers/size.test.d.ts +2 -0
  87. package/dist/modifiers/size.test.d.ts.map +1 -0
  88. package/dist/modifiers/startsWith.d.ts +5 -0
  89. package/dist/modifiers/startsWith.d.ts.map +1 -0
  90. package/dist/modifiers/startsWith.test.d.ts +2 -0
  91. package/dist/modifiers/startsWith.test.d.ts.map +1 -0
  92. package/dist/modifiers/url.d.ts +6 -0
  93. package/dist/modifiers/url.d.ts.map +1 -0
  94. package/dist/modifiers/url.test.d.ts +2 -0
  95. package/dist/modifiers/url.test.d.ts.map +1 -0
  96. package/dist/transformers/case.d.ts +4 -0
  97. package/dist/transformers/case.d.ts.map +1 -0
  98. package/dist/transformers/case.test.d.ts +2 -0
  99. package/dist/transformers/case.test.d.ts.map +1 -0
  100. package/dist/transformers/index.d.ts +3 -0
  101. package/dist/transformers/index.d.ts.map +1 -0
  102. package/dist/transformers/trim.d.ts +5 -0
  103. package/dist/transformers/trim.d.ts.map +1 -0
  104. package/dist/transformers/trim.test.d.ts +2 -0
  105. package/dist/transformers/trim.test.d.ts.map +1 -0
  106. package/dist/validators/any.d.ts +4 -0
  107. package/dist/validators/any.d.ts.map +1 -0
  108. package/dist/validators/any.test.d.ts +2 -0
  109. package/dist/validators/any.test.d.ts.map +1 -0
  110. package/dist/validators/array.d.ts +3 -0
  111. package/dist/validators/array.d.ts.map +1 -0
  112. package/dist/validators/array.test.d.ts +2 -0
  113. package/dist/validators/array.test.d.ts.map +1 -0
  114. package/dist/validators/boolean.d.ts +3 -0
  115. package/dist/validators/boolean.d.ts.map +1 -0
  116. package/dist/validators/boolean.test.d.ts +2 -0
  117. package/dist/validators/boolean.test.d.ts.map +1 -0
  118. package/dist/validators/date.d.ts +3 -0
  119. package/dist/validators/date.d.ts.map +1 -0
  120. package/dist/validators/date.test.d.ts +2 -0
  121. package/dist/validators/date.test.d.ts.map +1 -0
  122. package/dist/validators/enum.d.ts +6 -0
  123. package/dist/validators/enum.d.ts.map +1 -0
  124. package/dist/validators/enum.test.d.ts +2 -0
  125. package/dist/validators/enum.test.d.ts.map +1 -0
  126. package/dist/validators/index.d.ts +17 -0
  127. package/dist/validators/index.d.ts.map +1 -0
  128. package/dist/validators/intersection.d.ts +3 -0
  129. package/dist/validators/intersection.d.ts.map +1 -0
  130. package/dist/validators/intersection.test.d.ts +2 -0
  131. package/dist/validators/intersection.test.d.ts.map +1 -0
  132. package/dist/validators/literal.d.ts +3 -0
  133. package/dist/validators/literal.d.ts.map +1 -0
  134. package/dist/validators/literal.test.d.ts +2 -0
  135. package/dist/validators/literal.test.d.ts.map +1 -0
  136. package/dist/validators/null.d.ts +3 -0
  137. package/dist/validators/null.d.ts.map +1 -0
  138. package/dist/validators/null.test.d.ts +2 -0
  139. package/dist/validators/null.test.d.ts.map +1 -0
  140. package/dist/validators/nullable.d.ts +3 -0
  141. package/dist/validators/nullable.d.ts.map +1 -0
  142. package/dist/validators/nullable.test.d.ts +2 -0
  143. package/dist/validators/nullable.test.d.ts.map +1 -0
  144. package/dist/validators/number.d.ts +3 -0
  145. package/dist/validators/number.d.ts.map +1 -0
  146. package/dist/validators/number.test.d.ts +2 -0
  147. package/dist/validators/number.test.d.ts.map +1 -0
  148. package/dist/validators/object.d.ts +12 -0
  149. package/dist/validators/object.d.ts.map +1 -0
  150. package/dist/validators/object.test.d.ts +2 -0
  151. package/dist/validators/object.test.d.ts.map +1 -0
  152. package/dist/validators/optional.d.ts +3 -0
  153. package/dist/validators/optional.d.ts.map +1 -0
  154. package/dist/validators/optional.test.d.ts +2 -0
  155. package/dist/validators/optional.test.d.ts.map +1 -0
  156. package/dist/validators/record.d.ts +3 -0
  157. package/dist/validators/record.d.ts.map +1 -0
  158. package/dist/validators/record.test.d.ts +2 -0
  159. package/dist/validators/record.test.d.ts.map +1 -0
  160. package/dist/validators/string.d.ts +3 -0
  161. package/dist/validators/string.d.ts.map +1 -0
  162. package/dist/validators/string.test.d.ts +2 -0
  163. package/dist/validators/string.test.d.ts.map +1 -0
  164. package/dist/validators/union.d.ts +3 -0
  165. package/dist/validators/union.d.ts.map +1 -0
  166. package/dist/validators/union.test.d.ts +2 -0
  167. package/dist/validators/union.test.d.ts.map +1 -0
  168. package/dist/validators/void.d.ts +3 -0
  169. package/dist/validators/void.d.ts.map +1 -0
  170. package/package.json +31 -0
  171. package/src/index.ts +33 -0
  172. package/src/lib/introspect.ts +33 -0
  173. package/src/lib/result.test.ts +80 -0
  174. package/src/lib/result.ts +11 -0
  175. package/src/lib/types.ts +57 -0
  176. package/src/lib/validator.test.ts +82 -0
  177. package/src/lib/validator.ts +63 -0
  178. package/src/modifiers/color.test.ts +29 -0
  179. package/src/modifiers/color.ts +18 -0
  180. package/src/modifiers/email.test.ts +29 -0
  181. package/src/modifiers/email.ts +18 -0
  182. package/src/modifiers/emoji.test.ts +31 -0
  183. package/src/modifiers/emoji.ts +18 -0
  184. package/src/modifiers/endsWith.test.ts +50 -0
  185. package/src/modifiers/endsWith.ts +18 -0
  186. package/src/modifiers/equals.test.ts +70 -0
  187. package/src/modifiers/equals.ts +41 -0
  188. package/src/modifiers/includes.test.ts +64 -0
  189. package/src/modifiers/includes.ts +35 -0
  190. package/src/modifiers/index.ts +17 -0
  191. package/src/modifiers/integer.test.ts +45 -0
  192. package/src/modifiers/integer.ts +18 -0
  193. package/src/modifiers/ip.test.ts +34 -0
  194. package/src/modifiers/ip.ts +50 -0
  195. package/src/modifiers/isoDate.test.ts +83 -0
  196. package/src/modifiers/isoDate.ts +51 -0
  197. package/src/modifiers/length.test.ts +107 -0
  198. package/src/modifiers/length.ts +54 -0
  199. package/src/modifiers/multipleOf.test.ts +51 -0
  200. package/src/modifiers/multipleOf.ts +18 -0
  201. package/src/modifiers/oneOf.test.ts +27 -0
  202. package/src/modifiers/oneOf.ts +16 -0
  203. package/src/modifiers/positive.test.ts +64 -0
  204. package/src/modifiers/positive.ts +35 -0
  205. package/src/modifiers/regex.test.ts +40 -0
  206. package/src/modifiers/regex.ts +17 -0
  207. package/src/modifiers/size.test.ts +84 -0
  208. package/src/modifiers/size.ts +37 -0
  209. package/src/modifiers/startsWith.test.ts +40 -0
  210. package/src/modifiers/startsWith.ts +18 -0
  211. package/src/modifiers/url.test.ts +48 -0
  212. package/src/modifiers/url.ts +30 -0
  213. package/src/transformers/case.test.ts +36 -0
  214. package/src/transformers/case.ts +5 -0
  215. package/src/transformers/index.ts +2 -0
  216. package/src/transformers/trim.test.ts +32 -0
  217. package/src/transformers/trim.ts +7 -0
  218. package/src/validators/any.test.ts +11 -0
  219. package/src/validators/any.ts +11 -0
  220. package/src/validators/array.test.ts +46 -0
  221. package/src/validators/array.ts +43 -0
  222. package/src/validators/boolean.test.ts +39 -0
  223. package/src/validators/boolean.ts +34 -0
  224. package/src/validators/date.test.ts +39 -0
  225. package/src/validators/date.ts +26 -0
  226. package/src/validators/enum.test.ts +25 -0
  227. package/src/validators/enum.ts +56 -0
  228. package/src/validators/index.ts +16 -0
  229. package/src/validators/intersection.test.ts +35 -0
  230. package/src/validators/intersection.ts +24 -0
  231. package/src/validators/literal.test.ts +42 -0
  232. package/src/validators/literal.ts +26 -0
  233. package/src/validators/null.test.ts +39 -0
  234. package/src/validators/null.ts +18 -0
  235. package/src/validators/nullable.test.ts +34 -0
  236. package/src/validators/nullable.ts +16 -0
  237. package/src/validators/number.test.ts +39 -0
  238. package/src/validators/number.ts +23 -0
  239. package/src/validators/object.test.ts +66 -0
  240. package/src/validators/object.ts +66 -0
  241. package/src/validators/optional.test.ts +33 -0
  242. package/src/validators/optional.ts +16 -0
  243. package/src/validators/record.test.ts +56 -0
  244. package/src/validators/record.ts +56 -0
  245. package/src/validators/string.test.ts +39 -0
  246. package/src/validators/string.ts +30 -0
  247. package/src/validators/union.test.ts +73 -0
  248. package/src/validators/union.ts +38 -0
  249. package/src/validators/void.ts +6 -0
  250. package/tsconfig.json +9 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"null.d.ts","sourceRoot":"","sources":["../../src/validators/null.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGhD,eAAO,IAAI,SAAS,4FAalB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=null.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"null.test.d.ts","sourceRoot":"","sources":["../../src/validators/null.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import { ValidationType, ValidationTypeValue } from '../lib/types';
2
+ export declare let nullable: <A extends ValidationType<any>>(validator: A) => ValidationType<ValidationTypeValue<A> | null>;
3
+ //# sourceMappingURL=nullable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nullable.d.ts","sourceRoot":"","sources":["../../src/validators/nullable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEnE,eAAO,IAAI,QAAQ,GAAI,CAAC,SAAS,cAAc,CAAC,GAAG,CAAC,EAClD,WAAW,CAAC,KACX,cAAc,CAAC,mBAAmB,CAAC,CAAC,CAAC,GAAG,IAAI,CAW7C,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=nullable.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nullable.test.d.ts","sourceRoot":"","sources":["../../src/validators/nullable.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import { ValidatorOptions } from '../lib/types';
2
+ export declare let number: (opts?: ValidatorOptions<number> | undefined) => import("../lib/types").ValidationType<number>;
3
+ //# sourceMappingURL=number.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"number.d.ts","sourceRoot":"","sources":["../../src/validators/number.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGhD,eAAO,IAAI,MAAM,gGAkBhB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=number.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"number.test.d.ts","sourceRoot":"","sources":["../../src/validators/number.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,12 @@
1
+ import { ValidationType, ValidationTypeValue, ValidatorOptions } from '../lib/types';
2
+ type KeysWhichExtend<T, SelectedType> = {
3
+ [key in keyof T]: SelectedType extends T[key] ? key : never;
4
+ }[keyof T];
5
+ type Optional<T> = Partial<Pick<T, KeysWhichExtend<T, undefined>>>;
6
+ type Required<T> = Omit<T, KeysWhichExtend<T, undefined>>;
7
+ export type UndefinedIsOptional<T> = Optional<T> & Required<T>;
8
+ export declare let object: <Validator extends {
9
+ [key: string]: ValidationType<any>;
10
+ }>(shape: Validator, opts?: ValidatorOptions<Record<string, ValidationTypeValue<Validator>>>) => ValidationType<UndefinedIsOptional<{ [key in keyof Validator]: ValidationTypeValue<Validator[key]>; }>>;
11
+ export {};
12
+ //# sourceMappingURL=object.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"object.d.ts","sourceRoot":"","sources":["../../src/validators/object.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErF,KAAK,eAAe,CAAC,CAAC,EAAE,YAAY,IAAI;KACrC,GAAG,IAAI,MAAM,CAAC,GAAG,YAAY,SAAS,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,KAAK;CAC5D,CAAC,MAAM,CAAC,CAAC,CAAC;AACX,KAAK,QAAQ,CAAC,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;AACnE,KAAK,QAAQ,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;AAC1D,MAAM,MAAM,mBAAmB,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;AAE/D,eAAO,IAAI,MAAM,GAAI,SAAS,SAAS;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,CAAA;CAAE,EAC3E,OAAO,SAAS,EAChB,OAAO,gBAAgB,CAAC,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,SAAS,CAAC,CAAC,CAAC,KACtE,cAAc,CACf,mBAAmB,CAAC,GACjB,GAAG,IAAI,MAAM,SAAS,GAAG,mBAAmB,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAC9D,CAAC,CAiDF,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=object.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"object.test.d.ts","sourceRoot":"","sources":["../../src/validators/object.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import { ValidationType, ValidationTypeValue } from '../lib/types';
2
+ export declare let optional: <A extends ValidationType<any>>(validator: A) => ValidationType<ValidationTypeValue<A> | undefined>;
3
+ //# sourceMappingURL=optional.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"optional.d.ts","sourceRoot":"","sources":["../../src/validators/optional.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEnE,eAAO,IAAI,QAAQ,GAAI,CAAC,SAAS,cAAc,CAAC,GAAG,CAAC,EAClD,WAAW,CAAC,KACX,cAAc,CAAC,mBAAmB,CAAC,CAAC,CAAC,GAAG,SAAS,CAWlD,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=optional.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"optional.test.d.ts","sourceRoot":"","sources":["../../src/validators/optional.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import { ValidationType, ValidationTypeValue, ValidatorOptions } from '../lib/types';
2
+ export declare let record: <Validator extends ValidationType<any>>(validator: Validator, opts?: ValidatorOptions<Record<string, ValidationTypeValue<Validator>>>) => ValidationType<Record<string, ValidationTypeValue<Validator>>>;
3
+ //# sourceMappingURL=record.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record.d.ts","sourceRoot":"","sources":["../../src/validators/record.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErF,eAAO,IAAI,MAAM,GAAI,SAAS,SAAS,cAAc,CAAC,GAAG,CAAC,EACxD,WAAW,SAAS,EACpB,OAAO,gBAAgB,CAAC,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,SAAS,CAAC,CAAC,CAAC,KACtE,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,SAAS,CAAC,CAAC,CAiD9D,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=record.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record.test.d.ts","sourceRoot":"","sources":["../../src/validators/record.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import { ValidatorOptions } from '../lib/types';
2
+ export declare let string: (opts?: ValidatorOptions<string> | undefined) => import("../lib/types").ValidationType<string>;
3
+ //# sourceMappingURL=string.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"string.d.ts","sourceRoot":"","sources":["../../src/validators/string.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGhD,eAAO,IAAI,MAAM,gGAyBhB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=string.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"string.test.d.ts","sourceRoot":"","sources":["../../src/validators/string.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import { ValidationType, ValidationTypeValue, ValidatorOptions } from '../lib/types';
2
+ export declare let union: <A extends ValidationType<any>, B extends ValidationType<any>, Rest extends ValidationType<any>[]>(validators: [A, B, ...Rest], opts?: ValidatorOptions<ValidationTypeValue<A> | ValidationTypeValue<B> | ValidationTypeValue<Rest[number]>>) => ValidationType<ValidationTypeValue<A> | ValidationTypeValue<B> | ValidationTypeValue<Rest[number]>>;
3
+ //# sourceMappingURL=union.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"union.d.ts","sourceRoot":"","sources":["../../src/validators/union.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EACjB,MAAM,cAAc,CAAC;AAEtB,eAAO,IAAI,KAAK,GACd,CAAC,SAAS,cAAc,CAAC,GAAG,CAAC,EAC7B,CAAC,SAAS,cAAc,CAAC,GAAG,CAAC,EAC7B,IAAI,SAAS,cAAc,CAAC,GAAG,CAAC,EAAE,EAElC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,EAC3B,OAAO,gBAAgB,CACrB,mBAAmB,CAAC,CAAC,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,GAAG,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CACpF,KACA,cAAc,CACf,mBAAmB,CAAC,CAAC,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,GAAG,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAmBnF,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=union.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"union.test.d.ts","sourceRoot":"","sources":["../../src/validators/union.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import { ValidatorOptions } from '../lib/types';
2
+ export declare let voidType: (opts?: ValidatorOptions<void> | undefined) => import("../lib/types").ValidationType<void>;
3
+ //# sourceMappingURL=void.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"void.d.ts","sourceRoot":"","sources":["../../src/validators/void.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGhD,eAAO,IAAI,QAAQ,4FAEjB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@lowerdeck/validation",
3
+ "version": "1.0.0",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
7
+ "author": "Tobias Herber",
8
+ "license": "Apache 2",
9
+ "type": "module",
10
+ "source": "src/index.ts",
11
+ "exports": {
12
+ "require": "./dist/index.cjs",
13
+ "default": "./dist/index.modern.js"
14
+ },
15
+ "main": "./dist/index.cjs",
16
+ "module": "./dist/index.module.js",
17
+ "types": "dist/index.d.ts",
18
+ "unpkg": "./dist/index.umd.js",
19
+ "scripts": {
20
+ "test": "vitest run --passWithNoTests",
21
+ "lint": "prettier src/**/*.ts --check",
22
+ "build": "microbundle"
23
+ },
24
+ "dependencies": {},
25
+ "devDependencies": {
26
+ "microbundle": "^0.15.1",
27
+ "@lowerdeck/tsconfig": "^1.0.0",
28
+ "typescript": "^5.8.3",
29
+ "vitest": "^3.1.2"
30
+ }
31
+ }
package/src/index.ts ADDED
@@ -0,0 +1,33 @@
1
+ // export * from './lib/result';
2
+ // export * from './lib/validator';
3
+ // export * from './modifiers';
4
+ // export * from './transformers';
5
+ // export * from './validators';
6
+
7
+ export * from './lib/introspect';
8
+ export * from './lib/types';
9
+
10
+ import * as introspect from './lib/introspect';
11
+ import * as result from './lib/result';
12
+ import * as validator from './lib/validator';
13
+ import * as modifiers from './modifiers';
14
+ import * as transformers from './transformers';
15
+ import * as validators from './validators';
16
+
17
+ // export default {
18
+ // ...modifiers,
19
+ // ...introspect,
20
+ // ...transformers,
21
+ // ...validators,
22
+ // ...result,
23
+ // ...validator
24
+ // };
25
+
26
+ export let v = {
27
+ ...modifiers,
28
+ ...introspect,
29
+ ...transformers,
30
+ ...validators,
31
+ ...result,
32
+ ...validator
33
+ };
@@ -0,0 +1,33 @@
1
+ import { ValidationType } from './types';
2
+
3
+ export interface IntrospectedType {
4
+ examples: any[];
5
+ items?: IntrospectedType[];
6
+ properties?: Record<string, IntrospectedType>;
7
+ type: string;
8
+ name?: string;
9
+ description?: string;
10
+ optional: boolean;
11
+ nullable: boolean;
12
+ }
13
+
14
+ export let introspectType = (type: ValidationType<any>): IntrospectedType => ({
15
+ examples: type.examples ?? [],
16
+ items: type.items
17
+ ? Array.isArray(type.items)
18
+ ? type.items.map(introspectType)
19
+ : [introspectType(type.items)]
20
+ : undefined,
21
+ properties: type.properties
22
+ ? Object.fromEntries(
23
+ Object.entries(type.properties)
24
+ .filter(([_, v]) => !v.hidden)
25
+ .map(([key, value]) => [key, introspectType(value)])
26
+ )
27
+ : undefined,
28
+ type: type.type,
29
+ name: type.name,
30
+ description: type.description,
31
+ optional: !!type.optional,
32
+ nullable: !!type.nullable
33
+ });
@@ -0,0 +1,80 @@
1
+ import { describe, expect, test } from 'vitest';
2
+ import { error, success } from './result';
3
+
4
+ describe('Result', () => {
5
+ test('success should return a successful result', () => {
6
+ let s1 = success({
7
+ foo: 'bar'
8
+ });
9
+
10
+ expect(s1).toEqual({
11
+ success: true,
12
+ value: {
13
+ foo: 'bar'
14
+ }
15
+ });
16
+
17
+ let s2 = success(123);
18
+
19
+ expect(s2).toEqual({
20
+ success: true,
21
+ value: 123
22
+ });
23
+ });
24
+
25
+ test('error should return an error result', () => {
26
+ let e1 = error([
27
+ {
28
+ code: 'invalid_type',
29
+ message: 'Invalid type',
30
+ received: 'string',
31
+ expected: 'number'
32
+ }
33
+ ]);
34
+
35
+ expect(e1).toEqual({
36
+ success: false,
37
+ errors: [
38
+ {
39
+ code: 'invalid_type',
40
+ message: 'Invalid type',
41
+ received: 'string',
42
+ expected: 'number'
43
+ }
44
+ ]
45
+ });
46
+
47
+ let e2 = error([
48
+ {
49
+ code: 'invalid_type',
50
+ message: 'Invalid type',
51
+ received: 'string',
52
+ expected: 'number'
53
+ },
54
+ {
55
+ code: 'invalid_type',
56
+ message: 'Invalid type',
57
+ received: 'string',
58
+ expected: 'number'
59
+ }
60
+ ]);
61
+
62
+ expect(e2).toEqual({
63
+ success: false,
64
+ errors: [
65
+ {
66
+ code: 'invalid_type',
67
+ message: 'Invalid type',
68
+ received: 'string',
69
+ expected: 'number'
70
+ },
71
+ {
72
+ code: 'invalid_type',
73
+ message: 'Invalid type',
74
+ received: 'string',
75
+ expected: 'number'
76
+ }
77
+ ]
78
+ });
79
+ });
80
+ });
@@ -0,0 +1,11 @@
1
+ import { ValidationError, ValidationResult } from './types';
2
+
3
+ export let success = <T>(value: T): ValidationResult<T> => ({
4
+ success: true,
5
+ value
6
+ });
7
+
8
+ export let error = (errors: ValidationError[]): ValidationResult<any> => ({
9
+ success: false,
10
+ errors
11
+ });
@@ -0,0 +1,57 @@
1
+ export interface ValidationError {
2
+ code: string;
3
+ message: string;
4
+
5
+ expected?: any;
6
+ received?: any;
7
+
8
+ path?: string[];
9
+
10
+ min?: number;
11
+ max?: number;
12
+ positive?: boolean;
13
+ negative?: boolean;
14
+ }
15
+
16
+ export type ValidationResult<T> =
17
+ | {
18
+ success: true;
19
+ value: T;
20
+ }
21
+ | {
22
+ success: false;
23
+ errors: ValidationError[];
24
+ };
25
+
26
+ export type ValidationType<T> = {
27
+ validate: (value: any) => ValidationResult<T>;
28
+ examples?: T[];
29
+ items?: ValidationType<any> | ValidationType<any>[];
30
+ properties?: { [key: string]: ValidationType<any> };
31
+ type: string;
32
+ name?: string;
33
+ description?: string;
34
+ optional?: boolean;
35
+ nullable?: boolean;
36
+ hidden?: boolean;
37
+ };
38
+
39
+ export type ValidationTypeValue<T> = T extends ValidationType<infer U> ? U : never;
40
+
41
+ export type ValidationModifier<T> = (value: T) => ValidationError[];
42
+
43
+ export type Preprocessor = (value: any) => any;
44
+
45
+ export type Transformer<T> = (value: T) => T;
46
+
47
+ export interface ValidatorOptions<T> {
48
+ modifiers?: ValidationModifier<T>[];
49
+ transformers?: Transformer<T>[];
50
+ message?: string;
51
+ name?: string;
52
+ description?: string;
53
+ examples?: T[];
54
+ preprocessors?: Preprocessor[];
55
+ oneOf?: T[];
56
+ hidden?: boolean;
57
+ }
@@ -0,0 +1,82 @@
1
+ import { describe, expect, test } from 'vitest';
2
+ import { createValidator } from './validator';
3
+
4
+ describe('createValidator', () => {
5
+ test('should validate a string', () => {
6
+ let stringValidator = createValidator<string, any>('string', (opts, value) => {
7
+ if (typeof value !== 'string') {
8
+ return {
9
+ success: false,
10
+ errors: [{ code: 'invalid_type', message: 'Value must be a string' }]
11
+ };
12
+ }
13
+
14
+ if (opts.minLength && value.length < opts.minLength) {
15
+ return {
16
+ success: false,
17
+ errors: [
18
+ {
19
+ code: 'min_length',
20
+ message: `Value must be at least ${opts.minLength} characters long`
21
+ }
22
+ ]
23
+ };
24
+ }
25
+
26
+ return { success: true, value };
27
+ });
28
+
29
+ let result: any = stringValidator({ minLength: 5 }).validate('hello');
30
+ expect(result.success).toBe(true);
31
+ expect(result.value).toBe('hello');
32
+
33
+ let result2: any = stringValidator({ minLength: 5 }).validate('hi');
34
+ expect(result2.success).toBe(false);
35
+ expect(result2.errors).toEqual([
36
+ { code: 'min_length', message: 'Value must be at least 5 characters long' }
37
+ ]);
38
+ });
39
+
40
+ test('should validate a number', () => {
41
+ let numberValidator = createValidator<number, any>('number', (opts, value) => {
42
+ if (typeof value !== 'number') {
43
+ return {
44
+ success: false,
45
+ errors: [{ code: 'invalid_type', message: 'Value must be a number' }]
46
+ };
47
+ }
48
+
49
+ if (opts.min && value < opts.min) {
50
+ return {
51
+ success: false,
52
+ errors: [{ code: 'min_value', message: `Value must be at least ${opts.min}` }]
53
+ };
54
+ }
55
+
56
+ return { success: true, value };
57
+ });
58
+
59
+ let result: any = numberValidator({ min: 5 }).validate(10);
60
+ expect(result.success).toBe(true);
61
+ expect(result.value).toBe(10);
62
+
63
+ let result2: any = numberValidator({ min: 5 }).validate(3);
64
+ expect(result2.success).toBe(false);
65
+ expect(result2.errors).toEqual([
66
+ { code: 'min_value', message: 'Value must be at least 5' }
67
+ ]);
68
+ });
69
+
70
+ test('should handle throwing errors', () => {
71
+ let throwingValidator = createValidator<string, any>('throwing', () => {
72
+ throw new Error('Something went wrong');
73
+ });
74
+
75
+ let result: any = throwingValidator().validate('hello');
76
+
77
+ expect(result.success).toBe(false);
78
+ expect(result.errors).toEqual([
79
+ { code: 'invalid_type', message: 'Unable to validate value' }
80
+ ]);
81
+ });
82
+ });
@@ -0,0 +1,63 @@
1
+ import { error, success } from './result';
2
+ import {
3
+ Preprocessor,
4
+ Transformer,
5
+ ValidationError,
6
+ ValidationModifier,
7
+ ValidationResult,
8
+ ValidationType,
9
+ ValidatorOptions
10
+ } from './types';
11
+
12
+ let preprocess = (preprocessors: Preprocessor[], value: any) => {
13
+ return preprocessors.reduce((val, fn) => fn(val), value);
14
+ };
15
+
16
+ let modify = <T>(modifiers: ValidationModifier<T>[], value: T) => {
17
+ return modifiers.reduce((errors, fn) => errors.concat(fn(value)), [] as ValidationError[]);
18
+ };
19
+
20
+ let transform = <T>(transformers: Transformer<T>[], value: T) => {
21
+ return transformers.reduce((val, fn) => fn(val), value);
22
+ };
23
+
24
+ export let createValidator =
25
+ <Type, Opts extends ValidatorOptions<Type>>(
26
+ type: string,
27
+ handler: (opts: Opts, value: any) => ValidationResult<Type>
28
+ ) =>
29
+ (opts?: Opts): ValidationType<Type> => ({
30
+ validate: rawValue => {
31
+ try {
32
+ let value =
33
+ !opts?.preprocessors || !opts?.preprocessors.length
34
+ ? rawValue
35
+ : preprocess(opts?.preprocessors, rawValue);
36
+
37
+ let handlerRes = handler(opts ?? ({} as any), value);
38
+ if (!handlerRes.success) return handlerRes;
39
+
40
+ let modifierErrors =
41
+ !opts?.modifiers || !opts?.modifiers.length ? [] : modify(opts?.modifiers, value);
42
+ if (modifierErrors.length) return error(modifierErrors);
43
+
44
+ return success(
45
+ !opts?.transformers || !opts?.transformers.length
46
+ ? handlerRes.value
47
+ : transform(opts?.transformers, handlerRes.value)
48
+ );
49
+ } catch (err) {
50
+ return error([
51
+ {
52
+ code: 'invalid_type',
53
+ message: opts?.message ?? 'Unable to validate value'
54
+ }
55
+ ]);
56
+ }
57
+ },
58
+ examples: opts?.examples ?? [],
59
+ type,
60
+ name: opts?.name,
61
+ description: opts?.description,
62
+ hidden: !!opts?.hidden
63
+ });
@@ -0,0 +1,29 @@
1
+ import { describe, expect, test } from 'vitest';
2
+ import { color } from './color';
3
+
4
+ describe('color', () => {
5
+ test('returns an empty array for a valid color', () => {
6
+ let result = color()('#FF0000');
7
+ expect(result).toEqual([]);
8
+ });
9
+
10
+ test('returns an error object for an invalid color', () => {
11
+ let result = color()('not_a_color');
12
+ expect(result).toEqual([
13
+ {
14
+ code: 'invalid_color',
15
+ message: 'Invalid color'
16
+ }
17
+ ]);
18
+ });
19
+
20
+ test('returns a custom error message if provided', () => {
21
+ let result = color({ message: 'Custom error message' })('not_a_color');
22
+ expect(result).toEqual([
23
+ {
24
+ code: 'invalid_color',
25
+ message: 'Custom error message'
26
+ }
27
+ ]);
28
+ });
29
+ });
@@ -0,0 +1,18 @@
1
+ import { ValidationModifier } from '../lib/types';
2
+
3
+ let colorRegex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;
4
+
5
+ export let color =
6
+ (opts?: { message?: string }): ValidationModifier<string> =>
7
+ value => {
8
+ if (!colorRegex.test(value)) {
9
+ return [
10
+ {
11
+ code: 'invalid_color',
12
+ message: opts?.message ?? 'Invalid color'
13
+ }
14
+ ];
15
+ }
16
+
17
+ return [];
18
+ };
@@ -0,0 +1,29 @@
1
+ import { describe, expect, test } from 'vitest';
2
+ import { email } from './email';
3
+
4
+ describe('email', () => {
5
+ test('returns an empty array for a valid email address', () => {
6
+ let result = email()('test@example.com');
7
+ expect(result).toEqual([]);
8
+ });
9
+
10
+ test('returns an error object for an invalid email address', () => {
11
+ let result = email()('not_an_email');
12
+ expect(result).toEqual([
13
+ {
14
+ code: 'invalid_email',
15
+ message: 'Invalid email address'
16
+ }
17
+ ]);
18
+ });
19
+
20
+ test('returns a custom error message if provided', () => {
21
+ let result = email({ message: 'Custom error message' })('not_an_email');
22
+ expect(result).toEqual([
23
+ {
24
+ code: 'invalid_email',
25
+ message: 'Custom error message'
26
+ }
27
+ ]);
28
+ });
29
+ });
@@ -0,0 +1,18 @@
1
+ import { ValidationModifier } from '../lib/types';
2
+
3
+ let emailRegex = /^[\w+-]+(?:\.[\w+-]+)*@[A-Z0-9]+(?:(?:\.|-)[A-Z0-9]+)*\.[A-Z]{2,}$/i;
4
+
5
+ export let email =
6
+ (opts?: { message?: string }): ValidationModifier<string> =>
7
+ value => {
8
+ if (!emailRegex.test(value)) {
9
+ return [
10
+ {
11
+ code: 'invalid_email',
12
+ message: opts?.message ?? 'Invalid email address'
13
+ }
14
+ ];
15
+ }
16
+
17
+ return [];
18
+ };