@hazem3500/palette 0.9.108 → 0.9.110

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 (115) hide show
  1. package/NODE.md +32 -30
  2. package/README.md +58 -46
  3. package/cli/agent.mjs +93 -69
  4. package/cli/config.mjs +17 -1
  5. package/cli/design-edit.mjs +9 -7
  6. package/cli/index.mjs +26 -24
  7. package/cli/snapshots.mjs +3 -3
  8. package/cli/workflow.mjs +15 -7
  9. package/dist/{accent-picker-TTIZ65XF.js → accent-picker-PPVPURA7.js} +1 -1
  10. package/dist/account-tokens-LBRVZAEJ.js +1 -0
  11. package/dist/adapters/css-variables.js +1 -1
  12. package/dist/adapters/tailwind.js +1 -1
  13. package/dist/chunk-2FX2JEMO.js +1 -0
  14. package/dist/chunk-4HBBEVFK.js +1 -0
  15. package/dist/chunk-5HZI7HRR.js +1 -0
  16. package/dist/chunk-DU7H4TEX.js +1 -0
  17. package/dist/chunk-FGZXQUAD.js +1 -0
  18. package/dist/{chunk-AYGLN3MI.js → chunk-HLXSRXTK.js} +1 -1
  19. package/dist/{chunk-DZRM3YUQ.js → chunk-J47R52WX.js} +1 -1
  20. package/dist/chunk-KELFDOEC.js +1 -0
  21. package/dist/{chunk-2J3IID4N.js → chunk-KLPQTFVH.js} +1 -1
  22. package/dist/chunk-ONUORDYE.js +1 -0
  23. package/dist/chunk-PF4NYFZK.js +1 -0
  24. package/dist/chunk-S6NEYT36.js +1 -0
  25. package/dist/chunk-U55ASP2Y.js +1 -0
  26. package/dist/chunk-VX6XCU4E.js +1 -0
  27. package/dist/color-editor-QPJQD36F.js +1 -0
  28. package/dist/config.d.ts +1 -1
  29. package/dist/design-comment-BF2KGPWU.js +1 -0
  30. package/dist/{design-export-BNNHI4JP.js → design-export-Y2GU3KER.js} +1 -1
  31. package/dist/design-geometry-HJLEXLPO.js +1 -0
  32. package/dist/design-mode-styles.d.ts +1 -1
  33. package/dist/design-mode.js +1 -1
  34. package/dist/design-panel-ZQS4WQCI.js +1 -0
  35. package/dist/design-panel-styles.d.ts +1 -1
  36. package/dist/design-popup.d.ts +1 -1
  37. package/dist/design-system.d.ts +5 -4
  38. package/dist/{field-controls-4ROTPXMO.js → field-controls-4AIIXPNQ.js} +1 -1
  39. package/dist/{frame-iframe-WBEP3R6S.js → frame-iframe-PYLYMCOK.js} +1 -1
  40. package/dist/frame-size-TF6SIUFO.js +1 -0
  41. package/dist/frame-target.d.ts +5 -2
  42. package/dist/host-motion.d.ts +1 -1
  43. package/dist/index.js +1 -1
  44. package/dist/inline-text-editor-MK6FHDAM.js +1 -0
  45. package/dist/live-colors-D426RBEC.js +1 -0
  46. package/dist/live-colors.d.ts +1 -1
  47. package/dist/node.mjs +102 -75
  48. package/dist/onboarding-6OSADOWE.js +1 -0
  49. package/dist/{pin-groups-YAYFPJYA.js → pin-groups-GF53RTHP.js} +1 -1
  50. package/dist/{pin-move-PG54WWPU.js → pin-move-G6EWHLDO.js} +1 -1
  51. package/dist/public-env.d.ts +49 -11
  52. package/dist/react-props-panel-ZSKQ44GS.js +1 -0
  53. package/dist/react.d.ts +2 -0
  54. package/dist/react.js +1 -1
  55. package/dist/select-menu-OZVNHZ73.js +1 -0
  56. package/dist/server.js +80 -57
  57. package/dist/setup.js +1 -1
  58. package/dist/shell-mode-PLV6F474.js +1 -0
  59. package/dist/shell-session.d.ts +5 -3
  60. package/dist/shell.d.ts +1 -1
  61. package/dist/shell.js +1 -1
  62. package/dist/shortcut-help-DIMOT2ZK.js +1 -0
  63. package/dist/snapshot-3PSQKXUV.js +1 -0
  64. package/dist/snapshot.d.ts +1 -1
  65. package/dist/source-info.d.ts +1 -1
  66. package/dist/storage-keys.d.ts +5 -0
  67. package/dist/tag-editor-B3I7WD4N.js +1 -0
  68. package/dist/thread-snapshot-ML2RZVID.js +1 -0
  69. package/dist/token-custom-CASAQWYW.js +1 -0
  70. package/dist/token-page-NIB5HAVS.js +1 -0
  71. package/dist/token-picker-AJ5E5IN5.js +1 -0
  72. package/dist/{toolbar-runtime-QCZONSWE.js → toolbar-runtime-TZWY2KH3.js} +1 -1
  73. package/dist/typed-custom.d.ts +1 -1
  74. package/dist/types.d.ts +1 -1
  75. package/package.json +1 -1
  76. package/server/account-page.ts +6 -6
  77. package/server/iap.ts +2 -2
  78. package/server/index.ts +30 -24
  79. package/server/project-management.ts +5 -5
  80. package/server/proxy-auth.ts +17 -16
  81. package/server/public-env.ts +67 -11
  82. package/server/setup-client.txt +173 -173
  83. package/server/setup-page.ts +1 -1
  84. package/server/tokens.ts +9 -6
  85. package/server/webhooks.ts +9 -5
  86. package/src/types.ts +1 -1
  87. package/dist/account-tokens-PINQNSNE.js +0 -1
  88. package/dist/chunk-4KEVPMJJ.js +0 -1
  89. package/dist/chunk-4XQD75A2.js +0 -1
  90. package/dist/chunk-57MG3M5P.js +0 -1
  91. package/dist/chunk-5OVDW2RU.js +0 -1
  92. package/dist/chunk-6HM4JQLV.js +0 -1
  93. package/dist/chunk-DLC3CRFV.js +0 -1
  94. package/dist/chunk-DVYSFT6O.js +0 -1
  95. package/dist/chunk-FD4GACV2.js +0 -1
  96. package/dist/chunk-IQOPM3JF.js +0 -1
  97. package/dist/chunk-UEZCLURX.js +0 -1
  98. package/dist/color-editor-ATWWSENS.js +0 -1
  99. package/dist/design-comment-RXUCDTYA.js +0 -1
  100. package/dist/design-geometry-DPMHGQEK.js +0 -1
  101. package/dist/design-panel-HTN6LR3V.js +0 -1
  102. package/dist/frame-size-MRCN6XYD.js +0 -1
  103. package/dist/inline-text-editor-AMFRKW5Z.js +0 -1
  104. package/dist/live-colors-GWOVVQSO.js +0 -1
  105. package/dist/onboarding-BVTCFEHL.js +0 -1
  106. package/dist/react-props-panel-4XO3NSX3.js +0 -1
  107. package/dist/select-menu-QAYV7NKJ.js +0 -1
  108. package/dist/shell-mode-SUYLWDWW.js +0 -1
  109. package/dist/shortcut-help-XRDNX7MZ.js +0 -1
  110. package/dist/snapshot-V264ZMQG.js +0 -1
  111. package/dist/tag-editor-MMAMOEI4.js +0 -1
  112. package/dist/thread-snapshot-HLTNHS4N.js +0 -1
  113. package/dist/token-custom-UCA6CBOV.js +0 -1
  114. package/dist/token-page-PGPWPUKU.js +0 -1
  115. package/dist/token-picker-WMWUKLKJ.js +0 -1
@@ -1,4 +1,4 @@
1
- /** `base` is the path the app is served under, such as "/komo", or "". */
1
+ /** `base` is the path the app is served under, such as "/palette", or "". */
2
2
  export function setupPage(base: string) {
3
3
  return new Response(
4
4
  `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Set up inline feedback</title><style>html{color-scheme:dark}body{margin:0;background:#111;color:#777;font:15px system-ui}main{height:100dvh;display:grid;place-items:center;background:#171717}h1{font-size:32px;letter-spacing:-1.5px;font-weight:500;color:#444}</style></head><body><main><h1>Inline feedback</h1></main><script type="module" src="${base}/setup-client.js"></script></body></html>`,
package/server/tokens.ts CHANGED
@@ -2,12 +2,14 @@ import { timingSafeEqual } from "node:crypto";
2
2
  import { check, string } from "./validation";
3
3
 
4
4
  // Personal access tokens let a bot act as its owner with a narrower grant.
5
- // Format: komo_pat_<12-char lookup id>_<43-char secret>. Only a salted SHA-256
5
+ // Format: palette_pat_<12-char lookup id>_<43-char secret>. Only a salted SHA-256
6
6
  // of the secret is stored (plus an optional server pepper), never the token.
7
- export const PAT_PREFIX = "komo_pat_";
7
+ // Tokens issued before the rename start komo_pat_ and keep working: the prefix
8
+ // isn't part of the hash.
9
+ export const PAT_PREFIX = "palette_pat_";
8
10
  export const PAT_SCOPES = ["comments:read", "comments:write"] as const;
9
11
  export type PatAccess = "read" | "write" | "any";
10
- const PAT_PATTERN = /^komo_pat_([a-z0-9]{12})_([A-Za-z0-9_-]{43})$/;
12
+ const PAT_PATTERN = /^(?:palette|komo)_pat_([a-z0-9]{12})_([A-Za-z0-9_-]{43})$/;
11
13
  const MAX_ACTIVE_TOKENS = 25;
12
14
  const MAX_LIFETIME_DAYS = 365;
13
15
  const USE_LOG_INTERVAL = 60000;
@@ -44,7 +46,7 @@ async function sha256(value: string) {
44
46
  ).join("");
45
47
  }
46
48
  const digest = (env: Env, salt: string, secret: string) =>
47
- sha256(`${env.KOMO_TOKEN_PEPPER ?? ""}\0${salt}\0${secret}`);
49
+ sha256(`${env.PALETTE_TOKEN_PEPPER ?? ""}\0${salt}\0${secret}`);
48
50
  function randomId(length: number) {
49
51
  const alphabet = "abcdefghijklmnopqrstuvwxyz0123456789";
50
52
  let result = "";
@@ -71,7 +73,7 @@ const list = (value: string | null): string[] | null => {
71
73
  };
72
74
 
73
75
  export const isPersonalToken = (bearer: string) =>
74
- bearer.startsWith(PAT_PREFIX);
76
+ /^(?:palette|komo)_pat_/.test(bearer);
75
77
 
76
78
  export function auditStatement(
77
79
  env: Env,
@@ -108,7 +110,8 @@ export async function accountProjects(env: Env, userId: string) {
108
110
  const publicToken = (row: TokenRow, now: number) => ({
109
111
  id: row.id,
110
112
  name: row.name,
111
- prefix: `${PAT_PREFIX}${row.id}`,
113
+ // Issuance-neutral: tokens issued before the rename start komo_pat_, newer ones palette_pat_.
114
+ prefix: `…_pat_${row.id}`,
112
115
  last4: row.last4,
113
116
  scopes: list(row.scopes) ?? [],
114
117
  projects: list(row.projects),
@@ -29,8 +29,8 @@ type WebhookEnv = {
29
29
  };
30
30
  };
31
31
  };
32
- KOMO_WEBHOOK_KEYS?: string;
33
- KOMO_WEBHOOK_SEND?: (
32
+ PALETTE_WEBHOOK_KEYS?: string;
33
+ PALETTE_WEBHOOK_SEND?: (
34
34
  url: string,
35
35
  body: string,
36
36
  headers: Record<string, string>
@@ -178,17 +178,21 @@ export async function dispatchWebhook(
178
178
  if (!row?.webhook_enabled || !row.webhook_url || !row.webhook_secret) return;
179
179
  const events = JSON.parse(row.webhook_events ?? "[]") as unknown;
180
180
  if (!Array.isArray(events) || !events.includes(event.event)) return;
181
- if (!env.KOMO_WEBHOOK_SEND) return;
181
+ if (!env.PALETTE_WEBHOOK_SEND) return;
182
182
  const body = JSON.stringify(event);
183
183
  if (encoder.encode(body).length > 16 * 1024) return;
184
184
  const timestamp = Math.floor(Date.now() / 1000);
185
185
  const secret = await decryptWebhookSecret(
186
- env.KOMO_WEBHOOK_KEYS,
186
+ env.PALETTE_WEBHOOK_KEYS,
187
187
  project,
188
188
  row.webhook_secret
189
189
  );
190
190
  const signature = await signWebhook(secret, timestamp, body);
191
- await env.KOMO_WEBHOOK_SEND(row.webhook_url, body, {
191
+ await env.PALETTE_WEBHOOK_SEND(row.webhook_url, body, {
192
+ "X-Palette-Delivery": event.id,
193
+ "X-Palette-Event": event.event,
194
+ "X-Palette-Signature": signature,
195
+ // The same values under the names receivers checked before the rename.
192
196
  "X-Komo-Delivery": event.id,
193
197
  "X-Komo-Event": event.event,
194
198
  "X-Komo-Signature": signature,
package/src/types.ts CHANGED
@@ -350,7 +350,7 @@ export interface CommentsOptions {
350
350
  /**
351
351
  * Save an image and/or trimmed HTML of the commented element with each new
352
352
  * thread, e.g. { image: true, html: true }. Off by default. Palette's own UI is
353
- * never captured, nor is anything inside an element with data-komo-no-snapshot.
353
+ * never captured, nor is anything inside an element with data-palette-no-snapshot (or the older data-komo-no-snapshot).
354
354
  */
355
355
  snapshots?: PaletteSnapshots;
356
356
  }
@@ -1 +0,0 @@
1
- import{a as e}from"./chunk-57MG3M5P.js";import{E as t,F as n,G as o,y as a}from"./chunk-IQOPM3JF.js";var i=864e5,r=[["7 days",7],["30 days",30],["90 days",90],["1 year",365],["Never",null]],s={"comments:read":"Read","comments:write":"Write"},p=[["year",365*i],["month",30*i],["week",7*i],["day",i],["hour",36e5],["minute",6e4]];function d(e,t=Date.now()){let n=e-t,o=new Intl.RelativeTimeFormat(void 0,{numeric:"auto",style:"short"});for(let[e,t]of p)if(Math.abs(n)>=t)return o.format(Math.round(n/t),e);return"just now"}var l=e=>new Intl.DateTimeFormat(void 0,{dateStyle:"medium",timeStyle:"short"}).format(e),c=0;function u(i,p,u){let k=t("div","account account-tokens");k.setAttribute("role","region");let f=t("style");f.textContent=".account-layer .account.account-tokens{padding-top:16px;gap:16px}\n.api-tokens-head{display:flex;align-items:center;gap:6px;margin-right:36px;min-height:30px}\n.api-tokens-head h2{margin:0;font-size:15px;font-weight:500;letter-spacing:-.01em}\n.api-tokens-head h2:focus{outline:none}\n.account-layer .account .api-tokens-back{border-radius:8px;color:#bbb}\n.api-tokens-back svg{rotate:90deg;width:16px;height:16px}\n.api-tokens-back:hover{background:color-mix(in oklab,var(--mm-ink) 7%,transparent);color:var(--mm-ink)}\n.api-tokens-lede,.api-tokens-note{margin:0;font-size:12px;line-height:1.5;color:#999}\n.api-tokens-note code,.api-token-id{font:11px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace;color:#aaa;overflow-wrap:anywhere}\n.api-tokens-list{list-style:none;margin:0;padding:0;display:grid;gap:8px}\n.api-token,.api-tokens-sheet,.api-tokens-empty{display:grid;gap:8px;padding:14px;border-radius:14px;background:#ffffff05;box-shadow:inset 0 0 0 1px #ffffff09;font-size:12px;color:#ddd}\n.api-tokens-empty{gap:4px;color:#999;text-align:center;padding:20px 14px}\n.api-tokens-empty strong{color:#ddd;font-weight:500}\n.api-token-row{display:flex;align-items:center;gap:8px;min-width:0}\n.api-token-row strong{font-weight:500;color:#eee;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}\n.api-token-chips{display:flex;flex-wrap:wrap;gap:4px}\n.api-token-chip{padding:0 6px;border-radius:5px;background:color-mix(in oklab,var(--mm-ink) 9%,transparent);color:color-mix(in oklab,var(--mm-ink) 78%,transparent);font-size:10px;font-weight:500;line-height:18px;white-space:nowrap}\n.api-token-chip[data-tone=warn]{background:#f1b77d1f;color:#f1b77d}\n.api-token-meta{display:flex;flex-wrap:wrap;gap:2px 10px;margin:0;color:#909090;font-size:11px}\n.api-token-meta div{display:flex;gap:4px}\n.api-token-meta dd{margin:0;color:#bbb}\n.api-token-meta time{cursor:default}\n.account-layer .account .api-token-revoke{margin-left:auto;padding:4px 8px;min-height:26px;border-radius:7px;font-size:11px;background:transparent;color:#fda29b}\n.api-token-revoke:hover,.api-tokens-actions .api-tokens-danger:hover{background:#fda29b14}\n.api-token-confirm{display:grid;gap:8px;padding-top:8px;box-shadow:0 -1px #ffffff0b}\n.api-token-confirm p,.api-tokens-sheet p{margin:0;line-height:1.5;color:#bbb}\n.api-tokens-actions{display:flex;justify-content:flex-end;gap:8px}\n.account-layer .account .api-tokens-actions button{width:auto;min-height:32px;padding:6px 12px;border-radius:9px;font-size:12px}\n.account-layer .account .api-tokens-actions .api-tokens-danger{background:#fda29b1a;color:#fda29b}\n.api-tokens-sheet{gap:14px;padding:16px}\n.api-tokens-sheet h3{margin:0;font-size:13px;font-weight:500;color:#eee}\n.api-tokens-sheet fieldset{border:0;margin:0;padding:0;display:grid;gap:8px;min-width:0}\n.api-tokens-sheet legend{padding:0;margin-bottom:8px;font-size:12px;color:#999}\n.account-layer .account .api-tokens-sheet input[type=text]{min-height:38px;padding:8px 10px;font-size:13px;border-radius:10px}\n.api-tokens-choices{display:flex;flex-wrap:wrap;gap:6px}\n.api-tokens-choice{position:relative;display:inline-flex;align-items:center;gap:6px;padding:6px 10px;border-radius:9px;background:#ffffff06;box-shadow:inset 0 0 0 1px #ffffff0b;color:#bbb;cursor:pointer;font-size:12px;line-height:16px}\n.api-tokens-choice:hover{color:#eee}\n.account-layer .account .api-tokens-choice input{position:absolute;inset:0;width:100%;height:100%;min-height:0;margin:0;opacity:0;cursor:pointer}\n.api-tokens-choice:has(input:checked){background:#bda6ef24;box-shadow:inset 0 0 0 1px #bda6ef80;color:#eee}\n.api-tokens-choice:has(input:focus-visible){outline:2px solid #bda6ef;outline-offset:2px}\n.api-tokens-choice small{color:#888;font-size:10px}\n.api-tokens-sheet p.api-tokens-error,.api-tokens-error{margin:0;color:#fda29b;font-size:12px;line-height:1.5}\n.api-tokens-error:empty{display:none}\n.api-tokens-secret{display:flex;gap:8px;align-items:center}\n.api-tokens-secret code{flex:1;min-width:0;padding:8px 10px;border-radius:10px;background:#00000040;box-shadow:inset 0 0 0 1px #ffffff0b;font:11px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace;color:#eee;overflow-wrap:anywhere;user-select:all}\n.account-layer .account .api-tokens-secret button{width:auto;min-height:34px;padding:0 12px;font-size:12px}\n.api-tokens-secret svg{width:14px;height:14px}\n.api-tokens-warning{display:flex;gap:7px;align-items:flex-start}\n.api-tokens-warning svg{flex:none;width:13px;height:13px;margin-top:2px;color:#f1b77d}\n.api-tokens-skeleton{height:84px;border-radius:14px;background:linear-gradient(90deg,#ffffff05,#ffffff0d,#ffffff05) 0 0/200% 100%;animation:api-tokens-shimmer 1.4s linear infinite}\n@keyframes api-tokens-shimmer{to{background-position:-200% 0}}\n@media (prefers-reduced-motion:reduce){.api-tokens-skeleton{animation:none}}";let h=t("div","api-tokens-head"),m=o("Back to account",()=>M(),"icon api-tokens-back","chevron"),g=t("h2","","API tokens");g.id="api-tokens-"+ ++c,g.tabIndex=-1,g.dataset.focusKey="api-tokens-title",k.setAttribute("aria-labelledby",g.id),h.append(m,g);let x=t("p","api-tokens-lede","Let bots and CI read or write comments as you. Treat tokens like passwords."),y=t("p","sr-only");y.setAttribute("role","status"),y.setAttribute("aria-live","polite");let b=t("div"),v=t("div"),w=t("div","morphing-menu__tooltip sidebar-tooltip");w.setAttribute("aria-hidden","true"),k.append(f,h,x,b,v,y,w),m.dataset.focusKey="api-tokens-back";let A=null,C=null,$=!1,T=!1,j="",E=null,S=new Map,N=e=>{y.textContent="",setTimeout(()=>y.textContent=e,30)},I=e=>{a()||e.animate([{opacity:0,transform:"translateY(4px)"},{opacity:1,transform:"none"}],{duration:250,easing:"cubic-bezier(.22,1,.36,1)"})},K=e=>requestAnimationFrame(()=>k.querySelector(`[data-focus-key="${e}"]`)?.focus()),z=t=>t instanceof e&&404===t.status?"This Palette server doesn’t support API tokens.":t instanceof Error?t.message:"Something went wrong. Try again.";k.focusStart=()=>K("api-tokens-title"),k.dispose=()=>{L(),w.remove()};let M=()=>{k.dispose(),u()};k.addEventListener("keydown",e=>{if("Escape"===e.key)if(e.stopPropagation(),e.preventDefault(),j){let e=j;j="",U(),K(`api-tokens-revoke-${e}`)}else E?K("api-tokens-done"):$?O():M()});let R=0,L=()=>{clearTimeout(R),delete w.dataset.open};k.addEventListener("pointerover",e=>{let t=e.target.closest?.("[data-tip]");if(!t)return L();clearTimeout(R),R=window.setTimeout(()=>{if(!t.isConnected)return;let e=k.getRootNode();w.parentNode!==e&&e instanceof ShadowRoot&&e.append(w);let n=t.getBoundingClientRect();w.textContent=t.dataset.tip??"";let o=w.offsetWidth/2;w.style.left=`${Math.max(8+o,Math.min(document.documentElement.clientWidth-8-o,n.left+n.width/2))}px`,w.style.top=n.top-8-w.offsetHeight+"px",w.dataset.open="true"},w.dataset.open?0:400)}),k.addEventListener("pointerleave",k.dispose),k.addEventListener("pointerdown",k.dispose);let P=(e,n,o)=>{let a=t("div"),i=t("dd");if(null===n)i.textContent=o;else{let e=t("time","",d(n));e.dateTime=new Date(n).toISOString(),e.dataset.tip=l(n),i.append(e,t("span","sr-only",` (${l(n)})`))}return a.append(t("dt","",e),i),a},q=(e,n,o)=>{let a=t("span","api-token-chip",e);return n&&(a.dataset.tone=n),o&&(a.dataset.tip=o),a},D=e=>e?1===e.length&&e[0]===p?"This project":1===e.length?e[0]:`${e.length} projects`:"All projects";function F(n){let a=t("li","api-token");a.dataset.token=n.id;let r=t("div","api-token-row"),p=t("strong","",n.name);p.id=`api-token-${n.id}-${g.id}`,a.setAttribute("aria-labelledby",p.id),r.append(p),n.expired&&r.append(q("Expired","warn"));let d=o(`Revoke ${n.name}`,()=>{j=n.id,S.delete(n.id),U(),K(`api-tokens-keep-${n.id}`)},"api-token-revoke");d.textContent="Revoke",d.removeAttribute("title"),d.dataset.focusKey=`api-tokens-revoke-${n.id}`,d.disabled=j===n.id,r.append(d);let l=t("div","api-token-chips");for(let e of n.scopes)l.append(q(s[e]??e,"",e));l.append(q(D(n.projects),"",n.projects?.join(", ")??"Every project you can access"));let c=t("dl","api-token-meta");c.append(P("Created",n.createdAt,""),P("Last used",n.lastUsedAt,"Never"),P(n.expired?"Expired":"Expires",n.expiresAt,"Never")),a.append(r,t("code","api-token-id",`${n.prefix}…${n.last4}`),l,c);let u=S.get(n.id);if(u){let e=t("p","api-tokens-error",u);e.setAttribute("role","alert"),a.append(e)}if(j===n.id){let r=t("div","api-token-confirm");r.setAttribute("role","group"),r.setAttribute("aria-label",`Revoke ${n.name}`);let s=t("div","api-tokens-actions"),p=o("Keep token",()=>{j="",U(),K(`api-tokens-revoke-${n.id}`)},"secondary");p.dataset.focusKey=`api-tokens-keep-${n.id}`;let d=o("Revoke token",()=>{!async function(t){if(!A)return;let n=A,o=n.tokens.findIndex(e=>e.id===t.id);if(o<0)return;n.tokens.splice(o,1),j="",U();let a=n.tokens[o]??n.tokens[o-1];K(a?`api-tokens-revoke-${a.id}`:"api-tokens-new");try{await i.request(`account/tokens/${encodeURIComponent(t.id)}`,"DELETE"),N(`Revoked ${t.name}.`)}catch(a){if(a instanceof e&&404===a.status)return void N(`Revoked ${t.name}.`);if(A!==n)return;n.tokens.splice(Math.min(o,n.tokens.length),0,t),S.set(t.id,`Couldn’t revoke: ${z(a)}`),U(),N(`Couldn’t revoke ${t.name}.`),K(`api-tokens-revoke-${t.id}`)}}(n)},"secondary api-tokens-danger");d.dataset.focusKey=`api-tokens-confirm-${n.id}`,s.append(p,d),r.append(t("p","","Anything using this token stops working right away. This can’t be undone."),s),a.append(r),I(r)}return a}function O(){$=!1,U(),K("api-tokens-new")}let Y="";function U(){L();let a=A?E?"secret":$?"form":"list":C?"error":"loading",d=[];if(A&&"list"===a){let e=o("New token",()=>{$=!0,U(),K("api-tokens-name")},"secondary");e.replaceChildren(n("plus"),document.createTextNode("New token")),e.removeAttribute("title"),e.dataset.focusKey="api-tokens-new",d.push(e)}else A&&"form"===a?d.push(function(n){let a=t("form","api-tokens-sheet");a.noValidate=!0,a.setAttribute("aria-labelledby",`${g.id}-new`);let d=t("h3","","New token");d.id=`${g.id}-new`;let l=t("label","account-name-label","Name"),c=t("input");c.type="text",c.maxLength=60,c.required=!0,c.autocomplete="off",c.placeholder="e.g. Deploy bot",c.dataset.focusKey="api-tokens-name",l.append(c);let u=(e,n,o,a)=>{let i=t("fieldset"),r=t("div","api-tokens-choices");for(let[e,i,s,p]of a){let a=t("label","api-tokens-choice",i),d=t("input");d.type=n,d.name=o,d.value=e,d.checked=s,d.dataset.focusKey=`api-tokens-${o}-${e}`,p&&a.append(t("small","",p)),a.prepend(d),r.append(a)}return i.append(t("legend","",e),r),i},k=u("Access","checkbox","scope",n.scopes.map(e=>[e,s[e]?`${s[e]} comments`:e,"comments:read"===e])),f=n.projects.includes(p),h=u("Projects","radio","projects",[...f?[["this","This project",!0]]:[],["all","All your projects",!f]]),m=u("Expires","radio","expiry",r.map(([e,t])=>[String(t),e,30===t])),x=t("p","api-tokens-error");x.setAttribute("role","alert");let y=t("div","api-tokens-actions"),b=o("Cancel",O,"secondary");b.dataset.focusKey="api-tokens-cancel";let v=o("Create token",()=>{},"primary");return v.type="submit",v.dataset.focusKey="api-tokens-create",y.append(b,v),a.append(d,l,k,h,m,x,y),a.addEventListener("submit",async t=>{if(t.preventDefault(),T)return;let o=[...a.querySelectorAll("input[name=scope]:checked")].map(e=>e.value),r=a.querySelector("input[name=expiry]:checked")?.value,s=c.value.trim()?o.length?null:k.querySelector("input"):c;if(x.textContent=c.value.trim()?o.length?"":"Choose read, write, or both.":"Name your token.",s)s.focus();else{T=!0,v.disabled=b.disabled=!0,v.setAttribute("aria-busy","true");try{let e=await i.request("account/tokens","POST",{name:c.value.trim(),scopes:o,expiresInDays:r&&"null"!==r?Number(r):null,projects:"this"===a.querySelector("input[name=projects]:checked")?.value?[p]:[]});if(A!==n)return;n.tokens.unshift(e.item),$=!1,E=e,U(),N("Token created. Copy it now. You won’t see it again."),K("api-tokens-copy")}catch(t){x.textContent=t instanceof e&&429===t.status?"You’ve created several tokens recently. Try again later.":z(t),v.focus()}finally{T=!1,v.disabled=b.disabled=!1,v.removeAttribute("aria-busy")}}}),a}(A)):E&&d.push(function(e){let a=t("section","api-tokens-sheet");a.setAttribute("aria-labelledby",`${g.id}-secret`);let i=t("h3","",`Copy “${e.item.name}”`);i.id=`${g.id}-secret`;let r=t("p","api-tokens-warning");r.append(n("info"),t("span","","You won’t see this token again. Store it in a secret manager, never in source control."));let s=t("div","api-tokens-secret"),p=t("code","",e.token);p.setAttribute("aria-label","New API token"),p.tabIndex=0,p.dataset.focusKey="api-tokens-secret";let d=o("Copy token",async()=>{try{await navigator.clipboard.writeText(e.token),d.replaceChildren(n("check"),document.createTextNode("Copied")),N("Token copied to the clipboard.")}catch{getSelection()?.selectAllChildren(p),N("Couldn’t copy. The token is selected; copy it with your keyboard.")}},"primary");d.replaceChildren(n("copy"),document.createTextNode("Copy")),d.removeAttribute("title"),d.dataset.focusKey="api-tokens-copy",s.append(p,d);let l=t("div","api-tokens-actions"),c=o("Done",()=>{E=null,U(),K("api-tokens-new")},"secondary");return c.dataset.focusKey="api-tokens-done",l.append(c),a.append(i,r,s,l),a}(E));if(a!==Y&&d[0]&&I(d[0]),Y=a,b.replaceChildren(...d),v.setAttribute("aria-busy",String(!A&&!C)),!A){if(C){let n=t("p","api-tokens-error",z(C));n.setAttribute("role","alert");let a=C instanceof e&&[403,404].includes(C.status),i=o("Try again",()=>{W()},"secondary");i.dataset.focusKey="api-tokens-retry",v.replaceChildren(n,...a?[]:[i])}else{let e=t("div","api-tokens-list");e.setAttribute("aria-hidden","true"),e.append(t("div","api-tokens-skeleton"),t("div","api-tokens-skeleton"));let n=t("span","sr-only","Loading API tokens");n.setAttribute("role","status"),v.replaceChildren(e,n)}return}if(!A.tokens.length){let e=t("p","api-tokens-empty");return e.append(t("strong","","No tokens yet"),t("span","","Create one for a bot, a script, or a CI job.")),void v.replaceChildren(e)}let l=t("ul","api-tokens-list");l.setAttribute("aria-label","Your API tokens"),l.append(...A.tokens.map(F));let c=t("p","api-tokens-note");c.append(document.createTextNode("Use a token as "),t("code","","KOMO_TOKEN"),document.createTextNode(" with the palette CLI.")),v.replaceChildren(l,c)}async function W(){C=null,A=null,U();try{let t=await i.request("account/tokens");if(!Array.isArray(t.tokens)||!Array.isArray(t.projects))throw new e(0,"Couldn’t read your tokens. Try again.");A={tokens:t.tokens,projects:t.projects,scopes:Array.isArray(t.scopes)?t.scopes:["comments:read","comments:write"]}}catch(e){C=e instanceof Error?e:new Error(String(e))}U()}return W(),k}export{u as accountTokens,d as relativeTime};
@@ -1 +0,0 @@
1
- var t=".komo-select,.komo-tokens{position:absolute;z-index:20;box-sizing:border-box;border-radius:10px;background:#232323;box-shadow:0 0 0 1px #ffffff14,0 12px 32px #0008;color:#d9d6d1;font-size:11px;font-weight:400;line-height:1.25;text-align:left;cursor:default;transform-origin:top;animation:komo-popup-in var(--duration-fast,250ms) var(--ease-smooth-out,cubic-bezier(.22,1,.36,1)) backwards}.komo-select[data-up],.komo-tokens[data-up]{transform-origin:bottom}@keyframes komo-popup-in{from{opacity:0;transform:scale(.97)}}@media (prefers-reduced-motion:reduce){.komo-select,.komo-tokens{animation:none}}";function o(t){let o={top:0,left:0,bottom:innerHeight,right:innerWidth};for(let e=t.parentElement;e;e=e.parentElement)if(/auto|scroll|hidden/.test(getComputedStyle(e).overflowY)){let t=e.getBoundingClientRect();return{top:Math.max(t.top,0),left:Math.max(t.left,0),bottom:Math.min(t.bottom,o.bottom),right:Math.min(t.right,o.right)}}return o}function e(t,o,e){let n=t.getRootNode();n.addEventListener("komo-preview-cancel",o,{signal:e});let i=new MutationObserver(()=>{t.isConnected||o()});i.observe(document,{childList:!0,subtree:!0}),n instanceof ShadowRoot&&i.observe(n,{childList:!0,subtree:!0}),e.addEventListener("abort",()=>i.disconnect(),{once:!0})}export{t as a,o as b,e as c};
@@ -1 +0,0 @@
1
- import{c as e}from"./chunk-3BVM3I52.js";import{e as t,f as n}from"./chunk-4FX5IS2U.js";var o,l=new WeakSet,r=new WeakMap;function a(t,n,l,a){let s=()=>{},i=e=>{if(t instanceof HTMLInputElement&&"length"===n.kind&&(t.type="text"),t instanceof HTMLSelectElement&&![...t.options].some(t=>t.value===e)){let n=document.createElement("option");n.value=n.textContent=e,t.prepend(n)}t.value="length"===n.kind&&/^-?[\d.]+px$/.test(e)?e.slice(0,-2):e,t.title=e,s()};if("length"===n.kind&&i(l.element.style.getPropertyValue(n.property)||getComputedStyle(l.element).getPropertyValue(n.property)),"font-family"===n.property){let n=t.parentElement,o=document.createElement("style");o.textContent=".komo-font-name{position:absolute;inset:0 28px 0 var(--lead,8px);display:flex;align-items:center;gap:6px;pointer-events:none;overflow:hidden;white-space:nowrap}.komo-font-name span{overflow:hidden;color:#f1efeb;text-overflow:ellipsis}.komo-font-name small{flex:none;color:#898680;font-size:10px}.komo-font-name[data-unresolved] span{color:#e7c27d}.design-field:has(.komo-font-name)>input:not(:focus){color:transparent}.design-field:has(>input:focus)>.komo-font-name,.design-field[data-token-mode=token]>.komo-font-name,.design-field[data-token-mode=connected]>.komo-font-name{display:none}";let r=document.createElement("span"),a=document.createElement("b"),i=document.createElement("span"),p=document.createElement("small");r.className="komo-font-name",r.setAttribute("aria-hidden","true"),a.textContent="Aa",r.append(a,i,p);let d=()=>{let n=l.element,o=getComputedStyle(n),s=e(n.style.getPropertyValue("font-family")||function(e){let t="",n=o=>{for(let l of o)if(l instanceof CSSStyleRule){let n=l.style.getPropertyValue("font-family");try{n.includes("var(")&&e.matches(l.selectorText)&&(t=n)}catch{}}else"cssRules"in l&&n(l.cssRules)};for(let t of e.ownerDocument.styleSheets)try{n(t.cssRules)}catch{}return t}(n),o.fontFamily,e=>o.getPropertyValue(e));i.textContent=s.label,p.textContent=s.note,t.title=s.title,r.toggleAttribute("data-unresolved",s.label.endsWith(" unresolved")),a.style.fontFamily=i.style.fontFamily=o.fontFamily};s=d,t.addEventListener("input",d),t.addEventListener("blur",d);let c=new MutationObserver(()=>n.isConnected?d():c.disconnect());c.observe(l.element,{attributeFilter:["style","class"]}),d(),n.append(o,r)}let p=()=>l.element.style.getPropertyValue(n.property),d={field:n,declared:p,seen:p(),set(e){c(()=>{l.begin(t,n.property),l.apply(t,n.property,e),l.commit(t,n.property)}),i(e)},keep(e){c(()=>{l.apply(t,n.property,e),l.commit(t,n.property,!1)}),i(e)},refresh(){d.seen=p(),"length"===n.kind?i(d.seen||getComputedStyle(l.element).getPropertyValue(n.property)):a()}},c=e=>{o=t;try{e()}finally{o=void 0,d.seen=p()}};return r.set(t,d),c}function s(e,t){for(let n of e.querySelectorAll(".design-field > [data-property]")){let e=r.get(n);e&&n!==o&&!t(n)&&n.getRootNode().activeElement!==n&&e.declared()!==e.seen&&e.refresh()}}function i(e,t,o){if(!(o instanceof HTMLInputElement||o instanceof HTMLSelectElement))return;let a=r.get(o);return!a&&(o instanceof HTMLSelectElement||"number"===o.type)||"select"===a?.field.kind||"opacity"===t?void 0:{get value(){return!/color|^(fill|stroke)$/.test(t)&&e.style.getPropertyValue(t).trim()||getComputedStyle(e).getPropertyValue(t).trim()},field:a?.field,onPreview(o){let l=n(e,t);return e.style.setProperty(t,o,"important"),l.restore},onSelect(e){if(a&&"color"!==a.field.kind)return a.set(e);o.dispatchEvent(new Event("focus")),o.value=e,o.dispatchEvent(new Event("input",{bubbles:!0})),o.dispatchEvent(new Event("change",{bubbles:!0}))},onCommit(e){if(l.has(o)||o.dispatchEvent(new Event("focus")),l.add(o),a&&"color"!==a.field.kind)return a.keep(e);o.value=e,o.dispatchEvent(new Event("input",{bubbles:!0}))},onDone(){l.delete(o)&&o.dispatchEvent(new Event("change",{bubbles:!0}))},onCancel(){l.delete(o)&&o.dispatchEvent(new KeyboardEvent("keydown",{key:"Escape",bubbles:!0}))}}}function p(e,n){let o=n.value.trim();return"color"===e.kind?t(e.property,o):"length"===e.kind?o?t(e.property,/^-?[\d.]+$/.test(o)?`${o}px`:o):null:"size"===e.kind||"line-height"===e.property?/^(auto|normal|(?:\d+(?:\.\d+)?)(?:px|%|vw|vh|rem|em)?)$/.test(o)?"size"===e.kind&&/^[\d.]+$/.test(o)?`${o}px`:o:null:t(e.property,"letter-spacing"===e.property&&/^-?[\d.]+$/.test(o)?`${o}px`:o)}export{a,s as b,i as c,p as d};
@@ -1 +0,0 @@
1
- function e(e){return!!e&&"string"==typeof e.id&&"string"==typeof e.name&&"boolean"==typeof e.verified&&[e.avatarUrl,e.accentColor].every(e=>void 0===e||"string"==typeof e)}function t(t){return Array.isArray(t)&&t.every(t=>t&&"string"==typeof t.id&&"string"==typeof t.page&&"boolean"==typeof t.resolved&&Number.isFinite(t.createdAt)&&Number.isFinite(t.updatedAt)&&(null===t.resolvedBy||e(t.resolvedBy))&&t.anchor&&(!("context"in t.anchor)||function(e){if(void 0===e)return!0;if(!e||"object"!=typeof e||Array.isArray(e))return!1;let t={tag:32,role:80,label:160,nearby:160,classes:200,selectedText:200,styles:500,scope:2e3};return Object.entries(e).every(([e,o])=>"number"==typeof t[e]&&"string"==typeof o&&o.length<=t[e])}(t.anchor.context))&&"string"==typeof t.anchor.selector&&"string"==typeof t.anchor.text&&[t.anchor.x,t.anchor.y,t.anchor.width,t.anchor.height,t.anchor.pageX,t.anchor.pageY,t.anchor.viewportWidth].every(Number.isFinite)&&Array.isArray(t.comments)&&t.comments.every(t=>t&&"string"==typeof t.id&&"string"==typeof t.body&&e(t.author)&&Number.isFinite(t.createdAt)&&(null===t.editedAt||Number.isFinite(t.editedAt))&&t.reactions&&"object"==typeof t.reactions&&!Array.isArray(t.reactions)&&Object.values(t.reactions).every(e=>Array.isArray(e)&&e.every(e=>"string"==typeof e))))}function o(e,t){if(!t||!Array.isArray(e))return e;let o=e=>"string"==typeof e?Object.hasOwn(t,e)?t[e]:void 0:e;return e.map(e=>e&&{...e,resolvedBy:o(e.resolvedBy),comments:Array.isArray(e.comments)&&e.comments.map(e=>e&&{...e,author:o(e.author)})})}function s(){return new r(0,"Could not read comments. Try again.","invalid_response")}var r=class extends Error{constructor(e,t,o){super(t),this.status=e,this.code=o}status;code},i=class{constructor(t){this.options=t;let o=new URL(t.sessionEndpoint??t.endpoint).href.replace(/\/$/,""),s=t.sessionDomain?.replace(/^\./,"")??"";this.cookieDomain=s&&(location.hostname===s||location.hostname.endsWith(`.${s}`))?s:"",this.cookieName=`${this.cookieDomain?"__Secure-":"__Host-"}bc-session-${encodeURIComponent(JSON.stringify([o,t.project]))}`,this.key=`branch-comments:${t.endpoint}:${t.project}`;let r=!1;try{let e=document.cookie.split("; ").find(e=>e.startsWith(`${this.cookieName}=`));r=void 0!==e,this.token=e?.slice(this.cookieName.length+1)||null}catch{}try{let t;try{t=JSON.parse(localStorage.getItem(this.userKey)??"null")}catch{}let o=localStorage.getItem(this.key)??(e(t?.user)&&"string"==typeof t.token?t.token:null);r?!this.token&&o&&this.clear():this.token=o,this.token&&t?.token===this.token&&e(t.user)&&(this.user=t.user)}catch{}try{let e=`bc-session-${encodeURIComponent(t.project)}`,o=location.hostname.match(/^[^.]+\.([^.]+\.(?:workers|pages)\.dev)$/)?.[1];for(let t of new Set(["",this.cookieDomain,o]))void 0!==t&&(document.cookie=`${e}=; Max-Age=0; Path=/${t?`; Domain=${t}`:""}`)}catch{}}options;token=null;user=null;transient=!1;revision;cachedThreads=[];reads=new AbortController;persistenceQueued=!1;persistenceBlocked=!1;key;cookieName;cookieDomain;get sessionKey(){return this.key}get userKey(){return`${this.key}:user`}rememberUser(){try{this.token&&this.user?localStorage.setItem(this.userKey,JSON.stringify({token:this.token,user:this.user})):localStorage.removeItem(this.userKey)}catch{}}cancelReads(){this.reads.abort(),this.reads=new AbortController}async request(e,t="GET",o,i){let n=new URL(e,this.options.endpoint.replace(/\/?$/,"/"));n.searchParams.set("project",this.options.project),n.searchParams.set("repo",this.options.repo),n.searchParams.set("branch",this.options.branch);let a={},h=this.token;h&&(a.Authorization=`Bearer ${h}`),void 0!==o&&(a["Content-Type"]=i??"application/json");let c="GET"===t?this.reads.signal:void 0,l=AbortSignal.timeout(15e3),u=await fetch(n,{method:t,headers:a,body:void 0===o?void 0:i?o:JSON.stringify(o),credentials:"omit",cache:"no-store",signal:c?AbortSignal.any([c,l]):l}).catch(e=>{throw e instanceof TypeError?!1===navigator.onLine?new r(0,"You’re offline.","offline"):new r(0,"Can’t connect to comments.","unreachable"):e});c?.throwIfAborted();let d=await u.json().catch(()=>{if(c?.throwIfAborted(),u.ok)throw s();return{}});if(c?.throwIfAborted(),u.ok&&(!d||"object"!=typeof d||Array.isArray(d)))throw s();if(!u.ok)throw 401===u.status&&h&&this.token===h&&this.clear(),new r(u.status,"site_not_approved"===d?.code?"Comments aren’t turned on for this site yet.":d?.error??"Could not load comments.",d?.code);return d}get listKey(){return`${this.key}:${JSON.stringify([this.options.repo,this.options.branch])}:threads`}cached(){try{let e=JSON.parse(localStorage.getItem(this.listKey)??"null");return e&&(e.threads=o(e.threads,e.authors)),e?.token!==(this.token??"")||!t(e.threads)||void 0!==e.revision&&(!Number.isSafeInteger(e.revision)||e.revision<0)?null:(this.revision=e.revision,this.cachedThreads=e.threads,e.threads)}catch{return null}}persist(){this.persistenceQueued||this.persistenceBlocked||(this.persistenceQueued=!0,queueMicrotask(()=>{this.persistenceQueued=!1;try{let e=Object.create(null),t=[],o=0,s=!1,r=this.options.page?.()??location.pathname,i=[...this.cachedThreads].sort((e,t)=>+(t.page===r)-+(e.page===r));for(let r of i){let i=Object.create(null),n=t=>(t&&(i[t.id]={...e[t.id],...i[t.id],...t}),t?.id??null),a={...r,resolvedBy:n(r.resolvedBy),comments:r.comments.map(e=>({...e,author:n(e.author)}))},h=JSON.stringify(a).length+Object.entries(i).reduce((t,[o,s])=>t+JSON.stringify([o,s]).length-(e[o]?JSON.stringify([o,e[o]]).length:0),0)+2;o+h>25e4?s=!0:(o+=h,Object.assign(e,i),t.push(a))}if(s&&!t.length)return void localStorage.removeItem(this.listKey);localStorage.setItem(this.listKey,JSON.stringify({token:this.token??"",revision:s?void 0:this.revision,threads:t,authors:e}))}catch{this.persistenceBlocked=!0;try{localStorage.removeItem(this.listKey)}catch{}}}))}async list(){let e,i,n=this.token,a=this.reads.signal,h=[],c=0;for(;null!==c;){let l=await this.request(`threads?authors=1&offset=${c}${e?`&cursor=${encodeURIComponent(e)}`:""}${0===c&&void 0!==this.revision?`&revision=${this.revision}`:""}`).catch(e=>{throw e instanceof r&&403===e.status&&this.token===n&&(this.revision=void 0,this.cachedThreads=[],this.persist()),e});if(a.throwIfAborted(),l.threads=o(l.threads,l.authors),!0===l.notModified&&0===c&&void 0!==this.revision)return this.cachedThreads;if(!t(l.threads)||null!=l.nextCursor&&("string"!=typeof l.nextCursor||l.nextCursor.length>200||l.nextCursor===e)||void 0!==l.revision&&(!Number.isSafeInteger(l.revision)||l.revision<0)||null!=l.next&&(!Number.isSafeInteger(l.next)||l.next<=c))throw s();0===c&&(i=l.revision),h.push(...l.threads??[]),e=l.nextCursor??void 0,c=l.next??null}return this.revision=i,this.cachedThreads=h,this.persist(),h}save(e){e.token!==this.token&&(this.cancelReads(),this.revision=void 0,this.cachedThreads=[]),this.token=e.token,this.user=e.user,this.rememberUser();let t=!1;try{localStorage.setItem(this.key,e.token),t=!0}catch{}this.transient=!this.writeCookie(e.token,3456e4)&&!t}writeCookie(e,t){if("https:"!==location.protocol)return;let o="Path=/; SameSite=Lax; Secure";try{return this.cookieDomain&&(document.cookie=`${this.cookieName}=; Max-Age=0; ${o}`),document.cookie=`${this.cookieName}=${e}; Max-Age=${t}; ${o}${this.cookieDomain?`; Domain=${this.cookieDomain}`:""}`,document.cookie.split("; ").includes(`${this.cookieName}=${e}`)}catch{}}clear(){this.cancelReads();try{localStorage.removeItem(this.listKey);for(let e of Object.keys(localStorage))e.startsWith(`${this.key}:`)&&localStorage.removeItem(e)}catch{}this.revision=void 0,this.cachedThreads=[],this.token=null,this.user=null,this.transient=!1,this.rememberUser(),this.writeCookie("",3456e4);try{localStorage.removeItem(this.key)}catch{}}async restore(){if(!this.token)return;let t=this.token,o=await this.request("me");if(this.token===t){if(!e(o.user))throw s();this.save({token:t,user:o.user})}}async guest(e){this.save(await this.request("auth/guest","POST",{name:e}))}async logout(){let e=this.request("me","DELETE");this.clear(),await e}};export{r as a,i as b};