diff --git a/frontend.js b/frontend.js index cb4d347..e11dc0e 100644 --- a/frontend.js +++ b/frontend.js @@ -1,4 +1,16 @@ export class Frontend { + contentTypes = { + html: 'text/html; charset=utf-8', + js: 'text/javascript', + css: 'text/css', + md: 'text/plain', + txt: 'text/plain', + png: 'image/png', + jpg: 'image/jpg', + webm: 'image/webm', + svg: 'image/svg', + } + constructor({apiBaseUrl, appBaseUrl}) { this.apiBaseUrl = apiBaseUrl this.appBaseUrl = appBaseUrl @@ -9,34 +21,51 @@ export class Frontend { repoUrl(user, repo) { return ( this.apiBaseUrl + + '/repos' + '/' + encodeURIComponent(user) + '/' + encodeURIComponent(repo) ) } + pathString(path) { + return path.map(s => ( + '/' + encodeURIComponent(s) + )).join('') + } + rawUrl(user, repo, commit, path) { return ( this.appBaseUrl + + '/' + encodeURIComponent(user) + + '/' + encodeURIComponent(repo) + '/raw/commit' + '/' + encodeURIComponent(commit) + - '/' + encodeURI(path) + this.pathString(path) ) } + checkOk(resp) { + if (!resp.ok) { + throw new Error('not ok - ' + JSON.stringify( + {status: resp.status, url: resp.url} + )) + } + } + async loadFile(user, repo, commit, src, dest) { - const url = this.rawUrl(user, repo) + const url = this.rawUrl(user, repo, commit, dest) const resp = await fetch(url) + this.checkOk(resp) const body = await resp.arrayBuffer() - this.files[dest] = { + const ext = dest.at('-1')?.match?.(/\.(\w+)$/)?.[1] + const contentType = this.contentTypes[ext] + console.log({ext, contentType}) + this.files[this.pathString(dest)] = { user, repo, commit, body, - contentType: ( - dest.endsWith('.js') ? - 'text/javascript' : - resp.headers.get('content-type') - ) + contentType: contentType ?? 'application/octet-stream', } } @@ -44,9 +73,7 @@ export class Frontend { const url = new URL( this.repoUrl(user, repo) + '/contents' + - path.map(s => ( - '/' + encodeURIComponent(s) - )).join('') + this.pathString(path) ) if (ref !== undefined) { const search = new URLSearchParams() @@ -64,6 +91,7 @@ export class Frontend { user, repo, srcPath, ref ) const resp = await fetch(url) + this.checkOk(resp) const contents = await resp.json() for (const item of contents) { if (item.type === 'dir') { @@ -76,7 +104,7 @@ export class Frontend { this.tasks.push(this.loadFile( user, repo, - last_commit_sha, + item.last_commit_sha, [...srcPath, item.name], [...destPath, item.name], )) @@ -85,7 +113,7 @@ export class Frontend { let prevCount = 0 while (this.tasks.count > prevCount) { prevCount = this.tasks.count - await Promise.allSettled(this.tasks) + await Promise.all(this.tasks) } } @@ -94,7 +122,7 @@ export class Frontend { if (pathname in this.files) { const file = this.files[pathname] event.respondWith(new Response(file.body, { - status: 404, + status: 200, headers: { 'Content-Type': file.contentType, }, diff --git a/server.js b/server.js index 5fba0c7..1bd9962 100644 --- a/server.js +++ b/server.js @@ -70,4 +70,10 @@ export class Server { this.serveConn(conn) } } + + async run() { + await this.configure() + await this.init() + await this.serve() + } } \ No newline at end of file