Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: Shuunen/shuutils
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v10.4.0
Choose a base ref
...
head repository: Shuunen/shuutils
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v10.5.0
Choose a head ref
  • 3 commits
  • 8 files changed
  • 1 contributor

Commits on Feb 24, 2025

  1. chore: bump lock

    Shuunen committed Feb 24, 2025

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    887213a View commit details
  2. feat(result): integrate resultx library to have a working cjs build

    Shuunen committed Feb 24, 2025
    Copy the full SHA
    b9ea27c View commit details
  3. 10.5.0

    Shuunen committed Feb 24, 2025
    Copy the full SHA
    99961c8 View commit details
Showing with 246 additions and 118 deletions.
  1. +7 −6 biome.json
  2. +8 −1 eslint.config.js
  3. +1 −2 package.json
  4. +114 −104 pnpm-lock.yaml
  5. +52 −2 src/result.test.ts
  6. +3 −3 src/result.ts
  7. +60 −0 src/resultx.ts
  8. +1 −0 src/shuutils.ts
13 changes: 7 additions & 6 deletions biome.json
Original file line number Diff line number Diff line change
@@ -4,18 +4,19 @@
"ignore": [
"node_modules/**",
"dist/**",
"coverage/**"
"coverage/**",
"src/resultx.ts"
]
},
"formatter": {
"enabled": true,
"ignore": [
"src/shuutils.ts"
],
"indentStyle": "space",
"indentWidth": 2,
"lineEnding": "lf",
"lineWidth": 180,
"ignore": [
"src/shuutils.ts"
]
"lineWidth": 180
},
"javascript": {
"formatter": {
@@ -77,4 +78,4 @@
}
}
]
}
}
9 changes: 8 additions & 1 deletion eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import shuunen from 'eslint-plugin-shuunen'

/** @type {import('eslint').Linter.Config[]} */
const config = [...shuunen.configs.base, ...shuunen.configs.typescript]
const config = [
...shuunen.configs.base,
...shuunen.configs.typescript,
{
ignores: ['src/resultx.ts'],
name: 'shuutils-ignores',
},
]

export default config
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -6,7 +6,6 @@
},
"bugs": "https://github.com/Shuunen/shuutils/issues",
"dependencies": {
"resultx": "2.0",
"tiny-glob": "0.2"
},
"description": "utils collection",
@@ -76,5 +75,5 @@
},
"type": "module",
"types": "./dist/shuutils.d.ts",
"version": "10.4.0"
"version": "10.5.0"
}
218 changes: 114 additions & 104 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

54 changes: 52 additions & 2 deletions src/result.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { expect, it } from 'vitest'
import { Result } from './result'

it('result.ok', () => {
it('Result.ok', () => {
expect(Result.ok(42)).toMatchInlineSnapshot(`
Ok {
"ok": true,
@@ -10,11 +10,61 @@ it('result.ok', () => {
`)
})

it('result.error', () => {
it('Result.error', () => {
expect(Result.error('ay ay ay caramba !')).toMatchInlineSnapshot(`
Err {
"error": "ay ay ay caramba !",
"ok": false,
}
`)
})

it('Result.trySafe A ok', () => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
const result = Result.trySafe(() => JSON.parse('{"a": 42}'))
expect(result).toMatchInlineSnapshot(`
Ok {
"ok": true,
"value": {
"a": 42,
},
}
`)
})

it('Result.trySafe B error', () => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
const result = Result.trySafe(() => JSON.parse('{"a": 42'))
expect(result).toMatchInlineSnapshot(`
Err {
"error": [SyntaxError: Expected ',' or '}' after property value in JSON at position 8 (line 1 column 9)],
"ok": false,
}
`)
})

it('Result.trySafe C promise ok', async () => {
const result = await Result.trySafe(Promise.resolve(42))
expect(result).toMatchInlineSnapshot(`
Ok {
"ok": true,
"value": 42,
}
`)
})

it('Result.unwrap A ok', () => {
const result = Result.trySafe(() => ({ ahh: 42 }))
const { error, value } = Result.unwrap(result)
expect(value?.ahh).toMatchInlineSnapshot(`42`)
expect(error).toMatchInlineSnapshot(`undefined`)
})

it('Result.unwrap B error', () => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
const result = Result.trySafe(() => JSON.parse('{"a": 42'))
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const { error, value } = Result.unwrap(result)
expect(value).toMatchInlineSnapshot(`undefined`)
expect(error).toMatchInlineSnapshot(`[SyntaxError: Expected ',' or '}' after property value in JSON at position 8 (line 1 column 9)]`)
})
6 changes: 3 additions & 3 deletions src/result.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { err, ok, trySafe, unwrap } from 'resultx'
import { err as error, ok, trySafe, unwrap } from './resultx'

/**
* A `Result` collection of functions to handle errors and successes.
* A `Result` collection of functions from Johann Schopplich to handle errors and successes.
* @see https://github.com/johannschopplich/resultx
* @see https://github.com/Shuunen/ts-result-comparison
*/
@@ -11,7 +11,7 @@ export const Result = {
* Create a failing `Result` with an error message.
* @example if (shitHappen) return Result.error('File not found')
*/
error: err,
error,
/**
* Create a successful `Result` with a value.
* @example return Result.ok(42)
60 changes: 60 additions & 0 deletions src/resultx.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// MIT License Copyright (c) 2023-PRESENT Johann Schopplich
// I had to get sources from https://github.com/johannschopplich/resultx/blob/main/src/index.ts to be able to have a cjs working version of the library

type Result<T, E> = Ok<T> | Err<E>

interface UnwrappedOk<T> { value: T, error: undefined }
interface UnwrappedErr<E> { value: undefined, error: E }
type UnwrappedResult<T, E> = UnwrappedOk<T> | UnwrappedErr<E>

class Ok<T> {
readonly value: T
readonly ok = true
constructor(value: T) {
this.value = value
}
}

class Err<E> {
readonly error: E
readonly ok = false
constructor(error: E) {
this.error = error
}
}

export function ok<T>(value: T): Ok<T> {
return new Ok(value)
}

export function err<E extends string = string>(error: E): Err<E>
export function err<E = unknown>(error: E): Err<E>
export function err<E = unknown>(error: E): Err<E> {
return new Err(error)
}

export function trySafe<T, E = unknown>(fn: () => T): Result<T, E>
export function trySafe<T, E = unknown>(promise: Promise<T>): Promise<Result<T, E>>
export function trySafe<T, E = unknown>(
fnOrPromise: (() => T) | Promise<T>,
): Result<T, E> | Promise<Result<T, E>> {
if (fnOrPromise instanceof Promise) {
return fnOrPromise.then(ok).catch((err as (error: unknown) => Err<E>))
}

try {
return ok(fnOrPromise())
}
catch (error) {
return err(error as E)
}
}

export function unwrap<T>(result: Ok<T>): UnwrappedOk<T>
export function unwrap<E>(result: Err<E>): UnwrappedErr<E>
export function unwrap<T, E>(result: Result<T, E>): UnwrappedResult<T, E>
export function unwrap<T, E>(result: Result<T, E>): UnwrappedResult<T, E> {
return result.ok
? { value: result.value, error: undefined }
: { value: undefined, error: result.error }
}
1 change: 1 addition & 0 deletions src/shuutils.ts
Original file line number Diff line number Diff line change
@@ -36,6 +36,7 @@ export * from './object-sort'
export * from './objects'
export * from './random'
export * from './result'
export * from './resultx'
export * from './state'
export * from './storage'
export * from './string-case'