@elizaos/capacitor-appblocker 1.0.0 → 2.0.11-beta.7

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Shaw Walters and elizaOS Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,87 @@
1
+ # @elizaos/capacitor-appblocker
2
+
3
+ A Capacitor plugin that blocks selected apps on **Android** (Usage Access + system overlay) and **iOS** (Family Controls + ManagedSettings). Not available in browsers.
4
+
5
+ ## What it does
6
+
7
+ The plugin lets a Capacitor-based Eliza agent app:
8
+
9
+ - Check and request the OS permissions required for blocking.
10
+ - Present the user with a system-level app picker to choose which apps to block.
11
+ - Apply or lift an app block, optionally with a time limit (Android) or indefinitely (iOS).
12
+ - Query the current blocking status and engine details.
13
+
14
+ ### Platform engines
15
+
16
+ | Platform | Engine | Notes |
17
+ |---|---|---|
18
+ | Android | Usage Access + system overlay | A foreground service polls foreground events every 500 ms and shows a full-screen shield when a blocked app is detected. |
19
+ | iOS | Family Controls + ManagedSettings | `ManagedSettingsStore` shields selected apps. Timed blocks require a DeviceActivity extension; this package currently supports indefinite iOS blocks only. |
20
+ | Browser | None | Permission checks return `status: "not-applicable"`, `getStatus` returns `status: "unavailable"`, mutations return `success: false`, list methods return empty arrays. |
21
+
22
+ ## API
23
+
24
+ ```ts
25
+ import { AppBlocker } from "@elizaos/capacitor-appblocker";
26
+
27
+ // Check whether OS permissions are already granted
28
+ const perm = await AppBlocker.checkPermissions();
29
+
30
+ // Request missing permissions (opens system settings or triggers Family Controls auth)
31
+ await AppBlocker.requestPermissions();
32
+
33
+ // Android: get a list of installed launcher apps
34
+ const { apps } = await AppBlocker.getInstalledApps();
35
+
36
+ // iOS: opens FamilyActivityPicker and returns selected apps with tokenData.
37
+ // Android: returns immediately with { apps: [], cancelled: true } — use getInstalledApps() instead.
38
+ const { apps: selected, cancelled } = await AppBlocker.selectApps();
39
+
40
+ // Block apps — pass packageNames (Android) or appTokens (iOS)
41
+ const result = await AppBlocker.blockApps({
42
+ packageNames: ["com.instagram.android"],
43
+ durationMinutes: 60, // omit for indefinite; not supported on iOS
44
+ });
45
+
46
+ // Remove all active blocks
47
+ await AppBlocker.unblockApps();
48
+
49
+ // Get current blocking state
50
+ const status = await AppBlocker.getStatus();
51
+ ```
52
+
53
+ Full TypeScript types are exported from the package root: `AppBlockerPlugin`, `AppBlockerStatus`, `AppBlockerPermissionResult`, `BlockAppsOptions`, `InstalledApp`, `SelectAppsResult`, `UnblockAppsResult`, `AppBlockerCapabilities`.
54
+
55
+ ## Required permissions
56
+
57
+ ### Android
58
+
59
+ The consuming app's `AndroidManifest.xml` inherits these declarations from the plugin:
60
+
61
+ - `PACKAGE_USAGE_STATS` — Usage Access (user must grant via Settings).
62
+ - `SYSTEM_ALERT_WINDOW` — Draw Over Other Apps (user must grant via Settings).
63
+ - `FOREGROUND_SERVICE` + `FOREGROUND_SERVICE_SPECIAL_USE` — required for the monitoring service.
64
+ - `POST_NOTIFICATIONS` — for the persistent "App Blocker Active" notification.
65
+
66
+ Use `checkPermissions()` / `requestPermissions()` to guide the user through granting both.
67
+
68
+ ### iOS
69
+
70
+ The app must have the `com.apple.developer.family-controls` entitlement in its provisioning profile. Call `requestPermissions()` to trigger the system authorization sheet. Requires iOS 15.0+.
71
+
72
+ ## Installation
73
+
74
+ ```bash
75
+ npm install @elizaos/capacitor-appblocker
76
+ npx cap sync
77
+ ```
78
+
79
+ For iOS, add the pod to your `Podfile` (Capacitor's sync does this automatically) and ensure your Xcode target has the Family Controls entitlement enabled.
80
+
81
+ ## Building from source
82
+
83
+ ```bash
84
+ bun run --cwd plugins/plugin-native-appblocker build
85
+ ```
86
+
87
+ Produces `dist/esm/` (ESM), `dist/plugin.js` (IIFE/CDN), and `dist/plugin.cjs.js` (CJS).
@@ -7,6 +7,11 @@ ext {
7
7
  }
8
8
 
9
9
  apply plugin: 'com.android.library'
10
+ // Apply the Kotlin Android plugin so the plugin's .kt class is bundled into the
11
+ // library AAR. Without it AGP's built-in kotlinc compiles the sources but does
12
+ // NOT bundle the .class files, so the Capacitor plugin class is absent from the
13
+ // app dex at runtime (PluginLoadException -> the whole plugin set fails to load).
14
+ apply plugin: 'org.jetbrains.kotlin.android'
10
15
  android {
11
16
  namespace = "ai.eliza.plugins.appblocker"
12
17
  compileSdk project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 34
@@ -28,13 +33,16 @@ android {
28
33
  sourceCompatibility JavaVersion.VERSION_17
29
34
  targetCompatibility JavaVersion.VERSION_17
30
35
  }
36
+ kotlinOptions {
37
+ jvmTarget = "17"
38
+ }
31
39
 
32
40
  }
33
41
 
34
42
  repositories {
35
43
  google()
36
44
  maven {
37
- url = uri(rootProject.ext.mavenCentralMirrorUrl)
45
+ url = uri(rootProject.ext.has('mavenCentralMirrorUrl') ? rootProject.ext.mavenCentralMirrorUrl : 'https://repo.maven.apache.org/maven2')
38
46
  }
39
47
  mavenCentral()
40
48
  }
@@ -178,14 +178,19 @@ class AppBlockerPlugin : Plugin() {
178
178
 
179
179
  call.resolve(
180
180
  JSObject().apply {
181
+ put("status", if (saved != null) "active" else "inactive")
181
182
  put("available", true)
182
183
  put("active", saved != null)
183
184
  put("platform", "android")
184
185
  put("engine", "usage-stats-overlay")
186
+ put("capabilities", appBlockerCapabilities())
185
187
  put("blockedCount", saved?.packageNames?.size ?: 0)
186
188
  put("blockedPackageNames", JSArray(saved?.packageNames ?: emptyList<String>()))
187
189
  put("endsAt", saved?.endsAtEpochMs?.let { Instant.ofEpochMilli(it).toString() })
188
190
  put("permissionStatus", permission.getString("status"))
191
+ put("canRequest", permission.getBool("canRequest"))
192
+ put("canOpenSettings", permission.getBool("canOpenSettings"))
193
+ put("settingsTarget", permission.opt("settingsTarget"))
189
194
  if (!reason.isNullOrBlank()) {
190
195
  put("reason", reason)
191
196
  }
@@ -209,10 +214,35 @@ class AppBlockerPlugin : Plugin() {
209
214
  return JSObject().apply {
210
215
  put("status", if (usageAccess && overlayAccess) "granted" else "not-determined")
211
216
  put("canRequest", !usageAccess || !overlayAccess)
217
+ put("canOpenSettings", !usageAccess || !overlayAccess)
218
+ put("settingsTarget", settingsTarget(usageAccess, overlayAccess))
219
+ put("engine", "usage-stats-overlay")
220
+ put("capabilities", appBlockerCapabilities())
212
221
  missingPermissionReason()?.let { put("reason", it) }
213
222
  }
214
223
  }
215
224
 
225
+ private fun appBlockerCapabilities(): JSObject {
226
+ return JSObject().apply {
227
+ put("canSelectApps", true)
228
+ put("canBlockApps", true)
229
+ put("canScheduleTimedBlocks", true)
230
+ put("canUnblockEarly", true)
231
+ put("requiresFamilyControls", false)
232
+ put("requiresUsageAccess", true)
233
+ put("requiresOverlay", true)
234
+ }
235
+ }
236
+
237
+ private fun settingsTarget(usageAccess: Boolean, overlayAccess: Boolean): String? {
238
+ return when {
239
+ !usageAccess && !overlayAccess -> "deviceSettings"
240
+ !usageAccess -> "usageAccess"
241
+ !overlayAccess -> "overlay"
242
+ else -> null
243
+ }
244
+ }
245
+
216
246
  private fun missingPermissionReason(): String? {
217
247
  val missingUsageAccess = !hasUsageAccess()
218
248
  val missingOverlayAccess = !canDrawOverlays()
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Adapter that exposes the Capacitor `ElizaAppBlocker` plugin as the
3
+ * `NativeAppBlockerBackend` the `@elizaos/plugin-blocker` app-blocker engine
4
+ * dispatches to. Registering the result with `registerNativeAppBlockerBackend`
5
+ * makes the engine drive the real native enforcement (Family Controls on iOS,
6
+ * Usage-Stats + overlay on Android).
7
+ *
8
+ * Process boundary: this adapter only reaches the native plugin when it runs in
9
+ * the same JS realm as Capacitor (the WebView / web build).
10
+ */
11
+ import type { AppBlockerPlugin, BlockAppsOptions, BlockAppsResult, InstalledApp, SelectAppsResult, UnblockAppsResult } from "./definitions";
12
+ interface BackendAppBlockerStatus {
13
+ available: boolean;
14
+ active: boolean;
15
+ platform: string;
16
+ engine: "family-controls" | "usage-stats-overlay" | "none";
17
+ blockedCount: number;
18
+ blockedPackageNames: string[];
19
+ endsAt: string | null;
20
+ permissionStatus: "granted" | "denied" | "not-determined" | "not-applicable";
21
+ reason?: string;
22
+ }
23
+ interface BackendAppBlockerPermissionResult {
24
+ status: "granted" | "denied" | "not-determined" | "not-applicable";
25
+ canRequest: boolean;
26
+ reason?: string;
27
+ }
28
+ export interface NativeAppBlockerBackend {
29
+ [key: string]: unknown;
30
+ checkPermissions(): Promise<BackendAppBlockerPermissionResult>;
31
+ requestPermissions(): Promise<BackendAppBlockerPermissionResult>;
32
+ getInstalledApps(): Promise<{
33
+ apps: InstalledApp[];
34
+ }>;
35
+ selectApps(): Promise<SelectAppsResult>;
36
+ blockApps(options: BlockAppsOptions): Promise<BlockAppsResult>;
37
+ unblockApps(): Promise<UnblockAppsResult>;
38
+ getStatus(): Promise<BackendAppBlockerStatus>;
39
+ }
40
+ /**
41
+ * Wrap an `AppBlockerPlugin` (pass the registered `AppBlocker` Capacitor
42
+ * plugin) as a `NativeAppBlockerBackend`.
43
+ */
44
+ export declare function createNativeAppBlockerBackend(plugin: AppBlockerPlugin): NativeAppBlockerBackend;
45
+ export {};
46
+ //# sourceMappingURL=backend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../src/backend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAEV,gBAAgB,EAEhB,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EAClB,MAAM,eAAe,CAAC;AAKvB,UAAU,uBAAuB;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,iBAAiB,GAAG,qBAAqB,GAAG,MAAM,CAAC;IAC3D,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,gBAAgB,EAAE,SAAS,GAAG,QAAQ,GAAG,gBAAgB,GAAG,gBAAgB,CAAC;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,iCAAiC;IACzC,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,gBAAgB,GAAG,gBAAgB,CAAC;IACnE,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAKD,MAAM,WAAW,uBAAuB;IACtC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,gBAAgB,IAAI,OAAO,CAAC,iCAAiC,CAAC,CAAC;IAC/D,kBAAkB,IAAI,OAAO,CAAC,iCAAiC,CAAC,CAAC;IACjE,gBAAgB,IAAI,OAAO,CAAC;QAAE,IAAI,EAAE,YAAY,EAAE,CAAA;KAAE,CAAC,CAAC;IACtD,UAAU,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACxC,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAC/D,WAAW,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC1C,SAAS,IAAI,OAAO,CAAC,uBAAuB,CAAC,CAAC;CAC/C;AA0BD;;;GAGG;AACH,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,gBAAgB,GACvB,uBAAuB,CAwBzB"}
@@ -0,0 +1,50 @@
1
+ function toBackendStatus(status) {
2
+ return {
3
+ available: status.available,
4
+ active: status.active,
5
+ platform: status.platform,
6
+ engine: status.engine,
7
+ blockedCount: status.blockedCount,
8
+ blockedPackageNames: status.blockedPackageNames,
9
+ endsAt: status.endsAt,
10
+ permissionStatus: status.permissionStatus,
11
+ reason: status.reason,
12
+ };
13
+ }
14
+ function toBackendPermission(permission) {
15
+ return {
16
+ status: permission.status,
17
+ canRequest: permission.canRequest,
18
+ reason: permission.reason,
19
+ };
20
+ }
21
+ /**
22
+ * Wrap an `AppBlockerPlugin` (pass the registered `AppBlocker` Capacitor
23
+ * plugin) as a `NativeAppBlockerBackend`.
24
+ */
25
+ export function createNativeAppBlockerBackend(plugin) {
26
+ return {
27
+ async checkPermissions() {
28
+ return toBackendPermission(await plugin.checkPermissions());
29
+ },
30
+ async requestPermissions() {
31
+ return toBackendPermission(await plugin.requestPermissions());
32
+ },
33
+ getInstalledApps() {
34
+ return plugin.getInstalledApps();
35
+ },
36
+ selectApps() {
37
+ return plugin.selectApps();
38
+ },
39
+ blockApps(options) {
40
+ return plugin.blockApps(options);
41
+ },
42
+ unblockApps() {
43
+ return plugin.unblockApps();
44
+ },
45
+ async getStatus() {
46
+ return toBackendStatus(await plugin.getStatus());
47
+ },
48
+ };
49
+ }
50
+ //# sourceMappingURL=backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend.js","sourceRoot":"","sources":["../../src/backend.ts"],"names":[],"mappings":"AAwDA,SAAS,eAAe,CAAC,MAAwB;IAC/C,OAAO;QACL,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,mBAAmB,EAAE,MAAM,CAAC,mBAAmB;QAC/C,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAC;AACJ,CAAC;AAED,SAAS,mBAAmB,CAC1B,UAAsC;IAEtC,OAAO;QACL,MAAM,EAAE,UAAU,CAAC,MAAM;QACzB,UAAU,EAAE,UAAU,CAAC,UAAU;QACjC,MAAM,EAAE,UAAU,CAAC,MAAM;KAC1B,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,6BAA6B,CAC3C,MAAwB;IAExB,OAAO;QACL,KAAK,CAAC,gBAAgB;YACpB,OAAO,mBAAmB,CAAC,MAAM,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC;QAC9D,CAAC;QACD,KAAK,CAAC,kBAAkB;YACtB,OAAO,mBAAmB,CAAC,MAAM,MAAM,CAAC,kBAAkB,EAAE,CAAC,CAAC;QAChE,CAAC;QACD,gBAAgB;YACd,OAAO,MAAM,CAAC,gBAAgB,EAAE,CAAC;QACnC,CAAC;QACD,UAAU;YACR,OAAO,MAAM,CAAC,UAAU,EAAE,CAAC;QAC7B,CAAC;QACD,SAAS,CAAC,OAAO;YACf,OAAO,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACnC,CAAC;QACD,WAAW;YACT,OAAO,MAAM,CAAC,WAAW,EAAE,CAAC;QAC9B,CAAC;QACD,KAAK,CAAC,SAAS;YACb,OAAO,eAAe,CAAC,MAAM,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;QACnD,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=backend.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend.test.d.ts","sourceRoot":"","sources":["../../src/backend.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,112 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { createNativeAppBlockerBackend } from "./backend";
3
+ const CAPABILITIES = {
4
+ canSelectApps: true,
5
+ canBlockApps: true,
6
+ canScheduleTimedBlocks: false,
7
+ canUnblockEarly: true,
8
+ requiresFamilyControls: true,
9
+ requiresUsageAccess: false,
10
+ requiresOverlay: false,
11
+ };
12
+ function makeStatus(overrides = {}) {
13
+ return {
14
+ status: "inactive",
15
+ available: true,
16
+ active: false,
17
+ platform: "ios",
18
+ engine: "family-controls",
19
+ capabilities: CAPABILITIES,
20
+ blockedCount: 0,
21
+ blockedPackageNames: [],
22
+ endsAt: null,
23
+ permissionStatus: "granted",
24
+ canRequest: false,
25
+ canOpenSettings: true,
26
+ settingsTarget: "screenTime",
27
+ ...overrides,
28
+ };
29
+ }
30
+ function makePlugin(overrides = {}) {
31
+ return {
32
+ checkPermissions: vi.fn(async () => ({
33
+ status: "granted",
34
+ canRequest: false,
35
+ canOpenSettings: true,
36
+ settingsTarget: "screenTime",
37
+ engine: "family-controls",
38
+ capabilities: CAPABILITIES,
39
+ })),
40
+ requestPermissions: vi.fn(async () => ({
41
+ status: "granted",
42
+ canRequest: false,
43
+ canOpenSettings: true,
44
+ settingsTarget: "screenTime",
45
+ engine: "family-controls",
46
+ capabilities: CAPABILITIES,
47
+ })),
48
+ getInstalledApps: vi.fn(async () => ({ apps: [] })),
49
+ selectApps: vi.fn(async () => ({ apps: [], cancelled: false })),
50
+ blockApps: vi.fn(async () => ({
51
+ success: true,
52
+ endsAt: null,
53
+ blockedCount: 2,
54
+ })),
55
+ unblockApps: vi.fn(async () => ({ success: true })),
56
+ getStatus: vi.fn(async () => makeStatus()),
57
+ ...overrides,
58
+ };
59
+ }
60
+ describe("createNativeAppBlockerBackend", () => {
61
+ it("forwards blockApps to the Capacitor plugin", async () => {
62
+ const blockApps = vi.fn(async () => ({
63
+ success: true,
64
+ endsAt: null,
65
+ blockedCount: 3,
66
+ }));
67
+ const backend = createNativeAppBlockerBackend(makePlugin({ blockApps }));
68
+ const result = await backend.blockApps({ packageNames: ["a", "b", "c"] });
69
+ expect(blockApps).toHaveBeenCalledWith({ packageNames: ["a", "b", "c"] });
70
+ expect(result.blockedCount).toBe(3);
71
+ });
72
+ it("maps getStatus into the trimmed engine status shape", async () => {
73
+ const backend = createNativeAppBlockerBackend(makePlugin({
74
+ getStatus: vi.fn(async () => makeStatus({
75
+ active: true,
76
+ blockedCount: 2,
77
+ blockedPackageNames: ["com.x", "com.reddit"],
78
+ engine: "usage-stats-overlay",
79
+ platform: "android",
80
+ })),
81
+ }));
82
+ const status = await backend.getStatus();
83
+ expect(status).toEqual({
84
+ available: true,
85
+ active: true,
86
+ platform: "android",
87
+ engine: "usage-stats-overlay",
88
+ blockedCount: 2,
89
+ blockedPackageNames: ["com.x", "com.reddit"],
90
+ endsAt: null,
91
+ permissionStatus: "granted",
92
+ reason: undefined,
93
+ });
94
+ });
95
+ it("maps permission checks into the trimmed engine permission shape", async () => {
96
+ const backend = createNativeAppBlockerBackend(makePlugin());
97
+ const permission = await backend.checkPermissions();
98
+ expect(permission).toEqual({
99
+ status: "granted",
100
+ canRequest: false,
101
+ reason: undefined,
102
+ });
103
+ });
104
+ it("forwards unblockApps to the Capacitor plugin", async () => {
105
+ const unblockApps = vi.fn(async () => ({ success: true }));
106
+ const backend = createNativeAppBlockerBackend(makePlugin({ unblockApps }));
107
+ const result = await backend.unblockApps();
108
+ expect(unblockApps).toHaveBeenCalledOnce();
109
+ expect(result.success).toBe(true);
110
+ });
111
+ });
112
+ //# sourceMappingURL=backend.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend.test.js","sourceRoot":"","sources":["../../src/backend.test.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,21 @@
1
1
  export type AppBlockerPermissionStatus = "granted" | "denied" | "not-determined" | "not-applicable";
2
+ export type AppBlockerSettingsTarget = "screenTime" | "usageAccess" | "overlay" | "deviceSettings";
3
+ export interface AppBlockerCapabilities {
4
+ canSelectApps: boolean;
5
+ canBlockApps: boolean;
6
+ canScheduleTimedBlocks: boolean;
7
+ canUnblockEarly: boolean;
8
+ requiresFamilyControls: boolean;
9
+ requiresUsageAccess: boolean;
10
+ requiresOverlay: boolean;
11
+ }
2
12
  export interface AppBlockerPermissionResult {
3
13
  status: AppBlockerPermissionStatus;
4
14
  canRequest: boolean;
15
+ canOpenSettings: boolean;
16
+ settingsTarget: AppBlockerSettingsTarget | null;
17
+ engine: AppBlockerStatus["engine"];
18
+ capabilities: AppBlockerCapabilities;
5
19
  reason?: string;
6
20
  }
7
21
  export interface InstalledApp {
@@ -29,14 +43,19 @@ export interface UnblockAppsResult {
29
43
  error?: string;
30
44
  }
31
45
  export interface AppBlockerStatus {
46
+ status: "active" | "inactive" | "unavailable";
32
47
  available: boolean;
33
48
  active: boolean;
34
49
  platform: string;
35
50
  engine: "family-controls" | "usage-stats-overlay" | "none";
51
+ capabilities: AppBlockerCapabilities;
36
52
  blockedCount: number;
37
53
  blockedPackageNames: string[];
38
54
  endsAt: string | null;
39
55
  permissionStatus: AppBlockerPermissionStatus;
56
+ canRequest: boolean;
57
+ canOpenSettings: boolean;
58
+ settingsTarget: AppBlockerSettingsTarget | null;
40
59
  reason?: string;
41
60
  }
42
61
  export interface AppBlockerPlugin {
@@ -1 +1 @@
1
- {"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,0BAA0B,GAClC,SAAS,GACT,QAAQ,GACR,gBAAgB,GAChB,gBAAgB,CAAC;AAErB,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,0BAA0B,CAAC;IACnC,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,YAAY,EAAE,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,iBAAiB,GAAG,qBAAqB,GAAG,MAAM,CAAC;IAC3D,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,gBAAgB,EAAE,0BAA0B,CAAC;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,gBAAgB,IAAI,OAAO,CAAC,0BAA0B,CAAC,CAAC;IACxD,kBAAkB,IAAI,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAC1D,gBAAgB,IAAI,OAAO,CAAC;QAAE,IAAI,EAAE,YAAY,EAAE,CAAA;KAAE,CAAC,CAAC;IACtD,UAAU,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACxC,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAC/D,WAAW,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC1C,SAAS,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAC;CACxC"}
1
+ {"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import type { AppBlockerPlugin } from "./definitions";
2
2
  export * from "./definitions";
3
3
  export declare const AppBlocker: AppBlockerPlugin;
4
+ export { createNativeAppBlockerBackend, type NativeAppBlockerBackend, } from "./backend";
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,cAAc,eAAe,CAAC;AAK9B,eAAO,MAAM,UAAU,kBAErB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,cAAc,eAAe,CAAC;AAK9B,eAAO,MAAM,UAAU,kBAErB,CAAC;AAEH,OAAO,EACL,6BAA6B,EAC7B,KAAK,uBAAuB,GAC7B,MAAM,WAAW,CAAC"}
package/dist/esm/index.js CHANGED
@@ -4,4 +4,5 @@ const loadWeb = () => import("./web").then((module) => new module.AppBlockerWeb(
4
4
  export const AppBlocker = registerPlugin("ElizaAppBlocker", {
5
5
  web: loadWeb,
6
6
  });
7
+ export { createNativeAppBlockerBackend, } from "./backend";
7
8
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIjD,cAAc,eAAe,CAAC;AAE9B,MAAM,OAAO,GAAG,GAAG,EAAE,CACnB,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC;AAE/D,MAAM,CAAC,MAAM,UAAU,GAAG,cAAc,CAAmB,iBAAiB,EAAE;IAC5E,GAAG,EAAE,OAAO;CACb,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIjD,cAAc,eAAe,CAAC;AAE9B,MAAM,OAAO,GAAG,GAAG,EAAE,CACnB,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC;AAE/D,MAAM,CAAC,MAAM,UAAU,GAAG,cAAc,CAAmB,iBAAiB,EAAE;IAC5E,GAAG,EAAE,OAAO;CACb,CAAC,CAAC;AAEH,OAAO,EACL,6BAA6B,GAE9B,MAAM,WAAW,CAAC"}
package/dist/esm/web.d.ts CHANGED
@@ -7,7 +7,7 @@ export declare class AppBlockerWeb extends WebPlugin {
7
7
  apps: [];
8
8
  }>;
9
9
  selectApps(): Promise<SelectAppsResult>;
10
- blockApps(_options: BlockAppsOptions): Promise<BlockAppsResult>;
10
+ blockApps(options: BlockAppsOptions): Promise<BlockAppsResult>;
11
11
  unblockApps(): Promise<UnblockAppsResult>;
12
12
  getStatus(): Promise<AppBlockerStatus>;
13
13
  }
@@ -1 +1 @@
1
- {"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EACV,0BAA0B,EAC1B,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EAClB,MAAM,eAAe,CAAC;AAEvB,qBAAa,aAAc,SAAQ,SAAS;IACpC,gBAAgB,IAAI,OAAO,CAAC,0BAA0B,CAAC;IAQvD,kBAAkB,IAAI,OAAO,CAAC,0BAA0B,CAAC;IAQzD,gBAAgB,IAAI,OAAO,CAAC;QAAE,IAAI,EAAE,EAAE,CAAA;KAAE,CAAC;IAIzC,UAAU,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAIvC,SAAS,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IAS/D,WAAW,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAOzC,SAAS,IAAI,OAAO,CAAC,gBAAgB,CAAC;CAa7C"}
1
+ {"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EACV,0BAA0B,EAC1B,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EAClB,MAAM,eAAe,CAAC;AAuCvB,qBAAa,aAAc,SAAQ,SAAS;IACpC,gBAAgB,IAAI,OAAO,CAAC,0BAA0B,CAAC;IAoBvD,kBAAkB,IAAI,OAAO,CAAC,0BAA0B,CAAC;IAoBzD,gBAAgB,IAAI,OAAO,CAAC;QAAE,IAAI,EAAE,EAAE,CAAA;KAAE,CAAC;IAIzC,UAAU,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAIvC,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IAU9D,WAAW,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAOzC,SAAS,IAAI,OAAO,CAAC,gBAAgB,CAAC;CA0B7C"}
package/dist/esm/web.js CHANGED
@@ -1,9 +1,47 @@
1
1
  import { WebPlugin } from "@capacitor/core";
2
+ const PACKAGE_NAME_RE = /^[A-Za-z][A-Za-z0-9_]*(?:\.[A-Za-z][A-Za-z0-9_]*)+$/;
3
+ function validateBlockAppsOptions(options) {
4
+ const packageNames = Array.isArray(options?.packageNames)
5
+ ? options.packageNames
6
+ : [];
7
+ const appTokens = Array.isArray(options?.appTokens) ? options.appTokens : [];
8
+ for (const packageName of packageNames) {
9
+ if (typeof packageName !== "string" ||
10
+ !PACKAGE_NAME_RE.test(packageName.trim())) {
11
+ throw new Error("packageNames must contain valid Android package names");
12
+ }
13
+ }
14
+ for (const token of appTokens) {
15
+ if (typeof token !== "string" || token.trim().length === 0) {
16
+ throw new Error("appTokens must contain non-empty strings");
17
+ }
18
+ }
19
+ if (options?.durationMinutes !== undefined &&
20
+ options.durationMinutes !== null) {
21
+ if (typeof options.durationMinutes !== "number" ||
22
+ !Number.isFinite(options.durationMinutes) ||
23
+ options.durationMinutes <= 0) {
24
+ throw new Error("durationMinutes must be a positive finite number");
25
+ }
26
+ }
27
+ }
2
28
  export class AppBlockerWeb extends WebPlugin {
3
29
  async checkPermissions() {
4
30
  return {
5
31
  status: "not-applicable",
6
32
  canRequest: false,
33
+ canOpenSettings: false,
34
+ settingsTarget: null,
35
+ engine: "none",
36
+ capabilities: {
37
+ canSelectApps: false,
38
+ canBlockApps: false,
39
+ canScheduleTimedBlocks: false,
40
+ canUnblockEarly: false,
41
+ requiresFamilyControls: false,
42
+ requiresUsageAccess: false,
43
+ requiresOverlay: false,
44
+ },
7
45
  reason: "App blocking is only available on mobile devices.",
8
46
  };
9
47
  }
@@ -11,6 +49,18 @@ export class AppBlockerWeb extends WebPlugin {
11
49
  return {
12
50
  status: "not-applicable",
13
51
  canRequest: false,
52
+ canOpenSettings: false,
53
+ settingsTarget: null,
54
+ engine: "none",
55
+ capabilities: {
56
+ canSelectApps: false,
57
+ canBlockApps: false,
58
+ canScheduleTimedBlocks: false,
59
+ canUnblockEarly: false,
60
+ requiresFamilyControls: false,
61
+ requiresUsageAccess: false,
62
+ requiresOverlay: false,
63
+ },
14
64
  reason: "App blocking is only available on mobile devices.",
15
65
  };
16
66
  }
@@ -20,7 +70,8 @@ export class AppBlockerWeb extends WebPlugin {
20
70
  async selectApps() {
21
71
  return { apps: [], cancelled: true };
22
72
  }
23
- async blockApps(_options) {
73
+ async blockApps(options) {
74
+ validateBlockAppsOptions(options);
24
75
  return {
25
76
  success: false,
26
77
  endsAt: null,
@@ -36,14 +87,27 @@ export class AppBlockerWeb extends WebPlugin {
36
87
  }
37
88
  async getStatus() {
38
89
  return {
90
+ status: "unavailable",
39
91
  available: false,
40
92
  active: false,
41
93
  platform: "web",
42
94
  engine: "none",
95
+ capabilities: {
96
+ canSelectApps: false,
97
+ canBlockApps: false,
98
+ canScheduleTimedBlocks: false,
99
+ canUnblockEarly: false,
100
+ requiresFamilyControls: false,
101
+ requiresUsageAccess: false,
102
+ requiresOverlay: false,
103
+ },
43
104
  blockedCount: 0,
44
105
  blockedPackageNames: [],
45
106
  endsAt: null,
46
107
  permissionStatus: "not-applicable",
108
+ canRequest: false,
109
+ canOpenSettings: false,
110
+ settingsTarget: null,
47
111
  reason: "App blocking is only available on mobile devices.",
48
112
  };
49
113
  }
@@ -1 +1 @@
1
- {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAU5C,MAAM,OAAO,aAAc,SAAQ,SAAS;IAC1C,KAAK,CAAC,gBAAgB;QACpB,OAAO;YACL,MAAM,EAAE,gBAAgB;YACxB,UAAU,EAAE,KAAK;YACjB,MAAM,EAAE,mDAAmD;SAC5D,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,kBAAkB;QACtB,OAAO;YACL,MAAM,EAAE,gBAAgB;YACxB,UAAU,EAAE,KAAK;YACjB,MAAM,EAAE,mDAAmD;SAC5D,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,UAAU;QACd,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,QAA0B;QACxC,OAAO;YACL,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,IAAI;YACZ,KAAK,EAAE,mDAAmD;YAC1D,YAAY,EAAE,CAAC;SAChB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,WAAW;QACf,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,mDAAmD;SAC3D,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,SAAS;QACb,OAAO;YACL,SAAS,EAAE,KAAK;YAChB,MAAM,EAAE,KAAK;YACb,QAAQ,EAAE,KAAK;YACf,MAAM,EAAE,MAAM;YACd,YAAY,EAAE,CAAC;YACf,mBAAmB,EAAE,EAAE;YACvB,MAAM,EAAE,IAAI;YACZ,gBAAgB,EAAE,gBAAgB;YAClC,MAAM,EAAE,mDAAmD;SAC5D,CAAC;IACJ,CAAC;CACF"}
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=web.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.test.d.ts","sourceRoot":"","sources":["../../src/web.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,49 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { AppBlockerWeb } from "./web";
3
+ describe("AppBlockerWeb fallback", () => {
4
+ it("reports app blocking as unavailable on web", async () => {
5
+ const blocker = new AppBlockerWeb();
6
+ await expect(blocker.checkPermissions()).resolves.toMatchObject({
7
+ status: "not-applicable",
8
+ engine: "none",
9
+ canRequest: false,
10
+ });
11
+ await expect(blocker.getStatus()).resolves.toMatchObject({
12
+ status: "unavailable",
13
+ available: false,
14
+ active: false,
15
+ blockedCount: 0,
16
+ });
17
+ await expect(blocker.getInstalledApps()).resolves.toEqual({ apps: [] });
18
+ await expect(blocker.selectApps()).resolves.toEqual({
19
+ apps: [],
20
+ cancelled: true,
21
+ });
22
+ });
23
+ it.each([
24
+ { packageNames: [""] },
25
+ { packageNames: ["../settings"] },
26
+ { packageNames: ["com..example"] },
27
+ { packageNames: [{ name: "com.example.app" }] },
28
+ { appTokens: ["valid", ""] },
29
+ { appTokens: [42] },
30
+ { durationMinutes: 0 },
31
+ { durationMinutes: Number.POSITIVE_INFINITY },
32
+ { durationMinutes: Number.NaN },
33
+ ])("rejects malformed blockApps options %#", async (options) => {
34
+ await expect(new AppBlockerWeb().blockApps(options)).rejects.toThrow(/packageNames|appTokens|durationMinutes/);
35
+ });
36
+ it("returns a mobile-only block response for valid web fallback options", async () => {
37
+ await expect(new AppBlockerWeb().blockApps({
38
+ packageNames: ["com.example.app"],
39
+ appTokens: ["token-1"],
40
+ durationMinutes: 30,
41
+ })).resolves.toEqual({
42
+ success: false,
43
+ endsAt: null,
44
+ error: "App blocking is only available on mobile devices.",
45
+ blockedCount: 0,
46
+ });
47
+ });
48
+ });
49
+ //# sourceMappingURL=web.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.test.js","sourceRoot":"","sources":["../../src/web.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAEtC,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QAC1D,MAAM,OAAO,GAAG,IAAI,aAAa,EAAE,CAAC;QAEpC,MAAM,MAAM,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC;YAC9D,MAAM,EAAE,gBAAgB;YACxB,MAAM,EAAE,MAAM;YACd,UAAU,EAAE,KAAK;SAClB,CAAC,CAAC;QACH,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC;YACvD,MAAM,EAAE,aAAa;YACrB,SAAS,EAAE,KAAK;YAChB,MAAM,EAAE,KAAK;YACb,YAAY,EAAE,CAAC;SAChB,CAAC,CAAC;QACH,MAAM,MAAM,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QACxE,MAAM,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;YAClD,IAAI,EAAE,EAAE;YACR,SAAS,EAAE,IAAI;SAChB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,IAAI,CAAC;QACN,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC,EAAE;QACtB,EAAE,YAAY,EAAE,CAAC,aAAa,CAAC,EAAE;QACjC,EAAE,YAAY,EAAE,CAAC,cAAc,CAAC,EAAE;QAClC,EAAE,YAAY,EAAE,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAuB,CAAC,EAAE;QACpE,EAAE,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE;QAC5B,EAAE,SAAS,EAAE,CAAC,EAAuB,CAAC,EAAE;QACxC,EAAE,eAAe,EAAE,CAAC,EAAE;QACtB,EAAE,eAAe,EAAE,MAAM,CAAC,iBAAiB,EAAE;QAC7C,EAAE,eAAe,EAAE,MAAM,CAAC,GAAG,EAAE;KAChC,CAAC,CAAC,wCAAwC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAC7D,MAAM,MAAM,CAAC,IAAI,aAAa,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAClE,wCAAwC,CACzC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qEAAqE,EAAE,KAAK,IAAI,EAAE;QACnF,MAAM,MAAM,CACV,IAAI,aAAa,EAAE,CAAC,SAAS,CAAC;YAC5B,YAAY,EAAE,CAAC,iBAAiB,CAAC;YACjC,SAAS,EAAE,CAAC,SAAS,CAAC;YACtB,eAAe,EAAE,EAAE;SACpB,CAAC,CACH,CAAC,QAAQ,CAAC,OAAO,CAAC;YACjB,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,IAAI;YACZ,KAAK,EAAE,mDAAmD;YAC1D,YAAY,EAAE,CAAC;SAChB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -2,16 +2,104 @@
2
2
 
3
3
  var core = require('@capacitor/core');
4
4
 
5
+ function toBackendStatus(status) {
6
+ return {
7
+ available: status.available,
8
+ active: status.active,
9
+ platform: status.platform,
10
+ engine: status.engine,
11
+ blockedCount: status.blockedCount,
12
+ blockedPackageNames: status.blockedPackageNames,
13
+ endsAt: status.endsAt,
14
+ permissionStatus: status.permissionStatus,
15
+ reason: status.reason,
16
+ };
17
+ }
18
+ function toBackendPermission(permission) {
19
+ return {
20
+ status: permission.status,
21
+ canRequest: permission.canRequest,
22
+ reason: permission.reason,
23
+ };
24
+ }
25
+ /**
26
+ * Wrap an `AppBlockerPlugin` (pass the registered `AppBlocker` Capacitor
27
+ * plugin) as a `NativeAppBlockerBackend`.
28
+ */
29
+ function createNativeAppBlockerBackend(plugin) {
30
+ return {
31
+ async checkPermissions() {
32
+ return toBackendPermission(await plugin.checkPermissions());
33
+ },
34
+ async requestPermissions() {
35
+ return toBackendPermission(await plugin.requestPermissions());
36
+ },
37
+ getInstalledApps() {
38
+ return plugin.getInstalledApps();
39
+ },
40
+ selectApps() {
41
+ return plugin.selectApps();
42
+ },
43
+ blockApps(options) {
44
+ return plugin.blockApps(options);
45
+ },
46
+ unblockApps() {
47
+ return plugin.unblockApps();
48
+ },
49
+ async getStatus() {
50
+ return toBackendStatus(await plugin.getStatus());
51
+ },
52
+ };
53
+ }
54
+
5
55
  const loadWeb = () => Promise.resolve().then(function () { return web; }).then((module) => new module.AppBlockerWeb());
6
56
  const AppBlocker = core.registerPlugin("ElizaAppBlocker", {
7
57
  web: loadWeb,
8
58
  });
9
59
 
60
+ const PACKAGE_NAME_RE = /^[A-Za-z][A-Za-z0-9_]*(?:\.[A-Za-z][A-Za-z0-9_]*)+$/;
61
+ function validateBlockAppsOptions(options) {
62
+ const packageNames = Array.isArray(options?.packageNames)
63
+ ? options.packageNames
64
+ : [];
65
+ const appTokens = Array.isArray(options?.appTokens) ? options.appTokens : [];
66
+ for (const packageName of packageNames) {
67
+ if (typeof packageName !== "string" ||
68
+ !PACKAGE_NAME_RE.test(packageName.trim())) {
69
+ throw new Error("packageNames must contain valid Android package names");
70
+ }
71
+ }
72
+ for (const token of appTokens) {
73
+ if (typeof token !== "string" || token.trim().length === 0) {
74
+ throw new Error("appTokens must contain non-empty strings");
75
+ }
76
+ }
77
+ if (options?.durationMinutes !== undefined &&
78
+ options.durationMinutes !== null) {
79
+ if (typeof options.durationMinutes !== "number" ||
80
+ !Number.isFinite(options.durationMinutes) ||
81
+ options.durationMinutes <= 0) {
82
+ throw new Error("durationMinutes must be a positive finite number");
83
+ }
84
+ }
85
+ }
10
86
  class AppBlockerWeb extends core.WebPlugin {
11
87
  async checkPermissions() {
12
88
  return {
13
89
  status: "not-applicable",
14
90
  canRequest: false,
91
+ canOpenSettings: false,
92
+ settingsTarget: null,
93
+ engine: "none",
94
+ capabilities: {
95
+ canSelectApps: false,
96
+ canBlockApps: false,
97
+ canScheduleTimedBlocks: false,
98
+ canUnblockEarly: false,
99
+ requiresFamilyControls: false,
100
+ requiresUsageAccess: false,
101
+ requiresOverlay: false,
102
+ },
15
103
  reason: "App blocking is only available on mobile devices.",
16
104
  };
17
105
  }
@@ -19,6 +107,18 @@ class AppBlockerWeb extends core.WebPlugin {
19
107
  return {
20
108
  status: "not-applicable",
21
109
  canRequest: false,
110
+ canOpenSettings: false,
111
+ settingsTarget: null,
112
+ engine: "none",
113
+ capabilities: {
114
+ canSelectApps: false,
115
+ canBlockApps: false,
116
+ canScheduleTimedBlocks: false,
117
+ canUnblockEarly: false,
118
+ requiresFamilyControls: false,
119
+ requiresUsageAccess: false,
120
+ requiresOverlay: false,
121
+ },
22
122
  reason: "App blocking is only available on mobile devices.",
23
123
  };
24
124
  }
@@ -28,7 +128,8 @@ class AppBlockerWeb extends core.WebPlugin {
28
128
  async selectApps() {
29
129
  return { apps: [], cancelled: true };
30
130
  }
31
- async blockApps(_options) {
131
+ async blockApps(options) {
132
+ validateBlockAppsOptions(options);
32
133
  return {
33
134
  success: false,
34
135
  endsAt: null,
@@ -44,14 +145,27 @@ class AppBlockerWeb extends core.WebPlugin {
44
145
  }
45
146
  async getStatus() {
46
147
  return {
148
+ status: "unavailable",
47
149
  available: false,
48
150
  active: false,
49
151
  platform: "web",
50
152
  engine: "none",
153
+ capabilities: {
154
+ canSelectApps: false,
155
+ canBlockApps: false,
156
+ canScheduleTimedBlocks: false,
157
+ canUnblockEarly: false,
158
+ requiresFamilyControls: false,
159
+ requiresUsageAccess: false,
160
+ requiresOverlay: false,
161
+ },
51
162
  blockedCount: 0,
52
163
  blockedPackageNames: [],
53
164
  endsAt: null,
54
165
  permissionStatus: "not-applicable",
166
+ canRequest: false,
167
+ canOpenSettings: false,
168
+ settingsTarget: null,
55
169
  reason: "App blocking is only available on mobile devices.",
56
170
  };
57
171
  }
@@ -63,4 +177,5 @@ var web = /*#__PURE__*/Object.freeze({
63
177
  });
64
178
 
65
179
  exports.AppBlocker = AppBlocker;
180
+ exports.createNativeAppBlockerBackend = createNativeAppBlockerBackend;
66
181
  //# sourceMappingURL=plugin.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from \"@capacitor/core\";\nexport * from \"./definitions\";\nconst loadWeb = () => import(\"./web\").then((module) => new module.AppBlockerWeb());\nexport const AppBlocker = registerPlugin(\"ElizaAppBlocker\", {\n web: loadWeb,\n});\n//# sourceMappingURL=index.js.map","import { WebPlugin } from \"@capacitor/core\";\nexport class AppBlockerWeb extends WebPlugin {\n async checkPermissions() {\n return {\n status: \"not-applicable\",\n canRequest: false,\n reason: \"App blocking is only available on mobile devices.\",\n };\n }\n async requestPermissions() {\n return {\n status: \"not-applicable\",\n canRequest: false,\n reason: \"App blocking is only available on mobile devices.\",\n };\n }\n async getInstalledApps() {\n return { apps: [] };\n }\n async selectApps() {\n return { apps: [], cancelled: true };\n }\n async blockApps(_options) {\n return {\n success: false,\n endsAt: null,\n error: \"App blocking is only available on mobile devices.\",\n blockedCount: 0,\n };\n }\n async unblockApps() {\n return {\n success: false,\n error: \"App blocking is only available on mobile devices.\",\n };\n }\n async getStatus() {\n return {\n available: false,\n active: false,\n platform: \"web\",\n engine: \"none\",\n blockedCount: 0,\n blockedPackageNames: [],\n endsAt: null,\n permissionStatus: \"not-applicable\",\n reason: \"App blocking is only available on mobile devices.\",\n };\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;;AAEA,MAAM,OAAO,GAAG,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;AACtE,MAAC,UAAU,GAAGA,mBAAc,CAAC,iBAAiB,EAAE;AAC5D,IAAI,GAAG,EAAE,OAAO;AAChB,CAAC;;ACJM,MAAM,aAAa,SAASC,cAAS,CAAC;AAC7C,IAAI,MAAM,gBAAgB,GAAG;AAC7B,QAAQ,OAAO;AACf,YAAY,MAAM,EAAE,gBAAgB;AACpC,YAAY,UAAU,EAAE,KAAK;AAC7B,YAAY,MAAM,EAAE,mDAAmD;AACvE,SAAS;AACT,IAAI;AACJ,IAAI,MAAM,kBAAkB,GAAG;AAC/B,QAAQ,OAAO;AACf,YAAY,MAAM,EAAE,gBAAgB;AACpC,YAAY,UAAU,EAAE,KAAK;AAC7B,YAAY,MAAM,EAAE,mDAAmD;AACvE,SAAS;AACT,IAAI;AACJ,IAAI,MAAM,gBAAgB,GAAG;AAC7B,QAAQ,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE;AAC3B,IAAI;AACJ,IAAI,MAAM,UAAU,GAAG;AACvB,QAAQ,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE;AAC5C,IAAI;AACJ,IAAI,MAAM,SAAS,CAAC,QAAQ,EAAE;AAC9B,QAAQ,OAAO;AACf,YAAY,OAAO,EAAE,KAAK;AAC1B,YAAY,MAAM,EAAE,IAAI;AACxB,YAAY,KAAK,EAAE,mDAAmD;AACtE,YAAY,YAAY,EAAE,CAAC;AAC3B,SAAS;AACT,IAAI;AACJ,IAAI,MAAM,WAAW,GAAG;AACxB,QAAQ,OAAO;AACf,YAAY,OAAO,EAAE,KAAK;AAC1B,YAAY,KAAK,EAAE,mDAAmD;AACtE,SAAS;AACT,IAAI;AACJ,IAAI,MAAM,SAAS,GAAG;AACtB,QAAQ,OAAO;AACf,YAAY,SAAS,EAAE,KAAK;AAC5B,YAAY,MAAM,EAAE,KAAK;AACzB,YAAY,QAAQ,EAAE,KAAK;AAC3B,YAAY,MAAM,EAAE,MAAM;AAC1B,YAAY,YAAY,EAAE,CAAC;AAC3B,YAAY,mBAAmB,EAAE,EAAE;AACnC,YAAY,MAAM,EAAE,IAAI;AACxB,YAAY,gBAAgB,EAAE,gBAAgB;AAC9C,YAAY,MAAM,EAAE,mDAAmD;AACvE,SAAS;AACT,IAAI;AACJ;;;;;;;;;"}
1
+ {"version":3,"file":"plugin.cjs.js","sources":["esm/backend.js","esm/index.js","esm/web.js"],"sourcesContent":["function toBackendStatus(status) {\n return {\n available: status.available,\n active: status.active,\n platform: status.platform,\n engine: status.engine,\n blockedCount: status.blockedCount,\n blockedPackageNames: status.blockedPackageNames,\n endsAt: status.endsAt,\n permissionStatus: status.permissionStatus,\n reason: status.reason,\n };\n}\nfunction toBackendPermission(permission) {\n return {\n status: permission.status,\n canRequest: permission.canRequest,\n reason: permission.reason,\n };\n}\n/**\n * Wrap an `AppBlockerPlugin` (pass the registered `AppBlocker` Capacitor\n * plugin) as a `NativeAppBlockerBackend`.\n */\nexport function createNativeAppBlockerBackend(plugin) {\n return {\n async checkPermissions() {\n return toBackendPermission(await plugin.checkPermissions());\n },\n async requestPermissions() {\n return toBackendPermission(await plugin.requestPermissions());\n },\n getInstalledApps() {\n return plugin.getInstalledApps();\n },\n selectApps() {\n return plugin.selectApps();\n },\n blockApps(options) {\n return plugin.blockApps(options);\n },\n unblockApps() {\n return plugin.unblockApps();\n },\n async getStatus() {\n return toBackendStatus(await plugin.getStatus());\n },\n };\n}\n//# sourceMappingURL=backend.js.map","import { registerPlugin } from \"@capacitor/core\";\nexport * from \"./definitions\";\nconst loadWeb = () => import(\"./web\").then((module) => new module.AppBlockerWeb());\nexport const AppBlocker = registerPlugin(\"ElizaAppBlocker\", {\n web: loadWeb,\n});\nexport { createNativeAppBlockerBackend, } from \"./backend\";\n//# sourceMappingURL=index.js.map","import { WebPlugin } from \"@capacitor/core\";\nconst PACKAGE_NAME_RE = /^[A-Za-z][A-Za-z0-9_]*(?:\\.[A-Za-z][A-Za-z0-9_]*)+$/;\nfunction validateBlockAppsOptions(options) {\n const packageNames = Array.isArray(options?.packageNames)\n ? options.packageNames\n : [];\n const appTokens = Array.isArray(options?.appTokens) ? options.appTokens : [];\n for (const packageName of packageNames) {\n if (typeof packageName !== \"string\" ||\n !PACKAGE_NAME_RE.test(packageName.trim())) {\n throw new Error(\"packageNames must contain valid Android package names\");\n }\n }\n for (const token of appTokens) {\n if (typeof token !== \"string\" || token.trim().length === 0) {\n throw new Error(\"appTokens must contain non-empty strings\");\n }\n }\n if (options?.durationMinutes !== undefined &&\n options.durationMinutes !== null) {\n if (typeof options.durationMinutes !== \"number\" ||\n !Number.isFinite(options.durationMinutes) ||\n options.durationMinutes <= 0) {\n throw new Error(\"durationMinutes must be a positive finite number\");\n }\n }\n}\nexport class AppBlockerWeb extends WebPlugin {\n async checkPermissions() {\n return {\n status: \"not-applicable\",\n canRequest: false,\n canOpenSettings: false,\n settingsTarget: null,\n engine: \"none\",\n capabilities: {\n canSelectApps: false,\n canBlockApps: false,\n canScheduleTimedBlocks: false,\n canUnblockEarly: false,\n requiresFamilyControls: false,\n requiresUsageAccess: false,\n requiresOverlay: false,\n },\n reason: \"App blocking is only available on mobile devices.\",\n };\n }\n async requestPermissions() {\n return {\n status: \"not-applicable\",\n canRequest: false,\n canOpenSettings: false,\n settingsTarget: null,\n engine: \"none\",\n capabilities: {\n canSelectApps: false,\n canBlockApps: false,\n canScheduleTimedBlocks: false,\n canUnblockEarly: false,\n requiresFamilyControls: false,\n requiresUsageAccess: false,\n requiresOverlay: false,\n },\n reason: \"App blocking is only available on mobile devices.\",\n };\n }\n async getInstalledApps() {\n return { apps: [] };\n }\n async selectApps() {\n return { apps: [], cancelled: true };\n }\n async blockApps(options) {\n validateBlockAppsOptions(options);\n return {\n success: false,\n endsAt: null,\n error: \"App blocking is only available on mobile devices.\",\n blockedCount: 0,\n };\n }\n async unblockApps() {\n return {\n success: false,\n error: \"App blocking is only available on mobile devices.\",\n };\n }\n async getStatus() {\n return {\n status: \"unavailable\",\n available: false,\n active: false,\n platform: \"web\",\n engine: \"none\",\n capabilities: {\n canSelectApps: false,\n canBlockApps: false,\n canScheduleTimedBlocks: false,\n canUnblockEarly: false,\n requiresFamilyControls: false,\n requiresUsageAccess: false,\n requiresOverlay: false,\n },\n blockedCount: 0,\n blockedPackageNames: [],\n endsAt: null,\n permissionStatus: \"not-applicable\",\n canRequest: false,\n canOpenSettings: false,\n settingsTarget: null,\n reason: \"App blocking is only available on mobile devices.\",\n };\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":"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"}
package/dist/plugin.js CHANGED
@@ -1,16 +1,104 @@
1
1
  var capacitorAppBlocker = (function (exports, core) {
2
2
  'use strict';
3
3
 
4
+ function toBackendStatus(status) {
5
+ return {
6
+ available: status.available,
7
+ active: status.active,
8
+ platform: status.platform,
9
+ engine: status.engine,
10
+ blockedCount: status.blockedCount,
11
+ blockedPackageNames: status.blockedPackageNames,
12
+ endsAt: status.endsAt,
13
+ permissionStatus: status.permissionStatus,
14
+ reason: status.reason,
15
+ };
16
+ }
17
+ function toBackendPermission(permission) {
18
+ return {
19
+ status: permission.status,
20
+ canRequest: permission.canRequest,
21
+ reason: permission.reason,
22
+ };
23
+ }
24
+ /**
25
+ * Wrap an `AppBlockerPlugin` (pass the registered `AppBlocker` Capacitor
26
+ * plugin) as a `NativeAppBlockerBackend`.
27
+ */
28
+ function createNativeAppBlockerBackend(plugin) {
29
+ return {
30
+ async checkPermissions() {
31
+ return toBackendPermission(await plugin.checkPermissions());
32
+ },
33
+ async requestPermissions() {
34
+ return toBackendPermission(await plugin.requestPermissions());
35
+ },
36
+ getInstalledApps() {
37
+ return plugin.getInstalledApps();
38
+ },
39
+ selectApps() {
40
+ return plugin.selectApps();
41
+ },
42
+ blockApps(options) {
43
+ return plugin.blockApps(options);
44
+ },
45
+ unblockApps() {
46
+ return plugin.unblockApps();
47
+ },
48
+ async getStatus() {
49
+ return toBackendStatus(await plugin.getStatus());
50
+ },
51
+ };
52
+ }
53
+
4
54
  const loadWeb = () => Promise.resolve().then(function () { return web; }).then((module) => new module.AppBlockerWeb());
5
55
  const AppBlocker = core.registerPlugin("ElizaAppBlocker", {
6
56
  web: loadWeb,
7
57
  });
8
58
 
59
+ const PACKAGE_NAME_RE = /^[A-Za-z][A-Za-z0-9_]*(?:\.[A-Za-z][A-Za-z0-9_]*)+$/;
60
+ function validateBlockAppsOptions(options) {
61
+ const packageNames = Array.isArray(options?.packageNames)
62
+ ? options.packageNames
63
+ : [];
64
+ const appTokens = Array.isArray(options?.appTokens) ? options.appTokens : [];
65
+ for (const packageName of packageNames) {
66
+ if (typeof packageName !== "string" ||
67
+ !PACKAGE_NAME_RE.test(packageName.trim())) {
68
+ throw new Error("packageNames must contain valid Android package names");
69
+ }
70
+ }
71
+ for (const token of appTokens) {
72
+ if (typeof token !== "string" || token.trim().length === 0) {
73
+ throw new Error("appTokens must contain non-empty strings");
74
+ }
75
+ }
76
+ if (options?.durationMinutes !== undefined &&
77
+ options.durationMinutes !== null) {
78
+ if (typeof options.durationMinutes !== "number" ||
79
+ !Number.isFinite(options.durationMinutes) ||
80
+ options.durationMinutes <= 0) {
81
+ throw new Error("durationMinutes must be a positive finite number");
82
+ }
83
+ }
84
+ }
9
85
  class AppBlockerWeb extends core.WebPlugin {
10
86
  async checkPermissions() {
11
87
  return {
12
88
  status: "not-applicable",
13
89
  canRequest: false,
90
+ canOpenSettings: false,
91
+ settingsTarget: null,
92
+ engine: "none",
93
+ capabilities: {
94
+ canSelectApps: false,
95
+ canBlockApps: false,
96
+ canScheduleTimedBlocks: false,
97
+ canUnblockEarly: false,
98
+ requiresFamilyControls: false,
99
+ requiresUsageAccess: false,
100
+ requiresOverlay: false,
101
+ },
14
102
  reason: "App blocking is only available on mobile devices.",
15
103
  };
16
104
  }
@@ -18,6 +106,18 @@ var capacitorAppBlocker = (function (exports, core) {
18
106
  return {
19
107
  status: "not-applicable",
20
108
  canRequest: false,
109
+ canOpenSettings: false,
110
+ settingsTarget: null,
111
+ engine: "none",
112
+ capabilities: {
113
+ canSelectApps: false,
114
+ canBlockApps: false,
115
+ canScheduleTimedBlocks: false,
116
+ canUnblockEarly: false,
117
+ requiresFamilyControls: false,
118
+ requiresUsageAccess: false,
119
+ requiresOverlay: false,
120
+ },
21
121
  reason: "App blocking is only available on mobile devices.",
22
122
  };
23
123
  }
@@ -27,7 +127,8 @@ var capacitorAppBlocker = (function (exports, core) {
27
127
  async selectApps() {
28
128
  return { apps: [], cancelled: true };
29
129
  }
30
- async blockApps(_options) {
130
+ async blockApps(options) {
131
+ validateBlockAppsOptions(options);
31
132
  return {
32
133
  success: false,
33
134
  endsAt: null,
@@ -43,14 +144,27 @@ var capacitorAppBlocker = (function (exports, core) {
43
144
  }
44
145
  async getStatus() {
45
146
  return {
147
+ status: "unavailable",
46
148
  available: false,
47
149
  active: false,
48
150
  platform: "web",
49
151
  engine: "none",
152
+ capabilities: {
153
+ canSelectApps: false,
154
+ canBlockApps: false,
155
+ canScheduleTimedBlocks: false,
156
+ canUnblockEarly: false,
157
+ requiresFamilyControls: false,
158
+ requiresUsageAccess: false,
159
+ requiresOverlay: false,
160
+ },
50
161
  blockedCount: 0,
51
162
  blockedPackageNames: [],
52
163
  endsAt: null,
53
164
  permissionStatus: "not-applicable",
165
+ canRequest: false,
166
+ canOpenSettings: false,
167
+ settingsTarget: null,
54
168
  reason: "App blocking is only available on mobile devices.",
55
169
  };
56
170
  }
@@ -62,6 +176,7 @@ var capacitorAppBlocker = (function (exports, core) {
62
176
  });
63
177
 
64
178
  exports.AppBlocker = AppBlocker;
179
+ exports.createNativeAppBlockerBackend = createNativeAppBlockerBackend;
65
180
 
66
181
  return exports;
67
182
 
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from \"@capacitor/core\";\nexport * from \"./definitions\";\nconst loadWeb = () => import(\"./web\").then((module) => new module.AppBlockerWeb());\nexport const AppBlocker = registerPlugin(\"ElizaAppBlocker\", {\n web: loadWeb,\n});\n//# sourceMappingURL=index.js.map","import { WebPlugin } from \"@capacitor/core\";\nexport class AppBlockerWeb extends WebPlugin {\n async checkPermissions() {\n return {\n status: \"not-applicable\",\n canRequest: false,\n reason: \"App blocking is only available on mobile devices.\",\n };\n }\n async requestPermissions() {\n return {\n status: \"not-applicable\",\n canRequest: false,\n reason: \"App blocking is only available on mobile devices.\",\n };\n }\n async getInstalledApps() {\n return { apps: [] };\n }\n async selectApps() {\n return { apps: [], cancelled: true };\n }\n async blockApps(_options) {\n return {\n success: false,\n endsAt: null,\n error: \"App blocking is only available on mobile devices.\",\n blockedCount: 0,\n };\n }\n async unblockApps() {\n return {\n success: false,\n error: \"App blocking is only available on mobile devices.\",\n };\n }\n async getStatus() {\n return {\n available: false,\n active: false,\n platform: \"web\",\n engine: \"none\",\n blockedCount: 0,\n blockedPackageNames: [],\n endsAt: null,\n permissionStatus: \"not-applicable\",\n reason: \"App blocking is only available on mobile devices.\",\n };\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;IAEA,MAAM,OAAO,GAAG,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;AACtE,UAAC,UAAU,GAAGA,mBAAc,CAAC,iBAAiB,EAAE;IAC5D,IAAI,GAAG,EAAE,OAAO;IAChB,CAAC;;ICJM,MAAM,aAAa,SAASC,cAAS,CAAC;IAC7C,IAAI,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,OAAO;IACf,YAAY,MAAM,EAAE,gBAAgB;IACpC,YAAY,UAAU,EAAE,KAAK;IAC7B,YAAY,MAAM,EAAE,mDAAmD;IACvE,SAAS;IACT,IAAI;IACJ,IAAI,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,OAAO;IACf,YAAY,MAAM,EAAE,gBAAgB;IACpC,YAAY,UAAU,EAAE,KAAK;IAC7B,YAAY,MAAM,EAAE,mDAAmD;IACvE,SAAS;IACT,IAAI;IACJ,IAAI,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE;IAC3B,IAAI;IACJ,IAAI,MAAM,UAAU,GAAG;IACvB,QAAQ,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE;IAC5C,IAAI;IACJ,IAAI,MAAM,SAAS,CAAC,QAAQ,EAAE;IAC9B,QAAQ,OAAO;IACf,YAAY,OAAO,EAAE,KAAK;IAC1B,YAAY,MAAM,EAAE,IAAI;IACxB,YAAY,KAAK,EAAE,mDAAmD;IACtE,YAAY,YAAY,EAAE,CAAC;IAC3B,SAAS;IACT,IAAI;IACJ,IAAI,MAAM,WAAW,GAAG;IACxB,QAAQ,OAAO;IACf,YAAY,OAAO,EAAE,KAAK;IAC1B,YAAY,KAAK,EAAE,mDAAmD;IACtE,SAAS;IACT,IAAI;IACJ,IAAI,MAAM,SAAS,GAAG;IACtB,QAAQ,OAAO;IACf,YAAY,SAAS,EAAE,KAAK;IAC5B,YAAY,MAAM,EAAE,KAAK;IACzB,YAAY,QAAQ,EAAE,KAAK;IAC3B,YAAY,MAAM,EAAE,MAAM;IAC1B,YAAY,YAAY,EAAE,CAAC;IAC3B,YAAY,mBAAmB,EAAE,EAAE;IACnC,YAAY,MAAM,EAAE,IAAI;IACxB,YAAY,gBAAgB,EAAE,gBAAgB;IAC9C,YAAY,MAAM,EAAE,mDAAmD;IACvE,SAAS;IACT,IAAI;IACJ;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"plugin.js","sources":["esm/backend.js","esm/index.js","esm/web.js"],"sourcesContent":["function toBackendStatus(status) {\n return {\n available: status.available,\n active: status.active,\n platform: status.platform,\n engine: status.engine,\n blockedCount: status.blockedCount,\n blockedPackageNames: status.blockedPackageNames,\n endsAt: status.endsAt,\n permissionStatus: status.permissionStatus,\n reason: status.reason,\n };\n}\nfunction toBackendPermission(permission) {\n return {\n status: permission.status,\n canRequest: permission.canRequest,\n reason: permission.reason,\n };\n}\n/**\n * Wrap an `AppBlockerPlugin` (pass the registered `AppBlocker` Capacitor\n * plugin) as a `NativeAppBlockerBackend`.\n */\nexport function createNativeAppBlockerBackend(plugin) {\n return {\n async checkPermissions() {\n return toBackendPermission(await plugin.checkPermissions());\n },\n async requestPermissions() {\n return toBackendPermission(await plugin.requestPermissions());\n },\n getInstalledApps() {\n return plugin.getInstalledApps();\n },\n selectApps() {\n return plugin.selectApps();\n },\n blockApps(options) {\n return plugin.blockApps(options);\n },\n unblockApps() {\n return plugin.unblockApps();\n },\n async getStatus() {\n return toBackendStatus(await plugin.getStatus());\n },\n };\n}\n//# sourceMappingURL=backend.js.map","import { registerPlugin } from \"@capacitor/core\";\nexport * from \"./definitions\";\nconst loadWeb = () => import(\"./web\").then((module) => new module.AppBlockerWeb());\nexport const AppBlocker = registerPlugin(\"ElizaAppBlocker\", {\n web: loadWeb,\n});\nexport { createNativeAppBlockerBackend, } from \"./backend\";\n//# sourceMappingURL=index.js.map","import { WebPlugin } from \"@capacitor/core\";\nconst PACKAGE_NAME_RE = /^[A-Za-z][A-Za-z0-9_]*(?:\\.[A-Za-z][A-Za-z0-9_]*)+$/;\nfunction validateBlockAppsOptions(options) {\n const packageNames = Array.isArray(options?.packageNames)\n ? options.packageNames\n : [];\n const appTokens = Array.isArray(options?.appTokens) ? options.appTokens : [];\n for (const packageName of packageNames) {\n if (typeof packageName !== \"string\" ||\n !PACKAGE_NAME_RE.test(packageName.trim())) {\n throw new Error(\"packageNames must contain valid Android package names\");\n }\n }\n for (const token of appTokens) {\n if (typeof token !== \"string\" || token.trim().length === 0) {\n throw new Error(\"appTokens must contain non-empty strings\");\n }\n }\n if (options?.durationMinutes !== undefined &&\n options.durationMinutes !== null) {\n if (typeof options.durationMinutes !== \"number\" ||\n !Number.isFinite(options.durationMinutes) ||\n options.durationMinutes <= 0) {\n throw new Error(\"durationMinutes must be a positive finite number\");\n }\n }\n}\nexport class AppBlockerWeb extends WebPlugin {\n async checkPermissions() {\n return {\n status: \"not-applicable\",\n canRequest: false,\n canOpenSettings: false,\n settingsTarget: null,\n engine: \"none\",\n capabilities: {\n canSelectApps: false,\n canBlockApps: false,\n canScheduleTimedBlocks: false,\n canUnblockEarly: false,\n requiresFamilyControls: false,\n requiresUsageAccess: false,\n requiresOverlay: false,\n },\n reason: \"App blocking is only available on mobile devices.\",\n };\n }\n async requestPermissions() {\n return {\n status: \"not-applicable\",\n canRequest: false,\n canOpenSettings: false,\n settingsTarget: null,\n engine: \"none\",\n capabilities: {\n canSelectApps: false,\n canBlockApps: false,\n canScheduleTimedBlocks: false,\n canUnblockEarly: false,\n requiresFamilyControls: false,\n requiresUsageAccess: false,\n requiresOverlay: false,\n },\n reason: \"App blocking is only available on mobile devices.\",\n };\n }\n async getInstalledApps() {\n return { apps: [] };\n }\n async selectApps() {\n return { apps: [], cancelled: true };\n }\n async blockApps(options) {\n validateBlockAppsOptions(options);\n return {\n success: false,\n endsAt: null,\n error: \"App blocking is only available on mobile devices.\",\n blockedCount: 0,\n };\n }\n async unblockApps() {\n return {\n success: false,\n error: \"App blocking is only available on mobile devices.\",\n };\n }\n async getStatus() {\n return {\n status: \"unavailable\",\n available: false,\n active: false,\n platform: \"web\",\n engine: \"none\",\n capabilities: {\n canSelectApps: false,\n canBlockApps: false,\n canScheduleTimedBlocks: false,\n canUnblockEarly: false,\n requiresFamilyControls: false,\n requiresUsageAccess: false,\n requiresOverlay: false,\n },\n blockedCount: 0,\n blockedPackageNames: [],\n endsAt: null,\n permissionStatus: \"not-applicable\",\n canRequest: false,\n canOpenSettings: false,\n settingsTarget: null,\n reason: \"App blocking is only available on mobile devices.\",\n };\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":"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"}
@@ -97,7 +97,7 @@ public class ElizaAppBlockerPlugin: CAPPlugin, CAPBridgedPlugin {
97
97
  call.resolve([
98
98
  "success": false,
99
99
  "endsAt": NSNull(),
100
- "error": "Timed iPhone app blocking still needs a DeviceActivity extension. Start an indefinite block for now and unblock it manually.",
100
+ "error": "Timed iPhone app blocking requires a DeviceActivity extension. Omit durationMinutes for an indefinite block, then call unblockApps when the block should end.",
101
101
  "blockedCount": 0,
102
102
  ])
103
103
  return
@@ -136,16 +136,22 @@ public class ElizaAppBlockerPlugin: CAPPlugin, CAPBridgedPlugin {
136
136
  let permissionStatus = permission["status"] as? String ?? "not-determined"
137
137
  let reason = permission["reason"] as? String
138
138
  let blockedCount = state?.tokenDataArray.count ?? 0
139
+ let active = permissionStatus == "granted" && blockedCount > 0
139
140
 
140
141
  call.resolve([
142
+ "status": active ? "active" : "inactive",
141
143
  "available": true,
142
- "active": permissionStatus == "granted" && blockedCount > 0,
144
+ "active": active,
143
145
  "platform": "ios",
144
146
  "engine": "family-controls",
147
+ "capabilities": appBlockerCapabilities(),
145
148
  "blockedCount": blockedCount,
146
149
  "blockedPackageNames": [],
147
150
  "endsAt": nullable(AppBlockerShared.endsAtString(for: state)),
148
151
  "permissionStatus": permissionStatus,
152
+ "canRequest": permission["canRequest"] as? Bool ?? false,
153
+ "canOpenSettings": permission["canOpenSettings"] as? Bool ?? true,
154
+ "settingsTarget": nullable(permission["settingsTarget"]),
149
155
  "reason": nullable(reason),
150
156
  ])
151
157
  }
@@ -154,22 +160,30 @@ public class ElizaAppBlockerPlugin: CAPPlugin, CAPBridgedPlugin {
154
160
  let status = AuthorizationCenter.shared.authorizationStatus
155
161
  let mappedStatus: String
156
162
  let canRequest: Bool
163
+ let settingsTarget: Any
157
164
 
158
165
  switch status {
159
166
  case .approved:
160
167
  mappedStatus = "granted"
161
168
  canRequest = false
169
+ settingsTarget = NSNull()
162
170
  case .notDetermined:
163
171
  mappedStatus = "not-determined"
164
172
  canRequest = true
173
+ settingsTarget = "screenTime"
165
174
  default:
166
175
  mappedStatus = "denied"
167
176
  canRequest = true
177
+ settingsTarget = "screenTime"
168
178
  }
169
179
 
170
180
  var result: [String: Any] = [
171
181
  "status": mappedStatus,
172
182
  "canRequest": canRequest,
183
+ "canOpenSettings": mappedStatus != "granted",
184
+ "settingsTarget": settingsTarget,
185
+ "engine": "family-controls",
186
+ "capabilities": appBlockerCapabilities(),
173
187
  ]
174
188
 
175
189
  if let reason = reasonOverride ?? permissionReason(for: status) {
@@ -179,6 +193,18 @@ public class ElizaAppBlockerPlugin: CAPPlugin, CAPBridgedPlugin {
179
193
  return result
180
194
  }
181
195
 
196
+ private func appBlockerCapabilities() -> [String: Any] {
197
+ [
198
+ "canSelectApps": true,
199
+ "canBlockApps": true,
200
+ "canScheduleTimedBlocks": false,
201
+ "canUnblockEarly": true,
202
+ "requiresFamilyControls": true,
203
+ "requiresUsageAccess": false,
204
+ "requiresOverlay": false,
205
+ ]
206
+ }
207
+
182
208
  private func permissionReason(for status: AuthorizationStatus) -> String? {
183
209
  switch status {
184
210
  case .approved:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elizaos/capacitor-appblocker",
3
- "version": "1.0.0",
3
+ "version": "2.0.11-beta.7",
4
4
  "description": "Blocks selected apps on Android with Usage Access and an overlay shield, and on iPhone with Family Controls.",
5
5
  "keywords": [
6
6
  "app-blocker",
@@ -14,6 +14,8 @@
14
14
  "exports": {
15
15
  ".": {
16
16
  "types": "./dist/esm/index.d.ts",
17
+ "bun": "./src/index.ts",
18
+ "development": "./src/index.ts",
17
19
  "import": "./dist/esm/index.js",
18
20
  "require": "./dist/plugin.cjs.js"
19
21
  },
@@ -25,19 +27,22 @@
25
27
  "android/build.gradle",
26
28
  "dist/",
27
29
  "ios/Sources/",
28
- "*.podspec"
30
+ "*.podspec",
31
+ "dist"
29
32
  ],
30
33
  "scripts": {
31
- "build": "npm run clean && tsc && rollup -c rollup.config.mjs",
32
- "clean": "rimraf ./dist",
33
- "prepublishOnly": "npm run build"
34
+ "build": "node ../../packages/scripts/with-package-build-lock.mjs plugins/plugin-native-appblocker -- bun run build:unlocked",
35
+ "clean": "node ../../packages/scripts/rm-path-recursive.mjs dist",
36
+ "test": "vitest run",
37
+ "prepublishOnly": "bun run build",
38
+ "build:unlocked": "bun run clean && tsc && bunx rollup -c rollup.config.mjs"
34
39
  },
35
40
  "author": "elizaOS",
36
41
  "license": "MIT",
37
42
  "repository": {
38
43
  "type": "git",
39
44
  "url": "https://github.com/elizaOS/eliza.git",
40
- "directory": "packages/native-plugins/appblocker"
45
+ "directory": "plugins/plugin-native-appblocker"
41
46
  },
42
47
  "capacitor": {
43
48
  "ios": {
@@ -49,11 +54,10 @@
49
54
  }
50
55
  },
51
56
  "devDependencies": {
52
- "@capacitor/cli": "^8.0.0",
53
57
  "@capacitor/core": "^8.3.1",
54
- "rimraf": "^6.0.0",
55
58
  "rollup": "^4.60.2",
56
- "typescript": "^6.0.0"
59
+ "typescript": "^6.0.3",
60
+ "vitest": "^4.0.0"
57
61
  },
58
62
  "peerDependencies": {
59
63
  "@capacitor/core": "^8.3.1"
@@ -73,5 +77,6 @@
73
77
  "ios": "Uses Family Controls and Managed Settings to shield selected apps.",
74
78
  "android": "Uses Usage Access polling plus a system overlay shield."
75
79
  }
76
- }
80
+ },
81
+ "gitHead": "cdbc876f793d96073d7eb0d09715a031ce0cd32e"
77
82
  }