UNPKG

toystack

Version:

![Toystack CLI](https://framerusercontent.com/images/6KcXakCf8FI9LB2mJXNjcHIreDA.png)

216 lines (194 loc) 5.51 kB
import { ApolloClient, HttpLink, InMemoryCache, gql } from '@apollo/client'; import { outro } from '@clack/prompts'; import axios from 'axios'; import dotenv from 'dotenv'; import FormData from 'form-data'; import { createReadStream } from 'fs'; import process from 'process'; import { checkAuth, checkForToken } from '..'; dotenv.config(); const API_BASE_URL = process.env.API_BASE_URL || 'https://core.toystack.ai'; const listAllRepositories = async () => { const token = await checkAuth(); const client = new ApolloClient({ link: new HttpLink({ uri: `${API_BASE_URL}/graphql`, fetch, headers: { Authorization: `Bearer ${token}` }, }), cache: new InMemoryCache(), }); const { data } = await client.query({ query: gql` query { me { repositories { nodes { id name } } } } `, }); return data.me.repositories.nodes; }; const deployBranch = async (repositoryName: string, branchName: string) => { const token = await checkAuth(); const client = new ApolloClient({ link: new HttpLink({ uri: `${API_BASE_URL}/graphql`, fetch, headers: { Authorization: `Bearer ${token}` }, }), cache: new InMemoryCache(), }); const { data } = await client.mutate({ mutation: gql` mutation DeployBranchViaCLI($repositoryName: String!, $branchName: String!) { deployBranchViaCLI(repositoryName: $repositoryName, branchName: $branchName) { id } } `, variables: { repositoryName, branchName, }, }); return data; }; const uploadUserCode = async (filePath: string, repositoryName?: string, branchName?: string) => { const data = new FormData(); const operations = JSON.stringify({ query: ` mutation UploadUserCode($file: Upload!, $repositoryName: String, $branchName: String) { uploadUserCode(file: $file, repositoryName: $repositoryName, branchName: $branchName) { deploymentId } } `, variables: { file: null, repositoryName: repositoryName || null, branchName: branchName || null, }, }); const map = { '0': ['variables.file'], }; data.append('operations', operations); data.append('map', JSON.stringify(map)); data.append('0', createReadStream(filePath)); if (repositoryName) data.append('1', repositoryName); if (branchName) data.append('2', branchName); const token = await checkForToken(); const config = { method: 'post', url: `${API_BASE_URL}/graphql`, headers: { 'apollo-require-preflight': 'true', ...(token ? { authorization: `Bearer ${token}` } : {}), ...data.getHeaders(), }, data: data, }; try { const response = await axios.request(config); const { data } = response; const { uploadUserCode } = data.data; return { deploymentId: uploadUserCode.deploymentId, filename: uploadUserCode.filename, status: uploadUserCode.status, }; } catch (error) { console.error('Upload failed:', error); throw new Error('Upload failed'); } }; const createCLIFrontendDeployment = async (zipFileName: string) => { await delay(5000); const client = new ApolloClient({ link: new HttpLink({ uri: `${API_BASE_URL}/graphql`, fetch, }), cache: new InMemoryCache(), }); const { data } = await client.mutate({ mutation: gql` mutation CreateCLIFrontendDeployment($zipFileName: String!) { createCLIFrontendDeployment(zipFileName: $zipFileName) { id url timeToLive } } `, variables: { zipFileName, }, }); return data.createCLIFrontendDeployment; }; async function pullForDeploymentStatus(deploymentId: string) { const pollInterval = 4000; let isPolling = true; // Handle SIGINT (Ctrl+C) process.on('SIGINT', () => { isPolling = false; outro('Deployment cancelled'); process.exit(0); }); // Handle process termination process.on('SIGTERM', () => { isPolling = false; outro('Deployment cancelled'); process.exit(0); }); try { const token = await checkAuth(); const client = new ApolloClient({ link: new HttpLink({ uri: `${API_BASE_URL}/graphql`, fetch, headers: { Authorization: `Bearer ${token}` }, }), cache: new InMemoryCache(), }); while (isPolling) { try { await delay(pollInterval); const { data } = await client.query({ query: gql` query Deployment($deploymentId: ID!) { deployment(id: $deploymentId) { url id status } } `, variables: { deploymentId }, fetchPolicy: 'network-only', }); if (data.deployment.url) { return { url: data.deployment.url, status: data.deployment.status }; } else if (data.deployment.status === 'FAILED') { return { url: null, status: data.deployment.status }; } } catch (error) { return null; } } } catch (error) { return null; } finally { process.removeAllListeners('SIGINT'); process.removeAllListeners('SIGTERM'); } } const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); export { listAllRepositories, deployBranch, uploadUserCode, createCLIFrontendDeployment, pullForDeploymentStatus };