UNPKG

@hadss/hmrouter-plugin

Version:

HMRouter Compiler Plugin

265 lines (264 loc) 12.7 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.CodeGenerationProcessor = void 0; const micromatch_1 = __importDefault(require("micromatch")); const ejs_1 = __importDefault(require("ejs")); const framework_1 = require("../../framework"); const PluginError_1 = require("../error/PluginError"); const constants_1 = require("../constants"); class CodeGenerationProcessor { constructor(context) { this.sdkVersion = 0; this.context = context; } execute() { this.sdkVersion = this.getCompileSdkVersion(); framework_1.Logger.debug(this.context.node.getNodeName(), `Start to code generation...`); this.context.generatedPaths = new Map(); this.context.getAnalyzeResults().forEach((result) => { if (result.annotation === constants_1.AnnotationConstants.ROUTER_ANNOTATION) { if (!result.sourceFilePath) { throw PluginError_1.PluginError.create(PluginError_1.ErrorCode.ERROR_PAGE_SOURCE_FILE, this.context.config.moduleName, result.sourceFilePath); } let pageSourceFile = this.context.config .getRelativeSourcePath(result.sourceFilePath) .replaceAll(constants_1.FilePathConstants.FILE_SEPARATOR, constants_1.FilePathConstants.DELIMITER); this.generatePageFile(result, pageSourceFile, this.matchedPath(pageSourceFile, this.context.config.customPageTemplate, this.context.config.getDefaultTplFilePath())); } }); } extractVersion(compatibleSdkVersion) { if (typeof compatibleSdkVersion === 'number') { return compatibleSdkVersion; } else { const match = compatibleSdkVersion.match(/\((\d+)\)/); if (match && match[1]) { return parseInt(match[1], 10); } const num = parseFloat(compatibleSdkVersion); if (!isNaN(num) && num > constants_1.FilePathConstants.DEFAULT_VALUE) { return num; } return constants_1.FilePathConstants.DEFAULT_VALUE; } } getCompileSdkVersion() { let json5FilePath = ''; let sdkVersion = constants_1.FilePathConstants.DEFAULT_VALUE; let arrData = ['DEVECO_SDK_HOME', 'HOS_SDK_HOME', 'OHOS_SDK_HOME']; for (let index = 0; index <= 4; index++) { if (index < 3 && process.env[arrData[index]]) { json5FilePath = framework_1.PluginFileUtil.pathResolve(process.env[arrData[index]], constants_1.FilePathConstants.SDK_HOME); } else if (index === 3) { json5FilePath = framework_1.PluginFileUtil.pathResolve(framework_1.PluginStore.getInstance().get('projectFilePath'), constants_1.FilePathConstants.BUILD_PROFILE); } else if (index === 4) { json5FilePath = framework_1.PluginFileUtil.pathResolve(framework_1.PluginStore.getInstance().get('projectFilePath'), constants_1.FilePathConstants.BUILD_PROFILE); } const sdkVer = this.getSdkVersion(json5FilePath, index); if (sdkVer > constants_1.FilePathConstants.DEFAULT_VALUE) { sdkVersion = sdkVer; break; } } return sdkVersion; } getSdkVersion(json5FilePath, index) { if (framework_1.PluginFileUtil.exist(json5FilePath)) { const data = framework_1.PluginFileUtil.readJson5(json5FilePath); if (index < 3) { return this.extractVersion(data.apiVersion); } else if (index === 3) { if (data.app.products[0].compileSdkVersion) { return this.extractVersion(data.app.products[0].compileSdkVersion); } } else if (index === 4) { if (data.app.products[0].compatibleSdkVersion) { return this.extractVersion(data.app.products[0].compatibleSdkVersion); } } } return constants_1.FilePathConstants.DEFAULT_VALUE; } generatePageFile(result, pageSourceFile, tempFilePath) { const templateModel = this.prepareTemplateModel(result, pageSourceFile); tempFilePath = this.determineTemplatePath(result, tempFilePath); const generatedFilePath = this.generateFile(templateModel, tempFilePath); framework_1.Logger.info(this.context.node.getNodeName(), `Builder ${templateModel.generatorViewName}.ets has been generated in ${generatedFilePath}`); const uniqueKey = `${result.name}#${result.pageUrl}`; this.context.generatedPaths.set(uniqueKey, generatedFilePath); } matchedPath(filePath, customPageTemplate, defaultTplFilePath) { for (const template of customPageTemplate) { if (micromatch_1.default.isMatch(filePath, template.srcPath)) { framework_1.Logger.debug(this.context.node.getNodeName(), `${filePath} detected matching template: ${template.templatePath}`); return framework_1.PluginFileUtil.pathResolve(this.context.config.configDir, template.templatePath); } } return defaultTplFilePath; } prepareTemplateModel(analyzeResult, pageSourceFile) { let importPath = this.context.config .getRelativeBuilderPath(pageSourceFile) .replaceAll(constants_1.FilePathConstants.FILE_SEPARATOR, constants_1.FilePathConstants.DELIMITER) .replaceAll(constants_1.FilePathConstants.ETS_SUFFIX, ''); let generatorViewName = constants_1.PrefixConstants.VIEW_NAME_PREFIX + analyzeResult.name + framework_1.StringUtil.stringToHashCode(analyzeResult.pageUrl); let templateData = this.context.getTemplateData(analyzeResult.name); return { sdkVersion: this.sdkVersion, pageUrl: analyzeResult.pageUrl, componentName: analyzeResult.name, dialog: !!analyzeResult.dialog, isDefaultExport: !!templateData?.isDefaultExport, importPath, generatorViewName, ...templateData, }; } determineTemplatePath(analyzeResult, defaultTemplatePath) { const libraryVersion = this.detectLibraryVersion(); framework_1.Logger.debug(this.context.node.getNodeName(), `Library version: ${libraryVersion}`); if (analyzeResult.useNavDst === true) { return framework_1.PluginFileUtil.pathResolve(__dirname, constants_1.FilePathConstants.PARENT_DELIMITER.repeat(3), constants_1.TemplateConstants.CUSTOM_BUILDER_TEMPLATE); } const templateType = this.determineTemplateType(libraryVersion); if (templateType !== 'latest' && libraryVersion) { framework_1.Logger.warn(this.context.node.getNodeName(), `[HMRouter Version Compatibility] Detected library version ${libraryVersion}, ` + `which is below the minimum recommended version ${constants_1.VersionConstants.HMROUTER_MIN_VERSION_FOR_SDK_API}. ` + `Automatically switched to compatible template (${templateType}). ` + `Please upgrade @hadss/hmrouter to ${constants_1.VersionConstants.HMROUTER_MIN_VERSION_FOR_SDK_API} or higher for full feature support.`); } switch (templateType) { case 'v1': return framework_1.PluginFileUtil.pathResolve(__dirname, constants_1.FilePathConstants.PARENT_DELIMITER.repeat(3) + constants_1.TemplateConstants.V1_TEMPLATE); case 'v1_1': return framework_1.PluginFileUtil.pathResolve(__dirname, constants_1.FilePathConstants.PARENT_DELIMITER.repeat(3) + constants_1.TemplateConstants.V1_1_TEMPLATE); case 'latest': default: return defaultTemplatePath; } } determineTemplateType(libraryVersion) { if (!libraryVersion) { return 'v1'; } const currentVersion = this.parseVersion(libraryVersion); const v1_1Version = this.parseVersion(constants_1.VersionConstants.HMROUTER_MIN_VERSION_FOR_NAV_HELPER); const v1_2Version = this.parseVersion(constants_1.VersionConstants.HMROUTER_MIN_VERSION_FOR_SDK_API); if (!currentVersion || !v1_1Version || !v1_2Version) { return 'v1'; } if (this.compareVersions(currentVersion, v1_2Version) >= 0) { return 'latest'; } if (this.compareVersions(currentVersion, v1_1Version) >= 0) { return 'v1_1'; } return 'v1'; } generateFile(templateModel, templatePath) { if (!framework_1.PluginFileUtil.exist(templatePath)) { throw PluginError_1.PluginError.create(PluginError_1.ErrorCode.TEMPLATE_NOT_FOUND, this.context.config.moduleName, templatePath); } const tpl = framework_1.PluginFileUtil.readFileSync(templatePath).toString(); const templateStr = ejs_1.default.render(tpl, templateModel); const generatorFilePath = this.context.config.getGeneratedFilePath(templateModel.generatorViewName); framework_1.PluginFileUtil.ensureFileSync(generatorFilePath); framework_1.PluginFileUtil.writeFileSync(generatorFilePath, templateStr); return this.context.config .getBuilderFilePath(templateModel.generatorViewName) .replaceAll(constants_1.FilePathConstants.FILE_SEPARATOR, constants_1.FilePathConstants.DELIMITER); } detectLibraryVersion() { let libraryVersion = ''; const possiblePaths = this.getLibraryPossiblePaths(); for (const packagePath of possiblePaths) { libraryVersion = this.detectLibraryVersion2(packagePath); if (libraryVersion) { break; } } return libraryVersion; } detectLibraryVersion2(lockFilePath) { try { if (!framework_1.PluginFileUtil.exist(lockFilePath)) { return ''; } const lockFileData = framework_1.PluginFileUtil.readJson5(lockFilePath); return this.extractHMRouterVersion(lockFileData.packages); } catch (error) { return ''; } } extractHMRouterVersion(packages) { if (!packages) { return ''; } const hmrouterPrefix = `${constants_1.VersionConstants.HMROUTER_ORGANIZATION}/${constants_1.VersionConstants.HMROUTER_LIB_NAME}@`; for (const key of Object.keys(packages)) { if (!key.startsWith(hmrouterPrefix)) { continue; } const packageInfo = packages[key]; if (packageInfo && packageInfo[constants_1.VersionConstants.HMROUTER_VERSION_KEY]) { return packageInfo[constants_1.VersionConstants.HMROUTER_VERSION_KEY]; } } return ''; } getLibraryPossiblePaths() { const paths = []; paths.push(framework_1.PluginFileUtil.pathResolve(this.context.config.modulePath, constants_1.FilePathConstants.OH_PACKAGE_LOCK_FILE_NAME)); const projectRoot = framework_1.PluginStore.getInstance().get('projectFilePath'); if (projectRoot && projectRoot !== this.context.config.modulePath) { paths.push(framework_1.PluginFileUtil.pathResolve(projectRoot, constants_1.FilePathConstants.OH_PACKAGE_LOCK_FILE_NAME)); } return paths; } parseVersion(version) { const match = version.match(/^(\d+)\.(\d+)\.(\d+)(-.*)?/); if (!match) { return null; } return { major: parseInt(match[1], 10), minor: parseInt(match[2], 10), patch: parseInt(match[3], 10), preRelease: match[4] || '', }; } compareVersions(v1, v2) { if (v1.major !== v2.major) { return v1.major < v2.major ? -1 : 1; } if (v1.minor !== v2.minor) { return v1.minor < v2.minor ? -1 : 1; } if (v1.patch !== v2.patch) { return v1.patch < v2.patch ? -1 : 1; } if (v1.preRelease && !v2.preRelease) { return -1; } if (!v1.preRelease && v2.preRelease) { return 1; } if (v1.preRelease < v2.preRelease) { return -1; } if (v1.preRelease > v2.preRelease) { return 1; } return 0; } } exports.CodeGenerationProcessor = CodeGenerationProcessor;