@atomicservice/ascf-toolkit-hvigor-plugin 1.0.0 → 1.0.1-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.ts CHANGED
@@ -1,3 +1,7 @@
1
+ import { default as ascfPlugin } from './src/plugin/ascf-toolkit-hvigor-plugin';
1
2
 
2
- import ascfPlugin from './src/plugin/ascf-toolkit-hvigor-plugin';
3
+ export { default as signByBuildModePlugin } from './src/plugin/sign-by-build-mode-plugin';
4
+ export { default as modifyShareInfoPlugin } from './src/plugin/modifyShareInfoPlugin';
5
+ export { default as installAscfHspPlugin } from './src/plugin/installAscfHspPlugin';
6
+ export { ascfPlugin };
3
7
  export default ascfPlugin;
package/package.json CHANGED
@@ -1,13 +1,15 @@
1
1
  {
2
2
  "name": "@atomicservice/ascf-toolkit-hvigor-plugin",
3
- "version": "1.0.0",
3
+ "version": "1.0.1-beta.0",
4
4
  "title": "ASCF toolkit hvigor plugin for atomicservice",
5
5
  "description": "ASCF toolkit hvigor plugin for atomicservice",
6
- "main": "index.js",
6
+ "main": "index.ts",
7
7
  "author": "atomicservice",
8
+ "type": "module",
8
9
  "devDependencies": {
9
10
  "@ohos/hvigor": "5.8.9",
10
- "@ohos/hvigor-ohos-plugin": "5.8.9"
11
+ "@ohos/hvigor-ohos-plugin": "5.8.9",
12
+ "@atomicservice/ascf-toolkit": "*"
11
13
  },
12
14
  "scripts": {
13
15
  "test": "echo \"Error: no test specified\" && exit 1"
@@ -0,0 +1,3 @@
1
+ {
2
+ "ascfHspUrl": "https://h5hosting-drcn.dbankcdn.cn/cch5/wallet/ascf-cn/ascfHsp.html?auto=1"
3
+ }
@@ -1,64 +1,106 @@
1
- import { OhosPluginId, OhosAppContext } from '@ohos/hvigor-ohos-plugin';
2
- import { hvigor, HvigorNode, HvigorPlugin } from '@ohos/hvigor';
3
- import { exec, execSync } from 'child_process';
1
+ import { OhosAppContext, OhosPluginId } from '@ohos/hvigor-ohos-plugin';
2
+ import { Property } from '@ohos/hvigor-ohos-plugin/src/sdk/lib/property-get';
3
+ import { PropertyConst } from '@ohos/hvigor-ohos-plugin/src/const/property-const';
4
+ import { hvigor, HvigorLogger, HvigorNode, HvigorPlugin } from '@ohos/hvigor';
5
+ import ascf from '@atomicservice/ascf-toolkit';
6
+ import { exec } from 'child_process';
7
+ import path from 'path';
4
8
  import os from 'os';
5
9
 
6
- export default function ascfToolkitHvigorPlugin(): HvigorPlugin {
7
- return {
8
- pluginId: 'ascfToolkitHvigorPlugin',
9
- apply(node: HvigorNode) {
10
- hvigor.nodesEvaluated(async () => {
11
- const existCmdStr = getExistCmdStr();
12
- if (!await existCmd(existCmdStr)) {
13
- const installAscfCmd = `npm install -g @atomicservice/ascf-toolkit`;
14
- console.log(`start exec [${installAscfCmd}]`);
15
- try {
16
- const output = execSync(installAscfCmd, { stdio: 'inherit' });
17
- console.log(output);
18
- } catch (error) {
19
- console.error('ERROR: failed to install the ascf dependency');
20
- console.info(`INFO: run the [${installAscfCmd}] command to install the dependency`)
21
- return;
22
- }
23
- }
24
- const appContext = node.getContext(OhosPluginId.OHOS_APP_PLUGIN) as OhosAppContext;
25
- const cmd = `ascf compile -c ${appContext.getProjectPath()}`;
26
- console.log(`INFO: start exec [${cmd}]`);
27
- const output = execSync(cmd, { stdio: 'inherit' });
28
- console.log(output);
10
+ import { doModifyShareInfoPlugin } from './modifyShareInfoPlugin';
11
+ import { doInstallAscfHspPlugin } from './installAscfHspPlugin';
12
+
13
+ const logger = HvigorLogger.getLogger('ascfPlugin');
14
+
15
+ export interface AscfPluginOptions {
16
+ fixSharedHsp: true,
17
+ installAscfHsp: true,
18
+ debug: true,
19
+ }
20
+
21
+ const DEFAULT_OPTIONS: AscfPluginOptions = {
22
+ fixSharedHsp: true,
23
+ installAscfHsp: true,
24
+ debug: true,
25
+ };
26
+
27
+ export default function ascfToolkitHvigorPlugin(options: AscfPluginOptions): HvigorPlugin {
28
+ return {
29
+ pluginId: 'ascfToolkitHvigorPlugin',
30
+ apply(node: HvigorNode) {
31
+ const opts = Object.assign({}, DEFAULT_OPTIONS, options);
32
+
33
+ hvigor.nodesEvaluated(async () => {
34
+ await execPlugin(opts, node);
35
+
36
+ try {
37
+ if (hvigor.isCommandEntryTask('GetHvigorDepsCachesDir')) {
38
+ node.registerTask({
39
+ name: 'GetHvigorDepsCachesDir',
40
+ run() {
41
+ console.log('ASCF_GET_HVIGOR_DEPS_CACHES_DIR=' + ascf.getAscfToolkitDirname());
42
+ },
29
43
  });
44
+ } else {
45
+ logger.debug('start exec ascf compile');
46
+ const appContext = node.getContext(OhosPluginId.OHOS_APP_PLUGIN) as OhosAppContext;
47
+ const buildMode = appContext.getBuildMode();
48
+ const nodeExe = getNodeExe();
49
+ const ascfScript = getAscfScript();
50
+ let cmd = `\"${nodeExe}\" \"${ascfScript}\" compile -c ${buildMode === 'debug' ? '-m' : ''} ${appContext.getProjectPath()}`;
51
+
52
+ if (opts.debug && logger.getLevel().levelStr === 'DEBUG') {
53
+ cmd += ' --debug';
54
+ }
55
+
56
+ await executeCommand(cmd);
57
+ logger.debug('ascf compile completed');
58
+ }
59
+ } catch (err: any) {
60
+ logger.errorExit(new Error(err));
30
61
  }
62
+ });
31
63
  }
64
+ };
32
65
  }
33
66
 
34
- function executeCommand(command: string) {
35
- return new Promise((resolve, reject) => {
36
- exec(command, (error, stdout, stderr) => {
37
- if (error) {
38
- reject(error);
39
- } else {
40
- resolve(stdout);
41
- }
42
- });
43
- });
67
+ async function execPlugin(opts: AscfPluginOptions, node: HvigorNode) {
68
+ const entryNode = hvigor.getNodeByName('entry');
69
+ if (entryNode && opts.fixSharedHsp) {
70
+ await doModifyShareInfoPlugin(entryNode).catch(err => logger.error(err));
71
+ }
72
+ if (entryNode && opts.installAscfHsp) {
73
+ await doInstallAscfHspPlugin(node).catch(err => logger.error(err));
74
+ }
44
75
  }
45
76
 
46
- async function existCmd(command: string){
47
- let res;
48
- await executeCommand(command)
49
- .then((result) => {
50
- res = true;
51
- })
52
- .catch((error) => {
53
- res = false;
54
- })
55
- return res;
77
+ function executeCommand(command: string) {
78
+ return new Promise((resolve, reject) => {
79
+ exec(command, (error: any, stdout: any, stderr: string) => {
80
+ if (error) {
81
+ reject(error);
82
+ } else {
83
+ logger.debug(stderr);
84
+ logger.debug(stdout);
85
+ resolve(stderr);
86
+ }
87
+ });
88
+ });
56
89
  }
57
90
 
58
- function getExistCmdStr() {
59
- if (os.platform() === 'win32') {
60
- return 'where ascf';
61
- }
62
- return 'which ascf';
91
+ function getNodeExe() {
92
+ const property: Property = new Property();
93
+ const nodeDir = property.getProperty(PropertyConst.NPM_DIR);
94
+ const platform = os.platform();
95
+ if (platform === 'win32') {
96
+ return path.join(nodeDir, 'node.exe');
97
+ } else if (platform === 'darwin' || platform === 'linux') {
98
+ return path.join(nodeDir, 'node');
99
+ } else {
100
+ return 'node';
101
+ }
63
102
  }
64
103
 
104
+ function getAscfScript() {
105
+ return path.join(ascf.getAscfToolkitDirname(), 'bin', 'ascf.js');
106
+ }
@@ -0,0 +1,94 @@
1
+ import type { HvigorNode, HvigorPlugin } from '@ohos/hvigor';
2
+ import { hvigor, HvigorLogger } from '@ohos/hvigor';
3
+ import { OhosAppContext, OhosHapContext, OhosPluginId, Target } from '@ohos/hvigor-ohos-plugin';
4
+ import { execSync } from 'child_process';
5
+ import path from 'path';
6
+ import fs from 'fs';
7
+
8
+ const logger = HvigorLogger.getLogger('modifyShareInfoPlugin');
9
+
10
+ function execSafe(cmd: string) {
11
+ try {
12
+ return execSync(cmd)?.toString('utf8');
13
+ } catch (e) {
14
+ logger.warn('exec cmd error', e);
15
+ }
16
+ }
17
+
18
+ const BUNDLE_NAME_ASCF = 'com.huawei.hms.ascf';
19
+ const ERR_MSG = `${BUNDLE_NAME_ASCF} install failed, please open helloUniapp manually.`;
20
+
21
+ function checkAscfHsp() {
22
+ logger.debug(`Check and install ${BUNDLE_NAME_ASCF} for local development`);
23
+ const sharedInfo = execSafe(`hdc shell bm dump-shared -a`);
24
+ if (sharedInfo?.includes(BUNDLE_NAME_ASCF)) {
25
+ const verInfo = execSafe(`hdc shell "bm dump-shared -n ${BUNDLE_NAME_ASCF} | grep versionName"`);
26
+ logger.debug(`found ${BUNDLE_NAME_ASCF} ${verInfo}`);
27
+ return true;
28
+ }
29
+ return false;
30
+ }
31
+
32
+ function doInstallAscfHsp(resolve: any, reject: any) {
33
+ if (checkAscfHsp()) {
34
+ resolve();
35
+ return;
36
+ }
37
+
38
+ logger.debug(`trying to install ${BUNDLE_NAME_ASCF}`);
39
+ const configJsonPath = path.resolve(__dirname, '../config.json');
40
+ const configJson = JSON.parse(fs.readFileSync(configJsonPath).toString());
41
+ const startInfo = execSafe(`hdc shell aa start -b com.huawei.hmos.browser -a MainAbility -A ohos.want.action.viewData -U "${configJson.ascfHspUrl}"`);
42
+ if (!startInfo?.includes('successfully')) {
43
+ logger.warn(`${ERR_MSG} errorInfo=${startInfo}`);
44
+ reject(ERR_MSG);
45
+ return;
46
+ }
47
+
48
+ logger.debug(`begin to wait install hsp`);
49
+ let needWait = 0;
50
+ let timer = setInterval(() => {
51
+ const found = checkAscfHsp();
52
+ needWait++;
53
+
54
+ if (found || needWait > 5) {
55
+ clearInterval(timer);
56
+ if (found) {
57
+ resolve();
58
+ } else {
59
+ logger.warn(ERR_MSG);
60
+ reject(ERR_MSG);
61
+ }
62
+ return;
63
+ }
64
+ }, 1000);
65
+ }
66
+
67
+ export async function doInstallAscfHspPlugin(rootNode: HvigorNode): Promise<void> {
68
+ logger.debug('start exec install ascf hsp plugin');
69
+ const appContext = rootNode.getContext(OhosPluginId.OHOS_APP_PLUGIN) as OhosAppContext;
70
+ const currentNode = hvigor.getNodeByName('entry')!;
71
+ const hapContext = currentNode.getContext(OhosPluginId.OHOS_HAP_PLUGIN) as OhosHapContext;
72
+ if (appContext?.getBuildMode() !== 'debug') {
73
+ return;
74
+ }
75
+
76
+ hapContext?.targets((target: Target) => {
77
+ const targetName = target.getTargetName();
78
+ logger.debug(`installAscfHspPlugin targetName:${targetName}`);
79
+ currentNode.registerTask({
80
+ name: 'installAscfHspTask',
81
+ run: () => new Promise<void>(doInstallAscfHsp).catch((err) => logger.error(err)),
82
+ dependencies: [`${targetName}@CompileArkTS`],
83
+ postDependencies: [`${targetName}@PackageHap`]
84
+ });
85
+ });
86
+ logger.debug('exec install ascf hsp plugin completed');
87
+ }
88
+
89
+ export default function installAscfHspPlugin(): HvigorPlugin {
90
+ return {
91
+ pluginId: 'installAscfHspPlugin',
92
+ apply: doInstallAscfHspPlugin,
93
+ };
94
+ }
@@ -0,0 +1,138 @@
1
+ import type { HvigorNode, HvigorPlugin, HvigorTaskContext } from '@ohos/hvigor';
2
+ import { HvigorLogger } from '@ohos/hvigor';
3
+ import { OhosHapContext, OhosPluginId, Target } from '@ohos/hvigor-ohos-plugin';
4
+ import path from 'path';
5
+ import fs from 'fs';
6
+
7
+ const logger = HvigorLogger.getLogger('modifyShareInfoPlugin');
8
+
9
+ const readJson = (filepath: string) => JSON.parse(fs.readFileSync(filepath, 'utf-8'));
10
+ const writeJson = (filepath: string, str: any) => fs.writeFileSync(filepath, JSON.stringify(str), 'utf-8');
11
+
12
+ function addShareInfo(sharedInfos: any, srcPath: string) {
13
+ logger.debug(`addShareInfo srcPath ${srcPath}`);
14
+ let modulePath = path.resolve(srcPath, 'src/main/module.json');
15
+ if (!fs.existsSync(modulePath)) {
16
+ modulePath += '5'; // trying module.json5
17
+ if (!fs.existsSync(modulePath)) {
18
+ return;
19
+ }
20
+ }
21
+ logger.debug(`addShareInfo modulePath ${modulePath}`);
22
+ const srcModuleJson = readJson(modulePath);
23
+ logger.debug(`addShareInfo srcModuleJson ${JSON.stringify(srcModuleJson, null, ' ')}`);
24
+ const srcBundleName = srcModuleJson?.app?.bundleName ?? '';
25
+ const srcVersionCode = srcModuleJson?.app?.versionCode ?? 0;
26
+ const srcModuleName = srcModuleJson?.module?.name ?? '';
27
+ const srcModuleType = srcModuleJson?.module?.type ?? '';
28
+ if (srcModuleType === 'shared' && srcBundleName && srcVersionCode !== 0 && srcModuleName) {
29
+ const shareInfo = {
30
+ 'bundleName': srcBundleName,
31
+ 'moduleName': srcModuleName,
32
+ 'versionCode': srcVersionCode
33
+ };
34
+ sharedInfos.push(shareInfo);
35
+ } else if (srcModuleType === 'shared' && !srcBundleName && srcVersionCode === 0 && srcModuleName) {
36
+ const shareInfo = {
37
+ 'moduleName': srcModuleName,
38
+ };
39
+ sharedInfos.push(shareInfo);
40
+ }
41
+ };
42
+
43
+ function getSharedInfos(modulePath: string): Array<object> {
44
+ const sharedInfos: any = [];
45
+ const moduleFilePath = path.resolve(modulePath, `oh_modules`);
46
+ const moduleFileNames = fs.readdirSync(moduleFilePath);
47
+ logger.debug(`moduleFileNames=${moduleFileNames}`);
48
+
49
+ moduleFileNames.filter(v => v && !v.startsWith('.')).forEach((moduleFileName) => {
50
+ logger.debug(`moduleFileName=${moduleFileName}`);
51
+
52
+ if (moduleFileName.startsWith('@')) {
53
+ const cloudModuleFilePath = path.resolve(modulePath, `oh_modules/${moduleFileName}`);
54
+ const cloudModuleFileNames = fs.readdirSync(cloudModuleFilePath);
55
+ logger.debug(`cloudModuleFileNames=${cloudModuleFileNames}`);
56
+
57
+ cloudModuleFileNames.forEach((cloudModuleFileName) => {
58
+ logger.debug(`cloudModuleFileName=${cloudModuleFileName}`);
59
+ addShareInfo(sharedInfos, path.resolve(cloudModuleFilePath, `${cloudModuleFileName}`));
60
+ });
61
+ } else {
62
+ addShareInfo(sharedInfos, path.resolve(moduleFilePath, `${moduleFileName}`));
63
+ }
64
+ });
65
+ return sharedInfos;
66
+ }
67
+
68
+ function updateSharedInfo(modulePath: string): void {
69
+ const buildFilePath = path.resolve(modulePath, `build`);
70
+ if (!fs.existsSync(buildFilePath)) {
71
+ logger.debug('buildFilePath:' + buildFilePath);
72
+ return;
73
+ }
74
+
75
+ const dependencies = getSharedInfos(modulePath);
76
+ if (!dependencies?.length) {
77
+ logger.debug('dependencies is empty');
78
+ return;
79
+ }
80
+
81
+ const buildFileNames = fs.readdirSync(buildFilePath);
82
+ logger.debug('buildFileNames:' + buildFileNames);
83
+ buildFileNames.filter(v => v).forEach((productName) => {
84
+ logger.debug('productName: ' + productName);
85
+ const filePath = path.resolve(buildFilePath, `${productName}/intermediates/res/${productName}/module.json`);
86
+ logger.debug('module.json filePath: ' + filePath);
87
+ if (fs.existsSync(filePath)) {
88
+ const moduleJson = readJson(filePath);
89
+ moduleJson.module.dependencies = dependencies;
90
+ writeJson(filePath, moduleJson);
91
+ logger.debug(`final moduleJson ${JSON.stringify(moduleJson, null, ' ')}`);
92
+ } else {
93
+ logger.debug('module.json filePath: ' + filePath + ' is not Exists');
94
+ }
95
+
96
+ const metadataPath = path.resolve(buildFilePath,
97
+ `${productName}/intermediates/hap_metadata/${productName}/output_metadata.json`);
98
+ logger.debug('output_metadata.json filePath: ' + metadataPath);
99
+ if (fs.existsSync(metadataPath)) {
100
+ const metadataJson = readJson(metadataPath);
101
+ metadataJson?.forEach((v: any) => {
102
+ const found = v.dependRemoteHsps?.findIndex((x: any) => x.hspName?.includes('ascf'));
103
+ if (v.dependRemoteHsps && found !== -1) {
104
+ v.dependRemoteHsps.splice(found, 1);
105
+ }
106
+ });
107
+ writeJson(metadataPath, metadataJson);
108
+ logger.debug(`final metadataJson ${JSON.stringify(metadataJson, null, ' ')}`);
109
+ }
110
+ });
111
+ }
112
+
113
+ export async function doModifyShareInfoPlugin(currentNode: HvigorNode): Promise<void> {
114
+ logger.debug('start exec modify share info plugin');
115
+ const hapContext = currentNode.getContext(OhosPluginId.OHOS_HAP_PLUGIN) as OhosHapContext;
116
+
117
+ hapContext?.targets((target: Target) => {
118
+ const targetName = target.getTargetName();
119
+ logger.debug(`targetName:${targetName}`);
120
+ currentNode.registerTask({
121
+ name: 'modifyShareInfoTask',
122
+ run: (taskContext: HvigorTaskContext) => {
123
+ logger.debug('moduleName=' + taskContext.moduleName + ' modulePath=' + taskContext.modulePath);
124
+ updateSharedInfo(taskContext.modulePath);
125
+ },
126
+ dependencies: [`${targetName}@CompileArkTS`],
127
+ postDependencies: [`${targetName}@PackageHap`]
128
+ });
129
+ });
130
+ logger.debug('exec modify share info plugin completed');
131
+ }
132
+
133
+ export default function modifyShareInfoPlugin(): HvigorPlugin {
134
+ return {
135
+ pluginId: 'modifyShareInfoPlugin',
136
+ apply: doModifyShareInfoPlugin,
137
+ };
138
+ }
@@ -0,0 +1,27 @@
1
+ import { HvigorLogger, HvigorNode, HvigorPlugin } from '@ohos/hvigor';
2
+ import { OhosAppContext, OhosPluginId } from '@ohos/hvigor-ohos-plugin';
3
+
4
+ const logger = HvigorLogger.getLogger('signByBuildModePlugin');
5
+
6
+ function signByBuildMode(debugSignName: string, releaseSignName: string): HvigorPlugin {
7
+ return {
8
+ pluginId: 'signByBuildMode',
9
+ apply(node: HvigorNode) {
10
+ try {
11
+ logger.debug('start exec sign by build mode');
12
+ const appContext = node.getContext(OhosPluginId.OHOS_APP_PLUGIN) as OhosAppContext;
13
+ const signingConfig = appContext.getBuildMode() === 'debug' ? debugSignName : releaseSignName;
14
+ logger.debug('signByBuildMode change signingConfig=' + signingConfig);
15
+
16
+ const bpOpt = appContext.getBuildProfileOpt();
17
+ bpOpt.app.products![0].signingConfig = signingConfig;
18
+ appContext.setBuildProfileOpt(bpOpt);
19
+ logger.debug('sign by build mode completed');
20
+ } catch (err: any) {
21
+ logger.errorExit(new Error(err));
22
+ }
23
+ },
24
+ };
25
+ }
26
+
27
+ export default signByBuildMode;