@nemigo/helpers 0.13.3 → 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.
Files changed (111) hide show
  1. package/dist/aggregator.d.ts +33 -0
  2. package/dist/aggregator.js +44 -0
  3. package/dist/array.d.ts +33 -0
  4. package/dist/array.js +24 -0
  5. package/dist/async/context.d.ts +73 -0
  6. package/dist/async/context.js +90 -0
  7. package/dist/async/future.d.ts +54 -0
  8. package/dist/async/future.js +71 -0
  9. package/dist/async/index.d.ts +56 -27
  10. package/dist/async/index.js +63 -58
  11. package/dist/async/loader.d.ts +67 -0
  12. package/dist/async/loader.js +101 -0
  13. package/dist/async/queue.d.ts +51 -0
  14. package/dist/async/queue.js +84 -0
  15. package/dist/cases.d.ts +31 -21
  16. package/dist/cases.js +41 -37
  17. package/dist/clean.d.ts +44 -26
  18. package/dist/clean.js +67 -42
  19. package/dist/color/types.d.ts +31 -0
  20. package/dist/color/types.js +1 -0
  21. package/dist/datetime/delta.d.ts +28 -0
  22. package/dist/datetime/delta.js +65 -0
  23. package/dist/datetime/format.d.ts +53 -0
  24. package/dist/datetime/format.js +119 -0
  25. package/dist/datetime/index.d.ts +6 -0
  26. package/dist/datetime/index.js +22 -0
  27. package/dist/datetime/plural.d.ts +77 -0
  28. package/dist/datetime/plural.js +78 -0
  29. package/dist/emitter.d.ts +29 -17
  30. package/dist/emitter.js +35 -21
  31. package/dist/explorer.d.ts +22 -29
  32. package/dist/explorer.js +18 -16
  33. package/dist/files.d.ts +31 -2
  34. package/dist/files.js +33 -8
  35. package/dist/fish.d.ts +29 -0
  36. package/dist/fish.js +70 -0
  37. package/dist/html/cookie.d.ts +48 -0
  38. package/dist/html/cookie.js +37 -0
  39. package/dist/html/events.d.ts +133 -0
  40. package/dist/html/events.js +139 -0
  41. package/dist/html/index.d.ts +31 -0
  42. package/dist/html/index.js +61 -0
  43. package/dist/index.d.ts +38 -40
  44. package/dist/index.js +43 -56
  45. package/dist/jiff/apply.d.ts +93 -0
  46. package/dist/jiff/apply.js +64 -0
  47. package/dist/jiff/extract.d.ts +7 -0
  48. package/dist/jiff/extract.js +82 -0
  49. package/dist/jiff/types.d.ts +57 -0
  50. package/dist/jiff/types.js +1 -0
  51. package/dist/lens.d.ts +20 -31
  52. package/dist/lens.js +22 -37
  53. package/dist/msgpack.d.ts +11 -26
  54. package/dist/msgpack.js +9 -21
  55. package/dist/mutate.d.ts +70 -0
  56. package/dist/mutate.js +130 -0
  57. package/dist/omitter.d.ts +54 -34
  58. package/dist/omitter.js +33 -25
  59. package/dist/path.d.ts +20 -1
  60. package/dist/path.js +21 -2
  61. package/dist/phymath/format.d.ts +60 -0
  62. package/dist/phymath/format.js +34 -0
  63. package/dist/phymath/index.d.ts +30 -30
  64. package/dist/phymath/index.js +41 -33
  65. package/dist/promoter.d.ts +20 -12
  66. package/dist/promoter.js +24 -17
  67. package/dist/random.d.ts +20 -21
  68. package/dist/random.js +22 -23
  69. package/dist/rubles.d.ts +24 -0
  70. package/dist/rubles.js +24 -0
  71. package/dist/script.d.ts +60 -13
  72. package/dist/script.js +46 -10
  73. package/dist/string.d.ts +46 -92
  74. package/dist/string.js +46 -171
  75. package/dist/types.d.ts +144 -25
  76. package/dist/url/index.d.ts +12 -0
  77. package/dist/url/index.js +17 -0
  78. package/dist/url/params.d.ts +141 -0
  79. package/dist/{url.js → url/params.js} +90 -18
  80. package/dist/url/slug.d.ts +28 -0
  81. package/dist/url/slug.js +102 -0
  82. package/dist/veil.d.ts +14 -0
  83. package/dist/veil.js +26 -0
  84. package/dist/xod.d.ts +237 -16
  85. package/dist/xod.js +192 -18
  86. package/dist/zipper.d.ts +22 -4
  87. package/dist/zipper.js +22 -5
  88. package/package.json +82 -34
  89. package/dist/async/space.d.ts +0 -8
  90. package/dist/async/space.js +0 -31
  91. package/dist/cleanup.d.ts +0 -9
  92. package/dist/cleanup.js +0 -18
  93. package/dist/colors.d.ts +0 -539
  94. package/dist/colors.js +0 -888
  95. package/dist/cookie.d.ts +0 -60
  96. package/dist/cookie.js +0 -48
  97. package/dist/datetime.d.ts +0 -82
  98. package/dist/datetime.js +0 -161
  99. package/dist/format.d.ts +0 -36
  100. package/dist/format.js +0 -26
  101. package/dist/future.d.ts +0 -51
  102. package/dist/future.js +0 -71
  103. package/dist/html.d.ts +0 -145
  104. package/dist/html.js +0 -205
  105. package/dist/humanly.d.ts +0 -9
  106. package/dist/humanly.js +0 -93
  107. package/dist/lru.d.ts +0 -77
  108. package/dist/lru.js +0 -128
  109. package/dist/queue.d.ts +0 -40
  110. package/dist/queue.js +0 -56
  111. package/dist/url.d.ts +0 -61
@@ -1,62 +1,70 @@
1
1
  /**
2
- * Приведение -/+ 0 к 0
2
+ * Приведение -0 и +0 к обычному 0
3
+ *
4
+ * Если не 0, то вернётся исходное значение
3
5
  */
4
- export const toZero = (value) => (value === 0 ? 0 : value);
6
+ export const normalizero = (value) => (value === 0 ? 0 : value);
5
7
  /**
6
8
  * Округляет число до заданного количества знаков после запятой
7
9
  *
8
- * Если переданное значение является `NaN` возвращает 0
10
+ * Если переданное значение является `NaN` или 0, возвращает 0
9
11
  *
10
- * @param {number} value - Число для округления
11
- * @param {number} [fraction=2] - Количество знаков после запятой
12
- * @returns {number} Округленное число
12
+ * @param value - Число для округления
13
+ * @param [fraction=2] - Количество знаков после запятой
14
+ * @param [method="math"] - Метод округления
13
15
  */
14
- export const toRound = (value, fraction = 2) => {
16
+ export const round = (value, fraction = 2, method = "math") => {
15
17
  if (isNaN(value) || value === 0)
16
18
  return 0;
17
- return Number(value.toFixed(fraction));
19
+ const factor = Math.pow(10, fraction);
20
+ switch (method) {
21
+ case "up":
22
+ return Math.ceil(value * factor) / factor;
23
+ case "down":
24
+ return Math.floor(value * factor) / factor;
25
+ default:
26
+ return Math.round(value * factor) / factor;
27
+ }
18
28
  };
19
29
  //...
20
30
  /**
21
31
  * Вычисляет сумму всех переданных аргументов
22
32
  *
23
- * Сумма округляется с использованием функции {@link toRound}
24
- *
25
- * @param {...number} args - Числа для суммирования
26
- * @returns {number} Округленная сумма переданных чисел (или 0)
33
+ * Для пустого массива возвращает 0
27
34
  */
28
- export const sum = (...args) => toRound(args.reduce((acc, v) => acc + v, 0));
35
+ export const sum = (...args) => args.reduce((acc, value) => acc + value, 0);
29
36
  /**
30
37
  * Вычисляет произведение всех переданных аргументов
31
38
  *
32
- * Произведение округляется с использованием функции {@link toRound}
33
- *
34
- * @param {...number} args - Числа для перемножения.
35
- * @returns {number} Округленное произведение переданных чисел (или 1)
39
+ * Для пустого массива возвращает 1
36
40
  */
37
- export const mult = (...args) => toRound(args.reduce((acc, v) => acc * v, 1));
41
+ export const mult = (...args) => args.reduce((acc, value) => acc * value, 1);
38
42
  /**
39
43
  * Ограничивает значение в заданном диапазоне [min, max]
40
44
  *
41
- * Если значение меньше min, вернёт min. Если больше max — вернёт max.
42
- * Иначе возвращает само значение без изменений.
43
- *
44
- * @param {number} v - Исходное значение для ограничения
45
- * @param {number} min - Нижняя граница диапазона
46
- * @param {number} max - Верхняя граница диапазона
47
- *
48
- * @returns {number} Значение, ограниченное диапазоном [min, max]
45
+ * @example
46
+ * ```typescript
47
+ * clamp(5, 0, 10); // 5
48
+ * clamp(-5, 0, 10); // 0
49
+ * clamp(15, 0, 10); // 10
50
+ * ```
49
51
  */
50
- export const clamp = (v, min, max) => Math.max(Math.min(v, max), min);
52
+ export const clamp = (value, min, max) => Math.max(Math.min(value, max), min);
53
+ //...
54
+ /**
55
+ * Преобразует градусы в радианы
56
+ */
57
+ export const toRadians = (degrees) => (degrees * Math.PI) / 180;
58
+ /**
59
+ * Преобразует радианы в градусы
60
+ */
61
+ export const toDegrees = (radians) => (radians * 180) / Math.PI;
51
62
  //...
52
- export const toRadians = (deg) => (deg * Math.PI) / 180;
53
63
  /**
54
64
  * Линейная интерполяция между двумя числами
55
65
  *
56
- * @param {number} a - Начальное значение
57
- * @param {number} b - Конечное значение
58
- * @param {number} t - Весовой коэффициент, определяющий пропорцию между начальным и конечным значениями. Значение должно быть в диапазоне [0, 1]
59
- *
60
- * @returns {number} Результат линейной интерполяции между a и b при коэффициенте t
66
+ * @param a - Начальное значение
67
+ * @param b - Конечное значение
68
+ * @param t - Весовой коэффициент, определяющий состояние пропорции между начальным и конечным значениями. Должно быть в диапазоне `[0, 1]`
61
69
  */
62
70
  export const lerp = (a, b, t) => a + (b - a) * t;
@@ -1,25 +1,33 @@
1
1
  import type { RID } from "./types.js";
2
2
  /**
3
- * Класс для создания простого механизма подписок
3
+ * Простой механизм подписок
4
4
  */
5
- export declare class Promoter<Data> {
5
+ export declare class Promoter<E> {
6
6
  __subs: Map<RID, {
7
- call: (data: Data) => void;
7
+ callback: (event: E) => void;
8
8
  once?: boolean;
9
9
  }>;
10
+ notify(event: E): void;
10
11
  /**
11
- * Вызывает подписчиков
12
+ * @param callback - Функция подписчика
13
+ * @param [options] - Опции запуска
14
+ * @param [options.once] - Одноразовая подписка
15
+ * @param [options.key=Symbol()] - Ключ подписчика
16
+ *
17
+ * @returns - Функция для отмены подписки
12
18
  */
13
- notify(data: Data): void;
14
- /**
15
- * Подписка на события
16
- */
17
- sub(call: (data: Data) => void, params?: {
19
+ subscribe(callback: (event: E) => void, options?: {
18
20
  key?: RID;
19
21
  once?: boolean;
20
- }): () => boolean;
22
+ }): () => void;
21
23
  /**
22
- * Удаляет подписчика по ключу. Если не указан, очищаются все
24
+ * **Если ключ не указан, очищаются все**
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * promoter.unsubscribe("my-subscription"); // Удаление конкретной подписки
29
+ * promoter.unsubscribe(); // Очистка всех подписок
30
+ * ```
23
31
  */
24
- unsub(key?: RID): boolean;
32
+ unsubscribe(key?: RID): void;
25
33
  }
package/dist/promoter.js CHANGED
@@ -1,33 +1,40 @@
1
1
  /**
2
- * Класс для создания простого механизма подписок
2
+ * Простой механизм подписок
3
3
  */
4
4
  export class Promoter {
5
5
  __subs = new Map();
6
- /**
7
- * Вызывает подписчиков
8
- */
9
- notify(data) {
10
- this.__subs.forEach(({ call, once }, key) => {
11
- call(data);
6
+ notify(event) {
7
+ this.__subs.forEach(({ callback, once }, key) => {
8
+ callback(event);
12
9
  if (once)
13
10
  this.__subs.delete(key);
14
11
  });
15
12
  }
16
13
  /**
17
- * Подписка на события
14
+ * @param callback - Функция подписчика
15
+ * @param [options] - Опции запуска
16
+ * @param [options.once] - Одноразовая подписка
17
+ * @param [options.key=Symbol()] - Ключ подписчика
18
+ *
19
+ * @returns - Функция для отмены подписки
18
20
  */
19
- sub(call, params = {}) {
20
- const { key = Symbol(), once } = params;
21
- this.__subs.set(key, { call, once });
21
+ subscribe(callback, options = {}) {
22
+ const { key = Symbol(), once } = options;
23
+ this.__subs.set(key, { callback, once });
22
24
  return () => this.__subs.delete(key);
23
25
  }
24
26
  /**
25
- * Удаляет подписчика по ключу. Если не указан, очищаются все
27
+ * **Если ключ не указан, очищаются все**
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * promoter.unsubscribe("my-subscription"); // Удаление конкретной подписки
32
+ * promoter.unsubscribe(); // Очистка всех подписок
33
+ * ```
26
34
  */
27
- unsub(key) {
28
- if (key)
29
- return this.__subs.delete(key);
30
- this.__subs.clear();
31
- return true;
35
+ unsubscribe(key) {
36
+ if (key === undefined)
37
+ return this.__subs.clear();
38
+ this.__subs.delete(key);
32
39
  }
33
40
  }
package/dist/random.d.ts CHANGED
@@ -1,45 +1,44 @@
1
1
  /**
2
2
  * Генерирует случайный числовой код указанной длины.
3
- * Код состоит только из цифр и не может начинаться с нуля.
3
+ * Код состоит только из цифр и не может начинаться с нуля
4
4
  *
5
- * @param length - Длина генерируемого кода (по умолчанию 6)
6
- * @returns Строка с числовым кодом
5
+ * @param [length=6] - Длина генерируемого кода
7
6
  *
8
7
  * @example
9
8
  * ```typescript
10
- * rand(4); // "1234" (пример)
11
- * rand(6); // "123456" (пример)
12
- * rand(8); // "12345678" (пример)
9
+ * rand(4); // "1234"
10
+ * rand(); // "123456"
11
+ * rand(8); // "12345678"
13
12
  * ```
14
13
  */
15
14
  export declare const rand: (length?: number) => string;
16
15
  /**
17
- * Генерирует уникальный ID, состоящий из текущей временной метки и случайного кода.
18
- * Формат: `timestamp:randomCode`
16
+ * Генерирует уникальный ID, состоящий из {@link Timestamp} и случайного кода из {@link rand}
19
17
  *
20
- * @param length - Длина случайной части кода (по умолчанию 7)
21
- * @returns Уникальный ID в формате строки
18
+ * Формат: `${Date.now()}:${rand(length)}`
19
+ *
20
+ * @param [length=7] - Длина случайной части кода
22
21
  *
23
22
  * @example
24
23
  * ```typescript
25
- * randID(4); // "1696934400000:1234" (пример)
26
- * randID(6); // "1696934400000:123456" (пример)
24
+ * randID(4); // "1696934400000:1234"
25
+ * randID(6); // "1696934400000:123456"
27
26
  * ```
28
27
  */
29
28
  export declare const randID: (length?: number) => string;
30
29
  /**
31
- * Генерирует случайный UID (уникальный идентификатор) из буквенно-цифровых символов.
32
- * Может включать префикс таблицы для организации идентификаторов.
30
+ * Генерирует случайный UID из латиницы в нижнем регистре и цифр
31
+ *
32
+ * Формат: `prefix ? `${prefix}:${uid}` : uid`
33
33
  *
34
- * @param table - Префикс таблицы для организации UID (опционально)
35
- * @param length - Длина UID в символах (по умолчанию 20)
36
- * @returns Случайный UID в формате строки
34
+ * @param [prefix] - Префикс для категоризации UID (например таблица)
35
+ * @param [length=20] - Длина UID в символах
37
36
  *
38
37
  * @example
39
38
  * ```typescript
40
- * randUID(); // "a1b2c3d4e5f6g7h8i9j0" (пример)
41
- * randUID("user", 10); // "user:a1b2c3d4e5" (пример)
42
- * randUID("session", 16); // "session:a1b2c3d4e5f6g7h8" (пример)
39
+ * randUID(); // "a1b2c3d4e5f6g7h8i9j0"
40
+ * randUID("user", 10); // "user:a1b2c3d4e5"
41
+ * randUID("session", 16); // "session:a1b2c3d4e5f6g7h8"
43
42
  * ```
44
43
  */
45
- export declare const randUID: (table?: string, length?: number) => string;
44
+ export declare const randUID: (prefix?: string, length?: number) => string;
package/dist/random.js CHANGED
@@ -1,15 +1,14 @@
1
1
  /**
2
2
  * Генерирует случайный числовой код указанной длины.
3
- * Код состоит только из цифр и не может начинаться с нуля.
3
+ * Код состоит только из цифр и не может начинаться с нуля
4
4
  *
5
- * @param length - Длина генерируемого кода (по умолчанию 6)
6
- * @returns Строка с числовым кодом
5
+ * @param [length=6] - Длина генерируемого кода
7
6
  *
8
7
  * @example
9
8
  * ```typescript
10
- * rand(4); // "1234" (пример)
11
- * rand(6); // "123456" (пример)
12
- * rand(8); // "12345678" (пример)
9
+ * rand(4); // "1234"
10
+ * rand(); // "123456"
11
+ * rand(8); // "12345678"
13
12
  * ```
14
13
  */
15
14
  export const rand = (length = 6) => {
@@ -17,38 +16,38 @@ export const rand = (length = 6) => {
17
16
  return Math.floor(min + Math.random() * 9 * min).toString();
18
17
  };
19
18
  /**
20
- * Генерирует уникальный ID, состоящий из текущей временной метки и случайного кода.
21
- * Формат: `timestamp:randomCode`
19
+ * Генерирует уникальный ID, состоящий из {@link Timestamp} и случайного кода из {@link rand}
22
20
  *
23
- * @param length - Длина случайной части кода (по умолчанию 7)
24
- * @returns Уникальный ID в формате строки
21
+ * Формат: `${Date.now()}:${rand(length)}`
22
+ *
23
+ * @param [length=7] - Длина случайной части кода
25
24
  *
26
25
  * @example
27
26
  * ```typescript
28
- * randID(4); // "1696934400000:1234" (пример)
29
- * randID(6); // "1696934400000:123456" (пример)
27
+ * randID(4); // "1696934400000:1234"
28
+ * randID(6); // "1696934400000:123456"
30
29
  * ```
31
30
  */
32
31
  export const randID = (length = 7) => `${Date.now()}:${rand(length)}`;
33
32
  /**
34
- * Генерирует случайный UID (уникальный идентификатор) из буквенно-цифровых символов.
35
- * Может включать префикс таблицы для организации идентификаторов.
33
+ * Генерирует случайный UID из латиницы в нижнем регистре и цифр
34
+ *
35
+ * Формат: `prefix ? `${prefix}:${uid}` : uid`
36
36
  *
37
- * @param table - Префикс таблицы для организации UID (опционально)
38
- * @param length - Длина UID в символах (по умолчанию 20)
39
- * @returns Случайный UID в формате строки
37
+ * @param [prefix] - Префикс для категоризации UID (например таблица)
38
+ * @param [length=20] - Длина UID в символах
40
39
  *
41
40
  * @example
42
41
  * ```typescript
43
- * randUID(); // "a1b2c3d4e5f6g7h8i9j0" (пример)
44
- * randUID("user", 10); // "user:a1b2c3d4e5" (пример)
45
- * randUID("session", 16); // "session:a1b2c3d4e5f6g7h8" (пример)
42
+ * randUID(); // "a1b2c3d4e5f6g7h8i9j0"
43
+ * randUID("user", 10); // "user:a1b2c3d4e5"
44
+ * randUID("session", 16); // "session:a1b2c3d4e5f6g7h8"
46
45
  * ```
47
46
  */
48
- export const randUID = (table, length = 20) => {
49
- const UID = "abcdefghijklmnopqrstuvwxyz0123456789"; // 36 символов
47
+ export const randUID = (prefix, length = 20) => {
48
+ const UID = "abcdefghijklmnopqrstuvwxyz0123456789";
50
49
  let uid = "";
51
50
  for (let i = 0; i < length; i++)
52
51
  uid += UID[Math.floor(Math.random() * 36)];
53
- return table ? `${table}:${uid}` : uid;
52
+ return prefix ? `${prefix}:${uid}` : uid;
54
53
  };
@@ -0,0 +1,24 @@
1
+ import type { NumberFormatConfig } from "./phymath/format.js";
2
+ import type { CanBeNullable } from "./types.js";
3
+ /**
4
+ * Форматирование в RUB-формат с помощью {@link toNumberFormat}
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * formatRUB(1234); // "1 234 ₽"
9
+ * formatRUB(1234.5); // "1 234,50 ₽"
10
+ * formatRUB(1234.56); // "1 234,56 ₽"
11
+ * ```
12
+ */
13
+ export declare const formatRUB: (amount: CanBeNullable<number | string>, config?: Omit<NumberFormatConfig, "postfix">) => string;
14
+ /**
15
+ * Склонение слова "рубль" в зависимости от числа
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * pluralRUB(1); // "рубль"
20
+ * pluralRUB(3); // "рубля"
21
+ * pluralRUB(155); // "рублей"
22
+ * ```
23
+ */
24
+ export declare const pluralRUB: (value: number) => string;
package/dist/rubles.js ADDED
@@ -0,0 +1,24 @@
1
+ import { createValuePluralizer } from "./index.js";
2
+ import { toNumberFormat } from "./phymath/format.js";
3
+ /**
4
+ * Форматирование в RUB-формат с помощью {@link toNumberFormat}
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * formatRUB(1234); // "1 234 ₽"
9
+ * formatRUB(1234.5); // "1 234,50 ₽"
10
+ * formatRUB(1234.56); // "1 234,56 ₽"
11
+ * ```
12
+ */
13
+ export const formatRUB = (amount, config = {}) => toNumberFormat(amount, { ...config, postfix: "₽" });
14
+ /**
15
+ * Склонение слова "рубль" в зависимости от числа
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * pluralRUB(1); // "рубль"
20
+ * pluralRUB(3); // "рубля"
21
+ * pluralRUB(155); // "рублей"
22
+ * ```
23
+ */
24
+ export const pluralRUB = createValuePluralizer("рубль", "рубля", "рублей");
package/dist/script.d.ts CHANGED
@@ -1,21 +1,42 @@
1
- import type { Timestamp } from "./types.js";
2
1
  import type { ExecException } from "node:child_process";
3
2
  /**
4
- * Ищет значение флага в массиве аргументов процесса
5
- *
6
3
  * @param cmd - Команда, которой скрипт был запущен (`process.argv`)
7
4
  * @param name - Имя флага, который нужно найти
8
- * @param [strict=true] - Если `true`, выбрасывает ошибку, если флаг не найден. Если `false`, возвращает `null`
5
+ * @param [strict=true] - Выбрасывает ошибку, если флаг не найден
9
6
  *
10
- * @returns Значение флага (или `null`, если флаг не найден и `strict = false`)
11
7
  * @throws {Error} Если `strict = true` и флаг не найден
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * // process.argv = ["node", "script.js", "--name", "value"]
12
+ * getProcessFlag(process.argv, "--name"); // "value"
13
+ * getProcessFlag(process.argv, "--unknown", false); // null
14
+ * getProcessFlag(process.argv, "--unknown"); // Error
15
+ * ```
12
16
  */
13
17
  declare function getProcessFlag(cmd: string[], name: string, strict: boolean): string | null;
18
+ /**
19
+ * @param cmd - Команда, которой скрипт был запущен (`process.argv`)
20
+ * @param name - Имя флага, который нужно найти
21
+ * @param [strict=true] - Выбрасывает ошибку, если флаг не найден
22
+ *
23
+ * @throws {Error} Если флаг не найден
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * // process.argv = ["node", "script.js", "--name", "value"]
28
+ * getProcessFlag(process.argv, "--name"); // "value"
29
+ * getProcessFlag(process.argv, "--unknown"); // Error
30
+ * ```
31
+ */
14
32
  declare function getProcessFlag(cmd: string[], name: string, strict?: true): string;
15
33
  export { getProcessFlag };
34
+ /**
35
+ * Хуки логирования для {@link execute}
36
+ */
16
37
  export interface ExecuteLogger {
17
38
  /**
18
- * Перед выполнением команды
39
+ * Перед выполнением
19
40
  */
20
41
  before?: (path: string) => string;
21
42
  /**
@@ -27,21 +48,47 @@ export interface ExecuteLogger {
27
48
  */
28
49
  ontimeout?: () => string;
29
50
  }
51
+ /**
52
+ * Опции для {@link execute}
53
+ */
30
54
  export interface ExecuteOptions {
55
+ /**
56
+ * Хуки логирования выполнения команды
57
+ */
31
58
  logger?: ExecuteLogger;
32
59
  /**
33
- * @default 5min
60
+ * Таймаут выполнения команды в миллисекундах
34
61
  */
35
- timeout?: Timestamp | null;
62
+ timeout?: number | null;
36
63
  }
37
64
  /**
38
- * Запускает дочерний процесс с указанной командой в заданной директории
65
+ * Запускает команду через {@link exec} в указанной директории
39
66
  *
40
- * @param path - Директория, в которой будет выполнена команда
67
+ * @remarks При таймауте процесс завершается сигналом `SIGTERM`, но stdout/stderr могут быть выведены после отклонения промиса
68
+ *
69
+ * @param path - Путь к директории, в которой запускать команду
41
70
  * @param command - Команда для выполнения
42
- * @param logger - Хуки для логирования
43
- * @param [timeout=5min] - Таймаут выполнения команды в миллисекундах (по умолчанию 5 минут)
71
+ * @param [options] - Опции выполнения
72
+ * @param [options.logger] - Хуки логирования
73
+ * @param [options.timeout=5min] - Таймаут в миллисекундах или `null` без таймаута
74
+ *
75
+ * @throws {ExecException} Если команда завершается с ошибкой
76
+ * @throws {Error} Если истекает таймаут
77
+ *
78
+ * @example
79
+ * ```typescript
80
+ * await execute("/project/path", "pnpm install");
81
+ *
82
+ * await execute("/project/path", "pnpm run build", {
83
+ * logger: {
84
+ * before: (path) => `Запуск сборки в ${path}`,
85
+ * onerror: (error) => `Ошибка сборки: ${error.message}`,
86
+ * ontimeout: () => "Таймаут сборки"
87
+ * },
88
+ * timeout: 60000
89
+ * });
44
90
  *
45
- * @throws {Error} Если команда завершается с ошибкой или истекает таймаут
91
+ * await execute("/path", "long-running-command", { timeout: null | 0 });
92
+ * ```
46
93
  */
47
94
  export declare const execute: (path: string, command: string, { logger, timeout }?: ExecuteOptions) => Promise<void>;
package/dist/script.js CHANGED
@@ -1,4 +1,20 @@
1
+ import { MS_IN_MINUTE } from "./datetime/delta.js";
1
2
  import { exec } from "node:child_process";
3
+ /**
4
+ * @param cmd - Команда, которой скрипт был запущен (`process.argv`)
5
+ * @param name - Имя флага, который нужно найти
6
+ * @param [strict=true] - Выбрасывает ошибку, если флаг не найден
7
+ *
8
+ * @throws {Error} Если `strict = true` и флаг не найден
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * // process.argv = ["node", "script.js", "--name", "value"]
13
+ * getProcessFlag(process.argv, "--name"); // "value"
14
+ * getProcessFlag(process.argv, "--unknown", false); // null
15
+ * getProcessFlag(process.argv, "--unknown"); // Error
16
+ * ```
17
+ */
2
18
  function getProcessFlag(cmd, name, strict = true) {
3
19
  const argv = cmd.slice(2);
4
20
  const index = argv.indexOf(name);
@@ -14,16 +30,36 @@ function getProcessFlag(cmd, name, strict = true) {
14
30
  }
15
31
  export { getProcessFlag };
16
32
  /**
17
- * Запускает дочерний процесс с указанной командой в заданной директории
33
+ * Запускает команду через {@link exec} в указанной директории
34
+ *
35
+ * @remarks При таймауте процесс завершается сигналом `SIGTERM`, но stdout/stderr могут быть выведены после отклонения промиса
18
36
  *
19
- * @param path - Директория, в которой будет выполнена команда
37
+ * @param path - Путь к директории, в которой запускать команду
20
38
  * @param command - Команда для выполнения
21
- * @param logger - Хуки для логирования
22
- * @param [timeout=5min] - Таймаут выполнения команды в миллисекундах (по умолчанию 5 минут)
39
+ * @param [options] - Опции выполнения
40
+ * @param [options.logger] - Хуки логирования
41
+ * @param [options.timeout=5min] - Таймаут в миллисекундах или `null` без таймаута
23
42
  *
24
- * @throws {Error} Если команда завершается с ошибкой или истекает таймаут
43
+ * @throws {ExecException} Если команда завершается с ошибкой
44
+ * @throws {Error} Если истекает таймаут
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * await execute("/project/path", "pnpm install");
49
+ *
50
+ * await execute("/project/path", "pnpm run build", {
51
+ * logger: {
52
+ * before: (path) => `Запуск сборки в ${path}`,
53
+ * onerror: (error) => `Ошибка сборки: ${error.message}`,
54
+ * ontimeout: () => "Таймаут сборки"
55
+ * },
56
+ * timeout: 60000
57
+ * });
58
+ *
59
+ * await execute("/path", "long-running-command", { timeout: null | 0 });
60
+ * ```
25
61
  */
26
- export const execute = async (path, command, { logger = {}, timeout = 5 * 60 * 1000 } = {}) => new Promise((resolve, reject) => {
62
+ export const execute = async (path, command, { logger = {}, timeout = 5 * MS_IN_MINUTE } = {}) => new Promise((resolve, reject) => {
27
63
  if (logger.before)
28
64
  console.log(logger.before(path));
29
65
  let process = null;
@@ -34,14 +70,14 @@ export const execute = async (path, command, { logger = {}, timeout = 5 * 60 * 1
34
70
  clearTimeout(timer);
35
71
  timer = null;
36
72
  };
37
- timer = timeout
38
- ? setTimeout(() => {
73
+ if (timeout) {
74
+ timer = setTimeout(() => {
39
75
  process?.kill("SIGTERM");
40
76
  if (logger.ontimeout)
41
77
  console.error(logger.ontimeout());
42
78
  reject(new Error("TIMEOUT"));
43
- }, timeout)
44
- : null;
79
+ }, timeout);
80
+ }
45
81
  process = exec(command, { cwd: path }, (error, stdout, stderr) => {
46
82
  cleanup();
47
83
  if (stderr)