@nemigo/helpers 0.13.2 → 1.5.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/dist/aggregator.d.ts +33 -0
- package/dist/aggregator.js +44 -0
- package/dist/array.d.ts +33 -0
- package/dist/array.js +24 -0
- package/dist/async/context.d.ts +73 -0
- package/dist/async/context.js +90 -0
- package/dist/async/future.d.ts +54 -0
- package/dist/async/future.js +71 -0
- package/dist/async/index.d.ts +56 -27
- package/dist/async/index.js +63 -58
- package/dist/async/loader.d.ts +67 -0
- package/dist/async/loader.js +101 -0
- package/dist/async/queue.d.ts +51 -0
- package/dist/async/queue.js +84 -0
- package/dist/cases.d.ts +31 -21
- package/dist/cases.js +41 -37
- package/dist/clean.d.ts +44 -26
- package/dist/clean.js +67 -42
- package/dist/color/types.d.ts +31 -0
- package/dist/color/types.js +1 -0
- package/dist/datetime/delta.d.ts +28 -0
- package/dist/datetime/delta.js +65 -0
- package/dist/datetime/format.d.ts +53 -0
- package/dist/datetime/format.js +119 -0
- package/dist/datetime/index.d.ts +6 -0
- package/dist/datetime/index.js +22 -0
- package/dist/datetime/plural.d.ts +77 -0
- package/dist/datetime/plural.js +78 -0
- package/dist/emitter.d.ts +29 -17
- package/dist/emitter.js +35 -21
- package/dist/explorer.d.ts +22 -29
- package/dist/explorer.js +18 -16
- package/dist/files.d.ts +31 -2
- package/dist/files.js +33 -8
- package/dist/fish.d.ts +29 -0
- package/dist/fish.js +70 -0
- package/dist/html/cookie.d.ts +48 -0
- package/dist/html/cookie.js +37 -0
- package/dist/html/events.d.ts +133 -0
- package/dist/html/events.js +139 -0
- package/dist/html/index.d.ts +31 -0
- package/dist/html/index.js +61 -0
- package/dist/index.d.ts +38 -40
- package/dist/index.js +43 -56
- package/dist/jiff/apply.d.ts +93 -0
- package/dist/jiff/apply.js +64 -0
- package/dist/jiff/extract.d.ts +7 -0
- package/dist/jiff/extract.js +82 -0
- package/dist/jiff/types.d.ts +57 -0
- package/dist/jiff/types.js +1 -0
- package/dist/lens.d.ts +20 -31
- package/dist/lens.js +22 -37
- package/dist/msgpack.d.ts +11 -26
- package/dist/msgpack.js +9 -21
- package/dist/mutate.d.ts +70 -0
- package/dist/mutate.js +130 -0
- package/dist/omitter.d.ts +57 -34
- package/dist/omitter.js +38 -30
- package/dist/path.d.ts +20 -1
- package/dist/path.js +21 -2
- package/dist/phymath/format.d.ts +60 -0
- package/dist/phymath/format.js +34 -0
- package/dist/phymath/index.d.ts +30 -30
- package/dist/phymath/index.js +41 -33
- package/dist/promoter.d.ts +23 -12
- package/dist/promoter.js +24 -17
- package/dist/random.d.ts +20 -21
- package/dist/random.js +22 -23
- package/dist/rubles.d.ts +24 -0
- package/dist/rubles.js +24 -0
- package/dist/script.d.ts +60 -13
- package/dist/script.js +46 -10
- package/dist/string.d.ts +46 -92
- package/dist/string.js +46 -171
- package/dist/types.d.ts +144 -25
- package/dist/url/index.d.ts +12 -0
- package/dist/url/index.js +17 -0
- package/dist/url/params.d.ts +141 -0
- package/dist/{url.js → url/params.js} +90 -18
- package/dist/url/slug.d.ts +28 -0
- package/dist/url/slug.js +102 -0
- package/dist/veil.d.ts +14 -0
- package/dist/veil.js +26 -0
- package/dist/xod.d.ts +237 -16
- package/dist/xod.js +192 -18
- package/dist/zipper.d.ts +22 -4
- package/dist/zipper.js +22 -5
- package/package.json +82 -34
- package/dist/async/space.d.ts +0 -7
- package/dist/async/space.js +0 -31
- package/dist/cleanup.d.ts +0 -9
- package/dist/cleanup.js +0 -18
- package/dist/colors.d.ts +0 -539
- package/dist/colors.js +0 -888
- package/dist/cookie.d.ts +0 -60
- package/dist/cookie.js +0 -48
- package/dist/datetime.d.ts +0 -82
- package/dist/datetime.js +0 -161
- package/dist/format.d.ts +0 -36
- package/dist/format.js +0 -26
- package/dist/future.d.ts +0 -50
- package/dist/future.js +0 -59
- package/dist/html.d.ts +0 -145
- package/dist/html.js +0 -205
- package/dist/humanly.d.ts +0 -9
- package/dist/humanly.js +0 -93
- package/dist/lru.d.ts +0 -77
- package/dist/lru.js +0 -128
- package/dist/queue.d.ts +0 -39
- package/dist/queue.js +0 -54
- package/dist/url.d.ts +0 -61
package/dist/mutate.js
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { isObject, isSameType } from "./index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Рекурсивно модифицирует объект, приводя его структуру к виду целевого объекта.
|
|
4
|
+
* Использует внутри {@link deepMutateArray}
|
|
5
|
+
*
|
|
6
|
+
* Удаляет лишние свойства, обновляет существующие и добавляет новые.
|
|
7
|
+
* Работает **мутативно** — изменяет исходный объект напрямую
|
|
8
|
+
*
|
|
9
|
+
* @remarks **НЕ** предназначен для работы с декларативными методами (могут потерять `this`)
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const source = { a: 1, b: 2, c: 3 };
|
|
14
|
+
* const target = { a: 10, d: 40 };
|
|
15
|
+
*
|
|
16
|
+
* deepMutateObject(source, target);
|
|
17
|
+
* // source теперь: { a: 10, d: 40 }
|
|
18
|
+
* // свойства b и c удалены, a обновлено, d добавлено
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export const deepMutateObject = (source, target) => {
|
|
22
|
+
// Удаление лишних свойств
|
|
23
|
+
Object.keys(source).forEach((key) => {
|
|
24
|
+
if (!(key in target))
|
|
25
|
+
delete source[key];
|
|
26
|
+
});
|
|
27
|
+
// Обновление свойств
|
|
28
|
+
Object.entries(target).forEach(([key, targetValue]) => {
|
|
29
|
+
const sourceValue = source[key];
|
|
30
|
+
// Проверка изменения типа данных
|
|
31
|
+
if (!isSameType(sourceValue, targetValue)) {
|
|
32
|
+
source[key] = targetValue; // Полная замена при разном типе
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (Array.isArray(targetValue)) {
|
|
36
|
+
if (!Array.isArray(sourceValue))
|
|
37
|
+
source[key] = [];
|
|
38
|
+
deepMutateArray(source[key], targetValue);
|
|
39
|
+
}
|
|
40
|
+
else if (isObject(targetValue)) {
|
|
41
|
+
if (!isObject(sourceValue))
|
|
42
|
+
source[key] = {};
|
|
43
|
+
deepMutateObject(source[key], targetValue);
|
|
44
|
+
}
|
|
45
|
+
else if (sourceValue !== targetValue) {
|
|
46
|
+
source[key] = targetValue;
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Рекурсивно модифицирует массив, приводя его к виду целевого массива.
|
|
52
|
+
* Использует внутри {@link deepMutateObject}
|
|
53
|
+
*
|
|
54
|
+
* Обрезает лишние элементы, обновляет существующие и добавляет новые.
|
|
55
|
+
* Работает **мутативно** — изменяет исходный массив напрямую
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* const complexSource = [
|
|
60
|
+
* { id: 1, name: "John" },
|
|
61
|
+
* { id: 2, name: "Jane" }
|
|
62
|
+
* ];
|
|
63
|
+
* const complexTarget = [
|
|
64
|
+
* { id: 1, name: "Johnny" },
|
|
65
|
+
* { id: 3, name: "Bob" }
|
|
66
|
+
* ];
|
|
67
|
+
*
|
|
68
|
+
* deepMutateArray(complexSource, complexTarget);
|
|
69
|
+
*
|
|
70
|
+
* // complexSource теперь: [
|
|
71
|
+
* // { id: 1, name: "Johnny" },
|
|
72
|
+
* // { id: 3, name: "Bob" }
|
|
73
|
+
* // ]
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
export const deepMutateArray = (source, target) => {
|
|
77
|
+
// Обрезка длины массива
|
|
78
|
+
if (source.length > target.length) {
|
|
79
|
+
source.splice(target.length, source.length - target.length);
|
|
80
|
+
}
|
|
81
|
+
// Обновление элементов
|
|
82
|
+
target.forEach((targetItem, index) => {
|
|
83
|
+
const sourceItem = source[index];
|
|
84
|
+
if (Array.isArray(targetItem)) {
|
|
85
|
+
if (!Array.isArray(sourceItem))
|
|
86
|
+
source[index] = [];
|
|
87
|
+
deepMutateArray(source[index], targetItem);
|
|
88
|
+
}
|
|
89
|
+
else if (isObject(targetItem)) {
|
|
90
|
+
if (!isObject(sourceItem))
|
|
91
|
+
source[index] = {};
|
|
92
|
+
deepMutateObject(source[index], targetItem);
|
|
93
|
+
}
|
|
94
|
+
else if (sourceItem !== targetItem) {
|
|
95
|
+
source[index] = targetItem;
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
// Добавление новых элементов
|
|
99
|
+
while (source.length < target.length) {
|
|
100
|
+
source.push(target[source.length]);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* Заменяет метод объекта обёрткой, передающей управление указанной функции
|
|
105
|
+
*
|
|
106
|
+
* Обёртка предоставляет контекст с оригинальным объектом, прокси-методом через {@link Reflect.apply} для вызова
|
|
107
|
+
* исходной реализации и аргументами вызова
|
|
108
|
+
*
|
|
109
|
+
* @param self - Объект, метод которого будет заменён
|
|
110
|
+
* @param key - Ключ метода в объекте
|
|
111
|
+
* @param func - Функция-обработчик, получающая контекст вызова
|
|
112
|
+
* @param [dynamic=false] - Использовать связывание `this` при вызове, что позволяет переносить цепочки на другие объекты
|
|
113
|
+
*
|
|
114
|
+
* @throws {TypeError} Если `self[key]` не является функцией
|
|
115
|
+
*/
|
|
116
|
+
export const inject = (self, key, func, dynamic = false) => {
|
|
117
|
+
const original = self[key];
|
|
118
|
+
if (dynamic) {
|
|
119
|
+
// динамический this
|
|
120
|
+
self[key] = function (...args) {
|
|
121
|
+
const method = (...args) => Reflect.apply(original, this, args);
|
|
122
|
+
return func({ self: this, method, args });
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
// статический (захват self и original на момент вызова)
|
|
127
|
+
const method = (...args) => Reflect.apply(original, self, args);
|
|
128
|
+
self[key] = ((...args) => func({ self, method, args }));
|
|
129
|
+
}
|
|
130
|
+
};
|
package/dist/omitter.d.ts
CHANGED
|
@@ -1,72 +1,88 @@
|
|
|
1
1
|
import type { DeepPartial, KEYS } from "./types.js";
|
|
2
2
|
import type { ZIP } from "./zipper.js";
|
|
3
3
|
/**
|
|
4
|
-
* Исключает ключи из объекта `Source`, которые присутствуют в объекте `Target
|
|
5
|
-
*
|
|
4
|
+
* Исключает ключи из объекта `Source`, которые присутствуют в объекте `Target`
|
|
5
|
+
*
|
|
6
|
+
* Если значение ключа в `Source` и `Target` является объектом, рекурсивно применяет себя к этим объектам
|
|
7
|
+
*
|
|
8
|
+
* @remarks Криво работает с функциональными методами и **НЕ** имеет защиты от бесконечных рекурсий
|
|
6
9
|
*
|
|
7
10
|
* @template Source - Исходный объект, из которого нужно исключить ключи
|
|
8
11
|
* @template Target - Объект, ключи которого нужно исключить из `Source`
|
|
9
12
|
*
|
|
10
13
|
* @example
|
|
11
|
-
*
|
|
12
|
-
* type
|
|
13
|
-
* type
|
|
14
|
+
* ```typescript
|
|
15
|
+
* type Source = { a: number; b: { c: string; d: boolean }; e: string }
|
|
16
|
+
* type Target = { b: { c: string }; e: string }
|
|
17
|
+
* type Result = ExtractOmitSchema<Source, Target> // { a: number; b: { d: boolean } }
|
|
18
|
+
* ```
|
|
14
19
|
*/
|
|
15
20
|
export type ExtractOmitSchema<Source, Target extends DeepPartial<Source>> = {
|
|
16
21
|
[K in keyof Source as K extends keyof Target ? Source[K] extends Record<string, unknown> ? Target[K] extends Record<string, unknown> ? K : never : never : K]: K extends keyof Target ? Source[K] extends Record<string, unknown> ? Target[K] extends Record<string, unknown> & DeepPartial<Source[K]> ? ExtractOmitSchema<Source[K], Target[K]> : never : never : null;
|
|
17
22
|
};
|
|
18
23
|
/**
|
|
19
|
-
* Вычисляет тип Target на основе исходного типа Source и схемы удаления OmitSchema
|
|
24
|
+
* Вычисляет тип Target на основе исходного типа Source и схемы удаления OmitSchema
|
|
25
|
+
*
|
|
20
26
|
* Удаляет ключи, помеченные в схеме как null, и рекурсивно обрабатывает вложенные объекты
|
|
21
27
|
*
|
|
28
|
+
* @remarks Криво работает с функциональными методами и **НЕ** имеет защиты от бесконечных рекурсий
|
|
29
|
+
*
|
|
30
|
+
* @template Source - Исходный тип объекта
|
|
31
|
+
* @template OmitSchema - Схема удаления ключей
|
|
32
|
+
*
|
|
22
33
|
* @example
|
|
23
|
-
*
|
|
24
|
-
* type
|
|
25
|
-
* type
|
|
34
|
+
* ```typescript
|
|
35
|
+
* type Source = { a: number; b: { c: string; d: boolean }; e: string }
|
|
36
|
+
* type OmitSchema = { a: null; b: { c: null } }
|
|
37
|
+
* type Result = ExtractOmitTarget<Source, OmitSchema> // { b: { d: boolean }; e: string }
|
|
38
|
+
* ```
|
|
26
39
|
*/
|
|
27
40
|
export type ExtractOmitTarget<Source, OmitSchema> = {
|
|
28
41
|
[K in keyof Source as K extends keyof OmitSchema ? (OmitSchema[K] extends Record<string, unknown> ? K : never) : K]: K extends keyof OmitSchema ? OmitSchema[K] extends Record<string, unknown> ? ExtractOmitTarget<Source[K], OmitSchema[K]> : never : Source[K];
|
|
29
42
|
};
|
|
30
43
|
/**
|
|
31
|
-
* Рекурсивно объединяет две схемы удаления
|
|
44
|
+
* Рекурсивно объединяет две схемы удаления ключей
|
|
45
|
+
*
|
|
32
46
|
* Если ключ присутствует в обеих схемах:
|
|
33
47
|
* - Если оба значения являются объектами — объединяет вложенные схемы
|
|
34
48
|
* - Если хотя бы одно значение null — результат null (приоритет удаления)
|
|
35
49
|
*
|
|
36
50
|
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* type SchemaA = { a: null; b: { c: null } }
|
|
53
|
+
* type SchemaB = { b: { d: null }; e: null }
|
|
54
|
+
* type MergedSchema = MergeOmitSchemas<SchemaA, SchemaB> // { a: null; b: { c: null; d: null }; e: null }
|
|
37
55
|
*
|
|
38
|
-
* type
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* type MergedSchema = MergeOmitSchemas<SchemaA, SchemaB>;
|
|
42
|
-
* // Результат: { a: null; b: { c: null; d: null }; e: null }
|
|
43
|
-
*
|
|
44
|
-
* type ConflictSchema = MergeOmitSchemas<
|
|
45
|
-
* { user: { name: null } },
|
|
46
|
-
* { user: null }
|
|
47
|
-
* >;
|
|
48
|
-
* // Результат: { user: null } (приоритет удаления)
|
|
56
|
+
* type ConflictSchema = MergeOmitSchemas<{ user: { name: null } }, { user: null }> // { user: null }
|
|
57
|
+
* ```
|
|
49
58
|
*/
|
|
50
59
|
export type MergeOmitSchemas<S1, S2> = {
|
|
51
60
|
[K in keyof (S1 & S2)]: K extends keyof S1 ? K extends keyof S2 ? S1[K] extends Record<string, unknown> ? S2[K] extends Record<string, unknown> ? MergeOmitSchemas<S1[K], S2[K]> : null : null : S1[K] : K extends keyof S2 ? S2[K] : never;
|
|
52
61
|
};
|
|
53
62
|
/**
|
|
54
|
-
*
|
|
63
|
+
* Очистка объектов от свойств на основе схемы
|
|
55
64
|
*
|
|
56
|
-
* @
|
|
65
|
+
* @remarks Мутирует исходный объект
|
|
66
|
+
*
|
|
67
|
+
* @template Source - Тип объектов, из которых нужно удалить ключи
|
|
57
68
|
* @template OmitSchema - Схема удаления
|
|
58
69
|
*
|
|
59
70
|
* @example
|
|
60
|
-
*
|
|
61
|
-
* const
|
|
62
|
-
* const
|
|
63
|
-
* const
|
|
71
|
+
* ```typescript
|
|
72
|
+
* const source = { a: 1, b: { c: 2, d: 3 }, e: 4 }
|
|
73
|
+
* const schema = { b: { c: null } }
|
|
74
|
+
* const omitter = new Omitter(schema)
|
|
75
|
+
* const result = omitter.apply(source) // { a: 1, b: { d: 3 }, e: 4 }
|
|
76
|
+
* ```
|
|
64
77
|
*/
|
|
65
78
|
export declare class Omitter<Source, OmitSchema> {
|
|
66
79
|
#private;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
80
|
+
__structure: {
|
|
81
|
+
keys: Set<KEYS<OmitSchema>>;
|
|
82
|
+
nested: Map<KEYS<OmitSchema>, Omitter<any, any>>;
|
|
83
|
+
};
|
|
84
|
+
schema: OmitSchema;
|
|
85
|
+
zip: ZIP;
|
|
70
86
|
constructor(schema: OmitSchema);
|
|
71
87
|
/**
|
|
72
88
|
* Получение хэша вложенного эмиттера
|
|
@@ -77,10 +93,17 @@ export declare class Omitter<Source, OmitSchema> {
|
|
|
77
93
|
*/
|
|
78
94
|
left(key: KEYS<Source>): boolean;
|
|
79
95
|
/**
|
|
80
|
-
* Удаление ключей из объекта
|
|
96
|
+
* Удаление ключей из объекта по внутренней структуры
|
|
97
|
+
*
|
|
98
|
+
* @remarks Мутирует исходный объект
|
|
81
99
|
*
|
|
82
|
-
* @
|
|
83
|
-
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```typescript
|
|
102
|
+
* const source = { a: 1, b: { c: 2, d: 3 }, e: 4 }
|
|
103
|
+
* const schema = { b: { c: null } }
|
|
104
|
+
* const omitter = new Omitter(schema)
|
|
105
|
+
* const result = omitter.apply(source) // { a: 1, b: { d: 3 }, e: 4 }
|
|
106
|
+
* ```
|
|
84
107
|
*/
|
|
85
|
-
|
|
108
|
+
apply(source: Source): ExtractOmitTarget<Source, OmitSchema>;
|
|
86
109
|
}
|
package/dist/omitter.js
CHANGED
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
import { zipper } from "./zipper.js";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Очистка объектов от свойств на основе схемы
|
|
4
4
|
*
|
|
5
|
-
* @
|
|
5
|
+
* @remarks Мутирует исходный объект
|
|
6
|
+
*
|
|
7
|
+
* @template Source - Тип объектов, из которых нужно удалить ключи
|
|
6
8
|
* @template OmitSchema - Схема удаления
|
|
7
9
|
*
|
|
8
10
|
* @example
|
|
9
|
-
*
|
|
10
|
-
* const
|
|
11
|
-
* const
|
|
12
|
-
* const
|
|
11
|
+
* ```typescript
|
|
12
|
+
* const source = { a: 1, b: { c: 2, d: 3 }, e: 4 }
|
|
13
|
+
* const schema = { b: { c: null } }
|
|
14
|
+
* const omitter = new Omitter(schema)
|
|
15
|
+
* const result = omitter.apply(source) // { a: 1, b: { d: 3 }, e: 4 }
|
|
16
|
+
* ```
|
|
13
17
|
*/
|
|
14
18
|
export class Omitter {
|
|
15
|
-
|
|
19
|
+
__structure;
|
|
16
20
|
schema;
|
|
17
21
|
zip;
|
|
18
22
|
constructor(schema) {
|
|
@@ -27,25 +31,10 @@ export class Omitter {
|
|
|
27
31
|
}
|
|
28
32
|
return true;
|
|
29
33
|
}));
|
|
30
|
-
this.
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Получение хэша вложенного эмиттера
|
|
34
|
-
*/
|
|
35
|
-
into(key) {
|
|
36
|
-
return this.structure.nested.get(key)?.zip;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Проверяет, останется ли ключ в итоговом объекте
|
|
40
|
-
*/
|
|
41
|
-
left(key) {
|
|
42
|
-
return !this.structure.keys.has(key);
|
|
34
|
+
this.__structure = { keys, nested };
|
|
43
35
|
}
|
|
44
36
|
/**
|
|
45
37
|
* Рекурсивно удаляет ключи из объекта на основе структуры
|
|
46
|
-
*
|
|
47
|
-
* @param obj - Объект, из которого нужно удалить ключи
|
|
48
|
-
* @param structure - Структура, определяющая ключи для удаления
|
|
49
38
|
*/
|
|
50
39
|
#process(obj, structure) {
|
|
51
40
|
const schema = structure.keys.size + structure.nested.size;
|
|
@@ -58,7 +47,7 @@ export class Omitter {
|
|
|
58
47
|
structure.nested.forEach((omitter, key) => {
|
|
59
48
|
const nested = obj[key];
|
|
60
49
|
if (nested && typeof nested === "object")
|
|
61
|
-
omitter.#process(nested, omitter.
|
|
50
|
+
omitter.#process(nested, omitter.__structure);
|
|
62
51
|
});
|
|
63
52
|
}
|
|
64
53
|
else {
|
|
@@ -72,7 +61,7 @@ export class Omitter {
|
|
|
72
61
|
if (omitter) {
|
|
73
62
|
const nested = obj[key];
|
|
74
63
|
if (nested && typeof nested === "object") {
|
|
75
|
-
omitter.#process(nested, omitter.
|
|
64
|
+
omitter.#process(nested, omitter.__structure);
|
|
76
65
|
}
|
|
77
66
|
}
|
|
78
67
|
}
|
|
@@ -80,13 +69,32 @@ export class Omitter {
|
|
|
80
69
|
}
|
|
81
70
|
}
|
|
82
71
|
/**
|
|
83
|
-
*
|
|
72
|
+
* Получение хэша вложенного эмиттера
|
|
73
|
+
*/
|
|
74
|
+
into(key) {
|
|
75
|
+
return this.__structure.nested.get(key)?.zip;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Проверяет, останется ли ключ в итоговом объекте
|
|
79
|
+
*/
|
|
80
|
+
left(key) {
|
|
81
|
+
return !this.__structure.keys.has(key);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Удаление ключей из объекта по внутренней структуры
|
|
85
|
+
*
|
|
86
|
+
* @remarks Мутирует исходный объект
|
|
84
87
|
*
|
|
85
|
-
* @
|
|
86
|
-
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```typescript
|
|
90
|
+
* const source = { a: 1, b: { c: 2, d: 3 }, e: 4 }
|
|
91
|
+
* const schema = { b: { c: null } }
|
|
92
|
+
* const omitter = new Omitter(schema)
|
|
93
|
+
* const result = omitter.apply(source) // { a: 1, b: { d: 3 }, e: 4 }
|
|
94
|
+
* ```
|
|
87
95
|
*/
|
|
88
|
-
|
|
89
|
-
this.#process(source, this.
|
|
96
|
+
apply(source) {
|
|
97
|
+
this.#process(source, this.__structure);
|
|
90
98
|
return source;
|
|
91
99
|
}
|
|
92
100
|
}
|
package/dist/path.d.ts
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Преобразует путь в Unix-формат, заменяя все разделители на прямые слэши
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```typescript
|
|
6
|
+
* toUnixPath("C:\\Users\\Project"); // "C:/Users/Project"
|
|
7
|
+
* toUnixPath("src\\components\\file.ts"); // "src/components/file.ts"
|
|
8
|
+
* ```
|
|
9
|
+
*/
|
|
2
10
|
export declare const toUnixPath: (path: string) => string;
|
|
11
|
+
/**
|
|
12
|
+
* Проверяет, является ли один путь дочерним {@link String.startsWith} по отношению к другому.
|
|
13
|
+
* Использует {@link toUnixPath} для нормализации путей
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* isChildPath("/home/user", "\\home\\user\\project"); // true
|
|
18
|
+
* isChildPath("src", "src/components/file.ts"); // true
|
|
19
|
+
* isChildPath("/home/user", "/home/other"); // false
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
3
22
|
export declare const isChildPath: (parentPath: string, childPath: string) => boolean;
|
package/dist/path.js
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Преобразует путь в Unix-формат, заменяя все разделители на прямые слэши
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```typescript
|
|
6
|
+
* toUnixPath("C:\\Users\\Project"); // "C:/Users/Project"
|
|
7
|
+
* toUnixPath("src\\components\\file.ts"); // "src/components/file.ts"
|
|
8
|
+
* ```
|
|
9
|
+
*/
|
|
10
|
+
export const toUnixPath = (path) => path.replaceAll("\\", "/");
|
|
11
|
+
/**
|
|
12
|
+
* Проверяет, является ли один путь дочерним {@link String.startsWith} по отношению к другому.
|
|
13
|
+
* Использует {@link toUnixPath} для нормализации путей
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* isChildPath("/home/user", "\\home\\user\\project"); // true
|
|
18
|
+
* isChildPath("src", "src/components/file.ts"); // true
|
|
19
|
+
* isChildPath("/home/user", "/home/other"); // false
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
3
22
|
export const isChildPath = (parentPath, childPath) => {
|
|
4
23
|
const uChildPath = toUnixPath(childPath);
|
|
5
24
|
const nParentPath = toUnixPath(parentPath) + "/";
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { CanBeNullable } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Стратегии обработки нуля в {@link toNumberFormat}:
|
|
4
|
+
* - "always" - "0" для всех исключительных ситуаций
|
|
5
|
+
* - "value" - "0" только при значении равном нулю, иначе `fallback`
|
|
6
|
+
* - "never" - `fallback` всегда
|
|
7
|
+
*/
|
|
8
|
+
export type NumberFormatZeroStrategy = "always" | "value" | "never";
|
|
9
|
+
/**
|
|
10
|
+
* Конфигурация вывода из {@link toNumberFormat}
|
|
11
|
+
*/
|
|
12
|
+
export interface NumberFormatConfig {
|
|
13
|
+
/**
|
|
14
|
+
* Количество знаков после запятой
|
|
15
|
+
*/
|
|
16
|
+
fraction?: number;
|
|
17
|
+
/**
|
|
18
|
+
* Значение для исключительных ситуаций
|
|
19
|
+
*
|
|
20
|
+
* @see {@link NumberFormatZeroStrategy}
|
|
21
|
+
*/
|
|
22
|
+
fallback?: string;
|
|
23
|
+
/**
|
|
24
|
+
* @example "₽"
|
|
25
|
+
*/
|
|
26
|
+
postfix?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Стратегия обработки нуля
|
|
29
|
+
*/
|
|
30
|
+
zero?: NumberFormatZeroStrategy;
|
|
31
|
+
/**
|
|
32
|
+
* Разделитель дробной части
|
|
33
|
+
*/
|
|
34
|
+
fractional?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Разделитель тысяч
|
|
37
|
+
*/
|
|
38
|
+
separator?: string;
|
|
39
|
+
}
|
|
40
|
+
export declare const NumberFormatRegExp: RegExp;
|
|
41
|
+
/**
|
|
42
|
+
* Форматирование числа по тысячам
|
|
43
|
+
*
|
|
44
|
+
* @param value - Входное значение (число, строка, null, undefined)
|
|
45
|
+
* @param [config] - Конфигурация форматирования
|
|
46
|
+
* @param [config.fraction=2] - {@link NumberFormatConfig.fraction}
|
|
47
|
+
* @param [config.fallback="---"] - {@link NumberFormatConfig.fallback}
|
|
48
|
+
* @param [config.postfix=""] - {@link NumberFormatConfig.postfix}
|
|
49
|
+
* @param [config.zero="value"] - {@link NumberFormatConfig.zero}
|
|
50
|
+
* @param [config.fractional=","] - {@link NumberFormatConfig.fractional}
|
|
51
|
+
* @param [config.separator=" "] - {@link NumberFormatConfig.separator}
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```typescript
|
|
55
|
+
* toNumberFormat(1234); // "1 234"
|
|
56
|
+
* toNumberFormat(1234.5); // "1 234,50"
|
|
57
|
+
* toNumberFormat(1234.56); // "1 234,56"
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export declare const toNumberFormat: (value: CanBeNullable<number | string>, { fraction, fallback, zero, postfix, fractional, separator }?: NumberFormatConfig) => string;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { caseNumber } from "../cases.js";
|
|
2
|
+
import { round } from "./index.js";
|
|
3
|
+
export const NumberFormatRegExp = /\B(?=(\d{3})+(?!\d))/g;
|
|
4
|
+
/**
|
|
5
|
+
* Форматирование числа по тысячам
|
|
6
|
+
*
|
|
7
|
+
* @param value - Входное значение (число, строка, null, undefined)
|
|
8
|
+
* @param [config] - Конфигурация форматирования
|
|
9
|
+
* @param [config.fraction=2] - {@link NumberFormatConfig.fraction}
|
|
10
|
+
* @param [config.fallback="---"] - {@link NumberFormatConfig.fallback}
|
|
11
|
+
* @param [config.postfix=""] - {@link NumberFormatConfig.postfix}
|
|
12
|
+
* @param [config.zero="value"] - {@link NumberFormatConfig.zero}
|
|
13
|
+
* @param [config.fractional=","] - {@link NumberFormatConfig.fractional}
|
|
14
|
+
* @param [config.separator=" "] - {@link NumberFormatConfig.separator}
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* toNumberFormat(1234); // "1 234"
|
|
19
|
+
* toNumberFormat(1234.5); // "1 234,50"
|
|
20
|
+
* toNumberFormat(1234.56); // "1 234,56"
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export const toNumberFormat = (value, { fraction = 2, fallback = "---", zero = "value", postfix, fractional = ",", separator = " " } = {}) => caseNumber(value, (v) => {
|
|
24
|
+
if (v === undefined)
|
|
25
|
+
return zero === "always" ? (postfix ? "0 " + postfix : "0") : fallback;
|
|
26
|
+
if (v === 0)
|
|
27
|
+
return zero === "never" ? fallback : postfix ? "0 " + postfix : "0";
|
|
28
|
+
if (fraction === 0)
|
|
29
|
+
return Math.round(v).toString().replace(NumberFormatRegExp, separator);
|
|
30
|
+
const { 0: integer, 1: float = "" } = round(v, fraction).toString().split(".");
|
|
31
|
+
const result = integer.replace(NumberFormatRegExp, separator);
|
|
32
|
+
const formatted = float ? `${result}${fractional}${float}` : result;
|
|
33
|
+
return postfix ? formatted + " " + postfix : formatted;
|
|
34
|
+
});
|
package/dist/phymath/index.d.ts
CHANGED
|
@@ -1,56 +1,56 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Приведение
|
|
2
|
+
* Приведение -0 и +0 к обычному 0
|
|
3
|
+
*
|
|
4
|
+
* Если не 0, то вернётся исходное значение
|
|
3
5
|
*/
|
|
4
|
-
export declare const
|
|
6
|
+
export declare const normalizero: (value: number) => number;
|
|
7
|
+
export type RoundMethod = "up" | "down" | "math";
|
|
5
8
|
/**
|
|
6
9
|
* Округляет число до заданного количества знаков после запятой
|
|
7
10
|
*
|
|
8
|
-
* Если переданное значение является `NaN` возвращает 0
|
|
11
|
+
* Если переданное значение является `NaN` или 0, возвращает 0
|
|
9
12
|
*
|
|
10
|
-
* @param
|
|
11
|
-
* @param
|
|
12
|
-
* @
|
|
13
|
+
* @param value - Число для округления
|
|
14
|
+
* @param [fraction=2] - Количество знаков после запятой
|
|
15
|
+
* @param [method="math"] - Метод округления
|
|
13
16
|
*/
|
|
14
|
-
export declare const
|
|
17
|
+
export declare const round: (value: number, fraction?: number, method?: RoundMethod) => number;
|
|
15
18
|
/**
|
|
16
19
|
* Вычисляет сумму всех переданных аргументов
|
|
17
20
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* @param {...number} args - Числа для суммирования
|
|
21
|
-
* @returns {number} Округленная сумма переданных чисел (или 0)
|
|
21
|
+
* Для пустого массива возвращает 0
|
|
22
22
|
*/
|
|
23
23
|
export declare const sum: (...args: number[]) => number;
|
|
24
24
|
/**
|
|
25
25
|
* Вычисляет произведение всех переданных аргументов
|
|
26
26
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* @param {...number} args - Числа для перемножения.
|
|
30
|
-
* @returns {number} Округленное произведение переданных чисел (или 1)
|
|
27
|
+
* Для пустого массива возвращает 1
|
|
31
28
|
*/
|
|
32
29
|
export declare const mult: (...args: number[]) => number;
|
|
33
30
|
/**
|
|
34
31
|
* Ограничивает значение в заданном диапазоне [min, max]
|
|
35
32
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* @returns {number} Значение, ограниченное диапазоном [min, max]
|
|
33
|
+
* @example
|
|
34
|
+
* ```typescript
|
|
35
|
+
* clamp(5, 0, 10); // 5
|
|
36
|
+
* clamp(-5, 0, 10); // 0
|
|
37
|
+
* clamp(15, 0, 10); // 10
|
|
38
|
+
* ```
|
|
44
39
|
*/
|
|
45
|
-
export declare const clamp: (
|
|
46
|
-
|
|
40
|
+
export declare const clamp: (value: number, min: number, max: number) => number;
|
|
41
|
+
/**
|
|
42
|
+
* Преобразует градусы в радианы
|
|
43
|
+
*/
|
|
44
|
+
export declare const toRadians: (degrees: number) => number;
|
|
45
|
+
/**
|
|
46
|
+
* Преобразует радианы в градусы
|
|
47
|
+
*/
|
|
48
|
+
export declare const toDegrees: (radians: number) => number;
|
|
47
49
|
/**
|
|
48
50
|
* Линейная интерполяция между двумя числами
|
|
49
51
|
*
|
|
50
|
-
* @param
|
|
51
|
-
* @param
|
|
52
|
-
* @param
|
|
53
|
-
*
|
|
54
|
-
* @returns {number} Результат линейной интерполяции между a и b при коэффициенте t
|
|
52
|
+
* @param a - Начальное значение
|
|
53
|
+
* @param b - Конечное значение
|
|
54
|
+
* @param t - Весовой коэффициент, определяющий состояние пропорции между начальным и конечным значениями. Должно быть в диапазоне `[0, 1]`
|
|
55
55
|
*/
|
|
56
56
|
export declare const lerp: (a: number, b: number, t: number) => number;
|