@brandup/ui-helpers 2.0.1 → 2.0.3

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/cjs/index.js CHANGED
@@ -1,310 +1,18 @@
1
1
  'use strict';
2
2
 
3
- /**
4
- * Reads a nested property value from an object by a dot-separated path.
5
- *
6
- * @param obj Source object to read from.
7
- * @param path Dot-separated property path, e.g. `"header.value"`.
8
- * @returns The resolved value; `null` when `obj` is falsy, or `undefined` when
9
- * any segment of the path does not exist.
10
- * @example
11
- * getProperty({ header: { value: "Item" } }, "header.value"); // "Item"
12
- */
13
- function getProperty(obj, path) {
14
- if (!obj)
15
- return null;
16
- const props = path.split('.');
17
- for (let i = 0; i < props.length; i++) {
18
- const name = props[i];
19
- if (obj == null || (typeof obj !== "object" && typeof obj !== "function"))
20
- return undefined;
21
- if (!(name in obj))
22
- return undefined;
23
- obj = obj[name];
24
- }
25
- return obj;
26
- }
27
- /**
28
- * Determines whether an object has a nested property at the given dot-separated path.
29
- *
30
- * @param obj Source object to inspect.
31
- * @param path Dot-separated property path, e.g. `"header.value"`.
32
- * @returns `true` if every segment of the path exists, otherwise `false`.
33
- * @example
34
- * hasProperty({ header: { value: "Item" } }, "header.value"); // true
35
- */
36
- function hasProperty(obj, path) {
37
- if (!obj)
38
- return false;
39
- const props = path.split('.');
40
- for (let i = 0; i < props.length; i++) {
41
- const name = props[i];
42
- if (obj == null || (typeof obj !== "object" && typeof obj !== "function"))
43
- return false;
44
- if (!(name in obj))
45
- return false;
46
- obj = obj[name];
47
- }
48
- return true;
49
- }
3
+ var object = require('./helpers/object.js');
4
+ var type = require('./helpers/type.js');
5
+ var func = require('./helpers/func.js');
6
+ var word = require('./helpers/word.js');
7
+ var guid = require('./helpers/guid.js');
8
+ var string = require('./helpers/string.js');
50
9
 
51
- var object = /*#__PURE__*/Object.freeze({
52
- __proto__: null,
53
- getProperty: getProperty,
54
- hasProperty: hasProperty
55
- });
56
10
 
57
- /**
58
- * Determines whether the given value is a function.
59
- *
60
- * @param value Value to test.
61
- * @returns `true` if the value is a function, otherwise `false`.
62
- */
63
- function isFunction(value) {
64
- return (typeof value === "function");
65
- }
66
- /**
67
- * Determines whether the given value is a string.
68
- *
69
- * Returns `true` for both string primitives and `String` object instances.
70
- *
71
- * @param value Value to test.
72
- * @returns `true` if the value is a string, otherwise `false`.
73
- */
74
- function isString(value) {
75
- return (typeof value === "string" || value instanceof String);
76
- }
77
11
 
78
- var type = /*#__PURE__*/Object.freeze({
79
- __proto__: null,
80
- isFunction: isFunction,
81
- isString: isString
82
- });
83
-
84
- /**
85
- * Wraps a callback so that, when invoked, it runs no sooner than `minTime` milliseconds
86
- * after this wrapper was created.
87
- *
88
- * The deadline is measured from the moment `minWait` is called. If `minTime` is omitted
89
- * or falsy, the original function is returned unchanged.
90
- *
91
- * @param func Callback to defer.
92
- * @param minTime Minimum delay in milliseconds before the callback may run.
93
- * @returns A wrapped function with the same arguments as `func`.
94
- */
95
- const minWait = (func, minTime) => {
96
- if (!minTime)
97
- return func;
98
- const beginTime = Date.now();
99
- const ret = (...args) => {
100
- const rightTime = getRightTime(beginTime, minTime);
101
- if (rightTime)
102
- setTimeout(() => func(...args), rightTime);
103
- else
104
- func(...args);
105
- };
106
- return ret;
107
- };
108
- /**
109
- * Awaits an async operation and guarantees the returned promise settles no sooner than
110
- * `minTime` milliseconds after invocation, padding with an extra delay when needed.
111
- *
112
- * Useful for keeping spinners/loading states visible for a minimum duration. If `minTime`
113
- * is omitted or falsy, `func` is awaited and its result returned without padding.
114
- *
115
- * @typeParam TResult Result type produced by `func`.
116
- * @param func Factory returning the promise to await.
117
- * @param minTime Minimum total duration in milliseconds.
118
- * @param abort Optional signal used to cancel the padding delay.
119
- * @returns The result produced by `func`.
120
- */
121
- async function minWaitAsync(func, minTime, abort) {
122
- if (!minTime)
123
- return func();
124
- const beginTime = Date.now();
125
- const result = await func();
126
- const rightTime = getRightTime(beginTime, minTime);
127
- if (rightTime)
128
- await delay(rightTime, abort);
129
- return result;
130
- }
131
- /** @internal */
132
- const getRightTime = (start, minTime) => {
133
- const finishTime = Date.now();
134
- const w = minTime - (finishTime - start);
135
- return w > minTime * 0.1 ? w : 0;
136
- };
137
- /**
138
- * Returns a promise that resolves after the given number of milliseconds.
139
- *
140
- * If an already-aborted signal is supplied the promise rejects immediately; otherwise
141
- * aborting before the delay elapses clears the timer and rejects with the abort reason.
142
- *
143
- * @param time Delay in milliseconds.
144
- * @param abort Optional signal used to cancel the delay.
145
- * @returns A promise that resolves when the delay elapses.
146
- */
147
- function delay(time, abort) {
148
- return new Promise((resolve, reject) => {
149
- abort?.throwIfAborted();
150
- const onAbort = () => {
151
- clearTimeout(timer);
152
- reject(abort?.reason);
153
- };
154
- const timer = setTimeout(() => {
155
- abort?.removeEventListener("abort", onAbort);
156
- resolve();
157
- }, time);
158
- abort?.addEventListener("abort", onAbort, { once: true });
159
- });
160
- }
161
- /**
162
- * Races a promise against a timeout.
163
- *
164
- * Resolves/rejects with the original promise if it settles in time. If the timeout elapses
165
- * first the returned promise rejects with a {@link TimeoutError}. Aborting via `abort`
166
- * rejects with the signal's reason.
167
- *
168
- * @typeParam T Resolved value type of the wrapped promise.
169
- * @param promise Promise to guard with a timeout.
170
- * @param timeout Timeout in milliseconds; must be greater than `0`.
171
- * @param abort Optional signal used to cancel the wait.
172
- * @returns A promise mirroring `promise` unless the timeout or abort fires first.
173
- * @throws {Error} When `timeout` is not greater than `0`.
174
- */
175
- function timeout(promise, timeout, abort) {
176
- if (timeout <= 0)
177
- throw new Error("Invalid timeout value.");
178
- return new Promise((resolve, reject) => {
179
- abort?.throwIfAborted();
180
- const onAbort = () => {
181
- clearTimeout(timer);
182
- reject(abort?.reason);
183
- };
184
- const timer = setTimeout(() => {
185
- abort?.removeEventListener("abort", onAbort);
186
- reject(new TimeoutError());
187
- }, timeout);
188
- abort?.addEventListener("abort", onAbort, { once: true });
189
- promise
190
- .then(result => resolve(result))
191
- .catch(reason => reject(reason))
192
- .finally(() => {
193
- clearTimeout(timer);
194
- abort?.removeEventListener("abort", onAbort);
195
- });
196
- });
197
- }
198
- /** Thrown by {@link timeout} when the time limit is exceeded. */
199
- class TimeoutError extends Error {
200
- constructor() {
201
- super("Timeout");
202
- this.name = "TimeoutError";
203
- }
204
- }
205
-
206
- var func = /*#__PURE__*/Object.freeze({
207
- __proto__: null,
208
- TimeoutError: TimeoutError,
209
- delay: delay,
210
- minWait: minWait,
211
- minWaitAsync: minWaitAsync,
212
- timeout: timeout
213
- });
214
-
215
- /**
216
- * Returns a word combined with the grammatical ending that agrees with the given count.
217
- *
218
- * Implements Russian-style pluralization rules: the ending is chosen depending on
219
- * whether the count ends in 1, in 2–4, or in 0/5–9 (with 11–14 treated as the "five" form).
220
- *
221
- * @param count Quantity that the word refers to.
222
- * @param word Word stem to which the ending is appended.
223
- * @param one Ending used for counts ending in 1 (but not 11).
224
- * @param two Ending used for counts ending in 2–4 (but not 12–14).
225
- * @param five Ending used for counts ending in 0, 5–9 and 11–20.
226
- * @returns The word with the appropriate ending appended.
227
- * @example
228
- * getWordEnd(1, "товар", "", "а", "ов"); // "товар"
229
- * getWordEnd(3, "товар", "", "а", "ов"); // "товара"
230
- * getWordEnd(5, "товар", "", "а", "ов"); // "товаров"
231
- */
232
- function getWordEnd(count, word, one, two, five) {
233
- const tt = count % 100;
234
- if (tt >= 5 && tt <= 20)
235
- return word + (five || "");
236
- const t = count % 10;
237
- return (t === 1 ?
238
- (word + (one || "")) : ((t >= 2 && t <= 4) ? (word + (two || "")) : (word + (five || ""))));
239
- }
240
-
241
- var word = /*#__PURE__*/Object.freeze({
242
- __proto__: null,
243
- getWordEnd: getWordEnd
244
- });
245
-
246
- /**
247
- * Generates a RFC 4122 UUID v4 string using `crypto.randomUUID()`.
248
- *
249
- * @returns A newly generated UUID string in `xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx` form.
250
- * @example
251
- * createGuid(); // e.g. "3f2a1b4c-9d8e-4a23-b123-456789abcdef"
252
- */
253
- const createGuid = () => crypto.randomUUID();
254
- /** The empty (all-zero) GUID value `"00000000-0000-0000-0000-000000000000"`. */
255
- const empty = "00000000-0000-0000-0000-000000000000";
256
-
257
- var guid = /*#__PURE__*/Object.freeze({
258
- __proto__: null,
259
- createGuid: createGuid,
260
- empty: empty
261
- });
262
-
263
- /**
264
- * Formats a template string by substituting `{...}` placeholders.
265
- *
266
- * When the first argument is an object, placeholders are treated as dot-separated
267
- * property paths resolved against that object (see {@link getProperty}). Otherwise
268
- * placeholders are treated as zero-based indexes into the remaining arguments.
269
- * Unresolved placeholders are replaced with an empty string.
270
- *
271
- * @param template Template containing `{name}` or `{0}` placeholders.
272
- * @param args Either a single model object, or positional arguments.
273
- * @returns The formatted string.
274
- * @example
275
- * formatText("Hello, {name}", { name: "Dmitry" }); // "Hello, Dmitry"
276
- * formatText("Hello, {0}", "Dmitry"); // "Hello, Dmitry"
277
- */
278
- function formatText(template, ...args) {
279
- if (!args.length)
280
- return template;
281
- const obj = typeof args[0] === "object" ? args[0] : null;
282
- return template.replace(/\{([^}]+)\}/g, (_match, key) => {
283
- if (obj)
284
- return getProperty(obj, key) ?? "";
285
- else {
286
- const paramIndex = parseInt(key);
287
- if (!isNaN(paramIndex) && paramIndex < args.length)
288
- return args[paramIndex] ?? "";
289
- }
290
- return "";
291
- });
292
- }
293
-
294
- Object.prop = function (obj, path) {
295
- return getProperty(obj, path);
296
- };
297
- Object.hasProp = function (obj, path) {
298
- return hasProperty(obj, path);
299
- };
300
- String.prototype.format = function (...args) {
301
- return formatText(this.toString(), ...args);
302
- };
303
-
304
- exports.FuncHelper = func;
305
- exports.Guid = guid;
306
12
  exports.ObjectHelper = object;
307
13
  exports.TypeHelper = type;
14
+ exports.FuncHelper = func;
308
15
  exports.WordHelper = word;
309
- exports.formatText = formatText;
16
+ exports.Guid = guid;
17
+ exports.formatText = string.formatText;
310
18
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../source/helpers/object.ts","../../source/helpers/type.ts","../../source/helpers/func.ts","../../source/helpers/word.ts","../../source/helpers/guid.ts","../../source/helpers/string.ts","../../source/helpers/ext.ts"],"sourcesContent":[null,null,null,null,null,null,null],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;"}
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Wraps a callback so that, when invoked, it runs no sooner than `minTime` milliseconds
3
+ * after this wrapper was created.
4
+ *
5
+ * The deadline is measured from the moment `minWait` is called. If `minTime` is omitted
6
+ * or falsy, the original function is returned unchanged.
7
+ *
8
+ * @param func Callback to defer.
9
+ * @param minTime Minimum delay in milliseconds before the callback may run.
10
+ * @returns A wrapped function with the same arguments as `func`.
11
+ */
12
+ const minWait = (func, minTime) => {
13
+ if (!minTime)
14
+ return func;
15
+ const beginTime = Date.now();
16
+ const ret = (...args) => {
17
+ const rightTime = getRightTime(beginTime, minTime);
18
+ if (rightTime)
19
+ setTimeout(() => func(...args), rightTime);
20
+ else
21
+ func(...args);
22
+ };
23
+ return ret;
24
+ };
25
+ /**
26
+ * Awaits an async operation and guarantees the returned promise settles no sooner than
27
+ * `minTime` milliseconds after invocation, padding with an extra delay when needed.
28
+ *
29
+ * Useful for keeping spinners/loading states visible for a minimum duration. If `minTime`
30
+ * is omitted or falsy, `func` is awaited and its result returned without padding.
31
+ *
32
+ * An already-aborted signal rejects immediately, before `func` runs; aborting later cancels
33
+ * the padding delay (but not `func` itself, which can't be cancelled here).
34
+ *
35
+ * @typeParam TResult Result type produced by `func`.
36
+ * @param func Factory returning the promise to await.
37
+ * @param minTime Minimum total duration in milliseconds.
38
+ * @param abort Optional signal used to cancel the wait.
39
+ * @returns The result produced by `func`.
40
+ */
41
+ async function minWaitAsync(func, minTime, abort) {
42
+ abort?.throwIfAborted();
43
+ if (!minTime)
44
+ return func();
45
+ const beginTime = Date.now();
46
+ const result = await func();
47
+ const rightTime = getRightTime(beginTime, minTime);
48
+ if (rightTime)
49
+ await delay(rightTime, abort);
50
+ return result;
51
+ }
52
+ /** @internal */
53
+ const getRightTime = (start, minTime) => {
54
+ const finishTime = Date.now();
55
+ const w = minTime - (finishTime - start);
56
+ // Skip padding when the leftover is within 10% of `minTime`: the wait is already
57
+ // "close enough", and a sub-tick delay would only add jitter without a visible effect.
58
+ return w > minTime * 0.1 ? w : 0;
59
+ };
60
+ /**
61
+ * Returns a promise that resolves after the given number of milliseconds.
62
+ *
63
+ * If an already-aborted signal is supplied the promise rejects immediately; otherwise
64
+ * aborting before the delay elapses clears the timer and rejects with the abort reason.
65
+ *
66
+ * @param ms Delay in milliseconds; must not be negative. Values above 2147483647 (~24.8 days)
67
+ * overflow the timer and fire on the next tick — a `setTimeout` limitation.
68
+ * @param abort Optional signal used to cancel the delay.
69
+ * @returns A promise that resolves when the delay elapses.
70
+ * @throws {Error} When `ms` is negative.
71
+ */
72
+ function delay(ms, abort) {
73
+ if (ms < 0)
74
+ throw new Error("Invalid delay value.");
75
+ return new Promise((resolve, reject) => {
76
+ abort?.throwIfAborted();
77
+ const onAbort = () => {
78
+ clearTimeout(timer);
79
+ // `onAbort` only runs once the listener has fired, which means `abort` exists.
80
+ reject(abort.reason);
81
+ };
82
+ const timer = setTimeout(() => {
83
+ abort?.removeEventListener("abort", onAbort);
84
+ resolve();
85
+ }, ms);
86
+ abort?.addEventListener("abort", onAbort, { once: true });
87
+ });
88
+ }
89
+ /**
90
+ * Races a promise against a timeout.
91
+ *
92
+ * Resolves/rejects with the original promise if it settles in time. If the timeout elapses
93
+ * first the returned promise rejects with a {@link TimeoutError}. Aborting via `abort`
94
+ * rejects with the signal's reason.
95
+ *
96
+ * @typeParam T Resolved value type of the wrapped promise.
97
+ * @param promise Promise to guard with a timeout.
98
+ * @param ms Timeout in milliseconds; must be greater than `0`. Values above 2147483647
99
+ * (~24.8 days) overflow the timer and fire on the next tick — a `setTimeout` limitation.
100
+ * @param abort Optional signal used to cancel the wait.
101
+ * @returns A promise mirroring `promise` unless the timeout or abort fires first.
102
+ * @throws {Error} When `ms` is not greater than `0`.
103
+ */
104
+ function timeout(promise, ms, abort) {
105
+ if (ms <= 0)
106
+ throw new Error("Invalid timeout value.");
107
+ // Own controller so the `delay` timer can be torn down once the race is decided,
108
+ // independently of the caller's `abort`.
109
+ const timer = new AbortController();
110
+ // Wins the race only by timing out (rejects with TimeoutError). If the timer is cancelled
111
+ // instead — the guarded work settled, or the caller aborted — `delay` rejects, and we turn
112
+ // that into a never-settling promise so `expire` simply stands aside: the race never produces
113
+ // a stray rejection that nobody is listening for.
114
+ const expire = delay(ms, timer.signal).then(() => Promise.reject(new TimeoutError()), () => new Promise(() => { }));
115
+ return abortable(Promise.race([promise, expire]), abort)
116
+ .finally(() => timer.abort());
117
+ }
118
+ /**
119
+ * Makes *waiting* for a promise abortable: rejects with the signal's reason on abort.
120
+ * Does not stop the underlying work the promise performs.
121
+ *
122
+ * If no signal is supplied the promise is awaited as-is. An already-aborted signal rejects
123
+ * immediately; otherwise the abort listener is removed once the promise settles.
124
+ *
125
+ * @typeParam T Resolved value type of the wrapped promise.
126
+ * @param promise Promise (or thenable) whose wait should become abortable.
127
+ * @param abort Optional signal used to cancel the wait.
128
+ * @returns A promise mirroring `promise` unless the abort fires first.
129
+ */
130
+ function abortable(promise, abort) {
131
+ if (!abort)
132
+ return Promise.resolve(promise);
133
+ if (abort.aborted)
134
+ return Promise.reject(abort.reason);
135
+ return new Promise((resolve, reject) => {
136
+ const onAbort = () => reject(abort.reason);
137
+ abort.addEventListener("abort", onAbort, { once: true });
138
+ const cleanup = () => abort.removeEventListener("abort", onAbort);
139
+ Promise.resolve(promise).then(v => { cleanup(); resolve(v); }, e => { cleanup(); reject(e); });
140
+ });
141
+ }
142
+ /** Thrown by {@link timeout} when the time limit is exceeded. */
143
+ class TimeoutError extends Error {
144
+ constructor() {
145
+ super("Timeout");
146
+ this.name = "TimeoutError";
147
+ }
148
+ }
149
+
150
+ export { TimeoutError, abortable, delay, minWait, minWaitAsync, timeout };
151
+ //# sourceMappingURL=func.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"func.js","sources":["../../../../source/helpers/func.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Generates a RFC 4122 UUID v4 string using `crypto.randomUUID()`.
3
+ *
4
+ * @returns A newly generated UUID string in `xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx` form.
5
+ * @example
6
+ * createGuid(); // e.g. "3f2a1b4c-9d8e-4a23-b123-456789abcdef"
7
+ */
8
+ const createGuid = () => crypto.randomUUID();
9
+ /** The empty (all-zero) GUID value `"00000000-0000-0000-0000-000000000000"`. */
10
+ const empty = "00000000-0000-0000-0000-000000000000";
11
+
12
+ export { createGuid, empty };
13
+ //# sourceMappingURL=guid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guid.js","sources":["../../../../source/helpers/guid.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAA;;;;;;AAMG;AACH,MAAM,UAAU,GAAG,MAAc,MAAM,CAAC,UAAU;AAElD;AACA,MAAM,KAAK,GAAG;;;;"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Reads a nested property value from an object by a dot-separated path.
3
+ *
4
+ * @param obj Source object to read from.
5
+ * @param path Dot-separated property path, e.g. `"header.value"`.
6
+ * @returns The resolved value; `null` when `obj` is falsy, or `undefined` when
7
+ * any segment of the path does not exist.
8
+ * @example
9
+ * getProperty({ header: { value: "Item" } }, "header.value"); // "Item"
10
+ */
11
+ function getProperty(obj, path) {
12
+ if (!obj)
13
+ return null;
14
+ const props = path.split('.');
15
+ for (let i = 0; i < props.length; i++) {
16
+ const name = props[i];
17
+ if (obj == null || (typeof obj !== "object" && typeof obj !== "function"))
18
+ return undefined;
19
+ if (!(name in obj))
20
+ return undefined;
21
+ obj = obj[name];
22
+ }
23
+ return obj;
24
+ }
25
+ /**
26
+ * Determines whether an object has a nested property at the given dot-separated path.
27
+ *
28
+ * @param obj Source object to inspect.
29
+ * @param path Dot-separated property path, e.g. `"header.value"`.
30
+ * @returns `true` if every segment of the path exists, otherwise `false`.
31
+ * @example
32
+ * hasProperty({ header: { value: "Item" } }, "header.value"); // true
33
+ */
34
+ function hasProperty(obj, path) {
35
+ if (!obj)
36
+ return false;
37
+ const props = path.split('.');
38
+ for (let i = 0; i < props.length; i++) {
39
+ const name = props[i];
40
+ if (obj == null || (typeof obj !== "object" && typeof obj !== "function"))
41
+ return false;
42
+ if (!(name in obj))
43
+ return false;
44
+ obj = obj[name];
45
+ }
46
+ return true;
47
+ }
48
+
49
+ export { getProperty, hasProperty };
50
+ //# sourceMappingURL=object.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"object.js","sources":["../../../../source/helpers/object.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAA;;;;;;;;;AASG;AACH,SAAS,WAAW,CAAC,GAAQ,EAAE,IAAY,EAAA;AAC1C,IAAA,IAAI,CAAC,GAAG;AACP,QAAA,OAAO,IAAI;IAEZ,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;AAE7B,IAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACtC,QAAA,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC;AACrB,QAAA,IAAI,GAAG,IAAI,IAAI,KAAK,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAO,GAAG,KAAK,UAAU,CAAC;AACxE,YAAA,OAAO,SAAS;AAEjB,QAAA,IAAI,EAAE,IAAI,IAAI,GAAG,CAAC;AACjB,YAAA,OAAO,SAAS;AAEjB,QAAA,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC;IAChB;AAEA,IAAA,OAAO,GAAG;AACX;AAEA;;;;;;;;AAQG;AACH,SAAS,WAAW,CAAC,GAAQ,EAAE,IAAY,EAAA;AAC1C,IAAA,IAAI,CAAC,GAAG;AACP,QAAA,OAAO,KAAK;IAEb,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;AAE7B,IAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACtC,QAAA,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC;AACrB,QAAA,IAAI,GAAG,IAAI,IAAI,KAAK,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAO,GAAG,KAAK,UAAU,CAAC;AACxE,YAAA,OAAO,KAAK;AAEb,QAAA,IAAI,EAAE,IAAI,IAAI,GAAG,CAAC;AACjB,YAAA,OAAO,KAAK;AAEb,QAAA,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC;IAChB;AAEA,IAAA,OAAO,IAAI;AACZ;;;;"}
@@ -0,0 +1,35 @@
1
+ import { getProperty } from './object.js';
2
+
3
+ /**
4
+ * Formats a template string by substituting `{...}` placeholders.
5
+ *
6
+ * When the first argument is an object, placeholders are treated as dot-separated
7
+ * property paths resolved against that object (see {@link getProperty}). Otherwise
8
+ * placeholders are treated as zero-based indexes into the remaining arguments.
9
+ * Unresolved placeholders are replaced with an empty string.
10
+ *
11
+ * @param template Template containing `{name}` or `{0}` placeholders.
12
+ * @param args Either a single model object, or positional arguments.
13
+ * @returns The formatted string.
14
+ * @example
15
+ * formatText("Hello, {name}", { name: "Dmitry" }); // "Hello, Dmitry"
16
+ * formatText("Hello, {0}", "Dmitry"); // "Hello, Dmitry"
17
+ */
18
+ function formatText(template, ...args) {
19
+ if (!args.length)
20
+ return template;
21
+ const obj = typeof args[0] === "object" ? args[0] : null;
22
+ return template.replace(/\{([^}]+)\}/g, (_match, key) => {
23
+ if (obj)
24
+ return getProperty(obj, key) ?? "";
25
+ else {
26
+ const paramIndex = parseInt(key);
27
+ if (!isNaN(paramIndex) && paramIndex < args.length)
28
+ return args[paramIndex] ?? "";
29
+ }
30
+ return "";
31
+ });
32
+ }
33
+
34
+ export { formatText };
35
+ //# sourceMappingURL=string.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"string.js","sources":["../../../../source/helpers/string.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAEA;;;;;;;;;;;;;;AAcG;AACH,SAAS,UAAU,CAAC,QAAgB,EAAE,GAAG,IAAW,EAAA;IACnD,IAAI,CAAC,IAAI,CAAC,MAAM;AAAE,QAAA,OAAO,QAAQ;IAEjC,MAAM,GAAG,GAAG,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI;IAExD,OAAO,QAAQ,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,MAAM,EAAE,GAAG,KAAI;AACvD,QAAA,IAAI,GAAG;YAAE,OAAO,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE;aACtC;AACJ,YAAA,MAAM,UAAU,GAAG,QAAQ,CAAC,GAAG,CAAC;YAChC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,IAAI,CAAC,MAAM;AACjD,gBAAA,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE;QAC/B;AAEA,QAAA,OAAO,EAAE;AACV,IAAA,CAAC,CAAC;AACH;;;;"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Determines whether the given value is a function.
3
+ *
4
+ * @param value Value to test.
5
+ * @returns `true` if the value is a function, otherwise `false`.
6
+ */
7
+ function isFunction(value) {
8
+ return (typeof value === "function");
9
+ }
10
+ /**
11
+ * Determines whether the given value is a string.
12
+ *
13
+ * Returns `true` for both string primitives and `String` object instances.
14
+ *
15
+ * @param value Value to test.
16
+ * @returns `true` if the value is a string, otherwise `false`.
17
+ */
18
+ function isString(value) {
19
+ return (typeof value === "string" || value instanceof String);
20
+ }
21
+
22
+ export { isFunction, isString };
23
+ //# sourceMappingURL=type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type.js","sources":["../../../../source/helpers/type.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAA;;;;;AAKG;AACH,SAAS,UAAU,CAAC,KAAU,EAAA;AAC7B,IAAA,QAAQ,OAAO,KAAK,KAAK,UAAU;AACpC;AAEA;;;;;;;AAOG;AACH,SAAS,QAAQ,CAAC,KAAU,EAAA;IAC3B,QAAQ,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,YAAY,MAAM;AAC7D;;;;"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Returns a word combined with the grammatical ending that agrees with the given count.
3
+ *
4
+ * Implements Russian-style pluralization rules: the ending is chosen depending on
5
+ * whether the count ends in 1, in 2–4, or in 0/5–9 (with 11–14 treated as the "five" form).
6
+ *
7
+ * @param count Quantity that the word refers to.
8
+ * @param word Word stem to which the ending is appended.
9
+ * @param one Ending used for counts ending in 1 (but not 11).
10
+ * @param two Ending used for counts ending in 2–4 (but not 12–14).
11
+ * @param five Ending used for counts ending in 0, 5–9 and 11–20.
12
+ * @returns The word with the appropriate ending appended.
13
+ * @example
14
+ * getWordEnd(1, "товар", "", "а", "ов"); // "товар"
15
+ * getWordEnd(3, "товар", "", "а", "ов"); // "товара"
16
+ * getWordEnd(5, "товар", "", "а", "ов"); // "товаров"
17
+ */
18
+ function getWordEnd(count, word, one, two, five) {
19
+ const tt = count % 100;
20
+ if (tt >= 5 && tt <= 20)
21
+ return word + (five || "");
22
+ const t = count % 10;
23
+ return (t === 1 ?
24
+ (word + (one || "")) : ((t >= 2 && t <= 4) ? (word + (two || "")) : (word + (five || ""))));
25
+ }
26
+
27
+ export { getWordEnd };
28
+ //# sourceMappingURL=word.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"word.js","sources":["../../../../source/helpers/word.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;AAgBG;AACH,SAAS,UAAU,CAAC,KAAa,EAAE,IAAY,EAAE,GAAY,EAAE,GAAY,EAAE,IAAa,EAAA;AACzF,IAAA,MAAM,EAAE,GAAG,KAAK,GAAG,GAAG;AACtB,IAAA,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE;AACtB,QAAA,OAAO,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;AAE3B,IAAA,MAAM,CAAC,GAAG,KAAK,GAAG,EAAE;AAEpB,IAAA,QAAQ,CAAC,KAAK,CAAC;SACb,IAAI,IAAI,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,GAAG,IAAI,EAAE,CAAC,KAAK,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;AAE5F;;;;"}