@edgeandnode/eds-utils 1.0.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/LICENSE +21 -0
- package/README.md +53 -0
- package/dist/bigIntToNumber.d.ts +17 -0
- package/dist/bigIntToNumber.d.ts.map +1 -0
- package/dist/bigIntToNumber.js +25 -0
- package/dist/bigIntToNumber.js.map +1 -0
- package/dist/camelToKebab.d.ts +3 -0
- package/dist/camelToKebab.d.ts.map +1 -0
- package/dist/camelToKebab.js +15 -0
- package/dist/camelToKebab.js.map +1 -0
- package/dist/constants.d.ts +3 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +3 -0
- package/dist/constants.js.map +1 -0
- package/dist/createIdenticon.d.ts +2 -0
- package/dist/createIdenticon.d.ts.map +1 -0
- package/dist/createIdenticon.js +75 -0
- package/dist/createIdenticon.js.map +1 -0
- package/dist/formatAddress.d.ts +14 -0
- package/dist/formatAddress.d.ts.map +1 -0
- package/dist/formatAddress.js +28 -0
- package/dist/formatAddress.js.map +1 -0
- package/dist/formatBigInt.d.ts +23 -0
- package/dist/formatBigInt.d.ts.map +1 -0
- package/dist/formatBigInt.js +38 -0
- package/dist/formatBigInt.js.map +1 -0
- package/dist/getKey.d.ts +14 -0
- package/dist/getKey.d.ts.map +1 -0
- package/dist/getKey.js +36 -0
- package/dist/getKey.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/loremIpsum.d.ts +11 -0
- package/dist/loremIpsum.d.ts.map +1 -0
- package/dist/loremIpsum.js +136 -0
- package/dist/loremIpsum.js.map +1 -0
- package/dist/numberToBigInt.d.ts +18 -0
- package/dist/numberToBigInt.d.ts.map +1 -0
- package/dist/numberToBigInt.js +27 -0
- package/dist/numberToBigInt.js.map +1 -0
- package/dist/parseBigInt.d.ts +25 -0
- package/dist/parseBigInt.d.ts.map +1 -0
- package/dist/parseBigInt.js +35 -0
- package/dist/parseBigInt.js.map +1 -0
- package/dist/parseNumber.d.ts +17 -0
- package/dist/parseNumber.d.ts.map +1 -0
- package/dist/parseNumber.js +18 -0
- package/dist/parseNumber.js.map +1 -0
- package/dist/sliceWrap.d.ts +3 -0
- package/dist/sliceWrap.d.ts.map +1 -0
- package/dist/sliceWrap.js +11 -0
- package/dist/sliceWrap.js.map +1 -0
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +37 -0
- package/src/bigIntToNumber.ts +34 -0
- package/src/camelToKebab.ts +16 -0
- package/src/constants.ts +2 -0
- package/src/createIdenticon.ts +84 -0
- package/src/formatAddress.ts +33 -0
- package/src/formatBigInt.ts +60 -0
- package/src/getKey.ts +37 -0
- package/src/index.ts +13 -0
- package/src/loremIpsum.ts +143 -0
- package/src/numberToBigInt.ts +38 -0
- package/src/parseBigInt.ts +51 -0
- package/src/parseNumber.ts +24 -0
- package/src/sliceWrap.ts +9 -0
- package/src/types.ts +4 -0
package/src/getKey.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const refMap = new WeakMap<object, string>()
|
|
2
|
+
let refCounter = 0
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Generates a stable, unique string key for any JS value.
|
|
6
|
+
*
|
|
7
|
+
* - null / undefined => 'null' / 'undefined'
|
|
8
|
+
* - string / number / boolean => `${type}:${value}` (e.g. 'string:hello', 'number:42',
|
|
9
|
+
* 'boolean:false')
|
|
10
|
+
* - registered symbols (`Symbol.for('foo')`) => 'symbol:foo'
|
|
11
|
+
* - objects / functions / non-registered symbols => one-time ID (e.g. 'ref:1', 'ref:2', etc.)
|
|
12
|
+
*
|
|
13
|
+
* @param value - Any JavaScript value.
|
|
14
|
+
* @returns A string that uniquely and consistently identifies the value.
|
|
15
|
+
*/
|
|
16
|
+
export function getKey(value: unknown): string {
|
|
17
|
+
if (value === null) return 'null'
|
|
18
|
+
if (value === undefined) return 'undefined'
|
|
19
|
+
|
|
20
|
+
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
|
|
21
|
+
return `${typeof value}:${value}`
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (typeof value === 'symbol') {
|
|
25
|
+
const registryKey = Symbol.keyFor(value)
|
|
26
|
+
if (registryKey !== undefined) {
|
|
27
|
+
return `symbol:${registryKey}`
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
let id = refMap.get(value)
|
|
32
|
+
if (!id) {
|
|
33
|
+
id = `ref:${++refCounter}`
|
|
34
|
+
refMap.set(value, id)
|
|
35
|
+
}
|
|
36
|
+
return id
|
|
37
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export * from './constants.ts'
|
|
2
|
+
export * from './types.ts'
|
|
3
|
+
export { bigIntToNumber, type BigIntToNumberOptions } from './bigIntToNumber.ts'
|
|
4
|
+
export { camelToKebab } from './camelToKebab.ts'
|
|
5
|
+
export { createIdenticon } from './createIdenticon.ts'
|
|
6
|
+
export { formatAddress } from './formatAddress.ts'
|
|
7
|
+
export { formatBigInt, type BigIntFormatOptions } from './formatBigInt.ts'
|
|
8
|
+
export { getKey } from './getKey.ts'
|
|
9
|
+
export { loremIpsum } from './loremIpsum.ts'
|
|
10
|
+
export { numberToBigInt, type NumberToBigIntOptions } from './numberToBigInt.ts'
|
|
11
|
+
export { parseBigInt, type ParseBigIntOptions } from './parseBigInt.ts'
|
|
12
|
+
export { parseNumber, type ParseNumberOptions } from './parseNumber.ts'
|
|
13
|
+
export { sliceWrap } from './sliceWrap.ts'
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { sliceWrap } from './sliceWrap.ts'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Generates lorem ipsum text.
|
|
5
|
+
*
|
|
6
|
+
* @param {number} [count=4] - The number of words, sentences, or paragraphs to generate. Default is
|
|
7
|
+
* `4`
|
|
8
|
+
* @param {'words' | 'sentences' | 'paragraphs'} [units='sentences'] - The units to generate.
|
|
9
|
+
* Default is `'sentences'`
|
|
10
|
+
* @returns {string} The generated text.
|
|
11
|
+
*/
|
|
12
|
+
export function loremIpsum(
|
|
13
|
+
count: number = 4,
|
|
14
|
+
units: 'words' | 'sentences' | 'paragraphs' = 'sentences',
|
|
15
|
+
): string {
|
|
16
|
+
switch (units) {
|
|
17
|
+
case 'words':
|
|
18
|
+
return wordsToSentence(sliceWrap(WORDS, 0, count))
|
|
19
|
+
case 'sentences':
|
|
20
|
+
return sliceWrap(SENTENCES, 0, count)
|
|
21
|
+
.map((sentence) => wordsToSentence(sentence.words))
|
|
22
|
+
.join(' ')
|
|
23
|
+
case 'paragraphs':
|
|
24
|
+
return sliceWrap(PARAGRAPHS, 0, count)
|
|
25
|
+
.map((paragraph) =>
|
|
26
|
+
paragraph.sentences.map((sentence) => wordsToSentence(sentence.words)).join(' '),
|
|
27
|
+
)
|
|
28
|
+
.join('\n')
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function wordsToSentence(words: string[]) {
|
|
33
|
+
let sentence = ''
|
|
34
|
+
for (const word of words) {
|
|
35
|
+
if (sentence.length > 0) sentence += ' '
|
|
36
|
+
sentence += word
|
|
37
|
+
}
|
|
38
|
+
if (sentence.endsWith(',')) {
|
|
39
|
+
sentence = sentence.slice(0, -1)
|
|
40
|
+
}
|
|
41
|
+
if (sentence.length > 0 && !sentence.endsWith('.')) {
|
|
42
|
+
sentence += '.'
|
|
43
|
+
}
|
|
44
|
+
return sentence
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const LOREM_IPSUM = {
|
|
48
|
+
paragraphs: [
|
|
49
|
+
{
|
|
50
|
+
sentences: [
|
|
51
|
+
{
|
|
52
|
+
words: [
|
|
53
|
+
'Lorem',
|
|
54
|
+
'ipsum',
|
|
55
|
+
'dolor',
|
|
56
|
+
'sit',
|
|
57
|
+
'amet,',
|
|
58
|
+
'consectetur',
|
|
59
|
+
'adipiscing',
|
|
60
|
+
'elit,',
|
|
61
|
+
'sed',
|
|
62
|
+
'do',
|
|
63
|
+
'eiusmod',
|
|
64
|
+
'tempor',
|
|
65
|
+
'incididunt',
|
|
66
|
+
'ut',
|
|
67
|
+
'labore',
|
|
68
|
+
'et',
|
|
69
|
+
'dolore',
|
|
70
|
+
'magna',
|
|
71
|
+
'aliqua.',
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
words: [
|
|
76
|
+
'Ut',
|
|
77
|
+
'enim',
|
|
78
|
+
'ad',
|
|
79
|
+
'minim',
|
|
80
|
+
'veniam,',
|
|
81
|
+
'quis',
|
|
82
|
+
'nostrud',
|
|
83
|
+
'exercitation',
|
|
84
|
+
'ullamco',
|
|
85
|
+
'laboris',
|
|
86
|
+
'nisi',
|
|
87
|
+
'ut',
|
|
88
|
+
'aliquip',
|
|
89
|
+
'ex',
|
|
90
|
+
'ea',
|
|
91
|
+
'commodo',
|
|
92
|
+
'consequat.',
|
|
93
|
+
],
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
words: [
|
|
97
|
+
'Duis',
|
|
98
|
+
'aute',
|
|
99
|
+
'irure',
|
|
100
|
+
'dolor',
|
|
101
|
+
'in',
|
|
102
|
+
'reprehenderit',
|
|
103
|
+
'in',
|
|
104
|
+
'voluptate',
|
|
105
|
+
'velit',
|
|
106
|
+
'esse',
|
|
107
|
+
'cillum',
|
|
108
|
+
'dolore',
|
|
109
|
+
'eu',
|
|
110
|
+
'fugiat',
|
|
111
|
+
'nulla',
|
|
112
|
+
'pariatur.',
|
|
113
|
+
],
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
words: [
|
|
117
|
+
'Excepteur',
|
|
118
|
+
'sint',
|
|
119
|
+
'occaecat',
|
|
120
|
+
'cupidatat',
|
|
121
|
+
'non',
|
|
122
|
+
'proident,',
|
|
123
|
+
'sunt',
|
|
124
|
+
'in',
|
|
125
|
+
'culpa',
|
|
126
|
+
'qui',
|
|
127
|
+
'officia',
|
|
128
|
+
'deserunt',
|
|
129
|
+
'mollit',
|
|
130
|
+
'anim',
|
|
131
|
+
'id',
|
|
132
|
+
'est',
|
|
133
|
+
'laborum.',
|
|
134
|
+
],
|
|
135
|
+
},
|
|
136
|
+
],
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const PARAGRAPHS = LOREM_IPSUM.paragraphs
|
|
142
|
+
const SENTENCES = PARAGRAPHS.flatMap((paragraph) => paragraph.sentences)
|
|
143
|
+
const WORDS = SENTENCES.flatMap((sentence) => sentence.words)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { parseBigInt } from './parseBigInt.ts'
|
|
2
|
+
|
|
3
|
+
export interface NumberToBigIntOptions {
|
|
4
|
+
/**
|
|
5
|
+
* The number of digits starting from the right of the returned bigint to consider as decimal
|
|
6
|
+
* places.
|
|
7
|
+
*
|
|
8
|
+
* @default 18n
|
|
9
|
+
*/
|
|
10
|
+
precision?: bigint | undefined
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Converts a number to a bigint. Decimals to the right of `precision` are truncated.
|
|
15
|
+
*
|
|
16
|
+
* @param value - The number to convert to a bigint.
|
|
17
|
+
* @param options - Conversion options.
|
|
18
|
+
* @returns The bigint representation of `value`
|
|
19
|
+
*/
|
|
20
|
+
export function numberToBigInt(value: number, options?: NumberToBigIntOptions): bigint {
|
|
21
|
+
const { precision = 18n } = options ?? {}
|
|
22
|
+
if (precision < 0n) {
|
|
23
|
+
throw new Error(`[numberToBigInt] \`precision\` must be positive, got ${precision}`)
|
|
24
|
+
}
|
|
25
|
+
// If `value` has decimals and `precision` is at least 1, parse it as a string
|
|
26
|
+
if (value % 1 !== 0 && precision >= 1n) {
|
|
27
|
+
const parsedValue = parseBigInt(String(value), { precision })
|
|
28
|
+
if (parsedValue === null) {
|
|
29
|
+
throw new Error(
|
|
30
|
+
`[numberToBigInt] Failed to parse ${value} as a bigint with precision ${precision}`,
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
return parsedValue
|
|
34
|
+
} else {
|
|
35
|
+
const precisionFactor = 10n ** precision
|
|
36
|
+
return BigInt(Math.trunc(value)) * precisionFactor
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export interface ParseBigIntOptions {
|
|
2
|
+
/**
|
|
3
|
+
* The number of digits starting from the right of the returned bigint to consider as decimal
|
|
4
|
+
* places.
|
|
5
|
+
*
|
|
6
|
+
* @default 18n
|
|
7
|
+
*/
|
|
8
|
+
precision?: bigint | undefined
|
|
9
|
+
/**
|
|
10
|
+
* If true, requires exact match (no commas, no extra whitespace)
|
|
11
|
+
*
|
|
12
|
+
* @default false
|
|
13
|
+
*/
|
|
14
|
+
strict?: boolean | undefined
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Like `parseNumber()`, but returns a bigint instead of a number. Decimals to the right of
|
|
19
|
+
* `precision` are truncated.
|
|
20
|
+
*
|
|
21
|
+
* @param value - The string to parse as a bigint.
|
|
22
|
+
* @param options - Parsing options.
|
|
23
|
+
* @returns The bigint representation of `value`, or `null` if we failed to parse it.
|
|
24
|
+
*/
|
|
25
|
+
export function parseBigInt(value: string, options?: ParseBigIntOptions) {
|
|
26
|
+
const { precision = 18n, strict = false } = options ?? {}
|
|
27
|
+
if (precision < 0n) {
|
|
28
|
+
throw new Error(`[parseBigInt] \`precision\` must be positive, got ${precision}`)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const originalValue = value
|
|
32
|
+
const cleanedValue = value.replace(/,/g, '').trim()
|
|
33
|
+
|
|
34
|
+
if (strict && cleanedValue !== originalValue) return null
|
|
35
|
+
if (cleanedValue === '' || cleanedValue === '-' || cleanedValue === '.' || cleanedValue === '-.')
|
|
36
|
+
return null
|
|
37
|
+
|
|
38
|
+
const [integerPart, decimalPart = '', somethingAfterDecimalPart] = cleanedValue.split('.')
|
|
39
|
+
if (integerPart!.trim() !== integerPart) return null
|
|
40
|
+
if (decimalPart.trim() !== decimalPart) return null
|
|
41
|
+
if (somethingAfterDecimalPart !== undefined) return null
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
const precisionNumber = Number(precision)
|
|
45
|
+
return BigInt(
|
|
46
|
+
`${integerPart}${decimalPart.slice(0, precisionNumber).padEnd(precisionNumber, '0')}`,
|
|
47
|
+
)
|
|
48
|
+
} catch {
|
|
49
|
+
return null
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface ParseNumberOptions {
|
|
2
|
+
/**
|
|
3
|
+
* If true, requires exact match (no commas, no extra whitespace)
|
|
4
|
+
*
|
|
5
|
+
* @default false
|
|
6
|
+
*/
|
|
7
|
+
strict?: boolean | undefined
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Parses a string value into a number, with optional strict mode.
|
|
12
|
+
*
|
|
13
|
+
* @param value - The string value to parse.
|
|
14
|
+
* @param options - Parsing options.
|
|
15
|
+
* @returns The parsed number, or null if parsing fails.
|
|
16
|
+
*/
|
|
17
|
+
export function parseNumber(value: string, options?: ParseNumberOptions) {
|
|
18
|
+
const { strict = false } = options ?? {}
|
|
19
|
+
const cleanedValue = value.replace(/,/g, '').trim()
|
|
20
|
+
if (cleanedValue === '' || (cleanedValue !== value && strict)) return null
|
|
21
|
+
const number = Number(cleanedValue)
|
|
22
|
+
if (!Number.isFinite(number) || (String(number) !== cleanedValue && strict)) return null
|
|
23
|
+
return number
|
|
24
|
+
}
|
package/src/sliceWrap.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Same as `array.slice(start, end)`, but wraps around the end of the array. */
|
|
2
|
+
export function sliceWrap<T>(array: T[], start: number, end: number) {
|
|
3
|
+
if (array.length === 0) return []
|
|
4
|
+
const result: typeof array = []
|
|
5
|
+
for (let i = start; i < end; i++) {
|
|
6
|
+
result.push(array[i % array.length]!)
|
|
7
|
+
}
|
|
8
|
+
return result
|
|
9
|
+
}
|
package/src/types.ts
ADDED