expo-harmony-toolkit 1.6.0 → 1.7.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 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.6.0-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.7.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
14
  <img alt="Input" src="https://img.shields.io/badge/input-Managed%2FCNG-059669?style=flat-square">
15
15
  </p>
@@ -24,7 +24,7 @@
24
24
  </div>
25
25
 
26
26
  > [!IMPORTANT]
27
- > Starting with `v1.6`, the toolkit exposes `verified + preview + experimental` support tiers. `expo55-rnoh082-ui-stack` remains the only `verified` public matrix, while `expo-file-system` and `expo-image-picker` move into `preview`. This is still not a claim that arbitrary Expo apps can be published to HarmonyOS unchanged.
27
+ > `v1.7` keeps the `verified + preview + experimental` model and moves `expo-location` and `expo-camera` into `preview`. The public path is still "Core Expo Full Coverage first, long-tail third-party native modules second"; this is still not a claim that arbitrary Expo apps can be published to HarmonyOS unchanged.
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.
@@ -47,13 +47,13 @@
47
47
 
48
48
  | Item | Status |
49
49
  | --- | --- |
50
- | Current version | `v1.6.0` |
50
+ | Current version | `v1.7.0` |
51
51
  | Support model | `verified + preview + experimental` |
52
52
  | Public `verified` matrix | `expo55-rnoh082-ui-stack` |
53
53
  | Supported input | Managed/CNG Expo projects |
54
54
  | `verified` JS/UI capabilities | `expo-router`, `expo-linking`, `expo-constants`, `react-native-reanimated`, `react-native-svg` |
55
- | `preview` native capabilities | `expo-file-system`, `expo-image-picker` |
56
- | `experimental` capabilities | `expo-location`, `expo-camera`, `expo-notifications`, `react-native-gesture-handler` |
55
+ | `preview` native capabilities | `expo-file-system`, `expo-image-picker`, `expo-location`, `expo-camera` |
56
+ | `experimental` capabilities | `expo-notifications`, `react-native-gesture-handler` |
57
57
  | Build path | `doctor -> init -> bundle -> build-hap` |
58
58
  | Primary sample | `examples/official-ui-stack-sample` |
59
59
  | Preview sample | `examples/official-native-capabilities-sample` |
@@ -63,10 +63,9 @@
63
63
  <summary><strong>Still outside the verified public promise</strong></summary>
64
64
 
65
65
  - bare Expo
66
- - `expo-file-system` and `expo-image-picker` remain `preview`
67
- - `expo-location`
68
- - `expo-camera`
66
+ - `expo-file-system`, `expo-image-picker`, `expo-location`, and `expo-camera` remain `preview`
69
67
  - `expo-notifications`
68
+ - `react-native-gesture-handler`
70
69
  - multiple public matrices
71
70
 
72
71
  </details>
@@ -169,11 +168,11 @@ Common decision points:
169
168
 
170
169
  ## Support Matrix
171
170
 
172
- `v1.6` moves to tiered support:
171
+ `v1.7` keeps tiered support:
173
172
 
174
173
  - `verified`: the only public matrix remains `expo55-rnoh082-ui-stack`
175
- - `preview`: `expo-file-system`, `expo-image-picker`
176
- - `experimental`: `expo-location`, `expo-camera`, `expo-notifications`, `react-native-gesture-handler`
174
+ - `preview`: `expo-file-system`, `expo-image-picker`, `expo-location`, `expo-camera`
175
+ - `experimental`: `expo-notifications`, `react-native-gesture-handler`
177
176
 
178
177
  `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.
179
178
 
@@ -184,7 +183,7 @@ See [docs/support-matrix.md](./docs/support-matrix.md) for the full allowlist, p
184
183
  - `examples/official-ui-stack-sample`
185
184
  The primary public sample for `v1.5.0`, covering router, linking, constants, SVG, reanimated, and Harmony sidecar build flow.
186
185
  - `examples/official-native-capabilities-sample`
187
- The new preview sample for `v1.6`, covering the `expo-file-system` and `expo-image-picker` bridge, permission generation, and bundle-time alias flow.
186
+ The `v1.7` Batch A+B preview sample, covering `expo-file-system`, `expo-image-picker`, `expo-location`, and `expo-camera` bridge, permission, bundle, and debug-build validation.
188
187
  - `examples/official-app-shell-sample`
189
188
  The `v1.1` App Shell regression baseline that protects router behavior while UI-stack support is finalized.
190
189
  - `examples/official-minimal-sample`
@@ -247,7 +246,7 @@ Manual Harmony acceptance still requires:
247
246
  - pressing the home-screen motion rail triggers visible animation
248
247
  - routing still works after the animation completes
249
248
  - `Build Debug Hap(s)` succeeds
250
- - `official-native-capabilities-sample` at least proves preview route bundling and generated Harmony permissions
249
+ - `official-native-capabilities-sample` at least proves Batch A+B preview route bundling, generated Harmony permissions, and the debug build path
251
250
 
252
251
  See [docs/npm-release.md](./docs/npm-release.md) and [docs/signing-and-release.md](./docs/signing-and-release.md).
253
252
 
@@ -261,6 +260,7 @@ See [docs/npm-release.md](./docs/npm-release.md) and [docs/signing-and-release.m
261
260
  - [Official Minimal Sample Guide](./docs/official-minimal-sample.md)
262
261
  - [npm Release Notes](./docs/npm-release.md)
263
262
  - [Signing and Release Notes](./docs/signing-and-release.md)
263
+ - [v1.7.0 Acceptance Log (In Progress)](./docs/v1.7.0-acceptance.md)
264
264
  - [Roadmap](./docs/roadmap.md)
265
265
 
266
266
  ## License
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.6.0-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.7.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
14
  <img alt="Input" src="https://img.shields.io/badge/input-Managed%2FCNG-059669?style=flat-square">
15
15
  </p>
@@ -24,7 +24,7 @@
24
24
  </div>
25
25
 
26
26
  > [!IMPORTANT]
27
- > `v1.6` 开始,toolkit 采用 `verified + preview + experimental` 三层支持模型。`expo55-rnoh082-ui-stack` 仍是唯一 `verified` 公开矩阵;`expo-file-system` `expo-image-picker` 进入 `preview`,但这仍然不是“任意 Expo 项目都能原样发布到 HarmonyOS”的声明。
27
+ > `v1.7` 延续 `verified + preview + experimental` 三层支持模型,并把 `expo-location`、`expo-camera` 推进到 `preview`。当前对外路线仍然是先做到 `Core Expo Full Coverage`,再去覆盖长尾第三方 native module;这依然不是“任意 Expo 项目都能原样发布到 HarmonyOS”的声明。
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 阶段拉取私有资源而中断安装。
@@ -47,13 +47,13 @@
47
47
 
48
48
  | 项目 | 说明 |
49
49
  | --- | --- |
50
- | 当前版本 | `v1.6.0` |
50
+ | 当前版本 | `v1.7.0` |
51
51
  | 支持模型 | `verified + preview + experimental` |
52
52
  | 唯一 `verified` 公开矩阵 | `expo55-rnoh082-ui-stack` |
53
53
  | 输入范围 | Managed/CNG Expo 项目 |
54
54
  | `verified` JS/UI 能力 | `expo-router`、`expo-linking`、`expo-constants`、`react-native-reanimated`、`react-native-svg` |
55
- | `preview` 原生能力 | `expo-file-system`、`expo-image-picker` |
56
- | `experimental` 能力 | `expo-location`、`expo-camera`、`expo-notifications`、`react-native-gesture-handler` |
55
+ | `preview` 原生能力 | `expo-file-system`、`expo-image-picker`、`expo-location`、`expo-camera` |
56
+ | `experimental` 能力 | `expo-notifications`、`react-native-gesture-handler` |
57
57
  | 构建链 | `doctor -> init -> bundle -> build-hap` |
58
58
  | 主 sample | `examples/official-ui-stack-sample` |
59
59
  | preview sample | `examples/official-native-capabilities-sample` |
@@ -63,10 +63,9 @@
63
63
  <summary><strong>当前仍不在 verified 正式承诺范围</strong></summary>
64
64
 
65
65
  - bare Expo
66
- - `expo-file-system`、`expo-image-picker` 仍只属于 `preview`
67
- - `expo-location`
68
- - `expo-camera`
66
+ - `expo-file-system`、`expo-image-picker`、`expo-location`、`expo-camera` 仍只属于 `preview`
69
67
  - `expo-notifications`
68
+ - `react-native-gesture-handler`
70
69
  - 多矩阵并行支持
71
70
 
72
71
  </details>
@@ -169,11 +168,11 @@ pnpm exec expo-harmony build-hap --mode release
169
168
 
170
169
  ## 支持矩阵
171
170
 
172
- `v1.6` 开始改成支持分层:
171
+ `v1.7` 继续采用支持分层:
173
172
 
174
173
  - `verified`:唯一公开矩阵仍是 `expo55-rnoh082-ui-stack`
175
- - `preview`:`expo-file-system`、`expo-image-picker`
176
- - `experimental`:`expo-location`、`expo-camera`、`expo-notifications`、`react-native-gesture-handler`
174
+ - `preview`:`expo-file-system`、`expo-image-picker`、`expo-location`、`expo-camera`
175
+ - `experimental`:`expo-notifications`、`react-native-gesture-handler`
177
176
 
178
177
  `doctor --strict` 继续只代表 `verified`。`doctor --target-tier preview` 会在同一 runtime matrix 下额外放行 preview 能力,但这不等于它们已经进入正式承诺。
179
178
 
@@ -184,7 +183,7 @@ pnpm exec expo-harmony build-hap --mode release
184
183
  - `examples/official-ui-stack-sample`
185
184
  当前唯一对外主 sample,同时覆盖 router、linking、constants、SVG、reanimated 和 Harmony sidecar 构建链。
186
185
  - `examples/official-native-capabilities-sample`
187
- v1.6 新增的 preview sample,用来承接 `expo-file-system` 与 `expo-image-picker` 的 bridge、permission 与 bundle 骨架验收。
186
+ `v1.7` Batch A+B preview sample,用来承接 `expo-file-system`、`expo-image-picker`、`expo-location`、`expo-camera` 的 bridge、permission、bundledebug build 验收。
188
187
  - `examples/official-app-shell-sample`
189
188
  `v1.1` App Shell 回归基线,用来防止 UI-stack 收口引入 router 退化。
190
189
  - `examples/official-minimal-sample`
@@ -247,7 +246,7 @@ pnpm exec expo-harmony build-hap --mode release
247
246
  - 点击首页 motion rail 后能触发可见动画
248
247
  - 动画完成后路由跳转仍正常
249
248
  - `Build Debug Hap(s)` 成功
250
- - `official-native-capabilities-sample` 至少完成 preview route 的 bundle 与 permission 产物检查
249
+ - `official-native-capabilities-sample` 至少完成 Batch A+B preview route 的 bundle、permissiondebug build 检查
251
250
 
252
251
  详见 [docs/npm-release.md](./docs/npm-release.md) 与 [docs/signing-and-release.md](./docs/signing-and-release.md)。
253
252
 
@@ -261,6 +260,7 @@ pnpm exec expo-harmony build-hap --mode release
261
260
  - [官方最小 sample 指南](./docs/official-minimal-sample.md)
262
261
  - [npm 发布说明](./docs/npm-release.md)
263
262
  - [签名与 Release 说明](./docs/signing-and-release.md)
263
+ - [v1.7.0 验收记录(进行中)](./docs/v1.7.0-acceptance.md)
264
264
  - [路线图](./docs/roadmap.md)
265
265
 
266
266
  ## License
@@ -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.6.0";
3
+ export declare const TOOLKIT_VERSION = "1.7.0";
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";
@@ -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.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.6.0';
6
+ exports.TOOLKIT_VERSION = '1.7.0';
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';
@@ -717,6 +717,10 @@ function renderCapabilityModuleShim(capability) {
717
717
  return renderExpoFileSystemPreviewShim(capability);
718
718
  case 'expo-image-picker':
719
719
  return renderExpoImagePickerPreviewShim(capability);
720
+ case 'expo-location':
721
+ return renderExpoLocationPreviewShim(capability);
722
+ case 'expo-camera':
723
+ return renderExpoCameraPreviewShim(capability);
720
724
  default:
721
725
  return renderUnsupportedCapabilityShim(capability);
722
726
  }
@@ -1074,6 +1078,177 @@ module.exports = {
1074
1078
  };
1075
1079
  `;
1076
1080
  }
1081
+ function renderExpoLocationPreviewShim(capability) {
1082
+ return `'use strict';
1083
+
1084
+ const { CodedError } = require('expo-modules-core');
1085
+
1086
+ const PREVIEW_MESSAGE =
1087
+ '${capability.packageName} is routed through the Expo Harmony ${capability.supportTier} bridge. Bundling is supported, but foreground permission, current-position, and watch flows still need device-side validation.';
1088
+ const DEFAULT_PERMISSION_RESPONSE = {
1089
+ status: 'undetermined',
1090
+ granted: false,
1091
+ canAskAgain: true,
1092
+ expires: 'never',
1093
+ };
1094
+
1095
+ function createPreviewError(operationName) {
1096
+ return new CodedError(
1097
+ 'ERR_EXPO_HARMONY_PREVIEW',
1098
+ PREVIEW_MESSAGE + ' Attempted operation: ' + operationName + '.',
1099
+ );
1100
+ }
1101
+
1102
+ async function unavailable(operationName) {
1103
+ throw createPreviewError(operationName);
1104
+ }
1105
+
1106
+ function getPermissionResponse() {
1107
+ return { ...DEFAULT_PERMISSION_RESPONSE };
1108
+ }
1109
+
1110
+ module.exports = {
1111
+ Accuracy: {
1112
+ Lowest: 1,
1113
+ Low: 2,
1114
+ Balanced: 3,
1115
+ High: 4,
1116
+ Highest: 5,
1117
+ BestForNavigation: 6,
1118
+ },
1119
+ PermissionStatus: {
1120
+ DENIED: 'denied',
1121
+ GRANTED: 'granted',
1122
+ UNDETERMINED: 'undetermined',
1123
+ },
1124
+ requestForegroundPermissionsAsync() {
1125
+ return unavailable('requestForegroundPermissionsAsync');
1126
+ },
1127
+ getForegroundPermissionsAsync() {
1128
+ return Promise.resolve(getPermissionResponse());
1129
+ },
1130
+ requestBackgroundPermissionsAsync() {
1131
+ return unavailable('requestBackgroundPermissionsAsync');
1132
+ },
1133
+ getBackgroundPermissionsAsync() {
1134
+ return Promise.resolve(getPermissionResponse());
1135
+ },
1136
+ hasServicesEnabledAsync() {
1137
+ return Promise.resolve(false);
1138
+ },
1139
+ getCurrentPositionAsync(options) {
1140
+ return unavailable('getCurrentPositionAsync(' + JSON.stringify(options ?? {}) + ')');
1141
+ },
1142
+ getLastKnownPositionAsync(options) {
1143
+ return unavailable('getLastKnownPositionAsync(' + JSON.stringify(options ?? {}) + ')');
1144
+ },
1145
+ watchPositionAsync(options) {
1146
+ return unavailable('watchPositionAsync(' + JSON.stringify(options ?? {}) + ')');
1147
+ },
1148
+ };
1149
+ `;
1150
+ }
1151
+ function renderExpoCameraPreviewShim(capability) {
1152
+ return `'use strict';
1153
+
1154
+ const React = require('react');
1155
+ const { Text, View } = require('react-native');
1156
+ const { CodedError } = require('expo-modules-core');
1157
+
1158
+ const PREVIEW_MESSAGE =
1159
+ '${capability.packageName} is routed through the Expo Harmony ${capability.supportTier} bridge. Bundling is supported, and a managed preview surface can render, but device-side camera permission and capture flows still need validation.';
1160
+ const DEFAULT_PERMISSION_RESPONSE = {
1161
+ status: 'undetermined',
1162
+ granted: false,
1163
+ canAskAgain: true,
1164
+ expires: 'never',
1165
+ };
1166
+
1167
+ function createPreviewError(operationName) {
1168
+ return new CodedError(
1169
+ 'ERR_EXPO_HARMONY_PREVIEW',
1170
+ PREVIEW_MESSAGE + ' Attempted operation: ' + operationName + '.',
1171
+ );
1172
+ }
1173
+
1174
+ async function unavailable(operationName) {
1175
+ throw createPreviewError(operationName);
1176
+ }
1177
+
1178
+ function getPermissionResponse() {
1179
+ return { ...DEFAULT_PERMISSION_RESPONSE };
1180
+ }
1181
+
1182
+ const CameraView = React.forwardRef(function ExpoHarmonyCameraPreview(props, ref) {
1183
+ React.useImperativeHandle(ref, () => ({
1184
+ takePictureAsync(options) {
1185
+ return unavailable('CameraView.takePictureAsync(' + JSON.stringify(options ?? {}) + ')');
1186
+ },
1187
+ }));
1188
+
1189
+ return React.createElement(
1190
+ View,
1191
+ {
1192
+ style: [
1193
+ {
1194
+ minHeight: 220,
1195
+ alignItems: 'center',
1196
+ justifyContent: 'center',
1197
+ borderRadius: 20,
1198
+ borderWidth: 1,
1199
+ borderStyle: 'dashed',
1200
+ borderColor: '#14b8a6',
1201
+ backgroundColor: '#ccfbf1',
1202
+ padding: 20,
1203
+ },
1204
+ props.style,
1205
+ ],
1206
+ accessibilityLabel: 'Expo Harmony preview camera surface',
1207
+ },
1208
+ React.createElement(
1209
+ Text,
1210
+ {
1211
+ style: {
1212
+ color: '#0f766e',
1213
+ fontSize: 14,
1214
+ fontWeight: '600',
1215
+ textAlign: 'center',
1216
+ },
1217
+ },
1218
+ 'Expo Harmony preview camera surface',
1219
+ ),
1220
+ );
1221
+ });
1222
+
1223
+ CameraView.displayName = 'ExpoHarmonyCameraPreview';
1224
+
1225
+ module.exports = {
1226
+ CameraType: {
1227
+ front: 'front',
1228
+ back: 'back',
1229
+ },
1230
+ FlashMode: {
1231
+ off: 'off',
1232
+ on: 'on',
1233
+ auto: 'auto',
1234
+ torch: 'torch',
1235
+ },
1236
+ CameraView,
1237
+ requestCameraPermissionsAsync() {
1238
+ return unavailable('requestCameraPermissionsAsync');
1239
+ },
1240
+ getCameraPermissionsAsync() {
1241
+ return Promise.resolve(getPermissionResponse());
1242
+ },
1243
+ requestMicrophonePermissionsAsync() {
1244
+ return unavailable('requestMicrophonePermissionsAsync');
1245
+ },
1246
+ getMicrophonePermissionsAsync() {
1247
+ return Promise.resolve(getPermissionResponse());
1248
+ },
1249
+ };
1250
+ `;
1251
+ }
1077
1252
  function renderExpoModulesCoreHarmonyShim(expoConfig, identifiers) {
1078
1253
  const embeddedExpoConfig = buildExpoConfigForShim(expoConfig, identifiers);
1079
1254
  const serializedExpoConfig = JSON.stringify(embeddedExpoConfig, null, 2);
@@ -43,8 +43,8 @@ exports.CAPABILITY_DEFINITIONS = [
43
43
  id: 'expo-location',
44
44
  packageName: 'expo-location',
45
45
  status: 'manual',
46
- supportTier: 'experimental',
47
- note: 'Location hooks are planned on top of the shared permission bridge, but no verified runtime path is shipped yet.',
46
+ supportTier: 'preview',
47
+ note: 'Preview bridge scaffolding is available for foreground permissions, current-position probes, and watch flows, but device-side runtime behavior is still pending verified promotion.',
48
48
  docsUrl: 'https://github.com/react-native-oh-library/usage-docs/blob/master/en/%40react-native-community-geolocation.md',
49
49
  nativePackageNames: ['@react-native-community/geolocation', 'react-native-permissions'],
50
50
  harmonyPermissions: ['ohos.permission.LOCATION', 'ohos.permission.APPROXIMATELY_LOCATION'],
@@ -59,8 +59,8 @@ exports.CAPABILITY_DEFINITIONS = [
59
59
  id: 'expo-camera',
60
60
  packageName: 'expo-camera',
61
61
  status: 'manual',
62
- supportTier: 'experimental',
63
- note: 'Camera preview and capture remain experimental until a stable Harmony-native implementation is wired into the managed bridge.',
62
+ supportTier: 'preview',
63
+ note: 'Preview bridge scaffolding is available for permission, preview-surface, and capture-entry flows, but a verified Harmony-native runtime path is not public yet.',
64
64
  docsUrl: 'https://github.com/react-native-oh-library/usage-docs/blob/master/en/react-native-camera-kit.md',
65
65
  nativePackageNames: ['react-native-camera-kit', 'react-native-permissions'],
66
66
  harmonyPermissions: ['ohos.permission.CAMERA'],
package/docs/cli-build.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # CLI 构建指南
2
2
 
3
- `v1.6.0` 开始,toolkit 的公开叙事升级为 `verified + preview + experimental` 支持分层,其中 `expo55-rnoh082-ui-stack` 仍是唯一 verified 矩阵。
3
+ `v1.7.0` 延续 `verified + preview + experimental` 支持分层,并把 Batch B 设备能力推进到 preview 接入路径,其中 `expo55-rnoh082-ui-stack` 仍是唯一 verified 矩阵。
4
4
 
5
5
  CLI 命令集合不变:
6
6
 
@@ -33,6 +33,13 @@ expo-harmony build-hap --mode debug
33
33
  - `bundle` 负责 `bundle.harmony.js`
34
34
  - `build-hap` 负责串起 bundle、`ohpm`、`hvigor`
35
35
 
36
+ 当前 preview capability onboarding 范围:
37
+
38
+ - `expo-file-system`
39
+ - `expo-image-picker`
40
+ - `expo-location`
41
+ - `expo-camera`
42
+
36
43
  ## UI stack 依赖安装注意事项
37
44
 
38
45
  当前公开矩阵里的两项 Harmony adapter 依赖都固定为 Git URL + exact commit:
@@ -2,27 +2,31 @@
2
2
 
3
3
  路径:`examples/official-native-capabilities-sample`
4
4
 
5
- 这个 sample 从 `v1.6` 开始承担 preview 能力的官方入口。它不是新的 `verified` 主 sample,而是专门用来验证:
5
+ 这个 sample 从 `v1.7` 开始承担 Batch A+B preview 能力的统一官方入口。它不是新的 `verified` 主 sample,而是专门用来验证:
6
6
 
7
7
  - `doctor --target-tier preview`
8
8
  - managed Harmony permission 生成
9
9
  - preview capability Metro alias / shim
10
- - `bundle` 阶段对原生能力 import path 的稳定接管
10
+ - `bundle` 与 `build-hap --mode debug` 阶段对原生能力 import path 的稳定接管
11
11
 
12
12
  ## 当前覆盖
13
13
 
14
14
  - `expo-file-system`
15
15
  - `expo-image-picker`
16
+ - `expo-location`
17
+ - `expo-camera`
16
18
 
17
19
  当前 route:
18
20
 
19
21
  - `/file-system`
20
22
  - `/image-picker`
23
+ - `/location`
24
+ - `/camera`
21
25
 
22
26
  说明:
23
27
 
24
28
  - 这些 route 的目标是承接 preview bridge,而不是宣称运行时已经完全可用
25
- - 当前 sample 仍然强调“可分析、可生成 sidecar、可 bundle、可观察 permission/shim 产物”
29
+ - 当前 sample 强调“可分析、可生成 sidecar、可 bundle、可 debug build、可观察 permission/shim 产物”
26
30
  - 只有当设备侧 runtime、debug HAP、人工验收都完成后,对应能力才可以从 `preview` 晋升到 `verified`
27
31
 
28
32
  ## 推荐命令
@@ -32,6 +36,7 @@ cd examples/official-native-capabilities-sample
32
36
  pnpm run harmony:doctor:preview
33
37
  pnpm run harmony:sync-template
34
38
  pnpm run harmony:bundle
39
+ pnpm run harmony:build:debug
35
40
  ```
36
41
 
37
42
  如果要确认它为什么不能进入 `verified`:
@@ -43,15 +48,18 @@ pnpm run harmony:doctor:strict
43
48
  预期结果:
44
49
 
45
50
  - `doctor --target-tier preview`:通过
46
- - `doctor --strict`:失败,因为 `expo-file-system` / `expo-image-picker` 仍然不在 verified allowlist
47
- - `sync-template`:产出 preview shims 与 Harmony permissions
51
+ - `doctor --strict`:失败,因为 preview 能力仍然不在 verified allowlist
52
+ - `sync-template`:产出 Batch A+B 对应 preview shims 与 Harmony permissions
48
53
  - `bundle`:成功产出 `bundle.harmony.js`
54
+ - `build-hap --mode debug`:可进入 debug HAP 构建路径
49
55
 
50
56
  ## 关键受管产物
51
57
 
52
58
  - `harmony/entry/src/main/module.json5`
53
59
  - `.expo-harmony/shims/expo-file-system/index.js`
54
60
  - `.expo-harmony/shims/expo-image-picker/index.js`
61
+ - `.expo-harmony/shims/expo-location/index.js`
62
+ - `.expo-harmony/shims/expo-camera/index.js`
55
63
  - `metro.harmony.config.js`
56
64
 
57
65
  ## 晋升条件
@@ -60,5 +68,5 @@ pnpm run harmony:doctor:strict
60
68
 
61
69
  - 真机或模拟器运行时功能通过
62
70
  - debug `build-hap` 成功
63
- - 拒权限、取消流程、异常路径完成记录
71
+ - 权限拒绝、取消流程、异常路径完成记录
64
72
  - support matrix、README、roadmap、acceptance 记录同 PR 更新
package/docs/roadmap.md CHANGED
@@ -30,50 +30,74 @@
30
30
  - `official-ui-stack-sample` 升级为主 sample
31
31
  - npm 首次公开发布准备:`release:check`、tarball smoke、release workflow
32
32
 
33
- ## 当前主线
34
-
35
33
  ### v1.6 Support Tiers + Core Native Bridge
36
34
 
37
- 目标:在不放弃单一 verified 矩阵的前提下,把能力扩张路径产品化。
38
-
39
- - 保留 `expo55-rnoh082-ui-stack` 作为唯一 `verified` 公开矩阵
40
35
  - 新增 `preview` 与 `experimental` 支持层级
41
36
  - `doctor --target-tier <verified|preview|experimental>`
42
37
  - `DoctorReport` 增加 `supportTier`、`supportSummary`、`capabilities`
43
- - 建立 Expo 原生能力桥接骨架,沿用受管 Metro alias 与 `expo-modules-core` shim
44
38
  - 首批 `preview` 能力:`expo-file-system`、`expo-image-picker`
45
39
  - 共享 Harmony permission 生成链
46
40
  - 新增 `official-native-capabilities-sample`
47
41
 
48
- ### v1.7 Device APIs Batch B
42
+ ## 当前主线
49
43
 
50
- 目标:在同一套桥接与权限模型上补齐第二批高频设备能力。
44
+ ### v1.7 Device APIs Batch B + Capability Onboarding
51
45
 
52
- - `expo-location`
53
- - `expo-camera`
54
- - 前台定位权限、当前定位、watchPosition
55
- - 相机权限、预览、拍照验收
56
- - 将已完成端到端验收的 `preview` 能力提升为 `verified`
46
+ 目标:把第二批高频设备能力推进到 `preview`,并把 capability 接入、验证、晋升流程产品化。
57
47
 
58
- ### v1.8 Delivery Hardening
48
+ - `expo-location`、`expo-camera` 进入 `preview`
49
+ - 共用 managed capability bridge 行为:
50
+ 可 `doctor`、可 `sync-template`、可 `bundle`、可 `build-hap --mode debug`
51
+ - `expo-location` 至少覆盖:
52
+ 前台权限、当前定位、`watchPosition`
53
+ - `expo-camera` 至少覆盖:
54
+ 相机权限、预览 surface、单次拍照入口
55
+ - `official-native-capabilities-sample` 扩成 Batch A+B 统一验证入口
56
+ - 为 Batch A+B 维护 fixture、sample、文档、验收记录同步更新
57
+ - `expo-file-system`、`expo-image-picker` 只有在同版补齐完整证据时才晋升 `verified`
59
58
 
60
- 目标:把“能 bundle / debug build”推进到“交付路径可依赖”。
59
+ ### v1.8 Verification and Release Hardening
60
+
61
+ 目标:把 capability coverage 与 release reliability 合并成可重复执行的 gate。
61
62
 
62
63
  - 完整 deep link lifecycle 验收
63
64
  - 更强的 signing / profile / release lint
64
65
  - 快速 smoke 与 capability acceptance 双层验证
65
66
  - 具备 Harmony 工具链的 runner 上增加 debug HAP 真构建 gate
67
+ - capability promotion gate 固化到 sample、fixture、build、device acceptance 流程
66
68
  - release gate 只放在有签名环境的专用流程
67
69
 
68
- ### v2.0 Practical Full Coverage
70
+ ### v1.9 Core Expo Production Modules
71
+
72
+ 目标:优先补齐能解锁最多真实项目的 Expo 官方生产能力,而不是先追长尾第三方 native package。
73
+
74
+ - 存储、安全、设备信息、资产、多媒体、剪贴板、触感等高频官方模块
75
+ - 每个能力都必须沿用 v1.7 建立的 onboarding / acceptance 模型
76
+ - 继续保持单一 `verified` runtime matrix,对外承诺不膨胀
69
77
 
70
- 定义:不是 Expo / React Native 全生态的绝对 100% 覆盖,而是 Managed/CNG Expo 项目的“实用全兼容”。
78
+ ### v2.0 Core Expo Full Coverage
71
79
 
72
- - 大多数 Expo 生产项目可通过 `doctor -> init -> bundle -> build-hap`
73
- - 常见 UI stack、常见设备 API、常见交付链至少达到 `preview`
80
+ 定义:在单一 `verified` runtime matrix 下,把“核心 Expo 生产项目”推进到完整可用、可构建、可交付。
81
+
82
+ - 官方 Expo 常用能力达到明确公开支持
83
+ - 主流 UI stack、常见设备 API、常见交付链形成完整故事
74
84
  - 高频能力达到 `verified`
75
- - 明确 release readiness 路径
76
- - `expo-notifications` 在端到端服务故事未打通前继续停留在 `preview` 或更低层级
85
+ - 具备明确 release readiness 路径
86
+ - roadmap 对外叙事从“能跑 sample”升级为“核心 Expo 项目可稳定交付”
87
+
88
+ ### v2.x Long-tail Native Module Extension
89
+
90
+ 目标:在完成核心 Expo 全覆盖后,再去逼近“任何 Expo 项目都能打包成鸿蒙 APP”的长期目标。
91
+
92
+ - 引入长尾第三方 native module 的 extension / onboarding 模型
93
+ - 为第三方适配建立 capability registry、adapter、fixture、acceptance 规范
94
+ - 不对未知或未验证 native package 提前给出正式可用承诺
95
+
96
+ ## 长期方向
97
+
98
+ - 先做到 `Core Expo Full Coverage`
99
+ - 再做到 `Long-tail Native Module Coverage`
100
+ - “推进速度”与“完全可用”并行,而不是先扩承诺再补证据
77
101
 
78
102
  ## 路线约束
79
103
 
@@ -1,6 +1,6 @@
1
- # v1.6 支持矩阵
1
+ # v1.7 支持矩阵
2
2
 
3
- `v1.6` 开始,toolkit 不再只暴露“单一 allowlist”这一种语言,而是同时公开:
3
+ `v1.7` 延续并扩张 tiered support model:
4
4
 
5
5
  - 一条 `verified` 正式承诺矩阵
6
6
  - 一组 `preview` 预览能力
@@ -30,7 +30,7 @@
30
30
  | 层级 | 含义 | `doctor --strict` | `doctor --target-tier <tier>` |
31
31
  | --- | --- | --- | --- |
32
32
  | `verified` | 已进入正式公开承诺,要求完整样例、构建、人工验收 | 允许 | 允许 |
33
- | `preview` | 已具备 managed bridge / bundle 路径,但运行时仍待完整验收 | 阻断 | `preview` / `experimental` 允许 |
33
+ | `preview` | 已具备 managed bridge / bundle / debug build 路径,但运行时仍待完整验收 | 阻断 | `preview` / `experimental` 允许 |
34
34
  | `experimental` | 允许继续探索,但预期会有 bridge 漂移或设备侧缺口 | 阻断 | 仅 `experimental` 允许 |
35
35
  | `unsupported` | 不在 catalog 内,toolkit 无法给出可靠承诺 | 阻断 | 阻断 |
36
36
 
@@ -60,19 +60,19 @@
60
60
  | --- | --- | --- | --- | --- |
61
61
  | `expo-file-system` | `preview` | `react-native-fs` | 无新增必需权限 | `/file-system` |
62
62
  | `expo-image-picker` | `preview` | `react-native-image-picker` + `react-native-permissions` | `ohos.permission.CAMERA`、`ohos.permission.READ_IMAGEVIDEO` | `/image-picker` |
63
+ | `expo-location` | `preview` | `@react-native-community/geolocation` + `react-native-permissions` | `ohos.permission.LOCATION`、`ohos.permission.APPROXIMATELY_LOCATION` | `/location` |
64
+ | `expo-camera` | `preview` | `react-native-camera-kit` + `react-native-permissions` | `ohos.permission.CAMERA` | `/camera` |
63
65
 
64
66
  说明:
65
67
 
66
68
  - preview 能力会进入 `DoctorReport.capabilities`
67
- - toolkit 会生成对应 Metro alias shim,确保 preview 项目能稳定 bundle
69
+ - toolkit 会生成对应 Metro alias shim,确保 preview 项目能稳定 `bundle` 与 `build-hap --mode debug`
68
70
  - preview 不等于 verified;没有运行时与设备侧证据前,不可对外宣称完全可用
69
71
 
70
72
  ## Experimental 能力
71
73
 
72
74
  | Expo 能力 / 依赖 | 当前层级 | 说明 |
73
75
  | --- | --- | --- |
74
- | `expo-location` | `experimental` | 规划走共享 permission bridge + geolocation 方案 |
75
- | `expo-camera` | `experimental` | 相机预览与拍照仍需稳定 Harmony 原生桥 |
76
76
  | `expo-notifications` | `experimental` | 服务链路与交付故事未打通 |
77
77
  | `react-native-gesture-handler` | `experimental` | 继续保留本地探索 shim,但不在公开 verified 矩阵内 |
78
78
 
@@ -144,7 +144,7 @@ toolkit 受管的核心产物仍包括:
144
144
  - `harmony/entry/src/main/module.json5`
145
145
  - `.expo-harmony/shims/*`
146
146
 
147
- 新增约束:
147
+ 当前约束:
148
148
 
149
149
  - `entry/src/main/module.json5` 的 `requestPermissions` 由 toolkit 根据已启用能力自动补齐
150
150
  - preview / experimental 能力的 Metro import path 通过 `.expo-harmony/shims/<package>` 接管
@@ -163,7 +163,8 @@ toolkit 受管的核心产物仍包括:
163
163
 
164
164
  - `official-native-capabilities-sample` 在 `--target-tier preview` 下通过 `doctor`
165
165
  - `sync-template` 生成对应 preview shims 与 Harmony permissions
166
- - `bundle` 成功产出 `bundle.harmony.js`
166
+ - Batch A+B route 成功产出 `bundle.harmony.js`
167
+ - Batch A+B route 可进入 `build-hap --mode debug`
167
168
 
168
169
  ### Verified promotion gate
169
170
 
@@ -0,0 +1,142 @@
1
+ # v1.7.0 验收记录(已完成)
2
+
3
+ 日期:2026-03-31
4
+
5
+ 基线:
6
+
7
+ - 仓库:`Expo-Harmony-Toolkit`
8
+ - 版本:`1.7.0`
9
+ - 发布目标:Batch B capability onboarding baseline
10
+
11
+ ## 当前结论
12
+
13
+ `v1.7.0` 的 Batch B capability onboarding baseline 已完成验收。
14
+
15
+ 这一轮完成了代码与文档基线同步,把 `expo-location`、`expo-camera` 正式推进到 `preview` 接入路径,并把 roadmap 重写为:
16
+
17
+ - `v1.7 Device APIs Batch B + Capability Onboarding`
18
+ - `v1.8 Verification and Release Hardening`
19
+ - `v1.9 Core Expo Production Modules`
20
+ - `v2.0 Core Expo Full Coverage`
21
+ - `v2.x Long-tail Native Module Extension`
22
+
23
+ 本轮验收结论是:
24
+
25
+ - `expo-location`、`expo-camera` 的 preview-tier 接入链路已经完成基线验收
26
+ - `expo-file-system`、`expo-image-picker` 的 Batch A preview route 已完成回归验收
27
+ - `doctor --strict` 仍然会正确阻挡全部 preview capability;这条规则没有变化
28
+ - `preview` 验收完成不代表这些能力已经晋升到 `verified`
29
+
30
+ ## 本轮实现范围
31
+
32
+ - `expo-location`、`expo-camera` 调整为 `preview`
33
+ - `doctor --target-tier preview` 放行 Batch A+B preview capability
34
+ - managed Harmony permission / shim / Metro alias 生成扩展到 Batch A+B
35
+ - `official-native-capabilities-sample` 扩充到 `/file-system`、`/image-picker`、`/location`、`/camera`
36
+ - roadmap、support matrix、README、sample 指南同步更新
37
+
38
+ ## 自动化检查结果
39
+
40
+ - `pnpm build`
41
+ - `pnpm test`
42
+ - `official-native-capabilities-sample` 在 preview tier 下完成 `doctor`
43
+ - `sync-template` 生成 Batch A+B preview shims 与 Harmony permissions
44
+ - `bundle` 成功产出 `bundle.harmony.js`
45
+ - `build-hap --mode debug` 成功走完构建路径
46
+
47
+ 结果:
48
+
49
+ - `pnpm build`:通过
50
+ - `pnpm test`:通过,`11` suites / `58` tests
51
+ - `doctor --target-tier preview`:通过,`Eligibility: eligible`
52
+ - `doctor --strict`:按预期失败,`STRICT_EXIT=2`
53
+ - `init --force`:通过,`written: 42`
54
+ - `bundle`:通过,产物位于 `examples/official-native-capabilities-sample/harmony/entry/src/main/resources/rawfile/bundle.harmony.js`
55
+ - `build-hap --mode debug`:通过,产物位于 `examples/official-native-capabilities-sample/harmony/entry/build/default/outputs/default/entry-default-unsigned.hap`
56
+
57
+ 额外说明:
58
+
59
+ - `build-hap --mode debug` 期间仍会提示 `env.signing.missing`
60
+ - 这是预期结果;debug HAP 可构建,但 release signing 仍未配置
61
+
62
+ ## 模拟器设备侧验收
63
+
64
+ 环境:
65
+
66
+ - 模拟器 target:`127.0.0.1:5555`
67
+ - 安装产物:`examples/official-native-capabilities-sample/harmony/entry/build/default/outputs/default/entry-default-unsigned.hap`
68
+ - 安装结果:`install bundle successfully`
69
+ - 启动结果:`start ability successfully`
70
+
71
+ 首页:
72
+
73
+ - `Official Native Capabilities Sample` 成功渲染
74
+ - `/file-system`、`/image-picker`、`/location`、`/camera` 四条 route 入口全部可见
75
+
76
+ ### File System
77
+
78
+ - `/file-system` route 成功打开
79
+ - `Attempt preview write` 可触发 preview bridge
80
+ - 页面返回 `expo-file-system is routed through the Expo Harmony preview bridge...`
81
+ - 路由切换与返回首页过程中未发生 crash
82
+
83
+ ### Image Picker
84
+
85
+ - `/image-picker` route 成功打开
86
+ - `Attempt preview pick` 可触发 preview bridge
87
+ - 页面返回 `expo-image-picker is routed through the Expo Harmony preview bridge...`
88
+ - 路由切换与返回首页过程中未发生 crash
89
+
90
+ ### Location
91
+
92
+ - `/location` route 成功打开
93
+ - `Attempt foreground permission` 可触发 preview bridge
94
+ - `Attempt current position` 可触发 preview bridge
95
+ - `Attempt watch start` 可触发 preview bridge
96
+ - `Clear watch state` 可正常清理本地 watcher 状态
97
+ - 页面可观察到 `requestForegroundPermissionsAsync`、`getCurrentPositionAsync(`、`watchPositionAsync(` 与 `Preview watch state cleared.`
98
+ - 路由切换与返回首页过程中未发生 crash
99
+
100
+ ### Camera
101
+
102
+ - `/camera` route 成功打开
103
+ - `Expo Harmony preview camera surface` 成功渲染
104
+ - `Attempt camera permission` 可触发 preview bridge
105
+ - `Attempt preview capture` 可触发 preview bridge
106
+ - 页面可观察到 `requestCameraPermissionsAsync` 与 `CameraView.takePictureAsync(`
107
+ - 路由切换与返回首页过程中未发生 crash
108
+
109
+ ### 权限声明检查
110
+
111
+ - `ohos.permission.LOCATION`
112
+ - `ohos.permission.APPROXIMATELY_LOCATION`
113
+ - `ohos.permission.CAMERA`
114
+ - `ohos.permission.READ_IMAGEVIDEO`
115
+
116
+ 以上权限已在 `bm dump -n com.blackishgreen.expoharmonynativepreview` 中确认存在。
117
+
118
+ ## 晋升规则
119
+
120
+ - `preview` 能力只有在 sample、fixture、bundle、debug HAP、设备侧验收、文档记录都完成后,才允许晋升到 `verified`
121
+ - `expo-file-system`、`expo-image-picker` 不作为本轮发版阻塞;若证据不足则继续停留在 `preview`
122
+
123
+ ## 本轮已完成与未完成的边界
124
+
125
+ 已完成:
126
+
127
+ - preview-tier capability onboarding 基线
128
+ - managed shim / permission / Metro alias / route / debug build / emulator walkthrough
129
+ - Batch A+B unified sample 的可安装、可启动、可点击、可观察 preview bridge 验收
130
+
131
+ 未完成:
132
+
133
+ - `expo-location` 的真实权限 grant / deny 与真实坐标结果验收
134
+ - `expo-camera` 的真实权限 grant / deny 与真实拍照文件结果验收
135
+ - release signing / release HAP 验收
136
+ - 任何 preview capability 的 `verified` 晋升
137
+
138
+ 因此,`v1.7.0` 的结论不是“location/camera 已经原生完全可用”,而是:
139
+
140
+ - 它们已经完成 preview baseline 验收
141
+ - 工具链已经可以稳定支撑分析、生成、bundle、build、install、launch、route、bridge
142
+ - 它们仍然留在 `preview`,直到真实 Harmony-native runtime 证据补齐为止
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-harmony-toolkit",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
4
4
  "description": "面向 Managed/CNG Expo 项目的 HarmonyOS 迁移、准入检查与 UI-stack 构建工具链",
5
5
  "main": "app.plugin.js",
6
6
  "types": "build/index.d.ts",