@haex-space/vault-sdk 3.1.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +212 -24
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +209 -25
  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 +205 -23
  18. package/dist/react.js.map +1 -1
  19. package/dist/react.mjs +205 -23
  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 +205 -27
  24. package/dist/runtime/nuxt.plugin.client.js.map +1 -1
  25. package/dist/runtime/nuxt.plugin.client.mjs +205 -27
  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 +205 -23
  30. package/dist/svelte.js.map +1 -1
  31. package/dist/svelte.mjs +205 -23
  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 +205 -23
  42. package/dist/vue.js.map +1 -1
  43. package/dist/vue.mjs +205 -23
  44. package/dist/vue.mjs.map +1 -1
  45. package/package.json +1 -1
@@ -265,6 +265,40 @@ var SHELL_COMMANDS = {
265
265
  close: "extension_shell_close"
266
266
  };
267
267
 
268
+ // src/commands/passwords.ts
269
+ var PASSWORD_COMMANDS = {
270
+ /** List items (no secrets) within the extension's tag scope */
271
+ list: "extension_password_list",
272
+ /** Read full item including secrets, by id */
273
+ read: "extension_password_read",
274
+ /** Create item — must include >=1 tag in scope */
275
+ create: "extension_password_create",
276
+ /** Update item — keeps >=1 tag in scope */
277
+ update: "extension_password_update",
278
+ /** Delete item — must be in scope */
279
+ delete: "extension_password_delete"
280
+ };
281
+
282
+ // src/commands/mail.ts
283
+ var MAIL_COMMANDS = {
284
+ /** LIST mailboxes + optional STATUS counts */
285
+ listMailboxes: "extension_mail_list_mailboxes",
286
+ /** Lightweight envelope fetch for list views */
287
+ fetchEnvelopes: "extension_mail_fetch_envelopes",
288
+ /** Full message fetch (envelope + body + attachment metadata) */
289
+ fetchMessage: "extension_mail_fetch_message",
290
+ /** Set or unset IMAP flags on a UID set */
291
+ setFlags: "extension_mail_set_flags",
292
+ /** MOVE messages between mailboxes (COPY+EXPUNGE fallback) */
293
+ moveMessages: "extension_mail_move_messages",
294
+ /** APPEND a base64-encoded RFC822 message into a mailbox */
295
+ appendMessage: "extension_mail_append_message",
296
+ /** SMTP send. Returns the assigned Message-ID. */
297
+ sendMessage: "extension_mail_send_message",
298
+ /** Build RFC822 bytes without sending (for Drafts via APPEND) */
299
+ buildRfc822: "extension_mail_build_rfc822"
300
+ };
301
+
268
302
  // src/api/storage.ts
269
303
  var StorageAPI = class {
270
304
  constructor(client) {
@@ -288,6 +322,12 @@ var StorageAPI = class {
288
322
  };
289
323
 
290
324
  // src/api/database.ts
325
+ function quoteIdent(identifier) {
326
+ if (identifier.startsWith('"') && identifier.endsWith('"')) {
327
+ return identifier;
328
+ }
329
+ return `"${identifier.replace(/"/g, '""')}"`;
330
+ }
291
331
  var DatabaseAPI = class {
292
332
  constructor(client) {
293
333
  this.client = client;
@@ -318,11 +358,11 @@ var DatabaseAPI = class {
318
358
  });
319
359
  }
320
360
  async createTable(tableName, columns) {
321
- const query = `CREATE TABLE IF NOT EXISTS ${tableName} (${columns})`;
361
+ const query = `CREATE TABLE IF NOT EXISTS ${quoteIdent(tableName)} (${columns})`;
322
362
  await this.execute(query);
323
363
  }
324
364
  async dropTable(tableName) {
325
- const query = `DROP TABLE IF EXISTS ${tableName}`;
365
+ const query = `DROP TABLE IF EXISTS ${quoteIdent(tableName)}`;
326
366
  await this.execute(query);
327
367
  }
328
368
  /**
@@ -351,18 +391,17 @@ var DatabaseAPI = class {
351
391
  async insert(tableName, data) {
352
392
  const keys = Object.keys(data);
353
393
  const values = Object.values(data);
394
+ const quotedCols = keys.map(quoteIdent).join(", ");
354
395
  const placeholders = keys.map(() => "?").join(", ");
355
- const query = `INSERT INTO ${tableName} (${keys.join(
356
- ", "
357
- )}) VALUES (${placeholders})`;
396
+ const query = `INSERT INTO ${quoteIdent(tableName)} (${quotedCols}) VALUES (${placeholders})`;
358
397
  const result = await this.execute(query, values);
359
398
  return result.lastInsertId ?? -1;
360
399
  }
361
400
  async update(tableName, data, where, whereParams) {
362
401
  const keys = Object.keys(data);
363
402
  const values = Object.values(data);
364
- const setClause = keys.map((key) => `${key} = ?`).join(", ");
365
- const query = `UPDATE ${tableName} SET ${setClause} WHERE ${where}`;
403
+ const setClause = keys.map((key) => `${quoteIdent(key)} = ?`).join(", ");
404
+ const query = `UPDATE ${quoteIdent(tableName)} SET ${setClause} WHERE ${where}`;
366
405
  const result = await this.execute(query, [
367
406
  ...values,
368
407
  ...whereParams || []
@@ -370,12 +409,12 @@ var DatabaseAPI = class {
370
409
  return result.rowsAffected;
371
410
  }
372
411
  async delete(tableName, where, whereParams) {
373
- const query = `DELETE FROM ${tableName} WHERE ${where}`;
412
+ const query = `DELETE FROM ${quoteIdent(tableName)} WHERE ${where}`;
374
413
  const result = await this.execute(query, whereParams);
375
414
  return result.rowsAffected;
376
415
  }
377
416
  async count(tableName, where, whereParams) {
378
- const query = where ? `SELECT COUNT(*) as count FROM ${tableName} WHERE ${where}` : `SELECT COUNT(*) as count FROM ${tableName}`;
417
+ const query = where ? `SELECT COUNT(*) as count FROM ${quoteIdent(tableName)} WHERE ${where}` : `SELECT COUNT(*) as count FROM ${quoteIdent(tableName)}`;
379
418
  const result = await this.queryOne(query, whereParams);
380
419
  return result?.count ?? 0;
381
420
  }
@@ -1222,6 +1261,140 @@ var ShellAPI = class {
1222
1261
  }
1223
1262
  };
1224
1263
 
1264
+ // src/api/passwords.ts
1265
+ var PasswordsAPI = class {
1266
+ constructor(client) {
1267
+ this.client = client;
1268
+ }
1269
+ /** List items in scope — summaries only, no secrets. */
1270
+ async listAsync() {
1271
+ return this.client.request(
1272
+ PASSWORD_COMMANDS.list,
1273
+ {}
1274
+ );
1275
+ }
1276
+ /** Read a single item by id with full secrets. */
1277
+ async readAsync(itemId) {
1278
+ return this.client.request(PASSWORD_COMMANDS.read, {
1279
+ itemId
1280
+ });
1281
+ }
1282
+ /**
1283
+ * Create a new password item. `input.tags` must contain at least one
1284
+ * tag within the extension's permission scope, otherwise the write
1285
+ * is rejected as a security violation.
1286
+ *
1287
+ * Returns the new item id.
1288
+ */
1289
+ async createAsync(input) {
1290
+ return this.client.request(PASSWORD_COMMANDS.create, { input });
1291
+ }
1292
+ /**
1293
+ * Update an existing item. The item must already be in scope, and
1294
+ * the new tag set must keep at least one tag in scope (extensions
1295
+ * cannot orphan an item out of their own reach).
1296
+ */
1297
+ async updateAsync(itemId, input) {
1298
+ return this.client.request(PASSWORD_COMMANDS.update, {
1299
+ itemId,
1300
+ input
1301
+ });
1302
+ }
1303
+ /** Delete an item by id. Item must be in scope. */
1304
+ async deleteAsync(itemId) {
1305
+ return this.client.request(PASSWORD_COMMANDS.delete, { itemId });
1306
+ }
1307
+ };
1308
+
1309
+ // src/api/mail.ts
1310
+ var MailAPI = class {
1311
+ constructor(client) {
1312
+ this.client = client;
1313
+ }
1314
+ /**
1315
+ * LIST mailboxes for an IMAP account. Pass `includeStatus=true` for
1316
+ * EXISTS/UNSEEN/UIDVALIDITY/UIDNEXT per box (one extra round-trip
1317
+ * per mailbox — fine for typical accounts, expensive for large
1318
+ * trees).
1319
+ */
1320
+ async listMailboxesAsync(imap, options = {}) {
1321
+ return this.client.request(MAIL_COMMANDS.listMailboxes, {
1322
+ imap,
1323
+ reference: options.reference,
1324
+ pattern: options.pattern,
1325
+ includeStatus: options.includeStatus
1326
+ });
1327
+ }
1328
+ /** Fetch lightweight envelopes for a mailbox + range (for list views). */
1329
+ async fetchEnvelopesAsync(imap, mailbox, range) {
1330
+ return this.client.request(
1331
+ MAIL_COMMANDS.fetchEnvelopes,
1332
+ { imap, mailbox, range }
1333
+ );
1334
+ }
1335
+ /** Fetch a full message (envelope + body + attachment metadata) by UID. */
1336
+ async fetchMessageAsync(imap, mailbox, uid) {
1337
+ return this.client.request(MAIL_COMMANDS.fetchMessage, {
1338
+ imap,
1339
+ mailbox,
1340
+ uid
1341
+ });
1342
+ }
1343
+ /**
1344
+ * Set or unset IMAP flags. Use `flags=["\\Seen"]` + `add=true` to
1345
+ * mark messages as read; `add=false` removes the flag(s).
1346
+ */
1347
+ async setFlagsAsync(imap, mailbox, uids, flags, add) {
1348
+ return this.client.request(MAIL_COMMANDS.setFlags, {
1349
+ imap,
1350
+ mailbox,
1351
+ uids,
1352
+ flags,
1353
+ add
1354
+ });
1355
+ }
1356
+ /** Move messages between mailboxes. Falls back to COPY+EXPUNGE on servers without MOVE. */
1357
+ async moveMessagesAsync(imap, sourceMailbox, destinationMailbox, uids) {
1358
+ return this.client.request(MAIL_COMMANDS.moveMessages, {
1359
+ imap,
1360
+ sourceMailbox,
1361
+ destinationMailbox,
1362
+ uids
1363
+ });
1364
+ }
1365
+ /**
1366
+ * APPEND a base64-encoded RFC822 message into a mailbox. Combine
1367
+ * with `buildRfc822Async` to save drafts, or with the bytes returned
1368
+ * after `sendMessageAsync` to mirror the sent copy into "Sent".
1369
+ */
1370
+ async appendMessageAsync(imap, mailbox, rfc822Base64, flags) {
1371
+ return this.client.request(MAIL_COMMANDS.appendMessage, {
1372
+ imap,
1373
+ mailbox,
1374
+ rfc822Base64,
1375
+ flags
1376
+ });
1377
+ }
1378
+ /** Send a message via SMTP. Returns the assigned Message-ID (no angle brackets). */
1379
+ async sendMessageAsync(smtp, message) {
1380
+ return this.client.request(MAIL_COMMANDS.sendMessage, {
1381
+ smtp,
1382
+ message
1383
+ });
1384
+ }
1385
+ /**
1386
+ * Build RFC822 bytes for a message without sending — useful for
1387
+ * drafts that get APPENDed to a "Drafts" folder. Permission-wise
1388
+ * this is a fetch operation (no SMTP host involved).
1389
+ */
1390
+ async buildRfc822Async(imapHost, message) {
1391
+ return this.client.request(MAIL_COMMANDS.buildRfc822, {
1392
+ imapHost,
1393
+ message
1394
+ });
1395
+ }
1396
+ };
1397
+
1225
1398
  // src/messages.ts
1226
1399
  var HAEXSPACE_MESSAGE_TYPES = {
1227
1400
  /** Debug message for development/troubleshooting */
@@ -1669,7 +1842,7 @@ async function initIframeMode(ctx, log, messageHandler, request) {
1669
1842
  publicKey: ctx.config.manifest.publicKey,
1670
1843
  name: ctx.config.manifest.name,
1671
1844
  version: ctx.config.manifest.version,
1672
- displayName: ctx.config.manifest.name
1845
+ displayName: ctx.config.manifest.displayName ?? ctx.config.manifest.name
1673
1846
  };
1674
1847
  log("Extension info loaded from manifest:", ctx.state.extensionInfo);
1675
1848
  }
@@ -1860,11 +2033,10 @@ function processEvent(event, log, eventListeners, onContextChanged, onExternalRe
1860
2033
  emitEvent(event, log, eventListeners);
1861
2034
  }
1862
2035
  function emitEvent(event, log, eventListeners) {
1863
- console.log("[HaexVault SDK] emitEvent called with:", event.type, event);
1864
- console.log("[HaexVault SDK] Registered event types:", Array.from(eventListeners.keys()));
1865
- log("Event received:", event);
2036
+ log("emitEvent called with:", event.type, event);
2037
+ log("Registered event types:", Array.from(eventListeners.keys()));
1866
2038
  const listeners = eventListeners.get(event.type);
1867
- console.log("[HaexVault SDK] Listeners for", event.type, ":", listeners?.size ?? 0);
2039
+ log("Listeners for", event.type, ":", listeners?.size ?? 0);
1868
2040
  if (listeners) {
1869
2041
  listeners.forEach((callback) => callback(event));
1870
2042
  }
@@ -1961,9 +2133,9 @@ function registerExternalHandler(action, handler, handlers, log) {
1961
2133
  };
1962
2134
  }
1963
2135
  async function handleExternalRequest(request, handlers, respond, log) {
1964
- console.log("[SDK Debug] handleExternalRequest called!");
1965
- console.log("[SDK Debug] Request:", JSON.stringify(request, null, 2));
1966
- console.log("[SDK Debug] Available handlers:", Array.from(handlers.keys()));
2136
+ log("handleExternalRequest called");
2137
+ log("Request:", request);
2138
+ log("Available handlers:", Array.from(handlers.keys()));
1967
2139
  log(`[ExternalRequest] Received request: ${request.action} from ${request.publicKey.substring(0, 20)}...`);
1968
2140
  const handler = handlers.get(request.action);
1969
2141
  if (!handler) {
@@ -1989,7 +2161,6 @@ async function handleExternalRequest(request, handlers, respond, log) {
1989
2161
  }
1990
2162
  }
1991
2163
  async function respondToExternalRequest(response, request) {
1992
- console.log("[SDK Debug] respondToExternalRequest called with:", JSON.stringify(response, null, 2));
1993
2164
  await request(EXTERNAL_BRIDGE_COMMANDS.respond, response);
1994
2165
  }
1995
2166
 
@@ -2047,11 +2218,17 @@ var HaexVaultSdk = class {
2047
2218
  this.localsend = new LocalSendAPI(this);
2048
2219
  this.spaces = new SpacesAPI(this);
2049
2220
  this.shell = new ShellAPI(this);
2221
+ this.passwords = new PasswordsAPI(this);
2222
+ this.mail = new MailAPI(this);
2050
2223
  installConsoleForwarding(this.config.debug);
2051
- this.readyPromise = new Promise((resolve) => {
2224
+ this.readyPromise = new Promise((resolve, reject) => {
2052
2225
  this.resolveReady = resolve;
2226
+ this.rejectReady = reject;
2227
+ });
2228
+ this.init().catch((error) => {
2229
+ this.log("Init failed:", error);
2230
+ this.rejectReady(error);
2053
2231
  });
2054
- this.init();
2055
2232
  }
2056
2233
  // ==========================================================================
2057
2234
  // Lifecycle
@@ -2079,9 +2256,14 @@ var HaexVaultSdk = class {
2079
2256
  return this.setupPromise;
2080
2257
  }
2081
2258
  destroy() {
2082
- if (this.messageHandler) {
2083
- window.removeEventListener("message", this.messageHandler);
2259
+ if (this.messageHandler && this.hostPort) {
2260
+ this.hostPort.removeEventListener("message", this.messageHandler);
2261
+ }
2262
+ if (this.hostPort) {
2263
+ this.hostPort.close();
2264
+ this.hostPort = null;
2084
2265
  }
2266
+ this.messageHandler = null;
2085
2267
  this.pendingRequests.forEach(({ timeout }) => clearTimeout(timeout));
2086
2268
  this.pendingRequests.clear();
2087
2269
  this.eventListeners.clear();
@@ -2309,7 +2491,7 @@ var HaexVaultSdk = class {
2309
2491
  publicKey: this.config.manifest.publicKey,
2310
2492
  name: this.config.manifest.name,
2311
2493
  version: this.config.manifest.version,
2312
- displayName: this.config.manifest.name
2494
+ displayName: this.config.manifest.displayName ?? this.config.manifest.name
2313
2495
  };
2314
2496
  this.notifySubscribersInternal();
2315
2497
  }
@@ -2391,22 +2573,18 @@ var nuxt_plugin_client_default = defineNuxtPlugin(async (nuxtApp) => {
2391
2573
  context: client.context
2392
2574
  });
2393
2575
  await client.ready();
2394
- console.log("[Nuxt Plugin] Client ready, context:", client.context);
2395
2576
  state.value = {
2396
2577
  isReady: true,
2397
2578
  isSetupComplete: false,
2398
2579
  context: client.context
2399
2580
  };
2400
- console.log("[Nuxt Plugin] Initial state set:", state.value);
2401
2581
  client.subscribe(() => {
2402
- console.log("[Nuxt Plugin] Client context updated:", client.context);
2403
2582
  const isSetupComplete = client.setupCompleted;
2404
2583
  state.value = {
2405
2584
  ...state.value,
2406
2585
  context: client.context,
2407
2586
  isSetupComplete
2408
2587
  };
2409
- console.log("[Nuxt Plugin] State updated:", state.value);
2410
2588
  });
2411
2589
  const haexVaultPlugin = {
2412
2590
  client,