tspo 1.0.4 → 1.0.5
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/cjs/helpers/isPlainObject.js +13 -0
- package/dist/cjs/helpers/utility-types.js +1 -0
- package/dist/cjs/index.js +4 -0
- package/dist/cjs/tspo.js +189 -0
- package/dist/cjs/utils/compare.js +58 -0
- package/dist/cjs/utils/copy.js +113 -0
- package/dist/cjs/utils/iterate.js +34 -0
- package/dist/types/helpers/isPlainObject.d.ts +15 -0
- package/dist/types/helpers/utility-types.d.ts +47 -0
- package/dist/types/index.d.ts +25 -0
- package/dist/types/tspo.d.ts +122 -0
- package/dist/types/utils/compare.d.ts +18 -0
- package/dist/types/utils/copy.d.ts +27 -0
- package/dist/types/utils/iterate.d.ts +25 -0
- package/package.json +1 -1
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const objectProto = Object.prototype;
|
|
2
|
+
function isPlainObject(arg) {
|
|
3
|
+
if (typeof arg !== 'object' || arg === null) {
|
|
4
|
+
return false;
|
|
5
|
+
}
|
|
6
|
+
const argProto = Object.getPrototypeOf(arg);
|
|
7
|
+
return ((argProto === null ||
|
|
8
|
+
argProto === objectProto ||
|
|
9
|
+
Object.getPrototypeOf(argProto) === null) &&
|
|
10
|
+
!(Symbol.toStringTag in arg) &&
|
|
11
|
+
!(Symbol.iterator in arg));
|
|
12
|
+
}
|
|
13
|
+
export default isPlainObject;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/cjs/tspo.js
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import isPlainObject from './helpers/isPlainObject.js';
|
|
2
|
+
import compare from './utils/compare.js';
|
|
3
|
+
import copy from './utils/copy.js';
|
|
4
|
+
import iterate from './utils/iterate.js';
|
|
5
|
+
const hop = Object.prototype.hasOwnProperty;
|
|
6
|
+
function omit(obj, keys) {
|
|
7
|
+
const retVal = {};
|
|
8
|
+
const dict = obj;
|
|
9
|
+
if (Array.isArray(keys)) {
|
|
10
|
+
const set = new Set(keys);
|
|
11
|
+
for (const key in obj) {
|
|
12
|
+
if (!set.has(key)) {
|
|
13
|
+
retVal[key] = dict[key];
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return retVal;
|
|
17
|
+
}
|
|
18
|
+
const omittedKey = keys;
|
|
19
|
+
for (const key in obj) {
|
|
20
|
+
if (key !== omittedKey) {
|
|
21
|
+
retVal[key] = dict[key];
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return retVal;
|
|
25
|
+
}
|
|
26
|
+
function pick(obj, keys) {
|
|
27
|
+
const retVal = {};
|
|
28
|
+
const dict = obj;
|
|
29
|
+
if (Array.isArray(keys)) {
|
|
30
|
+
const set = new Set(keys);
|
|
31
|
+
for (const key in obj) {
|
|
32
|
+
if (set.has(key)) {
|
|
33
|
+
retVal[key] = dict[key];
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return retVal;
|
|
37
|
+
}
|
|
38
|
+
const pickedKey = keys;
|
|
39
|
+
for (const key in obj) {
|
|
40
|
+
if (key === pickedKey) {
|
|
41
|
+
retVal[key] = dict[key];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return retVal;
|
|
45
|
+
}
|
|
46
|
+
function merge(a, b) {
|
|
47
|
+
return { ...a, ...b };
|
|
48
|
+
}
|
|
49
|
+
function mergeArray(arr) {
|
|
50
|
+
return Object.assign({}, ...arr);
|
|
51
|
+
}
|
|
52
|
+
function addEntry(obj, entry) {
|
|
53
|
+
return { ...obj, [entry[0]]: entry[1] };
|
|
54
|
+
}
|
|
55
|
+
function addEntries(obj, entries) {
|
|
56
|
+
return {
|
|
57
|
+
...obj,
|
|
58
|
+
...Object.fromEntries(entries),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function append(obj, addOn) {
|
|
62
|
+
for (const key in addOn) {
|
|
63
|
+
obj[key] = addOn[key];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function remove(obj, keys) {
|
|
67
|
+
const keyArr = Array.isArray(keys) ? keys : [keys];
|
|
68
|
+
for (const key of keyArr) {
|
|
69
|
+
delete obj[key];
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function index(obj, key) {
|
|
73
|
+
return obj[key];
|
|
74
|
+
}
|
|
75
|
+
function safeIndex(obj, key) {
|
|
76
|
+
if (key in obj) {
|
|
77
|
+
return obj[key];
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
throw new Error('safeIndex was passed a key not present on the object. key: ' + key);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function reverseIndex(obj, value) {
|
|
84
|
+
const retVal = [];
|
|
85
|
+
for (const key in obj) {
|
|
86
|
+
if (obj[key] === value) {
|
|
87
|
+
retVal.push(key);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return retVal;
|
|
91
|
+
}
|
|
92
|
+
function safeReverseIndex(obj, value) {
|
|
93
|
+
let found = false;
|
|
94
|
+
let retVal;
|
|
95
|
+
for (const key in obj) {
|
|
96
|
+
if (obj[key] === value) {
|
|
97
|
+
if (found) {
|
|
98
|
+
throw new Error('.safeReverseIndex found 0 or more than 1 keys for value: ' +
|
|
99
|
+
String(value));
|
|
100
|
+
}
|
|
101
|
+
found = true;
|
|
102
|
+
retVal = key;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (!found) {
|
|
106
|
+
throw new Error('.safeReverseIndex found 0 or more than 1 keys for value: ' +
|
|
107
|
+
String(value));
|
|
108
|
+
}
|
|
109
|
+
return retVal;
|
|
110
|
+
}
|
|
111
|
+
function isKey(obj, arg) {
|
|
112
|
+
const keyArr = Array.isArray(arg) ? arg : [arg];
|
|
113
|
+
for (const key of keyArr) {
|
|
114
|
+
if (!(typeof arg === 'string' && arg in obj))
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
function isValue(obj, arg) {
|
|
120
|
+
const dict = obj;
|
|
121
|
+
if (!Array.isArray(arg)) {
|
|
122
|
+
for (const key in obj) {
|
|
123
|
+
if (hop.call(obj, key) && sameValueZero(dict[key], arg))
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
for (const val of arg) {
|
|
129
|
+
let found = false;
|
|
130
|
+
for (const key in obj) {
|
|
131
|
+
if (hop.call(obj, key) && sameValueZero(dict[key], val)) {
|
|
132
|
+
found = true;
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (!found)
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
function sameValueZero(a, b) {
|
|
142
|
+
return a === b || (a !== a && b !== b);
|
|
143
|
+
}
|
|
144
|
+
function isDict(arg) {
|
|
145
|
+
return isPlainObject(arg) && Object.getOwnPropertySymbols(arg).length === 0;
|
|
146
|
+
}
|
|
147
|
+
function keys(obj) {
|
|
148
|
+
return Object.keys(obj);
|
|
149
|
+
}
|
|
150
|
+
function values(obj) {
|
|
151
|
+
return Object.values(obj);
|
|
152
|
+
}
|
|
153
|
+
function entries(obj) {
|
|
154
|
+
return Object.entries(obj);
|
|
155
|
+
}
|
|
156
|
+
function firstEntry(obj) {
|
|
157
|
+
const dict = obj;
|
|
158
|
+
for (const key in obj) {
|
|
159
|
+
if (hop.call(obj, key)) {
|
|
160
|
+
return [key, dict[key]];
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return undefined;
|
|
164
|
+
}
|
|
165
|
+
export default {
|
|
166
|
+
omit,
|
|
167
|
+
pick,
|
|
168
|
+
merge,
|
|
169
|
+
mergeArray,
|
|
170
|
+
append,
|
|
171
|
+
addEntry,
|
|
172
|
+
addEntries,
|
|
173
|
+
index,
|
|
174
|
+
remove,
|
|
175
|
+
safeIndex,
|
|
176
|
+
reverseIndex,
|
|
177
|
+
safeReverseIndex,
|
|
178
|
+
is: isPlainObject,
|
|
179
|
+
isKey,
|
|
180
|
+
isValue,
|
|
181
|
+
keys,
|
|
182
|
+
values,
|
|
183
|
+
entries,
|
|
184
|
+
firstEntry,
|
|
185
|
+
iterate,
|
|
186
|
+
copy,
|
|
187
|
+
compare,
|
|
188
|
+
isDict,
|
|
189
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import isPlainObject, {} from '../helpers/isPlainObject.js';
|
|
2
|
+
const hop = Object.prototype.hasOwnProperty;
|
|
3
|
+
function compare(a, b) {
|
|
4
|
+
if (!isPlainObject(a) || !isPlainObject(b)) {
|
|
5
|
+
throw new Error('compare only works for plain-objects');
|
|
6
|
+
}
|
|
7
|
+
return comparePlainObjects(a, b);
|
|
8
|
+
}
|
|
9
|
+
function comparePlainObjects(a, b) {
|
|
10
|
+
let aSize = 0;
|
|
11
|
+
for (const key in a) {
|
|
12
|
+
if (!hop.call(a, key))
|
|
13
|
+
continue;
|
|
14
|
+
aSize++;
|
|
15
|
+
if (!hop.call(b, key))
|
|
16
|
+
return false;
|
|
17
|
+
if (!compareValue(a[key], b[key]))
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
let bSize = 0;
|
|
21
|
+
for (const key in b) {
|
|
22
|
+
if (hop.call(b, key))
|
|
23
|
+
bSize++;
|
|
24
|
+
}
|
|
25
|
+
return aSize === bSize;
|
|
26
|
+
}
|
|
27
|
+
function compareValue(a, b) {
|
|
28
|
+
if (Object.is(a, b))
|
|
29
|
+
return true;
|
|
30
|
+
if (a instanceof Date || b instanceof Date) {
|
|
31
|
+
return (a instanceof Date && b instanceof Date && a.getTime() === b.getTime());
|
|
32
|
+
}
|
|
33
|
+
const aIsArray = Array.isArray(a), bIsArray = Array.isArray(b);
|
|
34
|
+
if (aIsArray || bIsArray) {
|
|
35
|
+
return aIsArray && bIsArray && compareArrays(a, b);
|
|
36
|
+
}
|
|
37
|
+
const aIsPlainObject = isPlainObject(a), bIsPlainObject = isPlainObject(b);
|
|
38
|
+
if (aIsPlainObject || bIsPlainObject) {
|
|
39
|
+
return aIsPlainObject && bIsPlainObject && comparePlainObjects(a, b);
|
|
40
|
+
}
|
|
41
|
+
if (typeof a === 'object' &&
|
|
42
|
+
a !== null &&
|
|
43
|
+
typeof b === 'object' &&
|
|
44
|
+
b !== null) {
|
|
45
|
+
return a === b;
|
|
46
|
+
}
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
function compareArrays(a, b) {
|
|
50
|
+
if (a.length !== b.length)
|
|
51
|
+
return false;
|
|
52
|
+
for (let i = 0; i < a.length; i++) {
|
|
53
|
+
if (!compareValue(a[i], b[i]))
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
export default compare;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import isPlainObject, {} from '../helpers/isPlainObject.js';
|
|
2
|
+
const hop = Object.prototype.hasOwnProperty;
|
|
3
|
+
function copy(value, options) {
|
|
4
|
+
if (!isPlainObject(value)) {
|
|
5
|
+
throw new TypeError('.copy only accepts a plain-object as the root value');
|
|
6
|
+
}
|
|
7
|
+
const resetDates = options?.resetDates === true, deepCloneAll = options?.deepCloneAll === true;
|
|
8
|
+
return clonePlainObject(value, Object.getPrototypeOf(value), resetDates, deepCloneAll);
|
|
9
|
+
}
|
|
10
|
+
function clonePlainObject(source, proto, resetDates, deepCloneAll) {
|
|
11
|
+
const out = proto === null ? Object.create(null) : {};
|
|
12
|
+
for (const key in source) {
|
|
13
|
+
if (!hop.call(source, key))
|
|
14
|
+
continue;
|
|
15
|
+
out[key] = cloneValue(source[key], resetDates, deepCloneAll);
|
|
16
|
+
}
|
|
17
|
+
return out;
|
|
18
|
+
}
|
|
19
|
+
function cloneValue(value, resetDates, deepCloneAll) {
|
|
20
|
+
if (isPlainObject(value)) {
|
|
21
|
+
return clonePlainObject(value, Object.getPrototypeOf(value), resetDates, deepCloneAll);
|
|
22
|
+
}
|
|
23
|
+
if (Array.isArray(value)) {
|
|
24
|
+
return cloneArray(value, resetDates, deepCloneAll);
|
|
25
|
+
}
|
|
26
|
+
if (value instanceof Date) {
|
|
27
|
+
if (resetDates) {
|
|
28
|
+
return new Date();
|
|
29
|
+
}
|
|
30
|
+
return new Date(value.getTime());
|
|
31
|
+
}
|
|
32
|
+
if (typeof value === 'object' && value !== null) {
|
|
33
|
+
if (deepCloneAll) {
|
|
34
|
+
return cloneNonPlainDeep(value, resetDates);
|
|
35
|
+
}
|
|
36
|
+
return cloneNonPlainShallow(value);
|
|
37
|
+
}
|
|
38
|
+
return value;
|
|
39
|
+
}
|
|
40
|
+
function cloneArray(source, resetDates, deepCloneAll) {
|
|
41
|
+
const len = source.length, out = new Array(len);
|
|
42
|
+
for (let i = 0; i < len; i++) {
|
|
43
|
+
out[i] = cloneValue(source[i], resetDates, deepCloneAll);
|
|
44
|
+
}
|
|
45
|
+
return out;
|
|
46
|
+
}
|
|
47
|
+
function cloneNonPlainShallow(value) {
|
|
48
|
+
if (value instanceof RegExp) {
|
|
49
|
+
const re = new RegExp(value.source, value.flags);
|
|
50
|
+
re.lastIndex = value.lastIndex;
|
|
51
|
+
return re;
|
|
52
|
+
}
|
|
53
|
+
if (value instanceof Map)
|
|
54
|
+
return new Map(value);
|
|
55
|
+
if (value instanceof Set)
|
|
56
|
+
return new Set(value);
|
|
57
|
+
const clonedView = cloneArrayBufferView(value);
|
|
58
|
+
if (clonedView !== undefined)
|
|
59
|
+
return clonedView;
|
|
60
|
+
if (value instanceof ArrayBuffer)
|
|
61
|
+
return value.slice(0);
|
|
62
|
+
const proto = Object.getPrototypeOf(value), out = Object.create(proto);
|
|
63
|
+
for (const key in value) {
|
|
64
|
+
if (hop.call(value, key))
|
|
65
|
+
out[key] = value[key];
|
|
66
|
+
}
|
|
67
|
+
return out;
|
|
68
|
+
}
|
|
69
|
+
function cloneNonPlainDeep(value, resetDates) {
|
|
70
|
+
if (value instanceof RegExp) {
|
|
71
|
+
const re = new RegExp(value.source, value.flags);
|
|
72
|
+
re.lastIndex = value.lastIndex;
|
|
73
|
+
return re;
|
|
74
|
+
}
|
|
75
|
+
if (value instanceof Map) {
|
|
76
|
+
const out = new Map();
|
|
77
|
+
for (const [key, val] of value) {
|
|
78
|
+
out.set(cloneValue(key, resetDates, true), cloneValue(val, resetDates, true));
|
|
79
|
+
}
|
|
80
|
+
return out;
|
|
81
|
+
}
|
|
82
|
+
if (value instanceof Set) {
|
|
83
|
+
const out = new Set();
|
|
84
|
+
for (const entry of value) {
|
|
85
|
+
out.add(cloneValue(entry, resetDates, true));
|
|
86
|
+
}
|
|
87
|
+
return out;
|
|
88
|
+
}
|
|
89
|
+
const clonedView = cloneArrayBufferView(value);
|
|
90
|
+
if (clonedView !== undefined)
|
|
91
|
+
return clonedView;
|
|
92
|
+
if (value instanceof ArrayBuffer)
|
|
93
|
+
return value.slice(0);
|
|
94
|
+
const proto = Object.getPrototypeOf(value), out = Object.create(proto);
|
|
95
|
+
for (const key in value) {
|
|
96
|
+
if (!hop.call(value, key))
|
|
97
|
+
continue;
|
|
98
|
+
out[key] = cloneValue(value[key], resetDates, true);
|
|
99
|
+
}
|
|
100
|
+
return out;
|
|
101
|
+
}
|
|
102
|
+
function cloneArrayBufferView(value) {
|
|
103
|
+
if (!ArrayBuffer.isView(value))
|
|
104
|
+
return undefined;
|
|
105
|
+
const anyVal = value;
|
|
106
|
+
if (typeof anyVal.slice === 'function')
|
|
107
|
+
return anyVal.slice();
|
|
108
|
+
if (value instanceof DataView) {
|
|
109
|
+
return new DataView(value.buffer.slice(value.byteOffset, value.byteOffset + value.byteLength));
|
|
110
|
+
}
|
|
111
|
+
return new anyVal.constructor(value.buffer.slice(value.byteOffset, value.byteOffset + value.byteLength));
|
|
112
|
+
}
|
|
113
|
+
export default copy;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import isPlainObject, {} from '../helpers/isPlainObject.js';
|
|
2
|
+
const hop = Object.prototype.hasOwnProperty;
|
|
3
|
+
function iterate(root, cb) {
|
|
4
|
+
if (!isPlainObject(root))
|
|
5
|
+
return;
|
|
6
|
+
iterateHelper(root, [], cb);
|
|
7
|
+
}
|
|
8
|
+
function iterateHelper(node, path, cb) {
|
|
9
|
+
if (Array.isArray(node)) {
|
|
10
|
+
for (let i = 0; i < node.length; i++) {
|
|
11
|
+
const value = node[i];
|
|
12
|
+
cb({ parent: node, key: i, value, path: path.slice() });
|
|
13
|
+
if (isPlainObject(value) || Array.isArray(value)) {
|
|
14
|
+
path.push(i);
|
|
15
|
+
iterateHelper(value, path, cb);
|
|
16
|
+
path.pop();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const dict = node;
|
|
22
|
+
for (const key in dict) {
|
|
23
|
+
if (!hop.call(dict, key))
|
|
24
|
+
continue;
|
|
25
|
+
const value = dict[key];
|
|
26
|
+
cb({ parent: dict, key, value, path: path.slice() });
|
|
27
|
+
if (isPlainObject(value) || Array.isArray(value)) {
|
|
28
|
+
path.push(key);
|
|
29
|
+
iterateHelper(value, path, cb);
|
|
30
|
+
path.pop();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export default iterate;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/******************************************************************************
|
|
2
|
+
Constants/Types
|
|
3
|
+
******************************************************************************/
|
|
4
|
+
export type PlainObject = Record<PropertyKey, unknown>;
|
|
5
|
+
/******************************************************************************
|
|
6
|
+
Functions
|
|
7
|
+
******************************************************************************/
|
|
8
|
+
/**
|
|
9
|
+
* Check if a 'unknown' is a 'PlainObject.
|
|
10
|
+
*/
|
|
11
|
+
declare function isPlainObject(arg: unknown): arg is PlainObject;
|
|
12
|
+
/******************************************************************************
|
|
13
|
+
Export
|
|
14
|
+
******************************************************************************/
|
|
15
|
+
export default isPlainObject;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/******************************************************************************
|
|
2
|
+
Types
|
|
3
|
+
******************************************************************************/
|
|
4
|
+
export type TruthyObject = NonNullable<object>;
|
|
5
|
+
type Primitive = string | number | boolean | bigint | symbol | null | undefined;
|
|
6
|
+
export type Dict = Record<string, unknown>;
|
|
7
|
+
export type KeysParam<T extends object> = keyof T | (keyof T)[];
|
|
8
|
+
export type Mutable<T> = {
|
|
9
|
+
-readonly [K in keyof T]: T[K];
|
|
10
|
+
};
|
|
11
|
+
export type KeyUnion<T extends object, K extends KeysParam<T>> = K extends (keyof T)[] ? K[number] : K;
|
|
12
|
+
export type OmitKeys<T extends object, K extends KeysParam<T>> = Omit<T, KeyUnion<T, K>>;
|
|
13
|
+
export type PickKeys<T extends object, K extends KeysParam<T>> = Pick<T, KeyUnion<T, K>>;
|
|
14
|
+
export type Entry<T extends object> = T extends object ? {
|
|
15
|
+
[K in keyof T]-?: [K, T[K]];
|
|
16
|
+
}[keyof T] : never;
|
|
17
|
+
export type SetToNever<T, K extends PropertyKey> = T & {
|
|
18
|
+
[P in K]: never;
|
|
19
|
+
};
|
|
20
|
+
type NonNeverKeys<T extends object> = {
|
|
21
|
+
[K in keyof T]-?: [T[K]] extends [never] ? never : K;
|
|
22
|
+
}[keyof T];
|
|
23
|
+
export type OmitNever<T extends object> = Pick<T, NonNeverKeys<T>>;
|
|
24
|
+
type UnionToIntersection<U> = (U extends any ? (x: U) => void : never) extends (x: infer I) => void ? I : never;
|
|
25
|
+
type LastOf<U> = UnionToIntersection<U extends any ? () => U : never> extends () => infer L ? L : never;
|
|
26
|
+
type UnionToTuple<U, R extends any[] = []> = [U] extends [never] ? R : UnionToTuple<Exclude<U, LastOf<U>>, [LastOf<U>, ...R]>;
|
|
27
|
+
type Entries<T extends object> = {
|
|
28
|
+
[K in keyof T]-?: [K, T[K]];
|
|
29
|
+
}[keyof T];
|
|
30
|
+
export type EntriesTuple<T extends object> = UnionToTuple<Entries<T>>;
|
|
31
|
+
export type KeyTuple<T extends object> = UnionToTuple<keyof T>;
|
|
32
|
+
export type ValueTuple<T extends object> = UnionToTuple<T[keyof T]>;
|
|
33
|
+
type WidenPrimitive<T> = T extends string ? string : T extends number ? number : T extends boolean ? boolean : T extends bigint ? bigint : T extends symbol ? symbol : T;
|
|
34
|
+
export type DeepWiden<T> = T extends Primitive ? WidenPrimitive<T> : T extends (...args: any[]) => any ? T : T extends readonly (infer U)[] ? DeepWiden<U>[] : T extends object ? {
|
|
35
|
+
[K in keyof T]: DeepWiden<T[K]>;
|
|
36
|
+
} : T;
|
|
37
|
+
export type EntryToAdd = readonly [PropertyKey, unknown];
|
|
38
|
+
export type AddEntries<T extends object, Entries extends readonly EntryToAdd[]> = T & {
|
|
39
|
+
[K in Entries[number] as K[0]]: Extract<Entries[number], readonly [K[0], unknown]>[1];
|
|
40
|
+
};
|
|
41
|
+
type UnionKeys<U extends object> = U extends unknown ? keyof U : never;
|
|
42
|
+
type UnionValuesForKey<U extends object, K extends PropertyKey> = U extends unknown ? (K extends keyof U ? U[K] : never) : never;
|
|
43
|
+
type MergeUnion<U extends object> = [UnionKeys<U>] extends [never] ? Dict : {
|
|
44
|
+
[K in UnionKeys<U>]: UnionValuesForKey<U, K>;
|
|
45
|
+
};
|
|
46
|
+
export type MergeArray<A extends readonly TruthyObject[]> = MergeUnion<A[number]>;
|
|
47
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { PlainObject } from './helpers/isPlainObject.js';
|
|
2
|
+
import type { KeysParam, KeyUnion, SetToNever } from './helpers/utility-types.js';
|
|
3
|
+
import tspo from './tspo.js';
|
|
4
|
+
/******************************************************************************
|
|
5
|
+
Types
|
|
6
|
+
******************************************************************************/
|
|
7
|
+
type CollapseType<T> = {
|
|
8
|
+
[K in keyof T]: T[K];
|
|
9
|
+
} & {};
|
|
10
|
+
type Append = <T extends PlainObject, U extends PlainObject>(obj: T, addOn: U) => asserts obj is CollapseType<T & U>;
|
|
11
|
+
type AddEntry = <T extends PlainObject, K extends string, V>(obj: T, entry: [K, V]) => asserts obj is CollapseType<T & Record<K, V>>;
|
|
12
|
+
type Remove = <T extends PlainObject, K extends KeysParam<T>>(obj: T, keys: K) => asserts obj is CollapseType<SetToNever<T, KeyUnion<T, K>>>;
|
|
13
|
+
/******************************************************************************
|
|
14
|
+
Constants
|
|
15
|
+
******************************************************************************/
|
|
16
|
+
declare const typedTspo: Readonly<typeof tspo> & {
|
|
17
|
+
readonly append: Append;
|
|
18
|
+
readonly addEntry: AddEntry;
|
|
19
|
+
readonly remove: Remove;
|
|
20
|
+
};
|
|
21
|
+
/******************************************************************************
|
|
22
|
+
Export
|
|
23
|
+
******************************************************************************/
|
|
24
|
+
export { type OmitNever } from './helpers/utility-types.js';
|
|
25
|
+
export default typedTspo;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import isPlainObject from './helpers/isPlainObject.js';
|
|
2
|
+
import type { AddEntries, DeepWiden, EntriesTuple, Entry, EntryToAdd, KeysParam, KeyTuple, KeyUnion, MergeArray, OmitKeys, PickKeys, SetToNever, TruthyObject, ValueTuple } from './helpers/utility-types.js';
|
|
3
|
+
import compare from './utils/compare.js';
|
|
4
|
+
import copy from './utils/copy.js';
|
|
5
|
+
import iterate from './utils/iterate.js';
|
|
6
|
+
/******************************************************************************
|
|
7
|
+
Types
|
|
8
|
+
******************************************************************************/
|
|
9
|
+
type CollapseType<T> = {
|
|
10
|
+
-readonly [K in keyof T]: T[K];
|
|
11
|
+
} & {};
|
|
12
|
+
/******************************************************************************
|
|
13
|
+
Functions
|
|
14
|
+
******************************************************************************/
|
|
15
|
+
/**
|
|
16
|
+
* Return a new object by excluding certains keys from an object.
|
|
17
|
+
*/
|
|
18
|
+
declare function omit<T extends TruthyObject, K extends KeysParam<T>>(obj: T, keys: K): CollapseType<OmitKeys<T, K>>;
|
|
19
|
+
/**
|
|
20
|
+
* Return a new object by selecting a specific set of keys on an object.
|
|
21
|
+
*/
|
|
22
|
+
declare function pick<T extends TruthyObject, K extends KeysParam<T>>(obj: T, keys: K): CollapseType<PickKeys<T, K>>;
|
|
23
|
+
/**
|
|
24
|
+
* Merge two object together and return a new type.
|
|
25
|
+
*/
|
|
26
|
+
declare function merge<T extends TruthyObject, U extends TruthyObject>(a: T, b: U): CollapseType<Omit<T, keyof U> & U>;
|
|
27
|
+
/**
|
|
28
|
+
* Merge an array of objects together
|
|
29
|
+
*/
|
|
30
|
+
declare function mergeArray<const A extends readonly TruthyObject[]>(arr: A): CollapseType<MergeArray<A>>;
|
|
31
|
+
/**
|
|
32
|
+
* Append a single entry to an object.
|
|
33
|
+
*/
|
|
34
|
+
declare function addEntry<T extends TruthyObject, K extends string, V>(obj: T, entry: [K, V]): CollapseType<T & Record<K, V>>;
|
|
35
|
+
/**
|
|
36
|
+
* Append a single entry to an object.
|
|
37
|
+
*/
|
|
38
|
+
declare function addEntries<T extends TruthyObject, const E extends readonly EntryToAdd[]>(obj: T, entries: E): CollapseType<DeepWiden<AddEntries<T, E>>>;
|
|
39
|
+
/**
|
|
40
|
+
* Append one object to another, modifying the reference to the original
|
|
41
|
+
* object.
|
|
42
|
+
*/
|
|
43
|
+
declare function append<T extends TruthyObject, U extends TruthyObject>(obj: T, addOn: U): asserts obj is CollapseType<T & U>;
|
|
44
|
+
/**
|
|
45
|
+
* Remove keys from an object and set the type to 'never'.
|
|
46
|
+
*/
|
|
47
|
+
declare function remove<T extends TruthyObject, K extends KeysParam<T>>(obj: T, keys: K): asserts obj is CollapseType<SetToNever<T, KeyUnion<T, K>>>;
|
|
48
|
+
/**
|
|
49
|
+
* Get a value on an object and return 'undefined' if not found.
|
|
50
|
+
*/
|
|
51
|
+
declare function index<T extends TruthyObject>(obj: T, key: string | number): T[keyof T] | undefined;
|
|
52
|
+
/**
|
|
53
|
+
* Get a value on an object and return 'undefined' if not found.
|
|
54
|
+
*/
|
|
55
|
+
declare function safeIndex<T extends TruthyObject>(obj: T, key: string | number): T[keyof T];
|
|
56
|
+
/**
|
|
57
|
+
* Get a list of keys for which the value matches.
|
|
58
|
+
*/
|
|
59
|
+
declare function reverseIndex<T extends TruthyObject>(obj: T, value: unknown): (keyof T)[];
|
|
60
|
+
/**
|
|
61
|
+
* Get a key for a value only if you know the value is unique.
|
|
62
|
+
*/
|
|
63
|
+
declare function safeReverseIndex<T extends TruthyObject>(obj: T, value: unknown): keyof T;
|
|
64
|
+
/**
|
|
65
|
+
* Validator function to check
|
|
66
|
+
*/
|
|
67
|
+
declare function isKey<T extends TruthyObject>(obj: T, arg: PropertyKey): arg is keyof T;
|
|
68
|
+
/**
|
|
69
|
+
* Validator function to check
|
|
70
|
+
*/
|
|
71
|
+
declare function isValue<T extends TruthyObject>(obj: T, arg: unknown): arg is T[keyof T];
|
|
72
|
+
/**
|
|
73
|
+
* Similar to `isPlainObject` but narrows a plain-object even further to
|
|
74
|
+
* exclude symbols. Note that when numbers are added as keys to objects they
|
|
75
|
+
* are converted to strings so we don't have to check for those.
|
|
76
|
+
*/
|
|
77
|
+
declare function isDict(arg: unknown): arg is Record<string, unknown>;
|
|
78
|
+
/**
|
|
79
|
+
* Get a type-safe array of the object keys.
|
|
80
|
+
*/
|
|
81
|
+
declare function keys<T extends TruthyObject>(obj: T): KeyTuple<T>;
|
|
82
|
+
/**
|
|
83
|
+
* Get a type-safe array of the object values
|
|
84
|
+
*/
|
|
85
|
+
declare function values<T extends TruthyObject>(obj: T): ValueTuple<T>;
|
|
86
|
+
/**
|
|
87
|
+
* Get a type-safe array of the object entries
|
|
88
|
+
*/
|
|
89
|
+
declare function entries<T extends TruthyObject>(obj: T): EntriesTuple<T>;
|
|
90
|
+
/**
|
|
91
|
+
* Get a type-safe array of the object e
|
|
92
|
+
*/
|
|
93
|
+
declare function firstEntry<T extends TruthyObject>(obj: T): Entry<T>;
|
|
94
|
+
/******************************************************************************
|
|
95
|
+
Export
|
|
96
|
+
******************************************************************************/
|
|
97
|
+
declare const _default: {
|
|
98
|
+
readonly omit: typeof omit;
|
|
99
|
+
readonly pick: typeof pick;
|
|
100
|
+
readonly merge: typeof merge;
|
|
101
|
+
readonly mergeArray: typeof mergeArray;
|
|
102
|
+
readonly append: typeof append;
|
|
103
|
+
readonly addEntry: typeof addEntry;
|
|
104
|
+
readonly addEntries: typeof addEntries;
|
|
105
|
+
readonly index: typeof index;
|
|
106
|
+
readonly remove: typeof remove;
|
|
107
|
+
readonly safeIndex: typeof safeIndex;
|
|
108
|
+
readonly reverseIndex: typeof reverseIndex;
|
|
109
|
+
readonly safeReverseIndex: typeof safeReverseIndex;
|
|
110
|
+
readonly is: typeof isPlainObject;
|
|
111
|
+
readonly isKey: typeof isKey;
|
|
112
|
+
readonly isValue: typeof isValue;
|
|
113
|
+
readonly keys: typeof keys;
|
|
114
|
+
readonly values: typeof values;
|
|
115
|
+
readonly entries: typeof entries;
|
|
116
|
+
readonly firstEntry: typeof firstEntry;
|
|
117
|
+
readonly iterate: typeof iterate;
|
|
118
|
+
readonly copy: typeof copy;
|
|
119
|
+
readonly compare: typeof compare;
|
|
120
|
+
readonly isDict: typeof isDict;
|
|
121
|
+
};
|
|
122
|
+
export default _default;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type PlainObject } from '../helpers/isPlainObject.js';
|
|
2
|
+
/******************************************************************************
|
|
3
|
+
Functions
|
|
4
|
+
******************************************************************************/
|
|
5
|
+
/**
|
|
6
|
+
* Recursively compares two plain objects.
|
|
7
|
+
*
|
|
8
|
+
* Traversal rules:
|
|
9
|
+
* - recurse into plain objects
|
|
10
|
+
* - recurse into arrays
|
|
11
|
+
* - compare Date by epoch (`getTime()`)
|
|
12
|
+
* - compare any other object values by reference
|
|
13
|
+
*/
|
|
14
|
+
declare function compare(a: PlainObject, b: PlainObject): boolean;
|
|
15
|
+
/******************************************************************************
|
|
16
|
+
Export
|
|
17
|
+
******************************************************************************/
|
|
18
|
+
export default compare;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type PlainObject } from '../helpers/isPlainObject.js';
|
|
2
|
+
import type { Mutable } from '../helpers/utility-types.js';
|
|
3
|
+
/******************************************************************************
|
|
4
|
+
Types
|
|
5
|
+
******************************************************************************/
|
|
6
|
+
interface CopyOptions {
|
|
7
|
+
resetDates?: boolean;
|
|
8
|
+
deepCloneAll?: boolean;
|
|
9
|
+
}
|
|
10
|
+
/******************************************************************************
|
|
11
|
+
Functions
|
|
12
|
+
******************************************************************************/
|
|
13
|
+
/**
|
|
14
|
+
* Deep clones ONLY plain-objects (incl. null-prototype).
|
|
15
|
+
*
|
|
16
|
+
* - Root value must be a plain-object.
|
|
17
|
+
* - Recursion descends only into plain-objects and arrays.
|
|
18
|
+
* - Nested Date values are copied by epoch.
|
|
19
|
+
* - `resetDates` resets all nested Date values to current time.
|
|
20
|
+
* - Other nested non-plain objects are shallow-cloned by default.
|
|
21
|
+
* - `deepCloneAll` deep-clones all nested object values.
|
|
22
|
+
*/
|
|
23
|
+
declare function copy<T extends PlainObject>(value: T, options?: CopyOptions): Mutable<T>;
|
|
24
|
+
/******************************************************************************
|
|
25
|
+
Functions
|
|
26
|
+
******************************************************************************/
|
|
27
|
+
export default copy;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type PlainObject } from '../helpers/isPlainObject.js';
|
|
2
|
+
/******************************************************************************
|
|
3
|
+
Types
|
|
4
|
+
******************************************************************************/
|
|
5
|
+
type IterateCb = (args: {
|
|
6
|
+
parent: PlainObject | unknown[];
|
|
7
|
+
key: string | number;
|
|
8
|
+
value: unknown;
|
|
9
|
+
path: readonly (string | number)[];
|
|
10
|
+
}) => void;
|
|
11
|
+
/******************************************************************************
|
|
12
|
+
Functions
|
|
13
|
+
******************************************************************************/
|
|
14
|
+
/**
|
|
15
|
+
* Recursively walks plain-objects and arrays, and calls a callback for
|
|
16
|
+
* every key before descending into nested values.
|
|
17
|
+
*
|
|
18
|
+
* - Descends into a value if it is a plain-object or array.
|
|
19
|
+
* - Fires callback for every entry (including plain-objects/arrays).
|
|
20
|
+
*/
|
|
21
|
+
declare function iterate(root: unknown, cb: IterateCb): void;
|
|
22
|
+
/******************************************************************************
|
|
23
|
+
Export
|
|
24
|
+
******************************************************************************/
|
|
25
|
+
export default iterate;
|