@haex-space/vault-sdk 3.1.0 → 3.2.2

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.
Files changed (45) hide show
  1. package/dist/{client-C0DPNG62.d.mts → client-GeColu97.d.mts} +263 -2
  2. package/dist/{client-B_B6rLIw.d.ts → client-z1jTcuQE.d.ts} +263 -2
  3. package/dist/index.d.mts +76 -6
  4. package/dist/index.d.ts +76 -6
  5. package/dist/index.js +244 -47
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +241 -48
  8. package/dist/index.mjs.map +1 -1
  9. package/dist/node.d.mts +1 -1
  10. package/dist/node.d.ts +1 -1
  11. package/dist/nuxt.js +16 -6
  12. package/dist/nuxt.js.map +1 -1
  13. package/dist/nuxt.mjs +16 -6
  14. package/dist/nuxt.mjs.map +1 -1
  15. package/dist/react.d.mts +2 -2
  16. package/dist/react.d.ts +2 -2
  17. package/dist/react.js +237 -46
  18. package/dist/react.js.map +1 -1
  19. package/dist/react.mjs +237 -46
  20. package/dist/react.mjs.map +1 -1
  21. package/dist/runtime/nuxt.plugin.client.d.mts +2 -2
  22. package/dist/runtime/nuxt.plugin.client.d.ts +2 -2
  23. package/dist/runtime/nuxt.plugin.client.js +237 -50
  24. package/dist/runtime/nuxt.plugin.client.js.map +1 -1
  25. package/dist/runtime/nuxt.plugin.client.mjs +237 -50
  26. package/dist/runtime/nuxt.plugin.client.mjs.map +1 -1
  27. package/dist/svelte.d.mts +2 -2
  28. package/dist/svelte.d.ts +2 -2
  29. package/dist/svelte.js +237 -46
  30. package/dist/svelte.js.map +1 -1
  31. package/dist/svelte.mjs +237 -46
  32. package/dist/svelte.mjs.map +1 -1
  33. package/dist/{types-DmCSegdY.d.mts → types-CDMBvvjl.d.mts} +2 -0
  34. package/dist/{types-DmCSegdY.d.ts → types-CDMBvvjl.d.ts} +2 -0
  35. package/dist/vite.js +15 -5
  36. package/dist/vite.js.map +1 -1
  37. package/dist/vite.mjs +15 -5
  38. package/dist/vite.mjs.map +1 -1
  39. package/dist/vue.d.mts +2 -2
  40. package/dist/vue.d.ts +2 -2
  41. package/dist/vue.js +237 -46
  42. package/dist/vue.js.map +1 -1
  43. package/dist/vue.mjs +237 -46
  44. package/dist/vue.mjs.map +1 -1
  45. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1049,6 +1049,40 @@ var SHELL_COMMANDS = {
1049
1049
  close: "extension_shell_close"
1050
1050
  };
1051
1051
 
1052
+ // src/commands/passwords.ts
1053
+ var PASSWORD_COMMANDS = {
1054
+ /** List items (no secrets) within the extension's tag scope */
1055
+ list: "extension_password_list",
1056
+ /** Read full item including secrets, by id */
1057
+ read: "extension_password_read",
1058
+ /** Create item — must include >=1 tag in scope */
1059
+ create: "extension_password_create",
1060
+ /** Update item — keeps >=1 tag in scope */
1061
+ update: "extension_password_update",
1062
+ /** Delete item — must be in scope */
1063
+ delete: "extension_password_delete"
1064
+ };
1065
+
1066
+ // src/commands/mail.ts
1067
+ var MAIL_COMMANDS = {
1068
+ /** LIST mailboxes + optional STATUS counts */
1069
+ listMailboxes: "extension_mail_list_mailboxes",
1070
+ /** Lightweight envelope fetch for list views */
1071
+ fetchEnvelopes: "extension_mail_fetch_envelopes",
1072
+ /** Full message fetch (envelope + body + attachment metadata) */
1073
+ fetchMessage: "extension_mail_fetch_message",
1074
+ /** Set or unset IMAP flags on a UID set */
1075
+ setFlags: "extension_mail_set_flags",
1076
+ /** MOVE messages between mailboxes (COPY+EXPUNGE fallback) */
1077
+ moveMessages: "extension_mail_move_messages",
1078
+ /** APPEND a base64-encoded RFC822 message into a mailbox */
1079
+ appendMessage: "extension_mail_append_message",
1080
+ /** SMTP send. Returns the assigned Message-ID. */
1081
+ sendMessage: "extension_mail_send_message",
1082
+ /** Build RFC822 bytes without sending (for Drafts via APPEND) */
1083
+ buildRfc822: "extension_mail_build_rfc822"
1084
+ };
1085
+
1052
1086
  // src/commands/index.ts
1053
1087
  var TAURI_COMMANDS = {
1054
1088
  database: DATABASE_COMMANDS,
@@ -1061,7 +1095,9 @@ var TAURI_COMMANDS = {
1061
1095
  remoteStorage: REMOTE_STORAGE_COMMANDS,
1062
1096
  localsend: LOCALSEND_COMMANDS,
1063
1097
  spaces: SPACE_COMMANDS,
1064
- shell: SHELL_COMMANDS
1098
+ shell: SHELL_COMMANDS,
1099
+ passwords: PASSWORD_COMMANDS,
1100
+ mail: MAIL_COMMANDS
1065
1101
  };
1066
1102
 
1067
1103
  // src/api/storage.ts
@@ -1087,6 +1123,12 @@ var StorageAPI = class {
1087
1123
  };
1088
1124
 
1089
1125
  // src/api/database.ts
1126
+ function quoteIdent(identifier) {
1127
+ if (identifier.startsWith('"') && identifier.endsWith('"')) {
1128
+ return identifier;
1129
+ }
1130
+ return `"${identifier.replace(/"/g, '""')}"`;
1131
+ }
1090
1132
  var DatabaseAPI = class {
1091
1133
  constructor(client) {
1092
1134
  this.client = client;
@@ -1117,11 +1159,11 @@ var DatabaseAPI = class {
1117
1159
  });
1118
1160
  }
1119
1161
  async createTable(tableName, columns) {
1120
- const query = `CREATE TABLE IF NOT EXISTS ${tableName} (${columns})`;
1162
+ const query = `CREATE TABLE IF NOT EXISTS ${quoteIdent(tableName)} (${columns})`;
1121
1163
  await this.execute(query);
1122
1164
  }
1123
1165
  async dropTable(tableName) {
1124
- const query = `DROP TABLE IF EXISTS ${tableName}`;
1166
+ const query = `DROP TABLE IF EXISTS ${quoteIdent(tableName)}`;
1125
1167
  await this.execute(query);
1126
1168
  }
1127
1169
  /**
@@ -1150,18 +1192,17 @@ var DatabaseAPI = class {
1150
1192
  async insert(tableName, data) {
1151
1193
  const keys = Object.keys(data);
1152
1194
  const values = Object.values(data);
1195
+ const quotedCols = keys.map(quoteIdent).join(", ");
1153
1196
  const placeholders = keys.map(() => "?").join(", ");
1154
- const query = `INSERT INTO ${tableName} (${keys.join(
1155
- ", "
1156
- )}) VALUES (${placeholders})`;
1197
+ const query = `INSERT INTO ${quoteIdent(tableName)} (${quotedCols}) VALUES (${placeholders})`;
1157
1198
  const result = await this.execute(query, values);
1158
1199
  return result.lastInsertId ?? -1;
1159
1200
  }
1160
1201
  async update(tableName, data, where, whereParams) {
1161
1202
  const keys = Object.keys(data);
1162
1203
  const values = Object.values(data);
1163
- const setClause = keys.map((key) => `${key} = ?`).join(", ");
1164
- const query = `UPDATE ${tableName} SET ${setClause} WHERE ${where}`;
1204
+ const setClause = keys.map((key) => `${quoteIdent(key)} = ?`).join(", ");
1205
+ const query = `UPDATE ${quoteIdent(tableName)} SET ${setClause} WHERE ${where}`;
1165
1206
  const result = await this.execute(query, [
1166
1207
  ...values,
1167
1208
  ...whereParams || []
@@ -1169,12 +1210,12 @@ var DatabaseAPI = class {
1169
1210
  return result.rowsAffected;
1170
1211
  }
1171
1212
  async delete(tableName, where, whereParams) {
1172
- const query = `DELETE FROM ${tableName} WHERE ${where}`;
1213
+ const query = `DELETE FROM ${quoteIdent(tableName)} WHERE ${where}`;
1173
1214
  const result = await this.execute(query, whereParams);
1174
1215
  return result.rowsAffected;
1175
1216
  }
1176
1217
  async count(tableName, where, whereParams) {
1177
- const query = where ? `SELECT COUNT(*) as count FROM ${tableName} WHERE ${where}` : `SELECT COUNT(*) as count FROM ${tableName}`;
1218
+ const query = where ? `SELECT COUNT(*) as count FROM ${quoteIdent(tableName)} WHERE ${where}` : `SELECT COUNT(*) as count FROM ${quoteIdent(tableName)}`;
1178
1219
  const result = await this.queryOne(query, whereParams);
1179
1220
  return result?.count ?? 0;
1180
1221
  }
@@ -2005,6 +2046,140 @@ var ShellAPI = class {
2005
2046
  }
2006
2047
  };
2007
2048
 
2049
+ // src/api/passwords.ts
2050
+ var PasswordsAPI = class {
2051
+ constructor(client) {
2052
+ this.client = client;
2053
+ }
2054
+ /** List items in scope — summaries only, no secrets. */
2055
+ async listAsync() {
2056
+ return this.client.request(
2057
+ PASSWORD_COMMANDS.list,
2058
+ {}
2059
+ );
2060
+ }
2061
+ /** Read a single item by id with full secrets. */
2062
+ async readAsync(itemId) {
2063
+ return this.client.request(PASSWORD_COMMANDS.read, {
2064
+ itemId
2065
+ });
2066
+ }
2067
+ /**
2068
+ * Create a new password item. `input.tags` must contain at least one
2069
+ * tag within the extension's permission scope, otherwise the write
2070
+ * is rejected as a security violation.
2071
+ *
2072
+ * Returns the new item id.
2073
+ */
2074
+ async createAsync(input) {
2075
+ return this.client.request(PASSWORD_COMMANDS.create, { input });
2076
+ }
2077
+ /**
2078
+ * Update an existing item. The item must already be in scope, and
2079
+ * the new tag set must keep at least one tag in scope (extensions
2080
+ * cannot orphan an item out of their own reach).
2081
+ */
2082
+ async updateAsync(itemId, input) {
2083
+ return this.client.request(PASSWORD_COMMANDS.update, {
2084
+ itemId,
2085
+ input
2086
+ });
2087
+ }
2088
+ /** Delete an item by id. Item must be in scope. */
2089
+ async deleteAsync(itemId) {
2090
+ return this.client.request(PASSWORD_COMMANDS.delete, { itemId });
2091
+ }
2092
+ };
2093
+
2094
+ // src/api/mail.ts
2095
+ var MailAPI = class {
2096
+ constructor(client) {
2097
+ this.client = client;
2098
+ }
2099
+ /**
2100
+ * LIST mailboxes for an IMAP account. Pass `includeStatus=true` for
2101
+ * EXISTS/UNSEEN/UIDVALIDITY/UIDNEXT per box (one extra round-trip
2102
+ * per mailbox — fine for typical accounts, expensive for large
2103
+ * trees).
2104
+ */
2105
+ async listMailboxesAsync(imap, options = {}) {
2106
+ return this.client.request(MAIL_COMMANDS.listMailboxes, {
2107
+ imap,
2108
+ reference: options.reference,
2109
+ pattern: options.pattern,
2110
+ includeStatus: options.includeStatus
2111
+ });
2112
+ }
2113
+ /** Fetch lightweight envelopes for a mailbox + range (for list views). */
2114
+ async fetchEnvelopesAsync(imap, mailbox, range) {
2115
+ return this.client.request(
2116
+ MAIL_COMMANDS.fetchEnvelopes,
2117
+ { imap, mailbox, range }
2118
+ );
2119
+ }
2120
+ /** Fetch a full message (envelope + body + attachment metadata) by UID. */
2121
+ async fetchMessageAsync(imap, mailbox, uid) {
2122
+ return this.client.request(MAIL_COMMANDS.fetchMessage, {
2123
+ imap,
2124
+ mailbox,
2125
+ uid
2126
+ });
2127
+ }
2128
+ /**
2129
+ * Set or unset IMAP flags. Use `flags=["\\Seen"]` + `add=true` to
2130
+ * mark messages as read; `add=false` removes the flag(s).
2131
+ */
2132
+ async setFlagsAsync(imap, mailbox, uids, flags, add) {
2133
+ return this.client.request(MAIL_COMMANDS.setFlags, {
2134
+ imap,
2135
+ mailbox,
2136
+ uids,
2137
+ flags,
2138
+ add
2139
+ });
2140
+ }
2141
+ /** Move messages between mailboxes. Falls back to COPY+EXPUNGE on servers without MOVE. */
2142
+ async moveMessagesAsync(imap, sourceMailbox, destinationMailbox, uids) {
2143
+ return this.client.request(MAIL_COMMANDS.moveMessages, {
2144
+ imap,
2145
+ sourceMailbox,
2146
+ destinationMailbox,
2147
+ uids
2148
+ });
2149
+ }
2150
+ /**
2151
+ * APPEND a base64-encoded RFC822 message into a mailbox. Combine
2152
+ * with `buildRfc822Async` to save drafts, or with the bytes returned
2153
+ * after `sendMessageAsync` to mirror the sent copy into "Sent".
2154
+ */
2155
+ async appendMessageAsync(imap, mailbox, rfc822Base64, flags) {
2156
+ return this.client.request(MAIL_COMMANDS.appendMessage, {
2157
+ imap,
2158
+ mailbox,
2159
+ rfc822Base64,
2160
+ flags
2161
+ });
2162
+ }
2163
+ /** Send a message via SMTP. Returns the assigned Message-ID (no angle brackets). */
2164
+ async sendMessageAsync(smtp, message) {
2165
+ return this.client.request(MAIL_COMMANDS.sendMessage, {
2166
+ smtp,
2167
+ message
2168
+ });
2169
+ }
2170
+ /**
2171
+ * Build RFC822 bytes for a message without sending — useful for
2172
+ * drafts that get APPENDed to a "Drafts" folder. Permission-wise
2173
+ * this is a fetch operation (no SMTP host involved).
2174
+ */
2175
+ async buildRfc822Async(imapHost, message) {
2176
+ return this.client.request(MAIL_COMMANDS.buildRfc822, {
2177
+ imapHost,
2178
+ message
2179
+ });
2180
+ }
2181
+ };
2182
+
2008
2183
  // src/client/tableName.ts
2009
2184
  function validatePublicKey(publicKey) {
2010
2185
  if (!publicKey || typeof publicKey !== "string" || publicKey.trim() === "") {
@@ -2092,6 +2267,10 @@ function parseTableName(fullTableName) {
2092
2267
 
2093
2268
  // src/client/init.ts
2094
2269
  var PORT_HANDSHAKE_TIMEOUT_MS = 1e4;
2270
+ function getCurrentWebviewLabel() {
2271
+ const internals = window.__TAURI_INTERNALS__;
2272
+ return internals?.metadata?.currentWebview?.label;
2273
+ }
2095
2274
  function isInIframe() {
2096
2275
  return window.self !== window.top;
2097
2276
  }
@@ -2120,6 +2299,13 @@ async function initNativeMode(ctx, log, onEvent, onContextChange) {
2120
2299
  }
2121
2300
  async function setupTauriEventListeners(ctx, log, onEvent, onContextChange) {
2122
2301
  const { listen } = getTauriEvent();
2302
+ const webviewLabel = getCurrentWebviewLabel();
2303
+ const listenOptions = webviewLabel ? { target: webviewLabel } : void 0;
2304
+ if (!webviewLabel) {
2305
+ log(
2306
+ "WARNING: could not read __TAURI_INTERNALS__.metadata.currentWebview.label \u2014 registering listeners without a target. Label-scoped emits from the host will not be delivered until the metadata is available."
2307
+ );
2308
+ }
2123
2309
  log("Setting up Tauri event listener for:", HAEXTENSION_EVENTS.CONTEXT_CHANGED);
2124
2310
  try {
2125
2311
  await listen(HAEXTENSION_EVENTS.CONTEXT_CHANGED, (event) => {
@@ -2137,7 +2323,7 @@ async function setupTauriEventListeners(ctx, log, onEvent, onContextChange) {
2137
2323
  } else {
2138
2324
  log("Event received but no context in payload:", event);
2139
2325
  }
2140
- });
2326
+ }, listenOptions);
2141
2327
  log("Context change listener registered successfully");
2142
2328
  } catch (error) {
2143
2329
  log("Failed to setup context change listener:", error);
@@ -2155,7 +2341,7 @@ async function setupTauriEventListeners(ctx, log, onEvent, onContextChange) {
2155
2341
  } else {
2156
2342
  log("External request event has no payload!");
2157
2343
  }
2158
- });
2344
+ }, listenOptions);
2159
2345
  log("External request listener registered successfully");
2160
2346
  } catch (error) {
2161
2347
  log("Failed to setup external request listener:", error);
@@ -2173,7 +2359,7 @@ async function setupTauriEventListeners(ctx, log, onEvent, onContextChange) {
2173
2359
  } else {
2174
2360
  log("AI action request event has no payload!");
2175
2361
  }
2176
- });
2362
+ }, listenOptions);
2177
2363
  log("AI action request listener registered successfully");
2178
2364
  } catch (error) {
2179
2365
  log("Failed to setup AI action request listener:", error);
@@ -2192,7 +2378,7 @@ async function setupTauriEventListeners(ctx, log, onEvent, onContextChange) {
2192
2378
  timestamp: Date.now()
2193
2379
  });
2194
2380
  }
2195
- });
2381
+ }, listenOptions);
2196
2382
  log("File change listener registered successfully");
2197
2383
  } catch (error) {
2198
2384
  log("Failed to setup file change listener:", error);
@@ -2209,14 +2395,14 @@ async function setupTauriEventListeners(ctx, log, onEvent, onContextChange) {
2209
2395
  timestamp: Date.now()
2210
2396
  });
2211
2397
  }
2212
- });
2398
+ }, listenOptions);
2213
2399
  log("Sync tables updated listener registered successfully");
2214
2400
  } catch (error) {
2215
2401
  log("Failed to setup sync tables updated listener:", error);
2216
2402
  }
2217
2403
  log("Setting up LocalSend event listeners");
2218
2404
  try {
2219
- await setupLocalSendEventListeners(log, onEvent);
2405
+ await setupLocalSendEventListeners(log, onEvent, listenOptions);
2220
2406
  log("LocalSend event listeners setup complete");
2221
2407
  } catch (error) {
2222
2408
  log("Failed to setup LocalSend event listeners:", error);
@@ -2233,7 +2419,7 @@ async function setupTauriEventListeners(ctx, log, onEvent, onContextChange) {
2233
2419
  data: payload.data
2234
2420
  });
2235
2421
  }
2236
- });
2422
+ }, listenOptions);
2237
2423
  log("Shell output listener registered");
2238
2424
  await listen(SHELL_EVENTS.EXIT, (event) => {
2239
2425
  if (event.payload) {
@@ -2245,13 +2431,13 @@ async function setupTauriEventListeners(ctx, log, onEvent, onContextChange) {
2245
2431
  exitCode: payload.exitCode
2246
2432
  });
2247
2433
  }
2248
- });
2434
+ }, listenOptions);
2249
2435
  log("Shell exit listener registered");
2250
2436
  } catch (error) {
2251
2437
  log("Failed to setup Shell event listeners:", error);
2252
2438
  }
2253
2439
  }
2254
- async function setupLocalSendEventListeners(log, onEvent) {
2440
+ async function setupLocalSendEventListeners(log, onEvent, listenOptions) {
2255
2441
  const { listen } = getTauriEvent();
2256
2442
  try {
2257
2443
  await listen(LOCALSEND_EVENTS.deviceDiscovered, (event) => {
@@ -2263,7 +2449,7 @@ async function setupLocalSendEventListeners(log, onEvent) {
2263
2449
  timestamp: Date.now()
2264
2450
  });
2265
2451
  }
2266
- });
2452
+ }, listenOptions);
2267
2453
  log("LocalSend device discovered listener registered");
2268
2454
  } catch (error) {
2269
2455
  log("Failed to setup LocalSend device discovered listener:", error);
@@ -2278,7 +2464,7 @@ async function setupLocalSendEventListeners(log, onEvent) {
2278
2464
  timestamp: Date.now()
2279
2465
  });
2280
2466
  }
2281
- });
2467
+ }, listenOptions);
2282
2468
  log("LocalSend device lost listener registered");
2283
2469
  } catch (error) {
2284
2470
  log("Failed to setup LocalSend device lost listener:", error);
@@ -2293,7 +2479,7 @@ async function setupLocalSendEventListeners(log, onEvent) {
2293
2479
  timestamp: Date.now()
2294
2480
  });
2295
2481
  }
2296
- });
2482
+ }, listenOptions);
2297
2483
  log("LocalSend transfer request listener registered");
2298
2484
  } catch (error) {
2299
2485
  log("Failed to setup LocalSend transfer request listener:", error);
@@ -2308,7 +2494,7 @@ async function setupLocalSendEventListeners(log, onEvent) {
2308
2494
  timestamp: Date.now()
2309
2495
  });
2310
2496
  }
2311
- });
2497
+ }, listenOptions);
2312
2498
  log("LocalSend transfer progress listener registered");
2313
2499
  } catch (error) {
2314
2500
  log("Failed to setup LocalSend transfer progress listener:", error);
@@ -2323,7 +2509,7 @@ async function setupLocalSendEventListeners(log, onEvent) {
2323
2509
  timestamp: Date.now()
2324
2510
  });
2325
2511
  }
2326
- });
2512
+ }, listenOptions);
2327
2513
  log("LocalSend transfer complete listener registered");
2328
2514
  } catch (error) {
2329
2515
  log("Failed to setup LocalSend transfer complete listener:", error);
@@ -2338,13 +2524,13 @@ async function setupLocalSendEventListeners(log, onEvent) {
2338
2524
  timestamp: Date.now()
2339
2525
  });
2340
2526
  }
2341
- });
2527
+ }, listenOptions);
2342
2528
  log("LocalSend transfer failed listener registered");
2343
2529
  } catch (error) {
2344
2530
  log("Failed to setup LocalSend transfer failed listener:", error);
2345
2531
  }
2346
2532
  }
2347
- async function initIframeMode(ctx, log, messageHandler, request) {
2533
+ async function initIframeMode(ctx, log, messageHandler) {
2348
2534
  if (!isInIframe()) {
2349
2535
  throw new HaexVaultSdkError("NOT_IN_IFRAME" /* NOT_IN_IFRAME */, "errors.not_in_iframe");
2350
2536
  }
@@ -2361,15 +2547,12 @@ async function initIframeMode(ctx, log, messageHandler, request) {
2361
2547
  publicKey: ctx.config.manifest.publicKey,
2362
2548
  name: ctx.config.manifest.name,
2363
2549
  version: ctx.config.manifest.version,
2364
- displayName: ctx.config.manifest.name
2550
+ displayName: ctx.config.manifest.displayName ?? ctx.config.manifest.name
2365
2551
  };
2366
2552
  log("Extension info loaded from manifest:", ctx.state.extensionInfo);
2367
2553
  }
2368
2554
  sendDebugInfo(ctx.config);
2369
- const context = await request(EXTENSION_COMMANDS.getContext);
2370
- ctx.state.context = context;
2371
- log("Application context received:", context);
2372
- return { context, port };
2555
+ return port;
2373
2556
  }
2374
2557
  function waitForHostPortAsync(log) {
2375
2558
  return new Promise((resolve, reject) => {
@@ -2552,11 +2735,10 @@ function processEvent(event, log, eventListeners, onContextChanged, onExternalRe
2552
2735
  emitEvent(event, log, eventListeners);
2553
2736
  }
2554
2737
  function emitEvent(event, log, eventListeners) {
2555
- console.log("[HaexVault SDK] emitEvent called with:", event.type, event);
2556
- console.log("[HaexVault SDK] Registered event types:", Array.from(eventListeners.keys()));
2557
- log("Event received:", event);
2738
+ log("emitEvent called with:", event.type, event);
2739
+ log("Registered event types:", Array.from(eventListeners.keys()));
2558
2740
  const listeners = eventListeners.get(event.type);
2559
- console.log("[HaexVault SDK] Listeners for", event.type, ":", listeners?.size ?? 0);
2741
+ log("Listeners for", event.type, ":", listeners?.size ?? 0);
2560
2742
  if (listeners) {
2561
2743
  listeners.forEach((callback) => callback(event));
2562
2744
  }
@@ -2653,9 +2835,9 @@ function registerExternalHandler(action, handler, handlers, log) {
2653
2835
  };
2654
2836
  }
2655
2837
  async function handleExternalRequest(request, handlers, respond, log) {
2656
- console.log("[SDK Debug] handleExternalRequest called!");
2657
- console.log("[SDK Debug] Request:", JSON.stringify(request, null, 2));
2658
- console.log("[SDK Debug] Available handlers:", Array.from(handlers.keys()));
2838
+ log("handleExternalRequest called");
2839
+ log("Request:", request);
2840
+ log("Available handlers:", Array.from(handlers.keys()));
2659
2841
  log(`[ExternalRequest] Received request: ${request.action} from ${request.publicKey.substring(0, 20)}...`);
2660
2842
  const handler = handlers.get(request.action);
2661
2843
  if (!handler) {
@@ -2681,7 +2863,6 @@ async function handleExternalRequest(request, handlers, respond, log) {
2681
2863
  }
2682
2864
  }
2683
2865
  async function respondToExternalRequest(response, request) {
2684
- console.log("[SDK Debug] respondToExternalRequest called with:", JSON.stringify(response, null, 2));
2685
2866
  await request(EXTERNAL_BRIDGE_COMMANDS.respond, response);
2686
2867
  }
2687
2868
 
@@ -2739,11 +2920,17 @@ var HaexVaultSdk = class {
2739
2920
  this.localsend = new LocalSendAPI(this);
2740
2921
  this.spaces = new SpacesAPI(this);
2741
2922
  this.shell = new ShellAPI(this);
2923
+ this.passwords = new PasswordsAPI(this);
2924
+ this.mail = new MailAPI(this);
2742
2925
  installConsoleForwarding(this.config.debug);
2743
- this.readyPromise = new Promise((resolve) => {
2926
+ this.readyPromise = new Promise((resolve, reject) => {
2744
2927
  this.resolveReady = resolve;
2928
+ this.rejectReady = reject;
2929
+ });
2930
+ this.init().catch((error) => {
2931
+ this.log("Init failed:", error);
2932
+ this.rejectReady(error);
2745
2933
  });
2746
- this.init();
2747
2934
  }
2748
2935
  // ==========================================================================
2749
2936
  // Lifecycle
@@ -2771,9 +2958,14 @@ var HaexVaultSdk = class {
2771
2958
  return this.setupPromise;
2772
2959
  }
2773
2960
  destroy() {
2774
- if (this.messageHandler) {
2775
- window.removeEventListener("message", this.messageHandler);
2961
+ if (this.messageHandler && this.hostPort) {
2962
+ this.hostPort.removeEventListener("message", this.messageHandler);
2776
2963
  }
2964
+ if (this.hostPort) {
2965
+ this.hostPort.close();
2966
+ this.hostPort = null;
2967
+ }
2968
+ this.messageHandler = null;
2777
2969
  this.pendingRequests.forEach(({ timeout }) => clearTimeout(timeout));
2778
2970
  this.pendingRequests.clear();
2779
2971
  this.eventListeners.clear();
@@ -2963,7 +3155,7 @@ var HaexVaultSdk = class {
2963
3155
  () => this._extensionInfo,
2964
3156
  this.handleEvent.bind(this)
2965
3157
  );
2966
- const { context, port } = await initIframeMode(
3158
+ const port = await initIframeMode(
2967
3159
  {
2968
3160
  config: this.config,
2969
3161
  state: {
@@ -2992,8 +3184,7 @@ var HaexVaultSdk = class {
2992
3184
  }
2993
3185
  },
2994
3186
  this.log.bind(this),
2995
- this.messageHandler,
2996
- this.request.bind(this)
3187
+ this.messageHandler
2997
3188
  );
2998
3189
  this.hostPort = port;
2999
3190
  if (this.config.manifest) {
@@ -3001,10 +3192,12 @@ var HaexVaultSdk = class {
3001
3192
  publicKey: this.config.manifest.publicKey,
3002
3193
  name: this.config.manifest.name,
3003
3194
  version: this.config.manifest.version,
3004
- displayName: this.config.manifest.name
3195
+ displayName: this.config.manifest.displayName ?? this.config.manifest.name
3005
3196
  };
3006
3197
  this.notifySubscribersInternal();
3007
3198
  }
3199
+ const context = await this.request(EXTENSION_COMMANDS.getContext);
3200
+ this.log("Application context received:", context);
3008
3201
  this._context = context;
3009
3202
  this.isNativeWindow = false;
3010
3203
  this.initialized = true;
@@ -3671,6 +3864,10 @@ exports.HaexVaultSdkError = HaexVaultSdkError;
3671
3864
  exports.KnownPath = KnownPath;
3672
3865
  exports.LOCALSEND_EVENTS = LOCALSEND_EVENTS;
3673
3866
  exports.LocalSendAPI = LocalSendAPI;
3867
+ exports.MAIL_COMMANDS = MAIL_COMMANDS;
3868
+ exports.MailAPI = MailAPI;
3869
+ exports.PASSWORD_COMMANDS = PASSWORD_COMMANDS;
3870
+ exports.PasswordsAPI = PasswordsAPI;
3674
3871
  exports.PermissionErrorCode = PermissionErrorCode;
3675
3872
  exports.PermissionStatus = PermissionStatus;
3676
3873
  exports.PermissionsAPI = PermissionsAPI;