@goodbyenjn/utils 26.2.0 → 26.4.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 CHANGED
@@ -116,6 +116,10 @@ const parts = split("-", "hello-world-js"); // ["hello", "world", "js"]
116
116
  // Split string by line breaks (handles both \n and \r\n)
117
117
  const lines = splitByLineBreak("line1\nline2\r\nline3");
118
118
  console.log(lines); // ["line1", "line2", "line3"]
119
+
120
+ // Parse boolean value with custom default
121
+ const isEnabled = parseValueToBoolean("yes", false); // true
122
+ const debugMode = parseValueToBoolean("invalid", "auto"); // "auto"
119
123
  ```
120
124
 
121
125
  #### Promise Utilities
@@ -307,7 +311,7 @@ const pattern = convertPathToPattern("/home/user/project");
307
311
  ### Result Pattern - Functional Error Handling
308
312
 
309
313
  ```typescript
310
- import { err, ok, Result, safeTry } from "@goodbyenjn/utils/result";
314
+ import { err, ok, Result } from "@goodbyenjn/utils/result";
311
315
 
312
316
  // Create results explicitly
313
317
  const success = ok(42);
@@ -315,7 +319,7 @@ const failure = err("Something went wrong");
315
319
 
316
320
  // Handle results with chainable methods
317
321
  const doubled = success
318
- .map(value => value * 2)
322
+ .map(value => value * 2) // Supports async: .map(async v => v * 2) returns Promise<Result>
319
323
  .mapErr(err => `Error: ${err}`)
320
324
  .unwrapOr(0); // 84
321
325
 
@@ -323,28 +327,36 @@ const doubled = success
323
327
  const result: Result<string, Error> = ok("value");
324
328
  const transformed = result.mapErr(() => new Error("Custom error"));
325
329
 
326
- // Convert throwing functions to Result
330
+ // Convert throwing functions or promises to Result
327
331
  async function fetchUser(id: string) {
328
- // If the function throws, it's caught and wrapped in Err
329
- const user = await Result.fromCallable(() => JSON.parse(userJson));
332
+ // Result.try catches thrown errors
333
+ const user = await Result.try(() => JSON.parse(userJson));
334
+ // Or handle promise rejections
335
+ const user = await Result.try(fetch(`/api/users/${id}`));
330
336
 
331
337
  return user.map(u => u.name).mapErr(err => new Error(`Failed to parse user: ${err.message}`));
332
338
  }
333
339
 
340
+ // Wrap a function to always return a Result
341
+ const safeParse = Result.wrap(JSON.parse, Error);
342
+ const data = safeParse('{"valid": true}'); // Result<any, Error>
343
+
334
344
  // Combine multiple Results
335
345
  const results = [ok(1), ok(2), err("oops"), ok(4)];
336
346
  const combined = Result.all(...results); // Err("oops")
337
347
 
338
- // Safe try-catch alternative
339
- const safeTryExample = await safeTry(async () => {
340
- return await fetch("/api/data").then(r => r.json());
348
+ // Generator-based "do" notation for flattening Results
349
+ const finalResult = Result.gen(function* () {
350
+ const a = yield* ok(10);
351
+ const b = yield* ok(20);
352
+ return a + b;
353
+ }); // ok(30)
354
+
355
+ // Supports async generators
356
+ const asyncFinal = await Result.gen(async function* () {
357
+ const user = yield* await fetchUser("1");
358
+ return user.name;
341
359
  });
342
-
343
- if (safeTryExample.isOk()) {
344
- console.log("Data:", safeTryExample.unwrap());
345
- } else {
346
- console.error("Failed:", safeTryExample.unwrapErr());
347
- }
348
360
  ```
349
361
 
350
362
  ### Type Utilities
@@ -356,46 +368,56 @@ import type {
356
368
  YieldType,
357
369
  OmitByKey,
358
370
  SetNullable,
371
+ TemplateFn,
359
372
  } from "@goodbyenjn/utils/types";
360
373
 
374
+ // ... (other types)
375
+
376
+ // Template string function type
377
+ const myTag: TemplateFn<string> = (strings, ...values) => {
378
+ return strings[0] + values[0];
379
+ };
380
+ ```
381
+
361
382
  // Nullable type for values that can be null or undefined
362
383
  type User = {
363
- id: string;
364
- name: string;
365
- email: Nullable<string>; // string | null | undefined
384
+ id: string;
385
+ name: string;
386
+ email: Nullable<string>; // string | null | undefined
366
387
  };
367
388
 
368
389
  // Optional type (undefined but not null)
369
390
  type Profile = {
370
- bio: Optional<string>; // string | undefined
391
+ bio: Optional<string>; // string | undefined
371
392
  };
372
393
 
373
394
  // Extract yield type from generators
374
- function* numberGenerator() {
375
- yield 1;
376
- yield 2;
377
- yield 3;
395
+ function\* numberGenerator() {
396
+ yield 1;
397
+ yield 2;
398
+ yield 3;
378
399
  }
379
400
 
380
401
  type NumberType = YieldType<typeof numberGenerator>; // number
381
402
 
382
403
  // Omit properties by their value type
383
404
  type Config = {
384
- name: string;
385
- debug: boolean;
386
- verbose: boolean;
387
- timeout: number;
405
+ name: string;
406
+ debug: boolean;
407
+ verbose: boolean;
408
+ timeout: number;
388
409
  };
389
410
  type WithoutBooleans = OmitByKey<Config, boolean>; // { name: string; timeout: number }
390
411
 
391
412
  // Set specific properties to nullable
392
413
  type APIResponse = {
393
- id: number;
394
- name: string;
395
- email: string;
414
+ id: number;
415
+ name: string;
416
+ email: string;
396
417
  };
397
418
  type PartialResponse = SetNullable<APIResponse, "email" | "name">; // email and name become nullable
398
- ```
419
+
420
+ ````
399
421
 
400
422
  ### Extended Remeda Utilities
401
423
 
@@ -492,7 +514,7 @@ const totalAge = sumBy(
492
514
  // Chunk array into groups
493
515
  const chunked = chunk(users, 2);
494
516
  // [[user1, user2], [user3]]
495
- ```
517
+ ````
496
518
 
497
519
  ## API Reference
498
520
 
@@ -0,0 +1,39 @@
1
+ import { Except, IterableElement } from "type-fest";
2
+
3
+ //#region src/types/fn.d.ts
4
+ type Fn<Return = any, Args extends readonly any[] = any[]> = (...args: Args) => Return;
5
+ type FnWithThis<Return = any, Args extends readonly any[] = any[], This = unknown> = ((this: This, ...args: Args) => Return) & {
6
+ prototype: This;
7
+ };
8
+ type AsyncFn<Return = any, Args extends readonly any[] = any[]> = (...args: Args) => PromiseLike<Return>;
9
+ type AsyncFnWithThis<Return = any, Args extends readonly any[] = any[], This = unknown> = ((this: This, ...args: Args) => PromiseLike<Return>) & {
10
+ prototype: This;
11
+ };
12
+ type SyncFn<Return = any, Args extends readonly any[] = any[]> = (...args: Args) => Return extends PromiseLike<any> ? never : Return;
13
+ type SyncFnWithThis<Return = any, Args extends readonly any[] = any[], This = unknown> = ((this: This, ...args: Args) => Return extends PromiseLike<any> ? never : Return) & {
14
+ prototype: This;
15
+ };
16
+ type TemplateFn<Return = any> = (template: TemplateStringsArray, ...values: any[]) => Return;
17
+ //#endregion
18
+ //#region src/types/nullable.d.ts
19
+ type Nullable<T> = T | null | undefined;
20
+ //#endregion
21
+ //#region src/types/omit-by-key.d.ts
22
+ type OmitByKey<ObjectType, KeysType extends keyof ObjectType> = Except<ObjectType, KeysType, {
23
+ requireExactProps: true;
24
+ }>;
25
+ //#endregion
26
+ //#region src/types/optional.d.ts
27
+ type Optional<T> = T | undefined;
28
+ //#endregion
29
+ //#region src/types/set-nullable.d.ts
30
+ type SetNullable<BaseType, Keys extends keyof BaseType = keyof BaseType> = { [Key in keyof BaseType]: Key extends Keys ? Nullable<BaseType[Key]> : BaseType[Key] };
31
+ //#endregion
32
+ //#region src/types/yield-type.d.ts
33
+ type YieldType<TargetGeneratorFn extends Fn<Generator | AsyncGenerator>> = IterableElement<ReturnType<TargetGeneratorFn>>;
34
+ declare namespace index_d_exports {
35
+ export { AsyncFn, AsyncFnWithThis, Fn, FnWithThis, Nullable, OmitByKey, Optional, SetNullable, SyncFn, SyncFnWithThis, TemplateFn, YieldType };
36
+ }
37
+ import * as import_type_fest from "type-fest";
38
+ //#endregion
39
+ export { OmitByKey as a, AsyncFnWithThis as c, SyncFn as d, SyncFnWithThis as f, Optional as i, Fn as l, YieldType as n, Nullable as o, TemplateFn as p, SetNullable as r, AsyncFn as s, index_d_exports as t, FnWithThis as u };