shelving 1.131.0 → 1.132.0
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/package.json +1 -1
- package/schema/ColorSchema.d.ts +3 -4
- package/schema/ColorSchema.js +2 -2
- package/schema/EmailSchema.d.ts +3 -3
- package/schema/EmailSchema.js +4 -5
- package/schema/KeySchema.d.ts +4 -1
- package/schema/KeySchema.js +9 -3
- package/schema/LinkSchema.d.ts +2 -2
- package/schema/LinkSchema.js +5 -5
- package/schema/NumberSchema.js +1 -1
- package/schema/PhoneSchema.d.ts +2 -2
- package/schema/PhoneSchema.js +2 -2
- package/schema/SlugSchema.d.ts +1 -1
- package/schema/SlugSchema.js +2 -3
- package/schema/StringSchema.d.ts +3 -32
- package/schema/StringSchema.js +4 -35
- package/schema/TextSchema.d.ts +40 -0
- package/schema/TextSchema.js +47 -0
- package/schema/index.d.ts +1 -0
- package/schema/index.js +1 -0
- package/util/string.d.ts +4 -4
- package/util/string.js +4 -4
package/package.json
CHANGED
package/schema/ColorSchema.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import { StringSchema } from "./StringSchema.js";
|
|
1
|
+
import { TextSchema, type TextSchemaOptions } from "./TextSchema.js";
|
|
3
2
|
/**
|
|
4
3
|
* Define a valid color hex string, e.g `#00CCFF`
|
|
5
4
|
*
|
|
@@ -9,8 +8,8 @@ import { StringSchema } from "./StringSchema.js";
|
|
|
9
8
|
*
|
|
10
9
|
* Colors are limited to 512 characters (this can be changed with `max`), but generally these won't be data: URIs so this is a reasonable limit.
|
|
11
10
|
*/
|
|
12
|
-
export declare class ColorSchema extends
|
|
13
|
-
constructor({ title, value, ...options }: Omit<
|
|
11
|
+
export declare class ColorSchema extends TextSchema {
|
|
12
|
+
constructor({ title, value, ...options }: Omit<TextSchemaOptions, "type" | "min" | "max" | "multiline" | "match">);
|
|
14
13
|
sanitize(insaneString: string): string;
|
|
15
14
|
}
|
|
16
15
|
/** Valid color hex string, e.g. `#00CCFF` (required because empty string is invalid). */
|
package/schema/ColorSchema.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { OPTIONAL } from "./OptionalSchema.js";
|
|
2
|
-
import {
|
|
2
|
+
import { TextSchema } from "./TextSchema.js";
|
|
3
3
|
const COLOR_REGEXP = /^#[0-9A-F]{6}$/;
|
|
4
4
|
const NOT_HEX_REGEXP = /[^0-9A-F]/g;
|
|
5
5
|
/**
|
|
@@ -11,7 +11,7 @@ const NOT_HEX_REGEXP = /[^0-9A-F]/g;
|
|
|
11
11
|
*
|
|
12
12
|
* Colors are limited to 512 characters (this can be changed with `max`), but generally these won't be data: URIs so this is a reasonable limit.
|
|
13
13
|
*/
|
|
14
|
-
export class ColorSchema extends
|
|
14
|
+
export class ColorSchema extends TextSchema {
|
|
15
15
|
constructor({ title = "Color", value = "#000000", ...options }) {
|
|
16
16
|
super({
|
|
17
17
|
title,
|
package/schema/EmailSchema.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { StringSchemaOptions } from "./StringSchema.js";
|
|
2
|
-
import {
|
|
2
|
+
import { TextSchema } from "./TextSchema.js";
|
|
3
3
|
/**
|
|
4
4
|
* Define a valid email address.
|
|
5
5
|
*
|
|
@@ -17,9 +17,9 @@ import { StringSchema } from "./StringSchema.js";
|
|
|
17
17
|
* - Up to 10 segments of up to 63 characters each, separated by `.`
|
|
18
18
|
* - TLD is a segment of 2-63 characters, possibly in `xn--` international format.
|
|
19
19
|
*/
|
|
20
|
-
export declare class EmailSchema extends
|
|
20
|
+
export declare class EmailSchema extends TextSchema {
|
|
21
21
|
constructor({ title, ...options }: Omit<StringSchemaOptions, "type" | "min" | "max" | "match" | "multiline">);
|
|
22
|
-
sanitize(
|
|
22
|
+
sanitize(str: string): string;
|
|
23
23
|
}
|
|
24
24
|
/** Valid email, e.g. `test@test.com` */
|
|
25
25
|
export declare const EMAIL: EmailSchema;
|
package/schema/EmailSchema.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { OPTIONAL } from "./OptionalSchema.js";
|
|
2
|
-
import {
|
|
2
|
+
import { TextSchema } from "./TextSchema.js";
|
|
3
3
|
const R_MATCH = /^[a-z0-9](?:[a-zA-Z0-9._+-]{0,62}[a-zA-Z0-9])?@(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.){1,3}(?:[a-z]{2,63}|xn--[a-z0-9-]{0,58}[a-z0-9])$/;
|
|
4
4
|
/**
|
|
5
5
|
* Define a valid email address.
|
|
@@ -18,7 +18,7 @@ const R_MATCH = /^[a-z0-9](?:[a-zA-Z0-9._+-]{0,62}[a-zA-Z0-9])?@(?:[a-z0-9](?:[a
|
|
|
18
18
|
* - Up to 10 segments of up to 63 characters each, separated by `.`
|
|
19
19
|
* - TLD is a segment of 2-63 characters, possibly in `xn--` international format.
|
|
20
20
|
*/
|
|
21
|
-
export class EmailSchema extends
|
|
21
|
+
export class EmailSchema extends TextSchema {
|
|
22
22
|
constructor({ title = "Email", ...options }) {
|
|
23
23
|
super({
|
|
24
24
|
title,
|
|
@@ -30,9 +30,8 @@ export class EmailSchema extends StringSchema {
|
|
|
30
30
|
multiline: false,
|
|
31
31
|
});
|
|
32
32
|
}
|
|
33
|
-
sanitize(
|
|
34
|
-
|
|
35
|
-
return typeof sanitizedString === "string" ? sanitizedString.toLowerCase() : sanitizedString;
|
|
33
|
+
sanitize(str) {
|
|
34
|
+
return super.sanitize(str).toLowerCase();
|
|
36
35
|
}
|
|
37
36
|
}
|
|
38
37
|
/** Valid email, e.g. `test@test.com` */
|
package/schema/KeySchema.d.ts
CHANGED
|
@@ -2,11 +2,14 @@ import { StringSchema, type StringSchemaOptions } from "./StringSchema.js";
|
|
|
2
2
|
/**
|
|
3
3
|
* Define a valid database key.
|
|
4
4
|
*
|
|
5
|
+
* - Characters that are not a-z, A-Z, 0-9 are removed.
|
|
5
6
|
* - Default minimum key length is 1 character.
|
|
6
|
-
* - Default maximum key length is
|
|
7
|
+
* - Default maximum key length is 32 characters.
|
|
8
|
+
* - 32 characters is enough for UUIDs, as the 4 `-` hyphens are removed.
|
|
7
9
|
*/
|
|
8
10
|
export declare class KeySchema extends StringSchema {
|
|
9
11
|
constructor({ min, max, ...options }: StringSchemaOptions);
|
|
12
|
+
sanitize(str: string): string;
|
|
10
13
|
}
|
|
11
14
|
/** Valid database key. */
|
|
12
15
|
export declare const KEY: KeySchema;
|
package/schema/KeySchema.js
CHANGED
|
@@ -1,17 +1,23 @@
|
|
|
1
1
|
import { OPTIONAL } from "./OptionalSchema.js";
|
|
2
2
|
import { StringSchema } from "./StringSchema.js";
|
|
3
|
+
const R_NOT_CHAR = /[^a-zA-Z0-9]/g;
|
|
3
4
|
/**
|
|
4
5
|
* Define a valid database key.
|
|
5
6
|
*
|
|
7
|
+
* - Characters that are not a-z, A-Z, 0-9 are removed.
|
|
6
8
|
* - Default minimum key length is 1 character.
|
|
7
|
-
* - Default maximum key length is
|
|
9
|
+
* - Default maximum key length is 32 characters.
|
|
10
|
+
* - 32 characters is enough for UUIDs, as the 4 `-` hyphens are removed.
|
|
8
11
|
*/
|
|
9
12
|
export class KeySchema extends StringSchema {
|
|
10
|
-
constructor({ min = 1, max =
|
|
13
|
+
constructor({ min = 1, max = 32, ...options }) {
|
|
11
14
|
super({ min, max, ...options });
|
|
12
15
|
}
|
|
16
|
+
sanitize(str) {
|
|
17
|
+
return str.replace(R_NOT_CHAR, "");
|
|
18
|
+
}
|
|
13
19
|
}
|
|
14
20
|
/** Valid database key. */
|
|
15
|
-
export const KEY = new KeySchema({});
|
|
21
|
+
export const KEY = new KeySchema({ title: "ID" });
|
|
16
22
|
/** Valid optional database key. */
|
|
17
23
|
export const OPTIONAL_KEY = OPTIONAL(KEY);
|
package/schema/LinkSchema.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ImmutableArray } from "../util/array.js";
|
|
2
2
|
import { type AbsoluteLink } from "../util/link.js";
|
|
3
3
|
import type { StringSchemaOptions } from "./StringSchema.js";
|
|
4
|
-
import {
|
|
4
|
+
import { TextSchema } from "./TextSchema.js";
|
|
5
5
|
/** Allowed options for `LinkSchema` */
|
|
6
6
|
export interface LinkSchemaOptions extends Omit<StringSchemaOptions, "type" | "min" | "max" | "multiline"> {
|
|
7
7
|
readonly base?: AbsoluteLink | undefined;
|
|
@@ -14,7 +14,7 @@ export interface LinkSchemaOptions extends Omit<StringSchemaOptions, "type" | "m
|
|
|
14
14
|
* - URLs are limited to 512 characters, but generally these won't be data: URIs so this is a reasonable limit.
|
|
15
15
|
* - Falsy values are converted to `""` empty string.
|
|
16
16
|
*/
|
|
17
|
-
export declare class LinkSchema extends
|
|
17
|
+
export declare class LinkSchema extends TextSchema {
|
|
18
18
|
readonly base: AbsoluteLink | undefined;
|
|
19
19
|
readonly schemes: ImmutableArray<string> | undefined;
|
|
20
20
|
readonly hosts: ImmutableArray<string> | undefined;
|
package/schema/LinkSchema.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { ValueFeedback } from "../feedback/Feedback.js";
|
|
2
2
|
import { getOptionalLinkURL } from "../util/link.js";
|
|
3
3
|
import { OPTIONAL } from "./OptionalSchema.js";
|
|
4
|
-
import {
|
|
4
|
+
import { TextSchema } from "./TextSchema.js";
|
|
5
5
|
/**
|
|
6
6
|
* Type of `StringSchema` that defines a valid URL link.
|
|
7
7
|
* - Checks URL scheme against a whitelist (always), and checks URL domain against a whitelist (optional).
|
|
8
8
|
* - URLs are limited to 512 characters, but generally these won't be data: URIs so this is a reasonable limit.
|
|
9
9
|
* - Falsy values are converted to `""` empty string.
|
|
10
10
|
*/
|
|
11
|
-
export class LinkSchema extends
|
|
11
|
+
export class LinkSchema extends TextSchema {
|
|
12
12
|
base;
|
|
13
13
|
schemes;
|
|
14
14
|
hosts;
|
|
@@ -27,10 +27,10 @@ export class LinkSchema extends StringSchema {
|
|
|
27
27
|
}
|
|
28
28
|
// Override to clean the URL using builtin helper functions and check the schemes and hosts against the whitelists.
|
|
29
29
|
validate(unsafeValue) {
|
|
30
|
-
const
|
|
31
|
-
const url = getOptionalLinkURL(
|
|
30
|
+
const str = super.validate(unsafeValue);
|
|
31
|
+
const url = getOptionalLinkURL(str, this.base, this.schemes, this.hosts);
|
|
32
32
|
if (!url)
|
|
33
|
-
throw new ValueFeedback(
|
|
33
|
+
throw new ValueFeedback(str ? "Invalid format" : "Required", str);
|
|
34
34
|
return url.href;
|
|
35
35
|
}
|
|
36
36
|
}
|
package/schema/NumberSchema.js
CHANGED
|
@@ -26,7 +26,7 @@ export class NumberSchema extends Schema {
|
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
/** Valid number, e.g. `2048.12345` or `0` zero. */
|
|
29
|
-
export const NUMBER = new NumberSchema({});
|
|
29
|
+
export const NUMBER = new NumberSchema({ title: "Number" });
|
|
30
30
|
/** Valid optional number, e.g. `2048.12345` or `0` zero, or `null` */
|
|
31
31
|
export const OPTIONAL_NUMBER = OPTIONAL(NUMBER);
|
|
32
32
|
/** Valid integer number, e.g. `2048` or `0` zero. */
|
package/schema/PhoneSchema.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { StringSchemaOptions } from "./StringSchema.js";
|
|
2
|
-
import {
|
|
2
|
+
import { TextSchema } from "./TextSchema.js";
|
|
3
3
|
/**
|
|
4
4
|
* Type of `StringSchema` that defines a valid phone number.
|
|
5
5
|
* - Multiple string formats are automatically converted to E.164 format (starting with `+` plus).
|
|
6
6
|
* - Falsy values are converted to `""` empty string.
|
|
7
7
|
*/
|
|
8
|
-
export declare class PhoneSchema extends
|
|
8
|
+
export declare class PhoneSchema extends TextSchema {
|
|
9
9
|
constructor({ title, ...options }: StringSchemaOptions);
|
|
10
10
|
sanitize(insaneString: string): string;
|
|
11
11
|
}
|
package/schema/PhoneSchema.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { OPTIONAL } from "./OptionalSchema.js";
|
|
2
|
-
import {
|
|
2
|
+
import { TextSchema } from "./TextSchema.js";
|
|
3
3
|
// Valid phone number is max 16 digits made up of:
|
|
4
4
|
// - Country code (`+` plus character and 1-3 digits, e.g. `+44` or `+1`).
|
|
5
5
|
// - Subscriber number (5-12 digits — the Solomon Islands have five-digit phone numbers apparently).
|
|
@@ -9,7 +9,7 @@ const PHONE_REGEXP = /^\+[1-9][0-9]{0,2}[0-9]{5,12}$/;
|
|
|
9
9
|
* - Multiple string formats are automatically converted to E.164 format (starting with `+` plus).
|
|
10
10
|
* - Falsy values are converted to `""` empty string.
|
|
11
11
|
*/
|
|
12
|
-
export class PhoneSchema extends
|
|
12
|
+
export class PhoneSchema extends TextSchema {
|
|
13
13
|
constructor({ title = "Phone", ...options }) {
|
|
14
14
|
super({
|
|
15
15
|
title,
|
package/schema/SlugSchema.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { StringSchema, type StringSchemaOptions } from "./StringSchema.js";
|
|
|
8
8
|
*/
|
|
9
9
|
export declare class SlugSchema extends StringSchema {
|
|
10
10
|
constructor(options: Omit<StringSchemaOptions, "min" | "max" | "multiline">);
|
|
11
|
-
sanitize(
|
|
11
|
+
sanitize(str: string): string;
|
|
12
12
|
}
|
|
13
13
|
/** Valid slug, e.g. `this-is-a-slug` */
|
|
14
14
|
export declare const SLUG: SlugSchema;
|
package/schema/SlugSchema.js
CHANGED
|
@@ -14,11 +14,10 @@ export class SlugSchema extends StringSchema {
|
|
|
14
14
|
...options,
|
|
15
15
|
min: 2,
|
|
16
16
|
max: 32,
|
|
17
|
-
multiline: false,
|
|
18
17
|
});
|
|
19
18
|
}
|
|
20
|
-
sanitize(
|
|
21
|
-
return getSlug(
|
|
19
|
+
sanitize(str) {
|
|
20
|
+
return getSlug(str);
|
|
22
21
|
}
|
|
23
22
|
}
|
|
24
23
|
/** Valid slug, e.g. `this-is-a-slug` */
|
package/schema/StringSchema.d.ts
CHANGED
|
@@ -1,27 +1,16 @@
|
|
|
1
1
|
import type { SchemaOptions } from "./Schema.js";
|
|
2
2
|
import { Schema } from "./Schema.js";
|
|
3
|
-
/** `type=""` prop for HTML `<input />` tags that are relevant for strings. */
|
|
4
|
-
export type HtmlInputType = "text" | "password" | "color" | "date" | "email" | "number" | "tel" | "search" | "url";
|
|
5
3
|
/** Function that sanitizes a string. */
|
|
6
4
|
export type Sanitizer = (str: string) => string;
|
|
7
5
|
/** Options for `StringSchema` */
|
|
8
6
|
export interface StringSchemaOptions extends SchemaOptions {
|
|
9
7
|
readonly value?: string | undefined;
|
|
10
|
-
readonly type?: HtmlInputType | undefined;
|
|
11
8
|
readonly min?: number | undefined;
|
|
12
9
|
readonly max?: number | undefined;
|
|
13
|
-
readonly match?: RegExp | undefined;
|
|
14
|
-
readonly sanitizer?: Sanitizer | undefined;
|
|
15
|
-
readonly multiline?: boolean | undefined;
|
|
16
10
|
}
|
|
17
11
|
/**
|
|
18
12
|
* Schema that defines a valid string.
|
|
19
13
|
*
|
|
20
|
-
* Ensures value is string and optionally enforces min/max length, whether to trim whitespace, and regex match format.
|
|
21
|
-
* Doesn't allow `null` to mean no value — empty string is the equivalent for StringSchema (because it means we'll never accidentally get `"null"` by converting the `null` to string).
|
|
22
|
-
*
|
|
23
|
-
* Defaults to a single line text string (newlines are stripped). Use `multiline=true` to allow newlines.
|
|
24
|
-
*
|
|
25
14
|
* @example
|
|
26
15
|
* const schema = new StringSchema({ default: 'abc', required: true, min: 2, max: 6, match: /^[a-z0-9]+$/, trim: true });
|
|
27
16
|
* schema.validate('def'); // Returns 'def'
|
|
@@ -36,32 +25,14 @@ export interface StringSchemaOptions extends SchemaOptions {
|
|
|
36
25
|
*/
|
|
37
26
|
export declare class StringSchema extends Schema<string> {
|
|
38
27
|
readonly value: string;
|
|
39
|
-
readonly type: HtmlInputType;
|
|
40
28
|
readonly min: number;
|
|
41
29
|
readonly max: number;
|
|
42
|
-
|
|
43
|
-
readonly sanitizer: Sanitizer | undefined;
|
|
44
|
-
readonly multiline: boolean;
|
|
45
|
-
constructor({ type, min, max, match, sanitizer, multiline, value, ...options }: StringSchemaOptions);
|
|
30
|
+
constructor({ min, max, value, ...options }: StringSchemaOptions);
|
|
46
31
|
validate(unsafeValue?: unknown): string;
|
|
47
|
-
/**
|
|
48
|
-
|
|
49
|
-
* - Might be empty string if the string contained only invalid characters.
|
|
50
|
-
* - Applies `options.sanitizer` too (if it's set).
|
|
51
|
-
*/
|
|
52
|
-
sanitize(insaneString: string): string;
|
|
32
|
+
/** Sanitize the string by removing unwanted characters. */
|
|
33
|
+
sanitize(str: string): string;
|
|
53
34
|
}
|
|
54
35
|
/** Valid string, e.g. `Hello there!` */
|
|
55
36
|
export declare const STRING: StringSchema;
|
|
56
37
|
/** Valid string, `Hello there!`, with more than one character. */
|
|
57
38
|
export declare const REQUIRED_STRING: StringSchema;
|
|
58
|
-
/** Title string, e.g. `Title of something` */
|
|
59
|
-
export declare const TITLE: StringSchema;
|
|
60
|
-
/** Optional name string, e.g. `Title of something` or `null` */
|
|
61
|
-
export declare const OPTIONAL_TITLE: import("./OptionalSchema.js").OptionalSchema<string>;
|
|
62
|
-
/** Name string, e.g. `Name of Something` */
|
|
63
|
-
export declare const NAME: StringSchema;
|
|
64
|
-
/** Optional name string, e.g. `Name of Something` or `null` */
|
|
65
|
-
export declare const OPTIONAL_NAME: import("./OptionalSchema.js").OptionalSchema<string>;
|
|
66
|
-
/** Password string. */
|
|
67
|
-
export declare const PASSWORD: StringSchema;
|
package/schema/StringSchema.js
CHANGED
|
@@ -1,15 +1,8 @@
|
|
|
1
1
|
import { ValueFeedback } from "../feedback/Feedback.js";
|
|
2
|
-
import { sanitizeLines, sanitizeString } from "../util/string.js";
|
|
3
|
-
import { OPTIONAL } from "./OptionalSchema.js";
|
|
4
2
|
import { Schema } from "./Schema.js";
|
|
5
3
|
/**
|
|
6
4
|
* Schema that defines a valid string.
|
|
7
5
|
*
|
|
8
|
-
* Ensures value is string and optionally enforces min/max length, whether to trim whitespace, and regex match format.
|
|
9
|
-
* Doesn't allow `null` to mean no value — empty string is the equivalent for StringSchema (because it means we'll never accidentally get `"null"` by converting the `null` to string).
|
|
10
|
-
*
|
|
11
|
-
* Defaults to a single line text string (newlines are stripped). Use `multiline=true` to allow newlines.
|
|
12
|
-
*
|
|
13
6
|
* @example
|
|
14
7
|
* const schema = new StringSchema({ default: 'abc', required: true, min: 2, max: 6, match: /^[a-z0-9]+$/, trim: true });
|
|
15
8
|
* schema.validate('def'); // Returns 'def'
|
|
@@ -23,20 +16,12 @@ import { Schema } from "./Schema.js";
|
|
|
23
16
|
* schema.validate('j'); // Throws 'Minimum 3 chaacters'
|
|
24
17
|
*/
|
|
25
18
|
export class StringSchema extends Schema {
|
|
26
|
-
type;
|
|
27
19
|
min;
|
|
28
20
|
max;
|
|
29
|
-
|
|
30
|
-
sanitizer;
|
|
31
|
-
multiline;
|
|
32
|
-
constructor({ type = "text", min = 0, max = Number.POSITIVE_INFINITY, match, sanitizer, multiline = false, value = "", ...options }) {
|
|
21
|
+
constructor({ min = 0, max = Number.POSITIVE_INFINITY, value = "", ...options }) {
|
|
33
22
|
super({ value, ...options });
|
|
34
|
-
this.type = type;
|
|
35
23
|
this.min = min;
|
|
36
24
|
this.max = max;
|
|
37
|
-
this.match = match;
|
|
38
|
-
this.sanitizer = sanitizer;
|
|
39
|
-
this.multiline = multiline;
|
|
40
25
|
}
|
|
41
26
|
validate(unsafeValue = this.value) {
|
|
42
27
|
const possibleString = typeof unsafeValue === "number" ? unsafeValue.toString() : unsafeValue;
|
|
@@ -47,30 +32,14 @@ export class StringSchema extends Schema {
|
|
|
47
32
|
throw new ValueFeedback(saneString ? `Minimum ${this.min} characters` : "Required", saneString);
|
|
48
33
|
if (saneString.length > this.max)
|
|
49
34
|
throw new ValueFeedback(`Maximum ${this.max} characters`, saneString);
|
|
50
|
-
if (this.match && !this.match.test(saneString))
|
|
51
|
-
throw new ValueFeedback(saneString ? "Invalid format" : "Required", saneString);
|
|
52
35
|
return saneString;
|
|
53
36
|
}
|
|
54
|
-
/**
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
* - Applies `options.sanitizer` too (if it's set).
|
|
58
|
-
*/
|
|
59
|
-
sanitize(insaneString) {
|
|
60
|
-
return this.sanitizer ? this.sanitizer(insaneString) : this.multiline ? sanitizeLines(insaneString) : sanitizeString(insaneString);
|
|
37
|
+
/** Sanitize the string by removing unwanted characters. */
|
|
38
|
+
sanitize(str) {
|
|
39
|
+
return str;
|
|
61
40
|
}
|
|
62
41
|
}
|
|
63
42
|
/** Valid string, e.g. `Hello there!` */
|
|
64
43
|
export const STRING = new StringSchema({});
|
|
65
44
|
/** Valid string, `Hello there!`, with more than one character. */
|
|
66
45
|
export const REQUIRED_STRING = new StringSchema({ min: 1 });
|
|
67
|
-
/** Title string, e.g. `Title of something` */
|
|
68
|
-
export const TITLE = new StringSchema({ title: "Title", min: 1, max: 100 });
|
|
69
|
-
/** Optional name string, e.g. `Title of something` or `null` */
|
|
70
|
-
export const OPTIONAL_TITLE = OPTIONAL(TITLE);
|
|
71
|
-
/** Name string, e.g. `Name of Something` */
|
|
72
|
-
export const NAME = new StringSchema({ title: "Name", min: 1, max: 100 });
|
|
73
|
-
/** Optional name string, e.g. `Name of Something` or `null` */
|
|
74
|
-
export const OPTIONAL_NAME = OPTIONAL(NAME);
|
|
75
|
-
/** Password string. */
|
|
76
|
-
export const PASSWORD = new StringSchema({ title: "Password", min: 6, type: "password" });
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type Sanitizer, StringSchema, type StringSchemaOptions } from "./StringSchema.js";
|
|
2
|
+
/** `type=""` prop for HTML `<input />` tags that are relevant for strings. */
|
|
3
|
+
export type TextSchemaType = "text" | "password" | "color" | "date" | "email" | "number" | "tel" | "search" | "url";
|
|
4
|
+
/** Options for `TextSchema` */
|
|
5
|
+
export interface TextSchemaOptions extends StringSchemaOptions {
|
|
6
|
+
readonly type?: TextSchemaType | undefined;
|
|
7
|
+
readonly match?: RegExp | undefined;
|
|
8
|
+
readonly multiline?: boolean | undefined;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Schema that defines a valid text string.
|
|
12
|
+
*
|
|
13
|
+
* Ensures value is string and optionally enforces min/max length, whether to trim whitespace, and regex match format.
|
|
14
|
+
* Doesn't allow `null` to mean no value — empty string is the equivalent for StringSchema (because it means we'll never accidentally get `"null"` by converting the `null` to string).
|
|
15
|
+
*
|
|
16
|
+
* Defaults to a single line text string (newlines are stripped). Use `multiline=true` to allow newlines.
|
|
17
|
+
*/
|
|
18
|
+
export declare class TextSchema extends StringSchema {
|
|
19
|
+
readonly type: TextSchemaType;
|
|
20
|
+
readonly match: RegExp | undefined;
|
|
21
|
+
readonly sanitizer: Sanitizer | undefined;
|
|
22
|
+
readonly multiline: boolean;
|
|
23
|
+
constructor({ type, match, multiline, ...options }: TextSchemaOptions);
|
|
24
|
+
validate(unsafeValue?: unknown): string;
|
|
25
|
+
sanitize(str: string): string;
|
|
26
|
+
}
|
|
27
|
+
/** Valid text, e.g. `Hello there!` */
|
|
28
|
+
export declare const TEXT: TextSchema;
|
|
29
|
+
/** Valid text, `Hello there!`, with more than one character. */
|
|
30
|
+
export declare const REQUIRED_TEXT: TextSchema;
|
|
31
|
+
/** Title string, e.g. `Title of something` */
|
|
32
|
+
export declare const TITLE: TextSchema;
|
|
33
|
+
/** Optional name string, e.g. `Title of something` or `null` */
|
|
34
|
+
export declare const OPTIONAL_TITLE: import("./OptionalSchema.js").OptionalSchema<string>;
|
|
35
|
+
/** Name string, e.g. `Name of Something` */
|
|
36
|
+
export declare const NAME: TextSchema;
|
|
37
|
+
/** Optional name string, e.g. `Name of Something` or `null` */
|
|
38
|
+
export declare const OPTIONAL_NAME: import("./OptionalSchema.js").OptionalSchema<string>;
|
|
39
|
+
/** Password string. */
|
|
40
|
+
export declare const PASSWORD: TextSchema;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ValueFeedback } from "../feedback/Feedback.js";
|
|
2
|
+
import { sanitizeMultilineText, sanitizeText } from "../util/string.js";
|
|
3
|
+
import { OPTIONAL } from "./OptionalSchema.js";
|
|
4
|
+
import { StringSchema } from "./StringSchema.js";
|
|
5
|
+
/**
|
|
6
|
+
* Schema that defines a valid text string.
|
|
7
|
+
*
|
|
8
|
+
* Ensures value is string and optionally enforces min/max length, whether to trim whitespace, and regex match format.
|
|
9
|
+
* Doesn't allow `null` to mean no value — empty string is the equivalent for StringSchema (because it means we'll never accidentally get `"null"` by converting the `null` to string).
|
|
10
|
+
*
|
|
11
|
+
* Defaults to a single line text string (newlines are stripped). Use `multiline=true` to allow newlines.
|
|
12
|
+
*/
|
|
13
|
+
export class TextSchema extends StringSchema {
|
|
14
|
+
type;
|
|
15
|
+
match;
|
|
16
|
+
sanitizer;
|
|
17
|
+
multiline;
|
|
18
|
+
constructor({ type = "text", match, multiline = false, ...options }) {
|
|
19
|
+
super(options);
|
|
20
|
+
this.type = type;
|
|
21
|
+
this.match = match;
|
|
22
|
+
this.multiline = multiline;
|
|
23
|
+
}
|
|
24
|
+
validate(unsafeValue = this.value) {
|
|
25
|
+
const str = super.validate(unsafeValue);
|
|
26
|
+
if (this.match && !this.match.test(str))
|
|
27
|
+
throw new ValueFeedback(str ? "Invalid format" : "Required", str);
|
|
28
|
+
return str;
|
|
29
|
+
}
|
|
30
|
+
sanitize(str) {
|
|
31
|
+
return this.multiline ? sanitizeMultilineText(str) : sanitizeText(str);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/** Valid text, e.g. `Hello there!` */
|
|
35
|
+
export const TEXT = new TextSchema({ title: "Text" });
|
|
36
|
+
/** Valid text, `Hello there!`, with more than one character. */
|
|
37
|
+
export const REQUIRED_TEXT = new TextSchema({ min: 1 });
|
|
38
|
+
/** Title string, e.g. `Title of something` */
|
|
39
|
+
export const TITLE = new TextSchema({ title: "Title", min: 1, max: 100 });
|
|
40
|
+
/** Optional name string, e.g. `Title of something` or `null` */
|
|
41
|
+
export const OPTIONAL_TITLE = OPTIONAL(TITLE);
|
|
42
|
+
/** Name string, e.g. `Name of Something` */
|
|
43
|
+
export const NAME = new TextSchema({ title: "Name", min: 1, max: 100 });
|
|
44
|
+
/** Optional name string, e.g. `Name of Something` or `null` */
|
|
45
|
+
export const OPTIONAL_NAME = OPTIONAL(NAME);
|
|
46
|
+
/** Password string. */
|
|
47
|
+
export const PASSWORD = new TextSchema({ title: "Password", min: 6, type: "password" });
|
package/schema/index.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export * from "./NumberSchema.js";
|
|
|
15
15
|
export * from "./PhoneSchema.js";
|
|
16
16
|
export * from "./SlugSchema.js";
|
|
17
17
|
export * from "./StringSchema.js";
|
|
18
|
+
export * from "./TextSchema.js";
|
|
18
19
|
export * from "./TimeSchema.js";
|
|
19
20
|
export * from "./ThroughSchema.js";
|
|
20
21
|
export * from "./OptionalSchema.js";
|
package/schema/index.js
CHANGED
|
@@ -15,6 +15,7 @@ export * from "./NumberSchema.js";
|
|
|
15
15
|
export * from "./PhoneSchema.js";
|
|
16
16
|
export * from "./SlugSchema.js";
|
|
17
17
|
export * from "./StringSchema.js";
|
|
18
|
+
export * from "./TextSchema.js";
|
|
18
19
|
export * from "./TimeSchema.js";
|
|
19
20
|
export * from "./ThroughSchema.js";
|
|
20
21
|
export * from "./OptionalSchema.js";
|
package/util/string.d.ts
CHANGED
|
@@ -36,7 +36,7 @@ export declare function getStringLength(str: string, min?: number, max?: number)
|
|
|
36
36
|
/** Concatenate an iterable set of strings together. */
|
|
37
37
|
export declare function joinStrings(strs: Iterable<string> & NotString, joiner?: string): string;
|
|
38
38
|
/**
|
|
39
|
-
* Sanitize a single
|
|
39
|
+
* Sanitize a single line of text.
|
|
40
40
|
* - Used when you're sanitising a single-line input, e.g. a title for something.
|
|
41
41
|
* - Remove allow control characters
|
|
42
42
|
* - Normalise runs of whitespace to one ` ` space,
|
|
@@ -44,9 +44,9 @@ export declare function joinStrings(strs: Iterable<string> & NotString, joiner?:
|
|
|
44
44
|
*
|
|
45
45
|
* @example santizeString("\x00Nice! "); // Returns `"Nice!"`
|
|
46
46
|
*/
|
|
47
|
-
export declare function
|
|
47
|
+
export declare function sanitizeText(str: string): string;
|
|
48
48
|
/**
|
|
49
|
-
* Sanitize
|
|
49
|
+
* Sanitize multiple lines of text.
|
|
50
50
|
* - Used when you're sanitising a multi-line input, e.g. a description for something.
|
|
51
51
|
* - Remove all control characters except `\n` newline.
|
|
52
52
|
* - Normalise weird characters like paragraph separator, line separator, `\t` tab, `\r` carriage return.
|
|
@@ -55,7 +55,7 @@ export declare function sanitizeString(str: string): string;
|
|
|
55
55
|
* - Allow spaces at the start of each line (for indentation) but trim the end of each line.
|
|
56
56
|
* - Trim excess newlines at the start and end of the string and runs of more than two newlines in a row.
|
|
57
57
|
*/
|
|
58
|
-
export declare function
|
|
58
|
+
export declare function sanitizeMultilineText(str: string): string;
|
|
59
59
|
/**
|
|
60
60
|
* Simplify a string by removing anything that isn't a number, letter, or space.
|
|
61
61
|
* - Normalizes the string by
|
package/util/string.js
CHANGED
|
@@ -65,7 +65,7 @@ export function joinStrings(strs, joiner = "") {
|
|
|
65
65
|
return getArray(strs).join(joiner);
|
|
66
66
|
}
|
|
67
67
|
/**
|
|
68
|
-
* Sanitize a single
|
|
68
|
+
* Sanitize a single line of text.
|
|
69
69
|
* - Used when you're sanitising a single-line input, e.g. a title for something.
|
|
70
70
|
* - Remove allow control characters
|
|
71
71
|
* - Normalise runs of whitespace to one ` ` space,
|
|
@@ -73,14 +73,14 @@ export function joinStrings(strs, joiner = "") {
|
|
|
73
73
|
*
|
|
74
74
|
* @example santizeString("\x00Nice! "); // Returns `"Nice!"`
|
|
75
75
|
*/
|
|
76
|
-
export function
|
|
76
|
+
export function sanitizeText(str) {
|
|
77
77
|
return str
|
|
78
78
|
.replace(/[^\P{C}\s]/gu, "") // Strip control characters (except whitespace).
|
|
79
79
|
.replace(/\s+/gu, " ") // Normalise runs of whitespace to one ` ` space.
|
|
80
80
|
.trim(); // Trim whitespace from the start and end of the string.
|
|
81
81
|
}
|
|
82
82
|
/**
|
|
83
|
-
* Sanitize
|
|
83
|
+
* Sanitize multiple lines of text.
|
|
84
84
|
* - Used when you're sanitising a multi-line input, e.g. a description for something.
|
|
85
85
|
* - Remove all control characters except `\n` newline.
|
|
86
86
|
* - Normalise weird characters like paragraph separator, line separator, `\t` tab, `\r` carriage return.
|
|
@@ -89,7 +89,7 @@ export function sanitizeString(str) {
|
|
|
89
89
|
* - Allow spaces at the start of each line (for indentation) but trim the end of each line.
|
|
90
90
|
* - Trim excess newlines at the start and end of the string and runs of more than two newlines in a row.
|
|
91
91
|
*/
|
|
92
|
-
export function
|
|
92
|
+
export function sanitizeMultilineText(str) {
|
|
93
93
|
return str
|
|
94
94
|
.replace(/[^\P{C}\s]/gu, "") // Strip control characters (except whitespace).
|
|
95
95
|
.replace(/\r\n?|\v|\x85|\u2028/g, "\n") // Normalise line separators to `\n` newline
|