@expo-harmony/cli 55.0.26-harmony.1 → 55.0.26-harmony.10
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 +100 -0
- package/build/development/protocol.d.ts +2 -0
- package/build/development/protocol.js +26 -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 +216 -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 +35 -0
- package/build/runtime/config.js +118 -0
- package/build/runtime/contract.d.ts +5 -0
- package/build/runtime/contract.js +108 -0
- package/build/runtime/fingerprint.d.ts +1 -0
- package/build/runtime/fingerprint.js +44 -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 +106 -0
- package/src/development/protocol.ts +37 -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 +16 -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 +150 -0
- package/src/runtime/contract.ts +165 -0
- package/src/runtime/fingerprint.ts +39 -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,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 {};
|
|
@@ -0,0 +1,80 @@
|
|
|
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
|
+
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
7
|
+
const promises_1 = __importDefault(require("node:fs/promises"));
|
|
8
|
+
const node_module_1 = require("node:module");
|
|
9
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
+
const errors_1 = require("../errors");
|
|
11
|
+
async function main() {
|
|
12
|
+
const [root, serialized, destination] = process.argv.slice(2);
|
|
13
|
+
const project = (0, node_module_1.createRequire)(node_path_1.default.join(root, 'package.json'));
|
|
14
|
+
const expo = (0, node_module_1.createRequire)(project.resolve('expo/package.json'));
|
|
15
|
+
const require = (0, node_module_1.createRequire)(expo.resolve('@expo/cli/package.json'));
|
|
16
|
+
if (require('./package.json').version !== '55.0.32') {
|
|
17
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_EXPORT_UPSTREAM', 'Harmony asset export requires Expo CLI 55.0.32.', { operation: 'export' });
|
|
18
|
+
}
|
|
19
|
+
const options = JSON.parse(serialized);
|
|
20
|
+
require('./build/src/utils/nodeEnv').setNodeEnv('production');
|
|
21
|
+
require('./build/src/utils/nodeEnv').loadEnvFiles(root);
|
|
22
|
+
if (options.update) {
|
|
23
|
+
const directory = node_path_1.default.join(node_path_1.default.dirname(destination), 'export');
|
|
24
|
+
await require('./build/src/export/exportApp').exportAppAsync(root, {
|
|
25
|
+
platforms: ['harmony'], outputDir: directory, clear: options.resetCache,
|
|
26
|
+
dev: false, sourceMaps: true, minify: false, bytecode: false,
|
|
27
|
+
});
|
|
28
|
+
const metadata = JSON.parse(await promises_1.default.readFile(node_path_1.default.join(directory, 'metadata.json'), 'utf8')).fileMetadata.harmony;
|
|
29
|
+
const mime = require('mime-types');
|
|
30
|
+
const assets = [];
|
|
31
|
+
for (const asset of metadata.assets) {
|
|
32
|
+
const source = node_path_1.default.join(directory, asset.path);
|
|
33
|
+
const data = await promises_1.default.readFile(source);
|
|
34
|
+
const key = node_path_1.default.basename(asset.path, node_path_1.default.extname(asset.path));
|
|
35
|
+
const relative = `assets/${key}.${asset.ext}`;
|
|
36
|
+
await promises_1.default.mkdir(node_path_1.default.join(options.assetsDest, 'assets'), { recursive: true });
|
|
37
|
+
await promises_1.default.copyFile(source, node_path_1.default.join(options.assetsDest, relative));
|
|
38
|
+
assets.push({ key, hash: node_crypto_1.default.createHash('sha256').update(Uint8Array.from(data)).digest('base64url'),
|
|
39
|
+
contentType: mime.lookup(asset.ext) || 'application/octet-stream', fileExtension: '.' + asset.ext,
|
|
40
|
+
embeddedAssetFilename: relative });
|
|
41
|
+
}
|
|
42
|
+
await require('@expo/metro/metro/shared/output/bundle').save({
|
|
43
|
+
code: await promises_1.default.readFile(node_path_1.default.join(directory, metadata.bundle), 'utf8'),
|
|
44
|
+
map: await promises_1.default.readFile(node_path_1.default.join(directory, metadata.bundle + '.map'), 'utf8'),
|
|
45
|
+
}, options, console.log);
|
|
46
|
+
await promises_1.default.writeFile(destination, JSON.stringify(assets));
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const { bundle, assets, files } = await require('./build/src/export/embed/exportEmbedAsync').exportEmbedBundleAndAssetsAsync(root, options);
|
|
50
|
+
const { getAssetLocalPath } = require('./build/src/export/metroAssetLocalPath');
|
|
51
|
+
const mime = require('mime-types');
|
|
52
|
+
const metadata = [];
|
|
53
|
+
for (const asset of assets) {
|
|
54
|
+
if (!Array.isArray(asset.fileHashes) || asset.fileHashes.length !== asset.files.length) {
|
|
55
|
+
throw new errors_1.HarmonyCliError('ERR_HARMONY_EXPORT_ASSETS', 'Metro assets must include expo-asset fileHashes.', { operation: 'export' });
|
|
56
|
+
}
|
|
57
|
+
for (let index = 0; index < asset.files.length; index++) {
|
|
58
|
+
const data = await promises_1.default.readFile(asset.files[index]);
|
|
59
|
+
metadata.push({ key: asset.fileHashes[index], hash: node_crypto_1.default.createHash('sha256').update(Uint8Array.from(data)).digest('base64url'),
|
|
60
|
+
contentType: mime.lookup(asset.type) || 'application/octet-stream', fileExtension: '.' + asset.type,
|
|
61
|
+
embeddedAssetFilename: getAssetLocalPath(asset, { platform: 'harmony', scale: asset.scales[index] }) });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
await promises_1.default.mkdir(node_path_1.default.dirname(options.bundleOutput), { recursive: true });
|
|
65
|
+
await Promise.all([
|
|
66
|
+
require('@expo/metro/metro/shared/output/bundle').save(bundle, options, console.log),
|
|
67
|
+
require('./build/src/export/persistMetroAssets').persistMetroAssetsAsync(root, assets, { platform: 'harmony', outputDirectory: options.assetsDest }),
|
|
68
|
+
]);
|
|
69
|
+
if (files.size > 0) {
|
|
70
|
+
const { copyPublicFolderAsync, getPublicFolderPath } = require('./build/src/export/publicFolder');
|
|
71
|
+
const { DOM_COMPONENTS_BUNDLE_DIR } = require('./build/src/start/server/middleware/DomComponentsMiddleware');
|
|
72
|
+
await require('./build/src/export/saveAssets').persistMetroFilesAsync(files, options.assetsDest);
|
|
73
|
+
await copyPublicFolderAsync(getPublicFolderPath(root), node_path_1.default.join(options.assetsDest, DOM_COMPONENTS_BUNDLE_DIR));
|
|
74
|
+
}
|
|
75
|
+
await promises_1.default.writeFile(destination, JSON.stringify(metadata));
|
|
76
|
+
}
|
|
77
|
+
main().catch((error) => {
|
|
78
|
+
console.error(error);
|
|
79
|
+
process.exitCode = 1;
|
|
80
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.withHarmonyProjectLockAsync = exports.assertSafeCleanTarget = exports.withGeneratedProjectAsync = void 0;
|
|
4
|
+
var check_1 = require("../prebuild/check");
|
|
5
|
+
Object.defineProperty(exports, "withGeneratedProjectAsync", { enumerable: true, get: function () { return check_1.withGeneratedProjectAsync; } });
|
|
6
|
+
var clean_1 = require("../prebuild/clean");
|
|
7
|
+
Object.defineProperty(exports, "assertSafeCleanTarget", { enumerable: true, get: function () { return clean_1.assertSafeCleanTarget; } });
|
|
8
|
+
var projectLock_1 = require("../projectLock");
|
|
9
|
+
Object.defineProperty(exports, "withHarmonyProjectLockAsync", { enumerable: true, get: function () { return projectLock_1.withHarmonyProjectLockAsync; } });
|
package/build/log.d.ts
ADDED
package/build/log.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
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.parseModulesArgs, argv, io);
|
|
8
|
+
if (!args)
|
|
9
|
+
return 0;
|
|
10
|
+
const { projectRoot: root, options } = args;
|
|
11
|
+
const { formatModulesResult, runModulesCommandAsync } = await import('./modules.js');
|
|
12
|
+
const result = await runModulesCommandAsync(root, options);
|
|
13
|
+
io.log(formatModulesResult(result));
|
|
14
|
+
return result.ok ? 0 : 1;
|
|
15
|
+
};
|
|
16
|
+
exports.command = command;
|