From 09aa228ce59ed385c04326ce1b73b44596544a38 Mon Sep 17 00:00:00 2001 From: enxue Date: Fri, 8 Aug 2025 14:57:41 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9EapiCheckPlugin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: enxue --- BUILD.gn | 29 + .../custom-comment-parser/index.ts | 16 + .../src/custom_comment_parser.ts | 113 + .../api-check-wrapper/index.ts | 18 + .../src/api_check_wrapper.ts | 232 ++ .../utils/api_check_wrapper_enums.ts | 19 + .../utils/api_check_wrapper_typedef.ts | 110 + .../utils/ts_wrapper_node_util.ts | 1614 ++++++++++++ .../api-check-plugin-static/babel.config.js | 41 + .../custom-import-plugin.js | 51 + .../api-check-plugin-static/index.ts | 89 + .../api-check-plugin-static/package-lock.json | 2347 +++++++++++++++++ .../api-check-plugin-static/package.json | 22 + .../src/api_check_config.ts | 173 ++ .../utils/api_check_plugin_define.ts | 61 + .../utils/api_check_plugin_enums.ts | 23 + .../utils/api_check_plugin_typedef.ts | 132 + .../utils/api_check_plugin_utils.ts | 992 +++++++ build-tools/package.json | 2 +- build_api_check_plugin.py | 74 + 20 files changed, 6157 insertions(+), 1 deletion(-) create mode 100644 build-tools/compile-plugins/api-check-plugin-static/api-check-wrapper/custom-plugins/custom-comment-parser/index.ts create mode 100644 build-tools/compile-plugins/api-check-plugin-static/api-check-wrapper/custom-plugins/custom-comment-parser/src/custom_comment_parser.ts create mode 100644 build-tools/compile-plugins/api-check-plugin-static/api-check-wrapper/index.ts create mode 100644 build-tools/compile-plugins/api-check-plugin-static/api-check-wrapper/src/api_check_wrapper.ts create mode 100644 build-tools/compile-plugins/api-check-plugin-static/api-check-wrapper/utils/api_check_wrapper_enums.ts create mode 100644 build-tools/compile-plugins/api-check-plugin-static/api-check-wrapper/utils/api_check_wrapper_typedef.ts create mode 100644 build-tools/compile-plugins/api-check-plugin-static/api-check-wrapper/utils/ts_wrapper_node_util.ts create mode 100644 build-tools/compile-plugins/api-check-plugin-static/babel.config.js create mode 100644 build-tools/compile-plugins/api-check-plugin-static/custom-import-plugin.js create mode 100644 build-tools/compile-plugins/api-check-plugin-static/index.ts create mode 100644 build-tools/compile-plugins/api-check-plugin-static/package-lock.json create mode 100644 build-tools/compile-plugins/api-check-plugin-static/package.json create mode 100644 build-tools/compile-plugins/api-check-plugin-static/src/api_check_config.ts create mode 100644 build-tools/compile-plugins/api-check-plugin-static/utils/api_check_plugin_define.ts create mode 100644 build-tools/compile-plugins/api-check-plugin-static/utils/api_check_plugin_enums.ts create mode 100644 build-tools/compile-plugins/api-check-plugin-static/utils/api_check_plugin_typedef.ts create mode 100644 build-tools/compile-plugins/api-check-plugin-static/utils/api_check_plugin_utils.ts create mode 100755 build_api_check_plugin.py diff --git a/BUILD.gn b/BUILD.gn index a9d15c1291..e17e5b56c8 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -604,4 +604,33 @@ action("ohos_ets_process_interop") { ] outputs = ["${interface_sdk_path}/arkui_dummy_interop"] +} + +action("gen_api_check_plugin") { + deps = [ + "//developtools/ace_ets2bundle/arkui-plugins:ui_plugin" + ] + npm_path = "//prebuilts/build-tools/common/nodejs/current/bin/npm" + script = "build_api_check_plugin.py" + args = [ + "--source_path", + rebase_path(get_path_info("./build-tools/compile-plugins/api-check-plugin-static", "abspath")), + "--output_path", + rebase_path("$target_gen_dir"), + "--npm", + rebase_path(npm_path), + ] + outputs = [ "$target_gen_dir" ] +} + +ohos_copy("api_check_plugin") { + deps = [ + ":gen_api_check_plugin" + ] + sources = [ + rebase_path("$target_gen_dir") + ] + outputs = [ target_out_dir + "/$target_name" ] + module_source_dir = target_out_dir + "/$target_name" + module_install_name = "" } \ No newline at end of file diff --git a/build-tools/compile-plugins/api-check-plugin-static/api-check-wrapper/custom-plugins/custom-comment-parser/index.ts b/build-tools/compile-plugins/api-check-plugin-static/api-check-wrapper/custom-plugins/custom-comment-parser/index.ts new file mode 100644 index 0000000000..9c2f286b54 --- /dev/null +++ b/build-tools/compile-plugins/api-check-plugin-static/api-check-wrapper/custom-plugins/custom-comment-parser/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 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. + */ + +export { parseJSDoc } from './src/custom_comment_parser'; \ No newline at end of file diff --git a/build-tools/compile-plugins/api-check-plugin-static/api-check-wrapper/custom-plugins/custom-comment-parser/src/custom_comment_parser.ts b/build-tools/compile-plugins/api-check-plugin-static/api-check-wrapper/custom-plugins/custom-comment-parser/src/custom_comment_parser.ts new file mode 100644 index 0000000000..99f3932628 --- /dev/null +++ b/build-tools/compile-plugins/api-check-plugin-static/api-check-wrapper/custom-plugins/custom-comment-parser/src/custom_comment_parser.ts @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2025 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 { JSDoc, JSDocTag } from "../../../utils/api_check_wrapper_typedef"; + +/** + * 解析JSDoc字符串 + * + * @param { string } jsDocContent JSDoc字符串 + * @returns { JSDoc[] } JSDoc数组 + */ +export function parseJSDoc(jsDocContent: string): JSDoc[] { + const jsdocReg: RegExp = /(\/\*\*\s)(.|\n)*?(\s\*\/)/g; + const jsDocs: JSDoc[] = []; + const matches: RegExpStringIterator = jsDocContent.matchAll(jsdocReg); + for (const match of matches) { + if (match && match[0]) { + const jsDocContent: string = match[0]; + const description: string = collectDescription(jsDocContent); + const jsDocTags: JSDocTag[] = collectJSDocTags(jsDocContent); + jsDocs.push({ + description: description, + tags: jsDocTags + }); + } + } + return jsDocs; +} + +/** + * 匹配JSDoc整体内容 + * + * @param { string } jsDocContent + * @returns { string } + */ +function collectDescription(jsDocContent: string): string { + const jsDocDescriptionReg: RegExp = /(?<=\/\*\*\s)(.|\n)*?(?=(\s|\*)(\@|\s\*\/))/g; + let description: string = ''; + const descriptionMatche: RegExpMatchArray | null = jsDocContent.match(jsDocDescriptionReg); + if (descriptionMatche && descriptionMatche[0]) { + description = descriptionMatche[0].replace(/ *\* */g, '').replace(/\n|\r\n/g, ' '); + } + return description; +} + +/** + * 匹配"@"符号后内容 + * + * @param { string } jsDocContent + * @returns { JSDocTag[] } + */ +function collectJSDocTags(jsDocContent: string): JSDocTag[] { + const jsdocTagReg: RegExp = /(?<=(\s|\*)\@)(.|\n)*?(?=(\@|\s\*\/))/g; + const jsDocTags: JSDocTag[] = []; + const matches: RegExpStringIterator = jsDocContent.matchAll(jsdocTagReg); + for (const match of matches) { + if (match && match[0]) { + const jsDocTagContent: string = match[0].replace(/ *\* */g, '').replace(/\n|\r\n/g, ' '); + const jsDocTag: JSDocTag | undefined = collectJSDocTag(jsDocTagContent); + if (jsDocTag) { + jsDocTags.push(jsDocTag); + } + } + } + return jsDocTags; +} + +/** + * 将解析后的JSDoc内容组装成JSDocTag对象 + * + * @param { string } jsDocTagContent + * @returns { JSDocTag | undefined } + */ +function collectJSDocTag(jsDocTagContent: string): JSDocTag | undefined { + const jsDocTagTypeReg: RegExp = /(?<=\{).*?(?=\})/; + let content: string = jsDocTagContent; + const tagMatch: RegExpMatchArray | null = content.match(/\S+/); + const jsDocTag: JSDocTag = { + tag: '', + name: '', + description: '', + comment: '' + } + if (tagMatch && tagMatch[0]) { + jsDocTag.tag = tagMatch[0]; + content = content.replace(tagMatch[0], '').trim(); + if (/\S+/g.test(content)) { + jsDocTag.comment = content; + const tagNameMatch: RegExpMatchArray | null = content.match(/\S+/); + if (tagNameMatch && tagNameMatch[0]) { + jsDocTag.name = tagNameMatch[0]; + content = content.replace(tagNameMatch[0], '').trim(); + if (/\S+/g.test(content)) { + jsDocTag.description = content; + } + } + } + return jsDocTag; + } + return undefined; +} \ No newline at end of file diff --git a/build-tools/compile-plugins/api-check-plugin-static/api-check-wrapper/index.ts b/build-tools/compile-plugins/api-check-plugin-static/api-check-wrapper/index.ts new file mode 100644 index 0000000000..2b9456ff52 --- /dev/null +++ b/build-tools/compile-plugins/api-check-plugin-static/api-check-wrapper/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2025 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. + */ + +export * from './utils/api_check_wrapper_typedef'; +export * from './utils/api_check_wrapper_enums'; +export * from './custom-plugins/custom-comment-parser'; \ No newline at end of file diff --git a/build-tools/compile-plugins/api-check-plugin-static/api-check-wrapper/src/api_check_wrapper.ts b/build-tools/compile-plugins/api-check-plugin-static/api-check-wrapper/src/api_check_wrapper.ts new file mode 100644 index 0000000000..4de6cd2d78 --- /dev/null +++ b/build-tools/compile-plugins/api-check-plugin-static/api-check-wrapper/src/api_check_wrapper.ts @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2022-2025 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 arkts from '@koalaui/libarkts'; +import { traverseProgram, getJSDocInformation } from '../utils/ts_wrapper_node_util'; +import { + ApiCheckWrapperServiceHost, + JsDocNodeCheckConfig, + FileCheckModuleInfo, + JSDoc, + JSDocTag, + JsDocNodeCheckConfigItem, + CurrentAddress +} from '../utils/api_check_wrapper_typedef'; +import { SINCE_TAG_NAME } from "../../utils/api_check_plugin_define"; +import { parseJSDoc } from '../custom-plugins/custom-comment-parser'; +export let curApiCheckWrapper: ApiCheckWrapper; +export let curFileCheckModuleInfo: FileCheckModuleInfo; + +/** + * 导出arkts命名空间 + */ +export const WrapperApi = { + ...arkts +} + +let checkedNode = new Map(); + +export class ApiCheckWrapper { + constructor(apiCheckHost: ApiCheckWrapperServiceHost) { + this.apiCheckHost = apiCheckHost; + } + setFileName(fileName: string) { + this.fileName = fileName; + } + + fileName: string // ets源文件位置 + + sourcefile: string // 声明节点位置 + + apiCheckHost: ApiCheckWrapperServiceHost +} + +/** + * 获取AST节点 + * + * @param { ApiCheckWrapperServiceHost }apiCheckHost + * @param { number | undefined } peer + */ +export function checkApiExpression(apiCheckHost: ApiCheckWrapperServiceHost, peer: number | undefined) { + checkedNode = new Map(); + curApiCheckWrapper = new ApiCheckWrapper(apiCheckHost); + curApiCheckWrapper.fileName = arkts.arktsGlobal.filePath; + curFileCheckModuleInfo = {} as FileCheckModuleInfo; + curFileCheckModuleInfo.currentFileName = arkts.arktsGlobal.filePath; + + const contextPtr = arkts.arktsGlobal.compilerContext?.peer ?? peer; + // 获取当前ets文件路径,设置参数 + if (!!contextPtr) { + let program = arkts.getOrUpdateGlobalContext(contextPtr).program; + let script = program.astNode; + // 获取根节点,开始遍历 + traverseProgram(script); + } +} + +/** + * 处理identifier + * + * @param { arkts.AstNode } node + */ +export function checkIdentifier(node: arkts.AstNode) { + // 获取校验节点的声明节点 + const decl = arkts.getDecl(node); + + if (decl === undefined || decl === null) { + return; + } + // 获取声明节点系统路径 + let sysPath = getSysPath(decl); + curApiCheckWrapper.sourcefile = sysPath; + + if (sysPath === undefined || sysPath === null) { + return + } + let checkPram: JsDocNodeCheckConfig = curApiCheckWrapper.apiCheckHost.getJsDocNodeCheckedConfig( + curFileCheckModuleInfo.currentFileName, sysPath); + if (!checkPram.nodeNeedCheck) { + return; + } + // 获取校验节点的行列信息 + const address = getCurrentAddressByNode(node); + if (confirmNodeChecked(node.name, address.line, address.column)) { + return; + } + //进入检查jsdoc流程 + expressionCheckByJsDoc(decl, node, address, checkPram.checkConfig); +} + +/** + * 获取校验节点的行列信息 + * + * @param { string } nodeName + * @param { number } line + * @param { number } col + */ +function confirmNodeChecked(nodeName: string, line: number, col: number) { + let nodeKey = nodeName + "_" + line + "_" + col; + if (checkedNode.has(nodeKey) && checkedNode.get(nodeKey) !== undefined) { + return true; + } else { + checkedNode.set(nodeKey, nodeName); + } +} + +/** + * 获取Api文件路径 + * + * @param { arkts.AstNode } decl 声明节点 + * @returns { string } Api文件路径 + */ +function getSysPath(decl: arkts.AstNode): string { + // 获取节点的声明节点, + let program = arkts.getProgramFromAstNode(decl); + return program.sourceFilePath; +} + +/** + * 通过声明节点获取注释 + * + * @param { arkts.AstNde } decl 声明节点 + * @returns { string } 注释信息 + */ +export function getPeerJsDocs(decl: arkts.AstNde): string { + return getJSDocInformation(decl); +} + +/** + * 遍历jsdoc信息,实现打印报错 + * + * @param { arkts.AstNode } declaration 声明节点 + * @param { arkts.AstNode } identifier AST节点 + * @param { CurrentAddress } address 当前文件地址 + * @param { JsDocNodeCheckConfigItem[] } checkConfig 校验配置 + */ +function expressionCheckByJsDoc( + declaration: arkts.AstNode, identifier: arkts.AstNode, + address: CurrentAddress, checkConfig: JsDocNodeCheckConfigItem[]): void { + const jsDocsString = getPeerJsDocs(declaration); + const jsDocs: JSDoc[] = parseJSDoc(jsDocsString); + const jsDocTags = getCurrentJSDoc(jsDocs); + for (let i = 0; i < checkConfig.length; i++) { + const config = checkConfig[i]; + let tagNameExisted = false; + jsDocTags.forEach((item) => { + tagNameExisted = false; + if (config.tagName.includes(item.tag)) { + if (config.checkValidCallback) { + tagNameExisted = config.checkValidCallback(jsDocs, config); + } else { + tagNameExisted = true; + } + } + if (tagNameExisted && !config.tagNameShouldExisted) { + curApiCheckWrapper.apiCheckHost.pushLogInfo( + identifier.name, curApiCheckWrapper.fileName, + address, config.type, config.message); + } + }) + if (config.tagNameShouldExisted && !tagNameExisted) { + curApiCheckWrapper.apiCheckHost.pushLogInfo( + identifier.name, curApiCheckWrapper.fileName, + address, config.type, config.message); + } + } +} + +/** + * 获取节点行列信息 + * + * @param { arkts.AstNode } node 需要获取行列信息的节点 + * @returns { CurrentAddress } 节点行列信息 + */ +function getCurrentAddressByNode(node: arkts.AstNode): CurrentAddress { + let address = {} as CurrentAddress; + let startPosition = node.startPosition; + address.column = startPosition.col(); + address.line = startPosition.line() + 1; + return address; +} + +/** + * 获取最大的版本号 + * + * @param { JSDoc[] } jsDocs + * @returns { JSDocTag[] } + */ +function getCurrentJSDoc(jsDocs: JSDoc[]): JSDocTag[] { + let jsDocTags: JSDocTag[] = []; + let maxVersion: number = 0; + if (jsDocs && jsDocs.length > 0) { + for (let i = 0; i < jsDocs.length; i++) { + const jsdoc: JSDoc = jsDocs[i]; + if (jsdoc.tags && jsdoc.tags.length > 0) { + for (let j = 0; j < jsdoc.tags.length; j++) { + const tag: JSDocTag = jsdoc.tags[j]; + if (tag.tag === SINCE_TAG_NAME) { + const currentVersion: number = Number.parseInt(tag.name ?? "0"); + if (!Number.isNaN(currentVersion) && currentVersion > maxVersion) { + maxVersion = currentVersion; + jsDocTags = jsdoc.tags; + } + break; + } + } + } + } + } + return jsDocTags; +} \ No newline at end of file diff --git a/build-tools/compile-plugins/api-check-plugin-static/api-check-wrapper/utils/api_check_wrapper_enums.ts b/build-tools/compile-plugins/api-check-plugin-static/api-check-wrapper/utils/api_check_wrapper_enums.ts new file mode 100644 index 0000000000..b5b3ee904f --- /dev/null +++ b/build-tools/compile-plugins/api-check-plugin-static/api-check-wrapper/utils/api_check_wrapper_enums.ts @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 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. + */ + +export enum DiagnosticCategory { + WARNING = 0, + ERROR = 1 +} \ No newline at end of file diff --git a/build-tools/compile-plugins/api-check-plugin-static/api-check-wrapper/utils/api_check_wrapper_typedef.ts b/build-tools/compile-plugins/api-check-plugin-static/api-check-wrapper/utils/api_check_wrapper_typedef.ts new file mode 100644 index 0000000000..5bcb77bfe5 --- /dev/null +++ b/build-tools/compile-plugins/api-check-plugin-static/api-check-wrapper/utils/api_check_wrapper_typedef.ts @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2025 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 { DiagnosticCategory } from "./api_check_wrapper_enums"; +import * as arkts from '@koalaui/libarkts'; + +/** + * ApiCheckWrapper服务,绑定校验规则 + */ +export interface ApiCheckWrapperServiceHost { + getJsDocNodeCheckedConfig: (currentFileName: string, symbolSourceFilePath: string) => JsDocNodeCheckConfig; + getFileCheckedModuleInfo: (containFilePath: string) => FileCheckModuleInfo; + pushLogInfo: ( + apiName: string, currentFilePath: string, + currentAddress: CurrentAddress, logLevel: DiagnosticCategory, logMessage: string) => void; + collectImportInfo: (moduleName: string[], modulePath: string, currentFilePath: string) => void; +} + +export interface JsDocNodeCheckConfig { + nodeNeedCheck: boolean; + checkConfig: JsDocNodeCheckConfigItem[]; +} + +export interface JsDocNodeCheckConfigItem { + tagName: string[]; + message: string; + type: DiagnosticCategory; + tagNameShouldExisted: boolean; + checkValidCallback?: (jsDocs: JSDoc[], config: JsDocNodeCheckConfigItem) => boolean; +} + +/** + * JSDoc类型 + */ +export interface JSDoc { + description: string; + tags: JSDocTag[]; +} + +/** + * JSDoc标签类型 + */ +export interface JSDocTag { + /** + * 标签名 + */ + tag: string; + /** + * 参数名称 + */ + name: string; + /** + * 默认值 + */ + default?: string; + /** + * 描述 + */ + description: string; + /** + * 完整内容 + */ + comment: string; +} + +export interface CurrentAddress { + line: number; + column: number; +} + +export interface FileCheckModuleInfo { + currentFileName: string; + fileNeedCheck: boolean; +} + +export interface ConditionCheckResult { + valid: boolean; + type?: DiagnosticCategory; + message?: string; +} + +export interface ASTDeclaration extends arkts.AstNode { + kind: number; + pos: number; + end: number; + parent?: ASTDeclaration; + jsDoc?: JSDoc[]; +} + +export interface ASTIdentifier extends arkts.AstNode { + kind: number; + text: string; +} + +export interface ASTSourceFile extends arkts.AstNode { + fileName: string; + text: string; +} \ No newline at end of file diff --git a/build-tools/compile-plugins/api-check-plugin-static/api-check-wrapper/utils/ts_wrapper_node_util.ts b/build-tools/compile-plugins/api-check-plugin-static/api-check-wrapper/utils/ts_wrapper_node_util.ts new file mode 100644 index 0000000000..8b54f3f108 --- /dev/null +++ b/build-tools/compile-plugins/api-check-plugin-static/api-check-wrapper/utils/ts_wrapper_node_util.ts @@ -0,0 +1,1614 @@ +/* + * Copyright (c) 2025 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 arkts from '@koalaui/libarkts'; +import { checkIdentifier } from "../src/api_check_wrapper"; + +export const nodeHandleFunctionMap = new Map void>([ + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ASSIGNMENT_EXPRESSION, handleAssignmentExpression], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ANNOTATION_USAGE, handleAnnotatedAstNode], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_LABELLED_STATEMENT, handleLabelledStatement], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_THROW_STATEMENT, handleThrowStatement], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_CLASS_PROPERTY, handleClassProperty], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_VOID_KEYWORD, handleTSVoidKeyword], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ETS_FUNCTION_TYPE, handleETSFunctionType], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_TYPE_OPERATOR, handleTSTypeOperator], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_IF_STATEMENT, handleIfStatement], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_CONSTRUCTOR_TYPE, handleTSConstructorType], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_DECORATOR, handleDecorator], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_ENUM_DECLARATION, handleTSEnumDeclaration], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_NEVER_KEYWORD, handleTSNeverKeyword], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_IMPORT_DEFAULT_SPECIFIER, handleImportDefaultSpecifier], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_IMPORT_SPECIFIER, handleImportSpecifier], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_CONDITIONAL_EXPRESSION, handleConditionalExpression], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_CALL_EXPRESSION, handleCallExpression], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_BIGINT_LITERAL, handleBigIntLiteral], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_IMPORT_TYPE, handleTSImportType], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TAGGED_TEMPLATE_EXPRESSION, handleTaggedTemplateExpression], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_FUNCTION_DECLARATION, handleFunctionDeclaration], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ETS_TYPE_REFERENCE, handleETSTypeReference], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_TYPE_REFERENCE, handleTSTypeReference], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_NAMED_TYPE, handleNamedType], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_NUMBER_LITERAL, handleNumberLiteral], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_FUNCTION_TYPE, handleTSFunctionType], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TEMPLATE_ELEMENT, handleTemplateElement], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_INTERFACE_DECLARATION, handleTSInterfaceDeclaration], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_VARIABLE_DECLARATION, handleVariableDeclaration], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_UNDEFINED_LITERAL, handleUndefinedLiteral], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_MEMBER_EXPRESSION, handleMemberExpression], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_CLASS_IMPLEMENTS, handleTSClassImplements], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_OBJECT_KEYWORD, handleTSObjectKeyword], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ETS_UNION_TYPE, handleETSUnionType], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_PROPERTY_SIGNATURE, handleTSPropertySignature], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_CONDITIONAL_TYPE, handleTSConditionalType], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_LITERAL_TYPE, handleTSLiteralType], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_TYPE_ALIAS_DECLARATION, handleTSTypeAliasDeclaration], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_DEBUGGER_STATEMENT, handleDebuggerStatement], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_RETURN_STATEMENT, handleReturnStatement], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_EXPORT_DEFAULT_DECLARATION, handleExportDefaultDeclaration], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_SCRIPT_FUNCTION, handleScriptFunction], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_CLASS_DEFINITION, handleClassDefinition], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_INTERFACE_BODY, handleTSInterfaceBody], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_TYPE_QUERY, handleTSTypeQuery], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_BIGINT_KEYWORD, handleTSBigintKeyword], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_PROPERTY, handleProperty], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_VARIABLE_DECLARATOR, handleVariableDeclarator], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_STRING_LITERAL, handleStringLiteral], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_TYPE_ASSERTION, handleTSTypeAssertion], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_EXTERNAL_MODULE_REFERENCE, handleTSExternalModuleReference], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_UNDEFINED_KEYWORD, handleTSUndefinedKeyword], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ETS_TUPLE, handleETSTuple], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TRY_STATEMENT, handleTryStatement], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_UNARY_EXPRESSION, handleUnaryExpression], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_FOR_IN_STATEMENT, handleForInStatement], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_THIS_EXPRESSION, handleThisExpression], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_METHOD_SIGNATURE, handleTSMethodSignature], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_BINARY_EXPRESSION, handleBinaryExpression], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_SUPER_EXPRESSION, handleSuperExpression], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ASSERT_STATEMENT, handleAssertStatement], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_STRING_KEYWORD, handleTSStringKeyword], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_EXPRESSION_STATEMENT, handleExpressionStatement], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ETS_MODULE, handleETSModule], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_META_PROPERTY_EXPRESSION, handleMetaProperty], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_ARRAY_TYPE, handleTSArrayType], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_SIGNATURE_DECLARATION, handleTSSignatureDeclaration], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_EXPORT_ALL_DECLARATION, handleExportAllDeclaration], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_EXPORT_SPECIFIER, handleExportSpecifier], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_TUPLE_TYPE, handleTSTupleType], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_FUNCTION_EXPRESSION, handleFunctionExpression], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_INDEX_SIGNATURE, handleTSIndexSignature], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_MODULE_DECLARATION, handleTSModuleDeclaration], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_IMPORT_DECLARATION, handleImportDeclaration], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_PARENT_TYPE, handleTSParenthesizedType], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_CHAR_LITERAL, handleCharLiteral], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ETS_PACKAGE_DECLARATION, handleETSPackageDeclaration], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ETS_IMPORT_DECLARATION, handleETSImportDeclaration], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_STRUCT_DECLARATION, handleETSStructDeclaration], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_MODULE_BLOCK, handleTSModuleBlock], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ETS_NEW_ARRAY_INSTANCE_EXPRESSION, handleETSNewArrayInstanceExpression], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ANNOTATION_DECLARATION, handleAnnotationDeclaration], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ANNOTATION_USAGE, handleAnnotationUsage], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_EMPTY_STATEMENT, handleEmptyStatement], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_WHILE_STATEMENT, handleWhileStatement], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_CHAIN_EXPRESSION, handleChainExpression], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_INTERSECTION_TYPE, handleTSIntersectionType], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_UPDATE_EXPRESSION, handleUpdateExpression], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_BLOCK_EXPRESSION, handleBlockExpression], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_TYPE_LITERAL, handleTSTypeLiteral], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_TYPE_PARAMETER, handleTSTypeParameter], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_BOOLEAN_LITERAL, handleTSBooleanKeyword], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_TYPE_PREDICATE, handleTSTypePredicate], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_IMPORT_NAMESPACE_SPECIFIER, handleImportNamespaceSpecifier], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_EXPORT_NAMED_DECLARATION, handleExportNamedDeclaration], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ETS_PARAMETER_EXPRESSION, handleETSParameterExpression], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_TYPE_PARAMETER_INSTANTIATION, handleTSTypeParameterInstantiation], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_NULL_LITERAL, handleNullLiteral], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_INFER_TYPE, handleTSInferType], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_SWITCH_CASE_STATEMENT, handleSwitchCaseStatement], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_YIELD_EXPRESSION, handleYieldExpression], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_IMPORT_EQUALS_DECLARATION, handleTSImportEqualsDeclaration], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_BOOLEAN_LITERAL, handleBooleanLiteral], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_NUMBER_KEYWORD, handleTSNumberKeyword], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_CLASS_STATIC_BLOCK, handleClassStaticBlock], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_NON_NULL_EXPRESSION, handleTSNonNullExpression], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_PREFIX_ASSERTION_EXPRESSION, handlePrefixAssertionExpression], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_CLASS_EXPRESSION, handleClassExpression], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_FOR_OF_STATEMENT, handleForOfStatement], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TEMPLATE_LITERAL, handleTemplateLiteral], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_UNION_TYPE, handleTSUnionType], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_UNKNOWN_KEYWORD, handleTSUnknownKeyword], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_IDENTIFIER, handleIdentifier], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_OPAQUE_TYPE_NODE, handleOpaqueTypeNode], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_BLOCK_STATEMENT, handleBlockStatement], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_DIRECT_EVAL, handleDirectEvalExpression], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_TYPE_PARAMETER_DECLARATION, handleTSTypeParameterDeclaration], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_METHOD_DEFINITION, handleMethodDefinition], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_NULL_KEYWORD, handleTSNullKeyword], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_INTERFACE_HERITAGE, handleTSInterfaceHeritage], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ETS_CLASS_LITERAL, handleETSClassLiteral], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_BREAK_STATEMENT, handleBreakStatement], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_REGEXP_LITERAL, handleRegExpLiteral], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_MAPPED_TYPE, handleTSMappedType], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_ANY_KEYWORD, handleTSAnyKeyword], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_CLASS_DECLARATION, handleClassDeclaration], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_INDEXED_ACCESS_TYPE, handleTSIndexedAccessType], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_QUALIFIED_NAME, handleTSQualifiedName], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_AWAIT_EXPRESSION, handleAwaitExpression], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_CONTINUE_STATEMENT, handleContinueStatement], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ETS_NEW_MULTI_DIM_ARRAY_INSTANCE_EXPRESSION, + handleETSNewMultiDimArrayInstanceExpression], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_NAMED_TUPLE_MEMBER, handleTSNamedTupleMember], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_IMPORT_EXPRESSION, handleImportExpression], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ETS_NULL_TYPE, handleETSNullType], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ETS_UNDEFINED_TYPE, handleETSUndefinedType], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TYPEOF_EXPRESSION, handleTypeofExpression], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_ENUM_MEMBER, handleTSEnumMember], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_SWITCH_STATEMENT, handleSwitchStatement], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_DO_WHILE_STATEMENT, handleDoWhileStatement], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_CATCH_CLAUSE, handleCatchClause], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_SEQUENCE_EXPRESSION, handleSequenceExpression], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ARROW_FUNCTION_EXPRESSION, handleArrowFunctionExpression], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_OMITTED_EXPRESSION, handleOmittedExpression], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ETS_NEW_CLASS_INSTANCE_EXPRESSION, handleETSNewClassInstanceExpression], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_AS_EXPRESSION, handleTSAsExpression], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_FOR_UPDATE_STATEMENT, handleForUpdateStatement], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ETS_TYPE_REFERENCE_PART, handleETSTypeReferencePart], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_REEXPORT_STATEMENT, handleETSReExportDeclaration], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ETS_PRIMITIVE_TYPE, handleETSPrimitiveType], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_NEW_EXPRESSION, handleNewExpression], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_PARAMETER_PROPERTY, handleTSParameterProperty], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ETS_WILDCARD_TYPE, handleETSWildcardType], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_THIS_TYPE, handleTSThisType], +]) + +type NodeTuple = [string, number]; +const items: NodeTuple[] = []; +const isDebug = false; +const nodeMap = new Map(); +let exporssionCount = 0; + +/** + * 根节点处理 + * @param { arkts.AstNode } node + */ +export function traverseProgram(node: arkts.AstNode) { + // 处理Identifier + if (!!node.statements) { + node.statements.forEach((item: arkts.AstNode) => handleAstNode(item)); + } +} + +/** + * 获取Jsdoc信息 + * @param { arkts.AstNode } node 节点 + * @returns { string } jsdoc 字符串 + */ +export function getJSDocInformation(node: arkts.AstNode): string { + return arkts.getJsdocStringFromDeclaration(node); +} + +/** + * 解析AST + * + * @param { arkts.AstNode } node 节点 + * @param { (node: any, ...args: any[]) => void } func 实际方法 + */ +function handleFunction(node: arkts.AstNode, func: (node: any, ...args: any[]) => void) { + if (isDebug) { + items.push([func.name, node.peer.toString()]); + } + // Expression 下的identifier才会提示告警 + if (node instanceof arkts.Expression) { + exporssionCount++; + } + if (node == null || node == undefined) { + return; + } + + func(node); + + if (isDebug) { + if (nodeMap.has(node.peer.toString())) { + if (nodeMap.get(node.peer.toString()) > 2) { + console.error("[API_CHECK_PLUGIN] repeat traverse"); + } + nodeMap.set(node.peer.toString(), nodeMap.get(node.peer.toString()) + 1); + } else { + nodeMap.set(node.peer.toString(), 1); + } + items.pop(); + } + if (node instanceof arkts.Expression) { + exporssionCount--; + } +} + +export function handleAstNode(node: arkts.AstNode) { + if (isDebug) { + console.info('[API_CHECK_PLUGIN] handleAstNode'); + } + let kind: number = arkts.arktsGlobal.generatedEs2panda._AstNodeTypeConst(arkts.arktsGlobal.context, node.peer) + if (nodeHandleFunctionMap.has(kind) && nodeHandleFunctionMap.get(kind) !== undefined) { + handleFunction(node, nodeHandleFunctionMap.get(kind)!) + } else { + console.error(`[API_CHECK_PLUGIN] debug handleAstNode ${node.constructor.name} error!`) + } +} + +export function handleAnnotatedAstNode(node: arkts.AstNode) { } + +export function handleAnnotatedExpression(node: arkts.AstNode) { + if (!!node.typeAnnotation) { + handleAstNode(node.typeAnnotation); + } +} + +export function handleAnnotatedStatement(node: arkts.AstNode) { } + +export function handleAnnotationDeclaration(node: arkts.AstNode) { + if (!!node.expr) { + handleAstNode(node.expr); + } + if (!!node.properties) { + node.properties.forEach((item: arkts.AstNode) => handleAstNode(item)); + } + if (!!node.annotations) { + node.annotations.forEach((item: arkts.AstNode) => handleFunction(item, handleAnnotationUsage)); + } +} + +export function handleAnnotationUsage(node: arkts.AstNode) { + if (!!node.expr) { + handleAstNode(node.expr); + } + if (!!node.properties) { + node.properties.forEach((item: arkts.AstNode) => handleAstNode(item)); + } +} + +export function handleArrayExpression(node: arkts.AstNode) { + if (!!node.elements) { + node.elements.forEach((item: arkts.AstNode) => handleAstNode(item)); + } + if (!!node.declarators) { + node.declarators.forEach((item: arkts.AstNode) => handleFunction(item, handleDecorator)); + } + if (!!node.typeAnnotation) { + handleAstNode(node.typeAnnotation); + } +} + +export function handleArrowFunctionExpression(node: arkts.AstNode) { + if (!!node.annotations) { + node.annotations.forEach((item: arkts.AstNode) => handleFunction(item, handleAnnotationUsage)); + } + if (!!node.scriptFunction) { + handleAstNode(node.scriptFunction); + } +} + +export function handleAssertStatement(node: arkts.AstNode) { + if (!!node.test) { + handleAstNode(node.test); + } + if (!!node.second) { + handleAstNode(node.second); + } +} + +export function handleAssignmentExpression(node: arkts.AstNode) { + if (!!node.left) { + handleAstNode(node.left); + } + if (!!node.right) { + handleAstNode(node.right); + } +} + +export function handleAstDumper(node: arkts.AstNode) { + return; +} + +export function handleAwaitExpression(node: arkts.AstNode) { + if (!!node.argument) { + handleAstNode(node.argument); + } +} + +export function handleBigIntLiteral(node: arkts.AstNode) { } + +export function handleBinaryExpression(node: arkts.AstNode) { + if (!!node.left) { + handleAstNode(node.left); + } + if (!!node.right) { + handleAstNode(node.right); + } + if (!!node.result) { + handleAstNode(node.result); + } +} + +export function handleBlockExpression(node: arkts.AstNode) { + if (!!node.statements) { + node.statements.forEach((item: arkts.AstNode) => handleAstNode(item)); + } +} + +export function handleBlockStatement(node: arkts.AstNode) { + if (!!node.statements) { + node.statements.forEach((item: arkts.AstNode) => handleAstNode(item)); + } +} + +export function handleBooleanLiteral(node: arkts.AstNode) { } + +export function handleBreakStatement(node: arkts.AstNode) { + if (!!node.ident) { + handleFunction(node.ident, handleIdentifier); + } + if (!!node.target) { + handleAstNode(node.target); + } +} + +export function handleCallExpression(node: arkts.AstNode) { + if (!!node.trailingBlock) { + handleAstNode(node.trailingBlock); + } + if (!!node.expression) { + handleAstNode(node.expression); + } + if (!!node.typeArguments) { + node.typeArguments.forEach((item: arkts.TypeNode) => handleAstNode(item)); + } + if (!!node.arguments) { + node.arguments.forEach((item: arkts.Expression) => handleAstNode(item)); + } + if (!!node.params) { + node.params.forEach((item: arkts.TypeNode) => handleAstNode(item)); + } +} + +export function handleCatchClause(node: arkts.AstNode) { + if (!!node.param) { + handleAstNode(node.param); + } + if (!!node.body) { + handleAstNode(node.body); + } +} + +export function handleChainExpression(node: arkts.AstNode) { + if (!!node.getExpression) { + handleAstNode(node.getExpression); + } +} + +export function handleCharLiteral(node: arkts.AstNode) { } + +export function handleClassDeclaration(node: arkts.AstNode) { + if (!!node.definition) { + handleFunction(node.definition, handleClassDefinition); + } + if (!!node.decorators) { + node.decorators.forEach((item: arkts.AstNode) => handleFunction(item, handleDecorator)); + } +} + +export function handleClassDefinition(node: arkts.AstNode) { + if (!!node.ident) { + handleFunction(node.ident, handleIdentifier); + } + if (!!node.super) { + handleAstNode(node.super); + } + if (!!node.body) { + node.body.forEach((item: arkts.AstNode) => handleAstNode(item)); + } + if (!!node.implments) { + node.implments.forEach((item: arkts.AstNode) => handleFunction(item, handleTSClassImplements)); + } + if (!!node.typeParams) { + handleFunction(node.typeParams, handleTSTypeParameterDeclaration); + } + if (!!node.superTypeParams) { + handleFunction(node.superTypeParams, handleTSTypeParameterInstantiation); + } + if (!!node.origEnumDecl) { + handleFunction(node.origEnumDecl, handleTSEnumDeclaration); + } + if (!!node.getAnonClass) { + handleAstNode(node.getAnonClass); + } +} + +export function handleClassElement(node: arkts.AstNode) { + if (!!node.key) { + handleAstNode(node.key); + } + if (!!node.value) { + handleAstNode(node.value); + } + if (!!node.decorators) { + node.decorators.forEach((item: arkts.AstNode) => handleFunction(item, handleDecorator)); + } +} + +export function handleClassExpression(node: arkts.AstNode) { + if (!!node.definition) { + handleFunction(node.definition, handleClassDefinition); + } +} + +export function handleClassProperty(node: arkts.AstNode) { + if (!!node.typeAnnotation) { + handleAstNode(node.typeAnnotation); + } + if (!!node.annotations) { + node.annotations.forEach((item: arkts.AstNode) => handleFunction(item, handleAnnotationUsage)); + } +} + +export function handleClassStaticBlock(node: arkts.AstNode) { } + +export function handleConditionalExpression(node: arkts.AstNode) { + if (!!node.test) { + handleAstNode(node.test); + } + if (!!node.consequent) { + handleAstNode(node.consequent); + } + if (!!node.alternate) { + handleAstNode(node.alternate); + } +} + +export function handleContext(node: arkts.AstNode) { } + +/** + * target重复节点,不遍历 + * @param { arkts.AstNode } node + */ +export function handleContinueStatement(node: arkts.AstNode) { + if (!!node.ident) { + handleFunction(node.ident, handleIdentifier); + } +} + +export function handleDebuggerStatement(node: arkts.AstNode) { } + +export function handleDecorator(node: arkts.AstNode) { + if (!!node.expr) { + handleAstNode(node.expr); + } +} + +export function handleDirectEvalExpression(node: arkts.AstNode) { + if (!!node.trailingBlock) { + handleAstNode(node.trailingBlock); + } + if (!!node.expression) { + handleAstNode(node.expression); + } + if (!!node.typeArguments) { + node.typeArguments.forEach((item: arkts.TypeNode) => handleAstNode(item)); + } + if (!!node.arguments) { + node.arguments.forEach((item: arkts.Expression) => handleAstNode(item)); + } + if (!!node.params) { + node.params.forEach((item: arkts.TypeNode) => handleAstNode(item)); + } +} + +export function handleDoWhileStatement(node: arkts.AstNode) { + if (!!node.test) { + handleAstNode(node.test); + } + if (!!node.body) { + handleAstNode(node.body); + } +} + +export function handleETSClassLiteral(node: arkts.AstNode) { + if (!!node.expr) { + handleAstNode(node.expr); + } +} + +export function handleETSDynamicFunctionType(node: arkts.AstNode) { + if (!!node.typeParams) { + handleFunction(node.typeParams, handleTSTypeParameterDeclaration); + } + if (!!node.params) { + node.params.forEach((item: arkts.AstNode) => handleAstNode(item)); + } + if (!!node.returnType) { + handleAstNode(node.returnType); + } + if (!!node.functionInterface) { + handleAstNode(node.functionInterface); + } +} + +export function handleETSFunctionType(node: arkts.AstNode) { + if (!!node.typeParams) { + handleFunction(node.typeParams, handleTSTypeParameterDeclaration); + } + if (!!node.params) { + node.params.forEach((item: arkts.AstNode) => handleAstNode(item)); + } + if (!!node.returnType) { + handleAstNode(node.returnType); + } + if (!!node.functionInterface) { + handleAstNode(node.functionInterface); + } +} + +export function handleETSImportDeclaration(node: arkts.AstNode) { } + +export function handleETSModule(node: arkts.AstNode) { + if (!!node.ident) { + handleFunction(node.ident, handleIdentifier); + } + if (!!node.annotations) { + node.annotations.forEach((item: arkts.AstNode) => handleFunction(item, handleAnnotationUsage)); + } + if (!!node.statements) { + node.statements.forEach((item: arkts.AstNode) => handleAstNode(item)); + } +} + +export function handleETSNewArrayInstanceExpression(node: arkts.AstNode) { + if (!!node.typeReference) { + handleAstNode(node.typeReference); + } + if (!!node.dimension) { + handleAstNode(node.dimension); + } +} + +export function handleETSNewClassInstanceExpression(node: arkts.AstNode) { + if (!!node.getTypeRef) { + handleAstNode(node.getTypeRef); + } + if (!!node.getArgments) { + node.getArgments.forEach((item: arkts.AstNode) => handleAstNode(item)); + } +} + +export function handleETSNewMultiDimArrayInstanceExpression(node: arkts.AstNode) { + if (!!node.dimensions) { + node.dimensions.forEach((item: arkts.AstNode) => handleAstNode(item)); + } + if (!!node.typeReference) { + handleAstNode(node.typeReference); + } +} + +export function handleETSNullType(node: arkts.AstNode) { } + +export function handleETSPackageDeclaration(node: arkts.AstNode) { } + +export function handleETSParameterExpression(node: arkts.AstNode) { + if (!!node.annotations) { + node.annotations.forEach((item: arkts.AstNode) => handleFunction(item, handleAnnotationUsage)); + } + if (!!node.type) { + handleAstNode(node.type); + } + if (!!node.initializer) { + handleAstNode(node.initializer); + } + if (!!node.identifier) { + handleFunction(node.identifier, handleIdentifier); + } +} + +export function handleETSPrimitiveType(node: arkts.AstNode) { +} + +export function handleETSReExportDeclaration(node: arkts.AstNode) { + if (!!node.getETSImportDeclarations) { + handleFunction(node.getETSImportDeclarations, handleETSImportDeclaration); + } +} + +export function handleETSStructDeclaration(node: arkts.AstNode) { + if (!!node.definition) { + handleFunction(node.definition, handleClassDefinition); + } + if (!!node.decorators) { + node.decorators.forEach((item: arkts.AstNode) => handleFunction(item, handleDecorator)); + } +} + +export function handleETSTuple(node: arkts.AstNode) { + if (!!node.getTupleTypeAnnotationsList) { + node.getTupleTypeAnnotationsList.forEach((item: arkts.AstNde) => handleAstNode(item)); + } +} + +export function handleETSTypeReference(node: arkts.AstNode) { + if (!!node.part) { + handleFunction(node.part, handleETSTypeReferencePart); + } +} + +export function handleETSTypeReferencePart(node: arkts.AstNode) { + if (!!node.previous) { + handleFunction(node.previous, handleETSTypeReferencePart); + } + if (!!node.name) { + handleAstNode(node.name); + } + if (!!node.typeParams) { + handleFunction(node.typeParams, handleTSTypeParameterInstantiation); + } +} + +export function handleETSUndefinedType(node: arkts.AstNode) { } + +export function handleETSUnionType(node: arkts.AstNode) { + if (!!node.types) { + node.types.forEach((item: arkts.AstNde) => handleAstNode(item)); + } +} + +export function handleETSWildcardType(node: arkts.AstNode) { + if (!!node.typeReference) { + handleFunction(node.typeReference, handleETSTypeReference); + } +} + +export function handleEmptyStatement(node: arkts.AstNode) { } + +export function handleExportAllDeclaration(node: arkts.AstNode) { + if (!!node.source) { + handleFunction(node.source, handleStringLiteral); + } + if (!!node.exported) { + handleFunction(node.exported, handleIdentifier); + } +} + +export function handleExportDefaultDeclaration(node: arkts.AstNode) { + if (!!node.decl) { + handleAstNode(node.decl); + } +} + +export function handleExportNamedDeclaration(node: arkts.AstNode) { + if (!!node.decl) { + handleAstNode(node.decl); + } + if (!!node.source) { + handleFunction(node.source, handleStringLiteral); + } + if (!!node.specifiers) { + node.specifiers.forEach((item: arkts.AstNode) => handleFunction(item, handleExportSpecifier)); + } +} + +export function handleExportSpecifier(node: arkts.AstNode) { + if (!!node.local) { + handleFunction(node.local, handleIdentifier); + } + if (!!node.exported) { + handleFunction(node.exported, handleIdentifier); + } +} + +export function handleExpression(node: arkts.AstNode) { } + +export function handleExpressionStatement(node: arkts.AstNode) { + if (!!node.expression) { + handleAstNode(node.expression); + } +} + +export function handleForInStatement(node: arkts.AstNode) { + if (!!node.left) { + handleAstNode(node.left); + } + if (!!node.right) { + handleAstNode(node.right); + } + if (!!node.body) { + handleAstNode(node.body); + } +} + +export function handleForOfStatement(node: arkts.AstNode) { + if (!!node.left) { + handleAstNode(node.left); + } + if (!!node.right) { + handleAstNode(node.right); + } + if (!!node.body) { + handleAstNode(node.body); + } +} + +export function handleForUpdateStatement(node: arkts.AstNode) { + if (!!node.init) { + handleAstNode(node.init); + } + if (!!node.test) { + handleAstNode(node.test); + } + if (!!node.update) { + handleAstNode(node.update); + } + if (!!node.body) { + handleAstNode(node.body); + } +} + +export function handleFunctionDecl(node: arkts.AstNode) { + if (!!node.id) { + handleFunction(node.id, handleIdentifier); + } + if (!!node.params) { + node.params.forEach((item: arkts.AstNode) => handleAstNode(item)); + } + if (!!node.returnStatements) { + node.returnStatements.forEach((item: arkts.AstNode) => handleFunction(item, handleReturnStatement)); + } + if (!!node.typeParams) { + handleFunction(node.typeParams, handleTSTypeParameterDeclaration); + } + if (!!node.body) { + handleAstNode(node.body); + } + if (!!node.returnTypeAnnotation) { + handleAstNode(node.returnTypeAnnotation); + } + if (!!node.annotations) { + node.annotations.forEach((item: arkts.AstNde) => handleFunction(item, handleAnnotationUsage)); + } +} + +export function handleFunctionDeclaration(node: arkts.AstNode) { + if (!!node.annotations) { + node.annotations.forEach((item: arkts.AstNode) => handleFunction(item, handleAnnotationUsage)); + } + if (!!node.scriptFunction) { + handleAstNode(node.scriptFunction); + } + if (!!node.parameters) { + node.parameters.forEach((item: arkts.AstNode) => handleAstNode(item)); + } + if (!!node.name) { + handleFunction(node.name, handleIdentifier); + } + if (!!node.body) { + handleAstNode(node.body); + } + if (!!node.typeParamsDecl) { + handleFunction(node.typeParamsDecl, handleTSTypeParameterDeclaration); + } + if (!!node.returnType) { + handleAstNode(node.returnType); + } +} + +export function handleFunctionExpression(node: arkts.AstNode) { + if (!!node.scriptFunction) { + handleAstNode(node.scriptFunction); + } + +} + +export function handleFunctionSignature(node: arkts.AstNode) { + if (!!node.params) { + node.params.forEach((item: arkts.AstNode) => handleAstNode(item)); + } + if (!!node.typeParams) { + handleFunction(node.typeParams, handleTSTypeParameterDeclaration); + } + if (!!node.returnType) { + handleAstNode(node.returnType); + } +} + +export function handleIdentifier(node: arkts.AstNode) { + if (exporssionCount > 1) { + checkIdentifier(node); + } + + if (!!node.decorators) { + node.decorators.forEach((item: arkts.AstNode) => handleFunction(item, handleDecorator)); + } + if (!!node.typeAnnotation) { + handleAstNode(node.typeAnnotation); + } +} + +export function handleIfStatement(node: arkts.AstNode) { + if (!!node.test) { + handleAstNode(node.test); + } + if (!!node.consequent) { + handleAstNode(node.consequent); + } + if (!!node.alternate) { + handleAstNode(node.alternate); + } +} + +export function handleImportDeclaration(node: arkts.AstNode) { +} + +export function handleImportDefaultSpecifier(node: arkts.AstNode) { + if (!!node.local) { + handleFunction(node.local, handleIdentifier); + } +} + +export function handleImportExpression(node: arkts.AstNode) { + if (!!node.source) { + handleFunction(node.source, handleStringLiteral); + } +} + +export function handleImportNamespaceSpecifier(node: arkts.AstNode) { + if (!!node.local) { + handleFunction(node.local, handleIdentifier); + } + +} + +export function handleImportSource(node: arkts.AstNode) { + if (!!node.source) { + handleFunction(node.source, handleStringLiteral); + } + if (!!node.resolvedSource) { + handleFunction(node.resolvedSource, handleStringLiteral); + } +} + +export function handleImportSpecifier(node: arkts.AstNode) { + if (!!node.imported) { + handleFunction(node.imported, handleIdentifier); + } + if (!!node.local) { + handleFunction(node.local, handleIdentifier); + } + +} + +export function handleInterfaceDecl(node: arkts.AstNode) { + if (!!node.id) { + handleFunction(node.id, handleIdentifier); + } + if (!!node.body) { + handleFunction(node.body, handleTSInterfaceBody); + } + if (!!node.typeParams) { + handleFunction(node.typeParam, handleTSTypeParameterDeclaration); + } + if (!!node.extends) { + node.extends.forEach((item: arkts.TypeNode) => handleFunction(item, handleTSInterfaceHeritage)); + } + if (!!node.decorators) { + node.decorators.forEach((item: arkts.AstNode) => handleFunction(item, handleDecorator)); + } + if (!!node.getAnonClass) { + handleAstNode(node.getAnonClass); + } + if (!!node.annotations) { + node.annotations.forEach((item: arkts.AstNode) => handleFunction(item, handleAnnotationUsage)); + } +} + +export function handleLabelPair(node: arkts.AstNode) { + if (!!node.ident) { + handleFunction(node.ident, handleIdentifier); + } + if (!!node.body) { + handleAstNode(node.body); + } +} + +export function handleLabelledStatement(node: arkts.AstNode) { } + +export function handleLiteral(node: arkts.AstNode) { } + +export function handleLoopStatement(node: arkts.AstNode) { } + +export function handleMaybeOptionalExpression(node: arkts.AstNode) { } + +export function handleMemberExpression(node: arkts.AstNode) { + if (!!node.object) { + handleAstNode(node.object); + } + if (!!node.property) { + handleAstNode(node.property); + } +} + +export function handleMetaProperty(node: arkts.AstNode) { } + +export function handleMethodDefinition(node: arkts.AstNode) { + if (!!node.overloads) { + node.overloads.forEach((item: arkts.AstNode) => handleFunction(item, handleMethodDefinition)); + } + if (!!node.scriptFunction) { + handleAstNode(node.scriptFunction); + } + if (!!node.name) { + handleFunction(node.name, handleIdentifier); + } +} + +export function handleNamedType(node: arkts.AstNode) { + if (!!node.name) { + handleFunction(node.name, handleIdentifier); + } + if (!!node.typeParams) { + handleFunction(node.typeParams, handleTSTypeParameterInstantiation); + } +} + +export function handleNewExpression(node: arkts.AstNode) { + if (!!node.callee) { + handleAstNode(node.callee); + } + if (!!node.arguments) { + node.arguments.forEach((item: arkts.AstNode) => handleAstNode(item)); + } +} + +export function handleNullLiteral(node: arkts.AstNode) { } + +export function handleNumberLiteral(node: arkts.AstNode) { } + +export function handleObjectExpression(node: arkts.AstNode) { + if (!!node.properties) { + node.properties.forEach((item: arkts.AstNode) => handleAstNode(item)); + } + if (!!node.decorators) { + node.decorators.forEach((item: arkts.AstNode) => handleFunction(item, handleDecorator)); + } + if (!!node.typeAnnotation) { + handleAstNode(node.typeAnnotation); + } +} + +export function handleOmittedExpression(node: arkts.AstNode) { } + +export function handleOpaqueTypeNode(node: arkts.AstNode) { } + +export function handlePrefixAssertionExpression(node: arkts.AstNode) { + if (!!node.expr) { + handleAstNode(node.expr); + } + if (!!node.type) { + handleAstNode(node.type); + } +} + +export function handleProperty(node: arkts.AstNode) { + if (!!node.key) { + handleAstNode(node.key); + } + if (!!node.value) { + handleAstNode(node.value); + } +} + +export function handleRegExpLiteral(node: arkts.AstNode) { } + +export function handleReturnStatement(node: arkts.AstNode) { + if (!!node.argument) { + handleAstNode(node.argument); + } +} + +export function handleScriptFunction(node: arkts.AstNode) { + if (!!node.id) { + handleFunction(node.id, handleIdentifier); + } + if (!!node.params) { + node.params.forEach((item: arkts.AstNode) => handleAstNode(item)); + } + if (!!node.returnStatements) { + node.returnStatements.forEach((item: arkts.AstNode) => handleFunction(item, handleReturnStatement)); + } + if (!!node.typeParams) { + handleFunction(node.typeParams, handleTSTypeParameterDeclaration); + } + if (!!node.body) { + handleAstNode(node.body); + } + if (!!node.returnTypeAnnotation) { + handleAstNode(node.returnTypeAnnotation); + } + if (!!node.annotations) { + node.annotations.forEach((item: arkts.AstNde) => handleFunction(item, handleAnnotationUsage)); + } +} + +export function handleSequenceExpression(node: arkts.AstNode) { + if (!!node.sequence) { + node.sequence.forEach((item: arkts.AstNode) => handleAstNode(item)); + } +} + +export function handleSpreadElement(node: arkts.AstNode) { + if (!!node.argument) { + handleAstNode(node.argument); + } + if (!!node.decorators) { + node.decorators.forEach((item: arkts.AstNode) => handleFunction(item, handleDecorator)); + } + if (!!node.typeAnnotation) { + handleAstNode(node.typeAnnotation); + } +} + +export function handleSrcDumper(node: arkts.AstNode) { + return; +} + +export function handleStatement(node: arkts.AstNode) { +} + +export function handleStringLiteral(node: arkts.AstNode) { } + +export function handleSuperExpression(node: arkts.AstNode) { + if (!!node.id) { + handleFunction(node.id, handleIdentifier); + } +} + +export function handleSwitchCaseStatement(node: arkts.AstNode) { + if (!!node.test) { + handleAstNode(node.test); + } + if (!!node.consequent) { + node.consequent.forEach((item: arkts.AstNode) => handleAstNode(item)); + } +} + +export function handleSwitchStatement(node: arkts.AstNode) { + if (!!node.discriminant) { + handleAstNode(node.discriminant); + } + if (!!node.cases) { + node.cases.forEach((item: arkts.AstNode) => handleFunction(item, handleSwitchCaseStatement)); + } +} + +export function handleTSAnyKeyword(node: arkts.AstNode) { +} + +export function handleTSArrayType(node: arkts.AstNode) { + if (!!node.elementType) { + handleAstNode(node.elementType); + } +} + +export function handleTSAsExpression(node: arkts.AstNode) { + if (!!node.expr) { + handleAstNode(node.expr); + } + if (!!node.typeAnnotation) { + handleAstNode(node.typeAnnotation); + } +} + +export function handleTSBigintKeyword(node: arkts.AstNode) { } + +export function handleTSBooleanKeyword(node: arkts.AstNode) { } + +export function handleTSClassImplements(node: arkts.AstNode) { + if (!!node.expr) { + handleAstNode(node.expr); + } + if (!!node.typeParameters) { + handleFunction(node.typeParameters, handleTSTypeParameterInstantiation); + } +} + +export function handleTSConditionalType(node: arkts.AstNode) { + if (!!node.checkType) { + handleAstNode(node.checkType); + } + if (!!node.extendsType) { + handleAstNode(node.extendsType); + } + if (!!node.trueType) { + handleAstNode(node.trueType); + } + if (!!node.falseType) { + handleAstNode(node.falseType); + } +} + +export function handleTSConstructorType(node: arkts.AstNode) { + if (!!node.typeParams) { + handleFunction(node.typeParameters, handleTSTypeParameterInstantiation); + } + if (!!node.params) { + node.params.forEach((item: arkts.AstNode) => handleAstNode(item)); + } + if (!!node.returnType) { + handleAstNode(node.returnType); + } +} + +export function handleTSEnumDeclaration(node: arkts.AstNode) { + if (!!node.key) { + handleFunction(node.key, handleIdentifier); + } + if (!!node.members) { + node.members.forEach((item: arkts.AstNde) => handleAstNode(item)); + } + if (!!node.boxedClass) { + handleFunction(node.boxedClass, handleClassDefinition); + } + if (!!node.decorators) { + node.decorators.forEach((item: arkts.AstNode) => handleFunction(item, handleDecorator)); + } +} + +export function handleTSEnumMember(node: arkts.AstNode) { + if (!!node.key) { + handleAstNode(node.key); + } + if (!!node.init) { + handleAstNode(node.init); + } +} + +export function handleTSExternalModuleReference(node: arkts.AstNode) { + if (!!node.expr) { + handleAstNode(node.expr); + } +} + +export function handleTSFunctionType(node: arkts.AstNode) { + if (!!node.typeParams) { + handleFunction(node.typeParams, handleTSTypeParameterInstantiation); + } + if (!!node.params) { + node.params.forEach((item: arkts.TypeNode) => handleAstNode(item)); + } + if (!!node.returnType) { + handleAstNode(node.returnType); + } +} + +export function handleTSImportEqualsDeclaration(node: arkts.AstNode) { + if (!!node.id) { + handleFunction(node.id, handleIdentifier); + } + if (!!node.moduleReference) { + handleAstNode(node.moduleReference); + } +} + +export function handleTSImportType(node: arkts.AstNode) { + if (!!node.typeParams) { + handleFunction(node.typeParams, handleTSTypeParameterInstantiation); + } + if (!!node.params) { + handleAstNode(node.params); + } + if (!!node.qualifier) { + handleAstNode(node.qualifier); + } +} + +export function handleTSIndexSignature(node: arkts.AstNode) { + if (!!node.objectType) { + handleAstNode(node.objectType); + } + if (!!node.indexType) { + handleAstNode(node.indexType); + } +} + +export function handleTSIndexedAccessType(node: arkts.AstNode) { + if (!!node.param) { + handleAstNode(node.param); + } + if (!!node.typeAnnotation) { + handleAstNode(node.typeAnnotation); + } +} + +export function handleTSInferType(node: arkts.AstNode) { + if (!!node.typeParam) { + handleFunction(node.typeParam, handleTSTypeParameter); + } +} + +export function handleTSInterfaceBody(node: arkts.AstNode) { + if (!!node.body) { + node.body.forEach((item: arkts.TypeNode) => handleAstNode(item)); + } +} + +export function handleTSInterfaceDeclaration(node: arkts.AstNode) { + if (!!node.id) { + handleFunction(node.id, handleIdentifier); + } + if (!!node.body) { + handleFunction(node.body, handleTSInterfaceBody); + } + if (!!node.typeParams) { + handleFunction(node.typeParam, handleTSTypeParameterDeclaration); + } + if (!!node.extends) { + node.extends.forEach((item: arkts.TypeNode) => handleFunction(item, handleTSInterfaceHeritage)); + } + if (!!node.decorators) { + node.decorators.forEach((item: arkts.AstNode) => handleFunction(item, handleDecorator)); + } + if (!!node.getAnonClass) { + handleAstNode(node.getAnonClass); + } + if (!!node.annotations) { + node.annotations.forEach((item: arkts.AstNode) => handleFunction(item, handleAnnotationUsage)); + } +} + +export function handleTSInterfaceHeritage(node: arkts.AstNode) { + if (!!node.expr) { + handleAstNode(node.expr); + } +} + +export function handleTSIntersectionType(node: arkts.AstNode) { + if (!!node.types) { + node.types.forEach((item: arkts.AstNode) => handleAstNode(item)); + } +} + +export function handleTSLiteralType(node: arkts.AstNode) { + if (!!node.literal) { + handleAstNode(node.literal); + } +} + +export function handleTSMappedType(node: arkts.AstNode) { + if (!!node.typeParameter) { + handleFunction(node.typeParameter, handleTSTypeParameter); + } + if (!!node.typeAnnotation) { + handleAstNode(node.typeAnnotation); + } +} + +export function handleTSMethodSignature(node: arkts.AstNode) { + if (!!node.key) { + handleAstNode(node.key); + } + if (!!node.typeParams) { + handleFunction(node.typeParams, handleTSTypeParameterDeclaration); + } + if (!!node.params) { + node.params.forEach((item: arkts.AstNode) => handleAstNode(item)); + } + if (!!node.returnTypeAnnotation) { + handleAstNode(node.returnTypeAnnotation); + } +} + +export function handleTSModuleBlock(node: arkts.AstNode) { + if (!!node.statements) { + node.statements.forEach((item: arkts.AstNode) => handleAstNode(item)); + } +} + +export function handleTSModuleDeclaration(node: arkts.AstNode) { + if (!!node.name) { + handleAstNode(node.name); + } + if (!!node.body) { + handleAstNode(node.body); + } +} + +export function handleTSNamedTupleMember(node: arkts.AstNode) { + if (!!node.label) { + handleAstNode(node.label); + } + if (!!node.elementType) { + handleAstNode(node.elementType); + } +} + +export function handleTSNeverKeyword(node: arkts.AstNode) { } + +export function handleTSNonNullExpression(node: arkts.AstNode) { + if (!!node.expr) { + handleAstNode(node.expr); + } +} + +export function handleTSNullKeyword(node: arkts.AstNode) { } + +export function handleTSNumberKeyword(node: arkts.AstNode) { } + +export function handleTSObjectKeyword(node: arkts.AstNode) { } + +export function handleTSParameterProperty(node: arkts.AstNode) { + if (!!node.parameter) { + handleAstNode(node.parameter); + } +} + +export function handleTSParenthesizedType(node: arkts.AstNode) { + if (!!node.type) { + handleAstNode(node.type); + } +} + +export function handleTSPropertySignature(node: arkts.AstNode) { + if (!!node.key) { + handleAstNode(node.key); + } + if (!!node.typeAnnotation) { + handleAstNode(node.typeAnnotation); + } +} + +export function handleTSQualifiedName(node: arkts.AstNode) { + if (!!node.left) { + handleAstNode(node.left); + } + if (!!node.right) { + handleFunction(node.right, handleIdentifier); + } +} + +export function handleTSSignatureDeclaration(node: arkts.AstNode) { + if (!!node.typeParams) { + handleFunction(node.typeParams, handleTSTypeParameterDeclaration); + } + if (!!node.params) { + node.params.forEach((item: arkts.AstNode) => handleAstNode(item)); + } + if (!!node.returnTypeAnnotation) { + handleAstNode(node.returnTypeAnnotation); + } +} + +export function handleTSStringKeyword(node: arkts.AstNode) { } + +export function handleTSThisType(node: arkts.AstNode) { } + +export function handleTSTupleType(node: arkts.AstNode) { + if (!!node.elementType) { + node.elementType.forEach((item: arkts.AstNode) => handleAstNode(item)); + } +} + +export function handleTSTypeAliasDeclaration(node: arkts.AstNode) { + if (!!node.id) { + handleFunction(node.id, handleIdentifier); + } + if (!!node.typeParams) { + handleFunction(node.typeParams, handleTSTypeParameterDeclaration); + } + if (!!node.decorators) { + node.decorators.forEach((item: arkts.AstNode) => handleFunction(item, handleDecorator)); + } + if (!!node.annotations) { + node.annotations.forEach((item: arkts.AstNode) => handleFunction(item, handleAnnotationUsage)); + } + if (!!node.typeAnnotation) { + handleAstNode(node.typeAnnotation); + } +} + +export function handleTSTypeAssertion(node: arkts.AstNode) { + if (!!node.getExpression) { + handleAstNode(node.getExpression); + } + if (!!node.typeAnnotation) { + handleAstNode(node.typeAnnotation); + } + +} + +export function handleTSTypeLiteral(node: arkts.AstNode) { + if (!!node.members) { + node.members.forEach((item: arkts.AstNode) => handleAstNode(item)); + } + if (!!node.type) { + handleAstNode(node.type); + } +} + +export function handleTSTypeOperator(node: arkts.AstNode) { + if (!!node.type) { + handleAstNode(node.type); + } +} + +export function handleTSTypeParameter(node: arkts.AstNode) { + if (!!node.name) { + handleFunction(node.name, handleIdentifier); + } + if (!!node.constraint) { + handleAstNode(node.constraint); + } + if (!!node.defaultType) { + handleAstNode(node.defaultType); + } + if (!!node.annotations) { + node.annotations.forEach((item: arkts.AstNode) => handleFunction(item, handleAnnotationUsage)); + } +} + +export function handleTSTypeParameterDeclaration(node: arkts.AstNode) { + if (!!node.params) { + node.params.forEach((item: arkts.AstNode) => handleFunction(item, handleTSTypeParameter)); + } +} + +export function handleTSTypeParameterInstantiation(node: arkts.AstNode) { + if (!!node.params) { + node.params.forEach((item: arkts.AstNode) => handleAstNode(item)); + } +} + +export function handleTSTypePredicate(node: arkts.AstNode) { + if (!!node.parameterName) { + handleAstNode(node.parameterName); + } + if (!!node.typeAnnotation) { + handleAstNode(node.typeAnnotation); + } +} + +export function handleTSTypeQuery(node: arkts.AstNode) { + if (!!node.exprName) { + handleAstNode(node.exprName); + } +} + +export function handleTSTypeReference(node: arkts.AstNode) { + if (!!node.typeName) { + handleAstNode(node.typeName); + } + if (!!node.typeParams) { + handleFunction(node.typeParams, handleTSTypeParameterInstantiation); + } +} + +export function handleTSUndefinedKeyword(node: arkts.AstNode) { } + +export function handleTSUnionType(node: arkts.AstNode) { + if (!!node.types) { + node.types.forEach((item: arkts.AstNode) => traverseProgram(item)); + } +} + +export function handleTSUnknownKeyword(node: arkts.AstNode) { } + +export function handleTSVoidKeyword(node: arkts.AstNode) { } + +export function handleTaggedTemplateExpression(node: arkts.AstNode) { + if (!!node.tag) { + handleAstNode(node.tag); + } + if (!!node.quasi) { + handleFunction(node.quasi, handleTemplateLiteral); + } + if (!!node.typeParams) { + handleFunction(node.typeParams, handleTSTypeParameterInstantiation); + } +} + +export function handleTemplateElement(node: arkts.AstNode) { } + +export function handleTemplateLiteral(node: arkts.AstNode) { + if (!!node.quasis) { + node.quasis.forEach((item: arkts.AstNode) => handleFunction(item, handleTemplateLiteral)); + } + if (!!node.expressions) { + node.expressions.forEach((item: arkts.AstNode) => handleAstNode(item)); + } +} + +export function handleThisExpression(node: arkts.AstNode) { } + +export function handleThrowStatement(node: arkts.AstNode) { + if (!!node.argument) { + handleAstNode(node.argument); + } +} + +export function handleTryStatement(node: arkts.AstNode) { + if (!!node.finallyBlock) { + handleAstNode(node.finallyBlock); + } + if (!!node.block) { + handleAstNode(node.block); + } + if (!!node.catchClauses) { + node.catchClauses.forEach((item: arkts.AstNode) => handleFunction(item, handleCatchClause)); + } +} + +export function handleTypeNode(node: arkts.AstNode) { } + +export function handleTypedAstNode(node: arkts.AstNode) { } + +export function handleTypedStatement(node: arkts.AstNode) { } + +export function handleTypeofExpression(node: arkts.AstNode) { + if (!!node.argument) { + handleAstNode(node.argument); + } +} + +export function handleUnaryExpression(node: arkts.AstNode) { + if (!!node.argument) { + handleAstNode(node.argument); + } +} + +export function handleUndefinedLiteral(node: arkts.AstNode) { } + +export function handleUpdateExpression(node: arkts.AstNode) { + if (!!node.argument) { + handleAstNode(node.argument); + } +} + +export function handleValidationInfo(node: arkts.AstNode) { } + +export function handleVariableDeclaration(node: arkts.AstNode) { + if (!!node.annotations) { + node.annotations.forEach((item: arkts.AstNode) => handleFunction(item, handleAnnotationUsage)); + } + if (!!node.declarators) { + node.declarators.forEach((item: arkts.AstNode) => handleFunction(item, handleVariableDeclarator)); + } +} + +export function handleVariableDeclarator(node: arkts.AstNode) { + if (!!node.initializer) { + handleAstNode(node.initializer); + } + if (!!node.name) { + handleFunction(node.name, handleIdentifier); + } +} + +export function handleWhileStatement(node: arkts.AstNode) { + if (!!node.test) { + handleAstNode(node.test); + } + if (!!node.body) { + handleAstNode(node.body); + } +} + +export function handleYieldExpression(node: arkts.AstNode) { + if (!!node.argument) { + handleAstNode(node.argument); + } +} diff --git a/build-tools/compile-plugins/api-check-plugin-static/babel.config.js b/build-tools/compile-plugins/api-check-plugin-static/babel.config.js new file mode 100644 index 0000000000..9749768be6 --- /dev/null +++ b/build-tools/compile-plugins/api-check-plugin-static/babel.config.js @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2025 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. + */ + +module.exports = function(api) { + api.cache(true); + + const presets = ['@babel/typescript']; + const plugins = [ + '@babel/plugin-transform-modules-commonjs', + '@babel/plugin-proposal-class-properties', + [ + '@babel/plugin-transform-arrow-functions', + { + spec: true + } + ], + './custom-import-plugin' + ]; + const ignore = [ + '**/test/**', + '**/node_modules/**' + ]; + + return { + presets, + plugins, + ignore + }; +}; diff --git a/build-tools/compile-plugins/api-check-plugin-static/custom-import-plugin.js b/build-tools/compile-plugins/api-check-plugin-static/custom-import-plugin.js new file mode 100644 index 0000000000..a5ec31a241 --- /dev/null +++ b/build-tools/compile-plugins/api-check-plugin-static/custom-import-plugin.js @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2025 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. + */ + + +const path = require('path'); + +module.exports = function (babel) { + const { types: t } = babel; + + return { + name: 'custom-import-plugin', + visitor: { + ImportDeclaration(pathNode) { + const sourceValue = pathNode.node.source.value; + if ( + sourceValue === '@koalaui/libarkts' && + pathNode.node.specifiers.length === 1 && + t.isImportNamespaceSpecifier(pathNode.node.specifiers[0])) { + const currentFileDir = path.dirname(pathNode.hub.file.opts.filename); + const configDir = process.cwd(); + const relativePath = path.relative(currentFileDir, configDir); + const importPath = relativePath ? path.join(relativePath, '../path') : './path'; + + const newImport = t.importDeclaration( + [t.importSpecifier(t.identifier('getArktsPath'), t.identifier('getArktsPath'))], + t.stringLiteral(importPath)); + const requireCall = t.callExpression( + t.identifier('require'), + [t.callExpression(t.identifier('getArktsPath'), [])]); + const arkts = t.variableDeclaration( + 'const', + [t.variableDeclarator(t.identifier('arkts'), requireCall)]); + + pathNode.replaceWithMultiple([newImport, arkts]); + } + } + } + }; +}; \ No newline at end of file diff --git a/build-tools/compile-plugins/api-check-plugin-static/index.ts b/build-tools/compile-plugins/api-check-plugin-static/index.ts new file mode 100644 index 0000000000..7a2ef7bd43 --- /dev/null +++ b/build-tools/compile-plugins/api-check-plugin-static/index.ts @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2025 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 { Plugins, PluginContext } from '../common/plugin-context'; +import { GlobalObject, ProjectConfig } from './utils/api_check_plugin_typedef'; +import { createOrCleanProjectConfig, readCardPageSet, readPermissions, readSyscapInfo, readSystemModules, creatApiCheckConfig } from './utils/api_check_plugin_utils'; +import { ApiCheckWrapperServiceHost } from './api-check-wrapper'; +import { getApiCheckWrapperServiceHost } from './src/api_check_config'; +import { checkApiExpression, WrapperApi } from './api-check-wrapper/src/api_check_wrapper'; + +/** + * 导出projectConfig作为全局变量 + */ +export const globalObject: GlobalObject = { + projectConfig: createOrCleanProjectConfig() +} + +/** + * 入口方法 + * + * @returns { Plugins } + */ +export function apiCheckPlugin(): Plugins { + return { + name: 'api-check-plugins', + checked: apiCheckCallback, + clean() { + console.info("[API_CHECK_PLUGIN] CLEAN"); + WrapperApi.arktsGlobal.clearContext(); + } + }; +} + +/** + * 入口回调 + * + * @param { PluginContext } this PluginContext对象 + */ +function apiCheckCallback(this: PluginContext): void { + console.info('[API_CHECK_PLUGIN] AFTER CHECKED ENTER'); + try { + const currentProjectConfig: ProjectConfig | undefined = this.getProjectConfig() as ProjectConfig | undefined; + if (currentProjectConfig) { + initApiCheckConfig(currentProjectConfig); + Object.assign(globalObject.projectConfig, currentProjectConfig); + const ContextPtr = this.getContextPtr(); + const apiCheckHost: ApiCheckWrapperServiceHost = getApiCheckWrapperServiceHost(); + checkApiExpression(apiCheckHost, ContextPtr); + } + else { + throw new Error('[API_CHECK_PLUGIN] Get ProjectConfig Fail'); + } + } + catch (error) { + if (error) { + console.error(`[API_CHECK_PLUGIN] ${error}`); + } + } + console.info('[API_CHECK_PLUGIN] AFTER CHECKED EXIT'); +} + +/** + * 初始化projectConfig + * + * @param { ProjectConfig } projectConfig + * @returns + */ +export function initApiCheckConfig(projectConfig: ProjectConfig): void { + if (projectConfig.initApiCheckTag) { + return; + } + Object.assign(projectConfig, creatApiCheckConfig()); + readPermissions(projectConfig); + readCardPageSet(projectConfig); + readSystemModules(projectConfig); + readSyscapInfo(projectConfig); +} \ No newline at end of file diff --git a/build-tools/compile-plugins/api-check-plugin-static/package-lock.json b/build-tools/compile-plugins/api-check-plugin-static/package-lock.json new file mode 100644 index 0000000000..1564a63a94 --- /dev/null +++ b/build-tools/compile-plugins/api-check-plugin-static/package-lock.json @@ -0,0 +1,2347 @@ +{ + "name": "api-check-plugin-static", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "api-check-plugin-static", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@babel/cli": "7.20.7", + "@babel/core": "7.20.12", + "@babel/plugin-proposal-class-properties": "7.18.6", + "@babel/preset-env": "7.20.2", + "@babel/preset-typescript": "7.18.6", + "@babel/runtime": "7.20.13", + "fs": "^0.0.1-security", + "path": "^0.12.7" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/cli": { + "version": "7.20.7", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/cli/-/cli-7.20.7.tgz", + "integrity": "sha512-WylgcELHB66WwQqItxNILsMlaTd8/SO6SgTTjMp4uCI7P4QyH1r3nqgFmO3BfM4AtfniHgFMH3EpYFj/zynBkQ==", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.8", + "commander": "^4.0.1", + "convert-source-map": "^1.1.0", + "fs-readdir-recursive": "^1.1.0", + "glob": "^7.2.0", + "make-dir": "^2.1.0", + "slash": "^2.0.0" + }, + "bin": { + "babel": "bin/babel.js", + "babel-external-helpers": "bin/babel-external-helpers.js" + }, + "engines": { + "node": ">=6.9.0" + }, + "optionalDependencies": { + "@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents.3", + "chokidar": "^3.4.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/compat-data/-/compat-data-7.28.0.tgz", + "integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.20.12", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/core/-/core-7.20.12.tgz", + "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==", + "dependencies": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.7", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helpers": "^7.20.7", + "@babel/parser": "^7.20.7", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.12", + "@babel/types": "^7.20.7", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.2", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/generator/-/generator-7.28.0.tgz", + "integrity": "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==", + "dependencies": { + "@babel/parser": "^7.28.0", + "@babel/types": "^7.28.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.27.1.tgz", + "integrity": "sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/traverse": "^7.27.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.1.tgz", + "integrity": "sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "regexpu-core": "^6.2.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.3.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", + "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.17.7", + "@babel/helper-plugin-utils": "^7.16.7", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0-0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.24.7", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz", + "integrity": "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.27.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", + "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", + "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", + "dependencies": { + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", + "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-wrap-function": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", + "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", + "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/helper-wrap-function/-/helper-wrap-function-7.27.1.tgz", + "integrity": "sha512-NFJK2sHUvrjo8wAU/nQTWU890/zB2jj0qBcCbZbbf+005cAsv6tMjXz31fBign6M5ov1o0Bllu+9nbqkfsjjJQ==", + "dependencies": { + "@babel/template": "^7.27.1", + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.27.6", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/helpers/-/helpers-7.27.6.tgz", + "integrity": "sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.27.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/parser/-/parser-7.28.0.tgz", + "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", + "dependencies": { + "@babel/types": "^7.28.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz", + "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", + "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-proposal-async-generator-functions": { + "version": "7.20.7", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz", + "integrity": "sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-async-generator-functions instead.", + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-remap-async-to-generator": "^7.18.9", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-class-properties": { + "version": "7.18.6", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", + "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-class-static-block": { + "version": "7.21.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.21.0.tgz", + "integrity": "sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-static-block instead.", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.21.0", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-proposal-dynamic-import": { + "version": "7.18.6", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", + "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-dynamic-import instead.", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-export-namespace-from": { + "version": "7.18.9", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", + "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-export-namespace-from instead.", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-json-strings": { + "version": "7.18.6", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", + "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-json-strings instead.", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.20.7", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz", + "integrity": "sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-logical-assignment-operators instead.", + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.18.6", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", + "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead.", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-numeric-separator": { + "version": "7.18.6", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", + "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-numeric-separator instead.", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-object-rest-spread": { + "version": "7.20.7", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz", + "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead.", + "dependencies": { + "@babel/compat-data": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-optional-catch-binding": { + "version": "7.18.6", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", + "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-catch-binding instead.", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-optional-chaining": { + "version": "7.21.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", + "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.", + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-methods": { + "version": "7.18.6", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", + "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-methods instead.", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.11", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.11.tgz", + "integrity": "sha512-0QZ8qP/3RLDVBwBFoWAwCtgcDZJVwA5LUJRZU8x2YFfKNuFq161wK3cuGrALu5yiPu+vzwTAg/sMWVNeWeNyaw==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-property-in-object instead.", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.21.0", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-unicode-property-regex": { + "version": "7.18.6", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", + "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-unicode-property-regex instead.", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz", + "integrity": "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", + "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", + "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz", + "integrity": "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-remap-async-to-generator": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz", + "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.28.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.0.tgz", + "integrity": "sha512-gKKnwjpdx5sER/wl0WN0efUBFzF/56YZO0RJrSYP4CljXnP31ByY7fol89AzomdlLNzI36AvOTmYHsnZTCkq8Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.28.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.0.tgz", + "integrity": "sha512-IjM1IoJNw72AZFlj33Cu8X0q2XK/6AaVC3jQu+cgQ5lThWD5ajnuUAml80dqRmOhmPkTH8uAwnpMu9Rvj0LTRA==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-globals": "^7.28.0", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/traverse": "^7.28.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz", + "integrity": "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/template": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.28.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.0.tgz", + "integrity": "sha512-v1nrSMBiKcodhsyJ4Gf+Z0U/yawmJDBOTpEB3mcQY52r9RIyPneGyAS/yM6seP/8I+mWI3elOMtT5dB8GJVs+A==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz", + "integrity": "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz", + "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.27.1.tgz", + "integrity": "sha512-uspvXnhHvGKf2r4VVtBpeFnuDWsJLQ6MF6lGJLC89jBR1uoVeqM416AZtTuhTezOfgHicpJQmoD5YUakO/YmXQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", + "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", + "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", + "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz", + "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz", + "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", + "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.27.1.tgz", + "integrity": "sha512-w5N1XzsRbc0PQStASMksmUeqECuzKuTJer7kFagK8AXgpCMkeDMO5S+aaFb7A51ZYDF7XI34qsTX+fkHiIm5yA==", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz", + "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz", + "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz", + "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz", + "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.27.1.tgz", + "integrity": "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.27.7", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", + "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz", + "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.28.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.0.tgz", + "integrity": "sha512-LOAozRVbqxEVjSKfhGnuLoE4Kz4Oc5UJzuvFUhSsQzdCdaAQu06mG8zDv2GFSerM62nImUZ7K92vxnQcLSDlCQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz", + "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", + "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz", + "integrity": "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", + "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", + "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz", + "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.28.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.0.tgz", + "integrity": "sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz", + "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.27.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", + "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.20.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/preset-env/-/preset-env-7.20.2.tgz", + "integrity": "sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==", + "dependencies": { + "@babel/compat-data": "^7.20.1", + "@babel/helper-compilation-targets": "^7.20.0", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-validator-option": "^7.18.6", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-async-generator-functions": "^7.20.1", + "@babel/plugin-proposal-class-properties": "^7.18.6", + "@babel/plugin-proposal-class-static-block": "^7.18.6", + "@babel/plugin-proposal-dynamic-import": "^7.18.6", + "@babel/plugin-proposal-export-namespace-from": "^7.18.9", + "@babel/plugin-proposal-json-strings": "^7.18.6", + "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", + "@babel/plugin-proposal-numeric-separator": "^7.18.6", + "@babel/plugin-proposal-object-rest-spread": "^7.20.2", + "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", + "@babel/plugin-proposal-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-private-methods": "^7.18.6", + "@babel/plugin-proposal-private-property-in-object": "^7.18.6", + "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.20.0", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-transform-arrow-functions": "^7.18.6", + "@babel/plugin-transform-async-to-generator": "^7.18.6", + "@babel/plugin-transform-block-scoped-functions": "^7.18.6", + "@babel/plugin-transform-block-scoping": "^7.20.2", + "@babel/plugin-transform-classes": "^7.20.2", + "@babel/plugin-transform-computed-properties": "^7.18.9", + "@babel/plugin-transform-destructuring": "^7.20.2", + "@babel/plugin-transform-dotall-regex": "^7.18.6", + "@babel/plugin-transform-duplicate-keys": "^7.18.9", + "@babel/plugin-transform-exponentiation-operator": "^7.18.6", + "@babel/plugin-transform-for-of": "^7.18.8", + "@babel/plugin-transform-function-name": "^7.18.9", + "@babel/plugin-transform-literals": "^7.18.9", + "@babel/plugin-transform-member-expression-literals": "^7.18.6", + "@babel/plugin-transform-modules-amd": "^7.19.6", + "@babel/plugin-transform-modules-commonjs": "^7.19.6", + "@babel/plugin-transform-modules-systemjs": "^7.19.6", + "@babel/plugin-transform-modules-umd": "^7.18.6", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", + "@babel/plugin-transform-new-target": "^7.18.6", + "@babel/plugin-transform-object-super": "^7.18.6", + "@babel/plugin-transform-parameters": "^7.20.1", + "@babel/plugin-transform-property-literals": "^7.18.6", + "@babel/plugin-transform-regenerator": "^7.18.6", + "@babel/plugin-transform-reserved-words": "^7.18.6", + "@babel/plugin-transform-shorthand-properties": "^7.18.6", + "@babel/plugin-transform-spread": "^7.19.0", + "@babel/plugin-transform-sticky-regex": "^7.18.6", + "@babel/plugin-transform-template-literals": "^7.18.9", + "@babel/plugin-transform-typeof-symbol": "^7.18.9", + "@babel/plugin-transform-unicode-escapes": "^7.18.10", + "@babel/plugin-transform-unicode-regex": "^7.18.6", + "@babel/preset-modules": "^0.1.5", + "@babel/types": "^7.20.2", + "babel-plugin-polyfill-corejs2": "^0.3.3", + "babel-plugin-polyfill-corejs3": "^0.6.0", + "babel-plugin-polyfill-regenerator": "^0.4.1", + "core-js-compat": "^3.25.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/preset-modules/-/preset-modules-0.1.6.tgz", + "integrity": "sha512-ID2yj6K/4lKfhuU3+EX4UvNbIt7eACFbHmNUjzA+ep+B5971CknnA/9DEWKbRokfbbtblxxxXFJJrH47UEAMVg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.18.6", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz", + "integrity": "sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-validator-option": "^7.18.6", + "@babel/plugin-transform-typescript": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.20.13", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/runtime/-/runtime-7.20.13.tgz", + "integrity": "sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==", + "dependencies": { + "regenerator-runtime": "^0.13.11" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/traverse/-/traverse-7.28.0.tgz", + "integrity": "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.0", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/types/-/types-7.28.0.tgz", + "integrity": "sha512-jYnje+JyZG5YThjHiF28oT4SIZLnYOcSBb6+SDaFIyzDVSkXQmQQYclJ2R+YxcdmK0AX6x1E5OQNtuh3jHDrUg==", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.12", + "resolved": "https://repo.huaweicloud.com/repository/npm/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", + "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", + "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.29", + "resolved": "https://repo.huaweicloud.com/repository/npm/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", + "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nicolo-ribaudo/chokidar-2": { + "version": "2.1.8-no-fsevents.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz", + "integrity": "sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==", + "optional": true + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "optional": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.3.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", + "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", + "dependencies": { + "@babel/compat-data": "^7.17.7", + "@babel/helper-define-polyfill-provider": "^0.3.3", + "semver": "^6.1.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.6.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", + "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.3.3", + "core-js-compat": "^3.25.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.4.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", + "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.3.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "optional": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://repo.huaweicloud.com/repository/npm/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "optional": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.25.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/browserslist/-/browserslist-4.25.1.tgz", + "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001726", + "electron-to-chromium": "^1.5.173", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001727", + "resolved": "https://repo.huaweicloud.com/repository/npm/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz", + "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "optional": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "node_modules/core-js-compat": { + "version": "3.44.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/core-js-compat/-/core-js-compat-3.44.0.tgz", + "integrity": "sha512-JepmAj2zfl6ogy34qfWtcE7nHKAJnKsQFRn++scjVS2bZFllwptzw61BZcZFYBPpUznLfAvh0LGhxKppk04ClA==", + "dependencies": { + "browserslist": "^4.25.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.182", + "resolved": "https://repo.huaweicloud.com/repository/npm/electron-to-chromium/-/electron-to-chromium-1.5.182.tgz", + "integrity": "sha512-Lv65Btwv9W4J9pyODI6EWpdnhfvrve/us5h1WspW8B2Fb0366REPtY3hX7ounk1CkV/TBjWCEvCBBbYbmV0qCA==" + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "optional": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs": { + "version": "0.0.1-security", + "resolved": "https://repo.huaweicloud.com/repository/npm/fs/-/fs-0.0.1-security.tgz", + "integrity": "sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w==" + }, + "node_modules/fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "optional": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://repo.huaweicloud.com/repository/npm/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "optional": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "optional": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "optional": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://repo.huaweicloud.com/repository/npm/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://repo.huaweicloud.com/repository/npm/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/path": { + "version": "0.12.7", + "resolved": "https://repo.huaweicloud.com/repository/npm/path/-/path-0.12.7.tgz", + "integrity": "sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==", + "dependencies": { + "process": "^0.11.1", + "util": "^0.10.3" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://repo.huaweicloud.com/repository/npm/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "optional": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "engines": { + "node": ">=6" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://repo.huaweicloud.com/repository/npm/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "optional": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", + "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://repo.huaweicloud.com/repository/npm/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + }, + "node_modules/regexpu-core": { + "version": "6.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/regexpu-core/-/regexpu-core-6.2.0.tgz", + "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.0", + "regjsgen": "^0.8.0", + "regjsparser": "^0.12.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==" + }, + "node_modules/regjsparser": { + "version": "0.12.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/regjsparser/-/regjsparser-0.12.0.tgz", + "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", + "dependencies": { + "jsesc": "~3.0.2" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://repo.huaweicloud.com/repository/npm/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/slash": { + "version": "2.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "optional": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", + "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "engines": { + "node": ">=4" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/util": { + "version": "0.10.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "dependencies": { + "inherits": "2.0.3" + } + }, + "node_modules/util/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + } + } +} diff --git a/build-tools/compile-plugins/api-check-plugin-static/package.json b/build-tools/compile-plugins/api-check-plugin-static/package.json new file mode 100644 index 0000000000..2902bc4588 --- /dev/null +++ b/build-tools/compile-plugins/api-check-plugin-static/package.json @@ -0,0 +1,22 @@ +{ + "name": "api-check-plugin-static", + "version": "1.0.0", + "description": "", + "main": "compile-plugins/api-check-plugin-static/index.ts", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "compile:plugins": "./node_modules/.bin/babel ./ --out-dir ./lib --extensions .ts" + }, + "author": "", + "license": "ISC", + "dependencies": { + "fs": "^0.0.1-security", + "path": "^0.12.7", + "@babel/cli": "7.20.7", + "@babel/core": "7.20.12", + "@babel/plugin-proposal-class-properties": "7.18.6", + "@babel/preset-env": "7.20.2", + "@babel/preset-typescript": "7.18.6", + "@babel/runtime": "7.20.13" + } +} diff --git a/build-tools/compile-plugins/api-check-plugin-static/src/api_check_config.ts b/build-tools/compile-plugins/api-check-plugin-static/src/api_check_config.ts new file mode 100644 index 0000000000..9cf21cd2c5 --- /dev/null +++ b/build-tools/compile-plugins/api-check-plugin-static/src/api_check_config.ts @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2025 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 path from 'path'; +import { + PERMISSION_TAG_CHECK_NAME, + PERMISSION_TAG_CHECK_ERROR, + SYSTEM_API_TAG_CHECK_NAME, + SYSTEM_API_TAG_CHECK_WARNING, + TEST_TAG_CHECK_NAME, + TEST_TAG_CHECK_ERROR, + SYSCAP_TAG_CHECK_NAME, + SYSCAP_TAG_CHECK_WARNING, + FORM_TAG_CHECK_NAME, + FORM_TAG_CHECK_ERROR, + FIND_MODULE_WARNING, + CROSSPLATFORM_TAG_CHECK_NAME, + CROSSPLATFORM_TAG_CHECK_ERROR, + DEPRECATED_TAG_CHECK_NAME, + DEPRECATED_TAG_CHECK_WARNING, + FA_TAG_CHECK_NAME, + FA_TAG_HUMP_CHECK_NAME, + FA_TAG_CHECK_ERROR, + ATOMICSERVICE_BUNDLE_TYPE, + ATOMICSERVICE_TAG_CHECK_NAME, + ATOMICSERVICE_TAG_CHECK_ERROR, + ATOMICSERVICE_TAG_CHECK_VERSION, + SINCE_TAG_NAME, + SINCE_TAG_CHECK_ERROR, + STAGE_TAG_CHECK_NAME, + STAGE_TAG_HUMP_CHECK_NAME, + STAGE_TAG_CHECK_ERROR, + STAGE_COMPILE_MODE +} from '../utils/api_check_plugin_define'; +import { globalObject } from '../index'; +import { + checkPermissionTag, + checkSinceTag, + checkSyscapTag, + getJsDocNodeCheckConfigItem, + isCardFile, + pushLog, + collectInfo +} from '../utils/api_check_plugin_utils'; +import { + ApiCheckWrapperServiceHost, + CurrentAddress, + DiagnosticCategory, + JsDocNodeCheckConfig, + JsDocNodeCheckConfigItem +} from '../api-check-wrapper'; + +const jsDocNodeCheckConfigCache: Map> = + new Map>(); + +/** + * 根据ProjectConfig对象存入JsDoc校验规则 + * + * @param { string } fileName - 原始node文件路径 + * @param { string } sourceFileName - 目标api文件路径 + * @returns { JsDocNodeCheckConfig } - 返回校验规则对象 + */ +function getJsDocNodeCheckConfig(fileName: string, sourceFileName: string): JsDocNodeCheckConfig { + let byFileName: Map | undefined = jsDocNodeCheckConfigCache.get(fileName); + if (byFileName === undefined) { + byFileName = new Map(); + jsDocNodeCheckConfigCache.set(fileName, byFileName); + } + let result: JsDocNodeCheckConfig | undefined = byFileName.get(sourceFileName); + if (result !== undefined) { + return result; + } + // 预留check条件 + let needCheckResult: boolean = true; + const checkConfigArray: JsDocNodeCheckConfigItem[] = []; + const apiName: string = path.basename(fileName); + const sourceBaseName: string = path.basename(sourceFileName); + if (/(?= ATOMICSERVICE_TAG_CHECK_VERSION) { + checkConfigArray.push(getJsDocNodeCheckConfigItem([ATOMICSERVICE_TAG_CHECK_NAME], + ATOMICSERVICE_TAG_CHECK_ERROR, DiagnosticCategory.ERROR, true)); + } + } else { + needCheckResult = false; + } + result = { + nodeNeedCheck: needCheckResult, + checkConfig: checkConfigArray + }; + byFileName.set(sourceFileName, result); + return result; +} + + +/** + * 返回apiHost + * + * @returns { ApiCheckWrapperServiceHost } - apiHost + */ +export function getApiCheckWrapperServiceHost(): ApiCheckWrapperServiceHost { + return { + getJsDocNodeCheckedConfig: (currentFileName: string, symbolSourceFilePath: string) => { + return getJsDocNodeCheckConfig(currentFileName, symbolSourceFilePath); + }, + getFileCheckedModuleInfo: (containFilePath: string) => { + return { + fileNeedCheck: true, + currentFileName: containFilePath + }; + }, + pushLogInfo: (apiName: string, currentFilePath: string, currentAddress: CurrentAddress, + logLevel: DiagnosticCategory, logMessage: string) => { + return pushLog(apiName, currentFilePath, currentAddress, logLevel, logMessage); + }, + collectImportInfo: (moduleName: string[], modulePath: string, currentFilePath: string) => { + collectInfo(moduleName, modulePath, currentFilePath); + } + }; +} \ No newline at end of file diff --git a/build-tools/compile-plugins/api-check-plugin-static/utils/api_check_plugin_define.ts b/build-tools/compile-plugins/api-check-plugin-static/utils/api_check_plugin_define.ts new file mode 100644 index 0000000000..e02607bf6a --- /dev/null +++ b/build-tools/compile-plugins/api-check-plugin-static/utils/api_check_plugin_define.ts @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2025 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. + */ + +export const PERMISSION_TAG_CHECK_NAME: string = 'permission'; +export const PERMISSION_TAG_CHECK_ERROR: string = "To use this API, you need to apply for the permissions: $DT"; +export const SYSTEM_API_TAG_CHECK_NAME: string = 'systemapi'; +export const SYSTEM_API_TAG_CHECK_WARNING: string = "'{0}' is system api"; +export const TEST_TAG_CHECK_NAME: string = 'test'; +export const TEST_TAG_CHECK_ERROR: string = "'{0}' can only be used for testing directories "; +export const SYSCAP_TAG_CHECK_NAME: string = 'syscap'; +export const SYSCAP_TAG_CHECK_WARNING: string = "The system capacity of this api '{0}' is not supported on all devices"; +export const SYSCAP_TAG_CONDITION_CHECK_WARNING: string = + 'The API is not supported on all devices. Use the canIUse condition to determine whether the API is supported.'; +export const CANIUSE_FUNCTION_NAME: string = 'canIUse'; +export const VERSION_CHECK_FUNCTION_NAME: string = 'isApiVersionGreaterOrEqual'; +export const RUNTIME_OS_OH: string = 'OpenHarmony'; +export const FORM_TAG_CHECK_NAME: string = 'form'; +export const FORM_TAG_CHECK_ERROR: string = "'{0}' can't support form application."; +export const CROSSPLATFORM_TAG_CHECK_NAME: string = 'crossplatform'; +export const CROSSPLATFORM_TAG_CHECK_ERROR: string = "'{0}' can't support crossplatform application."; +export const DEPRECATED_TAG_CHECK_NAME: string = 'deprecated'; +export const DEPRECATED_TAG_CHECK_WARNING: string = "'{0}' has been deprecated."; +export const FA_TAG_CHECK_NAME: string = 'famodelonly'; +export const FA_TAG_HUMP_CHECK_NAME: string = 'FAModelOnly'; +export const FA_TAG_CHECK_ERROR: string = 'This API is used only in FA Mode, but the current Mode is Stage.'; +export const STAGE_TAG_CHECK_NAME: string = 'stagemodelonly'; +export const STAGE_TAG_HUMP_CHECK_NAME: string = 'StageModelOnly'; +export const STAGE_TAG_CHECK_ERROR: string = 'This API is used only in Stage Mode, but the current Mode is FA.'; +export const STAGE_COMPILE_MODE: string = 'moduleJson'; +export const ATOMICSERVICE_BUNDLE_TYPE: string = 'atomicService'; +export const ATOMICSERVICE_TAG_CHECK_NAME: string = 'atomicservice'; +export const ATOMICSERVICE_TAG_CHECK_ERROR: string = "'{0}' can't support atomicservice application."; +export const SINCE_TAG_NAME: string = 'since'; +export const SINCE_TAG_CHECK_ERROR: string = + "The '{0}' API is supported since SDK version $SINCE1. However, the current compatible SDK version is $SINCE2."; +export const ATOMICSERVICE_TAG_CHECK_VERSION: number = 11; +export const FIND_MODULE_WARNING: string = "Cannot find name '{0}'."; +export const CONSTANT_STEP_0: number = 0; +export const CONSTANT_STEP_1: number = 1; +export const CONSTANT_STEP_2: number = 2; +export const CONSTANT_STEP_3: number = 3; +export const GLOBAL_DECLARE_WHITE_LIST: Set = new Set(['Context', 'PointerStyle', 'PixelMap', 'UnifiedData', + 'Summary', 'UniformDataType', 'IntentionCode', 'NavDestinationInfo', 'UIContext', 'Resource', 'WebviewController']); +export const MESSAGE_CONFIG_COLOR_RED: string = '\u001b[31m'; +export const MESSAGE_CONFIG_COLOR_RESET: string = '\u001b[39m'; +export const MESSAGE_CONFIG_COLOR_ERROR: string = 'color:#f5a623'; +export const MESSAGE_CONFIG_COLOR_WARNING: string = 'color:#d0021b'; +export const MESSAGE_CONFIG_HEADER_ERROR: string = 'ERROR: ArkTS:ERROR File: '; +export const MESSAGE_CONFIG_HEADER_WARNING: string = 'WARN: ArkTS:WARN File: '; \ No newline at end of file diff --git a/build-tools/compile-plugins/api-check-plugin-static/utils/api_check_plugin_enums.ts b/build-tools/compile-plugins/api-check-plugin-static/utils/api_check_plugin_enums.ts new file mode 100644 index 0000000000..1208ff3c65 --- /dev/null +++ b/build-tools/compile-plugins/api-check-plugin-static/utils/api_check_plugin_enums.ts @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2025 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. + */ + +export enum PermissionValidTokenState { + Init, + LeftParenthesis, + RightParenthesis, + PermissionChar, + And, + Or, +} \ No newline at end of file diff --git a/build-tools/compile-plugins/api-check-plugin-static/utils/api_check_plugin_typedef.ts b/build-tools/compile-plugins/api-check-plugin-static/utils/api_check_plugin_typedef.ts new file mode 100644 index 0000000000..b1a6dbeb97 --- /dev/null +++ b/build-tools/compile-plugins/api-check-plugin-static/utils/api_check_plugin_typedef.ts @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2025 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 { JSDoc, JsDocNodeCheckConfigItem } from "../api-check-wrapper"; +import { PermissionValidTokenState } from "./api_check_plugin_enums"; + +/** + * 定义与显示窗口相关的配置 + */ +export interface WindowConfig { + designWidth: number; + autoDesignWidth: boolean; +} + +/** + * 卡片form_config.json配置 + */ +export interface FormConfig { + name: string; + displayName: string; + description: string; + src: string; // 目标字段 + uiSyntax: string; + window: WindowConfig; + colorMode: string; + isDynamic: boolean; + isDefault: boolean; + updateEnabled: boolean; + scheduledUpdateTime: string; + updateDuration: number; + defaultDimension: string; + supportDimensions: string[]; +} + + +export interface ConfigSchema { + forms: FormConfig[]; +} + +/** + * 工程编译配置 + */ +export interface ProjectConfig extends ApiCheckConfig { + bundleName: string; + moduleName: string; + cachePath: string; + projectRootPath: string; + isCrossplatform: boolean; + ignoreCrossplatformCheck: boolean; + bundleType: string; + compileSdkVersion: number; + compatibleSdkVersion: number; + compileSdkPath: string; + externalApiPaths: string; + buildSdkPath: string; + nativeDependencies: string[]; + aceSoPath: string; + permissions: ConfigPermission; + sdkConfigPaths: string; + projectPath: string; + aceModuleJsonPath: string; + compileMode: string; + aceProfilePath: string; + deviceTypes: string[]; + runtimeOS: string; +} + +export interface ApiCheckConfig { + permissionsArray: string[]; + cardPageSet: string[]; + sdkConfigs: SdkConfig[]; + systemModules: string[]; + allModulesPaths: string[]; + externalSdkPaths: string[]; + sdkConfigPrefix: string; + syscapIntersectionSet: Set; + syscapUnionSet: Set; + deviceTypesMessage: string; + initApiCheckTag: boolean; +} + +export interface CheckValidCallbackInterface { + (jsDocTag: JSDoc[], config: JsDocNodeCheckConfigItem): boolean; +} + +export interface SyscapConfig { + SysCaps: string[] +} + +export interface SdkConfig { + prefix: string; + apiPath: string[]; +} + +export interface GlobalObject { + projectConfig: ProjectConfig +} + +export interface PermissionVaildCalcInfo { + valid: boolean; + currentToken: PermissionValidTokenState; + finish: boolean; + currentPermissionMatch: boolean; +} + +export interface PermissionValidCalcGroup { + subQueue: string[]; + includeParenthesis: boolean; +} + +export interface PermissionModule { + modulePath: string; + testPermissions: string[]; + permissions: string[]; +} + +export interface ConfigPermission { + requestPermissions: Array<{ name: string }>; + definePermissions: Array<{ name: string }>; +} \ No newline at end of file diff --git a/build-tools/compile-plugins/api-check-plugin-static/utils/api_check_plugin_utils.ts b/build-tools/compile-plugins/api-check-plugin-static/utils/api_check_plugin_utils.ts new file mode 100644 index 0000000000..269c3cb979 --- /dev/null +++ b/build-tools/compile-plugins/api-check-plugin-static/utils/api_check_plugin_utils.ts @@ -0,0 +1,992 @@ +/* + * Copyright (c) 2025 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 fs from 'fs'; +import path from 'path'; +import { globalObject, initApiCheckConfig } from '../index'; +import { + CheckValidCallbackInterface, + ConfigPermission, + ConfigSchema, + PermissionValidCalcGroup, + PermissionVaildCalcInfo, + ProjectConfig, + SdkConfig, + SyscapConfig, + ApiCheckConfig +} from './api_check_plugin_typedef'; +import { + MESSAGE_CONFIG_COLOR_ERROR, + MESSAGE_CONFIG_COLOR_RED, + MESSAGE_CONFIG_COLOR_RESET, + MESSAGE_CONFIG_COLOR_WARNING, + MESSAGE_CONFIG_HEADER_ERROR, + MESSAGE_CONFIG_HEADER_WARNING, + PERMISSION_TAG_CHECK_ERROR, + PERMISSION_TAG_CHECK_NAME, + RUNTIME_OS_OH, + SINCE_TAG_CHECK_ERROR, + SINCE_TAG_NAME, + STAGE_COMPILE_MODE, + SYSCAP_TAG_CHECK_NAME +} from './api_check_plugin_define'; +import { + CurrentAddress, + DiagnosticCategory, + JSDoc, + JsDocNodeCheckConfigItem, + JSDocTag +} from '../api-check-wrapper'; +import { PermissionValidTokenState } from './api_check_plugin_enums'; + +/** + * 从 JSON 文件中提取所有 src 字段到数组 + * + * @param { string } filePath JSON 文件的绝对路径 + * @returns { string[] } 包含所有 src 字段的字符串数组 + * @throws 文件不存在、JSON 解析错误或数据结构不符时抛出异常 + */ +export function extractSrcPaths(filePath: string): string[] { + // 1. 验证路径格式和存在性 + if (!path.isAbsolute(filePath)) { + throw new Error(`路径必须是绝对路径: ${filePath}`); + } + + if (!fs.existsSync(filePath)) { + throw new Error(`文件不存在: ${filePath}`); + } + + try { + // 2. 读取并解析 JSON 文件 + const rawData = fs.readFileSync(filePath, 'utf-8'); + const config: ConfigSchema = JSON.parse(rawData); + + // 3. 验证数据结构 + if (!config.forms || !Array.isArray(config.forms)) { + throw new Error('JSON 缺少 forms 数组'); + } + + // 4. 提取所有 src 字段 + const srcPaths: string[] = []; + for (const form of config.forms) { + if (form.src && typeof form.src === 'string') { + let src = form.src.replace(/^\.\/ets/, ''); + srcPaths.push(globalObject.projectConfig?.projectPath + src); + } else { + console.warn(`跳过无效 src 字段的表单项: ${form.name}`); + } + } + + // 5. 返回结果数组 + return srcPaths; + } catch (error) { + // 6. 增强错误信息 + if (error instanceof SyntaxError) { + throw new SyntaxError(`JSON 解析错误: ${error.message}`); + } + throw new Error(`处理失败: ${error instanceof Error ? error.message : String(error)}`); + } +} + +/** + * 判断当前ets文件是否是卡片文件 + * + * @param { string } file 当前ets文件路径 + * @returns { boolean } 是否为卡片文件 + */ +export function isCardFile(file: string): boolean { + if (globalObject.projectConfig.cardPageSet.includes(file)) { + return true; + } + return false; +} + +/** + * 校验since标签,当前api版本是否小于等于compatibleSdkVersion + * + * @param { JSDoc[] } jsDocs 当前api的JSDoc + * @param { JsDocNodeCheckConfigItem } config 当前的since标签校验规则 + * @returns { boolean } 是否报错该since标签 + */ +export function checkSinceTag(jsDocs: JSDoc[], config: JsDocNodeCheckConfigItem): boolean { + if (jsDocs && jsDocs.length > 0) { + const minorJSDocVersion: number = getJSDocMinorVersion(jsDocs); + const compatibleSdkVersion: number = globalObject.projectConfig.compatibleSdkVersion; + if (minorJSDocVersion > compatibleSdkVersion) { + config.message = SINCE_TAG_CHECK_ERROR.replace('$SINCE1', minorJSDocVersion.toString()) + .replace('$SINCE2', compatibleSdkVersion.toString()); + return true; + } + } + return false; +} + +/** + * 获取最小的Since版本号 + * + * @param { JSDoc[] } jsDocs + * @returns { number } + */ +function getJSDocMinorVersion(jsDocs: JSDoc[]): number { + let minorVersion: number = 0; + if (jsDocs && jsDocs.length > 0) { + const jsdoc: JSDoc = jsDocs[0]; + if (jsdoc.tags && jsdoc.tags.length > 0) { + for (let i = 0; i < jsdoc.tags.length; i++) { + const tag: JSDocTag = jsdoc.tags[i]; + if (tag.tag === SINCE_TAG_NAME) { + const currentVersion: number = Number.parseInt(tag.name ?? ''); + if (minorVersion === 0 || + !Number.isNaN(currentVersion) && currentVersion > minorVersion) { + minorVersion = currentVersion; + } + break; + } + } + } + } + return minorVersion; +} + +/** + * 获取最新版本的JSDoc + * + * @param { JSDoc[] } jsDocs + * @returns { JSDoc } + */ +function getCurrentJSDoc(jsDocs: JSDoc[]): JSDoc { + let currentJsDoc: JSDoc = jsDocs[jsDocs.length - 1]; + return currentJsDoc; +} + +/** + * 获取最新版本的JSDoc + * + * @param { JSDoc } jsDoc + * @param { string } tagName + * @returns { JSDocTag | undefined } + */ +function getJSDocTag(jsDoc: JSDoc, tagName: string): JSDocTag | undefined { + const jsDocTag: JSDocTag | undefined = jsDoc.tags.find((item: JSDocTag) => { + return item.tag === tagName; + }); + return jsDocTag; +} + +/** + * STEP1. Parse the permission information configured on the API + * STEP2. Recursive queue to obtain whether the current permission configuration supports it + * + * @param { string } comment jsdoc中comment信息 + * @param { string[] } permissionsArray 应用permission集合 + * @returns { boolean } + */ +function validPermission(comment: string, permissionsArray: string[]): boolean { + const permissionsItem: string[] = getSplitsArrayWithDesignatedCharAndStr(comment ?? '', ' ') + .filter((item) => { + return item !== ''; + }); + const permissionsQueue: string[] = []; + permissionsItem.forEach((item: string) => { + // STEP1.1 Parse'(' + const leftParenthesisItem: string[] = getSplitsArrayWithDesignatedCharAndArrayStr([item], '('); + // STEP1.2 Parse')' + const rightParenthesisItem: string[] = getSplitsArrayWithDesignatedCharAndArrayStr(leftParenthesisItem, ')'); + permissionsQueue.push(...rightParenthesisItem); + }); + // STEP2 + const calcValidResult: PermissionVaildCalcInfo = { + valid: false, + currentToken: PermissionValidTokenState.Init, + finish: false, + currentPermissionMatch: true, + }; + validPermissionRecursion(permissionsQueue, permissionsArray, calcValidResult); + return calcValidResult.valid; +} + +/** + * 检测数组中是否包含括号 + * + * @param { string[] } permissionsQueue + * @param { string[] } permissions + * @param { PermissionVaildCalcInfo } calcValidResult + */ +function validPermissionRecursion(permissionsQueue: string[], permissions: string[], + calcValidResult: PermissionVaildCalcInfo): void { + if (permissionsQueue.some(item => ['(', ')'].includes(item))) { + const groups: PermissionValidCalcGroup[] = groupWithParenthesis(permissionsQueue); + const groupJoin: string[] = getGroupItemPermission(groups, calcValidResult, permissions); + getPermissionVaildAtoms(groupJoin, calcValidResult, permissions ?? []); + } else { + getPermissionVaildAtoms(permissionsQueue, calcValidResult, permissions ?? []); + } +} + +/** + * 分割字符串 + * + * @param { string } permission + * @param { string } designatedChar + * @returns { string[] } + */ +function getSplitsArrayWithDesignatedCharAndStr(permission: string, designatedChar: string): string[] { + return permission.split(designatedChar).map(item => item.trim()); +} + +/** + * 处理Permission项 + * + * @param { PermissionValidCalcGroup[] } groups + * @param { PermissionVaildCalcInfo } calcValidResult + * @param { string[] } permissions + * @returns { string[] } + */ +function getGroupItemPermission( + groups: PermissionValidCalcGroup[], + calcValidResult: PermissionVaildCalcInfo, + permissions: string[]): string[] { + const groupJoin: string[] = []; + groups.forEach((groupItem: PermissionValidCalcGroup) => { + if (groupItem.includeParenthesis) { + const calcValidResultItem: PermissionVaildCalcInfo = { + ...calcValidResult, + }; + const subStack: string[] = groupItem.subQueue.slice(1, groupItem.subQueue.length - 1); + validPermissionRecursion(subStack, permissions, calcValidResultItem); + if (calcValidResultItem.valid) { + groupJoin.push(''); + } else { + groupJoin.push('NA'); + } + } else { + groupJoin.push(...groupItem.subQueue); + } + }); + return groupJoin; +} + +/** + * 使用计数器根据括号分组 + * + * @param { string[] } stack + * @returns { PermissionValidCalcGroup[] } + */ +function groupWithParenthesis(stack: string[]): PermissionValidCalcGroup[] { + let currentLeftParenthesisCount: number = 0; + const groups: PermissionValidCalcGroup[] = []; + let currentGroupItem: PermissionValidCalcGroup = { + subQueue: [], + includeParenthesis: false, + }; + stack.forEach((item: string, index: number) => { + if (item === '(') { + if (currentLeftParenthesisCount === 0) { + groups.push(currentGroupItem); + currentGroupItem = { + subQueue: [item], + includeParenthesis: true + }; + } else { + currentGroupItem.subQueue.push(item); + } + currentLeftParenthesisCount++; + } else if (item === ')') { + currentLeftParenthesisCount--; + currentGroupItem.subQueue.push(item); + if (currentLeftParenthesisCount === 0) { + groups.push(currentGroupItem); + currentGroupItem = { + subQueue: [], + includeParenthesis: false, + }; + } + } else { + currentGroupItem.subQueue.push(item); + if (index === stack.length - 1) { + groups.push(currentGroupItem); + } + } + }); + return groups; +} + +/** + * 深度优先遍历递归处理atomStacks + * + * @param { string[] } atomStacks + * @param { PermissionVaildCalcInfo } calcValidResult + * @param { string[] } configPermissions + * @returns + */ +function getPermissionVaildAtoms(atomStacks: string[], calcValidResult: PermissionVaildCalcInfo, + configPermissions: string[]): void { + if (calcValidResult.finish) { + return; + } + if (atomStacks[0] === 'and') { + calcValidResult.currentToken = PermissionValidTokenState.And; + } else if (atomStacks[0] === 'or') { + calcValidResult.currentToken = PermissionValidTokenState.Or; + } else { + if (calcValidResult.currentToken === PermissionValidTokenState.Or) { + if (inValidOrExpression( + atomStacks, + calcValidResult, + configPermissions + )) { + calcValidResult.currentPermissionMatch = false; + } + } else if (calcValidResult.currentToken === PermissionValidTokenState.And) { + if (inValidAndExpression( + atomStacks, + calcValidResult, + configPermissions + )) { + calcValidResult.currentPermissionMatch = false; + } + } else { + calcValidResult.currentPermissionMatch = + validPermissionItem(atomStacks[0], configPermissions); + } + } + if (atomStacks.length > 1) { + getPermissionVaildAtoms( + atomStacks.slice(1), + calcValidResult, + configPermissions + ); + } else { + calcValidResult.valid = calcValidResult.currentPermissionMatch; + calcValidResult.finish = true; + } +} + +/** + * 处理Or + * + * @param { string[] } atomStacks + * @param { PermissionVaildCalcInfo } calcValidResult + * @param { string[] } configPermissions + * @returns + */ +function inValidOrExpression( + atomStacks: string[], + calcValidResult: PermissionVaildCalcInfo, + configPermissions: string[]): boolean { + if ( + !calcValidResult.currentPermissionMatch && + !validPermissionItem(atomStacks[0], configPermissions) + ) { + calcValidResult.valid = false; + return true; + } + calcValidResult.currentPermissionMatch = true; + return false; +} + +/** + * 处理And + * + * @param { string[] } atomStacks + * @param { PermissionVaildCalcInfo } calcValidResult + * @param { string[] } configPermissions + * @returns + */ +function inValidAndExpression( + atomStacks: string[], + calcValidResult: PermissionVaildCalcInfo, + configPermissions: string[]): boolean { + if ( + !calcValidResult.currentPermissionMatch || + !validPermissionItem(atomStacks[0], configPermissions) + ) { + calcValidResult.valid = false; + return true; + } + calcValidResult.currentPermissionMatch = + validPermissionItem(atomStacks[0], configPermissions); + return false; +} + +/** + * 基础校验PermissionItem + * + * @param { string } atomStackItem + * @param { string[] } configPermissions + * @returns { boolean } + */ +function validPermissionItem(atomStackItem: string, configPermissions: string[]): boolean { + return atomStackItem === '' || configPermissions.includes(atomStackItem); +} + +/** + * 递归分割leftParenthesisItems + * + * @param { string[] } leftParenthesisItems + * @param { string } designatedChar + * @returns { string[] } + */ +function getSplitsArrayWithDesignatedCharAndArrayStr( + leftParenthesisItems: string[], + designatedChar: string +): string[] { + const rightParenthesisItems: string[] = []; + leftParenthesisItems.forEach((leftParenthesisItem: string) => { + if (leftParenthesisItem.includes(designatedChar)) { + const rightParenthesis: string[] = + getSplitsArrayWithDesignatedCharAndStr( + leftParenthesisItem, + designatedChar + ); + rightParenthesis.forEach((item: string) => { + if (item === '') { + rightParenthesisItems.push(designatedChar); + } else { + rightParenthesisItems.push(item); + } + }); + } else { + rightParenthesisItems.push(leftParenthesisItem); + } + }); + return rightParenthesisItems; +} + +/** +* 获取jsDocNodeCheckConfigItem配置项 +* +* @param { string[] } tagName - tag name +* @param { string } message - error message +* @param { DiagnosticCategory } type - error type +* @param { boolean } tagNameShouldExisted - tag is required +* @param { CheckValidCallbackInterface } checkValidCallback +* @returns { JsDocNodeCheckConfigItem } +*/ +export function getJsDocNodeCheckConfigItem(tagName: string[], message: string, type: DiagnosticCategory, + tagNameShouldExisted: boolean, checkValidCallback?: CheckValidCallbackInterface): JsDocNodeCheckConfigItem { + return { + tagName: tagName, + message: message, + type: type, + tagNameShouldExisted: tagNameShouldExisted, + checkValidCallback: checkValidCallback + }; +} + +/** + * 创建/清空工程配置 + * + * @returns { ProjectConfig } + */ +export function createOrCleanProjectConfig(): ProjectConfig { + return { + bundleName: '', + moduleName: '', + cachePath: '', + aceModuleJsonPath: '', + compileMode: '', + permissions: { + requestPermissions: [], + definePermissions: [] + }, + projectRootPath: '', + isCrossplatform: false, + ignoreCrossplatformCheck: false, + bundleType: '', + compileSdkVersion: 0, + compatibleSdkVersion: 0, + projectPath: '', + aceProfilePath: '', + cardPageSet: [], + compileSdkPath: '', + systemModules: [], + allModulesPaths: [], + sdkConfigs: [], + externalApiPaths: '', + externalSdkPaths: [], + sdkConfigPrefix: '', + deviceTypes: [], + deviceTypesMessage: '', + runtimeOS: '', + syscapIntersectionSet: new Set([]), + syscapUnionSet: new Set([]), + permissionsArray: [], + buildSdkPath: '', + nativeDependencies: [], + aceSoPath: '', + sdkConfigPaths: '', + initApiCheckTag: true + }; +} + +/** + * 初始化组装projectConfig所需对象 + * + * @returns { ApiCheckConfig } + */ +export function creatApiCheckConfig(): ApiCheckConfig { + return { + cardPageSet: [], + systemModules: [], + allModulesPaths: [], + sdkConfigs: [], + externalSdkPaths: [], + sdkConfigPrefix: '', + deviceTypesMessage: '', + syscapIntersectionSet: new Set([]), + syscapUnionSet: new Set([]), + permissionsArray: [], + initApiCheckTag: true + } +} + +/** + * 获取PermissionsArray字段 + * + * @param { ProjectConfig } projectConfig + * @returns + */ +export function readPermissions(projectConfig: ProjectConfig): void { + if (!projectConfig) { + return; + } + const permissions: ConfigPermission = projectConfig.permissions; + const requestPermissions: string[] = permissions.requestPermissions + ? getPermissionFromConfig(permissions.requestPermissions) + : []; + + const definePermissions: string[] = permissions.definePermissions + ? getPermissionFromConfig(permissions.definePermissions) + : []; + + const permissionsArray: string[] = [ + ...requestPermissions, + ...definePermissions + ]; + projectConfig.permissionsArray = permissionsArray; +} + +/** + * 获取PermissionFrom + * + * @param { Array<{ name: string }> } array + * @returns { string[] } + */ +function getPermissionFromConfig(array: Array<{ name: string }>): string[] { + return array.map((item: { name: string }) => { + return String(item.name); + }); +} + +/** + * 获取卡片相关字段 + * + * @param { ProjectConfig } projectConfig + */ +export function readCardPageSet(projectConfig: ProjectConfig): void { + if (projectConfig.aceModuleJsonPath && fs.existsSync(projectConfig.aceModuleJsonPath)) { + projectConfig.compileMode = STAGE_COMPILE_MODE; + const moduleJson: any = JSON.parse(fs.readFileSync(projectConfig.aceModuleJsonPath).toString()); + const extensionAbilities: any = moduleJson?.module?.extensionAbilities; + if (extensionAbilities && extensionAbilities.length > 0) { + setCardPages(extensionAbilities, projectConfig); + } + } +} + +/** + * 获取卡片相关字段 + * + * @param { any } extensionAbilities + * @param { ProjectConfig } projectConfig + */ +function setCardPages(extensionAbilities: any, projectConfig: ProjectConfig): void { + if (extensionAbilities && extensionAbilities.length > 0) { + extensionAbilities.forEach((extensionAbility: any) => { + if (extensionAbility.type === 'form' && extensionAbility.metadata) { + extensionAbility.metadata.forEach((metadata: any) => { + if (metadata.resource) { + readCardResource(metadata.resource, projectConfig); + } + }); + } + }); + } +} + +/** + * 获取卡片资源字段 + * + * @param { string } resource + * @param { ProjectConfig } projectConfig + */ +function readCardResource(resource: string, projectConfig: ProjectConfig): void { + const cardJsonFileName: string = `${resource.replace(/\$profile\:/, '')}.json`; + const modulePagePath: string = path.resolve(projectConfig.aceProfilePath, cardJsonFileName); + if (fs.existsSync(modulePagePath)) { + const cardConfig: any = JSON.parse(fs.readFileSync(modulePagePath, 'utf-8')); + if (cardConfig.forms) { + cardConfig.forms.forEach((form: any) => { + if ((form.type && form.type === 'eTS') || (form.uiSyntax && form.uiSyntax === 'arkts')) { + const cardPath = path.resolve(projectConfig.projectPath, '..', form.src); + if (cardPath && fs.existsSync(cardPath) && !projectConfig.cardPageSet.includes(cardPath)) { + projectConfig.cardPageSet.push(cardPath); + } + } + }); + } + } +} + +/** + * 获取SystemModules字段 + * + * @param { ProjectConfig } projectConfig + */ +export function readSystemModules(projectConfig: ProjectConfig): void { + const apiDirPath = path.resolve(projectConfig.buildSdkPath, './api'); + const arktsDirPath = path.resolve(projectConfig.buildSdkPath, './arkts'); + const kitsDirPath = path.resolve(projectConfig.buildSdkPath, './kits'); + const systemModulePathArray = [apiDirPath, arktsDirPath, kitsDirPath]; + + systemModulePathArray.forEach(systemModulesPath => { + if (fs.existsSync(systemModulesPath) && projectConfig) { + const modulePaths: string[] = []; + readFile(systemModulesPath, modulePaths); + projectConfig.systemModules.push(...fs.readdirSync(systemModulesPath)); + modulePaths.filter(filePath => { + const dirName = path.dirname(filePath); + return !(dirName === apiDirPath || dirName === arktsDirPath || dirName === kitsDirPath); + }).map((filePath: string) => { + return filePath + .replace(apiDirPath, '') + .replace(arktsDirPath, '') + .replace(kitsDirPath, '') + .replace(/(^\\)|(.d.e?ts$)/g, '') + .replace(/\\/g, '/'); + }); + projectConfig.allModulesPaths.push(...modulePaths); + } + }); + const defaultSdkConfigs: SdkConfig[] = [ + { + 'apiPath': systemModulePathArray, + 'prefix': '@ohos' + }, { + 'apiPath': systemModulePathArray, + 'prefix': '@system' + }, { + 'apiPath': systemModulePathArray, + 'prefix': '@arkts' + } + ]; + const externalApiPathStr = projectConfig.sdkConfigPaths || ''; + const externalApiPaths = externalApiPathStr.split(path.delimiter); + projectConfig.externalSdkPaths = [...externalApiPaths]; + const extendSdkConfigs: SdkConfig[] = []; + collectExternalModules(externalApiPaths, extendSdkConfigs, projectConfig); + projectConfig.sdkConfigs = [...defaultSdkConfigs, ...extendSdkConfigs]; +} + +function collectExternalModules(sdkPaths: string[], extendSdkConfigs: SdkConfig[], projectConfig: ProjectConfig): void { + for (let i = 0; i < sdkPaths.length; i++) { + const sdkPath = sdkPaths[i]; + const sdkConfigPath = path.resolve(sdkPath, 'sdkConfig.json'); + if (!fs.existsSync(sdkConfigPath)) { + continue; + } + const sdkConfig: SdkConfig = JSON.parse(fs.readFileSync(sdkConfigPath, 'utf-8')); + if (!sdkConfig.apiPath) { + continue; + } + let externalApiPathArray: string[] = []; + if (Array.isArray(sdkConfig.apiPath)) { + externalApiPathArray = sdkConfig.apiPath; + } else { + externalApiPathArray.push(sdkConfig.apiPath); + } + const resolveApiPathArray: string[] = []; + externalApiPathArray.forEach((element: string) => { + const resolvePath: string = path.resolve(sdkPath, element); + resolveApiPathArray.push(resolvePath); + if (fs.existsSync(resolvePath) && projectConfig) { + const extrenalModulePaths: string[] = []; + projectConfig.systemModules.push(...fs.readdirSync(resolvePath)); + readFile(resolvePath, extrenalModulePaths); + projectConfig.allModulesPaths.push(...extrenalModulePaths); + } + }); + projectConfig.sdkConfigPrefix += `|${sdkConfig.prefix.replace(/^@/, '')}`; + sdkConfig.apiPath = resolveApiPathArray; + extendSdkConfigs.push(sdkConfig); + } +} + +/** + * 收集并计算Syscap的交集与并集 + * + * @param { ProjectConfig } projectConfig + */ +export function readSyscapInfo(projectConfig: ProjectConfig): void { + projectConfig.deviceTypesMessage = projectConfig.deviceTypes.join(','); + const deviceDir: string = path.resolve(__dirname, '../../../../../api/device-define/'); + const deviceInfoMap: Map = new Map(); + const syscaps: Array = []; + let allSyscaps: string[] = []; + projectConfig.deviceTypes.forEach((deviceType: string) => { + collectOhSyscapInfos(deviceType, deviceDir, deviceInfoMap); + }); + if (projectConfig.runtimeOS !== RUNTIME_OS_OH) { + collectExternalSyscapInfos(projectConfig.externalSdkPaths, projectConfig.deviceTypes, + deviceInfoMap); + } + deviceInfoMap.forEach((value: string[]) => { + syscaps.push(value); + allSyscaps = allSyscaps.concat(value); + }); + const intersectNoRepeatTwice = (arrs: Array) => { + return arrs.reduce(function (prev: string[], cur: string[]) { + return Array.from(new Set(cur.filter((item: string) => { + return prev.includes(item); + }))); + }); + }; + let syscapIntersection: string[] = []; + if (projectConfig.deviceTypes.length === 1 || syscaps.length === 1) { + syscapIntersection = syscaps[0]; + } else if (syscaps.length > 1) { + syscapIntersection = intersectNoRepeatTwice(syscaps); + } + projectConfig.syscapIntersectionSet = new Set(syscapIntersection); + projectConfig.syscapUnionSet = new Set(allSyscaps); +} + +/** + * 收集OH Syscap + * + * @param { string } deviceType + * @param { string } deviceDir + * @param { Map } deviceInfoMap + */ +function collectOhSyscapInfos(deviceType: string, deviceDir: string, deviceInfoMap: Map) { + let syscapFilePath: string = ''; + if (deviceType === 'phone') { + syscapFilePath = path.resolve(deviceDir, 'default.json'); + } else { + syscapFilePath = path.resolve(deviceDir, deviceType + '.json'); + } + if (fs.existsSync(syscapFilePath)) { + const content: SyscapConfig = JSON.parse(fs.readFileSync(syscapFilePath, 'utf-8')); + if (deviceInfoMap.get(deviceType)) { + deviceInfoMap.set(deviceType, (deviceInfoMap.get(deviceType) as string[]).concat(content.SysCaps)); + } else { + deviceInfoMap.set(deviceType, content.SysCaps); + } + } +} + +/** + * 收集额外Syscap + * + * @param { string[] } externalApiPaths + * @param { string[] } deviceTypes + * @param { Map }deviceInfoMap + */ +function collectExternalSyscapInfos( + externalApiPaths: string[], + deviceTypes: string[], + deviceInfoMap: Map +) { + const externalDeviceDirs: string[] = []; + externalApiPaths.forEach((externalApiPath: string) => { + const externalDeviceDir: string = path.resolve(externalApiPath, './api/device-define'); + if (fs.existsSync(externalDeviceDir)) { + externalDeviceDirs.push(externalDeviceDir); + } + }); + externalDeviceDirs.forEach((externalDeviceDir: string) => { + deviceTypes.forEach((deviceType: string) => { + let syscapFilePath: string = ''; + const files: string[] = fs.readdirSync(externalDeviceDir); + files.forEach((fileName: string) => { + if (fileName.startsWith(deviceType)) { + syscapFilePath = path.resolve(externalDeviceDir, fileName); + if (fs.existsSync(syscapFilePath)) { + const content: SyscapConfig = JSON.parse(fs.readFileSync(syscapFilePath, 'utf-8')); + if (deviceInfoMap.get(deviceType)) { + deviceInfoMap.set(deviceType, (deviceInfoMap.get(deviceType) as string[]).concat(content.SysCaps)); + } else { + deviceInfoMap.set(deviceType, content.SysCaps); + } + } + } + }); + }); + }); +} + +/** + * 递归读取目录下所有文件路径 + * + * @param { string } dir + * @param { string[] } utFiles + */ +export function readFile(dir: string, utFiles: string[]): void { + try { + const files: string[] = fs.readdirSync(dir); + files.forEach((element) => { + const filePath: string = path.join(dir, element); + const status: fs.Stats = fs.statSync(filePath); + if (status.isDirectory()) { + readFile(filePath, utFiles); + } else { + utFiles.push(filePath); + } + }); + } catch (e) { + console.error(MESSAGE_CONFIG_COLOR_RED, 'ArkTS ERROR: ' + e, MESSAGE_CONFIG_COLOR_RESET); + } +} + +/** +* 确认是否校验permission +* +* @param { JSDoc[] } jsDocs +* @param { JsDocNodeCheckConfigItem } config +* @returns { boolean } +*/ +export function checkPermissionTag(jsDocs: JSDoc[], config: JsDocNodeCheckConfigItem): boolean { + const currentJSDoc: JSDoc = getCurrentJSDoc(jsDocs); + const jsDocTag: JSDocTag | undefined = getJSDocTag(currentJSDoc, PERMISSION_TAG_CHECK_NAME); + if (!jsDocTag) { + return false; + } + const permissionExpression: string = jsDocTag.comment ?? ''; + config.message = PERMISSION_TAG_CHECK_ERROR.replace('$DT', permissionExpression); + return permissionExpression !== '' && + !validPermission(permissionExpression, globalObject.projectConfig.permissionsArray); +} + +/** + * 确定是否检查syscap + * + * @param { JSDoc[] } jsDocs + * @param { JsDocNodeCheckConfigItem } config + * @returns { boolean } + */ +export function checkSyscapTag(jsDocs: JSDoc[], config: JsDocNodeCheckConfigItem): boolean { + let currentSyscapValue: string = ''; + if (jsDocs && jsDocs.length > 0) { + const jsDoc: JSDoc = getCurrentJSDoc(jsDocs); + for (let i = 0; i < jsDoc.tags.length; i++) { + const jsDocTag: JSDocTag = jsDoc.tags[i]; + if (jsDocTag && jsDocTag.tag === SYSCAP_TAG_CHECK_NAME) { + currentSyscapValue = jsDocTag.name ?? ''; + break; + } + } + } + return globalObject.projectConfig.syscapIntersectionSet && + !globalObject.projectConfig.syscapIntersectionSet.has(currentSyscapValue); +} + +/** + * 组装打印信息 + * + * @param { string } apiName + * @param { string } currentFilePath + * @param { CurrentAddress } currentAddress + * @param { DiagnosticCategory } logLevel + * @param { string } logMessage + */ +export function pushLog(apiName: string, currentFilePath: string, currentAddress: CurrentAddress, + logLevel: DiagnosticCategory, logMessage: string) { + // 组装文件全路径 + const fileFullPath: string = currentFilePath + `(${currentAddress.line}:${currentAddress.column}).`; + // 替换api名称 + logMessage = logMessage.replace('{0}', apiName); + // 打印日志信息 + printMessage(fileFullPath, logMessage, logLevel); +} + +/** + * 日志打印 + * + * @param { string } fileInfo + * @param { string } message + * @param { DiagnosticCategory } level + */ +function printMessage(fileInfo: string, message: string, level: DiagnosticCategory) { + let messageHead: string = MESSAGE_CONFIG_HEADER_WARNING; + let messageColor: string = MESSAGE_CONFIG_COLOR_WARNING; + if (level === DiagnosticCategory.ERROR) { + messageHead = MESSAGE_CONFIG_HEADER_ERROR; + messageColor = MESSAGE_CONFIG_COLOR_ERROR; + } + // TODO: 待工具链日志输出方式确认后同步适配 + console.info(`%c${messageHead}${fileInfo}\n ${message}`, messageColor); +} + +/** + * 收集so模块依赖 + * + * @param { string[] } moduleName + * @param { string } modulePath + * @param { string } currentFilePath + */ +export function collectInfo(moduleName: string[], modulePath: string, currentFilePath: string) { + // 收集so模块依赖 + if (/lib(\S+)\.so/g.test(modulePath) && !globalObject.projectConfig.nativeDependencies.includes(currentFilePath)) { + globalObject.projectConfig.nativeDependencies.push(currentFilePath); + } +} + +/** + * 写入预览文件 + * + * @param { string[] } useOSFiles + */ +export function writeUseOSFiles(useOSFiles: string[]): void { + let info: string = useOSFiles.join('\n'); + if (!fs.existsSync(globalObject.projectConfig.aceSoPath)) { + const parent: string = path.resolve(globalObject.projectConfig.aceSoPath, '..'); + if (!(fs.existsSync(parent) && !fs.statSync(parent).isFile())) { + mkDir(parent); + } + } else { + const currentUseOSFiles: string[] = fs.readFileSync(globalObject.projectConfig.aceSoPath, 'utf-8').split('\n'); + useOSFiles.forEach((filePath: string) => { + if (!currentUseOSFiles.includes(filePath)) { + currentUseOSFiles.push(filePath); + } + }); + info = currentUseOSFiles.join('\n'); + } + fs.writeFileSync(globalObject.projectConfig.aceSoPath, info); +} + +/** + * 根据路径创建文件 + * + * @param { string } path_ + */ +function mkDir(path_: string): void { + const parent: string = path.join(path_, '..'); + if (!(fs.existsSync(parent) && !fs.statSync(parent).isFile())) { + mkDir(parent); + } + fs.mkdirSync(path_); +} \ No newline at end of file diff --git a/build-tools/package.json b/build-tools/package.json index a28fb3e7d7..848187334f 100644 --- a/build-tools/package.json +++ b/build-tools/package.json @@ -5,7 +5,7 @@ "main": "delete_systemapi_plugin.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "postinstall": "cd arkui_transformer && npm install" + "postinstall": "cd arkui_transformer && npm install && cd ../compile-plugins/api-check-plugin-static && npm install" }, "author": "", "license": "ISC", diff --git a/build_api_check_plugin.py b/build_api_check_plugin.py new file mode 100755 index 0000000000..4f833e5984 --- /dev/null +++ b/build_api_check_plugin.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 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 argparse +import os +import shutil +import subprocess +import sys +import tarfile + + +def copy_files(source_path, dest_path, is_file=False): + try: + if is_file: + os.makedirs(os.path.dirname(dest_path), exist_ok=True) + shutil.copy(source_path, dest_path) + else: + shutil.copytree(source_path, dest_path, dirs_exist_ok=True, + symlinks=True) + except Exception as err: + raise Exception("Copy files failed. Error: " + str(err)) from err + + +def run_cmd(cmd, execution_path=None): + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, + stdin=subprocess.PIPE, + stderr=subprocess.PIPE, + cwd=execution_path) + stdout, stderr = proc.communicate(timeout=1000) + if proc.returncode != 0: + raise Exception(stderr.decode()) + + +def build(options): + build_cmd = [options.npm, 'run', 'compile:plugins'] + run_cmd(build_cmd, options.source_path) + + +def copy_output(options): + copy_files(os.path.join(options.source_path, './lib'), + os.path.join(options.output_path, 'api-check-plugin')) + + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument('--npm', help='path to a npm exetuable') + parser.add_argument('--source_path', help='path to api_check_plugin source') + parser.add_argument('--output_path', help='path to output') + + options = parser.parse_args() + return options + + +def main(): + options = parse_args() + + build(options) + copy_output(options) + + +if __name__ == '__main__': + sys.exit(main()) \ No newline at end of file -- Gitee