anyvali 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +44 -0
- package/README.md +370 -0
- package/VERSION +1 -0
- package/dist/errors.d.ts +6 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +12 -0
- package/dist/errors.js.map +1 -0
- package/dist/format/validators.d.ts +2 -0
- package/dist/format/validators.d.ts.map +1 -0
- package/dist/format/validators.js +57 -0
- package/dist/format/validators.js.map +1 -0
- package/dist/forms/index.d.ts +57 -0
- package/dist/forms/index.d.ts.map +1 -0
- package/dist/forms/index.js +586 -0
- package/dist/forms/index.js.map +1 -0
- package/dist/index.d.ts +93 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +156 -0
- package/dist/index.js.map +1 -0
- package/dist/infer.d.ts +8 -0
- package/dist/infer.d.ts.map +1 -0
- package/dist/infer.js +2 -0
- package/dist/infer.js.map +1 -0
- package/dist/interchange/document.d.ts +5 -0
- package/dist/interchange/document.d.ts.map +1 -0
- package/dist/interchange/document.js +12 -0
- package/dist/interchange/document.js.map +1 -0
- package/dist/interchange/exporter.d.ts +7 -0
- package/dist/interchange/exporter.d.ts.map +1 -0
- package/dist/interchange/exporter.js +7 -0
- package/dist/interchange/exporter.js.map +1 -0
- package/dist/interchange/importer.d.ts +4 -0
- package/dist/interchange/importer.d.ts.map +1 -0
- package/dist/interchange/importer.js +229 -0
- package/dist/interchange/importer.js.map +1 -0
- package/dist/issue-codes.d.ts +19 -0
- package/dist/issue-codes.d.ts.map +1 -0
- package/dist/issue-codes.js +18 -0
- package/dist/issue-codes.js.map +1 -0
- package/dist/parse/coerce.d.ts +16 -0
- package/dist/parse/coerce.d.ts.map +1 -0
- package/dist/parse/coerce.js +115 -0
- package/dist/parse/coerce.js.map +1 -0
- package/dist/parse/defaults.d.ts +7 -0
- package/dist/parse/defaults.d.ts.map +1 -0
- package/dist/parse/defaults.js +12 -0
- package/dist/parse/defaults.js.map +1 -0
- package/dist/parse/parser.d.ts +11 -0
- package/dist/parse/parser.d.ts.map +1 -0
- package/dist/parse/parser.js +13 -0
- package/dist/parse/parser.js.map +1 -0
- package/dist/schemas/any.d.ts +7 -0
- package/dist/schemas/any.d.ts.map +1 -0
- package/dist/schemas/any.js +12 -0
- package/dist/schemas/any.js.map +1 -0
- package/dist/schemas/array.d.ts +13 -0
- package/dist/schemas/array.d.ts.map +1 -0
- package/dist/schemas/array.js +73 -0
- package/dist/schemas/array.js.map +1 -0
- package/dist/schemas/base.d.ts +37 -0
- package/dist/schemas/base.d.ts.map +1 -0
- package/dist/schemas/base.js +285 -0
- package/dist/schemas/base.js.map +1 -0
- package/dist/schemas/bool.d.ts +8 -0
- package/dist/schemas/bool.d.ts.map +1 -0
- package/dist/schemas/bool.js +27 -0
- package/dist/schemas/bool.js.map +1 -0
- package/dist/schemas/enum.d.ts +9 -0
- package/dist/schemas/enum.d.ts.map +1 -0
- package/dist/schemas/enum.js +31 -0
- package/dist/schemas/enum.js.map +1 -0
- package/dist/schemas/index.d.ts +21 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +21 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/int.d.ts +32 -0
- package/dist/schemas/int.d.ts.map +1 -0
- package/dist/schemas/int.js +108 -0
- package/dist/schemas/int.js.map +1 -0
- package/dist/schemas/intersection.d.ts +16 -0
- package/dist/schemas/intersection.d.ts.map +1 -0
- package/dist/schemas/intersection.js +58 -0
- package/dist/schemas/intersection.js.map +1 -0
- package/dist/schemas/literal.d.ts +11 -0
- package/dist/schemas/literal.d.ts.map +1 -0
- package/dist/schemas/literal.js +28 -0
- package/dist/schemas/literal.js.map +1 -0
- package/dist/schemas/never.d.ts +7 -0
- package/dist/schemas/never.d.ts.map +1 -0
- package/dist/schemas/never.js +19 -0
- package/dist/schemas/never.js.map +1 -0
- package/dist/schemas/null.d.ts +7 -0
- package/dist/schemas/null.d.ts.map +1 -0
- package/dist/schemas/null.js +24 -0
- package/dist/schemas/null.js.map +1 -0
- package/dist/schemas/nullable.d.ts +10 -0
- package/dist/schemas/nullable.d.ts.map +1 -0
- package/dist/schemas/nullable.js +29 -0
- package/dist/schemas/nullable.js.map +1 -0
- package/dist/schemas/number.d.ts +27 -0
- package/dist/schemas/number.d.ts.map +1 -0
- package/dist/schemas/number.js +134 -0
- package/dist/schemas/number.js.map +1 -0
- package/dist/schemas/object.d.ts +28 -0
- package/dist/schemas/object.d.ts.map +1 -0
- package/dist/schemas/object.js +153 -0
- package/dist/schemas/object.js.map +1 -0
- package/dist/schemas/optional.d.ts +11 -0
- package/dist/schemas/optional.d.ts.map +1 -0
- package/dist/schemas/optional.js +39 -0
- package/dist/schemas/optional.js.map +1 -0
- package/dist/schemas/record.d.ts +9 -0
- package/dist/schemas/record.d.ts.map +1 -0
- package/dist/schemas/record.js +45 -0
- package/dist/schemas/record.js.map +1 -0
- package/dist/schemas/ref.d.ts +10 -0
- package/dist/schemas/ref.d.ts.map +1 -0
- package/dist/schemas/ref.js +30 -0
- package/dist/schemas/ref.js.map +1 -0
- package/dist/schemas/string.d.ts +29 -0
- package/dist/schemas/string.d.ts.map +1 -0
- package/dist/schemas/string.js +181 -0
- package/dist/schemas/string.js.map +1 -0
- package/dist/schemas/tuple.d.ts +14 -0
- package/dist/schemas/tuple.d.ts.map +1 -0
- package/dist/schemas/tuple.js +59 -0
- package/dist/schemas/tuple.js.map +1 -0
- package/dist/schemas/union.d.ts +9 -0
- package/dist/schemas/union.d.ts.map +1 -0
- package/dist/schemas/union.js +45 -0
- package/dist/schemas/union.js.map +1 -0
- package/dist/schemas/unknown.d.ts +7 -0
- package/dist/schemas/unknown.d.ts.map +1 -0
- package/dist/schemas/unknown.js +12 -0
- package/dist/schemas/unknown.js.map +1 -0
- package/dist/types.d.ts +132 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/util.d.ts +6 -0
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +12 -0
- package/dist/util.js.map +1 -0
- package/package.json +41 -0
- package/sdk/js/CHANGELOG.md +13 -0
- package/src/errors.ts +17 -0
- package/src/format/validators.ts +71 -0
- package/src/forms/index.ts +789 -0
- package/src/index.ts +285 -0
- package/src/infer.ts +12 -0
- package/src/interchange/document.ts +18 -0
- package/src/interchange/exporter.ts +12 -0
- package/src/interchange/importer.ts +285 -0
- package/src/issue-codes.ts +19 -0
- package/src/parse/coerce.ts +133 -0
- package/src/parse/defaults.ts +15 -0
- package/src/parse/parser.ts +19 -0
- package/src/schemas/any.ts +14 -0
- package/src/schemas/array.ts +83 -0
- package/src/schemas/base.ts +322 -0
- package/src/schemas/bool.ts +30 -0
- package/src/schemas/enum.ts +37 -0
- package/src/schemas/index.ts +30 -0
- package/src/schemas/int.ts +129 -0
- package/src/schemas/intersection.ts +81 -0
- package/src/schemas/literal.ts +34 -0
- package/src/schemas/never.ts +21 -0
- package/src/schemas/null.ts +26 -0
- package/src/schemas/nullable.ts +36 -0
- package/src/schemas/number.ts +151 -0
- package/src/schemas/object.ts +203 -0
- package/src/schemas/optional.ts +49 -0
- package/src/schemas/record.ts +55 -0
- package/src/schemas/ref.ts +35 -0
- package/src/schemas/string.ts +192 -0
- package/src/schemas/tuple.ts +74 -0
- package/src/schemas/union.ts +53 -0
- package/src/schemas/unknown.ts +14 -0
- package/src/types.ts +239 -0
- package/src/util.ts +9 -0
- package/tests/conformance/runner.test.ts +28 -0
- package/tests/conformance/runner.ts +137 -0
- package/tests/forms.test.ts +146 -0
- package/tests/unit/coerce.test.ts +136 -0
- package/tests/unit/collections.test.ts +99 -0
- package/tests/unit/composition.test.ts +80 -0
- package/tests/unit/date-format.test.ts +18 -0
- package/tests/unit/default-mutation.test.ts +32 -0
- package/tests/unit/defaults.test.ts +49 -0
- package/tests/unit/errors.test.ts +53 -0
- package/tests/unit/export.test.ts +270 -0
- package/tests/unit/inference.test.ts +306 -0
- package/tests/unit/interchange.test.ts +191 -0
- package/tests/unit/number.test.ts +195 -0
- package/tests/unit/object.test.ts +208 -0
- package/tests/unit/parser.test.ts +151 -0
- package/tests/unit/primitives.test.ts +111 -0
- package/tests/unit/security-recursion.test.ts +105 -0
- package/tests/unit/security.test.ts +945 -0
- package/tests/unit/shared-ref-falsepos.test.ts +33 -0
- package/tests/unit/string-pattern-redos.test.ts +46 -0
- package/tests/unit/string.test.ts +147 -0
- package/tsconfig.json +21 -0
- package/vitest.config.ts +7 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
export type SchemaKind = "any" | "unknown" | "never" | "null" | "bool" | "string" | "number" | "int" | "float32" | "float64" | "int8" | "int16" | "int32" | "int64" | "uint8" | "uint16" | "uint32" | "uint64" | "literal" | "enum" | "array" | "tuple" | "object" | "record" | "union" | "intersection" | "optional" | "nullable" | "ref";
|
|
2
|
+
export interface MetadataOptions {
|
|
3
|
+
replace?: boolean;
|
|
4
|
+
}
|
|
5
|
+
export interface DescribeOptions {
|
|
6
|
+
title?: string;
|
|
7
|
+
deprecated?: boolean;
|
|
8
|
+
deprecatedMessage?: string;
|
|
9
|
+
notStable?: boolean;
|
|
10
|
+
since?: string;
|
|
11
|
+
sensitive?: boolean;
|
|
12
|
+
readonly?: boolean;
|
|
13
|
+
writeonly?: boolean;
|
|
14
|
+
examples?: unknown[];
|
|
15
|
+
}
|
|
16
|
+
export interface SchemaNodeBase {
|
|
17
|
+
kind: SchemaKind;
|
|
18
|
+
default?: unknown;
|
|
19
|
+
coerce?: CoercionConfig | string | string[];
|
|
20
|
+
metadata?: Record<string, unknown>;
|
|
21
|
+
}
|
|
22
|
+
export interface CoercionConfig {
|
|
23
|
+
from?: string;
|
|
24
|
+
trim?: boolean;
|
|
25
|
+
lower?: boolean;
|
|
26
|
+
upper?: boolean;
|
|
27
|
+
}
|
|
28
|
+
export interface StringSchemaNode extends SchemaNodeBase {
|
|
29
|
+
kind: "string";
|
|
30
|
+
minLength?: number;
|
|
31
|
+
maxLength?: number;
|
|
32
|
+
pattern?: string;
|
|
33
|
+
startsWith?: string;
|
|
34
|
+
endsWith?: string;
|
|
35
|
+
includes?: string;
|
|
36
|
+
format?: StringFormat;
|
|
37
|
+
}
|
|
38
|
+
export type StringFormat = "email" | "url" | "uuid" | "ipv4" | "ipv6" | "date" | "date-time";
|
|
39
|
+
export interface NumericSchemaNode extends SchemaNodeBase {
|
|
40
|
+
kind: "number" | "int" | "float32" | "float64" | "int8" | "int16" | "int32" | "int64" | "uint8" | "uint16" | "uint32" | "uint64";
|
|
41
|
+
min?: number;
|
|
42
|
+
max?: number;
|
|
43
|
+
exclusiveMin?: number;
|
|
44
|
+
exclusiveMax?: number;
|
|
45
|
+
multipleOf?: number;
|
|
46
|
+
}
|
|
47
|
+
export interface SimpleSchemaNode extends SchemaNodeBase {
|
|
48
|
+
kind: "any" | "unknown" | "never" | "null" | "bool";
|
|
49
|
+
}
|
|
50
|
+
export interface LiteralSchemaNode extends SchemaNodeBase {
|
|
51
|
+
kind: "literal";
|
|
52
|
+
value: string | number | boolean | null;
|
|
53
|
+
}
|
|
54
|
+
export interface EnumSchemaNode extends SchemaNodeBase {
|
|
55
|
+
kind: "enum";
|
|
56
|
+
values: (string | number)[];
|
|
57
|
+
}
|
|
58
|
+
export interface ArraySchemaNode extends SchemaNodeBase {
|
|
59
|
+
kind: "array";
|
|
60
|
+
items: SchemaNode;
|
|
61
|
+
minItems?: number;
|
|
62
|
+
maxItems?: number;
|
|
63
|
+
}
|
|
64
|
+
export interface TupleSchemaNode extends SchemaNodeBase {
|
|
65
|
+
kind: "tuple";
|
|
66
|
+
items: SchemaNode[];
|
|
67
|
+
}
|
|
68
|
+
export interface ObjectSchemaNode extends SchemaNodeBase {
|
|
69
|
+
kind: "object";
|
|
70
|
+
properties: Record<string, SchemaNode>;
|
|
71
|
+
required: string[];
|
|
72
|
+
unknownKeys?: UnknownKeyMode;
|
|
73
|
+
}
|
|
74
|
+
export interface RecordSchemaNode extends SchemaNodeBase {
|
|
75
|
+
kind: "record";
|
|
76
|
+
valueSchema: SchemaNode;
|
|
77
|
+
}
|
|
78
|
+
export interface UnionSchemaNode extends SchemaNodeBase {
|
|
79
|
+
kind: "union";
|
|
80
|
+
variants: SchemaNode[];
|
|
81
|
+
}
|
|
82
|
+
export interface IntersectionSchemaNode extends SchemaNodeBase {
|
|
83
|
+
kind: "intersection";
|
|
84
|
+
allOf: SchemaNode[];
|
|
85
|
+
}
|
|
86
|
+
export interface OptionalSchemaNode extends SchemaNodeBase {
|
|
87
|
+
kind: "optional";
|
|
88
|
+
inner: SchemaNode;
|
|
89
|
+
}
|
|
90
|
+
export interface NullableSchemaNode extends SchemaNodeBase {
|
|
91
|
+
kind: "nullable";
|
|
92
|
+
inner: SchemaNode;
|
|
93
|
+
}
|
|
94
|
+
export interface RefSchemaNode extends SchemaNodeBase {
|
|
95
|
+
kind: "ref";
|
|
96
|
+
ref: string;
|
|
97
|
+
}
|
|
98
|
+
export type SchemaNode = StringSchemaNode | NumericSchemaNode | SimpleSchemaNode | LiteralSchemaNode | EnumSchemaNode | ArraySchemaNode | TupleSchemaNode | ObjectSchemaNode | RecordSchemaNode | UnionSchemaNode | IntersectionSchemaNode | OptionalSchemaNode | NullableSchemaNode | RefSchemaNode;
|
|
99
|
+
export type ParseResult<T> = {
|
|
100
|
+
success: true;
|
|
101
|
+
data: T;
|
|
102
|
+
} | {
|
|
103
|
+
success: false;
|
|
104
|
+
issues: ValidationIssue[];
|
|
105
|
+
};
|
|
106
|
+
export interface ValidationIssue {
|
|
107
|
+
code: string;
|
|
108
|
+
message: string;
|
|
109
|
+
path: (string | number)[];
|
|
110
|
+
expected?: string;
|
|
111
|
+
received?: string;
|
|
112
|
+
meta?: Record<string, unknown>;
|
|
113
|
+
}
|
|
114
|
+
export interface AnyValiDocument {
|
|
115
|
+
anyvaliVersion: string;
|
|
116
|
+
schemaVersion: string;
|
|
117
|
+
root: SchemaNode;
|
|
118
|
+
definitions: Record<string, SchemaNode>;
|
|
119
|
+
extensions: Record<string, Record<string, unknown>>;
|
|
120
|
+
}
|
|
121
|
+
export type ExportMode = "portable" | "extended";
|
|
122
|
+
export type UnknownKeyMode = "reject" | "strip" | "allow";
|
|
123
|
+
export interface ParseContext {
|
|
124
|
+
path: (string | number)[];
|
|
125
|
+
issues: ValidationIssue[];
|
|
126
|
+
definitions?: Record<string, SchemaNode>;
|
|
127
|
+
/** Tracks objects already being validated to detect circular references. */
|
|
128
|
+
seen?: WeakSet<object>;
|
|
129
|
+
/** Current recursion depth, used to bound unbounded recursion (DoS guard). */
|
|
130
|
+
depth?: number;
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,0DAA0D"}
|
package/dist/util.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAInD"}
|
package/dist/util.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Describe the type of a value for error messages, matching the corpus expectations.
|
|
3
|
+
* null -> "null", array -> "array", otherwise typeof.
|
|
4
|
+
*/
|
|
5
|
+
export function describeType(value) {
|
|
6
|
+
if (value === null)
|
|
7
|
+
return "null";
|
|
8
|
+
if (Array.isArray(value))
|
|
9
|
+
return "array";
|
|
10
|
+
return typeof value;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=util.js.map
|
package/dist/util.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,MAAM,CAAC;IAClC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC;IACzC,OAAO,OAAO,KAAK,CAAC;AACtB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "anyvali",
|
|
3
|
+
"version": "0.3.1",
|
|
4
|
+
"description": "Native validation with portable schema interchange",
|
|
5
|
+
"homepage": "https://anyvali.com",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/BetterCorp/AnyVali",
|
|
9
|
+
"directory": "sdk/js"
|
|
10
|
+
},
|
|
11
|
+
"type": "module",
|
|
12
|
+
"main": "./dist/index.js",
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"import": "./dist/index.js",
|
|
17
|
+
"types": "./dist/index.d.ts"
|
|
18
|
+
},
|
|
19
|
+
"./forms": {
|
|
20
|
+
"import": "./dist/forms/index.js",
|
|
21
|
+
"types": "./dist/forms/index.d.ts"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "tsc",
|
|
26
|
+
"test": "vitest run",
|
|
27
|
+
"test:watch": "vitest",
|
|
28
|
+
"prepack": "node -e \"require('fs').copyFileSync('../../README.md','README.md')\"",
|
|
29
|
+
"postpack": "node -e \"try{require('fs').unlinkSync('README.md')}catch{}\""
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@vitest/coverage-v8": "^4.1.2",
|
|
33
|
+
"jsdom": "^29.1.1",
|
|
34
|
+
"typescript": "^6.0.2",
|
|
35
|
+
"vitest": "^4.1.2"
|
|
36
|
+
},
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=22"
|
|
39
|
+
},
|
|
40
|
+
"license": "MIT"
|
|
41
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.1.0](https://github.com/BetterCorp/AnyVali/compare/js-v0.0.1...js-v0.1.0) (2026-03-30)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **js:** add forms bindings and DOM enhancement tests ([1cb7fa1](https://github.com/BetterCorp/AnyVali/commit/1cb7fa1493282c5db3207f1e552d86ac3c57b4b0))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* update CI for Node 22/24 and fix CLI test runner ([43938a4](https://github.com/BetterCorp/AnyVali/commit/43938a4fb8f2e4867784b6729b71581e9e0dc8bf))
|
package/src/errors.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ValidationIssue } from "./types.js";
|
|
2
|
+
|
|
3
|
+
export class ValidationError extends Error {
|
|
4
|
+
public readonly issues: ValidationIssue[];
|
|
5
|
+
|
|
6
|
+
constructor(issues: ValidationIssue[]) {
|
|
7
|
+
const message = issues
|
|
8
|
+
.map(
|
|
9
|
+
(i) =>
|
|
10
|
+
`[${i.code}] ${i.path.length > 0 ? i.path.join(".") + ": " : ""}${i.message}`
|
|
11
|
+
)
|
|
12
|
+
.join("\n");
|
|
13
|
+
super(message);
|
|
14
|
+
this.name = "ValidationError";
|
|
15
|
+
this.issues = issues;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { StringFormat } from "../types.js";
|
|
2
|
+
|
|
3
|
+
// Email must have at least one dot after the @
|
|
4
|
+
const EMAIL_RE =
|
|
5
|
+
/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[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])?)+$/;
|
|
6
|
+
|
|
7
|
+
const UUID_RE =
|
|
8
|
+
/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
|
|
9
|
+
|
|
10
|
+
const IPV4_RE =
|
|
11
|
+
/^(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/;
|
|
12
|
+
|
|
13
|
+
const IPV6_RE =
|
|
14
|
+
/^(?:(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,7}:|(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:(?::[0-9a-fA-F]{1,4}){1,6}|:(?::[0-9a-fA-F]{1,4}){1,7}|::)$/;
|
|
15
|
+
|
|
16
|
+
// ISO 8601 date: YYYY-MM-DD
|
|
17
|
+
const DATE_RE = /^\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])$/;
|
|
18
|
+
|
|
19
|
+
// ISO 8601 date-time: YYYY-MM-DDTHH:MM:SS with optional fractional seconds and timezone
|
|
20
|
+
const DATETIME_RE =
|
|
21
|
+
/^\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/;
|
|
22
|
+
|
|
23
|
+
function isValidDate(str: string): boolean {
|
|
24
|
+
if (!DATE_RE.test(str)) return false;
|
|
25
|
+
const [y, m, d] = str.split("-").map(Number);
|
|
26
|
+
const date = new Date(y, m - 1, d);
|
|
27
|
+
// new Date() maps years 0-99 to 1900-1999; undo that so early ISO years
|
|
28
|
+
// (e.g. 0050-01-01) are not falsely rejected.
|
|
29
|
+
date.setFullYear(y);
|
|
30
|
+
return (
|
|
31
|
+
date.getFullYear() === y &&
|
|
32
|
+
date.getMonth() === m - 1 &&
|
|
33
|
+
date.getDate() === d
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function isValidDateTime(str: string): boolean {
|
|
38
|
+
if (!DATETIME_RE.test(str)) return false;
|
|
39
|
+
// Validate the date portion
|
|
40
|
+
const datePart = str.substring(0, 10);
|
|
41
|
+
return isValidDate(datePart);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function isValidUrl(str: string): boolean {
|
|
45
|
+
try {
|
|
46
|
+
const url = new URL(str);
|
|
47
|
+
// Only accept http and https protocols
|
|
48
|
+
return url.protocol === "http:" || url.protocol === "https:";
|
|
49
|
+
} catch {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const FORMAT_VALIDATORS: Record<StringFormat, (val: string) => boolean> = {
|
|
55
|
+
email: (val) => EMAIL_RE.test(val),
|
|
56
|
+
url: isValidUrl,
|
|
57
|
+
uuid: (val) => UUID_RE.test(val),
|
|
58
|
+
ipv4: (val) => IPV4_RE.test(val),
|
|
59
|
+
ipv6: (val) => IPV6_RE.test(val),
|
|
60
|
+
date: isValidDate,
|
|
61
|
+
"date-time": isValidDateTime,
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const FORMAT_NAME_RE = /^[A-Za-z][A-Za-z0-9-]*$/;
|
|
65
|
+
|
|
66
|
+
export function validateFormat(value: string, format: string): boolean {
|
|
67
|
+
if (!FORMAT_NAME_RE.test(format)) return false;
|
|
68
|
+
const validator = FORMAT_VALIDATORS[format as StringFormat];
|
|
69
|
+
if (!validator) return true; // valid custom formats pass
|
|
70
|
+
return validator(value);
|
|
71
|
+
}
|