@radio-garden/ditojs-utils 2.85.0-0.5067ad799
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 +6 -0
- package/package.json +43 -0
- package/src/__snapshots__/index.test.js.snap +88 -0
- package/src/array/flatten.js +14 -0
- package/src/array/flattten.test.js +29 -0
- package/src/array/index.js +2 -0
- package/src/array/shuffle.js +11 -0
- package/src/array/shuffle.test.js +25 -0
- package/src/base/base.js +118 -0
- package/src/base/base.test.js +590 -0
- package/src/base/index.js +1 -0
- package/src/class/index.js +1 -0
- package/src/class/mixin.js +29 -0
- package/src/class/mixin.test.js +70 -0
- package/src/dataPath/getEntriesAtDataPath.js +67 -0
- package/src/dataPath/getEntriesAtDataPath.test.js +204 -0
- package/src/dataPath/getValueAtDataPath.js +45 -0
- package/src/dataPath/getValueAtDataPath.test.js +140 -0
- package/src/dataPath/index.js +6 -0
- package/src/dataPath/normalizeDataPath.js +27 -0
- package/src/dataPath/normalizeDataPath.test.js +36 -0
- package/src/dataPath/parseDataPath.js +16 -0
- package/src/dataPath/parseDataPath.test.js +67 -0
- package/src/dataPath/setDataPathEntries.js +8 -0
- package/src/dataPath/setDataPathEntries.test.js +36 -0
- package/src/dataPath/setValueAtDataPath.js +13 -0
- package/src/dataPath/setValueAtDataPath.test.js +34 -0
- package/src/function/deprecate.js +9 -0
- package/src/function/index.js +4 -0
- package/src/function/toAsync.js +9 -0
- package/src/function/toAsync.test.js +31 -0
- package/src/function/toCallback.js +11 -0
- package/src/function/toCallback.test.js +29 -0
- package/src/function/toPromiseCallback.js +9 -0
- package/src/function/toPromiseCallback.test.js +24 -0
- package/src/html/escapeHtml.js +11 -0
- package/src/html/escapeHtml.test.js +19 -0
- package/src/html/index.js +2 -0
- package/src/html/stripHtml.js +23 -0
- package/src/html/stripHtml.test.js +37 -0
- package/src/index.js +10 -0
- package/src/index.test.js +7 -0
- package/src/object/asCallback.js +9 -0
- package/src/object/clone.js +75 -0
- package/src/object/clone.test.js +131 -0
- package/src/object/equals.js +36 -0
- package/src/object/equals.test.js +269 -0
- package/src/object/groupBy.js +15 -0
- package/src/object/groupBy.test.js +70 -0
- package/src/object/index.js +8 -0
- package/src/object/mapKeys.js +7 -0
- package/src/object/mapKeys.test.js +16 -0
- package/src/object/mapValues.js +9 -0
- package/src/object/mapValues.test.js +38 -0
- package/src/object/mergeDeeply.js +47 -0
- package/src/object/mergeDeeply.test.js +152 -0
- package/src/object/pick.js +11 -0
- package/src/object/pick.test.js +23 -0
- package/src/object/pickBy.js +11 -0
- package/src/object/pickBy.test.js +48 -0
- package/src/promise/index.js +2 -0
- package/src/promise/mapConcurrently.js +33 -0
- package/src/promise/mapSequentially.js +9 -0
- package/src/string/camelize.js +14 -0
- package/src/string/camelize.test.js +37 -0
- package/src/string/capitalize.js +7 -0
- package/src/string/capitalize.test.js +33 -0
- package/src/string/decamelize.js +27 -0
- package/src/string/decamelize.test.js +83 -0
- package/src/string/deindent.js +69 -0
- package/src/string/deindent.test.js +181 -0
- package/src/string/escapeRegexp.js +3 -0
- package/src/string/format.js +109 -0
- package/src/string/format.test.js +196 -0
- package/src/string/formatDate.js +13 -0
- package/src/string/formatDate.test.js +28 -0
- package/src/string/getCommonPrefix.js +35 -0
- package/src/string/getCommonPrefix.test.js +23 -0
- package/src/string/index.js +15 -0
- package/src/string/isAbsoluteUrl.js +7 -0
- package/src/string/isAbsoluteUrl.test.js +15 -0
- package/src/string/isCreditCard.js +21 -0
- package/src/string/isCreditCard.test.js +50 -0
- package/src/string/isDomain.js +9 -0
- package/src/string/isDomain.test.js +15 -0
- package/src/string/isEmail.js +6 -0
- package/src/string/isEmail.test.js +37 -0
- package/src/string/isHostname.js +8 -0
- package/src/string/isHostname.test.js +12 -0
- package/src/string/isUrl.js +23 -0
- package/src/string/isUrl.test.js +1595 -0
- package/src/string/labelize.js +17 -0
- package/src/string/labelize.test.js +39 -0
- package/src/timer/debounce.js +34 -0
- package/src/timer/debounce.test.js +101 -0
- package/src/timer/debounceAsync.js +60 -0
- package/src/timer/debounceAsync.test.js +143 -0
- package/src/timer/index.js +2 -0
- package/types/index.d.ts +939 -0
- package/types/tests/base.test-d.ts +172 -0
- package/types/tests/datapath.test-d.ts +75 -0
- package/types/tests/function.test-d.ts +137 -0
- package/types/tests/object.test-d.ts +190 -0
- package/types/tests/promise.test-d.ts +66 -0
package/README.md
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@radio-garden/ditojs-utils",
|
|
3
|
+
"version": "2.85.0-0.5067ad799",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Dito.js Utility Functions – Dito.js is a declarative and modern web framework, based on Objection.js, Koa.js and Vue.js",
|
|
6
|
+
"repository": "https://github.com/ditojs/dito/tree/master/packages/utils",
|
|
7
|
+
"author": "Jürg Lehni <juerg@scratchdisk.com> (http://scratchdisk.com)",
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"main": "./src/index.js",
|
|
10
|
+
"types": "./types/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./types/index.d.ts",
|
|
14
|
+
"import": "./src/index.js",
|
|
15
|
+
"require": "./src/index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"src/",
|
|
20
|
+
"types/"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"types": "tsc --noEmit types/index.d.ts"
|
|
24
|
+
},
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">= 20.0.0"
|
|
27
|
+
},
|
|
28
|
+
"browserslist": [
|
|
29
|
+
"node >= 18",
|
|
30
|
+
"> 1%",
|
|
31
|
+
"last 2 versions",
|
|
32
|
+
"ie >= 11",
|
|
33
|
+
"ie_mob >= 11"
|
|
34
|
+
],
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"punycode": "^2.3.1"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"typescript": "^5.9.3"
|
|
40
|
+
},
|
|
41
|
+
"gitHead": "5067ad799",
|
|
42
|
+
"gitBranch": "chore/improve-ts-types"
|
|
43
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`index > exports all symbols 1`] = `
|
|
4
|
+
{
|
|
5
|
+
"asArray": [Function],
|
|
6
|
+
"asFunction": [Function],
|
|
7
|
+
"asObject": [Function],
|
|
8
|
+
"assignDeeply": [Function],
|
|
9
|
+
"camelize": [Function],
|
|
10
|
+
"capitalize": [Function],
|
|
11
|
+
"clone": [Function],
|
|
12
|
+
"debounce": [Function],
|
|
13
|
+
"debounceAsync": [Function],
|
|
14
|
+
"decamelize": [Function],
|
|
15
|
+
"defaultFormats": {
|
|
16
|
+
"date": {
|
|
17
|
+
"day": "numeric",
|
|
18
|
+
"month": "long",
|
|
19
|
+
"year": "numeric",
|
|
20
|
+
},
|
|
21
|
+
"number": {
|
|
22
|
+
"style": "decimal",
|
|
23
|
+
},
|
|
24
|
+
"time": {
|
|
25
|
+
"hour": "2-digit",
|
|
26
|
+
"minute": "2-digit",
|
|
27
|
+
"second": "2-digit",
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
"deindent": [Function],
|
|
31
|
+
"deprecate": [Function],
|
|
32
|
+
"equals": [Function],
|
|
33
|
+
"escapeHtml": [Function],
|
|
34
|
+
"escapeRegexp": [Function],
|
|
35
|
+
"flatten": [Function],
|
|
36
|
+
"format": [Function],
|
|
37
|
+
"formatDate": [Function],
|
|
38
|
+
"getCommonOffset": [Function],
|
|
39
|
+
"getCommonPrefix": [Function],
|
|
40
|
+
"getEntriesAtDataPath": [Function],
|
|
41
|
+
"getValueAtDataPath": [Function],
|
|
42
|
+
"groupBy": [Function],
|
|
43
|
+
"hyphenate": [Function],
|
|
44
|
+
"is": [Function],
|
|
45
|
+
"isAbsoluteUrl": [Function],
|
|
46
|
+
"isArray": [Function],
|
|
47
|
+
"isArrayLike": [Function],
|
|
48
|
+
"isAsync": [Function],
|
|
49
|
+
"isBoolean": [Function],
|
|
50
|
+
"isCreditCard": [Function],
|
|
51
|
+
"isDate": [Function],
|
|
52
|
+
"isDomain": [Function],
|
|
53
|
+
"isEmail": [Function],
|
|
54
|
+
"isEmpty": [Function],
|
|
55
|
+
"isFunction": [Function],
|
|
56
|
+
"isHostname": [Function],
|
|
57
|
+
"isInteger": [Function],
|
|
58
|
+
"isModule": [Function],
|
|
59
|
+
"isNumber": [Function],
|
|
60
|
+
"isObject": [Function],
|
|
61
|
+
"isPlainArray": [Function],
|
|
62
|
+
"isPlainObject": [Function],
|
|
63
|
+
"isPromise": [Function],
|
|
64
|
+
"isRegExp": [Function],
|
|
65
|
+
"isString": [Function],
|
|
66
|
+
"isUrl": [Function],
|
|
67
|
+
"labelize": [Function],
|
|
68
|
+
"mapConcurrently": [Function],
|
|
69
|
+
"mapKeys": [Function],
|
|
70
|
+
"mapSequentially": [Function],
|
|
71
|
+
"mapValues": [Function],
|
|
72
|
+
"mergeDeeply": [Function],
|
|
73
|
+
"mixin": [Function],
|
|
74
|
+
"normalizeDataPath": [Function],
|
|
75
|
+
"parseDataPath": [Function],
|
|
76
|
+
"pick": [Function],
|
|
77
|
+
"pickBy": [Function],
|
|
78
|
+
"setDataPathEntries": [Function],
|
|
79
|
+
"setValueAtDataPath": [Function],
|
|
80
|
+
"shuffle": [Function],
|
|
81
|
+
"stripHtml": [Function],
|
|
82
|
+
"stripTags": [Function],
|
|
83
|
+
"toAsync": [Function],
|
|
84
|
+
"toCallback": [Function],
|
|
85
|
+
"toPromiseCallback": [Function],
|
|
86
|
+
"underscore": [Function],
|
|
87
|
+
}
|
|
88
|
+
`;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { isArray } from '../base/index.js'
|
|
2
|
+
|
|
3
|
+
export function flatten(array, maxDepth = Infinity, _depth = 0) {
|
|
4
|
+
const res = []
|
|
5
|
+
for (let i = 0, l = array.length; i < l; i++) {
|
|
6
|
+
const value = array[i]
|
|
7
|
+
if (_depth < maxDepth && isArray(value)) {
|
|
8
|
+
res.push(...flatten(value, maxDepth, _depth + 1))
|
|
9
|
+
} else {
|
|
10
|
+
res.push(value)
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return res
|
|
14
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { flatten } from './flatten.js'
|
|
2
|
+
|
|
3
|
+
describe('flatten()', () => {
|
|
4
|
+
it('should support flattening of nested arrays', () => {
|
|
5
|
+
const array = [1, [2, [3, [4]], 5]]
|
|
6
|
+
expect(flatten(array)).toStrictEqual([1, 2, 3, 4, 5])
|
|
7
|
+
expect(flatten(array, 1)).toStrictEqual([1, 2, [3, [4]], 5])
|
|
8
|
+
expect(flatten(array, 2)).toStrictEqual([1, 2, 3, [4], 5])
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
it('should work with empty arrays', () => {
|
|
12
|
+
const array = [[], [[]], [[], [[[]]]]]
|
|
13
|
+
|
|
14
|
+
expect(flatten(array)).toStrictEqual([])
|
|
15
|
+
expect(flatten(array, 1)).toStrictEqual([[], [], [[[]]]])
|
|
16
|
+
expect(flatten(array, 2)).toStrictEqual([[[]]])
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
it('should treat sparse arrays as dense', () => {
|
|
20
|
+
const array = [[1, 2, 3], Array(3)]
|
|
21
|
+
const expected = [1, 2, 3]
|
|
22
|
+
expected.push(undefined, undefined, undefined)
|
|
23
|
+
expect(flatten(array)).toStrictEqual(expected)
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it('should return an empty array for non array-like objects', () => {
|
|
27
|
+
expect(flatten({ 0: 'a' })).toStrictEqual([])
|
|
28
|
+
})
|
|
29
|
+
})
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function shuffle(array) {
|
|
2
|
+
// Do the Fisher-Yates (aka Knuth) Shuffle:
|
|
3
|
+
const res = array.slice()
|
|
4
|
+
for (let i = array.length; i; ) {
|
|
5
|
+
const r = Math.floor(Math.random() * i)
|
|
6
|
+
const t = res[--i]
|
|
7
|
+
res[i] = res[r]
|
|
8
|
+
res[r] = t
|
|
9
|
+
}
|
|
10
|
+
return res
|
|
11
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { shuffle } from './shuffle.js'
|
|
2
|
+
|
|
3
|
+
describe('shuffle()', () => {
|
|
4
|
+
const array = [1, 2, 3]
|
|
5
|
+
|
|
6
|
+
it('should return a new array', () => {
|
|
7
|
+
expect(shuffle(array)).not.toBe(array)
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
it(`should contain the same elements after a collection is shuffled and sorted again`, () => {
|
|
11
|
+
expect(shuffle(array).sort()).toStrictEqual(array)
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
it('should shuffle small collections', () => {
|
|
15
|
+
const results = {}
|
|
16
|
+
for (let i = 0; i < 1000; i++) {
|
|
17
|
+
const res = shuffle([1, 2])
|
|
18
|
+
results[res] = res
|
|
19
|
+
}
|
|
20
|
+
const sorted = Object.entries(results)
|
|
21
|
+
.sort()
|
|
22
|
+
.map(([, value]) => value)
|
|
23
|
+
expect(sorted).toStrictEqual([[1, 2], [2, 1]])
|
|
24
|
+
})
|
|
25
|
+
})
|
package/src/base/base.js
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
export const { isArray } = Array
|
|
2
|
+
const { toString } = Object.prototype
|
|
3
|
+
|
|
4
|
+
export const is = (
|
|
5
|
+
Object.is ||
|
|
6
|
+
// SameValue algorithm:
|
|
7
|
+
// istanbul ignore next
|
|
8
|
+
((x, y) => (x === y ? x !== 0 || 1 / x === 1 / y : x !== x && y !== y))
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
export function isPlainObject(arg) {
|
|
12
|
+
const ctor = arg?.constructor
|
|
13
|
+
// We also need to check for ctor.name === 'Object', in case this is an object
|
|
14
|
+
// from another global scope (e.g. another vm context in Node.js).
|
|
15
|
+
// When an value has no constructor, it was created with `Object.create(null)`
|
|
16
|
+
return !!(
|
|
17
|
+
arg && (
|
|
18
|
+
ctor && (ctor === Object || ctor.name === 'Object') ||
|
|
19
|
+
!ctor && !isModule(arg)
|
|
20
|
+
)
|
|
21
|
+
)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function isPlainArray(arg) {
|
|
25
|
+
const ctor = arg?.constructor
|
|
26
|
+
// See `isPlainObject()` for explanation.
|
|
27
|
+
return !!(arg && ctor && (ctor === Array || ctor.name === 'Array'))
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function isObject(arg) {
|
|
31
|
+
return !!arg && typeof arg === 'object' && !isArray(arg)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function isFunction(arg) {
|
|
35
|
+
return !!arg && typeof arg === 'function'
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function getPrimitiveCheck(name) {
|
|
39
|
+
// Create checking function for all primitive types (number, string, boolean)
|
|
40
|
+
// that also matches their Object wrappers. We can't check `valueOf()` returns
|
|
41
|
+
// here because `new Date().valueOf()` also returns a number.
|
|
42
|
+
const typeName = name.toLowerCase()
|
|
43
|
+
const toStringName = `[object ${name}]`
|
|
44
|
+
return function (arg) {
|
|
45
|
+
const type = typeof arg
|
|
46
|
+
return (
|
|
47
|
+
type === typeName ||
|
|
48
|
+
!!arg && type === 'object' && toString.call(arg) === toStringName
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export const isModule = getPrimitiveCheck('Module')
|
|
54
|
+
|
|
55
|
+
export const isNumber = getPrimitiveCheck('Number')
|
|
56
|
+
|
|
57
|
+
export const isString = getPrimitiveCheck('String')
|
|
58
|
+
|
|
59
|
+
export const isBoolean = getPrimitiveCheck('Boolean')
|
|
60
|
+
|
|
61
|
+
export function isDate(arg) {
|
|
62
|
+
return !!arg && toString.call(arg) === '[object Date]'
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function isRegExp(arg) {
|
|
66
|
+
return !!arg && toString.call(arg) === '[object RegExp]'
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function isPromise(arg) {
|
|
70
|
+
return !!arg && isFunction(arg.then) && isFunction(arg.catch)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export const isInteger = (
|
|
74
|
+
Number.isInteger ||
|
|
75
|
+
function isInteger(arg) {
|
|
76
|
+
return (
|
|
77
|
+
isNumber(arg) &&
|
|
78
|
+
isFinite(arg) &&
|
|
79
|
+
Math.floor(arg) === arg
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
export function isAsync(arg) {
|
|
85
|
+
return arg?.[Symbol.toStringTag] === 'AsyncFunction'
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function isArrayLike(arg) {
|
|
89
|
+
const length = arg?.length
|
|
90
|
+
return (
|
|
91
|
+
length != null &&
|
|
92
|
+
!isFunction(arg) &&
|
|
93
|
+
isNumber(length) &&
|
|
94
|
+
length >= 0 &&
|
|
95
|
+
length <= Number.MAX_SAFE_INTEGER
|
|
96
|
+
)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function isEmpty(arg) {
|
|
100
|
+
return (
|
|
101
|
+
arg == null ||
|
|
102
|
+
isArrayLike(arg) && arg.length === 0 ||
|
|
103
|
+
isObject(arg) && Object.keys(arg).length === 0
|
|
104
|
+
)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function asObject(arg) {
|
|
108
|
+
// http://2ality.com/2011/04/javascript-converting-any-value-to.html
|
|
109
|
+
return arg != null ? Object(arg) : arg
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function asArray(arg) {
|
|
113
|
+
return isArray(arg) ? arg : arg !== undefined ? [arg] : []
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function asFunction(arg) {
|
|
117
|
+
return isFunction(arg) ? arg : () => arg
|
|
118
|
+
}
|