| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- import { getCreateMigrationsTableSQL, getInsertMigrationSQL } from '@supabase/pg-meta'
- import { isResponseOk } from './api/apiWrapper'
- import { fetchHandler } from '@/data/fetchers'
- import type { Integration } from '@/data/integrations/integrations.types'
- import { ResponseError, type SupaResponse } from '@/types'
- async function fetchGitHub<T = any>(url: string, responseJson = true): Promise<SupaResponse<T>> {
- const response = await fetchHandler(url)
- if (!response.ok) {
- return {
- error: new ResponseError(response.statusText, response.status),
- }
- }
- try {
- return (responseJson ? await response.json() : await response.text()) as T
- } catch (error: any) {
- return {
- error: new ResponseError(error.message, 500),
- }
- }
- }
- export type File = {
- name: string
- download_url: string
- }
- /**
- * Returns the initial migration SQL from a GitHub repo.
- * @param externalId An external GitHub URL for example: https://github.com/vercel/next.js/tree/canary/examples/with-briven
- */
- export async function getInitialMigrationSQLFromGitHubRepo(
- externalId?: string
- ): Promise<string | null> {
- if (!externalId) return null
- const [, , , owner, repo, , branch, ...pathSegments] = externalId?.split('/') ?? []
- const path = pathSegments.join('/')
- const baseGitHubUrl = `https://api.github.com/repos/${owner}/${repo}/contents/${path}`
- const brivenFolderUrl = `${baseGitHubUrl}/briven?ref=${branch}`
- const brivenMigrationsPath = `briven/migrations` // TODO: read this from the `briven/config.toml` file
- const migrationsFolderUrl = `${baseGitHubUrl}/${brivenMigrationsPath}${
- branch ? `?ref=${branch}` : ``
- }`
- const [brivenFilesResponse, migrationFilesResponse] = await Promise.all([
- fetchGitHub<File[]>(brivenFolderUrl),
- fetchGitHub<File[]>(migrationsFolderUrl),
- ])
- if (!isResponseOk(brivenFilesResponse)) {
- console.warn(`Failed to fetch briven files from GitHub: ${brivenFilesResponse.error}`)
- return null
- }
- if (!isResponseOk(migrationFilesResponse)) {
- console.warn(`Failed to fetch migration files from GitHub: ${migrationFilesResponse.error}`)
- return null
- }
- const seedFileUrl = brivenFilesResponse.find((file) => file.name === 'seed.sql')?.download_url
- const sortedFiles = migrationFilesResponse.sort((a, b) => {
- // sort by name ascending
- if (a.name < b.name) return -1
- if (a.name > b.name) return 1
- return 0
- })
- const migrationFileDownloadUrlPromises = sortedFiles.map((file) =>
- fetchGitHub<string>(file.download_url, false)
- )
- const [seedFileResponse, ...migrationFileResponses] = await Promise.all([
- seedFileUrl ? fetchGitHub<string>(seedFileUrl, false) : Promise.resolve<string>(''),
- ...migrationFileDownloadUrlPromises,
- ])
- const migrations = migrationFileResponses.filter((response) => isResponseOk(response)).join(';')
- const seed = isResponseOk(seedFileResponse) ? seedFileResponse : ''
- const createMigrationsTableSql = getCreateMigrationsTableSQL()
- const migrationsTableSql = `
- ${createMigrationsTableSql}
- ${sortedFiles
- .map((file, i) => {
- const migration = migrationFileResponses[i]
- if (!isResponseOk(migration)) return ''
- const version = file.name.split('_')[0]
- const statements = JSON.stringify(
- migration
- .split(';')
- .map((statement) => statement.trim())
- .filter(Boolean)
- )
- return getInsertMigrationSQL({ name: file.name, version, statements })
- })
- .join('')}
- `
- return `${migrations};${migrationsTableSql};${seed}`
- }
- type VercelIntegration = Extract<Integration, { integration: { name: 'Vercel' } }>
- type GitHubIntegration = Extract<Integration, { integration: { name: 'GitHub' } }>
- export function getIntegrationConfigurationUrl(integration: Integration) {
- if (integration.integration.name === 'Vercel') {
- return getVercelConfigurationUrl(integration as VercelIntegration)
- }
- if (integration.integration.name === 'GitHub') {
- return getGitHubConfigurationUrl(integration as GitHubIntegration)
- }
- return ''
- }
- function getVercelConfigurationUrl(integration: VercelIntegration) {
- return `https://vercel.com/dashboard/${
- integration.metadata?.account.type === 'Team'
- ? `${integration.metadata?.account.team_slug}/`
- : ''
- }integrations/${integration.metadata?.configuration_id}`
- }
- function getGitHubConfigurationUrl(integration: GitHubIntegration) {
- return `https://github.com/${
- integration.metadata?.account.type === 'Organization'
- ? `organizations/${integration.metadata?.account.name}/`
- : ''
- }settings/installations/${integration.metadata?.installation_id}`
- }
|