{"version":3,"sources":["../../../packages/tools/gulp-merge-json-in-folders/json-merge.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,OAAO;IACpB;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,SAAS;IAClB;;;;;;;;;;;;;;;;;;;;;OAqBG;IACI,kBAAkB,CAAC,oBAAoB,EAAE,MAAM,EAAE,qBAAqB,EAAE,MAAM,EAAE,GAAG,GAAG,EAAE;IAgC/F,OAAO,CAAC,YAAY;IAmBpB,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,MAAM;CA6BjB","file":"json-merge.d.ts","sourcesContent":["const fs = require('fs');\r\nconst vinyl = require('vinyl');\r\n\r\nexport interface Options {\r\n    /**\r\n     * source folder.\r\n     */\r\n    src: string;\r\n}\r\n\r\nexport class JsonMerge {\r\n    /**\r\n     * Recursively merges JSON files with the same name and same subPath from the sourceFolders into the JSON files\r\n     * in the targetFolderPath.\r\n     *\r\n     * @example\r\n     *  src/assets/resources/strings/ <- targetFolderPath\r\n     *                              strings.json\r\n     *                              es/strings.json\r\n     *                              pt/strings.json\r\n     * [\r\n     *     'node_modules/@msft-sme/core/dist/assets/resources/strings',\r\n     *     'node_modules/@msft-sme/ng2/dist/assets/resources/strings'\r\n     * ] <- sourceFoldersPath\r\n     *\r\n     *                               src/assets/resources/strings/strings.json contents are merged with the contents of\r\n     *  node_modules/@msft-sme/core/dist/assets/resources/strings/strings.json and\r\n     *  node_modules/@msft-ng2/core/dist/assets/resources/strings/strings.json\r\n     *  and the source file is overwritten by the merged content\r\n     *\r\n     * @param targetFolderPathRoot The path of the base folder where the destination files are placed.\r\n     * @param sourceFoldersPathRoot The array of paths to the source folders from where to read the JSON files to merge\r\n     */\r\n    public mergeJsonInFolders(targetFolderPathRoot: string, sourceFoldersPathRoot: string[]): any[] {\r\n        const outputFiles: any[] = [];\r\n        const targetFilesContentMap = {};\r\n        const targetFiles = this.getFilePaths(targetFolderPathRoot);\r\n        targetFiles.forEach((targetFile) => {\r\n            const relativePath = targetFile.substring(targetFolderPathRoot.length + 1, targetFile.length);\r\n            targetFilesContentMap[relativePath] = this.readJSON(targetFile);\r\n\r\n        });\r\n\r\n        sourceFoldersPathRoot.forEach((sourceFolderPathRoot) => {\r\n            const sourceFiles = this.getFilePaths(sourceFolderPathRoot);\r\n            sourceFiles.forEach((sourceFile) => {\r\n                const relativePath = sourceFile.substring(sourceFolderPathRoot.length + 1, sourceFile.length);\r\n                const sourceJson = this.readJSON(sourceFile);\r\n\r\n                this.mergeJsons(relativePath, sourceJson, targetFilesContentMap);\r\n            });\r\n        });\r\n\r\n        Object.keys(targetFilesContentMap).forEach(path => {\r\n            const jsonFile = new vinyl({\r\n                cwd: './',\r\n                path: path,\r\n                contents: Buffer.from(JSON.stringify(targetFilesContentMap[path]), 'utf8')\r\n            });\r\n            outputFiles.push(jsonFile);\r\n        });\r\n\r\n        return outputFiles;\r\n    }\r\n\r\n    private getFilePaths(dir, paths: string[] = []): string[] {\r\n        if (!dir.endsWith('/')) {\r\n            dir += '/';\r\n        }\r\n\r\n        const files = fs.readdirSync(dir);\r\n        files.forEach(file => {\r\n            const filePath = dir + file;\r\n            if (fs.statSync(filePath).isDirectory()) {\r\n                paths.concat(this.getFilePaths(filePath, paths));\r\n            } else {\r\n                paths.push(dir + file);\r\n            }\r\n\r\n        });\r\n\r\n        return paths;\r\n    }\r\n\r\n    private mergeJsons(relativePath: string, sourceJson: any, targetFilesContentMap: {}): void {\r\n        if (targetFilesContentMap[relativePath]) {\r\n            this.extend(targetFilesContentMap[relativePath], [sourceJson]);\r\n        } else {\r\n            targetFilesContentMap[relativePath] = sourceJson;\r\n        }\r\n    }\r\n\r\n    private readJSON(path: string): any {\r\n        return JSON.parse(fs.readFileSync(path, 'utf8'));\r\n    }\r\n\r\n    private isObject(value): boolean {\r\n        return value !== null && typeof value === 'object';\r\n    }\r\n\r\n    private isFunction(value): boolean {\r\n        return typeof value === 'function';\r\n    }\r\n\r\n    private extend(dest: any, sources: any[]): any {\r\n        if (!sources || sources.length === 0) {\r\n            return dest;\r\n        }\r\n\r\n        for (let i = 0; i < sources.length; i++) {\r\n            const src = sources[i];\r\n            // Cant extend primitives or null/undefined values. so skip them\r\n            if (!this.isObject(src) && !this.isFunction(src)) {\r\n                continue;\r\n            }\r\n            const keys = Object.keys(src);\r\n            let ki = keys.length;\r\n            while (ki--) {\r\n                const srcField = keys[ki];\r\n                const srcValue = src[srcField];\r\n                let destValue = srcValue;\r\n\r\n                if (this.isObject(srcValue) && !Array.isArray(srcValue)) {\r\n                    destValue = {};\r\n                    this.extend(destValue, [dest[srcField], srcValue]);\r\n                }\r\n\r\n                dest[srcField] = destValue;\r\n            }\r\n        }\r\n\r\n        return dest;\r\n    }\r\n}\r\n"]}