@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.
- package/.turbo/turbo-build.log +11 -0
- package/.turbo/turbo-test.log +144 -0
- package/README.md +158 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +119 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.modern.js +2 -0
- package/dist/index.modern.js.map +1 -0
- package/dist/index.module.js +2 -0
- package/dist/index.module.js.map +1 -0
- package/dist/index.umd.js +2 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/lib/introspect.d.ts +13 -0
- package/dist/lib/introspect.d.ts.map +1 -0
- package/dist/lib/result.d.ts +4 -0
- package/dist/lib/result.d.ts.map +1 -0
- package/dist/lib/result.test.d.ts +2 -0
- package/dist/lib/result.test.d.ts.map +1 -0
- package/dist/lib/types.d.ts +48 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/validator.d.ts +3 -0
- package/dist/lib/validator.d.ts.map +1 -0
- package/dist/lib/validator.test.d.ts +2 -0
- package/dist/lib/validator.test.d.ts.map +1 -0
- package/dist/modifiers/color.d.ts +5 -0
- package/dist/modifiers/color.d.ts.map +1 -0
- package/dist/modifiers/color.test.d.ts +2 -0
- package/dist/modifiers/color.test.d.ts.map +1 -0
- package/dist/modifiers/email.d.ts +5 -0
- package/dist/modifiers/email.d.ts.map +1 -0
- package/dist/modifiers/email.test.d.ts +2 -0
- package/dist/modifiers/email.test.d.ts.map +1 -0
- package/dist/modifiers/emoji.d.ts +5 -0
- package/dist/modifiers/emoji.d.ts.map +1 -0
- package/dist/modifiers/emoji.test.d.ts +2 -0
- package/dist/modifiers/emoji.test.d.ts.map +1 -0
- package/dist/modifiers/endsWith.d.ts +5 -0
- package/dist/modifiers/endsWith.d.ts.map +1 -0
- package/dist/modifiers/endsWith.test.d.ts +2 -0
- package/dist/modifiers/endsWith.test.d.ts.map +1 -0
- package/dist/modifiers/equals.d.ts +8 -0
- package/dist/modifiers/equals.d.ts.map +1 -0
- package/dist/modifiers/equals.test.d.ts +2 -0
- package/dist/modifiers/equals.test.d.ts.map +1 -0
- package/dist/modifiers/includes.d.ts +8 -0
- package/dist/modifiers/includes.d.ts.map +1 -0
- package/dist/modifiers/includes.test.d.ts +2 -0
- package/dist/modifiers/includes.test.d.ts.map +1 -0
- package/dist/modifiers/index.d.ts +18 -0
- package/dist/modifiers/index.d.ts.map +1 -0
- package/dist/modifiers/integer.d.ts +5 -0
- package/dist/modifiers/integer.d.ts.map +1 -0
- package/dist/modifiers/integer.test.d.ts +2 -0
- package/dist/modifiers/integer.test.d.ts.map +1 -0
- package/dist/modifiers/ip.d.ts +11 -0
- package/dist/modifiers/ip.d.ts.map +1 -0
- package/dist/modifiers/ip.test.d.ts +2 -0
- package/dist/modifiers/ip.test.d.ts.map +1 -0
- package/dist/modifiers/isoDate.d.ts +11 -0
- package/dist/modifiers/isoDate.d.ts.map +1 -0
- package/dist/modifiers/isoDate.test.d.ts +2 -0
- package/dist/modifiers/isoDate.test.d.ts.map +1 -0
- package/dist/modifiers/length.d.ts +9 -0
- package/dist/modifiers/length.d.ts.map +1 -0
- package/dist/modifiers/length.test.d.ts +2 -0
- package/dist/modifiers/length.test.d.ts.map +1 -0
- package/dist/modifiers/multipleOf.d.ts +5 -0
- package/dist/modifiers/multipleOf.d.ts.map +1 -0
- package/dist/modifiers/multipleOf.test.d.ts +2 -0
- package/dist/modifiers/multipleOf.test.d.ts.map +1 -0
- package/dist/modifiers/oneOf.d.ts +5 -0
- package/dist/modifiers/oneOf.d.ts.map +1 -0
- package/dist/modifiers/oneOf.test.d.ts +2 -0
- package/dist/modifiers/oneOf.test.d.ts.map +1 -0
- package/dist/modifiers/positive.d.ts +8 -0
- package/dist/modifiers/positive.d.ts.map +1 -0
- package/dist/modifiers/positive.test.d.ts +2 -0
- package/dist/modifiers/positive.test.d.ts.map +1 -0
- package/dist/modifiers/regex.d.ts +5 -0
- package/dist/modifiers/regex.d.ts.map +1 -0
- package/dist/modifiers/regex.test.d.ts +2 -0
- package/dist/modifiers/regex.test.d.ts.map +1 -0
- package/dist/modifiers/size.d.ts +8 -0
- package/dist/modifiers/size.d.ts.map +1 -0
- package/dist/modifiers/size.test.d.ts +2 -0
- package/dist/modifiers/size.test.d.ts.map +1 -0
- package/dist/modifiers/startsWith.d.ts +5 -0
- package/dist/modifiers/startsWith.d.ts.map +1 -0
- package/dist/modifiers/startsWith.test.d.ts +2 -0
- package/dist/modifiers/startsWith.test.d.ts.map +1 -0
- package/dist/modifiers/url.d.ts +6 -0
- package/dist/modifiers/url.d.ts.map +1 -0
- package/dist/modifiers/url.test.d.ts +2 -0
- package/dist/modifiers/url.test.d.ts.map +1 -0
- package/dist/transformers/case.d.ts +4 -0
- package/dist/transformers/case.d.ts.map +1 -0
- package/dist/transformers/case.test.d.ts +2 -0
- package/dist/transformers/case.test.d.ts.map +1 -0
- package/dist/transformers/index.d.ts +3 -0
- package/dist/transformers/index.d.ts.map +1 -0
- package/dist/transformers/trim.d.ts +5 -0
- package/dist/transformers/trim.d.ts.map +1 -0
- package/dist/transformers/trim.test.d.ts +2 -0
- package/dist/transformers/trim.test.d.ts.map +1 -0
- package/dist/validators/any.d.ts +4 -0
- package/dist/validators/any.d.ts.map +1 -0
- package/dist/validators/any.test.d.ts +2 -0
- package/dist/validators/any.test.d.ts.map +1 -0
- package/dist/validators/array.d.ts +3 -0
- package/dist/validators/array.d.ts.map +1 -0
- package/dist/validators/array.test.d.ts +2 -0
- package/dist/validators/array.test.d.ts.map +1 -0
- package/dist/validators/boolean.d.ts +3 -0
- package/dist/validators/boolean.d.ts.map +1 -0
- package/dist/validators/boolean.test.d.ts +2 -0
- package/dist/validators/boolean.test.d.ts.map +1 -0
- package/dist/validators/date.d.ts +3 -0
- package/dist/validators/date.d.ts.map +1 -0
- package/dist/validators/date.test.d.ts +2 -0
- package/dist/validators/date.test.d.ts.map +1 -0
- package/dist/validators/enum.d.ts +6 -0
- package/dist/validators/enum.d.ts.map +1 -0
- package/dist/validators/enum.test.d.ts +2 -0
- package/dist/validators/enum.test.d.ts.map +1 -0
- package/dist/validators/index.d.ts +17 -0
- package/dist/validators/index.d.ts.map +1 -0
- package/dist/validators/intersection.d.ts +3 -0
- package/dist/validators/intersection.d.ts.map +1 -0
- package/dist/validators/intersection.test.d.ts +2 -0
- package/dist/validators/intersection.test.d.ts.map +1 -0
- package/dist/validators/literal.d.ts +3 -0
- package/dist/validators/literal.d.ts.map +1 -0
- package/dist/validators/literal.test.d.ts +2 -0
- package/dist/validators/literal.test.d.ts.map +1 -0
- package/dist/validators/null.d.ts +3 -0
- package/dist/validators/null.d.ts.map +1 -0
- package/dist/validators/null.test.d.ts +2 -0
- package/dist/validators/null.test.d.ts.map +1 -0
- package/dist/validators/nullable.d.ts +3 -0
- package/dist/validators/nullable.d.ts.map +1 -0
- package/dist/validators/nullable.test.d.ts +2 -0
- package/dist/validators/nullable.test.d.ts.map +1 -0
- package/dist/validators/number.d.ts +3 -0
- package/dist/validators/number.d.ts.map +1 -0
- package/dist/validators/number.test.d.ts +2 -0
- package/dist/validators/number.test.d.ts.map +1 -0
- package/dist/validators/object.d.ts +12 -0
- package/dist/validators/object.d.ts.map +1 -0
- package/dist/validators/object.test.d.ts +2 -0
- package/dist/validators/object.test.d.ts.map +1 -0
- package/dist/validators/optional.d.ts +3 -0
- package/dist/validators/optional.d.ts.map +1 -0
- package/dist/validators/optional.test.d.ts +2 -0
- package/dist/validators/optional.test.d.ts.map +1 -0
- package/dist/validators/record.d.ts +3 -0
- package/dist/validators/record.d.ts.map +1 -0
- package/dist/validators/record.test.d.ts +2 -0
- package/dist/validators/record.test.d.ts.map +1 -0
- package/dist/validators/string.d.ts +3 -0
- package/dist/validators/string.d.ts.map +1 -0
- package/dist/validators/string.test.d.ts +2 -0
- package/dist/validators/string.test.d.ts.map +1 -0
- package/dist/validators/union.d.ts +3 -0
- package/dist/validators/union.d.ts.map +1 -0
- package/dist/validators/union.test.d.ts +2 -0
- package/dist/validators/union.test.d.ts.map +1 -0
- package/dist/validators/void.d.ts +3 -0
- package/dist/validators/void.d.ts.map +1 -0
- package/package.json +31 -0
- package/src/index.ts +33 -0
- package/src/lib/introspect.ts +33 -0
- package/src/lib/result.test.ts +80 -0
- package/src/lib/result.ts +11 -0
- package/src/lib/types.ts +57 -0
- package/src/lib/validator.test.ts +82 -0
- package/src/lib/validator.ts +63 -0
- package/src/modifiers/color.test.ts +29 -0
- package/src/modifiers/color.ts +18 -0
- package/src/modifiers/email.test.ts +29 -0
- package/src/modifiers/email.ts +18 -0
- package/src/modifiers/emoji.test.ts +31 -0
- package/src/modifiers/emoji.ts +18 -0
- package/src/modifiers/endsWith.test.ts +50 -0
- package/src/modifiers/endsWith.ts +18 -0
- package/src/modifiers/equals.test.ts +70 -0
- package/src/modifiers/equals.ts +41 -0
- package/src/modifiers/includes.test.ts +64 -0
- package/src/modifiers/includes.ts +35 -0
- package/src/modifiers/index.ts +17 -0
- package/src/modifiers/integer.test.ts +45 -0
- package/src/modifiers/integer.ts +18 -0
- package/src/modifiers/ip.test.ts +34 -0
- package/src/modifiers/ip.ts +50 -0
- package/src/modifiers/isoDate.test.ts +83 -0
- package/src/modifiers/isoDate.ts +51 -0
- package/src/modifiers/length.test.ts +107 -0
- package/src/modifiers/length.ts +54 -0
- package/src/modifiers/multipleOf.test.ts +51 -0
- package/src/modifiers/multipleOf.ts +18 -0
- package/src/modifiers/oneOf.test.ts +27 -0
- package/src/modifiers/oneOf.ts +16 -0
- package/src/modifiers/positive.test.ts +64 -0
- package/src/modifiers/positive.ts +35 -0
- package/src/modifiers/regex.test.ts +40 -0
- package/src/modifiers/regex.ts +17 -0
- package/src/modifiers/size.test.ts +84 -0
- package/src/modifiers/size.ts +37 -0
- package/src/modifiers/startsWith.test.ts +40 -0
- package/src/modifiers/startsWith.ts +18 -0
- package/src/modifiers/url.test.ts +48 -0
- package/src/modifiers/url.ts +30 -0
- package/src/transformers/case.test.ts +36 -0
- package/src/transformers/case.ts +5 -0
- package/src/transformers/index.ts +2 -0
- package/src/transformers/trim.test.ts +32 -0
- package/src/transformers/trim.ts +7 -0
- package/src/validators/any.test.ts +11 -0
- package/src/validators/any.ts +11 -0
- package/src/validators/array.test.ts +46 -0
- package/src/validators/array.ts +43 -0
- package/src/validators/boolean.test.ts +39 -0
- package/src/validators/boolean.ts +34 -0
- package/src/validators/date.test.ts +39 -0
- package/src/validators/date.ts +26 -0
- package/src/validators/enum.test.ts +25 -0
- package/src/validators/enum.ts +56 -0
- package/src/validators/index.ts +16 -0
- package/src/validators/intersection.test.ts +35 -0
- package/src/validators/intersection.ts +24 -0
- package/src/validators/literal.test.ts +42 -0
- package/src/validators/literal.ts +26 -0
- package/src/validators/null.test.ts +39 -0
- package/src/validators/null.ts +18 -0
- package/src/validators/nullable.test.ts +34 -0
- package/src/validators/nullable.ts +16 -0
- package/src/validators/number.test.ts +39 -0
- package/src/validators/number.ts +23 -0
- package/src/validators/object.test.ts +66 -0
- package/src/validators/object.ts +66 -0
- package/src/validators/optional.test.ts +33 -0
- package/src/validators/optional.ts +16 -0
- package/src/validators/record.test.ts +56 -0
- package/src/validators/record.ts +56 -0
- package/src/validators/string.test.ts +39 -0
- package/src/validators/string.ts +30 -0
- package/src/validators/union.test.ts +73 -0
- package/src/validators/union.ts +38 -0
- package/src/validators/void.ts +6 -0
- 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 @@
|
|
|
1
|
+
{"version":3,"file":"null.test.d.ts","sourceRoot":"","sources":["../../src/validators/null.test.ts"],"names":[],"mappings":""}
|
|
@@ -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 @@
|
|
|
1
|
+
{"version":3,"file":"nullable.test.d.ts","sourceRoot":"","sources":["../../src/validators/nullable.test.ts"],"names":[],"mappings":""}
|
|
@@ -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 @@
|
|
|
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 @@
|
|
|
1
|
+
{"version":3,"file":"object.test.d.ts","sourceRoot":"","sources":["../../src/validators/object.test.ts"],"names":[],"mappings":""}
|
|
@@ -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 @@
|
|
|
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 @@
|
|
|
1
|
+
{"version":3,"file":"record.test.d.ts","sourceRoot":"","sources":["../../src/validators/record.test.ts"],"names":[],"mappings":""}
|
|
@@ -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 @@
|
|
|
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 @@
|
|
|
1
|
+
{"version":3,"file":"union.test.d.ts","sourceRoot":"","sources":["../../src/validators/union.test.ts"],"names":[],"mappings":""}
|
|
@@ -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
|
+
});
|
package/src/lib/types.ts
ADDED
|
@@ -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
|
+
};
|