@expo-harmony/expo-modules-autolinking 55.0.25-harmony.5 → 55.0.27-harmony.3
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/build/index.d.ts +3 -2
- package/build/index.js +4 -1
- package/build/runtime.d.ts +1 -1
- package/build/runtime.js +15 -26
- package/build/src/autolinking/link.d.ts +4 -2
- package/build/src/autolinking/link.js +34 -41
- package/build/src/autolinking/prepare.d.ts +15 -0
- package/build/src/autolinking/prepare.js +39 -0
- package/build/src/autolinking/verify.js +1 -0
- package/build/src/commands/link.js +5 -2
- package/build/src/harmony/configuredBuild.d.ts +2 -0
- package/build/src/harmony/configuredBuild.js +264 -0
- package/build/src/harmony/har.d.ts +6 -0
- package/build/src/harmony/har.js +160 -0
- package/build/src/harmony/manifest/index.js +1 -0
- package/build/src/harmony/materialize.d.ts +12 -2
- package/build/src/harmony/materialize.js +14 -8
- package/build/src/harmony/ohpm/dependencies.js +4 -1
- package/build/src/harmony/persistence/canonicalize.js +6 -0
- package/build/src/harmony/transaction/stageProject.js +3 -1
- package/build/src/metadata/schema.d.ts +0 -1
- package/build/src/metadata/schema.js +47 -18
- package/build/src/types.d.ts +8 -0
- package/harmony-module.schema.json +5 -0
- package/index.ts +4 -1
- package/package.json +7 -3
- package/runtime.ts +16 -28
- package/src/autolinking/link.ts +39 -51
- package/src/autolinking/prepare.ts +46 -0
- package/src/autolinking/verify.ts +1 -1
- package/src/commands/link.ts +6 -3
- package/src/harmony/configuredBuild.ts +289 -0
- package/src/harmony/har.ts +130 -0
- package/src/harmony/manifest/index.ts +1 -0
- package/src/harmony/materialize.ts +17 -7
- package/src/harmony/ohpm/dependencies.ts +4 -1
- package/src/harmony/persistence/canonicalize.ts +6 -0
- package/src/harmony/transaction/stageProject.ts +3 -1
- package/src/metadata/schema.ts +52 -16
- package/src/types.ts +4 -0
package/build/index.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { linkModulesAsync } from './src/autolinking/link';
|
|
1
|
+
import { linkModulesAsync, linkPreparedModulesAsync } from './src/autolinking/link';
|
|
2
|
+
import { prepareModulesAsync } from './src/autolinking/prepare';
|
|
2
3
|
import { canonicalizeAutolinkingArtifacts } from './src/harmony/persistence/canonicalize';
|
|
3
4
|
import { resolveModulesAsync } from './src/autolinking/resolve';
|
|
4
5
|
import { searchModulesAsync } from './src/autolinking/search';
|
|
5
6
|
import { verifyModulesAsync } from './src/autolinking/verify';
|
|
6
7
|
import { normalizeHarmonyModuleMetadata } from './src/metadata/schema';
|
|
7
|
-
export { canonicalizeAutolinkingArtifacts, linkModulesAsync, normalizeHarmonyModuleMetadata, resolveModulesAsync, searchModulesAsync, verifyModulesAsync, };
|
|
8
|
+
export { canonicalizeAutolinkingArtifacts, linkModulesAsync, linkPreparedModulesAsync, prepareModulesAsync, normalizeHarmonyModuleMetadata, resolveModulesAsync, searchModulesAsync, verifyModulesAsync, };
|
|
8
9
|
export type { BuildType, CanonicalizeAutolinkingArtifactsOptions, CanonicalizedAutolinkingArtifacts, Diagnostic, DiagnosticSource, ExpoMetadata, HostMetadata, HarmonyModuleMetadata, LinkOptions, LinkResult, Logger, Manifest, ModuleDescriptor, ModuleArtifactDescriptor, ModuleSource, Platform, ResolveOptions, RnohMetadata, SearchOptions, SearchRecord, SearchResult, VerificationResult, VerifyOptions, } from './src/types';
|
|
9
10
|
export { createNativeModuleContracts } from './src/harmony/manifest/runtime';
|
|
10
11
|
export { ohpmDependenciesFromManifest } from './src/harmony/manifest';
|
package/build/index.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ohpmDependenciesFromManifest = exports.createNativeModuleContracts = exports.verifyModulesAsync = exports.searchModulesAsync = exports.resolveModulesAsync = exports.normalizeHarmonyModuleMetadata = exports.linkModulesAsync = exports.canonicalizeAutolinkingArtifacts = void 0;
|
|
3
|
+
exports.ohpmDependenciesFromManifest = exports.createNativeModuleContracts = exports.verifyModulesAsync = exports.searchModulesAsync = exports.resolveModulesAsync = exports.normalizeHarmonyModuleMetadata = exports.prepareModulesAsync = exports.linkPreparedModulesAsync = exports.linkModulesAsync = exports.canonicalizeAutolinkingArtifacts = void 0;
|
|
4
4
|
const link_1 = require("./src/autolinking/link");
|
|
5
5
|
Object.defineProperty(exports, "linkModulesAsync", { enumerable: true, get: function () { return link_1.linkModulesAsync; } });
|
|
6
|
+
Object.defineProperty(exports, "linkPreparedModulesAsync", { enumerable: true, get: function () { return link_1.linkPreparedModulesAsync; } });
|
|
7
|
+
const prepare_1 = require("./src/autolinking/prepare");
|
|
8
|
+
Object.defineProperty(exports, "prepareModulesAsync", { enumerable: true, get: function () { return prepare_1.prepareModulesAsync; } });
|
|
6
9
|
const canonicalize_1 = require("./src/harmony/persistence/canonicalize");
|
|
7
10
|
Object.defineProperty(exports, "canonicalizeAutolinkingArtifacts", { enumerable: true, get: function () { return canonicalize_1.canonicalizeAutolinkingArtifacts; } });
|
|
8
11
|
const resolve_1 = require("./src/autolinking/resolve");
|
package/build/runtime.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export interface HarmonyRuntimeContract {
|
|
|
22
22
|
modules: HarmonyNativeModule[];
|
|
23
23
|
config: {
|
|
24
24
|
nativeCompiler: string;
|
|
25
|
-
targetApiVersion
|
|
25
|
+
targetApiVersion?: number | string;
|
|
26
26
|
compatibleApiVersion: number | string;
|
|
27
27
|
nativeLibFilterHash?: string;
|
|
28
28
|
permissions: string[];
|
package/build/runtime.js
CHANGED
|
@@ -19,31 +19,17 @@ exports.HarmonyCompatibilityError = HarmonyCompatibilityError;
|
|
|
19
19
|
function record(value) {
|
|
20
20
|
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
21
21
|
}
|
|
22
|
-
function
|
|
23
|
-
return typeof value === 'string' &&
|
|
24
|
-
&& !value.includes('://') && !value.includes('..') && !/^[A-Za-z]:/.test(value);
|
|
22
|
+
function nonEmptyString(value) {
|
|
23
|
+
return typeof value === 'string' && value.length > 0;
|
|
25
24
|
}
|
|
26
25
|
function strings(value) {
|
|
27
|
-
return Array.isArray(value) && value.every(
|
|
26
|
+
return Array.isArray(value) && value.every(nonEmptyString) && new Set(value).size === value.length;
|
|
28
27
|
}
|
|
29
28
|
const Versions = ['runtimeVersion', 'expo', 'expoModulesCore', 'rnoh', 'react', 'hermes'];
|
|
30
29
|
const Settings = ['permissions', 'querySchemes', 'backgroundModes', 'abiFilters'];
|
|
31
30
|
function apiVersion(value, schema) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if (schema === 2 && typeof value === 'string' && /^(?:[1-9]\d{1,2})\.(?:0|[1-9]\d{0,2})\.(?:0|[1-9]\d{0,2})$/.test(value)) {
|
|
35
|
-
const parts = value.split('.').map(Number);
|
|
36
|
-
if (parts[0] >= 26)
|
|
37
|
-
return parts;
|
|
38
|
-
}
|
|
39
|
-
return undefined;
|
|
40
|
-
}
|
|
41
|
-
function compareApiVersions(left, right) {
|
|
42
|
-
for (let index = 0; index < 3; index++) {
|
|
43
|
-
if (left[index] !== right[index])
|
|
44
|
-
return left[index] - right[index];
|
|
45
|
-
}
|
|
46
|
-
return 0;
|
|
31
|
+
return (typeof value === 'number' && Number.isSafeInteger(value) && value > 0)
|
|
32
|
+
|| (schema === 2 && typeof value === 'string' && /^\d+\.\d+\.\d+$/.test(value));
|
|
47
33
|
}
|
|
48
34
|
function harmonyRuntimeSchemaVersion(config) {
|
|
49
35
|
return typeof config.targetApiVersion === 'string' || typeof config.compatibleApiVersion === 'string'
|
|
@@ -67,7 +53,7 @@ function validateHarmonyRuntime(value) {
|
|
|
67
53
|
issues.push({ code: 'INVALID_CONTRACT', field: 'development', message: 'development must describe native development support.' });
|
|
68
54
|
}
|
|
69
55
|
for (const field of Versions) {
|
|
70
|
-
if (
|
|
56
|
+
if (!nonEmptyString(value[field])) {
|
|
71
57
|
issues.push({ code: 'INVALID_CONTRACT', field, message: `${field} must be an explicit version.` });
|
|
72
58
|
}
|
|
73
59
|
}
|
|
@@ -77,7 +63,7 @@ function validateHarmonyRuntime(value) {
|
|
|
77
63
|
else {
|
|
78
64
|
const names = new Set();
|
|
79
65
|
for (const module of value.modules) {
|
|
80
|
-
if (!record(module) || !
|
|
66
|
+
if (!record(module) || !nonEmptyString(module.packageName) || !nonEmptyString(module.packageVersion)
|
|
81
67
|
|| !strings(module.modules) || !strings(module.services) || !strings(module.registrations)
|
|
82
68
|
|| !strings(module.artifacts) || module.artifacts.some(hash => !/^[a-f0-9]{64}$/.test(hash))
|
|
83
69
|
|| names.has(module.packageName)) {
|
|
@@ -89,13 +75,13 @@ function validateHarmonyRuntime(value) {
|
|
|
89
75
|
}
|
|
90
76
|
}
|
|
91
77
|
const config = value.config;
|
|
92
|
-
const target = record(config)
|
|
78
|
+
const target = record(config)
|
|
79
|
+
&& (config.targetApiVersion === undefined || apiVersion(config.targetApiVersion, value.schemaVersion));
|
|
93
80
|
const compatible = record(config) ? apiVersion(config.compatibleApiVersion, value.schemaVersion) : undefined;
|
|
94
|
-
if (!record(config) || !
|
|
95
|
-
|| !target || !compatible
|
|
81
|
+
if (!record(config) || !nonEmptyString(config.nativeCompiler) || !Settings.every(field => strings(config[field]))
|
|
82
|
+
|| !target || !compatible
|
|
96
83
|
|| (config.nativeLibFilterHash !== undefined && (value.schemaVersion !== 2
|
|
97
|
-
|| typeof config.nativeLibFilterHash !== 'string' || !/^[a-f0-9]{64}$/.test(config.nativeLibFilterHash)))
|
|
98
|
-
|| (Array.isArray(config.abiFilters) && config.abiFilters.length === 0)) {
|
|
84
|
+
|| typeof config.nativeLibFilterHash !== 'string' || !/^[a-f0-9]{64}$/.test(config.nativeLibFilterHash)))) {
|
|
99
85
|
issues.push({ code: 'INVALID_CONTRACT', field: 'config', message: 'Invalid native build configuration.' });
|
|
100
86
|
}
|
|
101
87
|
return issues;
|
|
@@ -133,6 +119,9 @@ function checkHarmonyCompatibility(client, requirements) {
|
|
|
133
119
|
}
|
|
134
120
|
}
|
|
135
121
|
for (const field of ['nativeCompiler', 'targetApiVersion', 'compatibleApiVersion', 'nativeLibFilterHash']) {
|
|
122
|
+
// Hvigor chooses the target SDK when neither targetSdkVersion nor compileSdkVersion is explicit.
|
|
123
|
+
if (field === 'targetApiVersion' && (available.config[field] === undefined || required.config[field] === undefined))
|
|
124
|
+
continue;
|
|
136
125
|
if (available.config[field] !== required.config[field]) {
|
|
137
126
|
issues.push({ code: 'CONFIG_MISMATCH', field, message: `${field}: project requires ${required.config[field]}, client provides ${available.config[field]}.` });
|
|
138
127
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import type { LinkOptions, LinkResult } from '../types';
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
import { prepareModulesAsync } from './prepare';
|
|
3
|
+
declare function linkPreparedModulesAsync(raw: LinkOptions, prepared: Awaited<ReturnType<typeof prepareModulesAsync>>): Promise<LinkResult>;
|
|
4
|
+
declare function linkModulesAsync(raw: LinkOptions): Promise<LinkResult>;
|
|
5
|
+
export { linkModulesAsync, linkPreparedModulesAsync };
|
|
@@ -4,20 +4,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.linkModulesAsync = linkModulesAsync;
|
|
7
|
+
exports.linkPreparedModulesAsync = linkPreparedModulesAsync;
|
|
7
8
|
const node_path_1 = __importDefault(require("node:path"));
|
|
8
9
|
const constants_1 = require("../config/constants");
|
|
9
10
|
const host_1 = require("../harmony/providers/host");
|
|
10
11
|
const generate_1 = require("../harmony/manifest/generate");
|
|
11
12
|
const runtime_1 = require("../harmony/manifest/runtime");
|
|
12
13
|
const errors_1 = require("../errors");
|
|
13
|
-
const options_1 = require("../config/options");
|
|
14
14
|
const link_1 = require("../harmony/rnoh/link");
|
|
15
15
|
const stageProject_1 = require("../harmony/transaction/stageProject");
|
|
16
16
|
const publish_1 = require("../harmony/transaction/publish");
|
|
17
17
|
const previousState_1 = require("../harmony/transaction/previousState");
|
|
18
|
-
const verify_1 = require("./verify");
|
|
19
18
|
const values_1 = require("../utilities/values");
|
|
20
|
-
const
|
|
19
|
+
const prepare_1 = require("./prepare");
|
|
21
20
|
function buildPublishEntries(staging, hostProviderSource, manifest) {
|
|
22
21
|
return [
|
|
23
22
|
...Object.entries(constants_1.RnohArtifacts).map(([name, relative]) => ({
|
|
@@ -34,30 +33,9 @@ function buildPublishEntries(staging, hostProviderSource, manifest) {
|
|
|
34
33
|
},
|
|
35
34
|
];
|
|
36
35
|
}
|
|
37
|
-
async function
|
|
38
|
-
const options
|
|
39
|
-
|
|
40
|
-
throw new errors_1.HarmonyAutolinkingError('INVALID_OPTIONS', 'link requires harmonyProjectPath.', { stage: 'link' });
|
|
41
|
-
}
|
|
42
|
-
const verify = await (0, verify_1.verifyModulesAsync)((rawOptions.modules !== undefined
|
|
43
|
-
? { modules: rawOptions.modules }
|
|
44
|
-
: { ...options, searchResult: rawOptions.searchResult }));
|
|
45
|
-
(0, verify_1.assertVerificationSucceeded)(verify, 'link');
|
|
46
|
-
const modules = verify.modules;
|
|
47
|
-
const pendingSource = modules.filter(module => module.artifact.kind === 'local-source');
|
|
48
|
-
if (pendingSource.length > 0) {
|
|
49
|
-
if (pendingSource.some(module => module.source !== 'nativeModulesDir')) {
|
|
50
|
-
throw new errors_1.HarmonyAutolinkingError('SOURCE_ARTIFACT_MATERIALIZATION_REQUIRED', 'Only nativeModulesDir modules may build a local Harmony HAR.', { stage: 'link', details: pendingSource.map(module => module.packageName).sort() });
|
|
51
|
-
}
|
|
52
|
-
await (0, materialize_1.materializeLocalSourcesAsync)(pendingSource, {
|
|
53
|
-
dependencies: modules,
|
|
54
|
-
projectRoot: options.projectRoot,
|
|
55
|
-
timeoutMs: rawOptions.timeoutMs,
|
|
56
|
-
outputLimit: rawOptions.outputLimit,
|
|
57
|
-
env: rawOptions.env,
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
const hostProviderSource = (0, host_1.renderArkTsHostProviderSource)(modules);
|
|
36
|
+
async function linkPreparedModulesAsync(raw, prepared) {
|
|
37
|
+
const { options, modules, diagnostics } = prepared;
|
|
38
|
+
const provider = (0, host_1.renderArkTsHostProviderSource)(modules);
|
|
61
39
|
let staging;
|
|
62
40
|
let failure;
|
|
63
41
|
let cleanupWarning;
|
|
@@ -66,16 +44,16 @@ async function linkModulesAsync(rawOptions) {
|
|
|
66
44
|
const previous = await (0, previousState_1.readPreviousAutolinkingStateAsync)(options.projectRoot);
|
|
67
45
|
if (previous.warning) {
|
|
68
46
|
warnings.push(previous.warning);
|
|
69
|
-
(0, values_1.emitLog)(
|
|
47
|
+
(0, values_1.emitLog)(raw.logger, 'warn', previous.warning.message, previous.warning);
|
|
70
48
|
}
|
|
71
49
|
staging = await (0, stageProject_1.stageProjectAsync)({
|
|
72
50
|
projectRoot: options.projectRoot,
|
|
73
|
-
harmonyProjectPath:
|
|
74
|
-
nodeModulesPath:
|
|
51
|
+
harmonyProjectPath: raw.harmonyProjectPath,
|
|
52
|
+
nodeModulesPath: raw.nodeModulesPath,
|
|
75
53
|
modules,
|
|
76
54
|
buildType: options.buildType,
|
|
77
55
|
previousManagedOhpmPackageNames: previous.managedOhpmPackageNames,
|
|
78
|
-
rnohCliPackageJsonPath:
|
|
56
|
+
rnohCliPackageJsonPath: raw.rnohCliPackageJsonPath,
|
|
79
57
|
});
|
|
80
58
|
staging.rnohArtifacts = await (0, link_1.linkRnohAsync)({
|
|
81
59
|
...staging,
|
|
@@ -83,11 +61,11 @@ async function linkModulesAsync(rawOptions) {
|
|
|
83
61
|
buildType: options.buildType,
|
|
84
62
|
exclude: staging.rnohRuntimePackages,
|
|
85
63
|
commandNodeModulesPath: staging.sourceNodeModulesPath,
|
|
86
|
-
reactNativeExecutable:
|
|
87
|
-
rnohCliPackageJsonPath:
|
|
88
|
-
timeoutMs:
|
|
89
|
-
outputLimit:
|
|
90
|
-
env:
|
|
64
|
+
reactNativeExecutable: raw.reactNativeExecutable,
|
|
65
|
+
rnohCliPackageJsonPath: raw.rnohCliPackageJsonPath,
|
|
66
|
+
timeoutMs: raw.timeoutMs,
|
|
67
|
+
outputLimit: raw.outputLimit,
|
|
68
|
+
env: raw.env,
|
|
91
69
|
});
|
|
92
70
|
const harmonyRoot = node_path_1.default.relative(staging.projectRoot, staging.harmonyProjectPath)
|
|
93
71
|
.split(node_path_1.default.sep).join('/');
|
|
@@ -100,7 +78,19 @@ async function linkModulesAsync(rawOptions) {
|
|
|
100
78
|
const published = await (0, publish_1.publishArtifactsAsync)({
|
|
101
79
|
allowedRoot: staging.projectRoot,
|
|
102
80
|
lockPath: node_path_1.default.join(staging.projectRoot, '.expo/harmony/autolinking.lock'),
|
|
103
|
-
files:
|
|
81
|
+
files: [
|
|
82
|
+
...buildPublishEntries(staging, provider, manifest),
|
|
83
|
+
...(raw.moduleBuilds !== undefined
|
|
84
|
+
? [{
|
|
85
|
+
target: node_path_1.default.join(staging.projectRoot, '.expo/harmony/module-build-options.json'),
|
|
86
|
+
content: JSON.stringify({
|
|
87
|
+
schemaVersion: 1,
|
|
88
|
+
moduleBuilds: raw.moduleBuilds,
|
|
89
|
+
moduleBuildSettings: raw.moduleBuildSettings,
|
|
90
|
+
}, null, 2) + '\n',
|
|
91
|
+
}]
|
|
92
|
+
: []),
|
|
93
|
+
],
|
|
104
94
|
stale: previous.artifacts.filter(artifact => !managed.some((relative) => {
|
|
105
95
|
return artifact === node_path_1.default.join(staging.projectRoot, ...relative.split('/'));
|
|
106
96
|
})),
|
|
@@ -112,10 +102,10 @@ async function linkModulesAsync(rawOptions) {
|
|
|
112
102
|
managedArtifacts: [...managed],
|
|
113
103
|
changedArtifacts: published.changed.map(target => node_path_1.default.relative(staging.projectRoot, target).split(node_path_1.default.sep).join('/')),
|
|
114
104
|
unchangedArtifacts: published.unchanged.map(target => node_path_1.default.relative(staging.projectRoot, target).split(node_path_1.default.sep).join('/')),
|
|
115
|
-
diagnostics
|
|
105
|
+
diagnostics,
|
|
116
106
|
warnings,
|
|
117
107
|
};
|
|
118
|
-
(0, values_1.emitLog)(
|
|
108
|
+
(0, values_1.emitLog)(raw.logger, 'info', 'Harmony autolinking completed.', {
|
|
119
109
|
moduleCount: result.modules.length,
|
|
120
110
|
changedArtifactCount: result.changedArtifacts.length,
|
|
121
111
|
});
|
|
@@ -123,7 +113,7 @@ async function linkModulesAsync(rawOptions) {
|
|
|
123
113
|
}
|
|
124
114
|
catch (error) {
|
|
125
115
|
failure = error;
|
|
126
|
-
(0, values_1.emitLog)(
|
|
116
|
+
(0, values_1.emitLog)(raw.logger, 'error', 'Harmony autolinking failed.', {
|
|
127
117
|
code: error.code || 'ERR_EXPO_HARMONY_UNKNOWN',
|
|
128
118
|
stage: error.stage || 'link',
|
|
129
119
|
});
|
|
@@ -135,7 +125,7 @@ async function linkModulesAsync(rawOptions) {
|
|
|
135
125
|
const warning = { ...cleanup };
|
|
136
126
|
delete warning.cause;
|
|
137
127
|
warnings.push(warning);
|
|
138
|
-
(0, values_1.emitLog)(
|
|
128
|
+
(0, values_1.emitLog)(raw.logger, 'warn', warning.message, warning);
|
|
139
129
|
if (failure)
|
|
140
130
|
cleanupWarning = warning;
|
|
141
131
|
}
|
|
@@ -151,3 +141,6 @@ async function linkModulesAsync(rawOptions) {
|
|
|
151
141
|
: failure.details,
|
|
152
142
|
});
|
|
153
143
|
}
|
|
144
|
+
async function linkModulesAsync(raw) {
|
|
145
|
+
return linkPreparedModulesAsync(raw, await (0, prepare_1.prepareModulesAsync)(raw));
|
|
146
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { LinkOptions } from '../types';
|
|
2
|
+
export declare function prepareModulesAsync(raw: LinkOptions): Promise<{
|
|
3
|
+
options: {
|
|
4
|
+
projectRoot: string;
|
|
5
|
+
platform: string;
|
|
6
|
+
searchPaths: string[];
|
|
7
|
+
nativeModulesDir: string;
|
|
8
|
+
exclude: string[];
|
|
9
|
+
include: string[];
|
|
10
|
+
moduleOverrides: Readonly<{}>;
|
|
11
|
+
buildType: any;
|
|
12
|
+
};
|
|
13
|
+
diagnostics: readonly import("../types").Diagnostic[];
|
|
14
|
+
modules: readonly import("../types").ModuleDescriptor[];
|
|
15
|
+
}>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.prepareModulesAsync = prepareModulesAsync;
|
|
4
|
+
const errors_1 = require("../errors");
|
|
5
|
+
const options_1 = require("../config/options");
|
|
6
|
+
const materialize_1 = require("../harmony/materialize");
|
|
7
|
+
const configuredBuild_1 = require("../harmony/configuredBuild");
|
|
8
|
+
const verify_1 = require("./verify");
|
|
9
|
+
async function prepareModulesAsync(raw) {
|
|
10
|
+
const options = await (0, options_1.normalizeOptionsAsync)(raw);
|
|
11
|
+
if (typeof raw.harmonyProjectPath !== 'string' || !raw.harmonyProjectPath) {
|
|
12
|
+
throw new errors_1.HarmonyAutolinkingError('INVALID_OPTIONS', 'link requires harmonyProjectPath.', { stage: 'link' });
|
|
13
|
+
}
|
|
14
|
+
const verify = await (0, verify_1.verifyModulesAsync)((raw.modules !== undefined
|
|
15
|
+
? { modules: raw.modules }
|
|
16
|
+
: { ...options, searchResult: raw.searchResult }));
|
|
17
|
+
(0, verify_1.assertVerificationSucceeded)(verify, 'link');
|
|
18
|
+
const modules = verify.modules;
|
|
19
|
+
const pending = modules.filter(module => module.artifact.kind === 'local-source');
|
|
20
|
+
if (pending.length > 0) {
|
|
21
|
+
if (pending.some(module => module.source !== 'nativeModulesDir')) {
|
|
22
|
+
throw new errors_1.HarmonyAutolinkingError('SOURCE_ARTIFACT_MATERIALIZATION_REQUIRED', 'Only nativeModulesDir modules may build a local Harmony HAR.', { stage: 'link', details: pending.map(module => module.packageName).sort() });
|
|
23
|
+
}
|
|
24
|
+
await (0, materialize_1.materializeLocalSourcesAsync)(pending, {
|
|
25
|
+
dependencies: modules,
|
|
26
|
+
projectRoot: options.projectRoot,
|
|
27
|
+
timeoutMs: raw.timeoutMs,
|
|
28
|
+
outputLimit: raw.outputLimit,
|
|
29
|
+
env: raw.env,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
options,
|
|
34
|
+
diagnostics: verify.diagnostics,
|
|
35
|
+
modules: await (0, configuredBuild_1.buildConfiguredModulesAsync)(modules, {
|
|
36
|
+
...raw, projectRoot: options.projectRoot, buildType: options.buildType,
|
|
37
|
+
}),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -224,6 +224,7 @@ function searchRecordFromDescriptor(descriptor, declared) {
|
|
|
224
224
|
? {
|
|
225
225
|
platforms: ['harmony'],
|
|
226
226
|
harmony: {
|
|
227
|
+
...(descriptor.harmony.buildOptionsFile ? { buildOptionsFile: descriptor.harmony.buildOptionsFile } : {}),
|
|
227
228
|
modules,
|
|
228
229
|
services,
|
|
229
230
|
...Object.fromEntries(host_1.HostMetadataFields.map(field => [
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.registerLinkCommand = registerLinkCommand;
|
|
4
4
|
const link_1 = require("../autolinking/link");
|
|
5
|
+
const prepare_1 = require("../autolinking/prepare");
|
|
5
6
|
const autolinkingOptions_1 = require("./autolinkingOptions");
|
|
6
7
|
const output_1 = require("./output");
|
|
7
8
|
function registerLinkCommand(program, io) {
|
|
@@ -14,7 +15,7 @@ function registerLinkCommand(program, io) {
|
|
|
14
15
|
.option('--output-limit <bytes>', 'per-stream output capture limit', autolinkingOptions_1.parsePositiveInt)
|
|
15
16
|
.option('-j, --json', 'output results in the plain JSON format', false)
|
|
16
17
|
.action(async (searchPaths, options) => {
|
|
17
|
-
|
|
18
|
+
const input = {
|
|
18
19
|
...(0, autolinkingOptions_1.toApiOptions)(options, searchPaths),
|
|
19
20
|
harmonyProjectPath: options.harmonyProjectPath,
|
|
20
21
|
nodeModulesPath: options.nodeModulesPath,
|
|
@@ -22,6 +23,8 @@ function registerLinkCommand(program, io) {
|
|
|
22
23
|
rnohCliPackageJsonPath: options.rnohCliPackageJson,
|
|
23
24
|
timeoutMs: options.timeoutMs,
|
|
24
25
|
outputLimit: options.outputLimit,
|
|
25
|
-
}
|
|
26
|
+
};
|
|
27
|
+
const prepared = await (0, prepare_1.prepareModulesAsync)(input);
|
|
28
|
+
(0, output_1.writeResult)(io, await (0, link_1.linkPreparedModulesAsync)(input, prepared), options);
|
|
26
29
|
});
|
|
27
30
|
}
|
|
@@ -0,0 +1,264 @@
|
|
|
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.buildConfiguredModulesAsync = buildConfiguredModulesAsync;
|
|
7
|
+
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
8
|
+
const promises_1 = __importDefault(require("node:fs/promises"));
|
|
9
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
+
const json5_1 = __importDefault(require("json5"));
|
|
11
|
+
const errors_1 = require("../errors");
|
|
12
|
+
const values_1 = require("../utilities/values");
|
|
13
|
+
const dependencies_1 = require("./ohpm/dependencies");
|
|
14
|
+
const har_1 = require("./har");
|
|
15
|
+
const materialize_1 = require("./materialize");
|
|
16
|
+
const publish_1 = require("./transaction/publish");
|
|
17
|
+
const Ignored = new Set(['.git', '.hvigor', '.cxx', '.native-build', 'native-deps', 'build', 'node_modules', 'oh_modules', 'local.properties', 'oh-package-lock.json5', 'BuildProfile.ets']);
|
|
18
|
+
const InputsFile = '.expo/harmony/module-build-options.json';
|
|
19
|
+
async function readBuildInputs(options) {
|
|
20
|
+
if (options.moduleBuilds !== undefined)
|
|
21
|
+
return options;
|
|
22
|
+
let content;
|
|
23
|
+
try {
|
|
24
|
+
content = await promises_1.default.readFile(node_path_1.default.join(options.projectRoot, InputsFile), 'utf8');
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
if (error.code === 'ENOENT')
|
|
28
|
+
return options;
|
|
29
|
+
throw new errors_1.HarmonyAutolinkingError('INVALID_OPTIONS', `Cannot read ${InputsFile}.`, {
|
|
30
|
+
cause: error,
|
|
31
|
+
stage: 'configured-module-build',
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
let saved;
|
|
35
|
+
try {
|
|
36
|
+
saved = JSON.parse(content);
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
throw new errors_1.HarmonyAutolinkingError('INVALID_OPTIONS', `Invalid ${InputsFile}; run Harmony prebuild again.`, {
|
|
40
|
+
cause: error,
|
|
41
|
+
stage: 'configured-module-build',
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
if (!saved || typeof saved !== 'object' || saved.schemaVersion !== 1 || !saved.moduleBuilds) {
|
|
45
|
+
throw new errors_1.HarmonyAutolinkingError('INVALID_OPTIONS', `Invalid ${InputsFile}; run Harmony prebuild again.`, {
|
|
46
|
+
stage: 'configured-module-build',
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
return { ...options, moduleBuilds: saved.moduleBuilds, moduleBuildSettings: saved.moduleBuildSettings };
|
|
50
|
+
}
|
|
51
|
+
async function hashTree(hash, dir, depth = Infinity, metadataOnly = false) {
|
|
52
|
+
for (const entry of (await promises_1.default.readdir(dir, { withFileTypes: true })).sort((a, b) => a.name.localeCompare(b.name, 'en'))) {
|
|
53
|
+
if (Ignored.has(entry.name) || entry.name.endsWith('.har'))
|
|
54
|
+
continue;
|
|
55
|
+
const file = node_path_1.default.join(dir, entry.name);
|
|
56
|
+
if (entry.isDirectory() && depth > 0) {
|
|
57
|
+
hash.update(entry.name + '/');
|
|
58
|
+
await hashTree(hash, file, depth - 1, metadataOnly);
|
|
59
|
+
}
|
|
60
|
+
else if (entry.isFile() && (!metadataOnly || /(?:package|sdk-pkg)\.json$/u.test(entry.name))) {
|
|
61
|
+
hash.update(entry.name + '\0').update(new Uint8Array(await promises_1.default.readFile(file)));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
async function buildFingerprint(project, modules, options) {
|
|
66
|
+
const hash = node_crypto_1.default.createHash('sha256');
|
|
67
|
+
hash.update(new Uint8Array(await promises_1.default.readFile(__filename)));
|
|
68
|
+
hash.update(JSON.stringify([options.buildType, options.moduleBuildSettings]));
|
|
69
|
+
await hashTree(hash, project);
|
|
70
|
+
for (const { descriptor, mapping } of (0, dependencies_1.collectOhpmDeps)(modules)) {
|
|
71
|
+
const file = (0, dependencies_1.resolveOhpmSpecifier)(descriptor, mapping, { harmonyProjectPath: project });
|
|
72
|
+
hash.update(mapping.ohPackageName).update(new Uint8Array(await promises_1.default.readFile(node_path_1.default.resolve(project, file))));
|
|
73
|
+
}
|
|
74
|
+
const env = { ...process.env, ...options.env };
|
|
75
|
+
for (const key of Object.keys(env).sort()) {
|
|
76
|
+
if (/^(HARMONY_|DEVECO_|OHOS_)|^(PATH|CC|CXX|CFLAGS|CXXFLAGS|LDFLAGS)$/u.test(key))
|
|
77
|
+
hash.update(key + '=' + env[key]);
|
|
78
|
+
}
|
|
79
|
+
if (!env.DEVECO_SDK_HOME || !env.HARMONY_HVIGORW || !env.HARMONY_OHPM)
|
|
80
|
+
return null;
|
|
81
|
+
await hashTree(hash, env.DEVECO_SDK_HOME, 3, true);
|
|
82
|
+
for (const tool of [env.HARMONY_HVIGORW, env.HARMONY_OHPM]) {
|
|
83
|
+
hash.update(new Uint8Array(await promises_1.default.readFile(tool)));
|
|
84
|
+
const manifest = node_path_1.default.resolve(node_path_1.default.dirname(tool), '../package.json');
|
|
85
|
+
try {
|
|
86
|
+
hash.update(new Uint8Array(await promises_1.default.readFile(manifest)));
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
if (error.code !== 'ENOENT') {
|
|
90
|
+
throw new errors_1.HarmonyAutolinkingError('INVALID_OPTIONS', `Cannot read build tool metadata: ${manifest}`, {
|
|
91
|
+
cause: error,
|
|
92
|
+
stage: 'configured-module-build',
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return hash.digest('hex');
|
|
98
|
+
}
|
|
99
|
+
async function buildConfiguredModulesAsync(modules, raw) {
|
|
100
|
+
const options = await readBuildInputs(raw);
|
|
101
|
+
const builds = options.moduleBuilds ?? {};
|
|
102
|
+
if (!builds || typeof builds !== 'object' || Array.isArray(builds)) {
|
|
103
|
+
throw new errors_1.HarmonyAutolinkingError('INVALID_OPTIONS', 'moduleBuilds must be an object.', {
|
|
104
|
+
stage: 'configured-module-build',
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
const linked = [...modules];
|
|
108
|
+
for (const name of Object.keys(builds).sort()) {
|
|
109
|
+
const index = linked.findIndex(item => item.packageName === name);
|
|
110
|
+
if (index < 0) {
|
|
111
|
+
throw new errors_1.HarmonyAutolinkingError('INVALID_OPTIONS', `Configured native module ${name} is not linked. Install it or remove its config plugin.`, {
|
|
112
|
+
stage: 'configured-module-build',
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
const item = linked[index];
|
|
116
|
+
const file = item.harmony.buildOptionsFile;
|
|
117
|
+
if (!item.arkTs || !file) {
|
|
118
|
+
throw new errors_1.HarmonyAutolinkingError('INVALID_OPTIONS', `${name} does not declare harmony.buildOptionsFile.`, {
|
|
119
|
+
stage: 'configured-module-build',
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
const source = await (0, values_1.resolveInsideAsync)(item.packageRoot, 'harmony', 'Harmony source project', { packageName: name, type: 'directory' });
|
|
123
|
+
const defaultsPath = await (0, values_1.resolveInsideAsync)(source, file, 'Harmony build options', { packageName: name, type: 'file' });
|
|
124
|
+
const defaults = JSON.parse(await promises_1.default.readFile(defaultsPath, 'utf8'));
|
|
125
|
+
const selected = builds[name];
|
|
126
|
+
if (!selected || typeof selected !== 'object' || Array.isArray(selected)) {
|
|
127
|
+
throw new errors_1.HarmonyAutolinkingError('INVALID_OPTIONS', `Build options for ${name} must be an object.`, {
|
|
128
|
+
stage: 'configured-module-build',
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
for (const [key, value] of Object.entries(selected)) {
|
|
132
|
+
if (!Object.hasOwn(defaults, key) || !['boolean', 'string', 'number'].includes(typeof value)
|
|
133
|
+
|| typeof value !== typeof defaults[key] || (typeof value === 'number' && !Number.isFinite(value))) {
|
|
134
|
+
throw new errors_1.HarmonyAutolinkingError('INVALID_OPTIONS', `Invalid build option ${name}.${key}.`, {
|
|
135
|
+
stage: 'configured-module-build',
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const root = await promises_1.default.realpath(options.projectRoot);
|
|
140
|
+
const cache = await (0, values_1.resolveInsideAsync)(root, '.expo/harmony/module-builds', 'Module build directory', { mustExist: false });
|
|
141
|
+
let dir = root;
|
|
142
|
+
for (const segment of ['.expo', 'harmony', 'module-builds']) {
|
|
143
|
+
dir = node_path_1.default.join(dir, segment);
|
|
144
|
+
try {
|
|
145
|
+
await promises_1.default.mkdir(dir);
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
if (error.code !== 'EEXIST') {
|
|
149
|
+
throw new errors_1.HarmonyAutolinkingError('INVALID_OPTIONS', `Cannot create module build directory: ${dir}`, {
|
|
150
|
+
cause: error,
|
|
151
|
+
stage: 'configured-module-build',
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
const stat = await promises_1.default.lstat(dir);
|
|
156
|
+
if (!stat.isDirectory() || stat.isSymbolicLink()) {
|
|
157
|
+
throw new errors_1.HarmonyAutolinkingError('INVALID_OPTIONS', 'Module build directory must not be a symbolic link.', {
|
|
158
|
+
stage: 'configured-module-build',
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const temp = await promises_1.default.mkdtemp(node_path_1.default.join(cache, 'build-'));
|
|
163
|
+
const project = node_path_1.default.join(temp, 'harmony');
|
|
164
|
+
try {
|
|
165
|
+
await promises_1.default.cp(source, project, {
|
|
166
|
+
recursive: true,
|
|
167
|
+
dereference: true,
|
|
168
|
+
filter: async (entry) => {
|
|
169
|
+
if (Ignored.has(node_path_1.default.basename(entry)) || entry.endsWith('.har'))
|
|
170
|
+
return false;
|
|
171
|
+
if (!(0, values_1.isPathInside)(item.packageRoot, await promises_1.default.realpath(entry))) {
|
|
172
|
+
throw new errors_1.HarmonyAutolinkingError('INVALID_OPTIONS', `Harmony source link escapes ${name}: ${node_path_1.default.relative(source, entry)}`, {
|
|
173
|
+
stage: 'configured-module-build',
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
return true;
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
await promises_1.default.writeFile(node_path_1.default.join(project, file), JSON.stringify({ ...defaults, ...selected }, null, 2) + '\n');
|
|
180
|
+
const profilePath = node_path_1.default.join(project, 'build-profile.json5');
|
|
181
|
+
const profile = json5_1.default.parse(await promises_1.default.readFile(profilePath, 'utf8'));
|
|
182
|
+
const library = profile.modules?.find(entry => node_path_1.default.normalize(entry.srcPath) === 'library');
|
|
183
|
+
const product = profile.app?.products?.find(entry => entry.name === 'default');
|
|
184
|
+
if (!library || !product || !/^[A-Za-z][A-Za-z0-9_]*$/u.test(library.name)) {
|
|
185
|
+
throw new errors_1.HarmonyAutolinkingError('INVALID_OPTIONS', `${name} must declare a library module and default product in harmony/build-profile.json5.`, {
|
|
186
|
+
stage: 'configured-module-build',
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
const settings = options.moduleBuildSettings;
|
|
190
|
+
if (settings) {
|
|
191
|
+
if (!Array.isArray(settings.abiFilters)
|
|
192
|
+
|| settings.abiFilters.some(abi => typeof abi !== 'string' || !abi)
|
|
193
|
+
|| ![settings.compatibleSdkVersion, settings.targetSdkVersion].every(value => typeof value === 'string' && value.length > 0)) {
|
|
194
|
+
throw new errors_1.HarmonyAutolinkingError('INVALID_OPTIONS', 'Invalid moduleBuildSettings; run Harmony prebuild again.', {
|
|
195
|
+
stage: 'configured-module-build',
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
product.compatibleSdkVersion = settings.compatibleSdkVersion;
|
|
199
|
+
product.targetSdkVersion = settings.targetSdkVersion;
|
|
200
|
+
const file = node_path_1.default.join(project, 'library/build-profile.json5');
|
|
201
|
+
const build = json5_1.default.parse(await promises_1.default.readFile(file, 'utf8'));
|
|
202
|
+
if (build.buildOption?.externalNativeOptions) {
|
|
203
|
+
build.buildOption.externalNativeOptions.abiFilters = settings.abiFilters;
|
|
204
|
+
}
|
|
205
|
+
await promises_1.default.writeFile(file, JSON.stringify(build, null, 2) + '\n');
|
|
206
|
+
}
|
|
207
|
+
await promises_1.default.writeFile(profilePath, JSON.stringify(profile, null, 2) + '\n');
|
|
208
|
+
const deps = linked.filter(module => module.packageName !== name);
|
|
209
|
+
const key = await buildFingerprint(project, deps, options);
|
|
210
|
+
const cached = key ? node_path_1.default.join(cache, `${key}.har`) : null;
|
|
211
|
+
if (cached && await (0, materialize_1.isNonEmptyRegularHarAsync)(cached, cache, name)) {
|
|
212
|
+
try {
|
|
213
|
+
const expected = JSON.parse(await promises_1.default.readFile(cached + '.json', 'utf8')).sha256;
|
|
214
|
+
const actual = node_crypto_1.default.createHash('sha256').update(new Uint8Array(await promises_1.default.readFile(cached))).digest('hex');
|
|
215
|
+
if (expected === actual) {
|
|
216
|
+
linked[index] = { ...item, arkTs: { ...item.arkTs, builtHarPath: cached } };
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
catch (error) {
|
|
221
|
+
if (error.code !== 'ENOENT' && !(error instanceof SyntaxError)) {
|
|
222
|
+
throw new errors_1.HarmonyAutolinkingError('INVALID_OPTIONS', `Cannot inspect cached HAR for ${name}.`, {
|
|
223
|
+
cause: error,
|
|
224
|
+
stage: 'configured-module-build',
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
const manifestPath = node_path_1.default.join(project, 'oh-package.json5');
|
|
230
|
+
const manifest = json5_1.default.parse(await promises_1.default.readFile(manifestPath, 'utf8'));
|
|
231
|
+
const overrides = {};
|
|
232
|
+
const versions = {};
|
|
233
|
+
for (const { descriptor, mapping } of (0, dependencies_1.collectOhpmDeps)(deps)) {
|
|
234
|
+
overrides[mapping.ohPackageName] = (0, dependencies_1.resolveOhpmSpecifier)(descriptor, mapping, { harmonyProjectPath: project });
|
|
235
|
+
versions[mapping.ohPackageName] = descriptor.packageVersion;
|
|
236
|
+
}
|
|
237
|
+
await promises_1.default.writeFile(manifestPath, JSON.stringify({ ...manifest, overrides: { ...manifest.overrides, ...overrides } }, null, 2) + '\n');
|
|
238
|
+
const build = {
|
|
239
|
+
executable: 'hvigorw', cwd: project,
|
|
240
|
+
args: ['--mode', 'module', '-p', `module=${library.name}@default`, '-p', 'product=default', '-p', `buildMode=${options.buildType ?? 'debug'}`, '--no-daemon', 'assembleHar'],
|
|
241
|
+
};
|
|
242
|
+
for (const step of (0, materialize_1.fixedLocalSourceBuildSteps)(build))
|
|
243
|
+
await (0, materialize_1.runFixedBuildStepAsync)(step, name, options);
|
|
244
|
+
const output = node_path_1.default.join(project, 'library/build/default/outputs/default', `${library.name}.har`);
|
|
245
|
+
if (!await (0, materialize_1.isNonEmptyRegularHarAsync)(output, project, name)) {
|
|
246
|
+
throw new errors_1.HarmonyAutolinkingError('INVALID_OPTIONS', `${name}: Hvigor did not produce a HAR.`, {
|
|
247
|
+
stage: 'configured-module-build',
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
const sourceManifest = json5_1.default.parse(await promises_1.default.readFile(node_path_1.default.join(project, 'library/oh-package.json5'), 'utf8'));
|
|
251
|
+
await (0, har_1.sanitizeHarmonyHar)(output, { sourceManifest, workspaceVersions: versions });
|
|
252
|
+
const digest = node_crypto_1.default.createHash('sha256').update(new Uint8Array(await promises_1.default.readFile(output))).digest('hex');
|
|
253
|
+
const target = cached || node_path_1.default.join(cache, `${digest}.har`);
|
|
254
|
+
await (0, publish_1.publishArtifactsAsync)({
|
|
255
|
+
allowedRoot: root, lockPath: node_path_1.default.join(cache, 'publish.lock'), files: [{ source: output, target }, { content: JSON.stringify({ sha256: digest }) + '\n', target: target + '.json' }],
|
|
256
|
+
});
|
|
257
|
+
linked[index] = { ...item, arkTs: { ...item.arkTs, builtHarPath: target } };
|
|
258
|
+
}
|
|
259
|
+
finally {
|
|
260
|
+
await promises_1.default.rm(temp, { recursive: true, force: true });
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return linked;
|
|
264
|
+
}
|