@@ -3,33 +3,24 @@ import { useAtomValue, useAtomSet } from "@effect/atom-react";
33import * as Exit from "effect/Exit" ;
44import * as AsyncResult from "effect/unstable/reactivity/AsyncResult" ;
55import { graphqlSourceAtom , updateGraphqlSource } from "./atoms" ;
6- import {
7- connectionsAtom ,
8- setSourceCredentialBinding ,
9- sourceCredentialBindingsAtom ,
10- } from "@executor-js/react/api/atoms" ;
11- import { useScope , useScopeStack } from "@executor-js/react/api/scope-context" ;
12- import { connectionWriteKeys , sourceWriteKeys } from "@executor-js/react/api/reactivity-keys" ;
6+ import { sourceCredentialBindingsAtom } from "@executor-js/react/api/atoms" ;
7+ import { useScope } from "@executor-js/react/api/scope-context" ;
8+ import { sourceWriteKeys } from "@executor-js/react/api/reactivity-keys" ;
139import { useSecretPickerSecrets } from "@executor-js/react/plugins/use-secret-picker-secrets" ;
14- import {
15- HttpCredentials ,
16- serializeHttpCredentials ,
17- serializeScopedHttpCredentials ,
18- type HttpCredentialsState ,
19- } from "@executor-js/react/plugins/http-credentials" ;
20- import {
21- effectiveCredentialBindingForScope ,
22- httpCredentialsFromConfiguredCredentialBindings ,
23- initialCredentialTargetScope ,
24- } from "@executor-js/react/plugins/credential-bindings" ;
10+ import { HttpCredentials } from "@executor-js/react/plugins/http-credentials" ;
11+ import { useHttpCredentialEditor } from "@executor-js/react/plugins/http-credential-state" ;
12+ import { initialCredentialTargetScope } from "@executor-js/react/plugins/credential-bindings" ;
2513import { slugifyNamespace , useSourceIdentity } from "@executor-js/react/plugins/source-identity" ;
2614import { useCredentialTargetScope } from "@executor-js/react/plugins/credential-target-scope" ;
2715import { Button } from "@executor-js/react/components/button" ;
2816import { FilterTabs } from "@executor-js/react/components/filter-tabs" ;
29- import { SourceOAuthConnectionControl } from "@executor-js/react/plugins/source-oauth-connection" ;
17+ import {
18+ SourceOAuthConnectionControl ,
19+ useSourceOAuthConnectionBinding ,
20+ } from "@executor-js/react/plugins/source-oauth-connection" ;
3021import { Badge } from "@executor-js/react/components/badge" ;
3122import { ScopeId } from "@executor-js/sdk/core" ;
32- import type { CredentialBindingRef } from "@executor-js/sdk/core " ;
23+ import type { SourceCredentialBindingRef } from "@executor-js/react/plugins/credential-bindings " ;
3324import { GraphqlSourceFields } from "./GraphqlSourceFields" ;
3425import { GRAPHQL_OAUTH_CONNECTION_SLOT , type GraphqlCredentialInput } from "../sdk/types" ;
3526import type { StoredGraphqlSource } from "../sdk/store" ;
@@ -44,15 +35,16 @@ type AuthMode = "none" | "oauth2";
4435function EditForm ( props : {
4536 sourceId : string ;
4637 initial : EditableSource ;
47- bindings : readonly CredentialBindingRef [ ] ;
38+ bindings : readonly SourceCredentialBindingRef [ ] ;
4839 onSave : ( ) => void ;
4940} ) {
5041 const displayScope = useScope ( ) ;
51- const scopeStack = useScopeStack ( ) ;
5242 const sourceScope = ScopeId . make ( props . initial . scope ) ;
53- const { credentialTargetScope , credentialScopeOptions } = useCredentialTargetScope ( {
43+ const credentialEditor = useHttpCredentialEditor ( {
5444 sourceScope,
55- initialTargetScope : initialCredentialTargetScope ( sourceScope , props . bindings ) ,
45+ headers : props . initial . headers ,
46+ queryParams : props . initial . queryParams ,
47+ bindings : props . bindings ,
5648 } ) ;
5749 const {
5850 credentialTargetScope : oauthCredentialTargetScope ,
@@ -62,61 +54,35 @@ function EditForm(props: {
6254 initialTargetScope : initialCredentialTargetScope ( sourceScope , props . bindings ) ,
6355 } ) ;
6456 const doUpdate = useAtomSet ( updateGraphqlSource , { mode : "promiseExit" } ) ;
65- const setBinding = useAtomSet ( setSourceCredentialBinding , { mode : "promise" } ) ;
6657 const secretList = useSecretPickerSecrets ( ) ;
67- const connectionsResult = useAtomValue ( connectionsAtom ( displayScope ) ) ;
6858
6959 const identity = useSourceIdentity ( {
7060 fallbackName : props . initial . name ,
7161 fallbackNamespace : props . initial . namespace ,
7262 } ) ;
7363 const [ endpoint , setEndpoint ] = useState ( props . initial . endpoint ) ;
74- const [ credentials , setCredentials ] = useState < HttpCredentialsState > ( ( ) =>
75- httpCredentialsFromConfiguredCredentialBindings ( {
76- headers : props . initial . headers ,
77- queryParams : props . initial . queryParams ,
78- bindings : props . bindings ,
79- } ) ,
80- ) ;
8164 const [ authMode , setAuthMode ] = useState < AuthMode > ( props . initial . auth . kind ) ;
8265 const [ saving , setSaving ] = useState ( false ) ;
8366 const [ error , setError ] = useState < string | null > ( null ) ;
84- const [ credentialsDirty , setCredentialsDirty ] = useState ( false ) ;
8567 const [ authDirty , setAuthDirty ] = useState ( false ) ;
8668
8769 const identityDirty = identity . name . trim ( ) !== props . initial . name . trim ( ) ;
8870 const metadataDirty = identityDirty || endpoint . trim ( ) !== props . initial . endpoint . trim ( ) ;
89- const dirty = metadataDirty || credentialsDirty || authDirty ;
71+ const dirty = metadataDirty || credentialEditor . credentialsDirty || authDirty ;
9072 const oauth2 = props . initial . auth . kind === "oauth2" ? props . initial . auth : null ;
91- const connections = AsyncResult . isSuccess ( connectionsResult ) ? connectionsResult . value : [ ] ;
92- const scopeRanks = new Map ( scopeStack . map ( ( scope , index ) => [ scope . id , index ] as const ) ) ;
93- const connectionBinding = oauth2
94- ? effectiveCredentialBindingForScope (
95- props . bindings ,
96- oauth2 . connectionSlot ,
97- oauthCredentialTargetScope ,
98- scopeRanks ,
99- )
100- : null ;
101- const boundConnectionId =
102- connectionBinding ?. value . kind === "connection" ? connectionBinding . value . connectionId : null ;
103- const isConnected =
104- boundConnectionId !== null &&
105- connections . some ( ( connection ) => connection . id === boundConnectionId ) ;
106- const oauthRequestCredentials = serializeHttpCredentials ( credentials ) ;
107-
108- const handleCredentialsChange = ( next : HttpCredentialsState ) => {
109- setCredentials ( next ) ;
110- setCredentialsDirty ( true ) ;
111- } ;
73+ const oauthConnection = useSourceOAuthConnectionBinding ( {
74+ pluginId : "graphql" ,
75+ sourceId : props . sourceId ,
76+ sourceScope,
77+ slotKey : oauth2 ?. connectionSlot ?? GRAPHQL_OAUTH_CONNECTION_SLOT ,
78+ targetScope : oauthCredentialTargetScope ,
79+ bindings : props . bindings ,
80+ } ) ;
11281
11382 const handleSave = async ( ) => {
11483 setSaving ( true ) ;
11584 setError ( null ) ;
116- const { headers, queryParams } = serializeScopedHttpCredentials (
117- credentials ,
118- credentialTargetScope ,
119- ) ;
85+ const { headers, queryParams } = credentialEditor . serializeScopedCredentials ( ) ;
12086 const payload : {
12187 sourceScope : ScopeId ;
12288 name ?: string ;
@@ -130,10 +96,10 @@ function EditForm(props: {
13096 name : metadataDirty ? identity . name . trim ( ) || undefined : undefined ,
13197 endpoint : metadataDirty ? endpoint . trim ( ) || undefined : undefined ,
13298 } ;
133- if ( credentialsDirty ) {
99+ if ( credentialEditor . credentialsDirty ) {
134100 payload . headers = headers ;
135101 payload . queryParams = queryParams as Record < string , GraphqlCredentialInput > ;
136- payload . credentialTargetScope = credentialTargetScope ;
102+ payload . credentialTargetScope = credentialEditor . credentialTargetScope ;
137103 }
138104 if ( authDirty ) {
139105 payload . auth =
@@ -146,7 +112,7 @@ function EditForm(props: {
146112 : GRAPHQL_OAUTH_CONNECTION_SLOT ,
147113 }
148114 : { kind : "none" } ;
149- payload . credentialTargetScope = credentialTargetScope ;
115+ payload . credentialTargetScope = credentialEditor . credentialTargetScope ;
150116 }
151117 const exit = await doUpdate ( {
152118 params : { scopeId : displayScope , namespace : props . sourceId } ,
@@ -160,7 +126,7 @@ function EditForm(props: {
160126 return ;
161127 }
162128
163- setCredentialsDirty ( false ) ;
129+ credentialEditor . resetCredentialsDirty ( ) ;
164130 setAuthDirty ( false ) ;
165131 props . onSave ( ) ;
166132 setSaving ( false ) ;
@@ -192,13 +158,13 @@ function EditForm(props: {
192158 />
193159
194160 < HttpCredentials . Root
195- credentials = { credentials }
196- onChange = { handleCredentialsChange }
161+ credentials = { credentialEditor . credentials }
162+ onChange = { credentialEditor . onCredentialsChange }
197163 existingSecrets = { secretList }
198164 sourceName = { identity . name }
199- targetScope = { credentialTargetScope }
200- credentialScopeOptions = { credentialScopeOptions }
201- bindingScopeOptions = { credentialScopeOptions }
165+ targetScope = { credentialEditor . credentialTargetScope }
166+ credentialScopeOptions = { credentialEditor . credentialScopeOptions }
167+ bindingScopeOptions = { credentialEditor . credentialScopeOptions }
202168 >
203169 < HttpCredentials . Headers />
204170 < HttpCredentials . QueryParams />
@@ -236,26 +202,13 @@ function EditForm(props: {
236202 endpoint = { endpoint . trim ( ) }
237203 tokenScope = { oauthCredentialTargetScope }
238204 onTokenScopeChange = { setOAuthCredentialTargetScope }
239- credentialScopeOptions = { credentialScopeOptions }
240- connectionId = { boundConnectionId }
205+ credentialScopeOptions = { credentialEditor . credentialScopeOptions }
206+ connectionId = { oauthConnection . connectionId }
241207 sourceLabel = { `${ identity . name . trim ( ) || props . initial . namespace || "GraphQL" } OAuth` }
242- headers = { oauthRequestCredentials . headers }
243- queryParams = { oauthRequestCredentials . queryParams }
244- isConnected = { isConnected }
245- onConnected = { async ( connectionId ) => {
246- await setBinding ( {
247- params : { scopeId : oauthCredentialTargetScope } ,
248- payload : {
249- targetScope : oauthCredentialTargetScope ,
250- pluginId : "graphql" ,
251- sourceId : props . sourceId ,
252- sourceScope,
253- slotKey : oauth2 . connectionSlot ,
254- value : { kind : "connection" , connectionId } ,
255- } ,
256- reactivityKeys : [ ...sourceWriteKeys , ...connectionWriteKeys ] ,
257- } ) ;
258- } }
208+ headers = { credentialEditor . requestCredentials . headers }
209+ queryParams = { credentialEditor . requestCredentials . queryParams }
210+ isConnected = { oauthConnection . isConnected }
211+ onConnected = { oauthConnection . onConnected }
259212 />
260213 ) }
261214
0 commit comments