From e08ec12d261c6e18e7eb406777b39e54b92265e1 Mon Sep 17 00:00:00 2001 From: dominicbachmann Date: Tue, 5 Apr 2022 20:11:19 +0200 Subject: [PATCH] Introduced typing for the buildJob and cleaned up common.ts --- src/lib/common.ts | 78 ++++++++++++++++++++---------------- src/lib/queues/builder.ts | 28 +++++++------ src/lib/types/builderJob.ts | 51 +++++++++++++++++++++++ src/routes/dashboard.json.ts | 2 +- 4 files changed, 111 insertions(+), 48 deletions(-) create mode 100644 src/lib/types/builderJob.ts diff --git a/src/lib/common.ts b/src/lib/common.ts index 49a637065..185cb8c6d 100644 --- a/src/lib/common.ts +++ b/src/lib/common.ts @@ -12,7 +12,8 @@ import { version as currentVersion } from '../../package.json'; import dayjs from 'dayjs'; import Cookie from 'cookie'; import os from 'os'; -import cuid from 'cuid'; +import type { RequestEvent } from '@sveltejs/kit/types/internal'; +import type { Job } from 'bullmq'; try { if (!dev) { @@ -45,30 +46,26 @@ const customConfig: Config = { export const version = currentVersion; export const asyncExecShell = util.promisify(child.exec); -export const asyncSleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay)); +export const asyncSleep = (delay: number): Promise => + new Promise((resolve) => setTimeout(resolve, delay)); export const sentry = Sentry; -export const uniqueName = () => uniqueNamesGenerator(customConfig); +export const uniqueName = (): string => uniqueNamesGenerator(customConfig); -export const saveBuildLog = async ({ line, buildId, applicationId }) => { +export const saveBuildLog = async ({ + line, + buildId, + applicationId +}: { + line: string; + buildId: string; + applicationId: string; +}): Promise => { const addTimestamp = `${generateTimestamp()} ${line}`; return await buildLogQueue.add(buildId, { buildId, line: addTimestamp, applicationId }); }; -export const isTeamIdTokenAvailable = (request) => { - const cookie = request.headers.cookie - ?.split(';') - .map((s) => s.trim()) - .find((s) => s.startsWith('teamId=')) - ?.split('=')[1]; - if (!cookie) { - return getTeam(request); - } else { - return cookie; - } -}; - -export const getTeam = (event) => { +export const getTeam = (event: RequestEvent): string | null => { const cookies = Cookie.parse(event.request.headers.get('cookie')); if (cookies?.teamId) { return cookies.teamId; @@ -78,7 +75,16 @@ export const getTeam = (event) => { return null; }; -export const getUserDetails = async (event, isAdminRequired = true) => { +export const getUserDetails = async ( + event: RequestEvent, + isAdminRequired = true +): Promise<{ + teamId: string; + userId: string; + permission: string; + status: number; + body: { message: string }; +}> => { const teamId = getTeam(event); const userId = event?.locals?.session?.data?.userId || null; const { permission = 'read' } = await db.prisma.permission.findFirst({ @@ -104,11 +110,11 @@ export const getUserDetails = async (event, isAdminRequired = true) => { return payload; }; -export function getEngine(engine) { +export function getEngine(engine: string): string { return engine === '/var/run/docker.sock' ? 'unix:///var/run/docker.sock' : engine; } -export async function removeContainer(id, engine) { +export async function removeContainer(id: string, engine: string): Promise { const host = getEngine(engine); try { const { stdout } = await asyncExecShell( @@ -124,11 +130,23 @@ export async function removeContainer(id, engine) { } } -export const removeDestinationDocker = async ({ id, engine }) => { +export const removeDestinationDocker = async ({ + id, + engine +}: { + id: string; + engine: string; +}): Promise => { return await removeContainer(id, engine); }; -export const createDirectories = async ({ repository, buildId }) => { +export const createDirectories = async ({ + repository, + buildId +}: { + repository: string; + buildId: string; +}): Promise<{ workdir: string; repodir: string }> => { const repodir = `/tmp/build-sources/${repository}/`; const workdir = `/tmp/build-sources/${repository}/${buildId}`; @@ -140,20 +158,10 @@ export const createDirectories = async ({ repository, buildId }) => { }; }; -export function generateTimestamp() { +export function generateTimestamp(): string { return `${dayjs().format('HH:mm:ss.SSS')} `; } -export function getDomain(domain) { +export function getDomain(domain: string): string { return domain?.replace('https://', '').replace('http://', ''); } - -export function dashify(str: string, options?: any): string { - if (typeof str !== 'string') return str; - return str - .trim() - .replace(/\W/g, (m) => (/[À-ž]/.test(m) ? m : '-')) - .replace(/^-+|-+$/g, '') - .replace(/-{2,}/g, (m) => (options && options.condense ? '-' : m)) - .toLowerCase(); -} diff --git a/src/lib/queues/builder.ts b/src/lib/queues/builder.ts index 0ef207f2a..e7c0e6469 100644 --- a/src/lib/queues/builder.ts +++ b/src/lib/queues/builder.ts @@ -20,30 +20,24 @@ import { setDefaultConfiguration } from '$lib/buildPacks/common'; import yaml from 'js-yaml'; +import type { Job } from 'bullmq'; +import type { BuilderJob } from '$lib/types/builderJob'; -export default async function (job) { +export default async function (job: Job): Promise { /* Edge cases: 1 - Change build pack and redeploy, what should happen? */ - let { + const { id: applicationId, repository, - branch, - buildPack, name, destinationDocker, destinationDockerId, gitSource, build_id: buildId, configHash, - port, - installCommand, - buildCommand, - startCommand, fqdn, - baseDirectory, - publishDirectory, projectId, secrets, phpModules, @@ -56,6 +50,16 @@ export default async function (job) { pythonModule, pythonVariable } = job.data; + let { + branch, + buildPack, + port, + installCommand, + buildCommand, + startCommand, + baseDirectory, + publishDirectory + } = job.data; const { debug } = settings; await asyncSleep(500); @@ -70,7 +74,7 @@ export default async function (job) { }); let imageId = applicationId; let domain = getDomain(fqdn); - let volumes = + const volumes = persistentStorage?.map((storage) => { return `${applicationId}${storage.path.replace(/\//gi, '-')}:${ buildPack !== 'docker' ? '/app' : '' @@ -106,7 +110,7 @@ export default async function (job) { publishDirectory = configuration.publishDirectory; baseDirectory = configuration.baseDirectory; - let commit = await importers[gitSource.type]({ + const commit = await importers[gitSource.type]({ applicationId, debug, workdir, diff --git a/src/lib/types/builderJob.ts b/src/lib/types/builderJob.ts new file mode 100644 index 000000000..0f96520e5 --- /dev/null +++ b/src/lib/types/builderJob.ts @@ -0,0 +1,51 @@ +import type { DestinationDocker, GithubApp, GitlabApp, GitSource, Secret } from '@prisma/client'; + +export type BuilderJob = { + build_id: string; + type: BuildType; + id: string; + name: string; + fqdn: string; + repository: string; + configHash: unknown; + branch: string; + buildPack: BuildPackName; + projectId: number; + port: number; + installCommand: string; + buildCommand?: string; + startCommand?: string; + baseDirectory: string; + publishDirectory: string; + phpModules: unknown; // probably an array of some type; + pythonWSGI: unknown; // probably a string?; + pythonModule: unknown; // probably a string?; + pythonVariable: unknown; // probably a string?; + createdAt: string; + updatedAt: string; + destinationDockerId: string; + destinationDocker: DestinationDocker; + gitSource: GitSource & { githubApp?: GithubApp; gitlabApp?: GitlabApp }; + settings: BuilderJobSettings; + secrets: Secret[]; + persistentStorage: { path: string }[]; + pullmergeRequestId?: unknown; + sourceBranch?: string; +}; + +// TODO: Add the other build types +export type BuildType = 'manual'; + +// TODO: Add the other buildpack names +export type BuildPackName = 'node' | 'docker'; + +export type BuilderJobSettings = { + id: string; + applicationId: string; + dualCerts: boolean; + debug: boolean; + previews: boolean; + autodeploy: boolean; + createdAt: string; + updatedAt: string; +}; diff --git a/src/routes/dashboard.json.ts b/src/routes/dashboard.json.ts index 4c3ed3097..077ffe2df 100644 --- a/src/routes/dashboard.json.ts +++ b/src/routes/dashboard.json.ts @@ -1,4 +1,4 @@ -import { getTeam, getUserDetails } from '$lib/common'; +import { getUserDetails } from '$lib/common'; import * as db from '$lib/database'; import { ErrorHandler } from '$lib/database'; import type { RequestHandler } from '@sveltejs/kit';