@ptolemy2002/rgx 2.2.0 → 2.3.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/README.md +41 -2
- package/dist/collection.d.ts +41 -0
- package/dist/collection.js +156 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/types.d.ts +2 -1
- package/package.json +8 -2
package/README.md
CHANGED
|
@@ -9,7 +9,8 @@ import { MaybeArray } from "@ptolemy2002/ts-utils";
|
|
|
9
9
|
type RGXNoOpToken = null | undefined;
|
|
10
10
|
type RGXLiteralToken = RegExp;
|
|
11
11
|
type RGXNativeToken = string | number | boolean | RGXNoOpToken;
|
|
12
|
-
type
|
|
12
|
+
type RGXConvertibleTokenOutput = MaybeArray<RGXNativeToken | RGXLiteralToken>;
|
|
13
|
+
type RGXConvertibleToken = { toRgx: () => RGXConvertibleTokenOutput };
|
|
13
14
|
type RGXToken = RGXNativeToken | RGXLiteralToken | RGXConvertibleToken | RGXToken[];
|
|
14
15
|
|
|
15
16
|
const validRegexSymbol = Symbol('rgx.ValidRegex');
|
|
@@ -34,6 +35,7 @@ type ExpectedTokenType = {
|
|
|
34
35
|
type: "custom";
|
|
35
36
|
values: string[];
|
|
36
37
|
};
|
|
38
|
+
type RGXTokenCollectionMode = 'union' | 'concat';
|
|
37
39
|
```
|
|
38
40
|
|
|
39
41
|
## Classes
|
|
@@ -49,17 +51,24 @@ constructor(message: string, code?: RGXErrorCode)
|
|
|
49
51
|
- `message` (`string`): The error message.
|
|
50
52
|
- `code` (`RGXErrorCode`, optional): An optional error code that can be used to categorize the error. If not provided, it defaults to 'UNKNOWN'.
|
|
51
53
|
|
|
54
|
+
#### Properties
|
|
55
|
+
- `code` (`RGXErrorCode`): The error code associated with the error, which can be used to identify the type of error that occurred.
|
|
56
|
+
|
|
52
57
|
### RGXInvalidTokenError extends RGXError
|
|
53
58
|
A specific error class for invalid RGX tokens. This error is thrown when a value fails validation as a specific RGX token type. The error code is set to `INVALID_RGX_TOKEN` on instantiation.
|
|
54
59
|
|
|
55
60
|
#### Constructor
|
|
56
61
|
```typescript
|
|
57
|
-
constructor(message: string, expected:
|
|
62
|
+
constructor(message: string, expected: ExpectedTokenType | null, got: unknown)
|
|
58
63
|
```
|
|
59
64
|
- `message` (`string`): The error message.
|
|
60
65
|
- `expected` (`ExpectedTokenType | null`): Either an object describing the expected token type(s) or `null` if all token types are expected. This is used to generate a human-readable description of what was expected.
|
|
61
66
|
- `got` (`unknown`): The actual value that was received, which failed validation.
|
|
62
67
|
|
|
68
|
+
#### Properties
|
|
69
|
+
- `expected` (`string`): A human-readable description of the expected token type(s), generated from the `expected` parameter in the constructor. This can be used to provide more informative error messages.
|
|
70
|
+
- `got` (`unknown`): The actual value that was received, which failed validation.
|
|
71
|
+
|
|
63
72
|
### RGXInvalidRegexStringError extends RGXError
|
|
64
73
|
A specific error class for invalid regex strings. This error is thrown when a string fails validation as a valid regex string. The error code is set to `INVALID_REGEX_STRING` on instantiation.
|
|
65
74
|
|
|
@@ -70,6 +79,9 @@ constructor(message: string, got: string)
|
|
|
70
79
|
- `message` (`string`): The error message.
|
|
71
80
|
- `got` (`string`): The actual string that was received, which failed validation.
|
|
72
81
|
|
|
82
|
+
#### Properties
|
|
83
|
+
- `got` (`string`): The actual string that was received, which failed validation.
|
|
84
|
+
|
|
73
85
|
### RGXInvalidVanillaRegexFlagsError extends RGXError
|
|
74
86
|
A specific error class for invalid vanilla regex flags. This error is thrown when a string fails validation as valid vanilla regex flags. The error code is set to `INVALID_VANILLA_REGEX_FLAGS` on instantiation.
|
|
75
87
|
|
|
@@ -80,6 +92,30 @@ constructor(message: string, got: string)
|
|
|
80
92
|
- `message` (`string`): The error message.
|
|
81
93
|
- `got` (`string`): The actual string that was received, which failed validation.
|
|
82
94
|
|
|
95
|
+
#### Properties
|
|
96
|
+
- `got` (`string`): The actual string that was received, which failed validation.
|
|
97
|
+
|
|
98
|
+
### RGXTokenCollection
|
|
99
|
+
A class representing a collection of RGX tokens. This is not used internally, but may be useful for users who want to easily manage collections of RGX tokens like an array, but with additional metadata about the collection mode (union or concat).
|
|
100
|
+
|
|
101
|
+
#### Constructor
|
|
102
|
+
```typescript
|
|
103
|
+
constructor(tokens: RGXToken[] = [], mode: RGXTokenCollectionMode = 'concat')
|
|
104
|
+
```
|
|
105
|
+
- `tokens` (`RGXToken[]`, optional): An array of RGX tokens to be managed by the collection. Defaults to an empty array.
|
|
106
|
+
- `mode` (`RGXTokenCollectionMode`, optional): The mode of the collection, either 'union' or 'concat'. Defaults to 'concat'.
|
|
107
|
+
|
|
108
|
+
#### Properties
|
|
109
|
+
- `tokens` (`RGXToken[]`): The array of RGX tokens managed by the collection. In almost all cases, use `getTokens()` instead of accessing this property directly, as it will be copied to prevent external mutation.
|
|
110
|
+
- `mode` (`RGXTokenCollectionMode`): The mode of the collection, either 'union' or 'concat'. This determines how the tokens in the collection will be resolved when `toRgx()` is called.
|
|
111
|
+
- `toRgx()` (`() => RGXToken`): A method that resolves the collection to a single RGX token based on the collection mode. In both modes, a string is ultimately returned, but in 'union' mode, the tokens are resolved as alternatives (using the `|` operator), while in 'concat' mode, the tokens are resolved as concatenated together.
|
|
112
|
+
- `getTokens()` (`() => RGXToken[]`): A method that returns a copy of the array of RGX tokens managed by the collection. This is used to prevent external mutation of the internal `tokens` array.
|
|
113
|
+
- `clone()` (`() => RGXTokenCollection`): A method that creates and returns a deep clone of the RGXTokenCollection instance. This is useful for creating a new collection with the same tokens and mode without affecting the original collection.
|
|
114
|
+
- `asConcat()` (`() => RGXTokenCollection`): If this collection is in 'union' mode, this method returns a new RGXTokenCollection instance with the same tokens but in 'concat' mode. If the collection is already in 'concat' mode, it simply returns itself.
|
|
115
|
+
- `asUnion()` (`() => RGXTokenCollection`): If this collection is in 'concat' mode, this method returns a new RGXTokenCollection instance with the same tokens but in 'union' mode. If the collection is already in 'union' mode, it simply returns itself.
|
|
116
|
+
|
|
117
|
+
Standard array properties and methods like `length`, `push`, `pop`, etc. are implemented to work with the internal `tokens` array, but providing collection instances instead of raw arrays when relevant (e.g., `map` has the third parameter typed as `RGXTokenCollection` instead of `RGXToken[]`).
|
|
118
|
+
|
|
83
119
|
## Functions
|
|
84
120
|
The following functions are exported by the library:
|
|
85
121
|
|
|
@@ -359,9 +395,12 @@ As an alternative to using the `rgx` template tag, you can directly call `rgxa`
|
|
|
359
395
|
- `RegExp`: A `RegExp` object constructed from the resolved tokens and the provided flags.
|
|
360
396
|
|
|
361
397
|
## Peer Dependencies
|
|
398
|
+
- `@ptolemy2002/immutability-utils` ^1.2.1
|
|
399
|
+
- `@ptolemy2002/js-utils` ^3.2.2
|
|
362
400
|
- `@ptolemy2002/ts-brand-utils` ^1.0.0
|
|
363
401
|
- `@ptolemy2002/ts-utils` ^3.4.0
|
|
364
402
|
- `is-callable` ^1.2.7
|
|
403
|
+
- `lodash.clonedeep` ^4.5.0
|
|
365
404
|
|
|
366
405
|
## Commands
|
|
367
406
|
The following commands exist in the project:
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { RGXConvertibleTokenOutput, RGXToken } from "./types";
|
|
2
|
+
export type RGXTokenCollectionMode = 'union' | 'concat';
|
|
3
|
+
export declare class RGXTokenCollection {
|
|
4
|
+
mode: RGXTokenCollectionMode;
|
|
5
|
+
tokens: RGXToken[];
|
|
6
|
+
constructor(tokens?: RGXToken[], mode?: RGXTokenCollectionMode);
|
|
7
|
+
toRgx(): RGXConvertibleTokenOutput;
|
|
8
|
+
getTokens(): RGXToken[];
|
|
9
|
+
clone(): RGXTokenCollection;
|
|
10
|
+
asConcat(): RGXTokenCollection;
|
|
11
|
+
asUnion(): RGXTokenCollection;
|
|
12
|
+
get length(): number;
|
|
13
|
+
at(index: number): RGXToken | undefined;
|
|
14
|
+
find(predicate: (token: RGXToken, index: number, array: RGXToken[]) => boolean): RGXToken | undefined;
|
|
15
|
+
findIndex(predicate: (token: RGXToken, index: number, array: RGXToken[]) => boolean): number;
|
|
16
|
+
indexOf(token: RGXToken, fromIndex?: number): number;
|
|
17
|
+
includes(token: RGXToken, fromIndex?: number): boolean;
|
|
18
|
+
some(predicate: (token: RGXToken, index: number, array: RGXToken[]) => boolean): boolean;
|
|
19
|
+
every(predicate: (token: RGXToken, index: number, array: RGXToken[]) => boolean): boolean;
|
|
20
|
+
forEach(callback: (token: RGXToken, index: number, array: RGXToken[]) => void): void;
|
|
21
|
+
map(callback: (token: RGXToken, index: number, array: RGXToken[]) => RGXToken): RGXTokenCollection;
|
|
22
|
+
filter(predicate: (token: RGXToken, index: number, array: RGXToken[]) => boolean): RGXTokenCollection;
|
|
23
|
+
reduce<T>(callback: (accumulator: T, token: RGXToken, index: number, array: RGXToken[]) => T, initialValue: T): T;
|
|
24
|
+
reduce(callback: (accumulator: RGXToken, token: RGXToken, index: number, array: RGXToken[]) => RGXToken): RGXToken;
|
|
25
|
+
flat(depth?: number): RGXTokenCollection;
|
|
26
|
+
flatMap(callback: (token: RGXToken, index: number, array: RGXToken[]) => RGXToken | RGXToken[]): RGXTokenCollection;
|
|
27
|
+
slice(start?: number, end?: number): RGXTokenCollection;
|
|
28
|
+
concat(...others: (RGXToken | RGXTokenCollection)[]): RGXTokenCollection;
|
|
29
|
+
push(...tokens: RGXToken[]): void;
|
|
30
|
+
pop(): RGXToken | undefined;
|
|
31
|
+
shift(): RGXToken | undefined;
|
|
32
|
+
unshift(...tokens: RGXToken[]): number;
|
|
33
|
+
splice(start: number, deleteCount?: number, ...items: RGXToken[]): RGXTokenCollection;
|
|
34
|
+
reverse(): this;
|
|
35
|
+
sort(compareFn?: (a: RGXToken, b: RGXToken) => number): this;
|
|
36
|
+
fill(value: RGXToken, start?: number, end?: number): this;
|
|
37
|
+
[Symbol.iterator](): Iterator<RGXToken>;
|
|
38
|
+
entries(): IterableIterator<[number, RGXToken]>;
|
|
39
|
+
keys(): IterableIterator<number>;
|
|
40
|
+
values(): IterableIterator<RGXToken>;
|
|
41
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.RGXTokenCollection = void 0;
|
|
7
|
+
const lodash_clonedeep_1 = __importDefault(require("lodash.clonedeep"));
|
|
8
|
+
const index_1 = require("./index");
|
|
9
|
+
const immutability_utils_1 = require("@ptolemy2002/immutability-utils");
|
|
10
|
+
class RGXTokenCollection {
|
|
11
|
+
constructor(tokens = [], mode = 'concat') {
|
|
12
|
+
this.tokens = [];
|
|
13
|
+
this.tokens = (0, lodash_clonedeep_1.default)(tokens);
|
|
14
|
+
this.mode = mode;
|
|
15
|
+
}
|
|
16
|
+
toRgx() {
|
|
17
|
+
if (this.mode === 'union') {
|
|
18
|
+
return (0, index_1.resolveRGXToken)(this.tokens.map(index_1.resolveRGXToken));
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
return (0, index_1.rgxConcat)(this.tokens);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
getTokens() {
|
|
25
|
+
return (0, lodash_clonedeep_1.default)(this.tokens);
|
|
26
|
+
}
|
|
27
|
+
clone() {
|
|
28
|
+
return new RGXTokenCollection(this.tokens, this.mode);
|
|
29
|
+
}
|
|
30
|
+
asConcat() {
|
|
31
|
+
if (this.mode === 'concat')
|
|
32
|
+
return this;
|
|
33
|
+
return (0, immutability_utils_1.immutableMut)(this, clone => {
|
|
34
|
+
clone.mode = 'concat';
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
asUnion() {
|
|
38
|
+
if (this.mode === 'union')
|
|
39
|
+
return this;
|
|
40
|
+
return (0, immutability_utils_1.immutableMut)(this, clone => {
|
|
41
|
+
clone.mode = 'union';
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
// ------------------ Standard array properties and methods ------------------
|
|
45
|
+
get length() {
|
|
46
|
+
return this.tokens.length;
|
|
47
|
+
}
|
|
48
|
+
at(index) {
|
|
49
|
+
return this.tokens[index];
|
|
50
|
+
}
|
|
51
|
+
find(predicate) {
|
|
52
|
+
return this.tokens.find(predicate);
|
|
53
|
+
}
|
|
54
|
+
findIndex(predicate) {
|
|
55
|
+
return this.tokens.findIndex(predicate);
|
|
56
|
+
}
|
|
57
|
+
indexOf(token, fromIndex) {
|
|
58
|
+
return this.tokens.indexOf(token, fromIndex);
|
|
59
|
+
}
|
|
60
|
+
includes(token, fromIndex) {
|
|
61
|
+
return this.tokens.includes(token, fromIndex);
|
|
62
|
+
}
|
|
63
|
+
some(predicate) {
|
|
64
|
+
return this.tokens.some(predicate);
|
|
65
|
+
}
|
|
66
|
+
every(predicate) {
|
|
67
|
+
return this.tokens.every(predicate);
|
|
68
|
+
}
|
|
69
|
+
forEach(callback) {
|
|
70
|
+
this.tokens.forEach(callback);
|
|
71
|
+
}
|
|
72
|
+
map(callback) {
|
|
73
|
+
return (0, immutability_utils_1.immutableMut)(this, clone => {
|
|
74
|
+
clone.tokens = clone.tokens.map(callback);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
filter(predicate) {
|
|
78
|
+
return (0, immutability_utils_1.immutableMut)(this, clone => {
|
|
79
|
+
clone.tokens = clone.tokens.filter(predicate);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
reduce(callback, ...rest) {
|
|
83
|
+
if (rest.length > 0) {
|
|
84
|
+
return this.tokens.reduce(callback, rest[0]);
|
|
85
|
+
}
|
|
86
|
+
return this.tokens.reduce(callback);
|
|
87
|
+
}
|
|
88
|
+
flat(depth = 1) {
|
|
89
|
+
return (0, immutability_utils_1.immutableMut)(this, clone => {
|
|
90
|
+
// Fixing TypeScript complaining about possible infinite recursion here.
|
|
91
|
+
clone.tokens = clone.tokens.flat(depth);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
flatMap(callback) {
|
|
95
|
+
return (0, immutability_utils_1.immutableMut)(this, clone => {
|
|
96
|
+
// Fixing TypeScript complaining about possible infinite recursion here.
|
|
97
|
+
clone.tokens = clone.tokens.flatMap(callback);
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
slice(start, end) {
|
|
101
|
+
return (0, immutability_utils_1.immutableMut)(this, clone => {
|
|
102
|
+
clone.tokens = clone.tokens.slice(start, end);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
concat(...others) {
|
|
106
|
+
return (0, immutability_utils_1.immutableMut)(this, clone => {
|
|
107
|
+
const arrays = others.map(o => o instanceof RGXTokenCollection ? o.tokens : [o]);
|
|
108
|
+
clone.tokens = clone.tokens.concat(...arrays.flat());
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
push(...tokens) {
|
|
112
|
+
this.tokens.push(...tokens);
|
|
113
|
+
}
|
|
114
|
+
pop() {
|
|
115
|
+
return this.tokens.pop();
|
|
116
|
+
}
|
|
117
|
+
shift() {
|
|
118
|
+
return this.tokens.shift();
|
|
119
|
+
}
|
|
120
|
+
unshift(...tokens) {
|
|
121
|
+
return this.tokens.unshift(...tokens);
|
|
122
|
+
}
|
|
123
|
+
splice(start, deleteCount, ...items) {
|
|
124
|
+
return (0, immutability_utils_1.immutableMut)(this, clone => {
|
|
125
|
+
const removed = deleteCount === undefined
|
|
126
|
+
? this.tokens.splice(start)
|
|
127
|
+
: this.tokens.splice(start, deleteCount, ...items);
|
|
128
|
+
clone.tokens = removed;
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
reverse() {
|
|
132
|
+
this.tokens.reverse();
|
|
133
|
+
return this;
|
|
134
|
+
}
|
|
135
|
+
sort(compareFn) {
|
|
136
|
+
this.tokens.sort(compareFn);
|
|
137
|
+
return this;
|
|
138
|
+
}
|
|
139
|
+
fill(value, start, end) {
|
|
140
|
+
this.tokens.fill(value, start, end);
|
|
141
|
+
return this;
|
|
142
|
+
}
|
|
143
|
+
[Symbol.iterator]() {
|
|
144
|
+
return this.tokens[Symbol.iterator]();
|
|
145
|
+
}
|
|
146
|
+
entries() {
|
|
147
|
+
return this.tokens.entries();
|
|
148
|
+
}
|
|
149
|
+
keys() {
|
|
150
|
+
return this.tokens.keys();
|
|
151
|
+
}
|
|
152
|
+
values() {
|
|
153
|
+
return this.tokens.values();
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
exports.RGXTokenCollection = RGXTokenCollection;
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import * as t from "./types";
|
|
|
2
2
|
export * from "./errors";
|
|
3
3
|
export * from "./types";
|
|
4
4
|
export * from "./typeGuards";
|
|
5
|
+
export * from "./collection";
|
|
5
6
|
export declare function escapeRegex(value: string): t.ValidRegexString;
|
|
6
7
|
export declare function resolveRGXToken(token: t.RGXToken): t.ValidRegexString;
|
|
7
8
|
export declare function rgxConcat(tokens: t.RGXToken[]): t.ValidRegexString;
|
package/dist/index.js
CHANGED
|
@@ -46,6 +46,7 @@ const tg = __importStar(require("./typeGuards"));
|
|
|
46
46
|
__exportStar(require("./errors"), exports);
|
|
47
47
|
__exportStar(require("./types"), exports);
|
|
48
48
|
__exportStar(require("./typeGuards"), exports);
|
|
49
|
+
__exportStar(require("./collection"), exports);
|
|
49
50
|
function escapeRegex(value) {
|
|
50
51
|
return value.replaceAll(/[\-\^\$.*+?^${}()|[\]\\]/g, '\\$&');
|
|
51
52
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -3,8 +3,9 @@ import { MaybeArray } from "@ptolemy2002/ts-utils";
|
|
|
3
3
|
export type RGXNoOpToken = null | undefined;
|
|
4
4
|
export type RGXLiteralToken = RegExp;
|
|
5
5
|
export type RGXNativeToken = string | number | boolean | RGXNoOpToken;
|
|
6
|
+
export type RGXConvertibleTokenOutput = MaybeArray<RGXNativeToken | RGXLiteralToken>;
|
|
6
7
|
export type RGXConvertibleToken = {
|
|
7
|
-
toRgx: () =>
|
|
8
|
+
toRgx: () => RGXConvertibleTokenOutput;
|
|
8
9
|
};
|
|
9
10
|
export type RGXToken = RGXNativeToken | RGXLiteralToken | RGXConvertibleToken | RGXToken[];
|
|
10
11
|
export type RGXTokenType = 'no-op' | 'literal' | 'native' | 'convertible' | RGXTokenType[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ptolemy2002/rgx",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -29,21 +29,27 @@
|
|
|
29
29
|
"release-major": "bash ./scripts/release.sh major"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
+
"@ptolemy2002/immutability-utils": "^1.2.1",
|
|
32
33
|
"@ptolemy2002/js-utils": "^3.2.2",
|
|
33
34
|
"@ptolemy2002/ts-brand-utils": "^1.0.0",
|
|
34
35
|
"@ptolemy2002/ts-utils": "^3.4.0",
|
|
35
36
|
"@types/is-callable": "^1.1.2",
|
|
36
37
|
"@types/jest": "^29.5.0",
|
|
38
|
+
"@types/lodash.clonedeep": "^4.5.9",
|
|
37
39
|
"is-callable": "^1.2.7",
|
|
38
40
|
"jest": "^29.5.0",
|
|
41
|
+
"lodash.clonedeep": "^4.5.0",
|
|
39
42
|
"ts-jest": "^29.1.0",
|
|
40
43
|
"ts-patch": "^3.3.0",
|
|
41
44
|
"tsconfig-paths": "^4.2.0",
|
|
42
45
|
"typescript-transform-paths": "^3.5.3"
|
|
43
46
|
},
|
|
44
47
|
"peerDependencies": {
|
|
48
|
+
"@ptolemy2002/immutability-utils": "^1.2.1",
|
|
49
|
+
"@ptolemy2002/js-utils": "^3.2.2",
|
|
45
50
|
"@ptolemy2002/ts-brand-utils": "^1.0.0",
|
|
46
51
|
"@ptolemy2002/ts-utils": "^3.4.0",
|
|
47
|
-
"is-callable": "^1.2.7"
|
|
52
|
+
"is-callable": "^1.2.7",
|
|
53
|
+
"lodash.clonedeep": "^4.5.0"
|
|
48
54
|
}
|
|
49
55
|
}
|