From 7ff2418033b0383effd152576aae553c2c534be0 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Wed, 20 Mar 2024 13:30:50 +0200 Subject: [PATCH 01/66] feat: implement task monad --- src/task/index.ts | 0 src/task/task.ts | 26 ++++++++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 src/task/index.ts create mode 100644 src/task/task.ts diff --git a/src/task/index.ts b/src/task/index.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/task/task.ts b/src/task/task.ts new file mode 100644 index 0000000..2892fd3 --- /dev/null +++ b/src/task/task.ts @@ -0,0 +1,26 @@ +interface Task { + map: (f: (v: T) => R) => Task + flatMap: (f: (v: T) => Task) => Task + + run: () => Promise +} + +/** + * task monad represents computation that will never fail. + * for computations that might fail use `TaskEither`. + * @see {@link ../maybe/index.ts} + * @template T - type that Task monad is going to produce + * @param {() => Promise} run - function to wrap in task + * @returns {Task} new task monad + */ +export const of = (run: () => Promise): Task => ({ + map: (f: (v: T) => R) => + of(() => Promise.resolve().then(run).then(f)), + flatMap: (f: (v: T) => Task): Task => + of(() => + Promise.resolve() + .then(run) + .then((a) => f(a).run()), + ), + run, +}) From 884b27a873dd947b34af67b5bad94c60d219e05a Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Wed, 20 Mar 2024 13:32:07 +0200 Subject: [PATCH 02/66] feat: add task monad to exports --- package.json | 5 +++++ src/index.ts | 1 + src/task/index.ts | 1 + 3 files changed, 7 insertions(+) diff --git a/package.json b/package.json index 89de577..ee9bb73 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,11 @@ "import": "./dist/state/index.mjs", "require": "./dist/state/index.js", "types": "./dist/state/index.d.ts" + }, + "./task": { + "import": "./dist/task/index.mjs", + "require": "./dist/task/index.js", + "types": "./dist/task/index.d.ts" } }, "repository": { diff --git a/src/index.ts b/src/index.ts index eaeb234..94b208d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,3 +6,4 @@ export * as R from './reader' export * as RT from './readerT' export * as I from './identity' export * as L from './lens' +export * as T from './task' diff --git a/src/task/index.ts b/src/task/index.ts index e69de29..746e7a9 100644 --- a/src/task/index.ts +++ b/src/task/index.ts @@ -0,0 +1 @@ +export * from './task' From 29e5be9423747c373506281b2d82674eb7d53822 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Wed, 20 Mar 2024 14:42:09 +0200 Subject: [PATCH 03/66] feat: implement delay method for task monad --- package.json | 7 ++++--- src/task/task.ts | 16 ++++++++++++++-- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index ee9bb73..9b56980 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,8 @@ "module": "./dist/index.mjs", "typings": "./dist/index.d.ts", "scripts": { - "esm": "esbuild --out-extension:.js=.mjs --outdir=dist --platform=node --format=esm {src/*.ts,src/**/*.ts}", - "cjs": "esbuild --outdir=dist --platform=node --format=cjs {src/*.ts,src/**/*.ts}", + "esm": "esbuild --out-extension:.js=.mjs --outdir=dist --platform=node --format=esm src/*.ts src/**/*.ts", + "cjs": "esbuild --outdir=dist --platform=node --format=cjs src/*.ts src/**/*.ts", "build": "rm -rf dist && npm run esm && npm run cjs && tsc --emitDeclarationOnly", "release": "npm run build && changeset publish", "version-packages": "changeset version", @@ -91,7 +91,8 @@ "reader", "transformer", "lens", - "prisms" + "prisms", + "tasks" ], "author": "Victor Enokh Kuptsov ", "publishConfig": { diff --git a/src/task/task.ts b/src/task/task.ts index 2892fd3..6e7d0c5 100644 --- a/src/task/task.ts +++ b/src/task/task.ts @@ -1,12 +1,14 @@ -interface Task { +export interface Task { map: (f: (v: T) => R) => Task flatMap: (f: (v: T) => Task) => Task + delay: (ms: number) => Task + run: () => Promise } /** - * task monad represents computation that will never fail. + * task monad represents an asynchronous computation that yields value of type `T` and **never fails**. * for computations that might fail use `TaskEither`. * @see {@link ../maybe/index.ts} * @template T - type that Task monad is going to produce @@ -22,5 +24,15 @@ export const of = (run: () => Promise): Task => ({ .then(run) .then((a) => f(a).run()), ), + delay: (ms) => + of( + () => + new Promise((res) => + setTimeout( + () => Promise.resolve().then(run).then(res), + ms, + ), + ), + ), run, }) From 54896b5ee841192be5e6ef91a2f9ef5ade49a237 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Thu, 21 Mar 2024 12:43:23 +0200 Subject: [PATCH 04/66] feat: implement task either --- src/either/utils/index.ts | 1 + src/either/utils/is.ts | 9 +++++++++ src/maybe/maybe.ts | 2 +- src/task-either/index.ts | 27 +++++++++++++++++++++++++++ src/task/task.ts | 4 +--- 5 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 src/either/utils/is.ts create mode 100644 src/task-either/index.ts diff --git a/src/either/utils/index.ts b/src/either/utils/index.ts index 4312f09..c1c8e6c 100644 --- a/src/either/utils/index.ts +++ b/src/either/utils/index.ts @@ -3,3 +3,4 @@ export * from './from-maybe' export * from './to-maybe' export * from './merge' export * from './try-catch' +export * from './is' diff --git a/src/either/utils/is.ts b/src/either/utils/is.ts new file mode 100644 index 0000000..ca29222 --- /dev/null +++ b/src/either/utils/is.ts @@ -0,0 +1,9 @@ +import { Either, Left, Right } from '../either' + +export const isLeft = ( + v: Either, +): v is Left => v.isLeft() + +export const isRight = ( + v: Either, +): v is Right => v.isRight() diff --git a/src/maybe/maybe.ts b/src/maybe/maybe.ts index 0f55258..6f1b009 100644 --- a/src/maybe/maybe.ts +++ b/src/maybe/maybe.ts @@ -149,7 +149,7 @@ export const of = (value: T | null): Maybe => ({ /** * Creates a Maybe monad representing absence of value. * @template T - The type of the value contained in the Maybe monad (implicitly `null` in this case). - * @returns {Maybe} A new Maybe monad representing absence of value. + * @returns A new Maybe monad representing absence of value. */ export const none = () => of(null) diff --git a/src/task-either/index.ts b/src/task-either/index.ts new file mode 100644 index 0000000..c252e78 --- /dev/null +++ b/src/task-either/index.ts @@ -0,0 +1,27 @@ +import { Either, isRight, left } from 'src/either' + +type TaskEither = { + map: (f: (v: Right) => R) => TaskEither + flatMap: ( + f: (v: Right) => TaskEither, + ) => TaskEither + run: () => Promise> +} + +export const of = ( + task: () => Promise>, +): TaskEither => ({ + map: (f: (v: Right) => R): TaskEither => + of(() => task().then((either) => either.map(f))), + flatMap: ( + f: (v: Right) => TaskEither, + ): TaskEither => + of(() => + task().then((either) => + isRight(either) + ? f(either.right).run() + : left(either.left), + ), + ), + run: task, +}) diff --git a/src/task/task.ts b/src/task/task.ts index 6e7d0c5..7295f72 100644 --- a/src/task/task.ts +++ b/src/task/task.ts @@ -1,14 +1,12 @@ export interface Task { map: (f: (v: T) => R) => Task flatMap: (f: (v: T) => Task) => Task - delay: (ms: number) => Task - run: () => Promise } /** - * task monad represents an asynchronous computation that yields value of type `T` and **never fails**. + * `Task` represents an asynchronous computation that yields value of type `T` and **never fails**. * for computations that might fail use `TaskEither`. * @see {@link ../maybe/index.ts} * @template T - type that Task monad is going to produce From 71b602663b85e6aaff3ea0b8c1d6163f0c662c11 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Thu, 21 Mar 2024 12:55:55 +0200 Subject: [PATCH 05/66] feat: add exports for task-either --- package.json | 5 +++++ src/index.ts | 1 + src/task-either/index.ts | 9 ++++++++- src/task/task.ts | 2 +- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 9b56980..711150c 100644 --- a/package.json +++ b/package.json @@ -68,6 +68,11 @@ "import": "./dist/task/index.mjs", "require": "./dist/task/index.js", "types": "./dist/task/index.d.ts" + }, + "./task-either": { + "import": "./dist/task-either/index.mjs", + "require": "./dist/task-either/index.js", + "types": "./dist/task-either/index.d.ts" } }, "repository": { diff --git a/src/index.ts b/src/index.ts index 94b208d..6d198db 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,3 +7,4 @@ export * as RT from './readerT' export * as I from './identity' export * as L from './lens' export * as T from './task' +export * as TE from './task-either' diff --git a/src/task-either/index.ts b/src/task-either/index.ts index c252e78..8ebf81a 100644 --- a/src/task-either/index.ts +++ b/src/task-either/index.ts @@ -1,6 +1,6 @@ import { Either, isRight, left } from 'src/either' -type TaskEither = { +export interface TaskEither { map: (f: (v: Right) => R) => TaskEither flatMap: ( f: (v: Right) => TaskEither, @@ -8,6 +8,13 @@ type TaskEither = { run: () => Promise> } +/** + * `TaskEither` represents asynchrounous computation that might + * fail. + * for asynchrounous computations that never fails use `Task` + * @see {@link https://maybets.duckdns.org/task Task} + * @returns {TaskEither} - new TaskEither + */ export const of = ( task: () => Promise>, ): TaskEither => ({ diff --git a/src/task/task.ts b/src/task/task.ts index 7295f72..c7f5191 100644 --- a/src/task/task.ts +++ b/src/task/task.ts @@ -8,7 +8,7 @@ export interface Task { /** * `Task` represents an asynchronous computation that yields value of type `T` and **never fails**. * for computations that might fail use `TaskEither`. - * @see {@link ../maybe/index.ts} + * @see {@link https://maybets.duckdns.org/task-either.md Task either} * @template T - type that Task monad is going to produce * @param {() => Promise} run - function to wrap in task * @returns {Task} new task monad From 75f0992c4375fdce0999554eb12b431f77b91aae Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Thu, 21 Mar 2024 16:21:27 +0200 Subject: [PATCH 06/66] feat: add TaskEither#ensureOrElse method --- package-lock.json | 11 +++++++++-- package.json | 5 +++++ src/functions/index.ts | 36 +++++++++++++++++++++++++++++++++++ src/task-either/index.ts | 11 +++++++++++ tsconfig.namespaces.json | 41 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 src/functions/index.ts create mode 100644 tsconfig.namespaces.json diff --git a/package-lock.json b/package-lock.json index 9694cf8..4956c24 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@victorenokh/maybe.ts", - "version": "1.9.0", + "version": "1.10.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@victorenokh/maybe.ts", - "version": "1.9.0", + "version": "1.10.2", "license": "MIT", "devDependencies": { "@changesets/cli": "^2.27.1", @@ -15,6 +15,7 @@ "@types/jest": "^29.5.12", "@typescript-eslint/eslint-plugin": "^7.0.1", "@typescript-eslint/parser": "^7.0.1", + "@unsplash/ts-namespace-import-plugin": "^1.0.0", "esbuild": "^0.20.2", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", @@ -3295,6 +3296,12 @@ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true }, + "node_modules/@unsplash/ts-namespace-import-plugin": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@unsplash/ts-namespace-import-plugin/-/ts-namespace-import-plugin-1.0.0.tgz", + "integrity": "sha512-Z/fuSAWte/OP1ctpM/8PtecGeBN358yR1rxMiVlTQ3xIvTTFNpjQuZuqkY3XfvWFQ8mvpqumQvS7hG8XnUkTWg==", + "dev": true + }, "node_modules/acorn": { "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", diff --git a/package.json b/package.json index 711150c..28fd677 100644 --- a/package.json +++ b/package.json @@ -73,6 +73,10 @@ "import": "./dist/task-either/index.mjs", "require": "./dist/task-either/index.js", "types": "./dist/task-either/index.d.ts" + }, + "./namespaces": { + "import": "./tsconfig.namespaces.json", + "require": "./tsconfig.namespaces.json" } }, "repository": { @@ -111,6 +115,7 @@ "@types/jest": "^29.5.12", "@typescript-eslint/eslint-plugin": "^7.0.1", "@typescript-eslint/parser": "^7.0.1", + "@unsplash/ts-namespace-import-plugin": "^1.0.0", "esbuild": "^0.20.2", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", diff --git a/src/functions/index.ts b/src/functions/index.ts new file mode 100644 index 0000000..d262b65 --- /dev/null +++ b/src/functions/index.ts @@ -0,0 +1,36 @@ +/** + * in progress + */ + +type LastElement = T extends [ + ...unknown[], + infer LastItem, +] + ? LastItem + : never + +type Operator = (value: A) => B +type OperatorA = + T extends Operator ? A : never +type OperatorB = + T extends Operator ? B : never + +type PipeOperators< + Operators extends unknown[], + Input, +> = Operators extends [infer Item, ...infer Tail] + ? [ + Operator>, + ...PipeOperators>, + ] + : Operators +type PipeOperatorsOutput = + OperatorB> + +function pipe( + ...operators: PipeOperators +): (input: Input) => PipeOperatorsOutput { + return (input) => + // @ts-expect-error we do not care + operators.reduce((result, next) => next(result), input) +} diff --git a/src/task-either/index.ts b/src/task-either/index.ts index 8ebf81a..1e7bb68 100644 --- a/src/task-either/index.ts +++ b/src/task-either/index.ts @@ -5,6 +5,10 @@ export interface TaskEither { flatMap: ( f: (v: Right) => TaskEither, ) => TaskEither + ensureOrElse: ( + p: (v: Right) => boolean, + fr: (v: Right) => Left, + ) => TaskEither run: () => Promise> } @@ -30,5 +34,12 @@ export const of = ( : left(either.left), ), ), + ensureOrElse: ( + p: (v: Right) => boolean, + fr: (v: Right) => Left, + ) => + of(() => + task().then((either) => either.ensureOrElse(p, fr)), + ), run: task, }) diff --git a/tsconfig.namespaces.json b/tsconfig.namespaces.json new file mode 100644 index 0000000..141b854 --- /dev/null +++ b/tsconfig.namespaces.json @@ -0,0 +1,41 @@ +{ + "compilerOptions": { + "plugins": [ + { + "name": "@unsplash/ts-namespace-import-plugin", + "namespaces": { + "E": { + "importPath": "@victorenokh/maybe.ts/either" + }, + "M": { + "importPath": "@victorenokh/maybe.ts/maybe" + }, + "L": { + "importPath": "@victorenokh/maybe.ts/lens" + }, + "I": { + "importPath": "@victorenokh/maybe.ts/identity" + }, + "O": { + "importPath": "@victorenokh/maybe.ts/observable" + }, + "R": { + "importPath": "@victorenokh/maybe.ts/reader" + }, + "RT": { + "importPath": "@victorenokh/maybe.ts/readerT" + }, + "S": { + "importPath": "@victorenokh/maybe.ts/state" + }, + "T": { + "importPath": "@victorenokh/maybe.ts/task" + }, + "TE": { + "importPath": "@victorenokh/maybe.ts/task-either" + } + } + } + ] + } +} From d919bed705f5359df1fd68b2cb31ccd3972e5763 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Thu, 21 Mar 2024 23:58:33 +0200 Subject: [PATCH 07/66] feat: implement TaskEither tryCatch --- src/task-either/index.ts | 47 ++---------------------------- src/task-either/task-either.ts | 45 ++++++++++++++++++++++++++++ src/task-either/utils/index.ts | 1 + src/task-either/utils/try-catch.ts | 14 +++++++++ 4 files changed, 62 insertions(+), 45 deletions(-) create mode 100644 src/task-either/task-either.ts create mode 100644 src/task-either/utils/index.ts create mode 100644 src/task-either/utils/try-catch.ts diff --git a/src/task-either/index.ts b/src/task-either/index.ts index 1e7bb68..19b6382 100644 --- a/src/task-either/index.ts +++ b/src/task-either/index.ts @@ -1,45 +1,2 @@ -import { Either, isRight, left } from 'src/either' - -export interface TaskEither { - map: (f: (v: Right) => R) => TaskEither - flatMap: ( - f: (v: Right) => TaskEither, - ) => TaskEither - ensureOrElse: ( - p: (v: Right) => boolean, - fr: (v: Right) => Left, - ) => TaskEither - run: () => Promise> -} - -/** - * `TaskEither` represents asynchrounous computation that might - * fail. - * for asynchrounous computations that never fails use `Task` - * @see {@link https://maybets.duckdns.org/task Task} - * @returns {TaskEither} - new TaskEither - */ -export const of = ( - task: () => Promise>, -): TaskEither => ({ - map: (f: (v: Right) => R): TaskEither => - of(() => task().then((either) => either.map(f))), - flatMap: ( - f: (v: Right) => TaskEither, - ): TaskEither => - of(() => - task().then((either) => - isRight(either) - ? f(either.right).run() - : left(either.left), - ), - ), - ensureOrElse: ( - p: (v: Right) => boolean, - fr: (v: Right) => Left, - ) => - of(() => - task().then((either) => either.ensureOrElse(p, fr)), - ), - run: task, -}) +export * from './task-either' +export * from './utils' diff --git a/src/task-either/task-either.ts b/src/task-either/task-either.ts new file mode 100644 index 0000000..1e7bb68 --- /dev/null +++ b/src/task-either/task-either.ts @@ -0,0 +1,45 @@ +import { Either, isRight, left } from 'src/either' + +export interface TaskEither { + map: (f: (v: Right) => R) => TaskEither + flatMap: ( + f: (v: Right) => TaskEither, + ) => TaskEither + ensureOrElse: ( + p: (v: Right) => boolean, + fr: (v: Right) => Left, + ) => TaskEither + run: () => Promise> +} + +/** + * `TaskEither` represents asynchrounous computation that might + * fail. + * for asynchrounous computations that never fails use `Task` + * @see {@link https://maybets.duckdns.org/task Task} + * @returns {TaskEither} - new TaskEither + */ +export const of = ( + task: () => Promise>, +): TaskEither => ({ + map: (f: (v: Right) => R): TaskEither => + of(() => task().then((either) => either.map(f))), + flatMap: ( + f: (v: Right) => TaskEither, + ): TaskEither => + of(() => + task().then((either) => + isRight(either) + ? f(either.right).run() + : left(either.left), + ), + ), + ensureOrElse: ( + p: (v: Right) => boolean, + fr: (v: Right) => Left, + ) => + of(() => + task().then((either) => either.ensureOrElse(p, fr)), + ), + run: task, +}) diff --git a/src/task-either/utils/index.ts b/src/task-either/utils/index.ts new file mode 100644 index 0000000..770c2e2 --- /dev/null +++ b/src/task-either/utils/index.ts @@ -0,0 +1 @@ +export * from './try-catch' diff --git a/src/task-either/utils/try-catch.ts b/src/task-either/utils/try-catch.ts new file mode 100644 index 0000000..2cdf8d5 --- /dev/null +++ b/src/task-either/utils/try-catch.ts @@ -0,0 +1,14 @@ +import { left, right } from 'src/either' +import { TaskEither, of } from '..' + +export const tryCatch = ( + tryFn: () => Promise, + catchFn: (e: unknown) => E, +): TaskEither => + of(async () => { + try { + return right(await tryFn()) + } catch (e) { + return left(catchFn(e)) + } + }) From 4ff7b543b9c0a627c0fefa5b6fbd7642607b8fb7 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Fri, 22 Mar 2024 00:05:23 +0200 Subject: [PATCH 08/66] feat: implement to error util --- src/either/utils/index.ts | 1 + src/either/utils/to-error.ts | 2 ++ src/either/utils/try-catch.ts | 1 - 3 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 src/either/utils/to-error.ts diff --git a/src/either/utils/index.ts b/src/either/utils/index.ts index c1c8e6c..3ee6fbd 100644 --- a/src/either/utils/index.ts +++ b/src/either/utils/index.ts @@ -4,3 +4,4 @@ export * from './to-maybe' export * from './merge' export * from './try-catch' export * from './is' +export * from './to-error' diff --git a/src/either/utils/to-error.ts b/src/either/utils/to-error.ts new file mode 100644 index 0000000..3436b21 --- /dev/null +++ b/src/either/utils/to-error.ts @@ -0,0 +1,2 @@ +export const toError = (error: unknown): Error => + error instanceof Error ? error : new Error(String(error)) diff --git a/src/either/utils/try-catch.ts b/src/either/utils/try-catch.ts index 0ab0bfd..316d149 100644 --- a/src/either/utils/try-catch.ts +++ b/src/either/utils/try-catch.ts @@ -1,5 +1,4 @@ import { Either, left, right } from '../either' - /** * Executes a function in a try-catch block, returning either the result of the try function * or an error produced by the catch function. From 973d50754bb894f49b6227ca77d911ca68c6d23f Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Fri, 22 Mar 2024 00:51:32 +0200 Subject: [PATCH 09/66] feat: add import aliases --- esbuild.js | 30 + package-lock.json | 3199 ++++++++++++++++++++++++++++++-- package.json | 8 +- src/either/utils/from-maybe.ts | 4 +- src/lens/prism.ts | 4 +- tsconfig.json | 7 +- 6 files changed, 3108 insertions(+), 144 deletions(-) create mode 100644 esbuild.js diff --git a/esbuild.js b/esbuild.js new file mode 100644 index 0000000..f02dc82 --- /dev/null +++ b/esbuild.js @@ -0,0 +1,30 @@ +const esbuild = require('esbuild') +const { replaceTscAliasPaths } = require('tsc-alias') +/** + * @type {esbuild.BuildOptions} + */ +const baseOptions = { + platform: 'node', + outdir: 'dist', + plugins: [], + entryPoints: ['src/*.ts', 'src/**/*.ts'], +} + +esbuild.build({ + ...baseOptions, + outExtension: { '.js': '.mjs' }, + format: 'esm', +}) + +esbuild.build({ + ...baseOptions, + format: 'cjs', +}) + +replaceTscAliasPaths({ + configFile: 'tsconfig.json', + watch: false, + outDir: 'dist', + declarationDir: 'dist', + fileExtensions: '.mjs', +}) diff --git a/package-lock.json b/package-lock.json index 4956c24..7becb58 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,15 +17,19 @@ "@typescript-eslint/parser": "^7.0.1", "@unsplash/ts-namespace-import-plugin": "^1.0.0", "esbuild": "^0.20.2", + "esbuild-ts-paths": "^1.1.3", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", "husky": "^9.0.10", + "i": "^0.3.7", "jest": "^29.7.0", "lint-staged": "^15.2.2", + "npm": "^10.5.0", "prettier": "^3.2.5", "ts-jest": "^29.1.2", "ts-node": "^10.9.2", + "tsc-alias": "^1.8.8", "typescript": "^5.3.3" } }, @@ -3732,6 +3736,18 @@ "node": ">=4" } }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -3924,6 +3940,42 @@ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/ci-info": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", @@ -4815,6 +4867,16 @@ "@esbuild/win32-x64": "0.20.2" } }, + "node_modules/esbuild-ts-paths": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/esbuild-ts-paths/-/esbuild-ts-paths-1.1.3.tgz", + "integrity": "sha512-qV8WVCcMhQplEfqeu1VPa7llPL9NXpEES275z8z3FHhrescVKNzLSawGOINpmPTYo+WFUiKKLwSFcM0JoQQ5eg==", + "dev": true, + "dependencies": { + "fast-glob": "^3.2.11", + "normalize-path": "^3.0.0" + } + }, "node_modules/escalade": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", @@ -5864,6 +5926,15 @@ "url": "https://github.com/sponsors/typicode" } }, + "node_modules/i": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/i/-/i-0.3.7.tgz", + "integrity": "sha512-FYz4wlXgkQwIPqhzC5TdNMLSE5+GS1IIDJZY/1ZiEPCT2S3COUVZeT5OW4BmW4r5LHLQuOosSwsvnroG9GR59Q==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -6030,6 +6101,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-boolean-object": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", @@ -8777,6 +8860,19 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "node_modules/mylas": { + "version": "2.1.13", + "resolved": "https://registry.npmjs.org/mylas/-/mylas-2.1.13.tgz", + "integrity": "sha512-+MrqnJRtxdF+xngFfUUkIMQrUUL0KsxbADUkn23Z/4ibGg192Q+z+CQyiYwvWTsYjJygmMR8+w3ZDa98Zh6ESg==", + "dev": true, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/raouldeheer" + } + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -8825,6 +8921,170 @@ "node": ">=0.10.0" } }, + "node_modules/npm": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/npm/-/npm-10.5.0.tgz", + "integrity": "sha512-Ejxwvfh9YnWVU2yA5FzoYLTW52vxHCz+MHrOFg9Cc8IFgF/6f5AGPAvb5WTay5DIUP1NIfN3VBZ0cLlGO0Ys+A==", + "bundleDependencies": [ + "@isaacs/string-locale-compare", + "@npmcli/arborist", + "@npmcli/config", + "@npmcli/fs", + "@npmcli/map-workspaces", + "@npmcli/package-json", + "@npmcli/promise-spawn", + "@npmcli/run-script", + "@sigstore/tuf", + "abbrev", + "archy", + "cacache", + "chalk", + "ci-info", + "cli-columns", + "cli-table3", + "columnify", + "fastest-levenshtein", + "fs-minipass", + "glob", + "graceful-fs", + "hosted-git-info", + "ini", + "init-package-json", + "is-cidr", + "json-parse-even-better-errors", + "libnpmaccess", + "libnpmdiff", + "libnpmexec", + "libnpmfund", + "libnpmhook", + "libnpmorg", + "libnpmpack", + "libnpmpublish", + "libnpmsearch", + "libnpmteam", + "libnpmversion", + "make-fetch-happen", + "minimatch", + "minipass", + "minipass-pipeline", + "ms", + "node-gyp", + "nopt", + "normalize-package-data", + "npm-audit-report", + "npm-install-checks", + "npm-package-arg", + "npm-pick-manifest", + "npm-profile", + "npm-registry-fetch", + "npm-user-validate", + "npmlog", + "p-map", + "pacote", + "parse-conflict-json", + "proc-log", + "qrcode-terminal", + "read", + "semver", + "spdx-expression-parse", + "ssri", + "supports-color", + "tar", + "text-table", + "tiny-relative-date", + "treeverse", + "validate-npm-package-name", + "which", + "write-file-atomic" + ], + "dev": true, + "workspaces": [ + "docs", + "smoke-tests", + "mock-globals", + "mock-registry", + "workspaces/*" + ], + "dependencies": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/arborist": "^7.2.1", + "@npmcli/config": "^8.0.2", + "@npmcli/fs": "^3.1.0", + "@npmcli/map-workspaces": "^3.0.4", + "@npmcli/package-json": "^5.0.0", + "@npmcli/promise-spawn": "^7.0.1", + "@npmcli/run-script": "^7.0.4", + "@sigstore/tuf": "^2.3.1", + "abbrev": "^2.0.0", + "archy": "~1.0.0", + "cacache": "^18.0.2", + "chalk": "^5.3.0", + "ci-info": "^4.0.0", + "cli-columns": "^4.0.0", + "cli-table3": "^0.6.3", + "columnify": "^1.6.0", + "fastest-levenshtein": "^1.0.16", + "fs-minipass": "^3.0.3", + "glob": "^10.3.10", + "graceful-fs": "^4.2.11", + "hosted-git-info": "^7.0.1", + "ini": "^4.1.1", + "init-package-json": "^6.0.0", + "is-cidr": "^5.0.3", + "json-parse-even-better-errors": "^3.0.1", + "libnpmaccess": "^8.0.1", + "libnpmdiff": "^6.0.3", + "libnpmexec": "^7.0.4", + "libnpmfund": "^5.0.1", + "libnpmhook": "^10.0.0", + "libnpmorg": "^6.0.1", + "libnpmpack": "^6.0.3", + "libnpmpublish": "^9.0.2", + "libnpmsearch": "^7.0.0", + "libnpmteam": "^6.0.0", + "libnpmversion": "^5.0.1", + "make-fetch-happen": "^13.0.0", + "minimatch": "^9.0.3", + "minipass": "^7.0.4", + "minipass-pipeline": "^1.2.4", + "ms": "^2.1.2", + "node-gyp": "^10.0.1", + "nopt": "^7.2.0", + "normalize-package-data": "^6.0.0", + "npm-audit-report": "^5.0.0", + "npm-install-checks": "^6.3.0", + "npm-package-arg": "^11.0.1", + "npm-pick-manifest": "^9.0.0", + "npm-profile": "^9.0.0", + "npm-registry-fetch": "^16.1.0", + "npm-user-validate": "^2.0.0", + "npmlog": "^7.0.1", + "p-map": "^4.0.0", + "pacote": "^17.0.6", + "parse-conflict-json": "^3.0.1", + "proc-log": "^3.0.0", + "qrcode-terminal": "^0.12.0", + "read": "^2.1.0", + "semver": "^7.6.0", + "spdx-expression-parse": "^3.0.1", + "ssri": "^10.0.5", + "supports-color": "^9.4.0", + "tar": "^6.2.0", + "text-table": "~0.2.0", + "tiny-relative-date": "^1.3.0", + "treeverse": "^3.0.0", + "validate-npm-package-name": "^5.0.0", + "which": "^4.0.0", + "write-file-atomic": "^5.0.1" + }, + "bin": { + "npm": "bin/npm-cli.js", + "npx": "bin/npx-cli.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, "node_modules/npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -8837,236 +9097,2844 @@ "node": ">=8" } }, - "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "node_modules/npm/node_modules/@colors/colors": { + "version": "1.5.0", "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" } }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "node_modules/npm/node_modules/@isaacs/cliui": { + "version": "8.0.2", "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, "engines": { - "node": ">= 0.4" + "node": ">=12" } }, - "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", "dev": true, - "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, + "inBundle": true, + "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", "dev": true, - "dependencies": { - "wrappy": "1" - } + "inBundle": true, + "license": "MIT" }, - "node_modules/onetime": { + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, + "inBundle": true, + "license": "MIT", "dependencies": { - "mimic-fn": "^2.1.0" + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">=6" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", "dev": true, + "inBundle": true, + "license": "MIT", "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" + "ansi-regex": "^6.0.1" }, "engines": { - "node": ">= 0.8.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "node_modules/npm/node_modules/@isaacs/string-locale-compare": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/@npmcli/agent": { + "version": "2.2.1", "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/arborist": { + "version": "7.4.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/fs": "^3.1.0", + "@npmcli/installed-package-contents": "^2.0.2", + "@npmcli/map-workspaces": "^3.0.2", + "@npmcli/metavuln-calculator": "^7.0.0", + "@npmcli/name-from-folder": "^2.0.0", + "@npmcli/node-gyp": "^3.0.0", + "@npmcli/package-json": "^5.0.0", + "@npmcli/query": "^3.1.0", + "@npmcli/run-script": "^7.0.2", + "bin-links": "^4.0.1", + "cacache": "^18.0.0", + "common-ancestor-path": "^1.0.1", + "hosted-git-info": "^7.0.1", + "json-parse-even-better-errors": "^3.0.0", + "json-stringify-nice": "^1.1.4", + "minimatch": "^9.0.0", + "nopt": "^7.0.0", + "npm-install-checks": "^6.2.0", + "npm-package-arg": "^11.0.1", + "npm-pick-manifest": "^9.0.0", + "npm-registry-fetch": "^16.0.0", + "npmlog": "^7.0.1", + "pacote": "^17.0.4", + "parse-conflict-json": "^3.0.0", + "proc-log": "^3.0.0", + "promise-all-reject-late": "^1.0.0", + "promise-call-limit": "^3.0.1", + "read-package-json-fast": "^3.0.2", + "semver": "^7.3.7", + "ssri": "^10.0.5", + "treeverse": "^3.0.0", + "walk-up-path": "^3.0.1" + }, + "bin": { + "arborist": "bin/index.js" + }, "engines": { - "node": ">=0.10.0" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/outdent": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/outdent/-/outdent-0.5.0.tgz", - "integrity": "sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==", - "dev": true - }, - "node_modules/p-filter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", - "integrity": "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==", + "node_modules/npm/node_modules/@npmcli/config": { + "version": "8.2.0", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "p-map": "^2.0.0" + "@npmcli/map-workspaces": "^3.0.2", + "ci-info": "^4.0.0", + "ini": "^4.1.0", + "nopt": "^7.0.0", + "proc-log": "^3.0.0", + "read-package-json-fast": "^3.0.2", + "semver": "^7.3.5", + "walk-up-path": "^3.0.1" }, "engines": { - "node": ">=8" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/npm/node_modules/@npmcli/disparity-colors": { + "version": "3.0.0", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "p-try": "^2.0.0" + "ansi-styles": "^4.3.0" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "node_modules/npm/node_modules/@npmcli/disparity-colors/node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, + "inBundle": true, + "license": "MIT", "dependencies": { - "p-limit": "^3.0.2" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=10" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/p-locate/node_modules/p-limit": { + "node_modules/npm/node_modules/@npmcli/fs": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "yocto-queue": "^0.1.0" + "semver": "^7.3.5" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "node_modules/npm/node_modules/@npmcli/git": { + "version": "5.0.4", "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/promise-spawn": "^7.0.0", + "lru-cache": "^10.0.1", + "npm-pick-manifest": "^9.0.0", + "proc-log": "^3.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^4.0.0" + }, "engines": { - "node": ">=6" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "node_modules/npm/node_modules/@npmcli/installed-package-contents": { + "version": "2.0.2", "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-bundled": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "bin": { + "installed-package-contents": "lib/index.js" + }, "engines": { - "node": ">=6" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "node_modules/npm/node_modules/@npmcli/map-workspaces": { + "version": "3.0.4", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "callsites": "^3.0.0" + "@npmcli/name-from-folder": "^2.0.0", + "glob": "^10.2.2", + "minimatch": "^9.0.0", + "read-package-json-fast": "^3.0.0" }, "engines": { - "node": ">=6" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { + "version": "7.0.0", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" + "cacache": "^18.0.0", + "json-parse-even-better-errors": "^3.0.0", + "pacote": "^17.0.0", + "semver": "^7.3.5" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "node_modules/npm/node_modules/@npmcli/name-from-folder": { + "version": "2.0.0", "dev": true, + "inBundle": true, + "license": "ISC", "engines": { - "node": ">=8" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "node_modules/npm/node_modules/@npmcli/node-gyp": { + "version": "3.0.0", "dev": true, + "inBundle": true, + "license": "ISC", "engines": { - "node": ">=0.10.0" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "node_modules/npm/node_modules/@npmcli/package-json": { + "version": "5.0.0", "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^5.0.0", + "glob": "^10.2.2", + "hosted-git-info": "^7.0.0", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^6.0.0", + "proc-log": "^3.0.0", + "semver": "^7.5.3" + }, "engines": { - "node": ">=8" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, + "node_modules/npm/node_modules/@npmcli/promise-spawn": { + "version": "7.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/query": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/run-script": { + "version": "7.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/node-gyp": "^3.0.0", + "@npmcli/package-json": "^5.0.0", + "@npmcli/promise-spawn": "^7.0.0", + "node-gyp": "^10.0.0", + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/npm/node_modules/@sigstore/bundle": { + "version": "2.2.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.3.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@sigstore/core": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@sigstore/protobuf-specs": { + "version": "0.3.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@sigstore/sign": { + "version": "2.2.3", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^2.2.0", + "@sigstore/core": "^1.0.0", + "@sigstore/protobuf-specs": "^0.3.0", + "make-fetch-happen": "^13.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@sigstore/tuf": { + "version": "2.3.1", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.3.0", + "tuf-js": "^2.2.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@sigstore/verify": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^2.2.0", + "@sigstore/core": "^1.0.0", + "@sigstore/protobuf-specs": "^0.3.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@tufjs/canonical-json": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@tufjs/models": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^9.0.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/abbrev": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/agent-base": { + "version": "7.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/npm/node_modules/aggregate-error": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/ansi-styles": { + "version": "6.2.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/npm/node_modules/aproba": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/archy": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/are-we-there-yet": { + "version": "4.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/bin-links": { + "version": "4.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "cmd-shim": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "read-cmd-shim": "^4.0.0", + "write-file-atomic": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/binary-extensions": { + "version": "2.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/brace-expansion": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/npm/node_modules/builtins": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "semver": "^7.0.0" + } + }, + "node_modules/npm/node_modules/cacache": { + "version": "18.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/chalk": { + "version": "5.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/npm/node_modules/chownr": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/ci-info": { + "version": "4.0.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/cidr-regex": { + "version": "4.0.3", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "ip-regex": "^5.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/npm/node_modules/clean-stack": { + "version": "2.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/cli-columns": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/npm/node_modules/cli-table3": { + "version": "0.6.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/npm/node_modules/clone": { + "version": "1.0.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/npm/node_modules/cmd-shim": { + "version": "6.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/npm/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/color-support": { + "version": "1.1.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/npm/node_modules/columnify": { + "version": "1.6.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "strip-ansi": "^6.0.1", + "wcwidth": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/npm/node_modules/common-ancestor-path": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/console-control-strings": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/cross-spawn": { + "version": "7.0.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/cssesc": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/debug": { + "version": "4.3.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/npm/node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/defaults": { + "version": "1.0.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/diff": { + "version": "5.2.0", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/npm/node_modules/eastasianwidth": { + "version": "0.2.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/encoding": { + "version": "0.1.13", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/npm/node_modules/env-paths": { + "version": "2.2.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/err-code": { + "version": "2.0.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/exponential-backoff": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "Apache-2.0" + }, + "node_modules/npm/node_modules/fastest-levenshtein": { + "version": "1.0.16", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/npm/node_modules/foreground-child": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/fs-minipass": { + "version": "3.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/function-bind": { + "version": "1.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/npm/node_modules/gauge": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^4.0.1", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/glob": { + "version": "10.3.10", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/graceful-fs": { + "version": "4.2.11", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/has-unicode": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/hasown": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/npm/node_modules/hosted-git-info": { + "version": "7.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/http-cache-semantics": { + "version": "4.1.1", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause" + }, + "node_modules/npm/node_modules/http-proxy-agent": { + "version": "7.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/npm/node_modules/https-proxy-agent": { + "version": "7.0.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/npm/node_modules/iconv-lite": { + "version": "0.6.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/ignore-walk": { + "version": "6.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/imurmurhash": { + "version": "0.1.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/npm/node_modules/indent-string": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/ini": { + "version": "4.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/init-package-json": { + "version": "6.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-package-arg": "^11.0.0", + "promzard": "^1.0.0", + "read": "^2.0.0", + "read-package-json": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/ip-address": { + "version": "9.0.5", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/npm/node_modules/ip-address/node_modules/sprintf-js": { + "version": "1.1.3", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause" + }, + "node_modules/npm/node_modules/ip-regex": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/is-cidr": { + "version": "5.0.3", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "cidr-regex": "4.0.3" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/npm/node_modules/is-core-module": { + "version": "2.13.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/npm/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/is-lambda": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/jackspeak": { + "version": "2.3.6", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/npm/node_modules/jsbn": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/json-parse-even-better-errors": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/json-stringify-nice": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/jsonparse": { + "version": "1.3.1", + "dev": true, + "engines": [ + "node >= 0.2.0" + ], + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/just-diff": { + "version": "6.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/just-diff-apply": { + "version": "5.5.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/libnpmaccess": { + "version": "8.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-package-arg": "^11.0.1", + "npm-registry-fetch": "^16.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmdiff": { + "version": "6.0.7", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^7.2.1", + "@npmcli/disparity-colors": "^3.0.0", + "@npmcli/installed-package-contents": "^2.0.2", + "binary-extensions": "^2.2.0", + "diff": "^5.1.0", + "minimatch": "^9.0.0", + "npm-package-arg": "^11.0.1", + "pacote": "^17.0.4", + "tar": "^6.2.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmexec": { + "version": "7.0.8", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^7.2.1", + "@npmcli/run-script": "^7.0.2", + "ci-info": "^4.0.0", + "npm-package-arg": "^11.0.1", + "npmlog": "^7.0.1", + "pacote": "^17.0.4", + "proc-log": "^3.0.0", + "read": "^2.0.0", + "read-package-json-fast": "^3.0.2", + "semver": "^7.3.7", + "walk-up-path": "^3.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmfund": { + "version": "5.0.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^7.2.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmhook": { + "version": "10.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^16.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmorg": { + "version": "6.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^16.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmpack": { + "version": "6.0.7", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^7.2.1", + "@npmcli/run-script": "^7.0.2", + "npm-package-arg": "^11.0.1", + "pacote": "^17.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmpublish": { + "version": "9.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "ci-info": "^4.0.0", + "normalize-package-data": "^6.0.0", + "npm-package-arg": "^11.0.1", + "npm-registry-fetch": "^16.0.0", + "proc-log": "^3.0.0", + "semver": "^7.3.7", + "sigstore": "^2.2.0", + "ssri": "^10.0.5" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmsearch": { + "version": "7.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-registry-fetch": "^16.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmteam": { + "version": "6.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^16.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmversion": { + "version": "5.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^5.0.3", + "@npmcli/run-script": "^7.0.2", + "json-parse-even-better-errors": "^3.0.0", + "proc-log": "^3.0.0", + "semver": "^7.3.7" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/lru-cache": { + "version": "10.2.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/npm/node_modules/make-fetch-happen": { + "version": "13.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/agent": "^2.0.0", + "cacache": "^18.0.0", + "http-cache-semantics": "^4.1.1", + "is-lambda": "^1.0.1", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/minimatch": { + "version": "9.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/minipass": { + "version": "7.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/npm/node_modules/minipass-collect": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/npm/node_modules/minipass-fetch": { + "version": "3.0.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/npm/node_modules/minipass-flush": { + "version": "1.0.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-json-stream": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "jsonparse": "^1.3.1", + "minipass": "^3.0.0" + } + }, + "node_modules/npm/node_modules/minipass-json-stream/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-pipeline": { + "version": "1.2.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-sized": { + "version": "1.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minizlib": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/mkdirp": { + "version": "1.0.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/ms": { + "version": "2.1.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/mute-stream": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/negotiator": { + "version": "0.6.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/npm/node_modules/node-gyp": { + "version": "10.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^10.3.10", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^13.0.0", + "nopt": "^7.0.0", + "proc-log": "^3.0.0", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^4.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/nopt": { + "version": "7.2.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/normalize-package-data": { + "version": "6.0.0", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^7.0.0", + "is-core-module": "^2.8.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-audit-report": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-bundled": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-install-checks": { + "version": "6.3.0", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-normalize-package-bin": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-package-arg": { + "version": "11.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^7.0.0", + "proc-log": "^3.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-packlist": { + "version": "8.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "ignore-walk": "^6.0.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-pick-manifest": { + "version": "9.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-install-checks": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "npm-package-arg": "^11.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-profile": { + "version": "9.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-registry-fetch": "^16.0.0", + "proc-log": "^3.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-registry-fetch": { + "version": "16.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "make-fetch-happen": "^13.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minipass-json-stream": "^1.0.1", + "minizlib": "^2.1.2", + "npm-package-arg": "^11.0.0", + "proc-log": "^3.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-user-validate": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npmlog": { + "version": "7.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "are-we-there-yet": "^4.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^5.0.0", + "set-blocking": "^2.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/p-map": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/pacote": { + "version": "17.0.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^5.0.0", + "@npmcli/installed-package-contents": "^2.0.1", + "@npmcli/promise-spawn": "^7.0.0", + "@npmcli/run-script": "^7.0.0", + "cacache": "^18.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^11.0.0", + "npm-packlist": "^8.0.0", + "npm-pick-manifest": "^9.0.0", + "npm-registry-fetch": "^16.0.0", + "proc-log": "^3.0.0", + "promise-retry": "^2.0.1", + "read-package-json": "^7.0.0", + "read-package-json-fast": "^3.0.0", + "sigstore": "^2.2.0", + "ssri": "^10.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "lib/bin.js" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/parse-conflict-json": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^3.0.0", + "just-diff": "^6.0.0", + "just-diff-apply": "^5.2.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/path-key": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/path-scurry": { + "version": "1.10.1", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/postcss-selector-parser": { + "version": "6.0.15", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/proc-log": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/promise-all-reject-late": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/promise-call-limit": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/promise-inflight": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/promise-retry": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/promzard": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "read": "^2.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/qrcode-terminal": { + "version": "0.12.0", + "dev": true, + "inBundle": true, + "bin": { + "qrcode-terminal": "bin/qrcode-terminal.js" + } + }, + "node_modules/npm/node_modules/read": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "mute-stream": "~1.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/read-cmd-shim": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/read-package-json": { + "version": "7.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "glob": "^10.2.2", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/read-package-json-fast": { + "version": "3.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/retry": { + "version": "0.12.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/npm/node_modules/safer-buffer": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/npm/node_modules/semver": { + "version": "7.6.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/set-blocking": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/shebang-command": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/shebang-regex": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/signal-exit": { + "version": "4.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/sigstore": { + "version": "2.2.2", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^2.2.0", + "@sigstore/core": "^1.0.0", + "@sigstore/protobuf-specs": "^0.3.0", + "@sigstore/sign": "^2.2.3", + "@sigstore/tuf": "^2.3.1", + "@sigstore/verify": "^1.1.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/smart-buffer": { + "version": "4.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/npm/node_modules/socks": { + "version": "2.8.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 16.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/npm/node_modules/socks-proxy-agent": { + "version": "8.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "socks": "^2.7.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/npm/node_modules/spdx-correct": { + "version": "3.2.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/npm/node_modules/spdx-exceptions": { + "version": "2.5.0", + "dev": true, + "inBundle": true, + "license": "CC-BY-3.0" + }, + "node_modules/npm/node_modules/spdx-expression-parse": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/npm/node_modules/spdx-license-ids": { + "version": "3.0.17", + "dev": true, + "inBundle": true, + "license": "CC0-1.0" + }, + "node_modules/npm/node_modules/ssri": { + "version": "10.0.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/supports-color": { + "version": "9.4.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/npm/node_modules/tar": { + "version": "6.2.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/text-table": { + "version": "0.2.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/tiny-relative-date": { + "version": "1.3.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/treeverse": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/tuf-js": { + "version": "2.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@tufjs/models": "2.0.0", + "debug": "^4.3.4", + "make-fetch-happen": "^13.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/unique-filename": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/unique-slug": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/validate-npm-package-license": { + "version": "3.0.4", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/npm/node_modules/validate-npm-package-name": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "builtins": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/walk-up-path": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/wcwidth": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/npm/node_modules/which": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/which/node_modules/isexe": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/npm/node_modules/wide-align": { + "version": "1.1.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/npm/node_modules/wrap-ansi": { + "version": "8.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/npm/node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/npm/node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/npm/node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/npm/node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "9.2.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/wrap-ansi/node_modules/string-width": { + "version": "5.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/npm/node_modules/write-file-atomic": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/outdent": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/outdent/-/outdent-0.5.0.tgz", + "integrity": "sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==", + "dev": true + }, + "node_modules/p-filter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", + "integrity": "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==", + "dev": true, + "dependencies": { + "p-map": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -9173,6 +12041,18 @@ "node": ">=8" } }, + "node_modules/plimit-lit": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/plimit-lit/-/plimit-lit-1.6.1.tgz", + "integrity": "sha512-B7+VDyb8Tl6oMJT9oSO2CW8XC/T4UcJGrwOVoNGwOQsQYhlpfajmrMj5xeejqaASq3V/EqThyOeATEOMuSEXiA==", + "dev": true, + "dependencies": { + "queue-lit": "^1.5.1" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/possible-typed-array-names": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", @@ -9303,6 +12183,15 @@ } ] }, + "node_modules/queue-lit": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/queue-lit/-/queue-lit-1.5.2.tgz", + "integrity": "sha512-tLc36IOPeMAubu8BkW8YDBV+WyIgKlYU7zUNs0J5Vk9skSZ4JfGlPOqplP0aHdfv7HL0B2Pg6nwiq60Qc6M2Hw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -9449,6 +12338,18 @@ "node": ">=4" } }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -10597,6 +13498,32 @@ } } }, + "node_modules/tsc-alias": { + "version": "1.8.8", + "resolved": "https://registry.npmjs.org/tsc-alias/-/tsc-alias-1.8.8.tgz", + "integrity": "sha512-OYUOd2wl0H858NvABWr/BoSKNERw3N9GTi3rHPK8Iv4O1UyUXIrTTOAZNHsjlVpXFOhpJBVARI1s+rzwLivN3Q==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.3", + "commander": "^9.0.0", + "globby": "^11.0.4", + "mylas": "^2.1.9", + "normalize-path": "^3.0.0", + "plimit-lit": "^1.2.6" + }, + "bin": { + "tsc-alias": "dist/bin/index.js" + } + }, + "node_modules/tsc-alias/node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, "node_modules/tslib": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", diff --git a/package.json b/package.json index 28fd677..2349815 100644 --- a/package.json +++ b/package.json @@ -6,9 +6,7 @@ "module": "./dist/index.mjs", "typings": "./dist/index.d.ts", "scripts": { - "esm": "esbuild --out-extension:.js=.mjs --outdir=dist --platform=node --format=esm src/*.ts src/**/*.ts", - "cjs": "esbuild --outdir=dist --platform=node --format=cjs src/*.ts src/**/*.ts", - "build": "rm -rf dist && npm run esm && npm run cjs && tsc --emitDeclarationOnly", + "build": "rm -rf dist && node esbuild.js && tsc --emitDeclarationOnly", "release": "npm run build && changeset publish", "version-packages": "changeset version", "test-coverage": "jest --coverage", @@ -117,15 +115,19 @@ "@typescript-eslint/parser": "^7.0.1", "@unsplash/ts-namespace-import-plugin": "^1.0.0", "esbuild": "^0.20.2", + "esbuild-ts-paths": "^1.1.3", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", "husky": "^9.0.10", + "i": "^0.3.7", "jest": "^29.7.0", "lint-staged": "^15.2.2", + "npm": "^10.5.0", "prettier": "^3.2.5", "ts-jest": "^29.1.2", "ts-node": "^10.9.2", + "tsc-alias": "^1.8.8", "typescript": "^5.3.3" } } diff --git a/src/either/utils/from-maybe.ts b/src/either/utils/from-maybe.ts index a98a05d..5e52b58 100644 --- a/src/either/utils/from-maybe.ts +++ b/src/either/utils/from-maybe.ts @@ -1,5 +1,5 @@ -import { Maybe } from '../../maybe/' -import { Either, left, right } from '../either' +import { Maybe } from '->/maybe' +import { Either, left, right } from '->/either' /** * Converts a value from the Maybe monad to an Either monad. diff --git a/src/lens/prism.ts b/src/lens/prism.ts index 8a0b4d3..165bef2 100644 --- a/src/lens/prism.ts +++ b/src/lens/prism.ts @@ -1,5 +1,5 @@ -import { Maybe } from '../maybe' -import { of } from '../maybe' +import { Maybe } from '->/maybe' +import { of } from '->/maybe' export interface Prism { view: (v: T) => Maybe diff --git a/tsconfig.json b/tsconfig.json index 9eb5910..252d65d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,7 +8,12 @@ "forceConsistentCasingInFileNames": true, "declaration": true, "outDir": "./dist", - "baseUrl": "./" + "baseUrl": "./", + "paths": { + "->/*": [ + "./src/*" + ] + } }, "include": [ "src/**/*.ts" From 9963955bc10114145a7166ab1cb50d769fa58e20 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Fri, 22 Mar 2024 00:58:56 +0200 Subject: [PATCH 10/66] refactor: changed all ../ to ->/ --- src/either/utils/from-throwable.ts | 2 +- src/either/utils/is.ts | 2 +- src/either/utils/merge.ts | 2 +- src/either/utils/to-maybe.ts | 4 ++-- src/either/utils/try-catch.ts | 2 +- src/maybe/utils/from-throwable.ts | 2 +- src/maybe/utils/from-undefined.ts | 2 +- src/maybe/utils/merge-map.ts | 2 +- src/maybe/utils/merge.ts | 2 +- src/maybe/utils/or.ts | 2 +- src/observable/utils/merge.ts | 2 +- src/readerT/index.ts | 2 +- tsconfig.json | 3 +++ 13 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/either/utils/from-throwable.ts b/src/either/utils/from-throwable.ts index 761507b..11e6dc7 100644 --- a/src/either/utils/from-throwable.ts +++ b/src/either/utils/from-throwable.ts @@ -1,4 +1,4 @@ -import { Either, left, right } from '../either' +import { Either, left, right } from '->/either' /** * Constructs a function that converts a throwable function into an `Either` diff --git a/src/either/utils/is.ts b/src/either/utils/is.ts index ca29222..17b02ee 100644 --- a/src/either/utils/is.ts +++ b/src/either/utils/is.ts @@ -1,4 +1,4 @@ -import { Either, Left, Right } from '../either' +import { Either, Left, Right } from '->/either' export const isLeft = ( v: Either, diff --git a/src/either/utils/merge.ts b/src/either/utils/merge.ts index b6cb5d0..fa0cf36 100644 --- a/src/either/utils/merge.ts +++ b/src/either/utils/merge.ts @@ -1,4 +1,4 @@ -import { Either, GetLeft, GetRight, right } from '../either' +import { Either, GetLeft, GetRight, right } from '->/either' export type GetRightFromArray< T extends Array>, diff --git a/src/either/utils/to-maybe.ts b/src/either/utils/to-maybe.ts index 4abd90e..929f32b 100644 --- a/src/either/utils/to-maybe.ts +++ b/src/either/utils/to-maybe.ts @@ -1,5 +1,5 @@ -import { Maybe, none, of } from '../../maybe' -import { Either } from '../either' +import { Maybe, none, of } from '->/maybe' +import { Either } from '->/either' /** * Converts a value from the Either monad to a Maybe monad. diff --git a/src/either/utils/try-catch.ts b/src/either/utils/try-catch.ts index 316d149..368d8c5 100644 --- a/src/either/utils/try-catch.ts +++ b/src/either/utils/try-catch.ts @@ -1,4 +1,4 @@ -import { Either, left, right } from '../either' +import { Either, left, right } from '->/either' /** * Executes a function in a try-catch block, returning either the result of the try function * or an error produced by the catch function. diff --git a/src/maybe/utils/from-throwable.ts b/src/maybe/utils/from-throwable.ts index 17531f5..5488663 100644 --- a/src/maybe/utils/from-throwable.ts +++ b/src/maybe/utils/from-throwable.ts @@ -1,4 +1,4 @@ -import { of, none } from '../maybe' +import { of, none } from '->/maybe' /** * Wraps a potentially throwing function in a Maybe monad. diff --git a/src/maybe/utils/from-undefined.ts b/src/maybe/utils/from-undefined.ts index dfc50d7..e8752a7 100644 --- a/src/maybe/utils/from-undefined.ts +++ b/src/maybe/utils/from-undefined.ts @@ -1,4 +1,4 @@ -import { of, Maybe } from '../maybe' +import { of, Maybe } from '->/maybe' /** * Converts a value that may be undefined to a Maybe monad. diff --git a/src/maybe/utils/merge-map.ts b/src/maybe/utils/merge-map.ts index 445b6cc..268458f 100644 --- a/src/maybe/utils/merge-map.ts +++ b/src/maybe/utils/merge-map.ts @@ -1,4 +1,4 @@ -import { Maybe } from '../maybe' +import { Maybe } from '->/maybe' /** * Merges two Maybe monads and applies a callback function to their values. diff --git a/src/maybe/utils/merge.ts b/src/maybe/utils/merge.ts index 99b49a4..38f6dc6 100644 --- a/src/maybe/utils/merge.ts +++ b/src/maybe/utils/merge.ts @@ -1,4 +1,4 @@ -import { Maybe, of, UnwrapMaybe } from '../maybe' +import { Maybe, of, UnwrapMaybe } from '->/maybe' /** * Extracts the type contained in an array of Maybe monads. diff --git a/src/maybe/utils/or.ts b/src/maybe/utils/or.ts index 709d1ca..488835e 100644 --- a/src/maybe/utils/or.ts +++ b/src/maybe/utils/or.ts @@ -1,4 +1,4 @@ -import { Maybe, of } from '../maybe' +import { Maybe, of } from '->/maybe' /** * Combines multiple Maybe monads into one, returning the first non-empty Maybe monad. diff --git a/src/observable/utils/merge.ts b/src/observable/utils/merge.ts index 1832681..3e45b9f 100644 --- a/src/observable/utils/merge.ts +++ b/src/observable/utils/merge.ts @@ -2,7 +2,7 @@ import { Observable, UnwrapObservable, of, -} from '../observable' +} from '->/observable' export type UnwrapObservableArray< T extends Array>, diff --git a/src/readerT/index.ts b/src/readerT/index.ts index b41cee8..11beef2 100644 --- a/src/readerT/index.ts +++ b/src/readerT/index.ts @@ -1,4 +1,4 @@ -import { E, M, S, I } from '../' +import { E, M, S, I } from '-->' export type Acceptable = | M.Maybe diff --git a/tsconfig.json b/tsconfig.json index 252d65d..5a69650 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,6 +12,9 @@ "paths": { "->/*": [ "./src/*" + ], + "-->": [ + "./src/index.ts" ] } }, From 74b821d95dfb01ced1e78fe56dac0be113f7e90d Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Fri, 22 Mar 2024 12:58:32 +0200 Subject: [PATCH 11/66] docs: update readme --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index a8fc5c0..87e60fb 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,20 @@ To install the latest version: `npm i @victorenokh/maybe.ts` +## Namespaces auto import +Install ts-namespace-import-plugin: +`npm i -D @unsplash/ts-namespace-import-plugin` + +Extend from namespaces tsconfig: +```json +// tsconfig.json +{ + "extends": "./node_modules/@victorenokh/maybe.ts/tsconfig.namespaces.json" +} +``` + +Use project typescript version in vscode press Ctrl + Shift + p then running **TypeScript: Select TypeScript Version** command, and selectin **Use Workspace Version** refering to [this](https://github.com/unsplash/ts-namespace-import-plugin/issues/12#issuecomment-1836965622) + # Examples - [Maybe](https://maybets.duckdns.org/examples/maybe.html) - [State](https://maybets.duckdns.org/examples/state.html) From e5e2fbdba4101b81e781c11c51f169466ea30db5 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Fri, 22 Mar 2024 13:46:10 +0200 Subject: [PATCH 12/66] feat: implement task either orElse method --- src/task-either/task-either.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/task-either/task-either.ts b/src/task-either/task-either.ts index 1e7bb68..9b5fd7a 100644 --- a/src/task-either/task-either.ts +++ b/src/task-either/task-either.ts @@ -1,4 +1,4 @@ -import { Either, isRight, left } from 'src/either' +import { Either, isRight, left } from '->/either' export interface TaskEither { map: (f: (v: Right) => R) => TaskEither @@ -9,6 +9,9 @@ export interface TaskEither { p: (v: Right) => boolean, fr: (v: Right) => Left, ) => TaskEither + orElse: ( + f: (e: Left) => TaskEither, + ) => TaskEither run: () => Promise> } @@ -41,5 +44,18 @@ export const of = ( of(() => task().then((either) => either.ensureOrElse(p, fr)), ), + orElse: ( + f: (e: Left) => TaskEither, + ): TaskEither => + of(() => + task().then( + (either) => + (isRight(either) + ? Promise.resolve(either) + : f(either.left).run()) as Promise< + Either + >, + ), + ), run: task, }) From 7480d8f5c3480b5c0ef12d4d5fb747d6245828a4 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Fri, 22 Mar 2024 16:14:33 +0200 Subject: [PATCH 13/66] feat: implement task either --- package.json | 7 ++++--- src/index.ts | 1 + src/task-maybe/index.ts | 1 + src/task-maybe/task-maybe.ts | 13 +++++++++++++ src/types/lazy.ts | 7 +++++++ tsconfig.json | 3 +++ 6 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 src/task-maybe/index.ts create mode 100644 src/task-maybe/task-maybe.ts create mode 100644 src/types/lazy.ts diff --git a/package.json b/package.json index 2349815..7c11bb2 100644 --- a/package.json +++ b/package.json @@ -72,9 +72,10 @@ "require": "./dist/task-either/index.js", "types": "./dist/task-either/index.d.ts" }, - "./namespaces": { - "import": "./tsconfig.namespaces.json", - "require": "./tsconfig.namespaces.json" + "./task-maybe": { + "import": "./dist/task-maybe/index.mjs", + "require": "./dist/task-maybe/index.js", + "types": "./dist/task-maybe/index.d.ts" } }, "repository": { diff --git a/src/index.ts b/src/index.ts index 6d198db..44688a0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,3 +8,4 @@ export * as I from './identity' export * as L from './lens' export * as T from './task' export * as TE from './task-either' +export * as TM from './task-maybe' diff --git a/src/task-maybe/index.ts b/src/task-maybe/index.ts new file mode 100644 index 0000000..558cbf9 --- /dev/null +++ b/src/task-maybe/index.ts @@ -0,0 +1 @@ +export * from './task-maybe' diff --git a/src/task-maybe/task-maybe.ts b/src/task-maybe/task-maybe.ts new file mode 100644 index 0000000..b6e96ee --- /dev/null +++ b/src/task-maybe/task-maybe.ts @@ -0,0 +1,13 @@ +import { Maybe } from '->/maybe' +import { Lazy } from '->t/lazy' +import { M } from '-->' + +interface TaskMaybe { + run: () => Promise> +} + +export const of = ( + run: Lazy>, +): TaskMaybe => ({ + run: () => run().then(M.of), +}) diff --git a/src/types/lazy.ts b/src/types/lazy.ts new file mode 100644 index 0000000..54d6a2f --- /dev/null +++ b/src/types/lazy.ts @@ -0,0 +1,7 @@ +/** + * lazy argument + * usage in `Task`, `State` + */ +export interface Lazy { + (): T +} diff --git a/tsconfig.json b/tsconfig.json index 5a69650..3281001 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,6 +15,9 @@ ], "-->": [ "./src/index.ts" + ], + "->t/*": [ + "./src/types/*" ] } }, From 9cd9533e2501d41f56dcd4353ced83691e33d1be Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Fri, 22 Mar 2024 16:36:59 +0200 Subject: [PATCH 14/66] feat: add import sort prettier plugin --- .prettierrc | 12 ++- package-lock.json | 131 ++++++++++++++++++++++++++++++ package.json | 1 + src/either/either.ts | 2 +- src/either/utils/from-maybe.ts | 2 +- src/either/utils/to-maybe.ts | 2 +- src/either/utils/try-catch.ts | 1 + src/identity/identity.ts | 2 +- src/maybe/utils/from-throwable.ts | 2 +- src/maybe/utils/from-undefined.ts | 2 +- src/maybe/utils/merge.ts | 2 +- src/readerT/index.ts | 2 +- src/task-either/task-either.ts | 3 +- src/task-maybe/task-maybe.ts | 4 +- src/types/lazy.ts | 4 +- 15 files changed, 158 insertions(+), 14 deletions(-) diff --git a/.prettierrc b/.prettierrc index ab59514..ccd6800 100644 --- a/.prettierrc +++ b/.prettierrc @@ -4,5 +4,15 @@ "tabWidth": 2, "singleQuote": true, "printWidth": 60, - "bracketSpacing": true + "bracketSpacing": true, + "importOrder": [ + "^-->$", + "^->t/(.*)$", + "^->/(.*)$", + "^[./]" + ], + "importOrderSortSpecifiers": true, + "plugins": [ + "@trivago/prettier-plugin-sort-imports" + ] } diff --git a/package-lock.json b/package-lock.json index 7becb58..82cfb79 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@changesets/cli": "^2.27.1", "@commitlint/cli": "^19.0.3", "@commitlint/config-conventional": "^19.0.3", + "@trivago/prettier-plugin-sort-imports": "^4.3.0", "@types/jest": "^29.5.12", "@typescript-eslint/eslint-plugin": "^7.0.1", "@typescript-eslint/parser": "^7.0.1", @@ -2933,6 +2934,124 @@ "@sinonjs/commons": "^3.0.0" } }, + "node_modules/@trivago/prettier-plugin-sort-imports": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@trivago/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-4.3.0.tgz", + "integrity": "sha512-r3n0onD3BTOVUNPhR4lhVK4/pABGpbA7bW3eumZnYdKaHkf1qEC+Mag6DPbGNuuh0eG8AaYj+YqmVHSiGslaTQ==", + "dev": true, + "dependencies": { + "@babel/generator": "7.17.7", + "@babel/parser": "^7.20.5", + "@babel/traverse": "7.23.2", + "@babel/types": "7.17.0", + "javascript-natural-sort": "0.7.1", + "lodash": "^4.17.21" + }, + "peerDependencies": { + "@vue/compiler-sfc": "3.x", + "prettier": "2.x - 3.x" + }, + "peerDependenciesMeta": { + "@vue/compiler-sfc": { + "optional": true + } + } + }, + "node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/generator": { + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.7.tgz", + "integrity": "sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.17.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/traverse": { + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/traverse/node_modules/@babel/generator": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.1.tgz", + "integrity": "sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/traverse/node_modules/@babel/types": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", + "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@trivago/prettier-plugin-sort-imports/node_modules/@babel/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@trivago/prettier-plugin-sort-imports/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@trivago/prettier-plugin-sort-imports/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", @@ -6505,6 +6624,12 @@ "node": ">=8" } }, + "node_modules/javascript-natural-sort": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", + "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==", + "dev": true + }, "node_modules/jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", @@ -8497,6 +8622,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, "node_modules/lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", diff --git a/package.json b/package.json index 7c11bb2..bcedeb7 100644 --- a/package.json +++ b/package.json @@ -111,6 +111,7 @@ "@changesets/cli": "^2.27.1", "@commitlint/cli": "^19.0.3", "@commitlint/config-conventional": "^19.0.3", + "@trivago/prettier-plugin-sort-imports": "^4.3.0", "@types/jest": "^29.5.12", "@typescript-eslint/eslint-plugin": "^7.0.1", "@typescript-eslint/parser": "^7.0.1", diff --git a/src/either/either.ts b/src/either/either.ts index 4cfad8c..3c5dcc6 100644 --- a/src/either/either.ts +++ b/src/either/either.ts @@ -1,4 +1,4 @@ -import { Merged } from 'src/types/merged' +import { Merged } from '->t/merged' export type FoldFunction = ( lfn: (e: Left) => R, diff --git a/src/either/utils/from-maybe.ts b/src/either/utils/from-maybe.ts index 5e52b58..c3c3b05 100644 --- a/src/either/utils/from-maybe.ts +++ b/src/either/utils/from-maybe.ts @@ -1,5 +1,5 @@ -import { Maybe } from '->/maybe' import { Either, left, right } from '->/either' +import { Maybe } from '->/maybe' /** * Converts a value from the Maybe monad to an Either monad. diff --git a/src/either/utils/to-maybe.ts b/src/either/utils/to-maybe.ts index 929f32b..c8dc7b2 100644 --- a/src/either/utils/to-maybe.ts +++ b/src/either/utils/to-maybe.ts @@ -1,5 +1,5 @@ -import { Maybe, none, of } from '->/maybe' import { Either } from '->/either' +import { Maybe, none, of } from '->/maybe' /** * Converts a value from the Either monad to a Maybe monad. diff --git a/src/either/utils/try-catch.ts b/src/either/utils/try-catch.ts index 368d8c5..588bc05 100644 --- a/src/either/utils/try-catch.ts +++ b/src/either/utils/try-catch.ts @@ -1,4 +1,5 @@ import { Either, left, right } from '->/either' + /** * Executes a function in a try-catch block, returning either the result of the try function * or an error produced by the catch function. diff --git a/src/identity/identity.ts b/src/identity/identity.ts index ac065f6..1791092 100644 --- a/src/identity/identity.ts +++ b/src/identity/identity.ts @@ -1,4 +1,4 @@ -import { Merged } from 'src/types/merged' +import { Merged } from '->t/merged' export interface Identity { map: (f: (v: T) => R) => Identity diff --git a/src/maybe/utils/from-throwable.ts b/src/maybe/utils/from-throwable.ts index 5488663..2749af1 100644 --- a/src/maybe/utils/from-throwable.ts +++ b/src/maybe/utils/from-throwable.ts @@ -1,4 +1,4 @@ -import { of, none } from '->/maybe' +import { none, of } from '->/maybe' /** * Wraps a potentially throwing function in a Maybe monad. diff --git a/src/maybe/utils/from-undefined.ts b/src/maybe/utils/from-undefined.ts index e8752a7..b4e850d 100644 --- a/src/maybe/utils/from-undefined.ts +++ b/src/maybe/utils/from-undefined.ts @@ -1,4 +1,4 @@ -import { of, Maybe } from '->/maybe' +import { Maybe, of } from '->/maybe' /** * Converts a value that may be undefined to a Maybe monad. diff --git a/src/maybe/utils/merge.ts b/src/maybe/utils/merge.ts index 38f6dc6..bf8282a 100644 --- a/src/maybe/utils/merge.ts +++ b/src/maybe/utils/merge.ts @@ -1,4 +1,4 @@ -import { Maybe, of, UnwrapMaybe } from '->/maybe' +import { Maybe, UnwrapMaybe, of } from '->/maybe' /** * Extracts the type contained in an array of Maybe monads. diff --git a/src/readerT/index.ts b/src/readerT/index.ts index 11beef2..a207615 100644 --- a/src/readerT/index.ts +++ b/src/readerT/index.ts @@ -1,4 +1,4 @@ -import { E, M, S, I } from '-->' +import { E, I, M, S } from '-->' export type Acceptable = | M.Maybe diff --git a/src/task-either/task-either.ts b/src/task-either/task-either.ts index 9b5fd7a..cae15b5 100644 --- a/src/task-either/task-either.ts +++ b/src/task-either/task-either.ts @@ -1,3 +1,4 @@ +import { Lazy } from '->t/lazy' import { Either, isRight, left } from '->/either' export interface TaskEither { @@ -23,7 +24,7 @@ export interface TaskEither { * @returns {TaskEither} - new TaskEither */ export const of = ( - task: () => Promise>, + task: Lazy>>, ): TaskEither => ({ map: (f: (v: Right) => R): TaskEither => of(() => task().then((either) => either.map(f))), diff --git a/src/task-maybe/task-maybe.ts b/src/task-maybe/task-maybe.ts index b6e96ee..ab12d92 100644 --- a/src/task-maybe/task-maybe.ts +++ b/src/task-maybe/task-maybe.ts @@ -1,6 +1,6 @@ -import { Maybe } from '->/maybe' -import { Lazy } from '->t/lazy' import { M } from '-->' +import { Lazy } from '->t/lazy' +import { Maybe } from '->/maybe' interface TaskMaybe { run: () => Promise> diff --git a/src/types/lazy.ts b/src/types/lazy.ts index 54d6a2f..b404fef 100644 --- a/src/types/lazy.ts +++ b/src/types/lazy.ts @@ -1,6 +1,6 @@ /** - * lazy argument - * usage in `Task`, `State` + * Lazy argument + * @template T - Type of lazy argument */ export interface Lazy { (): T From 3ca946e23b6e5f13b228291282d568da79148f5a Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Sat, 23 Mar 2024 12:46:56 +0200 Subject: [PATCH 15/66] feat: add .editorconfig --- .editorconfig | 7 +++++++ package.json | 1 + 2 files changed, 8 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..7ed0206 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,7 @@ +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 diff --git a/package.json b/package.json index bcedeb7..b596dcc 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "lint": "eslint src", "lint-fix": "eslint src --fix" }, + "sideEffects": false, "exports": { ".": { "import": "./dist/index.mjs", From 93a2ff9fe330abe13abef3275e3c6c61e865c4ee Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Sat, 23 Mar 2024 15:31:24 +0200 Subject: [PATCH 16/66] feat: add Either#mapLeft method --- src/either/either.ts | 48 ++++++++++++++++++-------------------------- 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/src/either/either.ts b/src/either/either.ts index 3c5dcc6..6ea9e2b 100644 --- a/src/either/either.ts +++ b/src/either/either.ts @@ -9,6 +9,10 @@ export type MapFunction = ( fn: (v: Right) => R, ) => Either +export type MapLeft = ( + f: (v: Left) => R, +) => Either + export type FlatMapFunction = ( fn: (v: Right) => Either, ) => Either @@ -62,10 +66,18 @@ export interface Left { /** * Maps a function over the right value. * @template U - The type of the result of the mapping function. + * @param {Function} fn - The function to map over the right value. + * @returns {Left} - A new Left containing the result of applying `fn` to the right value. + */ + map: MapFunction + + /** + * Maps a function over the left value. + * @template U - The type of the result of the mapping function. * @param {Function} fn - The function to map over the left value. * @returns {Left} - A new Left containing the result of applying `fn` to the left value. */ - map: MapFunction + mapLeft: MapLeft /** * Maps a function over the right value and flattens the result. @@ -118,39 +130,14 @@ export interface Right { fold: FoldFunction - /** - * Maps a function over the right value. - * @template U - The type of the result of the mapping function. - * @param {Function} fn - The function to map over the right value. - * @returns {Right} - A new Right containing the result of applying `fn` to the right value. - */ map: MapFunction - /** - * Maps a function over the right value and flattens the result. - * @template U - The type of the result of the mapping function. - * @param {Function} fn - The function to map over the right value. - * @returns {Right} - A new Right containing the flattened result of applying `fn` to the right value. - */ + mapLeft: MapLeft + flatMap: FlatMapFunction - /** - * Ensures that a predicate `fn` holds true for the success value. - * If the predicate fails, returns an alternative failure value computed by `fr`. - * This method is applicable when the `Either` instance represents a success value. - * @template Re The type of the alternative failure value returned if the predicate fails. - * @param {function(R): boolean} fn The predicate function to be satisfied by the success value. - * @param {function(R): Re} fr The function to compute an alternative failure value if the predicate fails. - * @returns {Either} An `Either` instance with the same failure type `L` but potentially different success type. - */ ensureOrElse: EnsureOrElseFunction - /** - * Merges two Either monads into one, combining their values if both are Right, or returning the first Left value otherwise. - * @template Nr The type of the value in the second Either monad. - * @param {Either} or The Either monad to merge. - * @returns {Either>} An Either monad representing the merged result. - */ merge: MergeFunction } @@ -177,6 +164,9 @@ export const left = (e: L): Either => ({ map: (_: (v: R) => Re) => left(e), + mapLeft: (f: (v: L) => Re): Either => + left(f(e)), + asyncMap: (_: (v: R) => Promise) => Promise.resolve>(left(e)), @@ -212,6 +202,8 @@ export const right = ( map: (fn: (v: R) => Re) => right(fn(v)), + mapLeft: (_: (v: L) => Re): Either => right(v), + asyncMap: ( fn: (v: R) => Promise, ): Promise> => From a66a5c1f4753cd0a879b0de07ae0caf7b4851aed Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Sat, 23 Mar 2024 22:31:22 +0200 Subject: [PATCH 17/66] feat: implement TaskEither#mapLeft method --- src/task-either/task-either.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/task-either/task-either.ts b/src/task-either/task-either.ts index cae15b5..54b58a7 100644 --- a/src/task-either/task-either.ts +++ b/src/task-either/task-either.ts @@ -14,6 +14,7 @@ export interface TaskEither { f: (e: Left) => TaskEither, ) => TaskEither run: () => Promise> + mapLeft: (f: (v: Left) => R) => TaskEither } /** @@ -58,5 +59,7 @@ export const of = ( >, ), ), + mapLeft: (f: (v: Left) => R): TaskEither => + of(() => task().then((either) => either.mapLeft(f))), run: task, }) From 4a7a3aff6d38e39096df2f962b1be2227ee13c31 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Sun, 24 Mar 2024 22:47:26 +0200 Subject: [PATCH 18/66] feat: implement TaskEither#fold method --- examples/observable.md | 4 ++-- src/either/utils/try-catch.ts | 3 --- src/task-either/task-either.ts | 11 ++++++++++- src/task-either/utils/try-catch.ts | 2 +- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/examples/observable.md b/examples/observable.md index 1a352c3..9f209aa 100644 --- a/examples/observable.md +++ b/examples/observable.md @@ -3,13 +3,13 @@ ## .map() ```ts const observable = O.of(42) -observable.map((num) => num.toString()).observe(console.log()) // Output: "42" +observable.map((num) => num.toString()).observe(console.log) // Output: "42" ``` ## .flatMap() ```ts const observable = O.of(42) -observable.flatMap(num => O.of(num + 1)).observe(console.log()) // Output: 43 +observable.flatMap(num => O.of(num + 1)).observe(console.log) // Output: 43 ``` diff --git a/src/either/utils/try-catch.ts b/src/either/utils/try-catch.ts index 588bc05..b185984 100644 --- a/src/either/utils/try-catch.ts +++ b/src/either/utils/try-catch.ts @@ -14,13 +14,10 @@ import { Either, left, right } from '->/either' export const tryCatch = ( tryFn: () => T, catchFn: (reason: unknown) => E, - finallyFn?: () => void, ): Either => { try { return right(tryFn()) } catch (e) { return left(catchFn(e)) - } finally { - finallyFn?.() } } diff --git a/src/task-either/task-either.ts b/src/task-either/task-either.ts index 54b58a7..95d418d 100644 --- a/src/task-either/task-either.ts +++ b/src/task-either/task-either.ts @@ -1,5 +1,5 @@ import { Lazy } from '->t/lazy' -import { Either, isRight, left } from '->/either' +import { Either, isRight, left, right } from '->/either' export interface TaskEither { map: (f: (v: Right) => R) => TaskEither @@ -15,6 +15,10 @@ export interface TaskEither { ) => TaskEither run: () => Promise> mapLeft: (f: (v: Left) => R) => TaskEither + fold: ( + onLeft: (e: Left) => Promise | R, + onRight: (v: Right) => Promise | R, + ) => Promise } /** @@ -61,5 +65,10 @@ export const of = ( ), mapLeft: (f: (v: Left) => R): TaskEither => of(() => task().then((either) => either.mapLeft(f))), + fold: ( + onLeft: (v: Left) => Promise | R, + onRight: (v: Right) => Promise | R, + ): Promise => + task().then((either) => either.fold(onLeft, onRight)), run: task, }) diff --git a/src/task-either/utils/try-catch.ts b/src/task-either/utils/try-catch.ts index 2cdf8d5..9c771ca 100644 --- a/src/task-either/utils/try-catch.ts +++ b/src/task-either/utils/try-catch.ts @@ -7,7 +7,7 @@ export const tryCatch = ( ): TaskEither => of(async () => { try { - return right(await tryFn()) + return tryFn().then(right) } catch (e) { return left(catchFn(e)) } From 6a48083b12b55fb53018e45ae20290bad29a2595 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Mon, 25 Mar 2024 13:56:46 +0200 Subject: [PATCH 19/66] fix: incorrect email in package.json --- jest.config.ts | 5 +++++ package.json | 2 +- src/task-either/task-either.ts | 2 +- tests/either.test.ts | 22 ++++++---------------- 4 files changed, 13 insertions(+), 18 deletions(-) diff --git a/jest.config.ts b/jest.config.ts index 9590e24..4fbf127 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -4,5 +4,10 @@ const config: Config.InitialOptions = { preset: 'ts-jest', verbose: true, testEnvironment: 'node', + moduleNameMapper: { + '->/(.*)': '/src/$1', + '-->': '/src/index.ts', + '->t/(.*)': '', + }, } export default config diff --git a/package.json b/package.json index b596dcc..3fd9fea 100644 --- a/package.json +++ b/package.json @@ -103,7 +103,7 @@ "prisms", "tasks" ], - "author": "Victor Enokh Kuptsov ", + "author": "Victor Enokh Kuptsov ", "publishConfig": { "access": "public" }, diff --git a/src/task-either/task-either.ts b/src/task-either/task-either.ts index 95d418d..7a62561 100644 --- a/src/task-either/task-either.ts +++ b/src/task-either/task-either.ts @@ -1,5 +1,5 @@ import { Lazy } from '->t/lazy' -import { Either, isRight, left, right } from '->/either' +import { Either, isRight, left } from '->/either' export interface TaskEither { map: (f: (v: Right) => R) => TaskEither diff --git a/tests/either.test.ts b/tests/either.test.ts index fb4de12..ba06c0f 100644 --- a/tests/either.test.ts +++ b/tests/either.test.ts @@ -1,5 +1,5 @@ import { E, M } from '../src' -import { Either, tryCatch } from '../src/either' +import { tryCatch } from '../src/either' const dontCallMePls = () => { throw new Error('should not be called') @@ -338,15 +338,9 @@ describe('either.ts', () => { throw new Error('Error') }) - const finalyFn = jest.fn() - - tryCatch( - tryFn, - () => { - dontCallMePls() - }, - finalyFn, - ).fold( + tryCatch(tryFn, () => { + dontCallMePls() + }).fold( () => dontCallMePls(), (num) => { expect(num).toBe(20) @@ -354,16 +348,12 @@ describe('either.ts', () => { ) expect(tryFn).toHaveBeenCalled() - expect(finalyFn).toHaveBeenCalled() - tryCatch( - throwableTryFn, - (reason) => String(reason), - finalyFn, + tryCatch(throwableTryFn, (reason) => + String(reason), ).fold( (e) => expect(e).toBe('Error: Error'), dontCallMePls, ) - expect(finalyFn).toHaveBeenCalledTimes(2) }) }) From 215ff609258ba23ad7a00cead4699e4ef3d6b266 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Mon, 25 Mar 2024 16:38:32 +0200 Subject: [PATCH 20/66] feat: implement TaskMaybe#map & TaskMaybe#flatMap methods --- src/functions/pipe.ts | 35 +++++++++++++++++++++++++++++++++++ src/task-maybe/task-maybe.ts | 20 ++++++++++++++++---- 2 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 src/functions/pipe.ts diff --git a/src/functions/pipe.ts b/src/functions/pipe.ts new file mode 100644 index 0000000..53d2d14 --- /dev/null +++ b/src/functions/pipe.ts @@ -0,0 +1,35 @@ +type AnyFunction = (...args: any[]) => any + +type PipeArgs< + F extends AnyFunction[], + Acc extends AnyFunction[] = [], +> = F extends [(...args: infer A) => infer B] + ? [...Acc, (...args: A) => B] + : F extends [(...args: infer A) => any, ...infer Tail] + ? Tail extends [(arg: infer B) => any, ...any[]] + ? PipeArgs B]> + : Acc + : Acc + +type LastFnReturnType< + F extends AnyFunction[], + R, +> = F extends [] + ? R + : F extends [...infer Rest, (arg: R) => infer Last] + ? LastFnReturnType< + Rest extends AnyFunction[] ? Rest : [], + Last + > + : never + +export function pipe( + arg: Parameters[0], + ...fns: PipeArgs extends F ? F : PipeArgs +): LastFnReturnType> { + return (fns.slice(1) as AnyFunction[]).reduce( + (acc, fn) => fn(acc), + fns[0]?.(arg), + ) +} +const add = (num: number) => (toAdd: number) => num + toAdd diff --git a/src/task-maybe/task-maybe.ts b/src/task-maybe/task-maybe.ts index ab12d92..9305e50 100644 --- a/src/task-maybe/task-maybe.ts +++ b/src/task-maybe/task-maybe.ts @@ -1,13 +1,25 @@ import { M } from '-->' import { Lazy } from '->t/lazy' -import { Maybe } from '->/maybe' +import { none } from '->/maybe' interface TaskMaybe { - run: () => Promise> + run: () => Promise> + map: (f: (v: T) => R) => TaskMaybe + flatMap: (f: (v: T) => TaskMaybe) => TaskMaybe } export const of = ( - run: Lazy>, + run: Lazy>>, ): TaskMaybe => ({ - run: () => run().then(M.of), + run: run, + map: (f: (v: T) => R): TaskMaybe => + of(() => run().then((value) => value.map(f))), + flatMap: (f: (v: T) => TaskMaybe): TaskMaybe => + of(() => + run().then((maybe) => + maybe.value !== null + ? f(maybe.value).run() + : none(), + ), + ), }) From 04f2b1a3592501f368d485ba0e67d7ac6df14894 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Wed, 27 Mar 2024 15:13:54 +0200 Subject: [PATCH 21/66] fix: incorrect either path --- src/task-either/utils/try-catch.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/task-either/utils/try-catch.ts b/src/task-either/utils/try-catch.ts index 9c771ca..9239916 100644 --- a/src/task-either/utils/try-catch.ts +++ b/src/task-either/utils/try-catch.ts @@ -1,4 +1,4 @@ -import { left, right } from 'src/either' +import { left, right } from '->/either' import { TaskEither, of } from '..' export const tryCatch = ( From 9ac925e65c133932774611952bcb7df59bdf45be Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Wed, 27 Mar 2024 23:46:53 +0200 Subject: [PATCH 22/66] docs: add task-either docs --- README.md | 1 + examples/task-either.md | 29 +++++++++++++++++++++++++++++ src/functions/pipe.ts | 1 - 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 examples/task-either.md diff --git a/README.md b/README.md index 87e60fb..8857def 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ Use project typescript version in vscode press Ctrl + Shift { + if (!res.ok) { + throw new Error(res.statusText) + } + + return res.text() +} + +const fetchString = (url: string) => + tryCatch(() => fetch(url).then(parseOrThrow), toError) + +fetchString('https://example.com').fold( + console.error, + console.log, +) // Output: html string of example.com site +fetchString('https://example.com/non/existing/path').fold( + console.error, + console.log, +) // Ouput: Error: internal server error +``` diff --git a/src/functions/pipe.ts b/src/functions/pipe.ts index 53d2d14..ac86e6b 100644 --- a/src/functions/pipe.ts +++ b/src/functions/pipe.ts @@ -32,4 +32,3 @@ export function pipe( fns[0]?.(arg), ) } -const add = (num: number) => (toAdd: number) => num + toAdd From 847501c8db5dceb338d9be04c008c3ac7254a304 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Thu, 28 Mar 2024 19:28:17 +0200 Subject: [PATCH 23/66] feat: add Task#map test --- tests/task.test.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 tests/task.test.ts diff --git a/tests/task.test.ts b/tests/task.test.ts new file mode 100644 index 0000000..1b5cdce --- /dev/null +++ b/tests/task.test.ts @@ -0,0 +1,17 @@ +import { of } from '../src/task' + +describe('task.ts', () => { + it('map', async () => { + const task = of(() => Promise.resolve(40)) + + task.map((num) => num * 2) + + const result = await task.run() + + expect(result).toBe(80) + }) + + it('flatMap', () => {}) + + it('delay', () => {}) +}) From 6cbb787af288cc93d6be9d48d354fd60d6069f96 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Thu, 28 Mar 2024 20:12:34 +0200 Subject: [PATCH 24/66] fix: incorrect usage of map method in tests --- tests/task.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/task.test.ts b/tests/task.test.ts index 1b5cdce..7434715 100644 --- a/tests/task.test.ts +++ b/tests/task.test.ts @@ -2,9 +2,9 @@ import { of } from '../src/task' describe('task.ts', () => { it('map', async () => { - const task = of(() => Promise.resolve(40)) - - task.map((num) => num * 2) + const task = of(() => Promise.resolve(40)).map( + (num) => num * 2, + ) const result = await task.run() From cec30e142d6e6884171eb13777f1cdf4ffb1f3f3 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Thu, 28 Mar 2024 21:56:27 +0200 Subject: [PATCH 25/66] feat: add Task#flatMap & Task#delay methods tests --- tests/task.test.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/tests/task.test.ts b/tests/task.test.ts index 7434715..edfec20 100644 --- a/tests/task.test.ts +++ b/tests/task.test.ts @@ -11,7 +11,20 @@ describe('task.ts', () => { expect(result).toBe(80) }) - it('flatMap', () => {}) + it('flatMap', async () => { + const task = of(() => Promise.resolve(50)) + const otherTask = of(() => Promise.resolve(60)) - it('delay', () => {}) + const taskInTask = task.flatMap(() => otherTask) + + const runned = await taskInTask.run() + + expect(runned).toBe(60) + }) + + it('delay', () => { + const a = of(() => Promise.resolve(40)).delay(10) + + expect(a).toBe(40) + }) }) From 9363b6a435d684f821266059aaafb0935576a8de Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Thu, 28 Mar 2024 22:14:12 +0200 Subject: [PATCH 26/66] feat: add TaskEither#map test --- tests/task-either.test.ts | 40 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 tests/task-either.test.ts diff --git a/tests/task-either.test.ts b/tests/task-either.test.ts new file mode 100644 index 0000000..f381561 --- /dev/null +++ b/tests/task-either.test.ts @@ -0,0 +1,40 @@ +import { left, right } from '../src/either' +import { of } from '../src/task-either' + +const shouldNotBeCalled = () => { + throw new Error('should not be called') +} + +describe('task-either.ts', () => { + it('map', async () => { + const mapFn = jest.fn((num: number) => num * 2) + + const task = of(() => Promise.resolve(right(40))).map( + mapFn, + ) + + const taskWithRight = of(() => + Promise.resolve(left('some error')), + ).map(mapFn) + + const onRightFn = jest.fn((num: number) => { + expect(num).toBe(80) + }) + + const onLeftFn = jest.fn((e: string) => { + expect(e).toBe('some error') + }) + + task.fold(shouldNotBeCalled, onRightFn).then(() => { + expect(onRightFn).toHaveBeenCalled() + expect(mapFn).toHaveBeenCalled() + }) + + taskWithRight + .fold(onLeftFn, shouldNotBeCalled) + .then(() => { + expect(onLeftFn).toHaveBeenCalled() + expect(mapFn).toHaveBeenCalledTimes(1) + }) + }) +}) From add208e091b7ec00f3ca9ed762653176719f959f Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Thu, 28 Mar 2024 22:17:40 +0200 Subject: [PATCH 27/66] fix: task#delay test --- tests/task.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/task.test.ts b/tests/task.test.ts index edfec20..ee9e47d 100644 --- a/tests/task.test.ts +++ b/tests/task.test.ts @@ -22,9 +22,9 @@ describe('task.ts', () => { expect(runned).toBe(60) }) - it('delay', () => { + it('delay', async () => { const a = of(() => Promise.resolve(40)).delay(10) - expect(a).toBe(40) + expect(await a.run()).toBe(40) }) }) From e5403f1f549fd07c9d667dba2c40850ea1e3a4a8 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Fri, 29 Mar 2024 14:48:06 +0200 Subject: [PATCH 28/66] feat: add Either#mapLeft test, add vim folds to tests for better navigation --- tests/either.test.ts | 77 +++++++++++++++++++++++++++++++-------- tests/task-either.test.ts | 5 +++ 2 files changed, 67 insertions(+), 15 deletions(-) diff --git a/tests/either.test.ts b/tests/either.test.ts index ba06c0f..cc30275 100644 --- a/tests/either.test.ts +++ b/tests/either.test.ts @@ -1,6 +1,7 @@ import { E, M } from '../src' import { tryCatch } from '../src/either' +// {{{ Functions that helps with tests const dontCallMePls = () => { throw new Error('should not be called') } @@ -43,8 +44,10 @@ const throwable = (num: number) => { return num / 2 } +// }}} describe('either.ts', () => { + // {{{ fold it('fold', () => { const nums = [0, 2] as const @@ -63,7 +66,8 @@ describe('either.ts', () => { expect(onLeft).toHaveBeenCalled() expect(onRight).not.toHaveBeenCalled() }) - + // }}} + // {{{ fromThrowable it('fromThrowable', () => { const wrapped = E.fromThrowable(throwable) @@ -82,7 +86,8 @@ describe('either.ts', () => { expect(onLeft).toHaveBeenCalledTimes(1) expect(onRight).toHaveBeenCalled() }) - + // }}} + // {{{ map it('map', () => { const mapFn = jest.fn((number: number) => number + 1) @@ -107,7 +112,8 @@ describe('either.ts', () => { expect(left).toHaveBeenCalled() expect(right).toHaveBeenCalledTimes(1) }) - + // }}} + // {{{ flatMap it('flatMap', () => { const flatMapFn = jest.fn( (number: number): E.Either => { @@ -139,8 +145,9 @@ describe('either.ts', () => { eitherExample(0, 2).flatMap(flatMapFn) expect(flatMapFn).toHaveBeenCalledTimes(2) }) - - it('ensureOrelse', () => { + // }}} + // {{{ ensureOrElse + it('ensureOrElse', () => { validateUser({ has2Fa: true, name: '1234' }).fold( () => { throw new Error('should not be called') @@ -171,7 +178,8 @@ describe('either.ts', () => { }, ) }) - + // }}} + // {{{ fromMaybe it('fromMaybe', () => { E.fromMaybe(M.of(42), '!').fold( () => { @@ -187,7 +195,8 @@ describe('either.ts', () => { }, ) }) - + // }}} + // {{{ toMaybe it('toMaybe', () => { const eitherRight: E.Either = E.right(5) const eitherLeft: E.Either = @@ -198,7 +207,8 @@ describe('either.ts', () => { ) expect(E.toMaybe(eitherLeft).value).toBeNull() }) - + // }}} + // {{{ merge it('merge', () => { const a: E.Either = E.right(5) const b: E.Either = E.right('Hello') @@ -228,7 +238,8 @@ describe('either.ts', () => { }, ) }) - + // }}} + // {{{ merge util it('merge util', () => { const merged = E.merge[]>( E.right(4), @@ -245,7 +256,8 @@ describe('either.ts', () => { }, ) }) - + // }}} + // {{{ isLeft it('isLeft', () => { const right: E.Either = E.right('hello') const left: E.Either = E.left('bye') @@ -253,7 +265,8 @@ describe('either.ts', () => { expect(right.isLeft()).not.toBeTruthy() expect(left.isLeft()).toBeTruthy() }) - + // }}} + // {{{ isRight it('isRight', () => { const right: E.Either = E.right('hello') const left: E.Either = E.left('bye') @@ -261,7 +274,8 @@ describe('either.ts', () => { expect(right.isRight()).toBeTruthy() expect(left.isRight()).not.toBeTruthy() }) - + // }}} + // {{{ orElse it('orElse', () => { const a: E.Either = E.right('k').orElse( () => E.left('test'), @@ -287,7 +301,8 @@ describe('either.ts', () => { }, ) }) - + // }}} + // {{{ asyncMap it('asyncMap', async () => { const sleep = (ms: number): Promise => new Promise((res) => setTimeout(() => res(ms), ms)) @@ -319,7 +334,8 @@ describe('either.ts', () => { (n) => expect(n).toBe(50), ) }) - + // }}} + // {{{ of it('of', () => { E.of(42).fold( () => { @@ -328,7 +344,8 @@ describe('either.ts', () => { (n) => expect(n).toBe(42), ) }) - + // }}} + // {{{ tryCatch it('tryCatch', () => { const tryFn = jest.fn(() => { return 20 @@ -356,4 +373,34 @@ describe('either.ts', () => { dontCallMePls, ) }) + // }}} + // {{{ mapLeft + it('mapLeft', () => { + const mapFn = jest.fn((string: string) => + string.repeat(1), + ) + + const right = E.right(40).mapLeft(mapFn) + + expect(mapFn).not.toHaveBeenCalled() + + const left = E.left('some string').mapLeft(mapFn) + + expect(mapFn).toHaveBeenCalled() + + const onLeftFn = jest.fn((str: string) => + expect(str).toBe('some stringsome string'), + ) + + const onRightFn = jest.fn((num: number) => + expect(num).toBe(42), + ) + + left.fold(onLeftFn, dontCallMePls) + right.fold(dontCallMePls, onRightFn) + + expect(onLeftFn).toHaveBeenCalled() + expect(onRightFn).toHaveBeenCalled() + }) + // }}} }) diff --git a/tests/task-either.test.ts b/tests/task-either.test.ts index f381561..dcd18c5 100644 --- a/tests/task-either.test.ts +++ b/tests/task-either.test.ts @@ -6,6 +6,7 @@ const shouldNotBeCalled = () => { } describe('task-either.ts', () => { + // {{{ map test it('map', async () => { const mapFn = jest.fn((num: number) => num * 2) @@ -37,4 +38,8 @@ describe('task-either.ts', () => { expect(mapFn).toHaveBeenCalledTimes(1) }) }) + // }}} + // {{{ flatMap test + it('flatMap', () => {}) + // }}} }) From 9002fe4b7bba7951438bab01f3b6afe4176f01e0 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Fri, 29 Mar 2024 14:50:03 +0200 Subject: [PATCH 29/66] fix: string.repeat(1) in Either#mapLeft test --- tests/either.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/either.test.ts b/tests/either.test.ts index cc30275..84c093e 100644 --- a/tests/either.test.ts +++ b/tests/either.test.ts @@ -377,7 +377,7 @@ describe('either.ts', () => { // {{{ mapLeft it('mapLeft', () => { const mapFn = jest.fn((string: string) => - string.repeat(1), + string.repeat(2), ) const right = E.right(40).mapLeft(mapFn) From 253404380d7b0acddf70cb00ee88a72ce7579773 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Fri, 29 Mar 2024 14:51:49 +0200 Subject: [PATCH 30/66] fix: incorrect number was passed in .toBe() in Either#mapLeft test --- tests/either.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/either.test.ts b/tests/either.test.ts index 84c093e..8fee5af 100644 --- a/tests/either.test.ts +++ b/tests/either.test.ts @@ -393,7 +393,7 @@ describe('either.ts', () => { ) const onRightFn = jest.fn((num: number) => - expect(num).toBe(42), + expect(num).toBe(40), ) left.fold(onLeftFn, dontCallMePls) From 641e65b7286e2aea789f2ad5655186904ed9e09f Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Fri, 29 Mar 2024 14:56:39 +0200 Subject: [PATCH 31/66] feat: add vim folds for task tests --- tests/task.test.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/task.test.ts b/tests/task.test.ts index ee9e47d..3a89c7e 100644 --- a/tests/task.test.ts +++ b/tests/task.test.ts @@ -1,6 +1,7 @@ import { of } from '../src/task' describe('task.ts', () => { + // {{{ map it('map', async () => { const task = of(() => Promise.resolve(40)).map( (num) => num * 2, @@ -10,7 +11,8 @@ describe('task.ts', () => { expect(result).toBe(80) }) - + // }}} + // {{{ flatMap it('flatMap', async () => { const task = of(() => Promise.resolve(50)) const otherTask = of(() => Promise.resolve(60)) @@ -21,10 +23,11 @@ describe('task.ts', () => { expect(runned).toBe(60) }) - + // }}} + // {{{ delay it('delay', async () => { const a = of(() => Promise.resolve(40)).delay(10) expect(await a.run()).toBe(40) - }) + }) // }}} }) From ce7d02b048c15759c5d1e8643b2ed44af5a7fcf7 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Fri, 29 Mar 2024 14:57:43 +0200 Subject: [PATCH 32/66] feat: add vim folds for identity tests --- tests/identity.test.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/identity.test.ts b/tests/identity.test.ts index be1caab..bb7eaba 100644 --- a/tests/identity.test.ts +++ b/tests/identity.test.ts @@ -1,6 +1,7 @@ import { I } from '../src/' describe('identity.ts', () => { + // {{{ map it('map', () => { const map = jest.fn((num: number) => { expect(num).toBe(10) @@ -12,7 +13,8 @@ describe('identity.ts', () => { expect(map).toHaveBeenCalled() expect(identity.value).toBe(20) }) - + // }}} + // {{{ flatMap it('flatMap', () => { const toMerge = I.of(50) @@ -25,7 +27,8 @@ describe('identity.ts', () => { expect(flatMapFn).toHaveBeenCalled() expect(merged.value).toStrictEqual([10, 50]) }) - + // }}} + // {{{ merge it('merge', () => { const a = I.of(50) const b = I.of(500) @@ -35,4 +38,5 @@ describe('identity.ts', () => { right: 500, }) }) + // }}} }) From b7ec888bd0f49109ae17a3b5e483abb92e4b01de Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Fri, 29 Mar 2024 15:07:18 +0200 Subject: [PATCH 33/66] feat: add vim folds for lens tests --- tests/lens.test.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/lens.test.ts b/tests/lens.test.ts index 72d3484..627bd79 100644 --- a/tests/lens.test.ts +++ b/tests/lens.test.ts @@ -1,6 +1,7 @@ import { Lens, from, fromProp } from '../src/lens' describe('lens.ts', () => { + // {{{ set it('set()', () => { const obj = { a: 'string' } @@ -21,7 +22,8 @@ describe('lens.ts', () => { expect(setted.a).toBe('str') expect(setted).not.toBe(obj) }) - + // }}} + // {{{ get it('get()', () => { const obj = { a: 'string' } @@ -42,7 +44,8 @@ describe('lens.ts', () => { expect(lens.view(obj)).toBe('string') expect(view).toHaveBeenCalled() }) - + // }}} + // {{{ compose it('compose()', () => { interface Nested2 { a: string @@ -88,4 +91,5 @@ describe('lens.ts', () => { newObj, ) }) + // }}} }) From a1f949556cdc2dd94ad7c0d11c8fa379f44151f6 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Fri, 29 Mar 2024 15:12:41 +0200 Subject: [PATCH 34/66] feat: add vim folds for maybe-utils tests --- tests/maybe-utils.test.ts | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/tests/maybe-utils.test.ts b/tests/maybe-utils.test.ts index bb99b07..67eca92 100644 --- a/tests/maybe-utils.test.ts +++ b/tests/maybe-utils.test.ts @@ -1,12 +1,14 @@ import { M } from '../src/index' describe('utils.ts', () => { + // {{{ or it('or', () => { const final = M.or(M.of(null), M.of(3), M.of(4)) expect(final.value).toBe(3) }) - + // }}} + // {{{ merge it('merge without nothing', () => { const merged = M.merge( M.of(42), @@ -16,7 +18,8 @@ describe('utils.ts', () => { expect(merged.value).toStrictEqual([42, 10, 'hello']) }) - + // }}} + // {{{ merge it('merge with nothing', () => { const merged = M.merge( M.of(null), @@ -26,15 +29,18 @@ describe('utils.ts', () => { expect(merged.value).toBeNull() }) - - it('fromMaybe', () => { + // }}} + // {{{ fromUndefined + it('fromUndefined', () => { expect(M.fromUndefined(42).value).toBe(42) }) - - it('fromMaybe with undefined', () => { + // }}} + // {{{ fromUndefined + it('fromUndefined with undefined', () => { expect(M.fromUndefined(undefined).value).toBeNull() }) - + // }}} + // {{{ mergeMap it('merge map', () => { const add = (a: number, b: number) => a + b @@ -43,7 +49,8 @@ describe('utils.ts', () => { expect(M.mergeMap(a, b, add).value).toBe(3) }) - + // }}} + // {{{ mergeMap it('merge map with nothing', () => { const add = (a: number, b: number) => a + b @@ -52,7 +59,8 @@ describe('utils.ts', () => { expect(M.mergeMap(a, b, add).value).toBe(null) }) - + // }}} + // {{{ fromThrowable it('fromThrowable', () => { const throwable = (num: number) => { if (num < 5) { @@ -66,4 +74,5 @@ describe('utils.ts', () => { expect(handled(0).value).toBeNull() expect(handled(6).value).toBe(':)') }) + // }}} }) From 7f832a0abbec4c341b08b6d7140be2ead2ab4693 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Fri, 29 Mar 2024 15:16:59 +0200 Subject: [PATCH 35/66] feat: add vim folds for observable tests --- tests/observable.test.ts | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/tests/observable.test.ts b/tests/observable.test.ts index d5c0ed3..ab77fa1 100644 --- a/tests/observable.test.ts +++ b/tests/observable.test.ts @@ -1,10 +1,13 @@ import { O } from '../src' +// {{{ function to help with tests const double = (num: number): number => num * 2 const flatDouble = (num: number): O.Observable => O.of(num * 2) +// }}} describe('observable.ts', () => { + // {{{ map it('map', () => { const observable = O.of(52) const newObservable = observable.map(double) @@ -17,7 +20,8 @@ describe('observable.ts', () => { expect(observer).toHaveBeenCalled() }) - + // }}} + // {{{ flatMap it('flatMap', () => { const observable = O.of(2) const newObservable = observable.flatMap(flatDouble) @@ -30,7 +34,8 @@ describe('observable.ts', () => { expect(observer).toHaveBeenCalled() }) - + // }}} + // {{{ next it('next', () => { const observable = O.of(42) const observer = jest.fn((num: number) => @@ -42,7 +47,8 @@ describe('observable.ts', () => { expect(observer).toHaveBeenCalledTimes(2) }) - + // }}} + // {{{ dependingNext it('dependingNext', () => { const initialState = 2 const observable = O.of(initialState) @@ -58,7 +64,8 @@ describe('observable.ts', () => { expect(observer).toHaveBeenCalled() }) - + // }}} + // {{{ merge it('merge', () => { const a = O.of(2) const b = O.of(9) @@ -81,7 +88,8 @@ describe('observable.ts', () => { a.dependingNext(double) expect(merged.value).toStrictEqual([8, 18, 3]) }) - + // }}} + // {{{ unobserve it('observe.unobserve', () => { const a = O.of(4) const observer = jest.fn((_: number) => { @@ -93,7 +101,8 @@ describe('observable.ts', () => { a.next(10) expect(a.value).toBe(10) }) - + // }}} + // {{{ equals it('equals', () => { const x = 5 const f = (v: number) => O.of(v * 2) @@ -111,4 +120,5 @@ describe('observable.ts', () => { const law3_rhs = O.of(x).flatMap((x) => f(x).flatMap(g)) expect(law3_lhs.equals(law3_rhs)).toBeTruthy() }) + // }}} }) From fdc1b17fb3056506fb9a8c16ffa2a9536ee55b12 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Fri, 29 Mar 2024 15:23:56 +0200 Subject: [PATCH 36/66] feat: add vim folds for reader tests --- tests/reader.test.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tests/reader.test.ts b/tests/reader.test.ts index 2fc302b..9b90cc2 100644 --- a/tests/reader.test.ts +++ b/tests/reader.test.ts @@ -1,10 +1,12 @@ import { R } from '../src' +// {{{ interface for enviroments interface Env { s: number } - +// }}} describe('reader.ts', () => { + // {{{ run it('run', () => { const run = jest.fn( (env: Record) => env.someKey, @@ -18,7 +20,8 @@ describe('reader.ts', () => { ) expect(run).toHaveBeenCalledTimes(2) }) - + // }}} + // {{{ map it('map', () => { const run = jest.fn((env: Env) => env.s * 2) @@ -27,7 +30,8 @@ describe('reader.ts', () => { expect(reader.run({ s: 100 })).toBe(1000) expect(run).toHaveBeenCalled() }) - + // }}} + // {{{ flatMap it('flatMap', () => { const a = R.of((env) => env.s * 10) const b = R.of((env) => env.s * 2) @@ -40,7 +44,8 @@ describe('reader.ts', () => { expect(merged.run({ s: 10 })).toStrictEqual([100, 20]) }) - + // }}} + // {{{ ap it('ap', () => { const a = R.of((env) => env.s / 2) const b = R.of string>( @@ -49,4 +54,5 @@ describe('reader.ts', () => { expect(a.ap(b).run({ s: 58 })).toBe('29.58') }) + // }}} }) From 91bbb2439207f8b33a89c9543e02c6a4c35d42fb Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Fri, 29 Mar 2024 15:26:10 +0200 Subject: [PATCH 37/66] feat: add vim folds for readerT tests --- tests/readerT.test.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/readerT.test.ts b/tests/readerT.test.ts index 3f8d521..8f86816 100644 --- a/tests/readerT.test.ts +++ b/tests/readerT.test.ts @@ -1,5 +1,6 @@ -import { RT, M } from '../src' +import { M, RT } from '../src' +// {{{ helpers to run tests interface Env { somevalue: number | null stringValueThatMayNotExist: string | undefined @@ -18,8 +19,10 @@ const envWithoutMissingValues: Env = { const someValue: RT.ReaderT> = RT.of( (e) => M.of(e.somevalue), ) +// }}} describe('readerT.ts', () => { + // {{{ map it('map', () => { const map = jest.fn((number: number) => number * 2) @@ -29,7 +32,8 @@ describe('readerT.ts', () => { expect(map).toHaveBeenCalled() expect(runned.value).toBe(100) }) - + // }}} + // {{{ flatMap it('flatMap', () => { const run = jest.fn((enviroment: Env) => { expect(enviroment).toBe(envWithoutMissingValues) @@ -58,4 +62,5 @@ describe('readerT.ts', () => { envWithoutMissingValues.stringValueThatMayNotExist, ]) }) + // }}} }) From 328cec723c9481bd581b461a80f3f4cf4245edad Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Fri, 29 Mar 2024 15:27:51 +0200 Subject: [PATCH 38/66] feat: add vim folds for state tests --- tests/state.test.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/state.test.ts b/tests/state.test.ts index f90f0d4..94e7c9c 100644 --- a/tests/state.test.ts +++ b/tests/state.test.ts @@ -1,5 +1,6 @@ import { S } from '../src' +// {{{ helpers for running tests const double = (num: number): [number, number] => [ num * 2, num * 2, @@ -8,14 +9,17 @@ const double = (num: number): [number, number] => [ const initialState = 10 const doubleState = S.of(double) +// }}} describe('state.ts', () => { + // {{{ run it('run', () => { expect(doubleState.run(initialState)).toStrictEqual([ 20, 20, ]) }) - + // }}} + // {{{ map it('map', () => { const [result, newState] = doubleState .map((num) => num.toString()) @@ -25,7 +29,8 @@ describe('state.ts', () => { expect(result).toBe('2020') expect(newState).toBe(initialState * 2) }) - + // }}} + // {{{ flatMap it('flatMap', () => { const result = doubleState .flatMap(() => S.of((num) => [num.toString(), num])) @@ -33,4 +38,5 @@ describe('state.ts', () => { expect(result).toStrictEqual(['20', 20]) }) + // }}} }) From b30242451e2a78f983652aec07afbd1c1605d611 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Fri, 29 Mar 2024 20:19:05 +0200 Subject: [PATCH 39/66] feat: implement ap method for either --- src/either/either.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/either/either.ts b/src/either/either.ts index 6ea9e2b..d201109 100644 --- a/src/either/either.ts +++ b/src/either/either.ts @@ -9,6 +9,10 @@ export type MapFunction = ( fn: (v: Right) => R, ) => Either +export type ApFunction = ( + fn: Either R>, +) => Either + export type MapLeft = ( f: (v: Left) => R, ) => Either @@ -52,6 +56,8 @@ export interface Left { orElse: (fn: (e: T) => Either) => Either + ap: ApFunction + asyncMap: AsyncMapFunction /** @@ -124,6 +130,8 @@ export interface Right { */ isLeft: () => false + ap: ApFunction + asyncMap: AsyncMapFunction orElse: (fn: (e: R) => Either) => Either @@ -177,6 +185,9 @@ export const left = (e: L): Either => ({ left(e), merge: (_: Either) => left(e), + + ap: (_f: Either Re>): Either => + left(e), }) /** @@ -222,6 +233,9 @@ export const right = ( right(v).flatMap((cv) => or.map((ov) => ({ left: cv, right: ov })), ), + + ap: (fn: Either Re>): Either => + fn.map((fn) => fn(v)), }) /** From a3fa96d0f23f2500a4ef29127ab1a2e0cbb218ab Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Fri, 29 Mar 2024 20:26:43 +0200 Subject: [PATCH 40/66] feat: add vim folds --- src/either/either.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/either/either.ts b/src/either/either.ts index d201109..96415e2 100644 --- a/src/either/either.ts +++ b/src/either/either.ts @@ -1,5 +1,6 @@ import { Merged } from '->t/merged' +// {{{ types for either functions export type FoldFunction = ( lfn: (e: Left) => R, rfn: (v: Right) => R, @@ -33,7 +34,9 @@ export type MergeFunction = ( export type AsyncMapFunction = ( fn: (v: Right) => Promise, ) => Promise> +// }}} +// {{{ interface for left /** * Represents the left side of the Either monad. * @template T - The type of the left value. @@ -109,7 +112,9 @@ export interface Left { */ merge: MergeFunction } +// }}} +// {{{ interface for right /** * Represents the right side of the Either monad. * @template T - The type of the right value. @@ -148,9 +153,11 @@ export interface Right { merge: MergeFunction } +// }}} export type Either = Left | Right +// {{{ function for left /** * Constructs a Left Either monad with the provided value. * @@ -189,7 +196,9 @@ export const left = (e: L): Either => ({ ap: (_f: Either Re>): Either => left(e), }) +// }}} +// {{{ function for right /** * Constructs a Right Either monad with the provided value. * @@ -246,6 +255,8 @@ export const right = ( * * right.fold(console.error, console.log) // Output: 42 */ +// }}} + export const of = (value: Right) => right(value) From 0d8b01d4581ebb0a2cc785d470ecec64879cd92a Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Sat, 30 Mar 2024 09:53:44 +0200 Subject: [PATCH 41/66] feat: implement applicative for identity --- src/identity/identity.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/identity/identity.ts b/src/identity/identity.ts index 1791092..25029e0 100644 --- a/src/identity/identity.ts +++ b/src/identity/identity.ts @@ -4,6 +4,7 @@ export interface Identity { map: (f: (v: T) => R) => Identity flatMap: (f: (v: T) => Identity) => Identity merge: (oi: Identity) => Identity> + ap: (f: Identity<(v: T) => R>) => Identity value: T } @@ -14,5 +15,7 @@ export const of = (value: T): Identity => ({ of(value).flatMap((left) => oi.map((right) => ({ left, right })), ), + ap: (f: Identity<(v: T) => R>): Identity => + f.map((fn) => fn(value)), value, }) From 46e6d8b4c810fd9b17aa9bb9d1b9f90d47ac74e9 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Sat, 30 Mar 2024 10:06:29 +0200 Subject: [PATCH 42/66] feat: implement applicative for state --- src/state/state.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/state/state.ts b/src/state/state.ts index da4b54d..75772fd 100644 --- a/src/state/state.ts +++ b/src/state/state.ts @@ -26,6 +26,8 @@ export interface State { * @returns {State} A new State monad resulting from flat mapping. */ flatMap: (f: (v: A) => State) => State + + ap: (f: State R>) => State } /** @@ -51,4 +53,6 @@ export const of = ( return fn(a).run(b) }), + ap: (f: State R>) => + of(rs).flatMap((v) => f.map((f) => f(v))), }) From 09b2ee053e5d7d0f584b3e7cbec078322c5fd55d Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Sat, 30 Mar 2024 10:11:44 +0200 Subject: [PATCH 43/66] refactor: change type of run task --- src/state/state.ts | 2 ++ src/task-either/task-either.ts | 2 ++ src/task/task.ts | 6 ++++-- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/state/state.ts b/src/state/state.ts index 75772fd..f352481 100644 --- a/src/state/state.ts +++ b/src/state/state.ts @@ -1,3 +1,4 @@ +// {{{ state interface /** * Represents a State monad, which encapsulates a computation that modifies a state of type `T` and produces a value of type `A`. * @template T The type of the state. @@ -29,6 +30,7 @@ export interface State { ap: (f: State R>) => State } +// }}} /** * Constructs a State monad with the provided computation. diff --git a/src/task-either/task-either.ts b/src/task-either/task-either.ts index 7a62561..008104e 100644 --- a/src/task-either/task-either.ts +++ b/src/task-either/task-either.ts @@ -1,6 +1,7 @@ import { Lazy } from '->t/lazy' import { Either, isRight, left } from '->/either' +// {{{ TaskEither interface export interface TaskEither { map: (f: (v: Right) => R) => TaskEither flatMap: ( @@ -20,6 +21,7 @@ export interface TaskEither { onRight: (v: Right) => Promise | R, ) => Promise } +// }}} /** * `TaskEither` represents asynchrounous computation that might diff --git a/src/task/task.ts b/src/task/task.ts index c7f5191..9081d02 100644 --- a/src/task/task.ts +++ b/src/task/task.ts @@ -1,8 +1,10 @@ +import { Lazy } from '->/types/lazy' + export interface Task { map: (f: (v: T) => R) => Task flatMap: (f: (v: T) => Task) => Task delay: (ms: number) => Task - run: () => Promise + run: Lazy> } /** @@ -13,7 +15,7 @@ export interface Task { * @param {() => Promise} run - function to wrap in task * @returns {Task} new task monad */ -export const of = (run: () => Promise): Task => ({ +export const of = (run: Lazy>): Task => ({ map: (f: (v: T) => R) => of(() => Promise.resolve().then(run).then(f)), flatMap: (f: (v: T) => Task): Task => From 8a24d96a5083e66c0fe369ac0a1c5380b52db7ef Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Sat, 30 Mar 2024 10:16:26 +0200 Subject: [PATCH 44/66] refactor: add LazyPromise type to remove useless generic nesting --- src/task-either/task-either.ts | 3 ++- src/task/task.ts | 6 +++--- src/types/lazy-promise.ts | 11 +++++++++++ 3 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 src/types/lazy-promise.ts diff --git a/src/task-either/task-either.ts b/src/task-either/task-either.ts index 008104e..fff0e68 100644 --- a/src/task-either/task-either.ts +++ b/src/task-either/task-either.ts @@ -1,5 +1,6 @@ import { Lazy } from '->t/lazy' import { Either, isRight, left } from '->/either' +import { LazyPromise } from '->/types/lazy-promise' // {{{ TaskEither interface export interface TaskEither { @@ -31,7 +32,7 @@ export interface TaskEither { * @returns {TaskEither} - new TaskEither */ export const of = ( - task: Lazy>>, + task: LazyPromise>, ): TaskEither => ({ map: (f: (v: Right) => R): TaskEither => of(() => task().then((either) => either.map(f))), diff --git a/src/task/task.ts b/src/task/task.ts index 9081d02..42fbe1e 100644 --- a/src/task/task.ts +++ b/src/task/task.ts @@ -1,10 +1,10 @@ -import { Lazy } from '->/types/lazy' +import { LazyPromise } from '->/types/lazy-promise' export interface Task { map: (f: (v: T) => R) => Task flatMap: (f: (v: T) => Task) => Task delay: (ms: number) => Task - run: Lazy> + run: LazyPromise } /** @@ -15,7 +15,7 @@ export interface Task { * @param {() => Promise} run - function to wrap in task * @returns {Task} new task monad */ -export const of = (run: Lazy>): Task => ({ +export const of = (run: LazyPromise): Task => ({ map: (f: (v: T) => R) => of(() => Promise.resolve().then(run).then(f)), flatMap: (f: (v: T) => Task): Task => diff --git a/src/types/lazy-promise.ts b/src/types/lazy-promise.ts new file mode 100644 index 0000000..704e0d1 --- /dev/null +++ b/src/types/lazy-promise.ts @@ -0,0 +1,11 @@ +import { Lazy } from './lazy' + +/** + * just like `Lazy` but returns promise + * useful for removing nested generics + * @template T - type of lazy argument that is going to be wrapped in promise + * @see {@link Lazy} + */ +export interface LazyPromise { + (): Promise +} From a3d183a613a129366145cfa1cc96563d14824bd1 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Sat, 30 Mar 2024 15:37:52 +0200 Subject: [PATCH 45/66] refactor: change type of run parameter in task-maybe --- src/task-either/task-either.ts | 1 - src/task-maybe/task-maybe.ts | 9 ++++----- src/types/lazy-promise.ts | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/task-either/task-either.ts b/src/task-either/task-either.ts index fff0e68..09686a5 100644 --- a/src/task-either/task-either.ts +++ b/src/task-either/task-either.ts @@ -1,4 +1,3 @@ -import { Lazy } from '->t/lazy' import { Either, isRight, left } from '->/either' import { LazyPromise } from '->/types/lazy-promise' diff --git a/src/task-maybe/task-maybe.ts b/src/task-maybe/task-maybe.ts index 9305e50..23593f5 100644 --- a/src/task-maybe/task-maybe.ts +++ b/src/task-maybe/task-maybe.ts @@ -1,15 +1,14 @@ -import { M } from '-->' -import { Lazy } from '->t/lazy' -import { none } from '->/maybe' +import { Maybe, none } from '->/maybe' +import { LazyPromise } from '->/types/lazy-promise' interface TaskMaybe { - run: () => Promise> + run: LazyPromise> map: (f: (v: T) => R) => TaskMaybe flatMap: (f: (v: T) => TaskMaybe) => TaskMaybe } export const of = ( - run: Lazy>>, + run: LazyPromise>, ): TaskMaybe => ({ run: run, map: (f: (v: T) => R): TaskMaybe => diff --git a/src/types/lazy-promise.ts b/src/types/lazy-promise.ts index 704e0d1..d0d5173 100644 --- a/src/types/lazy-promise.ts +++ b/src/types/lazy-promise.ts @@ -1,7 +1,7 @@ import { Lazy } from './lazy' /** - * just like `Lazy` but returns promise + * just like `Lazy` but returns a promise * useful for removing nested generics * @template T - type of lazy argument that is going to be wrapped in promise * @see {@link Lazy} From 5d4126e2bd8a8c87167d958c4fb418c1feb49a05 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Sat, 30 Mar 2024 21:23:26 +0200 Subject: [PATCH 46/66] feat: implement multiple function --- .eslintrc.js | 8 ------- src/either/utils/from-throwable.ts | 14 +++++------ src/functions/index.ts | 37 +----------------------------- src/functions/multiple.ts | 36 +++++++++++++++++++++++++++++ src/functions/pipe.ts | 34 --------------------------- 5 files changed, 44 insertions(+), 85 deletions(-) create mode 100644 src/functions/multiple.ts delete mode 100644 src/functions/pipe.ts diff --git a/.eslintrc.js b/.eslintrc.js index aed9e77..3a248cd 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -69,12 +69,4 @@ module.exports = { ], 'block-spacing': ['warn', 'always'], }, - overrides: [ - { - files: ['*.ts', '*.tsx'], - rules: { - '@typescript-eslint/indent': ['error', 2], - }, - }, - ], } diff --git a/src/either/utils/from-throwable.ts b/src/either/utils/from-throwable.ts index 11e6dc7..4e8b6cc 100644 --- a/src/either/utils/from-throwable.ts +++ b/src/either/utils/from-throwable.ts @@ -4,7 +4,7 @@ import { Either, left, right } from '->/either' * Constructs a function that converts a throwable function into an `Either` * monad. * @param {(...a: T) => R} f The function to be wrapped. - * @returns {(...a: T) => Either} A function that takes the same parameters as `f` and returns an `Either`. + * @returns A function that takes the same parameters as `f` and returns an `Either`. * @template T The types of the parameters of the function `f`. * @template R The return type of the function `f`. */ @@ -12,10 +12,10 @@ export const fromThrowable = , R>( f: (...a: T) => R, ) => - (...a: T): Either => { - try { - return right(f(...a)) - } catch (e) { - return left(e) - } + (...a: T): Either => { + try { + return right(f(...a)) + } catch (e) { + return left(e) } + } diff --git a/src/functions/index.ts b/src/functions/index.ts index d262b65..9997053 100644 --- a/src/functions/index.ts +++ b/src/functions/index.ts @@ -1,36 +1 @@ -/** - * in progress - */ - -type LastElement = T extends [ - ...unknown[], - infer LastItem, -] - ? LastItem - : never - -type Operator = (value: A) => B -type OperatorA = - T extends Operator ? A : never -type OperatorB = - T extends Operator ? B : never - -type PipeOperators< - Operators extends unknown[], - Input, -> = Operators extends [infer Item, ...infer Tail] - ? [ - Operator>, - ...PipeOperators>, - ] - : Operators -type PipeOperatorsOutput = - OperatorB> - -function pipe( - ...operators: PipeOperators -): (input: Input) => PipeOperatorsOutput { - return (input) => - // @ts-expect-error we do not care - operators.reduce((result, next) => next(result), input) -} +export * from './multiple' diff --git a/src/functions/multiple.ts b/src/functions/multiple.ts new file mode 100644 index 0000000..75a3399 --- /dev/null +++ b/src/functions/multiple.ts @@ -0,0 +1,36 @@ +export type ReturnTypes< + A extends readonly unknown[], + T extends ((...a: A) => unknown)[], +> = { + [K in keyof T]: T[K] extends (...a: infer _A) => infer U + ? U + : never +} + +/** + * @example + * + * const add = (num: number) => (toAdd: number) => num + toAdd + * const double = (num: number) => num * 2 + * const quadriple = (num: number) => double(double(num)) + * const toString = (num: number) => num.toString() + * + * const a = multiple( + * add(10), + * ) + * + * a() // Output: [ 60, 100, 200, 140, "50" ] + * @returns result of all computations passed in + */ +export const multiple = + < + A extends readonly any[], + F extends (...a: A) => any, + T extends ((...a: A) => any)[], + >( + ...fns: T extends Array<(...a: A) => any> + ? [F, ...T] + : T + ) => + (...a: A): ReturnTypes => + fns.map((fn) => fn(...a)) as ReturnTypes diff --git a/src/functions/pipe.ts b/src/functions/pipe.ts deleted file mode 100644 index ac86e6b..0000000 --- a/src/functions/pipe.ts +++ /dev/null @@ -1,34 +0,0 @@ -type AnyFunction = (...args: any[]) => any - -type PipeArgs< - F extends AnyFunction[], - Acc extends AnyFunction[] = [], -> = F extends [(...args: infer A) => infer B] - ? [...Acc, (...args: A) => B] - : F extends [(...args: infer A) => any, ...infer Tail] - ? Tail extends [(arg: infer B) => any, ...any[]] - ? PipeArgs B]> - : Acc - : Acc - -type LastFnReturnType< - F extends AnyFunction[], - R, -> = F extends [] - ? R - : F extends [...infer Rest, (arg: R) => infer Last] - ? LastFnReturnType< - Rest extends AnyFunction[] ? Rest : [], - Last - > - : never - -export function pipe( - arg: Parameters[0], - ...fns: PipeArgs extends F ? F : PipeArgs -): LastFnReturnType> { - return (fns.slice(1) as AnyFunction[]).reduce( - (acc, fn) => fn(acc), - fns[0]?.(arg), - ) -} From 6b7a757ce89e820ad6601f05158bcfaf43c11ce7 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Sat, 30 Mar 2024 21:59:05 +0200 Subject: [PATCH 47/66] feat: add vim folds for maybe interface --- src/maybe/maybe.ts | 13 +++++++------ src/maybe/utils/from-throwable.ts | 12 ++++++------ src/task-either/task-either.ts | 2 +- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/maybe/maybe.ts b/src/maybe/maybe.ts index 6f1b009..15df422 100644 --- a/src/maybe/maybe.ts +++ b/src/maybe/maybe.ts @@ -1,3 +1,4 @@ +// {{{ maybe interface /** * Represents a Maybe monad, which can contain either a value of type `T` or `null`. * @template T - The type of the value contained in the Maybe monad. @@ -91,7 +92,7 @@ export interface Maybe { */ value: T | null } - +// }}} /** * Creates a Maybe monad containing the specified value. * @template T - The type of the value contained in the Maybe monad. @@ -136,11 +137,11 @@ export const of = (value: T | null): Maybe => ({ value === null ? none() : fn(value) - .then((mapped) => of(mapped)) - .catch((err) => { - error?.(err) - return none() - }), + .then((mapped) => of(mapped)) + .catch((err) => { + error?.(err) + return none() + }), get value() { return value }, diff --git a/src/maybe/utils/from-throwable.ts b/src/maybe/utils/from-throwable.ts index 2749af1..83652c7 100644 --- a/src/maybe/utils/from-throwable.ts +++ b/src/maybe/utils/from-throwable.ts @@ -11,10 +11,10 @@ export const fromThrowable = , R>( f: (...a: T) => R, ) => - (...a: T) => { - try { - return of(f(...a)) - } catch (e) { - return none() - } + (...a: T) => { + try { + return of(f(...a)) + } catch (e) { + return none() } + } diff --git a/src/task-either/task-either.ts b/src/task-either/task-either.ts index 09686a5..a20aee8 100644 --- a/src/task-either/task-either.ts +++ b/src/task-either/task-either.ts @@ -61,7 +61,7 @@ export const of = ( (isRight(either) ? Promise.resolve(either) : f(either.left).run()) as Promise< - Either + Either >, ), ), From eb20dd20f762049dfb51bd40f6d2901218cbbba3 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Sat, 30 Mar 2024 22:01:18 +0200 Subject: [PATCH 48/66] feat: implement correction function for fromThrowable --- src/either/utils/from-throwable.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/either/utils/from-throwable.ts b/src/either/utils/from-throwable.ts index 4e8b6cc..fc1918f 100644 --- a/src/either/utils/from-throwable.ts +++ b/src/either/utils/from-throwable.ts @@ -9,13 +9,14 @@ import { Either, left, right } from '->/either' * @template R The return type of the function `f`. */ export const fromThrowable = - , R>( + , R, E>( f: (...a: T) => R, + c: (e: unknown) => E, ) => - (...a: T): Either => { + (...a: T): Either => { try { return right(f(...a)) } catch (e) { - return left(e) + return left(c(e)) } } From 3c8e2b884fff825385442aa6666153260db01c04 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Sun, 31 Mar 2024 20:41:18 +0300 Subject: [PATCH 49/66] feat: add Either#ap test --- src/either/utils/try-catch.ts | 1 - tests/either.test.ts | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/either/utils/try-catch.ts b/src/either/utils/try-catch.ts index b185984..5591b7c 100644 --- a/src/either/utils/try-catch.ts +++ b/src/either/utils/try-catch.ts @@ -7,7 +7,6 @@ import { Either, left, right } from '->/either' * @template E The type of the error produced by the catch function. * @param {() => T} tryFn The function to be executed in the try block. * @param {(reason: unknown) => E} catchFn The function to handle errors caught in the catch block. - * @param {() => void} [finallyFn] Optional function to be executed in the finally block. * @returns {Either} An Either monad containing either the result of the try function * or an error produced by the catch function. */ diff --git a/tests/either.test.ts b/tests/either.test.ts index 8fee5af..6611c6f 100644 --- a/tests/either.test.ts +++ b/tests/either.test.ts @@ -69,7 +69,13 @@ describe('either.ts', () => { // }}} // {{{ fromThrowable it('fromThrowable', () => { - const wrapped = E.fromThrowable(throwable) + const correctionFn = jest.fn((e: unknown) => { + expect(e).toStrictEqual(eitherExampleError) + + return E.toError(e) + }) + + const wrapped = E.fromThrowable(throwable, correctionFn) const onLeft = jest.fn((e) => expect(e).toStrictEqual(eitherExampleError), @@ -80,6 +86,7 @@ describe('either.ts', () => { expect(onLeft).toHaveBeenCalled() expect(onRight).not.toHaveBeenCalled() + expect(correctionFn).toHaveBeenCalled() wrapped(4).fold(onLeft, onRight) @@ -403,4 +410,29 @@ describe('either.ts', () => { expect(onRightFn).toHaveBeenCalled() }) // }}} + // {{{ ap + it('ap', () => { + const apFn = jest.fn((num: number) => num * 2) + + const leftAp = E.left number>( + 'no fn', + ) + const rightAp = E.right< + (num: number) => number, + string + >(apFn) + + const left = E.left('error') + + left.ap(leftAp) + + expect(apFn).not.toHaveBeenCalled() + + const right = E.right(50) + + right.ap(rightAp) + + expect(apFn).toHaveBeenCalled() + }) + // }}} }) From ae17648e9f322c49ab3f413ed3dc7e6b64f8e6e4 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Sun, 31 Mar 2024 20:44:39 +0300 Subject: [PATCH 50/66] feat: add toError test --- tests/either.test.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/either.test.ts b/tests/either.test.ts index 6611c6f..7ac0ba8 100644 --- a/tests/either.test.ts +++ b/tests/either.test.ts @@ -435,4 +435,13 @@ describe('either.ts', () => { expect(apFn).toHaveBeenCalled() }) // }}} + // {{{ toError + it('toError', () => { + const something = 'hey' + + const error = E.toError(something) + + expect(error instanceof Error).toBe(true) + }) + // }}} }) From a4ceb96ad02ddd841c98dd2646e50865b8fdcfdf Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Sun, 31 Mar 2024 20:54:14 +0300 Subject: [PATCH 51/66] feat: add isRight & isLeft tests --- tests/either.test.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/either.test.ts b/tests/either.test.ts index 7ac0ba8..e6eaa57 100644 --- a/tests/either.test.ts +++ b/tests/either.test.ts @@ -444,4 +444,16 @@ describe('either.ts', () => { expect(error instanceof Error).toBe(true) }) // }}} + // {{{ isRight (is) + it('isRight', () => { + expect(E.isRight(E.right(null))).toBeTruthy() + expect(E.isRight(E.left(null))).toBeFalsy() + }) + // }}} + // {{{ isLeft (is) + it('isLeft', () => { + expect(E.isLeft(E.right(null))).toBeFalsy() + expect(E.isLeft(E.left(null))).toBeTruthy() + }) + // }}} }) From 5798ac2560dc6f4025c4830147dc96497e85368d Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Sun, 31 Mar 2024 21:02:29 +0300 Subject: [PATCH 52/66] feat: add ap tests fro state & identity --- tests/identity.test.ts | 10 ++++++++++ tests/state.test.ts | 12 ++++++++++++ 2 files changed, 22 insertions(+) diff --git a/tests/identity.test.ts b/tests/identity.test.ts index bb7eaba..04d6155 100644 --- a/tests/identity.test.ts +++ b/tests/identity.test.ts @@ -28,6 +28,16 @@ describe('identity.ts', () => { expect(merged.value).toStrictEqual([10, 50]) }) // }}} + // {{{ + it('ap', () => { + const apFn = jest.fn((v: number) => v * 2) + const identityFn = I.of(apFn) + const toApply = I.of(30) + + expect(toApply.ap(identityFn).value).toBe(60) + expect(apFn).toHaveBeenCalled() + }) + // }}} // {{{ merge it('merge', () => { const a = I.of(50) diff --git a/tests/state.test.ts b/tests/state.test.ts index 94e7c9c..b49b16c 100644 --- a/tests/state.test.ts +++ b/tests/state.test.ts @@ -39,4 +39,16 @@ describe('state.ts', () => { expect(result).toStrictEqual(['20', 20]) }) // }}} + // {{{ ap + it('ap', () => { + const ap = S.of((n: number) => [ + (toAdd: number) => n + toAdd, + n, + ]) + + const num = S.of((n: number) => [n, n]) + + expect(num.ap(ap).run(50)).toStrictEqual([100, 50]) + }) + // }}} }) From 211c7c54e08d42d74d73bd7aac34dcebc46fdf17 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Mon, 1 Apr 2024 11:55:44 +0300 Subject: [PATCH 53/66] refactor: move prism into separate dir --- src/lens/index.ts | 1 - src/lens/prism.ts | 25 ------------------------- src/maybe/utils/index.ts | 1 + src/maybe/utils/is.ts | 11 +++++++++++ src/prism/index.ts | 1 + src/prism/prism.ts | 20 ++++++++++++++++++++ 6 files changed, 33 insertions(+), 26 deletions(-) delete mode 100644 src/lens/prism.ts create mode 100644 src/maybe/utils/is.ts create mode 100644 src/prism/index.ts create mode 100644 src/prism/prism.ts diff --git a/src/lens/index.ts b/src/lens/index.ts index 628aa48..bfca677 100644 --- a/src/lens/index.ts +++ b/src/lens/index.ts @@ -1,2 +1 @@ export * from './lens' -export * from './prism' diff --git a/src/lens/prism.ts b/src/lens/prism.ts deleted file mode 100644 index 165bef2..0000000 --- a/src/lens/prism.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Maybe } from '->/maybe' -import { of } from '->/maybe' - -export interface Prism { - view: (v: T) => Maybe - set: (v: R, s: T) => T -} - -export const prism = ( - view: (v: T) => R, - set: Prism['set'], -): Prism => ({ - view: (v) => of(view(v)), - set, -}) - -export const composePrism = ( - ab: Prism, - bc: Prism, -): Prism => ({ - view: (a) => ab.view(a).flatMap((view) => bc.view(view)), - set: (c, a) => - ab.view(a).map((view) => ab.set(bc.set(c, view), a)) - .value!, -}) diff --git a/src/maybe/utils/index.ts b/src/maybe/utils/index.ts index 572d5db..82ad378 100644 --- a/src/maybe/utils/index.ts +++ b/src/maybe/utils/index.ts @@ -4,3 +4,4 @@ export * from './from-undefined' export * from './merge' export * from './or' export * from './from-throwable' +export * from './is' diff --git a/src/maybe/utils/is.ts b/src/maybe/utils/is.ts new file mode 100644 index 0000000..fcce7f0 --- /dev/null +++ b/src/maybe/utils/is.ts @@ -0,0 +1,11 @@ +import { Maybe } from '../maybe' + +export const isMaybe = ( + value: unknown, +): value is Maybe => + !!value && + typeof value === 'object' && + 'map' in value && + typeof value.map === 'function' && + 'flatMap' in value && + typeof value.flatMap === 'function' diff --git a/src/prism/index.ts b/src/prism/index.ts new file mode 100644 index 0000000..d1c2867 --- /dev/null +++ b/src/prism/index.ts @@ -0,0 +1 @@ +export * from './prism' diff --git a/src/prism/prism.ts b/src/prism/prism.ts new file mode 100644 index 0000000..bfeb22c --- /dev/null +++ b/src/prism/prism.ts @@ -0,0 +1,20 @@ +import { Maybe, of as some } from '->/maybe' + +export interface Prism { + view: (v: T) => Maybe + set: (v: R, s: T) => T + compose: (bc: Prism) => Prism +} + +export const prism = ( + view: (v: T) => R | null, + set: Prism['set'], +): Prism => ({ + view: (v) => some(view(v)), + set, + compose: (bc: Prism): Prism => + prism( + (a) => bc.view(view(a)!).value, + (c, a) => set(bc.set(c, view(a)!), a), + ), +}) From 7ed043f61d76bda4295122f3bc40834aa859fb00 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Mon, 1 Apr 2024 12:00:01 +0300 Subject: [PATCH 54/66] feat: add fromProp prism function --- src/lens/lens.ts | 2 ++ src/prism/prism.ts | 12 ++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/lens/lens.ts b/src/lens/lens.ts index 83898f8..4bf91e5 100644 --- a/src/lens/lens.ts +++ b/src/lens/lens.ts @@ -1,3 +1,4 @@ +// {{{ Lens Interface /** * Represents a lens that can focus on a specific part (property) of an object. * @template T The type of the whole object. @@ -27,6 +28,7 @@ export interface Lens { */ compose: (bc: Lens) => Lens } +// }}} /** * Creates a lens for focusing on a specific part (property) of an object. diff --git a/src/prism/prism.ts b/src/prism/prism.ts index bfeb22c..26f917d 100644 --- a/src/prism/prism.ts +++ b/src/prism/prism.ts @@ -6,15 +6,23 @@ export interface Prism { compose: (bc: Prism) => Prism } -export const prism = ( +export const of = ( view: (v: T) => R | null, set: Prism['set'], ): Prism => ({ view: (v) => some(view(v)), set, compose: (bc: Prism): Prism => - prism( + of( (a) => bc.view(view(a)!).value, (c, a) => set(bc.set(c, view(a)!), a), ), }) + +export const fromProp = ( + key: K, +): Prism => + of( + (v) => v[key], + (v, s) => ({ ...s, [key]: v }), + ) From a7cd3adde74f437df05954f05af9925fc47ff36b Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Mon, 1 Apr 2024 12:07:45 +0300 Subject: [PATCH 55/66] feat: add Maybe#is test --- src/maybe/utils/is.ts | 4 +--- tests/maybe.test.ts | 39 +++++++++++++++++++++++++++++---------- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/maybe/utils/is.ts b/src/maybe/utils/is.ts index fcce7f0..5561393 100644 --- a/src/maybe/utils/is.ts +++ b/src/maybe/utils/is.ts @@ -1,8 +1,6 @@ import { Maybe } from '../maybe' -export const isMaybe = ( - value: unknown, -): value is Maybe => +export const is = (value: unknown): value is Maybe => !!value && typeof value === 'object' && 'map' in value && diff --git a/tests/maybe.test.ts b/tests/maybe.test.ts index 5fbdacc..dae7f6c 100644 --- a/tests/maybe.test.ts +++ b/tests/maybe.test.ts @@ -1,6 +1,7 @@ import { M } from '../src/' describe('maybe.ts', () => { + // {{{ map it('map', () => { const number = M.of(42).map((num) => num * 2) @@ -18,7 +19,8 @@ describe('maybe.ts', () => { expect(mockedFunction).not.toHaveBeenCalled() }) - + // }}} + // {{{ mapNullable it('mapNullable', () => { const shouldntBeCalled = jest.fn(() => { throw new Error('shouldnt be called') @@ -33,7 +35,8 @@ describe('maybe.ts', () => { expect(c.value).toBe(null) expect(shouldntBeCalled).not.toHaveBeenCalled() }) - + // }}} + // {{{ flatMap it('flatMap', () => { const a = M.of(5) const b = M.of(52).flatMap((value) => @@ -42,7 +45,8 @@ describe('maybe.ts', () => { expect(b.value).toBe(57) }) - + // }}} + // {{{ getOrElse it('getOrElse', () => { const get = M.none().getOrElse(5) const m = M.of(10).getOrElse(6) @@ -50,7 +54,8 @@ describe('maybe.ts', () => { expect(get).toBe(5) expect(m).toBe(10) }) - + // }}} + // {{{ flatGetOrElse it('flatGetOrElse', () => { const maybeFive = M.of(5) const maybeSix = M.of(6) @@ -61,7 +66,8 @@ describe('maybe.ts', () => { expect(get.value).toBe(5) expect(m.value).toBe(5) }) - + // }}} + // {{{ merge it('merge', () => { const a = M.of(5) const b = M.of('decyat') @@ -74,7 +80,8 @@ describe('maybe.ts', () => { expect(a.merge(nullable).value).toBeNull() }) - + // }}} + // {{{ asyncMap it('asyncMap', async () => { const sleep = (ms: number): Promise => new Promise((res) => setTimeout(() => res(ms), ms)) @@ -107,7 +114,8 @@ describe('maybe.ts', () => { expect(catchError).toHaveBeenCalled() expect(withError.value).toBeNull() }) - + // }}} + // {{{ equals it('equals', () => { const a = M.of(5) const b = M.of(5) @@ -116,7 +124,8 @@ describe('maybe.ts', () => { expect(a.equals(b)).toBeTruthy() expect(a.equals(c)).not.toBeTruthy() }) - + // }}} + // {{{ apoly it('apply', () => { const double = M.of((num: number) => num * 2) const doubleNoCall = M.of((num: number) => { @@ -128,16 +137,26 @@ describe('maybe.ts', () => { M.none().apply(doubleNoCall).value, ).toBeNull() }) - + // }}} + // {{{ isNothing it('isNothing', () => { expect(M.none().isNothing()).toBeTruthy() expect(M.of(2).isNothing()).toBeFalsy() }) - + // }}} + // {{{ call it('call', () => { const fn = jest.fn(() => 0) expect(M.call(fn)).toBe(0) expect(fn).toHaveBeenCalled() + }) // }}} + // {{{ is + it('is', () => { + const maybe = M.of(30) + + expect(M.is(maybe)).toBeTruthy() + expect(M.is(40)).toBeFalsy() }) + // }}} }) From dd9fa95ff842b76e6d529f162a28f91960df22dd Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Mon, 1 Apr 2024 12:13:17 +0300 Subject: [PATCH 56/66] feat: add new features exports --- package.json | 10 ++++++++++ src/index.ts | 2 ++ 2 files changed, 12 insertions(+) diff --git a/package.json b/package.json index 3fd9fea..edd2236 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,11 @@ "require": "./dist/lens/index.js", "types": "./dist/lens/index.d.ts" }, + "./prism": { + "import": "./dist/prism/index.mjs", + "require": "./dist/prism/index.js", + "types": "./dist/prism/index.d.ts" + }, "./identity": { "import": "./dist/identity/index.mjs", "require": "./dist/identity/index.js", @@ -77,6 +82,11 @@ "import": "./dist/task-maybe/index.mjs", "require": "./dist/task-maybe/index.js", "types": "./dist/task-maybe/index.d.ts" + }, + "./functions": { + "import": "./dist/functions/index.mjs", + "require": "./dist/functions/index.js", + "types": "./dist/functions/index.d.ts" } }, "repository": { diff --git a/src/index.ts b/src/index.ts index 44688a0..270d8db 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,6 +6,8 @@ export * as R from './reader' export * as RT from './readerT' export * as I from './identity' export * as L from './lens' +export * as P from './prism' export * as T from './task' export * as TE from './task-either' export * as TM from './task-maybe' +export * as F from './functions' From 61e1d5315b0e24c74c54ddcad38fc72818c4b763 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Mon, 1 Apr 2024 12:18:47 +0300 Subject: [PATCH 57/66] feat: add functions test --- tests/functions.test.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 tests/functions.test.ts diff --git a/tests/functions.test.ts b/tests/functions.test.ts new file mode 100644 index 0000000..809f81f --- /dev/null +++ b/tests/functions.test.ts @@ -0,0 +1,21 @@ +import { F } from '../src/' + +// {{{ function helpers +const add = (n: number) => (toAdd: number) => n + toAdd +const double = (n: number) => n * 2 +const quadriple = (n: number) => double(double(n)) +// }}} + +describe('functions', () => { + // {{{ multiple + it('multiple', () => { + const computations = F.multiple( + add(50), + double, + quadriple, + ) + + expect(computations(50)).toStrictEqual([100, 100, 200]) + }) + // }}} +}) From d37527489d6bfd3a93e8be2a3a5e499930091775 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Mon, 1 Apr 2024 12:28:47 +0300 Subject: [PATCH 58/66] fix: typings of multiple function --- src/functions/multiple.ts | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/functions/multiple.ts b/src/functions/multiple.ts index 75a3399..372feeb 100644 --- a/src/functions/multiple.ts +++ b/src/functions/multiple.ts @@ -2,12 +2,13 @@ export type ReturnTypes< A extends readonly unknown[], T extends ((...a: A) => unknown)[], > = { - [K in keyof T]: T[K] extends (...a: infer _A) => infer U + [K in keyof T]: T[K] extends (...a: A) => infer U ? U : never } /** + * requires at least one function to execute * @example * * const add = (num: number) => (toAdd: number) => num + toAdd @@ -24,13 +25,17 @@ export type ReturnTypes< */ export const multiple = < - A extends readonly any[], - F extends (...a: A) => any, - T extends ((...a: A) => any)[], + F extends (...a: any) => any, + T extends ((...a: Parameters) => any)[], >( - ...fns: T extends Array<(...a: A) => any> + ...fns: T extends Array<(...a: Parameters) => any> ? [F, ...T] : T ) => - (...a: A): ReturnTypes => - fns.map((fn) => fn(...a)) as ReturnTypes + ( + ...a: Parameters + ): ReturnTypes, [F, ...T]> => + fns.map((fn) => fn(...a)) as ReturnTypes< + Parameters, + [F, ...T] + > From a8696317d473eaf0eca75643b4dc09956cec4229 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Mon, 1 Apr 2024 12:33:38 +0300 Subject: [PATCH 59/66] refactor: fix jsdoc example --- src/functions/multiple.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/functions/multiple.ts b/src/functions/multiple.ts index 372feeb..e17523b 100644 --- a/src/functions/multiple.ts +++ b/src/functions/multiple.ts @@ -16,11 +16,9 @@ export type ReturnTypes< * const quadriple = (num: number) => double(double(num)) * const toString = (num: number) => num.toString() * - * const a = multiple( - * add(10), - * ) + * const a = multiple(add(10), double, quadriple, toString) * - * a() // Output: [ 60, 100, 200, 140, "50" ] + * console.log(a(50)) // Output: [ 60, 100, 200, "50" ] * @returns result of all computations passed in */ export const multiple = From e98ff16f4decec0421fb17d92edf793eb75588ad Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Mon, 1 Apr 2024 13:03:14 +0300 Subject: [PATCH 60/66] feat: add AbstractFn type --- src/functions/multiple.ts | 4 +++- src/types/abstract-fn.ts | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 src/types/abstract-fn.ts diff --git a/src/functions/multiple.ts b/src/functions/multiple.ts index e17523b..f8dfd80 100644 --- a/src/functions/multiple.ts +++ b/src/functions/multiple.ts @@ -1,3 +1,5 @@ +import { type AbstractFn } from '->/types/abstract-fn' + export type ReturnTypes< A extends readonly unknown[], T extends ((...a: A) => unknown)[], @@ -23,7 +25,7 @@ export type ReturnTypes< */ export const multiple = < - F extends (...a: any) => any, + F extends AbstractFn, T extends ((...a: Parameters) => any)[], >( ...fns: T extends Array<(...a: Parameters) => any> diff --git a/src/types/abstract-fn.ts b/src/types/abstract-fn.ts new file mode 100644 index 0000000..a9f66f2 --- /dev/null +++ b/src/types/abstract-fn.ts @@ -0,0 +1 @@ +export type AbstractFn = (...a: any) => any From b31f06124fbfbe1a5cf6d3568c98547afea9146f Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Mon, 1 Apr 2024 14:28:50 +0300 Subject: [PATCH 61/66] docs: update docs --- README.md | 22 ++++++++++++++++++++++ package.json | 3 +++ src/functions/pipe.ts | 29 +++++++++++++++++++++++++++++ src/index.ts | 1 + src/types/index.ts | 4 ++++ 5 files changed, 59 insertions(+) create mode 100644 src/functions/pipe.ts create mode 100644 src/types/index.ts diff --git a/README.md b/README.md index 8857def..737ecfa 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,28 @@ Extend from namespaces tsconfig: Use project typescript version in vscode press Ctrl + Shift + p then running **TypeScript: Select TypeScript Version** command, and selectin **Use Workspace Version** refering to [this](https://github.com/unsplash/ts-namespace-import-plugin/issues/12#issuecomment-1836965622) # Examples + +- Imagine you have a piece of text that represents data in JSON format (like a configuration file or an API response). +- The parse function takes this text as input. +- Inside the function, it tries to convert the text into a JavaScript object using JSON.parse. +- If successful, it returns the either `right` parsed object. +- If there’s an issue (for example, the text isn’t valid JSON), it returns either `left` containing Error instead. +- We are using toError function that takes anything then stringifies it and + wraps in `Error` to handle catch block +- Why Use This? + - The tryCatch approach is useful because it gracefully handles potential errors without crashing our program using `Either` monad. + It’s like saying, “Hey, let’s try to parse this JSON, and if anything goes wrong, we’ll handle it gracefully.” +```ts +import { tryCatch, toError } from '@victorenokh/maybe.ts/either' + +const parse = (text: string) => { + return tryCatch( + () => JSON.parse(text), + toError + ) +} +``` + - [Maybe](https://maybets.duckdns.org/examples/maybe.html) - [State](https://maybets.duckdns.org/examples/state.html) - [Either](https://maybets.duckdns.org/examples/either.html) diff --git a/package.json b/package.json index edd2236..1d5fb0f 100644 --- a/package.json +++ b/package.json @@ -87,6 +87,9 @@ "import": "./dist/functions/index.mjs", "require": "./dist/functions/index.js", "types": "./dist/functions/index.d.ts" + }, + "./types": { + "types": "./dist/types/index.d.ts" } }, "repository": { diff --git a/src/functions/pipe.ts b/src/functions/pipe.ts new file mode 100644 index 0000000..94ff172 --- /dev/null +++ b/src/functions/pipe.ts @@ -0,0 +1,29 @@ +import { type AbstractFn } from '->/types/abstract-fn' + +type LastFnReturnType< + F extends Array, + Else = never, +> = F extends [...any[], (...arg: any) => infer R] + ? R + : Else + +export type Pipe< + F extends AbstractFn[], + Acc extends AbstractFn[] = [], +> = F extends [(...a: infer A) => infer R] + ? [...Acc, [(...a: A) => R]] + : F extends [(...a: infer A) => any, ...infer T] + ? T extends [(a: infer B) => any, ...any[]] + ? Pipe B]> + : Acc + : Acc + +type Input = [(a: A) => D, (b: B) => C] +type Output = Pipe> + +export const pipe = < + F extends AbstractFn, + Rest extends AbstractFn[], +>( + a: Parameters[0], +) => {} diff --git a/src/index.ts b/src/index.ts index 270d8db..bd750ca 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,3 +11,4 @@ export * as T from './task' export * as TE from './task-either' export * as TM from './task-maybe' export * as F from './functions' +export * as TY from './types' diff --git a/src/types/index.ts b/src/types/index.ts new file mode 100644 index 0000000..5d139e4 --- /dev/null +++ b/src/types/index.ts @@ -0,0 +1,4 @@ +export * from './lazy' +export * from './merged' +export * from './abstract-fn' +export * from './lazy-promise' From d8016ae341fd027bf7188d187dd52c24140fff69 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Mon, 1 Apr 2024 15:13:37 +0300 Subject: [PATCH 62/66] feat: add Prism#view test --- tests/prism.test.ts | 49 +++++++++++++++++++++++++++++ tests/utils/should-not-be-called.ts | 3 ++ 2 files changed, 52 insertions(+) create mode 100644 tests/prism.test.ts create mode 100644 tests/utils/should-not-be-called.ts diff --git a/tests/prism.test.ts b/tests/prism.test.ts new file mode 100644 index 0000000..52b70a1 --- /dev/null +++ b/tests/prism.test.ts @@ -0,0 +1,49 @@ +import { M, P } from '../src' + +// {{{ helpers to run tests +interface Nested2 { + a: number + b: string +} + +interface Nested { + something: Nested2 +} + +interface Obj { + a: 5 + nonExisting?: string + nonExistingExisting: string | null + nested: Nested +} + +const obj: Obj = { + a: 5, + nonExistingExisting: 'hello', + nested: { + something: { + a: 42, + b: 'something', + }, + }, +} +// }}} + +describe('prism', () => { + // {{{ view + it('view', () => { + const prism: P.Prism = P.fromProp('a') + const canNotExist: P.Prism = + P.fromProp('nonExistingExisting') + + const viewed = prism.view(obj) + const viewed2 = canNotExist.view(obj) + + expect(M.is(viewed)).toBeTruthy() + expect(M.is(viewed2)).toBeTruthy() + + expect(viewed.value).toBe(5) + expect(viewed2.value).toBe('hello') + }) + // }}} +}) diff --git a/tests/utils/should-not-be-called.ts b/tests/utils/should-not-be-called.ts new file mode 100644 index 0000000..5067637 --- /dev/null +++ b/tests/utils/should-not-be-called.ts @@ -0,0 +1,3 @@ +export const shouldNotBeCalled = (...args: any[]): any => { + throw new Error('should not be called') +} From b135ca4e7a2bc1f264ab6022ee061cd87572a34e Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Mon, 1 Apr 2024 15:21:47 +0300 Subject: [PATCH 63/66] fix: try catch wasnt catching errors --- src/task-either/utils/try-catch.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/task-either/utils/try-catch.ts b/src/task-either/utils/try-catch.ts index 9239916..d80f448 100644 --- a/src/task-either/utils/try-catch.ts +++ b/src/task-either/utils/try-catch.ts @@ -7,7 +7,7 @@ export const tryCatch = ( ): TaskEither => of(async () => { try { - return tryFn().then(right) + return right(await tryFn()) } catch (e) { return left(catchFn(e)) } From eacc51063848220e59eeb62bea023d968d81bb8a Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Mon, 1 Apr 2024 15:51:45 +0300 Subject: [PATCH 64/66] feat: add prism.compose test --- tests/prism.test.ts | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tests/prism.test.ts b/tests/prism.test.ts index 52b70a1..4a25bdb 100644 --- a/tests/prism.test.ts +++ b/tests/prism.test.ts @@ -46,4 +46,38 @@ describe('prism', () => { expect(viewed2.value).toBe('hello') }) // }}} + // {{{ set + it('set', () => { + const prism: P.Prism = P.fromProp( + 'nonExistingExisting', + ) + + const setted = prism.set('helloworld', obj) + + expect(setted.nonExistingExisting).toBe('helloworld') + }) + // }}} + // {{{ compose + it('compose', () => { + const a: P.Prism = P.fromProp('nested') + const b: P.Prism = + P.fromProp('something') + + const composed = a.compose(b) + + const viewed = composed.view(obj) + + expect(M.is(viewed)).toBeTruthy() + expect(viewed.value).toStrictEqual(obj.nested.something) + + const nested2: Nested2 = { + a: 50, + b: 'qwerty', + } + + const setted = composed.set(nested2, obj) + + expect(setted.nested.something).toBe(nested2) + }) + // }}} }) From cf28fda0254108fa86702c622443e4ea1c4613f0 Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Mon, 1 Apr 2024 15:57:59 +0300 Subject: [PATCH 65/66] feat: add changesets, new namespaces --- .changeset/pink-falcons-enjoy.md | 5 +++++ tsconfig.namespaces.json | 9 +++++++++ 2 files changed, 14 insertions(+) create mode 100644 .changeset/pink-falcons-enjoy.md diff --git a/.changeset/pink-falcons-enjoy.md b/.changeset/pink-falcons-enjoy.md new file mode 100644 index 0000000..8c91ba9 --- /dev/null +++ b/.changeset/pink-falcons-enjoy.md @@ -0,0 +1,5 @@ +--- +"@victorenokh/maybe.ts": minor +--- + +Implemented Task, Task Either, Task Maybe monads, implemented prisms, multiple function, namespace autoimport diff --git a/tsconfig.namespaces.json b/tsconfig.namespaces.json index 141b854..daa02c9 100644 --- a/tsconfig.namespaces.json +++ b/tsconfig.namespaces.json @@ -33,6 +33,15 @@ }, "TE": { "importPath": "@victorenokh/maybe.ts/task-either" + }, + "F": { + "importPath": "@victorenokh/maybe.ts/functions" + }, + "TY": { + "importPath": "@victorenokh/maybe.ts/types" + }, + "P": { + "importPath": "@victorenokh/maybe.ts/prism" } } } From d599520794f473017f786c3a6dcd4d688a9f8f7d Mon Sep 17 00:00:00 2001 From: VKTRenokh Date: Mon, 1 Apr 2024 15:59:03 +0300 Subject: [PATCH 66/66] feat: add missing task-maybe namespace --- tsconfig.namespaces.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tsconfig.namespaces.json b/tsconfig.namespaces.json index daa02c9..ecc8497 100644 --- a/tsconfig.namespaces.json +++ b/tsconfig.namespaces.json @@ -34,6 +34,9 @@ "TE": { "importPath": "@victorenokh/maybe.ts/task-either" }, + "TM": { + "importPath": "@victorenokh/maybe.ts/task-maybe" + }, "F": { "importPath": "@victorenokh/maybe.ts/functions" },