1/* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import path from 'path'; 17import fs from 'fs'; 18import {FileUtils} from '../utils/FileUtils'; 19import {ApiExtractor} from './ApiExtractor'; 20import {ListUtil} from '../utils/ListUtil'; 21import type {IOptions} from '../configs/IOptions'; 22import es6Info from '../configs/preset/es6_reserved_properties.json'; 23 24 25export const scanProjectConfig: {mKeepStringProperty?: boolean} = {}; 26 27/** 28 * if rename property is not open, api read and extract can be skipped 29 * 30 * init plugin, read api info of openHarmony sdk and generate file of reserved name, property and string. 31 * @param sdkDir absolute path like D:\\HuaweiApp\\ohsdk 32 * @param outputDir 33 */ 34export function initPlugin(sdkDir: string, outputDir: string): void { 35 // create sdk api file if not exist 36 const ohSdkPath: string = path.resolve(sdkDir); 37 if (!ohSdkPath) { 38 console.error('SDK path is not found.'); 39 } 40 41 const apiVersions: string[] = ['']; 42 43 apiVersions.forEach((versionString) => { 44 ApiExtractor.parseOhSdk(ohSdkPath, versionString, true, outputDir); 45 }); 46} 47 48/** 49 * need read api info or not 50 * @param customProfiles 51 */ 52export function needReadApiInfo(customProfiles: IOptions): boolean { 53 return customProfiles.mNameObfuscation && 54 customProfiles.mNameObfuscation.mEnable && 55 customProfiles.mNameObfuscation.mRenameProperties; 56} 57 58/** 59 * read project reserved properties 60 * @param projectPaths can be dir or file 61 * @param customProfiles 62 */ 63export function readProjectProperties(projectPaths: string[], customProfiles: IOptions, isOHProject?: boolean): string[] { 64 if (!needReadApiInfo(customProfiles) && !isOHProject) { 65 return []; 66 } 67 68 scanProjectConfig.mKeepStringProperty = customProfiles.mNameObfuscation?.mKeepStringProperty; 69 70 for (const projectPath of projectPaths) { 71 if (!fs.existsSync(projectPath)) { 72 console.error(`File ${FileUtils.getFileName(projectPath)} is not found.`); 73 return []; 74 } 75 76 const sourcPath = isOHProject ? path.join(projectPath, 'src', 'main') : projectPath; 77 const projProperties: string[] = ApiExtractor.parseCommonProject(sourcPath); 78 const sdkProperties: string[] = readThirdPartyLibProperties(projectPath); 79 80 // read project code export names 81 customProfiles.mNameObfuscation.mReservedProperties = ListUtil.uniqueMergeList(projProperties, 82 customProfiles.mNameObfuscation.mReservedProperties); 83 84 // read project lib export names 85 if (sdkProperties) { 86 customProfiles.mNameObfuscation.mReservedProperties = ListUtil.uniqueMergeList(sdkProperties, 87 customProfiles.mNameObfuscation.mReservedProperties); 88 } 89 } 90 return customProfiles.mNameObfuscation.mReservedProperties; 91} 92 93function readThirdPartyLibProperties(projectPath: string): string[] { 94 let reservedProperties: string[] = []; 95 96 if (!fs.lstatSync(projectPath).isDirectory()) { 97 return undefined; 98 } 99 100 // find third party lib and extract reserved names 101 const fileNames: string[] = fs.readdirSync(projectPath); 102 const hasNodeModules: boolean = fileNames.includes('node_modules'); 103 const hasOHModules: boolean = fileNames.includes('oh_modules'); 104 if (!hasNodeModules && !hasOHModules) { 105 return undefined; 106 } 107 if (hasNodeModules && hasOHModules) { 108 throw new Error(`There are both node_modules and oh_modules folders in ${projectPath}`); 109 } 110 111 let filePath: string = ''; 112 if (hasNodeModules) { 113 filePath = path.join(projectPath, 'node_modules'); 114 } else { 115 filePath = path.join(projectPath, 'oh_modules'); 116 } 117 118 const properties: string[] = ApiExtractor.parseThirdPartyLibs(filePath); 119 reservedProperties = [...reservedProperties, ...properties]; 120 const propertySet: Set<string> = new Set<string>(reservedProperties); 121 122 return Array.from(propertySet); 123} 124