feat(template projects): generate git repo on backend (#218)

### TL;DR

- Still cretaes app if user migrates from page

The PR introduces a new `AddProjectFromTemplate` mutation to facilitate project creation using a repository template. This change centralizes the template project creation logic within the backend, improving code maintainability by removing redundant client-side code.

### What changed?
- Added `AddProjectFromTemplate` input type in `schema.gql` and corresponding TypeScript interfaces.
- Implemented `addProjectFromTemplate` resolver with error handling and Octokit integration for repository creation.
- Updated `service.ts` to include the new `addProjectFromTemplate` method.
- Created new GraphQL `Mutation` for `addProjectFromTemplate` in the GraphQL schema.
- Adjusted the client-side GQLClient to support the new mutation.
- Modified frontend to utilize the new backend mutation for project creation from a template.

### How to test?
1. Ensure your backend server is running.
2. Use a GraphQL client like Postman to call the `addProjectFromTemplate` mutation with appropriate input.
3. Verify that the new project is created using the specified template, and appropriate error messages are returned for failures.
4. Check the frontend flow for creating a project from a template to ensure it is working correctly.

### Why make this change?
This change enhances code maintainability by centralizing template project creation logic within the backend, thereby reducing redundancy and potential inconsistencies in client-side implementations.

---
This commit is contained in:
Vivian Phung 2024-06-24 18:38:01 -04:00 committed by GitHub
parent b12c95b2ff
commit a684743bd6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 579 additions and 370 deletions

View File

@ -6,6 +6,7 @@ import { Permission } from './entity/ProjectMember';
import { Domain } from './entity/Domain'; import { Domain } from './entity/Domain';
import { Project } from './entity/Project'; import { Project } from './entity/Project';
import { EnvironmentVariable } from './entity/EnvironmentVariable'; import { EnvironmentVariable } from './entity/EnvironmentVariable';
import { AddProjectFromTemplateInput } from './types';
const log = debug('snowball:resolver'); const log = debug('snowball:resolver');
@ -197,6 +198,26 @@ export const createResolvers = async (service: Service): Promise<any> => {
} }
}, },
addProjectFromTemplate: async (
_: any,
{
organizationSlug,
data,
}: { organizationSlug: string; data: AddProjectFromTemplateInput },
context: any,
) => {
try {
return await service.addProjectFromTemplate(
context.user,
organizationSlug,
data,
);
} catch (err) {
log(err);
throw err;
}
},
addProject: async ( addProject: async (
_: any, _: any,
{ {

View File

@ -130,6 +130,14 @@ input AddEnvironmentVariableInput {
value: String! value: String!
} }
input AddProjectFromTemplateInput {
templateOwner: String!
templateRepo: String!
owner: String!
name: String!
isPrivate: Boolean!
}
input AddProjectInput { input AddProjectInput {
name: String! name: String!
repository: String! repository: String!
@ -204,6 +212,10 @@ type Mutation {
): Boolean! ): Boolean!
removeEnvironmentVariable(environmentVariableId: String!): Boolean! removeEnvironmentVariable(environmentVariableId: String!): Boolean!
updateDeploymentToProd(deploymentId: String!): Boolean! updateDeploymentToProd(deploymentId: String!): Boolean!
addProjectFromTemplate(
organizationSlug: String!
data: AddProjectFromTemplateInput
): Project!
addProject(organizationSlug: String!, data: AddProjectInput): Project! addProject(organizationSlug: String!, data: AddProjectInput): Project!
updateProject(projectId: String!, data: UpdateProjectInput): Boolean! updateProject(projectId: String!, data: UpdateProjectInput): Boolean!
redeployToProd(deploymentId: String!): Boolean! redeployToProd(deploymentId: String!): Boolean!

View File

@ -16,6 +16,7 @@ import { User } from './entity/User';
import { Registry } from './registry'; import { Registry } from './registry';
import { GitHubConfig, RegistryConfig } from './config'; import { GitHubConfig, RegistryConfig } from './config';
import { import {
AddProjectFromTemplateInput,
AppDeploymentRecord, AppDeploymentRecord,
AppDeploymentRemovalRecord, AppDeploymentRemovalRecord,
GitPushEventPayload, GitPushEventPayload,
@ -643,6 +644,53 @@ export class Service {
return newDeployment; return newDeployment;
} }
async addProjectFromTemplate(
user: User,
organizationSlug: string,
data: AddProjectFromTemplateInput,
): Promise<Project | undefined> {
try {
const octokit = await this.getOctokit(user.id);
const gitRepo = await octokit?.rest.repos.createUsingTemplate({
template_owner: data.templateOwner,
template_repo: data.templateRepo,
owner: data.owner,
name: data.name,
include_all_branches: false,
private: data.isPrivate,
});
if (!gitRepo) {
throw new Error('Failed to create repository from template');
}
const createdTemplateRepo = await octokit.rest.repos.get({
owner: data.owner,
repo: data.name,
});
const prodBranch = createdTemplateRepo.data.default_branch ?? 'main';
const project = await this.addProject(user, organizationSlug, {
name: `${gitRepo.data.owner!.login}-${gitRepo.data.name}`,
prodBranch,
repository: gitRepo.data.full_name,
// TODO: Set selected template
template: 'webapp',
});
if (!project || !project.id) {
throw new Error('Failed to create project from template');
}
return project;
} catch (error) {
console.error('Error creating project from template:', error);
throw error;
}
}
async addProject( async addProject(
user: User, user: User,
organizationSlug: string, organizationSlug: string,
@ -672,7 +720,7 @@ export class Service {
}); });
// Create deployment with prod branch and latest commit // Create deployment with prod branch and latest commit
await this.createDeployment(user.id, octokit, { const deployment = await this.createDeployment(user.id, octokit, {
project, project,
branch: project.prodBranch, branch: project.prodBranch,
environment: Environment.Production, environment: Environment.Production,
@ -683,6 +731,8 @@ export class Service {
await this.createRepoHook(octokit, project); await this.createRepoHook(octokit, project);
console.log('projectid is', project.id);
return project; return project;
} }

View File

@ -41,7 +41,7 @@ export interface AppDeploymentRecordAttributes {
export interface AppDeploymentRemovalRecordAttributes { export interface AppDeploymentRemovalRecordAttributes {
deployment: string; deployment: string;
request: string; request: string;
type: "ApplicationDeploymentRemovalRecord"; type: 'ApplicationDeploymentRemovalRecord';
version: string; version: string;
} }
@ -61,3 +61,11 @@ export interface AppDeploymentRecord extends RegistryRecord {
export interface AppDeploymentRemovalRecord extends RegistryRecord { export interface AppDeploymentRemovalRecord extends RegistryRecord {
attributes: AppDeploymentRemovalRecordAttributes; attributes: AppDeploymentRemovalRecordAttributes;
} }
export interface AddProjectFromTemplateInput {
templateOwner: string;
templateRepo: string;
owner: string;
name: string;
isPrivate: boolean;
}

View File

@ -50,36 +50,22 @@ const CreateRepo = () => {
assert(template.repoFullName, 'Template URL not provided'); assert(template.repoFullName, 'Template URL not provided');
const [owner, repo] = template.repoFullName.split('/'); const [owner, repo] = template.repoFullName.split('/');
// TODO: Handle this functionality in backend setIsLoading(true);
const gitRepo = await octokit?.rest.repos.createUsingTemplate({
template_owner: owner,
template_repo: repo,
owner: data.account,
name: data.repoName,
include_all_branches: false,
private: data.isPrivate,
});
if (!gitRepo) { const { addProjectFromTemplate } = await client.addProjectFromTemplate(
return; orgSlug!,
} {
templateOwner: owner,
templateRepo: repo,
owner: data.account,
name: data.repoName,
isPrivate: false,
},
);
// Refetch to always get correct default branch navigate(
const templateRepo = await octokit.rest.repos.get({ `deploy?projectId=${addProjectFromTemplate.id}&templateId=${template.id}`,
owner: template.repoFullName.split('/')[0], );
repo: template.repoFullName.split('/')[1],
});
const prodBranch = templateRepo.data.default_branch ?? 'main';
const { addProject } = await client.addProject(orgSlug!, {
name: `${gitRepo.data.owner!.login}-${gitRepo.data.name}`,
prodBranch,
repository: gitRepo.data.full_name,
// TODO: Set selected template
template: 'webapp',
});
navigate(`deploy?projectId=${addProject.id}&templateId=${template.id}`);
} catch (err) { } catch (err) {
setIsLoading(false); setIsLoading(false);

View File

@ -185,6 +185,9 @@ type RemoveEnvironmentVariableResponse = {
type UpdateDeploymentToProdResponse = { type UpdateDeploymentToProdResponse = {
updateDeploymentToProd: boolean; updateDeploymentToProd: boolean;
}; };
type AddProjectFromTemplateResponse = {
addProjectFromTemplate: Project;
};
type AddProjectResponse = { type AddProjectResponse = {
addProject: Project; addProject: Project;
}; };
@ -200,6 +203,13 @@ type DeleteProjectResponse = {
type DeleteDomainResponse = { type DeleteDomainResponse = {
deleteDomain: boolean; deleteDomain: boolean;
}; };
type AddProjectFromTemplateInput = {
templateOwner: string;
templateRepo: string;
owner: string;
name: string;
isPrivate: boolean;
};
type AddProjectInput = { type AddProjectInput = {
name: string; name: string;
repository: string; repository: string;
@ -267,6 +277,7 @@ declare class GQLClient {
updateEnvironmentVariable(environmentVariableId: string, data: UpdateEnvironmentVariableInput): Promise<UpdateEnvironmentVariableResponse>; updateEnvironmentVariable(environmentVariableId: string, data: UpdateEnvironmentVariableInput): Promise<UpdateEnvironmentVariableResponse>;
removeEnvironmentVariable(environmentVariableId: string): Promise<RemoveEnvironmentVariableResponse>; removeEnvironmentVariable(environmentVariableId: string): Promise<RemoveEnvironmentVariableResponse>;
updateDeploymentToProd(deploymentId: string): Promise<UpdateDeploymentToProdResponse>; updateDeploymentToProd(deploymentId: string): Promise<UpdateDeploymentToProdResponse>;
addProjectFromTemplate(organizationSlug: string, data: AddProjectFromTemplateInput): Promise<AddProjectFromTemplateResponse>;
addProject(organizationSlug: string, data: AddProjectInput): Promise<AddProjectResponse>; addProject(organizationSlug: string, data: AddProjectInput): Promise<AddProjectResponse>;
updateProject(projectId: string, data: UpdateProjectInput): Promise<UpdateProjectResponse>; updateProject(projectId: string, data: UpdateProjectInput): Promise<UpdateProjectResponse>;
updateDomain(domainId: string, data: UpdateDomainInput): Promise<UpdateDomainResponse>; updateDomain(domainId: string, data: UpdateDomainInput): Promise<UpdateDomainResponse>;
@ -281,4 +292,4 @@ declare class GQLClient {
unauthenticateGithub(): Promise<UnauthenticateGitHubResponse>; unauthenticateGithub(): Promise<UnauthenticateGitHubResponse>;
} }
export { type AddDomainInput, type AddDomainResponse, type AddEnvironmentVariableInput, type AddEnvironmentVariablesResponse, type AddProjectInput, type AddProjectMemberInput, type AddProjectMemberResponse, type AddProjectResponse, type AuthenticateGitHubResponse, type DeleteDeploymentResponse, type DeleteDomainResponse, type DeleteProjectResponse, type Deployment, DeploymentStatus, type Domain, DomainStatus, Environment, type EnvironmentVariable, type FilterDomainInput, GQLClient, type GetDeploymentsResponse, type GetDomainsResponse, type GetEnvironmentVariablesResponse, type GetOrganizationsResponse, type GetProjectMembersResponse, type GetProjectResponse, type GetProjectsInOrganizationResponse, type GetUserResponse, type GraphQLConfig, type Organization, type OrganizationMember, type OrganizationProject, Permission, type Project, type ProjectMember, type RedeployToProdResponse, type RemoveEnvironmentVariableResponse, type RemoveProjectMemberResponse, Role, type RollbackDeploymentResponse, type SearchProjectsResponse, type UnauthenticateGitHubResponse, type UpdateDeploymentToProdResponse, type UpdateDomainInput, type UpdateDomainResponse, type UpdateEnvironmentVariableInput, type UpdateEnvironmentVariableResponse, type UpdateProjectInput, type UpdateProjectMemberInput, type UpdateProjectMemberResponse, type UpdateProjectResponse, type User }; export { type AddDomainInput, type AddDomainResponse, type AddEnvironmentVariableInput, type AddEnvironmentVariablesResponse, type AddProjectFromTemplateInput, type AddProjectFromTemplateResponse, type AddProjectInput, type AddProjectMemberInput, type AddProjectMemberResponse, type AddProjectResponse, type AuthenticateGitHubResponse, type DeleteDeploymentResponse, type DeleteDomainResponse, type DeleteProjectResponse, type Deployment, DeploymentStatus, type Domain, DomainStatus, Environment, type EnvironmentVariable, type FilterDomainInput, GQLClient, type GetDeploymentsResponse, type GetDomainsResponse, type GetEnvironmentVariablesResponse, type GetOrganizationsResponse, type GetProjectMembersResponse, type GetProjectResponse, type GetProjectsInOrganizationResponse, type GetUserResponse, type GraphQLConfig, type Organization, type OrganizationMember, type OrganizationProject, Permission, type Project, type ProjectMember, type RedeployToProdResponse, type RemoveEnvironmentVariableResponse, type RemoveProjectMemberResponse, Role, type RollbackDeploymentResponse, type SearchProjectsResponse, type UnauthenticateGitHubResponse, type UpdateDeploymentToProdResponse, type UpdateDomainInput, type UpdateDomainResponse, type UpdateEnvironmentVariableInput, type UpdateEnvironmentVariableResponse, type UpdateProjectInput, type UpdateProjectMemberInput, type UpdateProjectMemberResponse, type UpdateProjectResponse, type User };

View File

@ -185,6 +185,9 @@ type RemoveEnvironmentVariableResponse = {
type UpdateDeploymentToProdResponse = { type UpdateDeploymentToProdResponse = {
updateDeploymentToProd: boolean; updateDeploymentToProd: boolean;
}; };
type AddProjectFromTemplateResponse = {
addProjectFromTemplate: Project;
};
type AddProjectResponse = { type AddProjectResponse = {
addProject: Project; addProject: Project;
}; };
@ -200,6 +203,13 @@ type DeleteProjectResponse = {
type DeleteDomainResponse = { type DeleteDomainResponse = {
deleteDomain: boolean; deleteDomain: boolean;
}; };
type AddProjectFromTemplateInput = {
templateOwner: string;
templateRepo: string;
owner: string;
name: string;
isPrivate: boolean;
};
type AddProjectInput = { type AddProjectInput = {
name: string; name: string;
repository: string; repository: string;
@ -267,6 +277,7 @@ declare class GQLClient {
updateEnvironmentVariable(environmentVariableId: string, data: UpdateEnvironmentVariableInput): Promise<UpdateEnvironmentVariableResponse>; updateEnvironmentVariable(environmentVariableId: string, data: UpdateEnvironmentVariableInput): Promise<UpdateEnvironmentVariableResponse>;
removeEnvironmentVariable(environmentVariableId: string): Promise<RemoveEnvironmentVariableResponse>; removeEnvironmentVariable(environmentVariableId: string): Promise<RemoveEnvironmentVariableResponse>;
updateDeploymentToProd(deploymentId: string): Promise<UpdateDeploymentToProdResponse>; updateDeploymentToProd(deploymentId: string): Promise<UpdateDeploymentToProdResponse>;
addProjectFromTemplate(organizationSlug: string, data: AddProjectFromTemplateInput): Promise<AddProjectFromTemplateResponse>;
addProject(organizationSlug: string, data: AddProjectInput): Promise<AddProjectResponse>; addProject(organizationSlug: string, data: AddProjectInput): Promise<AddProjectResponse>;
updateProject(projectId: string, data: UpdateProjectInput): Promise<UpdateProjectResponse>; updateProject(projectId: string, data: UpdateProjectInput): Promise<UpdateProjectResponse>;
updateDomain(domainId: string, data: UpdateDomainInput): Promise<UpdateDomainResponse>; updateDomain(domainId: string, data: UpdateDomainInput): Promise<UpdateDomainResponse>;
@ -281,4 +292,4 @@ declare class GQLClient {
unauthenticateGithub(): Promise<UnauthenticateGitHubResponse>; unauthenticateGithub(): Promise<UnauthenticateGitHubResponse>;
} }
export { type AddDomainInput, type AddDomainResponse, type AddEnvironmentVariableInput, type AddEnvironmentVariablesResponse, type AddProjectInput, type AddProjectMemberInput, type AddProjectMemberResponse, type AddProjectResponse, type AuthenticateGitHubResponse, type DeleteDeploymentResponse, type DeleteDomainResponse, type DeleteProjectResponse, type Deployment, DeploymentStatus, type Domain, DomainStatus, Environment, type EnvironmentVariable, type FilterDomainInput, GQLClient, type GetDeploymentsResponse, type GetDomainsResponse, type GetEnvironmentVariablesResponse, type GetOrganizationsResponse, type GetProjectMembersResponse, type GetProjectResponse, type GetProjectsInOrganizationResponse, type GetUserResponse, type GraphQLConfig, type Organization, type OrganizationMember, type OrganizationProject, Permission, type Project, type ProjectMember, type RedeployToProdResponse, type RemoveEnvironmentVariableResponse, type RemoveProjectMemberResponse, Role, type RollbackDeploymentResponse, type SearchProjectsResponse, type UnauthenticateGitHubResponse, type UpdateDeploymentToProdResponse, type UpdateDomainInput, type UpdateDomainResponse, type UpdateEnvironmentVariableInput, type UpdateEnvironmentVariableResponse, type UpdateProjectInput, type UpdateProjectMemberInput, type UpdateProjectMemberResponse, type UpdateProjectResponse, type User }; export { type AddDomainInput, type AddDomainResponse, type AddEnvironmentVariableInput, type AddEnvironmentVariablesResponse, type AddProjectFromTemplateInput, type AddProjectFromTemplateResponse, type AddProjectInput, type AddProjectMemberInput, type AddProjectMemberResponse, type AddProjectResponse, type AuthenticateGitHubResponse, type DeleteDeploymentResponse, type DeleteDomainResponse, type DeleteProjectResponse, type Deployment, DeploymentStatus, type Domain, DomainStatus, Environment, type EnvironmentVariable, type FilterDomainInput, GQLClient, type GetDeploymentsResponse, type GetDomainsResponse, type GetEnvironmentVariablesResponse, type GetOrganizationsResponse, type GetProjectMembersResponse, type GetProjectResponse, type GetProjectsInOrganizationResponse, type GetUserResponse, type GraphQLConfig, type Organization, type OrganizationMember, type OrganizationProject, Permission, type Project, type ProjectMember, type RedeployToProdResponse, type RemoveEnvironmentVariableResponse, type RemoveProjectMemberResponse, Role, type RollbackDeploymentResponse, type SearchProjectsResponse, type UnauthenticateGitHubResponse, type UpdateDeploymentToProdResponse, type UpdateDomainInput, type UpdateDomainResponse, type UpdateEnvironmentVariableInput, type UpdateEnvironmentVariableResponse, type UpdateProjectInput, type UpdateProjectMemberInput, type UpdateProjectMemberResponse, type UpdateProjectResponse, type User };

View File

@ -267,93 +267,112 @@ query ($projectId: String!, $filter: FilterDomainsInput) {
// src/mutations.ts // src/mutations.ts
var import_client2 = require("@apollo/client"); var import_client2 = require("@apollo/client");
var removeProjectMember = import_client2.gql` var removeProjectMember = import_client2.gql`
mutation ($projectMemberId: String!) { mutation ($projectMemberId: String!) {
removeProjectMember(projectMemberId: $projectMemberId) removeProjectMember(projectMemberId: $projectMemberId)
} }
`; `;
var updateProjectMember = import_client2.gql` var updateProjectMember = import_client2.gql`
mutation ($projectMemberId: String!, $data: UpdateProjectMemberInput) { mutation ($projectMemberId: String!, $data: UpdateProjectMemberInput) {
updateProjectMember(projectMemberId: $projectMemberId, data: $data) updateProjectMember(projectMemberId: $projectMemberId, data: $data)
} }
`; `;
var addProjectMember = import_client2.gql` var addProjectMember = import_client2.gql`
mutation ($projectId: String!, $data: AddProjectMemberInput) { mutation ($projectId: String!, $data: AddProjectMemberInput) {
addProjectMember(projectId: $projectId, data: $data) addProjectMember(projectId: $projectId, data: $data)
} }
`; `;
var addEnvironmentVariables = import_client2.gql` var addEnvironmentVariables = import_client2.gql`
mutation ($projectId: String!, $data: [AddEnvironmentVariableInput!]) { mutation ($projectId: String!, $data: [AddEnvironmentVariableInput!]) {
addEnvironmentVariables(projectId: $projectId, data: $data) addEnvironmentVariables(projectId: $projectId, data: $data)
} }
`; `;
var updateEnvironmentVariable = import_client2.gql` var updateEnvironmentVariable = import_client2.gql`
mutation ($environmentVariableId: String!, $data: UpdateEnvironmentVariableInput!) { mutation (
updateEnvironmentVariable(environmentVariableId: $environmentVariableId, data: $data) $environmentVariableId: String!
} $data: UpdateEnvironmentVariableInput!
) {
updateEnvironmentVariable(
environmentVariableId: $environmentVariableId
data: $data
)
}
`; `;
var removeEnvironmentVariable = import_client2.gql` var removeEnvironmentVariable = import_client2.gql`
mutation ($environmentVariableId: String!) { mutation ($environmentVariableId: String!) {
removeEnvironmentVariable(environmentVariableId: $environmentVariableId) removeEnvironmentVariable(environmentVariableId: $environmentVariableId)
} }
`; `;
var updateDeploymentToProd = import_client2.gql` var updateDeploymentToProd = import_client2.gql`
mutation ($deploymentId: String!) { mutation ($deploymentId: String!) {
updateDeploymentToProd(deploymentId: $deploymentId) updateDeploymentToProd(deploymentId: $deploymentId)
} }
`;
var addProjectFromTemplate = import_client2.gql`
mutation ($organizationSlug: String!, $data: AddProjectFromTemplateInput) {
addProjectFromTemplate(organizationSlug: $organizationSlug, data: $data) {
id
}
}
`; `;
var addProject = import_client2.gql` var addProject = import_client2.gql`
mutation ($organizationSlug: String!, $data: AddProjectInput) { mutation ($organizationSlug: String!, $data: AddProjectInput) {
addProject(organizationSlug: $organizationSlug, data: $data) { addProject(organizationSlug: $organizationSlug, data: $data) {
id id
}
} }
}`; `;
var updateProjectMutation = import_client2.gql` var updateProjectMutation = import_client2.gql`
mutation ($projectId: String!, $data: UpdateProjectInput) { mutation ($projectId: String!, $data: UpdateProjectInput) {
updateProject(projectId: $projectId, data: $data) updateProject(projectId: $projectId, data: $data)
}`; }
`;
var updateDomainMutation = import_client2.gql` var updateDomainMutation = import_client2.gql`
mutation ($domainId: String!, $data: UpdateDomainInput!) { mutation ($domainId: String!, $data: UpdateDomainInput!) {
updateDomain(domainId: $domainId, data: $data) updateDomain(domainId: $domainId, data: $data)
}`; }
`;
var redeployToProd = import_client2.gql` var redeployToProd = import_client2.gql`
mutation ($deploymentId: String!) { mutation ($deploymentId: String!) {
redeployToProd(deploymentId: $deploymentId) redeployToProd(deploymentId: $deploymentId)
} }
`; `;
var deleteProject = import_client2.gql` var deleteProject = import_client2.gql`
mutation ($projectId: String!) { mutation ($projectId: String!) {
deleteProject(projectId: $projectId) deleteProject(projectId: $projectId)
} }
`; `;
var deleteDomain = import_client2.gql` var deleteDomain = import_client2.gql`
mutation ($domainId: String!) { mutation ($domainId: String!) {
deleteDomain(domainId: $domainId) deleteDomain(domainId: $domainId)
}`; }
`;
var rollbackDeployment = import_client2.gql` var rollbackDeployment = import_client2.gql`
mutation ($projectId: String! ,$deploymentId: String!) { mutation ($projectId: String!, $deploymentId: String!) {
rollbackDeployment(projectId: $projectId, deploymentId: $deploymentId) rollbackDeployment(projectId: $projectId, deploymentId: $deploymentId)
} }
`; `;
var deleteDeployment = import_client2.gql` var deleteDeployment = import_client2.gql`
mutation ($deploymentId: String!) { mutation ($deploymentId: String!) {
deleteDeployment(deploymentId: $deploymentId) deleteDeployment(deploymentId: $deploymentId)
} }
`; `;
var addDomain = import_client2.gql` var addDomain = import_client2.gql`
mutation ($projectId: String!, $data: AddDomainInput!) { mutation ($projectId: String!, $data: AddDomainInput!) {
addDomain(projectId: $projectId, data: $data) addDomain(projectId: $projectId, data: $data)
} }
`; `;
var authenticateGitHub = import_client2.gql` var authenticateGitHub = import_client2.gql`
mutation ($code: String!) { mutation ($code: String!) {
authenticateGitHub(code: $code) { authenticateGitHub(code: $code) {
token token
}
} }
}`; `;
var unauthenticateGitHub = import_client2.gql` var unauthenticateGitHub = import_client2.gql`
mutation { mutation {
unauthenticateGitHub unauthenticateGitHub
}`; }
`;
// src/client.ts // src/client.ts
var defaultOptions = { var defaultOptions = {
@ -538,6 +557,18 @@ var GQLClient = class {
return data; return data;
}); });
} }
addProjectFromTemplate(organizationSlug, data) {
return __async(this, null, function* () {
const result = yield this.client.mutate({
mutation: addProjectFromTemplate,
variables: {
organizationSlug,
data
}
});
return result.data;
});
}
addProject(organizationSlug, data) { addProject(organizationSlug, data) {
return __async(this, null, function* () { return __async(this, null, function* () {
const result = yield this.client.mutate({ const result = yield this.client.mutate({

File diff suppressed because one or more lines are too long

View File

@ -240,93 +240,112 @@ query ($projectId: String!, $filter: FilterDomainsInput) {
// src/mutations.ts // src/mutations.ts
import { gql as gql2 } from "@apollo/client"; import { gql as gql2 } from "@apollo/client";
var removeProjectMember = gql2` var removeProjectMember = gql2`
mutation ($projectMemberId: String!) { mutation ($projectMemberId: String!) {
removeProjectMember(projectMemberId: $projectMemberId) removeProjectMember(projectMemberId: $projectMemberId)
} }
`; `;
var updateProjectMember = gql2` var updateProjectMember = gql2`
mutation ($projectMemberId: String!, $data: UpdateProjectMemberInput) { mutation ($projectMemberId: String!, $data: UpdateProjectMemberInput) {
updateProjectMember(projectMemberId: $projectMemberId, data: $data) updateProjectMember(projectMemberId: $projectMemberId, data: $data)
} }
`; `;
var addProjectMember = gql2` var addProjectMember = gql2`
mutation ($projectId: String!, $data: AddProjectMemberInput) { mutation ($projectId: String!, $data: AddProjectMemberInput) {
addProjectMember(projectId: $projectId, data: $data) addProjectMember(projectId: $projectId, data: $data)
} }
`; `;
var addEnvironmentVariables = gql2` var addEnvironmentVariables = gql2`
mutation ($projectId: String!, $data: [AddEnvironmentVariableInput!]) { mutation ($projectId: String!, $data: [AddEnvironmentVariableInput!]) {
addEnvironmentVariables(projectId: $projectId, data: $data) addEnvironmentVariables(projectId: $projectId, data: $data)
} }
`; `;
var updateEnvironmentVariable = gql2` var updateEnvironmentVariable = gql2`
mutation ($environmentVariableId: String!, $data: UpdateEnvironmentVariableInput!) { mutation (
updateEnvironmentVariable(environmentVariableId: $environmentVariableId, data: $data) $environmentVariableId: String!
} $data: UpdateEnvironmentVariableInput!
) {
updateEnvironmentVariable(
environmentVariableId: $environmentVariableId
data: $data
)
}
`; `;
var removeEnvironmentVariable = gql2` var removeEnvironmentVariable = gql2`
mutation ($environmentVariableId: String!) { mutation ($environmentVariableId: String!) {
removeEnvironmentVariable(environmentVariableId: $environmentVariableId) removeEnvironmentVariable(environmentVariableId: $environmentVariableId)
} }
`; `;
var updateDeploymentToProd = gql2` var updateDeploymentToProd = gql2`
mutation ($deploymentId: String!) { mutation ($deploymentId: String!) {
updateDeploymentToProd(deploymentId: $deploymentId) updateDeploymentToProd(deploymentId: $deploymentId)
} }
`;
var addProjectFromTemplate = gql2`
mutation ($organizationSlug: String!, $data: AddProjectFromTemplateInput) {
addProjectFromTemplate(organizationSlug: $organizationSlug, data: $data) {
id
}
}
`; `;
var addProject = gql2` var addProject = gql2`
mutation ($organizationSlug: String!, $data: AddProjectInput) { mutation ($organizationSlug: String!, $data: AddProjectInput) {
addProject(organizationSlug: $organizationSlug, data: $data) { addProject(organizationSlug: $organizationSlug, data: $data) {
id id
}
} }
}`; `;
var updateProjectMutation = gql2` var updateProjectMutation = gql2`
mutation ($projectId: String!, $data: UpdateProjectInput) { mutation ($projectId: String!, $data: UpdateProjectInput) {
updateProject(projectId: $projectId, data: $data) updateProject(projectId: $projectId, data: $data)
}`; }
`;
var updateDomainMutation = gql2` var updateDomainMutation = gql2`
mutation ($domainId: String!, $data: UpdateDomainInput!) { mutation ($domainId: String!, $data: UpdateDomainInput!) {
updateDomain(domainId: $domainId, data: $data) updateDomain(domainId: $domainId, data: $data)
}`; }
`;
var redeployToProd = gql2` var redeployToProd = gql2`
mutation ($deploymentId: String!) { mutation ($deploymentId: String!) {
redeployToProd(deploymentId: $deploymentId) redeployToProd(deploymentId: $deploymentId)
} }
`; `;
var deleteProject = gql2` var deleteProject = gql2`
mutation ($projectId: String!) { mutation ($projectId: String!) {
deleteProject(projectId: $projectId) deleteProject(projectId: $projectId)
} }
`; `;
var deleteDomain = gql2` var deleteDomain = gql2`
mutation ($domainId: String!) { mutation ($domainId: String!) {
deleteDomain(domainId: $domainId) deleteDomain(domainId: $domainId)
}`; }
`;
var rollbackDeployment = gql2` var rollbackDeployment = gql2`
mutation ($projectId: String! ,$deploymentId: String!) { mutation ($projectId: String!, $deploymentId: String!) {
rollbackDeployment(projectId: $projectId, deploymentId: $deploymentId) rollbackDeployment(projectId: $projectId, deploymentId: $deploymentId)
} }
`; `;
var deleteDeployment = gql2` var deleteDeployment = gql2`
mutation ($deploymentId: String!) { mutation ($deploymentId: String!) {
deleteDeployment(deploymentId: $deploymentId) deleteDeployment(deploymentId: $deploymentId)
} }
`; `;
var addDomain = gql2` var addDomain = gql2`
mutation ($projectId: String!, $data: AddDomainInput!) { mutation ($projectId: String!, $data: AddDomainInput!) {
addDomain(projectId: $projectId, data: $data) addDomain(projectId: $projectId, data: $data)
} }
`; `;
var authenticateGitHub = gql2` var authenticateGitHub = gql2`
mutation ($code: String!) { mutation ($code: String!) {
authenticateGitHub(code: $code) { authenticateGitHub(code: $code) {
token token
}
} }
}`; `;
var unauthenticateGitHub = gql2` var unauthenticateGitHub = gql2`
mutation { mutation {
unauthenticateGitHub unauthenticateGitHub
}`; }
`;
// src/client.ts // src/client.ts
var defaultOptions = { var defaultOptions = {
@ -511,6 +530,18 @@ var GQLClient = class {
return data; return data;
}); });
} }
addProjectFromTemplate(organizationSlug, data) {
return __async(this, null, function* () {
const result = yield this.client.mutate({
mutation: addProjectFromTemplate,
variables: {
organizationSlug,
data
}
});
return result.data;
});
}
addProject(organizationSlug, data) { addProject(organizationSlug, data) {
return __async(this, null, function* () { return __async(this, null, function* () {
const result = yield this.client.mutate({ const result = yield this.client.mutate({

File diff suppressed because one or more lines are too long

View File

@ -228,6 +228,21 @@ export class GQLClient {
return data; return data;
} }
async addProjectFromTemplate(
organizationSlug: string,
data: types.AddProjectFromTemplateInput
): Promise<types.AddProjectFromTemplateResponse> {
const result = await this.client.mutate({
mutation: mutations.addProjectFromTemplate,
variables: {
organizationSlug,
data,
},
});
return result.data;
}
async addProject( async addProject(
organizationSlug: string, organizationSlug: string,
data: types.AddProjectInput data: types.AddProjectInput

View File

@ -1,107 +1,127 @@
import { gql } from '@apollo/client'; import { gql } from "@apollo/client";
export const removeProjectMember = gql` export const removeProjectMember = gql`
mutation ($projectMemberId: String!) { mutation ($projectMemberId: String!) {
removeProjectMember(projectMemberId: $projectMemberId) removeProjectMember(projectMemberId: $projectMemberId)
} }
`; `;
export const updateProjectMember = gql` export const updateProjectMember = gql`
mutation ($projectMemberId: String!, $data: UpdateProjectMemberInput) { mutation ($projectMemberId: String!, $data: UpdateProjectMemberInput) {
updateProjectMember(projectMemberId: $projectMemberId, data: $data) updateProjectMember(projectMemberId: $projectMemberId, data: $data)
} }
`; `;
export const addProjectMember = gql` export const addProjectMember = gql`
mutation ($projectId: String!, $data: AddProjectMemberInput) { mutation ($projectId: String!, $data: AddProjectMemberInput) {
addProjectMember(projectId: $projectId, data: $data) addProjectMember(projectId: $projectId, data: $data)
} }
`; `;
export const addEnvironmentVariables = gql` export const addEnvironmentVariables = gql`
mutation ($projectId: String!, $data: [AddEnvironmentVariableInput!]) { mutation ($projectId: String!, $data: [AddEnvironmentVariableInput!]) {
addEnvironmentVariables(projectId: $projectId, data: $data) addEnvironmentVariables(projectId: $projectId, data: $data)
} }
`; `;
export const updateEnvironmentVariable = gql` export const updateEnvironmentVariable = gql`
mutation ($environmentVariableId: String!, $data: UpdateEnvironmentVariableInput!) { mutation (
updateEnvironmentVariable(environmentVariableId: $environmentVariableId, data: $data) $environmentVariableId: String!
} $data: UpdateEnvironmentVariableInput!
) {
updateEnvironmentVariable(
environmentVariableId: $environmentVariableId
data: $data
)
}
`; `;
export const removeEnvironmentVariable = gql` export const removeEnvironmentVariable = gql`
mutation ($environmentVariableId: String!) { mutation ($environmentVariableId: String!) {
removeEnvironmentVariable(environmentVariableId: $environmentVariableId) removeEnvironmentVariable(environmentVariableId: $environmentVariableId)
} }
`; `;
export const updateDeploymentToProd = gql` export const updateDeploymentToProd = gql`
mutation ($deploymentId: String!) { mutation ($deploymentId: String!) {
updateDeploymentToProd(deploymentId: $deploymentId) updateDeploymentToProd(deploymentId: $deploymentId)
} }
`;
export const addProjectFromTemplate = gql`
mutation ($organizationSlug: String!, $data: AddProjectFromTemplateInput) {
addProjectFromTemplate(organizationSlug: $organizationSlug, data: $data) {
id
}
}
`; `;
export const addProject = gql` export const addProject = gql`
mutation ($organizationSlug: String!, $data: AddProjectInput) { mutation ($organizationSlug: String!, $data: AddProjectInput) {
addProject(organizationSlug: $organizationSlug, data: $data) { addProject(organizationSlug: $organizationSlug, data: $data) {
id id
}
} }
}`; `;
export const updateProjectMutation = gql` export const updateProjectMutation = gql`
mutation ($projectId: String!, $data: UpdateProjectInput) { mutation ($projectId: String!, $data: UpdateProjectInput) {
updateProject(projectId: $projectId, data: $data) updateProject(projectId: $projectId, data: $data)
}`; }
`;
export const updateDomainMutation = gql` export const updateDomainMutation = gql`
mutation ($domainId: String!, $data: UpdateDomainInput!) { mutation ($domainId: String!, $data: UpdateDomainInput!) {
updateDomain(domainId: $domainId, data: $data) updateDomain(domainId: $domainId, data: $data)
}`; }
`;
export const redeployToProd = gql` export const redeployToProd = gql`
mutation ($deploymentId: String!) { mutation ($deploymentId: String!) {
redeployToProd(deploymentId: $deploymentId) redeployToProd(deploymentId: $deploymentId)
} }
`; `;
export const deleteProject = gql` export const deleteProject = gql`
mutation ($projectId: String!) { mutation ($projectId: String!) {
deleteProject(projectId: $projectId) deleteProject(projectId: $projectId)
} }
`; `;
export const deleteDomain = gql` export const deleteDomain = gql`
mutation ($domainId: String!) { mutation ($domainId: String!) {
deleteDomain(domainId: $domainId) deleteDomain(domainId: $domainId)
}`; }
`;
export const rollbackDeployment = gql` export const rollbackDeployment = gql`
mutation ($projectId: String! ,$deploymentId: String!) { mutation ($projectId: String!, $deploymentId: String!) {
rollbackDeployment(projectId: $projectId, deploymentId: $deploymentId) rollbackDeployment(projectId: $projectId, deploymentId: $deploymentId)
} }
`; `;
export const deleteDeployment = gql` export const deleteDeployment = gql`
mutation ($deploymentId: String!) { mutation ($deploymentId: String!) {
deleteDeployment(deploymentId: $deploymentId) deleteDeployment(deploymentId: $deploymentId)
} }
`; `;
export const addDomain = gql` export const addDomain = gql`
mutation ($projectId: String!, $data: AddDomainInput!) { mutation ($projectId: String!, $data: AddDomainInput!) {
addDomain(projectId: $projectId, data: $data) addDomain(projectId: $projectId, data: $data)
} }
`; `;
export const authenticateGitHub = gql` export const authenticateGitHub = gql`
mutation ($code: String!) { mutation ($code: String!) {
authenticateGitHub(code: $code) { authenticateGitHub(code: $code) {
token token
}
} }
}`; `;
export const unauthenticateGitHub = gql` export const unauthenticateGitHub = gql`
mutation { mutation {
unauthenticateGitHub unauthenticateGitHub
}`; }
`;

View File

@ -1,298 +1,311 @@
import { addProjectFromTemplate } from "./mutations";
// Note: equivalent to types present in GQL schema // Note: equivalent to types present in GQL schema
export enum Role { export enum Role {
Owner = 'Owner', Owner = "Owner",
Maintainer = 'Maintainer', Maintainer = "Maintainer",
Reader = 'Reader', Reader = "Reader",
} }
export enum Permission { export enum Permission {
View = 'View', View = "View",
Edit = 'Edit', Edit = "Edit",
} }
export enum Environment { export enum Environment {
Production = 'Production', Production = "Production",
Preview = 'Preview', Preview = "Preview",
Development = 'Development', Development = "Development",
} }
export enum DeploymentStatus { export enum DeploymentStatus {
Building = 'Building', Building = "Building",
Ready = 'Ready', Ready = "Ready",
Error = 'Error', Error = "Error",
Deleting = 'Deleting' Deleting = "Deleting",
} }
export enum DomainStatus { export enum DomainStatus {
Live = 'Live', Live = "Live",
Pending = 'Pending', Pending = "Pending",
} }
export type EnvironmentVariable = { export type EnvironmentVariable = {
id: string id: string;
environment: Environment environment: Environment;
key: string key: string;
value: string value: string;
createdAt: string createdAt: string;
updatedAt: string updatedAt: string;
} };
export type Domain = { export type Domain = {
id: string id: string;
branch: string branch: string;
name: string name: string;
status: DomainStatus status: DomainStatus;
redirectTo: Domain | null redirectTo: Domain | null;
createdAt: string createdAt: string;
updatedAt: string updatedAt: string;
} };
export type User = { export type User = {
id: string id: string;
name: string | null name: string | null;
email: string email: string;
isVerified: boolean isVerified: boolean;
createdAt: string createdAt: string;
updatedAt: string updatedAt: string;
gitHubToken: string | null gitHubToken: string | null;
} };
export type Deployment = { export type Deployment = {
id: string id: string;
domain: Domain domain: Domain;
branch: string branch: string;
commitHash: string commitHash: string;
commitMessage: string commitMessage: string;
url?: string url?: string;
environment: Environment environment: Environment;
isCurrent: boolean isCurrent: boolean;
status: DeploymentStatus status: DeploymentStatus;
createdBy: User createdBy: User;
createdAt: string createdAt: string;
updatedAt: string updatedAt: string;
} };
export type OrganizationMember = { export type OrganizationMember = {
id: string id: string;
member: User member: User;
role: Role role: Role;
createdAt: string createdAt: string;
updatedAt: string updatedAt: string;
} };
export type ProjectMember = { export type ProjectMember = {
id: string id: string;
member: User member: User;
permissions: Permission[] permissions: Permission[];
isPending: boolean isPending: boolean;
createdAt: string createdAt: string;
updatedAt: string updatedAt: string;
} };
export type OrganizationProject = { export type OrganizationProject = {
id: string id: string;
owner: User owner: User;
deployments: Deployment[] deployments: Deployment[];
name: string name: string;
repository: string repository: string;
prodBranch: string prodBranch: string;
description: string description: string;
template: string template: string;
framework: string framework: string;
webhooks: string[] webhooks: string[];
members: ProjectMember[] members: ProjectMember[];
environmentVariables: EnvironmentVariable[] environmentVariables: EnvironmentVariable[];
createdAt: string createdAt: string;
updatedAt: string updatedAt: string;
} };
export type Organization = { export type Organization = {
id: string id: string;
name: string name: string;
slug: string slug: string;
projects: OrganizationProject[] projects: OrganizationProject[];
createdAt: string createdAt: string;
updatedAt: string updatedAt: string;
members: OrganizationMember[] members: OrganizationMember[];
} };
export type Project = { export type Project = {
id: string id: string;
owner: User owner: User;
deployments: Deployment[] deployments: Deployment[];
name: string name: string;
repository: string repository: string;
prodBranch: string prodBranch: string;
description: string description: string;
template: string template: string;
framework: string framework: string;
webhooks: string[] webhooks: string[];
members: ProjectMember[] members: ProjectMember[];
environmentVariables: EnvironmentVariable[] environmentVariables: EnvironmentVariable[];
createdAt: string createdAt: string;
updatedAt: string updatedAt: string;
organization: Organization organization: Organization;
icon: string icon: string;
subDomain: string subDomain: string;
} };
export type GetProjectMembersResponse = { export type GetProjectMembersResponse = {
projectMembers: ProjectMember[] projectMembers: ProjectMember[];
} };
export type AddProjectMemberResponse = { export type AddProjectMemberResponse = {
addProjectMember: boolean addProjectMember: boolean;
} };
export type RemoveProjectMemberResponse = { export type RemoveProjectMemberResponse = {
removeProjectMember: boolean; removeProjectMember: boolean;
} };
export type UpdateProjectMemberResponse = { export type UpdateProjectMemberResponse = {
updateProjectMember: boolean; updateProjectMember: boolean;
} };
export type GetDeploymentsResponse = { export type GetDeploymentsResponse = {
deployments: Deployment[] deployments: Deployment[];
} };
export type GetEnvironmentVariablesResponse = { export type GetEnvironmentVariablesResponse = {
environmentVariables: EnvironmentVariable[] environmentVariables: EnvironmentVariable[];
} };
export type GetOrganizationsResponse = { export type GetOrganizationsResponse = {
organizations: Organization[] organizations: Organization[];
} };
export type GetUserResponse = { export type GetUserResponse = {
user: User user: User;
} };
export type GetProjectResponse = { export type GetProjectResponse = {
project: Project | null project: Project | null;
} };
export type GetProjectsInOrganizationResponse = { export type GetProjectsInOrganizationResponse = {
projectsInOrganization: Project[] projectsInOrganization: Project[];
} };
export type GetDomainsResponse = { export type GetDomainsResponse = {
domains: Domain[] domains: Domain[];
} };
export type SearchProjectsResponse = { export type SearchProjectsResponse = {
searchProjects: Project[] searchProjects: Project[];
} };
export type AddEnvironmentVariablesResponse = { export type AddEnvironmentVariablesResponse = {
addEnvironmentVariables: boolean; addEnvironmentVariables: boolean;
} };
export type AddEnvironmentVariableInput = { export type AddEnvironmentVariableInput = {
environments: string[]; environments: string[];
key: string; key: string;
value: string; value: string;
} };
export type UpdateEnvironmentVariableInput = { export type UpdateEnvironmentVariableInput = {
key: string; key: string;
value: string; value: string;
} };
export type UpdateProjectMemberInput = { export type UpdateProjectMemberInput = {
permissions: Permission[]; permissions: Permission[];
} };
export type AddProjectMemberInput = { export type AddProjectMemberInput = {
email: string; email: string;
permissions: Permission[] permissions: Permission[];
} };
export type UpdateEnvironmentVariableResponse = { export type UpdateEnvironmentVariableResponse = {
updateEnvironmentVariable: boolean; updateEnvironmentVariable: boolean;
} };
export type RemoveEnvironmentVariableResponse = { export type RemoveEnvironmentVariableResponse = {
removeEnvironmentVariable: boolean; removeEnvironmentVariable: boolean;
} };
export type UpdateDeploymentToProdResponse = { export type UpdateDeploymentToProdResponse = {
updateDeploymentToProd: boolean; updateDeploymentToProd: boolean;
} };
export type AddProjectFromTemplateResponse = {
addProjectFromTemplate: Project;
};
export type AddProjectResponse = { export type AddProjectResponse = {
addProject: Project addProject: Project;
} };
export type UpdateProjectResponse = { export type UpdateProjectResponse = {
updateProject: boolean; updateProject: boolean;
} };
export type UpdateDomainResponse = { export type UpdateDomainResponse = {
updateDomain: boolean; updateDomain: boolean;
} };
export type DeleteProjectResponse = { export type DeleteProjectResponse = {
deleteProject: boolean; deleteProject: boolean;
} };
export type DeleteDomainResponse = { export type DeleteDomainResponse = {
deleteDomain: boolean; deleteDomain: boolean;
} };
export type AddProjectFromTemplateInput = {
templateOwner: string;
templateRepo: string;
owner: string;
name: string;
isPrivate: boolean;
};
export type AddProjectInput = { export type AddProjectInput = {
name: string; name: string;
repository: string; repository: string;
prodBranch: string; prodBranch: string;
template?: string; template?: string;
} };
export type UpdateProjectInput = { export type UpdateProjectInput = {
name?: string name?: string;
description?: string description?: string;
prodBranch?: string prodBranch?: string;
webhooks?: string[] webhooks?: string[];
organizationId?: string organizationId?: string;
} };
export type UpdateDomainInput = { export type UpdateDomainInput = {
name?: string; name?: string;
branch?: string; branch?: string;
redirectToId?: string | null; redirectToId?: string | null;
} };
export type RedeployToProdResponse = { export type RedeployToProdResponse = {
redeployToProd: boolean redeployToProd: boolean;
} };
export type RollbackDeploymentResponse = { export type RollbackDeploymentResponse = {
rollbackDeployment: boolean rollbackDeployment: boolean;
} };
export type DeleteDeploymentResponse = { export type DeleteDeploymentResponse = {
deleteDeployment: boolean deleteDeployment: boolean;
} };
export type AddDomainInput = { export type AddDomainInput = {
name: string name: string;
} };
export type FilterDomainInput = { export type FilterDomainInput = {
branch?: string branch?: string;
status?: DomainStatus status?: DomainStatus;
} };
export type AddDomainResponse = { export type AddDomainResponse = {
addDomain: true addDomain: true;
} };
export type AuthenticateGitHubResponse = { export type AuthenticateGitHubResponse = {
authenticateGitHub: { authenticateGitHub: {
token: string token: string;
} };
} };
export type UnauthenticateGitHubResponse = { export type UnauthenticateGitHubResponse = {
unauthenticateGitHub: boolean unauthenticateGitHub: boolean;
} };