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 { KeyValue, Members, MockBuffer } from '../types'; 19import { D_ETS, D_TS, KeyValueTypes, NAPI_DIR_PATH } from './constants'; 20import { getProjectDir } from './systemUtils'; 21 22/** 23 * 递归创建文件夹 24 * @param dirname 需要创建文件夹的路径 25 * @returns 是否创建成功 26 */ 27export function mkdirsSync(dirname: string): boolean { 28 if (fs.existsSync(dirname)) { 29 return true; 30 } else { 31 if (mkdirsSync(path.dirname(dirname))) { 32 fs.mkdirSync(dirname); 33 return true; 34 } 35 } 36 return false; 37} 38 39/** 40 * 生成KeyValue节点 41 * @param key 节点名称 42 * @param type 节点类型 43 * @param parent 该节点的父节点 44 * @param optionMembers 其他初始化参数 45 * @returns KeyValue节点 46 */ 47export function generateKeyValue(key: string, type: KeyValueTypes, parent?: KeyValue, optionMembers?: { 48 members: Members, 49 typeParameters: Members, 50 methodParams: Members, 51 constraint: Members, 52 sameName: KeyValue[], 53 dependOnGlobals: Set<KeyValue> 54}): KeyValue { 55 const keyValue = {key, type, parent, sameDeclares: []} as KeyValue; 56 if (optionMembers) { 57 keyValue.members = optionMembers.members ?? {}; 58 keyValue.typeParameters = optionMembers.typeParameters ?? {}; 59 keyValue.methodParams = optionMembers.methodParams ?? {}; 60 keyValue.constraint = optionMembers.constraint ?? {}; 61 keyValue.sameName = optionMembers.sameName ?? []; 62 keyValue.dependOnGlobals = optionMembers.dependOnGlobals ?? new Set<KeyValue>(); 63 } else { 64 keyValue.members = {}; 65 keyValue.typeParameters = {}; 66 keyValue.methodParams = {}; 67 keyValue.constraint = {}; 68 keyValue.sameName = []; 69 keyValue.dependOnGlobals = new Set<KeyValue>(); 70 } 71 return keyValue as KeyValue; 72} 73 74/** 75 * 获取开源接口的api路径 76 */ 77export function getOhosInterfacesDir(): string { 78 return path.join(getProjectDir(), 'interface', 'sdk-js', 'api'); 79} 80 81/** 82 * 获取导入路径的绝对路径 83 * @param mockBuffer 文件mock缓存信息 84 * @param specifier 导入路径 85 * @returns 导入文件的绝对路径 86 */ 87export function getAbsolutePath(mockBuffer: MockBuffer, specifier: string): string { 88 let absolutePath: string; 89 const importPath = specifier.replace(/['"]/g, ''); 90 if (importPath.startsWith('./') || importPath.startsWith('../')) { 91 absolutePath = path.resolve(path.dirname(mockBuffer.mockedFilePath), importPath) + '.js'; 92 } else if (importPath.startsWith('@ohos.') || importPath.startsWith('@system.')) { 93 absolutePath = path.join(NAPI_DIR_PATH, 'api', importPath) + '.js'; 94 } else if (importPath.startsWith('@kit.')) { 95 absolutePath = path.join(NAPI_DIR_PATH, 'kits', importPath) + '.js'; 96 } else if (importPath.startsWith('@arkts.')) { 97 absolutePath = path.join(NAPI_DIR_PATH, 'arkts', importPath) + '.js'; 98 } else { 99 absolutePath = path.resolve(path.dirname(mockBuffer.mockedFilePath), importPath) + '.js'; 100 } 101 return absolutePath; 102} 103 104/** 105 * 处理迭代器函数 106 * @param typeParams 迭代器返回值的类型参数 107 */ 108export function handleIterableIterator(typeParams: string): string { 109 return `function* () { 110 const yieldObj = ${typeParams}; 111 yield yieldObj; 112 yield yieldObj; 113 yield yieldObj; 114 }`; 115} 116 117/** 118 * 关联类型参数 119 * @param keyValue KV节点 120 * @param typeParameters 121 */ 122export function associateTypeParameters(keyValue: KeyValue, typeParameters: Members): void { 123 if (!keyValue.property) { 124 keyValue.typeParameters = typeParameters; 125 return; 126 } 127 associateTypeParameters(keyValue.property, typeParameters); 128} 129 130/** 131 * 判断是否是类型申明文件 132 * @param fileName 文件名 133 */ 134export function isDeclarationFile(fileName: string): boolean { 135 return fileName.endsWith(D_TS) || fileName.endsWith(D_ETS); 136} 137 138/** 139 * 判断文件是否需要被mock 140 * @param filePath 文件路径 141 */ 142export function isNeedMocked(filePath: string): boolean { 143 if (path.basename(filePath).startsWith('@ohos.')) { 144 return true; 145 } 146 if (path.basename(filePath).startsWith('@arkts.')) { 147 return true; 148 } 149 return path.basename(filePath).startsWith('@kit.'); 150} 151