expo-harmony-toolkit 1.8.3 → 1.9.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  <div align="center">
2
2
  <h1>Expo Harmony Toolkit</h1>
3
- <p><strong>A HarmonyOS migration, admission, and UI-stack build toolkit for Managed/CNG Expo projects.</strong></p>
3
+ <p><strong>A HarmonyOS migration, admission, and UI-stack build toolkit for Managed/CNG Expo projects, now with a bare intake baseline.</strong></p>
4
4
  <p>One verified UI-stack matrix, additive preview/experimental capability tiers, managed Harmony sidecar scaffolding, and a toolkit-driven <code>doctor → init → bundle → build-hap</code> path.</p>
5
5
  <p>
6
6
  <a href="./README.md">简体中文</a> ·
@@ -9,9 +9,9 @@
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.3-111827?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.9.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
- <img alt="Input" src="https://img.shields.io/badge/input-Managed%2FCNG-059669?style=flat-square">
14
+ <img alt="Input" src="https://img.shields.io/badge/input-Managed%2FCNG%20%2B%20bare%20intake-059669?style=flat-square">
15
15
  </p>
16
16
  <p>
17
17
  <a href="./docs/support-matrix.md">Support Matrix</a> ·
@@ -24,7 +24,7 @@
24
24
  </div>
25
25
 
26
26
  > [!IMPORTANT]
27
- > `v1.8` keeps the `verified + preview + experimental` model and continues to keep `expo-location` and `expo-camera` in `preview`. The public promise remains tighter: `latest` only carries fully accepted `verified` capabilities, while `next` is reserved for preview fast-track work. The roadmap now defines `v2.0.0` itself as “reliable Harmony packaging for any Expo project”, so the intermediate versions will keep getting split smaller, but that still does not widen the current `verified` boundary yet.
27
+ > `v1.9.1` keeps the `v1.9.0` bare workflow intake, app foundation modules, and `react-native-gesture-handler` formal slice, and adds a local HAR normalize opt-out for `build-hap`. The public promise remains tighter: `latest` only carries fully accepted `verified` capabilities, while `next` is reserved for preview fast-track work. The expanded goal still does not widen the current `verified` boundary yet.
28
28
 
29
29
  > [!TIP]
30
30
  > The two validated `@react-native-oh-tpl/*` adapters in the public matrix are currently consumed via exact Git URLs and commits. For repository development and the official UI-stack sample, prefer `pnpm install --ignore-scripts` so adapter prepare hooks do not fail on private upstream resources.
@@ -48,12 +48,12 @@
48
48
  <!-- GENERATED:readme-current-status:start -->
49
49
  | Item | Status |
50
50
  | --- | --- |
51
- | Current version | `v1.8.3` |
51
+ | Current version | `v1.9.1` |
52
52
  | Support model | `verified + preview + experimental` |
53
53
  | Public `verified` matrix | `expo55-rnoh082-ui-stack` |
54
- | Supported input | Managed/CNG Expo projects |
54
+ | Supported input | Managed/CNG Expo projects; bare workflow intake baseline |
55
55
  | `verified` JS/UI capabilities | `expo-router`, `expo-linking`, `expo-constants`, `react-native-reanimated`, `react-native-svg` |
56
- | `preview` native capabilities | `expo-file-system`, `expo-image-picker`, `expo-location`, `expo-camera` |
56
+ | `preview` native capabilities | `expo-file-system`, `expo-image-picker`, `expo-location`, `expo-camera`, `expo-secure-store`, `expo-asset`, `expo-device`, `expo-clipboard`, `expo-haptics` |
57
57
  | `experimental` capabilities | `expo-notifications`, `react-native-gesture-handler` |
58
58
  | Release tracks | `latest` = fully accepted `verified` only; `next` = preview fast track |
59
59
  | Capability telemetry | `runtimeMode` + `evidence(...)` + `evidenceSource(...)` + `coverageProfile` + `nextActions` |
@@ -66,10 +66,11 @@
66
66
  <details>
67
67
  <summary><strong>Still outside the verified public promise</strong></summary>
68
68
 
69
- - bare Expo
69
+ - bare Expo still only reaches the intake baseline
70
70
  - `expo-file-system`, `expo-image-picker`, `expo-location`, and `expo-camera` remain `preview`
71
+ - `expo-secure-store`, `expo-asset`, `expo-device`, `expo-clipboard`, and `expo-haptics` remain the `preview` shim baseline
71
72
  - `expo-notifications`
72
- - `react-native-gesture-handler`
73
+ - `react-native-gesture-handler` remains a formal experimental slice
73
74
  - multiple public matrices
74
75
 
75
76
  </details>
@@ -174,7 +175,7 @@ Common decision points:
174
175
 
175
176
  <!-- GENERATED:readme-support-matrix:start -->
176
177
  - `verified`: the only public matrix remains `expo55-rnoh082-ui-stack`
177
- - `preview`: `expo-file-system`, `expo-image-picker`, `expo-location`, `expo-camera`
178
+ - `preview`: `expo-file-system`, `expo-image-picker`, `expo-location`, `expo-camera`, `expo-secure-store`, `expo-asset`, `expo-device`, `expo-clipboard`, `expo-haptics`
178
179
  - `experimental`: `expo-notifications`, `react-native-gesture-handler`
179
180
 
180
181
  `doctor --strict` still means `verified` only. `doctor --target-tier preview` allows the same runtime matrix plus preview-tier capabilities, but that does not promote them into the formal public promise.
@@ -198,7 +199,7 @@ If you want the `v1.8.x` promotion board directly, use [acceptance/v1.8.x-capabi
198
199
  - `examples/official-ui-stack-sample`
199
200
  The current public main sample, covering router, linking, constants, SVG, reanimated, and the Harmony sidecar build flow.
200
201
  - `examples/official-native-capabilities-sample`
201
- The `v1.8.x` preview walkthrough sample, covering the supported core subsets for `expo-file-system`, `expo-image-picker`, `expo-location`, and `expo-camera` plus permission, bundle, debug-build validation, and per-capability acceptance tracking.
202
+ Preview walkthrough sample for `expo-file-system`, `expo-image-picker`, `expo-location`, `expo-camera`, and the v1.9 app foundation modules, keeping core subsets, permissions, bundle/debug evidence, and per-capability acceptance tracking explicit.
202
203
  - `examples/official-app-shell-sample`
203
204
  The minimal App Shell onboarding sample that demonstrates router, linking, constants, pathname, observed URL, and a generated deep-link flow.
204
205
  - `examples/official-minimal-sample`
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  <div align="center">
2
2
  <h1>Expo Harmony Toolkit</h1>
3
- <p><strong>面向 Managed/CNG Expo 项目的 HarmonyOS 迁移、准入检查与 UI-stack 构建工具链。</strong></p>
3
+ <p><strong>面向 Managed/CNG Expo 项目,并开始纳入 bare intake baseline 的 HarmonyOS 迁移、准入检查与 UI-stack 构建工具链。</strong></p>
4
4
  <p>One verified UI-stack matrix, additive preview/experimental capability tiers, managed Harmony sidecar scaffolding, and a toolkit-driven <code>doctor → init → bundle → build-hap</code> path.</p>
5
5
  <p>
6
6
  <a href="./README.md">简体中文</a> ·
@@ -9,9 +9,9 @@
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.3-111827?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.9.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
- <img alt="Input" src="https://img.shields.io/badge/input-Managed%2FCNG-059669?style=flat-square">
14
+ <img alt="Input" src="https://img.shields.io/badge/input-Managed%2FCNG%20%2B%20bare%20intake-059669?style=flat-square">
15
15
  </p>
16
16
  <p>
17
17
  <a href="./docs/support-matrix.md">支持矩阵</a> ·
@@ -24,7 +24,7 @@
24
24
  </div>
25
25
 
26
26
  > [!IMPORTANT]
27
- > `v1.8` 延续 `verified + preview + experimental` 三层支持模型,并把 `expo-location`、`expo-camera` 继续保持在 `preview`。当前公开承诺仍然收紧为:`latest` 只承诺完整验收的 `verified` 能力,`next` 用于 preview fast track。最新 roadmap 已把 `v2.0.0` 直接定义成“任何 Expo 项目都能可靠打包成鸿蒙 App”,因此中间版本会继续拆小,但这不等于当前 `verified` 边界已经放宽。
27
+ > `v1.9.1` 延续 `v1.9.0` bare workflow intake、app foundation modules 与 `react-native-gesture-handler` formal slice,并为 `build-hap` 增加本地 HAR normalize opt-out。当前公开承诺仍然收紧为:`latest` 只承诺完整验收的 `verified` 能力,`next` 用于 preview fast track。目标扩大不等于当前 `verified` 边界已经放宽。
28
28
 
29
29
  > [!TIP]
30
30
  > 由于当前公开矩阵内的两套 `@react-native-oh-tpl/*` adapter 依赖以 Git URL + exact commit 形式接入,仓库开发和官方 UI-stack sample 推荐使用 `pnpm install --ignore-scripts`,避免 Git adapter 在 prepare 阶段拉取私有资源而中断安装。
@@ -48,12 +48,12 @@
48
48
  <!-- GENERATED:readme-current-status:start -->
49
49
  | 项目 | 说明 |
50
50
  | --- | --- |
51
- | 当前版本 | `v1.8.3` |
51
+ | 当前版本 | `v1.9.1` |
52
52
  | 支持模型 | `verified + preview + experimental` |
53
53
  | 唯一 `verified` 公开矩阵 | `expo55-rnoh082-ui-stack` |
54
- | 输入范围 | Managed/CNG Expo 项目 |
54
+ | 输入范围 | Managed/CNG Expo 项目;bare workflow intake baseline |
55
55
  | `verified` JS/UI 能力 | `expo-router`、`expo-linking`、`expo-constants`、`react-native-reanimated`、`react-native-svg` |
56
- | `preview` 原生能力 | `expo-file-system`、`expo-image-picker`、`expo-location`、`expo-camera` |
56
+ | `preview` 原生能力 | `expo-file-system`、`expo-image-picker`、`expo-location`、`expo-camera`、`expo-secure-store`、`expo-asset`、`expo-device`、`expo-clipboard`、`expo-haptics` |
57
57
  | `experimental` 能力 | `expo-notifications`、`react-native-gesture-handler` |
58
58
  | 发布轨 | `latest` = fully accepted verified only;`next` = preview fast track |
59
59
  | capability 遥测 | `runtimeMode` + `evidence(...)` + `evidenceSource(...)` + `coverageProfile` + `nextActions` |
@@ -66,10 +66,11 @@
66
66
  <details>
67
67
  <summary><strong>当前仍不在 verified 正式承诺范围</strong></summary>
68
68
 
69
- - bare Expo
69
+ - bare Expo 仍只到 intake baseline
70
70
  - `expo-file-system`、`expo-image-picker`、`expo-location`、`expo-camera` 仍只属于 `preview`
71
+ - `expo-secure-store`、`expo-asset`、`expo-device`、`expo-clipboard`、`expo-haptics` 仍只属于 `preview` shim baseline
71
72
  - `expo-notifications`
72
- - `react-native-gesture-handler`
73
+ - `react-native-gesture-handler` 仍只属于 formal experimental slice
73
74
  - 多矩阵并行支持
74
75
 
75
76
  </details>
@@ -174,7 +175,7 @@ pnpm exec expo-harmony build-hap --mode release
174
175
 
175
176
  <!-- GENERATED:readme-support-matrix:start -->
176
177
  - `verified`:唯一公开矩阵仍是 `expo55-rnoh082-ui-stack`
177
- - `preview`:`expo-file-system`, `expo-image-picker`, `expo-location`, `expo-camera`
178
+ - `preview`:`expo-file-system`, `expo-image-picker`, `expo-location`, `expo-camera`, `expo-secure-store`, `expo-asset`, `expo-device`, `expo-clipboard`, `expo-haptics`
178
179
  - `experimental`:`expo-notifications`, `react-native-gesture-handler`
179
180
 
180
181
  `doctor --strict` 继续只代表 `verified`。`doctor --target-tier preview` 会在同一 runtime matrix 下额外放行 preview 能力,但这不等于它们已经进入正式承诺。
@@ -204,7 +205,7 @@ pnpm exec expo-harmony build-hap --mode release
204
205
  - `examples/official-ui-stack-sample`
205
206
  当前唯一对外主 sample,同时覆盖 router、linking、constants、SVG、reanimated 和 Harmony sidecar 构建链。
206
207
  - `examples/official-native-capabilities-sample`
207
- `v1.8.x` 的 preview walkthrough sample,用来承接 `expo-file-system`、`expo-image-picker`、`expo-location`、`expo-camera` 的核心支持子集、permission、bundle、debug build 与逐 capability 验收追踪。
208
+ preview walkthrough sample,用来承接 `expo-file-system`、`expo-image-picker`、`expo-location`、`expo-camera` 与 v1.9 app foundation modules 的核心支持子集、permission、bundle、debug build 与逐 capability 验收追踪。
208
209
  - `examples/official-app-shell-sample`
209
210
  最小可理解的 App Shell onboarding sample,用来展示 router、linking、constants、pathname、observed URL 与 generated deep link。
210
211
  - `examples/official-minimal-sample`
package/build/cli.js CHANGED
@@ -40,6 +40,7 @@ async function run(argv = process.argv) {
40
40
  .description('Build a Harmony HAP from the validated sidecar and bundle outputs')
41
41
  .option('-p, --project-root <path>', 'path to the Expo project')
42
42
  .option('--mode <mode>', 'build mode: debug or release', 'debug')
43
+ .option('--no-har-normalize', 'let ohpm consume file:*.har dependencies without extracting local HARs')
43
44
  .action(buildHap_1.runBuildHapCommand);
44
45
  program
45
46
  .command('init')
@@ -1,5 +1,6 @@
1
1
  export interface BuildHapCommandOptions {
2
2
  projectRoot?: string;
3
3
  mode?: 'debug' | 'release';
4
+ harNormalize?: boolean;
4
5
  }
5
6
  export declare function runBuildHapCommand(options: BuildHapCommandOptions): Promise<void>;
@@ -17,6 +17,7 @@ async function runBuildHapCommand(options) {
17
17
  }
18
18
  const report = await (0, build_1.buildHapProject)(projectRoot, {
19
19
  mode,
20
+ skipHarNormalize: options.harNormalize === false,
20
21
  });
21
22
  await (0, metadata_1.writeBuildReport)(projectRoot, report);
22
23
  if (report.status === 'failed') {
@@ -2,6 +2,7 @@ import type { BuildReport } from '../types';
2
2
  import type { CommandRunner } from './build/commands';
3
3
  export type { CommandRunner, CommandRunnerResult } from './build/commands';
4
4
  export { renderBuildReport } from './build/reporting';
5
+ export declare const SKIP_HAR_NORMALIZE_WARNING = "Local HAR normalization is disabled; ohpm will consume file:*.har dependencies directly and normalized build-profile/RNOH compatibility steps will be skipped.";
5
6
  interface BundleProjectOptions {
6
7
  env?: NodeJS.ProcessEnv;
7
8
  runner?: CommandRunner;
@@ -11,6 +12,7 @@ interface BuildHapProjectOptions {
11
12
  mode: 'debug' | 'release';
12
13
  env?: NodeJS.ProcessEnv;
13
14
  runner?: CommandRunner;
15
+ skipHarNormalize?: boolean;
14
16
  }
15
17
  export declare function bundleProject(projectRoot: string, options?: BundleProjectOptions): Promise<BuildReport>;
16
18
  export declare function buildHapProject(projectRoot: string, options: BuildHapProjectOptions): Promise<BuildReport>;
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.renderBuildReport = void 0;
6
+ exports.SKIP_HAR_NORMALIZE_WARNING = exports.renderBuildReport = void 0;
7
7
  exports.bundleProject = bundleProject;
8
8
  exports.buildHapProject = buildHapProject;
9
9
  exports.getDesiredHarmonyScripts = getDesiredHarmonyScripts;
@@ -20,6 +20,7 @@ const reporting_1 = require("./build/reporting");
20
20
  const rnohCompatibility_1 = require("./build/rnohCompatibility");
21
21
  var reporting_2 = require("./build/reporting");
22
22
  Object.defineProperty(exports, "renderBuildReport", { enumerable: true, get: function () { return reporting_2.renderBuildReport; } });
23
+ exports.SKIP_HAR_NORMALIZE_WARNING = 'Local HAR normalization is disabled; ohpm will consume file:*.har dependencies directly and normalized build-profile/RNOH compatibility steps will be skipped.';
23
24
  async function bundleProject(projectRoot, options = {}) {
24
25
  const runtimeEnv = options.env ?? process.env;
25
26
  const runCommand = options.runner ?? commands_1.defaultCommandRunner;
@@ -193,6 +194,7 @@ async function bundleProject(projectRoot, options = {}) {
193
194
  async function buildHapProject(projectRoot, options) {
194
195
  const runtimeEnv = options.env ?? process.env;
195
196
  const runCommand = options.runner ?? commands_1.defaultCommandRunner;
197
+ const skipHarNormalize = options.skipHarNormalize === true || runtimeEnv.EXPO_HARMONY_SKIP_HAR_NORMALIZE === '1';
196
198
  const loadedProject = await (0, project_1.loadProject)(projectRoot);
197
199
  const envReport = await (0, env_1.buildEnvReport)(loadedProject.projectRoot, {
198
200
  env: runtimeEnv,
@@ -202,6 +204,9 @@ async function buildHapProject(projectRoot, options) {
202
204
  ...envReport.warnings.filter((warning) => !warning.startsWith('Harmony sidecar files are not present yet.')),
203
205
  ...relevantEnvAdvisories.map((issue) => `${issue.code}: ${issue.message}`),
204
206
  ];
207
+ if (skipHarNormalize) {
208
+ warnings.push(exports.SKIP_HAR_NORMALIZE_WARNING);
209
+ }
205
210
  const blockingIssues = [];
206
211
  if (!envReport.hvigorPath) {
207
212
  blockingIssues.push({
@@ -286,39 +291,41 @@ async function buildHapProject(projectRoot, options) {
286
291
  let restoreNormalizedRnohCliAutolinkingTemplates = async () => { };
287
292
  let restoreNormalizedRnohCodegenAlignment = async () => { };
288
293
  let restoreNormalizedHarmonyPackageJsons = async () => { };
289
- try {
290
- const normalizedLocalHarDependencies = await (0, localHar_1.normalizeLocalHarDependencies)(harmonyProjectRoot);
291
- normalizedLocalHarPackages = normalizedLocalHarDependencies.packages;
292
- restoreNormalizedDependencies = normalizedLocalHarDependencies.restore;
293
- restoreNormalizedLocalHarModules = await (0, localHar_1.ensureHarmonyBuildProfileSupportsNormalizedLocalDeps)(harmonyProjectRoot, normalizedLocalHarDependencies.packages);
294
- restoreNormalizedRnohCliAutolinkingTemplates =
295
- await (0, rnohCompatibility_1.normalizeProjectRnohCliAutolinkingTemplates)(loadedProject.projectRoot);
296
- restoreNormalizedHarmonyPackageJsons =
297
- await (0, autolinking_1.normalizeKnownHarmonyPackageJsons)(loadedProject.projectRoot);
298
- }
299
- catch (error) {
300
- const message = error instanceof Error ? error.message : String(error);
301
- return (0, reporting_1.createBuildReport)({
302
- projectRoot: loadedProject.projectRoot,
303
- command: 'build-hap',
304
- mode: options.mode,
305
- status: 'failed',
306
- harmonyProjectRoot,
307
- entryFile: bundleReport.entryFile,
308
- bundleOutputPath: bundleReport.bundleOutputPath,
309
- assetsDestPath: bundleReport.assetsDestPath,
310
- artifactPaths: [],
311
- blockingIssues: [
312
- {
313
- code: 'build.hap.failed',
314
- message,
315
- },
316
- ],
317
- warnings: [...warnings, ...bundleReport.warnings],
318
- steps,
319
- });
294
+ if (!skipHarNormalize) {
295
+ try {
296
+ const normalizedLocalHarDependencies = await (0, localHar_1.normalizeLocalHarDependencies)(harmonyProjectRoot);
297
+ normalizedLocalHarPackages = normalizedLocalHarDependencies.packages;
298
+ restoreNormalizedDependencies = normalizedLocalHarDependencies.restore;
299
+ restoreNormalizedLocalHarModules = await (0, localHar_1.ensureHarmonyBuildProfileSupportsNormalizedLocalDeps)(harmonyProjectRoot, normalizedLocalHarDependencies.packages);
300
+ restoreNormalizedRnohCliAutolinkingTemplates =
301
+ await (0, rnohCompatibility_1.normalizeProjectRnohCliAutolinkingTemplates)(loadedProject.projectRoot);
302
+ restoreNormalizedHarmonyPackageJsons =
303
+ await (0, autolinking_1.normalizeKnownHarmonyPackageJsons)(loadedProject.projectRoot);
304
+ }
305
+ catch (error) {
306
+ const message = error instanceof Error ? error.message : String(error);
307
+ return (0, reporting_1.createBuildReport)({
308
+ projectRoot: loadedProject.projectRoot,
309
+ command: 'build-hap',
310
+ mode: options.mode,
311
+ status: 'failed',
312
+ harmonyProjectRoot,
313
+ entryFile: bundleReport.entryFile,
314
+ bundleOutputPath: bundleReport.bundleOutputPath,
315
+ assetsDestPath: bundleReport.assetsDestPath,
316
+ artifactPaths: [],
317
+ blockingIssues: [
318
+ {
319
+ code: 'build.hap.failed',
320
+ message,
321
+ },
322
+ ],
323
+ warnings: [...warnings, ...bundleReport.warnings],
324
+ steps,
325
+ });
326
+ }
327
+ restoreNormalizedRnohCodegenAlignment = await (0, localHar_1.alignRnohCodegenWithNormalizedLocalPackage)(harmonyProjectRoot, normalizedLocalHarPackages);
320
328
  }
321
- restoreNormalizedRnohCodegenAlignment = await (0, localHar_1.alignRnohCodegenWithNormalizedLocalPackage)(harmonyProjectRoot, normalizedLocalHarPackages);
322
329
  const ohpmCommand = (0, commands_1.buildInvocation)(envReport.ohpmPath, ['install', '--all']);
323
330
  try {
324
331
  const ohpmResult = await runCommand(ohpmCommand.file, ohpmCommand.args, {
@@ -349,10 +356,12 @@ async function buildHapProject(projectRoot, options) {
349
356
  steps,
350
357
  });
351
358
  }
352
- if (!normalizedLocalHarPackages.some((localPackage) => localPackage.packageName === '@rnoh/react-native-openharmony')) {
353
- await (0, localHar_1.ensureRnohGeneratedTsShim)(harmonyProjectRoot);
359
+ if (!skipHarNormalize) {
360
+ if (!normalizedLocalHarPackages.some((localPackage) => localPackage.packageName === '@rnoh/react-native-openharmony')) {
361
+ await (0, localHar_1.ensureRnohGeneratedTsShim)(harmonyProjectRoot);
362
+ }
363
+ await (0, localHar_1.patchRnohGeneratedCodegenForNormalizedLocalPackage)(harmonyProjectRoot);
354
364
  }
355
- await (0, localHar_1.patchRnohGeneratedCodegenForNormalizedLocalPackage)(harmonyProjectRoot);
356
365
  await (0, localHar_1.patchKnownHarmonyAdapterCodegenOutputs)(harmonyProjectRoot);
357
366
  const hvigorCommand = (0, commands_1.buildInvocation)(envReport.hvigorPath, [
358
367
  'assembleHap',
@@ -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";
3
+ export declare const TOOLKIT_VERSION = "1.9.1";
4
4
  export declare const TEMPLATE_VERSION = "rnoh-0.82.29";
5
5
  export declare const RNOH_VERSION = "0.82.29";
6
6
  export declare const RNOH_CLI_VERSION = "0.82.29";
@@ -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.3';
6
+ exports.TOOLKIT_VERSION = '1.9.1';
7
7
  exports.TEMPLATE_VERSION = 'rnoh-0.82.29';
8
8
  exports.RNOH_VERSION = '0.82.29';
9
9
  exports.RNOH_CLI_VERSION = '0.82.29';
@@ -25,6 +25,12 @@ const DEFAULT_RECORD = {
25
25
  };
26
26
  const BARE_WORKFLOW_DIRECTORY_NAMES = ['android', 'ios'];
27
27
  const BARE_WORKFLOW_DEPENDENCIES = new Set(['expo-build-properties', 'expo-dev-client']);
28
+ const FORMAL_EXPERIMENTAL_ADAPTER_PAIRS = [
29
+ {
30
+ canonicalPackageName: 'react-native-gesture-handler',
31
+ adapterPackageName: '@react-native-oh-tpl/react-native-gesture-handler',
32
+ },
33
+ ];
28
34
  async function buildDoctorReport(projectRoot, options = {}) {
29
35
  const loadedProject = await (0, project_1.loadProject)(projectRoot);
30
36
  const doctorConfig = (0, project_1.resolveExpoHarmonyDoctorConfig)(loadedProject.expoConfig);
@@ -329,6 +335,24 @@ async function collectBlockingIssues(projectRoot, expoConfig, packageJson, expoP
329
335
  });
330
336
  }
331
337
  }
338
+ for (const pairing of FORMAL_EXPERIMENTAL_ADAPTER_PAIRS) {
339
+ const hasCanonical = dependencyMap.has(pairing.canonicalPackageName);
340
+ const hasAdapter = dependencyMap.has(pairing.adapterPackageName);
341
+ if (hasCanonical && !hasAdapter) {
342
+ issues.push({
343
+ code: 'dependency.required_missing',
344
+ message: `Using ${pairing.canonicalPackageName} in its formal experimental Harmony slice also requires ${pairing.adapterPackageName}.`,
345
+ subject: pairing.adapterPackageName,
346
+ });
347
+ }
348
+ if (hasAdapter && !hasCanonical) {
349
+ issues.push({
350
+ code: 'dependency.required_missing',
351
+ message: `Using ${pairing.adapterPackageName} in its formal experimental Harmony slice also requires ${pairing.canonicalPackageName}.`,
352
+ subject: pairing.canonicalPackageName,
353
+ });
354
+ }
355
+ }
332
356
  if (!expoConfig.android?.package && !expoConfig.ios?.bundleIdentifier) {
333
357
  issues.push({
334
358
  code: 'config.native_identifier.missing',
@@ -392,14 +416,14 @@ function resolveDependencyGapCategory(dependency, coverageProfile) {
392
416
  dependency.name === 'react-native')) {
393
417
  return 'bare-workflow-gap';
394
418
  }
419
+ if (isThirdPartyNativeGapDependency(dependency)) {
420
+ return 'third-party-native-gap';
421
+ }
395
422
  if (isOfficialExpoDependencyName(dependency.name) || capabilities_1.CAPABILITY_BY_PACKAGE[dependency.name]) {
396
423
  return dependency.supportTier === 'verified' && dependency.status === 'supported'
397
424
  ? 'matrix-drift'
398
425
  : 'official-module-gap';
399
426
  }
400
- if (isThirdPartyNativeGapDependency(dependency)) {
401
- return 'third-party-native-gap';
402
- }
403
427
  if (coverageProfile === 'bare') {
404
428
  return 'bare-workflow-gap';
405
429
  }
@@ -462,7 +486,7 @@ function buildNextActions(input) {
462
486
  if (blockingIssues.some((issue) => issue.code === 'dependency.not_allowed' &&
463
487
  (issue.subject === 'react-native-gesture-handler' ||
464
488
  issue.subject === '@react-native-oh-tpl/react-native-gesture-handler'))) {
465
- actions.push('Keep `react-native-gesture-handler` out of the verified lane until its Harmony adapter path has stable doctor, sample, and build coverage.');
489
+ actions.push('Keep `react-native-gesture-handler` on the formal experimental slice until its Harmony adapter path closes device and release evidence.');
466
490
  }
467
491
  if (hasBlockingIssueCode(blockingIssues, 'config.native_identifier.missing')) {
468
492
  actions.push('Set `android.package` or `ios.bundleIdentifier` in Expo config before expecting a strict Harmony build path.');
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MANAGED_EXPO_HARMONY_MODULE_RENDERERS = void 0;
4
4
  exports.renderCapabilityModuleShim = renderCapabilityModuleShim;
5
5
  exports.renderUnsupportedCapabilityShim = renderUnsupportedCapabilityShim;
6
+ const appFoundation_1 = require("./renderers/appFoundation");
6
7
  const camera_1 = require("./renderers/camera");
7
8
  const fileSystem_1 = require("./renderers/fileSystem");
8
9
  const imagePicker_1 = require("./renderers/imagePicker");
@@ -24,6 +25,26 @@ const CAPABILITY_SHIM_RENDERERS = {
24
25
  adapter: camera_1.renderExpoCameraHarmonyAdapterShim,
25
26
  preview: camera_1.renderExpoCameraPreviewShim,
26
27
  },
28
+ 'expo-secure-store': {
29
+ adapter: appFoundation_1.renderExpoSecureStorePreviewShim,
30
+ preview: appFoundation_1.renderExpoSecureStorePreviewShim,
31
+ },
32
+ 'expo-asset': {
33
+ adapter: appFoundation_1.renderExpoAssetPreviewShim,
34
+ preview: appFoundation_1.renderExpoAssetPreviewShim,
35
+ },
36
+ 'expo-device': {
37
+ adapter: appFoundation_1.renderExpoDevicePreviewShim,
38
+ preview: appFoundation_1.renderExpoDevicePreviewShim,
39
+ },
40
+ 'expo-clipboard': {
41
+ adapter: appFoundation_1.renderExpoClipboardPreviewShim,
42
+ preview: appFoundation_1.renderExpoClipboardPreviewShim,
43
+ },
44
+ 'expo-haptics': {
45
+ adapter: appFoundation_1.renderExpoHapticsPreviewShim,
46
+ preview: appFoundation_1.renderExpoHapticsPreviewShim,
47
+ },
27
48
  };
28
49
  exports.MANAGED_EXPO_HARMONY_MODULE_RENDERERS = [
29
50
  {
@@ -0,0 +1,5 @@
1
+ export declare function renderExpoSecureStorePreviewShim(): string;
2
+ export declare function renderExpoAssetPreviewShim(): string;
3
+ export declare function renderExpoDevicePreviewShim(): string;
4
+ export declare function renderExpoClipboardPreviewShim(): string;
5
+ export declare function renderExpoHapticsPreviewShim(): string;