@adminide-stack/yantra-mobile 12.0.69 → 12.0.70-alpha.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.
@@ -1,4 +1,4 @@
1
- import {jsxs,jsx}from'react/jsx-runtime';import {memo,useMemo}from'react';import {View,StyleSheet,Text,Pressable,ActivityIndicator}from'react-native';import {MaterialCommunityIcons}from'@expo/vector-icons';const ACCENT = "#2563eb";
1
+ import {jsxs,jsx}from'react/jsx-runtime';import {memo,useMemo}from'react';import {View,StyleSheet,Text,Pressable,ActivityIndicator}from'react-native';import {MaterialCommunityIcons}from'@expo/vector-icons';import {a11yActionLabel}from'./connectorConnect.js';const ACCENT = "#2563eb";
2
2
  const styles = StyleSheet.create({
3
3
  card: {
4
4
  width: "100%",
@@ -90,8 +90,9 @@ const styles = StyleSheet.create({
90
90
  function ConnectorConnectCardView({
91
91
  name,
92
92
  reason,
93
- siteLogin,
93
+ icon,
94
94
  connected,
95
+ connectedLabel = "Connected",
95
96
  actionLabel,
96
97
  busy = false,
97
98
  actionPending = false,
@@ -111,6 +112,7 @@ function ConnectorConnectCardView({
111
112
  outline: isDark ? "#334155" : "#d1d5db"
112
113
  }), [isDark]);
113
114
  const actionDisabled = busy || actionPending;
115
+ const actionA11yLabel = a11yActionLabel(actionLabel, name);
114
116
  return /* @__PURE__ */ jsxs(View, { style: [styles.card, {
115
117
  backgroundColor: palette.card,
116
118
  borderColor: palette.border
@@ -118,7 +120,7 @@ function ConnectorConnectCardView({
118
120
  /* @__PURE__ */ jsxs(View, { style: styles.row, children: [
119
121
  /* @__PURE__ */ jsx(View, { style: [styles.icon, {
120
122
  backgroundColor: palette.iconBg
121
- }], children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: siteLogin ? "key-variant" : "power-plug-outline", size: 18, color: palette.muted }) }),
123
+ }], children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: icon, size: 18, color: palette.muted }) }),
122
124
  /* @__PURE__ */ jsxs(View, { style: styles.body, children: [
123
125
  /* @__PURE__ */ jsxs(View, { style: styles.titleRow, children: [
124
126
  /* @__PURE__ */ jsx(Text, { style: [styles.title, {
@@ -128,7 +130,7 @@ function ConnectorConnectCardView({
128
130
  backgroundColor: palette.badgeBg
129
131
  }], children: /* @__PURE__ */ jsx(Text, { style: [styles.badgeText, {
130
132
  color: palette.badgeText
131
- }], children: "Connected" }) }) : null
133
+ }], children: connectedLabel }) }) : null
132
134
  ] }),
133
135
  /* @__PURE__ */ jsx(Text, { style: [styles.reason, {
134
136
  color: palette.muted
@@ -141,7 +143,7 @@ function ConnectorConnectCardView({
141
143
  }, onPress: onDismiss, disabled: busy, hitSlop: 6, style: styles.secondary, children: /* @__PURE__ */ jsx(Text, { style: [styles.secondaryText, {
142
144
  color: palette.muted
143
145
  }], children: "Not now" }) }),
144
- /* @__PURE__ */ jsx(Pressable, { accessibilityRole: "button", accessibilityLabel: `${actionLabel} ${name}`, accessibilityState: {
146
+ /* @__PURE__ */ jsx(Pressable, { accessibilityRole: "button", accessibilityLabel: actionA11yLabel, accessibilityState: {
145
147
  disabled: actionDisabled,
146
148
  busy: actionDisabled
147
149
  }, onPress: onAction, disabled: actionDisabled, style: ({
@@ -1 +1 @@
1
- {"version":3,"file":"ConnectorConnectCard.js","sources":["../../../src/features/chat/ConnectorConnectCard.tsx"],"sourcesContent":["/**\n * <ConnectorConnectCard> - the `[CONNECTOR_CONNECT]` request as a touch card.\n *\n * Phone twin of the web ConnectorConnectCard: icon, name (+ \"Connected\" when a\n * matching credential is already saved), the agent's reason, then the primary\n * action (\"Save login\" / \"Connect\", or \"Update\" for a saved one) and \"Not now\".\n * Presentational only: status, the browser session and the reply live in\n * ConnectorConnectPrompt.\n */\nimport React, { memo, useMemo } from 'react';\nimport { ActivityIndicator, Pressable, StyleSheet, Text, View } from 'react-native';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\n\nconst ACCENT = '#2563eb';\n\nconst styles = StyleSheet.create({\n card: {\n width: '100%',\n borderWidth: 1,\n borderRadius: 16,\n padding: 14,\n marginTop: 4,\n marginBottom: 8,\n },\n row: { flexDirection: 'row', alignItems: 'flex-start', gap: 12 },\n icon: { width: 36, height: 36, borderRadius: 10, alignItems: 'center', justifyContent: 'center' },\n body: { flex: 1, minWidth: 0 },\n titleRow: { flexDirection: 'row', alignItems: 'center', gap: 8 },\n title: { flexShrink: 1, fontSize: 15, fontWeight: '700', lineHeight: 20 },\n badge: { borderRadius: 999, paddingHorizontal: 8, paddingVertical: 2 },\n badgeText: { fontSize: 11, fontWeight: '700' },\n reason: { fontSize: 13, lineHeight: 18, marginTop: 2 },\n actions: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'flex-end',\n marginTop: 12,\n gap: 4,\n },\n secondary: { paddingHorizontal: 12, minHeight: 44, justifyContent: 'center' },\n secondaryText: { fontSize: 13, fontWeight: '600' },\n primary: {\n paddingHorizontal: 18,\n borderRadius: 12,\n minHeight: 44,\n minWidth: 104,\n alignItems: 'center',\n justifyContent: 'center',\n },\n primaryText: { fontSize: 14, fontWeight: '700' },\n pressed: { opacity: 0.75 },\n note: { fontSize: 12, lineHeight: 16, marginTop: 6, textAlign: 'right' },\n});\n\nexport interface ConnectorConnectCardProps {\n name: string;\n reason: string;\n /** A website sign-in (key icon) rather than a catalog connector (plug icon). */\n siteLogin: boolean;\n /** A matching credential is already saved: badge it, and the action updates it. */\n connected: boolean;\n actionLabel: string;\n /** The browser session is open, or its result is being checked. */\n busy?: boolean;\n /**\n * What is saved is still being read: the primary action waits (spinner, not\n * tappable) so it never opens \"Save login\" for a login that exists. \"Not now\"\n * stays available.\n */\n actionPending?: boolean;\n /** One line under the actions, e.g. why nothing was sent after the browser closed. */\n note?: string | null;\n isDark?: boolean;\n onAction: () => void;\n onDismiss: () => void;\n}\n\nfunction ConnectorConnectCardView({\n name,\n reason,\n siteLogin,\n connected,\n actionLabel,\n busy = false,\n actionPending = false,\n note,\n isDark = false,\n onAction,\n onDismiss,\n}: ConnectorConnectCardProps) {\n const palette = useMemo(\n () => ({\n card: isDark ? '#111827' : '#ffffff',\n border: isDark ? '#1f2937' : '#e5e7eb',\n title: isDark ? '#f1f5f9' : '#111827',\n muted: isDark ? '#94a3b8' : '#6b7280',\n iconBg: isDark ? '#1e293b' : '#f3f4f6',\n badgeBg: isDark ? '#064e3b' : '#d1fae5',\n badgeText: isDark ? '#6ee7b7' : '#047857',\n outline: isDark ? '#334155' : '#d1d5db',\n }),\n [isDark],\n );\n const actionDisabled = busy || actionPending;\n\n return (\n <View style={[styles.card, { backgroundColor: palette.card, borderColor: palette.border }]}>\n <View style={styles.row}>\n <View style={[styles.icon, { backgroundColor: palette.iconBg }]}>\n <MaterialCommunityIcons\n name={siteLogin ? 'key-variant' : 'power-plug-outline'}\n size={18}\n color={palette.muted}\n />\n </View>\n <View style={styles.body}>\n <View style={styles.titleRow}>\n <Text style={[styles.title, { color: palette.title }]} numberOfLines={1}>\n {name}\n </Text>\n {connected ? (\n <View style={[styles.badge, { backgroundColor: palette.badgeBg }]}>\n <Text style={[styles.badgeText, { color: palette.badgeText }]}>Connected</Text>\n </View>\n ) : null}\n </View>\n <Text style={[styles.reason, { color: palette.muted }]}>{reason}</Text>\n </View>\n </View>\n\n <View style={styles.actions}>\n <Pressable\n accessibilityRole=\"button\"\n accessibilityState={{ disabled: busy }}\n onPress={onDismiss}\n disabled={busy}\n hitSlop={6}\n style={styles.secondary}\n >\n <Text style={[styles.secondaryText, { color: palette.muted }]}>Not now</Text>\n </Pressable>\n <Pressable\n accessibilityRole=\"button\"\n accessibilityLabel={`${actionLabel} ${name}`}\n accessibilityState={{ disabled: actionDisabled, busy: actionDisabled }}\n onPress={onAction}\n disabled={actionDisabled}\n style={({ pressed }) => [\n styles.primary,\n connected\n ? { backgroundColor: 'transparent', borderColor: palette.outline, borderWidth: 1 }\n : { backgroundColor: ACCENT },\n (pressed || actionDisabled) && styles.pressed,\n ]}\n >\n {actionDisabled ? (\n <ActivityIndicator size=\"small\" color={connected ? palette.title : '#ffffff'} />\n ) : (\n <Text style={[styles.primaryText, { color: connected ? palette.title : '#ffffff' }]}>\n {actionLabel}\n </Text>\n )}\n </Pressable>\n </View>\n {note ? <Text style={[styles.note, { color: palette.muted }]}>{note}</Text> : null}\n </View>\n );\n}\n\nexport const ConnectorConnectCard = memo(ConnectorConnectCardView);\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ConnectorConnectCard.js","sources":["../../../src/features/chat/ConnectorConnectCard.tsx"],"sourcesContent":["/**\n * <ConnectorConnectCard> - the `[CONNECTOR_CONNECT]` request as a touch card.\n *\n * Phone twin of the web ConnectorConnectCard: icon, name (+ \"Connected\" / \"Saved\"\n * when a matching credential is already saved), the agent's reason, then the\n * primary action (\"Save login\" / \"Add card\" / \"Connect\", or \"Update\" for a saved\n * one) and \"Not now\".\n * Presentational only: status, the browser session and the reply live in\n * ConnectorConnectPrompt.\n */\nimport React, { memo, useMemo } from 'react';\nimport { ActivityIndicator, Pressable, StyleSheet, Text, View } from 'react-native';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { a11yActionLabel } from './connectorConnect';\n\nconst ACCENT = '#2563eb';\n\nconst styles = StyleSheet.create({\n card: {\n width: '100%',\n borderWidth: 1,\n borderRadius: 16,\n padding: 14,\n marginTop: 4,\n marginBottom: 8,\n },\n row: { flexDirection: 'row', alignItems: 'flex-start', gap: 12 },\n icon: { width: 36, height: 36, borderRadius: 10, alignItems: 'center', justifyContent: 'center' },\n body: { flex: 1, minWidth: 0 },\n titleRow: { flexDirection: 'row', alignItems: 'center', gap: 8 },\n title: { flexShrink: 1, fontSize: 15, fontWeight: '700', lineHeight: 20 },\n badge: { borderRadius: 999, paddingHorizontal: 8, paddingVertical: 2 },\n badgeText: { fontSize: 11, fontWeight: '700' },\n reason: { fontSize: 13, lineHeight: 18, marginTop: 2 },\n actions: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'flex-end',\n marginTop: 12,\n gap: 4,\n },\n secondary: { paddingHorizontal: 12, minHeight: 44, justifyContent: 'center' },\n secondaryText: { fontSize: 13, fontWeight: '600' },\n primary: {\n paddingHorizontal: 18,\n borderRadius: 12,\n minHeight: 44,\n minWidth: 104,\n alignItems: 'center',\n justifyContent: 'center',\n },\n primaryText: { fontSize: 14, fontWeight: '700' },\n pressed: { opacity: 0.75 },\n note: { fontSize: 12, lineHeight: 16, marginTop: 6, textAlign: 'right' },\n});\n\nexport interface ConnectorConnectCardProps {\n name: string;\n reason: string;\n /**\n * MaterialCommunityIcons name: the vault form kind's own (common's VAULT_FORM_KINDS mobileIcon - a key for a\n * login, a card for a payment card), or a plug for a catalog connector.\n */\n icon: string;\n /** A matching credential is already saved: badge it, and the action updates it. */\n connected: boolean;\n /** The badge a connected card shows. Defaults to \"Connected\"; a saved card or address says \"Saved\". */\n connectedLabel?: string;\n actionLabel: string;\n /** The browser session is open, or its result is being checked. */\n busy?: boolean;\n /**\n * What is saved is still being read: the primary action waits (spinner, not\n * tappable) so it never opens \"Save login\" for a login that exists. \"Not now\"\n * stays available.\n */\n actionPending?: boolean;\n /** One line under the actions, e.g. why nothing was sent after the browser closed. */\n note?: string | null;\n isDark?: boolean;\n onAction: () => void;\n onDismiss: () => void;\n}\n\nfunction ConnectorConnectCardView({\n name,\n reason,\n icon,\n connected,\n connectedLabel = 'Connected',\n actionLabel,\n busy = false,\n actionPending = false,\n note,\n isDark = false,\n onAction,\n onDismiss,\n}: ConnectorConnectCardProps) {\n const palette = useMemo(\n () => ({\n card: isDark ? '#111827' : '#ffffff',\n border: isDark ? '#1f2937' : '#e5e7eb',\n title: isDark ? '#f1f5f9' : '#111827',\n muted: isDark ? '#94a3b8' : '#6b7280',\n iconBg: isDark ? '#1e293b' : '#f3f4f6',\n badgeBg: isDark ? '#064e3b' : '#d1fae5',\n badgeText: isDark ? '#6ee7b7' : '#047857',\n outline: isDark ? '#334155' : '#d1d5db',\n }),\n [isDark],\n );\n const actionDisabled = busy || actionPending;\n // Say the card once: \"Add card\", not \"Add card Your card\" for an untitled autofill card; \"Save login Amazon login\"\n // keeps the site a login is for.\n const actionA11yLabel = a11yActionLabel(actionLabel, name);\n\n return (\n <View style={[styles.card, { backgroundColor: palette.card, borderColor: palette.border }]}>\n <View style={styles.row}>\n <View style={[styles.icon, { backgroundColor: palette.iconBg }]}>\n <MaterialCommunityIcons\n name={icon as React.ComponentProps<typeof MaterialCommunityIcons>['name']}\n size={18}\n color={palette.muted}\n />\n </View>\n <View style={styles.body}>\n <View style={styles.titleRow}>\n <Text style={[styles.title, { color: palette.title }]} numberOfLines={1}>\n {name}\n </Text>\n {connected ? (\n <View style={[styles.badge, { backgroundColor: palette.badgeBg }]}>\n <Text style={[styles.badgeText, { color: palette.badgeText }]}>{connectedLabel}</Text>\n </View>\n ) : null}\n </View>\n <Text style={[styles.reason, { color: palette.muted }]}>{reason}</Text>\n </View>\n </View>\n\n <View style={styles.actions}>\n <Pressable\n accessibilityRole=\"button\"\n accessibilityState={{ disabled: busy }}\n onPress={onDismiss}\n disabled={busy}\n hitSlop={6}\n style={styles.secondary}\n >\n <Text style={[styles.secondaryText, { color: palette.muted }]}>Not now</Text>\n </Pressable>\n <Pressable\n accessibilityRole=\"button\"\n accessibilityLabel={actionA11yLabel}\n accessibilityState={{ disabled: actionDisabled, busy: actionDisabled }}\n onPress={onAction}\n disabled={actionDisabled}\n style={({ pressed }) => [\n styles.primary,\n connected\n ? { backgroundColor: 'transparent', borderColor: palette.outline, borderWidth: 1 }\n : { backgroundColor: ACCENT },\n (pressed || actionDisabled) && styles.pressed,\n ]}\n >\n {actionDisabled ? (\n <ActivityIndicator size=\"small\" color={connected ? palette.title : '#ffffff'} />\n ) : (\n <Text style={[styles.primaryText, { color: connected ? palette.title : '#ffffff' }]}>\n {actionLabel}\n </Text>\n )}\n </Pressable>\n </View>\n {note ? <Text style={[styles.note, { color: palette.muted }]}>{note}</Text> : null}\n </View>\n );\n}\n\nexport const ConnectorConnectCard = memo(ConnectorConnectCardView);\n"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import {jsx}from'react/jsx-runtime';import {useMemo,useState,useCallback,useRef,useEffect}from'react';import {View}from'react-native';import*as WebBrowser from'expo-web-browser';import {buildConnectorReply,isSiteLoginRequest,connectorCredentialsVariables,credentialsOfOrg,CONNECTOR_CONNECT_APP_RETURN_URL,parseConnectorConnectAppReturnUrl}from'common';import {useFormBuilderCredentialsQuery}from'common/graphql';import {config}from'../../config/env-config.js';import {resolveMobileWebUrl,getPackagerHost}from'../../bridge/resolveMobileWebUrl.js';import {usePrerequisiteIds}from'../../hooks/usePrerequisiteIds.js';import {ConnectorConnectCard}from'./ConnectorConnectCard.js';import {pendingConnectorConnect,connectorConnectKey,connectorConnectName,pickConnectorConnectCredential,decideConnectorConnectOutcome,snapshotConnectorCredentials,buildConnectorConnectUrl,parkedHandbackCredential,connectorConnectActionLabel,connectorConnectReason}from'./connectorConnect.js';import {beginConnectorConnectSession,endConnectorConnectSession,peekConnectorConnectHandback,takeConnectorConnectHandback,subscribeConnectorConnectHandbacks}from'./connectorConnectHandbacks.js';var __defProp = Object.defineProperty;
1
+ import {jsx}from'react/jsx-runtime';import {useMemo,useState,useCallback,useRef,useEffect}from'react';import {View}from'react-native';import*as WebBrowser from'expo-web-browser';import {buildConnectorReply,vaultKindOf,connectorCredentialsVariables,credentialsOfOrg,CONNECTOR_CONNECT_APP_RETURN_URL,parseConnectorConnectAppReturnUrl}from'common';import {useFormBuilderCredentialsQuery}from'common/graphql';import {config}from'../../config/env-config.js';import {resolveMobileWebUrl,getPackagerHost}from'../../bridge/resolveMobileWebUrl.js';import {usePrerequisiteIds}from'../../hooks/usePrerequisiteIds.js';import {ConnectorConnectCard}from'./ConnectorConnectCard.js';import {pendingConnectorConnect,connectorConnectKey,pickConnectorConnectCredential,connectorConnectName,decideConnectorConnectOutcome,snapshotConnectorCredentials,buildConnectorConnectUrl,parkedHandbackCredential,connectorConnectActionLabel,connectorConnectReason}from'./connectorConnect.js';import {beginConnectorConnectSession,endConnectorConnectSession,peekConnectorConnectHandback,takeConnectorConnectHandback,subscribeConnectorConnectHandbacks}from'./connectorConnectHandbacks.js';var __defProp = Object.defineProperty;
2
2
  var __defProps = Object.defineProperties;
3
3
  var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
4
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
@@ -26,14 +26,13 @@ function ConnectorConnectPrompt({
26
26
  isDark = false,
27
27
  onResolve
28
28
  }) {
29
- var _a;
29
+ var _a, _b;
30
30
  const {
31
31
  orgName,
32
32
  projectId,
33
33
  loading: idsLoading
34
34
  } = usePrerequisiteIds();
35
- const siteLogin = isSiteLoginRequest(payload);
36
- const name = connectorConnectName(payload);
35
+ const vaultKind = vaultKindOf(payload.connector);
37
36
  const variables = useMemo(() => orgName ? connectorCredentialsVariables(orgName) : null, [orgName]);
38
37
  const {
39
38
  data,
@@ -56,6 +55,7 @@ function ConnectorConnectPrompt({
56
55
  return status === "ready" && cachedRows ? (_a2 = pickConnectorConnectCredential(cachedRows, payload)) != null ? _a2 : null : null;
57
56
  }, [status, cachedRows, payload]);
58
57
  const connected = Boolean(existing);
58
+ const name = connectorConnectName(payload, connected);
59
59
  const [busy, setBusy] = useState(false);
60
60
  const [note, setNote] = useState(null);
61
61
  const [unsent, setUnsent] = useState(null);
@@ -65,13 +65,13 @@ function ConnectorConnectPrompt({
65
65
  mountedRef.current = false;
66
66
  }, []);
67
67
  const readVault = useCallback(async () => {
68
- var _a2, _b;
68
+ var _a2, _b2;
69
69
  if (!variables) return {
70
70
  ok: false
71
71
  };
72
72
  try {
73
73
  const result = await refetch(variables);
74
- const rows = (_b = (_a2 = result.data) == null ? void 0 : _a2.formBuilderCredentials) == null ? void 0 : _b.data;
74
+ const rows = (_b2 = (_a2 = result.data) == null ? void 0 : _a2.formBuilderCredentials) == null ? void 0 : _b2.data;
75
75
  if (result.error || !Array.isArray(rows)) return {
76
76
  ok: false
77
77
  };
@@ -114,7 +114,8 @@ function ConnectorConnectPrompt({
114
114
  after: after.ok ? {
115
115
  rows: after.rows,
116
116
  match: (_a2 = pickConnectorConnectCredential(after.rows, payload)) != null ? _a2 : null
117
- } : null
117
+ } : null,
118
+ kind: vaultKind == null ? void 0 : vaultKind.id
118
119
  });
119
120
  if (decision.kind === "connected") {
120
121
  if (mountedRef.current) setUnverified(null);
@@ -128,10 +129,11 @@ function ConnectorConnectPrompt({
128
129
  }
129
130
  if (mountedRef.current) setUnverified(null);
130
131
  if (wasConnected) settle("No changes were saved.");
131
- else settle(siteLogin ? "The login was not saved." : `${name} is not connected yet.`);
132
- }, [readVault, payload, replyConnected, settle, siteLogin, name]);
132
+ else if (vaultKind) settle(`The ${vaultKind.noun} was not saved.`);
133
+ else settle(`${name} is not connected yet.`);
134
+ }, [readVault, payload, replyConnected, settle, vaultKind, name]);
133
135
  const handleAction = useCallback(async () => {
134
- var _a2, _b;
136
+ var _a2, _b2;
135
137
  if (busy) return;
136
138
  setBusy(true);
137
139
  setNote(null);
@@ -159,11 +161,11 @@ function ConnectorConnectPrompt({
159
161
  origin: resolveMobileWebUrl(config.CLIENT_URL, getPackagerHost()),
160
162
  payload,
161
163
  name,
162
- // A saved login: open the vault form ON it so the edit (email, username or password) lands on it
163
- // instead of on a new duplicate, in the project it lives in (the form refuses a login from another).
164
- // A catalog connector's page makes this pick itself, with the template's formId.
165
- credentialId: siteLogin ? current == null ? void 0 : current.id : void 0,
166
- projectId: siteLogin ? ((_b = current == null ? void 0 : current.project) == null ? void 0 : _b.projectId) || projectId : void 0
164
+ // A saved login or entry: open the vault form ON it so the edit (email, username or password, a card's
165
+ // expiry) lands on it instead of on a new duplicate, in the project it lives in (the form refuses an entry
166
+ // from another). A catalog connector's page makes this pick itself, with the template's formId.
167
+ credentialId: vaultKind ? current == null ? void 0 : current.id : void 0,
168
+ projectId: vaultKind ? ((_b2 = current == null ? void 0 : current.project) == null ? void 0 : _b2.projectId) || projectId : void 0
167
169
  });
168
170
  let result;
169
171
  beginConnectorConnectSession(payload.requestId);
@@ -177,7 +179,7 @@ function ConnectorConnectPrompt({
177
179
  }
178
180
  const handback = result.type === "success" ? parseConnectorConnectAppReturnUrl(result.url) : null;
179
181
  await conclude(before, handback, Boolean(current));
180
- }, [busy, unsent, unverified, status, readVault, payload, name, siteLogin, projectId, conclude, replyConnected, settle]);
182
+ }, [busy, unsent, unverified, status, readVault, payload, name, vaultKind, projectId, conclude, replyConnected, settle]);
181
183
  const adoptingRef = useRef(false);
182
184
  const adoptParkedHandback = useCallback(async () => {
183
185
  if (busy || unsent || !variables || adoptingRef.current) return;
@@ -229,7 +231,23 @@ function ConnectorConnectPrompt({
229
231
  else if (unverified) actionLabel = "Check";
230
232
  else if (status === "failed") actionLabel = "Try again";
231
233
  const statusNote = status === "failed" && !unsent && !unverified ? STATUS_FAILED_NOTE : null;
232
- return /* @__PURE__ */ jsx(ConnectorConnectCard, { name, reason: connectorConnectReason(payload, name), siteLogin, connected, actionLabel, busy, actionPending: !busy && !unsent && !unverified && status === "checking", note: note != null ? note : statusNote, isDark, onAction: onActionPress, onDismiss: onDismissPress });
234
+ return /* @__PURE__ */ jsx(
235
+ ConnectorConnectCard,
236
+ {
237
+ name,
238
+ reason: connectorConnectReason(payload, name, connected),
239
+ icon: (_b = vaultKind == null ? void 0 : vaultKind.mobileIcon) != null ? _b : "power-plug-outline",
240
+ connected,
241
+ connectedLabel: (vaultKind == null ? void 0 : vaultKind.autofill) ? "Saved" : void 0,
242
+ actionLabel,
243
+ busy,
244
+ actionPending: !busy && !unsent && !unverified && status === "checking",
245
+ note: note != null ? note : statusNote,
246
+ isDark,
247
+ onAction: onActionPress,
248
+ onDismiss: onDismissPress
249
+ }
250
+ );
233
251
  }
234
252
  function PendingConnectorConnectCard({
235
253
  messages,
@@ -1 +1 @@
1
- {"version":3,"file":"ConnectorConnectPrompt.js","sources":["../../../src/features/chat/ConnectorConnectPrompt.tsx"],"sourcesContent":["/**\n * <ConnectorConnectPrompt> - owns one `[CONNECTOR_CONNECT]` card: whether the\n * connection is already saved, the web page the action opens, and the reply.\n *\n * The phone cannot host the web's inline vault / connector forms, so the action\n * opens the web page in an in-app browser session (expo-web-browser's auth\n * session, which shares the system browser's sign-in with the web app). A site\n * login's page hands the saved credential back through the app's scheme URL (see\n * common's CONNECTOR_CONNECT_APP_RETURN_URL); any other connector's page has no\n * way back, so once the browser closes the card re-reads the vault and only a\n * credential the session created or updated counts. Only then does it reply\n * `[CONNECTOR_CONNECTED:<requestId>:<credentialId>]` - never on a closed browser.\n *\n * The action never runs on a guess about what is saved. It stays disabled until\n * the status read has come back from the server, and at the tap the vault is read\n * once more: the form opens ON the saved login (\"Update\", so an email / username\n * or password edit lands on it) or, only when the server says there is none, as a\n * new one. A read that fails opens nothing - offering \"Save login\" then would save\n * a duplicate next to the login the user meant to edit.\n *\n * Status is the same query (the org's credentials, most recently updated first)\n * and the same match (common's matchConnectorCredentials) the web card uses, so a\n * site login's \"Update\" edits the login the web would edit - and the agent signs in\n * with: the one the agent named when it is the org's and fits, else the most\n * recently updated login for the site. It is edited in the project it lives in. A\n * catalog connector's page is the web card itself, which picks with the template's\n * formId the phone cannot resolve; the phone sends it only the agent's credentialId.\n *\n * Host-only (Apollo, redux, expo-web-browser): a surface remote gets this card as\n * a render prop from its host screen (useHostConnectorCard), never by import.\n */\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { View, type StyleProp, type ViewStyle } from 'react-native';\nimport * as WebBrowser from 'expo-web-browser';\nimport {\n buildConnectorReply,\n CONNECTOR_CONNECT_APP_RETURN_URL,\n connectorCredentialsVariables,\n credentialsOfOrg,\n isSiteLoginRequest,\n parseConnectorConnectAppReturnUrl,\n type ConnectorConnectHandback,\n type ConnectorConnectOutcome,\n type ConnectorConnectPayload,\n} from 'common';\nimport { useFormBuilderCredentialsQuery } from 'common/graphql';\nimport { config } from '../../config/env-config';\nimport { getPackagerHost, resolveMobileWebUrl } from '../../bridge/resolveMobileWebUrl';\nimport { usePrerequisiteIds } from '../../hooks/usePrerequisiteIds';\nimport { ConnectorConnectCard } from './ConnectorConnectCard';\nimport {\n buildConnectorConnectUrl,\n connectorConnectActionLabel,\n connectorConnectKey,\n connectorConnectName,\n connectorConnectReason,\n decideConnectorConnectOutcome,\n parkedHandbackCredential,\n pendingConnectorConnect,\n pickConnectorConnectCredential,\n snapshotConnectorCredentials,\n type ConnectorConnectBefore,\n type CredentialVersionRow,\n} from './connectorConnect';\nimport {\n beginConnectorConnectSession,\n endConnectorConnectSession,\n peekConnectorConnectHandback,\n subscribeConnectorConnectHandbacks,\n takeConnectorConnectHandback,\n} from './connectorConnectHandbacks';\n\n/** The vault as one read returned it; `ok: false` when the read failed. */\ntype VaultRead = { ok: true; rows: CredentialVersionRow[] } | { ok: false };\n\n/** Where the status read stands: the action waits for `ready`. */\ntype StatusState = 'checking' | 'ready' | 'failed';\n\nconst STATUS_FAILED_NOTE = 'Could not check your saved logins. Tap Try again.';\nconst READ_FAILED_NOTE = 'Could not reach your vault. Try again.';\nconst VERIFY_FAILED_NOTE = 'Could not check whether it saved. Tap Check to look again.';\nconst SEND_FAILED_NOTE = 'Could not reach the chat. Try again.';\n\nexport function ConnectorConnectPrompt({\n payload,\n isDark = false,\n onResolve,\n}: {\n payload: ConnectorConnectPayload;\n isDark?: boolean;\n /** Send the reply for this request; resolves false when it could not go out. */\n onResolve: (outcome: ConnectorConnectOutcome, credentialId?: string) => Promise<boolean>;\n}) {\n const { orgName, projectId, loading: idsLoading } = usePrerequisiteIds();\n const siteLogin = isSiteLoginRequest(payload);\n const name = connectorConnectName(payload);\n\n // Same query and variables as the web card's useConnectorCredentialMatch (common's\n // connectorCredentialsVariables: the whole org, most recently updated first), so the\n // Apollo cache and the pick agree across the two.\n const variables = useMemo(() => (orgName ? connectorCredentialsVariables(orgName) : null), [orgName]);\n const { data, loading, error, refetch } = useFormBuilderCredentialsQuery({\n variables: variables ?? undefined,\n skip: !variables,\n fetchPolicy: 'cache-and-network',\n });\n // Only this org's rows (credentialsOfOrg): the server deployed today can answer with the caller's rows of\n // every org, and another org's same-named login must never be the one this card edits.\n const listed = data?.formBuilderCredentials?.data as ReadonlyArray<CredentialVersionRow | null> | undefined;\n const cachedRows = useMemo(() => (listed ? credentialsOfOrg(listed, orgName) : undefined), [listed, orgName]);\n\n // `cache-and-network` paints a cached answer first and keeps `loading` until the\n // server answers; a cached \"not saved\" can be stale, so only the server's\n // answer makes the action live.\n let status: StatusState = 'ready';\n if (!variables) status = idsLoading ? 'checking' : 'failed';\n else if (error) status = 'failed';\n else if (loading || !cachedRows) status = 'checking';\n\n const existing = useMemo(\n () => (status === 'ready' && cachedRows ? (pickConnectorConnectCredential(cachedRows, payload) ?? null) : null),\n [status, cachedRows, payload],\n );\n const connected = Boolean(existing);\n\n const [busy, setBusy] = useState(false);\n const [note, setNote] = useState<string | null>(null);\n // The vault changed but the reply did not go out: the next tap resends the\n // reply instead of reopening the browser.\n const [unsent, setUnsent] = useState<{ credentialId?: string } | null>(null);\n // The browser closed but the vault could not be re-read: the next tap checks\n // again against the same \"before\", instead of reopening the browser.\n const [unverified, setUnverified] = useState<ConnectorConnectBefore | null>(null);\n const mountedRef = useRef(true);\n useEffect(\n () => () => {\n mountedRef.current = false;\n },\n [],\n );\n\n /** The vault as the server has it now (not the cache). */\n const readVault = useCallback(async (): Promise<VaultRead> => {\n if (!variables) return { ok: false };\n try {\n const result = await refetch(variables);\n const rows = result.data?.formBuilderCredentials?.data;\n if (result.error || !Array.isArray(rows)) return { ok: false };\n return { ok: true, rows: credentialsOfOrg(rows as ReadonlyArray<CredentialVersionRow | null>, orgName) };\n } catch {\n return { ok: false };\n }\n }, [variables, refetch, orgName]);\n\n /** Send the reply; a send that throws counts as not sent, so the card stays. */\n const sendReply = useCallback(\n async (outcome: ConnectorConnectOutcome, credentialId?: string): Promise<boolean> => {\n try {\n return await onResolve(outcome, credentialId);\n } catch {\n return false;\n }\n },\n [onResolve],\n );\n\n /** Reply `connected`; on failure keep the result so the next tap only resends. */\n const replyConnected = useCallback(\n async (credentialId: string | undefined): Promise<string | null> => {\n if (await sendReply('connected', credentialId)) return null;\n if (mountedRef.current) setUnsent({ credentialId });\n return 'Saved, but the chat did not get it. Tap Send to try again.';\n },\n [sendReply],\n );\n\n /** Leave the busy state with `text` under the actions (null clears it). */\n const settle = useCallback((text: string | null) => {\n if (!mountedRef.current) return;\n setNote(text);\n setBusy(false);\n }, []);\n\n /** Decide from a hand-back and a fresh read against `before`, then reply or say why not. */\n const conclude = useCallback(\n async (\n before: ConnectorConnectBefore,\n handback: ConnectorConnectHandback | null,\n wasConnected: boolean,\n ): Promise<void> => {\n const after = await readVault();\n const decision = decideConnectorConnectOutcome({\n requestId: payload.requestId,\n handback,\n before,\n after: after.ok\n ? { rows: after.rows, match: pickConnectorConnectCredential(after.rows, payload) ?? null }\n : null,\n });\n if (decision.kind === 'connected') {\n if (mountedRef.current) setUnverified(null);\n settle(await replyConnected(decision.credentialId));\n return;\n }\n if (!after.ok) {\n if (mountedRef.current) setUnverified(before);\n settle(VERIFY_FAILED_NOTE);\n return;\n }\n if (mountedRef.current) setUnverified(null);\n if (wasConnected) settle('No changes were saved.');\n else settle(siteLogin ? 'The login was not saved.' : `${name} is not connected yet.`);\n },\n [readVault, payload, replyConnected, settle, siteLogin, name],\n );\n\n const handleAction = useCallback(async () => {\n if (busy) return;\n setBusy(true);\n setNote(null);\n if (unsent) {\n setUnsent(null);\n settle(await replyConnected(unsent.credentialId));\n return;\n }\n if (unverified) {\n await conclude(unverified, null, Boolean(unverified.targetId));\n return;\n }\n if (status === 'failed') {\n // \"Try again\": re-read the status; the action goes live once it answers.\n settle((await readVault()).ok ? null : STATUS_FAILED_NOTE);\n return;\n }\n // Read the vault as it is NOW: the form opens on the credential the server\n // has, and the same read is the \"before\" the result is measured against.\n const now = await readVault();\n if (!now.ok) {\n settle(READ_FAILED_NOTE);\n return;\n }\n const current = pickConnectorConnectCredential(now.rows, payload) ?? null;\n const before = snapshotConnectorCredentials(now.rows, current?.id);\n const url = buildConnectorConnectUrl({\n origin: resolveMobileWebUrl(config.CLIENT_URL, getPackagerHost()),\n payload,\n name,\n // A saved login: open the vault form ON it so the edit (email, username or password) lands on it\n // instead of on a new duplicate, in the project it lives in (the form refuses a login from another).\n // A catalog connector's page makes this pick itself, with the template's formId.\n credentialId: siteLogin ? current?.id : undefined,\n projectId: siteLogin ? current?.project?.projectId || projectId : undefined,\n });\n let result: WebBrowser.WebBrowserAuthSessionResult;\n beginConnectorConnectSession(payload.requestId);\n try {\n result = await WebBrowser.openAuthSessionAsync(url, CONNECTOR_CONNECT_APP_RETURN_URL);\n } catch {\n settle('Could not open the page. Try again.');\n return;\n } finally {\n endConnectorConnectSession(payload.requestId);\n }\n const handback = result.type === 'success' ? parseConnectorConnectAppReturnUrl(result.url) : null;\n await conclude(before, handback, Boolean(current));\n }, [\n busy,\n unsent,\n unverified,\n status,\n readVault,\n payload,\n name,\n siteLogin,\n projectId,\n conclude,\n replyConnected,\n settle,\n ]);\n\n /**\n * A hand-back that reached the app while no browser session of this card was\n * waiting for it: Android can kill the app behind Custom Tabs, and the return\n * page then cold-starts it with the scheme URL. Anyone can open that URL, so\n * the credential it names is only taken once a fresh read shows it is one this\n * request could have saved, saved just now (parkedHandbackCredential).\n *\n * On a cold start the card mounts before the org is known and cannot read the\n * vault yet, so the hand-back stays parked until a read answers: it is looked\n * at again whenever the status read settles.\n */\n const adoptingRef = useRef(false);\n const adoptParkedHandback = useCallback(async () => {\n if (busy || unsent || !variables || adoptingRef.current) return;\n const handback = peekConnectorConnectHandback(payload.requestId);\n if (!handback?.credentialId) return;\n adoptingRef.current = true;\n try {\n setBusy(true);\n setNote(null);\n const now = await readVault();\n if (!now.ok) {\n // Left parked: the next settled status read tries again.\n settle(null);\n return;\n }\n takeConnectorConnectHandback(payload.requestId);\n if (!parkedHandbackCredential(now.rows, payload, handback.credentialId, Date.now())) {\n settle(null);\n return;\n }\n settle(await replyConnected(handback.credentialId));\n } finally {\n adoptingRef.current = false;\n }\n }, [busy, unsent, variables, payload, readVault, replyConnected, settle]);\n\n const adoptRef = useRef(adoptParkedHandback);\n useEffect(() => {\n adoptRef.current = adoptParkedHandback;\n }, [adoptParkedHandback]);\n useEffect(\n () =>\n subscribeConnectorConnectHandbacks(() => {\n adoptRef.current().catch(() => undefined);\n }),\n [],\n );\n useEffect(() => {\n if (status === 'checking') return;\n adoptRef.current().catch(() => undefined);\n }, [status]);\n\n const handleDismiss = useCallback(async () => {\n if (busy) return;\n setBusy(true);\n settle((await sendReply('declined')) ? null : SEND_FAILED_NOTE);\n }, [busy, sendReply, settle]);\n\n const onActionPress = useCallback(() => {\n handleAction().catch(() => settle(READ_FAILED_NOTE));\n }, [handleAction, settle]);\n const onDismissPress = useCallback(() => {\n handleDismiss().catch(() => settle(SEND_FAILED_NOTE));\n }, [handleDismiss, settle]);\n\n let actionLabel = connectorConnectActionLabel(payload, connected);\n if (unsent) actionLabel = 'Send';\n else if (unverified) actionLabel = 'Check';\n else if (status === 'failed') actionLabel = 'Try again';\n const statusNote = status === 'failed' && !unsent && !unverified ? STATUS_FAILED_NOTE : null;\n\n return (\n <ConnectorConnectCard\n name={name}\n reason={connectorConnectReason(payload, name)}\n siteLogin={siteLogin}\n connected={connected}\n actionLabel={actionLabel}\n busy={busy}\n actionPending={!busy && !unsent && !unverified && status === 'checking'}\n note={note ?? statusNote}\n isDark={isDark}\n onAction={onActionPress}\n onDismiss={onDismissPress}\n />\n );\n}\n\n/**\n * The card for the connect request still waiting in `messages`, if any - the\n * one piece both chat screens (the main chat, and the host screens of the native\n * surface chats) render above their composer.\n *\n * The reply goes out through the screen's ordinary send path, as an ASK_USER\n * answer does, and lands in the thread as a user message; that message is what\n * settles the request, so a reloaded thread does not bring the card back\n * (pendingConnectorConnect). The local mark only bridges the moment between the\n * send and the reply showing up, and is keyed on the message as well as the\n * request id, so the same id-less marker in a later turn still gets its card.\n */\nexport function PendingConnectorConnectCard({\n messages,\n send,\n isDark = false,\n style,\n}: {\n /** The raw thread, outbox rows included - a queued reply settles its request too. */\n messages: ReadonlyArray<{ role: string; content: string }>;\n /** Send `text` as the user's next message; resolves false when it could not go out. */\n send: (text: string) => Promise<boolean>;\n isDark?: boolean;\n style?: StyleProp<ViewStyle>;\n}) {\n const pending = useMemo(() => pendingConnectorConnect(messages), [messages]);\n const key = pending ? connectorConnectKey(pending) : null;\n const [resolved, setResolved] = useState<Record<string, boolean>>({});\n\n const handleResolve = useCallback(\n async (outcome: ConnectorConnectOutcome, credentialId?: string): Promise<boolean> => {\n if (!pending || !key) return false;\n const sent = await send(buildConnectorReply(pending.payload.requestId, outcome, credentialId));\n if (!sent) return false;\n setResolved((prev) => ({ ...prev, [key]: true }));\n return true;\n },\n [pending, key, send],\n );\n\n if (!pending || !key || resolved[key]) return null;\n return (\n <View style={style}>\n <ConnectorConnectPrompt key={key} payload={pending.payload} isDark={isDark} onResolve={handleResolve} />\n </View>\n );\n}\n"],"names":["_a"],"mappings":"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"}
1
+ {"version":3,"file":"ConnectorConnectPrompt.js","sources":["../../../src/features/chat/ConnectorConnectPrompt.tsx"],"sourcesContent":["/**\n * <ConnectorConnectPrompt> - owns one `[CONNECTOR_CONNECT]` card: whether the\n * connection is already saved, the web page the action opens, and the reply.\n *\n * The phone cannot host the web's inline vault / connector forms, so the action\n * opens the web page in an in-app browser session (expo-web-browser's auth\n * session, which shares the system browser's sign-in with the web app). The vault\n * form's page (a login, a card, an address) hands the saved credential back\n * through the app's scheme URL (see common's CONNECTOR_CONNECT_APP_RETURN_URL);\n * any other connector's page has no way back, so once the browser closes the card\n * re-reads the vault and only a credential the session created or updated counts.\n * Only then does it reply `[CONNECTOR_CONNECTED:<requestId>:<credentialId>]` -\n * never on a closed browser.\n *\n * The action never runs on a guess about what is saved. It stays disabled until\n * the status read has come back from the server, and at the tap the vault is read\n * once more: the form opens ON the saved login (\"Update\", so an email / username\n * or password edit lands on it) or, only when the server says there is none, as a\n * new one. A read that fails opens nothing - offering \"Save login\" then would save\n * a duplicate next to the login the user meant to edit.\n *\n * Status is the same query (the org's credentials, most recently updated first)\n * and the same match (common's matchConnectorCredentials) the web card uses, so a\n * site login's \"Update\" edits the login the web would edit - and the agent signs in\n * with: the one the agent named when it is the org's and fits, else the most\n * recently updated login for the site. An autofill entry's \"Update\" is only ever\n * the entry the agent named; without one the card adds a new entry. Either is\n * edited in the project it lives in. A catalog connector's page is the web card\n * itself, which picks with the template's formId the phone cannot resolve; the\n * phone sends it only the agent's credentialId.\n *\n * Host-only (Apollo, redux, expo-web-browser): a surface remote gets this card as\n * a render prop from its host screen (useHostConnectorCard), never by import.\n */\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { View, type StyleProp, type ViewStyle } from 'react-native';\nimport * as WebBrowser from 'expo-web-browser';\nimport {\n buildConnectorReply,\n CONNECTOR_CONNECT_APP_RETURN_URL,\n connectorCredentialsVariables,\n credentialsOfOrg,\n parseConnectorConnectAppReturnUrl,\n vaultKindOf,\n type ConnectorConnectHandback,\n type ConnectorConnectOutcome,\n type ConnectorConnectPayload,\n} from 'common';\nimport { useFormBuilderCredentialsQuery } from 'common/graphql';\nimport { config } from '../../config/env-config';\nimport { getPackagerHost, resolveMobileWebUrl } from '../../bridge/resolveMobileWebUrl';\nimport { usePrerequisiteIds } from '../../hooks/usePrerequisiteIds';\nimport { ConnectorConnectCard } from './ConnectorConnectCard';\nimport {\n buildConnectorConnectUrl,\n connectorConnectActionLabel,\n connectorConnectKey,\n connectorConnectName,\n connectorConnectReason,\n decideConnectorConnectOutcome,\n parkedHandbackCredential,\n pendingConnectorConnect,\n pickConnectorConnectCredential,\n snapshotConnectorCredentials,\n type ConnectorConnectBefore,\n type CredentialVersionRow,\n} from './connectorConnect';\nimport {\n beginConnectorConnectSession,\n endConnectorConnectSession,\n peekConnectorConnectHandback,\n subscribeConnectorConnectHandbacks,\n takeConnectorConnectHandback,\n} from './connectorConnectHandbacks';\n\n/** The vault as one read returned it; `ok: false` when the read failed. */\ntype VaultRead = { ok: true; rows: CredentialVersionRow[] } | { ok: false };\n\n/** Where the status read stands: the action waits for `ready`. */\ntype StatusState = 'checking' | 'ready' | 'failed';\n\nconst STATUS_FAILED_NOTE = 'Could not check your saved logins. Tap Try again.';\nconst READ_FAILED_NOTE = 'Could not reach your vault. Try again.';\nconst VERIFY_FAILED_NOTE = 'Could not check whether it saved. Tap Check to look again.';\nconst SEND_FAILED_NOTE = 'Could not reach the chat. Try again.';\n\nexport function ConnectorConnectPrompt({\n payload,\n isDark = false,\n onResolve,\n}: {\n payload: ConnectorConnectPayload;\n isDark?: boolean;\n /** Send the reply for this request; resolves false when it could not go out. */\n onResolve: (outcome: ConnectorConnectOutcome, credentialId?: string) => Promise<boolean>;\n}) {\n const { orgName, projectId, loading: idsLoading } = usePrerequisiteIds();\n // A website login or an autofill entry (a card, an address): the web vault form for that kind.\n const vaultKind = vaultKindOf(payload.connector);\n\n // Same query and variables as the web card's useConnectorCredentialMatch (common's\n // connectorCredentialsVariables: the whole org, most recently updated first), so the\n // Apollo cache and the pick agree across the two.\n const variables = useMemo(() => (orgName ? connectorCredentialsVariables(orgName) : null), [orgName]);\n const { data, loading, error, refetch } = useFormBuilderCredentialsQuery({\n variables: variables ?? undefined,\n skip: !variables,\n fetchPolicy: 'cache-and-network',\n });\n // Only this org's rows (credentialsOfOrg): the server deployed today can answer with the caller's rows of\n // every org, and another org's same-named login must never be the one this card edits.\n const listed = data?.formBuilderCredentials?.data as ReadonlyArray<CredentialVersionRow | null> | undefined;\n const cachedRows = useMemo(() => (listed ? credentialsOfOrg(listed, orgName) : undefined), [listed, orgName]);\n\n // `cache-and-network` paints a cached answer first and keeps `loading` until the\n // server answers; a cached \"not saved\" can be stale, so only the server's\n // answer makes the action live.\n let status: StatusState = 'ready';\n if (!variables) status = idsLoading ? 'checking' : 'failed';\n else if (error) status = 'failed';\n else if (loading || !cachedRows) status = 'checking';\n\n const existing = useMemo(\n () => (status === 'ready' && cachedRows ? (pickConnectorConnectCredential(cachedRows, payload) ?? null) : null),\n [status, cachedRows, payload],\n );\n const connected = Boolean(existing);\n const name = connectorConnectName(payload, connected);\n\n const [busy, setBusy] = useState(false);\n const [note, setNote] = useState<string | null>(null);\n // The vault changed but the reply did not go out: the next tap resends the\n // reply instead of reopening the browser.\n const [unsent, setUnsent] = useState<{ credentialId?: string } | null>(null);\n // The browser closed but the vault could not be re-read: the next tap checks\n // again against the same \"before\", instead of reopening the browser.\n const [unverified, setUnverified] = useState<ConnectorConnectBefore | null>(null);\n const mountedRef = useRef(true);\n useEffect(\n () => () => {\n mountedRef.current = false;\n },\n [],\n );\n\n /** The vault as the server has it now (not the cache). */\n const readVault = useCallback(async (): Promise<VaultRead> => {\n if (!variables) return { ok: false };\n try {\n const result = await refetch(variables);\n const rows = result.data?.formBuilderCredentials?.data;\n if (result.error || !Array.isArray(rows)) return { ok: false };\n return { ok: true, rows: credentialsOfOrg(rows as ReadonlyArray<CredentialVersionRow | null>, orgName) };\n } catch {\n return { ok: false };\n }\n }, [variables, refetch, orgName]);\n\n /** Send the reply; a send that throws counts as not sent, so the card stays. */\n const sendReply = useCallback(\n async (outcome: ConnectorConnectOutcome, credentialId?: string): Promise<boolean> => {\n try {\n return await onResolve(outcome, credentialId);\n } catch {\n return false;\n }\n },\n [onResolve],\n );\n\n /** Reply `connected`; on failure keep the result so the next tap only resends. */\n const replyConnected = useCallback(\n async (credentialId: string | undefined): Promise<string | null> => {\n if (await sendReply('connected', credentialId)) return null;\n if (mountedRef.current) setUnsent({ credentialId });\n return 'Saved, but the chat did not get it. Tap Send to try again.';\n },\n [sendReply],\n );\n\n /** Leave the busy state with `text` under the actions (null clears it). */\n const settle = useCallback((text: string | null) => {\n if (!mountedRef.current) return;\n setNote(text);\n setBusy(false);\n }, []);\n\n /** Decide from a hand-back and a fresh read against `before`, then reply or say why not. */\n const conclude = useCallback(\n async (\n before: ConnectorConnectBefore,\n handback: ConnectorConnectHandback | null,\n wasConnected: boolean,\n ): Promise<void> => {\n const after = await readVault();\n const decision = decideConnectorConnectOutcome({\n requestId: payload.requestId,\n handback,\n before,\n after: after.ok\n ? { rows: after.rows, match: pickConnectorConnectCredential(after.rows, payload) ?? null }\n : null,\n kind: vaultKind?.id,\n });\n if (decision.kind === 'connected') {\n if (mountedRef.current) setUnverified(null);\n settle(await replyConnected(decision.credentialId));\n return;\n }\n if (!after.ok) {\n if (mountedRef.current) setUnverified(before);\n settle(VERIFY_FAILED_NOTE);\n return;\n }\n if (mountedRef.current) setUnverified(null);\n if (wasConnected) settle('No changes were saved.');\n else if (vaultKind) settle(`The ${vaultKind.noun} was not saved.`);\n else settle(`${name} is not connected yet.`);\n },\n [readVault, payload, replyConnected, settle, vaultKind, name],\n );\n\n const handleAction = useCallback(async () => {\n if (busy) return;\n setBusy(true);\n setNote(null);\n if (unsent) {\n setUnsent(null);\n settle(await replyConnected(unsent.credentialId));\n return;\n }\n if (unverified) {\n await conclude(unverified, null, Boolean(unverified.targetId));\n return;\n }\n if (status === 'failed') {\n // \"Try again\": re-read the status; the action goes live once it answers.\n settle((await readVault()).ok ? null : STATUS_FAILED_NOTE);\n return;\n }\n // Read the vault as it is NOW: the form opens on the credential the server\n // has, and the same read is the \"before\" the result is measured against.\n const now = await readVault();\n if (!now.ok) {\n settle(READ_FAILED_NOTE);\n return;\n }\n const current = pickConnectorConnectCredential(now.rows, payload) ?? null;\n const before = snapshotConnectorCredentials(now.rows, current?.id);\n const url = buildConnectorConnectUrl({\n origin: resolveMobileWebUrl(config.CLIENT_URL, getPackagerHost()),\n payload,\n name,\n // A saved login or entry: open the vault form ON it so the edit (email, username or password, a card's\n // expiry) lands on it instead of on a new duplicate, in the project it lives in (the form refuses an entry\n // from another). A catalog connector's page makes this pick itself, with the template's formId.\n credentialId: vaultKind ? current?.id : undefined,\n projectId: vaultKind ? current?.project?.projectId || projectId : undefined,\n });\n let result: WebBrowser.WebBrowserAuthSessionResult;\n beginConnectorConnectSession(payload.requestId);\n try {\n result = await WebBrowser.openAuthSessionAsync(url, CONNECTOR_CONNECT_APP_RETURN_URL);\n } catch {\n settle('Could not open the page. Try again.');\n return;\n } finally {\n endConnectorConnectSession(payload.requestId);\n }\n const handback = result.type === 'success' ? parseConnectorConnectAppReturnUrl(result.url) : null;\n await conclude(before, handback, Boolean(current));\n }, [\n busy,\n unsent,\n unverified,\n status,\n readVault,\n payload,\n name,\n vaultKind,\n projectId,\n conclude,\n replyConnected,\n settle,\n ]);\n\n /**\n * A hand-back that reached the app while no browser session of this card was\n * waiting for it: Android can kill the app behind Custom Tabs, and the return\n * page then cold-starts it with the scheme URL. Anyone can open that URL, so\n * the credential it names is only taken once a fresh read shows it is one this\n * request could have saved, saved just now (parkedHandbackCredential).\n *\n * On a cold start the card mounts before the org is known and cannot read the\n * vault yet, so the hand-back stays parked until a read answers: it is looked\n * at again whenever the status read settles.\n */\n const adoptingRef = useRef(false);\n const adoptParkedHandback = useCallback(async () => {\n if (busy || unsent || !variables || adoptingRef.current) return;\n const handback = peekConnectorConnectHandback(payload.requestId);\n if (!handback?.credentialId) return;\n adoptingRef.current = true;\n try {\n setBusy(true);\n setNote(null);\n const now = await readVault();\n if (!now.ok) {\n // Left parked: the next settled status read tries again.\n settle(null);\n return;\n }\n takeConnectorConnectHandback(payload.requestId);\n if (!parkedHandbackCredential(now.rows, payload, handback.credentialId, Date.now())) {\n settle(null);\n return;\n }\n settle(await replyConnected(handback.credentialId));\n } finally {\n adoptingRef.current = false;\n }\n }, [busy, unsent, variables, payload, readVault, replyConnected, settle]);\n\n const adoptRef = useRef(adoptParkedHandback);\n useEffect(() => {\n adoptRef.current = adoptParkedHandback;\n }, [adoptParkedHandback]);\n useEffect(\n () =>\n subscribeConnectorConnectHandbacks(() => {\n adoptRef.current().catch(() => undefined);\n }),\n [],\n );\n useEffect(() => {\n if (status === 'checking') return;\n adoptRef.current().catch(() => undefined);\n }, [status]);\n\n const handleDismiss = useCallback(async () => {\n if (busy) return;\n setBusy(true);\n settle((await sendReply('declined')) ? null : SEND_FAILED_NOTE);\n }, [busy, sendReply, settle]);\n\n const onActionPress = useCallback(() => {\n handleAction().catch(() => settle(READ_FAILED_NOTE));\n }, [handleAction, settle]);\n const onDismissPress = useCallback(() => {\n handleDismiss().catch(() => settle(SEND_FAILED_NOTE));\n }, [handleDismiss, settle]);\n\n let actionLabel = connectorConnectActionLabel(payload, connected);\n if (unsent) actionLabel = 'Send';\n else if (unverified) actionLabel = 'Check';\n else if (status === 'failed') actionLabel = 'Try again';\n const statusNote = status === 'failed' && !unsent && !unverified ? STATUS_FAILED_NOTE : null;\n\n return (\n <ConnectorConnectCard\n name={name}\n reason={connectorConnectReason(payload, name, connected)}\n icon={vaultKind?.mobileIcon ?? 'power-plug-outline'}\n connected={connected}\n // A saved card or address is not a connection.\n connectedLabel={vaultKind?.autofill ? 'Saved' : undefined}\n actionLabel={actionLabel}\n busy={busy}\n actionPending={!busy && !unsent && !unverified && status === 'checking'}\n note={note ?? statusNote}\n isDark={isDark}\n onAction={onActionPress}\n onDismiss={onDismissPress}\n />\n );\n}\n\n/**\n * The card for the connect request still waiting in `messages`, if any - the\n * one piece both chat screens (the main chat, and the host screens of the native\n * surface chats) render above their composer.\n *\n * The reply goes out through the screen's ordinary send path, as an ASK_USER\n * answer does, and lands in the thread as a user message; that message is what\n * settles the request, so a reloaded thread does not bring the card back\n * (pendingConnectorConnect). The local mark only bridges the moment between the\n * send and the reply showing up, and is keyed on the message as well as the\n * request id, so the same id-less marker in a later turn still gets its card.\n */\nexport function PendingConnectorConnectCard({\n messages,\n send,\n isDark = false,\n style,\n}: {\n /** The raw thread, outbox rows included - a queued reply settles its request too. */\n messages: ReadonlyArray<{ role: string; content: string }>;\n /** Send `text` as the user's next message; resolves false when it could not go out. */\n send: (text: string) => Promise<boolean>;\n isDark?: boolean;\n style?: StyleProp<ViewStyle>;\n}) {\n const pending = useMemo(() => pendingConnectorConnect(messages), [messages]);\n const key = pending ? connectorConnectKey(pending) : null;\n const [resolved, setResolved] = useState<Record<string, boolean>>({});\n\n const handleResolve = useCallback(\n async (outcome: ConnectorConnectOutcome, credentialId?: string): Promise<boolean> => {\n if (!pending || !key) return false;\n const sent = await send(buildConnectorReply(pending.payload.requestId, outcome, credentialId));\n if (!sent) return false;\n setResolved((prev) => ({ ...prev, [key]: true }));\n return true;\n },\n [pending, key, send],\n );\n\n if (!pending || !key || resolved[key]) return null;\n return (\n <View style={style}>\n <ConnectorConnectPrompt key={key} payload={pending.payload} isDark={isDark} onResolve={handleResolve} />\n </View>\n );\n}\n"],"names":["_a","_b"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import {parseConnectorConnect,isSiteLoginRequest,pickConnectorCredential,CONNECTOR_CONNECT_WEB_RETURN_PATH,isSiteLoginCredential,credentialSavedAt}from'common';export{displayConnectorConnectMessages,displayConnectorConnectText}from'common';var __defProp = Object.defineProperty;
1
+ import {parseConnectorConnect,pickConnectorCredential,isSiteLoginRequest,vaultKindOf,autofillCardTitle,VAULT_FORM_KINDS,credentialVaultKind,CONNECTOR_CONNECT_WEB_RETURN_PATH,SITE_LOGIN_CONNECTOR,credentialSavedAt,autofillCardReason}from'common';export{displayConnectorConnectMessages,displayConnectorConnectText}from'common';var __defProp = Object.defineProperty;
2
2
  var __defProps = Object.defineProperties;
3
3
  var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
4
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
@@ -37,34 +37,40 @@ function readableConnector(connector) {
37
37
  const cleaned = connector.replace(/-app-[a-z0-9]+$/i, "").replace(/\s*\((?:app|api|oauth)\)\s*$/i, "").replace(/[_-]+/g, " ").trim();
38
38
  return cleaned || connector;
39
39
  }
40
- function connectorConnectName(payload) {
40
+ function connectorConnectName(payload, connected = false) {
41
41
  var _a;
42
42
  if (payload.title) return payload.title;
43
43
  if (isSiteLoginRequest(payload)) return ((_a = payload.form) == null ? void 0 : _a.site) ? `${payload.form.site} login` : "Website login";
44
+ const kind = vaultKindOf(payload.connector);
45
+ if (kind == null ? void 0 : kind.autofill) return autofillCardTitle(kind, connected);
44
46
  return readableConnector(payload.connector);
45
47
  }
46
- function connectorConnectReason(payload, name) {
48
+ function connectorConnectReason(payload, name, connected = false) {
47
49
  var _a, _b;
48
50
  if (payload.reason) return payload.reason;
49
51
  if (isSiteLoginRequest(payload)) {
50
52
  return `Save your ${(_b = (_a = payload.form) == null ? void 0 : _a.site) != null ? _b : "website"} sign-in to the vault so I can log in on your Computer.`;
51
53
  }
54
+ const kind = vaultKindOf(payload.connector);
55
+ if (kind == null ? void 0 : kind.autofill) return autofillCardReason(kind, connected);
52
56
  return `Connect ${name} to use it from this chat.`;
53
57
  }
54
58
  function connectorConnectTarget(payload) {
55
- var _a, _b, _c;
56
- const siteLogin = isSiteLoginRequest(payload);
59
+ var _a, _b, _c, _d;
60
+ const kind = (_a = vaultKindOf(payload.connector)) == null ? void 0 : _a.id;
61
+ const siteLogin = kind === SITE_LOGIN_CONNECTOR;
57
62
  return {
58
63
  name: connectorConnectName(payload),
64
+ kind,
59
65
  siteLogin,
60
- site: siteLogin ? (_c = (_a = payload.form) == null ? void 0 : _a.site) != null ? _c : (_b = payload.form) == null ? void 0 : _b.loginUrl : void 0,
66
+ site: siteLogin ? (_d = (_b = payload.form) == null ? void 0 : _b.site) != null ? _d : (_c = payload.form) == null ? void 0 : _c.loginUrl : void 0,
61
67
  credentialId: payload.credentialId
62
68
  };
63
69
  }
64
70
  const matchKey = (name) => (name != null ? name : "").toLowerCase().replace(/[^a-z0-9]/g, "");
65
71
  function pickConnectorConnectCredential(rows, payload) {
66
72
  const target = connectorConnectTarget(payload);
67
- if (target.siteLogin) return pickConnectorCredential(rows, target);
73
+ if (target.kind) return pickConnectorCredential(rows, target);
68
74
  const tried = /* @__PURE__ */ new Set();
69
75
  for (const name of [target.name, readableConnector(payload.connector)]) {
70
76
  const key = matchKey(name);
@@ -79,8 +85,9 @@ function pickConnectorConnectCredential(rows, payload) {
79
85
  return void 0;
80
86
  }
81
87
  function connectorConnectActionLabel(payload, connected) {
88
+ var _a, _b;
82
89
  if (connected) return "Update";
83
- return isSiteLoginRequest(payload) ? "Save login" : "Connect";
90
+ return (_b = (_a = vaultKindOf(payload.connector)) == null ? void 0 : _a.actionLabel) != null ? _b : "Connect";
84
91
  }
85
92
  function toQuery(params) {
86
93
  return params.filter((entry) => {
@@ -96,13 +103,18 @@ function buildConnectorConnectUrl({
96
103
  credentialId,
97
104
  projectId
98
105
  }) {
99
- var _a, _b, _c, _d;
106
+ var _a, _b, _c, _d, _e;
100
107
  const base = origin.trim().replace(/\/+$/, "");
108
+ const kind = vaultKindOf(payload.connector);
109
+ if (kind == null ? void 0 : kind.autofill) {
110
+ const query = toQuery([["provider", kind.id], ["agent", (_a = payload.form) == null ? void 0 : _a.agentName], ["credentialId", credentialId], ["projectId", credentialId ? projectId : void 0], ["requestId", payload.requestId], ["returnTo", CONNECTOR_CONNECT_WEB_RETURN_PATH]]);
111
+ return `${base}${VAULT_NEW_PATH}?${query}`;
112
+ }
101
113
  if (isSiteLoginRequest(payload)) {
102
- const query = toQuery([["name", name], ["site", (_a = payload.form) == null ? void 0 : _a.site], ["loginUrl", (_b = payload.form) == null ? void 0 : _b.loginUrl], ["agent", (_c = payload.form) == null ? void 0 : _c.agentName], ["credentialId", credentialId], ["projectId", projectId], ["requestId", payload.requestId], ["returnTo", CONNECTOR_CONNECT_WEB_RETURN_PATH]]);
114
+ const query = toQuery([["name", name], ["site", (_b = payload.form) == null ? void 0 : _b.site], ["loginUrl", (_c = payload.form) == null ? void 0 : _c.loginUrl], ["agent", (_d = payload.form) == null ? void 0 : _d.agentName], ["credentialId", credentialId], ["projectId", projectId], ["requestId", payload.requestId], ["returnTo", CONNECTOR_CONNECT_WEB_RETURN_PATH]]);
103
115
  return `${base}${VAULT_NEW_PATH}?${query}`;
104
116
  }
105
- const aliases = ((_d = payload.aliases) != null ? _d : []).map((alias) => ["aliases", alias]);
117
+ const aliases = ((_e = payload.aliases) != null ? _e : []).map((alias) => ["aliases", alias]);
106
118
  return `${base}${CONNECTORS_PATH}?${toQuery([["connector", payload.connector], ...aliases, ["title", payload.title], ["credentialId", payload.credentialId], ["requestId", payload.requestId], ["returnTo", CONNECTOR_CONNECT_WEB_RETURN_PATH]])}`;
107
119
  }
108
120
  function credentialFingerprint(row) {
@@ -124,9 +136,10 @@ function decideConnectorConnectOutcome({
124
136
  requestId,
125
137
  handback,
126
138
  before,
127
- after
139
+ after,
140
+ kind
128
141
  }) {
129
- var _a, _b, _c, _d, _e;
142
+ var _a, _b, _c, _d, _e, _f;
130
143
  if (handback && (!handback.requestId || handback.requestId === requestId)) {
131
144
  return {
132
145
  kind: "connected",
@@ -155,10 +168,11 @@ function decideConnectorConnectOutcome({
155
168
  kind: "connected",
156
169
  credentialId: (_d = after.match.id) != null ? _d : void 0
157
170
  };
158
- const created = after.rows.filter((row) => Boolean((row == null ? void 0 : row.id) && row.status === "active" && !versions[row.id]));
171
+ const createdKind = kind && ((_e = VAULT_FORM_KINDS[kind]) == null ? void 0 : _e.autofill) ? kind : void 0;
172
+ const created = after.rows.filter((row) => Boolean((row == null ? void 0 : row.id) && row.status === "active" && !versions[row.id] && (!createdKind || credentialVaultKind(row) === createdKind)));
159
173
  if (created.length === 1) return {
160
174
  kind: "connected",
161
- credentialId: (_e = created[0].id) != null ? _e : void 0
175
+ credentialId: (_f = created[0].id) != null ? _f : void 0
162
176
  };
163
177
  return {
164
178
  kind: "unchanged"
@@ -170,10 +184,24 @@ function parkedHandbackCredential(rows, payload, credentialId, nowMs) {
170
184
  if (!credentialId) return null;
171
185
  const row = rows.find((r) => (r == null ? void 0 : r.id) === credentialId && r.status === "active");
172
186
  if (!row) return null;
173
- const fits = isSiteLoginRequest(payload) ? ((_a = pickConnectorCredential(rows, __spreadProps(__spreadValues({}, connectorConnectTarget(payload)), {
174
- credentialId
175
- }))) == null ? void 0 : _a.id) === credentialId : !isSiteLoginCredential(row);
187
+ const kind = vaultKindOf(payload.connector);
188
+ let fits;
189
+ if ((kind == null ? void 0 : kind.id) === SITE_LOGIN_CONNECTOR) {
190
+ fits = ((_a = pickConnectorCredential(rows, __spreadProps(__spreadValues({}, connectorConnectTarget(payload)), {
191
+ credentialId
192
+ }))) == null ? void 0 : _a.id) === credentialId;
193
+ } else if (kind) {
194
+ fits = credentialVaultKind(row) === kind.id;
195
+ } else {
196
+ fits = !credentialVaultKind(row);
197
+ }
176
198
  if (!fits) return null;
177
199
  const savedAt = credentialSavedAt(row);
178
200
  return savedAt > 0 && nowMs - savedAt <= PARKED_HANDBACK_MAX_AGE_MS ? row : null;
179
- }export{CONNECTORS_PATH,PARKED_HANDBACK_MAX_AGE_MS,VAULT_NEW_PATH,buildConnectorConnectUrl,connectorConnectActionLabel,connectorConnectKey,connectorConnectName,connectorConnectReason,connectorConnectTarget,credentialFingerprint,decideConnectorConnectOutcome,parkedHandbackCredential,pendingConnectorConnect,pickConnectorConnectCredential,snapshotConnectorCredentials};//# sourceMappingURL=connectorConnect.js.map
201
+ }
202
+ function a11yActionLabel(actionLabel, name) {
203
+ const action = actionLabel.toLowerCase();
204
+ const subject = name.toLowerCase().replace(/^your\s+/, "");
205
+ if (action.endsWith(subject) || name.toLowerCase().startsWith(action)) return actionLabel;
206
+ return `${actionLabel} ${name}`;
207
+ }export{CONNECTORS_PATH,PARKED_HANDBACK_MAX_AGE_MS,VAULT_NEW_PATH,a11yActionLabel,buildConnectorConnectUrl,connectorConnectActionLabel,connectorConnectKey,connectorConnectName,connectorConnectReason,connectorConnectTarget,credentialFingerprint,decideConnectorConnectOutcome,parkedHandbackCredential,pendingConnectorConnect,pickConnectorConnectCredential,snapshotConnectorCredentials};//# sourceMappingURL=connectorConnect.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"connectorConnect.js","sources":["../../../src/features/chat/connectorConnect.ts"],"sourcesContent":["/**\n * The `[CONNECTOR_CONNECT]` card, mobile side.\n *\n * The marker and its replies are parsed by common's CONNECTOR_CONNECT_PROTOCOL,\n * the same module the web chat uses, so every marker shape the model drifts into\n * is read the same way on both. This file holds only what is specific to the\n * phone: which request is still waiting, the card's copy, the web page the card\n * opens (the phone cannot host the web's inline forms, so it opens them in an\n * in-app browser session), and how to tell, once that session ends, whether the\n * vault really changed.\n *\n * Host-only: this module imports `common`, which the federated surface remotes\n * must not bundle. A remote's chat gets its messages already cleaned\n * (displayConnectorConnectMessages) and its card as a host render prop.\n */\nimport {\n CONNECTOR_CONNECT_WEB_RETURN_PATH,\n credentialSavedAt,\n isSiteLoginCredential,\n isSiteLoginRequest,\n parseConnectorConnect,\n pickConnectorCredential,\n type ConnectorConnectHandback,\n type ConnectorConnectPayload,\n type ConnectorConnectionTarget,\n type ConnectorCredentialListRow,\n} from 'common';\n\n/** How a transcript shows a thread with connect markers in it - shared with the web host's surface chat. */\nexport { displayConnectorConnectMessages, displayConnectorConnectText } from 'common';\n\n/** forms-stack's \"Save to vault\" page as the web app mounts it (AccountRoutes.AccountConnectorsVaultNew). */\nexport const VAULT_NEW_PATH = '/account/connectors/vault/new';\n\n/** A connect request still waiting on the user, and where it sits in the thread. */\nexport interface PendingConnectorConnect {\n payload: ConnectorConnectPayload;\n /** Index of the assistant message that carried the marker. */\n messageIndex: number;\n}\n\n/**\n * The connect request still awaiting an answer: the newest marker in the\n * assistant messages since the last user message. Any user message after it - the\n * `[CONNECTOR_CONNECTED:…]` / `[CONNECTOR_DECLINED:…]` reply the card sends, or\n * the user simply typing on - settles it, so a reloaded thread never brings back a\n * card that was already answered (the same rule as pendingAskUser).\n */\nexport function pendingConnectorConnect(\n messages: ReadonlyArray<{ role: string; content: string }>,\n): PendingConnectorConnect | null {\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n const msg = messages[i];\n if (msg.role === 'user') return null;\n const payload = msg.role === 'assistant' ? parseConnectorConnect(msg.content) : null;\n if (payload) return { payload, messageIndex: i };\n }\n return null;\n}\n\n/**\n * What a local \"answered\" mark is keyed on. The request id alone is not enough: a\n * marker that carries no id gets one derived from its text, so the same marker\n * repeated in a later turn has the same id, and keying on the id alone would hide\n * that new card too.\n */\nexport function connectorConnectKey(pending: PendingConnectorConnect): string {\n return `${pending.messageIndex}:${pending.payload.requestId}`;\n}\n\n/** A connector key as a readable name: `google-ads` -> `google ads` (the web's cleanup, minus the template lookup). */\nfunction readableConnector(connector: string): string {\n const cleaned = connector\n .replace(/-app-[a-z0-9]+$/i, '')\n .replace(/\\s*\\((?:app|api|oauth)\\)\\s*$/i, '')\n .replace(/[_-]+/g, ' ')\n .trim();\n return cleaned || connector;\n}\n\n/** Card title, and the name a new site login is saved under: \"Amazon login\", \"amazon.com login\", \"openai\". */\nexport function connectorConnectName(payload: ConnectorConnectPayload): string {\n if (payload.title) return payload.title;\n if (isSiteLoginRequest(payload)) return payload.form?.site ? `${payload.form.site} login` : 'Website login';\n return readableConnector(payload.connector);\n}\n\n/** The card's one line under the title; the agent's own reason wins. */\nexport function connectorConnectReason(payload: ConnectorConnectPayload, name: string): string {\n if (payload.reason) return payload.reason;\n if (isSiteLoginRequest(payload)) {\n return `Save your ${payload.form?.site ?? 'website'} sign-in to the vault so I can log in on your Computer.`;\n }\n return `Connect ${name} to use it from this chat.`;\n}\n\n/**\n * What the card looks for in the vault: the web card's target for the same request (common's\n * matchConnectorCredentials), minus the template's formId, which only the web can resolve. A site\n * login takes saved logins for its site only; the credential the agent named wins when it is one\n * of the org's and fits, else the most recently updated match - the row the agent signs in with.\n *\n * For a site login this is the same target the web card builds, so the pick is the web's. For a\n * catalog connector it is only the card's status (\"Connected\" / \"Update\"): without the formId a\n * name-only match can take another connector's credential (\"Azure OpenAI\" for OpenAI) or miss one\n * saved under another name, so the phone never acts on it - the web page it opens picks (see\n * buildConnectorConnectUrl, and pickConnectorConnectCredential for the status).\n */\nexport function connectorConnectTarget(payload: ConnectorConnectPayload): Omit<ConnectorConnectionTarget, 'id'> {\n const siteLogin = isSiteLoginRequest(payload);\n return {\n name: connectorConnectName(payload),\n siteLogin,\n site: siteLogin ? (payload.form?.site ?? payload.form?.loginUrl) : undefined,\n credentialId: payload.credentialId,\n };\n}\n\n/** A name as the matcher compares it (common's matchConnectorCredentials): lower case, letters and digits only. */\nconst matchKey = (name: string | undefined) => (name ?? '').toLowerCase().replace(/[^a-z0-9]/g, '');\n\n/**\n * The saved credential the phone's card stands on for a request - \"Update\" when there is one, and the one the card\n * measures the browser session against - or undefined.\n *\n * A site login: common's pick on connectorConnectTarget, the web card's own target, so the very row the web card\n * and the agent use. A catalog connector: the web card also matches the template's formId, which the phone cannot\n * resolve, so a card titled \"OpenAI API key\" missed the \"OpenAI\" credential the web card finds by formId and showed\n * \"Connect\" where the web shows \"Update\". A credential saved from a template is named for it, so after the card\n * title the phone also looks under the connector the agent named (`openai`, `google-calendar` as \"google\n * calendar\"); the first name that matches wins. Only the phone's label and its after-the-session check rest on\n * this: the web page the card opens makes the pick it edits (buildConnectorConnectUrl).\n */\nexport function pickConnectorConnectCredential<T extends ConnectorCredentialListRow>(\n rows: ReadonlyArray<T | null | undefined>,\n payload: ConnectorConnectPayload,\n): T | undefined {\n const target = connectorConnectTarget(payload);\n if (target.siteLogin) return pickConnectorCredential(rows, target);\n const tried = new Set<string>();\n for (const name of [target.name, readableConnector(payload.connector)]) {\n const key = matchKey(name);\n if (key && !tried.has(key)) {\n tried.add(key);\n const hit = pickConnectorCredential(rows, { ...target, name });\n if (hit) return hit;\n }\n }\n return undefined;\n}\n\n/** The primary action: a saved connection is updated in place, a new one is saved or connected. */\nexport function connectorConnectActionLabel(payload: ConnectorConnectPayload, connected: boolean): string {\n if (connected) return 'Update';\n return isSiteLoginRequest(payload) ? 'Save login' : 'Connect';\n}\n\n/** `a=1&b=2`, skipping empty values. Hand-rolled: React Native's URLSearchParams cannot be relied on. */\nfunction toQuery(params: ReadonlyArray<readonly [string, string | null | undefined]>): string {\n return params\n .filter((entry): entry is readonly [string, string] => Boolean(entry[1]?.trim()))\n .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value.trim())}`)\n .join('&');\n}\n\nexport interface ConnectorConnectUrlInput {\n /** The web app's origin (CLIENT_URL). */\n origin: string;\n payload: ConnectorConnectPayload;\n /** Card title; a site login is saved under it. */\n name: string;\n /**\n * A site login only: update THIS saved login in place (the card's \"Update\"); absent saves a new one. Never sent\n * for a catalog connector, whose page makes the pick itself (see buildConnectorConnectUrl).\n */\n credentialId?: string | null;\n /**\n * A site login only: the project the vault form works in - where a new login is saved, and for an update the\n * project the login LIVES in (the form refuses to change a login from any other project, and the card matches\n * the whole org's).\n */\n projectId?: string | null;\n}\n\n/** The web Connectors entry that resolves a connector to its template first (ConnectorsRedirect). */\nexport const CONNECTORS_PATH = '/account/connectors';\n\n/**\n * The web page the card opens.\n *\n * A site login opens forms-stack's \"Save to vault\" page. Given `credentialId` that\n * page UPDATES that credential (username / email and password alike) instead of\n * saving a duplicate next to it. `returnTo` sends it, once saved, to the web\n * return page that hands the credential id back to the app, and `requestId`\n * rides along so the hand-back names the request it answers.\n *\n * Any other connector opens the Connectors entry with the agent's `connector` and\n * `aliases` as they came, and the page there is the web card itself\n * (ConnectorCredentialEdit): it resolves them against the org's template pool with\n * the web card's own resolver (useCredentialTemplateByKey), so a display name like\n * \"Google Calendar\" or a drifted key reaches the same template on both, and then\n * makes the web card's pick with the template's formId - which saved credential is\n * this connector's, to update in place, or none, to connect a new one. The phone\n * cannot resolve that formId, so it sends no pick of its own: a name-only pick can be\n * another connector's credential (\"Azure OpenAI\" for OpenAI), which the form would\n * then overwrite, or miss one saved under another name and start a duplicate. Only\n * the agent's own `credentialId` rides along, as the hint the web card honours when\n * it fits. Once saved the page returns through the same return page as the vault\n * form, so the phone learns which credential it was.\n */\nexport function buildConnectorConnectUrl({\n origin,\n payload,\n name,\n credentialId,\n projectId,\n}: ConnectorConnectUrlInput): string {\n const base = origin.trim().replace(/\\/+$/, '');\n if (isSiteLoginRequest(payload)) {\n const query = toQuery([\n ['name', name],\n ['site', payload.form?.site],\n ['loginUrl', payload.form?.loginUrl],\n ['agent', payload.form?.agentName],\n ['credentialId', credentialId],\n ['projectId', projectId],\n ['requestId', payload.requestId],\n ['returnTo', CONNECTOR_CONNECT_WEB_RETURN_PATH],\n ]);\n return `${base}${VAULT_NEW_PATH}?${query}`;\n }\n const aliases = (payload.aliases ?? []).map((alias) => ['aliases', alias] as const);\n return `${base}${CONNECTORS_PATH}?${toQuery([\n ['connector', payload.connector],\n ...aliases,\n ['title', payload.title],\n ['credentialId', payload.credentialId],\n ['requestId', payload.requestId],\n ['returnTo', CONNECTOR_CONNECT_WEB_RETURN_PATH],\n ])}`;\n}\n\n/** A saved credential as the card reads it: the matched fields, its version (`updatedAt`) and where it lives. */\nexport type CredentialVersionRow = ConnectorCredentialListRow;\n\n/**\n * A saved credential's identity AND version. An update keeps the id but moves\n * `updatedAt`, so comparing these before and after the browser tells a real save\n * apart from a closed browser.\n */\nexport function credentialFingerprint(row: CredentialVersionRow | null | undefined): string | null {\n if (!row?.id) return null;\n return `${row.id}@${row.updatedAt == null ? '' : String(row.updatedAt)}`;\n}\n\n/** The vault as it stood when the browser opened: every credential's version, and the one being updated. */\nexport interface ConnectorConnectBefore {\n /** Credential id -> fingerprint, for every row the read returned. */\n versions: Record<string, string>;\n /** The credential the card opened the form ON (\"Update\"), if any. */\n targetId?: string | null;\n}\n\n/** Record the vault before the browser opens, so the check afterwards can tell what the session changed. */\nexport function snapshotConnectorCredentials(\n rows: ReadonlyArray<CredentialVersionRow | null | undefined>,\n targetId?: string | null,\n): ConnectorConnectBefore {\n const versions: Record<string, string> = {};\n for (const row of rows) {\n const fingerprint = credentialFingerprint(row);\n if (row?.id && fingerprint) versions[row.id] = fingerprint;\n }\n return { versions, targetId: targetId ?? null };\n}\n\nexport type ConnectorConnectOutcomeDecision =\n | { kind: 'connected'; credentialId?: string }\n /** Nothing changed in the vault: the card stays up, the agent is told nothing. */\n | { kind: 'unchanged' };\n\n/**\n * Whether the browser session produced a connection, and with which credential.\n *\n * 1. The session ended on the app's return URL: the vault page saved, and says\n * which credential. That is the answer, unless it names a different request.\n * 2. Otherwise (the person closed the browser, or the connector's page has no way\n * back to the app) the vault is read again and compared with `before`:\n * - the credential the form was opened ON has a newer version: updated in place\n * (found by id, so an edit that also renamed it still counts);\n * - the credential matching this request (formId / name) is new or newer;\n * - exactly one active credential appeared that was not there before: the\n * session created it, under whatever name the person gave it.\n * A credential some other flow merely touched is never taken, and a card never\n * claims a connection it cannot see.\n */\nexport function decideConnectorConnectOutcome({\n requestId,\n handback,\n before,\n after,\n}: {\n requestId: string;\n handback: ConnectorConnectHandback | null;\n /** The vault before the browser opened; without it nothing but a hand-back counts. */\n before: ConnectorConnectBefore | null;\n /** The vault after the browser closed, re-read from the server; null when that read failed. */\n after: { rows: ReadonlyArray<CredentialVersionRow | null | undefined>; match: CredentialVersionRow | null } | null;\n}): ConnectorConnectOutcomeDecision {\n if (handback && (!handback.requestId || handback.requestId === requestId)) {\n return { kind: 'connected', credentialId: handback.credentialId ?? after?.match?.id ?? undefined };\n }\n if (!before || !after) return { kind: 'unchanged' };\n const { versions, targetId } = before;\n const changed = (row: CredentialVersionRow | null | undefined): row is CredentialVersionRow => {\n const now = credentialFingerprint(row);\n return Boolean(now && row?.id && versions[row.id] !== now);\n };\n if (targetId) {\n const target = after.rows.find((row) => row?.id === targetId);\n if (target?.status === 'active' && changed(target)) return { kind: 'connected', credentialId: targetId };\n }\n if (changed(after.match)) return { kind: 'connected', credentialId: after.match.id ?? undefined };\n const created = after.rows.filter((row): row is CredentialVersionRow =>\n Boolean(row?.id && row.status === 'active' && !versions[row.id]),\n );\n if (created.length === 1) return { kind: 'connected', credentialId: created[0].id ?? undefined };\n return { kind: 'unchanged' };\n}\n\n/**\n * How long after its save a hand-back that reached the app with no browser session waiting is still taken: the\n * session the app was killed during (Android kills it behind Custom Tabs, and the return page cold-starts it).\n */\nexport const PARKED_HANDBACK_MAX_AGE_MS = 30 * 60 * 1000;\n\n/**\n * The credential a PARKED hand-back names, when it may be taken as this request's answer; null otherwise.\n *\n * Anyone can open the app's scheme URL, and the vault snapshot the card took before the browser opened died with\n * the app, so \"the vault has it\" is not enough. The credential must be:\n * - an ACTIVE credential of the org (`rows` is a fresh read);\n * - one this request could have saved: for a site login, the login the card itself picks for the request with\n * that id named (its site or name; never another site's login or a catalog credential); for a catalog\n * connector, a connector credential, never a website login - the phone cannot resolve the template, so a name\n * alone cannot rule a connector credential in or out (see connectorConnectTarget);\n * - saved in the last PARKED_HANDBACK_MAX_AGE_MS, the stand-in for \"changed during the session\": every save on\n * the web page moves `updatedAt`, while an id lifted from anywhere else names a credential saved long ago.\n */\nexport function parkedHandbackCredential(\n rows: ReadonlyArray<CredentialVersionRow | null | undefined>,\n payload: ConnectorConnectPayload,\n credentialId: string | null | undefined,\n nowMs: number,\n): CredentialVersionRow | null {\n if (!credentialId) return null;\n const row = rows.find((r) => r?.id === credentialId && r.status === 'active');\n if (!row) return null;\n const fits = isSiteLoginRequest(payload)\n ? pickConnectorCredential(rows, { ...connectorConnectTarget(payload), credentialId })?.id === credentialId\n : !isSiteLoginCredential(row);\n if (!fits) return null;\n const savedAt = credentialSavedAt(row);\n return savedAt > 0 && nowMs - savedAt <= PARKED_HANDBACK_MAX_AGE_MS ? row : null;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"connectorConnect.js","sources":["../../../src/features/chat/connectorConnect.ts"],"sourcesContent":["/**\n * The `[CONNECTOR_CONNECT]` card, mobile side.\n *\n * The marker and its replies are parsed by common's CONNECTOR_CONNECT_PROTOCOL,\n * the same module the web chat uses, so every marker shape the model drifts into\n * is read the same way on both. This file holds only what is specific to the\n * phone: which request is still waiting, the card's copy, the web page the card\n * opens (the phone cannot host the web's inline forms, so it opens them in an\n * in-app browser session), and how to tell, once that session ends, whether the\n * vault really changed.\n *\n * Host-only: this module imports `common`, which the federated surface remotes\n * must not bundle. A remote's chat gets its messages already cleaned\n * (displayConnectorConnectMessages) and its card as a host render prop.\n */\nimport {\n autofillCardReason,\n autofillCardTitle,\n CONNECTOR_CONNECT_WEB_RETURN_PATH,\n credentialSavedAt,\n credentialVaultKind,\n isSiteLoginRequest,\n parseConnectorConnect,\n pickConnectorCredential,\n SITE_LOGIN_CONNECTOR,\n VAULT_FORM_KINDS,\n vaultKindOf,\n type ConnectorConnectHandback,\n type ConnectorConnectPayload,\n type ConnectorConnectionTarget,\n type ConnectorCredentialListRow,\n type VaultFormKindId,\n} from 'common';\n\n/** How a transcript shows a thread with connect markers in it - shared with the web host's surface chat. */\nexport { displayConnectorConnectMessages, displayConnectorConnectText } from 'common';\n\n/** forms-stack's \"Save to vault\" page as the web app mounts it (AccountRoutes.AccountConnectorsVaultNew). */\nexport const VAULT_NEW_PATH = '/account/connectors/vault/new';\n\n/** A connect request still waiting on the user, and where it sits in the thread. */\nexport interface PendingConnectorConnect {\n payload: ConnectorConnectPayload;\n /** Index of the assistant message that carried the marker. */\n messageIndex: number;\n}\n\n/**\n * The connect request still awaiting an answer: the newest marker in the\n * assistant messages since the last user message. Any user message after it - the\n * `[CONNECTOR_CONNECTED:…]` / `[CONNECTOR_DECLINED:…]` reply the card sends, or\n * the user simply typing on - settles it, so a reloaded thread never brings back a\n * card that was already answered (the same rule as pendingAskUser).\n */\nexport function pendingConnectorConnect(\n messages: ReadonlyArray<{ role: string; content: string }>,\n): PendingConnectorConnect | null {\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n const msg = messages[i];\n if (msg.role === 'user') return null;\n const payload = msg.role === 'assistant' ? parseConnectorConnect(msg.content) : null;\n if (payload) return { payload, messageIndex: i };\n }\n return null;\n}\n\n/**\n * What a local \"answered\" mark is keyed on. The request id alone is not enough: a\n * marker that carries no id gets one derived from its text, so the same marker\n * repeated in a later turn has the same id, and keying on the id alone would hide\n * that new card too.\n */\nexport function connectorConnectKey(pending: PendingConnectorConnect): string {\n return `${pending.messageIndex}:${pending.payload.requestId}`;\n}\n\n/** A connector key as a readable name: `google-ads` -> `google ads` (the web's cleanup, minus the template lookup). */\nfunction readableConnector(connector: string): string {\n const cleaned = connector\n .replace(/-app-[a-z0-9]+$/i, '')\n .replace(/\\s*\\((?:app|api|oauth)\\)\\s*$/i, '')\n .replace(/[_-]+/g, ' ')\n .trim();\n return cleaned || connector;\n}\n\n/**\n * Card title, and the name a new site login is saved under: \"Amazon login\", \"amazon.com login\", \"openai\". An\n * autofill request the agent gave no title reads \"Add card\", or \"Update card\" once `connected` (the saved entry it\n * names is listed).\n */\nexport function connectorConnectName(payload: ConnectorConnectPayload, connected = false): string {\n if (payload.title) return payload.title;\n if (isSiteLoginRequest(payload)) return payload.form?.site ? `${payload.form.site} login` : 'Website login';\n const kind = vaultKindOf(payload.connector);\n if (kind?.autofill) return autofillCardTitle(kind, connected);\n return readableConnector(payload.connector);\n}\n\n/** The card's one line under the title; the agent's own reason wins. */\nexport function connectorConnectReason(payload: ConnectorConnectPayload, name: string, connected = false): string {\n if (payload.reason) return payload.reason;\n if (isSiteLoginRequest(payload)) {\n return `Save your ${payload.form?.site ?? 'website'} sign-in to the vault so I can log in on your Computer.`;\n }\n const kind = vaultKindOf(payload.connector);\n if (kind?.autofill) return autofillCardReason(kind, connected);\n return `Connect ${name} to use it from this chat.`;\n}\n\n/**\n * What the card looks for in the vault: the web card's target for the same request (common's\n * matchConnectorCredentials), minus the template's formId, which only the web can resolve. A site\n * login takes saved logins for its site only; the credential the agent named wins when it is one\n * of the org's and fits, else the most recently updated match - the row the agent signs in with.\n * An autofill request (a card, an address) takes only the entry of its kind the agent named, and\n * otherwise none: the card adds a new one.\n *\n * For a vault form kind this is the same target the web card builds, so the pick is the web's. For a\n * catalog connector it is only the card's status (\"Connected\" / \"Update\"): without the formId a\n * name-only match can take another connector's credential (\"Azure OpenAI\" for OpenAI) or miss one\n * saved under another name, so the phone never acts on it - the web page it opens picks (see\n * buildConnectorConnectUrl, and pickConnectorConnectCredential for the status).\n */\nexport function connectorConnectTarget(payload: ConnectorConnectPayload): Omit<ConnectorConnectionTarget, 'id'> {\n const kind = vaultKindOf(payload.connector)?.id;\n const siteLogin = kind === SITE_LOGIN_CONNECTOR;\n return {\n name: connectorConnectName(payload),\n kind,\n siteLogin,\n site: siteLogin ? (payload.form?.site ?? payload.form?.loginUrl) : undefined,\n credentialId: payload.credentialId,\n };\n}\n\n/** A name as the matcher compares it (common's matchConnectorCredentials): lower case, letters and digits only. */\nconst matchKey = (name: string | undefined) => (name ?? '').toLowerCase().replace(/[^a-z0-9]/g, '');\n\n/**\n * The saved credential the phone's card stands on for a request - \"Update\" when there is one, and the one the card\n * measures the browser session against - or undefined.\n *\n * A site login: common's pick on connectorConnectTarget, the web card's own target, so the very row the web card\n * and the agent use. A catalog connector: the web card also matches the template's formId, which the phone cannot\n * resolve, so a card titled \"OpenAI API key\" missed the \"OpenAI\" credential the web card finds by formId and showed\n * \"Connect\" where the web shows \"Update\". A credential saved from a template is named for it, so after the card\n * title the phone also looks under the connector the agent named (`openai`, `google-calendar` as \"google\n * calendar\"); the first name that matches wins. Only the phone's label and its after-the-session check rest on\n * this: the web page the card opens makes the pick it edits (buildConnectorConnectUrl).\n */\nexport function pickConnectorConnectCredential<T extends ConnectorCredentialListRow>(\n rows: ReadonlyArray<T | null | undefined>,\n payload: ConnectorConnectPayload,\n): T | undefined {\n const target = connectorConnectTarget(payload);\n // A vault form kind: the web card's own target, so the very row the web card edits (or none, for a new entry).\n if (target.kind) return pickConnectorCredential(rows, target);\n const tried = new Set<string>();\n for (const name of [target.name, readableConnector(payload.connector)]) {\n const key = matchKey(name);\n if (key && !tried.has(key)) {\n tried.add(key);\n const hit = pickConnectorCredential(rows, { ...target, name });\n if (hit) return hit;\n }\n }\n return undefined;\n}\n\n/** The primary action: a saved one is updated in place, a new one saved (\"Save login\", \"Add card\") or connected. */\nexport function connectorConnectActionLabel(payload: ConnectorConnectPayload, connected: boolean): string {\n if (connected) return 'Update';\n return vaultKindOf(payload.connector)?.actionLabel ?? 'Connect';\n}\n\n/** `a=1&b=2`, skipping empty values. Hand-rolled: React Native's URLSearchParams cannot be relied on. */\nfunction toQuery(params: ReadonlyArray<readonly [string, string | null | undefined]>): string {\n return params\n .filter((entry): entry is readonly [string, string] => Boolean(entry[1]?.trim()))\n .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value.trim())}`)\n .join('&');\n}\n\nexport interface ConnectorConnectUrlInput {\n /** The web app's origin (CLIENT_URL). */\n origin: string;\n payload: ConnectorConnectPayload;\n /** Card title; a site login is saved under it (an autofill entry is named after what it holds). */\n name: string;\n /**\n * A vault form kind only: update THIS saved entry in place (the card's \"Update\"); absent saves a new one. Never\n * sent for a catalog connector, whose page makes the pick itself (see buildConnectorConnectUrl).\n */\n credentialId?: string | null;\n /**\n * A vault form kind only: the project the vault form works in - for an update the project the entry LIVES in\n * (the form refuses to change an entry from any other project, and the card matches the whole org's), and for a\n * new login where it is saved. A new autofill entry is saved where the page's own default project is.\n */\n projectId?: string | null;\n}\n\n/** The web Connectors entry that resolves a connector to its template first (ConnectorsRedirect). */\nexport const CONNECTORS_PATH = '/account/connectors';\n\n/**\n * The web page the card opens.\n *\n * A site login opens forms-stack's \"Save to vault\" page. Given `credentialId` that\n * page UPDATES that credential (username / email and password alike) instead of\n * saving a duplicate next to it. `returnTo` sends it, once saved, to the web\n * return page that hands the credential id back to the app, and `requestId`\n * rides along so the hand-back names the request it answers.\n *\n * An autofill request (a card, an address, a passport) opens the same page with\n * its kind as `provider`, which picks the form's fields; `credentialId` (and the\n * entry's project) only when it updates the entry the agent named, since a new\n * entry is named after what it holds and saved to the page's default project.\n *\n * Any other connector opens the Connectors entry with the agent's `connector` and\n * `aliases` as they came, and the page there is the web card itself\n * (ConnectorCredentialEdit): it resolves them against the org's template pool with\n * the web card's own resolver (useCredentialTemplateByKey), so a display name like\n * \"Google Calendar\" or a drifted key reaches the same template on both, and then\n * makes the web card's pick with the template's formId - which saved credential is\n * this connector's, to update in place, or none, to connect a new one. The phone\n * cannot resolve that formId, so it sends no pick of its own: a name-only pick can be\n * another connector's credential (\"Azure OpenAI\" for OpenAI), which the form would\n * then overwrite, or miss one saved under another name and start a duplicate. Only\n * the agent's own `credentialId` rides along, as the hint the web card honours when\n * it fits. Once saved the page returns through the same return page as the vault\n * form, so the phone learns which credential it was.\n */\nexport function buildConnectorConnectUrl({\n origin,\n payload,\n name,\n credentialId,\n projectId,\n}: ConnectorConnectUrlInput): string {\n const base = origin.trim().replace(/\\/+$/, '');\n const kind = vaultKindOf(payload.connector);\n if (kind?.autofill) {\n const query = toQuery([\n ['provider', kind.id],\n ['agent', payload.form?.agentName],\n ['credentialId', credentialId],\n ['projectId', credentialId ? projectId : undefined],\n ['requestId', payload.requestId],\n ['returnTo', CONNECTOR_CONNECT_WEB_RETURN_PATH],\n ]);\n return `${base}${VAULT_NEW_PATH}?${query}`;\n }\n if (isSiteLoginRequest(payload)) {\n const query = toQuery([\n ['name', name],\n ['site', payload.form?.site],\n ['loginUrl', payload.form?.loginUrl],\n ['agent', payload.form?.agentName],\n ['credentialId', credentialId],\n ['projectId', projectId],\n ['requestId', payload.requestId],\n ['returnTo', CONNECTOR_CONNECT_WEB_RETURN_PATH],\n ]);\n return `${base}${VAULT_NEW_PATH}?${query}`;\n }\n const aliases = (payload.aliases ?? []).map((alias) => ['aliases', alias] as const);\n return `${base}${CONNECTORS_PATH}?${toQuery([\n ['connector', payload.connector],\n ...aliases,\n ['title', payload.title],\n ['credentialId', payload.credentialId],\n ['requestId', payload.requestId],\n ['returnTo', CONNECTOR_CONNECT_WEB_RETURN_PATH],\n ])}`;\n}\n\n/** A saved credential as the card reads it: the matched fields, its version (`updatedAt`) and where it lives. */\nexport type CredentialVersionRow = ConnectorCredentialListRow;\n\n/**\n * A saved credential's identity AND version. An update keeps the id but moves\n * `updatedAt`, so comparing these before and after the browser tells a real save\n * apart from a closed browser.\n */\nexport function credentialFingerprint(row: CredentialVersionRow | null | undefined): string | null {\n if (!row?.id) return null;\n return `${row.id}@${row.updatedAt == null ? '' : String(row.updatedAt)}`;\n}\n\n/** The vault as it stood when the browser opened: every credential's version, and the one being updated. */\nexport interface ConnectorConnectBefore {\n /** Credential id -> fingerprint, for every row the read returned. */\n versions: Record<string, string>;\n /** The credential the card opened the form ON (\"Update\"), if any. */\n targetId?: string | null;\n}\n\n/** Record the vault before the browser opens, so the check afterwards can tell what the session changed. */\nexport function snapshotConnectorCredentials(\n rows: ReadonlyArray<CredentialVersionRow | null | undefined>,\n targetId?: string | null,\n): ConnectorConnectBefore {\n const versions: Record<string, string> = {};\n for (const row of rows) {\n const fingerprint = credentialFingerprint(row);\n if (row?.id && fingerprint) versions[row.id] = fingerprint;\n }\n return { versions, targetId: targetId ?? null };\n}\n\nexport type ConnectorConnectOutcomeDecision =\n | { kind: 'connected'; credentialId?: string }\n /** Nothing changed in the vault: the card stays up, the agent is told nothing. */\n | { kind: 'unchanged' };\n\n/**\n * Whether the browser session produced a connection, and with which credential.\n *\n * 1. The session ended on the app's return URL: the vault page saved, and says\n * which credential. That is the answer, unless it names a different request.\n * 2. Otherwise (the person closed the browser, or the connector's page has no way\n * back to the app) the vault is read again and compared with `before`:\n * - the credential the form was opened ON has a newer version: updated in place\n * (found by id, so an edit that also renamed it still counts);\n * - the credential matching this request (formId / name) is new or newer;\n * - exactly one active credential appeared that was not there before: the\n * session created it, under whatever name the person gave it. For an\n * autofill request (`kind`) only an entry of that kind counts: the vault\n * page saves nothing else, and an entry is named after what it holds.\n * A credential some other flow merely touched is never taken, and a card never\n * claims a connection it cannot see.\n */\nexport function decideConnectorConnectOutcome({\n requestId,\n handback,\n before,\n after,\n kind,\n}: {\n requestId: string;\n handback: ConnectorConnectHandback | null;\n /** The vault before the browser opened; without it nothing but a hand-back counts. */\n before: ConnectorConnectBefore | null;\n /** The vault after the browser closed, re-read from the server; null when that read failed. */\n after: { rows: ReadonlyArray<CredentialVersionRow | null | undefined>; match: CredentialVersionRow | null } | null;\n /** The request's vault form kind (vaultKindOf its connector), if any. */\n kind?: VaultFormKindId;\n}): ConnectorConnectOutcomeDecision {\n if (handback && (!handback.requestId || handback.requestId === requestId)) {\n return { kind: 'connected', credentialId: handback.credentialId ?? after?.match?.id ?? undefined };\n }\n if (!before || !after) return { kind: 'unchanged' };\n const { versions, targetId } = before;\n const changed = (row: CredentialVersionRow | null | undefined): row is CredentialVersionRow => {\n const now = credentialFingerprint(row);\n return Boolean(now && row?.id && versions[row.id] !== now);\n };\n if (targetId) {\n const target = after.rows.find((row) => row?.id === targetId);\n if (target?.status === 'active' && changed(target)) return { kind: 'connected', credentialId: targetId };\n }\n if (changed(after.match)) return { kind: 'connected', credentialId: after.match.id ?? undefined };\n const createdKind = kind && VAULT_FORM_KINDS[kind]?.autofill ? kind : undefined;\n const created = after.rows.filter((row): row is CredentialVersionRow =>\n Boolean(\n row?.id &&\n row.status === 'active' &&\n !versions[row.id] &&\n (!createdKind || credentialVaultKind(row) === createdKind),\n ),\n );\n if (created.length === 1) return { kind: 'connected', credentialId: created[0].id ?? undefined };\n return { kind: 'unchanged' };\n}\n\n/**\n * How long after its save a hand-back that reached the app with no browser session waiting is still taken: the\n * session the app was killed during (Android kills it behind Custom Tabs, and the return page cold-starts it).\n */\nexport const PARKED_HANDBACK_MAX_AGE_MS = 30 * 60 * 1000;\n\n/**\n * The credential a PARKED hand-back names, when it may be taken as this request's answer; null otherwise.\n *\n * Anyone can open the app's scheme URL, and the vault snapshot the card took before the browser opened died with\n * the app, so \"the vault has it\" is not enough. The credential must be:\n * - an ACTIVE credential of the org (`rows` is a fresh read);\n * - one this request could have saved: for a site login, the login the card itself picks for the request with\n * that id named (its site or name; never another site's login or a catalog credential); for an autofill\n * request, an entry of its kind (a new one is named after what it holds, so nothing else can tie it to the\n * request); for a catalog connector, a connector credential, never a vault entry - the phone cannot resolve\n * the template, so a name alone cannot rule a connector credential in or out (see connectorConnectTarget);\n * - saved in the last PARKED_HANDBACK_MAX_AGE_MS, the stand-in for \"changed during the session\": every save on\n * the web page moves `updatedAt`, while an id lifted from anywhere else names a credential saved long ago.\n */\nexport function parkedHandbackCredential(\n rows: ReadonlyArray<CredentialVersionRow | null | undefined>,\n payload: ConnectorConnectPayload,\n credentialId: string | null | undefined,\n nowMs: number,\n): CredentialVersionRow | null {\n if (!credentialId) return null;\n const row = rows.find((r) => r?.id === credentialId && r.status === 'active');\n if (!row) return null;\n const kind = vaultKindOf(payload.connector);\n let fits: boolean;\n if (kind?.id === SITE_LOGIN_CONNECTOR) {\n fits = pickConnectorCredential(rows, { ...connectorConnectTarget(payload), credentialId })?.id === credentialId;\n } else if (kind) {\n fits = credentialVaultKind(row) === kind.id;\n } else {\n fits = !credentialVaultKind(row);\n }\n if (!fits) return null;\n const savedAt = credentialSavedAt(row);\n return savedAt > 0 && nowMs - savedAt <= PARKED_HANDBACK_MAX_AGE_MS ? row : null;\n}\n\n/** The primary action's accessibility label: the action, plus the card's name unless the action already says it. */\nexport function a11yActionLabel(actionLabel: string, name: string): string {\n const action = actionLabel.toLowerCase();\n const subject = name.toLowerCase().replace(/^your\\s+/, '');\n if (action.endsWith(subject) || name.toLowerCase().startsWith(action)) return actionLabel;\n return `${actionLabel} ${name}`;\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adminide-stack/yantra-mobile",
3
- "version": "12.0.69",
3
+ "version": "12.0.70-alpha.0",
4
4
  "description": "Sample core for higher packages to depend on",
5
5
  "license": "ISC",
6
6
  "author": "CDMBase LLC",
@@ -26,7 +26,7 @@
26
26
  "uuid": "^9.0.0"
27
27
  },
28
28
  "devDependencies": {
29
- "common": "^12.0.69"
29
+ "common": "12.0.70-alpha.0"
30
30
  },
31
31
  "peerDependencies": {
32
32
  "@admin-layout/gluestack-ui-mobile": "*",
@@ -42,7 +42,7 @@
42
42
  "@messenger-box/platform-mobile": "*",
43
43
  "@react-native-async-storage/async-storage": "*",
44
44
  "@react-navigation/native": "*",
45
- "common": "12.0.68",
45
+ "common": "12.0.69-alpha.25",
46
46
  "expo-constants": "*",
47
47
  "expo-secure-store": "*",
48
48
  "expo-web-browser": "*",
@@ -59,5 +59,5 @@
59
59
  "typescript": {
60
60
  "definition": "lib/index.d.ts"
61
61
  },
62
- "gitHead": "ca3b2528eb7f4ccbaad08a3c112c56399c2fa894"
62
+ "gitHead": "b15e1b2ed56e147d8258d1584830c85f91c37e9f"
63
63
  }