@goodbyenjn/utils 26.4.0 → 26.4.2
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 +78 -35
- package/dist/chunks/{chunk-486f65b0.js → chunk-11b9216b.js} +41 -40
- package/dist/chunks/chunk-1b381080.js +25 -0
- package/dist/chunks/{chunk-7ffde8d4.js → chunk-3ce2ea14.js} +14 -21
- package/dist/chunks/chunk-71e0c144.d.ts +168 -0
- package/dist/chunks/chunk-9fe6b612.d.ts +10 -0
- package/dist/chunks/{chunk-704a1835.d.ts → chunk-bd9f56dd.d.ts} +2 -1
- package/dist/common.d.ts +2 -187
- package/dist/common.js +2 -3
- package/dist/exec.d.ts +129 -0
- package/dist/exec.js +759 -0
- package/dist/fs.d.ts +422 -95
- package/dist/fs.js +859 -387
- package/dist/global-types.d.ts +70 -0
- package/dist/json.d.ts +29 -0
- package/dist/json.js +3 -0
- package/dist/remeda.d.ts +3 -1
- package/dist/remeda.js +2 -3
- package/dist/result.d.ts +2 -2
- package/dist/result.js +2 -3
- package/dist/types.js +1 -1
- package/package.json +22 -16
- package/dist/chunks/chunk-b61db0a7.js +0 -27
- package/dist/shell.d.ts +0 -101
- package/dist/shell.js +0 -781
package/README.md
CHANGED
|
@@ -11,9 +11,9 @@ A modern TypeScript/JavaScript utility library providing a comprehensive collect
|
|
|
11
11
|
- 🔒 **Type-safe**: Full TypeScript support with comprehensive type definitions and type inference
|
|
12
12
|
- 📦 **Modular**: Import only what you need with tree-shakable exports and multiple entry points
|
|
13
13
|
- 🛡️ **Result Pattern**: Functional error handling without exceptions, based on Rust-style Result types
|
|
14
|
-
- 📁 **
|
|
15
|
-
- 🐚 **
|
|
16
|
-
- 🧰 **Common Utilities**: String manipulation, math operations, promise utilities, and
|
|
14
|
+
- 📁 **VFile & FS**: Type-safe file system operations and a powerful virtual file object
|
|
15
|
+
- 🐚 **Exec**: Powerful and flexible command execution with safe and unsafe variants
|
|
16
|
+
- 🧰 **Common Utilities**: String manipulation, math operations, promise utilities, and JSON handling
|
|
17
17
|
- 📊 **Remeda Extensions**: Extended utilities built on top of [Remeda](https://remedajs.com/)
|
|
18
18
|
|
|
19
19
|
## Installation
|
|
@@ -33,9 +33,10 @@ yarn add @goodbyenjn/utils
|
|
|
33
33
|
```typescript
|
|
34
34
|
// Import what you need from the main module
|
|
35
35
|
import { sleep, template } from "@goodbyenjn/utils";
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
36
|
+
import { exec, safeExec } from "@goodbyenjn/utils/exec";
|
|
37
|
+
import { BaseVFile } from "@goodbyenjn/utils/fs";
|
|
38
38
|
import { ok, Result } from "@goodbyenjn/utils/result";
|
|
39
|
+
import { parse, safeParse } from "@goodbyenjn/utils/json";
|
|
39
40
|
```
|
|
40
41
|
|
|
41
42
|
### Common Utilities
|
|
@@ -154,34 +155,39 @@ setTimeout(() => resolve("done!"), 1000);
|
|
|
154
155
|
const result = await promise;
|
|
155
156
|
```
|
|
156
157
|
|
|
157
|
-
|
|
158
|
+
### Command Execution
|
|
158
159
|
|
|
159
160
|
```typescript
|
|
160
|
-
import {
|
|
161
|
+
import { exec, safeExec } from "@goodbyenjn/utils/exec";
|
|
161
162
|
|
|
162
|
-
//
|
|
163
|
-
const
|
|
164
|
-
console.log(
|
|
165
|
-
console.log(result.stderr);
|
|
163
|
+
// 1. Unsafe Execution (throws on failure)
|
|
164
|
+
const output = await exec`npm install`;
|
|
165
|
+
console.log(output.stdout);
|
|
166
166
|
|
|
167
167
|
// String command with args
|
|
168
|
-
const
|
|
169
|
-
console.log(
|
|
168
|
+
const lsOutput = await exec("ls", ["-la"]);
|
|
169
|
+
console.log(lsOutput.stdout);
|
|
170
170
|
|
|
171
|
-
//
|
|
172
|
-
const
|
|
171
|
+
// 2. Safe Execution (returns Result)
|
|
172
|
+
const safeOutput = await safeExec`npm install`;
|
|
173
|
+
if (safeOutput.isOk()) {
|
|
174
|
+
console.log("Success:", safeOutput.unwrap().stdout);
|
|
175
|
+
} else {
|
|
176
|
+
// Result contains error information (e.g., NonZeroExitError)
|
|
177
|
+
console.error("Failed:", safeOutput.unwrapErr().message);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// 3. Pipe Output
|
|
181
|
+
const piped = await exec`echo "hello"`.pipe`cat`;
|
|
173
182
|
console.log(piped.stdout);
|
|
174
183
|
|
|
175
|
-
// Iterate
|
|
176
|
-
for await (const line of
|
|
184
|
+
// 4. Iterate Output
|
|
185
|
+
for await (const line of exec`cat large-file.txt`) {
|
|
177
186
|
console.log(line);
|
|
178
187
|
}
|
|
179
188
|
|
|
180
|
-
//
|
|
181
|
-
const
|
|
182
|
-
|
|
183
|
-
// Factory function with options
|
|
184
|
-
const withCwd = $({ cwd: "/path/to/project" });
|
|
189
|
+
// 5. Configuration Factory
|
|
190
|
+
const withCwd = exec({ cwd: "/path/to/project" });
|
|
185
191
|
const result3 = await withCwd`npm install`;
|
|
186
192
|
```
|
|
187
193
|
|
|
@@ -236,6 +242,25 @@ const throttledScroll = throttle(() => {
|
|
|
236
242
|
window.addEventListener("scroll", throttledScroll);
|
|
237
243
|
```
|
|
238
244
|
|
|
245
|
+
#### JSON Handling
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
import { parse, stringify, safeParse, safeStringify } from "@goodbyenjn/utils/json";
|
|
249
|
+
|
|
250
|
+
// Standard JSON parsing (returns value or nil)
|
|
251
|
+
const data = parse('{"a": 1}'); // { a: 1 }
|
|
252
|
+
const invalid = parse("bad"); // nil
|
|
253
|
+
|
|
254
|
+
// Safe JSON parsing (returns Result)
|
|
255
|
+
const result = safeParse('{"a": 1}');
|
|
256
|
+
if (result.isOk()) {
|
|
257
|
+
console.log(result.unwrap().a);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Safe stringify
|
|
261
|
+
const json = safeStringify({ a: 1 }); // Result<string, Error>
|
|
262
|
+
```
|
|
263
|
+
|
|
239
264
|
### File System Operations
|
|
240
265
|
|
|
241
266
|
```typescript
|
|
@@ -248,33 +273,50 @@ import {
|
|
|
248
273
|
safeMkdir,
|
|
249
274
|
safeRm,
|
|
250
275
|
safeReadFileByLine,
|
|
276
|
+
BaseVFile,
|
|
251
277
|
} from "@goodbyenjn/utils/fs";
|
|
252
278
|
|
|
253
|
-
//
|
|
254
|
-
|
|
279
|
+
// ... (safe operations)
|
|
280
|
+
|
|
281
|
+
// BaseVFile - Unified file handling
|
|
282
|
+
const vfile = new BaseVFile("example.json");
|
|
283
|
+
|
|
284
|
+
// Fluid path manipulation
|
|
285
|
+
vfile.filename("data").extname("ts");
|
|
286
|
+
console.log(vfile.basename()); // "data.ts"
|
|
287
|
+
|
|
288
|
+
// Cross-platform path handling
|
|
289
|
+
const relative = vfile.pathname.relative(); // "data.ts" (relative to cwd)
|
|
290
|
+
const absolute = vfile.pathname(); // "/full/path/to/data.ts"
|
|
291
|
+
|
|
292
|
+
// Built-in operations (available in extended VFile implementations)
|
|
293
|
+
// await vfile.read(); // Get content
|
|
294
|
+
// await vfile.write(); // Write content
|
|
295
|
+
```
|
|
296
|
+
|
|
255
297
|
if (textResult.isOk()) {
|
|
256
|
-
|
|
298
|
+
console.log("File content:", textResult.unwrap());
|
|
257
299
|
} else {
|
|
258
|
-
|
|
300
|
+
console.error("Failed to read file:", textResult.unwrapErr().message);
|
|
259
301
|
}
|
|
260
302
|
|
|
261
303
|
// Read and parse JSON safely
|
|
262
304
|
const jsonResult = await safeReadJson("package.json");
|
|
263
305
|
if (jsonResult.isOk()) {
|
|
264
|
-
|
|
265
|
-
|
|
306
|
+
const pkg = jsonResult.unwrap();
|
|
307
|
+
console.log("Package name:", pkg.name);
|
|
266
308
|
}
|
|
267
309
|
|
|
268
310
|
// Write JSON file
|
|
269
311
|
const writeResult = await safeWriteJson("data.json", { users: [] }, { pretty: true });
|
|
270
312
|
if (writeResult.isErr()) {
|
|
271
|
-
|
|
313
|
+
console.error("Write failed:", writeResult.unwrapErr());
|
|
272
314
|
}
|
|
273
315
|
|
|
274
316
|
// Check if file exists
|
|
275
317
|
const existsResult = await safeExists("path/to/file.txt");
|
|
276
318
|
if (existsResult.isOk() && existsResult.unwrap()) {
|
|
277
|
-
|
|
319
|
+
console.log("File exists!");
|
|
278
320
|
}
|
|
279
321
|
|
|
280
322
|
// Create directories (recursive)
|
|
@@ -286,11 +328,12 @@ const rmResult = await safeRm("build", { recursive: true, force: true });
|
|
|
286
328
|
// Read file line by line
|
|
287
329
|
const lineResult = await safeReadFileByLine("large-file.log");
|
|
288
330
|
if (lineResult.isOk()) {
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
}
|
|
331
|
+
for await (const line of lineResult.unwrap()) {
|
|
332
|
+
console.log(line);
|
|
292
333
|
}
|
|
293
|
-
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
````
|
|
294
337
|
|
|
295
338
|
### Glob Patterns
|
|
296
339
|
|
|
@@ -306,7 +349,7 @@ const syncFiles = globSync("**/*.test.ts", { cwd: "tests" });
|
|
|
306
349
|
|
|
307
350
|
// Convert file path to glob pattern
|
|
308
351
|
const pattern = convertPathToPattern("/home/user/project");
|
|
309
|
-
|
|
352
|
+
````
|
|
310
353
|
|
|
311
354
|
### Result Pattern - Functional Error Handling
|
|
312
355
|
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
var require_safe_stable_stringify = __commonJSMin(((exports, module) => {
|
|
1
|
+
import { a as __toESM, t as __commonJSMin } from "./chunk-3ce2ea14.js";
|
|
2
|
+
import { add, addProp, allPass, anyPass, capitalize, ceil, chunk, clamp, clone, concat, conditional, constant, countBy, debounce as debounce$1, defaultTo, difference, differenceWith, divide, doNothing, drop, dropFirstBy, dropLast, dropLastWhile, dropWhile, endsWith, entries, evolve, filter, find, findIndex, findLast, findLastIndex, first, firstBy, flat, flatMap, floor, forEach, forEachObj, fromEntries, fromKeys, funnel, groupBy, groupByProp, hasAtLeast, hasSubObject, identity, indexBy, intersection, intersectionWith, invert, isArray, isBigInt, isBoolean, isDate, isDeepEqual, isDefined, isEmpty, isEmptyish, isError, isFunction, isIncludedIn, isNonNull, isNonNullish, isNot, isNullish, isNumber, isObjectType, isObjectType as isObjectType$1, isPlainObject, isPromise, isShallowEqual, isStrictEqual, isString as isString$1, isSymbol, isTruthy, join as join$1, keys, last, length, map, mapKeys, mapToObj, mapValues, mapWithFeedback, mean, meanBy, median, merge, mergeAll, mergeDeep, multiply, nthBy, objOf, omit, omitBy, once, only, partialBind, partialLastBind, partition, pathOr, pick, pickBy, pipe, piped, product, prop, pullObject, purry, purry as purry$1, randomBigInt, randomInteger, randomString, range, rankBy, reduce, reverse, round, sample, set, setPath, shuffle, sliceString, sort, sortBy, sortedIndex, sortedIndexBy, sortedIndexWith, sortedLastIndex, sortedLastIndexBy, splice, split as split$1, splitAt, splitWhen, startsWith, stringToPath, subtract, sum, sumBy, swapIndices, swapProps, take, takeFirstBy, takeLast, takeLastWhile, takeWhile, tap, times, toCamelCase, toKebabCase, toLowerCase, toSnakeCase, toTitleCase, toUpperCase, truncate, uncapitalize, unique, uniqueBy, uniqueWith, values, when, zip, zipWith } from "remeda";
|
|
3
|
+
import { accumulateAsync as accumulateP, accumulateSync as accumulate, awaitAll, buffer, chunkAsync as chunkP, compose, concatAsync as concatP, concurrency, differenceAsync as differenceP, differenceByAsync as differenceByP, differenceBySync as differenceBy, differenceWithAsync as differenceWithP, dropAsync as dropP, everyAsync as everyP, everySync as every, executeAsync as executeP, executeSync as execute, filterAsync as filterP, findAsync as findP, flatMapAsync as flatMapP, flattenAsync as flattenP, flattenSync as flatten, forEachAsync as forEachP, intersectionAsync as intersectionP, intersectionByAsync as intersectionByP, intersectionBySync as intersectionBy, intersectionWithAsync as intersectionWithP, mapAsync as mapP, peekAsync as peekP, peekSync as peek, reduceAsync as reduceP, serializeAsync as serializeP, serializeSync as serialize, someAsync as someP, someSync as some, takeAsync as takeP, throttle as throttle$1, toArrayAsync as toArrayP, toArraySync as toArray, toIteratorAsync as toIteratorP, toIteratorSync as toIterator, uniqueAsync as uniqueP, uniqueByAsync as uniqueByP, uniqueWithAsync as uniqueWithP } from "rotery";
|
|
4
|
+
const configure = __toESM(__commonJSMin(((exports, module) => {
|
|
6
5
|
const { hasOwnProperty } = Object.prototype;
|
|
7
6
|
const stringify = configure();
|
|
8
7
|
stringify.configure = configure;
|
|
@@ -410,13 +409,10 @@ var require_safe_stable_stringify = __commonJSMin(((exports, module) => {
|
|
|
410
409
|
}
|
|
411
410
|
return stringify;
|
|
412
411
|
}
|
|
413
|
-
}));
|
|
414
|
-
|
|
412
|
+
}))(), 1).configure;
|
|
415
413
|
//#endregion
|
|
416
|
-
//#region
|
|
417
|
-
|
|
418
|
-
const configure = import_safe_stable_stringify.configure;
|
|
419
|
-
|
|
414
|
+
//#region src/json/stable.ts
|
|
415
|
+
const stableStringify = configure({ bigint: true });
|
|
420
416
|
//#endregion
|
|
421
417
|
//#region src/result/error.ts
|
|
422
418
|
const prepare = (result, msg) => {
|
|
@@ -475,7 +471,6 @@ Stack trace:`, prepared.options);
|
|
|
475
471
|
return this.#formatted;
|
|
476
472
|
}
|
|
477
473
|
};
|
|
478
|
-
|
|
479
474
|
//#endregion
|
|
480
475
|
//#region src/result/result.ts
|
|
481
476
|
const never = void 0;
|
|
@@ -495,7 +490,7 @@ var Result = class Result {
|
|
|
495
490
|
return new Result(false, error, never);
|
|
496
491
|
}
|
|
497
492
|
static try(fnOrPromise, onThrow) {
|
|
498
|
-
if (!isFunction(fnOrPromise) && !isPromiseLike(fnOrPromise)) {
|
|
493
|
+
if (!isFunction$1(fnOrPromise) && !isPromiseLike(fnOrPromise)) {
|
|
499
494
|
const error = new TypeError("Argument must be a function or a promise");
|
|
500
495
|
return this.err(transformError(error, onThrow));
|
|
501
496
|
}
|
|
@@ -629,19 +624,27 @@ var Result = class Result {
|
|
|
629
624
|
};
|
|
630
625
|
const ok = Result.ok;
|
|
631
626
|
const err = Result.err;
|
|
632
|
-
|
|
627
|
+
const isResult = Result.is;
|
|
633
628
|
//#endregion
|
|
634
|
-
//#region src/
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
const
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
629
|
+
//#region src/remeda/hasOwnProperty.ts
|
|
630
|
+
function hasOwnProperty(...args) {
|
|
631
|
+
return purry(hasOwnPropertyImplementation, args);
|
|
632
|
+
}
|
|
633
|
+
function hasOwnPropertyImplementation(data, properties) {
|
|
634
|
+
if (!isObjectType(data)) return false;
|
|
635
|
+
for (const property of properties) if (!Object.hasOwn(data, property)) return false;
|
|
636
|
+
return true;
|
|
637
|
+
}
|
|
638
|
+
//#endregion
|
|
639
|
+
//#region src/remeda/isFunction.ts
|
|
640
|
+
function isFunction$1(data) {
|
|
641
|
+
return typeof data === "function";
|
|
642
|
+
}
|
|
643
|
+
//#endregion
|
|
644
|
+
//#region src/remeda/isPromiseLike.ts
|
|
645
|
+
function isPromiseLike(data) {
|
|
646
|
+
return isObjectType(data) && isFunction(data.then) && Object.getOwnPropertyDescriptor(data, "then")?.get === void 0;
|
|
647
|
+
}
|
|
645
648
|
//#endregion
|
|
646
649
|
//#region src/common/error.ts
|
|
647
650
|
const normalizeError = (error, caller) => {
|
|
@@ -654,13 +657,12 @@ const getErrorMessage = (error, message) => {
|
|
|
654
657
|
if (isError(error)) return error.message;
|
|
655
658
|
if (message !== void 0) return message;
|
|
656
659
|
let msg;
|
|
657
|
-
if (isString(error) || isNumber(error) || isBigInt(error) || isBoolean(error) || isSymbol(error)) msg = error.toString();
|
|
660
|
+
if (isString$1(error) || isNumber(error) || isBigInt(error) || isBoolean(error) || isSymbol(error)) msg = error.toString();
|
|
658
661
|
else if (error === void 0) msg = "undefined";
|
|
659
662
|
else if (error === null) msg = "null";
|
|
660
|
-
else msg =
|
|
663
|
+
else msg = stableStringify(error);
|
|
661
664
|
return msg;
|
|
662
665
|
};
|
|
663
|
-
|
|
664
666
|
//#endregion
|
|
665
667
|
//#region src/common/math.ts
|
|
666
668
|
const linear = (value, range) => {
|
|
@@ -676,7 +678,10 @@ const scale = (value, inRange, outRange) => {
|
|
|
676
678
|
const [outMin, outMax] = outRange;
|
|
677
679
|
return linear((value - inMin) / (inMax - inMin), [outMin, outMax]);
|
|
678
680
|
};
|
|
679
|
-
|
|
681
|
+
//#endregion
|
|
682
|
+
//#region src/common/nil.ts
|
|
683
|
+
const nil = Symbol("nil");
|
|
684
|
+
const isNil = (value) => value === nil;
|
|
680
685
|
//#endregion
|
|
681
686
|
//#region src/common/parse.ts
|
|
682
687
|
const parseKey = (input, raw = input) => {
|
|
@@ -757,7 +762,6 @@ const parseValueToBoolean = (value, defaultValue) => {
|
|
|
757
762
|
if (/^(?:n|no|false|0|off)$/.test(str)) return false;
|
|
758
763
|
return defaultValue;
|
|
759
764
|
};
|
|
760
|
-
|
|
761
765
|
//#endregion
|
|
762
766
|
//#region src/common/promise.ts
|
|
763
767
|
const sleep = (ms, callback) => new Promise((resolve) => {
|
|
@@ -804,7 +808,7 @@ const createLock = () => {
|
|
|
804
808
|
};
|
|
805
809
|
};
|
|
806
810
|
const createPromiseWithResolvers = () => {
|
|
807
|
-
if (isFunction(Promise.withResolvers)) return Promise.withResolvers();
|
|
811
|
+
if (isFunction$1(Promise.withResolvers)) return Promise.withResolvers();
|
|
808
812
|
let resolve;
|
|
809
813
|
let reject;
|
|
810
814
|
return {
|
|
@@ -816,7 +820,6 @@ const createPromiseWithResolvers = () => {
|
|
|
816
820
|
reject
|
|
817
821
|
};
|
|
818
822
|
};
|
|
819
|
-
|
|
820
823
|
//#endregion
|
|
821
824
|
//#region src/common/string.ts
|
|
822
825
|
const REGEXP_WHITESPACE_ONLY = /^\s*$/;
|
|
@@ -864,7 +867,7 @@ function unindent(...params) {
|
|
|
864
867
|
let trimStart = true;
|
|
865
868
|
let trimEnd = true;
|
|
866
869
|
const unindentImpl = (...params) => {
|
|
867
|
-
const lines = splitByLineBreak(isString(params[0]) ? params[0] : concatTemplateStrings(params[0], params.slice(1)));
|
|
870
|
+
const lines = splitByLineBreak(isString$1(params[0]) ? params[0] : concatTemplateStrings(params[0], params.slice(1)));
|
|
868
871
|
let commonIndent = Number.POSITIVE_INFINITY;
|
|
869
872
|
let firstContentLine = -1;
|
|
870
873
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -887,7 +890,7 @@ function unindent(...params) {
|
|
|
887
890
|
trimEnd = params[1] !== false;
|
|
888
891
|
return unindentImpl;
|
|
889
892
|
}
|
|
890
|
-
if (isString(params[0]) || isArray(params[0])) return unindentImpl(...params);
|
|
893
|
+
if (isString$1(params[0]) || isArray(params[0])) return unindentImpl(...params);
|
|
891
894
|
throw new TypeError(`First parameter has an invalid type: "${typeof params[0]}"`);
|
|
892
895
|
}
|
|
893
896
|
function indent(...params) {
|
|
@@ -895,7 +898,7 @@ function indent(...params) {
|
|
|
895
898
|
let trimStart = true;
|
|
896
899
|
let trimEnd = true;
|
|
897
900
|
const indentImpl = (...params) => {
|
|
898
|
-
const lines = splitByLineBreak(isString(params[0]) ? params[0] : concatTemplateStrings(params[0], params.slice(1)));
|
|
901
|
+
const lines = splitByLineBreak(isString$1(params[0]) ? params[0] : concatTemplateStrings(params[0], params.slice(1)));
|
|
899
902
|
const whitespaceLines = lines.map((line) => REGEXP_WHITESPACE_ONLY.test(line));
|
|
900
903
|
let startIndex = 0;
|
|
901
904
|
let endIndex = lines.length;
|
|
@@ -913,7 +916,7 @@ function indent(...params) {
|
|
|
913
916
|
indentString = " ".repeat(params[0]);
|
|
914
917
|
return indentImpl;
|
|
915
918
|
}
|
|
916
|
-
if (isString(params[0])) {
|
|
919
|
+
if (isString$1(params[0])) {
|
|
917
920
|
indentString = params[0];
|
|
918
921
|
return indentImpl;
|
|
919
922
|
}
|
|
@@ -923,14 +926,13 @@ function template(str, ...args) {
|
|
|
923
926
|
const [firstArg, fallback] = args;
|
|
924
927
|
if (isPlainObject(firstArg)) {
|
|
925
928
|
const mapping = firstArg;
|
|
926
|
-
return str.replace(/\{(\w+)\}/g, (_, key) => mapping[key] || ((isFunction(fallback) ? fallback(key) : fallback) ?? key));
|
|
929
|
+
return str.replace(/\{(\w+)\}/g, (_, key) => mapping[key] || ((isFunction$1(fallback) ? fallback(key) : fallback) ?? key));
|
|
927
930
|
} else return str.replace(/\{(\d+)\}/g, (_, key) => {
|
|
928
931
|
const index = Number(key);
|
|
929
932
|
if (Number.isNaN(index)) return key;
|
|
930
933
|
return args[index];
|
|
931
934
|
});
|
|
932
935
|
}
|
|
933
|
-
|
|
934
936
|
//#endregion
|
|
935
937
|
//#region src/common/throttle.ts
|
|
936
938
|
const wrap = (fn, wait, options) => {
|
|
@@ -964,6 +966,5 @@ const throttle = (fn, wait = 0, options = {}) => {
|
|
|
964
966
|
trailing
|
|
965
967
|
});
|
|
966
968
|
};
|
|
967
|
-
|
|
968
969
|
//#endregion
|
|
969
|
-
export {
|
|
970
|
+
export { differenceBy as $, pipe as $n, toIterator as $r, isArray as $t, accumulateP as A, mapValues as An, splice as Ar, flatMapP as At, chunkP as B, objOf as Bn, swapProps as Br, groupBy as Bt, isNil as C, isResult as Ci, keys as Cn, sort as Cr, findLast as Ct, getErrorMessage as D, mapKeys as Dn, sortedIndexWith as Dr, firstBy as Dt, scale as E, stableStringify as Ei, map as En, sortedIndexBy as Er, first as Et, awaitAll as F, merge as Fn, stringToPath as Fr, forEachObj as Ft, concatP as G, partialBind as Gn, takeP as Gr, indexBy as Gt, clone as H, omitBy as Hn, takeFirstBy as Hr, hasAtLeast as Ht, buffer as I, mergeAll as In, subtract as Ir, forEachP as It, constant as J, pathOr as Jn, throttle$1 as Jr, intersectionByP as Jt, concurrency as K, partialLastBind as Kn, takeWhile as Kr, intersection as Kt, capitalize as L, mergeDeep as Ln, sum as Lr, fromEntries as Lt, addProp as M, mean as Mn, splitAt as Mr, flattenP as Mt, allPass as N, meanBy as Nn, splitWhen as Nr, floor as Nt, normalizeError as O, mapP as On, sortedLastIndex as Or, flat as Ot, anyPass as P, median as Pn, startsWith as Pr, forEach as Pt, difference as Q, pickBy as Qn, toCamelCase as Qr, invert as Qt, ceil as R, multiply as Rn, sumBy as Rr, fromKeys as Rt, parseValueToBoolean as S, err as Si, join$1 as Sn, someP as Sr, findIndex as St, linear as T, ResultError as Ti, length as Tn, sortedIndex as Tr, findP as Tt, compose as U, once as Un, takeLast as Ur, hasSubObject as Ut, clamp as V, omit as Vn, take as Vr, groupByProp as Vt, concat as W, only as Wn, takeLastWhile as Wr, identity as Wt, debounce$1 as X, peekP as Xn, toArray as Xr, intersectionWith as Xt, countBy as Y, peek as Yn, times as Yr, intersectionP as Yt, defaultTo as Z, pick as Zn, toArrayP as Zr, intersectionWithP as Zt, createLock as _, zipWith as _i, isShallowEqual as _n, set as _r, execute as _t, concatTemplateStrings as a, toUpperCase as ai, isEmpty as an, randomBigInt as ar, doNothing as at, sleep as b, hasOwnProperty as bi, isSymbol as bn, sliceString as br, filterP as bt, joinWithSlash as c, unique as ci, isIncludedIn as cn, range as cr, dropLast as ct, split as d, uniqueP as di, isNot as dn, reduceP as dr, dropWhile as dt, toIteratorP as ei, isBigInt as en, piped as er, differenceByP as et, splitByLineBreak as f, uniqueWith as fi, isNullish as fn, reverse as fr, endsWith as ft, unindent as g, zip as gi, isPromise as gn, serializeP as gr, evolve as gt, toForwardSlash as h, when as hi, isPlainObject as hn, serialize as hr, everyP as ht, addSuffix as i, toTitleCase as ii, isDefined as in, purry$1 as ir, divide as it, add as j, mapWithFeedback as jn, split$1 as jr, flatten as jt, accumulate as k, mapToObj as kn, sortedLastIndexBy as kr, flatMap as kt, removePrefix as l, uniqueBy as li, isNonNull as ln, rankBy as lr, dropLastWhile as lt, template as m, values as mi, isObjectType$1 as mn, sample as mr, every as mt, throttle as n, toLowerCase as ni, isDate as nn, prop as nr, differenceWith as nt, indent as o, truncate as oi, isEmptyish as on, randomInteger as or, drop as ot, splitWithSlash as p, uniqueWithP as pi, isNumber as pn, round as pr, entries as pt, conditional as q, partition as qn, tap as qr, intersectionBy as qt, addPrefix as r, toSnakeCase as ri, isDeepEqual as rn, pullObject as rr, differenceWithP as rt, join as s, uncapitalize as si, isError as sn, randomString as sr, dropFirstBy as st, debounce as t, toKebabCase as ti, isBoolean as tn, product as tr, differenceP as tt, removeSuffix as u, uniqueByP as ui, isNonNullish as un, reduce as ur, dropP as ut, createPromiseWithResolvers as v, isPromiseLike as vi, isStrictEqual as vn, setPath as vr, executeP as vt, nil as w, ok as wi, last as wn, sortBy as wr, findLastIndex as wt, parseKeyValuePairs as x, Result as xi, isTruthy as xn, some as xr, find as xt, createSingleton as y, isFunction$1 as yi, isString$1 as yn, shuffle as yr, filter as yt, chunk as z, nthBy as zn, swapIndices as zr, funnel as zt };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Si as err, w as nil, xi as Result } from "./chunk-11b9216b.js";
|
|
2
|
+
//#region src/json/safe.ts
|
|
3
|
+
const safeStringify = Result.wrap(JSON.stringify);
|
|
4
|
+
const stringify$1 = (value, replacer, space) => Result.gen(function* () {
|
|
5
|
+
const text = yield* safeStringify(value, replacer, space).context(`Failed to stringify value: ${String(value)}`);
|
|
6
|
+
if (text === void 0) return err(new TypeError(`Value cannot be stringified: ${String(value)}`));
|
|
7
|
+
return text;
|
|
8
|
+
});
|
|
9
|
+
const safeParse = Result.wrap(JSON.parse);
|
|
10
|
+
const parse$1 = (text, reviver) => safeParse(text, reviver).context(`Failed to parse JSON string: ${text.length > 100 ? text.slice(0, 100) + "..." : text}`);
|
|
11
|
+
//#endregion
|
|
12
|
+
//#region src/json/unsafe.ts
|
|
13
|
+
function stringify(value, replacer, space) {
|
|
14
|
+
const text = JSON.stringify(value, replacer, space);
|
|
15
|
+
return text === void 0 ? nil : text;
|
|
16
|
+
}
|
|
17
|
+
const parse = (text, reviver) => {
|
|
18
|
+
try {
|
|
19
|
+
return JSON.parse(text, reviver);
|
|
20
|
+
} catch {
|
|
21
|
+
return nil;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
//#endregion
|
|
25
|
+
export { stringify$1 as i, stringify as n, parse$1 as r, parse as t };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
1
2
|
//#region \0rolldown/runtime.js
|
|
2
3
|
var __create = Object.create;
|
|
3
4
|
var __defProp = Object.defineProperty;
|
|
@@ -8,28 +9,20 @@ var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
|
8
9
|
var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
9
10
|
var __exportAll = (all, no_symbols) => {
|
|
10
11
|
let target = {};
|
|
11
|
-
for (var name in all) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
if (!no_symbols) {
|
|
18
|
-
__defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
19
|
-
}
|
|
12
|
+
for (var name in all) __defProp(target, name, {
|
|
13
|
+
get: all[name],
|
|
14
|
+
enumerable: true
|
|
15
|
+
});
|
|
16
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
20
17
|
return target;
|
|
21
18
|
};
|
|
22
19
|
var __copyProps = (to, from, except, desc) => {
|
|
23
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
}
|
|
20
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
21
|
+
key = keys[i];
|
|
22
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
23
|
+
get: ((k) => from[k]).bind(null, key),
|
|
24
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
25
|
+
});
|
|
33
26
|
}
|
|
34
27
|
return to;
|
|
35
28
|
};
|
|
@@ -38,6 +31,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
38
31
|
value: mod,
|
|
39
32
|
enumerable: true
|
|
40
33
|
}) : target, mod));
|
|
41
|
-
|
|
34
|
+
var __require = createRequire(import.meta.url);
|
|
42
35
|
//#endregion
|
|
43
|
-
export { __toESM as i, __exportAll as n, __reExport as r, __commonJSMin as t };
|
|
36
|
+
export { __toESM as a, __require as i, __exportAll as n, __reExport as r, __commonJSMin as t };
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { l as Fn, p as TemplateFn, s as AsyncFn, t as index_d_exports } from "./chunk-3c6f28c7.js";
|
|
2
|
+
|
|
3
|
+
//#region src/common/error.d.ts
|
|
4
|
+
declare const normalizeError: (error: unknown, caller?: Function) => Error;
|
|
5
|
+
declare const getErrorMessage: (error: unknown, message?: string) => string;
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region src/common/math.d.ts
|
|
8
|
+
/**
|
|
9
|
+
* @example
|
|
10
|
+
* ```
|
|
11
|
+
* const value = linear(0.5, [0, 2]) // value: 1
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
declare const linear: (value: number, range: [min: number, max: number]) => number;
|
|
15
|
+
/**
|
|
16
|
+
* @example
|
|
17
|
+
* ```
|
|
18
|
+
* const value = scale(0.5, [0, 1], [200, 400]) // value: 300
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
declare const scale: (value: number, inRange: [min: number, max: number], outRange: [min: number, max: number]) => number;
|
|
22
|
+
//#endregion
|
|
23
|
+
//#region src/common/nil.d.ts
|
|
24
|
+
type Nil = index_d_exports.Tagged<symbol, "nil">;
|
|
25
|
+
declare const nil: Nil;
|
|
26
|
+
declare const isNil: (value: unknown) => value is Nil;
|
|
27
|
+
//#endregion
|
|
28
|
+
//#region src/common/parse.d.ts
|
|
29
|
+
declare const parseKeyValuePairs: (input: string) => Record<string, string>;
|
|
30
|
+
declare const parseValueToBoolean: <T>(value: unknown, defaultValue: T | boolean) => T | boolean;
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region src/common/promise.d.ts
|
|
33
|
+
interface Singleton<T> {
|
|
34
|
+
(): Promise<T>;
|
|
35
|
+
reset: () => Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
interface Lock {
|
|
38
|
+
run: <T = void>(fn: AsyncFn<T>) => Promise<T>;
|
|
39
|
+
wait: () => Promise<void>;
|
|
40
|
+
isWaiting: () => boolean;
|
|
41
|
+
clear: () => void;
|
|
42
|
+
}
|
|
43
|
+
interface PromiseWithResolvers<T> {
|
|
44
|
+
promise: Promise<T>;
|
|
45
|
+
resolve: (value: T | PromiseLike<T>) => void;
|
|
46
|
+
reject: (reason?: any) => void;
|
|
47
|
+
}
|
|
48
|
+
declare const sleep: (ms: number, callback?: Fn) => Promise<void>;
|
|
49
|
+
declare const createSingleton: <T>(fn: AsyncFn<T>) => Singleton<T>;
|
|
50
|
+
/**
|
|
51
|
+
* @example
|
|
52
|
+
* ```
|
|
53
|
+
* const lock = createLock()
|
|
54
|
+
*
|
|
55
|
+
* lock.run(async () => {
|
|
56
|
+
* await doSomething()
|
|
57
|
+
* })
|
|
58
|
+
*
|
|
59
|
+
* // in anther context:
|
|
60
|
+
* await lock.wait() // it will wait all tasking finished
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
declare const createLock: () => Lock;
|
|
64
|
+
declare const createPromiseWithResolvers: <T>() => PromiseWithResolvers<T>;
|
|
65
|
+
//#endregion
|
|
66
|
+
//#region src/common/string.d.ts
|
|
67
|
+
declare const addPrefix: (prefix: string, str: string) => string;
|
|
68
|
+
declare const addSuffix: (suffix: string, str: string) => string;
|
|
69
|
+
declare const removePrefix: (prefix: string, str: string) => string;
|
|
70
|
+
declare const removeSuffix: (suffix: string, str: string) => string;
|
|
71
|
+
declare const join: (separator: string, ...paths: string[]) => string;
|
|
72
|
+
declare const split: (separator: string, path: string) => string[];
|
|
73
|
+
declare const toForwardSlash: (str: string) => string;
|
|
74
|
+
declare const joinWithSlash: (...paths: string[]) => string;
|
|
75
|
+
declare const splitWithSlash: (path: string) => string[];
|
|
76
|
+
declare const splitByLineBreak: (str: string) => string[];
|
|
77
|
+
declare const concatTemplateStrings: (template: TemplateStringsArray, values: any[]) => string;
|
|
78
|
+
/**
|
|
79
|
+
* @example
|
|
80
|
+
* ```ts
|
|
81
|
+
* // Default behavior: trim both start and end
|
|
82
|
+
* const str1 = unindent`
|
|
83
|
+
* if (a) {
|
|
84
|
+
* b()
|
|
85
|
+
* }
|
|
86
|
+
* `;
|
|
87
|
+
*
|
|
88
|
+
* // Factory function: custom trim behavior
|
|
89
|
+
* const str2 = unindent(false, false)`
|
|
90
|
+
* if (a) {
|
|
91
|
+
* b()
|
|
92
|
+
* }
|
|
93
|
+
* `;
|
|
94
|
+
*
|
|
95
|
+
* // Only trim start, keep end
|
|
96
|
+
* const str3 = unindent(true, false)(" hello\n world\n");
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
declare function unindent(str: string): string;
|
|
100
|
+
declare function unindent(template: TemplateStringsArray, ...values: any[]): string;
|
|
101
|
+
declare function unindent(trimStart?: boolean, trimEnd?: boolean): TemplateFn<string> & ((str: string) => string);
|
|
102
|
+
/**
|
|
103
|
+
* @example
|
|
104
|
+
* ```ts
|
|
105
|
+
* // Using indent count with default space character
|
|
106
|
+
* const str1 = indent(2)`
|
|
107
|
+
* if (a) {
|
|
108
|
+
* b()
|
|
109
|
+
* }
|
|
110
|
+
* `;
|
|
111
|
+
*
|
|
112
|
+
* // Using custom indent string directly
|
|
113
|
+
* const str2 = indent(">>")`
|
|
114
|
+
* if (a) {
|
|
115
|
+
* b()
|
|
116
|
+
* }
|
|
117
|
+
* `;
|
|
118
|
+
*
|
|
119
|
+
* // Only trim start, keep end
|
|
120
|
+
* const str3 = indent(2, true, false)("hello\nworld\n");
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
declare function indent(indentNumber: number, trimStart?: boolean, trimEnd?: boolean): TemplateFn<string> & ((str: string) => string);
|
|
124
|
+
declare function indent(indentString: string, trimStart?: boolean, trimEnd?: boolean): TemplateFn<string> & ((str: string) => string);
|
|
125
|
+
/**
|
|
126
|
+
* @example
|
|
127
|
+
* ```
|
|
128
|
+
* const result = template(
|
|
129
|
+
* 'Hello {0}! My name is {1}.',
|
|
130
|
+
* 'World',
|
|
131
|
+
* 'Alice'
|
|
132
|
+
* ) // Hello World! My name is Alice.
|
|
133
|
+
* ```
|
|
134
|
+
*
|
|
135
|
+
* ```
|
|
136
|
+
* const result = template(
|
|
137
|
+
* '{greet}! My name is {name}.',
|
|
138
|
+
* { greet: 'Hello', name: 'Alice' }
|
|
139
|
+
* ) // Hello! My name is Alice.
|
|
140
|
+
* ```
|
|
141
|
+
*
|
|
142
|
+
* const result = template(
|
|
143
|
+
* '{greet}! My name is {name}.',
|
|
144
|
+
* { greet: 'Hello' }, // name isn't passed hence fallback will be used for name
|
|
145
|
+
* 'placeholder'
|
|
146
|
+
* ) // Hello! My name is placeholder.
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
declare function template(str: string, mapping: Record<string | number, any>, fallback?: string | ((key: string) => string)): string;
|
|
150
|
+
declare function template(str: string, ...args: (string | number | bigint | undefined | null)[]): string;
|
|
151
|
+
//#endregion
|
|
152
|
+
//#region src/common/throttle.d.ts
|
|
153
|
+
interface WrappedFn<T extends Fn> {
|
|
154
|
+
(...args: Parameters<T>): void;
|
|
155
|
+
cancel: Fn<void>;
|
|
156
|
+
}
|
|
157
|
+
interface Options {
|
|
158
|
+
leading?: boolean;
|
|
159
|
+
trailing?: boolean;
|
|
160
|
+
}
|
|
161
|
+
type DebouncedFn<T extends Fn> = WrappedFn<T>;
|
|
162
|
+
type ThrottledFn<T extends Fn> = WrappedFn<T>;
|
|
163
|
+
type DebounceOptions = Options;
|
|
164
|
+
type ThrottleOptions = Options;
|
|
165
|
+
declare const debounce: <T extends Fn>(fn: T, wait?: number, options?: DebounceOptions) => DebouncedFn<T>;
|
|
166
|
+
declare const throttle: <T extends Fn>(fn: T, wait?: number, options?: ThrottleOptions) => ThrottledFn<T>;
|
|
167
|
+
//#endregion
|
|
168
|
+
export { Nil as A, Singleton as C, sleep as D, createSingleton as E, getErrorMessage as F, normalizeError as I, nil as M, linear as N, parseKeyValuePairs as O, scale as P, PromiseWithResolvers as S, createPromiseWithResolvers as T, splitWithSlash as _, debounce as a, unindent as b, addSuffix as c, join as d, joinWithSlash as f, splitByLineBreak as g, split as h, ThrottledFn as i, isNil as j, parseValueToBoolean as k, concatTemplateStrings as l, removeSuffix as m, DebouncedFn as n, throttle as o, removePrefix as p, ThrottleOptions as r, addPrefix as s, DebounceOptions as t, indent as u, template as v, createLock as w, Lock as x, toForwardSlash as y };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { i as Result } from "./chunk-bd9f56dd.js";
|
|
2
|
+
|
|
3
|
+
//#region src/json/safe.d.ts
|
|
4
|
+
declare const stringify: {
|
|
5
|
+
(value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): Result<string, TypeError>;
|
|
6
|
+
(value: any, replacer?: (number | string)[] | null, space?: string | number): Result<string, TypeError>;
|
|
7
|
+
};
|
|
8
|
+
declare const parse: <T = any>(text: string, reviver?: (this: any, key: string, value: any) => any) => Result<T, SyntaxError>;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { stringify as n, parse as t };
|