generated from obsidianmd/obsidian-sample-plugin
-
-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: allow pick/omit in Result helpers
this also includes the objectSelect utility and it's tests fixes #101
- Loading branch information
1 parent
efc05a4
commit 1c5bd5f
Showing
7 changed files
with
151 additions
and
21 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { objectSelect } from "./objectSelect"; | ||
|
||
describe("objectSelect", () => { | ||
const obj = { | ||
name: "John Doe", | ||
age: 30, | ||
hobbies: ["reading", "swimming"], | ||
isEmployed: true, | ||
}; | ||
|
||
it("should return the original object if no options are provided", () => { | ||
expect(objectSelect(obj, {})).toEqual(obj); | ||
}); | ||
|
||
it("should pick the specified properties from the object", () => { | ||
const opts = { pick: ["name", "age"] }; | ||
const expectedOutput = { name: "John Doe", age: 30 }; | ||
expect(objectSelect(obj, opts)).toEqual(expectedOutput); | ||
}); | ||
|
||
it("should omit the specified properties from the object", () => { | ||
const opts = { omit: ["name", "hobbies"] }; | ||
const expectedOutput = { age: 30, isEmployed: true }; | ||
expect(objectSelect(obj, opts)).toEqual(expectedOutput); | ||
}); | ||
|
||
it("should pick and omit properties from the object", () => { | ||
const opts = { pick: ["name", "age"], omit: ["age"] }; | ||
const expectedOutput = { name: "John Doe" }; | ||
expect(objectSelect(obj, opts)).toEqual(expectedOutput); | ||
}); | ||
|
||
it("should return the original object if the pick array is empty", () => { | ||
const opts = { pick: [] }; | ||
expect(objectSelect(obj, opts)).toEqual(obj); | ||
}); | ||
|
||
it("should return an empty object if the omit array contains all properties", () => { | ||
const opts = { omit: ["name", "age", "hobbies", "isEmployed"] }; | ||
expect(objectSelect(obj, opts)).toEqual({}); | ||
}); | ||
|
||
it("should return the original object if the omit array is empty", () => { | ||
const opts = { omit: [] }; | ||
expect(objectSelect(obj, opts)).toEqual(obj); | ||
}); | ||
|
||
it("should return the original object if the options argument is not an object", () => { | ||
expect(objectSelect(obj, "invalid options")).toEqual(obj); | ||
}); | ||
|
||
it("should return the original object if the options argument is null", () => { | ||
expect(objectSelect(obj, null)).toEqual(obj); | ||
}); | ||
|
||
it("should return the original object if the options argument is undefined", () => { | ||
expect(objectSelect(obj, undefined)).toEqual(obj); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { E, parse, pipe } from "@std"; | ||
import * as O from "fp-ts/Option"; | ||
import * as NEA from "fp-ts/NonEmptyArray"; | ||
import { filterWithIndex } from "fp-ts/lib/Record"; | ||
import { object, optional, array, string, coerce } from "valibot"; | ||
|
||
const KeysSchema = array(coerce(string(), String)) | ||
|
||
const PickOmitSchema = object({ | ||
pick: optional(KeysSchema), | ||
omit: optional(KeysSchema), | ||
}); | ||
|
||
|
||
|
||
/** | ||
* Utility to pick/omit keys from an object. | ||
* It is user facing, that's why we are so defensive in the options. | ||
* The object should come from the form results, so we don't need to be that strict. | ||
* @param obj the object you want to pick/omit from | ||
* @param opts the options for picking/omitting based on key names | ||
*/ | ||
export function objectSelect(obj: Record<string, unknown>, opts: unknown): Record<string, unknown> { | ||
return pipe( | ||
parse(PickOmitSchema, opts, { abortEarly: true }), | ||
E.map((opts) => { | ||
const picked = pipe( | ||
O.fromNullable(opts.pick), | ||
O.flatMap(NEA.fromArray), | ||
O.map((pick) => { | ||
return filterWithIndex((k) => pick.includes(k))(obj); | ||
}), | ||
O.getOrElse(() => obj) | ||
); | ||
return pipe( | ||
O.fromNullable(opts.omit), | ||
O.map((omit) => | ||
filterWithIndex((k) => !omit.includes(k))(picked)), | ||
O.getOrElse(() => picked) | ||
) | ||
} | ||
), | ||
E.getOrElse(() => obj) | ||
) | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters