selectic 3.0.10 → 3.0.11
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/selectic.common.js +10 -5
- package/dist/selectic.esm.js +11 -6
- package/package.json +1 -1
- package/rollup.config.js +8 -1
- package/src/Store.tsx +2 -2
- package/src/tools.ts +11 -4
- package/test/Store/Store_creation.spec.js +0 -13
- package/test/Store/commit.spec.js +0 -13
- package/test/Store/getItem.spec.js +0 -13
- package/test/Store/getItems.spec.js +0 -13
- package/test/Store/selectItem.spec.js +0 -13
- package/test/Store/toggleSelectAll.spec.js +0 -13
- package/test/Tools/tools.spec.js +404 -0
- package/types/tools.d.ts +1 -1
- package/.package.json.un~ +0 -0
package/dist/selectic.common.js
CHANGED
|
@@ -41,7 +41,8 @@ styleInject(css_248z);
|
|
|
41
41
|
* @param refs internal reference to object to avoid cyclic references
|
|
42
42
|
* @returns a copy of obj
|
|
43
43
|
*/
|
|
44
|
-
function deepClone(
|
|
44
|
+
function deepClone(origObject, ignoreAttributes = [], refs = new WeakMap()) {
|
|
45
|
+
const obj = vue.unref(origObject);
|
|
45
46
|
/* For circular references */
|
|
46
47
|
if (refs.has(obj)) {
|
|
47
48
|
return refs.get(obj);
|
|
@@ -54,7 +55,7 @@ function deepClone(obj, refs = new WeakMap()) {
|
|
|
54
55
|
const ref = [];
|
|
55
56
|
refs.set(obj, ref);
|
|
56
57
|
obj.forEach((val, idx) => {
|
|
57
|
-
ref[idx] = deepClone(val, refs);
|
|
58
|
+
ref[idx] = deepClone(val, ignoreAttributes, refs);
|
|
58
59
|
});
|
|
59
60
|
return ref;
|
|
60
61
|
}
|
|
@@ -67,7 +68,11 @@ function deepClone(obj, refs = new WeakMap()) {
|
|
|
67
68
|
const ref = {};
|
|
68
69
|
refs.set(obj, ref);
|
|
69
70
|
for (const [key, val] of Object.entries(obj)) {
|
|
70
|
-
|
|
71
|
+
if (ignoreAttributes.includes(key)) {
|
|
72
|
+
ref[key] = val;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
ref[key] = deepClone(val, ignoreAttributes, refs);
|
|
71
76
|
}
|
|
72
77
|
return ref;
|
|
73
78
|
}
|
|
@@ -684,7 +689,7 @@ class SelecticStore {
|
|
|
684
689
|
}
|
|
685
690
|
/* This method is for the computed property listOptions */
|
|
686
691
|
getListOptions() {
|
|
687
|
-
const options = deepClone(this.props.options);
|
|
692
|
+
const options = deepClone(this.props.options, ['data']);
|
|
688
693
|
const listOptions = [];
|
|
689
694
|
if (!Array.isArray(options)) {
|
|
690
695
|
return listOptions;
|
|
@@ -721,7 +726,7 @@ class SelecticStore {
|
|
|
721
726
|
}
|
|
722
727
|
/* This method is for the computed property elementOptions */
|
|
723
728
|
getElementOptions() {
|
|
724
|
-
const options = deepClone(this.props.childOptions);
|
|
729
|
+
const options = deepClone(this.props.childOptions, ['data']);
|
|
725
730
|
const childOptions = [];
|
|
726
731
|
if (!Array.isArray(options) || options.length === 0) {
|
|
727
732
|
return childOptions;
|
package/dist/selectic.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Prop, Watch, Component, Vue, h, Emit } from 'vtyx';
|
|
2
|
-
import { reactive, computed,
|
|
2
|
+
import { unref, reactive, computed, watch } from 'vue';
|
|
3
3
|
|
|
4
4
|
function styleInject(css, ref) {
|
|
5
5
|
if ( ref === void 0 ) ref = {};
|
|
@@ -37,7 +37,8 @@ styleInject(css_248z);
|
|
|
37
37
|
* @param refs internal reference to object to avoid cyclic references
|
|
38
38
|
* @returns a copy of obj
|
|
39
39
|
*/
|
|
40
|
-
function deepClone(
|
|
40
|
+
function deepClone(origObject, ignoreAttributes = [], refs = new WeakMap()) {
|
|
41
|
+
const obj = unref(origObject);
|
|
41
42
|
/* For circular references */
|
|
42
43
|
if (refs.has(obj)) {
|
|
43
44
|
return refs.get(obj);
|
|
@@ -50,7 +51,7 @@ function deepClone(obj, refs = new WeakMap()) {
|
|
|
50
51
|
const ref = [];
|
|
51
52
|
refs.set(obj, ref);
|
|
52
53
|
obj.forEach((val, idx) => {
|
|
53
|
-
ref[idx] = deepClone(val, refs);
|
|
54
|
+
ref[idx] = deepClone(val, ignoreAttributes, refs);
|
|
54
55
|
});
|
|
55
56
|
return ref;
|
|
56
57
|
}
|
|
@@ -63,7 +64,11 @@ function deepClone(obj, refs = new WeakMap()) {
|
|
|
63
64
|
const ref = {};
|
|
64
65
|
refs.set(obj, ref);
|
|
65
66
|
for (const [key, val] of Object.entries(obj)) {
|
|
66
|
-
|
|
67
|
+
if (ignoreAttributes.includes(key)) {
|
|
68
|
+
ref[key] = val;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
ref[key] = deepClone(val, ignoreAttributes, refs);
|
|
67
72
|
}
|
|
68
73
|
return ref;
|
|
69
74
|
}
|
|
@@ -680,7 +685,7 @@ class SelecticStore {
|
|
|
680
685
|
}
|
|
681
686
|
/* This method is for the computed property listOptions */
|
|
682
687
|
getListOptions() {
|
|
683
|
-
const options = deepClone(this.props.options);
|
|
688
|
+
const options = deepClone(this.props.options, ['data']);
|
|
684
689
|
const listOptions = [];
|
|
685
690
|
if (!Array.isArray(options)) {
|
|
686
691
|
return listOptions;
|
|
@@ -717,7 +722,7 @@ class SelecticStore {
|
|
|
717
722
|
}
|
|
718
723
|
/* This method is for the computed property elementOptions */
|
|
719
724
|
getElementOptions() {
|
|
720
|
-
const options = deepClone(this.props.childOptions);
|
|
725
|
+
const options = deepClone(this.props.childOptions, ['data']);
|
|
721
726
|
const childOptions = [];
|
|
722
727
|
if (!Array.isArray(options) || options.length === 0) {
|
|
723
728
|
return childOptions;
|
package/package.json
CHANGED
package/rollup.config.js
CHANGED
package/src/Store.tsx
CHANGED
|
@@ -1060,7 +1060,7 @@ export default class SelecticStore {
|
|
|
1060
1060
|
|
|
1061
1061
|
/* This method is for the computed property listOptions */
|
|
1062
1062
|
private getListOptions(): OptionValue[] {
|
|
1063
|
-
const options = deepClone(this.props.options);
|
|
1063
|
+
const options = deepClone(this.props.options, ['data']);
|
|
1064
1064
|
const listOptions: OptionValue[] = [];
|
|
1065
1065
|
|
|
1066
1066
|
if (!Array.isArray(options)) {
|
|
@@ -1106,7 +1106,7 @@ export default class SelecticStore {
|
|
|
1106
1106
|
|
|
1107
1107
|
/* This method is for the computed property elementOptions */
|
|
1108
1108
|
private getElementOptions(): OptionValue[] {
|
|
1109
|
-
const options = deepClone(this.props.childOptions);
|
|
1109
|
+
const options = deepClone(this.props.childOptions, ['data']);
|
|
1110
1110
|
const childOptions: OptionValue[] = [];
|
|
1111
1111
|
|
|
1112
1112
|
if (!Array.isArray(options) || options.length === 0) {
|
package/src/tools.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { unref } from 'vue';
|
|
1
2
|
|
|
2
3
|
/**
|
|
3
4
|
* Clone the object and its inner properties.
|
|
@@ -5,7 +6,9 @@
|
|
|
5
6
|
* @param refs internal reference to object to avoid cyclic references
|
|
6
7
|
* @returns a copy of obj
|
|
7
8
|
*/
|
|
8
|
-
export function deepClone<T = any>(
|
|
9
|
+
export function deepClone<T = any>(origObject: T, ignoreAttributes: string[] = [], refs: WeakMap<any, any> = new WeakMap()): T {
|
|
10
|
+
const obj = unref(origObject);
|
|
11
|
+
|
|
9
12
|
/* For circular references */
|
|
10
13
|
if (refs.has(obj)) {
|
|
11
14
|
return refs.get(obj);
|
|
@@ -20,7 +23,7 @@ export function deepClone<T = any>(obj: T, refs: WeakMap<any, any> = new WeakMap
|
|
|
20
23
|
const ref: any[] = [];
|
|
21
24
|
refs.set(obj, ref);
|
|
22
25
|
obj.forEach((val, idx) => {
|
|
23
|
-
ref[idx] = deepClone(val, refs);
|
|
26
|
+
ref[idx] = deepClone(val, ignoreAttributes, refs);
|
|
24
27
|
});
|
|
25
28
|
return ref as unknown as T;
|
|
26
29
|
}
|
|
@@ -35,7 +38,12 @@ export function deepClone<T = any>(obj: T, refs: WeakMap<any, any> = new WeakMap
|
|
|
35
38
|
const ref: any = {};
|
|
36
39
|
refs.set(obj, ref);
|
|
37
40
|
for (const [key, val] of Object.entries(obj)) {
|
|
38
|
-
|
|
41
|
+
if (ignoreAttributes.includes(key)) {
|
|
42
|
+
ref[key] = val;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
ref[key] = deepClone(val, ignoreAttributes, refs);
|
|
39
47
|
}
|
|
40
48
|
return ref as unknown as T;
|
|
41
49
|
}
|
|
@@ -44,7 +52,6 @@ export function deepClone<T = any>(obj: T, refs: WeakMap<any, any> = new WeakMap
|
|
|
44
52
|
return obj;
|
|
45
53
|
}
|
|
46
54
|
|
|
47
|
-
|
|
48
55
|
/**
|
|
49
56
|
* Escape search string to consider regexp special characters as they
|
|
50
57
|
* are and not like special characters.
|
|
@@ -1,16 +1,3 @@
|
|
|
1
|
-
/**************************************************************************/
|
|
2
|
-
/* */
|
|
3
|
-
/* Copyright (C) INTERSEC SA */
|
|
4
|
-
/* */
|
|
5
|
-
/* Should you receive a copy of this source code, you must check you */
|
|
6
|
-
/* have a proper, written authorization of INTERSEC to hold it. If you */
|
|
7
|
-
/* don't have such an authorization, you must DELETE all source code */
|
|
8
|
-
/* files in your possession, and inform INTERSEC of the fact you obtain */
|
|
9
|
-
/* these files. Should you not comply to these terms, you can be */
|
|
10
|
-
/* prosecuted in the extent permitted by applicable law. */
|
|
11
|
-
/* */
|
|
12
|
-
/**************************************************************************/
|
|
13
|
-
|
|
14
1
|
const _ = require('../tools.js');
|
|
15
2
|
const {
|
|
16
3
|
getInitialState,
|
|
@@ -1,16 +1,3 @@
|
|
|
1
|
-
/**************************************************************************/
|
|
2
|
-
/* */
|
|
3
|
-
/* Copyright (C) INTERSEC SA */
|
|
4
|
-
/* */
|
|
5
|
-
/* Should you receive a copy of this source code, you must check you */
|
|
6
|
-
/* have a proper, written authorization of INTERSEC to hold it. If you */
|
|
7
|
-
/* don't have such an authorization, you must DELETE all source code */
|
|
8
|
-
/* files in your possession, and inform INTERSEC of the fact you obtain */
|
|
9
|
-
/* these files. Should you not comply to these terms, you can be */
|
|
10
|
-
/* prosecuted in the extent permitted by applicable law. */
|
|
11
|
-
/* */
|
|
12
|
-
/**************************************************************************/
|
|
13
|
-
|
|
14
1
|
const _ = require('../tools.js');
|
|
15
2
|
const {
|
|
16
3
|
getInitialState,
|
|
@@ -1,16 +1,3 @@
|
|
|
1
|
-
/**************************************************************************/
|
|
2
|
-
/* */
|
|
3
|
-
/* Copyright (C) INTERSEC SA */
|
|
4
|
-
/* */
|
|
5
|
-
/* Should you receive a copy of this source code, you must check you */
|
|
6
|
-
/* have a proper, written authorization of INTERSEC to hold it. If you */
|
|
7
|
-
/* don't have such an authorization, you must DELETE all source code */
|
|
8
|
-
/* files in your possession, and inform INTERSEC of the fact you obtain */
|
|
9
|
-
/* these files. Should you not comply to these terms, you can be */
|
|
10
|
-
/* prosecuted in the extent permitted by applicable law. */
|
|
11
|
-
/* */
|
|
12
|
-
/**************************************************************************/
|
|
13
|
-
|
|
14
1
|
const _ = require('../tools.js');
|
|
15
2
|
const {
|
|
16
3
|
buildFetchCb,
|
|
@@ -1,16 +1,3 @@
|
|
|
1
|
-
/**************************************************************************/
|
|
2
|
-
/* */
|
|
3
|
-
/* Copyright (C) INTERSEC SA */
|
|
4
|
-
/* */
|
|
5
|
-
/* Should you receive a copy of this source code, you must check you */
|
|
6
|
-
/* have a proper, written authorization of INTERSEC to hold it. If you */
|
|
7
|
-
/* don't have such an authorization, you must DELETE all source code */
|
|
8
|
-
/* files in your possession, and inform INTERSEC of the fact you obtain */
|
|
9
|
-
/* these files. Should you not comply to these terms, you can be */
|
|
10
|
-
/* prosecuted in the extent permitted by applicable law. */
|
|
11
|
-
/* */
|
|
12
|
-
/**************************************************************************/
|
|
13
|
-
|
|
14
1
|
const _ = require('../tools.js');
|
|
15
2
|
const {
|
|
16
3
|
getOptions,
|
|
@@ -1,16 +1,3 @@
|
|
|
1
|
-
/**************************************************************************/
|
|
2
|
-
/* */
|
|
3
|
-
/* Copyright (C) INTERSEC SA */
|
|
4
|
-
/* */
|
|
5
|
-
/* Should you receive a copy of this source code, you must check you */
|
|
6
|
-
/* have a proper, written authorization of INTERSEC to hold it. If you */
|
|
7
|
-
/* don't have such an authorization, you must DELETE all source code */
|
|
8
|
-
/* files in your possession, and inform INTERSEC of the fact you obtain */
|
|
9
|
-
/* these files. Should you not comply to these terms, you can be */
|
|
10
|
-
/* prosecuted in the extent permitted by applicable law. */
|
|
11
|
-
/* */
|
|
12
|
-
/**************************************************************************/
|
|
13
|
-
|
|
14
1
|
const _ = require('../tools.js');
|
|
15
2
|
const {
|
|
16
3
|
getOptions,
|
|
@@ -1,16 +1,3 @@
|
|
|
1
|
-
/**************************************************************************/
|
|
2
|
-
/* */
|
|
3
|
-
/* Copyright (C) INTERSEC SA */
|
|
4
|
-
/* */
|
|
5
|
-
/* Should you receive a copy of this source code, you must check you */
|
|
6
|
-
/* have a proper, written authorization of INTERSEC to hold it. If you */
|
|
7
|
-
/* don't have such an authorization, you must DELETE all source code */
|
|
8
|
-
/* files in your possession, and inform INTERSEC of the fact you obtain */
|
|
9
|
-
/* these files. Should you not comply to these terms, you can be */
|
|
10
|
-
/* prosecuted in the extent permitted by applicable law. */
|
|
11
|
-
/* */
|
|
12
|
-
/**************************************************************************/
|
|
13
|
-
|
|
14
1
|
const _ = require('../tools.js');
|
|
15
2
|
const {
|
|
16
3
|
getOptions,
|
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
const tape = require('tape');
|
|
2
|
+
const toolFile = require('../dist/tools.js');
|
|
3
|
+
|
|
4
|
+
const {
|
|
5
|
+
assignObject,
|
|
6
|
+
convertToRegExp,
|
|
7
|
+
deepClone,
|
|
8
|
+
} = toolFile;
|
|
9
|
+
|
|
10
|
+
tape.test('assignObject()', (st) => {
|
|
11
|
+
st.test('behaves like Object.assign', (tst) => {
|
|
12
|
+
const deep1 = {
|
|
13
|
+
dp: 1,
|
|
14
|
+
};
|
|
15
|
+
const deep2 = {
|
|
16
|
+
dp: 2,
|
|
17
|
+
other: 'value',
|
|
18
|
+
};
|
|
19
|
+
const obj1 = {
|
|
20
|
+
a: 1,
|
|
21
|
+
b: 2,
|
|
22
|
+
c: false,
|
|
23
|
+
deep: deep1,
|
|
24
|
+
};
|
|
25
|
+
const obj2 = {
|
|
26
|
+
a: 3,
|
|
27
|
+
c: true,
|
|
28
|
+
d: false,
|
|
29
|
+
deep: deep2,
|
|
30
|
+
other: {
|
|
31
|
+
attr: 'str',
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const result = assignObject(obj1, obj2);
|
|
36
|
+
|
|
37
|
+
tst.is(result, obj1, 'should modify first argument');
|
|
38
|
+
tst.deepEqual(result, {
|
|
39
|
+
a: 3,
|
|
40
|
+
b: 2,
|
|
41
|
+
c: true,
|
|
42
|
+
d: false,
|
|
43
|
+
deep: {
|
|
44
|
+
dp: 2,
|
|
45
|
+
other: 'value',
|
|
46
|
+
},
|
|
47
|
+
other: {
|
|
48
|
+
attr: 'str',
|
|
49
|
+
},
|
|
50
|
+
}, 'should merge all attributes');
|
|
51
|
+
tst.is(result.deep, deep2, 'should keep references');
|
|
52
|
+
tst.deepEqual(obj2, {
|
|
53
|
+
a: 3,
|
|
54
|
+
c: true,
|
|
55
|
+
d: false,
|
|
56
|
+
deep: deep2,
|
|
57
|
+
other: {
|
|
58
|
+
attr: 'str',
|
|
59
|
+
},
|
|
60
|
+
}, 'should not change second argument');
|
|
61
|
+
tst.end();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
st.test('accept multiple arguments', (tst) => {
|
|
65
|
+
const obj1 = {
|
|
66
|
+
a: 1,
|
|
67
|
+
b: 2,
|
|
68
|
+
};
|
|
69
|
+
const obj2 = {
|
|
70
|
+
a: 2,
|
|
71
|
+
c: 3,
|
|
72
|
+
};
|
|
73
|
+
const obj3 = {
|
|
74
|
+
a: 3,
|
|
75
|
+
d: 4,
|
|
76
|
+
};
|
|
77
|
+
const obj4 = {
|
|
78
|
+
a: 4,
|
|
79
|
+
e: 5,
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const result = assignObject(obj1, obj2, obj3, obj4);
|
|
83
|
+
|
|
84
|
+
tst.is(result, obj1, 'should modify first argument');
|
|
85
|
+
tst.deepEqual(result, {
|
|
86
|
+
a: 4,
|
|
87
|
+
b: 2,
|
|
88
|
+
c: 3,
|
|
89
|
+
d: 4,
|
|
90
|
+
e: 5,
|
|
91
|
+
}, 'should merge all attributes');
|
|
92
|
+
tst.deepEqual(obj2, {
|
|
93
|
+
a: 2,
|
|
94
|
+
c: 3,
|
|
95
|
+
}, 'should not change second argument');
|
|
96
|
+
tst.deepEqual(obj3, {
|
|
97
|
+
a: 3,
|
|
98
|
+
d: 4,
|
|
99
|
+
}, 'should not change third argument');
|
|
100
|
+
tst.deepEqual(obj4, {
|
|
101
|
+
a: 4,
|
|
102
|
+
e: 5,
|
|
103
|
+
}, 'should not change fourth argument');
|
|
104
|
+
tst.end();
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
st.test('ignores undefined attributes', (tst) => {
|
|
108
|
+
const obj1 = {
|
|
109
|
+
a: 1, // modified by all
|
|
110
|
+
b: 2, // not modified by all (undefined)
|
|
111
|
+
c: 3, // obj2: undefined, modified by obj3
|
|
112
|
+
d: 4, // modified by obj2, obj3: undefined
|
|
113
|
+
e: 5, // not set by obj2, obj3: undefined
|
|
114
|
+
f: 6, // not set by all
|
|
115
|
+
};
|
|
116
|
+
const obj2 = {
|
|
117
|
+
a: 'a',
|
|
118
|
+
b: undefined,
|
|
119
|
+
c: undefined,
|
|
120
|
+
d: 'd',
|
|
121
|
+
};
|
|
122
|
+
const obj3 = {
|
|
123
|
+
a: 2,
|
|
124
|
+
b: undefined,
|
|
125
|
+
c: 'c',
|
|
126
|
+
d: undefined,
|
|
127
|
+
e: undefined,
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
const result = assignObject(obj1, obj2, obj3);
|
|
131
|
+
|
|
132
|
+
tst.is(result, obj1, 'should modify first argument');
|
|
133
|
+
tst.deepEqual(result, {
|
|
134
|
+
a: 2,
|
|
135
|
+
b: 2,
|
|
136
|
+
c: 'c',
|
|
137
|
+
d: 'd',
|
|
138
|
+
e: 5,
|
|
139
|
+
f: 6,
|
|
140
|
+
}, 'should merge all attributes');
|
|
141
|
+
tst.deepEqual(obj2, {
|
|
142
|
+
a: 'a',
|
|
143
|
+
b: undefined,
|
|
144
|
+
c: undefined,
|
|
145
|
+
d: 'd',
|
|
146
|
+
}, 'should not change second argument');
|
|
147
|
+
tst.deepEqual(obj3, {
|
|
148
|
+
a: 2,
|
|
149
|
+
b: undefined,
|
|
150
|
+
c: 'c',
|
|
151
|
+
d: undefined,
|
|
152
|
+
e: undefined,
|
|
153
|
+
}, 'should not change third argument');
|
|
154
|
+
tst.end();
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
tape.test('convertToRegExp()', (st) => {
|
|
159
|
+
st.test('convert wildcard', (tst) => {
|
|
160
|
+
const str = '*the search*';
|
|
161
|
+
|
|
162
|
+
const result = convertToRegExp(str);
|
|
163
|
+
|
|
164
|
+
tst.is(result instanceof RegExp, true, 'should create a RegExp');
|
|
165
|
+
|
|
166
|
+
const pattern = result.source;
|
|
167
|
+
const flags = result.flags;
|
|
168
|
+
|
|
169
|
+
tst.is(pattern, '.*the search.*', 'should create wildcard sequence');
|
|
170
|
+
tst.is(flags, 'i', 'should be case insensitive by default');
|
|
171
|
+
|
|
172
|
+
tst.end();
|
|
173
|
+
});
|
|
174
|
+
st.test('escape special characters', (tst) => {
|
|
175
|
+
const str = '\\^$.+?(){}[]|';
|
|
176
|
+
|
|
177
|
+
const result = convertToRegExp(str);
|
|
178
|
+
|
|
179
|
+
tst.is(result instanceof RegExp, true, 'should create a RegExp');
|
|
180
|
+
|
|
181
|
+
const pattern = result.source;
|
|
182
|
+
const flags = result.flags;
|
|
183
|
+
|
|
184
|
+
tst.is(pattern, '\\\\\\^\\$\\.\\+\\?\\(\\)\\{\\}\\[\\]\\|', 'should escape special characters');
|
|
185
|
+
tst.is(flags, 'i', 'should be case insensitive by default');
|
|
186
|
+
|
|
187
|
+
tst.end();
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
st.test('allow RegExp flags', (tst) => {
|
|
191
|
+
const str = 'file*.*';
|
|
192
|
+
|
|
193
|
+
const result = convertToRegExp(str, 'gm');
|
|
194
|
+
|
|
195
|
+
tst.is(result instanceof RegExp, true, 'should create a RegExp');
|
|
196
|
+
|
|
197
|
+
const pattern = result.source;
|
|
198
|
+
const flags = result.flags;
|
|
199
|
+
|
|
200
|
+
tst.is(pattern, 'file.*\\..*', 'should convert special characters');
|
|
201
|
+
tst.is(flags, 'gm', 'should set flags');
|
|
202
|
+
|
|
203
|
+
tst.end();
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
tape.test('deepClone()', (st) => {
|
|
208
|
+
st.test('should copy simple object', (tst) => {
|
|
209
|
+
const fn = () => {};
|
|
210
|
+
const objRef = {
|
|
211
|
+
a: 1,
|
|
212
|
+
b: 'b',
|
|
213
|
+
c: false,
|
|
214
|
+
d: undefined,
|
|
215
|
+
e: null,
|
|
216
|
+
f: {},
|
|
217
|
+
g: fn,
|
|
218
|
+
spe1: NaN,
|
|
219
|
+
spe2: Infinity,
|
|
220
|
+
spe3: '',
|
|
221
|
+
spe4: [],
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
const result = deepClone(objRef);
|
|
225
|
+
|
|
226
|
+
tst.isNot(result, objRef, 'should create a copy');
|
|
227
|
+
tst.deepEqual(result, objRef, 'should have been similar to original');
|
|
228
|
+
|
|
229
|
+
tst.end();
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
st.test('should copy nested object', (tst) => {
|
|
233
|
+
const fn = () => {};
|
|
234
|
+
const deep1 = {
|
|
235
|
+
a: 1,
|
|
236
|
+
b: 'b',
|
|
237
|
+
c: false,
|
|
238
|
+
d: undefined,
|
|
239
|
+
e: null,
|
|
240
|
+
f: {},
|
|
241
|
+
g: fn,
|
|
242
|
+
spe1: NaN,
|
|
243
|
+
spe2: Infinity,
|
|
244
|
+
spe3: '',
|
|
245
|
+
spe4: [],
|
|
246
|
+
};
|
|
247
|
+
const deep2 = {
|
|
248
|
+
deep: deep1,
|
|
249
|
+
added: 'a value',
|
|
250
|
+
};
|
|
251
|
+
const objRef = {
|
|
252
|
+
d: deep2,
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const result = deepClone(objRef);
|
|
256
|
+
|
|
257
|
+
tst.isNot(result, objRef, 'should create a copy');
|
|
258
|
+
tst.deepEqual(result, objRef, 'should have been similar to original');
|
|
259
|
+
tst.isNot(result.d, deep2, 'should copy nested object');
|
|
260
|
+
tst.isNot(result.d.deep, deep1, 'should copy deeper nested object');
|
|
261
|
+
|
|
262
|
+
tst.end();
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
st.test('with arrays', (tst) => {
|
|
267
|
+
const fn = () => {};
|
|
268
|
+
const objRef = {
|
|
269
|
+
a: 1,
|
|
270
|
+
b: 'b',
|
|
271
|
+
c: false,
|
|
272
|
+
d: undefined,
|
|
273
|
+
e: null,
|
|
274
|
+
f: {},
|
|
275
|
+
g: fn,
|
|
276
|
+
spe1: NaN,
|
|
277
|
+
spe2: Infinity,
|
|
278
|
+
spe3: '',
|
|
279
|
+
spe4: [],
|
|
280
|
+
};
|
|
281
|
+
const nestedArray1 = [
|
|
282
|
+
objRef,
|
|
283
|
+
{ a: 'value' },
|
|
284
|
+
null,
|
|
285
|
+
undefined,
|
|
286
|
+
42,
|
|
287
|
+
'value',
|
|
288
|
+
];
|
|
289
|
+
const nestedArray2 = [
|
|
290
|
+
objRef,
|
|
291
|
+
{ a: 'value' },
|
|
292
|
+
null,
|
|
293
|
+
undefined,
|
|
294
|
+
42,
|
|
295
|
+
'value',
|
|
296
|
+
];
|
|
297
|
+
const arrayRef = [
|
|
298
|
+
{
|
|
299
|
+
deep: nestedArray1,
|
|
300
|
+
},
|
|
301
|
+
nestedArray2,
|
|
302
|
+
42, 'value', null, undefined, [[]],
|
|
303
|
+
];
|
|
304
|
+
|
|
305
|
+
const result = deepClone(arrayRef);
|
|
306
|
+
|
|
307
|
+
tst.isNot(result, arrayRef, 'should create a copy');
|
|
308
|
+
tst.is(Array.isArray(arrayRef), true, 'should create an array');
|
|
309
|
+
tst.deepEqual(result, arrayRef, 'should have been similar to original');
|
|
310
|
+
tst.isNot(result[1], nestedArray2, 'should copy nested array');
|
|
311
|
+
tst.isNot(result[0].deep, nestedArray1, 'should copy deeper nested array');
|
|
312
|
+
tst.isNot(result[1][0], objRef, 'should copy nested object');
|
|
313
|
+
tst.isNot(result[0].deep[0], objRef, 'should copy deeper nested object');
|
|
314
|
+
|
|
315
|
+
tst.end();
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
st.test('with RegExp', (tst) => {
|
|
319
|
+
const r1 = /hello?/gi;
|
|
320
|
+
const r2 = /.* [aA]+?/;
|
|
321
|
+
|
|
322
|
+
const result1 = deepClone(r1);
|
|
323
|
+
const result2 = deepClone({rgx: r2});
|
|
324
|
+
|
|
325
|
+
tst.isNot(result1, r1, 'should copy RegExp');
|
|
326
|
+
tst.is(result1 instanceof RegExp, true, 'should create a RegExp');
|
|
327
|
+
tst.is(result1.source, 'hello?', 'should copy pattern');
|
|
328
|
+
tst.is(result1.flags, 'gi', 'should copy flags');
|
|
329
|
+
|
|
330
|
+
tst.isNot(result2.rgx, r2, 'should copy the RegExp');
|
|
331
|
+
tst.is(result2.rgx.source, '.* [aA]+?', 'should copy the attribute pattern');
|
|
332
|
+
tst.is(result2.rgx.flags, '', 'should copy the attribute flags');
|
|
333
|
+
tst.end();
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
st.test('with primitives', (tst) => {
|
|
337
|
+
const result1 = deepClone(1);
|
|
338
|
+
const result2 = deepClone('a');
|
|
339
|
+
const result3 = deepClone(false);
|
|
340
|
+
const result4 = deepClone(null);
|
|
341
|
+
const result5 = deepClone(undefined);
|
|
342
|
+
|
|
343
|
+
tst.is(result1, 1, 'should return number');
|
|
344
|
+
tst.is(result2, 'a', 'should return string');
|
|
345
|
+
tst.is(result3, false, 'should return boolean');
|
|
346
|
+
tst.is(result4, null, 'should return null');
|
|
347
|
+
tst.is(result5, undefined, 'should return undefined');
|
|
348
|
+
tst.end();
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
st.test('with circular references', (tst) => {
|
|
352
|
+
const obj1 = {
|
|
353
|
+
a: 'a',
|
|
354
|
+
}
|
|
355
|
+
const obj2 = {
|
|
356
|
+
b: 'b',
|
|
357
|
+
}
|
|
358
|
+
obj1.child = obj1;
|
|
359
|
+
obj1.sibling = obj2;
|
|
360
|
+
obj2.sibling = obj1;
|
|
361
|
+
|
|
362
|
+
const ref = [obj1, obj2];
|
|
363
|
+
|
|
364
|
+
const result = deepClone(ref);
|
|
365
|
+
|
|
366
|
+
tst.isNot(result, ref, 'should create a new object');
|
|
367
|
+
tst.isNot(result[0], obj1, 'should copy inner objects');
|
|
368
|
+
tst.is(result[0].child, result[0], 'should keep the circular reference');
|
|
369
|
+
tst.is(result[1].sibling, result[0], 'should keep similar references');
|
|
370
|
+
tst.is(result[0].sibling, result[1], 'should keep similar references (2)');
|
|
371
|
+
|
|
372
|
+
tst.end();
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
st.test('can ignore some attributes', (tst) => {
|
|
376
|
+
const noCopy1 = {
|
|
377
|
+
ref: 1,
|
|
378
|
+
};
|
|
379
|
+
const noCopy2 = new Set(['alpha', 'omega']);
|
|
380
|
+
const noCopy3 = new Map([[1, 'alpha'], [22, 'omega']]);
|
|
381
|
+
const deep1 = {
|
|
382
|
+
a: 'alpha',
|
|
383
|
+
noCopy: noCopy3,
|
|
384
|
+
};
|
|
385
|
+
const ref = {
|
|
386
|
+
id: 'ref',
|
|
387
|
+
noCopy: noCopy1,
|
|
388
|
+
nop: noCopy2,
|
|
389
|
+
not: 42,
|
|
390
|
+
deep: deep1,
|
|
391
|
+
};
|
|
392
|
+
|
|
393
|
+
const result = deepClone(ref, ['noCopy', 'nothing', 'nop', 'not']);
|
|
394
|
+
|
|
395
|
+
tst.isNot(result, ref, 'should create a new object');
|
|
396
|
+
tst.isNot(result.deep, deep1, 'should create a new object');
|
|
397
|
+
tst.is(result.noCopy, noCopy1, 'should keep original reference');
|
|
398
|
+
tst.is(result.nop, noCopy2, 'should keep original reference (2)');
|
|
399
|
+
tst.is(result.not, 42, 'should keep primitive');
|
|
400
|
+
tst.is(result.deep.noCopy, noCopy3, 'should keep nested original reference');
|
|
401
|
+
|
|
402
|
+
tst.end();
|
|
403
|
+
});
|
|
404
|
+
});
|
package/types/tools.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @param refs internal reference to object to avoid cyclic references
|
|
5
5
|
* @returns a copy of obj
|
|
6
6
|
*/
|
|
7
|
-
export declare function deepClone<T = any>(
|
|
7
|
+
export declare function deepClone<T = any>(origObject: T, ignoreAttributes?: string[], refs?: WeakMap<any, any>): T;
|
|
8
8
|
/**
|
|
9
9
|
* Escape search string to consider regexp special characters as they
|
|
10
10
|
* are and not like special characters.
|
package/.package.json.un~
DELETED
|
Binary file
|