typebox 1.3.11 → 1.3.12
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/date.d.mts +1 -1
- package/build/format/date.mjs +1 -1
- package/build/format/date_time.d.mts +2 -2
- package/build/format/date_time.mjs +3 -3
- package/build/format/email.d.mts +1 -1
- package/build/format/email.mjs +2 -2
- package/build/format/hostname.mjs +2 -10
- package/build/format/idn_email.d.mts +1 -1
- package/build/format/idn_email.mjs +3 -3
- package/build/format/idn_hostname.d.mts +1 -0
- package/build/format/idn_hostname.mjs +3 -11
- package/build/format/idna/format/bidi.d.mts +3 -0
- package/build/format/idna/format/bidi.mjs +98 -0
- package/build/format/idna/format/puny.d.mts +3 -0
- package/build/format/idna/format/puny.mjs +144 -0
- package/build/format/idna/hostname.d.mts +1 -0
- package/build/format/idna/hostname.mjs +16 -0
- package/build/format/idna/idn-hostname.d.mts +1 -0
- package/build/format/idna/idn-hostname.mjs +23 -0
- package/build/format/idna/index.d.mts +2 -0
- package/build/format/idna/index.mjs +2 -0
- package/build/format/idna/label/ascii.d.mts +1 -0
- package/build/format/idna/label/ascii.mjs +9 -0
- package/build/format/idna/label/puny.d.mts +1 -0
- package/build/format/idna/label/puny.mjs +28 -0
- package/build/format/idna/label/unicode.d.mts +1 -0
- package/build/format/idna/label/unicode.mjs +106 -0
- package/build/format/idna/pattern/pattern.d.mts +30 -0
- package/build/format/idna/pattern/pattern.mjs +70 -0
- package/build/format/ipv4.d.mts +0 -1
- package/build/format/ipv4.mjs +2 -32
- package/build/format/ipv6.mjs +2 -61
- package/build/format/iri.d.mts +1 -1
- package/build/format/iri.mjs +2 -8
- package/build/format/iri_reference.d.mts +2 -2
- package/build/format/iri_reference.mjs +9 -55
- package/build/format/regex.d.mts +1 -2
- package/build/format/regex.mjs +2 -6
- package/build/format/time.d.mts +2 -2
- package/build/format/time.mjs +19 -14
- package/build/format/uri.mjs +2 -129
- package/build/format/uri_template.d.mts +0 -1
- package/build/format/uri_template.mjs +1 -2
- package/build/format/url.d.mts +2 -2
- package/build/format/url.mjs +3 -4
- package/build/guard/guard.mjs +2 -2
- package/build/guard/string.d.mts +2 -2
- package/build/guard/string.mjs +6 -6
- package/build/schema/engine/_regexp.d.mts +2 -0
- package/build/schema/engine/_regexp.mjs +4 -0
- package/build/schema/engine/_stack.mjs +1 -1
- package/build/schema/engine/additionalProperties.mjs +4 -3
- package/build/schema/engine/pattern.mjs +3 -2
- package/build/schema/engine/patternProperties.mjs +4 -3
- package/build/schema/engine/schema.mjs +13 -4
- package/build/schema/resolve/ref.d.mts +1 -0
- package/build/schema/resolve/ref.mjs +13 -3
- package/build/schema/types/index.d.mts +0 -2
- package/build/schema/types/index.mjs +0 -2
- package/package.json +1 -1
- package/build/format/_idna.d.mts +0 -2
- package/build/format/_idna.mjs +0 -246
- package/build/format/_puny.d.mts +0 -1
- package/build/format/_puny.mjs +0 -77
- package/build/schema/types/contentEncoding.d.mts +0 -9
- package/build/schema/types/contentEncoding.mjs +0 -13
- package/build/schema/types/contentMediaType.d.mts +0 -9
- package/build/schema/types/contentMediaType.mjs +0 -13
|
@@ -3,6 +3,7 @@ import * as S from '../types/index.mjs';
|
|
|
3
3
|
import * as V from './_externals.mjs';
|
|
4
4
|
import { Unique } from './_unique.mjs';
|
|
5
5
|
import { AccumulatedErrorContext } from './_context.mjs';
|
|
6
|
+
import { UnicodeRegExp } from './_regexp.mjs';
|
|
6
7
|
import { EmitGuard as E, Guard as G } from '../../guard/index.mjs';
|
|
7
8
|
import { BuildSchemaPushStack, CheckSchemaPushStack, ErrorSchemaPushStack } from './schema.mjs';
|
|
8
9
|
// ------------------------------------------------------------------
|
|
@@ -58,7 +59,7 @@ export function BuildAdditionalPropertiesFast(_context, schema, value) {
|
|
|
58
59
|
// ------------------------------------------------------------------
|
|
59
60
|
export function BuildAdditionalPropertiesStandard(stack, context, schema, value) {
|
|
60
61
|
const [key, _index] = [Unique(), Unique()];
|
|
61
|
-
const regexp = V.CreateVariable(
|
|
62
|
+
const regexp = V.CreateVariable(UnicodeRegExp(GetPropertiesPattern(schema)));
|
|
62
63
|
const isSchema = BuildSchemaPushStack(stack, context, schema.additionalProperties, `${value}[${key}]`);
|
|
63
64
|
const isKey = E.Call(E.Member(regexp, 'test'), [key]);
|
|
64
65
|
const addKey = context.AddKey(key);
|
|
@@ -78,7 +79,7 @@ export function BuildAdditionalProperties(stack, context, schema, value) {
|
|
|
78
79
|
// Check
|
|
79
80
|
// ------------------------------------------------------------------
|
|
80
81
|
export function CheckAdditionalProperties(stack, context, schema, value) {
|
|
81
|
-
const regexp =
|
|
82
|
+
const regexp = UnicodeRegExp(GetPropertiesPattern(schema));
|
|
82
83
|
const isAdditionalProperties = G.Every(G.Keys(value), 0, (key, _index) => {
|
|
83
84
|
return regexp.test(key) ||
|
|
84
85
|
(CheckSchemaPushStack(stack, context, schema.additionalProperties, value[key]) && context.AddKey(key));
|
|
@@ -89,7 +90,7 @@ export function CheckAdditionalProperties(stack, context, schema, value) {
|
|
|
89
90
|
// Error
|
|
90
91
|
// ------------------------------------------------------------------
|
|
91
92
|
export function ErrorAdditionalProperties(stack, context, schemaPath, instancePath, schema, value) {
|
|
92
|
-
const regexp =
|
|
93
|
+
const regexp = UnicodeRegExp(GetPropertiesPattern(schema));
|
|
93
94
|
const additionalProperties = [];
|
|
94
95
|
const isAdditionalProperties = G.EveryAll(G.Keys(value), 0, (key, _index) => {
|
|
95
96
|
const nextSchemaPath = `${schemaPath}/additionalProperties`;
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
// deno-fmt-ignore-file
|
|
2
2
|
import * as Externals from './_externals.mjs';
|
|
3
3
|
import { Guard as G, EmitGuard as E } from '../../guard/index.mjs';
|
|
4
|
+
import { UnicodeRegExp } from './_regexp.mjs';
|
|
4
5
|
// ------------------------------------------------------------------
|
|
5
6
|
// Build
|
|
6
7
|
// ------------------------------------------------------------------
|
|
7
8
|
export function BuildPattern(_stack, _context, schema, value) {
|
|
8
|
-
const regexp = Externals.CreateVariable(G.IsString(schema.pattern) ?
|
|
9
|
+
const regexp = Externals.CreateVariable(G.IsString(schema.pattern) ? UnicodeRegExp(schema.pattern) : schema.pattern);
|
|
9
10
|
return E.Call(E.Member(regexp, 'test'), [value]);
|
|
10
11
|
}
|
|
11
12
|
// ------------------------------------------------------------------
|
|
12
13
|
// Check
|
|
13
14
|
// ------------------------------------------------------------------
|
|
14
15
|
export function CheckPattern(_stack, _context, schema, value) {
|
|
15
|
-
const regexp = G.IsString(schema.pattern) ?
|
|
16
|
+
const regexp = G.IsString(schema.pattern) ? UnicodeRegExp(schema.pattern) : schema.pattern;
|
|
16
17
|
return regexp.test(value);
|
|
17
18
|
}
|
|
18
19
|
// ------------------------------------------------------------------
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// deno-fmt-ignore-file
|
|
2
2
|
import * as Externals from './_externals.mjs';
|
|
3
3
|
import { Unique } from './_unique.mjs';
|
|
4
|
+
import { UnicodeRegExp } from './_regexp.mjs';
|
|
4
5
|
import { Guard as G, EmitGuard as E } from '../../guard/index.mjs';
|
|
5
6
|
import { BuildSchemaPushStack, CheckSchemaPushStack, ErrorSchemaPushStack } from './schema.mjs';
|
|
6
7
|
// ------------------------------------------------------------------
|
|
@@ -9,7 +10,7 @@ import { BuildSchemaPushStack, CheckSchemaPushStack, ErrorSchemaPushStack } from
|
|
|
9
10
|
export function BuildPatternProperties(stack, context, schema, value) {
|
|
10
11
|
return E.ReduceAnd(G.Entries(schema.patternProperties).map(([pattern, schema]) => {
|
|
11
12
|
const [key, prop] = [Unique(), Unique()];
|
|
12
|
-
const regexp = Externals.CreateVariable(
|
|
13
|
+
const regexp = Externals.CreateVariable(UnicodeRegExp(pattern));
|
|
13
14
|
const notKey = E.Not(E.Call(E.Member(regexp, 'test'), [key]));
|
|
14
15
|
const isSchema = BuildSchemaPushStack(stack, context, schema, prop);
|
|
15
16
|
const addKey = context.AddKey(key);
|
|
@@ -22,7 +23,7 @@ export function BuildPatternProperties(stack, context, schema, value) {
|
|
|
22
23
|
// ------------------------------------------------------------------
|
|
23
24
|
export function CheckPatternProperties(stack, context, schema, value) {
|
|
24
25
|
return G.Every(G.Entries(schema.patternProperties), 0, ([pattern, schema]) => {
|
|
25
|
-
const regexp =
|
|
26
|
+
const regexp = UnicodeRegExp(pattern);
|
|
26
27
|
return G.Every(G.Entries(value), 0, ([key, prop]) => {
|
|
27
28
|
return !regexp.test(key) || CheckSchemaPushStack(stack, context, schema, prop) && context.AddKey(key);
|
|
28
29
|
});
|
|
@@ -34,7 +35,7 @@ export function CheckPatternProperties(stack, context, schema, value) {
|
|
|
34
35
|
export function ErrorPatternProperties(stack, context, schemaPath, instancePath, schema, value) {
|
|
35
36
|
return G.EveryAll(G.Entries(schema.patternProperties), 0, ([pattern, schema]) => {
|
|
36
37
|
const nextSchemaPath = `${schemaPath}/patternProperties/${pattern}`;
|
|
37
|
-
const regexp =
|
|
38
|
+
const regexp = UnicodeRegExp(pattern);
|
|
38
39
|
return G.EveryAll(G.Entries(value), 0, ([key, value]) => {
|
|
39
40
|
const nextInstancePath = `${instancePath}/${key}`;
|
|
40
41
|
const notKey = !regexp.test(key);
|
|
@@ -45,12 +45,21 @@ import { BuildUnevaluatedItems, CheckUnevaluatedItems, ErrorUnevaluatedItems } f
|
|
|
45
45
|
import { BuildUnevaluatedProperties, CheckUnevaluatedProperties, ErrorUnevaluatedProperties } from './unevaluatedProperties.mjs';
|
|
46
46
|
import { BuildUniqueItems, CheckUniqueItems, ErrorUniqueItems } from './uniqueItems.mjs';
|
|
47
47
|
// ----------------------------------------------------------------
|
|
48
|
-
// HasTypeName
|
|
48
|
+
// HasTypeName (Optimization)
|
|
49
|
+
//
|
|
50
|
+
// We only consider a schema as having a type name when the schema
|
|
51
|
+
// has a single type string, or when every element in the type
|
|
52
|
+
// array is the same. For a type array, we must treat multi-variant
|
|
53
|
+
// types as unions and therefore can NOT use an optimized forward
|
|
54
|
+
// type check.
|
|
55
|
+
//
|
|
49
56
|
// ----------------------------------------------------------------
|
|
50
57
|
function HasTypeName(schema, typename) {
|
|
51
|
-
return Schema.IsType(schema) &&
|
|
52
|
-
(G.IsArray(schema.type) &&
|
|
53
|
-
G.
|
|
58
|
+
return (Schema.IsType(schema) &&
|
|
59
|
+
((G.IsArray(schema.type) &&
|
|
60
|
+
G.IsGreaterThan(schema.type.length, 0) &&
|
|
61
|
+
G.Every(schema.type, 0, type => G.IsEqual(type, typename))) ||
|
|
62
|
+
G.IsEqual(schema.type, typename)));
|
|
54
63
|
}
|
|
55
64
|
// ----------------------------------------------------------------
|
|
56
65
|
// HasObject
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import * as Schema from '../types/index.mjs';
|
|
2
|
+
export declare const DefaultBase: URL;
|
|
2
3
|
export declare function Ref(schema: Schema.XSchemaObject, ref: string): Schema.XSchema | undefined;
|
|
3
4
|
export declare function DynamicRef(root: Schema.XSchemaObject, base: Schema.XSchemaObject, dynamicRef: Schema.XDynamicRef, dynamicAnchors: Schema.XDynamicAnchor[]): Schema.XSchema | undefined;
|
|
@@ -3,6 +3,10 @@ import { Guard } from '../../guard/index.mjs';
|
|
|
3
3
|
import { Pointer } from '../pointer/index.mjs';
|
|
4
4
|
import * as Schema from '../types/index.mjs';
|
|
5
5
|
// ------------------------------------------------------------------
|
|
6
|
+
// DefaultBase
|
|
7
|
+
// ------------------------------------------------------------------
|
|
8
|
+
export const DefaultBase = new URL('https://json-schema.org');
|
|
9
|
+
// ------------------------------------------------------------------
|
|
6
10
|
// Match: Id
|
|
7
11
|
// ------------------------------------------------------------------
|
|
8
12
|
function MatchId(schema, base, ref) {
|
|
@@ -83,8 +87,15 @@ function FromArray(schema, base, ref) {
|
|
|
83
87
|
// ------------------------------------------------------------------
|
|
84
88
|
// FromObject
|
|
85
89
|
// ------------------------------------------------------------------
|
|
90
|
+
function SkipProperty(key) {
|
|
91
|
+
// these are explicit data encoded in a schema, they should not
|
|
92
|
+
// be considered valid targets used for de-referencing.
|
|
93
|
+
return Guard.IsEqual(key, 'const') || Guard.IsEqual(key, 'enum');
|
|
94
|
+
}
|
|
86
95
|
function FromObject(schema, base, ref) {
|
|
87
96
|
return Guard.Keys(schema).reduce((result, key) => {
|
|
97
|
+
if (SkipProperty(key))
|
|
98
|
+
return result;
|
|
88
99
|
const match = FromValue(schema[key], base, ref);
|
|
89
100
|
return !Guard.IsUndefined(match) ? match : result;
|
|
90
101
|
}, undefined);
|
|
@@ -111,8 +122,7 @@ function FromValue(schema, base, ref) {
|
|
|
111
122
|
// Ref
|
|
112
123
|
// ------------------------------------------------------------------
|
|
113
124
|
export function Ref(schema, ref) {
|
|
114
|
-
const
|
|
115
|
-
const initialBase = Schema.IsId(schema) ? new URL(schema.$id, defaultBase.href) : defaultBase;
|
|
125
|
+
const initialBase = Schema.IsId(schema) ? new URL(schema.$id, DefaultBase.href) : DefaultBase;
|
|
116
126
|
const initialRef = new URL(ref, initialBase.href);
|
|
117
127
|
return FromValue(schema, initialBase, initialRef);
|
|
118
128
|
}
|
|
@@ -134,7 +144,7 @@ export function DynamicRef(root, base, dynamicRef, dynamicAnchors) {
|
|
|
134
144
|
// Extract the fragment portion of the reference. According to the test suite,
|
|
135
145
|
// only plain fragment names (e.g., "#foo") trigger the dynamic scope; JSON
|
|
136
146
|
// Pointer fragments (e.g., "#/definitions/foo") bypass dynamic resolution.
|
|
137
|
-
const fragment = new URL(dynamicRef.$dynamicRef,
|
|
147
|
+
const fragment = new URL(dynamicRef.$dynamicRef, DefaultBase).hash;
|
|
138
148
|
if (fragment.startsWith('#/'))
|
|
139
149
|
return fragmentTarget;
|
|
140
150
|
// Search the live dynamic anchor stack for a schema whose $dynamicAnchor matches the
|
|
@@ -6,8 +6,6 @@ export * from './anchor.mjs';
|
|
|
6
6
|
export * from './anyOf.mjs';
|
|
7
7
|
export * from './const.mjs';
|
|
8
8
|
export * from './contains.mjs';
|
|
9
|
-
export * from './contentEncoding.mjs';
|
|
10
|
-
export * from './contentMediaType.mjs';
|
|
11
9
|
export * from './default.mjs';
|
|
12
10
|
export * from './defs.mjs';
|
|
13
11
|
export * from './dependencies.mjs';
|
|
@@ -12,8 +12,6 @@ export * from './anchor.mjs';
|
|
|
12
12
|
export * from './anyOf.mjs';
|
|
13
13
|
export * from './const.mjs';
|
|
14
14
|
export * from './contains.mjs';
|
|
15
|
-
export * from './contentEncoding.mjs';
|
|
16
|
-
export * from './contentMediaType.mjs';
|
|
17
15
|
export * from './default.mjs';
|
|
18
16
|
export * from './defs.mjs';
|
|
19
17
|
export * from './dependencies.mjs';
|
package/package.json
CHANGED
package/build/format/_idna.d.mts
DELETED
package/build/format/_idna.mjs
DELETED
|
@@ -1,246 +0,0 @@
|
|
|
1
|
-
import { Unreachable } from '../system/unreachable/index.mjs';
|
|
2
|
-
import * as Puny from './_puny.mjs';
|
|
3
|
-
// ------------------------------------------------------------------
|
|
4
|
-
// Unicode General Category Helper (RFC 5892)
|
|
5
|
-
// ------------------------------------------------------------------
|
|
6
|
-
function IsNonspacingMark(cp) {
|
|
7
|
-
return /\p{Mn}/u.test(String.fromCodePoint(cp));
|
|
8
|
-
}
|
|
9
|
-
function IsSpacingCombiningMark(cp) {
|
|
10
|
-
return /\p{Mc}/u.test(String.fromCodePoint(cp));
|
|
11
|
-
}
|
|
12
|
-
function IsEnclosingMark(cp) {
|
|
13
|
-
return /\p{Me}/u.test(String.fromCodePoint(cp));
|
|
14
|
-
}
|
|
15
|
-
function IsCombiningMark(cp) {
|
|
16
|
-
return IsNonspacingMark(cp) || IsSpacingCombiningMark(cp) || IsEnclosingMark(cp);
|
|
17
|
-
}
|
|
18
|
-
// ------------------------------------------------------------------
|
|
19
|
-
// RFC 5892 §2.6 DISALLOWED exceptions
|
|
20
|
-
//
|
|
21
|
-
// https://tools.ietf.org/html/rfc5892#section-2.6
|
|
22
|
-
// ------------------------------------------------------------------
|
|
23
|
-
const RFC5892_DISALLOWED = new Set([
|
|
24
|
-
0x0640, // ARABIC TATWEEL
|
|
25
|
-
0x07fa, // NKO LAJANYALAN
|
|
26
|
-
0x302e, // HANGUL SINGLE DOT TONE MARK
|
|
27
|
-
0x302f, // HANGUL DOUBLE DOT TONE MARK
|
|
28
|
-
0x3031, // VERTICAL KANA REPEAT MARK
|
|
29
|
-
0x3032, // VERTICAL KANA REPEAT WITH VOICED ITERATION MARK
|
|
30
|
-
0x3033, // VERTICAL KANA REPEAT MARK UPPER HALF
|
|
31
|
-
0x3034, // VERTICAL KANA REPEAT WITH VOICED ITERATION MARK UPPER HALF
|
|
32
|
-
0x3035, // VERTICAL KANA REPEAT MARK LOWER HALF
|
|
33
|
-
0x303b // VERTICAL IDEOGRAPHIC ITERATION MARK
|
|
34
|
-
]);
|
|
35
|
-
// ------------------------------------------------------------------
|
|
36
|
-
// A set of Virama (halant) code points used to validate CONTEXTJ
|
|
37
|
-
// rules (RFC 5892 Appendix A.1). These characters allow a subsequent
|
|
38
|
-
// Zero Width Non-Joiner (U+200C) or Zero Width Joiner (U+200D) to
|
|
39
|
-
// be valid in a label.
|
|
40
|
-
// ------------------------------------------------------------------
|
|
41
|
-
const VIRAMA_CPS = new Set([
|
|
42
|
-
0x094d,
|
|
43
|
-
0x09cd,
|
|
44
|
-
0x0a4d,
|
|
45
|
-
0x0acd,
|
|
46
|
-
0x0b4d,
|
|
47
|
-
0x0bcd,
|
|
48
|
-
0x0c4d,
|
|
49
|
-
0x0ccd,
|
|
50
|
-
0x0d3b,
|
|
51
|
-
0x0d3c,
|
|
52
|
-
0x0d4d,
|
|
53
|
-
0x0dca,
|
|
54
|
-
0x1b44,
|
|
55
|
-
0x1baa,
|
|
56
|
-
0x1bab,
|
|
57
|
-
0xa9c0,
|
|
58
|
-
0x11046,
|
|
59
|
-
0x1107f,
|
|
60
|
-
0x110b9,
|
|
61
|
-
0x11133,
|
|
62
|
-
0x11134,
|
|
63
|
-
0x111c0,
|
|
64
|
-
0x11235,
|
|
65
|
-
0x1134d,
|
|
66
|
-
0x11442,
|
|
67
|
-
0x114c2,
|
|
68
|
-
0x115bf,
|
|
69
|
-
0x1163f,
|
|
70
|
-
0x116b6,
|
|
71
|
-
0x11c3f,
|
|
72
|
-
0x11d44,
|
|
73
|
-
0x11d45
|
|
74
|
-
]);
|
|
75
|
-
// ------------------------------------------------------------------
|
|
76
|
-
// Guards for CONTEXTO rules (RFC 5892 Appendix A)
|
|
77
|
-
// ------------------------------------------------------------------
|
|
78
|
-
function IsGreek(cp) {
|
|
79
|
-
return /\p{Script=Greek}/u.test(String.fromCodePoint(cp));
|
|
80
|
-
}
|
|
81
|
-
function IsHebrew(cp) {
|
|
82
|
-
return /\p{Script=Hebrew}/u.test(String.fromCodePoint(cp));
|
|
83
|
-
}
|
|
84
|
-
function IsHiragana(cp) {
|
|
85
|
-
return /\p{Script=Hiragana}/u.test(String.fromCodePoint(cp));
|
|
86
|
-
}
|
|
87
|
-
function IsKatakana(cp) {
|
|
88
|
-
return /\p{Script=Katakana}/u.test(String.fromCodePoint(cp));
|
|
89
|
-
}
|
|
90
|
-
function IsHan(cp) {
|
|
91
|
-
return /\p{Script=Han}/u.test(String.fromCodePoint(cp));
|
|
92
|
-
}
|
|
93
|
-
function IsArabicIndicDigit(cp) {
|
|
94
|
-
return cp >= 0x0660 && cp <= 0x0669;
|
|
95
|
-
}
|
|
96
|
-
function IsExtendedArabicIndicDigit(cp) {
|
|
97
|
-
return cp >= 0x06f0 && cp <= 0x06f9;
|
|
98
|
-
}
|
|
99
|
-
function IsVirama(cp) {
|
|
100
|
-
return VIRAMA_CPS.has(cp);
|
|
101
|
-
}
|
|
102
|
-
// ------------------------------------------------------------------
|
|
103
|
-
// IsUnicodeLabel
|
|
104
|
-
// ------------------------------------------------------------------
|
|
105
|
-
function IsUnicodeLabel(value) {
|
|
106
|
-
// deno-coverage-ignore-start - unable to reach via format guards
|
|
107
|
-
if (value.length === 0)
|
|
108
|
-
return Unreachable(); // false
|
|
109
|
-
// deno-coverage-ignore-stop
|
|
110
|
-
// Use spread to handle surrogate pairs and provide O(1) neighbor access
|
|
111
|
-
const cps = [...value].map((c) => c.codePointAt(0));
|
|
112
|
-
const len = cps.length;
|
|
113
|
-
// RFC 5891 §4.2.3.2: Hyphen rules
|
|
114
|
-
if (cps[0] === 0x2d || cps[len - 1] === 0x2d)
|
|
115
|
-
return false;
|
|
116
|
-
if (len >= 4 && cps[2] === 0x2d && cps[3] === 0x2d)
|
|
117
|
-
return false;
|
|
118
|
-
// RFC 5891 §4.2.3.2 - Must not begin with a combining mark
|
|
119
|
-
if (IsCombiningMark(cps[0]))
|
|
120
|
-
return false;
|
|
121
|
-
let hasJapanese = false;
|
|
122
|
-
let hasArabicIndic = false;
|
|
123
|
-
let hasExtendedArabicIndic = false;
|
|
124
|
-
for (let i = 0; i < len; i++) {
|
|
125
|
-
const cp = cps[i];
|
|
126
|
-
// 1. DISALLOWED exceptions
|
|
127
|
-
if (RFC5892_DISALLOWED.has(cp))
|
|
128
|
-
return false;
|
|
129
|
-
// 2. Collect Flags
|
|
130
|
-
if (IsHiragana(cp) || IsKatakana(cp) || IsHan(cp))
|
|
131
|
-
hasJapanese = true;
|
|
132
|
-
if (IsArabicIndicDigit(cp))
|
|
133
|
-
hasArabicIndic = true;
|
|
134
|
-
if (IsExtendedArabicIndicDigit(cp))
|
|
135
|
-
hasExtendedArabicIndic = true;
|
|
136
|
-
// 3. CONTEXTO / CONTEXTJ Neighbor Rules
|
|
137
|
-
const prev = cps[i - 1], next = cps[i + 1];
|
|
138
|
-
switch (cp) {
|
|
139
|
-
case 0x00b7:
|
|
140
|
-
if (prev !== 0x006c || next !== 0x006c)
|
|
141
|
-
return false;
|
|
142
|
-
break; // MIDDLE DOT (Catalan)
|
|
143
|
-
case 0x0375:
|
|
144
|
-
if (next === undefined || !IsGreek(next))
|
|
145
|
-
return false;
|
|
146
|
-
break; // Greek KERAIA
|
|
147
|
-
case 0x05f3:
|
|
148
|
-
case 0x05f4:
|
|
149
|
-
if (prev === undefined || !IsHebrew(prev))
|
|
150
|
-
return false;
|
|
151
|
-
break; // Hebrew GERESH
|
|
152
|
-
case 0x200c: // ZWNJ - RFC 5892 Appendix A.1
|
|
153
|
-
// Note: Full validation requires a Unicode joining type table. We reject
|
|
154
|
-
// only when preceded by ASCII (U+0000-U+007F), which can never satisfy
|
|
155
|
-
// the Virama or cursive-joining rules.
|
|
156
|
-
if (prev === undefined || (prev < 0x0080 && !IsVirama(prev)))
|
|
157
|
-
return false;
|
|
158
|
-
break;
|
|
159
|
-
case 0x200d: // ZWJ - RFC 5892 Appendix A.2
|
|
160
|
-
if (prev === undefined || !IsVirama(prev))
|
|
161
|
-
return false;
|
|
162
|
-
break;
|
|
163
|
-
case 0x30fb: /* Checked at end via hasJapanese */
|
|
164
|
-
break; // KATAKANA MIDDLE DOT
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
// 4. Global Context Validations (Post-loop)
|
|
168
|
-
// RFC 5892 Appendix A.7 - Katakana Middle Dot requirement
|
|
169
|
-
if (value.includes('\u30fb') && !hasJapanese)
|
|
170
|
-
return false;
|
|
171
|
-
// RFC 5892 Appendix A.8/A.9 - Mixing Arabic Digits
|
|
172
|
-
if (hasArabicIndic && hasExtendedArabicIndic)
|
|
173
|
-
return false;
|
|
174
|
-
return true;
|
|
175
|
-
}
|
|
176
|
-
// ------------------------------------------------------------------
|
|
177
|
-
// IsAsciiLabel
|
|
178
|
-
// ------------------------------------------------------------------
|
|
179
|
-
function IsAsciiLabel(value) {
|
|
180
|
-
// Must not start or end with a hyphen
|
|
181
|
-
if (value.charCodeAt(0) === 45 || value.charCodeAt(value.length - 1) === 45)
|
|
182
|
-
return false;
|
|
183
|
-
// RFC 5891 §4.2.3.1 : "--" at positions 3-4 is reserved for A-labels only
|
|
184
|
-
if (value.length >= 4 && value.charCodeAt(2) === 45 && value.charCodeAt(3) === 45)
|
|
185
|
-
return false;
|
|
186
|
-
// All characters must be alphanumeric or hyphen
|
|
187
|
-
for (let i = 0; i < value.length; i++) {
|
|
188
|
-
const ch = value.charCodeAt(i);
|
|
189
|
-
if (!((ch >= 97 && ch <= 122) || // a-z
|
|
190
|
-
(ch >= 65 && ch <= 90) || // A-Z
|
|
191
|
-
(ch >= 48 && ch <= 57) || // 0-9
|
|
192
|
-
ch === 45 // '-'
|
|
193
|
-
))
|
|
194
|
-
return false;
|
|
195
|
-
}
|
|
196
|
-
return true;
|
|
197
|
-
}
|
|
198
|
-
// ------------------------------------------------------------------
|
|
199
|
-
// IsPunyLabel
|
|
200
|
-
// ------------------------------------------------------------------
|
|
201
|
-
function IsPuny(value) {
|
|
202
|
-
return value.toLowerCase().startsWith('xn--');
|
|
203
|
-
}
|
|
204
|
-
function IsPunyLabel(value) {
|
|
205
|
-
try {
|
|
206
|
-
const payload = value.slice(4).toLowerCase();
|
|
207
|
-
// 1. Structural Validation (RFC 3492 syntax)
|
|
208
|
-
//
|
|
209
|
-
// If the payload contains a hyphen, it MUST be a delimiter separating basic
|
|
210
|
-
// ASCII characters from the variable-length integers. A payload consisting
|
|
211
|
-
// of ONLY a hyphen or starting with multiple hyphens without basic ASCII
|
|
212
|
-
// characters (like "-9uc") is fundamentally malformed.
|
|
213
|
-
//
|
|
214
|
-
const lastHyphen = payload.lastIndexOf('-');
|
|
215
|
-
if (lastHyphen === 0) {
|
|
216
|
-
// Catches "-9uc" right here because the delimiter is at index 0, meaning 0
|
|
217
|
-
// basic ASCII characters preceded it, which is non-canonical.
|
|
218
|
-
return false;
|
|
219
|
-
}
|
|
220
|
-
// 2. Decode the payload
|
|
221
|
-
const decoded = Puny.Decode(payload);
|
|
222
|
-
if (!decoded)
|
|
223
|
-
return false;
|
|
224
|
-
// 3. Validate the output rules against RFC 5892
|
|
225
|
-
return IsUnicodeLabel(decoded);
|
|
226
|
-
}
|
|
227
|
-
catch {
|
|
228
|
-
return false;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
// ------------------------------------------------------------------
|
|
232
|
-
// IsIdnLabel
|
|
233
|
-
// ------------------------------------------------------------------
|
|
234
|
-
export function IsIdnLabel(value) {
|
|
235
|
-
if (value.length === 0 || value.length > 63)
|
|
236
|
-
return false;
|
|
237
|
-
return IsPuny(value) ? IsPunyLabel(value) : IsUnicodeLabel(value);
|
|
238
|
-
}
|
|
239
|
-
// ------------------------------------------------------------------
|
|
240
|
-
// IsLabel
|
|
241
|
-
// ------------------------------------------------------------------
|
|
242
|
-
export function IsLabel(value) {
|
|
243
|
-
if (value.length === 0 || value.length > 63)
|
|
244
|
-
return false;
|
|
245
|
-
return IsPuny(value) ? IsPunyLabel(value) : IsAsciiLabel(value);
|
|
246
|
-
}
|
package/build/format/_puny.d.mts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function Decode(value: string): string;
|
package/build/format/_puny.mjs
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { Unreachable } from '../system/unreachable/index.mjs';
|
|
2
|
-
// ------------------------------------------------------------------
|
|
3
|
-
// PunyCode (RFC 3492)
|
|
4
|
-
// ------------------------------------------------------------------
|
|
5
|
-
const PUNYCODE_BASE = 36;
|
|
6
|
-
const PUNYCODE_TMIN = 1;
|
|
7
|
-
const PUNYCODE_TMAX = 26;
|
|
8
|
-
const PUNYCODE_SKEW = 38;
|
|
9
|
-
const PUNYCODE_DAMP = 700;
|
|
10
|
-
const PUNYCODE_INITIAL_BIAS = 72;
|
|
11
|
-
const PUNYCODE_INITIAL_N = 128;
|
|
12
|
-
// ------------------------------------------------------------------
|
|
13
|
-
// Adapt
|
|
14
|
-
// ------------------------------------------------------------------
|
|
15
|
-
function Adapt(delta, numPoints, firstTime) {
|
|
16
|
-
delta = firstTime ? Math.floor(delta / PUNYCODE_DAMP) : delta >> 1;
|
|
17
|
-
delta += Math.floor(delta / numPoints);
|
|
18
|
-
let k = 0;
|
|
19
|
-
while (delta > (((PUNYCODE_BASE - PUNYCODE_TMIN) * PUNYCODE_TMAX) >> 1)) {
|
|
20
|
-
delta = Math.floor(delta / (PUNYCODE_BASE - PUNYCODE_TMIN));
|
|
21
|
-
k += PUNYCODE_BASE;
|
|
22
|
-
}
|
|
23
|
-
return k + Math.floor(((PUNYCODE_BASE - PUNYCODE_TMIN + 1) * delta) / (delta + PUNYCODE_SKEW));
|
|
24
|
-
}
|
|
25
|
-
// ------------------------------------------------------------------
|
|
26
|
-
// Decode
|
|
27
|
-
// ------------------------------------------------------------------
|
|
28
|
-
export function Decode(value) {
|
|
29
|
-
const output = [];
|
|
30
|
-
let n = PUNYCODE_INITIAL_N;
|
|
31
|
-
let i = 0;
|
|
32
|
-
let bias = PUNYCODE_INITIAL_BIAS;
|
|
33
|
-
const delimIdx = value.lastIndexOf('-');
|
|
34
|
-
if (delimIdx > 0) {
|
|
35
|
-
for (let j = 0; j < delimIdx; j++) {
|
|
36
|
-
const cp = value.charCodeAt(j);
|
|
37
|
-
if (cp >= 128)
|
|
38
|
-
throw new Error('Invalid punycode: non-basic before delimiter');
|
|
39
|
-
output.push(cp);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
let inIdx = delimIdx < 0 ? 0 : delimIdx + 1;
|
|
43
|
-
while (inIdx < value.length) {
|
|
44
|
-
const oldi = i;
|
|
45
|
-
let w = 1;
|
|
46
|
-
let k = PUNYCODE_BASE;
|
|
47
|
-
while (true) {
|
|
48
|
-
if (inIdx >= value.length)
|
|
49
|
-
throw new Error('Invalid punycode: unexpected end of input');
|
|
50
|
-
const ch = value.charCodeAt(inIdx++);
|
|
51
|
-
let digit;
|
|
52
|
-
if (ch >= 0x61 && ch <= 0x7a)
|
|
53
|
-
digit = ch - 0x61; // a-z => 0-25
|
|
54
|
-
else if (ch >= 0x30 && ch <= 0x39)
|
|
55
|
-
digit = ch - 0x30 + 26; // 0-9 => 26-35
|
|
56
|
-
// deno-coverage-ignore-start - _idna.ts maps input to lowercase, so we can't reach here
|
|
57
|
-
else if (ch >= 0x41 && ch <= 0x5a)
|
|
58
|
-
Unreachable(); // digit = ch - 0x41 // A-Z => 0-25
|
|
59
|
-
// deno-coverage-ignore-stop
|
|
60
|
-
else
|
|
61
|
-
throw new Error('Invalid punycode: bad digit character');
|
|
62
|
-
i += digit * w;
|
|
63
|
-
const t = k <= bias ? PUNYCODE_TMIN : k >= bias + PUNYCODE_TMAX ? PUNYCODE_TMAX : k - bias;
|
|
64
|
-
if (digit < t)
|
|
65
|
-
break;
|
|
66
|
-
w *= PUNYCODE_BASE - t;
|
|
67
|
-
k += PUNYCODE_BASE;
|
|
68
|
-
}
|
|
69
|
-
const outLen = output.length + 1;
|
|
70
|
-
bias = Adapt(i - oldi, outLen, oldi === 0);
|
|
71
|
-
n += Math.floor(i / outLen);
|
|
72
|
-
i %= outLen;
|
|
73
|
-
output.splice(i, 0, n);
|
|
74
|
-
i++;
|
|
75
|
-
}
|
|
76
|
-
return globalThis.String.fromCodePoint(...output);
|
|
77
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { type XSchemaObject } from './schema.mjs';
|
|
2
|
-
export interface XContentEncoding<ContentEncoding extends string = string> {
|
|
3
|
-
contentEncoding: ContentEncoding;
|
|
4
|
-
}
|
|
5
|
-
/**
|
|
6
|
-
* Returns true if the schema contains a valid contentEncoding property
|
|
7
|
-
* @specification Json Schema 7
|
|
8
|
-
*/
|
|
9
|
-
export declare function IsContentEncoding(schema: XSchemaObject): schema is XContentEncoding;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
// deno-fmt-ignore-file
|
|
2
|
-
import { Guard } from '../../guard/index.mjs';
|
|
3
|
-
// ------------------------------------------------------------------
|
|
4
|
-
// Guard
|
|
5
|
-
// ------------------------------------------------------------------
|
|
6
|
-
/**
|
|
7
|
-
* Returns true if the schema contains a valid contentEncoding property
|
|
8
|
-
* @specification Json Schema 7
|
|
9
|
-
*/
|
|
10
|
-
export function IsContentEncoding(schema) {
|
|
11
|
-
return Guard.HasPropertyKey(schema, 'contentEncoding')
|
|
12
|
-
&& Guard.IsString(schema.contentEncoding);
|
|
13
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { type XSchemaObject } from './schema.mjs';
|
|
2
|
-
export interface XContentMediaType<ContentMediaType extends string = string> {
|
|
3
|
-
contentMediaType: ContentMediaType;
|
|
4
|
-
}
|
|
5
|
-
/**
|
|
6
|
-
* Returns true if the schema contains a valid contentMediaType property
|
|
7
|
-
* @specification Json Schema 7
|
|
8
|
-
*/
|
|
9
|
-
export declare function IsContentMediaType(schema: XSchemaObject): schema is XContentMediaType;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
// deno-fmt-ignore-file
|
|
2
|
-
import { Guard } from '../../guard/index.mjs';
|
|
3
|
-
// ------------------------------------------------------------------
|
|
4
|
-
// Guard
|
|
5
|
-
// ------------------------------------------------------------------
|
|
6
|
-
/**
|
|
7
|
-
* Returns true if the schema contains a valid contentMediaType property
|
|
8
|
-
* @specification Json Schema 7
|
|
9
|
-
*/
|
|
10
|
-
export function IsContentMediaType(schema) {
|
|
11
|
-
return Guard.HasPropertyKey(schema, 'contentMediaType')
|
|
12
|
-
&& Guard.IsString(schema.contentMediaType);
|
|
13
|
-
}
|