shelving 1.30.0 → 1.30.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/package.json +1 -1
- package/schema/StringSchema.d.ts +1 -3
- package/schema/StringSchema.js +2 -7
- package/util/search.d.ts +2 -2
- package/util/search.js +4 -4
- package/util/string.d.ts +7 -5
- package/util/string.js +24 -25
package/package.json
CHANGED
package/schema/StringSchema.d.ts
CHANGED
|
@@ -31,8 +31,7 @@ export declare class StringSchema extends Schema<string> {
|
|
|
31
31
|
readonly match: RegExp | null;
|
|
32
32
|
readonly sanitizer: Sanitizer | null;
|
|
33
33
|
readonly multiline: boolean;
|
|
34
|
-
|
|
35
|
-
constructor({ value, type, min, max, match, sanitizer, multiline, trim, ...rest }: ConstructorParameters<typeof Schema>[0] & {
|
|
34
|
+
constructor({ value, type, min, max, match, sanitizer, multiline, ...rest }: ConstructorParameters<typeof Schema>[0] & {
|
|
36
35
|
readonly value?: string;
|
|
37
36
|
readonly type?: HtmlInputType;
|
|
38
37
|
readonly min?: number;
|
|
@@ -40,7 +39,6 @@ export declare class StringSchema extends Schema<string> {
|
|
|
40
39
|
readonly match?: RegExp | null;
|
|
41
40
|
readonly sanitizer?: Sanitizer | null;
|
|
42
41
|
readonly multiline?: boolean;
|
|
43
|
-
readonly trim?: boolean;
|
|
44
42
|
});
|
|
45
43
|
validate(unsafeValue?: unknown): string;
|
|
46
44
|
/**
|
package/schema/StringSchema.js
CHANGED
|
@@ -22,7 +22,7 @@ import { Schema } from "./Schema.js";
|
|
|
22
22
|
* schema.validate('j'); // Throws 'Minimum 3 chaacters'
|
|
23
23
|
*/
|
|
24
24
|
export class StringSchema extends Schema {
|
|
25
|
-
constructor({ value = "", type = "text", min = 0, max = null, match = null, sanitizer = null, multiline = false,
|
|
25
|
+
constructor({ value = "", type = "text", min = 0, max = null, match = null, sanitizer = null, multiline = false, ...rest }) {
|
|
26
26
|
super(rest);
|
|
27
27
|
this.type = type;
|
|
28
28
|
this.value = value;
|
|
@@ -31,7 +31,6 @@ export class StringSchema extends Schema {
|
|
|
31
31
|
this.match = match;
|
|
32
32
|
this.sanitizer = sanitizer;
|
|
33
33
|
this.multiline = multiline;
|
|
34
|
-
this.trim = trim;
|
|
35
34
|
}
|
|
36
35
|
validate(unsafeValue = this.value) {
|
|
37
36
|
const unsafeString = typeof unsafeValue === "number" ? unsafeValue.toString() : unsafeValue;
|
|
@@ -52,11 +51,7 @@ export class StringSchema extends Schema {
|
|
|
52
51
|
* - Applies `options.sanitizer` too (if it's set).
|
|
53
52
|
*/
|
|
54
53
|
sanitize(uncleanString) {
|
|
55
|
-
return this.sanitizer
|
|
56
|
-
? this.sanitizer(uncleanString)
|
|
57
|
-
: this.multiline
|
|
58
|
-
? sanitizeLines(uncleanString, this.trim)
|
|
59
|
-
: sanitizeString(uncleanString, this.trim);
|
|
54
|
+
return this.sanitizer ? this.sanitizer(uncleanString) : this.multiline ? sanitizeLines(uncleanString) : sanitizeString(uncleanString);
|
|
60
55
|
}
|
|
61
56
|
}
|
|
62
57
|
/** Valid string, e.g. `Hello there!` */
|
package/util/search.d.ts
CHANGED
|
@@ -36,7 +36,7 @@ export declare function MATCHES_ANY(item: unknown, regexps: ImmutableArray<RegEx
|
|
|
36
36
|
* - Quoted phrases match fully (starting and ending with a word boundary).
|
|
37
37
|
*/
|
|
38
38
|
export declare const toWordRegExps: (query: string) => ImmutableArray<RegExp>;
|
|
39
|
-
/** Convert a string
|
|
39
|
+
/** Convert a string to a regular expression matching the start of a word boundary. */
|
|
40
40
|
export declare const toWordRegExp: (word: string) => RegExp;
|
|
41
41
|
/** Matcher that matches any words in a string. */
|
|
42
42
|
export declare class MatchAnyWord implements Matchable<unknown, void> {
|
|
@@ -51,7 +51,7 @@ export declare class MatchAllWords implements Matchable<unknown, void> {
|
|
|
51
51
|
match(value: string): boolean;
|
|
52
52
|
}
|
|
53
53
|
/** Matcher that matches an exact phrase. */
|
|
54
|
-
export declare class
|
|
54
|
+
export declare class MatchWord implements Matchable<unknown, void> {
|
|
55
55
|
private _regexp;
|
|
56
56
|
constructor(phrase: string);
|
|
57
57
|
match(value: string): boolean;
|
package/util/search.js
CHANGED
|
@@ -50,9 +50,9 @@ export function MATCHES_ANY(item, regexps) {
|
|
|
50
50
|
* - Unquoted words match partially (starting with a word boundary).
|
|
51
51
|
* - Quoted phrases match fully (starting and ending with a word boundary).
|
|
52
52
|
*/
|
|
53
|
-
export const toWordRegExps = (query) => toWords(query).map(
|
|
54
|
-
/** Convert a string
|
|
55
|
-
export const toWordRegExp = (word) =>
|
|
53
|
+
export const toWordRegExps = (query) => toWords(query).map(toWordRegExp);
|
|
54
|
+
/** Convert a string to a regular expression matching the start of a word boundary. */
|
|
55
|
+
export const toWordRegExp = (word) => new RegExp(`\\b${escapeRegExp(normalizeString(word))}`, "i");
|
|
56
56
|
/** Matcher that matches any words in a string. */
|
|
57
57
|
export class MatchAnyWord {
|
|
58
58
|
constructor(words) {
|
|
@@ -72,7 +72,7 @@ export class MatchAllWords {
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
/** Matcher that matches an exact phrase. */
|
|
75
|
-
export class
|
|
75
|
+
export class MatchWord {
|
|
76
76
|
constructor(phrase) {
|
|
77
77
|
this._regexp = toWordRegExp(phrase);
|
|
78
78
|
}
|
package/util/string.d.ts
CHANGED
|
@@ -33,25 +33,25 @@ export declare function toTitle(value: unknown): string;
|
|
|
33
33
|
* @param multiline If `true`, `\t` horizontal tabs and `\r` newlines are allowed (defaults to `false` which strips these characters).
|
|
34
34
|
* @returns The clean output string.
|
|
35
35
|
*/
|
|
36
|
-
export declare
|
|
36
|
+
export declare const sanitizeString: (dirty: string) => string;
|
|
37
37
|
/**
|
|
38
38
|
* Sanitize a multiline string.
|
|
39
39
|
* - Like `sanitizeString()` but allows `\t` horizontal tab and `\r` newline.
|
|
40
40
|
*/
|
|
41
|
-
export declare
|
|
41
|
+
export declare const sanitizeLines: (dirty: string) => string;
|
|
42
42
|
/**
|
|
43
43
|
* Normalize a string so it can be compared to another string (free from upper/lower cases, symbols, punctuation).
|
|
44
44
|
*
|
|
45
45
|
* Does the following:
|
|
46
|
-
* -
|
|
46
|
+
* - Removes control characters.
|
|
47
47
|
* - Remove symbols (e.g. `$` dollar) and punctuation (e.g. `"` double quote).
|
|
48
48
|
* - Remove marks (e.g. the umlout dots above `ö`).
|
|
49
49
|
* - Convert spaces/separators to " " single space (e.g. line breaks, non-breaking space).
|
|
50
50
|
* - Convert to lowercase and trim excess whitespace.
|
|
51
51
|
*
|
|
52
|
-
* @example normalizeString("Däve-is
|
|
52
|
+
* @example normalizeString("Däve-is\nREALLY éxcitable—apparęntly!!! 😂"); // Returns "dave is really excitable apparently"
|
|
53
53
|
*/
|
|
54
|
-
export declare const normalizeString: (
|
|
54
|
+
export declare const normalizeString: (str: string) => string;
|
|
55
55
|
/**
|
|
56
56
|
* Convert a string to a `kebab-case` URL slug.
|
|
57
57
|
* - Remove any characters not in the range `[a-z0-9-]`
|
|
@@ -67,6 +67,8 @@ export declare const toSlug: (value: string) => string;
|
|
|
67
67
|
* @returns Array of the found words, e.g. `["yellow", "dog", "Golden Retriever"
|
|
68
68
|
*/
|
|
69
69
|
export declare const toWords: (value: string) => ImmutableArray<string>;
|
|
70
|
+
/** Find and iterate over the words in a string. */
|
|
71
|
+
export declare function yieldWords(value: string): Generator<string, void, void>;
|
|
70
72
|
/**
|
|
71
73
|
* Convert a string to a regular expression that matches that string.
|
|
72
74
|
*
|
package/util/string.js
CHANGED
|
@@ -3,7 +3,6 @@ import { formatDate } from "./date.js";
|
|
|
3
3
|
import { isData } from "./data.js";
|
|
4
4
|
import { isArray } from "./array.js";
|
|
5
5
|
import { formatNumber, isBetween } from "./number.js";
|
|
6
|
-
import { IS_DEFINED } from "./undefined.js";
|
|
7
6
|
/** Is a value a string? */
|
|
8
7
|
export const IS_STRING = (v) => typeof v === "string";
|
|
9
8
|
/**
|
|
@@ -70,47 +69,40 @@ export function toTitle(value) {
|
|
|
70
69
|
* @param multiline If `true`, `\t` horizontal tabs and `\r` newlines are allowed (defaults to `false` which strips these characters).
|
|
71
70
|
* @returns The clean output string.
|
|
72
71
|
*/
|
|
73
|
-
export
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
77
|
-
const CONTROLS = /[\x00-\x1F\x7F-\x9F]/g; // All control characters (`\x00`-`\x1F`, `\x7F`-`\x9F`)
|
|
78
|
-
const SPACES = /\s/g; // Sanitize zero-width spacers etc.
|
|
72
|
+
export const sanitizeString = (dirty) => dirty.replace(SANE_DISALLOWED, "").replace(SANE_SPACES, " ").trim();
|
|
73
|
+
const SANE_DISALLOWED = /[\x00-\x1F\x7F-\x9F]/g; // All control characters (`\x00`-`\x1F`, `\x7F`-`\x9F`)
|
|
74
|
+
const SANE_SPACES = /\s/g; // Zero-width spacers etc.
|
|
79
75
|
/**
|
|
80
76
|
* Sanitize a multiline string.
|
|
81
77
|
* - Like `sanitizeString()` but allows `\t` horizontal tab and `\r` newline.
|
|
82
78
|
*/
|
|
83
|
-
export
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const CONTROLS_MULTILINE = /(?![\t\n])[\x00-\x1F\x7F-\x9F]/g; // Control characters except `\t` horizontal tab and `\n` new line.
|
|
88
|
-
const SPACES_MULTILINE = /(?![\t\n])\s/g; // All spaces except `\t` horizontal tab and `\n` new line.
|
|
89
|
-
const TRIM_END_MULTILINE = /\s+$/gm;
|
|
79
|
+
export const sanitizeLines = (dirty) => dirty.replace(LINES_DISALLOW, "").replace(LINES_SPACES, " ").replace(LINES_TRIM, "");
|
|
80
|
+
const LINES_DISALLOW = /(?![\t\n])[\x00-\x1F\x7F-\x9F]/g; // Control characters except `\t` horizontal tab and `\n` new line.
|
|
81
|
+
const LINES_TRIM = /\s+$/gm; // Spaces at the end of lines.
|
|
82
|
+
const LINES_SPACES = /(?![\t\n])\s/g; // All spaces except `\t` horizontal tab and `\n` new line.
|
|
90
83
|
/**
|
|
91
84
|
* Normalize a string so it can be compared to another string (free from upper/lower cases, symbols, punctuation).
|
|
92
85
|
*
|
|
93
86
|
* Does the following:
|
|
94
|
-
* -
|
|
87
|
+
* - Removes control characters.
|
|
95
88
|
* - Remove symbols (e.g. `$` dollar) and punctuation (e.g. `"` double quote).
|
|
96
89
|
* - Remove marks (e.g. the umlout dots above `ö`).
|
|
97
90
|
* - Convert spaces/separators to " " single space (e.g. line breaks, non-breaking space).
|
|
98
91
|
* - Convert to lowercase and trim excess whitespace.
|
|
99
92
|
*
|
|
100
|
-
* @example normalizeString("Däve-is
|
|
93
|
+
* @example normalizeString("Däve-is\nREALLY éxcitable—apparęntly!!! 😂"); // Returns "dave is really excitable apparently"
|
|
101
94
|
*/
|
|
102
|
-
export const normalizeString = (
|
|
103
|
-
const
|
|
104
|
-
const
|
|
95
|
+
export const normalizeString = (str) => str.normalize("NFD").replace(NORMAL_DISALLOW, "").replace(NORMAL_SPACES, " ").trim().toLowerCase();
|
|
96
|
+
const NORMAL_DISALLOW = /[^\p{L}\p{N}\s]+/gu; // Keep letters, numbers, separators. Don't need to use `\p{Z}` because `\s` matches those already e.g. hair space and nbsp.
|
|
97
|
+
const NORMAL_SPACES = /\s+/gu; // Convert all possible separators to space.
|
|
105
98
|
/**
|
|
106
99
|
* Convert a string to a `kebab-case` URL slug.
|
|
107
100
|
* - Remove any characters not in the range `[a-z0-9-]`
|
|
108
101
|
* - Change all spaces/separators/hyphens/dashes/underscores to `-` single hyphen.
|
|
109
102
|
*/
|
|
110
|
-
export const toSlug = (value) => value.toLowerCase().normalize("NFD").replace(
|
|
111
|
-
const
|
|
112
|
-
const
|
|
113
|
-
const TRIM_HYPHENS = /^-+|-+$/g; // Trim excess hyphens at start and end.
|
|
103
|
+
export const toSlug = (value) => value.toLowerCase().normalize("NFD").replace(SLUG_HYPHENS, "-").replace(SLUG_DISALLOWED, "");
|
|
104
|
+
const SLUG_DISALLOWED = /[^a-z0-9-]+|^-+|-+$/gu; // Remove anything outside a-z and hyphen (except at start/end).
|
|
105
|
+
const SLUG_HYPHENS = /[\s\-–—_]+/gu; // Anything that is a space becomes a hyphen.
|
|
114
106
|
/**
|
|
115
107
|
* Split a string into its separate words.
|
|
116
108
|
* - Words enclosed "in quotes" are a single word.
|
|
@@ -119,8 +111,15 @@ const TRIM_HYPHENS = /^-+|-+$/g; // Trim excess hyphens at start and end.
|
|
|
119
111
|
* @param value The input string, e.g. `yellow dog "Golden Retriever"`
|
|
120
112
|
* @returns Array of the found words, e.g. `["yellow", "dog", "Golden Retriever"
|
|
121
113
|
*/
|
|
122
|
-
export const toWords = (value) => Array.from(value
|
|
123
|
-
|
|
114
|
+
export const toWords = (value) => Array.from(yieldWords(value));
|
|
115
|
+
/** Find and iterate over the words in a string. */
|
|
116
|
+
export function* yieldWords(value) {
|
|
117
|
+
for (const matches of value.matchAll(MATCH_WORD)) {
|
|
118
|
+
const str = matches[1] || matches[0];
|
|
119
|
+
if (str)
|
|
120
|
+
yield str;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
124
123
|
const MATCH_WORD = /[^\s"]+|"([^"]*)"/g;
|
|
125
124
|
/**
|
|
126
125
|
* Convert a string to a regular expression that matches that string.
|