@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
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { createValuePluralizer } from "../index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Склонение слова "секунда" в зависимости от числа
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```typescript
|
|
7
|
+
* pluralSeconds(1); // "секунда"
|
|
8
|
+
* pluralSeconds(3); // "секунды"
|
|
9
|
+
* pluralSeconds(155); // "секунд"
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
export const pluralSeconds = createValuePluralizer("секунда", "секунды", "секунд");
|
|
13
|
+
/**
|
|
14
|
+
* Склонение слова "минута" в зависимости от числа
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* pluralMinutes(1); // "минута"
|
|
19
|
+
* pluralMinutes(3); // "минуты"
|
|
20
|
+
* pluralMinutes(155); // "минут"
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export const pluralMinutes = createValuePluralizer("минута", "минуты", "минут");
|
|
24
|
+
/**
|
|
25
|
+
* Склонение слова "час" в зависимости от числа
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* pluralHours(1); // "час"
|
|
30
|
+
* pluralHours(3); // "часа"
|
|
31
|
+
* pluralHours(155); // "часов"
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export const pluralHours = createValuePluralizer("час", "часа", "часов");
|
|
35
|
+
/**
|
|
36
|
+
* Склонение слова "день" в зависимости от числа
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* pluralDays(1); // "день"
|
|
41
|
+
* pluralDays(3); // "дня"
|
|
42
|
+
* pluralDays(155); // "дней"
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export const pluralDays = createValuePluralizer("день", "дня", "дней");
|
|
46
|
+
/**
|
|
47
|
+
* Склонение слова "неделя" в зависимости от числа
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```typescript
|
|
51
|
+
* pluralWeeks(1); // "неделя"
|
|
52
|
+
* pluralWeeks(3); // "недели"
|
|
53
|
+
* pluralWeeks(155); // "недель"
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export const pluralWeeks = createValuePluralizer("неделя", "недели", "недель");
|
|
57
|
+
/**
|
|
58
|
+
* Склонение слова "месяц" в зависимости от числа
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```typescript
|
|
62
|
+
* pluralMonths(1); // "месяц"
|
|
63
|
+
* pluralMonths(3); // "месяца"
|
|
64
|
+
* pluralMonths(155); // "месяцев"
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export const pluralMonths = createValuePluralizer("месяц", "месяца", "месяцев");
|
|
68
|
+
/**
|
|
69
|
+
* Склонение слова "год" в зависимости от числа
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```typescript
|
|
73
|
+
* pluralYears(1); // "год"
|
|
74
|
+
* pluralYears(3); // "года"
|
|
75
|
+
* pluralYears(155); // "лет"
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
export const pluralYears = createValuePluralizer("год", "года", "лет");
|
package/dist/emitter.d.ts
CHANGED
|
@@ -1,28 +1,40 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { RID } from "./types.js";
|
|
1
|
+
import type { KEYS, RID } from "./types.js";
|
|
3
2
|
/**
|
|
4
|
-
*
|
|
5
|
-
* Позволяет подписываться на события, уведомлять и удалять обработчики
|
|
3
|
+
* Реализует простую систему событийного взаимодействия
|
|
6
4
|
*
|
|
7
|
-
* @template
|
|
5
|
+
* @template Schema - Схема событий вида `{ [key]: data }`
|
|
8
6
|
*/
|
|
9
|
-
export declare class Emitter<
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
dispatch<K extends keyof Events>(target: K, data: Events[K]): void;
|
|
7
|
+
export declare class Emitter<Schema extends object> {
|
|
8
|
+
__listeners: Map<RID, {
|
|
9
|
+
event: KEYS<Schema>;
|
|
10
|
+
callback: (data: Schema[KEYS<Schema>]) => void;
|
|
11
|
+
once?: boolean;
|
|
12
|
+
}>;
|
|
13
|
+
dispatch<K extends KEYS<Schema>>(event: K, data: Schema[K]): void;
|
|
17
14
|
/**
|
|
18
|
-
*
|
|
15
|
+
* @param event - Ключ события
|
|
16
|
+
* @param callback - Обработчик события
|
|
17
|
+
* @param [options] - Опции запуска
|
|
18
|
+
* @param [options.once] - Одноразовая подписка
|
|
19
|
+
* @param [options.key=Symbol()] - Ключ подписчика
|
|
20
|
+
*
|
|
21
|
+
* @returns - Функция для удаления обработчика
|
|
19
22
|
*/
|
|
20
|
-
on<K extends
|
|
23
|
+
on<K extends KEYS<Schema>>(event: K, callback: (data: Schema[K]) => void, options?: {
|
|
21
24
|
key?: RID;
|
|
22
25
|
once?: boolean;
|
|
23
26
|
}): () => void;
|
|
24
27
|
/**
|
|
25
|
-
*
|
|
28
|
+
* **Если ключ не указан, очищаются все**
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* // Удаление конкретного обработчика
|
|
33
|
+
* emitter.un("my-handler")
|
|
34
|
+
*
|
|
35
|
+
* // Очистка всех обработчиков
|
|
36
|
+
* emitter.un()
|
|
37
|
+
* ```
|
|
26
38
|
*/
|
|
27
|
-
un(key?: RID):
|
|
39
|
+
un(key?: RID): void;
|
|
28
40
|
}
|
package/dist/emitter.js
CHANGED
|
@@ -1,33 +1,47 @@
|
|
|
1
|
-
import { Promoter } from "./promoter.js";
|
|
2
1
|
/**
|
|
3
|
-
*
|
|
4
|
-
* Позволяет подписываться на события, уведомлять и удалять обработчики
|
|
2
|
+
* Реализует простую систему событийного взаимодействия
|
|
5
3
|
*
|
|
6
|
-
* @template
|
|
4
|
+
* @template Schema - Схема событий вида `{ [key]: data }`
|
|
7
5
|
*/
|
|
8
|
-
export class Emitter
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
export class Emitter {
|
|
7
|
+
__listeners = new Map();
|
|
8
|
+
dispatch(event, data) {
|
|
9
|
+
this.__listeners.forEach((handler, key) => {
|
|
10
|
+
if (event === handler.event)
|
|
11
|
+
handler.callback(data);
|
|
12
|
+
if (handler.once)
|
|
13
|
+
this.__listeners.delete(key);
|
|
14
|
+
});
|
|
14
15
|
}
|
|
15
16
|
/**
|
|
16
|
-
*
|
|
17
|
+
* @param event - Ключ события
|
|
18
|
+
* @param callback - Обработчик события
|
|
19
|
+
* @param [options] - Опции запуска
|
|
20
|
+
* @param [options.once] - Одноразовая подписка
|
|
21
|
+
* @param [options.key=Symbol()] - Ключ подписчика
|
|
22
|
+
*
|
|
23
|
+
* @returns - Функция для удаления обработчика
|
|
17
24
|
*/
|
|
18
|
-
on(event,
|
|
19
|
-
const { key = Symbol(), once } =
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
// @ts-expect-error <оно не может корректно сузить тип>
|
|
23
|
-
call(payload.data);
|
|
24
|
-
}
|
|
25
|
-
}, { key, once });
|
|
25
|
+
on(event, callback, options = {}) {
|
|
26
|
+
const { key = Symbol(), once } = options;
|
|
27
|
+
this.__listeners.set(key, { event, callback, once });
|
|
28
|
+
return () => this.__listeners.delete(key);
|
|
26
29
|
}
|
|
27
30
|
/**
|
|
28
|
-
*
|
|
31
|
+
* **Если ключ не указан, очищаются все**
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```typescript
|
|
35
|
+
* // Удаление конкретного обработчика
|
|
36
|
+
* emitter.un("my-handler")
|
|
37
|
+
*
|
|
38
|
+
* // Очистка всех обработчиков
|
|
39
|
+
* emitter.un()
|
|
40
|
+
* ```
|
|
29
41
|
*/
|
|
30
42
|
un(key) {
|
|
31
|
-
|
|
43
|
+
if (key)
|
|
44
|
+
return void this.__listeners.delete(key);
|
|
45
|
+
this.__listeners.clear();
|
|
32
46
|
}
|
|
33
47
|
}
|
package/dist/explorer.d.ts
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import type { PathLike, Stats } from "node:fs";
|
|
2
2
|
/**
|
|
3
|
-
* Проверяет существование пути
|
|
3
|
+
* @param path - Проверяет существование пути через {@link stat}
|
|
4
|
+
* @param [expected] - Ожидаемый тип: `"file"` (файл) или `"folder"` (директория)
|
|
5
|
+
* @param [strict=false] - Выбрасывает ошибку, если путь не существует
|
|
4
6
|
*
|
|
5
|
-
* @param path - Путь для проверки
|
|
6
|
-
* @param [expected] - Ожидаемый тип: `"file"` (файл) или `"folder"` (папка)
|
|
7
|
-
* @param [strict=false] - Если `true`, выбрасывает ошибку, если путь не существует
|
|
8
|
-
*
|
|
9
|
-
* @returns {@link Stats}, если путь существует и соответствует ожидаемому типу (если указан). Иначе возвращает `null`, если `strict = false`
|
|
10
7
|
* @throws {Error} Если `strict = true` и путь не существует или не соответствует ожидаемому типу
|
|
11
8
|
*/
|
|
12
9
|
declare function exists(path: PathLike, expected?: "file" | "folder", strict?: boolean): Promise<Stats | null>;
|
|
10
|
+
/**
|
|
11
|
+
* @param path - Проверяет существование пути через {@link stat}
|
|
12
|
+
* @param [expected] - Ожидаемый тип: `"file"` (файл) или `"folder"` (директория)
|
|
13
|
+
* @param strict - Выбрасывает ошибку, если путь не существует
|
|
14
|
+
*
|
|
15
|
+
* @throws {Error} Если путь не существует или не соответствует ожидаемому типу
|
|
16
|
+
*/
|
|
13
17
|
declare function exists(path: PathLike, expected: "file" | "folder" | undefined, strict: true): Promise<Stats>;
|
|
14
18
|
export { exists };
|
|
15
19
|
/**
|
|
@@ -17,37 +21,29 @@ export { exists };
|
|
|
17
21
|
*/
|
|
18
22
|
export interface RemoveOptions {
|
|
19
23
|
/**
|
|
20
|
-
* Если
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* @default false
|
|
24
|
+
* Если это была не пустая директория, бросит ошибку
|
|
25
|
+
* @remarks {@link RemoveOptions.expected} приводится к `"folder"`
|
|
24
26
|
*/
|
|
25
27
|
empty?: boolean;
|
|
26
28
|
/**
|
|
27
29
|
* Проверка перед удалением
|
|
28
|
-
*
|
|
29
|
-
* @default undefined
|
|
30
30
|
*/
|
|
31
31
|
expected?: "file" | "folder";
|
|
32
32
|
}
|
|
33
33
|
/**
|
|
34
34
|
* Удаляет файл или папку по указанному пути
|
|
35
35
|
*
|
|
36
|
-
* @
|
|
37
|
-
* @param options - Опции поведения {@link RemoveOptions}
|
|
36
|
+
* @returns {@link Stats} удалённого элемента или `null`, если он не существовал
|
|
38
37
|
*
|
|
39
|
-
* @
|
|
40
|
-
* @throws {Error} Если путь не существует или не соответствует ожидаемому типу
|
|
38
|
+
* @throws {Error} Если это была не пустая директория при {@link RemoveOptions.empty} или не соответствует ожидаемому типу {@link RemoveOptions.expected}
|
|
41
39
|
*/
|
|
42
40
|
export declare function remove(path: PathLike, options?: RemoveOptions): Promise<Stats | null>;
|
|
43
41
|
/**
|
|
44
|
-
* Опции для функции {@link remake}
|
|
42
|
+
* Опции поведения для функции {@link remake}
|
|
45
43
|
*/
|
|
46
44
|
export interface RemakeOptions {
|
|
47
45
|
/**
|
|
48
|
-
* Если
|
|
49
|
-
*
|
|
50
|
-
* @default false
|
|
46
|
+
* Если это была не пустая директория, бросит ошибку
|
|
51
47
|
*/
|
|
52
48
|
empty?: boolean;
|
|
53
49
|
/**
|
|
@@ -58,23 +54,20 @@ export interface RemakeOptions {
|
|
|
58
54
|
recursive?: boolean;
|
|
59
55
|
}
|
|
60
56
|
/**
|
|
61
|
-
* Удаляет (если существовала) и заново создаёт
|
|
57
|
+
* Удаляет (если существовала) и заново создаёт директорию по указанному пути
|
|
62
58
|
*
|
|
63
|
-
* @
|
|
64
|
-
* @param options - Опции поведения {@link RemakeOptions}
|
|
59
|
+
* @returns {@link Stats} удалённой директории или `null`, если она не существовала
|
|
65
60
|
*
|
|
66
|
-
* @
|
|
67
|
-
* @throws {Error} Если путь не существует или не является папкой
|
|
61
|
+
* @throws {Error} Если это была не пустая директория при {@link RemakeOptions.empty} или нет родительской папки при отключённом {@link RemakeOptions.recursive}
|
|
68
62
|
*/
|
|
69
|
-
export declare
|
|
63
|
+
export declare const remake: (path: PathLike, options?: RemakeOptions) => Promise<Stats | null>;
|
|
70
64
|
/**
|
|
71
65
|
* Сравнивает содержимое файла с ожидаемым значением
|
|
72
66
|
*
|
|
73
67
|
* @param path - Путь к файлу
|
|
74
68
|
* @param expected - Ожидаемое содержимое файла
|
|
75
|
-
* @param [strict=
|
|
69
|
+
* @param [strict=false] - Выбрасывает ошибку, если файл не существует
|
|
76
70
|
*
|
|
77
|
-
* @returns `true`, если содержимое файла совпадает с ожидаемым, иначе `false`
|
|
78
71
|
* @throws {Error} Если `strict = true` и файл не существует
|
|
79
72
|
*/
|
|
80
|
-
export declare
|
|
73
|
+
export declare const compare: (path: PathLike, expected: string, strict?: boolean) => Promise<boolean>;
|
package/dist/explorer.js
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import { mkdir, readdir, readFile, rm, stat } from "node:fs/promises";
|
|
2
|
+
/**
|
|
3
|
+
* @param path - Проверяет существование пути через {@link stat}
|
|
4
|
+
* @param [expected] - Ожидаемый тип: `"file"` (файл) или `"folder"` (директория)
|
|
5
|
+
* @param [strict=false] - Выбрасывает ошибку, если путь не существует
|
|
6
|
+
*
|
|
7
|
+
* @throws {Error} Если `strict = true` и путь не существует или не соответствует ожидаемому типу
|
|
8
|
+
*/
|
|
2
9
|
async function exists(path, expected, strict = false) {
|
|
3
10
|
let existed;
|
|
4
11
|
try {
|
|
@@ -22,11 +29,9 @@ export { exists };
|
|
|
22
29
|
/**
|
|
23
30
|
* Удаляет файл или папку по указанному пути
|
|
24
31
|
*
|
|
25
|
-
* @
|
|
26
|
-
* @param options - Опции поведения {@link RemoveOptions}
|
|
32
|
+
* @returns {@link Stats} удалённого элемента или `null`, если он не существовал
|
|
27
33
|
*
|
|
28
|
-
* @
|
|
29
|
-
* @throws {Error} Если путь не существует или не соответствует ожидаемому типу
|
|
34
|
+
* @throws {Error} Если это была не пустая директория при {@link RemoveOptions.empty} или не соответствует ожидаемому типу {@link RemoveOptions.expected}
|
|
30
35
|
*/
|
|
31
36
|
export async function remove(path, options = {}) {
|
|
32
37
|
const { empty = false, expected } = options;
|
|
@@ -37,7 +42,7 @@ export async function remove(path, options = {}) {
|
|
|
37
42
|
return null;
|
|
38
43
|
const entries = await readdir(path, { withFileTypes: true });
|
|
39
44
|
if (entries.length > 0) {
|
|
40
|
-
throw new Error(`Ожидалось, что
|
|
45
|
+
throw new Error(`Ожидалось, что директория "${path}" будет пуста`);
|
|
41
46
|
}
|
|
42
47
|
}
|
|
43
48
|
else {
|
|
@@ -49,35 +54,32 @@ export async function remove(path, options = {}) {
|
|
|
49
54
|
return existed;
|
|
50
55
|
}
|
|
51
56
|
/**
|
|
52
|
-
* Удаляет (если существовала) и заново создаёт
|
|
57
|
+
* Удаляет (если существовала) и заново создаёт директорию по указанному пути
|
|
53
58
|
*
|
|
54
|
-
* @
|
|
55
|
-
* @param options - Опции поведения {@link RemakeOptions}
|
|
59
|
+
* @returns {@link Stats} удалённой директории или `null`, если она не существовала
|
|
56
60
|
*
|
|
57
|
-
* @
|
|
58
|
-
* @throws {Error} Если путь не существует или не является папкой
|
|
61
|
+
* @throws {Error} Если это была не пустая директория при {@link RemakeOptions.empty} или нет родительской папки при отключённом {@link RemakeOptions.recursive}
|
|
59
62
|
*/
|
|
60
|
-
export async
|
|
63
|
+
export const remake = async (path, options = {}) => {
|
|
61
64
|
const { empty = false, recursive = true } = options;
|
|
62
65
|
const existed = await remove(path, { empty, expected: "folder" });
|
|
63
66
|
await mkdir(path, { recursive });
|
|
64
67
|
return existed;
|
|
65
|
-
}
|
|
68
|
+
};
|
|
66
69
|
//...
|
|
67
70
|
/**
|
|
68
71
|
* Сравнивает содержимое файла с ожидаемым значением
|
|
69
72
|
*
|
|
70
73
|
* @param path - Путь к файлу
|
|
71
74
|
* @param expected - Ожидаемое содержимое файла
|
|
72
|
-
* @param [strict=
|
|
75
|
+
* @param [strict=false] - Выбрасывает ошибку, если файл не существует
|
|
73
76
|
*
|
|
74
|
-
* @returns `true`, если содержимое файла совпадает с ожидаемым, иначе `false`
|
|
75
77
|
* @throws {Error} Если `strict = true` и файл не существует
|
|
76
78
|
*/
|
|
77
|
-
export async
|
|
79
|
+
export const compare = async (path, expected, strict = false) => {
|
|
78
80
|
const existed = await exists(path, "file", strict);
|
|
79
81
|
if (!existed)
|
|
80
82
|
return false;
|
|
81
83
|
const content = await readFile(path, "utf-8");
|
|
82
84
|
return content === expected;
|
|
83
|
-
}
|
|
85
|
+
};
|
package/dist/files.d.ts
CHANGED
|
@@ -1,8 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Конвертирует файл в строку base64 используя {@link FileReader.readAsDataURL}
|
|
3
|
+
*
|
|
4
|
+
* @throws {Error} Если чтение файла завершается с ошибкой
|
|
5
|
+
*/
|
|
1
6
|
export declare const fileToBase64: (file: File) => Promise<string>;
|
|
2
7
|
/**
|
|
3
|
-
* Проверяет, является ли файл изображением.
|
|
8
|
+
* Проверяет, является ли файл изображением.
|
|
9
|
+
* SVG данную проверку не проходят
|
|
4
10
|
*/
|
|
5
11
|
export declare const isImage: (file: File) => boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Проверяет, является ли файл видео
|
|
14
|
+
*/
|
|
6
15
|
export declare const isVideo: (file: File) => boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Проверяет, является ли файл аудио
|
|
18
|
+
*/
|
|
7
19
|
export declare const isAudio: (file: File) => boolean;
|
|
8
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Словарь степеней байтов для {@link getFileSize}
|
|
22
|
+
*/
|
|
23
|
+
export declare const BYTES_UNITS: string[];
|
|
24
|
+
/**
|
|
25
|
+
* Форматирует размер файла в читаемом виде
|
|
26
|
+
*
|
|
27
|
+
* @param size - Размер файла в байтах
|
|
28
|
+
* @param [dictionary=BYTES_UNITS] - Словарь степеней байтов
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* getFileSize(1024) // "1 kB"
|
|
33
|
+
* getFileSize(1048576) // "1 MB"
|
|
34
|
+
* getFileSize(500) // "500 B"
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare const getFileSize: (size: number, dictionary?: string[]) => string;
|
package/dist/files.js
CHANGED
|
@@ -1,18 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Конвертирует файл в строку base64 используя {@link FileReader.readAsDataURL}
|
|
3
|
+
*
|
|
4
|
+
* @throws {Error} Если чтение файла завершается с ошибкой
|
|
5
|
+
*/
|
|
1
6
|
export const fileToBase64 = (file) => new Promise((resolve, reject) => {
|
|
2
7
|
const reader = new FileReader();
|
|
3
8
|
reader.onload = () => resolve(reader.result);
|
|
4
9
|
reader.onerror = reject;
|
|
5
10
|
reader.readAsDataURL(file);
|
|
6
11
|
});
|
|
7
|
-
//...
|
|
8
12
|
/**
|
|
9
|
-
* Проверяет, является ли файл изображением.
|
|
13
|
+
* Проверяет, является ли файл изображением.
|
|
14
|
+
* SVG данную проверку не проходят
|
|
10
15
|
*/
|
|
11
16
|
export const isImage = (file) => file.type.startsWith("image/") && !file.type.includes("svg");
|
|
17
|
+
/**
|
|
18
|
+
* Проверяет, является ли файл видео
|
|
19
|
+
*/
|
|
12
20
|
export const isVideo = (file) => file.type.startsWith("video/");
|
|
21
|
+
/**
|
|
22
|
+
* Проверяет, является ли файл аудио
|
|
23
|
+
*/
|
|
13
24
|
export const isAudio = (file) => file.type.startsWith("audio/");
|
|
14
25
|
//...
|
|
15
|
-
|
|
26
|
+
/**
|
|
27
|
+
* Словарь степеней байтов для {@link getFileSize}
|
|
28
|
+
*/
|
|
29
|
+
export const BYTES_UNITS = [
|
|
16
30
|
"B",
|
|
17
31
|
"kB",
|
|
18
32
|
"MB",
|
|
@@ -23,13 +37,24 @@ const UNITS = [
|
|
|
23
37
|
"ZB",
|
|
24
38
|
"YB",
|
|
25
39
|
];
|
|
26
|
-
|
|
40
|
+
/**
|
|
41
|
+
* Форматирует размер файла в читаемом виде
|
|
42
|
+
*
|
|
43
|
+
* @param size - Размер файла в байтах
|
|
44
|
+
* @param [dictionary=BYTES_UNITS] - Словарь степеней байтов
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* getFileSize(1024) // "1 kB"
|
|
49
|
+
* getFileSize(1048576) // "1 MB"
|
|
50
|
+
* getFileSize(500) // "500 B"
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export const getFileSize = (size, dictionary = BYTES_UNITS) => {
|
|
27
54
|
const bytes = Math.round(size);
|
|
28
|
-
if (bytes === 0)
|
|
29
|
-
return "0 B";
|
|
30
55
|
if (bytes < 1000)
|
|
31
56
|
return bytes.toString() + " B";
|
|
32
|
-
const exponent = Math.min(Math.floor(Math.log10(bytes) / 3),
|
|
57
|
+
const exponent = Math.min(Math.floor(Math.log10(bytes) / 3), dictionary.length - 1);
|
|
33
58
|
const result = bytes / 1000 ** exponent;
|
|
34
|
-
return Math.round(result) + " " +
|
|
59
|
+
return Math.round(result) + " " + dictionary[exponent];
|
|
35
60
|
};
|
package/dist/fish.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { AnyFunc, Args, Dictionary, FuncCopy, Return } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Выполнение функции только один раз, после будет возвращать уже полученный ранее результат
|
|
4
|
+
*
|
|
5
|
+
* @throws {unknown} Если первый вызов будет с ошибкой, можно попровать ещё раз
|
|
6
|
+
*/
|
|
7
|
+
export declare const oncefish: <F extends AnyFunc>(func: F) => FuncCopy<F>;
|
|
8
|
+
/**
|
|
9
|
+
* Однократное выполнение асинхронной функции, после будет возвращать уже полученный ранее промисс
|
|
10
|
+
*
|
|
11
|
+
* @throws {unknown} Если первый вызов будет с ошибкой, можно попровать ещё раз
|
|
12
|
+
*/
|
|
13
|
+
export declare const profish: <T, A extends any[] = any[]>(func: (...args: A) => Promise<T>) => ((...args: A) => Promise<T>);
|
|
14
|
+
/**
|
|
15
|
+
* Оборачивает функцию так, чтобы она запоминала **только последний вызов**.
|
|
16
|
+
* При повторном аналогичном (согласно `strategy`) вызове возвращается сохранённый результат
|
|
17
|
+
*
|
|
18
|
+
* @throws {unknown} Если вызов `func` завершается ошибкой, новый результат не кэшируется, и ошибка пробрасывается
|
|
19
|
+
*/
|
|
20
|
+
export declare const goldfish: <F extends AnyFunc>(func: F, strategy: (curr: Args<F>, prev: Args<F>, result: Return<F>) => boolean) => FuncCopy<F>;
|
|
21
|
+
/**
|
|
22
|
+
* Оборачивает функцию так, чтобы она кэшировала результаты вызовов по ключу,
|
|
23
|
+
* полученному с помощью функции `serialize`
|
|
24
|
+
*
|
|
25
|
+
* Кэш хранится в обычной `Map`, ключи генерируются вызовом `serialize` от аргументов
|
|
26
|
+
*
|
|
27
|
+
* @throws {unknown} Если вызов `func` завершается ошибкой, результат не кэшируется, и ошибка пробрасывается
|
|
28
|
+
*/
|
|
29
|
+
export declare const memofish: <F extends AnyFunc, Cache extends Dictionary<any, Return<F>>>(func: F, serialize: (args: Args<F>, cache: Cache) => Args<Cache["get"]>[0], cache?: Cache) => FuncCopy<F>;
|
package/dist/fish.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Выполнение функции только один раз, после будет возвращать уже полученный ранее результат
|
|
3
|
+
*
|
|
4
|
+
* @throws {unknown} Если первый вызов будет с ошибкой, можно попровать ещё раз
|
|
5
|
+
*/
|
|
6
|
+
export const oncefish = (func) => {
|
|
7
|
+
let ready = false;
|
|
8
|
+
let result;
|
|
9
|
+
return (...args) => {
|
|
10
|
+
if (!ready) {
|
|
11
|
+
result = func(args);
|
|
12
|
+
ready = true;
|
|
13
|
+
}
|
|
14
|
+
return result;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Однократное выполнение асинхронной функции, после будет возвращать уже полученный ранее промисс
|
|
19
|
+
*
|
|
20
|
+
* @throws {unknown} Если первый вызов будет с ошибкой, можно попровать ещё раз
|
|
21
|
+
*/
|
|
22
|
+
export const profish = (func) => {
|
|
23
|
+
let promise;
|
|
24
|
+
return (...args) => {
|
|
25
|
+
if (!promise) {
|
|
26
|
+
promise = func(...args).catch((err) => {
|
|
27
|
+
promise = undefined;
|
|
28
|
+
throw err;
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
return promise;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Оборачивает функцию так, чтобы она запоминала **только последний вызов**.
|
|
36
|
+
* При повторном аналогичном (согласно `strategy`) вызове возвращается сохранённый результат
|
|
37
|
+
*
|
|
38
|
+
* @throws {unknown} Если вызов `func` завершается ошибкой, новый результат не кэшируется, и ошибка пробрасывается
|
|
39
|
+
*/
|
|
40
|
+
export const goldfish = (func, strategy) => {
|
|
41
|
+
let lastArgs;
|
|
42
|
+
let lastResult;
|
|
43
|
+
return (...args) => {
|
|
44
|
+
if (lastArgs && strategy(args, lastArgs, lastResult)) {
|
|
45
|
+
return lastResult;
|
|
46
|
+
}
|
|
47
|
+
lastResult = func(args);
|
|
48
|
+
lastArgs = args;
|
|
49
|
+
return lastResult;
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Оборачивает функцию так, чтобы она кэшировала результаты вызовов по ключу,
|
|
54
|
+
* полученному с помощью функции `serialize`
|
|
55
|
+
*
|
|
56
|
+
* Кэш хранится в обычной `Map`, ключи генерируются вызовом `serialize` от аргументов
|
|
57
|
+
*
|
|
58
|
+
* @throws {unknown} Если вызов `func` завершается ошибкой, результат не кэшируется, и ошибка пробрасывается
|
|
59
|
+
*/
|
|
60
|
+
export const memofish = (func, serialize, cache = new Map()) => {
|
|
61
|
+
return (...args) => {
|
|
62
|
+
const key = serialize(args, cache);
|
|
63
|
+
const existed = cache.get(key);
|
|
64
|
+
if (existed)
|
|
65
|
+
return existed;
|
|
66
|
+
const result = func(...args);
|
|
67
|
+
cache.set(key, result);
|
|
68
|
+
return result;
|
|
69
|
+
};
|
|
70
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Политика {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite SameSite} приватности кук для {@link setDocumentCookie}
|
|
3
|
+
*
|
|
4
|
+
* - Strict: Куки будут отправляться только при навигации внутри сайта
|
|
5
|
+
* - Lax: Куки доступны для навигации с одного сайта на другой (рекомендуется)
|
|
6
|
+
* - None: Куки доступны для всех запросов, требуется параметр Secure (для кросс-сайтовых запросов)
|
|
7
|
+
*/
|
|
8
|
+
export type CookieSameSite = "Strict" | "Lax" | "None";
|
|
9
|
+
/**
|
|
10
|
+
* Опции установки куки для {@link setDocumentCookie}
|
|
11
|
+
*/
|
|
12
|
+
export interface SetDocumentCookieOptions {
|
|
13
|
+
SameSite?: CookieSameSite;
|
|
14
|
+
/**
|
|
15
|
+
* Максимальное время жизни куки в секундах
|
|
16
|
+
*
|
|
17
|
+
* @remarks `MaxAge === null` делает хранение сессионным!
|
|
18
|
+
*/
|
|
19
|
+
MaxAge?: number | null;
|
|
20
|
+
/**
|
|
21
|
+
* Флаг, указывающий, что кука будет передаваться только по защищенному соединению (HTTPS)
|
|
22
|
+
*/
|
|
23
|
+
Secure?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Путь раздела, для которого кука существует при отправке на сервер
|
|
26
|
+
*/
|
|
27
|
+
Path?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Для установки куки, которая будет доступна на текущем домене и всех его поддоменах `.${window.location.hostname}`
|
|
30
|
+
*/
|
|
31
|
+
Domain?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* @param name - Имя куки
|
|
35
|
+
* @param value - Значение куки
|
|
36
|
+
* @param [options] - Опции куки
|
|
37
|
+
* @param [options.MaxAge=21days] - {@link SetDocumentCookieOptions.MaxAge}
|
|
38
|
+
* @param [options.SameSite="Lax"] - {@link SetDocumentCookieOptions.SameSite}
|
|
39
|
+
* @param [options.Secure=true] - {@link SetDocumentCookieOptions.Secure}
|
|
40
|
+
* @param [options.Path="/"] - {@link SetDocumentCookieOptions.Path}
|
|
41
|
+
* @param [options.Domain] - {@link SetDocumentCookieOptions.Domain}
|
|
42
|
+
*/
|
|
43
|
+
export declare const setDocumentCookie: (name: string, value: string, options?: SetDocumentCookieOptions) => void;
|
|
44
|
+
export declare const getDocumentCookie: (name: string) => string | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Удаляет куку по имени, устанавливая Max-Age=0 через {@link setDocumentCookie}
|
|
47
|
+
*/
|
|
48
|
+
export declare const deleteDocumentCookie: (name: string, Path?: string) => void;
|