@putkoff/abstract-utilities 0.1.242 → 0.1.244

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 (91) hide show
  1. package/dist/functions/auth_utils/imports.js +1 -0
  2. package/dist/functions/auth_utils/index.js +1 -0
  3. package/dist/functions/auth_utils/src/index.js +1 -0
  4. package/dist/functions/auth_utils/src/token_utils.js +104 -0
  5. package/dist/functions/config_utils/imports.js +2 -0
  6. package/dist/functions/config_utils/index.js +1 -0
  7. package/dist/functions/config_utils/src/config_utils.js +16 -0
  8. package/dist/functions/config_utils/src/index.js +1 -0
  9. package/dist/functions/constants_utils/index.js +1 -0
  10. package/dist/functions/constants_utils/src/constants.js +7 -0
  11. package/dist/functions/constants_utils/src/index.js +1 -0
  12. package/dist/functions/env_utils/imports.js +1 -0
  13. package/dist/functions/env_utils/index.js +1 -0
  14. package/dist/functions/env_utils/src/index.js +1 -0
  15. package/dist/functions/env_utils/src/window_utils.js +47 -0
  16. package/dist/functions/fetch_utils/imports.js +2 -0
  17. package/dist/functions/fetch_utils/index.js +1 -0
  18. package/dist/functions/fetch_utils/src/fetch_utils.js +65 -0
  19. package/dist/functions/fetch_utils/src/index.js +3 -0
  20. package/dist/functions/fetch_utils/src/url_utils.js +83 -0
  21. package/dist/functions/fetch_utils/src/utils.js +101 -0
  22. package/dist/functions/index.js +17 -0
  23. package/dist/functions/math_utils/index.js +1 -0
  24. package/dist/functions/math_utils/safe_math.js +26 -0
  25. package/dist/functions/path_utils/imports.js +28 -0
  26. package/dist/functions/path_utils/index.js +1 -0
  27. package/dist/functions/path_utils/src/base_dirs.js +17 -0
  28. package/dist/functions/path_utils/src/function_dirs.js +42 -0
  29. package/dist/functions/path_utils/src/index.js +6 -0
  30. package/dist/functions/path_utils/src/misc_dirs.js +15 -0
  31. package/dist/functions/path_utils/src/path_utils.browser.js +3 -0
  32. package/dist/functions/path_utils/src/path_utils.js +112 -0
  33. package/dist/functions/path_utils/src/path_utils.node.js +3 -0
  34. package/dist/functions/path_utils/src/paths.js +12 -0
  35. package/dist/functions/path_utils/src/src_dirs.js +25 -0
  36. package/dist/functions/read_utils/imports.js +1 -0
  37. package/dist/functions/read_utils/index.js +1 -0
  38. package/dist/functions/read_utils/src/index.js +1 -0
  39. package/dist/functions/read_utils/src/read_utils.browser.js +17 -0
  40. package/dist/functions/read_utils/src/utils.browser.js +32 -0
  41. package/dist/functions/read_utils/src/utils.js +70 -0
  42. package/dist/functions/rndm_utils/imports.js +1 -0
  43. package/dist/functions/rndm_utils/index.js +1 -0
  44. package/dist/functions/rndm_utils/src/index.js +1 -0
  45. package/dist/functions/rndm_utils/src/utils.js +13 -0
  46. package/dist/functions/safe_utils/imports.js +1 -0
  47. package/dist/functions/safe_utils/index.js +1 -0
  48. package/dist/functions/safe_utils/src/index.js +4 -0
  49. package/dist/functions/safe_utils/src/safe_document.js +12 -0
  50. package/dist/functions/safe_utils/src/safe_globals.js +14 -0
  51. package/dist/functions/safe_utils/src/safe_storage.js +52 -0
  52. package/dist/functions/safe_utils/src/safe_window.js +42 -0
  53. package/dist/functions/string_utils/index.js +1 -0
  54. package/dist/functions/string_utils/src/index.js +1 -0
  55. package/dist/functions/string_utils/src/string_utils.js +153 -0
  56. package/dist/functions/type_utils/imports.js +1 -0
  57. package/dist/functions/type_utils/index.js +1 -0
  58. package/dist/functions/type_utils/src/clean_utils.js +38 -0
  59. package/dist/functions/type_utils/src/ensure_utils.js +33 -0
  60. package/dist/functions/type_utils/src/index.js +5 -0
  61. package/dist/functions/type_utils/src/json_utils.js +22 -0
  62. package/dist/functions/type_utils/src/mime_utils.js +311 -0
  63. package/dist/functions/type_utils/src/type_utils.js +39 -0
  64. package/dist/functions/ui_utils/imports.js +5 -0
  65. package/dist/functions/ui_utils/index.js +1 -0
  66. package/dist/functions/ui_utils/src/button.js +22 -0
  67. package/dist/functions/ui_utils/src/checkbox.js +6 -0
  68. package/dist/functions/ui_utils/src/index.js +4 -0
  69. package/dist/functions/ui_utils/src/input.js +6 -0
  70. package/dist/functions/ui_utils/src/spinner.js +4 -0
  71. package/dist/functions/url_utils/index.js +1 -0
  72. package/dist/functions/url_utils/uri_utils.js +69 -0
  73. package/dist/functions/variable_utils/imports.js +1 -0
  74. package/dist/functions/variable_utils/index.js +1 -0
  75. package/dist/functions/variable_utils/src/index.js +1 -0
  76. package/dist/functions/variable_utils/src/variable_utils.js +34 -0
  77. package/dist/functions.json +1727 -0
  78. package/dist/index.js +2 -0
  79. package/dist/types/index.js +1 -0
  80. package/dist/types/src/ChangePassword.js +1 -0
  81. package/dist/types/src/Files.js +1 -0
  82. package/dist/types/src/index.js +5 -0
  83. package/dist/types/src/login.js +1 -0
  84. package/dist/types/src/logout.js +1 -0
  85. package/dist/types/src/utils.js +1 -0
  86. package/dist/utils/imports.js +1 -0
  87. package/dist/utils/index.js +1 -0
  88. package/dist/utils/src/Input.js +2 -0
  89. package/dist/utils/src/config.js +12 -0
  90. package/dist/utils/src/index.js +3 -0
  91. package/package.json +4 -1
@@ -0,0 +1,33 @@
1
+ export function ensure_list(obj) {
2
+ const objArray = Array.isArray(obj) ? obj : [obj];
3
+ return objArray;
4
+ }
5
+ // coerce any single value into a number (0 if it can't)
6
+ export function ensure_number(x) {
7
+ const n = Number(x);
8
+ return isNaN(n) ? 0 : n;
9
+ }
10
+ export function ensure_array(input) {
11
+ if (typeof input === 'string') {
12
+ return [input];
13
+ }
14
+ if (Array.isArray(input)) {
15
+ return input.map(item => ensure_string(item));
16
+ }
17
+ return [];
18
+ }
19
+ export function ensure_string(obj) {
20
+ return String(obj);
21
+ }
22
+ export const assureList = ensure_list;
23
+ export const assureString = ensure_string;
24
+ export const assureNumber = ensure_number;
25
+ export const assureArray = ensure_array;
26
+ export const assure_list = ensure_list;
27
+ export const assure_string = ensure_string;
28
+ export const assure_number = ensure_number;
29
+ export const assure_array = ensure_array;
30
+ export const ensureList = ensure_list;
31
+ export const ensureString = ensure_string;
32
+ export const ensureNumber = ensure_number;
33
+ export const ensureArray = ensure_array;
@@ -0,0 +1,5 @@
1
+ export * from './clean_utils';
2
+ export * from './ensure_utils';
3
+ export * from './json_utils';
4
+ export * from './type_utils';
5
+ export * from './mime_utils';
@@ -0,0 +1,22 @@
1
+ import { ensure_array } from './ensure_utils.js';
2
+ // Constrain T so 'in obj' is allowed
3
+ export function get_key_value(obj, key) {
4
+ // we cast to any for the indexing, since TS can’t infer arbitrary string keys
5
+ if (key in obj && obj[key] != null) {
6
+ return obj[key];
7
+ }
8
+ return null;
9
+ }
10
+ export function get(obj, keys, defaultValue = null) {
11
+ const keyArray = ensure_array(keys);
12
+ if (!obj || keyArray.length === 0) {
13
+ return defaultValue;
14
+ }
15
+ for (const key of keyArray) {
16
+ const val = get_key_value(obj, key);
17
+ if (val != null) {
18
+ return val;
19
+ }
20
+ }
21
+ return defaultValue;
22
+ }
@@ -0,0 +1,311 @@
1
+ import { __awaiter } from "tslib";
2
+ // mediaTypes.ts
3
+ import * as fs from "node:fs";
4
+ import * as fsp from "node:fs/promises";
5
+ import * as path from "node:path";
6
+ /** ---- Data: large but explicit, mirrors your Python mapping ---- */
7
+ export const MIME_TYPES = {
8
+ image: {
9
+ ".jpg": "image/jpeg",
10
+ ".jpeg": "image/jpeg",
11
+ ".png": "image/png",
12
+ ".gif": "image/gif",
13
+ ".bmp": "image/bmp",
14
+ ".tiff": "image/tiff",
15
+ ".webp": "image/webp",
16
+ ".svg": "image/svg+xml",
17
+ ".ico": "image/vnd.microsoft.icon",
18
+ ".heic": "image/heic",
19
+ ".psd": "image/vnd.adobe.photoshop",
20
+ ".raw": "image/x-raw",
21
+ },
22
+ video: {
23
+ ".mp4": "video/mp4",
24
+ ".webm": "video/webm",
25
+ ".ogg": "video/ogg",
26
+ ".mov": "video/quicktime",
27
+ ".avi": "video/x-msvideo",
28
+ ".mkv": "video/x-matroska",
29
+ ".flv": "video/x-flv",
30
+ ".wmv": "video/x-ms-wmv",
31
+ ".3gp": "video/3gpp",
32
+ ".ts": "video/mp2t",
33
+ ".mpeg": "video/mpeg",
34
+ ".mpg": "video/mpg",
35
+ },
36
+ audio: {
37
+ ".mp3": "audio/mpeg",
38
+ ".wav": "audio/wav",
39
+ ".flac": "audio/flac",
40
+ ".aac": "audio/aac",
41
+ ".ogg": "audio/ogg",
42
+ ".m4a": "audio/mp4",
43
+ ".opus": "audio/opus",
44
+ },
45
+ document: {
46
+ ".pdf": "application/pdf",
47
+ ".doc": "application/msword",
48
+ ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
49
+ ".odt": "application/vnd.oasis.opendocument.text",
50
+ ".txt": "text/plain",
51
+ ".rtf": "application/rtf",
52
+ ".md": "text/markdown",
53
+ ".markdown": "text/markdown",
54
+ ".tex": "application/x-tex",
55
+ ".log": "text/plain",
56
+ ".json": "application/json",
57
+ ".xml": "application/xml",
58
+ ".yaml": "application/x-yaml",
59
+ ".yml": "application/x-yaml",
60
+ ".ini": "text/plain",
61
+ ".cfg": "text/plain",
62
+ ".toml": "application/toml",
63
+ ".csv": "text/csv",
64
+ ".tsv": "text/tab-separated-values",
65
+ },
66
+ presentation: {
67
+ ".ppt": "application/vnd.ms-powerpoint",
68
+ ".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
69
+ ".odp": "application/vnd.oasis.opendocument.presentation",
70
+ },
71
+ spreadsheet: {
72
+ ".xls": "application/vnd.ms-excel",
73
+ ".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
74
+ ".ods": "application/vnd.oasis.opendocument.spreadsheet",
75
+ ".csv": "text/csv",
76
+ ".tsv": "text/tab-separated-values",
77
+ },
78
+ code: {
79
+ ".py": "text/x-python",
80
+ ".java": "text/x-java-source",
81
+ ".c": "text/x-c",
82
+ ".cpp": "text/x-c++",
83
+ ".h": "text/x-c",
84
+ ".hpp": "text/x-c++",
85
+ ".js": "application/javascript",
86
+ ".cjs": "application/javascript",
87
+ ".mjs": "application/javascript",
88
+ ".jsx": "application/javascript",
89
+ ".ts": "application/typescript",
90
+ ".tsx": "application/typescript",
91
+ ".rb": "text/x-ruby",
92
+ ".php": "application/x-php",
93
+ ".go": "text/x-go",
94
+ ".rs": "text/rust",
95
+ ".swift": "text/x-swift",
96
+ ".kt": "text/x-kotlin",
97
+ ".sh": "application/x-shellscript",
98
+ ".bash": "application/x-shellscript",
99
+ ".ps1": "application/x-powershell",
100
+ ".sql": "application/sql",
101
+ ".yml": "application/x-yaml",
102
+ ".coffee": "text/coffeescript",
103
+ ".lua": "text/x-lua",
104
+ },
105
+ archive: {
106
+ ".zip": "application/zip",
107
+ ".tar": "application/x-tar",
108
+ ".gz": "application/gzip",
109
+ ".tgz": "application/gzip",
110
+ ".bz2": "application/x-bzip2",
111
+ ".xz": "application/x-xz",
112
+ ".rar": "application/vnd.rar",
113
+ ".7z": "application/x-7z-compressed",
114
+ ".iso": "application/x-iso9660-image",
115
+ ".dmg": "application/x-apple-diskimage",
116
+ ".jar": "application/java-archive",
117
+ ".war": "application/java-archive",
118
+ ".whl": "application/python-wheel",
119
+ ".egg": "application/python-egg",
120
+ },
121
+ font: {
122
+ ".ttf": "font/ttf",
123
+ ".otf": "font/otf",
124
+ ".woff": "font/woff",
125
+ ".woff2": "font/woff2",
126
+ ".eot": "application/vnd.ms-fontobject",
127
+ },
128
+ executable: {
129
+ ".exe": "application/vnd.microsoft.portable-executable",
130
+ ".dll": "application/vnd.microsoft.portable-executable",
131
+ ".bin": "application/octet-stream",
132
+ ".deb": "application/vnd.debian.binary-package",
133
+ ".rpm": "application/x-rpm",
134
+ },
135
+ };
136
+ /** Mirror of MEDIA_TYPES in Python: category -> Set of extensions */
137
+ export const MEDIA_TYPES = Object.fromEntries(Object.entries(MIME_TYPES).map(([cat, mapping]) => [
138
+ cat,
139
+ new Set(Object.keys(mapping)),
140
+ ]));
141
+ /** ---- Helpers ---- */
142
+ function toCategorySet(categories) {
143
+ const allCats = new Set(Object.keys(MIME_TYPES));
144
+ if (!categories) {
145
+ // all categories
146
+ return new Set(allCats);
147
+ }
148
+ const out = new Set();
149
+ for (const c of categories) {
150
+ const key = String(c);
151
+ if (allCats.has(key))
152
+ out.add(key);
153
+ }
154
+ return out.size ? out : new Set(allCats);
155
+ }
156
+ function normalizeCategories(categories, opts) {
157
+ var _a;
158
+ const selected = (_a = categories !== null && categories !== void 0 ? categories : opts === null || opts === void 0 ? void 0 : opts.media_types) !== null && _a !== void 0 ? _a : null;
159
+ return toCategorySet(selected);
160
+ }
161
+ function extOf(input) {
162
+ // Behaves like pathlib.Path(...).suffix.lower(): last extension only; lowercased.
163
+ let ext = path.extname(input || "");
164
+ if (!ext && input && input.startsWith(".")) {
165
+ // user passed ".jpg" directly
166
+ ext = input;
167
+ }
168
+ return (ext || "").toLowerCase();
169
+ }
170
+ function unionExts(categories) {
171
+ const out = new Set();
172
+ for (const c of categories) {
173
+ const set = MEDIA_TYPES[c];
174
+ for (const e of set)
175
+ out.add(e);
176
+ }
177
+ return out;
178
+ }
179
+ /** ---- API (Python parity) ---- */
180
+ /**
181
+ * Return a sub-map of MEDIA_TYPES for the given categories.
182
+ * If categories is falsy, returns all categories.
183
+ */
184
+ export function getMediaMap(categories, opts) {
185
+ const cats = normalizeCategories(categories, opts);
186
+ const result = {};
187
+ for (const c of cats)
188
+ result[c] = new Set(MEDIA_TYPES[c]);
189
+ return result;
190
+ }
191
+ /**
192
+ * Return a flat, sorted list of all extensions for the given categories.
193
+ */
194
+ export function getMediaExts(categories, opts) {
195
+ const cats = normalizeCategories(categories, opts);
196
+ return Array.from(unionExts(cats)).sort();
197
+ }
198
+ /**
199
+ * Given a file path or extension, return its media category (e.g. "image") or null.
200
+ * Mirrors Python's confirm_type.
201
+ */
202
+ export function confirmType(pathOrExt, categories, opts) {
203
+ const cats = normalizeCategories(categories, opts);
204
+ const ext = extOf(pathOrExt);
205
+ // Preserve object insertion order like Python dict iteration
206
+ for (const [category, exts] of Object.entries(MEDIA_TYPES)) {
207
+ if (!cats.has(category))
208
+ continue;
209
+ if (ext && exts.has(ext))
210
+ return category;
211
+ }
212
+ return null;
213
+ }
214
+ /**
215
+ * True if the given file path or extension belongs to one of the categories.
216
+ */
217
+ export function isMediaType(pathOrExt, categories, opts) {
218
+ return confirmType(pathOrExt, categories, opts) !== null;
219
+ }
220
+ /**
221
+ * Look up the MIME type by extension; fall back to 'application/octet-stream'.
222
+ */
223
+ export function getMimeType(pathOrExt) {
224
+ const ext = extOf(pathOrExt);
225
+ for (const mapping of Object.values(MIME_TYPES)) {
226
+ if (ext && mapping[ext]) {
227
+ return mapping[ext];
228
+ }
229
+ }
230
+ return "application/octet-stream";
231
+ }
232
+ /**
233
+ * Recursively collect files under `directory` whose extension is in `categories`.
234
+ * Synchronous version.
235
+ */
236
+ export function getAllFileTypesSync(directory, categories, opts) {
237
+ const base = directory;
238
+ let stat;
239
+ try {
240
+ stat = fs.statSync(base);
241
+ }
242
+ catch (_a) {
243
+ return [];
244
+ }
245
+ if (!stat.isDirectory())
246
+ return [];
247
+ const cats = normalizeCategories(categories, opts);
248
+ const wanted = unionExts(cats);
249
+ const results = [];
250
+ function walkSync(dir) {
251
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
252
+ for (const ent of entries) {
253
+ const full = path.join(dir, ent.name);
254
+ if (ent.isDirectory()) {
255
+ walkSync(full);
256
+ }
257
+ else if (ent.isFile()) {
258
+ const ext = path.extname(ent.name).toLowerCase();
259
+ if (wanted.has(ext))
260
+ results.push(full);
261
+ }
262
+ }
263
+ }
264
+ walkSync(base);
265
+ return results;
266
+ }
267
+ /**
268
+ * Recursively collect files under `directory` whose extension is in `categories`.
269
+ * Async/Promise version.
270
+ */
271
+ export function getAllFileTypes(directory, categories, opts) {
272
+ return __awaiter(this, void 0, void 0, function* () {
273
+ let stat;
274
+ try {
275
+ stat = yield fsp.stat(directory);
276
+ }
277
+ catch (_a) {
278
+ return [];
279
+ }
280
+ if (!stat.isDirectory())
281
+ return [];
282
+ const cats = normalizeCategories(categories, opts);
283
+ const wanted = unionExts(cats);
284
+ const results = [];
285
+ function walkAsync(dir) {
286
+ return __awaiter(this, void 0, void 0, function* () {
287
+ const entries = yield fsp.readdir(dir, { withFileTypes: true });
288
+ for (const ent of entries) {
289
+ const full = path.join(dir, ent.name);
290
+ if (ent.isDirectory()) {
291
+ yield walkAsync(full);
292
+ }
293
+ else if (ent.isFile()) {
294
+ const ext = path.extname(ent.name).toLowerCase();
295
+ if (wanted.has(ext))
296
+ results.push(full);
297
+ }
298
+ }
299
+ });
300
+ }
301
+ yield walkAsync(directory);
302
+ return results;
303
+ });
304
+ }
305
+ /** Optional convenience re-exports that mirror your Python names */
306
+ export const get_all_file_types = getAllFileTypes;
307
+ export const get_media_map = getMediaMap;
308
+ export const get_media_exts = getMediaExts;
309
+ export const confirm_type = confirmType;
310
+ export const is_media_type = isMediaType;
311
+ export const get_mime_type = getMimeType;
@@ -0,0 +1,39 @@
1
+ import { ensure_string } from './ensure_utils.js';
2
+ export function isType(obj, type) {
3
+ if (typeof obj === type) {
4
+ return true;
5
+ }
6
+ return false;
7
+ }
8
+ export function isStrInString(obj, string) {
9
+ const obj_str = ensure_string(obj).toLowerCase;
10
+ string = ensure_string(string).toLowerCase;
11
+ if (string.includes(obj_str)) {
12
+ return true;
13
+ }
14
+ return false;
15
+ }
16
+ export function getChar(i, string) {
17
+ if (string.length >= i) {
18
+ return ensure_string(string)[i];
19
+ }
20
+ }
21
+ export function getAlphaNum(obj) {
22
+ const is_num = isNum(obj);
23
+ const alphas = getAlphas();
24
+ if (is_num) {
25
+ return getChar(obj, alphas);
26
+ }
27
+ if (isStrInString(obj, alphas)) {
28
+ return getChar(obj, alphas);
29
+ }
30
+ }
31
+ export function getNums() {
32
+ return '0123456789';
33
+ }
34
+ export function isNum(obj) {
35
+ return !Number.isNaN(Number(obj));
36
+ }
37
+ export function getAlphas() {
38
+ return 'abcdefghijklmnopqrstuvwxyz';
39
+ }
@@ -0,0 +1,5 @@
1
+ //src/components/UI/UI.tsx
2
+ import React from 'react';
3
+ export const { useState, useEffect, useCallback } = React;
4
+ export { fetchIt } from './../fetch_utils';
5
+ export { currentUsername, isTokenExpired, getToken } from './../auth_utils';
@@ -0,0 +1 @@
1
+ export * from './src';
@@ -0,0 +1,22 @@
1
+ import { __rest } from "tslib";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ export function Button(_a) {
4
+ var { children, color = 'gray', variant = 'default', className = '' } = _a, rest = __rest(_a, ["children", "color", "variant", "className"]);
5
+ const base = 'rounded px-3 py-1 text-sm font-medium focus:outline-none focus:ring-2 focus:ring-offset-2 transition-colors duration-150';
6
+ const variantStyles = {
7
+ default: '',
8
+ icon: 'p-1 bg-transparent hover:bg-gray-100',
9
+ primary: 'text-white',
10
+ secondary: '',
11
+ };
12
+ const palette = {
13
+ gray: variant === 'primary'
14
+ ? 'bg-gray-600 hover:bg-gray-700 focus:ring-gray-500'
15
+ : 'bg-gray-200 hover:bg-gray-300 focus:ring-gray-400',
16
+ green: 'bg-green-600 text-white hover:bg-green-700 focus:ring-green-500',
17
+ blue: variant === 'primary'
18
+ ? 'bg-blue-600 hover:bg-blue-700 focus:ring-blue-500'
19
+ : 'bg-blue-200 hover:bg-blue-300 focus:ring-blue-400',
20
+ };
21
+ return (_jsx("button", Object.assign({ className: `${base} ${variantStyles[variant]} ${palette[color]} ${className}` }, rest, { children: children })));
22
+ }
@@ -0,0 +1,6 @@
1
+ import { __rest } from "tslib";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ export function Checkbox(_a) {
4
+ var { label } = _a, rest = __rest(_a, ["label"]);
5
+ return (_jsxs("label", { className: 'flex items-center gap-2 mb-4', children: [_jsx("input", Object.assign({ type: 'checkbox' }, rest)), _jsx("span", { children: label })] }));
6
+ }
@@ -0,0 +1,4 @@
1
+ export * from './button';
2
+ export * from './checkbox';
3
+ export * from './input';
4
+ export * from './spinner';
@@ -0,0 +1,6 @@
1
+ import { __rest } from "tslib";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ export function Input(_a) {
4
+ var { label, trailing } = _a, rest = __rest(_a, ["label", "trailing"]);
5
+ return (_jsxs("label", { className: 'mb-4 block', children: [_jsx("span", { className: 'block text-sm font-medium mb-1', children: label }), _jsxs("div", { className: 'flex gap-2', children: [_jsx("input", Object.assign({ className: 'flex-1 rounded border px-2 py-1 disabled:bg-gray-100' }, rest)), trailing] })] }));
6
+ }
@@ -0,0 +1,4 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ export function Spinner() {
3
+ return (_jsx("p", { className: 'animate-pulse', children: "Loading\u2026" }));
4
+ }
@@ -0,0 +1 @@
1
+ export * from './uri_utils';
@@ -0,0 +1,69 @@
1
+ // urlTools.ts
2
+ // Minimal, safe encoders/decoders + helpers to build/parse URLs
3
+ /** Encode a single query value/key safely */
4
+ export const encode = (v) => encodeURIComponent(String(v !== null && v !== void 0 ? v : ""));
5
+ /** Decode a single query value/key safely (never throws) */
6
+ export const decodeSafe = (v) => {
7
+ if (v == null)
8
+ return "";
9
+ try {
10
+ return decodeURIComponent(v);
11
+ }
12
+ catch (_a) {
13
+ // handles bad % sequences or already-decoded strings
14
+ return v;
15
+ }
16
+ };
17
+ /** Decode strings that might be double-encoded (up to 2 passes) */
18
+ export const decodeMaybeDouble = (v) => {
19
+ const once = decodeSafe(v);
20
+ const twice = decodeSafe(once);
21
+ return twice.length < once.length ? twice : once;
22
+ };
23
+ /** Convert + to spaces (legacy www-form behavior) then decode */
24
+ export const decodeFormComponent = (v) => decodeSafe(v.replace(/\+/g, " "));
25
+ /** Build a URL with query params (skips null/undefined) */
26
+ export const buildUrl = (base, params) => {
27
+ const u = new URL(base, typeof window !== "undefined" ? window.location.origin : "http://localhost");
28
+ if (params) {
29
+ for (const [k, val] of Object.entries(params)) {
30
+ if (val === null || val === undefined)
31
+ continue;
32
+ // arrays -> multiple entries
33
+ if (Array.isArray(val)) {
34
+ val.forEach(v => u.searchParams.append(k, String(v)));
35
+ }
36
+ else {
37
+ u.searchParams.set(k, String(val));
38
+ }
39
+ }
40
+ }
41
+ return u.toString();
42
+ };
43
+ /** Parse a query string into an object (first value wins; arrays if repeat=true) */
44
+ export const parseQuery = (qs, opts) => {
45
+ var _a;
46
+ const { repeat = false, form = false } = opts || {};
47
+ const out = {};
48
+ const s = qs.startsWith("?") ? qs.slice(1) : qs;
49
+ if (!s)
50
+ return out;
51
+ for (const part of s.split("&")) {
52
+ if (!part)
53
+ continue;
54
+ const [kRaw, vRaw = ""] = part.split("=");
55
+ const K = form ? decodeFormComponent(kRaw) : decodeSafe(kRaw);
56
+ const V = form ? decodeFormComponent(vRaw) : decodeSafe(vRaw);
57
+ if (repeat) {
58
+ ((_a = out[K]) !== null && _a !== void 0 ? _a : (out[K] = [])).push(V);
59
+ }
60
+ else {
61
+ out[K] = V;
62
+ }
63
+ }
64
+ return out;
65
+ };
66
+ /** Quick helper: percent-encode whole strings for placement in URLs */
67
+ export const encodeTextForUrl = (text) => encode(text);
68
+ /** Quick helper: decode long blobs coming from share-intents/UTMs */
69
+ export const decodeShareBlob = (blob) => decodeMaybeDouble(blob).replace(/\r\n/g, "\n");
@@ -0,0 +1 @@
1
+ export { eatAll } from './../string_utils';
@@ -0,0 +1 @@
1
+ export * from './src';
@@ -0,0 +1 @@
1
+ export * from './variable_utils';
@@ -0,0 +1,34 @@
1
+ import { eatAll } from './../imports.js';
2
+ /**
3
+ * Processes keywords by checking if keywords is a string and splitting it.
4
+ * Then cleans each keyword using `eatAll` with a set of characters to remove.
5
+ *
6
+ * @param keywords - The keywords as a comma-separated string or as an array.
7
+ * @returns An array of cleaned keywords.
8
+ */
9
+ export function processKeywords(keywords) {
10
+ let keywordArray;
11
+ // If keywords is a string, split it on commas
12
+ if (typeof keywords === "string") {
13
+ keywordArray = keywords.split(",");
14
+ }
15
+ else {
16
+ keywordArray = keywords;
17
+ }
18
+ // Clean each keyword by removing unwanted characters
19
+ return keywordArray.map(keyword => eatAll(keyword, [",", "\n", "\t", " ", "#"]));
20
+ }
21
+ /**
22
+ * Constructs a keyword string where each keyword is prefixed with a hash (#).
23
+ *
24
+ * @param keywords - An array of keywords.
25
+ * @returns A string with each keyword prefixed by '#'.
26
+ */
27
+ export function get_keyword_string(keywords) {
28
+ keywords = processKeywords(keywords);
29
+ let allString = "";
30
+ for (const keyword of keywords) {
31
+ allString += ` #${keyword}`;
32
+ }
33
+ return allString;
34
+ }