188c88e8eSopenharmony_ci/*
288c88e8eSopenharmony_ci * Licensed to the Apache Software Foundation (ASF) under one
388c88e8eSopenharmony_ci * or more contributor license agreements.  See the NOTICE file
488c88e8eSopenharmony_ci * distributed with this work for additional information
588c88e8eSopenharmony_ci * regarding copyright ownership.  The ASF licenses this file
688c88e8eSopenharmony_ci * to you under the Apache License, Version 2.0 (the
788c88e8eSopenharmony_ci * "License"); you may not use this file except in compliance
888c88e8eSopenharmony_ci * with the License.  You may obtain a copy of the License at
988c88e8eSopenharmony_ci *
1088c88e8eSopenharmony_ci *   http://www.apache.org/licenses/LICENSE-2.0
1188c88e8eSopenharmony_ci *
1288c88e8eSopenharmony_ci * Unless required by applicable law or agreed to in writing,
1388c88e8eSopenharmony_ci * software distributed under the License is distributed on an
1488c88e8eSopenharmony_ci * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1588c88e8eSopenharmony_ci * KIND, either express or implied.  See the License for the
1688c88e8eSopenharmony_ci * specific language governing permissions and limitations
1788c88e8eSopenharmony_ci * under the License.
1888c88e8eSopenharmony_ci */
1988c88e8eSopenharmony_ci
2088c88e8eSopenharmony_ciimport path from 'path'
2188c88e8eSopenharmony_ciimport fs from 'fs'
2288c88e8eSopenharmony_ciimport loaderUtils from 'loader-utils'
2388c88e8eSopenharmony_ciconst crypto = require("crypto")
2488c88e8eSopenharmony_ciimport {
2588c88e8eSopenharmony_ci  SourceMapGenerator,
2688c88e8eSopenharmony_ci  SourceMapConsumer
2788c88e8eSopenharmony_ci} from 'source-map'
2888c88e8eSopenharmony_ci
2988c88e8eSopenharmony_ciconst { systemModules } =  require('../main.product')
3088c88e8eSopenharmony_ciconst { DEVICE_LEVEL } = require('./lite/lite-enum')
3188c88e8eSopenharmony_ciexport const useOSFiles = new Set();
3288c88e8eSopenharmony_ciexport const elements = {};
3388c88e8eSopenharmony_ci
3488c88e8eSopenharmony_ciexport function getNameByPath (resourcePath) {
3588c88e8eSopenharmony_ci  return path.basename(resourcePath).replace(/\..*$/, '')
3688c88e8eSopenharmony_ci}
3788c88e8eSopenharmony_ci
3888c88e8eSopenharmony_ciexport function getFileNameWithHash (resourcePath, content) {
3988c88e8eSopenharmony_ci  const filename = path.relative('.', resourcePath)
4088c88e8eSopenharmony_ci  const hash = crypto.createHash('sha256')
4188c88e8eSopenharmony_ci  hash.update((filename + content).toString())
4288c88e8eSopenharmony_ci  const cacheKey = hash.digest('hex')
4388c88e8eSopenharmony_ci  return `./${filename}?${cacheKey}`
4488c88e8eSopenharmony_ci}
4588c88e8eSopenharmony_ci
4688c88e8eSopenharmony_ciexport function getFilenameByPath (filepath) {
4788c88e8eSopenharmony_ci  return path.relative('.', filepath)
4888c88e8eSopenharmony_ci}
4988c88e8eSopenharmony_ci
5088c88e8eSopenharmony_ciexport const FUNC_START = '#####FUN_S#####'
5188c88e8eSopenharmony_ciexport const FUNC_START_REG = new RegExp('["\']' + FUNC_START, 'g')
5288c88e8eSopenharmony_ciexport const FUNC_END = '#####FUN_E#####'
5388c88e8eSopenharmony_ciexport const FUNC_END_REG = new RegExp(FUNC_END + '["\']', 'g')
5488c88e8eSopenharmony_ci
5588c88e8eSopenharmony_ciexport function stringifyFunction (key, value) {
5688c88e8eSopenharmony_ci  if (typeof value === 'function') {
5788c88e8eSopenharmony_ci    return FUNC_START + value.toString() + FUNC_END
5888c88e8eSopenharmony_ci  }
5988c88e8eSopenharmony_ci  return value
6088c88e8eSopenharmony_ci}
6188c88e8eSopenharmony_ci
6288c88e8eSopenharmony_ciexport function logWarn (loader, logs) {
6388c88e8eSopenharmony_ci  // add flag to determine if there is an error log
6488c88e8eSopenharmony_ci  let flag = false
6588c88e8eSopenharmony_ci  if (process.env.logLevel > 0) {
6688c88e8eSopenharmony_ci    if (logs && logs.length) {
6788c88e8eSopenharmony_ci      logs.forEach(log => {
6888c88e8eSopenharmony_ci        if (log.reason.startsWith('NOTE') && parseInt(process.env.logLevel) <= 1) {
6988c88e8eSopenharmony_ci          if (log.line && log.column) {
7088c88e8eSopenharmony_ci            loader.emitWarning('noteStartNOTE File:' + loader.resourcePath + ':' +
7188c88e8eSopenharmony_ci              log.line + ':' + log.column + '\n ' + log.reason.replace('NOTE: ', '') + 'noteEnd')
7288c88e8eSopenharmony_ci          } else {
7388c88e8eSopenharmony_ci            loader.emitWarning('noteStartNOTE File:' + loader.resourcePath +
7488c88e8eSopenharmony_ci              '\n ' + log.reason.replace('NOTE: ', '') + 'noteEnd')
7588c88e8eSopenharmony_ci          }
7688c88e8eSopenharmony_ci        } else if (log.reason.startsWith('WARN') && parseInt(process.env.logLevel) <= 2) {
7788c88e8eSopenharmony_ci          if (log.line && log.column) {
7888c88e8eSopenharmony_ci            loader.emitWarning('warnStartWARNING File:' + loader.resourcePath + ':' +
7988c88e8eSopenharmony_ci              log.line + ':' + log.column + '\n ' + log.reason.replace('WARNING: ', '') + 'warnEnd')
8088c88e8eSopenharmony_ci          } else {
8188c88e8eSopenharmony_ci            loader.emitWarning('warnStartWARNING File:' + loader.resourcePath +
8288c88e8eSopenharmony_ci              '\n ' + log.reason.replace('WARNING: ', '') + 'warnEnd')
8388c88e8eSopenharmony_ci          }
8488c88e8eSopenharmony_ci        } else if (log.reason.startsWith('ERROR') && parseInt(process.env.logLevel) <= 3) {
8588c88e8eSopenharmony_ci          flag = true
8688c88e8eSopenharmony_ci          if (log.line && log.column) {
8788c88e8eSopenharmony_ci            loader.emitError('errorStartERROR File:' + loader.resourcePath + ':' +
8888c88e8eSopenharmony_ci              log.line + ':' + log.column + '\n ' + log.reason.replace('ERROR: ', '') + 'errorEnd')
8988c88e8eSopenharmony_ci          } else {
9088c88e8eSopenharmony_ci            loader.emitError('errorStartERROR File:' + loader.resourcePath +
9188c88e8eSopenharmony_ci              '\n ' + log.reason.replace('ERROR: ', '') + 'errorEnd')
9288c88e8eSopenharmony_ci          }
9388c88e8eSopenharmony_ci        }
9488c88e8eSopenharmony_ci      })
9588c88e8eSopenharmony_ci    }
9688c88e8eSopenharmony_ci  }
9788c88e8eSopenharmony_ci  return flag
9888c88e8eSopenharmony_ci}
9988c88e8eSopenharmony_ci
10088c88e8eSopenharmony_ciexport function getRequireString (loaderContext, loader, filepath) {
10188c88e8eSopenharmony_ci  return 'require(' +
10288c88e8eSopenharmony_ci                loaderUtils.stringifyRequest(
10388c88e8eSopenharmony_ci                  loaderContext,
10488c88e8eSopenharmony_ci                  loader ?
10588c88e8eSopenharmony_ci                    `!!${loader}!${filepath}` :
10688c88e8eSopenharmony_ci                    `${filepath}`
10788c88e8eSopenharmony_ci                ) +
10888c88e8eSopenharmony_ci           ')\n'
10988c88e8eSopenharmony_ci}
11088c88e8eSopenharmony_ci
11188c88e8eSopenharmony_ciexport function stringifyLoaders (loaders) {
11288c88e8eSopenharmony_ci  return loaders.map(loader => {
11388c88e8eSopenharmony_ci    if (typeof loader === 'string') {
11488c88e8eSopenharmony_ci      return loader
11588c88e8eSopenharmony_ci    }
11688c88e8eSopenharmony_ci    else {
11788c88e8eSopenharmony_ci      const name = loader.name
11888c88e8eSopenharmony_ci      const query = []
11988c88e8eSopenharmony_ci      if (loader.query) {
12088c88e8eSopenharmony_ci        for (const k in loader.query) {
12188c88e8eSopenharmony_ci          const v = loader.query[k]
12288c88e8eSopenharmony_ci          if (v != null) {
12388c88e8eSopenharmony_ci            if (v === true) {
12488c88e8eSopenharmony_ci              query.push(k)
12588c88e8eSopenharmony_ci            }
12688c88e8eSopenharmony_ci            else if (v instanceof Array) {
12788c88e8eSopenharmony_ci              query.push(`${k}[]=${v.join(',')}`)
12888c88e8eSopenharmony_ci            }
12988c88e8eSopenharmony_ci            else {
13088c88e8eSopenharmony_ci              query.push(`${k}=${v}`)
13188c88e8eSopenharmony_ci            }
13288c88e8eSopenharmony_ci          }
13388c88e8eSopenharmony_ci        }
13488c88e8eSopenharmony_ci      }
13588c88e8eSopenharmony_ci      return `${name}${query.length ? ('?' + query.join('&')) : ''}`
13688c88e8eSopenharmony_ci    }
13788c88e8eSopenharmony_ci  }).join('!')
13888c88e8eSopenharmony_ci}
13988c88e8eSopenharmony_ci
14088c88e8eSopenharmony_ciexport function generateMap (loader, source, iterator) {
14188c88e8eSopenharmony_ci  const filePath = loader.resourcePath
14288c88e8eSopenharmony_ci
14388c88e8eSopenharmony_ci  const fileNameWithHash = getFileNameWithHash(filePath)
14488c88e8eSopenharmony_ci  const sourceRoot = path.resolve('.')
14588c88e8eSopenharmony_ci
14688c88e8eSopenharmony_ci  const map = new SourceMapGenerator({
14788c88e8eSopenharmony_ci    sourceRoot,
14888c88e8eSopenharmony_ci    skipValidation: true
14988c88e8eSopenharmony_ci  })
15088c88e8eSopenharmony_ci  map.setSourceContent(fileNameWithHash, source)
15188c88e8eSopenharmony_ci
15288c88e8eSopenharmony_ci  for (const { original, generated } of iterator) {
15388c88e8eSopenharmony_ci    map.addMapping({
15488c88e8eSopenharmony_ci      source: fileNameWithHash,
15588c88e8eSopenharmony_ci      original,
15688c88e8eSopenharmony_ci      generated
15788c88e8eSopenharmony_ci    })
15888c88e8eSopenharmony_ci  }
15988c88e8eSopenharmony_ci
16088c88e8eSopenharmony_ci  return map
16188c88e8eSopenharmony_ci}
16288c88e8eSopenharmony_ci
16388c88e8eSopenharmony_ciexport function consumeMap (loader, target, map) {
16488c88e8eSopenharmony_ci  const smc = new SourceMapConsumer(map)
16588c88e8eSopenharmony_ci  let source
16688c88e8eSopenharmony_ci  const original = []
16788c88e8eSopenharmony_ci  const generated = []
16888c88e8eSopenharmony_ci  const mapping = {}
16988c88e8eSopenharmony_ci
17088c88e8eSopenharmony_ci  splitSourceLine(target)
17188c88e8eSopenharmony_ci    .forEach((input, line) => {
17288c88e8eSopenharmony_ci      const column = 0
17388c88e8eSopenharmony_ci      line = line + 1
17488c88e8eSopenharmony_ci
17588c88e8eSopenharmony_ci      const pos = smc.originalPositionFor({
17688c88e8eSopenharmony_ci        line,
17788c88e8eSopenharmony_ci        column
17888c88e8eSopenharmony_ci      })
17988c88e8eSopenharmony_ci
18088c88e8eSopenharmony_ci      if (pos.source) {
18188c88e8eSopenharmony_ci        source = pos.source
18288c88e8eSopenharmony_ci        original.push({
18388c88e8eSopenharmony_ci          line: pos.line,
18488c88e8eSopenharmony_ci          column: pos.column
18588c88e8eSopenharmony_ci        })
18688c88e8eSopenharmony_ci        generated.push({
18788c88e8eSopenharmony_ci          line,
18888c88e8eSopenharmony_ci          column
18988c88e8eSopenharmony_ci        })
19088c88e8eSopenharmony_ci        mapping[`line-${line}-column-${column}`] = {
19188c88e8eSopenharmony_ci          line: pos.line,
19288c88e8eSopenharmony_ci          column: pos.column
19388c88e8eSopenharmony_ci        }
19488c88e8eSopenharmony_ci      }
19588c88e8eSopenharmony_ci    })
19688c88e8eSopenharmony_ci
19788c88e8eSopenharmony_ci  return {
19888c88e8eSopenharmony_ci    source,
19988c88e8eSopenharmony_ci    original,
20088c88e8eSopenharmony_ci    generated,
20188c88e8eSopenharmony_ci    mapping,
20288c88e8eSopenharmony_ci    sourcesContent: smc.sourcesContent
20388c88e8eSopenharmony_ci  }
20488c88e8eSopenharmony_ci}
20588c88e8eSopenharmony_ci
20688c88e8eSopenharmony_ciconst LINE_REG = /\r?\n/g
20788c88e8eSopenharmony_ciexport function splitSourceLine (source) {
20888c88e8eSopenharmony_ci  return source.split(LINE_REG)
20988c88e8eSopenharmony_ci}
21088c88e8eSopenharmony_ci
21188c88e8eSopenharmony_ciexport function printSourceWithLine (source) {
21288c88e8eSopenharmony_ci  console.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
21388c88e8eSopenharmony_ci  source = splitSourceLine(source)
21488c88e8eSopenharmony_ci    .map((input, line) => {
21588c88e8eSopenharmony_ci      console.log(line + 1 + ':', input)
21688c88e8eSopenharmony_ci    })
21788c88e8eSopenharmony_ci  console.log('<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<')
21888c88e8eSopenharmony_ci}
21988c88e8eSopenharmony_ci
22088c88e8eSopenharmony_ciexport function loadBabelModule (moduleName) {
22188c88e8eSopenharmony_ci  try {
22288c88e8eSopenharmony_ci    const filePath = require.resolve(moduleName)
22388c88e8eSopenharmony_ci    return filePath.slice(0, filePath.indexOf(moduleName.replace(/\//g, path.sep)) + moduleName.length)
22488c88e8eSopenharmony_ci  }
22588c88e8eSopenharmony_ci  catch (e) {
22688c88e8eSopenharmony_ci    return moduleName
22788c88e8eSopenharmony_ci  }
22888c88e8eSopenharmony_ci}
22988c88e8eSopenharmony_ci
23088c88e8eSopenharmony_ciconst methodForLite =
23188c88e8eSopenharmony_ci`
23288c88e8eSopenharmony_cifunction requireModule(moduleName) {
23388c88e8eSopenharmony_ci  return requireNative(moduleName.slice(1));
23488c88e8eSopenharmony_ci}
23588c88e8eSopenharmony_ci`
23688c88e8eSopenharmony_ciconst methodForOthers =
23788c88e8eSopenharmony_ci`
23888c88e8eSopenharmony_cifunction requireModule(moduleName) {
23988c88e8eSopenharmony_ci  const systemList = ['system.router', 'system.app', 'system.prompt', 'system.configuration',
24088c88e8eSopenharmony_ci  'system.image', 'system.device', 'system.mediaquery', 'ohos.animator', 'system.grid', 'system.resource']
24188c88e8eSopenharmony_ci  var target = ''
24288c88e8eSopenharmony_ci  if (systemList.includes(moduleName.replace('@', ''))) {
24388c88e8eSopenharmony_ci    target = $app_require$('@app-module/' + moduleName.substring(1));
24488c88e8eSopenharmony_ci    return target;
24588c88e8eSopenharmony_ci  }
24688c88e8eSopenharmony_ci  var shortName = moduleName.replace(/@[^.]+\.([^.]+)/, '$1');
24788c88e8eSopenharmony_ci  target = requireNapi(shortName);
24888c88e8eSopenharmony_ci  if (typeof target !== 'undefined' && /@ohos/.test(moduleName)) {
24988c88e8eSopenharmony_ci    return target;
25088c88e8eSopenharmony_ci  }
25188c88e8eSopenharmony_ci  if (typeof ohosplugin !== 'undefined' && /@ohos/.test(moduleName)) {
25288c88e8eSopenharmony_ci    target = ohosplugin;
25388c88e8eSopenharmony_ci    for (let key of shortName.split('.')) {
25488c88e8eSopenharmony_ci      target = target[key];
25588c88e8eSopenharmony_ci      if(!target) {
25688c88e8eSopenharmony_ci        break;
25788c88e8eSopenharmony_ci      }
25888c88e8eSopenharmony_ci    }
25988c88e8eSopenharmony_ci    if (typeof target !== 'undefined') {
26088c88e8eSopenharmony_ci      return target;
26188c88e8eSopenharmony_ci    }
26288c88e8eSopenharmony_ci  }
26388c88e8eSopenharmony_ci  if (typeof systemplugin !== 'undefined') {
26488c88e8eSopenharmony_ci    target = systemplugin;
26588c88e8eSopenharmony_ci    for (let key of shortName.split('.')) {
26688c88e8eSopenharmony_ci      target = target[key];
26788c88e8eSopenharmony_ci      if(!target) {
26888c88e8eSopenharmony_ci        break;
26988c88e8eSopenharmony_ci      }
27088c88e8eSopenharmony_ci    }
27188c88e8eSopenharmony_ci    if (typeof target !== 'undefined') {
27288c88e8eSopenharmony_ci      return target;
27388c88e8eSopenharmony_ci    }
27488c88e8eSopenharmony_ci  }
27588c88e8eSopenharmony_ci  return target;
27688c88e8eSopenharmony_ci}
27788c88e8eSopenharmony_ci`
27888c88e8eSopenharmony_ciexport function parseRequireModule (source, resourcePath) {
27988c88e8eSopenharmony_ci  const requireMethod = process.env.DEVICE_LEVEL === DEVICE_LEVEL.LITE ? methodForLite : methodForOthers
28088c88e8eSopenharmony_ci  source = `${source}\n${requireMethod}`
28188c88e8eSopenharmony_ci  const requireReg = /require\(['"]([^()]+)['"]\)/g
28288c88e8eSopenharmony_ci  const libReg = /^lib(.+)\.so$/
28388c88e8eSopenharmony_ci  const REG_SYSTEM = /@(system|ohos)\.(\S+)/g;
28488c88e8eSopenharmony_ci  let requireStatements = source.match(requireReg)
28588c88e8eSopenharmony_ci  if (requireStatements && requireStatements.length) {
28688c88e8eSopenharmony_ci    for (let requireStatement of requireStatements) {
28788c88e8eSopenharmony_ci      const requireStatementExec = /\((\"|\')(.+)(\"|\')\)/.exec(requireStatement);
28888c88e8eSopenharmony_ci      if (requireStatement.match(REG_SYSTEM) && requireStatementExec && requireStatementExec.length > 3) {
28988c88e8eSopenharmony_ci        if (systemModules.length === 0 || systemModules.includes(requireStatementExec[2] + '.d.ts') ||
29088c88e8eSopenharmony_ci          process.env.DEVICE_LEVEL === 'lite') {
29188c88e8eSopenharmony_ci          source = source.replace(requireStatement, requireStatement.replace('require', 'requireModule'));
29288c88e8eSopenharmony_ci        }
29388c88e8eSopenharmony_ci      }
29488c88e8eSopenharmony_ci    }
29588c88e8eSopenharmony_ci  }
29688c88e8eSopenharmony_ci  source = source.replace(requireReg, (item, item1) => {
29788c88e8eSopenharmony_ci    if (libReg.test(item1)) {
29888c88e8eSopenharmony_ci      item = `requireNapi("${item1.replace(libReg, '$1')}", true)`
29988c88e8eSopenharmony_ci      if (resourcePath) {
30088c88e8eSopenharmony_ci        useOSFiles.add(resourcePath);
30188c88e8eSopenharmony_ci      }
30288c88e8eSopenharmony_ci    }
30388c88e8eSopenharmony_ci    return item
30488c88e8eSopenharmony_ci  })
30588c88e8eSopenharmony_ci  return source
30688c88e8eSopenharmony_ci}
30788c88e8eSopenharmony_ci
30888c88e8eSopenharmony_ciexport function jsonLoaders (type, customLoader, isVisual, queryType) {
30988c88e8eSopenharmony_ci  let loaders = []
31088c88e8eSopenharmony_ci
31188c88e8eSopenharmony_ci  switch (type) {
31288c88e8eSopenharmony_ci    case "template":
31388c88e8eSopenharmony_ci      loaders = [{
31488c88e8eSopenharmony_ci        name: path.resolve(__dirname, 'json.js')
31588c88e8eSopenharmony_ci      }, {
31688c88e8eSopenharmony_ci        name: path.resolve(__dirname, 'template.js')
31788c88e8eSopenharmony_ci      }]
31888c88e8eSopenharmony_ci      break
31988c88e8eSopenharmony_ci    case "style":
32088c88e8eSopenharmony_ci      loaders = [{
32188c88e8eSopenharmony_ci        name: path.resolve(__dirname, 'json.js')
32288c88e8eSopenharmony_ci      }, {
32388c88e8eSopenharmony_ci        name: path.resolve(__dirname, 'style.js')
32488c88e8eSopenharmony_ci      }]
32588c88e8eSopenharmony_ci      break
32688c88e8eSopenharmony_ci    case "json":
32788c88e8eSopenharmony_ci      loaders = [{
32888c88e8eSopenharmony_ci        name: path.resolve(__dirname, 'json.js')
32988c88e8eSopenharmony_ci      }]
33088c88e8eSopenharmony_ci      break
33188c88e8eSopenharmony_ci    default:
33288c88e8eSopenharmony_ci      break
33388c88e8eSopenharmony_ci  }
33488c88e8eSopenharmony_ci
33588c88e8eSopenharmony_ci  if (customLoader) {
33688c88e8eSopenharmony_ci    loaders.push({
33788c88e8eSopenharmony_ci      name: path.resolve(__dirname, `../node_modules/${customLoader}`)
33888c88e8eSopenharmony_ci    })
33988c88e8eSopenharmony_ci  }
34088c88e8eSopenharmony_ci
34188c88e8eSopenharmony_ci  if (isVisual) {
34288c88e8eSopenharmony_ci    loaders.push({
34388c88e8eSopenharmony_ci      name: path.resolve(__dirname, 'extgen.js'),
34488c88e8eSopenharmony_ci      query: {
34588c88e8eSopenharmony_ci        type: queryType
34688c88e8eSopenharmony_ci      }
34788c88e8eSopenharmony_ci    })
34888c88e8eSopenharmony_ci  }
34988c88e8eSopenharmony_ci
35088c88e8eSopenharmony_ci  return stringifyLoaders(loaders)
35188c88e8eSopenharmony_ci}
35288c88e8eSopenharmony_ci
35388c88e8eSopenharmony_ciexport function circularFile(inputPath, outputPath) {
35488c88e8eSopenharmony_ci  if ((!inputPath) || (!outputPath)) {
35588c88e8eSopenharmony_ci    return;
35688c88e8eSopenharmony_ci  }
35788c88e8eSopenharmony_ci  fs.readdir(inputPath,function(err, files){
35888c88e8eSopenharmony_ci    if (!files) {
35988c88e8eSopenharmony_ci      return;
36088c88e8eSopenharmony_ci    }
36188c88e8eSopenharmony_ci    files.forEach(file => {
36288c88e8eSopenharmony_ci      const inputFile = path.resolve(inputPath, file);
36388c88e8eSopenharmony_ci      const outputFile = path.resolve(outputPath, file);
36488c88e8eSopenharmony_ci      const fileStat = fs.statSync(inputFile);
36588c88e8eSopenharmony_ci      if (fileStat.isFile()) {
36688c88e8eSopenharmony_ci        copyFile(inputFile, outputFile);
36788c88e8eSopenharmony_ci      } else {
36888c88e8eSopenharmony_ci        circularFile(inputFile, outputFile);
36988c88e8eSopenharmony_ci      }
37088c88e8eSopenharmony_ci    });
37188c88e8eSopenharmony_ci  })
37288c88e8eSopenharmony_ci}
37388c88e8eSopenharmony_ci
37488c88e8eSopenharmony_cifunction copyFile(inputFile, outputFile) {
37588c88e8eSopenharmony_ci  try {
37688c88e8eSopenharmony_ci    const parent = path.join(outputFile, '..');
37788c88e8eSopenharmony_ci    if (!(fs.existsSync(parent) && fs.statSync(parent).isDirectory())) {
37888c88e8eSopenharmony_ci      mkDir(parent);
37988c88e8eSopenharmony_ci    }
38088c88e8eSopenharmony_ci    if (path.parse(parent).name === 'i18n' && path.parse(inputFile).ext === '.json' &&
38188c88e8eSopenharmony_ci      fs.existsSync(outputFile)) {
38288c88e8eSopenharmony_ci        copyJsonFile(inputFile, outputFile);
38388c88e8eSopenharmony_ci    } else if (!fs.existsSync(outputFile)){
38488c88e8eSopenharmony_ci      fs.writeFileSync(outputFile, fs.readFileSync(inputFile));
38588c88e8eSopenharmony_ci    }
38688c88e8eSopenharmony_ci  } catch (err) {
38788c88e8eSopenharmony_ci    throw err;
38888c88e8eSopenharmony_ci  }
38988c88e8eSopenharmony_ci}
39088c88e8eSopenharmony_ci
39188c88e8eSopenharmony_cifunction copyJsonFile(inputFile, outputFile) {
39288c88e8eSopenharmony_ci  try {
39388c88e8eSopenharmony_ci    const contentInput = JSON.parse(fs.readFileSync(inputFile, 'utf-8'));
39488c88e8eSopenharmony_ci    const contentOutput = JSON.parse(fs.readFileSync(outputFile, 'utf-8'));
39588c88e8eSopenharmony_ci    Object.keys(contentInput).forEach(function (key) {
39688c88e8eSopenharmony_ci      const contentElementMerge = mergeJson(contentInput[key], contentOutput[key]);
39788c88e8eSopenharmony_ci      contentOutput[key] = contentElementMerge;
39888c88e8eSopenharmony_ci    });
39988c88e8eSopenharmony_ci    fs.writeFileSync(outputFile, JSON.stringify(contentOutput, null, '\t'));
40088c88e8eSopenharmony_ci  } catch (err) {
40188c88e8eSopenharmony_ci    throw err;
40288c88e8eSopenharmony_ci  }
40388c88e8eSopenharmony_ci}
40488c88e8eSopenharmony_ci
40588c88e8eSopenharmony_cifunction mergeJson(inputValue, outputValue) {
40688c88e8eSopenharmony_ci  if (outputValue === null || outputValue === undefined) {
40788c88e8eSopenharmony_ci    return inputValue;
40888c88e8eSopenharmony_ci  }
40988c88e8eSopenharmony_ci  const typeInput = typeof inputValue;
41088c88e8eSopenharmony_ci  if (typeInput === typeof outputValue && typeInput === 'object') {
41188c88e8eSopenharmony_ci    Object.keys(inputValue).forEach(function (key) {
41288c88e8eSopenharmony_ci      const contentElementMerge = mergeJson(inputValue[key], outputValue[key]);
41388c88e8eSopenharmony_ci      outputValue[key] = contentElementMerge;
41488c88e8eSopenharmony_ci    })
41588c88e8eSopenharmony_ci  }
41688c88e8eSopenharmony_ci  return outputValue;
41788c88e8eSopenharmony_ci}
41888c88e8eSopenharmony_ci
41988c88e8eSopenharmony_ciexport function mkDir(path_) {
42088c88e8eSopenharmony_ci  const parent = path.join(path_, '..');
42188c88e8eSopenharmony_ci  if (!(fs.existsSync(parent) && !fs.statSync(parent).isFile())) {
42288c88e8eSopenharmony_ci    mkDir(parent);
42388c88e8eSopenharmony_ci  }
42488c88e8eSopenharmony_ci  fs.mkdirSync(path_);
42588c88e8eSopenharmony_ci}