feat: sub function
This commit is contained in:
commit
8362e0ec54
11
.gitignore
vendored
Normal file
11
.gitignore
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
/node_modules
|
||||||
|
/oh_modules
|
||||||
|
/local.properties
|
||||||
|
/.idea
|
||||||
|
**/build
|
||||||
|
/.hvigor
|
||||||
|
.cxx
|
||||||
|
/.clangd
|
||||||
|
/.clang-format
|
||||||
|
/.clang-tidy
|
||||||
|
**/.test
|
10
AppScope/app.json5
Normal file
10
AppScope/app.json5
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"app": {
|
||||||
|
"bundleName": "com.example.harmony_demo_napi",
|
||||||
|
"vendor": "example",
|
||||||
|
"versionCode": 1000000,
|
||||||
|
"versionName": "1.0.0",
|
||||||
|
"icon": "$media:app_icon",
|
||||||
|
"label": "$string:app_name"
|
||||||
|
}
|
||||||
|
}
|
8
AppScope/resources/base/element/string.json
Normal file
8
AppScope/resources/base/element/string.json
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"string": [
|
||||||
|
{
|
||||||
|
"name": "app_name",
|
||||||
|
"value": "harmony_demo_napi"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
BIN
AppScope/resources/base/media/app_icon.png
Normal file
BIN
AppScope/resources/base/media/app_icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
50
build-profile.json5
Normal file
50
build-profile.json5
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
{
|
||||||
|
"app": {
|
||||||
|
"signingConfigs": [
|
||||||
|
{
|
||||||
|
"name": "default",
|
||||||
|
"type": "HarmonyOS",
|
||||||
|
"material": {
|
||||||
|
"certpath": "C:\\Users\\Administrator\\.ohos\\config\\auto_debug_harmony_demo_napi_com.example.harmony_demo_napi_70086000144137060.cer",
|
||||||
|
"storePassword": "0000001BA1ED8F00F73AA9A394939AC6A63C32E438DF25C6F5BE025E0785D5C4B18D752D78CA3C52C72A0E",
|
||||||
|
"keyAlias": "debugKey",
|
||||||
|
"keyPassword": "0000001B9A7B57C755AB223A572604DB1A1B8FA572BB6BF59D2D4B51EC1DA51FD66A8376319D46990C6943",
|
||||||
|
"profile": "C:\\Users\\Administrator\\.ohos\\config\\auto_debug_harmony_demo_napi_com.example.harmony_demo_napi_70086000144137060.p7b",
|
||||||
|
"signAlg": "SHA256withECDSA",
|
||||||
|
"storeFile": "C:\\Users\\Administrator\\.ohos\\config\\auto_debug_harmony_demo_napi_com.example.harmony_demo_napi_70086000144137060.p12"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"products": [
|
||||||
|
{
|
||||||
|
"name": "default",
|
||||||
|
"signingConfig": "default",
|
||||||
|
"compileSdkVersion": "4.0.0(10)",
|
||||||
|
"compatibleSdkVersion": "4.0.0(10)",
|
||||||
|
"runtimeOS": "HarmonyOS",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"buildModeSet": [
|
||||||
|
{
|
||||||
|
"name": "debug",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "release"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"modules": [
|
||||||
|
{
|
||||||
|
"name": "entry",
|
||||||
|
"srcPath": "./entry",
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"name": "default",
|
||||||
|
"applyToProducts": [
|
||||||
|
"default"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
BIN
dependencies/hvigor-3.0.9-s.tgz
vendored
Normal file
BIN
dependencies/hvigor-3.0.9-s.tgz
vendored
Normal file
Binary file not shown.
BIN
dependencies/hvigor-ohos-arkui-x-plugin-2.1.7-s.tgz
vendored
Normal file
BIN
dependencies/hvigor-ohos-arkui-x-plugin-2.1.7-s.tgz
vendored
Normal file
Binary file not shown.
BIN
dependencies/hvigor-ohos-plugin-3.0.9-s.tgz
vendored
Normal file
BIN
dependencies/hvigor-ohos-plugin-3.0.9-s.tgz
vendored
Normal file
Binary file not shown.
BIN
dependencies/rollup.tgz
vendored
Normal file
BIN
dependencies/rollup.tgz
vendored
Normal file
Binary file not shown.
6
entry/.gitignore
vendored
Normal file
6
entry/.gitignore
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
/node_modules
|
||||||
|
/oh_modules
|
||||||
|
/.preview
|
||||||
|
/build
|
||||||
|
/.cxx
|
||||||
|
/.test
|
36
entry/build-profile.json5
Normal file
36
entry/build-profile.json5
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
"apiType": "stageMode",
|
||||||
|
"buildOption": {
|
||||||
|
"arkOptions": {
|
||||||
|
// "apPath": "./modules.ap" /* Profile used for profile-guided optimization (PGO), a compiler optimization technique to improve app runtime performance. */
|
||||||
|
},
|
||||||
|
"externalNativeOptions": {
|
||||||
|
"path": "./src/main/cpp/CMakeLists.txt",
|
||||||
|
"arguments": "",
|
||||||
|
"cppFlags": "",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"buildOptionSet": [
|
||||||
|
{
|
||||||
|
"name": "release",
|
||||||
|
"arkOptions": {
|
||||||
|
"obfuscation": {
|
||||||
|
"ruleOptions": {
|
||||||
|
"enable": true,
|
||||||
|
"files": [
|
||||||
|
"./obfuscation-rules.txt"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"name": "default"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ohosTest",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
6
entry/hvigorfile.ts
Normal file
6
entry/hvigorfile.ts
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import { hapTasks } from '@ohos/hvigor-ohos-plugin';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
|
||||||
|
plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
|
||||||
|
}
|
18
entry/obfuscation-rules.txt
Normal file
18
entry/obfuscation-rules.txt
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# Define project specific obfuscation rules here.
|
||||||
|
# You can include the obfuscation configuration files in the current module's build-profile.json5.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md
|
||||||
|
|
||||||
|
# Obfuscation options:
|
||||||
|
# -disable-obfuscation: disable all obfuscations
|
||||||
|
# -enable-property-obfuscation: obfuscate the property names
|
||||||
|
# -enable-toplevel-obfuscation: obfuscate the names in the global scope
|
||||||
|
# -compact: remove unnecessary blank spaces and all line feeds
|
||||||
|
# -remove-log: remove all console.* statements
|
||||||
|
# -print-namecache: print the name cache that contains the mapping from the old names to new names
|
||||||
|
# -apply-namecache: reuse the given cache file
|
||||||
|
|
||||||
|
# Keep options:
|
||||||
|
# -keep-property-name: specifies property names that you want to keep
|
||||||
|
# -keep-global-name: specifies names that you want to keep in the global scope
|
12
entry/oh-package.json5
Normal file
12
entry/oh-package.json5
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"license": "",
|
||||||
|
"devDependencies": {},
|
||||||
|
"author": "",
|
||||||
|
"name": "entry",
|
||||||
|
"description": "Please describe the basic information.",
|
||||||
|
"main": "",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"dependencies": {
|
||||||
|
"libentry.so": "file:./src/main/cpp/types/libentry"
|
||||||
|
}
|
||||||
|
}
|
11
entry/src/main/cpp/CMakeLists.txt
Normal file
11
entry/src/main/cpp/CMakeLists.txt
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# the minimum version of CMake.
|
||||||
|
cmake_minimum_required(VERSION 3.4.1)
|
||||||
|
project(harmony_demo_napi)
|
||||||
|
|
||||||
|
set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
||||||
|
include_directories(${NATIVERENDER_ROOT_PATH}
|
||||||
|
${NATIVERENDER_ROOT_PATH}/include)
|
||||||
|
|
||||||
|
add_library(entry SHARED hello.cpp)
|
||||||
|
target_link_libraries(entry PUBLIC libace_napi.z.so)
|
81
entry/src/main/cpp/hello.cpp
Normal file
81
entry/src/main/cpp/hello.cpp
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
#include "napi/native_api.h"
|
||||||
|
|
||||||
|
static napi_value Add(napi_env env, napi_callback_info info) {
|
||||||
|
size_t requireArgc = 2;
|
||||||
|
size_t argc = 2;
|
||||||
|
napi_value args[2] = {nullptr}; // 定义参数列表
|
||||||
|
|
||||||
|
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); // 从env中获取arkTs方法参数
|
||||||
|
|
||||||
|
napi_valuetype valuetype0, valuetype1;
|
||||||
|
napi_typeof(env, args[0], &valuetype0); // 获取参数类型,没用上
|
||||||
|
napi_typeof(env, args[1], &valuetype1);
|
||||||
|
|
||||||
|
double param0, param1;
|
||||||
|
napi_get_value_double(env, args[0], ¶m0); // 获取参数1值
|
||||||
|
napi_get_value_double(env, args[1], ¶m1); // 获取参数2值
|
||||||
|
|
||||||
|
double nativeSum = param0 + param1; // native侧的业务逻辑,这里简单以两数相加为例。
|
||||||
|
|
||||||
|
napi_value sum;
|
||||||
|
napi_create_double(env, nativeSum, &sum); // 计算结果赋值给返回值
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
static napi_value Sub(napi_env env, napi_callback_info info) {
|
||||||
|
size_t argc = 2;
|
||||||
|
napi_value args[2] = {nullptr};
|
||||||
|
|
||||||
|
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
|
||||||
|
|
||||||
|
double param0, param1;
|
||||||
|
napi_get_value_double(env, args[0], ¶m0);
|
||||||
|
napi_get_value_double(env, args[1], ¶m1);
|
||||||
|
|
||||||
|
double nativeRes = param0 - param1;
|
||||||
|
|
||||||
|
napi_value sub_value;
|
||||||
|
napi_create_double(env, nativeRes, &sub_value);
|
||||||
|
|
||||||
|
// [out = std::ref(std::cout << "Result from C code: " << 1 + 2)](int sum) {
|
||||||
|
// out.get() << ".\n";
|
||||||
|
// out.get() << "sum: " << sum << std::endl;
|
||||||
|
// }(100);
|
||||||
|
|
||||||
|
return sub_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXTERN_C_START
|
||||||
|
static napi_value Init(napi_env env, napi_value exports) {
|
||||||
|
napi_property_descriptor desc[] = {
|
||||||
|
{
|
||||||
|
.utf8name = "add",
|
||||||
|
.name = nullptr,
|
||||||
|
.method = Add,
|
||||||
|
.getter = nullptr,
|
||||||
|
.setter = nullptr,
|
||||||
|
.value = nullptr,
|
||||||
|
.attributes = napi_default,
|
||||||
|
.data = nullptr,
|
||||||
|
},
|
||||||
|
{"sub", nullptr, Sub, nullptr, nullptr, nullptr, napi_default, nullptr},
|
||||||
|
};
|
||||||
|
|
||||||
|
napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
|
||||||
|
|
||||||
|
return exports;
|
||||||
|
}
|
||||||
|
EXTERN_C_END
|
||||||
|
|
||||||
|
static napi_module demoModule = {
|
||||||
|
.nm_version = 1,
|
||||||
|
.nm_flags = 0,
|
||||||
|
.nm_filename = nullptr,
|
||||||
|
.nm_register_func = Init,
|
||||||
|
.nm_modname = "entry",
|
||||||
|
.nm_priv = ((void *)0),
|
||||||
|
.reserved = {0},
|
||||||
|
};
|
||||||
|
|
||||||
|
extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }
|
3
entry/src/main/cpp/types/libentry/index.d.ts
vendored
Normal file
3
entry/src/main/cpp/types/libentry/index.d.ts
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
export const add: (a: number, b: number) => number;
|
||||||
|
|
||||||
|
export const sub: (a: number, b: number) => number;
|
6
entry/src/main/cpp/types/libentry/oh-package.json5
Normal file
6
entry/src/main/cpp/types/libentry/oh-package.json5
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"name": "libentry.so",
|
||||||
|
"types": "./index.d.ts",
|
||||||
|
"version": "",
|
||||||
|
"description": "Please describe the basic information."
|
||||||
|
}
|
43
entry/src/main/ets/entryability/EntryAbility.ets
Normal file
43
entry/src/main/ets/entryability/EntryAbility.ets
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
|
||||||
|
import hilog from '@ohos.hilog';
|
||||||
|
import UIAbility from '@ohos.app.ability.UIAbility';
|
||||||
|
import Want from '@ohos.app.ability.Want';
|
||||||
|
import window from '@ohos.window';
|
||||||
|
|
||||||
|
export default class EntryAbility extends UIAbility {
|
||||||
|
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
|
||||||
|
}
|
||||||
|
|
||||||
|
onDestroy(): void {
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
|
||||||
|
}
|
||||||
|
|
||||||
|
onWindowStageCreate(windowStage: window.WindowStage): void {
|
||||||
|
// Main window is created, set main page for this ability
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
|
||||||
|
|
||||||
|
windowStage.loadContent('pages/Index', (err, data) => {
|
||||||
|
if (err.code) {
|
||||||
|
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onWindowStageDestroy(): void {
|
||||||
|
// Main window is destroyed, release UI related resources
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
|
||||||
|
}
|
||||||
|
|
||||||
|
onForeground(): void {
|
||||||
|
// Ability has brought to foreground
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
|
||||||
|
}
|
||||||
|
|
||||||
|
onBackground(): void {
|
||||||
|
// Ability has back to background
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
|
||||||
|
}
|
||||||
|
};
|
37
entry/src/main/ets/pages/Index.ets
Normal file
37
entry/src/main/ets/pages/Index.ets
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
import hilog from '@ohos.hilog';
|
||||||
|
import testNapi from 'libentry.so';
|
||||||
|
|
||||||
|
@Entry
|
||||||
|
@Component
|
||||||
|
struct Index {
|
||||||
|
@State message: string = 'Hello World';
|
||||||
|
@State res: number = 0
|
||||||
|
|
||||||
|
build() {
|
||||||
|
Row() {
|
||||||
|
Column() {
|
||||||
|
Text(String(this.res))
|
||||||
|
.fontSize(50)
|
||||||
|
.fontWeight(FontWeight.Bold)
|
||||||
|
|
||||||
|
Row({ space: 2 }) {
|
||||||
|
Button('add')
|
||||||
|
.onClick(() => {
|
||||||
|
const res = testNapi.add(2, 3)
|
||||||
|
hilog.info(0x0000, 'testTag', 'Test NAPI 2 + 3 = %{public}d', res)
|
||||||
|
this.res += res
|
||||||
|
})
|
||||||
|
|
||||||
|
Button('sub')
|
||||||
|
.onClick(() => {
|
||||||
|
const res = testNapi.sub(10, 5)
|
||||||
|
hilog.info(0x0000, 'testTag', 'Test NAPI 10 - 5 = %{public}d', res)
|
||||||
|
this.res -= res
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.width('100%')
|
||||||
|
}
|
||||||
|
.height('100%')
|
||||||
|
}
|
||||||
|
}
|
38
entry/src/main/module.json5
Normal file
38
entry/src/main/module.json5
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"module": {
|
||||||
|
"name": "entry",
|
||||||
|
"type": "entry",
|
||||||
|
"description": "$string:module_desc",
|
||||||
|
"mainElement": "EntryAbility",
|
||||||
|
"deviceTypes": [
|
||||||
|
"phone",
|
||||||
|
"tablet",
|
||||||
|
"2in1"
|
||||||
|
],
|
||||||
|
"deliveryWithInstall": true,
|
||||||
|
"installationFree": false,
|
||||||
|
"pages": "$profile:main_pages",
|
||||||
|
"abilities": [
|
||||||
|
{
|
||||||
|
"name": "EntryAbility",
|
||||||
|
"srcEntry": "./ets/entryability/EntryAbility.ets",
|
||||||
|
"description": "$string:EntryAbility_desc",
|
||||||
|
"icon": "$media:icon",
|
||||||
|
"label": "$string:EntryAbility_label",
|
||||||
|
"startWindowIcon": "$media:startIcon",
|
||||||
|
"startWindowBackground": "$color:start_window_background",
|
||||||
|
"exported": true,
|
||||||
|
"skills": [
|
||||||
|
{
|
||||||
|
"entities": [
|
||||||
|
"entity.system.home"
|
||||||
|
],
|
||||||
|
"actions": [
|
||||||
|
"action.system.home"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
8
entry/src/main/resources/base/element/color.json
Normal file
8
entry/src/main/resources/base/element/color.json
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"color": [
|
||||||
|
{
|
||||||
|
"name": "start_window_background",
|
||||||
|
"value": "#FFFFFF"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
16
entry/src/main/resources/base/element/string.json
Normal file
16
entry/src/main/resources/base/element/string.json
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"string": [
|
||||||
|
{
|
||||||
|
"name": "module_desc",
|
||||||
|
"value": "module description"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "EntryAbility_desc",
|
||||||
|
"value": "description"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "EntryAbility_label",
|
||||||
|
"value": "napi"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
BIN
entry/src/main/resources/base/media/icon.png
Normal file
BIN
entry/src/main/resources/base/media/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
BIN
entry/src/main/resources/base/media/startIcon.png
Normal file
BIN
entry/src/main/resources/base/media/startIcon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
5
entry/src/main/resources/base/profile/main_pages.json
Normal file
5
entry/src/main/resources/base/profile/main_pages.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"src": [
|
||||||
|
"pages/Index"
|
||||||
|
]
|
||||||
|
}
|
16
entry/src/main/resources/en_US/element/string.json
Normal file
16
entry/src/main/resources/en_US/element/string.json
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"string": [
|
||||||
|
{
|
||||||
|
"name": "module_desc",
|
||||||
|
"value": "module description"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "EntryAbility_desc",
|
||||||
|
"value": "description"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "EntryAbility_label",
|
||||||
|
"value": "label"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
16
entry/src/main/resources/zh_CN/element/string.json
Normal file
16
entry/src/main/resources/zh_CN/element/string.json
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"string": [
|
||||||
|
{
|
||||||
|
"name": "module_desc",
|
||||||
|
"value": "模块描述"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "EntryAbility_desc",
|
||||||
|
"value": "description"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "EntryAbility_label",
|
||||||
|
"value": "label"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
35
entry/src/ohosTest/ets/test/Ability.test.ets
Normal file
35
entry/src/ohosTest/ets/test/Ability.test.ets
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import hilog from '@ohos.hilog';
|
||||||
|
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
|
||||||
|
|
||||||
|
export default function abilityTest() {
|
||||||
|
describe('ActsAbilityTest', () => {
|
||||||
|
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
|
||||||
|
beforeAll(() => {
|
||||||
|
// Presets an action, which is performed only once before all test cases of the test suite start.
|
||||||
|
// This API supports only one parameter: preset action function.
|
||||||
|
})
|
||||||
|
beforeEach(() => {
|
||||||
|
// Presets an action, which is performed before each unit test case starts.
|
||||||
|
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||||
|
// This API supports only one parameter: preset action function.
|
||||||
|
})
|
||||||
|
afterEach(() => {
|
||||||
|
// Presets a clear action, which is performed after each unit test case ends.
|
||||||
|
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||||
|
// This API supports only one parameter: clear action function.
|
||||||
|
})
|
||||||
|
afterAll(() => {
|
||||||
|
// Presets a clear action, which is performed after all test cases of the test suite end.
|
||||||
|
// This API supports only one parameter: clear action function.
|
||||||
|
})
|
||||||
|
it('assertContain', 0, () => {
|
||||||
|
// Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'it begin');
|
||||||
|
let a = 'abc';
|
||||||
|
let b = 'b';
|
||||||
|
// Defines a variety of assertion methods, which are used to declare expected boolean conditions.
|
||||||
|
expect(a).assertContain(b);
|
||||||
|
expect(a).assertEqual(a);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
5
entry/src/ohosTest/ets/test/List.test.ets
Normal file
5
entry/src/ohosTest/ets/test/List.test.ets
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import abilityTest from './Ability.test';
|
||||||
|
|
||||||
|
export default function testsuite() {
|
||||||
|
abilityTest();
|
||||||
|
}
|
50
entry/src/ohosTest/ets/testability/TestAbility.ets
Normal file
50
entry/src/ohosTest/ets/testability/TestAbility.ets
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
import UIAbility from '@ohos.app.ability.UIAbility';
|
||||||
|
import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
|
||||||
|
import hilog from '@ohos.hilog';
|
||||||
|
import { Hypium } from '@ohos/hypium';
|
||||||
|
import testsuite from '../test/List.test';
|
||||||
|
import window from '@ohos.window';
|
||||||
|
import Want from '@ohos.app.ability.Want';
|
||||||
|
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
|
||||||
|
|
||||||
|
export default class TestAbility extends UIAbility {
|
||||||
|
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate');
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? '');
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:' + JSON.stringify(launchParam) ?? '');
|
||||||
|
let abilityDelegator: AbilityDelegatorRegistry.AbilityDelegator;
|
||||||
|
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
|
||||||
|
let abilityDelegatorArguments: AbilityDelegatorRegistry.AbilityDelegatorArgs;
|
||||||
|
abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments();
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!');
|
||||||
|
Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite);
|
||||||
|
}
|
||||||
|
|
||||||
|
onDestroy() {
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy');
|
||||||
|
}
|
||||||
|
|
||||||
|
onWindowStageCreate(windowStage: window.WindowStage) {
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate');
|
||||||
|
windowStage.loadContent('testability/pages/Index', (err, data) => {
|
||||||
|
if (err.code) {
|
||||||
|
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s',
|
||||||
|
JSON.stringify(data) ?? '');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onWindowStageDestroy() {
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy');
|
||||||
|
}
|
||||||
|
|
||||||
|
onForeground() {
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground');
|
||||||
|
}
|
||||||
|
|
||||||
|
onBackground() {
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground');
|
||||||
|
}
|
||||||
|
}
|
17
entry/src/ohosTest/ets/testability/pages/Index.ets
Normal file
17
entry/src/ohosTest/ets/testability/pages/Index.ets
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
@Entry
|
||||||
|
@Component
|
||||||
|
struct Index {
|
||||||
|
@State message: string = 'Hello World';
|
||||||
|
|
||||||
|
build() {
|
||||||
|
Row() {
|
||||||
|
Column() {
|
||||||
|
Text(this.message)
|
||||||
|
.fontSize(50)
|
||||||
|
.fontWeight(FontWeight.Bold)
|
||||||
|
}
|
||||||
|
.width('100%')
|
||||||
|
}
|
||||||
|
.height('100%')
|
||||||
|
}
|
||||||
|
}
|
47
entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ets
Normal file
47
entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ets
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
import hilog from '@ohos.hilog';
|
||||||
|
import TestRunner from '@ohos.application.testRunner';
|
||||||
|
import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
|
||||||
|
import Want from '@ohos.app.ability.Want';
|
||||||
|
|
||||||
|
let abilityDelegator: AbilityDelegatorRegistry.AbilityDelegator | undefined = undefined
|
||||||
|
let abilityDelegatorArguments: AbilityDelegatorRegistry.AbilityDelegatorArgs | undefined = undefined
|
||||||
|
|
||||||
|
async function onAbilityCreateCallback() {
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'onAbilityCreateCallback');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function addAbilityMonitorCallback(err : Error) {
|
||||||
|
hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? '');
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class OpenHarmonyTestRunner implements TestRunner {
|
||||||
|
constructor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
onPrepare() {
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare ');
|
||||||
|
}
|
||||||
|
|
||||||
|
async onRun() {
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun run');
|
||||||
|
abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments()
|
||||||
|
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator()
|
||||||
|
const bundleName = abilityDelegatorArguments.bundleName;
|
||||||
|
const testAbilityName = 'TestAbility';
|
||||||
|
let lMonitor: AbilityDelegatorRegistry.AbilityMonitor = {
|
||||||
|
abilityName: testAbilityName,
|
||||||
|
onAbilityCreate: onAbilityCreateCallback,
|
||||||
|
};
|
||||||
|
abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback)
|
||||||
|
const want: Want = {
|
||||||
|
bundleName: bundleName,
|
||||||
|
abilityName: testAbilityName
|
||||||
|
};
|
||||||
|
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
|
||||||
|
abilityDelegator.startAbility(want, (err, data) => {
|
||||||
|
hilog.info(0x0000, 'testTag', 'startAbility : err : %{public}s', JSON.stringify(err) ?? '');
|
||||||
|
hilog.info(0x0000, 'testTag', 'startAbility : data : %{public}s',JSON.stringify(data) ?? '');
|
||||||
|
})
|
||||||
|
hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun end');
|
||||||
|
}
|
||||||
|
}
|
38
entry/src/ohosTest/module.json5
Normal file
38
entry/src/ohosTest/module.json5
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"module": {
|
||||||
|
"name": "entry_test",
|
||||||
|
"type": "feature",
|
||||||
|
"description": "$string:module_test_desc",
|
||||||
|
"mainElement": "TestAbility",
|
||||||
|
"deviceTypes": [
|
||||||
|
"phone",
|
||||||
|
"tablet",
|
||||||
|
"2in1"
|
||||||
|
],
|
||||||
|
"deliveryWithInstall": true,
|
||||||
|
"installationFree": false,
|
||||||
|
"pages": "$profile:test_pages",
|
||||||
|
"abilities": [
|
||||||
|
{
|
||||||
|
"name": "TestAbility",
|
||||||
|
"srcEntry": "./ets/testability/TestAbility.ets",
|
||||||
|
"description": "$string:TestAbility_desc",
|
||||||
|
"icon": "$media:icon",
|
||||||
|
"label": "$string:TestAbility_label",
|
||||||
|
"exported": true,
|
||||||
|
"startWindowIcon": "$media:icon",
|
||||||
|
"startWindowBackground": "$color:start_window_background",
|
||||||
|
"skills": [
|
||||||
|
{
|
||||||
|
"actions": [
|
||||||
|
"action.system.home"
|
||||||
|
],
|
||||||
|
"entities": [
|
||||||
|
"entity.system.home"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
8
entry/src/ohosTest/resources/base/element/color.json
Normal file
8
entry/src/ohosTest/resources/base/element/color.json
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"color": [
|
||||||
|
{
|
||||||
|
"name": "start_window_background",
|
||||||
|
"value": "#FFFFFF"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
16
entry/src/ohosTest/resources/base/element/string.json
Normal file
16
entry/src/ohosTest/resources/base/element/string.json
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"string": [
|
||||||
|
{
|
||||||
|
"name": "module_test_desc",
|
||||||
|
"value": "test ability description"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "TestAbility_desc",
|
||||||
|
"value": "the test ability"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "TestAbility_label",
|
||||||
|
"value": "test label"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
BIN
entry/src/ohosTest/resources/base/media/icon.png
Normal file
BIN
entry/src/ohosTest/resources/base/media/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.6 KiB |
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"src": [
|
||||||
|
"testability/pages/Index"
|
||||||
|
]
|
||||||
|
}
|
5
entry/src/test/List.test.ets
Normal file
5
entry/src/test/List.test.ets
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import localUnitTest from './LocalUnit.test';
|
||||||
|
|
||||||
|
export default function testsuite() {
|
||||||
|
localUnitTest();
|
||||||
|
}
|
33
entry/src/test/LocalUnit.test.ets
Normal file
33
entry/src/test/LocalUnit.test.ets
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
|
||||||
|
|
||||||
|
export default function localUnitTest() {
|
||||||
|
describe('localUnitTest',() => {
|
||||||
|
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
|
||||||
|
beforeAll(() => {
|
||||||
|
// Presets an action, which is performed only once before all test cases of the test suite start.
|
||||||
|
// This API supports only one parameter: preset action function.
|
||||||
|
});
|
||||||
|
beforeEach(() => {
|
||||||
|
// Presets an action, which is performed before each unit test case starts.
|
||||||
|
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||||
|
// This API supports only one parameter: preset action function.
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
// Presets a clear action, which is performed after each unit test case ends.
|
||||||
|
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||||
|
// This API supports only one parameter: clear action function.
|
||||||
|
});
|
||||||
|
afterAll(() => {
|
||||||
|
// Presets a clear action, which is performed after all test cases of the test suite end.
|
||||||
|
// This API supports only one parameter: clear action function.
|
||||||
|
});
|
||||||
|
it('assertContain', 0, () => {
|
||||||
|
// Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
|
||||||
|
let a = 'abc';
|
||||||
|
let b = 'b';
|
||||||
|
// Defines a variety of assertion methods, which are used to declare expected boolean conditions.
|
||||||
|
expect(a).assertContain(b);
|
||||||
|
expect(a).assertEqual(a);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
19
hvigor/hvigor-config.json5
Normal file
19
hvigor/hvigor-config.json5
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"hvigorVersion": "file:../dependencies/hvigor-3.0.9-s.tgz",
|
||||||
|
"dependencies": {
|
||||||
|
"@ohos/hvigor-ohos-plugin": "file:../dependencies/hvigor-ohos-plugin-3.0.9-s.tgz",
|
||||||
|
"rollup": "file:../dependencies/rollup.tgz"
|
||||||
|
},
|
||||||
|
"execution": {
|
||||||
|
// "daemon": true, /* Enable daemon compilation. Default: true */
|
||||||
|
// "incremental": true, /* Enable incremental compilation. Default: true */
|
||||||
|
// "parallel": true, /* Enable parallel compilation. Default: true */
|
||||||
|
// "typeCheck": false, /* Enable typeCheck. Default: false */
|
||||||
|
},
|
||||||
|
"logging": {
|
||||||
|
// "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */
|
||||||
|
},
|
||||||
|
"debugging": {
|
||||||
|
// "stacktrace": false /* Disable stacktrace compilation. Default: false */
|
||||||
|
}
|
||||||
|
}
|
1
hvigor/hvigor-wrapper.js
Normal file
1
hvigor/hvigor-wrapper.js
Normal file
File diff suppressed because one or more lines are too long
6
hvigorfile.ts
Normal file
6
hvigorfile.ts
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import { appTasks } from '@ohos/hvigor-ohos-plugin';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
|
||||||
|
plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
|
||||||
|
}
|
48
hvigorw
Normal file
48
hvigorw
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
# Hvigor startup script, version 1.0.0
|
||||||
|
#
|
||||||
|
# Required ENV vars:
|
||||||
|
# ------------------
|
||||||
|
# NODE_HOME - location of a Node home dir
|
||||||
|
# or
|
||||||
|
# Add /usr/local/nodejs/bin to the PATH environment variable
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
HVIGOR_APP_HOME="`pwd -P`"
|
||||||
|
HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js
|
||||||
|
warn() {
|
||||||
|
echo ""
|
||||||
|
echo -e "\033[1;33m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
error() {
|
||||||
|
echo ""
|
||||||
|
echo -e "\033[1;31m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
fail() {
|
||||||
|
error "$@"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Determine node to start hvigor wrapper script
|
||||||
|
if [ -n "${NODE_HOME}" ];then
|
||||||
|
EXECUTABLE_NODE="${NODE_HOME}/bin/node"
|
||||||
|
if [ ! -x "$EXECUTABLE_NODE" ];then
|
||||||
|
fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
EXECUTABLE_NODE="node"
|
||||||
|
which ${EXECUTABLE_NODE} > /dev/null 2>&1 || fail "ERROR: NODE_HOME is not set and not 'node' command found in your path"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check hvigor wrapper script
|
||||||
|
if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ];then
|
||||||
|
fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# start hvigor-wrapper script
|
||||||
|
exec "${EXECUTABLE_NODE}" \
|
||||||
|
"${HVIGOR_WRAPPER_SCRIPT}" "$@"
|
64
hvigorw.bat
Normal file
64
hvigorw.bat
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Hvigor startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||||
|
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||||
|
|
||||||
|
set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js
|
||||||
|
set NODE_EXE=node.exe
|
||||||
|
|
||||||
|
goto start
|
||||||
|
|
||||||
|
:start
|
||||||
|
@rem Find node.exe
|
||||||
|
if defined NODE_HOME goto findNodeFromNodeHome
|
||||||
|
|
||||||
|
%NODE_EXE% --version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto execute
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the NODE_HOME variable in your environment to match the
|
||||||
|
echo location of your NodeJs installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findNodeFromNodeHome
|
||||||
|
set NODE_HOME=%NODE_HOME:"=%
|
||||||
|
set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE%
|
||||||
|
|
||||||
|
if exist "%NODE_EXE_PATH%" goto execute
|
||||||
|
echo.
|
||||||
|
echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the NODE_HOME variable in your environment to match the
|
||||||
|
echo location of your NodeJs installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Execute hvigor
|
||||||
|
"%NODE_EXE%" "%WRAPPER_MODULE_PATH%" %*
|
||||||
|
|
||||||
|
if "%ERRORLEVEL%" == "0" goto hvigorwEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:hvigorwEnd
|
||||||
|
if "%OS%" == "Windows_NT" endlocal
|
||||||
|
|
||||||
|
:end
|
13
oh-package-lock.json5
Normal file
13
oh-package-lock.json5
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"lockfileVersion": 1,
|
||||||
|
"ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
|
||||||
|
"specifiers": {
|
||||||
|
"@ohos/hypium@1.0.11": "@ohos/hypium@1.0.11"
|
||||||
|
},
|
||||||
|
"packages": {
|
||||||
|
"@ohos/hypium@1.0.11": {
|
||||||
|
"resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.11.tgz",
|
||||||
|
"integrity": "sha512-KawcLnv43C3QIYv1UbDnKCFX3MohtDxGuFvzlUxT/qf2DBilR56Ws6zrj90LdH6PjloJQwOPESuBQIHBACAK7w=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
12
oh-package.json5
Normal file
12
oh-package.json5
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"license": "",
|
||||||
|
"devDependencies": {
|
||||||
|
"@ohos/hypium": "1.0.11"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"name": "harmony_demo_napi",
|
||||||
|
"description": "Please describe the basic information.",
|
||||||
|
"main": "",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"dependencies": {}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user