expo-harmony-toolkit 1.8.0 → 1.8.1
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.en.md +2 -2
- package/README.md +2 -2
- package/build/core/constants.d.ts +1 -1
- package/build/core/constants.js +1 -1
- package/build/core/project.d.ts +3 -1
- package/build/core/project.js +47 -0
- package/build/core/report.js +31 -12
- package/build/core/template.js +5 -1
- package/build/data/capabilities.d.ts +6 -2
- package/build/data/capabilities.js +6 -4
- package/build/data/dependencyCatalog.js +24 -0
- package/build/data/publicDocs.d.ts +1 -1
- package/build/plugin.js +4 -0
- package/build/types.d.ts +11 -0
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
<p>
|
|
10
10
|
<a href="https://github.com/BlackishGreen33/Expo-Harmony-Toolkit/actions/workflows/ci.yml"><img alt="Checks" src="https://img.shields.io/badge/checks-passing-16a34a?style=flat-square&logo=githubactions&logoColor=white"></a>
|
|
11
11
|
<a href="./LICENSE"><img alt="License" src="https://img.shields.io/badge/license-MIT-0f766e?style=flat-square"></a>
|
|
12
|
-
<a href="https://github.com/BlackishGreen33/Expo-Harmony-Toolkit/releases"><img alt="Version" src="https://img.shields.io/badge/version-v1.8.
|
|
12
|
+
<a href="https://github.com/BlackishGreen33/Expo-Harmony-Toolkit/releases"><img alt="Version" src="https://img.shields.io/badge/version-v1.8.1-111827?style=flat-square"></a>
|
|
13
13
|
<a href="./docs/support-matrix.md"><img alt="Matrix" src="https://img.shields.io/badge/matrix-expo55--rnoh082--ui--stack-2563eb?style=flat-square"></a>
|
|
14
14
|
<img alt="Input" src="https://img.shields.io/badge/input-Managed%2FCNG-059669?style=flat-square">
|
|
15
15
|
</p>
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
<!-- GENERATED:readme-current-status:start -->
|
|
49
49
|
| Item | Status |
|
|
50
50
|
| --- | --- |
|
|
51
|
-
| Current version | `v1.8.
|
|
51
|
+
| Current version | `v1.8.1` |
|
|
52
52
|
| Support model | `verified + preview + experimental` |
|
|
53
53
|
| Public `verified` matrix | `expo55-rnoh082-ui-stack` |
|
|
54
54
|
| Supported input | Managed/CNG Expo projects |
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
<p>
|
|
10
10
|
<a href="https://github.com/BlackishGreen33/Expo-Harmony-Toolkit/actions/workflows/ci.yml"><img alt="Checks" src="https://img.shields.io/badge/checks-passing-16a34a?style=flat-square&logo=githubactions&logoColor=white"></a>
|
|
11
11
|
<a href="./LICENSE"><img alt="License" src="https://img.shields.io/badge/license-MIT-0f766e?style=flat-square"></a>
|
|
12
|
-
<a href="https://github.com/BlackishGreen33/Expo-Harmony-Toolkit/releases"><img alt="Version" src="https://img.shields.io/badge/version-v1.8.
|
|
12
|
+
<a href="https://github.com/BlackishGreen33/Expo-Harmony-Toolkit/releases"><img alt="Version" src="https://img.shields.io/badge/version-v1.8.1-111827?style=flat-square"></a>
|
|
13
13
|
<a href="./docs/support-matrix.md"><img alt="Matrix" src="https://img.shields.io/badge/matrix-expo55--rnoh082--ui--stack-2563eb?style=flat-square"></a>
|
|
14
14
|
<img alt="Input" src="https://img.shields.io/badge/input-Managed%2FCNG-059669?style=flat-square">
|
|
15
15
|
</p>
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
<!-- GENERATED:readme-current-status:start -->
|
|
49
49
|
| 项目 | 说明 |
|
|
50
50
|
| --- | --- |
|
|
51
|
-
| 当前版本 | `v1.8.
|
|
51
|
+
| 当前版本 | `v1.8.1` |
|
|
52
52
|
| 支持模型 | `verified + preview + experimental` |
|
|
53
53
|
| 唯一 `verified` 公开矩阵 | `expo55-rnoh082-ui-stack` |
|
|
54
54
|
| 输入范围 | Managed/CNG Expo 项目 |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export declare const TOOLKIT_PACKAGE_NAME = "expo-harmony-toolkit";
|
|
2
2
|
export declare const CLI_NAME = "expo-harmony";
|
|
3
|
-
export declare const TOOLKIT_VERSION = "1.8.
|
|
3
|
+
export declare const TOOLKIT_VERSION = "1.8.1";
|
|
4
4
|
export declare const TEMPLATE_VERSION = "rnoh-0.82.18";
|
|
5
5
|
export declare const RNOH_VERSION = "0.82.18";
|
|
6
6
|
export declare const RNOH_CLI_VERSION = "0.82.18";
|
package/build/core/constants.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.DESIRED_PACKAGE_SCRIPTS = exports.HARMONY_RUNTIME_PRELUDE_RELATIVE_PATH = exports.HARMONY_ROUTER_ENTRY_FILENAME = exports.STRICT_ENV_EXIT_CODE = exports.STRICT_DOCTOR_EXIT_CODE = exports.DEFAULT_HVIGOR_PLUGIN_FILENAME = exports.PREBUILD_METADATA_FILENAME = exports.TOOLKIT_CONFIG_FILENAME = exports.BUILD_REPORT_FILENAME = exports.ENV_REPORT_FILENAME = exports.DOCTOR_REPORT_FILENAME = exports.MANIFEST_FILENAME = exports.SIGNING_LOCAL_EXAMPLE_FILENAME = exports.SIGNING_LOCAL_FILENAME = exports.GENERATED_SHIMS_DIR = exports.GENERATED_DIR = exports.SUPPORTED_EXPO_SDKS = exports.RNOH_CLI_VERSION = exports.RNOH_VERSION = exports.TEMPLATE_VERSION = exports.TOOLKIT_VERSION = exports.CLI_NAME = exports.TOOLKIT_PACKAGE_NAME = void 0;
|
|
4
4
|
exports.TOOLKIT_PACKAGE_NAME = 'expo-harmony-toolkit';
|
|
5
5
|
exports.CLI_NAME = 'expo-harmony';
|
|
6
|
-
exports.TOOLKIT_VERSION = '1.8.
|
|
6
|
+
exports.TOOLKIT_VERSION = '1.8.1';
|
|
7
7
|
exports.TEMPLATE_VERSION = 'rnoh-0.82.18';
|
|
8
8
|
exports.RNOH_VERSION = '0.82.18';
|
|
9
9
|
exports.RNOH_CLI_VERSION = '0.82.18';
|
package/build/core/project.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DependencySource, ExpoHarmonyPluginProps, HarmonyIdentifiers, LoadedProject, PackageJson } from '../types';
|
|
1
|
+
import { DependencySource, ExpoHarmonyResolvedDoctorConfig, ExpoHarmonyPluginProps, HarmonyIdentifiers, LoadedProject, PackageJson } from '../types';
|
|
2
2
|
export declare function resolveProjectRoot(projectRoot?: string): Promise<string>;
|
|
3
3
|
export declare function loadProject(projectRoot: string): Promise<LoadedProject>;
|
|
4
4
|
export declare function ensureProjectPackageJsonPath(projectRoot: string): Promise<string>;
|
|
@@ -10,6 +10,8 @@ export declare function collectDeclaredDependencies(packageJson: PackageJson): A
|
|
|
10
10
|
}>;
|
|
11
11
|
export declare function hasDeclaredDependency(packageJson: PackageJson, dependencyName: string): boolean;
|
|
12
12
|
export declare function collectExpoPlugins(expoConfig: Record<string, any>): string[];
|
|
13
|
+
export declare function resolveExpoHarmonyDoctorConfig(expoConfig: Record<string, any>): ExpoHarmonyResolvedDoctorConfig;
|
|
14
|
+
export declare function applyDependencyExclusions(packageJson: PackageJson, excludedDependencies: readonly string[]): PackageJson;
|
|
13
15
|
export declare function collectExpoSchemes(expoConfig: Record<string, any>): string[];
|
|
14
16
|
export declare function deriveHarmonyIdentifiers(expoConfig: Record<string, any>, packageJson?: PackageJson, props?: ExpoHarmonyPluginProps): HarmonyIdentifiers;
|
|
15
17
|
export declare function detectExpoSdkVersion(packageJson: PackageJson): number | null;
|
package/build/core/project.js
CHANGED
|
@@ -10,6 +10,8 @@ exports.findAppConfigPath = findAppConfigPath;
|
|
|
10
10
|
exports.collectDeclaredDependencies = collectDeclaredDependencies;
|
|
11
11
|
exports.hasDeclaredDependency = hasDeclaredDependency;
|
|
12
12
|
exports.collectExpoPlugins = collectExpoPlugins;
|
|
13
|
+
exports.resolveExpoHarmonyDoctorConfig = resolveExpoHarmonyDoctorConfig;
|
|
14
|
+
exports.applyDependencyExclusions = applyDependencyExclusions;
|
|
13
15
|
exports.collectExpoSchemes = collectExpoSchemes;
|
|
14
16
|
exports.deriveHarmonyIdentifiers = deriveHarmonyIdentifiers;
|
|
15
17
|
exports.detectExpoSdkVersion = detectExpoSdkVersion;
|
|
@@ -100,6 +102,27 @@ function collectExpoPlugins(expoConfig) {
|
|
|
100
102
|
}
|
|
101
103
|
return [...names].sort((left, right) => left.localeCompare(right));
|
|
102
104
|
}
|
|
105
|
+
function resolveExpoHarmonyDoctorConfig(expoConfig) {
|
|
106
|
+
const rawDoctorConfig = expoConfig.extra?.expoHarmony?.doctor;
|
|
107
|
+
const coverageProfile = normalizeCoverageProfile(rawDoctorConfig?.coverageProfile);
|
|
108
|
+
return {
|
|
109
|
+
excludeDependencies: normalizeStringArray(rawDoctorConfig?.excludeDependencies),
|
|
110
|
+
excludePlugins: normalizeStringArray(rawDoctorConfig?.excludePlugins),
|
|
111
|
+
coverageProfile,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
function applyDependencyExclusions(packageJson, excludedDependencies) {
|
|
115
|
+
if (excludedDependencies.length === 0) {
|
|
116
|
+
return packageJson;
|
|
117
|
+
}
|
|
118
|
+
const excludedDependencySet = new Set(excludedDependencies);
|
|
119
|
+
return {
|
|
120
|
+
...packageJson,
|
|
121
|
+
dependencies: filterDependencySection(packageJson.dependencies, excludedDependencySet),
|
|
122
|
+
devDependencies: filterDependencySection(packageJson.devDependencies, excludedDependencySet),
|
|
123
|
+
peerDependencies: filterDependencySection(packageJson.peerDependencies, excludedDependencySet),
|
|
124
|
+
};
|
|
125
|
+
}
|
|
103
126
|
function collectExpoSchemes(expoConfig) {
|
|
104
127
|
const rawScheme = expoConfig.scheme;
|
|
105
128
|
if (typeof rawScheme === 'string' && rawScheme.trim().length > 0) {
|
|
@@ -204,3 +227,27 @@ function sanitizeIdentifierSegment(value) {
|
|
|
204
227
|
.replace(/^_+/, '');
|
|
205
228
|
return cleaned.length > 0 ? cleaned : 'entry';
|
|
206
229
|
}
|
|
230
|
+
function normalizeStringArray(value) {
|
|
231
|
+
if (!Array.isArray(value)) {
|
|
232
|
+
return [];
|
|
233
|
+
}
|
|
234
|
+
return [...new Set(value
|
|
235
|
+
.filter((entry) => typeof entry === 'string')
|
|
236
|
+
.map((entry) => entry.trim())
|
|
237
|
+
.filter((entry) => entry.length > 0))].sort((left, right) => left.localeCompare(right));
|
|
238
|
+
}
|
|
239
|
+
function normalizeCoverageProfile(value) {
|
|
240
|
+
if (value === 'managed-core' ||
|
|
241
|
+
value === 'managed-native-heavy' ||
|
|
242
|
+
value === 'bare' ||
|
|
243
|
+
value === 'third-party-native-heavy') {
|
|
244
|
+
return value;
|
|
245
|
+
}
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
function filterDependencySection(section, excludedDependencies) {
|
|
249
|
+
if (!section) {
|
|
250
|
+
return section;
|
|
251
|
+
}
|
|
252
|
+
return Object.fromEntries(Object.entries(section).filter(([dependencyName]) => !excludedDependencies.has(dependencyName)));
|
|
253
|
+
}
|
package/build/core/report.js
CHANGED
|
@@ -27,13 +27,16 @@ const BARE_WORKFLOW_DIRECTORY_NAMES = ['android', 'ios'];
|
|
|
27
27
|
const BARE_WORKFLOW_DEPENDENCIES = new Set(['expo-build-properties', 'expo-dev-client']);
|
|
28
28
|
async function buildDoctorReport(projectRoot, options = {}) {
|
|
29
29
|
const loadedProject = await (0, project_1.loadProject)(projectRoot);
|
|
30
|
+
const doctorConfig = (0, project_1.resolveExpoHarmonyDoctorConfig)(loadedProject.expoConfig);
|
|
31
|
+
const filteredPackageJson = (0, project_1.applyDependencyExclusions)(loadedProject.packageJson, doctorConfig.excludeDependencies);
|
|
30
32
|
const expoSdkVersion = (0, project_1.detectExpoSdkVersion)(loadedProject.packageJson);
|
|
31
33
|
const matrix = validatedMatrices_1.VALIDATED_RELEASE_MATRICES[validatedMatrices_1.DEFAULT_VALIDATED_MATRIX_ID];
|
|
32
34
|
const targetTier = options.targetTier ?? 'verified';
|
|
33
|
-
const
|
|
35
|
+
const excludedPlugins = new Set(doctorConfig.excludePlugins);
|
|
36
|
+
const expoPlugins = (0, project_1.collectExpoPlugins)(loadedProject.expoConfig).filter((pluginName) => !excludedPlugins.has(pluginName));
|
|
34
37
|
const expoSchemes = (0, project_1.collectExpoSchemes)(loadedProject.expoConfig);
|
|
35
38
|
const dependencyRecords = new Map();
|
|
36
|
-
const declaredDependencies = (0, project_1.collectDeclaredDependencies)(
|
|
39
|
+
const declaredDependencies = (0, project_1.collectDeclaredDependencies)(filteredPackageJson);
|
|
37
40
|
for (const dependency of declaredDependencies) {
|
|
38
41
|
dependencyRecords.set(dependency.name, createDependencyRecord(dependency.name, dependency.version, dependency.source));
|
|
39
42
|
}
|
|
@@ -43,8 +46,11 @@ async function buildDoctorReport(projectRoot, options = {}) {
|
|
|
43
46
|
}
|
|
44
47
|
}
|
|
45
48
|
const dependencies = await (0, dependencyInspection_1.annotateDependencyBuildability)(loadedProject.projectRoot, [...dependencyRecords.values()].sort((left, right) => left.name.localeCompare(right.name)));
|
|
46
|
-
const blockingIssues = await collectBlockingIssues(loadedProject.projectRoot, loadedProject.expoConfig,
|
|
47
|
-
const
|
|
49
|
+
const blockingIssues = await collectBlockingIssues(loadedProject.projectRoot, loadedProject.expoConfig, filteredPackageJson, expoPlugins, expoSchemes, expoSdkVersion, dependencies, matrix, targetTier);
|
|
50
|
+
const excludedDependencies = new Set(doctorConfig.excludeDependencies);
|
|
51
|
+
const capabilities = (0, capabilities_1.getCapabilityDefinitionsForProject)(filteredPackageJson, {
|
|
52
|
+
excludedDependencies,
|
|
53
|
+
}).map((definition) => ({
|
|
48
54
|
id: definition.id,
|
|
49
55
|
packageName: definition.packageName,
|
|
50
56
|
status: definition.status,
|
|
@@ -59,7 +65,7 @@ async function buildDoctorReport(projectRoot, options = {}) {
|
|
|
59
65
|
sampleRoute: definition.sampleRoute,
|
|
60
66
|
acceptanceChecklist: [...definition.acceptanceChecklist],
|
|
61
67
|
}));
|
|
62
|
-
const coverageProfile = await detectCoverageProfile(loadedProject.projectRoot,
|
|
68
|
+
const coverageProfile = await detectCoverageProfile(loadedProject.projectRoot, filteredPackageJson, dependencies, doctorConfig.coverageProfile);
|
|
63
69
|
const blockingDependencyNames = new Set(blockingIssues
|
|
64
70
|
.filter((issue) => issue.code.startsWith('dependency.') && issue.subject)
|
|
65
71
|
.map((issue) => issue.subject));
|
|
@@ -76,7 +82,7 @@ async function buildDoctorReport(projectRoot, options = {}) {
|
|
|
76
82
|
capabilities,
|
|
77
83
|
});
|
|
78
84
|
const warnings = buildWarnings(loadedProject.expoConfig, expoSdkVersion, resolvedDependencies);
|
|
79
|
-
const advisories = buildAdvisories(loadedProject.expoConfig);
|
|
85
|
+
const advisories = buildAdvisories(loadedProject.expoConfig, doctorConfig);
|
|
80
86
|
return {
|
|
81
87
|
generatedAt: new Date().toISOString(),
|
|
82
88
|
projectRoot: loadedProject.projectRoot,
|
|
@@ -353,7 +359,10 @@ async function collectBlockingIssues(projectRoot, expoConfig, packageJson, expoP
|
|
|
353
359
|
}
|
|
354
360
|
return dedupeIssues(issues);
|
|
355
361
|
}
|
|
356
|
-
async function detectCoverageProfile(projectRoot, packageJson, dependencies) {
|
|
362
|
+
async function detectCoverageProfile(projectRoot, packageJson, dependencies, coverageProfileOverride) {
|
|
363
|
+
if (coverageProfileOverride) {
|
|
364
|
+
return coverageProfileOverride;
|
|
365
|
+
}
|
|
357
366
|
for (const directoryName of BARE_WORKFLOW_DIRECTORY_NAMES) {
|
|
358
367
|
if (await fs_extra_1.default.pathExists(path_1.default.join(projectRoot, directoryName))) {
|
|
359
368
|
return 'bare';
|
|
@@ -490,8 +499,17 @@ function buildWarnings(expoConfig, expoSdkVersion, dependencies) {
|
|
|
490
499
|
}
|
|
491
500
|
return warnings;
|
|
492
501
|
}
|
|
493
|
-
function buildAdvisories(expoConfig) {
|
|
502
|
+
function buildAdvisories(expoConfig, doctorConfig) {
|
|
494
503
|
const advisories = [];
|
|
504
|
+
if (doctorConfig.excludeDependencies.length > 0) {
|
|
505
|
+
advisories.push(`Expo Harmony doctor excluded dependencies: ${doctorConfig.excludeDependencies.join(', ')}.`);
|
|
506
|
+
}
|
|
507
|
+
if (doctorConfig.excludePlugins.length > 0) {
|
|
508
|
+
advisories.push(`Expo Harmony doctor excluded plugins: ${doctorConfig.excludePlugins.join(', ')}.`);
|
|
509
|
+
}
|
|
510
|
+
if (doctorConfig.coverageProfile) {
|
|
511
|
+
advisories.push(`Expo Harmony doctor forced coverage profile to ${doctorConfig.coverageProfile}.`);
|
|
512
|
+
}
|
|
495
513
|
if (!expoConfig.android?.package && expoConfig.ios?.bundleIdentifier) {
|
|
496
514
|
advisories.push('The project is using ios.bundleIdentifier as the only explicit native identifier. Prefer setting android.package as well before claiming release readiness.');
|
|
497
515
|
}
|
|
@@ -501,11 +519,12 @@ function isDependencyAllowedForTargetTier(dependencyName, matrix, targetTier) {
|
|
|
501
519
|
if (matrix.allowedDependencies.includes(dependencyName)) {
|
|
502
520
|
return true;
|
|
503
521
|
}
|
|
504
|
-
const
|
|
505
|
-
if (
|
|
506
|
-
return
|
|
522
|
+
const catalogRecord = dependencyCatalog_1.DEPENDENCY_CATALOG[dependencyName];
|
|
523
|
+
if (catalogRecord) {
|
|
524
|
+
return (0, capabilities_1.isSupportTierAllowed)(catalogRecord.supportTier, targetTier);
|
|
507
525
|
}
|
|
508
|
-
|
|
526
|
+
const capability = capabilities_1.CAPABILITY_BY_PACKAGE[dependencyName];
|
|
527
|
+
return capability ? (0, capabilities_1.isSupportTierAllowed)(capability.supportTier, targetTier) : false;
|
|
509
528
|
}
|
|
510
529
|
function matchesVersionRange(rawVersion, range) {
|
|
511
530
|
const coerced = semver_1.default.coerce(rawVersion);
|
package/build/core/template.js
CHANGED
|
@@ -135,9 +135,12 @@ async function syncProjectTemplate(projectRoot, force = false, options = {}) {
|
|
|
135
135
|
}
|
|
136
136
|
async function buildManagedFiles(loadedProject, identifiers, previousToolkitConfig, doctorReport) {
|
|
137
137
|
const hasExpoRouter = (0, support_1.usesExpoRouter)(loadedProject.packageJson);
|
|
138
|
+
const doctorConfig = (0, project_1.resolveExpoHarmonyDoctorConfig)(loadedProject.expoConfig);
|
|
138
139
|
const enabledCapabilities = doctorReport.capabilities;
|
|
139
140
|
const hasManagedExpoHarmonyPackage = enabledCapabilities.some((capability) => capability.runtimeMode !== 'shim');
|
|
140
|
-
const requestedHarmonyPermissions = (0, capabilities_1.collectCapabilityHarmonyPermissions)(loadedProject.packageJson
|
|
141
|
+
const requestedHarmonyPermissions = (0, capabilities_1.collectCapabilityHarmonyPermissions)(loadedProject.packageJson, {
|
|
142
|
+
excludedDependencies: new Set(doctorConfig.excludeDependencies),
|
|
143
|
+
});
|
|
141
144
|
const signingLocalConfig = await (0, signing_1.readSigningLocalConfig)(loadedProject.projectRoot);
|
|
142
145
|
const hvigorPluginFilename = await (0, project_1.resolveRnohHvigorPluginFilename)(loadedProject.projectRoot);
|
|
143
146
|
const renderedHarmonyRootPackage = renderTemplate(await fs_extra_1.default.readFile(path_1.default.join(TEMPLATE_ROOT, 'oh-package.json5'), 'utf8'), loadedProject, identifiers, hvigorPluginFilename);
|
|
@@ -179,6 +182,7 @@ async function buildManagedFiles(loadedProject, identifiers, previousToolkitConf
|
|
|
179
182
|
bundleName: identifiers.bundleName,
|
|
180
183
|
entryModuleName: identifiers.entryModuleName,
|
|
181
184
|
coverageProfile: doctorReport.coverageProfile,
|
|
185
|
+
doctorConfig,
|
|
182
186
|
capabilities: enabledCapabilities.map((capability) => ({
|
|
183
187
|
id: capability.id,
|
|
184
188
|
packageName: capability.packageName,
|
|
@@ -3,5 +3,9 @@ export declare const CAPABILITY_DEFINITIONS: readonly CapabilityDefinition[];
|
|
|
3
3
|
export declare const CAPABILITY_BY_PACKAGE: Record<string, CapabilityDefinition>;
|
|
4
4
|
export declare function compareSupportTiers(left: SupportTier, right: SupportTier): number;
|
|
5
5
|
export declare function isSupportTierAllowed(dependencyTier: SupportTier, targetTier: DoctorTargetTier): boolean;
|
|
6
|
-
export declare function getCapabilityDefinitionsForProject(packageJson: PackageJson
|
|
7
|
-
|
|
6
|
+
export declare function getCapabilityDefinitionsForProject(packageJson: PackageJson, options?: {
|
|
7
|
+
excludedDependencies?: ReadonlySet<string>;
|
|
8
|
+
}): CapabilityDefinition[];
|
|
9
|
+
export declare function collectCapabilityHarmonyPermissions(packageJson: PackageJson, options?: {
|
|
10
|
+
excludedDependencies?: ReadonlySet<string>;
|
|
11
|
+
}): string[];
|
|
@@ -149,9 +149,11 @@ function compareSupportTiers(left, right) {
|
|
|
149
149
|
function isSupportTierAllowed(dependencyTier, targetTier) {
|
|
150
150
|
return compareSupportTiers(dependencyTier, targetTier) <= 0;
|
|
151
151
|
}
|
|
152
|
-
function getCapabilityDefinitionsForProject(packageJson) {
|
|
153
|
-
|
|
152
|
+
function getCapabilityDefinitionsForProject(packageJson, options = {}) {
|
|
153
|
+
const excludedDependencies = options.excludedDependencies ?? new Set();
|
|
154
|
+
return exports.CAPABILITY_DEFINITIONS.filter((definition) => !excludedDependencies.has(definition.packageName) &&
|
|
155
|
+
(0, project_1.hasDeclaredDependency)(packageJson, definition.packageName)).sort((left, right) => left.packageName.localeCompare(right.packageName));
|
|
154
156
|
}
|
|
155
|
-
function collectCapabilityHarmonyPermissions(packageJson) {
|
|
156
|
-
return Array.from(new Set(getCapabilityDefinitionsForProject(packageJson).flatMap((definition) => definition.harmonyPermissions))).sort((left, right) => left.localeCompare(right));
|
|
157
|
+
function collectCapabilityHarmonyPermissions(packageJson, options = {}) {
|
|
158
|
+
return Array.from(new Set(getCapabilityDefinitionsForProject(packageJson, options).flatMap((definition) => definition.harmonyPermissions))).sort((left, right) => left.localeCompare(right));
|
|
157
159
|
}
|
|
@@ -112,6 +112,30 @@ exports.DEPENDENCY_CATALOG = {
|
|
|
112
112
|
supportTier: 'verified',
|
|
113
113
|
note: 'File-based routing is treated as part of the validated App Shell matrix when router peers, scheme, and plugin config are present.',
|
|
114
114
|
},
|
|
115
|
+
'@react-native-async-storage/async-storage': {
|
|
116
|
+
status: 'manual',
|
|
117
|
+
supportTier: 'experimental',
|
|
118
|
+
note: 'Async storage is a high-frequency startup dependency. Treat it as an experimental Harmony intake dependency until the managed adapter path has stable doctor, sample, and build coverage.',
|
|
119
|
+
docsUrl: 'https://github.com/react-native-oh-library',
|
|
120
|
+
},
|
|
121
|
+
'react-native-safe-area-context': {
|
|
122
|
+
status: 'supported',
|
|
123
|
+
supportTier: 'experimental',
|
|
124
|
+
note: 'Safe-area handling is shimmed by the toolkit for Harmony so App Shell layouts can keep rendering while the native path remains outside the verified matrix.',
|
|
125
|
+
docsUrl: 'https://github.com/react-native-oh-library',
|
|
126
|
+
},
|
|
127
|
+
'react-native-screens': {
|
|
128
|
+
status: 'manual',
|
|
129
|
+
supportTier: 'experimental',
|
|
130
|
+
note: 'Navigation stacks frequently depend on react-native-screens. Keep it on the experimental lane until the Harmony adapter path has repeatable sample and device coverage.',
|
|
131
|
+
docsUrl: 'https://github.com/react-native-oh-library',
|
|
132
|
+
},
|
|
133
|
+
'react-native-webview': {
|
|
134
|
+
status: 'manual',
|
|
135
|
+
supportTier: 'experimental',
|
|
136
|
+
note: 'WebView is a common app-shell blocker. Treat it as an experimental intake dependency until the Harmony runtime path is validated on device.',
|
|
137
|
+
docsUrl: 'https://github.com/react-native-oh-library',
|
|
138
|
+
},
|
|
115
139
|
...UI_STACK_COMPATIBILITY_RECORDS,
|
|
116
140
|
'react-native-gesture-handler': {
|
|
117
141
|
status: 'manual',
|
|
@@ -8,4 +8,4 @@ export declare const SUPPORTING_SAMPLE_PATHS: readonly ["examples/official-app-s
|
|
|
8
8
|
export declare const VERIFIED_JS_UI_CAPABILITY_NAMES: readonly ["expo-router", "expo-linking", "expo-constants", ...("react-native-reanimated" | "react-native-svg")[]];
|
|
9
9
|
export declare const PREVIEW_CAPABILITY_DEFINITIONS: import("..").CapabilityDefinition[];
|
|
10
10
|
export declare const EXPERIMENTAL_CAPABILITY_NAMES: readonly [...string[], "react-native-gesture-handler"];
|
|
11
|
-
export declare const PUBLIC_CURRENT_VERSION = "1.8.
|
|
11
|
+
export declare const PUBLIC_CURRENT_VERSION = "1.8.1";
|
package/build/plugin.js
CHANGED
|
@@ -16,9 +16,13 @@ const project_2 = require("./core/project");
|
|
|
16
16
|
const withExpoHarmony = (config, props = {}) => {
|
|
17
17
|
validatePluginProps(props);
|
|
18
18
|
const identifiers = (0, project_1.deriveHarmonyIdentifiers)(config, undefined, props);
|
|
19
|
+
const existingExpoHarmonyConfig = config.extra && typeof config.extra.expoHarmony === 'object' && config.extra.expoHarmony
|
|
20
|
+
? config.extra.expoHarmony
|
|
21
|
+
: {};
|
|
19
22
|
config.extra = {
|
|
20
23
|
...(config.extra ?? {}),
|
|
21
24
|
expoHarmony: {
|
|
25
|
+
...existingExpoHarmonyConfig,
|
|
22
26
|
bundleName: identifiers.bundleName,
|
|
23
27
|
entryModuleName: identifiers.entryModuleName,
|
|
24
28
|
templateVersion: props.templateVersion ?? constants_1.TEMPLATE_VERSION,
|
package/build/types.d.ts
CHANGED
|
@@ -8,6 +8,16 @@ export type DependencyBuildabilityRisk = 'known' | 'js-only-unknown' | 'native-r
|
|
|
8
8
|
export type CoverageProfile = 'managed-core' | 'managed-native-heavy' | 'bare' | 'third-party-native-heavy';
|
|
9
9
|
export type GapCategory = 'matrix-drift' | 'official-module-gap' | 'third-party-native-gap' | 'bare-workflow-gap';
|
|
10
10
|
export type DependencySource = 'dependency' | 'devDependency' | 'peerDependency' | 'expo-plugin';
|
|
11
|
+
export interface ExpoHarmonyDoctorConfig {
|
|
12
|
+
excludeDependencies?: string[];
|
|
13
|
+
excludePlugins?: string[];
|
|
14
|
+
coverageProfile?: CoverageProfile;
|
|
15
|
+
}
|
|
16
|
+
export interface ExpoHarmonyResolvedDoctorConfig {
|
|
17
|
+
excludeDependencies: string[];
|
|
18
|
+
excludePlugins: string[];
|
|
19
|
+
coverageProfile: CoverageProfile | null;
|
|
20
|
+
}
|
|
11
21
|
export interface ExpoHarmonyPluginProps {
|
|
12
22
|
bundleName?: string;
|
|
13
23
|
entryModuleName?: string;
|
|
@@ -236,6 +246,7 @@ export interface ToolkitConfig {
|
|
|
236
246
|
bundleName: string;
|
|
237
247
|
entryModuleName: string;
|
|
238
248
|
coverageProfile: CoverageProfile;
|
|
249
|
+
doctorConfig: ExpoHarmonyResolvedDoctorConfig;
|
|
239
250
|
capabilities: ManagedCapabilityRecord[];
|
|
240
251
|
requestedHarmonyPermissions: string[];
|
|
241
252
|
nextActions: string[];
|