circleci-integration-setup

This commit is contained in:
Aashish-Upadhyay-101
2023-02-04 15:28:04 +05:45
parent 3ccc6e5d5c
commit 5ba851adff
5 changed files with 321 additions and 308 deletions
+98 -101
View File
@@ -1,7 +1,7 @@
import axios from 'axios'; import axios from "axios";
import * as Sentry from '@sentry/node'; import * as Sentry from "@sentry/node";
import { Octokit } from '@octokit/rest'; import { Octokit } from "@octokit/rest";
import { IIntegrationAuth } from '../models'; import { IIntegrationAuth } from "../models";
import { import {
INTEGRATION_HEROKU, INTEGRATION_HEROKU,
INTEGRATION_VERCEL, INTEGRATION_VERCEL,
@@ -9,12 +9,13 @@ import {
INTEGRATION_GITHUB, INTEGRATION_GITHUB,
INTEGRATION_RENDER, INTEGRATION_RENDER,
INTEGRATION_FLYIO, INTEGRATION_FLYIO,
INTEGRATION_CIRCLECI,
INTEGRATION_HEROKU_API_URL, INTEGRATION_HEROKU_API_URL,
INTEGRATION_VERCEL_API_URL, INTEGRATION_VERCEL_API_URL,
INTEGRATION_NETLIFY_API_URL, INTEGRATION_NETLIFY_API_URL,
INTEGRATION_RENDER_API_URL, INTEGRATION_RENDER_API_URL,
INTEGRATION_FLYIO_API_URL INTEGRATION_FLYIO_API_URL,
} from '../variables'; } from "../variables";
/** /**
* Return list of names of apps for integration named [integration] * Return list of names of apps for integration named [integration]
@@ -26,7 +27,7 @@ import {
*/ */
const getApps = async ({ const getApps = async ({
integrationAuth, integrationAuth,
accessToken accessToken,
}: { }: {
integrationAuth: IIntegrationAuth; integrationAuth: IIntegrationAuth;
accessToken: string; accessToken: string;
@@ -42,40 +43,45 @@ const getApps = async ({
switch (integrationAuth.integration) { switch (integrationAuth.integration) {
case INTEGRATION_HEROKU: case INTEGRATION_HEROKU:
apps = await getAppsHeroku({ apps = await getAppsHeroku({
accessToken accessToken,
}); });
break; break;
case INTEGRATION_VERCEL: case INTEGRATION_VERCEL:
apps = await getAppsVercel({ apps = await getAppsVercel({
integrationAuth, integrationAuth,
accessToken accessToken,
}); });
break; break;
case INTEGRATION_NETLIFY: case INTEGRATION_NETLIFY:
apps = await getAppsNetlify({ apps = await getAppsNetlify({
accessToken accessToken,
}); });
break; break;
case INTEGRATION_GITHUB: case INTEGRATION_GITHUB:
apps = await getAppsGithub({ apps = await getAppsGithub({
accessToken accessToken,
}); });
break; break;
case INTEGRATION_RENDER: case INTEGRATION_RENDER:
apps = await getAppsRender({ apps = await getAppsRender({
accessToken accessToken,
}); });
break; break;
case INTEGRATION_FLYIO: case INTEGRATION_FLYIO:
apps = await getAppsFlyio({ apps = await getAppsFlyio({
accessToken accessToken,
});
break;
case INTEGRATION_CIRCLECI:
apps = await getAppsCircleci({
accessToken,
}); });
break; break;
} }
} catch (err) { } catch (err) {
Sentry.setUser(null); Sentry.setUser(null);
Sentry.captureException(err); Sentry.captureException(err);
throw new Error('Failed to get integration apps'); throw new Error("Failed to get integration apps");
} }
return apps; return apps;
@@ -94,19 +100,19 @@ const getAppsHeroku = async ({ accessToken }: { accessToken: string }) => {
const res = ( const res = (
await axios.get(`${INTEGRATION_HEROKU_API_URL}/apps`, { await axios.get(`${INTEGRATION_HEROKU_API_URL}/apps`, {
headers: { headers: {
Accept: 'application/vnd.heroku+json; version=3', Accept: "application/vnd.heroku+json; version=3",
Authorization: `Bearer ${accessToken}` Authorization: `Bearer ${accessToken}`,
} },
}) })
).data; ).data;
apps = res.map((a: any) => ({ apps = res.map((a: any) => ({
name: a.name name: a.name,
})); }));
} catch (err) { } catch (err) {
Sentry.setUser(null); Sentry.setUser(null);
Sentry.captureException(err); Sentry.captureException(err);
throw new Error('Failed to get Heroku integration apps'); throw new Error("Failed to get Heroku integration apps");
} }
return apps; return apps;
@@ -119,10 +125,10 @@ const getAppsHeroku = async ({ accessToken }: { accessToken: string }) => {
* @returns {Object[]} apps - names of Vercel apps * @returns {Object[]} apps - names of Vercel apps
* @returns {String} apps.name - name of Vercel app * @returns {String} apps.name - name of Vercel app
*/ */
const getAppsVercel = async ({ const getAppsVercel = async ({
integrationAuth, integrationAuth,
accessToken accessToken,
}: { }: {
integrationAuth: IIntegrationAuth; integrationAuth: IIntegrationAuth;
accessToken: string; accessToken: string;
}) => { }) => {
@@ -131,23 +137,25 @@ const getAppsVercel = async ({
const res = ( const res = (
await axios.get(`${INTEGRATION_VERCEL_API_URL}/v9/projects`, { await axios.get(`${INTEGRATION_VERCEL_API_URL}/v9/projects`, {
headers: { headers: {
Authorization: `Bearer ${accessToken}` Authorization: `Bearer ${accessToken}`,
}, },
...( integrationAuth?.teamId ? { ...(integrationAuth?.teamId
params: { ? {
teamId: integrationAuth.teamId params: {
} teamId: integrationAuth.teamId,
} : {}) },
}
: {}),
}) })
).data; ).data;
apps = res.projects.map((a: any) => ({ apps = res.projects.map((a: any) => ({
name: a.name name: a.name,
})); }));
} catch (err) { } catch (err) {
Sentry.setUser(null); Sentry.setUser(null);
Sentry.captureException(err); Sentry.captureException(err);
throw new Error('Failed to get Vercel integration apps'); throw new Error("Failed to get Vercel integration apps");
} }
return apps; return apps;
@@ -160,29 +168,25 @@ const getAppsVercel = async ({
* @returns {Object[]} apps - names of Netlify sites * @returns {Object[]} apps - names of Netlify sites
* @returns {String} apps.name - name of Netlify site * @returns {String} apps.name - name of Netlify site
*/ */
const getAppsNetlify = async ({ const getAppsNetlify = async ({ accessToken }: { accessToken: string }) => {
accessToken
}: {
accessToken: string;
}) => {
let apps; let apps;
try { try {
const res = ( const res = (
await axios.get(`${INTEGRATION_NETLIFY_API_URL}/api/v1/sites`, { await axios.get(`${INTEGRATION_NETLIFY_API_URL}/api/v1/sites`, {
headers: { headers: {
Authorization: `Bearer ${accessToken}` Authorization: `Bearer ${accessToken}`,
} },
}) })
).data; ).data;
apps = res.map((a: any) => ({ apps = res.map((a: any) => ({
name: a.name, name: a.name,
appId: a.site_id appId: a.site_id,
})); }));
} catch (err) { } catch (err) {
Sentry.setUser(null); Sentry.setUser(null);
Sentry.captureException(err); Sentry.captureException(err);
throw new Error('Failed to get Netlify integration apps'); throw new Error("Failed to get Netlify integration apps");
} }
return apps; return apps;
@@ -195,35 +199,32 @@ const getAppsNetlify = async ({
* @returns {Object[]} apps - names of Netlify sites * @returns {Object[]} apps - names of Netlify sites
* @returns {String} apps.name - name of Netlify site * @returns {String} apps.name - name of Netlify site
*/ */
const getAppsGithub = async ({ const getAppsGithub = async ({ accessToken }: { accessToken: string }) => {
accessToken
}: {
accessToken: string;
}) => {
let apps; let apps;
try { try {
const octokit = new Octokit({ const octokit = new Octokit({
auth: accessToken auth: accessToken,
}); });
const repos = (await octokit.request( const repos = (
'GET /user/repos{?visibility,affiliation,type,sort,direction,per_page,page,since,before}', await octokit.request(
{ "GET /user/repos{?visibility,affiliation,type,sort,direction,per_page,page,since,before}",
per_page: 100 {
} per_page: 100,
)).data; }
)
).data;
apps = repos apps = repos
.filter((a:any) => a.permissions.admin === true) .filter((a: any) => a.permissions.admin === true)
.map((a: any) => ({ .map((a: any) => ({
name: a.name, name: a.name,
owner: a.owner.login owner: a.owner.login,
}) }));
);
} catch (err) { } catch (err) {
Sentry.setUser(null); Sentry.setUser(null);
Sentry.captureException(err); Sentry.captureException(err);
throw new Error('Failed to get Github repos'); throw new Error("Failed to get Github repos");
} }
return apps; return apps;
@@ -237,34 +238,29 @@ const getAppsGithub = async ({
* @returns {String} apps.name - name of Render service * @returns {String} apps.name - name of Render service
* @returns {String} apps.appId - id of Render service * @returns {String} apps.appId - id of Render service
*/ */
const getAppsRender = async ({ const getAppsRender = async ({ accessToken }: { accessToken: string }) => {
accessToken
}: {
accessToken: string;
}) => {
let apps: any; let apps: any;
try { try {
const res = ( const res = (
await axios.get(`${INTEGRATION_RENDER_API_URL}/v1/services`, { await axios.get(`${INTEGRATION_RENDER_API_URL}/v1/services`, {
headers: { headers: {
Authorization: `Bearer ${accessToken}` Authorization: `Bearer ${accessToken}`,
} },
}) })
).data; ).data;
apps = res apps = res.map((a: any) => ({
.map((a: any) => ({ name: a.service.name,
name: a.service.name, appId: a.service.id,
appId: a.service.id }));
}));
} catch (err) { } catch (err) {
Sentry.setUser(null); Sentry.setUser(null);
Sentry.captureException(err); Sentry.captureException(err);
throw new Error('Failed to get Render services'); throw new Error("Failed to get Render services");
} }
return apps; return apps;
} };
/** /**
* Return list of apps for Fly.io integration * Return list of apps for Fly.io integration
@@ -273,11 +269,7 @@ const getAppsRender = async ({
* @returns {Object[]} apps - names and ids of Fly.io apps * @returns {Object[]} apps - names and ids of Fly.io apps
* @returns {String} apps.name - name of Fly.io apps * @returns {String} apps.name - name of Fly.io apps
*/ */
const getAppsFlyio = async ({ const getAppsFlyio = async ({ accessToken }: { accessToken: string }) => {
accessToken
}: {
accessToken: string;
}) => {
let apps; let apps;
try { try {
const query = ` const query = `
@@ -291,32 +283,37 @@ const getAppsFlyio = async ({
} }
} }
`; `;
const res = (await axios({ const res = (
url: INTEGRATION_FLYIO_API_URL, await axios({
method: 'post', url: INTEGRATION_FLYIO_API_URL,
headers: { method: "post",
'Authorization': 'Bearer ' + accessToken headers: {
}, Authorization: "Bearer " + accessToken,
data: { },
query, data: {
variables: { query,
role: null variables: {
} role: null,
} },
})).data.data.apps.nodes; },
})
apps = res ).data.data.apps.nodes;
.map((a: any) => ({
name: a.name apps = res.map((a: any) => ({
})); name: a.name,
}));
} catch (err) { } catch (err) {
Sentry.setUser(null); Sentry.setUser(null);
Sentry.captureException(err); Sentry.captureException(err);
throw new Error('Failed to get Fly.io apps'); throw new Error("Failed to get Fly.io apps");
} }
return apps; return apps;
} };
const getAppsCircleci = async ({ accessToken }: { accessToken: string }) => {
return [];
};
export { getApps }; export { getApps };
+32 -23
View File
@@ -1,12 +1,12 @@
import { Schema, model, Types } from 'mongoose'; import { Schema, model, Types } from "mongoose";
import { import {
INTEGRATION_HEROKU, INTEGRATION_HEROKU,
INTEGRATION_VERCEL, INTEGRATION_VERCEL,
INTEGRATION_NETLIFY, INTEGRATION_NETLIFY,
INTEGRATION_GITHUB, INTEGRATION_GITHUB,
INTEGRATION_RENDER, INTEGRATION_RENDER,
INTEGRATION_FLYIO INTEGRATION_FLYIO,
} from '../variables'; } from "../variables";
export interface IIntegration { export interface IIntegration {
_id: Types.ObjectId; _id: Types.ObjectId;
@@ -17,44 +17,53 @@ export interface IIntegration {
owner: string; owner: string;
targetEnvironment: string; targetEnvironment: string;
appId: string; appId: string;
integration: 'heroku' | 'vercel' | 'netlify' | 'github' | 'render' | 'flyio'; integration:
| "heroku"
| "vercel"
| "netlify"
| "github"
| "render"
| "flyio"
| "circleci";
integrationAuth: Types.ObjectId; integrationAuth: Types.ObjectId;
} }
const integrationSchema = new Schema<IIntegration>( const integrationSchema = new Schema<IIntegration>(
{ {
workspace: { workspace: {
type: Schema.Types.ObjectId, type: Schema.Types.ObjectId,
ref: 'Workspace', ref: "Workspace",
required: true required: true,
}, },
environment: { environment: {
type: String, type: String,
required: true required: true,
}, },
isActive: { isActive: {
type: Boolean, type: Boolean,
required: true required: true,
}, },
app: { app: {
// name of app in provider // name of app in provider
type: String, type: String,
default: null default: null,
}, },
appId: { // (new) appId: {
// (new)
// id of app in provider // id of app in provider
type: String, type: String,
default: null default: null,
}, },
targetEnvironment: { // (new) targetEnvironment: {
// target environment // (new)
// target environment
type: String, type: String,
default: null default: null,
}, },
owner: { owner: {
// github-specific repo owner-login // github-specific repo owner-login
type: String, type: String,
default: null default: null,
}, },
integration: { integration: {
type: String, type: String,
@@ -64,21 +73,21 @@ const integrationSchema = new Schema<IIntegration>(
INTEGRATION_NETLIFY, INTEGRATION_NETLIFY,
INTEGRATION_GITHUB, INTEGRATION_GITHUB,
INTEGRATION_RENDER, INTEGRATION_RENDER,
INTEGRATION_FLYIO INTEGRATION_FLYIO,
], ],
required: true required: true,
}, },
integrationAuth: { integrationAuth: {
type: Schema.Types.ObjectId, type: Schema.Types.ObjectId,
ref: 'IntegrationAuth', ref: "IntegrationAuth",
required: true required: true,
} },
}, },
{ {
timestamps: true timestamps: true,
} }
); );
const Integration = model<IIntegration>('Integration', integrationSchema); const Integration = model<IIntegration>("Integration", integrationSchema);
export default Integration; export default Integration;
+28 -21
View File
@@ -1,15 +1,22 @@
import { Schema, model, Types } from 'mongoose'; import { Schema, model, Types } from "mongoose";
import { import {
INTEGRATION_HEROKU, INTEGRATION_HEROKU,
INTEGRATION_VERCEL, INTEGRATION_VERCEL,
INTEGRATION_NETLIFY, INTEGRATION_NETLIFY,
INTEGRATION_GITHUB INTEGRATION_GITHUB,
} from '../variables'; } from "../variables";
export interface IIntegrationAuth { export interface IIntegrationAuth {
_id: Types.ObjectId; _id: Types.ObjectId;
workspace: Types.ObjectId; workspace: Types.ObjectId;
integration: 'heroku' | 'vercel' | 'netlify' | 'github' | 'render' | 'flyio'; integration:
| "heroku"
| "vercel"
| "netlify"
| "github"
| "render"
| "flyio"
| "circleci";
teamId: string; teamId: string;
accountId: string; accountId: string;
refreshCiphertext?: string; refreshCiphertext?: string;
@@ -24,9 +31,9 @@ export interface IIntegrationAuth {
const integrationAuthSchema = new Schema<IIntegrationAuth>( const integrationAuthSchema = new Schema<IIntegrationAuth>(
{ {
workspace: { workspace: {
type: Schema.Types.ObjectId, type: Schema.Types.ObjectId,
ref: 'Workspace', ref: "Workspace",
required: true required: true,
}, },
integration: { integration: {
type: String, type: String,
@@ -34,54 +41,54 @@ const integrationAuthSchema = new Schema<IIntegrationAuth>(
INTEGRATION_HEROKU, INTEGRATION_HEROKU,
INTEGRATION_VERCEL, INTEGRATION_VERCEL,
INTEGRATION_NETLIFY, INTEGRATION_NETLIFY,
INTEGRATION_GITHUB INTEGRATION_GITHUB,
], ],
required: true required: true,
}, },
teamId: { teamId: {
// vercel-specific integration param // vercel-specific integration param
type: String type: String,
}, },
accountId: { accountId: {
// netlify-specific integration param // netlify-specific integration param
type: String type: String,
}, },
refreshCiphertext: { refreshCiphertext: {
type: String, type: String,
select: false select: false,
}, },
refreshIV: { refreshIV: {
type: String, type: String,
select: false select: false,
}, },
refreshTag: { refreshTag: {
type: String, type: String,
select: false select: false,
}, },
accessCiphertext: { accessCiphertext: {
type: String, type: String,
select: false select: false,
}, },
accessIV: { accessIV: {
type: String, type: String,
select: false select: false,
}, },
accessTag: { accessTag: {
type: String, type: String,
select: false select: false,
}, },
accessExpiresAt: { accessExpiresAt: {
type: Date, type: Date,
select: false select: false,
} },
}, },
{ {
timestamps: true timestamps: true,
} }
); );
const IntegrationAuth = model<IIntegrationAuth>( const IntegrationAuth = model<IIntegrationAuth>(
'IntegrationAuth', "IntegrationAuth",
integrationAuthSchema integrationAuthSchema
); );
+13 -17
View File
@@ -3,8 +3,8 @@ import {
ENV_TESTING, ENV_TESTING,
ENV_STAGING, ENV_STAGING,
ENV_PROD, ENV_PROD,
ENV_SET ENV_SET,
} from './environment'; } from "./environment";
import { import {
INTEGRATION_HEROKU, INTEGRATION_HEROKU,
INTEGRATION_VERCEL, INTEGRATION_VERCEL,
@@ -12,6 +12,7 @@ import {
INTEGRATION_GITHUB, INTEGRATION_GITHUB,
INTEGRATION_RENDER, INTEGRATION_RENDER,
INTEGRATION_FLYIO, INTEGRATION_FLYIO,
INTEGRATION_CIRCLECI,
INTEGRATION_SET, INTEGRATION_SET,
INTEGRATION_OAUTH2, INTEGRATION_OAUTH2,
INTEGRATION_HEROKU_TOKEN_URL, INTEGRATION_HEROKU_TOKEN_URL,
@@ -23,25 +24,19 @@ import {
INTEGRATION_NETLIFY_API_URL, INTEGRATION_NETLIFY_API_URL,
INTEGRATION_RENDER_API_URL, INTEGRATION_RENDER_API_URL,
INTEGRATION_FLYIO_API_URL, INTEGRATION_FLYIO_API_URL,
INTEGRATION_OPTIONS INTEGRATION_OPTIONS,
} from './integration'; } from "./integration";
import { import { OWNER, ADMIN, MEMBER, INVITED, ACCEPTED } from "./organization";
OWNER, import { SECRET_SHARED, SECRET_PERSONAL } from "./secret";
ADMIN, import { EVENT_PUSH_SECRETS, EVENT_PULL_SECRETS } from "./event";
MEMBER,
INVITED,
ACCEPTED,
} from './organization';
import { SECRET_SHARED, SECRET_PERSONAL } from './secret';
import { EVENT_PUSH_SECRETS, EVENT_PULL_SECRETS } from './event';
import { import {
ACTION_ADD_SECRETS, ACTION_ADD_SECRETS,
ACTION_UPDATE_SECRETS, ACTION_UPDATE_SECRETS,
ACTION_DELETE_SECRETS, ACTION_DELETE_SECRETS,
ACTION_READ_SECRETS ACTION_READ_SECRETS,
} from './action'; } from "./action";
import { SMTP_HOST_SENDGRID, SMTP_HOST_MAILGUN } from './smtp'; import { SMTP_HOST_SENDGRID, SMTP_HOST_MAILGUN } from "./smtp";
import { PLAN_STARTER, PLAN_PRO } from './stripe'; import { PLAN_STARTER, PLAN_PRO } from "./stripe";
export { export {
OWNER, OWNER,
@@ -62,6 +57,7 @@ export {
INTEGRATION_GITHUB, INTEGRATION_GITHUB,
INTEGRATION_RENDER, INTEGRATION_RENDER,
INTEGRATION_FLYIO, INTEGRATION_FLYIO,
INTEGRATION_CIRCLECI,
INTEGRATION_SET, INTEGRATION_SET,
INTEGRATION_OAUTH2, INTEGRATION_OAUTH2,
INTEGRATION_HEROKU_TOKEN_URL, INTEGRATION_HEROKU_TOKEN_URL,
+150 -146
View File
@@ -1,164 +1,168 @@
import { import {
CLIENT_ID_HEROKU, CLIENT_ID_HEROKU,
CLIENT_ID_NETLIFY, CLIENT_ID_NETLIFY,
CLIENT_ID_GITHUB, CLIENT_ID_GITHUB,
CLIENT_SLUG_VERCEL CLIENT_SLUG_VERCEL,
} from '../config'; } from "../config";
// integrations // integrations
const INTEGRATION_HEROKU = 'heroku'; const INTEGRATION_HEROKU = "heroku";
const INTEGRATION_VERCEL = 'vercel'; const INTEGRATION_VERCEL = "vercel";
const INTEGRATION_NETLIFY = 'netlify'; const INTEGRATION_NETLIFY = "netlify";
const INTEGRATION_GITHUB = 'github'; const INTEGRATION_GITHUB = "github";
const INTEGRATION_RENDER = 'render'; const INTEGRATION_RENDER = "render";
const INTEGRATION_FLYIO = 'flyio'; const INTEGRATION_FLYIO = "flyio";
const INTEGRATION_CIRCLECI = "circleci";
const INTEGRATION_SET = new Set([ const INTEGRATION_SET = new Set([
INTEGRATION_HEROKU, INTEGRATION_HEROKU,
INTEGRATION_VERCEL, INTEGRATION_VERCEL,
INTEGRATION_NETLIFY, INTEGRATION_NETLIFY,
INTEGRATION_GITHUB, INTEGRATION_GITHUB,
INTEGRATION_RENDER, INTEGRATION_RENDER,
INTEGRATION_FLYIO INTEGRATION_FLYIO,
INTEGRATION_CIRCLECI,
]); ]);
// integration types // integration types
const INTEGRATION_OAUTH2 = 'oauth2'; const INTEGRATION_OAUTH2 = "oauth2";
// integration oauth endpoints // integration oauth endpoints
const INTEGRATION_HEROKU_TOKEN_URL = 'https://id.heroku.com/oauth/token'; const INTEGRATION_HEROKU_TOKEN_URL = "https://id.heroku.com/oauth/token";
const INTEGRATION_VERCEL_TOKEN_URL = const INTEGRATION_VERCEL_TOKEN_URL =
'https://api.vercel.com/v2/oauth/access_token'; "https://api.vercel.com/v2/oauth/access_token";
const INTEGRATION_NETLIFY_TOKEN_URL = 'https://api.netlify.com/oauth/token'; const INTEGRATION_NETLIFY_TOKEN_URL = "https://api.netlify.com/oauth/token";
const INTEGRATION_GITHUB_TOKEN_URL = const INTEGRATION_GITHUB_TOKEN_URL =
'https://github.com/login/oauth/access_token'; "https://github.com/login/oauth/access_token";
// integration apps endpoints // integration apps endpoints
const INTEGRATION_HEROKU_API_URL = 'https://api.heroku.com'; const INTEGRATION_HEROKU_API_URL = "https://api.heroku.com";
const INTEGRATION_VERCEL_API_URL = 'https://api.vercel.com'; const INTEGRATION_VERCEL_API_URL = "https://api.vercel.com";
const INTEGRATION_NETLIFY_API_URL = 'https://api.netlify.com'; const INTEGRATION_NETLIFY_API_URL = "https://api.netlify.com";
const INTEGRATION_RENDER_API_URL = 'https://api.render.com'; const INTEGRATION_RENDER_API_URL = "https://api.render.com";
const INTEGRATION_FLYIO_API_URL = 'https://api.fly.io/graphql'; const INTEGRATION_FLYIO_API_URL = "https://api.fly.io/graphql";
const INTEGRATION_CIRCLECI_API_URL = "https://circleci.com/api/v2";
const INTEGRATION_OPTIONS = [ const INTEGRATION_OPTIONS = [
{ {
name: 'Heroku', name: "Heroku",
slug: 'heroku', slug: "heroku",
image: 'Heroku.png', image: "Heroku.png",
isAvailable: true, isAvailable: true,
type: 'oauth', type: "oauth",
clientId: CLIENT_ID_HEROKU, clientId: CLIENT_ID_HEROKU,
docsLink: '' docsLink: "",
}, },
{ {
name: 'Vercel', name: "Vercel",
slug: 'vercel', slug: "vercel",
image: 'Vercel.png', image: "Vercel.png",
isAvailable: true, isAvailable: true,
type: 'oauth', type: "oauth",
clientId: '', clientId: "",
clientSlug: CLIENT_SLUG_VERCEL, clientSlug: CLIENT_SLUG_VERCEL,
docsLink: '' docsLink: "",
}, },
{ {
name: 'Netlify', name: "Netlify",
slug: 'netlify', slug: "netlify",
image: 'Netlify.png', image: "Netlify.png",
isAvailable: true, isAvailable: true,
type: 'oauth', type: "oauth",
clientId: CLIENT_ID_NETLIFY, clientId: CLIENT_ID_NETLIFY,
docsLink: '' docsLink: "",
}, },
{ {
name: 'GitHub', name: "GitHub",
slug: 'github', slug: "github",
image: 'GitHub.png', image: "GitHub.png",
isAvailable: true, isAvailable: true,
type: 'oauth', type: "oauth",
clientId: CLIENT_ID_GITHUB, clientId: CLIENT_ID_GITHUB,
docsLink: '' docsLink: "",
}, },
{ {
name: 'Render', name: "Render",
slug: 'render', slug: "render",
image: 'Render.png', image: "Render.png",
isAvailable: true, isAvailable: true,
type: 'pat', type: "pat",
clientId: '', clientId: "",
docsLink: '' docsLink: "",
}, },
{ {
name: 'Fly.io', name: "Fly.io",
slug: 'flyio', slug: "flyio",
image: 'Flyio.svg', image: "Flyio.svg",
isAvailable: true, isAvailable: true,
type: 'pat', type: "pat",
clientId: '', clientId: "",
docsLink: '' docsLink: "",
}, },
{ {
name: 'Google Cloud Platform', name: "Google Cloud Platform",
slug: 'gcp', slug: "gcp",
image: 'Google Cloud Platform.png', image: "Google Cloud Platform.png",
isAvailable: false, isAvailable: false,
type: '', type: "",
clientId: '', clientId: "",
docsLink: '' docsLink: "",
}, },
{ {
name: 'Amazon Web Services', name: "Amazon Web Services",
slug: 'aws', slug: "aws",
image: 'Amazon Web Services.png', image: "Amazon Web Services.png",
isAvailable: false, isAvailable: false,
type: '', type: "",
clientId: '', clientId: "",
docsLink: '' docsLink: "",
}, },
{ {
name: 'Microsoft Azure', name: "Microsoft Azure",
slug: 'azure', slug: "azure",
image: 'Microsoft Azure.png', image: "Microsoft Azure.png",
isAvailable: false, isAvailable: false,
type: '', type: "",
clientId: '', clientId: "",
docsLink: '' docsLink: "",
}, },
{ {
name: 'Travis CI', name: "Travis CI",
slug: 'travisci', slug: "travisci",
image: 'Travis CI.png', image: "Travis CI.png",
isAvailable: false, isAvailable: false,
type: '', type: "",
clientId: '', clientId: "",
docsLink: '' docsLink: "",
}, },
{ {
name: 'Circle CI', name: "Circle CI",
slug: 'circleci', slug: "circleci",
image: 'Circle CI.png', image: "Circle CI.png",
isAvailable: false, isAvailable: false,
type: '', type: "",
clientId: '', clientId: "",
docsLink: '' docsLink: "",
} },
] ];
export { export {
INTEGRATION_HEROKU, INTEGRATION_HEROKU,
INTEGRATION_VERCEL, INTEGRATION_VERCEL,
INTEGRATION_NETLIFY, INTEGRATION_NETLIFY,
INTEGRATION_GITHUB, INTEGRATION_GITHUB,
INTEGRATION_RENDER, INTEGRATION_RENDER,
INTEGRATION_FLYIO, INTEGRATION_FLYIO,
INTEGRATION_SET, INTEGRATION_CIRCLECI,
INTEGRATION_OAUTH2, INTEGRATION_SET,
INTEGRATION_HEROKU_TOKEN_URL, INTEGRATION_OAUTH2,
INTEGRATION_VERCEL_TOKEN_URL, INTEGRATION_HEROKU_TOKEN_URL,
INTEGRATION_NETLIFY_TOKEN_URL, INTEGRATION_VERCEL_TOKEN_URL,
INTEGRATION_GITHUB_TOKEN_URL, INTEGRATION_NETLIFY_TOKEN_URL,
INTEGRATION_HEROKU_API_URL, INTEGRATION_GITHUB_TOKEN_URL,
INTEGRATION_VERCEL_API_URL, INTEGRATION_HEROKU_API_URL,
INTEGRATION_NETLIFY_API_URL, INTEGRATION_VERCEL_API_URL,
INTEGRATION_RENDER_API_URL, INTEGRATION_NETLIFY_API_URL,
INTEGRATION_FLYIO_API_URL, INTEGRATION_RENDER_API_URL,
INTEGRATION_OPTIONS INTEGRATION_FLYIO_API_URL,
INTEGRATION_OPTIONS,
}; };