History

chore: apply oxfmt across repo

main's format:check was red: 20 package.json files (publishConfig key ordering) plus two source files were not oxfmt-clean under 0.44.0. Run oxfmt to bring the tree back to a passing format:check so this branch can merge.

Rhys Sullivan committed 4 months ago

Commit 5d6b26c1 parent 778542b22 files · +64 −114Browse files

Unified · Split

22 files
  1. packages/core/cli/package.json +2 −2
  2. packages/core/config/package.json +2 −2
  3. packages/core/execution/package.json +2 −2
  4. packages/core/integrations-registry/package.json +2 −2
  5. packages/core/sdk/package.json +2 −2
  6. packages/core/vite-plugin/package.json +2 −2
  7. packages/kernel/core/package.json +2 −2
  8. packages/kernel/runtime-quickjs/package.json +2 −2
  9. packages/plugins/desktop-settings/package.json +2 −2
  10. packages/plugins/example/package.json +2 −2
  11. packages/plugins/file-secrets/package.json +2 −2
  12. packages/plugins/google/package.json +2 −2
  13. packages/plugins/graphql/package.json +2 −2
  14. packages/plugins/keychain/package.json +2 −2
  15. packages/plugins/mcp/package.json +2 −2
  16. packages/plugins/microsoft/package.json +2 −2
  17. packages/plugins/onepassword/package.json +2 −2
  18. packages/plugins/openapi/package.json +2 −2
  19. packages/plugins/toolkits/package.json +2 −2
  20. packages/plugins/workos-vault/package.json +2 −2
  21. packages/react/src/components/accounts-section.tsx +19 −59
  22. packages/react/src/plugins/oauth-reconnect.ts +5 −15
packages/core/cli/package.json+2−2
@@ -23,7 +23,6 @@ · 22 unmodified lines
23 ".": "./src/index.ts"23 ".": "./src/index.ts"
24 },24 },
25 "publishConfig": {25 "publishConfig": {
26 "access": "public",
27 "exports": {26 "exports": {
28 ".": {27 ".": {
29 "import": {28 "import": {
@@ -31,7 +30,8 @@ · 1 unmodified line
31 "default": "./dist/index.js"30 "default": "./dist/index.js"
32 }31 }
33 }32 }
34 }33 },
34 "access": "public"
35 },35 },
36 "scripts": {36 "scripts": {
37 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",37 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
packages/core/config/package.json+2−2
@@ -19,7 +19,6 @@ · 18 unmodified lines
19 ".": "./src/index.ts"19 ".": "./src/index.ts"
20 },20 },
21 "publishConfig": {21 "publishConfig": {
22 "access": "public",
23 "exports": {22 "exports": {
24 ".": {23 ".": {
25 "import": {24 "import": {
@@ -27,7 +26,8 @@ · 1 unmodified line
27 "default": "./dist/index.js"26 "default": "./dist/index.js"
28 }27 }
29 }28 }
30 }29 },
30 "access": "public"
31 },31 },
32 "scripts": {32 "scripts": {
33 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",33 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
packages/core/execution/package.json+2−2
@@ -20,7 +20,6 @@ · 19 unmodified lines
20 "./promise": "./src/promise.ts"20 "./promise": "./src/promise.ts"
21 },21 },
22 "publishConfig": {22 "publishConfig": {
23 "access": "public",
24 "exports": {23 "exports": {
25 ".": {24 ".": {
26 "import": {25 "import": {
@@ -34,7 +33,8 @@ · 7 unmodified lines
34 "default": "./dist/core.js"33 "default": "./dist/core.js"
35 }34 }
36 }35 }
37 }36 },
37 "access": "public"
38 },38 },
39 "scripts": {39 "scripts": {
40 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",40 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
packages/core/integrations-registry/package.json+2−2
@@ -20,7 +20,6 @@ · 19 unmodified lines
20 ".": "./src/index.ts"20 ".": "./src/index.ts"
21 },21 },
22 "publishConfig": {22 "publishConfig": {
23 "access": "public",
24 "exports": {23 "exports": {
25 ".": {24 ".": {
26 "import": {25 "import": {
@@ -28,7 +27,8 @@ · 1 unmodified line
28 "default": "./dist/index.js"27 "default": "./dist/index.js"
29 }28 }
30 }29 }
31 }30 },
31 "access": "public"
32 },32 },
33 "scripts": {33 "scripts": {
34 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",34 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
packages/core/sdk/package.json+2−2
@@ -28,7 +28,6 @@ · 27 unmodified lines
28 "./public-origin": "./src/public-origin.ts"28 "./public-origin": "./src/public-origin.ts"
29 },29 },
30 "publishConfig": {30 "publishConfig": {
31 "access": "public",
32 "exports": {31 "exports": {
33 ".": {32 ".": {
34 "import": {33 "import": {
@@ -84,7 +83,8 @@ · 49 unmodified lines
84 "default": "./dist/public-origin.js"83 "default": "./dist/public-origin.js"
85 }84 }
86 }85 }
87 }86 },
87 "access": "public"
88 },88 },
89 "scripts": {89 "scripts": {
90 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",90 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
packages/core/vite-plugin/package.json+2−2
@@ -23,7 +23,6 @@ · 22 unmodified lines
23 }23 }
24 },24 },
25 "publishConfig": {25 "publishConfig": {
26 "access": "public",
27 "exports": {26 "exports": {
28 ".": {27 ".": {
29 "import": {28 "import": {
@@ -31,7 +30,8 @@ · 1 unmodified line
31 "default": "./dist/index.js"30 "default": "./dist/index.js"
32 }31 }
33 }32 }
34 }33 },
34 "access": "public"
35 },35 },
36 "scripts": {36 "scripts": {
37 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",37 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
packages/kernel/core/package.json+2−2
@@ -19,7 +19,6 @@ · 18 unmodified lines
19 ".": "./src/index.ts"19 ".": "./src/index.ts"
20 },20 },
21 "publishConfig": {21 "publishConfig": {
22 "access": "public",
23 "exports": {22 "exports": {
24 ".": {23 ".": {
25 "import": {24 "import": {
@@ -27,7 +26,8 @@ · 1 unmodified line
27 "default": "./dist/index.js"26 "default": "./dist/index.js"
28 }27 }
29 }28 }
30 }29 },
30 "access": "public"
31 },31 },
32 "scripts": {32 "scripts": {
33 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",33 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
packages/kernel/runtime-quickjs/package.json+2−2
@@ -19,7 +19,6 @@ · 18 unmodified lines
19 ".": "./src/index.ts"19 ".": "./src/index.ts"
20 },20 },
21 "publishConfig": {21 "publishConfig": {
22 "access": "public",
23 "exports": {22 "exports": {
24 ".": {23 ".": {
25 "import": {24 "import": {
@@ -27,7 +26,8 @@ · 1 unmodified line
27 "default": "./dist/index.js"26 "default": "./dist/index.js"
28 }27 }
29 }28 }
30 }29 },
30 "access": "public"
31 },31 },
32 "scripts": {32 "scripts": {
33 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",33 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
packages/plugins/desktop-settings/package.json+2−2
@@ -20,7 +20,6 @@ · 19 unmodified lines
20 "./client": "./src/client.tsx"20 "./client": "./src/client.tsx"
21 },21 },
22 "publishConfig": {22 "publishConfig": {
23 "access": "public",
24 "exports": {23 "exports": {
25 "./server": {24 "./server": {
26 "import": {25 "import": {
@@ -34,7 +33,8 @@ · 7 unmodified lines
34 "default": "./dist/client.js"33 "default": "./dist/client.js"
35 }34 }
36 }35 }
37 }36 },
37 "access": "public"
38 },38 },
39 "scripts": {39 "scripts": {
40 "build": "tsup",40 "build": "tsup",
packages/plugins/example/package.json+2−2
@@ -21,7 +21,6 @@ · 20 unmodified lines
21 "./shared": "./src/shared.ts"21 "./shared": "./src/shared.ts"
22 },22 },
23 "publishConfig": {23 "publishConfig": {
24 "access": "public",
25 "exports": {24 "exports": {
26 "./server": {25 "./server": {
27 "import": {26 "import": {
@@ -41,7 +40,8 @@ · 13 unmodified lines
41 "default": "./dist/shared.js"40 "default": "./dist/shared.js"
42 }41 }
43 }42 }
44 }43 },
44 "access": "public"
45 },45 },
46 "scripts": {46 "scripts": {
47 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",47 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
packages/plugins/file-secrets/package.json+2−2
@@ -20,7 +20,6 @@ · 19 unmodified lines
20 "./promise": "./src/promise.ts"20 "./promise": "./src/promise.ts"
21 },21 },
22 "publishConfig": {22 "publishConfig": {
23 "access": "public",
24 "exports": {23 "exports": {
25 ".": {24 ".": {
26 "import": {25 "import": {
@@ -34,7 +33,8 @@ · 7 unmodified lines
34 "default": "./dist/core.js"33 "default": "./dist/core.js"
35 }34 }
36 }35 }
37 }36 },
37 "access": "public"
38 },38 },
39 "scripts": {39 "scripts": {
40 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",40 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
packages/plugins/google/package.json+2−2
@@ -23,7 +23,6 @@ · 22 unmodified lines
23 "./client": "./src/react/plugin-client.tsx"23 "./client": "./src/react/plugin-client.tsx"
24 },24 },
25 "publishConfig": {25 "publishConfig": {
26 "access": "public",
27 "exports": {26 "exports": {
28 ".": {27 ".": {
29 "import": {28 "import": {
@@ -43,7 +42,8 @@ · 13 unmodified lines
43 "default": "./dist/client.js"42 "default": "./dist/client.js"
44 }43 }
45 }44 }
46 }45 },
46 "access": "public"
47 },47 },
48 "scripts": {48 "scripts": {
49 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",49 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
packages/plugins/graphql/package.json+2−2
@@ -25,7 +25,6 @@ · 24 unmodified lines
25 "./testing": "./src/testing/index.ts"25 "./testing": "./src/testing/index.ts"
26 },26 },
27 "publishConfig": {27 "publishConfig": {
28 "access": "public",
29 "exports": {28 "exports": {
30 ".": {29 ".": {
31 "import": {30 "import": {
@@ -51,7 +50,8 @@ · 19 unmodified lines
51 "default": "./dist/testing.js"50 "default": "./dist/testing.js"
52 }51 }
53 }52 }
54 }53 },
54 "access": "public"
55 },55 },
56 "scripts": {56 "scripts": {
57 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",57 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
packages/plugins/keychain/package.json+2−2
@@ -20,7 +20,6 @@ · 19 unmodified lines
20 "./promise": "./src/promise.ts"20 "./promise": "./src/promise.ts"
21 },21 },
22 "publishConfig": {22 "publishConfig": {
23 "access": "public",
24 "exports": {23 "exports": {
25 ".": {24 ".": {
26 "import": {25 "import": {
@@ -34,7 +33,8 @@ · 7 unmodified lines
34 "default": "./dist/core.js"33 "default": "./dist/core.js"
35 }34 }
36 }35 }
37 }36 },
37 "access": "public"
38 },38 },
39 "scripts": {39 "scripts": {
40 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",40 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
packages/plugins/mcp/package.json+2−2
@@ -25,7 +25,6 @@ · 24 unmodified lines
25 "./testing": "./src/testing/index.ts"25 "./testing": "./src/testing/index.ts"
26 },26 },
27 "publishConfig": {27 "publishConfig": {
28 "access": "public",
29 "exports": {28 "exports": {
30 ".": {29 ".": {
31 "import": {30 "import": {
@@ -51,7 +50,8 @@ · 19 unmodified lines
51 "default": "./dist/testing.js"50 "default": "./dist/testing.js"
52 }51 }
53 }52 }
54 }53 },
54 "access": "public"
55 },55 },
56 "scripts": {56 "scripts": {
57 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",57 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
packages/plugins/microsoft/package.json+2−2
@@ -23,7 +23,6 @@ · 22 unmodified lines
23 "./client": "./src/react/plugin-client.tsx"23 "./client": "./src/react/plugin-client.tsx"
24 },24 },
25 "publishConfig": {25 "publishConfig": {
26 "access": "public",
27 "exports": {26 "exports": {
28 ".": {27 ".": {
29 "import": {28 "import": {
@@ -43,7 +42,8 @@ · 13 unmodified lines
43 "default": "./dist/client.js"42 "default": "./dist/client.js"
44 }43 }
45 }44 }
46 }45 },
46 "access": "public"
47 },47 },
48 "scripts": {48 "scripts": {
49 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",49 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
packages/plugins/onepassword/package.json+2−2
@@ -23,7 +23,6 @@ · 22 unmodified lines
23 "./client": "./src/react/plugin-client.tsx"23 "./client": "./src/react/plugin-client.tsx"
24 },24 },
25 "publishConfig": {25 "publishConfig": {
26 "access": "public",
27 "exports": {26 "exports": {
28 ".": {27 ".": {
29 "import": {28 "import": {
@@ -43,7 +42,8 @@ · 13 unmodified lines
43 "default": "./dist/client.js"42 "default": "./dist/client.js"
44 }43 }
45 }44 }
46 }45 },
46 "access": "public"
47 },47 },
48 "scripts": {48 "scripts": {
49 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",49 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
packages/plugins/openapi/package.json+2−2
@@ -25,7 +25,6 @@ · 24 unmodified lines
25 "./testing": "./src/testing/index.ts"25 "./testing": "./src/testing/index.ts"
26 },26 },
27 "publishConfig": {27 "publishConfig": {
28 "access": "public",
29 "exports": {28 "exports": {
30 ".": {29 ".": {
31 "import": {30 "import": {
@@ -51,7 +50,8 @@ · 19 unmodified lines
51 "default": "./dist/testing.js"50 "default": "./dist/testing.js"
52 }51 }
53 }52 }
54 }53 },
54 "access": "public"
55 },55 },
56 "scripts": {56 "scripts": {
57 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",57 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
packages/plugins/toolkits/package.json+2−2
@@ -21,7 +21,6 @@ · 20 unmodified lines
21 "./shared": "./src/shared.ts"21 "./shared": "./src/shared.ts"
22 },22 },
23 "publishConfig": {23 "publishConfig": {
24 "access": "public",
25 "exports": {24 "exports": {
26 "./server": {25 "./server": {
27 "import": {26 "import": {
@@ -41,7 +40,8 @@ · 13 unmodified lines
41 "default": "./dist/shared.js"40 "default": "./dist/shared.js"
42 }41 }
43 }42 }
44 }43 },
44 "access": "public"
45 },45 },
46 "scripts": {46 "scripts": {
47 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",47 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
packages/plugins/workos-vault/package.json+2−2
@@ -23,7 +23,6 @@ · 22 unmodified lines
23 "./testing": "./src/sdk/testing.ts"23 "./testing": "./src/sdk/testing.ts"
24 },24 },
25 "publishConfig": {25 "publishConfig": {
26 "access": "public",
27 "exports": {26 "exports": {
28 ".": {27 ".": {
29 "import": {28 "import": {
@@ -43,7 +42,8 @@ · 13 unmodified lines
43 "default": "./dist/testing.js"42 "default": "./dist/testing.js"
44 }43 }
45 }44 }
46 }45 },
46 "access": "public"
47 },47 },
48 "scripts": {48 "scripts": {
49 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",49 "build": "tsup && (tsc --declaration --emitDeclarationOnly --outDir dist --rootDir src || true)",
packages/react/src/components/accounts-section.tsx+19−59
@@ -2,11 +2,7 @@ import { useEffect, useMemo, useState } from "react"; · 1 unmodified line
2import { useAtomValue, useAtomSet } from "@effect/atom-react";2import { useAtomValue, useAtomSet } from "@effect/atom-react";
3import * as AsyncResult from "effect/unstable/reactivity/AsyncResult";3import * as AsyncResult from "effect/unstable/reactivity/AsyncResult";
4import * as Exit from "effect/Exit";4import * as Exit from "effect/Exit";
5import {5import { IntegrationSlug, type Connection, type Owner } from "@executor-js/sdk/shared";
6 IntegrationSlug,
7 type Connection,
8 type Owner,
9} from "@executor-js/sdk/shared";
10import type { IntegrationAccountHandoff } from "@executor-js/sdk/client";6import type { IntegrationAccountHandoff } from "@executor-js/sdk/client";
11import { toast } from "sonner";7import { toast } from "sonner";
12 8
@@ -84,10 +80,7 @@ function AccountRow(props: { · 71 unmodified lines
84 <CardStackEntryTitle className="flex min-w-0 items-center gap-2">80 <CardStackEntryTitle className="flex min-w-0 items-center gap-2">
85 <span className="truncate">{displayLabel}</span>81 <span className="truncate">{displayLabel}</span>
86 {needsReconsent ? (82 {needsReconsent ? (
87 <Badge83 <Badge variant="outline" className="shrink-0 border-border text-muted-foreground">
88 variant="outline"
89 className="shrink-0 border-border text-muted-foreground"
90 >
91 Reconnect to grant access84 Reconnect to grant access
92 </Badge>85 </Badge>
93 ) : null}86 ) : null}
@@ -99,8 +92,7 @@ function AccountRow(props: { · 5 unmodified lines
99 ) : null}92 ) : null}
100 {needsReconsent ? (93 {needsReconsent ? (
101 <CardStackEntryDescription className="mt-1 text-xs text-muted-foreground">94 <CardStackEntryDescription className="mt-1 text-xs text-muted-foreground">
102 This connection wasn't granted all the access this integration now95 This connection wasn't granted all the access this integration now needs.
103 needs.
104 </CardStackEntryDescription>96 </CardStackEntryDescription>
105 ) : null}97 ) : null}
106 </CardStackEntryContent>98 </CardStackEntryContent>
@@ -129,11 +121,7 @@ function AccountRow(props: { · 22 unmodified lines
129 <DropdownMenuItem className="text-sm" onClick={props.onReconnect}>121 <DropdownMenuItem className="text-sm" onClick={props.onReconnect}>
130 Reconnect122 Reconnect
131 </DropdownMenuItem>123 </DropdownMenuItem>
132 <DropdownMenuItem124 <DropdownMenuItem variant="destructive" className="text-sm" onClick={props.onRemove}>
133 variant="destructive"
134 className="text-sm"
135 onClick={props.onRemove}
136 >
137 Remove125 Remove
138 </DropdownMenuItem>126 </DropdownMenuItem>
139 </DropdownMenuContent>127 </DropdownMenuContent>
@@ -155,9 +143,7 @@ function OwnerAccounts(props: { · 15 unmodified lines
155 readonly declaredScopes: readonly string[] | undefined;143 readonly declaredScopes: readonly string[] | undefined;
156}) {144}) {
157 const { integration, owner } = props;145 const { integration, owner } = props;
158 const connections = useAtomValue(146 const connections = useAtomValue(connectionsForIntegrationAtom({ integration, owner }));
159 connectionsForIntegrationAtom({ integration, owner }),
160 );
161 const doRemove = useAtomSet(removeConnectionOptimistic(owner), {147 const doRemove = useAtomSet(removeConnectionOptimistic(owner), {
162 mode: "promiseExit",148 mode: "promiseExit",
163 });149 });
@@ -174,9 +160,7 @@ function OwnerAccounts(props: { · 10 unmodified lines
174 startErrorMessage: "Failed to reconnect",160 startErrorMessage: "Failed to reconnect",
175 });161 });
176 162
177 const rows: readonly Connection[] = AsyncResult.isSuccess(connections)163 const rows: readonly Connection[] = AsyncResult.isSuccess(connections) ? connections.value : [];
178 ? connections.value
179 : [];
180 if (rows.length === 0) return null;164 if (rows.length === 0) return null;
181 165
182 const handleReconnect = async (connection: Connection) => {166 const handleReconnect = async (connection: Connection) => {
@@ -185,8 +169,7 @@ function OwnerAccounts(props: { · 2 unmodified lines
185 if (reconnectMode(connection) === "oauth") {169 if (reconnectMode(connection) === "oauth") {
186 const method = props.methods.find(170 const method = props.methods.find(
187 (candidate: AuthMethod) =>171 (candidate: AuthMethod) =>
188 candidate.kind === "oauth" &&172 candidate.kind === "oauth" && String(candidate.template) === String(connection.template),
189 String(candidate.template) === String(connection.template),
190 );173 );
191 if (174 if (
192 method?.oauth?.supportsDynamicRegistration === true ||175 method?.oauth?.supportsDynamicRegistration === true ||
@@ -293,18 +276,13 @@ function OwnerAccounts(props: { · 100 unmodified lines
293 276
294 return (277 return (
295 <CardStack>278 <CardStack>
296 {props.showOwnerLabels ? (279 {props.showOwnerLabels ? <CardStackHeader>{ownerLabel(owner)}</CardStackHeader> : null}
297 <CardStackHeader>{ownerLabel(owner)}</CardStackHeader>
298 ) : null}
299 <CardStackContent>280 <CardStackContent>
300 {rows.map((connection: Connection) => (281 {rows.map((connection: Connection) => (
301 <AccountRow282 <AccountRow
302 key={`${connection.owner}:${connection.integration}:${connection.name}`}283 key={`${connection.owner}:${connection.integration}:${connection.name}`}
303 connection={connection}284 connection={connection}
304 needsReconsent={connectionNeedsReconsent(285 needsReconsent={connectionNeedsReconsent(connection, props.declaredScopes)}
305 connection,
306 props.declaredScopes,
307 )}
308 showOwnerLabel={props.showOwnerLabels}286 showOwnerLabel={props.showOwnerLabels}
309 onEdit={() => props.onEdit(connection)}287 onEdit={() => props.onEdit(connection)}
310 onReconnect={() => void handleReconnect(connection)}288 onReconnect={() => void handleReconnect(connection)}
@@ -335,14 +313,10 @@ export function AccountsSection(props: { · 24 unmodified lines
335 removeCustomMethod,313 removeCustomMethod,
336 } = props;314 } = props;
337 const [adding, setAdding] = useState(false);315 const [adding, setAdding] = useState(false);
338 const [editingConnection, setEditingConnection] = useState<Connection | null>(316 const [editingConnection, setEditingConnection] = useState<Connection | null>(null);
339 null,317 const [reconnectHandoff, setReconnectHandoff] = useState<IntegrationAccountHandoff | null>(null);
340 );
341 const [reconnectHandoff, setReconnectHandoff] =
342 useState<IntegrationAccountHandoff | null>(null);
343 const ownerDisplay = useOwnerDisplay();318 const ownerDisplay = useOwnerDisplay();
344 const canAddConnection =319 const canAddConnection = methods.length > 0 || createCustomMethod !== undefined;
345 methods.length > 0 || createCustomMethod !== undefined;
346 320
347 useEffect(() => {321 useEffect(() => {
348 if (accountHandoff) {322 if (accountHandoff) {
@@ -364,9 +338,7 @@ export function AccountsSection(props: { · 15 unmodified lines
364 338
365 // Read both owners to decide between the grouped view and the empty CTA. The339 // Read both owners to decide between the grouped view and the empty CTA. The
366 // grouped sub-components re-read these (effect-atom dedupes) and self-hide.340 // grouped sub-components re-read these (effect-atom dedupes) and self-hide.
367 const orgConnections = useAtomValue(341 const orgConnections = useAtomValue(connectionsForIntegrationAtom({ integration, owner: "org" }));
368 connectionsForIntegrationAtom({ integration, owner: "org" }),
369 );
370 const userConnections = useAtomValue(342 const userConnections = useAtomValue(
371 connectionsForIntegrationAtom({ integration, owner: "user" }),343 connectionsForIntegrationAtom({ integration, owner: "user" }),
372 );344 );
@@ -377,18 +349,12 @@ export function AccountsSection(props: { · 4 unmodified lines
377 useAtomSet(addConnectionOptimistic("user"));349 useAtomSet(addConnectionOptimistic("user"));
378 350
379 const totalCount = useMemo(() => {351 const totalCount = useMemo(() => {
380 const orgRows = AsyncResult.isSuccess(orgConnections)352 const orgRows = AsyncResult.isSuccess(orgConnections) ? orgConnections.value.length : 0;
381 ? orgConnections.value.length353 const userRows = AsyncResult.isSuccess(userConnections) ? userConnections.value.length : 0;
382 : 0;
383 const userRows = AsyncResult.isSuccess(userConnections)
384 ? userConnections.value.length
385 : 0;
386 return orgRows + userRows;354 return orgRows + userRows;
387 }, [orgConnections, userConnections]);355 }, [orgConnections, userConnections]);
388 356
389 const loading =357 const loading = !AsyncResult.isSuccess(orgConnections) && !AsyncResult.isSuccess(userConnections);
390 !AsyncResult.isSuccess(orgConnections) &&
391 !AsyncResult.isSuccess(userConnections);
392 358
393 const modalState = reconnectHandoff ?? accountHandoff;359 const modalState = reconnectHandoff ?? accountHandoff;
394 const modal = (360 const modal = (
@@ -420,9 +386,7 @@ export function AccountsSection(props: { · 25 unmodified lines
420 onClick={() => {386 onClick={() => {
421 trackEvent("connection_add_opened", {387 trackEvent("connection_add_opened", {
422 integration_slug: String(integration),388 integration_slug: String(integration),
423 has_oauth_method: methods.some(389 has_oauth_method: methods.some((m: AuthMethod) => m.kind === "oauth"),
424 (m: AuthMethod) => m.kind === "oauth",
425 ),
426 has_api_key_method: methods.some(390 has_api_key_method: methods.some(
427 (m: AuthMethod) => m.kind !== "oauth" && m.kind !== "none",391 (m: AuthMethod) => m.kind !== "oauth" && m.kind !== "none",
428 ),392 ),
@@ -442,9 +406,7 @@ export function AccountsSection(props: { · 13 unmodified lines
442 </div>406 </div>
443 ) : totalCount === 0 ? (407 ) : totalCount === 0 ? (
444 <div className="rounded-lg border border-dashed border-border/60 px-6 py-8 text-center">408 <div className="rounded-lg border border-dashed border-border/60 px-6 py-8 text-center">
445 <p className="text-sm font-medium text-foreground">409 <p className="text-sm font-medium text-foreground">No connections yet</p>
446 No connections yet
447 </p>
448 <p className="mt-1 text-sm text-muted-foreground">410 <p className="mt-1 text-sm text-muted-foreground">
449 Add a connection to make this integration's tools available.411 Add a connection to make this integration's tools available.
450 </p>412 </p>
@@ -455,9 +417,7 @@ export function AccountsSection(props: { · 4 unmodified lines
455 onClick={() => {417 onClick={() => {
456 trackEvent("connection_add_opened", {418 trackEvent("connection_add_opened", {
457 integration_slug: String(integration),419 integration_slug: String(integration),
458 has_oauth_method: methods.some(420 has_oauth_method: methods.some((m: AuthMethod) => m.kind === "oauth"),
459 (m: AuthMethod) => m.kind === "oauth",
460 ),
461 has_api_key_method: methods.some(421 has_api_key_method: methods.some(
462 (m: AuthMethod) => m.kind !== "oauth" && m.kind !== "none",422 (m: AuthMethod) => m.kind !== "oauth" && m.kind !== "none",
463 ),423 ),
packages/react/src/plugins/oauth-reconnect.ts+5−15
@@ -28,9 +28,7 @@ export function reconnectMode(connection: Connection): ReconnectMode { · 27 unmodified lines
28 * connection are exactly the branded types `oauth.start` expects, so the same28 * connection are exactly the branded types `oauth.start` expects, so the same
29 * connection (owner/integration/name) is re-minted with a fresh refresh token29 * connection (owner/integration/name) is re-minted with a fresh refresh token
30 * and the widened scope union. Returns null for a non-OAuth connection. */30 * and the widened scope union. Returns null for a non-OAuth connection. */
31export function oauthReconnectPayload(31export function oauthReconnectPayload(connection: Connection): OAuthStartPayload | null {
32 connection: Connection,
33): OAuthStartPayload | null {
34 if (connection.oauthClient == null) return null;32 if (connection.oauthClient == null) return null;
35 return {33 return {
36 client: connection.oauthClient,34 client: connection.oauthClient,
@@ -61,8 +59,7 @@ const OAUTH_SCOPE_ALIASES: Readonly<Record<string, string>> = { · 24 unmodified lines
61 "https://www.googleapis.com/auth/userinfo.profile": "profile",59 "https://www.googleapis.com/auth/userinfo.profile": "profile",
62};60};
63 61
64const canonicalScope = (scope: string): string =>62const canonicalScope = (scope: string): string => OAUTH_SCOPE_ALIASES[scope] ?? scope;
65 OAUTH_SCOPE_ALIASES[scope] ?? scope;
66 63
67/** Normalize a scope list: trim, canonicalize known provider aliases, drop64/** Normalize a scope list: trim, canonicalize known provider aliases, drop
68 * empties, de-dupe (order-preserving). A scope set is compared as a SET —65 * empties, de-dupe (order-preserving). A scope set is compared as a SET —
@@ -94,12 +91,8 @@ export function missingScopes( · 25 unmodified lines
94 91
95/** The scopes a connection was actually GRANTED, parsed from its space-delimited92/** The scopes a connection was actually GRANTED, parsed from its space-delimited
96 * `oauthScope` record. Empty for static creds / when the AS omitted scope. */93 * `oauthScope` record. Empty for static creds / when the AS omitted scope. */
97export function connectionGrantedScopes(94export function connectionGrantedScopes(connection: Connection): readonly string[] {
98 connection: Connection,95 return connection.oauthScope ? connection.oauthScope.split(/\s+/).filter(Boolean) : [];
99): readonly string[] {
100 return connection.oauthScope
101 ? connection.oauthScope.split(/\s+/).filter(Boolean)
102 : [];
103}96}
104 97
105/** Whether an OAuth connection must RECONNECT to grant newly-needed access: the98/** Whether an OAuth connection must RECONNECT to grant newly-needed access: the
@@ -113,10 +106,7 @@ export function connectionNeedsReconsent( · 7 unmodified lines
113 declaredScopes: readonly string[] | undefined,106 declaredScopes: readonly string[] | undefined,
114): boolean {107): boolean {
115 if (connection.oauthClient == null) return false;108 if (connection.oauthClient == null) return false;
116 return (109 return missingScopes(declaredScopes, connectionGrantedScopes(connection)).length > 0;
117 missingScopes(declaredScopes, connectionGrantedScopes(connection)).length >
118 0
119 );
120}110}
121 111
122/** The scopes that count as REQUIRED for a connection to be considered fully112/** The scopes that count as REQUIRED for a connection to be considered fully