@oniroproject/oniro-app 0.6.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 (37) hide show
  1. package/dist/oniro-app.js +434 -0
  2. package/dist/oniro-app.js.map +1 -0
  3. package/package.json +33 -0
  4. package/templates/EmptyAbility/AppScope/app.json5 +10 -0
  5. package/templates/EmptyAbility/AppScope/resources/base/element/string.json +8 -0
  6. package/templates/EmptyAbility/AppScope/resources/base/media/background.png +0 -0
  7. package/templates/EmptyAbility/AppScope/resources/base/media/foreground.png +0 -0
  8. package/templates/EmptyAbility/AppScope/resources/base/media/layered_image.json +7 -0
  9. package/templates/EmptyAbility/build-profile.json5 +35 -0
  10. package/templates/EmptyAbility/entry/build-profile.json5 +33 -0
  11. package/templates/EmptyAbility/entry/hvigorfile.ts +6 -0
  12. package/templates/EmptyAbility/entry/obfuscation-rules.txt +23 -0
  13. package/templates/EmptyAbility/entry/oh-package.json5 +10 -0
  14. package/templates/EmptyAbility/entry/src/main/ets/entryability/EntryAbility.ets +48 -0
  15. package/templates/EmptyAbility/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets +16 -0
  16. package/templates/EmptyAbility/entry/src/main/ets/pages/Index.ets +23 -0
  17. package/templates/EmptyAbility/entry/src/main/module.json5 +50 -0
  18. package/templates/EmptyAbility/entry/src/main/resources/base/element/color.json +8 -0
  19. package/templates/EmptyAbility/entry/src/main/resources/base/element/float.json +8 -0
  20. package/templates/EmptyAbility/entry/src/main/resources/base/element/string.json +16 -0
  21. package/templates/EmptyAbility/entry/src/main/resources/base/media/background.png +0 -0
  22. package/templates/EmptyAbility/entry/src/main/resources/base/media/foreground.png +0 -0
  23. package/templates/EmptyAbility/entry/src/main/resources/base/media/layered_image.json +7 -0
  24. package/templates/EmptyAbility/entry/src/main/resources/base/media/startIcon.png +0 -0
  25. package/templates/EmptyAbility/entry/src/main/resources/base/profile/backup_config.json +3 -0
  26. package/templates/EmptyAbility/entry/src/main/resources/base/profile/main_pages.json +5 -0
  27. package/templates/EmptyAbility/entry/src/main/resources/dark/element/color.json +8 -0
  28. package/templates/EmptyAbility/entry/src/mock/mock-config.json5 +2 -0
  29. package/templates/EmptyAbility/entry/src/ohosTest/ets/test/Ability.test.ets +35 -0
  30. package/templates/EmptyAbility/entry/src/ohosTest/ets/test/List.test.ets +5 -0
  31. package/templates/EmptyAbility/entry/src/ohosTest/module.json5 +11 -0
  32. package/templates/EmptyAbility/entry/src/test/List.test.ets +5 -0
  33. package/templates/EmptyAbility/entry/src/test/LocalUnit.test.ets +33 -0
  34. package/templates/EmptyAbility/hvigor/hvigor-config.json5 +23 -0
  35. package/templates/EmptyAbility/hvigorfile.ts +6 -0
  36. package/templates/EmptyAbility/oh-package.json5 +10 -0
  37. package/templates/EmptyAbility/template.json +6 -0
@@ -0,0 +1,434 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/bin/oniro-app.ts
4
+ import { Command as Command2 } from "commander";
5
+ import { OniroError } from "@oniroproject/core";
6
+
7
+ // src/commands/sdk.ts
8
+ import * as fs from "fs";
9
+ import * as path from "path";
10
+ import {
11
+ ALL_SDKS,
12
+ downloadAndInstallSdk,
13
+ getOsFolder,
14
+ getSdkRootDir,
15
+ getSupportedSdksForUi,
16
+ removeSdk
17
+ } from "@oniroproject/core";
18
+
19
+ // src/adapters/logger.ts
20
+ function createCliLogger() {
21
+ const debugEnabled = process.env.ONIRO_DEBUG === "1" || process.env.ONIRO_DEBUG === "true";
22
+ return {
23
+ debug(m) {
24
+ if (debugEnabled) process.stderr.write(`[debug] ${m}
25
+ `);
26
+ },
27
+ info(m) {
28
+ process.stderr.write(`${m}
29
+ `);
30
+ },
31
+ warn(m) {
32
+ process.stderr.write(`[warn] ${m}
33
+ `);
34
+ },
35
+ error(m) {
36
+ process.stderr.write(`[error] ${m}
37
+ `);
38
+ }
39
+ };
40
+ }
41
+
42
+ // src/adapters/progress.ts
43
+ function createCliProgress() {
44
+ let total = 0;
45
+ let lastEmitted = -1;
46
+ let lastMessage = "";
47
+ return {
48
+ report({ message, increment }) {
49
+ if (typeof increment === "number") total = Math.min(100, total + increment);
50
+ const pct = total > 0 ? Math.round(total) : null;
51
+ const msg = message ?? lastMessage;
52
+ if (pct === lastEmitted && msg === lastMessage) return;
53
+ const prefix = pct === null ? "[progress]" : `[progress ${pct}%]`;
54
+ process.stderr.write(`${prefix} ${msg}
55
+ `);
56
+ lastEmitted = pct ?? lastEmitted;
57
+ if (message) lastMessage = message;
58
+ }
59
+ };
60
+ }
61
+
62
+ // src/adapters/config.ts
63
+ import * as os from "os";
64
+ var ENV_VAR_BY_KEY = {
65
+ sdkRootDir: "ONIRO_SDK_ROOT_DIR",
66
+ cmdToolsPath: "ONIRO_CMD_TOOLS_PATH",
67
+ emulatorDir: "ONIRO_EMULATOR_DIR",
68
+ hapPath: "ONIRO_HAP_PATH",
69
+ cmdToolsUrlLinux: "ONIRO_CMD_TOOLS_URL_LINUX",
70
+ cmdToolsUrlWindows: "ONIRO_CMD_TOOLS_URL_WINDOWS",
71
+ cmdToolsUrlMac: "ONIRO_CMD_TOOLS_URL_MAC",
72
+ emulatorUrl: "ONIRO_EMULATOR_URL"
73
+ };
74
+ function createEnvConfig(env = process.env) {
75
+ return {
76
+ get(key, fallback) {
77
+ const envName = ENV_VAR_BY_KEY[key];
78
+ const raw = env[envName];
79
+ if (raw === void 0 || raw === "") return fallback;
80
+ const expanded = raw.includes("${userHome}") ? raw.replace(/\$\{userHome\}/g, os.homedir()) : raw;
81
+ return expanded;
82
+ }
83
+ };
84
+ }
85
+
86
+ // src/lib/runtime.ts
87
+ var cached = null;
88
+ function getRuntime() {
89
+ if (!cached) {
90
+ cached = {
91
+ logger: createCliLogger(),
92
+ config: createEnvConfig(),
93
+ progress: createCliProgress()
94
+ };
95
+ }
96
+ return cached;
97
+ }
98
+
99
+ // src/commands/sdk.ts
100
+ function registerSdkCommand(program) {
101
+ const sdk = program.command("sdk").description("Manage OpenHarmony SDK installs.");
102
+ sdk.command("install <version>").description("Download and install an OpenHarmony SDK. Skips if already installed.").option("--force", "Reinstall even if the SDK is already present.").action(async (version, opts) => {
103
+ const { config, logger, progress } = getRuntime();
104
+ const release = ALL_SDKS.find((s) => s.version === version);
105
+ if (!release) {
106
+ throw new Error(
107
+ `Unknown SDK version "${version}". Known: ${ALL_SDKS.map((s) => s.version).join(", ")}`
108
+ );
109
+ }
110
+ const sdkInstallDir = path.join(getSdkRootDir(config), getOsFolder(), release.api);
111
+ if (fs.existsSync(sdkInstallDir) && !opts.force) {
112
+ logger.info(
113
+ `SDK ${release.version} (api ${release.api}) already installed at ${sdkInstallDir}; pass --force to reinstall.`
114
+ );
115
+ return;
116
+ }
117
+ logger.info(`Installing OpenHarmony SDK ${release.version} (api ${release.api})...`);
118
+ await downloadAndInstallSdk({ config, version: release.version, api: release.api, progress, logger });
119
+ logger.info("SDK installed.");
120
+ });
121
+ sdk.command("list").description("List known SDK versions and whether they are installed on this machine.").option("--json", "Emit machine-readable JSON instead of a table.").action((opts) => {
122
+ const { config } = getRuntime();
123
+ const sdks = getSupportedSdksForUi(config);
124
+ if (opts.json) {
125
+ process.stdout.write(`${JSON.stringify(sdks, null, 2)}
126
+ `);
127
+ return;
128
+ }
129
+ const rows = sdks.map((s) => `${s.installed ? "*" : " "} ${s.version.padEnd(8)} api ${s.api}`);
130
+ process.stdout.write(`${rows.join("\n")}
131
+ `);
132
+ });
133
+ sdk.command("remove <api>").description("Remove an installed SDK by API level (e.g. 18, 20).").action((api) => {
134
+ const { config, logger } = getRuntime();
135
+ const removed = removeSdk(config, api);
136
+ if (!removed) {
137
+ logger.warn(`No SDK with api ${api} found under the configured SDK root.`);
138
+ process.exit(1);
139
+ }
140
+ logger.info(`Removed SDK api ${api}.`);
141
+ });
142
+ }
143
+
144
+ // src/commands/cmdtools.ts
145
+ import { getCmdToolsStatus, installCmdTools, isCmdToolsInstalled, removeCmdTools } from "@oniroproject/core";
146
+ function registerCmdToolsCommand(program) {
147
+ const cmdtools = program.command("cmdtools").description("Manage OpenHarmony command-line tools.");
148
+ cmdtools.command("install").description("Install the OpenHarmony command-line tools (hvigorw, ohpm, hdc). Skips if already installed.").option("--from-zip <path>", "Install from a local ZIP instead of downloading.").option("--force", "Reinstall even if the tools are already present.").action(async (opts) => {
149
+ const { config, logger, progress } = getRuntime();
150
+ if (isCmdToolsInstalled(config) && !opts.force) {
151
+ logger.info("Command-line tools already installed; pass --force to reinstall.");
152
+ return;
153
+ }
154
+ logger.info("Installing OpenHarmony command-line tools...");
155
+ await installCmdTools({ config, progress, logger, localZipPath: opts.fromZip });
156
+ logger.info("Command-line tools installed.");
157
+ });
158
+ cmdtools.command("status").description("Report whether the command-line tools are installed and their version.").option("--json", "Emit machine-readable JSON.").action((opts) => {
159
+ const { config } = getRuntime();
160
+ const status = getCmdToolsStatus(config);
161
+ if (opts.json) {
162
+ process.stdout.write(`${JSON.stringify(status, null, 2)}
163
+ `);
164
+ return;
165
+ }
166
+ process.stdout.write(`${status.status}
167
+ `);
168
+ if (!status.installed) process.exit(1);
169
+ });
170
+ cmdtools.command("remove").description("Delete the configured command-line tools directory.").action(() => {
171
+ const { config, logger } = getRuntime();
172
+ removeCmdTools(config);
173
+ logger.info("Command-line tools removed.");
174
+ });
175
+ }
176
+
177
+ // src/commands/emulator.ts
178
+ import {
179
+ attemptHdcConnection,
180
+ installEmulator,
181
+ isEmulatorInstalled,
182
+ removeEmulator,
183
+ startEmulator,
184
+ stopEmulator
185
+ } from "@oniroproject/core";
186
+ function registerEmulatorCommand(program) {
187
+ const emu = program.command("emulator").description("Manage the Oniro emulator.");
188
+ emu.command("install").description("Download and install the Oniro emulator (QEMU-based). Skips if already installed.").option("--force", "Reinstall even if the emulator is already present.").action(async (opts) => {
189
+ const { config, logger, progress } = getRuntime();
190
+ if (isEmulatorInstalled(config) && !opts.force) {
191
+ logger.info("Emulator already installed; pass --force to reinstall.");
192
+ return;
193
+ }
194
+ logger.info("Installing Oniro emulator...");
195
+ await installEmulator({ config, progress, logger });
196
+ logger.info("Emulator installed.");
197
+ });
198
+ emu.command("start").description("Start the Oniro emulator via the bundled launcher (run.sh / run.bat). Detaches so the CLI can exit while the emulator keeps running.").option("--headless", "Launch headless (VNC + telnet serial, no local window). Required in CI.").option("--log <path>", "Redirect launcher stdout/stderr to this file. Defaults to discarding output.").option("--wait-for-hdc <seconds>", "Wait up to N seconds for hdc to connect. 0 = do not wait.", (v) => parseInt(v, 10), 0).option("--connect <host:port>", "Override the launcher's hdc port-forward bind address. Pass 0.0.0.0:55555 on hosts where QEMU refuses to bind 127.0.0.1 (some CI runners).").action(async (opts) => {
199
+ const { config, logger } = getRuntime();
200
+ await startEmulator({
201
+ config,
202
+ logger,
203
+ headless: opts.headless === true,
204
+ logFile: opts.log,
205
+ waitForHdcSeconds: opts.waitForHdc,
206
+ connect: opts.connect
207
+ });
208
+ logger.info("Emulator start command complete.");
209
+ });
210
+ emu.command("stop").description("Kill running emulator processes.").action(async () => {
211
+ const { logger } = getRuntime();
212
+ await stopEmulator(logger);
213
+ logger.info("Emulator stopped.");
214
+ });
215
+ emu.command("connect").description("Attempt to connect hdc to the emulator.").option("--address <addr>", "hdc address to connect to", "127.0.0.1:55555").action(async (opts) => {
216
+ const { config, logger } = getRuntime();
217
+ const ok = await attemptHdcConnection(config, opts.address, logger);
218
+ if (!ok) {
219
+ logger.error(`Could not connect hdc to ${opts.address}.`);
220
+ process.exit(1);
221
+ }
222
+ logger.info(`hdc connected to ${opts.address}.`);
223
+ });
224
+ emu.command("remove").description("Delete the configured emulator directory.").action(() => {
225
+ const { config, logger } = getRuntime();
226
+ removeEmulator(config);
227
+ logger.info("Emulator removed.");
228
+ });
229
+ }
230
+
231
+ // src/commands/build.ts
232
+ import * as path2 from "path";
233
+ import { runHvigorw } from "@oniroproject/core";
234
+ function registerBuildCommand(program) {
235
+ program.command("build [project-dir]").description("Build an OpenHarmony app via hvigorw. Defaults to the current directory.").option("--product <product>", "hvigor product name", "default").option("--module <module>", "restrict the build to a specific module").option("--mode <mode>", "hvigor build mode (e.g. release, debug)").option("--task <task>", "hvigor task to run", "assembleHap").action(async (projectDir, opts) => {
236
+ const { config, logger } = getRuntime();
237
+ const dir = path2.resolve(projectDir ?? process.cwd());
238
+ logger.info(`Building project at ${dir}...`);
239
+ await runHvigorw({
240
+ config,
241
+ projectDir: dir,
242
+ product: opts.product,
243
+ module: opts.module,
244
+ buildMode: opts.mode,
245
+ task: opts.task,
246
+ logger,
247
+ // Forward output as it arrives. We don't double-print since the logger
248
+ // already echoes spawn output; this hook is for streaming to other UIs.
249
+ onOutput: () => {
250
+ }
251
+ });
252
+ logger.info("Build complete.");
253
+ });
254
+ }
255
+
256
+ // src/commands/sign.ts
257
+ import { Option } from "commander";
258
+ import * as path3 from "path";
259
+ import {
260
+ APL_VALUES,
261
+ APP_FEATURE_VALUES,
262
+ generateSigningConfigs,
263
+ getOhosBaseSdkHome
264
+ } from "@oniroproject/core";
265
+ function registerSignCommand(program) {
266
+ program.command("sign [project-dir]").description(
267
+ [
268
+ "Generate signing keys, certificates, and signingConfigs for an OpenHarmony project.",
269
+ "Requires java on PATH. The generated profile uses the SDK's built-in development",
270
+ "cert (issuer=pki_internal) and its bundled validity window \u2014 dev/local builds only.",
271
+ "Overwrites the `signingConfigs` block in build-profile.json5 (other keys preserved)."
272
+ ].join(" ")
273
+ ).addOption(
274
+ new Option(
275
+ "--apl <level>",
276
+ "Ability Privilege Level written into the profile. Apps that request permissions above `normal` (e.g. ohos.permission.GET_WIFI_INFO_INTERNAL) need system_basic or system_core."
277
+ ).choices([...APL_VALUES]).default("normal")
278
+ ).addOption(
279
+ new Option(
280
+ "--app-feature <feature>",
281
+ "App feature written into the profile. Defaults: hos_normal_app for apl=normal; hos_system_app for apl=system_basic/system_core."
282
+ ).choices([...APP_FEATURE_VALUES])
283
+ ).action((projectDir, opts) => {
284
+ const { config, logger } = getRuntime();
285
+ const dir = path3.resolve(projectDir ?? process.cwd());
286
+ const sdkHome = getOhosBaseSdkHome(config);
287
+ logger.info(`Generating signing configs in ${dir} using SDK at ${sdkHome}...`);
288
+ generateSigningConfigs({
289
+ projectDir: dir,
290
+ sdkHome,
291
+ apl: opts.apl,
292
+ appFeature: opts.appFeature,
293
+ logger
294
+ });
295
+ logger.info("Signing configs generated.");
296
+ });
297
+ }
298
+
299
+ // src/commands/app.ts
300
+ import * as path4 from "path";
301
+ import { installApp, launchApp } from "@oniroproject/core";
302
+ function registerAppCommand(program) {
303
+ const app = program.command("app").description("Install and launch built apps on a connected device/emulator.");
304
+ app.command("install [project-dir]").description("Install the signed .hap on the connected device/emulator via hdc.").option("--hap <path>", "Override the .hap path (relative to project-dir or absolute).").action(async (projectDir, opts) => {
305
+ const { config, logger } = getRuntime();
306
+ const dir = path4.resolve(projectDir ?? process.cwd());
307
+ logger.info(`Installing app from ${dir}...`);
308
+ await installApp({ config, projectDir: dir, hapPath: opts.hap, logger });
309
+ logger.info("App installed.");
310
+ });
311
+ app.command("launch [project-dir]").description("Launch the app on the connected device/emulator via hdc.").option("--module <module>", "Module folder name", "entry").action(async (projectDir, opts) => {
312
+ const { config, logger } = getRuntime();
313
+ const dir = path4.resolve(projectDir ?? process.cwd());
314
+ logger.info(`Launching app from ${dir}...`);
315
+ await launchApp({ config, projectDir: dir, moduleName: opts.module, logger });
316
+ logger.info("App launched.");
317
+ });
318
+ }
319
+
320
+ // src/commands/create.ts
321
+ import * as path6 from "path";
322
+ import {
323
+ ALL_SDKS as ALL_SDKS2,
324
+ createScaffold,
325
+ isValidBundleName,
326
+ isValidProjectName
327
+ } from "@oniroproject/core";
328
+
329
+ // src/lib/templateRoot.ts
330
+ import * as fs2 from "fs";
331
+ import * as path5 from "path";
332
+ import { fileURLToPath } from "url";
333
+ function getBundledTemplateRoot() {
334
+ const here = path5.dirname(fileURLToPath(import.meta.url));
335
+ const candidates = [
336
+ path5.resolve(here, "../templates"),
337
+ // dist/oniro-app.js → ../templates
338
+ path5.resolve(here, "../../templates")
339
+ // src/bin/oniro-app.ts → ../../templates
340
+ ];
341
+ for (const c of candidates) {
342
+ if (fs2.existsSync(c)) return c;
343
+ }
344
+ return candidates[0];
345
+ }
346
+
347
+ // src/commands/create.ts
348
+ function registerCreateCommand(program) {
349
+ program.command("create").description("Scaffold a new Oniro/OpenHarmony app from a template. All flags are required (non-interactive).").requiredOption("--name <name>", "Project folder name (letters, digits, ._- only)").requiredOption("--bundle <bundleName>", "Bundle name in reverse-DNS form, e.g. com.example.myapp").requiredOption("--location <dir>", "Parent directory where the new project folder will be created").requiredOption("--sdk <api>", "Target SDK API level (e.g. 18, 20)").option("--template <id>", "Template id", "EmptyAbility").option("--module <name>", "Module folder name (defaults to the template default, usually `entry`)").option("--overwrite", "Replace the destination if it already exists").action(async (opts) => {
350
+ const { config, logger } = getRuntime();
351
+ if (!isValidProjectName(opts.name)) {
352
+ throw new Error(`Invalid --name '${opts.name}'. Use letters/numbers/._- and no slashes.`);
353
+ }
354
+ if (!isValidBundleName(opts.bundle)) {
355
+ throw new Error(`Invalid --bundle '${opts.bundle}'. Example: com.example.myapp`);
356
+ }
357
+ const sdkApi = Number(opts.sdk);
358
+ if (!Number.isFinite(sdkApi)) {
359
+ throw new Error(`--sdk must be a numeric api level. Known: ${ALL_SDKS2.map((s) => s.api).join(", ")}`);
360
+ }
361
+ const templateRoot = getBundledTemplateRoot();
362
+ const result = await createScaffold({
363
+ config,
364
+ templateId: opts.template,
365
+ projectName: opts.name,
366
+ bundleName: opts.bundle,
367
+ location: path6.resolve(opts.location),
368
+ sdkApi,
369
+ moduleName: opts.module,
370
+ templateRoot,
371
+ overwrite: opts.overwrite,
372
+ logger
373
+ });
374
+ logger.info(`Project created at ${result.projectDir}`);
375
+ process.stdout.write(`${result.projectDir}
376
+ `);
377
+ });
378
+ }
379
+
380
+ // src/commands/templates.ts
381
+ import { listTemplates } from "@oniroproject/core";
382
+ function registerTemplatesCommand(program) {
383
+ const templates = program.command("templates").description("Inspect the templates bundled with this CLI.");
384
+ templates.command("list").description("List available project templates.").option("--json", "Emit machine-readable JSON.").action((opts) => {
385
+ const root = getBundledTemplateRoot();
386
+ const list = listTemplates(root);
387
+ if (opts.json) {
388
+ process.stdout.write(`${JSON.stringify(list, null, 2)}
389
+ `);
390
+ return;
391
+ }
392
+ if (list.length === 0) {
393
+ process.stdout.write("No templates available.\n");
394
+ return;
395
+ }
396
+ const rows = list.map((t) => `${t.id.padEnd(20)} ${t.label.padEnd(24)} ${t.description}`);
397
+ process.stdout.write(`${rows.join("\n")}
398
+ `);
399
+ });
400
+ }
401
+
402
+ // src/bin/oniro-app.ts
403
+ var CLI_VERSION = "0.6.0";
404
+ function buildProgram() {
405
+ const program = new Command2().name("oniro-app").description(
406
+ "Cross-platform CLI for Oniro/OpenHarmony app development.\n\nDesigned for non-interactive use (CI, scripts, agents): every command\ntakes explicit flags, results go to stdout, progress/logs go to stderr,\nand a non-zero exit code indicates failure."
407
+ ).version(CLI_VERSION).showHelpAfterError();
408
+ registerSdkCommand(program);
409
+ registerCmdToolsCommand(program);
410
+ registerEmulatorCommand(program);
411
+ registerBuildCommand(program);
412
+ registerSignCommand(program);
413
+ registerAppCommand(program);
414
+ registerCreateCommand(program);
415
+ registerTemplatesCommand(program);
416
+ return program;
417
+ }
418
+ async function main() {
419
+ const program = buildProgram();
420
+ try {
421
+ await program.parseAsync(process.argv);
422
+ } catch (err) {
423
+ const message = err instanceof OniroError ? err.message : err instanceof Error ? err.message : String(err);
424
+ process.stderr.write(`[error] ${message}
425
+ `);
426
+ if (process.env.ONIRO_DEBUG === "1" && err instanceof Error && err.stack) {
427
+ process.stderr.write(`${err.stack}
428
+ `);
429
+ }
430
+ process.exit(1);
431
+ }
432
+ }
433
+ void main();
434
+ //# sourceMappingURL=oniro-app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/bin/oniro-app.ts","../src/commands/sdk.ts","../src/adapters/logger.ts","../src/adapters/progress.ts","../src/adapters/config.ts","../src/lib/runtime.ts","../src/commands/cmdtools.ts","../src/commands/emulator.ts","../src/commands/build.ts","../src/commands/sign.ts","../src/commands/app.ts","../src/commands/create.ts","../src/lib/templateRoot.ts","../src/commands/templates.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { OniroError } from '@oniroproject/core';\nimport { registerSdkCommand } from '../commands/sdk.js';\nimport { registerCmdToolsCommand } from '../commands/cmdtools.js';\nimport { registerEmulatorCommand } from '../commands/emulator.js';\nimport { registerBuildCommand } from '../commands/build.js';\nimport { registerSignCommand } from '../commands/sign.js';\nimport { registerAppCommand } from '../commands/app.js';\nimport { registerCreateCommand } from '../commands/create.js';\nimport { registerTemplatesCommand } from '../commands/templates.js';\n\ndeclare const __CLI_VERSION__: string;\nconst CLI_VERSION = __CLI_VERSION__;\n\nfunction buildProgram(): Command {\n const program = new Command()\n .name('oniro-app')\n .description(\n 'Cross-platform CLI for Oniro/OpenHarmony app development.\\n\\n' +\n 'Designed for non-interactive use (CI, scripts, agents): every command\\n' +\n 'takes explicit flags, results go to stdout, progress/logs go to stderr,\\n' +\n 'and a non-zero exit code indicates failure.',\n )\n .version(CLI_VERSION)\n .showHelpAfterError();\n\n registerSdkCommand(program);\n registerCmdToolsCommand(program);\n registerEmulatorCommand(program);\n registerBuildCommand(program);\n registerSignCommand(program);\n registerAppCommand(program);\n registerCreateCommand(program);\n registerTemplatesCommand(program);\n\n return program;\n}\n\nasync function main(): Promise<void> {\n const program = buildProgram();\n try {\n await program.parseAsync(process.argv);\n } catch (err) {\n const message = err instanceof OniroError ? err.message : err instanceof Error ? err.message : String(err);\n process.stderr.write(`[error] ${message}\\n`);\n if (process.env.ONIRO_DEBUG === '1' && err instanceof Error && err.stack) {\n process.stderr.write(`${err.stack}\\n`);\n }\n process.exit(1);\n }\n}\n\nvoid main();\n","import { Command } from 'commander';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport {\n ALL_SDKS,\n downloadAndInstallSdk,\n getOsFolder,\n getSdkRootDir,\n getSupportedSdksForUi,\n removeSdk,\n} from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\nexport function registerSdkCommand(program: Command): void {\n const sdk = program.command('sdk').description('Manage OpenHarmony SDK installs.');\n\n sdk\n .command('install <version>')\n .description('Download and install an OpenHarmony SDK. Skips if already installed.')\n .option('--force', 'Reinstall even if the SDK is already present.')\n .action(async (version: string, opts: { force?: boolean }) => {\n const { config, logger, progress } = getRuntime();\n const release = ALL_SDKS.find((s) => s.version === version);\n if (!release) {\n throw new Error(\n `Unknown SDK version \"${version}\". Known: ${ALL_SDKS.map((s) => s.version).join(', ')}`,\n );\n }\n const sdkInstallDir = path.join(getSdkRootDir(config), getOsFolder(), release.api);\n if (fs.existsSync(sdkInstallDir) && !opts.force) {\n logger.info(\n `SDK ${release.version} (api ${release.api}) already installed at ${sdkInstallDir}; pass --force to reinstall.`,\n );\n return;\n }\n logger.info(`Installing OpenHarmony SDK ${release.version} (api ${release.api})...`);\n await downloadAndInstallSdk({ config, version: release.version, api: release.api, progress, logger });\n logger.info('SDK installed.');\n });\n\n sdk\n .command('list')\n .description('List known SDK versions and whether they are installed on this machine.')\n .option('--json', 'Emit machine-readable JSON instead of a table.')\n .action((opts: { json?: boolean }) => {\n const { config } = getRuntime();\n const sdks = getSupportedSdksForUi(config);\n if (opts.json) {\n process.stdout.write(`${JSON.stringify(sdks, null, 2)}\\n`);\n return;\n }\n const rows = sdks.map((s) => `${s.installed ? '*' : ' '} ${s.version.padEnd(8)} api ${s.api}`);\n process.stdout.write(`${rows.join('\\n')}\\n`);\n });\n\n sdk\n .command('remove <api>')\n .description('Remove an installed SDK by API level (e.g. 18, 20).')\n .action((api: string) => {\n const { config, logger } = getRuntime();\n const removed = removeSdk(config, api);\n if (!removed) {\n logger.warn(`No SDK with api ${api} found under the configured SDK root.`);\n process.exit(1);\n }\n logger.info(`Removed SDK api ${api}.`);\n });\n}\n","import type { Logger } from '@oniroproject/core';\n\n/**\n * Stderr-only logger. All diagnostic output goes to stderr so command stdout\n * stays clean for machine consumers (json results, paths, etc.).\n *\n * Debug lines are suppressed unless `ONIRO_DEBUG=1`.\n */\nexport function createCliLogger(): Logger {\n const debugEnabled = process.env.ONIRO_DEBUG === '1' || process.env.ONIRO_DEBUG === 'true';\n return {\n debug(m) {\n if (debugEnabled) process.stderr.write(`[debug] ${m}\\n`);\n },\n info(m) {\n process.stderr.write(`${m}\\n`);\n },\n warn(m) {\n process.stderr.write(`[warn] ${m}\\n`);\n },\n error(m) {\n process.stderr.write(`[error] ${m}\\n`);\n },\n };\n}\n","import type { ProgressReporter } from '@oniroproject/core';\n\n/**\n * Line-per-update progress reporter, designed for machine consumers and log scrapers.\n * Format: `[progress NN%] message` (or `[progress] message` if no percent is known).\n * Updates that don't change the percent and don't carry a message are suppressed\n * to keep output volume reasonable on chatty downloads.\n */\nexport function createCliProgress(): ProgressReporter {\n let total = 0;\n let lastEmitted = -1;\n let lastMessage = '';\n return {\n report({ message, increment }) {\n if (typeof increment === 'number') total = Math.min(100, total + increment);\n const pct = total > 0 ? Math.round(total) : null;\n const msg = message ?? lastMessage;\n // Drop redundant updates: same message, same percent.\n if (pct === lastEmitted && msg === lastMessage) return;\n const prefix = pct === null ? '[progress]' : `[progress ${pct}%]`;\n process.stderr.write(`${prefix} ${msg}\\n`);\n lastEmitted = pct ?? lastEmitted;\n if (message) lastMessage = message;\n },\n };\n}\n","import * as os from 'node:os';\nimport type { ConfigKey, ConfigProvider } from '@oniroproject/core';\n\n/**\n * Maps a core ConfigKey to its environment variable name.\n * Convention: ONIRO_<UPPER_SNAKE>.\n */\nconst ENV_VAR_BY_KEY: Record<ConfigKey, string> = {\n sdkRootDir: 'ONIRO_SDK_ROOT_DIR',\n cmdToolsPath: 'ONIRO_CMD_TOOLS_PATH',\n emulatorDir: 'ONIRO_EMULATOR_DIR',\n hapPath: 'ONIRO_HAP_PATH',\n cmdToolsUrlLinux: 'ONIRO_CMD_TOOLS_URL_LINUX',\n cmdToolsUrlWindows: 'ONIRO_CMD_TOOLS_URL_WINDOWS',\n cmdToolsUrlMac: 'ONIRO_CMD_TOOLS_URL_MAC',\n emulatorUrl: 'ONIRO_EMULATOR_URL',\n};\n\n/**\n * Reads configuration from environment variables (ONIRO_*). Returns the fallback\n * when the variable is unset or empty. Expands `${userHome}` to the user's home\n * directory for parity with the VS Code extension's `${userHome}` expansion.\n */\nexport function createEnvConfig(env: NodeJS.ProcessEnv = process.env): ConfigProvider {\n return {\n get<T extends string | number | boolean>(key: ConfigKey, fallback: T): T {\n const envName = ENV_VAR_BY_KEY[key];\n const raw = env[envName];\n if (raw === undefined || raw === '') return fallback;\n const expanded = raw.includes('${userHome}')\n ? raw.replace(/\\$\\{userHome\\}/g, os.homedir())\n : raw;\n return expanded as unknown as T;\n },\n };\n}\n","import type { ConfigProvider, Logger, ProgressReporter } from '@oniroproject/core';\nimport { createCliLogger } from '../adapters/logger.js';\nimport { createCliProgress } from '../adapters/progress.js';\nimport { createEnvConfig } from '../adapters/config.js';\n\nexport interface CliRuntime {\n logger: Logger;\n config: ConfigProvider;\n progress: ProgressReporter;\n}\n\nlet cached: CliRuntime | null = null;\n\n/**\n * Build (and cache) the per-process runtime used by every command. Tests can\n * override the cached runtime via `setRuntime` to inject mocks.\n */\nexport function getRuntime(): CliRuntime {\n if (!cached) {\n cached = {\n logger: createCliLogger(),\n config: createEnvConfig(),\n progress: createCliProgress(),\n };\n }\n return cached;\n}\n\nexport function setRuntime(runtime: CliRuntime | null): void {\n cached = runtime;\n}\n","import { Command } from 'commander';\nimport { getCmdToolsStatus, installCmdTools, isCmdToolsInstalled, removeCmdTools } from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\nexport function registerCmdToolsCommand(program: Command): void {\n const cmdtools = program.command('cmdtools').description('Manage OpenHarmony command-line tools.');\n\n cmdtools\n .command('install')\n .description('Install the OpenHarmony command-line tools (hvigorw, ohpm, hdc). Skips if already installed.')\n .option('--from-zip <path>', 'Install from a local ZIP instead of downloading.')\n .option('--force', 'Reinstall even if the tools are already present.')\n .action(async (opts: { fromZip?: string; force?: boolean }) => {\n const { config, logger, progress } = getRuntime();\n if (isCmdToolsInstalled(config) && !opts.force) {\n logger.info('Command-line tools already installed; pass --force to reinstall.');\n return;\n }\n logger.info('Installing OpenHarmony command-line tools...');\n await installCmdTools({ config, progress, logger, localZipPath: opts.fromZip });\n logger.info('Command-line tools installed.');\n });\n\n cmdtools\n .command('status')\n .description('Report whether the command-line tools are installed and their version.')\n .option('--json', 'Emit machine-readable JSON.')\n .action((opts: { json?: boolean }) => {\n const { config } = getRuntime();\n const status = getCmdToolsStatus(config);\n if (opts.json) {\n process.stdout.write(`${JSON.stringify(status, null, 2)}\\n`);\n return;\n }\n process.stdout.write(`${status.status}\\n`);\n if (!status.installed) process.exit(1);\n });\n\n cmdtools\n .command('remove')\n .description('Delete the configured command-line tools directory.')\n .action(() => {\n const { config, logger } = getRuntime();\n removeCmdTools(config);\n logger.info('Command-line tools removed.');\n });\n}\n","import { Command } from 'commander';\nimport {\n attemptHdcConnection,\n installEmulator,\n isEmulatorInstalled,\n removeEmulator,\n startEmulator,\n stopEmulator,\n} from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\nexport function registerEmulatorCommand(program: Command): void {\n const emu = program.command('emulator').description('Manage the Oniro emulator.');\n\n emu\n .command('install')\n .description('Download and install the Oniro emulator (QEMU-based). Skips if already installed.')\n .option('--force', 'Reinstall even if the emulator is already present.')\n .action(async (opts: { force?: boolean }) => {\n const { config, logger, progress } = getRuntime();\n if (isEmulatorInstalled(config) && !opts.force) {\n logger.info('Emulator already installed; pass --force to reinstall.');\n return;\n }\n logger.info('Installing Oniro emulator...');\n await installEmulator({ config, progress, logger });\n logger.info('Emulator installed.');\n });\n\n emu\n .command('start')\n .description('Start the Oniro emulator via the bundled launcher (run.sh / run.bat). Detaches so the CLI can exit while the emulator keeps running.')\n .option('--headless', 'Launch headless (VNC + telnet serial, no local window). Required in CI.')\n .option('--log <path>', 'Redirect launcher stdout/stderr to this file. Defaults to discarding output.')\n .option('--wait-for-hdc <seconds>', 'Wait up to N seconds for hdc to connect. 0 = do not wait.', (v) => parseInt(v, 10), 0)\n .option('--connect <host:port>', 'Override the launcher\\'s hdc port-forward bind address. Pass 0.0.0.0:55555 on hosts where QEMU refuses to bind 127.0.0.1 (some CI runners).')\n .action(async (opts: { headless?: boolean; log?: string; waitForHdc: number; connect?: string }) => {\n const { config, logger } = getRuntime();\n await startEmulator({\n config,\n logger,\n headless: opts.headless === true,\n logFile: opts.log,\n waitForHdcSeconds: opts.waitForHdc,\n connect: opts.connect,\n });\n logger.info('Emulator start command complete.');\n });\n\n emu\n .command('stop')\n .description('Kill running emulator processes.')\n .action(async () => {\n const { logger } = getRuntime();\n await stopEmulator(logger);\n logger.info('Emulator stopped.');\n });\n\n emu\n .command('connect')\n .description('Attempt to connect hdc to the emulator.')\n .option('--address <addr>', 'hdc address to connect to', '127.0.0.1:55555')\n .action(async (opts: { address: string }) => {\n const { config, logger } = getRuntime();\n const ok = await attemptHdcConnection(config, opts.address, logger);\n if (!ok) {\n logger.error(`Could not connect hdc to ${opts.address}.`);\n process.exit(1);\n }\n logger.info(`hdc connected to ${opts.address}.`);\n });\n\n emu\n .command('remove')\n .description('Delete the configured emulator directory.')\n .action(() => {\n const { config, logger } = getRuntime();\n removeEmulator(config);\n logger.info('Emulator removed.');\n });\n}\n","import { Command } from 'commander';\nimport * as path from 'node:path';\nimport { runHvigorw } from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\nexport function registerBuildCommand(program: Command): void {\n program\n .command('build [project-dir]')\n .description('Build an OpenHarmony app via hvigorw. Defaults to the current directory.')\n .option('--product <product>', 'hvigor product name', 'default')\n .option('--module <module>', 'restrict the build to a specific module')\n .option('--mode <mode>', 'hvigor build mode (e.g. release, debug)')\n .option('--task <task>', 'hvigor task to run', 'assembleHap')\n .action(async (projectDir: string | undefined, opts: { product: string; module?: string; mode?: string; task: string }) => {\n const { config, logger } = getRuntime();\n const dir = path.resolve(projectDir ?? process.cwd());\n logger.info(`Building project at ${dir}...`);\n await runHvigorw({\n config,\n projectDir: dir,\n product: opts.product,\n module: opts.module,\n buildMode: opts.mode,\n task: opts.task,\n logger,\n // Forward output as it arrives. We don't double-print since the logger\n // already echoes spawn output; this hook is for streaming to other UIs.\n onOutput: () => {},\n });\n logger.info('Build complete.');\n });\n}\n","import { Command, Option } from 'commander';\nimport * as path from 'node:path';\nimport {\n APL_VALUES,\n APP_FEATURE_VALUES,\n generateSigningConfigs,\n getOhosBaseSdkHome,\n type Apl,\n type AppFeature,\n} from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\nexport function registerSignCommand(program: Command): void {\n program\n .command('sign [project-dir]')\n .description(\n [\n 'Generate signing keys, certificates, and signingConfigs for an OpenHarmony project.',\n 'Requires java on PATH. The generated profile uses the SDK\\'s built-in development',\n 'cert (issuer=pki_internal) and its bundled validity window — dev/local builds only.',\n 'Overwrites the `signingConfigs` block in build-profile.json5 (other keys preserved).',\n ].join(' '),\n )\n .addOption(\n new Option(\n '--apl <level>',\n 'Ability Privilege Level written into the profile. Apps that request permissions above `normal` (e.g. ohos.permission.GET_WIFI_INFO_INTERNAL) need system_basic or system_core.',\n )\n .choices([...APL_VALUES])\n .default('normal'),\n )\n .addOption(\n new Option(\n '--app-feature <feature>',\n 'App feature written into the profile. Defaults: hos_normal_app for apl=normal; hos_system_app for apl=system_basic/system_core.',\n ).choices([...APP_FEATURE_VALUES]),\n )\n .action((projectDir: string | undefined, opts: { apl: Apl; appFeature?: AppFeature }) => {\n const { config, logger } = getRuntime();\n const dir = path.resolve(projectDir ?? process.cwd());\n const sdkHome = getOhosBaseSdkHome(config);\n logger.info(`Generating signing configs in ${dir} using SDK at ${sdkHome}...`);\n generateSigningConfigs({\n projectDir: dir,\n sdkHome,\n apl: opts.apl,\n appFeature: opts.appFeature,\n logger,\n });\n logger.info('Signing configs generated.');\n });\n}\n","import { Command } from 'commander';\nimport * as path from 'node:path';\nimport { installApp, launchApp } from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\nexport function registerAppCommand(program: Command): void {\n const app = program.command('app').description('Install and launch built apps on a connected device/emulator.');\n\n app\n .command('install [project-dir]')\n .description('Install the signed .hap on the connected device/emulator via hdc.')\n .option('--hap <path>', 'Override the .hap path (relative to project-dir or absolute).')\n .action(async (projectDir: string | undefined, opts: { hap?: string }) => {\n const { config, logger } = getRuntime();\n const dir = path.resolve(projectDir ?? process.cwd());\n logger.info(`Installing app from ${dir}...`);\n await installApp({ config, projectDir: dir, hapPath: opts.hap, logger });\n logger.info('App installed.');\n });\n\n app\n .command('launch [project-dir]')\n .description('Launch the app on the connected device/emulator via hdc.')\n .option('--module <module>', 'Module folder name', 'entry')\n .action(async (projectDir: string | undefined, opts: { module: string }) => {\n const { config, logger } = getRuntime();\n const dir = path.resolve(projectDir ?? process.cwd());\n logger.info(`Launching app from ${dir}...`);\n await launchApp({ config, projectDir: dir, moduleName: opts.module, logger });\n logger.info('App launched.');\n });\n}\n","import { Command } from 'commander';\nimport * as path from 'node:path';\nimport {\n ALL_SDKS,\n createScaffold,\n isValidBundleName,\n isValidProjectName,\n} from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\nimport { getBundledTemplateRoot } from '../lib/templateRoot.js';\n\ninterface CreateOpts {\n name: string;\n bundle: string;\n location: string;\n sdk: string;\n template: string;\n module?: string;\n overwrite?: boolean;\n}\n\nexport function registerCreateCommand(program: Command): void {\n program\n .command('create')\n .description('Scaffold a new Oniro/OpenHarmony app from a template. All flags are required (non-interactive).')\n .requiredOption('--name <name>', 'Project folder name (letters, digits, ._- only)')\n .requiredOption('--bundle <bundleName>', 'Bundle name in reverse-DNS form, e.g. com.example.myapp')\n .requiredOption('--location <dir>', 'Parent directory where the new project folder will be created')\n .requiredOption('--sdk <api>', 'Target SDK API level (e.g. 18, 20)')\n .option('--template <id>', 'Template id', 'EmptyAbility')\n .option('--module <name>', 'Module folder name (defaults to the template default, usually `entry`)')\n .option('--overwrite', 'Replace the destination if it already exists')\n .action(async (opts: CreateOpts) => {\n const { config, logger } = getRuntime();\n\n if (!isValidProjectName(opts.name)) {\n throw new Error(`Invalid --name '${opts.name}'. Use letters/numbers/._- and no slashes.`);\n }\n if (!isValidBundleName(opts.bundle)) {\n throw new Error(`Invalid --bundle '${opts.bundle}'. Example: com.example.myapp`);\n }\n const sdkApi = Number(opts.sdk);\n if (!Number.isFinite(sdkApi)) {\n throw new Error(`--sdk must be a numeric api level. Known: ${ALL_SDKS.map((s) => s.api).join(', ')}`);\n }\n\n const templateRoot = getBundledTemplateRoot();\n const result = await createScaffold({\n config,\n templateId: opts.template,\n projectName: opts.name,\n bundleName: opts.bundle,\n location: path.resolve(opts.location),\n sdkApi,\n moduleName: opts.module,\n templateRoot,\n overwrite: opts.overwrite,\n logger,\n });\n\n logger.info(`Project created at ${result.projectDir}`);\n process.stdout.write(`${result.projectDir}\\n`);\n });\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/**\n * Resolve the bundled `templates/` directory shipped inside this CLI package.\n *\n * The CLI's `dist/oniro-app.js` lives at `<pkg>/dist/oniro-app.js` after build\n * and the templates ship at `<pkg>/templates/`. During development the entrypoint\n * lives at `<pkg>/src/bin/oniro-app.ts` so we also try `../../templates` from there.\n */\nexport function getBundledTemplateRoot(): string {\n const here = path.dirname(fileURLToPath(import.meta.url));\n const candidates = [\n path.resolve(here, '../templates'), // dist/oniro-app.js → ../templates\n path.resolve(here, '../../templates'), // src/bin/oniro-app.ts → ../../templates\n ];\n for (const c of candidates) {\n if (fs.existsSync(c)) return c;\n }\n // Return the most likely path even if it doesn't exist yet; createScaffold will\n // surface a clear error from there.\n return candidates[0]!;\n}\n","import { Command } from 'commander';\nimport { listTemplates } from '@oniroproject/core';\nimport { getBundledTemplateRoot } from '../lib/templateRoot.js';\n\nexport function registerTemplatesCommand(program: Command): void {\n const templates = program.command('templates').description('Inspect the templates bundled with this CLI.');\n\n templates\n .command('list')\n .description('List available project templates.')\n .option('--json', 'Emit machine-readable JSON.')\n .action((opts: { json?: boolean }) => {\n const root = getBundledTemplateRoot();\n const list = listTemplates(root);\n if (opts.json) {\n process.stdout.write(`${JSON.stringify(list, null, 2)}\\n`);\n return;\n }\n if (list.length === 0) {\n process.stdout.write('No templates available.\\n');\n return;\n }\n const rows = list.map((t) => `${t.id.padEnd(20)} ${t.label.padEnd(24)} ${t.description}`);\n process.stdout.write(`${rows.join('\\n')}\\n`);\n });\n}\n"],"mappings":"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","names":["Command","path","path","path","path","ALL_SDKS","fs","path","ALL_SDKS","Command"]}
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@oniroproject/oniro-app",
3
+ "version": "0.6.0",
4
+ "description": "Cross-platform CLI for Oniro/OpenHarmony application development.",
5
+ "license": "Apache-2.0",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/eclipse-oniro4openharmony/oniro-app-builder.git",
9
+ "directory": "packages/cli"
10
+ },
11
+ "type": "module",
12
+ "bin": {
13
+ "oniro-app": "./dist/oniro-app.js"
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "templates"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsup",
21
+ "pretest": "npm run build",
22
+ "test": "vitest run --passWithNoTests",
23
+ "typecheck": "tsc --noEmit",
24
+ "clean": "rm -rf dist"
25
+ },
26
+ "dependencies": {
27
+ "@oniroproject/core": "0.6.0",
28
+ "commander": "^12.1.0"
29
+ },
30
+ "engines": {
31
+ "node": ">=20"
32
+ }
33
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "app": {
3
+ "bundleName": "com.example.myapplication",
4
+ "vendor": "example",
5
+ "versionCode": 1000000,
6
+ "versionName": "1.0.0",
7
+ "icon": "$media:layered_image",
8
+ "label": "$string:app_name"
9
+ }
10
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "string": [
3
+ {
4
+ "name": "app_name",
5
+ "value": "MyApplication"
6
+ }
7
+ ]
8
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "layered-image":
3
+ {
4
+ "background" : "$media:background",
5
+ "foreground" : "$media:foreground"
6
+ }
7
+ }
@@ -0,0 +1,35 @@
1
+ {
2
+ "app": {
3
+ "products": [
4
+ {
5
+ "name": "default",
6
+ "signingConfig": "default",
7
+ "compileSdkVersion": 20,
8
+ "compatibleSdkVersion": 20,
9
+ "runtimeOS": "OpenHarmony"
10
+ }
11
+ ],
12
+ "buildModeSet": [
13
+ {
14
+ "name": "debug"
15
+ },
16
+ {
17
+ "name": "release"
18
+ }
19
+ ]
20
+ },
21
+ "modules": [
22
+ {
23
+ "name": "entry",
24
+ "srcPath": "./entry",
25
+ "targets": [
26
+ {
27
+ "name": "default",
28
+ "applyToProducts": [
29
+ "default"
30
+ ]
31
+ }
32
+ ]
33
+ }
34
+ ]
35
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "apiType": "stageMode",
3
+ "buildOption": {
4
+ "resOptions": {
5
+ "copyCodeResource": {
6
+ "enable": false
7
+ }
8
+ }
9
+ },
10
+ "buildOptionSet": [
11
+ {
12
+ "name": "release",
13
+ "arkOptions": {
14
+ "obfuscation": {
15
+ "ruleOptions": {
16
+ "enable": false,
17
+ "files": [
18
+ "./obfuscation-rules.txt"
19
+ ]
20
+ }
21
+ }
22
+ }
23
+ },
24
+ ],
25
+ "targets": [
26
+ {
27
+ "name": "default"
28
+ },
29
+ {
30
+ "name": "ohosTest",
31
+ }
32
+ ]
33
+ }
@@ -0,0 +1,6 @@
1
+ import { hapTasks } from '@ohos/hvigor-ohos-plugin';
2
+
3
+ export default {
4
+ system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
5
+ plugins: [] /* Custom plugin to extend the functionality of Hvigor. */
6
+ }
@@ -0,0 +1,23 @@
1
+ # Define project specific obfuscation rules here.
2
+ # You can include the obfuscation configuration files in the current module's build-profile.json5.
3
+ #
4
+ # For more details, see
5
+ # https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5
6
+
7
+ # Obfuscation options:
8
+ # -disable-obfuscation: disable all obfuscations
9
+ # -enable-property-obfuscation: obfuscate the property names
10
+ # -enable-toplevel-obfuscation: obfuscate the names in the global scope
11
+ # -compact: remove unnecessary blank spaces and all line feeds
12
+ # -remove-log: remove all console.* statements
13
+ # -print-namecache: print the name cache that contains the mapping from the old names to new names
14
+ # -apply-namecache: reuse the given cache file
15
+
16
+ # Keep options:
17
+ # -keep-property-name: specifies property names that you want to keep
18
+ # -keep-global-name: specifies names that you want to keep in the global scope
19
+
20
+ -enable-property-obfuscation
21
+ -enable-toplevel-obfuscation
22
+ -enable-filename-obfuscation
23
+ -enable-export-obfuscation
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "entry",
3
+ "version": "1.0.0",
4
+ "description": "Please describe the basic information.",
5
+ "main": "",
6
+ "author": "",
7
+ "license": "",
8
+ "dependencies": {}
9
+ }
10
+
@@ -0,0 +1,48 @@
1
+ import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit';
2
+ import { hilog } from '@kit.PerformanceAnalysisKit';
3
+ import { window } from '@kit.ArkUI';
4
+
5
+ const DOMAIN = 0x0000;
6
+
7
+ export default class EntryAbility extends UIAbility {
8
+ onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
9
+ try {
10
+ this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
11
+ } catch (err) {
12
+ hilog.error(DOMAIN, 'testTag', 'Failed to set colorMode. Cause: %{public}s', JSON.stringify(err));
13
+ }
14
+ hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
15
+ }
16
+
17
+ onDestroy(): void {
18
+ hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy');
19
+ }
20
+
21
+ onWindowStageCreate(windowStage: window.WindowStage): void {
22
+ // Main window is created, set main page for this ability
23
+ hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
24
+
25
+ windowStage.loadContent('pages/Index', (err) => {
26
+ if (err.code) {
27
+ hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
28
+ return;
29
+ }
30
+ hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
31
+ });
32
+ }
33
+
34
+ onWindowStageDestroy(): void {
35
+ // Main window is destroyed, release UI related resources
36
+ hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
37
+ }
38
+
39
+ onForeground(): void {
40
+ // Ability has brought to foreground
41
+ hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground');
42
+ }
43
+
44
+ onBackground(): void {
45
+ // Ability has back to background
46
+ hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground');
47
+ }
48
+ }
@@ -0,0 +1,16 @@
1
+ import { hilog } from '@kit.PerformanceAnalysisKit';
2
+ import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit';
3
+
4
+ const DOMAIN = 0x0000;
5
+
6
+ export default class EntryBackupAbility extends BackupExtensionAbility {
7
+ async onBackup() {
8
+ hilog.info(DOMAIN, 'testTag', 'onBackup ok');
9
+ await Promise.resolve();
10
+ }
11
+
12
+ async onRestore(bundleVersion: BundleVersion) {
13
+ hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion));
14
+ await Promise.resolve();
15
+ }
16
+ }
@@ -0,0 +1,23 @@
1
+ @Entry
2
+ @Component
3
+ struct Index {
4
+ @State message: string = 'Hello World';
5
+
6
+ build() {
7
+ RelativeContainer() {
8
+ Text(this.message)
9
+ .id('HelloWorld')
10
+ .fontSize($r('app.float.page_text_font_size'))
11
+ .fontWeight(FontWeight.Bold)
12
+ .alignRules({
13
+ center: { anchor: '__container__', align: VerticalAlign.Center },
14
+ middle: { anchor: '__container__', align: HorizontalAlign.Center }
15
+ })
16
+ .onClick(() => {
17
+ this.message = 'Welcome';
18
+ })
19
+ }
20
+ .height('100%')
21
+ .width('100%')
22
+ }
23
+ }
@@ -0,0 +1,50 @@
1
+ {
2
+ "module": {
3
+ "name": "entry",
4
+ "type": "entry",
5
+ "description": "$string:module_desc",
6
+ "mainElement": "EntryAbility",
7
+ "deviceTypes": [
8
+ "default"
9
+ ],
10
+ "deliveryWithInstall": true,
11
+ "installationFree": false,
12
+ "pages": "$profile:main_pages",
13
+ "abilities": [
14
+ {
15
+ "name": "EntryAbility",
16
+ "srcEntry": "./ets/entryability/EntryAbility.ets",
17
+ "description": "$string:EntryAbility_desc",
18
+ "icon": "$media:layered_image",
19
+ "label": "$string:EntryAbility_label",
20
+ "startWindowIcon": "$media:startIcon",
21
+ "startWindowBackground": "$color:start_window_background",
22
+ "exported": true,
23
+ "skills": [
24
+ {
25
+ "entities": [
26
+ "entity.system.home"
27
+ ],
28
+ "actions": [
29
+ "ohos.want.action.home"
30
+ ]
31
+ }
32
+ ]
33
+ }
34
+ ],
35
+ "extensionAbilities": [
36
+ {
37
+ "name": "EntryBackupAbility",
38
+ "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets",
39
+ "type": "backup",
40
+ "exported": false,
41
+ "metadata": [
42
+ {
43
+ "name": "ohos.extension.backup",
44
+ "resource": "$profile:backup_config"
45
+ }
46
+ ],
47
+ }
48
+ ]
49
+ }
50
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "color": [
3
+ {
4
+ "name": "start_window_background",
5
+ "value": "#FFFFFF"
6
+ }
7
+ ]
8
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "float": [
3
+ {
4
+ "name": "page_text_font_size",
5
+ "value": "50fp"
6
+ }
7
+ ]
8
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "string": [
3
+ {
4
+ "name": "module_desc",
5
+ "value": "module description"
6
+ },
7
+ {
8
+ "name": "EntryAbility_desc",
9
+ "value": "description"
10
+ },
11
+ {
12
+ "name": "EntryAbility_label",
13
+ "value": "label"
14
+ }
15
+ ]
16
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "layered-image":
3
+ {
4
+ "background" : "$media:background",
5
+ "foreground" : "$media:foreground"
6
+ }
7
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "allowToBackupRestore": true
3
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "color": [
3
+ {
4
+ "name": "start_window_background",
5
+ "value": "#000000"
6
+ }
7
+ ]
8
+ }
@@ -0,0 +1,35 @@
1
+ import { hilog } from '@kit.PerformanceAnalysisKit';
2
+ import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
3
+
4
+ export default function abilityTest() {
5
+ describe('ActsAbilityTest', () => {
6
+ // Defines a test suite. Two parameters are supported: test suite name and test suite function.
7
+ beforeAll(() => {
8
+ // Presets an action, which is performed only once before all test cases of the test suite start.
9
+ // This API supports only one parameter: preset action function.
10
+ })
11
+ beforeEach(() => {
12
+ // Presets an action, which is performed before each unit test case starts.
13
+ // The number of execution times is the same as the number of test cases defined by **it**.
14
+ // This API supports only one parameter: preset action function.
15
+ })
16
+ afterEach(() => {
17
+ // Presets a clear action, which is performed after each unit test case ends.
18
+ // The number of execution times is the same as the number of test cases defined by **it**.
19
+ // This API supports only one parameter: clear action function.
20
+ })
21
+ afterAll(() => {
22
+ // Presets a clear action, which is performed after all test cases of the test suite end.
23
+ // This API supports only one parameter: clear action function.
24
+ })
25
+ it('assertContain', 0, () => {
26
+ // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
27
+ hilog.info(0x0000, 'testTag', '%{public}s', 'it begin');
28
+ let a = 'abc';
29
+ let b = 'b';
30
+ // Defines a variety of assertion methods, which are used to declare expected boolean conditions.
31
+ expect(a).assertContain(b);
32
+ expect(a).assertEqual(a);
33
+ })
34
+ })
35
+ }
@@ -0,0 +1,5 @@
1
+ import abilityTest from './Ability.test';
2
+
3
+ export default function testsuite() {
4
+ abilityTest();
5
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "module": {
3
+ "name": "entry_test",
4
+ "type": "feature",
5
+ "deviceTypes": [
6
+ "phone"
7
+ ],
8
+ "deliveryWithInstall": true,
9
+ "installationFree": false
10
+ }
11
+ }
@@ -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,23 @@
1
+ {
2
+ "modelVersion": "5.1.0",
3
+ "dependencies": {
4
+ },
5
+ "execution": {
6
+ // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | "ultrafine" | false ]. Default: "normal" */
7
+ // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */
8
+ // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */
9
+ // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */
10
+ // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */
11
+ // "optimizationStrategy": "memory" /* Define the optimization strategy. Value: [ "memory" | "performance" ]. Default: "memory" */
12
+ },
13
+ "logging": {
14
+ // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */
15
+ },
16
+ "debugging": {
17
+ // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */
18
+ },
19
+ "nodeOptions": {
20
+ // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/
21
+ // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/
22
+ }
23
+ }
@@ -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,10 @@
1
+ {
2
+ "modelVersion": "5.1.0",
3
+ "description": "Please describe the basic information.",
4
+ "dependencies": {
5
+ },
6
+ "devDependencies": {
7
+ "@ohos/hypium": "1.0.24",
8
+ "@ohos/hamock": "1.0.0"
9
+ }
10
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "id": "EmptyAbility",
3
+ "label": "Empty Ability",
4
+ "description": "Minimal OpenHarmony (ArkTS/ArkUI) application with a single entry ability (HelloWorld-style starter).",
5
+ "defaultModuleName": "entry"
6
+ }