@json-schema-engine/formats 0.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Henry Andrews
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,45 @@
1
+ # @json-schema-engine/formats
2
+
3
+ Format implementations for `@json-schema-engine/core`'s format-assertion vocabulary and `assertFormats` configuration — `date`, `date-time`, `time`, `duration`, `email`, `hostname`, `ipv4`, `ipv6`, `uri`, `uri-reference`, `uri-template`, `iri`, `iri-reference`, `json-pointer`, `relative-json-pointer`, `regex`, `uuid`, and their per-dialect tables. Add this package when a schema needs `format` to actually reject bad values rather than only annotate them. Needs `@json-schema-engine/core` installed alongside.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ npm install @json-schema-engine/formats @json-schema-engine/core
9
+ ```
10
+
11
+ ## Example
12
+
13
+ ```ts
14
+ import assert from "node:assert";
15
+ import { createEngine } from "@json-schema-engine/core";
16
+ import { FORMATS_2020_12 } from "@json-schema-engine/formats";
17
+
18
+ const engine = createEngine({
19
+ formats: FORMATS_2020_12,
20
+ assertFormats: true,
21
+ });
22
+ const uri = engine.registerSchema(
23
+ { type: "string", format: "date" },
24
+ "https://example.com/date",
25
+ );
26
+
27
+ assert.equal(engine.evaluate(uri, "2024-01-15").valid, true);
28
+ assert.equal(engine.evaluate(uri, "not-a-date").valid, false);
29
+ ```
30
+
31
+ ## Status
32
+
33
+ Version 0.0.1 is published for initial public feedback on both the functionality and the documentation. APIs may change before 1.0. [STATUS.md](https://github.com/handrews/json-schema-engine/blob/main/STATUS.md) is the authoritative statement of what is built and what is staged.
34
+
35
+ ## Documentation
36
+
37
+ - [User guide](https://github.com/handrews/json-schema-engine/blob/main/docs/guide/index.md)
38
+ - [Validation](https://github.com/handrews/json-schema-engine/blob/main/docs/guide/validation.md)
39
+ - [Dialects](https://github.com/handrews/json-schema-engine/blob/main/docs/guide/dialects.md)
40
+ - [Conformance](https://github.com/handrews/json-schema-engine/blob/main/docs/conformance.md)
41
+ - [Repository](https://github.com/handrews/json-schema-engine)
42
+
43
+ ## License
44
+
45
+ MIT
package/dist/idn.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import type { FormatDefinition } from "@json-schema-engine/core";
2
+ export declare const idnHostname: FormatDefinition;
3
+ export declare const idnEmail: FormatDefinition;
4
+ //# sourceMappingURL=idn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"idn.d.ts","sourceRoot":"","sources":["../src/idn.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAyNjE,eAAO,MAAM,WAAW,EAAE,gBAEzB,CAAC;AAkFF,eAAO,MAAM,QAAQ,EAAE,gBAEtB,CAAC"}
package/dist/idn.js ADDED
@@ -0,0 +1,304 @@
1
+ // idn-hostname / idn-email (RFC 5890/5891/5892/5893, RFC 6531) — the
2
+ // U-label side of the IDNA2008 machinery in idna.ts. Implemented from the
3
+ // RFCs with Unicode data through ECMA-262's native \p{...} property
4
+ // escapes plus small cited tables (DESIGN.md D15).
5
+ import { decodePunycode, encodePunycode, isValidALabel, isValidIdnaLabel, } from "./idna.js";
6
+ // ---------------------------------------------------------------------------
7
+ // RFC 5892 derived-property approximation for U-label code points. PVALID's
8
+ // backbone is letters/digits/marks in lowercase or caseless form; uppercase
9
+ // (and anything case-unstable), symbols, punctuation, spaces, and controls
10
+ // are DISALLOWED. Context characters (Appendix A) are admitted here and
11
+ // judged by their rules in isValidIdnaLabel.
12
+ const LETTER_DIGIT_MARK = /^[\p{Ll}\p{Lo}\p{Lm}\p{Mn}\p{Mc}\p{Nd}]$/u;
13
+ const CONTEXT_CPS = new Set([
14
+ 0x200c, // ZWNJ (CONTEXTJ, A.1)
15
+ 0x200d, // ZWJ (CONTEXTJ, A.2)
16
+ 0x00b7, // MIDDLE DOT (A.3)
17
+ 0x0375, // GREEK KERAIA (A.4)
18
+ 0x05f3, // HEBREW GERESH (A.5)
19
+ 0x05f4, // HEBREW GERSHAYIM (A.6)
20
+ 0x30fb, // KATAKANA MIDDLE DOT (A.7)
21
+ ]);
22
+ // RFC 5892 §2.6 exceptions carrying PVALID despite their general
23
+ // category (punctuation/symbol/number-letter): TIBETAN TSHEG, IDEOGRAPHIC
24
+ // ZERO, the Sindhi Arabic signs. (ß/ς are Ll and need no exception here.)
25
+ const PVALID_EXCEPTIONS = new Set([0x0f0b, 0x3007, 0x06fd, 0x06fe]);
26
+ const allowedUnicodeCp = (cp) => {
27
+ if (PVALID_EXCEPTIONS.has(cp))
28
+ return true;
29
+ if (cp === 0x2d)
30
+ return true; // hyphen (LDH; placement rules elsewhere)
31
+ if (cp >= 0x30 && cp <= 0x39)
32
+ return true;
33
+ if (cp >= 0x61 && cp <= 0x7a)
34
+ return true;
35
+ if (cp < 0x80)
36
+ return false; // other ASCII: uppercase, symbols, dots…
37
+ if (CONTEXT_CPS.has(cp))
38
+ return true;
39
+ return LETTER_DIGIT_MARK.test(String.fromCodePoint(cp));
40
+ };
41
+ const R_RANGES = [
42
+ [0x05be, 0x05be],
43
+ [0x05c0, 0x05c0],
44
+ [0x05c3, 0x05c3],
45
+ [0x05c6, 0x05c6],
46
+ [0x05d0, 0x05f4],
47
+ [0x0608, 0x0608],
48
+ [0x200f, 0x200f],
49
+ [0xfb1d, 0xfb1d],
50
+ [0xfb1f, 0xfb28],
51
+ [0xfb2a, 0xfb4f],
52
+ ];
53
+ const AL_RANGES = [
54
+ [0x0600, 0x0605],
55
+ [0x060b, 0x060b],
56
+ [0x060d, 0x060d],
57
+ [0x061b, 0x064a],
58
+ [0x066d, 0x066f],
59
+ [0x0671, 0x06d5],
60
+ [0x06e5, 0x06e6],
61
+ [0x06ee, 0x06ef],
62
+ [0x06fa, 0x0710],
63
+ [0x0712, 0x072f],
64
+ [0x074d, 0x07a5],
65
+ [0x07b1, 0x07b1],
66
+ [0x0780, 0x07a5],
67
+ [0xfb50, 0xfdfd],
68
+ [0xfe70, 0xfefc],
69
+ ];
70
+ const AN_RANGES = [
71
+ [0x0660, 0x0669],
72
+ [0x066b, 0x066c],
73
+ [0x06dd, 0x06dd],
74
+ ];
75
+ const inRanges = (cp, ranges) => ranges.some(([lo, hi]) => cp >= lo && cp <= hi);
76
+ const NSM_RE = /^\p{Mn}$/u;
77
+ const L_RE = /^[\p{L}\p{Nl}]$/u;
78
+ function bidiClass(cp) {
79
+ if (inRanges(cp, AN_RANGES))
80
+ return "AN";
81
+ if (inRanges(cp, R_RANGES))
82
+ return "R";
83
+ if (inRanges(cp, AL_RANGES))
84
+ return "AL";
85
+ if (cp >= 0x30 && cp <= 0x39)
86
+ return "EN";
87
+ if (cp >= 0x06f0 && cp <= 0x06f9)
88
+ return "EN"; // extended Arabic-Indic: EN
89
+ const ch = String.fromCodePoint(cp);
90
+ if (NSM_RE.test(ch))
91
+ return "NSM";
92
+ if (L_RE.test(ch))
93
+ return "L";
94
+ return "N"; // ES/CS/ET/ON/BN for the rule's purposes
95
+ }
96
+ /**
97
+ * The RFC 5893 §2 Bidi rule for one label. Applied only when the whole
98
+ * domain name is a "Bidi domain name" (some label contains R/AL/AN).
99
+ */
100
+ function satisfiesBidiRule(codepoints) {
101
+ const classes = codepoints.map(bidiClass);
102
+ const first = classes[0];
103
+ // Trailing NSMs attach to the preceding character (rules 3 and 6).
104
+ let lastIdx = classes.length - 1;
105
+ while (lastIdx > 0 && classes[lastIdx] === "NSM")
106
+ lastIdx--;
107
+ const last = classes[lastIdx];
108
+ if (first === "R" || first === "AL") {
109
+ // RTL label: rules 2-4.
110
+ const allowed = new Set(["R", "AL", "AN", "EN", "NSM", "N"]);
111
+ if (!classes.every((c) => allowed.has(c)))
112
+ return false;
113
+ if (!(last === "R" || last === "AL" || last === "AN" || last === "EN")) {
114
+ return false;
115
+ }
116
+ const hasEN = classes.includes("EN");
117
+ const hasAN = classes.includes("AN");
118
+ return !(hasEN && hasAN);
119
+ }
120
+ if (first === "L") {
121
+ // LTR label: rules 5-6.
122
+ const allowed = new Set(["L", "EN", "NSM", "N"]);
123
+ if (!classes.every((c) => allowed.has(c)))
124
+ return false;
125
+ return last === "L" || last === "EN";
126
+ }
127
+ return false; // rule 1: first character must be L, R, or AL
128
+ }
129
+ // ---------------------------------------------------------------------------
130
+ const LDH_ASCII = /^[a-z0-9-]+$/i;
131
+ /**
132
+ * Validate one label; returns its A-label (ACE) octet length, or null when
133
+ * invalid. RFC 5891 §4.2.3.1 hyphen restrictions apply to both forms.
134
+ */
135
+ function labelAceLength(label) {
136
+ if (label.length === 0)
137
+ return null;
138
+ if (label.startsWith("-") || label.endsWith("-"))
139
+ return null;
140
+ // ASCII labels: plain LDH, or a full A-label when ACE-prefixed.
141
+ // eslint-disable-next-line no-control-regex -- explicit ASCII-range test
142
+ if (/^[\x00-\x7f]*$/u.test(label)) {
143
+ if (!LDH_ASCII.test(label))
144
+ return null;
145
+ if (label.length > 63)
146
+ return null;
147
+ if (/^..--/.test(label)) {
148
+ if (!/^xn--/i.test(label))
149
+ return null; // reserved LDH label
150
+ if (!isValidALabel(label))
151
+ return null;
152
+ // idn-hostname additionally screens the DECODED content's code
153
+ // points (an A-label hiding a DISALLOWED code point is invalid).
154
+ const decoded = decodePunycode(label.slice(4).toLowerCase());
155
+ if (!decoded?.every(allowedUnicodeCp))
156
+ return null;
157
+ return label.length;
158
+ }
159
+ return label.length;
160
+ }
161
+ // U-label. RFC 5891 §4.2.3: NFC form required.
162
+ if (label.normalize("NFC") !== label)
163
+ return null;
164
+ if (/^..--/u.test(label))
165
+ return null; // hyphens in positions 3-4
166
+ // eslint-disable-next-line @typescript-eslint/no-misused-spread -- code-point iteration is the IDNA unit
167
+ const codepoints = [...label].map((ch) => ch.codePointAt(0));
168
+ if (!codepoints.every(allowedUnicodeCp))
169
+ return null;
170
+ // Context rules + leading-mark + exceptions (RFC 5892; shared with the
171
+ // A-label path).
172
+ if (!isValidIdnaLabel(label, codepoints))
173
+ return null;
174
+ const ace = encodePunycode(codepoints);
175
+ const aceLength = ace.length + 4; // "xn--" prefix
176
+ if (aceLength > 63)
177
+ return null;
178
+ // The canonical ACE must decode back (guards encoder edge cases).
179
+ if (decodePunycode(ace) === undefined)
180
+ return null;
181
+ return aceLength;
182
+ }
183
+ function isIdnHostname(value) {
184
+ if (value.length === 0)
185
+ return false;
186
+ // IDNA label separators: the ideographic/fullwidth/halfwidth full stops
187
+ // separate labels exactly like ".".
188
+ const labels = value.split(/[.\u3002\uff0e\uff61]/u);
189
+ const decodedLabels = [];
190
+ let total = 0;
191
+ for (const label of labels) {
192
+ const aceLength = labelAceLength(label);
193
+ if (aceLength === null)
194
+ return false;
195
+ total += aceLength;
196
+ // Bidi checking needs the Unicode form: decode A-labels.
197
+ if (/^xn--/i.test(label)) {
198
+ decodedLabels.push(decodePunycode(label.slice(4).toLowerCase()) ?? []);
199
+ }
200
+ else {
201
+ // eslint-disable-next-line @typescript-eslint/no-misused-spread -- code-point iteration is the IDNA unit
202
+ decodedLabels.push([...label].map((ch) => ch.codePointAt(0)));
203
+ }
204
+ }
205
+ if (total + labels.length - 1 > 253)
206
+ return false;
207
+ // RFC 5893 §1.4: a Bidi domain name (any RTL character anywhere) must
208
+ // satisfy the Bidi rule in EVERY label.
209
+ const isBidiName = decodedLabels.some((cps) => cps.some((cp) => {
210
+ const c = bidiClass(cp);
211
+ return c === "R" || c === "AL" || c === "AN";
212
+ }));
213
+ if (isBidiName) {
214
+ return decodedLabels.every((cps) => cps.length === 0 || satisfiesBidiRule(cps));
215
+ }
216
+ return true;
217
+ }
218
+ export const idnHostname = {
219
+ test: (value) => typeof value === "string" && isIdnHostname(value),
220
+ };
221
+ // ---------------------------------------------------------------------------
222
+ // idn-email (RFC 6531): RFC 5321's mailbox grammar with `atext`/`qtextSMTP`
223
+ // extended by UTF8-non-ascii — any non-ASCII code point is admitted in the
224
+ // local part; the domain side is an idn-hostname (U- or A-labels) or an
225
+ // address literal.
226
+ const ATEXT_ASCII = /^[A-Za-z0-9!#$%&'*+\-/=?^_`{|}~]$/;
227
+ const isExtendedAtext = (ch) => {
228
+ const cp = ch.codePointAt(0);
229
+ // A lone surrogate is not a Unicode scalar value — UTF8-non-ascii can
230
+ // never encode it (RFC 3629 forbids surrogate code points in UTF-8).
231
+ if (cp >= 0xd800 && cp <= 0xdfff && ch.length === 1)
232
+ return false;
233
+ return ATEXT_ASCII.test(ch) || cp >= 0x80;
234
+ };
235
+ function isIdnDotString(local) {
236
+ if (local.length === 0)
237
+ return false;
238
+ const atoms = local.split(".");
239
+ return atoms.every((atom) =>
240
+ // eslint-disable-next-line @typescript-eslint/no-misused-spread -- code-point iteration
241
+ atom.length > 0 && [...atom].every(isExtendedAtext));
242
+ }
243
+ function isIdnQuotedString(local) {
244
+ if (local.length < 2 || !local.startsWith('"') || !local.endsWith('"'))
245
+ return false;
246
+ const body = local.slice(1, -1);
247
+ for (let i = 0; i < body.length; i++) {
248
+ const ch = body[i];
249
+ if (ch === "\\") {
250
+ // quoted-pairSMTP: "\" + printable ASCII (RFC 6531 leaves this rule).
251
+ const next = body.charCodeAt(i + 1);
252
+ if (Number.isNaN(next) || next < 32 || next > 126)
253
+ return false;
254
+ i++;
255
+ continue;
256
+ }
257
+ const cp = ch.codePointAt(0);
258
+ // qtextSMTP (32-126 minus '"' and "\") or UTF8-non-ascii.
259
+ if (cp >= 0x80)
260
+ continue;
261
+ if (cp < 32 || cp > 126 || ch === '"')
262
+ return false;
263
+ }
264
+ return true;
265
+ }
266
+ // Address literals ([IPv4] / [IPv6:...]) are pure ASCII plumbing shared
267
+ // with `email`; the idn-email suite exercises hostname domains, and a
268
+ // literal domain simply defers to the same bracket grammar via the plain
269
+ // email rules embedded here.
270
+ const IPV4_LITERAL = /^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}$/;
271
+ function isIdnEmail(value) {
272
+ let local;
273
+ let domain;
274
+ if (value.startsWith('"')) {
275
+ let i = 1;
276
+ while (i < value.length && value[i] !== '"') {
277
+ i += value[i] === "\\" ? 2 : 1;
278
+ }
279
+ if (i >= value.length || value[i + 1] !== "@")
280
+ return false;
281
+ local = value.slice(0, i + 1);
282
+ domain = value.slice(i + 2);
283
+ if (!isIdnQuotedString(local))
284
+ return false;
285
+ }
286
+ else {
287
+ const at = value.lastIndexOf("@");
288
+ if (at === -1)
289
+ return false;
290
+ local = value.slice(0, at);
291
+ domain = value.slice(at + 1);
292
+ if (!isIdnDotString(local))
293
+ return false;
294
+ }
295
+ if (domain.startsWith("[") && domain.endsWith("]")) {
296
+ const inner = domain.slice(1, -1);
297
+ return IPV4_LITERAL.test(inner);
298
+ }
299
+ return isIdnHostname(domain);
300
+ }
301
+ export const idnEmail = {
302
+ test: (value) => typeof value === "string" && isIdnEmail(value),
303
+ };
304
+ //# sourceMappingURL=idn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"idn.js","sourceRoot":"","sources":["../src/idn.ts"],"names":[],"mappings":"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"}
package/dist/idna.d.ts ADDED
@@ -0,0 +1,50 @@
1
+ /**
2
+ * RFC 3492 §6.2 decoding procedure over the Bootstring-encoded remainder
3
+ * of an A-label (the part after the "xn--" ACE prefix, which is an IDNA
4
+ * layering concern handled by the caller, not by Bootstring itself).
5
+ * Returns the decoded code points, or undefined for any malformed input:
6
+ * a non-ASCII basic code point, an unrecognized digit, an incomplete
7
+ * trailing generalized variable-length integer, arithmetic overflow, or a
8
+ * resulting code point outside the valid Unicode scalar value range.
9
+ */
10
+ export declare function decodePunycode(input: string): number[] | undefined;
11
+ /**
12
+ * RFC 3492 §6.3 encoding procedure — the inverse of {@link decodePunycode}.
13
+ * RFC 5891 §4.4 requires an A-label to be the CANONICAL Punycode encoding
14
+ * of its decoded content: a non-canonical Bootstring digit sequence can
15
+ * decode successfully yet not be what encoding those code points would
16
+ * produce (e.g. an encoder-would-never-emit extra "--" run), so an A-label
17
+ * is only valid when decode-then-re-encode round-trips to the original
18
+ * (case-insensitive) text.
19
+ */
20
+ export declare function encodePunycode(input: number[]): string;
21
+ /**
22
+ * Applies the RFC 5891 §4.2.3.2 leading-mark rule and the RFC 5892
23
+ * Appendix A rules that the suite exercises to a decoded label's code
24
+ * points. `label` is the lowercase ASCII text of the label (the "xn--..."
25
+ * form); `codepoints` is its Punycode-decoded content.
26
+ */
27
+ export declare function isValidIdnaLabel(label: string, codepoints: number[]): boolean;
28
+ /**
29
+ * Validates one "xn--..." A-label per RFC 5890 §2.3.1/§2.3.2.1 (ACE
30
+ * prefix, case-insensitive) + RFC 5891 §4.4 (canonical Punycode) + the
31
+ * content rules above. §4.4 requires the ACE suffix to be the CANONICAL
32
+ * encoding of its decoded content — decode-then-re-encode must round-trip
33
+ * to the original suffix, not merely decode without error, since a
34
+ * non-canonical Bootstring digit sequence can be well-formed enough to
35
+ * decode yet isn't what an encoder would ever produce for that content.
36
+ *
37
+ * §2.3.1's "'--' in the third/fourth position is reserved for ACE labels"
38
+ * is, per the suite, a constraint on the label's ASCII text as a whole,
39
+ * not just its mandatory prefix occurrence: every valid A-label in the
40
+ * suite has exactly one "--" pair (the "xn--" prefix itself), while the
41
+ * sole invalid "contains '--' in the 3rd and 4th position" case has a
42
+ * second "--" later in the same label. A second reserved-looking marker
43
+ * elsewhere in the text is rejected on the same "R-LDH labels are
44
+ * reserved for ACE use" grounds as the prefix position itself — allowing
45
+ * it would let two different byte-for-byte-identical ACE-shaped
46
+ * substrings coexist in one label with no way to say which is "the"
47
+ * prefix.
48
+ */
49
+ export declare function isValidALabel(label: string): boolean;
50
+ //# sourceMappingURL=idna.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"idna.d.ts","sourceRoot":"","sources":["../src/idna.ts"],"names":[],"mappings":"AA8CA;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAkDlE;AAID;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CA0CtD;AA6FD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAyE7E;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAUpD"}