utilful 2.0.0 → 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.
- package/README.md +100 -10
- package/dist/array.d.ts +7 -5
- package/dist/array.js +11 -0
- package/dist/csv.d.ts +57 -57
- package/dist/csv.js +98 -0
- package/dist/defu.d.ts +16 -0
- package/dist/defu.js +34 -0
- package/dist/emitter.d.ts +20 -14
- package/dist/emitter.js +32 -0
- package/dist/index.d.ts +12 -10
- package/dist/index.js +12 -0
- package/dist/json.d.ts +13 -11
- package/dist/json.js +34 -0
- package/dist/module.d.ts +9 -7
- package/dist/module.js +14 -0
- package/dist/object.d.ts +23 -21
- package/dist/object.js +51 -0
- package/dist/path.d.ts +21 -19
- package/dist/path.js +105 -0
- package/dist/result.d.ts +13 -11
- package/dist/result.js +45 -0
- package/dist/string.d.ts +16 -14
- package/dist/string.js +32 -0
- package/dist/types.d.ts +4 -4
- package/dist/types.js +0 -0
- package/package.json +18 -13
- package/dist/array.d.mts +0 -10
- package/dist/array.mjs +0 -6
- package/dist/csv.d.mts +0 -67
- package/dist/csv.mjs +0 -77
- package/dist/emitter.d.mts +0 -24
- package/dist/emitter.mjs +0 -63
- package/dist/index.d.mts +0 -10
- package/dist/index.mjs +0 -9
- package/dist/json.d.mts +0 -16
- package/dist/json.mjs +0 -26
- package/dist/module.d.mts +0 -11
- package/dist/module.mjs +0 -6
- package/dist/object.d.mts +0 -31
- package/dist/object.mjs +0 -34
- package/dist/path.d.mts +0 -40
- package/dist/path.mjs +0 -113
- package/dist/result.d.mts +0 -32
- package/dist/result.mjs +0 -43
- package/dist/string.d.mts +0 -19
- package/dist/string.mjs +0 -16
- package/dist/types.d.mts +0 -8
- package/dist/types.mjs +0 -1
package/dist/csv.mjs
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
function createCSV(data, columns, options = {}) {
|
|
2
|
-
const {
|
|
3
|
-
delimiter = ",",
|
|
4
|
-
addHeader = true,
|
|
5
|
-
quoteAll = false
|
|
6
|
-
} = options;
|
|
7
|
-
const escapeAndQuote = (value) => escapeCSVValue(value, { delimiter, quoteAll });
|
|
8
|
-
const rows = data.map(
|
|
9
|
-
(obj) => columns.map((key) => escapeAndQuote(obj[key])).join(delimiter)
|
|
10
|
-
);
|
|
11
|
-
if (addHeader) {
|
|
12
|
-
rows.unshift(columns.map(escapeAndQuote).join(delimiter));
|
|
13
|
-
}
|
|
14
|
-
return rows.join("\n");
|
|
15
|
-
}
|
|
16
|
-
function escapeCSVValue(value, options = {}) {
|
|
17
|
-
const {
|
|
18
|
-
delimiter = ",",
|
|
19
|
-
quoteAll = false
|
|
20
|
-
} = options;
|
|
21
|
-
if (value == null) {
|
|
22
|
-
return "";
|
|
23
|
-
}
|
|
24
|
-
const stringValue = String(value);
|
|
25
|
-
const needsQuoting = quoteAll || stringValue.includes(delimiter) || stringValue.includes('"') || stringValue.includes("\n") || stringValue.includes("\r");
|
|
26
|
-
if (needsQuoting) {
|
|
27
|
-
return `"${stringValue.replaceAll('"', '""')}"`;
|
|
28
|
-
}
|
|
29
|
-
return stringValue;
|
|
30
|
-
}
|
|
31
|
-
function parseCSV(csv, options = {}) {
|
|
32
|
-
if (!csv?.trim())
|
|
33
|
-
return [];
|
|
34
|
-
const rows = [];
|
|
35
|
-
let currentRow = [];
|
|
36
|
-
let currentField = "";
|
|
37
|
-
let inQuotes = false;
|
|
38
|
-
const { delimiter = ",", trimValues = true } = options;
|
|
39
|
-
for (let i = 0; i < csv.length; i++) {
|
|
40
|
-
const char = csv[i];
|
|
41
|
-
const nextChar = i + 1 < csv.length ? csv[i + 1] : "";
|
|
42
|
-
if (char === '"') {
|
|
43
|
-
if (inQuotes && nextChar === '"') {
|
|
44
|
-
currentField += '"';
|
|
45
|
-
i++;
|
|
46
|
-
} else {
|
|
47
|
-
inQuotes = !inQuotes;
|
|
48
|
-
}
|
|
49
|
-
} else if (char === delimiter && !inQuotes) {
|
|
50
|
-
currentRow.push(trimValues ? currentField.trim() : currentField);
|
|
51
|
-
currentField = "";
|
|
52
|
-
} else if ((char === "\n" || char === "\r" && nextChar === "\n") && !inQuotes) {
|
|
53
|
-
if (char === "\r")
|
|
54
|
-
i++;
|
|
55
|
-
currentRow.push(trimValues ? currentField.trim() : currentField);
|
|
56
|
-
rows.push(currentRow);
|
|
57
|
-
currentRow = [];
|
|
58
|
-
currentField = "";
|
|
59
|
-
} else {
|
|
60
|
-
currentField += char;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
if (currentField || currentRow.length > 0) {
|
|
64
|
-
currentRow.push(trimValues ? currentField.trim() : currentField);
|
|
65
|
-
rows.push(currentRow);
|
|
66
|
-
}
|
|
67
|
-
if (rows.length <= 1)
|
|
68
|
-
return [];
|
|
69
|
-
const headers = rows[0];
|
|
70
|
-
return rows.slice(1).filter((row) => row.some((field) => field.trim().length > 0)).map((values) => {
|
|
71
|
-
return Object.fromEntries(
|
|
72
|
-
headers.map((header, index) => [header, index < values.length ? values[index] : ""])
|
|
73
|
-
);
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export { createCSV, escapeCSVValue, parseCSV };
|
package/dist/emitter.d.mts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
type EventType = string | symbol;
|
|
2
|
-
type Handler<T = unknown> = (event: T) => void;
|
|
3
|
-
type WildcardHandler<T = Record<string, unknown>> = (type: keyof T, event: T[keyof T]) => void;
|
|
4
|
-
type EventHandlerList<T = unknown> = Handler<T>[];
|
|
5
|
-
type WildCardEventHandlerList<T = Record<string, unknown>> = WildcardHandler<T>[];
|
|
6
|
-
type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<keyof Events | '*', EventHandlerList<Events[keyof Events]> | WildCardEventHandlerList<Events>>;
|
|
7
|
-
interface Emitter<Events extends Record<EventType, unknown>> {
|
|
8
|
-
events: EventHandlerMap<Events>;
|
|
9
|
-
on<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>): void;
|
|
10
|
-
on(type: '*', handler: WildcardHandler<Events>): void;
|
|
11
|
-
off<Key extends keyof Events>(type: Key, handler?: Handler<Events[Key]>): void;
|
|
12
|
-
off(type: '*', handler: WildcardHandler<Events>): void;
|
|
13
|
-
emit<Key extends keyof Events>(type: Key, event: Events[Key]): void;
|
|
14
|
-
emit<Key extends keyof Events>(type: undefined extends Events[Key] ? Key : never): void;
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Simple functional event emitter / pubsub.
|
|
18
|
-
*
|
|
19
|
-
* @remarks Ported from `mitt`.
|
|
20
|
-
* @see https://github.com/developit/mitt
|
|
21
|
-
*/
|
|
22
|
-
declare function createEmitter<Events extends Record<EventType, unknown>>(events?: EventHandlerMap<Events>): Emitter<Events>;
|
|
23
|
-
|
|
24
|
-
export { type Emitter, type EventHandlerList, type EventHandlerMap, type EventType, type Handler, type WildCardEventHandlerList, type WildcardHandler, createEmitter };
|
package/dist/emitter.mjs
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
function createEmitter(events) {
|
|
2
|
-
events ||= /* @__PURE__ */ new Map();
|
|
3
|
-
return {
|
|
4
|
-
/**
|
|
5
|
-
* A Map of event names to registered handler functions.
|
|
6
|
-
*/
|
|
7
|
-
events,
|
|
8
|
-
/**
|
|
9
|
-
* Register an event handler for the given type.
|
|
10
|
-
*
|
|
11
|
-
* @memberOf createEmitter
|
|
12
|
-
*/
|
|
13
|
-
on(type, handler) {
|
|
14
|
-
const handlers = events.get(type);
|
|
15
|
-
if (handlers) {
|
|
16
|
-
handlers.push(handler);
|
|
17
|
-
} else {
|
|
18
|
-
events.set(type, [handler]);
|
|
19
|
-
}
|
|
20
|
-
},
|
|
21
|
-
/**
|
|
22
|
-
* Remove an event handler for the given type.
|
|
23
|
-
*
|
|
24
|
-
* @remarks
|
|
25
|
-
* If `handler` is omitted, all handlers of the given type are removed.
|
|
26
|
-
*
|
|
27
|
-
* @memberOf createEmitter
|
|
28
|
-
*/
|
|
29
|
-
off(type, handler) {
|
|
30
|
-
const handlers = events.get(type);
|
|
31
|
-
if (handlers) {
|
|
32
|
-
if (handler) {
|
|
33
|
-
handlers.splice(handlers.indexOf(handler) >>> 0, 1);
|
|
34
|
-
} else {
|
|
35
|
-
events.set(type, []);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
},
|
|
39
|
-
/**
|
|
40
|
-
* Invoke all handlers for the given type.
|
|
41
|
-
*
|
|
42
|
-
* @remarks
|
|
43
|
-
* If present, `'*'` handlers are invoked after type-matched handlers.
|
|
44
|
-
* Manually firing '*' handlers is not supported.
|
|
45
|
-
*
|
|
46
|
-
* @memberOf createEmitter
|
|
47
|
-
*/
|
|
48
|
-
emit(type, evt) {
|
|
49
|
-
let handlers = events.get(type);
|
|
50
|
-
if (handlers) {
|
|
51
|
-
for (const handler of [...handlers])
|
|
52
|
-
handler(evt);
|
|
53
|
-
}
|
|
54
|
-
handlers = events.get("*");
|
|
55
|
-
if (handlers) {
|
|
56
|
-
for (const handler of [...handlers])
|
|
57
|
-
handler(type, evt);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export { createEmitter };
|
package/dist/index.d.mts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export { MaybeArray, toArray } from './array.mjs';
|
|
2
|
-
export { CSVRow, createCSV, escapeCSVValue, parseCSV } from './csv.mjs';
|
|
3
|
-
export { Emitter, EventHandlerList, EventHandlerMap, EventType, Handler, WildCardEventHandlerList, WildcardHandler, createEmitter } from './emitter.mjs';
|
|
4
|
-
export { cloneJSON, tryParseJSON } from './json.mjs';
|
|
5
|
-
export { interopDefault } from './module.mjs';
|
|
6
|
-
export { deepApply, memoize, objectEntries, objectKeys } from './object.mjs';
|
|
7
|
-
export { QueryObject, QueryValue, getPathname, joinURL, withBase, withLeadingSlash, withQuery, withTrailingSlash, withoutBase, withoutLeadingSlash, withoutTrailingSlash } from './path.mjs';
|
|
8
|
-
export { Err, ErrData, Ok, OkData, Result, ResultData, err, ok, toResult, tryCatch, unwrapResult } from './result.mjs';
|
|
9
|
-
export { generateRandomId, template } from './string.mjs';
|
|
10
|
-
export { AutocompletableString, LooseAutocomplete, UnifyIntersection } from './types.mjs';
|
package/dist/index.mjs
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export { toArray } from './array.mjs';
|
|
2
|
-
export { createCSV, escapeCSVValue, parseCSV } from './csv.mjs';
|
|
3
|
-
export { createEmitter } from './emitter.mjs';
|
|
4
|
-
export { cloneJSON, tryParseJSON } from './json.mjs';
|
|
5
|
-
export { interopDefault } from './module.mjs';
|
|
6
|
-
export { deepApply, memoize, objectEntries, objectKeys } from './object.mjs';
|
|
7
|
-
export { getPathname, joinURL, withBase, withLeadingSlash, withQuery, withTrailingSlash, withoutBase, withoutLeadingSlash, withoutTrailingSlash } from './path.mjs';
|
|
8
|
-
export { Err, Ok, err, ok, toResult, tryCatch, unwrapResult } from './result.mjs';
|
|
9
|
-
export { generateRandomId, template } from './string.mjs';
|
package/dist/json.d.mts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
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
|
-
*/
|
|
7
|
-
declare function tryParseJSON<T = unknown>(value: unknown): T;
|
|
8
|
-
/**
|
|
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
|
-
*/
|
|
14
|
-
declare function cloneJSON<T>(value: T): T;
|
|
15
|
-
|
|
16
|
-
export { cloneJSON, tryParseJSON };
|
package/dist/json.mjs
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
function tryParseJSON(value) {
|
|
2
|
-
if (typeof value !== "string") {
|
|
3
|
-
return value;
|
|
4
|
-
}
|
|
5
|
-
try {
|
|
6
|
-
return JSON.parse(value);
|
|
7
|
-
} catch {
|
|
8
|
-
return value;
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
function cloneJSON(value) {
|
|
12
|
-
if (typeof value !== "object" || value === null) {
|
|
13
|
-
return value;
|
|
14
|
-
}
|
|
15
|
-
if (Array.isArray(value)) {
|
|
16
|
-
return value.map((e) => typeof e !== "object" || e === null ? e : cloneJSON(e));
|
|
17
|
-
}
|
|
18
|
-
const result = {};
|
|
19
|
-
for (const k in value) {
|
|
20
|
-
const v = value[k];
|
|
21
|
-
result[k] = typeof v !== "object" || v === null ? v : cloneJSON(v);
|
|
22
|
-
}
|
|
23
|
-
return result;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export { cloneJSON, tryParseJSON };
|
package/dist/module.d.mts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Interop helper for default exports.
|
|
3
|
-
*
|
|
4
|
-
* @example
|
|
5
|
-
* const mod = await interopDefault(import('./module.js'))
|
|
6
|
-
*/
|
|
7
|
-
declare function interopDefault<T>(m: T | Promise<T>): Promise<T extends {
|
|
8
|
-
default: infer U;
|
|
9
|
-
} ? U : T>;
|
|
10
|
-
|
|
11
|
-
export { interopDefault };
|
package/dist/module.mjs
DELETED
package/dist/object.d.mts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A simple general purpose memoizer utility.
|
|
3
|
-
* - Lazily computes a value when accessed
|
|
4
|
-
* - Auto-caches the result by overwriting the getter
|
|
5
|
-
*
|
|
6
|
-
* @remarks
|
|
7
|
-
* 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.
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* const myValue = lazy(() => 'Hello, World!')
|
|
11
|
-
* console.log(myValue.value) // Computes value, overwrites getter
|
|
12
|
-
* console.log(myValue.value) // Returns cached value
|
|
13
|
-
* console.log(myValue.value) // Returns cached value
|
|
14
|
-
*/
|
|
15
|
-
declare function memoize<T>(getter: () => T): {
|
|
16
|
-
value: T;
|
|
17
|
-
};
|
|
18
|
-
/**
|
|
19
|
-
* Strictly typed `Object.keys`.
|
|
20
|
-
*/
|
|
21
|
-
declare function objectKeys<T extends Record<any, any>>(obj: T): Array<`${keyof T & (string | number | boolean | null | undefined)}`>;
|
|
22
|
-
/**
|
|
23
|
-
* Strictly typed `Object.entries`.
|
|
24
|
-
*/
|
|
25
|
-
declare function objectEntries<T extends Record<any, any>>(obj: T): Array<[keyof T, T[keyof T]]>;
|
|
26
|
-
/**
|
|
27
|
-
* Deeply applies a callback to every key-value pair in the given object, as well as nested objects and arrays.
|
|
28
|
-
*/
|
|
29
|
-
declare function deepApply<T extends Record<any, any>>(data: T, callback: (item: T, key: keyof T, value: T[keyof T]) => void): void;
|
|
30
|
-
|
|
31
|
-
export { deepApply, memoize, objectEntries, objectKeys };
|
package/dist/object.mjs
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
function memoize(getter) {
|
|
2
|
-
return {
|
|
3
|
-
get value() {
|
|
4
|
-
const value = getter();
|
|
5
|
-
Object.defineProperty(this, "value", { value });
|
|
6
|
-
return value;
|
|
7
|
-
}
|
|
8
|
-
};
|
|
9
|
-
}
|
|
10
|
-
function objectKeys(obj) {
|
|
11
|
-
return Object.keys(obj);
|
|
12
|
-
}
|
|
13
|
-
function objectEntries(obj) {
|
|
14
|
-
return Object.entries(obj);
|
|
15
|
-
}
|
|
16
|
-
function deepApply(data, callback) {
|
|
17
|
-
for (const [key, value] of Object.entries(data)) {
|
|
18
|
-
callback(data, key, value);
|
|
19
|
-
if (Array.isArray(value)) {
|
|
20
|
-
for (const element of value) {
|
|
21
|
-
if (isObject(element)) {
|
|
22
|
-
deepApply(element, callback);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
} else if (isObject(value)) {
|
|
26
|
-
deepApply(value, callback);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
function isObject(value) {
|
|
31
|
-
return Object.prototype.toString.call(value) === "[object Object]";
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export { deepApply, memoize, objectEntries, objectKeys };
|
package/dist/path.d.mts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
type QueryValue = string | number | boolean | QueryValue[] | Record<string, any> | null | undefined;
|
|
2
|
-
type QueryObject = Record<string, QueryValue | QueryValue[]>;
|
|
3
|
-
/**
|
|
4
|
-
* Removes the leading slash from the given path if it has one.
|
|
5
|
-
*/
|
|
6
|
-
declare function withoutLeadingSlash(path?: string): string;
|
|
7
|
-
/**
|
|
8
|
-
* Adds a leading slash to the given path if it does not already have one.
|
|
9
|
-
*/
|
|
10
|
-
declare function withLeadingSlash(path?: string): string;
|
|
11
|
-
/**
|
|
12
|
-
* Removes the trailing slash from the given path if it has one.
|
|
13
|
-
*/
|
|
14
|
-
declare function withoutTrailingSlash(path?: string): string;
|
|
15
|
-
/**
|
|
16
|
-
* Adds a trailing slash to the given path if it does not already have one
|
|
17
|
-
*/
|
|
18
|
-
declare function withTrailingSlash(path?: string): string;
|
|
19
|
-
/**
|
|
20
|
-
* Joins the given URL path segments, ensuring that there is only one slash between them.
|
|
21
|
-
*/
|
|
22
|
-
declare function joinURL(...paths: (string | undefined)[]): string;
|
|
23
|
-
/**
|
|
24
|
-
* Adds the base path to the input path, if it is not already present.
|
|
25
|
-
*/
|
|
26
|
-
declare function withBase(input?: string, base?: string): string;
|
|
27
|
-
/**
|
|
28
|
-
* Removes the base path from the input path, if it is present.
|
|
29
|
-
*/
|
|
30
|
-
declare function withoutBase(input?: string, base?: string): string;
|
|
31
|
-
/**
|
|
32
|
-
* Returns the pathname of the given path, which is the path without the query string.
|
|
33
|
-
*/
|
|
34
|
-
declare function getPathname(path?: string): string;
|
|
35
|
-
/**
|
|
36
|
-
* Returns the URL with the given query parameters. If a query parameter is undefined, it is omitted.
|
|
37
|
-
*/
|
|
38
|
-
declare function withQuery(input: string, query?: QueryObject): string;
|
|
39
|
-
|
|
40
|
-
export { type QueryObject, type QueryValue, getPathname, joinURL, withBase, withLeadingSlash, withQuery, withTrailingSlash, withoutBase, withoutLeadingSlash, withoutTrailingSlash };
|
package/dist/path.mjs
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
function withoutLeadingSlash(path) {
|
|
2
|
-
if (!path || path === "/") {
|
|
3
|
-
return "/";
|
|
4
|
-
}
|
|
5
|
-
return path[0] === "/" ? path.slice(1) : path;
|
|
6
|
-
}
|
|
7
|
-
function withLeadingSlash(path) {
|
|
8
|
-
if (!path || path === "/") {
|
|
9
|
-
return "/";
|
|
10
|
-
}
|
|
11
|
-
return path[0] === "/" ? path : `/${path}`;
|
|
12
|
-
}
|
|
13
|
-
function withoutTrailingSlash(path) {
|
|
14
|
-
if (!path || path === "/") {
|
|
15
|
-
return "/";
|
|
16
|
-
}
|
|
17
|
-
return path[path.length - 1] === "/" ? path.slice(0, -1) : path;
|
|
18
|
-
}
|
|
19
|
-
function withTrailingSlash(path) {
|
|
20
|
-
if (!path || path === "/") {
|
|
21
|
-
return "/";
|
|
22
|
-
}
|
|
23
|
-
return path[path.length - 1] === "/" ? path : `${path}/`;
|
|
24
|
-
}
|
|
25
|
-
function joinURL(...paths) {
|
|
26
|
-
let result = "";
|
|
27
|
-
for (let i = 0; i < paths.length; i++) {
|
|
28
|
-
const path = paths[i];
|
|
29
|
-
if (!result || result === "/") {
|
|
30
|
-
result = path || "/";
|
|
31
|
-
continue;
|
|
32
|
-
}
|
|
33
|
-
if (!path || path === "/") {
|
|
34
|
-
continue;
|
|
35
|
-
}
|
|
36
|
-
const resultHasTrailing = result[result.length - 1] === "/";
|
|
37
|
-
const pathHasLeading = path[0] === "/";
|
|
38
|
-
if (resultHasTrailing && pathHasLeading) {
|
|
39
|
-
result += path.slice(1);
|
|
40
|
-
} else if (!resultHasTrailing && !pathHasLeading) {
|
|
41
|
-
result += `/${path}`;
|
|
42
|
-
} else {
|
|
43
|
-
result += path;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return result;
|
|
47
|
-
}
|
|
48
|
-
function withBase(input = "", base = "") {
|
|
49
|
-
if (!base || base === "/") {
|
|
50
|
-
return input;
|
|
51
|
-
}
|
|
52
|
-
const _base = withoutTrailingSlash(base);
|
|
53
|
-
if (input.startsWith(_base)) {
|
|
54
|
-
return input;
|
|
55
|
-
}
|
|
56
|
-
return joinURL(_base, input);
|
|
57
|
-
}
|
|
58
|
-
function withoutBase(input = "", base = "") {
|
|
59
|
-
if (!base || base === "/") {
|
|
60
|
-
return input;
|
|
61
|
-
}
|
|
62
|
-
const _base = withoutTrailingSlash(base);
|
|
63
|
-
if (!input.startsWith(_base)) {
|
|
64
|
-
return input;
|
|
65
|
-
}
|
|
66
|
-
const trimmed = input.slice(_base.length);
|
|
67
|
-
return trimmed[0] === "/" ? trimmed : `/${trimmed}`;
|
|
68
|
-
}
|
|
69
|
-
function getPathname(path = "/") {
|
|
70
|
-
return path.startsWith("/") ? path.split("?")[0] : new URL(path, "http://localhost").pathname;
|
|
71
|
-
}
|
|
72
|
-
function withQuery(input, query) {
|
|
73
|
-
if (!query || Object.keys(query).length === 0) {
|
|
74
|
-
return input;
|
|
75
|
-
}
|
|
76
|
-
const searchIndex = input.indexOf("?");
|
|
77
|
-
const hasExistingParams = searchIndex !== -1;
|
|
78
|
-
const base = hasExistingParams ? input.slice(0, searchIndex) : input;
|
|
79
|
-
const searchParams = hasExistingParams ? new URLSearchParams(input.slice(searchIndex + 1)) : new URLSearchParams();
|
|
80
|
-
for (const [key, value] of Object.entries(query)) {
|
|
81
|
-
if (value === void 0) {
|
|
82
|
-
searchParams.delete(key);
|
|
83
|
-
continue;
|
|
84
|
-
}
|
|
85
|
-
if (Array.isArray(value)) {
|
|
86
|
-
if (value.length === 0)
|
|
87
|
-
continue;
|
|
88
|
-
for (const item of value) {
|
|
89
|
-
if (item !== void 0) {
|
|
90
|
-
searchParams.append(key, normalizeQueryValue(item));
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
} else {
|
|
94
|
-
searchParams.set(key, normalizeQueryValue(value));
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
const queryString = searchParams.toString();
|
|
98
|
-
return queryString ? `${base}?${queryString}` : base;
|
|
99
|
-
}
|
|
100
|
-
function normalizeQueryValue(value) {
|
|
101
|
-
if (value === null) {
|
|
102
|
-
return "";
|
|
103
|
-
}
|
|
104
|
-
if (typeof value === "number" || typeof value === "boolean") {
|
|
105
|
-
return String(value);
|
|
106
|
-
}
|
|
107
|
-
if (typeof value === "object") {
|
|
108
|
-
return JSON.stringify(value);
|
|
109
|
-
}
|
|
110
|
-
return String(value);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export { getPathname, joinURL, withBase, withLeadingSlash, withQuery, withTrailingSlash, withoutBase, withoutLeadingSlash, withoutTrailingSlash };
|
package/dist/result.d.mts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
type Result<T, E> = Ok<T> | Err<E>;
|
|
2
|
-
interface OkData<T> {
|
|
3
|
-
value: T;
|
|
4
|
-
error: undefined;
|
|
5
|
-
}
|
|
6
|
-
interface ErrData<E> {
|
|
7
|
-
value: undefined;
|
|
8
|
-
error: E;
|
|
9
|
-
}
|
|
10
|
-
type ResultData<T, E> = OkData<T> | ErrData<E>;
|
|
11
|
-
declare class Ok<T> {
|
|
12
|
-
readonly value: T;
|
|
13
|
-
readonly ok = true;
|
|
14
|
-
constructor(value: T);
|
|
15
|
-
}
|
|
16
|
-
declare class Err<E> {
|
|
17
|
-
readonly error: E;
|
|
18
|
-
readonly ok = false;
|
|
19
|
-
constructor(error: E);
|
|
20
|
-
}
|
|
21
|
-
declare function ok<T>(value: T): Ok<T>;
|
|
22
|
-
declare function err<E extends string = string>(error: E): Err<E>;
|
|
23
|
-
declare function err<E = unknown>(error: E): Err<E>;
|
|
24
|
-
declare function toResult<T, E = unknown>(fn: () => T): Result<T, E>;
|
|
25
|
-
declare function toResult<T, E = unknown>(promise: Promise<T>): Promise<Result<T, E>>;
|
|
26
|
-
declare function unwrapResult<T>(result: Ok<T>): OkData<T>;
|
|
27
|
-
declare function unwrapResult<E>(result: Err<E>): ErrData<E>;
|
|
28
|
-
declare function unwrapResult<T, E>(result: Result<T, E>): ResultData<T, E>;
|
|
29
|
-
declare function tryCatch<T, E = unknown>(fn: () => T): ResultData<T, E>;
|
|
30
|
-
declare function tryCatch<T, E = unknown>(promise: Promise<T>): Promise<ResultData<T, E>>;
|
|
31
|
-
|
|
32
|
-
export { Err, type ErrData, Ok, type OkData, type Result, type ResultData, err, ok, toResult, tryCatch, unwrapResult };
|
package/dist/result.mjs
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
class Ok {
|
|
2
|
-
value;
|
|
3
|
-
ok = true;
|
|
4
|
-
constructor(value) {
|
|
5
|
-
this.value = value;
|
|
6
|
-
}
|
|
7
|
-
}
|
|
8
|
-
class Err {
|
|
9
|
-
error;
|
|
10
|
-
ok = false;
|
|
11
|
-
constructor(error) {
|
|
12
|
-
this.error = error;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
function ok(value) {
|
|
16
|
-
return new Ok(value);
|
|
17
|
-
}
|
|
18
|
-
function err(error) {
|
|
19
|
-
return new Err(error);
|
|
20
|
-
}
|
|
21
|
-
function toResult(fnOrPromise) {
|
|
22
|
-
if (fnOrPromise instanceof Promise) {
|
|
23
|
-
return fnOrPromise.then(ok).catch(err);
|
|
24
|
-
}
|
|
25
|
-
try {
|
|
26
|
-
return ok(fnOrPromise());
|
|
27
|
-
} catch (error) {
|
|
28
|
-
return err(error);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
function unwrapResult(result) {
|
|
32
|
-
return result.ok ? { value: result.value, error: void 0 } : { value: void 0, error: result.error };
|
|
33
|
-
}
|
|
34
|
-
function tryCatch(fnOrPromise) {
|
|
35
|
-
if (fnOrPromise instanceof Promise) {
|
|
36
|
-
return toResult(fnOrPromise).then(
|
|
37
|
-
(result) => unwrapResult(result)
|
|
38
|
-
);
|
|
39
|
-
}
|
|
40
|
-
return unwrapResult(toResult(fnOrPromise));
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export { Err, Ok, err, ok, toResult, tryCatch, unwrapResult };
|
package/dist/string.d.mts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
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
|
-
*/
|
|
10
|
-
declare function template(str: string, variables: Record<string | number, any>, fallback?: string | ((key: string) => string)): string;
|
|
11
|
-
/**
|
|
12
|
-
* Generates a random string.
|
|
13
|
-
*
|
|
14
|
-
* @remarks Ported from `nanoid`.
|
|
15
|
-
* @see https://github.com/ai/nanoid
|
|
16
|
-
*/
|
|
17
|
-
declare function generateRandomId(size?: number, dict?: string): string;
|
|
18
|
-
|
|
19
|
-
export { generateRandomId, template };
|
package/dist/string.mjs
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
const URL_ALPHABET = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
|
|
2
|
-
function template(str, variables, fallback) {
|
|
3
|
-
return str.replace(/\{(\w+)\}/g, (_, key) => {
|
|
4
|
-
return variables[key] || ((typeof fallback === "function" ? fallback(key) : fallback) ?? key);
|
|
5
|
-
});
|
|
6
|
-
}
|
|
7
|
-
function generateRandomId(size = 16, dict = URL_ALPHABET) {
|
|
8
|
-
let id = "";
|
|
9
|
-
let i = size;
|
|
10
|
-
const len = dict.length;
|
|
11
|
-
while (i--)
|
|
12
|
-
id += dict[Math.random() * len | 0];
|
|
13
|
-
return id;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export { generateRandomId, template };
|
package/dist/types.d.mts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
type AutocompletableString = string & {};
|
|
2
|
-
type LooseAutocomplete<T extends string> = T | AutocompletableString;
|
|
3
|
-
/** Also commonly referred to as `Prettify` */
|
|
4
|
-
type UnifyIntersection<T> = {
|
|
5
|
-
[K in keyof T]: T[K];
|
|
6
|
-
} & {};
|
|
7
|
-
|
|
8
|
-
export type { AutocompletableString, LooseAutocomplete, UnifyIntersection };
|
package/dist/types.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|