@ls-stack/utils 3.42.0 → 3.44.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/dist/cache.cjs +24 -2
- package/dist/cache.d.cts +8 -1
- package/dist/cache.d.ts +8 -1
- package/dist/cache.js +10 -208
- package/dist/chunk-OIAGLRII.js +236 -0
- package/dist/concurrentCalls.js +3 -3
- package/dist/matchPath.cjs +148 -0
- package/dist/matchPath.d.cts +53 -0
- package/dist/matchPath.d.ts +53 -0
- package/dist/matchPath.js +107 -0
- package/dist/partialEqual.cjs +289 -0
- package/dist/partialEqual.d.cts +71 -0
- package/dist/partialEqual.d.ts +71 -0
- package/dist/partialEqual.js +201 -0
- package/dist/typingFnUtils.d.cts +7 -0
- package/dist/typingFnUtils.d.ts +7 -0
- package/package.json +9 -1
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
type _PathParam<Path extends string> = Path extends `${infer L}/${infer R}` ? _PathParam<L> | _PathParam<R> : Path extends `:${infer Param}` ? Param extends `${infer Optional}?` ? Optional : Param : never;
|
|
2
|
+
type PathParam<Path extends string> = Path extends '*' | '/*' ? '*' : Path extends `${infer Rest}/*` ? '*' | _PathParam<Rest> : _PathParam<Path>;
|
|
3
|
+
type ParamParseKey<Segment extends string> = [
|
|
4
|
+
PathParam<Segment>
|
|
5
|
+
] extends [never] ? string : PathParam<Segment>;
|
|
6
|
+
/** A PathPattern is used to match on some portion of a URL pathname. */
|
|
7
|
+
interface PathPattern<Path extends string = string> {
|
|
8
|
+
/**
|
|
9
|
+
* A string to match against a URL pathname. May contain `:id`-style segments
|
|
10
|
+
* to indicate placeholders for dynamic parameters. May also end with `/*` to
|
|
11
|
+
* indicate matching the rest of the URL pathname.
|
|
12
|
+
*/
|
|
13
|
+
path: Path;
|
|
14
|
+
/**
|
|
15
|
+
* Should be `true` if the static portions of the `path` should be matched in
|
|
16
|
+
* the same case.
|
|
17
|
+
*/
|
|
18
|
+
caseSensitive?: boolean;
|
|
19
|
+
/** Should be `true` if this pattern should match the entire URL pathname. */
|
|
20
|
+
end?: boolean;
|
|
21
|
+
}
|
|
22
|
+
/** The parameters that were parsed from the URL path. */
|
|
23
|
+
type Params<Key extends string = string> = {
|
|
24
|
+
readonly [key in Key]: string | undefined;
|
|
25
|
+
};
|
|
26
|
+
type PathMatchGlob = {
|
|
27
|
+
matchPath: <K extends ParamParseKey<Path>, Path extends string>(pattern: PathPattern<Path> | Path) => PathMatch<K> | null;
|
|
28
|
+
path: string;
|
|
29
|
+
};
|
|
30
|
+
/** A PathMatch contains info about how a PathPattern matched on a URL pathname. */
|
|
31
|
+
interface PathMatch<ParamKey extends string = string> {
|
|
32
|
+
/** The names and values of dynamic parameters in the URL. */
|
|
33
|
+
params: Params<ParamKey>;
|
|
34
|
+
/** The portion of the URL pathname that was matched. */
|
|
35
|
+
pathname: string;
|
|
36
|
+
/** The portion of the URL pathname that was matched before child routes. */
|
|
37
|
+
pathnameBase: string;
|
|
38
|
+
/** The pattern that was used to match. */
|
|
39
|
+
pattern: PathPattern;
|
|
40
|
+
glob: null | PathMatchGlob;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Performs pattern matching on a URL pathname and returns information about the
|
|
44
|
+
* match.
|
|
45
|
+
*
|
|
46
|
+
* @see https://reactrouter.com/utils/match-path
|
|
47
|
+
*/
|
|
48
|
+
declare function matchPath<ParamKey extends ParamParseKey<Path>, Path extends string>(pattern: PathPattern<Path> | Path, pathname: string): PathMatch<ParamKey> | null;
|
|
49
|
+
declare function matchPathWith(path: string | undefined | null): {
|
|
50
|
+
patterns: <R>(patterns: Record<string, (match: PathMatch) => R>) => R | null;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export { type ParamParseKey, type Params, type PathMatch, type PathMatchGlob, type PathParam, type PathPattern, matchPath, matchPathWith };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
type _PathParam<Path extends string> = Path extends `${infer L}/${infer R}` ? _PathParam<L> | _PathParam<R> : Path extends `:${infer Param}` ? Param extends `${infer Optional}?` ? Optional : Param : never;
|
|
2
|
+
type PathParam<Path extends string> = Path extends '*' | '/*' ? '*' : Path extends `${infer Rest}/*` ? '*' | _PathParam<Rest> : _PathParam<Path>;
|
|
3
|
+
type ParamParseKey<Segment extends string> = [
|
|
4
|
+
PathParam<Segment>
|
|
5
|
+
] extends [never] ? string : PathParam<Segment>;
|
|
6
|
+
/** A PathPattern is used to match on some portion of a URL pathname. */
|
|
7
|
+
interface PathPattern<Path extends string = string> {
|
|
8
|
+
/**
|
|
9
|
+
* A string to match against a URL pathname. May contain `:id`-style segments
|
|
10
|
+
* to indicate placeholders for dynamic parameters. May also end with `/*` to
|
|
11
|
+
* indicate matching the rest of the URL pathname.
|
|
12
|
+
*/
|
|
13
|
+
path: Path;
|
|
14
|
+
/**
|
|
15
|
+
* Should be `true` if the static portions of the `path` should be matched in
|
|
16
|
+
* the same case.
|
|
17
|
+
*/
|
|
18
|
+
caseSensitive?: boolean;
|
|
19
|
+
/** Should be `true` if this pattern should match the entire URL pathname. */
|
|
20
|
+
end?: boolean;
|
|
21
|
+
}
|
|
22
|
+
/** The parameters that were parsed from the URL path. */
|
|
23
|
+
type Params<Key extends string = string> = {
|
|
24
|
+
readonly [key in Key]: string | undefined;
|
|
25
|
+
};
|
|
26
|
+
type PathMatchGlob = {
|
|
27
|
+
matchPath: <K extends ParamParseKey<Path>, Path extends string>(pattern: PathPattern<Path> | Path) => PathMatch<K> | null;
|
|
28
|
+
path: string;
|
|
29
|
+
};
|
|
30
|
+
/** A PathMatch contains info about how a PathPattern matched on a URL pathname. */
|
|
31
|
+
interface PathMatch<ParamKey extends string = string> {
|
|
32
|
+
/** The names and values of dynamic parameters in the URL. */
|
|
33
|
+
params: Params<ParamKey>;
|
|
34
|
+
/** The portion of the URL pathname that was matched. */
|
|
35
|
+
pathname: string;
|
|
36
|
+
/** The portion of the URL pathname that was matched before child routes. */
|
|
37
|
+
pathnameBase: string;
|
|
38
|
+
/** The pattern that was used to match. */
|
|
39
|
+
pattern: PathPattern;
|
|
40
|
+
glob: null | PathMatchGlob;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Performs pattern matching on a URL pathname and returns information about the
|
|
44
|
+
* match.
|
|
45
|
+
*
|
|
46
|
+
* @see https://reactrouter.com/utils/match-path
|
|
47
|
+
*/
|
|
48
|
+
declare function matchPath<ParamKey extends ParamParseKey<Path>, Path extends string>(pattern: PathPattern<Path> | Path, pathname: string): PathMatch<ParamKey> | null;
|
|
49
|
+
declare function matchPathWith(path: string | undefined | null): {
|
|
50
|
+
patterns: <R>(patterns: Record<string, (match: PathMatch) => R>) => R | null;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export { type ParamParseKey, type Params, type PathMatch, type PathMatchGlob, type PathParam, type PathPattern, matchPath, matchPathWith };
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import {
|
|
2
|
+
fastCache
|
|
3
|
+
} from "./chunk-OIAGLRII.js";
|
|
4
|
+
import "./chunk-5MNYPLZI.js";
|
|
5
|
+
import "./chunk-HTCYUMDR.js";
|
|
6
|
+
import "./chunk-II4R3VVX.js";
|
|
7
|
+
import "./chunk-C2SVCIWE.js";
|
|
8
|
+
import "./chunk-JF2MDHOJ.js";
|
|
9
|
+
|
|
10
|
+
// src/matchPath.ts
|
|
11
|
+
function matchPath(pattern, pathname) {
|
|
12
|
+
if (typeof pattern === "string") {
|
|
13
|
+
pattern = { path: pattern, caseSensitive: false, end: true };
|
|
14
|
+
}
|
|
15
|
+
const [matcher, compiledParams] = compilePath(
|
|
16
|
+
pattern.path,
|
|
17
|
+
pattern.caseSensitive,
|
|
18
|
+
pattern.end
|
|
19
|
+
);
|
|
20
|
+
const match = pathname.match(matcher);
|
|
21
|
+
if (!match) return null;
|
|
22
|
+
const matchedPathname = match[0];
|
|
23
|
+
let pathnameBase = matchedPathname.replace(/(.)\/+$/, "$1");
|
|
24
|
+
const captureGroups = match.slice(1);
|
|
25
|
+
const params = compiledParams.reduce(
|
|
26
|
+
(memo, { paramName, isOptional }, index) => {
|
|
27
|
+
if (paramName === "*") {
|
|
28
|
+
const splatValue = captureGroups[index] || "";
|
|
29
|
+
pathnameBase = matchedPathname.slice(0, matchedPathname.length - splatValue.length).replace(/(.)\/+$/, "$1");
|
|
30
|
+
}
|
|
31
|
+
const value = captureGroups[index];
|
|
32
|
+
if (isOptional && !value) {
|
|
33
|
+
memo[paramName] = void 0;
|
|
34
|
+
} else {
|
|
35
|
+
memo[paramName] = (value || "").replace(/%2F/g, "/");
|
|
36
|
+
}
|
|
37
|
+
return memo;
|
|
38
|
+
},
|
|
39
|
+
{}
|
|
40
|
+
);
|
|
41
|
+
const glob = params["*"];
|
|
42
|
+
const globPath = glob && `/${glob}`;
|
|
43
|
+
return {
|
|
44
|
+
params,
|
|
45
|
+
pathname: matchedPathname,
|
|
46
|
+
pathnameBase,
|
|
47
|
+
pattern,
|
|
48
|
+
glob: globPath ? {
|
|
49
|
+
matchPath: (subPattern) => matchPath(subPattern, globPath),
|
|
50
|
+
path: globPath
|
|
51
|
+
} : null
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function warning(condition, message) {
|
|
55
|
+
if (process.env.NODE_ENV === "development" && !condition) {
|
|
56
|
+
console.warn(message);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
var cache = fastCache({ maxCacheSize: 5e3 });
|
|
60
|
+
function compilePath(path, caseSensitive = false, end = true) {
|
|
61
|
+
return cache.getOrInsert(
|
|
62
|
+
`${path}-${caseSensitive ? "s" : "i"}${end ? "e" : ""}`,
|
|
63
|
+
() => {
|
|
64
|
+
warning(
|
|
65
|
+
path === "*" || !path.endsWith("*") || path.endsWith("/*"),
|
|
66
|
+
`Route path "${path}" will be treated as if it were "${path.replace(/\*$/, "/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${path.replace(/\*$/, "/*")}".`
|
|
67
|
+
);
|
|
68
|
+
const params = [];
|
|
69
|
+
let regexpSource = `^${path.replace(/\/*\*?$/, "").replace(/^\/*/, "/").replace(/[\\.*+^${}|()[\]]/g, "\\$&").replace(
|
|
70
|
+
/\/:([\w-]+)(\?)?/g,
|
|
71
|
+
(_, paramName, isOptional) => {
|
|
72
|
+
params.push({ paramName, isOptional: isOptional != null });
|
|
73
|
+
return isOptional ? "/?([^\\/]+)?" : "/([^\\/]+)";
|
|
74
|
+
}
|
|
75
|
+
)}`;
|
|
76
|
+
if (path.endsWith("*")) {
|
|
77
|
+
params.push({ paramName: "*" });
|
|
78
|
+
regexpSource += path === "*" || path === "/*" ? "(.*)$" : "(?:\\/(.+)|\\/*)$";
|
|
79
|
+
} else if (end) {
|
|
80
|
+
regexpSource += "\\/*$";
|
|
81
|
+
} else if (path !== "" && path !== "/") {
|
|
82
|
+
regexpSource += "(?:(?=\\/|$))";
|
|
83
|
+
} else {
|
|
84
|
+
}
|
|
85
|
+
const matcher = new RegExp(regexpSource, caseSensitive ? void 0 : "i");
|
|
86
|
+
return [matcher, params];
|
|
87
|
+
}
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
function matchPathWith(path) {
|
|
91
|
+
return {
|
|
92
|
+
patterns: (patternsToMatch) => {
|
|
93
|
+
if (!path) return null;
|
|
94
|
+
for (const [key, pattern] of Object.entries(patternsToMatch)) {
|
|
95
|
+
const match = matchPath(key, path);
|
|
96
|
+
if (match) {
|
|
97
|
+
return pattern(match);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
export {
|
|
105
|
+
matchPath,
|
|
106
|
+
matchPathWith
|
|
107
|
+
};
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/partialEqual.ts
|
|
21
|
+
var partialEqual_exports = {};
|
|
22
|
+
__export(partialEqual_exports, {
|
|
23
|
+
match: () => match,
|
|
24
|
+
partialEqual: () => partialEqual
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(partialEqual_exports);
|
|
27
|
+
|
|
28
|
+
// src/deepEqual.ts
|
|
29
|
+
var has = Object.prototype.hasOwnProperty;
|
|
30
|
+
function find(iter, tar, maxDepth) {
|
|
31
|
+
for (const key of iter.keys()) {
|
|
32
|
+
if (deepEqual(key, tar, maxDepth)) return key;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function deepEqual(foo, bar, maxDepth = 20) {
|
|
36
|
+
let ctor, len, tmp;
|
|
37
|
+
if (foo === bar) return true;
|
|
38
|
+
if (maxDepth && maxDepth <= 0) return false;
|
|
39
|
+
if (foo && bar && (ctor = foo.constructor) === bar.constructor) {
|
|
40
|
+
if (ctor === Date)
|
|
41
|
+
return deepEqual(foo.getTime(), bar.getTime(), maxDepth - 1);
|
|
42
|
+
if (ctor === RegExp) return foo.toString() === bar.toString();
|
|
43
|
+
if (ctor === Array) {
|
|
44
|
+
if ((len = foo.length) === bar.length) {
|
|
45
|
+
while (len-- && deepEqual(foo[len], bar[len], maxDepth - 1)) ;
|
|
46
|
+
}
|
|
47
|
+
return len === -1;
|
|
48
|
+
}
|
|
49
|
+
if (ctor === Set) {
|
|
50
|
+
if (foo.size !== bar.size) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
for (len of foo) {
|
|
54
|
+
tmp = len;
|
|
55
|
+
if (tmp && typeof tmp === "object") {
|
|
56
|
+
tmp = find(bar, tmp, maxDepth - 1);
|
|
57
|
+
if (!tmp) return false;
|
|
58
|
+
}
|
|
59
|
+
if (!bar.has(tmp)) return false;
|
|
60
|
+
}
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
if (ctor === Map) {
|
|
64
|
+
if (foo.size !== bar.size) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
for (len of foo) {
|
|
68
|
+
tmp = len[0];
|
|
69
|
+
if (tmp && typeof tmp === "object") {
|
|
70
|
+
tmp = find(bar, tmp, maxDepth - 1);
|
|
71
|
+
if (!tmp) return false;
|
|
72
|
+
}
|
|
73
|
+
if (!deepEqual(len[1], bar.get(tmp), maxDepth - 1)) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
if (!ctor || typeof foo === "object") {
|
|
80
|
+
len = 0;
|
|
81
|
+
for (ctor in foo) {
|
|
82
|
+
if (has.call(foo, ctor) && ++len && !has.call(bar, ctor)) return false;
|
|
83
|
+
if (!(ctor in bar) || !deepEqual(foo[ctor], bar[ctor], maxDepth - 1))
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
return Object.keys(bar).length === len;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return foo !== foo && bar !== bar;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// src/partialEqual.ts
|
|
93
|
+
var has2 = Object.prototype.hasOwnProperty;
|
|
94
|
+
var Comparisons = class {
|
|
95
|
+
type;
|
|
96
|
+
constructor(type) {
|
|
97
|
+
this.type = type;
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
var match = {
|
|
101
|
+
hasType: {
|
|
102
|
+
string: new Comparisons(["hasType", "string"]),
|
|
103
|
+
number: new Comparisons(["hasType", "number"]),
|
|
104
|
+
boolean: new Comparisons(["hasType", "boolean"]),
|
|
105
|
+
object: new Comparisons(["hasType", "object"]),
|
|
106
|
+
array: new Comparisons(["hasType", "array"]),
|
|
107
|
+
function: new Comparisons(["hasType", "function"])
|
|
108
|
+
},
|
|
109
|
+
isInstanceOf: (constructor) => new Comparisons(["isInstanceOf", constructor]),
|
|
110
|
+
str: {
|
|
111
|
+
contains: (substring) => new Comparisons(["strContains", substring]),
|
|
112
|
+
startsWith: (substring) => new Comparisons(["strStartsWith", substring]),
|
|
113
|
+
endsWith: (substring) => new Comparisons(["strEndsWith", substring]),
|
|
114
|
+
matchesRegex: (regex) => new Comparisons(["strMatchesRegex", regex])
|
|
115
|
+
},
|
|
116
|
+
num: {
|
|
117
|
+
isGreaterThan: (value) => new Comparisons(["numIsGreaterThan", value]),
|
|
118
|
+
isGreaterThanOrEqual: (value) => new Comparisons(["numIsGreaterThanOrEqual", value]),
|
|
119
|
+
isLessThan: (value) => new Comparisons(["numIsLessThan", value]),
|
|
120
|
+
isLessThanOrEqual: (value) => new Comparisons(["numIsLessThanOrEqual", value]),
|
|
121
|
+
isInRange: (value) => new Comparisons(["numIsInRange", value])
|
|
122
|
+
},
|
|
123
|
+
jsonString: {
|
|
124
|
+
hasPartial: (value) => new Comparisons(["jsonStringHasPartial", value])
|
|
125
|
+
},
|
|
126
|
+
equal: (value) => new Comparisons(["deepEqual", value]),
|
|
127
|
+
partialEqual: (value) => new Comparisons(["partialEqual", value]),
|
|
128
|
+
custom: (isEqual) => new Comparisons(["custom", isEqual]),
|
|
129
|
+
not: {
|
|
130
|
+
hasType: {
|
|
131
|
+
string: new Comparisons(["not", ["hasType", "string"]]),
|
|
132
|
+
number: new Comparisons(["not", ["hasType", "number"]]),
|
|
133
|
+
boolean: new Comparisons(["not", ["hasType", "boolean"]]),
|
|
134
|
+
object: new Comparisons(["not", ["hasType", "object"]]),
|
|
135
|
+
array: new Comparisons(["not", ["hasType", "array"]]),
|
|
136
|
+
function: new Comparisons(["not", ["hasType", "function"]])
|
|
137
|
+
},
|
|
138
|
+
isInstanceOf: (constructor) => new Comparisons(["not", ["isInstanceOf", constructor]]),
|
|
139
|
+
str: {
|
|
140
|
+
contains: (substring) => new Comparisons(["not", ["strContains", substring]]),
|
|
141
|
+
startsWith: (substring) => new Comparisons(["not", ["strStartsWith", substring]]),
|
|
142
|
+
endsWith: (substring) => new Comparisons(["not", ["strEndsWith", substring]]),
|
|
143
|
+
matchesRegex: (regex) => new Comparisons(["not", ["strMatchesRegex", regex]])
|
|
144
|
+
},
|
|
145
|
+
num: {
|
|
146
|
+
isGreaterThan: (value) => new Comparisons(["not", ["numIsGreaterThan", value]]),
|
|
147
|
+
isGreaterThanOrEqual: (value) => new Comparisons(["not", ["numIsGreaterThanOrEqual", value]]),
|
|
148
|
+
isLessThan: (value) => new Comparisons(["not", ["numIsLessThan", value]]),
|
|
149
|
+
isLessThanOrEqual: (value) => new Comparisons(["not", ["numIsLessThanOrEqual", value]]),
|
|
150
|
+
isInRange: (value) => new Comparisons(["not", ["numIsInRange", value]])
|
|
151
|
+
},
|
|
152
|
+
jsonString: {
|
|
153
|
+
hasPartial: (value) => new Comparisons(["not", ["jsonStringHasPartial", value]])
|
|
154
|
+
},
|
|
155
|
+
equal: (value) => new Comparisons(["not", ["deepEqual", value]]),
|
|
156
|
+
partialEqual: (value) => new Comparisons(["not", ["partialEqual", value]]),
|
|
157
|
+
custom: (value) => new Comparisons(["not", ["custom", value]])
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
function find2(iter, tar) {
|
|
161
|
+
for (const key of iter.keys()) {
|
|
162
|
+
if (partialEqual(key, tar)) return key;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function executeComparison(target, comparison) {
|
|
166
|
+
const [type, value] = comparison;
|
|
167
|
+
switch (type) {
|
|
168
|
+
case "hasType":
|
|
169
|
+
switch (value) {
|
|
170
|
+
case "string":
|
|
171
|
+
return typeof target === "string";
|
|
172
|
+
case "number":
|
|
173
|
+
return typeof target === "number";
|
|
174
|
+
case "boolean":
|
|
175
|
+
return typeof target === "boolean";
|
|
176
|
+
case "function":
|
|
177
|
+
return typeof target === "function";
|
|
178
|
+
case "array":
|
|
179
|
+
return Array.isArray(target);
|
|
180
|
+
case "object":
|
|
181
|
+
return typeof target === "object" && target !== null && !Array.isArray(target);
|
|
182
|
+
default:
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
case "isInstanceOf":
|
|
186
|
+
return target instanceof value;
|
|
187
|
+
case "strStartsWith":
|
|
188
|
+
return typeof target === "string" && target.startsWith(value);
|
|
189
|
+
case "strEndsWith":
|
|
190
|
+
return typeof target === "string" && target.endsWith(value);
|
|
191
|
+
case "strContains":
|
|
192
|
+
return typeof target === "string" && target.includes(value);
|
|
193
|
+
case "strMatchesRegex":
|
|
194
|
+
return typeof target === "string" && value.test(target);
|
|
195
|
+
case "numIsGreaterThan":
|
|
196
|
+
return typeof target === "number" && target > value;
|
|
197
|
+
case "numIsGreaterThanOrEqual":
|
|
198
|
+
return typeof target === "number" && target >= value;
|
|
199
|
+
case "numIsLessThan":
|
|
200
|
+
return typeof target === "number" && target < value;
|
|
201
|
+
case "numIsLessThanOrEqual":
|
|
202
|
+
return typeof target === "number" && target <= value;
|
|
203
|
+
case "numIsInRange":
|
|
204
|
+
return typeof target === "number" && target >= value[0] && target <= value[1];
|
|
205
|
+
case "jsonStringHasPartial":
|
|
206
|
+
if (typeof target !== "string") return false;
|
|
207
|
+
try {
|
|
208
|
+
const parsed = JSON.parse(target);
|
|
209
|
+
return partialEqual(parsed, value);
|
|
210
|
+
} catch {
|
|
211
|
+
return false;
|
|
212
|
+
}
|
|
213
|
+
case "deepEqual":
|
|
214
|
+
return deepEqual(target, value);
|
|
215
|
+
case "partialEqual":
|
|
216
|
+
return partialEqual(target, value);
|
|
217
|
+
case "custom":
|
|
218
|
+
return value(target);
|
|
219
|
+
case "not":
|
|
220
|
+
return !executeComparison(target, value);
|
|
221
|
+
default:
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
function partialEqual(target, sub) {
|
|
226
|
+
if (sub === target) return true;
|
|
227
|
+
if (sub instanceof Comparisons) {
|
|
228
|
+
return executeComparison(target, sub.type);
|
|
229
|
+
}
|
|
230
|
+
if (sub && target && sub.constructor === target.constructor) {
|
|
231
|
+
const ctor = sub.constructor;
|
|
232
|
+
if (ctor === Date) {
|
|
233
|
+
return sub.getTime() === target.getTime();
|
|
234
|
+
}
|
|
235
|
+
if (ctor === RegExp) {
|
|
236
|
+
return sub.toString() === target.toString();
|
|
237
|
+
}
|
|
238
|
+
if (ctor === Array) {
|
|
239
|
+
if (sub.length > target.length) return false;
|
|
240
|
+
for (let i = 0; i < sub.length; i++) {
|
|
241
|
+
if (!partialEqual(target[i], sub[i])) return false;
|
|
242
|
+
}
|
|
243
|
+
return true;
|
|
244
|
+
}
|
|
245
|
+
if (ctor === Set) {
|
|
246
|
+
if (sub.size > target.size) return false;
|
|
247
|
+
for (const value of sub) {
|
|
248
|
+
let found = false;
|
|
249
|
+
if (value && typeof value === "object") {
|
|
250
|
+
found = !!find2(target, value);
|
|
251
|
+
} else {
|
|
252
|
+
found = target.has(value);
|
|
253
|
+
}
|
|
254
|
+
if (!found) return false;
|
|
255
|
+
}
|
|
256
|
+
return true;
|
|
257
|
+
}
|
|
258
|
+
if (ctor === Map) {
|
|
259
|
+
if (sub.size > target.size) return false;
|
|
260
|
+
for (const [key, value] of sub) {
|
|
261
|
+
let targetKey = key;
|
|
262
|
+
if (key && typeof key === "object") {
|
|
263
|
+
targetKey = find2(target, key);
|
|
264
|
+
if (!targetKey) return false;
|
|
265
|
+
}
|
|
266
|
+
if (!target.has(targetKey) || !partialEqual(target.get(targetKey), value)) {
|
|
267
|
+
return false;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return true;
|
|
271
|
+
}
|
|
272
|
+
if (!ctor || typeof sub === "object") {
|
|
273
|
+
for (const key in sub) {
|
|
274
|
+
if (has2.call(sub, key)) {
|
|
275
|
+
if (!has2.call(target, key) || !partialEqual(target[key], sub[key])) {
|
|
276
|
+
return false;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return true;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return sub !== sub && target !== target;
|
|
284
|
+
}
|
|
285
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
286
|
+
0 && (module.exports = {
|
|
287
|
+
match,
|
|
288
|
+
partialEqual
|
|
289
|
+
});
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
type ComparisonsType = [type: 'strStartsWith', value: string] | [type: 'strEndsWith', value: string] | [
|
|
2
|
+
type: 'hasType',
|
|
3
|
+
value: 'string' | 'number' | 'boolean' | 'object' | 'array' | 'function'
|
|
4
|
+
] | [type: 'strContains', value: string] | [type: 'strMatchesRegex', value: RegExp] | [type: 'deepEqual', value: any] | [type: 'numIsGreaterThan', value: number] | [type: 'numIsGreaterThanOrEqual', value: number] | [type: 'numIsLessThan', value: number] | [type: 'numIsLessThanOrEqual', value: number] | [type: 'numIsInRange', value: [number, number]] | [type: 'jsonStringHasPartial', value: any] | [type: 'partialEqual', value: any] | [type: 'custom', value: (target: unknown) => boolean] | [type: 'isInstanceOf', value: new (...args: any[]) => any] | [type: 'not', value: ComparisonsType];
|
|
5
|
+
declare class Comparisons {
|
|
6
|
+
type: ComparisonsType;
|
|
7
|
+
constructor(type: ComparisonsType);
|
|
8
|
+
}
|
|
9
|
+
declare const match: {
|
|
10
|
+
hasType: {
|
|
11
|
+
string: Comparisons;
|
|
12
|
+
number: Comparisons;
|
|
13
|
+
boolean: Comparisons;
|
|
14
|
+
object: Comparisons;
|
|
15
|
+
array: Comparisons;
|
|
16
|
+
function: Comparisons;
|
|
17
|
+
};
|
|
18
|
+
isInstanceOf: (constructor: new (...args: any[]) => any) => Comparisons;
|
|
19
|
+
str: {
|
|
20
|
+
contains: (substring: string) => Comparisons;
|
|
21
|
+
startsWith: (substring: string) => Comparisons;
|
|
22
|
+
endsWith: (substring: string) => Comparisons;
|
|
23
|
+
matchesRegex: (regex: RegExp) => Comparisons;
|
|
24
|
+
};
|
|
25
|
+
num: {
|
|
26
|
+
isGreaterThan: (value: number) => Comparisons;
|
|
27
|
+
isGreaterThanOrEqual: (value: number) => Comparisons;
|
|
28
|
+
isLessThan: (value: number) => Comparisons;
|
|
29
|
+
isLessThanOrEqual: (value: number) => Comparisons;
|
|
30
|
+
isInRange: (value: [number, number]) => Comparisons;
|
|
31
|
+
};
|
|
32
|
+
jsonString: {
|
|
33
|
+
hasPartial: (value: any) => Comparisons;
|
|
34
|
+
};
|
|
35
|
+
equal: (value: any) => Comparisons;
|
|
36
|
+
partialEqual: (value: any) => Comparisons;
|
|
37
|
+
custom: (isEqual: (value: unknown) => boolean) => Comparisons;
|
|
38
|
+
not: {
|
|
39
|
+
hasType: {
|
|
40
|
+
string: Comparisons;
|
|
41
|
+
number: Comparisons;
|
|
42
|
+
boolean: Comparisons;
|
|
43
|
+
object: Comparisons;
|
|
44
|
+
array: Comparisons;
|
|
45
|
+
function: Comparisons;
|
|
46
|
+
};
|
|
47
|
+
isInstanceOf: (constructor: new (...args: any[]) => any) => Comparisons;
|
|
48
|
+
str: {
|
|
49
|
+
contains: (substring: string) => Comparisons;
|
|
50
|
+
startsWith: (substring: string) => Comparisons;
|
|
51
|
+
endsWith: (substring: string) => Comparisons;
|
|
52
|
+
matchesRegex: (regex: RegExp) => Comparisons;
|
|
53
|
+
};
|
|
54
|
+
num: {
|
|
55
|
+
isGreaterThan: (value: number) => Comparisons;
|
|
56
|
+
isGreaterThanOrEqual: (value: number) => Comparisons;
|
|
57
|
+
isLessThan: (value: number) => Comparisons;
|
|
58
|
+
isLessThanOrEqual: (value: number) => Comparisons;
|
|
59
|
+
isInRange: (value: [number, number]) => Comparisons;
|
|
60
|
+
};
|
|
61
|
+
jsonString: {
|
|
62
|
+
hasPartial: (value: any) => Comparisons;
|
|
63
|
+
};
|
|
64
|
+
equal: (value: any) => Comparisons;
|
|
65
|
+
partialEqual: (value: any) => Comparisons;
|
|
66
|
+
custom: (value: (target: unknown) => boolean) => Comparisons;
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
declare function partialEqual(target: any, sub: any): boolean;
|
|
70
|
+
|
|
71
|
+
export { match, partialEqual };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
type ComparisonsType = [type: 'strStartsWith', value: string] | [type: 'strEndsWith', value: string] | [
|
|
2
|
+
type: 'hasType',
|
|
3
|
+
value: 'string' | 'number' | 'boolean' | 'object' | 'array' | 'function'
|
|
4
|
+
] | [type: 'strContains', value: string] | [type: 'strMatchesRegex', value: RegExp] | [type: 'deepEqual', value: any] | [type: 'numIsGreaterThan', value: number] | [type: 'numIsGreaterThanOrEqual', value: number] | [type: 'numIsLessThan', value: number] | [type: 'numIsLessThanOrEqual', value: number] | [type: 'numIsInRange', value: [number, number]] | [type: 'jsonStringHasPartial', value: any] | [type: 'partialEqual', value: any] | [type: 'custom', value: (target: unknown) => boolean] | [type: 'isInstanceOf', value: new (...args: any[]) => any] | [type: 'not', value: ComparisonsType];
|
|
5
|
+
declare class Comparisons {
|
|
6
|
+
type: ComparisonsType;
|
|
7
|
+
constructor(type: ComparisonsType);
|
|
8
|
+
}
|
|
9
|
+
declare const match: {
|
|
10
|
+
hasType: {
|
|
11
|
+
string: Comparisons;
|
|
12
|
+
number: Comparisons;
|
|
13
|
+
boolean: Comparisons;
|
|
14
|
+
object: Comparisons;
|
|
15
|
+
array: Comparisons;
|
|
16
|
+
function: Comparisons;
|
|
17
|
+
};
|
|
18
|
+
isInstanceOf: (constructor: new (...args: any[]) => any) => Comparisons;
|
|
19
|
+
str: {
|
|
20
|
+
contains: (substring: string) => Comparisons;
|
|
21
|
+
startsWith: (substring: string) => Comparisons;
|
|
22
|
+
endsWith: (substring: string) => Comparisons;
|
|
23
|
+
matchesRegex: (regex: RegExp) => Comparisons;
|
|
24
|
+
};
|
|
25
|
+
num: {
|
|
26
|
+
isGreaterThan: (value: number) => Comparisons;
|
|
27
|
+
isGreaterThanOrEqual: (value: number) => Comparisons;
|
|
28
|
+
isLessThan: (value: number) => Comparisons;
|
|
29
|
+
isLessThanOrEqual: (value: number) => Comparisons;
|
|
30
|
+
isInRange: (value: [number, number]) => Comparisons;
|
|
31
|
+
};
|
|
32
|
+
jsonString: {
|
|
33
|
+
hasPartial: (value: any) => Comparisons;
|
|
34
|
+
};
|
|
35
|
+
equal: (value: any) => Comparisons;
|
|
36
|
+
partialEqual: (value: any) => Comparisons;
|
|
37
|
+
custom: (isEqual: (value: unknown) => boolean) => Comparisons;
|
|
38
|
+
not: {
|
|
39
|
+
hasType: {
|
|
40
|
+
string: Comparisons;
|
|
41
|
+
number: Comparisons;
|
|
42
|
+
boolean: Comparisons;
|
|
43
|
+
object: Comparisons;
|
|
44
|
+
array: Comparisons;
|
|
45
|
+
function: Comparisons;
|
|
46
|
+
};
|
|
47
|
+
isInstanceOf: (constructor: new (...args: any[]) => any) => Comparisons;
|
|
48
|
+
str: {
|
|
49
|
+
contains: (substring: string) => Comparisons;
|
|
50
|
+
startsWith: (substring: string) => Comparisons;
|
|
51
|
+
endsWith: (substring: string) => Comparisons;
|
|
52
|
+
matchesRegex: (regex: RegExp) => Comparisons;
|
|
53
|
+
};
|
|
54
|
+
num: {
|
|
55
|
+
isGreaterThan: (value: number) => Comparisons;
|
|
56
|
+
isGreaterThanOrEqual: (value: number) => Comparisons;
|
|
57
|
+
isLessThan: (value: number) => Comparisons;
|
|
58
|
+
isLessThanOrEqual: (value: number) => Comparisons;
|
|
59
|
+
isInRange: (value: [number, number]) => Comparisons;
|
|
60
|
+
};
|
|
61
|
+
jsonString: {
|
|
62
|
+
hasPartial: (value: any) => Comparisons;
|
|
63
|
+
};
|
|
64
|
+
equal: (value: any) => Comparisons;
|
|
65
|
+
partialEqual: (value: any) => Comparisons;
|
|
66
|
+
custom: (value: (target: unknown) => boolean) => Comparisons;
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
declare function partialEqual(target: any, sub: any): boolean;
|
|
70
|
+
|
|
71
|
+
export { match, partialEqual };
|