@ai-matrx/vault 0.1.6 → 0.1.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/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.6
3
+ ## 0.1.7
4
4
  ### Unreleased
5
5
 
6
6
  - Host-held lock: `host.lock` (`VaultLock`: `locked`, `subscribe`, `unlock`, optional `lock` and
package/dist/index.cjs CHANGED
@@ -150,10 +150,10 @@ __export(src_exports, {
150
150
  inferFromUrl: () => inferFromUrl,
151
151
  locationFromParams: () => locationFromParams,
152
152
  locationToParams: () => locationToParams,
153
+ loginSiteOf: () => loginSiteOf,
153
154
  matchesQuery: () => matchesQuery,
154
155
  needsRecentSignIn: () => needsRecentSignIn,
155
156
  parseDefinitions: () => parseDefinitions,
156
- siteOf: () => siteOf,
157
157
  sortItems: () => sortItems
158
158
  });
159
159
  module.exports = __toCommonJS(src_exports);
@@ -678,12 +678,7 @@ function formatBytes(n) {
678
678
  if (n < 1024 * 1024) return `${(n / 1024).toFixed(n < 10 * 1024 ? 1 : 0)} KB`;
679
679
  return `${(n / 1024 / 1024).toFixed(1)} MB`;
680
680
  }
681
- function formatDate(iso, withTime = false) {
682
- if (!iso) return "";
683
- const d = new Date(iso);
684
- if (Number.isNaN(d.getTime())) return iso;
685
- return d.toLocaleString(void 0, withTime ? { year: "numeric", month: "short", day: "numeric", hour: "numeric", minute: "2-digit" } : { year: "numeric", month: "short", day: "numeric" });
686
- }
681
+ var DAY_FORMAT = { year: "numeric", month: "short", day: "numeric" };
687
682
 
688
683
  // src/FieldRows.tsx
689
684
  var import_jsx_runtime5 = require("react/jsx-runtime");
@@ -823,6 +818,9 @@ function CustomEditRow({ label, value, onLabel, onValue, secret, onRemove }) {
823
818
  );
824
819
  }
825
820
 
821
+ // src/activity/HistoryPanel.tsx
822
+ var import_format3 = require("@ai-matrx/kit/format");
823
+
826
824
  // src/activity/logic.ts
827
825
  var import_format = require("@ai-matrx/kit/format");
828
826
 
@@ -874,7 +872,7 @@ function matchesQuery(item, query) {
874
872
  return [item.name, item.definitionLabel, ...item.tags, ...item.loginUrls, ...item.custom.map((c) => `${c.label} ${c.value}`)].some((h) => h.toLowerCase().includes(q));
875
873
  }
876
874
  var isAuthenticatorStorage = (key) => key === "totp_seed" || key.startsWith("totp_") || key === "authenticator_last_time_step";
877
- function siteOf(item) {
875
+ function loginSiteOf(item) {
878
876
  const raw = item.loginUrls[0];
879
877
  if (!raw) return "";
880
878
  try {
@@ -888,7 +886,7 @@ function sortItems(items, sort) {
888
886
  const byName = (a, b) => a.name.localeCompare(b.name, void 0, { sensitivity: "base" });
889
887
  if (sort === "name") return out.sort(byName);
890
888
  if (sort === "website") return out.sort((a, b) => {
891
- const x = siteOf(a), y = siteOf(b);
889
+ const x = loginSiteOf(a), y = loginSiteOf(b);
892
890
  return x && y ? x.localeCompare(y) || byName(a, b) : x ? -1 : y ? 1 : byName(a, b);
893
891
  });
894
892
  if (sort === "updated") return out.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
@@ -1280,6 +1278,7 @@ var HistoryChangedError = class extends Error {
1280
1278
  var import_react6 = require("react");
1281
1279
  var import_controls3 = require("@ai-matrx/design-system/controls");
1282
1280
  var import_design_system6 = require("@ai-matrx/design-system");
1281
+ var import_format2 = require("@ai-matrx/kit/format");
1283
1282
  var import_jsx_runtime6 = require("react/jsx-runtime");
1284
1283
  var PAGE = 50;
1285
1284
  var MAX = 500;
@@ -1316,7 +1315,7 @@ function ActivityPanel({ item, port, onClose }) {
1316
1315
  day.entries.map((entry) => ({ entry, s: auditSentence(entry, item, me) })),
1317
1316
  (r) => `${r.s.what}|${r.s.who ?? ""}`
1318
1317
  ).map(({ row: { entry, s }, times }) => {
1319
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex min-h-9 items-center gap-1.5 px-3 text-sm sm:px-4", title: formatDate(entry.at, true), children: [
1318
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex min-h-9 items-center gap-1.5 px-3 text-sm sm:px-4", title: (0, import_format2.formatAbsoluteDate)(entry.at, void 0, ""), children: [
1320
1319
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: (0, import_design_system6.cn)("truncate", s.refused ? "text-destructive" : "text-foreground"), children: s.what }),
1321
1320
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "shrink-0 text-muted-foreground", children: [
1322
1321
  times > 1 ? ` \xB7 ${times} times` : "",
@@ -1401,7 +1400,7 @@ function HistoryPanel({ item, port, arg, onClose, onChanged }) {
1401
1400
  page && (page.captureStartedAt || page.incomplete) ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-wrap gap-x-3 gap-y-1 px-1 text-xs", children: [
1402
1401
  page.captureStartedAt ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "text-muted-foreground", children: [
1403
1402
  "Kept since ",
1404
- formatDate(page.captureStartedAt, true)
1403
+ (0, import_format3.formatAbsoluteDate)(page.captureStartedAt, void 0, "")
1405
1404
  ] }) : null,
1406
1405
  page.incomplete ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-warning", children: "Some changes could not be read" }) : null
1407
1406
  ] }) : null
@@ -1414,7 +1413,7 @@ function HistoryRow({ item, port, page, entry, label, onRestored, onConflict, on
1414
1413
  const secret = useTransientSecret();
1415
1414
  const copyValue2 = useCopy();
1416
1415
  const [busy, setBusy] = (0, import_react7.useState)(false);
1417
- const when = formatDate(entry.recordedAt, true);
1416
+ const when = (0, import_format3.formatAbsoluteDate)(entry.recordedAt, void 0, "");
1418
1417
  async function read() {
1419
1418
  if (secret.value !== null) return secret.value;
1420
1419
  setBusy(true);
@@ -1576,11 +1575,11 @@ function authenticatorName(current, parsed) {
1576
1575
  if (name && !PLACEHOLDER_NAMES.includes(name.toLowerCase())) return name;
1577
1576
  return parsed.issuer || parsed.account || name || "One-time password";
1578
1577
  }
1579
- function matchIssuerToSite(issuer, candidates, siteOf2) {
1578
+ function matchIssuerToSite(issuer, candidates, siteOf) {
1580
1579
  const key = (issuer ?? "").toLowerCase().replace(/[^a-z0-9]/g, "");
1581
1580
  if (key.length < 2) return null;
1582
1581
  for (const c of candidates) {
1583
- const host = siteOf2(c).toLowerCase();
1582
+ const host = siteOf(c).toLowerCase();
1584
1583
  if (!host) continue;
1585
1584
  const labels = host.split(".");
1586
1585
  if (labels.some((l) => l.replace(/[^a-z0-9]/g, "") === key)) return c;
@@ -2201,7 +2200,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
2201
2200
  const recognise = (p) => {
2202
2201
  if (!nameTouched) setName((n) => authenticatorName(n, p));
2203
2202
  if (!targetChosen) {
2204
- const match = matchIssuerToSite(p.issuer, candidates, siteOf);
2203
+ const match = matchIssuerToSite(p.issuer, candidates, loginSiteOf);
2205
2204
  setTarget(match ? match.id : NEW);
2206
2205
  }
2207
2206
  };
@@ -2279,7 +2278,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
2279
2278
  value: target,
2280
2279
  disabled: busy || created !== null,
2281
2280
  "aria-label": "Add to",
2282
- options: [{ value: NEW, label: "New login" }, ...candidates.map((c) => ({ value: c.id, label: siteOf(c) ? `${c.name} \xB7 ${siteOf(c)}` : c.name }))],
2281
+ options: [{ value: NEW, label: "New login" }, ...candidates.map((c) => ({ value: c.id, label: loginSiteOf(c) ? `${c.name} \xB7 ${loginSiteOf(c)}` : c.name }))],
2283
2282
  onValueChange: (v) => {
2284
2283
  setTarget(v);
2285
2284
  setTargetChosen(true);
@@ -2441,7 +2440,7 @@ function OtpListRow({ port, item, family, entry, onOpen, onRename, onChanged, on
2441
2440
  const Icon = definitionGlyph(item.definitionKey, family);
2442
2441
  const canManage = item.capabilities.canManage || item.capabilities.canEdit;
2443
2442
  if (a.removed) return null;
2444
- const sub = a.error ?? [entry?.account, siteOf(item) || entry?.issuer].filter((v, i, all) => Boolean(v) && all.indexOf(v) === i).join(" \xB7 ");
2443
+ const sub = a.error ?? [entry?.account, loginSiteOf(item) || entry?.issuer].filter((v, i, all) => Boolean(v) && all.indexOf(v) === i).join(" \xB7 ");
2445
2444
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "grid min-h-14 grid-cols-[2rem_minmax(0,1fr)_auto_auto] items-center gap-x-3 rounded-lg px-2 py-1.5 transition-colors hover:bg-accent/50", children: [
2446
2445
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", onClick: onOpen, "aria-label": `Open ${item.name}`, tabIndex: -1, className: (0, import_design_system9.cn)("flex size-8 items-center justify-center rounded-lg bg-muted", a.enabled ? "text-foreground" : "text-disabled-foreground"), children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Icon, { className: "size-4" }) }),
2447
2446
  /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { type: "button", onClick: onOpen, className: "flex min-w-0 flex-col items-start rounded-md text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: [
@@ -5207,7 +5206,7 @@ var MEMBER_ACCESS_LABEL = { none: "No access", use: "Can use", editor: "Can edit
5207
5206
  function levelOf(flags) {
5208
5207
  return flags.can_manage ? "edit" : "use";
5209
5208
  }
5210
- function flagsOf(level) {
5209
+ function shareFlagsOf(level) {
5211
5210
  return { can_use: true, can_manage: level === "edit" };
5212
5211
  }
5213
5212
  function isEmail(value) {
@@ -5621,6 +5620,7 @@ function SharingSummary({ item, port, className }) {
5621
5620
  }
5622
5621
 
5623
5622
  // src/ItemPane.tsx
5623
+ var import_format4 = require("@ai-matrx/kit/format");
5624
5624
  var import_jsx_runtime26 = require("react/jsx-runtime");
5625
5625
  var USERNAME_KEYS = /^(username|user_name|email|login|username_or_email|account_email)$/;
5626
5626
  function ItemPane(props) {
@@ -5768,7 +5768,7 @@ function ItemPane(props) {
5768
5768
  const descriptionVisible = showDescription || draft.description !== "";
5769
5769
  const header = /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("header", { className: "flex min-h-14 items-center gap-2 border-b border-border px-3 py-2 sm:gap-3 sm:px-5", children: [
5770
5770
  onBack ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_controls21.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ChevronLeftGlyph, {}), "aria-label": "Back", onClick: mode === "new" ? onCancelNew : onBack }) : null,
5771
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ItemIcon, { definitionKey: definition?.key ?? item?.definitionKey ?? "custom", family: definition?.family ?? "generic", site: item ? siteOf(item) : siteOf({ loginUrls: draft.loginUrls }), size: "lg" }),
5771
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ItemIcon, { definitionKey: definition?.key ?? item?.definitionKey ?? "custom", family: definition?.family ?? "generic", site: item ? loginSiteOf(item) : loginSiteOf({ loginUrls: draft.loginUrls }), size: "lg" }),
5772
5772
  /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex min-w-0 flex-1 flex-col", children: [
5773
5773
  /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("h2", { className: "truncate text-base font-semibold leading-tight", children: editing ? draft.name || (mode === "new" ? `New ${typeLabel.toLowerCase()}` : item?.name) : item?.name }),
5774
5774
  /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "flex min-w-0 items-center gap-1 text-xs text-muted-foreground", children: [
@@ -6001,9 +6001,9 @@ function ItemPane(props) {
6001
6001
  filesProps ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(FilesSection, { ...filesProps, editing: false }) : null,
6002
6002
  /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("p", { className: (0, import_design_system17.cn)("px-1 text-xs text-muted-foreground"), children: [
6003
6003
  "Modified ",
6004
- formatDate(item.updatedAt),
6004
+ (0, import_format4.formatAbsoluteDate)(item.updatedAt, DAY_FORMAT, ""),
6005
6005
  " \xB7 Created ",
6006
- formatDate(item.createdAt)
6006
+ (0, import_format4.formatAbsoluteDate)(item.createdAt, DAY_FORMAT, "")
6007
6007
  ] })
6008
6008
  ] }) : null }) })
6009
6009
  ] }) });
@@ -6018,7 +6018,7 @@ var SORTS2 = [
6018
6018
  { value: "created", label: "Recently added" }
6019
6019
  ];
6020
6020
  function subtitleOf(item, withOwner) {
6021
- const what = siteOf(item) || item.definitionLabel;
6021
+ const what = loginSiteOf(item) || item.definitionLabel;
6022
6022
  return withOwner ? `${what} \xB7 ${item.owner.label}` : what;
6023
6023
  }
6024
6024
  function ItemList({ title, items, definitions, port, selectedId, onSelect, query, onQuery, sort, onSort, onNew, matchingIds, header }) {
@@ -6101,7 +6101,7 @@ function ListRow({ item, family, port, on, onSelect, withOwner }) {
6101
6101
  onClick: () => onSelect(item.id),
6102
6102
  className: (0, import_design_system19.cn)("flex h-12 w-full items-center gap-3 rounded-lg px-2 text-left", on ? "bg-primary text-primary-foreground" : "hover:bg-accent"),
6103
6103
  children: [
6104
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ItemIcon, { definitionKey: item.definitionKey, family, site: siteOf(item), inverted: on }),
6104
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ItemIcon, { definitionKey: item.definitionKey, family, site: loginSiteOf(item), inverted: on }),
6105
6105
  /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: "flex min-w-0 flex-1 flex-col leading-tight", children: [
6106
6106
  /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "truncate text-sm font-medium", children: item.name }),
6107
6107
  /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "truncate text-xs text-muted-foreground", children: subtitleOf(item, withOwner) })
@@ -6119,6 +6119,7 @@ function ListRow({ item, family, port, on, onSelect, withOwner }) {
6119
6119
  // src/lists/TrashView.tsx
6120
6120
  var import_react30 = require("react");
6121
6121
  var import_controls24 = require("@ai-matrx/design-system/controls");
6122
+ var import_format5 = require("@ai-matrx/kit/format");
6122
6123
 
6123
6124
  // src/lists/logic.ts
6124
6125
  var ENTITY_TYPE = "credential_item";
@@ -6129,7 +6130,7 @@ function favoriteIds(data) {
6129
6130
  function recentIds(data, limit = 50) {
6130
6131
  return rowsOf(data).filter((r) => typeof r.last_viewed_at === "string" && r.last_viewed_at !== "").sort((a, b) => Date.parse(b.last_viewed_at) - Date.parse(a.last_viewed_at)).slice(0, limit).map((r) => r.entity_id);
6131
6132
  }
6132
- function matchesQuery2(item, query) {
6133
+ function trashItemMatchesQuery(item, query) {
6133
6134
  const q = query.trim().toLowerCase();
6134
6135
  if (!q) return true;
6135
6136
  return [item.name, item.definitionLabel, item.owner.label, ...item.tags].some((s) => s.toLowerCase().includes(q));
@@ -6261,7 +6262,7 @@ function TrashView({ port, deleted, query, header, onChanged }) {
6261
6262
  const confirmed = useConfirmed();
6262
6263
  const [busyId, setBusyId] = (0, import_react30.useState)(null);
6263
6264
  const [message2, setMessage] = (0, import_react30.useState)(null);
6264
- const shown = deleted.filter((i) => matchesQuery2(i, query));
6265
+ const shown = deleted.filter((i) => trashItemMatchesQuery(i, query));
6265
6266
  const [restoring, setRestoring] = (0, import_react30.useState)(null);
6266
6267
  const restore = async (item, deletionId) => {
6267
6268
  setBusyId(item.id);
@@ -6286,7 +6287,7 @@ function TrashView({ port, deleted, query, header, onChanged }) {
6286
6287
  /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex min-h-12 items-center gap-3 px-3 py-1.5 sm:px-4", children: [
6287
6288
  /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { className: "flex min-w-0 flex-1 flex-col leading-tight", children: [
6288
6289
  /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "truncate text-sm text-foreground", children: item.name }),
6289
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "truncate text-xs text-muted-foreground", children: [item.deletion?.deletedAt ? `Deleted ${formatDate(item.deletion.deletedAt)}` : null, item.owner.kind !== "me" ? item.owner.label : null].filter(Boolean).join(" \xB7 ") })
6290
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "truncate text-xs text-muted-foreground", children: [item.deletion?.deletedAt ? `Deleted ${(0, import_format5.formatAbsoluteDate)(item.deletion.deletedAt, DAY_FORMAT, "")}` : null, item.owner.kind !== "me" ? item.owner.label : null].filter(Boolean).join(" \xB7 ") })
6290
6291
  ] }),
6291
6292
  /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_controls24.Button, { variant: "outline", icon: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(RestoreGlyph, {}), disabled: busyId !== null || !item.deletion, onClick: () => setRestoring(item), children: "Restore" })
6292
6293
  ] }, item.id)
@@ -6373,9 +6374,10 @@ var import_react32 = require("react");
6373
6374
  var import_confirm_opener10 = require("@ai-matrx/kit/confirm-opener");
6374
6375
  var import_design_system21 = require("@ai-matrx/design-system");
6375
6376
  var import_controls26 = require("@ai-matrx/design-system/controls");
6377
+ var import_format7 = require("@ai-matrx/kit/format");
6376
6378
 
6377
6379
  // src/sharing/secure-link-logic.ts
6378
- var import_format2 = require("@ai-matrx/kit/format");
6380
+ var import_format6 = require("@ai-matrx/kit/format");
6379
6381
  var SECURE_RESOURCE_TYPE = "credential_item";
6380
6382
  var NOTE_MAX = 1e3;
6381
6383
  var CHANNEL_WORD = { email: "email", sms: "text" };
@@ -6413,7 +6415,7 @@ function carriedWords(keys, fields) {
6413
6415
  const known = new Map(fields.map((f) => [f.key, f.label]));
6414
6416
  return keys.map((k) => known.get(k) ?? fieldNames([k])).join(", ");
6415
6417
  }
6416
- var lifetimeWords = (minutes) => (0, import_format2.formatDurationMinutes)(minutes, { style: "long" });
6418
+ var lifetimeWords = (minutes) => (0, import_format6.formatDurationMinutes)(minutes, { style: "long" });
6417
6419
  function remedyOf(e) {
6418
6420
  const body = e?.serverDetail;
6419
6421
  if (!body || typeof body !== "object") return null;
@@ -6642,7 +6644,7 @@ function SecureLinkPanel({ item, port, onClose }) {
6642
6644
  );
6643
6645
  }
6644
6646
  function sentMeta(row, options) {
6645
- const when = row.status === "pending" ? `Until ${formatDate(row.expiresAt, true)}` : row.status === "viewed" && row.viewedAt ? formatDate(row.viewedAt, true) : formatDate(row.createdAt);
6647
+ const when = row.status === "pending" ? `Until ${(0, import_format7.formatAbsoluteDate)(row.expiresAt, void 0, "")}` : row.status === "viewed" && row.viewedAt ? (0, import_format7.formatAbsoluteDate)(row.viewedAt, void 0, "") : (0, import_format7.formatAbsoluteDate)(row.createdAt, DAY_FORMAT, "");
6646
6648
  const carried = row.fieldKeys.length ? carriedWords(row.fieldKeys, options?.fields ?? []) : "";
6647
6649
  return [when, carried].filter(Boolean).join(" \xB7 ");
6648
6650
  }
@@ -6651,6 +6653,7 @@ function sentMeta(row, options) {
6651
6653
  var import_react33 = require("react");
6652
6654
  var import_confirm_opener11 = require("@ai-matrx/kit/confirm-opener");
6653
6655
  var import_controls27 = require("@ai-matrx/design-system/controls");
6656
+ var import_format8 = require("@ai-matrx/kit/format");
6654
6657
 
6655
6658
  // src/devices/logic.ts
6656
6659
  var PASSKEY_RP_ID = "aimatrx.com";
@@ -6780,13 +6783,13 @@ function DevicesPanel({ port, onClose }) {
6780
6783
  Row,
6781
6784
  {
6782
6785
  label: off ? "Turned off" : "Can fill",
6783
- hint: off ? formatDate(device.revokedAt) : void 0,
6786
+ hint: off ? (0, import_format8.formatAbsoluteDate)(device.revokedAt, DAY_FORMAT, "") : void 0,
6784
6787
  actions: off ? null : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_controls27.Button, { variant: "outline", icon: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(PowerGlyph, {}), disabled: busyId !== null, onClick: () => void revoke(device), children: "Revoke" }),
6785
6788
  children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "flex min-w-0 flex-col", children: [
6786
6789
  /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: off ? "truncate text-muted-foreground" : "truncate text-foreground", children: device.label }),
6787
6790
  /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "truncate text-xs text-muted-foreground", children: [
6788
- device.lastUsedAt ? `Last used ${formatDate(device.lastUsedAt, true)}` : "Never used",
6789
- device.addedAt ? ` \xB7 added ${formatDate(device.addedAt)}` : ""
6791
+ device.lastUsedAt ? `Last used ${(0, import_format8.formatAbsoluteDate)(device.lastUsedAt, void 0, "")}` : "Never used",
6792
+ device.addedAt ? ` \xB7 added ${(0, import_format8.formatAbsoluteDate)(device.addedAt, DAY_FORMAT, "")}` : ""
6790
6793
  ] })
6791
6794
  ] })
6792
6795
  },
@@ -6880,7 +6883,7 @@ function ApprovePanel({ port, host, onClose, approvalKey, label, kind = "browser
6880
6883
  "Return to ",
6881
6884
  where,
6882
6885
  " by ",
6883
- formatDate(approvedUntil, true),
6886
+ (0, import_format8.formatAbsoluteDate)(approvedUntil, void 0, ""),
6884
6887
  "."
6885
6888
  ] }) }) : !passkeys ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(Empty, { children: [
6886
6889
  "Approve with your password in ",
@@ -7571,10 +7574,10 @@ function MatchRow({ itemId, item, tag, family, port, busy, running, onOpen, onFi
7571
7574
  setReading(false);
7572
7575
  }
7573
7576
  };
7574
- const subtitle = [item ? siteOf(item) || item.definitionLabel : "", tag].filter(Boolean).join(" \xB7 ");
7577
+ const subtitle = [item ? loginSiteOf(item) || item.definitionLabel : "", tag].filter(Boolean).join(" \xB7 ");
7575
7578
  return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("li", { className: "flex h-12 items-center gap-1 pl-1 pr-2", "data-item": itemId, children: [
7576
7579
  /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("button", { type: "button", onClick: () => onOpen(itemId), className: "flex h-11 min-w-0 flex-1 items-center gap-3 rounded-lg px-2 text-left hover:bg-accent", children: [
7577
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ItemIcon, { definitionKey: item?.definitionKey ?? "website_login", family, site: item ? siteOf(item) : "" }),
7580
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ItemIcon, { definitionKey: item?.definitionKey ?? "website_login", family, site: item ? loginSiteOf(item) : "" }),
7578
7581
  /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "flex min-w-0 flex-1 flex-col leading-tight", children: [
7579
7582
  /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "truncate text-sm font-medium", children: item?.name ?? "Saved login" }),
7580
7583
  subtitle ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "truncate text-xs text-muted-foreground", children: subtitle }) : null
@@ -8557,7 +8560,7 @@ function createSharingPort(ctx, options = {}) {
8557
8560
  return r.grants.map(grantOf);
8558
8561
  },
8559
8562
  async addPerson(item, email, level) {
8560
- const w = await account6.addGrant(api, { path: { item_id: item.id }, body: { recipient_email: email.trim(), ...flagsOf(level), initiation: "user" } }, ctx.optsFor(item));
8563
+ const w = await account6.addGrant(api, { path: { item_id: item.id }, body: { recipient_email: email.trim(), ...shareFlagsOf(level), initiation: "user" } }, ctx.optsFor(item));
8561
8564
  return grantOf(w);
8562
8565
  },
8563
8566
  async addOrganization(item, organizationId, level) {
@@ -8565,14 +8568,14 @@ function createSharingPort(ctx, options = {}) {
8565
8568
  return grantOf(w);
8566
8569
  },
8567
8570
  async setLevel(item, grant, level) {
8568
- const w = await account6.updateGrant(api, { path: { item_id: item.id, grant_id: grant.id }, body: { ...flagsOf(level), initiation: "user" } }, ctx.optsFor(item));
8571
+ const w = await account6.updateGrant(api, { path: { item_id: item.id, grant_id: grant.id }, body: { ...shareFlagsOf(level), initiation: "user" } }, ctx.optsFor(item));
8569
8572
  return grantOf(w);
8570
8573
  },
8571
8574
  async revoke(item, grant) {
8572
8575
  await account6.removeGrant(api, { path: { item_id: item.id, grant_id: grant.id } }, ctx.optsFor(item));
8573
8576
  },
8574
8577
  async setAccessMode(item, mode, people) {
8575
- const grantees = mode === "restricted" ? people.filter((g) => g.kind === "person" && g.userId).map((g) => ({ user_id: g.userId, ...flagsOf(g.level) })) : [];
8578
+ const grantees = mode === "restricted" ? people.filter((g) => g.kind === "person" && g.userId).map((g) => ({ user_id: g.userId, ...shareFlagsOf(g.level) })) : [];
8576
8579
  await account6.share(api, { path: { item_id: item.id }, body: { access_mode: mode, grantees, initiation: "user" } }, ctx.optsFor(item));
8577
8580
  return ctx.refetch(item.id, item.owner);
8578
8581
  },