@email-utils/validator-syntax 1.0.0-rc.1 → 1.0.0-rc.3
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/dist/fixtures.cjs +125 -8
- package/dist/fixtures.cjs.map +1 -1
- package/dist/fixtures.d.cts +133 -7
- package/dist/fixtures.d.mts +133 -7
- package/dist/fixtures.mjs +125 -8
- package/dist/fixtures.mjs.map +1 -1
- package/dist/index.cjs +243 -72
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +50 -16
- package/dist/index.d.mts +50 -16
- package/dist/index.mjs +243 -72
- package/dist/index.mjs.map +1 -1
- package/dist/{result-BZjmlevS.d.cts → result-CNbJ54oT.d.cts} +17 -1
- package/dist/{result-BZjmlevS.d.mts → result-CNbJ54oT.d.mts} +17 -1
- package/package.json +7 -3
package/dist/fixtures.d.cts
CHANGED
|
@@ -1,9 +1,26 @@
|
|
|
1
|
-
import { i as SyntaxOptions, t as ReasonCode } from "./result-
|
|
1
|
+
import { i as SyntaxOptions, t as ReasonCode } from "./result-CNbJ54oT.cjs";
|
|
2
2
|
//#region src/fixtures/types.d.ts
|
|
3
|
+
/** A preset's name: the same union as the root entry's `Preset`. */
|
|
3
4
|
type Preset = "practical" | "rfc5321" | "rfc5322" | "html5";
|
|
5
|
+
/**
|
|
6
|
+
* Every preset, in the order the support matrix's columns take.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { isValidSyntax } from '@email-utils/validator-syntax';
|
|
11
|
+
* import { presets } from '@email-utils/validator-syntax/fixtures';
|
|
12
|
+
*
|
|
13
|
+
* presets.filter((preset) => isValidSyntax('ada@localhost', { preset }));
|
|
14
|
+
* // => ['html5']
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
4
17
|
export declare const presets: readonly Preset[];
|
|
5
18
|
/** The `syntax.*` codes from the reason-code catalogue (meta docs/api/reason-codes.md). */
|
|
6
19
|
type SyntaxReasonCode = ReasonCode;
|
|
20
|
+
/**
|
|
21
|
+
* A fixture's result under one preset: the `ok`, `reason`, and `index` of
|
|
22
|
+
* what `parseAddress` returns, without the value or message.
|
|
23
|
+
*/
|
|
7
24
|
type Expected = {
|
|
8
25
|
ok: true;
|
|
9
26
|
} | {
|
|
@@ -17,11 +34,22 @@ type Expected = {
|
|
|
17
34
|
* which presets accept the tagged fixtures gives the matrix.
|
|
18
35
|
*/
|
|
19
36
|
type SyntaxFeature = "dot-atom" | "atext-specials" | "route-chars" | "misplaced-dots" | "long-local" | "quoted-local" | "quoted-pair" | "obs-local" | "comments" | "fws" | "obs-control" | "ipv4-literal" | "ipv6-literal" | "general-literal" | "dotless-domain" | "unknown-tld";
|
|
20
|
-
/**
|
|
37
|
+
/**
|
|
38
|
+
* The support matrix's rows, in order, with each feature's label.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* import { syntaxFeatures } from '@email-utils/validator-syntax/fixtures';
|
|
43
|
+
*
|
|
44
|
+
* syntaxFeatures[0];
|
|
45
|
+
* // => { feature: 'dot-atom', label: 'Letters, digits, and single dots' }
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
21
48
|
export declare const syntaxFeatures: readonly {
|
|
22
49
|
feature: SyntaxFeature;
|
|
23
50
|
label: string;
|
|
24
51
|
}[];
|
|
52
|
+
/** An address, and what each preset makes of it. */
|
|
25
53
|
interface SyntaxFixture {
|
|
26
54
|
address: string;
|
|
27
55
|
description: string;
|
|
@@ -30,6 +58,7 @@ interface SyntaxFixture {
|
|
|
30
58
|
/** The support-matrix row this fixture is a well-formed example of. */
|
|
31
59
|
feature?: SyntaxFeature;
|
|
32
60
|
}
|
|
61
|
+
/** A fixture from the 0.0.1 test suite, with what 0.0.1 made of it. */
|
|
33
62
|
interface LegacyFixture extends SyntaxFixture {
|
|
34
63
|
/** What 0.0.1's `validate()` returned with its default config. */
|
|
35
64
|
legacy: boolean;
|
|
@@ -40,27 +69,106 @@ interface LegacyFixture extends SyntaxFixture {
|
|
|
40
69
|
*/
|
|
41
70
|
flipped?: string;
|
|
42
71
|
}
|
|
72
|
+
/** A fixture from isemail's test set. */
|
|
43
73
|
interface IsemailFixture extends SyntaxFixture {
|
|
44
74
|
/** The test's `id` in isemail's tests.xml. */
|
|
45
75
|
isemail: number;
|
|
46
76
|
}
|
|
47
77
|
//#endregion
|
|
48
78
|
//#region src/fixtures/isemail.d.ts
|
|
79
|
+
/**
|
|
80
|
+
* Dominic Sayers' is_email tests, each tagged with its `id` in tests.xml.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* import { isemailFixtures } from '@email-utils/validator-syntax/fixtures';
|
|
85
|
+
*
|
|
86
|
+
* isemailFixtures.find((fixture) => fixture.isemail === 5);
|
|
87
|
+
* // => {
|
|
88
|
+
* // address: 'test@io',
|
|
89
|
+
* // expected: { practical: { ok: false, reason: 'syntax.domain.no_dot' } },
|
|
90
|
+
* // }
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
49
93
|
export declare const isemailFixtures: readonly IsemailFixture[];
|
|
50
94
|
//#endregion
|
|
51
95
|
//#region src/fixtures/legacy.d.ts
|
|
96
|
+
/**
|
|
97
|
+
* Every address the 0.0.1 test suite checked, with what 0.0.1 returned.
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```ts
|
|
101
|
+
* import { legacyFixtures } from '@email-utils/validator-syntax/fixtures';
|
|
102
|
+
*
|
|
103
|
+
* // The addresses v1's default preset judges differently from 0.0.1.
|
|
104
|
+
* const flipped = legacyFixtures.filter(
|
|
105
|
+
* (fixture) => fixture.flipped !== undefined,
|
|
106
|
+
* );
|
|
107
|
+
* flipped.every((fixture) => fixture.legacy !== fixture.expected.practical.ok);
|
|
108
|
+
* // => true
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
52
111
|
export declare const legacyFixtures: readonly LegacyFixture[];
|
|
53
112
|
//#endregion
|
|
54
113
|
//#region src/fixtures/rfc3696.d.ts
|
|
114
|
+
/**
|
|
115
|
+
* RFC 3696's examples, as corrected by its erratum 246.
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```ts
|
|
119
|
+
* import { rfc3696Fixtures } from '@email-utils/validator-syntax/fixtures';
|
|
120
|
+
*
|
|
121
|
+
* // Printed as valid, but a backslash escape needs a quoted string.
|
|
122
|
+
* rfc3696Fixtures
|
|
123
|
+
* .filter((fixture) => !fixture.expected.rfc5322.ok)
|
|
124
|
+
* .map((fixture) => fixture.address);
|
|
125
|
+
* // => [
|
|
126
|
+
* // 'Abc\\@def@example.com',
|
|
127
|
+
* // 'Fred\\ Bloggs@example.com',
|
|
128
|
+
* // 'Joe.\\\\Blow@example.com',
|
|
129
|
+
* // ]
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
55
132
|
export declare const rfc3696Fixtures: readonly SyntaxFixture[];
|
|
56
133
|
//#endregion
|
|
57
134
|
//#region src/fixtures/wikipedia.d.ts
|
|
135
|
+
/**
|
|
136
|
+
* The examples from Wikipedia's "Email address" article.
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```ts
|
|
140
|
+
* import { wikipediaFixtures } from '@email-utils/validator-syntax/fixtures';
|
|
141
|
+
*
|
|
142
|
+
* wikipediaFixtures.find((fixture) => fixture.address === 'admin@example');
|
|
143
|
+
* // => {
|
|
144
|
+
* // expected: {
|
|
145
|
+
* // practical: { ok: false, reason: 'syntax.domain.no_dot' },
|
|
146
|
+
* // html5: { ok: true },
|
|
147
|
+
* // },
|
|
148
|
+
* // }
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
58
151
|
export declare const wikipediaFixtures: readonly SyntaxFixture[];
|
|
59
152
|
//#endregion
|
|
60
153
|
//#region src/fixtures/index.d.ts
|
|
61
|
-
/**
|
|
154
|
+
/**
|
|
155
|
+
* Every fixture from every source, each address once.
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* ```ts
|
|
159
|
+
* import { isValidSyntax } from '@email-utils/validator-syntax';
|
|
160
|
+
* import { syntaxFixtures } from '@email-utils/validator-syntax/fixtures';
|
|
161
|
+
*
|
|
162
|
+
* syntaxFixtures.every(
|
|
163
|
+
* ({ address, expected }) =>
|
|
164
|
+
* isValidSyntax(address, { preset: 'rfc5321' }) === expected.rfc5321.ok,
|
|
165
|
+
* ); // => true
|
|
166
|
+
* ```
|
|
167
|
+
*/
|
|
62
168
|
export declare const syntaxFixtures: readonly SyntaxFixture[];
|
|
169
|
+
/** Whether a preset accepts all, some, or none of a feature's fixtures. */
|
|
63
170
|
export type Support = "yes" | "partial" | "no";
|
|
171
|
+
/** A row of {@link supportMatrix}: one feature, and each preset's support. */
|
|
64
172
|
export interface SupportRow {
|
|
65
173
|
feature: SyntaxFeature;
|
|
66
174
|
label: string;
|
|
@@ -69,7 +177,18 @@ export interface SupportRow {
|
|
|
69
177
|
/** The feature's fixtures, for examples. */
|
|
70
178
|
fixtures: readonly SyntaxFixture[];
|
|
71
179
|
}
|
|
72
|
-
/**
|
|
180
|
+
/**
|
|
181
|
+
* The docs' support matrix: one row per feature, one column per preset.
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* ```ts
|
|
185
|
+
* import { supportMatrix } from '@email-utils/validator-syntax/fixtures';
|
|
186
|
+
*
|
|
187
|
+
* const row = supportMatrix().find(({ feature }) => feature === 'quoted-local');
|
|
188
|
+
* row?.support;
|
|
189
|
+
* // => { practical: 'no', rfc5321: 'yes', rfc5322: 'yes', html5: 'no' }
|
|
190
|
+
* ```
|
|
191
|
+
*/
|
|
73
192
|
export declare function supportMatrix(): SupportRow[];
|
|
74
193
|
/** An address the configuration accepts. */
|
|
75
194
|
export interface ValidPreviewEntry {
|
|
@@ -106,9 +225,16 @@ export interface SyntaxPreview {
|
|
|
106
225
|
*
|
|
107
226
|
* @example
|
|
108
227
|
* ```ts
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
228
|
+
* import { previewSyntaxOptions } from '@email-utils/validator-syntax/fixtures';
|
|
229
|
+
*
|
|
230
|
+
* const { valid } = previewSyntaxOptions({ checkTld: false });
|
|
231
|
+
* valid.find((entry) => entry.address === 'example@s.example');
|
|
232
|
+
* // => { changed: true }
|
|
233
|
+
* previewSyntaxOptions({ preset: 'html5' }, ['ada@localhost', 'ada@example..com']);
|
|
234
|
+
* // => {
|
|
235
|
+
* // valid: [{ address: 'ada@localhost', changed: false }],
|
|
236
|
+
* // invalid: [{ address: 'ada@example..com', reason: 'syntax.domain.label_invalid' }],
|
|
237
|
+
* // }
|
|
112
238
|
* ```
|
|
113
239
|
*
|
|
114
240
|
* @param addresses - The addresses to judge; `syntaxFixtures` by default.
|
package/dist/fixtures.d.mts
CHANGED
|
@@ -1,9 +1,26 @@
|
|
|
1
|
-
import { i as SyntaxOptions, t as ReasonCode } from "./result-
|
|
1
|
+
import { i as SyntaxOptions, t as ReasonCode } from "./result-CNbJ54oT.mjs";
|
|
2
2
|
//#region src/fixtures/types.d.ts
|
|
3
|
+
/** A preset's name: the same union as the root entry's `Preset`. */
|
|
3
4
|
type Preset = "practical" | "rfc5321" | "rfc5322" | "html5";
|
|
5
|
+
/**
|
|
6
|
+
* Every preset, in the order the support matrix's columns take.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { isValidSyntax } from '@email-utils/validator-syntax';
|
|
11
|
+
* import { presets } from '@email-utils/validator-syntax/fixtures';
|
|
12
|
+
*
|
|
13
|
+
* presets.filter((preset) => isValidSyntax('ada@localhost', { preset }));
|
|
14
|
+
* // => ['html5']
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
4
17
|
export declare const presets: readonly Preset[];
|
|
5
18
|
/** The `syntax.*` codes from the reason-code catalogue (meta docs/api/reason-codes.md). */
|
|
6
19
|
type SyntaxReasonCode = ReasonCode;
|
|
20
|
+
/**
|
|
21
|
+
* A fixture's result under one preset: the `ok`, `reason`, and `index` of
|
|
22
|
+
* what `parseAddress` returns, without the value or message.
|
|
23
|
+
*/
|
|
7
24
|
type Expected = {
|
|
8
25
|
ok: true;
|
|
9
26
|
} | {
|
|
@@ -17,11 +34,22 @@ type Expected = {
|
|
|
17
34
|
* which presets accept the tagged fixtures gives the matrix.
|
|
18
35
|
*/
|
|
19
36
|
type SyntaxFeature = "dot-atom" | "atext-specials" | "route-chars" | "misplaced-dots" | "long-local" | "quoted-local" | "quoted-pair" | "obs-local" | "comments" | "fws" | "obs-control" | "ipv4-literal" | "ipv6-literal" | "general-literal" | "dotless-domain" | "unknown-tld";
|
|
20
|
-
/**
|
|
37
|
+
/**
|
|
38
|
+
* The support matrix's rows, in order, with each feature's label.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* import { syntaxFeatures } from '@email-utils/validator-syntax/fixtures';
|
|
43
|
+
*
|
|
44
|
+
* syntaxFeatures[0];
|
|
45
|
+
* // => { feature: 'dot-atom', label: 'Letters, digits, and single dots' }
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
21
48
|
export declare const syntaxFeatures: readonly {
|
|
22
49
|
feature: SyntaxFeature;
|
|
23
50
|
label: string;
|
|
24
51
|
}[];
|
|
52
|
+
/** An address, and what each preset makes of it. */
|
|
25
53
|
interface SyntaxFixture {
|
|
26
54
|
address: string;
|
|
27
55
|
description: string;
|
|
@@ -30,6 +58,7 @@ interface SyntaxFixture {
|
|
|
30
58
|
/** The support-matrix row this fixture is a well-formed example of. */
|
|
31
59
|
feature?: SyntaxFeature;
|
|
32
60
|
}
|
|
61
|
+
/** A fixture from the 0.0.1 test suite, with what 0.0.1 made of it. */
|
|
33
62
|
interface LegacyFixture extends SyntaxFixture {
|
|
34
63
|
/** What 0.0.1's `validate()` returned with its default config. */
|
|
35
64
|
legacy: boolean;
|
|
@@ -40,27 +69,106 @@ interface LegacyFixture extends SyntaxFixture {
|
|
|
40
69
|
*/
|
|
41
70
|
flipped?: string;
|
|
42
71
|
}
|
|
72
|
+
/** A fixture from isemail's test set. */
|
|
43
73
|
interface IsemailFixture extends SyntaxFixture {
|
|
44
74
|
/** The test's `id` in isemail's tests.xml. */
|
|
45
75
|
isemail: number;
|
|
46
76
|
}
|
|
47
77
|
//#endregion
|
|
48
78
|
//#region src/fixtures/isemail.d.ts
|
|
79
|
+
/**
|
|
80
|
+
* Dominic Sayers' is_email tests, each tagged with its `id` in tests.xml.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* import { isemailFixtures } from '@email-utils/validator-syntax/fixtures';
|
|
85
|
+
*
|
|
86
|
+
* isemailFixtures.find((fixture) => fixture.isemail === 5);
|
|
87
|
+
* // => {
|
|
88
|
+
* // address: 'test@io',
|
|
89
|
+
* // expected: { practical: { ok: false, reason: 'syntax.domain.no_dot' } },
|
|
90
|
+
* // }
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
49
93
|
export declare const isemailFixtures: readonly IsemailFixture[];
|
|
50
94
|
//#endregion
|
|
51
95
|
//#region src/fixtures/legacy.d.ts
|
|
96
|
+
/**
|
|
97
|
+
* Every address the 0.0.1 test suite checked, with what 0.0.1 returned.
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```ts
|
|
101
|
+
* import { legacyFixtures } from '@email-utils/validator-syntax/fixtures';
|
|
102
|
+
*
|
|
103
|
+
* // The addresses v1's default preset judges differently from 0.0.1.
|
|
104
|
+
* const flipped = legacyFixtures.filter(
|
|
105
|
+
* (fixture) => fixture.flipped !== undefined,
|
|
106
|
+
* );
|
|
107
|
+
* flipped.every((fixture) => fixture.legacy !== fixture.expected.practical.ok);
|
|
108
|
+
* // => true
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
52
111
|
export declare const legacyFixtures: readonly LegacyFixture[];
|
|
53
112
|
//#endregion
|
|
54
113
|
//#region src/fixtures/rfc3696.d.ts
|
|
114
|
+
/**
|
|
115
|
+
* RFC 3696's examples, as corrected by its erratum 246.
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```ts
|
|
119
|
+
* import { rfc3696Fixtures } from '@email-utils/validator-syntax/fixtures';
|
|
120
|
+
*
|
|
121
|
+
* // Printed as valid, but a backslash escape needs a quoted string.
|
|
122
|
+
* rfc3696Fixtures
|
|
123
|
+
* .filter((fixture) => !fixture.expected.rfc5322.ok)
|
|
124
|
+
* .map((fixture) => fixture.address);
|
|
125
|
+
* // => [
|
|
126
|
+
* // 'Abc\\@def@example.com',
|
|
127
|
+
* // 'Fred\\ Bloggs@example.com',
|
|
128
|
+
* // 'Joe.\\\\Blow@example.com',
|
|
129
|
+
* // ]
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
55
132
|
export declare const rfc3696Fixtures: readonly SyntaxFixture[];
|
|
56
133
|
//#endregion
|
|
57
134
|
//#region src/fixtures/wikipedia.d.ts
|
|
135
|
+
/**
|
|
136
|
+
* The examples from Wikipedia's "Email address" article.
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```ts
|
|
140
|
+
* import { wikipediaFixtures } from '@email-utils/validator-syntax/fixtures';
|
|
141
|
+
*
|
|
142
|
+
* wikipediaFixtures.find((fixture) => fixture.address === 'admin@example');
|
|
143
|
+
* // => {
|
|
144
|
+
* // expected: {
|
|
145
|
+
* // practical: { ok: false, reason: 'syntax.domain.no_dot' },
|
|
146
|
+
* // html5: { ok: true },
|
|
147
|
+
* // },
|
|
148
|
+
* // }
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
58
151
|
export declare const wikipediaFixtures: readonly SyntaxFixture[];
|
|
59
152
|
//#endregion
|
|
60
153
|
//#region src/fixtures/index.d.ts
|
|
61
|
-
/**
|
|
154
|
+
/**
|
|
155
|
+
* Every fixture from every source, each address once.
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* ```ts
|
|
159
|
+
* import { isValidSyntax } from '@email-utils/validator-syntax';
|
|
160
|
+
* import { syntaxFixtures } from '@email-utils/validator-syntax/fixtures';
|
|
161
|
+
*
|
|
162
|
+
* syntaxFixtures.every(
|
|
163
|
+
* ({ address, expected }) =>
|
|
164
|
+
* isValidSyntax(address, { preset: 'rfc5321' }) === expected.rfc5321.ok,
|
|
165
|
+
* ); // => true
|
|
166
|
+
* ```
|
|
167
|
+
*/
|
|
62
168
|
export declare const syntaxFixtures: readonly SyntaxFixture[];
|
|
169
|
+
/** Whether a preset accepts all, some, or none of a feature's fixtures. */
|
|
63
170
|
export type Support = "yes" | "partial" | "no";
|
|
171
|
+
/** A row of {@link supportMatrix}: one feature, and each preset's support. */
|
|
64
172
|
export interface SupportRow {
|
|
65
173
|
feature: SyntaxFeature;
|
|
66
174
|
label: string;
|
|
@@ -69,7 +177,18 @@ export interface SupportRow {
|
|
|
69
177
|
/** The feature's fixtures, for examples. */
|
|
70
178
|
fixtures: readonly SyntaxFixture[];
|
|
71
179
|
}
|
|
72
|
-
/**
|
|
180
|
+
/**
|
|
181
|
+
* The docs' support matrix: one row per feature, one column per preset.
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* ```ts
|
|
185
|
+
* import { supportMatrix } from '@email-utils/validator-syntax/fixtures';
|
|
186
|
+
*
|
|
187
|
+
* const row = supportMatrix().find(({ feature }) => feature === 'quoted-local');
|
|
188
|
+
* row?.support;
|
|
189
|
+
* // => { practical: 'no', rfc5321: 'yes', rfc5322: 'yes', html5: 'no' }
|
|
190
|
+
* ```
|
|
191
|
+
*/
|
|
73
192
|
export declare function supportMatrix(): SupportRow[];
|
|
74
193
|
/** An address the configuration accepts. */
|
|
75
194
|
export interface ValidPreviewEntry {
|
|
@@ -106,9 +225,16 @@ export interface SyntaxPreview {
|
|
|
106
225
|
*
|
|
107
226
|
* @example
|
|
108
227
|
* ```ts
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
228
|
+
* import { previewSyntaxOptions } from '@email-utils/validator-syntax/fixtures';
|
|
229
|
+
*
|
|
230
|
+
* const { valid } = previewSyntaxOptions({ checkTld: false });
|
|
231
|
+
* valid.find((entry) => entry.address === 'example@s.example');
|
|
232
|
+
* // => { changed: true }
|
|
233
|
+
* previewSyntaxOptions({ preset: 'html5' }, ['ada@localhost', 'ada@example..com']);
|
|
234
|
+
* // => {
|
|
235
|
+
* // valid: [{ address: 'ada@localhost', changed: false }],
|
|
236
|
+
* // invalid: [{ address: 'ada@example..com', reason: 'syntax.domain.label_invalid' }],
|
|
237
|
+
* // }
|
|
112
238
|
* ```
|
|
113
239
|
*
|
|
114
240
|
* @param addresses - The addresses to judge; `syntaxFixtures` by default.
|
package/dist/fixtures.mjs
CHANGED
|
@@ -1,12 +1,34 @@
|
|
|
1
1
|
import { createSyntaxValidator } from "./index.mjs";
|
|
2
2
|
//#region src/fixtures/types.ts
|
|
3
|
+
/**
|
|
4
|
+
* Every preset, in the order the support matrix's columns take.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* import { isValidSyntax } from '@email-utils/validator-syntax';
|
|
9
|
+
* import { presets } from '@email-utils/validator-syntax/fixtures';
|
|
10
|
+
*
|
|
11
|
+
* presets.filter((preset) => isValidSyntax('ada@localhost', { preset }));
|
|
12
|
+
* // => ['html5']
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
3
15
|
const presets = [
|
|
4
16
|
"practical",
|
|
5
17
|
"rfc5321",
|
|
6
18
|
"rfc5322",
|
|
7
19
|
"html5"
|
|
8
20
|
];
|
|
9
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* The support matrix's rows, in order, with each feature's label.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* import { syntaxFeatures } from '@email-utils/validator-syntax/fixtures';
|
|
27
|
+
*
|
|
28
|
+
* syntaxFeatures[0];
|
|
29
|
+
* // => { feature: 'dot-atom', label: 'Letters, digits, and single dots' }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
10
32
|
const syntaxFeatures = [
|
|
11
33
|
{
|
|
12
34
|
feature: "dot-atom",
|
|
@@ -135,6 +157,20 @@ function quotedLocal(rfc) {
|
|
|
135
157
|
};
|
|
136
158
|
}
|
|
137
159
|
const longLabel = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghikl";
|
|
160
|
+
/**
|
|
161
|
+
* Dominic Sayers' is_email tests, each tagged with its `id` in tests.xml.
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* ```ts
|
|
165
|
+
* import { isemailFixtures } from '@email-utils/validator-syntax/fixtures';
|
|
166
|
+
*
|
|
167
|
+
* isemailFixtures.find((fixture) => fixture.isemail === 5);
|
|
168
|
+
* // => {
|
|
169
|
+
* // address: 'test@io',
|
|
170
|
+
* // expected: { practical: { ok: false, reason: 'syntax.domain.no_dot' } },
|
|
171
|
+
* // }
|
|
172
|
+
* ```
|
|
173
|
+
*/
|
|
138
174
|
const isemailFixtures = [
|
|
139
175
|
{
|
|
140
176
|
isemail: 1,
|
|
@@ -1305,6 +1341,21 @@ function withUppercase(fixture) {
|
|
|
1305
1341
|
description: `${fixture.description}, uppercased`
|
|
1306
1342
|
}];
|
|
1307
1343
|
}
|
|
1344
|
+
/**
|
|
1345
|
+
* Every address the 0.0.1 test suite checked, with what 0.0.1 returned.
|
|
1346
|
+
*
|
|
1347
|
+
* @example
|
|
1348
|
+
* ```ts
|
|
1349
|
+
* import { legacyFixtures } from '@email-utils/validator-syntax/fixtures';
|
|
1350
|
+
*
|
|
1351
|
+
* // The addresses v1's default preset judges differently from 0.0.1.
|
|
1352
|
+
* const flipped = legacyFixtures.filter(
|
|
1353
|
+
* (fixture) => fixture.flipped !== undefined,
|
|
1354
|
+
* );
|
|
1355
|
+
* flipped.every((fixture) => fixture.legacy !== fixture.expected.practical.ok);
|
|
1356
|
+
* // => true
|
|
1357
|
+
* ```
|
|
1358
|
+
*/
|
|
1308
1359
|
const legacyFixtures = [
|
|
1309
1360
|
...withUppercase({
|
|
1310
1361
|
address: "simple@example.com",
|
|
@@ -1780,6 +1831,24 @@ const legacyFixtures = [
|
|
|
1780
1831
|
];
|
|
1781
1832
|
//#endregion
|
|
1782
1833
|
//#region src/fixtures/rfc3696.ts
|
|
1834
|
+
/**
|
|
1835
|
+
* RFC 3696's examples, as corrected by its erratum 246.
|
|
1836
|
+
*
|
|
1837
|
+
* @example
|
|
1838
|
+
* ```ts
|
|
1839
|
+
* import { rfc3696Fixtures } from '@email-utils/validator-syntax/fixtures';
|
|
1840
|
+
*
|
|
1841
|
+
* // Printed as valid, but a backslash escape needs a quoted string.
|
|
1842
|
+
* rfc3696Fixtures
|
|
1843
|
+
* .filter((fixture) => !fixture.expected.rfc5322.ok)
|
|
1844
|
+
* .map((fixture) => fixture.address);
|
|
1845
|
+
* // => [
|
|
1846
|
+
* // 'Abc\\@def@example.com',
|
|
1847
|
+
* // 'Fred\\ Bloggs@example.com',
|
|
1848
|
+
* // 'Joe.\\\\Blow@example.com',
|
|
1849
|
+
* // ]
|
|
1850
|
+
* ```
|
|
1851
|
+
*/
|
|
1783
1852
|
const rfc3696Fixtures = [
|
|
1784
1853
|
{
|
|
1785
1854
|
address: "Abc\\@def@example.com",
|
|
@@ -1862,6 +1931,22 @@ const rfc3696Fixtures = [
|
|
|
1862
1931
|
];
|
|
1863
1932
|
//#endregion
|
|
1864
1933
|
//#region src/fixtures/wikipedia.ts
|
|
1934
|
+
/**
|
|
1935
|
+
* The examples from Wikipedia's "Email address" article.
|
|
1936
|
+
*
|
|
1937
|
+
* @example
|
|
1938
|
+
* ```ts
|
|
1939
|
+
* import { wikipediaFixtures } from '@email-utils/validator-syntax/fixtures';
|
|
1940
|
+
*
|
|
1941
|
+
* wikipediaFixtures.find((fixture) => fixture.address === 'admin@example');
|
|
1942
|
+
* // => {
|
|
1943
|
+
* // expected: {
|
|
1944
|
+
* // practical: { ok: false, reason: 'syntax.domain.no_dot' },
|
|
1945
|
+
* // html5: { ok: true },
|
|
1946
|
+
* // },
|
|
1947
|
+
* // }
|
|
1948
|
+
* ```
|
|
1949
|
+
*/
|
|
1865
1950
|
const wikipediaFixtures = [
|
|
1866
1951
|
{
|
|
1867
1952
|
address: "FirstName.LastName@EasierReading.org",
|
|
@@ -1999,8 +2084,9 @@ const wikipediaFixtures = [
|
|
|
1999
2084
|
* string, comment, or literal left open runs to the end, taking any `@`
|
|
2000
2085
|
* with it.
|
|
2001
2086
|
*
|
|
2002
|
-
* The first failure wins, checked in this order: empty input;
|
|
2003
|
-
*
|
|
2087
|
+
* The first failure wins, checked in this order: empty input; input longer
|
|
2088
|
+
* than `maxLength` (512 by default, which no fixture reaches); the split; the
|
|
2089
|
+
* local part, left to right, then its length; the domain, left to right,
|
|
2004
2090
|
* then its length; the address length; a dotless domain; the TLD. Where a
|
|
2005
2091
|
* failure has a position, `index` points at the first offending character
|
|
2006
2092
|
* in the whole address: the `(` of a disallowed or unterminated comment,
|
|
@@ -2009,14 +2095,38 @@ const wikipediaFixtures = [
|
|
|
2009
2095
|
*
|
|
2010
2096
|
* @packageDocumentation
|
|
2011
2097
|
*/
|
|
2012
|
-
/**
|
|
2098
|
+
/**
|
|
2099
|
+
* Every fixture from every source, each address once.
|
|
2100
|
+
*
|
|
2101
|
+
* @example
|
|
2102
|
+
* ```ts
|
|
2103
|
+
* import { isValidSyntax } from '@email-utils/validator-syntax';
|
|
2104
|
+
* import { syntaxFixtures } from '@email-utils/validator-syntax/fixtures';
|
|
2105
|
+
*
|
|
2106
|
+
* syntaxFixtures.every(
|
|
2107
|
+
* ({ address, expected }) =>
|
|
2108
|
+
* isValidSyntax(address, { preset: 'rfc5321' }) === expected.rfc5321.ok,
|
|
2109
|
+
* ); // => true
|
|
2110
|
+
* ```
|
|
2111
|
+
*/
|
|
2013
2112
|
const syntaxFixtures = [
|
|
2014
2113
|
...legacyFixtures,
|
|
2015
2114
|
...isemailFixtures,
|
|
2016
2115
|
...wikipediaFixtures,
|
|
2017
2116
|
...rfc3696Fixtures
|
|
2018
2117
|
];
|
|
2019
|
-
/**
|
|
2118
|
+
/**
|
|
2119
|
+
* The docs' support matrix: one row per feature, one column per preset.
|
|
2120
|
+
*
|
|
2121
|
+
* @example
|
|
2122
|
+
* ```ts
|
|
2123
|
+
* import { supportMatrix } from '@email-utils/validator-syntax/fixtures';
|
|
2124
|
+
*
|
|
2125
|
+
* const row = supportMatrix().find(({ feature }) => feature === 'quoted-local');
|
|
2126
|
+
* row?.support;
|
|
2127
|
+
* // => { practical: 'no', rfc5321: 'yes', rfc5322: 'yes', html5: 'no' }
|
|
2128
|
+
* ```
|
|
2129
|
+
*/
|
|
2020
2130
|
function supportMatrix() {
|
|
2021
2131
|
return syntaxFeatures.map(({ feature, label }) => {
|
|
2022
2132
|
const fixtures = syntaxFixtures.filter((fixture) => fixture.feature === feature);
|
|
@@ -2049,9 +2159,16 @@ function supportMatrix() {
|
|
|
2049
2159
|
*
|
|
2050
2160
|
* @example
|
|
2051
2161
|
* ```ts
|
|
2052
|
-
*
|
|
2053
|
-
*
|
|
2054
|
-
*
|
|
2162
|
+
* import { previewSyntaxOptions } from '@email-utils/validator-syntax/fixtures';
|
|
2163
|
+
*
|
|
2164
|
+
* const { valid } = previewSyntaxOptions({ checkTld: false });
|
|
2165
|
+
* valid.find((entry) => entry.address === 'example@s.example');
|
|
2166
|
+
* // => { changed: true }
|
|
2167
|
+
* previewSyntaxOptions({ preset: 'html5' }, ['ada@localhost', 'ada@example..com']);
|
|
2168
|
+
* // => {
|
|
2169
|
+
* // valid: [{ address: 'ada@localhost', changed: false }],
|
|
2170
|
+
* // invalid: [{ address: 'ada@example..com', reason: 'syntax.domain.label_invalid' }],
|
|
2171
|
+
* // }
|
|
2055
2172
|
* ```
|
|
2056
2173
|
*
|
|
2057
2174
|
* @param addresses - The addresses to judge; `syntaxFixtures` by default.
|