Skip to content

Commit

Permalink
refactor: unzip repo in memory
Browse files Browse the repository at this point in the history
  • Loading branch information
boywithkeyboard committed Apr 4, 2024
1 parent df80970 commit 75fd0ad
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 136 deletions.
104 changes: 7 additions & 97 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@
"@aws-sdk/client-s3": "^3.540.0",
"@sinclair/typebox": "^0.32.20",
"fastify": "^4.26.2",
"fflate": "^0.8.2",
"fs-extra": "^11.2.0",
"lru-cache": "^10.2.0",
"octokit": "^3.2.0",
"rimraf": "^5.0.5",
"semver": "^7.6.0",
"slash": "^5.1.0",
"tar": "^6.2.1"
"slash": "^5.1.0"
},
"devDependencies": {
"@astrojs/check": "^0.5.10",
Expand Down
17 changes: 17 additions & 0 deletions registry/deadline.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export function delay(ms: number) {
return new Promise<void>(resolve => {
setTimeout(() => {
resolve()
}, ms)
})
}

export function deadline<T>(p: Promise<T>, ms: number): Promise<T> {
const controller = new AbortController()

const d = delay(ms)
.catch(() => {})
.then(() => Promise.reject(new Error()))

return Promise.race([p.finally(() => controller.abort()), d])
}
49 changes: 12 additions & 37 deletions registry/file_map.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import { ensureDir } from 'fs-extra'
import { mkdtemp, readFile, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { rimraf } from 'rimraf'
import slash from 'slash'
import * as tar from 'tar'
import { readFile, writeFile } from 'node:fs/promises'
import { deadline } from './deadline'
import { compress, decompress } from './gzip'
import { s3 } from './s3'
import { unzip } from './unzip'
import { validExt } from './valid_ext'

const sha1Pattern = /^[0-9a-f]{40}$/
Expand All @@ -17,7 +14,7 @@ export async function createFileMap(user: string, repo: string, tag: string): Pr
const res = await fetch(
'https://github.com/' + user + '/' + repo + (
sha1Pattern.test(tag) ? '/archive/' : '/archive/refs/tags/'
) + tag + '.tar.gz'
) + tag + '.zip'
)

if (!res.ok) {
Expand All @@ -26,45 +23,23 @@ export async function createFileMap(user: string, repo: string, tag: string): Pr
return null
}

const buf = await res.arrayBuffer()
const buf = await deadline(res.arrayBuffer(), 2500)

if (buf.byteLength > 10_000_000) { // 10 MB
return null
}

let tmpDirPath = await mkdtemp(join(tmpdir(), crypto.randomUUID()))

tmpDirPath = slash(tmpDirPath)

await writeFile(tmpDirPath + '/archive.tar.gz', Buffer.from(buf))

const map: FileMap = {}

await tar.x({
C: tmpDirPath,
file: tmpDirPath + '/archive.tar.gz',
filter(path, stat) {
// @ts-expect-error
if (stat.type !== 'File') {
return true
}

return validExt(path)
},
onentry(entry) {
if (entry.type === 'File') {
const path = entry.path.substring(entry.path.indexOf('/'))

const content = entry.read()

if (content && content.byteLength > 0) {
map[path] = content.toString('base64')
}
}
const files = await deadline(unzip(buf), 2500)

for (const key in files) {
if (!validExt(key) || files[key].byteLength < 1) {
continue
}
})

await rimraf(tmpDirPath)
map[key.substring(key.indexOf('/'))] = Buffer.from(files[key]).toString('base64')
}

return map
}
Expand Down
15 changes: 15 additions & 0 deletions registry/unzip.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { unzip as _unzip, type Unzipped } from 'fflate'

export function unzip(buf: ArrayBuffer) {
const promise = new Promise<Unzipped>((resolve, reject) => {
_unzip(new Uint8Array(buf), (err, data) => {
if (err) {
reject(err)
} else {
resolve(data)
}
})
})

return promise
}

0 comments on commit 75fd0ad

Please sign in to comment.