{"version":3,"file":"remove-disallowed-fields.mjs","sources":["../../../src/sanitize/visitors/remove-disallowed-fields.ts"],"sourcesContent":["import { isArray, isNil, isString, toPath } from 'lodash/fp';\nimport type { Visitor } from '../../traverse/factory';\n\nexport default (allowedFields: string[] | null = null): Visitor =>\n  ({ key, path: { attribute: path } }, { remove }) => {\n    // All fields are allowed\n    if (allowedFields === null) {\n      return;\n    }\n\n    // Throw on invalid formats\n    if (!(isArray(allowedFields) && allowedFields.every(isString))) {\n      throw new TypeError(\n        `Expected array of strings for allowedFields but got \"${typeof allowedFields}\"`\n      );\n    }\n\n    if (isNil(path)) {\n      return;\n    }\n\n    const containedPaths = getContainedPaths(path);\n\n    /**\n     * Tells if the current path should be kept or not based\n     * on the success of the check functions for any of the allowed paths.\n     *\n     * The check functions are defined as follow:\n     *\n     * `containedPaths.includes(p)`\n     * @example\n     * ```js\n     * const path = 'foo.bar.field';\n     * const p = 'foo.bar';\n     * // it should match\n     *\n     * const path = 'foo.bar.field';\n     * const p = 'bar.foo';\n     * // it shouldn't match\n     *\n     * const path = 'foo.bar';\n     * const p = 'foo.bar.field';\n     * // it should match but isn't handled by this check\n     * ```\n     *\n     * `p.startsWith(`${path}.`)`\n     * @example\n     * ```js\n     * const path = 'foo.bar';\n     * const p = 'foo.bar.field';\n     * // it should match\n     *\n     * const path = 'foo.bar.field';\n     * const p = 'bar.foo';\n     * // it shouldn't match\n     *\n     * const path = 'foo.bar.field';\n     * const p = 'foo.bar';\n     * // it should match but isn't handled by this check\n     * ```\n     */\n    const isPathAllowed = allowedFields.some(\n      (p) => containedPaths.includes(p) || p.startsWith(`${path}.`)\n    );\n\n    if (isPathAllowed) {\n      return;\n    }\n\n    // Remove otherwise\n    remove(key);\n  };\n\n/**\n * Retrieve the list of allowed paths based on the given path\n *\n * @example\n * ```js\n * const containedPaths = getContainedPaths('foo');\n * // ['foo']\n *\n *  * const containedPaths = getContainedPaths('foo.bar');\n * // ['foo', 'foo.bar']\n *\n *  * const containedPaths = getContainedPaths('foo.bar.field');\n * // ['foo', 'foo.bar', 'foo.bar.field']\n * ```\n */\nconst getContainedPaths = (path: string) => {\n  const parts = toPath(path);\n\n  return parts.reduce((acc, value, index, list) => {\n    return [...acc, list.slice(0, index + 1).join('.')];\n  }, [] as string[]);\n};\n"],"names":["allowedFields","key","path","attribute","remove","isArray","every","isString","TypeError","isNil","containedPaths","getContainedPaths","isPathAllowed","some","p","includes","startsWith","parts","toPath","reduce","acc","value","index","list","slice","join"],"mappings":";;AAGA,6BAAe,CAAA,CAACA,aAAAA,GAAiC,IAAI,GACnD,CAAC,EAAEC,GAAG,EAAEC,IAAM,EAAA,EAAEC,WAAWD,IAAI,EAAE,EAAE,EAAE,EAAEE,MAAM,EAAE,GAAA;;AAE7C,QAAA,IAAIJ,kBAAkB,IAAM,EAAA;AAC1B,YAAA;AACF;;QAGA,IAAI,EAAEK,OAAQL,CAAAA,aAAAA,CAAAA,IAAkBA,cAAcM,KAAK,CAACC,SAAQ,CAAI,EAAA;YAC9D,MAAM,IAAIC,UACR,CAAC,qDAAqD,EAAE,OAAOR,aAAAA,CAAc,CAAC,CAAC,CAAA;AAEnF;AAEA,QAAA,IAAIS,MAAMP,IAAO,CAAA,EAAA;AACf,YAAA;AACF;AAEA,QAAA,MAAMQ,iBAAiBC,iBAAkBT,CAAAA,IAAAA,CAAAA;AAEzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCC,QACD,MAAMU,aAAgBZ,GAAAA,aAAAA,CAAca,IAAI,CACtC,CAACC,IAAMJ,cAAeK,CAAAA,QAAQ,CAACD,CAAAA,CAAAA,IAAMA,EAAEE,UAAU,CAAC,CAAC,EAAEd,IAAAA,CAAK,CAAC,CAAC,CAAA,CAAA;AAG9D,QAAA,IAAIU,aAAe,EAAA;AACjB,YAAA;AACF;;QAGAR,MAAOH,CAAAA,GAAAA,CAAAA;AACT,KAAA;AAEF;;;;;;;;;;;;;;IAeA,MAAMU,oBAAoB,CAACT,IAAAA,GAAAA;AACzB,IAAA,MAAMe,QAAQC,MAAOhB,CAAAA,IAAAA,CAAAA;AAErB,IAAA,OAAOe,MAAME,MAAM,CAAC,CAACC,GAAAA,EAAKC,OAAOC,KAAOC,EAAAA,IAAAA,GAAAA;QACtC,OAAO;AAAIH,YAAAA,GAAAA,GAAAA;AAAKG,YAAAA,IAAAA,CAAKC,KAAK,CAAC,CAAA,EAAGF,KAAQ,GAAA,CAAA,CAAA,CAAGG,IAAI,CAAC,GAAA;AAAK,SAAA;AACrD,KAAA,EAAG,EAAE,CAAA;AACP,CAAA;;;;"}