+4
-4
@@ -1,4 +1,4 @@
|
|||||||
FROM golang:1.26-alpine AS go-builder
|
FROM --platform=$BUILDPLATFORM golang:1.26-alpine AS go-builder
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
RUN apk add --no-cache bash curl unzip upx
|
RUN apk add --no-cache bash curl unzip upx
|
||||||
|
|
||||||
@@ -16,12 +16,12 @@ RUN GOOS=windows GOARCH=amd64 go build -trimpath -ldflags='-s -w -buildid=' -o /
|
|||||||
RUN cp /out/tsrun-linux /out/tsrun-linux-upx && upx --best --lzma /out/tsrun-linux-upx
|
RUN cp /out/tsrun-linux /out/tsrun-linux-upx && upx --best --lzma /out/tsrun-linux-upx
|
||||||
RUN cp /out/tsrun.exe /out/tsrun-upx.exe && upx --best --lzma /out/tsrun-upx.exe
|
RUN cp /out/tsrun.exe /out/tsrun-upx.exe && upx --best --lzma /out/tsrun-upx.exe
|
||||||
|
|
||||||
FROM oven/bun:1.3.14-alpine AS bun-builder
|
FROM --platform=$BUILDPLATFORM oven/bun:1.3.14-alpine AS bun-builder
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY server ./server
|
COPY server ./server
|
||||||
RUN bun build --target bun --outfile /out/server.js ./server/index.ts
|
RUN bun build --target bun --minify --outfile /out/server.js ./server/index.ts
|
||||||
|
|
||||||
FROM oven/bun:1.3.14-alpine
|
FROM --platform=linux/arm64 oven/bun:1.3.14-alpine
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=bun-builder /out/server.js ./server.js
|
COPY --from=bun-builder /out/server.js ./server.js
|
||||||
COPY --from=go-builder /out/tsrun-linux ./dist/tsrun-linux
|
COPY --from=go-builder /out/tsrun-linux ./dist/tsrun-linux
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"lockfileVersion": 1,
|
||||||
|
"configVersion": 1,
|
||||||
|
"workspaces": {
|
||||||
|
"": {
|
||||||
|
"name": "tsrun",
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/bun": "latest",
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": "^5",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"packages": {
|
||||||
|
"@types/bun": ["@types/[email protected]", "", { "dependencies": { "bun-types": "1.3.14" } }, "sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw=="],
|
||||||
|
|
||||||
|
"@types/node": ["@types/[email protected]", "", { "dependencies": { "undici-types": "~8.3.0" } }, "sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw=="],
|
||||||
|
|
||||||
|
"bun-types": ["[email protected]", "", { "dependencies": { "@types/node": "*" } }, "sha512-4N0ig0fEomHt5R0KCFWjovxow98rIoRwKolrYdCcknNwMekCXRnWEUvgu5soYV8QXtVsrUD8B95MBOZGPvr6KQ=="],
|
||||||
|
|
||||||
|
"typescript": ["[email protected]", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
||||||
|
|
||||||
|
"undici-types": ["[email protected]", "", {}, "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ=="],
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"name": "tsrun",
|
||||||
|
"module": "index.ts",
|
||||||
|
"type": "module",
|
||||||
|
"private": true,
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/bun": "latest"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": "^5"
|
||||||
|
}
|
||||||
|
}
|
||||||
+78
-10
@@ -67,6 +67,7 @@ run_as_root "$outfile"
|
|||||||
|
|
||||||
function powershellBootstrap(url: URL) {
|
function powershellBootstrap(url: URL) {
|
||||||
const binURL = new URL(routes.windows, url).toString();
|
const binURL = new URL(routes.windows, url).toString();
|
||||||
|
const rawBinURL = new URL(routes.windowsRaw, url).toString();
|
||||||
return `$ErrorActionPreference = 'Stop'
|
return `$ErrorActionPreference = 'Stop'
|
||||||
|
|
||||||
function Test-Administrator {
|
function Test-Administrator {
|
||||||
@@ -75,33 +76,100 @@ function Test-Administrator {
|
|||||||
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Download-Tsrun {
|
||||||
|
param(
|
||||||
|
[string] $PrimaryUrl,
|
||||||
|
[string] $FallbackUrl,
|
||||||
|
[string] $ExePath
|
||||||
|
)
|
||||||
|
|
||||||
|
$attempts = @(
|
||||||
|
@{ Url = $PrimaryUrl; Label = 'upx' },
|
||||||
|
@{ Url = $FallbackUrl; Label = 'raw' }
|
||||||
|
)
|
||||||
|
|
||||||
|
foreach ($attempt in $attempts) {
|
||||||
|
Write-Host "downloading tsrun ($($attempt.Label))..."
|
||||||
|
Remove-Item -Force -ErrorAction SilentlyContinue $ExePath
|
||||||
|
Invoke-WebRequest -UseBasicParsing -Uri $attempt.Url -OutFile $ExePath
|
||||||
|
|
||||||
|
if (-not (Test-Path $ExePath)) {
|
||||||
|
Write-Warning "downloaded file was removed immediately; trying next artifact"
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
$item = Get-Item $ExePath -ErrorAction SilentlyContinue
|
||||||
|
if ($null -eq $item -or $item.Length -le 0) {
|
||||||
|
Write-Warning "downloaded file is missing or empty; trying next artifact"
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
return $attempt.Label
|
||||||
|
}
|
||||||
|
|
||||||
|
throw 'unable to download a usable tsrun executable; Windows Security may have removed it'
|
||||||
|
}
|
||||||
|
|
||||||
|
function Start-TsrunProcess {
|
||||||
|
param(
|
||||||
|
[string] $ExePath,
|
||||||
|
[string[]] $TsrunArgs,
|
||||||
|
[switch] $Elevated
|
||||||
|
)
|
||||||
|
|
||||||
|
if (-not (Test-Path $ExePath)) {
|
||||||
|
throw 'tsrun executable is missing before launch'
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($Elevated) {
|
||||||
|
Start-Process -FilePath $ExePath -Verb RunAs -ArgumentList $TsrunArgs | Out-Null
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
& $ExePath @TsrunArgs
|
||||||
|
}
|
||||||
|
|
||||||
function Start-Tsrun {
|
function Start-Tsrun {
|
||||||
param(
|
param(
|
||||||
[string[]] $TsrunArgs = @()
|
[string[]] $TsrunArgs = @()
|
||||||
)
|
)
|
||||||
|
|
||||||
$url = ${psQuote(binURL)}
|
$url = ${psQuote(binURL)}
|
||||||
|
$rawUrl = ${psQuote(rawBinURL)}
|
||||||
$tempDir = Join-Path $env:TEMP 'tsrun-bootstrap'
|
$tempDir = Join-Path $env:TEMP 'tsrun-bootstrap'
|
||||||
$exePath = Join-Path $tempDir 'tsrun.exe'
|
$exePath = Join-Path $tempDir 'tsrun.exe'
|
||||||
New-Item -ItemType Directory -Force -Path $tempDir | Out-Null
|
New-Item -ItemType Directory -Force -Path $tempDir | Out-Null
|
||||||
|
|
||||||
Write-Host 'downloading tsrun...'
|
$downloadedVariant = Download-Tsrun -PrimaryUrl $url -FallbackUrl $rawUrl -ExePath $exePath
|
||||||
Invoke-WebRequest -UseBasicParsing -Uri $url -OutFile $exePath
|
|
||||||
|
|
||||||
if (-not (Test-Administrator)) {
|
if (-not (Test-Administrator)) {
|
||||||
Write-Host 'elevating privileges...'
|
Write-Host 'elevating privileges...'
|
||||||
$argList = @(
|
try {
|
||||||
'-NoProfile',
|
Start-TsrunProcess -ExePath $exePath -TsrunArgs $TsrunArgs -Elevated
|
||||||
'-ExecutionPolicy', 'Bypass',
|
} catch {
|
||||||
'-Command',
|
if ($downloadedVariant -ne 'raw') {
|
||||||
"& { & '${exePath}' $($TsrunArgs -join ' ') }"
|
Write-Warning 'launch failed after UPX download; retrying with raw executable'
|
||||||
)
|
$null = Download-Tsrun -PrimaryUrl $rawUrl -FallbackUrl $rawUrl -ExePath $exePath
|
||||||
Start-Process -FilePath 'powershell' -Verb RunAs -ArgumentList $argList | Out-Null
|
Start-TsrunProcess -ExePath $exePath -TsrunArgs $TsrunArgs -Elevated
|
||||||
|
return
|
||||||
|
}
|
||||||
|
throw
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Host 'starting tsrun...'
|
Write-Host 'starting tsrun...'
|
||||||
& $exePath @TsrunArgs
|
try {
|
||||||
|
Start-TsrunProcess -ExePath $exePath -TsrunArgs $TsrunArgs
|
||||||
|
} catch {
|
||||||
|
if ($downloadedVariant -ne 'raw') {
|
||||||
|
Write-Warning 'launch failed after UPX download; retrying with raw executable'
|
||||||
|
$null = Download-Tsrun -PrimaryUrl $rawUrl -FallbackUrl $rawUrl -ExePath $exePath
|
||||||
|
Start-TsrunProcess -ExePath $exePath -TsrunArgs $TsrunArgs
|
||||||
|
return
|
||||||
|
}
|
||||||
|
throw
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Start-Tsrun
|
Start-Tsrun
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
// Environment setup & latest features
|
||||||
|
"lib": ["ESNext"],
|
||||||
|
"target": "ESNext",
|
||||||
|
"module": "Preserve",
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"allowJs": true,
|
||||||
|
"types": ["bun"],
|
||||||
|
|
||||||
|
// Bundler mode
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"verbatimModuleSyntax": true,
|
||||||
|
"noEmit": true,
|
||||||
|
|
||||||
|
// Best practices
|
||||||
|
"strict": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"noUncheckedIndexedAccess": true,
|
||||||
|
"noImplicitOverride": true,
|
||||||
|
|
||||||
|
// Some stricter flags (disabled by default)
|
||||||
|
"noUnusedLocals": false,
|
||||||
|
"noUnusedParameters": false,
|
||||||
|
"noPropertyAccessFromIndexSignature": false
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user