107ac75b1Sopenharmony_ci/*
207ac75b1Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
307ac75b1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
407ac75b1Sopenharmony_ci * you may not use this file except in compliance with the License.
507ac75b1Sopenharmony_ci * You may obtain a copy of the License at
607ac75b1Sopenharmony_ci *
707ac75b1Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
807ac75b1Sopenharmony_ci *
907ac75b1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1007ac75b1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1107ac75b1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1207ac75b1Sopenharmony_ci * See the License for the specific language governing permissions and
1307ac75b1Sopenharmony_ci * limitations under the License.
1407ac75b1Sopenharmony_ci */
1507ac75b1Sopenharmony_ci
1607ac75b1Sopenharmony_ciimport * as fs from 'fs';
1707ac75b1Sopenharmony_ciimport * as path from 'path';
1807ac75b1Sopenharmony_ciimport { logger } from './compile_info';
1907ac75b1Sopenharmony_ciconst { projectConfig } = require('../main');
2007ac75b1Sopenharmony_ci
2107ac75b1Sopenharmony_ciconst red: string = '\u001b[31m';
2207ac75b1Sopenharmony_ciconst reset: string = '\u001b[39m';
2307ac75b1Sopenharmony_ci
2407ac75b1Sopenharmony_ciconst REG_OHM_URL: RegExp = /^@bundle:(\S+)\/(\S+)\/(ets|js)\/(\S+)$/;
2507ac75b1Sopenharmony_ci
2607ac75b1Sopenharmony_ciexport class OHMResolverPlugin {
2707ac75b1Sopenharmony_ci  private source: any;
2807ac75b1Sopenharmony_ci  private target: any;
2907ac75b1Sopenharmony_ci
3007ac75b1Sopenharmony_ci  constructor(source = 'resolve', target = 'resolve') {
3107ac75b1Sopenharmony_ci    this.source = source;
3207ac75b1Sopenharmony_ci    this.target = target;
3307ac75b1Sopenharmony_ci  }
3407ac75b1Sopenharmony_ci
3507ac75b1Sopenharmony_ci  apply(resolver) {
3607ac75b1Sopenharmony_ci    const target: any = resolver.ensureHook(this.target);
3707ac75b1Sopenharmony_ci    resolver.getHook(this.source).tapAsync('OHMResolverPlugin', (request, resolveContext, callback) => {
3807ac75b1Sopenharmony_ci      if (isOhmUrl(request.request)) {
3907ac75b1Sopenharmony_ci        const resolvedSourceFile: string = resolveSourceFile(request.request);
4007ac75b1Sopenharmony_ci        const obj = Object.assign({}, request, {
4107ac75b1Sopenharmony_ci          request: resolvedSourceFile
4207ac75b1Sopenharmony_ci        });
4307ac75b1Sopenharmony_ci        return resolver.doResolve(target, obj, null, resolveContext, callback);
4407ac75b1Sopenharmony_ci      }
4507ac75b1Sopenharmony_ci      callback();
4607ac75b1Sopenharmony_ci      return undefined;
4707ac75b1Sopenharmony_ci    });
4807ac75b1Sopenharmony_ci  }
4907ac75b1Sopenharmony_ci}
5007ac75b1Sopenharmony_ci
5107ac75b1Sopenharmony_ciexport function isOhmUrl(moduleRequest: string): boolean {
5207ac75b1Sopenharmony_ci  return !!/^@(\S+):/.test(moduleRequest);
5307ac75b1Sopenharmony_ci}
5407ac75b1Sopenharmony_ci
5507ac75b1Sopenharmony_cifunction addExtension(file: string, srcPath: string): string {
5607ac75b1Sopenharmony_ci  let extension: string = '.d.ts';
5707ac75b1Sopenharmony_ci  if (fs.existsSync(file + '.ets') && fs.statSync(file + '.ets').isFile()) {
5807ac75b1Sopenharmony_ci    extension = '.ets';
5907ac75b1Sopenharmony_ci  }
6007ac75b1Sopenharmony_ci  if (fs.existsSync(file + '.ts') && fs.statSync(file + '.ts').isFile()) {
6107ac75b1Sopenharmony_ci    if (extension !== '.d.ts') {
6207ac75b1Sopenharmony_ci      logger.error(red, `ArkTS:ERROR Failed to compile with files with same name ${srcPath} in the same directory`, reset);
6307ac75b1Sopenharmony_ci    }
6407ac75b1Sopenharmony_ci    extension = '.ts';
6507ac75b1Sopenharmony_ci  }
6607ac75b1Sopenharmony_ci  if (fs.existsSync(file + '.js') && fs.statSync(file + '.js').isFile()) {
6707ac75b1Sopenharmony_ci    if (extension !== '.d.ts') {
6807ac75b1Sopenharmony_ci      logger.error(red, `ArkTS:ERROR Failed to compile with files with same name ${srcPath} in the same directory`, reset);
6907ac75b1Sopenharmony_ci    }
7007ac75b1Sopenharmony_ci    extension = '.js';
7107ac75b1Sopenharmony_ci  }
7207ac75b1Sopenharmony_ci  return file + extension;
7307ac75b1Sopenharmony_ci}
7407ac75b1Sopenharmony_ci
7507ac75b1Sopenharmony_ciexport function resolveSourceFile(ohmUrl: string): string {
7607ac75b1Sopenharmony_ci  if (!projectConfig.aceBuildJson) {
7707ac75b1Sopenharmony_ci    logger.error(red, `ArkTS:ERROR Failed to resolve OhmUrl because of aceBuildJson not existing `, reset);
7807ac75b1Sopenharmony_ci    return ohmUrl;
7907ac75b1Sopenharmony_ci  }
8007ac75b1Sopenharmony_ci
8107ac75b1Sopenharmony_ci  const result: RegExpMatchArray = ohmUrl.match(REG_OHM_URL);
8207ac75b1Sopenharmony_ci  const moduleName: string = result[2];
8307ac75b1Sopenharmony_ci  const srcKind: string = result[3];
8407ac75b1Sopenharmony_ci
8507ac75b1Sopenharmony_ci  const modulePath: string = projectConfig.modulePathMap[moduleName];
8607ac75b1Sopenharmony_ci  const srcRoot: string = projectConfig.isOhosTest ? 'src/ohosTest' : 'src/main';
8707ac75b1Sopenharmony_ci  let file: string = path.join(modulePath, srcRoot, srcKind, result[4]);
8807ac75b1Sopenharmony_ci  file = addExtension(file, result[4]);
8907ac75b1Sopenharmony_ci
9007ac75b1Sopenharmony_ci  if (!fs.existsSync(file) || !fs.statSync(file).isFile()) {
9107ac75b1Sopenharmony_ci    if (projectConfig.isOhosTest) {
9207ac75b1Sopenharmony_ci      file = path.join(modulePath, 'src/main', srcKind, result[4]);
9307ac75b1Sopenharmony_ci      file = addExtension(file, result[4]);
9407ac75b1Sopenharmony_ci
9507ac75b1Sopenharmony_ci      if (fs.existsSync(file) && fs.statSync(file).isFile()) {
9607ac75b1Sopenharmony_ci        return file;
9707ac75b1Sopenharmony_ci      }
9807ac75b1Sopenharmony_ci    }
9907ac75b1Sopenharmony_ci
10007ac75b1Sopenharmony_ci    logger.error(red, `ArkTS:ERROR Failed to resolve existed file by this ohm url ${ohmUrl} `, reset);
10107ac75b1Sopenharmony_ci  }
10207ac75b1Sopenharmony_ci
10307ac75b1Sopenharmony_ci  return file;
10407ac75b1Sopenharmony_ci}
105