* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as fs from 'fs';
import * as path from 'path';
import { logger } from './compile_info';
import { fileInfoCache } from './file_info_cache';
const { projectConfig } = require('../main');
const red: string = '\u001b[31m';
const reset: string = '\u001b[39m';
const REG_OHM_URL: RegExp = /^@bundle:(\S+)\/(\S+)\/(ets|js)\/(\S+)$/;
export class OHMResolverPlugin {
private source: any;
private target: any;
constructor(source = 'resolve', target = 'resolve') {
this.source = source;
this.target = target;
}
apply(resolver) {
const target: any = resolver.ensureHook(this.target);
resolver.getHook(this.source).tapAsync('OHMResolverPlugin', (request, resolveContext, callback) => {
if (isOhmUrl(request.request)) {
const resolvedSourceFile: string = resolveSourceFile(request.request);
const obj = Object.assign({}, request, {
request: resolvedSourceFile
});
return resolver.doResolve(target, obj, null, resolveContext, callback);
}
callback();
return undefined;
});
}
}
export function isOhmUrl(moduleRequest: string): boolean {
return !!/^@(\S+):/.test(moduleRequest);
}
function addExtension(file: string, srcPath: string): string {
let extension: string = '.d.ts';
if (fileInfoCache.isFile(file + '.ets')) {
extension = '.ets';
}
if (fileInfoCache.isFile(file + '.ts')) {
if (extension !== '.d.ts') {
logger.error(red, `ArkTS:ERROR Failed to compile with files with same name ${srcPath} in the same directory`, reset);
}
extension = '.ts';
}
if (fileInfoCache.isFile(file + '.js')) {
if (extension !== '.d.ts') {
logger.error(red, `ArkTS:ERROR Failed to compile with files with same name ${srcPath} in the same directory`, reset);
}
extension = '.js';
}
return file + extension;
}
export function resolveSourceFile(ohmUrl: string): string {
if (!projectConfig.aceBuildJson) {
logger.error(red, `ArkTS:ERROR Failed to resolve OhmUrl because of aceBuildJson not existing `, reset);
return ohmUrl;
}
const result: RegExpMatchArray = ohmUrl.match(REG_OHM_URL);
const moduleName: string = result[2];
const srcKind: string = result[3];
const modulePath: string = projectConfig.modulePathMap[moduleName];
const srcRoot: string = projectConfig.isOhosTest ? 'src/ohosTest' : 'src/main';
let file: string = path.join(modulePath, srcRoot, srcKind, result[4]);
file = addExtension(file, result[4]);
if (!fileInfoCache.isFile(file)) {
if (projectConfig.isOhosTest) {
file = path.join(modulePath, 'src/main', srcKind, result[4]);
file = addExtension(file, result[4]);
if (fileInfoCache.isFile(file)) {
return file;
}
}
logger.error(red, `ArkTS:ERROR Failed to resolve existed file by this ohm url ${ohmUrl} `, reset);
}
return file;
}