@expo-harmony/expo-modules-autolinking 55.0.25-harmony.4 → 55.0.27-harmony.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/build/index.d.ts +3 -2
  2. package/build/index.js +4 -1
  3. package/build/runtime.d.ts +5 -3
  4. package/build/runtime.js +34 -5
  5. package/build/src/autolinking/link.d.ts +4 -2
  6. package/build/src/autolinking/link.js +34 -41
  7. package/build/src/autolinking/prepare.d.ts +15 -0
  8. package/build/src/autolinking/prepare.js +39 -0
  9. package/build/src/autolinking/verify.js +1 -0
  10. package/build/src/commands/link.js +5 -2
  11. package/build/src/harmony/configuredBuild.d.ts +2 -0
  12. package/build/src/harmony/configuredBuild.js +264 -0
  13. package/build/src/harmony/har.d.ts +6 -0
  14. package/build/src/harmony/har.js +160 -0
  15. package/build/src/harmony/manifest/index.js +1 -0
  16. package/build/src/harmony/materialize.d.ts +12 -2
  17. package/build/src/harmony/materialize.js +31 -21
  18. package/build/src/harmony/ohpm/dependencies.js +4 -1
  19. package/build/src/harmony/ohpm/mirror.d.ts +1 -0
  20. package/build/src/harmony/ohpm/mirror.js +56 -0
  21. package/build/src/harmony/persistence/canonicalize.js +6 -0
  22. package/build/src/harmony/transaction/stageProject.js +3 -1
  23. package/build/src/metadata/schema.d.ts +0 -1
  24. package/build/src/metadata/schema.js +47 -18
  25. package/build/src/types.d.ts +8 -0
  26. package/harmony-module.schema.json +5 -0
  27. package/index.ts +4 -1
  28. package/package.json +7 -3
  29. package/runtime.ts +41 -8
  30. package/src/autolinking/link.ts +39 -51
  31. package/src/autolinking/prepare.ts +46 -0
  32. package/src/autolinking/verify.ts +1 -1
  33. package/src/commands/link.ts +6 -3
  34. package/src/harmony/configuredBuild.ts +289 -0
  35. package/src/harmony/har.ts +130 -0
  36. package/src/harmony/manifest/index.ts +1 -0
  37. package/src/harmony/materialize.ts +44 -21
  38. package/src/harmony/ohpm/dependencies.ts +4 -1
  39. package/src/harmony/ohpm/mirror.ts +80 -0
  40. package/src/harmony/persistence/canonicalize.ts +6 -0
  41. package/src/harmony/transaction/stageProject.ts +3 -1
  42. package/src/metadata/schema.ts +52 -16
  43. 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");
@@ -7,7 +7,7 @@ export interface HarmonyNativeModule {
7
7
  artifacts: string[];
8
8
  }
9
9
  export interface HarmonyRuntimeContract {
10
- schemaVersion: 1;
10
+ schemaVersion: 1 | 2;
11
11
  platform: 'harmony';
12
12
  runtimeVersion: string;
13
13
  development: boolean;
@@ -22,8 +22,9 @@ export interface HarmonyRuntimeContract {
22
22
  modules: HarmonyNativeModule[];
23
23
  config: {
24
24
  nativeCompiler: string;
25
- targetApiVersion: number;
26
- compatibleApiVersion: number;
25
+ targetApiVersion: number | string;
26
+ compatibleApiVersion: number | string;
27
+ nativeLibFilterHash?: string;
27
28
  permissions: string[];
28
29
  querySchemes: string[];
29
30
  backgroundModes: string[];
@@ -40,6 +41,7 @@ export declare class HarmonyCompatibilityError extends Error {
40
41
  readonly code = "ERR_HARMONY_INCOMPATIBLE";
41
42
  constructor(issues: HarmonyCompatibilityIssue[]);
42
43
  }
44
+ export declare function harmonyRuntimeSchemaVersion(config: HarmonyRuntimeContract['config']): 1 | 2;
43
45
  export declare function validateHarmonyRuntime(value: unknown): HarmonyCompatibilityIssue[];
44
46
  export declare function checkHarmonyCompatibility(client: unknown, requirements: unknown): HarmonyCompatibilityIssue[];
45
47
  export declare function assertHarmonyCompatibility(client: unknown, requirements: unknown): asserts requirements is HarmonyRuntimeContract;
package/build/runtime.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.HarmonyCompatibilityError = void 0;
4
+ exports.harmonyRuntimeSchemaVersion = harmonyRuntimeSchemaVersion;
4
5
  exports.validateHarmonyRuntime = validateHarmonyRuntime;
5
6
  exports.checkHarmonyCompatibility = checkHarmonyCompatibility;
6
7
  exports.assertHarmonyCompatibility = assertHarmonyCompatibility;
@@ -27,11 +28,37 @@ function strings(value) {
27
28
  }
28
29
  const Versions = ['runtimeVersion', 'expo', 'expoModulesCore', 'rnoh', 'react', 'hermes'];
29
30
  const Settings = ['permissions', 'querySchemes', 'backgroundModes', 'abiFilters'];
31
+ function apiVersion(value, schema) {
32
+ if (typeof value === 'number' && Number.isSafeInteger(value) && value >= 13 && value < 26)
33
+ return [value, 0, 0];
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;
47
+ }
48
+ function harmonyRuntimeSchemaVersion(config) {
49
+ return typeof config.targetApiVersion === 'string' || typeof config.compatibleApiVersion === 'string'
50
+ || config.nativeLibFilterHash !== undefined
51
+ ? 2
52
+ : 1;
53
+ }
30
54
  function validateHarmonyRuntime(value) {
31
55
  if (!record(value))
32
56
  return [{ code: 'INVALID_CONTRACT', field: '', message: 'Runtime contract must be an object.' }];
33
57
  const issues = [];
34
- for (const [field, expected] of Object.entries({ schemaVersion: 1, platform: 'harmony', engine: 'hermes-v1', bundleFormat: 'js-source', renderer: 'rnoh' })) {
58
+ if (value.schemaVersion !== 1 && value.schemaVersion !== 2) {
59
+ issues.push({ code: 'INVALID_CONTRACT', field: 'schemaVersion', message: 'schemaVersion must be 1 or 2.' });
60
+ }
61
+ for (const [field, expected] of Object.entries({ platform: 'harmony', engine: 'hermes-v1', bundleFormat: 'js-source', renderer: 'rnoh' })) {
35
62
  if (value[field] !== expected) {
36
63
  issues.push({ code: field === 'platform' ? 'PLATFORM_MISMATCH' : 'INVALID_CONTRACT', field, message: `${field} must be ${expected}.` });
37
64
  }
@@ -62,10 +89,12 @@ function validateHarmonyRuntime(value) {
62
89
  }
63
90
  }
64
91
  const config = value.config;
92
+ const target = record(config) ? apiVersion(config.targetApiVersion, value.schemaVersion) : undefined;
93
+ const compatible = record(config) ? apiVersion(config.compatibleApiVersion, value.schemaVersion) : undefined;
65
94
  if (!record(config) || !token(config.nativeCompiler) || !Settings.every(field => strings(config[field]))
66
- || !Number.isInteger(config.targetApiVersion) || Number(config.targetApiVersion) < 13
67
- || !Number.isInteger(config.compatibleApiVersion) || Number(config.compatibleApiVersion) < 13
68
- || Number(config.compatibleApiVersion) > Number(config.targetApiVersion)
95
+ || !target || !compatible || compareApiVersions(compatible, target) > 0
96
+ || (config.nativeLibFilterHash !== undefined && (value.schemaVersion !== 2
97
+ || typeof config.nativeLibFilterHash !== 'string' || !/^[a-f0-9]{64}$/.test(config.nativeLibFilterHash)))
69
98
  || (Array.isArray(config.abiFilters) && config.abiFilters.length === 0)) {
70
99
  issues.push({ code: 'INVALID_CONTRACT', field: 'config', message: 'Invalid native build configuration.' });
71
100
  }
@@ -103,7 +132,7 @@ function checkHarmonyCompatibility(client, requirements) {
103
132
  issues.push({ code: 'NATIVE_MODULE_MISMATCH', field: module.packageName, message: `Native contract differs for ${module.packageName}. Rebuild or select a matching client.` });
104
133
  }
105
134
  }
106
- for (const field of ['nativeCompiler', 'targetApiVersion', 'compatibleApiVersion']) {
135
+ for (const field of ['nativeCompiler', 'targetApiVersion', 'compatibleApiVersion', 'nativeLibFilterHash']) {
107
136
  if (available.config[field] !== required.config[field]) {
108
137
  issues.push({ code: 'CONFIG_MISMATCH', field, message: `${field}: project requires ${required.config[field]}, client provides ${available.config[field]}.` });
109
138
  }
@@ -1,3 +1,5 @@
1
1
  import type { LinkOptions, LinkResult } from '../types';
2
- declare function linkModulesAsync(rawOptions: LinkOptions): Promise<LinkResult>;
3
- export { linkModulesAsync };
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 materialize_1 = require("../harmony/materialize");
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 linkModulesAsync(rawOptions) {
38
- const options = await (0, options_1.normalizeOptionsAsync)(rawOptions);
39
- if (typeof rawOptions.harmonyProjectPath !== 'string' || !rawOptions.harmonyProjectPath) {
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)(rawOptions.logger, 'warn', previous.warning.message, previous.warning);
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: rawOptions.harmonyProjectPath,
74
- nodeModulesPath: rawOptions.nodeModulesPath,
51
+ harmonyProjectPath: raw.harmonyProjectPath,
52
+ nodeModulesPath: raw.nodeModulesPath,
75
53
  modules,
76
54
  buildType: options.buildType,
77
55
  previousManagedOhpmPackageNames: previous.managedOhpmPackageNames,
78
- rnohCliPackageJsonPath: rawOptions.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: rawOptions.reactNativeExecutable,
87
- rnohCliPackageJsonPath: rawOptions.rnohCliPackageJsonPath,
88
- timeoutMs: rawOptions.timeoutMs,
89
- outputLimit: rawOptions.outputLimit,
90
- env: rawOptions.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: buildPublishEntries(staging, hostProviderSource, manifest),
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: verify.diagnostics,
105
+ diagnostics,
116
106
  warnings,
117
107
  };
118
- (0, values_1.emitLog)(rawOptions.logger, 'info', 'Harmony autolinking completed.', {
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)(rawOptions.logger, 'error', 'Harmony autolinking failed.', {
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)(rawOptions.logger, 'warn', warning.message, warning);
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
- (0, output_1.writeResult)(io, await (0, link_1.linkModulesAsync)({
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
- }), options);
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,2 @@
1
+ import type { LinkOptions, ModuleDescriptor } from '../types';
2
+ export declare function buildConfiguredModulesAsync(modules: ReadonlyArray<ModuleDescriptor>, raw: LinkOptions): Promise<ReadonlyArray<ModuleDescriptor>>;