11import pc from 'picocolors' ;
22import ora from 'ora' ;
33import { program } from 'commander' ;
4- import { BaseCommandOptions } from '../../core/types/types.js ' ;
4+ import type { FederatedGraph , Subgraph , WhoAmIResponse } from '@wundergraph/cosmo-connect/dist/platform/v1/platform_pb ' ;
55import { config } from '../../core/config.js' ;
6+ import { BaseCommandOptions } from '../../core/types/types.js' ;
67import { waitForKeyPress , rainbow } from '../../utils.js' ;
7- import { fetchUserInfo , checkExistingOnboarding } from './api.js' ;
88import type { UserInfo } from './types.js' ;
9+ import {
10+ cleanUpFederatedGraph ,
11+ createFederatedGraph ,
12+ fetchFederatedGraphByName ,
13+ fetchUserInfo ,
14+ checkExistingOnboarding ,
15+ } from './api.js' ;
916import {
1017 checkDockerReadiness ,
1118 clearScreen ,
@@ -23,6 +30,177 @@ function printHello() {
2330 console . log ( 'This command will guide you through the inital setup to create your first federated graph.' ) ;
2431}
2532
33+ async function handleGetFederatedGraphResponse (
34+ client : BaseCommandOptions [ 'client' ] ,
35+ {
36+ onboarding,
37+ userInfo,
38+ } : {
39+ onboarding : {
40+ finishedAt ?: string ;
41+ } ;
42+ userInfo : UserInfo ;
43+ } ,
44+ ) {
45+ function retryFn ( ) {
46+ resetScreen ( userInfo ) ;
47+ return handleGetFederatedGraphResponse ( client , {
48+ onboarding,
49+ userInfo,
50+ } ) ;
51+ }
52+
53+ const spinner = ora ( ) . start ( ) ;
54+ const getFederatedGraphResponse = await fetchFederatedGraphByName ( client , {
55+ name : config . demoGraphName ,
56+ namespace : config . demoNamespace ,
57+ } ) ;
58+
59+ if ( getFederatedGraphResponse . error ) {
60+ spinner . fail ( `Failed to retrieve graph information ${ getFederatedGraphResponse . error } ` ) ;
61+ await waitForKeyPress (
62+ {
63+ r : retryFn ,
64+ R : retryFn ,
65+ } ,
66+ 'Hit [r] to refresh. CTRL+C to quit' ,
67+ ) ;
68+ return ;
69+ }
70+
71+ if ( getFederatedGraphResponse . data ?. graph ) {
72+ spinner . succeed ( `Federated graph ${ pc . bold ( getFederatedGraphResponse . data ?. graph ?. name ) } exists.` ) ;
73+ } else {
74+ spinner . stop ( ) ;
75+ }
76+
77+ return getFederatedGraphResponse . data ;
78+ }
79+
80+ async function cleanupFederatedGraph (
81+ client : BaseCommandOptions [ 'client' ] ,
82+ {
83+ graphData,
84+ userInfo,
85+ } : {
86+ graphData : {
87+ graph : FederatedGraph ;
88+ subgraphs : Subgraph [ ] ;
89+ } ;
90+ userInfo : UserInfo ;
91+ } ,
92+ ) {
93+ function retryFn ( ) {
94+ resetScreen ( userInfo ) ;
95+ cleanupFederatedGraph ( client , { graphData, userInfo } ) ;
96+ }
97+
98+ const spinner = ora ( ) . start ( `Removing federated graph ${ pc . bold ( graphData . graph . name ) } …` ) ;
99+ const deleteResponse = await cleanUpFederatedGraph ( client , graphData ) ;
100+
101+ if ( deleteResponse . error ) {
102+ spinner . fail ( `Removing federated graph ${ graphData . graph . name } failed.` ) ;
103+ console . error ( deleteResponse . error . message ) ;
104+
105+ await waitForKeyPress (
106+ {
107+ Enter : ( ) => undefined ,
108+ r : retryFn ,
109+ R : retryFn ,
110+ } ,
111+ `Failed to delete the federated graph ${ pc . bold ( graphData . graph . name ) } . [ENTER] to continue, [r] to retry. CTRL+C to quit.` ,
112+ ) ;
113+ }
114+
115+ spinner . succeed ( `Federated graph ${ pc . bold ( graphData . graph . name ) } removed.` ) ;
116+ }
117+
118+ async function handleCreateFederatedGraphResponse (
119+ client : BaseCommandOptions [ 'client' ] ,
120+ {
121+ onboarding,
122+ userInfo,
123+ } : {
124+ onboarding : {
125+ finishedAt ?: string ;
126+ } ;
127+ userInfo : UserInfo ;
128+ } ,
129+ ) {
130+ function retryFn ( ) {
131+ resetScreen ( userInfo ) ;
132+ handleCreateFederatedGraphResponse ( client , { onboarding, userInfo } ) ;
133+ }
134+
135+ const routingUrl = new URL ( 'graphql' , 'http://localhost' ) ;
136+ routingUrl . port = String ( config . demoRouterPort ) ;
137+
138+ const federatedGraphSpinner = ora ( ) . start ( ) ;
139+ const createGraphResponse = await createFederatedGraph ( client , {
140+ name : config . demoGraphName ,
141+ namespace : config . demoNamespace ,
142+ labelMatcher : config . demoLabelMatcher ,
143+ routingUrl,
144+ } ) ;
145+
146+ if ( createGraphResponse . error ) {
147+ federatedGraphSpinner . fail ( createGraphResponse . error . message ) ;
148+
149+ await waitForKeyPress (
150+ {
151+ r : retryFn ,
152+ R : retryFn ,
153+ } ,
154+ 'Hit [r] to refresh. CTRL+C to quit' ,
155+ ) ;
156+ return ;
157+ }
158+
159+ federatedGraphSpinner . succeed ( `Federated graph ${ pc . bold ( 'demo' ) } succesfully created.` ) ;
160+ }
161+
162+ async function handleStep2 (
163+ opts : BaseCommandOptions ,
164+ {
165+ onboarding,
166+ userInfo,
167+ } : {
168+ onboarding : {
169+ finishedAt ?: string ;
170+ } ;
171+ userInfo : UserInfo ;
172+ } ,
173+ ) {
174+ const graphData = await handleGetFederatedGraphResponse ( opts . client , {
175+ onboarding,
176+ userInfo,
177+ } ) ;
178+
179+ const graph = graphData ?. graph ;
180+ const subgraphs = graphData ?. subgraphs ?? [ ] ;
181+ if ( graph ) {
182+ const cleanupFn = async ( ) =>
183+ await cleanupFederatedGraph ( opts . client , {
184+ graphData : { graph, subgraphs } ,
185+ userInfo,
186+ } ) ;
187+ await waitForKeyPress (
188+ {
189+ Enter : ( ) => undefined ,
190+ d : cleanupFn ,
191+ D : cleanupFn ,
192+ } ,
193+ 'Hit [ENTER] to continue or [d] to delete the federated graph and its subgraphs to start over. CTRL+C to quit.' ,
194+ ) ;
195+ return ;
196+ }
197+
198+ await handleCreateFederatedGraphResponse ( opts . client , {
199+ onboarding,
200+ userInfo,
201+ } ) ;
202+ }
203+
26204async function handleGetOnboardingResponse ( client : BaseCommandOptions [ 'client' ] , userInfo : UserInfo ) {
27205 const onboardingCheck = await checkExistingOnboarding ( client ) ;
28206
@@ -53,7 +231,7 @@ async function handleGetOnboardingResponse(client: BaseCommandOptions['client'],
53231}
54232
55233async function handleStep1 ( opts : BaseCommandOptions , userInfo : UserInfo ) {
56- await handleGetOnboardingResponse ( opts . client , userInfo ) ;
234+ return await handleGetOnboardingResponse ( opts . client , userInfo ) ;
57235}
58236
59237async function getUserInfo ( client : BaseCommandOptions [ 'client' ] ) {
@@ -90,6 +268,12 @@ export default function (opts: BaseCommandOptions) {
90268
91269 resetScreen ( userInfo ) ;
92270
93- await handleStep1 ( opts , userInfo ) ;
271+ const onboardingCheck = await handleStep1 ( opts , userInfo ) ;
272+
273+ if ( ! onboardingCheck ) {
274+ return ;
275+ }
276+
277+ await handleStep2 ( opts , { onboarding : onboardingCheck , userInfo } ) ;
94278 } ;
95279}
0 commit comments