templating api
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
import {
|
||||
cloneDeep,
|
||||
isArray,
|
||||
isBoolean,
|
||||
isNull,
|
||||
isNumber,
|
||||
isObject,
|
||||
isString,
|
||||
isUndefined,
|
||||
} from "lodash"
|
||||
|
||||
export type Path =
|
||||
| string
|
||||
| {
|
||||
[key: string]: (string | Path)[]
|
||||
}
|
||||
|
||||
/*
|
||||
Usage:
|
||||
const object = {
|
||||
a: 1,
|
||||
b: 2,
|
||||
c: {
|
||||
d: 4,
|
||||
f: 5,
|
||||
},
|
||||
g: [
|
||||
{
|
||||
h: 6,
|
||||
i: 7,
|
||||
},
|
||||
{
|
||||
h: 8,
|
||||
i: 9,
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
const picked = deepPick(object, ["a", { c: ["d"] }, { g: ["h"] }]);
|
||||
console.log(picked); // Output: { a: 1, c: { d: 4 }, g: [{ h: 6 }, { h: 8 }] }
|
||||
|
||||
TODO: figure out how to do this without "any"
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function deepPick(object: any, paths: Path[]): any {
|
||||
if (isArray(object)) {
|
||||
return object.map((item) => deepPick(item, paths))
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return paths.reduce((result: any, path: Path) => {
|
||||
if (isString(path)) {
|
||||
if (path in object === false) return result
|
||||
|
||||
const value = cloneDeep(object[path])
|
||||
if (isSimpleType(value)) {
|
||||
result[path] = value
|
||||
return result
|
||||
} else if (isArray(value) && value.every(isSimpleType)) {
|
||||
result[path] = value
|
||||
return result
|
||||
} else if (isArray(value) && value.every(isObject)) {
|
||||
result[path] = []
|
||||
return result
|
||||
} else if (isObject(value)) {
|
||||
result[path] = value
|
||||
return result
|
||||
} else {
|
||||
throw new Error(`Unsupported value type at path: ${path} -> ${JSON.stringify(value)}`)
|
||||
}
|
||||
} else if (isObject(path)) {
|
||||
Object.entries(path).forEach(([path, nestedPaths]) => {
|
||||
if (path in object === false) return
|
||||
|
||||
const value = cloneDeep(object[path])
|
||||
if (isSimpleType(value)) {
|
||||
result[path] = value
|
||||
} else if (isArray(value) && value.every(isSimpleType)) {
|
||||
result[path] = value
|
||||
} else if (Array.isArray(value) && value.every(isObject)) {
|
||||
result[path] = value.map((item) => deepPick(item, nestedPaths))
|
||||
} else if (isObject(value)) {
|
||||
result[path] = deepPick(value, nestedPaths)
|
||||
} else {
|
||||
throw new Error(
|
||||
`Unsupported value structure at path: ${path} -> ${JSON.stringify(value)}`
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
return result
|
||||
} else {
|
||||
throw new Error(`Unsupported path type: ${path}`)
|
||||
}
|
||||
}, {})
|
||||
}
|
||||
|
||||
function isSimpleType(value: unknown) {
|
||||
return (
|
||||
isString(value) || isNumber(value) || isBoolean(value) || isNull(value) || isUndefined(value)
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user