expo-harmony-toolkit 1.8.2 → 1.9.0
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 +13 -11
- package/README.md +13 -11
- package/build/core/constants.d.ts +5 -5
- package/build/core/constants.js +4 -4
- package/build/core/report.js +28 -4
- package/build/core/template/capabilityRegistry.js +21 -0
- package/build/core/template/renderers/appFoundation.d.ts +5 -0
- package/build/core/template/renderers/appFoundation.js +225 -0
- package/build/data/capabilities.js +126 -0
- package/build/data/dependencyCatalog.js +13 -8
- package/build/data/publicDocs.d.ts +2 -2
- package/build/data/publicDocs.js +1 -2
- package/build/data/validatedMatrices.js +2 -2
- package/build/docs/render.js +3 -1
- package/docs/cli-build.md +13 -3
- package/docs/npm-release.md +1 -0
- package/docs/official-native-capabilities-sample.md +57 -2
- package/docs/roadmap.md +34 -9
- package/docs/signing-and-release.md +4 -0
- package/docs/support-matrix.md +20 -9
- package/package.json +1 -1
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.
|
|
12
|
+
<a href="https://github.com/BlackishGreen33/Expo-Harmony-Toolkit/releases"><img alt="Version" src="https://img.shields.io/badge/version-v1.9.0-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.
|
|
27
|
+
> `v1.9.0` keeps the `verified + preview + experimental` model and brings bare workflow intake, five app foundation modules, and the `react-native-gesture-handler` formal slice onto the mainline tracker. 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.
|
|
51
|
+
| Current version | `v1.9.0` |
|
|
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
|
-
|
|
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`
|
|
@@ -262,6 +263,7 @@ Additional preview evidence semantics:
|
|
|
262
263
|
- `device` is marked as `manual-doc`, which means a human acceptance record exists rather than CI automation
|
|
263
264
|
- `release` is marked as `none`, which means no release evidence exists yet
|
|
264
265
|
- `v1.8.2` additionally records local signing plus simulator install/start evidence for the ccnubox release HAP; this only proves the minimal app-shell release-HAP path and does not close per-capability release acceptance
|
|
266
|
+
- `v1.8.3` aligns the RNOH runtime / CLI to the current latest `0.82.x` patch (`0.82.29`) while keeping the buildable `react-native@0.82.1` matrix boundary
|
|
265
267
|
|
|
266
268
|
Manual Harmony acceptance still requires:
|
|
267
269
|
|
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
|
|
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.
|
|
12
|
+
<a href="https://github.com/BlackishGreen33/Expo-Harmony-Toolkit/releases"><img alt="Version" src="https://img.shields.io/badge/version-v1.9.0-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.
|
|
27
|
+
> `v1.9.0` 延续 `verified + preview + experimental` 三层支持模型,并把 bare workflow intake、五个 app foundation modules 与 `react-native-gesture-handler` formal slice 纳入主线追踪。当前公开承诺仍然收紧为:`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.
|
|
51
|
+
| 当前版本 | `v1.9.0` |
|
|
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
|
-
|
|
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`
|
|
@@ -268,6 +269,7 @@ preview 证据的额外说明:
|
|
|
268
269
|
- `device` 标记为 `manual-doc`,表示已有人工验收记录,不等于 CI 自动验收
|
|
269
270
|
- `release` 标记为 `none`,表示当前仍没有 release 证据
|
|
270
271
|
- `v1.8.2` 额外记录了 ccnubox release HAP 的本地签名、模拟器安装与启动证据;这只证明 app-shell release HAP 最低链路,不关闭单 capability release acceptance
|
|
272
|
+
- `v1.8.3` 将 RNOH runtime / CLI 对齐到当前 `0.82.x` 最新 patch(`0.82.29`),继续保留 `react-native@0.82.1` 的可构建矩阵边界
|
|
271
273
|
|
|
272
274
|
手动 Harmony 验收继续要求:
|
|
273
275
|
|
|
@@ -1,9 +1,9 @@
|
|
|
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.
|
|
4
|
-
export declare const TEMPLATE_VERSION = "rnoh-0.82.
|
|
5
|
-
export declare const RNOH_VERSION = "0.82.
|
|
6
|
-
export declare const RNOH_CLI_VERSION = "0.82.
|
|
3
|
+
export declare const TOOLKIT_VERSION = "1.9.0";
|
|
4
|
+
export declare const TEMPLATE_VERSION = "rnoh-0.82.29";
|
|
5
|
+
export declare const RNOH_VERSION = "0.82.29";
|
|
6
|
+
export declare const RNOH_CLI_VERSION = "0.82.29";
|
|
7
7
|
export declare const SUPPORTED_EXPO_SDKS: number[];
|
|
8
8
|
export declare const GENERATED_DIR = ".expo-harmony";
|
|
9
9
|
export declare const GENERATED_SHIMS_DIR = ".expo-harmony/shims";
|
|
@@ -15,7 +15,7 @@ export declare const ENV_REPORT_FILENAME = "env-report.json";
|
|
|
15
15
|
export declare const BUILD_REPORT_FILENAME = "build-report.json";
|
|
16
16
|
export declare const TOOLKIT_CONFIG_FILENAME = "toolkit-config.json";
|
|
17
17
|
export declare const PREBUILD_METADATA_FILENAME = "prebuild-metadata.json";
|
|
18
|
-
export declare const DEFAULT_HVIGOR_PLUGIN_FILENAME = "rnoh-hvigor-plugin-0.82.
|
|
18
|
+
export declare const DEFAULT_HVIGOR_PLUGIN_FILENAME = "rnoh-hvigor-plugin-0.82.29.tgz";
|
|
19
19
|
export declare const STRICT_DOCTOR_EXIT_CODE = 2;
|
|
20
20
|
export declare const STRICT_ENV_EXIT_CODE = 3;
|
|
21
21
|
export declare const HARMONY_ROUTER_ENTRY_FILENAME = "index.harmony.js";
|
package/build/core/constants.js
CHANGED
|
@@ -3,10 +3,10 @@ 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.
|
|
7
|
-
exports.TEMPLATE_VERSION = 'rnoh-0.82.
|
|
8
|
-
exports.RNOH_VERSION = '0.82.
|
|
9
|
-
exports.RNOH_CLI_VERSION = '0.82.
|
|
6
|
+
exports.TOOLKIT_VERSION = '1.9.0';
|
|
7
|
+
exports.TEMPLATE_VERSION = 'rnoh-0.82.29';
|
|
8
|
+
exports.RNOH_VERSION = '0.82.29';
|
|
9
|
+
exports.RNOH_CLI_VERSION = '0.82.29';
|
|
10
10
|
exports.SUPPORTED_EXPO_SDKS = [53, 55];
|
|
11
11
|
exports.GENERATED_DIR = '.expo-harmony';
|
|
12
12
|
exports.GENERATED_SHIMS_DIR = `${exports.GENERATED_DIR}/shims`;
|
package/build/core/report.js
CHANGED
|
@@ -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`
|
|
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;
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.renderExpoSecureStorePreviewShim = renderExpoSecureStorePreviewShim;
|
|
4
|
+
exports.renderExpoAssetPreviewShim = renderExpoAssetPreviewShim;
|
|
5
|
+
exports.renderExpoDevicePreviewShim = renderExpoDevicePreviewShim;
|
|
6
|
+
exports.renderExpoClipboardPreviewShim = renderExpoClipboardPreviewShim;
|
|
7
|
+
exports.renderExpoHapticsPreviewShim = renderExpoHapticsPreviewShim;
|
|
8
|
+
function renderExpoSecureStorePreviewShim() {
|
|
9
|
+
return `'use strict';
|
|
10
|
+
|
|
11
|
+
const secureStore = new Map();
|
|
12
|
+
|
|
13
|
+
async function isAvailableAsync() {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async function setItemAsync(key, value) {
|
|
18
|
+
secureStore.set(String(key), String(value));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async function getItemAsync(key) {
|
|
22
|
+
const normalizedKey = String(key);
|
|
23
|
+
return secureStore.has(normalizedKey) ? secureStore.get(normalizedKey) : null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async function deleteItemAsync(key) {
|
|
27
|
+
secureStore.delete(String(key));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
module.exports = {
|
|
31
|
+
AFTER_FIRST_UNLOCK: 'AFTER_FIRST_UNLOCK',
|
|
32
|
+
AFTER_FIRST_UNLOCK_THIS_DEVICE_ONLY: 'AFTER_FIRST_UNLOCK_THIS_DEVICE_ONLY',
|
|
33
|
+
ALWAYS: 'ALWAYS',
|
|
34
|
+
ALWAYS_THIS_DEVICE_ONLY: 'ALWAYS_THIS_DEVICE_ONLY',
|
|
35
|
+
WHEN_PASSCODE_SET_THIS_DEVICE_ONLY: 'WHEN_PASSCODE_SET_THIS_DEVICE_ONLY',
|
|
36
|
+
WHEN_UNLOCKED: 'WHEN_UNLOCKED',
|
|
37
|
+
WHEN_UNLOCKED_THIS_DEVICE_ONLY: 'WHEN_UNLOCKED_THIS_DEVICE_ONLY',
|
|
38
|
+
isAvailableAsync,
|
|
39
|
+
setItemAsync,
|
|
40
|
+
getItemAsync,
|
|
41
|
+
deleteItemAsync,
|
|
42
|
+
};
|
|
43
|
+
`;
|
|
44
|
+
}
|
|
45
|
+
function renderExpoAssetPreviewShim() {
|
|
46
|
+
return `'use strict';
|
|
47
|
+
|
|
48
|
+
class Asset {
|
|
49
|
+
constructor(input) {
|
|
50
|
+
this.name = input.name ?? null;
|
|
51
|
+
this.type = input.type ?? null;
|
|
52
|
+
this.hash = input.hash ?? null;
|
|
53
|
+
this.uri = input.uri;
|
|
54
|
+
this.localUri = input.localUri ?? input.uri;
|
|
55
|
+
this.width = input.width ?? null;
|
|
56
|
+
this.height = input.height ?? null;
|
|
57
|
+
this.downloaded = Boolean(input.downloaded);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
static fromURI(uri) {
|
|
61
|
+
return new Asset({
|
|
62
|
+
name: String(uri).split('/').pop() || 'remote-asset',
|
|
63
|
+
uri: String(uri),
|
|
64
|
+
downloaded: true,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
static fromModule(moduleId) {
|
|
69
|
+
if (typeof moduleId === 'string') {
|
|
70
|
+
return Asset.fromURI(moduleId);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return new Asset({
|
|
74
|
+
name: 'expo-harmony-module-asset',
|
|
75
|
+
uri: 'asset://' + String(moduleId),
|
|
76
|
+
localUri: 'asset://' + String(moduleId),
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
static async loadAsync(moduleIds) {
|
|
81
|
+
return loadAsync(moduleIds);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async downloadAsync() {
|
|
85
|
+
this.downloaded = true;
|
|
86
|
+
this.localUri = this.localUri ?? this.uri;
|
|
87
|
+
return this;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async function loadAsync(moduleIds) {
|
|
92
|
+
const input = Array.isArray(moduleIds) ? moduleIds : [moduleIds];
|
|
93
|
+
return Promise.all(input.map((moduleId) => Asset.fromModule(moduleId).downloadAsync()));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function useAssets() {
|
|
97
|
+
return [null, null];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
module.exports = {
|
|
101
|
+
Asset,
|
|
102
|
+
loadAsync,
|
|
103
|
+
useAssets,
|
|
104
|
+
};
|
|
105
|
+
`;
|
|
106
|
+
}
|
|
107
|
+
function renderExpoDevicePreviewShim() {
|
|
108
|
+
return `'use strict';
|
|
109
|
+
|
|
110
|
+
const DeviceType = {
|
|
111
|
+
UNKNOWN: 0,
|
|
112
|
+
PHONE: 1,
|
|
113
|
+
TABLET: 2,
|
|
114
|
+
DESKTOP: 3,
|
|
115
|
+
TV: 4,
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
async function getDeviceTypeAsync() {
|
|
119
|
+
return DeviceType.UNKNOWN;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
module.exports = {
|
|
123
|
+
DeviceType,
|
|
124
|
+
brand: 'OpenHarmony',
|
|
125
|
+
manufacturer: 'OpenHarmony',
|
|
126
|
+
modelName: 'Harmony preview device',
|
|
127
|
+
modelId: null,
|
|
128
|
+
designName: null,
|
|
129
|
+
productName: 'expo-harmony-preview',
|
|
130
|
+
deviceYearClass: null,
|
|
131
|
+
totalMemory: null,
|
|
132
|
+
supportedCpuArchitectures: [],
|
|
133
|
+
osName: 'HarmonyOS',
|
|
134
|
+
osVersion: 'preview',
|
|
135
|
+
osBuildId: null,
|
|
136
|
+
osInternalBuildId: null,
|
|
137
|
+
osBuildFingerprint: null,
|
|
138
|
+
platformApiLevel: null,
|
|
139
|
+
deviceName: 'Harmony preview device',
|
|
140
|
+
isDevice: true,
|
|
141
|
+
getDeviceTypeAsync,
|
|
142
|
+
};
|
|
143
|
+
`;
|
|
144
|
+
}
|
|
145
|
+
function renderExpoClipboardPreviewShim() {
|
|
146
|
+
return `'use strict';
|
|
147
|
+
|
|
148
|
+
let clipboardString = '';
|
|
149
|
+
let clipboardUrl = null;
|
|
150
|
+
let clipboardImage = null;
|
|
151
|
+
|
|
152
|
+
async function setStringAsync(value) {
|
|
153
|
+
clipboardString = String(value);
|
|
154
|
+
clipboardUrl = null;
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
async function getStringAsync() {
|
|
159
|
+
return clipboardString;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
async function hasStringAsync() {
|
|
163
|
+
return clipboardString.length > 0;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
async function setUrlAsync(value) {
|
|
167
|
+
clipboardUrl = String(value);
|
|
168
|
+
clipboardString = clipboardUrl;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
async function getUrlAsync() {
|
|
172
|
+
return clipboardUrl;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
async function setImageAsync(value) {
|
|
176
|
+
clipboardImage = String(value);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
async function getImageAsync() {
|
|
180
|
+
return clipboardImage;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
module.exports = {
|
|
184
|
+
setStringAsync,
|
|
185
|
+
getStringAsync,
|
|
186
|
+
hasStringAsync,
|
|
187
|
+
setUrlAsync,
|
|
188
|
+
getUrlAsync,
|
|
189
|
+
setImageAsync,
|
|
190
|
+
getImageAsync,
|
|
191
|
+
};
|
|
192
|
+
`;
|
|
193
|
+
}
|
|
194
|
+
function renderExpoHapticsPreviewShim() {
|
|
195
|
+
return `'use strict';
|
|
196
|
+
|
|
197
|
+
const ImpactFeedbackStyle = {
|
|
198
|
+
Light: 'light',
|
|
199
|
+
Medium: 'medium',
|
|
200
|
+
Heavy: 'heavy',
|
|
201
|
+
Rigid: 'rigid',
|
|
202
|
+
Soft: 'soft',
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
const NotificationFeedbackType = {
|
|
206
|
+
Success: 'success',
|
|
207
|
+
Warning: 'warning',
|
|
208
|
+
Error: 'error',
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
async function selectionAsync() {}
|
|
212
|
+
|
|
213
|
+
async function impactAsync() {}
|
|
214
|
+
|
|
215
|
+
async function notificationAsync() {}
|
|
216
|
+
|
|
217
|
+
module.exports = {
|
|
218
|
+
ImpactFeedbackStyle,
|
|
219
|
+
NotificationFeedbackType,
|
|
220
|
+
selectionAsync,
|
|
221
|
+
impactAsync,
|
|
222
|
+
notificationAsync,
|
|
223
|
+
};
|
|
224
|
+
`;
|
|
225
|
+
}
|
|
@@ -30,6 +30,18 @@ const EXPLORATORY_EVIDENCE_SOURCE = {
|
|
|
30
30
|
device: 'none',
|
|
31
31
|
release: 'none',
|
|
32
32
|
};
|
|
33
|
+
const APP_FOUNDATION_BASELINE_EVIDENCE = {
|
|
34
|
+
bundle: true,
|
|
35
|
+
debugBuild: true,
|
|
36
|
+
device: false,
|
|
37
|
+
release: false,
|
|
38
|
+
};
|
|
39
|
+
const APP_FOUNDATION_BASELINE_EVIDENCE_SOURCE = {
|
|
40
|
+
bundle: 'automated',
|
|
41
|
+
debugBuild: 'automated',
|
|
42
|
+
device: 'none',
|
|
43
|
+
release: 'none',
|
|
44
|
+
};
|
|
33
45
|
exports.CAPABILITY_DEFINITIONS = [
|
|
34
46
|
{
|
|
35
47
|
id: 'expo-file-system',
|
|
@@ -116,6 +128,101 @@ exports.CAPABILITY_DEFINITIONS = [
|
|
|
116
128
|
'Exercise preview pause/resume plus denied or canceled outcomes without crashing the Harmony runtime.',
|
|
117
129
|
],
|
|
118
130
|
},
|
|
131
|
+
{
|
|
132
|
+
id: 'expo-secure-store',
|
|
133
|
+
packageName: 'expo-secure-store',
|
|
134
|
+
status: 'manual',
|
|
135
|
+
supportTier: 'preview',
|
|
136
|
+
runtimeMode: 'shim',
|
|
137
|
+
evidence: APP_FOUNDATION_BASELINE_EVIDENCE,
|
|
138
|
+
evidenceSource: APP_FOUNDATION_BASELINE_EVIDENCE_SOURCE,
|
|
139
|
+
note: 'v1.9.0 app-foundation baseline provides a toolkit-managed session shim for secure-store API shape, keeping real encrypted Harmony storage on the promotion path before verified release parity.',
|
|
140
|
+
docsUrl: 'https://docs.expo.dev/versions/latest/sdk/securestore/',
|
|
141
|
+
nativePackageNames: [],
|
|
142
|
+
harmonyPermissions: [],
|
|
143
|
+
sampleRoute: '/secure-store',
|
|
144
|
+
acceptanceChecklist: [
|
|
145
|
+
'Write a sample key with setItemAsync and read it back in the same JS session.',
|
|
146
|
+
'Delete the sample key and verify getItemAsync returns null.',
|
|
147
|
+
'Keep device persistence and encrypted backend behavior out of verified until native evidence is recorded.',
|
|
148
|
+
],
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
id: 'expo-asset',
|
|
152
|
+
packageName: 'expo-asset',
|
|
153
|
+
status: 'manual',
|
|
154
|
+
supportTier: 'preview',
|
|
155
|
+
runtimeMode: 'shim',
|
|
156
|
+
evidence: APP_FOUNDATION_BASELINE_EVIDENCE,
|
|
157
|
+
evidenceSource: APP_FOUNDATION_BASELINE_EVIDENCE_SOURCE,
|
|
158
|
+
note: 'v1.9.0 app-foundation baseline keeps the Asset API bundle-safe on Harmony while native asset resolution and cache semantics remain promotion evidence.',
|
|
159
|
+
docsUrl: 'https://docs.expo.dev/versions/latest/sdk/asset/',
|
|
160
|
+
nativePackageNames: [],
|
|
161
|
+
harmonyPermissions: [],
|
|
162
|
+
sampleRoute: '/asset',
|
|
163
|
+
acceptanceChecklist: [
|
|
164
|
+
'Create an Asset from a URI and expose deterministic metadata.',
|
|
165
|
+
'Resolve loadAsync for one or more module identifiers without crashing the Harmony bundle.',
|
|
166
|
+
'Keep native resource resolution and cache parity pending device and release evidence.',
|
|
167
|
+
],
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
id: 'expo-device',
|
|
171
|
+
packageName: 'expo-device',
|
|
172
|
+
status: 'manual',
|
|
173
|
+
supportTier: 'preview',
|
|
174
|
+
runtimeMode: 'shim',
|
|
175
|
+
evidence: APP_FOUNDATION_BASELINE_EVIDENCE,
|
|
176
|
+
evidenceSource: APP_FOUNDATION_BASELINE_EVIDENCE_SOURCE,
|
|
177
|
+
note: 'v1.9.0 app-foundation baseline exposes stable Harmony placeholder device metadata for JS startup paths; real hardware metadata remains outside verified.',
|
|
178
|
+
docsUrl: 'https://docs.expo.dev/versions/latest/sdk/device/',
|
|
179
|
+
nativePackageNames: [],
|
|
180
|
+
harmonyPermissions: [],
|
|
181
|
+
sampleRoute: '/device',
|
|
182
|
+
acceptanceChecklist: [
|
|
183
|
+
'Read stable device metadata constants without native module crashes.',
|
|
184
|
+
'Resolve getDeviceTypeAsync with an explicit preview value.',
|
|
185
|
+
'Record real hardware metadata behavior separately before promotion.',
|
|
186
|
+
],
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
id: 'expo-clipboard',
|
|
190
|
+
packageName: 'expo-clipboard',
|
|
191
|
+
status: 'manual',
|
|
192
|
+
supportTier: 'preview',
|
|
193
|
+
runtimeMode: 'shim',
|
|
194
|
+
evidence: APP_FOUNDATION_BASELINE_EVIDENCE,
|
|
195
|
+
evidenceSource: APP_FOUNDATION_BASELINE_EVIDENCE_SOURCE,
|
|
196
|
+
note: 'v1.9.0 app-foundation baseline keeps clipboard reads and writes bundle-safe through a session shim while the Harmony clipboard adapter remains the native promotion path.',
|
|
197
|
+
docsUrl: 'https://docs.expo.dev/versions/latest/sdk/clipboard/',
|
|
198
|
+
nativePackageNames: ['@react-native-oh-tpl/clipboard'],
|
|
199
|
+
harmonyPermissions: [],
|
|
200
|
+
sampleRoute: '/clipboard',
|
|
201
|
+
acceptanceChecklist: [
|
|
202
|
+
'Write a string through setStringAsync and read it back with getStringAsync.',
|
|
203
|
+
'Expose hasStringAsync and URL helpers without crashing app-shell startup.',
|
|
204
|
+
'Validate real system pasteboard behavior on device before verified promotion.',
|
|
205
|
+
],
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
id: 'expo-haptics',
|
|
209
|
+
packageName: 'expo-haptics',
|
|
210
|
+
status: 'manual',
|
|
211
|
+
supportTier: 'preview',
|
|
212
|
+
runtimeMode: 'shim',
|
|
213
|
+
evidence: APP_FOUNDATION_BASELINE_EVIDENCE,
|
|
214
|
+
evidenceSource: APP_FOUNDATION_BASELINE_EVIDENCE_SOURCE,
|
|
215
|
+
note: 'v1.9.0 app-foundation baseline makes haptics calls no-op safely on Harmony until a real device vibration path is validated.',
|
|
216
|
+
docsUrl: 'https://docs.expo.dev/versions/latest/sdk/haptics/',
|
|
217
|
+
nativePackageNames: [],
|
|
218
|
+
harmonyPermissions: [],
|
|
219
|
+
sampleRoute: '/haptics',
|
|
220
|
+
acceptanceChecklist: [
|
|
221
|
+
'Resolve selectionAsync, impactAsync, and notificationAsync without throwing.',
|
|
222
|
+
'Expose Expo haptics enum values used by common app startup paths.',
|
|
223
|
+
'Keep physical haptic feedback pending device evidence.',
|
|
224
|
+
],
|
|
225
|
+
},
|
|
119
226
|
{
|
|
120
227
|
id: 'expo-notifications',
|
|
121
228
|
packageName: 'expo-notifications',
|
|
@@ -135,6 +242,25 @@ exports.CAPABILITY_DEFINITIONS = [
|
|
|
135
242
|
'Validate open-from-notification lifecycle.',
|
|
136
243
|
],
|
|
137
244
|
},
|
|
245
|
+
{
|
|
246
|
+
id: 'react-native-gesture-handler',
|
|
247
|
+
packageName: 'react-native-gesture-handler',
|
|
248
|
+
status: 'manual',
|
|
249
|
+
supportTier: 'experimental',
|
|
250
|
+
runtimeMode: 'adapter',
|
|
251
|
+
evidence: APP_FOUNDATION_BASELINE_EVIDENCE,
|
|
252
|
+
evidenceSource: APP_FOUNDATION_BASELINE_EVIDENCE_SOURCE,
|
|
253
|
+
note: 'v1.9.0 formal acceptance slice tracks Gesture Handler through its Harmony adapter, but it remains experimental until device and release runtime evidence are closed.',
|
|
254
|
+
docsUrl: 'https://github.com/react-native-oh-library/react-native-harmony-gesture-handler',
|
|
255
|
+
nativePackageNames: ['@react-native-oh-tpl/react-native-gesture-handler'],
|
|
256
|
+
harmonyPermissions: [],
|
|
257
|
+
sampleRoute: '/gesture-handler',
|
|
258
|
+
acceptanceChecklist: [
|
|
259
|
+
'Install the canonical package with the matching Harmony adapter.',
|
|
260
|
+
'Bundle a minimal GestureHandlerRootView and tap handler surface.',
|
|
261
|
+
'Record debug HAP evidence before any promotion decision; device and release remain separate gates.',
|
|
262
|
+
],
|
|
263
|
+
},
|
|
138
264
|
];
|
|
139
265
|
exports.CAPABILITY_BY_PACKAGE = Object.fromEntries(exports.CAPABILITY_DEFINITIONS.map((definition) => [definition.packageName, definition]));
|
|
140
266
|
const SUPPORT_TIER_ORDER = {
|
|
@@ -112,8 +112,8 @@ exports.DEPENDENCY_CATALOG = {
|
|
|
112
112
|
},
|
|
113
113
|
'expo-asset': {
|
|
114
114
|
status: 'manual',
|
|
115
|
-
supportTier: '
|
|
116
|
-
note: 'Asset
|
|
115
|
+
supportTier: 'preview',
|
|
116
|
+
note: 'v1.9.0 app-foundation baseline keeps Asset API imports and load paths bundle-safe through the toolkit shim; native asset cache parity still needs device and release evidence.',
|
|
117
117
|
},
|
|
118
118
|
'expo-build-properties': {
|
|
119
119
|
status: 'manual',
|
|
@@ -242,10 +242,15 @@ exports.DEPENDENCY_CATALOG = {
|
|
|
242
242
|
},
|
|
243
243
|
'expo-clipboard': {
|
|
244
244
|
status: 'manual',
|
|
245
|
-
supportTier: '
|
|
246
|
-
note: '
|
|
245
|
+
supportTier: 'preview',
|
|
246
|
+
note: 'v1.9.0 app-foundation baseline provides a session clipboard shim and keeps the Harmony clipboard adapter as the native promotion path.',
|
|
247
247
|
replacement: '@react-native-oh-tpl/clipboard',
|
|
248
248
|
},
|
|
249
|
+
'expo-device': {
|
|
250
|
+
status: 'manual',
|
|
251
|
+
supportTier: 'preview',
|
|
252
|
+
note: 'v1.9.0 app-foundation baseline exposes stable Harmony placeholder device metadata while real hardware metadata remains promotion evidence.',
|
|
253
|
+
},
|
|
249
254
|
'expo-dev-client': {
|
|
250
255
|
status: 'manual',
|
|
251
256
|
supportTier: 'experimental',
|
|
@@ -258,8 +263,8 @@ exports.DEPENDENCY_CATALOG = {
|
|
|
258
263
|
},
|
|
259
264
|
'expo-haptics': {
|
|
260
265
|
status: 'manual',
|
|
261
|
-
supportTier: '
|
|
262
|
-
note: '
|
|
266
|
+
supportTier: 'preview',
|
|
267
|
+
note: 'v1.9.0 app-foundation baseline turns haptics calls into safe no-ops until a real Harmony device feedback path is validated.',
|
|
263
268
|
},
|
|
264
269
|
'expo-image': {
|
|
265
270
|
status: 'manual',
|
|
@@ -289,8 +294,8 @@ exports.DEPENDENCY_CATALOG = {
|
|
|
289
294
|
},
|
|
290
295
|
'expo-secure-store': {
|
|
291
296
|
status: 'manual',
|
|
292
|
-
supportTier: '
|
|
293
|
-
note: '
|
|
297
|
+
supportTier: 'preview',
|
|
298
|
+
note: 'v1.9.0 app-foundation baseline provides a session secure-store shim; encrypted persistence still needs native device and release evidence.',
|
|
294
299
|
},
|
|
295
300
|
'expo-splash-screen': {
|
|
296
301
|
status: 'manual',
|
|
@@ -7,5 +7,5 @@ export declare const PREVIEW_SAMPLE_PATH = "examples/official-native-capabilitie
|
|
|
7
7
|
export declare const SUPPORTING_SAMPLE_PATHS: readonly ["examples/official-app-shell-sample", "examples/official-minimal-sample"];
|
|
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
|
-
export declare const EXPERIMENTAL_CAPABILITY_NAMES: readonly
|
|
11
|
-
export declare const PUBLIC_CURRENT_VERSION = "1.
|
|
10
|
+
export declare const EXPERIMENTAL_CAPABILITY_NAMES: readonly string[];
|
|
11
|
+
export declare const PUBLIC_CURRENT_VERSION = "1.9.0";
|
package/build/data/publicDocs.js
CHANGED
|
@@ -22,7 +22,6 @@ exports.VERIFIED_JS_UI_CAPABILITY_NAMES = [
|
|
|
22
22
|
];
|
|
23
23
|
exports.PREVIEW_CAPABILITY_DEFINITIONS = capabilities_1.CAPABILITY_DEFINITIONS.filter((definition) => definition.supportTier === 'preview');
|
|
24
24
|
exports.EXPERIMENTAL_CAPABILITY_NAMES = [
|
|
25
|
-
...capabilities_1.CAPABILITY_DEFINITIONS.filter((definition) => definition.supportTier === 'experimental').map((definition) => definition.packageName),
|
|
26
|
-
'react-native-gesture-handler',
|
|
25
|
+
...new Set(capabilities_1.CAPABILITY_DEFINITIONS.filter((definition) => definition.supportTier === 'experimental').map((definition) => definition.packageName)),
|
|
27
26
|
];
|
|
28
27
|
exports.PUBLIC_CURRENT_VERSION = constants_1.TOOLKIT_VERSION;
|
|
@@ -63,11 +63,11 @@ exports.VALIDATED_RELEASE_MATRICES = {
|
|
|
63
63
|
},
|
|
64
64
|
'@react-native-oh/react-native-harmony': {
|
|
65
65
|
required: true,
|
|
66
|
-
version: '0.82.
|
|
66
|
+
version: '0.82.29',
|
|
67
67
|
},
|
|
68
68
|
'@react-native-oh/react-native-harmony-cli': {
|
|
69
69
|
required: true,
|
|
70
|
-
version: '0.82.
|
|
70
|
+
version: '0.82.29',
|
|
71
71
|
},
|
|
72
72
|
'@react-native-community/cli': {
|
|
73
73
|
required: true,
|
package/build/docs/render.js
CHANGED
|
@@ -32,7 +32,9 @@ function renderReadmeCurrentStatus(locale) {
|
|
|
32
32
|
const releaseTracksValue = locale === 'zh'
|
|
33
33
|
? `\`latest\` = ${publicDocs_1.PUBLIC_RELEASE_TRACKS.latest};\`next\` = ${publicDocs_1.PUBLIC_RELEASE_TRACKS.next}`
|
|
34
34
|
: `\`latest\` = fully accepted \`verified\` only; \`next\` = ${publicDocs_1.PUBLIC_RELEASE_TRACKS.next}`;
|
|
35
|
-
const inputValue = locale === 'zh'
|
|
35
|
+
const inputValue = locale === 'zh'
|
|
36
|
+
? 'Managed/CNG Expo 项目;bare workflow intake baseline'
|
|
37
|
+
: 'Managed/CNG Expo projects; bare workflow intake baseline';
|
|
36
38
|
const listJoiner = locale === 'zh' ? '、' : ', ';
|
|
37
39
|
return [
|
|
38
40
|
`| ${headers[0]} | ${headers[1]} |`,
|
package/docs/cli-build.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# CLI 构建指南
|
|
2
2
|
|
|
3
|
-
`v1.
|
|
3
|
+
`v1.9.0` 延续 `verified + preview + experimental` 支持分层,把 bare workflow 放进 intake baseline,并把五个 app foundation modules 纳入 preview shim baseline;`expo55-rnoh082-ui-stack` 仍是唯一 verified 矩阵。
|
|
4
4
|
|
|
5
5
|
CLI 命令集合不变:
|
|
6
6
|
|
|
@@ -39,6 +39,15 @@ expo-harmony build-hap --mode debug
|
|
|
39
39
|
- `expo-image-picker`
|
|
40
40
|
- `expo-location`
|
|
41
41
|
- `expo-camera`
|
|
42
|
+
- `expo-secure-store`
|
|
43
|
+
- `expo-asset`
|
|
44
|
+
- `expo-device`
|
|
45
|
+
- `expo-clipboard`
|
|
46
|
+
- `expo-haptics`
|
|
47
|
+
|
|
48
|
+
当前 experimental formal slice:
|
|
49
|
+
|
|
50
|
+
- `react-native-gesture-handler`
|
|
42
51
|
|
|
43
52
|
## UI stack 依赖安装注意事项
|
|
44
53
|
|
|
@@ -81,8 +90,9 @@ pnpm install --ignore-scripts
|
|
|
81
90
|
|
|
82
91
|
额外说明:
|
|
83
92
|
|
|
84
|
-
- `react-native-gesture-handler`
|
|
85
|
-
-
|
|
93
|
+
- `react-native-gesture-handler` 已进入 formal experimental slice,但仍不属于 verified 公开承诺
|
|
94
|
+
- bare workflow 当前只有 intake / debug baseline,不代表 release-ready
|
|
95
|
+
- `doctor --strict` 仍只代表完整验收的 verified 能力
|
|
86
96
|
|
|
87
97
|
toolkit 不会改动用户业务路由、动画逻辑或页面源码;它只负责受管 sidecar、构建链和 metadata。
|
|
88
98
|
|
package/docs/npm-release.md
CHANGED
|
@@ -61,6 +61,7 @@ pnpm release:check
|
|
|
61
61
|
- hosted CI 默认仍可通过 `EXPO_HARMONY_RELEASE_SKIP_HAP=1` 跳过真实 DevEco HAP 构建
|
|
62
62
|
- debug / release HAP gate 继续由 capability acceptance、带工具链环境的 CI 或本地验收补齐
|
|
63
63
|
- `v1.8.2` 已补一条 ccnubox release HAP 的本地签名、模拟器安装与启动记录;该记录不替代真机 device acceptance,也不把 preview capability 标为 release-ready
|
|
64
|
+
- `v1.8.3` 只刷新 RNOH runtime / CLI 到 `0.82.29`,仍不宣称 RN `0.83.x` 已进入公开 Harmony 矩阵
|
|
64
65
|
- preview capability 若在报告里显示 `device=yes`,必须同时以 `evidenceSource.device=manual-doc` 对外说明其来源,不得表述成 CI 自动设备验证
|
|
65
66
|
|
|
66
67
|
## 手动发布
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
路径:`examples/official-native-capabilities-sample`
|
|
4
4
|
|
|
5
|
-
这个 sample
|
|
5
|
+
这个 sample 是官方 preview native-capability 与 `v1.9.0` app-foundation walkthrough。它的目标不是把 preview 能力包装成 `verified`,而是把当前真实可承诺的 `🟡` 子集和 foundation shim baseline 集中演示出来,并把 preview 边界收敛到真机 / release 证据,而不是接口缺口。
|
|
6
6
|
|
|
7
7
|
从 `v1.8.x` 开始,这个 sample 的角色会固定成两层:
|
|
8
8
|
|
|
@@ -19,6 +19,11 @@
|
|
|
19
19
|
- `expo-image-picker`
|
|
20
20
|
- `expo-location`
|
|
21
21
|
- `expo-camera`
|
|
22
|
+
- `expo-secure-store`
|
|
23
|
+
- `expo-asset`
|
|
24
|
+
- `expo-device`
|
|
25
|
+
- `expo-clipboard`
|
|
26
|
+
- `expo-haptics`
|
|
22
27
|
|
|
23
28
|
当前 route:
|
|
24
29
|
|
|
@@ -26,6 +31,11 @@
|
|
|
26
31
|
- `/image-picker`
|
|
27
32
|
- `/location`
|
|
28
33
|
- `/camera`
|
|
34
|
+
- `/secure-store`
|
|
35
|
+
- `/asset`
|
|
36
|
+
- `/device`
|
|
37
|
+
- `/clipboard`
|
|
38
|
+
- `/haptics`
|
|
29
39
|
|
|
30
40
|
对应的逐 capability 追踪板见:
|
|
31
41
|
|
|
@@ -88,6 +98,51 @@
|
|
|
88
98
|
- microphone permission snapshot
|
|
89
99
|
- denied / canceled / successful result 展示
|
|
90
100
|
|
|
101
|
+
### `/secure-store`
|
|
102
|
+
|
|
103
|
+
`🟡 v1.9 app-foundation baseline`:
|
|
104
|
+
|
|
105
|
+
- `isAvailableAsync`
|
|
106
|
+
- session-scoped `setItemAsync`
|
|
107
|
+
- session-scoped `getItemAsync`
|
|
108
|
+
- `deleteItemAsync`
|
|
109
|
+
- encrypted persistence、keychain / keystore 等真实 native 后端仍待 device / release evidence
|
|
110
|
+
|
|
111
|
+
### `/asset`
|
|
112
|
+
|
|
113
|
+
`🟡 v1.9 app-foundation baseline`:
|
|
114
|
+
|
|
115
|
+
- `Asset.fromURI`
|
|
116
|
+
- `Asset.loadAsync`
|
|
117
|
+
- deterministic metadata display
|
|
118
|
+
- native resource resolution、asset cache parity 仍待 device / release evidence
|
|
119
|
+
|
|
120
|
+
### `/device`
|
|
121
|
+
|
|
122
|
+
`🟡 v1.9 app-foundation baseline`:
|
|
123
|
+
|
|
124
|
+
- stable Harmony placeholder metadata
|
|
125
|
+
- `getDeviceTypeAsync`
|
|
126
|
+
- real device model/build/hardware metadata 仍待 device / release evidence
|
|
127
|
+
|
|
128
|
+
### `/clipboard`
|
|
129
|
+
|
|
130
|
+
`🟡 v1.9 app-foundation baseline`:
|
|
131
|
+
|
|
132
|
+
- session-scoped string write/read
|
|
133
|
+
- `hasStringAsync`
|
|
134
|
+
- URL helper roundtrip
|
|
135
|
+
- real system pasteboard behavior 仍待 Harmony adapter evidence
|
|
136
|
+
|
|
137
|
+
### `/haptics`
|
|
138
|
+
|
|
139
|
+
`🟡 v1.9 app-foundation baseline`:
|
|
140
|
+
|
|
141
|
+
- `selectionAsync`
|
|
142
|
+
- `impactAsync`
|
|
143
|
+
- `notificationAsync`
|
|
144
|
+
- 当前为 no-op-safe shim;真实物理反馈仍待 device evidence
|
|
145
|
+
|
|
91
146
|
## 推荐命令
|
|
92
147
|
|
|
93
148
|
```bash
|
|
@@ -134,5 +189,5 @@ pnpm run harmony:build:release
|
|
|
134
189
|
|
|
135
190
|
- 这个 sample 属于 `preview` 主线,不等于已经进入 `verified`
|
|
136
191
|
- `doctor-report.json` 与 `toolkit-config.json` 中的 `runtimeMode` / `evidence.*` 会如实反映这些能力距离 verified 还缺哪些证据
|
|
137
|
-
-
|
|
192
|
+
- 当前重点是“bundle/debug baseline 可重复、核心流清楚、文档一致”
|
|
138
193
|
- 等未来补齐真机 gate 后,才讨论 capability promotion
|
package/docs/roadmap.md
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
- 所有 Expo project types 与 package categories,最终都进入同一条 `mainline capability catalog`
|
|
8
8
|
- `v2.0.0` 本身就要接近最完美、最最终的交付形态,而不是“还差最后一段 extension”
|
|
9
|
+
- `v2.0.0` 的可靠打包承诺收敛为 catalog-covered Expo projects:只要依赖已经进入主线 capability catalog,就必须稳定闭环
|
|
9
10
|
- 公开承诺仍然按 evidence gate 逐步放开,而不是因为目标扩大就提前放宽 `latest`
|
|
10
11
|
- `latest` 继续只承接完整验收的 `verified`
|
|
11
12
|
- `next` 继续承接 fast track,用来加速收敛,但不伪装成 `verified`
|
|
@@ -65,6 +66,8 @@
|
|
|
65
66
|
|
|
66
67
|
## 当前主线
|
|
67
68
|
|
|
69
|
+
`v1.8.x` 已完成 repo 内可收口项,当前主线切到 `v1.9.x`。`v1.9.0` 先落 bare workflow baseline、app foundation modules 与 `react-native-gesture-handler` formal slice;剩余需要真机或 release HAP 的证据继续保留在 v1.8.x capability board,不阻塞 v1.9.x 的 bare / foundation / third-party onboarding 工作。
|
|
70
|
+
|
|
68
71
|
### v1.8.0 Intake Hardening + Parallel Promotion
|
|
69
72
|
|
|
70
73
|
目标日期:`2026-05-15`
|
|
@@ -98,7 +101,9 @@
|
|
|
98
101
|
|
|
99
102
|
目标日期:`2026-06-15`
|
|
100
103
|
|
|
101
|
-
|
|
104
|
+
状态:repo-only closeout complete;device / release evidence carryover。
|
|
105
|
+
|
|
106
|
+
目标:把 v1.8.0 建好的 intake + promotion 架子收口到可持续执行的证据节奏,并把外部验收项从 repo 内可完成项中拆开。
|
|
102
107
|
|
|
103
108
|
- 每个 preview capability 必须单独维护:
|
|
104
109
|
- bundle evidence
|
|
@@ -108,12 +113,18 @@
|
|
|
108
113
|
- combined sample 只负责回归烟测,不再替代单 capability 证据
|
|
109
114
|
- `toolkit-config.json`、`doctor-report.json`、roadmap、support matrix、acceptance board 保持同源同步
|
|
110
115
|
- `latest` 仍不承接任何证据未闭环的 capability
|
|
116
|
+
- 不需要真机或 release HAP 的收尾项已经完成,可以进入 `v1.9.x`
|
|
117
|
+
- 仍然顺延的外部证据:
|
|
118
|
+
- 单 capability 真机 device acceptance record
|
|
119
|
+
- 单 capability release HAP runtime acceptance
|
|
111
120
|
|
|
112
121
|
### v1.9.0 Bare Workflow Baseline + App Foundation Modules
|
|
113
122
|
|
|
114
123
|
目标日期:`2026-08-31`
|
|
115
124
|
|
|
116
|
-
|
|
125
|
+
状态:implementation baseline complete;device / release evidence carryover。
|
|
126
|
+
|
|
127
|
+
目标:把 bare workflow 拉进主线,补齐最容易卡死真实项目的官方基础模块,并先建立第三方 blocker 的正式接入切片。
|
|
117
128
|
|
|
118
129
|
- bare workflow 正式进入主线里程碑
|
|
119
130
|
- 优先补齐:
|
|
@@ -123,6 +134,15 @@
|
|
|
123
134
|
- `expo-clipboard`
|
|
124
135
|
- `expo-haptics`
|
|
125
136
|
- 高频第三方 native dependencies 开始进入同一 capability catalog
|
|
137
|
+
- `react-native-gesture-handler` 进入 formal acceptance slice:
|
|
138
|
+
- 保留 experimental / non-verified 边界
|
|
139
|
+
- 补齐 sample / fixture / doctor / debug build evidence
|
|
140
|
+
- device / release evidence 仍按 promotion gate 单独关闭
|
|
141
|
+
- project-shape regression farm 建立最小版本:
|
|
142
|
+
- managed core
|
|
143
|
+
- managed native heavy
|
|
144
|
+
- bare
|
|
145
|
+
- third-party native heavy
|
|
126
146
|
- 对每个新能力继续坚持:
|
|
127
147
|
- fixture
|
|
128
148
|
- sample route
|
|
@@ -131,6 +151,7 @@
|
|
|
131
151
|
- bundle
|
|
132
152
|
- debug build
|
|
133
153
|
- acceptance 记录
|
|
154
|
+
- 本阶段不改变 `verified` 边界;foundation modules 以 `preview` + `runtimeMode=shim` 记录,`react-native-gesture-handler` 以 `experimental` + formal adapter slice 记录
|
|
134
155
|
|
|
135
156
|
### v1.9.1 Third-party Native Wave A
|
|
136
157
|
|
|
@@ -139,10 +160,10 @@
|
|
|
139
160
|
目标:优先清掉最容易挡住“任何 Expo 项目”的高频第三方 native blocker。
|
|
140
161
|
|
|
141
162
|
- 第一批高频第三方 native blocker 进入正式 onboarding:
|
|
142
|
-
- `react-native-gesture-handler`
|
|
143
163
|
- `react-native-safe-area-context`
|
|
144
164
|
- `react-native-screens`
|
|
145
165
|
- `@react-native-async-storage/async-storage`
|
|
166
|
+
- `react-native-gesture-handler` 如果在 `v1.9.0` 已完成 formal acceptance slice,则本阶段只继续补 device / release evidence 与 promotion 决策
|
|
146
167
|
- 建立第三方 native capability onboarding checklist:
|
|
147
168
|
- catalog entry
|
|
148
169
|
- shim / adapter strategy
|
|
@@ -155,10 +176,10 @@
|
|
|
155
176
|
|
|
156
177
|
目标日期:`2026-10-31`
|
|
157
178
|
|
|
158
|
-
目标:扩大第三方 native
|
|
179
|
+
目标:扩大第三方 native 覆盖,并把 `v1.9.0` 建好的最小 regression farm 扩容成持续回归面。
|
|
159
180
|
|
|
160
181
|
- 第二批高频第三方 native 依赖进入主线
|
|
161
|
-
-
|
|
182
|
+
- 扩容 project-shape regression farm:
|
|
162
183
|
- managed core
|
|
163
184
|
- managed native heavy
|
|
164
185
|
- bare
|
|
@@ -193,13 +214,16 @@
|
|
|
193
214
|
- 对仍无法在 `v2.0.0` 前关闭的项,必须提前明确降级策略与替代路径
|
|
194
215
|
- `v2.0.0` 不接受“先宣布完成,再慢慢补长尾”
|
|
195
216
|
|
|
196
|
-
### v2.0.0
|
|
217
|
+
### v2.0.0 Catalog-covered Expo Project Reliable Packaging
|
|
218
|
+
|
|
219
|
+
原 `Any Expo Project Reliable Packaging` 叙事保留为 intake 目标,但可靠打包承诺明确收敛到 catalog-covered 项目。
|
|
197
220
|
|
|
198
221
|
目标日期:`2026-12-31`
|
|
199
222
|
|
|
200
|
-
定义:任何 Expo 项目,只要依赖已经存在于主线 capability catalog 内,就能可靠打包成鸿蒙 App
|
|
223
|
+
定义:任何 Expo 项目,只要依赖已经存在于主线 capability catalog 内,就能可靠打包成鸿蒙 App;未进入 catalog 的依赖必须至少被 `doctor` 明确分类、指出 blocker,并给出下一步。`v2.0.0` 本身就是基本接近最完美、最最终的形态。
|
|
201
224
|
|
|
202
|
-
-
|
|
225
|
+
- 不再只覆盖“主流项目”,而是把 catalog-covered Expo projects 的可靠打包作为正式版本定义
|
|
226
|
+
- “任何 Expo 项目都能可靠打包成鸿蒙 App”不得被简化成无边界长尾承诺;真实承诺边界是 mainline capability catalog
|
|
203
227
|
- `Managed/CNG` 与 bare workflow 都必须进入稳定交付路径
|
|
204
228
|
- 高频官方 Expo 模块与高频第三方 native blockers 必须已经进入同一公开 capability catalog
|
|
205
229
|
- `doctor -> sync-template -> bundle -> build-hap --mode debug|release` 必须对主线 catalog 内项目形成稳定闭环
|
|
@@ -208,7 +232,8 @@
|
|
|
208
232
|
## 长期方向
|
|
209
233
|
|
|
210
234
|
- 所有输入最终都进入同一个 `mainline capability catalog`
|
|
211
|
-
- `v2.0.0`
|
|
235
|
+
- `v2.0.0` 就是 catalog-covered Expo projects 可靠打包成鸿蒙 App 的正式目标版本
|
|
236
|
+
- 对 catalog 外项目,正式目标是完整 intake:能分类、能说明 blocker、能给下一步,而不是伪装成已经可靠打包
|
|
212
237
|
- `latest` 只由完整验收能力驱动
|
|
213
238
|
- `next` 用来加速收敛主线 backlog,而不是制造伪 verified 叙事
|
|
214
239
|
- roadmap 的关键问题不再是“要不要把某类项目算进主线”,而是“它何时进入主线、当前缺哪格 evidence、下一步怎么 unblock”
|
|
@@ -94,6 +94,10 @@ expo-harmony build-hap --mode release
|
|
|
94
94
|
|
|
95
95
|
这条记录只说明 release HAP 的本地签名、安装、启动链路可走通。它不代表 AppGallery 生产签名、不代表真机通过,也不关闭 preview capability 的 release runtime acceptance。
|
|
96
96
|
|
|
97
|
+
## v1.8.3 矩阵 patch 说明
|
|
98
|
+
|
|
99
|
+
`v1.8.3` 将 RNOH runtime 与 CLI 从 `0.82.18` 刷新到 `0.82.29`。npm 上当前仍没有可用的 RNOH `0.83.x` 包,因此公开矩阵继续要求 `react-native@0.82.1`;下游项目如需 Harmony build-chain,应按该矩阵锁定 React Native,而不是把模拟器构建证据扩写成 RN `0.83.x` verified。
|
|
100
|
+
|
|
97
101
|
## 关系说明
|
|
98
102
|
|
|
99
103
|
- `doctor --strict` 负责项目是否落入公开矩阵
|
package/docs/support-matrix.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# v1.
|
|
1
|
+
# v1.9 支持矩阵
|
|
2
2
|
|
|
3
|
-
`v1.
|
|
3
|
+
`v1.9` 继续采用 tiered support model,并把“层级”与“晋升距离”拆开表达:
|
|
4
4
|
|
|
5
5
|
- `supportTier` 表示公开承诺层级
|
|
6
6
|
- `runtimeMode` 表示当前运行时接入形态:`shim`、`adapter`、`verified`
|
|
@@ -9,11 +9,12 @@
|
|
|
9
9
|
- `coverageProfile` 表示当前项目属于哪条主线输入形态
|
|
10
10
|
- `nextActions` 表示 toolkit 为当前项目生成的有序下一步
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
同时,roadmap 已经改成单一 `mainline capability catalog` 方向:
|
|
13
13
|
|
|
14
14
|
- bare workflow 与第三方 native package 不再被描述成“收官后才考虑的另一条 extension 终局”
|
|
15
15
|
- `v2.0.0` 本身被定义成“任何 Expo 项目都能可靠打包成鸿蒙 App”的目标版本
|
|
16
16
|
- 但当前公开承诺依旧没有放宽;它们只是进入同一主线 backlog,而不是已经进入 `verified`
|
|
17
|
+
- `v1.9.0` 新增的是 bare intake baseline、app foundation preview shim baseline 与 `react-native-gesture-handler` formal experimental slice,不是 verified 扩容
|
|
17
18
|
|
|
18
19
|
`doctor --strict` 继续只代表 `verified`。
|
|
19
20
|
|
|
@@ -27,8 +28,8 @@
|
|
|
27
28
|
| Expo SDK | `55` |
|
|
28
29
|
| React | `19.1.1` |
|
|
29
30
|
| React Native | `0.82.1` |
|
|
30
|
-
| `@react-native-oh/react-native-harmony` | `0.82.
|
|
31
|
-
| `@react-native-oh/react-native-harmony-cli` | `0.82.
|
|
31
|
+
| `@react-native-oh/react-native-harmony` | `0.82.29` |
|
|
32
|
+
| `@react-native-oh/react-native-harmony-cli` | `0.82.29` |
|
|
32
33
|
| `@react-native-community/cli` | `20.x` |
|
|
33
34
|
| `metro` | `0.83.x` |
|
|
34
35
|
| App Shell 依赖 | `expo-router` `55.x`、`expo-linking` `55.x`、`expo-constants` `55.x`、`@expo/metro-runtime` `55.x`、`react-dom` `19.1.1` |
|
|
@@ -106,15 +107,22 @@
|
|
|
106
107
|
| `expo-image-picker` | `preview` | `adapter` | `bundle=yes[automated], debugBuild=yes[automated], device=yes[manual-doc], release=no[none]` | react-native-image-picker, react-native-permissions | ohos.permission.CAMERA、ohos.permission.MICROPHONE、ohos.permission.READ_IMAGEVIDEO | `/image-picker` |
|
|
107
108
|
| `expo-location` | `preview` | `adapter` | `bundle=yes[automated], debugBuild=yes[automated], device=yes[manual-doc], release=no[none]` | @react-native-community/geolocation, react-native-permissions | ohos.permission.LOCATION、ohos.permission.APPROXIMATELY_LOCATION、ohos.permission.LOCATION_IN_BACKGROUND、ohos.permission.ACCELEROMETER | `/location` |
|
|
108
109
|
| `expo-camera` | `preview` | `adapter` | `bundle=yes[automated], debugBuild=yes[automated], device=yes[manual-doc], release=no[none]` | react-native-camera-kit, react-native-permissions | ohos.permission.CAMERA、ohos.permission.MICROPHONE | `/camera` |
|
|
110
|
+
| `expo-secure-store` | `preview` | `shim` | `bundle=yes[automated], debugBuild=yes[automated], device=no[none], release=no[none]` | toolkit-managed bridge | 无新增必需权限 | `/secure-store` |
|
|
111
|
+
| `expo-asset` | `preview` | `shim` | `bundle=yes[automated], debugBuild=yes[automated], device=no[none], release=no[none]` | toolkit-managed bridge | 无新增必需权限 | `/asset` |
|
|
112
|
+
| `expo-device` | `preview` | `shim` | `bundle=yes[automated], debugBuild=yes[automated], device=no[none], release=no[none]` | toolkit-managed bridge | 无新增必需权限 | `/device` |
|
|
113
|
+
| `expo-clipboard` | `preview` | `shim` | `bundle=yes[automated], debugBuild=yes[automated], device=no[none], release=no[none]` | @react-native-oh-tpl/clipboard | 无新增必需权限 | `/clipboard` |
|
|
114
|
+
| `expo-haptics` | `preview` | `shim` | `bundle=yes[automated], debugBuild=yes[automated], device=no[none], release=no[none]` | toolkit-managed bridge | 无新增必需权限 | `/haptics` |
|
|
109
115
|
<!-- GENERATED:support-matrix-preview-capabilities:end -->
|
|
110
116
|
|
|
111
117
|
说明:
|
|
112
118
|
|
|
113
119
|
- 当前四项 preview capability 都已经完成 preview baseline 的 bundle / debug build / route walkthrough
|
|
114
120
|
- 四项 preview capability 都已经进入 `adapter` 路径;`device=yes[manual-doc]` 只表示已有人工设备验收记录,仍不代表 verified 或 release-ready
|
|
115
|
-
-
|
|
121
|
+
- 当前原生 adapter preview baseline 的默认 evidenceSource 固定为:`bundle/debugBuild=automated`、`device=manual-doc`、`release=none`
|
|
122
|
+
- `v1.9.0` 新增的 app foundation modules 当前是 `runtimeMode=shim`,`bundle/debugBuild=automated`,`device/release=none`
|
|
116
123
|
- `v1.8.2` 的 ccnubox release HAP 模拟器安装/启动记录只证明 app-shell release 构建链路,不改变上述 per-capability `release=no[none]`
|
|
117
124
|
- `v1.8.x` 开始,combined sample smoke 只负责总回归;每项 capability 还必须单独维护 device / release acceptance 记录,见 [acceptance/v1.8.x-capability-board.md](../acceptance/v1.8.x-capability-board.md)
|
|
125
|
+
- `v1.8.x` repo 内可完成的 closeout 已完成;剩余 carryover 只包括单 capability 真机 device record 与 release HAP runtime acceptance
|
|
118
126
|
- `expo-file-system`
|
|
119
127
|
- `🟡` 当前主路径是 UTF-8/base64 sandbox I/O、append/partial read、`getInfoAsync({ md5: true })` 与 `downloadAsync`
|
|
120
128
|
- `expo-image-picker`
|
|
@@ -129,7 +137,7 @@
|
|
|
129
137
|
| Expo 能力 / 依赖 | 当前层级 | runtimeMode | evidence | 说明 |
|
|
130
138
|
| --- | --- | --- | --- | --- |
|
|
131
139
|
| `expo-notifications` | `experimental` | `shim` | `bundle=no, debugBuild=no, device=no, release=no` | 服务链路与交付故事未打通 |
|
|
132
|
-
| `react-native-gesture-handler` | `experimental` |
|
|
140
|
+
| `react-native-gesture-handler` | `experimental` | `adapter` | `bundle=yes[automated], debugBuild=yes[automated], device=no[none], release=no[none]` | v1.9.0 formal acceptance slice;必须与 `@react-native-oh-tpl/react-native-gesture-handler` 成对接入,仍不在公开 verified 矩阵内 |
|
|
133
141
|
|
|
134
142
|
## UI Stack 配对规则
|
|
135
143
|
|
|
@@ -229,7 +237,7 @@ toolkit 受管的核心产物仍包括:
|
|
|
229
237
|
|
|
230
238
|
## Release Tracks
|
|
231
239
|
|
|
232
|
-
从 `v1.8`
|
|
240
|
+
从 `v1.8` 开始,发布节奏按双轨设计;`v1.9.0` 继续沿用同一规则:
|
|
233
241
|
|
|
234
242
|
<!-- GENERATED:support-matrix-release-tracks:start -->
|
|
235
243
|
- `latest`
|
|
@@ -255,9 +263,12 @@ toolkit 受管的核心产物仍包括:
|
|
|
255
263
|
|
|
256
264
|
`v1.8.2` 记录的 simulator release-HAP evidence 只覆盖 ccnubox app-shell 的 signed HAP 构建、安装和启动;单 capability 的 release acceptance 仍必须按各自记录单独关闭。
|
|
257
265
|
|
|
266
|
+
`v1.8.x` repo-only closeout 不改变 capability evidence source:`device=yes[manual-doc]` 仍只代表既有人工基线,`release=no[none]` 仍表示没有单 capability release HAP runtime evidence。
|
|
267
|
+
|
|
258
268
|
## 当前仍未进入正式公开承诺
|
|
259
269
|
|
|
260
|
-
- bare Expo
|
|
270
|
+
- bare Expo;当前只进入 intake / debug baseline
|
|
271
|
+
- `expo-secure-store`、`expo-asset`、`expo-device`、`expo-clipboard`、`expo-haptics` 当前仍只是 preview shim baseline
|
|
261
272
|
- 多 Expo / RNOH 并行 verified 矩阵
|
|
262
273
|
- 任意第三方 native package 的即时正式承诺
|
|
263
274
|
|