@withone/connect 0.16.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -45,7 +45,7 @@ later: oneConnect.runAction(userId, …) ──► One, gr
45
45
  - [5 · Using the grant](#5--using-the-grant)
46
46
  - [6 · Errors](#6--errors)
47
47
  - [7 · Token mode](#7--token-mode)
48
- - [Security](#security) · [Troubleshooting](#troubleshooting) · [API reference](#api-reference)
48
+ - [Security](#security) · [Troubleshooting](#troubleshooting) · [Supported versions](#supported-versions) · [API reference](#api-reference) · [Support](#support)
49
49
 
50
50
  ## Choose how your server holds the grant
51
51
 
@@ -122,6 +122,16 @@ export const { GET } = createOneConnectRoutes(oneConnect, {
122
122
  });
123
123
  ```
124
124
 
125
+ `identifyUser` answers one question: which of **your** app's users clicked Connect? Return the id from your own session. One's page then signs the person in to **One** with their email and a code. Those are two different accounts, and the callback joins them:
126
+
127
+ ```
128
+ your session ── identifyUser ──► "user_123" which of your users is this?
129
+ One's page ── email + code ──► Maya on One whose tools are these?
130
+ callback ── saves Maya's grant on user_123 ──► later: runAction("user_123", …)
131
+ ```
132
+
133
+ `loginHintFor` only pre-fills the email on One's page. Nobody signed in? `identifyUser` returns null and the route sends them to `signInUrl` (or answers `401`).
134
+
125
135
  That file serves `/api/one/authorize` and `/api/one/callback`. For Express, Fastify, Koa or plain Node, `createOneConnectHandlers` from `@withone/connect/node` takes the same options and returns `{ authorize, callback }` to mount on those two paths.
126
136
 
127
137
  ## 4 · The button
@@ -147,6 +157,8 @@ import { ConnectButton } from "@withone/connect/react";
147
157
  | `size` | `sm`, `md` or `lg`. |
148
158
  | `fullWidth` | Fills its container. |
149
159
  | `theme` | `light`, `dark` or `auto`. `connectTheme` sets One's page. |
160
+ | `connector` | A connector slug (`gmail`). One's page opens that connector's connect screen first, then the usual list. |
161
+ | `returnTo` | Where this flow returns to: a path on your app, such as `/chat/42`. Overrides the server's `returnTo` for this flow only. |
150
162
  | `label` / `connectedLabel` | Button text, and the text once connected. |
151
163
  | `disabled` | Not clickable. |
152
164
  | `onSuccess` / `onError` / `onCancel` | How the flow ended. |
@@ -227,6 +239,26 @@ The user lands back on your `returnTo` page (`/` unless you set it) with the out
227
239
 
228
240
  Show your own text for each code and never text taken from the URL, since anyone can craft a link. Remove the parameters after reading them so a refresh does not repeat the message. To theme One's page, add `#one_theme=dark` or `#one_theme=light` to the link.
229
241
 
242
+ ### One connector first
243
+
244
+ A chat or a settings page often needs a single tool connected now, not the whole list. Pass `connector`, and `returnTo` when the flow must come back to the page it started on:
245
+
246
+ ```tsx
247
+ const { open } = useOneConnect({
248
+ authorizeUrl: "/api/one/authorize",
249
+ connector: "gmail",
250
+ returnTo: "/chat/42",
251
+ });
252
+
253
+ <button onClick={open}>Connect Gmail</button>
254
+ ```
255
+
256
+ One's page still signs the user in and asks for the space. Then, instead of the list, it opens Gmail's connect screen straight away. The list follows with everything the user has connected, so they confirm the whole grant as always.
257
+
258
+ - `connector` is a slug from One's catalog (`gmail`, `google-calendar`, `stripe`). A slug your permission set does not offer, or one the user already connected in that space, is ignored and the page opens on the list.
259
+ - `returnTo` must be a path on your app. Anything else is ignored and the server's `returnTo` applies.
260
+ - Both work the same on `ConnectButton`, `createConnectFlow` and a plain link: `<a href="/api/one/authorize?one_return_to=%2Fchat%2F42#one_connector=gmail">`.
261
+
230
262
  ## 5 · Using the grant
231
263
 
232
264
  Work the way the One CLI does: find the action, read its knowledge, run it.
@@ -356,11 +388,26 @@ The job renews both tokens when either is within 3 days of expiring. Without it,
356
388
  |---|---|
357
389
  | Signed-out users see "Sign in to your account before connecting One." | `identifyUser` returned null. Set `signInUrl` to send them to your sign-in page. |
358
390
  | Every attempt ends with `expired` | The state cookie did not reach the callback. Serve both routes from the same directory (`/api/one/authorize` and `/api/one/callback`) on the origin of `ONE_REDIRECT_URI`. An attempt also expires after 30 minutes. |
359
- | Every attempt ends with `failed` | Usually One refused the code exchange. Check that `ONE_REDIRECT_URI` matches the registered URL exactly and that the client secret is current. Log `result.message` with `onComplete` on the routes to see why. |
391
+ | One answers `invalid redirect_uri` instead of showing its page | `ONE_REDIRECT_URI` is not registered on the app character for character (scheme, host, port, path). Register it, or fix the variable. |
392
+ | Every attempt ends with `failed` | One refused the code exchange, most often because the client secret is wrong or was rotated. Log `result.message` with `onComplete` on the routes to see the reason. |
360
393
  | Every call fails with `request_failed`: "One did not accept the connect key" | The key is not this app's, or it was revoked. Create a key on the app's page and update `ONE_CONNECT_KEY`. |
361
394
  | Every user's calls throw `reconnect_required` | The app is deactivated. Check that it is active in the dashboard. |
362
395
  | A call returns `403` with `blockedByGrant: true` | The action is outside what the user granted. Ask for it in your permission set; users see new tools the next time they connect. |
363
396
 
397
+ ## Supported versions
398
+
399
+ | | |
400
+ |---|---|
401
+ | Node.js | 18 or later |
402
+ | React | 17 or later (optional peer dependency) |
403
+ | Vue | 3 or later (optional peer dependency) |
404
+ | Svelte | 3 or later (the `use:` action); no peer dependency |
405
+ | `@withone/connect/next` | Any server with web `Request` and `Response`: Next.js App Router, Remix, SvelteKit, Hono, Bun |
406
+ | `@withone/connect/node` | Node's `http` request and response: Express, Fastify (`reply.raw`), Koa (`ctx.req`/`ctx.res`), plain Node |
407
+ | Browsers | Any browser with Shadow DOM and custom elements; the build targets `> 0.25%, not dead` |
408
+
409
+ **Versioning.** Until 1.0, a minor version may remove an API that an earlier minor deprecated; every deprecation is marked in the types and in the [release notes](CHANGELOG.md), and stays for at least one minor. Patch versions only fix bugs or docs.
410
+
364
411
  ## API reference
365
412
 
366
413
  ### `createOneConnect(config)` · `@withone/connect/server`
@@ -411,6 +458,14 @@ The job renews both tokens when either is within 3 days of expiring. Without it,
411
458
  | `createConnectFlow(options)` | Your own button anywhere. |
412
459
  | `readConnectReturn()` | How this page load ended a flow, or null. |
413
460
 
461
+ `useOneConnect` and `createConnectFlow` take `authorizeUrl`, `connectTheme`, `connector`, `returnTo`, `onSuccess`, `onError` and `onCancel`.
462
+
463
+ ## Support
464
+
465
+ - Bugs and questions: [GitHub issues](https://github.com/withoneai/connect/issues).
466
+ - Security issues: see [SECURITY.md](SECURITY.md). Please don't open a public issue.
467
+ - Everything else: hello@withone.ai.
468
+
414
469
  ## License
415
470
 
416
471
  GPL-3.0. See [LICENSE](LICENSE).
@@ -11,6 +11,14 @@ export declare const LEGACY_MESSAGE_PARAM = "one_connect_message";
11
11
  * A fragment never reaches any server and survives the whole redirect
12
12
  * chain, so the app's backend forwards nothing. */
13
13
  export declare const THEME_PARAM = "one_theme";
14
+ /** Fragment key naming the connector One's page opens first. Sign-in
15
+ * and the space step run as always; then that connector's connect
16
+ * screen opens instead of the list, and the list follows with
17
+ * everything the user has connected. */
18
+ export declare const CONNECTOR_PARAM = "one_connector";
19
+ /** Query param on the app's own authorize route naming where this one
20
+ * flow returns to. The route reads it; it never reaches One. */
21
+ export declare const RETURN_TO_PARAM = "one_return_to";
14
22
  /** One's connector logos, by slug. */
15
23
  export declare const CONNECTOR_ASSETS_URL = "https://assets.withone.ai/connectors";
16
24
  /** One's production API. Point `oneApiUrl` elsewhere for development. */
package/dist/index.cjs.js CHANGED
@@ -1 +1 @@
1
- "use strict";const e="one_connect",t="one_connect_error",n={declined:"You cancelled the connection.",expired:"The connection attempt expired. Please try again.",failed:"The connection could not be completed. Please try again."};function o(o){const i=new URLSearchParams(o),r=i.get(e);if("success"===r)return{status:r};if("error"!==r)return null;const a=i.get(t),l=null!==(s=a)&&Object.prototype.hasOwnProperty.call(n,s)?a:"failed";var s;return{status:r,code:l,message:n[l]}}const i=[e,t,"one_connect_message"];function r(e){const t=new URLSearchParams(e);return i.some(e=>t.has(e))}let a,l=!1,s=!1,c=!1;const d=[];function p(){return u()}function u(){return"undefined"==typeof window?null:(void 0===a&&(a=o(window.location.search),(a||r(window.location.search))&&function(){const e=()=>{r(window.location.search)&&window.history.replaceState(window.history.state,"",function(e){const t=new URLSearchParams(e.search);for(const e of i)t.delete(e);const n=t.toString();return`${e.pathname}${n?`?${n}`:""}${e.hash}`}(window.location))};e();for(const t of[50,500,2e3])window.setTimeout(e,t)}()),a)}function h(e){let t=e,n=!1;const o={deliver:e=>{try{var n,o,i,r,a,l;"success"===e.status?null===(n=(o=t).onSuccess)||void 0===n||n.call(o):null===(i=(r=t).onError)||void 0===i||i.call(r,null!==(a=e.message)&&void 0!==a?a:"",null!==(l=e.code)&&void 0!==l?l:"failed")}catch{}},restored:()=>{if(n){n=!1;try{var e,o;null===(e=(o=t).onCancel)||void 0===e||e.call(o)}catch{}}}};return"undefined"!=typeof window&&(d.push(o),c||"undefined"==typeof window||(c=!0,window.addEventListener("pageshow",e=>{if(e.persisted)for(const e of[...d])e.restored()})),function(){if(l||s)return;const e=u();e&&(s=!0,window.setTimeout(()=>{s=!1;const t=d[0];t&&!l&&(l=!0,t.deliver(e))},0))}()),{open:()=>{"undefined"!=typeof window&&(n=!0,window.location.assign((e=>{const t=e.connectTheme;try{const n=new URL(e.authorizeUrl,window.location.origin);return t&&(n.hash=`one_theme=${t}`),n.toString()}catch{return e.authorizeUrl}})(t)))},update:e=>{t=e},destroy:()=>{const e=d.indexOf(o);e>=0&&d.splice(e,1)}}}function C(e,t,n){return(t=function(e){var t=function(e,t){if("object"!=typeof e||!e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var o=n.call(e,t);if("object"!=typeof o)return o;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:t+""}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function f(e){return e.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")}const b={"cal-com":"Cal.com","click-up":"ClickUp",clickup:"ClickUp",docusign:"DocuSign",elevenlabs:"ElevenLabs","fireflies-ai":"Fireflies.ai",github:"GitHub",gitlab:"GitLab",hubspot:"HubSpot","linked-in":"LinkedIn",linkedin:"LinkedIn","one-drive":"OneDrive",onedrive:"OneDrive",openai:"OpenAI","otter-ai":"Otter.ai",paypal:"PayPal",posthog:"PostHog",quickbooks:"QuickBooks",sharepoint:"SharePoint","spotify-web":"Spotify",teams:"Microsoft Teams","telegram-bot":"Telegram","whatsapp-business":"WhatsApp Business",woocommerce:"WooCommerce",x:"X","youtube-data":"YouTube",youtube:"YouTube"};function g(e){var t;return null!==(t=b[e])&&void 0!==t?t:e.split(/[-_]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(" ")}function v(e){return e?`https://assets.withone.ai/connectors/${e}.svg`:""}function m(e){var t,n,o,i;const r="string"==typeof e?{slug:e}:e,a=null!==(t=r.slug)&&void 0!==t&&t.trim()?f(r.slug):null!==(n=r.name)&&void 0!==n&&n.trim()?f(r.name):"";return a?{slug:a,name:(null===(o=r.name)||void 0===o?void 0:o.trim())||g(a),imageUrl:(null===(i=r.imageUrl)||void 0===i?void 0:i.trim())||v(a)}:null}function x(e){const t=null==e?void 0:e.trim();if(!t)return[];if(t.startsWith("["))try{const e=JSON.parse(t);return Array.isArray(e)?e.filter(e=>"string"==typeof e||"object"==typeof e&&null!==e):[]}catch{return[]}return t.split(",").map(e=>e.trim()).filter(Boolean)}const w="#CCFF00",y="#0A0C0B",k="#FFFFFF",A=`\n:host{display:inline-block;vertical-align:middle;max-width:100%}\n:host([data-full-width]),:host([full-width]:not([full-width="false"])),\n:host([data-variant="block"]),:host([variant="block"]){display:block;width:100%}\n.b{all:unset;box-sizing:border-box;position:relative;display:inline-flex;align-items:center;gap:var(--gap);\n max-width:100%;cursor:pointer;user-select:none;-webkit-tap-highlight-color:transparent;\n font-family:var(--one-connect-font,inherit);font-size:var(--fs);font-weight:500;line-height:1.2;letter-spacing:-.01em;\n padding:var(--pad);border-radius:var(--one-connect-radius,12px);background:var(--bg);color:var(--fg);\n box-shadow:var(--shadow);transition:box-shadow .2s var(--ease),background-color .2s var(--ease),opacity .2s var(--ease)}\n.b[data-full-width]{display:flex;width:100%;justify-content:center}\n.b:focus-visible{outline:2px solid var(--ring);outline-offset:2px}\n.b:hover{box-shadow:var(--shadow-hover)}\n.b[disabled]{cursor:not-allowed;opacity:.5;box-shadow:none}\n.b[aria-busy="true"]{cursor:progress}\n.b{--ease:cubic-bezier(.2,.9,.25,1)}\n.b[data-size="sm"]{--fs:13px;--pad:8px 12px 8px 10px;--gap:8px;--chip:18px;--logo:12px}\n.b[data-size="md"]{--fs:14.5px;--pad:12px 16px 12px 14px;--gap:12px;--chip:22px;--logo:14px}\n.b[data-size="lg"]{--fs:16px;--pad:14px 20px 14px 16px;--gap:12px;--chip:26px;--logo:16px}\n.b[data-theme="light"],.b[data-theme="auto"]{--ink-bg:${y};--ink-fg:${k};--surface:${k};--surface-fg:${y};\n --muted:#5B6560;--line:#D5DAD7;--ring:${y};--shadow-base:0 1px 2px rgba(10,12,11,.08),0 4px 14px rgba(10,12,11,.06);\n --shadow-strong:0 1px 2px rgba(10,12,11,.12),0 6px 18px rgba(10,12,11,.1)}\n.b[data-theme="dark"]{--ink-bg:#F2F5F3;--ink-fg:${y};--surface:#101312;--surface-fg:#F2F5F3;\n --muted:#9AA39E;--line:#2A302D;--ring:${w};--shadow-base:0 1px 2px rgba(0,0,0,.4),0 8px 24px rgba(0,0,0,.35);\n --shadow-strong:0 1px 2px rgba(0,0,0,.5),0 10px 28px rgba(0,0,0,.45)}\n@media (prefers-color-scheme:dark){.b[data-theme="auto"]{--ink-bg:#F2F5F3;--ink-fg:${y};--surface:#101312;--surface-fg:#F2F5F3;\n --muted:#9AA39E;--line:#2A302D;--ring:${w};--shadow-base:0 1px 2px rgba(0,0,0,.4),0 8px 24px rgba(0,0,0,.35);\n --shadow-strong:0 1px 2px rgba(0,0,0,.5),0 10px 28px rgba(0,0,0,.45)}}\n.b[data-variant="default"]{--bg:var(--ink-bg);--fg:var(--ink-fg);--shadow:var(--shadow-base);--shadow-hover:var(--shadow-strong)}\n.b[data-variant="accent"]{--bg:var(--one-connect-accent,${w});--fg:var(--one-connect-accent-fg,${y});\n --shadow:0 1px 2px rgba(10,12,11,.1);--shadow-hover:0 1px 2px rgba(10,12,11,.12),0 6px 18px rgba(10,12,11,.12)}\n.b[data-variant="block"]{--bg:var(--surface);--fg:var(--surface-fg);--shadow:inset 0 0 0 1px var(--line);\n --shadow-hover:inset 0 0 0 1px var(--muted);flex-direction:column;align-items:stretch;gap:0;\n width:100%;max-width:420px;text-align:left;padding:16px;border-radius:var(--one-connect-radius,14px)}\n.b[data-variant="block"][data-full-width]{max-width:none}\n.stack{display:inline-flex;align-items:center;flex-shrink:0}\n.chip{width:var(--chip);height:var(--chip);border-radius:6px;display:grid;place-items:center;overflow:hidden;\n margin-left:-7px;position:relative;background:${k};color:${y};box-shadow:0 0 0 1.5px var(--bg);\n transition:margin-left .28s var(--ease)}\n.chip:first-child{margin-left:0}\n.b[data-variant="block"] .chip{box-shadow:0 0 0 1.5px var(--bg),0 0 0 2.5px var(--line)}\n.chip img{width:var(--logo);height:var(--logo);display:block;object-fit:contain}\n.chip.more,.chip.letter{font:500 9px/1 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:-.02em}\n.chip.letter{font-size:10px;font-weight:600}\n.b:hover .chip{margin-left:-2px}.b:hover .chip:first-child{margin-left:0}\n.label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.icon{display:inline-flex;flex-shrink:0}\n.arrow{opacity:.55;transition:transform .2s var(--ease),opacity .2s var(--ease)}\n.b:hover .arrow{transform:translateX(2px);opacity:.85}\n.spinner{width:16px;height:16px;border-radius:50%;border:2px solid currentColor;border-top-color:transparent;\n opacity:.7;animation:spin .7s linear infinite;flex-shrink:0}\n@keyframes spin{to{transform:rotate(360deg)}}\n.top{display:flex;align-items:center;justify-content:space-between;gap:12px}\n.title{font-size:15px;font-weight:600;letter-spacing:-.01em}\n.sub{font-size:13px;line-height:1.5;margin-top:6px;font-weight:400;color:var(--muted)}\n.foot{margin-top:14px;padding-top:12px;display:flex;align-items:center;gap:6px;font-size:11px;font-weight:400;\n color:var(--muted);border-top:1px solid var(--line)}\n.lockup{display:inline-flex;color:var(--surface-fg)}\n.sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}\n@media (prefers-reduced-motion:reduce){.b,.chip,.arrow{transition:none}.spinner{animation-duration:1.6s}}\n@media (forced-colors:active){.b{border:1px solid ButtonText}.b:focus-visible{outline-color:Highlight}}\n`;let S=null;const L=(e,t,n)=>{const o=document.createElement(e);return t&&(o.className=t),void 0!==n&&(o.textContent=n),o},E=(e,t="icon")=>{const n=L("span",t);return n.innerHTML=e,n};function z(e){var t;const n=(null!=(o=null!==(t=e.logos)&&void 0!==t?t:e.platforms)?o:[]).map(m).filter(e=>null!==e);var o;if(0===n.length)return null;const i=L("span","stack");i.setAttribute("aria-hidden","true");for(const e of n.slice(0,3)){const t=L("span","chip");t.title=e.name;const n=L("img");n.alt="",n.decoding="async",n.src=e.imageUrl,n.addEventListener("error",()=>{n.remove(),t.classList.add("letter"),t.textContent=e.name.charAt(0).toUpperCase()}),t.appendChild(n),i.appendChild(t)}const r=n.length-3;return r>0&&i.appendChild(L("span","chip more",`+${r}`)),i}const F=(e,t)=>({authorizeUrl:e.authorizeUrl,connectTheme:e.connectTheme,...t});function M(e,t){var n;const o=null!==(n=e.shadowRoot)&&void 0!==n?n:e.attachShadow({mode:"open"});!function(e){if("undefined"!=typeof CSSStyleSheet&&"replaceSync"in CSSStyleSheet.prototype&&"adoptedStyleSheets"in e)try{return S||(S=new CSSStyleSheet,S.replaceSync(A)),void(e.adoptedStyleSheets=[S])}catch{}const t=document.createElement("style");t.textContent=A,e.appendChild(t)}(o);let i=t,r=!1,a=!1,l=null;const s=L("button","b");s.type="button",s.setAttribute("part","button");const c=L("span","sr");c.setAttribute("role","status"),c.setAttribute("aria-live","polite"),o.append(s,c);const d=()=>{return r?"connecting":void 0!==i.connected?i.connected?"connected":"idle":"success"===(null===(e=p())||void 0===e?void 0:e.status)?"connected":"idle";var e},u={onSuccess:()=>{var e,t;return null===(e=(t=i).onSuccess)||void 0===e?void 0:e.call(t)},onError:(e,t)=>{var n,o;return null===(n=(o=i).onError)||void 0===n?void 0:n.call(o,e,t)},onCancel:()=>{var e,t;r=!1,f(),null===(e=(t=i).onCancel)||void 0===e||e.call(t)}},C=h(F(i,u)),f=()=>{var e,t,n,o,r;if(a)return;const p=d(),u=null!==(e=i.variant)&&void 0!==e?e:"default",h="connecting"===p?"Connecting…":"connected"===p?null!==(t=i.connectedLabel)&&void 0!==t?t:"Connected":null!==(n=i.label)&&void 0!==n?n:"Connect your apps";s.dataset.variant=u,s.dataset.size=null!==(o=i.size)&&void 0!==o?o:"md",s.dataset.theme=null!==(r=i.theme)&&void 0!==r?r:"light",s.dataset.state=p,s.toggleAttribute("data-full-width",Boolean(i.fullWidth)),s.disabled=Boolean(i.disabled),s.setAttribute("aria-busy",String("connecting"===p)),"connecting"===p?s.setAttribute("aria-disabled","true"):s.removeAttribute("aria-disabled");const C="idle"===p?z(i):null,f="connecting"===p?L("span","spinner"):"connected"===p?E('<svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M3 8.5l3.5 3.5L13 5"/></svg>'):C;if(s.replaceChildren(),s.removeAttribute("aria-labelledby"),s.removeAttribute("aria-describedby"),"block"===u){const e=L("span","top"),t=L("span","title",h);if(t.id="one-connect-title",t.setAttribute("part","label"),e.appendChild(t),f&&e.appendChild(f),s.appendChild(e),s.setAttribute("aria-labelledby",t.id),i.description){const e=L("span","sub",i.description);e.id="one-connect-description",s.appendChild(e),s.setAttribute("aria-describedby",e.id)}const n=L("span","foot");n.setAttribute("aria-hidden","true"),n.append(L("span","","Secured by"),E('<svg viewBox="0 0 3152 990" width="35" height="11" fill="none" aria-hidden="true" focusable="false"><path d="M1698.02 793.203C1525.75 793.203 1401 666.834 1401 495.102C1401 323.909 1524.67 197 1698.02 197C1870.83 197 1996.12 323.909 1996.12 495.102C1996.12 666.834 1869.75 793.203 1698.02 793.203ZM1698.02 694.916C1801.71 694.916 1884.88 615.53 1884.88 495.102C1884.88 374.133 1801.71 295.827 1698.02 295.827C1594.87 295.827 1511.71 373.053 1511.71 495.102C1511.71 616.61 1595.41 694.916 1698.02 694.916Z" fill="currentColor"/><path d="M2326.71 197.54C2480.62 197.54 2565.95 289.887 2565.95 467.56V779.702H2455.24V468.64C2455.24 361.172 2411.5 292.587 2308.35 292.587C2217.63 292.587 2140.4 356.852 2140.4 484.841V779.702H2030.77V211.041H2140.4V272.065C2185.76 225.082 2248.41 197.54 2326.71 197.54Z" fill="currentColor"/><path d="M3151.98 493.481C3151.98 514.003 3150.36 520.483 3148.74 529.124H2700.51C2715.63 637.672 2794.47 686.815 2922.46 686.815C3031.01 686.815 3099.6 650.633 3116.88 643.072V747.84C3100.68 755.4 3023.45 793.203 2908.96 793.203C2699.97 793.203 2588.18 661.434 2588.18 497.802C2588.18 332.55 2702.67 197 2871.7 197C3031.55 197 3151.98 317.969 3151.98 493.481ZM2876.02 300.688C2784.75 300.688 2720.49 345.511 2702.67 434.617H3050.45C3034.79 344.971 2967.29 300.688 2876.02 300.688Z" fill="currentColor"/><path d="M537.494 782.175C641.011 827.7 767.922 858.83 880.501 839.875C983.155 822.599 1069.64 764.946 1094.39 659.271C1114.47 573.493 1088.54 481.273 1047.27 405.311C983.124 287.246 874.768 183.791 759.847 114.657C644.926 45.5225 507.181 -5.02605 372.102 0.398669C289.698 3.69665 205.938 26.536 146.544 85.6685C112.069 119.989 88.3818 171.231 83.1266 219.823C78.1642 265.64 84.3749 310.317 99.8478 354.007C168.243 547.14 354.009 701.467 537.51 782.191L537.494 782.175ZM751.956 818.053C583.05 796.2 415.7 707.108 292.472 593.004C222.536 528.246 159.366 444.979 125.985 355.471C102.961 293.734 96.3956 223.367 122.41 161.969C137.158 127.14 160.367 98.244 190.743 75.9133C275.581 13.5752 395.819 6.99464 495.977 26.8596C608.848 49.252 713.875 99.4615 806.712 166.515C907.085 239.025 999.537 339.922 1048.42 454.627C1072.45 511.001 1083.99 570.103 1075.64 630.869C1067.38 690.957 1034.57 742.353 983.987 775.379C917.626 818.715 830.861 828.255 751.972 818.053H751.956Z" fill="currentColor"/><path d="M1103.27 661.228C1086.68 755.313 1024.9 818.622 934.021 848.69C821.751 885.846 685.146 860.263 576.251 818.915C452.515 771.942 340.336 699.91 245.157 607.813C209.002 572.83 177.255 534.456 148.837 493.031C100.384 422.402 61.7024 335.19 65.8326 248.071C68.2213 197.769 83.987 159.241 111.403 116.938C45.8289 171.308 31.404 262.511 47.1543 342.002C53.4728 373.841 62.9815 403.23 76.528 432.958C100.338 485.202 130.914 532.992 167.747 577.238C255.452 682.573 367.83 765.13 491.073 824.124C614.317 883.118 769.307 920.691 900.471 889.128C985.788 868.601 1061.47 816.095 1090.83 730.856C1098.18 708.71 1104.61 686.564 1103.25 661.244L1103.27 661.228Z" fill="currentColor"/><path d="M883.297 963.502C923.15 947.074 960.877 926.022 988.309 893.967C954.265 917.839 920.931 934.807 882.403 944.993C751.747 979.53 595.123 942.589 474.731 886.57C422.102 862.082 372.617 834.018 325.181 800.591C205.128 715.984 89.4825 597.996 36.7762 458.756C20.2092 414.973 11.7793 370.404 11.5327 323.739C11.4249 302.641 15.4627 283.747 19.0226 263.004C-2.52219 310.486 -3.66265 380.915 5.21419 431.617C32.0605 584.881 147.151 721.146 266.988 813.983C343.443 873.224 436.403 924.913 528.424 954.672C620.444 984.431 713.851 999.426 808.491 983.598C834.459 979.252 858.362 973.781 883.297 963.502Z" fill="currentColor"/><path d="M1045.09 830.737C1053.55 816.158 1061.75 802.95 1066.99 787.061C1043.75 824.541 1013.3 854.408 974.29 874.982C947.752 888.991 920.228 899.27 890.577 905.219C864.578 910.428 839.673 914.481 812.781 914.851C739.716 915.852 668.717 903.092 599.459 880.854C418.686 822.8 238.422 697.6 127.985 543.165C94.8819 496.87 68.8679 447.847 50.7135 394.031C28.1978 324.45 25.7782 258.69 53.4104 189.078C36.1345 211.825 26.9956 237.793 20.4151 264.916C18.3654 282.732 14.713 299.345 15.0828 317.561C15.9613 360.774 23.5436 402.692 38.477 443.562C73.1522 538.464 134.936 621.869 207.368 691.913C307.34 788.587 426.762 862.268 558.127 907.993C689.491 953.718 871.975 973.768 992.614 885.446C1013.28 870.312 1029.39 851.773 1045.07 830.752L1045.09 830.737Z" fill="currentColor"/><path d="M552.552 745.664C671.079 797.831 835.825 835.526 954.768 769.12C999.137 744.354 1031.99 705.626 1047.99 657.312C1086.75 540.264 1020.28 405.817 947.124 315.631C855.536 202.745 729.688 114.516 592.76 66.0323C506.349 35.4412 418.968 22.0797 328.211 37.46C262.313 48.6177 195.29 81.7054 157.563 138.234C118.912 196.133 115.891 270.785 136.758 335.882C176.519 459.926 276.769 570.763 381.01 646.277C434.995 685.391 491.662 718.864 552.567 745.664H552.552ZM210.162 422.955C199.898 402.381 189.141 382.701 184.733 360.385C182.267 347.918 184.625 333.477 184.564 320.64C184.44 293.223 194.072 269.059 209.992 247.93C219.609 235.17 229.456 224.844 243.018 215.906C341.218 151.179 476.051 175.991 576.763 223.904C661.971 264.435 737.394 321.534 796.11 395.862C836.919 447.52 871.193 513.634 880.502 579.501C888.238 634.272 873.243 695.485 826.763 729.189C807.853 742.905 785.045 751.721 761.728 755.974C721.921 763.217 688.802 758.008 649.565 748.916C594.27 736.094 542.488 715.212 492.279 688.889C441.977 662.521 396.745 631.483 353.008 595.436C314.372 563.597 280.252 537.845 248.458 498.007L248.274 497.837L221.504 461.945L211.379 445.84C194.103 418.408 177.398 391.346 165.238 361.202C151.291 326.604 142.676 291.852 143.678 254.279C146.19 160.564 203.766 96.7467 290.238 67.82C434.394 19.5985 611.561 79.4246 735.298 157.636C825.099 214.411 904.435 286.581 963.321 375.134C989.767 414.894 1010.42 456.998 1023.78 502.646C1049.84 591.66 1036.79 685.884 957.404 742.659C890.257 790.68 785.6 793.146 707.295 776.486C680.403 769.736 654.065 766.007 629.222 754.818C732.107 783.93 882.397 797.723 963.938 715.35C990.599 688.412 1007.55 656.218 1013.75 618.537C1020.87 575.232 1016.12 531.634 1002.62 489.931C985.498 437.071 956.34 384.026 922.405 340.289C876.911 281.665 823.188 230.531 762.468 187.981C681.112 130.975 588.783 88.887 490.799 71.0872C425.595 59.2514 349.463 60.4072 287.557 85.0959C256.441 97.5019 228.501 114.5 205.924 138.85C158.303 190.2 147.176 256.036 161.539 323.383C166.856 348.334 175.456 371.296 185.596 394.737C194.488 415.295 222.676 461.883 236.022 477.649L226.729 456.196L210.162 423.001V422.955ZM832.342 286.936C756.904 211.544 666.44 154.076 564.896 120.249C526.553 107.473 487.948 99.4899 447.648 96.084C401.26 92.1696 356.167 96.7313 312.215 111.341C222.337 141.208 169.399 217.277 175.255 312.333C177.567 324.847 179.555 335.774 180.603 348.503C152.971 264.944 174.454 175.236 251.356 125.581C310.797 87.2072 387.39 78.2071 456.694 86.7603C503.714 92.5549 555.387 106.656 599.078 124.317C706.016 167.546 800.764 234.615 876.741 321.395C912.002 361.664 942.085 405.756 963.876 454.532C996.779 528.166 1011.85 610.046 965.895 681.369C952.379 702.359 935.427 718.818 914.283 731.871C884.432 747.421 852.947 758.671 818.872 761.06C839.523 755.959 859.404 750.981 878.637 740.424C929.186 717.061 964.601 671.567 974.818 616.488C987.671 547.245 964.693 475.429 930.881 415.357C903.834 367.305 871.471 326.049 832.311 286.905L832.342 286.936ZM890.673 420.18C861.623 370.387 825.515 327.621 783.288 287.999C721.659 230.161 650.028 185.345 570.598 156.033C513.623 135.013 454.506 124.394 393.786 128.108C353.316 130.59 315.728 139.867 280.498 159.516C245.268 179.166 216.819 204.918 201.023 240.394L188.617 268.242C204.583 180.445 278.325 132.054 361.931 119.355C412.757 111.634 462.658 116.643 512.421 129.048C596.905 150.116 674.1 189.923 743.45 242.028C816.607 296.999 885.526 373.531 924.578 456.982C949.713 510.675 965.094 571.61 949.837 630.234C939.018 671.768 912.511 706.566 875.308 727.987C847.013 744.292 816.191 754.679 783.242 758.101C825.915 745.926 863.75 731.917 895.327 698.799C913.512 679.72 926.535 657.62 933.054 631.714C951.347 558.989 927.49 483.274 890.642 420.134L890.673 420.18ZM726.19 279.369C625.678 198.799 493.404 141.917 362.655 156.973C343.854 159.131 326.547 164.17 308.639 169.195C301.18 171.29 295.201 177.732 286.493 176.253C378.313 130.081 492.063 149.545 583.143 188.119C684.102 230.87 775.952 302.825 840.664 391.069C871.794 433.527 895.805 479.652 909.506 530.386C918.382 563.273 920.232 596.654 911.941 629.294C905.622 654.153 895.481 677.778 875.786 694.9C893.987 666.327 905.452 637.693 907.086 604.128C908.72 570.562 903.141 536.565 891.567 503.57C861.392 417.53 797.066 336.19 726.205 279.384L726.19 279.369Z" fill="currentColor"/></svg>',"lockup")),s.appendChild(n)}else{f&&s.appendChild(f);const e=L("span","label",h);e.setAttribute("part","label"),s.appendChild(e),"idle"===p&&s.appendChild(E('<svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M6 3l5 5-5 5"/></svg>',"icon arrow"))}var b,g;b=p,null!==l?b!==l&&(l=b,c.textContent="connecting"===b?"Connecting to One…":"connected"===b?null!==(g=i.connectedLabel)&&void 0!==g?g:"Connected":""):l=b};return s.addEventListener("click",()=>{a||i.disabled||r||(r=!0,f(),C.open())}),f(),{update:e=>{i=e,C.update(F(i,u)),f()},destroy:()=>{a=!0,C.destroy(),o.replaceChildren()}}}const $=["authorize-url","logos","platforms","connected","disabled","variant","size","full-width","theme","connect-theme","label","connected-label","description"];function B(e,t,n){const o=e.getAttribute(t);return o&&n.includes(o)?o:void 0}const T=(e,t)=>e.hasAttribute(t)?"false"!==e.getAttribute(t):void 0;function U(){if("undefined"!=typeof window&&"undefined"!=typeof customElements&&!customElements.get("one-connect-button")){class e extends HTMLElement{constructor(...e){super(...e),C(this,"onSuccess",null),C(this,"onError",null),C(this,"onCancel",null),C(this,"handle",null)}connectedCallback(){this.sync()}disconnectedCallback(){var e;null===(e=this.handle)||void 0===e||e.destroy(),this.handle=null}attributeChangedCallback(){this.isConnected&&this.sync()}props(e){var t,n,o,i;return{authorizeUrl:e,logos:x(null!==(t=this.getAttribute("logos"))&&void 0!==t?t:this.getAttribute("platforms")),connected:T(this,"connected"),disabled:T(this,"disabled"),variant:B(this,"variant",["default","accent","block"]),size:B(this,"size",["sm","md","lg"]),fullWidth:T(this,"full-width"),theme:B(this,"theme",["light","dark","auto"]),connectTheme:B(this,"connect-theme",["light","dark"]),label:null!==(n=this.getAttribute("label"))&&void 0!==n?n:void 0,connectedLabel:null!==(o=this.getAttribute("connected-label"))&&void 0!==o?o:void 0,description:null!==(i=this.getAttribute("description"))&&void 0!==i?i:void 0,onSuccess:()=>{var e;null===(e=this.onSuccess)||void 0===e||e.call(this),this.dispatchEvent(new CustomEvent("success"))},onError:(e,t)=>{var n;null===(n=this.onError)||void 0===n||n.call(this,e,t),this.dispatchEvent(new CustomEvent("error",{detail:{message:e,code:t}}))},onCancel:()=>{var e;null===(e=this.onCancel)||void 0===e||e.call(this),this.dispatchEvent(new CustomEvent("cancel"))}}}sync(){const e=this.getAttribute("authorize-url");var t;if(!e)return null===(t=this.handle)||void 0===t||t.destroy(),void(this.handle=null);const n=this.props(e);this.handle?this.handle.update(n):this.handle=M(this,n)}}C(e,"observedAttributes",[...$]),customElements.define("one-connect-button",e)}}U(),exports.createConnectFlow=h,exports.mountConnectButton=function(e,t){const n=document.createElement("span");n.className="one-connect";const o=e=>{var t;n.setAttribute("data-variant",null!==(t=e.variant)&&void 0!==t?t:"default"),n.toggleAttribute("data-full-width",Boolean(e.fullWidth))};o(t),e.appendChild(n);const i=M(n,t);return{update:e=>{o(e),i.update(e)},destroy:()=>{i.destroy(),n.remove()}}},exports.readConnectReturn=p,exports.registerConnectButton=U,exports.renderConnectButton=M;
1
+ "use strict";const e="one_connect",t="one_connect_error",n={declined:"You cancelled the connection.",expired:"The connection attempt expired. Please try again.",failed:"The connection could not be completed. Please try again."};function o(o){const i=new URLSearchParams(o),r=i.get(e);if("success"===r)return{status:r};if("error"!==r)return null;const a=i.get(t),l=null!==(s=a)&&Object.prototype.hasOwnProperty.call(n,s)?a:"failed";var s;return{status:r,code:l,message:n[l]}}const i=[e,t,"one_connect_message"];function r(e){const t=new URLSearchParams(e);return i.some(e=>t.has(e))}let a,l=!1,s=!1,c=!1;const d=[];function u(){return p()}function p(){return"undefined"==typeof window?null:(void 0===a&&(a=o(window.location.search),(a||r(window.location.search))&&function(){const e=()=>{r(window.location.search)&&window.history.replaceState(window.history.state,"",function(e){const t=new URLSearchParams(e.search);for(const e of i)t.delete(e);const n=t.toString();return`${e.pathname}${n?`?${n}`:""}${e.hash}`}(window.location))};e();for(const t of[50,500,2e3])window.setTimeout(e,t)}()),a)}function h(e){let t=e,n=!1;const o={deliver:e=>{try{var n,o,i,r,a,l;"success"===e.status?null===(n=(o=t).onSuccess)||void 0===n||n.call(o):null===(i=(r=t).onError)||void 0===i||i.call(r,null!==(a=e.message)&&void 0!==a?a:"",null!==(l=e.code)&&void 0!==l?l:"failed")}catch{}},restored:()=>{if(n){n=!1;try{var e,o;null===(e=(o=t).onCancel)||void 0===e||e.call(o)}catch{}}}};return"undefined"!=typeof window&&(d.push(o),c||"undefined"==typeof window||(c=!0,window.addEventListener("pageshow",e=>{if(e.persisted)for(const e of[...d])e.restored()})),function(){if(l||s)return;const e=p();e&&(s=!0,window.setTimeout(()=>{s=!1;const t=d[0];t&&!l&&(l=!0,t.deliver(e))},0))}()),{open:()=>{"undefined"!=typeof window&&(n=!0,window.location.assign((e=>{try{var t;const n=new URL(e.authorizeUrl,window.location.origin);e.returnTo&&n.searchParams.set("one_return_to",e.returnTo);const o=new URLSearchParams;e.connectTheme&&o.set("one_theme",e.connectTheme);const i=null===(t=e.connector)||void 0===t?void 0:t.trim().toLowerCase();i&&o.set("one_connector",i);const r=o.toString();return r&&(n.hash=r),n.toString()}catch{return e.authorizeUrl}})(t)))},update:e=>{t=e},destroy:()=>{const e=d.indexOf(o);e>=0&&d.splice(e,1)}}}function C(e,t,n){return(t=function(e){var t=function(e,t){if("object"!=typeof e||!e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var o=n.call(e,t);if("object"!=typeof o)return o;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:t+""}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function f(e){return e.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")}const b={"cal-com":"Cal.com","click-up":"ClickUp",clickup:"ClickUp",docusign:"DocuSign",elevenlabs:"ElevenLabs","fireflies-ai":"Fireflies.ai",github:"GitHub",gitlab:"GitLab",hubspot:"HubSpot","linked-in":"LinkedIn",linkedin:"LinkedIn","one-drive":"OneDrive",onedrive:"OneDrive",openai:"OpenAI","otter-ai":"Otter.ai",paypal:"PayPal",posthog:"PostHog",quickbooks:"QuickBooks",sharepoint:"SharePoint","spotify-web":"Spotify",teams:"Microsoft Teams","telegram-bot":"Telegram","whatsapp-business":"WhatsApp Business",woocommerce:"WooCommerce",x:"X","youtube-data":"YouTube",youtube:"YouTube"};function g(e){var t;return null!==(t=b[e])&&void 0!==t?t:e.split(/[-_]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(" ")}function v(e){return e?`https://assets.withone.ai/connectors/${e}.svg`:""}function m(e){var t,n,o,i;const r="string"==typeof e?{slug:e}:e,a=null!==(t=r.slug)&&void 0!==t&&t.trim()?f(r.slug):null!==(n=r.name)&&void 0!==n&&n.trim()?f(r.name):"";return a?{slug:a,name:(null===(o=r.name)||void 0===o?void 0:o.trim())||g(a),imageUrl:(null===(i=r.imageUrl)||void 0===i?void 0:i.trim())||v(a)}:null}function x(e){const t=null==e?void 0:e.trim();if(!t)return[];if(t.startsWith("["))try{const e=JSON.parse(t);return Array.isArray(e)?e.filter(e=>"string"==typeof e||"object"==typeof e&&null!==e):[]}catch{return[]}return t.split(",").map(e=>e.trim()).filter(Boolean)}const w="#CCFF00",y="#0A0C0B",k="#FFFFFF",A=`\n:host{display:inline-block;vertical-align:middle;max-width:100%}\n:host([data-full-width]),:host([full-width]:not([full-width="false"])),\n:host([data-variant="block"]),:host([variant="block"]){display:block;width:100%}\n.b{all:unset;box-sizing:border-box;position:relative;display:inline-flex;align-items:center;gap:var(--gap);\n max-width:100%;cursor:pointer;user-select:none;-webkit-tap-highlight-color:transparent;\n font-family:var(--one-connect-font,inherit);font-size:var(--fs);font-weight:500;line-height:1.2;letter-spacing:-.01em;\n padding:var(--pad);border-radius:var(--one-connect-radius,12px);background:var(--bg);color:var(--fg);\n box-shadow:var(--shadow);transition:box-shadow .2s var(--ease),background-color .2s var(--ease),opacity .2s var(--ease)}\n.b[data-full-width]{display:flex;width:100%;justify-content:center}\n.b:focus-visible{outline:2px solid var(--ring);outline-offset:2px}\n.b:hover{box-shadow:var(--shadow-hover)}\n.b[disabled]{cursor:not-allowed;opacity:.5;box-shadow:none}\n.b[aria-busy="true"]{cursor:progress}\n.b{--ease:cubic-bezier(.2,.9,.25,1)}\n.b[data-size="sm"]{--fs:13px;--pad:8px 12px 8px 10px;--gap:8px;--chip:18px;--logo:12px}\n.b[data-size="md"]{--fs:14.5px;--pad:12px 16px 12px 14px;--gap:12px;--chip:22px;--logo:14px}\n.b[data-size="lg"]{--fs:16px;--pad:14px 20px 14px 16px;--gap:12px;--chip:26px;--logo:16px}\n.b[data-theme="light"],.b[data-theme="auto"]{--ink-bg:${y};--ink-fg:${k};--surface:${k};--surface-fg:${y};\n --muted:#5B6560;--line:#D5DAD7;--ring:${y};--shadow-base:0 1px 2px rgba(10,12,11,.08),0 4px 14px rgba(10,12,11,.06);\n --shadow-strong:0 1px 2px rgba(10,12,11,.12),0 6px 18px rgba(10,12,11,.1)}\n.b[data-theme="dark"]{--ink-bg:#F2F5F3;--ink-fg:${y};--surface:#101312;--surface-fg:#F2F5F3;\n --muted:#9AA39E;--line:#2A302D;--ring:${w};--shadow-base:0 1px 2px rgba(0,0,0,.4),0 8px 24px rgba(0,0,0,.35);\n --shadow-strong:0 1px 2px rgba(0,0,0,.5),0 10px 28px rgba(0,0,0,.45)}\n@media (prefers-color-scheme:dark){.b[data-theme="auto"]{--ink-bg:#F2F5F3;--ink-fg:${y};--surface:#101312;--surface-fg:#F2F5F3;\n --muted:#9AA39E;--line:#2A302D;--ring:${w};--shadow-base:0 1px 2px rgba(0,0,0,.4),0 8px 24px rgba(0,0,0,.35);\n --shadow-strong:0 1px 2px rgba(0,0,0,.5),0 10px 28px rgba(0,0,0,.45)}}\n.b[data-variant="default"]{--bg:var(--ink-bg);--fg:var(--ink-fg);--shadow:var(--shadow-base);--shadow-hover:var(--shadow-strong)}\n.b[data-variant="accent"]{--bg:var(--one-connect-accent,${w});--fg:var(--one-connect-accent-fg,${y});\n --shadow:0 1px 2px rgba(10,12,11,.1);--shadow-hover:0 1px 2px rgba(10,12,11,.12),0 6px 18px rgba(10,12,11,.12)}\n.b[data-variant="block"]{--bg:var(--surface);--fg:var(--surface-fg);--shadow:inset 0 0 0 1px var(--line);\n --shadow-hover:inset 0 0 0 1px var(--muted);flex-direction:column;align-items:stretch;gap:0;\n width:100%;max-width:420px;text-align:left;padding:16px;border-radius:var(--one-connect-radius,14px)}\n.b[data-variant="block"][data-full-width]{max-width:none}\n.stack{display:inline-flex;align-items:center;flex-shrink:0}\n.chip{width:var(--chip);height:var(--chip);border-radius:6px;display:grid;place-items:center;overflow:hidden;\n margin-left:-7px;position:relative;background:${k};color:${y};box-shadow:0 0 0 1.5px var(--bg);\n transition:margin-left .28s var(--ease)}\n.chip:first-child{margin-left:0}\n.b[data-variant="block"] .chip{box-shadow:0 0 0 1.5px var(--bg),0 0 0 2.5px var(--line)}\n.chip img{width:var(--logo);height:var(--logo);display:block;object-fit:contain}\n.chip.more,.chip.letter{font:500 9px/1 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:-.02em}\n.chip.letter{font-size:10px;font-weight:600}\n.b:hover .chip{margin-left:-2px}.b:hover .chip:first-child{margin-left:0}\n.label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.icon{display:inline-flex;flex-shrink:0}\n.arrow{opacity:.55;transition:transform .2s var(--ease),opacity .2s var(--ease)}\n.b:hover .arrow{transform:translateX(2px);opacity:.85}\n.spinner{width:16px;height:16px;border-radius:50%;border:2px solid currentColor;border-top-color:transparent;\n opacity:.7;animation:spin .7s linear infinite;flex-shrink:0}\n@keyframes spin{to{transform:rotate(360deg)}}\n.top{display:flex;align-items:center;justify-content:space-between;gap:12px}\n.title{font-size:15px;font-weight:600;letter-spacing:-.01em}\n.sub{font-size:13px;line-height:1.5;margin-top:6px;font-weight:400;color:var(--muted)}\n.foot{margin-top:14px;padding-top:12px;display:flex;align-items:center;gap:6px;font-size:11px;font-weight:400;\n color:var(--muted);border-top:1px solid var(--line)}\n.lockup{display:inline-flex;color:var(--surface-fg)}\n.sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}\n@media (prefers-reduced-motion:reduce){.b,.chip,.arrow{transition:none}.spinner{animation-duration:1.6s}}\n@media (forced-colors:active){.b{border:1px solid ButtonText}.b:focus-visible{outline-color:Highlight}}\n`;let S=null;const L=(e,t,n)=>{const o=document.createElement(e);return t&&(o.className=t),void 0!==n&&(o.textContent=n),o},E=(e,t="icon")=>{const n=L("span",t);return n.innerHTML=e,n};function z(e){var t;const n=(null!=(o=null!==(t=e.logos)&&void 0!==t?t:e.platforms)?o:[]).map(m).filter(e=>null!==e);var o;if(0===n.length)return null;const i=L("span","stack");i.setAttribute("aria-hidden","true");for(const e of n.slice(0,3)){const t=L("span","chip");t.title=e.name;const n=L("img");n.alt="",n.decoding="async",n.src=e.imageUrl,n.addEventListener("error",()=>{n.remove(),t.classList.add("letter"),t.textContent=e.name.charAt(0).toUpperCase()}),t.appendChild(n),i.appendChild(t)}const r=n.length-3;return r>0&&i.appendChild(L("span","chip more",`+${r}`)),i}const F=(e,t)=>({authorizeUrl:e.authorizeUrl,connectTheme:e.connectTheme,connector:e.connector,returnTo:e.returnTo,...t});function M(e,t){var n;const o=null!==(n=e.shadowRoot)&&void 0!==n?n:e.attachShadow({mode:"open"});!function(e){if("undefined"!=typeof CSSStyleSheet&&"replaceSync"in CSSStyleSheet.prototype&&"adoptedStyleSheets"in e)try{return S||(S=new CSSStyleSheet,S.replaceSync(A)),void(e.adoptedStyleSheets=[S])}catch{}const t=document.createElement("style");t.textContent=A,e.appendChild(t)}(o);let i=t,r=!1,a=!1,l=null;const s=L("button","b");s.type="button",s.setAttribute("part","button");const c=L("span","sr");c.setAttribute("role","status"),c.setAttribute("aria-live","polite"),o.append(s,c);const d=()=>{return r?"connecting":void 0!==i.connected?i.connected?"connected":"idle":"success"===(null===(e=u())||void 0===e?void 0:e.status)?"connected":"idle";var e},p={onSuccess:()=>{var e,t;return null===(e=(t=i).onSuccess)||void 0===e?void 0:e.call(t)},onError:(e,t)=>{var n,o;return null===(n=(o=i).onError)||void 0===n?void 0:n.call(o,e,t)},onCancel:()=>{var e,t;r=!1,f(),null===(e=(t=i).onCancel)||void 0===e||e.call(t)}},C=h(F(i,p)),f=()=>{var e,t,n,o,r;if(a)return;const u=d(),p=null!==(e=i.variant)&&void 0!==e?e:"default",h="connecting"===u?"Connecting…":"connected"===u?null!==(t=i.connectedLabel)&&void 0!==t?t:"Connected":null!==(n=i.label)&&void 0!==n?n:"Connect your apps";s.dataset.variant=p,s.dataset.size=null!==(o=i.size)&&void 0!==o?o:"md",s.dataset.theme=null!==(r=i.theme)&&void 0!==r?r:"light",s.dataset.state=u,s.toggleAttribute("data-full-width",Boolean(i.fullWidth)),s.disabled=Boolean(i.disabled),s.setAttribute("aria-busy",String("connecting"===u)),"connecting"===u?s.setAttribute("aria-disabled","true"):s.removeAttribute("aria-disabled");const C="idle"===u?z(i):null,f="connecting"===u?L("span","spinner"):"connected"===u?E('<svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M3 8.5l3.5 3.5L13 5"/></svg>'):C;if(s.replaceChildren(),s.removeAttribute("aria-labelledby"),s.removeAttribute("aria-describedby"),"block"===p){const e=L("span","top"),t=L("span","title",h);if(t.id="one-connect-title",t.setAttribute("part","label"),e.appendChild(t),f&&e.appendChild(f),s.appendChild(e),s.setAttribute("aria-labelledby",t.id),i.description){const e=L("span","sub",i.description);e.id="one-connect-description",s.appendChild(e),s.setAttribute("aria-describedby",e.id)}const n=L("span","foot");n.setAttribute("aria-hidden","true"),n.append(L("span","","Secured by"),E('<svg viewBox="0 0 3152 990" width="35" height="11" fill="none" aria-hidden="true" focusable="false"><path d="M1698.02 793.203C1525.75 793.203 1401 666.834 1401 495.102C1401 323.909 1524.67 197 1698.02 197C1870.83 197 1996.12 323.909 1996.12 495.102C1996.12 666.834 1869.75 793.203 1698.02 793.203ZM1698.02 694.916C1801.71 694.916 1884.88 615.53 1884.88 495.102C1884.88 374.133 1801.71 295.827 1698.02 295.827C1594.87 295.827 1511.71 373.053 1511.71 495.102C1511.71 616.61 1595.41 694.916 1698.02 694.916Z" fill="currentColor"/><path d="M2326.71 197.54C2480.62 197.54 2565.95 289.887 2565.95 467.56V779.702H2455.24V468.64C2455.24 361.172 2411.5 292.587 2308.35 292.587C2217.63 292.587 2140.4 356.852 2140.4 484.841V779.702H2030.77V211.041H2140.4V272.065C2185.76 225.082 2248.41 197.54 2326.71 197.54Z" fill="currentColor"/><path d="M3151.98 493.481C3151.98 514.003 3150.36 520.483 3148.74 529.124H2700.51C2715.63 637.672 2794.47 686.815 2922.46 686.815C3031.01 686.815 3099.6 650.633 3116.88 643.072V747.84C3100.68 755.4 3023.45 793.203 2908.96 793.203C2699.97 793.203 2588.18 661.434 2588.18 497.802C2588.18 332.55 2702.67 197 2871.7 197C3031.55 197 3151.98 317.969 3151.98 493.481ZM2876.02 300.688C2784.75 300.688 2720.49 345.511 2702.67 434.617H3050.45C3034.79 344.971 2967.29 300.688 2876.02 300.688Z" fill="currentColor"/><path d="M537.494 782.175C641.011 827.7 767.922 858.83 880.501 839.875C983.155 822.599 1069.64 764.946 1094.39 659.271C1114.47 573.493 1088.54 481.273 1047.27 405.311C983.124 287.246 874.768 183.791 759.847 114.657C644.926 45.5225 507.181 -5.02605 372.102 0.398669C289.698 3.69665 205.938 26.536 146.544 85.6685C112.069 119.989 88.3818 171.231 83.1266 219.823C78.1642 265.64 84.3749 310.317 99.8478 354.007C168.243 547.14 354.009 701.467 537.51 782.191L537.494 782.175ZM751.956 818.053C583.05 796.2 415.7 707.108 292.472 593.004C222.536 528.246 159.366 444.979 125.985 355.471C102.961 293.734 96.3956 223.367 122.41 161.969C137.158 127.14 160.367 98.244 190.743 75.9133C275.581 13.5752 395.819 6.99464 495.977 26.8596C608.848 49.252 713.875 99.4615 806.712 166.515C907.085 239.025 999.537 339.922 1048.42 454.627C1072.45 511.001 1083.99 570.103 1075.64 630.869C1067.38 690.957 1034.57 742.353 983.987 775.379C917.626 818.715 830.861 828.255 751.972 818.053H751.956Z" fill="currentColor"/><path d="M1103.27 661.228C1086.68 755.313 1024.9 818.622 934.021 848.69C821.751 885.846 685.146 860.263 576.251 818.915C452.515 771.942 340.336 699.91 245.157 607.813C209.002 572.83 177.255 534.456 148.837 493.031C100.384 422.402 61.7024 335.19 65.8326 248.071C68.2213 197.769 83.987 159.241 111.403 116.938C45.8289 171.308 31.404 262.511 47.1543 342.002C53.4728 373.841 62.9815 403.23 76.528 432.958C100.338 485.202 130.914 532.992 167.747 577.238C255.452 682.573 367.83 765.13 491.073 824.124C614.317 883.118 769.307 920.691 900.471 889.128C985.788 868.601 1061.47 816.095 1090.83 730.856C1098.18 708.71 1104.61 686.564 1103.25 661.244L1103.27 661.228Z" fill="currentColor"/><path d="M883.297 963.502C923.15 947.074 960.877 926.022 988.309 893.967C954.265 917.839 920.931 934.807 882.403 944.993C751.747 979.53 595.123 942.589 474.731 886.57C422.102 862.082 372.617 834.018 325.181 800.591C205.128 715.984 89.4825 597.996 36.7762 458.756C20.2092 414.973 11.7793 370.404 11.5327 323.739C11.4249 302.641 15.4627 283.747 19.0226 263.004C-2.52219 310.486 -3.66265 380.915 5.21419 431.617C32.0605 584.881 147.151 721.146 266.988 813.983C343.443 873.224 436.403 924.913 528.424 954.672C620.444 984.431 713.851 999.426 808.491 983.598C834.459 979.252 858.362 973.781 883.297 963.502Z" fill="currentColor"/><path d="M1045.09 830.737C1053.55 816.158 1061.75 802.95 1066.99 787.061C1043.75 824.541 1013.3 854.408 974.29 874.982C947.752 888.991 920.228 899.27 890.577 905.219C864.578 910.428 839.673 914.481 812.781 914.851C739.716 915.852 668.717 903.092 599.459 880.854C418.686 822.8 238.422 697.6 127.985 543.165C94.8819 496.87 68.8679 447.847 50.7135 394.031C28.1978 324.45 25.7782 258.69 53.4104 189.078C36.1345 211.825 26.9956 237.793 20.4151 264.916C18.3654 282.732 14.713 299.345 15.0828 317.561C15.9613 360.774 23.5436 402.692 38.477 443.562C73.1522 538.464 134.936 621.869 207.368 691.913C307.34 788.587 426.762 862.268 558.127 907.993C689.491 953.718 871.975 973.768 992.614 885.446C1013.28 870.312 1029.39 851.773 1045.07 830.752L1045.09 830.737Z" fill="currentColor"/><path d="M552.552 745.664C671.079 797.831 835.825 835.526 954.768 769.12C999.137 744.354 1031.99 705.626 1047.99 657.312C1086.75 540.264 1020.28 405.817 947.124 315.631C855.536 202.745 729.688 114.516 592.76 66.0323C506.349 35.4412 418.968 22.0797 328.211 37.46C262.313 48.6177 195.29 81.7054 157.563 138.234C118.912 196.133 115.891 270.785 136.758 335.882C176.519 459.926 276.769 570.763 381.01 646.277C434.995 685.391 491.662 718.864 552.567 745.664H552.552ZM210.162 422.955C199.898 402.381 189.141 382.701 184.733 360.385C182.267 347.918 184.625 333.477 184.564 320.64C184.44 293.223 194.072 269.059 209.992 247.93C219.609 235.17 229.456 224.844 243.018 215.906C341.218 151.179 476.051 175.991 576.763 223.904C661.971 264.435 737.394 321.534 796.11 395.862C836.919 447.52 871.193 513.634 880.502 579.501C888.238 634.272 873.243 695.485 826.763 729.189C807.853 742.905 785.045 751.721 761.728 755.974C721.921 763.217 688.802 758.008 649.565 748.916C594.27 736.094 542.488 715.212 492.279 688.889C441.977 662.521 396.745 631.483 353.008 595.436C314.372 563.597 280.252 537.845 248.458 498.007L248.274 497.837L221.504 461.945L211.379 445.84C194.103 418.408 177.398 391.346 165.238 361.202C151.291 326.604 142.676 291.852 143.678 254.279C146.19 160.564 203.766 96.7467 290.238 67.82C434.394 19.5985 611.561 79.4246 735.298 157.636C825.099 214.411 904.435 286.581 963.321 375.134C989.767 414.894 1010.42 456.998 1023.78 502.646C1049.84 591.66 1036.79 685.884 957.404 742.659C890.257 790.68 785.6 793.146 707.295 776.486C680.403 769.736 654.065 766.007 629.222 754.818C732.107 783.93 882.397 797.723 963.938 715.35C990.599 688.412 1007.55 656.218 1013.75 618.537C1020.87 575.232 1016.12 531.634 1002.62 489.931C985.498 437.071 956.34 384.026 922.405 340.289C876.911 281.665 823.188 230.531 762.468 187.981C681.112 130.975 588.783 88.887 490.799 71.0872C425.595 59.2514 349.463 60.4072 287.557 85.0959C256.441 97.5019 228.501 114.5 205.924 138.85C158.303 190.2 147.176 256.036 161.539 323.383C166.856 348.334 175.456 371.296 185.596 394.737C194.488 415.295 222.676 461.883 236.022 477.649L226.729 456.196L210.162 423.001V422.955ZM832.342 286.936C756.904 211.544 666.44 154.076 564.896 120.249C526.553 107.473 487.948 99.4899 447.648 96.084C401.26 92.1696 356.167 96.7313 312.215 111.341C222.337 141.208 169.399 217.277 175.255 312.333C177.567 324.847 179.555 335.774 180.603 348.503C152.971 264.944 174.454 175.236 251.356 125.581C310.797 87.2072 387.39 78.2071 456.694 86.7603C503.714 92.5549 555.387 106.656 599.078 124.317C706.016 167.546 800.764 234.615 876.741 321.395C912.002 361.664 942.085 405.756 963.876 454.532C996.779 528.166 1011.85 610.046 965.895 681.369C952.379 702.359 935.427 718.818 914.283 731.871C884.432 747.421 852.947 758.671 818.872 761.06C839.523 755.959 859.404 750.981 878.637 740.424C929.186 717.061 964.601 671.567 974.818 616.488C987.671 547.245 964.693 475.429 930.881 415.357C903.834 367.305 871.471 326.049 832.311 286.905L832.342 286.936ZM890.673 420.18C861.623 370.387 825.515 327.621 783.288 287.999C721.659 230.161 650.028 185.345 570.598 156.033C513.623 135.013 454.506 124.394 393.786 128.108C353.316 130.59 315.728 139.867 280.498 159.516C245.268 179.166 216.819 204.918 201.023 240.394L188.617 268.242C204.583 180.445 278.325 132.054 361.931 119.355C412.757 111.634 462.658 116.643 512.421 129.048C596.905 150.116 674.1 189.923 743.45 242.028C816.607 296.999 885.526 373.531 924.578 456.982C949.713 510.675 965.094 571.61 949.837 630.234C939.018 671.768 912.511 706.566 875.308 727.987C847.013 744.292 816.191 754.679 783.242 758.101C825.915 745.926 863.75 731.917 895.327 698.799C913.512 679.72 926.535 657.62 933.054 631.714C951.347 558.989 927.49 483.274 890.642 420.134L890.673 420.18ZM726.19 279.369C625.678 198.799 493.404 141.917 362.655 156.973C343.854 159.131 326.547 164.17 308.639 169.195C301.18 171.29 295.201 177.732 286.493 176.253C378.313 130.081 492.063 149.545 583.143 188.119C684.102 230.87 775.952 302.825 840.664 391.069C871.794 433.527 895.805 479.652 909.506 530.386C918.382 563.273 920.232 596.654 911.941 629.294C905.622 654.153 895.481 677.778 875.786 694.9C893.987 666.327 905.452 637.693 907.086 604.128C908.72 570.562 903.141 536.565 891.567 503.57C861.392 417.53 797.066 336.19 726.205 279.384L726.19 279.369Z" fill="currentColor"/></svg>',"lockup")),s.appendChild(n)}else{f&&s.appendChild(f);const e=L("span","label",h);e.setAttribute("part","label"),s.appendChild(e),"idle"===u&&s.appendChild(E('<svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M6 3l5 5-5 5"/></svg>',"icon arrow"))}var b,g;b=u,null!==l?b!==l&&(l=b,c.textContent="connecting"===b?"Connecting to One…":"connected"===b?null!==(g=i.connectedLabel)&&void 0!==g?g:"Connected":""):l=b};return s.addEventListener("click",()=>{a||i.disabled||r||(r=!0,f(),C.open())}),f(),{update:e=>{i=e,C.update(F(i,p)),f()},destroy:()=>{a=!0,C.destroy(),o.replaceChildren()}}}const T=["authorize-url","logos","platforms","connected","disabled","variant","size","full-width","theme","connect-theme","connector","return-to","label","connected-label","description"];function $(e,t,n){const o=e.getAttribute(t);return o&&n.includes(o)?o:void 0}const U=(e,t)=>e.hasAttribute(t)?"false"!==e.getAttribute(t):void 0;function B(){if("undefined"!=typeof window&&"undefined"!=typeof customElements&&!customElements.get("one-connect-button")){class e extends HTMLElement{constructor(...e){super(...e),C(this,"onSuccess",null),C(this,"onError",null),C(this,"onCancel",null),C(this,"handle",null)}connectedCallback(){this.sync()}disconnectedCallback(){var e;null===(e=this.handle)||void 0===e||e.destroy(),this.handle=null}attributeChangedCallback(){this.isConnected&&this.sync()}props(e){var t,n,o,i,r,a;return{authorizeUrl:e,logos:x(null!==(t=this.getAttribute("logos"))&&void 0!==t?t:this.getAttribute("platforms")),connected:U(this,"connected"),disabled:U(this,"disabled"),variant:$(this,"variant",["default","accent","block"]),size:$(this,"size",["sm","md","lg"]),fullWidth:U(this,"full-width"),theme:$(this,"theme",["light","dark","auto"]),connectTheme:$(this,"connect-theme",["light","dark"]),connector:null!==(n=this.getAttribute("connector"))&&void 0!==n?n:void 0,returnTo:null!==(o=this.getAttribute("return-to"))&&void 0!==o?o:void 0,label:null!==(i=this.getAttribute("label"))&&void 0!==i?i:void 0,connectedLabel:null!==(r=this.getAttribute("connected-label"))&&void 0!==r?r:void 0,description:null!==(a=this.getAttribute("description"))&&void 0!==a?a:void 0,onSuccess:()=>{var e;null===(e=this.onSuccess)||void 0===e||e.call(this),this.dispatchEvent(new CustomEvent("success"))},onError:(e,t)=>{var n;null===(n=this.onError)||void 0===n||n.call(this,e,t),this.dispatchEvent(new CustomEvent("error",{detail:{message:e,code:t}}))},onCancel:()=>{var e;null===(e=this.onCancel)||void 0===e||e.call(this),this.dispatchEvent(new CustomEvent("cancel"))}}}sync(){const e=this.getAttribute("authorize-url");var t;if(!e)return null===(t=this.handle)||void 0===t||t.destroy(),void(this.handle=null);const n=this.props(e);this.handle?this.handle.update(n):this.handle=M(this,n)}}C(e,"observedAttributes",[...T]),customElements.define("one-connect-button",e)}}B(),exports.createConnectFlow=h,exports.mountConnectButton=function(e,t){const n=document.createElement("span");n.className="one-connect";const o=e=>{var t;n.setAttribute("data-variant",null!==(t=e.variant)&&void 0!==t?t:"default"),n.toggleAttribute("data-full-width",Boolean(e.fullWidth))};o(t),e.appendChild(n);const i=M(n,t);return{update:e=>{o(e),i.update(e)},destroy:()=>{i.destroy(),n.remove()}}},exports.readConnectReturn=u,exports.registerConnectButton=B,exports.renderConnectButton=M;
package/dist/index.esm.js CHANGED
@@ -1 +1 @@
1
- const e="one_connect",t="one_connect_error",n={declined:"You cancelled the connection.",expired:"The connection attempt expired. Please try again.",failed:"The connection could not be completed. Please try again."};function o(o){const i=new URLSearchParams(o),a=i.get(e);if("success"===a)return{status:a};if("error"!==a)return null;const r=i.get(t),l=null!==(s=r)&&Object.prototype.hasOwnProperty.call(n,s)?r:"failed";var s;return{status:a,code:l,message:n[l]}}const i=[e,t,"one_connect_message"];function a(e){const t=new URLSearchParams(e);return i.some(e=>t.has(e))}let r,l=!1,s=!1,c=!1;const d=[];function p(){return u()}function u(){return"undefined"==typeof window?null:(void 0===r&&(r=o(window.location.search),(r||a(window.location.search))&&function(){const e=()=>{a(window.location.search)&&window.history.replaceState(window.history.state,"",function(e){const t=new URLSearchParams(e.search);for(const e of i)t.delete(e);const n=t.toString();return`${e.pathname}${n?`?${n}`:""}${e.hash}`}(window.location))};e();for(const t of[50,500,2e3])window.setTimeout(e,t)}()),r)}function h(e){let t=e,n=!1;const o={deliver:e=>{try{var n,o,i,a,r,l;"success"===e.status?null===(n=(o=t).onSuccess)||void 0===n||n.call(o):null===(i=(a=t).onError)||void 0===i||i.call(a,null!==(r=e.message)&&void 0!==r?r:"",null!==(l=e.code)&&void 0!==l?l:"failed")}catch{}},restored:()=>{if(n){n=!1;try{var e,o;null===(e=(o=t).onCancel)||void 0===e||e.call(o)}catch{}}}};return"undefined"!=typeof window&&(d.push(o),c||"undefined"==typeof window||(c=!0,window.addEventListener("pageshow",e=>{if(e.persisted)for(const e of[...d])e.restored()})),function(){if(l||s)return;const e=u();e&&(s=!0,window.setTimeout(()=>{s=!1;const t=d[0];t&&!l&&(l=!0,t.deliver(e))},0))}()),{open:()=>{"undefined"!=typeof window&&(n=!0,window.location.assign((e=>{const t=e.connectTheme;try{const n=new URL(e.authorizeUrl,window.location.origin);return t&&(n.hash=`one_theme=${t}`),n.toString()}catch{return e.authorizeUrl}})(t)))},update:e=>{t=e},destroy:()=>{const e=d.indexOf(o);e>=0&&d.splice(e,1)}}}function C(e,t,n){return(t=function(e){var t=function(e,t){if("object"!=typeof e||!e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var o=n.call(e,t);if("object"!=typeof o)return o;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:t+""}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function f(e){return e.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")}const b={"cal-com":"Cal.com","click-up":"ClickUp",clickup:"ClickUp",docusign:"DocuSign",elevenlabs:"ElevenLabs","fireflies-ai":"Fireflies.ai",github:"GitHub",gitlab:"GitLab",hubspot:"HubSpot","linked-in":"LinkedIn",linkedin:"LinkedIn","one-drive":"OneDrive",onedrive:"OneDrive",openai:"OpenAI","otter-ai":"Otter.ai",paypal:"PayPal",posthog:"PostHog",quickbooks:"QuickBooks",sharepoint:"SharePoint","spotify-web":"Spotify",teams:"Microsoft Teams","telegram-bot":"Telegram","whatsapp-business":"WhatsApp Business",woocommerce:"WooCommerce",x:"X","youtube-data":"YouTube",youtube:"YouTube"};function g(e){var t;return null!==(t=b[e])&&void 0!==t?t:e.split(/[-_]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(" ")}function v(e){return e?`https://assets.withone.ai/connectors/${e}.svg`:""}function m(e){var t,n,o,i;const a="string"==typeof e?{slug:e}:e,r=null!==(t=a.slug)&&void 0!==t&&t.trim()?f(a.slug):null!==(n=a.name)&&void 0!==n&&n.trim()?f(a.name):"";return r?{slug:r,name:(null===(o=a.name)||void 0===o?void 0:o.trim())||g(r),imageUrl:(null===(i=a.imageUrl)||void 0===i?void 0:i.trim())||v(r)}:null}function x(e){const t=null==e?void 0:e.trim();if(!t)return[];if(t.startsWith("["))try{const e=JSON.parse(t);return Array.isArray(e)?e.filter(e=>"string"==typeof e||"object"==typeof e&&null!==e):[]}catch{return[]}return t.split(",").map(e=>e.trim()).filter(Boolean)}const w="#CCFF00",y="#0A0C0B",k="#FFFFFF",A=`\n:host{display:inline-block;vertical-align:middle;max-width:100%}\n:host([data-full-width]),:host([full-width]:not([full-width="false"])),\n:host([data-variant="block"]),:host([variant="block"]){display:block;width:100%}\n.b{all:unset;box-sizing:border-box;position:relative;display:inline-flex;align-items:center;gap:var(--gap);\n max-width:100%;cursor:pointer;user-select:none;-webkit-tap-highlight-color:transparent;\n font-family:var(--one-connect-font,inherit);font-size:var(--fs);font-weight:500;line-height:1.2;letter-spacing:-.01em;\n padding:var(--pad);border-radius:var(--one-connect-radius,12px);background:var(--bg);color:var(--fg);\n box-shadow:var(--shadow);transition:box-shadow .2s var(--ease),background-color .2s var(--ease),opacity .2s var(--ease)}\n.b[data-full-width]{display:flex;width:100%;justify-content:center}\n.b:focus-visible{outline:2px solid var(--ring);outline-offset:2px}\n.b:hover{box-shadow:var(--shadow-hover)}\n.b[disabled]{cursor:not-allowed;opacity:.5;box-shadow:none}\n.b[aria-busy="true"]{cursor:progress}\n.b{--ease:cubic-bezier(.2,.9,.25,1)}\n.b[data-size="sm"]{--fs:13px;--pad:8px 12px 8px 10px;--gap:8px;--chip:18px;--logo:12px}\n.b[data-size="md"]{--fs:14.5px;--pad:12px 16px 12px 14px;--gap:12px;--chip:22px;--logo:14px}\n.b[data-size="lg"]{--fs:16px;--pad:14px 20px 14px 16px;--gap:12px;--chip:26px;--logo:16px}\n.b[data-theme="light"],.b[data-theme="auto"]{--ink-bg:${y};--ink-fg:${k};--surface:${k};--surface-fg:${y};\n --muted:#5B6560;--line:#D5DAD7;--ring:${y};--shadow-base:0 1px 2px rgba(10,12,11,.08),0 4px 14px rgba(10,12,11,.06);\n --shadow-strong:0 1px 2px rgba(10,12,11,.12),0 6px 18px rgba(10,12,11,.1)}\n.b[data-theme="dark"]{--ink-bg:#F2F5F3;--ink-fg:${y};--surface:#101312;--surface-fg:#F2F5F3;\n --muted:#9AA39E;--line:#2A302D;--ring:${w};--shadow-base:0 1px 2px rgba(0,0,0,.4),0 8px 24px rgba(0,0,0,.35);\n --shadow-strong:0 1px 2px rgba(0,0,0,.5),0 10px 28px rgba(0,0,0,.45)}\n@media (prefers-color-scheme:dark){.b[data-theme="auto"]{--ink-bg:#F2F5F3;--ink-fg:${y};--surface:#101312;--surface-fg:#F2F5F3;\n --muted:#9AA39E;--line:#2A302D;--ring:${w};--shadow-base:0 1px 2px rgba(0,0,0,.4),0 8px 24px rgba(0,0,0,.35);\n --shadow-strong:0 1px 2px rgba(0,0,0,.5),0 10px 28px rgba(0,0,0,.45)}}\n.b[data-variant="default"]{--bg:var(--ink-bg);--fg:var(--ink-fg);--shadow:var(--shadow-base);--shadow-hover:var(--shadow-strong)}\n.b[data-variant="accent"]{--bg:var(--one-connect-accent,${w});--fg:var(--one-connect-accent-fg,${y});\n --shadow:0 1px 2px rgba(10,12,11,.1);--shadow-hover:0 1px 2px rgba(10,12,11,.12),0 6px 18px rgba(10,12,11,.12)}\n.b[data-variant="block"]{--bg:var(--surface);--fg:var(--surface-fg);--shadow:inset 0 0 0 1px var(--line);\n --shadow-hover:inset 0 0 0 1px var(--muted);flex-direction:column;align-items:stretch;gap:0;\n width:100%;max-width:420px;text-align:left;padding:16px;border-radius:var(--one-connect-radius,14px)}\n.b[data-variant="block"][data-full-width]{max-width:none}\n.stack{display:inline-flex;align-items:center;flex-shrink:0}\n.chip{width:var(--chip);height:var(--chip);border-radius:6px;display:grid;place-items:center;overflow:hidden;\n margin-left:-7px;position:relative;background:${k};color:${y};box-shadow:0 0 0 1.5px var(--bg);\n transition:margin-left .28s var(--ease)}\n.chip:first-child{margin-left:0}\n.b[data-variant="block"] .chip{box-shadow:0 0 0 1.5px var(--bg),0 0 0 2.5px var(--line)}\n.chip img{width:var(--logo);height:var(--logo);display:block;object-fit:contain}\n.chip.more,.chip.letter{font:500 9px/1 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:-.02em}\n.chip.letter{font-size:10px;font-weight:600}\n.b:hover .chip{margin-left:-2px}.b:hover .chip:first-child{margin-left:0}\n.label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.icon{display:inline-flex;flex-shrink:0}\n.arrow{opacity:.55;transition:transform .2s var(--ease),opacity .2s var(--ease)}\n.b:hover .arrow{transform:translateX(2px);opacity:.85}\n.spinner{width:16px;height:16px;border-radius:50%;border:2px solid currentColor;border-top-color:transparent;\n opacity:.7;animation:spin .7s linear infinite;flex-shrink:0}\n@keyframes spin{to{transform:rotate(360deg)}}\n.top{display:flex;align-items:center;justify-content:space-between;gap:12px}\n.title{font-size:15px;font-weight:600;letter-spacing:-.01em}\n.sub{font-size:13px;line-height:1.5;margin-top:6px;font-weight:400;color:var(--muted)}\n.foot{margin-top:14px;padding-top:12px;display:flex;align-items:center;gap:6px;font-size:11px;font-weight:400;\n color:var(--muted);border-top:1px solid var(--line)}\n.lockup{display:inline-flex;color:var(--surface-fg)}\n.sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}\n@media (prefers-reduced-motion:reduce){.b,.chip,.arrow{transition:none}.spinner{animation-duration:1.6s}}\n@media (forced-colors:active){.b{border:1px solid ButtonText}.b:focus-visible{outline-color:Highlight}}\n`;let S=null;const L=(e,t,n)=>{const o=document.createElement(e);return t&&(o.className=t),void 0!==n&&(o.textContent=n),o},E=(e,t="icon")=>{const n=L("span",t);return n.innerHTML=e,n};function z(e){var t;const n=(null!=(o=null!==(t=e.logos)&&void 0!==t?t:e.platforms)?o:[]).map(m).filter(e=>null!==e);var o;if(0===n.length)return null;const i=L("span","stack");i.setAttribute("aria-hidden","true");for(const e of n.slice(0,3)){const t=L("span","chip");t.title=e.name;const n=L("img");n.alt="",n.decoding="async",n.src=e.imageUrl,n.addEventListener("error",()=>{n.remove(),t.classList.add("letter"),t.textContent=e.name.charAt(0).toUpperCase()}),t.appendChild(n),i.appendChild(t)}const a=n.length-3;return a>0&&i.appendChild(L("span","chip more",`+${a}`)),i}const F=(e,t)=>({authorizeUrl:e.authorizeUrl,connectTheme:e.connectTheme,...t});function M(e,t){var n;const o=null!==(n=e.shadowRoot)&&void 0!==n?n:e.attachShadow({mode:"open"});!function(e){if("undefined"!=typeof CSSStyleSheet&&"replaceSync"in CSSStyleSheet.prototype&&"adoptedStyleSheets"in e)try{return S||(S=new CSSStyleSheet,S.replaceSync(A)),void(e.adoptedStyleSheets=[S])}catch{}const t=document.createElement("style");t.textContent=A,e.appendChild(t)}(o);let i=t,a=!1,r=!1,l=null;const s=L("button","b");s.type="button",s.setAttribute("part","button");const c=L("span","sr");c.setAttribute("role","status"),c.setAttribute("aria-live","polite"),o.append(s,c);const d=()=>{return a?"connecting":void 0!==i.connected?i.connected?"connected":"idle":"success"===(null===(e=p())||void 0===e?void 0:e.status)?"connected":"idle";var e},u={onSuccess:()=>{var e,t;return null===(e=(t=i).onSuccess)||void 0===e?void 0:e.call(t)},onError:(e,t)=>{var n,o;return null===(n=(o=i).onError)||void 0===n?void 0:n.call(o,e,t)},onCancel:()=>{var e,t;a=!1,f(),null===(e=(t=i).onCancel)||void 0===e||e.call(t)}},C=h(F(i,u)),f=()=>{var e,t,n,o,a;if(r)return;const p=d(),u=null!==(e=i.variant)&&void 0!==e?e:"default",h="connecting"===p?"Connecting…":"connected"===p?null!==(t=i.connectedLabel)&&void 0!==t?t:"Connected":null!==(n=i.label)&&void 0!==n?n:"Connect your apps";s.dataset.variant=u,s.dataset.size=null!==(o=i.size)&&void 0!==o?o:"md",s.dataset.theme=null!==(a=i.theme)&&void 0!==a?a:"light",s.dataset.state=p,s.toggleAttribute("data-full-width",Boolean(i.fullWidth)),s.disabled=Boolean(i.disabled),s.setAttribute("aria-busy",String("connecting"===p)),"connecting"===p?s.setAttribute("aria-disabled","true"):s.removeAttribute("aria-disabled");const C="idle"===p?z(i):null,f="connecting"===p?L("span","spinner"):"connected"===p?E('<svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M3 8.5l3.5 3.5L13 5"/></svg>'):C;if(s.replaceChildren(),s.removeAttribute("aria-labelledby"),s.removeAttribute("aria-describedby"),"block"===u){const e=L("span","top"),t=L("span","title",h);if(t.id="one-connect-title",t.setAttribute("part","label"),e.appendChild(t),f&&e.appendChild(f),s.appendChild(e),s.setAttribute("aria-labelledby",t.id),i.description){const e=L("span","sub",i.description);e.id="one-connect-description",s.appendChild(e),s.setAttribute("aria-describedby",e.id)}const n=L("span","foot");n.setAttribute("aria-hidden","true"),n.append(L("span","","Secured by"),E('<svg viewBox="0 0 3152 990" width="35" height="11" fill="none" aria-hidden="true" focusable="false"><path d="M1698.02 793.203C1525.75 793.203 1401 666.834 1401 495.102C1401 323.909 1524.67 197 1698.02 197C1870.83 197 1996.12 323.909 1996.12 495.102C1996.12 666.834 1869.75 793.203 1698.02 793.203ZM1698.02 694.916C1801.71 694.916 1884.88 615.53 1884.88 495.102C1884.88 374.133 1801.71 295.827 1698.02 295.827C1594.87 295.827 1511.71 373.053 1511.71 495.102C1511.71 616.61 1595.41 694.916 1698.02 694.916Z" fill="currentColor"/><path d="M2326.71 197.54C2480.62 197.54 2565.95 289.887 2565.95 467.56V779.702H2455.24V468.64C2455.24 361.172 2411.5 292.587 2308.35 292.587C2217.63 292.587 2140.4 356.852 2140.4 484.841V779.702H2030.77V211.041H2140.4V272.065C2185.76 225.082 2248.41 197.54 2326.71 197.54Z" fill="currentColor"/><path d="M3151.98 493.481C3151.98 514.003 3150.36 520.483 3148.74 529.124H2700.51C2715.63 637.672 2794.47 686.815 2922.46 686.815C3031.01 686.815 3099.6 650.633 3116.88 643.072V747.84C3100.68 755.4 3023.45 793.203 2908.96 793.203C2699.97 793.203 2588.18 661.434 2588.18 497.802C2588.18 332.55 2702.67 197 2871.7 197C3031.55 197 3151.98 317.969 3151.98 493.481ZM2876.02 300.688C2784.75 300.688 2720.49 345.511 2702.67 434.617H3050.45C3034.79 344.971 2967.29 300.688 2876.02 300.688Z" fill="currentColor"/><path d="M537.494 782.175C641.011 827.7 767.922 858.83 880.501 839.875C983.155 822.599 1069.64 764.946 1094.39 659.271C1114.47 573.493 1088.54 481.273 1047.27 405.311C983.124 287.246 874.768 183.791 759.847 114.657C644.926 45.5225 507.181 -5.02605 372.102 0.398669C289.698 3.69665 205.938 26.536 146.544 85.6685C112.069 119.989 88.3818 171.231 83.1266 219.823C78.1642 265.64 84.3749 310.317 99.8478 354.007C168.243 547.14 354.009 701.467 537.51 782.191L537.494 782.175ZM751.956 818.053C583.05 796.2 415.7 707.108 292.472 593.004C222.536 528.246 159.366 444.979 125.985 355.471C102.961 293.734 96.3956 223.367 122.41 161.969C137.158 127.14 160.367 98.244 190.743 75.9133C275.581 13.5752 395.819 6.99464 495.977 26.8596C608.848 49.252 713.875 99.4615 806.712 166.515C907.085 239.025 999.537 339.922 1048.42 454.627C1072.45 511.001 1083.99 570.103 1075.64 630.869C1067.38 690.957 1034.57 742.353 983.987 775.379C917.626 818.715 830.861 828.255 751.972 818.053H751.956Z" fill="currentColor"/><path d="M1103.27 661.228C1086.68 755.313 1024.9 818.622 934.021 848.69C821.751 885.846 685.146 860.263 576.251 818.915C452.515 771.942 340.336 699.91 245.157 607.813C209.002 572.83 177.255 534.456 148.837 493.031C100.384 422.402 61.7024 335.19 65.8326 248.071C68.2213 197.769 83.987 159.241 111.403 116.938C45.8289 171.308 31.404 262.511 47.1543 342.002C53.4728 373.841 62.9815 403.23 76.528 432.958C100.338 485.202 130.914 532.992 167.747 577.238C255.452 682.573 367.83 765.13 491.073 824.124C614.317 883.118 769.307 920.691 900.471 889.128C985.788 868.601 1061.47 816.095 1090.83 730.856C1098.18 708.71 1104.61 686.564 1103.25 661.244L1103.27 661.228Z" fill="currentColor"/><path d="M883.297 963.502C923.15 947.074 960.877 926.022 988.309 893.967C954.265 917.839 920.931 934.807 882.403 944.993C751.747 979.53 595.123 942.589 474.731 886.57C422.102 862.082 372.617 834.018 325.181 800.591C205.128 715.984 89.4825 597.996 36.7762 458.756C20.2092 414.973 11.7793 370.404 11.5327 323.739C11.4249 302.641 15.4627 283.747 19.0226 263.004C-2.52219 310.486 -3.66265 380.915 5.21419 431.617C32.0605 584.881 147.151 721.146 266.988 813.983C343.443 873.224 436.403 924.913 528.424 954.672C620.444 984.431 713.851 999.426 808.491 983.598C834.459 979.252 858.362 973.781 883.297 963.502Z" fill="currentColor"/><path d="M1045.09 830.737C1053.55 816.158 1061.75 802.95 1066.99 787.061C1043.75 824.541 1013.3 854.408 974.29 874.982C947.752 888.991 920.228 899.27 890.577 905.219C864.578 910.428 839.673 914.481 812.781 914.851C739.716 915.852 668.717 903.092 599.459 880.854C418.686 822.8 238.422 697.6 127.985 543.165C94.8819 496.87 68.8679 447.847 50.7135 394.031C28.1978 324.45 25.7782 258.69 53.4104 189.078C36.1345 211.825 26.9956 237.793 20.4151 264.916C18.3654 282.732 14.713 299.345 15.0828 317.561C15.9613 360.774 23.5436 402.692 38.477 443.562C73.1522 538.464 134.936 621.869 207.368 691.913C307.34 788.587 426.762 862.268 558.127 907.993C689.491 953.718 871.975 973.768 992.614 885.446C1013.28 870.312 1029.39 851.773 1045.07 830.752L1045.09 830.737Z" fill="currentColor"/><path d="M552.552 745.664C671.079 797.831 835.825 835.526 954.768 769.12C999.137 744.354 1031.99 705.626 1047.99 657.312C1086.75 540.264 1020.28 405.817 947.124 315.631C855.536 202.745 729.688 114.516 592.76 66.0323C506.349 35.4412 418.968 22.0797 328.211 37.46C262.313 48.6177 195.29 81.7054 157.563 138.234C118.912 196.133 115.891 270.785 136.758 335.882C176.519 459.926 276.769 570.763 381.01 646.277C434.995 685.391 491.662 718.864 552.567 745.664H552.552ZM210.162 422.955C199.898 402.381 189.141 382.701 184.733 360.385C182.267 347.918 184.625 333.477 184.564 320.64C184.44 293.223 194.072 269.059 209.992 247.93C219.609 235.17 229.456 224.844 243.018 215.906C341.218 151.179 476.051 175.991 576.763 223.904C661.971 264.435 737.394 321.534 796.11 395.862C836.919 447.52 871.193 513.634 880.502 579.501C888.238 634.272 873.243 695.485 826.763 729.189C807.853 742.905 785.045 751.721 761.728 755.974C721.921 763.217 688.802 758.008 649.565 748.916C594.27 736.094 542.488 715.212 492.279 688.889C441.977 662.521 396.745 631.483 353.008 595.436C314.372 563.597 280.252 537.845 248.458 498.007L248.274 497.837L221.504 461.945L211.379 445.84C194.103 418.408 177.398 391.346 165.238 361.202C151.291 326.604 142.676 291.852 143.678 254.279C146.19 160.564 203.766 96.7467 290.238 67.82C434.394 19.5985 611.561 79.4246 735.298 157.636C825.099 214.411 904.435 286.581 963.321 375.134C989.767 414.894 1010.42 456.998 1023.78 502.646C1049.84 591.66 1036.79 685.884 957.404 742.659C890.257 790.68 785.6 793.146 707.295 776.486C680.403 769.736 654.065 766.007 629.222 754.818C732.107 783.93 882.397 797.723 963.938 715.35C990.599 688.412 1007.55 656.218 1013.75 618.537C1020.87 575.232 1016.12 531.634 1002.62 489.931C985.498 437.071 956.34 384.026 922.405 340.289C876.911 281.665 823.188 230.531 762.468 187.981C681.112 130.975 588.783 88.887 490.799 71.0872C425.595 59.2514 349.463 60.4072 287.557 85.0959C256.441 97.5019 228.501 114.5 205.924 138.85C158.303 190.2 147.176 256.036 161.539 323.383C166.856 348.334 175.456 371.296 185.596 394.737C194.488 415.295 222.676 461.883 236.022 477.649L226.729 456.196L210.162 423.001V422.955ZM832.342 286.936C756.904 211.544 666.44 154.076 564.896 120.249C526.553 107.473 487.948 99.4899 447.648 96.084C401.26 92.1696 356.167 96.7313 312.215 111.341C222.337 141.208 169.399 217.277 175.255 312.333C177.567 324.847 179.555 335.774 180.603 348.503C152.971 264.944 174.454 175.236 251.356 125.581C310.797 87.2072 387.39 78.2071 456.694 86.7603C503.714 92.5549 555.387 106.656 599.078 124.317C706.016 167.546 800.764 234.615 876.741 321.395C912.002 361.664 942.085 405.756 963.876 454.532C996.779 528.166 1011.85 610.046 965.895 681.369C952.379 702.359 935.427 718.818 914.283 731.871C884.432 747.421 852.947 758.671 818.872 761.06C839.523 755.959 859.404 750.981 878.637 740.424C929.186 717.061 964.601 671.567 974.818 616.488C987.671 547.245 964.693 475.429 930.881 415.357C903.834 367.305 871.471 326.049 832.311 286.905L832.342 286.936ZM890.673 420.18C861.623 370.387 825.515 327.621 783.288 287.999C721.659 230.161 650.028 185.345 570.598 156.033C513.623 135.013 454.506 124.394 393.786 128.108C353.316 130.59 315.728 139.867 280.498 159.516C245.268 179.166 216.819 204.918 201.023 240.394L188.617 268.242C204.583 180.445 278.325 132.054 361.931 119.355C412.757 111.634 462.658 116.643 512.421 129.048C596.905 150.116 674.1 189.923 743.45 242.028C816.607 296.999 885.526 373.531 924.578 456.982C949.713 510.675 965.094 571.61 949.837 630.234C939.018 671.768 912.511 706.566 875.308 727.987C847.013 744.292 816.191 754.679 783.242 758.101C825.915 745.926 863.75 731.917 895.327 698.799C913.512 679.72 926.535 657.62 933.054 631.714C951.347 558.989 927.49 483.274 890.642 420.134L890.673 420.18ZM726.19 279.369C625.678 198.799 493.404 141.917 362.655 156.973C343.854 159.131 326.547 164.17 308.639 169.195C301.18 171.29 295.201 177.732 286.493 176.253C378.313 130.081 492.063 149.545 583.143 188.119C684.102 230.87 775.952 302.825 840.664 391.069C871.794 433.527 895.805 479.652 909.506 530.386C918.382 563.273 920.232 596.654 911.941 629.294C905.622 654.153 895.481 677.778 875.786 694.9C893.987 666.327 905.452 637.693 907.086 604.128C908.72 570.562 903.141 536.565 891.567 503.57C861.392 417.53 797.066 336.19 726.205 279.384L726.19 279.369Z" fill="currentColor"/></svg>',"lockup")),s.appendChild(n)}else{f&&s.appendChild(f);const e=L("span","label",h);e.setAttribute("part","label"),s.appendChild(e),"idle"===p&&s.appendChild(E('<svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M6 3l5 5-5 5"/></svg>',"icon arrow"))}var b,g;b=p,null!==l?b!==l&&(l=b,c.textContent="connecting"===b?"Connecting to One…":"connected"===b?null!==(g=i.connectedLabel)&&void 0!==g?g:"Connected":""):l=b};return s.addEventListener("click",()=>{r||i.disabled||a||(a=!0,f(),C.open())}),f(),{update:e=>{i=e,C.update(F(i,u)),f()},destroy:()=>{r=!0,C.destroy(),o.replaceChildren()}}}function $(e,t){const n=document.createElement("span");n.className="one-connect";const o=e=>{var t;n.setAttribute("data-variant",null!==(t=e.variant)&&void 0!==t?t:"default"),n.toggleAttribute("data-full-width",Boolean(e.fullWidth))};o(t),e.appendChild(n);const i=M(n,t);return{update:e=>{o(e),i.update(e)},destroy:()=>{i.destroy(),n.remove()}}}const T=["authorize-url","logos","platforms","connected","disabled","variant","size","full-width","theme","connect-theme","label","connected-label","description"];function U(e,t,n){const o=e.getAttribute(t);return o&&n.includes(o)?o:void 0}const Z=(e,t)=>e.hasAttribute(t)?"false"!==e.getAttribute(t):void 0;function B(){if("undefined"!=typeof window&&"undefined"!=typeof customElements&&!customElements.get("one-connect-button")){class e extends HTMLElement{constructor(...e){super(...e),C(this,"onSuccess",null),C(this,"onError",null),C(this,"onCancel",null),C(this,"handle",null)}connectedCallback(){this.sync()}disconnectedCallback(){var e;null===(e=this.handle)||void 0===e||e.destroy(),this.handle=null}attributeChangedCallback(){this.isConnected&&this.sync()}props(e){var t,n,o,i;return{authorizeUrl:e,logos:x(null!==(t=this.getAttribute("logos"))&&void 0!==t?t:this.getAttribute("platforms")),connected:Z(this,"connected"),disabled:Z(this,"disabled"),variant:U(this,"variant",["default","accent","block"]),size:U(this,"size",["sm","md","lg"]),fullWidth:Z(this,"full-width"),theme:U(this,"theme",["light","dark","auto"]),connectTheme:U(this,"connect-theme",["light","dark"]),label:null!==(n=this.getAttribute("label"))&&void 0!==n?n:void 0,connectedLabel:null!==(o=this.getAttribute("connected-label"))&&void 0!==o?o:void 0,description:null!==(i=this.getAttribute("description"))&&void 0!==i?i:void 0,onSuccess:()=>{var e;null===(e=this.onSuccess)||void 0===e||e.call(this),this.dispatchEvent(new CustomEvent("success"))},onError:(e,t)=>{var n;null===(n=this.onError)||void 0===n||n.call(this,e,t),this.dispatchEvent(new CustomEvent("error",{detail:{message:e,code:t}}))},onCancel:()=>{var e;null===(e=this.onCancel)||void 0===e||e.call(this),this.dispatchEvent(new CustomEvent("cancel"))}}}sync(){const e=this.getAttribute("authorize-url");var t;if(!e)return null===(t=this.handle)||void 0===t||t.destroy(),void(this.handle=null);const n=this.props(e);this.handle?this.handle.update(n):this.handle=M(this,n)}}C(e,"observedAttributes",[...T]),customElements.define("one-connect-button",e)}}B();export{h as createConnectFlow,$ as mountConnectButton,p as readConnectReturn,B as registerConnectButton,M as renderConnectButton};
1
+ const e="one_connect",t="one_connect_error",n={declined:"You cancelled the connection.",expired:"The connection attempt expired. Please try again.",failed:"The connection could not be completed. Please try again."};function o(o){const i=new URLSearchParams(o),r=i.get(e);if("success"===r)return{status:r};if("error"!==r)return null;const a=i.get(t),l=null!==(s=a)&&Object.prototype.hasOwnProperty.call(n,s)?a:"failed";var s;return{status:r,code:l,message:n[l]}}const i=[e,t,"one_connect_message"];function r(e){const t=new URLSearchParams(e);return i.some(e=>t.has(e))}let a,l=!1,s=!1,c=!1;const d=[];function u(){return p()}function p(){return"undefined"==typeof window?null:(void 0===a&&(a=o(window.location.search),(a||r(window.location.search))&&function(){const e=()=>{r(window.location.search)&&window.history.replaceState(window.history.state,"",function(e){const t=new URLSearchParams(e.search);for(const e of i)t.delete(e);const n=t.toString();return`${e.pathname}${n?`?${n}`:""}${e.hash}`}(window.location))};e();for(const t of[50,500,2e3])window.setTimeout(e,t)}()),a)}function h(e){let t=e,n=!1;const o={deliver:e=>{try{var n,o,i,r,a,l;"success"===e.status?null===(n=(o=t).onSuccess)||void 0===n||n.call(o):null===(i=(r=t).onError)||void 0===i||i.call(r,null!==(a=e.message)&&void 0!==a?a:"",null!==(l=e.code)&&void 0!==l?l:"failed")}catch{}},restored:()=>{if(n){n=!1;try{var e,o;null===(e=(o=t).onCancel)||void 0===e||e.call(o)}catch{}}}};return"undefined"!=typeof window&&(d.push(o),c||"undefined"==typeof window||(c=!0,window.addEventListener("pageshow",e=>{if(e.persisted)for(const e of[...d])e.restored()})),function(){if(l||s)return;const e=p();e&&(s=!0,window.setTimeout(()=>{s=!1;const t=d[0];t&&!l&&(l=!0,t.deliver(e))},0))}()),{open:()=>{"undefined"!=typeof window&&(n=!0,window.location.assign((e=>{try{var t;const n=new URL(e.authorizeUrl,window.location.origin);e.returnTo&&n.searchParams.set("one_return_to",e.returnTo);const o=new URLSearchParams;e.connectTheme&&o.set("one_theme",e.connectTheme);const i=null===(t=e.connector)||void 0===t?void 0:t.trim().toLowerCase();i&&o.set("one_connector",i);const r=o.toString();return r&&(n.hash=r),n.toString()}catch{return e.authorizeUrl}})(t)))},update:e=>{t=e},destroy:()=>{const e=d.indexOf(o);e>=0&&d.splice(e,1)}}}function C(e,t,n){return(t=function(e){var t=function(e,t){if("object"!=typeof e||!e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var o=n.call(e,t);if("object"!=typeof o)return o;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:t+""}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function f(e){return e.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")}const b={"cal-com":"Cal.com","click-up":"ClickUp",clickup:"ClickUp",docusign:"DocuSign",elevenlabs:"ElevenLabs","fireflies-ai":"Fireflies.ai",github:"GitHub",gitlab:"GitLab",hubspot:"HubSpot","linked-in":"LinkedIn",linkedin:"LinkedIn","one-drive":"OneDrive",onedrive:"OneDrive",openai:"OpenAI","otter-ai":"Otter.ai",paypal:"PayPal",posthog:"PostHog",quickbooks:"QuickBooks",sharepoint:"SharePoint","spotify-web":"Spotify",teams:"Microsoft Teams","telegram-bot":"Telegram","whatsapp-business":"WhatsApp Business",woocommerce:"WooCommerce",x:"X","youtube-data":"YouTube",youtube:"YouTube"};function g(e){var t;return null!==(t=b[e])&&void 0!==t?t:e.split(/[-_]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(" ")}function v(e){return e?`https://assets.withone.ai/connectors/${e}.svg`:""}function m(e){var t,n,o,i;const r="string"==typeof e?{slug:e}:e,a=null!==(t=r.slug)&&void 0!==t&&t.trim()?f(r.slug):null!==(n=r.name)&&void 0!==n&&n.trim()?f(r.name):"";return a?{slug:a,name:(null===(o=r.name)||void 0===o?void 0:o.trim())||g(a),imageUrl:(null===(i=r.imageUrl)||void 0===i?void 0:i.trim())||v(a)}:null}function x(e){const t=null==e?void 0:e.trim();if(!t)return[];if(t.startsWith("["))try{const e=JSON.parse(t);return Array.isArray(e)?e.filter(e=>"string"==typeof e||"object"==typeof e&&null!==e):[]}catch{return[]}return t.split(",").map(e=>e.trim()).filter(Boolean)}const w="#CCFF00",y="#0A0C0B",k="#FFFFFF",A=`\n:host{display:inline-block;vertical-align:middle;max-width:100%}\n:host([data-full-width]),:host([full-width]:not([full-width="false"])),\n:host([data-variant="block"]),:host([variant="block"]){display:block;width:100%}\n.b{all:unset;box-sizing:border-box;position:relative;display:inline-flex;align-items:center;gap:var(--gap);\n max-width:100%;cursor:pointer;user-select:none;-webkit-tap-highlight-color:transparent;\n font-family:var(--one-connect-font,inherit);font-size:var(--fs);font-weight:500;line-height:1.2;letter-spacing:-.01em;\n padding:var(--pad);border-radius:var(--one-connect-radius,12px);background:var(--bg);color:var(--fg);\n box-shadow:var(--shadow);transition:box-shadow .2s var(--ease),background-color .2s var(--ease),opacity .2s var(--ease)}\n.b[data-full-width]{display:flex;width:100%;justify-content:center}\n.b:focus-visible{outline:2px solid var(--ring);outline-offset:2px}\n.b:hover{box-shadow:var(--shadow-hover)}\n.b[disabled]{cursor:not-allowed;opacity:.5;box-shadow:none}\n.b[aria-busy="true"]{cursor:progress}\n.b{--ease:cubic-bezier(.2,.9,.25,1)}\n.b[data-size="sm"]{--fs:13px;--pad:8px 12px 8px 10px;--gap:8px;--chip:18px;--logo:12px}\n.b[data-size="md"]{--fs:14.5px;--pad:12px 16px 12px 14px;--gap:12px;--chip:22px;--logo:14px}\n.b[data-size="lg"]{--fs:16px;--pad:14px 20px 14px 16px;--gap:12px;--chip:26px;--logo:16px}\n.b[data-theme="light"],.b[data-theme="auto"]{--ink-bg:${y};--ink-fg:${k};--surface:${k};--surface-fg:${y};\n --muted:#5B6560;--line:#D5DAD7;--ring:${y};--shadow-base:0 1px 2px rgba(10,12,11,.08),0 4px 14px rgba(10,12,11,.06);\n --shadow-strong:0 1px 2px rgba(10,12,11,.12),0 6px 18px rgba(10,12,11,.1)}\n.b[data-theme="dark"]{--ink-bg:#F2F5F3;--ink-fg:${y};--surface:#101312;--surface-fg:#F2F5F3;\n --muted:#9AA39E;--line:#2A302D;--ring:${w};--shadow-base:0 1px 2px rgba(0,0,0,.4),0 8px 24px rgba(0,0,0,.35);\n --shadow-strong:0 1px 2px rgba(0,0,0,.5),0 10px 28px rgba(0,0,0,.45)}\n@media (prefers-color-scheme:dark){.b[data-theme="auto"]{--ink-bg:#F2F5F3;--ink-fg:${y};--surface:#101312;--surface-fg:#F2F5F3;\n --muted:#9AA39E;--line:#2A302D;--ring:${w};--shadow-base:0 1px 2px rgba(0,0,0,.4),0 8px 24px rgba(0,0,0,.35);\n --shadow-strong:0 1px 2px rgba(0,0,0,.5),0 10px 28px rgba(0,0,0,.45)}}\n.b[data-variant="default"]{--bg:var(--ink-bg);--fg:var(--ink-fg);--shadow:var(--shadow-base);--shadow-hover:var(--shadow-strong)}\n.b[data-variant="accent"]{--bg:var(--one-connect-accent,${w});--fg:var(--one-connect-accent-fg,${y});\n --shadow:0 1px 2px rgba(10,12,11,.1);--shadow-hover:0 1px 2px rgba(10,12,11,.12),0 6px 18px rgba(10,12,11,.12)}\n.b[data-variant="block"]{--bg:var(--surface);--fg:var(--surface-fg);--shadow:inset 0 0 0 1px var(--line);\n --shadow-hover:inset 0 0 0 1px var(--muted);flex-direction:column;align-items:stretch;gap:0;\n width:100%;max-width:420px;text-align:left;padding:16px;border-radius:var(--one-connect-radius,14px)}\n.b[data-variant="block"][data-full-width]{max-width:none}\n.stack{display:inline-flex;align-items:center;flex-shrink:0}\n.chip{width:var(--chip);height:var(--chip);border-radius:6px;display:grid;place-items:center;overflow:hidden;\n margin-left:-7px;position:relative;background:${k};color:${y};box-shadow:0 0 0 1.5px var(--bg);\n transition:margin-left .28s var(--ease)}\n.chip:first-child{margin-left:0}\n.b[data-variant="block"] .chip{box-shadow:0 0 0 1.5px var(--bg),0 0 0 2.5px var(--line)}\n.chip img{width:var(--logo);height:var(--logo);display:block;object-fit:contain}\n.chip.more,.chip.letter{font:500 9px/1 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:-.02em}\n.chip.letter{font-size:10px;font-weight:600}\n.b:hover .chip{margin-left:-2px}.b:hover .chip:first-child{margin-left:0}\n.label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.icon{display:inline-flex;flex-shrink:0}\n.arrow{opacity:.55;transition:transform .2s var(--ease),opacity .2s var(--ease)}\n.b:hover .arrow{transform:translateX(2px);opacity:.85}\n.spinner{width:16px;height:16px;border-radius:50%;border:2px solid currentColor;border-top-color:transparent;\n opacity:.7;animation:spin .7s linear infinite;flex-shrink:0}\n@keyframes spin{to{transform:rotate(360deg)}}\n.top{display:flex;align-items:center;justify-content:space-between;gap:12px}\n.title{font-size:15px;font-weight:600;letter-spacing:-.01em}\n.sub{font-size:13px;line-height:1.5;margin-top:6px;font-weight:400;color:var(--muted)}\n.foot{margin-top:14px;padding-top:12px;display:flex;align-items:center;gap:6px;font-size:11px;font-weight:400;\n color:var(--muted);border-top:1px solid var(--line)}\n.lockup{display:inline-flex;color:var(--surface-fg)}\n.sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}\n@media (prefers-reduced-motion:reduce){.b,.chip,.arrow{transition:none}.spinner{animation-duration:1.6s}}\n@media (forced-colors:active){.b{border:1px solid ButtonText}.b:focus-visible{outline-color:Highlight}}\n`;let S=null;const L=(e,t,n)=>{const o=document.createElement(e);return t&&(o.className=t),void 0!==n&&(o.textContent=n),o},E=(e,t="icon")=>{const n=L("span",t);return n.innerHTML=e,n};function z(e){var t;const n=(null!=(o=null!==(t=e.logos)&&void 0!==t?t:e.platforms)?o:[]).map(m).filter(e=>null!==e);var o;if(0===n.length)return null;const i=L("span","stack");i.setAttribute("aria-hidden","true");for(const e of n.slice(0,3)){const t=L("span","chip");t.title=e.name;const n=L("img");n.alt="",n.decoding="async",n.src=e.imageUrl,n.addEventListener("error",()=>{n.remove(),t.classList.add("letter"),t.textContent=e.name.charAt(0).toUpperCase()}),t.appendChild(n),i.appendChild(t)}const r=n.length-3;return r>0&&i.appendChild(L("span","chip more",`+${r}`)),i}const F=(e,t)=>({authorizeUrl:e.authorizeUrl,connectTheme:e.connectTheme,connector:e.connector,returnTo:e.returnTo,...t});function M(e,t){var n;const o=null!==(n=e.shadowRoot)&&void 0!==n?n:e.attachShadow({mode:"open"});!function(e){if("undefined"!=typeof CSSStyleSheet&&"replaceSync"in CSSStyleSheet.prototype&&"adoptedStyleSheets"in e)try{return S||(S=new CSSStyleSheet,S.replaceSync(A)),void(e.adoptedStyleSheets=[S])}catch{}const t=document.createElement("style");t.textContent=A,e.appendChild(t)}(o);let i=t,r=!1,a=!1,l=null;const s=L("button","b");s.type="button",s.setAttribute("part","button");const c=L("span","sr");c.setAttribute("role","status"),c.setAttribute("aria-live","polite"),o.append(s,c);const d=()=>{return r?"connecting":void 0!==i.connected?i.connected?"connected":"idle":"success"===(null===(e=u())||void 0===e?void 0:e.status)?"connected":"idle";var e},p={onSuccess:()=>{var e,t;return null===(e=(t=i).onSuccess)||void 0===e?void 0:e.call(t)},onError:(e,t)=>{var n,o;return null===(n=(o=i).onError)||void 0===n?void 0:n.call(o,e,t)},onCancel:()=>{var e,t;r=!1,f(),null===(e=(t=i).onCancel)||void 0===e||e.call(t)}},C=h(F(i,p)),f=()=>{var e,t,n,o,r;if(a)return;const u=d(),p=null!==(e=i.variant)&&void 0!==e?e:"default",h="connecting"===u?"Connecting…":"connected"===u?null!==(t=i.connectedLabel)&&void 0!==t?t:"Connected":null!==(n=i.label)&&void 0!==n?n:"Connect your apps";s.dataset.variant=p,s.dataset.size=null!==(o=i.size)&&void 0!==o?o:"md",s.dataset.theme=null!==(r=i.theme)&&void 0!==r?r:"light",s.dataset.state=u,s.toggleAttribute("data-full-width",Boolean(i.fullWidth)),s.disabled=Boolean(i.disabled),s.setAttribute("aria-busy",String("connecting"===u)),"connecting"===u?s.setAttribute("aria-disabled","true"):s.removeAttribute("aria-disabled");const C="idle"===u?z(i):null,f="connecting"===u?L("span","spinner"):"connected"===u?E('<svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M3 8.5l3.5 3.5L13 5"/></svg>'):C;if(s.replaceChildren(),s.removeAttribute("aria-labelledby"),s.removeAttribute("aria-describedby"),"block"===p){const e=L("span","top"),t=L("span","title",h);if(t.id="one-connect-title",t.setAttribute("part","label"),e.appendChild(t),f&&e.appendChild(f),s.appendChild(e),s.setAttribute("aria-labelledby",t.id),i.description){const e=L("span","sub",i.description);e.id="one-connect-description",s.appendChild(e),s.setAttribute("aria-describedby",e.id)}const n=L("span","foot");n.setAttribute("aria-hidden","true"),n.append(L("span","","Secured by"),E('<svg viewBox="0 0 3152 990" width="35" height="11" fill="none" aria-hidden="true" focusable="false"><path d="M1698.02 793.203C1525.75 793.203 1401 666.834 1401 495.102C1401 323.909 1524.67 197 1698.02 197C1870.83 197 1996.12 323.909 1996.12 495.102C1996.12 666.834 1869.75 793.203 1698.02 793.203ZM1698.02 694.916C1801.71 694.916 1884.88 615.53 1884.88 495.102C1884.88 374.133 1801.71 295.827 1698.02 295.827C1594.87 295.827 1511.71 373.053 1511.71 495.102C1511.71 616.61 1595.41 694.916 1698.02 694.916Z" fill="currentColor"/><path d="M2326.71 197.54C2480.62 197.54 2565.95 289.887 2565.95 467.56V779.702H2455.24V468.64C2455.24 361.172 2411.5 292.587 2308.35 292.587C2217.63 292.587 2140.4 356.852 2140.4 484.841V779.702H2030.77V211.041H2140.4V272.065C2185.76 225.082 2248.41 197.54 2326.71 197.54Z" fill="currentColor"/><path d="M3151.98 493.481C3151.98 514.003 3150.36 520.483 3148.74 529.124H2700.51C2715.63 637.672 2794.47 686.815 2922.46 686.815C3031.01 686.815 3099.6 650.633 3116.88 643.072V747.84C3100.68 755.4 3023.45 793.203 2908.96 793.203C2699.97 793.203 2588.18 661.434 2588.18 497.802C2588.18 332.55 2702.67 197 2871.7 197C3031.55 197 3151.98 317.969 3151.98 493.481ZM2876.02 300.688C2784.75 300.688 2720.49 345.511 2702.67 434.617H3050.45C3034.79 344.971 2967.29 300.688 2876.02 300.688Z" fill="currentColor"/><path d="M537.494 782.175C641.011 827.7 767.922 858.83 880.501 839.875C983.155 822.599 1069.64 764.946 1094.39 659.271C1114.47 573.493 1088.54 481.273 1047.27 405.311C983.124 287.246 874.768 183.791 759.847 114.657C644.926 45.5225 507.181 -5.02605 372.102 0.398669C289.698 3.69665 205.938 26.536 146.544 85.6685C112.069 119.989 88.3818 171.231 83.1266 219.823C78.1642 265.64 84.3749 310.317 99.8478 354.007C168.243 547.14 354.009 701.467 537.51 782.191L537.494 782.175ZM751.956 818.053C583.05 796.2 415.7 707.108 292.472 593.004C222.536 528.246 159.366 444.979 125.985 355.471C102.961 293.734 96.3956 223.367 122.41 161.969C137.158 127.14 160.367 98.244 190.743 75.9133C275.581 13.5752 395.819 6.99464 495.977 26.8596C608.848 49.252 713.875 99.4615 806.712 166.515C907.085 239.025 999.537 339.922 1048.42 454.627C1072.45 511.001 1083.99 570.103 1075.64 630.869C1067.38 690.957 1034.57 742.353 983.987 775.379C917.626 818.715 830.861 828.255 751.972 818.053H751.956Z" fill="currentColor"/><path d="M1103.27 661.228C1086.68 755.313 1024.9 818.622 934.021 848.69C821.751 885.846 685.146 860.263 576.251 818.915C452.515 771.942 340.336 699.91 245.157 607.813C209.002 572.83 177.255 534.456 148.837 493.031C100.384 422.402 61.7024 335.19 65.8326 248.071C68.2213 197.769 83.987 159.241 111.403 116.938C45.8289 171.308 31.404 262.511 47.1543 342.002C53.4728 373.841 62.9815 403.23 76.528 432.958C100.338 485.202 130.914 532.992 167.747 577.238C255.452 682.573 367.83 765.13 491.073 824.124C614.317 883.118 769.307 920.691 900.471 889.128C985.788 868.601 1061.47 816.095 1090.83 730.856C1098.18 708.71 1104.61 686.564 1103.25 661.244L1103.27 661.228Z" fill="currentColor"/><path d="M883.297 963.502C923.15 947.074 960.877 926.022 988.309 893.967C954.265 917.839 920.931 934.807 882.403 944.993C751.747 979.53 595.123 942.589 474.731 886.57C422.102 862.082 372.617 834.018 325.181 800.591C205.128 715.984 89.4825 597.996 36.7762 458.756C20.2092 414.973 11.7793 370.404 11.5327 323.739C11.4249 302.641 15.4627 283.747 19.0226 263.004C-2.52219 310.486 -3.66265 380.915 5.21419 431.617C32.0605 584.881 147.151 721.146 266.988 813.983C343.443 873.224 436.403 924.913 528.424 954.672C620.444 984.431 713.851 999.426 808.491 983.598C834.459 979.252 858.362 973.781 883.297 963.502Z" fill="currentColor"/><path d="M1045.09 830.737C1053.55 816.158 1061.75 802.95 1066.99 787.061C1043.75 824.541 1013.3 854.408 974.29 874.982C947.752 888.991 920.228 899.27 890.577 905.219C864.578 910.428 839.673 914.481 812.781 914.851C739.716 915.852 668.717 903.092 599.459 880.854C418.686 822.8 238.422 697.6 127.985 543.165C94.8819 496.87 68.8679 447.847 50.7135 394.031C28.1978 324.45 25.7782 258.69 53.4104 189.078C36.1345 211.825 26.9956 237.793 20.4151 264.916C18.3654 282.732 14.713 299.345 15.0828 317.561C15.9613 360.774 23.5436 402.692 38.477 443.562C73.1522 538.464 134.936 621.869 207.368 691.913C307.34 788.587 426.762 862.268 558.127 907.993C689.491 953.718 871.975 973.768 992.614 885.446C1013.28 870.312 1029.39 851.773 1045.07 830.752L1045.09 830.737Z" fill="currentColor"/><path d="M552.552 745.664C671.079 797.831 835.825 835.526 954.768 769.12C999.137 744.354 1031.99 705.626 1047.99 657.312C1086.75 540.264 1020.28 405.817 947.124 315.631C855.536 202.745 729.688 114.516 592.76 66.0323C506.349 35.4412 418.968 22.0797 328.211 37.46C262.313 48.6177 195.29 81.7054 157.563 138.234C118.912 196.133 115.891 270.785 136.758 335.882C176.519 459.926 276.769 570.763 381.01 646.277C434.995 685.391 491.662 718.864 552.567 745.664H552.552ZM210.162 422.955C199.898 402.381 189.141 382.701 184.733 360.385C182.267 347.918 184.625 333.477 184.564 320.64C184.44 293.223 194.072 269.059 209.992 247.93C219.609 235.17 229.456 224.844 243.018 215.906C341.218 151.179 476.051 175.991 576.763 223.904C661.971 264.435 737.394 321.534 796.11 395.862C836.919 447.52 871.193 513.634 880.502 579.501C888.238 634.272 873.243 695.485 826.763 729.189C807.853 742.905 785.045 751.721 761.728 755.974C721.921 763.217 688.802 758.008 649.565 748.916C594.27 736.094 542.488 715.212 492.279 688.889C441.977 662.521 396.745 631.483 353.008 595.436C314.372 563.597 280.252 537.845 248.458 498.007L248.274 497.837L221.504 461.945L211.379 445.84C194.103 418.408 177.398 391.346 165.238 361.202C151.291 326.604 142.676 291.852 143.678 254.279C146.19 160.564 203.766 96.7467 290.238 67.82C434.394 19.5985 611.561 79.4246 735.298 157.636C825.099 214.411 904.435 286.581 963.321 375.134C989.767 414.894 1010.42 456.998 1023.78 502.646C1049.84 591.66 1036.79 685.884 957.404 742.659C890.257 790.68 785.6 793.146 707.295 776.486C680.403 769.736 654.065 766.007 629.222 754.818C732.107 783.93 882.397 797.723 963.938 715.35C990.599 688.412 1007.55 656.218 1013.75 618.537C1020.87 575.232 1016.12 531.634 1002.62 489.931C985.498 437.071 956.34 384.026 922.405 340.289C876.911 281.665 823.188 230.531 762.468 187.981C681.112 130.975 588.783 88.887 490.799 71.0872C425.595 59.2514 349.463 60.4072 287.557 85.0959C256.441 97.5019 228.501 114.5 205.924 138.85C158.303 190.2 147.176 256.036 161.539 323.383C166.856 348.334 175.456 371.296 185.596 394.737C194.488 415.295 222.676 461.883 236.022 477.649L226.729 456.196L210.162 423.001V422.955ZM832.342 286.936C756.904 211.544 666.44 154.076 564.896 120.249C526.553 107.473 487.948 99.4899 447.648 96.084C401.26 92.1696 356.167 96.7313 312.215 111.341C222.337 141.208 169.399 217.277 175.255 312.333C177.567 324.847 179.555 335.774 180.603 348.503C152.971 264.944 174.454 175.236 251.356 125.581C310.797 87.2072 387.39 78.2071 456.694 86.7603C503.714 92.5549 555.387 106.656 599.078 124.317C706.016 167.546 800.764 234.615 876.741 321.395C912.002 361.664 942.085 405.756 963.876 454.532C996.779 528.166 1011.85 610.046 965.895 681.369C952.379 702.359 935.427 718.818 914.283 731.871C884.432 747.421 852.947 758.671 818.872 761.06C839.523 755.959 859.404 750.981 878.637 740.424C929.186 717.061 964.601 671.567 974.818 616.488C987.671 547.245 964.693 475.429 930.881 415.357C903.834 367.305 871.471 326.049 832.311 286.905L832.342 286.936ZM890.673 420.18C861.623 370.387 825.515 327.621 783.288 287.999C721.659 230.161 650.028 185.345 570.598 156.033C513.623 135.013 454.506 124.394 393.786 128.108C353.316 130.59 315.728 139.867 280.498 159.516C245.268 179.166 216.819 204.918 201.023 240.394L188.617 268.242C204.583 180.445 278.325 132.054 361.931 119.355C412.757 111.634 462.658 116.643 512.421 129.048C596.905 150.116 674.1 189.923 743.45 242.028C816.607 296.999 885.526 373.531 924.578 456.982C949.713 510.675 965.094 571.61 949.837 630.234C939.018 671.768 912.511 706.566 875.308 727.987C847.013 744.292 816.191 754.679 783.242 758.101C825.915 745.926 863.75 731.917 895.327 698.799C913.512 679.72 926.535 657.62 933.054 631.714C951.347 558.989 927.49 483.274 890.642 420.134L890.673 420.18ZM726.19 279.369C625.678 198.799 493.404 141.917 362.655 156.973C343.854 159.131 326.547 164.17 308.639 169.195C301.18 171.29 295.201 177.732 286.493 176.253C378.313 130.081 492.063 149.545 583.143 188.119C684.102 230.87 775.952 302.825 840.664 391.069C871.794 433.527 895.805 479.652 909.506 530.386C918.382 563.273 920.232 596.654 911.941 629.294C905.622 654.153 895.481 677.778 875.786 694.9C893.987 666.327 905.452 637.693 907.086 604.128C908.72 570.562 903.141 536.565 891.567 503.57C861.392 417.53 797.066 336.19 726.205 279.384L726.19 279.369Z" fill="currentColor"/></svg>',"lockup")),s.appendChild(n)}else{f&&s.appendChild(f);const e=L("span","label",h);e.setAttribute("part","label"),s.appendChild(e),"idle"===u&&s.appendChild(E('<svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M6 3l5 5-5 5"/></svg>',"icon arrow"))}var b,g;b=u,null!==l?b!==l&&(l=b,c.textContent="connecting"===b?"Connecting to One…":"connected"===b?null!==(g=i.connectedLabel)&&void 0!==g?g:"Connected":""):l=b};return s.addEventListener("click",()=>{a||i.disabled||r||(r=!0,f(),C.open())}),f(),{update:e=>{i=e,C.update(F(i,p)),f()},destroy:()=>{a=!0,C.destroy(),o.replaceChildren()}}}function T(e,t){const n=document.createElement("span");n.className="one-connect";const o=e=>{var t;n.setAttribute("data-variant",null!==(t=e.variant)&&void 0!==t?t:"default"),n.toggleAttribute("data-full-width",Boolean(e.fullWidth))};o(t),e.appendChild(n);const i=M(n,t);return{update:e=>{o(e),i.update(e)},destroy:()=>{i.destroy(),n.remove()}}}const $=["authorize-url","logos","platforms","connected","disabled","variant","size","full-width","theme","connect-theme","connector","return-to","label","connected-label","description"];function U(e,t,n){const o=e.getAttribute(t);return o&&n.includes(o)?o:void 0}const P=(e,t)=>e.hasAttribute(t)?"false"!==e.getAttribute(t):void 0;function Z(){if("undefined"!=typeof window&&"undefined"!=typeof customElements&&!customElements.get("one-connect-button")){class e extends HTMLElement{constructor(...e){super(...e),C(this,"onSuccess",null),C(this,"onError",null),C(this,"onCancel",null),C(this,"handle",null)}connectedCallback(){this.sync()}disconnectedCallback(){var e;null===(e=this.handle)||void 0===e||e.destroy(),this.handle=null}attributeChangedCallback(){this.isConnected&&this.sync()}props(e){var t,n,o,i,r,a;return{authorizeUrl:e,logos:x(null!==(t=this.getAttribute("logos"))&&void 0!==t?t:this.getAttribute("platforms")),connected:P(this,"connected"),disabled:P(this,"disabled"),variant:U(this,"variant",["default","accent","block"]),size:U(this,"size",["sm","md","lg"]),fullWidth:P(this,"full-width"),theme:U(this,"theme",["light","dark","auto"]),connectTheme:U(this,"connect-theme",["light","dark"]),connector:null!==(n=this.getAttribute("connector"))&&void 0!==n?n:void 0,returnTo:null!==(o=this.getAttribute("return-to"))&&void 0!==o?o:void 0,label:null!==(i=this.getAttribute("label"))&&void 0!==i?i:void 0,connectedLabel:null!==(r=this.getAttribute("connected-label"))&&void 0!==r?r:void 0,description:null!==(a=this.getAttribute("description"))&&void 0!==a?a:void 0,onSuccess:()=>{var e;null===(e=this.onSuccess)||void 0===e||e.call(this),this.dispatchEvent(new CustomEvent("success"))},onError:(e,t)=>{var n;null===(n=this.onError)||void 0===n||n.call(this,e,t),this.dispatchEvent(new CustomEvent("error",{detail:{message:e,code:t}}))},onCancel:()=>{var e;null===(e=this.onCancel)||void 0===e||e.call(this),this.dispatchEvent(new CustomEvent("cancel"))}}}sync(){const e=this.getAttribute("authorize-url");var t;if(!e)return null===(t=this.handle)||void 0===t||t.destroy(),void(this.handle=null);const n=this.props(e);this.handle?this.handle.update(n):this.handle=M(this,n)}}C(e,"observedAttributes",[...$]),customElements.define("one-connect-button",e)}}Z();export{h as createConnectFlow,T as mountConnectButton,u as readConnectReturn,Z as registerConnectButton,M as renderConnectButton};
package/dist/next.cjs.js CHANGED
@@ -1,5 +1,13 @@
1
1
  'use strict';
2
2
 
3
+ /** Query params the app's callback route puts on its final redirect.
4
+ * The SDK reads them off the page URL when the tab comes home, so
5
+ * there is no completion page to build. */
6
+
7
+ /** Query param on the app's own authorize route naming where this one
8
+ * flow returns to. The route reads it; it never reaches One. */
9
+ const RETURN_TO_PARAM = "one_return_to";
10
+
3
11
  /**
4
12
  * `@withone/connect/next`: the two routes as one file, for any server
5
13
  * that speaks the web `Request` and `Response` (Next.js App Router,
@@ -16,7 +24,6 @@
16
24
  * That serves /api/one/authorize and /api/one/callback. Register
17
25
  * `https://yourapp.com/api/one/callback` as the app's redirect URI.
18
26
  */
19
-
20
27
  const AUTHORIZE_ROUTE = "authorize";
21
28
  const CALLBACK_ROUTE = "callback";
22
29
  function redirectWithCookies(location, setCookies) {
@@ -67,11 +74,15 @@ function createOneConnectRoutes(oneConnect, options) {
67
74
  const user = await requireUser(request);
68
75
  if (user instanceof Response) return user;
69
76
  const loginHint = (await options.loginHintFor?.(request)) ?? undefined;
77
+ // The browser flow names where this one flow returns to; the client
78
+ // keeps only a path on the app, so a crafted link goes nowhere else.
79
+ const returnTo = new URL(request.url).searchParams.get(RETURN_TO_PARAM) ?? undefined;
70
80
  const {
71
81
  redirectUrl,
72
82
  cookie
73
83
  } = oneConnect.startAuthorization({
74
- loginHint
84
+ loginHint,
85
+ returnTo
75
86
  });
76
87
  return redirectWithCookies(redirectUrl, [serializeCookie(cookie.name, cookie.value, cookie.options)]);
77
88
  };
package/dist/next.d.ts CHANGED
@@ -1,19 +1,3 @@
1
- /**
2
- * `@withone/connect/next`: the two routes as one file, for any server
3
- * that speaks the web `Request` and `Response` (Next.js App Router,
4
- * Remix, SvelteKit, Nuxt/h3 via its adapters, Hono, Bun).
5
- *
6
- * // app/api/one/[action]/route.ts
7
- * import { createOneConnectRoutes } from "@withone/connect/next";
8
- * import { oneConnect } from "@/lib/one";
9
- *
10
- * export const { GET } = createOneConnectRoutes(oneConnect, {
11
- * identifyUser: async (request) => getSessionUserId(request),
12
- * });
13
- *
14
- * That serves /api/one/authorize and /api/one/callback. Register
15
- * `https://yourapp.com/api/one/callback` as the app's redirect URI.
16
- */
17
1
  import type { CompleteAuthorizationResult, OneConnectClient } from "./server";
18
2
  export interface OneConnectRoutesOptions {
19
3
  /** The app's own id for the signed-in user, or null when nobody is
package/dist/next.esm.js CHANGED
@@ -1,3 +1,11 @@
1
+ /** Query params the app's callback route puts on its final redirect.
2
+ * The SDK reads them off the page URL when the tab comes home, so
3
+ * there is no completion page to build. */
4
+
5
+ /** Query param on the app's own authorize route naming where this one
6
+ * flow returns to. The route reads it; it never reaches One. */
7
+ const RETURN_TO_PARAM = "one_return_to";
8
+
1
9
  /**
2
10
  * `@withone/connect/next`: the two routes as one file, for any server
3
11
  * that speaks the web `Request` and `Response` (Next.js App Router,
@@ -14,7 +22,6 @@
14
22
  * That serves /api/one/authorize and /api/one/callback. Register
15
23
  * `https://yourapp.com/api/one/callback` as the app's redirect URI.
16
24
  */
17
-
18
25
  const AUTHORIZE_ROUTE = "authorize";
19
26
  const CALLBACK_ROUTE = "callback";
20
27
  function redirectWithCookies(location, setCookies) {
@@ -65,11 +72,15 @@ function createOneConnectRoutes(oneConnect, options) {
65
72
  const user = await requireUser(request);
66
73
  if (user instanceof Response) return user;
67
74
  const loginHint = (await options.loginHintFor?.(request)) ?? undefined;
75
+ // The browser flow names where this one flow returns to; the client
76
+ // keeps only a path on the app, so a crafted link goes nowhere else.
77
+ const returnTo = new URL(request.url).searchParams.get(RETURN_TO_PARAM) ?? undefined;
68
78
  const {
69
79
  redirectUrl,
70
80
  cookie
71
81
  } = oneConnect.startAuthorization({
72
- loginHint
82
+ loginHint,
83
+ returnTo
73
84
  });
74
85
  return redirectWithCookies(redirectUrl, [serializeCookie(cookie.name, cookie.value, cookie.options)]);
75
86
  };
package/dist/react.cjs.js CHANGED
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- "use strict";var e=require("react"),n=require("@withone/connect");const r=e=>{var n,r;return JSON.stringify([e.authorizeUrl,null!==(n=null!==(r=e.logos)&&void 0!==r?r:e.platforms)&&void 0!==n?n:[],e.connected,e.disabled,e.variant,e.size,e.fullWidth,e.theme,e.connectTheme,e.label,e.connectedLabel,e.description])};exports.ConnectButton=function(t){var u;const c=e.useRef(null),l=e.useRef(null),o=e.useRef(""),s=e.useRef(t);s.current=t;const a=()=>({...s.current,onSuccess:()=>{var e,n;return null===(e=(n=s.current).onSuccess)||void 0===e?void 0:e.call(n)},onError:(e,n)=>{var r,t;return null===(r=(t=s.current).onError)||void 0===r?void 0:r.call(t,e,n)},onCancel:()=>{var e,n;return null===(e=(n=s.current).onCancel)||void 0===e?void 0:e.call(n)}});e.useEffect(()=>{if(c.current)return l.current=n.renderConnectButton(c.current,a()),o.current=r(s.current),()=>{var e;null===(e=l.current)||void 0===e||e.destroy(),l.current=null}},[]);const i=r(t);return e.useEffect(()=>{l.current&&i!==o.current&&(o.current=i,l.current.update(a()))},[i]),e.createElement("span",{ref:c,className:t.className?`one-connect ${t.className}`:"one-connect",style:t.style,"data-variant":null!==(u=t.variant)&&void 0!==u?u:"default","data-full-width":t.fullWidth?"":void 0})},exports.useOneConnect=function(r){const[t,u]=e.useState("idle"),[c,l]=e.useState(null),o=e.useRef(r);o.current=r;const s=e.useRef(null),a=()=>({...o.current,onSuccess:()=>{var e,n;return null===(e=(n=o.current).onSuccess)||void 0===e?void 0:e.call(n)},onError:(e,n)=>{var r,t;return null===(r=(t=o.current).onError)||void 0===r?void 0:r.call(t,e,n)},onCancel:()=>{var e,n;u("idle"),null===(e=(n=o.current).onCancel)||void 0===e||e.call(n)}});return e.useEffect(()=>{const e=n.createConnectFlow(a());s.current=e;const r=n.readConnectReturn();if("success"===(null==r?void 0:r.status))u("connected");else if("error"===(null==r?void 0:r.status)){var t,c;u("error"),l({message:null!==(t=r.message)&&void 0!==t?t:"",code:null!==(c=r.code)&&void 0!==c?c:"failed"})}return()=>{e.destroy(),s.current=null}},[]),e.useEffect(()=>{var e;null===(e=s.current)||void 0===e||e.update(a())}),{open:e.useCallback(()=>{s.current&&(l(null),u("connecting"),s.current.open())},[]),status:t,error:c}};
2
+ "use strict";var e=require("react"),n=require("@withone/connect");const r=e=>{var n,r;return JSON.stringify([e.authorizeUrl,null!==(n=null!==(r=e.logos)&&void 0!==r?r:e.platforms)&&void 0!==n?n:[],e.connected,e.disabled,e.variant,e.size,e.fullWidth,e.theme,e.connectTheme,e.connector,e.returnTo,e.label,e.connectedLabel,e.description])};exports.ConnectButton=function(t){var u;const c=e.useRef(null),l=e.useRef(null),o=e.useRef(""),s=e.useRef(t);s.current=t;const a=()=>({...s.current,onSuccess:()=>{var e,n;return null===(e=(n=s.current).onSuccess)||void 0===e?void 0:e.call(n)},onError:(e,n)=>{var r,t;return null===(r=(t=s.current).onError)||void 0===r?void 0:r.call(t,e,n)},onCancel:()=>{var e,n;return null===(e=(n=s.current).onCancel)||void 0===e?void 0:e.call(n)}});e.useEffect(()=>{if(c.current)return l.current=n.renderConnectButton(c.current,a()),o.current=r(s.current),()=>{var e;null===(e=l.current)||void 0===e||e.destroy(),l.current=null}},[]);const i=r(t);return e.useEffect(()=>{l.current&&i!==o.current&&(o.current=i,l.current.update(a()))},[i]),e.createElement("span",{ref:c,className:t.className?`one-connect ${t.className}`:"one-connect",style:t.style,"data-variant":null!==(u=t.variant)&&void 0!==u?u:"default","data-full-width":t.fullWidth?"":void 0})},exports.useOneConnect=function(r){const[t,u]=e.useState("idle"),[c,l]=e.useState(null),o=e.useRef(r);o.current=r;const s=e.useRef(null),a=()=>({...o.current,onSuccess:()=>{var e,n;return null===(e=(n=o.current).onSuccess)||void 0===e?void 0:e.call(n)},onError:(e,n)=>{var r,t;return null===(r=(t=o.current).onError)||void 0===r?void 0:r.call(t,e,n)},onCancel:()=>{var e,n;u("idle"),null===(e=(n=o.current).onCancel)||void 0===e||e.call(n)}});return e.useEffect(()=>{const e=n.createConnectFlow(a());s.current=e;const r=n.readConnectReturn();if("success"===(null==r?void 0:r.status))u("connected");else if("error"===(null==r?void 0:r.status)){var t,c;u("error"),l({message:null!==(t=r.message)&&void 0!==t?t:"",code:null!==(c=r.code)&&void 0!==c?c:"failed"})}return()=>{e.destroy(),s.current=null}},[]),e.useEffect(()=>{var e;null===(e=s.current)||void 0===e||e.update(a())}),{open:e.useCallback(()=>{s.current&&(l(null),u("connecting"),s.current.open())},[]),status:t,error:c}};
package/dist/react.esm.js CHANGED
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{useRef as r,useEffect as n,createElement as e,useState as t,useCallback as l}from"react";import{renderConnectButton as c,createConnectFlow as o,readConnectReturn as u}from"@withone/connect";const a=r=>{var n,e;return JSON.stringify([r.authorizeUrl,null!==(n=null!==(e=r.logos)&&void 0!==e?e:r.platforms)&&void 0!==n?n:[],r.connected,r.disabled,r.variant,r.size,r.fullWidth,r.theme,r.connectTheme,r.label,r.connectedLabel,r.description])};function s(t){var l;const o=r(null),u=r(null),s=r(""),i=r(t);i.current=t;const d=()=>({...i.current,onSuccess:()=>{var r,n;return null===(r=(n=i.current).onSuccess)||void 0===r?void 0:r.call(n)},onError:(r,n)=>{var e,t;return null===(e=(t=i.current).onError)||void 0===e?void 0:e.call(t,r,n)},onCancel:()=>{var r,n;return null===(r=(n=i.current).onCancel)||void 0===r?void 0:r.call(n)}});n(()=>{if(o.current)return u.current=c(o.current,d()),s.current=a(i.current),()=>{var r;null===(r=u.current)||void 0===r||r.destroy(),u.current=null}},[]);const v=a(t);return n(()=>{u.current&&v!==s.current&&(s.current=v,u.current.update(d()))},[v]),e("span",{ref:o,className:t.className?`one-connect ${t.className}`:"one-connect",style:t.style,"data-variant":null!==(l=t.variant)&&void 0!==l?l:"default","data-full-width":t.fullWidth?"":void 0})}function i(e){const[c,a]=t("idle"),[s,i]=t(null),d=r(e);d.current=e;const v=r(null),f=()=>({...d.current,onSuccess:()=>{var r,n;return null===(r=(n=d.current).onSuccess)||void 0===r?void 0:r.call(n)},onError:(r,n)=>{var e,t;return null===(e=(t=d.current).onError)||void 0===e?void 0:e.call(t,r,n)},onCancel:()=>{var r,n;a("idle"),null===(r=(n=d.current).onCancel)||void 0===r||r.call(n)}});n(()=>{const r=o(f());v.current=r;const n=u();if("success"===(null==n?void 0:n.status))a("connected");else if("error"===(null==n?void 0:n.status)){var e,t;a("error"),i({message:null!==(e=n.message)&&void 0!==e?e:"",code:null!==(t=n.code)&&void 0!==t?t:"failed"})}return()=>{r.destroy(),v.current=null}},[]),n(()=>{var r;null===(r=v.current)||void 0===r||r.update(f())});return{open:l(()=>{v.current&&(i(null),a("connecting"),v.current.open())},[]),status:c,error:s}}export{s as ConnectButton,i as useOneConnect};
2
+ import{useRef as r,useEffect as n,createElement as e,useState as t,useCallback as l}from"react";import{renderConnectButton as c,createConnectFlow as o,readConnectReturn as u}from"@withone/connect";const a=r=>{var n,e;return JSON.stringify([r.authorizeUrl,null!==(n=null!==(e=r.logos)&&void 0!==e?e:r.platforms)&&void 0!==n?n:[],r.connected,r.disabled,r.variant,r.size,r.fullWidth,r.theme,r.connectTheme,r.connector,r.returnTo,r.label,r.connectedLabel,r.description])};function s(t){var l;const o=r(null),u=r(null),s=r(""),i=r(t);i.current=t;const d=()=>({...i.current,onSuccess:()=>{var r,n;return null===(r=(n=i.current).onSuccess)||void 0===r?void 0:r.call(n)},onError:(r,n)=>{var e,t;return null===(e=(t=i.current).onError)||void 0===e?void 0:e.call(t,r,n)},onCancel:()=>{var r,n;return null===(r=(n=i.current).onCancel)||void 0===r?void 0:r.call(n)}});n(()=>{if(o.current)return u.current=c(o.current,d()),s.current=a(i.current),()=>{var r;null===(r=u.current)||void 0===r||r.destroy(),u.current=null}},[]);const v=a(t);return n(()=>{u.current&&v!==s.current&&(s.current=v,u.current.update(d()))},[v]),e("span",{ref:o,className:t.className?`one-connect ${t.className}`:"one-connect",style:t.style,"data-variant":null!==(l=t.variant)&&void 0!==l?l:"default","data-full-width":t.fullWidth?"":void 0})}function i(e){const[c,a]=t("idle"),[s,i]=t(null),d=r(e);d.current=e;const v=r(null),f=()=>({...d.current,onSuccess:()=>{var r,n;return null===(r=(n=d.current).onSuccess)||void 0===r?void 0:r.call(n)},onError:(r,n)=>{var e,t;return null===(e=(t=d.current).onError)||void 0===e?void 0:e.call(t,r,n)},onCancel:()=>{var r,n;a("idle"),null===(r=(n=d.current).onCancel)||void 0===r||r.call(n)}});n(()=>{const r=o(f());v.current=r;const n=u();if("success"===(null==n?void 0:n.status))a("connected");else if("error"===(null==n?void 0:n.status)){var e,t;a("error"),i({message:null!==(e=n.message)&&void 0!==e?e:"",code:null!==(t=n.code)&&void 0!==t?t:"failed"})}return()=>{r.destroy(),v.current=null}},[]),n(()=>{var r;null===(r=v.current)||void 0===r||r.update(f())});return{open:l(()=>{v.current&&(i(null),a("connecting"),v.current.open())},[]),status:c,error:s}}export{s as ConnectButton,i as useOneConnect};
@@ -34,14 +34,40 @@ function txCookieName(state) {
34
34
  return `${TX_COOKIE_PREFIX}${state}`;
35
35
  }
36
36
 
37
+ /** A return path this one flow may use: a path on the app itself. A
38
+ * full URL, a protocol-relative one or anything else is dropped, so
39
+ * the callback never sends a user to another site. */
40
+ function appPath(value) {
41
+ if (!value || !value.startsWith("/")) return undefined;
42
+ if (value.startsWith("//") || value.startsWith("/\\")) return undefined;
43
+ return value;
44
+ }
45
+
46
+ /** The cookie value: the verifier, then the flow's own return path when
47
+ * it has one. A dot separates them; the verifier is base64url, which
48
+ * never contains one, so a value written before 0.17 still reads. */
49
+ function txCookieValue(verifier, returnTo) {
50
+ return returnTo ? `${verifier}.${Buffer.from(returnTo).toString("base64url")}` : verifier;
51
+ }
52
+ function parseTxCookieValue(value) {
53
+ const dot = value.indexOf(".");
54
+ if (dot < 0) return {
55
+ verifier: value
56
+ };
57
+ return {
58
+ verifier: value.slice(0, dot),
59
+ returnTo: appPath(Buffer.from(value.slice(dot + 1), "base64url").toString())
60
+ };
61
+ }
62
+
37
63
  /** The cookie scoped to the routes that need it: the directory of the
38
64
  * callback path, which is also where the authorize route lives. */
39
- function txCookie(state, verifier, redirectUri) {
65
+ function txCookie(state, verifier, redirectUri, returnTo) {
40
66
  const url = new URL(redirectUri);
41
67
  const path = url.pathname.replace(/\/[^/]*$/, "") || "/";
42
68
  return {
43
69
  name: txCookieName(state),
44
- value: verifier,
70
+ value: txCookieValue(verifier, returnTo),
45
71
  options: {
46
72
  httpOnly: true,
47
73
  secure: url.protocol === "https:",
@@ -563,8 +589,8 @@ function createOneConnect(config) {
563
589
  const apiUrl = `${oneApiUrl}/v1`;
564
590
  const returnTo = config.returnTo ?? "/";
565
591
  const scopes = config.scopes ?? DEFAULT_SCOPES;
566
- const returnUrl = (status, code) => {
567
- const url = new URL(returnTo, config.redirectUri);
592
+ const returnUrl = (status, code, flowReturnTo) => {
593
+ const url = new URL(flowReturnTo ?? returnTo, config.redirectUri);
568
594
  url.searchParams.set(RETURN_STATUS_PARAM, status);
569
595
  if (code) url.searchParams.set(RETURN_ERROR_PARAM, code);
570
596
  return url.toString();
@@ -623,7 +649,7 @@ function createOneConnect(config) {
623
649
  if (input.loginHint) url.searchParams.set("login_hint", input.loginHint);
624
650
  return {
625
651
  redirectUrl: url.toString(),
626
- cookie: txCookie(state, verifier, config.redirectUri)
652
+ cookie: txCookie(state, verifier, config.redirectUri, appPath(input.returnTo))
627
653
  };
628
654
  };
629
655
  const completeAuthorization = async input => {
@@ -632,12 +658,19 @@ function createOneConnect(config) {
632
658
  const state = params.get("state");
633
659
  const oauthError = params.get("error");
634
660
  const cookieName = state ? txCookieName(state) : undefined;
635
- const verifier = cookieName ? input.getCookie(cookieName) : undefined;
661
+ const stored = cookieName ? input.getCookie(cookieName) : undefined;
662
+ const {
663
+ verifier,
664
+ returnTo: flowReturnTo
665
+ } = stored ? parseTxCookieValue(stored) : {
666
+ verifier: undefined,
667
+ returnTo: undefined
668
+ };
636
669
  const fail = (failure, message) => ({
637
670
  outcome: failure === "declined" ? "declined" : "failed",
638
671
  code: failure,
639
672
  message,
640
- redirectUrl: returnUrl("error", failure),
673
+ redirectUrl: returnUrl("error", failure, flowReturnTo),
641
674
  clearCookieName: cookieName
642
675
  });
643
676
  if (oauthError === "access_denied") return fail("declined", "The user cancelled on One's page.");
@@ -660,7 +693,7 @@ function createOneConnect(config) {
660
693
  }
661
694
  return {
662
695
  outcome: "connected",
663
- redirectUrl: returnUrl("success"),
696
+ redirectUrl: returnUrl("success", undefined, flowReturnTo),
664
697
  clearCookieName: cookieName
665
698
  };
666
699
  };
@@ -32,14 +32,40 @@ function txCookieName(state) {
32
32
  return `${TX_COOKIE_PREFIX}${state}`;
33
33
  }
34
34
 
35
+ /** A return path this one flow may use: a path on the app itself. A
36
+ * full URL, a protocol-relative one or anything else is dropped, so
37
+ * the callback never sends a user to another site. */
38
+ function appPath(value) {
39
+ if (!value || !value.startsWith("/")) return undefined;
40
+ if (value.startsWith("//") || value.startsWith("/\\")) return undefined;
41
+ return value;
42
+ }
43
+
44
+ /** The cookie value: the verifier, then the flow's own return path when
45
+ * it has one. A dot separates them; the verifier is base64url, which
46
+ * never contains one, so a value written before 0.17 still reads. */
47
+ function txCookieValue(verifier, returnTo) {
48
+ return returnTo ? `${verifier}.${Buffer.from(returnTo).toString("base64url")}` : verifier;
49
+ }
50
+ function parseTxCookieValue(value) {
51
+ const dot = value.indexOf(".");
52
+ if (dot < 0) return {
53
+ verifier: value
54
+ };
55
+ return {
56
+ verifier: value.slice(0, dot),
57
+ returnTo: appPath(Buffer.from(value.slice(dot + 1), "base64url").toString())
58
+ };
59
+ }
60
+
35
61
  /** The cookie scoped to the routes that need it: the directory of the
36
62
  * callback path, which is also where the authorize route lives. */
37
- function txCookie(state, verifier, redirectUri) {
63
+ function txCookie(state, verifier, redirectUri, returnTo) {
38
64
  const url = new URL(redirectUri);
39
65
  const path = url.pathname.replace(/\/[^/]*$/, "") || "/";
40
66
  return {
41
67
  name: txCookieName(state),
42
- value: verifier,
68
+ value: txCookieValue(verifier, returnTo),
43
69
  options: {
44
70
  httpOnly: true,
45
71
  secure: url.protocol === "https:",
@@ -561,8 +587,8 @@ function createOneConnect(config) {
561
587
  const apiUrl = `${oneApiUrl}/v1`;
562
588
  const returnTo = config.returnTo ?? "/";
563
589
  const scopes = config.scopes ?? DEFAULT_SCOPES;
564
- const returnUrl = (status, code) => {
565
- const url = new URL(returnTo, config.redirectUri);
590
+ const returnUrl = (status, code, flowReturnTo) => {
591
+ const url = new URL(flowReturnTo ?? returnTo, config.redirectUri);
566
592
  url.searchParams.set(RETURN_STATUS_PARAM, status);
567
593
  if (code) url.searchParams.set(RETURN_ERROR_PARAM, code);
568
594
  return url.toString();
@@ -621,7 +647,7 @@ function createOneConnect(config) {
621
647
  if (input.loginHint) url.searchParams.set("login_hint", input.loginHint);
622
648
  return {
623
649
  redirectUrl: url.toString(),
624
- cookie: txCookie(state, verifier, config.redirectUri)
650
+ cookie: txCookie(state, verifier, config.redirectUri, appPath(input.returnTo))
625
651
  };
626
652
  };
627
653
  const completeAuthorization = async input => {
@@ -630,12 +656,19 @@ function createOneConnect(config) {
630
656
  const state = params.get("state");
631
657
  const oauthError = params.get("error");
632
658
  const cookieName = state ? txCookieName(state) : undefined;
633
- const verifier = cookieName ? input.getCookie(cookieName) : undefined;
659
+ const stored = cookieName ? input.getCookie(cookieName) : undefined;
660
+ const {
661
+ verifier,
662
+ returnTo: flowReturnTo
663
+ } = stored ? parseTxCookieValue(stored) : {
664
+ verifier: undefined,
665
+ returnTo: undefined
666
+ };
634
667
  const fail = (failure, message) => ({
635
668
  outcome: failure === "declined" ? "declined" : "failed",
636
669
  code: failure,
637
670
  message,
638
- redirectUrl: returnUrl("error", failure),
671
+ redirectUrl: returnUrl("error", failure, flowReturnTo),
639
672
  clearCookieName: cookieName
640
673
  });
641
674
  if (oauthError === "access_denied") return fail("declined", "The user cancelled on One's page.");
@@ -658,7 +691,7 @@ function createOneConnect(config) {
658
691
  }
659
692
  return {
660
693
  outcome: "connected",
661
- redirectUrl: returnUrl("success"),
694
+ redirectUrl: returnUrl("success", undefined, flowReturnTo),
662
695
  clearCookieName: cookieName
663
696
  };
664
697
  };
@@ -11,9 +11,21 @@ export declare function createState(): string;
11
11
  export declare function createPkceVerifier(): string;
12
12
  export declare function pkceChallenge(verifier: string): string;
13
13
  export declare function txCookieName(state: string): string;
14
+ /** A return path this one flow may use: a path on the app itself. A
15
+ * full URL, a protocol-relative one or anything else is dropped, so
16
+ * the callback never sends a user to another site. */
17
+ export declare function appPath(value: string | undefined): string | undefined;
18
+ /** The cookie value: the verifier, then the flow's own return path when
19
+ * it has one. A dot separates them; the verifier is base64url, which
20
+ * never contains one, so a value written before 0.17 still reads. */
21
+ export declare function txCookieValue(verifier: string, returnTo?: string): string;
22
+ export declare function parseTxCookieValue(value: string): {
23
+ verifier: string;
24
+ returnTo?: string;
25
+ };
14
26
  /** The cookie scoped to the routes that need it: the directory of the
15
27
  * callback path, which is also where the authorize route lives. */
16
- export declare function txCookie(state: string, verifier: string, redirectUri: string): OneConnectCookie;
28
+ export declare function txCookie(state: string, verifier: string, redirectUri: string, returnTo?: string): OneConnectCookie;
17
29
  export declare function basicAuthorization(clientId: string, clientSecret: string): string;
18
30
  /** The tenant headers a grant needs on every call. A grant made into an
19
31
  * organization or project lives there; One resolves the tenant from
@@ -149,6 +149,10 @@ export interface OneConnectCookie {
149
149
  export interface StartAuthorizationInput {
150
150
  /** Pre-fills the sign-in email on One's page. Never locks it. */
151
151
  loginHint?: string;
152
+ /** Where this one flow returns to: a path on your app ("/chat/42").
153
+ * Kept in the flow's cookie, never sent to One. Anything that is not
154
+ * a plain path is ignored and the configured `returnTo` applies. */
155
+ returnTo?: string;
152
156
  }
153
157
  export interface StartAuthorizationResult {
154
158
  /** Send the browser here with a 302. */
package/dist/types.d.ts CHANGED
@@ -27,6 +27,14 @@ export interface OneConnectFlowOptions {
27
27
  /** Theme for One's hosted page. Carried on the URL fragment, which
28
28
  * survives the redirect chain, so the backend forwards nothing. */
29
29
  connectTheme?: OneConnectTheme;
30
+ /** A connector slug ("gmail"). One's page opens that connector's
31
+ * connect screen first, then shows the full list as usual. Carried
32
+ * on the URL fragment like the theme. */
33
+ connector?: string;
34
+ /** Where the user lands afterwards, for this flow only: a path on
35
+ * your app such as "/chat/42". Your authorize route reads it and
36
+ * the callback uses it instead of the server's `returnTo`. */
37
+ returnTo?: string;
30
38
  /** The grant completed and the backend stored the tokens. Fires once
31
39
  * per page load, on the first flow still mounted when the tab
32
40
  * returns. Treat it as a hint to refetch: your server is the truth. */
@@ -69,9 +77,9 @@ export interface ConnectButtonLogo {
69
77
  name: string;
70
78
  imageUrl: string;
71
79
  }
72
- /** @deprecated Renamed to `ConnectButtonLogoInput`; removed in 0.17.0. */
80
+ /** @deprecated Renamed to `ConnectButtonLogoInput`; removed in 0.18.0. */
73
81
  export type ConnectButtonPlatformInput = ConnectButtonLogoInput;
74
- /** @deprecated Renamed to `ConnectButtonLogo`; removed in 0.17.0. */
82
+ /** @deprecated Renamed to `ConnectButtonLogo`; removed in 0.18.0. */
75
83
  export type ConnectButtonPlatform = ConnectButtonLogo;
76
84
  export type ConnectButtonVariant = "default" | "accent" | "block";
77
85
  export type ConnectButtonSize = "sm" | "md" | "lg";
@@ -86,7 +94,7 @@ export interface ConnectButtonProps {
86
94
  * into a "+N" chip. Decoration only; the permission set decides what
87
95
  * One asks for. */
88
96
  logos?: ConnectButtonLogoInput[];
89
- /** @deprecated Renamed to `logos`; removed in 0.17.0. */
97
+ /** @deprecated Renamed to `logos`; removed in 0.18.0. */
90
98
  platforms?: ConnectButtonLogoInput[];
91
99
  /** Whether this user has a live grant, from your server. When set, it
92
100
  * decides the Connected state. When omitted, the button shows
@@ -105,6 +113,10 @@ export interface ConnectButtonProps {
105
113
  theme?: ConnectButtonTheme;
106
114
  /** Theme of One's hosted page. */
107
115
  connectTheme?: OneConnectTheme;
116
+ /** A connector slug ("gmail") to open first on One's page. */
117
+ connector?: string;
118
+ /** Where this flow returns to: a path on your app. */
119
+ returnTo?: string;
108
120
  /** "Connect your apps" unless set. */
109
121
  label?: string;
110
122
  /** "Connected" unless set. */
package/dist/vue.cjs.js CHANGED
@@ -1 +1 @@
1
- "use strict";var e=require("vue"),t=require("@withone/connect");const n={type:Boolean,default:void 0},o=e.defineComponent({name:"OneConnectButton",props:{authorizeUrl:{type:String,required:!0},logos:{type:Array,default:void 0},platforms:{type:Array,default:void 0},connected:n,disabled:n,variant:{type:String,default:void 0},size:{type:String,default:void 0},fullWidth:n,theme:{type:String,default:void 0},connectTheme:{type:String,default:void 0},label:{type:String,default:void 0},connectedLabel:{type:String,default:void 0},description:{type:String,default:void 0}},emits:{success:()=>!0,error:(e,t)=>"string"==typeof e&&"string"==typeof t,cancel:()=>!0},setup(n,{emit:o}){const r=e.ref(null);let i=null;const l=()=>({...n,onSuccess:()=>o("success"),onError:(e,t)=>o("error",e,t),onCancel:()=>o("cancel")});return e.onMounted(()=>{r.value&&(i=t.renderConnectButton(r.value,l()))}),e.watch(()=>({...n}),()=>{var e;return null===(e=i)||void 0===e?void 0:e.update(l())},{deep:!0}),e.onBeforeUnmount(()=>{var e;null===(e=i)||void 0===e||e.destroy(),i=null}),()=>{var t;return e.h("span",{ref:r,class:"one-connect","data-variant":null!==(t=n.variant)&&void 0!==t?t:"default","data-full-width":n.fullWidth?"":void 0})}}});exports.ConnectButton=o;
1
+ "use strict";var e=require("vue"),t=require("@withone/connect");const n={type:Boolean,default:void 0},o=e.defineComponent({name:"OneConnectButton",props:{authorizeUrl:{type:String,required:!0},logos:{type:Array,default:void 0},platforms:{type:Array,default:void 0},connected:n,disabled:n,variant:{type:String,default:void 0},size:{type:String,default:void 0},fullWidth:n,theme:{type:String,default:void 0},connectTheme:{type:String,default:void 0},connector:{type:String,default:void 0},returnTo:{type:String,default:void 0},label:{type:String,default:void 0},connectedLabel:{type:String,default:void 0},description:{type:String,default:void 0}},emits:{success:()=>!0,error:(e,t)=>"string"==typeof e&&"string"==typeof t,cancel:()=>!0},setup(n,{emit:o}){const r=e.ref(null);let i=null;const d=()=>({...n,onSuccess:()=>o("success"),onError:(e,t)=>o("error",e,t),onCancel:()=>o("cancel")});return e.onMounted(()=>{r.value&&(i=t.renderConnectButton(r.value,d()))}),e.watch(()=>({...n}),()=>{var e;return null===(e=i)||void 0===e?void 0:e.update(d())},{deep:!0}),e.onBeforeUnmount(()=>{var e;null===(e=i)||void 0===e||e.destroy(),i=null}),()=>{var t;return e.h("span",{ref:r,class:"one-connect","data-variant":null!==(t=n.variant)&&void 0!==t?t:"default","data-full-width":n.fullWidth?"":void 0})}}});exports.ConnectButton=o;
package/dist/vue.d.ts CHANGED
@@ -42,6 +42,14 @@ export declare const ConnectButton: import("vue").DefineComponent<import("vue").
42
42
  type: PropType<OneConnectTheme>;
43
43
  default: undefined;
44
44
  };
45
+ connector: {
46
+ type: StringConstructor;
47
+ default: undefined;
48
+ };
49
+ returnTo: {
50
+ type: StringConstructor;
51
+ default: undefined;
52
+ };
45
53
  label: {
46
54
  type: StringConstructor;
47
55
  default: undefined;
@@ -102,6 +110,14 @@ export declare const ConnectButton: import("vue").DefineComponent<import("vue").
102
110
  type: PropType<OneConnectTheme>;
103
111
  default: undefined;
104
112
  };
113
+ connector: {
114
+ type: StringConstructor;
115
+ default: undefined;
116
+ };
117
+ returnTo: {
118
+ type: StringConstructor;
119
+ default: undefined;
120
+ };
105
121
  label: {
106
122
  type: StringConstructor;
107
123
  default: undefined;
@@ -123,6 +139,8 @@ export declare const ConnectButton: import("vue").DefineComponent<import("vue").
123
139
  label: string;
124
140
  disabled: boolean;
125
141
  connectTheme: OneConnectTheme;
142
+ connector: string;
143
+ returnTo: string;
126
144
  logos: ConnectButtonLogoInput[];
127
145
  platforms: ConnectButtonLogoInput[];
128
146
  variant: ConnectButtonVariant;
package/dist/vue.esm.js CHANGED
@@ -1 +1 @@
1
- import{defineComponent as e,ref as t,onMounted as n,watch as o,onBeforeUnmount as r,h as l}from"vue";import{renderConnectButton as i}from"@withone/connect";const a={type:Boolean,default:void 0},d=e({name:"OneConnectButton",props:{authorizeUrl:{type:String,required:!0},logos:{type:Array,default:void 0},platforms:{type:Array,default:void 0},connected:a,disabled:a,variant:{type:String,default:void 0},size:{type:String,default:void 0},fullWidth:a,theme:{type:String,default:void 0},connectTheme:{type:String,default:void 0},label:{type:String,default:void 0},connectedLabel:{type:String,default:void 0},description:{type:String,default:void 0}},emits:{success:()=>!0,error:(e,t)=>"string"==typeof e&&"string"==typeof t,cancel:()=>!0},setup(e,{emit:a}){const d=t(null);let u=null;const c=()=>({...e,onSuccess:()=>a("success"),onError:(e,t)=>a("error",e,t),onCancel:()=>a("cancel")});return n(()=>{d.value&&(u=i(d.value,c()))}),o(()=>({...e}),()=>{var e;return null===(e=u)||void 0===e?void 0:e.update(c())},{deep:!0}),r(()=>{var e;null===(e=u)||void 0===e||e.destroy(),u=null}),()=>{var t;return l("span",{ref:d,class:"one-connect","data-variant":null!==(t=e.variant)&&void 0!==t?t:"default","data-full-width":e.fullWidth?"":void 0})}}});export{d as ConnectButton};
1
+ import{defineComponent as e,ref as t,onMounted as n,watch as o,onBeforeUnmount as r,h as i}from"vue";import{renderConnectButton as l}from"@withone/connect";const d={type:Boolean,default:void 0},a=e({name:"OneConnectButton",props:{authorizeUrl:{type:String,required:!0},logos:{type:Array,default:void 0},platforms:{type:Array,default:void 0},connected:d,disabled:d,variant:{type:String,default:void 0},size:{type:String,default:void 0},fullWidth:d,theme:{type:String,default:void 0},connectTheme:{type:String,default:void 0},connector:{type:String,default:void 0},returnTo:{type:String,default:void 0},label:{type:String,default:void 0},connectedLabel:{type:String,default:void 0},description:{type:String,default:void 0}},emits:{success:()=>!0,error:(e,t)=>"string"==typeof e&&"string"==typeof t,cancel:()=>!0},setup(e,{emit:d}){const a=t(null);let u=null;const c=()=>({...e,onSuccess:()=>d("success"),onError:(e,t)=>d("error",e,t),onCancel:()=>d("cancel")});return n(()=>{a.value&&(u=l(a.value,c()))}),o(()=>({...e}),()=>{var e;return null===(e=u)||void 0===e?void 0:e.update(c())},{deep:!0}),r(()=>{var e;null===(e=u)||void 0===e||e.destroy(),u=null}),()=>{var t;return i("span",{ref:a,class:"one-connect","data-variant":null!==(t=e.variant)&&void 0!==t?t:"default","data-full-width":e.fullWidth?"":void 0})}}});export{a as ConnectButton};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@withone/connect",
3
- "version": "0.16.0",
3
+ "version": "0.17.0",
4
4
  "description": "One Connect for your app: the button your users press, the two backend routes as one import, and a server client that calls One with the grant. Users keep their connections in One; your app holds only what they granted.",
5
5
  "files": [
6
6
  "dist",
@@ -115,6 +115,14 @@ export const { GET } = createOneConnectRoutes(oneConnect, {
115
115
  });
116
116
  ```
117
117
 
118
+ `identifyUser` returns the id of the app's own signed-in user, from the
119
+ app's existing session. It is not the email: One's page signs the person
120
+ in to One with their email and a code; this id is which of the app's
121
+ accounts the grant is saved under, and the `userId` every later call
122
+ takes. `loginHintFor` only pre-fills that email. If the app has no
123
+ sign-in, ask the human what to use; for a throwaway demo, one fixed id
124
+ is fine.
125
+
118
126
  Express, Fastify, Koa or plain Node: `createOneConnectHandlers(oneConnect,
119
127
  options)` from `@withone/connect/node` takes the same options and returns
120
128
  `{ authorize, callback }`, mounted at `/api/one/authorize` and
@@ -141,8 +149,10 @@ import { ConnectButton } from "@withone/connect/react";
141
149
 
142
150
  Optional props: `variant` ("default" | "accent" | "block"), `size` ("sm" |
143
151
  "md" | "lg"), `fullWidth`, `theme` ("light" | "dark" | "auto"),
144
- `connectTheme` ("light" | "dark", One's page), `label`, `connectedLabel`,
145
- `description`, `disabled`, `onCancel`. The accent variant's colours come
152
+ `connectTheme` ("light" | "dark", One's page), `connector` (a slug such as
153
+ "gmail": One's page opens that connector's connect screen first, then the
154
+ usual list), `returnTo` (a path on the app this flow returns to), `label`,
155
+ `connectedLabel`, `description`, `disabled`, `onCancel`. The accent variant's colours come
146
156
  from the host's `--one-connect-accent` and `--one-connect-accent-fg` CSS
147
157
  variables.
148
158
 
@@ -169,8 +179,15 @@ keep it and wire the flow to it instead of adding a second style:
169
179
  button.addEventListener("click", () => flow.open());
170
180
  ```
171
181
 
182
+ - One connector at a time (a chat that says "Connect Gmail", a settings
183
+ row): `useOneConnect({ authorizeUrl, connector: "gmail", returnTo: "/chat/42" })`.
184
+ One's page still signs the user in and asks for the space, then opens
185
+ Gmail's connect screen instead of the list; the list follows with
186
+ everything connected. `returnTo` must be a path on the app.
187
+
172
188
  - No SDK in the browser (server-rendered pages): a plain link,
173
- `<a href="/api/one/authorize">`. The user returns with
189
+ `<a href="/api/one/authorize">` (add `#one_connector=gmail` and
190
+ `?one_return_to=%2Fchat%2F42` for the above). The user returns with
174
191
  `?one_connect=success`, or `?one_connect=error&one_connect_error=` with
175
192
  `declined`, `expired` or `failed`. Show the app's own text per code, never
176
193
  text from the URL, and remove the parameters after reading them.
@@ -254,7 +271,10 @@ Rules:
254
271
  - Connect keys work in Production only; the human creates the key with
255
272
  the dashboard on Production.
256
273
  - Store the per-user string as given.
257
- - The registered redirect URI and `ONE_REDIRECT_URI` must be identical.
274
+ - The registered redirect URI and `ONE_REDIRECT_URI` must be identical;
275
+ otherwise One answers `invalid redirect_uri` and never shows its page.
276
+ - A flow that ends with `failed` is usually a wrong or rotated client
277
+ secret; log `result.message` from `onComplete` to see why.
258
278
  - Do not write OAuth steps or One request headers by hand; use the package.
259
279
  - Never show `result.message` or any URL text to users; log it.
260
280
 
package/src/button.ts CHANGED
@@ -182,6 +182,8 @@ const flowOptions = (
182
182
  ): OneConnectFlowOptions => ({
183
183
  authorizeUrl: props.authorizeUrl,
184
184
  connectTheme: props.connectTheme,
185
+ connector: props.connector,
186
+ returnTo: props.returnTo,
185
187
  ...handlers,
186
188
  });
187
189
 
@@ -382,6 +384,8 @@ const ATTRIBUTES = [
382
384
  "full-width",
383
385
  "theme",
384
386
  "connect-theme",
387
+ "connector",
388
+ "return-to",
385
389
  "label",
386
390
  "connected-label",
387
391
  "description",
@@ -454,6 +458,8 @@ export function registerConnectButton(): void {
454
458
  fullWidth: flag(this, "full-width"),
455
459
  theme: attributeAs(this, "theme", ["light", "dark", "auto"]),
456
460
  connectTheme: attributeAs(this, "connect-theme", ["light", "dark"]),
461
+ connector: this.getAttribute("connector") ?? undefined,
462
+ returnTo: this.getAttribute("return-to") ?? undefined,
457
463
  label: this.getAttribute("label") ?? undefined,
458
464
  connectedLabel: this.getAttribute("connected-label") ?? undefined,
459
465
  description: this.getAttribute("description") ?? undefined,
package/src/constants.ts CHANGED
@@ -13,6 +13,16 @@ export const LEGACY_MESSAGE_PARAM = "one_connect_message";
13
13
  * chain, so the app's backend forwards nothing. */
14
14
  export const THEME_PARAM = "one_theme";
15
15
 
16
+ /** Fragment key naming the connector One's page opens first. Sign-in
17
+ * and the space step run as always; then that connector's connect
18
+ * screen opens instead of the list, and the list follows with
19
+ * everything the user has connected. */
20
+ export const CONNECTOR_PARAM = "one_connector";
21
+
22
+ /** Query param on the app's own authorize route naming where this one
23
+ * flow returns to. The route reads it; it never reaches One. */
24
+ export const RETURN_TO_PARAM = "one_return_to";
25
+
16
26
  /** One's connector logos, by slug. */
17
27
  export const CONNECTOR_ASSETS_URL = "https://assets.withone.ai/connectors";
18
28
 
package/src/flow.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { THEME_PARAM } from "./constants";
1
+ import { CONNECTOR_PARAM, RETURN_TO_PARAM, THEME_PARAM } from "./constants";
2
2
  import { hasReturnParams, parseReturn, stripReturnParams } from "./return";
3
3
  import type {
4
4
  OneConnectFlow,
@@ -91,11 +91,19 @@ function bindPageshow(): void {
91
91
  });
92
92
  }
93
93
 
94
+ /** The theme and the connector ride the fragment: no server sees it,
95
+ * and it survives every redirect to One's page. The return path is a
96
+ * query param for the app's own route, which reads it and keeps it. */
94
97
  const authorizeUrlFor = (options: OneConnectFlowOptions): string => {
95
- const theme = options.connectTheme;
96
98
  try {
97
99
  const url = new URL(options.authorizeUrl, window.location.origin);
98
- if (theme) url.hash = `${THEME_PARAM}=${theme}`;
100
+ if (options.returnTo) url.searchParams.set(RETURN_TO_PARAM, options.returnTo);
101
+ const fragment = new URLSearchParams();
102
+ if (options.connectTheme) fragment.set(THEME_PARAM, options.connectTheme);
103
+ const connector = options.connector?.trim().toLowerCase();
104
+ if (connector) fragment.set(CONNECTOR_PARAM, connector);
105
+ const hash = fragment.toString();
106
+ if (hash) url.hash = hash;
99
107
  return url.toString();
100
108
  } catch {
101
109
  return options.authorizeUrl;
package/src/next.ts CHANGED
@@ -14,6 +14,7 @@
14
14
  * That serves /api/one/authorize and /api/one/callback. Register
15
15
  * `https://yourapp.com/api/one/callback` as the app's redirect URI.
16
16
  */
17
+ import { RETURN_TO_PARAM } from "./constants";
17
18
  import type { CompleteAuthorizationResult, OneConnectClient } from "./server";
18
19
 
19
20
  export interface OneConnectRoutesOptions {
@@ -109,7 +110,11 @@ export function createOneConnectRoutes(
109
110
  const user = await requireUser(request);
110
111
  if (user instanceof Response) return user;
111
112
  const loginHint = (await options.loginHintFor?.(request)) ?? undefined;
112
- const { redirectUrl, cookie } = oneConnect.startAuthorization({ loginHint });
113
+ // The browser flow names where this one flow returns to; the client
114
+ // keeps only a path on the app, so a crafted link goes nowhere else.
115
+ const returnTo =
116
+ new URL(request.url).searchParams.get(RETURN_TO_PARAM) ?? undefined;
117
+ const { redirectUrl, cookie } = oneConnect.startAuthorization({ loginHint, returnTo });
113
118
  return redirectWithCookies(redirectUrl, [
114
119
  serializeCookie(cookie.name, cookie.value, cookie.options),
115
120
  ]);
package/src/react.ts CHANGED
@@ -38,6 +38,8 @@ const visualKey = (props: ConnectButtonCoreProps): string =>
38
38
  props.fullWidth,
39
39
  props.theme,
40
40
  props.connectTheme,
41
+ props.connector,
42
+ props.returnTo,
41
43
  props.label,
42
44
  props.connectedLabel,
43
45
  props.description,
@@ -38,6 +38,8 @@ import {
38
38
  createPkceVerifier,
39
39
  createState,
40
40
  pkceChallenge,
41
+ appPath,
42
+ parseTxCookieValue,
41
43
  txCookie,
42
44
  txCookieName,
43
45
  } from "./oauth";
@@ -246,8 +248,12 @@ export function createOneConnect(
246
248
  const returnTo = config.returnTo ?? "/";
247
249
  const scopes = config.scopes ?? DEFAULT_SCOPES;
248
250
 
249
- const returnUrl = (status: "success" | "error", code?: ConnectFailureCode): string => {
250
- const url = new URL(returnTo, config.redirectUri);
251
+ const returnUrl = (
252
+ status: "success" | "error",
253
+ code?: ConnectFailureCode,
254
+ flowReturnTo?: string,
255
+ ): string => {
256
+ const url = new URL(flowReturnTo ?? returnTo, config.redirectUri);
251
257
  url.searchParams.set(RETURN_STATUS_PARAM, status);
252
258
  if (code) url.searchParams.set(RETURN_ERROR_PARAM, code);
253
259
  return url.toString();
@@ -319,7 +325,7 @@ export function createOneConnect(
319
325
  if (input.loginHint) url.searchParams.set("login_hint", input.loginHint);
320
326
  return {
321
327
  redirectUrl: url.toString(),
322
- cookie: txCookie(state, verifier, config.redirectUri),
328
+ cookie: txCookie(state, verifier, config.redirectUri, appPath(input.returnTo)),
323
329
  };
324
330
  };
325
331
 
@@ -331,7 +337,10 @@ export function createOneConnect(
331
337
  const state = params.get("state");
332
338
  const oauthError = params.get("error");
333
339
  const cookieName = state ? txCookieName(state) : undefined;
334
- const verifier = cookieName ? input.getCookie(cookieName) : undefined;
340
+ const stored = cookieName ? input.getCookie(cookieName) : undefined;
341
+ const { verifier, returnTo: flowReturnTo } = stored
342
+ ? parseTxCookieValue(stored)
343
+ : { verifier: undefined, returnTo: undefined };
335
344
 
336
345
  const fail = (
337
346
  failure: ConnectFailureCode,
@@ -340,7 +349,7 @@ export function createOneConnect(
340
349
  outcome: failure === "declined" ? "declined" : "failed",
341
350
  code: failure,
342
351
  message,
343
- redirectUrl: returnUrl("error", failure),
352
+ redirectUrl: returnUrl("error", failure, flowReturnTo),
344
353
  clearCookieName: cookieName,
345
354
  });
346
355
 
@@ -378,7 +387,7 @@ export function createOneConnect(
378
387
 
379
388
  return {
380
389
  outcome: "connected",
381
- redirectUrl: returnUrl("success"),
390
+ redirectUrl: returnUrl("success", undefined, flowReturnTo),
382
391
  clearCookieName: cookieName,
383
392
  };
384
393
  };
@@ -36,18 +36,49 @@ export function txCookieName(state: string): string {
36
36
  return `${TX_COOKIE_PREFIX}${state}`;
37
37
  }
38
38
 
39
+ /** A return path this one flow may use: a path on the app itself. A
40
+ * full URL, a protocol-relative one or anything else is dropped, so
41
+ * the callback never sends a user to another site. */
42
+ export function appPath(value: string | undefined): string | undefined {
43
+ if (!value || !value.startsWith("/")) return undefined;
44
+ if (value.startsWith("//") || value.startsWith("/\\")) return undefined;
45
+ return value;
46
+ }
47
+
48
+ /** The cookie value: the verifier, then the flow's own return path when
49
+ * it has one. A dot separates them; the verifier is base64url, which
50
+ * never contains one, so a value written before 0.17 still reads. */
51
+ export function txCookieValue(verifier: string, returnTo?: string): string {
52
+ return returnTo
53
+ ? `${verifier}.${Buffer.from(returnTo).toString("base64url")}`
54
+ : verifier;
55
+ }
56
+
57
+ export function parseTxCookieValue(value: string): {
58
+ verifier: string;
59
+ returnTo?: string;
60
+ } {
61
+ const dot = value.indexOf(".");
62
+ if (dot < 0) return { verifier: value };
63
+ return {
64
+ verifier: value.slice(0, dot),
65
+ returnTo: appPath(Buffer.from(value.slice(dot + 1), "base64url").toString()),
66
+ };
67
+ }
68
+
39
69
  /** The cookie scoped to the routes that need it: the directory of the
40
70
  * callback path, which is also where the authorize route lives. */
41
71
  export function txCookie(
42
72
  state: string,
43
73
  verifier: string,
44
74
  redirectUri: string,
75
+ returnTo?: string,
45
76
  ): OneConnectCookie {
46
77
  const url = new URL(redirectUri);
47
78
  const path = url.pathname.replace(/\/[^/]*$/, "") || "/";
48
79
  return {
49
80
  name: txCookieName(state),
50
- value: verifier,
81
+ value: txCookieValue(verifier, returnTo),
51
82
  options: {
52
83
  httpOnly: true,
53
84
  secure: url.protocol === "https:",
@@ -161,6 +161,10 @@ export interface OneConnectCookie {
161
161
  export interface StartAuthorizationInput {
162
162
  /** Pre-fills the sign-in email on One's page. Never locks it. */
163
163
  loginHint?: string;
164
+ /** Where this one flow returns to: a path on your app ("/chat/42").
165
+ * Kept in the flow's cookie, never sent to One. Anything that is not
166
+ * a plain path is ignored and the configured `returnTo` applies. */
167
+ returnTo?: string;
164
168
  }
165
169
 
166
170
  export interface StartAuthorizationResult {
package/src/types.ts CHANGED
@@ -31,6 +31,14 @@ export interface OneConnectFlowOptions {
31
31
  /** Theme for One's hosted page. Carried on the URL fragment, which
32
32
  * survives the redirect chain, so the backend forwards nothing. */
33
33
  connectTheme?: OneConnectTheme;
34
+ /** A connector slug ("gmail"). One's page opens that connector's
35
+ * connect screen first, then shows the full list as usual. Carried
36
+ * on the URL fragment like the theme. */
37
+ connector?: string;
38
+ /** Where the user lands afterwards, for this flow only: a path on
39
+ * your app such as "/chat/42". Your authorize route reads it and
40
+ * the callback uses it instead of the server's `returnTo`. */
41
+ returnTo?: string;
34
42
  /** The grant completed and the backend stored the tokens. Fires once
35
43
  * per page load, on the first flow still mounted when the tab
36
44
  * returns. Treat it as a hint to refetch: your server is the truth. */
@@ -75,9 +83,9 @@ export interface ConnectButtonLogo {
75
83
  imageUrl: string;
76
84
  }
77
85
 
78
- /** @deprecated Renamed to `ConnectButtonLogoInput`; removed in 0.17.0. */
86
+ /** @deprecated Renamed to `ConnectButtonLogoInput`; removed in 0.18.0. */
79
87
  export type ConnectButtonPlatformInput = ConnectButtonLogoInput;
80
- /** @deprecated Renamed to `ConnectButtonLogo`; removed in 0.17.0. */
88
+ /** @deprecated Renamed to `ConnectButtonLogo`; removed in 0.18.0. */
81
89
  export type ConnectButtonPlatform = ConnectButtonLogo;
82
90
 
83
91
  export type ConnectButtonVariant = "default" | "accent" | "block";
@@ -94,7 +102,7 @@ export interface ConnectButtonProps {
94
102
  * into a "+N" chip. Decoration only; the permission set decides what
95
103
  * One asks for. */
96
104
  logos?: ConnectButtonLogoInput[];
97
- /** @deprecated Renamed to `logos`; removed in 0.17.0. */
105
+ /** @deprecated Renamed to `logos`; removed in 0.18.0. */
98
106
  platforms?: ConnectButtonLogoInput[];
99
107
  /** Whether this user has a live grant, from your server. When set, it
100
108
  * decides the Connected state. When omitted, the button shows
@@ -113,6 +121,10 @@ export interface ConnectButtonProps {
113
121
  theme?: ConnectButtonTheme;
114
122
  /** Theme of One's hosted page. */
115
123
  connectTheme?: OneConnectTheme;
124
+ /** A connector slug ("gmail") to open first on One's page. */
125
+ connector?: string;
126
+ /** Where this flow returns to: a path on your app. */
127
+ returnTo?: string;
116
128
  /** "Connect your apps" unless set. */
117
129
  label?: string;
118
130
  /** "Connected" unless set. */
package/src/vue.ts CHANGED
@@ -62,6 +62,8 @@ export const ConnectButton = defineComponent({
62
62
  type: String as PropType<OneConnectTheme>,
63
63
  default: undefined,
64
64
  },
65
+ connector: { type: String, default: undefined },
66
+ returnTo: { type: String, default: undefined },
65
67
  label: { type: String, default: undefined },
66
68
  connectedLabel: { type: String, default: undefined },
67
69
  description: { type: String, default: undefined },