{"version":3,"sources":["../../../packages/tools/wac-cli/src/angular15/utils/file-writer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAErC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAK3C,MAAM,WAAW,cAAc;IAC3B,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,UAAU;IACnB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,iBAAiB,CAAS;IAElC;;;OAGG;IACI,OAAO;IAId;;;OAGG;gBACS,IAAI,EAAE,MAAM;IAKxB;;;;OAIG;IACI,QAAQ,CAAC,QAAQ,KAAA;IAKxB;;;OAGG;IACI,cAAc;IAUrB;;;;OAIG;IACI,cAAc,CAAC,KAAK,EAAE,MAAM;IAWnC;;;;;;;;OAQG;IACI,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,EAAE,EAAE,SAAS,UAAQ,EAAE,KAAK,SAAI,EAAE,SAAS,SAAI;IAyCxF;;;OAGG;IACI,gBAAgB,CAAC,OAAO,EAAE,MAAM;IAcvC;;;;OAIG;IACI,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,UAAQ;IAsB7D;;;;OAIG;IACI,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,UAAU,EAAE;IA0BnD;;;OAGG;IACI,SAAS;IAKhB;;;;OAIG;IACI,cAAc,CAAC,KAAK,EAAE,MAAM;IAYnC;;;;OAIG;IACI,sBAAsB,CAAC,KAAK,EAAE,MAAM;IAY3C;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAQpB;;;;OAIG;IACH,OAAO,CAAC,oBAAoB;IAK5B;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAoCvB,OAAO,CAAC,kBAAkB;IAqB1B,OAAO,CAAC,WAAW;CAKtB","file":"file-writer.d.ts","sourcesContent":["import { addItem } from \"./add-item\";\r\nimport { Logger } from \"./logger\";\r\nimport { removeItem } from \"./remove-item\";\r\nimport { spaceGenerator } from \"./space-generator\";\r\n\r\nconst fs = require('fs');\r\n\r\nexport interface FileWriterData {\r\n    filePath: string;\r\n}\r\n\r\nexport class FileWriter {\r\n    private data: string;\r\n    private filePath: string;\r\n    private needImportHandler = false;\r\n\r\n    /**\r\n     * the getter data.\r\n     * @returns the data.\r\n     */\r\n    public getData() {\r\n        return this.data;\r\n    }\r\n\r\n    /**\r\n     * the constructor.\r\n     * @param path the path.\r\n     */\r\n    constructor(path: string) {\r\n        Logger.log(path);\r\n        this.data = this.readFile(path);\r\n    }\r\n\r\n    /**\r\n     * the read file function.\r\n     * @param filePath the file path.\r\n     * @returns the file content.\r\n     */\r\n    public readFile(filePath) {\r\n        this.filePath = filePath;\r\n        return fs.readFileSync(filePath, 'utf8');\r\n    }\r\n\r\n    /**\r\n     * the tab to two spaces function.\r\n     * @returns this context.\r\n     */\r\n    public tabToTwoSpaces() {\r\n        const lines = this.data.split('\\n');\r\n\r\n        if (lines.length > 1 && /^    /.test(lines[1])) {\r\n            this.data = this.data.replace(/    /g, '  ');\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * replaces the version in version.json\r\n     * @param input the input.\r\n     * @returns \r\n     */\r\n    public replaceVersion(input: object) {\r\n        const regexPattern = /\"version\":\\s+\"(\\d+\\.\\d+\\.\\d+)\"/g;\r\n        \r\n        for (const [_, newKeyword] of Object.entries(input)) {\r\n            Logger.log(this.data)\r\n            this.data = this.data.replace(regexPattern, newKeyword);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * the add content function.\r\n     * the default indent count should be matching with addBefore or addAfter.\r\n     * @param input the input.\r\n     * @param wholeLine the whole line flag.\r\n     * @param space the space number.\r\n     * @param connector the connector.\r\n     * @returns this context.\r\n     */\r\n    public addContent(input: object | addItem[], wholeLine = false, space = 4, connector=',') {\r\n        if (typeof input === 'object' && !Array.isArray(input)) {\r\n            for (const [oldKeyword, newKeyword] of Object.entries(input)) {\r\n                if (!this.checkIfKeywordExists(newKeyword)) {\r\n                    const regex = wholeLine ? new RegExp(`^${this.escapeRegExp(oldKeyword)}$`, 'gm') : new RegExp(this.escapeRegExp(oldKeyword), 'g');\r\n                    this.data = this.data.replace(regex, `${oldKeyword}${connector}\\n${spaceGenerator(space)}${newKeyword}`);\r\n                }\r\n            }\r\n        } else {\r\n            for(let i = 0; i < input.length; i++) {\r\n                let item = input[i];\r\n                if (!this.checkIfKeywordExists(item.toBeAdded) && !this.checkIfKeywordExists(item.keyword)) {\r\n                    let indent = '';\r\n\r\n                    if (item.needImportHandler && (\r\n                        item.toBeAddedBefore && this.checkIfKeywordExists(item.toBeAddedBefore) || item.toBeAddedAfter && this.checkIfKeywordExists(item.toBeAddedAfter))) {\r\n                        this.needImportHandler = true;\r\n                    }\r\n\r\n                    if (item.toBeAddedAfter) {\r\n                        indent = spaceGenerator(this.getIndentByKeyword(this.data, item.toBeAddedAfter));\r\n                        const regex = wholeLine ? new RegExp(`^${this.escapeRegExp(item.toBeAddedAfter)}$`, 'gm') : new RegExp(this.escapeRegExp(item.toBeAddedAfter), 'g');\r\n                        this.data = this.data.replace(\r\n                            regex,\r\n                            `${item.toBeAddedAfter}${item.connector === undefined ? connector : item.connector}\\n${indent}${item.toBeAdded}`);\r\n                    } else if (item.toBeAddedBefore) {\r\n                        if (item.toBeAddedBefore) {\r\n                            indent = spaceGenerator(this.getIndentByKeyword(this.data, item.toBeAddedBefore));\r\n                        }\r\n                        const regex = wholeLine ? new RegExp(`^${this.escapeRegExp(item.toBeAddedBefore)}$`, 'gm') : new RegExp(this.escapeRegExp(item.toBeAddedBefore), 'g');\r\n                        this.data = this.data.replace(\r\n                            regex,\r\n                            `${item.toBeAdded}\\n${indent}${item.toBeAddedBefore}`);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * the fix imports function.\r\n     * @returns this context.\r\n     */\r\n    public fixImportHandler(imports: string) {\r\n        if (!this.needImportHandler) {\r\n            return this;\r\n        }\r\n\r\n        this.needImportHandler = false;\r\n\r\n        this.importFixer(imports);\r\n\r\n        Logger.log(imports);\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * the replace dependency version function.\r\n     * @param input the input.\r\n     * @returns the this context.\r\n     */\r\n    public replaceDependencyVersion(input: object, ignore = false) {\r\n        if (ignore) {\r\n            return this;\r\n        }\r\n\r\n        for (const [oldKeyword, newKeyword] of Object.entries(input)) {\r\n            const oldKeywordRegex = new RegExp(\r\n                `\"${this.escapeRegExp(oldKeyword.match(/\"([^\"]+)\"/)[1])}\": \"\\\\d+\\\\.\\\\d+\\\\.\\\\d+\"`,\r\n                'g'\r\n            );\r\n            this.data = this.data.replace(oldKeywordRegex, newKeyword);\r\n\r\n            const oldKeywordRegex2 = new RegExp(\r\n                `\"${this.escapeRegExp(oldKeyword.match(/\"([^\"]+)\"/)[1])}\": [\"^~]+\\\\d+\\\\.\\\\d+\\\\.\\\\d+\"`,\r\n                'g'\r\n            );\r\n            this.data = this.data.replace(oldKeywordRegex2, newKeyword);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * the remove content function.\r\n     * @param input the input array.\r\n     * @returns the this context.\r\n     */\r\n    public removeContent(input: string[] | removeItem[]) {\r\n        if (!input || !input.length) {\r\n            return this;\r\n        }\r\n\r\n        if (typeof input[0] === 'string') {\r\n            this.data = this.data.split('\\n')\r\n            .filter(line => {\r\n                return !input.some(keyword => line.includes(keyword))\r\n            })\r\n            .join('\\n');\r\n        } else {\r\n            let tempData = this.data.split('\\n');\r\n            for (let i = 0; i < input.length; i++) {\r\n                if (!(<removeItem>input[i]).exactMatch) {\r\n                    tempData = this.removeByKeyword(tempData, (<removeItem>input[i]).key, (<removeItem>input[i]).linesInTotalAfterKey, (<removeItem>input[i]).toBeRemovedAfter);\r\n                } else {\r\n                    tempData.splice(tempData.indexOf((<removeItem>input[i]).key), (<removeItem>input[i]).linesInTotalAfterKey);\r\n                }\r\n                this.data = tempData.join('\\n');\r\n            }\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * the write file function.\r\n     * @returns the write file result.\r\n     */\r\n    public writeFile() {\r\n        fs.writeFileSync(this.filePath, this.data);\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * the replace content function.\r\n     * @param input the input object\r\n     * @returns the this context\r\n     */\r\n    public replaceContent(input: object) {\r\n        for (const [oldKeyword, newKeyword] of Object.entries(input)) {\r\n            const oldKeywordRegex = new RegExp(\r\n                `${this.escapeRegExp(oldKeyword)}`,\r\n                'gi'\r\n            );\r\n            this.data = this.data.replace(oldKeywordRegex, newKeyword);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * the replace tsconfig content function.\r\n     * @param input the input object\r\n     * @returns the this context\r\n     */\r\n    public replaceTsConfigContent(input: object) {\r\n        for (const [oldKeyword, newKeyword] of Object.entries(input)) {\r\n            const oldKeywordRegex = new RegExp(\r\n                `\"${this.escapeRegExp(oldKeyword.match(/\"([^\"]+)\"/)[1])}\":\\\\s*\"[^\"]+\"`,\r\n                'gi'\r\n            );\r\n            this.data = this.data.replace(oldKeywordRegex, newKeyword);\r\n        }\r\n\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * the escape for RegExp function.\r\n     * @param string the string to escape\r\n     * @returns the escaped string\r\n     */\r\n    private escapeRegExp(string) {\r\n        if (string && string.length) {\r\n            return string.replace(/[.*+\\-?^${}()|[\\]\\\\]/g, '\\\\$&');\r\n        }\r\n\r\n        return string;\r\n    }\r\n\r\n    /**\r\n     * the check if dependency exists function.\r\n     * @param newKeyword the new keyword to check\r\n     * @returns the boolean value\r\n     */\r\n    private checkIfKeywordExists(newKeyword: string): boolean {\r\n        const regex = new RegExp(this.escapeRegExp(newKeyword), 'g');\r\n        return regex.exec(this.data) ? true : false;\r\n    }\r\n\r\n    /**\r\n     * removes the next n items after the index of the string containing the keyword\r\n     * @param array the file content array\r\n     * @param keyword the keyword, removeItem.key\r\n     */\r\n    private removeByKeyword(array: string[], keyword = '', removeIndex = 1, toBeRemovedAfter = undefined) {\r\n        let startIndex = -1;\r\n        const indent = spaceGenerator(4);\r\n        if (toBeRemovedAfter) {\r\n            startIndex = array.findIndex((arrayItem) => arrayItem.includes(toBeRemovedAfter));\r\n            // If the marker for toBeRemovedAfter is not found, return the original array\r\n            // No-op\r\n            if (startIndex === -1) {\r\n                return array;\r\n            }\r\n        }\r\n        const index = array.findIndex((arrayItem, i) => {\r\n            if (arrayItem.includes(keyword)) {\r\n                if (i < startIndex) {\r\n                    return false;\r\n                } else {\r\n                    return true;\r\n                }\r\n            }\r\n            return false;\r\n        });\r\n\r\n        if (index !== -1) {\r\n            if (index < array.length - removeIndex) {\r\n                array.splice(index, removeIndex);\r\n                Logger.log(`Removed the next ${removeIndex} items after index ${index}.`, indent);\r\n            } else {\r\n                Logger.log(`No ${removeIndex} items to remove after index ${index}.`, indent);\r\n            }\r\n        } else {\r\n            Logger.log(`No string containing '${keyword}' was found.`, indent);\r\n        }\r\n\r\n        return array;\r\n    }\r\n\r\n    private getIndentByKeyword(input: string, target: string): number {\r\n        const lines = input.split(/\\r?\\n/);\r\n        let leadingSpaces = 0;\r\n\r\n        for (let line of lines) {\r\n            if (line.includes(target)) {\r\n                for (let char of line) {\r\n                    if (char === ' ') {\r\n                        leadingSpaces++;\r\n                    } else {\r\n                        break;\r\n                    }\r\n                }\r\n                Logger.log(`There are ${leadingSpaces} spaces before \"${target}\" on this line.`);\r\n                break;\r\n            }\r\n        }\r\n\r\n        return leadingSpaces;\r\n    }\r\n\r\n    private importFixer(imports: string): void {\r\n        if (!this.data.includes(imports)) {\r\n            this.data = imports + '\\n' + this.data;\r\n        }\r\n    }\r\n}\r\n"]}