typebox 1.1.9 → 1.1.11
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/build/format/email.d.mts +4 -1
- package/build/format/email.mjs +27 -3
- package/build/format/format.d.mts +21 -21
- package/build/format/format.mjs +21 -21
- package/build/format/hostname.d.mts +4 -1
- package/build/format/hostname.mjs +32 -3
- package/build/format/idn-email.d.mts +4 -1
- package/build/format/idn-email.mjs +6 -3
- package/build/format/idn-hostname.d.mts +2 -2
- package/build/format/idn-hostname.mjs +68 -77
- package/build/format/ipv4.d.mts +1 -1
- package/build/format/ipv4.mjs +32 -3
- package/build/format/ipv6.d.mts +1 -2
- package/build/format/ipv6.mjs +62 -4
- package/build/format/uri.d.mts +2 -3
- package/build/format/uri.mjs +131 -5
- package/build/type/action/mapped.d.mts +4 -4
- package/build/type/action/mapped.mjs +4 -4
- package/build/type/engine/call/distribute-arguments.d.mts +2 -2
- package/build/type/engine/call/distribute-arguments.mjs +10 -3
- package/build/type/engine/call/instantiate.mjs +1 -1
- package/build/type/engine/mapped/instantiate.d.mts +14 -17
- package/build/type/engine/mapped/instantiate.mjs +32 -30
- package/build/type/engine/mapped/{mapped-keys.d.mts → mapped-variants.d.mts} +4 -3
- package/build/type/engine/mapped/{mapped-keys.mjs → mapped-variants.mjs} +2 -2
- package/build/type/script/mapping.d.mts +1 -1
- package/package.json +1 -1
package/build/format/email.d.mts
CHANGED
package/build/format/email.mjs
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
1
|
+
import { IsIPv4Internal } from './ipv4.mjs';
|
|
2
|
+
/**
|
|
3
|
+
* Returns true if the value is an Email
|
|
4
|
+
* @specification Json Schema 2020-12
|
|
5
|
+
*/
|
|
3
6
|
export function IsEmail(value) {
|
|
4
|
-
|
|
7
|
+
const dot = value.indexOf('.');
|
|
8
|
+
const at = value.indexOf('@');
|
|
9
|
+
const quoted = value[0] === '"' && value[at - 1] === '"';
|
|
10
|
+
const ipLiteral = value[at + 1] === '[' && value[value.length - 1] === ']';
|
|
11
|
+
const ipv6 = ipLiteral && value.indexOf(':', at) !== -1;
|
|
12
|
+
const ipv4 = ipLiteral && !ipv6 && IsIPv4Internal(value, at + 2, value.length - 1);
|
|
13
|
+
return (at > 0 && at < value.length - 1) &&
|
|
14
|
+
!(
|
|
15
|
+
// .test@example.com
|
|
16
|
+
(!quoted && dot === 0) ||
|
|
17
|
+
// te..st@example.com
|
|
18
|
+
(!quoted && dot !== -1 && value.indexOf('.', dot + 1) === dot + 1) ||
|
|
19
|
+
// test.@example.com
|
|
20
|
+
(dot !== -1 && value.indexOf('@', dot) === dot + 1) ||
|
|
21
|
+
// joe bloggs@example.com
|
|
22
|
+
(!quoted && value.indexOf(' ') !== -1) ||
|
|
23
|
+
// user1@oceania.org, user2@oceania.org
|
|
24
|
+
(value.indexOf(',') !== -1) ||
|
|
25
|
+
// joe.bloggs@[127.0.0.300]
|
|
26
|
+
(ipLiteral && !ipv4 && !ipv6) ||
|
|
27
|
+
// joe.bloggs@invalid=domain.com
|
|
28
|
+
(value.indexOf('=', at) !== -1));
|
|
5
29
|
}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
export * from './_registry.mjs';
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
export
|
|
6
|
-
export
|
|
7
|
-
export
|
|
8
|
-
export
|
|
9
|
-
export
|
|
10
|
-
export
|
|
11
|
-
export
|
|
12
|
-
export
|
|
13
|
-
export
|
|
14
|
-
export
|
|
15
|
-
export
|
|
16
|
-
export
|
|
17
|
-
export
|
|
18
|
-
export
|
|
19
|
-
export
|
|
20
|
-
export
|
|
21
|
-
export
|
|
22
|
-
export
|
|
2
|
+
export { IsDateTime } from './date-time.mjs';
|
|
3
|
+
export { IsDate } from './date.mjs';
|
|
4
|
+
export { IsDuration } from './duration.mjs';
|
|
5
|
+
export { IsEmail } from './email.mjs';
|
|
6
|
+
export { IsHostname } from './hostname.mjs';
|
|
7
|
+
export { IsIdnEmail } from './idn-email.mjs';
|
|
8
|
+
export { IsIdnHostname } from './idn-hostname.mjs';
|
|
9
|
+
export { IsIPv4 } from './ipv4.mjs';
|
|
10
|
+
export { IsIPv6 } from './ipv6.mjs';
|
|
11
|
+
export { IsIriReference } from './iri-reference.mjs';
|
|
12
|
+
export { IsIri } from './iri.mjs';
|
|
13
|
+
export { IsJsonPointerUriFragment } from './json-pointer-uri-fragment.mjs';
|
|
14
|
+
export { IsJsonPointer } from './json-pointer.mjs';
|
|
15
|
+
export { IsRegex } from './regex.mjs';
|
|
16
|
+
export { IsRelativeJsonPointer } from './relative-json-pointer.mjs';
|
|
17
|
+
export { IsTime } from './time.mjs';
|
|
18
|
+
export { IsUriReference } from './uri-reference.mjs';
|
|
19
|
+
export { IsUriTemplate } from './uri-template.mjs';
|
|
20
|
+
export { IsUri } from './uri.mjs';
|
|
21
|
+
export { IsUrl } from './url.mjs';
|
|
22
|
+
export { IsUuid } from './uuid.mjs';
|
package/build/format/format.mjs
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
export * from './_registry.mjs';
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
export
|
|
6
|
-
export
|
|
7
|
-
export
|
|
8
|
-
export
|
|
9
|
-
export
|
|
10
|
-
export
|
|
11
|
-
export
|
|
12
|
-
export
|
|
13
|
-
export
|
|
14
|
-
export
|
|
15
|
-
export
|
|
16
|
-
export
|
|
17
|
-
export
|
|
18
|
-
export
|
|
19
|
-
export
|
|
20
|
-
export
|
|
21
|
-
export
|
|
22
|
-
export
|
|
2
|
+
export { IsDateTime } from './date-time.mjs';
|
|
3
|
+
export { IsDate } from './date.mjs';
|
|
4
|
+
export { IsDuration } from './duration.mjs';
|
|
5
|
+
export { IsEmail } from './email.mjs';
|
|
6
|
+
export { IsHostname } from './hostname.mjs';
|
|
7
|
+
export { IsIdnEmail } from './idn-email.mjs';
|
|
8
|
+
export { IsIdnHostname } from './idn-hostname.mjs';
|
|
9
|
+
export { IsIPv4 } from './ipv4.mjs';
|
|
10
|
+
export { IsIPv6 } from './ipv6.mjs';
|
|
11
|
+
export { IsIriReference } from './iri-reference.mjs';
|
|
12
|
+
export { IsIri } from './iri.mjs';
|
|
13
|
+
export { IsJsonPointerUriFragment } from './json-pointer-uri-fragment.mjs';
|
|
14
|
+
export { IsJsonPointer } from './json-pointer.mjs';
|
|
15
|
+
export { IsRegex } from './regex.mjs';
|
|
16
|
+
export { IsRelativeJsonPointer } from './relative-json-pointer.mjs';
|
|
17
|
+
export { IsTime } from './time.mjs';
|
|
18
|
+
export { IsUriReference } from './uri-reference.mjs';
|
|
19
|
+
export { IsUriTemplate } from './uri-template.mjs';
|
|
20
|
+
export { IsUri } from './uri.mjs';
|
|
21
|
+
export { IsUrl } from './url.mjs';
|
|
22
|
+
export { IsUuid } from './uuid.mjs';
|
|
@@ -1,5 +1,34 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Returns true if the value matches RFC 1123 hostname syntax.
|
|
3
|
+
* @specification https://tools.ietf.org/html/rfc1123
|
|
4
|
+
*/
|
|
3
5
|
export function IsHostname(value) {
|
|
4
|
-
|
|
6
|
+
if (value.length > 253 || value.length === 0)
|
|
7
|
+
return false;
|
|
8
|
+
let start = 0;
|
|
9
|
+
let prev = 0;
|
|
10
|
+
for (let i = 0; i < value.length; i++) {
|
|
11
|
+
const ch = value.charCodeAt(i);
|
|
12
|
+
if (ch === 46) { // '.'
|
|
13
|
+
// trailing dot is valid e.g. "example.com." but not "."
|
|
14
|
+
if (i === value.length - 1 && start < i)
|
|
15
|
+
break;
|
|
16
|
+
const len = i - start;
|
|
17
|
+
if (len === 0 || len > 63 || value.charCodeAt(start) === 45 || prev === 45)
|
|
18
|
+
return false;
|
|
19
|
+
start = i + 1;
|
|
20
|
+
}
|
|
21
|
+
else if (!((ch >= 97 && ch <= 122) || // a-z
|
|
22
|
+
(ch >= 65 && ch <= 90) || // A-Z
|
|
23
|
+
(ch >= 48 && ch <= 57) || // 0-9
|
|
24
|
+
ch === 45 // '-'
|
|
25
|
+
)) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
prev = ch;
|
|
29
|
+
}
|
|
30
|
+
const length = value.length - start;
|
|
31
|
+
const first = value.charCodeAt(start);
|
|
32
|
+
const last = value.charCodeAt(value.length - 1);
|
|
33
|
+
return length > 0 && length <= 63 && first !== 45 && last !== 45;
|
|
5
34
|
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
1
|
+
import { IsEmail } from './email.mjs';
|
|
2
|
+
/**
|
|
3
|
+
* Returns true if the value is an IdnEmail
|
|
4
|
+
* @specification Json Schema 2020-12
|
|
5
|
+
*/
|
|
3
6
|
export function IsIdnEmail(value) {
|
|
4
|
-
return
|
|
7
|
+
return IsEmail(value);
|
|
5
8
|
}
|
|
@@ -1,124 +1,115 @@
|
|
|
1
|
-
function IsValidAdjacentForKatakanaMiddleDot(
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
return false;
|
|
6
|
-
return ((codePoint >= 0x3040 && codePoint <= 0x309F) || // Hiragana
|
|
7
|
-
(codePoint >= 0x30A0 && codePoint <= 0x30FF && codePoint !== 0x30FB) || // Katakana (excluding U+30FB)
|
|
8
|
-
(codePoint >= 0x4E00 && codePoint <= 0x9FFF) // Han (CJK Unified Ideographs)
|
|
1
|
+
function IsValidAdjacentForKatakanaMiddleDot(cp) {
|
|
2
|
+
return ((cp >= 0x3040 && cp <= 0x309F) || // Hiragana
|
|
3
|
+
(cp >= 0x30A0 && cp <= 0x30FF && cp !== 0x30FB) || // Katakana (excluding U+30FB)
|
|
4
|
+
(cp >= 0x4E00 && cp <= 0x9FFF) // Han (CJK Unified Ideographs)
|
|
9
5
|
);
|
|
10
6
|
}
|
|
11
7
|
/**
|
|
12
|
-
* Returns true if the value is
|
|
13
|
-
* @specification
|
|
8
|
+
* Returns true if the value is an IDN Hostname
|
|
9
|
+
* @specification Json Schema 2020-12
|
|
14
10
|
*/
|
|
15
11
|
export function IsIdnHostname(value) {
|
|
16
|
-
if (value.length === 0)
|
|
17
|
-
return false;
|
|
18
|
-
if (value.includes(' '))
|
|
12
|
+
if (value.length === 0 || value.includes(' '))
|
|
19
13
|
return false;
|
|
20
|
-
//
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const normalized = value.normalize('NFC').replace(separators, '.');
|
|
14
|
+
// Normalize (NFC) and replace allowed separators with a dot
|
|
15
|
+
// Allowed label separators per RFC3490: U+002E, U+3002, U+FF0E, U+FF61
|
|
16
|
+
const normalized = value.normalize('NFC').replace(/[\u002E\u3002\uFF0E\uFF61]/g, '.');
|
|
24
17
|
if (normalized.length > 253)
|
|
25
18
|
return false;
|
|
26
|
-
// Split into labels; disallow empty labels.
|
|
27
19
|
const labels = normalized.split('.');
|
|
28
|
-
if (labels.some((label) => label.length === 0))
|
|
29
|
-
return false;
|
|
30
20
|
for (const label of labels) {
|
|
31
|
-
|
|
32
|
-
if (label.length > 63)
|
|
21
|
+
if (label.length === 0 || label.length > 63)
|
|
33
22
|
return false;
|
|
34
|
-
// Labels must not begin or end with a hyphen
|
|
35
|
-
if (label.
|
|
23
|
+
// Labels must not begin or end with a hyphen
|
|
24
|
+
if (label.charCodeAt(0) === 45 || label.charCodeAt(label.length - 1) === 45)
|
|
36
25
|
return false;
|
|
37
|
-
// A-label (punycode) checks
|
|
38
|
-
if (
|
|
26
|
+
// A-label (punycode) checks
|
|
27
|
+
if ((label.charCodeAt(0) === 120 || label.charCodeAt(0) === 88) && // 'x' or 'X'
|
|
28
|
+
(label.charCodeAt(1) === 110 || label.charCodeAt(1) === 78) && // 'n' or 'N'
|
|
29
|
+
label.charCodeAt(2) === 45 && // '-'
|
|
30
|
+
label.charCodeAt(3) === 45 // '-'
|
|
31
|
+
) {
|
|
39
32
|
const punycodePart = label.slice(4);
|
|
40
|
-
if (punycodePart.length < 2)
|
|
41
|
-
return false;
|
|
42
|
-
if (punycodePart.includes('---'))
|
|
33
|
+
if (punycodePart.length < 2 || punycodePart.includes('---'))
|
|
43
34
|
return false;
|
|
44
35
|
continue;
|
|
45
36
|
}
|
|
46
|
-
// U-label
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return false;
|
|
50
|
-
}
|
|
51
|
-
// Disallow labels starting with certain combining marks.
|
|
52
|
-
const firstChar = label.charAt(0);
|
|
53
|
-
if (/[\u0903\u0300\u0488]/.test(firstChar))
|
|
54
|
-
return false;
|
|
55
|
-
// Check each character within the label.
|
|
37
|
+
// U-label checks
|
|
38
|
+
let hasArabicIndic = false;
|
|
39
|
+
let hasExtendedArabicIndic = false;
|
|
56
40
|
for (let i = 0; i < label.length; i++) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
//
|
|
60
|
-
if (
|
|
41
|
+
// deno-coverage-ignore
|
|
42
|
+
const cp = label.codePointAt(i) ?? 0;
|
|
43
|
+
// Disallowed code points
|
|
44
|
+
if (cp === 0x302E || cp === 0x302F ||
|
|
45
|
+
cp === 0x3031 || cp === 0x3032 || cp === 0x3033 || cp === 0x3034 || cp === 0x3035 ||
|
|
46
|
+
cp === 0x303B || cp === 0x0640 || cp === 0x07FA)
|
|
47
|
+
return false;
|
|
48
|
+
// Disallow labels starting with certain combining marks
|
|
49
|
+
if (i === 0 && (cp === 0x0903 || cp === 0x0300 || cp === 0x0488))
|
|
50
|
+
return false;
|
|
51
|
+
// MIDDLE DOT (U+00B7) must be flanked by 'l' or 'L'
|
|
52
|
+
if (cp === 0x00B7) {
|
|
61
53
|
if (i === 0 || i === label.length - 1)
|
|
62
54
|
return false;
|
|
63
|
-
|
|
64
|
-
const
|
|
65
|
-
|
|
55
|
+
// deno-coverage-ignore
|
|
56
|
+
const prev = label.codePointAt(i - 1) ?? 0;
|
|
57
|
+
// deno-coverage-ignore
|
|
58
|
+
const next = label.codePointAt(i + 1) ?? 0;
|
|
59
|
+
if ((prev !== 108 && prev !== 76) || (next !== 108 && next !== 76))
|
|
66
60
|
return false;
|
|
67
61
|
}
|
|
68
|
-
//
|
|
69
|
-
if (
|
|
70
|
-
// If label is a single character, it's invalid.
|
|
62
|
+
// KATAKANA MIDDLE DOT (U+30FB) | U+30FB is below U+FFFF so stride is always 1
|
|
63
|
+
if (cp === 0x30FB) {
|
|
71
64
|
if (label.length === 1)
|
|
72
65
|
return false;
|
|
73
66
|
if (i === 0) {
|
|
74
|
-
//
|
|
75
|
-
const next = label.
|
|
67
|
+
// deno-coverage-ignore
|
|
68
|
+
const next = label.codePointAt(i + 1) ?? 0;
|
|
76
69
|
if (!IsValidAdjacentForKatakanaMiddleDot(next))
|
|
77
70
|
return false;
|
|
78
71
|
}
|
|
79
72
|
else {
|
|
80
|
-
//
|
|
81
|
-
const prev = label.
|
|
82
|
-
|
|
83
|
-
|
|
73
|
+
// deno-coverage-ignore
|
|
74
|
+
const prev = label.codePointAt(i - 1) ?? 0;
|
|
75
|
+
// deno-coverage-ignore
|
|
76
|
+
const next = label.codePointAt(i + 1) ?? 0;
|
|
77
|
+
if (!IsValidAdjacentForKatakanaMiddleDot(prev) || !IsValidAdjacentForKatakanaMiddleDot(next))
|
|
84
78
|
return false;
|
|
85
|
-
}
|
|
86
79
|
}
|
|
87
80
|
}
|
|
88
|
-
//
|
|
89
|
-
if (
|
|
81
|
+
// Greek KERAIA (U+0375) | U+0375 is below U+FFFF so stride is always 1
|
|
82
|
+
if (cp === 0x0375) {
|
|
90
83
|
if (i === label.length - 1)
|
|
91
84
|
return false;
|
|
92
|
-
|
|
93
|
-
|
|
85
|
+
// deno-coverage-ignore
|
|
86
|
+
const next = label.codePointAt(i + 1) ?? 0;
|
|
87
|
+
if (next < 0x0370 || next > 0x03FF)
|
|
94
88
|
return false;
|
|
95
89
|
}
|
|
96
|
-
//
|
|
97
|
-
if (
|
|
90
|
+
// Hebrew GERESH (U+05F3) and GERSHAYIM (U+05F4)
|
|
91
|
+
if (cp === 0x05F3 || cp === 0x05F4) {
|
|
98
92
|
if (i === 0)
|
|
99
93
|
return false;
|
|
100
|
-
|
|
101
|
-
|
|
94
|
+
// deno-coverage-ignore
|
|
95
|
+
const prev = label.codePointAt(i - 1) ?? 0;
|
|
96
|
+
if (prev < 0x05D0 || prev > 0x05EA)
|
|
102
97
|
return false;
|
|
103
98
|
}
|
|
104
|
-
//
|
|
105
|
-
if (
|
|
99
|
+
// ZERO WIDTH JOINER (U+200D)
|
|
100
|
+
if (cp === 0x200D) {
|
|
106
101
|
if (i === 0)
|
|
107
102
|
return false;
|
|
108
|
-
|
|
109
|
-
|
|
103
|
+
// deno-coverage-ignore
|
|
104
|
+
const prev = label.codePointAt(i - 1) ?? 0;
|
|
105
|
+
if (prev !== 0x094D)
|
|
110
106
|
return false;
|
|
111
107
|
}
|
|
112
|
-
//
|
|
113
|
-
|
|
114
|
-
// --- Arabic-Indic digits vs. Extended Arabic-Indic digits ---
|
|
115
|
-
let hasArabicIndic = false;
|
|
116
|
-
let hasExtendedArabicIndic = false;
|
|
117
|
-
for (let i = 0; i < label.length; i++) {
|
|
118
|
-
const char = label.charAt(i);
|
|
119
|
-
if (/[\u0660-\u0669]/.test(char))
|
|
108
|
+
// Arabic-Indic digits
|
|
109
|
+
if (cp >= 0x0660 && cp <= 0x0669)
|
|
120
110
|
hasArabicIndic = true;
|
|
121
|
-
|
|
111
|
+
// Extended Arabic-Indic digits
|
|
112
|
+
if (cp >= 0x06F0 && cp <= 0x06F9)
|
|
122
113
|
hasExtendedArabicIndic = true;
|
|
123
114
|
}
|
|
124
115
|
if (hasArabicIndic && hasExtendedArabicIndic)
|
package/build/format/ipv4.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
export declare function IsIPv4Internal(value: string, start: number, end: number): boolean;
|
|
1
2
|
/**
|
|
2
3
|
* Returns true if the value is a IPV4 address
|
|
3
|
-
* @source ajv-formats
|
|
4
4
|
* @specification http://tools.ietf.org/html/rfc2673#section-3.2
|
|
5
5
|
*/
|
|
6
6
|
export declare function IsIPv4(value: string): boolean;
|
package/build/format/ipv4.mjs
CHANGED
|
@@ -1,9 +1,38 @@
|
|
|
1
|
-
|
|
1
|
+
// ------------------------------------------------------------------
|
|
2
|
+
// Ranged Fast Path
|
|
3
|
+
// ------------------------------------------------------------------
|
|
4
|
+
/* Returns true if the value is a IPV4 address from index range offsets */
|
|
5
|
+
export function IsIPv4Internal(value, start, end) {
|
|
6
|
+
let dots = 0;
|
|
7
|
+
let num = 0;
|
|
8
|
+
let digits = 0;
|
|
9
|
+
let leading = 0;
|
|
10
|
+
for (let i = start; i < end; i++) {
|
|
11
|
+
const ch = value.charCodeAt(i);
|
|
12
|
+
if (ch === 46) { // '.'
|
|
13
|
+
if (digits === 0 || num > 255 || (leading === 48 && digits > 1))
|
|
14
|
+
return false;
|
|
15
|
+
dots++;
|
|
16
|
+
num = 0;
|
|
17
|
+
digits = 0;
|
|
18
|
+
leading = 0;
|
|
19
|
+
}
|
|
20
|
+
else if (ch >= 48 && ch <= 57) { // '0'-'9'
|
|
21
|
+
if (digits === 0)
|
|
22
|
+
leading = ch;
|
|
23
|
+
num = num * 10 + (ch - 48);
|
|
24
|
+
digits++;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return dots === 3 && digits > 0 && num <= 255 && !(leading === 48 && digits > 1);
|
|
31
|
+
}
|
|
2
32
|
/**
|
|
3
33
|
* Returns true if the value is a IPV4 address
|
|
4
|
-
* @source ajv-formats
|
|
5
34
|
* @specification http://tools.ietf.org/html/rfc2673#section-3.2
|
|
6
35
|
*/
|
|
7
36
|
export function IsIPv4(value) {
|
|
8
|
-
return
|
|
37
|
+
return IsIPv4Internal(value, 0, value.length);
|
|
9
38
|
}
|
package/build/format/ipv6.d.mts
CHANGED
package/build/format/ipv6.mjs
CHANGED
|
@@ -1,9 +1,67 @@
|
|
|
1
|
-
|
|
1
|
+
import { IsIPv4Internal } from './ipv4.mjs';
|
|
2
|
+
function InRange(ch) {
|
|
3
|
+
return (ch >= 48 && ch <= 57) || // 0-9
|
|
4
|
+
(ch >= 65 && ch <= 70) || // A-F
|
|
5
|
+
(ch >= 97 && ch <= 102); // a-f
|
|
6
|
+
}
|
|
2
7
|
/**
|
|
3
|
-
* Returns true if the value is
|
|
4
|
-
* @source ajv-formats
|
|
8
|
+
* Returns true if the value is an IPv6 address
|
|
5
9
|
* @specification http://tools.ietf.org/html/rfc2373#section-2.2
|
|
6
10
|
*/
|
|
7
11
|
export function IsIPv6(value) {
|
|
8
|
-
|
|
12
|
+
const length = value.length;
|
|
13
|
+
if (length === 0)
|
|
14
|
+
return false;
|
|
15
|
+
let groups = 0;
|
|
16
|
+
let compressed = false;
|
|
17
|
+
let i = 0;
|
|
18
|
+
// handle leading '::'
|
|
19
|
+
if (value.charCodeAt(0) === 58 && value.charCodeAt(1) === 58) {
|
|
20
|
+
if (length === 2)
|
|
21
|
+
return true; // '::' is valid
|
|
22
|
+
compressed = true;
|
|
23
|
+
i = 2;
|
|
24
|
+
}
|
|
25
|
+
while (i < length) {
|
|
26
|
+
// read hex digits
|
|
27
|
+
let digits = 0;
|
|
28
|
+
const start = i;
|
|
29
|
+
while (i < length && InRange(value.charCodeAt(i))) {
|
|
30
|
+
i++;
|
|
31
|
+
digits++;
|
|
32
|
+
}
|
|
33
|
+
if (digits === 0)
|
|
34
|
+
return false;
|
|
35
|
+
const next = value.charCodeAt(i);
|
|
36
|
+
// check for embedded IPv4 at the end
|
|
37
|
+
if (next === 46) { // '.'
|
|
38
|
+
if (!IsIPv4Internal(value, start, length))
|
|
39
|
+
return false;
|
|
40
|
+
groups += 2;
|
|
41
|
+
i = length;
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
if (digits > 4)
|
|
45
|
+
return false;
|
|
46
|
+
groups++;
|
|
47
|
+
if (i === length)
|
|
48
|
+
break;
|
|
49
|
+
// expect ':' separator
|
|
50
|
+
if (next !== 58)
|
|
51
|
+
return false;
|
|
52
|
+
i++;
|
|
53
|
+
// check for '::' compression
|
|
54
|
+
if (value.charCodeAt(i) === 58) {
|
|
55
|
+
if (compressed)
|
|
56
|
+
return false; // only one '::' allowed
|
|
57
|
+
// check for ':::'
|
|
58
|
+
if (value.charCodeAt(i + 1) === 58)
|
|
59
|
+
return false;
|
|
60
|
+
compressed = true;
|
|
61
|
+
i++;
|
|
62
|
+
if (i === length)
|
|
63
|
+
break; // trailing '::'
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return compressed ? groups <= 7 : groups === 8;
|
|
9
67
|
}
|
package/build/format/uri.d.mts
CHANGED
package/build/format/uri.mjs
CHANGED
|
@@ -1,9 +1,135 @@
|
|
|
1
|
-
|
|
1
|
+
function IsAlpha(ch) {
|
|
2
|
+
return (ch >= 97 && ch <= 122) || (ch >= 65 && ch <= 90); // a-z, A-Z
|
|
3
|
+
}
|
|
4
|
+
function IsAlphaNumeric(ch) {
|
|
5
|
+
return IsAlpha(ch) || (ch >= 48 && ch <= 57); // a-z, A-Z, 0-9
|
|
6
|
+
}
|
|
7
|
+
function IsHex(ch) {
|
|
8
|
+
return (ch >= 48 && ch <= 57) || // 0-9
|
|
9
|
+
(ch >= 65 && ch <= 70) || // A-F
|
|
10
|
+
(ch >= 97 && ch <= 102); // a-f
|
|
11
|
+
}
|
|
12
|
+
function IsSchemeChar(ch) {
|
|
13
|
+
return IsAlphaNumeric(ch) ||
|
|
14
|
+
ch === 43 || ch === 45 || ch === 46; // '+', '-', '.'
|
|
15
|
+
}
|
|
16
|
+
function IsUnreserved(ch) {
|
|
17
|
+
return IsAlphaNumeric(ch) ||
|
|
18
|
+
ch === 45 || ch === 46 || // '-', '.'
|
|
19
|
+
ch === 95 || ch === 126; // '_', '~'
|
|
20
|
+
}
|
|
21
|
+
function IsSubDelim(ch) {
|
|
22
|
+
return ch === 33 || ch === 36 || ch === 38 || ch === 39 ||
|
|
23
|
+
ch === 40 || ch === 41 || ch === 42 || ch === 43 ||
|
|
24
|
+
ch === 44 || ch === 59 || ch === 61; // ! $ & ' ( ) * + , ; =
|
|
25
|
+
}
|
|
26
|
+
function IsPchar(ch) {
|
|
27
|
+
return IsUnreserved(ch) || IsSubDelim(ch) || ch === 58 || ch === 64; // ':', '@'
|
|
28
|
+
}
|
|
2
29
|
/**
|
|
3
|
-
* Returns true if the value
|
|
4
|
-
* @specification
|
|
5
|
-
* @source ajv-formats
|
|
30
|
+
* Returns true if the value matches RFC 3986 URI syntax.
|
|
31
|
+
* @specification https://tools.ietf.org/html/rfc3986
|
|
6
32
|
*/
|
|
7
33
|
export function IsUri(value) {
|
|
8
|
-
|
|
34
|
+
const length = value.length;
|
|
35
|
+
if (length === 0)
|
|
36
|
+
return false;
|
|
37
|
+
// Scheme: must start with a letter
|
|
38
|
+
if (!IsAlpha(value.charCodeAt(0)))
|
|
39
|
+
return false;
|
|
40
|
+
// Scheme: continues until ':'
|
|
41
|
+
let i = 1;
|
|
42
|
+
while (i < length) {
|
|
43
|
+
const ch = value.charCodeAt(i);
|
|
44
|
+
if (ch === 58)
|
|
45
|
+
break; // ':'
|
|
46
|
+
if (!IsSchemeChar(ch))
|
|
47
|
+
return false;
|
|
48
|
+
i++;
|
|
49
|
+
}
|
|
50
|
+
// Ensure scheme is terminated by ':'
|
|
51
|
+
if (value.charCodeAt(i) !== 58)
|
|
52
|
+
return false;
|
|
53
|
+
i++;
|
|
54
|
+
// Authority: optional '//'
|
|
55
|
+
if (value.charCodeAt(i) === 47 && value.charCodeAt(i + 1) === 47) {
|
|
56
|
+
i += 2;
|
|
57
|
+
// Userinfo: check for '@' before path/query/fragment delimiters
|
|
58
|
+
const authorityStart = i;
|
|
59
|
+
let atPos = -1;
|
|
60
|
+
for (let j = i; j < length; j++) {
|
|
61
|
+
const ch = value.charCodeAt(j);
|
|
62
|
+
if (ch === 64) {
|
|
63
|
+
atPos = j;
|
|
64
|
+
break;
|
|
65
|
+
} // '@'
|
|
66
|
+
if (ch === 47 || ch === 63 || ch === 35)
|
|
67
|
+
break; // '/', '?', '#'
|
|
68
|
+
}
|
|
69
|
+
if (atPos !== -1) {
|
|
70
|
+
// Userinfo: validate allowed chars and percent-encoding
|
|
71
|
+
for (let j = authorityStart; j < atPos; j++) {
|
|
72
|
+
const ch = value.charCodeAt(j);
|
|
73
|
+
if (ch === 91 || ch === 93)
|
|
74
|
+
return false; // No '[' or ']' in userinfo
|
|
75
|
+
if (ch === 37) { // '%' percent-encoding
|
|
76
|
+
if (j + 2 >= atPos || !IsHex(value.charCodeAt(j + 1)) || !IsHex(value.charCodeAt(j + 2)))
|
|
77
|
+
return false;
|
|
78
|
+
j += 2;
|
|
79
|
+
}
|
|
80
|
+
else if (!IsUnreserved(ch) && !IsSubDelim(ch) && ch !== 58)
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
i = atPos + 1;
|
|
84
|
+
}
|
|
85
|
+
// Host: IP-literal [addr] or reg-name
|
|
86
|
+
if (value.charCodeAt(i) === 91) { // '['
|
|
87
|
+
i++;
|
|
88
|
+
while (i < length && value.charCodeAt(i) !== 93)
|
|
89
|
+
i++;
|
|
90
|
+
if (value.charCodeAt(i) !== 93)
|
|
91
|
+
return false; // ']'
|
|
92
|
+
i++;
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
// Host: validate ASCII; skip validation for non-ASCII (Unicode hosts)
|
|
96
|
+
while (i < length) {
|
|
97
|
+
const ch = value.charCodeAt(i);
|
|
98
|
+
if (ch === 47 || ch === 63 || ch === 35 || ch === 58)
|
|
99
|
+
break;
|
|
100
|
+
if (ch < 128 && !IsUnreserved(ch) && !IsSubDelim(ch))
|
|
101
|
+
return false;
|
|
102
|
+
i++;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Port: optional digits after ':'
|
|
106
|
+
if (value.charCodeAt(i) === 58) { // ':'
|
|
107
|
+
i++;
|
|
108
|
+
while (i < length) {
|
|
109
|
+
const ch = value.charCodeAt(i);
|
|
110
|
+
if (ch === 47 || ch === 63 || ch === 35)
|
|
111
|
+
break;
|
|
112
|
+
if (ch < 48 || ch > 57)
|
|
113
|
+
return false; // 0-9
|
|
114
|
+
i++;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// Path, Query, and Fragment
|
|
119
|
+
while (i < length) {
|
|
120
|
+
const ch = value.charCodeAt(i);
|
|
121
|
+
if (ch === 37) { // '%' percent-encoding
|
|
122
|
+
if (i + 2 >= length || !IsHex(value.charCodeAt(i + 1)) || !IsHex(value.charCodeAt(i + 2)))
|
|
123
|
+
return false;
|
|
124
|
+
i += 2;
|
|
125
|
+
}
|
|
126
|
+
else if (ch > 127) {
|
|
127
|
+
return false; // URI is ASCII-only
|
|
128
|
+
}
|
|
129
|
+
else if (!(IsPchar(ch) || ch === 47 || ch === 63 || ch === 35)) {
|
|
130
|
+
return false; // '/', '?', '#'
|
|
131
|
+
}
|
|
132
|
+
i++;
|
|
133
|
+
}
|
|
134
|
+
return true;
|
|
9
135
|
}
|
|
@@ -3,10 +3,10 @@ import { type TIdentifier } from '../types/identifier.mjs';
|
|
|
3
3
|
import { type TDeferred } from '../types/deferred.mjs';
|
|
4
4
|
import { type TInstantiate } from '../engine/instantiate.mjs';
|
|
5
5
|
/** Creates a deferred Mapped action. */
|
|
6
|
-
export type TMappedDeferred<Identifier extends TIdentifier,
|
|
6
|
+
export type TMappedDeferred<Identifier extends TIdentifier, Type extends TSchema, As extends TSchema, Property extends TSchema> = (TDeferred<'Mapped', [Identifier, Type, As, Property]>);
|
|
7
7
|
/** Creates a deferred Mapped action. */
|
|
8
|
-
export declare function MappedDeferred<Identifier extends TIdentifier,
|
|
8
|
+
export declare function MappedDeferred<Identifier extends TIdentifier, Type extends TSchema, As extends TSchema, Property extends TSchema>(identifier: Identifier, type: Type, as: As, property: Property, options?: TSchemaOptions): TMappedDeferred<Identifier, Type, As, Property>;
|
|
9
9
|
/** Applies a Mapped action using the given types. */
|
|
10
|
-
export type TMapped<Identifier extends TIdentifier,
|
|
10
|
+
export type TMapped<Identifier extends TIdentifier, Type extends TSchema, As extends TSchema, Property extends TSchema> = (TInstantiate<{}, TMappedDeferred<Identifier, Type, As, Property>>);
|
|
11
11
|
/** Applies a Mapped action using the given types. */
|
|
12
|
-
export declare function Mapped<Identifier extends TIdentifier,
|
|
12
|
+
export declare function Mapped<Identifier extends TIdentifier, Type extends TSchema, As extends TSchema, Property extends TSchema>(identifier: Identifier, type: Type, as: As, property: Property, options?: TSchemaOptions): TMapped<Identifier, Type, As, Property>;
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import { Deferred } from '../types/deferred.mjs';
|
|
3
3
|
import { Instantiate } from '../engine/instantiate.mjs';
|
|
4
4
|
/** Creates a deferred Mapped action. */
|
|
5
|
-
export function MappedDeferred(identifier,
|
|
6
|
-
return Deferred('Mapped', [identifier,
|
|
5
|
+
export function MappedDeferred(identifier, type, as, property, options = {}) {
|
|
6
|
+
return Deferred('Mapped', [identifier, type, as, property], options);
|
|
7
7
|
}
|
|
8
8
|
/** Applies a Mapped action using the given types. */
|
|
9
|
-
export function Mapped(identifier,
|
|
10
|
-
return Instantiate({}, MappedDeferred(identifier,
|
|
9
|
+
export function Mapped(identifier, type, as, property, options = {}) {
|
|
10
|
+
return Instantiate({}, MappedDeferred(identifier, type, as, property, options));
|
|
11
11
|
}
|
|
@@ -3,13 +3,13 @@ import { type TUnion } from '../../types/union.mjs';
|
|
|
3
3
|
import { type TDeferred } from '../../types/deferred.mjs';
|
|
4
4
|
import { type TRef } from '../../types/ref.mjs';
|
|
5
5
|
import { type TParameter } from '../../types/parameter.mjs';
|
|
6
|
-
type TCollectDistributionNames<Expression extends TSchema, Result extends string[] = []> = (Expression extends TDeferred<'Conditional', [infer Left extends TSchema, infer _Right extends TSchema, infer True extends TSchema, infer False extends TSchema]> ? Left extends TRef<infer Name extends string> ? TCollectDistributionNames<True, TCollectDistributionNames<False, [...Result, Name]>> : TCollectDistributionNames<True, TCollectDistributionNames<False, Result>> : Result);
|
|
6
|
+
type TCollectDistributionNames<Expression extends TSchema, Result extends string[] = []> = (Expression extends TDeferred<'Conditional', [infer Left extends TSchema, infer _Right extends TSchema, infer True extends TSchema, infer False extends TSchema]> ? Left extends TRef<infer Name extends string> ? TCollectDistributionNames<True, TCollectDistributionNames<False, [...Result, Name]>> : TCollectDistributionNames<True, TCollectDistributionNames<False, Result>> : Expression extends TDeferred<'Mapped', [infer _Identifier extends TSchema, infer Type extends TSchema, infer _As extends TSchema, infer _Property extends TSchema]> ? (Type extends TDeferred<'KeyOf', [infer Ref extends TRef]> ? [...Result, Ref['$ref']] : Result) : Result);
|
|
7
7
|
type TBuildDistributionArray<Parameters extends TParameter[], Names extends string[], Result extends boolean[] = []> = (Parameters extends [infer Left extends TParameter, ...infer Right extends TParameter[]] ? Left['name'] extends Names[number] ? TBuildDistributionArray<Right, Names, [...Result, true]> : TBuildDistributionArray<Right, Names, [...Result, false]> : Result);
|
|
8
8
|
type TZipDistributionArray<Arguments extends TSchema[], DistributionArray extends boolean[], Result extends [boolean, TSchema][] = []> = (Arguments extends [infer ArgumentLeft extends TSchema, ...infer ArgumentRight extends TSchema[]] ? DistributionArray extends [infer BooleanLeft extends boolean, ...infer BooleanRight extends boolean[]] ? TZipDistributionArray<ArgumentRight, BooleanRight, [...Result, [BooleanLeft, ArgumentLeft]]> : Result : Result);
|
|
9
9
|
type TExpand<Type extends TSchema> = (Type extends TUnion<infer Types extends TSchema[]> ? [...Types] : [Type]);
|
|
10
10
|
type TAppend<Current extends TSchema[][], Type extends TSchema, Result extends TSchema[][] = []> = (Current extends [infer Left extends TSchema[], ...infer Right extends TSchema[][]] ? TAppend<Right, Type, [...Result, [...Left, Type]]> : Result);
|
|
11
11
|
type TCross<Current extends TSchema[][], Variants extends TSchema[], Result extends TSchema[][] = []> = (Variants extends [infer Left extends TSchema, ...infer Right extends TSchema[]] ? TCross<Current, Right, [...Result, ...TAppend<Current, Left>]> : Result);
|
|
12
12
|
type TDistribute<ZippedArguments extends [boolean, TSchema][], Result extends TSchema[][] = [[]]> = (ZippedArguments extends [infer Left extends [boolean, TSchema], ...infer Right extends [boolean, TSchema][]] ? Left[0] extends true ? TDistribute<Right, TCross<Result, TExpand<Left[1]>>> : TDistribute<Right, TCross<Result, [Left[1]]>> : Result);
|
|
13
|
-
export type TDistributeArguments<Parameters extends TParameter[], Arguments extends TSchema[], Expression extends TSchema, DistributionNames extends string[] = TCollectDistributionNames<Expression>, DistributionArray extends boolean[] = TBuildDistributionArray<Parameters, DistributionNames>, ZippedArguments extends [boolean, TSchema][] = TZipDistributionArray<Arguments, DistributionArray>, Result extends TSchema[][] = Expression extends TDeferred<'Conditional', TSchema[]> ? TDistribute<ZippedArguments> : [Arguments]> = Result;
|
|
13
|
+
export type TDistributeArguments<Parameters extends TParameter[], Arguments extends TSchema[], Expression extends TSchema, DistributionNames extends string[] = TCollectDistributionNames<Expression>, DistributionArray extends boolean[] = TBuildDistributionArray<Parameters, DistributionNames>, ZippedArguments extends [boolean, TSchema][] = TZipDistributionArray<Arguments, DistributionArray>, Result extends TSchema[][] = (Expression extends TDeferred<'Conditional', TSchema[]> ? TDistribute<ZippedArguments> : Expression extends TDeferred<'Mapped', TSchema[]> ? TDistribute<ZippedArguments> : [Arguments])> = Result;
|
|
14
14
|
export declare function DistributeArguments<Parameters extends TParameter[], Arguments extends TSchema[], Expression extends TSchema>(parameters: [...Parameters], arguments_: [...Arguments], expression: Expression): TDistributeArguments<Parameters, Arguments, Expression>;
|
|
15
15
|
export {};
|
|
@@ -4,11 +4,16 @@ import { IsUnion } from '../../types/union.mjs';
|
|
|
4
4
|
import { IsDeferred } from '../../types/deferred.mjs';
|
|
5
5
|
import { IsRef } from '../../types/ref.mjs';
|
|
6
6
|
function CollectDistributionNames(expression, result = []) {
|
|
7
|
-
return (
|
|
7
|
+
return (
|
|
8
|
+
// Conditional
|
|
9
|
+
IsDeferred(expression) && Guard.IsEqual(expression.action, 'Conditional')
|
|
8
10
|
? IsRef(expression.parameters[0])
|
|
9
11
|
? CollectDistributionNames(expression.parameters[2], CollectDistributionNames(expression.parameters[3], [...result, expression.parameters[0].$ref]))
|
|
10
12
|
: CollectDistributionNames(expression.parameters[2], CollectDistributionNames(expression.parameters[3], result))
|
|
11
|
-
|
|
13
|
+
// Mapped
|
|
14
|
+
: IsDeferred(expression) && Guard.IsEqual(expression.action, 'Mapped')
|
|
15
|
+
? (IsDeferred(expression.parameters[1]) && Guard.IsEqual(expression.parameters[1].action, 'KeyOf') && IsRef(expression.parameters[1].parameters[0]) ? [...result, expression.parameters[1].parameters[0]['$ref']] :
|
|
16
|
+
result) : result);
|
|
12
17
|
}
|
|
13
18
|
function BuildDistributionArray(parameters, names) {
|
|
14
19
|
return parameters.reduce((result, left) => [...result, names.includes(left.name)], []);
|
|
@@ -48,5 +53,7 @@ export function DistributeArguments(parameters, arguments_, expression) {
|
|
|
48
53
|
const zippedArguments = ZipDistributionArray(arguments_, distributionArray);
|
|
49
54
|
return (IsDeferred(expression) && Guard.IsEqual(expression.action, 'Conditional')
|
|
50
55
|
? Distribute(zippedArguments)
|
|
51
|
-
:
|
|
56
|
+
: IsDeferred(expression) && Guard.IsEqual(expression.action, 'Mapped')
|
|
57
|
+
? Distribute(zippedArguments)
|
|
58
|
+
: [arguments_]);
|
|
52
59
|
}
|
|
@@ -31,7 +31,7 @@ function CallDistributed(context, state, target, parameters, expression, distrib
|
|
|
31
31
|
function CallImmediate(context, state, target, parameters, expression, arguments_) {
|
|
32
32
|
const distributedArguments = DistributeArguments(parameters, arguments_, expression);
|
|
33
33
|
const returnTypes = CallDistributed(context, state, target, parameters, expression, distributedArguments);
|
|
34
|
-
const result = returnTypes.length
|
|
34
|
+
const result = Guard.IsEqual(returnTypes.length, 1) ? returnTypes[0] : EvaluateUnion(returnTypes);
|
|
35
35
|
return result;
|
|
36
36
|
}
|
|
37
37
|
export function CallInstantiate(context, state, target, arguments_) {
|
|
@@ -4,25 +4,22 @@ import { type TLiteral } from '../../types/literal.mjs';
|
|
|
4
4
|
import { type TObject } from '../../types/object.mjs';
|
|
5
5
|
import { type TProperties } from '../../types/properties.mjs';
|
|
6
6
|
import { type TIdentifier } from '../../types/identifier.mjs';
|
|
7
|
-
import { type TMappedKeys } from './mapped-keys.mjs';
|
|
8
7
|
import { type TTemplateLiteral } from '../../types/template-literal.mjs';
|
|
9
8
|
import { type TMappedDeferred } from '../../action/mapped.mjs';
|
|
10
9
|
import { type TTemplateLiteralDecode } from '../template-literal/decode.mjs';
|
|
11
10
|
import { type TState, type TInstantiateType, type TCanInstantiate } from '../instantiate.mjs';
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
type
|
|
16
|
-
[_ in Identifier['name']]:
|
|
17
|
-
}>, InstantiatedProperty extends TSchema = TInstantiateType<
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
type
|
|
22
|
-
type TMappedAction<Context extends TProperties, State extends TState, Identifier extends TIdentifier,
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
export type TMappedInstantiate<Context extends TProperties, State extends TState, Identifier extends TIdentifier, Key extends TSchema, As extends TSchema, Property extends TSchema> = TCanInstantiate<Context, [Key]> extends true ? TMappedImmediate<Context, State, Identifier, Key, As, Property> : TMappedDeferred<Identifier, Key, As, Property>;
|
|
27
|
-
export declare function MappedInstantiate<Context extends TProperties, State extends TState, Identifier extends TIdentifier, Key extends TSchema, As extends TSchema, Property extends TSchema>(context: Context, state: State, identifier: Identifier, key: Key, as: As, property: Property, options: TSchemaOptions): TMappedInstantiate<Context, State, Identifier, Key, As, Property>;
|
|
11
|
+
import { type TMappedVariants } from './mapped-variants.mjs';
|
|
12
|
+
import { type TEvaluateIntersect } from '../evaluate/index.mjs';
|
|
13
|
+
type TCanonicalAs<InstantiatedAs extends TSchema, Result extends TSchema = InstantiatedAs extends TTemplateLiteral<infer Pattern extends string> ? TTemplateLiteralDecode<Pattern> : InstantiatedAs> = Result;
|
|
14
|
+
type TMappedVariant<Context extends TProperties, State extends TState, Identifier extends TIdentifier, Variant extends TSchema, As extends TSchema, Property extends TSchema, VariantContext extends TProperties = Memory.TAssign<Context, {
|
|
15
|
+
[_ in Identifier['name']]: Variant;
|
|
16
|
+
}>, InstantiatedAs extends TSchema = TInstantiateType<VariantContext, State, As>, CanonicalAs extends TSchema = TCanonicalAs<InstantiatedAs>, InstantiatedProperty extends TSchema = TInstantiateType<VariantContext, State, Property>, Result extends TProperties = CanonicalAs extends TLiteral<string | number> ? {
|
|
17
|
+
[_ in CanonicalAs['const']]: InstantiatedProperty;
|
|
18
|
+
} : {}> = Result;
|
|
19
|
+
type TMappedProperties<Context extends TProperties, State extends TState, Identifier extends TIdentifier, Variants extends TSchema[], As extends TSchema, Property extends TSchema, Result extends TProperties[] = []> = (Variants extends [infer Left extends TSchema, ...infer Right extends TSchema[]] ? TMappedProperties<Context, State, Identifier, Right, As, Property, [...Result, TMappedVariant<Context, State, Identifier, Left, As, Property>]> : Result);
|
|
20
|
+
type TReduceProperties<Properties extends TProperties[], Result extends TSchema[] = []> = (Properties extends [infer Left extends TProperties, ...infer Right extends TProperties[]] ? TReduceProperties<Right, [...Result, TObject<Left>]> : Result);
|
|
21
|
+
type TMappedAction<Context extends TProperties, State extends TState, Identifier extends TIdentifier, Type extends TSchema, As extends TSchema, Property extends TSchema, Variants extends TSchema[] = TMappedVariants<Type>, MappedProperties extends TProperties[] = TMappedProperties<Context, State, Identifier, Variants, As, Property>, MappedObjects extends TSchema[] = TReduceProperties<MappedProperties>, Result extends TSchema = TEvaluateIntersect<MappedObjects>> = Result;
|
|
22
|
+
type TMappedImmediate<Context extends TProperties, State extends TState, Identifier extends TIdentifier, Type extends TSchema, As extends TSchema, Property extends TSchema, InstantiatedType extends TSchema = TInstantiateType<Context, State, Type>> = TMappedAction<Context, State, Identifier, InstantiatedType, As, Property>;
|
|
23
|
+
export type TMappedInstantiate<Context extends TProperties, State extends TState, Identifier extends TIdentifier, Type extends TSchema, As extends TSchema, Property extends TSchema> = TCanInstantiate<Context, [Type]> extends true ? TMappedImmediate<Context, State, Identifier, Type, As, Property> : TMappedDeferred<Identifier, Type, As, Property>;
|
|
24
|
+
export declare function MappedInstantiate<Context extends TProperties, State extends TState, Identifier extends TIdentifier, Type extends TSchema, As extends TSchema, Property extends TSchema>(context: Context, state: State, identifier: Identifier, type: Type, as: As, property: Property, options: TSchemaOptions): TMappedInstantiate<Context, State, Identifier, Type, As, Property>;
|
|
28
25
|
export {};
|
|
@@ -2,46 +2,48 @@
|
|
|
2
2
|
import { Memory } from '../../../system/memory/index.mjs';
|
|
3
3
|
import { IsLiteralNumber, IsLiteralString } from '../../types/literal.mjs';
|
|
4
4
|
import { Object } from '../../types/object.mjs';
|
|
5
|
-
import { MappedKeys } from './mapped-keys.mjs';
|
|
6
5
|
import { IsTemplateLiteral } from '../../types/template-literal.mjs';
|
|
7
6
|
import { MappedDeferred } from '../../action/mapped.mjs';
|
|
8
7
|
import { TemplateLiteralDecode } from '../template-literal/decode.mjs';
|
|
9
8
|
import { InstantiateType, CanInstantiate } from '../instantiate.mjs';
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const result = IsTemplateLiteral(
|
|
9
|
+
import { MappedVariants } from './mapped-variants.mjs';
|
|
10
|
+
import { EvaluateIntersect } from '../evaluate/index.mjs';
|
|
11
|
+
function CanonicalAs(instantiatedAs) {
|
|
12
|
+
const result = IsTemplateLiteral(instantiatedAs) ? TemplateLiteralDecode(instantiatedAs.pattern) : instantiatedAs;
|
|
14
13
|
return result;
|
|
15
14
|
}
|
|
16
|
-
function
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const instantiatedKeyAs = InstantiateKeyAs(context, state, identifier, key, as);
|
|
24
|
-
return (IsLiteralString(instantiatedKeyAs) || IsLiteralNumber(instantiatedKeyAs)
|
|
25
|
-
? { [instantiatedKeyAs.const]: instantiatedProperty }
|
|
15
|
+
function MappedVariant(context, state, identifier, variant, as, property) {
|
|
16
|
+
const variantContext = Memory.Assign(context, { [identifier['name']]: variant });
|
|
17
|
+
const instantiatedAs = InstantiateType(variantContext, state, as);
|
|
18
|
+
const canonicalAs = CanonicalAs(instantiatedAs);
|
|
19
|
+
const instantiatedProperty = InstantiateType(variantContext, state, property);
|
|
20
|
+
return (IsLiteralNumber(canonicalAs) || IsLiteralString(canonicalAs)
|
|
21
|
+
? { [canonicalAs.const]: instantiatedProperty }
|
|
26
22
|
: {});
|
|
27
23
|
}
|
|
28
|
-
function MappedProperties(context, state, identifier,
|
|
29
|
-
return
|
|
30
|
-
return
|
|
31
|
-
},
|
|
24
|
+
function MappedProperties(context, state, identifier, variants, as, property) {
|
|
25
|
+
return variants.reduce((result, left) => {
|
|
26
|
+
return [...result, MappedVariant(context, state, identifier, left, as, property)];
|
|
27
|
+
}, []);
|
|
28
|
+
}
|
|
29
|
+
function MappedObjects(properties) {
|
|
30
|
+
return properties.reduce((result, left) => {
|
|
31
|
+
return [...result, Object(left)];
|
|
32
|
+
}, []);
|
|
32
33
|
}
|
|
33
|
-
function MappedAction(context, state, identifier,
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
const
|
|
34
|
+
function MappedAction(context, state, identifier, type, as, property) {
|
|
35
|
+
const variants = MappedVariants(type);
|
|
36
|
+
const mappedProperties = MappedProperties(context, state, identifier, variants, as, property);
|
|
37
|
+
const mappedObjects = MappedObjects(mappedProperties);
|
|
38
|
+
const result = EvaluateIntersect(mappedObjects);
|
|
37
39
|
return result;
|
|
38
40
|
}
|
|
39
|
-
function MappedImmediate(context, state, identifier,
|
|
40
|
-
const
|
|
41
|
-
return Memory.Update(MappedAction(context, state, identifier,
|
|
41
|
+
function MappedImmediate(context, state, identifier, type, as, property, options) {
|
|
42
|
+
const instantiatedType = InstantiateType(context, state, type);
|
|
43
|
+
return Memory.Update(MappedAction(context, state, identifier, instantiatedType, as, property), {}, options);
|
|
42
44
|
}
|
|
43
|
-
export function MappedInstantiate(context, state, identifier,
|
|
44
|
-
return (CanInstantiate(context, [
|
|
45
|
-
? MappedImmediate(context, state, identifier,
|
|
46
|
-
: MappedDeferred(identifier,
|
|
45
|
+
export function MappedInstantiate(context, state, identifier, type, as, property, options) {
|
|
46
|
+
return (CanInstantiate(context, [type])
|
|
47
|
+
? MappedImmediate(context, state, identifier, type, as, property, options)
|
|
48
|
+
: MappedDeferred(identifier, type, as, property, options));
|
|
47
49
|
}
|
|
@@ -5,10 +5,11 @@ import { type TTemplateLiteral } from '../../types/template-literal.mjs';
|
|
|
5
5
|
import { type TUnion } from '../../types/union.mjs';
|
|
6
6
|
import { type TEnumValuesToVariants } from '../enum/index.mjs';
|
|
7
7
|
import { type TTemplateLiteralDecode } from '../template-literal/decode.mjs';
|
|
8
|
-
type TFromTemplateLiteral<Pattern extends string, Decoded extends TSchema = TTemplateLiteralDecode<Pattern>, Result extends TSchema = TFromType<Decoded>> = Result;
|
|
8
|
+
type TFromTemplateLiteral<Pattern extends string, Decoded extends TSchema = TTemplateLiteralDecode<Pattern>, Result extends TSchema[] = TFromType<Decoded>> = Result;
|
|
9
9
|
type TFromUnion<Types extends TSchema[], Result extends TSchema[] = []> = (Types extends [infer Left extends TSchema, ...infer Right extends TSchema[]] ? TFromUnion<Right, [...Result, ...TFromType<Left>]> : Result);
|
|
10
10
|
type TFromType<Type extends TSchema, Result extends TSchema[] = (Type extends TEnum<infer Values extends TEnumValue[]> ? TFromUnion<TEnumValuesToVariants<Values>> : Type extends TLiteral<string | number> ? [Type] : Type extends TTemplateLiteral<infer Pattern extends string> ? TFromTemplateLiteral<Pattern> : Type extends TUnion<infer Types extends TSchema[]> ? TFromUnion<Types> : [
|
|
11
|
+
Type
|
|
11
12
|
])> = Result;
|
|
12
|
-
export type
|
|
13
|
-
export declare function
|
|
13
|
+
export type TMappedVariants<Type extends TSchema, Result extends TSchema[] = TFromType<Type>> = Result;
|
|
14
|
+
export declare function MappedVariants<Type extends TSchema>(type: Type): TMappedVariants<Type>;
|
|
14
15
|
export {};
|
|
@@ -20,10 +20,10 @@ function FromType(type) {
|
|
|
20
20
|
IsLiteralString(type) || IsLiteralNumber(type) ? [type] :
|
|
21
21
|
IsTemplateLiteral(type) ? FromTemplateLiteral(type.pattern) :
|
|
22
22
|
IsUnion(type) ? FromUnion(type.anyOf) :
|
|
23
|
-
[]);
|
|
23
|
+
[type]);
|
|
24
24
|
return result;
|
|
25
25
|
}
|
|
26
|
-
export function
|
|
26
|
+
export function MappedVariants(type) {
|
|
27
27
|
const result = FromType(type);
|
|
28
28
|
return result;
|
|
29
29
|
}
|
|
@@ -274,7 +274,7 @@ export type TMappedOptionalMapping<Input extends [unknown, unknown] | [unknown]
|
|
|
274
274
|
export declare function MappedOptionalMapping(input: [unknown, unknown] | [unknown] | []): unknown;
|
|
275
275
|
export type TMappedAsMapping<Input extends [unknown, unknown] | []> = (Input extends ['as', infer Type extends T.TSchema] ? [Type] : []);
|
|
276
276
|
export declare function MappedAsMapping(input: [unknown, unknown] | []): unknown;
|
|
277
|
-
export type TMappedMapping<Input extends [unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown]> = (Input extends ['{', infer Readonly extends TModifierOperation, '[', infer Key extends string, 'in', infer
|
|
277
|
+
export type TMappedMapping<Input extends [unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown]> = (Input extends ['{', infer Readonly extends TModifierOperation, '[', infer Key extends string, 'in', infer Type extends T.TSchema, infer As extends T.TSchema[], ']', infer Optional extends TModifierOperation, ':', infer Property extends T.TSchema, null, '}'] ? (As extends [infer As extends T.TSchema] ? C.TMappedDeferred<T.TIdentifier<Key>, Type, As, TApplyReadonly<Readonly, TApplyOptional<Optional, Property>>> : C.TMappedDeferred<T.TIdentifier<Key>, Type, T.TRef<Key>, TApplyReadonly<Readonly, TApplyOptional<Optional, Property>>>) : never);
|
|
278
278
|
export declare function MappedMapping(input: [unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown]): unknown;
|
|
279
279
|
export type TReferenceMapping<Input extends string, Result extends T.TSchema = T.TRef<Input>> = Result;
|
|
280
280
|
export declare function ReferenceMapping(input: string): unknown;
|