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 fs from 'fs'; 17import path from 'path'; 18import os from 'os'; 19import { createSourceFile, ScriptTarget } from 'typescript'; 20import { collectAllFileName, getAllClassDeclaration, dtsFileList, getOhosInterfacesDir } from './common/commonUtils'; 21import { getSourceFileAssembly } from './declaration-node/sourceFileElementsAssemply'; 22import { generateEntry } from './generate/generateEntry'; 23import { generateIndex } from './generate/generateIndex'; 24import { generateSourceFileElements } from './generate/generateMockJsFile'; 25import { generateSystemIndex } from './generate/generateSystemIndex'; 26 27/** 28 * get all api .d.ts file path 29 * @param dir 30 * @returns 31 */ 32function getAllDtsFile(dir: string): Array<string> { 33 const arr = fs.readdirSync(dir); 34 if (!dir.toString().includes('node_modules') && !dir.toString().includes(path.join('@internal', 'component'))) { 35 arr.forEach(value => { 36 const fullPath = path.join(dir, value); 37 const stats = fs.statSync(fullPath); 38 if (stats.isDirectory()) { 39 getAllDtsFile(fullPath); 40 } else { 41 dtsFileList.push(fullPath); 42 } 43 }); 44 } 45 return dtsFileList; 46} 47 48/** 49 * delete the old mock file befor generate new mock file 50 * @param outDir 51 */ 52function deleteOldMockJsFile(outDir: string): void { 53 const arr = fs.readdirSync(outDir); 54 arr.forEach(value => { 55 const currPath = path.join(outDir, value); 56 const stas = fs.statSync(currPath); 57 if (stas.isDirectory()) { 58 deleteOldMockJsFile(currPath); 59 } else { 60 fs.unlink(currPath, function(err) { 61 if (err) { 62 console.log(err); 63 } 64 }); 65 } 66 }); 67} 68 69/** 70 * mkdir 71 * @param dirname 72 * @returns 73 */ 74function mkdirsSync(dirname): boolean { 75 if (fs.existsSync(dirname)) { 76 return true; 77 } else { 78 if (mkdirsSync(path.dirname(dirname))) { 79 fs.mkdirSync(dirname); 80 return true; 81 } 82 } 83 return false; 84} 85 86function main(apiInputPath): void { 87 let interfaceRootDir = ''; 88 if (os.platform() === 'linux' || os.platform() === 'darwin') { 89 interfaceRootDir = __dirname.split('/out')[0]; 90 } else { 91 interfaceRootDir = __dirname.split('\\out')[0]; 92 } 93 const dtsDir = apiInputPath; 94 const outMockJsFileDir = path.join(__dirname, '../../runtime/main/extend/systemplugin'); 95 // deleteOldMockJsFile(outMockJsFileDir); 96 getAllDtsFile(dtsDir); 97 98 dtsFileList.forEach(value => { 99 collectAllFileName(value); 100 if (value.endsWith('.d.ts') || value.endsWith('.d.ets')) { 101 const code = fs.readFileSync(value); 102 const sourceFile = createSourceFile(value, code.toString(), ScriptTarget.Latest); 103 getAllClassDeclaration(sourceFile); 104 } 105 }); 106 107 let index = 0; 108 while (index < dtsFileList.length) { 109 const value = dtsFileList[index]; 110 index ++; 111 112 if (!value.endsWith('.d.ts') && !value.endsWith('.d.ets')) { 113 continue; 114 } 115 116 const code = fs.readFileSync(value); 117 const sourceFile = createSourceFile(value, code.toString(), ScriptTarget.Latest); 118 let fileName: string; 119 if (value.endsWith('.d.ts')) { 120 fileName = path.basename(value, '.d.ts'); 121 } else if (value.endsWith('.d.ets')) { 122 fileName = path.basename(value, '.d.ets'); 123 } else { 124 continue; 125 } 126 let outputFileName = ''; 127 if (fileName.includes('@')) { 128 outputFileName = fileName.split('@')[1].replace(/\./g, '_'); 129 } else { 130 outputFileName = fileName; 131 } 132 133 let tmpOutputMockJsFileDir = outMockJsFileDir; 134 if (!outputFileName.startsWith('system_')) { 135 tmpOutputMockJsFileDir = path.join(outMockJsFileDir, 'napi'); 136 } 137 138 if (value.startsWith(getOhosInterfacesDir()) && !apiInputPath.startsWith(getOhosInterfacesDir())) { 139 tmpOutputMockJsFileDir = path.join(tmpOutputMockJsFileDir, '@ohos'); 140 } 141 142 let dirName = ''; 143 dirName = path.join(tmpOutputMockJsFileDir, path.dirname(value).split(`${path.sep}api`)[1]); 144 if (!fs.existsSync(dirName)) { 145 mkdirsSync(dirName); 146 } 147 const sourceFileEntity = getSourceFileAssembly(sourceFile, fileName); 148 const filePath = path.join(dirName, outputFileName + '.js'); 149 fs.writeFileSync(filePath, ''); 150 fs.appendFileSync(path.join(filePath), generateSourceFileElements('', sourceFileEntity, sourceFile, outputFileName)); 151 } 152 153 if (!fs.existsSync(path.join(outMockJsFileDir, 'napi'))) { 154 mkdirsSync(path.join(outMockJsFileDir, 'napi')); 155 } 156 fs.writeFileSync(path.join(outMockJsFileDir, 'napi', 'index.js'), generateIndex()); 157 fs.writeFileSync(path.join(outMockJsFileDir, 'index.js'), generateSystemIndex()); 158 fs.writeFileSync(path.join(outMockJsFileDir, 'entry.js'), generateEntry()); 159} 160 161const paramIndex = 2; 162const apiInputPath = process.argv[paramIndex]; 163main(apiInputPath);