From b84e4e4b59ad5eac9d6355d92ec287498fdb42a6 Mon Sep 17 00:00:00 2001 From: Anthony Gabriele Date: Thu, 31 Mar 2022 09:54:54 -0700 Subject: [PATCH 1/7] initial commit --- src/types/set.ts | 3 ++- src/util/AtPath.ts | 2 +- src/util/Build.ts | 9 +++++++-- src/util/Paths.ts | 2 +- src/util/indicies.ts | 8 ++++++++ src/values/set.ts | 16 ++++++++++------ 6 files changed, 29 insertions(+), 11 deletions(-) create mode 100644 src/util/indicies.ts diff --git a/src/types/set.ts b/src/types/set.ts index 5070a19..f6ac711 100644 --- a/src/types/set.ts +++ b/src/types/set.ts @@ -1,8 +1,9 @@ import type { AtPath } from "../util/AtPath"; +import { IndiciesForPath } from "../util/indicies"; import type { Paths } from "../util/Paths"; import { AddNullSegments } from "../util/segments"; export type Set = , Val extends AtPath, "no-traversals">>( path: Path & string, - val: Val + ...args: [...IndiciesForPath, Val] ) => (obj: Infer) => Infer; diff --git a/src/util/AtPath.ts b/src/util/AtPath.ts index 4601f5a..6910c6e 100644 --- a/src/util/AtPath.ts +++ b/src/util/AtPath.ts @@ -39,7 +39,7 @@ type ApplySegment = Seg extends `(${string}` ? Extract>["left"] : Seg extends "?right" ? Extract>["right"] - : Seg extends "[]>" + : Seg extends "[]>" | "[number]" ? Extract[number] : Seg extends "{}>" ? Extract>[string] diff --git a/src/util/Build.ts b/src/util/Build.ts index 5b34b3a..bbd0ebd 100644 --- a/src/util/Build.ts +++ b/src/util/Build.ts @@ -35,7 +35,8 @@ type FromScratch = OnSegment< option: Option; left: Either; right: Either; - traversal: New; + arrayIndex: New[]; + traversal: New[]; sum: Segment extends `${infer Discriminant}:${string}` ? { readonly [K in Exclude]+?: New[K]; @@ -53,7 +54,8 @@ type Augment; left: Either>["right"]>; right: Either>["left"], New>; - traversal: New; + arrayIndex: New[]; + traversal: New[]; sum: Segment extends `${infer Discriminant}:${infer Member}` ? | { @@ -91,6 +93,7 @@ type OnSegment< option: unknown; left: unknown; right: unknown; + arrayIndex: unknown; traversal: unknown; sum: unknown; tuple: unknown; @@ -108,6 +111,8 @@ type OnSegment< ? Handler["right"] : S extends `${string}:${string}` ? Handler["sum"] + : S extends "[number]" + ? Handler["arrayIndex"] : S extends "[]>" ? Handler["traversal"] : S extends "{}>" diff --git a/src/util/Paths.ts b/src/util/Paths.ts index 4a06fba..1913240 100644 --- a/src/util/Paths.ts +++ b/src/util/Paths.ts @@ -73,7 +73,7 @@ type BubbleUp> = UnionToIntersection< }[NullableChildren] | { [K in ArrayChildren]: { - [K2 in K as K extends "" ? "[]>" : `${Extract}.[]>`]: A[K][number]; + [K2 in K as K extends "" ? "[]>" | "[number]" : `${Extract}.${"[]>" | "[number]"}`]: A[K][number]; }; }[ArrayChildren] | { diff --git a/src/util/indicies.ts b/src/util/indicies.ts new file mode 100644 index 0000000..e9fe70e --- /dev/null +++ b/src/util/indicies.ts @@ -0,0 +1,8 @@ +import { AddNullSegments, FirstSegment, TailSegment } from "./segments"; +export type IndiciesForPath

= _IndiciesForPath>; + +type _IndiciesForPath

= FirstSegment

extends "" + ? Acc + : FirstSegment

extends "[number]" + ? _IndiciesForPath, [...Acc, number]> + : _IndiciesForPath, Acc>; diff --git a/src/values/set.ts b/src/values/set.ts index 83128de..34149f6 100644 --- a/src/values/set.ts +++ b/src/values/set.ts @@ -3,9 +3,13 @@ import * as Tr from "monocle-ts/lib/Traversal"; import { isPathLens, lensFromPath, traversalFromPath } from "../util/monocle"; import { Set } from "../types/set"; -export const set: Set = (path: string, val: unknown) => (obj: unknown) => { - if (isPathLens(path as any)) { - return lensFromPath(path as any).set(val)(obj); - } - return pipe(traversalFromPath(path as any), Tr.set(val))(obj); -}; +export const set: Set = + (path: string, ...args: unknown[]) => + (obj: unknown) => { + const indicies = args.slice(0, args.length - 1); + const val = args[args.length - 1]; + if (isPathLens(path as any)) { + return lensFromPath(path as any).set(val)(obj); + } + return pipe(traversalFromPath(path as any), Tr.set(val))(obj); + }; From 9acdf1e8dd8ec9fdfac8fcc39c0457bae08ace81 Mon Sep 17 00:00:00 2001 From: Anthony Gabriele Date: Mon, 4 Apr 2022 09:38:14 -0400 Subject: [PATCH 2/7] modify infinitely deep --- src/types/get.ts | 6 ++++-- src/types/modify.ts | 14 +++++++++----- src/types/modifyF.ts | 9 +++++---- src/types/modifyOption.ts | 12 ++++++++---- src/types/modifyOptionW.ts | 8 ++++++-- src/types/modifyW.ts | 8 ++++++-- src/types/set.ts | 2 +- src/types/setOption.ts | 5 +++-- src/types/upsert.ts | 3 ++- src/util/AtPath.ts | 2 +- src/util/Build.ts | 5 +++++ src/util/Paths.ts | 2 +- src/util/indicies.ts | 2 ++ src/util/monocle.ts | 17 ++++++++++++++--- src/util/predicates.ts | 2 ++ src/values/get.ts | 6 +++--- src/values/modify.ts | 16 ++++++++++------ src/values/modifyF.ts | 17 +++++++++++------ src/values/modifyOption.ts | 22 +++++++++++++--------- src/values/modifyOptionW.ts | 22 +++++++++++++--------- src/values/modifyW.ts | 16 ++++++++++------ src/values/remove.ts | 2 +- src/values/rename.ts | 2 +- src/values/set.ts | 2 +- src/values/setOption.ts | 22 +++++++++++++--------- src/values/upsert.ts | 24 ++++++++++++++---------- test/jest/get.spec.ts | 14 ++++++++++++++ test/jest/modify.spec.ts | 2 +- test/jest/modifyOptionW.spec.ts | 7 +++++++ test/jest/modifyW.spec.ts | 7 +++++++ test/jest/set.spec.ts | 1 + test/tsd/get.spec.ts | 5 +++++ test/tsd/modifyOptionW.spec.ts | 6 ++++++ test/tsd/modifyW.spec.ts | 12 ++++++++++++ test/tsd/upsert.spec.ts | 7 +++++++ 35 files changed, 219 insertions(+), 90 deletions(-) diff --git a/src/types/get.ts b/src/types/get.ts index c2ce395..0e95284 100644 --- a/src/types/get.ts +++ b/src/types/get.ts @@ -1,16 +1,18 @@ import type { Option } from "fp-ts/Option"; import type { AtPath } from "../util/AtPath"; import type { Build } from "../util/Build"; +import type { IndiciesForPath } from "../util/indicies"; import type { Paths } from "../util/Paths"; import type { GiveOpt, HasOptional } from "../util/predicates"; -import { AddNullSegments } from "../util/segments"; +import type { AddNullSegments } from "../util/segments"; export type Get = < Infer, Path extends unknown extends Infer ? string : Paths, Ret extends unknown extends Infer ? unknown : GiveOpt>, AddNullSegments> >( - path: Path & string + path: Path & string, + ...indicies: IndiciesForPath ) => unknown extends Infer ? unknown extends Ret ? >( diff --git a/src/types/modify.ts b/src/types/modify.ts index 002622b..99068d6 100644 --- a/src/types/modify.ts +++ b/src/types/modify.ts @@ -1,10 +1,14 @@ import type { Paths } from "../util/Paths"; import type { AtPath } from "../util/AtPath"; -import { AddNullSegments } from "../util/segments"; +import type { AddNullSegments } from "../util/segments"; +import type { IndiciesForPath } from "../util/indicies"; -export type Modify = >( +export type Modify = , Indicies extends unknown[] = IndiciesForPath>( path: Path & string, - modFunc: ( - v: AtPath, "no-traversals"> - ) => AtPath, "no-traversals"> + ...args: [ + ...indicies: Indicies, + modFunc: ( + v: AtPath, "no-traversals"> + ) => AtPath, "no-traversals"> + ] ) => (a: Infer) => Infer; diff --git a/src/types/modifyF.ts b/src/types/modifyF.ts index 6c3f108..83ebdf1 100644 --- a/src/types/modifyF.ts +++ b/src/types/modifyF.ts @@ -3,6 +3,7 @@ import { HKT, Kind, Kind2, Kind3, URIS, URIS2, URIS3 } from "fp-ts/lib/HKT"; import type { Paths } from "../util/Paths"; import type { AtPath } from "../util/AtPath"; import { AddNullSegments } from "../util/segments"; +import { IndiciesForPath } from "../util/indicies"; export type ModifyF = { (F: Applicative3): < @@ -13,7 +14,7 @@ export type ModifyF = { Val extends AtPath, "no-traversals"> >( path: Path & string, - modFunc: (v: Val) => Kind3 + ...args: [...indicies: IndiciesForPath, modFunc: (v: Val) => Kind3] ) => (a: Infer) => Kind3; (F: Applicative2): < E, @@ -22,7 +23,7 @@ export type ModifyF = { Val extends AtPath, "no-traversals"> >( path: Path & string, - modFunc: (v: Val) => Kind2 + ...args: [...indicies: IndiciesForPath, modFunc: (v: Val) => Kind2] ) => (a: Infer) => Kind2; (F: Applicative1): < Infer, @@ -30,7 +31,7 @@ export type ModifyF = { Val extends AtPath, "no-traversals"> >( path: Path & string, - modFunc: (v: Val) => Kind + ...args: [...indicies: IndiciesForPath, modFunc: (v: Val) => Kind] ) => (a: Infer) => Kind; (F: Applicative): < Infer, @@ -38,6 +39,6 @@ export type ModifyF = { Val extends AtPath, "no-traversals"> >( path: Path & string, - modFunc: (v: Val) => HKT + ...args: [...indicies: IndiciesForPath, modFunc: (v: Val) => HKT] ) => (a: Infer) => HKT; }; diff --git a/src/types/modifyOption.ts b/src/types/modifyOption.ts index 1b20817..724bfbd 100644 --- a/src/types/modifyOption.ts +++ b/src/types/modifyOption.ts @@ -1,11 +1,15 @@ import type { AtPath } from "../util/AtPath"; +import type { IndiciesForPath } from "../util/indicies"; import type { Paths } from "../util/Paths"; import type { GiveOpt } from "../util/predicates"; -import { AddNullSegments } from "../util/segments"; +import type { AddNullSegments } from "../util/segments"; export type ModifyOption = >( path: Path & string, - modFunc: ( - v: AtPath, "no-traversals"> - ) => AtPath, "no-traversals"> + ...args: [ + ...indicies: IndiciesForPath, + modFunc: ( + v: AtPath, "no-traversals"> + ) => AtPath, "no-traversals"> + ] ) => (a: Infer) => GiveOpt>; diff --git a/src/types/modifyOptionW.ts b/src/types/modifyOptionW.ts index 84707b7..8fbcdcf 100644 --- a/src/types/modifyOptionW.ts +++ b/src/types/modifyOptionW.ts @@ -2,9 +2,13 @@ import type { Paths } from "../util/Paths"; import type { Build } from "../util/Build"; import type { ApplyTraversals, AtPath } from "../util/AtPath"; import type { GiveOpt } from "../util/predicates"; -import { AddNullSegments } from "../util/segments"; +import type { AddNullSegments } from "../util/segments"; +import type { IndiciesForPath } from "../util/indicies"; export type ModifyOptionW = , RetVal>( path: Path & string, - modFunc: (v: AtPath, "no-traversals">) => RetVal + ...args: [ + ...indicies: IndiciesForPath, + modFunc: (v: AtPath, "no-traversals">) => RetVal + ] ) => (a: Infer) => GiveOpt, Path>, Path>; diff --git a/src/types/modifyW.ts b/src/types/modifyW.ts index 62d2d2a..346d253 100644 --- a/src/types/modifyW.ts +++ b/src/types/modifyW.ts @@ -2,11 +2,15 @@ import type { Paths } from "../util/Paths"; import type { Build } from "../util/Build"; import type { ApplyTraversals, AtPath } from "../util/AtPath"; import type { HasOptional } from "../util/predicates"; -import { AddNullSegments } from "../util/segments"; +import type { AddNullSegments } from "../util/segments"; +import type { IndiciesForPath } from "../util/indicies"; export type ModifyW = , RetVal>( path: Path & string, - modFunc: (v: AtPath, "no-traversals">) => RetVal + ...args: [ + ...indicies: IndiciesForPath, + modFunc: (v: AtPath, "no-traversals">) => RetVal + ] ) => ( a: Infer ) => true extends HasOptional diff --git a/src/types/set.ts b/src/types/set.ts index f6ac711..0e1811b 100644 --- a/src/types/set.ts +++ b/src/types/set.ts @@ -5,5 +5,5 @@ import { AddNullSegments } from "../util/segments"; export type Set = , Val extends AtPath, "no-traversals">>( path: Path & string, - ...args: [...IndiciesForPath, Val] + ...args: [...indicies: IndiciesForPath, val: Val] ) => (obj: Infer) => Infer; diff --git a/src/types/setOption.ts b/src/types/setOption.ts index d3ca75b..9391484 100644 --- a/src/types/setOption.ts +++ b/src/types/setOption.ts @@ -1,7 +1,8 @@ import type { AtPath } from "../util/AtPath"; +import type { IndiciesForPath } from "../util/indicies"; import type { Paths } from "../util/Paths"; import type { GiveOpt } from "../util/predicates"; -import { AddNullSegments } from "../util/segments"; +import type { AddNullSegments } from "../util/segments"; export type SetOption = < Infer, @@ -9,5 +10,5 @@ export type SetOption = < Val extends AtPath, "no-traversals"> >( path: Path & string, - val: Val + ...args: [...indicies: IndiciesForPath, val: Val] ) => (obj: Infer) => GiveOpt; diff --git a/src/types/upsert.ts b/src/types/upsert.ts index c0995dc..4e85943 100644 --- a/src/types/upsert.ts +++ b/src/types/upsert.ts @@ -1,8 +1,9 @@ import type { Paths } from "../util/Paths"; import type { Build } from "../util/Build"; +import type { IndiciesForPath } from "../util/indicies"; export type Upsert = , Final extends string, Val>( path: Path & string, final: Final, - val: Val + ...args: [...indicies: IndiciesForPath, val: Val] ) => (a: Infer) => Build<`${Extract}.${Final}`, Val, Infer>; diff --git a/src/util/AtPath.ts b/src/util/AtPath.ts index 6910c6e..a2bbf11 100644 --- a/src/util/AtPath.ts +++ b/src/util/AtPath.ts @@ -41,7 +41,7 @@ type ApplySegment = Seg extends `(${string}` ? Extract>["right"] : Seg extends "[]>" | "[number]" ? Extract[number] - : Seg extends "{}>" + : Seg extends "{}>" | "[string]" ? Extract>[string] : Seg extends `[${infer TupleIndex}]` ? A[Extract] diff --git a/src/util/Build.ts b/src/util/Build.ts index bbd0ebd..3ab9b1a 100644 --- a/src/util/Build.ts +++ b/src/util/Build.ts @@ -36,6 +36,7 @@ type FromScratch = OnSegment< left: Either; right: Either; arrayIndex: New[]; + recordIndex: Record; traversal: New[]; sum: Segment extends `${infer Discriminant}:${string}` ? { @@ -55,6 +56,7 @@ type Augment>["right"]>; right: Either>["left"], New>; arrayIndex: New[]; + recordIndex: Record; traversal: New[]; sum: Segment extends `${infer Discriminant}:${infer Member}` ? @@ -94,6 +96,7 @@ type OnSegment< left: unknown; right: unknown; arrayIndex: unknown; + recordIndex: unknown; traversal: unknown; sum: unknown; tuple: unknown; @@ -113,6 +116,8 @@ type OnSegment< ? Handler["sum"] : S extends "[number]" ? Handler["arrayIndex"] + : S extends "[string]" + ? Handler["recordIndex"] : S extends "[]>" ? Handler["traversal"] : S extends "{}>" diff --git a/src/util/Paths.ts b/src/util/Paths.ts index 1913240..e3588e1 100644 --- a/src/util/Paths.ts +++ b/src/util/Paths.ts @@ -78,7 +78,7 @@ type BubbleUp> = UnionToIntersection< }[ArrayChildren] | { [K in NonStructRecordChildren]: { - [K2 in K as K extends "" ? "{}>" : `${Extract}.{}>`]: A[K][number]; + [K2 in K as K extends "" ? "{}>" | "[string]" : `${Extract}.${"{}>" | "[string]"}`]: A[K][number]; }; }[NonStructRecordChildren] >; diff --git a/src/util/indicies.ts b/src/util/indicies.ts index e9fe70e..117065b 100644 --- a/src/util/indicies.ts +++ b/src/util/indicies.ts @@ -5,4 +5,6 @@ type _IndiciesForPath

= FirstSegme ? Acc : FirstSegment

extends "[number]" ? _IndiciesForPath, [...Acc, number]> + : FirstSegment

extends "[string]" + ? _IndiciesForPath, [...Acc, string]> : _IndiciesForPath, Acc>; diff --git a/src/util/monocle.ts b/src/util/monocle.ts index 6a3b601..6f04823 100644 --- a/src/util/monocle.ts +++ b/src/util/monocle.ts @@ -8,7 +8,8 @@ import * as Tr from "monocle-ts/lib/Traversal"; export const isPathLens = (path: string): boolean => !split(path).some( - (s) => ["?", "?some", "?left", "right", "[]>", "{}>"].includes(s) || (!s.startsWith("(") && s.includes(":")) + (s) => + ["?", "?some", "?left", "right", "[]>", "{}>", "[number]"].includes(s) || (!s.startsWith("(") && s.includes(":")) ); export const isPathTraversal = (path: string): boolean => split(path).some((s) => ["[]>", "{}>"].includes(s)); @@ -72,7 +73,8 @@ const split = (path: string): string[] => { }); }; -export const optionalFromPath = (path: string): Op.Optional => { +export const optionalFromPath = (path: string, _indicies: unknown[]): Op.Optional => { + const indicies = [..._indicies]; const opt = split(path).reduce((acc, cur) => { if (cur === "?") { return pipe(acc, Op.fromNullable); @@ -82,6 +84,10 @@ export const optionalFromPath = (path: string): Op.Optional => { return pipe(acc, Op.left); } else if (cur === "?right") { return pipe(acc, Op.left); + } else if (cur === "[number]") { + return pipe(acc, Op.index(indicies.shift() as number)); + } else if (cur === "[string]") { + return pipe(acc, Op.key(indicies.shift() as string)); } else if (cur.includes("[") && cur.includes("]") && cur.indexOf("[") < cur.indexOf("]")) { const component: number = Number.parseInt(cur.substring(cur.indexOf("[") + 1, cur.indexOf("]")), 10); return pipe(acc, Op.component(component)); @@ -99,7 +105,8 @@ export const optionalFromPath = (path: string): Op.Optional => { return opt; }; -export const traversalFromPath = (path: string): Tr.Traversal => { +export const traversalFromPath = (path: string, _indicies: unknown[]): Tr.Traversal => { + const indicies = [..._indicies]; const opt = split(path).reduce((acc, cur) => { if (cur === "?") { return pipe(acc, Tr.fromNullable); @@ -109,6 +116,10 @@ export const traversalFromPath = (path: string): Tr.Traversal => { return pipe(acc, Tr.left); } else if (cur === "?right") { return pipe(acc, Tr.left); + } else if (cur === "[number]") { + return pipe(acc, Tr.index(indicies.shift() as number)); + } else if (cur === "[string]") { + return pipe(acc, Tr.key(indicies.shift() as string)); } else if (cur === "[]>") { const a = pipe(acc, Tr.traverse(A.Traversable)); return a; diff --git a/src/util/predicates.ts b/src/util/predicates.ts index 3d9c309..e553ede 100644 --- a/src/util/predicates.ts +++ b/src/util/predicates.ts @@ -23,6 +23,8 @@ type HasSum = Args extends "" ? HasSum> : FirstSegment extends `${string}:${string}` ? true + : FirstSegment extends "[number]" + ? true : HasSum>; type HasNull = Args extends "" diff --git a/src/values/get.ts b/src/values/get.ts index f57f90c..499e43b 100644 --- a/src/values/get.ts +++ b/src/values/get.ts @@ -3,14 +3,14 @@ import * as Tr from "monocle-ts/lib/Traversal"; import { isPathLens, isPathTraversal, lensFromPath, optionalFromPath, traversalFromPath } from "../util/monocle"; import { Get } from "../types/get"; -export const get: Get = (path: string) => { +export const get: Get = (path: string, ...indicies: unknown[]) => { if (isPathLens(path)) { return lensFromPath(path).get; } if (isPathTraversal(path)) { return (v: unknown) => { - return pipe(traversalFromPath(path), Tr.getAll(v)); + return pipe(traversalFromPath(path, indicies), Tr.getAll(v)); }; } - return optionalFromPath(path).getOption; + return optionalFromPath(path, indicies).getOption; }; diff --git a/src/values/modify.ts b/src/values/modify.ts index 4213be5..3e99a53 100644 --- a/src/values/modify.ts +++ b/src/values/modify.ts @@ -4,9 +4,13 @@ import { modify as modifyTr } from "monocle-ts/Traversal"; import { isPathLens, lensFromPath, traversalFromPath } from "../util/monocle"; import { Modify } from "../types/modify"; -export const modify: Modify = (path: string, modFunc: (v: any) => unknown) => (a: unknown) => { - if (isPathLens(path)) { - return pipe(lensFromPath(path), L.modify(modFunc))(a); - } - return pipe(traversalFromPath(path), modifyTr(modFunc))(a); -}; +export const modify: Modify = + (path: string, ...args: unknown[]) => + (a: unknown) => { + const indicies = args.slice(0, args.length - 1); + const modFunc: (v: any) => unknown = args[args.length - 1] as any; + if (isPathLens(path)) { + return pipe(lensFromPath(path), L.modify(modFunc))(a); + } + return pipe(traversalFromPath(path, indicies), modifyTr(modFunc))(a); + }; diff --git a/src/values/modifyF.ts b/src/values/modifyF.ts index e84ffb5..5cea03e 100644 --- a/src/values/modifyF.ts +++ b/src/values/modifyF.ts @@ -3,9 +3,14 @@ import * as L from "monocle-ts/lib/Lens"; import { isPathLens, lensFromPath, traversalFromPath } from "../util/monocle"; import { ModifyF } from "../types/modifyF"; -export const modifyF: ModifyF = (F: any) => (path: string, modFunc: (v: any) => unknown) => (a: unknown) => { - if (isPathLens(path)) { - return pipe(lensFromPath(path), L.modifyF(F)(modFunc as any))(a); - } - return traversalFromPath(path).modifyF(F)(modFunc as any)(a); -}; +export const modifyF: ModifyF = + (F: any) => + (path: string, ...args: unknown[]) => + (a: unknown) => { + const indicies = args.slice(0, args.length - 1); + const modFunc: (v: any) => unknown = args[args.length - 1] as any; + if (isPathLens(path)) { + return pipe(lensFromPath(path), L.modifyF(F)(modFunc as any))(a); + } + return traversalFromPath(path, indicies).modifyF(F)(modFunc as any)(a); + }; diff --git a/src/values/modifyOption.ts b/src/values/modifyOption.ts index 7a8c899..ae22160 100644 --- a/src/values/modifyOption.ts +++ b/src/values/modifyOption.ts @@ -5,12 +5,16 @@ import * as Tr from "monocle-ts/lib/Traversal"; import { isPathLens, isPathTraversal, lensFromPath, optionalFromPath, traversalFromPath } from "../util/monocle"; import { ModifyOption } from "../types/modifyOption"; -export const modifyOption: ModifyOption = (path: string, modFunc: (v: any) => unknown) => (a: unknown) => { - if (isPathLens(path)) { - return pipe(lensFromPath(path), L.modify(modFunc))(a); - } - if (isPathTraversal(path)) { - return pipe(traversalFromPath(path), Tr.modify(modFunc))(a); - } - return pipe(optionalFromPath(path), Op.modifyOption(modFunc))(a); -}; +export const modifyOption: ModifyOption = + (path: string, ...args: unknown[]) => + (a: unknown) => { + const indicies = args.slice(0, args.length - 1); + const modFunc: (v: any) => unknown = args[args.length - 1] as any; + if (isPathLens(path)) { + return pipe(lensFromPath(path), L.modify(modFunc))(a); + } + if (isPathTraversal(path)) { + return pipe(traversalFromPath(path, indicies), Tr.modify(modFunc))(a); + } + return pipe(optionalFromPath(path, indicies), Op.modifyOption(modFunc))(a); + }; diff --git a/src/values/modifyOptionW.ts b/src/values/modifyOptionW.ts index aa8fb5d..8fa4cb4 100644 --- a/src/values/modifyOptionW.ts +++ b/src/values/modifyOptionW.ts @@ -5,12 +5,16 @@ import * as Tr from "monocle-ts/lib/Traversal"; import { isPathLens, isPathTraversal, lensFromPath, optionalFromPath, traversalFromPath } from "../util/monocle"; import { ModifyOptionW } from "../types/modifyOptionW"; -export const modifyOptionW: ModifyOptionW = (path: string, modFunc: (v: any) => unknown) => (a: unknown) => { - if (isPathLens(path)) { - return pipe(lensFromPath(path), L.modify(modFunc))(a); - } - if (isPathTraversal(path)) { - return pipe(traversalFromPath(path), Tr.modify(modFunc))(a); - } - return pipe(optionalFromPath(path), Op.modifyOption(modFunc))(a); -}; +export const modifyOptionW: ModifyOptionW = + (path: string, ...args: unknown[]) => + (a: unknown) => { + const indicies = args.slice(0, args.length - 1); + const modFunc: (v: any) => unknown = args[args.length - 1] as any; + if (isPathLens(path)) { + return pipe(lensFromPath(path), L.modify(modFunc))(a); + } + if (isPathTraversal(path)) { + return pipe(traversalFromPath(path, indicies), Tr.modify(modFunc))(a); + } + return pipe(optionalFromPath(path, indicies), Op.modifyOption(modFunc))(a); + }; diff --git a/src/values/modifyW.ts b/src/values/modifyW.ts index ed61364..b2eceef 100644 --- a/src/values/modifyW.ts +++ b/src/values/modifyW.ts @@ -4,9 +4,13 @@ import { modify as modifyTr } from "monocle-ts/Traversal"; import { isPathLens, lensFromPath, traversalFromPath } from "../util/monocle"; import { ModifyW } from "../types/modifyW"; -export const modifyW: ModifyW = (path: string, modFunc: (v: any) => unknown) => (a: unknown) => { - if (isPathLens(path)) { - return pipe(lensFromPath(path), L.modify(modFunc))(a); - } - return pipe(traversalFromPath(path), modifyTr(modFunc))(a); -}; +export const modifyW: ModifyW = + (path: string, ...args: unknown[]) => + (a: unknown) => { + const indicies = args.slice(0, args.length - 1); + const modFunc: (v: any) => unknown = args[args.length - 1] as any; + if (isPathLens(path)) { + return pipe(lensFromPath(path), L.modify(modFunc))(a); + } + return pipe(traversalFromPath(path, indicies), modifyTr(modFunc))(a); + }; diff --git a/src/values/remove.ts b/src/values/remove.ts index d831740..482df9f 100644 --- a/src/values/remove.ts +++ b/src/values/remove.ts @@ -16,7 +16,7 @@ export const remove: Remove = (fullPath: string) => (a: unknown) => { )(a); } return pipe( - traversalFromPath(path as any), + traversalFromPath(path as any, []), Tr.modify((obj) => omit(Array.isArray(final) ? final : [final])(obj)) )(a); }; diff --git a/src/values/rename.ts b/src/values/rename.ts index 96a7d18..a436061 100644 --- a/src/values/rename.ts +++ b/src/values/rename.ts @@ -15,7 +15,7 @@ export const rename: Rename = (fullPath: string, newKey: string) => (a: unknown) )(a); } return pipe( - traversalFromPath(path), + traversalFromPath(path, []), Tr.modify(({ [final as string]: val, ...rest }) => ({ ...rest, [newKey as string]: val })) )(a); }; diff --git a/src/values/set.ts b/src/values/set.ts index 34149f6..ee51783 100644 --- a/src/values/set.ts +++ b/src/values/set.ts @@ -11,5 +11,5 @@ export const set: Set = if (isPathLens(path as any)) { return lensFromPath(path as any).set(val)(obj); } - return pipe(traversalFromPath(path as any), Tr.set(val))(obj); + return pipe(traversalFromPath(path as any, indicies), Tr.set(val))(obj); }; diff --git a/src/values/setOption.ts b/src/values/setOption.ts index 915964e..92f1e2d 100644 --- a/src/values/setOption.ts +++ b/src/values/setOption.ts @@ -4,12 +4,16 @@ import { set as setTr } from "monocle-ts/Traversal"; import { isPathLens, isPathTraversal, lensFromPath, optionalFromPath, traversalFromPath } from "../util/monocle"; import { SetOption } from "../types/setOption"; -export const setOption: SetOption = (path: string, val: unknown) => (obj: unknown) => { - if (isPathLens(path)) { - return lensFromPath(path).set(val)(obj); - } - if (isPathTraversal(path)) { - return pipe(traversalFromPath(path), setTr(val))(obj); - } - return pipe(optionalFromPath(path), setOptionOp(val))(obj); -}; +export const setOption: SetOption = + (path: string, ...args: unknown[]) => + (obj: unknown) => { + const indicies = args.slice(0, args.length - 1); + const val = args[args.length - 1]; + if (isPathLens(path)) { + return lensFromPath(path).set(val)(obj); + } + if (isPathTraversal(path)) { + return pipe(traversalFromPath(path, indicies), setTr(val))(obj); + } + return pipe(optionalFromPath(path, indicies), setOptionOp(val))(obj); + }; diff --git a/src/values/upsert.ts b/src/values/upsert.ts index 58e7bb2..e6b05eb 100644 --- a/src/values/upsert.ts +++ b/src/values/upsert.ts @@ -4,15 +4,19 @@ import * as Tr from "monocle-ts/lib/Traversal"; import { lensFromPath, traversalFromPath, isPathLens } from "../util/monocle"; import { Upsert } from "../types/upsert"; -export const upsert: Upsert = (path: string, final: string, val: unknown) => (a: unknown) => { - if (isPathLens(path as any)) { +export const upsert: Upsert = + (path: string, final: string, ...args: unknown[]) => + (a: unknown) => { + const indicies = args.slice(0, args.length - 1); + const val = args[args.length - 1]; + if (isPathLens(path as any)) { + return pipe( + lensFromPath(path as any), + L.modify((obj) => ({ ...obj, [final as string]: val })) + )(a) as any; + } return pipe( - lensFromPath(path as any), - L.modify((obj) => ({ ...obj, [final as string]: val })) + traversalFromPath(path as any, indicies), + Tr.modify((obj) => ({ ...obj, [final as string]: val })) )(a) as any; - } - return pipe( - traversalFromPath(path as any), - Tr.modify((obj) => ({ ...obj, [final as string]: val })) - )(a) as any; -}; + }; diff --git a/test/jest/get.spec.ts b/test/jest/get.spec.ts index a8f720f..08c8e43 100644 --- a/test/jest/get.spec.ts +++ b/test/jest/get.spec.ts @@ -13,6 +13,20 @@ describe("get", () => { const traverse = pipe([{ a: 123 }, { a: 456 }], get("[]>.a")); assert.deepStrictEqual(traverse, [123, 456]); }); + it("has indexed array access", () => { + const record = [{ a: 123 }]; + const picked = pipe(record, get("[number].a", 0)); + assert.deepStrictEqual(picked, O.some(123)); + }); + it("has indexed record access", () => { + const record = { a: 123 } as Record; + const picked = pipe(record, get("[string]", "b")); + assert.deepStrictEqual(picked, O.none); + }); + it("can traverse arrays", () => { + const traverse = pipe([{ a: 123 }, { a: 456 }], get("[]>.a")); + assert.deepStrictEqual(traverse, [123, 456]); + }); it("can traverse records (sorting keys)", () => { const traverseRecord = pipe({ b: { z: 456 }, a: { z: 123 } } as Record, get("{}>.z")); assert.deepStrictEqual(traverseRecord, [123, 456]); diff --git a/test/jest/modify.spec.ts b/test/jest/modify.spec.ts index e99fe0d..b0cc535 100644 --- a/test/jest/modify.spec.ts +++ b/test/jest/modify.spec.ts @@ -8,7 +8,7 @@ describe("modify", () => { it("modifies a definite value", () => { const modified: SimpleData = pipe( simpleData, - modify("a.b.[0]", (j) => j + 4) + modify("a.b.[1]", (j) => j + 4) ); assert.deepStrictEqual(modified, { a: { b: [127, "abc", false], c: "def", d: false }, e: 456 }); }); diff --git a/test/jest/modifyOptionW.spec.ts b/test/jest/modifyOptionW.spec.ts index b5be27f..dcb09bc 100644 --- a/test/jest/modifyOptionW.spec.ts +++ b/test/jest/modifyOptionW.spec.ts @@ -43,4 +43,11 @@ describe("modifyOptionW", () => { ); assert.deepStrictEqual(modifyRecordTraversal, { a: "127", b: "460" }); }); + it("widens a collection's type", () => { + const collectionWidensType = pipe( + { a: [123, 456] }, + modifyOptionW(["a", 0], (j) => `${j + 2}`) + ); + assert.deepStrictEqual(collectionWidensType, O.some({ a: ["125", 456] })); + }); }); diff --git a/test/jest/modifyW.spec.ts b/test/jest/modifyW.spec.ts index 9af015d..a5051c4 100644 --- a/test/jest/modifyW.spec.ts +++ b/test/jest/modifyW.spec.ts @@ -26,4 +26,11 @@ describe("modifyW", () => { }), }); }); + it("widens a collection's type", () => { + const collectionWidensType = pipe( + { a: [123, 456] }, + modifyW(["a", 0], (j) => `${j + 2}`) + ); + assert.deepStrictEqual(collectionWidensType, { a: ["125", 456] }); + }); }); diff --git a/test/jest/set.spec.ts b/test/jest/set.spec.ts index c9b73b4..1ab8bd1 100644 --- a/test/jest/set.spec.ts +++ b/test/jest/set.spec.ts @@ -11,6 +11,7 @@ describe("set", () => { }); it("modifies an optional value", () => { const optSet: Data = pipe(data, set("type:A.a.?some.c", -123)); + const optSet2: Data = pipe(data, set("type:A.a.?some.d.[number]", 0, "cde")); assert.deepStrictEqual(optSet, { type: "A", a: O.some({ diff --git a/test/tsd/get.spec.ts b/test/tsd/get.spec.ts index 6ec321e..024602f 100644 --- a/test/tsd/get.spec.ts +++ b/test/tsd/get.spec.ts @@ -15,6 +15,11 @@ const optional = pipe(data, get("type:A.a.?some.c")); expectType>(optional); expectError>(optional); +// has checked record access +const record = { a: 123 } as Record; +const picked2 = pipe(record, get("?key", "b")); +expectType>(picked2); + // can traverse arrays const traverseArray = pipe([{ a: 123 }, { a: 456 }], get("[]>.a")); expectType(traverseArray); diff --git a/test/tsd/modifyOptionW.spec.ts b/test/tsd/modifyOptionW.spec.ts index dd8702c..826da7d 100644 --- a/test/tsd/modifyOptionW.spec.ts +++ b/test/tsd/modifyOptionW.spec.ts @@ -41,6 +41,12 @@ const optionalReplacesType = pipe( ); expectType>(optionalReplacesType); +const collectionWidensType = pipe( + { a: [123, 456] }, + modifyOptionW(["a", 0], (j) => `${j + 2}`) +); +expectType>(collectionWidensType); + const modifyArrayTraversal = pipe( [{ a: O.some(123) }, { a: O.some(456) }], modifyOptionW("[]>.a.?some", (j) => `${j + 4}`) diff --git a/test/tsd/modifyW.spec.ts b/test/tsd/modifyW.spec.ts index 527c5fe..d652b85 100644 --- a/test/tsd/modifyW.spec.ts +++ b/test/tsd/modifyW.spec.ts @@ -38,3 +38,15 @@ const optionalWidensType = pipe( modifyW("a?", (j) => `${j + 2}`) ); expectType<{ a: string | number | undefined }>(optionalWidensType); + +const collectionWidensType = pipe( + { a: [123, 456] }, + modifyW(["a", 0], (j) => `${j + 2}`) +); +expectType<{ a: (string | number)[] }>(collectionWidensType); + +const preservesReadonlyArr = pipe( + [123, 456] as readonly number[], + modifyW([0], (j) => `${j + 2}`) +); +expectType(preservesReadonlyArr); diff --git a/test/tsd/upsert.spec.ts b/test/tsd/upsert.spec.ts index a2603ec..ca8deae 100644 --- a/test/tsd/upsert.spec.ts +++ b/test/tsd/upsert.spec.ts @@ -22,3 +22,10 @@ declare const nullable: { a?: { b: number; c: string } }; expectType(pipe(nullable, upsert("a?", "b", 123))); expectError(pipe(nullable, upsert("a", "a", 123))); expectError(pipe(nullable, upsert("a?.c", "a", 123))); + +// insert into record type +const insertInsideCollection = pipe( + { a: { x: { b: 123 }, y: { b: 456 } } as Record }, + upsert(["a", "?key", "z", "b"], "789") +); +expectType<{ a: Record }>(insertInsideCollection); From b2da3f97c42eadb9e341195afad19d715acaba77 Mon Sep 17 00:00:00 2001 From: Anthony Gabriele Date: Mon, 4 Apr 2022 10:50:28 -0400 Subject: [PATCH 3/7] optimized! modifyw still busted --- src/types/get.ts | 17 +++++----- src/types/modify.ts | 16 ++++----- src/types/modifyF.ts | 22 +++++++------ src/types/modifyOption.ts | 18 +++++------ src/types/modifyOptionW.ts | 11 +++---- src/types/modifyW.ts | 15 ++++----- src/types/remove.ts | 3 +- src/types/rename.ts | 11 +++++-- src/types/set.ts | 11 +++++-- src/types/setOption.ts | 9 +++--- src/types/upsert.ts | 13 ++++++-- src/util/AtPath.ts | 37 +++++++++++---------- src/util/Build.ts | 29 ++++++++++------- src/util/indicies.ts | 17 ++++------ src/util/predicates.ts | 57 ++++++++++++++++----------------- src/util/segments.ts | 55 ++++++++----------------------- test/jest/modifyW.spec.ts | 2 +- test/jest/set.spec.ts | 1 - test/jest/special-characters.ts | 2 +- 19 files changed, 168 insertions(+), 178 deletions(-) diff --git a/src/types/get.ts b/src/types/get.ts index 0e95284..6a3d864 100644 --- a/src/types/get.ts +++ b/src/types/get.ts @@ -4,21 +4,20 @@ import type { Build } from "../util/Build"; import type { IndiciesForPath } from "../util/indicies"; import type { Paths } from "../util/Paths"; import type { GiveOpt, HasOptional } from "../util/predicates"; -import type { AddNullSegments } from "../util/segments"; +import type { Segments } from "../util/segments"; export type Get = < Infer, Path extends unknown extends Infer ? string : Paths, - Ret extends unknown extends Infer ? unknown : GiveOpt>, AddNullSegments> + Ret extends unknown extends Infer ? unknown : GiveOpt, S>, + S extends unknown[] = Segments >( path: Path & string, - ...indicies: IndiciesForPath + ...indicies: IndiciesForPath ) => unknown extends Infer ? unknown extends Ret - ? >( - obj: Constructed - ) => GiveOpt>, AddNullSegments> - : true extends HasOptional - ? (obj: Build] ? A : unknown>) => Ret - : (obj: Build) => Ret + ? >(obj: Constructed) => GiveOpt, S> + : true extends HasOptional + ? (obj: Build] ? A : unknown>) => Ret + : (obj: Build) => Ret : (obj: Infer) => Ret; diff --git a/src/types/modify.ts b/src/types/modify.ts index 99068d6..78ba979 100644 --- a/src/types/modify.ts +++ b/src/types/modify.ts @@ -1,14 +1,14 @@ import type { Paths } from "../util/Paths"; import type { AtPath } from "../util/AtPath"; -import type { AddNullSegments } from "../util/segments"; +import type { Segments } from "../util/segments"; import type { IndiciesForPath } from "../util/indicies"; -export type Modify = , Indicies extends unknown[] = IndiciesForPath>( +export type Modify = < + Infer, + Path extends Paths, + S extends unknown[] = Segments, + A = AtPath +>( path: Path & string, - ...args: [ - ...indicies: Indicies, - modFunc: ( - v: AtPath, "no-traversals"> - ) => AtPath, "no-traversals"> - ] + ...args: [...indicies: IndiciesForPath, modFunc: (v: A) => A] ) => (a: Infer) => Infer; diff --git a/src/types/modifyF.ts b/src/types/modifyF.ts index 83ebdf1..f5ef37c 100644 --- a/src/types/modifyF.ts +++ b/src/types/modifyF.ts @@ -2,7 +2,7 @@ import { Applicative, Applicative1, Applicative2, Applicative3 } from "fp-ts/lib import { HKT, Kind, Kind2, Kind3, URIS, URIS2, URIS3 } from "fp-ts/lib/HKT"; import type { Paths } from "../util/Paths"; import type { AtPath } from "../util/AtPath"; -import { AddNullSegments } from "../util/segments"; +import { Segments } from "../util/segments"; import { IndiciesForPath } from "../util/indicies"; export type ModifyF = { @@ -11,34 +11,38 @@ export type ModifyF = { E, Infer, Path extends Paths, - Val extends AtPath, "no-traversals"> + Val extends AtPath, + S extends unknown[] = Segments >( path: Path & string, - ...args: [...indicies: IndiciesForPath, modFunc: (v: Val) => Kind3] + ...args: [...indicies: IndiciesForPath, modFunc: (v: Val) => Kind3] ) => (a: Infer) => Kind3; (F: Applicative2): < E, Infer, Path extends Paths, - Val extends AtPath, "no-traversals"> + Val extends AtPath, + S extends unknown[] = Segments >( path: Path & string, - ...args: [...indicies: IndiciesForPath, modFunc: (v: Val) => Kind2] + ...args: [...indicies: IndiciesForPath, modFunc: (v: Val) => Kind2] ) => (a: Infer) => Kind2; (F: Applicative1): < Infer, Path extends Paths, - Val extends AtPath, "no-traversals"> + Val extends AtPath, + S extends unknown[] = Segments >( path: Path & string, - ...args: [...indicies: IndiciesForPath, modFunc: (v: Val) => Kind] + ...args: [...indicies: IndiciesForPath, modFunc: (v: Val) => Kind] ) => (a: Infer) => Kind; (F: Applicative): < Infer, Path extends Paths, - Val extends AtPath, "no-traversals"> + Val extends AtPath, + S extends unknown[] = Segments >( path: Path & string, - ...args: [...indicies: IndiciesForPath, modFunc: (v: Val) => HKT] + ...args: [...indicies: IndiciesForPath, modFunc: (v: Val) => HKT] ) => (a: Infer) => HKT; }; diff --git a/src/types/modifyOption.ts b/src/types/modifyOption.ts index 724bfbd..0a4fe23 100644 --- a/src/types/modifyOption.ts +++ b/src/types/modifyOption.ts @@ -2,14 +2,14 @@ import type { AtPath } from "../util/AtPath"; import type { IndiciesForPath } from "../util/indicies"; import type { Paths } from "../util/Paths"; import type { GiveOpt } from "../util/predicates"; -import type { AddNullSegments } from "../util/segments"; +import type { Segments } from "../util/segments"; -export type ModifyOption = >( +export type ModifyOption = < + Infer, + Path extends Paths, + S extends unknown[] = Segments, + A = AtPath +>( path: Path & string, - ...args: [ - ...indicies: IndiciesForPath, - modFunc: ( - v: AtPath, "no-traversals"> - ) => AtPath, "no-traversals"> - ] -) => (a: Infer) => GiveOpt>; + ...args: [...indicies: IndiciesForPath, modFunc: (v: A) => A] +) => (a: Infer) => GiveOpt; diff --git a/src/types/modifyOptionW.ts b/src/types/modifyOptionW.ts index 8fbcdcf..1e329cb 100644 --- a/src/types/modifyOptionW.ts +++ b/src/types/modifyOptionW.ts @@ -2,13 +2,10 @@ import type { Paths } from "../util/Paths"; import type { Build } from "../util/Build"; import type { ApplyTraversals, AtPath } from "../util/AtPath"; import type { GiveOpt } from "../util/predicates"; -import type { AddNullSegments } from "../util/segments"; +import type { Segments } from "../util/segments"; import type { IndiciesForPath } from "../util/indicies"; -export type ModifyOptionW = , RetVal>( +export type ModifyOptionW = , RetVal, S extends unknown[] = Segments>( path: Path & string, - ...args: [ - ...indicies: IndiciesForPath, - modFunc: (v: AtPath, "no-traversals">) => RetVal - ] -) => (a: Infer) => GiveOpt, Path>, Path>; + ...args: [...indicies: IndiciesForPath, modFunc: (v: AtPath) => RetVal] +) => (a: Infer) => GiveOpt, S>, S>; diff --git a/src/types/modifyW.ts b/src/types/modifyW.ts index 346d253..5bb915f 100644 --- a/src/types/modifyW.ts +++ b/src/types/modifyW.ts @@ -2,17 +2,14 @@ import type { Paths } from "../util/Paths"; import type { Build } from "../util/Build"; import type { ApplyTraversals, AtPath } from "../util/AtPath"; import type { HasOptional } from "../util/predicates"; -import type { AddNullSegments } from "../util/segments"; +import type { Segments } from "../util/segments"; import type { IndiciesForPath } from "../util/indicies"; -export type ModifyW = , RetVal>( +export type ModifyW = , RetVal, S extends unknown[] = Segments>( path: Path & string, - ...args: [ - ...indicies: IndiciesForPath, - modFunc: (v: AtPath, "no-traversals">) => RetVal - ] + ...args: [...indicies: IndiciesForPath, modFunc: (v: AtPath) => RetVal] ) => ( a: Infer -) => true extends HasOptional - ? ApplyTraversals>, Infer>, AddNullSegments> - : ApplyTraversals, AddNullSegments>; +) => true extends HasOptional + ? ApplyTraversals, Infer>, S> + : ApplyTraversals, S>; diff --git a/src/types/remove.ts b/src/types/remove.ts index 03a26fd..a4cd563 100644 --- a/src/types/remove.ts +++ b/src/types/remove.ts @@ -1,6 +1,7 @@ import type { Paths } from "../util/Paths"; import type { Build } from "../util/Build"; +import { Segments } from "../util/segments"; export type Remove = >( fullPath: Path & string -) => (a: Infer) => Build; +) => (a: Infer) => Build, unknown, Infer, string, "remove">; diff --git a/src/types/rename.ts b/src/types/rename.ts index 34a3c3f..130c58b 100644 --- a/src/types/rename.ts +++ b/src/types/rename.ts @@ -1,9 +1,14 @@ import type { Paths } from "../util/Paths"; import type { Build } from "../util/Build"; import { AtPath } from "../util/AtPath"; -import { AddNullSegments } from "../util/segments"; +import { Segments } from "../util/segments"; -export type Rename = , NewKey extends string>( +export type Rename = < + Infer, + Path extends Paths, + NewKey extends string, + S extends unknown[] = Segments +>( fullPath: Path & string, newKey: NewKey -) => (a: Infer) => Build>, Infer, NewKey>; +) => (a: Infer) => Build, Infer, NewKey>; diff --git a/src/types/set.ts b/src/types/set.ts index 0e1811b..8972902 100644 --- a/src/types/set.ts +++ b/src/types/set.ts @@ -1,9 +1,14 @@ import type { AtPath } from "../util/AtPath"; import { IndiciesForPath } from "../util/indicies"; import type { Paths } from "../util/Paths"; -import { AddNullSegments } from "../util/segments"; +import { Segments } from "../util/segments"; -export type Set = , Val extends AtPath, "no-traversals">>( +export type Set = < + Infer, + Path extends Paths, + Val extends AtPath, + S extends unknown[] = Segments +>( path: Path & string, - ...args: [...indicies: IndiciesForPath, val: Val] + ...args: [...indicies: IndiciesForPath, val: Val] ) => (obj: Infer) => Infer; diff --git a/src/types/setOption.ts b/src/types/setOption.ts index 9391484..09c43cd 100644 --- a/src/types/setOption.ts +++ b/src/types/setOption.ts @@ -2,13 +2,14 @@ import type { AtPath } from "../util/AtPath"; import type { IndiciesForPath } from "../util/indicies"; import type { Paths } from "../util/Paths"; import type { GiveOpt } from "../util/predicates"; -import type { AddNullSegments } from "../util/segments"; +import type { Segments } from "../util/segments"; export type SetOption = < Infer, Path extends Paths, - Val extends AtPath, "no-traversals"> + Val extends AtPath, + S extends unknown[] = Segments >( path: Path & string, - ...args: [...indicies: IndiciesForPath, val: Val] -) => (obj: Infer) => GiveOpt; + ...args: [...indicies: IndiciesForPath, val: Val] +) => (obj: Infer) => GiveOpt; diff --git a/src/types/upsert.ts b/src/types/upsert.ts index 4e85943..626f1b2 100644 --- a/src/types/upsert.ts +++ b/src/types/upsert.ts @@ -1,9 +1,16 @@ import type { Paths } from "../util/Paths"; import type { Build } from "../util/Build"; import type { IndiciesForPath } from "../util/indicies"; +import { Segments } from "../util/segments"; -export type Upsert = , Final extends string, Val>( +export type Upsert = < + Infer, + Path extends Paths, + Final extends string, + Val, + S extends unknown[] = Segments +>( path: Path & string, final: Final, - ...args: [...indicies: IndiciesForPath, val: Val] -) => (a: Infer) => Build<`${Extract}.${Final}`, Val, Infer>; + ...args: [...indicies: IndiciesForPath, val: Val] +) => (a: Infer) => Build<[...S, Final], Val, Infer>; diff --git a/src/util/AtPath.ts b/src/util/AtPath.ts index a2bbf11..d93964a 100644 --- a/src/util/AtPath.ts +++ b/src/util/AtPath.ts @@ -1,36 +1,35 @@ import { Some } from "fp-ts/Option"; import { Left, Right } from "fp-ts/Either"; -import { FirstSegment, TailSegment, UnescapeParenthesis } from "./segments"; type Operation = "apply-traversals" | "no-traversals"; -export type AtPath = unknown extends A +export type AtPath = unknown extends A ? unknown : Args extends "" ? A : Op extends "apply-traversals" ? ApplyTraversals< - TailSegment extends "" - ? ApplySegment - : AtPath>, TailSegment, "no-traversals">, + Args extends [infer First, ...infer Tail] + ? AtPath>, Tail, "no-traversals"> + : A, Args > - : TailSegment extends "" - ? ApplySegment - : AtPath>, TailSegment, Op>; + : Args extends [infer First, ...infer Tail] + ? AtPath>, Tail, Op> + : A; -export type ApplyTraversals = Args extends "" - ? A - : FirstSegment extends `(${string}` - ? ApplyTraversals> - : FirstSegment extends "[]>" - ? ApplyTraversals> - : FirstSegment extends "{}>" - ? ApplyTraversals, TailSegment> - : ApplyTraversals>; +export type ApplyTraversals = Args extends [infer First, ...infer Tail] + ? First extends `(${string}` + ? ApplyTraversals + : First extends "[]>" + ? ApplyTraversals + : First extends "{}>" + ? ApplyTraversals, Tail> + : ApplyTraversals + : A; -type ApplySegment = Seg extends `(${string}` - ? A[Extract, keyof A>] +type ApplySegment = Seg extends `(${infer Middle})` + ? A[Extract] : Seg extends "?" ? NonNullable : Seg extends "?some" diff --git a/src/util/Build.ts b/src/util/Build.ts index 3ab9b1a..d7429ec 100644 --- a/src/util/Build.ts +++ b/src/util/Build.ts @@ -2,27 +2,32 @@ import { Option } from "fp-ts/Option"; import { Either, Left, Right } from "fp-ts/Either"; import type { AtPath } from "./AtPath"; import { IsRecord } from "./predicates"; -import { AddNullSegments, InitSegment, LastSegment, UnescapeParenthesis } from "./segments"; type Operation = "augment" | "remove"; export type Build< - Path extends string, + Segments extends unknown[], Output, Original = unknown, NewKey extends string = string, Op extends Operation = "augment" -> = _Build, Output, Original, NewKey, Op>; +> = _Build; -type _Build = Path extends "" - ? Output - : _Build< - InitSegment, - BuildSegment, AtPath, "no-traversals">, Output, NewKey, Op>, +type _Build< + Segments extends unknown[], + Output, + Original, + NewKey extends string, + Op extends Operation +> = Segments extends [...infer Init, infer Last] + ? _Build< + Init, + BuildSegment, AtPath, Output, NewKey, Op>, Original, string, "augment" - >; + > + : Output; type BuildSegment = unknown extends Old ? FromScratch @@ -44,7 +49,7 @@ type FromScratch = OnSegment< } & { readonly [K in Discriminant]: string } : never; tuple: New[] & { readonly [K in Segment]: New }; - record: { readonly [K in UnescapeParenthesis]: New }; + record: { readonly [K in Segment extends `(${infer Middle})` ? Middle : Segment]: New }; } >; @@ -66,7 +71,9 @@ type Augment> : never; tuple: Segment extends `[${infer TupleKey}]` ? AugmentRecord : never; - record: true extends IsRecord ? AugmentRecord, Old, New, NewKey, Op> : never; + record: true extends IsRecord + ? AugmentRecord + : never; } >; diff --git a/src/util/indicies.ts b/src/util/indicies.ts index 117065b..14bae90 100644 --- a/src/util/indicies.ts +++ b/src/util/indicies.ts @@ -1,10 +1,7 @@ -import { AddNullSegments, FirstSegment, TailSegment } from "./segments"; -export type IndiciesForPath

= _IndiciesForPath>; - -type _IndiciesForPath

= FirstSegment

extends "" - ? Acc - : FirstSegment

extends "[number]" - ? _IndiciesForPath, [...Acc, number]> - : FirstSegment

extends "[string]" - ? _IndiciesForPath, [...Acc, string]> - : _IndiciesForPath, Acc>; +export type IndiciesForPath

= P extends [infer First, ...infer Tail] + ? First extends "[number]" + ? IndiciesForPath + : First extends "[string]" + ? IndiciesForPath + : IndiciesForPath + : Acc; diff --git a/src/util/predicates.ts b/src/util/predicates.ts index e553ede..9aabd91 100644 --- a/src/util/predicates.ts +++ b/src/util/predicates.ts @@ -1,47 +1,46 @@ import type { Option } from "fp-ts/Option"; -import { AddNullSegments, FirstSegment, TailSegment } from "./segments"; export type TupleKeyof = Exclude>; -export type GiveOpt = true extends HasTraversals> +export type GiveOpt = true extends HasTraversals ? A - : true extends HasNull> + : true extends HasNull ? Option - : true extends HasSum> + : true extends HasSum ? Option : A; -export type HasOptional = true extends HasNull> +export type HasOptional = true extends HasNull ? true - : true extends HasSum> + : true extends HasSum ? true : never; -type HasSum = Args extends "" - ? never - : FirstSegment extends `(${string}` - ? HasSum> - : FirstSegment extends `${string}:${string}` - ? true - : FirstSegment extends "[number]" - ? true - : HasSum>; +type HasSum = Args extends [infer First, ...infer Tail] + ? First extends `(${string})` + ? HasSum + : First extends `${string}:${string}` + ? true + : First extends "[number]" + ? true + : HasSum + : never; -type HasNull = Args extends "" - ? never - : FirstSegment extends `(${string}` - ? HasNull> - : FirstSegment extends `${string}?${string}` - ? true - : HasNull>; +type HasNull = Args extends [infer First, ...infer Tail] + ? First extends `(${string})` + ? HasNull + : First extends `${string}?${string}` + ? true + : HasNull + : never; -type HasTraversals = Args extends "" - ? never - : FirstSegment extends `(${string}` - ? HasTraversals> - : FirstSegment extends "[]>" | "{}>" - ? true - : HasTraversals>; +type HasTraversals = Args extends [infer First, ...infer Tail] + ? First extends `(${string})` + ? HasTraversals + : First extends "[]>" | "{}>" + ? true + : HasTraversals + : never; export type IsNull = undefined extends A ? true : null extends A ? true : never; diff --git a/src/util/segments.ts b/src/util/segments.ts index e12e3c5..2253e4a 100644 --- a/src/util/segments.ts +++ b/src/util/segments.ts @@ -4,7 +4,7 @@ type ShouldUnescape = S extends `(${infer Rest}` ? true : never; -export type FirstSegment = true extends ShouldUnescape +type FirstSegment = true extends ShouldUnescape ? FirstEscapedSegment : S extends `(${infer Middle})${string}` ? `(${Middle})` @@ -14,16 +14,16 @@ export type FirstSegment = true extends ShouldUnescape type FirstEscapedSegment< S extends string, - Acc extends string = "*" + Acc extends string = "" > = S extends `(${infer Parens}*${infer Middle})${infer Rest}` ? Parens extends "" ? `(${Acc}${Middle})` - : FirstEscapedSegment<`${Parens}*${Rest}`, `(${Acc}${Middle})`> + : FirstEscapedSegment<`${Parens}*${Rest}`, `${Acc}${Middle})`> : S extends `(${infer Middle})${string}` ? `(${Middle})` : S; -export type TailSegment = true extends ShouldUnescape +type TailSegment = true extends ShouldUnescape ? TailEscapedSegment : S extends `(${string})${infer Tail}` ? Tail extends `.${infer AfterDot}` @@ -41,33 +41,17 @@ type TailEscapedSegment = S extends `(${infer Parens}*${string : TailEscapedSegment<`${Parens}*${Rest}`> : S; -export type InitSegment = S extends `(${string}` - ? TailEscapedSegment extends "" - ? Acc - : InitSegment, Acc extends "" ? FirstEscapedSegment : `${Acc}.${FirstEscapedSegment}`> - : S extends `${infer Head}.${infer Tail}` - ? InitSegment - : Acc; - -export type LastSegment = S extends `(${string}` - ? TailEscapedSegment extends "" - ? S - : LastSegment> - : S extends `${string}.${infer Tail}` - ? LastSegment - : S; - -export type AddNullSegments = S extends "" +export type Segments> = S extends "" ? Acc - : FirstSegment extends `(${string})` - ? AddNullSegments, Acc extends "" ? FirstSegment : `${Acc}.${FirstSegment}`> - : FirstSegment extends "?" - ? AddNullSegments, Acc extends "" ? "?" : `${Acc}.?`> - : FirstSegment extends `${infer First}?` - ? AddNullSegments, Acc extends "" ? `${First}.?` : `${Acc}.${First}.?`> - : FirstSegment extends `(${infer Middle})?` - ? AddNullSegments, Acc extends "" ? `(${Middle}).?` : `${Acc}.(${Middle}).?`> - : AddNullSegments, Acc extends "" ? FirstSegment : `${Acc}.${FirstSegment}`>; + : First extends `(${string})` + ? Segments, Acc extends [] ? [First] : [...Acc, First]> + : First extends "?" + ? Segments, Acc extends [] ? ["?"] : [...Acc, "?"]> + : First extends `${infer First}?` + ? Segments, Acc extends [] ? [First, "?"] : [...Acc, First, "?"]> + : First extends `(${infer Middle})?` + ? Segments, Acc extends [] ? [`(${Middle})`, "?"] : [...Acc, `(${Middle})`, "?"]> + : Segments, Acc extends [] ? [First] : [...Acc, First]>; export type EscapeSpecialChars = S extends `${string})${string}` ? EscapeParenthesis @@ -89,14 +73,3 @@ type EscapeParenthesis = `(${StartingParens}*${S})`; type StartingParens = S extends `${string})${infer Tail}` ? StartingParens : Acc; - -export type UnescapeParenthesis< - S extends string, - Acc extends string = "" -> = S extends `(${infer Parens}*${infer Middle})${infer Rest}` - ? Parens extends "" - ? `${Acc}${Middle}` - : UnescapeParenthesis<`${Parens}*${Rest}`, `${Acc}${Middle})`> - : S extends `(${infer Middle})` - ? Middle - : S; diff --git a/test/jest/modifyW.spec.ts b/test/jest/modifyW.spec.ts index a5051c4..1bb0113 100644 --- a/test/jest/modifyW.spec.ts +++ b/test/jest/modifyW.spec.ts @@ -29,7 +29,7 @@ describe("modifyW", () => { it("widens a collection's type", () => { const collectionWidensType = pipe( { a: [123, 456] }, - modifyW(["a", 0], (j) => `${j + 2}`) + modifyW("a.[number]", 0, (j) => `${j + 2}`) ); assert.deepStrictEqual(collectionWidensType, { a: ["125", 456] }); }); diff --git a/test/jest/set.spec.ts b/test/jest/set.spec.ts index 1ab8bd1..c9b73b4 100644 --- a/test/jest/set.spec.ts +++ b/test/jest/set.spec.ts @@ -11,7 +11,6 @@ describe("set", () => { }); it("modifies an optional value", () => { const optSet: Data = pipe(data, set("type:A.a.?some.c", -123)); - const optSet2: Data = pipe(data, set("type:A.a.?some.d.[number]", 0, "cde")); assert.deepStrictEqual(optSet, { type: "A", a: O.some({ diff --git a/test/jest/special-characters.ts b/test/jest/special-characters.ts index 0a54f27..c491672 100644 --- a/test/jest/special-characters.ts +++ b/test/jest/special-characters.ts @@ -21,7 +21,7 @@ describe("special characters", () => { }, }, }, - get("().(colon:char).(end?).(?front).(middle?middle).([]>)") + get("().(colon:char).(end?).(?front).(middle?middle).([]>).({}>)") ); assert.deepStrictEqual(specialCharKeys, 123); }); From 66b2f8c7aa4ee8f6cbdc50b113c8b98d32057d42 Mon Sep 17 00:00:00 2001 From: Anthony Gabriele Date: Mon, 4 Apr 2022 14:25:35 -0400 Subject: [PATCH 4/7] resolve errs --- src/types/modifyOptionW.ts | 16 +++++++++++----- src/types/modifyW.ts | 20 +++++++++++--------- src/types/upsert.ts | 6 ++++-- src/util/AtPath.ts | 2 +- src/util/Build.ts | 12 ++---------- src/util/Paths.ts | 12 ++++++------ src/util/monocle.ts | 3 ++- src/util/predicates.ts | 28 ++++++++++++++++++++++++---- test/jest/modify.spec.ts | 2 +- test/jest/modifyF.spec.ts | 6 +++--- test/jest/modifyOptionW.spec.ts | 2 +- test/tsd/get.spec.ts | 2 +- test/tsd/modifyF.spec.ts | 2 +- test/tsd/modifyOptionW.spec.ts | 2 +- test/tsd/modifyW.spec.ts | 10 +++++----- test/tsd/upsert.spec.ts | 7 ------- 16 files changed, 74 insertions(+), 58 deletions(-) diff --git a/src/types/modifyOptionW.ts b/src/types/modifyOptionW.ts index 1e329cb..eb4bc47 100644 --- a/src/types/modifyOptionW.ts +++ b/src/types/modifyOptionW.ts @@ -1,11 +1,17 @@ import type { Paths } from "../util/Paths"; import type { Build } from "../util/Build"; -import type { ApplyTraversals, AtPath } from "../util/AtPath"; -import type { GiveOpt } from "../util/predicates"; +import type { AtPath } from "../util/AtPath"; +import type { GiveOpt, HasIndexedAccess } from "../util/predicates"; import type { Segments } from "../util/segments"; import type { IndiciesForPath } from "../util/indicies"; -export type ModifyOptionW = , RetVal, S extends unknown[] = Segments>( +export type ModifyOptionW = < + Infer, + Path extends Paths, + RetVal, + S extends unknown[] = Segments, + A = AtPath +>( path: Path & string, - ...args: [...indicies: IndiciesForPath, modFunc: (v: AtPath) => RetVal] -) => (a: Infer) => GiveOpt, S>, S>; + ...args: [...indicies: IndiciesForPath, modFunc: (v: A) => RetVal] +) => (a: Infer) => GiveOpt ? RetVal | AtPath : RetVal, Infer>, S>; diff --git a/src/types/modifyW.ts b/src/types/modifyW.ts index 5bb915f..0c55306 100644 --- a/src/types/modifyW.ts +++ b/src/types/modifyW.ts @@ -1,15 +1,17 @@ import type { Paths } from "../util/Paths"; import type { Build } from "../util/Build"; -import type { ApplyTraversals, AtPath } from "../util/AtPath"; -import type { HasOptional } from "../util/predicates"; +import type { AtPath } from "../util/AtPath"; +import type { HasIndexedAccess } from "../util/predicates"; import type { Segments } from "../util/segments"; import type { IndiciesForPath } from "../util/indicies"; -export type ModifyW = , RetVal, S extends unknown[] = Segments>( +export type ModifyW = < + Infer, + Path extends Paths, + RetVal, + S extends unknown[] = Segments, + A = AtPath +>( path: Path & string, - ...args: [...indicies: IndiciesForPath, modFunc: (v: AtPath) => RetVal] -) => ( - a: Infer -) => true extends HasOptional - ? ApplyTraversals, Infer>, S> - : ApplyTraversals, S>; + ...args: [...indicies: IndiciesForPath, modFunc: (v: A) => RetVal] +) => (a: Infer) => Build ? RetVal | AtPath : RetVal, Infer>; diff --git a/src/types/upsert.ts b/src/types/upsert.ts index 626f1b2..9c38b87 100644 --- a/src/types/upsert.ts +++ b/src/types/upsert.ts @@ -1,7 +1,9 @@ import type { Paths } from "../util/Paths"; import type { Build } from "../util/Build"; import type { IndiciesForPath } from "../util/indicies"; -import { Segments } from "../util/segments"; +import type { HasIndexedAccess } from "../util/predicates"; +import type { Segments } from "../util/segments"; +import type { AtPath } from "../util/AtPath"; export type Upsert = < Infer, @@ -13,4 +15,4 @@ export type Upsert = < path: Path & string, final: Final, ...args: [...indicies: IndiciesForPath, val: Val] -) => (a: Infer) => Build<[...S, Final], Val, Infer>; +) => (a: Infer) => Build<[...S, Final], true extends HasIndexedAccess ? AtPath | Val : Val, Infer>; diff --git a/src/util/AtPath.ts b/src/util/AtPath.ts index d93964a..fd49e96 100644 --- a/src/util/AtPath.ts +++ b/src/util/AtPath.ts @@ -39,7 +39,7 @@ type ApplySegment = Seg extends `(${infer Middle})` : Seg extends "?right" ? Extract>["right"] : Seg extends "[]>" | "[number]" - ? Extract[number] + ? Extract[number] : Seg extends "{}>" | "[string]" ? Extract>[string] : Seg extends `[${infer TupleIndex}]` diff --git a/src/util/Build.ts b/src/util/Build.ts index d7429ec..ae23e91 100644 --- a/src/util/Build.ts +++ b/src/util/Build.ts @@ -11,16 +11,8 @@ export type Build< Original = unknown, NewKey extends string = string, Op extends Operation = "augment" -> = _Build; - -type _Build< - Segments extends unknown[], - Output, - Original, - NewKey extends string, - Op extends Operation > = Segments extends [...infer Init, infer Last] - ? _Build< + ? Build< Init, BuildSegment, AtPath, Output, NewKey, Op>, Original, @@ -60,7 +52,7 @@ type Augment; left: Either>["right"]>; right: Either>["left"], New>; - arrayIndex: New[]; + arrayIndex: { [K in keyof Old]: New }; recordIndex: Record; traversal: New[]; sum: Segment extends `${infer Discriminant}:${infer Member}` diff --git a/src/util/Paths.ts b/src/util/Paths.ts index e3588e1..a1f3fbb 100644 --- a/src/util/Paths.ts +++ b/src/util/Paths.ts @@ -1,7 +1,7 @@ import type { Option, Some } from "fp-ts/Option"; import type { Either, Left, Right } from "fp-ts/Either"; import type { IsNull, IsRecord, IsNonTupleArray, TupleKeyof, IsNonStructRecord } from "./predicates"; -import { EscapeSpecialChars, LastSegment } from "./segments"; +import { EscapeSpecialChars } from "./segments"; import type { Cases, Discriminant } from "./sum"; // Credit to Stefan Baumgartner @@ -39,7 +39,7 @@ type NonStructRecordChildren = keyof { type BubbleUp> = UnionToIntersection< | { [K in RecordChildren]: { - [K2 in TupleKeyof as A[K] extends unknown[] + [K2 in TupleKeyof as A[K] extends readonly unknown[] ? K extends "" ? `[${Extract}]` : `${Extract}.[${Extract}]` @@ -98,14 +98,14 @@ type BubbleSum< }[Case["tag"]] : never >; - +/* type ExtractChangeableKeys = K extends string ? LastSegment extends `${string}:${string}` ? never : LastSegment extends `${string}?${string}` ? never : K - : never; + : never; */ type UpsertableKeys = Extract< keyof { @@ -127,13 +127,13 @@ type _Paths = true extends ? Extract : Op extends "upsert" ? UpsertableKeys - : ExtractChangeableKeys) + : Extract) //ExtractChangeableKeys) > : Acc; // Not tail recursive!! type EscapeKeys = A extends Record - ? A extends unknown[] + ? A extends readonly unknown[] ? A : { [K in keyof A as EscapeSpecialChars>]: EscapeKeys; diff --git a/src/util/monocle.ts b/src/util/monocle.ts index 6f04823..56ae289 100644 --- a/src/util/monocle.ts +++ b/src/util/monocle.ts @@ -9,7 +9,8 @@ import * as Tr from "monocle-ts/lib/Traversal"; export const isPathLens = (path: string): boolean => !split(path).some( (s) => - ["?", "?some", "?left", "right", "[]>", "{}>", "[number]"].includes(s) || (!s.startsWith("(") && s.includes(":")) + ["?", "?some", "?left", "right", "[]>", "{}>", "[number]", "[string]"].includes(s) || + (!s.startsWith("(") && s.includes(":")) ); export const isPathTraversal = (path: string): boolean => split(path).some((s) => ["[]>", "{}>"].includes(s)); diff --git a/src/util/predicates.ts b/src/util/predicates.ts index 9aabd91..d87c0f2 100644 --- a/src/util/predicates.ts +++ b/src/util/predicates.ts @@ -8,12 +8,24 @@ export type GiveOpt = true extends HasTraversals : true extends HasSum ? Option + : true extends HasIndexedAccess + ? Option : A; export type HasOptional = true extends HasNull ? true : true extends HasSum ? true + : true extends HasIndexedAccess + ? true + : never; + +export type HasIndexedAccess = Args extends [infer First, ...infer Tail] + ? First extends "[number]" + ? true + : First extends "[string]" + ? true + : HasIndexedAccess : never; type HasSum = Args extends [infer First, ...infer Tail] @@ -21,15 +33,19 @@ type HasSum = Args extends [infer First, ...infer Tail] ? HasSum : First extends `${string}:${string}` ? true - : First extends "[number]" - ? true : HasSum : never; type HasNull = Args extends [infer First, ...infer Tail] ? First extends `(${string})` ? HasNull - : First extends `${string}?${string}` + : First extends `${string}?` + ? true + : First extends `?some` + ? true + : First extends `?left` + ? true + : First extends `?right` ? true : HasNull : never; @@ -46,6 +62,10 @@ export type IsNull = undefined extends A ? true : null extends A ? true : nev export type IsRecord = unknown extends A ? never : [A] extends [Record] ? true : never; -export type IsNonTupleArray = [A] extends [unknown[]] ? (TupleKeyof extends never ? true : never) : never; +export type IsNonTupleArray = [A] extends [readonly unknown[]] + ? TupleKeyof extends never + ? true + : never + : never; export type IsNonStructRecord = string extends keyof A ? true : never; diff --git a/test/jest/modify.spec.ts b/test/jest/modify.spec.ts index b0cc535..e99fe0d 100644 --- a/test/jest/modify.spec.ts +++ b/test/jest/modify.spec.ts @@ -8,7 +8,7 @@ describe("modify", () => { it("modifies a definite value", () => { const modified: SimpleData = pipe( simpleData, - modify("a.b.[1]", (j) => j + 4) + modify("a.b.[0]", (j) => j + 4) ); assert.deepStrictEqual(modified, { a: { b: [127, "abc", false], c: "def", d: false }, e: 456 }); }); diff --git a/test/jest/modifyF.spec.ts b/test/jest/modifyF.spec.ts index ed25d8e..25fd71f 100644 --- a/test/jest/modifyF.spec.ts +++ b/test/jest/modifyF.spec.ts @@ -2,13 +2,13 @@ import { pipe } from "fp-ts/function"; import * as E from "fp-ts/Either"; import * as assert from "assert"; import { modifyF } from "../../src"; -import { SimpleData, simpleData } from "../shared"; +import { simpleData } from "../shared"; describe("modifyF", () => { it("modifies a value", () => { - const modified: E.Either = pipe( + const modified = pipe( simpleData, - modifyF(E.Applicative)("a.b.[0]", (b) => (b < 100 ? E.right(100) : E.left("never mind"))) + modifyF(E.Applicative)("a.b.[0]", (b) => (b < 100 ? E.right(100) : E.left("never mind"))) ); assert.deepStrictEqual(modified, E.left("never mind")); }); diff --git a/test/jest/modifyOptionW.spec.ts b/test/jest/modifyOptionW.spec.ts index dcb09bc..13ffa07 100644 --- a/test/jest/modifyOptionW.spec.ts +++ b/test/jest/modifyOptionW.spec.ts @@ -46,7 +46,7 @@ describe("modifyOptionW", () => { it("widens a collection's type", () => { const collectionWidensType = pipe( { a: [123, 456] }, - modifyOptionW(["a", 0], (j) => `${j + 2}`) + modifyOptionW("a.[number]", 0, (j) => `${j + 2}`) ); assert.deepStrictEqual(collectionWidensType, O.some({ a: ["125", 456] })); }); diff --git a/test/tsd/get.spec.ts b/test/tsd/get.spec.ts index 024602f..b3335e8 100644 --- a/test/tsd/get.spec.ts +++ b/test/tsd/get.spec.ts @@ -17,7 +17,7 @@ expectError>(optional); // has checked record access const record = { a: 123 } as Record; -const picked2 = pipe(record, get("?key", "b")); +const picked2 = pipe(record, get("[string]", "b")); expectType>(picked2); // can traverse arrays diff --git a/test/tsd/modifyF.spec.ts b/test/tsd/modifyF.spec.ts index 0616ced..e39ba3a 100644 --- a/test/tsd/modifyF.spec.ts +++ b/test/tsd/modifyF.spec.ts @@ -7,6 +7,6 @@ import { SimpleData, simpleData } from "../shared"; // modifies a definite value const modified = pipe( simpleData, - modifyF(E.Applicative)("a.b.[0]", (b) => (b > 30 ? E.right(40) : E.left("never mind"))) + modifyF(E.Applicative)("a.b.[0]", (b) => (b > 30 ? E.right(40) : E.left("never mind"))) ); expectType>(modified); diff --git a/test/tsd/modifyOptionW.spec.ts b/test/tsd/modifyOptionW.spec.ts index 826da7d..c9d6aa4 100644 --- a/test/tsd/modifyOptionW.spec.ts +++ b/test/tsd/modifyOptionW.spec.ts @@ -43,7 +43,7 @@ expectType>(optionalReplacesType); const collectionWidensType = pipe( { a: [123, 456] }, - modifyOptionW(["a", 0], (j) => `${j + 2}`) + modifyOptionW("a.[number]", 0, (j) => `${j + 2}`) ); expectType>(collectionWidensType); diff --git a/test/tsd/modifyW.spec.ts b/test/tsd/modifyW.spec.ts index d652b85..f63302a 100644 --- a/test/tsd/modifyW.spec.ts +++ b/test/tsd/modifyW.spec.ts @@ -25,7 +25,7 @@ expectType< | B | { a: O.Option<{ - c: string | number; + c: string; d: string[]; e: boolean; }>; @@ -33,20 +33,20 @@ expectType< } >(modifyOptional); -const optionalWidensType = pipe( +const optionalReplacesType = pipe( { a: 123 } as { a: number | undefined }, modifyW("a?", (j) => `${j + 2}`) ); -expectType<{ a: string | number | undefined }>(optionalWidensType); +expectType<{ a: string | undefined }>(optionalReplacesType); const collectionWidensType = pipe( { a: [123, 456] }, - modifyW(["a", 0], (j) => `${j + 2}`) + modifyW("a.[number]", 0, (j) => `${j + 2}`) ); expectType<{ a: (string | number)[] }>(collectionWidensType); const preservesReadonlyArr = pipe( [123, 456] as readonly number[], - modifyW([0], (j) => `${j + 2}`) + modifyW("[number]", 0, (j) => `${j + 2}`) ); expectType(preservesReadonlyArr); diff --git a/test/tsd/upsert.spec.ts b/test/tsd/upsert.spec.ts index ca8deae..a2603ec 100644 --- a/test/tsd/upsert.spec.ts +++ b/test/tsd/upsert.spec.ts @@ -22,10 +22,3 @@ declare const nullable: { a?: { b: number; c: string } }; expectType(pipe(nullable, upsert("a?", "b", 123))); expectError(pipe(nullable, upsert("a", "a", 123))); expectError(pipe(nullable, upsert("a?.c", "a", 123))); - -// insert into record type -const insertInsideCollection = pipe( - { a: { x: { b: 123 }, y: { b: 456 } } as Record }, - upsert(["a", "?key", "z", "b"], "789") -); -expectType<{ a: Record }>(insertInsideCollection); From 41d87f62ccf46ee954c64c3ef312bfe91b8ad2ed Mon Sep 17 00:00:00 2001 From: Anthony Gabriele Date: Tue, 5 Apr 2022 13:40:27 -0400 Subject: [PATCH 5/7] put in commit history --- PathIdea2.md | 25 ++ package.json | 3 +- src/util/Paths.ts | 202 ++++++++-------- src/util/Paths2.ts | 141 +++++++++++ src/util/Paths3.ts | 96 ++++++++ src/util/Paths4.ts | 93 ++++++++ src/util/predicates.ts | 2 +- src/util/segments.ts | 13 ++ test/tsd/set.spec.ts | 4 +- yarn.lock | 514 ++++++++++++++++++++++++++++++++++++++++- 10 files changed, 973 insertions(+), 120 deletions(-) create mode 100644 PathIdea2.md create mode 100644 src/util/Paths2.ts create mode 100644 src/util/Paths3.ts create mode 100644 src/util/Paths4.ts diff --git a/PathIdea2.md b/PathIdea2.md new file mode 100644 index 0000000..a8c10a4 --- /dev/null +++ b/PathIdea2.md @@ -0,0 +1,25 @@ +# Build (tail recursive) + +```ts +_Obj1 = { a: { b: number, x: boolean }, c: { d: { e: string } } } +Obj1 = [ + { path: ['a']; value: { b: number, x: boolean} }, + { path: ['c']; value: { d: { e: string } } +] +Output1 = ['a'] | ['c'] + | + V +Obj2 = [ + { path: ['a', 'b']; value: number }, + { path: ['a', 'x']; value: boolean } + { path: ['c', 'd']; value: { e: string } } +] +Output2 = ['a', 'b'] | ['a', 'x'] | ['c', 'd'] + | + V +Obj3 = [ + { path: ['c', 'd', 'e']; value: string } +] +Output3 = ['c', 'd', 'e'] + +``` \ No newline at end of file diff --git a/package.json b/package.json index c7bf718..0524a7f 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,8 @@ }, "dependencies": { "fp-ts-std": "^0.10.1", - "monocle-ts": "^2.3.5" + "monocle-ts": "^2.3.5", + "ts-toolbelt": "^9.6.0" }, "devDependencies": { "@types/jest": "^26.0.20", diff --git a/src/util/Paths.ts b/src/util/Paths.ts index a1f3fbb..a3b1571 100644 --- a/src/util/Paths.ts +++ b/src/util/Paths.ts @@ -1,87 +1,69 @@ import type { Option, Some } from "fp-ts/Option"; import type { Either, Left, Right } from "fp-ts/Either"; -import type { IsNull, IsRecord, IsNonTupleArray, TupleKeyof, IsNonStructRecord } from "./predicates"; -import { EscapeSpecialChars } from "./segments"; +import type { IsNull, IsRecord, TupleKeyof } from "./predicates"; +import type { EscapeSpecialChars } from "./segments"; import type { Cases, Discriminant } from "./sum"; -// Credit to Stefan Baumgartner -// https://fettblog.eu/typescript-union-to-intersection/ -type UnionToIntersection = (T extends any ? (x: T) => any : never) extends (x: infer R) => any ? R : never; - -type RecordChildren = keyof { - [K in TupleKeyof as true extends IsRecord - ? Discriminant extends never - ? true extends IsNonTupleArray - ? never - : true extends IsNonStructRecord - ? never - : K - : never - : never]: unknown; -}; - -type SumChildren = keyof { - [K in TupleKeyof as Discriminant extends never ? never : K]: unknown; -}; +type Operation = "static" | "dynamic" | "upsert"; -type NullableChildren = keyof { - [K in TupleKeyof as true extends IsNull ? K : never]: unknown; -}; +export type Paths = _Paths<{ "": A }, Op>; -type ArrayChildren = keyof { - [K in TupleKeyof as true extends IsNonTupleArray ? K : never]: unknown; -}; +type _Paths = true extends IsRecord + ? _Paths< + keyof A extends never ? unknown : BubbleUp, + Op, + | Acc + | (Op extends "static" + ? Extract + : Op extends "upsert" + ? UpsertableKeys + : ExtractChangeableKeys) + > + : Acc; -type NonStructRecordChildren = keyof { - [K in TupleKeyof as true extends IsNonStructRecord ? K : never]: unknown; -}; +type BubbleUp> = UnionToIntersection>>; -type BubbleUp> = UnionToIntersection< - | { - [K in RecordChildren]: { - [K2 in TupleKeyof as A[K] extends readonly unknown[] - ? K extends "" - ? `[${Extract}]` - : `${Extract}.[${Extract}]` - : K extends "" - ? Extract - : `${Extract}.${Extract}`]: A[K][K2]; - }; - }[RecordChildren] - | { - [K in SumChildren]: Option extends A[K] - ? Record< - K, - { - "?some": Extract>["value"]; - } - > - : Either extends A[K] - ? Record< - K, - { - "?left": Extract>["left"]; - "?right": Extract>["right"]; - } - > - : Record>; - }[SumChildren] - | { - [K in NullableChildren]-?: { - [K2 in K as `${Extract}?`]: NonNullable; - }; - }[NullableChildren] - | { - [K in ArrayChildren]: { - [K2 in K as K extends "" ? "[]>" | "[number]" : `${Extract}.${"[]>" | "[number]"}`]: A[K][number]; +type _BubbleUp> = { + [K in TupleKeyof]-?: Match< + A[K], + { + nullable: Record<`${Extract}?`, NonNullable>; + struct: { + [K2 in keyof A[K] as `${Extract}${Extract extends "" ? "" : "."}${EscapeSpecialChars< + Extract + >}`]: A[K][K2]; }; - }[ArrayChildren] - | { - [K in NonStructRecordChildren]: { - [K2 in K as K extends "" ? "{}>" | "[string]" : `${Extract}.${"{}>" | "[string]"}`]: A[K][number]; + tuple: { + [K2 in keyof A[K] as `${Extract}${Extract extends "" ? "" : "."}[${Extract< + K2, + string + >}]`]: A[K][K2]; }; - }[NonStructRecordChildren] ->; + record: Record< + `${Extract}${Extract extends "" ? "" : "."}${"[string]" | "{}>"}`, + A[K][string] + >; + array: Record< + `${Extract}${Extract extends "" ? "" : "."}${"[number]" | "[]>"}`, + A[K][number] + >; + option: Record< + `${Extract}${Extract extends "" ? "" : "."}?some`, + Extract>["value"] + >; + either: Record< + `${Extract}${Extract extends "" ? "" : "."}?left`, + Extract>["left"] + > & + Record< + `${Extract}${Extract extends "" ? "" : "."}?right`, + Extract>["right"] + >; + sum: BubbleSum; + other: never; + } + >; +}; type BubbleSum< A, @@ -98,14 +80,37 @@ type BubbleSum< }[Case["tag"]] : never >; -/* -type ExtractChangeableKeys = K extends string - ? LastSegment extends `${string}:${string}` - ? never - : LastSegment extends `${string}?${string}` - ? never - : K - : never; */ + +type Match< + A, + Matches extends { + struct: unknown; + record: unknown; + tuple: unknown; + array: unknown; + nullable: unknown; + option: unknown; + either: unknown; + sum: unknown; + other: unknown; + } +> = Discriminant extends never + ? [A] extends [readonly unknown[]] + ? TupleKeyof extends never + ? Matches["array"] + : Matches["tuple"] + : string extends keyof A + ? Matches["record"] + : true extends IsRecord + ? Matches["struct"] + : true extends IsNull + ? Matches["nullable"] + : Matches["other"] + : Option extends A + ? Matches["option"] + : Either extends A + ? Matches["either"] + : Matches["sum"]; type UpsertableKeys = Extract< keyof { @@ -114,28 +119,15 @@ type UpsertableKeys = Extract< string >; -type Operation = "static" | "dynamic" | "upsert"; - -export type Paths = _Paths<{ "": EscapeKeys }, Op>; +type ExtractChangeableKeys = Extract< + keyof { + [K in keyof A as true extends IsNull ? never : Discriminant extends never ? K : never]: unknown; + }, + string +>; -type _Paths = true extends IsRecord - ? _Paths< - keyof A extends never ? unknown : BubbleUp, - Op, - | Acc - | (Op extends "static" - ? Extract - : Op extends "upsert" - ? UpsertableKeys - : Extract) //ExtractChangeableKeys) - > - : Acc; +// Credit to Stefan Baumgartner +// https://fettblog.eu/typescript-union-to-intersection/ +type UnionToIntersection = (T extends any ? (x: T) => any : never) extends (x: infer R) => any ? R : never; -// Not tail recursive!! -type EscapeKeys = A extends Record - ? A extends readonly unknown[] - ? A - : { - [K in keyof A as EscapeSpecialChars>]: EscapeKeys; - } - : A; +type ValueOf = A[keyof A]; diff --git a/src/util/Paths2.ts b/src/util/Paths2.ts new file mode 100644 index 0000000..d8c9163 --- /dev/null +++ b/src/util/Paths2.ts @@ -0,0 +1,141 @@ +import type { Option, Some } from "fp-ts/Option"; +import type { Either, Left, Right } from "fp-ts/Either"; +import type { IsNull, IsRecord, IsNonTupleArray, TupleKeyof, IsNonStructRecord } from "./predicates"; +import { EscapeSpecialChars } from "./segments"; +import type { Cases, Discriminant } from "./sum"; + +// Credit to Stefan Baumgartner +// https://fettblog.eu/typescript-union-to-intersection/ +type UnionToIntersection = (T extends any ? (x: T) => any : never) extends (x: infer R) => any ? R : never; + +type RecordChildren = keyof { + [K in TupleKeyof as true extends IsRecord + ? Discriminant extends never + ? true extends IsNonTupleArray + ? never + : true extends IsNonStructRecord + ? never + : K + : never + : never]: unknown; +}; + +type SumChildren = keyof { + [K in TupleKeyof as Discriminant extends never ? never : K]: unknown; +}; + +type NullableChildren = keyof { + [K in TupleKeyof as true extends IsNull ? K : never]: unknown; +}; + +type ArrayChildren = keyof { + [K in TupleKeyof as true extends IsNonTupleArray ? K : never]: unknown; +}; + +type NonStructRecordChildren = keyof { + [K in TupleKeyof as true extends IsNonStructRecord ? K : never]: unknown; +}; + +type BubbleUp> = UnionToIntersection< + | { + [K in RecordChildren]: { + [K2 in TupleKeyof as A[K] extends readonly unknown[] + ? K extends "" + ? `[${Extract}]` + : `${Extract}.[${Extract}]` + : K extends "" + ? Extract + : `${Extract}.${Extract}`]: A[K][K2]; + }; + }[RecordChildren] + | { + [K in SumChildren]: Option extends A[K] + ? Record< + K, + { + "?some": Extract>["value"]; + } + > + : Either extends A[K] + ? Record< + K, + { + "?left": Extract>["left"]; + "?right": Extract>["right"]; + } + > + : Record>; + }[SumChildren] + | { + [K in NullableChildren]-?: Record<`${Extract}?`, NonNullable>; + }[NullableChildren] + | { + [K in ArrayChildren]: Record< + K extends "" ? "[]>" | "[number]" : `${Extract}.${"[]>" | "[number]"}`, + A[K][number] + >; + }[ArrayChildren] + | { + [K in NonStructRecordChildren]: Record< + K extends "" ? "{}>" | "[string]" : `${Extract}.${"{}>" | "[string]"}`, + A[K][number] + >; + }[NonStructRecordChildren] +>; + +type BubbleSum< + A, + Case extends { tag: string; cases: string } = Extract, { tag: string; cases: string }> +> = UnionToIntersection< + Case extends unknown + ? { + [K in Case["tag"]]: { + [K2 in Case["cases"] as `${Extract}:${Extract}`]: Omit< + Extract, + K + >; + }; + }[Case["tag"]] + : never +>; +/* +type ExtractChangeableKeys = K extends string + ? LastSegment extends `${string}:${string}` + ? never + : LastSegment extends `${string}?${string}` + ? never + : K + : never; */ + +type UpsertableKeys = Extract< + keyof { + [K in keyof A as true extends IsRecord ? K : never]: unknown; + }, + string +>; + +type Operation = "static" | "dynamic" | "upsert"; + +export type Paths = _Paths<{ "": EscapeKeys }, Op>; + +type _Paths = true extends IsRecord + ? _Paths< + keyof A extends never ? unknown : BubbleUp, + Op, + | Acc + | (Op extends "static" + ? Extract + : Op extends "upsert" + ? UpsertableKeys + : Extract) //ExtractChangeableKeys) + > + : Acc; + +// Not tail recursive!! +type EscapeKeys = A extends Record + ? A extends readonly unknown[] + ? A + : { + [K in keyof A as EscapeSpecialChars>]: EscapeKeys; + } + : A; diff --git a/src/util/Paths3.ts b/src/util/Paths3.ts new file mode 100644 index 0000000..3d5712d --- /dev/null +++ b/src/util/Paths3.ts @@ -0,0 +1,96 @@ +import type { Option, Some } from "fp-ts/Option"; +import type { Either, Left, Right } from "fp-ts/Either"; +import type { IsNull, IsRecord, IsNonTupleArray, TupleKeyof, IsNonStructRecord } from "./predicates"; +import { EscapeSpecialChars } from "./segments"; +import type { Cases, Discriminant } from "./sum"; +import { Data, SimpleData } from "../../test/shared"; + +type Join = S extends [infer First, ...infer Tail] + ? Join : `${Acc}.${Extract}`> + : Acc; + +type a = Paths; + +export type Paths = _Paths<{ path: []; atPath: A }>; + +type _Paths< + A extends { path: unknown[]; atPath: unknown }, + Acc extends unknown[] = never, + Bubbled extends { path: unknown[]; atPath: unknown } = BubbleUp +> = Bubbled["path"] extends never ? Acc | A["path"] : _Paths; + +type BubbleUp = A extends unknown + ? true extends IsNull + ? { + path: [...A["path"], "?"]; + atPath: NonNullable; + } + : Discriminant extends never + ? [A["atPath"]] extends [readonly unknown[]] + ? TupleKeyof extends never + ? { + path: [...A["path"], "[]>"] | [...A["path"], "[number]"]; + atPath: A["atPath"][number]; + } + : { + [K in TupleKeyof]: { + path: [...A["path"], `[${Extract}]`]; + atPath: A["atPath"][K]; + }; + }[TupleKeyof] + : string extends keyof A["atPath"] + ? { + path: [...A["path"], "{}>"] | [...A["path"], "[string]"]; + atPath: Extract>[string]; + } + : true extends IsRecord + ? { + [K in keyof A["atPath"]]: { + path: [...A["path"], EscapeSpecialChars>]; + atPath: A["atPath"][K]; + }; + }[keyof A["atPath"]] + : never + : Option extends A["atPath"] + ? { + path: [...A["path"], "?some"]; + atPath: Extract>["value"]; + } + : Either extends A["atPath"] + ? + | { + path: [...A["path"], "?left"]; + atPath: Extract>["left"]; + } + | { + path: [...A["path"], "?right"]; + atPath: Extract>["right"]; + } + : BubbleSum + : never; + +type BubbleSum< + A extends { path: unknown[]; atPath: unknown }, + Case extends { tag: string; cases: string } = Extract, { tag: string; cases: string }> +> = Case extends unknown + ? { + [K in Case["tag"]]: { + [K2 in Case["cases"]]: { + path: [...A["path"], `${Extract}:${Extract}`]; + atPath: Omit, K>; + }; + }[Case["cases"]]; + }[Case["tag"]] + : never; + +type Operation = "static" | "dynamic" | "upsert"; +type Type = { a: { b: number; c: boolean }; d: { e: { f: string } } }; + +type t1 = { path: []; atPath: Type }; + +type t2 = BubbleUp; +type t3 = BubbleUp; +type t4 = BubbleUp; + +type t5 = t1["path"] | t2["path"] | t3["path"] | t4["path"]; +type t6 = Paths; diff --git a/src/util/Paths4.ts b/src/util/Paths4.ts new file mode 100644 index 0000000..896f91d --- /dev/null +++ b/src/util/Paths4.ts @@ -0,0 +1,93 @@ +import type { Option, Some } from "fp-ts/Option"; +import type { Either, Left, Right } from "fp-ts/Either"; +import type { IsNull, IsRecord, IsNonTupleArray, TupleKeyof, IsNonStructRecord } from "./predicates"; +import { EscapeSpecialChars } from "./segments"; +import type { Cases, Discriminant } from "./sum"; +import { Data, SimpleData } from "../../test/shared"; + +type a = Paths; + +export type Paths = _Paths<{ path: ""; atPath: A }>; + +type _Paths = { + path: any; + atPath: any; +} extends A + ? _Paths, `${Acc}1`> + : Acc; + +type BubbleUp = A extends unknown + ? true extends IsNull + ? { + path: `${A["path"]}${A["path"] extends "" ? "" : "."}?`; + atPath: NonNullable; + } + : Discriminant extends never + ? [A["atPath"]] extends [readonly unknown[]] + ? TupleKeyof extends never + ? { + path: `${A["path"]}${A["path"] extends "" ? "" : "."}${"[]>" | "[number]"}`; + atPath: A["atPath"][number]; + } + : { + [K in TupleKeyof]: { + path: `${A["path"]}${A["path"] extends "" ? "" : "."}[${Extract}]`; + atPath: A["atPath"][K]; + }; + }[TupleKeyof] + : string extends keyof A["atPath"] + ? { + path: `${A["path"]}${A["path"] extends "" ? "" : "."}${"[string]" | "{}>"}`; + atPath: Extract>[string]; + } + : true extends IsRecord + ? { + [K in keyof A["atPath"]]: { + path: `${A["path"]}${A["path"] extends "" ? "" : "."}${EscapeSpecialChars>}`; + atPath: A["atPath"][K]; + }; + }[keyof A["atPath"]] + : never + : Option extends A["atPath"] + ? { + path: `${A["path"]}${A["path"] extends "" ? "" : "."}?some`; + atPath: Extract>["value"]; + } + : Either extends A["atPath"] + ? + | { + path: `${A["path"]}${A["path"] extends "" ? "" : "."}?left`; + atPath: Extract>["left"]; + } + | { + path: `${A["path"]}${A["path"] extends "" ? "" : "."}?right`; + atPath: Extract>["right"]; + } + : BubbleSum + : never; + +type BubbleSum< + A extends { path: string; atPath: unknown }, + Case extends { tag: string; cases: string } = Extract, { tag: string; cases: string }> +> = Case extends unknown + ? { + [K in Case["tag"]]: { + [K2 in Case["cases"]]: { + path: `${A["path"]}${A["path"] extends "" ? "" : "."}${Extract}:${Extract}`; + atPath: Omit, K>; + }; + }[Case["cases"]]; + }[Case["tag"]] + : never; + +type Operation = "static" | "dynamic" | "upsert"; +type Type = { a: { b: number; c: boolean }; d: { e: { f: string } } }; + +type t1 = { path: ""; atPath: Type }; + +type t2 = BubbleUp; +type t3 = BubbleUp; +type t4 = BubbleUp; + +type t5 = t1["path"] | t2["path"] | t3["path"] | t4["path"]; +type t6 = Paths; diff --git a/src/util/predicates.ts b/src/util/predicates.ts index d87c0f2..60ea53b 100644 --- a/src/util/predicates.ts +++ b/src/util/predicates.ts @@ -58,7 +58,7 @@ type HasTraversals = Args extends [infer First, ...infer : HasTraversals : never; -export type IsNull = undefined extends A ? true : null extends A ? true : never; +export type IsNull = Extract extends never ? never : true; export type IsRecord = unknown extends A ? never : [A] extends [Record] ? true : never; diff --git a/src/util/segments.ts b/src/util/segments.ts index 2253e4a..36b4fc5 100644 --- a/src/util/segments.ts +++ b/src/util/segments.ts @@ -73,3 +73,16 @@ type EscapeParenthesis = `(${StartingParens}*${S})`; type StartingParens = S extends `${string})${infer Tail}` ? StartingParens : Acc; + +export type EscapeSpecialChars2 = S extends + | "" + | "[]>" + | "{}>" + | "({}>)" + | `[${string}]` + | `${string}.${string}` + | `${string}?${string}` + | `${string}:${string}` + | `${string}(${string}` + ? `(${S})` + : S; diff --git a/test/tsd/set.spec.ts b/test/tsd/set.spec.ts index aa9b15a..7a3fb32 100644 --- a/test/tsd/set.spec.ts +++ b/test/tsd/set.spec.ts @@ -4,9 +4,9 @@ import { set } from "../../src"; import { Data, data, SimpleData, simpleData } from "../shared"; // modifies a definite value -const defSet: SimpleData = pipe(simpleData, set("a.b.[0]", -123)); +const defSet = pipe(simpleData, set("a.b.[0]", -123)); expectType(defSet); // modifies an optional value -const optSet: Data = pipe(data, set("type:A.a.?some.c", -123)); +const optSet = pipe(data, set("type:A.a.?some.c", -123)); expectType(optSet); diff --git a/yarn.lock b/yarn.lock index 6bf19c3..6b8556c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -547,6 +547,11 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@sindresorhus/is@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" + integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== + "@sinonjs/commons@^1.7.0": version "1.8.3" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" @@ -561,6 +566,13 @@ dependencies: "@sinonjs/commons" "^1.7.0" +"@szmarczak/http-timer@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" + integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== + dependencies: + defer-to-connect "^1.0.1" + "@technote-space/anchor-markdown-header@^1.1.23": version "1.1.24" resolved "https://registry.yarnpkg.com/@technote-space/anchor-markdown-header/-/anchor-markdown-header-1.1.24.tgz#18038c329ad8267e28dd888e06eb50a66aa86d33" @@ -878,6 +890,11 @@ abab@^2.0.3, abab@^2.0.5: resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + acorn-globals@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" @@ -933,6 +950,13 @@ ajv@^8.0.1: require-from-string "^2.0.2" uri-js "^4.2.2" +ansi-align@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" + integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== + dependencies: + string-width "^4.1.0" + ansi-colors@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" @@ -950,6 +974,11 @@ ansi-regex@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -972,7 +1001,7 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -anymatch@^3.0.3: +anymatch@^3.0.3, anymatch@~3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== @@ -1146,11 +1175,30 @@ base@^0.11.1: mixin-deep "^1.2.0" pascalcase "^0.1.1" +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + binary-search-bounds@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/binary-search-bounds/-/binary-search-bounds-2.0.5.tgz#125e5bd399882f71e6660d4bf1186384e989fba7" integrity sha512-H0ea4Fd3lS1+sTEB2TgcLoK21lLhwEJzlQv3IN47pJS976Gx4zoWe0ak3q+uYh60ppQxg9F16Ri4tS1sfD4+jA== +boxen@^5.0.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" + integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== + dependencies: + ansi-align "^3.0.0" + camelcase "^6.2.0" + chalk "^4.1.0" + cli-boxes "^2.2.1" + string-width "^4.2.2" + type-fest "^0.20.2" + widest-line "^3.1.0" + wrap-ansi "^7.0.0" + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -1175,7 +1223,7 @@ braces@^2.3.1: split-string "^3.0.2" to-regex "^3.0.1" -braces@^3.0.1: +braces@^3.0.1, braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== @@ -1237,6 +1285,19 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" +cacheable-request@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" + integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^3.0.0" + lowercase-keys "^2.0.0" + normalize-url "^4.1.0" + responselike "^1.0.2" + call-bind@^1.0.0, call-bind@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" @@ -1269,6 +1330,11 @@ camelcase@^6.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== +camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + caniuse-lite@^1.0.30001219: version "1.0.30001248" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001248.tgz#26ab45e340f155ea5da2920dadb76a533cb8ebce" @@ -1328,6 +1394,21 @@ character-reference-invalid@^1.0.0: resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560" integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg== +chokidar@^3.5.2: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + 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" + optionalDependencies: + fsevents "~2.3.2" + ci-info@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" @@ -1348,6 +1429,11 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" +cli-boxes@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" + integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== + cliui@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" @@ -1357,6 +1443,13 @@ cliui@^6.0.0: strip-ansi "^6.0.0" wrap-ansi "^6.2.0" +clone-response@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= + dependencies: + mimic-response "^1.0.0" + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -1441,6 +1534,18 @@ concat-stream@^1.6.0, concat-stream@^1.6.2: readable-stream "^2.2.2" typedarray "^0.0.6" +configstore@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" + integrity sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA== + dependencies: + dot-prop "^5.2.0" + graceful-fs "^4.1.2" + make-dir "^3.0.0" + unique-string "^2.0.0" + write-file-atomic "^3.0.0" + xdg-basedir "^4.0.0" + convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: version "1.8.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" @@ -1483,6 +1588,11 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2: shebang-command "^2.0.0" which "^2.0.1" +crypto-random-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" + integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== + cssom@^0.4.4: version "0.4.4" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" @@ -1523,6 +1633,13 @@ debug@^2.2.0, debug@^2.3.3: dependencies: ms "2.0.0" +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + decamelize-keys@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" @@ -1546,6 +1663,18 @@ decode-uri-component@^0.2.0: resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= +decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= + dependencies: + mimic-response "^1.0.0" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + deep-is@^0.1.3, deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" @@ -1556,6 +1685,11 @@ deepmerge@^4.2.2: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== +defer-to-connect@^1.0.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" + integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== + define-properties@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" @@ -1656,6 +1790,18 @@ domutils@^2.5.2: domelementtype "^2.2.0" domhandler "^4.2.0" +dot-prop@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" + integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q== + dependencies: + is-obj "^2.0.0" + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= + electron-to-chromium@^1.3.723: version "1.3.792" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.792.tgz#791b0d8fcf7411885d086193fb49aaef0c1594ca" @@ -1744,6 +1890,11 @@ escalade@^3.1.1: resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== +escape-goat@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675" + integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q== + escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" @@ -2196,7 +2347,7 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@^2.1.2: +fsevents@^2.1.2, fsevents@~2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== @@ -2240,14 +2391,14 @@ get-port@^3.1.0: resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc" integrity sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw= -get-stream@^4.0.0: +get-stream@^4.0.0, get-stream@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== dependencies: pump "^3.0.0" -get-stream@^5.0.0: +get-stream@^5.0.0, get-stream@^5.1.0: version "5.2.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== @@ -2259,7 +2410,7 @@ get-value@^2.0.3, get-value@^2.0.6: resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= -glob-parent@^5.1.2: +glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== @@ -2278,6 +2429,13 @@ glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: once "^1.3.0" path-is-absolute "^1.0.0" +global-dirs@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.0.tgz#70a76fe84ea315ab37b1f5576cbde7d48ef72686" + integrity sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA== + dependencies: + ini "2.0.0" + globals@^11.1.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" @@ -2328,6 +2486,28 @@ globby@^11.0.4: merge2 "^1.4.1" slash "^3.0.0" +got@^9.6.0: + version "9.6.0" + resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" + integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== + dependencies: + "@sindresorhus/is" "^0.14.0" + "@szmarczak/http-timer" "^1.1.2" + cacheable-request "^6.0.0" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^4.1.0" + lowercase-keys "^1.0.1" + mimic-response "^1.0.1" + p-cancelable "^1.0.0" + to-readable-stream "^1.0.0" + url-parse-lax "^3.0.0" + +graceful-fs@^4.1.2: + version "4.2.10" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + graceful-fs@^4.2.4: version "4.2.6" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" @@ -2394,6 +2574,11 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.0.0" +has-yarn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77" + integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw== + has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -2445,6 +2630,11 @@ http-basic@^8.1.1: http-response-object "^3.0.1" parse-cache-control "^1.0.1" +http-cache-semantics@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" + integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== + http-proxy-agent@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" @@ -2481,6 +2671,11 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" +ignore-by-default@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" + integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk= + ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" @@ -2504,6 +2699,11 @@ import-fresh@^3.0.0, import-fresh@^3.2.1: parent-module "^1.0.0" resolve-from "^4.0.0" +import-lazy@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" + integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= + import-local@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.2.tgz#a8cfd0431d1de4a2199703d003e3e62364fa6db6" @@ -2535,6 +2735,16 @@ inherits@2, inherits@^2.0.3, inherits@~2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +ini@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" + integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== + +ini@~1.3.0: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + internal-slot@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" @@ -2593,6 +2803,13 @@ is-bigint@^1.0.1: resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.2.tgz#ffb381442503235ad245ea89e45b3dbff040ee5a" integrity sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA== +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + is-boolean-object@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.1.tgz#3c0878f035cb821228d350d2e1e36719716a3de8" @@ -2715,7 +2932,7 @@ is-glob@^4.0.0, is-glob@^4.0.1: dependencies: is-extglob "^2.1.1" -is-glob@^4.0.3: +is-glob@^4.0.3, is-glob@~4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== @@ -2727,6 +2944,14 @@ is-hexadecimal@^1.0.0: resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7" integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== +is-installed-globally@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" + integrity sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ== + dependencies: + global-dirs "^3.0.0" + is-path-inside "^3.0.2" + is-local-path@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/is-local-path/-/is-local-path-0.1.6.tgz#815d144b14d569cecbead4d5693097f00a9bf6c5" @@ -2745,6 +2970,11 @@ is-negative-zero@^2.0.1: resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== +is-npm@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-5.0.0.tgz#43e8d65cc56e1b67f8d47262cf667099193f45a8" + integrity sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA== + is-number-object@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.5.tgz#6edfaeed7950cff19afedce9fbfca9ee6dd289eb" @@ -2762,6 +2992,16 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +is-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" + integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== + +is-path-inside@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + is-plain-obj@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" @@ -2847,6 +3087,11 @@ is-wsl@^2.2.0: dependencies: is-docker "^2.0.0" +is-yarn-global@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232" + integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw== + isarray@1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -3334,6 +3579,11 @@ jsesc@^2.5.1: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= + json-parse-even-better-errors@^2.3.0: version "2.3.1" resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" @@ -3361,6 +3611,13 @@ json5@2.x, json5@^2.1.2: dependencies: minimist "^1.2.5" +keyv@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" + integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== + dependencies: + json-buffer "3.0.0" + kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -3390,6 +3647,13 @@ kleur@^3.0.3: resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== +latest-version@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" + integrity sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA== + dependencies: + package-json "^6.3.0" + leven@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" @@ -3468,6 +3732,16 @@ longest-streak@^2.0.0: resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.4.tgz#b8599957da5b5dab64dee3fe316fa774597d90e4" integrity sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg== +lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -3770,6 +4044,11 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +mimic-response@^1.0.0, mimic-response@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + min-indent@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" @@ -3824,6 +4103,11 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + nanomatch@^1.2.9: version "1.2.13" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" @@ -3878,6 +4162,29 @@ node-releases@^1.1.71: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.73.tgz#dd4e81ddd5277ff846b80b52bb40c49edf7a7b20" integrity sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg== +nodemon@^2.0.15: + version "2.0.15" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.15.tgz#504516ce3b43d9dc9a955ccd9ec57550a31a8d4e" + integrity sha512-gdHMNx47Gw7b3kWxJV64NI+Q5nfl0y5DgDbiVtShiwa7Z0IZ07Ll4RLFo6AjrhzMtoEZn5PDE3/c2AbVsiCkpA== + dependencies: + chokidar "^3.5.2" + debug "^3.2.7" + ignore-by-default "^1.0.1" + minimatch "^3.0.4" + pstree.remy "^1.1.8" + semver "^5.7.1" + supports-color "^5.5.0" + touch "^3.1.0" + undefsafe "^2.0.5" + update-notifier "^5.1.0" + +nopt@~1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" + integrity sha1-bd0hvSoxQXuScn3Vhfim83YI6+4= + dependencies: + abbrev "1" + normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" @@ -3905,11 +4212,16 @@ normalize-path@^2.1.1: dependencies: remove-trailing-separator "^1.0.1" -normalize-path@^3.0.0: +normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== +normalize-url@^4.1.0: + version "4.5.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" + integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== + npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" @@ -4018,6 +4330,11 @@ optionator@^0.9.1: type-check "^0.4.0" word-wrap "^1.2.3" +p-cancelable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" + integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== + p-each-series@^2.1.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.2.0.tgz#105ab0357ce72b202a8a8b94933672657b5e2a9a" @@ -4061,6 +4378,16 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== +package-json@^6.3.0: + version "6.5.0" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" + integrity sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ== + dependencies: + got "^9.6.0" + registry-auth-token "^4.0.0" + registry-url "^5.0.0" + semver "^6.2.0" + parent-module@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" @@ -4140,6 +4467,11 @@ picomatch@^2.0.4, picomatch@^2.2.3: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== +picomatch@^2.2.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + pirates@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" @@ -4176,6 +4508,11 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= + prettier-linter-helpers@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" @@ -4238,6 +4575,11 @@ psl@^1.1.33: resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== +pstree.remy@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" + integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== + pump@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" @@ -4251,6 +4593,13 @@ punycode@^2.1.0, punycode@^2.1.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== +pupa@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.1.1.tgz#f5e8fd4afc2c5d97828faa523549ed8744a20d62" + integrity sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A== + dependencies: + escape-goat "^2.0.0" + qs@^6.4.0: version "6.10.1" resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.1.tgz#4931482fa8d647a5aab799c5271d2133b981fb6a" @@ -4268,6 +4617,16 @@ quick-lru@^4.0.1: resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== +rc@^1.2.8: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + react-is@^17.0.1: version "17.0.2" resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" @@ -4305,6 +4664,13 @@ readable-stream@^2.2.2: string_decoder "~1.1.1" util-deprecate "~1.0.1" +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + redent@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" @@ -4326,6 +4692,20 @@ regexpp@^3.1.0, regexpp@^3.2.0: resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== +registry-auth-token@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.1.tgz#6d7b4006441918972ccd5fedcd41dc322c79b250" + integrity sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw== + dependencies: + rc "^1.2.8" + +registry-url@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009" + integrity sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw== + dependencies: + rc "^1.2.8" + remark-footnotes@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/remark-footnotes/-/remark-footnotes-3.0.0.tgz#5756b56f8464fa7ed80dbba0c966136305d8cb8d" @@ -4417,6 +4797,13 @@ resolve@^1.10.0, resolve@^1.18.1, resolve@^1.20.0: is-core-module "^2.2.0" path-parse "^1.0.6" +responselike@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= + dependencies: + lowercase-keys "^1.0.0" + ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" @@ -4490,7 +4877,14 @@ saxes@^5.0.1: dependencies: xmlchars "^2.2.0" -"semver@2 || 3 || 4 || 5", semver@^5.5.0: +semver-diff@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b" + integrity sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg== + dependencies: + semver "^6.3.0" + +"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.7.1: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== @@ -4502,7 +4896,7 @@ semver@7.x, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: dependencies: lru-cache "^6.0.0" -semver@^6.0.0, semver@^6.3.0: +semver@^6.0.0, semver@^6.2.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== @@ -4714,6 +5108,15 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" +string-width@^4.0.0, string-width@^4.2.2: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + string-width@^4.1.0, string-width@^4.2.0: version "4.2.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" @@ -4753,6 +5156,13 @@ strip-ansi@^6.0.0: dependencies: ansi-regex "^5.0.0" +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-bom@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" @@ -4780,7 +5190,12 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -supports-color@^5.3.0: +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +supports-color@^5.3.0, supports-color@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== @@ -4896,6 +5311,11 @@ to-object-path@^0.3.0: dependencies: kind-of "^3.0.2" +to-readable-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" + integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== + to-regex-range@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" @@ -4921,6 +5341,13 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" +touch@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" + integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== + dependencies: + nopt "~1.0.10" + tough-cookie@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" @@ -4980,6 +5407,11 @@ ts-node@^9.1.1: source-map-support "^0.5.17" yn "3.1.1" +ts-toolbelt@^9.6.0: + version "9.6.0" + resolved "https://registry.yarnpkg.com/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz#50a25426cfed500d4a09bd1b3afb6f28879edfd5" + integrity sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w== + tsd@^0.19.1: version "0.19.1" resolved "https://registry.yarnpkg.com/tsd/-/tsd-0.19.1.tgz#c37891ad907d6ce2122e4a20c99cceca5767d713" @@ -5075,6 +5507,11 @@ unbox-primitive@^1.0.1: has-symbols "^1.0.2" which-boxed-primitive "^1.0.2" +undefsafe@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" + integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== + unified@^9.2.1: version "9.2.2" resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.2.tgz#67649a1abfc3ab85d2969502902775eb03146975" @@ -5097,6 +5534,13 @@ union-value@^1.0.0: is-extendable "^0.1.1" set-value "^2.0.1" +unique-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" + integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== + dependencies: + crypto-random-string "^2.0.0" + unist-util-is@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-4.1.0.tgz#976e5f462a7a5de73d94b706bac1b90671b57797" @@ -5130,6 +5574,26 @@ unset-value@^1.0.0: has-value "^0.3.1" isobject "^3.0.0" +update-notifier@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-5.1.0.tgz#4ab0d7c7f36a231dd7316cf7729313f0214d9ad9" + integrity sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw== + dependencies: + boxen "^5.0.0" + chalk "^4.1.0" + configstore "^5.0.1" + has-yarn "^2.1.0" + import-lazy "^2.1.0" + is-ci "^2.0.0" + is-installed-globally "^0.4.0" + is-npm "^5.0.0" + is-yarn-global "^0.3.0" + latest-version "^5.1.0" + pupa "^2.1.1" + semver "^7.3.4" + semver-diff "^3.1.1" + xdg-basedir "^4.0.0" + update-section@^0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/update-section/-/update-section-0.3.3.tgz#458f17820d37820dc60e20b86d94391b00123158" @@ -5147,6 +5611,13 @@ urix@^0.1.0: resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= + dependencies: + prepend-http "^2.0.0" + use@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" @@ -5309,6 +5780,13 @@ which@^2.0.1, which@^2.0.2: dependencies: isexe "^2.0.0" +widest-line@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" + integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== + dependencies: + string-width "^4.0.0" + word-wrap@^1.2.3, word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" @@ -5323,6 +5801,15 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -5343,6 +5830,11 @@ ws@^7.4.5: resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.3.tgz#160835b63c7d97bfab418fc1b8a9fced2ac01a74" integrity sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg== +xdg-basedir@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" + integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== + xml-name-validator@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" From 1bd6ffd79960b17a2c4da3ad90951b84ef5d1091 Mon Sep 17 00:00:00 2001 From: Anthony Gabriele Date: Tue, 5 Apr 2022 13:48:12 -0400 Subject: [PATCH 6/7] remove unused dependendies --- package.json | 4 +--- src/values/remove.ts | 13 ++++++++++--- yarn.lock | 10 ---------- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 0524a7f..1141a0f 100644 --- a/package.json +++ b/package.json @@ -19,9 +19,7 @@ "prepublishOnly": "yarn fix:lint && yarn test" }, "dependencies": { - "fp-ts-std": "^0.10.1", - "monocle-ts": "^2.3.5", - "ts-toolbelt": "^9.6.0" + "monocle-ts": "^2.3.5" }, "devDependencies": { "@types/jest": "^26.0.20", diff --git a/src/values/remove.ts b/src/values/remove.ts index 482df9f..de6dd92 100644 --- a/src/values/remove.ts +++ b/src/values/remove.ts @@ -1,5 +1,4 @@ import { pipe } from "fp-ts/function"; -import { omit } from "fp-ts-std/Record"; import * as L from "monocle-ts/lib/Lens"; import * as Tr from "monocle-ts/lib/Traversal"; import { lensFromPath, traversalFromPath, isPathLens } from "../util/monocle"; @@ -12,11 +11,19 @@ export const remove: Remove = (fullPath: string) => (a: unknown) => { if (isPathLens(path as any)) { return pipe( lensFromPath(path as any), - L.modify((obj) => omit(Array.isArray(final) ? final : [final])(obj)) + L.modify((obj) => { + const omitted = { ...obj }; + delete omitted[final as string]; + return omitted; + }) )(a); } return pipe( traversalFromPath(path as any, []), - Tr.modify((obj) => omit(Array.isArray(final) ? final : [final])(obj)) + Tr.modify((obj) => { + const omitted = { ...obj }; + delete omitted[final as string]; + return omitted; + }) )(a); }; diff --git a/yarn.lock b/yarn.lock index 6b8556c..f22b89f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2325,11 +2325,6 @@ format@^0.2.0: resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b" integrity sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs= -fp-ts-std@^0.10.1: - version "0.10.1" - resolved "https://registry.yarnpkg.com/fp-ts-std/-/fp-ts-std-0.10.1.tgz#e8fe6263ae538626a194a3e388a960bd9680a403" - integrity sha512-vjQvdRerpFcbuO/LrK8wBIgzM+mK65ixrS4LcPVBPoF0ishnkzg4rRWx5iEVKgVLk5bCq43tXz+oDAoGR7QGYw== - fp-ts@^2.11.1: version "2.11.1" resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-2.11.1.tgz#b1eeb2540728b6328542664888442f8f805d2443" @@ -5407,11 +5402,6 @@ ts-node@^9.1.1: source-map-support "^0.5.17" yn "3.1.1" -ts-toolbelt@^9.6.0: - version "9.6.0" - resolved "https://registry.yarnpkg.com/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz#50a25426cfed500d4a09bd1b3afb6f28879edfd5" - integrity sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w== - tsd@^0.19.1: version "0.19.1" resolved "https://registry.yarnpkg.com/tsd/-/tsd-0.19.1.tgz#c37891ad907d6ce2122e4a20c99cceca5767d713" From 130e1a5e4a71dc43e8f17e8782e657cdf70a0747 Mon Sep 17 00:00:00 2001 From: Anthony Gabriele Date: Tue, 5 Apr 2022 13:50:21 -0400 Subject: [PATCH 7/7] less strict testing, remove unused files --- src/util/Paths.ts | 25 +------ src/util/Paths2.ts | 141 ---------------------------------------- src/util/Paths3.ts | 96 --------------------------- src/util/Paths4.ts | 93 -------------------------- test/tsd/remove.spec.ts | 13 +--- test/tsd/rename.spec.ts | 24 +------ test/tsd/upsert.spec.ts | 8 +-- 7 files changed, 4 insertions(+), 396 deletions(-) delete mode 100644 src/util/Paths2.ts delete mode 100644 src/util/Paths3.ts delete mode 100644 src/util/Paths4.ts diff --git a/src/util/Paths.ts b/src/util/Paths.ts index a3b1571..e0cd22b 100644 --- a/src/util/Paths.ts +++ b/src/util/Paths.ts @@ -9,16 +9,7 @@ type Operation = "static" | "dynamic" | "upsert"; export type Paths = _Paths<{ "": A }, Op>; type _Paths = true extends IsRecord - ? _Paths< - keyof A extends never ? unknown : BubbleUp, - Op, - | Acc - | (Op extends "static" - ? Extract - : Op extends "upsert" - ? UpsertableKeys - : ExtractChangeableKeys) - > + ? _Paths, Op, Acc | Extract> : Acc; type BubbleUp> = UnionToIntersection>>; @@ -112,20 +103,6 @@ type Match< ? Matches["either"] : Matches["sum"]; -type UpsertableKeys = Extract< - keyof { - [K in keyof A as true extends IsRecord ? K : never]: unknown; - }, - string ->; - -type ExtractChangeableKeys = Extract< - keyof { - [K in keyof A as true extends IsNull ? never : Discriminant extends never ? K : never]: unknown; - }, - string ->; - // Credit to Stefan Baumgartner // https://fettblog.eu/typescript-union-to-intersection/ type UnionToIntersection = (T extends any ? (x: T) => any : never) extends (x: infer R) => any ? R : never; diff --git a/src/util/Paths2.ts b/src/util/Paths2.ts deleted file mode 100644 index d8c9163..0000000 --- a/src/util/Paths2.ts +++ /dev/null @@ -1,141 +0,0 @@ -import type { Option, Some } from "fp-ts/Option"; -import type { Either, Left, Right } from "fp-ts/Either"; -import type { IsNull, IsRecord, IsNonTupleArray, TupleKeyof, IsNonStructRecord } from "./predicates"; -import { EscapeSpecialChars } from "./segments"; -import type { Cases, Discriminant } from "./sum"; - -// Credit to Stefan Baumgartner -// https://fettblog.eu/typescript-union-to-intersection/ -type UnionToIntersection = (T extends any ? (x: T) => any : never) extends (x: infer R) => any ? R : never; - -type RecordChildren = keyof { - [K in TupleKeyof as true extends IsRecord - ? Discriminant extends never - ? true extends IsNonTupleArray - ? never - : true extends IsNonStructRecord - ? never - : K - : never - : never]: unknown; -}; - -type SumChildren = keyof { - [K in TupleKeyof as Discriminant extends never ? never : K]: unknown; -}; - -type NullableChildren = keyof { - [K in TupleKeyof as true extends IsNull ? K : never]: unknown; -}; - -type ArrayChildren = keyof { - [K in TupleKeyof as true extends IsNonTupleArray ? K : never]: unknown; -}; - -type NonStructRecordChildren = keyof { - [K in TupleKeyof as true extends IsNonStructRecord ? K : never]: unknown; -}; - -type BubbleUp> = UnionToIntersection< - | { - [K in RecordChildren]: { - [K2 in TupleKeyof as A[K] extends readonly unknown[] - ? K extends "" - ? `[${Extract}]` - : `${Extract}.[${Extract}]` - : K extends "" - ? Extract - : `${Extract}.${Extract}`]: A[K][K2]; - }; - }[RecordChildren] - | { - [K in SumChildren]: Option extends A[K] - ? Record< - K, - { - "?some": Extract>["value"]; - } - > - : Either extends A[K] - ? Record< - K, - { - "?left": Extract>["left"]; - "?right": Extract>["right"]; - } - > - : Record>; - }[SumChildren] - | { - [K in NullableChildren]-?: Record<`${Extract}?`, NonNullable>; - }[NullableChildren] - | { - [K in ArrayChildren]: Record< - K extends "" ? "[]>" | "[number]" : `${Extract}.${"[]>" | "[number]"}`, - A[K][number] - >; - }[ArrayChildren] - | { - [K in NonStructRecordChildren]: Record< - K extends "" ? "{}>" | "[string]" : `${Extract}.${"{}>" | "[string]"}`, - A[K][number] - >; - }[NonStructRecordChildren] ->; - -type BubbleSum< - A, - Case extends { tag: string; cases: string } = Extract, { tag: string; cases: string }> -> = UnionToIntersection< - Case extends unknown - ? { - [K in Case["tag"]]: { - [K2 in Case["cases"] as `${Extract}:${Extract}`]: Omit< - Extract, - K - >; - }; - }[Case["tag"]] - : never ->; -/* -type ExtractChangeableKeys = K extends string - ? LastSegment extends `${string}:${string}` - ? never - : LastSegment extends `${string}?${string}` - ? never - : K - : never; */ - -type UpsertableKeys = Extract< - keyof { - [K in keyof A as true extends IsRecord ? K : never]: unknown; - }, - string ->; - -type Operation = "static" | "dynamic" | "upsert"; - -export type Paths = _Paths<{ "": EscapeKeys }, Op>; - -type _Paths = true extends IsRecord - ? _Paths< - keyof A extends never ? unknown : BubbleUp, - Op, - | Acc - | (Op extends "static" - ? Extract - : Op extends "upsert" - ? UpsertableKeys - : Extract) //ExtractChangeableKeys) - > - : Acc; - -// Not tail recursive!! -type EscapeKeys = A extends Record - ? A extends readonly unknown[] - ? A - : { - [K in keyof A as EscapeSpecialChars>]: EscapeKeys; - } - : A; diff --git a/src/util/Paths3.ts b/src/util/Paths3.ts deleted file mode 100644 index 3d5712d..0000000 --- a/src/util/Paths3.ts +++ /dev/null @@ -1,96 +0,0 @@ -import type { Option, Some } from "fp-ts/Option"; -import type { Either, Left, Right } from "fp-ts/Either"; -import type { IsNull, IsRecord, IsNonTupleArray, TupleKeyof, IsNonStructRecord } from "./predicates"; -import { EscapeSpecialChars } from "./segments"; -import type { Cases, Discriminant } from "./sum"; -import { Data, SimpleData } from "../../test/shared"; - -type Join = S extends [infer First, ...infer Tail] - ? Join : `${Acc}.${Extract}`> - : Acc; - -type a = Paths; - -export type Paths = _Paths<{ path: []; atPath: A }>; - -type _Paths< - A extends { path: unknown[]; atPath: unknown }, - Acc extends unknown[] = never, - Bubbled extends { path: unknown[]; atPath: unknown } = BubbleUp -> = Bubbled["path"] extends never ? Acc | A["path"] : _Paths; - -type BubbleUp = A extends unknown - ? true extends IsNull - ? { - path: [...A["path"], "?"]; - atPath: NonNullable; - } - : Discriminant extends never - ? [A["atPath"]] extends [readonly unknown[]] - ? TupleKeyof extends never - ? { - path: [...A["path"], "[]>"] | [...A["path"], "[number]"]; - atPath: A["atPath"][number]; - } - : { - [K in TupleKeyof]: { - path: [...A["path"], `[${Extract}]`]; - atPath: A["atPath"][K]; - }; - }[TupleKeyof] - : string extends keyof A["atPath"] - ? { - path: [...A["path"], "{}>"] | [...A["path"], "[string]"]; - atPath: Extract>[string]; - } - : true extends IsRecord - ? { - [K in keyof A["atPath"]]: { - path: [...A["path"], EscapeSpecialChars>]; - atPath: A["atPath"][K]; - }; - }[keyof A["atPath"]] - : never - : Option extends A["atPath"] - ? { - path: [...A["path"], "?some"]; - atPath: Extract>["value"]; - } - : Either extends A["atPath"] - ? - | { - path: [...A["path"], "?left"]; - atPath: Extract>["left"]; - } - | { - path: [...A["path"], "?right"]; - atPath: Extract>["right"]; - } - : BubbleSum - : never; - -type BubbleSum< - A extends { path: unknown[]; atPath: unknown }, - Case extends { tag: string; cases: string } = Extract, { tag: string; cases: string }> -> = Case extends unknown - ? { - [K in Case["tag"]]: { - [K2 in Case["cases"]]: { - path: [...A["path"], `${Extract}:${Extract}`]; - atPath: Omit, K>; - }; - }[Case["cases"]]; - }[Case["tag"]] - : never; - -type Operation = "static" | "dynamic" | "upsert"; -type Type = { a: { b: number; c: boolean }; d: { e: { f: string } } }; - -type t1 = { path: []; atPath: Type }; - -type t2 = BubbleUp; -type t3 = BubbleUp; -type t4 = BubbleUp; - -type t5 = t1["path"] | t2["path"] | t3["path"] | t4["path"]; -type t6 = Paths; diff --git a/src/util/Paths4.ts b/src/util/Paths4.ts deleted file mode 100644 index 896f91d..0000000 --- a/src/util/Paths4.ts +++ /dev/null @@ -1,93 +0,0 @@ -import type { Option, Some } from "fp-ts/Option"; -import type { Either, Left, Right } from "fp-ts/Either"; -import type { IsNull, IsRecord, IsNonTupleArray, TupleKeyof, IsNonStructRecord } from "./predicates"; -import { EscapeSpecialChars } from "./segments"; -import type { Cases, Discriminant } from "./sum"; -import { Data, SimpleData } from "../../test/shared"; - -type a = Paths; - -export type Paths = _Paths<{ path: ""; atPath: A }>; - -type _Paths = { - path: any; - atPath: any; -} extends A - ? _Paths, `${Acc}1`> - : Acc; - -type BubbleUp = A extends unknown - ? true extends IsNull - ? { - path: `${A["path"]}${A["path"] extends "" ? "" : "."}?`; - atPath: NonNullable; - } - : Discriminant extends never - ? [A["atPath"]] extends [readonly unknown[]] - ? TupleKeyof extends never - ? { - path: `${A["path"]}${A["path"] extends "" ? "" : "."}${"[]>" | "[number]"}`; - atPath: A["atPath"][number]; - } - : { - [K in TupleKeyof]: { - path: `${A["path"]}${A["path"] extends "" ? "" : "."}[${Extract}]`; - atPath: A["atPath"][K]; - }; - }[TupleKeyof] - : string extends keyof A["atPath"] - ? { - path: `${A["path"]}${A["path"] extends "" ? "" : "."}${"[string]" | "{}>"}`; - atPath: Extract>[string]; - } - : true extends IsRecord - ? { - [K in keyof A["atPath"]]: { - path: `${A["path"]}${A["path"] extends "" ? "" : "."}${EscapeSpecialChars>}`; - atPath: A["atPath"][K]; - }; - }[keyof A["atPath"]] - : never - : Option extends A["atPath"] - ? { - path: `${A["path"]}${A["path"] extends "" ? "" : "."}?some`; - atPath: Extract>["value"]; - } - : Either extends A["atPath"] - ? - | { - path: `${A["path"]}${A["path"] extends "" ? "" : "."}?left`; - atPath: Extract>["left"]; - } - | { - path: `${A["path"]}${A["path"] extends "" ? "" : "."}?right`; - atPath: Extract>["right"]; - } - : BubbleSum - : never; - -type BubbleSum< - A extends { path: string; atPath: unknown }, - Case extends { tag: string; cases: string } = Extract, { tag: string; cases: string }> -> = Case extends unknown - ? { - [K in Case["tag"]]: { - [K2 in Case["cases"]]: { - path: `${A["path"]}${A["path"] extends "" ? "" : "."}${Extract}:${Extract}`; - atPath: Omit, K>; - }; - }[Case["cases"]]; - }[Case["tag"]] - : never; - -type Operation = "static" | "dynamic" | "upsert"; -type Type = { a: { b: number; c: boolean }; d: { e: { f: string } } }; - -type t1 = { path: ""; atPath: Type }; - -type t2 = BubbleUp; -type t3 = BubbleUp; -type t4 = BubbleUp; - -type t5 = t1["path"] | t2["path"] | t3["path"] | t4["path"]; -type t6 = Paths; diff --git a/test/tsd/remove.spec.ts b/test/tsd/remove.spec.ts index eb6373f..4eea86b 100644 --- a/test/tsd/remove.spec.ts +++ b/test/tsd/remove.spec.ts @@ -1,18 +1,7 @@ -import { expectType, expectError } from "tsd"; +import { expectType } from "tsd"; import { pipe } from "fp-ts/function"; import { remove } from "../../src"; -import { B, Data } from "../shared"; // omit a key const omitKey = pipe({ a: { b: 123, c: "abc" } }, remove("a.b")); expectType<{ a: { c: string } }>(omitKey); - -// don't suggest nullable-narrowing 'leaves' -declare const nullable: { a?: { b: number; c: string } }; -expectType<{ a?: { c: string } }>(pipe(nullable, remove("a?.b"))); -expectError(pipe(nullable, remove("a?"))); - -// don't suggest sum narrowing leaves -declare const data: Data; -expectType(pipe(data, remove("type:A.a"))); -expectError(pipe(data, remove("type:A"))); diff --git a/test/tsd/rename.spec.ts b/test/tsd/rename.spec.ts index 1af0efa..6d13331 100644 --- a/test/tsd/rename.spec.ts +++ b/test/tsd/rename.spec.ts @@ -1,30 +1,8 @@ -import { expectError, expectType } from "tsd"; -import type { Option } from "fp-ts/Option"; +import { expectType } from "tsd"; import { pipe } from "fp-ts/function"; import { rename } from "../../src"; -import { Data, B } from "../shared"; // rename a key const renamed = pipe({ a: { oldKey: 123, b: "abc" } }, rename("a.oldKey", "newKey")); expectType<{ a: { b: string } & { readonly newKey: number } }>(renamed); - -// don't suggest nullable-narrowing 'leaves' -declare const nullable: { a?: { b: number; c: string } }; -expectType<{ a?: { c: string } & { readonly z: number } }>(pipe(nullable, rename("a?.b", "z"))); -expectError(pipe(nullable, rename("a?", "z"))); - -// don't suggest sum narrowing leaves -declare const data: Data; -expectType< - | B - | { - z: Option<{ - c: number; - d: string[]; - e: boolean; - }>; - type: "A"; - } ->(pipe(data, rename("type:A.a", "z"))); -expectError(pipe(data, rename("type:A", "z"))); diff --git a/test/tsd/upsert.spec.ts b/test/tsd/upsert.spec.ts index a2603ec..da4cdaa 100644 --- a/test/tsd/upsert.spec.ts +++ b/test/tsd/upsert.spec.ts @@ -1,4 +1,4 @@ -import { expectType, expectError } from "tsd"; +import { expectType } from "tsd"; import { pipe } from "fp-ts/function"; import { upsert } from "../../src"; @@ -16,9 +16,3 @@ const preservesReadonlyKeys = pipe( upsert("a", "b", true) ); expectType<{ a: { readonly b: boolean; f: boolean } }>(preservesReadonlyKeys); - -// don't suggest non-record 'leaves' -declare const nullable: { a?: { b: number; c: string } }; -expectType(pipe(nullable, upsert("a?", "b", 123))); -expectError(pipe(nullable, upsert("a", "a", 123))); -expectError(pipe(nullable, upsert("a?.c", "a", 123)));