@oniroproject/capacitor-openharmony 0.1.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.
Files changed (48) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +4 -0
  3. package/assets/native-template/AppScope/app.json5 +10 -0
  4. package/assets/native-template/AppScope/resources/base/element/string.json +8 -0
  5. package/assets/native-template/AppScope/resources/base/media/background.png +0 -0
  6. package/assets/native-template/AppScope/resources/base/media/foreground.png +0 -0
  7. package/assets/native-template/AppScope/resources/base/media/layered_image.json +7 -0
  8. package/assets/native-template/build-profile.json5 +36 -0
  9. package/assets/native-template/entry/build-profile.json5 +33 -0
  10. package/assets/native-template/entry/hvigorfile.ts +6 -0
  11. package/assets/native-template/entry/obfuscation-rules.txt +23 -0
  12. package/assets/native-template/entry/oh-package.json5 +9 -0
  13. package/assets/native-template/entry/src/main/ets/capacitor/BridgeInterfaces.ets +49 -0
  14. package/assets/native-template/entry/src/main/ets/capacitor/CapacitorBridge.ets +355 -0
  15. package/assets/native-template/entry/src/main/ets/capacitor/CapacitorPlugin.ets +42 -0
  16. package/assets/native-template/entry/src/main/ets/capacitor/PluginCall.ets +60 -0
  17. package/assets/native-template/entry/src/main/ets/capacitor/PluginRegistry.ets +35 -0
  18. package/assets/native-template/entry/src/main/ets/entryability/EntryAbility.ets +66 -0
  19. package/assets/native-template/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets +16 -0
  20. package/assets/native-template/entry/src/main/ets/pages/Index.ets +86 -0
  21. package/assets/native-template/entry/src/main/module.json5 +58 -0
  22. package/assets/native-template/entry/src/main/resources/base/element/color.json +8 -0
  23. package/assets/native-template/entry/src/main/resources/base/element/float.json +8 -0
  24. package/assets/native-template/entry/src/main/resources/base/element/string.json +16 -0
  25. package/assets/native-template/entry/src/main/resources/base/media/background.png +0 -0
  26. package/assets/native-template/entry/src/main/resources/base/media/foreground.png +0 -0
  27. package/assets/native-template/entry/src/main/resources/base/media/layered_image.json +7 -0
  28. package/assets/native-template/entry/src/main/resources/base/media/startIcon.png +0 -0
  29. package/assets/native-template/entry/src/main/resources/base/profile/backup_config.json +3 -0
  30. package/assets/native-template/entry/src/main/resources/base/profile/main_pages.json +5 -0
  31. package/assets/native-template/entry/src/main/resources/dark/element/color.json +8 -0
  32. package/assets/native-template/entry/src/main/resources/rawfile/www/assets/index-DyaJ3fSD.css +1 -0
  33. package/assets/native-template/entry/src/main/resources/rawfile/www/assets/index-f0ambvls.js +40 -0
  34. package/assets/native-template/entry/src/main/resources/rawfile/www/index.html +13 -0
  35. package/assets/native-template/entry/src/mock/mock-config.json5 +1 -0
  36. package/assets/native-template/entry/src/ohosTest/ets/test/Ability.test.ets +35 -0
  37. package/assets/native-template/entry/src/ohosTest/ets/test/List.test.ets +5 -0
  38. package/assets/native-template/entry/src/ohosTest/module.json5 +11 -0
  39. package/assets/native-template/entry/src/test/List.test.ets +5 -0
  40. package/assets/native-template/entry/src/test/LocalUnit.test.ets +33 -0
  41. package/assets/native-template/hvigor/hvigor-config.json5 +8 -0
  42. package/assets/native-template/hvigorfile.ts +6 -0
  43. package/assets/native-template/oh-package.json5 +9 -0
  44. package/dist/add.js +27 -0
  45. package/dist/common.js +58 -0
  46. package/dist/index.js +20 -0
  47. package/dist/sync.js +191 -0
  48. package/package.json +51 -0
@@ -0,0 +1,5 @@
1
+ import localUnitTest from './LocalUnit.test';
2
+
3
+ export default function testsuite() {
4
+ localUnitTest();
5
+ }
@@ -0,0 +1,33 @@
1
+ import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
2
+
3
+ export default function localUnitTest() {
4
+ describe('localUnitTest', () => {
5
+ // Defines a test suite. Two parameters are supported: test suite name and test suite function.
6
+ beforeAll(() => {
7
+ // Presets an action, which is performed only once before all test cases of the test suite start.
8
+ // This API supports only one parameter: preset action function.
9
+ });
10
+ beforeEach(() => {
11
+ // Presets an action, which is performed before each unit test case starts.
12
+ // The number of execution times is the same as the number of test cases defined by **it**.
13
+ // This API supports only one parameter: preset action function.
14
+ });
15
+ afterEach(() => {
16
+ // Presets a clear action, which is performed after each unit test case ends.
17
+ // The number of execution times is the same as the number of test cases defined by **it**.
18
+ // This API supports only one parameter: clear action function.
19
+ });
20
+ afterAll(() => {
21
+ // Presets a clear action, which is performed after all test cases of the test suite end.
22
+ // This API supports only one parameter: clear action function.
23
+ });
24
+ it('assertContain', 0, () => {
25
+ // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
26
+ let a = 'abc';
27
+ let b = 'b';
28
+ // Defines a variety of assertion methods, which are used to declare expected boolean conditions.
29
+ expect(a).assertContain(b);
30
+ expect(a).assertEqual(a);
31
+ });
32
+ });
33
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "modelVersion": "5.1.0",
3
+ "dependencies": {},
4
+ "execution": {},
5
+ "logging": {},
6
+ "debugging": {},
7
+ "nodeOptions": {}
8
+ }
@@ -0,0 +1,6 @@
1
+ import { appTasks } from '@ohos/hvigor-ohos-plugin';
2
+
3
+ export default {
4
+ system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
5
+ plugins: [] /* Custom plugin to extend the functionality of Hvigor. */
6
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "modelVersion": "5.1.0",
3
+ "description": "Please describe the basic information.",
4
+ "dependencies": {},
5
+ "devDependencies": {
6
+ "@ohos/hypium": "1.0.24",
7
+ "@ohos/hamock": "1.0.0"
8
+ }
9
+ }
package/dist/add.js ADDED
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.addOpenHarmony = addOpenHarmony;
4
+ const fs_extra_1 = require("fs-extra");
5
+ const path_1 = require("path");
6
+ const common_1 = require("./common");
7
+ async function addOpenHarmony(config) {
8
+ const projectRoot = process.env.CAPACITOR_ROOT_DIR || process.cwd();
9
+ const platformDir = (0, path_1.join)(projectRoot, 'openharmony');
10
+ if ((0, fs_extra_1.existsSync)(platformDir)) {
11
+ console.log('OpenHarmony platform already exists.');
12
+ return;
13
+ }
14
+ console.log('Adding OpenHarmony platform...');
15
+ const templateDir = (0, path_1.join)(__dirname, '../assets/native-template');
16
+ try {
17
+ await (0, fs_extra_1.copy)(templateDir, platformDir);
18
+ console.log('Template copied.');
19
+ if ((config === null || config === void 0 ? void 0 : config.appId) && (config === null || config === void 0 ? void 0 : config.appName)) {
20
+ await (0, common_1.updateAppJson5)(projectRoot, config.appId, config.appName);
21
+ console.log('App configuration updated.');
22
+ }
23
+ }
24
+ catch (e) {
25
+ console.error('Failed to add OpenHarmony platform:', e);
26
+ }
27
+ }
package/dist/common.js ADDED
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCapacitorConfig = getCapacitorConfig;
4
+ exports.updateAppJson5 = updateAppJson5;
5
+ const path_1 = require("path");
6
+ async function getCapacitorConfig() {
7
+ try {
8
+ const configPath = (0, path_1.join)(process.cwd(), 'capacitor.config.ts');
9
+ // Using dynamic import for ts config or require for json
10
+ // For simplicity in this environment, we might need a more robust config loader
11
+ // But let's assume standard capacitor CLI usage where config is available
12
+ // Actually, @capacitor/cli might not expose a simple config loader for plugins.
13
+ // We will implement a basic reader for now.
14
+ return require((0, path_1.join)(process.cwd(), 'capacitor.config.json'));
15
+ }
16
+ catch (e) {
17
+ try {
18
+ // Fallback for ts config - in a real plugin we'd use capacitor's config loader
19
+ // For this POC, we'll try to read capacitor.config.json if ts fails
20
+ // or just mock it if we are running in the demo app which has ts.
21
+ // NOTE: compiled CLI won't run TS directly.
22
+ // practical approach: expect capacitor.config.json or parse basic TS
23
+ console.warn('Could not read capacitor.config.json, manual config might be needed');
24
+ return null;
25
+ }
26
+ catch (e2) {
27
+ return null;
28
+ }
29
+ }
30
+ }
31
+ async function updateAppJson5(projectRoot, appId, appName) {
32
+ const appJsonPath = (0, path_1.join)(projectRoot, 'openharmony', 'AppScope', 'app.json5');
33
+ try {
34
+ // json5 is not strict json, so standard require/JSON.parse might fail if it has comments.
35
+ // However, native-template app.json5 is usually simple.
36
+ // We'll use fs-extra to read as text and replace regex for safety if we don't want a json5 parser dep.
37
+ const fs = require('fs-extra');
38
+ let content = await fs.readFile(appJsonPath, 'utf8');
39
+ // Simple regex replacement to preserve comments/formatting if possible
40
+ content = content.replace(/"bundleName":\s*".*?"/, `"bundleName": "${appId}"`);
41
+ content = content.replace(/"label":\s*".*?"/, `"label": "$string:app_name"`); // Usually points to resource
42
+ // Also need to update string resource for app_name
43
+ const stringResPath = (0, path_1.join)(projectRoot, 'openharmony', 'AppScope', 'resources', 'base', 'element', 'string.json');
44
+ const strings = await fs.readJson(stringResPath);
45
+ const appNameEntry = strings.string.find((e) => e.name === 'app_name');
46
+ if (appNameEntry) {
47
+ appNameEntry.value = appName;
48
+ }
49
+ else {
50
+ strings.string.push({ name: 'app_name', value: appName });
51
+ }
52
+ await fs.writeJson(stringResPath, strings, { spaces: 2 });
53
+ await fs.writeFile(appJsonPath, content);
54
+ }
55
+ catch (e) {
56
+ console.error('Error updating AppScope/app.json5', e);
57
+ }
58
+ }
package/dist/index.js ADDED
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.add = add;
4
+ exports.copy = copy;
5
+ exports.update = update;
6
+ exports.open = open;
7
+ const add_1 = require("./add");
8
+ const sync_1 = require("./sync");
9
+ async function add(config) {
10
+ await (0, add_1.addOpenHarmony)(config);
11
+ }
12
+ async function copy(config) {
13
+ await (0, sync_1.sync)(config);
14
+ }
15
+ async function update(config) {
16
+ console.log('Update command not implemented yet (plugins)');
17
+ }
18
+ async function open(config) {
19
+ console.log('Open command not implemented yet (DevEco Studio)');
20
+ }
package/dist/sync.js ADDED
@@ -0,0 +1,191 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.sync = sync;
37
+ const fs_extra_1 = require("fs-extra");
38
+ const path_1 = require("path");
39
+ async function sync(config) {
40
+ const projectRoot = process.env.CAPACITOR_ROOT_DIR || process.cwd();
41
+ const webDir = config.webDir || 'dist';
42
+ const src = (0, path_1.join)(projectRoot, webDir);
43
+ const dest = (0, path_1.join)(projectRoot, 'openharmony/entry/src/main/resources/rawfile/www');
44
+ console.log(`Syncing ${src} to ${dest}...`);
45
+ if (!(0, fs_extra_1.existsSync)(src)) {
46
+ console.error(`Web directory ${src} does not exist. Did you build your web app?`);
47
+ return;
48
+ }
49
+ try {
50
+ // Clean destination? Maybe not needed as copy overwrites
51
+ await (0, fs_extra_1.mkdirp)(dest);
52
+ await (0, fs_extra_1.copy)(src, dest);
53
+ console.log('Web assets synced.');
54
+ await updateAppName(projectRoot, config.appName);
55
+ await generatePluginRegistry(projectRoot);
56
+ }
57
+ catch (e) {
58
+ console.error('Sync failed:', e);
59
+ }
60
+ }
61
+ async function updateAppName(projectRoot, appName) {
62
+ const stringJsonPath = (0, path_1.join)(projectRoot, 'openharmony/entry/src/main/resources/base/element/string.json');
63
+ if (!(0, fs_extra_1.existsSync)(stringJsonPath)) {
64
+ console.warn(`string.json not found at ${stringJsonPath}. Skipping App Name sync.`);
65
+ return;
66
+ }
67
+ try {
68
+ const fs = require('fs-extra');
69
+ const content = await fs.readJson(stringJsonPath);
70
+ let updated = false;
71
+ if (content.string) {
72
+ const labelItem = content.string.find((item) => item.name === 'EntryAbility_label');
73
+ if (labelItem) {
74
+ labelItem.value = appName;
75
+ updated = true;
76
+ }
77
+ }
78
+ if (updated) {
79
+ await fs.writeJson(stringJsonPath, content, { spaces: 2 });
80
+ console.log(`Updated App Name to "${appName}" in string.json`);
81
+ }
82
+ else {
83
+ console.warn('EntryAbility_label not found in string.json');
84
+ }
85
+ }
86
+ catch (e) {
87
+ console.error('Failed to update App Name:', e);
88
+ }
89
+ }
90
+ async function generatePluginRegistry(projectRoot) {
91
+ var _a;
92
+ console.log('Generating PluginRegistry...');
93
+ const packageJsonPath = (0, path_1.join)(projectRoot, 'package.json');
94
+ if (!(0, fs_extra_1.existsSync)(packageJsonPath)) {
95
+ console.error(`package.json not found at ${packageJsonPath}`);
96
+ return;
97
+ }
98
+ const packageJson = await Promise.resolve(`${packageJsonPath}`).then(s => __importStar(require(s)));
99
+ const dependencies = { ...packageJson.dependencies, ...packageJson.devDependencies };
100
+ const plugins = [];
101
+ for (const depName of Object.keys(dependencies)) {
102
+ try {
103
+ const depPackagePath = (0, path_1.join)(projectRoot, 'node_modules', depName, 'package.json');
104
+ if (!(0, fs_extra_1.existsSync)(depPackagePath)) {
105
+ continue;
106
+ }
107
+ const depPackage = await Promise.resolve(`${depPackagePath}`).then(s => __importStar(require(s)));
108
+ if ((_a = depPackage.capacitor) === null || _a === void 0 ? void 0 : _a.openharmony) {
109
+ plugins.push({
110
+ name: depName,
111
+ ...depPackage.capacitor.openharmony
112
+ });
113
+ }
114
+ }
115
+ catch (e) {
116
+ // ignore
117
+ }
118
+ }
119
+ // Check for local plugins or special overrides
120
+ const registryPath = (0, path_1.join)(projectRoot, 'openharmony/entry/src/main/ets/capacitor/PluginRegistry.ets');
121
+ const pluginsPath = (0, path_1.join)(projectRoot, 'openharmony/entry/src/main/ets/capacitor/plugins');
122
+ // Ensure plugins directory exists
123
+ await (0, fs_extra_1.mkdirp)(pluginsPath);
124
+ const imports = [];
125
+ const registrations = [];
126
+ for (const p of plugins) {
127
+ if (p.src) {
128
+ // Copy the plugin source file
129
+ const pluginSrcAbsPath = (0, path_1.join)(projectRoot, 'node_modules', p.name, p.src);
130
+ const pluginDestPath = (0, path_1.join)(pluginsPath, p.src);
131
+ if ((0, fs_extra_1.existsSync)(pluginSrcAbsPath)) {
132
+ await (0, fs_extra_1.copy)(pluginSrcAbsPath, pluginDestPath);
133
+ console.log(`Copied ${p.name} source to ${pluginDestPath}`);
134
+ // Assume className is derived from filename if not provided, or we can parse it.
135
+ // For now, let's assume the class name is standard PascalCase of the plugin name + "Plugin"
136
+ // Or we can try to find the class export in the file content?
137
+ // For MVP, let's stick to the convention: Filename "Device.ets" -> class "DevicePlugin"
138
+ // AND we also need to know the import path.
139
+ // Import path will be `./plugins/${filename_without_ext}`
140
+ const filename = p.src.replace('.ets', '');
141
+ const className = `${filename}Plugin`; // Convention
142
+ imports.push(`import { ${className} } from './plugins/${filename}';`);
143
+ registrations.push(`this.plugins.set('${filename}', new ${className}(this.bridge, this.context));`);
144
+ }
145
+ else {
146
+ console.warn(`Plugin source not found for ${p.name} at ${pluginSrcAbsPath}`);
147
+ }
148
+ }
149
+ }
150
+ const content = `import { CapacitorPlugin } from './CapacitorPlugin';
151
+ import { CapacitorBridge } from './CapacitorBridge';
152
+ import { PluginHeader, PluginMethod } from './BridgeInterfaces';
153
+ import { common } from '@kit.AbilityKit';
154
+ ${imports.join('\n')}
155
+
156
+ export class PluginRegistry {
157
+ private plugins: Map<string, CapacitorPlugin> = new Map();
158
+ private bridge: CapacitorBridge;
159
+ private context: common.UIAbilityContext;
160
+
161
+ constructor(bridge: CapacitorBridge, context: common.UIAbilityContext) {
162
+ this.bridge = bridge;
163
+ this.context = context;
164
+ this.registerPlugins();
165
+ }
166
+
167
+ private registerPlugins() {
168
+ ${registrations.join('\n ')}
169
+ }
170
+
171
+ getPlugin(pluginId: string): CapacitorPlugin | undefined {
172
+ return this.plugins.get(pluginId);
173
+ }
174
+
175
+ getPluginHeaders(): PluginHeader[] {
176
+ let headers: PluginHeader[] = [];
177
+ this.plugins.forEach((plugin) => {
178
+ headers.push({
179
+ name: plugin.getPluginId(),
180
+ methods: plugin.getMethods().map((m): PluginMethod => {
181
+ return { name: m, rtype: 'promise' };
182
+ })
183
+ });
184
+ });
185
+ return headers;
186
+ }
187
+ }
188
+ `;
189
+ await (0, fs_extra_1.writeFile)(registryPath, content);
190
+ console.log('PluginRegistry.ets generated.');
191
+ }
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@oniroproject/capacitor-openharmony",
3
+ "version": "0.1.0",
4
+ "description": "OpenHarmony platform adapter for Capacitor",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/eclipse-oniro4openharmony/capacitor-openharmony.git"
10
+ },
11
+ "publishConfig": {
12
+ "access": "public"
13
+ },
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "prepublishOnly": "npm run build",
17
+ "capacitor:add": "node -e \"require('./dist/index').add(JSON.parse(process.env.CAPACITOR_CONFIG))\"",
18
+ "capacitor:copy": "node -e \"require('./dist/index').copy(JSON.parse(process.env.CAPACITOR_CONFIG))\"",
19
+ "capacitor:update": "node -e \"require('./dist/index').update(JSON.parse(process.env.CAPACITOR_CONFIG))\"",
20
+ "capacitor:open": "node -e \"require('./dist/index').open(JSON.parse(process.env.CAPACITOR_CONFIG))\""
21
+ },
22
+ "keywords": [
23
+ "capacitor",
24
+ "openharmony",
25
+ "ionic"
26
+ ],
27
+ "author": "Ionic Team",
28
+ "license": "MIT",
29
+ "peerDependencies": {
30
+ "@capacitor/core": "^6.0.0"
31
+ },
32
+ "dependencies": {
33
+ "@capacitor/cli": "^6.0.0",
34
+ "commander": "^12.0.0",
35
+ "fs-extra": "^11.0.0",
36
+ "prompts": "^2.4.0"
37
+ },
38
+ "devDependencies": {
39
+ "@types/fs-extra": "^11.0.0",
40
+ "@types/node": "^20.0.0",
41
+ "@types/prompts": "^2.4.0",
42
+ "typescript": "^5.0.0"
43
+ },
44
+ "files": [
45
+ "dist/",
46
+ "assets/"
47
+ ],
48
+ "capacitor": {
49
+ "platform": "openharmony"
50
+ }
51
+ }