@oniroproject/core 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.
- package/dist/index.cjs +1856 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +593 -0
- package/dist/index.d.ts +593 -0
- package/dist/index.js +1748 -0
- package/dist/index.js.map +1 -0
- package/package.json +43 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ports/logger.ts","../src/ports/progress.ts","../src/ports/config.ts","../src/ports/prompter.ts","../src/ports/errors.ts","../src/ports/context.ts","../src/sdk/constants.ts","../src/sdk/platform.ts","../src/sdk/paths.ts","../src/sdk/detectProjectSdk.ts","../src/sdk/download.ts","../src/sdk/extract.ts","../src/sdk/list.ts","../src/sdk/remove.ts","../src/sdk/install.ts","../src/cmdTools/install.ts","../src/sign/encryptKey.ts","../src/sign/generateSigningConfigs.ts","../src/emulator/install.ts","../src/emulator/lifecycle.ts","../src/hdc/project.ts","../src/hdc/app.ts","../src/hdc/hilog.ts","../src/build/runHvigorw.ts","../src/project/validators.ts","../src/project/templates.ts","../src/project/createScaffold.ts","../src/project/jsonHelpers.ts","../src/index.ts"],"sourcesContent":["export interface Logger {\n debug(message: string): void;\n info(message: string): void;\n warn(message: string): void;\n error(message: string): void;\n}\n\nexport const noopLogger: Logger = {\n debug() {},\n info() {},\n warn() {},\n error() {},\n};\n\nexport const consoleLogger: Logger = {\n debug: (m) => console.debug(m),\n info: (m) => console.log(m),\n warn: (m) => console.warn(m),\n error: (m) => console.error(m),\n};\n","export interface ProgressUpdate {\n message?: string;\n increment?: number;\n}\n\nexport interface ProgressReporter {\n report(update: ProgressUpdate): void;\n}\n\nexport const noopProgress: ProgressReporter = {\n report() {},\n};\n","import * as os from 'node:os';\nimport * as path from 'node:path';\n\n/**\n * Keys read from the ConfigProvider by core. Frontends (CLI, VS Code extension)\n * implement the provider however they like (env vars, settings.json, etc.).\n */\nexport type ConfigKey =\n | 'sdkRootDir'\n | 'cmdToolsPath'\n | 'emulatorDir'\n | 'hapPath'\n | 'cmdToolsUrlLinux'\n | 'cmdToolsUrlWindows'\n | 'cmdToolsUrlMac'\n | 'emulatorUrl';\n\nexport interface ConfigProvider {\n /**\n * Get the configured value for `key`, or `fallback` if unset/empty.\n * Implementations should expand the literal `${userHome}` to the user's home dir.\n */\n get<T extends string | number | boolean>(key: ConfigKey, fallback: T): T;\n}\n\n/**\n * Default config values used when a ConfigProvider returns the fallback.\n * These match the historical paths used by the bash CLI and the extension.\n */\nexport const defaultPaths = {\n sdkRootDir: () => path.join(os.homedir(), 'setup-ohos-sdk'),\n cmdToolsPath: () => path.join(os.homedir(), 'command-line-tools'),\n emulatorDir: () => path.join(os.homedir(), 'oniro-emulator'),\n hapPath: 'entry/build/default/outputs/default/entry-default-signed.hap',\n emulatorUrl:\n 'https://github.com/eclipse-oniro4openharmony/device_board_oniro/releases/latest/download/oniro_emulator.zip',\n // The Huawei mirror only hosts a public Linux build of the command-line tools.\n // Windows and macOS require a manual download from the Huawei developer portal\n // (https://developer.huawei.com/...); pass the resulting ZIP to `cmdtools install --from-zip <path>`\n // or set ONIRO_CMD_TOOLS_URL_WINDOWS / ONIRO_CMD_TOOLS_URL_MAC to a self-hosted URL.\n cmdToolsUrlLinux:\n 'https://repo.huaweicloud.com/harmonyos/ohpm/5.1.0/commandline-tools-linux-x64-5.1.0.840.zip',\n} as const;\n\n/**\n * A simple in-memory ConfigProvider, useful for tests and as a base for CLI/extension impls.\n */\nexport function staticConfig(values: Partial<Record<ConfigKey, string>> = {}): ConfigProvider {\n return {\n get<T extends string | number | boolean>(key: ConfigKey, fallback: T): T {\n const v = values[key];\n if (v === undefined || v === '') {\n return fallback;\n }\n // Expand ${userHome} like the extension does.\n if (typeof v === 'string' && v.includes('${userHome}')) {\n return v.replace(/\\$\\{userHome\\}/g, os.homedir()) as unknown as T;\n }\n return v as unknown as T;\n },\n };\n}\n","/**\n * Interactive prompts. Frontends implement these — CLI uses @inquirer/prompts,\n * the extension uses `vscode.window.show*`. Core never assumes a TTY.\n */\nexport interface Prompter {\n /** Ask the user to confirm an action. */\n confirm(message: string, defaultValue?: boolean): Promise<boolean>;\n /** Ask the user for a single line of text. */\n input(message: string, defaultValue?: string): Promise<string>;\n /** Ask the user to pick a directory on disk; resolves to an absolute path or null if cancelled. */\n selectDirectory(message: string, defaultPath?: string): Promise<string | null>;\n /** Ask the user to pick a file on disk; resolves to an absolute path or null if cancelled. */\n selectFile(message: string, filters?: { extensions?: string[] }): Promise<string | null>;\n}\n\n/**\n * Throws on any prompt — used in non-interactive contexts where all answers must come from flags.\n */\nexport const nonInteractivePrompter: Prompter = {\n async confirm(message) {\n throw new Error(`Non-interactive mode: cannot confirm \"${message}\"`);\n },\n async input(message) {\n throw new Error(`Non-interactive mode: cannot ask \"${message}\"`);\n },\n async selectDirectory(message) {\n throw new Error(`Non-interactive mode: cannot prompt for directory \"${message}\"`);\n },\n async selectFile(message) {\n throw new Error(`Non-interactive mode: cannot prompt for file \"${message}\"`);\n },\n};\n","export class OniroError extends Error {\n constructor(message: string, public override readonly cause?: unknown) {\n super(message);\n this.name = 'OniroError';\n }\n}\n\nexport class SdkNotInstalledError extends OniroError {\n constructor(public readonly api: string, public readonly expectedPath: string) {\n super(`SDK API ${api} is not installed at ${expectedPath}.`);\n this.name = 'SdkNotInstalledError';\n }\n}\n\nexport class CmdToolsNotInstalledError extends OniroError {\n constructor(public readonly expectedPath: string) {\n super(`OpenHarmony command-line tools are not installed at ${expectedPath}.`);\n this.name = 'CmdToolsNotInstalledError';\n }\n}\n\nexport class UnsupportedPlatformError extends OniroError {\n constructor(public readonly platform: string) {\n super(`Unsupported platform: ${platform}.`);\n this.name = 'UnsupportedPlatformError';\n }\n}\n\nexport class ChecksumMismatchError extends OniroError {\n constructor(public readonly expected: string, public readonly actual: string) {\n super(`SHA256 mismatch: expected ${expected}, got ${actual}.`);\n this.name = 'ChecksumMismatchError';\n }\n}\n\nexport class CancelledError extends OniroError {\n constructor(message = 'Operation cancelled.') {\n super(message);\n this.name = 'CancelledError';\n }\n}\n","import { Logger, noopLogger } from './logger.js';\nimport { ConfigProvider, staticConfig } from './config.js';\n\n/**\n * Carries the cross-cutting dependencies most core functions need: a Logger and a ConfigProvider.\n * Functions that report progress or prompt the user take those as additional parameters.\n */\nexport interface OniroContext {\n logger: Logger;\n config: ConfigProvider;\n}\n\nexport function defaultContext(overrides: Partial<OniroContext> = {}): OniroContext {\n return {\n logger: overrides.logger ?? noopLogger,\n config: overrides.config ?? staticConfig(),\n };\n}\n","export interface SdkRelease {\n version: string;\n api: string;\n}\n\n/**\n * Known OpenHarmony SDK releases. Kept in sync with the bash CLI / extension.\n * Update when a new SDK ships.\n */\nexport const ALL_SDKS: readonly SdkRelease[] = [\n { version: '4.0', api: '10' },\n { version: '4.1', api: '11' },\n { version: '5.0.0', api: '12' },\n { version: '5.0.1', api: '13' },\n { version: '5.0.2', api: '14' },\n { version: '5.0.3', api: '15' },\n { version: '5.1.0', api: '18' },\n { version: '6.0', api: '20' },\n { version: '6.1', api: '23' },\n];\n\nexport const OHOS_URL_BASE = 'https://repo.huaweicloud.com/openharmony/os';\n","import * as os from 'node:os';\nimport { ALL_SDKS } from './constants.js';\nimport { UnsupportedPlatformError } from '../ports/errors.js';\n\nexport type OsFolder = 'linux' | 'darwin' | 'windows';\n\n/**\n * Map Node's `os.platform()` to the OS folder name used in the SDK install layout\n * and the SDK release tarballs.\n */\nexport function getOsFolder(): OsFolder {\n const platform = os.platform();\n if (platform === 'linux') return 'linux';\n if (platform === 'darwin') return 'darwin';\n if (platform === 'win32') return 'windows';\n throw new UnsupportedPlatformError(platform);\n}\n\nexport interface SdkArchiveInfo {\n filename: string;\n osFolder: OsFolder;\n /** Number of leading path components to strip when extracting the tarball. */\n strip: number;\n}\n\n/**\n * Resolve the SDK archive filename, OS folder, and tar strip count for the current platform.\n *\n * The Huawei mirror packages Linux and Windows together in one tarball with `linux/` and\n * `windows/` subfolders. For 5.0.0/5.0.1/6.0 the tarball has no extra top-level wrapper\n * (strip=0); newer/older releases wrap the OS folders in a single top-level directory (strip=1).\n * macOS tarballs have a deeper layout (strip=3).\n */\nexport function getSdkFilename(version?: string): SdkArchiveInfo {\n const platform = os.platform();\n const v = version ?? ALL_SDKS[ALL_SDKS.length - 1]!.version;\n\n if (platform === 'linux') {\n const strip = v === '5.0.0' || v === '5.0.1' || v === '6.0' || v === '6.1' ? 0 : 1;\n return { filename: 'ohos-sdk-windows_linux-public.tar.gz', osFolder: 'linux', strip };\n }\n if (platform === 'darwin') {\n if (os.arch() === 'arm64') {\n return { filename: 'L2-SDK-MAC-M1-PUBLIC.tar.gz', osFolder: 'darwin', strip: 3 };\n }\n return { filename: 'ohos-sdk-mac-public.tar.gz', osFolder: 'darwin', strip: 3 };\n }\n if (platform === 'win32') {\n const strip = v === '5.0.0' || v === '5.0.1' || v === '6.0' || v === '6.1' ? 0 : 1;\n return { filename: 'ohos-sdk-windows_linux-public.tar.gz', osFolder: 'windows', strip };\n }\n throw new UnsupportedPlatformError(platform);\n}\n","import * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { ConfigProvider, defaultPaths } from '../ports/config.js';\nimport { getOsFolder } from './platform.js';\n\nexport function getSdkRootDir(config: ConfigProvider): string {\n return config.get('sdkRootDir', defaultPaths.sdkRootDir());\n}\n\n/**\n * Base SDK home for the current OS: `<sdkRootDir>/<linux|darwin|windows>`.\n * SDK API folders (e.g. `12`, `18`, `20`) live inside this directory.\n */\nexport function getOhosBaseSdkHome(config: ConfigProvider): string {\n return path.join(getSdkRootDir(config), getOsFolder());\n}\n\nexport function getCmdToolsPath(config: ConfigProvider): string {\n return config.get('cmdToolsPath', defaultPaths.cmdToolsPath());\n}\n\nexport function getEmulatorDir(config: ConfigProvider): string {\n return config.get('emulatorDir', defaultPaths.emulatorDir());\n}\n\nfunction pickExisting(candidates: string[]): string {\n for (const c of candidates) {\n if (fs.existsSync(c)) return c;\n }\n return candidates[0]!;\n}\n\n/**\n * Resolve the OHPM binary path inside the command-line tools install.\n * On Windows tries common executable suffixes (.exe, .cmd, .bat) before the POSIX name.\n */\nexport function getCmdToolsBin(config: ConfigProvider): string {\n const binDir = path.join(getCmdToolsPath(config), 'bin');\n if (os.platform() === 'win32') {\n return pickExisting([\n path.join(binDir, 'ohpm.exe'),\n path.join(binDir, 'ohpm.cmd'),\n path.join(binDir, 'ohpm.bat'),\n path.join(binDir, 'ohpm'),\n ]);\n }\n return path.join(binDir, 'ohpm');\n}\n\n/**\n * Resolve the hdc binary path inside the SDK toolchains tree.\n */\nexport function getHdcPath(config: ConfigProvider): string {\n const base = path.join(getCmdToolsPath(config), 'sdk', 'default', 'openharmony', 'toolchains');\n if (os.platform() === 'win32') {\n return pickExisting([\n path.join(base, 'hdc.exe'),\n path.join(base, 'hdc.bat'),\n path.join(base, 'hdc.cmd'),\n path.join(base, 'hdc'),\n ]);\n }\n return path.join(base, 'hdc');\n}\n\n/**\n * Resolve the hvigorw wrapper for a project, preferring the project-local copy\n * (which carries the project's pinned hvigor version) and falling back to the\n * one shipped with the command-line tools.\n */\nexport function getHvigorwPath(config: ConfigProvider, projectDir: string): string {\n const cmdToolsBin = path.join(getCmdToolsPath(config), 'bin');\n return pickExisting([\n path.join(projectDir, 'hvigorw'),\n path.join(projectDir, 'hvigorw.bat'),\n path.join(projectDir, 'hvigorw.cmd'),\n path.join(cmdToolsBin, 'hvigorw'),\n path.join(cmdToolsBin, 'hvigorw.bat'),\n path.join(cmdToolsBin, 'hvigorw.cmd'),\n ]);\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport JSON5 from 'json5';\nimport { Logger, noopLogger } from '../ports/logger.js';\n\n/**\n * Detect the SDK API a project targets by reading `build-profile.json5`.\n * Returns the `compileSdkVersion` of the first declared product, or undefined\n * if the file is missing/malformed or no product declares one.\n */\nexport function detectProjectSdkVersion(projectRoot: string, logger: Logger = noopLogger): number | undefined {\n const buildProfilePath = path.join(projectRoot, 'build-profile.json5');\n if (!fs.existsSync(buildProfilePath)) {\n logger.warn(`build-profile.json5 not found at ${projectRoot}`);\n return undefined;\n }\n try {\n const content = fs.readFileSync(buildProfilePath, 'utf-8');\n const config = JSON5.parse(content) as { app?: { products?: Array<{ compileSdkVersion?: unknown }> } };\n const product = config.app?.products?.[0];\n const v = product?.compileSdkVersion;\n return typeof v === 'number' ? v : undefined;\n } catch (err) {\n logger.error(`Error reading build-profile.json5 at ${projectRoot}: ${String(err)}`);\n return undefined;\n }\n}\n","import * as fs from 'node:fs';\nimport * as crypto from 'node:crypto';\nimport { pipeline } from 'node:stream';\nimport { promisify } from 'node:util';\nimport followRedirects from 'follow-redirects';\nimport type { ProgressReporter } from '../ports/progress.js';\nimport { CancelledError, ChecksumMismatchError, OniroError } from '../ports/errors.js';\n\nconst { http, https } = followRedirects;\nconst pipelineAsync = promisify(pipeline);\n\nexport interface DownloadOptions {\n url: string;\n dest: string;\n progress?: ProgressReporter;\n abortSignal?: AbortSignal;\n /** Overall progress start offset (0..100). Default 0. */\n start?: number;\n /** Overall progress range to consume (0..100). Default 100. */\n range?: number;\n}\n\n/**\n * Stream a remote file to disk with optional progress reporting and cancellation.\n * Follows redirects via the `follow-redirects` library.\n */\nexport async function downloadFile(opts: DownloadOptions): Promise<void> {\n const { url, dest, progress, abortSignal } = opts;\n const proto = url.startsWith('https') ? https : http;\n\n return new Promise((resolve, reject) => {\n const s = Math.max(0, Math.min(100, opts.start ?? 0));\n const r = Math.max(0, Math.min(100 - s, opts.range ?? 100));\n\n let settled = false;\n const done = (err?: unknown) => {\n if (settled) return;\n settled = true;\n err ? reject(err) : resolve();\n };\n\n if (abortSignal?.aborted) {\n done(new CancelledError('Download cancelled before start.'));\n return;\n }\n\n const file = fs.createWriteStream(dest);\n\n const req = proto.get(url, (response) => {\n if (response.statusCode !== 200) {\n try { response.destroy(); } catch {}\n try { file.close(); } catch {}\n fs.unlink(dest, () => {});\n done(new OniroError(`Failed to download '${url}' (HTTP ${response.statusCode})`));\n return;\n }\n\n const total = parseInt(response.headers['content-length'] || '0', 10);\n let downloaded = 0;\n let lastOverall = Math.round(s);\n\n response.on('data', (chunk: Buffer) => {\n downloaded += chunk.length;\n if (progress && total) {\n const localPercent = Math.min(100, Math.round((downloaded / total) * 100));\n const overall = Math.min(100, Math.round(s + (downloaded / total) * r));\n const inc = overall - lastOverall;\n if (inc > 0) {\n progress.report({ message: `Downloading: ${localPercent}%`, increment: inc });\n lastOverall = overall;\n } else {\n progress.report({ message: `Downloading: ${localPercent}%`, increment: 0 });\n }\n }\n });\n\n response.pipe(file);\n\n file.on('finish', () => {\n if (progress) {\n const endOverall = Math.min(100, Math.round(s + r));\n const inc = endOverall - lastOverall;\n if (inc > 0) progress.report({ message: 'Downloading: 100%', increment: inc });\n }\n file.close((err) => (err ? done(err) : done()));\n });\n\n abortSignal?.addEventListener('abort', () => {\n response.destroy();\n file.close();\n fs.unlink(dest, () => {});\n done(new CancelledError('Download cancelled.'));\n });\n });\n\n req.on('error', (err) => {\n try { file.close(); } catch {}\n fs.unlink(dest, () => {});\n done(new OniroError(`Error downloading '${url}': ${err.message}`, err));\n });\n\n abortSignal?.addEventListener('abort', () => {\n req.destroy();\n file.close();\n fs.unlink(dest, () => {});\n done(new CancelledError('Download cancelled.'));\n });\n });\n}\n\n/**\n * Verify the SHA-256 checksum of a file against an on-disk .sha256 file.\n * The .sha256 file is expected to contain the hex digest as its first whitespace-delimited token.\n */\nexport async function verifySha256(filePath: string, sha256Path: string): Promise<void> {\n const expected = fs.readFileSync(sha256Path, 'utf8').split(/\\s+/)[0]!;\n const hash = crypto.createHash('sha256');\n await pipelineAsync(fs.createReadStream(filePath), hash);\n const actual = hash.digest('hex');\n if (actual !== expected) {\n throw new ChecksumMismatchError(expected, actual);\n }\n}\n","import * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { pipeline } from 'node:stream';\nimport { promisify } from 'node:util';\nimport * as tar from 'tar';\nimport StreamZip from 'node-stream-zip';\nimport type { ProgressReporter } from '../ports/progress.js';\nimport type { Logger } from '../ports/logger.js';\nimport { noopLogger } from '../ports/logger.js';\nimport { OniroError } from '../ports/errors.js';\n\nconst pipelineAsync = promisify(pipeline);\n\nexport interface ExtractZipOptions {\n zipPath: string;\n dest: string;\n progress?: ProgressReporter;\n /** Overall progress start offset (0..100). Default 0. */\n start?: number;\n /** Overall progress range to consume (0..100). Default 100. */\n range?: number;\n logger?: Logger;\n}\n\n/**\n * Extract a ZIP to a destination directory, preserving file permissions and following\n * symlinks defensively. Protects against Zip Slip (entries whose paths escape `dest`).\n */\nexport async function extractZipWithProgress(opts: ExtractZipOptions): Promise<void> {\n const { zipPath, dest, progress } = opts;\n const logger = opts.logger ?? noopLogger;\n\n const zip = new (StreamZip as unknown as { async: new (cfg: { file: string }) => StreamZipAsync }).async({ file: zipPath });\n const entries = await zip.entries();\n const files = Object.values(entries);\n const total = files.length || 1;\n\n const s = Math.max(0, Math.min(100, opts.start ?? 0));\n const r = Math.max(0, Math.min(100 - s, opts.range ?? 100));\n\n let processed = 0;\n let lastOverall = Math.round(s);\n\n await fs.promises.mkdir(dest, { recursive: true });\n const destRoot = path.resolve(dest);\n\n const safeResolveTarget = (entryName: string): string => {\n const resolved = path.resolve(destRoot, entryName);\n const rel = path.relative(destRoot, resolved);\n if (rel.startsWith('..') || path.isAbsolute(rel)) {\n throw new OniroError(`Blocked ZIP entry with illegal path: ${entryName}`);\n }\n return resolved;\n };\n\n try {\n for (const file of files) {\n const entryName = file.name;\n const targetPath = safeResolveTarget(entryName);\n const attr = file.attr ? (file.attr >>> 16) : 0;\n const isSymlink = 'isSymbolicLink' in file\n ? Boolean(file.isSymbolicLink)\n : (attr & 0o170000) === 0o120000;\n\n if (file.isDirectory) {\n await fs.promises.mkdir(targetPath, { recursive: true });\n } else if (isSymlink) {\n await fs.promises.mkdir(path.dirname(targetPath), { recursive: true });\n const linkTargetBuffer = await zip.entryData(file);\n const linkTarget = linkTargetBuffer.toString('utf8');\n try {\n const isWin = os.platform() === 'win32';\n await fs.promises.symlink(linkTarget, targetPath, isWin ? 'file' : undefined);\n } catch (e) {\n logger.warn(`Failed to create symlink at ${targetPath}: ${String(e)}`);\n }\n } else {\n await fs.promises.mkdir(path.dirname(targetPath), { recursive: true });\n const readStream = await zip.stream(file);\n const writeStream = fs.createWriteStream(targetPath);\n await pipelineAsync(readStream, writeStream);\n if (attr > 0) {\n try {\n await fs.promises.chmod(targetPath, attr & 0o777);\n } catch {\n // Best-effort: Windows or filesystems without POSIX perms — ignore.\n }\n }\n }\n\n processed++;\n if (progress) {\n const localPercent = Math.min(100, Math.round((processed / total) * 100));\n const overall = Math.min(100, Math.round(s + (processed / total) * r));\n const inc = overall - lastOverall;\n if (inc > 0) {\n progress.report({ message: `Extracting: ${localPercent}%`, increment: inc });\n lastOverall = overall;\n } else {\n progress.report({ message: `Extracting: ${localPercent}%`, increment: 0 });\n }\n }\n }\n } finally {\n await zip.close();\n }\n\n if (progress) {\n const endOverall = Math.min(100, Math.round(s + r));\n const inc = endOverall - lastOverall;\n if (inc > 0) progress.report({ message: 'Extracting: 100%', increment: inc });\n }\n}\n\n/**\n * Extract a tar/tar.gz/tar.bz2 archive. Wraps `tar.x`.\n */\nexport async function extractTarball(tarPath: string, dest: string, strip = 0): Promise<void> {\n await tar.x({ file: tarPath, cwd: dest, strip });\n}\n\n// node-stream-zip's TypeScript types aren't great; this is the minimal shape we use.\ninterface ZipEntry {\n name: string;\n isDirectory: boolean;\n isSymbolicLink?: boolean;\n attr?: number;\n}\ninterface StreamZipAsync {\n entries(): Promise<Record<string, ZipEntry>>;\n entryData(entry: ZipEntry): Promise<Buffer>;\n stream(entry: ZipEntry): Promise<NodeJS.ReadableStream>;\n close(): Promise<void>;\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { ALL_SDKS } from './constants.js';\nimport { getSdkRootDir } from './paths.js';\nimport { getOsFolder } from './platform.js';\nimport type { ConfigProvider } from '../ports/config.js';\n\nexport interface SdkInfo {\n version: string;\n api: string;\n installed: boolean;\n}\n\n/**\n * List supported SDKs annotated with whether they are installed for the current OS.\n * Sorted by API descending (newest first).\n */\nexport function getSupportedSdksForUi(config: ConfigProvider): SdkInfo[] {\n const base = path.join(getSdkRootDir(config), getOsFolder());\n return ALL_SDKS.map((sdk) => ({\n version: sdk.version,\n api: sdk.api,\n installed: fs.existsSync(path.join(base, sdk.api)),\n })).sort((a, b) => Number(b.api) - Number(a.api));\n}\n\n/**\n * Return the SDK versions that have at least one OS-folder install in `sdkRootDir`.\n * Scans `linux`, `darwin`, `windows` so the list is consistent across machines that\n * share an SDK root over a network mount.\n */\nexport function getInstalledSdks(config: ConfigProvider): string[] {\n const sdkRoot = getSdkRootDir(config);\n const versions = new Set<string>();\n if (!fs.existsSync(sdkRoot)) return [];\n\n for (const osFolder of ['linux', 'darwin', 'windows'] as const) {\n const osPath = path.join(sdkRoot, osFolder);\n if (!fs.existsSync(osPath) || !fs.statSync(osPath).isDirectory()) continue;\n for (const api of fs.readdirSync(osPath)) {\n const apiPath = path.join(osPath, api);\n if (fs.statSync(apiPath).isDirectory()) versions.add(api);\n }\n }\n return ALL_SDKS.filter((sdk) => versions.has(sdk.api)).map((sdk) => sdk.version);\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { getSdkRootDir } from './paths.js';\nimport type { ConfigProvider } from '../ports/config.js';\n\n/**\n * Remove an installed SDK for a given API level, across all OS folders.\n * Returns true if at least one folder was deleted.\n */\nexport function removeSdk(config: ConfigProvider, api: string): boolean {\n const sdkRoot = getSdkRootDir(config);\n let removed = false;\n for (const osFolder of ['linux', 'darwin', 'windows']) {\n const sdkPath = path.join(sdkRoot, osFolder, api);\n if (fs.existsSync(sdkPath)) {\n fs.rmSync(sdkPath, { recursive: true, force: true });\n removed = true;\n }\n }\n return removed;\n}\n","import * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport type { ConfigProvider } from '../ports/config.js';\nimport type { ProgressReporter } from '../ports/progress.js';\nimport type { Logger } from '../ports/logger.js';\nimport { noopLogger } from '../ports/logger.js';\nimport { CancelledError, OniroError } from '../ports/errors.js';\nimport { OHOS_URL_BASE } from './constants.js';\nimport { getSdkFilename } from './platform.js';\nimport { getSdkRootDir } from './paths.js';\nimport { downloadFile, verifySha256 } from './download.js';\nimport { extractTarball, extractZipWithProgress } from './extract.js';\n\nexport interface InstallSdkOptions {\n config: ConfigProvider;\n version: string;\n api: string;\n progress?: ProgressReporter;\n abortSignal?: AbortSignal;\n logger?: Logger;\n}\n\n/**\n * Download and install an OpenHarmony SDK release into `<sdkRootDir>/<osFolder>/<api>`.\n *\n * Progress budget (overall 0..100):\n * 0..35 SDK archive download\n * 35..45 Checksum download\n * 45..50 Checksum verify\n * 50..60 Tarball extract\n * 60..95 Component ZIP extracts\n * 95..100 Finalize + cleanup\n */\nexport async function downloadAndInstallSdk(opts: InstallSdkOptions): Promise<void> {\n const { config, version, api, progress, abortSignal } = opts;\n const logger = opts.logger ?? noopLogger;\n\n const { filename, osFolder, strip } = getSdkFilename(version);\n const downloadUrl = `${OHOS_URL_BASE}/${version}-Release/${filename}`;\n const sha256Url = `${downloadUrl}.sha256`;\n\n const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'oniro-sdk-'));\n const tarPath = path.join(tmpDir, filename);\n const sha256Path = path.join(tmpDir, `${filename}.sha256`);\n const extractDir = path.join(tmpDir, 'extract');\n fs.mkdirSync(extractDir);\n\n const sdkInstallDir = path.join(getSdkRootDir(config), osFolder, api);\n fs.mkdirSync(path.dirname(sdkInstallDir), { recursive: true });\n\n const checkCancelled = () => {\n if (abortSignal?.aborted) throw new CancelledError();\n };\n\n try {\n progress?.report({ message: 'Downloading SDK archive...', increment: 0 });\n await downloadFile({ url: downloadUrl, dest: tarPath, progress, abortSignal, start: 0, range: 35 });\n\n progress?.report({ message: 'Downloading checksum...', increment: 0 });\n await downloadFile({ url: sha256Url, dest: sha256Path, progress, abortSignal, start: 35, range: 10 });\n\n progress?.report({ message: 'Verifying checksum...', increment: 0 });\n await verifySha256(tarPath, sha256Path);\n progress?.report({ message: 'Verifying checksum...', increment: 5 });\n\n checkCancelled();\n\n progress?.report({ message: 'Extracting SDK (this may take a while)...', increment: 0 });\n await extractTarball(tarPath, extractDir, strip);\n progress?.report({ message: 'Extracting SDK (this may take a while)...', increment: 10 });\n\n checkCancelled();\n\n const osContentPath = path.join(extractDir, osFolder);\n if (!fs.existsSync(osContentPath)) {\n throw new OniroError(\n `Expected folder '${osFolder}' not found in extracted SDK. Tarball layout may have changed.`,\n );\n }\n const zipFiles = fs.readdirSync(osContentPath).filter((n) => n.endsWith('.zip'));\n\n const componentsStart = 60;\n const componentsBudget = 35;\n const n = zipFiles.length;\n if (n === 0) {\n progress?.report({ message: 'No SDK component ZIPs found.', increment: componentsBudget });\n } else {\n progress?.report({ message: 'Extracting SDK components...', increment: 0 });\n }\n\n const base = n > 0 ? Math.floor(componentsBudget / n) : 0;\n let rem = n > 0 ? componentsBudget % n : 0;\n let cursor = componentsStart;\n\n for (const zipFile of zipFiles) {\n checkCancelled();\n logger.info(`Extracting component ${zipFile}`);\n const zipPath = path.join(osContentPath, zipFile);\n const thisBudget = base + (rem > 0 ? 1 : 0);\n if (rem > 0) rem--;\n await extractZipWithProgress({ zipPath, dest: osContentPath, progress, start: cursor, range: thisBudget, logger });\n cursor += thisBudget;\n fs.unlinkSync(zipPath);\n }\n\n progress?.report({ message: 'Finalizing installation...', increment: 0 });\n if (fs.existsSync(sdkInstallDir)) {\n fs.rmSync(sdkInstallDir, { recursive: true, force: true });\n }\n fs.renameSync(osContentPath, sdkInstallDir);\n progress?.report({ message: 'Finalizing installation...', increment: 3 });\n\n progress?.report({ message: 'Cleaning up...', increment: 0 });\n fs.rmSync(tmpDir, { recursive: true, force: true });\n progress?.report({ message: 'Cleaning up...', increment: 2 });\n } catch (err) {\n logger.error(`SDK install failed: ${err instanceof Error ? err.message : String(err)}`);\n fs.rmSync(tmpDir, { recursive: true, force: true });\n throw err;\n }\n}\n","import * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { execFileSync } from 'node:child_process';\nimport type { ConfigProvider } from '../ports/config.js';\nimport { defaultPaths } from '../ports/config.js';\nimport type { ProgressReporter } from '../ports/progress.js';\nimport type { Logger } from '../ports/logger.js';\nimport { noopLogger } from '../ports/logger.js';\nimport { OniroError, UnsupportedPlatformError } from '../ports/errors.js';\nimport { getCmdToolsPath } from '../sdk/paths.js';\nimport { downloadFile } from '../sdk/download.js';\nimport { extractZipWithProgress } from '../sdk/extract.js';\n\n/**\n * Resolve the per-platform download URL for the OpenHarmony command-line tools.\n *\n * Only Linux has a public download URL on the Huawei mirror. Windows and macOS\n * builds are gated behind the Huawei developer portal: users must download the\n * ZIP manually and pass it via `--from-zip`, or self-host the archive and point\n * `cmdToolsUrlWindows` / `cmdToolsUrlMac` at it.\n *\n * @param platform Defaults to the current host. Override for testing.\n */\nexport function getCmdToolsDownloadUrl(config: ConfigProvider, platform: NodeJS.Platform = os.platform()): string {\n if (platform === 'linux') {\n return config.get('cmdToolsUrlLinux', defaultPaths.cmdToolsUrlLinux);\n }\n if (platform === 'win32') {\n const url = config.get('cmdToolsUrlWindows', '');\n if (!url) {\n throw new OniroError(\n 'No Windows command-line tools URL configured. The Huawei mirror does not host a public Windows build; ' +\n 'download the ZIP from the Huawei developer portal and run `oniro-app cmdtools install --from-zip <path>`, ' +\n 'or set ONIRO_CMD_TOOLS_URL_WINDOWS to a self-hosted URL.',\n );\n }\n return url;\n }\n if (platform === 'darwin') {\n const url = config.get('cmdToolsUrlMac', '');\n if (!url) {\n throw new OniroError(\n 'No macOS command-line tools URL configured. The Huawei mirror does not host a public macOS build; ' +\n 'download the ZIP from the Huawei developer portal and run `oniro-app cmdtools install --from-zip <path>`, ' +\n 'or set ONIRO_CMD_TOOLS_URL_MAC to a self-hosted URL.',\n );\n }\n return url;\n }\n throw new UnsupportedPlatformError(platform);\n}\n\n/**\n * Locate the extracted command-line tools' source root within a temp extraction folder.\n * Tries known top-level names, then any subdirectory containing a `bin/` folder.\n */\nexport function findCmdToolsSourceDir(extractPath: string): string {\n const known = [\n path.join(extractPath, 'command-line-tools'),\n path.join(extractPath, 'oh-command-line-tools'),\n path.join(extractPath, 'commandline-tools'),\n ];\n for (const c of known) {\n if (fs.existsSync(c)) return c;\n }\n const entries = fs\n .readdirSync(extractPath, { withFileTypes: true })\n .filter((e) => e.isDirectory())\n .map((e) => path.join(extractPath, e.name));\n for (const dir of entries) {\n if (fs.existsSync(path.join(dir, 'bin'))) return dir;\n }\n throw new OniroError('Could not locate command line tools folder in the extracted archive.');\n}\n\nexport interface InstallCmdToolsOptions {\n config: ConfigProvider;\n progress?: ProgressReporter;\n abortSignal?: AbortSignal;\n logger?: Logger;\n /** Skip download and install from a local zip the caller already has. */\n localZipPath?: string;\n}\n\n/**\n * Install the OpenHarmony command-line tools into `<cmdToolsPath>`.\n * Either downloads from the platform-specific URL or installs from a caller-supplied ZIP.\n */\nexport async function installCmdTools(opts: InstallCmdToolsOptions): Promise<void> {\n const { config, progress, abortSignal } = opts;\n const logger = opts.logger ?? noopLogger;\n const CMD_PATH = getCmdToolsPath(config);\n\n const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'oniro-cmdtools-'));\n const zipPath = opts.localZipPath ?? path.join(tmpDir, 'oh-command-line-tools.zip');\n const extractPath = path.join(tmpDir, 'oh-command-line-tools');\n\n try {\n if (!opts.localZipPath) {\n const url = getCmdToolsDownloadUrl(config);\n progress?.report({ message: 'Downloading command line tools...', increment: 0 });\n await downloadFile({ url, dest: zipPath, progress, abortSignal, start: 0, range: 50 });\n }\n\n progress?.report({ message: 'Extracting tools...', increment: 0 });\n await extractZipWithProgress({ zipPath, dest: extractPath, progress, start: 50, range: 45, logger });\n\n fs.mkdirSync(CMD_PATH, { recursive: true });\n const srcDir = findCmdToolsSourceDir(extractPath);\n\n for (const entry of fs.readdirSync(srcDir)) {\n const src = path.join(srcDir, entry);\n const dest = path.join(CMD_PATH, entry);\n if (fs.statSync(src).isDirectory()) {\n if (fs.existsSync(dest)) fs.rmSync(dest, { recursive: true, force: true });\n fs.renameSync(src, dest);\n } else {\n fs.copyFileSync(src, dest);\n }\n }\n\n const binDir = path.join(CMD_PATH, 'bin');\n if (fs.existsSync(binDir) && os.platform() !== 'win32') {\n for (const file of fs.readdirSync(binDir)) {\n fs.chmodSync(path.join(binDir, file), 0o755);\n }\n }\n\n progress?.report({ message: 'Finalizing installation...', increment: 5 });\n progress?.report({ message: 'Cleaning up...', increment: 0 });\n } finally {\n fs.rmSync(tmpDir, { recursive: true, force: true });\n }\n}\n\nexport interface CmdToolsStatus {\n installed: boolean;\n status: string;\n}\n\n/**\n * Reports whether ohpm is present at the configured path, and if so its version.\n * Prefers reading `version.txt` (`# Version: x.y.z`) before falling back to executing\n * the binary with `-v`.\n */\nexport function getCmdToolsStatus(config: ConfigProvider): CmdToolsStatus {\n const cmdPath = getCmdToolsPath(config);\n const binDir = path.join(cmdPath, 'bin');\n const candidates = os.platform() === 'win32'\n ? ['ohpm.exe', 'ohpm.cmd', 'ohpm.bat', 'ohpm']\n : ['ohpm'];\n const bin = candidates.map((c) => path.join(binDir, c)).find((p) => fs.existsSync(p));\n if (!bin) {\n return { installed: false, status: 'Not installed' };\n }\n\n // Prefer version.txt.\n try {\n const versionFile = path.join(cmdPath, 'version.txt');\n if (fs.existsSync(versionFile)) {\n const content = fs.readFileSync(versionFile, 'utf8');\n for (const line of content.split(/\\r?\\n/)) {\n const m = line.match(/^\\s*#\\s*Version:\\s*(.+)$/);\n if (m?.[1]) return { installed: true, status: `Installed (${m[1].trim()})` };\n }\n }\n } catch {\n // Fall through to exec.\n }\n\n try {\n const version = execFileSync(bin, ['-v'], { encoding: 'utf8' }).trim();\n return { installed: true, status: `Installed (${version})` };\n } catch {\n return { installed: true, status: 'Installed (version unknown)' };\n }\n}\n\nexport function isCmdToolsInstalled(config: ConfigProvider): boolean {\n return getCmdToolsStatus(config).installed;\n}\n\nexport function removeCmdTools(config: ConfigProvider): void {\n const cmdPath = getCmdToolsPath(config);\n if (fs.existsSync(cmdPath)) {\n fs.rmSync(cmdPath, { recursive: true, force: true });\n }\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as crypto from 'node:crypto';\n\nconst DAEMON_ROOT_KEY_COMPONENT_LENGTH = 16;\nconst DAEMON_SALT_KEY_LENGTH = 16;\nconst DAEMON_WORK_KEY_LENGTH = 16;\nconst KEY_FILE_DIRECTORY_PERMISSIONS = 0o755;\nconst KEY_FILE_PERMISSIONS = 0o600;\n\nconst COMPONENT = Buffer.from([\n 49, 243, 9, 115, 214, 175, 91, 184, 211, 190, 177, 88, 101, 131, 192, 119,\n]);\n\n/**\n * Encrypts data using AES-128-GCM.\n * Output layout: [4-byte BE length][12-byte IV][ciphertext][16-byte auth tag].\n */\nfunction encrypt(key: Buffer, data: Buffer): Buffer {\n const iv = crypto.randomBytes(12);\n const cipher = crypto.createCipheriv('aes-128-gcm', key, iv);\n const ciphertext = Buffer.concat([cipher.update(data), cipher.final()]);\n const authTag = cipher.getAuthTag();\n const totalLength = ciphertext.length + authTag.length;\n const out = Buffer.alloc(4 + iv.length + ciphertext.length + authTag.length);\n out.writeUInt32BE(totalLength, 0);\n iv.copy(out, 4);\n ciphertext.copy(out, 16);\n authTag.copy(out, 16 + ciphertext.length);\n return out;\n}\n\nfunction decrypt(key: Buffer, data: Buffer): Buffer {\n const totalLength = data.readUInt32BE(0);\n const iv = data.subarray(4, 16);\n const ciphertextLength = totalLength - 16;\n const ciphertext = data.subarray(16, 16 + ciphertextLength);\n const authTag = data.subarray(16 + ciphertextLength);\n const decipher = crypto.createDecipheriv('aes-128-gcm', key, iv);\n decipher.setAuthTag(authTag);\n return Buffer.concat([decipher.update(ciphertext), decipher.final()]);\n}\n\nfunction xorBuffers(buffers: Buffer[]): Buffer {\n if (buffers.length === 0) {\n throw new Error('No buffers provided for XOR.');\n }\n const result = Buffer.from(buffers[0]!);\n for (let i = 1; i < buffers.length; i++) {\n const buf = buffers[i]!;\n if (buf.length !== result.length) {\n throw new Error('Buffers have different lengths in XOR.');\n }\n for (let j = 0; j < result.length; j++) {\n result[j] = result[j]! ^ buf[j]!;\n }\n }\n return result;\n}\n\nfunction getRootKey(fdComponents: Buffer[], salt: Buffer): Buffer {\n const components = fdComponents.concat([COMPONENT]);\n const xored = xorBuffers(components);\n return crypto.pbkdf2Sync(xored.toString(), salt, 10000, 16, 'sha256');\n}\n\nfunction createAndStoreKey(dir: string, keyLength: number): Buffer {\n const key = crypto.randomBytes(keyLength);\n const hash = crypto.createHash('sha256').update(key).digest('hex');\n const filePath = path.join(dir, hash);\n fs.writeFileSync(filePath, key);\n fs.chmodSync(filePath, KEY_FILE_PERMISSIONS);\n return key;\n}\n\nfunction createAndStoreEnKey(rootKey: Buffer, ceDir: string): void {\n const workKey = crypto.randomBytes(DAEMON_WORK_KEY_LENGTH);\n const encrypted = encrypt(rootKey, workKey);\n const hash = crypto.createHash('sha256').update(encrypted).digest('hex');\n const filePath = path.join(ceDir, hash);\n fs.writeFileSync(filePath, encrypted);\n fs.chmodSync(filePath, KEY_FILE_PERMISSIONS);\n}\n\n/**\n * Generates the signing-material directory tree: fd/{0,1,2}, ac, ce.\n * Each subfolder contains a randomly-named keyfile derived as described in\n * the OpenHarmony hap-sign-tool reference implementation.\n */\nexport function createMaterial(materialPath: string): void {\n fs.mkdirSync(materialPath, { recursive: true });\n fs.chmodSync(materialPath, KEY_FILE_DIRECTORY_PERMISSIONS);\n\n const fdDir = path.join(materialPath, 'fd');\n const acDir = path.join(materialPath, 'ac');\n const ceDir = path.join(materialPath, 'ce');\n\n fs.mkdirSync(fdDir, { recursive: true });\n fs.mkdirSync(acDir, { recursive: true });\n fs.mkdirSync(ceDir, { recursive: true });\n\n const fdSubDirs = ['0', '1', '2'];\n const fdComponents: Buffer[] = [];\n for (const sub of fdSubDirs) {\n const subDir = path.join(fdDir, sub);\n fs.mkdirSync(subDir, { recursive: true });\n const comp = createAndStoreKey(subDir, DAEMON_ROOT_KEY_COMPONENT_LENGTH);\n fdComponents.push(comp);\n }\n\n const salt = createAndStoreKey(acDir, DAEMON_SALT_KEY_LENGTH);\n const rootKey = getRootKey(fdComponents, salt);\n createAndStoreEnKey(rootKey, ceDir);\n}\n\nfunction readSingleFile(dir: string): Buffer {\n if (!fs.existsSync(dir) || !fs.statSync(dir).isDirectory()) {\n throw new Error(`Missing signing material directory: ${dir}`);\n }\n const files = fs.readdirSync(dir).filter((f) => f !== '.DS_Store');\n if (files.length !== 1) {\n throw new Error(`Signing material in ${dir} is illegal (expected exactly one file).`);\n }\n return fs.readFileSync(path.join(dir, files[0]!));\n}\n\n/**\n * Re-derives the work key from an existing material directory.\n */\nexport function getKey(materialPath: string): Buffer {\n if (!fs.existsSync(materialPath) || !fs.statSync(materialPath).isDirectory()) {\n throw new Error('Material directory does not exist.');\n }\n\n const fdDir = path.join(materialPath, 'fd');\n const fdComponents = ['0', '1', '2'].map((sub) => readSingleFile(path.join(fdDir, sub)));\n const salt = readSingleFile(path.join(materialPath, 'ac'));\n const rootKey = getRootKey(fdComponents, salt);\n const workMaterial = readSingleFile(path.join(materialPath, 'ce'));\n return decrypt(rootKey, workMaterial);\n}\n\n/**\n * Encrypts a password using the work key derived from `materialPath`.\n * Returns the encrypted blob as a hex string (the format expected in build-profile.json5).\n */\nexport function encryptPwd(password: string, materialPath: string): string {\n const key = getKey(materialPath);\n const pwdBuffer = Buffer.from(password, 'utf-8');\n return encrypt(key, pwdBuffer).toString('hex');\n}\n\n/**\n * Inverse of `encryptPwd`. Exposed for parity with the original CLI.\n */\nexport function decryptPwd(encryptedHex: string, materialPath: string): string {\n const key = getKey(materialPath);\n const encryptedBuffer = Buffer.from(encryptedHex, 'hex');\n return decrypt(key, encryptedBuffer).toString('utf-8');\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { execFileSync } from 'node:child_process';\nimport JSON5 from 'json5';\nimport { encryptPwd, createMaterial } from './encryptKey.js';\nimport { detectProjectSdkVersion } from '../sdk/detectProjectSdk.js';\nimport type { Logger } from '../ports/logger.js';\nimport { noopLogger } from '../ports/logger.js';\nimport { OniroError } from '../ports/errors.js';\n\n/** Ability Privilege Level written into the profile's `bundle-info.apl`. */\nexport type Apl = 'normal' | 'system_basic' | 'system_core';\n\n/** App feature written into the profile's `bundle-info.app-feature`. */\nexport type AppFeature = 'hos_normal_app' | 'hos_system_app';\n\nexport const APL_VALUES: readonly Apl[] = ['normal', 'system_basic', 'system_core'];\nexport const APP_FEATURE_VALUES: readonly AppFeature[] = ['hos_normal_app', 'hos_system_app'];\n\nexport interface GenerateSigningConfigsOptions {\n /** Absolute path to the OpenHarmony project (the folder containing build-profile.json5). */\n projectDir: string;\n /** Absolute path to the OS-specific SDK home (the folder containing API-version subfolders). */\n sdkHome: string;\n /**\n * APL level to write into the profile's `bundle-info.apl`. Defaults to `'normal'`.\n * Apps requesting permissions above `normal` (e.g. `ohos.permission.GET_WIFI_INFO_INTERNAL`)\n * need `system_basic` or `system_core` — otherwise `bm install` fails with\n * `grant request permissions failed`.\n */\n apl?: Apl;\n /**\n * App feature to write into `bundle-info.app-feature`. Defaults to `'hos_normal_app'`\n * when `apl='normal'`, otherwise `'hos_system_app'`.\n */\n appFeature?: AppFeature;\n /** Optional logger; defaults to no-op. */\n logger?: Logger;\n}\n\nfunction copyFilesToProject(\n projectDir: string,\n paths: { keystore: string; profileCert: string; unsignedProfileTemplate: string },\n logger: Logger,\n): void {\n logger.info('[sign] Copying signing material into project...');\n const signaturesDir = path.join(projectDir, 'signatures');\n fs.mkdirSync(signaturesDir, { recursive: true });\n\n fs.copyFileSync(paths.keystore, path.join(signaturesDir, 'OpenHarmony.p12'));\n fs.copyFileSync(paths.profileCert, path.join(signaturesDir, 'OpenHarmonyProfileRelease.pem'));\n fs.copyFileSync(paths.unsignedProfileTemplate, path.join(signaturesDir, 'UnsgnedReleasedProfileTemplate.json'));\n}\n\n/**\n * Pick the app-feature value: explicit override wins; otherwise `hos_normal_app` for\n * apl=normal, `hos_system_app` for system_basic/system_core.\n * @internal exposed for tests.\n */\nexport function resolveAppFeature(apl: Apl, override?: AppFeature): AppFeature {\n if (override) return override;\n return apl === 'normal' ? 'hos_normal_app' : 'hos_system_app';\n}\n\n/** @internal exposed for tests. */\nexport function modifyProfileTemplate(\n projectDir: string,\n apl: Apl,\n appFeature: AppFeature,\n logger: Logger,\n): void {\n logger.info(`[sign] Modifying profile template (apl=${apl}, app-feature=${appFeature})...`);\n const appJsonPath = path.join(projectDir, 'AppScope/app.json5');\n const profileTemplatePath = path.join(projectDir, 'signatures/UnsgnedReleasedProfileTemplate.json');\n const profileCertFilePath = path.join(projectDir, 'signatures/OpenHarmonyProfileRelease.pem');\n\n if (!fs.existsSync(appJsonPath)) {\n throw new OniroError(`${appJsonPath} does not exist.`);\n }\n\n let appJson: { app?: { bundleName?: string } };\n try {\n appJson = JSON5.parse(fs.readFileSync(appJsonPath, 'utf-8'));\n } catch (e) {\n throw new OniroError(`Error parsing ${appJsonPath}: ${(e as Error).message}`, e);\n }\n\n let profileTemplate: {\n 'bundle-info'?: {\n 'bundle-name'?: string;\n 'distribution-certificate'?: string;\n apl?: string;\n 'app-feature'?: string;\n };\n };\n try {\n profileTemplate = JSON.parse(fs.readFileSync(profileTemplatePath, 'utf-8'));\n } catch (e) {\n throw new OniroError(`Error parsing ${profileTemplatePath}: ${(e as Error).message}`, e);\n }\n\n if (!appJson.app?.bundleName) {\n throw new OniroError('app.json5 does not contain app.bundleName.');\n }\n if (!profileTemplate['bundle-info']) {\n throw new OniroError('UnsgnedReleasedProfileTemplate.json is missing the bundle-info section.');\n }\n\n profileTemplate['bundle-info']['bundle-name'] = appJson.app.bundleName;\n profileTemplate['bundle-info']['apl'] = apl;\n profileTemplate['bundle-info']['app-feature'] = appFeature;\n\n const certContent = fs.readFileSync(profileCertFilePath, 'utf-8');\n const certs = certContent.split('-----END CERTIFICATE-----');\n if (certs.length < 3) {\n throw new OniroError(`${profileCertFilePath} does not contain enough certificates.`);\n }\n const thirdCert = certs[2]!.trim() + '\\n-----END CERTIFICATE-----\\n';\n profileTemplate['bundle-info']['distribution-certificate'] = thirdCert;\n\n fs.writeFileSync(profileTemplatePath, JSON.stringify(profileTemplate, null, 2));\n}\n\nfunction generateP7bFile(\n projectDir: string,\n paths: { signTool: string; profileCert: string; keystore: string },\n logger: Logger,\n): void {\n logger.info('[sign] Generating P7b profile via hap-sign-tool...');\n const signaturesDir = path.join(projectDir, 'signatures');\n const profileTemplatePath = path.join(signaturesDir, 'UnsgnedReleasedProfileTemplate.json');\n const outputProfilePath = path.join(signaturesDir, 'app1-profile.p7b');\n\n const args = [\n '-jar', paths.signTool,\n 'sign-profile',\n '-keyAlias', 'openharmony application profile release',\n '-signAlg', 'SHA256withECDSA',\n '-mode', 'localSign',\n '-profileCertFile', paths.profileCert,\n '-inFile', profileTemplatePath,\n '-keystoreFile', paths.keystore,\n '-outFile', outputProfilePath,\n '-keyPwd', '123456',\n '-keystorePwd', '123456',\n ];\n\n try {\n execFileSync('java', args, { stdio: 'inherit' });\n } catch (e) {\n throw new OniroError(\n `hap-sign-tool failed. Ensure a JDK (with keytool/java) is on PATH. Underlying error: ${(e as Error).message}`,\n e,\n );\n }\n}\n\nfunction updateBuildProfile(projectDir: string, logger: Logger): void {\n logger.info('[sign] Writing signing configs into build-profile.json5...');\n const materialDir = path.join(projectDir, 'signatures', 'material');\n const buildProfilePath = path.join(projectDir, 'build-profile.json5');\n\n const encryptedStorePassword = encryptPwd('123456', materialDir);\n const encryptedKeyPassword = encryptPwd('123456', materialDir);\n\n let buildProfile: { app?: { signingConfigs?: unknown[] } } = { app: {} };\n if (fs.existsSync(buildProfilePath)) {\n try {\n buildProfile = JSON5.parse(fs.readFileSync(buildProfilePath, 'utf-8'));\n } catch (e) {\n throw new OniroError(`Error parsing ${buildProfilePath}: ${(e as Error).message}`, e);\n }\n }\n\n buildProfile.app = buildProfile.app ?? {};\n buildProfile.app.signingConfigs = [\n {\n name: 'default',\n material: {\n certpath: './signatures/OpenHarmonyProfileRelease.pem',\n storePassword: encryptedStorePassword,\n keyAlias: 'openharmony application profile release',\n keyPassword: encryptedKeyPassword,\n profile: './signatures/app1-profile.p7b',\n signAlg: 'SHA256withECDSA',\n storeFile: './signatures/OpenHarmony.p12',\n },\n },\n ];\n\n // Intentionally strict JSON (not JSON5) — keeps the file readable by VS Code's JSON parser.\n fs.writeFileSync(buildProfilePath, JSON.stringify(buildProfile, null, 2));\n}\n\nfunction prepareMaterialDirectory(projectDir: string, logger: Logger): void {\n logger.info('[sign] Generating fresh signing material...');\n const materialDir = path.join(projectDir, 'signatures', 'material');\n if (fs.existsSync(materialDir)) {\n fs.rmSync(materialDir, { recursive: true, force: true });\n }\n createMaterial(materialDir);\n}\n\n/**\n * Generate signing configs for an OpenHarmony project: copies certs, signs the profile,\n * generates the signing material, and writes the resulting `signingConfigs` entry into\n * `build-profile.json5`.\n *\n * Requires `java` on PATH (the OpenHarmony hap-sign-tool ships as a .jar).\n */\nexport function generateSigningConfigs(options: GenerateSigningConfigsOptions): void {\n const { projectDir, sdkHome } = options;\n const logger = options.logger ?? noopLogger;\n const apl: Apl = options.apl ?? 'normal';\n if (!APL_VALUES.includes(apl)) {\n throw new OniroError(`Invalid apl '${apl}'. Expected one of: ${APL_VALUES.join(', ')}.`);\n }\n const appFeature: AppFeature = resolveAppFeature(apl, options.appFeature);\n if (!APP_FEATURE_VALUES.includes(appFeature)) {\n throw new OniroError(\n `Invalid appFeature '${appFeature}'. Expected one of: ${APP_FEATURE_VALUES.join(', ')}.`,\n );\n }\n\n const sdkVersion = detectProjectSdkVersion(projectDir, logger);\n if (!sdkVersion) {\n throw new OniroError(\n 'Could not detect project SDK version (compileSdkVersion missing in build-profile.json5).',\n );\n }\n\n const sdkPath = path.join(sdkHome, String(sdkVersion));\n if (!fs.existsSync(sdkPath)) {\n throw new OniroError(`SDK path does not exist: ${sdkPath}`);\n }\n\n const paths = {\n signTool: path.join(sdkPath, 'toolchains/lib/hap-sign-tool.jar'),\n keystore: path.join(sdkPath, 'toolchains/lib/OpenHarmony.p12'),\n profileCert: path.join(sdkPath, 'toolchains/lib/OpenHarmonyProfileRelease.pem'),\n unsignedProfileTemplate: path.join(sdkPath, 'toolchains/lib/UnsgnedReleasedProfileTemplate.json'),\n };\n\n logger.info('[sign] Starting signing configuration generation...');\n copyFilesToProject(projectDir, paths, logger);\n modifyProfileTemplate(projectDir, apl, appFeature, logger);\n generateP7bFile(projectDir, paths, logger);\n prepareMaterialDirectory(projectDir, logger);\n updateBuildProfile(projectDir, logger);\n logger.info('[sign] Signing configuration generated successfully.');\n}\n","import * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport type { ConfigProvider } from '../ports/config.js';\nimport { defaultPaths } from '../ports/config.js';\nimport type { ProgressReporter } from '../ports/progress.js';\nimport type { Logger } from '../ports/logger.js';\nimport { noopLogger } from '../ports/logger.js';\nimport { getEmulatorDir } from '../sdk/paths.js';\nimport { downloadFile } from '../sdk/download.js';\nimport { extractZipWithProgress } from '../sdk/extract.js';\n\nexport interface InstallEmulatorOptions {\n config: ConfigProvider;\n progress?: ProgressReporter;\n abortSignal?: AbortSignal;\n logger?: Logger;\n}\n\n/**\n * Download and extract the Oniro emulator into the configured `emulatorDir`.\n */\nexport async function installEmulator(opts: InstallEmulatorOptions): Promise<void> {\n const { config, progress, abortSignal } = opts;\n const logger = opts.logger ?? noopLogger;\n\n const url = config.get('emulatorUrl', defaultPaths.emulatorUrl);\n const emulatorDir = getEmulatorDir(config);\n const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'oniro-emulator-'));\n const tmpZip = path.join(tmpDir, 'oniro_emulator.zip');\n\n try {\n fs.mkdirSync(emulatorDir, { recursive: true });\n\n progress?.report({ message: 'Downloading emulator...', increment: 0 });\n await downloadFile({ url, dest: tmpZip, progress, abortSignal, start: 0, range: 50 });\n\n progress?.report({ message: 'Extracting emulator...', increment: 0 });\n await extractZipWithProgress({ zipPath: tmpZip, dest: emulatorDir, progress, start: 50, range: 45, logger });\n\n const runSh = path.join(emulatorDir, 'images', 'run.sh');\n if (fs.existsSync(runSh)) {\n fs.chmodSync(runSh, 0o755);\n }\n progress?.report({ message: 'Finalizing installation...', increment: 5 });\n } finally {\n fs.rmSync(tmpDir, { recursive: true, force: true });\n }\n}\n\n/**\n * Heuristic: emulator is considered installed if `images/run.sh` is present.\n * On Windows-only emulator builds (when they exist) this may not apply.\n */\nexport function isEmulatorInstalled(config: ConfigProvider): boolean {\n return fs.existsSync(path.join(getEmulatorDir(config), 'images', 'run.sh'));\n}\n\nexport function removeEmulator(config: ConfigProvider): void {\n const emulatorDir = getEmulatorDir(config);\n if (fs.existsSync(emulatorDir)) {\n fs.rmSync(emulatorDir, { recursive: true, force: true });\n }\n}\n","import * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { exec, spawn } from 'node:child_process';\nimport type { ConfigProvider } from '../ports/config.js';\nimport type { Logger } from '../ports/logger.js';\nimport { noopLogger } from '../ports/logger.js';\nimport { CancelledError, OniroError } from '../ports/errors.js';\nimport { getEmulatorDir, getHdcPath } from '../sdk/paths.js';\n\nconst PID_FILE = path.join(os.tmpdir(), 'oniro_emulator.pid');\n\nfunction execPromise(cmd: string, cwd: string | undefined, logger: Logger): Promise<void> {\n return new Promise((resolve, reject) => {\n exec(cmd, { cwd }, (error, stdout, stderr) => {\n if (stdout?.trim()) logger.info(`[emulator] ${stdout.trim()}`);\n if (stderr?.trim()) logger.warn(`[emulator] ${stderr.trim()}`);\n if (error) {\n logger.error(`[emulator] ${error.message}`);\n reject(error);\n } else {\n resolve();\n }\n });\n });\n}\n\n/**\n * Try to connect hdc to the emulator. Resolves true on success, false otherwise.\n */\nexport async function attemptHdcConnection(\n config: ConfigProvider,\n address = '127.0.0.1:55555',\n logger: Logger = noopLogger,\n): Promise<boolean> {\n const hdc = getHdcPath(config);\n try {\n await execPromise(`\"${hdc}\" start -r`, undefined, logger);\n await execPromise(`\"${hdc}\" tconn ${address}`, undefined, logger);\n return await new Promise<boolean>((resolve) => {\n exec(`\"${hdc}\" list targets`, (_error, stdout) => {\n resolve(stdout?.includes(address) ?? false);\n });\n });\n } catch (err) {\n logger.warn(`hdc connection attempt failed: ${(err as Error).message}`);\n return false;\n }\n}\n\ninterface LauncherSpec {\n /** Executable to spawn (e.g. `bash` on POSIX, `cmd.exe` on Windows). */\n command: string;\n /** Args, including the launcher script path. */\n args: readonly string[];\n /** Working directory (images dir). */\n cwd: string;\n}\n\n/**\n * Pick the right bundled launcher for the current OS. Prefers run.bat on Windows\n * and run.sh elsewhere; falls back to the other if only one is present.\n */\nfunction resolveLauncher(\n imagesPath: string,\n headless: boolean,\n connect: string | undefined,\n): LauncherSpec {\n const runSh = path.join(imagesPath, 'run.sh');\n const runBat = path.join(imagesPath, 'run.bat');\n const extra: string[] = [];\n if (headless) extra.push('--headless');\n if (connect) extra.push('--connect', connect);\n\n if (os.platform() === 'win32') {\n if (fs.existsSync(runBat)) {\n return { command: 'cmd.exe', args: ['/c', runBat, ...extra], cwd: imagesPath };\n }\n if (fs.existsSync(runSh)) {\n return { command: 'bash', args: [runSh, ...extra], cwd: imagesPath };\n }\n throw new OniroError(`No emulator launcher (run.bat or run.sh) found in ${imagesPath}.`);\n }\n\n if (fs.existsSync(runSh)) {\n return { command: 'bash', args: [runSh, ...extra], cwd: imagesPath };\n }\n if (fs.existsSync(runBat)) {\n return { command: 'bash', args: [runBat, ...extra], cwd: imagesPath };\n }\n throw new OniroError(`No emulator launcher (run.sh or run.bat) found in ${imagesPath}.`);\n}\n\nexport interface StartEmulatorOptions {\n config: ConfigProvider;\n logger?: Logger;\n /** Pass --headless to the bundled launcher (VNC + telnet serial, no local window). */\n headless?: boolean;\n /**\n * Override the launcher's host:port for hdc port forwarding. Defaults to the\n * launcher's own default (typically `127.0.0.1:55555`). Use `0.0.0.0:55555`\n * on hosts where QEMU refuses to bind the hostfwd to 127.0.0.1 (e.g. some\n * CI runners with restricted loopback bindings).\n */\n connect?: string;\n /**\n * Redirect launcher stdout/stderr to this file. Default: discard\n * (/dev/null on POSIX, NUL on Windows). Use a real path in CI so you can\n * surface qemu output on failure.\n */\n logFile?: string;\n /**\n * If > 0, block until hdc connects to the running emulator, up to this many\n * seconds. 0 (default) returns as soon as the launcher process is spawned.\n */\n waitForHdcSeconds?: number;\n /** Poll interval for the hdc wait, ms. Default 5000. */\n hdcPollIntervalMs?: number;\n abortSignal?: AbortSignal;\n}\n\n/**\n * Launch the Oniro emulator in the background via the bundled run.sh/run.bat.\n *\n * The launcher process is detached + unref'd so callers can exit while the\n * emulator keeps running. A PID file is written to the OS temp dir so\n * `stopEmulator` and rerun-detection logic can find the process later.\n */\nexport async function startEmulator(opts: StartEmulatorOptions): Promise<void> {\n const { config } = opts;\n const logger = opts.logger ?? noopLogger;\n\n // Detect a still-running emulator from a previous run (POSIX only — Windows\n // PID semantics with process groups make this unreliable to check by hand).\n if (os.platform() !== 'win32' && fs.existsSync(PID_FILE)) {\n try {\n const pid = Number(fs.readFileSync(PID_FILE, 'utf8').trim());\n if (Number.isFinite(pid) && pid > 0) {\n try {\n process.kill(pid, 0);\n logger.info(`Emulator already running (PID ${pid}); not starting another.`);\n if (opts.waitForHdcSeconds && opts.waitForHdcSeconds > 0) {\n await waitForHdc(config, opts.waitForHdcSeconds, opts.hdcPollIntervalMs ?? 5000, logger, opts.abortSignal);\n }\n return;\n } catch {\n // Stale PID file — fall through and launch a fresh one.\n }\n }\n } catch (err) {\n logger.warn(`Could not read PID file: ${(err as Error).message}`);\n }\n }\n\n const imagesPath = path.join(getEmulatorDir(config), 'images');\n if (!fs.existsSync(imagesPath)) {\n throw new OniroError(`Emulator images directory not found at ${imagesPath}. Run \\`oniro-app emulator install\\` first.`);\n }\n const launcher = resolveLauncher(imagesPath, opts.headless === true, opts.connect);\n\n // Open the log target. Default to OS-level null sink so the child process\n // doesn't keep the parent's stdout/stderr file descriptors alive.\n const logPath = opts.logFile ?? (os.platform() === 'win32' ? 'NUL' : '/dev/null');\n const logFd = fs.openSync(logPath, 'a');\n\n let child;\n try {\n child = spawn(launcher.command, [...launcher.args], {\n cwd: launcher.cwd,\n detached: true,\n stdio: ['ignore', logFd, logFd],\n windowsHide: true,\n });\n } finally {\n fs.closeSync(logFd);\n }\n\n // Catch synchronous spawn failures (e.g. bash not found on PATH).\n if (!child.pid) {\n throw new OniroError(`Failed to spawn launcher (${launcher.command} ${launcher.args.join(' ')}).`);\n }\n\n // Record PID + detach. The launcher script `exec`s into qemu so this PID\n // remains valid for the whole emulator lifetime.\n fs.writeFileSync(PID_FILE, String(child.pid));\n child.unref();\n logger.info(`Emulator launched (PID ${child.pid}). Logs: ${logPath}`);\n\n // Watch for an immediate failure (e.g. KVM unavailable → run.sh exits ~instantly\n // with a friendly error). We hold a reference to the exit event but won't await\n // it if the child stays alive.\n const earlyExit = new Promise<number | null>((resolve) => {\n child.once('exit', (code) => resolve(code));\n child.once('error', () => resolve(-1));\n });\n const liveness = new Promise<'alive'>((resolve) => setTimeout(() => resolve('alive'), 2000));\n const outcome = await Promise.race([earlyExit, liveness]);\n if (outcome !== 'alive') {\n const tail = readTail(logPath, 4000);\n throw new OniroError(\n `Emulator launcher exited with code ${outcome} before reaching steady state. Tail of ${logPath}:\\n${tail}`,\n );\n }\n\n if (opts.waitForHdcSeconds && opts.waitForHdcSeconds > 0) {\n await waitForHdc(config, opts.waitForHdcSeconds, opts.hdcPollIntervalMs ?? 5000, logger, opts.abortSignal, logPath);\n }\n}\n\nasync function waitForHdc(\n config: ConfigProvider,\n timeoutSeconds: number,\n pollIntervalMs: number,\n logger: Logger,\n abortSignal?: AbortSignal,\n logPathForDiagnostics?: string,\n): Promise<void> {\n const deadline = Date.now() + timeoutSeconds * 1000;\n let attempt = 0;\n while (Date.now() < deadline) {\n if (abortSignal?.aborted) throw new CancelledError('hdc wait cancelled.');\n attempt++;\n if (await attemptHdcConnection(config, undefined, noopLogger)) {\n logger.info(`hdc connected on attempt ${attempt}.`);\n return;\n }\n // Every ~6 attempts, log a heartbeat with the latest emulator log tail so\n // a hung guest is debuggable from a single command's output stream.\n if (attempt % 6 === 0) {\n logger.info(`hdc not yet ready (attempt ${attempt}, ${Math.max(0, deadline - Date.now()) / 1000 | 0}s remaining).`);\n if (logPathForDiagnostics) {\n const tail = readTail(logPathForDiagnostics, 1200);\n if (tail.trim()) logger.debug(`emulator log tail:\\n${tail}`);\n }\n }\n await new Promise((r) => setTimeout(r, pollIntervalMs));\n }\n const tail = logPathForDiagnostics ? readTail(logPathForDiagnostics, 4000) : '';\n throw new OniroError(`hdc did not connect within ${timeoutSeconds}s.${tail ? `\\nTail of emulator log:\\n${tail}` : ''}`);\n}\n\nfunction readTail(filePath: string, bytes: number): string {\n try {\n const stat = fs.statSync(filePath);\n const start = Math.max(0, stat.size - bytes);\n const fd = fs.openSync(filePath, 'r');\n try {\n const buf = Buffer.alloc(stat.size - start);\n fs.readSync(fd, buf, 0, buf.length, start);\n return buf.toString('utf8');\n } finally {\n fs.closeSync(fd);\n }\n } catch {\n return '';\n }\n}\n\nexport async function stopEmulator(logger: Logger = noopLogger): Promise<void> {\n // Prefer killing the recorded PID; fall back to a broad kill for stragglers.\n if (fs.existsSync(PID_FILE)) {\n try {\n const pid = Number(fs.readFileSync(PID_FILE, 'utf8').trim());\n if (Number.isFinite(pid) && pid > 0) {\n try {\n process.kill(pid, 'SIGTERM');\n logger.info(`Sent SIGTERM to emulator PID ${pid}.`);\n } catch (err) {\n logger.warn(`Could not signal PID ${pid}: ${(err as Error).message}`);\n }\n }\n } catch (err) {\n logger.warn(`Could not read PID file: ${(err as Error).message}`);\n }\n }\n\n const killCmd = os.platform() === 'win32'\n ? 'taskkill /IM qemu-system-x86_64.exe /F'\n : 'pkill -f qemu-system-x86_64';\n try {\n await execPromise(killCmd, undefined, logger);\n } catch {\n // pkill / taskkill return non-zero when nothing matched — that's fine.\n }\n\n fs.rm(PID_FILE, { force: true }, (err) => {\n if (err) logger.warn(`Could not remove PID file: ${err.message}`);\n });\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport JSON5 from 'json5';\nimport { OniroError } from '../ports/errors.js';\n\nfunction readJson5<T>(filePath: string): T {\n const content = fs.readFileSync(filePath, 'utf-8');\n return JSON5.parse(content) as T;\n}\n\n/**\n * Read the project's bundle name from `AppScope/app.json5`.\n */\nexport function getBundleName(projectDir: string): string {\n const appJsonPath = path.join(projectDir, 'AppScope', 'app.json5');\n if (!fs.existsSync(appJsonPath)) {\n throw new OniroError(`Could not find app.json5 at ${appJsonPath}`);\n }\n const appJson = readJson5<{ app?: { bundleName?: string } }>(appJsonPath);\n if (!appJson.app?.bundleName) {\n throw new OniroError('bundleName not found in app.json5');\n }\n return appJson.app.bundleName;\n}\n\n/**\n * Read the main ability from `<module>/src/main/module.json5`. Defaults to `entry`\n * for the module folder name if not provided — projects with custom module names\n * should pass it explicitly.\n */\nexport function getMainAbility(projectDir: string, moduleName = 'entry'): string {\n const moduleJsonPath = path.join(projectDir, moduleName, 'src', 'main', 'module.json5');\n if (!fs.existsSync(moduleJsonPath)) {\n throw new OniroError(`Could not find module.json5 at ${moduleJsonPath}`);\n }\n const moduleJson = readJson5<{ module?: { mainElement?: string } }>(moduleJsonPath);\n if (!moduleJson.module?.mainElement) {\n throw new OniroError('mainElement not found in module.json5');\n }\n return moduleJson.module.mainElement;\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { exec, spawn } from 'node:child_process';\nimport type { ConfigProvider } from '../ports/config.js';\nimport { defaultPaths } from '../ports/config.js';\nimport type { Logger } from '../ports/logger.js';\nimport { noopLogger } from '../ports/logger.js';\nimport { OniroError } from '../ports/errors.js';\nimport { getHdcPath } from '../sdk/paths.js';\nimport { getBundleName, getMainAbility } from './project.js';\n\nfunction execPromise(cmd: string, logger: Logger): Promise<void> {\n return new Promise((resolve, reject) => {\n exec(cmd, (error, stdout, stderr) => {\n if (stdout?.trim()) logger.info(`[hdc] ${stdout.trim()}`);\n if (stderr?.trim()) logger.warn(`[hdc] ${stderr.trim()}`);\n if (error) {\n logger.error(`[hdc] ${error.message}`);\n reject(error);\n } else {\n resolve();\n }\n });\n });\n}\n\nexport interface InstallAppOptions {\n config: ConfigProvider;\n projectDir: string;\n /**\n * Explicit path (absolute, or relative to projectDir) to the signed `.hap`.\n * Falls back to the `hapPath` config key, then to the well-known default.\n */\n hapPath?: string;\n logger?: Logger;\n}\n\nexport async function installApp(opts: InstallAppOptions): Promise<void> {\n const logger = opts.logger ?? noopLogger;\n const relativeHapPath = opts.hapPath ?? opts.config.get('hapPath', defaultPaths.hapPath);\n const hapPath = path.isAbsolute(relativeHapPath) ? relativeHapPath : path.join(opts.projectDir, relativeHapPath);\n\n if (!fs.existsSync(hapPath)) {\n throw new OniroError(`HAP file not found at: ${hapPath}. Build and sign the app first.`);\n }\n\n const hdc = getHdcPath(opts.config);\n await execPromise(`\"${hdc}\" install \"${hapPath}\"`, logger);\n}\n\nexport interface LaunchAppOptions {\n config: ConfigProvider;\n projectDir: string;\n /** Override the module name if it isn't the default `entry`. */\n moduleName?: string;\n logger?: Logger;\n}\n\nexport async function launchApp(opts: LaunchAppOptions): Promise<void> {\n const logger = opts.logger ?? noopLogger;\n const bundleName = getBundleName(opts.projectDir);\n const mainAbility = getMainAbility(opts.projectDir, opts.moduleName);\n const hdc = getHdcPath(opts.config);\n await execPromise(`\"${hdc}\" shell aa start -a ${mainAbility} -b ${bundleName}`, logger);\n}\n\nexport interface RunningProcess {\n pid: string;\n name: string;\n}\n\n/**\n * List running processes via `hdc track-jpid`. Times out after `timeoutMs`.\n * When `targetProcessName` is set, resolves to that process's PID early; otherwise\n * resolves to the full list collected within the timeout window.\n */\nexport function listRunningProcesses(\n config: ConfigProvider,\n options: { targetProcessName?: string; timeoutMs?: number; logger?: Logger } = {},\n): Promise<RunningProcess[] | string> {\n const logger = options.logger ?? noopLogger;\n const timeoutMs = options.timeoutMs ?? 1000;\n const hdc = getHdcPath(config);\n\n return new Promise((resolve, reject) => {\n const proc = spawn(hdc, ['track-jpid']);\n const processes: RunningProcess[] = [];\n let resolved = false;\n\n proc.stdout.on('data', (data: Buffer) => {\n for (const line of data.toString().split('\\n').filter(Boolean)) {\n const match = line.match(/^(\\d+)\\s+(.+)$/);\n if (!match) continue;\n const pid = match[1]!;\n const name = match[2]!;\n processes.push({ pid, name });\n if (options.targetProcessName && name === options.targetProcessName && !resolved) {\n resolved = true;\n proc.kill();\n resolve(pid);\n return;\n }\n }\n });\n\n proc.stderr.on('data', (data: Buffer) => {\n logger.warn(`[hdc track-jpid] ${data.toString()}`);\n });\n\n proc.on('error', (err) => {\n if (!resolved) {\n resolved = true;\n reject(err);\n }\n });\n\n const timeout = setTimeout(() => {\n if (resolved) return;\n resolved = true;\n proc.kill();\n if (options.targetProcessName) {\n reject(new OniroError(`Could not find process for bundle: ${options.targetProcessName}`));\n } else {\n resolve(processes);\n }\n }, timeoutMs);\n\n proc.on('close', () => {\n clearTimeout(timeout);\n if (resolved) return;\n resolved = true;\n if (options.targetProcessName) {\n reject(new OniroError(`Could not find process for bundle: ${options.targetProcessName}`));\n } else {\n resolve(processes);\n }\n });\n });\n}\n\nexport async function findAppProcessId(config: ConfigProvider, projectDir: string, logger?: Logger): Promise<string> {\n const bundleName = getBundleName(projectDir);\n const result = await listRunningProcesses(config, { targetProcessName: bundleName, logger });\n return result as string;\n}\n","import { spawn, type ChildProcessWithoutNullStreams } from 'node:child_process';\nimport type { ConfigProvider } from '../ports/config.js';\nimport type { Logger } from '../ports/logger.js';\nimport { noopLogger } from '../ports/logger.js';\nimport { getHdcPath } from '../sdk/paths.js';\n\nexport type HilogLevel = 'DEBUG' | 'INFO' | 'WARN' | 'ERROR' | 'FATAL';\n\n/** A parsed line of `hdc shell hilog` output. */\nexport interface HilogEntry {\n /** \"MM-DD HH:MM:SS.mmm\". The device timestamp; no year. */\n time: string;\n pid: string;\n tid: string;\n /** Short level letter as printed by hilog: D, I, W, E (F is rare). */\n level: 'D' | 'I' | 'W' | 'E' | 'F';\n tag: string;\n message: string;\n}\n\nexport interface SetHilogLevelOptions {\n config: ConfigProvider;\n level: HilogLevel;\n logger?: Logger;\n}\n\n/**\n * Set the hilog buffer level on the connected device. Resolves when the\n * underlying `hdc shell hilog -b <LEVEL>` exits successfully; rejects with\n * the stderr text if the command fails.\n */\nexport function setHilogLevel(opts: SetHilogLevelOptions): Promise<void> {\n const logger = opts.logger ?? noopLogger;\n const hdc = getHdcPath(opts.config);\n return new Promise((resolve, reject) => {\n const child = spawn(hdc, ['shell', 'hilog', '-b', opts.level]);\n let stderr = '';\n child.stderr.on('data', (chunk: Buffer) => {\n stderr += chunk.toString();\n });\n child.once('error', (err) => {\n logger.error(`[hilog] failed to spawn hdc: ${err.message}`);\n reject(err);\n });\n child.once('close', (code) => {\n if (code === 0) {\n resolve();\n } else {\n const msg = stderr.trim() || `hdc shell hilog -b ${opts.level} exited with code ${code}`;\n logger.error(`[hilog] ${msg}`);\n reject(new Error(msg));\n }\n });\n });\n}\n\nexport interface StreamHilogOptions {\n config: ConfigProvider;\n /** Restrict the stream to a single process id (passed as `-P <pid>`). */\n processId?: string;\n}\n\n/**\n * Spawn `hdc shell hilog [-P <pid>]` and return the child process. The caller\n * owns the stdout/stderr streams (typically wired through `parseHilogLine`) and\n * is responsible for killing the process when streaming should stop.\n */\nexport function streamHilog(opts: StreamHilogOptions): ChildProcessWithoutNullStreams {\n const hdc = getHdcPath(opts.config);\n const args = ['shell', 'hilog'];\n if (opts.processId && opts.processId.trim() !== '') {\n args.push('-P', opts.processId.trim());\n }\n return spawn(hdc, args);\n}\n\n// `\\S+` is greedy on the tag so values like `C01406/OHOS::RS` aren't split at\n// the first internal colon — the regex backtracks to the last `:` followed by\n// whitespace, which is the actual tag/message separator hilog emits.\nconst HILOG_LINE_RE = /^(\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}\\.\\d{3})\\s+(\\d+)\\s+(\\d+)\\s+([DIWEF])\\s+(\\S+):\\s+(.*)$/;\n\n/**\n * Parse a single line of `hdc shell hilog` output into structured fields.\n * Returns null when the line doesn't match the expected hilog format (e.g.\n * banners, blank lines, or partial chunks).\n */\nexport function parseHilogLine(line: string): HilogEntry | null {\n const match = HILOG_LINE_RE.exec(line);\n if (!match) return null;\n return {\n time: match[1]!,\n pid: match[2]!,\n tid: match[3]!,\n level: match[4]! as HilogEntry['level'],\n tag: match[5]!.trim(),\n message: match[6]!,\n };\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { spawn } from 'node:child_process';\nimport type { ConfigProvider } from '../ports/config.js';\nimport type { Logger } from '../ports/logger.js';\nimport { noopLogger } from '../ports/logger.js';\nimport { CmdToolsNotInstalledError, OniroError } from '../ports/errors.js';\nimport { getHvigorwPath, getOhosBaseSdkHome, getCmdToolsPath } from '../sdk/paths.js';\n\nexport interface RunHvigorwOptions {\n config: ConfigProvider;\n projectDir: string;\n /** Forwarded as `-p product=<product>`. Default `default`. */\n product?: string;\n /** Forwarded as `-p module=<module>` when set. */\n module?: string;\n /** Forwarded as `-p buildMode=<mode>` when set. */\n buildMode?: string;\n /** hvigor task to run. Default `assembleHap`. */\n task?: string;\n /** Extra raw args appended after the standard ones. */\n extraArgs?: readonly string[];\n logger?: Logger;\n /**\n * Optional callback for each stdout/stderr chunk, lets callers stream output\n * to a terminal or webview without buffering. Lines also flow through `logger`.\n */\n onOutput?: (chunk: string, stream: 'stdout' | 'stderr') => void;\n}\n\nexport interface RunHvigorwResult {\n exitCode: number;\n}\n\n/**\n * Run the project's `hvigorw` wrapper. Replaces the extension's vscode-tasks indirection\n * and the bash CLI's chained `clean` + `assembleHap` calls with a single direct spawn.\n */\nexport function runHvigorw(opts: RunHvigorwOptions): Promise<RunHvigorwResult> {\n const { config, projectDir } = opts;\n const logger = opts.logger ?? noopLogger;\n\n if (!fs.existsSync(path.join(projectDir, 'build-profile.json5'))) {\n throw new OniroError(`Not an OpenHarmony project: ${projectDir} (build-profile.json5 not found).`);\n }\n if (!fs.existsSync(getCmdToolsPath(config))) {\n throw new CmdToolsNotInstalledError(getCmdToolsPath(config));\n }\n\n const hvigorw = getHvigorwPath(config, projectDir);\n const args: string[] = [opts.task ?? 'assembleHap', '--mode', 'module'];\n args.push('-p', `product=${opts.product ?? 'default'}`);\n if (opts.module) args.push('-p', `module=${opts.module}`);\n if (opts.buildMode) args.push('-p', `buildMode=${opts.buildMode}`);\n args.push('--stacktrace', '--no-parallel', '--no-daemon');\n if (opts.extraArgs?.length) args.push(...opts.extraArgs);\n\n // Ensure hvigorw is executable on POSIX (project-local copies often aren't after a fresh clone).\n if (process.platform !== 'win32') {\n try { fs.chmodSync(hvigorw, 0o755); } catch { /* best effort */ }\n }\n\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n OHOS_BASE_SDK_HOME: getOhosBaseSdkHome(config),\n };\n\n return new Promise((resolve, reject) => {\n logger.info(`[build] ${hvigorw} ${args.join(' ')}`);\n const child = spawn(hvigorw, args, { cwd: projectDir, env, shell: false });\n child.stdout.on('data', (chunk: Buffer) => {\n const text = chunk.toString();\n opts.onOutput?.(text, 'stdout');\n logger.info(text.trimEnd());\n });\n child.stderr.on('data', (chunk: Buffer) => {\n const text = chunk.toString();\n opts.onOutput?.(text, 'stderr');\n logger.warn(text.trimEnd());\n });\n child.on('error', (err) => reject(new OniroError(`Failed to start hvigorw: ${err.message}`, err)));\n child.on('close', (code) => {\n const exitCode = code ?? 1;\n if (exitCode === 0) resolve({ exitCode });\n else reject(new OniroError(`hvigorw exited with code ${exitCode}`));\n });\n });\n}\n","/**\n * Conservative project-folder-name validator (no path separators, conservative charset).\n */\nexport function isValidProjectName(name: string): boolean {\n if (!name) return false;\n if (name.includes('/') || name.includes('\\\\')) return false;\n return /^[A-Za-z0-9._-]+$/.test(name);\n}\n\n/**\n * Bundle-name validator. Allows reverse-DNS style identifiers like `com.example.myapp`.\n */\nexport function isValidBundleName(bundleName: string): boolean {\n return /^[A-Za-z][A-Za-z0-9_]*(\\.[A-Za-z][A-Za-z0-9_]*)+$/.test(bundleName);\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nexport interface TemplateOption {\n id: string;\n label: string;\n description: string;\n defaultModuleName: string;\n}\n\ninterface TemplateMeta {\n id?: string;\n label?: string;\n description?: string;\n defaultModuleName?: string;\n}\n\nfunction toHumanTemplateName(folderName: string): string {\n return folderName.replace(/([a-z])([A-Z])/g, '$1 $2');\n}\n\n/**\n * Enumerate templates inside `templateRoot`. Each direct subfolder is a template;\n * per-template metadata (label/description/defaultModuleName) may live in a\n * `template.json` file alongside the template content.\n *\n * Callers own the template root — the CLI ships its own under\n * `<cli-package>/templates/`, the VS Code extension uses `extensionPath/template`.\n */\nexport function listTemplates(templateRoot: string): TemplateOption[] {\n if (!fs.existsSync(templateRoot)) return [];\n const entries = fs.readdirSync(templateRoot, { withFileTypes: true });\n return entries\n .filter((e) => e.isDirectory())\n .map((e) => {\n const dir = path.join(templateRoot, e.name);\n const metaPath = path.join(dir, 'template.json');\n let meta: TemplateMeta = {};\n if (fs.existsSync(metaPath)) {\n try {\n meta = JSON.parse(fs.readFileSync(metaPath, 'utf8')) as TemplateMeta;\n } catch {\n // Ignore malformed template metadata.\n }\n }\n return {\n id: e.name,\n label: meta.label ?? toHumanTemplateName(e.name),\n description: meta.description ?? '',\n defaultModuleName: (meta.defaultModuleName ?? 'entry').trim() || 'entry',\n };\n })\n .sort((a, b) => a.label.localeCompare(b.label));\n}\n\n/**\n * Verify that a template directory contains the files required by the scaffold pipeline.\n * Returns the list of missing relative paths, or [] if the template is complete.\n */\nexport function validateTemplateLayout(templateDir: string, defaultModuleName: string): string[] {\n const required = [\n 'build-profile.json5',\n path.join('AppScope', 'app.json5'),\n path.join(defaultModuleName, 'src', 'main', 'module.json5'),\n path.join(defaultModuleName, 'oh-package.json5'),\n 'hvigorfile.ts',\n ];\n return required.filter((rel) => !fs.existsSync(path.join(templateDir, rel)));\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { ConfigProvider } from '../ports/config.js';\nimport type { Logger } from '../ports/logger.js';\nimport { noopLogger } from '../ports/logger.js';\nimport { OniroError } from '../ports/errors.js';\nimport { getOhosBaseSdkHome } from '../sdk/paths.js';\nimport { listTemplates, validateTemplateLayout } from './templates.js';\nimport { isValidBundleName, isValidProjectName } from './validators.js';\nimport { readJson5File, readJsonFile, writeJson5File, writeJsonFile } from './jsonHelpers.js';\n\nconst IGNORED_DIRS = new Set(['oh_modules', 'node_modules', 'build', '.hvigor']);\n\nexport interface CreateScaffoldOptions {\n config: ConfigProvider;\n templateId: string;\n projectName: string;\n bundleName: string;\n /** Parent directory that will contain the new project folder. */\n location: string;\n sdkApi: number;\n /** Module folder name. Defaults to the template's `defaultModuleName`. */\n moduleName?: string;\n /** Absolute path to the directory containing template subfolders. */\n templateRoot: string;\n /** If the destination exists, remove it before scaffolding instead of throwing. */\n overwrite?: boolean;\n logger?: Logger;\n}\n\nexport interface CreateScaffoldResult {\n projectDir: string;\n}\n\n/**\n * Async existence check.\n */\nasync function pathExists(p: string): Promise<boolean> {\n try {\n await fs.promises.access(p);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Recursively copy a template directory, skipping symlinks and template metadata.\n */\nasync function copyDirRecursive(srcDir: string, destDir: string): Promise<void> {\n await fs.promises.mkdir(destDir, { recursive: true });\n const entries = await fs.promises.readdir(srcDir, { withFileTypes: true });\n for (const entry of entries) {\n const src = path.join(srcDir, entry.name);\n const dest = path.join(destDir, entry.name);\n if (entry.isDirectory()) {\n await copyDirRecursive(src, dest);\n } else if (entry.isSymbolicLink()) {\n continue;\n } else if (entry.isFile()) {\n if (entry.name === 'template.json') continue;\n await fs.promises.copyFile(src, dest);\n }\n }\n}\n\n/**\n * Normalize every .json5 file in `projectDir` to strict JSON formatting (quoted keys).\n * Keeps JSON5 parsers happy while letting VS Code's built-in JSON parser handle them.\n */\nasync function normalizeJson5ToJson(projectDir: string, logger: Logger): Promise<void> {\n const stack: string[] = [projectDir];\n while (stack.length > 0) {\n const currentDir = stack.pop()!;\n const entries = await fs.promises.readdir(currentDir, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = path.join(currentDir, entry.name);\n if (entry.isDirectory()) {\n if (IGNORED_DIRS.has(entry.name)) continue;\n stack.push(fullPath);\n continue;\n }\n if (!entry.isFile() || !entry.name.endsWith('.json5')) continue;\n try {\n const parsed = readJson5File<unknown>(fullPath);\n writeJson5File(fullPath, parsed);\n } catch (err) {\n logger.warn(`Failed to normalize ${fullPath}: ${String(err)}`);\n }\n }\n }\n}\n\nfunction toJavaPropertiesPath(p: string): string {\n return process.platform === 'win32' ? p.replace(/\\\\/g, '\\\\\\\\') : p;\n}\n\nfunction createOrUpdateLocalProperties(projectDir: string, sdkDir: string): void {\n const content = `sdk.dir=${toJavaPropertiesPath(sdkDir)}\\n`;\n fs.writeFileSync(path.join(projectDir, 'local.properties'), content, 'utf8');\n}\n\nfunction renameIfExists(fromPath: string, toPath: string): void {\n if (fs.existsSync(fromPath) && fromPath !== toPath) {\n fs.renameSync(fromPath, toPath);\n }\n}\n\n/**\n * Apply user-selected names/versions to template files. Mirrors the writes done by\n * the extension's `updateTemplateConfigs` so a scaffold is identical regardless of\n * which frontend produced it.\n */\nfunction updateTemplateConfigs(\n projectDir: string,\n args: {\n projectName: string;\n bundleName: string;\n sdkApi: number;\n moduleName: string;\n },\n sdkBaseDir: string,\n): void {\n // 1) AppScope/app.json5 -> bundleName\n const appJsonPath = path.join(projectDir, 'AppScope', 'app.json5');\n if (fs.existsSync(appJsonPath)) {\n const appJson = readJson5File<{ app?: { bundleName?: string } }>(appJsonPath);\n appJson.app = appJson.app ?? {};\n appJson.app.bundleName = args.bundleName;\n writeJson5File(appJsonPath, appJson);\n }\n\n // 2) AppScope/resources/base/element/string.json -> app_name = projectName\n const stringsPath = path.join(projectDir, 'AppScope', 'resources', 'base', 'element', 'string.json');\n if (fs.existsSync(stringsPath)) {\n const strings = readJsonFile<{ string?: Array<{ name?: string; value?: string }> }>(stringsPath);\n if (Array.isArray(strings.string)) {\n const appName = strings.string.find((s) => s.name === 'app_name');\n if (appName) appName.value = args.projectName;\n }\n writeJsonFile(stringsPath, strings);\n }\n\n // 3) build-profile.json5 -> sdk + module name + srcPath\n const buildProfilePath = path.join(projectDir, 'build-profile.json5');\n if (fs.existsSync(buildProfilePath)) {\n const buildProfile = readJson5File<{\n app?: { products?: Array<{ compileSdkVersion?: number; compatibleSdkVersion?: number }> };\n modules?: Array<{ name?: string; srcPath?: string }>;\n }>(buildProfilePath);\n buildProfile.app = buildProfile.app ?? {};\n if (Array.isArray(buildProfile.app.products) && buildProfile.app.products.length > 0) {\n buildProfile.app.products[0]!.compileSdkVersion = args.sdkApi;\n buildProfile.app.products[0]!.compatibleSdkVersion = args.sdkApi;\n }\n if (Array.isArray(buildProfile.modules) && buildProfile.modules.length > 0) {\n buildProfile.modules[0]!.name = args.moduleName;\n buildProfile.modules[0]!.srcPath = `./${args.moduleName}`;\n }\n writeJson5File(buildProfilePath, buildProfile);\n }\n\n // 4) <module>/src/main/module.json5 -> module.name\n const moduleJsonPath = path.join(projectDir, args.moduleName, 'src', 'main', 'module.json5');\n if (fs.existsSync(moduleJsonPath)) {\n const moduleJson = readJson5File<{ module?: { name?: string } }>(moduleJsonPath);\n moduleJson.module = moduleJson.module ?? {};\n moduleJson.module.name = args.moduleName;\n writeJson5File(moduleJsonPath, moduleJson);\n }\n\n // 5) <module>/oh-package.json5 -> name\n const moduleOhPackagePath = path.join(projectDir, args.moduleName, 'oh-package.json5');\n if (fs.existsSync(moduleOhPackagePath)) {\n const pkg = readJson5File<{ name?: string }>(moduleOhPackagePath);\n pkg.name = args.moduleName;\n writeJson5File(moduleOhPackagePath, pkg);\n }\n\n // 6) .vscode/settings.json — useful for users who do open the project in VS Code.\n const vscodeDir = path.join(projectDir, '.vscode');\n fs.mkdirSync(vscodeDir, { recursive: true });\n const hapPath = `${args.moduleName}/build/default/outputs/default/${args.moduleName}-default-signed.hap`;\n writeJsonFile(path.join(vscodeDir, 'settings.json'), {\n 'oniro.hapPath': hapPath,\n 'files.associations': { '*.json5': 'jsonc' },\n });\n\n // 7) local.properties — sdk.dir must point at the OS base SDK home (containing API folders),\n // NOT a specific API folder, otherwise hvigor double-nests the lookup.\n createOrUpdateLocalProperties(projectDir, sdkBaseDir);\n}\n\n/**\n * Scaffold a new Oniro/OpenHarmony project from a template. Returns the absolute path\n * to the created project directory.\n */\nexport async function createScaffold(opts: CreateScaffoldOptions): Promise<CreateScaffoldResult> {\n const logger = opts.logger ?? noopLogger;\n\n if (!isValidProjectName(opts.projectName)) {\n throw new OniroError(`Invalid project name '${opts.projectName}'. Use letters/numbers/._- and no slashes.`);\n }\n if (!isValidBundleName(opts.bundleName)) {\n throw new OniroError(`Invalid bundle name '${opts.bundleName}'. Example: com.example.myapplication`);\n }\n if (!opts.location || !(await pathExists(opts.location))) {\n throw new OniroError(`Location does not exist: ${opts.location}`);\n }\n\n const templateDir = path.join(opts.templateRoot, opts.templateId);\n if (!(await pathExists(templateDir))) {\n throw new OniroError(`Template not found: ${templateDir}`);\n }\n\n const templates = listTemplates(opts.templateRoot);\n const selected = templates.find((t) => t.id === opts.templateId);\n const defaultModuleName = selected?.defaultModuleName ?? 'entry';\n const moduleName = (opts.moduleName ?? defaultModuleName).trim() || defaultModuleName;\n\n const missing = validateTemplateLayout(templateDir, defaultModuleName);\n if (missing.length > 0) {\n throw new OniroError(`Template '${opts.templateId}' is missing required files:\\n- ${missing.join('\\n- ')}`);\n }\n\n const projectDir = path.join(opts.location, opts.projectName);\n if (await pathExists(projectDir)) {\n if (!opts.overwrite) {\n throw new OniroError(`Destination already exists: ${projectDir}. Pass overwrite: true to replace it.`);\n }\n await fs.promises.rm(projectDir, { recursive: true, force: true });\n }\n\n logger.info(`[create] Scaffolding ${opts.templateId} at ${projectDir}`);\n await copyDirRecursive(templateDir, projectDir);\n\n if (moduleName !== defaultModuleName) {\n renameIfExists(path.join(projectDir, defaultModuleName), path.join(projectDir, moduleName));\n }\n\n updateTemplateConfigs(\n projectDir,\n {\n projectName: opts.projectName,\n bundleName: opts.bundleName,\n sdkApi: opts.sdkApi,\n moduleName,\n },\n getOhosBaseSdkHome(opts.config),\n );\n\n await normalizeJson5ToJson(projectDir, logger);\n\n return { projectDir };\n}\n","import * as fs from 'node:fs';\nimport JSON5 from 'json5';\n\nexport function readJson5File<T>(filePath: string): T {\n return JSON5.parse(fs.readFileSync(filePath, 'utf8')) as T;\n}\n\n/**\n * Write strict JSON content (quoted keys) to a `.json5` file. Keeps the file\n * compatible with VS Code's JSON parser while remaining valid JSON5.\n */\nexport function writeJson5File(filePath: string, value: unknown): void {\n fs.writeFileSync(filePath, JSON.stringify(value, null, 2) + '\\n', 'utf8');\n}\n\nexport function readJsonFile<T>(filePath: string): T {\n return JSON.parse(fs.readFileSync(filePath, 'utf8')) as T;\n}\n\nexport function writeJsonFile(filePath: string, value: unknown): void {\n fs.writeFileSync(filePath, JSON.stringify(value, null, 2) + '\\n', 'utf8');\n}\n","declare const __PKG_VERSION__: string;\nexport const VERSION = __PKG_VERSION__;\n\nexport * from './ports/index.js';\nexport * from './sdk/index.js';\nexport * from './cmdTools/index.js';\nexport * from './sign/index.js';\nexport * from './emulator/index.js';\nexport * from './hdc/index.js';\nexport * from './build/index.js';\nexport * from './project/index.js';\n"],"mappings":"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","names":["platform","os","platform","os","path","fs","path","fs","resolve","fs","os","path","pipeline","promisify","pipelineAsync","promisify","pipeline","fs","path","fs","path","fs","os","path","n","fs","os","path","platform","fs","path","crypto","fs","path","execFileSync","JSON5","JSON5","execFileSync","fs","os","path","fs","os","path","resolve","tail","fs","path","JSON5","JSON5","fs","path","exec","spawn","execPromise","resolve","exec","spawn","spawn","resolve","spawn","fs","path","spawn","resolve","spawn","fs","path","fs","path","fs","JSON5"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@oniroproject/core",
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"description": "Shared library for Oniro/OpenHarmony app development tooling: SDK install, build, sign, emulator, hdc, project scaffolding.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/eclipse-oniro4openharmony/oniro-app-builder.git",
|
|
9
|
+
"directory": "packages/core"
|
|
10
|
+
},
|
|
11
|
+
"type": "module",
|
|
12
|
+
"main": "./dist/index.cjs",
|
|
13
|
+
"module": "./dist/index.js",
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"import": "./dist/index.js",
|
|
19
|
+
"require": "./dist/index.cjs"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsup",
|
|
27
|
+
"test": "vitest run --passWithNoTests",
|
|
28
|
+
"typecheck": "tsc --noEmit",
|
|
29
|
+
"clean": "rm -rf dist"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"follow-redirects": "^1.15.9",
|
|
33
|
+
"json5": "^2.2.3",
|
|
34
|
+
"node-stream-zip": "^1.15.0",
|
|
35
|
+
"tar": "^7.4.3"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/follow-redirects": "^1.14.4"
|
|
39
|
+
},
|
|
40
|
+
"engines": {
|
|
41
|
+
"node": ">=20"
|
|
42
|
+
}
|
|
43
|
+
}
|