@foxford/foxford-utils 1.0.1 → 1.1.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/index.js.flow ADDED
@@ -0,0 +1,654 @@
1
+
2
+ /**
3
+ * Генерирует уникальный идентификатор (qid)
4
+ * @param length - длина уникального идентификатора
5
+ * @param number - включает ли цифры в алфавит
6
+ * @return строка
7
+ */
8
+ declare function qid(length?: number, number?: boolean): string;
9
+
10
+ /**
11
+ * Генерирует уникальный сгруппированный идентификатор (псевдо-UUID в стиле v4).
12
+ * Формат: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (hex)
13
+ */
14
+ declare function uuid(): string;
15
+
16
+ /**
17
+ * Фильтрует поля объекта
18
+ * @param obj - исходный объект
19
+ * @param filterFunc - предикат, принимающий (key, value)
20
+ * @returns новый объект с отфильтрованными полями
21
+ */
22
+ declare function pickBy<T: { [key: string]: mixed, ... }>(
23
+ obj: T,
24
+ filterFunc: (
25
+ key: { ...$Keys<T>, ...string },
26
+ value: $ElementType<T, $Keys<T>>
27
+ ) => boolean
28
+ ): $Rest<T, { ... }>;
29
+ declare type ToggleEventLike = {
30
+ currentTarget: EventTarget | null,
31
+ ...
32
+ };
33
+ declare class Collapse {
34
+ onClickHandler: (e: ToggleEventLike) => boolean;
35
+ constructor(): this;
36
+ makeCollapse(collapse: HTMLElement): boolean;
37
+ init(): void;
38
+ destroy(): void;
39
+ reinit(): void;
40
+ }
41
+ /**
42
+ * Декоратор для функции, добавляющий debounce (задержку выполнения).
43
+ * @export
44
+ * @param {function} f - исходная функция
45
+ * @param {number} ms - задержка в миллисекундах
46
+ * @returns {function} - функция-декоратор с debounce
47
+ */
48
+ declare function debounce<T: (...args: any[]) => any>(
49
+ f: T,
50
+ ms: number
51
+ ): (
52
+ ...args: $ReadOnlyArray<mixed>
53
+ ) => $Call<<R>((...args: any[]) => R) => R, typeof setTimeout>;
54
+
55
+ /**
56
+ * Преобразует массив элементов в объект, где ключ — строковый id элемента.
57
+ *
58
+ * Пример:
59
+ * [{ id: 1, name: 'item 1' }] -> { "1": { id: 1, name: 'item 1' } }
60
+ */
61
+ declare function indexById<
62
+ T: {
63
+ id: string | number | symbol,
64
+ ...
65
+ }
66
+ >(
67
+ items: $ReadOnlyArray<T>
68
+ ): { [key: string]: T, ... };
69
+
70
+ /**
71
+ * Русская форма множественного числа.
72
+ * @docs http://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
73
+ * @example pluralize(1, ['штука', 'штуки', 'штук'])
74
+ */
75
+ declare type PluralForms<T> = [T, T, T];
76
+ declare function pluralize<T>(counter: number, forms: PluralForms<T>): T;
77
+
78
+ /**
79
+ * Возвращает объект, пригодный для React-свойства `dangerouslySetInnerHTML`.
80
+ * @example <div dangerouslySetInnerHTML={rawMarkup("<b>text</b>")} />
81
+ */
82
+ declare type DangerousHTML = {
83
+ __html: string,
84
+ ...
85
+ };
86
+ declare function rawMarkup(text: string): DangerousHTML;
87
+
88
+ /**
89
+ * Делает первую букву строки заглавной
90
+ * @param str - входная строка
91
+ * @returns строка с первой заглавной буквой
92
+ */
93
+ declare function capitalize(str: string): string;
94
+ declare type FileLike = {
95
+ size: number,
96
+ ...
97
+ };
98
+ /**
99
+ * getFilesSize — суммирует size у переданных файлов/вложений
100
+ * Совместимо с File/Blob (у них тоже есть поле size).
101
+ */
102
+ declare function getFilesSize(
103
+ attachments: $ReadOnlyArray<FileLike>,
104
+ files: $ReadOnlyArray<FileLike>
105
+ ): number;
106
+ declare type MimeEntry = {
107
+ mime: string,
108
+ extensions: string[],
109
+ ...
110
+ };
111
+ declare type MimeFiles = $ReadOnlyArray<MimeEntry>;
112
+ /**
113
+ * Возвращает массив MIME-типов из массива файлов
114
+ */
115
+ declare function getMimeTypes(files: MimeFiles): string[];
116
+
117
+ /**
118
+ * Возвращает случайное целое число между min (включительно) и max (не включая max)
119
+ */
120
+ declare function getRandomInt(min: number, max: number): number;
121
+ declare type HasGroupId = {
122
+ group: {
123
+ id: string | number,
124
+ ...
125
+ },
126
+ ...
127
+ };
128
+ /**
129
+ * Превращает массив элементов с group.id в объект,
130
+ * где ключ — String(group.id), значение — сам элемент.
131
+ *
132
+ * Последний элемент с одинаковым group.id перезапишет предыдущий.
133
+ */
134
+ declare function indexByGroupId<T: HasGroupId>(items: $ReadOnlyArray<T>): {
135
+ [key: string]: T,
136
+ ...
137
+ };
138
+
139
+ /**
140
+ * Прокручивает окно к верхней границе первого элемента, соответствующего селектору.
141
+ * Возвращает `false`, если элемент не найден; иначе возвращает `undefined`.
142
+ */
143
+ declare function scrollToElement(selector: string): false | void;
144
+ declare var TYPES: {
145
+ +days: ["день", "дня", "дней"],
146
+ +exercises: ["занятие", "занятия", "занятий"],
147
+ +hours: ["час", "часа", "часов"],
148
+ +members: ["участник", "участника", "участников"],
149
+ +minutes: ["минута", "минуты", "минут"],
150
+ +points: ["балл", "балла", "баллов"],
151
+ +remains: ["остался", "осталось", "осталось"],
152
+ +seconds: ["секунда", "секунды", "секунд"],
153
+ +students: ["ученик", "ученика", "учеников"],
154
+ +studentsParentalCase: ["ученика", "учеников", "учеников"],
155
+ +tasks: ["задача", "задачи", "задач"],
156
+ ...
157
+ };
158
+ declare type PluralizeType = $Keys<typeof TYPES>;
159
+ /**
160
+ * Возвращает строку во множественном числе для заданного типа
161
+ * @param counter — число, по которому выбирается форма
162
+ * @param type — один из предопределённых ключей типов
163
+ */
164
+ declare function pluralizeByType(counter: number, type: PluralizeType): string;
165
+
166
+ /**
167
+ * Конвертирует строку base64 в ArrayBuffer.
168
+ */
169
+ declare function base64ToArrayBuffer(base64: string): ArrayBuffer;
170
+
171
+ /**
172
+ * Парсит строку-список вида:
173
+ * "— Преподаватель кафедры ... <br>
174
+ * — Старший преподаватель ..."
175
+ * в массив элементов без начальных тире/дефисов и пробелов.
176
+ *
177
+ * Поддерживаемые разделители между пунктами:
178
+ * - начало строки
179
+ * - <br>, <br/>, <br /> (в любом регистре)
180
+ * - перевод строки \n
181
+ *
182
+ * Поддерживаемые маркеры пункта:
183
+ * - дефис '-' и множество вариантов тире:
184
+ * U+2010..U+2015, U+FE58, U+FE63, U+FF0D
185
+ */
186
+ declare function parseStringListToArray(input?: string): string[];
187
+ declare interface SourceOption {
188
+ id: string | number;
189
+ name: string;
190
+ image_url?: string | null;
191
+ }
192
+ declare interface SelectOption {
193
+ value: string | number;
194
+ label: string;
195
+ image_url?: string | null;
196
+ }
197
+ /**
198
+ * Преобразует массив опций (например, уровней/классов) в формат для select.
199
+ * @example transformOptionsForSelect([{ id: 1, name: 'A', image_url: 'x.png' }])
200
+ * // => [{ value: 1, label: 'A', image_url: 'x.png' }]
201
+ */
202
+ declare var transformOptionsForSelect: <T: SourceOption>(
203
+ options?: $ReadOnlyArray<T>
204
+ ) => SelectOption[];
205
+ declare type AnyRecord = { [key: string | number | Symbol]: mixed, ... };
206
+ /**
207
+ * Глубокий мерж объектов «как в оригинале»:
208
+ * - мутирует **target** и не мутирует **source**
209
+ * - если по ключу и в target, и в source лежат объекты — сливаем рекурсивно
210
+ * - иначе просто присваиваем ссылку из source в target
211
+ */
212
+ declare function merge<T: AnyRecord, S: AnyRecord>(
213
+ target: T,
214
+ source: S
215
+ ): { ...T, ...S };
216
+
217
+ /**
218
+ * Определяет Internet Explorer (<=11) или старый Edge (движок EdgeHTML).
219
+ * @returns false, если это не IE/EdgeHTML; иначе — номер основной версии.
220
+ */
221
+ declare function detectIE(ua?: string): number | false;
222
+ declare type SerializedField = {
223
+ name: string,
224
+ value: string,
225
+ ...
226
+ };
227
+ /**
228
+ * Сериализует поля формы аналогично jQuery.serializeArray()
229
+ */
230
+ declare function serializeArray(form: mixed): SerializedField[];
231
+
232
+ /**
233
+ * Возвращает внешнюю высоту элемента (offsetHeight + вертикальные отступы).
234
+ */
235
+ declare function outerHeight(el: HTMLElement): number;
236
+
237
+ /**
238
+ * Проверяет, полностью ли элемент находится в текущей области видимости (viewport).
239
+ */
240
+ declare function isElementInViewport(el: Element): boolean;
241
+ declare type StringMap = { [key: string]: string, ... };
242
+ /**
243
+ * Преобразует ключи объекта в camelCase
244
+ */
245
+ declare function toCamelCase(obj: StringMap): StringMap;
246
+
247
+ /**
248
+ * Преобразует ключи объекта из camelCase в under_scored
249
+ */
250
+ declare function toUnderscoredCase(obj: StringMap): StringMap;
251
+
252
+ /**
253
+ * Разбивает массив на чанки (подмассивы) указанного размера.
254
+ * @param limit - Максимальный размер каждого чанка
255
+ * @param arr - Исходный массив
256
+ * @returns Массив чанков
257
+ */
258
+ declare function splitEvery<T>(limit?: number, arr?: T[]): T[][];
259
+
260
+ /**
261
+ * Удаляет дубликаты элементов из массива.
262
+ * @param arrArg - Массив для дедупликации
263
+ * @returns Новый массив без дубликатов
264
+ */
265
+ declare function uniq<T>(arrArg: T[]): T[];
266
+
267
+ /**
268
+ * Удаляет элемент массива по индексу.
269
+ * @param arr - Исходный массив
270
+ * @param index - Индекс удаляемого элемента
271
+ * @returns Новый массив без этого элемента
272
+ */
273
+ declare function removeElFromArr<T>(arr: T[], index: number): T[];
274
+
275
+ /**
276
+ * Сливает два массива объектов по общему ключу.
277
+ *
278
+ * Если объект с тем же значением ключа есть в обоих массивах,
279
+ * объекты объединяются, при этом свойства из `arr2` имеют приоритет.
280
+ * @param arr1 - Первый массив объектов
281
+ * @param arr2 - Второй массив объектов
282
+ * @param key - Ключевое поле для сравнения (по умолчанию: 'id')
283
+ * @returns Объединённый массив
284
+ */
285
+ declare function mergeByKey<T: { [key: string]: mixed, ... }, K: $Keys<T>>(
286
+ arr1?: T[],
287
+ arr2?: T[],
288
+ key?: K
289
+ ): T[];
290
+
291
+ /**
292
+ * Функция принимает Ф.И.О, возвращает Ф.И.
293
+ *
294
+ * Примеры:
295
+ * - "Иванов Иван Иванович" -> "Иван Иванов"
296
+ * - "Иванов Иван" -> "Иван Иванов"
297
+ * - "Иванов" -> "Иванов"
298
+ */
299
+ declare var makeShortNameFromFull: (fullName?: string) => string;
300
+ /**
301
+ * Извлекает все цифры из строки
302
+ *
303
+ * Если вход не строка — вернёт пустую строку.
304
+ */
305
+ declare var extractDigits: (input?: mixed) => string;
306
+ /**
307
+ * Карта ISO-кодов -> символ валюты.
308
+ */
309
+ declare var CURRENCY_DIRECTORY: {
310
+ +AFN: "؋",
311
+ +ALL: "Lek",
312
+ +ANG: "ƒ",
313
+ +ARS: "$",
314
+ +AUD: "$",
315
+ +AWG: "ƒ",
316
+ +AZN: "₼",
317
+ +BAM: "KM",
318
+ +BBD: "$",
319
+ +BGN: "лв",
320
+ +BMD: "$",
321
+ +BND: "$",
322
+ +BOB: "$b",
323
+ +BRL: "R$",
324
+ +BSD: "$",
325
+ +BWP: "P",
326
+ +BYR: "Br",
327
+ +BZD: "BZ$",
328
+ +CAD: "C$",
329
+ +CHF: "CHF",
330
+ +CLP: "$",
331
+ +CNY: "¥",
332
+ +COP: "$",
333
+ +CRC: "₡",
334
+ +CUP: "₱",
335
+ +CZK: "Kč",
336
+ +DKK: "kr",
337
+ +DOP: "RD$",
338
+ +EEK: "kr",
339
+ +EGP: "£",
340
+ +EUR: "€",
341
+ +FJD: "$",
342
+ +FKP: "£",
343
+ +FRF: "₣",
344
+ +GBP: "£",
345
+ +GGP: "£",
346
+ +GHC: "¢",
347
+ +GIP: "£",
348
+ +GTQ: "Q",
349
+ +GYD: "$",
350
+ +HKD: "$",
351
+ +HNL: "L",
352
+ +HRK: "kn",
353
+ +HUF: "Ft",
354
+ +IDR: "Rp",
355
+ +ILS: "₪",
356
+ +IMP: "£",
357
+ +INR: "₨",
358
+ +IRR: "﷼",
359
+ +ISK: "kr",
360
+ +JEP: "£",
361
+ +JMD: "J$",
362
+ +JPY: "¥",
363
+ +KGS: "KGS",
364
+ +KHR: "៛",
365
+ +KPW: "₩",
366
+ +KRW: "₩",
367
+ +KYD: "$",
368
+ +KZT: "₸",
369
+ +LAK: "₭",
370
+ +LBP: "£",
371
+ +LKR: "₨",
372
+ +LRD: "$",
373
+ +LTL: "Lt",
374
+ +LVL: "Ls",
375
+ +MKD: "ден",
376
+ +MNT: "₮",
377
+ +MUR: "₨",
378
+ +MXN: "$",
379
+ +MYR: "RM",
380
+ +MZN: "MT",
381
+ +NAD: "$",
382
+ +NGN: "₦",
383
+ +NIO: "C$",
384
+ +NOK: "kr",
385
+ +NPR: "₨",
386
+ +NZD: "$",
387
+ +OMR: "﷼",
388
+ +PAB: "B/.",
389
+ +PEN: "S/.",
390
+ +PHP: "₱",
391
+ +PKR: "₨",
392
+ +PLN: "zł",
393
+ +PYG: "Gs",
394
+ +QAR: "﷼",
395
+ +RON: "lei",
396
+ +RSD: "Дин.",
397
+ +RUR: "₽",
398
+ +SAR: "﷼",
399
+ +SBD: "$",
400
+ +SCR: "₨",
401
+ +SEK: "kr",
402
+ +SGD: "$",
403
+ +SHP: "£",
404
+ +SOS: "S",
405
+ +SRD: "$",
406
+ +SVC: "$",
407
+ +SYP: "£",
408
+ +THB: "฿",
409
+ +TRL: "₤",
410
+ +TRY: "₤",
411
+ +TTD: "TT$",
412
+ +TVD: "$",
413
+ +TWD: "NT$",
414
+ +UAH: "₴",
415
+ +USD: "$",
416
+ +UYU: "$U",
417
+ +UZS: "лв",
418
+ +VEF: "Bs",
419
+ +VND: "₫",
420
+ +XCD: "$",
421
+ +YER: "﷼",
422
+ +ZAR: "R",
423
+ +ZWD: "Z$",
424
+ ...
425
+ };
426
+ /**
427
+ * Возвращает символ валюты по ISO-коду.
428
+ *
429
+ * Если код неизвестен — вернёт сам переданный код без изменений.
430
+ */
431
+ declare function getCurrencySymbol(currencyCode: string): string;
432
+
433
+ /**
434
+ * Регулирует яркость (осветляет/затемняет) шестнадцатеричного цвета.
435
+ * Принимает 3- или 6-символьный hex (с решёткой '#' или без неё).
436
+ */
437
+ declare function colorLuminance(rawHex: string, lum?: number): string;
438
+
439
+ /**
440
+ * Собирает linear-gradient, используя чуть более светлый и тёмный оттенки цвета.
441
+ * @param degree CSS-угол, например "90deg"
442
+ * @param color hex-строка БЕЗ '#', например "6699cc"
443
+ */
444
+ declare function getGradient(degree: string, color: string): string;
445
+
446
+ /**
447
+ * Детерминированный выбор цвета по строке.
448
+ * @param str произвольная строка
449
+ * @param colors массив CSS-цветов
450
+ * @returns один из цветов или null, если colors не передан
451
+ */
452
+ declare function getColorByString(
453
+ str: string,
454
+ colors?: string[]
455
+ ): string | null;
456
+
457
+ /**
458
+ * Хэлпер для создания строки URL адреса
459
+ * @example createPath('/library', { id: 1 }) // => /library?id=1
460
+ */
461
+ declare function createPath(
462
+ u: string,
463
+ query?: {
464
+ [key: string]:
465
+ | string
466
+ | number
467
+ | boolean
468
+ | null
469
+ | void
470
+ | Array<string | number | boolean | null | void>,
471
+ ...
472
+ }
473
+ ): string;
474
+
475
+ /**
476
+ * Хэлпер для парсинга строки запроса (location.search)
477
+ * @example parseQueryString('?id=1') // => { id: '1' }
478
+ */
479
+ declare function parseQueryString(query: string): { [string]: string | $ReadOnlyArray<string>, ... };
480
+
481
+ /**
482
+ * Извлекает URL следующей страницы из HTTP заголовка Link
483
+ * @example getNextPageURLFromLinkHeader("<http://x/api?page=2>; rel='next'") // => 'http://x/api?page=2'
484
+ */
485
+ declare function getNextPageURLFromLinkHeader(link?: string): string;
486
+
487
+ /**
488
+ * Извлекает номер следующей страницы из HTTP заголовка Link
489
+ * @example getNextPageFromLinkHeader("<http://x/api?page=2>; rel='next'") // => 2
490
+ */
491
+ declare function getNextPageFromLinkHeader(link?: string): number | null;
492
+
493
+ /**
494
+ * Генерирует query-строку из объекта
495
+ */
496
+ declare function makeParamString(object?: {
497
+ [key: string]: string | number | boolean | null | void,
498
+ ...
499
+ }): string;
500
+ declare var mimeImages: () => string[];
501
+ declare var mimeFiles: () => string[];
502
+ declare var mimeAudio: () => string[];
503
+ declare var acceptFileTypes: () => string[];
504
+ declare var acceptAllTypes: () => string[];
505
+ declare var acceptImagesExtensions: () => string[];
506
+ declare var acceptFilesExtensions: () => string[];
507
+ declare var acceptAudioExtensions: () => string[];
508
+ declare var acceptAllExtensions: () => string[];
509
+ /**
510
+ * Оборачивает все имена полей query-строки в `wrapper[<field>]`, пропуская поля из `untouchables`.
511
+ *
512
+ * Пример:
513
+ * wrapFormFields('user', 'name=Alex&age=30', ['age'])
514
+ * -> 'user[name]=Alex&age=30'
515
+ */
516
+ declare function wrapFormFields(
517
+ wrapper: string,
518
+ formFieldsString: string,
519
+ untouchables?: string[]
520
+ ): string;
521
+
522
+ /**
523
+ * Возвращает предикат, проверяющий, совпадает ли `id` объекта с `idToMatch`.
524
+ *
525
+ * Использование: arr.find(matchesId(id))
526
+ */
527
+ declare var matchesId: <
528
+ T: {
529
+ id: mixed,
530
+ ...
531
+ }
532
+ >(
533
+ idToMatch: mixed
534
+ ) => (obj: T) => boolean;
535
+ /**
536
+ * Минимальная форма события для детекции клавиши Enter.
537
+ */
538
+ declare type KeyLikeEvent =
539
+ | {
540
+ which?: number,
541
+ keyCode?: number,
542
+ ...
543
+ }
544
+ | { which?: number, keyCode?: number, ... };
545
+ /**
546
+ * Определяет, была ли нажата клавиша Enter.
547
+ */
548
+ declare function detectEnterKey(e: KeyLikeEvent): boolean;
549
+
550
+ /**
551
+ * Собирает объект опции или возвращает `undefined`, если `value` — ложное значение.
552
+ * Примечание: сохраняет исходное поведение — `0`, пустая строка, false → `undefined`.
553
+ */
554
+ declare function makeOption<T>(
555
+ value: T,
556
+ label: string
557
+ ): {
558
+ value: T,
559
+ label: string,
560
+ ...
561
+ } | void;
562
+
563
+ /**
564
+ * Создаёт загрузчик для асинхронных опций селекта.
565
+ *
566
+ * `func(args)` должен вернуть Promise с массивом опций или null/undefined.
567
+ * Если возвращается Promise, разрешённый `{ options }` объединяется с `extras`.
568
+ * Если возвращается null/undefined, используется `{ options: defaultOptions }` (плюс `extras`).
569
+ *
570
+ * `extras` сохраняет обратную совместимость со старым распространением (spread) значений по умолчанию.
571
+ */
572
+ declare function makeLoadOptionsFunc<O: { [key: string]: any }, A>(
573
+ func: (args: A) => Promise<O[]> | void | null,
574
+ args: A,
575
+ defaultOptions: O[],
576
+ extras?: { [key: string]: mixed, ... }
577
+ ): Promise<{
578
+ ...{
579
+ options: O[],
580
+ ...
581
+ },
582
+ ...{ [key: string]: mixed, ... },
583
+ }>;
584
+ export type {
585
+ AnyRecord,
586
+ DangerousHTML,
587
+ FileLike,
588
+ HasGroupId,
589
+ MimeFiles,
590
+ PluralForms,
591
+ PluralizeType,
592
+ SelectOption,
593
+ SerializedField,
594
+ SourceOption,
595
+ StringMap,
596
+ };
597
+ declare export {
598
+ Collapse,
599
+ TYPES,
600
+ acceptAllExtensions,
601
+ acceptAllTypes,
602
+ acceptAudioExtensions,
603
+ acceptFileTypes,
604
+ acceptFilesExtensions,
605
+ acceptImagesExtensions,
606
+ base64ToArrayBuffer,
607
+ capitalize,
608
+ colorLuminance,
609
+ createPath,
610
+ CURRENCY_DIRECTORY as currencyDirectory,
611
+ debounce,
612
+ detectEnterKey,
613
+ detectIE,
614
+ extractDigits,
615
+ getColorByString,
616
+ getCurrencySymbol,
617
+ getFilesSize,
618
+ getGradient,
619
+ getMimeTypes,
620
+ getNextPageFromLinkHeader,
621
+ getNextPageURLFromLinkHeader,
622
+ getRandomInt,
623
+ indexByGroupId,
624
+ indexById,
625
+ isElementInViewport,
626
+ makeLoadOptionsFunc,
627
+ makeOption,
628
+ makeParamString,
629
+ makeShortNameFromFull,
630
+ matchesId,
631
+ merge,
632
+ mergeByKey,
633
+ mimeAudio,
634
+ mimeFiles,
635
+ mimeImages,
636
+ outerHeight,
637
+ parseQueryString,
638
+ parseStringListToArray,
639
+ pickBy,
640
+ pluralize,
641
+ pluralizeByType,
642
+ qid,
643
+ rawMarkup,
644
+ removeElFromArr,
645
+ scrollToElement,
646
+ serializeArray,
647
+ splitEvery,
648
+ toCamelCase,
649
+ toUnderscoredCase,
650
+ transformOptionsForSelect,
651
+ uniq,
652
+ uuid,
653
+ wrapFormFields,
654
+ };