@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
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Карта для транслитерации кириллических символов в латинские.
3
+ * Содержит соответствия для всех букв русского алфавита в нижнем регистре.
4
+ * Используется в функции {@link toSlug} для создания URL-friendly строк
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * cyrillicToLatinMap.get("а"); // "a"
9
+ * cyrillicToLatinMap.get("ё"); // "yo"
10
+ * cyrillicToLatinMap.get("ъ"); // ""
11
+ * ```
12
+ */
13
+ export const cyrillicToLatinMap = new Map([
14
+ ["а", "a"],
15
+ ["б", "b"],
16
+ ["в", "v"],
17
+ ["г", "g"],
18
+ ["д", "d"],
19
+ ["е", "e"],
20
+ ["ё", "yo"],
21
+ ["ж", "zh"],
22
+ ["з", "z"],
23
+ ["и", "i"],
24
+ ["й", "y"],
25
+ ["к", "k"],
26
+ ["л", "l"],
27
+ ["м", "m"],
28
+ ["н", "n"],
29
+ ["о", "o"],
30
+ ["п", "p"],
31
+ ["р", "r"],
32
+ ["с", "s"],
33
+ ["т", "t"],
34
+ ["у", "u"],
35
+ ["ф", "f"],
36
+ ["х", "h"],
37
+ ["ц", "ts"],
38
+ ["ч", "ch"],
39
+ ["ш", "sh"],
40
+ ["щ", "sch"],
41
+ ["ъ", ""],
42
+ ["ы", "y"],
43
+ ["ь", ""],
44
+ ["э", "e"],
45
+ ["ю", "yu"],
46
+ ["я", "ya"],
47
+ ]);
48
+ /**
49
+ * Конвертирует кириллицу в латиницу, удаляет специальные символы, нормализует пробелы и заменяет их на разделитель
50
+ *
51
+ * @param str - Строка для преобразования в slug
52
+ * @param [separator="-"] - Разделитель для замены пробелов
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * toSlug("Привет, мир!"); // "privet-mir"
57
+ * toSlug("JavaScript Programming"); // "javascript-programming"
58
+ * toSlug("Café & Restaurant", "_"); // "cafe_restaurant"
59
+ * toSlug("Специальные символы!!!", "."); // "specialnye-simvoly"
60
+ * ```
61
+ */
62
+ export const toSlug = (str, separator = "-") => {
63
+ const buf = [];
64
+ let wasSpace = false;
65
+ for (const _char of str.split("")) {
66
+ const char = _char.toLowerCase();
67
+ const code = char.charCodeAt(0);
68
+ // Кириллица (а-я, ё)
69
+ if ((code >= 1072 && code <= 1103) || code === 1105) {
70
+ buf.push(cyrillicToLatinMap.get(char) ?? char);
71
+ wasSpace = false;
72
+ }
73
+ // Цифры (0-9)
74
+ else if (code >= 48 && code <= 57) {
75
+ buf.push(char);
76
+ wasSpace = false;
77
+ }
78
+ // Латиница (a-z)
79
+ else if (code >= 97 && code <= 122) {
80
+ buf.push(char);
81
+ wasSpace = false;
82
+ }
83
+ // Пробуем нормализовать символы с диакритиками в латиницу (é -> e)
84
+ else {
85
+ const normalized = char.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
86
+ const nCode = normalized.charCodeAt(0);
87
+ if (normalized.length === 1 && nCode >= 97 && nCode <= 122) {
88
+ buf.push(normalized);
89
+ wasSpace = false;
90
+ }
91
+ else {
92
+ if (!wasSpace && buf.length > 0) {
93
+ buf.push(separator);
94
+ wasSpace = true;
95
+ }
96
+ }
97
+ }
98
+ }
99
+ const acc = buf.join("");
100
+ // Убираем завершающий separator (с учётом многосимвольного separator)
101
+ return separator && acc.endsWith(separator) ? acc.slice(0, -separator.length) : acc;
102
+ };
package/dist/veil.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ import type { Serializable } from "./types.js";
2
+ /**
3
+ * Декодирует строку, закодированную функцией {@link veil}, в исходное значение и десериализует
4
+ *
5
+ * @remarks Для десериализации используется {@link JSON.parse}
6
+ */
7
+ export declare const unveil: <T = string>(veiled: string) => T;
8
+ /**
9
+ * Кодирует serializable-значение в URL-safe base64-строку
10
+ *
11
+ * @remarks Для сериализации используется {@link JSON.stringify}
12
+ * @remarks Поддерживает полный Unicode, включая смайлики и символы вне BMP
13
+ */
14
+ export declare const veil: (snap: Serializable) => string;
package/dist/veil.js ADDED
@@ -0,0 +1,26 @@
1
+ const encoder = new TextEncoder();
2
+ const decoder = new TextDecoder();
3
+ /**
4
+ * Декодирует строку, закодированную функцией {@link veil}, в исходное значение и десериализует
5
+ *
6
+ * @remarks Для десериализации используется {@link JSON.parse}
7
+ */
8
+ export const unveil = (veiled) => {
9
+ const decoded = atob(decodeURIComponent(veiled));
10
+ const bytes = new Uint8Array(decoded.length);
11
+ for (let i = 0; i < decoded.length; i++)
12
+ bytes[i] = decoded.charCodeAt(i);
13
+ return JSON.parse(decoder.decode(bytes));
14
+ };
15
+ /**
16
+ * Кодирует serializable-значение в URL-safe base64-строку
17
+ *
18
+ * @remarks Для сериализации используется {@link JSON.stringify}
19
+ * @remarks Поддерживает полный Unicode, включая смайлики и символы вне BMP
20
+ */
21
+ export const veil = (snap) => {
22
+ const str = JSON.stringify(snap);
23
+ const bytes = encoder.encode(str);
24
+ const binary = String.fromCharCode(...bytes);
25
+ return encodeURIComponent(btoa(binary));
26
+ };
package/dist/xod.d.ts CHANGED
@@ -1,26 +1,247 @@
1
1
  import { z } from "zod";
2
- export declare const invalid: (value: unknown, ctx: z.core.$RefinementCtx, { message, expected }: {
2
+ /**
3
+ * Параметры для создания ошибки валидации {@link https://zod.dev Zod}
4
+ */
5
+ export interface InvalidValueIssue {
6
+ /**
7
+ * Исходное значение которое не прошло валидацию
8
+ */
9
+ value: unknown;
10
+ /**
11
+ * Контекст валидации {@link https://zod.dev Zod}
12
+ */
13
+ ctx: z.core.$RefinementCtx;
14
+ /**
15
+ * Сообщение об ошибке
16
+ */
3
17
  message: string;
18
+ /**
19
+ * Ожидаемый тип значения
20
+ */
4
21
  expected: string;
5
- }) => never;
22
+ }
23
+ /**
24
+ * Добавляет ошибку валидации в контекст {@link https://zod.dev Zod}-схемы через {@link RefinementCtx.addIssue} и прерывает выполнение
25
+ */
26
+ export declare const throwValueIssue: (props: InvalidValueIssue) => never;
27
+ /**
28
+ * Схема для отсутствующих значений
29
+ *
30
+ * Замаскировано под эквивалент: `z.union([z.null().optional().transform(() => undefined)])`
31
+ *
32
+ * Принимает:
33
+ * - `null` → `undefined`
34
+ * - `undefined` → `undefined`
35
+ * - `"nUll"` (любой регистр) → `undefined`
36
+ * - `"undeFinEd"` (любой регистр) → `undefined`
37
+ * - `""` → `undefined`
38
+ * - `ETC` → ZodError
39
+ */
6
40
  export declare const nullSchema: z.ZodPipe<z.ZodOptional<z.ZodNull>, z.ZodTransform<undefined, null | undefined>>;
41
+ /**
42
+ * Создаёт схему: либо {@link nullSchema}, либо значения по переданной схеме
43
+ *
44
+ * @example
45
+ * ```typescript
46
+ * const nullableString = toNullable(z.string());
47
+ * nullableString.parse("hello"); // "hello"
48
+ * nullableString.parse(null); // undefined
49
+ * nullableString.parse("null"); // undefined
50
+ * ```
51
+ */
52
+ export declare const toNullable: <T extends z.core.SomeType>(schema: T) => z.ZodUnion<[typeof nullSchema, T]>;
53
+ /**
54
+ * Схема для boolean-значений через {@link caseBoolean}
55
+ *
56
+ * Замаскировано под эквивалент: `z.boolean().transform((v) => v)`
57
+ */
7
58
  export declare const booleanSchema: z.ZodPipe<z.ZodBoolean, z.ZodTransform<boolean, boolean>>;
8
- export declare const booleanSchemaOptional: z.ZodUnion<readonly [z.ZodPipe<z.ZodOptional<z.ZodNull>, z.ZodTransform<undefined, null | undefined>>, z.ZodPipe<z.ZodBoolean, z.ZodTransform<boolean, boolean>>]>;
59
+ /**
60
+ * Сочетает {@link nullSchema} и {@link booleanSchema}
61
+ */
62
+ export declare const booleanSchemaOptional: z.ZodUnion<[z.ZodPipe<z.ZodOptional<z.ZodNull>, z.ZodTransform<undefined, null | undefined>>, z.ZodPipe<z.ZodBoolean, z.ZodTransform<boolean, boolean>>]>;
63
+ /**
64
+ * Схема для числовых значений через {@link caseNumber}
65
+ *
66
+ * Замаскировано под эквивалент: `z.union([z.number(), z.string()]).transform((v) => Number(v))`
67
+ */
9
68
  export declare const numberSchema: z.ZodPipe<z.ZodUnion<[z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>;
10
- export declare const numberSchemaOptional: z.ZodUnion<readonly [z.ZodPipe<z.ZodOptional<z.ZodNull>, z.ZodTransform<undefined, null | undefined>>, z.ZodPipe<z.ZodUnion<[z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>]>;
11
- export declare const stringSchema: z.ZodUnion<[z.ZodString, z.ZodPipe<z.ZodNumber, z.ZodTransform<string, number>>]>;
12
- export declare const stringSchemaOptional: z.ZodUnion<readonly [z.ZodPipe<z.ZodOptional<z.ZodNull>, z.ZodTransform<undefined, null | undefined>>, z.ZodUnion<[z.ZodString, z.ZodPipe<z.ZodNumber, z.ZodTransform<string, number>>]>]>;
13
- declare const _default: {
14
- invalid: (value: unknown, ctx: z.core.$RefinementCtx, { message, expected }: {
15
- message: string;
16
- expected: string;
17
- }) => never;
69
+ /**
70
+ * Сочетает {@link nullSchema} и {@link numberSchema}
71
+ */
72
+ export declare const numberSchemaOptional: z.ZodUnion<[z.ZodPipe<z.ZodOptional<z.ZodNull>, z.ZodTransform<undefined, null | undefined>>, z.ZodPipe<z.ZodUnion<[z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>]>;
73
+ /**
74
+ * Отличается типизацией от {@link numberSchema} тем, что якобы не принимает строки
75
+ *
76
+ * Замаскировано под эквивалент: `z.number().transform((v) => v)`
77
+ *
78
+ * @example
79
+ * ```typescript
80
+ * numberStrictSchema.parse(42); // 42
81
+ * numberStrictSchema.parse("42"); // Ошибка типизации!
82
+ * ```
83
+ */
84
+ export declare const numberStrictSchema: z.ZodPipe<z.ZodNumber, z.ZodTransform<number, number>>;
85
+ /**
86
+ * Сочетает {@link nullSchema} и {@link numberStrictSchema}
87
+ */
88
+ export declare const numberStrictSchemaOptional: z.ZodUnion<[typeof nullSchema, typeof numberStrictSchema]>;
89
+ /**
90
+ * Схема для строковых значений через {@link caseString}
91
+ *
92
+ * Замаскировано под эквивалент: `z.union([z.number(), z.string()]).transform((v) => String(v))`
93
+ */
94
+ export declare const stringSchema: z.ZodPipe<z.ZodUnion<[z.ZodNumber, z.ZodString]>, z.ZodTransform<string, string | number>>;
95
+ /**
96
+ * Сочетает {@link nullSchema} и {@link stringSchema}
97
+ */
98
+ export declare const stringSchemaOptional: z.ZodUnion<[z.ZodPipe<z.ZodOptional<z.ZodNull>, z.ZodTransform<undefined, null | undefined>>, z.ZodPipe<z.ZodUnion<[z.ZodNumber, z.ZodString]>, z.ZodTransform<string, string | number>>]>;
99
+ /**
100
+ * Отличается типизацией от {@link stringSchema} тем, что якобы не принимает числа
101
+ *
102
+ * Замаскировано под эквивалент: `z.string().transform((v) => v)`
103
+ *
104
+ * @example
105
+ * ```typescript
106
+ * stringStrictSchema.parse("hello"); // "hello"
107
+ * stringStrictSchema.parse(42); // Ошибка типизации!
108
+ * ```
109
+ */
110
+ export declare const stringStrictSchema: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
111
+ /**
112
+ * Сочетает {@link nullSchema} и {@link stringStrictSchema}
113
+ */
114
+ export declare const stringStrictSchemaOptional: z.ZodUnion<[typeof nullSchema, typeof stringStrictSchema]>;
115
+ /**
116
+ * Схема для {@link ZoneStamp}
117
+ */
118
+ export declare const zoneStampSchema: z.ZodObject<{
119
+ stamp: z.ZodPipe<z.ZodUnion<[z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>;
120
+ zone: z.ZodPipe<z.ZodUnion<[z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>;
121
+ }, z.core.$strip>;
122
+ /**
123
+ * Сочетает {@link nullSchema} и {@link zoneStampSchema}
124
+ */
125
+ export declare const zoneStampSchemaOptional: z.ZodUnion<[z.ZodPipe<z.ZodOptional<z.ZodNull>, z.ZodTransform<undefined, null | undefined>>, z.ZodObject<{
126
+ stamp: z.ZodPipe<z.ZodUnion<[z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>;
127
+ zone: z.ZodPipe<z.ZodUnion<[z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>;
128
+ }, z.core.$strip>]>;
129
+ /**
130
+ * Строгая версия {@link zoneStampSchema}, которая не якобы принимает строковые представления чисел
131
+ *
132
+ * @example
133
+ * ```typescript
134
+ * zoneStampStrictSchema.parse({ stamp: 1234567890, zone: 3 }); // { stamp: 1234567890, zone: 3 }
135
+ * zoneStampStrictSchema.parse({ stamp: 1234567890, zone: "3" }); // Ошибка типизации!
136
+ * ```
137
+ */
138
+ export declare const zoneStampStrictSchema: z.ZodObject<{
139
+ stamp: typeof numberStrictSchema;
140
+ zone: typeof numberStrictSchema;
141
+ }>;
142
+ /**
143
+ * Сочетает {@link nullSchema} и {@link zoneStampStrictSchema}
144
+ */
145
+ export declare const zoneStampStrictSchemaOptional: z.ZodUnion<[typeof nullSchema, typeof zoneStampStrictSchema]>;
146
+ /**
147
+ * Схема для {@link LWH}
148
+ */
149
+ export declare const lwhSchema: z.ZodObject<{
150
+ length: z.ZodPipe<z.ZodUnion<[z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>;
151
+ width: z.ZodPipe<z.ZodUnion<[z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>;
152
+ height: z.ZodPipe<z.ZodUnion<[z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>;
153
+ }, z.core.$strip>;
154
+ /**
155
+ * Сочетает {@link nullSchema} и {@link lwhSchema}
156
+ */
157
+ export declare const lwhSchemaOptional: z.ZodUnion<[z.ZodPipe<z.ZodOptional<z.ZodNull>, z.ZodTransform<undefined, null | undefined>>, z.ZodObject<{
158
+ length: z.ZodPipe<z.ZodUnion<[z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>;
159
+ width: z.ZodPipe<z.ZodUnion<[z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>;
160
+ height: z.ZodPipe<z.ZodUnion<[z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>;
161
+ }, z.core.$strip>]>;
162
+ /**
163
+ * Отличается типизацией от {@link lwhSchema} тем, что якобы не принимает строковые представления чисел
164
+ *
165
+ * @example
166
+ * ```typescript
167
+ * lwhStrictSchema.parse({ length: 10, width: 20, height: 30 }); // { length: 10, width: 20, height: 30 }
168
+ * lwhStrictSchema.parse({ length: "10", width: "20", height: "30" }); // Ошибка типизации!
169
+ * ```
170
+ */
171
+ export declare const lwhStrictSchema: z.ZodObject<{
172
+ length: typeof numberStrictSchema;
173
+ width: typeof numberStrictSchema;
174
+ height: typeof numberStrictSchema;
175
+ }>;
176
+ /**
177
+ * Сочетает {@link nullSchema} и {@link lwhStrictSchema}
178
+ */
179
+ export declare const lwhStrictSchemaOptional: z.ZodUnion<[typeof nullSchema, typeof lwhStrictSchema]>;
180
+ /**
181
+ * Коллекция расширенных {@link https://zod.dev Zod}-схем со встроенными преобразованиями типов
182
+ *
183
+ * @example
184
+ * ```typescript
185
+ * import { xod } from "./xod.js"; // or import xod from "./xod.js";
186
+ *
187
+ * const userSchema = z.object({
188
+ * name: xod.string, // Принимает string и number
189
+ * age: xod.number, // Принимает number и string
190
+ * isActive: xod.boolean, // Принимает boolean, number, string
191
+ * notes: xod.stringOptional, // Принимает string, number, null, undefined
192
+ * created: xod.zoneStamp, // Принимает объект с временной меткой и зоной
193
+ * });
194
+ * ```
195
+ */
196
+ export declare const xod: {
197
+ throwValueIssue: (props: InvalidValueIssue) => never;
198
+ toNullable: <T extends z.core.SomeType>(schema: T) => z.ZodUnion<[typeof nullSchema, T]>;
18
199
  null: z.ZodPipe<z.ZodOptional<z.ZodNull>, z.ZodTransform<undefined, null | undefined>>;
19
200
  boolean: z.ZodPipe<z.ZodBoolean, z.ZodTransform<boolean, boolean>>;
20
- booleanOptional: z.ZodUnion<readonly [z.ZodPipe<z.ZodOptional<z.ZodNull>, z.ZodTransform<undefined, null | undefined>>, z.ZodPipe<z.ZodBoolean, z.ZodTransform<boolean, boolean>>]>;
201
+ booleanOptional: z.ZodUnion<[z.ZodPipe<z.ZodOptional<z.ZodNull>, z.ZodTransform<undefined, null | undefined>>, z.ZodPipe<z.ZodBoolean, z.ZodTransform<boolean, boolean>>]>;
21
202
  number: z.ZodPipe<z.ZodUnion<[z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>;
22
- numberOptional: z.ZodUnion<readonly [z.ZodPipe<z.ZodOptional<z.ZodNull>, z.ZodTransform<undefined, null | undefined>>, z.ZodPipe<z.ZodUnion<[z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>]>;
23
- string: z.ZodUnion<[z.ZodString, z.ZodPipe<z.ZodNumber, z.ZodTransform<string, number>>]>;
24
- stringOptional: z.ZodUnion<readonly [z.ZodPipe<z.ZodOptional<z.ZodNull>, z.ZodTransform<undefined, null | undefined>>, z.ZodUnion<[z.ZodString, z.ZodPipe<z.ZodNumber, z.ZodTransform<string, number>>]>]>;
203
+ numberStrict: z.ZodPipe<z.ZodNumber, z.ZodTransform<number, number>>;
204
+ numberOptional: z.ZodUnion<[z.ZodPipe<z.ZodOptional<z.ZodNull>, z.ZodTransform<undefined, null | undefined>>, z.ZodPipe<z.ZodUnion<[z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>]>;
205
+ numberStrictOptional: z.ZodUnion<[z.ZodPipe<z.ZodOptional<z.ZodNull>, z.ZodTransform<undefined, null | undefined>>, z.ZodPipe<z.ZodNumber, z.ZodTransform<number, number>>]>;
206
+ string: z.ZodPipe<z.ZodUnion<[z.ZodNumber, z.ZodString]>, z.ZodTransform<string, string | number>>;
207
+ stringStrict: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
208
+ stringOptional: z.ZodUnion<[z.ZodPipe<z.ZodOptional<z.ZodNull>, z.ZodTransform<undefined, null | undefined>>, z.ZodPipe<z.ZodUnion<[z.ZodNumber, z.ZodString]>, z.ZodTransform<string, string | number>>]>;
209
+ stringStrictOptional: z.ZodUnion<[z.ZodPipe<z.ZodOptional<z.ZodNull>, z.ZodTransform<undefined, null | undefined>>, z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>]>;
210
+ zoneStamp: z.ZodObject<{
211
+ stamp: z.ZodPipe<z.ZodUnion<[z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>;
212
+ zone: z.ZodPipe<z.ZodUnion<[z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>;
213
+ }, z.core.$strip>;
214
+ zoneStampOptional: z.ZodUnion<[z.ZodPipe<z.ZodOptional<z.ZodNull>, z.ZodTransform<undefined, null | undefined>>, z.ZodObject<{
215
+ stamp: z.ZodPipe<z.ZodUnion<[z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>;
216
+ zone: z.ZodPipe<z.ZodUnion<[z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>;
217
+ }, z.core.$strip>]>;
218
+ zoneStampStrict: z.ZodObject<{
219
+ stamp: typeof numberStrictSchema;
220
+ zone: typeof numberStrictSchema;
221
+ }, z.core.$strip>;
222
+ zoneStampStrictOptional: z.ZodUnion<[z.ZodPipe<z.ZodOptional<z.ZodNull>, z.ZodTransform<undefined, null | undefined>>, z.ZodObject<{
223
+ stamp: typeof numberStrictSchema;
224
+ zone: typeof numberStrictSchema;
225
+ }, z.core.$strip>]>;
226
+ lwh: z.ZodObject<{
227
+ length: z.ZodPipe<z.ZodUnion<[z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>;
228
+ width: z.ZodPipe<z.ZodUnion<[z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>;
229
+ height: z.ZodPipe<z.ZodUnion<[z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>;
230
+ }, z.core.$strip>;
231
+ lwhOptional: z.ZodUnion<[z.ZodPipe<z.ZodOptional<z.ZodNull>, z.ZodTransform<undefined, null | undefined>>, z.ZodObject<{
232
+ length: z.ZodPipe<z.ZodUnion<[z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>;
233
+ width: z.ZodPipe<z.ZodUnion<[z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>;
234
+ height: z.ZodPipe<z.ZodUnion<[z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>;
235
+ }, z.core.$strip>]>;
236
+ lwhStrict: z.ZodObject<{
237
+ length: typeof numberStrictSchema;
238
+ width: typeof numberStrictSchema;
239
+ height: typeof numberStrictSchema;
240
+ }, z.core.$strip>;
241
+ lwhStrictOptional: z.ZodUnion<[z.ZodPipe<z.ZodOptional<z.ZodNull>, z.ZodTransform<undefined, null | undefined>>, z.ZodObject<{
242
+ length: typeof numberStrictSchema;
243
+ width: typeof numberStrictSchema;
244
+ height: typeof numberStrictSchema;
245
+ }, z.core.$strip>]>;
25
246
  };
26
- export default _default;
247
+ export default xod;
package/dist/xod.js CHANGED
@@ -1,66 +1,240 @@
1
1
  import { caseBoolean, caseNumber, caseString } from "./cases.js";
2
2
  import { z } from "zod";
3
- export const invalid = (value, ctx, { message, expected }) => {
4
- ctx.addIssue({
3
+ /**
4
+ * Добавляет ошибку валидации в контекст {@link https://zod.dev Zod}-схемы через {@link RefinementCtx.addIssue} и прерывает выполнение
5
+ */
6
+ export const throwValueIssue = (props) => {
7
+ props.ctx.addIssue({
5
8
  code: "invalid_type",
6
- message,
7
- input: value,
8
- expected: expected,
9
+ message: props.message,
10
+ input: props.value,
11
+ expected: props.expected,
9
12
  });
10
13
  return z.NEVER;
11
14
  };
15
+ //...
16
+ /**
17
+ * Схема для отсутствующих значений
18
+ *
19
+ * Замаскировано под эквивалент: `z.union([z.null().optional().transform(() => undefined)])`
20
+ *
21
+ * Принимает:
22
+ * - `null` → `undefined`
23
+ * - `undefined` → `undefined`
24
+ * - `"nUll"` (любой регистр) → `undefined`
25
+ * - `"undeFinEd"` (любой регистр) → `undefined`
26
+ * - `""` → `undefined`
27
+ * - `ETC` → ZodError
28
+ */
12
29
  export const nullSchema = z.union([
13
- z
14
- .null()
15
- .optional()
16
- .transform(() => undefined),
30
+ // prettier-ignore
31
+ z.null().optional().transform(() => undefined),
17
32
  z.string().transform((value, ctx) => {
18
33
  if (!value)
19
34
  return undefined;
20
35
  const flat = value.trim().toLowerCase();
21
36
  if (flat === "undefined" || flat === "null")
22
37
  return undefined;
23
- return invalid(value, ctx, {
38
+ return throwValueIssue({
39
+ ctx,
40
+ value,
24
41
  message: "It isn't a null / undefined",
25
42
  expected: "null / undefined (or string like null / undefined)",
26
43
  });
27
44
  }),
28
45
  ]);
46
+ /**
47
+ * Создаёт схему: либо {@link nullSchema}, либо значения по переданной схеме
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * const nullableString = toNullable(z.string());
52
+ * nullableString.parse("hello"); // "hello"
53
+ * nullableString.parse(null); // undefined
54
+ * nullableString.parse("null"); // undefined
55
+ * ```
56
+ */
57
+ export const toNullable = (schema) => z.union([nullSchema, schema]);
29
58
  //...
59
+ /**
60
+ * Схема для boolean-значений через {@link caseBoolean}
61
+ *
62
+ * Замаскировано под эквивалент: `z.boolean().transform((v) => v)`
63
+ */
30
64
  export const booleanSchema = z.unknown().transform((value, ctx) => caseBoolean(value, (result) => result === undefined
31
- ? invalid(value, ctx, {
65
+ ? throwValueIssue({
66
+ ctx,
67
+ value,
32
68
  message: "It isn't a boolean",
33
69
  expected: "boolean (or string / number like boolean)",
34
70
  })
35
71
  : result));
36
- export const booleanSchemaOptional = z.union([nullSchema, booleanSchema]);
72
+ /**
73
+ * Сочетает {@link nullSchema} и {@link booleanSchema}
74
+ */
75
+ export const booleanSchemaOptional = toNullable(booleanSchema);
37
76
  //...
77
+ /**
78
+ * Схема для числовых значений через {@link caseNumber}
79
+ *
80
+ * Замаскировано под эквивалент: `z.union([z.number(), z.string()]).transform((v) => Number(v))`
81
+ */
38
82
  export const numberSchema = z.unknown().transform((value, ctx) => caseNumber(value, (result) => result === undefined
39
- ? invalid(value, ctx, {
83
+ ? throwValueIssue({
84
+ ctx,
85
+ value,
40
86
  message: "It isn't a number",
41
87
  expected: "number (or string like number)",
42
88
  })
43
89
  : result));
44
- export const numberSchemaOptional = z.union([nullSchema, numberSchema]);
90
+ /**
91
+ * Сочетает {@link nullSchema} и {@link numberSchema}
92
+ */
93
+ export const numberSchemaOptional = toNullable(numberSchema);
94
+ /**
95
+ * Отличается типизацией от {@link numberSchema} тем, что якобы не принимает строки
96
+ *
97
+ * Замаскировано под эквивалент: `z.number().transform((v) => v)`
98
+ *
99
+ * @example
100
+ * ```typescript
101
+ * numberStrictSchema.parse(42); // 42
102
+ * numberStrictSchema.parse("42"); // Ошибка типизации!
103
+ * ```
104
+ */
105
+ export const numberStrictSchema = numberSchema;
106
+ /**
107
+ * Сочетает {@link nullSchema} и {@link numberStrictSchema}
108
+ */
109
+ export const numberStrictSchemaOptional = numberSchemaOptional;
45
110
  //...
111
+ /**
112
+ * Схема для строковых значений через {@link caseString}
113
+ *
114
+ * Замаскировано под эквивалент: `z.union([z.number(), z.string()]).transform((v) => String(v))`
115
+ */
46
116
  export const stringSchema = z.unknown().transform((value, ctx) => caseString(value, (result) => {
47
117
  const trimmed = result === undefined ? "" : result.trim();
48
118
  return trimmed === ""
49
- ? invalid(value, ctx, {
119
+ ? throwValueIssue({
120
+ ctx,
121
+ value,
50
122
  message: "It isn't a string or empty string",
51
123
  expected: "string (or number)",
52
124
  })
53
125
  : trimmed;
54
126
  }));
55
- export const stringSchemaOptional = z.union([nullSchema, stringSchema]);
127
+ /**
128
+ * Сочетает {@link nullSchema} и {@link stringSchema}
129
+ */
130
+ export const stringSchemaOptional = toNullable(stringSchema);
131
+ /**
132
+ * Отличается типизацией от {@link stringSchema} тем, что якобы не принимает числа
133
+ *
134
+ * Замаскировано под эквивалент: `z.string().transform((v) => v)`
135
+ *
136
+ * @example
137
+ * ```typescript
138
+ * stringStrictSchema.parse("hello"); // "hello"
139
+ * stringStrictSchema.parse(42); // Ошибка типизации!
140
+ * ```
141
+ */
142
+ export const stringStrictSchema = stringSchema;
143
+ /**
144
+ * Сочетает {@link nullSchema} и {@link stringStrictSchema}
145
+ */
146
+ export const stringStrictSchemaOptional = stringSchemaOptional;
147
+ //...
148
+ /**
149
+ * Схема для {@link ZoneStamp}
150
+ */
151
+ export const zoneStampSchema = z.object({
152
+ stamp: numberSchema,
153
+ zone: numberSchema,
154
+ });
155
+ /**
156
+ * Сочетает {@link nullSchema} и {@link zoneStampSchema}
157
+ */
158
+ export const zoneStampSchemaOptional = toNullable(zoneStampSchema);
159
+ /**
160
+ * Строгая версия {@link zoneStampSchema}, которая не якобы принимает строковые представления чисел
161
+ *
162
+ * @example
163
+ * ```typescript
164
+ * zoneStampStrictSchema.parse({ stamp: 1234567890, zone: 3 }); // { stamp: 1234567890, zone: 3 }
165
+ * zoneStampStrictSchema.parse({ stamp: 1234567890, zone: "3" }); // Ошибка типизации!
166
+ * ```
167
+ */
168
+ export const zoneStampStrictSchema = zoneStampSchema;
169
+ /**
170
+ * Сочетает {@link nullSchema} и {@link zoneStampStrictSchema}
171
+ */
172
+ export const zoneStampStrictSchemaOptional = zoneStampSchemaOptional;
173
+ //...
174
+ /**
175
+ * Схема для {@link LWH}
176
+ */
177
+ export const lwhSchema = z.object({
178
+ length: numberSchema,
179
+ width: numberSchema,
180
+ height: numberSchema,
181
+ });
182
+ /**
183
+ * Сочетает {@link nullSchema} и {@link lwhSchema}
184
+ */
185
+ export const lwhSchemaOptional = toNullable(lwhSchema);
186
+ /**
187
+ * Отличается типизацией от {@link lwhSchema} тем, что якобы не принимает строковые представления чисел
188
+ *
189
+ * @example
190
+ * ```typescript
191
+ * lwhStrictSchema.parse({ length: 10, width: 20, height: 30 }); // { length: 10, width: 20, height: 30 }
192
+ * lwhStrictSchema.parse({ length: "10", width: "20", height: "30" }); // Ошибка типизации!
193
+ * ```
194
+ */
195
+ export const lwhStrictSchema = lwhSchema;
196
+ /**
197
+ * Сочетает {@link nullSchema} и {@link lwhStrictSchema}
198
+ */
199
+ export const lwhStrictSchemaOptional = lwhSchemaOptional;
56
200
  //...
57
- export default {
58
- invalid,
201
+ /**
202
+ * Коллекция расширенных {@link https://zod.dev Zod}-схем со встроенными преобразованиями типов
203
+ *
204
+ * @example
205
+ * ```typescript
206
+ * import { xod } from "./xod.js"; // or import xod from "./xod.js";
207
+ *
208
+ * const userSchema = z.object({
209
+ * name: xod.string, // Принимает string и number
210
+ * age: xod.number, // Принимает number и string
211
+ * isActive: xod.boolean, // Принимает boolean, number, string
212
+ * notes: xod.stringOptional, // Принимает string, number, null, undefined
213
+ * created: xod.zoneStamp, // Принимает объект с временной меткой и зоной
214
+ * });
215
+ * ```
216
+ */
217
+ export const xod = {
218
+ throwValueIssue,
219
+ toNullable,
59
220
  null: nullSchema,
60
221
  boolean: booleanSchema,
61
222
  booleanOptional: booleanSchemaOptional,
62
223
  number: numberSchema,
224
+ numberStrict: numberStrictSchema,
63
225
  numberOptional: numberSchemaOptional,
226
+ numberStrictOptional: numberStrictSchemaOptional,
64
227
  string: stringSchema,
228
+ stringStrict: stringStrictSchema,
65
229
  stringOptional: stringSchemaOptional,
230
+ stringStrictOptional: stringStrictSchemaOptional,
231
+ zoneStamp: zoneStampSchema,
232
+ zoneStampOptional: zoneStampSchemaOptional,
233
+ zoneStampStrict: zoneStampStrictSchema,
234
+ zoneStampStrictOptional: zoneStampStrictSchemaOptional,
235
+ lwh: lwhSchema,
236
+ lwhOptional: lwhSchemaOptional,
237
+ lwhStrict: lwhStrictSchema,
238
+ lwhStrictOptional: lwhStrictSchemaOptional,
66
239
  };
240
+ export default xod;