|
|
@ -1,4 +1,16 @@ |
|
|
export class Frontend { |
|
|
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}) { |
|
|
constructor({apiBaseUrl, appBaseUrl}) { |
|
|
this.apiBaseUrl = apiBaseUrl |
|
|
this.apiBaseUrl = apiBaseUrl |
|
|
this.appBaseUrl = appBaseUrl |
|
|
this.appBaseUrl = appBaseUrl |
|
|
@ -9,34 +21,51 @@ export class Frontend { |
|
|
repoUrl(user, repo) { |
|
|
repoUrl(user, repo) { |
|
|
return ( |
|
|
return ( |
|
|
this.apiBaseUrl + |
|
|
this.apiBaseUrl + |
|
|
|
|
|
'/repos' + |
|
|
'/' + encodeURIComponent(user) + |
|
|
'/' + encodeURIComponent(user) + |
|
|
'/' + encodeURIComponent(repo) |
|
|
'/' + encodeURIComponent(repo) |
|
|
) |
|
|
) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pathString(path) { |
|
|
|
|
|
return path.map(s => ( |
|
|
|
|
|
'/' + encodeURIComponent(s) |
|
|
|
|
|
)).join('') |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
rawUrl(user, repo, commit, path) { |
|
|
rawUrl(user, repo, commit, path) { |
|
|
return ( |
|
|
return ( |
|
|
this.appBaseUrl + |
|
|
this.appBaseUrl + |
|
|
|
|
|
'/' + encodeURIComponent(user) + |
|
|
|
|
|
'/' + encodeURIComponent(repo) + |
|
|
'/raw/commit' + |
|
|
'/raw/commit' + |
|
|
'/' + encodeURIComponent(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) { |
|
|
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) |
|
|
const resp = await fetch(url) |
|
|
|
|
|
this.checkOk(resp) |
|
|
const body = await resp.arrayBuffer() |
|
|
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, |
|
|
user, |
|
|
repo, |
|
|
repo, |
|
|
commit, |
|
|
commit, |
|
|
body, |
|
|
body, |
|
|
contentType: ( |
|
|
contentType: contentType ?? 'application/octet-stream', |
|
|
dest.endsWith('.js') ? |
|
|
|
|
|
'text/javascript' : |
|
|
|
|
|
resp.headers.get('content-type') |
|
|
|
|
|
) |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -44,9 +73,7 @@ export class Frontend { |
|
|
const url = new URL( |
|
|
const url = new URL( |
|
|
this.repoUrl(user, repo) + |
|
|
this.repoUrl(user, repo) + |
|
|
'/contents' + |
|
|
'/contents' + |
|
|
path.map(s => ( |
|
|
this.pathString(path) |
|
|
'/' + encodeURIComponent(s) |
|
|
|
|
|
)).join('') |
|
|
|
|
|
) |
|
|
) |
|
|
if (ref !== undefined) { |
|
|
if (ref !== undefined) { |
|
|
const search = new URLSearchParams() |
|
|
const search = new URLSearchParams() |
|
|
@ -64,6 +91,7 @@ export class Frontend { |
|
|
user, repo, srcPath, ref |
|
|
user, repo, srcPath, ref |
|
|
) |
|
|
) |
|
|
const resp = await fetch(url) |
|
|
const resp = await fetch(url) |
|
|
|
|
|
this.checkOk(resp) |
|
|
const contents = await resp.json() |
|
|
const contents = await resp.json() |
|
|
for (const item of contents) { |
|
|
for (const item of contents) { |
|
|
if (item.type === 'dir') { |
|
|
if (item.type === 'dir') { |
|
|
@ -76,7 +104,7 @@ export class Frontend { |
|
|
this.tasks.push(this.loadFile( |
|
|
this.tasks.push(this.loadFile( |
|
|
user, |
|
|
user, |
|
|
repo, |
|
|
repo, |
|
|
last_commit_sha, |
|
|
item.last_commit_sha, |
|
|
[...srcPath, item.name], |
|
|
[...srcPath, item.name], |
|
|
[...destPath, item.name], |
|
|
[...destPath, item.name], |
|
|
)) |
|
|
)) |
|
|
@ -85,7 +113,7 @@ export class Frontend { |
|
|
let prevCount = 0 |
|
|
let prevCount = 0 |
|
|
while (this.tasks.count > prevCount) { |
|
|
while (this.tasks.count > prevCount) { |
|
|
prevCount = this.tasks.count |
|
|
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) { |
|
|
if (pathname in this.files) { |
|
|
const file = this.files[pathname] |
|
|
const file = this.files[pathname] |
|
|
event.respondWith(new Response(file.body, { |
|
|
event.respondWith(new Response(file.body, { |
|
|
status: 404, |
|
|
status: 200, |
|
|
headers: { |
|
|
headers: { |
|
|
'Content-Type': file.contentType, |
|
|
'Content-Type': file.contentType, |
|
|
}, |
|
|
}, |
|
|
|