@h-ai/capacitor 1.0.0-beta.18 → 1.0.0-beta.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +2 -0
- package/README.ja.md +2 -0
- package/README.md +2 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +58 -27
- package/dist/index.js.map +1 -1
- package/package.json +9 -9
package/README.en.md
CHANGED
|
@@ -53,6 +53,8 @@ await apiClient.init({
|
|
|
53
53
|
|
|
54
54
|
A failed credential write blocks both credentials, including an access token already saved before a refresh-token write failed. After failed login or registration persistence, attempt `auth.clear()` to remove partially saved data. Report cleanup failures explicitly instead of claiming device credentials were deleted.
|
|
55
55
|
|
|
56
|
+
All TokenStorage instances in the same module share a native mutation queue. `clear()` waits for earlier writes before removing credentials, preventing late writes from restoring old tokens after successful cleanup. Explicit later writes may save new credentials. This ordering does not coordinate independent WebViews or JavaScript runtimes.
|
|
57
|
+
|
|
56
58
|
#### Device information and push notifications
|
|
57
59
|
|
|
58
60
|
```ts
|
package/README.ja.md
CHANGED
|
@@ -53,6 +53,8 @@ await apiClient.init({
|
|
|
53
53
|
|
|
54
54
|
認証情報の一方の書き込みが失敗すると両方を読み取り不可にするため、access token 保存後に refresh token の保存が失敗しても不完全な認証状態は公開しません。ログイン・登録時の保存失敗後は `auth.clear()` で部分保存データの削除を試み、削除も失敗した場合は端末の認証情報を削除できたと表示しないでください。
|
|
55
55
|
|
|
56
|
+
同じモジュール内のすべての TokenStorage はネイティブ変更キューを共有します。`clear()` は先行書き込みの完了後に削除し、削除成功後に古い書き込みが認証情報を復活させることを防ぎます。その後の明示的な書き込みは新しい認証情報を保存できます。別の WebView や JavaScript 実行環境とのプロセス間調整は提供しません。
|
|
57
|
+
|
|
56
58
|
#### 端末情報とプッシュ通知
|
|
57
59
|
|
|
58
60
|
```ts
|
package/README.md
CHANGED
|
@@ -53,6 +53,8 @@ await apiClient.init({
|
|
|
53
53
|
|
|
54
54
|
任一凭据写入失败都会屏蔽整对凭据,因此 access 已保存而 refresh 保存失败时也不会留下可读的半完成会话。登录/注册保存失败后应尝试 `auth.clear()` 清理部分持久数据;清理再次失败须明确提示,不得声称设备凭据已删除。
|
|
55
55
|
|
|
56
|
+
同一模块中的全部 TokenStorage 实例共享原生变更队列。`clear()` 等待更早调用的写入完成再删除,避免迟到写入在清理成功后恢复旧凭据;之后显式调用的写入可保存新凭据。该顺序不跨独立 WebView/JavaScript 运行环境提供进程间协调。
|
|
57
|
+
|
|
56
58
|
#### 设备信息与推送
|
|
57
59
|
|
|
58
60
|
```ts
|
package/dist/index.d.ts
CHANGED
|
@@ -415,6 +415,7 @@ declare const capacitor: CapacitorFunctions;
|
|
|
415
415
|
* `clear()` 一开始即屏蔽本实例旧凭据,删除失败时仍保持屏蔽;相应 key 成功写入后恢复读取。
|
|
416
416
|
* 任一凭据写入失败也会屏蔽整对凭据,避免 access 已保存、refresh 失败时暴露半完成登录。
|
|
417
417
|
* 本实例屏蔽不代表原生持久数据已删除;跨重启撤销仍依赖服务端退出/撤销会话。
|
|
418
|
+
* 同模块内全部适配器的原生变更按调用顺序完成;clear 等待更早写入,之后的显式写入可建立新凭据。
|
|
418
419
|
*
|
|
419
420
|
* @returns TokenStorage 实例
|
|
420
421
|
* @throws 返回适配器的方法在插件不可用或原生存储失败时拒绝 Promise。
|
|
@@ -501,4 +502,5 @@ declare function safeSetPreference(key: string, value: string): Promise<HaiResul
|
|
|
501
502
|
*/
|
|
502
503
|
declare function safeRemovePreference(key: string): Promise<HaiResult<void>>;
|
|
503
504
|
|
|
504
|
-
export {
|
|
505
|
+
export { HaiCapacitorError, capacitor, createCapacitorTokenStorage, safeGetPreference, safeRemovePreference, safeSetPreference };
|
|
506
|
+
export type { CameraOperations, CapacitorFunctions, DeviceInfo, DeviceOperations, DevicePlatform, PhotoOptions, PhotoResult, PhotoSource, PreferencesOperations, PushCleanup, PushNotification, PushNotificationCallbacks, PushOperations, PushOptions, PushRegistration, StatusBarConfig, StatusBarOperations, StatusBarStyle };
|
package/dist/index.js
CHANGED
|
@@ -246,7 +246,10 @@ function createPushScope(options) {
|
|
|
246
246
|
controller.signal.addEventListener("abort", interrupt, { once: true });
|
|
247
247
|
});
|
|
248
248
|
try {
|
|
249
|
-
return await Promise.race([
|
|
249
|
+
return await Promise.race([
|
|
250
|
+
Promise.resolve().then(operation),
|
|
251
|
+
aborted
|
|
252
|
+
]);
|
|
250
253
|
} finally {
|
|
251
254
|
if (interrupt)
|
|
252
255
|
controller.signal.removeEventListener("abort", interrupt);
|
|
@@ -300,7 +303,10 @@ async function registerPush(options) {
|
|
|
300
303
|
scope.assertOpen();
|
|
301
304
|
await push.register();
|
|
302
305
|
};
|
|
303
|
-
return (await Promise.all([
|
|
306
|
+
return (await Promise.all([
|
|
307
|
+
setup(),
|
|
308
|
+
tokenResult
|
|
309
|
+
]))[1];
|
|
304
310
|
});
|
|
305
311
|
await scope.dispose();
|
|
306
312
|
return ok({ token });
|
|
@@ -317,14 +323,26 @@ async function listenPush(callbacks, options) {
|
|
|
317
323
|
scope.assertOpen();
|
|
318
324
|
if (callbacks.onReceived) {
|
|
319
325
|
await scope.attach(() => push.addListener("pushNotificationReceived", (notification) => {
|
|
320
|
-
if (!scope.signal.aborted)
|
|
321
|
-
callbacks.onReceived?.({
|
|
326
|
+
if (!scope.signal.aborted) {
|
|
327
|
+
callbacks.onReceived?.({
|
|
328
|
+
id: notification.id,
|
|
329
|
+
title: notification.title,
|
|
330
|
+
body: notification.body,
|
|
331
|
+
data: notification.data
|
|
332
|
+
});
|
|
333
|
+
}
|
|
322
334
|
}));
|
|
323
335
|
}
|
|
324
336
|
if (callbacks.onActionPerformed) {
|
|
325
337
|
await scope.attach(() => push.addListener("pushNotificationActionPerformed", (action) => {
|
|
326
|
-
if (!scope.signal.aborted)
|
|
327
|
-
callbacks.onActionPerformed?.({
|
|
338
|
+
if (!scope.signal.aborted) {
|
|
339
|
+
callbacks.onActionPerformed?.({
|
|
340
|
+
id: action.notification.id,
|
|
341
|
+
title: action.notification.title,
|
|
342
|
+
body: action.notification.body,
|
|
343
|
+
data: action.notification.data
|
|
344
|
+
});
|
|
345
|
+
}
|
|
328
346
|
}));
|
|
329
347
|
}
|
|
330
348
|
});
|
|
@@ -397,6 +415,13 @@ async function hideStatusBar() {
|
|
|
397
415
|
}
|
|
398
416
|
var PREF_ACCESS_TOKEN = "hai_access_token";
|
|
399
417
|
var PREF_REFRESH_TOKEN = "hai_refresh_token";
|
|
418
|
+
var credentialMutationTail = Promise.resolve();
|
|
419
|
+
function mutateCredentials(operation) {
|
|
420
|
+
const pending = credentialMutationTail.then(operation);
|
|
421
|
+
credentialMutationTail = pending.catch(() => {
|
|
422
|
+
});
|
|
423
|
+
return pending;
|
|
424
|
+
}
|
|
400
425
|
async function loadSecureStoragePlugin() {
|
|
401
426
|
const { Capacitor } = await import('@capacitor/core');
|
|
402
427
|
if (!Capacitor.isNativePlatform())
|
|
@@ -415,24 +440,27 @@ function createCapacitorTokenStorage() {
|
|
|
415
440
|
}
|
|
416
441
|
async function writeToken(key, token) {
|
|
417
442
|
const writeGeneration = credentialGeneration;
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
if (
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
443
|
+
await mutateCredentials(async () => {
|
|
444
|
+
try {
|
|
445
|
+
const storage = await loadSecureStoragePlugin();
|
|
446
|
+
await storage.setItem(key, token);
|
|
447
|
+
if (writeGeneration === credentialGeneration) {
|
|
448
|
+
if (key === PREF_ACCESS_TOKEN)
|
|
449
|
+
accessBlocked = false;
|
|
450
|
+
else
|
|
451
|
+
refreshBlocked = false;
|
|
452
|
+
}
|
|
453
|
+
} catch (error) {
|
|
454
|
+
if (writeGeneration === credentialGeneration)
|
|
455
|
+
blockCredentials();
|
|
456
|
+
throw error;
|
|
426
457
|
}
|
|
427
|
-
}
|
|
428
|
-
if (writeGeneration === credentialGeneration)
|
|
429
|
-
blockCredentials();
|
|
430
|
-
throw error;
|
|
431
|
-
}
|
|
458
|
+
});
|
|
432
459
|
}
|
|
433
460
|
return {
|
|
434
461
|
async getAccessToken() {
|
|
435
462
|
const readGeneration = credentialGeneration;
|
|
463
|
+
await credentialMutationTail;
|
|
436
464
|
const storage = await loadSecureStoragePlugin();
|
|
437
465
|
if (accessBlocked)
|
|
438
466
|
return null;
|
|
@@ -441,6 +469,7 @@ function createCapacitorTokenStorage() {
|
|
|
441
469
|
},
|
|
442
470
|
async getRefreshToken() {
|
|
443
471
|
const readGeneration = credentialGeneration;
|
|
472
|
+
await credentialMutationTail;
|
|
444
473
|
const storage = await loadSecureStoragePlugin();
|
|
445
474
|
if (refreshBlocked)
|
|
446
475
|
return null;
|
|
@@ -455,14 +484,16 @@ function createCapacitorTokenStorage() {
|
|
|
455
484
|
},
|
|
456
485
|
async clear() {
|
|
457
486
|
blockCredentials();
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
487
|
+
await mutateCredentials(async () => {
|
|
488
|
+
const storage = await loadSecureStoragePlugin();
|
|
489
|
+
const results = await Promise.allSettled([
|
|
490
|
+
storage.removeItem(PREF_ACCESS_TOKEN),
|
|
491
|
+
storage.removeItem(PREF_REFRESH_TOKEN)
|
|
492
|
+
]);
|
|
493
|
+
const errors = results.filter((result) => result.status === "rejected").map((result) => result.reason);
|
|
494
|
+
if (errors.length > 0)
|
|
495
|
+
throw new AggregateError(errors, capacitorM("capacitor_secureStorageClearFailed"));
|
|
496
|
+
});
|
|
466
497
|
}
|
|
467
498
|
};
|
|
468
499
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../messages/en-US.json","../messages/ja-JP.json","../messages/zh-CN.json","../src/capacitor-i18n.ts","../src/capacitor-types.ts","../src/capacitor-camera.ts","../src/capacitor-device.ts","../src/capacitor-push.ts","../src/capacitor-status-bar.ts","../src/capacitor-token-storage.ts","../src/capacitor-main.ts"],"names":["core","ok","err","logger"],"mappings":"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","file":"index.js","sourcesContent":["{\n \"capacitor_initFailed\": \"Capacitor initialization failed\",\n \"capacitor_initInProgress\": \"Capacitor initialization is already in progress\",\n \"capacitor_notAvailable\": \"Capacitor is not available in this environment\",\n \"capacitor_secureStorageClearFailed\": \"Could not fully clear sign-in credentials from secure storage; retry signing out\",\n \"capacitor_preferencesGetFailed\": \"Failed to read from Capacitor Preferences\",\n \"capacitor_preferencesSetFailed\": \"Failed to write to Capacitor Preferences\",\n \"capacitor_preferencesRemoveFailed\": \"Failed to remove from Capacitor Preferences\",\n \"capacitor_deviceInfoFailed\": \"Failed to get device info\",\n \"capacitor_appVersionFailed\": \"Failed to get app version\",\n \"capacitor_pushRegisterFailed\": \"Failed to register push notifications\",\n \"capacitor_pushListenFailed\": \"Failed to listen for push notifications\",\n \"capacitor_cameraFailed\": \"Failed to access camera\",\n \"capacitor_statusBarFailed\": \"Failed to configure status bar\",\n \"capacitor_notInitialized\": \"Capacitor module is not initialized\",\n \"capacitor_pushCancelled\": \"The push operation was cancelled, timed out or the module was closed\",\n \"capacitor_pushCleanupFailed\": \"Push listeners could not be fully removed; retry cleanup or close the module\"\n}\n","{\n \"capacitor_initFailed\": \"Capacitorの初期化に失敗しました\",\n \"capacitor_initInProgress\": \"Capacitorの初期化は既に実行中です\",\n \"capacitor_notAvailable\": \"この環境ではCapacitorを利用できません\",\n \"capacitor_secureStorageClearFailed\": \"安全なストレージのログイン認証情報を完全に削除できませんでした。ログアウトを再試行してください\",\n \"capacitor_preferencesGetFailed\": \"Capacitor Preferencesからの読み取りに失敗しました\",\n \"capacitor_preferencesSetFailed\": \"Capacitor Preferencesへの書き込みに失敗しました\",\n \"capacitor_preferencesRemoveFailed\": \"Capacitor Preferencesからの削除に失敗しました\",\n \"capacitor_deviceInfoFailed\": \"デバイス情報の取得に失敗しました\",\n \"capacitor_appVersionFailed\": \"アプリのバージョンの取得に失敗しました\",\n \"capacitor_pushRegisterFailed\": \"プッシュ通知の登録に失敗しました\",\n \"capacitor_pushListenFailed\": \"プッシュ通知の受信設定に失敗しました\",\n \"capacitor_cameraFailed\": \"カメラへのアクセスに失敗しました\",\n \"capacitor_statusBarFailed\": \"ステータスバーの設定に失敗しました\",\n \"capacitor_notInitialized\": \"Capacitorモジュールが初期化されていません\",\n \"capacitor_pushCancelled\": \"プッシュ操作がキャンセルされたか、タイムアウトしたか、モジュールが終了しました\",\n \"capacitor_pushCleanupFailed\": \"プッシュリスナーを完全に削除できませんでした。クリーンアップを再試行するか、モジュールを終了してください\"\n}\n","{\n \"capacitor_initFailed\": \"Capacitor 初始化失败\",\n \"capacitor_initInProgress\": \"Capacitor 正在初始化中\",\n \"capacitor_notAvailable\": \"当前环境不支持 Capacitor\",\n \"capacitor_secureStorageClearFailed\": \"未能完全清除安全存储中的登录凭据,请重试退出\",\n \"capacitor_preferencesGetFailed\": \"读取 Capacitor Preferences 失败\",\n \"capacitor_preferencesSetFailed\": \"写入 Capacitor Preferences 失败\",\n \"capacitor_preferencesRemoveFailed\": \"删除 Capacitor Preferences 失败\",\n \"capacitor_deviceInfoFailed\": \"获取设备信息失败\",\n \"capacitor_appVersionFailed\": \"获取应用版本失败\",\n \"capacitor_pushRegisterFailed\": \"注册推送通知失败\",\n \"capacitor_pushListenFailed\": \"监听推送通知失败\",\n \"capacitor_cameraFailed\": \"访问相机失败\",\n \"capacitor_statusBarFailed\": \"配置状态栏失败\",\n \"capacitor_notInitialized\": \"Capacitor 模块未初始化\",\n \"capacitor_pushCancelled\": \"推送操作已取消、超时或模块已关闭\",\n \"capacitor_pushCleanupFailed\": \"推送监听器未完全移除,请重试清理或关闭模块\"\n}\n","/**\n * @h-ai/capacitor — i18n\n *\n * 模块 i18n 文案访问入口。\n * @module capacitor-i18n\n */\n\nimport { core } from '@h-ai/core'\nimport messagesEnUS from '../messages/en-US.json'\nimport messagesJaJP from '../messages/ja-JP.json'\nimport messagesZhCN from '../messages/zh-CN.json'\n\n/**\n * CapacitorMessageKey 的数据约束与操作契约。\n * @example 模块内部上下文\n * ```ts\n * const key: CapacitorMessageKey = 'capacitor_notAvailable'\n * const text = capacitorM(key)\n * void text\n * ```\n */\ntype CapacitorMessageKey = keyof typeof messagesZhCN\n\n/**\n * capacitor 模块 i18n 文案获取器\n *\n * @param key - 文案 Key\n * @returns 本地化后的文案字符串\n * @example 模块内部上下文\n * ```ts\n * const text = capacitorM('capacitor_notAvailable', { locale: 'en-US' })\n * void text\n * ```\n */\nexport const capacitorM = core.i18n.createMessageGetter<CapacitorMessageKey>({\n 'zh-CN': messagesZhCN,\n 'en-US': messagesEnUS,\n 'ja-JP': messagesJaJP,\n})\n","/**\n * @h-ai/capacitor — 类型定义\n *\n * Capacitor 原生桥接模块的公共类型。\n * @module capacitor-types\n */\n\nimport type { ErrorInfo, HaiResult } from '@h-ai/core'\nimport { core } from '@h-ai/core'\n\nconst CapacitorErrorInfo = {\n INIT_FAILED: '001:500',\n NOT_AVAILABLE: '002:400',\n INIT_IN_PROGRESS: '003:409',\n NOT_INITIALIZED: '010:500',\n PREFERENCES_GET_FAILED: '011:500',\n PREFERENCES_SET_FAILED: '012:500',\n PREFERENCES_REMOVE_FAILED: '013:500',\n DEVICE_INFO_FAILED: '020:500',\n APP_VERSION_FAILED: '021:500',\n PUSH_REGISTER_FAILED: '030:500',\n PUSH_LISTEN_FAILED: '031:500',\n PUSH_CLEANUP_FAILED: '032:500',\n CAMERA_FAILED: '040:500',\n STATUS_BAR_FAILED: '050:500',\n} as const satisfies ErrorInfo\n\n/**\n * Capacitor 模块的公共错误定义;业务操作通过 HaiResult 返回。\n * @example\n * ```ts\n * import { HaiCapacitorError } from '@h-ai/capacitor'\n * import { err } from '@h-ai/core'\n *\n * const result = err(HaiCapacitorError.NOT_AVAILABLE, 'Native bridge required')\n * if (!result.success) void result.error.code\n * ```\n */\nexport const HaiCapacitorError = core.error.buildHaiErrorsDef('capacitor', CapacitorErrorInfo)\n\n// ─── 子操作接口 ───\n\n/**\n * 设备信息操作\n * @example\n * ```ts\n * import type { DeviceOperations } from '@h-ai/capacitor'\n *\n * async function use(operations: DeviceOperations) {\n * const result = await operations.getInfo()\n * if (!result.success) return result.error.message\n * return result.data\n * }\n * // 由已初始化的 capacitor.device 提供这些操作。\n * ```\n */\nexport interface DeviceOperations {\n /** 获取设备信息(平台、型号、系统版本等) */\n getInfo: () => Promise<HaiResult<DeviceInfo>>\n /** 获取应用版本信息 */\n getAppVersion: () => Promise<HaiResult<{ version: string, build: string }>>\n}\n\n/**\n * 相机操作\n * @example\n * ```ts\n * import type { CameraOperations } from '@h-ai/capacitor'\n *\n * async function use(operations: CameraOperations) {\n * const result = await operations.takePhoto({ source: 'photos' })\n * if (!result.success) return result.error.message\n * return result.data\n * }\n * // 由已初始化的 capacitor.camera 提供这些操作。\n * ```\n */\nexport interface CameraOperations {\n /** 拍照或选取相册图片 */\n takePhoto: (options?: PhotoOptions) => Promise<HaiResult<PhotoResult>>\n}\n\n/**\n * 推送通知操作\n * @example\n * ```ts\n * import type { PushOperations } from '@h-ai/capacitor'\n *\n * async function use(operations: PushOperations) {\n * const result = await operations.register()\n * if (!result.success) return result.error.message\n * return result.data\n * }\n * // 由已初始化的 capacitor.push 提供这些操作。\n * ```\n */\nexport interface PushOperations {\n /** 注册原生 Token;30 秒总超时,可取消,结束时回收监听器。 */\n register: (options?: PushOptions) => Promise<HaiResult<PushRegistration>>\n /** 监听原生事件;设置阶段限时 30 秒,成功后由 cleanup/信号/模块关闭释放。 */\n listen: (callbacks: PushNotificationCallbacks, options?: PushOptions) => Promise<HaiResult<PushCleanup>>\n}\n\n/**\n * 状态栏操作\n * @example\n * ```ts\n * import type { StatusBarOperations } from '@h-ai/capacitor'\n *\n * async function use(operations: StatusBarOperations) {\n * const result = await operations.configure({ style: 'dark' })\n * if (!result.success) return result.error.message\n * return result.data\n * }\n * // 由已初始化的 capacitor.statusBar 提供这些操作。\n * ```\n */\nexport interface StatusBarOperations {\n /** 配置状态栏(样式、背景色、沉浸式) */\n configure: (config: StatusBarConfig) => Promise<HaiResult<void>>\n /** 显示状态栏 */\n show: () => Promise<HaiResult<void>>\n /** 隐藏状态栏 */\n hide: () => Promise<HaiResult<void>>\n}\n\n/**\n * Preferences 操作(安全读写,返回 HaiResult)\n * @example\n * ```ts\n * import type { PreferencesOperations } from '@h-ai/capacitor'\n *\n * async function use(operations: PreferencesOperations) {\n * const result = await operations.get('theme')\n * if (!result.success) return result.error.message\n * return result.data\n * }\n * // 由已初始化的 capacitor.preferences 提供这些操作。\n * ```\n */\nexport interface PreferencesOperations {\n /** 安全读取 Preference 值 */\n get: (key: string) => Promise<HaiResult<string | null>>\n /** 安全写入 Preference 值 */\n set: (key: string, value: string) => Promise<HaiResult<void>>\n /** 安全删除 Preference 值 */\n remove: (key: string) => Promise<HaiResult<void>>\n}\n\n// ─── 函数接口 ───\n\n/**\n * Capacitor 模块服务对象接口\n * @example\n * ```ts\n * import { capacitor } from '@h-ai/capacitor'\n *\n * const initialized = await capacitor.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const result = await capacitor.device.getInfo()\n * if (!result.success) throw new Error(result.error.message)\n * void result.data\n * } finally {\n * const closed = await capacitor.close()\n * if (!closed.success) throw new Error(closed.error.message)\n * }\n * ```\n */\nexport interface CapacitorFunctions {\n /** 初始化 Capacitor 模块 */\n init: () => Promise<HaiResult<void>>\n /** 关闭模块并回收推送监听;失败时保持不可用,保留句柄供再次 close 重试。 */\n close: () => Promise<HaiResult<void>>\n /** 获取当前平台 */\n getPlatform: () => string\n /** 是否运行在原生 App 中 */\n isNative: () => boolean\n /** 是否已初始化 */\n readonly isInitialized: boolean\n\n /** 设备信息操作 */\n readonly device: DeviceOperations\n /** 相机操作 */\n readonly camera: CameraOperations\n /** 推送通知操作 */\n readonly push: PushOperations\n /** 状态栏操作 */\n readonly statusBar: StatusBarOperations\n /** Preferences 安全读写操作 */\n readonly preferences: PreferencesOperations\n}\n\n// ─── 设备信息 ───\n\n/**\n * 设备平台\n * @example\n * ```ts\n * import type { DevicePlatform } from '@h-ai/capacitor'\n *\n * const value: DevicePlatform = 'android'\n * void value\n * ```\n */\nexport type DevicePlatform = 'ios' | 'android' | 'web'\n\n/**\n * 设备信息\n * @example\n * ```ts\n * import type { DeviceInfo } from '@h-ai/capacitor'\n *\n * const value: DeviceInfo = { platform: 'android', osVersion: '15', model: 'Example device', manufacturer: 'Example', isVirtual: false }\n * void value\n * ```\n */\nexport interface DeviceInfo {\n /** 平台(ios / android / web) */\n platform: DevicePlatform\n /** 操作系统版本(如 '14.5') */\n osVersion: string\n /** 设备型号(如 'iPhone 14 Pro') */\n model: string\n /** 设备制造商 */\n manufacturer: string\n /** 是否为虚拟设备(模拟器) */\n isVirtual: boolean\n /** 应用版本 */\n appVersion?: string\n /** 应用 Build 号 */\n appBuild?: string\n}\n\n// ─── 推送通知 ───\n\n/**\n * 推送流程的取消选项;listen 成功后信号仍可终止监听。\n * @example\n * ```ts\n * import type { PushOptions } from '@h-ai/capacitor'\n *\n * const value: PushOptions = { signal: new AbortController().signal }\n * void value\n * ```\n */\nexport interface PushOptions {\n /** 取消当前注册或监听,不影响其他消费者拥有的句柄。 */\n signal?: AbortSignal\n}\n\n/**\n * 幂等推送清理函数;原生 remove 失败返回错误,调用同一函数可重试。\n * @example\n * ```ts\n * import type { PushCleanup } from '@h-ai/capacitor'\n *\n * async function release(cleanup: PushCleanup) {\n * const result = await cleanup()\n * if (!result.success) return cleanup() // 同一所有权句柄允许重试清理。\n * return result\n * }\n * ```\n */\nexport type PushCleanup = () => Promise<HaiResult<void>>\n\n/**\n * 推送通知数据\n * @example\n * ```ts\n * import type { PushNotification } from '@h-ai/capacitor'\n *\n * const value: PushNotification = { id: 'notice_1', title: 'Order ready', data: { orderId: 'order_1' } }\n * void value\n * ```\n */\nexport interface PushNotification {\n /** 通知 ID */\n id: string\n /** 标题 */\n title?: string\n /** 正文 */\n body?: string\n /** 附加数据 */\n data?: Record<string, unknown>\n}\n\n/**\n * 推送注册结果\n * @example\n * ```ts\n * import type { PushRegistration } from '@h-ai/capacitor'\n *\n * const value: PushRegistration = { token: 'example-only-native-token' }\n * void value\n * ```\n */\nexport interface PushRegistration {\n /** 设备推送 Token */\n token: string\n}\n\n/**\n * 推送通知回调\n * @example\n * ```ts\n * import type { PushNotificationCallbacks } from '@h-ai/capacitor'\n *\n * const value: PushNotificationCallbacks = { onReceived: notification => { document.title = notification.title ?? 'Notice' } }\n * void value\n * ```\n */\nexport interface PushNotificationCallbacks {\n /** 收到推送时调用 */\n onReceived?: (notification: PushNotification) => void\n /** 用户点击推送时调用 */\n onActionPerformed?: (notification: PushNotification) => void\n}\n\n// ─── 相机 ───\n\n/**\n * 照片来源\n * @example\n * ```ts\n * import type { PhotoSource } from '@h-ai/capacitor'\n *\n * const value: PhotoSource = 'photos'\n * void value\n * ```\n */\nexport type PhotoSource = 'camera' | 'photos' | 'prompt'\n\n/**\n * 照片选项\n * @example\n * ```ts\n * import type { PhotoOptions } from '@h-ai/capacitor'\n *\n * const value: PhotoOptions = { source: 'photos', resultType: 'uri', quality: 90, width: 1200 }\n * void value\n * ```\n */\nexport interface PhotoOptions {\n /** 来源(默认 'prompt') */\n source?: PhotoSource\n /** 图片质量 0-100(默认 90) */\n quality?: number\n /** 最大宽度(像素) */\n width?: number\n /** 最大高度(像素) */\n height?: number\n /** 返回格式 */\n resultType?: 'uri' | 'base64' | 'dataUrl'\n}\n\n/**\n * 照片结果\n * @example\n * ```ts\n * import type { PhotoResult } from '@h-ai/capacitor'\n *\n * const value: PhotoResult = { data: 'file:///example/photo.jpeg', format: 'jpeg' }\n * void value\n * ```\n */\nexport interface PhotoResult {\n /** 图片路径或 base64 数据 */\n data: string\n /** 原生插件返回的格式扩展名(如 jpeg),不是 MIME 类型 */\n format: string\n}\n\n// ─── 状态栏 ───\n\n/**\n * 状态栏样式\n * @example\n * ```ts\n * import type { StatusBarStyle } from '@h-ai/capacitor'\n *\n * const value: StatusBarStyle = 'dark'\n * void value\n * ```\n */\nexport type StatusBarStyle = 'dark' | 'light' | 'default'\n\n/**\n * 状态栏配置\n * @example\n * ```ts\n * import type { StatusBarConfig } from '@h-ai/capacitor'\n *\n * const value: StatusBarConfig = { style: 'dark', overlay: false }\n * void value\n * ```\n */\nexport interface StatusBarConfig {\n /** 状态栏文字样式 */\n style?: StatusBarStyle\n /** 背景颜色(十六进制) */\n backgroundColor?: string\n /** 是否覆盖在内容上(沉浸式) */\n overlay?: boolean\n}\n","/**\n * @h-ai/capacitor — 相机 / 相册\n *\n * 封装 `@capacitor/camera` 插件,提供拍照与相册选择能力。\n *\n * @module capacitor-camera\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { PhotoOptions, PhotoResult } from './capacitor-types.js'\nimport { err, ok } from '@h-ai/core'\nimport { capacitorM } from './capacitor-i18n.js'\nimport { HaiCapacitorError } from './capacitor-types.js'\n\n/** 照片来源映射(内部使用) */\nconst SOURCE_MAP = {\n camera: 'Camera',\n photos: 'Photos',\n prompt: 'Prompt',\n} as const\n\n/** 结果类型映射(内部使用) */\nconst RESULT_TYPE_MAP = {\n uri: 'Uri',\n base64: 'Base64',\n dataUrl: 'DataUrl',\n} as const\n\n/**\n * 拍照或选取相册图片\n *\n * 需要安装 `@capacitor/camera` 插件。\n *\n * @param options - 照片选项\n * @returns 照片结果\n * @example\n * ```ts\n * import { capacitor } from '@h-ai/capacitor'\n *\n * const initialized = await capacitor.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const result = await capacitor.camera.takePhoto({ source: 'photos', width: 1200 })\n * if (!result.success) throw new Error(result.error.message)\n * void result.data\n * } finally {\n * const closed = await capacitor.close()\n * if (!closed.success) throw new Error(closed.error.message)\n * }\n * ```\n */\nexport async function takePhoto(options?: PhotoOptions): Promise<HaiResult<PhotoResult>> {\n try {\n const { Camera, CameraSource, CameraResultType } = await import('@capacitor/camera')\n\n const source = options?.source ?? 'prompt'\n const resultType = options?.resultType ?? 'uri'\n\n const photo = await Camera.getPhoto({\n quality: options?.quality ?? 90,\n source: CameraSource[SOURCE_MAP[source] as keyof typeof CameraSource],\n resultType: CameraResultType[RESULT_TYPE_MAP[resultType] as keyof typeof CameraResultType],\n width: options?.width,\n height: options?.height,\n })\n\n // 根据 resultType 返回对应数据\n let data: string\n if (resultType === 'base64') {\n data = photo.base64String ?? ''\n }\n else if (resultType === 'dataUrl') {\n data = photo.dataUrl ?? ''\n }\n else {\n data = photo.webPath ?? ''\n }\n\n return ok({\n data,\n format: photo.format,\n })\n }\n catch (cause) {\n return err(\n HaiCapacitorError.CAMERA_FAILED,\n capacitorM('capacitor_cameraFailed'),\n cause,\n )\n }\n}\n","/**\n * @h-ai/capacitor — 设备信息\n *\n * 封装 `@capacitor/device` 插件,提供统一的设备信息读取接口。\n *\n * @module capacitor-device\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { DeviceInfo } from './capacitor-types.js'\nimport { err, ok } from '@h-ai/core'\nimport { capacitorM } from './capacitor-i18n.js'\nimport { HaiCapacitorError } from './capacitor-types.js'\n\n/**\n * 获取设备信息\n *\n * 需要安装 `@capacitor/device` 插件。\n *\n * @returns 设备信息(平台、系统版本、型号等)\n * @example\n * ```ts\n * import { capacitor } from '@h-ai/capacitor'\n *\n * const initialized = await capacitor.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const result = await capacitor.device.getInfo()\n * if (!result.success) throw new Error(result.error.message)\n * void result.data\n * } finally {\n * const closed = await capacitor.close()\n * if (!closed.success) throw new Error(closed.error.message)\n * }\n * ```\n */\nexport async function getDeviceInfo(): Promise<HaiResult<DeviceInfo>> {\n try {\n const { Device } = await import('@capacitor/device')\n const info = await Device.getInfo()\n\n return ok({\n platform: info.platform as DeviceInfo['platform'],\n osVersion: info.osVersion,\n model: info.model,\n manufacturer: info.manufacturer,\n isVirtual: info.isVirtual,\n })\n }\n catch (cause) {\n return err(\n HaiCapacitorError.DEVICE_INFO_FAILED,\n capacitorM('capacitor_deviceInfoFailed'),\n cause,\n )\n }\n}\n\n/**\n * 获取应用版本信息\n *\n * @returns appVersion 与 appBuild\n * @example\n * ```ts\n * import { capacitor } from '@h-ai/capacitor'\n *\n * const initialized = await capacitor.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const result = await capacitor.device.getAppVersion()\n * if (!result.success) throw new Error(result.error.message)\n * void result.data\n * } finally {\n * const closed = await capacitor.close()\n * if (!closed.success) throw new Error(closed.error.message)\n * }\n * ```\n */\nexport async function getAppVersion(): Promise<HaiResult<{ version: string, build: string }>> {\n try {\n const { App } = await import('@capacitor/app')\n const info = await App.getInfo()\n\n return ok({\n version: info.version,\n build: info.build,\n })\n }\n catch (cause) {\n return err(\n HaiCapacitorError.APP_VERSION_FAILED,\n capacitorM('capacitor_appVersionFailed'),\n cause,\n )\n }\n}\n","/**\n * @h-ai/capacitor — 推送通知及其受管监听生命周期。\n * @module capacitor-push\n */\nimport type { PluginListenerHandle } from '@capacitor/core'\nimport type { HaiResult } from '@h-ai/core'\nimport type { PushCleanup, PushNotificationCallbacks, PushOptions, PushRegistration } from './capacitor-types.js'\nimport { core, err, ok } from '@h-ai/core'\nimport { capacitorM } from './capacitor-i18n.js'\nimport { HaiCapacitorError } from './capacitor-types.js'\n\nconst logger = core.logger.child({ module: 'capacitor', scope: 'push' })\n\n/**\n * 两类推送流程共用的资源所有权;关闭立即停止回调,迟到 handle 仍必须回收。\n * @example 模块内部上下文\n * ```ts\n * const scope: PushScope = createPushScope({ signal: new AbortController().signal })\n * try {\n * const state = await scope.wait(async () => 'ready')\n * scope.assertOpen()\n * void state\n * } finally {\n * await scope.dispose()\n * }\n * ```\n */\ninterface PushScope {\n readonly signal: AbortSignal\n assertOpen: () => void\n attach: (add: () => Promise<PluginListenerHandle>) => Promise<void>\n wait: <T>(operation: () => Promise<T>) => Promise<T>\n finishSetup: () => void\n dispose: () => Promise<void>\n}\n\nconst activeScopes = new Set<PushScope>()\n\n/** 为一次注册/监听建立所有权,不使用 removeAllListeners 影响其他消费者。 */\nfunction createPushScope(options?: PushOptions): PushScope {\n let scope: PushScope\n const controller = new AbortController()\n const handles = new Set<PluginListenerHandle>()\n const removals = new Map<PluginListenerHandle, Promise<void>>()\n let pending = 0\n let closing: Promise<void> | undefined\n let timer: ReturnType<typeof setTimeout> | undefined\n const cancelled = () => new Error(capacitorM('capacitor_pushCancelled'))\n\n function releaseIfComplete(): void {\n if (controller.signal.aborted && pending === 0 && handles.size === 0)\n activeScopes.delete(scope)\n }\n\n function remove(handle: PluginListenerHandle): Promise<void> {\n const current = removals.get(handle)\n if (current)\n return current\n const removal = Promise.resolve().then(() => handle.remove()).then(() => {\n handles.delete(handle)\n }).finally(() => {\n removals.delete(handle)\n releaseIfComplete()\n })\n removals.set(handle, removal)\n return removal\n }\n\n function finishSetup(): void {\n if (timer !== undefined) {\n clearTimeout(timer)\n timer = undefined\n }\n }\n\n function dispose(): Promise<void> {\n controller.abort()\n finishSetup()\n options?.signal?.removeEventListener('abort', onAbort)\n if (closing)\n return closing\n closing = Promise.allSettled([...handles].map(remove)).then((results) => {\n releaseIfComplete()\n if (results.some(result => result.status === 'rejected'))\n throw new Error(capacitorM('capacitor_pushCleanupFailed'))\n }).finally(() => { closing = undefined })\n return closing\n }\n\n function onAbort(): void {\n void dispose().catch(() => logger.warn('Push listener cleanup failed; retry cleanup or capacitor.close'))\n }\n\n scope = {\n signal: controller.signal,\n assertOpen() {\n if (controller.signal.aborted)\n throw cancelled()\n },\n async attach(add) {\n scope.assertOpen()\n pending++\n try {\n const handle = await add()\n handles.add(handle)\n if (controller.signal.aborted) {\n await remove(handle)\n throw cancelled()\n }\n }\n finally {\n pending--\n releaseIfComplete()\n }\n },\n async wait(operation) {\n scope.assertOpen()\n let interrupt: (() => void) | undefined\n const aborted = new Promise<never>((_, reject) => {\n interrupt = () => reject(cancelled())\n controller.signal.addEventListener('abort', interrupt, { once: true })\n })\n try {\n return await Promise.race([Promise.resolve().then(operation), aborted])\n }\n finally {\n if (interrupt)\n controller.signal.removeEventListener('abort', interrupt)\n }\n },\n finishSetup,\n dispose,\n }\n activeScopes.add(scope)\n timer = setTimeout(onAbort, 30_000)\n options?.signal?.addEventListener('abort', onAbort, { once: true })\n if (options?.signal?.aborted)\n onAbort()\n return scope\n}\n\n/** 原生能力必须实际存在;Web 插件不可作为 FCM/APNs 注册证明。 */\nasync function loadPushPlugin() {\n const { Capacitor } = await import('@capacitor/core')\n if (!Capacitor.isNativePlatform())\n throw new Error(capacitorM('capacitor_notAvailable'))\n return (await import('@capacitor/push-notifications')).PushNotifications\n}\n\n/**\n * 关闭模块所拥有的全部推送监听器;失败句柄保留以便再次 close 重试。\n * @returns 全部移除成功,或 PUSH_CLEANUP_FAILED;迟到句柄到达时立即移除。\n * @example\n * ```ts\n * import { capacitor } from '@h-ai/capacitor'\n *\n * // 关闭由本模块拥有的监听器,失败句柄可再次 close 重试。\n * const closed = await capacitor.close()\n * if (!closed.success) throw new Error(closed.error.message)\n * ```\n */\nexport async function closePushListeners(): Promise<HaiResult<void>> {\n const results = await Promise.allSettled([...activeScopes].map(scope => scope.dispose()))\n return results.some(result => result.status === 'rejected')\n ? err(HaiCapacitorError.PUSH_CLEANUP_FAILED, capacitorM('capacitor_pushCleanupFailed'))\n : ok(undefined)\n}\n\n/**\n * 注册原生推送 Token;30 秒包含权限、挂载监听器与原生注册等待。\n * 部分失败、超时、AbortSignal 和模块关闭都会回收已知及迟到句柄。\n * @param options - 可选取消信号;取消返回失败结果,不注册后续原生操作。\n * @returns 真实原生插件返回的 token 或 PUSH_REGISTER_FAILED。\n * @example\n * ```ts\n * import { capacitor } from '@h-ai/capacitor'\n *\n * const initialized = await capacitor.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const result = await capacitor.push.register({ signal: new AbortController().signal })\n * if (!result.success) throw new Error(result.error.message)\n * void result.data\n * } finally {\n * const closed = await capacitor.close()\n * if (!closed.success) throw new Error(closed.error.message)\n * }\n * ```\n */\nexport async function registerPush(options?: PushOptions): Promise<HaiResult<PushRegistration>> {\n const scope = createPushScope(options)\n try {\n const token = await scope.wait(async () => {\n const push = await loadPushPlugin()\n scope.assertOpen()\n const permission = await push.requestPermissions()\n scope.assertOpen()\n if (permission.receive !== 'granted')\n throw new Error(capacitorM('capacitor_pushRegisterFailed'))\n let resolveToken!: (value: string) => void\n let rejectToken!: (reason: Error) => void\n const tokenResult = new Promise<string>((resolve, reject) => {\n resolveToken = resolve\n rejectToken = reject\n })\n // 在触发 register 之前就订阅结果,避免同步插件回调丢失或未处理拒绝。\n const setup = async () => {\n await scope.attach(() => push.addListener('registration', (result) => {\n if (!scope.signal.aborted)\n resolveToken(result.value)\n }))\n await scope.attach(() => push.addListener('registrationError', () => {\n if (!scope.signal.aborted)\n rejectToken(new Error(capacitorM('capacitor_pushRegisterFailed')))\n }))\n scope.assertOpen()\n await push.register()\n }\n return (await Promise.all([setup(), tokenResult]))[1]\n })\n await scope.dispose()\n return ok({ token })\n }\n catch (cause) {\n await scope.dispose().catch(() => logger.warn('Push registration cleanup failed; retry capacitor.close'))\n return err(HaiCapacitorError.PUSH_REGISTER_FAILED, capacitorM('capacitor_pushRegisterFailed'), cause)\n }\n}\n\n/**\n * 监听原生推送事件;设置阶段限时 30 秒,之后由 cleanup、信号或模块关闭结束。\n * @param callbacks - 收到消息与点击消息的回调。\n * @param options - 可选取消信号,监听建立后仍有效。\n * @returns 幂等清理函数;清理失败可见且可重试,关闭后立即停止业务回调。\n * @example\n * ```ts\n * import { capacitor } from '@h-ai/capacitor'\n *\n * const initialized = await capacitor.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const listening = await capacitor.push.listen({ onReceived: notice => { document.title = notice.title ?? 'Notice' } })\n * if (!listening.success) throw new Error(listening.error.message)\n * const closed = await listening.data()\n * if (!closed.success) throw new Error(closed.error.message)\n * } finally {\n * const closed = await capacitor.close()\n * if (!closed.success) throw new Error(closed.error.message)\n * }\n * ```\n */\nexport async function listenPush(callbacks: PushNotificationCallbacks, options?: PushOptions): Promise<HaiResult<PushCleanup>> {\n const scope = createPushScope(options)\n try {\n await scope.wait(async () => {\n const push = await loadPushPlugin()\n scope.assertOpen()\n if (callbacks.onReceived) {\n await scope.attach(() => push.addListener('pushNotificationReceived', (notification) => {\n if (!scope.signal.aborted)\n callbacks.onReceived?.({ id: notification.id, title: notification.title, body: notification.body, data: notification.data as Record<string, unknown> })\n }))\n }\n if (callbacks.onActionPerformed) {\n await scope.attach(() => push.addListener('pushNotificationActionPerformed', (action) => {\n if (!scope.signal.aborted)\n callbacks.onActionPerformed?.({ id: action.notification.id, title: action.notification.title, body: action.notification.body, data: action.notification.data as Record<string, unknown> })\n }))\n }\n })\n scope.assertOpen()\n scope.finishSetup()\n return ok(async () => {\n try {\n await scope.dispose()\n return ok(undefined)\n }\n catch (cause) {\n return err(HaiCapacitorError.PUSH_CLEANUP_FAILED, capacitorM('capacitor_pushCleanupFailed'), cause)\n }\n })\n }\n catch (cause) {\n await scope.dispose().catch(() => logger.warn('Push setup cleanup failed; retry capacitor.close'))\n return err(HaiCapacitorError.PUSH_LISTEN_FAILED, capacitorM('capacitor_pushListenFailed'), cause)\n }\n}\n","/**\n * @h-ai/capacitor — 状态栏\n *\n * 封装 `@capacitor/status-bar` 插件,支持沉浸式状态栏配置。\n *\n * @module capacitor-status-bar\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { StatusBarConfig } from './capacitor-types.js'\nimport { err, ok } from '@h-ai/core'\nimport { capacitorM } from './capacitor-i18n.js'\nimport { HaiCapacitorError } from './capacitor-types.js'\n\n/**\n * 配置状态栏\n *\n * 需要安装 `@capacitor/status-bar` 插件。\n *\n * @param config - 状态栏配置\n * @returns HaiResult\n * @example\n * ```ts\n * import { capacitor } from '@h-ai/capacitor'\n *\n * const initialized = await capacitor.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const result = await capacitor.statusBar.configure({ style: 'dark', overlay: false })\n * if (!result.success) throw new Error(result.error.message)\n * void result.data\n * } finally {\n * const closed = await capacitor.close()\n * if (!closed.success) throw new Error(closed.error.message)\n * }\n * ```\n */\nexport async function configureStatusBar(config: StatusBarConfig): Promise<HaiResult<void>> {\n try {\n const { StatusBar, Style } = await import('@capacitor/status-bar')\n\n // 设置样式\n if (config.style) {\n const styleMap: Record<string, typeof Style[keyof typeof Style]> = {\n dark: Style.Dark,\n light: Style.Light,\n default: Style.Default,\n }\n await StatusBar.setStyle({ style: styleMap[config.style] ?? Style.Default })\n }\n\n // 设置背景色\n if (config.backgroundColor) {\n await StatusBar.setBackgroundColor({ color: config.backgroundColor })\n }\n\n // 设置覆盖模式\n if (config.overlay !== undefined) {\n await StatusBar.setOverlaysWebView({ overlay: config.overlay })\n }\n\n return ok(undefined)\n }\n catch (cause) {\n return err(\n HaiCapacitorError.STATUS_BAR_FAILED,\n capacitorM('capacitor_statusBarFailed'),\n cause,\n )\n }\n}\n\n/**\n * 显示状态栏\n *\n * @returns HaiResult\n * @example\n * ```ts\n * import { capacitor } from '@h-ai/capacitor'\n *\n * const initialized = await capacitor.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const result = await capacitor.statusBar.show()\n * if (!result.success) throw new Error(result.error.message)\n * void result.data\n * } finally {\n * const closed = await capacitor.close()\n * if (!closed.success) throw new Error(closed.error.message)\n * }\n * ```\n */\nexport async function showStatusBar(): Promise<HaiResult<void>> {\n try {\n const { StatusBar } = await import('@capacitor/status-bar')\n await StatusBar.show()\n return ok(undefined)\n }\n catch (cause) {\n return err(\n HaiCapacitorError.STATUS_BAR_FAILED,\n capacitorM('capacitor_statusBarFailed'),\n cause,\n )\n }\n}\n\n/**\n * 隐藏状态栏\n *\n * @returns HaiResult\n * @example\n * ```ts\n * import { capacitor } from '@h-ai/capacitor'\n *\n * const initialized = await capacitor.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const result = await capacitor.statusBar.hide()\n * if (!result.success) throw new Error(result.error.message)\n * void result.data\n * } finally {\n * const closed = await capacitor.close()\n * if (!closed.success) throw new Error(closed.error.message)\n * }\n * ```\n */\nexport async function hideStatusBar(): Promise<HaiResult<void>> {\n try {\n const { StatusBar } = await import('@capacitor/status-bar')\n await StatusBar.hide()\n return ok(undefined)\n }\n catch (cause) {\n return err(\n HaiCapacitorError.STATUS_BAR_FAILED,\n capacitorM('capacitor_statusBarFailed'),\n cause,\n )\n }\n}\n","/**\n * @h-ai/capacitor — Token 存储\n *\n * 基于原生安全存储插件的 TokenStorage 实现。\n * 仅在 Capacitor 原生环境启用,拒绝回退到不安全的 Web 存储。\n *\n * @module capacitor-token-storage\n */\n\nimport type { SecureStoragePlugin } from '@aparajita/capacitor-secure-storage'\nimport type { TokenStorage } from '@h-ai/api-client'\nimport type { HaiResult } from '@h-ai/core'\nimport { Preferences } from '@capacitor/preferences'\nimport { err, ok } from '@h-ai/core'\nimport { capacitorM } from './capacitor-i18n.js'\nimport { HaiCapacitorError } from './capacitor-types.js'\n\n/** 原生安全存储 Key;普通 Preferences 不存放认证凭据。 */\nconst PREF_ACCESS_TOKEN = 'hai_access_token'\nconst PREF_REFRESH_TOKEN = 'hai_refresh_token'\n\n/** 动态 import 自带模块缓存;不永久缓存平台检查失败或缺失插件的结果。 */\nasync function loadSecureStoragePlugin(): Promise<SecureStoragePlugin> {\n const { Capacitor } = await import('@capacitor/core')\n if (!Capacitor.isNativePlatform())\n throw new Error(capacitorM('capacitor_notAvailable'))\n const { SecureStorage } = await import('@aparajita/capacitor-secure-storage')\n return SecureStorage\n}\n\n/**\n * 创建基于原生安全存储的 TokenStorage\n *\n * 在原生 Android/iOS 环境下使用 `@aparajita/capacitor-secure-storage`\n * 保存 access token / refresh token。所有方法的存储/平台错误均通过 Promise 拒绝传播,\n * Web 调用明确失败,不做存储回退或伪成功。\n * `clear()` 一开始即屏蔽本实例旧凭据,删除失败时仍保持屏蔽;相应 key 成功写入后恢复读取。\n * 任一凭据写入失败也会屏蔽整对凭据,避免 access 已保存、refresh 失败时暴露半完成登录。\n * 本实例屏蔽不代表原生持久数据已删除;跨重启撤销仍依赖服务端退出/撤销会话。\n *\n * @returns TokenStorage 实例\n * @throws 返回适配器的方法在插件不可用或原生存储失败时拒绝 Promise。\n * @example\n * ```ts\n * import { createCapacitorTokenStorage } from '@h-ai/capacitor'\n *\n * const storage = createCapacitorTokenStorage()\n * try {\n * const token = await storage.getAccessToken()\n * void token // 仅原生安全存储;平台或存储失败会拒绝 Promise。\n * } catch (cause) {\n * // 应阻止认证流程继续并呈现本地化错误;不回退到普通 Preferences。\n * void cause\n * }\n * ```\n */\nexport function createCapacitorTokenStorage(): TokenStorage {\n let credentialGeneration = 0\n let accessBlocked = false\n let refreshBlocked = false\n\n /** 使本代际的读取/写入资格失效;实例内屏蔽不声称原生数据已经删除。 */\n function blockCredentials(): void {\n credentialGeneration++\n accessBlocked = true\n refreshBlocked = true\n }\n\n /** 部分写入失败时撤销整对本地凭据,交由认证调用方显式重试持久清理。 */\n async function writeToken(key: typeof PREF_ACCESS_TOKEN | typeof PREF_REFRESH_TOKEN, token: string): Promise<void> {\n const writeGeneration = credentialGeneration\n try {\n const storage = await loadSecureStoragePlugin()\n await storage.setItem(key, token)\n if (writeGeneration === credentialGeneration) {\n if (key === PREF_ACCESS_TOKEN)\n accessBlocked = false\n else\n refreshBlocked = false\n }\n }\n catch (error) {\n if (writeGeneration === credentialGeneration)\n blockCredentials()\n throw error\n }\n }\n\n return {\n async getAccessToken(): Promise<string | null> {\n const readGeneration = credentialGeneration\n const storage = await loadSecureStoragePlugin()\n if (accessBlocked)\n return null\n const token = await storage.getItem(PREF_ACCESS_TOKEN)\n return accessBlocked || readGeneration !== credentialGeneration ? null : token\n },\n\n async getRefreshToken(): Promise<string | null> {\n const readGeneration = credentialGeneration\n const storage = await loadSecureStoragePlugin()\n if (refreshBlocked)\n return null\n const token = await storage.getItem(PREF_REFRESH_TOKEN)\n return refreshBlocked || readGeneration !== credentialGeneration ? null : token\n },\n\n async setAccessToken(token: string): Promise<void> {\n await writeToken(PREF_ACCESS_TOKEN, token)\n },\n\n async setRefreshToken(token: string): Promise<void> {\n await writeToken(PREF_REFRESH_TOKEN, token)\n },\n\n async clear(): Promise<void> {\n blockCredentials()\n const storage = await loadSecureStoragePlugin()\n // 等全部删除完成再报告失败,避免迟到的删除与下一次登录写入交错。\n const results = await Promise.allSettled([\n storage.removeItem(PREF_ACCESS_TOKEN),\n storage.removeItem(PREF_REFRESH_TOKEN),\n ])\n const errors = results.filter(result => result.status === 'rejected').map(result => result.reason)\n if (errors.length > 0)\n throw new AggregateError(errors, capacitorM('capacitor_secureStorageClearFailed'))\n },\n }\n}\n\n/**\n * 安全读取 Preference 值(返回 HaiResult)\n *\n * @param key - Preference Key\n * @returns HaiResult 包裹的值\n * @example\n * ```ts\n * import { capacitor } from '@h-ai/capacitor'\n *\n * const initialized = await capacitor.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const result = await capacitor.preferences.get('theme')\n * if (!result.success) throw new Error(result.error.message)\n * void result.data\n * } finally {\n * const closed = await capacitor.close()\n * if (!closed.success) throw new Error(closed.error.message)\n * }\n * ```\n */\nexport async function safeGetPreference(key: string): Promise<HaiResult<string | null>> {\n try {\n const { value } = await Preferences.get({ key })\n return ok(value)\n }\n catch (cause) {\n return err(\n HaiCapacitorError.PREFERENCES_GET_FAILED,\n capacitorM('capacitor_preferencesGetFailed'),\n cause,\n )\n }\n}\n\n/**\n * 安全写入 Preference 值\n *\n * @param key - Preference Key\n * @param value - 要写入的值\n * @returns HaiResult\n * @example\n * ```ts\n * import { capacitor } from '@h-ai/capacitor'\n *\n * const initialized = await capacitor.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const result = await capacitor.preferences.set('theme', 'dark')\n * if (!result.success) throw new Error(result.error.message)\n * void result.data\n * } finally {\n * const closed = await capacitor.close()\n * if (!closed.success) throw new Error(closed.error.message)\n * }\n * ```\n */\nexport async function safeSetPreference(key: string, value: string): Promise<HaiResult<void>> {\n try {\n await Preferences.set({ key, value })\n return ok(undefined)\n }\n catch (cause) {\n return err(\n HaiCapacitorError.PREFERENCES_SET_FAILED,\n capacitorM('capacitor_preferencesSetFailed'),\n cause,\n )\n }\n}\n\n/**\n * 安全删除 Preference 值\n *\n * @param key - Preference Key\n * @returns HaiResult\n * @example\n * ```ts\n * import { capacitor } from '@h-ai/capacitor'\n *\n * const initialized = await capacitor.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const result = await capacitor.preferences.remove('theme')\n * if (!result.success) throw new Error(result.error.message)\n * void result.data\n * } finally {\n * const closed = await capacitor.close()\n * if (!closed.success) throw new Error(closed.error.message)\n * }\n * ```\n */\nexport async function safeRemovePreference(key: string): Promise<HaiResult<void>> {\n try {\n await Preferences.remove({ key })\n return ok(undefined)\n }\n catch (cause) {\n return err(\n HaiCapacitorError.PREFERENCES_REMOVE_FAILED,\n capacitorM('capacitor_preferencesRemoveFailed'),\n cause,\n )\n }\n}\n","/**\n * @h-ai/capacitor — 模块入口(生命周期管理)\n *\n * 提供 Capacitor 原生桥接的初始化与环境检测。\n * `capacitor.init()` 应在应用启动时调用,用于检测 Capacitor 环境可用性。\n *\n * @module capacitor-main\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { CameraOperations, CapacitorFunctions, DeviceOperations, PreferencesOperations, PushOperations, StatusBarOperations } from './capacitor-types.js'\nimport { core, err, ok } from '@h-ai/core'\nimport { takePhoto } from './capacitor-camera.js'\nimport { getAppVersion, getDeviceInfo } from './capacitor-device.js'\nimport { capacitorM } from './capacitor-i18n.js'\nimport { closePushListeners, listenPush, registerPush } from './capacitor-push.js'\nimport { configureStatusBar, hideStatusBar, showStatusBar } from './capacitor-status-bar.js'\nimport { safeGetPreference, safeRemovePreference, safeSetPreference } from './capacitor-token-storage.js'\nimport { HaiCapacitorError } from './capacitor-types.js'\n\nconst logger = core.logger.child({ module: 'capacitor', scope: 'main' })\n\n/** 是否已初始化 */\nlet initialized = false\n\n/** 是否正在初始化中(并发防护) */\nlet initInProgress = false\n\n/** 缓存平台信息 */\nlet cachedPlatform: string | null = null\n\n// ─── 未初始化代理 ───\n\nconst notInitialized = core.module.createNotInitializedKit(\n HaiCapacitorError.NOT_INITIALIZED,\n () => capacitorM('capacitor_notInitialized'),\n)\n\nconst notInitializedDevice = notInitialized.proxy<DeviceOperations>()\nconst notInitializedCamera = notInitialized.proxy<CameraOperations>()\nconst notInitializedPush = notInitialized.proxy<PushOperations>()\nconst notInitializedStatusBar = notInitialized.proxy<StatusBarOperations>()\nconst notInitializedPreferences = notInitialized.proxy<PreferencesOperations>()\n\n// ─── 已初始化时的操作实现 ───\n\nconst deviceOps: DeviceOperations = {\n getInfo: getDeviceInfo,\n getAppVersion,\n}\n\nconst cameraOps: CameraOperations = {\n takePhoto,\n}\n\nconst pushOps: PushOperations = {\n register: registerPush,\n listen: listenPush,\n}\n\nconst statusBarOps: StatusBarOperations = {\n configure: configureStatusBar,\n show: showStatusBar,\n hide: hideStatusBar,\n}\n\nconst preferencesOps: PreferencesOperations = {\n get: safeGetPreference,\n set: safeSetPreference,\n remove: safeRemovePreference,\n}\n\n// ─── 检测 Capacitor 是否可用(模块内部使用) ───\n\nfunction isCapacitorAvailable(): boolean {\n try {\n // window 上由 Capacitor 运行时注入 Capacitor 全局对象,lib.dom 未声明该属性,故强转为可查库的 Record\n return typeof window !== 'undefined'\n && (window as unknown as Record<string, unknown>).Capacitor !== undefined\n }\n catch {\n return false\n }\n}\n\n// ─── 服务对象 ───\n\n/**\n * Capacitor 模块服务对象\n * @example\n * ```ts\n * import { capacitor } from '@h-ai/capacitor'\n *\n * const initialized = await capacitor.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const result = await capacitor.device.getInfo()\n * if (!result.success) throw new Error(result.error.message)\n * void result.data\n * } finally {\n * const closed = await capacitor.close()\n * if (!closed.success) throw new Error(closed.error.message)\n * }\n * ```\n */\nexport const capacitor: CapacitorFunctions = {\n async init(): Promise<HaiResult<void>> {\n // 并发初始化防护:避免多次 init 同时执行导致资源泄漏\n if (initInProgress) {\n logger.warn('Capacitor init already in progress, skipping concurrent call')\n return err(\n HaiCapacitorError.INIT_IN_PROGRESS,\n capacitorM('capacitor_initInProgress'),\n )\n }\n initInProgress = true\n\n try {\n if (initialized) {\n logger.warn('Capacitor module is already initialized, reinitializing')\n const closed = await capacitor.close()\n if (!closed.success)\n return closed\n }\n // 先重试上次关闭未释放的句柄,不把资源清理失败隐藏成新的初始化成功。\n const cleaned = await closePushListeners()\n if (!cleaned.success)\n return cleaned\n\n logger.info('Initializing capacitor module')\n\n if (!isCapacitorAvailable()) {\n logger.error('Capacitor is not available in current environment')\n return err(\n HaiCapacitorError.NOT_AVAILABLE,\n capacitorM('capacitor_notAvailable'),\n )\n }\n\n const { Capacitor } = await import('@capacitor/core')\n const platform = Capacitor.getPlatform()\n\n if (!platform) {\n logger.error('Capacitor initialization failed, platform not detected')\n return err(\n HaiCapacitorError.INIT_FAILED,\n capacitorM('capacitor_initFailed'),\n )\n }\n\n cachedPlatform = platform\n initialized = true\n logger.info('Capacitor module initialized', { platform })\n return ok(undefined)\n }\n catch (cause) {\n logger.error('Capacitor module initialization failed', { error: cause })\n return err(\n HaiCapacitorError.INIT_FAILED,\n capacitorM('capacitor_initFailed'),\n cause,\n )\n }\n finally {\n initInProgress = false\n }\n },\n\n async close() {\n logger.info('Closing capacitor module')\n initialized = false\n cachedPlatform = null\n const cleaned = await closePushListeners()\n if (!cleaned.success)\n return cleaned\n logger.info('Capacitor module closed')\n return ok(undefined)\n },\n\n getPlatform(): string {\n if (cachedPlatform) {\n return cachedPlatform\n }\n try {\n // 同 isCapacitorAvailable:Capacitor 全局仅在运行时由 native bridge 注入,需强转后读取\n const cap = (window as unknown as Record<string, unknown>).Capacitor as { getPlatform?: () => string } | undefined\n return cap?.getPlatform?.() ?? 'web'\n }\n catch {\n return 'web'\n }\n },\n\n isNative(): boolean {\n try {\n const cap = (window as unknown as Record<string, unknown>).Capacitor as { isNativePlatform?: () => boolean } | undefined\n return cap?.isNativePlatform?.() ?? false\n }\n catch {\n return false\n }\n },\n\n get isInitialized(): boolean {\n return initialized\n },\n\n get device(): DeviceOperations {\n return initialized ? deviceOps : notInitializedDevice\n },\n\n get camera(): CameraOperations {\n return initialized ? cameraOps : notInitializedCamera\n },\n\n get push(): PushOperations {\n return initialized ? pushOps : notInitializedPush\n },\n\n get statusBar(): StatusBarOperations {\n return initialized ? statusBarOps : notInitializedStatusBar\n },\n\n get preferences(): PreferencesOperations {\n return initialized ? preferencesOps : notInitializedPreferences\n },\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../messages/en-US.json","../messages/ja-JP.json","../messages/zh-CN.json","../src/capacitor-i18n.ts","../src/capacitor-types.ts","../src/capacitor-camera.ts","../src/capacitor-device.ts","../src/capacitor-push.ts","../src/capacitor-status-bar.ts","../src/capacitor-token-storage.ts","../src/capacitor-main.ts"],"names":["core","ok","err","logger"],"mappings":"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","file":"index.js","sourcesContent":["{\n \"capacitor_initFailed\": \"Capacitor initialization failed\",\n \"capacitor_initInProgress\": \"Capacitor initialization is already in progress\",\n \"capacitor_notAvailable\": \"Capacitor is not available in this environment\",\n \"capacitor_secureStorageClearFailed\": \"Could not fully clear sign-in credentials from secure storage; retry signing out\",\n \"capacitor_preferencesGetFailed\": \"Failed to read from Capacitor Preferences\",\n \"capacitor_preferencesSetFailed\": \"Failed to write to Capacitor Preferences\",\n \"capacitor_preferencesRemoveFailed\": \"Failed to remove from Capacitor Preferences\",\n \"capacitor_deviceInfoFailed\": \"Failed to get device info\",\n \"capacitor_appVersionFailed\": \"Failed to get app version\",\n \"capacitor_pushRegisterFailed\": \"Failed to register push notifications\",\n \"capacitor_pushListenFailed\": \"Failed to listen for push notifications\",\n \"capacitor_cameraFailed\": \"Failed to access camera\",\n \"capacitor_statusBarFailed\": \"Failed to configure status bar\",\n \"capacitor_notInitialized\": \"Capacitor module is not initialized\",\n \"capacitor_pushCancelled\": \"The push operation was cancelled, timed out or the module was closed\",\n \"capacitor_pushCleanupFailed\": \"Push listeners could not be fully removed; retry cleanup or close the module\"\n}\n","{\n \"capacitor_initFailed\": \"Capacitorの初期化に失敗しました\",\n \"capacitor_initInProgress\": \"Capacitorの初期化は既に実行中です\",\n \"capacitor_notAvailable\": \"この環境ではCapacitorを利用できません\",\n \"capacitor_secureStorageClearFailed\": \"安全なストレージのログイン認証情報を完全に削除できませんでした。ログアウトを再試行してください\",\n \"capacitor_preferencesGetFailed\": \"Capacitor Preferencesからの読み取りに失敗しました\",\n \"capacitor_preferencesSetFailed\": \"Capacitor Preferencesへの書き込みに失敗しました\",\n \"capacitor_preferencesRemoveFailed\": \"Capacitor Preferencesからの削除に失敗しました\",\n \"capacitor_deviceInfoFailed\": \"デバイス情報の取得に失敗しました\",\n \"capacitor_appVersionFailed\": \"アプリのバージョンの取得に失敗しました\",\n \"capacitor_pushRegisterFailed\": \"プッシュ通知の登録に失敗しました\",\n \"capacitor_pushListenFailed\": \"プッシュ通知の受信設定に失敗しました\",\n \"capacitor_cameraFailed\": \"カメラへのアクセスに失敗しました\",\n \"capacitor_statusBarFailed\": \"ステータスバーの設定に失敗しました\",\n \"capacitor_notInitialized\": \"Capacitorモジュールが初期化されていません\",\n \"capacitor_pushCancelled\": \"プッシュ操作がキャンセルされたか、タイムアウトしたか、モジュールが終了しました\",\n \"capacitor_pushCleanupFailed\": \"プッシュリスナーを完全に削除できませんでした。クリーンアップを再試行するか、モジュールを終了してください\"\n}\n","{\n \"capacitor_initFailed\": \"Capacitor 初始化失败\",\n \"capacitor_initInProgress\": \"Capacitor 正在初始化中\",\n \"capacitor_notAvailable\": \"当前环境不支持 Capacitor\",\n \"capacitor_secureStorageClearFailed\": \"未能完全清除安全存储中的登录凭据,请重试退出\",\n \"capacitor_preferencesGetFailed\": \"读取 Capacitor Preferences 失败\",\n \"capacitor_preferencesSetFailed\": \"写入 Capacitor Preferences 失败\",\n \"capacitor_preferencesRemoveFailed\": \"删除 Capacitor Preferences 失败\",\n \"capacitor_deviceInfoFailed\": \"获取设备信息失败\",\n \"capacitor_appVersionFailed\": \"获取应用版本失败\",\n \"capacitor_pushRegisterFailed\": \"注册推送通知失败\",\n \"capacitor_pushListenFailed\": \"监听推送通知失败\",\n \"capacitor_cameraFailed\": \"访问相机失败\",\n \"capacitor_statusBarFailed\": \"配置状态栏失败\",\n \"capacitor_notInitialized\": \"Capacitor 模块未初始化\",\n \"capacitor_pushCancelled\": \"推送操作已取消、超时或模块已关闭\",\n \"capacitor_pushCleanupFailed\": \"推送监听器未完全移除,请重试清理或关闭模块\"\n}\n","/**\n * @h-ai/capacitor — i18n\n *\n * 模块 i18n 文案访问入口。\n * @module capacitor-i18n\n */\n\nimport { core } from '@h-ai/core'\nimport messagesEnUS from '../messages/en-US.json'\nimport messagesJaJP from '../messages/ja-JP.json'\nimport messagesZhCN from '../messages/zh-CN.json'\n\n/**\n * CapacitorMessageKey 的数据约束与操作契约。\n * @example 模块内部上下文\n * ```ts\n * const key: CapacitorMessageKey = 'capacitor_notAvailable'\n * const text = capacitorM(key)\n * void text\n * ```\n */\ntype CapacitorMessageKey = keyof typeof messagesZhCN\n\n/**\n * capacitor 模块 i18n 文案获取器\n *\n * @param key - 文案 Key\n * @returns 本地化后的文案字符串\n * @example 模块内部上下文\n * ```ts\n * const text = capacitorM('capacitor_notAvailable', { locale: 'en-US' })\n * void text\n * ```\n */\nexport const capacitorM = core.i18n.createMessageGetter<CapacitorMessageKey>({\n 'zh-CN': messagesZhCN,\n 'en-US': messagesEnUS,\n 'ja-JP': messagesJaJP,\n})\n","/**\n * @h-ai/capacitor — 类型定义\n *\n * Capacitor 原生桥接模块的公共类型。\n * @module capacitor-types\n */\n\nimport type { ErrorInfo, HaiResult } from '@h-ai/core'\nimport { core } from '@h-ai/core'\n\nconst CapacitorErrorInfo = {\n INIT_FAILED: '001:500',\n NOT_AVAILABLE: '002:400',\n INIT_IN_PROGRESS: '003:409',\n NOT_INITIALIZED: '010:500',\n PREFERENCES_GET_FAILED: '011:500',\n PREFERENCES_SET_FAILED: '012:500',\n PREFERENCES_REMOVE_FAILED: '013:500',\n DEVICE_INFO_FAILED: '020:500',\n APP_VERSION_FAILED: '021:500',\n PUSH_REGISTER_FAILED: '030:500',\n PUSH_LISTEN_FAILED: '031:500',\n PUSH_CLEANUP_FAILED: '032:500',\n CAMERA_FAILED: '040:500',\n STATUS_BAR_FAILED: '050:500',\n} as const satisfies ErrorInfo\n\n/**\n * Capacitor 模块的公共错误定义;业务操作通过 HaiResult 返回。\n * @example\n * ```ts\n * import { HaiCapacitorError } from '@h-ai/capacitor'\n * import { err } from '@h-ai/core'\n *\n * const result = err(HaiCapacitorError.NOT_AVAILABLE, 'Native bridge required')\n * if (!result.success) void result.error.code\n * ```\n */\nexport const HaiCapacitorError = core.error.buildHaiErrorsDef('capacitor', CapacitorErrorInfo)\n\n// ─── 子操作接口 ───\n\n/**\n * 设备信息操作\n * @example\n * ```ts\n * import type { DeviceOperations } from '@h-ai/capacitor'\n *\n * async function use(operations: DeviceOperations) {\n * const result = await operations.getInfo()\n * if (!result.success) return result.error.message\n * return result.data\n * }\n * // 由已初始化的 capacitor.device 提供这些操作。\n * ```\n */\nexport interface DeviceOperations {\n /** 获取设备信息(平台、型号、系统版本等) */\n getInfo: () => Promise<HaiResult<DeviceInfo>>\n /** 获取应用版本信息 */\n getAppVersion: () => Promise<HaiResult<{ version: string, build: string }>>\n}\n\n/**\n * 相机操作\n * @example\n * ```ts\n * import type { CameraOperations } from '@h-ai/capacitor'\n *\n * async function use(operations: CameraOperations) {\n * const result = await operations.takePhoto({ source: 'photos' })\n * if (!result.success) return result.error.message\n * return result.data\n * }\n * // 由已初始化的 capacitor.camera 提供这些操作。\n * ```\n */\nexport interface CameraOperations {\n /** 拍照或选取相册图片 */\n takePhoto: (options?: PhotoOptions) => Promise<HaiResult<PhotoResult>>\n}\n\n/**\n * 推送通知操作\n * @example\n * ```ts\n * import type { PushOperations } from '@h-ai/capacitor'\n *\n * async function use(operations: PushOperations) {\n * const result = await operations.register()\n * if (!result.success) return result.error.message\n * return result.data\n * }\n * // 由已初始化的 capacitor.push 提供这些操作。\n * ```\n */\nexport interface PushOperations {\n /** 注册原生 Token;30 秒总超时,可取消,结束时回收监听器。 */\n register: (options?: PushOptions) => Promise<HaiResult<PushRegistration>>\n /** 监听原生事件;设置阶段限时 30 秒,成功后由 cleanup/信号/模块关闭释放。 */\n listen: (callbacks: PushNotificationCallbacks, options?: PushOptions) => Promise<HaiResult<PushCleanup>>\n}\n\n/**\n * 状态栏操作\n * @example\n * ```ts\n * import type { StatusBarOperations } from '@h-ai/capacitor'\n *\n * async function use(operations: StatusBarOperations) {\n * const result = await operations.configure({ style: 'dark' })\n * if (!result.success) return result.error.message\n * return result.data\n * }\n * // 由已初始化的 capacitor.statusBar 提供这些操作。\n * ```\n */\nexport interface StatusBarOperations {\n /** 配置状态栏(样式、背景色、沉浸式) */\n configure: (config: StatusBarConfig) => Promise<HaiResult<void>>\n /** 显示状态栏 */\n show: () => Promise<HaiResult<void>>\n /** 隐藏状态栏 */\n hide: () => Promise<HaiResult<void>>\n}\n\n/**\n * Preferences 操作(安全读写,返回 HaiResult)\n * @example\n * ```ts\n * import type { PreferencesOperations } from '@h-ai/capacitor'\n *\n * async function use(operations: PreferencesOperations) {\n * const result = await operations.get('theme')\n * if (!result.success) return result.error.message\n * return result.data\n * }\n * // 由已初始化的 capacitor.preferences 提供这些操作。\n * ```\n */\nexport interface PreferencesOperations {\n /** 安全读取 Preference 值 */\n get: (key: string) => Promise<HaiResult<string | null>>\n /** 安全写入 Preference 值 */\n set: (key: string, value: string) => Promise<HaiResult<void>>\n /** 安全删除 Preference 值 */\n remove: (key: string) => Promise<HaiResult<void>>\n}\n\n// ─── 函数接口 ───\n\n/**\n * Capacitor 模块服务对象接口\n * @example\n * ```ts\n * import { capacitor } from '@h-ai/capacitor'\n *\n * const initialized = await capacitor.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const result = await capacitor.device.getInfo()\n * if (!result.success) throw new Error(result.error.message)\n * void result.data\n * } finally {\n * const closed = await capacitor.close()\n * if (!closed.success) throw new Error(closed.error.message)\n * }\n * ```\n */\nexport interface CapacitorFunctions {\n /** 初始化 Capacitor 模块 */\n init: () => Promise<HaiResult<void>>\n /** 关闭模块并回收推送监听;失败时保持不可用,保留句柄供再次 close 重试。 */\n close: () => Promise<HaiResult<void>>\n /** 获取当前平台 */\n getPlatform: () => string\n /** 是否运行在原生 App 中 */\n isNative: () => boolean\n /** 是否已初始化 */\n readonly isInitialized: boolean\n\n /** 设备信息操作 */\n readonly device: DeviceOperations\n /** 相机操作 */\n readonly camera: CameraOperations\n /** 推送通知操作 */\n readonly push: PushOperations\n /** 状态栏操作 */\n readonly statusBar: StatusBarOperations\n /** Preferences 安全读写操作 */\n readonly preferences: PreferencesOperations\n}\n\n// ─── 设备信息 ───\n\n/**\n * 设备平台\n * @example\n * ```ts\n * import type { DevicePlatform } from '@h-ai/capacitor'\n *\n * const value: DevicePlatform = 'android'\n * void value\n * ```\n */\nexport type DevicePlatform = 'ios' | 'android' | 'web'\n\n/**\n * 设备信息\n * @example\n * ```ts\n * import type { DeviceInfo } from '@h-ai/capacitor'\n *\n * const value: DeviceInfo = { platform: 'android', osVersion: '15', model: 'Example device', manufacturer: 'Example', isVirtual: false }\n * void value\n * ```\n */\nexport interface DeviceInfo {\n /** 平台(ios / android / web) */\n platform: DevicePlatform\n /** 操作系统版本(如 '14.5') */\n osVersion: string\n /** 设备型号(如 'iPhone 14 Pro') */\n model: string\n /** 设备制造商 */\n manufacturer: string\n /** 是否为虚拟设备(模拟器) */\n isVirtual: boolean\n /** 应用版本 */\n appVersion?: string\n /** 应用 Build 号 */\n appBuild?: string\n}\n\n// ─── 推送通知 ───\n\n/**\n * 推送流程的取消选项;listen 成功后信号仍可终止监听。\n * @example\n * ```ts\n * import type { PushOptions } from '@h-ai/capacitor'\n *\n * const value: PushOptions = { signal: new AbortController().signal }\n * void value\n * ```\n */\nexport interface PushOptions {\n /** 取消当前注册或监听,不影响其他消费者拥有的句柄。 */\n signal?: AbortSignal\n}\n\n/**\n * 幂等推送清理函数;原生 remove 失败返回错误,调用同一函数可重试。\n * @example\n * ```ts\n * import type { PushCleanup } from '@h-ai/capacitor'\n *\n * async function release(cleanup: PushCleanup) {\n * const result = await cleanup()\n * if (!result.success) return cleanup() // 同一所有权句柄允许重试清理。\n * return result\n * }\n * ```\n */\nexport type PushCleanup = () => Promise<HaiResult<void>>\n\n/**\n * 推送通知数据\n * @example\n * ```ts\n * import type { PushNotification } from '@h-ai/capacitor'\n *\n * const value: PushNotification = { id: 'notice_1', title: 'Order ready', data: { orderId: 'order_1' } }\n * void value\n * ```\n */\nexport interface PushNotification {\n /** 通知 ID */\n id: string\n /** 标题 */\n title?: string\n /** 正文 */\n body?: string\n /** 附加数据 */\n data?: Record<string, unknown>\n}\n\n/**\n * 推送注册结果\n * @example\n * ```ts\n * import type { PushRegistration } from '@h-ai/capacitor'\n *\n * const value: PushRegistration = { token: 'example-only-native-token' }\n * void value\n * ```\n */\nexport interface PushRegistration {\n /** 设备推送 Token */\n token: string\n}\n\n/**\n * 推送通知回调\n * @example\n * ```ts\n * import type { PushNotificationCallbacks } from '@h-ai/capacitor'\n *\n * const value: PushNotificationCallbacks = { onReceived: notification => { document.title = notification.title ?? 'Notice' } }\n * void value\n * ```\n */\nexport interface PushNotificationCallbacks {\n /** 收到推送时调用 */\n onReceived?: (notification: PushNotification) => void\n /** 用户点击推送时调用 */\n onActionPerformed?: (notification: PushNotification) => void\n}\n\n// ─── 相机 ───\n\n/**\n * 照片来源\n * @example\n * ```ts\n * import type { PhotoSource } from '@h-ai/capacitor'\n *\n * const value: PhotoSource = 'photos'\n * void value\n * ```\n */\nexport type PhotoSource = 'camera' | 'photos' | 'prompt'\n\n/**\n * 照片选项\n * @example\n * ```ts\n * import type { PhotoOptions } from '@h-ai/capacitor'\n *\n * const value: PhotoOptions = { source: 'photos', resultType: 'uri', quality: 90, width: 1200 }\n * void value\n * ```\n */\nexport interface PhotoOptions {\n /** 来源(默认 'prompt') */\n source?: PhotoSource\n /** 图片质量 0-100(默认 90) */\n quality?: number\n /** 最大宽度(像素) */\n width?: number\n /** 最大高度(像素) */\n height?: number\n /** 返回格式 */\n resultType?: 'uri' | 'base64' | 'dataUrl'\n}\n\n/**\n * 照片结果\n * @example\n * ```ts\n * import type { PhotoResult } from '@h-ai/capacitor'\n *\n * const value: PhotoResult = { data: 'file:///example/photo.jpeg', format: 'jpeg' }\n * void value\n * ```\n */\nexport interface PhotoResult {\n /** 图片路径或 base64 数据 */\n data: string\n /** 原生插件返回的格式扩展名(如 jpeg),不是 MIME 类型 */\n format: string\n}\n\n// ─── 状态栏 ───\n\n/**\n * 状态栏样式\n * @example\n * ```ts\n * import type { StatusBarStyle } from '@h-ai/capacitor'\n *\n * const value: StatusBarStyle = 'dark'\n * void value\n * ```\n */\nexport type StatusBarStyle = 'dark' | 'light' | 'default'\n\n/**\n * 状态栏配置\n * @example\n * ```ts\n * import type { StatusBarConfig } from '@h-ai/capacitor'\n *\n * const value: StatusBarConfig = { style: 'dark', overlay: false }\n * void value\n * ```\n */\nexport interface StatusBarConfig {\n /** 状态栏文字样式 */\n style?: StatusBarStyle\n /** 背景颜色(十六进制) */\n backgroundColor?: string\n /** 是否覆盖在内容上(沉浸式) */\n overlay?: boolean\n}\n","/**\n * @h-ai/capacitor — 相机 / 相册\n *\n * 封装 `@capacitor/camera` 插件,提供拍照与相册选择能力。\n *\n * @module capacitor-camera\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { PhotoOptions, PhotoResult } from './capacitor-types.js'\nimport { err, ok } from '@h-ai/core'\nimport { capacitorM } from './capacitor-i18n.js'\nimport { HaiCapacitorError } from './capacitor-types.js'\n\n/** 照片来源映射(内部使用) */\nconst SOURCE_MAP = {\n camera: 'Camera',\n photos: 'Photos',\n prompt: 'Prompt',\n} as const\n\n/** 结果类型映射(内部使用) */\nconst RESULT_TYPE_MAP = {\n uri: 'Uri',\n base64: 'Base64',\n dataUrl: 'DataUrl',\n} as const\n\n/**\n * 拍照或选取相册图片\n *\n * 需要安装 `@capacitor/camera` 插件。\n *\n * @param options - 照片选项\n * @returns 照片结果\n * @example\n * ```ts\n * import { capacitor } from '@h-ai/capacitor'\n *\n * const initialized = await capacitor.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const result = await capacitor.camera.takePhoto({ source: 'photos', width: 1200 })\n * if (!result.success) throw new Error(result.error.message)\n * void result.data\n * } finally {\n * const closed = await capacitor.close()\n * if (!closed.success) throw new Error(closed.error.message)\n * }\n * ```\n */\nexport async function takePhoto(options?: PhotoOptions): Promise<HaiResult<PhotoResult>> {\n try {\n const { Camera, CameraSource, CameraResultType } = await import('@capacitor/camera')\n\n const source = options?.source ?? 'prompt'\n const resultType = options?.resultType ?? 'uri'\n\n const photo = await Camera.getPhoto({\n quality: options?.quality ?? 90,\n source: CameraSource[SOURCE_MAP[source] as keyof typeof CameraSource],\n resultType: CameraResultType[RESULT_TYPE_MAP[resultType] as keyof typeof CameraResultType],\n width: options?.width,\n height: options?.height,\n })\n\n // 根据 resultType 返回对应数据\n let data: string\n if (resultType === 'base64') {\n data = photo.base64String ?? ''\n }\n else if (resultType === 'dataUrl') {\n data = photo.dataUrl ?? ''\n }\n else {\n data = photo.webPath ?? ''\n }\n\n return ok({\n data,\n format: photo.format,\n })\n }\n catch (cause) {\n return err(\n HaiCapacitorError.CAMERA_FAILED,\n capacitorM('capacitor_cameraFailed'),\n cause,\n )\n }\n}\n","/**\n * @h-ai/capacitor — 设备信息\n *\n * 封装 `@capacitor/device` 插件,提供统一的设备信息读取接口。\n *\n * @module capacitor-device\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { DeviceInfo } from './capacitor-types.js'\nimport { err, ok } from '@h-ai/core'\nimport { capacitorM } from './capacitor-i18n.js'\nimport { HaiCapacitorError } from './capacitor-types.js'\n\n/**\n * 获取设备信息\n *\n * 需要安装 `@capacitor/device` 插件。\n *\n * @returns 设备信息(平台、系统版本、型号等)\n * @example\n * ```ts\n * import { capacitor } from '@h-ai/capacitor'\n *\n * const initialized = await capacitor.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const result = await capacitor.device.getInfo()\n * if (!result.success) throw new Error(result.error.message)\n * void result.data\n * } finally {\n * const closed = await capacitor.close()\n * if (!closed.success) throw new Error(closed.error.message)\n * }\n * ```\n */\nexport async function getDeviceInfo(): Promise<HaiResult<DeviceInfo>> {\n try {\n const { Device } = await import('@capacitor/device')\n const info = await Device.getInfo()\n\n return ok({\n platform: info.platform as DeviceInfo['platform'],\n osVersion: info.osVersion,\n model: info.model,\n manufacturer: info.manufacturer,\n isVirtual: info.isVirtual,\n })\n }\n catch (cause) {\n return err(\n HaiCapacitorError.DEVICE_INFO_FAILED,\n capacitorM('capacitor_deviceInfoFailed'),\n cause,\n )\n }\n}\n\n/**\n * 获取应用版本信息\n *\n * @returns appVersion 与 appBuild\n * @example\n * ```ts\n * import { capacitor } from '@h-ai/capacitor'\n *\n * const initialized = await capacitor.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const result = await capacitor.device.getAppVersion()\n * if (!result.success) throw new Error(result.error.message)\n * void result.data\n * } finally {\n * const closed = await capacitor.close()\n * if (!closed.success) throw new Error(closed.error.message)\n * }\n * ```\n */\nexport async function getAppVersion(): Promise<HaiResult<{ version: string, build: string }>> {\n try {\n const { App } = await import('@capacitor/app')\n const info = await App.getInfo()\n\n return ok({\n version: info.version,\n build: info.build,\n })\n }\n catch (cause) {\n return err(\n HaiCapacitorError.APP_VERSION_FAILED,\n capacitorM('capacitor_appVersionFailed'),\n cause,\n )\n }\n}\n","/**\n * @h-ai/capacitor — 推送通知及其受管监听生命周期。\n * @module capacitor-push\n */\nimport type { PluginListenerHandle } from '@capacitor/core'\nimport type { HaiResult } from '@h-ai/core'\nimport type { PushCleanup, PushNotificationCallbacks, PushOptions, PushRegistration } from './capacitor-types.js'\nimport { core, err, ok } from '@h-ai/core'\nimport { capacitorM } from './capacitor-i18n.js'\nimport { HaiCapacitorError } from './capacitor-types.js'\n\nconst logger = core.logger.child({ module: 'capacitor', scope: 'push' })\n\n/**\n * 两类推送流程共用的资源所有权;关闭立即停止回调,迟到 handle 仍必须回收。\n * @example 模块内部上下文\n * ```ts\n * const scope: PushScope = createPushScope({ signal: new AbortController().signal })\n * try {\n * const state = await scope.wait(async () => 'ready')\n * scope.assertOpen()\n * void state\n * } finally {\n * await scope.dispose()\n * }\n * ```\n */\ninterface PushScope {\n readonly signal: AbortSignal\n assertOpen: () => void\n attach: (add: () => Promise<PluginListenerHandle>) => Promise<void>\n wait: <T>(operation: () => Promise<T>) => Promise<T>\n finishSetup: () => void\n dispose: () => Promise<void>\n}\n\nconst activeScopes = new Set<PushScope>()\n\n/** 为一次注册/监听建立所有权,不使用 removeAllListeners 影响其他消费者。 */\nfunction createPushScope(options?: PushOptions): PushScope {\n let scope: PushScope\n const controller = new AbortController()\n const handles = new Set<PluginListenerHandle>()\n const removals = new Map<PluginListenerHandle, Promise<void>>()\n let pending = 0\n let closing: Promise<void> | undefined\n let timer: ReturnType<typeof setTimeout> | undefined\n const cancelled = () => new Error(capacitorM('capacitor_pushCancelled'))\n\n function releaseIfComplete(): void {\n if (controller.signal.aborted && pending === 0 && handles.size === 0)\n activeScopes.delete(scope)\n }\n\n function remove(handle: PluginListenerHandle): Promise<void> {\n const current = removals.get(handle)\n if (current)\n return current\n const removal = Promise.resolve().then(() => handle.remove()).then(() => {\n handles.delete(handle)\n }).finally(() => {\n removals.delete(handle)\n releaseIfComplete()\n })\n removals.set(handle, removal)\n return removal\n }\n\n function finishSetup(): void {\n if (timer !== undefined) {\n clearTimeout(timer)\n timer = undefined\n }\n }\n\n function dispose(): Promise<void> {\n controller.abort()\n finishSetup()\n options?.signal?.removeEventListener('abort', onAbort)\n if (closing)\n return closing\n closing = Promise.allSettled([...handles].map(remove)).then((results) => {\n releaseIfComplete()\n if (results.some(result => result.status === 'rejected'))\n throw new Error(capacitorM('capacitor_pushCleanupFailed'))\n }).finally(() => { closing = undefined })\n return closing\n }\n\n function onAbort(): void {\n void dispose().catch(() => logger.warn('Push listener cleanup failed; retry cleanup or capacitor.close'))\n }\n\n scope = {\n signal: controller.signal,\n assertOpen() {\n if (controller.signal.aborted)\n throw cancelled()\n },\n async attach(add) {\n scope.assertOpen()\n pending++\n try {\n const handle = await add()\n handles.add(handle)\n if (controller.signal.aborted) {\n await remove(handle)\n throw cancelled()\n }\n }\n finally {\n pending--\n releaseIfComplete()\n }\n },\n async wait(operation) {\n scope.assertOpen()\n let interrupt: (() => void) | undefined\n const aborted = new Promise<never>((_, reject) => {\n interrupt = () => reject(cancelled())\n controller.signal.addEventListener('abort', interrupt, { once: true })\n })\n try {\n return await Promise.race([\n Promise.resolve().then(operation),\n aborted,\n ])\n }\n finally {\n if (interrupt)\n controller.signal.removeEventListener('abort', interrupt)\n }\n },\n finishSetup,\n dispose,\n }\n activeScopes.add(scope)\n timer = setTimeout(onAbort, 30_000)\n options?.signal?.addEventListener('abort', onAbort, { once: true })\n if (options?.signal?.aborted)\n onAbort()\n return scope\n}\n\n/** 原生能力必须实际存在;Web 插件不可作为 FCM/APNs 注册证明。 */\nasync function loadPushPlugin() {\n const { Capacitor } = await import('@capacitor/core')\n if (!Capacitor.isNativePlatform())\n throw new Error(capacitorM('capacitor_notAvailable'))\n return (await import('@capacitor/push-notifications')).PushNotifications\n}\n\n/**\n * 关闭模块所拥有的全部推送监听器;失败句柄保留以便再次 close 重试。\n * @returns 全部移除成功,或 PUSH_CLEANUP_FAILED;迟到句柄到达时立即移除。\n * @example\n * ```ts\n * import { capacitor } from '@h-ai/capacitor'\n *\n * // 关闭由本模块拥有的监听器,失败句柄可再次 close 重试。\n * const closed = await capacitor.close()\n * if (!closed.success) throw new Error(closed.error.message)\n * ```\n */\nexport async function closePushListeners(): Promise<HaiResult<void>> {\n const results = await Promise.allSettled([...activeScopes].map(scope => scope.dispose()))\n return results.some(result => result.status === 'rejected')\n ? err(HaiCapacitorError.PUSH_CLEANUP_FAILED, capacitorM('capacitor_pushCleanupFailed'))\n : ok(undefined)\n}\n\n/**\n * 注册原生推送 Token;30 秒包含权限、挂载监听器与原生注册等待。\n * 部分失败、超时、AbortSignal 和模块关闭都会回收已知及迟到句柄。\n * @param options - 可选取消信号;取消返回失败结果,不注册后续原生操作。\n * @returns 真实原生插件返回的 token 或 PUSH_REGISTER_FAILED。\n * @example\n * ```ts\n * import { capacitor } from '@h-ai/capacitor'\n *\n * const initialized = await capacitor.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const result = await capacitor.push.register({ signal: new AbortController().signal })\n * if (!result.success) throw new Error(result.error.message)\n * void result.data\n * } finally {\n * const closed = await capacitor.close()\n * if (!closed.success) throw new Error(closed.error.message)\n * }\n * ```\n */\nexport async function registerPush(options?: PushOptions): Promise<HaiResult<PushRegistration>> {\n const scope = createPushScope(options)\n try {\n const token = await scope.wait(async () => {\n const push = await loadPushPlugin()\n scope.assertOpen()\n const permission = await push.requestPermissions()\n scope.assertOpen()\n if (permission.receive !== 'granted')\n throw new Error(capacitorM('capacitor_pushRegisterFailed'))\n let resolveToken!: (value: string) => void\n let rejectToken!: (reason: Error) => void\n const tokenResult = new Promise<string>((resolve, reject) => {\n resolveToken = resolve\n rejectToken = reject\n })\n // 在触发 register 之前就订阅结果,避免同步插件回调丢失或未处理拒绝。\n const setup = async () => {\n await scope.attach(() => push.addListener('registration', (result) => {\n if (!scope.signal.aborted)\n resolveToken(result.value)\n }))\n await scope.attach(() => push.addListener('registrationError', () => {\n if (!scope.signal.aborted)\n rejectToken(new Error(capacitorM('capacitor_pushRegisterFailed')))\n }))\n scope.assertOpen()\n await push.register()\n }\n return (await Promise.all([\n setup(),\n tokenResult,\n ]))[1]\n })\n await scope.dispose()\n return ok({ token })\n }\n catch (cause) {\n await scope.dispose().catch(() => logger.warn('Push registration cleanup failed; retry capacitor.close'))\n return err(HaiCapacitorError.PUSH_REGISTER_FAILED, capacitorM('capacitor_pushRegisterFailed'), cause)\n }\n}\n\n/**\n * 监听原生推送事件;设置阶段限时 30 秒,之后由 cleanup、信号或模块关闭结束。\n * @param callbacks - 收到消息与点击消息的回调。\n * @param options - 可选取消信号,监听建立后仍有效。\n * @returns 幂等清理函数;清理失败可见且可重试,关闭后立即停止业务回调。\n * @example\n * ```ts\n * import { capacitor } from '@h-ai/capacitor'\n *\n * const initialized = await capacitor.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const listening = await capacitor.push.listen({ onReceived: notice => { document.title = notice.title ?? 'Notice' } })\n * if (!listening.success) throw new Error(listening.error.message)\n * const closed = await listening.data()\n * if (!closed.success) throw new Error(closed.error.message)\n * } finally {\n * const closed = await capacitor.close()\n * if (!closed.success) throw new Error(closed.error.message)\n * }\n * ```\n */\nexport async function listenPush(callbacks: PushNotificationCallbacks, options?: PushOptions): Promise<HaiResult<PushCleanup>> {\n const scope = createPushScope(options)\n try {\n await scope.wait(async () => {\n const push = await loadPushPlugin()\n scope.assertOpen()\n if (callbacks.onReceived) {\n await scope.attach(() => push.addListener('pushNotificationReceived', (notification) => {\n if (!scope.signal.aborted) {\n callbacks.onReceived?.({\n id: notification.id,\n title: notification.title,\n body: notification.body,\n data: notification.data as Record<string, unknown>,\n })\n }\n }))\n }\n if (callbacks.onActionPerformed) {\n await scope.attach(() => push.addListener('pushNotificationActionPerformed', (action) => {\n if (!scope.signal.aborted) {\n callbacks.onActionPerformed?.({\n id: action.notification.id,\n title: action.notification.title,\n body: action.notification.body,\n data: action.notification.data as Record<string, unknown>,\n })\n }\n }))\n }\n })\n scope.assertOpen()\n scope.finishSetup()\n return ok(async () => {\n try {\n await scope.dispose()\n return ok(undefined)\n }\n catch (cause) {\n return err(HaiCapacitorError.PUSH_CLEANUP_FAILED, capacitorM('capacitor_pushCleanupFailed'), cause)\n }\n })\n }\n catch (cause) {\n await scope.dispose().catch(() => logger.warn('Push setup cleanup failed; retry capacitor.close'))\n return err(HaiCapacitorError.PUSH_LISTEN_FAILED, capacitorM('capacitor_pushListenFailed'), cause)\n }\n}\n","/**\n * @h-ai/capacitor — 状态栏\n *\n * 封装 `@capacitor/status-bar` 插件,支持沉浸式状态栏配置。\n *\n * @module capacitor-status-bar\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { StatusBarConfig } from './capacitor-types.js'\nimport { err, ok } from '@h-ai/core'\nimport { capacitorM } from './capacitor-i18n.js'\nimport { HaiCapacitorError } from './capacitor-types.js'\n\n/**\n * 配置状态栏\n *\n * 需要安装 `@capacitor/status-bar` 插件。\n *\n * @param config - 状态栏配置\n * @returns HaiResult\n * @example\n * ```ts\n * import { capacitor } from '@h-ai/capacitor'\n *\n * const initialized = await capacitor.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const result = await capacitor.statusBar.configure({ style: 'dark', overlay: false })\n * if (!result.success) throw new Error(result.error.message)\n * void result.data\n * } finally {\n * const closed = await capacitor.close()\n * if (!closed.success) throw new Error(closed.error.message)\n * }\n * ```\n */\nexport async function configureStatusBar(config: StatusBarConfig): Promise<HaiResult<void>> {\n try {\n const { StatusBar, Style } = await import('@capacitor/status-bar')\n\n // 设置样式\n if (config.style) {\n const styleMap: Record<string, typeof Style[keyof typeof Style]> = {\n dark: Style.Dark,\n light: Style.Light,\n default: Style.Default,\n }\n await StatusBar.setStyle({ style: styleMap[config.style] ?? Style.Default })\n }\n\n // 设置背景色\n if (config.backgroundColor) {\n await StatusBar.setBackgroundColor({ color: config.backgroundColor })\n }\n\n // 设置覆盖模式\n if (config.overlay !== undefined) {\n await StatusBar.setOverlaysWebView({ overlay: config.overlay })\n }\n\n return ok(undefined)\n }\n catch (cause) {\n return err(\n HaiCapacitorError.STATUS_BAR_FAILED,\n capacitorM('capacitor_statusBarFailed'),\n cause,\n )\n }\n}\n\n/**\n * 显示状态栏\n *\n * @returns HaiResult\n * @example\n * ```ts\n * import { capacitor } from '@h-ai/capacitor'\n *\n * const initialized = await capacitor.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const result = await capacitor.statusBar.show()\n * if (!result.success) throw new Error(result.error.message)\n * void result.data\n * } finally {\n * const closed = await capacitor.close()\n * if (!closed.success) throw new Error(closed.error.message)\n * }\n * ```\n */\nexport async function showStatusBar(): Promise<HaiResult<void>> {\n try {\n const { StatusBar } = await import('@capacitor/status-bar')\n await StatusBar.show()\n return ok(undefined)\n }\n catch (cause) {\n return err(\n HaiCapacitorError.STATUS_BAR_FAILED,\n capacitorM('capacitor_statusBarFailed'),\n cause,\n )\n }\n}\n\n/**\n * 隐藏状态栏\n *\n * @returns HaiResult\n * @example\n * ```ts\n * import { capacitor } from '@h-ai/capacitor'\n *\n * const initialized = await capacitor.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const result = await capacitor.statusBar.hide()\n * if (!result.success) throw new Error(result.error.message)\n * void result.data\n * } finally {\n * const closed = await capacitor.close()\n * if (!closed.success) throw new Error(closed.error.message)\n * }\n * ```\n */\nexport async function hideStatusBar(): Promise<HaiResult<void>> {\n try {\n const { StatusBar } = await import('@capacitor/status-bar')\n await StatusBar.hide()\n return ok(undefined)\n }\n catch (cause) {\n return err(\n HaiCapacitorError.STATUS_BAR_FAILED,\n capacitorM('capacitor_statusBarFailed'),\n cause,\n )\n }\n}\n","/**\n * @h-ai/capacitor — Token 存储\n *\n * 基于原生安全存储插件的 TokenStorage 实现。\n * 仅在 Capacitor 原生环境启用,拒绝回退到不安全的 Web 存储。\n *\n * @module capacitor-token-storage\n */\n\nimport type { SecureStoragePlugin } from '@aparajita/capacitor-secure-storage'\nimport type { TokenStorage } from '@h-ai/api-client'\nimport type { HaiResult } from '@h-ai/core'\nimport { Preferences } from '@capacitor/preferences'\nimport { err, ok } from '@h-ai/core'\nimport { capacitorM } from './capacitor-i18n.js'\nimport { HaiCapacitorError } from './capacitor-types.js'\n\n/** 原生安全存储 Key;普通 Preferences 不存放认证凭据。 */\nconst PREF_ACCESS_TOKEN = 'hai_access_token'\nconst PREF_REFRESH_TOKEN = 'hai_refresh_token'\n\n// 所有适配器使用相同原生键;串行完成写入/删除,防止旧写在 clear 返回后恢复持久凭据。\nlet credentialMutationTail: Promise<void> = Promise.resolve()\n\nfunction mutateCredentials(operation: () => Promise<void>): Promise<void> {\n const pending = credentialMutationTail.then(operation)\n credentialMutationTail = pending.catch(() => {})\n return pending\n}\n\n/** 动态 import 自带模块缓存;不永久缓存平台检查失败或缺失插件的结果。 */\nasync function loadSecureStoragePlugin(): Promise<SecureStoragePlugin> {\n const { Capacitor } = await import('@capacitor/core')\n if (!Capacitor.isNativePlatform())\n throw new Error(capacitorM('capacitor_notAvailable'))\n const { SecureStorage } = await import('@aparajita/capacitor-secure-storage')\n return SecureStorage\n}\n\n/**\n * 创建基于原生安全存储的 TokenStorage\n *\n * 在原生 Android/iOS 环境下使用 `@aparajita/capacitor-secure-storage`\n * 保存 access token / refresh token。所有方法的存储/平台错误均通过 Promise 拒绝传播,\n * Web 调用明确失败,不做存储回退或伪成功。\n * `clear()` 一开始即屏蔽本实例旧凭据,删除失败时仍保持屏蔽;相应 key 成功写入后恢复读取。\n * 任一凭据写入失败也会屏蔽整对凭据,避免 access 已保存、refresh 失败时暴露半完成登录。\n * 本实例屏蔽不代表原生持久数据已删除;跨重启撤销仍依赖服务端退出/撤销会话。\n * 同模块内全部适配器的原生变更按调用顺序完成;clear 等待更早写入,之后的显式写入可建立新凭据。\n *\n * @returns TokenStorage 实例\n * @throws 返回适配器的方法在插件不可用或原生存储失败时拒绝 Promise。\n * @example\n * ```ts\n * import { createCapacitorTokenStorage } from '@h-ai/capacitor'\n *\n * const storage = createCapacitorTokenStorage()\n * try {\n * const token = await storage.getAccessToken()\n * void token // 仅原生安全存储;平台或存储失败会拒绝 Promise。\n * } catch (cause) {\n * // 应阻止认证流程继续并呈现本地化错误;不回退到普通 Preferences。\n * void cause\n * }\n * ```\n */\nexport function createCapacitorTokenStorage(): TokenStorage {\n let credentialGeneration = 0\n let accessBlocked = false\n let refreshBlocked = false\n\n /** 使本代际的读取/写入资格失效;实例内屏蔽不声称原生数据已经删除。 */\n function blockCredentials(): void {\n credentialGeneration++\n accessBlocked = true\n refreshBlocked = true\n }\n\n /** 部分写入失败时撤销整对本地凭据,交由认证调用方显式重试持久清理。 */\n async function writeToken(key: typeof PREF_ACCESS_TOKEN | typeof PREF_REFRESH_TOKEN, token: string): Promise<void> {\n const writeGeneration = credentialGeneration\n await mutateCredentials(async () => {\n try {\n const storage = await loadSecureStoragePlugin()\n await storage.setItem(key, token)\n if (writeGeneration === credentialGeneration) {\n if (key === PREF_ACCESS_TOKEN)\n accessBlocked = false\n else\n refreshBlocked = false\n }\n }\n catch (error) {\n if (writeGeneration === credentialGeneration)\n blockCredentials()\n throw error\n }\n })\n }\n\n return {\n async getAccessToken(): Promise<string | null> {\n const readGeneration = credentialGeneration\n await credentialMutationTail\n const storage = await loadSecureStoragePlugin()\n if (accessBlocked)\n return null\n const token = await storage.getItem(PREF_ACCESS_TOKEN)\n return accessBlocked || readGeneration !== credentialGeneration\n ? null\n : token\n },\n\n async getRefreshToken(): Promise<string | null> {\n const readGeneration = credentialGeneration\n await credentialMutationTail\n const storage = await loadSecureStoragePlugin()\n if (refreshBlocked)\n return null\n const token = await storage.getItem(PREF_REFRESH_TOKEN)\n return refreshBlocked || readGeneration !== credentialGeneration\n ? null\n : token\n },\n\n async setAccessToken(token: string): Promise<void> {\n await writeToken(PREF_ACCESS_TOKEN, token)\n },\n\n async setRefreshToken(token: string): Promise<void> {\n await writeToken(PREF_REFRESH_TOKEN, token)\n },\n\n async clear(): Promise<void> {\n blockCredentials()\n await mutateCredentials(async () => {\n const storage = await loadSecureStoragePlugin()\n // 两个删除全部完成才释放变更队列,失败也不能留下迟到的删除影响后续登录。\n const results = await Promise.allSettled([\n storage.removeItem(PREF_ACCESS_TOKEN),\n storage.removeItem(PREF_REFRESH_TOKEN),\n ])\n const errors = results.filter(result => result.status === 'rejected').map(result => result.reason)\n if (errors.length > 0)\n throw new AggregateError(errors, capacitorM('capacitor_secureStorageClearFailed'))\n })\n },\n }\n}\n\n/**\n * 安全读取 Preference 值(返回 HaiResult)\n *\n * @param key - Preference Key\n * @returns HaiResult 包裹的值\n * @example\n * ```ts\n * import { capacitor } from '@h-ai/capacitor'\n *\n * const initialized = await capacitor.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const result = await capacitor.preferences.get('theme')\n * if (!result.success) throw new Error(result.error.message)\n * void result.data\n * } finally {\n * const closed = await capacitor.close()\n * if (!closed.success) throw new Error(closed.error.message)\n * }\n * ```\n */\nexport async function safeGetPreference(key: string): Promise<HaiResult<string | null>> {\n try {\n const { value } = await Preferences.get({ key })\n return ok(value)\n }\n catch (cause) {\n return err(\n HaiCapacitorError.PREFERENCES_GET_FAILED,\n capacitorM('capacitor_preferencesGetFailed'),\n cause,\n )\n }\n}\n\n/**\n * 安全写入 Preference 值\n *\n * @param key - Preference Key\n * @param value - 要写入的值\n * @returns HaiResult\n * @example\n * ```ts\n * import { capacitor } from '@h-ai/capacitor'\n *\n * const initialized = await capacitor.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const result = await capacitor.preferences.set('theme', 'dark')\n * if (!result.success) throw new Error(result.error.message)\n * void result.data\n * } finally {\n * const closed = await capacitor.close()\n * if (!closed.success) throw new Error(closed.error.message)\n * }\n * ```\n */\nexport async function safeSetPreference(key: string, value: string): Promise<HaiResult<void>> {\n try {\n await Preferences.set({ key, value })\n return ok(undefined)\n }\n catch (cause) {\n return err(\n HaiCapacitorError.PREFERENCES_SET_FAILED,\n capacitorM('capacitor_preferencesSetFailed'),\n cause,\n )\n }\n}\n\n/**\n * 安全删除 Preference 值\n *\n * @param key - Preference Key\n * @returns HaiResult\n * @example\n * ```ts\n * import { capacitor } from '@h-ai/capacitor'\n *\n * const initialized = await capacitor.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const result = await capacitor.preferences.remove('theme')\n * if (!result.success) throw new Error(result.error.message)\n * void result.data\n * } finally {\n * const closed = await capacitor.close()\n * if (!closed.success) throw new Error(closed.error.message)\n * }\n * ```\n */\nexport async function safeRemovePreference(key: string): Promise<HaiResult<void>> {\n try {\n await Preferences.remove({ key })\n return ok(undefined)\n }\n catch (cause) {\n return err(\n HaiCapacitorError.PREFERENCES_REMOVE_FAILED,\n capacitorM('capacitor_preferencesRemoveFailed'),\n cause,\n )\n }\n}\n","/**\n * @h-ai/capacitor — 模块入口(生命周期管理)\n *\n * 提供 Capacitor 原生桥接的初始化与环境检测。\n * `capacitor.init()` 应在应用启动时调用,用于检测 Capacitor 环境可用性。\n *\n * @module capacitor-main\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { CameraOperations, CapacitorFunctions, DeviceOperations, PreferencesOperations, PushOperations, StatusBarOperations } from './capacitor-types.js'\nimport { core, err, ok } from '@h-ai/core'\nimport { takePhoto } from './capacitor-camera.js'\nimport { getAppVersion, getDeviceInfo } from './capacitor-device.js'\nimport { capacitorM } from './capacitor-i18n.js'\nimport { closePushListeners, listenPush, registerPush } from './capacitor-push.js'\nimport { configureStatusBar, hideStatusBar, showStatusBar } from './capacitor-status-bar.js'\nimport { safeGetPreference, safeRemovePreference, safeSetPreference } from './capacitor-token-storage.js'\nimport { HaiCapacitorError } from './capacitor-types.js'\n\nconst logger = core.logger.child({ module: 'capacitor', scope: 'main' })\n\n/** 是否已初始化 */\nlet initialized = false\n\n/** 是否正在初始化中(并发防护) */\nlet initInProgress = false\n\n/** 缓存平台信息 */\nlet cachedPlatform: string | null = null\n\n// ─── 未初始化代理 ───\n\nconst notInitialized = core.module.createNotInitializedKit(\n HaiCapacitorError.NOT_INITIALIZED,\n () => capacitorM('capacitor_notInitialized'),\n)\n\nconst notInitializedDevice = notInitialized.proxy<DeviceOperations>()\nconst notInitializedCamera = notInitialized.proxy<CameraOperations>()\nconst notInitializedPush = notInitialized.proxy<PushOperations>()\nconst notInitializedStatusBar = notInitialized.proxy<StatusBarOperations>()\nconst notInitializedPreferences = notInitialized.proxy<PreferencesOperations>()\n\n// ─── 已初始化时的操作实现 ───\n\nconst deviceOps: DeviceOperations = {\n getInfo: getDeviceInfo,\n getAppVersion,\n}\n\nconst cameraOps: CameraOperations = {\n takePhoto,\n}\n\nconst pushOps: PushOperations = {\n register: registerPush,\n listen: listenPush,\n}\n\nconst statusBarOps: StatusBarOperations = {\n configure: configureStatusBar,\n show: showStatusBar,\n hide: hideStatusBar,\n}\n\nconst preferencesOps: PreferencesOperations = {\n get: safeGetPreference,\n set: safeSetPreference,\n remove: safeRemovePreference,\n}\n\n// ─── 检测 Capacitor 是否可用(模块内部使用) ───\n\nfunction isCapacitorAvailable(): boolean {\n try {\n // window 上由 Capacitor 运行时注入 Capacitor 全局对象,lib.dom 未声明该属性,故强转为可查库的 Record\n return typeof window !== 'undefined'\n && (window as unknown as Record<string, unknown>).Capacitor !== undefined\n }\n catch {\n return false\n }\n}\n\n// ─── 服务对象 ───\n\n/**\n * Capacitor 模块服务对象\n * @example\n * ```ts\n * import { capacitor } from '@h-ai/capacitor'\n *\n * const initialized = await capacitor.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const result = await capacitor.device.getInfo()\n * if (!result.success) throw new Error(result.error.message)\n * void result.data\n * } finally {\n * const closed = await capacitor.close()\n * if (!closed.success) throw new Error(closed.error.message)\n * }\n * ```\n */\nexport const capacitor: CapacitorFunctions = {\n async init(): Promise<HaiResult<void>> {\n // 并发初始化防护:避免多次 init 同时执行导致资源泄漏\n if (initInProgress) {\n logger.warn('Capacitor init already in progress, skipping concurrent call')\n return err(\n HaiCapacitorError.INIT_IN_PROGRESS,\n capacitorM('capacitor_initInProgress'),\n )\n }\n initInProgress = true\n\n try {\n if (initialized) {\n logger.warn('Capacitor module is already initialized, reinitializing')\n const closed = await capacitor.close()\n if (!closed.success)\n return closed\n }\n // 先重试上次关闭未释放的句柄,不把资源清理失败隐藏成新的初始化成功。\n const cleaned = await closePushListeners()\n if (!cleaned.success)\n return cleaned\n\n logger.info('Initializing capacitor module')\n\n if (!isCapacitorAvailable()) {\n logger.error('Capacitor is not available in current environment')\n return err(\n HaiCapacitorError.NOT_AVAILABLE,\n capacitorM('capacitor_notAvailable'),\n )\n }\n\n const { Capacitor } = await import('@capacitor/core')\n const platform = Capacitor.getPlatform()\n\n if (!platform) {\n logger.error('Capacitor initialization failed, platform not detected')\n return err(\n HaiCapacitorError.INIT_FAILED,\n capacitorM('capacitor_initFailed'),\n )\n }\n\n cachedPlatform = platform\n initialized = true\n logger.info('Capacitor module initialized', { platform })\n return ok(undefined)\n }\n catch (cause) {\n logger.error('Capacitor module initialization failed', { error: cause })\n return err(\n HaiCapacitorError.INIT_FAILED,\n capacitorM('capacitor_initFailed'),\n cause,\n )\n }\n finally {\n initInProgress = false\n }\n },\n\n async close() {\n logger.info('Closing capacitor module')\n initialized = false\n cachedPlatform = null\n const cleaned = await closePushListeners()\n if (!cleaned.success)\n return cleaned\n logger.info('Capacitor module closed')\n return ok(undefined)\n },\n\n getPlatform(): string {\n if (cachedPlatform) {\n return cachedPlatform\n }\n try {\n // 同 isCapacitorAvailable:Capacitor 全局仅在运行时由 native bridge 注入,需强转后读取\n const cap = (window as unknown as Record<string, unknown>).Capacitor as { getPlatform?: () => string } | undefined\n return cap?.getPlatform?.() ?? 'web'\n }\n catch {\n return 'web'\n }\n },\n\n isNative(): boolean {\n try {\n const cap = (window as unknown as Record<string, unknown>).Capacitor as { isNativePlatform?: () => boolean } | undefined\n return cap?.isNativePlatform?.() ?? false\n }\n catch {\n return false\n }\n },\n\n get isInitialized(): boolean {\n return initialized\n },\n\n get device(): DeviceOperations {\n return initialized ? deviceOps : notInitializedDevice\n },\n\n get camera(): CameraOperations {\n return initialized ? cameraOps : notInitializedCamera\n },\n\n get push(): PushOperations {\n return initialized ? pushOps : notInitializedPush\n },\n\n get statusBar(): StatusBarOperations {\n return initialized ? statusBarOps : notInitializedStatusBar\n },\n\n get preferences(): PreferencesOperations {\n return initialized ? preferencesOps : notInitializedPreferences\n },\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@h-ai/capacitor",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.0-beta.
|
|
4
|
+
"version": "1.0.0-beta.19",
|
|
5
5
|
"description": "Hai Framework Capacitor bridge module for native mobile capabilities.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"exports": {
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
26
|
"@aparajita/capacitor-secure-storage": "^8.0.1",
|
|
27
|
-
"@capacitor/core": "^8.
|
|
27
|
+
"@capacitor/core": "^8.6.0",
|
|
28
28
|
"@capacitor/preferences": "^8.0.1"
|
|
29
29
|
},
|
|
30
30
|
"peerDependenciesMeta": {
|
|
@@ -48,21 +48,21 @@
|
|
|
48
48
|
}
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@h-ai/api-client": "1.0.0-beta.
|
|
52
|
-
"@h-ai/core": "1.0.0-beta.
|
|
51
|
+
"@h-ai/api-client": "1.0.0-beta.19",
|
|
52
|
+
"@h-ai/core": "1.0.0-beta.19"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@aparajita/capacitor-secure-storage": "^8.0.1",
|
|
56
56
|
"@capacitor/app": "^8.1.2",
|
|
57
|
-
"@capacitor/camera": "^8.2.
|
|
57
|
+
"@capacitor/camera": "^8.2.6",
|
|
58
58
|
"@capacitor/device": "^8.0.3",
|
|
59
59
|
"@capacitor/push-notifications": "^8.1.3",
|
|
60
60
|
"@capacitor/status-bar": "^8.0.4",
|
|
61
|
-
"@types/node": "^26.6.
|
|
62
|
-
"rimraf": "^6.1.
|
|
63
|
-
"tsup": "^
|
|
61
|
+
"@types/node": "^26.6.6",
|
|
62
|
+
"rimraf": "^6.1.4",
|
|
63
|
+
"tsup": "^9.0.0",
|
|
64
64
|
"typescript": "^6.0.3",
|
|
65
|
-
"vitest": "^
|
|
65
|
+
"vitest": "^5.1.0"
|
|
66
66
|
},
|
|
67
67
|
"scripts": {
|
|
68
68
|
"build": "tsup",
|