reflet-sdk 0.7.3 → 0.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/README.md +22 -16
- package/dist/{devtools-layer-CsIcpepI.js → devtools-layer-CcTmlikp.js} +396 -277
- package/dist/devtools-layer-CcTmlikp.js.map +1 -0
- package/dist/devtools-next.js +1 -1
- package/dist/{sessions-panel-BYM0UUgT.js → devtools-styles-teRMfSzW.js} +1836 -1465
- package/dist/devtools-styles-teRMfSzW.js.map +1 -0
- package/dist/devtools-vite.js +1 -1
- package/dist/feedback.js +4 -4
- package/dist/{handler-17FmwoSX.js → handler-B3_PQB1q.js} +2 -2
- package/dist/handler-B3_PQB1q.js.map +1 -0
- package/dist/{submit-Dl0rm6TV.js → submit-CG4LXioK.js} +2 -2
- package/dist/{submit-Dl0rm6TV.js.map → submit-CG4LXioK.js.map} +1 -1
- package/dist/{team-layer-Dvjkh-_y.js → team-layer-zLj_QPQX.js} +36 -42
- package/dist/team-layer-zLj_QPQX.js.map +1 -0
- package/package.json +1 -1
- package/dist/devtools-layer-CsIcpepI.js.map +0 -1
- package/dist/handler-17FmwoSX.js.map +0 -1
- package/dist/sessions-panel-BYM0UUgT.js.map +0 -1
- package/dist/team-layer-Dvjkh-_y.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { r as teamAccessStorageKey, t as TEAM_ACTIVATION_PARAM } from "./team-activation-Cv5U7OF1.js";
|
|
2
|
-
import {
|
|
2
|
+
import { I as sessionApiErrorSchema, L as Notices, S as purgeAccount, _ as RecordingLayer, b as failureMessage, d as sessionSheetPlace, f as useSessionNavigation, l as SESSIONS_STYLES, n as DevtoolsSheet, o as SessionsBarButton, r as DevtoolsBar, s as AccountFooter, t as DEVTOOLS_STYLES, u as SessionsPanel, w as teamTransport, x as useWorkspaceLoader, y as SessionWorkspaceProvider, z as reportFailure } from "./devtools-styles-teRMfSzW.js";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { useEffect, useState } from "react";
|
|
5
|
-
import {
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
//#region src/sessions/team/team-auth.ts
|
|
7
7
|
const RETURN_CODE_PARAM = "reflet-team-code";
|
|
8
8
|
const RETURN_ERROR_PARAM = "reflet-team-error";
|
|
@@ -266,22 +266,6 @@ function TeamSignInCard({ connection, isFinishing, notice }) {
|
|
|
266
266
|
//#region src/sessions/team/team-layer.tsx
|
|
267
267
|
const TEAM_TOOLS_LABEL = "Reflet team tools";
|
|
268
268
|
const REFUSED_SIGN_IN_COPY = "Reflet no longer accepts this sign-in. Sign in again to record.";
|
|
269
|
-
function AccountControls({ access, onSignOut, workspace }) {
|
|
270
|
-
const [isOpen, setIsOpen] = useState(false);
|
|
271
|
-
const user = workspace?.account.userName ?? workspace?.account.userEmail;
|
|
272
|
-
const label = user ? `Signed in as ${user} · ${access.organizationName}` : `Signed in · ${access.organizationName}`;
|
|
273
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(BarButton, {
|
|
274
|
-
label,
|
|
275
|
-
onClick: () => setIsOpen(!isOpen),
|
|
276
|
-
pressed: isOpen,
|
|
277
|
-
children: /* @__PURE__ */ jsx(PersonIcon, {})
|
|
278
|
-
}), isOpen && /* @__PURE__ */ jsx("button", {
|
|
279
|
-
className: "dt-btn",
|
|
280
|
-
onClick: onSignOut,
|
|
281
|
-
type: "button",
|
|
282
|
-
children: "Sign out"
|
|
283
|
-
})] });
|
|
284
|
-
}
|
|
285
269
|
function SessionsBody({ navigation, onStarted, state }) {
|
|
286
270
|
if (state.kind === "ready") return /* @__PURE__ */ jsx(SessionsPanel, {
|
|
287
271
|
navigation,
|
|
@@ -302,17 +286,30 @@ function SessionsBody({ navigation, onStarted, state }) {
|
|
|
302
286
|
children: "Opening your sessions…"
|
|
303
287
|
});
|
|
304
288
|
}
|
|
305
|
-
function TeamSheet({ navigation,
|
|
289
|
+
function TeamSheet({ account, navigation, onClose, side }) {
|
|
290
|
+
const { state } = account;
|
|
291
|
+
const place = state.kind === "ready" ? sessionSheetPlace(navigation) : null;
|
|
306
292
|
return /* @__PURE__ */ jsx(DevtoolsSheet, {
|
|
293
|
+
footer: place === null && /* @__PURE__ */ jsx(AccountFooter, {
|
|
294
|
+
actions: [{
|
|
295
|
+
label: "Sign out",
|
|
296
|
+
onSelect: account.onSignOut
|
|
297
|
+
}],
|
|
298
|
+
organizationName: account.access.organizationName,
|
|
299
|
+
person: state.kind === "ready" ? state.workspace.identity.user : null
|
|
300
|
+
}),
|
|
307
301
|
label: TEAM_TOOLS_LABEL,
|
|
308
|
-
|
|
309
|
-
|
|
302
|
+
navigation: {
|
|
303
|
+
onSelectTab: () => void 0,
|
|
304
|
+
place,
|
|
305
|
+
tab: "sessions",
|
|
306
|
+
tabs: ["sessions"]
|
|
307
|
+
},
|
|
308
|
+
onClose,
|
|
310
309
|
side,
|
|
311
|
-
tab: "sessions",
|
|
312
|
-
tabs: ["sessions"],
|
|
313
310
|
children: /* @__PURE__ */ jsx(SessionsBody, {
|
|
314
311
|
navigation,
|
|
315
|
-
onStarted:
|
|
312
|
+
onStarted: onClose,
|
|
316
313
|
state
|
|
317
314
|
})
|
|
318
315
|
});
|
|
@@ -355,34 +352,31 @@ function useTeamWorkspace(team) {
|
|
|
355
352
|
function TeamTools({ team, placement }) {
|
|
356
353
|
const { signOut, state, workspace } = useTeamWorkspace(team);
|
|
357
354
|
const [isSheetOpen, setIsSheetOpen] = useState(false);
|
|
358
|
-
const
|
|
355
|
+
const navigation = useSessionNavigation();
|
|
359
356
|
return /* @__PURE__ */ jsxs(SessionWorkspaceProvider, {
|
|
360
357
|
workspace,
|
|
361
358
|
children: [
|
|
362
359
|
isSheetOpen && /* @__PURE__ */ jsx(TeamSheet, {
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
360
|
+
account: {
|
|
361
|
+
access: team.access,
|
|
362
|
+
onSignOut: signOut,
|
|
363
|
+
state
|
|
366
364
|
},
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
365
|
+
navigation,
|
|
366
|
+
onClose: () => setIsSheetOpen(false),
|
|
367
|
+
side: placement.side
|
|
370
368
|
}),
|
|
371
|
-
/* @__PURE__ */
|
|
369
|
+
/* @__PURE__ */ jsx(DevtoolsBar, {
|
|
372
370
|
edge: placement.edge,
|
|
373
371
|
label: TEAM_TOOLS_LABEL,
|
|
374
372
|
side: placement.side,
|
|
375
|
-
children:
|
|
376
|
-
isOpen: isSheetOpen,
|
|
377
|
-
onToggle: () => setIsSheetOpen(!isSheetOpen)
|
|
378
|
-
}), /* @__PURE__ */ jsx(AccountControls, {
|
|
379
|
-
access: team.access,
|
|
380
|
-
onSignOut: signOut,
|
|
381
|
-
workspace
|
|
382
|
-
})]
|
|
373
|
+
children: /* @__PURE__ */ jsx(SessionsBarButton, { onOpen: () => setIsSheetOpen(true) })
|
|
383
374
|
}),
|
|
384
375
|
workspace && /* @__PURE__ */ jsx(RecordingLayer, { onFinished: (target) => {
|
|
385
|
-
|
|
376
|
+
navigation.go({
|
|
377
|
+
target,
|
|
378
|
+
view: "review"
|
|
379
|
+
});
|
|
386
380
|
setIsSheetOpen(true);
|
|
387
381
|
} })
|
|
388
382
|
]
|
|
@@ -445,4 +439,4 @@ function TeamLayer({ connection, position }) {
|
|
|
445
439
|
//#endregion
|
|
446
440
|
export { TeamLayer };
|
|
447
441
|
|
|
448
|
-
//# sourceMappingURL=team-layer-
|
|
442
|
+
//# sourceMappingURL=team-layer-zLj_QPQX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-layer-zLj_QPQX.js","names":[],"sources":["../src/sessions/team/team-auth.ts","../src/sessions/team/team-sign-in-card.tsx","../src/sessions/team/team-layer.tsx"],"sourcesContent":["import { z } from \"zod\";\nimport { sessionApiErrorSchema } from \"../protocol\";\nimport { TEAM_ACTIVATION_PARAM, teamAccessStorageKey } from \"./team-activation\";\n\nconst RETURN_CODE_PARAM = \"reflet-team-code\";\nconst RETURN_ERROR_PARAM = \"reflet-team-error\";\nconst RETURN_STATE_PARAM = \"reflet-team-state\";\nconst RETURN_PARAMS = [\n RETURN_CODE_PARAM,\n RETURN_ERROR_PARAM,\n RETURN_STATE_PARAM,\n];\nconst PENDING_SIGN_IN_PREFIX = \"reflet-team-sign-in:\";\nconst PKCE_RANDOM_BYTES = 32;\nconst TRAILING_SLASHES = /\\/+$/;\nconst BASE64_PADDING = /[=]+$/;\n\nconst teamAccessSchema = z.object({\n expiresAt: z.number(),\n organizationName: z.string(),\n token: z.string().startsWith(\"fb_team_\"),\n});\n\nexport type TeamAccess = z.infer<typeof teamAccessSchema>;\n\nconst pendingSignInSchema = z.object({\n codeVerifier: z.string(),\n state: z.string(),\n});\n\ntype PendingSignIn = z.infer<typeof pendingSignInSchema>;\n\nconst SIGN_IN_FAILURE_MESSAGES = {\n cancelled: \"Sign-in was cancelled.\",\n exchange_failed: \"Couldn't finish signing in to Reflet. Try again.\",\n interrupted:\n \"This sign-in was started in another tab or has expired. Sign in again.\",\n storage_blocked:\n \"Your browser blocks storage for this site, so Reflet sign-in can't finish. Allow site data, then try again.\",\n} as const;\n\nexport type TeamSignInFailure = keyof typeof SIGN_IN_FAILURE_MESSAGES;\n\nexport class TeamSignInError extends Error {\n readonly reason: TeamSignInFailure;\n\n constructor(reason: TeamSignInFailure, message?: string) {\n super(message ?? SIGN_IN_FAILURE_MESSAGES[reason]);\n this.name = \"TeamSignInError\";\n this.reason = reason;\n }\n}\n\nfunction base64Url(bytes: Uint8Array): string {\n return btoa(String.fromCharCode(...bytes))\n .replaceAll(\"+\", \"-\")\n .replaceAll(\"/\", \"_\")\n .replace(BASE64_PADDING, \"\");\n}\n\nfunction randomBase64Url(): string {\n return base64Url(crypto.getRandomValues(new Uint8Array(PKCE_RANDOM_BYTES)));\n}\n\nasync function pkceChallengeFor(codeVerifier: string): Promise<string> {\n const digest = await crypto.subtle.digest(\n \"SHA-256\",\n new TextEncoder().encode(codeVerifier)\n );\n return base64Url(new Uint8Array(digest));\n}\n\nfunction apiEndpoint(apiUrl: string, path: string): string {\n return `${apiUrl.replace(TRAILING_SLASHES, \"\")}${path}`;\n}\n\nfunction parseStoredJson(raw: string): unknown {\n try {\n return JSON.parse(raw);\n } catch {\n return null;\n }\n}\n\nfunction storedTeamAccess(publicKey: string): TeamAccess | null {\n try {\n const raw = localStorage.getItem(teamAccessStorageKey(publicKey));\n const parsed = teamAccessSchema.safeParse(\n raw === null ? null : parseStoredJson(raw)\n );\n return parsed.success ? parsed.data : null;\n } catch {\n return null;\n }\n}\n\nfunction persistTeamAccess(publicKey: string, access: TeamAccess | null): void {\n try {\n if (access) {\n localStorage.setItem(\n teamAccessStorageKey(publicKey),\n JSON.stringify(access)\n );\n } else {\n localStorage.removeItem(teamAccessStorageKey(publicKey));\n }\n } catch {\n // Storage disabled by browser policy: access then only lasts for this page.\n }\n}\n\nexport function readTeamAccess(publicKey: string): TeamAccess | null {\n const access = storedTeamAccess(publicKey);\n if (access && access.expiresAt > Date.now()) {\n return access;\n }\n persistTeamAccess(publicKey, null);\n return null;\n}\n\nfunction pendingSignInKey(publicKey: string): string {\n return `${PENDING_SIGN_IN_PREFIX}${publicKey}`;\n}\n\nfunction takePendingSignIn(publicKey: string): PendingSignIn | null {\n try {\n const key = pendingSignInKey(publicKey);\n const raw = sessionStorage.getItem(key);\n sessionStorage.removeItem(key);\n const parsed = pendingSignInSchema.safeParse(\n raw === null ? null : parseStoredJson(raw)\n );\n return parsed.success ? parsed.data : null;\n } catch {\n return null;\n }\n}\n\nfunction rememberPendingSignIn(publicKey: string, pending: PendingSignIn) {\n try {\n sessionStorage.setItem(\n pendingSignInKey(publicKey),\n JSON.stringify(pending)\n );\n } catch {\n throw new TeamSignInError(\"storage_blocked\");\n }\n}\n\nfunction returnUrl(): string {\n const url = new URL(window.location.href);\n for (const param of RETURN_PARAMS) {\n url.searchParams.delete(param);\n }\n if (!url.searchParams.has(TEAM_ACTIVATION_PARAM)) {\n url.searchParams.set(TEAM_ACTIVATION_PARAM, \"\");\n }\n return url.href;\n}\n\nasync function exchangeCode(options: {\n apiUrl: string;\n code: string;\n codeVerifier: string;\n}): Promise<TeamAccess> {\n const response = await fetch(\n apiEndpoint(options.apiUrl, \"/api/v1/team/token\"),\n {\n body: JSON.stringify({\n code: options.code,\n codeVerifier: options.codeVerifier,\n }),\n headers: { \"Content-Type\": \"application/json\" },\n method: \"POST\",\n }\n );\n if (!response.ok) {\n const failure = sessionApiErrorSchema.safeParse(\n await response.json().catch(() => null)\n );\n throw new TeamSignInError(\n \"exchange_failed\",\n failure.success ? failure.data.error : undefined\n );\n }\n const access = teamAccessSchema.safeParse(\n await response.json().catch(() => null)\n );\n if (!access.success) {\n throw new TeamSignInError(\"exchange_failed\");\n }\n return access.data;\n}\n\nexport async function prepareTeamSignIn(options: {\n appUrl: string;\n publicKey: string;\n}): Promise<string> {\n const pending = { codeVerifier: randomBase64Url(), state: randomBase64Url() };\n rememberPendingSignIn(options.publicKey, pending);\n const consentUrl = new URL(\"/auth/team\", options.appUrl);\n consentUrl.search = new URLSearchParams({\n code_challenge: await pkceChallengeFor(pending.codeVerifier),\n origin: window.location.origin,\n public_key: options.publicKey,\n return_to: returnUrl(),\n state: pending.state,\n }).toString();\n return consentUrl.href;\n}\n\nexport function hasTeamSignInReturn(): boolean {\n return new URL(window.location.href).searchParams.has(RETURN_STATE_PARAM);\n}\n\nasync function completeReturnedSignIn(options: {\n apiUrl: string;\n code: string | null;\n pending: PendingSignIn | null;\n publicKey: string;\n state: string;\n}): Promise<TeamAccess> {\n if (options.pending?.state !== options.state) {\n throw new TeamSignInError(\"interrupted\");\n }\n if (options.code === null) {\n throw new TeamSignInError(\"cancelled\");\n }\n const access = await exchangeCode({\n apiUrl: options.apiUrl,\n code: options.code,\n codeVerifier: options.pending.codeVerifier,\n });\n persistTeamAccess(options.publicKey, access);\n return access;\n}\n\n/** Strips the returned code from the address bar at once, so it is consumed by one caller only. */\nexport function finishTeamSignIn(options: {\n apiUrl: string;\n publicKey: string;\n}): Promise<TeamAccess> | null {\n const url = new URL(window.location.href);\n const state = url.searchParams.get(RETURN_STATE_PARAM);\n if (state === null) {\n return null;\n }\n const code = url.searchParams.get(RETURN_CODE_PARAM);\n for (const param of RETURN_PARAMS) {\n url.searchParams.delete(param);\n }\n window.history.replaceState(window.history.state, \"\", url.href);\n return completeReturnedSignIn({\n apiUrl: options.apiUrl,\n code,\n pending: takePendingSignIn(options.publicKey),\n publicKey: options.publicKey,\n state,\n });\n}\n\nexport async function forgetTeamAccess(options: {\n apiUrl: string;\n publicKey: string;\n}): Promise<void> {\n const access = storedTeamAccess(options.publicKey);\n persistTeamAccess(options.publicKey, null);\n if (!access) {\n return;\n }\n await fetch(apiEndpoint(options.apiUrl, \"/api/v1/team/revoke\"), {\n headers: { Authorization: `Bearer ${access.token}` },\n method: \"POST\",\n });\n}\n","import { useState } from \"react\";\nimport { failureMessage } from \"../ui/session-workspace\";\nimport { prepareTeamSignIn } from \"./team-auth\";\n\nexport interface TeamConnection {\n apiUrl: string;\n appUrl: string;\n publicKey: string;\n}\n\nfunction useTeamSignIn(connection: TeamConnection) {\n const [isLeaving, setIsLeaving] = useState(false);\n const [failure, setFailure] = useState<string | null>(null);\n\n const signIn = async () => {\n setIsLeaving(true);\n setFailure(null);\n try {\n window.location.assign(await prepareTeamSignIn(connection));\n } catch (error) {\n setFailure(failureMessage(error));\n setIsLeaving(false);\n }\n };\n\n return { failure, isLeaving, signIn };\n}\n\nfunction SignInActions({\n isSigningIn,\n onHide,\n onSignIn,\n}: {\n isSigningIn: boolean;\n onHide: () => void;\n onSignIn: () => void;\n}) {\n return (\n <div className=\"dt-actions\">\n <button\n className=\"dt-btn\"\n data-variant=\"primary\"\n disabled={isSigningIn}\n onClick={onSignIn}\n type=\"button\"\n >\n Sign in with Reflet\n </button>\n <button className=\"dt-btn\" onClick={onHide} type=\"button\">\n Hide\n </button>\n </div>\n );\n}\n\nexport function TeamSignInCard({\n connection,\n isFinishing,\n notice,\n}: {\n connection: TeamConnection;\n isFinishing: boolean;\n notice: string | null;\n}) {\n const [isHidden, setIsHidden] = useState(false);\n const { failure, isLeaving, signIn } = useTeamSignIn(connection);\n\n if (isHidden) {\n return null;\n }\n return (\n <section aria-labelledby=\"rf-team-title\" className=\"dt-team-card glass\">\n <h2 className=\"dt-ses-subhead\" id=\"rf-team-title\">\n Reflet team tools\n </h2>\n <p className=\"dt-meta\">\n Sign in with your Reflet account to record a session on this app.\n </p>\n <p className=\"dt-meta\">\n Only members of the app's Reflet organization can sign in.\n </p>\n {isFinishing && (\n <p className=\"dt-meta\" role=\"status\">\n Finishing sign-in…\n </p>\n )}\n {notice && (\n <p className=\"dt-meta\" role=\"status\">\n {notice}\n </p>\n )}\n {failure && (\n <p className=\"dt-error\" role=\"alert\">\n {failure}\n </p>\n )}\n <SignInActions\n isSigningIn={isLeaving || isFinishing}\n onHide={() => setIsHidden(true)}\n onSignIn={signIn}\n />\n </section>\n );\n}\n","import { useEffect, useState } from \"react\";\nimport { AccountFooter } from \"../../devtools/client/account/account-footer\";\nimport {\n DevtoolsBar,\n SessionsBarButton,\n} from \"../../devtools/client/devtools-bar\";\nimport { DevtoolsSheet } from \"../../devtools/client/devtools-sheet\";\nimport { DEVTOOLS_STYLES } from \"../../devtools/client/devtools-styles\";\nimport { Notices, reportFailure } from \"../../devtools/client/notices\";\nimport type { RefletFeedbackProps } from \"../../feedback/types\";\nimport { teamTransport } from \"../api/session-transports\";\nimport { purgeAccount } from \"../local/local-sessions\";\nimport { RecordingLayer } from \"../ui/recording/recording-layer\";\nimport {\n failureMessage,\n SessionWorkspaceProvider,\n useWorkspaceLoader,\n type WorkspaceState,\n} from \"../ui/session-workspace\";\nimport {\n type SessionNavigation,\n SessionsPanel,\n sessionSheetPlace,\n useSessionNavigation,\n} from \"../ui/sessions-panel\";\nimport { SESSIONS_STYLES } from \"../ui/sessions-styles\";\nimport {\n finishTeamSignIn,\n forgetTeamAccess,\n hasTeamSignInReturn,\n readTeamAccess,\n type TeamAccess,\n} from \"./team-auth\";\nimport { type TeamConnection, TeamSignInCard } from \"./team-sign-in-card\";\n\nconst TEAM_TOOLS_LABEL = \"Reflet team tools\";\nconst REFUSED_SIGN_IN_COPY =\n \"Reflet no longer accepts this sign-in. Sign in again to record.\";\n\ninterface TeamPlacement {\n edge: \"bottom\" | \"top\";\n side: \"left\" | \"right\";\n}\n\nfunction SessionsBody({\n navigation,\n onStarted,\n state,\n}: {\n navigation: SessionNavigation;\n onStarted: () => void;\n state: WorkspaceState;\n}) {\n if (state.kind === \"ready\") {\n return <SessionsPanel navigation={navigation} onStarted={onStarted} />;\n }\n if (state.kind === \"failed\") {\n return (\n <div className=\"dt-empty\" role=\"alert\">\n <p>Sessions did not open: {state.message}</p>\n <button className=\"dt-btn\" onClick={state.retry} type=\"button\">\n Try again\n </button>\n </div>\n );\n }\n return <p className=\"dt-status\">Opening your sessions…</p>;\n}\n\nfunction TeamSheet({\n account,\n navigation,\n onClose,\n side,\n}: {\n account: { access: TeamAccess; onSignOut: () => void; state: WorkspaceState };\n navigation: SessionNavigation;\n onClose: () => void;\n side: TeamPlacement[\"side\"];\n}) {\n const { state } = account;\n const place = state.kind === \"ready\" ? sessionSheetPlace(navigation) : null;\n return (\n <DevtoolsSheet\n footer={\n place === null && (\n <AccountFooter\n actions={[{ label: \"Sign out\", onSelect: account.onSignOut }]}\n organizationName={account.access.organizationName}\n person={\n state.kind === \"ready\" ? state.workspace.identity.user : null\n }\n />\n )\n }\n label={TEAM_TOOLS_LABEL}\n navigation={{\n onSelectTab: () => undefined,\n place,\n tab: \"sessions\",\n tabs: [\"sessions\"],\n }}\n onClose={onClose}\n side={side}\n >\n <SessionsBody navigation={navigation} onStarted={onClose} state={state} />\n </DevtoolsSheet>\n );\n}\n\ninterface TeamSession {\n access: TeamAccess;\n apiUrl: string;\n onSignOut: (reason: string | null) => void;\n}\n\nfunction useTeamTransport(team: TeamSession) {\n const createTransport = () => ({\n apiUrl: team.apiUrl,\n transport: teamTransport({ apiUrl: team.apiUrl, token: team.access.token }),\n });\n const [current, setCurrent] = useState(createTransport);\n if (current.apiUrl !== team.apiUrl) {\n const next = createTransport();\n setCurrent(next);\n return next.transport;\n }\n return current.transport;\n}\n\nfunction useTeamWorkspace(team: TeamSession) {\n const { onSignOut } = team;\n const transport = useTeamTransport(team);\n const state = useWorkspaceLoader({\n onUnauthorized: () => onSignOut(REFUSED_SIGN_IN_COPY),\n surface: \"app\",\n transport,\n });\n const workspace = state.kind === \"ready\" ? state.workspace : null;\n\n const signOut = async () => {\n if (workspace) {\n await purgeAccount(workspace.account.key).catch((error: unknown) =>\n reportFailure(\"This device's session data was not removed\", error)\n );\n }\n onSignOut(null);\n };\n\n return { signOut, state, workspace };\n}\n\nfunction TeamTools({\n team,\n placement,\n}: {\n placement: TeamPlacement;\n team: TeamSession;\n}) {\n const { signOut, state, workspace } = useTeamWorkspace(team);\n const [isSheetOpen, setIsSheetOpen] = useState(false);\n const navigation = useSessionNavigation();\n\n return (\n <SessionWorkspaceProvider workspace={workspace}>\n {isSheetOpen && (\n <TeamSheet\n account={{ access: team.access, onSignOut: signOut, state }}\n navigation={navigation}\n onClose={() => setIsSheetOpen(false)}\n side={placement.side}\n />\n )}\n <DevtoolsBar\n edge={placement.edge}\n label={TEAM_TOOLS_LABEL}\n side={placement.side}\n >\n <SessionsBarButton onOpen={() => setIsSheetOpen(true)} />\n </DevtoolsBar>\n {workspace && (\n <RecordingLayer\n onFinished={(target) => {\n navigation.go({ target, view: \"review\" });\n setIsSheetOpen(true);\n }}\n />\n )}\n </SessionWorkspaceProvider>\n );\n}\n\nfunction placementFor(\n position: NonNullable<RefletFeedbackProps[\"position\"]>\n): TeamPlacement {\n return {\n edge: position.startsWith(\"top\") ? \"top\" : \"bottom\",\n side: position.endsWith(\"right\") ? \"right\" : \"left\",\n };\n}\n\nexport function TeamLayer({\n connection,\n position,\n}: {\n connection: TeamConnection;\n position: NonNullable<RefletFeedbackProps[\"position\"]>;\n}) {\n const { apiUrl, publicKey } = connection;\n const [access, setAccess] = useState(() => readTeamAccess(publicKey));\n const [notice, setNotice] = useState<string | null>(null);\n const [isFinishing, setIsFinishing] = useState(hasTeamSignInReturn);\n useEffect(() => {\n finishTeamSignIn({ apiUrl, publicKey })\n ?.then(\n (signedIn) => {\n setAccess(signedIn);\n setNotice(null);\n },\n (error: unknown) => setNotice(failureMessage(error))\n )\n .finally(() => setIsFinishing(false));\n }, [apiUrl, publicKey]);\n const signOut = (reason: string | null) => {\n setAccess(null);\n setNotice(reason);\n forgetTeamAccess({ apiUrl, publicKey }).catch((error: unknown) =>\n reportFailure(\"Signing out of Reflet did not finish\", error)\n );\n };\n const placement = placementFor(position);\n\n return (\n <div className=\"dt\">\n <style>{`${DEVTOOLS_STYLES}${SESSIONS_STYLES}`}</style>\n {access ? (\n <TeamTools\n placement={placement}\n team={{ access, apiUrl, onSignOut: signOut }}\n />\n ) : (\n <div\n className=\"dt-team-anchor\"\n data-edge={placement.edge}\n data-side={placement.side}\n >\n <TeamSignInCard\n connection={connection}\n isFinishing={isFinishing}\n notice={notice}\n />\n </div>\n )}\n <Notices />\n </div>\n );\n}\n"],"mappings":";;;;;;AAIA,MAAM,oBAAoB;AAC1B,MAAM,qBAAqB;AAC3B,MAAM,qBAAqB;AAC3B,MAAM,gBAAgB;CACpB;CACA;CACA;AACF;AACA,MAAM,yBAAyB;AAC/B,MAAM,oBAAoB;AAC1B,MAAM,mBAAmB;AACzB,MAAM,iBAAiB;AAEvB,MAAM,mBAAmB,EAAE,OAAO;CAChC,WAAW,EAAE,OAAO;CACpB,kBAAkB,EAAE,OAAO;CAC3B,OAAO,EAAE,OAAO,CAAC,CAAC,WAAW,UAAU;AACzC,CAAC;AAID,MAAM,sBAAsB,EAAE,OAAO;CACnC,cAAc,EAAE,OAAO;CACvB,OAAO,EAAE,OAAO;AAClB,CAAC;AAID,MAAM,2BAA2B;CAC/B,WAAW;CACX,iBAAiB;CACjB,aACE;CACF,iBACE;AACJ;AAIA,IAAa,kBAAb,cAAqC,MAAM;CACzC;CAEA,YAAY,QAA2B,SAAkB;EACvD,MAAM,WAAW,yBAAyB,OAAO;EACjD,KAAK,OAAO;EACZ,KAAK,SAAS;CAChB;AACF;AAEA,SAAS,UAAU,OAA2B;CAC5C,OAAO,KAAK,OAAO,aAAa,GAAG,KAAK,CAAC,CAAC,CACvC,WAAW,KAAK,GAAG,CAAC,CACpB,WAAW,KAAK,GAAG,CAAC,CACpB,QAAQ,gBAAgB,EAAE;AAC/B;AAEA,SAAS,kBAA0B;CACjC,OAAO,UAAU,OAAO,gBAAgB,IAAI,WAAW,iBAAiB,CAAC,CAAC;AAC5E;AAEA,eAAe,iBAAiB,cAAuC;CACrE,MAAM,SAAS,MAAM,OAAO,OAAO,OACjC,WACA,IAAI,YAAY,CAAC,CAAC,OAAO,YAAY,CACvC;CACA,OAAO,UAAU,IAAI,WAAW,MAAM,CAAC;AACzC;AAEA,SAAS,YAAY,QAAgB,MAAsB;CACzD,OAAO,GAAG,OAAO,QAAQ,kBAAkB,EAAE,IAAI;AACnD;AAEA,SAAS,gBAAgB,KAAsB;CAC7C,IAAI;EACF,OAAO,KAAK,MAAM,GAAG;CACvB,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAS,iBAAiB,WAAsC;CAC9D,IAAI;EACF,MAAM,MAAM,aAAa,QAAQ,qBAAqB,SAAS,CAAC;EAChE,MAAM,SAAS,iBAAiB,UAC9B,QAAQ,OAAO,OAAO,gBAAgB,GAAG,CAC3C;EACA,OAAO,OAAO,UAAU,OAAO,OAAO;CACxC,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAS,kBAAkB,WAAmB,QAAiC;CAC7E,IAAI;EACF,IAAI,QACF,aAAa,QACX,qBAAqB,SAAS,GAC9B,KAAK,UAAU,MAAM,CACvB;OAEA,aAAa,WAAW,qBAAqB,SAAS,CAAC;CAE3D,QAAQ,CAER;AACF;AAEA,SAAgB,eAAe,WAAsC;CACnE,MAAM,SAAS,iBAAiB,SAAS;CACzC,IAAI,UAAU,OAAO,YAAY,KAAK,IAAI,GACxC,OAAO;CAET,kBAAkB,WAAW,IAAI;CACjC,OAAO;AACT;AAEA,SAAS,iBAAiB,WAA2B;CACnD,OAAO,GAAG,yBAAyB;AACrC;AAEA,SAAS,kBAAkB,WAAyC;CAClE,IAAI;EACF,MAAM,MAAM,iBAAiB,SAAS;EACtC,MAAM,MAAM,eAAe,QAAQ,GAAG;EACtC,eAAe,WAAW,GAAG;EAC7B,MAAM,SAAS,oBAAoB,UACjC,QAAQ,OAAO,OAAO,gBAAgB,GAAG,CAC3C;EACA,OAAO,OAAO,UAAU,OAAO,OAAO;CACxC,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAS,sBAAsB,WAAmB,SAAwB;CACxE,IAAI;EACF,eAAe,QACb,iBAAiB,SAAS,GAC1B,KAAK,UAAU,OAAO,CACxB;CACF,QAAQ;EACN,MAAM,IAAI,gBAAgB,iBAAiB;CAC7C;AACF;AAEA,SAAS,YAAoB;CAC3B,MAAM,MAAM,IAAI,IAAI,OAAO,SAAS,IAAI;CACxC,KAAK,MAAM,SAAS,eAClB,IAAI,aAAa,OAAO,KAAK;CAE/B,IAAI,CAAC,IAAI,aAAa,IAAA,aAAyB,GAC7C,IAAI,aAAa,IAAI,uBAAuB,EAAE;CAEhD,OAAO,IAAI;AACb;AAEA,eAAe,aAAa,SAIJ;CACtB,MAAM,WAAW,MAAM,MACrB,YAAY,QAAQ,QAAQ,oBAAoB,GAChD;EACE,MAAM,KAAK,UAAU;GACnB,MAAM,QAAQ;GACd,cAAc,QAAQ;EACxB,CAAC;EACD,SAAS,EAAE,gBAAgB,mBAAmB;EAC9C,QAAQ;CACV,CACF;CACA,IAAI,CAAC,SAAS,IAAI;EAChB,MAAM,UAAU,sBAAsB,UACpC,MAAM,SAAS,KAAK,CAAC,CAAC,YAAY,IAAI,CACxC;EACA,MAAM,IAAI,gBACR,mBACA,QAAQ,UAAU,QAAQ,KAAK,QAAQ,KAAA,CACzC;CACF;CACA,MAAM,SAAS,iBAAiB,UAC9B,MAAM,SAAS,KAAK,CAAC,CAAC,YAAY,IAAI,CACxC;CACA,IAAI,CAAC,OAAO,SACV,MAAM,IAAI,gBAAgB,iBAAiB;CAE7C,OAAO,OAAO;AAChB;AAEA,eAAsB,kBAAkB,SAGpB;CAClB,MAAM,UAAU;EAAE,cAAc,gBAAgB;EAAG,OAAO,gBAAgB;CAAE;CAC5E,sBAAsB,QAAQ,WAAW,OAAO;CAChD,MAAM,aAAa,IAAI,IAAI,cAAc,QAAQ,MAAM;CACvD,WAAW,SAAS,IAAI,gBAAgB;EACtC,gBAAgB,MAAM,iBAAiB,QAAQ,YAAY;EAC3D,QAAQ,OAAO,SAAS;EACxB,YAAY,QAAQ;EACpB,WAAW,UAAU;EACrB,OAAO,QAAQ;CACjB,CAAC,CAAC,CAAC,SAAS;CACZ,OAAO,WAAW;AACpB;AAEA,SAAgB,sBAA+B;CAC7C,OAAO,IAAI,IAAI,OAAO,SAAS,IAAI,CAAC,CAAC,aAAa,IAAI,kBAAkB;AAC1E;AAEA,eAAe,uBAAuB,SAMd;CACtB,IAAI,QAAQ,SAAS,UAAU,QAAQ,OACrC,MAAM,IAAI,gBAAgB,aAAa;CAEzC,IAAI,QAAQ,SAAS,MACnB,MAAM,IAAI,gBAAgB,WAAW;CAEvC,MAAM,SAAS,MAAM,aAAa;EAChC,QAAQ,QAAQ;EAChB,MAAM,QAAQ;EACd,cAAc,QAAQ,QAAQ;CAChC,CAAC;CACD,kBAAkB,QAAQ,WAAW,MAAM;CAC3C,OAAO;AACT;;AAGA,SAAgB,iBAAiB,SAGF;CAC7B,MAAM,MAAM,IAAI,IAAI,OAAO,SAAS,IAAI;CACxC,MAAM,QAAQ,IAAI,aAAa,IAAI,kBAAkB;CACrD,IAAI,UAAU,MACZ,OAAO;CAET,MAAM,OAAO,IAAI,aAAa,IAAI,iBAAiB;CACnD,KAAK,MAAM,SAAS,eAClB,IAAI,aAAa,OAAO,KAAK;CAE/B,OAAO,QAAQ,aAAa,OAAO,QAAQ,OAAO,IAAI,IAAI,IAAI;CAC9D,OAAO,uBAAuB;EAC5B,QAAQ,QAAQ;EAChB;EACA,SAAS,kBAAkB,QAAQ,SAAS;EAC5C,WAAW,QAAQ;EACnB;CACF,CAAC;AACH;AAEA,eAAsB,iBAAiB,SAGrB;CAChB,MAAM,SAAS,iBAAiB,QAAQ,SAAS;CACjD,kBAAkB,QAAQ,WAAW,IAAI;CACzC,IAAI,CAAC,QACH;CAEF,MAAM,MAAM,YAAY,QAAQ,QAAQ,qBAAqB,GAAG;EAC9D,SAAS,EAAE,eAAe,UAAU,OAAO,QAAQ;EACnD,QAAQ;CACV,CAAC;AACH;;;ACxQA,SAAS,cAAc,YAA4B;CACjD,MAAM,CAAC,WAAW,gBAAgB,SAAS,KAAK;CAChD,MAAM,CAAC,SAAS,cAAc,SAAwB,IAAI;CAE1D,MAAM,SAAS,YAAY;EACzB,aAAa,IAAI;EACjB,WAAW,IAAI;EACf,IAAI;GACF,OAAO,SAAS,OAAO,MAAM,kBAAkB,UAAU,CAAC;EAC5D,SAAS,OAAO;GACd,WAAW,eAAe,KAAK,CAAC;GAChC,aAAa,KAAK;EACpB;CACF;CAEA,OAAO;EAAE;EAAS;EAAW;CAAO;AACtC;AAEA,SAAS,cAAc,EACrB,aACA,QACA,YAKC;CACD,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,UAAD;GACE,WAAU;GACV,gBAAa;GACb,UAAU;GACV,SAAS;GACT,MAAK;GACN,UAAA;EAEO,CAAA,GACR,oBAAC,UAAD;GAAQ,WAAU;GAAS,SAAS;GAAQ,MAAK;GAAS,UAAA;EAElD,CAAA,CACL;;AAET;AAEA,SAAgB,eAAe,EAC7B,YACA,aACA,UAKC;CACD,MAAM,CAAC,UAAU,eAAe,SAAS,KAAK;CAC9C,MAAM,EAAE,SAAS,WAAW,WAAW,cAAc,UAAU;CAE/D,IAAI,UACF,OAAO;CAET,OACE,qBAAC,WAAD;EAAS,mBAAgB;EAAgB,WAAU;EAAnD,UAAA;GACE,oBAAC,MAAD;IAAI,WAAU;IAAiB,IAAG;IAAgB,UAAA;GAE9C,CAAA;GACJ,oBAAC,KAAD;IAAG,WAAU;IAAU,UAAA;GAEpB,CAAA;GACH,oBAAC,KAAD;IAAG,WAAU;IAAU,UAAA;GAEpB,CAAA;GACF,eACC,oBAAC,KAAD;IAAG,WAAU;IAAU,MAAK;IAAS,UAAA;GAElC,CAAA;GAEJ,UACC,oBAAC,KAAD;IAAG,WAAU;IAAU,MAAK;IACzB,UAAA;GACA,CAAA;GAEJ,WACC,oBAAC,KAAD;IAAG,WAAU;IAAW,MAAK;IAC1B,UAAA;GACA,CAAA;GAEL,oBAAC,eAAD;IACE,aAAa,aAAa;IAC1B,cAAc,YAAY,IAAI;IAC9B,UAAU;GACX,CAAA;EACM;;AAEb;;;ACpEA,MAAM,mBAAmB;AACzB,MAAM,uBACJ;AAOF,SAAS,aAAa,EACpB,YACA,WACA,SAKC;CACD,IAAI,MAAM,SAAS,SACjB,OAAO,oBAAC,eAAD;EAA2B;EAAuB;CAAY,CAAA;CAEvE,IAAI,MAAM,SAAS,UACjB,OACE,qBAAC,OAAD;EAAK,WAAU;EAAW,MAAK;EAA/B,UAAA,CACE,qBAAC,KAAD,EAAA,UAAA,CAAG,2BAAwB,MAAM,OAAW,EAAA,CAAA,GAC5C,oBAAC,UAAD;GAAQ,WAAU;GAAS,SAAS,MAAM;GAAO,MAAK;GAAS,UAAA;EAEvD,CAAA,CACL;;CAGT,OAAO,oBAAC,KAAD;EAAG,WAAU;EAAY,UAAA;CAAyB,CAAA;AAC3D;AAEA,SAAS,UAAU,EACjB,SACA,YACA,SACA,QAMC;CACD,MAAM,EAAE,UAAU;CAClB,MAAM,QAAQ,MAAM,SAAS,UAAU,kBAAkB,UAAU,IAAI;CACvE,OACE,oBAAC,eAAD;EACE,QACE,UAAU,QACR,oBAAC,eAAD;GACE,SAAS,CAAC;IAAE,OAAO;IAAY,UAAU,QAAQ;GAAU,CAAC;GAC5D,kBAAkB,QAAQ,OAAO;GACjC,QACE,MAAM,SAAS,UAAU,MAAM,UAAU,SAAS,OAAO;EAE5D,CAAA;EAGL,OAAO;EACP,YAAY;GACV,mBAAmB,KAAA;GACnB;GACA,KAAK;GACL,MAAM,CAAC,UAAU;EACnB;EACS;EACH;EAEN,UAAA,oBAAC,cAAD;GAA0B;GAAY,WAAW;GAAgB;EAAQ,CAAA;CAC5D,CAAA;AAEnB;AAQA,SAAS,iBAAiB,MAAmB;CAC3C,MAAM,yBAAyB;EAC7B,QAAQ,KAAK;EACb,WAAW,cAAc;GAAE,QAAQ,KAAK;GAAQ,OAAO,KAAK,OAAO;EAAM,CAAC;CAC5E;CACA,MAAM,CAAC,SAAS,cAAc,SAAS,eAAe;CACtD,IAAI,QAAQ,WAAW,KAAK,QAAQ;EAClC,MAAM,OAAO,gBAAgB;EAC7B,WAAW,IAAI;EACf,OAAO,KAAK;CACd;CACA,OAAO,QAAQ;AACjB;AAEA,SAAS,iBAAiB,MAAmB;CAC3C,MAAM,EAAE,cAAc;CACtB,MAAM,YAAY,iBAAiB,IAAI;CACvC,MAAM,QAAQ,mBAAmB;EAC/B,sBAAsB,UAAU,oBAAoB;EACpD,SAAS;EACT;CACF,CAAC;CACD,MAAM,YAAY,MAAM,SAAS,UAAU,MAAM,YAAY;CAE7D,MAAM,UAAU,YAAY;EAC1B,IAAI,WACF,MAAM,aAAa,UAAU,QAAQ,GAAG,CAAC,CAAC,OAAO,UAC/C,cAAc,8CAA8C,KAAK,CACnE;EAEF,UAAU,IAAI;CAChB;CAEA,OAAO;EAAE;EAAS;EAAO;CAAU;AACrC;AAEA,SAAS,UAAU,EACjB,MACA,aAIC;CACD,MAAM,EAAE,SAAS,OAAO,cAAc,iBAAiB,IAAI;CAC3D,MAAM,CAAC,aAAa,kBAAkB,SAAS,KAAK;CACpD,MAAM,aAAa,qBAAqB;CAExC,OACE,qBAAC,0BAAD;EAAqC;EAArC,UAAA;GACG,eACC,oBAAC,WAAD;IACE,SAAS;KAAE,QAAQ,KAAK;KAAQ,WAAW;KAAS;IAAM;IAC9C;IACZ,eAAe,eAAe,KAAK;IACnC,MAAM,UAAU;GACjB,CAAA;GAEH,oBAAC,aAAD;IACE,MAAM,UAAU;IAChB,OAAO;IACP,MAAM,UAAU;IAEhB,UAAA,oBAAC,mBAAD,EAAmB,cAAc,eAAe,IAAI,EAAI,CAAA;GAC7C,CAAA;GACZ,aACC,oBAAC,gBAAD,EACE,aAAa,WAAW;IACtB,WAAW,GAAG;KAAE;KAAQ,MAAM;IAAS,CAAC;IACxC,eAAe,IAAI;GACrB,EACD,CAAA;EAEqB;;AAE9B;AAEA,SAAS,aACP,UACe;CACf,OAAO;EACL,MAAM,SAAS,WAAW,KAAK,IAAI,QAAQ;EAC3C,MAAM,SAAS,SAAS,OAAO,IAAI,UAAU;CAC/C;AACF;AAEA,SAAgB,UAAU,EACxB,YACA,YAIC;CACD,MAAM,EAAE,QAAQ,cAAc;CAC9B,MAAM,CAAC,QAAQ,aAAa,eAAe,eAAe,SAAS,CAAC;CACpE,MAAM,CAAC,QAAQ,aAAa,SAAwB,IAAI;CACxD,MAAM,CAAC,aAAa,kBAAkB,SAAS,mBAAmB;CAClE,gBAAgB;EACd,iBAAiB;GAAE;GAAQ;EAAU,CAAC,CAAC,EACnC,MACC,aAAa;GACZ,UAAU,QAAQ;GAClB,UAAU,IAAI;EAChB,IACC,UAAmB,UAAU,eAAe,KAAK,CAAC,CACrD,CAAC,CACA,cAAc,eAAe,KAAK,CAAC;CACxC,GAAG,CAAC,QAAQ,SAAS,CAAC;CACtB,MAAM,WAAW,WAA0B;EACzC,UAAU,IAAI;EACd,UAAU,MAAM;EAChB,iBAAiB;GAAE;GAAQ;EAAU,CAAC,CAAC,CAAC,OAAO,UAC7C,cAAc,wCAAwC,KAAK,CAC7D;CACF;CACA,MAAM,YAAY,aAAa,QAAQ;CAEvC,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA;GACE,oBAAC,SAAD,EAAA,UAAQ,GAAG,kBAAkB,kBAAyB,CAAA;GACrD,SACC,oBAAC,WAAD;IACa;IACX,MAAM;KAAE;KAAQ;KAAQ,WAAW;IAAQ;GAC5C,CAAA,IAED,oBAAC,OAAD;IACE,WAAU;IACV,aAAW,UAAU;IACrB,aAAW,UAAU;IAErB,UAAA,oBAAC,gBAAD;KACc;KACC;KACL;IACT,CAAA;GACE,CAAA;GAEP,oBAAC,SAAD,CAAU,CAAA;EACP;;AAET"}
|