utilful 1.2.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +240 -24
  2. package/dist/array.d.ts +7 -5
  3. package/dist/array.js +11 -0
  4. package/dist/csv.d.ts +57 -57
  5. package/dist/csv.js +98 -0
  6. package/dist/defu.d.ts +16 -0
  7. package/dist/defu.js +34 -0
  8. package/dist/emitter.d.ts +20 -14
  9. package/dist/emitter.js +32 -0
  10. package/dist/index.d.ts +12 -10
  11. package/dist/index.js +12 -0
  12. package/dist/json.d.ts +13 -11
  13. package/dist/json.js +34 -0
  14. package/dist/module.d.ts +9 -7
  15. package/dist/module.js +14 -0
  16. package/dist/object.d.ts +26 -7
  17. package/dist/object.js +51 -0
  18. package/dist/path.d.ts +21 -19
  19. package/dist/path.js +105 -0
  20. package/dist/result.d.ts +34 -0
  21. package/dist/result.js +45 -0
  22. package/dist/string.d.ts +16 -14
  23. package/dist/string.js +32 -0
  24. package/dist/types.d.ts +4 -4
  25. package/dist/types.js +0 -0
  26. package/package.json +23 -18
  27. package/dist/array.d.mts +0 -10
  28. package/dist/array.mjs +0 -6
  29. package/dist/csv.d.mts +0 -67
  30. package/dist/csv.mjs +0 -77
  31. package/dist/emitter.d.mts +0 -24
  32. package/dist/emitter.mjs +0 -63
  33. package/dist/index.d.mts +0 -10
  34. package/dist/index.mjs +0 -9
  35. package/dist/json.d.mts +0 -16
  36. package/dist/json.mjs +0 -26
  37. package/dist/lazy.d.mts +0 -20
  38. package/dist/lazy.d.ts +0 -20
  39. package/dist/lazy.mjs +0 -11
  40. package/dist/module.d.mts +0 -11
  41. package/dist/module.mjs +0 -6
  42. package/dist/object.d.mts +0 -14
  43. package/dist/object.mjs +0 -25
  44. package/dist/path.d.mts +0 -40
  45. package/dist/path.mjs +0 -113
  46. package/dist/string.d.mts +0 -19
  47. package/dist/string.mjs +0 -16
  48. package/dist/types.d.mts +0 -8
  49. package/dist/types.mjs +0 -1
package/dist/index.d.ts CHANGED
@@ -1,10 +1,12 @@
1
- export { MaybeArray, toArray } from './array.js';
2
- export { CSVRow, createCSV, escapeCSVValue, parseCSV } from './csv.js';
3
- export { Emitter, EventHandlerList, EventHandlerMap, EventType, Handler, WildCardEventHandlerList, WildcardHandler, createEmitter } from './emitter.js';
4
- export { cloneJSON, tryParseJSON } from './json.js';
5
- export { lazy } from './lazy.js';
6
- export { interopDefault } from './module.js';
7
- export { deepApply, objectEntries, objectKeys } from './object.js';
8
- export { QueryObject, QueryValue, getPathname, joinURL, withBase, withLeadingSlash, withQuery, withTrailingSlash, withoutBase, withoutLeadingSlash, withoutTrailingSlash } from './path.js';
9
- export { generateRandomId, template } from './string.js';
10
- export { AutocompletableString, LooseAutocomplete, UnifyIntersection } from './types.js';
1
+ import { MaybeArray, toArray } from "./array.js";
2
+ import { CSVRow, createCSV, escapeCSVValue, parseCSV } from "./csv.js";
3
+ import { Emitter, EventHandlerList, EventHandlerMap, EventType, Handler, WildCardEventHandlerList, WildcardHandler, createEmitter } from "./emitter.js";
4
+ import { DefuFn, DefuMerger, createDefu$1 as createDefu, defu$1 as defu } from "./defu.js";
5
+ import { cloneJSON, tryParseJSON } from "./json.js";
6
+ import { interopDefault } from "./module.js";
7
+ import { deepApply, memoize, objectEntries, objectKeys } from "./object.js";
8
+ import { QueryObject, QueryValue, getPathname, joinURL, withBase, withLeadingSlash, withQuery, withTrailingSlash, withoutBase, withoutLeadingSlash, withoutTrailingSlash } from "./path.js";
9
+ import { Err, ErrData, Ok, OkData, Result, ResultData, err, ok, toResult, tryCatch, unwrapResult } from "./result.js";
10
+ import { generateRandomId, template } from "./string.js";
11
+ import { AutocompletableString, LooseAutocomplete, UnifyIntersection } from "./types.js";
12
+ export { AutocompletableString, CSVRow, DefuFn, DefuMerger, Emitter, Err, ErrData, EventHandlerList, EventHandlerMap, EventType, Handler, LooseAutocomplete, MaybeArray, Ok, OkData, QueryObject, QueryValue, Result, ResultData, UnifyIntersection, WildCardEventHandlerList, WildcardHandler, cloneJSON, createCSV, createDefu, createEmitter, deepApply, defu, err, escapeCSVValue, generateRandomId, getPathname, interopDefault, joinURL, memoize, objectEntries, objectKeys, ok, parseCSV, template, toArray, toResult, tryCatch, tryParseJSON, unwrapResult, withBase, withLeadingSlash, withQuery, withTrailingSlash, withoutBase, withoutLeadingSlash, withoutTrailingSlash };
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ import { toArray } from "./array.js";
2
+ import { createCSV, escapeCSVValue, parseCSV } from "./csv.js";
3
+ import { createEmitter } from "./emitter.js";
4
+ import { createDefu, defu } from "./defu.js";
5
+ import { cloneJSON, tryParseJSON } from "./json.js";
6
+ import { interopDefault } from "./module.js";
7
+ import { deepApply, memoize, objectEntries, objectKeys } from "./object.js";
8
+ import { getPathname, joinURL, withBase, withLeadingSlash, withQuery, withTrailingSlash, withoutBase, withoutLeadingSlash, withoutTrailingSlash } from "./path.js";
9
+ import { Err, Ok, err, ok, toResult, tryCatch, unwrapResult } from "./result.js";
10
+ import { generateRandomId, template } from "./string.js";
11
+
12
+ export { Err, Ok, cloneJSON, createCSV, createDefu, createEmitter, deepApply, defu, err, escapeCSVValue, generateRandomId, getPathname, interopDefault, joinURL, memoize, objectEntries, objectKeys, ok, parseCSV, template, toArray, toResult, tryCatch, tryParseJSON, unwrapResult, withBase, withLeadingSlash, withQuery, withTrailingSlash, withoutBase, withoutLeadingSlash, withoutTrailingSlash };
package/dist/json.d.ts CHANGED
@@ -1,16 +1,18 @@
1
+ //#region src/json.d.ts
1
2
  /**
2
- * Type-safe wrapper around `JSON.stringify`.
3
- *
4
- * @remarks
5
- * Falls back to the original value if the JSON serialization fails or the value is not a string.
6
- */
3
+ * Type-safe wrapper around `JSON.stringify`.
4
+ *
5
+ * @remarks
6
+ * Falls back to the original value if the JSON serialization fails or the value is not a string.
7
+ */
7
8
  declare function tryParseJSON<T = unknown>(value: unknown): T;
8
9
  /**
9
- * Clones the given JSON value.
10
- *
11
- * @remarks
12
- * The value must not contain circular references as JSON does not support them. It also must contain JSON serializable values.
13
- */
10
+ * Clones the given JSON value.
11
+ *
12
+ * @remarks
13
+ * The value must not contain circular references as JSON does not support them. It also must contain JSON serializable values.
14
+ */
14
15
  declare function cloneJSON<T>(value: T): T;
15
16
 
16
- export { cloneJSON, tryParseJSON };
17
+ //#endregion
18
+ export { cloneJSON, tryParseJSON };
package/dist/json.js ADDED
@@ -0,0 +1,34 @@
1
+ //#region src/json.ts
2
+ /**
3
+ * Type-safe wrapper around `JSON.stringify`.
4
+ *
5
+ * @remarks
6
+ * Falls back to the original value if the JSON serialization fails or the value is not a string.
7
+ */
8
+ function tryParseJSON(value) {
9
+ if (typeof value !== "string") return value;
10
+ try {
11
+ return JSON.parse(value);
12
+ } catch {
13
+ return value;
14
+ }
15
+ }
16
+ /**
17
+ * Clones the given JSON value.
18
+ *
19
+ * @remarks
20
+ * The value must not contain circular references as JSON does not support them. It also must contain JSON serializable values.
21
+ */
22
+ function cloneJSON(value) {
23
+ if (typeof value !== "object" || value === null) return value;
24
+ if (Array.isArray(value)) return value.map((e) => typeof e !== "object" || e === null ? e : cloneJSON(e));
25
+ const result = {};
26
+ for (const k in value) {
27
+ const v = value[k];
28
+ result[k] = typeof v !== "object" || v === null ? v : cloneJSON(v);
29
+ }
30
+ return result;
31
+ }
32
+
33
+ //#endregion
34
+ export { cloneJSON, tryParseJSON };
package/dist/module.d.ts CHANGED
@@ -1,11 +1,13 @@
1
+ //#region src/module.d.ts
1
2
  /**
2
- * Interop helper for default exports.
3
- *
4
- * @example
5
- * const mod = await interopDefault(import('./module.js'))
6
- */
3
+ * Interop helper for default exports.
4
+ *
5
+ * @example
6
+ * const mod = await interopDefault(import('./module.js'))
7
+ */
7
8
  declare function interopDefault<T>(m: T | Promise<T>): Promise<T extends {
8
- default: infer U;
9
+ default: infer U;
9
10
  } ? U : T>;
10
11
 
11
- export { interopDefault };
12
+ //#endregion
13
+ export { interopDefault };
package/dist/module.js ADDED
@@ -0,0 +1,14 @@
1
+ //#region src/module.ts
2
+ /**
3
+ * Interop helper for default exports.
4
+ *
5
+ * @example
6
+ * const mod = await interopDefault(import('./module.js'))
7
+ */
8
+ async function interopDefault(m) {
9
+ const resolved = await m;
10
+ return resolved.default || resolved;
11
+ }
12
+
13
+ //#endregion
14
+ export { interopDefault };
package/dist/object.d.ts CHANGED
@@ -1,14 +1,33 @@
1
+ //#region src/object.d.ts
1
2
  /**
2
- * Strictly typed `Object.keys`.
3
- */
3
+ * A simple general purpose memoizer utility.
4
+ * - Lazily computes a value when accessed
5
+ * - Auto-caches the result by overwriting the getter
6
+ *
7
+ * @remarks
8
+ * Useful for deferring initialization or expensive operations. Unlike a simple getter, there is no runtime overhead after the first invokation, since the getter itself is overwritten with the memoized value.
9
+ *
10
+ * @example
11
+ * const myValue = lazy(() => 'Hello, World!')
12
+ * console.log(myValue.value) // Computes value, overwrites getter
13
+ * console.log(myValue.value) // Returns cached value
14
+ * console.log(myValue.value) // Returns cached value
15
+ */
16
+ declare function memoize<T>(getter: () => T): {
17
+ value: T;
18
+ };
19
+ /**
20
+ * Strictly typed `Object.keys`.
21
+ */
4
22
  declare function objectKeys<T extends Record<any, any>>(obj: T): Array<`${keyof T & (string | number | boolean | null | undefined)}`>;
5
23
  /**
6
- * Strictly typed `Object.entries`.
7
- */
24
+ * Strictly typed `Object.entries`.
25
+ */
8
26
  declare function objectEntries<T extends Record<any, any>>(obj: T): Array<[keyof T, T[keyof T]]>;
9
27
  /**
10
- * Deeply applies a callback to every key-value pair in the given object, as well as nested objects and arrays.
11
- */
28
+ * Deeply applies a callback to every key-value pair in the given object, as well as nested objects and arrays.
29
+ */
12
30
  declare function deepApply<T extends Record<any, any>>(data: T, callback: (item: T, key: keyof T, value: T[keyof T]) => void): void;
13
31
 
14
- export { deepApply, objectEntries, objectKeys };
32
+ //#endregion
33
+ export { deepApply, memoize, objectEntries, objectKeys };
package/dist/object.js ADDED
@@ -0,0 +1,51 @@
1
+ //#region src/object.ts
2
+ /**
3
+ * A simple general purpose memoizer utility.
4
+ * - Lazily computes a value when accessed
5
+ * - Auto-caches the result by overwriting the getter
6
+ *
7
+ * @remarks
8
+ * Useful for deferring initialization or expensive operations. Unlike a simple getter, there is no runtime overhead after the first invokation, since the getter itself is overwritten with the memoized value.
9
+ *
10
+ * @example
11
+ * const myValue = lazy(() => 'Hello, World!')
12
+ * console.log(myValue.value) // Computes value, overwrites getter
13
+ * console.log(myValue.value) // Returns cached value
14
+ * console.log(myValue.value) // Returns cached value
15
+ */
16
+ function memoize(getter) {
17
+ return { get value() {
18
+ const value = getter();
19
+ Object.defineProperty(this, "value", { value });
20
+ return value;
21
+ } };
22
+ }
23
+ /**
24
+ * Strictly typed `Object.keys`.
25
+ */
26
+ function objectKeys(obj) {
27
+ return Object.keys(obj);
28
+ }
29
+ /**
30
+ * Strictly typed `Object.entries`.
31
+ */
32
+ function objectEntries(obj) {
33
+ return Object.entries(obj);
34
+ }
35
+ /**
36
+ * Deeply applies a callback to every key-value pair in the given object, as well as nested objects and arrays.
37
+ */
38
+ function deepApply(data, callback) {
39
+ for (const [key, value] of Object.entries(data)) {
40
+ callback(data, key, value);
41
+ if (Array.isArray(value)) {
42
+ for (const element of value) if (isObject(element)) deepApply(element, callback);
43
+ } else if (isObject(value)) deepApply(value, callback);
44
+ }
45
+ }
46
+ function isObject(value) {
47
+ return Object.prototype.toString.call(value) === "[object Object]";
48
+ }
49
+
50
+ //#endregion
51
+ export { deepApply, memoize, objectEntries, objectKeys };
package/dist/path.d.ts CHANGED
@@ -1,40 +1,42 @@
1
+ //#region src/path.d.ts
1
2
  type QueryValue = string | number | boolean | QueryValue[] | Record<string, any> | null | undefined;
2
3
  type QueryObject = Record<string, QueryValue | QueryValue[]>;
3
4
  /**
4
- * Removes the leading slash from the given path if it has one.
5
- */
5
+ * Removes the leading slash from the given path if it has one.
6
+ */
6
7
  declare function withoutLeadingSlash(path?: string): string;
7
8
  /**
8
- * Adds a leading slash to the given path if it does not already have one.
9
- */
9
+ * Adds a leading slash to the given path if it does not already have one.
10
+ */
10
11
  declare function withLeadingSlash(path?: string): string;
11
12
  /**
12
- * Removes the trailing slash from the given path if it has one.
13
- */
13
+ * Removes the trailing slash from the given path if it has one.
14
+ */
14
15
  declare function withoutTrailingSlash(path?: string): string;
15
16
  /**
16
- * Adds a trailing slash to the given path if it does not already have one
17
- */
17
+ * Adds a trailing slash to the given path if it does not already have one
18
+ */
18
19
  declare function withTrailingSlash(path?: string): string;
19
20
  /**
20
- * Joins the given URL path segments, ensuring that there is only one slash between them.
21
- */
21
+ * Joins the given URL path segments, ensuring that there is only one slash between them.
22
+ */
22
23
  declare function joinURL(...paths: (string | undefined)[]): string;
23
24
  /**
24
- * Adds the base path to the input path, if it is not already present.
25
- */
25
+ * Adds the base path to the input path, if it is not already present.
26
+ */
26
27
  declare function withBase(input?: string, base?: string): string;
27
28
  /**
28
- * Removes the base path from the input path, if it is present.
29
- */
29
+ * Removes the base path from the input path, if it is present.
30
+ */
30
31
  declare function withoutBase(input?: string, base?: string): string;
31
32
  /**
32
- * Returns the pathname of the given path, which is the path without the query string.
33
- */
33
+ * Returns the pathname of the given path, which is the path without the query string.
34
+ */
34
35
  declare function getPathname(path?: string): string;
35
36
  /**
36
- * Returns the URL with the given query parameters. If a query parameter is undefined, it is omitted.
37
- */
37
+ * Returns the URL with the given query parameters. If a query parameter is undefined, it is omitted.
38
+ */
38
39
  declare function withQuery(input: string, query?: QueryObject): string;
39
40
 
40
- export { type QueryObject, type QueryValue, getPathname, joinURL, withBase, withLeadingSlash, withQuery, withTrailingSlash, withoutBase, withoutLeadingSlash, withoutTrailingSlash };
41
+ //#endregion
42
+ export { QueryObject, QueryValue, getPathname, joinURL, withBase, withLeadingSlash, withQuery, withTrailingSlash, withoutBase, withoutLeadingSlash, withoutTrailingSlash };
package/dist/path.js ADDED
@@ -0,0 +1,105 @@
1
+ //#region src/path.ts
2
+ /**
3
+ * Removes the leading slash from the given path if it has one.
4
+ */
5
+ function withoutLeadingSlash(path) {
6
+ if (!path || path === "/") return "/";
7
+ return path[0] === "/" ? path.slice(1) : path;
8
+ }
9
+ /**
10
+ * Adds a leading slash to the given path if it does not already have one.
11
+ */
12
+ function withLeadingSlash(path) {
13
+ if (!path || path === "/") return "/";
14
+ return path[0] === "/" ? path : `/${path}`;
15
+ }
16
+ /**
17
+ * Removes the trailing slash from the given path if it has one.
18
+ */
19
+ function withoutTrailingSlash(path) {
20
+ if (!path || path === "/") return "/";
21
+ return path[path.length - 1] === "/" ? path.slice(0, -1) : path;
22
+ }
23
+ /**
24
+ * Adds a trailing slash to the given path if it does not already have one
25
+ */
26
+ function withTrailingSlash(path) {
27
+ if (!path || path === "/") return "/";
28
+ return path[path.length - 1] === "/" ? path : `${path}/`;
29
+ }
30
+ /**
31
+ * Joins the given URL path segments, ensuring that there is only one slash between them.
32
+ */
33
+ function joinURL(...paths) {
34
+ let result = "";
35
+ for (let i = 0; i < paths.length; i++) {
36
+ const path = paths[i];
37
+ if (!result || result === "/") {
38
+ result = path || "/";
39
+ continue;
40
+ }
41
+ if (!path || path === "/") continue;
42
+ const resultHasTrailing = result[result.length - 1] === "/";
43
+ const pathHasLeading = path[0] === "/";
44
+ if (resultHasTrailing && pathHasLeading) result += path.slice(1);
45
+ else if (!resultHasTrailing && !pathHasLeading) result += `/${path}`;
46
+ else result += path;
47
+ }
48
+ return result;
49
+ }
50
+ /**
51
+ * Adds the base path to the input path, if it is not already present.
52
+ */
53
+ function withBase(input = "", base = "") {
54
+ if (!base || base === "/") return input;
55
+ const _base = withoutTrailingSlash(base);
56
+ if (input.startsWith(_base)) return input;
57
+ return joinURL(_base, input);
58
+ }
59
+ /**
60
+ * Removes the base path from the input path, if it is present.
61
+ */
62
+ function withoutBase(input = "", base = "") {
63
+ if (!base || base === "/") return input;
64
+ const _base = withoutTrailingSlash(base);
65
+ if (!input.startsWith(_base)) return input;
66
+ const trimmed = input.slice(_base.length);
67
+ return trimmed[0] === "/" ? trimmed : `/${trimmed}`;
68
+ }
69
+ /**
70
+ * Returns the pathname of the given path, which is the path without the query string.
71
+ */
72
+ function getPathname(path = "/") {
73
+ return path.startsWith("/") ? path.split("?")[0] : new URL(path, "http://localhost").pathname;
74
+ }
75
+ /**
76
+ * Returns the URL with the given query parameters. If a query parameter is undefined, it is omitted.
77
+ */
78
+ function withQuery(input, query) {
79
+ if (!query || Object.keys(query).length === 0) return input;
80
+ const searchIndex = input.indexOf("?");
81
+ const hasExistingParams = searchIndex !== -1;
82
+ const base = hasExistingParams ? input.slice(0, searchIndex) : input;
83
+ const searchParams = hasExistingParams ? new URLSearchParams(input.slice(searchIndex + 1)) : new URLSearchParams();
84
+ for (const [key, value] of Object.entries(query)) {
85
+ if (value === void 0) {
86
+ searchParams.delete(key);
87
+ continue;
88
+ }
89
+ if (Array.isArray(value)) {
90
+ if (value.length === 0) continue;
91
+ for (const item of value) if (item !== void 0) searchParams.append(key, normalizeQueryValue(item));
92
+ } else searchParams.set(key, normalizeQueryValue(value));
93
+ }
94
+ const queryString = searchParams.toString();
95
+ return queryString ? `${base}?${queryString}` : base;
96
+ }
97
+ function normalizeQueryValue(value) {
98
+ if (value === null) return "";
99
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
100
+ if (typeof value === "object") return JSON.stringify(value);
101
+ return String(value);
102
+ }
103
+
104
+ //#endregion
105
+ export { getPathname, joinURL, withBase, withLeadingSlash, withQuery, withTrailingSlash, withoutBase, withoutLeadingSlash, withoutTrailingSlash };
@@ -0,0 +1,34 @@
1
+ //#region src/result.d.ts
2
+ type Result<T, E> = Ok<T> | Err<E>;
3
+ interface OkData<T> {
4
+ value: T;
5
+ error: undefined;
6
+ }
7
+ interface ErrData<E> {
8
+ value: undefined;
9
+ error: E;
10
+ }
11
+ type ResultData<T, E> = OkData<T> | ErrData<E>;
12
+ declare class Ok<T> {
13
+ readonly value: T;
14
+ readonly ok: true;
15
+ constructor(value: T);
16
+ }
17
+ declare class Err<E> {
18
+ readonly error: E;
19
+ readonly ok: false;
20
+ constructor(error: E);
21
+ }
22
+ declare function ok<T>(value: T): Ok<T>;
23
+ declare function err<E extends string = string>(error: E): Err<E>;
24
+ declare function err<E = unknown>(error: E): Err<E>;
25
+ declare function toResult<T, E = unknown>(fn: () => T): Result<T, E>;
26
+ declare function toResult<T, E = unknown>(promise: Promise<T>): Promise<Result<T, E>>;
27
+ declare function unwrapResult<T>(result: Ok<T>): OkData<T>;
28
+ declare function unwrapResult<E>(result: Err<E>): ErrData<E>;
29
+ declare function unwrapResult<T, E>(result: Result<T, E>): ResultData<T, E>;
30
+ declare function tryCatch<T, E = unknown>(fn: () => T): ResultData<T, E>;
31
+ declare function tryCatch<T, E = unknown>(promise: Promise<T>): Promise<ResultData<T, E>>;
32
+
33
+ //#endregion
34
+ export { Err, ErrData, Ok, OkData, Result, ResultData, err, ok, toResult, tryCatch, unwrapResult };
package/dist/result.js ADDED
@@ -0,0 +1,45 @@
1
+ //#region src/result.ts
2
+ var Ok = class {
3
+ value;
4
+ ok = true;
5
+ constructor(value) {
6
+ this.value = value;
7
+ }
8
+ };
9
+ var Err = class {
10
+ error;
11
+ ok = false;
12
+ constructor(error) {
13
+ this.error = error;
14
+ }
15
+ };
16
+ function ok(value) {
17
+ return new Ok(value);
18
+ }
19
+ function err(error) {
20
+ return new Err(error);
21
+ }
22
+ function toResult(fnOrPromise) {
23
+ if (fnOrPromise instanceof Promise) return fnOrPromise.then(ok).catch(err);
24
+ try {
25
+ return ok(fnOrPromise());
26
+ } catch (error) {
27
+ return err(error);
28
+ }
29
+ }
30
+ function unwrapResult(result) {
31
+ return result.ok ? {
32
+ value: result.value,
33
+ error: void 0
34
+ } : {
35
+ value: void 0,
36
+ error: result.error
37
+ };
38
+ }
39
+ function tryCatch(fnOrPromise) {
40
+ if (fnOrPromise instanceof Promise) return toResult(fnOrPromise).then((result) => unwrapResult(result));
41
+ return unwrapResult(toResult(fnOrPromise));
42
+ }
43
+
44
+ //#endregion
45
+ export { Err, Ok, err, ok, toResult, tryCatch, unwrapResult };
package/dist/string.d.ts CHANGED
@@ -1,19 +1,21 @@
1
+ //#region src/string.d.ts
1
2
  /**
2
- * Simple template engine to replace variables in a string.
3
- *
4
- * @example
5
- * const str = 'Hello, {name}!'
6
- * const variables = { name: 'world' }
7
- *
8
- * console.log(template(str, variables)) // Hello, world!
9
- */
3
+ * Simple template engine to replace variables in a string.
4
+ *
5
+ * @example
6
+ * const str = 'Hello, {name}!'
7
+ * const variables = { name: 'world' }
8
+ *
9
+ * console.log(template(str, variables)) // Hello, world!
10
+ */
10
11
  declare function template(str: string, variables: Record<string | number, any>, fallback?: string | ((key: string) => string)): string;
11
12
  /**
12
- * Generates a random string.
13
- *
14
- * @remarks Ported from `nanoid`.
15
- * @see https://github.com/ai/nanoid
16
- */
13
+ * Generates a random string.
14
+ *
15
+ * @remarks Ported from `nanoid`.
16
+ * @see https://github.com/ai/nanoid
17
+ */
17
18
  declare function generateRandomId(size?: number, dict?: string): string;
18
19
 
19
- export { generateRandomId, template };
20
+ //#endregion
21
+ export { generateRandomId, template };
package/dist/string.js ADDED
@@ -0,0 +1,32 @@
1
+ //#region src/string.ts
2
+ const URL_ALPHABET = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
3
+ /**
4
+ * Simple template engine to replace variables in a string.
5
+ *
6
+ * @example
7
+ * const str = 'Hello, {name}!'
8
+ * const variables = { name: 'world' }
9
+ *
10
+ * console.log(template(str, variables)) // Hello, world!
11
+ */
12
+ function template(str, variables, fallback) {
13
+ return str.replace(/\{(\w+)\}/g, (_, key) => {
14
+ return variables[key] || ((typeof fallback === "function" ? fallback(key) : fallback) ?? key);
15
+ });
16
+ }
17
+ /**
18
+ * Generates a random string.
19
+ *
20
+ * @remarks Ported from `nanoid`.
21
+ * @see https://github.com/ai/nanoid
22
+ */
23
+ function generateRandomId(size = 16, dict = URL_ALPHABET) {
24
+ let id = "";
25
+ let i = size;
26
+ const len = dict.length;
27
+ while (i--) id += dict[Math.random() * len | 0];
28
+ return id;
29
+ }
30
+
31
+ //#endregion
32
+ export { generateRandomId, template };
package/dist/types.d.ts CHANGED
@@ -1,8 +1,8 @@
1
+ //#region src/types.d.ts
1
2
  type AutocompletableString = string & {};
2
3
  type LooseAutocomplete<T extends string> = T | AutocompletableString;
3
4
  /** Also commonly referred to as `Prettify` */
4
- type UnifyIntersection<T> = {
5
- [K in keyof T]: T[K];
6
- } & {};
5
+ type UnifyIntersection<T> = { [K in keyof T]: T[K] } & {};
7
6
 
8
- export type { AutocompletableString, LooseAutocomplete, UnifyIntersection };
7
+ //#endregion
8
+ export { AutocompletableString, LooseAutocomplete, UnifyIntersection };
package/dist/types.js ADDED
File without changes
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "utilful",
3
3
  "type": "module",
4
- "version": "1.2.1",
5
- "packageManager": "pnpm@10.5.2",
4
+ "version": "2.1.0",
5
+ "packageManager": "pnpm@10.11.0",
6
6
  "description": "A collection of TypeScript utilities",
7
7
  "author": "Johann Schopplich <hello@johannschopplich.com>",
8
8
  "license": "MIT",
@@ -28,18 +28,18 @@
28
28
  "types": "./dist/csv.d.mts",
29
29
  "default": "./dist/csv.mjs"
30
30
  },
31
+ "./defu": {
32
+ "types": "./dist/defu.d.mts",
33
+ "default": "./dist/defu.mjs"
34
+ },
31
35
  "./emitter": {
32
- "types": "./dist/csv.d.mts",
33
- "default": "./dist/csv.mjs"
36
+ "types": "./dist/emitter.d.mts",
37
+ "default": "./dist/emitter.mjs"
34
38
  },
35
39
  "./json": {
36
40
  "types": "./dist/json.d.mts",
37
41
  "default": "./dist/json.mjs"
38
42
  },
39
- "./lazy": {
40
- "types": "./dist/lazy.d.mts",
41
- "default": "./dist/lazy.mjs"
42
- },
43
43
  "./module": {
44
44
  "types": "./dist/module.d.mts",
45
45
  "default": "./dist/module.mjs"
@@ -52,6 +52,10 @@
52
52
  "types": "./dist/path.d.mts",
53
53
  "default": "./dist/path.mjs"
54
54
  },
55
+ "./result": {
56
+ "types": "./dist/result.d.mts",
57
+ "default": "./dist/result.mjs"
58
+ },
55
59
  "./string": {
56
60
  "types": "./dist/string.d.mts",
57
61
  "default": "./dist/string.mjs"
@@ -61,12 +65,12 @@
61
65
  "default": "./dist/types.mjs"
62
66
  }
63
67
  },
64
- "types": "./dist/index.d.ts",
68
+ "types": "./dist/index.d.mts",
65
69
  "files": [
66
70
  "dist"
67
71
  ],
68
72
  "scripts": {
69
- "build": "unbuild",
73
+ "build": "tsdown",
70
74
  "lint": "eslint .",
71
75
  "lint:fix": "eslint . --fix",
72
76
  "test": "vitest",
@@ -74,17 +78,18 @@
74
78
  "release": "bumpp"
75
79
  },
76
80
  "devDependencies": {
77
- "@antfu/eslint-config": "^4.3.0",
78
- "@types/node": "^22.13.5",
79
- "bumpp": "^10.0.3",
80
- "eslint": "^9.21.0",
81
- "typescript": "^5.7.3",
82
- "unbuild": "^3.5.0",
83
- "vitest": "^3.0.7"
81
+ "@antfu/eslint-config": "^4.13.2",
82
+ "@types/node": "^22.15.21",
83
+ "bumpp": "^10.1.1",
84
+ "eslint": "^9.27.0",
85
+ "tsdown": "^0.12.3",
86
+ "typescript": "^5.8.3",
87
+ "vitest": "^3.1.4"
84
88
  },
85
89
  "pnpm": {
86
90
  "onlyBuiltDependencies": [
87
- "esbuild"
91
+ "esbuild",
92
+ "unrs-resolver"
88
93
  ]
89
94
  }
90
95
  }