diff --git a/README.md b/README.md new file mode 100644 index 0000000000000000000000000000000000000000..5d54051798a1f0fc1515c6cc1ae058af7243f7b3 --- /dev/null +++ b/README.md @@ -0,0 +1,19 @@ +# assist_tools + +#### Description +This warehouse is used to incubate the assist tools of openharmony system, so that developers can improve development efficiency.Currently NAPI framework code generation tool has been implemented, and the bootanimation tool is being planned.Other similar tools can be incubated in this warehouse. + +#### Directory Structure +``` +/assist_tools/ +├── napi_tool # NAPI framework code generation tool +│ ├── doc # Current capability and version planning +│ ├── image # image resource +│ ├── output # Executable program and plug-in program corresponding to the tool +│ ├── code # Source code of tool +│ └── README # Instructions of tool +└──README +``` + +#### Repositories Involved +no diff --git a/README_ZH.md b/README_ZH.md new file mode 100644 index 0000000000000000000000000000000000000000..f03d6200726ba0015577e677ea26b00667ca5919 --- /dev/null +++ b/README_ZH.md @@ -0,0 +1,23 @@ +# assist_tools + +#### 仓名 + assist_tools +#### 简介 +此仓用于孵化OpenHarmony系统的辅助工具,以便开发者提升开发效率。当前已实现的工具有NAPI框架代码生成工具、正在规划的工具是开机动画生成工具,后续其他类似工具均可在此仓孵化。 + +#### 目录 +``` +/assist_tools/ +├── napi_tool # NAPI框架代码生成工具 +│ ├── doc # 工具当前能力、版本规划 +│ ├── image # 图片资源文件 +│ ├── output # 工具对应的可执行程序与插件程序 +│ ├── code # 工具源码 +│ └── README # 工具使用指导 +└──README +``` + +#### 相关仓 +无 + + diff --git a/napi_tool/LICENSE b/napi_tool/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..29f81d812f3e768fa89638d1f72920dbfd1413a8 --- /dev/null +++ b/napi_tool/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/napi_tool/README_ZH.md b/napi_tool/README_ZH.md new file mode 100644 index 0000000000000000000000000000000000000000..7ed1d60d938e272c667f684515e20651ca6866af --- /dev/null +++ b/napi_tool/README_ZH.md @@ -0,0 +1,103 @@ +# napi_tool + +#### 介绍 +NAPI框架代码生成工具,根据用户指定的路径下的ts接口文件可以一键生成NAPI框架代码、业务代码框架、GN文件等,这样框架层开发者无需关注Nodejs相关语法,C++与JS之间的接口类型转换、数据类型转换等,只需关注业务实现逻辑即可,从而可以大大提高开发效率。目前工具支持命令行、VScode插件两种入口。 + +#### 软件架构 +![](image/frm.png) + +#### 目录 + +``` +├── napi_tool # NAPI框架代码生成工具 +│ ├── doc # 工具当前能力、版本规划 +│ ├── image # 图片资源文件 +│ ├── output # 工具对应的可执行程序与插件程序 +│ ├── code # 工具源码 +│ └── README # 工具使用指导 +└──README +``` + +#### 安装教程 + +1. 将output目录下Windows可执行程序cmd_gen-win.exe拷贝到对应目录下,不需要安装,可以在cmd命令行中直接运行。 +2. 将output目录下Linux可执行程序cmd_gen-linux拷贝到对应目录下,可以在终端下直接运行。 + +#### 使用说明 + +##### 可执行程序使用方法 + +###### Windows + + 1) 将要转换的.d.ts文件放到任意目录下,建议放到可执行程序cmd_gen-win.exe同级目录下,例如: + + ![](image/image-20220106103805904.png) + + 2) 右键windows开始菜单,点击运行,输入cmd,点击确定。 + + ![](image/image-20220106104037879.png) + +3) 在命令行中进入到之前可执行程序cmd_gen-win.exe所在的目录,并运行cmd_gen-win.exe,在cmd_gen-win.exe后面要对应的.d.ts文件名,例如: + +![](image/image-20220106105707675.png) + +4) 运行成功后会在.d.ts文件说在的目录下生成对应的文件,例如: + + ![](image/image-20220106110113948.png) + +###### Linux + +1) 将要转换的.d.ts文件放到任意目录下,建议放到可执行程序cmd_gen-linux同级目录下,例如: + + ![](image/image-20220106111154843.png) + +2) 在终端中进入到之前可执行程序cmd_gen-linux所在的目录,并运行cmd_gen-linux,在cmd_gen-linux后面要对应的.d.ts文件名,例如: + + ![](image/image-20220106111753702.png) + +3) 运行成功后会在.d.ts文件说在的目录下生成对应的文件,例如: + + ![](image/image-20220106111909233.png) + +###### Mac + 方法步骤参考windows、Linux的使用方法 + +##### 插件使用方法 +###### 说明 + visual studio code 版本需1.62.0及以上 + +###### 步骤 + +1) 打开vscode,在左侧边栏中选择插件安装。 + + ![](image/image-20220106145345449.png) + +2) 点击上面三个点的按钮,选择从VSIX安装选项,然后选择刚才生成的gnapi-0.0.1.vsix插件文件,再点击安装。 + + ![](image/image-20220106145540860.png) + +3) 安装完成后就会在vscode的插件管理器中能看到gnapi这个插件了。 + + ![](image/image-20220106150434168.png) + +4) 在vscode中找到需要转换的.d.ts文件,例如: + + ![](image/image-20220106151044789.png) + +5) 鼠标在.d.ts上点击右键,选择.d.ts生成c++选项。 + + ![](image/image-20220106151204896.png) + +6) 之后就会在该目录下生成对应文件,例如: + + ![](image/image-20220106151510092.png) + +注:以上插件使用示例为windows的,linux、mac的使用方法类似。 + +#### 参与贡献 + +1. Fork 本仓库 +2. 新建开发分支 +3. 提交代码 +4. 新建 Pull Request + diff --git a/napi_tool/code/README_ZH.md b/napi_tool/code/README_ZH.md new file mode 100644 index 0000000000000000000000000000000000000000..ae7dbeb9534f679bfa0b80bce9f6c3580625f391 --- /dev/null +++ b/napi_tool/code/README_ZH.md @@ -0,0 +1,38 @@ +# napi_tool_code + +#### 介绍 +此目录为NAPI框架代码生成工具对应的源码,开发者可基于此代码进行二次开发。 + +#### 目录 +``` +/napi_tool/code +├── tool_code # 工具源码 +│ ├── gen +│ | |── analyze # 解析器 +│ │ |── extend # 扩展模块,包括gn文件生成、linux环境适配代码等 +│ │ |── generate # 生成器 +│ │ └── tools # 公共模块代码,包括消息体校验、文件读写、正则表达式转换等 +│ └── test # 插件测试用例 +└──ts_test # 工具需要的ts文件样例 +``` + +#### 说明 +##### 可执行文件开发说明 +1.安装pkg : 执行命令sudo npm i -g pkg + +2.打包三个版本 : 执行命令pkg vscode_plugin/gnapi/gen/cmd_gen.js + +执行以上步骤后,即可在gen目录下生成Windows、linux、mac系统下的可执行程序。 + +##### 插件开发说明 +1. 安装yo : 执行命令npm install -g yo generator-code。 + +2. 使用yo : 执行命令yo code,gnapi是使用yo code生成的插件代码框架,其中gnapi/gen目录下是我们开发的自动化生成napi程序的源代码。 + + ![](image/image-20220106161201896.png) + +3. 在napi_generator/vscode_plugin/gnapi这个目录中执行命令npm i vsce。 + +4. 执行命令./node_modules/vsce/vsce package命令,最终会打包生成一个插件gnapi-0.0.1.vsix。 + + ![](image/image-20220106162517246.png) \ No newline at end of file diff --git a/napi_tool/code/image/image-20220106161201896.png b/napi_tool/code/image/image-20220106161201896.png new file mode 100644 index 0000000000000000000000000000000000000000..80a39816e50bd07c2d6cb1854c3185c0cff21b5f Binary files /dev/null and b/napi_tool/code/image/image-20220106161201896.png differ diff --git a/napi_tool/code/image/image-20220106162517246.png b/napi_tool/code/image/image-20220106162517246.png new file mode 100644 index 0000000000000000000000000000000000000000..0d732af7f99f3671c9792c6e83c23a08f6bbaa7e Binary files /dev/null and b/napi_tool/code/image/image-20220106162517246.png differ diff --git a/napi_tool/code/tool_code/.eslintrc.json b/napi_tool/code/tool_code/.eslintrc.json new file mode 100644 index 0000000000000000000000000000000000000000..d25565bb97aa415ae7970c49a8e5a3bc6a56d37e --- /dev/null +++ b/napi_tool/code/tool_code/.eslintrc.json @@ -0,0 +1,25 @@ +{ + "env": { + "browser": false, + "commonjs": true, + "es6": true, + "node": true, + "mocha": true + }, + "parserOptions": { + "ecmaVersion": 2018, + "ecmaFeatures": { + "jsx": true + }, + "sourceType": "module" + }, + "rules": { + "no-const-assign": "warn", + "no-this-before-super": "warn", + "no-undef": "warn", + "no-unreachable": "warn", + "no-unused-vars": "warn", + "constructor-super": "warn", + "valid-typeof": "warn" + } +} diff --git a/napi_tool/code/tool_code/.gitignore b/napi_tool/code/tool_code/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..71e387d4682d92977e11fdef63c25cc635347594 --- /dev/null +++ b/napi_tool/code/tool_code/.gitignore @@ -0,0 +1,4 @@ +dist +.vscode-test/ +*.vsix +node_modules \ No newline at end of file diff --git a/napi_tool/code/tool_code/.vscode/extensions.json b/napi_tool/code/tool_code/.vscode/extensions.json new file mode 100644 index 0000000000000000000000000000000000000000..09152020b23a10bb45e7007ecfb0ffb6a0e7167d --- /dev/null +++ b/napi_tool/code/tool_code/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the extensions.json format + "recommendations": [ + "dbaeumer.vscode-eslint" + ] +} \ No newline at end of file diff --git a/napi_tool/code/tool_code/.vscode/launch.json b/napi_tool/code/tool_code/.vscode/launch.json new file mode 100644 index 0000000000000000000000000000000000000000..c774552166e359833190cbad454570846918db7e --- /dev/null +++ b/napi_tool/code/tool_code/.vscode/launch.json @@ -0,0 +1,26 @@ +// A launch configuration that launches the extension inside a new window +// Use IntelliSense to learn about possible attributes. +// Hover to view descriptions of existing attributes. +// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Run Extension", + "type": "extensionHost", + "request": "launch", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder}" + ] + }, + { + "name": "Extension Tests", + "type": "extensionHost", + "request": "launch", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder}", + "--extensionTestsPath=${workspaceFolder}/test/suite/index" + ] + } + ] +} diff --git a/napi_tool/code/tool_code/.vscode/settings.json b/napi_tool/code/tool_code/.vscode/settings.json new file mode 100644 index 0000000000000000000000000000000000000000..8e4063b09c466fd5e8fde8b341f2e48d6ca19635 --- /dev/null +++ b/napi_tool/code/tool_code/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "editor.fontSize": 20 +} \ No newline at end of file diff --git a/napi_tool/code/tool_code/.vscodeignore b/napi_tool/code/tool_code/.vscodeignore new file mode 100644 index 0000000000000000000000000000000000000000..a775644108e0c564f36e57e412c1d02d7cbf57db --- /dev/null +++ b/napi_tool/code/tool_code/.vscodeignore @@ -0,0 +1,9 @@ +.vscode/** +.vscode-test/** +test/** +.gitignore +.yarnrc +vsc-extension-quickstart.md +**/jsconfig.json +**/*.map +**/.eslintrc.json diff --git a/napi_tool/code/tool_code/CHANGELOG.md b/napi_tool/code/tool_code/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..5b631eac1593fe76ca57eeaa4859c6cf642662ea --- /dev/null +++ b/napi_tool/code/tool_code/CHANGELOG.md @@ -0,0 +1,9 @@ +# Change Log + +All notable changes to the "gnapi" extension will be documented in this file. + +Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. + +## [Unreleased] + +- Initial release \ No newline at end of file diff --git a/napi_tool/code/tool_code/README.md b/napi_tool/code/tool_code/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a81a3a29d3c7cfc7eae4b7327b5b10a828e598bb --- /dev/null +++ b/napi_tool/code/tool_code/README.md @@ -0,0 +1,5 @@ +# gnapi README + +1,右键点击@ohos.xxxx.d.ts文件 + +2,点击菜单[.d.ts生成c++] diff --git a/napi_tool/code/tool_code/extension.js b/napi_tool/code/tool_code/extension.js new file mode 100644 index 0000000000000000000000000000000000000000..dc3de761047bd4ee48b05036115e74041694c86c --- /dev/null +++ b/napi_tool/code/tool_code/extension.js @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2021 Shenzhen Kaihong Digital Industry Development 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. +*/ + +// The module 'vscode' contains the VS Code extensibility API +// Import the module and reference it with the alias vscode in your code below +const vscode = require('vscode'); +const xgen = require('./gen/main'); +// const memfs=require("./gen/memfs/fileSystemProvider") +// this method is called when your extension is activated +// your extension is activated the very first time the command is executed + +/** + * @param {vscode.ExtensionContext} context + */ +function activate(context) { + + // Use the console to output diagnostic information (console.log) and errors (console.error) + // This line of code will only be executed once when your extension is activated + console.log('Congratulations, your extension "gnapi" is now active!'); + + let disposable = vscode.commands.registerCommand('generate_napi', function (uri) { + // The code you place here will be executed every time your command is executed + // Display a message box to the user + vscode.window.showInformationMessage("正在生成"+uri.fsPath); + xgen.DoGenerate(uri.fsPath); + vscode.window.showInformationMessage("生成成功"); + }); + + context.subscriptions.push(disposable); +} + +// this method is called when your extension is deactivated +function deactivate() {} + +module.exports = { + activate, + deactivate +} diff --git a/napi_tool/code/tool_code/gen/analyze.js b/napi_tool/code/tool_code/gen/analyze.js new file mode 100644 index 0000000000000000000000000000000000000000..4a912ebaa736e93a02ae5df53c46e8a4f64c7fcc --- /dev/null +++ b/napi_tool/code/tool_code/gen/analyze.js @@ -0,0 +1,147 @@ +/* +* Copyright (c) 2021 Shenzhen Kaihong Digital Industry Development 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 re = require("./tools/re"); +const { print, RemoveExplains, RemoveEmptyLine, CheckOutBody } = require("./tools/tool"); +const { FuncType, NumberIncrease } = require("./tools/common"); +const { ReadFile } = require("./tools/FileRW"); + +const { AnalyzeNamespace } = require("./analyze/namespace"); + +function AnalyzeFile(fn) { + NumberIncrease.Reset(); + let data = ReadFile(fn); + // print("[",fn,"]") + data = RemoveExplains(data)//去除注释 + data = RemoveEmptyLine(data)//去除空行 + while (true) {//去除import + let tt = re.search("import ([{}A-Za-z ,]+) from [\"']{1}([@./a-zA-Z]+)[\"']{1};*", data); + if (tt != null) data = re.remove_reg(data, tt.regs[0]); + else break; + } + let result = { + export_default: [], + exports: [], + // declare_enum: [], + // declare_const: [], + declare_type: [], + declare_function: [], + declare_namespace: [], + declare_interface: [], + } + while (true) { + let old_data = data + data = RemoveEmptyLine(data) + + let tt = re.match(" *\n*", data) + if (tt && tt.regs[0][1] == data.length) break//只剩下空格和回车时,解析完成 + + tt = re.match("export default ([a-zA-Z]+);", data); + if (tt != null) { + let export_name = re.get_reg(data, tt.regs[1]) + data = re.remove_reg(data, tt.regs[0]); + result.export_default.push(export_name) + continue; + } + + tt = re.match("(export )*type ([a-zA-Z]+) = ([()a-zA-Z :=>,\"| ]+);", data) + if (tt) { + let export_name = re.get_reg(data, tt.regs[2]) + let export_body = re.get_reg(data, tt.regs[3]) + data = re.remove_reg(data, tt.regs[0]); + result.declare_type.push({ + name: export_name, + body: export_body//todo + }) + if (tt.regs[1][0] != -1) { + result.exports.push(export_name) + } + continue; + } + + tt = re.match("(export )*type ([a-zA-Z]+) = ({)", data) + if (tt) { + let export_name = re.get_reg(data, tt.regs[2]) + let export_body = CheckOutBody(data, tt.regs[3][0], null, true) + data = data.substring(tt.regs[3][1] + export_body.length + 2, data.length) + result.declare_type.push({ + name: export_name, + body: export_body//todo + }) + if (tt.regs[1][0] != -1) { + result.exports.push(export_name) + } + continue; + } + + tt = re.match("declare namespace ([a-zA-Z0-9]+) ({)", data); + if (tt != null)//解析declare + { + let namespace_name = re.get_reg(data, tt.regs[1]) + // print(1, "declare namespace", namespace_name) + let namespace_data = CheckOutBody(data, tt.regs[2][0], null, true) + // XGenerate.gi().Start(re.get_file_in_path(ifname), namespace_name) + // CheckOutDeclare(data) + // XGenerate.gi().End(re.get_path_in_path(ifname))//odname + data = data.substring(tt.regs[2][1] + namespace_data.length + 1, data.length) + result.declare_namespace.push({ + name: namespace_name, + // zzzz: "zzzz",//this is namespace + body: AnalyzeNamespace(namespace_data) + }) + continue; + } + + tt = re.match("(export )*(declare )*interface ([A-Za-z_0-9<>= ]+) (extends [a-zA-Z]+ )*({)", data) + if (tt) { + let interface_name = re.get_reg(data, tt.regs[3]) + // print(1, "declare interface", interface_name) + let interface_data = CheckOutBody(data, tt.regs[5][0], null, true) + data = data.substring(tt.regs[5][1] + interface_data.length + 1, data.length) + result.declare_interface.push({ + name: interface_name, + body: {}//todo + }) + continue + } + + tt = re.match("declare function ([A-Za-z0-9_]+)\\(([\n a-zA-Z:;=,_0-9?<>{}|]*)\\) *: *([A-Za-z0-9_<>{}:, .]+);*", data) + if (tt) { + let function_name = re.get_reg(data, tt.regs[1]) + let function_body = re.get_reg(data, tt.regs[2]) + // print(1, "declare function", function_name) + // # print("function :",data[tt.regs[1][0]:tt.regs[1][1]]) + data = re.remove_reg(data, tt.regs[0]) + result.declare_function.push({ + name: function_name, + body: function_body//todo + }) + continue + } + + if (old_data == data) { + print("\nvvv 解析文件失败 vvv") + print("[", data.substring(0, data.length > 64 ? 64 : data.length), "]") + print("^^^ 解析文件失败 ^^^\n") + break; + } + } + // print(JSON.stringify(result, null, 4)) + // print(result) + return result +} + +module.exports = { + AnalyzeFile +} \ No newline at end of file diff --git a/napi_tool/code/tool_code/gen/analyze/function.js b/napi_tool/code/tool_code/gen/analyze/function.js new file mode 100644 index 0000000000000000000000000000000000000000..66c3671aead454f673c6c76e53b453c446320436 --- /dev/null +++ b/napi_tool/code/tool_code/gen/analyze/function.js @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2021 Shenzhen Kaihong Digital Industry Development 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 re = require("../tools/re"); +const { print, RemoveExplains, RemoveEmptyLine, CheckOutBody } = require("../tools/tool"); +const { FuncType,NumberIncrease } = require("../tools/common"); +const { AnalyzeParams } = require("./params"); +const { AnalyzeReturn }=require("./return"); + +/**函数解析 */ +function AnalyzeFunction(name, values, ret) { + values = re.replace_all(re.replace_all(values, " ", ""), "\n", "") + let tmp = AnalyzeParams(values) + values = tmp[0] + let func_type = tmp[1] + + tmp = AnalyzeReturn(ret) + ret = tmp[0] + if (tmp[1]) + func_type = FuncType.PROMISE + + if (func_type == FuncType.ASYNC || func_type == FuncType.PROMISE) { + //查看是否有同名的函数,async_callback和promise,只需要保留一个,这里简单处理,忽略所有promise + if (func_type == FuncType.PROMISE) return null; + } + + for (let j in values) { + let v = values[j] + if (v["type"].indexOf("number") >= 0) { + v["type"] = v["type"].replace("number", "NUMBER_TYPE_" + NumberIncrease.GetAndIncrease()) + } + } + if (ret.indexOf("number") >= 0) { + ret = ret.replace("number", "NUMBER_TYPE_" + NumberIncrease.GetAndIncrease()) + } + + let result = { + name: name, + type: func_type, + value: values, + ret: ret, + } + return result +} + +module.exports = { + AnalyzeFunction +} \ No newline at end of file diff --git a/napi_tool/code/tool_code/gen/analyze/interface.js b/napi_tool/code/tool_code/gen/analyze/interface.js new file mode 100644 index 0000000000000000000000000000000000000000..18bf666667f4fec282430df83e88c2d74dbc2569 --- /dev/null +++ b/napi_tool/code/tool_code/gen/analyze/interface.js @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2021 Shenzhen Kaihong Digital Industry Development 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 re = require("../tools/re"); +const { print, RemoveExplains, RemoveEmptyLine, CheckOutBody } = require("../tools/tool"); +const { FuncType,NumberIncrease } = require("../tools/common"); + +const { AnalyzeFunction }=require("./function"); + +/**interface解析 */ +function AnalyzeInterface(data) {//same as class + let body = re.replace_all(data, "\n", "").split(";")// # replace(" ", ""). + // print(body) + let result = { + value: [], + function: [] + } + for (let i in body) { + let t = body[i] + while (t.length > 0 && t[0] == ' ')//去除前面的空格 + t = t.substring(1, t.length) + while (t.length > 0 && t[-1] == ' ')//去除后面的空格 + t = t.substring(0, t.length - 1) + if (t == "") break//如果t为空直接返回 + // print(t) + let tt = re.match(" *([a-zA-Z0-9_]+) *: *([a-zA-Z_0-9<>]+)", t) + if (tt) {//变量 + + let value_name = re.get_reg(t, tt.regs[1]) + let value_type = re.get_reg(t, tt.regs[2]) + if (value_type.indexOf("number") >= 0) { + value_type = value_type.replace("number", "NUMBER_TYPE_" + NumberIncrease.GetAndIncrease()) + } + result.value.push({ + name: value_name, + type: value_type + }) + continue + } + tt = re.match(" *([A-Za-z0-9_]+)\\(([\n a-zA-Z:;=,_0-9?<>{}|]*)\\) *: *([A-Za-z0-9_<>{}:, .]+)", t) + if (tt) {//函数 + let func_detail = AnalyzeFunction(re.get_reg(t, tt.regs[1]), re.get_reg(t, tt.regs[2]), re.get_reg(t, tt.regs[3])) + if (func_detail != null) + result.function.push(func_detail) + continue + } + } + return result +} + +module.exports = { + AnalyzeInterface +} \ No newline at end of file diff --git a/napi_tool/code/tool_code/gen/analyze/namespace.js b/napi_tool/code/tool_code/gen/analyze/namespace.js new file mode 100644 index 0000000000000000000000000000000000000000..3f61edce7e2a8203ae845a2b9fd54c6b6115f7a0 --- /dev/null +++ b/napi_tool/code/tool_code/gen/analyze/namespace.js @@ -0,0 +1,222 @@ +/* +* Copyright (c) 2021 Shenzhen Kaihong Digital Industry Development 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 re = require("../tools/re"); +const { print, RemoveExplains, RemoveEmptyLine, CheckOutBody } = require("../tools/tool"); +const { FuncType, NumberIncrease } = require("../tools/common"); + +const { AnalyzeFunction } = require("./function"); +const { AnalyzeInterface } = require("./interface"); + +/**namespace解析 */ +function AnalyzeNamespace(data) { + let result = { + exports: [], + + enum: [], + const: [], + type: [], + function: [], + + interface: [], + class: [], + namespace: [], + } + while (data != '\n') { + let old_data = data + data = RemoveEmptyLine(data) + let tt = re.match(" *\n*", data) + if (tt && tt.regs[0][1] == data.length) break//只剩下空格和回车时,解析完成 + + tt = re.match("(export )*enum *([A-Za-z]+) *({)", data) + if (tt != null) { + let enum_name = re.get_reg(data, tt.regs[2]); + let enum_body = CheckOutBody(data, tt.regs[3][0], null, null) + result.enum.push({ + name: enum_name, + body: enum_body.substring(1, -1) + }) + data = data.substring(tt.regs[3][0] + enum_body.length) + //todo + if (tt.regs[1][0] != -1) { + result.exports.push(enum_name) + } + continue + } + + tt = re.match("(export )*const ([a-zA-Z_]+) *[:=]{1} ([a-zA-Z0-9]+);", data) + if (tt) { + let const_name = re.get_reg(data, tt.regs[1]) + result.const.push({ + name: const_name, + body: re.get_reg(data, tt.regs[2]) + }) + data = re.remove_reg(data, tt.regs[0]) + //todo + if (tt.regs[1][0] != -1) { + result.exports.push(const_name) + } + continue + } + + tt = re.match("(export )*interface ([A-Za-z_0-9]+)()* (extends [a-zA-Z]+ )*({)", data) + if (tt) { + let interface_name = re.get_reg(data, tt.regs[2]) + let interface_body = CheckOutBody(data, tt.regs[5][0], null, null) + // print(interface_body) + result.interface.push({ + name: interface_name, + body: AnalyzeInterface(interface_body.substring(1, interface_body.length - 1)) + }) + // XGenerate.gi().AddInterface(re.get_reg(data,tt.regs[2]), data1.substring(1,data1.length-1)) + data = data.substring(tt.regs[5][0] + interface_body.length, data.length) + //todo + if (tt.regs[1][0] != -1) { + result.exports.push(interface_name) + } + continue + } + + // tt = re.match("(export )*function ([A-Za-z0-9_]+)\\(([\n a-zA-Z:;=,_0-9?<>{}|\\.\\[\\]]*)\\) *: *([A-Za-z0-9_<>{}:, .=]+);*", data) + tt = re.match("(export )*function ([A-Za-z0-9_]+) *(\\()", data) + if (tt) { + let func_name = re.get_reg(data, tt.regs[2]) + // print(func_name) + let func_value = CheckOutBody(data, tt.regs[3][0], ["(", ")"], null) + let func_ret = CheckOutBody(data.substring(tt.regs[3][0] + func_value.length), 0, ["", "\n"], null) + + data = data.substring(tt.regs[3][0] + func_value.length + func_ret.length) + // print(func_value) + // print(func_ret) + let tt2 = re.match(" *: *([A-Za-z0-9_<>{}:, .=]+);*", func_ret) + if (tt2) { + func_ret = re.get_reg(func_ret, tt2.regs[1]) + } + else {//maybe error + // print(func_ret) + func_ret = "void" + } + + let func_detail = AnalyzeFunction(func_name, func_value.substring(1, func_value.length - 1), func_ret) + if (func_detail != null) + result.function.push(func_detail) + + //todo + if (tt.regs[1][0] != -1) { + result.exports.push(func_name) + } + continue + } + + tt = re.match("(export )*type ([a-zA-Z]+) = *([\\(\\):=a-zA-Z<> |\n']+);", data) + if (tt) { + let type_name = re.get_reg(data, tt.regs[2]); + result.type.push({ + name: type_name, + body: re.get_reg(data, tt.regs[3]) + }) + data = re.remove_reg(data, tt.regs[0]) + //todo + if (tt.regs[1][0] != -1) { + result.exports.push(type_name) + } + continue + } + + tt = re.match("(export )*type ([a-zA-Z]+) = ({)", data) + if (tt) { + let type_name = re.get_reg(data, tt.regs[2]); + let type_body = CheckOutBody(data, tt.regs[3][0], null, true) + result.type.push({ + name: type_name, + body: type_body + }) + data = data.substring(tt.regs[3][0] + type_body.length + 2, data.length) + //todo + if (tt.regs[1][0] != -1) { + result.exports.push(type_name) + } + continue + } + + tt = re.match("(export )*class ([a-zA-Z]+) (extends [a-zA-Z]+ )*(implements [a-zA-Z]+ )*({)", data) + if (tt) { + let class_name = re.get_reg(data, tt.regs[2]) + let class_body = CheckOutBody(data, tt.regs[5][0], null, true) + result.class.push({ + name: class_name, + body: class_body + }) + // print(class_name) + // print(class_body) + data = data.substring(tt.regs[5][0] + class_body.length + 2, data.length) + //todo + if (tt.regs[1][0] != -1) { + result.exports.push(class_name) + } + continue + } + + tt = re.match("(export )*namespace ([a-zA-Z0-9]+) ({)", data) + if (tt) { + let namespace_name = re.get_reg(data, tt.regs[2]) + let namespace_body = CheckOutBody(data, tt.regs[3][0], null, true) + result.namespace.push({ + name: namespace_name, + body: AnalyzeNamespace(namespace_body) + }) + data = data.substring(tt.regs[3][0] + namespace_body.length + 2, data.length) + //todo + if (tt.regs[1][0] != -1) { + result.exports.push(namespace_name) + } + continue + } + + tt = re.match("export { ([a-zA-Z]+) };", data) + if (tt) { + let export_name = re.get_reg(data, tt.regs[1]) + result.exports.push(export_name) + data = re.remove_reg(data, tt.regs[0]) + //todo + continue + } + + tt = re.match("export import [a-zA-Z]+ = [a-zA-Z\\.]+;", data) + if (tt) {//todo + data = re.remove_reg(data, tt.regs[0]) + continue + } + + tt = re.match("readonly [a-zA-Z]+: [a-z\\[\\]]+;*", data) + if (tt) {//todo + data = re.remove_reg(data, tt.regs[0]) + continue + } + + if (old_data == data) { + print("\nvvv 解析Namespace失败 vvv") + print("[", data.substring(0, data.length > 128 ? 128 : data.length), "]") + print("^^^ 解析Namespace失败 ^^^\n") + break; + } + } + // print(result) + // print(JSON.stringify(result, null, 4)) + return result +} + +module.exports = { + AnalyzeNamespace +} \ No newline at end of file diff --git a/napi_tool/code/tool_code/gen/analyze/params.js b/napi_tool/code/tool_code/gen/analyze/params.js new file mode 100644 index 0000000000000000000000000000000000000000..adeb7d356a63887bc7cd5d0875bc52bc349d91d3 --- /dev/null +++ b/napi_tool/code/tool_code/gen/analyze/params.js @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2021 Shenzhen Kaihong Digital Industry Development 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 re = require("../tools/re"); +const { print, RemoveExplains, RemoveEmptyLine, CheckOutBody } = require("../tools/tool"); +const { FuncType,NumberIncrease } = require("../tools/common"); + +/**函数参数解析 */ +function AnalyzeParams(values) { + let result = [] + let func_type = FuncType.DIRECT + while (values.length > 0) { + let v = CheckOutBody(values, 0, ["", ","]) + if (v == null) + v = values + values = values.substring(v.length, values.length) + let tt = re.match("([a-zA-Z0-9\\.]+)\\?*:([a-zA-Z<>_0-9\\(\\):='{}]+)", v) + if (tt != null) { + let type = re.get_reg(v, tt.regs[2]) + result.push({ "name": re.get_reg(v, tt.regs[1]), "type": type }) + if (type.indexOf("AsyncCallback") >= 0) + func_type = FuncType.ASYNC + if (func_type == FuncType.DIRECT && type.indexOf("Callback") >= 0 && type.indexOf("AsyncCallback") < 0) + func_type = FuncType.SYNC + } + else { + print("\nvvv 参数列表解析失败 vvv") + print(v, values) + print("^^^ 参数列表解析失败 ^^^\n") + } + } + return [result, func_type] +} + +module.exports = { + AnalyzeParams +} \ No newline at end of file diff --git a/napi_tool/code/tool_code/gen/analyze/return.js b/napi_tool/code/tool_code/gen/analyze/return.js new file mode 100644 index 0000000000000000000000000000000000000000..578809bf8f45f535645915e60ffab7e1e55bb533 --- /dev/null +++ b/napi_tool/code/tool_code/gen/analyze/return.js @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2021 Shenzhen Kaihong Digital Industry Development 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 re = require("../tools/re"); +const { print, RemoveExplains, RemoveEmptyLine, CheckOutBody } = require("../tools/tool"); +const { FuncType,NumberIncrease } = require("../tools/common"); + +/**函数返回值解析 */ +function AnalyzeReturn(ret) { + let is_promise = false + if (ret.indexOf("Promise") >= 0) { + is_promise = true + } + return [ret, is_promise] +} + +module.exports = { + AnalyzeReturn +} \ No newline at end of file diff --git a/napi_tool/code/tool_code/gen/cmd_gen.js b/napi_tool/code/tool_code/gen/cmd_gen.js new file mode 100644 index 0000000000000000000000000000000000000000..b83e80504daca82d4c04ad0b3005c310591d9879 --- /dev/null +++ b/napi_tool/code/tool_code/gen/cmd_gen.js @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2021 Shenzhen Kaihong Digital Industry Development 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 main = require("./main"); +const re = require("./tools/re"); +function print(...args) +{ + console.log(...args) +} + +let usage_str=`usage: +cmd_gen-win.exe d:\\@ohos.youmodulename.d.ts` + +if(process.argv.length<=2) +{ + print(usage_str) +} +else +{ + let fn=re.get_file_in_path(process.argv[2]) + + let tt=re.match("@ohos.[a-zA-Z0-9]+.d.ts",fn) + if(tt) + { + main.DoGenerate(process.argv[2]) + } + else + { + print("\n文件名 "+fn+" 校验失败,需要符合 @ohos.xxx.d.ts") + } +} + +/* +打包成exe文件 +pkg vscode_plugin/gnapi/gen/cmd_gen.js +*/ \ No newline at end of file diff --git a/napi_tool/code/tool_code/gen/extend/binding_gyp.js b/napi_tool/code/tool_code/gen/extend/binding_gyp.js new file mode 100644 index 0000000000000000000000000000000000000000..befd934e1eac6cf31bbfda4eb82a649531f5c422 --- /dev/null +++ b/napi_tool/code/tool_code/gen/extend/binding_gyp.js @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2021 Shenzhen Kaihong Digital Industry Development 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 { WriteFile } = require("../tools/FileRW"); +const re = require("../tools/re"); + +let gyp_templete = ` +{ + "targets": [ + { + "target_name": "[impl_name]", + "sources": [ + "./[impl_name].cpp", + "./[impl_name]_middle.cpp", + "./x_napi_tool.cpp"], + "include_dirs": ["."], + "cflags_cc": [ "-frtti","-std=c++17" ] + } + ] +} +` + +/**创建nodejs编译文件,用于在ubuntu测试 */ +function GenerateGYP(dest_dir, impl_name) { + let ss = gyp_templete.ReplaceAll("[impl_name]", impl_name) + WriteFile(re.path_join(dest_dir, "binding.gyp"), ss) + + WriteFile(re.path_join(dest_dir, "test.sh"), "node-gyp configure build && sleep 0.5 && node --expose-gc test.js") + +} + +module.exports = { + GenerateGYP +} \ No newline at end of file diff --git a/napi_tool/code/tool_code/gen/extend/build_gn.js b/napi_tool/code/tool_code/gen/extend/build_gn.js new file mode 100644 index 0000000000000000000000000000000000000000..11148b51e86d17f6370a6b00d3af5c8515b10803 --- /dev/null +++ b/napi_tool/code/tool_code/gen/extend/build_gn.js @@ -0,0 +1,58 @@ +/* +* Copyright (c) 2021 Shenzhen Kaihong Digital Industry Development 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 { WriteFile } = require("../tools/FileRW"); +const re = require("../tools/re"); + +let gn_templete = `\ +import("//build/ohos.gni") + +ohos_shared_library("[impl_name]") +{ + sources = [ + "[impl_name]_middle.cpp", + "[impl_name].cpp", + "x_napi_tool.cpp", + ] + include_dirs = [ + ".", + "//third_party/node/src", + ] + deps=[ + "//foundation/ace/napi:ace_napi", + ] + remove_configs = [ "//build/config/compiler:no_rtti" ] + cflags=[ + ] + cflags_cc=[ + "-frtti", + ] + ldflags = [ + ] + + relative_install_dir = "module" + part_name = "" + subsystem_name = "" +} +` + +/**创建nodejs编译文件,用于在ubuntu测试 */ +function GenerateGN(dest_dir, impl_name) { + let ss = gn_templete.ReplaceAll("[impl_name]", impl_name) + WriteFile(re.path_join(dest_dir, "BUILD.gn"), ss) +} + +module.exports = { + GenerateGN +} \ No newline at end of file diff --git a/napi_tool/code/tool_code/gen/extend/x_napi_tool.js b/napi_tool/code/tool_code/gen/extend/x_napi_tool.js new file mode 100644 index 0000000000000000000000000000000000000000..5291932669bfdb7dbfb1e1943250aa772d33e2e6 --- /dev/null +++ b/napi_tool/code/tool_code/gen/extend/x_napi_tool.js @@ -0,0 +1,608 @@ +/* +* Copyright (c) 2021 Shenzhen Kaihong Digital Industry Development 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 { WriteFile } = require("../tools/FileRW"); +const re = require("../tools/re"); + +let x_napi_tool_h = `\ +#ifndef CC_TOOL_H +#define CC_TOOL_H + +#include +#include +#include +#include +#include +#include + +class XNapiTool +{ +public: + using CallbackFunction = void (*)(XNapiTool *pxt, void *data); + using RELEASE_INSTANCE = void (*)(void *p); + static napi_value UndefinedValue(napi_env env); + napi_value UndefinedValue(); + + napi_value CreateSubObject(napi_value parent, const char *name); + void DefineFunction(const char *funcName, napi_callback callback, napi_value dest = nullptr); + void DefineClass(const char *className, napi_callback constructorFunc, std::map> &valueList, std::map &funcList, napi_value dest = nullptr); + + XNapiTool(napi_env env, napi_callback_info info); + XNapiTool(napi_env env, napi_value exports); + ~XNapiTool(); + + bool SwapJs2CBool(napi_value value); + int32_t SwapJs2CInt32(napi_value value); + uint32_t SwapJs2CUint32(napi_value value); + int64_t SwapJs2CInt64(napi_value value); + double_t SwapJs2CDouble(napi_value value); + size_t SwapJs2CUtf8(napi_value value, std::string &str); + + napi_value SwapC2JsBool(bool value); + napi_value SwapC2JsInt32(int32_t value); + napi_value SwapC2JsUint32(uint32_t value); + napi_value SwapC2JsInt64(int64_t value); + napi_value SwapC2JsDouble(double_t value); + napi_value SwapC2JsUtf8(const char *value); + + napi_value GetArgv(uint32_t p); + uint32_t GetArgc(); + + napi_value GetValueProperty(napi_value value, const char *propertyName); + napi_value SetValueProperty(napi_value &value, const char *propertyName, napi_value property); + + uint32_t GetArrayLength(napi_value value); + napi_value GetArrayElement(napi_value value, uint32_t p); + napi_value SetArrayElement(napi_value &value, uint32_t p, napi_value ele); + + napi_value SyncCallBack(napi_value func, size_t argc, napi_value *args); + + napi_value StartAsync(CallbackFunction pe, void *data, CallbackFunction pc, napi_value func = nullptr); + void FinishAsync(size_t argc, napi_value *args); + + bool IsFailed() + { + return bFailed_; + } + napi_value GetError() + { + return error_; + } + napi_env GetEnv() + { + return env_; + } + + napi_value tmp_value; + +private: + napi_env env_; + napi_value exports_; + + //解析参数 + napi_value argv_[8]; + size_t argc_; + napi_value thisVar_; + void *data_; + + //错误信息 + napi_value error_; + bool bFailed_; + bool CheckFailed(bool b, const char *errStr); + bool CheckValueType(napi_value value, napi_valuetype type); + + //异步调用相关代码 + static void AsyncExecute(napi_env env, void *p); + void AsyncExecuteFunction(); + static void AsyncComplete(napi_env env, napi_status status, void *p); + void AsyncCompleteFunction(); + napi_ref callbackFunc_; + napi_async_work work_; + bool asyncNeedRelease_; + CallbackFunction executeFunction_; + CallbackFunction completeFunction_; + void *valueData_; + napi_deferred deferred_; + enum class AsyncMode + { + NONE, + CALLBACK, + PROMISE, + }; + AsyncMode asyncMode_; + + //创建类相关代码 +public: + static void WrapFinalize(napi_env env, void *data, void *hint); + void ReleaseInstance(); + napi_value WrapInstance(void *instance, RELEASE_INSTANCE ri); + void *UnWarpInstance(); + + void SetAsyncInstance(void *p); + void *GetAsyncInstance(); + +private: + napi_ref wrapper_; + void *pInstance_; + RELEASE_INSTANCE releaseInstance_; + void *asyncInstance_; +}; + +#endif +` + +let x_napi_tool_cpp = ` + +#include "x_napi_tool.h" +#include +#include + +#define CC_ASSERT(btrue) \\ + if (!(btrue)) \\ + { \\ + } \\ + assert(btrue); + +XNapiTool::XNapiTool(napi_env env, napi_callback_info info) +{ + env_ = env; + bFailed_ = false; + executeFunction_ = nullptr; + completeFunction_ = nullptr; + valueData_ = nullptr; + asyncNeedRelease_ = false; + asyncMode_ = AsyncMode::NONE; + pInstance_ = nullptr; + releaseInstance_ = nullptr; + wrapper_ = nullptr; + + argc_ = 8; + + napi_status result_status = napi_get_cb_info(env, info, &argc_, argv_, &thisVar_, &data_); + CheckFailed(result_status == napi_ok, "get args fail"); +} + +XNapiTool::XNapiTool(napi_env env, napi_value exports) +{ + env_ = env; + exports_ = exports; + + asyncMode_ = AsyncMode::NONE; + wrapper_ = nullptr; +} + +XNapiTool::~XNapiTool() +{ + if (asyncMode_ == AsyncMode::PROMISE) + { + napi_status result_status = napi_delete_async_work(env_, work_); + CC_ASSERT(result_status == napi_ok); + } + if (asyncMode_ == AsyncMode::CALLBACK) + { + napi_status result_status = napi_delete_reference(env_, callbackFunc_); + CC_ASSERT(result_status == napi_ok); + result_status = napi_delete_async_work(env_, work_); + CC_ASSERT(result_status == napi_ok); + } + if (wrapper_ != nullptr) + { + napi_status result_status = napi_delete_reference(env_, wrapper_); + CC_ASSERT(result_status == napi_ok); + } + /*printf("----------------release XNapiTool\\n");*/ +} + +bool XNapiTool::SwapJs2CBool(napi_value value) +{ + bool result; + napi_status result_status = napi_get_value_bool(env_, value, &result); + if (CheckFailed(result_status == napi_ok, "swap_js_2_c_bool fail")) + return -1; + return result; +} + +napi_value XNapiTool::GetArgv(uint32_t p) +{ + if (CheckFailed(p < argc_, "GetArgv失败")) + return error_; + + return argv_[p]; +} + +uint32_t XNapiTool::GetArgc() +{ + return argc_; +} + +napi_value XNapiTool::GetValueProperty(napi_value value, const char *propertyName) +{ + napi_value result; + napi_status result_status = napi_get_named_property(env_, value, propertyName, &result); + CC_ASSERT(result_status == napi_ok); + return result; +} + +napi_value XNapiTool::SetValueProperty(napi_value &value, const char *propertyName, napi_value property) +{ + napi_status result_status; + if (value == nullptr) + { + result_status = napi_create_object(env_, &value); + CC_ASSERT(result_status == napi_ok); + } + result_status = napi_set_named_property(env_, value, propertyName, property); + CC_ASSERT(result_status == napi_ok); + return value; +} + +uint32_t XNapiTool::GetArrayLength(napi_value value) +{ + uint32_t ret; + napi_status result_status = napi_get_array_length(env_, value, &ret); + CC_ASSERT(result_status == napi_ok); + return ret; +} + +napi_value XNapiTool::GetArrayElement(napi_value value, uint32_t p) +{ + napi_value result; + napi_status result_status = napi_get_element(env_, value, p, &result); + CC_ASSERT(result_status == napi_ok); + return result; +} + +napi_value XNapiTool::SetArrayElement(napi_value &value, uint32_t p, napi_value ele) +{ + napi_status result_status; + if (value == nullptr) + { + result_status = napi_create_array(env_, &value); + CC_ASSERT(result_status == napi_ok); + } + result_status = napi_set_element(env_, value, p, ele); + CC_ASSERT(result_status == napi_ok); + return value; +} + +bool XNapiTool::CheckFailed(bool b, const char *errStr) +{ + if (bFailed_) + return true; + if (b) + return false; + + napi_value errCode = nullptr; + napi_value errMessage = nullptr; + + napi_create_string_utf8(env_, "x_tool", strlen("x_tool"), &errCode); + napi_create_string_utf8(env_, errStr, strlen(errStr), &errMessage); + napi_create_error(env_, errCode, errMessage, &error_); + printf("x_napi_tool err : %s\\n", errStr); + + bFailed_ = true; + return true; +} + +int32_t XNapiTool::SwapJs2CInt32(napi_value value) +{ + int32_t result; + napi_status result_status = napi_get_value_int32(env_, value, &result); + if (CheckFailed(result_status == napi_ok, "swap_js_2_c_int32 fail")) + return -1; + return result; +} + +uint32_t XNapiTool::SwapJs2CUint32(napi_value value) +{ + uint32_t result; + napi_status result_status = napi_get_value_uint32(env_, value, &result); + if (CheckFailed(result_status == napi_ok, "swap_js_2_c_uint32 fail")) + return -1; + return result; +} + +int64_t XNapiTool::SwapJs2CInt64(napi_value value) +{ + int64_t result; + napi_status result_status = napi_get_value_int64(env_, value, &result); + if (CheckFailed(result_status == napi_ok, "swap_js_2_c_int32 fail")) + return -1; + return result; +} + +double_t XNapiTool::SwapJs2CDouble(napi_value value) +{ + double_t result; + napi_status result_status = napi_get_value_double(env_, value, &result); + if (CheckFailed(result_status == napi_ok, "swap_js_2_c_int32 fail")) + return -1; + return result; +} + +size_t XNapiTool::SwapJs2CUtf8(napi_value value, std::string &str) +{ + char buf[1024]; + size_t result; + napi_status result_status = napi_get_value_string_utf8(env_, value, buf, 1024, &result); + if (CheckFailed(result_status == napi_ok, "napi_get_value_string_utf8 fail")) + return -1; + str = buf; + return result; +} + +napi_value XNapiTool::SwapC2JsBool(bool value) +{ + napi_value result; + napi_status result_status = napi_create_int32(env_, value, &result); + CC_ASSERT(result_status == napi_ok); + return result; +} + +napi_value XNapiTool::SwapC2JsInt32(int32_t value) +{ + napi_value result; + napi_status result_status = napi_create_int32(env_, value, &result); + CC_ASSERT(result_status == napi_ok); + return result; +} + +napi_value XNapiTool::SwapC2JsUint32(uint32_t value) +{ + napi_value result; + napi_status result_status = napi_create_uint32(env_, value, &result); + CC_ASSERT(result_status == napi_ok); + return result; +} + +napi_value XNapiTool::SwapC2JsInt64(int64_t value) +{ + napi_value result; + napi_status result_status = napi_create_int64(env_, value, &result); + CC_ASSERT(result_status == napi_ok); + return result; +} + +napi_value XNapiTool::SwapC2JsDouble(double_t value) +{ + napi_value result; + napi_status result_status = napi_create_double(env_, value, &result); + CC_ASSERT(result_status == napi_ok); + return result; +} + +napi_value XNapiTool::SwapC2JsUtf8(const char *value) +{ + napi_value result; + napi_status result_status = napi_create_string_utf8(env_, value, NAPI_AUTO_LENGTH, &result); + CC_ASSERT(result_status == napi_ok); + return result; +} + +bool XNapiTool::CheckValueType(napi_value value, napi_valuetype type) +{ + napi_valuetype value_type; + napi_status result_status = napi_typeof(env_, value, &value_type); + CC_ASSERT(result_status == napi_ok); + if (CheckFailed(value_type == type, "传入参数类型不是回调函数")) + return false; + return true; +} + +napi_value XNapiTool::SyncCallBack(napi_value func, size_t argc, napi_value *args) +{ + napi_value cb_result; + napi_status result_status = napi_call_function(env_, thisVar_, func, argc, args, &cb_result); + CC_ASSERT(result_status == napi_ok); + return cb_result; +} + +void XNapiTool::AsyncExecuteFunction() +{ + if (executeFunction_ != nullptr) + { + executeFunction_(this, valueData_); + } +} +void XNapiTool::AsyncExecute(napi_env env, void *p) +{ + XNapiTool *pxt = (XNapiTool *)p; + pxt->AsyncExecuteFunction(); +} +void XNapiTool::AsyncCompleteFunction() +{ + if (completeFunction_ != nullptr) + { + completeFunction_(this, valueData_); + } +} +void XNapiTool::AsyncComplete(napi_env env, napi_status status, void *p) +{ + XNapiTool *pxt = (XNapiTool *)p; + pxt->AsyncCompleteFunction(); + delete pxt; +} + +napi_value XNapiTool::StartAsync(CallbackFunction pe, void *data, CallbackFunction pc, napi_value func) +{ + napi_value result; + napi_status result_status; + + if (func == nullptr) + { // promise + result_status = napi_create_promise(env_, &deferred_, &result); + CC_ASSERT(result_status == napi_ok); + asyncMode_ = AsyncMode::PROMISE; + } + else + { // callback + result_status = napi_create_reference(env_, func, 1, &callbackFunc_); + CC_ASSERT(result_status == napi_ok); + asyncMode_ = AsyncMode::CALLBACK; + result = UndefinedValue(env_); + } + + napi_value resourceName = nullptr; + result_status = napi_create_string_utf8(env_, "x_napi_tool", NAPI_AUTO_LENGTH, &resourceName); + CC_ASSERT(result_status == napi_ok); + result_status = napi_create_async_work(env_, nullptr, resourceName, XNapiTool::AsyncExecute, XNapiTool::AsyncComplete, this, &work_); + CC_ASSERT(result_status == napi_ok); + result_status = napi_queue_async_work(env_, work_); + CC_ASSERT(result_status == napi_ok); + + asyncNeedRelease_ = true; + executeFunction_ = pe; + completeFunction_ = pc; + valueData_ = data; + + return result; +} + +void XNapiTool::FinishAsync(size_t argc, napi_value *args) +{ + if (asyncMode_ == AsyncMode::PROMISE) + { + if (argc > 0) + { + napi_resolve_deferred(env_, deferred_, args[0]); + } + else + { + napi_reject_deferred(env_, deferred_, SwapC2JsUtf8("promise fail")); + } + return; + } + napi_value result = 0; + napi_value cb = 0; + + napi_status result_status = napi_get_reference_value(env_, callbackFunc_, &cb); + CC_ASSERT(result_status == napi_ok); + result_status = napi_call_function(env_, thisVar_, cb, argc, args, &result); + CC_ASSERT(result_status == napi_ok); +} + +napi_value XNapiTool::UndefinedValue(napi_env env) +{ + napi_value result; + napi_get_undefined(env, &result); + return result; +} + +napi_value XNapiTool::UndefinedValue() +{ + napi_value result; + napi_get_undefined(env_, &result); + return result; +} + +napi_value XNapiTool::CreateSubObject(napi_value parent, const char *name) +{ + napi_value result; + napi_status result_status = napi_create_object(env_, &result); + CC_ASSERT(result_status == napi_ok); + + result_status = napi_set_named_property(env_, parent, name, result); + CC_ASSERT(result_status == napi_ok); + + return result; +} + +void XNapiTool::DefineFunction(const char *funcName, napi_callback callback, napi_value dest) +{ + if (dest == nullptr) + dest = exports_; + napi_property_descriptor descriptor[] = { + {funcName, 0, callback, 0, 0, 0, napi_default, 0}}; + + napi_status result_status = napi_define_properties(env_, dest, 1, descriptor); + CC_ASSERT(result_status == napi_ok); +} + +void XNapiTool::DefineClass(const char *className, napi_callback constructorFunc, std::map> &valueList, std::map &funcList, napi_value dest) +{ + if (dest == nullptr) + dest = exports_; + napi_value tmpClass = nullptr; + napi_property_descriptor funcs[funcList.size() + valueList.size()]; + + uint32_t p = 0; + for (auto it = valueList.begin(); it != valueList.end(); it++) + { + funcs[p++] = {it->first, 0, 0, it->second["getvalue"], it->second["setvalue"], 0, napi_default, 0}; // get,set + } + for (auto it = funcList.begin(); it != funcList.end(); it++) + { + funcs[p++] = {it->first, 0, it->second, 0, 0, 0, napi_default, 0}; + } + + napi_status result_status = napi_define_class(env_, className, NAPI_AUTO_LENGTH, constructorFunc, nullptr, p, funcs, &tmpClass); + CC_ASSERT(result_status == napi_ok); + + result_status = napi_set_named_property(env_, dest, className, tmpClass); + CC_ASSERT(result_status == napi_ok); +} + +void XNapiTool::WrapFinalize(napi_env env, void *data, void *hint) +{ + // (void)env; + // (void)hint; + XNapiTool *pxt = (XNapiTool *)data; + pxt->ReleaseInstance(); + delete pxt; +} + +void XNapiTool::ReleaseInstance() +{ + if (releaseInstance_ != nullptr) + { + releaseInstance_(pInstance_); + } +} + +napi_value XNapiTool::WrapInstance(void *instance, RELEASE_INSTANCE ri) +{ + pInstance_ = instance; + releaseInstance_ = ri; + napi_status result_status = napi_wrap(env_, thisVar_, this, WrapFinalize, nullptr, &wrapper_); + CC_ASSERT(result_status == napi_ok); + return thisVar_; +} + +void *XNapiTool::UnWarpInstance() +{ + XNapiTool *p; + napi_status result_status = napi_unwrap(env_, thisVar_, (void **)&p); + CC_ASSERT(result_status == napi_ok); + return p->pInstance_; +} + +void XNapiTool::SetAsyncInstance(void *p) +{ + asyncInstance_ = p; +} + +void *XNapiTool::GetAsyncInstance() +{ + return asyncInstance_; +} +` + +function GenerateBase(dest_dir) { + WriteFile(re.path_join(dest_dir, "x_napi_tool.h"), x_napi_tool_h) + WriteFile(re.path_join(dest_dir, "x_napi_tool.cpp"), x_napi_tool_cpp) +} + +module.exports = { + GenerateBase +} \ No newline at end of file diff --git a/napi_tool/code/tool_code/gen/generate.js b/napi_tool/code/tool_code/gen/generate.js new file mode 100644 index 0000000000000000000000000000000000000000..933af37ab00b455c6a17fb8520f8310a65b86af1 --- /dev/null +++ b/napi_tool/code/tool_code/gen/generate.js @@ -0,0 +1,143 @@ +/* +* Copyright (c) 2021 Shenzhen Kaihong Digital Industry Development 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. +*/ +//生成BUILD.gn +//生成x_napi_tool.h,生成x_napi_tool.cpp +const { ReplaceAll, print } = require("./tools/tool"); +const { GenerateNamespace } = require("./generate/namespace"); +const { WriteFile } = require("./tools/FileRW"); +const re = require("./tools/re"); +const { GenerateGYP } = require("./extend/binding_gyp"); +const { GenerateGN } = require("./extend/build_gn"); +const { GenerateBase } = require("./extend/x_napi_tool"); +const { NumberIncrease } = require("./tools/common"); + +let module_cpp_tmplete = `\ +#include +#include +#include +#include +#include +#include "x_napi_tool.h" +#include "[impl_name].h" + +#define NUMBER_JS_2_C(napi_v, type, dest) \\ + if (typeid(type) == typeid(int32_t)) \\ + dest = pxt->SwapJs2CInt32(napi_v); \\ + else if (typeid(type) == typeid(uint32_t)) \\ + dest = pxt->SwapJs2CUint32(napi_v); \\ + else if (typeid(type) == typeid(int64_t)) \\ + dest = pxt->SwapJs2CInt64(napi_v); \\ + else if (typeid(type) == typeid(double_t)) \\ + dest = pxt->SwapJs2CDouble(napi_v); + +napi_value number_c_to_js(XNapiTool *pxt, const std::type_info &n, void *num) +{ + if (n == typeid(int32_t)) + return pxt->SwapC2JsInt32(*(int32_t *)num); + else if (n == typeid(uint32_t)) + return pxt->SwapC2JsUint32(*(uint32_t *)num); + else if (n == typeid(int64_t)) + return pxt->SwapC2JsInt64(*(int64_t *)num); + else if (n == typeid(double_t)) + return pxt->SwapC2JsDouble(*(double_t *)num); + return nullptr; +} +#define NUMBER_C_2_JS(pxt, n) \\ + number_c_to_js(pxt, typeid(n), &n) + +[body_replace] + +napi_value init(napi_env env, napi_value exports) +{ + std::shared_ptr pxt = std::make_shared(env, exports); + + [init_replace] + + return exports; +} + +static napi_module g_[impl_name]_Module = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = init, + .nm_modname = "", + .nm_priv = ((void *)0), + .reserved = {(void *)0}, +}; + +extern "C" __attribute__((constructor)) void Register_[impl_name]_Module(void) +{ + napi_module_register(&g_[impl_name]_Module); +} +` + +let impl_h_templete = `\ +#ifndef IMPL_[impl_name_upper]_H +#define IMPL_[impl_name_upper]_H + +#include +#include +#include +#include +#include + +[number_using] + +[impl_h_detail] + +#endif // IMPL_[impl_name_upper]_H +` + +let impl_cpp_templete = `\ +#include "[impl_name].h" + +[impl_cpp_detail] +` + +function GenerateAll(struct_of_ts, dest_dir) { + let ns0 = struct_of_ts.declare_namespace[0]; + + let result = GenerateNamespace(ns0.name, ns0.body) + + let number_using = "" + for (let i = 1; i < NumberIncrease.Get(); i++) { + number_using += "using NUMBER_TYPE_%d = uint32_t;\n".format(i) + } + + let middle_cpp = ReplaceAll(module_cpp_tmplete, "[body_replace]", result.middle_body); + middle_cpp = ReplaceAll(middle_cpp, "[init_replace]", result.middle_init); + middle_cpp = ReplaceAll(middle_cpp, "[impl_name]", ns0.name); + WriteFile(re.path_join(dest_dir, "%s_middle.cpp".format(ns0.name)), middle_cpp) + + let impl_h = ReplaceAll(impl_h_templete, "[impl_name_upper]", ns0.name.toUpperCase()) + impl_h = impl_h.ReplaceAll("[number_using]", number_using); + impl_h = ReplaceAll(impl_h, "[impl_h_detail]", result.impl_h) + WriteFile(re.path_join(dest_dir, "%s.h".format(ns0.name)), impl_h) + + let impl_cpp = impl_cpp_templete.ReplaceAll("[impl_name]", ns0.name) + impl_cpp = impl_cpp.ReplaceAll("[impl_cpp_detail]", result.impl_cpp) + WriteFile(re.path_join(dest_dir, "%s.cpp".format(ns0.name)), impl_cpp) + + + GenerateGYP(dest_dir, ns0.name)//生成ubuntu下测试的编译脚本 + GenerateGN(dest_dir, ns0.name)//生成BUILD.gn for ohos + GenerateBase(dest_dir)//x_napi_tool.h/cpp + // print(middle_cpp) +} + +module.exports = { + GenerateAll +} \ No newline at end of file diff --git a/napi_tool/code/tool_code/gen/generate/function_async.js b/napi_tool/code/tool_code/gen/generate/function_async.js new file mode 100644 index 0000000000000000000000000000000000000000..9d65a4c8cae604776a1b30118746eddc6debe0fe --- /dev/null +++ b/napi_tool/code/tool_code/gen/generate/function_async.js @@ -0,0 +1,159 @@ +/* +* Copyright (c) 2021 Shenzhen Kaihong Digital Industry Development 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 { ReplaceAll, print } = require("../tools/tool"); +const { ParamGenerate } = require("./param_generate"); +const { ReturnGenerate } = require("./return_generate"); +/**结果异步返回Async|Promise */ +let func_async_templete = ` +struct [func_name]_value_struct {[value_in] + + [value_out] +}; + +[static_define]void [func_name]_execute(XNapiTool *pxt, void *data) +{ + [func_name]_value_struct *vio = ([func_name]_value_struct *)data; + [checkout_async_instance] + + [call_func] +} + +[static_define]void [func_name]_complete(XNapiTool *pxt, void *data) +{ + [func_name]_value_struct *vio = ([func_name]_value_struct *)data; + + [value_package] + + { + napi_value args[1] = {result}; + pxt->FinishAsync(1, args); + } + + delete vio; +} + +[static_define]napi_value [func_name]_middle(napi_env env, napi_callback_info info) +{ + XNapiTool *pxt = std::make_unique(env, info).release(); + if (pxt->IsFailed()) + { + napi_value err = pxt->GetError(); + delete pxt; + return err; + } + [unwarp_instance] + + struct [func_name]_value_struct *vio=new [func_name]_value_struct(); + + [value_checkout] + + [start_async] + + if (pxt->IsFailed()) + result = pxt->GetError(); + return result; +}` + +function GenerateFunctionAsync(func, class_name) { + // this.len_to = 0 + // // print(type, name, values, ret_type) + let middle_func = ReplaceAll(func_async_templete, "[func_name]", func.name) + if (class_name == null) { + middle_func = middle_func.ReplaceAll("[static_define]", "") + middle_func = middle_func.ReplaceAll("[unwarp_instance]", "") + middle_func = middle_func.ReplaceAll("[checkout_async_instance]", "") + } + else { + middle_func = middle_func.ReplaceAll("[static_define]", "static ") + middle_func = middle_func.ReplaceAll("[unwarp_instance]", `pxt->SetAsyncInstance(pxt->UnWarpInstance());`) + middle_func = middle_func.ReplaceAll("[checkout_async_instance]", "%s *pInstance = (%s *)pxt->GetAsyncInstance();".format(class_name, class_name)) + } + let param = { + value_in: "",//定义输入 + value_out: "",//定义输出 + + value_checkout: "",//解析 + value_fill: "",//填充到函数内 + value_package: "",//输出参数打包 + value_define: ""//impl参数定义 + } + + for (let i in func.value) { + let v = func.value[i] + ParamGenerate(i, v.name, v.type, param) + } + + // ReturnGenerate(func.ret, param) + ReturnGenerate(param.callback.type, param) + + middle_func = ReplaceAll(middle_func, "[value_in]", param.value_in)// # 输入参数定义 + middle_func = ReplaceAll(middle_func, "[value_out]", param.value_out)// # 输出参数定义 + + middle_func = ReplaceAll(middle_func, "[value_checkout]", param.value_checkout)// # 输入参数解析 + + middle_func = ReplaceAll(middle_func, "[start_async]", ` + napi_value result = \ +pxt->StartAsync(%s_execute, vio, %s_complete, pxt->GetArgc() == %s ? pxt->GetArgv(%d) : nullptr);`.format(func.name, + func.name, parseInt(param.callback.offset) + 1, param.callback.offset))// 注册异步调用 + + let call_func = "%s%s(%s);".format(class_name == null ? "" : "pInstance->", func.name, param.value_fill) + middle_func = ReplaceAll(middle_func, "[call_func]", call_func)//执行 + + middle_func = ReplaceAll(middle_func, "[value_package]", param.value_package)//输出参数打包 + + // middle_func = ReplaceAll(middle_func, " delete vio;", "") + // middle_func = ReplaceAll(middle_func, " delete pxt;// release", "") + // let ttt = ReplaceAll(codestring.func_promise, "[func_name]", name) + // let call_func; + + // if (cvs == null) + // call_func = "%s::%s(%s);".format(this.declare_name, name, param["value_call"]) + // else + // call_func = "%s::%s(%s);".format(cvs[0], cvs[1], param["value_call"]) + // // print(call_func) + // ttt = ReplaceAll(ttt, "[call_static_func]", call_func) + // print("=====1======") + // let ttt2 = "napi_value result = nullptr;\n%s".format(this.c_to_js("vio->out", this.callback_type, "result")) + // // print(this.callback_type) + // print("=====2======") + // ttt = ReplaceAll(ttt, "[promise_arg]", "%s napi_value args[1] = {result,};".format(ttt2)) + // middle_func = middle_func.replace("};", ttt) + // } + + + // if (ret_type == "void" && type != (FuncType.ASYNC | FuncType.PROMISE)) + // param["value_package"] = "napi_value result = XNapiTool::UndefinedValue(env);" + + // middle_func = ReplaceAll(middle_func, "[value_out]", param["value_out"]) + // if (type != (FuncType.ASYNC | FuncType.PROMISE)) + // middle_func = ReplaceAll(middle_func, "[value_package]", param["value_package"]) + // else + // middle_func = ReplaceAll(middle_func, "[value_package]", "") + + // if (cvs == null) { + let impl_h = "\nbool %s(%s);".format(func.name, param.value_define) + let impl_cpp = ` +bool %s%s(%s) { + // TODO + return true; +} +`.format(class_name == null ? "" : class_name + "::", func.name, param.value_define) + + return [middle_func, impl_h, impl_cpp] +} + +module.exports = { + GenerateFunctionAsync +} \ No newline at end of file diff --git a/napi_tool/code/tool_code/gen/generate/function_direct.js b/napi_tool/code/tool_code/gen/generate/function_direct.js new file mode 100644 index 0000000000000000000000000000000000000000..1ba0318ed964984e6e1bc17edb96d06dae296d9c --- /dev/null +++ b/napi_tool/code/tool_code/gen/generate/function_direct.js @@ -0,0 +1,157 @@ +/* +* Copyright (c) 2021 Shenzhen Kaihong Digital Industry Development 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 { ReplaceAll, print } = require("../tools/tool"); +const { ParamGenerate } = require("./param_generate"); +const { ReturnGenerate } = require("./return_generate"); +/**结果直接返回 */ +let func_direct_templete = ` +struct [func_name]_value_struct {[value_in] + + [value_out] +}; + +[static_define]napi_value [func_name]_middle(napi_env env, napi_callback_info info) +{ + XNapiTool *pxt = std::make_unique(env, info).release(); + if (pxt->IsFailed()) + { + napi_value err = pxt->GetError(); + delete pxt; + return err; + } + [unwarp_instance] + + struct [func_name]_value_struct *vio=new [func_name]_value_struct(); + + [value_checkout] + + [call_func] + + [value_package] + + delete vio; + if (pxt->IsFailed()) + result = pxt->GetError(); + delete pxt;// release + return result; +}` + +function GenerateFunctionDirect(func, class_name) { + // this.len_to = 0 + // // print(type, name, values, ret_type) + let middle_func = ReplaceAll(func_direct_templete, "[func_name]", func.name) + if(class_name==null) + { + middle_func=middle_func.ReplaceAll("[static_define]","") + middle_func=middle_func.ReplaceAll("[unwarp_instance]","") + } + else + { + middle_func=middle_func.ReplaceAll("[static_define]","static ") + middle_func=middle_func.ReplaceAll("[unwarp_instance]","%s *pInstance = (%s *)pxt->UnWarpInstance();".format(class_name,class_name)) + } + let param = { + value_in: "",//定义输入 + value_out: "",//定义输出 + + value_checkout: "",//解析 + value_fill: "",//填充到函数内 + value_package: "",//输出参数打包 + value_define: ""//impl参数定义 + } + + for (let i in func.value) { + let v = func.value[i] + ParamGenerate(i, v.name, v.type, param) + } + + ReturnGenerate(func.ret, param) + + middle_func = ReplaceAll(middle_func, "[value_in]", param.value_in)// # 输入参数定义 + middle_func = ReplaceAll(middle_func, "[value_out]", param.value_out)// # 输出参数定义 + + middle_func = ReplaceAll(middle_func, "[value_checkout]", param.value_checkout)// # 输入参数解析 + + let call_func = "%s%s(%s);".format(class_name==null?"":"pInstance->",func.name, param.value_fill) + middle_func = ReplaceAll(middle_func, "[call_func]", call_func)//执行 + + middle_func = ReplaceAll(middle_func, "[value_package]", param.value_package)//输出参数打包 + + // if (type == (FuncType.ASYNC | FuncType.PROMISE)) { + // this.generate_value_out(this.callback_type) + // middle_func = ReplaceAll(middle_func, "[call_static_func]", + // ` + // napi_value result = pxt->StartAsync(%s_execute, vio, %s_complete, pxt->GetArgc() == %s ? pxt->GetArgv(%d) : nullptr);`.format + // (name, name, this.callback_offet + 1, this.callback_offet)) + // middle_func = ReplaceAll(middle_func, " delete vio;", "") + // middle_func = ReplaceAll(middle_func, " delete pxt;// release", "") + // let ttt = ReplaceAll(codestring.func_promise, "[func_name]", name) + // let call_func; + + // if (cvs == null) + // call_func = "%s::%s(%s);".format(this.declare_name, name, param["value_call"]) + // else + // call_func = "%s::%s(%s);".format(cvs[0], cvs[1], param["value_call"]) + // // print(call_func) + // ttt = ReplaceAll(ttt, "[call_static_func]", call_func) + // print("=====1======") + // let ttt2 = "napi_value result = nullptr;\n%s".format(this.c_to_js("vio->out", this.callback_type, "result")) + // // print(this.callback_type) + // print("=====2======") + // ttt = ReplaceAll(ttt, "[promise_arg]", "%s napi_value args[1] = {result,};".format(ttt2)) + // middle_func = middle_func.replace("};", ttt) + // } + // else if (type == FuncType.SYNC) { + // this.generate_value_out(this.callback_type) + // let call_func; + // if (cvs == null) + // call_func = "%s::%s(%s);".format(this.declare_name, name, param["value_call"]) + // else + // call_func = "%s::%s(%s);".format(cvs[0], cvs[1], param["value_call"]) + // middle_func = ReplaceAll(middle_func, "[call_static_func]", + // `%s + // { + // napi_value result = nullptr; + // %s + // napi_value args[1] = {result}; + // pxt->SyncCallBack(pxt->GetArgv(%d), 1, args);}`.format(call_func, + // this.c_to_js("vio->out", this.callback_type, "result"), + // this.callback_offet)) + // } + + // if (ret_type == "void" && type != (FuncType.ASYNC | FuncType.PROMISE)) + // param["value_package"] = "napi_value result = XNapiTool::UndefinedValue(env);" + + // middle_func = ReplaceAll(middle_func, "[value_out]", param["value_out"]) + // if (type != (FuncType.ASYNC | FuncType.PROMISE)) + // middle_func = ReplaceAll(middle_func, "[value_package]", param["value_package"]) + // else + // middle_func = ReplaceAll(middle_func, "[value_package]", "") + + // if (cvs == null) { + let impl_h = "\nbool %s(%s);".format(func.name, param.value_define) + let impl_cpp = ` +bool %s%s(%s) { + // TODO + return true; +} +`.format(class_name==null?"":class_name+"::",func.name, param.value_define) + + return [middle_func, impl_h, impl_cpp] +} + +module.exports = { + GenerateFunctionDirect +} \ No newline at end of file diff --git a/napi_tool/code/tool_code/gen/generate/function_sync.js b/napi_tool/code/tool_code/gen/generate/function_sync.js new file mode 100644 index 0000000000000000000000000000000000000000..3cfcd7dd4af371e049feb291700666fd2c781287 --- /dev/null +++ b/napi_tool/code/tool_code/gen/generate/function_sync.js @@ -0,0 +1,150 @@ +/* +* Copyright (c) 2021 Shenzhen Kaihong Digital Industry Development 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 { ReplaceAll, print } = require("../tools/tool"); +const { ParamGenerate } = require("./param_generate"); +const { ReturnGenerate } = require("./return_generate"); +/**结果通过同步回调(CallBack)返回 */ +let func_sync_templete = ` +struct [func_name]_value_struct {[value_in] + + [value_out] +}; + +[static_define]napi_value [func_name]_middle(napi_env env, napi_callback_info info) +{ + XNapiTool *pxt = std::make_unique(env, info).release(); + if (pxt->IsFailed()) + { + napi_value err = pxt->GetError(); + delete pxt; + return err; + } + [unwarp_instance] + + struct [func_name]_value_struct *vio=new [func_name]_value_struct(); + + [value_checkout] + + [call_func] + + [value_package] + + { + napi_value args[1] = {result}; + pxt->SyncCallBack(pxt->GetArgv([callback_param_offset]), 1, args); + } + result = pxt->UndefinedValue(); + + delete vio; + if (pxt->IsFailed()) + result = pxt->GetError(); + delete pxt;// release + return result; +}` + +function GenerateFunctionSync(func, class_name) { + // this.len_to = 0 + // // print(type, name, values, ret_type) + let middle_func = ReplaceAll(func_sync_templete, "[func_name]", func.name) + if(class_name==null) + { + middle_func=middle_func.ReplaceAll("[static_define]","") + middle_func=middle_func.ReplaceAll("[unwarp_instance]","") + } + else + { + middle_func=middle_func.ReplaceAll("[static_define]","static ") + middle_func=middle_func.ReplaceAll("[unwarp_instance]","%s *pInstance = (%s *)pxt->UnWarpInstance();".format(class_name,class_name)) + } + let param = { + value_in: "",//定义输入 + value_out: "",//定义输出 + + value_checkout: "",//解析 + value_fill: "",//填充到函数内 + value_package: "",//输出参数打包 + value_define: ""//impl参数定义 + } + + for (let i in func.value) { + let v = func.value[i] + ParamGenerate(i, v.name, v.type, param) + } + + // ReturnGenerate(func.ret, param) + ReturnGenerate(param.callback.type, param) + + middle_func = ReplaceAll(middle_func, "[value_in]", param.value_in)// # 输入参数定义 + middle_func = ReplaceAll(middle_func, "[value_out]", param.value_out)// # 输出参数定义 + + middle_func = ReplaceAll(middle_func, "[value_checkout]", param.value_checkout)// # 输入参数解析 + + let call_func = "%s%s(%s);".format(class_name==null?"":"pInstance->",func.name, param.value_fill) + middle_func = ReplaceAll(middle_func, "[call_func]", call_func)//执行 + + middle_func = ReplaceAll(middle_func, "[value_package]", param.value_package)//输出参数打包 + + middle_func = middle_func.ReplaceAll("[callback_param_offset]", param.callback.offset);//呼叫回调 + + // if (type == (FuncType.ASYNC | FuncType.PROMISE)) { + // this.generate_value_out(this.callback_type) + // middle_func = ReplaceAll(middle_func, "[call_static_func]", + // ` + // napi_value result = pxt->StartAsync(%s_execute, vio, %s_complete, pxt->GetArgc() == %s ? pxt->GetArgv(%d) : nullptr);`.format + // (name, name, this.callback_offet + 1, this.callback_offet)) + // middle_func = ReplaceAll(middle_func, " delete vio;", "") + // middle_func = ReplaceAll(middle_func, " delete pxt;// release", "") + // let ttt = ReplaceAll(codestring.func_promise, "[func_name]", name) + // let call_func; + + // if (cvs == null) + // call_func = "%s::%s(%s);".format(this.declare_name, name, param["value_call"]) + // else + // call_func = "%s::%s(%s);".format(cvs[0], cvs[1], param["value_call"]) + // // print(call_func) + // ttt = ReplaceAll(ttt, "[call_static_func]", call_func) + // print("=====1======") + // let ttt2 = "napi_value result = nullptr;\n%s".format(this.c_to_js("vio->out", this.callback_type, "result")) + // // print(this.callback_type) + // print("=====2======") + // ttt = ReplaceAll(ttt, "[promise_arg]", "%s napi_value args[1] = {result,};".format(ttt2)) + // middle_func = middle_func.replace("};", ttt) + // } + + + // if (ret_type == "void" && type != (FuncType.ASYNC | FuncType.PROMISE)) + // param["value_package"] = "napi_value result = XNapiTool::UndefinedValue(env);" + + // middle_func = ReplaceAll(middle_func, "[value_out]", param["value_out"]) + // if (type != (FuncType.ASYNC | FuncType.PROMISE)) + // middle_func = ReplaceAll(middle_func, "[value_package]", param["value_package"]) + // else + // middle_func = ReplaceAll(middle_func, "[value_package]", "") + + // if (cvs == null) { + let impl_h = "\nbool %s(%s);".format(func.name, param.value_define) + let impl_cpp = ` +bool %s%s(%s) { + // TODO + return true; +} +`.format(class_name==null?"":class_name+"::",func.name, param.value_define) + + return [middle_func, impl_h, impl_cpp] +} + +module.exports = { + GenerateFunctionSync +} \ No newline at end of file diff --git a/napi_tool/code/tool_code/gen/generate/interface.js b/napi_tool/code/tool_code/gen/generate/interface.js new file mode 100644 index 0000000000000000000000000000000000000000..49a043ca9812975407cbbf70237833ee944c9071 --- /dev/null +++ b/napi_tool/code/tool_code/gen/generate/interface.js @@ -0,0 +1,161 @@ +/* +* Copyright (c) 2021 Shenzhen Kaihong Digital Industry Development 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 { print } = require("../tools/tool"); +const { GenerateFunctionDirect } = require("./function_direct"); +const { GenerateFunctionSync } = require("./function_sync"); +const { GenerateFunctionAsync } = require("./function_async"); +const { FuncType, InterfaceList, get_array_type } = require("../tools/common"); +const { js_to_c } = require("./param_generate"); +const { c_to_js } = require("./return_generate"); +const re = require("../tools/re"); + +let middle_body_tmplete = ` +class [class_name]_middle { +public: +static napi_value constructor(napi_env env, napi_callback_info info) +{ + XNapiTool *pxt = new XNapiTool(env, info); + + [class_name] *p = new [class_name](); + // printf("static constructor %x\\n", p); + + napi_value thisvar = pxt->WrapInstance(p, release); + + return thisvar; +} +static void release(void *p) +{ + // printf("test2 released\\n"); + [class_name] *p2 = ([class_name] *)p; + delete p2; +} +[static_funcs] +};` + +function GenerateVariable(name, type, variable, class_name) { + if (type == "string") variable.h_define += "\n std::string %s;".format(name) + else if (type.substring(0, 12) == "NUMBER_TYPE_") variable.h_define += "\n %s %s;".format(type, name) + else if (InterfaceList.GetValue(type)) variable.h_define += "\n %s %s;".format(type, name) + else if (type.indexOf("Array<") == 0) { + let type2 = get_array_type(type) + if (type2 == "string") type2 = "std::string" + variable.h_define += "\n std::vector<%s> %s;".format(type2, name) + } + else + print(` +---- GenerateVariable fail %s,%s ---- +`.format(name, type)) + //todo + variable.middle_value += ` + static napi_value getvalue_%s(napi_env env, napi_callback_info info) + { + XNapiTool *pxt = std::make_unique(env, info).release(); + %s *p = (%s *)pxt->UnWarpInstance(); + napi_value result; + `.format(name, class_name, class_name) + c_to_js("p->" + name, type, "result") + ` + delete pxt; + return result; + } + static napi_value setvalue_%s(napi_env env, napi_callback_info info) + { + std::shared_ptr pxt = std::make_shared(env, info); + %s *p = (%s *)pxt->UnWarpInstance(); + `.format(name, class_name, class_name) + js_to_c("p->" + name, "pxt->GetArgv(0)", type) + ` + return nullptr; + } +` +} + +function GenerateInterface(name, data, in_namespace) { + let impl_h = "" + let impl_cpp = "" + let middle_func = "" + let middle_init = "" + let variable = { + h_define: "", + middle_value: "", + } + + middle_init = `{\n std::map> valueList;` + for (let i in data.value) { + let v = data.value[i] + // print(v) + GenerateVariable(v.name, v.type, variable, name) + middle_init += ` + valueList["%s"]["getvalue"]=%s%s_middle::getvalue_%s; + valueList["%s"]["setvalue"]=%s%s_middle::setvalue_%s;`.format(v.name, in_namespace, name, v.name, v.name, in_namespace, name, v.name) + } + impl_h += variable.h_define + middle_func += variable.middle_value + // + // + middle_init += `\n std::map funcList;` + for (let i in data.function) { + let func = data.function[i] + // print(func) + let tmp; + switch (func.type) { + case FuncType.DIRECT: + tmp = GenerateFunctionDirect(func, name) + break; + case FuncType.SYNC: + tmp = GenerateFunctionSync(func, name) + break + case FuncType.ASYNC: + case FuncType.PROMISE: + tmp = GenerateFunctionAsync(func, name) + break + default: + //to do yichangchuli + return + } + middle_func += tmp[0] + impl_h += tmp[1] + impl_cpp += tmp[2] + + middle_init += `\n funcList["%s"] = %s%s_middle::%s_middle;`.format(func.name, in_namespace, name, func.name) + } + + let self_ns="" + if (in_namespace.length > 0) { + let nsl = in_namespace.split("::") + nsl.pop() + if (nsl.length >= 2) { + self_ns = ", "+nsl[nsl.length - 1] + } + } + middle_init += `\n pxt->DefineClass("%s", %s%s_middle::constructor, valueList ,funcList%s);\n}\n`.format(name, in_namespace, name, self_ns) + + let result = { + impl_h: ` +class %s { +public:%s +};`.format(name, impl_h), + impl_cpp: impl_cpp, + middle_body: middle_body_tmplete.ReplaceAll("[class_name]", name).ReplaceAll("[static_funcs]", middle_func), + middle_init: middle_init + } + // print("----------------------------") + // print(result.impl_h) + // print("----------------------------") + // print(result.impl_cpp) + // print("----------------------------") + // print(result.middle_body) + return result +} + +module.exports = { + GenerateInterface +} \ No newline at end of file diff --git a/napi_tool/code/tool_code/gen/generate/namespace.js b/napi_tool/code/tool_code/gen/generate/namespace.js new file mode 100644 index 0000000000000000000000000000000000000000..515c53b774c2713ade6e7c44f733880c3f3a4aac --- /dev/null +++ b/napi_tool/code/tool_code/gen/generate/namespace.js @@ -0,0 +1,118 @@ +/* +* Copyright (c) 2021 Shenzhen Kaihong Digital Industry Development 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 { print } = require("../tools/tool"); +const { GenerateFunctionDirect } = require("./function_direct"); +const { GenerateFunctionSync } = require("./function_sync"); +const { GenerateFunctionAsync } = require("./function_async"); +const { GenerateInterface } = require("./interface"); +const { FuncType, InterfaceList } = require("../tools/common"); + +function GenerateNamespace(name, data, in_namespace = "") { + // print(name) + // print(data) + // print(in_namespace) + // print(JSON.stringify(result, null, 4)) + //生成module_middle.cpp + //生成module.h + //生成module.cpp + + let impl_h = "" + let impl_cpp = "" + let middle_func = "" + let middle_init = "" + + if (in_namespace.length > 0) { + let nsl = in_namespace.split("::") + nsl.pop() + let parent_ns = nsl[nsl.length - 1] + // print("parent=", parent_ns) + middle_init = `{\nnapi_value %s=pxt->CreateSubObject(%s,"%s");\n`.format(name, nsl.length == 1 ? "exports" : parent_ns, name) + } + + InterfaceList.Push(data.interface) + // InterfaceList.GetValue("TestClass1") + for (let i in data.interface) { + let ii = data.interface[i] + // print(ii) + let result = GenerateInterface(ii.name, ii.body, in_namespace + name + "::") + + middle_func += result.middle_body + impl_h += result.impl_h + impl_cpp += result.impl_cpp + middle_init += result.middle_init + } + + for (let i in data.function) { + let func = data.function[i] + // print(func) + let tmp; + switch (func.type) { + case FuncType.DIRECT: + tmp = GenerateFunctionDirect(func) + break; + case FuncType.SYNC: + tmp = GenerateFunctionSync(func) + break + case FuncType.ASYNC: + case FuncType.PROMISE: + tmp = GenerateFunctionAsync(func) + break + default: + // to do yichangchuli + return + } + middle_func += tmp[0] + impl_h += tmp[1] + impl_cpp += tmp[2] + middle_init += ' pxt->DefineFunction("%s", %s%s::%s_middle%s);\n'.format(func.name, in_namespace, name, func.name, in_namespace.length > 0 ? ", "+name : "") + } + + for (let i in data.namespace) { + let ns = data.namespace[i] + // print(ns) + let result = GenerateNamespace(ns.name, ns.body, in_namespace + name + "::") + middle_func += result.middle_body + impl_h += result.impl_h + impl_cpp += result.impl_cpp + middle_init += result.middle_init + } + InterfaceList.Pop(); + + if (in_namespace.length > 0) { + middle_init += "}" + } + let result = { + impl_h: ` +namespace %s { +%s +}`.format(name, impl_h), + impl_cpp: ` +namespace %s { +%s +} +`.format(name, impl_cpp), + middle_body: ` +namespace %s { +%s +} +`.format(name, middle_func), + middle_init: middle_init + } + return result +} + +module.exports = { + GenerateNamespace +} \ No newline at end of file diff --git a/napi_tool/code/tool_code/gen/generate/param_generate.js b/napi_tool/code/tool_code/gen/generate/param_generate.js new file mode 100644 index 0000000000000000000000000000000000000000..42305a8ac7d4c4384675e3724ea9244f9b893ae6 --- /dev/null +++ b/napi_tool/code/tool_code/gen/generate/param_generate.js @@ -0,0 +1,153 @@ +/* +* Copyright (c) 2021 Shenzhen Kaihong Digital Industry Development 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 { ReplaceAll, print } = require("../tools/tool"); +const { InterfaceList, get_array_type } = require("../tools/common"); +const re = require("../tools/re"); + +class LenIncrease { } +LenIncrease.LEN_TO = 1; +LenIncrease.Reset = function () { + LenIncrease.LEN_TO = 1; +} +LenIncrease.GetAndIncrease = function () { + return LenIncrease.LEN_TO++; +} + +function get_value_property(napi_vn, name) { + return 'pxt->GetValueProperty(%s, "%s")'.format(napi_vn, name) +} + +function js_to_c(dest, napi_vn, type) { + if (type == "string") { + if (napi_vn.indexOf("GetValueProperty") >= 0) { + let lt = LenIncrease.GetAndIncrease() + return `napi_value tnv%d = %s;\n if(tnv%d!=nullptr){pxt->SwapJs2CUtf8(tnv%d,%s);}`.format(lt, napi_vn, lt, lt, dest) + } + else + return "pxt->SwapJs2CUtf8(%s, %s);".format(napi_vn, dest) + } + else if (type.substring(0, 12) == "NUMBER_TYPE_") { + if (napi_vn.indexOf("GetValueProperty") >= 0) { + let lt = LenIncrease.GetAndIncrease() + return `napi_value tnv%d = %s;\n if(tnv%d!=nullptr){NUMBER_JS_2_C(tnv%d,%s,%s);}`.format(lt, napi_vn, lt, lt, type, dest) + } + else + return `NUMBER_JS_2_C(%s,%s,%s);`.format(napi_vn, type, dest) + } + else if (InterfaceList.GetValue(type)) { + let tt = "" + let ifl = InterfaceList.GetValue(type) + for (let i in ifl) { + let name2 = ifl[i].name + let type2 = ifl[i].type + tt += js_to_c("%s.%s".format(dest, name2), get_value_property(napi_vn, name2), type2) + } + return tt + } + else if (type.indexOf("Array<") == 0) { + let array_type = get_array_type(type) + let lt = LenIncrease.GetAndIncrease() + if (array_type == "string") array_type = "std::string" + let arr_templete = `\ + uint32_t len[replace_lt]=pxt->GetArrayLength(%s); + for(uint32_t i[replace_lt]=0;i[replace_lt]GetArrayElement(%s,i%d),%s,tt%d);".format(napi_vn, lt, array_type, lt)) + } + else if (array_type == "std::string") { + arr_templete = arr_templete.ReplaceAll("[replace_swap]", + "pxt->SwapJs2CUtf8(pxt->GetArrayElement(%s,i%d), tt%d);".format(napi_vn, lt, lt)) + } + else if (InterfaceList.GetValue(array_type)) { + arr_templete = arr_templete.ReplaceAll("[replace_swap]", + js_to_c("tt" + lt, "pxt->GetArrayElement(%s,i%d)".format(napi_vn, lt), array_type)) + } + return arr_templete; + } + else + print(`\n---- generate js_to_c fail %s,%s,%s ----\n`.format(dest, napi_vn, type)) +} + +function ParamCheckout(name, napi_vn, type) { + if (type in this.interface_list) { + for (let i in this.interface_list[type]) { + let e = this.interface_list[type][i] + let name2 = Object.keys(e)[0] + let type2 = e[name2] + this.values_["value_analyze"] += "%s%s".format(new_line(this.values_["value_analyze"]), + this.js_to_c("%s.%s".format(name, name2), + this.get_value_property(napi_vn, name2), + type2)) + } + } + else if (type.substring(0, 12) == "NUMBER_TYPE_" || type == "string" || type.substring(0, 6) == "Array<") + this.values_["value_analyze"] += "%s%s".format(new_line(this.values_["value_analyze"]), + this.js_to_c(name, napi_vn, type)) +} + +//函数的参数处理 +function ParamGenerate(p, name, type, param) { + if (type == "string") { + param.value_in += "\n std::string in%d;".format(p) + param.value_checkout += js_to_c("vio->in" + p, "pxt->GetArgv(%d)".format(p), type) + param.value_fill += "%svio->in%d".format(param.value_fill.length > 0 ? ", " : "", p) + param.value_define += "%sstd::string &%s".format(param.value_define.length > 0 ? ", " : "", name) + } + else if (type.substring(0, 12) == "NUMBER_TYPE_") { + param.value_in += "\n %s in%d;".format(type, p) + param.value_checkout += js_to_c("vio->in" + p, "pxt->GetArgv(%d)".format(p), type) + param.value_fill += "%svio->in%d".format(param.value_fill.length > 0 ? ", " : "", p) + param.value_define += "%s%s &%s".format(param.value_define.length > 0 ? ", " : "", type, name) + } + else if (InterfaceList.GetValue(type)) { + param.value_in += "\n %s in%d;".format(type, p) + param.value_checkout += js_to_c("vio->in" + p, "pxt->GetArgv(%d)".format(p), type) + // this.ParamCheckout("vio->in%d".format(p), "pxt->GetArgv(%d)".format(p), type) + param.value_fill += "%svio->in%d".format(param.value_fill.length > 0 ? ", " : "", p) + param.value_define += "%s%s &%s".format(param.value_define.length > 0 ? ", " : "", type, name) + } + else if (type.substring(0, 6) == "Array<") { + let array_type = get_array_type(type) + if (array_type == "string") array_type = "std::string" + param.value_in += "\n std::vector<%s> in%d;".format(array_type, p) + param.value_checkout += js_to_c("vio->in" + p, "pxt->GetArgv(%d)".format(p), type) + // this.ParamCheckout("vio->in%d".format(p), "pxt->GetArgv(%d)".format(p), type) + param.value_fill += "%svio->in%d".format(param.value_fill.length > 0 ? ", " : "", p) + param.value_define += "%sstd::vector<%s> &%s".format(param.value_define.length > 0 ? ", " : "", array_type, name) + } + else if (type.substring(0, 9) == "Callback<" || type.substring(0, 14) == "AsyncCallback<") { + let tt = re.match("(Async)*Callback<([a-zA-Z_0-9]+)>", type) + param.callback = { + type: re.get_reg(type, tt.regs[2]), + offset: p + } + } + + + else + print("param generate err :", name, "type :", type) +} + +module.exports = { + js_to_c, + ParamGenerate +} \ No newline at end of file diff --git a/napi_tool/code/tool_code/gen/generate/return_generate.js b/napi_tool/code/tool_code/gen/generate/return_generate.js new file mode 100644 index 0000000000000000000000000000000000000000..d3388624390a2c567732b0d7612d69f7d67e6425 --- /dev/null +++ b/napi_tool/code/tool_code/gen/generate/return_generate.js @@ -0,0 +1,126 @@ +/* +* Copyright (c) 2021 Shenzhen Kaihong Digital Industry Development 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 { ReplaceAll, print } = require("../tools/tool"); +const { InterfaceList, get_array_type } = require("../tools/common"); + +function c_to_js(value, type, dest, deep = 1) { + // print(value, type, dest) + if (type == "void") + return "%s = pxt->UndefinedValue();".format(dest); + else if (type == "boolean") + return "%s = pxt->SwapC2JsBool(%s);".format(dest, value); + else if (type == "string") + return `%s = pxt->SwapC2JsUtf8(%s.c_str());`.format(dest, value) + else if (type.substring(0, 12) == "NUMBER_TYPE_") + return `%s = NUMBER_C_2_JS(pxt, %s);`.format(dest, value) + else if (InterfaceList.GetValue(type)) { + let lt = deep + let tt = "" + let ifl = InterfaceList.GetValue(type) + for (let i in ifl) { + let name2 = ifl[i].name + let type2 = ifl[i].type + let tt1 = c_to_js("%s.%s".format(value, name2), type2, "tnv%d".format(lt), deep + 1) + tt += "{\nnapi_value tnv%d = nullptr;\n".format(lt) + tt1 + `\npxt->SetValueProperty(%s,"%s",tnv%d);\n}`.format( + dest, name2, lt) + } + return tt + } + else if (type.substring(0, 6) == "Array<") { + let array_type = get_array_type(type) + let lt = deep + let tnv = dest + let tnvdef = `uint32_t len%d=%s.size(); + for(uint32_t i=0;iSetArrayElement(%s, i, tnv%d); + }`.format(lt, value, lt, lt, tnv, lt) + let ret = "" + if (array_type.substring(0, 12) == "NUMBER_TYPE_") { + ret = tnvdef.ReplaceAll("[calc_out]", `tnv%d = NUMBER_C_2_JS(pxt,%s[i]);`.format(lt, value)) + } + else if (array_type == "string") { + ret = tnvdef.ReplaceAll("[calc_out]", `tnv%d = pxt->SwapC2JsUtf8(%s[i].c_str());`.format(lt, value)) + } + else if (InterfaceList.GetValue(array_type)) { + ret = tnvdef.ReplaceAll("[calc_out]", c_to_js(value + "[i]", array_type, "tnv" + lt, deep + 1)) + } + return ret + } + else + print(`\n---- generate c_to_js fail %s,%s,%s ----\n`.format(value, type, dest)) +} + +function ReturnGenerate(type, param) { + param.value_fill += "%svio->out".format(param.value_fill.length > 0 ? ", " : "") + param.value_package = "napi_value result = nullptr;\n " + c_to_js("vio->out", type, "result") + if (type == "string") { + param.value_out = "std::string out;" + param.value_define += "%sstd::string &out".format(param.value_define.length > 0 ? ", " : "") + } + else if (type == "void") { + return; + } + else if (type == "boolean") { + param.value_out = "bool out;" + param.value_define += "%sbool &out".format(param.value_define.length > 0 ? ", " : "") + } + else if (type.substring(0, 12) == "NUMBER_TYPE_") { + param.value_out = type + " out;" + param.value_define += "%s%s &out".format(param.value_define.length > 0 ? ", " : "", type) + // this.values_["value_call"] += "%svio->out".format(len(this.values_["value_call"]) > 0 ? ", " : "") + // this.generate_value_package("vio->out", type) + // this.values_["value_out"] = "%s out;".format(type) + // this.values_["value_define"] += "%s%s &out".format( + // len(this.values_["value_define"]) > 0 ? ", " : "", type) + } + else if (InterfaceList.GetValue(type)) { + param.value_out = type + " out;" + param.value_define += "%s%s &out".format(param.value_define.length > 0 ? ", " : "", type) + } + else if (type.substring(0, 6) == "Array<") { + let array_type = get_array_type(type) + if (array_type == "string") array_type = "std::string" + param.value_out = "std::vector<%s> out;".format(array_type) + param.value_define += "%sstd::vector<%s> &out".format(param.value_define.length > 0 ? ", " : "", array_type) + } + // else if (type in this.interface_list) { + // this.values_["value_call"] += "%svio->out".format(len(this.values_["value_call"]) > 0 ? ", " : "") + // this.generate_value_package("vio->out", type) + // this.values_["value_out"] = "%s out;".format(type) + // this.values_["value_define"] += "%s%s &out".format( + // len(this.values_["value_define"]) > 0 ? ", " : "", type) + // } + + // else if (type.substring(0, 6) == "Array<") { + // let array_type = get_array_type(type) + // if (array_type == "string") array_type = "std::string" + // this.values_["value_call"] += "%svio->out".format(len(this.values_["value_call"]) > 0 ? ", " : "") + // this.generate_value_package("vio->out", type) + // this.values_["value_out"] = "std::vector<%s> out;".formatarray_type + // this.values_["value_define"] += "%sstd::vector<%s> &out".format( + // len(this.values_["value_define"]) > 0 ? ", " : "", array_type) + // } + else { + print(`\n---- ReturnGenerate fail %s ----\n`.format(type)) + } + param.value_fill += "%svio->out".format(param.value_fill.length > 0 ? ", " : "") +} + +module.exports = { + c_to_js, + ReturnGenerate +} \ No newline at end of file diff --git a/napi_tool/code/tool_code/gen/main.js b/napi_tool/code/tool_code/gen/main.js new file mode 100644 index 0000000000000000000000000000000000000000..b47186727269396c7926969e86618db5a1f56285 --- /dev/null +++ b/napi_tool/code/tool_code/gen/main.js @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2021 Shenzhen Kaihong Digital Industry Development 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 vscode = require('vscode'); +const { AnalyzeFile } = require("./analyze"); +const { GenerateAll } = require("./generate"); +const re = require("./tools/re") + +function DoGenerate(ifname) { + // console.log("----------generate start---------") + + let struct_of_ts = AnalyzeFile(ifname); + // print(struct_of_ts) + + GenerateAll(struct_of_ts, re.get_path_in_path(ifname)); + + // console.log("----------generate end---------") +} + +module.exports = { + DoGenerate +} \ No newline at end of file diff --git a/napi_tool/code/tool_code/gen/test.js b/napi_tool/code/tool_code/gen/test.js new file mode 100644 index 0000000000000000000000000000000000000000..5781805969df3ff20db9badf93f0838b0faabfa7 --- /dev/null +++ b/napi_tool/code/tool_code/gen/test.js @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2021 Shenzhen Kaihong Digital Industry Development 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 fs = require("fs"); +const path = require("path"); +const main = require("./main"); +const { print } = require("./tools/tool"); + +main.DoGenerate("nodejs_test/gen/@ohos.napitest.d.ts"); + +// if (1 == 1) { +// main.DoGenerate("nodejs_test/gen/@ohos.napitest.d.ts"); +// } +// else { +// let test_ts_dir = "test_ts/ohos" + +// if (1 == 0) { +// main.DoGenerate(path.join(test_ts_dir, "@ohos.fileio.d.ts")); +// } +// else { +// let files = fs.readdirSync(test_ts_dir) +// for (let i in files) { +// let fn = files[i] +// let gf = path.join(test_ts_dir, fn) +// print("--------------", i, "-----------------") +// print(gf) +// main.DoGenerate(gf); +// // if (i > 20) break +// } +// } +// } + +/** + * run test: + * node vscode_plugin/gnapi/gen/test.js + */ + +// main.DoGenerate("Z:\\napi_test\\@ohos.napitest.d.ts"); + +// main.DoGenerate("Z:\\l1\\foundation\\communication\\cx_test\\napi_test\\@ohos.xtestx.d.ts"); \ No newline at end of file diff --git a/napi_tool/code/tool_code/gen/tools/FileRW.js b/napi_tool/code/tool_code/gen/tools/FileRW.js new file mode 100644 index 0000000000000000000000000000000000000000..8364266179a81f3c9f06744eeb0522559fd8686e --- /dev/null +++ b/napi_tool/code/tool_code/gen/tools/FileRW.js @@ -0,0 +1,133 @@ +/* +* Copyright (c) 2021 Shenzhen Kaihong Digital Industry Development 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 fs = require('fs'); + +function Utf8ArrayToStr(array) { + var out, i, len, c; + var char2, char3; + + out = ""; + len = array.length; + i = 0; + while(i < len) { + c = array[i++]; + switch(c >> 4) + { + case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: + // 0xxxxxxx + out += String.fromCharCode(c); + break; + case 12: case 13: + // 110x xxxx 10xx xxxx + char2 = array[i++]; + out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F)); + break; + case 14: + // 1110 xxxx 10xx xxxx 10xx xxxx + char2 = array[i++]; + char3 = array[i++]; + out += String.fromCharCode(((c & 0x0F) << 12) | + ((char2 & 0x3F) << 6) | + ((char3 & 0x3F) << 0)); + break; + } + } + + return out; +} + +function stringToUint8Array(string, options={stream: false}) { + if (options.stream) { + throw new Error(`Failed to encode: the 'stream' option is unsupported.`); + } + + let pos = 0; + const len = string.length; + const out = []; + + let at = 0; // output position + let tlen = Math.max(32, len + (len >> 1) + 7); // 1.5x size + let target = new Uint8Array((tlen >> 3) << 3); // ... but at 8 byte offset + + while (pos < len) { + let value = string.charCodeAt(pos++); + if (value >= 0xd800 && value <= 0xdbff) { + // high surrogate + if (pos < len) { + const extra = string.charCodeAt(pos); + if ((extra & 0xfc00) === 0xdc00) { + ++pos; + value = ((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000; + } + } + if (value >= 0xd800 && value <= 0xdbff) { + continue; // drop lone surrogate + } + } + + // expand the buffer if we couldn't write 4 bytes + if (at + 4 > target.length) { + tlen += 8; // minimum extra + tlen *= (1.0 + (pos / string.length) * 2); // take 2x the remaining + tlen = (tlen >> 3) << 3; // 8 byte offset + + const update = new Uint8Array(tlen); + update.set(target); + target = update; + } + + if ((value & 0xffffff80) === 0) { // 1-byte + target[at++] = value; // ASCII + continue; + } else if ((value & 0xfffff800) === 0) { // 2-byte + target[at++] = ((value >> 6) & 0x1f) | 0xc0; + } else if ((value & 0xffff0000) === 0) { // 3-byte + target[at++] = ((value >> 12) & 0x0f) | 0xe0; + target[at++] = ((value >> 6) & 0x3f) | 0x80; + } else if ((value & 0xffe00000) === 0) { // 4-byte + target[at++] = ((value >> 18) & 0x07) | 0xf0; + target[at++] = ((value >> 12) & 0x3f) | 0x80; + target[at++] = ((value >> 6) & 0x3f) | 0x80; + } else { + // FIXME: do we care + continue; + } + + target[at++] = (value & 0x3f) | 0x80; + } + + return target.slice(0, at); + } + +function ReadFile(fn) +{ + if (!fs.existsSync(fn)) + { + return ""; + } + let data=fs.readFileSync(fn); + data=Utf8ArrayToStr(data); + return data; +} +function WriteFile(fn,str) +{ + let data=stringToUint8Array(str); + fs.writeFileSync(fn, data); +} + +module.exports = { + ReadFile, + WriteFile +} \ No newline at end of file diff --git a/napi_tool/code/tool_code/gen/tools/common.js b/napi_tool/code/tool_code/gen/tools/common.js new file mode 100644 index 0000000000000000000000000000000000000000..1756ba2baeb122c7f55198b0bbb52e7fe3f711d5 --- /dev/null +++ b/napi_tool/code/tool_code/gen/tools/common.js @@ -0,0 +1,70 @@ +/* +* Copyright (c) 2021 Shenzhen Kaihong Digital Industry Development 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 re = require("./re"); + +class FuncType { } +FuncType.DIRECT = 1 +FuncType.SYNC = 2 +FuncType.ASYNC = 4 +FuncType.PROMISE = 8 +FuncType.ToString = function (type) { + if (type == FuncType.DIRECT) return "DIRECT"; + else if (type == FuncType.SYNC) return "SYNC"; + else if (type == FuncType.ASYNC) return "ASYNC"; + else if (type == FuncType.PROMISE) return "PROMISE"; + return "UNKNOW"; +} + +class NumberIncrease { } +NumberIncrease.num = 1 +NumberIncrease.GetAndIncrease = function () { + return NumberIncrease.num++; +} +NumberIncrease.Get = function () { + return NumberIncrease.num; +} +NumberIncrease.Reset = function () { + NumberIncrease.num = 1 +} + +class InterfaceList { } +InterfaceList.interfacess_ = []; +InterfaceList.Push = function (ifs) { + InterfaceList.interfacess_.push(ifs) +} +InterfaceList.Pop = function () { + InterfaceList.interfacess_.pop() +} +InterfaceList.GetValue = function (name) { + let ifs = InterfaceList.interfacess_[InterfaceList.interfacess_.length - 1] + for (let i in ifs) { + if (ifs[i].name == name) { + return ifs[i].body.value; + } + } + return null; +} + +function get_array_type(type) { + let tt = re.match("Array<([a-zA-Z_0-9]+)>", type) + return re.get_reg(type, tt.regs[1]) +} + +module.exports = { + FuncType, + NumberIncrease, + InterfaceList, + get_array_type +} \ No newline at end of file diff --git a/napi_tool/code/tool_code/gen/tools/re.js b/napi_tool/code/tool_code/gen/tools/re.js new file mode 100644 index 0000000000000000000000000000000000000000..eca48f8e7cf7795a8a39e90b6f214f9dd4b4ac1c --- /dev/null +++ b/napi_tool/code/tool_code/gen/tools/re.js @@ -0,0 +1,109 @@ +/* +* Copyright (c) 2021 Shenzhen Kaihong Digital Industry Development 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'); + +function print(...args) { + console.log(...args) +} + +function search(ss, data) { + ss = replace_all(ss, "\\.", "\\.") + let reg = new RegExp(ss); + let tt = reg.exec(data); + // print("#############") + // print(tt) + // print("#############") + if (tt == null) return null; + let ret = { "regs": [] } + for (let i = 0; i < tt.length; i++) { + let p = data.indexOf(tt[i]); + if (tt[i] == null) { + ret["regs"].push([-1, -1]) + } + else { + ret["regs"].push([p, p + tt[i].length]) + } + } + + return ret; +} + +function match(ss, data) { + let tt = search(ss, data) + if (tt != null && tt.regs[0][0] == 0) return tt; + return null; +} + +function remove_reg(data, reg) { + return data.substring(0, reg[0]) + data.substring(reg[1], data.length) +} + +function get_reg(data, reg) { + return data.substring(reg[0], reg[1]) +} + +function get_file_in_path(tpath) { + return path.parse(tpath).base; + // for(let i=tpath.length-1;i>=0;i--) + // { + // if(tpath[i]=='\\' || tpath[i]=='/') + // return tpath.substring(i+1,tpath.length); + // } + // return tpath; +} + +function get_path_in_path(tpath) { + return path.parse(tpath).dir; + // for(let i=tpath.length-1;i>=0;i--) + // { + // if(tpath[i]=='\\' || tpath[i]=='/') + // return tpath.substring(0,i); + // } + // return tpath; +} + +function all(sfrom) { + return new RegExp(sfrom, "g"); +} + +function replace_all(ss, sfrom, sto) { + return ss.replace(all(sfrom), sto) +} + +function path_join(...args) { + return path.join(...args) + // let ret="" + // for (let i=0;i0) + // { + // if(ret[ret.length-1]!="/" && ret[ret.length-1]!="\\")ret+="\\" + // } + // ret+=args[i]; + // } + // return ret +} + +module.exports = { + search, + match, + remove_reg, + get_reg, + get_file_in_path, + get_path_in_path, + path_join, + replace_all, + all +} \ No newline at end of file diff --git a/napi_tool/code/tool_code/gen/tools/tool.js b/napi_tool/code/tool_code/gen/tools/tool.js new file mode 100644 index 0000000000000000000000000000000000000000..bb9b2f54ab73ac8a9c04bbd0d7115db8bf5ca345 --- /dev/null +++ b/napi_tool/code/tool_code/gen/tools/tool.js @@ -0,0 +1,177 @@ +/* +* Copyright (c) 2021 Shenzhen Kaihong Digital Industry Development 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 re = require("./re"); +let vscode=null; +try { + vscode = require('vscode'); +} +catch (err) { + vscode = null; +} + +function print(...args) { + if(vscode) + { + vscode.window.showInformationMessage(...args); + } + console.log(...args) +} + +String.prototype.format = function (...args) { + var result = this; + let reg = new RegExp("%[sd]{1}") + // print(result) + // print(args) + for (let i = 0; i < args.length; i++) { + let p = result.search(reg) + if (p < 0) break; + result = result.substring(0, p) + args[i] + result.substring(p + 2, result.length) + // print(i,result,0) + } + return result; +} + +String.prototype.ReplaceAll = function (...args) { + let result = this; + while (result.indexOf(args[0]) >= 0) { + result = result.replace(args[0], args[1]) + } + return result; +} + +function CheckOutBody(body, off, flag, binside) { + off = off || 0; + flag = flag || ["{", "}"]; + binside = binside || false; + let idx = { + "(": ")", + "{": "}", + "<": ">", + //"<": "<", + ">": ">", + }; + let csl = {}; + let csr = {}; + for (let f in idx) { + csl[f] = 0 + csr[idx[f]] = 0 + } + let cs1 = 0 + if (flag[0].length > 0 && body.substring(off, off + flag[0].length) != flag[0]) { + return null; + } + + for (let i = off + flag[0].length; i < body.length; i++) { + // print(body[i]) + if (body[i] == '"') cs1 += 1 + if (cs1 % 2 != 0) continue + + // print(i,csl,csr) + let tb1 = true; + for (let k in csl) { + if (csl[k] != csr[idx[k]]) { + tb1 = false; + break; + } + } + if (tb1) { + // # print("i=",i,body[i:i + len(flag[1])]) + if (body.substring(i, i + flag[1].length) == flag[1]) { + if (binside) + return body.substring(off + flag[0].length, i); + return body.substring(off, i + flag[1].length); + } + } + + if (body[i] in csl) { + csl[body[i]] += 1; + if (body[i] in csr) csr[body[i]] += 1; + continue; + } + if (body[i] in csr) { + csr[body[i]] += 1; + continue; + } + } + + return null; +} + + +function RemoveExplains(data) { + while (data.indexOf("/*") >= 0) { + let i1 = data.indexOf("/*") + let i2 = data.indexOf("*/") + 2 + // # print(data[i1:i2]) + data = data.substring(0, i1) + data.substring(i2, data.length) + // # print("------------------------------------------------------------------------------") + } + while (true) { + let tt = re.search("\n *//([a-zA-Z .]+)\n", data) + // print(tt) + if (tt != null) { + // # print("help",data[tt.regs[1][0]:tt.regs[1][1]]) + data = data.substring(0, tt.regs[0][0]) + data.substring(tt.regs[0][1], data.length) + } + else break; + } + return data +} + +function RemoveEmptyLine(data) { + while (data.indexOf("\r") >= 0) { + data = data.replace("\r", "") + } + while (data.indexOf(" \n") >= 0) { + data = data.replace(" \n", "\n") + } + while (data.indexOf("\n ") >= 0) { + data = data.replace("\n ", "\n") + } + while (data.indexOf("\n\n") >= 0) { + data = data.replace("\n\n", "\n") + } + while (data.indexOf("\n") == 0) { + data = data.substring(1, data.length) + } + while (data.indexOf(" ") == 0) { + data = data.substring(1, data.length) + } + return data +} + +function RemoveEmptyLine2(data) { + while (data.indexOf(" \n")) + data = data.replace(" \n", "\n") + while (data.indexOf("\n\n\n")) + data = data.replace("\n\n\n", "\n\n") + return data +} + +function ReplaceAll(s, sfrom, sto) { + while (s.indexOf(sfrom) >= 0) { + s = s.replace(sfrom, sto) + } + return s; +} + +module.exports = { + CheckOutBody, + RemoveExplains, + RemoveEmptyLine, + RemoveEmptyLine2, + ReplaceAll, + print +} \ No newline at end of file diff --git a/napi_tool/code/tool_code/jsconfig.json b/napi_tool/code/tool_code/jsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..53b981c57b79a7a2dac9995ee4ce04b8c94e0b17 --- /dev/null +++ b/napi_tool/code/tool_code/jsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "ES2020", + "checkJs": true, /* Typecheck .js files. */ + "lib": [ + "ES2020" + ] + }, + "exclude": [ + "node_modules" + ] +} diff --git a/napi_tool/code/tool_code/package-lock.json b/napi_tool/code/tool_code/package-lock.json new file mode 100644 index 0000000000000000000000000000000000000000..0bd5a54fe2964ee8ba9c397982c613ec347fd68d --- /dev/null +++ b/napi_tool/code/tool_code/package-lock.json @@ -0,0 +1,2244 @@ +{ + "name": "gnapi", + "version": "0.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@discoveryjs/json-ext": { + "version": "0.5.6", + "resolved": "https://repo.huaweicloud.com/repository/npm/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz", + "integrity": "sha512-ws57AidsDvREKrZKYffXddNkyaF14iHNHm8VQnZH6t99E8gczjNN0GpvcGny0imC80yQ0tHz1xVUKk/KFQSUyA==", + "dev": true + }, + "@eslint/eslintrc": { + "version": "1.0.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/@eslint/eslintrc/-/eslintrc-1.0.4.tgz", + "integrity": "sha512-h8Vx6MdxwWI2WM8/zREHMoqdgLNXEL4QX3MWSVMdyNJGvXVOs+6lp+m2hc3FnuMHDc4poxFNI20vCk0OmI4G0Q==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.0.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + } + }, + "@humanwhocodes/config-array": { + "version": "0.6.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@humanwhocodes/config-array/-/config-array-0.6.0.tgz", + "integrity": "sha512-JQlEKbcgEUjBFhLIF4iqM7u/9lwgHRBcpHrmUNCALK0Q3amXN6lxdoXLnF0sm11E9VqTmBALR87IlUg1bZ8A9A==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true + }, + "@types/eslint": { + "version": "8.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@types/eslint/-/eslint-8.2.0.tgz", + "integrity": "sha512-74hbvsnc+7TEDa1z5YLSe4/q8hGYB3USNvCuzHUJrjPV6hXaq8IXcngCrHkuvFt0+8rFz7xYXrHgNayIX0UZvQ==", + "dev": true, + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/eslint-scope": { + "version": "3.7.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@types/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g==", + "dev": true, + "requires": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "@types/estree": { + "version": "0.0.50", + "resolved": "https://repo.huaweicloud.com/repository/npm/@types/estree/-/estree-0.0.50.tgz", + "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==", + "dev": true + }, + "@types/glob": { + "version": "7.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "requires": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/json-schema": { + "version": "7.0.9", + "resolved": "https://repo.huaweicloud.com/repository/npm/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "dev": true + }, + "@types/minimatch": { + "version": "3.0.5", + "resolved": "https://repo.huaweicloud.com/repository/npm/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, + "@types/mocha": { + "version": "9.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@types/mocha/-/mocha-9.0.0.tgz", + "integrity": "sha512-scN0hAWyLVAvLR9AyW7HoFF5sJZglyBsbPuHO4fv7JRvfmPBMfp1ozWqOf/e4wwPNxezBZXRfWzMb6iFLgEVRA==", + "dev": true + }, + "@types/node": { + "version": "14.17.34", + "resolved": "https://repo.huaweicloud.com/repository/npm/@types/node/-/node-14.17.34.tgz", + "integrity": "sha512-USUftMYpmuMzeWobskoPfzDi+vkpe0dvcOBRNOscFrGxVp4jomnRxWuVohgqBow2xyIPC0S3gjxV/5079jhmDg==", + "dev": true + }, + "@types/vscode": { + "version": "1.62.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@types/vscode/-/vscode-1.62.0.tgz", + "integrity": "sha512-iGlQJ1w5e3qPUryroO6v4lxg3ql1ztdTCwQW3xEwFawdyPLoeUSv48SYfMwc7kQA7h6ThUqflZIjgKAykeF9oA==", + "dev": true + }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "@vscode/test-electron": { + "version": "1.6.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/@vscode/test-electron/-/test-electron-1.6.2.tgz", + "integrity": "sha512-W01ajJEMx6223Y7J5yaajGjVs1QfW3YGkkOJHVKfAMEqNB1ZHN9wCcViehv5ZwVSSJnjhu6lYEYgwBdHtCxqhQ==", + "dev": true, + "requires": { + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "rimraf": "^3.0.2", + "unzipper": "^0.10.11" + } + }, + "@webassemblyjs/ast": { + "version": "1.11.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webassemblyjs/ast/-/ast-1.11.1.tgz", + "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "dev": true, + "requires": { + "@webassemblyjs/helper-numbers": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", + "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.11.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", + "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.11.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", + "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", + "dev": true + }, + "@webassemblyjs/helper-numbers": { + "version": "1.11.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", + "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "dev": true, + "requires": { + "@webassemblyjs/floating-point-hex-parser": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", + "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.11.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", + "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.11.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", + "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.11.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", + "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.11.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", + "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.11.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", + "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/helper-wasm-section": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-opt": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "@webassemblyjs/wast-printer": "1.11.1" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.11.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", + "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.11.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", + "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.11.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", + "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.11.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", + "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "@webpack-cli/configtest": { + "version": "1.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webpack-cli/configtest/-/configtest-1.1.0.tgz", + "integrity": "sha512-ttOkEkoalEHa7RaFYpM0ErK1xc4twg3Am9hfHhL7MVqlHebnkYd2wuI/ZqTDj0cVzZho6PdinY0phFZV3O0Mzg==", + "dev": true + }, + "@webpack-cli/info": { + "version": "1.4.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webpack-cli/info/-/info-1.4.0.tgz", + "integrity": "sha512-F6b+Man0rwE4n0409FyAJHStYA5OIZERxmnUfLVwv0mc0V1wLad3V7jqRlMkgKBeAq07jUvglacNaa6g9lOpuw==", + "dev": true, + "requires": { + "envinfo": "^7.7.3" + } + }, + "@webpack-cli/serve": { + "version": "1.6.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@webpack-cli/serve/-/serve-1.6.0.tgz", + "integrity": "sha512-ZkVeqEmRpBV2GHvjjUZqEai2PpUbuq8Bqd//vEYsp63J8WyexI8ppCqVS3Zs0QADf6aWuPdU+0XsPI647PVlQA==", + "dev": true + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "acorn": { + "version": "8.5.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/acorn/-/acorn-8.5.0.tgz", + "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", + "dev": true + }, + "acorn-import-assertions": { + "version": "1.8.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", + "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://repo.huaweicloud.com/repository/npm/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "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==", + "dev": true + }, + "big-integer": { + "version": "1.6.51", + "resolved": "https://repo.huaweicloud.com/repository/npm/big-integer/-/big-integer-1.6.51.tgz", + "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", + "dev": true + }, + "binary": { + "version": "0.3.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/binary/-/binary-0.3.0.tgz", + "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", + "dev": true, + "requires": { + "buffers": "~0.1.1", + "chainsaw": "~0.1.0" + } + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "bluebird": { + "version": "3.4.7", + "resolved": "https://repo.huaweicloud.com/repository/npm/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://repo.huaweicloud.com/repository/npm/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "browserslist": { + "version": "4.18.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/browserslist/-/browserslist-4.18.1.tgz", + "integrity": "sha512-8ScCzdpPwR2wQh8IT82CA2VgDwjHyqMovPBZSNH54+tm4Jk2pCuv90gmAdH6J84OCRWi0b4gMe6O6XPXuJnjgQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001280", + "electron-to-chromium": "^1.3.896", + "escalade": "^3.1.1", + "node-releases": "^2.0.1", + "picocolors": "^1.0.0" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "buffer-indexof-polyfill": { + "version": "1.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", + "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", + "dev": true + }, + "buffers": { + "version": "0.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=", + "dev": true + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "6.2.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/camelcase/-/camelcase-6.2.1.tgz", + "integrity": "sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001283", + "resolved": "https://repo.huaweicloud.com/repository/npm/caniuse-lite/-/caniuse-lite-1.0.30001283.tgz", + "integrity": "sha512-9RoKo841j1GQFSJz/nCXOj0sD7tHBtlowjYlrqIUS812x9/emfBLBt6IyMz1zIaYc/eRL8Cs6HPUVi2Hzq4sIg==", + "dev": true + }, + "chainsaw": { + "version": "0.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", + "dev": true, + "requires": { + "traverse": ">=0.3.0 <0.4" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "chokidar": { + "version": "3.5.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/chokidar/-/chokidar-3.5.2.tgz", + "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.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" + }, + "dependencies": { + "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==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, + "chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "clone-deep": { + "version": "4.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "colorette": { + "version": "2.0.16", + "resolved": "https://repo.huaweicloud.com/repository/npm/colorette/-/colorette-2.0.16.tgz", + "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", + "dev": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "debug": { + "version": "4.3.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "diff": { + "version": "5.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, + "electron-to-chromium": { + "version": "1.4.7", + "resolved": "https://repo.huaweicloud.com/repository/npm/electron-to-chromium/-/electron-to-chromium-1.4.7.tgz", + "integrity": "sha512-UPy2MsQw1OdcbxR7fvwWZH/rXcv+V26+uvQVHx0fGa1kqRfydtfOw+NMGAvZJ63hyaH4aEBxbhSEtqbpliSNWA==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "enhanced-resolve": { + "version": "5.8.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", + "integrity": "sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://repo.huaweicloud.com/repository/npm/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "envinfo": { + "version": "7.8.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/envinfo/-/envinfo-7.8.1.tgz", + "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", + "dev": true + }, + "es-module-lexer": { + "version": "0.9.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/es-module-lexer/-/es-module-lexer-0.9.3.tgz", + "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint": { + "version": "8.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/eslint/-/eslint-8.2.0.tgz", + "integrity": "sha512-erw7XmM+CLxTOickrimJ1SiF55jiNlVSp2qqm0NuBWPtHYQCegD5ZMaW0c3i5ytPqL+SSLaCxdvQXFPLJn+ABw==", + "dev": true, + "requires": { + "@eslint/eslintrc": "^1.0.4", + "@humanwhocodes/config-array": "^0.6.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^6.0.0", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.0.0", + "espree": "^9.0.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.2.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + } + }, + "eslint-scope": { + "version": "6.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/eslint-scope/-/eslint-scope-6.0.0.tgz", + "integrity": "sha512-uRDL9MWmQCkaFus8RF5K9/L/2fn+80yoW3jkD53l4shjCh26fCtvJGasxjUqP5OT87SYTxCVA3BwTUzuELx9kA==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "3.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", + "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==", + "dev": true + }, + "espree": { + "version": "9.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/espree/-/espree-9.0.0.tgz", + "integrity": "sha512-r5EQJcYZ2oaGbeR0jR0fFVijGOcwai07/690YRXLINuhmVeRY4UKSAsQPe/0BNuDgwP7Ophoc1PRsr2E3tkbdQ==", + "dev": true, + "requires": { + "acorn": "^8.5.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^3.0.0" + } + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "events": { + "version": "3.3.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true + }, + "execa": { + "version": "5.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://repo.huaweicloud.com/repository/npm/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fastest-levenshtein": { + "version": "1.0.12", + "resolved": "https://repo.huaweicloud.com/repository/npm/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", + "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", + "dev": true + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/flatted/-/flatted-3.2.4.tgz", + "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "fstream": { + "version": "1.0.12", + "resolved": "https://repo.huaweicloud.com/repository/npm/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "dependencies": { + "rimraf": { + "version": "2.7.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://repo.huaweicloud.com/repository/npm/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "glob": { + "version": "7.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "globals": { + "version": "13.12.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/globals/-/globals-13.12.0.tgz", + "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "graceful-fs": { + "version": "4.2.8", + "resolved": "https://repo.huaweicloud.com/repository/npm/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", + "dev": true + }, + "growl": { + "version": "1.10.5", + "resolved": "https://repo.huaweicloud.com/repository/npm/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "he": { + "version": "1.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } + }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://repo.huaweicloud.com/repository/npm/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "import-local": { + "version": "3.0.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/import-local/-/import-local-3.0.3.tgz", + "integrity": "sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://repo.huaweicloud.com/repository/npm/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "interpret": { + "version": "2.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/interpret/-/interpret-2.2.0.tgz", + "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.8.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-core-module/-/is-core-module-2.8.0.tgz", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "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==", + "dev": true + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "jest-worker": { + "version": "27.4.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/jest-worker/-/jest-worker-27.4.2.tgz", + "integrity": "sha512-0QMy/zPovLfUPyHuOuuU4E+kGACXXE84nRnq6lBVI9GJg5DCBiA97SATi+ZP8CpiJwEQy1oCPjRBf8AnLjN+Ag==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "dependencies": { + "supports-color": { + "version": "8.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "levn": { + "version": "0.4.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "listenercount": { + "version": "1.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/listenercount/-/listenercount-1.0.1.tgz", + "integrity": "sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=", + "dev": true + }, + "loader-runner": { + "version": "4.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/loader-runner/-/loader-runner-4.2.0.tgz", + "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", + "dev": true + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "mime-db": { + "version": "1.51.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", + "dev": true + }, + "mime-types": { + "version": "2.1.34", + "resolved": "https://repo.huaweicloud.com/repository/npm/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "dev": true, + "requires": { + "mime-db": "1.51.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://repo.huaweicloud.com/repository/npm/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://repo.huaweicloud.com/repository/npm/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "mocha": { + "version": "9.1.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/mocha/-/mocha-9.1.3.tgz", + "integrity": "sha512-Xcpl9FqXOAYqI3j79pEtHBBnQgVXIhpULjGQa7DVb0Po+VzmSIK9kanAiWLHoRR/dbZ2qpdPshuXr8l1VaHCzw==", + "dev": true, + "requires": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.2", + "debug": "4.3.2", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.7", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "3.0.4", + "ms": "2.1.3", + "nanoid": "3.1.25", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "workerpool": "6.1.5", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "dependencies": { + "glob": { + "version": "7.1.7", + "resolved": "https://repo.huaweicloud.com/repository/npm/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "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==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "nanoid": { + "version": "3.1.25", + "resolved": "https://repo.huaweicloud.com/repository/npm/nanoid/-/nanoid-3.1.25.tgz", + "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node-releases": { + "version": "2.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/node-releases/-/node-releases-2.0.1.tgz", + "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==", + "dev": true + }, + "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==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "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": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "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==", + "dev": true + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + } + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://repo.huaweicloud.com/repository/npm/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "rechoir": { + "version": "0.7.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/rechoir/-/rechoir-0.7.1.tgz", + "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", + "dev": true, + "requires": { + "resolve": "^1.9.0" + } + }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "schema-utils": { + "version": "3.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/schema-utils/-/schema-utils-3.1.1.tgz", + "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://repo.huaweicloud.com/repository/npm/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "serialize-javascript": { + "version": "6.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://repo.huaweicloud.com/repository/npm/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "shallow-clone": { + "version": "3.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "signal-exit": { + "version": "3.0.6", + "resolved": "https://repo.huaweicloud.com/repository/npm/signal-exit/-/signal-exit-3.0.6.tgz", + "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.21", + "resolved": "https://repo.huaweicloud.com/repository/npm/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "tapable": { + "version": "2.2.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true + }, + "terser": { + "version": "5.10.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/terser/-/terser-5.10.0.tgz", + "integrity": "sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.7.2", + "source-map-support": "~0.5.20" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } + }, + "terser-webpack-plugin": { + "version": "5.2.5", + "resolved": "https://repo.huaweicloud.com/repository/npm/terser-webpack-plugin/-/terser-webpack-plugin-5.2.5.tgz", + "integrity": "sha512-3luOVHku5l0QBeYS8r4CdHYWEGMmIj3H1U64jgkdZzECcSOJAyJ9TjuqcQZvw1Y+4AOBN9SeYJPJmFn2cM4/2g==", + "dev": true, + "requires": { + "jest-worker": "^27.0.6", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.0", + "source-map": "^0.6.1", + "terser": "^5.7.2" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "traverse": { + "version": "0.3.9", + "resolved": "https://repo.huaweicloud.com/repository/npm/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=", + "dev": true + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, + "typescript": { + "version": "4.4.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/typescript/-/typescript-4.4.4.tgz", + "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", + "dev": true + }, + "unzipper": { + "version": "0.10.11", + "resolved": "https://repo.huaweicloud.com/repository/npm/unzipper/-/unzipper-0.10.11.tgz", + "integrity": "sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==", + "dev": true, + "requires": { + "big-integer": "^1.6.17", + "binary": "~0.3.0", + "bluebird": "~3.4.1", + "buffer-indexof-polyfill": "~1.0.0", + "duplexer2": "~0.1.4", + "fstream": "^1.0.12", + "graceful-fs": "^4.2.2", + "listenercount": "~1.0.1", + "readable-stream": "~2.3.6", + "setimmediate": "~1.0.4" + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "watchpack": { + "version": "2.3.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/watchpack/-/watchpack-2.3.0.tgz", + "integrity": "sha512-MnN0Q1OsvB/GGHETrFeZPQaOelWh/7O+EiFlj8sM9GPjtQkis7k01aAxrg/18kTfoIVcLL+haEVFlXDaSRwKRw==", + "dev": true, + "requires": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + } + }, + "webpack": { + "version": "5.64.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/webpack/-/webpack-5.64.4.tgz", + "integrity": "sha512-LWhqfKjCLoYJLKJY8wk2C3h77i8VyHowG3qYNZiIqD6D0ZS40439S/KVuc/PY48jp2yQmy0mhMknq8cys4jFMw==", + "dev": true, + "requires": { + "@types/eslint-scope": "^3.7.0", + "@types/estree": "^0.0.50", + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/wasm-edit": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "acorn": "^8.4.1", + "acorn-import-assertions": "^1.7.6", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.8.3", + "es-module-lexer": "^0.9.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.4", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.3", + "watchpack": "^2.3.0", + "webpack-sources": "^3.2.2" + }, + "dependencies": { + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + } + } + }, + "webpack-cli": { + "version": "4.9.1", + "resolved": "https://repo.huaweicloud.com/repository/npm/webpack-cli/-/webpack-cli-4.9.1.tgz", + "integrity": "sha512-JYRFVuyFpzDxMDB+v/nanUdQYcZtqFPGzmlW4s+UkPMFhSpfRNmf1z4AwYcHJVdvEFAM7FFCQdNTpsBYhDLusQ==", + "dev": true, + "requires": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^1.1.0", + "@webpack-cli/info": "^1.4.0", + "@webpack-cli/serve": "^1.6.0", + "colorette": "^2.0.14", + "commander": "^7.0.0", + "execa": "^5.0.0", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^2.2.0", + "rechoir": "^0.7.0", + "webpack-merge": "^5.7.3" + }, + "dependencies": { + "commander": { + "version": "7.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true + } + } + }, + "webpack-merge": { + "version": "5.8.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/webpack-merge/-/webpack-merge-5.8.0.tgz", + "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", + "dev": true, + "requires": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + } + }, + "webpack-sources": { + "version": "3.2.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/webpack-sources/-/webpack-sources-3.2.2.tgz", + "integrity": "sha512-cp5qdmHnu5T8wRg2G3vZZHoJPN14aqQ89SyQ11NpGH5zEMDCclt49rzo+MaRazk7/UeILhAI+/sEtcM+7Fr0nw==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wildcard": { + "version": "2.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/wildcard/-/wildcard-2.0.0.tgz", + "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", + "dev": true + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://repo.huaweicloud.com/repository/npm/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "workerpool": { + "version": "6.1.5", + "resolved": "https://repo.huaweicloud.com/repository/npm/workerpool/-/workerpool-6.1.5.tgz", + "integrity": "sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://repo.huaweicloud.com/repository/npm/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://repo.huaweicloud.com/repository/npm/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.4", + "resolved": "https://repo.huaweicloud.com/repository/npm/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true + }, + "yargs-unparser": { + "version": "2.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + } + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + } + } +} diff --git a/napi_tool/code/tool_code/package.json b/napi_tool/code/tool_code/package.json new file mode 100644 index 0000000000000000000000000000000000000000..fd116553ec7017da16acdad474edbc693d1f0955 --- /dev/null +++ b/napi_tool/code/tool_code/package.json @@ -0,0 +1,53 @@ +{ + "name": "gnapi", + "displayName": "gnapi", + "description": "test", + "version": "0.0.1", + "engines": { + "vscode": "^1.62.0" + }, + "categories": [ + "Other" + ], + "activationEvents": [ + "*" + ], + "main": "./extension.js", + "contributes": { + "commands": [ + { + "command": "generate_napi", + "title": ".d.ts生成c++" + } + ], + "menus": { + "explorer/context": [ + { + "when": "resourceExtname == .ts", + "command": "generate_napi" + } + ] + } + }, + "scripts": { + "lint": "eslint .", + "pretest": "npm run lint", + "test": "node ./test/runTest.js", + "vscode:prepublish": "webpack --mode production", + "compile": "webpack --mode none", + "watch": "webpack --mode none --watch" + }, + "devDependencies": { + "@types/glob": "^7.1.4", + "@types/mocha": "^9.0.0", + "@types/node": "14.x", + "@types/vscode": "^1.62.0", + "@vscode/test-electron": "^1.6.2", + "eslint": "^8.1.0", + "glob": "^7.1.7", + "mocha": "^9.1.3", + "typescript": "^4.4.4", + "webpack": "^5.64.4", + "webpack-cli": "^4.9.1" + } +} diff --git a/napi_tool/code/tool_code/test/runTest.js b/napi_tool/code/tool_code/test/runTest.js new file mode 100644 index 0000000000000000000000000000000000000000..407bba7b65fb0fd5a9117fe16615f71c63119d86 --- /dev/null +++ b/napi_tool/code/tool_code/test/runTest.js @@ -0,0 +1,37 @@ +/* +* Copyright (c) 2021 Shenzhen Kaihong Digital Industry Development 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'); + +const { runTests } = require('@vscode/test-electron'); + +async function main() { + try { + // The folder containing the Extension Manifest package.json + // Passed to `--extensionDevelopmentPath` + const extensionDevelopmentPath = path.resolve(__dirname, '../'); + + // The path to the extension test script + // Passed to --extensionTestsPath + const extensionTestsPath = path.resolve(__dirname, './suite/index'); + + // Download VS Code, unzip it and run the integration test + await runTests({ extensionDevelopmentPath, extensionTestsPath }); + } catch (err) { + console.error('Failed to run tests'); + process.exit(1); + } +} + +main(); diff --git a/napi_tool/code/tool_code/test/suite/extension.test.js b/napi_tool/code/tool_code/test/suite/extension.test.js new file mode 100644 index 0000000000000000000000000000000000000000..0caaeafa5da217922e87b459ddbe0f722a74cf02 --- /dev/null +++ b/napi_tool/code/tool_code/test/suite/extension.test.js @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2021 Shenzhen Kaihong Digital Industry Development 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 assert = require('assert'); + +// You can import and use all API from the 'vscode' module +// as well as import your extension to test it +const vscode = require('vscode'); +// const myExtension = require('../extension'); + +suite('Extension Test Suite', () => { + vscode.window.showInformationMessage('Start all tests.'); + + test('Sample test', () => { + assert.strictEqual(-1, [1, 2, 3].indexOf(5)); + assert.strictEqual(-1, [1, 2, 3].indexOf(0)); + }); +}); diff --git a/napi_tool/code/tool_code/test/suite/index.js b/napi_tool/code/tool_code/test/suite/index.js new file mode 100644 index 0000000000000000000000000000000000000000..58ab4c8568ac3b9bdccfb11414b4627df14f029d --- /dev/null +++ b/napi_tool/code/tool_code/test/suite/index.js @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2021 Shenzhen Kaihong Digital Industry Development 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'); +const Mocha = require('mocha'); +const glob = require('glob'); + +function run() { + // Create the mocha test + const mocha = new Mocha({ + ui: 'tdd', + color: true + }); + + const testsRoot = path.resolve(__dirname, '..'); + + return new Promise((c, e) => { + glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { + if (err) { + return e(err); + } + + // Add files to the test suite + files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); + + try { + // Run the mocha test + mocha.run(failures => { + if (failures > 0) { + e(new Error(`${failures} tests failed.`)); + } else { + c(); + } + }); + } catch (err) { + console.error(err); + e(err); + } + }); + }); +} + +module.exports = { + run +}; diff --git a/napi_tool/code/tool_code/vsc-extension-quickstart.md b/napi_tool/code/tool_code/vsc-extension-quickstart.md new file mode 100644 index 0000000000000000000000000000000000000000..e6da2a5c8e5a2590cb867d8a5fc207800b190639 --- /dev/null +++ b/napi_tool/code/tool_code/vsc-extension-quickstart.md @@ -0,0 +1,39 @@ +# Welcome to your VS Code Extension + +## What's in the folder + +* This folder contains all of the files necessary for your extension. +* `package.json` - this is the manifest file in which you declare your extension and command. + * The sample plugin registers a command and defines its title and command name. With this information VS Code can show the command in the command palette. It doesn’t yet need to load the plugin. +* `extension.js` - this is the main file where you will provide the implementation of your command. + * The file exports one function, `activate`, which is called the very first time your extension is activated (in this case by executing the command). Inside the `activate` function we call `registerCommand`. + * We pass the function containing the implementation of the command as the second parameter to `registerCommand`. + +## Get up and running straight away + +* Press `F5` to open a new window with your extension loaded. +* Run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Hello World`. +* Set breakpoints in your code inside `extension.js` to debug your extension. +* Find output from your extension in the debug console. + +## Make changes + +* You can relaunch the extension from the debug toolbar after changing code in `extension.js`. +* You can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes. + +## Explore the API + +* You can open the full set of our API when you open the file `node_modules/@types/vscode/index.d.ts`. + +## Run tests + +* Open the debug viewlet (`Ctrl+Shift+D` or `Cmd+Shift+D` on Mac) and from the launch configuration dropdown pick `Extension Tests`. +* Press `F5` to run the tests in a new window with your extension loaded. +* See the output of the test result in the debug console. +* Make changes to `src/test/suite/extension.test.js` or create new test files inside the `test/suite` folder. + * The provided test runner will only consider files matching the name pattern `**.test.ts`. + * You can create folders inside the `test` folder to structure your tests any way you want. +## Go further + + * [Publish your extension](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) on the VSCode extension marketplace. + * Automate builds by setting up [Continuous Integration](https://code.visualstudio.com/api/working-with-extensions/continuous-integration). diff --git a/napi_tool/code/tool_code/webpack.config.js b/napi_tool/code/tool_code/webpack.config.js new file mode 100644 index 0000000000000000000000000000000000000000..f9357f1ac00797ceeb170ebdd60e5480ac9cfc47 --- /dev/null +++ b/napi_tool/code/tool_code/webpack.config.js @@ -0,0 +1,46 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +//@ts-check + +"use strict"; + +const path = require("path"); + +/**@type {import('webpack').Configuration}*/ +const config = { + target: "node", // vscode插件运行在Node.js环境中 📖 -> https://webpack.js.org/configuration/node/ + + entry: "./extension.js", // 插件的入口文件 📖 -> https://webpack.js.org/configuration/entry-context/ + output: { + // 打包好的文件储存在'dist'文件夹中 (请参考package.json), 📖 -> https://webpack.js.org/configuration/output/ + path: path.resolve(__dirname, "dist"), + filename: "extension.js", + libraryTarget: "commonjs2", + devtoolModuleFilenameTemplate: "../[resource-path]" + }, + devtool: "source-map", + externals: { + vscode: "commonjs vscode" // vscode-module是热更新的临时目录,所以要排除掉。 在这里添加其他不应该被webpack打包的文件, 📖 -> https://webpack.js.org/configuration/externals/ + }, + resolve: { + // 支持读取TypeScript和JavaScript文件, 📖 -> https://github.com/TypeStrong/ts-loader + extensions: [".ts", ".js"] + }, + module: { + rules: [ + { + test: /\.ts$/, + exclude: /node_modules/, + use: [ + { + loader: "ts-loader" + } + ] + } + ] + } +}; +module.exports = config; \ No newline at end of file diff --git a/napi_tool/code/ts_test/gen/.gitignore b/napi_tool/code/ts_test/gen/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..fcb6a2f4c6b9859395aa0cc73a3cd03b227f433d --- /dev/null +++ b/napi_tool/code/ts_test/gen/.gitignore @@ -0,0 +1 @@ +build diff --git a/napi_tool/code/ts_test/gen/@ohos.napitest.d.ts b/napi_tool/code/ts_test/gen/@ohos.napitest.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..ee005d20106639d87f5e20575a9e6edeb745f3a4 --- /dev/null +++ b/napi_tool/code/ts_test/gen/@ohos.napitest.d.ts @@ -0,0 +1,54 @@ + +/* +* Copyright (c) 2021 Shenzhen Kaihong Digital Industry Development 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 { AsyncCallback, Callback } from './basic'; + +declare namespace napitest { + interface Human { + name: string; + age: number; + } + interface TestClass1 { + ahuman: Human; + num1: number; + str1: string; + nums: Array; + strs: Array; + mans: Array; + if_direct(v1: string): string; + if_callback(v1: string, cb: Callback): string; + if_async(v1: string, cb: AsyncCallback): string; + } + + function fun2(v2: string, numcc: Array, mancc: Human): Array; + function fun3(v2: string, cb: Callback): void; + function fun4(v2: string, cb: AsyncCallback): void; + + namespace Space3 { + function fun3(v3: string): string; + interface TestClass2 { + haha: number; + } + namespace Space4 { + function fun3(v3: string): string; + interface TestClass3 { + hoho: number; + add(v1: Array): number; + } + } + } +} + +export default napitest; \ No newline at end of file diff --git a/napi_tool/code/ts_test/gen/test.js b/napi_tool/code/ts_test/gen/test.js new file mode 100644 index 0000000000000000000000000000000000000000..670727c946173ae2b25c1b9d4e3a0bcf7b16fb89 --- /dev/null +++ b/napi_tool/code/ts_test/gen/test.js @@ -0,0 +1,57 @@ +/* +* Copyright (c) 2021 Shenzhen Kaihong Digital Industry Development 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 test = require("./build/Release/napitest") + +//直接返回 +let result = test.fun2("direct", [1, 2, 3], {name: "cc", age: 20}) +console.log(result) + +//同步回调 +test.fun3("callback", function (ret) {console.log(ret)}) + +// function cb(ret) +// { +// console.log(ret) +// } +//异步回调 +function test_async() { + test.fun4("async", function (ret) {console.log(ret)}) + test.fun4("promise").then(ret => {console.log(ret);}) +} +test_async() +// //promise + +let tc1 = new test.TestClass1() +tc1.str1 = "asdf" +console.log(tc1.str1) +console.log(tc1.if_direct("123")) + +tc1.if_callback("abc", function (ret) {console.log(ret)}) +tc1.if_async("world").then(ret => {console.log(ret)}) + +console.log(test.Space3.fun3("ccnto")) +let tc2 = new test.Space3.Space4.TestClass3() +console.log("hoho=", tc2.add([3,4,5])) +console.log("==== end ====") + +setTimeout(function () { + console.log('interval') +}, 100); + +// function asdfasdf(ret) +// { +// console.log(ret) +// } diff --git a/napi_tool/code/ts_test/readme.txt b/napi_tool/code/ts_test/readme.txt new file mode 100644 index 0000000000000000000000000000000000000000..3c9de1d6d31870da91426af232ce4fdd49ab75f9 --- /dev/null +++ b/napi_tool/code/ts_test/readme.txt @@ -0,0 +1,7 @@ +使用nodejs测试napi生成程序,可以更快的测试验证 + +环境搭建: +npm i bindings node-addon-api -S + +raw:手工编写最终代码,快速验证可行性,最后生成程序来生成这个代码 +gen:由gnapi生成的代码,生成的跟手写的(raw)一致 \ No newline at end of file diff --git a/napi_tool/doc/README_ZH.md b/napi_tool/doc/README_ZH.md new file mode 100644 index 0000000000000000000000000000000000000000..5adf0f4e6a76e3c6dd509cff35be96f1c5cb45d8 --- /dev/null +++ b/napi_tool/doc/README_ZH.md @@ -0,0 +1,35 @@ +# NAPI框架代码生成工具 + +- [当前支持特性](#section11660541593) +- [版本规划](#section161941989596) +- [相关链接](#section11759141594811) + +## 当前支持特性 + +1.支持参数解析、生成,支持的参数类型:number、string、array、boolean、void; + +2.支持函数解析、生成,包括同步直接返回函数、同步callback函数、异步callback函数、异步promise函数; + +3.支持Interface解析、生成,包括变量、函数; + +4.支持返回值解析、生成,返回值的类型有int、string、array、bool、void; + +5.支持namespace解析、生成,包括interface、变量、函数等; + +## 版本规划 +- **一阶段** + 支持函数、基础数据类型解析、代码框架生成,330入主干 + +- **二阶段** + + 支持openHarmony的所有语法、接口的数据解析、代码框架生成,630入主干 + +- **三阶段** + + 支持接口对应的应用范例自动化生成,930入主干 + +## 相关链接 +[napi官网](http://nodejs.cn/api/n-api.html) + +[vscode插件开发参考](https://liiked.github.io/VS-Code-Extension-Doc-ZH/#/) + diff --git "a/napi_tool/doc/\345\274\200\345\217\221\346\214\207\345\215\227.md" "b/napi_tool/doc/\345\274\200\345\217\221\346\214\207\345\215\227.md" new file mode 100644 index 0000000000000000000000000000000000000000..c04525ce6fad8c1fe004787ef3ca2365c7e1d5ca --- /dev/null +++ "b/napi_tool/doc/\345\274\200\345\217\221\346\214\207\345\215\227.md" @@ -0,0 +1,668 @@ +## 什么是N-API + +N-API为开发者提供了一套C/C++ API用于开发Node.js的Native扩展模块。从Node.js 8.0.0开始,N-API以实验性特性作为Node.js本身的一部分被引入,并且从Node.js 10.0.0开始正式全面支持N-API。 + +## Hello N-API + +本文将使用一个简单的模块作为示例介绍N-API。我们将编写一个`hello`模块,其中包括一个返回`Hello N-API!`字符串的方法`greeting`。其实现的功能相当于下列Javascript代码: + +```js +const greeting = () => { + return 'Hello N-API!'; +} + +module.exports = { + greeting, +}; +``` + +### greeting方法定义 + +首先,我们需要定义`greeting`方法,并返回值为`Hello N-API!`的字符串。为了使用N-API提供的接口及类型定义,我们需要引入`node_api.h`头文件。使用N-API定义的方法需要满足`napi_callback`类型,其定义为: + +```c +typedef napi_value (*napi_callback)(napi_env env, napi_callback_info info); +``` + +`napi_callback`是使用N-API开发的Native函数的函数指针类型,其接受类型分别为`napi_env`以及`napi_callback_info`的两个参数,并返回类型为`napi_value`的值。`greeting`方法中涉及到的几个类型定义及其用途如下: + +- `napi_value`类型是一个用于表示Javascript值的指针 +- `napi_env`类型用于存储Javascript虚拟机的上下文 +- `napi_callback_info`类型用于调用回调函数时,传递调用时的上下文信息 + +我们定义的`greeting`方法如下: + +```c +napi_value greeting(napi_env env, napi_callback_info info) { + napi_status status; + napi_value word; + char *str = "Hello N-API!"; + + status = napi_create_string_utf8(env, str, strlen(str), &word); + + assert(status == napi_ok); + + return word; +} +``` + +在`greeting`方法中,我们通过`napi_create_string_utf8`函数创建了值为`"Hello N-API!"`的Javascript字符串对象,并将其作为该方法的返回值返回。`napi_create_string_utf8`用于创建一个UTF-8类型的字符串对象,其值来自于参数传递的UTF-8编码字符串,函数原型如下: + +```c +napi_status napi_create_string_utf8(napi_env env, + const char *str, + size_t length, + napi_value* result); +``` + +- `env`:传递当前VM的上下文信息 +- `str`:UTF-8编码的字符序列 +- `length`:字符序列`str`的长度 +- `result`:用于表示创建的Javascript字符串对象的指针 + +`napi_create_string_utf8`返回一个`napi_status`类型的值,当其值为`napi_ok`时代表完成字符串对象的创建。如示例中代码所示,我们在调用`napi_create_string_utf8`后,便使用`assert`判断其返回值是否为`napi_ok`。 + +`napi_status`是一个用于指示N-API中状态的枚举类型,其值可参考[napi_status](https://nodejs.org/dist/latest-v12.x/docs/api/n-api.html#n_api_napi_status)。 + +### 模块注册 + +在完成了`greeting`方法后,我们还需要注册我们的`hello`模块。N-API通过`NAPI_MODULE(modname, regfunc)`宏进行模块的注册。其接受两个参数,分别为模块名及模块初始化函数。模块初始化函数需要满足下列函数签名: + +```c +napi_value (*)(napi_env env, napi_value exports); +``` + +在模块的初始化中,我们可以定义模块需要暴露的方法及属性。我们的模块初始化函数如下所示: + +```c +napi_value init(napi_env env, napi_value exports) { + napi_status status; + napi_property_descriptor descriptor = { + "greeting", + 0, + greeting, + 0, + 0, + 0, + napi_default, + 0, + }; + + status = napi_define_properties(env, exports, 1, &descriptor); + assert(status == napi_ok); + + return exports; +} + +NAPI_MODULE(hello, init); +``` + +在我们的的初始化函数中,需要在模块的`exports`对象中定义`greeting`属性。在定义属性之前,我们需要创建一个`napi_property_descriptor`类型的属性描述符,该类型的定义如下: + +```c +typedef struct { + const char* utf8name; + napi_value name; + + napi_callback method; + napi_callback getter; + napi_callback setter; + napi_value value; + + napi_property_attributes attributes; + void* data; +} napi_property_descriptor; +``` + +对于本文示例中需要使用的属性值描述如下所示,关于`napi_property_descriptor`的更多描述可参考[napi_property_descriptor](https://nodejs.org/dist/latest-v12.x/docs/api/n-api.html#n_api_napi_property_descriptor)。 + +- `utf8name`:UTF-8编码的字符序列 +- `name`:由Javascript对象表示的字符串或者Symbol + +`utf8name`以及`name`二者中必须且只能有一个被提供,其代表属性的名称。 + +- `method`:将该属性设置为表示一个Javascript方法(function) +- `attributes`:属性的行为控制标志,示例中使用了默认的`napi_default`值,更多描述可参考[napi_property_attributes](https://nodejs.org/dist/latest-v12.x/docs/api/n-api.html#n_api_napi_property_attributes) + +我们需要定义的`greeting`属性是一个方法,所以我们所创建的属性描述符主要传递了`utf8name`以及`method`属性。 + +在创建属性描述符后,便需要将其在模块的`exports`对象中定义,使Javascript代码能够访问。对象属性的定义使用了`napi_define_properties`函数,它可以快速的为一个对象定义指定数量的属性。该函数定义为: + +```c +napi_status napi_define_properties(napi_env env, + napi_value object, + size_t property_count, + const napi_property_descriptor *properties); +``` + +- `object`:需要定义属性的Javascript对象 +- `property_count`:属性数量 +- `properties`:属性描述符数组 + +同样,`napi_define_properties`也返回了一个`napi_status`类型的值表示函数调用是否成功。 + +最后,我们只需要在模块初始化函数中返回`exports`对象,并通过`NAPI_MODULE(hello, init)`注册`hello`模块。到此为止,我们的`hello`模块便编写完成了。 + +## 模块编译 + +Native模块的构建可选择`node-gyp`或者`cmake.js`,二者的使用需要安装C/C++工具链,本文选择了`node-gyp`作为示例的构建工具。`node-gyp`是基于Google的`gyp`工具开发,它除了必要的C/C++编译器以外,还需要安装Python以及make工具。对于Windows用户,使用`node-gyp`需要安装Python并通过npm安装`windows-build-tools`(`npm install --global --production windows-build-tools`)。 + +接下来,需要定义`binding,gyp`文件。`binding,gyp`是node-gyp的JSON类型配置文件,文中示例程序使用的`binding.gyp`内容如下所示: + +```json +{ + "targets": [ + { + "target_name": "hello", + "sources": [ + "hello.c" + ] + } + ] +} +``` + +如示例所示,`binding,gyp`文件中定义了`targets`,它定义了一组gyp能生成的目标。`targets`中定义了一个对象,其包括了`target_name`和`sources`两个属性。`target_name`定义了该Native包的名称,`sources`定义了需要编译的文件。 + +对于gyp文件的更多配置,可参考[nodejs/node-gyp](https://github.com/nodejs/node-gyp)、[GYP User Documentation](https://gyp.gsrc.io/docs/UserDocumentation.md)以及[GYP Input Format Reference](https://gyp.gsrc.io/docs/InputFormatReference.md)。 + +接下来便可以使用`node-gyp`构建示例中编写的Native模块。 + +```bash +$ node-gyp configure build +``` + +在完成构建后,将会在当前目录下产生一个`build`文件,其中包括了生成的各个中间文件以及`.node`文件。`.node`文件本质上即一个动态的链接库,Node.js会调用`dlopen`函数用于加载`.node`文件。 + +## 测试 + +在构建Native模块后,就将在js代码中引入生成的`.node`文件,并调用上文模块中定义`greeting`方法。 + +```js +const hello = require('./build/Release/hello.node'); + +console.log(hello.greeting()); +``` + +运行该程序,将得到下面的输出结果: + +```bash +$ node index.js +Hello N-API! +``` + +若安装了`bindings`依赖,便可将`const hello = require('./build/Release/hello.node');`修改为`const hello = require('bindings')('hello');`。 + +```js +const hello = require('bindings')('hello'); + +console.log(hello.greeting()); +``` + +## 示例 + +### 函数封装 + +native代码 + +```c++ +//Native Function +napi_value HelloWorld(napi_env env, napi_callback_info info) { + napi_value thisVar = nullptr; + unsigned int argc = 1; //需要接受参数的个数 + napi_value argv[1] = { 0 }; //存储参数空间 + void *data = nullptr; //用户指针 + + napi_status result_status = 0; + + result_status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); + + if(result_status != napi_ok) + { + napi_value errCode = nullptr; + napi_value errMessage = nullptr; + napi_value error = nullptr; + napi_create_string_utf8(env, "", NAPI_AUTOLENGTH, &errCode); //根据业务错误代码定义 + napi_create_string_utf8(env, "获取callback info失败!", NAPI_AUTOLENGTH, &errMessage); + napi_create_error(env, errCode, errMessage, &error); + return error; + } + + if(!(argc >= 1)) + { + napi_value errCode = nullptr; + napi_value errMessage = nullptr; + napi_value error = nullptr; + napi_create_string_utf8(env, "", NAPI_AUTOLENGTH, &errCode); //根据业务错误代码定义 + napi_create_string_utf8(env, "传递参数数量不足,至少需要一个字符串参数!", NAPI_AUTOLENGTH, &errMessage); + napi_create_error(env, errCode, errMessage, &error); + return error; + } + + napi_valuetype type; + result_status = napi_typeof(env, argv[0], &type); //获取参数类型 + if(type != native_string) //对比参数类型 + { + napi_value errCode = nullptr; + napi_value errMessage = nullptr; + napi_value error = nullptr; + napi_create_string_utf8(env, "", NAPI_AUTOLENGTH, &errCode); //根据业务错误代码定义 + napi_create_string_utf8(env, "传入参数类型错误!", NAPI_AUTOLENGTH, &errMessage); + napi_create_error(env, errCode, errMessage, &error); + return error; + } + + char cValue[1024] = { 0 }; + size_t cValuelLength = 0; + napi_get_value_string_utf8(env, argv[0], cValue, 1023, &cValueLength); + + printf("hello world: %s\n", cValue); + + napi_value result = nullptr; + napi_create_int32(env, 0, &result); + return result; +} + +//模块初始化函数 +napi_value init(napi_env env, napi_value exports) { + napi_status status; + napi_property_descriptor descriptors[] = { + { "helloWorld", 0, HelloWorld, 0, 0, 0, napi_default, 0, } + }; + status = napi_define_properties(env, exports, 1, descriptors); + assert(status == napi_ok); + return exports; +} + +//模块注册 +NAPI_MODULE(helloWorld, init); +``` + +javascript代码 + +```javascript +//模块引入 +const { helloworld } = require("helloworld.node"); + +//调用模块函数 +let ret = helloWorld("test"); + +``` + +### 类封装 + +native代码 + +```c++ +napi_value Constructor(napi_env env, napi_callback_info info) +{ + +} + +napi_value Add(napi_env env, napi_callback_info info) +{ + +} + +napi_value Sub(napi_env env, napi_callback_info info) +{ + +} + +napi_value Mul(napi_env env, napi_callback_info info) +{ + +} + +napi_value Div(napi_env env, napi_callback_info info) +{ + +} + +napi_value init(napi_env env, napi_value expotrs) +{ + napi_value demoClass = nullptr; + + napi_property_descriptor props[] = { + { "add", 0, Add, 0, 0, 0, napi_default, 0, }, + { "sub", 0, Sub, 0, 0, 0, napi_default, 0, }, + { "mul", 0, Mul, 0, 0, 0, napi_default, 0, }, + { "div", 0, Div, 0, 0, 0, napi_default, 0, }, + }; + + napi_define_class(env, "DemoClass", NAPI_AUTOLENGTH, Constructor, nullptr, props, sizeof(props) / sizeof(props[0]), &demoClass); + + napi_set_named_property(env, exports, "DemoClass", demoClass); + + return exports; +} + +NAPI_Module(demo, init); + +``` + +javascript代码 + +```javascript + +const { DemoClass } = require('demo.node'); + +let demo = new DemoClass(); + +demo.add(3, 3); +demo.sub(3, 3); +demo.mul(3, 3); +demo.div(3, 3); + +``` + +### 同步回调 + +native代码 + +```c++ +//Native Function +napi_value SyncCallback(napi_env env, napi_callback_info info) { + napi_value thisVar = nullptr; + unsigned int argc = 1; //需要接受参数的个数 + napi_value argv[1] = { 0 }; //存储参数空间 + void *data = nullptr; //用户指针 + + napi_status result_status = 0; + + result_status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); + + if(result_status != napi_ok) + { + napi_value errCode = nullptr; + napi_value errMessage = nullptr; + napi_value error = nullptr; + napi_create_string_utf8(env, "", NAPI_AUTOLENGTH, &errCode); //根据业务错误代码定义 + napi_create_string_utf8(env, "获取callback info失败!", NAPI_AUTOLENGTH, &errMessage); + napi_create_error(env, errCode, errMessage, &error); + return error; + } + + if(!(argc >= 1)) + { + napi_value errCode = nullptr; + napi_value errMessage = nullptr; + napi_value error = nullptr; + napi_create_string_utf8(env, "", NAPI_AUTOLENGTH, &errCode); //根据业务错误代码定义 + napi_create_string_utf8(env, "传递参数数量不足,至少需要一个字符串参数!", NAPI_AUTOLENGTH, &errMessage); + napi_create_error(env, errCode, errMessage, &error); + return error; + } + + napi_valuetype type; + result_status = napi_typeof(env, argv[0], &type); //获取参数类型 + if(type != native_function) //对比参数类型 + { + napi_value errCode = nullptr; + napi_value errMessage = nullptr; + napi_value error = nullptr; + napi_create_string_utf8(env, "", NAPI_AUTOLENGTH, &errCode); //根据业务错误代码定义 + napi_create_string_utf8(env, "传入参数类型错误!", NAPI_AUTOLENGTH, &errMessage); + napi_create_error(env, errCode, errMessage, &error); + return error; + } + + //Native回调发起 + napi_value args[1] = { nullptr }; + napi_value cb_result = nullptr; + napi_create_int32(env, 123, &args[0]); + napi_call_function(env, nullptr, argv[0], 1, args, &cb_result); + + napi_value result = nullptr; + napi_get_undefind(env, &result); + return result; +} + +//模块初始化函数 +napi_value init(napi_env env, napi_value exports) { + napi_status status; + napi_property_descriptor descriptors[] = { + { "syncCallback", 0, SyncCallback, 0, 0, 0, napi_default, 0, } + }; + status = napi_define_properties(env, exports, 1, descriptors); + assert(status == napi_ok); + return exports; +} + +//模块注册 +NAPI_MODULE(SyncCallback, init); +``` + +javascript代码 + +```javascript +const { syncCallback } = require('SyncCallback.node'); + +syncCallback(function (data) { + console.log("sync callback"); +}); +console.log('completed'); +``` + +### 异步回调 + +native代码 + +```c++ +//异步回调数据 +typedef struct _AsyncCallbackInfo +{ + napi_async_work work; + napi_ref data; +} AsyncCallbackInfo ; + +//Native Function +napi_value AsyncCallback(napi_env env, napi_callback_info info) { + napi_value thisVar = nullptr; + unsigned int argc = 1; //需要接受参数的个数 + napi_value argv[1] = { 0 }; //存储参数空间 + void *data = nullptr; //用户指针 + + napi_status result_status = 0; + + result_status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); + + if(result_status != napi_ok) + { + napi_value errCode = nullptr; + napi_value errMessage = nullptr; + napi_value error = nullptr; + napi_create_string_utf8(env, "", NAPI_AUTOLENGTH, &errCode); //根据业务错误代码定义 + napi_create_string_utf8(env, "获取callback info失败!", NAPI_AUTOLENGTH, &errMessage); + napi_create_error(env, errCode, errMessage, &error); + return error; + } + + if(!(argc >= 1)) + { + napi_value errCode = nullptr; + napi_value errMessage = nullptr; + napi_value error = nullptr; + napi_create_string_utf8(env, "", NAPI_AUTOLENGTH, &errCode); //根据业务错误代码定义 + napi_create_string_utf8(env, "传递参数数量不足,至少需要一个字符串参数!", NAPI_AUTOLENGTH, &errMessage); + napi_create_error(env, errCode, errMessage, &error); + return error; + } + + napi_valuetype type; + result_status = napi_typeof(env, argv[0], &type); //获取参数类型 + if(type != native_function) //对比参数类型 + { + napi_value errCode = nullptr; + napi_value errMessage = nullptr; + napi_value error = nullptr; + napi_create_string_utf8(env, "", NAPI_AUTOLENGTH, &errCode); //根据业务错误代码定义 + napi_create_string_utf8(env, "传入参数类型错误!", NAPI_AUTOLENGTH, &errMessage); + napi_create_error(env, errCode, errMessage, &error); + return error; + } + + AsyncCallbackInfo *asyncCallbackInfo = new AsyncCallbackInfo { 0 }; + //创建引用值脱离当前作用域 + napi_create_reference(env, argv[0], 1, &callbackInfo.data); + //创建异步调用(仅示例中模拟异步回调使用),真实环境可以保存回调函数由其他函数或线程调用 + napi_create_async_work(env, + async_resource, + async_resource_name, + [](napi_env env, void *data) { + + }, + [](napi_env env, int status, void *data) { + AsyncCallbackInfo *asyncCallbackInfo = (AsyncCallbackInfo *)data; + napi_value result = 0; + napi_value cb = 0; + //获取引用值 + napi_get_reference_value(env, callbackInfo.data, &cb); + //调用回调函数 + napi_call_function(env, cb, 0, nullptr, &result); + //删除引用值 + napi_delete_reference(env, callbackInfo.data); + //删除异步 + napi_delete_async_work(env, callbackInfo.work); + //释放异步回调数据 + delete asyncCallbackInfo; + }, callbackInfo, &callbackInfo.work); + + napi_value result = nullptr; + napi_get_undefind(env, &result); + return result; +} + +//模块初始化函数 +napi_value init(napi_env env, napi_value exports) { + napi_status status; + napi_property_descriptor descriptors[] = { + { "asyncCallback", 0, AsyncCallback, 0, 0, 0, napi_default, 0, } + }; + status = napi_define_properties(env, exports, 1, descriptors); + assert(status == napi_ok); + return exports; +} + +//模块注册 +NAPI_MODULE(AsyncCallback, init); +``` + +javascript代码 + +```javascript +const { asyncCallback } require('AsyncCallback.node'); +asyncCallback(() => { + console.log("async callback"); +}); +console.log("completed"); +``` + +### Promise + +native代码 + +```C++ +//异步回调数据 +typedef struct _AsyncCallbackInfo +{ + napi_async_work work; + napi_deferred deferred; +} AsyncCallbackInfo ; + +//Native Function +napi_value AsyncCallback(napi_env env, napi_callback_info info) { + napi_value thisVar = nullptr; + void *data = nullptr; //用户指针 + + napi_status result_status = 0; + + result_status = napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data); + + if(result_status != napi_ok) + { + napi_value errCode = nullptr; + napi_value errMessage = nullptr; + napi_value error = nullptr; + napi_create_string_utf8(env, "", NAPI_AUTOLENGTH, &errCode); //根据业务错误代码定义 + napi_create_string_utf8(env, "获取callback info失败!", NAPI_AUTOLENGTH, &errMessage); + napi_create_error(env, errCode, errMessage, &error); + return error; + } + + //创建异步回调数据 + AsyncCallbackInfo *asyncCallbackInfo = new AsyncCallbackInfo { 0 }; + + napi_value promise = nullptr; + //创建Promise对象 + napi_create_promise(env, &asyncCallbackInfo->deferred, &promise); + + //创建异步调用(仅示例中模拟异步回调使用),真实环境可以保存deferred由其他线程或函数调用。 + napi_create_async_work(env, + async_resource,+ + async_resource_name, + [](napi_env env, void *data) { + + }, + [](napi_env env, int status, void *data) { + AsyncCallbackInfo *asyncCallbackInfo = (AsyncCallbackInfo *)data; + + if() //执行成功 + { + napi_value data = nullptr; + napi_create_string_utf8(env, "执行成功", NAPI_AUTOLENGTH, &data); + napi_resolve_deferred(env, asyncCallbackInfo->deferred, ); + } + else + { + napi_value reason = nullptr; + napi_create_string_utf8(env, "执行失败", NAPI_AUTOLENGTH, &reason); + napi_reject_deferred(env, asyncCallbackInfo->deferred, reason); + } + + //删除异步 + napi_delete_async_work(env, callbackInfo.work); + //释放异步回调数据 + delete asyncCallbackInfo; + }, callbackInfo, &callbackInfo->work); + + return promise; +} + +//模块初始化函数 +napi_value init(napi_env env, napi_value exports) { + napi_status status; + napi_property_descriptor descriptors[] = { + { "PromiseTest", 0, PromiseTest, 0, 0, 0, napi_default, 0, } + }; + status = napi_define_properties(env, exports, 1, descriptors); + assert(status == napi_ok); + return exports; +} + +//模块注册 +NAPI_MODULE(PromiseTest, init); +``` + +javascript代码 + +```javascript +const { PromiseTest } = require('PromiseTest.node'); + +PromiseTest() + .then(data => { + console.log('promise::then', data); + }) + .catch(reason => { + console.log("promise::catch", reason); + }); +``` + +## 结束语 + +N-API提供的接口为纯C的风格,对于C++开发者可选用[node-addon-api](https://github.com/nodejs/node-addon-api),其在N-API的基础上提供了C++对象模型以及异常处理。 + +## 参考资料 + +1. [N-API - Node.js v12 Documentation](https://nodejs.org/dist/latest-v12.x/docs/api/n-api.html) +2. [node-addon-examples - GitHub](https://github.com/nodejs/node-addon-examples/tree/master/1_hello_world/napi) diff --git a/napi_tool/image/frm.png b/napi_tool/image/frm.png new file mode 100644 index 0000000000000000000000000000000000000000..3a54e76ec893e81bd18b763b002fbac66943cbf1 Binary files /dev/null and b/napi_tool/image/frm.png differ diff --git a/napi_tool/image/image-20220106103805904.png b/napi_tool/image/image-20220106103805904.png new file mode 100644 index 0000000000000000000000000000000000000000..709dd675ecf30192ba315e7850b927c6fa9e9063 Binary files /dev/null and b/napi_tool/image/image-20220106103805904.png differ diff --git a/napi_tool/image/image-20220106104037879.png b/napi_tool/image/image-20220106104037879.png new file mode 100644 index 0000000000000000000000000000000000000000..a9fdb0571fe0e81d5659ea7cf306ae4eadbd2661 Binary files /dev/null and b/napi_tool/image/image-20220106104037879.png differ diff --git a/napi_tool/image/image-20220106105707675.png b/napi_tool/image/image-20220106105707675.png new file mode 100644 index 0000000000000000000000000000000000000000..2d97eae4d4d7ec0e136f046d68bd86d38c07e682 Binary files /dev/null and b/napi_tool/image/image-20220106105707675.png differ diff --git a/napi_tool/image/image-20220106110113948.png b/napi_tool/image/image-20220106110113948.png new file mode 100644 index 0000000000000000000000000000000000000000..5e1f0073c887b1f65de80207e0edf1b0fccdea3b Binary files /dev/null and b/napi_tool/image/image-20220106110113948.png differ diff --git a/napi_tool/image/image-20220106111154843.png b/napi_tool/image/image-20220106111154843.png new file mode 100644 index 0000000000000000000000000000000000000000..e4c6a40651e5b027398dcd0be065638d53949925 Binary files /dev/null and b/napi_tool/image/image-20220106111154843.png differ diff --git a/napi_tool/image/image-20220106111753702.png b/napi_tool/image/image-20220106111753702.png new file mode 100644 index 0000000000000000000000000000000000000000..7fb218dd974de93f323930920f595cf26bd36d2d Binary files /dev/null and b/napi_tool/image/image-20220106111753702.png differ diff --git a/napi_tool/image/image-20220106111909233.png b/napi_tool/image/image-20220106111909233.png new file mode 100644 index 0000000000000000000000000000000000000000..72ae0a886840fa702f3c067ca11d4443cc5aefa5 Binary files /dev/null and b/napi_tool/image/image-20220106111909233.png differ diff --git a/napi_tool/image/image-20220106145345449.png b/napi_tool/image/image-20220106145345449.png new file mode 100644 index 0000000000000000000000000000000000000000..f1e0ed1396ff4511806056770aee956a9d840ae5 Binary files /dev/null and b/napi_tool/image/image-20220106145345449.png differ diff --git a/napi_tool/image/image-20220106145540860.png b/napi_tool/image/image-20220106145540860.png new file mode 100644 index 0000000000000000000000000000000000000000..d6e4af228aa25ba9b778effd2b5c944e1cb57f02 Binary files /dev/null and b/napi_tool/image/image-20220106145540860.png differ diff --git a/napi_tool/image/image-20220106150434168.png b/napi_tool/image/image-20220106150434168.png new file mode 100644 index 0000000000000000000000000000000000000000..1ccd4705d23faa169db0f3dfec8baf17068bebaa Binary files /dev/null and b/napi_tool/image/image-20220106150434168.png differ diff --git a/napi_tool/image/image-20220106151044789.png b/napi_tool/image/image-20220106151044789.png new file mode 100644 index 0000000000000000000000000000000000000000..dbf3c56eda85bd4977fd3491e6d5d9748c5bcf5d Binary files /dev/null and b/napi_tool/image/image-20220106151044789.png differ diff --git a/napi_tool/image/image-20220106151204896.png b/napi_tool/image/image-20220106151204896.png new file mode 100644 index 0000000000000000000000000000000000000000..2af11305b1e8de042792ec23d719d7046ad0d7b2 Binary files /dev/null and b/napi_tool/image/image-20220106151204896.png differ diff --git a/napi_tool/image/image-20220106151510092.png b/napi_tool/image/image-20220106151510092.png new file mode 100644 index 0000000000000000000000000000000000000000..65cac858c162b9717407a6579f7927edc1da9511 Binary files /dev/null and b/napi_tool/image/image-20220106151510092.png differ diff --git a/napi_tool/image/image-20220106161108215.png b/napi_tool/image/image-20220106161108215.png new file mode 100644 index 0000000000000000000000000000000000000000..d579ef5e10db5b45874cfb24e5a56ba4d50721fb Binary files /dev/null and b/napi_tool/image/image-20220106161108215.png differ diff --git a/napi_tool/image/image-20220106161201896.png b/napi_tool/image/image-20220106161201896.png new file mode 100644 index 0000000000000000000000000000000000000000..80a39816e50bd07c2d6cb1854c3185c0cff21b5f Binary files /dev/null and b/napi_tool/image/image-20220106161201896.png differ diff --git a/napi_tool/image/image-20220106162517246.png b/napi_tool/image/image-20220106162517246.png new file mode 100644 index 0000000000000000000000000000000000000000..0d732af7f99f3671c9792c6e83c23a08f6bbaa7e Binary files /dev/null and b/napi_tool/image/image-20220106162517246.png differ diff --git a/napi_tool/output/cmd_gen-linux b/napi_tool/output/cmd_gen-linux new file mode 100755 index 0000000000000000000000000000000000000000..da6527c14855cb32dced17b2a2410bd86c26105e Binary files /dev/null and b/napi_tool/output/cmd_gen-linux differ diff --git a/napi_tool/output/cmd_gen-macos b/napi_tool/output/cmd_gen-macos new file mode 100644 index 0000000000000000000000000000000000000000..0c7d9a725f239c457339d9618b9eda0b1520df23 Binary files /dev/null and b/napi_tool/output/cmd_gen-macos differ diff --git a/napi_tool/output/cmd_gen-win.exe b/napi_tool/output/cmd_gen-win.exe new file mode 100644 index 0000000000000000000000000000000000000000..a940e261e47b3f49277d717eae2e1c3e0e2a4c04 Binary files /dev/null and b/napi_tool/output/cmd_gen-win.exe differ diff --git a/napi_tool/output/gnapi-0.0.1.vsix b/napi_tool/output/gnapi-0.0.1.vsix new file mode 100644 index 0000000000000000000000000000000000000000..9e9a5713064694d0486a2b4e877d96a06733ebe5 Binary files /dev/null and b/napi_tool/output/gnapi-0.0.1.vsix differ