@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 +1 -1
- package/dist/index.cjs +41 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +39 -36
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.cts
CHANGED
|
@@ -122,7 +122,7 @@ declare function locationToParams(loc: VaultLocation): URLSearchParams;
|
|
|
122
122
|
/** The one search every list shares: name, type, tags, URLs, then plaintext custom fields. */
|
|
123
123
|
declare function matchesQuery(item: VaultItem, query: string): boolean;
|
|
124
124
|
/** An item's website as people read it: `github.com` (no scheme, no `www.`), or "" when it has none. */
|
|
125
|
-
declare function
|
|
125
|
+
declare function loginSiteOf(item: Pick<VaultItem, "loginUrls">): string;
|
|
126
126
|
declare function sortItems(items: readonly VaultItem[], sort: VaultSort): VaultItem[];
|
|
127
127
|
interface NewSecretField {
|
|
128
128
|
key: string;
|
|
@@ -1240,4 +1240,4 @@ declare function GenerateButton({ onUse, label, limits, disabled }: {
|
|
|
1240
1240
|
disabled?: boolean;
|
|
1241
1241
|
}): react.JSX.Element | null;
|
|
1242
1242
|
|
|
1243
|
-
export { type ApiVaultPortOptions, CATEGORIES, type CategoryId, type CopyOptions, DEFAULT_LOCATION, type DefinitionField, type FieldHandling, type FieldKind, GenerateButton, type IdentityAccount, type IdentityMethod, type ItemDraft, LOCKED_MESSAGE, type NoticeKind, type Notify, type SaveResult, type SupabaseAuthLike, type TotpReading, type UriMatchMode, type UrlGuess, VaultApp, type VaultAppProps, type VaultAttachment, type VaultAuthenticator, type VaultClipboard, type VaultCustomField, type VaultDefinition, type VaultField, type VaultHostCapabilities, type VaultIdentity, type VaultItem, type VaultItemCapabilities, type VaultKnobs, type VaultLayout, type VaultLocation, type VaultLock, VaultLockedError, type VaultOrganizationRef, type VaultOwner, type VaultPort, type VaultSelection, type VaultSnapshot, type VaultSort, type VaultUserStateDoor, categoryOf, copyValue, createApiVaultPort, createSupabaseIdentity, createVaultKnobs, guardPort, inferFromUrl, locationFromParams, locationToParams, matchesQuery, needsRecentSignIn, parseDefinitions,
|
|
1243
|
+
export { type ApiVaultPortOptions, CATEGORIES, type CategoryId, type CopyOptions, DEFAULT_LOCATION, type DefinitionField, type FieldHandling, type FieldKind, GenerateButton, type IdentityAccount, type IdentityMethod, type ItemDraft, LOCKED_MESSAGE, type NoticeKind, type Notify, type SaveResult, type SupabaseAuthLike, type TotpReading, type UriMatchMode, type UrlGuess, VaultApp, type VaultAppProps, type VaultAttachment, type VaultAuthenticator, type VaultClipboard, type VaultCustomField, type VaultDefinition, type VaultField, type VaultHostCapabilities, type VaultIdentity, type VaultItem, type VaultItemCapabilities, type VaultKnobs, type VaultLayout, type VaultLocation, type VaultLock, VaultLockedError, type VaultOrganizationRef, type VaultOwner, type VaultPort, type VaultSelection, type VaultSnapshot, type VaultSort, type VaultUserStateDoor, categoryOf, copyValue, createApiVaultPort, createSupabaseIdentity, createVaultKnobs, guardPort, inferFromUrl, locationFromParams, locationToParams, loginSiteOf, matchesQuery, needsRecentSignIn, parseDefinitions, sortItems };
|
package/dist/index.d.ts
CHANGED
|
@@ -122,7 +122,7 @@ declare function locationToParams(loc: VaultLocation): URLSearchParams;
|
|
|
122
122
|
/** The one search every list shares: name, type, tags, URLs, then plaintext custom fields. */
|
|
123
123
|
declare function matchesQuery(item: VaultItem, query: string): boolean;
|
|
124
124
|
/** An item's website as people read it: `github.com` (no scheme, no `www.`), or "" when it has none. */
|
|
125
|
-
declare function
|
|
125
|
+
declare function loginSiteOf(item: Pick<VaultItem, "loginUrls">): string;
|
|
126
126
|
declare function sortItems(items: readonly VaultItem[], sort: VaultSort): VaultItem[];
|
|
127
127
|
interface NewSecretField {
|
|
128
128
|
key: string;
|
|
@@ -1240,4 +1240,4 @@ declare function GenerateButton({ onUse, label, limits, disabled }: {
|
|
|
1240
1240
|
disabled?: boolean;
|
|
1241
1241
|
}): react.JSX.Element | null;
|
|
1242
1242
|
|
|
1243
|
-
export { type ApiVaultPortOptions, CATEGORIES, type CategoryId, type CopyOptions, DEFAULT_LOCATION, type DefinitionField, type FieldHandling, type FieldKind, GenerateButton, type IdentityAccount, type IdentityMethod, type ItemDraft, LOCKED_MESSAGE, type NoticeKind, type Notify, type SaveResult, type SupabaseAuthLike, type TotpReading, type UriMatchMode, type UrlGuess, VaultApp, type VaultAppProps, type VaultAttachment, type VaultAuthenticator, type VaultClipboard, type VaultCustomField, type VaultDefinition, type VaultField, type VaultHostCapabilities, type VaultIdentity, type VaultItem, type VaultItemCapabilities, type VaultKnobs, type VaultLayout, type VaultLocation, type VaultLock, VaultLockedError, type VaultOrganizationRef, type VaultOwner, type VaultPort, type VaultSelection, type VaultSnapshot, type VaultSort, type VaultUserStateDoor, categoryOf, copyValue, createApiVaultPort, createSupabaseIdentity, createVaultKnobs, guardPort, inferFromUrl, locationFromParams, locationToParams, matchesQuery, needsRecentSignIn, parseDefinitions,
|
|
1243
|
+
export { type ApiVaultPortOptions, CATEGORIES, type CategoryId, type CopyOptions, DEFAULT_LOCATION, type DefinitionField, type FieldHandling, type FieldKind, GenerateButton, type IdentityAccount, type IdentityMethod, type ItemDraft, LOCKED_MESSAGE, type NoticeKind, type Notify, type SaveResult, type SupabaseAuthLike, type TotpReading, type UriMatchMode, type UrlGuess, VaultApp, type VaultAppProps, type VaultAttachment, type VaultAuthenticator, type VaultClipboard, type VaultCustomField, type VaultDefinition, type VaultField, type VaultHostCapabilities, type VaultIdentity, type VaultItem, type VaultItemCapabilities, type VaultKnobs, type VaultLayout, type VaultLocation, type VaultLock, VaultLockedError, type VaultOrganizationRef, type VaultOwner, type VaultPort, type VaultSelection, type VaultSnapshot, type VaultSort, type VaultUserStateDoor, categoryOf, copyValue, createApiVaultPort, createSupabaseIdentity, createVaultKnobs, guardPort, inferFromUrl, locationFromParams, locationToParams, loginSiteOf, matchesQuery, needsRecentSignIn, parseDefinitions, sortItems };
|
package/dist/index.js
CHANGED
|
@@ -620,12 +620,7 @@ function formatBytes(n) {
|
|
|
620
620
|
if (n < 1024 * 1024) return `${(n / 1024).toFixed(n < 10 * 1024 ? 1 : 0)} KB`;
|
|
621
621
|
return `${(n / 1024 / 1024).toFixed(1)} MB`;
|
|
622
622
|
}
|
|
623
|
-
|
|
624
|
-
if (!iso) return "";
|
|
625
|
-
const d = new Date(iso);
|
|
626
|
-
if (Number.isNaN(d.getTime())) return iso;
|
|
627
|
-
return d.toLocaleString(void 0, withTime ? { year: "numeric", month: "short", day: "numeric", hour: "numeric", minute: "2-digit" } : { year: "numeric", month: "short", day: "numeric" });
|
|
628
|
-
}
|
|
623
|
+
var DAY_FORMAT = { year: "numeric", month: "short", day: "numeric" };
|
|
629
624
|
|
|
630
625
|
// src/FieldRows.tsx
|
|
631
626
|
import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
@@ -765,6 +760,9 @@ function CustomEditRow({ label, value, onLabel, onValue, secret, onRemove }) {
|
|
|
765
760
|
);
|
|
766
761
|
}
|
|
767
762
|
|
|
763
|
+
// src/activity/HistoryPanel.tsx
|
|
764
|
+
import { formatAbsoluteDate as formatAbsoluteDate2 } from "@ai-matrx/kit/format";
|
|
765
|
+
|
|
768
766
|
// src/activity/logic.ts
|
|
769
767
|
import { formatRelativeTime } from "@ai-matrx/kit/format";
|
|
770
768
|
|
|
@@ -816,7 +814,7 @@ function matchesQuery(item, query) {
|
|
|
816
814
|
return [item.name, item.definitionLabel, ...item.tags, ...item.loginUrls, ...item.custom.map((c) => `${c.label} ${c.value}`)].some((h) => h.toLowerCase().includes(q));
|
|
817
815
|
}
|
|
818
816
|
var isAuthenticatorStorage = (key) => key === "totp_seed" || key.startsWith("totp_") || key === "authenticator_last_time_step";
|
|
819
|
-
function
|
|
817
|
+
function loginSiteOf(item) {
|
|
820
818
|
const raw = item.loginUrls[0];
|
|
821
819
|
if (!raw) return "";
|
|
822
820
|
try {
|
|
@@ -830,7 +828,7 @@ function sortItems(items, sort) {
|
|
|
830
828
|
const byName = (a, b) => a.name.localeCompare(b.name, void 0, { sensitivity: "base" });
|
|
831
829
|
if (sort === "name") return out.sort(byName);
|
|
832
830
|
if (sort === "website") return out.sort((a, b) => {
|
|
833
|
-
const x =
|
|
831
|
+
const x = loginSiteOf(a), y = loginSiteOf(b);
|
|
834
832
|
return x && y ? x.localeCompare(y) || byName(a, b) : x ? -1 : y ? 1 : byName(a, b);
|
|
835
833
|
});
|
|
836
834
|
if (sort === "updated") return out.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
@@ -1222,6 +1220,7 @@ var HistoryChangedError = class extends Error {
|
|
|
1222
1220
|
import { useEffect as useEffect6, useRef as useRef4, useState as useState6 } from "react";
|
|
1223
1221
|
import { Button as Button3 } from "@ai-matrx/design-system/controls";
|
|
1224
1222
|
import { cn as cn4 } from "@ai-matrx/design-system";
|
|
1223
|
+
import { formatAbsoluteDate } from "@ai-matrx/kit/format";
|
|
1225
1224
|
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1226
1225
|
var PAGE = 50;
|
|
1227
1226
|
var MAX = 500;
|
|
@@ -1258,7 +1257,7 @@ function ActivityPanel({ item, port, onClose }) {
|
|
|
1258
1257
|
day.entries.map((entry) => ({ entry, s: auditSentence(entry, item, me) })),
|
|
1259
1258
|
(r) => `${r.s.what}|${r.s.who ?? ""}`
|
|
1260
1259
|
).map(({ row: { entry, s }, times }) => {
|
|
1261
|
-
return /* @__PURE__ */ jsxs6("div", { className: "flex min-h-9 items-center gap-1.5 px-3 text-sm sm:px-4", title:
|
|
1260
|
+
return /* @__PURE__ */ jsxs6("div", { className: "flex min-h-9 items-center gap-1.5 px-3 text-sm sm:px-4", title: formatAbsoluteDate(entry.at, void 0, ""), children: [
|
|
1262
1261
|
/* @__PURE__ */ jsx6("span", { className: cn4("truncate", s.refused ? "text-destructive" : "text-foreground"), children: s.what }),
|
|
1263
1262
|
/* @__PURE__ */ jsxs6("span", { className: "shrink-0 text-muted-foreground", children: [
|
|
1264
1263
|
times > 1 ? ` \xB7 ${times} times` : "",
|
|
@@ -1343,7 +1342,7 @@ function HistoryPanel({ item, port, arg, onClose, onChanged }) {
|
|
|
1343
1342
|
page && (page.captureStartedAt || page.incomplete) ? /* @__PURE__ */ jsxs7("div", { className: "flex flex-wrap gap-x-3 gap-y-1 px-1 text-xs", children: [
|
|
1344
1343
|
page.captureStartedAt ? /* @__PURE__ */ jsxs7("span", { className: "text-muted-foreground", children: [
|
|
1345
1344
|
"Kept since ",
|
|
1346
|
-
|
|
1345
|
+
formatAbsoluteDate2(page.captureStartedAt, void 0, "")
|
|
1347
1346
|
] }) : null,
|
|
1348
1347
|
page.incomplete ? /* @__PURE__ */ jsx7("span", { className: "text-warning", children: "Some changes could not be read" }) : null
|
|
1349
1348
|
] }) : null
|
|
@@ -1356,7 +1355,7 @@ function HistoryRow({ item, port, page, entry, label, onRestored, onConflict, on
|
|
|
1356
1355
|
const secret = useTransientSecret();
|
|
1357
1356
|
const copyValue2 = useCopy();
|
|
1358
1357
|
const [busy, setBusy] = useState7(false);
|
|
1359
|
-
const when =
|
|
1358
|
+
const when = formatAbsoluteDate2(entry.recordedAt, void 0, "");
|
|
1360
1359
|
async function read() {
|
|
1361
1360
|
if (secret.value !== null) return secret.value;
|
|
1362
1361
|
setBusy(true);
|
|
@@ -1518,11 +1517,11 @@ function authenticatorName(current, parsed) {
|
|
|
1518
1517
|
if (name && !PLACEHOLDER_NAMES.includes(name.toLowerCase())) return name;
|
|
1519
1518
|
return parsed.issuer || parsed.account || name || "One-time password";
|
|
1520
1519
|
}
|
|
1521
|
-
function matchIssuerToSite(issuer, candidates,
|
|
1520
|
+
function matchIssuerToSite(issuer, candidates, siteOf) {
|
|
1522
1521
|
const key = (issuer ?? "").toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
1523
1522
|
if (key.length < 2) return null;
|
|
1524
1523
|
for (const c of candidates) {
|
|
1525
|
-
const host =
|
|
1524
|
+
const host = siteOf(c).toLowerCase();
|
|
1526
1525
|
if (!host) continue;
|
|
1527
1526
|
const labels = host.split(".");
|
|
1528
1527
|
if (labels.some((l) => l.replace(/[^a-z0-9]/g, "") === key)) return c;
|
|
@@ -2143,7 +2142,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
|
|
|
2143
2142
|
const recognise = (p) => {
|
|
2144
2143
|
if (!nameTouched) setName((n) => authenticatorName(n, p));
|
|
2145
2144
|
if (!targetChosen) {
|
|
2146
|
-
const match = matchIssuerToSite(p.issuer, candidates,
|
|
2145
|
+
const match = matchIssuerToSite(p.issuer, candidates, loginSiteOf);
|
|
2147
2146
|
setTarget(match ? match.id : NEW);
|
|
2148
2147
|
}
|
|
2149
2148
|
};
|
|
@@ -2221,7 +2220,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
|
|
|
2221
2220
|
value: target,
|
|
2222
2221
|
disabled: busy || created !== null,
|
|
2223
2222
|
"aria-label": "Add to",
|
|
2224
|
-
options: [{ value: NEW, label: "New login" }, ...candidates.map((c) => ({ value: c.id, label:
|
|
2223
|
+
options: [{ value: NEW, label: "New login" }, ...candidates.map((c) => ({ value: c.id, label: loginSiteOf(c) ? `${c.name} \xB7 ${loginSiteOf(c)}` : c.name }))],
|
|
2225
2224
|
onValueChange: (v) => {
|
|
2226
2225
|
setTarget(v);
|
|
2227
2226
|
setTargetChosen(true);
|
|
@@ -2383,7 +2382,7 @@ function OtpListRow({ port, item, family, entry, onOpen, onRename, onChanged, on
|
|
|
2383
2382
|
const Icon = definitionGlyph(item.definitionKey, family);
|
|
2384
2383
|
const canManage = item.capabilities.canManage || item.capabilities.canEdit;
|
|
2385
2384
|
if (a.removed) return null;
|
|
2386
|
-
const sub = a.error ?? [entry?.account,
|
|
2385
|
+
const sub = a.error ?? [entry?.account, loginSiteOf(item) || entry?.issuer].filter((v, i, all) => Boolean(v) && all.indexOf(v) === i).join(" \xB7 ");
|
|
2387
2386
|
return /* @__PURE__ */ jsxs12("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: [
|
|
2388
2387
|
/* @__PURE__ */ jsx12("button", { type: "button", onClick: onOpen, "aria-label": `Open ${item.name}`, tabIndex: -1, className: cn6("flex size-8 items-center justify-center rounded-lg bg-muted", a.enabled ? "text-foreground" : "text-disabled-foreground"), children: /* @__PURE__ */ jsx12(Icon, { className: "size-4" }) }),
|
|
2389
2388
|
/* @__PURE__ */ jsxs12("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: [
|
|
@@ -5152,7 +5151,7 @@ var MEMBER_ACCESS_LABEL = { none: "No access", use: "Can use", editor: "Can edit
|
|
|
5152
5151
|
function levelOf(flags) {
|
|
5153
5152
|
return flags.can_manage ? "edit" : "use";
|
|
5154
5153
|
}
|
|
5155
|
-
function
|
|
5154
|
+
function shareFlagsOf(level) {
|
|
5156
5155
|
return { can_use: true, can_manage: level === "edit" };
|
|
5157
5156
|
}
|
|
5158
5157
|
function isEmail(value) {
|
|
@@ -5566,6 +5565,7 @@ function SharingSummary({ item, port, className }) {
|
|
|
5566
5565
|
}
|
|
5567
5566
|
|
|
5568
5567
|
// src/ItemPane.tsx
|
|
5568
|
+
import { formatAbsoluteDate as formatAbsoluteDate3 } from "@ai-matrx/kit/format";
|
|
5569
5569
|
import { Fragment as Fragment15, jsx as jsx26, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
5570
5570
|
var USERNAME_KEYS = /^(username|user_name|email|login|username_or_email|account_email)$/;
|
|
5571
5571
|
function ItemPane(props) {
|
|
@@ -5713,7 +5713,7 @@ function ItemPane(props) {
|
|
|
5713
5713
|
const descriptionVisible = showDescription || draft.description !== "";
|
|
5714
5714
|
const header = /* @__PURE__ */ jsxs24("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: [
|
|
5715
5715
|
onBack ? /* @__PURE__ */ jsx26(Button21, { variant: "quiet", icon: /* @__PURE__ */ jsx26(ChevronLeftGlyph, {}), "aria-label": "Back", onClick: mode === "new" ? onCancelNew : onBack }) : null,
|
|
5716
|
-
/* @__PURE__ */ jsx26(ItemIcon, { definitionKey: definition?.key ?? item?.definitionKey ?? "custom", family: definition?.family ?? "generic", site: item ?
|
|
5716
|
+
/* @__PURE__ */ jsx26(ItemIcon, { definitionKey: definition?.key ?? item?.definitionKey ?? "custom", family: definition?.family ?? "generic", site: item ? loginSiteOf(item) : loginSiteOf({ loginUrls: draft.loginUrls }), size: "lg" }),
|
|
5717
5717
|
/* @__PURE__ */ jsxs24("div", { className: "flex min-w-0 flex-1 flex-col", children: [
|
|
5718
5718
|
/* @__PURE__ */ jsx26("h2", { className: "truncate text-base font-semibold leading-tight", children: editing ? draft.name || (mode === "new" ? `New ${typeLabel.toLowerCase()}` : item?.name) : item?.name }),
|
|
5719
5719
|
/* @__PURE__ */ jsxs24("span", { className: "flex min-w-0 items-center gap-1 text-xs text-muted-foreground", children: [
|
|
@@ -5946,9 +5946,9 @@ function ItemPane(props) {
|
|
|
5946
5946
|
filesProps ? /* @__PURE__ */ jsx26(FilesSection, { ...filesProps, editing: false }) : null,
|
|
5947
5947
|
/* @__PURE__ */ jsxs24("p", { className: cn12("px-1 text-xs text-muted-foreground"), children: [
|
|
5948
5948
|
"Modified ",
|
|
5949
|
-
|
|
5949
|
+
formatAbsoluteDate3(item.updatedAt, DAY_FORMAT, ""),
|
|
5950
5950
|
" \xB7 Created ",
|
|
5951
|
-
|
|
5951
|
+
formatAbsoluteDate3(item.createdAt, DAY_FORMAT, "")
|
|
5952
5952
|
] })
|
|
5953
5953
|
] }) : null }) })
|
|
5954
5954
|
] }) });
|
|
@@ -5963,7 +5963,7 @@ var SORTS2 = [
|
|
|
5963
5963
|
{ value: "created", label: "Recently added" }
|
|
5964
5964
|
];
|
|
5965
5965
|
function subtitleOf(item, withOwner) {
|
|
5966
|
-
const what =
|
|
5966
|
+
const what = loginSiteOf(item) || item.definitionLabel;
|
|
5967
5967
|
return withOwner ? `${what} \xB7 ${item.owner.label}` : what;
|
|
5968
5968
|
}
|
|
5969
5969
|
function ItemList({ title, items, definitions, port, selectedId, onSelect, query, onQuery, sort, onSort, onNew, matchingIds, header }) {
|
|
@@ -6046,7 +6046,7 @@ function ListRow({ item, family, port, on, onSelect, withOwner }) {
|
|
|
6046
6046
|
onClick: () => onSelect(item.id),
|
|
6047
6047
|
className: cn13("flex h-12 w-full items-center gap-3 rounded-lg px-2 text-left", on ? "bg-primary text-primary-foreground" : "hover:bg-accent"),
|
|
6048
6048
|
children: [
|
|
6049
|
-
/* @__PURE__ */ jsx27(ItemIcon, { definitionKey: item.definitionKey, family, site:
|
|
6049
|
+
/* @__PURE__ */ jsx27(ItemIcon, { definitionKey: item.definitionKey, family, site: loginSiteOf(item), inverted: on }),
|
|
6050
6050
|
/* @__PURE__ */ jsxs25("span", { className: "flex min-w-0 flex-1 flex-col leading-tight", children: [
|
|
6051
6051
|
/* @__PURE__ */ jsx27("span", { className: "truncate text-sm font-medium", children: item.name }),
|
|
6052
6052
|
/* @__PURE__ */ jsx27("span", { className: "truncate text-xs text-muted-foreground", children: subtitleOf(item, withOwner) })
|
|
@@ -6064,6 +6064,7 @@ function ListRow({ item, family, port, on, onSelect, withOwner }) {
|
|
|
6064
6064
|
// src/lists/TrashView.tsx
|
|
6065
6065
|
import { useState as useState29 } from "react";
|
|
6066
6066
|
import { Button as Button24 } from "@ai-matrx/design-system/controls";
|
|
6067
|
+
import { formatAbsoluteDate as formatAbsoluteDate4 } from "@ai-matrx/kit/format";
|
|
6067
6068
|
|
|
6068
6069
|
// src/lists/logic.ts
|
|
6069
6070
|
var ENTITY_TYPE = "credential_item";
|
|
@@ -6074,7 +6075,7 @@ function favoriteIds(data) {
|
|
|
6074
6075
|
function recentIds(data, limit = 50) {
|
|
6075
6076
|
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);
|
|
6076
6077
|
}
|
|
6077
|
-
function
|
|
6078
|
+
function trashItemMatchesQuery(item, query) {
|
|
6078
6079
|
const q = query.trim().toLowerCase();
|
|
6079
6080
|
if (!q) return true;
|
|
6080
6081
|
return [item.name, item.definitionLabel, item.owner.label, ...item.tags].some((s) => s.toLowerCase().includes(q));
|
|
@@ -6206,7 +6207,7 @@ function TrashView({ port, deleted, query, header, onChanged }) {
|
|
|
6206
6207
|
const confirmed = useConfirmed();
|
|
6207
6208
|
const [busyId, setBusyId] = useState29(null);
|
|
6208
6209
|
const [message2, setMessage] = useState29(null);
|
|
6209
|
-
const shown = deleted.filter((i) =>
|
|
6210
|
+
const shown = deleted.filter((i) => trashItemMatchesQuery(i, query));
|
|
6210
6211
|
const [restoring, setRestoring] = useState29(null);
|
|
6211
6212
|
const restore = async (item, deletionId) => {
|
|
6212
6213
|
setBusyId(item.id);
|
|
@@ -6231,7 +6232,7 @@ function TrashView({ port, deleted, query, header, onChanged }) {
|
|
|
6231
6232
|
/* @__PURE__ */ jsxs27("div", { className: "flex min-h-12 items-center gap-3 px-3 py-1.5 sm:px-4", children: [
|
|
6232
6233
|
/* @__PURE__ */ jsxs27("span", { className: "flex min-w-0 flex-1 flex-col leading-tight", children: [
|
|
6233
6234
|
/* @__PURE__ */ jsx29("span", { className: "truncate text-sm text-foreground", children: item.name }),
|
|
6234
|
-
/* @__PURE__ */ jsx29("span", { className: "truncate text-xs text-muted-foreground", children: [item.deletion?.deletedAt ? `Deleted ${
|
|
6235
|
+
/* @__PURE__ */ jsx29("span", { className: "truncate text-xs text-muted-foreground", children: [item.deletion?.deletedAt ? `Deleted ${formatAbsoluteDate4(item.deletion.deletedAt, DAY_FORMAT, "")}` : null, item.owner.kind !== "me" ? item.owner.label : null].filter(Boolean).join(" \xB7 ") })
|
|
6235
6236
|
] }),
|
|
6236
6237
|
/* @__PURE__ */ jsx29(Button24, { variant: "outline", icon: /* @__PURE__ */ jsx29(RestoreGlyph, {}), disabled: busyId !== null || !item.deletion, onClick: () => setRestoring(item), children: "Restore" })
|
|
6237
6238
|
] }, item.id)
|
|
@@ -6318,6 +6319,7 @@ import { useEffect as useEffect19, useRef as useRef16, useState as useState31 }
|
|
|
6318
6319
|
import { confirm as confirm10 } from "@ai-matrx/kit/confirm-opener";
|
|
6319
6320
|
import { Checkbox as Checkbox2 } from "@ai-matrx/design-system";
|
|
6320
6321
|
import { Badge as Badge8, Button as Button26, Field as Field11, RegionSkeleton as RegionSkeleton2, SegmentedControl as SegmentedControl5, Textarea as Textarea4 } from "@ai-matrx/design-system/controls";
|
|
6322
|
+
import { formatAbsoluteDate as formatAbsoluteDate5 } from "@ai-matrx/kit/format";
|
|
6321
6323
|
|
|
6322
6324
|
// src/sharing/secure-link-logic.ts
|
|
6323
6325
|
import { formatDurationMinutes } from "@ai-matrx/kit/format";
|
|
@@ -6587,7 +6589,7 @@ function SecureLinkPanel({ item, port, onClose }) {
|
|
|
6587
6589
|
);
|
|
6588
6590
|
}
|
|
6589
6591
|
function sentMeta(row, options) {
|
|
6590
|
-
const when = row.status === "pending" ? `Until ${
|
|
6592
|
+
const when = row.status === "pending" ? `Until ${formatAbsoluteDate5(row.expiresAt, void 0, "")}` : row.status === "viewed" && row.viewedAt ? formatAbsoluteDate5(row.viewedAt, void 0, "") : formatAbsoluteDate5(row.createdAt, DAY_FORMAT, "");
|
|
6591
6593
|
const carried = row.fieldKeys.length ? carriedWords(row.fieldKeys, options?.fields ?? []) : "";
|
|
6592
6594
|
return [when, carried].filter(Boolean).join(" \xB7 ");
|
|
6593
6595
|
}
|
|
@@ -6596,6 +6598,7 @@ function sentMeta(row, options) {
|
|
|
6596
6598
|
import { useCallback as useCallback4, useEffect as useEffect20, useState as useState32 } from "react";
|
|
6597
6599
|
import { confirm as confirm11 } from "@ai-matrx/kit/confirm-opener";
|
|
6598
6600
|
import { Button as Button27, RegionSkeleton as RegionSkeleton3 } from "@ai-matrx/design-system/controls";
|
|
6601
|
+
import { formatAbsoluteDate as formatAbsoluteDate6 } from "@ai-matrx/kit/format";
|
|
6599
6602
|
|
|
6600
6603
|
// src/devices/logic.ts
|
|
6601
6604
|
var PASSKEY_RP_ID = "aimatrx.com";
|
|
@@ -6725,13 +6728,13 @@ function DevicesPanel({ port, onClose }) {
|
|
|
6725
6728
|
Row,
|
|
6726
6729
|
{
|
|
6727
6730
|
label: off ? "Turned off" : "Can fill",
|
|
6728
|
-
hint: off ?
|
|
6731
|
+
hint: off ? formatAbsoluteDate6(device.revokedAt, DAY_FORMAT, "") : void 0,
|
|
6729
6732
|
actions: off ? null : /* @__PURE__ */ jsx32(Button27, { variant: "outline", icon: /* @__PURE__ */ jsx32(PowerGlyph, {}), disabled: busyId !== null, onClick: () => void revoke(device), children: "Revoke" }),
|
|
6730
6733
|
children: /* @__PURE__ */ jsxs30("span", { className: "flex min-w-0 flex-col", children: [
|
|
6731
6734
|
/* @__PURE__ */ jsx32("span", { className: off ? "truncate text-muted-foreground" : "truncate text-foreground", children: device.label }),
|
|
6732
6735
|
/* @__PURE__ */ jsxs30("span", { className: "truncate text-xs text-muted-foreground", children: [
|
|
6733
|
-
device.lastUsedAt ? `Last used ${
|
|
6734
|
-
device.addedAt ? ` \xB7 added ${
|
|
6736
|
+
device.lastUsedAt ? `Last used ${formatAbsoluteDate6(device.lastUsedAt, void 0, "")}` : "Never used",
|
|
6737
|
+
device.addedAt ? ` \xB7 added ${formatAbsoluteDate6(device.addedAt, DAY_FORMAT, "")}` : ""
|
|
6735
6738
|
] })
|
|
6736
6739
|
] })
|
|
6737
6740
|
},
|
|
@@ -6825,7 +6828,7 @@ function ApprovePanel({ port, host, onClose, approvalKey, label, kind = "browser
|
|
|
6825
6828
|
"Return to ",
|
|
6826
6829
|
where,
|
|
6827
6830
|
" by ",
|
|
6828
|
-
|
|
6831
|
+
formatAbsoluteDate6(approvedUntil, void 0, ""),
|
|
6829
6832
|
"."
|
|
6830
6833
|
] }) }) : !passkeys ? /* @__PURE__ */ jsxs30(Empty, { children: [
|
|
6831
6834
|
"Approve with your password in ",
|
|
@@ -7516,10 +7519,10 @@ function MatchRow({ itemId, item, tag, family, port, busy, running, onOpen, onFi
|
|
|
7516
7519
|
setReading(false);
|
|
7517
7520
|
}
|
|
7518
7521
|
};
|
|
7519
|
-
const subtitle = [item ?
|
|
7522
|
+
const subtitle = [item ? loginSiteOf(item) || item.definitionLabel : "", tag].filter(Boolean).join(" \xB7 ");
|
|
7520
7523
|
return /* @__PURE__ */ jsxs35("li", { className: "flex h-12 items-center gap-1 pl-1 pr-2", "data-item": itemId, children: [
|
|
7521
7524
|
/* @__PURE__ */ jsxs35("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: [
|
|
7522
|
-
/* @__PURE__ */ jsx37(ItemIcon, { definitionKey: item?.definitionKey ?? "website_login", family, site: item ?
|
|
7525
|
+
/* @__PURE__ */ jsx37(ItemIcon, { definitionKey: item?.definitionKey ?? "website_login", family, site: item ? loginSiteOf(item) : "" }),
|
|
7523
7526
|
/* @__PURE__ */ jsxs35("span", { className: "flex min-w-0 flex-1 flex-col leading-tight", children: [
|
|
7524
7527
|
/* @__PURE__ */ jsx37("span", { className: "truncate text-sm font-medium", children: item?.name ?? "Saved login" }),
|
|
7525
7528
|
subtitle ? /* @__PURE__ */ jsx37("span", { className: "truncate text-xs text-muted-foreground", children: subtitle }) : null
|
|
@@ -8502,7 +8505,7 @@ function createSharingPort(ctx, options = {}) {
|
|
|
8502
8505
|
return r.grants.map(grantOf);
|
|
8503
8506
|
},
|
|
8504
8507
|
async addPerson(item, email, level) {
|
|
8505
|
-
const w = await account6.addGrant(api, { path: { item_id: item.id }, body: { recipient_email: email.trim(), ...
|
|
8508
|
+
const w = await account6.addGrant(api, { path: { item_id: item.id }, body: { recipient_email: email.trim(), ...shareFlagsOf(level), initiation: "user" } }, ctx.optsFor(item));
|
|
8506
8509
|
return grantOf(w);
|
|
8507
8510
|
},
|
|
8508
8511
|
async addOrganization(item, organizationId, level) {
|
|
@@ -8510,14 +8513,14 @@ function createSharingPort(ctx, options = {}) {
|
|
|
8510
8513
|
return grantOf(w);
|
|
8511
8514
|
},
|
|
8512
8515
|
async setLevel(item, grant, level) {
|
|
8513
|
-
const w = await account6.updateGrant(api, { path: { item_id: item.id, grant_id: grant.id }, body: { ...
|
|
8516
|
+
const w = await account6.updateGrant(api, { path: { item_id: item.id, grant_id: grant.id }, body: { ...shareFlagsOf(level), initiation: "user" } }, ctx.optsFor(item));
|
|
8514
8517
|
return grantOf(w);
|
|
8515
8518
|
},
|
|
8516
8519
|
async revoke(item, grant) {
|
|
8517
8520
|
await account6.removeGrant(api, { path: { item_id: item.id, grant_id: grant.id } }, ctx.optsFor(item));
|
|
8518
8521
|
},
|
|
8519
8522
|
async setAccessMode(item, mode, people) {
|
|
8520
|
-
const grantees = mode === "restricted" ? people.filter((g) => g.kind === "person" && g.userId).map((g) => ({ user_id: g.userId, ...
|
|
8523
|
+
const grantees = mode === "restricted" ? people.filter((g) => g.kind === "person" && g.userId).map((g) => ({ user_id: g.userId, ...shareFlagsOf(g.level) })) : [];
|
|
8521
8524
|
await account6.share(api, { path: { item_id: item.id }, body: { access_mode: mode, grantees, initiation: "user" } }, ctx.optsFor(item));
|
|
8522
8525
|
return ctx.refetch(item.id, item.owner);
|
|
8523
8526
|
},
|
|
@@ -8932,10 +8935,10 @@ export {
|
|
|
8932
8935
|
inferFromUrl,
|
|
8933
8936
|
locationFromParams,
|
|
8934
8937
|
locationToParams,
|
|
8938
|
+
loginSiteOf,
|
|
8935
8939
|
matchesQuery,
|
|
8936
8940
|
needsRecentSignIn,
|
|
8937
8941
|
parseDefinitions,
|
|
8938
|
-
siteOf,
|
|
8939
8942
|
sortItems
|
|
8940
8943
|
};
|
|
8941
8944
|
//# sourceMappingURL=index.js.map
|