import fs from 'node:fs/promises'
import url from 'node:url'
import path from 'node:path'
import unzipper from 'unzipper'
import { Readable } from 'node:stream'
import { Octokit } from '@octokit/rest'
const REPO_OWNER = 'webdriverio'
const REPO_NAME = 'i18n'
const GITHUB_TOKEN = process.env.GITHUB_AUTH
if (!GITHUB_TOKEN) {
throw new Error('GITHUB_AUTH is not set')
}
const IGNORE_FILES = ['src', 'package.json', 'package-lock.json', 'README.md', 'LICENSE', 'tsconfig.json']
const __dirname = path.dirname(url.fileURLToPath(import.meta.url))
const octokit = new Octokit({ auth: GITHUB_TOKEN })
export function downloadDocsTranslations() {
return downloadAndExtractRepo(REPO_OWNER, REPO_NAME)
}
async function downloadAndExtractRepo(owner: string, repo: string, branch?: string) {
if (!branch) {
const { data } = await octokit.repos.get({ owner, repo })
branch = data.default_branch
}
const url = `https://api.github.com/repos/${owner}/${repo}/zipball/${branch}`
console.log(`Downloading ${url}...`)
const response = await fetch(url, {
headers: {
Authorization: `token ${GITHUB_TOKEN}`,
Accept: 'application/vnd.github.v3+json',
},
})
if (!response.ok) {
throw new Error(`Failed to download repo zip: ${response.status} ${response.statusText}`)
}
const tempExtractPath = path.resolve(__dirname, '..', '..', 'temp_extract')
const finalExtractPath = path.resolve(__dirname, '..', '..', 'website', 'i18n')
await fs.mkdir(tempExtractPath, { recursive: true })
await fs.mkdir(finalExtractPath, { recursive: true })
try {
await new Promise((resolve, reject) => {
if (!response.body) {
return reject(new Error('Response body is null'))
}
const nodeStream = Readable.fromWeb(response.body)
nodeStream
.pipe(unzipper.Extract({ path: tempExtractPath }))
.on('close', resolve)
.on('error', reject)
})
const extractedDirs = await fs.readdir(tempExtractPath)
const repoDir = extractedDirs[0]
const repoDirPath = path.join(tempExtractPath, repoDir)
const files = await fs.readdir(repoDirPath)
for (const file of files) {
const baseName = path.basename(file)
if (baseName.startsWith('.') || IGNORE_FILES.includes(baseName)) {
continue
}
const srcPath = path.join(repoDirPath, file)
const destPath = path.join(finalExtractPath, file)
try {
await fs.rm(destPath, { recursive: true, force: true })
} catch {
}
await fs.cp(srcPath, destPath, { recursive: true })
}
console.log(`Repository extracted to ${finalExtractPath}`)
} finally {
try {
await fs.rm(tempExtractPath, { recursive: true, force: true })
} catch (err) {
console.warn('Failed to clean up temporary directory:', err)
}
}
}