yummies 7.19.4 → 7.20.1
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/assert.cjs +1 -1
- package/assert.cjs.map +1 -1
- package/assert.js +1 -1
- package/assert.js.map +1 -1
- package/async.cjs +147 -137
- package/async.cjs.map +1 -1
- package/async.d.ts +98 -131
- package/async.js +147 -137
- package/async.js.map +1 -1
- package/common.cjs +3 -1
- package/common.cjs.map +1 -1
- package/common.d.ts +18 -24
- package/common.js +3 -1
- package/common.js.map +1 -1
- package/complex.cjs +1 -0
- package/complex.cjs.map +1 -1
- package/complex.js +1 -0
- package/complex.js.map +1 -1
- package/cookie.cjs +1 -1
- package/cookie.cjs.map +1 -1
- package/cookie.d.ts +0 -18
- package/cookie.js +1 -1
- package/cookie.js.map +1 -1
- package/css-cx.cjs +78 -0
- package/css-cx.cjs.map +1 -0
- package/css-cx.d.ts +69 -0
- package/css-cx.js +74 -0
- package/css-cx.js.map +1 -0
- package/css.cjs +32 -111
- package/css.cjs.map +1 -1
- package/css.d.ts +32 -42
- package/css.js +30 -107
- package/css.js.map +1 -1
- package/data.cjs +60 -50
- package/data.cjs.map +1 -1
- package/data.d.ts +21 -34
- package/data.js +60 -50
- package/data.js.map +1 -1
- package/date-time.cjs +104 -98
- package/date-time.cjs.map +1 -1
- package/date-time.d.ts +51 -57
- package/date-time.js +104 -97
- package/date-time.js.map +1 -1
- package/device.cjs +14 -19
- package/device.cjs.map +1 -1
- package/device.d.ts +15 -26
- package/device.js +14 -19
- package/device.js.map +1 -1
- package/encodings.cjs +1 -1
- package/encodings.cjs.map +1 -1
- package/encodings.d.ts +0 -17
- package/encodings.js +1 -1
- package/encodings.js.map +1 -1
- package/errors.cjs +1 -18
- package/errors.cjs.map +1 -1
- package/errors.d.ts +0 -17
- package/errors.js +1 -17
- package/errors.js.map +1 -1
- package/file.cjs +3 -17
- package/file.cjs.map +1 -1
- package/file.d.ts +1 -16
- package/file.js +3 -17
- package/file.js.map +1 -1
- package/format.cjs +1 -1
- package/format.cjs.map +1 -1
- package/format.js +1 -1
- package/format.js.map +1 -1
- package/html.cjs +112 -175
- package/html.cjs.map +1 -1
- package/html.d.ts +58 -57
- package/html.js +111 -172
- package/html.js.map +1 -1
- package/id-nanoid.cjs +36 -0
- package/id-nanoid.cjs.map +1 -0
- package/id-nanoid.d.ts +26 -0
- package/id-nanoid.js +32 -0
- package/id-nanoid.js.map +1 -0
- package/id.cjs +10 -45
- package/id.cjs.map +1 -1
- package/id.d.ts +27 -36
- package/id.js +6 -40
- package/id.js.map +1 -1
- package/imports.cjs +3 -18
- package/imports.cjs.map +1 -1
- package/imports.d.ts +1 -16
- package/imports.js +3 -17
- package/imports.js.map +1 -1
- package/math.cjs +16 -12
- package/math.cjs.map +1 -1
- package/math.d.ts +9 -24
- package/math.js +16 -12
- package/math.js.map +1 -1
- package/media.cjs +88 -89
- package/media.cjs.map +1 -1
- package/media.d.ts +72 -80
- package/media.js +88 -88
- package/media.js.map +1 -1
- package/mobx.cjs +0 -1
- package/mobx.cjs.map +1 -1
- package/mobx.js.map +1 -1
- package/ms.cjs +3 -17
- package/ms.cjs.map +1 -1
- package/ms.d.ts +1 -16
- package/ms.js +3 -17
- package/ms.js.map +1 -1
- package/number.cjs +1 -17
- package/number.cjs.map +1 -1
- package/number.d.ts +0 -16
- package/number.js +1 -17
- package/number.js.map +1 -1
- package/package.json +6 -6
- package/parser.cjs +1 -1
- package/parser.cjs.map +1 -1
- package/parser.js +1 -1
- package/parser.js.map +1 -1
- package/price.cjs +1 -1
- package/price.cjs.map +1 -1
- package/price.d.ts +0 -16
- package/price.js +1 -1
- package/price.js.map +1 -1
- package/random.cjs +37 -39
- package/random.cjs.map +1 -1
- package/random.d.ts +31 -40
- package/random.js +37 -39
- package/random.js.map +1 -1
- package/react.cjs +0 -1
- package/react.cjs.map +1 -1
- package/react.js.map +1 -1
- package/sanitize-html.cjs +82 -0
- package/sanitize-html.cjs.map +1 -0
- package/sanitize-html.d.ts +28 -0
- package/sanitize-html.js +79 -0
- package/sanitize-html.js.map +1 -0
- package/sound.cjs +1 -17
- package/sound.cjs.map +1 -1
- package/sound.d.ts +0 -16
- package/sound.js +1 -17
- package/sound.js.map +1 -1
- package/storage.cjs +7 -5
- package/storage.cjs.map +1 -1
- package/storage.d.ts +3 -17
- package/storage.js +7 -5
- package/storage.js.map +1 -1
- package/text.cjs +3 -17
- package/text.cjs.map +1 -1
- package/text.d.ts +1 -16
- package/text.js +3 -17
- package/text.js.map +1 -1
- package/type-guard.cjs +38 -1
- package/type-guard.cjs.map +1 -1
- package/type-guard.d.ts +38 -0
- package/type-guard.js +38 -1
- package/type-guard.js.map +1 -1
- package/types.d.ts +20 -1
- package/types.global.d.ts +19 -0
- package/vibrate.cjs +1 -17
- package/vibrate.cjs.map +1 -1
- package/vibrate.d.ts +0 -16
- package/vibrate.js +1 -17
- package/vibrate.js.map +1 -1
- /package/{chunk-pbuEa-1d.js → chunk-D7D4PA-g.js} +0 -0
- /package/{chunk-CZWwpsFl.cjs → chunk-DakpK96I.cjs} +0 -0
package/html.js
CHANGED
|
@@ -1,64 +1,41 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { sanitizeHtml } from "./sanitize-html.js";
|
|
2
2
|
import { blobToUrl } from "yummies/media";
|
|
3
|
-
//#region src/html.ts
|
|
3
|
+
//#region src/html/calc-scrollbar-width.ts
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
* # yummies/html
|
|
7
|
-
*
|
|
8
|
-
* ## Description
|
|
9
|
-
*
|
|
10
|
-
* DOM-centric utilities: sanitizing HTML with **DOMPurify**, computed style probes, downloads via
|
|
11
|
-
* temporary anchors, and small string helpers for safe markup. Prefer these over `innerHTML` with
|
|
12
|
-
* raw user input; keep CSP and server-side validation as the real security boundary.
|
|
13
|
-
*
|
|
14
|
-
* ## Usage
|
|
15
|
-
*
|
|
16
|
-
* ```ts
|
|
17
|
-
* import { getComputedColor } from "yummies/html";
|
|
18
|
-
* ```
|
|
19
|
-
*/
|
|
20
|
-
/**
|
|
21
|
-
* Extracts an RGB value from any valid CSS color.
|
|
22
|
-
*
|
|
23
|
-
* Not recommended for frequent use because it triggers a reflow.
|
|
5
|
+
* Calculates the scrollbar width.
|
|
24
6
|
*/
|
|
25
|
-
var
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
7
|
+
var calcScrollbarWidth = (elementToAppend = document.body) => {
|
|
8
|
+
const outer = document.createElement("div");
|
|
9
|
+
outer.style.visibility = "hidden";
|
|
10
|
+
outer.style.width = "100px";
|
|
11
|
+
outer.style.overflow = "scroll";
|
|
12
|
+
elementToAppend.append(outer);
|
|
13
|
+
const inner = document.createElement("div");
|
|
14
|
+
inner.style.width = "100%";
|
|
15
|
+
outer.append(inner);
|
|
16
|
+
const scrollbarWidth = outer.offsetWidth - inner.offsetWidth;
|
|
17
|
+
outer.parentNode?.removeChild(outer);
|
|
18
|
+
return scrollbarWidth;
|
|
35
19
|
};
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region src/html/check-element-has-parent.ts
|
|
36
22
|
/**
|
|
37
|
-
*
|
|
23
|
+
* Checks whether the element is nested inside the provided parent element.
|
|
38
24
|
*
|
|
39
25
|
* @example
|
|
40
26
|
* ```ts
|
|
41
|
-
*
|
|
27
|
+
* checkElementHasParent(childElement, modalElement);
|
|
42
28
|
* ```
|
|
43
29
|
*/
|
|
44
|
-
var
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
document.body.append(a);
|
|
51
|
-
a.click();
|
|
52
|
-
a.remove();
|
|
30
|
+
var checkElementHasParent = (element, parent) => {
|
|
31
|
+
let node = element;
|
|
32
|
+
if (!parent) return false;
|
|
33
|
+
while (node != null) if (node === parent) return true;
|
|
34
|
+
else node = node.parentElement;
|
|
35
|
+
return false;
|
|
53
36
|
};
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
*/
|
|
57
|
-
function wrapTextToTagLink(link) {
|
|
58
|
-
const descr = String(link).replace(/^(https?:\/{0,2})?(w{3}\.)?/, "www.");
|
|
59
|
-
if (!/^https?:\/{2}/.test(link)) link = `http://${link}`;
|
|
60
|
-
return `<a href=${link} target="_blank">${descr}</a>`;
|
|
61
|
-
}
|
|
37
|
+
//#endregion
|
|
38
|
+
//#region src/html/collect-offset-top.ts
|
|
62
39
|
/**
|
|
63
40
|
* Collects the cumulative `offsetTop` value through the element parent chain.
|
|
64
41
|
*
|
|
@@ -76,19 +53,66 @@ var collectOffsetTop = (element) => {
|
|
|
76
53
|
}
|
|
77
54
|
return offsetTop;
|
|
78
55
|
};
|
|
56
|
+
//#endregion
|
|
57
|
+
//#region src/html/download-using-anchor.ts
|
|
79
58
|
/**
|
|
80
|
-
*
|
|
59
|
+
* Triggers a file download by creating and clicking a temporary anchor element.
|
|
81
60
|
*
|
|
82
61
|
* @example
|
|
83
62
|
* ```ts
|
|
84
|
-
*
|
|
63
|
+
* downloadUsingAnchor('/report.pdf', 'report.pdf');
|
|
85
64
|
* ```
|
|
86
65
|
*/
|
|
87
|
-
var
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
66
|
+
var downloadUsingAnchor = (urlOrBlob, fileName) => {
|
|
67
|
+
const url = blobToUrl(urlOrBlob);
|
|
68
|
+
const a = document.createElement("a");
|
|
69
|
+
a.href = url;
|
|
70
|
+
a.download = fileName ?? "file";
|
|
71
|
+
a.target = "_blank";
|
|
72
|
+
document.body.append(a);
|
|
73
|
+
a.click();
|
|
74
|
+
a.remove();
|
|
91
75
|
};
|
|
76
|
+
//#endregion
|
|
77
|
+
//#region src/html/get-computed-color.ts
|
|
78
|
+
/**
|
|
79
|
+
* Extracts an RGB value from any valid CSS color.
|
|
80
|
+
*
|
|
81
|
+
* Not recommended for frequent use because it triggers a reflow.
|
|
82
|
+
*/
|
|
83
|
+
var getComputedColor = (color) => {
|
|
84
|
+
if (!color) return null;
|
|
85
|
+
const d = document.createElement("div");
|
|
86
|
+
d.style.color = color;
|
|
87
|
+
document.body.append(d);
|
|
88
|
+
const rgbcolor = globalThis.getComputedStyle(d).color;
|
|
89
|
+
const match = /rgba?\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*\d+[.d+]*)*\)/g.exec(rgbcolor);
|
|
90
|
+
d.remove();
|
|
91
|
+
if (!match) return null;
|
|
92
|
+
return `${match[1]}, ${match[2]}, ${match[3]}`;
|
|
93
|
+
};
|
|
94
|
+
//#endregion
|
|
95
|
+
//#region src/html/get-element-inner-height.ts
|
|
96
|
+
/**
|
|
97
|
+
* Calculates the inner height of an HTML element, accounting for padding.
|
|
98
|
+
*/
|
|
99
|
+
function getElementInnerHeight(element) {
|
|
100
|
+
const { clientHeight } = element;
|
|
101
|
+
const { paddingTop, paddingBottom } = getComputedStyle(element);
|
|
102
|
+
return clientHeight - Number.parseFloat(paddingTop) - Number.parseFloat(paddingBottom);
|
|
103
|
+
}
|
|
104
|
+
//#endregion
|
|
105
|
+
//#region src/html/get-element-inner-width.ts
|
|
106
|
+
/**
|
|
107
|
+
* Calculates the inner width of an HTML element, accounting for padding.
|
|
108
|
+
*/
|
|
109
|
+
function getElementInnerWidth(el) {
|
|
110
|
+
const { clientWidth } = el;
|
|
111
|
+
const { paddingLeft, paddingRight } = getComputedStyle(el);
|
|
112
|
+
return clientWidth - Number.parseFloat(paddingLeft) - Number.parseFloat(paddingRight);
|
|
113
|
+
}
|
|
114
|
+
//#endregion
|
|
115
|
+
//#region src/html/global-scroll-into-view-for-y.ts
|
|
92
116
|
/**
|
|
93
117
|
* Scrolls the page vertically to the viewport section containing the target element.
|
|
94
118
|
*
|
|
@@ -108,90 +132,45 @@ var globalScrollIntoViewForY = (node) => {
|
|
|
108
132
|
behavior: "smooth"
|
|
109
133
|
});
|
|
110
134
|
};
|
|
135
|
+
//#endregion
|
|
136
|
+
//#region src/html/is-prefers-dark-theme.ts
|
|
111
137
|
/**
|
|
112
|
-
*
|
|
138
|
+
* Checks whether the user prefers a dark color scheme.
|
|
113
139
|
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```ts
|
|
142
|
+
* const prefersDark = isPrefersDarkTheme();
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
var isPrefersDarkTheme = () => !!globalThis.matchMedia?.("(prefers-color-scheme: dark)")?.matches;
|
|
146
|
+
//#endregion
|
|
147
|
+
//#region src/html/is-prefers-light-theme.ts
|
|
148
|
+
/**
|
|
149
|
+
* Checks whether the user prefers a light color scheme.
|
|
116
150
|
*
|
|
117
151
|
* @example
|
|
118
152
|
* ```ts
|
|
119
|
-
*
|
|
153
|
+
* const prefersLight = isPrefersLightTheme();
|
|
120
154
|
* ```
|
|
121
155
|
*/
|
|
122
|
-
var
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
...config
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
sanitizeHtml.defaults = {
|
|
129
|
-
ALLOWED_TAGS: [
|
|
130
|
-
"a",
|
|
131
|
-
"article",
|
|
132
|
-
"b",
|
|
133
|
-
"blockquote",
|
|
134
|
-
"br",
|
|
135
|
-
"caption",
|
|
136
|
-
"code",
|
|
137
|
-
"del",
|
|
138
|
-
"details",
|
|
139
|
-
"div",
|
|
140
|
-
"em",
|
|
141
|
-
"h1",
|
|
142
|
-
"h2",
|
|
143
|
-
"h3",
|
|
144
|
-
"h4",
|
|
145
|
-
"h5",
|
|
146
|
-
"h6",
|
|
147
|
-
"hr",
|
|
148
|
-
"i",
|
|
149
|
-
"img",
|
|
150
|
-
"ins",
|
|
151
|
-
"kbd",
|
|
152
|
-
"li",
|
|
153
|
-
"main",
|
|
154
|
-
"ol",
|
|
155
|
-
"p",
|
|
156
|
-
"pre",
|
|
157
|
-
"section",
|
|
158
|
-
"span",
|
|
159
|
-
"strong",
|
|
160
|
-
"sub",
|
|
161
|
-
"summary",
|
|
162
|
-
"sup",
|
|
163
|
-
"table",
|
|
164
|
-
"tbody",
|
|
165
|
-
"td",
|
|
166
|
-
"th",
|
|
167
|
-
"thead",
|
|
168
|
-
"tr",
|
|
169
|
-
"u",
|
|
170
|
-
"ul"
|
|
171
|
-
],
|
|
172
|
-
ALLOWED_ATTR: [
|
|
173
|
-
"href",
|
|
174
|
-
"target",
|
|
175
|
-
"name",
|
|
176
|
-
"src",
|
|
177
|
-
"class"
|
|
178
|
-
]
|
|
179
|
-
};
|
|
156
|
+
var isPrefersLightTheme = () => !!globalThis.matchMedia?.("(prefers-color-scheme: light)")?.matches;
|
|
157
|
+
//#endregion
|
|
158
|
+
//#region src/html/skip-event.ts
|
|
180
159
|
/**
|
|
181
|
-
*
|
|
160
|
+
* Prevents the default browser action and stops event propagation.
|
|
182
161
|
*
|
|
183
162
|
* @example
|
|
184
163
|
* ```ts
|
|
185
|
-
*
|
|
164
|
+
* button.addEventListener('click', (event) => skipEvent(event));
|
|
186
165
|
* ```
|
|
187
166
|
*/
|
|
188
|
-
var
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
while (node != null) if (node === parent) return true;
|
|
192
|
-
else node = node.parentElement;
|
|
167
|
+
var skipEvent = (e) => {
|
|
168
|
+
e.preventDefault();
|
|
169
|
+
e.stopPropagation();
|
|
193
170
|
return false;
|
|
194
171
|
};
|
|
172
|
+
//#endregion
|
|
173
|
+
//#region src/html/start-view-transition-safety.ts
|
|
195
174
|
/**
|
|
196
175
|
* Executes a function within a view transition if supported by the browser.
|
|
197
176
|
*
|
|
@@ -204,56 +183,16 @@ var startViewTransitionSafety = (fn, params) => {
|
|
|
204
183
|
if (typeof document !== "undefined" && document.startViewTransition && !params?.disabled) return document.startViewTransition(fn);
|
|
205
184
|
fn();
|
|
206
185
|
};
|
|
186
|
+
//#endregion
|
|
187
|
+
//#region src/html/wrap-text-to-tag-link.ts
|
|
207
188
|
/**
|
|
208
|
-
*
|
|
209
|
-
*/
|
|
210
|
-
var calcScrollbarWidth = (elementToAppend = document.body) => {
|
|
211
|
-
const outer = document.createElement("div");
|
|
212
|
-
outer.style.visibility = "hidden";
|
|
213
|
-
outer.style.width = "100px";
|
|
214
|
-
outer.style.overflow = "scroll";
|
|
215
|
-
elementToAppend.append(outer);
|
|
216
|
-
const inner = document.createElement("div");
|
|
217
|
-
inner.style.width = "100%";
|
|
218
|
-
outer.append(inner);
|
|
219
|
-
const scrollbarWidth = outer.offsetWidth - inner.offsetWidth;
|
|
220
|
-
outer.parentNode?.removeChild(outer);
|
|
221
|
-
return scrollbarWidth;
|
|
222
|
-
};
|
|
223
|
-
/**
|
|
224
|
-
* Calculates the inner height of an HTML element, accounting for padding.
|
|
225
|
-
*/
|
|
226
|
-
function getElementInnerHeight(element) {
|
|
227
|
-
const { clientHeight } = element;
|
|
228
|
-
const { paddingTop, paddingBottom } = getComputedStyle(element);
|
|
229
|
-
return clientHeight - Number.parseFloat(paddingTop) - Number.parseFloat(paddingBottom);
|
|
230
|
-
}
|
|
231
|
-
/**
|
|
232
|
-
* Calculates the inner width of an HTML element, accounting for padding.
|
|
189
|
+
* Surrounds string in an anchor tag
|
|
233
190
|
*/
|
|
234
|
-
function
|
|
235
|
-
const
|
|
236
|
-
|
|
237
|
-
return
|
|
191
|
+
function wrapTextToTagLink(link) {
|
|
192
|
+
const descr = String(link).replace(/^(https?:\/{0,2})?(w{3}\.)?/, "www.");
|
|
193
|
+
if (!/^https?:\/{2}/.test(link)) link = `http://${link}`;
|
|
194
|
+
return `<a href=${link} target="_blank">${descr}</a>`;
|
|
238
195
|
}
|
|
239
|
-
/**
|
|
240
|
-
* Checks whether the user prefers a dark color scheme.
|
|
241
|
-
*
|
|
242
|
-
* @example
|
|
243
|
-
* ```ts
|
|
244
|
-
* const prefersDark = isPrefersDarkTheme();
|
|
245
|
-
* ```
|
|
246
|
-
*/
|
|
247
|
-
var isPrefersDarkTheme = () => !!globalThis.matchMedia?.("(prefers-color-scheme: dark)")?.matches;
|
|
248
|
-
/**
|
|
249
|
-
* Checks whether the user prefers a light color scheme.
|
|
250
|
-
*
|
|
251
|
-
* @example
|
|
252
|
-
* ```ts
|
|
253
|
-
* const prefersLight = isPrefersLightTheme();
|
|
254
|
-
* ```
|
|
255
|
-
*/
|
|
256
|
-
var isPrefersLightTheme = () => !!globalThis.matchMedia?.("(prefers-color-scheme: light)")?.matches;
|
|
257
196
|
//#endregion
|
|
258
197
|
export { calcScrollbarWidth, checkElementHasParent, collectOffsetTop, downloadUsingAnchor, getComputedColor, getElementInnerHeight, getElementInnerWidth, globalScrollIntoViewForY, isPrefersDarkTheme, isPrefersLightTheme, sanitizeHtml, skipEvent, startViewTransitionSafety, wrapTextToTagLink };
|
|
259
198
|
|
package/html.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html.js","names":[],"sources":["../src/html.ts"],"sourcesContent":["/**\n * ---header-docs-section---\n * # yummies/html\n *\n * ## Description\n *\n * DOM-centric utilities: sanitizing HTML with **DOMPurify**, computed style probes, downloads via\n * temporary anchors, and small string helpers for safe markup. Prefer these over `innerHTML` with\n * raw user input; keep CSP and server-side validation as the real security boundary.\n *\n * ## Usage\n *\n * ```ts\n * import { getComputedColor } from \"yummies/html\";\n * ```\n */\n\nimport DOMPurify, { type Config as DOMPurifyConfig } from 'dompurify';\nimport { blobToUrl } from 'yummies/media';\nimport type { Maybe } from 'yummies/types';\n\n/**\n * Extracts an RGB value from any valid CSS color.\n *\n * Not recommended for frequent use because it triggers a reflow.\n */\nexport const getComputedColor = (color?: string): string | null => {\n if (!color) return null;\n\n const d = document.createElement('div');\n d.style.color = color;\n document.body.append(d);\n const rgbcolor = globalThis.getComputedStyle(d).color;\n const match =\n /rgba?\\((\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(,\\s*\\d+[.d+]*)*\\)/g.exec(rgbcolor);\n\n d.remove();\n\n if (!match) return null;\n\n return `${match[1]}, ${match[2]}, ${match[3]}`;\n};\n\n/**\n * Triggers a file download by creating and clicking a temporary anchor element.\n *\n * @example\n * ```ts\n * downloadUsingAnchor('/report.pdf', 'report.pdf');\n * ```\n */\nexport const downloadUsingAnchor = (\n urlOrBlob: string | Blob,\n fileName?: string,\n) => {\n const url = blobToUrl(urlOrBlob);\n\n const a = document.createElement('a');\n a.href = url;\n\n a.download = fileName ?? 'file';\n\n a.target = '_blank';\n\n document.body.append(a);\n\n a.click();\n\n a.remove();\n};\n\n/**\n * Surrounds string in an anchor tag\n */\nexport function wrapTextToTagLink(link: string) {\n const descr = String(link).replace(/^(https?:\\/{0,2})?(w{3}\\.)?/, 'www.');\n if (!/^https?:\\/{2}/.test(link)) link = `http://${link}`;\n return `<a href=${link} target=\"_blank\">${descr}</a>`;\n}\n\n/**\n * Collects the cumulative `offsetTop` value through the element parent chain.\n *\n * @example\n * ```ts\n * const offsetTop = collectOffsetTop(document.getElementById('section'));\n * ```\n */\nexport const collectOffsetTop = (element: HTMLElement | null) => {\n let offsetTop = 0;\n let node = element;\n\n while (node != null) {\n offsetTop += node.offsetTop;\n node = node.parentElement;\n }\n\n return offsetTop;\n};\n\n/**\n * Prevents the default browser action and stops event propagation.\n *\n * @example\n * ```ts\n * button.addEventListener('click', (event) => skipEvent(event));\n * ```\n */\nexport const skipEvent = (e: Event) => {\n e.preventDefault();\n e.stopPropagation();\n\n return false;\n};\n\n/**\n * Scrolls the page vertically to the viewport section containing the target element.\n *\n * @example\n * ```ts\n * globalScrollIntoViewForY(document.getElementById('footer')!);\n * ```\n */\nexport const globalScrollIntoViewForY = (node: HTMLElement) => {\n const scrollContainer = document.body;\n const pageHeight = window.innerHeight;\n const nodeBounding = node.getBoundingClientRect();\n const scrollPagesCount = scrollContainer.scrollHeight / pageHeight;\n\n const scrollPageNumber = Math.min(\n Math.max(nodeBounding.top / pageHeight, 1),\n scrollPagesCount,\n );\n\n window.scroll({\n top: scrollPageNumber * pageHeight,\n behavior: 'smooth',\n });\n};\n\ntype SanitizeHtmlFn = ((\n html: Maybe<string>,\n config?: DOMPurifyConfig,\n) => string) & {\n /**\n * Default DOMPurify settings\n */\n defaults: DOMPurifyConfig;\n};\n/**\n * Sanitizes HTML using the default allowlist merged with custom DOMPurify config.\n *\n * Default DOMPurify settings are exposed on `sanitizeHtml.defaults` and can be\n * overridden per call via `config`.\n *\n * @example\n * ```ts\n * sanitizeHtml('<img src=x onerror=alert(1) />');\n * ```\n */\nexport const sanitizeHtml = ((\n html: Maybe<string>,\n config?: DOMPurifyConfig,\n) => {\n return DOMPurify.sanitize(html || '', {\n ...sanitizeHtml.defaults,\n ...config,\n });\n}) as SanitizeHtmlFn;\n\nsanitizeHtml.defaults = {\n ALLOWED_TAGS: [\n 'a',\n 'article',\n 'b',\n 'blockquote',\n 'br',\n 'caption',\n 'code',\n 'del',\n 'details',\n 'div',\n 'em',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'hr',\n 'i',\n 'img',\n 'ins',\n 'kbd',\n 'li',\n 'main',\n 'ol',\n 'p',\n 'pre',\n 'section',\n 'span',\n 'strong',\n 'sub',\n 'summary',\n 'sup',\n 'table',\n 'tbody',\n 'td',\n 'th',\n 'thead',\n 'tr',\n 'u',\n 'ul',\n ],\n ALLOWED_ATTR: ['href', 'target', 'name', 'src', 'class'],\n};\n\n/**\n * Checks whether the element is nested inside the provided parent element.\n *\n * @example\n * ```ts\n * checkElementHasParent(childElement, modalElement);\n * ```\n */\nexport const checkElementHasParent = (\n element: HTMLElement | null,\n parent: Maybe<HTMLElement>,\n) => {\n let node = element;\n\n if (!parent) return false;\n\n while (node != null) {\n if (node === parent) {\n return true;\n } else {\n node = node.parentElement;\n }\n }\n\n return false;\n};\n\n/**\n * Executes a function within a view transition if supported by the browser.\n *\n * @param {VoidFunction} fn - The function to be executed.\n * @returns {ViewTransition} - The result of the executed function.\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/startViewTransition | MDN: Document.startViewTransition}\n */\nexport const startViewTransitionSafety = (\n fn: VoidFunction,\n params?: { disabled?: boolean },\n) => {\n if (\n typeof document !== 'undefined' &&\n document.startViewTransition &&\n !params?.disabled\n ) {\n return document.startViewTransition(fn);\n }\n fn();\n};\n\n/**\n * Calculates the scrollbar width.\n */\nexport const calcScrollbarWidth = (elementToAppend = document.body) => {\n const outer = document.createElement('div');\n\n outer.style.visibility = 'hidden';\n outer.style.width = '100px';\n outer.style.overflow = 'scroll';\n\n elementToAppend.append(outer);\n\n const inner = document.createElement('div');\n inner.style.width = '100%';\n\n outer.append(inner);\n\n const scrollbarWidth = outer.offsetWidth - inner.offsetWidth;\n\n outer.parentNode?.removeChild(outer);\n\n return scrollbarWidth;\n};\n\n/**\n * Calculates the inner height of an HTML element, accounting for padding.\n */\nexport function getElementInnerHeight(element: HTMLElement) {\n const { clientHeight } = element;\n const { paddingTop, paddingBottom } = getComputedStyle(element);\n return (\n clientHeight -\n Number.parseFloat(paddingTop) -\n Number.parseFloat(paddingBottom)\n );\n}\n\n/**\n * Calculates the inner width of an HTML element, accounting for padding.\n */\nexport function getElementInnerWidth(el: HTMLElement) {\n const { clientWidth } = el;\n const { paddingLeft, paddingRight } = getComputedStyle(el);\n return (\n clientWidth -\n Number.parseFloat(paddingLeft) -\n Number.parseFloat(paddingRight)\n );\n}\n\n/**\n * Checks whether the user prefers a dark color scheme.\n *\n * @example\n * ```ts\n * const prefersDark = isPrefersDarkTheme();\n * ```\n */\nexport const isPrefersDarkTheme = () =>\n !!globalThis.matchMedia?.('(prefers-color-scheme: dark)')?.matches;\n\n/**\n * Checks whether the user prefers a light color scheme.\n *\n * @example\n * ```ts\n * const prefersLight = isPrefersLightTheme();\n * ```\n */\nexport const isPrefersLightTheme = () =>\n !!globalThis.matchMedia?.('(prefers-color-scheme: light)')?.matches;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"html.js","names":[],"sources":["../src/html/calc-scrollbar-width.ts","../src/html/check-element-has-parent.ts","../src/html/collect-offset-top.ts","../src/html/download-using-anchor.ts","../src/html/get-computed-color.ts","../src/html/get-element-inner-height.ts","../src/html/get-element-inner-width.ts","../src/html/global-scroll-into-view-for-y.ts","../src/html/is-prefers-dark-theme.ts","../src/html/is-prefers-light-theme.ts","../src/html/skip-event.ts","../src/html/start-view-transition-safety.ts","../src/html/wrap-text-to-tag-link.ts"],"sourcesContent":["/**\n * Calculates the scrollbar width.\n */\nexport const calcScrollbarWidth = (elementToAppend = document.body) => {\n const outer = document.createElement('div');\n\n outer.style.visibility = 'hidden';\n outer.style.width = '100px';\n outer.style.overflow = 'scroll';\n\n elementToAppend.append(outer);\n\n const inner = document.createElement('div');\n inner.style.width = '100%';\n\n outer.append(inner);\n\n const scrollbarWidth = outer.offsetWidth - inner.offsetWidth;\n\n outer.parentNode?.removeChild(outer);\n\n return scrollbarWidth;\n};\n","import type { Maybe } from 'yummies/types';\n\n/**\n * Checks whether the element is nested inside the provided parent element.\n *\n * @example\n * ```ts\n * checkElementHasParent(childElement, modalElement);\n * ```\n */\nexport const checkElementHasParent = (\n element: HTMLElement | null,\n parent: Maybe<HTMLElement>,\n) => {\n let node = element;\n\n if (!parent) return false;\n\n while (node != null) {\n if (node === parent) {\n return true;\n } else {\n node = node.parentElement;\n }\n }\n\n return false;\n};\n","/**\n * Collects the cumulative `offsetTop` value through the element parent chain.\n *\n * @example\n * ```ts\n * const offsetTop = collectOffsetTop(document.getElementById('section'));\n * ```\n */\nexport const collectOffsetTop = (element: HTMLElement | null) => {\n let offsetTop = 0;\n let node = element;\n\n while (node != null) {\n offsetTop += node.offsetTop;\n node = node.parentElement;\n }\n\n return offsetTop;\n};\n","import { blobToUrl } from 'yummies/media';\n\n/**\n * Triggers a file download by creating and clicking a temporary anchor element.\n *\n * @example\n * ```ts\n * downloadUsingAnchor('/report.pdf', 'report.pdf');\n * ```\n */\nexport const downloadUsingAnchor = (\n urlOrBlob: string | Blob,\n fileName?: string,\n) => {\n const url = blobToUrl(urlOrBlob);\n\n const a = document.createElement('a');\n a.href = url;\n\n a.download = fileName ?? 'file';\n\n a.target = '_blank';\n\n document.body.append(a);\n\n a.click();\n\n a.remove();\n};\n","/**\n * Extracts an RGB value from any valid CSS color.\n *\n * Not recommended for frequent use because it triggers a reflow.\n */\nexport const getComputedColor = (color?: string): string | null => {\n if (!color) return null;\n\n const d = document.createElement('div');\n d.style.color = color;\n document.body.append(d);\n const rgbcolor = globalThis.getComputedStyle(d).color;\n const match =\n /rgba?\\((\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(,\\s*\\d+[.d+]*)*\\)/g.exec(rgbcolor);\n\n d.remove();\n\n if (!match) return null;\n\n return `${match[1]}, ${match[2]}, ${match[3]}`;\n};\n","/**\n * Calculates the inner height of an HTML element, accounting for padding.\n */\nexport function getElementInnerHeight(element: HTMLElement) {\n const { clientHeight } = element;\n const { paddingTop, paddingBottom } = getComputedStyle(element);\n return (\n clientHeight -\n Number.parseFloat(paddingTop) -\n Number.parseFloat(paddingBottom)\n );\n}\n","/**\n * Calculates the inner width of an HTML element, accounting for padding.\n */\nexport function getElementInnerWidth(el: HTMLElement) {\n const { clientWidth } = el;\n const { paddingLeft, paddingRight } = getComputedStyle(el);\n return (\n clientWidth -\n Number.parseFloat(paddingLeft) -\n Number.parseFloat(paddingRight)\n );\n}\n","/**\n * Scrolls the page vertically to the viewport section containing the target element.\n *\n * @example\n * ```ts\n * globalScrollIntoViewForY(document.getElementById('footer')!);\n * ```\n */\nexport const globalScrollIntoViewForY = (node: HTMLElement) => {\n const scrollContainer = document.body;\n const pageHeight = window.innerHeight;\n const nodeBounding = node.getBoundingClientRect();\n const scrollPagesCount = scrollContainer.scrollHeight / pageHeight;\n\n const scrollPageNumber = Math.min(\n Math.max(nodeBounding.top / pageHeight, 1),\n scrollPagesCount,\n );\n\n window.scroll({\n top: scrollPageNumber * pageHeight,\n behavior: 'smooth',\n });\n};\n","/**\n * Checks whether the user prefers a dark color scheme.\n *\n * @example\n * ```ts\n * const prefersDark = isPrefersDarkTheme();\n * ```\n */\nexport const isPrefersDarkTheme = () =>\n !!globalThis.matchMedia?.('(prefers-color-scheme: dark)')?.matches;\n","/**\n * Checks whether the user prefers a light color scheme.\n *\n * @example\n * ```ts\n * const prefersLight = isPrefersLightTheme();\n * ```\n */\nexport const isPrefersLightTheme = () =>\n !!globalThis.matchMedia?.('(prefers-color-scheme: light)')?.matches;\n","/**\n * Prevents the default browser action and stops event propagation.\n *\n * @example\n * ```ts\n * button.addEventListener('click', (event) => skipEvent(event));\n * ```\n */\nexport const skipEvent = (e: Event) => {\n e.preventDefault();\n e.stopPropagation();\n\n return false;\n};\n","/**\n * Executes a function within a view transition if supported by the browser.\n *\n * @param {VoidFunction} fn - The function to be executed.\n * @returns {ViewTransition} - The result of the executed function.\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/startViewTransition | MDN: Document.startViewTransition}\n */\nexport const startViewTransitionSafety = (\n fn: VoidFunction,\n params?: { disabled?: boolean },\n) => {\n if (\n typeof document !== 'undefined' &&\n document.startViewTransition &&\n !params?.disabled\n ) {\n return document.startViewTransition(fn);\n }\n fn();\n};\n","/**\n * Surrounds string in an anchor tag\n */\nexport function wrapTextToTagLink(link: string) {\n const descr = String(link).replace(/^(https?:\\/{0,2})?(w{3}\\.)?/, 'www.');\n if (!/^https?:\\/{2}/.test(link)) link = `http://${link}`;\n return `<a href=${link} target=\"_blank\">${descr}</a>`;\n}\n"],"mappings":"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"}
|
package/id-nanoid.cjs
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
let nanoid = require("nanoid");
|
|
3
|
+
//#region src/id/id-nanoid.ts
|
|
4
|
+
/**
|
|
5
|
+
* @internal Separate chunk so nanoid is tree-shaken away when generateId/generateShortId/etc.
|
|
6
|
+
* are not used. Consumers import from `yummies/id` — this module is not a public entry point.
|
|
7
|
+
*/
|
|
8
|
+
var DIGITS = "0123456789";
|
|
9
|
+
var ALPHABET = `abcdefghijklmnopqrstuvwxyz${DIGITS}`;
|
|
10
|
+
/**
|
|
11
|
+
* Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.
|
|
12
|
+
* Length: 6.
|
|
13
|
+
*/
|
|
14
|
+
var generateId = (0, nanoid.customAlphabet)(ALPHABET, 6);
|
|
15
|
+
/**
|
|
16
|
+
* Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.
|
|
17
|
+
* Length: 4.
|
|
18
|
+
*/
|
|
19
|
+
var generateShortId = (0, nanoid.customAlphabet)(ALPHABET, 4);
|
|
20
|
+
/**
|
|
21
|
+
* Uses the alphabet `0123456789`.
|
|
22
|
+
* Length: 6.
|
|
23
|
+
*/
|
|
24
|
+
var generateNumericId = (0, nanoid.customAlphabet)(DIGITS, 6);
|
|
25
|
+
/**
|
|
26
|
+
* Uses the alphabet `0123456789`.
|
|
27
|
+
* Length: 4.
|
|
28
|
+
*/
|
|
29
|
+
var generateNumericShortId = (0, nanoid.customAlphabet)(DIGITS, 4);
|
|
30
|
+
//#endregion
|
|
31
|
+
exports.generateId = generateId;
|
|
32
|
+
exports.generateNumericId = generateNumericId;
|
|
33
|
+
exports.generateNumericShortId = generateNumericShortId;
|
|
34
|
+
exports.generateShortId = generateShortId;
|
|
35
|
+
|
|
36
|
+
//# sourceMappingURL=id-nanoid.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"id-nanoid.cjs","names":[],"sources":["../src/id/id-nanoid.ts"],"sourcesContent":["/**\n * @internal Separate chunk so nanoid is tree-shaken away when generateId/generateShortId/etc.\n * are not used. Consumers import from `yummies/id` — this module is not a public entry point.\n */\n\nimport { customAlphabet } from 'nanoid';\n\nconst DIGITS = '0123456789';\nconst LATIN_CHARS = 'abcdefghijklmnopqrstuvwxyz';\n\nconst ALPHABET = `${LATIN_CHARS}${DIGITS}`;\n\n/**\n * Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.\n * Length: 6.\n */\nexport const generateId = customAlphabet(ALPHABET, 6);\n\n/**\n * Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.\n * Length: 4.\n */\nexport const generateShortId = customAlphabet(ALPHABET, 4);\n\n/**\n * Uses the alphabet `0123456789`.\n * Length: 6.\n */\nexport const generateNumericId = customAlphabet(DIGITS, 6);\n\n/**\n * Uses the alphabet `0123456789`.\n * Length: 4.\n */\nexport const generateNumericShortId = customAlphabet(DIGITS, 4);\n"],"mappings":";;;;;;;AAOA,IAAM,SAAS;AAGf,IAAM,WAAW,6BAAiB;;;;;AAMlC,IAAa,cAAA,GAAA,OAAA,gBAA4B,UAAU,CAAC;;;;;AAMpD,IAAa,mBAAA,GAAA,OAAA,gBAAiC,UAAU,CAAC;;;;;AAMzD,IAAa,qBAAA,GAAA,OAAA,gBAAmC,QAAQ,CAAC;;;;;AAMzD,IAAa,0BAAA,GAAA,OAAA,gBAAwC,QAAQ,CAAC"}
|
package/id-nanoid.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @internal Separate chunk so nanoid is tree-shaken away when generateId/generateShortId/etc.
|
|
3
|
+
* are not used. Consumers import from `yummies/id` — this module is not a public entry point.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.
|
|
7
|
+
* Length: 6.
|
|
8
|
+
*/
|
|
9
|
+
declare const generateId: (size?: number) => string;
|
|
10
|
+
/**
|
|
11
|
+
* Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.
|
|
12
|
+
* Length: 4.
|
|
13
|
+
*/
|
|
14
|
+
declare const generateShortId: (size?: number) => string;
|
|
15
|
+
/**
|
|
16
|
+
* Uses the alphabet `0123456789`.
|
|
17
|
+
* Length: 6.
|
|
18
|
+
*/
|
|
19
|
+
declare const generateNumericId: (size?: number) => string;
|
|
20
|
+
/**
|
|
21
|
+
* Uses the alphabet `0123456789`.
|
|
22
|
+
* Length: 4.
|
|
23
|
+
*/
|
|
24
|
+
declare const generateNumericShortId: (size?: number) => string;
|
|
25
|
+
|
|
26
|
+
export { generateId, generateNumericId, generateNumericShortId, generateShortId };
|
package/id-nanoid.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { customAlphabet } from "nanoid";
|
|
2
|
+
//#region src/id/id-nanoid.ts
|
|
3
|
+
/**
|
|
4
|
+
* @internal Separate chunk so nanoid is tree-shaken away when generateId/generateShortId/etc.
|
|
5
|
+
* are not used. Consumers import from `yummies/id` — this module is not a public entry point.
|
|
6
|
+
*/
|
|
7
|
+
var DIGITS = "0123456789";
|
|
8
|
+
var ALPHABET = `abcdefghijklmnopqrstuvwxyz${DIGITS}`;
|
|
9
|
+
/**
|
|
10
|
+
* Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.
|
|
11
|
+
* Length: 6.
|
|
12
|
+
*/
|
|
13
|
+
var generateId = customAlphabet(ALPHABET, 6);
|
|
14
|
+
/**
|
|
15
|
+
* Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.
|
|
16
|
+
* Length: 4.
|
|
17
|
+
*/
|
|
18
|
+
var generateShortId = customAlphabet(ALPHABET, 4);
|
|
19
|
+
/**
|
|
20
|
+
* Uses the alphabet `0123456789`.
|
|
21
|
+
* Length: 6.
|
|
22
|
+
*/
|
|
23
|
+
var generateNumericId = customAlphabet(DIGITS, 6);
|
|
24
|
+
/**
|
|
25
|
+
* Uses the alphabet `0123456789`.
|
|
26
|
+
* Length: 4.
|
|
27
|
+
*/
|
|
28
|
+
var generateNumericShortId = customAlphabet(DIGITS, 4);
|
|
29
|
+
//#endregion
|
|
30
|
+
export { generateId, generateNumericId, generateNumericShortId, generateShortId };
|
|
31
|
+
|
|
32
|
+
//# sourceMappingURL=id-nanoid.js.map
|
package/id-nanoid.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"id-nanoid.js","names":[],"sources":["../src/id/id-nanoid.ts"],"sourcesContent":["/**\n * @internal Separate chunk so nanoid is tree-shaken away when generateId/generateShortId/etc.\n * are not used. Consumers import from `yummies/id` — this module is not a public entry point.\n */\n\nimport { customAlphabet } from 'nanoid';\n\nconst DIGITS = '0123456789';\nconst LATIN_CHARS = 'abcdefghijklmnopqrstuvwxyz';\n\nconst ALPHABET = `${LATIN_CHARS}${DIGITS}`;\n\n/**\n * Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.\n * Length: 6.\n */\nexport const generateId = customAlphabet(ALPHABET, 6);\n\n/**\n * Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.\n * Length: 4.\n */\nexport const generateShortId = customAlphabet(ALPHABET, 4);\n\n/**\n * Uses the alphabet `0123456789`.\n * Length: 6.\n */\nexport const generateNumericId = customAlphabet(DIGITS, 6);\n\n/**\n * Uses the alphabet `0123456789`.\n * Length: 4.\n */\nexport const generateNumericShortId = customAlphabet(DIGITS, 4);\n"],"mappings":";;;;;;AAOA,IAAM,SAAS;AAGf,IAAM,WAAW,6BAAiB;;;;;AAMlC,IAAa,aAAa,eAAe,UAAU,CAAC;;;;;AAMpD,IAAa,kBAAkB,eAAe,UAAU,CAAC;;;;;AAMzD,IAAa,oBAAoB,eAAe,QAAQ,CAAC;;;;;AAMzD,IAAa,yBAAyB,eAAe,QAAQ,CAAC"}
|
package/id.cjs
CHANGED
|
@@ -1,45 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
require("./
|
|
3
|
-
|
|
4
|
-
//#region src/id.ts
|
|
5
|
-
/**
|
|
6
|
-
* ---header-docs-section---
|
|
7
|
-
* # yummies/id
|
|
8
|
-
*
|
|
9
|
-
* ## Description
|
|
10
|
-
*
|
|
11
|
-
* Fast, URL-friendly identifiers based on **nanoid** with curated alphabets and lengths. Use for
|
|
12
|
-
* client-generated keys, trace ids, or UI instance ids where UUID size is unnecessary. Collisions are
|
|
13
|
-
* unlikely at these lengths but still assume server-side uniqueness for persisted entities.
|
|
14
|
-
*
|
|
15
|
-
* ## Usage
|
|
16
|
-
*
|
|
17
|
-
* ```ts
|
|
18
|
-
* import { generateId } from "yummies/id";
|
|
19
|
-
* ```
|
|
20
|
-
*/
|
|
21
|
-
var DIGITS = "0123456789";
|
|
22
|
-
var ALPHABET = `abcdefghijklmnopqrstuvwxyz${DIGITS}`;
|
|
23
|
-
/**
|
|
24
|
-
* Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.
|
|
25
|
-
* Length: 6.
|
|
26
|
-
*/
|
|
27
|
-
var generateId = (0, nanoid.customAlphabet)(ALPHABET, 6);
|
|
28
|
-
/**
|
|
29
|
-
* Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.
|
|
30
|
-
* Length: 4.
|
|
31
|
-
*/
|
|
32
|
-
var generateShortId = (0, nanoid.customAlphabet)(ALPHABET, 4);
|
|
33
|
-
/**
|
|
34
|
-
* Uses the alphabet `0123456789`.
|
|
35
|
-
* Length: 6.
|
|
36
|
-
*/
|
|
37
|
-
var generateNumericId = (0, nanoid.customAlphabet)(DIGITS, 6);
|
|
38
|
-
/**
|
|
39
|
-
* Uses the alphabet `0123456789`.
|
|
40
|
-
* Length: 4.
|
|
41
|
-
*/
|
|
42
|
-
var generateNumericShortId = (0, nanoid.customAlphabet)(DIGITS, 4);
|
|
2
|
+
const require_id_nanoid = require("./id-nanoid.cjs");
|
|
3
|
+
//#region src/id/create-linear-numeric-id-generator.ts
|
|
43
4
|
/**
|
|
44
5
|
* Creates a function that generates unique strings based on call order.
|
|
45
6
|
*
|
|
@@ -65,6 +26,8 @@ var createLinearNumericIdGenerator = (size = 9) => {
|
|
|
65
26
|
return (lastCount++).toString().padStart(size, "0");
|
|
66
27
|
};
|
|
67
28
|
};
|
|
29
|
+
//#endregion
|
|
30
|
+
//#region src/id/generate-linear-numeric-id.ts
|
|
68
31
|
/**
|
|
69
32
|
*
|
|
70
33
|
* @example
|
|
@@ -81,6 +44,8 @@ var createLinearNumericIdGenerator = (size = 9) => {
|
|
|
81
44
|
*
|
|
82
45
|
*/
|
|
83
46
|
var generateLinearNumericId = createLinearNumericIdGenerator();
|
|
47
|
+
//#endregion
|
|
48
|
+
//#region src/id/generate-stack-based-id.ts
|
|
84
49
|
/**
|
|
85
50
|
* Is not recommended to use.
|
|
86
51
|
*
|
|
@@ -89,11 +54,11 @@ var generateLinearNumericId = createLinearNumericIdGenerator();
|
|
|
89
54
|
var generateStackBasedId = () => (/* @__PURE__ */ new Error()).stack.split("\n").slice(1, 4).join("");
|
|
90
55
|
//#endregion
|
|
91
56
|
exports.createLinearNumericIdGenerator = createLinearNumericIdGenerator;
|
|
92
|
-
exports.generateId = generateId;
|
|
57
|
+
exports.generateId = require_id_nanoid.generateId;
|
|
93
58
|
exports.generateLinearNumericId = generateLinearNumericId;
|
|
94
|
-
exports.generateNumericId = generateNumericId;
|
|
95
|
-
exports.generateNumericShortId = generateNumericShortId;
|
|
96
|
-
exports.generateShortId = generateShortId;
|
|
59
|
+
exports.generateNumericId = require_id_nanoid.generateNumericId;
|
|
60
|
+
exports.generateNumericShortId = require_id_nanoid.generateNumericShortId;
|
|
61
|
+
exports.generateShortId = require_id_nanoid.generateShortId;
|
|
97
62
|
exports.generateStackBasedId = generateStackBasedId;
|
|
98
63
|
|
|
99
64
|
//# sourceMappingURL=id.cjs.map
|
package/id.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"id.cjs","names":[],"sources":["../src/id.ts"
|
|
1
|
+
{"version":3,"file":"id.cjs","names":[],"sources":["../src/id/create-linear-numeric-id-generator.ts","../src/id/generate-linear-numeric-id.ts","../src/id/generate-stack-based-id.ts"],"sourcesContent":["/**\n * Creates a function that generates unique strings based on call order.\n *\n * @example\n * ```ts\n * generateLinearNumericId = createLinearNumericIdGenerator(6);\n * generateLinearNumericId() // '000000'\n * generateLinearNumericId() // '000001'\n * ...\n * generateLinearNumericId() // '999999'\n * generateLinearNumericId() // '1000000'\n * ...\n * generateLinearNumericId() // '9999999'\n * generateLinearNumericId() // '10000000'\n * ```\n *\n * @param size Minimum string length.\n * @returns {()=>string}\n */\nexport const createLinearNumericIdGenerator = (size: number = 9) => {\n let lastCount = 0;\n return () => {\n return (lastCount++).toString().padStart(size, '0');\n };\n};\n","import { createLinearNumericIdGenerator } from './create-linear-numeric-id-generator.js';\n\n/**\n *\n * @example\n * ```ts\n * generateLinearNumericId() // '000000000'\n * generateLinearNumericId() // '000000001'\n * ...\n * generateLinearNumericId() // '999999999'\n * generateLinearNumericId() // '1000000000'\n * ...\n * generateLinearNumericId() // '9999999999'\n * generateLinearNumericId() // '10000000000'\n * ```\n *\n */\nexport const generateLinearNumericId = createLinearNumericIdGenerator();\n","/**\n * Is not recommended to use.\n *\n * Generates execution stack based pseudo-id (just sliced string from error stack)\n */\nexport const generateStackBasedId = () =>\n new Error().stack!.split('\\n').slice(1, 4).join('');\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAmBA,IAAa,kCAAkC,OAAe,MAAM;CAClE,IAAI,YAAY;CAChB,aAAa;EACX,QAAQ,aAAa,SAAS,EAAE,SAAS,MAAM,GAAG;CACpD;AACF;;;;;;;;;;;;;;;;;;ACPA,IAAa,0BAA0B,+BAA+B;;;;;;;;ACZtE,IAAa,8CACX,IAAI,MAAM,GAAE,MAAO,MAAM,IAAI,EAAE,MAAM,GAAG,CAAC,EAAE,KAAK,EAAE"}
|