@expo-harmony/cli 55.0.26-harmony.1 → 55.0.26-harmony.11
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/README.md +87 -38
- package/build/args.d.ts +19 -0
- package/build/args.js +27 -0
- package/build/bin/expo-harmony.d.ts +2 -0
- package/build/bin/expo-harmony.js +1 -1
- package/build/buildHap/build.d.ts +18 -0
- package/build/buildHap/build.js +38 -0
- package/build/buildHap/index.d.ts +2 -0
- package/build/buildHap/index.js +19 -0
- package/build/buildHap/options.d.ts +7 -0
- package/build/buildHap/options.js +30 -0
- package/build/cli.d.ts +3 -0
- package/build/cli.js +40 -0
- package/build/command.d.ts +9 -0
- package/build/command.js +20 -0
- package/build/development/manifest.d.ts +1 -0
- package/build/development/manifest.js +121 -0
- package/build/development/protocol.d.ts +3 -0
- package/build/development/protocol.js +33 -0
- package/build/development/session.d.ts +5 -0
- package/build/development/session.js +66 -0
- package/build/doctor/doctor.d.ts +20 -0
- package/build/doctor/doctor.js +226 -0
- package/build/doctor/index.d.ts +2 -0
- package/build/doctor/index.js +16 -0
- package/build/doctor/options.d.ts +5 -0
- package/build/doctor/options.js +15 -0
- package/build/entry.d.ts +2 -0
- package/build/entry.js +47 -0
- package/build/errors.d.ts +12 -0
- package/build/errors.js +16 -0
- package/build/expo.d.ts +19 -0
- package/build/expo.js +53 -0
- package/build/exportEmbed/export.d.ts +18 -0
- package/build/exportEmbed/export.js +124 -0
- package/build/exportEmbed/index.d.ts +2 -0
- package/build/exportEmbed/index.js +19 -0
- package/build/exportEmbed/manifest.d.ts +44 -0
- package/build/exportEmbed/manifest.js +171 -0
- package/build/exportEmbed/options.d.ts +7 -0
- package/build/exportEmbed/options.js +22 -0
- package/build/file.d.ts +10 -0
- package/build/file.js +110 -0
- package/build/help.d.ts +1 -0
- package/build/help.js +44 -0
- package/build/index.d.ts +14 -0
- package/build/index.js +6 -5
- package/build/internal/development.d.ts +1 -0
- package/build/internal/development.js +8 -0
- package/build/internal/export.d.ts +1 -0
- package/build/internal/export.js +80 -0
- package/build/internal/prebuild.d.ts +3 -0
- package/build/internal/prebuild.js +9 -0
- package/build/log.d.ts +4 -0
- package/build/log.js +6 -0
- package/build/modules/index.d.ts +2 -0
- package/build/modules/index.js +16 -0
- package/build/modules/modules.d.ts +42 -0
- package/build/modules/modules.js +84 -0
- package/build/modules/options.d.ts +10 -0
- package/build/modules/options.js +45 -0
- package/build/native/bare.d.ts +4 -0
- package/build/native/bare.js +130 -0
- package/build/native/build.d.ts +15 -0
- package/build/native/build.js +69 -0
- package/build/native/cache.d.ts +11 -0
- package/build/native/cache.js +73 -0
- package/build/native/hvigor.d.ts +3 -0
- package/build/native/hvigor.js +83 -0
- package/build/native/install.d.ts +5 -0
- package/build/native/install.js +13 -0
- package/build/native/prepareProject.d.ts +11 -0
- package/build/native/prepareProject.js +68 -0
- package/build/native/project.d.ts +8 -0
- package/build/native/project.js +58 -0
- package/build/native/toolchain.d.ts +16 -0
- package/build/native/toolchain.js +172 -0
- package/build/native/types.d.ts +47 -0
- package/build/native/types.js +2 -0
- package/build/path.d.ts +4 -0
- package/build/path.js +27 -0
- package/build/prebuild/check.d.ts +10 -0
- package/build/prebuild/check.js +151 -0
- package/build/prebuild/clean.d.ts +2 -0
- package/build/prebuild/clean.js +50 -0
- package/build/prebuild/index.d.ts +2 -0
- package/build/prebuild/index.js +51 -0
- package/build/prebuild/options.d.ts +10 -0
- package/build/prebuild/options.js +50 -0
- package/build/prebuild/prebuild.d.ts +6 -0
- package/build/prebuild/prebuild.js +70 -0
- package/build/prebuild/template.d.ts +8 -0
- package/build/prebuild/template.js +86 -0
- package/build/process.d.ts +41 -0
- package/build/process.js +324 -0
- package/build/profile.d.ts +1 -0
- package/build/profile.js +12 -0
- package/build/project.d.ts +2 -0
- package/build/project.js +23 -0
- package/build/projectLock.d.ts +2 -0
- package/build/projectLock.js +185 -0
- package/build/run/devices.d.ts +29 -0
- package/build/run/devices.js +223 -0
- package/build/run/emulators.d.ts +13 -0
- package/build/run/emulators.js +82 -0
- package/build/run/index.d.ts +2 -0
- package/build/run/index.js +25 -0
- package/build/run/metro.d.ts +21 -0
- package/build/run/metro.js +162 -0
- package/build/run/options.d.ts +14 -0
- package/build/run/options.js +62 -0
- package/build/run/run.d.ts +46 -0
- package/build/run/run.js +135 -0
- package/build/runtime/config.d.ts +37 -0
- package/build/runtime/config.js +169 -0
- package/build/runtime/contract.d.ts +5 -0
- package/build/runtime/contract.js +109 -0
- package/build/runtime/fingerprint.d.ts +1 -0
- package/build/runtime/fingerprint.js +49 -0
- package/build/runtime/index.d.ts +2 -0
- package/build/runtime/index.js +50 -0
- package/build/start/index.d.ts +2 -0
- package/build/start/index.js +38 -0
- package/build/start/options.d.ts +9 -0
- package/build/start/options.js +38 -0
- package/build/updates/export.d.ts +14 -0
- package/build/updates/export.js +46 -0
- package/build/updates/index.d.ts +2 -0
- package/build/updates/index.js +96 -0
- package/build/upstream.d.ts +9 -0
- package/build/upstream.js +17 -0
- package/package.json +21 -5
- package/src/bin/expo-harmony.ts +2 -2
- package/src/buildHap/build.ts +13 -105
- package/src/buildHap/index.ts +19 -0
- package/src/cli.ts +27 -225
- package/src/command.ts +24 -0
- package/src/development/manifest.ts +127 -0
- package/src/development/protocol.ts +42 -0
- package/src/development/session.ts +83 -0
- package/src/doctor/doctor.ts +67 -62
- package/src/doctor/index.ts +16 -0
- package/src/exportEmbed/export.ts +73 -72
- package/src/exportEmbed/index.ts +17 -0
- package/src/file.ts +20 -11
- package/src/help.ts +41 -0
- package/src/index.ts +5 -3
- package/src/internal/development.ts +8 -0
- package/src/internal/export.ts +82 -0
- package/src/internal/prebuild.ts +3 -0
- package/src/log.ts +5 -0
- package/src/modules/index.ts +16 -0
- package/src/native/bare.ts +145 -0
- package/src/native/build.ts +83 -0
- package/src/{run → native}/cache.ts +10 -9
- package/src/native/hvigor.ts +88 -0
- package/src/native/install.ts +17 -0
- package/src/native/prepareProject.ts +99 -0
- package/src/native/project.ts +88 -0
- package/src/{tools.ts → native/toolchain.ts} +38 -140
- package/src/native/types.ts +44 -0
- package/src/prebuild/check.ts +56 -31
- package/src/prebuild/clean.ts +3 -3
- package/src/prebuild/index.ts +56 -0
- package/src/prebuild/prebuild.ts +11 -1
- package/src/prebuild/template.ts +2 -2
- package/src/process.ts +175 -64
- package/src/profile.ts +13 -0
- package/src/projectLock.ts +9 -1
- package/src/run/devices.ts +24 -11
- package/src/run/emulators.ts +4 -6
- package/src/run/index.ts +25 -0
- package/src/run/metro.ts +10 -1
- package/src/run/options.ts +2 -0
- package/src/run/run.ts +63 -129
- package/src/runtime/config.ts +207 -0
- package/src/runtime/contract.ts +167 -0
- package/src/runtime/fingerprint.ts +49 -0
- package/src/runtime/index.ts +54 -0
- package/src/start/index.ts +37 -0
- package/src/start/options.ts +12 -0
- package/src/updates/export.ts +60 -0
- package/src/updates/index.ts +89 -0
- package/src/buildHap/common.ts +0 -145
- package/src/run/install.ts +0 -41
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.exportEmbedAsync = exportEmbedAsync;
|
|
7
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
+
const node_module_1 = require("node:module");
|
|
9
|
+
const node_os_1 = __importDefault(require("node:os"));
|
|
10
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
11
|
+
const export_1 = require("../updates/export");
|
|
12
|
+
const doctor_1 = require("../doctor/doctor");
|
|
13
|
+
const entry_1 = require("../entry");
|
|
14
|
+
const errors_1 = require("../errors");
|
|
15
|
+
const projectLock_1 = require("../projectLock");
|
|
16
|
+
const project_1 = require("../native/project");
|
|
17
|
+
const process_1 = require("../process");
|
|
18
|
+
const expo_1 = require("../expo");
|
|
19
|
+
const manifest_1 = require("./manifest");
|
|
20
|
+
async function exportEmbedUnlockedAsync(root, options = {}) {
|
|
21
|
+
if (!options.skipDoctor) {
|
|
22
|
+
const doctor = await (0, doctor_1.doctorAsync)(root);
|
|
23
|
+
if (!doctor.ok) {
|
|
24
|
+
const checks = doctor.checks.filter(check => check.status === 'error').map(check => check.id);
|
|
25
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_EXPORT_DOCTOR', `Harmony doctor found blocking checks: ${checks.join(', ') || 'unknown'}.`, { operation: 'doctor' });
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const plan = await (0, project_1.resolveHarmonyBuildPlanAsync)(root, { buildMode: 'release' });
|
|
29
|
+
const paths = options.outputDirectory
|
|
30
|
+
? {
|
|
31
|
+
rawfileRoot: node_path_1.default.join(options.outputDirectory, 'embedded'), bundle: node_path_1.default.join(options.outputDirectory, 'embedded/hermes_bundle.hbc'),
|
|
32
|
+
metadataRoot: options.outputDirectory, manifest: node_path_1.default.join(options.outputDirectory, 'export-manifest.json'),
|
|
33
|
+
sourceMap: node_path_1.default.join(options.outputDirectory, 'hermes_bundle.hbc.map'),
|
|
34
|
+
}
|
|
35
|
+
: (0, manifest_1.exportPaths)(plan);
|
|
36
|
+
if (options.check)
|
|
37
|
+
return await (0, manifest_1.validatePublishedExportAsync)(paths);
|
|
38
|
+
const entry = (0, entry_1.resolveHarmonyEntryPoint)(root);
|
|
39
|
+
const directory = await node_fs_1.default.promises.mkdtemp(node_path_1.default.join(node_os_1.default.tmpdir(), 'expo-harmony-export-'));
|
|
40
|
+
const temp = {
|
|
41
|
+
assets: node_path_1.default.join(directory, 'assets'),
|
|
42
|
+
metadata: node_path_1.default.join(directory, 'assets.json'),
|
|
43
|
+
bundle: node_path_1.default.join(directory, 'hermes_bundle.hbc'),
|
|
44
|
+
javascript: node_path_1.default.join(directory, 'index.js'),
|
|
45
|
+
metroSourceMap: node_path_1.default.join(directory, 'index.js.map'),
|
|
46
|
+
sourceMap: node_path_1.default.join(directory, 'hermes_bundle.hbc.map'),
|
|
47
|
+
};
|
|
48
|
+
try {
|
|
49
|
+
await node_fs_1.default.promises.mkdir(temp.assets, { recursive: true });
|
|
50
|
+
const result = await (0, process_1.spawnAsync)(process.execPath, [
|
|
51
|
+
node_path_1.default.resolve(__dirname, '../internal/export.js'), root,
|
|
52
|
+
JSON.stringify({ update: !!options.outputDirectory, platform: 'harmony', entryFile: entry, bundleOutput: temp.javascript, assetsDest: temp.assets,
|
|
53
|
+
dev: false, minify: false, sourcemapOutput: temp.metroSourceMap, sourcemapSourcesRoot: '.',
|
|
54
|
+
unstableTransformProfile: 'hermes-stable', resetCache: options.resetCache }), temp.metadata,
|
|
55
|
+
], {
|
|
56
|
+
capture: true,
|
|
57
|
+
cwd: root,
|
|
58
|
+
env: {
|
|
59
|
+
...process.env,
|
|
60
|
+
EXPO_METRO_TARGET: 'harmony',
|
|
61
|
+
HERMES_V1_ENABLED: 'true',
|
|
62
|
+
NODE_ENV: 'production',
|
|
63
|
+
},
|
|
64
|
+
operation: 'expo-export-embed',
|
|
65
|
+
outputLimit: 4 * 1024 * 1024,
|
|
66
|
+
timeoutMs: options.timeoutMs || 10 * 60_000,
|
|
67
|
+
});
|
|
68
|
+
if (result.code !== 0 || result.timedOut) {
|
|
69
|
+
const diagnostics = (0, process_1.formatDiagnostics)(result);
|
|
70
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_EXPORT_FAILED', `Expo export:embed exited with code ${result.code}${result.timedOut ? ' after timing out' : ''}.${diagnostics ? `\n${diagnostics}` : ''}`, { exitCode: result.code || 1, operation: 'expo-export-embed' });
|
|
71
|
+
}
|
|
72
|
+
// Expo 55 only infers Hermes for iOS and Android. Keep Harmony bundling in the Expo CLI,
|
|
73
|
+
// then explicitly hand its JS and source map to Expo's own Hermes exporter.
|
|
74
|
+
try {
|
|
75
|
+
const [code, map] = await Promise.all([
|
|
76
|
+
node_fs_1.default.promises.readFile(temp.javascript, 'utf8'),
|
|
77
|
+
node_fs_1.default.promises.readFile(temp.metroSourceMap, 'utf8'),
|
|
78
|
+
]);
|
|
79
|
+
const buildHermesBundleAsync = (0, expo_1.resolveExpoHermesBuilder)(root);
|
|
80
|
+
// Expo resolves hermes-compiler from react-native. For Harmony, resolve it
|
|
81
|
+
// from RNOH instead of the app's Android/iOS React Native installation.
|
|
82
|
+
const require = (0, node_module_1.createRequire)(node_path_1.default.join(root, 'package.json'));
|
|
83
|
+
const runtime = node_path_1.default.dirname(require.resolve('@react-native-oh/react-native-harmony/package.json'));
|
|
84
|
+
const modules = node_path_1.default.join(directory, 'node_modules');
|
|
85
|
+
await node_fs_1.default.promises.mkdir(modules);
|
|
86
|
+
await node_fs_1.default.promises.symlink(runtime, node_path_1.default.join(modules, 'react-native'), process.platform === 'win32' ? 'junction' : 'dir');
|
|
87
|
+
const output = await buildHermesBundleAsync({
|
|
88
|
+
code,
|
|
89
|
+
filename: entry,
|
|
90
|
+
map,
|
|
91
|
+
minify: true,
|
|
92
|
+
projectRoot: directory,
|
|
93
|
+
});
|
|
94
|
+
if (!(output?.hbc instanceof Uint8Array) || typeof output.sourcemap !== 'string') {
|
|
95
|
+
throw new Error('Expo did not return Hermes bytecode and a composed source map.');
|
|
96
|
+
}
|
|
97
|
+
await Promise.all([
|
|
98
|
+
node_fs_1.default.promises.writeFile(temp.bundle, output.hbc),
|
|
99
|
+
node_fs_1.default.promises.writeFile(temp.sourceMap, output.sourcemap),
|
|
100
|
+
]);
|
|
101
|
+
}
|
|
102
|
+
catch (cause) {
|
|
103
|
+
if (cause instanceof errors_1.HarmonyCliError) {
|
|
104
|
+
throw new errors_1.HarmonyCliError(cause.code, cause.message, {
|
|
105
|
+
cause,
|
|
106
|
+
exitCode: cause.exitCode,
|
|
107
|
+
operation: cause.operation,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_EXPORT_HERMES', 'Expo failed to compile the Harmony bundle to Hermes bytecode.', { cause, operation: 'expo-hermes-export' });
|
|
111
|
+
}
|
|
112
|
+
const bytecode = await (0, manifest_1.assertHermesBundle)(temp.bundle);
|
|
113
|
+
await (0, manifest_1.assertSourceMap)(temp.sourceMap);
|
|
114
|
+
const manifest = await (0, manifest_1.publishExportAsync)(root, paths, temp, entry, bytecode);
|
|
115
|
+
await (0, export_1.publishEmbeddedUpdateAsync)(root, paths, JSON.parse(await node_fs_1.default.promises.readFile(temp.metadata, 'utf8')));
|
|
116
|
+
return manifest;
|
|
117
|
+
}
|
|
118
|
+
finally {
|
|
119
|
+
await node_fs_1.default.promises.rm(directory, { force: true, recursive: true });
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
async function exportEmbedAsync(root, options = {}) {
|
|
123
|
+
return (0, projectLock_1.withHarmonyProjectLockAsync)(root, 'export:embed', () => exportEmbedUnlockedAsync(root, options));
|
|
124
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.command = void 0;
|
|
4
|
+
const command_1 = require("../command");
|
|
5
|
+
const options_1 = require("./options");
|
|
6
|
+
const command = async (argv, io) => {
|
|
7
|
+
const args = (0, command_1.parseCommandArgs)(options_1.parseExportEmbedArgs, argv, io);
|
|
8
|
+
if (!args)
|
|
9
|
+
return 0;
|
|
10
|
+
const { projectRoot: root, options } = args;
|
|
11
|
+
const { exportEmbedAsync } = await import('./export.js');
|
|
12
|
+
const result = await exportEmbedAsync(root, options);
|
|
13
|
+
if (options.check)
|
|
14
|
+
io.log('Harmony export bundle, assets, and source map are valid.');
|
|
15
|
+
else
|
|
16
|
+
io.log(`Exported Hermes bytecode ${result.bundle.path} with ${result.assets.length} asset file(s).`);
|
|
17
|
+
return 0;
|
|
18
|
+
};
|
|
19
|
+
exports.command = command;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { ExportTemporary } from './export';
|
|
2
|
+
export interface HarmonyExportFile {
|
|
3
|
+
path: string;
|
|
4
|
+
sha256: string;
|
|
5
|
+
size: number;
|
|
6
|
+
}
|
|
7
|
+
export interface HarmonyExportManifest {
|
|
8
|
+
assets: HarmonyExportFile[];
|
|
9
|
+
bundle: HarmonyExportFile & {
|
|
10
|
+
bytecodeVersion: number;
|
|
11
|
+
};
|
|
12
|
+
entryFile: string;
|
|
13
|
+
platform: 'harmony';
|
|
14
|
+
schemaVersion: 1;
|
|
15
|
+
sourceMap: HarmonyExportFile;
|
|
16
|
+
transformProfile: 'hermes-stable';
|
|
17
|
+
}
|
|
18
|
+
declare const HermesMagic: Buffer;
|
|
19
|
+
declare function exportPaths(plan: {
|
|
20
|
+
exportPaths: {
|
|
21
|
+
bundle: string;
|
|
22
|
+
manifest: string;
|
|
23
|
+
metadataRoot: string;
|
|
24
|
+
rawfileRoot: string;
|
|
25
|
+
sourceMap: string;
|
|
26
|
+
};
|
|
27
|
+
}): {
|
|
28
|
+
bundle: string;
|
|
29
|
+
manifest: string;
|
|
30
|
+
metadataRoot: string;
|
|
31
|
+
rawfileRoot: string;
|
|
32
|
+
sourceMap: string;
|
|
33
|
+
};
|
|
34
|
+
declare function assertHermesBundle(file: any): Promise<{
|
|
35
|
+
bytecodeVersion: number;
|
|
36
|
+
size: any;
|
|
37
|
+
}>;
|
|
38
|
+
declare function assertSourceMap(file: any): Promise<{
|
|
39
|
+
sha256: string;
|
|
40
|
+
size: number;
|
|
41
|
+
}>;
|
|
42
|
+
declare function publishExportAsync(projectRoot: string, paths: ReturnType<typeof exportPaths>, temporary: ExportTemporary, entryFile: string, bytecode: Awaited<ReturnType<typeof assertHermesBundle>>): Promise<HarmonyExportManifest>;
|
|
43
|
+
declare function validatePublishedExportAsync(paths: ReturnType<typeof exportPaths>): Promise<HarmonyExportManifest>;
|
|
44
|
+
export { HermesMagic, assertHermesBundle, assertSourceMap, exportPaths, publishExportAsync, validatePublishedExportAsync, };
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.HermesMagic = void 0;
|
|
7
|
+
exports.assertHermesBundle = assertHermesBundle;
|
|
8
|
+
exports.assertSourceMap = assertSourceMap;
|
|
9
|
+
exports.exportPaths = exportPaths;
|
|
10
|
+
exports.publishExportAsync = publishExportAsync;
|
|
11
|
+
exports.validatePublishedExportAsync = validatePublishedExportAsync;
|
|
12
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
13
|
+
const node_os_1 = __importDefault(require("node:os"));
|
|
14
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
15
|
+
const errors_1 = require("../errors");
|
|
16
|
+
const file_1 = require("../file");
|
|
17
|
+
const path_1 = require("../path");
|
|
18
|
+
const HermesMagic = Buffer.from('c61fbc03c103191f', 'hex');
|
|
19
|
+
exports.HermesMagic = HermesMagic;
|
|
20
|
+
const ManifestSchemaVersion = 1;
|
|
21
|
+
function exportPaths(plan) {
|
|
22
|
+
return plan.exportPaths;
|
|
23
|
+
}
|
|
24
|
+
async function assertHermesBundle(file) {
|
|
25
|
+
let handle;
|
|
26
|
+
try {
|
|
27
|
+
handle = await node_fs_1.default.promises.open(file, 'r');
|
|
28
|
+
const header = Buffer.alloc(12);
|
|
29
|
+
const { bytesRead } = await handle.read(header, 0, header.length, 0);
|
|
30
|
+
const stat = await handle.stat();
|
|
31
|
+
if (bytesRead < header.length || stat.size <= header.length
|
|
32
|
+
|| header.subarray(0, HermesMagic.length).toString('hex') !== HermesMagic.toString('hex')) {
|
|
33
|
+
throw new Error('Expo export did not produce non-empty Hermes bytecode.');
|
|
34
|
+
}
|
|
35
|
+
return { bytecodeVersion: header.readUInt32LE(8), size: stat.size };
|
|
36
|
+
}
|
|
37
|
+
catch (cause) {
|
|
38
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_EXPORT_INVALID_BUNDLE', 'The Harmony export output is not a valid Hermes bytecode bundle.', { cause, operation: 'validate-export' });
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
await handle?.close();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
async function assertSourceMap(file) {
|
|
45
|
+
try {
|
|
46
|
+
const contents = await node_fs_1.default.promises.readFile(file, 'utf8');
|
|
47
|
+
const sourceMap = JSON.parse(contents);
|
|
48
|
+
const paths = JSON.stringify({ sourceRoot: sourceMap?.sourceRoot, sources: sourceMap?.sources });
|
|
49
|
+
const sourcePaths = [sourceMap?.sourceRoot, ...(sourceMap?.sources || [])]
|
|
50
|
+
.filter(value => typeof value === 'string');
|
|
51
|
+
const hasAbsoluteSource = sourcePaths.some(value => (node_path_1.default.posix.isAbsolute(value) || node_path_1.default.win32.isAbsolute(value) || /^[A-Za-z][A-Za-z0-9+.-]*:\/\//u.test(value)));
|
|
52
|
+
if (sourceMap?.version !== 3 || !Array.isArray(sourceMap.sources)
|
|
53
|
+
|| hasAbsoluteSource || paths.includes(node_os_1.default.homedir())) {
|
|
54
|
+
throw new Error('Invalid or host-specific source map.');
|
|
55
|
+
}
|
|
56
|
+
return await (0, file_1.describeFile)(file);
|
|
57
|
+
}
|
|
58
|
+
catch (cause) {
|
|
59
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_EXPORT_INVALID_SOURCEMAP', 'Expo export did not produce a portable source map.', { cause, operation: 'validate-export' });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
async function readPreviousManifest(file) {
|
|
63
|
+
try {
|
|
64
|
+
const manifest = JSON.parse(await node_fs_1.default.promises.readFile(file, 'utf8'));
|
|
65
|
+
if (manifest?.schemaVersion !== ManifestSchemaVersion || !Array.isArray(manifest.assets)) {
|
|
66
|
+
throw new Error('Unsupported export manifest schema.');
|
|
67
|
+
}
|
|
68
|
+
for (const asset of manifest.assets) {
|
|
69
|
+
(0, path_1.assertSafeRelative)(asset?.path, 'Previous export manifest');
|
|
70
|
+
}
|
|
71
|
+
return manifest;
|
|
72
|
+
}
|
|
73
|
+
catch (cause) {
|
|
74
|
+
if (cause.code === 'ENOENT')
|
|
75
|
+
return null;
|
|
76
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_EXPORT_MANIFEST', 'Cannot read the previous Harmony export manifest.', { cause, operation: 'publish-export' });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
async function publishExportAsync(projectRoot, paths, temporary, entryFile, bytecode) {
|
|
80
|
+
const previous = await readPreviousManifest(paths.manifest);
|
|
81
|
+
const previouslyOwned = new Set((previous?.assets || []).map(asset => asset.path));
|
|
82
|
+
const assetFiles = await (0, file_1.listFiles)(temporary.assets);
|
|
83
|
+
const assetOutputs = [];
|
|
84
|
+
for (const source of assetFiles) {
|
|
85
|
+
const relative = (0, path_1.toPosixPath)(node_path_1.default.relative(temporary.assets, source));
|
|
86
|
+
const nativeRelative = (0, path_1.assertSafeRelative)(relative, 'Expo asset output');
|
|
87
|
+
const destination = node_path_1.default.join(paths.rawfileRoot, nativeRelative);
|
|
88
|
+
if (await node_fs_1.default.promises.lstat(destination).catch(error => error.code === 'ENOENT' ? null : Promise.reject(error))) {
|
|
89
|
+
if (!previouslyOwned.has(relative)) {
|
|
90
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_EXPORT_COLLISION', `Expo asset output collides with an unmanaged raw resource: ${relative}.`, { operation: 'publish-export' });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
assetOutputs.push({ descriptor: { path: relative, ...(await (0, file_1.describeFile)(source)) }, source });
|
|
94
|
+
}
|
|
95
|
+
assetOutputs.sort((left, right) => left.descriptor.path.localeCompare(right.descriptor.path, 'en'));
|
|
96
|
+
const assets = assetOutputs.map(output => output.descriptor);
|
|
97
|
+
const bundle = await (0, file_1.describeFile)(temporary.bundle);
|
|
98
|
+
const sourceMap = await (0, file_1.describeFile)(temporary.sourceMap);
|
|
99
|
+
const manifest = {
|
|
100
|
+
assets,
|
|
101
|
+
bundle: {
|
|
102
|
+
bytecodeVersion: bytecode.bytecodeVersion,
|
|
103
|
+
path: (0, path_1.toPosixPath)(node_path_1.default.relative(projectRoot, paths.bundle)),
|
|
104
|
+
...bundle,
|
|
105
|
+
},
|
|
106
|
+
entryFile: (0, path_1.toPosixPath)(node_path_1.default.relative(projectRoot, entryFile)),
|
|
107
|
+
platform: 'harmony',
|
|
108
|
+
schemaVersion: ManifestSchemaVersion,
|
|
109
|
+
sourceMap: {
|
|
110
|
+
path: (0, path_1.toPosixPath)(node_path_1.default.relative(projectRoot, paths.sourceMap)),
|
|
111
|
+
...sourceMap,
|
|
112
|
+
},
|
|
113
|
+
transformProfile: 'hermes-stable',
|
|
114
|
+
};
|
|
115
|
+
try {
|
|
116
|
+
await (0, file_1.atomicCopy)(temporary.bundle, paths.bundle, paths.rawfileRoot);
|
|
117
|
+
await (0, file_1.atomicCopy)(temporary.sourceMap, paths.sourceMap, paths.metadataRoot);
|
|
118
|
+
for (const output of assetOutputs) {
|
|
119
|
+
const relative = output.descriptor.path;
|
|
120
|
+
await (0, file_1.atomicCopy)(output.source, node_path_1.default.join(paths.rawfileRoot, (0, path_1.assertSafeRelative)(relative, 'Expo asset output')), paths.rawfileRoot);
|
|
121
|
+
}
|
|
122
|
+
await (0, file_1.atomicWriteJson)(manifest, paths.manifest, node_path_1.default.dirname(paths.manifest));
|
|
123
|
+
const nextOwned = new Set(assets.map(asset => asset.path));
|
|
124
|
+
for (const stale of previouslyOwned) {
|
|
125
|
+
if (nextOwned.has(stale))
|
|
126
|
+
continue;
|
|
127
|
+
const destination = node_path_1.default.join(paths.rawfileRoot, (0, path_1.assertSafeRelative)(stale, 'Previous export manifest'));
|
|
128
|
+
if (!(0, path_1.isInside)(paths.rawfileRoot, destination))
|
|
129
|
+
continue;
|
|
130
|
+
await node_fs_1.default.promises.rm(destination, { force: true });
|
|
131
|
+
await (0, file_1.removeEmptyParents)(destination, paths.rawfileRoot);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
catch (cause) {
|
|
135
|
+
if (cause instanceof errors_1.HarmonyCliError) {
|
|
136
|
+
throw new errors_1.HarmonyCliError(cause.code, cause.message, {
|
|
137
|
+
cause,
|
|
138
|
+
exitCode: cause.exitCode,
|
|
139
|
+
operation: cause.operation,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_EXPORT_PUBLISH', 'Cannot publish the validated Harmony bundle and assets.', { cause, operation: 'publish-export' });
|
|
143
|
+
}
|
|
144
|
+
return manifest;
|
|
145
|
+
}
|
|
146
|
+
async function validatePublishedExportAsync(paths) {
|
|
147
|
+
const manifest = await readPreviousManifest(paths.manifest);
|
|
148
|
+
if (!manifest) {
|
|
149
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_EXPORT_MANIFEST', 'Harmony export manifest does not exist. Run expo-harmony export:embed first.', { operation: 'check-export' });
|
|
150
|
+
}
|
|
151
|
+
const bytecode = await assertHermesBundle(paths.bundle);
|
|
152
|
+
const sourceMap = await assertSourceMap(paths.sourceMap);
|
|
153
|
+
const expectedBundle = await (0, file_1.describeFile)(paths.bundle);
|
|
154
|
+
if (manifest.bundle?.sha256 !== expectedBundle.sha256
|
|
155
|
+
|| manifest.bundle?.size !== expectedBundle.size
|
|
156
|
+
|| manifest.bundle?.bytecodeVersion !== bytecode.bytecodeVersion
|
|
157
|
+
|| manifest.sourceMap?.sha256 !== sourceMap.sha256
|
|
158
|
+
|| manifest.sourceMap?.size !== sourceMap.size) {
|
|
159
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_EXPORT_MANIFEST', 'Harmony bundle or source map differs from the export manifest.', { operation: 'check-export' });
|
|
160
|
+
}
|
|
161
|
+
for (const asset of manifest.assets) {
|
|
162
|
+
const file = node_path_1.default.join(paths.rawfileRoot, (0, path_1.assertSafeRelative)(asset.path, 'Export manifest'));
|
|
163
|
+
const actual = await (0, file_1.describeFile)(file).catch((cause) => {
|
|
164
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_EXPORT_MANIFEST', `Harmony export asset is missing or invalid: ${asset.path}.`, { cause, operation: 'check-export' });
|
|
165
|
+
});
|
|
166
|
+
if (actual.sha256 !== asset.sha256 || actual.size !== asset.size) {
|
|
167
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_EXPORT_MANIFEST', `Harmony export asset differs from the manifest: ${asset.path}.`, { operation: 'check-export' });
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return manifest;
|
|
171
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseExportEmbedArgs = parseExportEmbedArgs;
|
|
4
|
+
const errors_1 = require("../errors");
|
|
5
|
+
const args_1 = require("../args");
|
|
6
|
+
const ExportEmbedOptions = {
|
|
7
|
+
...args_1.CommonOptions,
|
|
8
|
+
'check': { type: 'boolean' },
|
|
9
|
+
'reset-cache': { type: 'boolean' },
|
|
10
|
+
};
|
|
11
|
+
function parseExportEmbedArgs(argv) {
|
|
12
|
+
const { positionals, values } = (0, args_1.parseArgs)(ExportEmbedOptions, argv);
|
|
13
|
+
if (positionals.length > 1) {
|
|
14
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_CONFIG_INVALID', `Unexpected export:embed positional argument: ${positionals[1]}`, { operation: 'parse-arguments' });
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
check: Boolean(values.check),
|
|
18
|
+
help: Boolean(values.help),
|
|
19
|
+
project: positionals[0],
|
|
20
|
+
resetCache: Boolean(values['reset-cache']),
|
|
21
|
+
};
|
|
22
|
+
}
|
package/build/file.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
declare function describeFile(file: string): Promise<{
|
|
2
|
+
sha256: string;
|
|
3
|
+
size: number;
|
|
4
|
+
}>;
|
|
5
|
+
declare function listFiles(root: string): Promise<string[]>;
|
|
6
|
+
declare function atomicCopy(source: string, destination: string, root: string): Promise<void>;
|
|
7
|
+
declare function atomicWriteJson(value: unknown, destination: string, root: string): Promise<void>;
|
|
8
|
+
declare function removeEmptyParents(file: string, stop: string): Promise<void>;
|
|
9
|
+
declare function isNonEmptyRegularFile(file: string): boolean;
|
|
10
|
+
export { atomicCopy, atomicWriteJson, describeFile, isNonEmptyRegularFile, listFiles, removeEmptyParents };
|
package/build/file.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.atomicCopy = atomicCopy;
|
|
7
|
+
exports.atomicWriteJson = atomicWriteJson;
|
|
8
|
+
exports.describeFile = describeFile;
|
|
9
|
+
exports.isNonEmptyRegularFile = isNonEmptyRegularFile;
|
|
10
|
+
exports.listFiles = listFiles;
|
|
11
|
+
exports.removeEmptyParents = removeEmptyParents;
|
|
12
|
+
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
13
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
14
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
15
|
+
const path_1 = require("./path");
|
|
16
|
+
async function sha256File(file) {
|
|
17
|
+
return await new Promise((resolve, reject) => {
|
|
18
|
+
const hash = node_crypto_1.default.createHash('sha256');
|
|
19
|
+
const input = node_fs_1.default.createReadStream(file);
|
|
20
|
+
input.on('error', reject);
|
|
21
|
+
input.on('data', (chunk) => {
|
|
22
|
+
const bytes = typeof chunk === 'string' ? new TextEncoder().encode(chunk) : Uint8Array.from(chunk);
|
|
23
|
+
hash.update(bytes);
|
|
24
|
+
});
|
|
25
|
+
input.on('end', () => resolve(hash.digest('hex')));
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
async function describeFile(file) {
|
|
29
|
+
const stat = await node_fs_1.default.promises.stat(file);
|
|
30
|
+
if (!stat.isFile())
|
|
31
|
+
throw new Error(`Expected a regular file: ${file}`);
|
|
32
|
+
return { sha256: await sha256File(file), size: stat.size };
|
|
33
|
+
}
|
|
34
|
+
async function listFiles(root) {
|
|
35
|
+
const files = [];
|
|
36
|
+
async function visit(directory) {
|
|
37
|
+
const entries = await node_fs_1.default.promises.readdir(directory, { withFileTypes: true });
|
|
38
|
+
entries.sort((left, right) => left.name.localeCompare(right.name, 'en'));
|
|
39
|
+
for (const entry of entries) {
|
|
40
|
+
const file = node_path_1.default.join(directory, entry.name);
|
|
41
|
+
if (entry.isSymbolicLink())
|
|
42
|
+
throw new Error(`Asset output contains a symbolic link: ${entry.name}`);
|
|
43
|
+
if (entry.isDirectory())
|
|
44
|
+
await visit(file);
|
|
45
|
+
else if (entry.isFile())
|
|
46
|
+
files.push(file);
|
|
47
|
+
else
|
|
48
|
+
throw new Error(`Asset output contains an unsupported file: ${entry.name}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
await visit(root);
|
|
52
|
+
return files;
|
|
53
|
+
}
|
|
54
|
+
async function ensureSafeParent(root, destination) {
|
|
55
|
+
if (!(0, path_1.isInside)(root, destination) || destination === root) {
|
|
56
|
+
throw new Error('Export destination escapes its owned root.');
|
|
57
|
+
}
|
|
58
|
+
await node_fs_1.default.promises.mkdir(root, { recursive: true });
|
|
59
|
+
await node_fs_1.default.promises.mkdir(node_path_1.default.dirname(destination), { recursive: true });
|
|
60
|
+
const [realRoot, realParent] = await Promise.all([
|
|
61
|
+
node_fs_1.default.promises.realpath(root),
|
|
62
|
+
node_fs_1.default.promises.realpath(node_path_1.default.dirname(destination)),
|
|
63
|
+
]);
|
|
64
|
+
if (!(0, path_1.isInside)(realRoot, realParent)) {
|
|
65
|
+
throw new Error('Export destination follows a link outside its owned root.');
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async function atomicCopy(source, destination, root) {
|
|
69
|
+
await ensureSafeParent(root, destination);
|
|
70
|
+
const temp = node_path_1.default.join(node_path_1.default.dirname(destination), `.${node_path_1.default.basename(destination)}.expo-${node_crypto_1.default.randomUUID()}.tmp`);
|
|
71
|
+
try {
|
|
72
|
+
await node_fs_1.default.promises.copyFile(source, temp, node_fs_1.default.constants.COPYFILE_EXCL);
|
|
73
|
+
await node_fs_1.default.promises.rename(temp, destination);
|
|
74
|
+
}
|
|
75
|
+
finally {
|
|
76
|
+
await node_fs_1.default.promises.rm(temp, { force: true });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
async function atomicWriteJson(value, destination, root) {
|
|
80
|
+
await ensureSafeParent(root, destination);
|
|
81
|
+
const temp = node_path_1.default.join(node_path_1.default.dirname(destination), `.${node_path_1.default.basename(destination)}.expo-${node_crypto_1.default.randomUUID()}.tmp`);
|
|
82
|
+
try {
|
|
83
|
+
await node_fs_1.default.promises.writeFile(temp, `${JSON.stringify(value, null, 2)}\n`, { flag: 'wx' });
|
|
84
|
+
await node_fs_1.default.promises.rename(temp, destination);
|
|
85
|
+
}
|
|
86
|
+
finally {
|
|
87
|
+
await node_fs_1.default.promises.rm(temp, { force: true });
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async function removeEmptyParents(file, stop) {
|
|
91
|
+
let directory = node_path_1.default.dirname(file);
|
|
92
|
+
while (directory !== stop && (0, path_1.isInside)(stop, directory)) {
|
|
93
|
+
try {
|
|
94
|
+
await node_fs_1.default.promises.rmdir(directory);
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
directory = node_path_1.default.dirname(directory);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function isNonEmptyRegularFile(file) {
|
|
103
|
+
try {
|
|
104
|
+
const stat = node_fs_1.default.lstatSync(file);
|
|
105
|
+
return !stat.isSymbolicLink() && stat.isFile() && stat.size > 0;
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
}
|
package/build/help.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const Help = "Usage: expo-harmony <command> [project] [options]\n\nCommands:\n start Start Expo Metro for Harmony development\n runtime Describe project requirements; --client file checks compatibility\n runtime --publish Embed capabilities from prepared native build inputs\n prebuild Generate the Harmony native project with Expo CNG\n prebuild --clean Safely recreate the managed Harmony directory\n prebuild --check Compare generated desired state without project writes\n build Build a HAP without selecting or contacting a device\n doctor Validate config, versions, Metro, RNOH, SDK, and signing\n modules list List native module candidates and their discovery source\n modules inspect Resolve Harmony metadata (--package narrows the result)\n modules verify Validate module config, registration conflicts and safe paths\n export Export an OTA update, assets, metadata, and source map\n export:embed Export validated Hermes bytecode, assets, and a source map\n run Build, install, and launch the Harmony app\n\nOptions:\n --no-install Skip dependency install (prebuild) or HAP install (run)\n --npm|--yarn|--pnpm|--bun\n Select the package manager used by prebuild dependency install\n --skip-dependency-update <packages>\n Preserve comma-separated dependency versions\n --device <id-or-name> Select an HDC target or start a local emulator by name\n --variant <mode> Build debug or release (default: debug)\n --no-bundler Use an already-running Expo Metro server\n --app-id <bundleName>\n Launch another installed app (requires --no-install when different)\n --host <hostname> Advertised HTTP LAN hostname (start)\n --private-key-path <path>\n Sign development manifests using the configured Updates certificate\n --port <number> Metro and device reverse port (default: 8081)\n --sync Re-run prebuild before building\n --output-dir <path> OTA export directory (default: dist)\n --asset-url <url> HTTP(S) root hosting exported OTA assets\n --check Validate an existing export without writing\n --reset-cache Reset Metro while exporting or starting\n -c, --clear Alias for --reset-cache (start)\n -h, --help Show this help\n";
|
package/build/help.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Help = void 0;
|
|
4
|
+
exports.Help = `Usage: expo-harmony <command> [project] [options]
|
|
5
|
+
|
|
6
|
+
Commands:
|
|
7
|
+
start Start Expo Metro for Harmony development
|
|
8
|
+
runtime Describe project requirements; --client file checks compatibility
|
|
9
|
+
runtime --publish Embed capabilities from prepared native build inputs
|
|
10
|
+
prebuild Generate the Harmony native project with Expo CNG
|
|
11
|
+
prebuild --clean Safely recreate the managed Harmony directory
|
|
12
|
+
prebuild --check Compare generated desired state without project writes
|
|
13
|
+
build Build a HAP without selecting or contacting a device
|
|
14
|
+
doctor Validate config, versions, Metro, RNOH, SDK, and signing
|
|
15
|
+
modules list List native module candidates and their discovery source
|
|
16
|
+
modules inspect Resolve Harmony metadata (--package narrows the result)
|
|
17
|
+
modules verify Validate module config, registration conflicts and safe paths
|
|
18
|
+
export Export an OTA update, assets, metadata, and source map
|
|
19
|
+
export:embed Export validated Hermes bytecode, assets, and a source map
|
|
20
|
+
run Build, install, and launch the Harmony app
|
|
21
|
+
|
|
22
|
+
Options:
|
|
23
|
+
--no-install Skip dependency install (prebuild) or HAP install (run)
|
|
24
|
+
--npm|--yarn|--pnpm|--bun
|
|
25
|
+
Select the package manager used by prebuild dependency install
|
|
26
|
+
--skip-dependency-update <packages>
|
|
27
|
+
Preserve comma-separated dependency versions
|
|
28
|
+
--device <id-or-name> Select an HDC target or start a local emulator by name
|
|
29
|
+
--variant <mode> Build debug or release (default: debug)
|
|
30
|
+
--no-bundler Use an already-running Expo Metro server
|
|
31
|
+
--app-id <bundleName>
|
|
32
|
+
Launch another installed app (requires --no-install when different)
|
|
33
|
+
--host <hostname> Advertised HTTP LAN hostname (start)
|
|
34
|
+
--private-key-path <path>
|
|
35
|
+
Sign development manifests using the configured Updates certificate
|
|
36
|
+
--port <number> Metro and device reverse port (default: 8081)
|
|
37
|
+
--sync Re-run prebuild before building
|
|
38
|
+
--output-dir <path> OTA export directory (default: dist)
|
|
39
|
+
--asset-url <url> HTTP(S) root hosting exported OTA assets
|
|
40
|
+
--check Validate an existing export without writing
|
|
41
|
+
--reset-cache Reset Metro while exporting or starting
|
|
42
|
+
-c, --clear Alias for --reset-cache (start)
|
|
43
|
+
-h, --help Show this help
|
|
44
|
+
`;
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { runAsync } from './cli';
|
|
2
|
+
export { buildHarmonyAsync } from './buildHap/build';
|
|
3
|
+
export type { HarmonyBuildOptions, HarmonyBuildResult } from './buildHap/build';
|
|
4
|
+
export { exportEmbedAsync } from './exportEmbed/export';
|
|
5
|
+
export { resolveHarmonyBuildPlanAsync } from './native/project';
|
|
6
|
+
export type { HarmonyBuildPlan, HarmonyBuildMode } from './native/types';
|
|
7
|
+
export { resolveHarmonyToolchain } from './native/toolchain';
|
|
8
|
+
export { installHarmonyDependenciesAsync } from './native/install';
|
|
9
|
+
export { formatModulesResult, runModulesCommandAsync } from './modules/modules';
|
|
10
|
+
export type { ModulesCommandResult } from './modules/modules';
|
|
11
|
+
export { commitHarmonyNativeBuildCacheAsync, prepareHarmonyNativeBuildCacheAsync } from './native/cache';
|
|
12
|
+
export { runHarmonyAsync } from './run/run';
|
|
13
|
+
export type { HarmonyExportManifest } from './exportEmbed/manifest';
|
|
14
|
+
export type { HarmonyRunOptions, HarmonyRunResult } from './run/run';
|
package/build/index.js
CHANGED
|
@@ -7,15 +7,16 @@ var build_1 = require("./buildHap/build");
|
|
|
7
7
|
Object.defineProperty(exports, "buildHarmonyAsync", { enumerable: true, get: function () { return build_1.buildHarmonyAsync; } });
|
|
8
8
|
var export_1 = require("./exportEmbed/export");
|
|
9
9
|
Object.defineProperty(exports, "exportEmbedAsync", { enumerable: true, get: function () { return export_1.exportEmbedAsync; } });
|
|
10
|
-
var
|
|
11
|
-
Object.defineProperty(exports, "resolveHarmonyBuildPlanAsync", { enumerable: true, get: function () { return
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
var project_1 = require("./native/project");
|
|
11
|
+
Object.defineProperty(exports, "resolveHarmonyBuildPlanAsync", { enumerable: true, get: function () { return project_1.resolveHarmonyBuildPlanAsync; } });
|
|
12
|
+
var toolchain_1 = require("./native/toolchain");
|
|
13
|
+
Object.defineProperty(exports, "resolveHarmonyToolchain", { enumerable: true, get: function () { return toolchain_1.resolveHarmonyToolchain; } });
|
|
14
|
+
var install_1 = require("./native/install");
|
|
14
15
|
Object.defineProperty(exports, "installHarmonyDependenciesAsync", { enumerable: true, get: function () { return install_1.installHarmonyDependenciesAsync; } });
|
|
15
16
|
var modules_1 = require("./modules/modules");
|
|
16
17
|
Object.defineProperty(exports, "formatModulesResult", { enumerable: true, get: function () { return modules_1.formatModulesResult; } });
|
|
17
18
|
Object.defineProperty(exports, "runModulesCommandAsync", { enumerable: true, get: function () { return modules_1.runModulesCommandAsync; } });
|
|
18
|
-
var cache_1 = require("./
|
|
19
|
+
var cache_1 = require("./native/cache");
|
|
19
20
|
Object.defineProperty(exports, "commitHarmonyNativeBuildCacheAsync", { enumerable: true, get: function () { return cache_1.commitHarmonyNativeBuildCacheAsync; } });
|
|
20
21
|
Object.defineProperty(exports, "prepareHarmonyNativeBuildCacheAsync", { enumerable: true, get: function () { return cache_1.prepareHarmonyNativeBuildCacheAsync; } });
|
|
21
22
|
var run_1 = require("./run/run");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const node_module_1 = require("node:module");
|
|
4
|
+
const manifest_1 = require("../development/manifest");
|
|
5
|
+
(0, manifest_1.installHarmonyManifest)(process.cwd());
|
|
6
|
+
process.argv.splice(1, 1);
|
|
7
|
+
const run = (0, node_module_1.createRequire)(__filename);
|
|
8
|
+
run(process.argv[1]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|