1+ import os from 'node:os' ;
2+ import fs from 'node:fs/promises' ;
3+ import path from 'node:path' ;
14import pc from 'picocolors' ;
25import ora from 'ora' ;
36import { program } from 'commander' ;
7+ import { z } from 'zod' ;
48import type { WhoAmIResponse } from '@wundergraph/cosmo-connect/dist/platform/v1/platform_pb' ;
59import { EnumStatusCode } from '@wundergraph/cosmo-connect/dist/common/common_pb' ;
610import { BaseCommandOptions } from '../../core/types/types.js' ;
711import { getBaseHeaders , config } from '../../core/config.js' ;
812import { waitForKeyPress , rainbow , visibleLength } from '../../utils.js' ;
913
14+ const ONBOARDING_REPO = 'wundergraph/cosmo-onboarding' ;
15+ const ONBOARDING_BRANCH = 'main' ;
16+ const ONBOARDING_DIR_PREFIX = 'plugins/' ;
17+
18+ const GitHubTreeSchema = z . object ( {
19+ tree : z . array (
20+ z . object ( {
21+ type : z . string ( ) ,
22+ path : z . string ( ) ,
23+ } ) ,
24+ ) ,
25+ } ) ;
26+
1027type UserInfo = {
1128 userEmail : WhoAmIResponse [ 'userEmail' ] ;
1229 organizationName : WhoAmIResponse [ 'organizationName' ] ;
@@ -161,6 +178,63 @@ async function fetchUserInfo(client: BaseCommandOptions['client']) {
161178 }
162179}
163180
181+ async function prepareSupportingData ( ) {
182+ const spinner = ora ( 'Preparing supporting data…' ) . start ( ) ;
183+
184+ const tmpDir = await fs . mkdtemp ( path . join ( os . tmpdir ( ) , 'cosmo-' ) ) ;
185+ const cosmoDir = path . join ( tmpDir , 'cosmo' ) ;
186+ await fs . mkdir ( cosmoDir , { recursive : true } ) ;
187+
188+ const treeResponse = await fetch (
189+ `https://api.github.com/repos/${ ONBOARDING_REPO } /git/trees/${ ONBOARDING_BRANCH } ?recursive=1` ,
190+ ) ;
191+ if ( ! treeResponse . ok ) {
192+ spinner . fail ( 'Failed to fetch repository tree.' ) ;
193+ program . error ( `GitHub API error: ${ treeResponse . statusText } ` ) ;
194+ }
195+
196+ const parsed = GitHubTreeSchema . safeParse ( await treeResponse . json ( ) ) ;
197+ if ( ! parsed . success ) {
198+ spinner . fail ( 'Failed to parse repository tree.' ) ;
199+ program . error ( 'Unexpected response format from GitHub API. The repository structure may have changed.' ) ;
200+ }
201+
202+ const files = parsed . data . tree . filter (
203+ ( entry ) => entry . type === 'blob' && entry . path . startsWith ( ONBOARDING_DIR_PREFIX ) ,
204+ ) ;
205+
206+ const results = await Promise . all (
207+ files . map ( async ( file ) => {
208+ const rawUrl = `https://raw.githubusercontent.com/${ ONBOARDING_REPO } /${ ONBOARDING_BRANCH } /${ file . path } ` ;
209+ try {
210+ const response = await fetch ( rawUrl ) ;
211+ if ( ! response . ok ) {
212+ return { path : file . path , error : response . statusText } ;
213+ }
214+
215+ const content = Buffer . from ( await response . arrayBuffer ( ) ) ;
216+ const destPath = path . join ( cosmoDir , file . path ) ;
217+ await fs . mkdir ( path . dirname ( destPath ) , { recursive : true } ) ;
218+ await fs . writeFile ( destPath , content ) ;
219+
220+ return { path : file . path , error : null } ;
221+ } catch ( err ) {
222+ return { path : file . path , error : err instanceof Error ? err . message : String ( err ) } ;
223+ }
224+ } ) ,
225+ ) ;
226+
227+ const failed = results . filter ( ( r ) => r . error !== null ) ;
228+ if ( failed . length > 0 ) {
229+ spinner . fail ( `Failed to fetch some files from onboarding repository or store them in ${ cosmoDir } .` ) ;
230+ program . error ( failed . map ( ( f ) => ` ${ f . path } : ${ f . error } ` ) . join ( '\n' ) ) ;
231+ }
232+
233+ spinner . succeed ( `Support files copied to ${ pc . bold ( cosmoDir ) } ` ) ;
234+
235+ return cosmoDir ;
236+ }
237+
164238async function getUserInfo ( client : BaseCommandOptions [ 'client' ] ) {
165239 const spinner = ora ( 'Retrieving information about you…' ) . start ( ) ;
166240 const { userInfo, error } = await fetchUserInfo ( client ) ;
@@ -181,6 +255,7 @@ export default function (opts: BaseCommandOptions) {
181255 return async function handleCommand ( ) {
182256 clearScreen ( ) ;
183257 printHello ( ) ;
258+ await prepareSupportingData ( ) ;
184259
185260 await waitForKeyPress (
186261 {
0 commit comments