144 lines
3.9 KiB
JavaScript
144 lines
3.9 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
/**
|
|
* @tailwindcss/oxide postinstall script
|
|
*
|
|
* This script ensures that the correct binary for the current platform and
|
|
* architecture is downloaded and available.
|
|
*/
|
|
|
|
const fs = require('fs')
|
|
const path = require('path')
|
|
const https = require('https')
|
|
const { extract } = require('tar')
|
|
const packageJson = require('../package.json')
|
|
const detectLibc = require('detect-libc')
|
|
|
|
const version = packageJson.version
|
|
|
|
function getPlatformPackageName() {
|
|
let platform = process.platform
|
|
let arch = process.arch
|
|
|
|
let libc = ''
|
|
if (platform === 'linux') {
|
|
libc = detectLibc.isNonGlibcLinuxSync() ? 'musl' : 'gnu'
|
|
}
|
|
|
|
// Map to our package naming conventions
|
|
switch (platform) {
|
|
case 'darwin':
|
|
return arch === 'arm64' ? '@tailwindcss/oxide-darwin-arm64' : '@tailwindcss/oxide-darwin-x64'
|
|
case 'win32':
|
|
if (arch === 'arm64') return '@tailwindcss/oxide-win32-arm64-msvc'
|
|
if (arch === 'ia32') return '@tailwindcss/oxide-win32-ia32-msvc'
|
|
return '@tailwindcss/oxide-win32-x64-msvc'
|
|
case 'linux':
|
|
if (arch === 'x64') {
|
|
return libc === 'musl'
|
|
? '@tailwindcss/oxide-linux-x64-musl'
|
|
: '@tailwindcss/oxide-linux-x64-gnu'
|
|
} else if (arch === 'arm64') {
|
|
return libc === 'musl'
|
|
? '@tailwindcss/oxide-linux-arm64-musl'
|
|
: '@tailwindcss/oxide-linux-arm64-gnu'
|
|
} else if (arch === 'arm') {
|
|
return '@tailwindcss/oxide-linux-arm-gnueabihf'
|
|
}
|
|
break
|
|
case 'freebsd':
|
|
return '@tailwindcss/oxide-freebsd-x64'
|
|
case 'android':
|
|
return '@tailwindcss/oxide-android-arm64'
|
|
default:
|
|
return '@tailwindcss/oxide-wasm32-wasi'
|
|
}
|
|
}
|
|
|
|
function isPackageAvailable(packageName) {
|
|
try {
|
|
require.resolve(packageName)
|
|
return true
|
|
} catch (e) {
|
|
return false
|
|
}
|
|
}
|
|
|
|
// Extract all files from a tarball to a destination directory
|
|
async function extractTarball(tarballStream, destDir) {
|
|
if (!fs.existsSync(destDir)) {
|
|
fs.mkdirSync(destDir, { recursive: true })
|
|
}
|
|
|
|
return new Promise((resolve, reject) => {
|
|
tarballStream
|
|
.pipe(extract({ cwd: destDir, strip: 1 }))
|
|
.on('error', (err) => reject(err))
|
|
.on('end', () => resolve())
|
|
})
|
|
}
|
|
|
|
async function downloadAndExtractBinary(packageName) {
|
|
let tarballUrl = `https://registry.npmjs.org/${packageName}/-/${packageName.replace('@tailwindcss/', '')}-${version}.tgz`
|
|
console.log(`Downloading ${tarballUrl}...`)
|
|
|
|
return new Promise((resolve) => {
|
|
https
|
|
.get(tarballUrl, (response) => {
|
|
if (response.statusCode === 302 || response.statusCode === 301) {
|
|
// Handle redirects
|
|
https.get(response.headers.location, handleResponse).on('error', (err) => {
|
|
console.error('Download error:', err)
|
|
resolve()
|
|
})
|
|
return
|
|
}
|
|
|
|
handleResponse(response)
|
|
|
|
async function handleResponse(response) {
|
|
try {
|
|
if (response.statusCode !== 200) {
|
|
throw new Error(`Download failed with status code: ${response.statusCode}`)
|
|
}
|
|
|
|
await extractTarball(
|
|
response,
|
|
path.join(__dirname, '..', 'node_modules', ...packageName.split('/')),
|
|
)
|
|
console.log(`Successfully downloaded and installed ${packageName}`)
|
|
} catch (error) {
|
|
console.error('Error during extraction:', error)
|
|
resolve()
|
|
} finally {
|
|
resolve()
|
|
}
|
|
}
|
|
})
|
|
.on('error', (err) => {
|
|
console.error('Download error:', err)
|
|
resolve()
|
|
})
|
|
})
|
|
}
|
|
|
|
async function main() {
|
|
// Don't run this script in the package source
|
|
try {
|
|
if (fs.existsSync(path.join(__dirname, '..', 'build.rs'))) {
|
|
return
|
|
}
|
|
|
|
let packageName = getPlatformPackageName()
|
|
if (!packageName) return
|
|
if (isPackageAvailable(packageName)) return
|
|
|
|
await downloadAndExtractBinary(packageName)
|
|
} catch (error) {
|
|
console.error(error)
|
|
return
|
|
}
|
|
}
|
|
|
|
main()
|