@elizaos/capacitor-websiteblocker 2.0.0-beta.1 → 2.0.3-beta.3

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/dist/plugin.js CHANGED
@@ -1,11 +1,143 @@
1
1
  var capacitorWebsiteBlocker = (function (exports, core) {
2
2
  'use strict';
3
3
 
4
+ function toSelfControlStatus(status) {
5
+ return {
6
+ available: status.available,
7
+ active: status.active,
8
+ hostsFilePath: status.hostsFilePath,
9
+ startedAt: null,
10
+ endsAt: status.endsAt,
11
+ websites: status.websites,
12
+ blockedWebsites: status.blockedWebsites,
13
+ allowedWebsites: status.allowedWebsites,
14
+ requestedWebsites: status.requestedWebsites,
15
+ matchMode: status.matchMode,
16
+ managedBy: null,
17
+ metadata: null,
18
+ scheduledByAgentId: null,
19
+ canUnblockEarly: status.canUnblockEarly,
20
+ requiresElevation: status.requiresElevation,
21
+ engine: status.engine,
22
+ platform: status.platform,
23
+ supportsElevationPrompt: status.supportsElevationPrompt,
24
+ elevationPromptMethod: toElevationMethod(status.elevationPromptMethod),
25
+ reason: status.reason,
26
+ };
27
+ }
28
+ function toElevationMethod(method) {
29
+ return method === "osascript" ||
30
+ method === "pkexec" ||
31
+ method === "powershell-runas" ||
32
+ method === "vpn-consent" ||
33
+ method === "system-settings"
34
+ ? method
35
+ : null;
36
+ }
37
+ function toSelfControlPermissionState(permission) {
38
+ return {
39
+ id: "website-blocking",
40
+ status: permission.status,
41
+ lastChecked: Date.now(),
42
+ canRequest: permission.canRequest,
43
+ reason: permission.reason,
44
+ supportsElevationPrompt: permission.canRequest,
45
+ };
46
+ }
47
+ /**
48
+ * Wrap a `WebsiteBlockerPlugin` (pass the registered `WebsiteBlocker` Capacitor
49
+ * plugin) as a `NativeWebsiteBlockerBackend`.
50
+ */
51
+ function createNativeWebsiteBlockerBackend(plugin) {
52
+ return {
53
+ async getStatus() {
54
+ return toSelfControlStatus(await plugin.getStatus());
55
+ },
56
+ async startBlock(request) {
57
+ const options = {
58
+ websites: request.websites,
59
+ durationMinutes: request.durationMinutes,
60
+ };
61
+ const result = await plugin.startBlock(options);
62
+ if (result.success) {
63
+ return { success: true, endsAt: result.endsAt };
64
+ }
65
+ return { success: false, error: result.error };
66
+ },
67
+ async stopBlock() {
68
+ const result = await plugin.stopBlock();
69
+ const status = toSelfControlStatus(await plugin.getStatus());
70
+ if (result.success) {
71
+ return { success: true, removed: result.removed, status };
72
+ }
73
+ return { success: false, error: result.error, status };
74
+ },
75
+ async getPermissionState() {
76
+ return toSelfControlPermissionState(await plugin.checkPermissions());
77
+ },
78
+ async requestPermission() {
79
+ return toSelfControlPermissionState(await plugin.requestPermissions());
80
+ },
81
+ };
82
+ }
83
+
4
84
  const loadWeb = () => Promise.resolve().then(function () { return web; }).then((module) => new module.WebsiteBlockerWeb());
5
85
  const WebsiteBlocker = core.registerPlugin("ElizaWebsiteBlocker", {
6
86
  web: loadWeb,
7
87
  });
8
88
 
89
+ const HOSTNAME_RE = /^(?=.{1,253}$)(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\.)+[A-Za-z]{2,63}$/;
90
+ function isString(value) {
91
+ return typeof value === "string";
92
+ }
93
+ function normalizeHostname(value) {
94
+ if (typeof value !== "string")
95
+ return null;
96
+ const trimmed = value.trim();
97
+ if (!trimmed)
98
+ return null;
99
+ if (/^[a-z][a-z0-9+.-]*:/i.test(trimmed)) {
100
+ if (!/^https?:\/\//i.test(trimmed))
101
+ return null;
102
+ try {
103
+ return normalizeHostname(new URL(trimmed).hostname);
104
+ }
105
+ catch {
106
+ return null;
107
+ }
108
+ }
109
+ const withoutWildcard = trimmed.replace(/^\*\./, "");
110
+ const withoutTrailingDot = withoutWildcard.replace(/\.$/, "");
111
+ const ascii = withoutTrailingDot.toLowerCase();
112
+ return HOSTNAME_RE.test(ascii) ? ascii : null;
113
+ }
114
+ function validateStartBlockOptions(options) {
115
+ const candidates = [
116
+ ...(Array.isArray(options?.websites) ? options.websites : []),
117
+ ...(typeof options?.websites === "string" ? [options.websites] : []),
118
+ ];
119
+ if (typeof options?.text === "string") {
120
+ candidates.push(...options.text.split(/[\s,]+/));
121
+ }
122
+ const websites = [
123
+ ...new Set(candidates.map(normalizeHostname).filter(isString)),
124
+ ];
125
+ if (websites.length === 0) {
126
+ throw new Error("Provide at least one public website hostname.");
127
+ }
128
+ let durationMinutes = null;
129
+ if (options?.durationMinutes !== undefined &&
130
+ options.durationMinutes !== null) {
131
+ const parsed = typeof options.durationMinutes === "number"
132
+ ? options.durationMinutes
133
+ : Number(options.durationMinutes);
134
+ if (!Number.isFinite(parsed) || parsed <= 0) {
135
+ throw new Error("durationMinutes must be a positive finite number");
136
+ }
137
+ durationMinutes = Math.trunc(parsed);
138
+ }
139
+ return { websites, durationMinutes };
140
+ }
9
141
  class WebsiteBlockerWeb extends core.WebPlugin {
10
142
  apiBase() {
11
143
  const global = typeof window !== "undefined"
@@ -67,9 +199,10 @@ var capacitorWebsiteBlocker = (function (exports, core) {
67
199
  return await this.requestJson("/api/website-blocker");
68
200
  }
69
201
  async startBlock(options) {
202
+ const body = validateStartBlockOptions(options);
70
203
  return await this.requestJson("/api/website-blocker", {
71
204
  method: "PUT",
72
- body: JSON.stringify(options),
205
+ body: JSON.stringify(body),
73
206
  });
74
207
  }
75
208
  async stopBlock() {
@@ -82,6 +215,9 @@ var capacitorWebsiteBlocker = (function (exports, core) {
82
215
  return {
83
216
  status: permission.status,
84
217
  canRequest: permission.canRequest,
218
+ canOpenSettings: permission.canOpenSettings ?? true,
219
+ settingsTarget: permission.settingsTarget ?? "runtime",
220
+ engine: permission.engine ?? "hosts-file",
85
221
  reason: permission.reason,
86
222
  };
87
223
  }
@@ -92,16 +228,30 @@ var capacitorWebsiteBlocker = (function (exports, core) {
92
228
  return {
93
229
  status: permission.status,
94
230
  canRequest: permission.canRequest,
231
+ canOpenSettings: permission.canOpenSettings ?? true,
232
+ settingsTarget: permission.settingsTarget ?? "runtime",
233
+ engine: permission.engine ?? "hosts-file",
95
234
  reason: permission.reason,
96
235
  };
97
236
  }
98
237
  async openSettings() {
99
238
  if (!this.canReachApi()) {
100
- return { opened: false };
239
+ return {
240
+ opened: false,
241
+ target: "runtime",
242
+ actualTarget: "runtime",
243
+ reason: "Eliza API not available.",
244
+ };
101
245
  }
102
- return await this.requestJson("/api/permissions/website-blocking/open-settings", {
246
+ const result = await this.requestJson("/api/permissions/website-blocking/open-settings", {
103
247
  method: "POST",
104
248
  });
249
+ return {
250
+ opened: result.opened ?? false,
251
+ target: result.target ?? "runtime",
252
+ actualTarget: result.actualTarget ?? result.target ?? "runtime",
253
+ reason: result.reason ?? null,
254
+ };
105
255
  }
106
256
  }
107
257
 
@@ -111,6 +261,7 @@ var capacitorWebsiteBlocker = (function (exports, core) {
111
261
  });
112
262
 
113
263
  exports.WebsiteBlocker = WebsiteBlocker;
264
+ exports.createNativeWebsiteBlockerBackend = createNativeWebsiteBlockerBackend;
114
265
 
115
266
  return exports;
116
267
 
@@ -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.WebsiteBlockerWeb());\nexport const WebsiteBlocker = registerPlugin(\"ElizaWebsiteBlocker\", {\n web: loadWeb,\n});\n//# sourceMappingURL=index.js.map","import { WebPlugin } from \"@capacitor/core\";\nexport class WebsiteBlockerWeb extends WebPlugin {\n apiBase() {\n const global = typeof window !== \"undefined\"\n ? window.__ELIZA_API_BASE__\n : undefined;\n if (typeof global === \"string\" && global.trim().length > 0) {\n return global;\n }\n return \"\";\n }\n apiToken() {\n const global = typeof window !== \"undefined\"\n ? window.__ELIZA_API_TOKEN__\n : undefined;\n if (typeof global === \"string\" && global.trim().length > 0) {\n return global.trim();\n }\n if (typeof window === \"undefined\") {\n return null;\n }\n const stored = window.sessionStorage.getItem(\"eliza_api_token\");\n return stored?.trim() ? stored.trim() : null;\n }\n authHeaders() {\n const token = this.apiToken();\n return token ? { Authorization: `Bearer ${token}` } : {};\n }\n canReachApi() {\n const global = typeof window !== \"undefined\"\n ? window.__ELIZA_API_BASE__\n : undefined;\n if (typeof global === \"string\" && global.trim().length > 0) {\n return true;\n }\n if (typeof window === \"undefined\") {\n return false;\n }\n const protocol = window.location.protocol;\n return protocol === \"http:\" || protocol === \"https:\";\n }\n async requestJson(pathname, init) {\n if (!this.canReachApi()) {\n throw new Error(\"Eliza API not available\");\n }\n const response = await fetch(`${this.apiBase()}${pathname}`, {\n ...init,\n headers: {\n ...(init?.body ? { \"Content-Type\": \"application/json\" } : {}),\n ...this.authHeaders(),\n ...(init?.headers ?? {}),\n },\n });\n if (!response.ok) {\n throw new Error(`Request failed (${response.status})`);\n }\n return (await response.json());\n }\n async getStatus() {\n return await this.requestJson(\"/api/website-blocker\");\n }\n async startBlock(options) {\n return await this.requestJson(\"/api/website-blocker\", {\n method: \"PUT\",\n body: JSON.stringify(options),\n });\n }\n async stopBlock() {\n return await this.requestJson(\"/api/website-blocker\", {\n method: \"DELETE\",\n });\n }\n async checkPermissions() {\n const permission = await this.requestJson(\"/api/permissions/website-blocking\");\n return {\n status: permission.status,\n canRequest: permission.canRequest,\n reason: permission.reason,\n };\n }\n async requestPermissions() {\n const permission = await this.requestJson(\"/api/permissions/website-blocking/request\", {\n method: \"POST\",\n });\n return {\n status: permission.status,\n canRequest: permission.canRequest,\n reason: permission.reason,\n };\n }\n async openSettings() {\n if (!this.canReachApi()) {\n return { opened: false };\n }\n return await this.requestJson(\"/api/permissions/website-blocking/open-settings\", {\n method: \"POST\",\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,iBAAiB,EAAE,CAAC;AAC1E,UAAC,cAAc,GAAGA,mBAAc,CAAC,qBAAqB,EAAE;IACpE,IAAI,GAAG,EAAE,OAAO;IAChB,CAAC;;ICJM,MAAM,iBAAiB,SAASC,cAAS,CAAC;IACjD,IAAI,OAAO,GAAG;IACd,QAAQ,MAAM,MAAM,GAAG,OAAO,MAAM,KAAK;IACzC,cAAc,MAAM,CAAC;IACrB,cAAc,SAAS;IACvB,QAAQ,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE;IACpE,YAAY,OAAO,MAAM;IACzB,QAAQ;IACR,QAAQ,OAAO,EAAE;IACjB,IAAI;IACJ,IAAI,QAAQ,GAAG;IACf,QAAQ,MAAM,MAAM,GAAG,OAAO,MAAM,KAAK;IACzC,cAAc,MAAM,CAAC;IACrB,cAAc,SAAS;IACvB,QAAQ,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE;IACpE,YAAY,OAAO,MAAM,CAAC,IAAI,EAAE;IAChC,QAAQ;IACR,QAAQ,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;IAC3C,YAAY,OAAO,IAAI;IACvB,QAAQ;IACR,QAAQ,MAAM,MAAM,GAAG,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,iBAAiB,CAAC;IACvE,QAAQ,OAAO,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC,IAAI,EAAE,GAAG,IAAI;IACpD,IAAI;IACJ,IAAI,WAAW,GAAG;IAClB,QAAQ,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE;IACrC,QAAQ,OAAO,KAAK,GAAG,EAAE,aAAa,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE;IAChE,IAAI;IACJ,IAAI,WAAW,GAAG;IAClB,QAAQ,MAAM,MAAM,GAAG,OAAO,MAAM,KAAK;IACzC,cAAc,MAAM,CAAC;IACrB,cAAc,SAAS;IACvB,QAAQ,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE;IACpE,YAAY,OAAO,IAAI;IACvB,QAAQ;IACR,QAAQ,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;IAC3C,YAAY,OAAO,KAAK;IACxB,QAAQ;IACR,QAAQ,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ;IACjD,QAAQ,OAAO,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,QAAQ;IAC5D,IAAI;IACJ,IAAI,MAAM,WAAW,CAAC,QAAQ,EAAE,IAAI,EAAE;IACtC,QAAQ,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE;IACjC,YAAY,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC;IACtD,QAAQ;IACR,QAAQ,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAE;IACrE,YAAY,GAAG,IAAI;IACnB,YAAY,OAAO,EAAE;IACrB,gBAAgB,IAAI,IAAI,EAAE,IAAI,GAAG,EAAE,cAAc,EAAE,kBAAkB,EAAE,GAAG,EAAE,CAAC;IAC7E,gBAAgB,GAAG,IAAI,CAAC,WAAW,EAAE;IACrC,gBAAgB,IAAI,IAAI,EAAE,OAAO,IAAI,EAAE,CAAC;IACxC,aAAa;IACb,SAAS,CAAC;IACV,QAAQ,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE;IAC1B,YAAY,MAAM,IAAI,KAAK,CAAC,CAAC,gBAAgB,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAClE,QAAQ;IACR,QAAQ,QAAQ,MAAM,QAAQ,CAAC,IAAI,EAAE;IACrC,IAAI;IACJ,IAAI,MAAM,SAAS,GAAG;IACtB,QAAQ,OAAO,MAAM,IAAI,CAAC,WAAW,CAAC,sBAAsB,CAAC;IAC7D,IAAI;IACJ,IAAI,MAAM,UAAU,CAAC,OAAO,EAAE;IAC9B,QAAQ,OAAO,MAAM,IAAI,CAAC,WAAW,CAAC,sBAAsB,EAAE;IAC9D,YAAY,MAAM,EAAE,KAAK;IACzB,YAAY,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;IACzC,SAAS,CAAC;IACV,IAAI;IACJ,IAAI,MAAM,SAAS,GAAG;IACtB,QAAQ,OAAO,MAAM,IAAI,CAAC,WAAW,CAAC,sBAAsB,EAAE;IAC9D,YAAY,MAAM,EAAE,QAAQ;IAC5B,SAAS,CAAC;IACV,IAAI;IACJ,IAAI,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,mCAAmC,CAAC;IACtF,QAAQ,OAAO;IACf,YAAY,MAAM,EAAE,UAAU,CAAC,MAAM;IACrC,YAAY,UAAU,EAAE,UAAU,CAAC,UAAU;IAC7C,YAAY,MAAM,EAAE,UAAU,CAAC,MAAM;IACrC,SAAS;IACT,IAAI;IACJ,IAAI,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,2CAA2C,EAAE;IAC/F,YAAY,MAAM,EAAE,MAAM;IAC1B,SAAS,CAAC;IACV,QAAQ,OAAO;IACf,YAAY,MAAM,EAAE,UAAU,CAAC,MAAM;IACrC,YAAY,UAAU,EAAE,UAAU,CAAC,UAAU;IAC7C,YAAY,MAAM,EAAE,UAAU,CAAC,MAAM;IACrC,SAAS;IACT,IAAI;IACJ,IAAI,MAAM,YAAY,GAAG;IACzB,QAAQ,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE;IACjC,YAAY,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE;IACpC,QAAQ;IACR,QAAQ,OAAO,MAAM,IAAI,CAAC,WAAW,CAAC,iDAAiD,EAAE;IACzF,YAAY,MAAM,EAAE,MAAM;IAC1B,SAAS,CAAC;IACV,IAAI;IACJ;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"plugin.js","sources":["esm/backend.js","esm/index.js","esm/web.js"],"sourcesContent":["function toSelfControlStatus(status) {\n return {\n available: status.available,\n active: status.active,\n hostsFilePath: status.hostsFilePath,\n startedAt: null,\n endsAt: status.endsAt,\n websites: status.websites,\n blockedWebsites: status.blockedWebsites,\n allowedWebsites: status.allowedWebsites,\n requestedWebsites: status.requestedWebsites,\n matchMode: status.matchMode,\n managedBy: null,\n metadata: null,\n scheduledByAgentId: null,\n canUnblockEarly: status.canUnblockEarly,\n requiresElevation: status.requiresElevation,\n engine: status.engine,\n platform: status.platform,\n supportsElevationPrompt: status.supportsElevationPrompt,\n elevationPromptMethod: toElevationMethod(status.elevationPromptMethod),\n reason: status.reason,\n };\n}\nfunction toElevationMethod(method) {\n return method === \"osascript\" ||\n method === \"pkexec\" ||\n method === \"powershell-runas\" ||\n method === \"vpn-consent\" ||\n method === \"system-settings\"\n ? method\n : null;\n}\nfunction toSelfControlPermissionState(permission) {\n return {\n id: \"website-blocking\",\n status: permission.status,\n lastChecked: Date.now(),\n canRequest: permission.canRequest,\n reason: permission.reason,\n supportsElevationPrompt: permission.canRequest,\n };\n}\n/**\n * Wrap a `WebsiteBlockerPlugin` (pass the registered `WebsiteBlocker` Capacitor\n * plugin) as a `NativeWebsiteBlockerBackend`.\n */\nexport function createNativeWebsiteBlockerBackend(plugin) {\n return {\n async getStatus() {\n return toSelfControlStatus(await plugin.getStatus());\n },\n async startBlock(request) {\n const options = {\n websites: request.websites,\n durationMinutes: request.durationMinutes,\n };\n const result = await plugin.startBlock(options);\n if (result.success) {\n return { success: true, endsAt: result.endsAt };\n }\n return { success: false, error: result.error };\n },\n async stopBlock() {\n const result = await plugin.stopBlock();\n const status = toSelfControlStatus(await plugin.getStatus());\n if (result.success) {\n return { success: true, removed: result.removed, status };\n }\n return { success: false, error: result.error, status };\n },\n async getPermissionState() {\n return toSelfControlPermissionState(await plugin.checkPermissions());\n },\n async requestPermission() {\n return toSelfControlPermissionState(await plugin.requestPermissions());\n },\n };\n}\n//# sourceMappingURL=backend.js.map","import { registerPlugin } from \"@capacitor/core\";\nexport * from \"./definitions\";\nconst loadWeb = () => import(\"./web\").then((module) => new module.WebsiteBlockerWeb());\nexport const WebsiteBlocker = registerPlugin(\"ElizaWebsiteBlocker\", {\n web: loadWeb,\n});\nexport { createNativeWebsiteBlockerBackend, } from \"./backend\";\n//# sourceMappingURL=index.js.map","import { WebPlugin } from \"@capacitor/core\";\nconst HOSTNAME_RE = /^(?=.{1,253}$)(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\\.)+[A-Za-z]{2,63}$/;\nfunction isString(value) {\n return typeof value === \"string\";\n}\nfunction normalizeHostname(value) {\n if (typeof value !== \"string\")\n return null;\n const trimmed = value.trim();\n if (!trimmed)\n return null;\n if (/^[a-z][a-z0-9+.-]*:/i.test(trimmed)) {\n if (!/^https?:\\/\\//i.test(trimmed))\n return null;\n try {\n return normalizeHostname(new URL(trimmed).hostname);\n }\n catch {\n return null;\n }\n }\n const withoutWildcard = trimmed.replace(/^\\*\\./, \"\");\n const withoutTrailingDot = withoutWildcard.replace(/\\.$/, \"\");\n const ascii = withoutTrailingDot.toLowerCase();\n return HOSTNAME_RE.test(ascii) ? ascii : null;\n}\nfunction validateStartBlockOptions(options) {\n const candidates = [\n ...(Array.isArray(options?.websites) ? options.websites : []),\n ...(typeof options?.websites === \"string\" ? [options.websites] : []),\n ];\n if (typeof options?.text === \"string\") {\n candidates.push(...options.text.split(/[\\s,]+/));\n }\n const websites = [\n ...new Set(candidates.map(normalizeHostname).filter(isString)),\n ];\n if (websites.length === 0) {\n throw new Error(\"Provide at least one public website hostname.\");\n }\n let durationMinutes = null;\n if (options?.durationMinutes !== undefined &&\n options.durationMinutes !== null) {\n const parsed = typeof options.durationMinutes === \"number\"\n ? options.durationMinutes\n : Number(options.durationMinutes);\n if (!Number.isFinite(parsed) || parsed <= 0) {\n throw new Error(\"durationMinutes must be a positive finite number\");\n }\n durationMinutes = Math.trunc(parsed);\n }\n return { websites, durationMinutes };\n}\nexport class WebsiteBlockerWeb extends WebPlugin {\n apiBase() {\n const global = typeof window !== \"undefined\"\n ? window.__ELIZA_API_BASE__\n : undefined;\n if (typeof global === \"string\" && global.trim().length > 0) {\n return global;\n }\n return \"\";\n }\n apiToken() {\n const global = typeof window !== \"undefined\"\n ? window.__ELIZA_API_TOKEN__\n : undefined;\n if (typeof global === \"string\" && global.trim().length > 0) {\n return global.trim();\n }\n if (typeof window === \"undefined\") {\n return null;\n }\n const stored = window.sessionStorage.getItem(\"eliza_api_token\");\n return stored?.trim() ? stored.trim() : null;\n }\n authHeaders() {\n const token = this.apiToken();\n return token ? { Authorization: `Bearer ${token}` } : {};\n }\n canReachApi() {\n const global = typeof window !== \"undefined\"\n ? window.__ELIZA_API_BASE__\n : undefined;\n if (typeof global === \"string\" && global.trim().length > 0) {\n return true;\n }\n if (typeof window === \"undefined\") {\n return false;\n }\n const protocol = window.location.protocol;\n return protocol === \"http:\" || protocol === \"https:\";\n }\n async requestJson(pathname, init) {\n if (!this.canReachApi()) {\n throw new Error(\"Eliza API not available\");\n }\n const response = await fetch(`${this.apiBase()}${pathname}`, {\n ...init,\n headers: {\n ...(init?.body ? { \"Content-Type\": \"application/json\" } : {}),\n ...this.authHeaders(),\n ...(init?.headers ?? {}),\n },\n });\n if (!response.ok) {\n throw new Error(`Request failed (${response.status})`);\n }\n return (await response.json());\n }\n async getStatus() {\n return await this.requestJson(\"/api/website-blocker\");\n }\n async startBlock(options) {\n const body = validateStartBlockOptions(options);\n return await this.requestJson(\"/api/website-blocker\", {\n method: \"PUT\",\n body: JSON.stringify(body),\n });\n }\n async stopBlock() {\n return await this.requestJson(\"/api/website-blocker\", {\n method: \"DELETE\",\n });\n }\n async checkPermissions() {\n const permission = await this.requestJson(\"/api/permissions/website-blocking\");\n return {\n status: permission.status,\n canRequest: permission.canRequest,\n canOpenSettings: permission.canOpenSettings ?? true,\n settingsTarget: permission.settingsTarget ?? \"runtime\",\n engine: permission.engine ?? \"hosts-file\",\n reason: permission.reason,\n };\n }\n async requestPermissions() {\n const permission = await this.requestJson(\"/api/permissions/website-blocking/request\", {\n method: \"POST\",\n });\n return {\n status: permission.status,\n canRequest: permission.canRequest,\n canOpenSettings: permission.canOpenSettings ?? true,\n settingsTarget: permission.settingsTarget ?? \"runtime\",\n engine: permission.engine ?? \"hosts-file\",\n reason: permission.reason,\n };\n }\n async openSettings() {\n if (!this.canReachApi()) {\n return {\n opened: false,\n target: \"runtime\",\n actualTarget: \"runtime\",\n reason: \"Eliza API not available.\",\n };\n }\n const result = await this.requestJson(\"/api/permissions/website-blocking/open-settings\", {\n method: \"POST\",\n });\n return {\n opened: result.opened ?? false,\n target: result.target ?? \"runtime\",\n actualTarget: result.actualTarget ?? result.target ?? \"runtime\",\n reason: result.reason ?? null,\n };\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":"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"}
@@ -130,7 +130,14 @@ public class ElizaWebsiteBlockerPlugin: CAPPlugin, CAPBridgedPlugin {
130
130
 
131
131
  @objc func openSettings(_ call: CAPPluginCall) {
132
132
  Task {
133
- call.resolve(["opened": await openSettingsInternal()])
133
+ let opened = await openSettingsInternal()
134
+ let reason: Any = opened ? NSNull() : "iOS declined to open Settings."
135
+ call.resolve([
136
+ "opened": opened,
137
+ "target": "contentBlocker",
138
+ "actualTarget": "contentBlocker",
139
+ "reason": reason,
140
+ ])
134
141
  }
135
142
  }
136
143
 
@@ -141,12 +148,18 @@ public class ElizaWebsiteBlockerPlugin: CAPPlugin, CAPBridgedPlugin {
141
148
  return [
142
149
  "status": "granted",
143
150
  "canRequest": false,
151
+ "canOpenSettings": true,
152
+ "settingsTarget": "contentBlocker",
153
+ "engine": "content-blocker",
144
154
  ]
145
155
  }
146
156
 
147
157
  return [
148
158
  "status": "not-determined",
149
159
  "canRequest": true,
160
+ "canOpenSettings": true,
161
+ "settingsTarget": "contentBlocker",
162
+ "engine": "content-blocker",
150
163
  "reason": disabledReason(
151
164
  configuredWebsites: WebsiteBlockerShared.loadState()?.websites ?? []
152
165
  ),
@@ -155,6 +168,9 @@ public class ElizaWebsiteBlockerPlugin: CAPPlugin, CAPBridgedPlugin {
155
168
  return [
156
169
  "status": "not-determined",
157
170
  "canRequest": true,
171
+ "canOpenSettings": true,
172
+ "settingsTarget": "contentBlocker",
173
+ "engine": "content-blocker",
158
174
  "reason": error.localizedDescription,
159
175
  ]
160
176
  }
@@ -167,17 +183,22 @@ public class ElizaWebsiteBlockerPlugin: CAPPlugin, CAPBridgedPlugin {
167
183
  let permissionStatus = permission["status"] as? String ?? "not-determined"
168
184
  let enabled = permissionStatus == "granted"
169
185
  let reason = permission["reason"] as? String
186
+ let active = enabled && !websites.isEmpty
170
187
  var status = statusPayload(
171
188
  storedState: storedState,
172
- active: enabled && !websites.isEmpty,
189
+ active: active,
173
190
  requiresElevation: !enabled
174
191
  )
192
+ status["status"] = active ? "active" : "inactive"
175
193
  status["hostsFilePath"] = NSNull()
176
194
  status["engine"] = "content-blocker"
177
195
  status["platform"] = "ios"
178
196
  status["supportsElevationPrompt"] = false
179
- status["elevationPromptMethod"] = enabled ? NSNull() : "system-settings"
197
+ status["elevationPromptMethod"] = enabled ? NSNull() as Any : "system-settings"
180
198
  status["permissionStatus"] = permissionStatus
199
+ status["canRequest"] = permission["canRequest"] as? Bool ?? false
200
+ status["canOpenSettings"] = permission["canOpenSettings"] as? Bool ?? true
201
+ status["settingsTarget"] = permission["settingsTarget"] ?? "contentBlocker"
181
202
  status["canRequestPermission"] = permission["canRequest"] as? Bool ?? false
182
203
  status["canOpenSystemSettings"] = true
183
204
  status["reason"] = nullable(reason)
@@ -197,6 +218,7 @@ public class ElizaWebsiteBlockerPlugin: CAPPlugin, CAPBridgedPlugin {
197
218
  let matchMode = storedState?.matchMode ?? WebsiteBlockerShared.exactMatchMode
198
219
 
199
220
  return [
221
+ "status": active ? "active" : "inactive",
200
222
  "available": true,
201
223
  "active": active,
202
224
  "endsAt": nullable(WebsiteBlockerShared.endsAtString(for: storedState)),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elizaos/capacitor-websiteblocker",
3
- "version": "2.0.0-beta.1",
3
+ "version": "2.0.3-beta.3",
4
4
  "description": "Blocks websites through the Eliza runtime on desktop/web, uses native Android VPN DNS enforcement, and manages a native Safari content blocker on iPhone and iPad.",
5
5
  "keywords": [
6
6
  "website-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
  },
@@ -29,9 +31,12 @@
29
31
  "dist"
30
32
  ],
31
33
  "scripts": {
32
- "build": "bun run clean && tsc && bun --bun rollup -c rollup.config.mjs",
33
- "clean": "node ../../../scripts/rm-path-recursive.mjs dist",
34
- "prepublishOnly": "bun run build"
34
+ "build": "node ../../packages/scripts/with-package-build-lock.mjs plugins/plugin-native-websiteblocker -- bun run build:unlocked",
35
+ "clean": "node ../../packages/scripts/rm-path-recursive.mjs dist",
36
+ "test": "vitest run",
37
+ "test:android:manual": "cd android && gradle test",
38
+ "prepublishOnly": "bun run build",
39
+ "build:unlocked": "bun run clean && tsc && bunx rollup -c rollup.config.mjs"
35
40
  },
36
41
  "author": "elizaOS",
37
42
  "license": "MIT",
@@ -50,11 +55,10 @@
50
55
  }
51
56
  },
52
57
  "devDependencies": {
53
- "@capacitor/cli": "^8.0.0",
54
58
  "@capacitor/core": "^8.3.1",
55
- "rimraf": "^6.0.0",
56
59
  "rollup": "^4.60.2",
57
- "typescript": "^6.0.3"
60
+ "typescript": "^6.0.3",
61
+ "vitest": "^4.0.0"
58
62
  },
59
63
  "peerDependencies": {
60
64
  "@capacitor/core": "^8.3.1"
@@ -74,5 +78,6 @@
74
78
  "ios": "Native Safari content blocker managed by the Eliza app with shared block state and Settings-based enablement",
75
79
  "android": "Native split-tunnel VPN DNS blocker with system-wide hostname blocking"
76
80
  }
77
- }
81
+ },
82
+ "gitHead": "f54b0f4eaed317d59fa7dbcdce20f4cdb0734420"
78
83
  }