{"version":3,"file":"index.mjs","names":[],"sources":["../src/helpers/array-to-path.ts","../src/utils/is-object.ts","../src/utils/is-unsafe-key.ts","../src/helpers/path-to-array.ts","../src/path-expand/constants.ts","../src/path-expand/module.ts","../src/path-value/get.ts","../src/path-value/set.ts","../src/path-info/module.ts","../src/path-info/helper.ts","../src/remove.ts"],"sourcesContent":["/*\n * Copyright (c) 2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\n/**\n * @see https://github.com/express-validator/express-validator/blob/bec1dcbaa29002dcd21093ec84818c4671063b5d/src/field-selection.ts#L214\n * @param parts\n */\nexport function arrayToPath(parts: readonly PropertyKey[]) : string {\n    let output = '';\n\n    for (let part of parts) {\n        let current = '';\n\n        if (typeof part === 'string') {\n            part = part.replace(/^\\[(\\d+)]$/g, '\\\\[$1]');\n            part = part.replace(/\\./g, '\\\\.');\n\n            if (/^\\d+$/.test(part)) {\n                // Index access\n                current = `[${part}]`;\n            } else if (output) {\n                // Object key access\n                current = `.${part}`;\n            } else {\n                // Top level key\n                current = part;\n            }\n        } else if (typeof part === 'number') {\n            current = `[${part}]`;\n        }\n\n        output += current;\n    }\n\n    return output;\n}\n","/*\n * Copyright (c) 2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nexport function isObject(input: unknown) : input is Record<string, any> {\n    return !!input &&\n        typeof input === 'object' &&\n        !Array.isArray(input);\n}\n","/*\n * Copyright (c) 2024-2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nconst UNSAFE_KEYS = new Set<PropertyKey>(['__proto__', 'constructor', 'prototype']);\n\nexport function isUnsafeKey(key: PropertyKey): boolean {\n    return UNSAFE_KEYS.has(key);\n}\n","/*\n * Copyright (c) 2024-2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { isUnsafeKey } from '../utils';\n\nexport const BRACKET_NUMBER_REGEX = /(?<!\\\\)\\[(\\d+)]$/;\n\n/**\n * Convert string to property path array.\n *\n * @see https://github.com/lodash/lodash/blob/main/src/.internal/stringToPath.ts\n * @see https://github.com/chaijs/pathval\n *\n * @param segment\n */\nexport function pathToArray(segment: PropertyKey) : PropertyKey[] {\n    if (typeof segment === 'number') {\n        return [segment];\n    }\n\n    if (typeof segment === 'symbol') {\n        return [];\n    }\n\n    const str = segment.replace(/([^\\\\])\\[/g, '$1.[');\n    const parts = str.match(/(\\\\\\.|[^.]+?)+/g);\n    if (!parts) {\n        return [];\n    }\n\n    const result : PropertyKey[] = [];\n\n    for (const part of parts) {\n        if (isUnsafeKey(part)) {\n            continue;\n        }\n\n        const regex = BRACKET_NUMBER_REGEX.exec(part);\n        if (regex) {\n            result.push(Number(regex[1]));\n        } else {\n            result.push(part.replace(/\\\\([.[\\]])/g, '$1'));\n        }\n    }\n\n    return result;\n}\n","/*\n * Copyright (c) 2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nexport enum Character {\n    WILDCARD = '*',\n    GLOBSTAR = '**',\n}\n","/*\n * Copyright (c) 2024-2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { Character } from './constants';\nimport type { PathExpanded } from './types';\nimport { isObject } from '../utils';\nimport { arrayToPath, pathToArray } from '../helpers';\n\nfunction expandPathVerboseInternal(\n    data: Record<string, any>,\n    path: PropertyKey | PropertyKey[],\n    currPath: readonly PropertyKey[] = [],\n    currMatches: readonly (string | string[])[] = [],\n): PathExpanded[] {\n    const segments = Array.isArray(path) ? path : pathToArray(path);\n    if (!segments.length) {\n        // no more paths to traverse\n        return [\n            {\n                value: arrayToPath(currPath),\n                matches: currMatches,\n            },\n        ];\n    }\n\n    const key = segments[0];\n    if (typeof key === 'symbol') {\n        return [];\n    }\n\n    const rest = segments.slice(1);\n\n    if (\n        typeof data !== 'undefined' &&\n        data !== null &&\n        !isObject(data) &&\n        !Array.isArray(data)\n    ) {\n        if (key === Character.GLOBSTAR) {\n            if (!rest.length) {\n                // globstar leaves are always selected\n                return [\n                    {\n                        value: arrayToPath(currPath),\n                        matches: currMatches,\n                    },\n                ];\n            }\n\n            return [];\n        }\n\n        if (key === Character.WILDCARD) {\n            return [];\n        }\n\n        // value is a primitive, paths being traversed from here might be in their prototype,\n        // return the entire path\n        return [{\n            value: arrayToPath([...currPath, ...segments]),\n            matches: currMatches \n        }];\n    }\n\n    // Use a non-null value so that non-existing fields are still selected\n    data = data || {};\n\n    if (key === Character.WILDCARD) {\n        return Object.keys(data)\n            .flatMap((key) => expandPathVerboseInternal(\n                data[key],\n                arrayToPath(rest),\n                currPath.concat(key),\n                currMatches.concat(key),\n            ));\n    }\n\n    if (key === Character.GLOBSTAR) {\n        return Object.keys(data)\n            .flatMap((key) => {\n                const nextPath = currPath.concat(key);\n                const value = data[key];\n\n                // recursively find matching sub-paths & skip the first remaining segment, if it matches the current key\n                const children = expandPathVerboseInternal(value, arrayToPath(segments), nextPath, [key])\n                    .concat(rest[0] === key ? expandPathVerboseInternal(value, arrayToPath(rest.slice(1)), nextPath, []) : []);\n\n                const pathMatches : string[] = [];\n                const output : PathExpanded[] = [];\n                for (const child of children) {\n                    /* istanbul ignore next */\n                    if (pathMatches.includes(child.value)) {\n                        continue;\n                    }\n\n                    pathMatches.push(child.value);\n\n                    output.push({\n                        value: child.value,\n                        matches: child.matches.length > 0 ?\n                            [...currMatches, child.matches.flat()] :\n                            currMatches,\n                    });\n                }\n\n                return output;\n            });\n    }\n\n    return expandPathVerboseInternal(data[key], rest, currPath.concat(key), currMatches);\n}\n\n/**\n * Verbose expand wildcard and glob patterns.\n * Track wildcard/glob pattern matches.\n *\n * @param data\n * @param path\n */\nexport function expandPathVerbose(\n    data: Record<string, any>,\n    path: PropertyKey | PropertyKey[],\n): PathExpanded[] {\n    return expandPathVerboseInternal(data, path);\n}\n\n/**\n * Expand wildcard and glob patterns to paths.\n *\n * @param data\n * @param path\n */\nexport function expandPath(\n    data: Record<PropertyKey, any>,\n    path: PropertyKey | PropertyKey[],\n): string[] {\n    return expandPathVerbose(data, path)\n        .map((el) => el.value);\n}\n","/*\n * Copyright (c) 2024-2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { pathToArray } from '../helpers';\nimport { isUnsafeKey } from '../utils';\n\nexport function getPathValue(\n    data: unknown,\n    path: PropertyKey | PropertyKey[],\n): unknown {\n    const parts = Array.isArray(path) ?\n        path :\n        pathToArray(path);\n\n    let res : unknown | undefined;\n    let temp = data;\n    let index = 0;\n    while (index < parts.length) {\n        if (temp === null || typeof temp === 'undefined') {\n            break;\n        }\n\n        if (isUnsafeKey(parts[index])) {\n            break;\n        }\n\n        if (parts[index] in Object(temp)) {\n            // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n            // @ts-expect-error\n            temp = temp[parts[index]];\n        } else {\n            break;\n        }\n\n        if (index === parts.length - 1) {\n            res = temp;\n        }\n\n        index++;\n    }\n\n    return res;\n}\n","/*\n * Copyright (c) 2024-2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { pathToArray } from '../helpers';\nimport { isObject, isUnsafeKey } from '../utils';\n\nconst NUMBER_REGEX = /^\\d+$/;\n\nexport function setPathValue(\n    data: Record<string, any> | Record<string, any>[],\n    path: string | string[],\n    value: unknown,\n) {\n    const parts = Array.isArray(path) ?\n        path :\n        pathToArray(path);\n\n    let temp = data;\n    let index = 0;\n    while (index < parts.length) {\n        /* istanbul ignore next */\n        if (!Array.isArray(temp) && !isObject(temp)) {\n            break;\n        }\n\n        const key = parts[index] as keyof typeof temp;\n\n        if (isUnsafeKey(key)) {\n            break;\n        }\n\n        // [foo, '0']\n        if (typeof temp[key] === 'undefined') {\n            const match = NUMBER_REGEX.test(key);\n            if (match) {\n                (temp as Record<string, any>)[key] = [];\n            } else {\n                temp[key] = {};\n            }\n        }\n\n        if (index === parts.length - 1) {\n            temp[key] = value;\n            break;\n        }\n\n        index++;\n        temp = temp[key];\n    }\n\n    return data;\n}\n","/*\n * Copyright (c) 2024-2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { getPathValue } from '../path-value';\nimport { pathToArray } from '../helpers';\nimport { isUnsafeKey } from '../utils';\n\nexport class PathInfo {\n    protected data: unknown;\n\n    protected pathParts: PropertyKey[];\n\n    protected _value: unknown;\n\n    protected _parent: PathInfo | null | undefined;\n\n    protected _exists: boolean | undefined;\n\n    constructor(data: unknown, path: PropertyKey | PropertyKey[]) {\n        this.data = data;\n\n        if (Array.isArray(path)) {\n            this.pathParts = path.filter((p) => !isUnsafeKey(p));\n        } else {\n            this.pathParts = pathToArray(path);\n        }\n    }\n\n    get value() {\n        if (typeof this._value !== 'undefined') {\n            return this._value;\n        }\n\n        if (this.pathParts.length > 0) {\n            this._value = getPathValue(this.data, this.pathParts);\n        } else {\n            this._value = this.data;\n        }\n\n        return this._value;\n    }\n\n    get name() : PropertyKey | null {\n        if (this.pathParts.length > 0) {\n            return this.pathParts[this.pathParts.length - 1];\n        }\n\n        return null;\n    }\n\n    get parent() : PathInfo | null {\n        if (typeof this._parent !== 'undefined') {\n            return this._parent;\n        }\n\n        if (this.pathParts.length === 0) {\n            this._parent = null;\n            return this._parent;\n        }\n\n        if (this.pathParts.length > 1) {\n            this._parent = new PathInfo(\n                this.data,\n                this.pathParts.slice(0, this.pathParts.length - 1),\n            );\n        } else {\n            this._parent = new PathInfo(this.data, []);\n        }\n\n        return this._parent;\n    }\n\n    get exists() : boolean {\n        if (typeof this._exists !== 'undefined') {\n            return this._exists;\n        }\n\n        if (!this.name || !this.parent) {\n            this._exists = true;\n            return this._exists;\n        }\n\n        if (\n            this.parent.value !== null &&\n            typeof this.parent.value !== 'undefined'\n        ) {\n            this._exists = this.name in Object(this.parent.value);\n        } else {\n            this._exists = false;\n        }\n\n        return this._exists;\n    }\n}\n","/*\n * Copyright (c) 2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { PathInfo } from './module';\n\nexport function getPathInfo(\n    data: Record<string, any>,\n    path: PropertyKey | PropertyKey[],\n) : PathInfo {\n    return new PathInfo(data, path);\n}\n","/*\n * Copyright (c) 2024-2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { pathToArray } from './helpers';\nimport { isObject, isUnsafeKey } from './utils';\n\nexport function removePath(\n    data: Record<string, any> | Record<string, any>[],\n    path: string | string[],\n) {\n    const parts = Array.isArray(path) ?\n        path :\n        pathToArray(path);\n\n    let temp = data;\n    let index = 0;\n    while (index < parts.length) {\n        /* istanbul ignore next */\n        if (!Array.isArray(temp) && !isObject(temp)) {\n            break;\n        }\n\n        const key = parts[index] as keyof typeof temp;\n\n        if (isUnsafeKey(key)) {\n            break;\n        }\n\n        if (!Object.prototype.hasOwnProperty.call(temp, key)) {\n            break;\n        }\n\n        if (index === parts.length - 1) {\n            if (Array.isArray(temp)) {\n                const tempKey = Number(key);\n                if (!Number.isNaN(tempKey)) {\n                    temp.splice(tempKey, 1);\n                    break;\n                }\n            }\n\n            delete temp[key];\n            break;\n        }\n\n        index++;\n        temp = temp[key];\n    }\n}\n"],"mappings":"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"}