mirror of
https://github.com/System-End/cdn.git
synced 2026-04-19 20:55:10 +00:00
Closes #1, add separate endpoint for uploading files
This commit is contained in:
parent
17eb29bb11
commit
9cacef61da
2 changed files with 67 additions and 40 deletions
60
api/new.ts
60
api/new.ts
|
|
@ -1,6 +1,4 @@
|
||||||
import { ServerRequest } from 'https://deno.land/std@0.61.0/http/server.ts'
|
import { ServerRequest } from 'https://deno.land/std@0.75.0/http/server.ts'
|
||||||
import { Hash } from "https://deno.land/x/checksum@1.4.0/mod.ts"
|
|
||||||
import { urlParse } from 'https://deno.land/x/url_parse/mod.ts';
|
|
||||||
|
|
||||||
const endpoint = (path: string) => {
|
const endpoint = (path: string) => {
|
||||||
// https://vercel.com/docs/api#api-basics/authentication/accessing-resources-owned-by-a-team
|
// https://vercel.com/docs/api#api-basics/authentication/accessing-resources-owned-by-a-team
|
||||||
|
|
@ -11,36 +9,7 @@ const endpoint = (path: string) => {
|
||||||
return url
|
return url
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vercel protects against env tokens starting with `VERCEL_`, so we're calling
|
const deploy = async (files: { sha: string, file: string, path: string, size: number }[]) => {
|
||||||
// it the ZEIT_TOKEN
|
|
||||||
|
|
||||||
const uploadFile = async (url: string, index: number) => {
|
|
||||||
const req = await fetch(url)
|
|
||||||
const data = new Uint8Array(await req.arrayBuffer())
|
|
||||||
const sha = new Hash('sha1').digest(data).hex()
|
|
||||||
const size = data.byteLength
|
|
||||||
const { pathname } = urlParse(url)
|
|
||||||
const filename = index + pathname.substr(pathname.lastIndexOf('/') + 1)
|
|
||||||
|
|
||||||
const uploadedFile = await fetch(endpoint('v2/now/files'), {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Length': size.toString(),
|
|
||||||
'x-now-digest': sha,
|
|
||||||
'Authorization': `Bearer ${Deno.env.get('ZEIT_TOKEN')}`
|
|
||||||
},
|
|
||||||
body: data.buffer,
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
|
||||||
sha,
|
|
||||||
size,
|
|
||||||
file: 'public/' + filename,
|
|
||||||
path: filename
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const deploy = async (files: {sha: string, file: string, path: string, size: number}[]) => {
|
|
||||||
const req = await fetch(endpoint('v12/now/deployments'), {
|
const req = await fetch(endpoint('v12/now/deployments'), {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
|
|
@ -68,26 +37,37 @@ const deploy = async (files: {sha: string, file: string, path: string, size: num
|
||||||
|
|
||||||
export default async (req: ServerRequest) => {
|
export default async (req: ServerRequest) => {
|
||||||
if (req.method == 'OPTIONS') {
|
if (req.method == 'OPTIONS') {
|
||||||
return req.respond({status: 204, body: JSON.stringify({ status: "YIPPE YAY. YOU HAVE CLEARANCE TO PROCEED." })})
|
return req.respond({ status: 204, body: JSON.stringify({ status: "YIPPE YAY. YOU HAVE CLEARANCE TO PROCEED." }) })
|
||||||
}
|
}
|
||||||
if (req.method == 'GET') {
|
if (req.method == 'GET') {
|
||||||
return req.respond({status: 405, body: JSON.stringify({ error: '*GET outta here!* (Method not allowed, use POST)' })})
|
return req.respond({ status: 405, body: JSON.stringify({ error: '*GET outta here!* (Method not allowed, use POST)' }) })
|
||||||
}
|
}
|
||||||
if (req.method == 'PUT') {
|
if (req.method == 'PUT') {
|
||||||
return req.respond({status: 405, body: JSON.stringify({ error: '*PUT that request away!* (Method not allowed, use POST)' })})
|
return req.respond({ status: 405, body: JSON.stringify({ error: '*PUT that request away!* (Method not allowed, use POST)' }) })
|
||||||
}
|
}
|
||||||
if (req.method != 'POST') {
|
if (req.method != 'POST') {
|
||||||
return req.respond({status: 405, body: JSON.stringify({ error: 'Method not allowed, use POST' })})
|
return req.respond({ status: 405, body: JSON.stringify({ error: 'Method not allowed, use POST' }) })
|
||||||
}
|
}
|
||||||
|
|
||||||
const decoder = new TextDecoder()
|
const decoder = new TextDecoder()
|
||||||
const buf = await Deno.readAll(req.body)
|
const buf = await Deno.readAll(req.body)
|
||||||
const fileURLs = JSON.parse(decoder.decode(buf))
|
const fileURLs = JSON.parse(decoder.decode(buf))
|
||||||
if (!Array.isArray(fileURLs) || fileURLs.length < 1) {
|
if (!Array.isArray(fileURLs) || fileURLs.length < 1) {
|
||||||
return req.respond({status: 422, body: JSON.stringify({ error: 'Empty file array' })})
|
return req.respond({ status: 422, body: JSON.stringify({ error: 'Empty file array' }) })
|
||||||
}
|
}
|
||||||
const uploadedFiles = await Promise.all(fileURLs.map(uploadFile))
|
|
||||||
const result = await deploy(uploadedFiles)
|
let uploadedURLs = await Promise.all(fileURLs.map(async (url) => {
|
||||||
|
const res = await fetch("https://cdn.hackclub.com/api/newSingle", {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: url
|
||||||
|
})
|
||||||
|
return JSON.parse(await res.json())
|
||||||
|
}))
|
||||||
|
|
||||||
|
const result = await deploy(uploadedURLs)
|
||||||
|
|
||||||
req.respond({
|
req.respond({
|
||||||
status: result.status,
|
status: result.status,
|
||||||
|
|
|
||||||
47
api/newSingle.ts
Normal file
47
api/newSingle.ts
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
import { ServerRequest } from 'https://deno.land/std@0.75.0/http/server.ts'
|
||||||
|
import { Hash } from "https://deno.land/x/checksum@1.4.0/mod.ts"
|
||||||
|
import { urlParse } from 'https://deno.land/x/url_parse/mod.ts';
|
||||||
|
|
||||||
|
const uploadFile = async (url: string) => {
|
||||||
|
const req = await fetch(url)
|
||||||
|
const data = new Uint8Array(await req.arrayBuffer())
|
||||||
|
const sha = new Hash('sha1').digest(data).hex()
|
||||||
|
const size = data.byteLength
|
||||||
|
const { pathname } = urlParse(url)
|
||||||
|
const filename = pathname.substr(pathname.lastIndexOf('/') + 1)
|
||||||
|
|
||||||
|
await fetch(endpoint('v2/now/files'), {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Length': size.toString(),
|
||||||
|
'x-now-digest': sha,
|
||||||
|
'Authorization': `Bearer ${Deno.env.get('ZEIT_TOKEN')}`
|
||||||
|
},
|
||||||
|
body: data.buffer,
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
sha,
|
||||||
|
size,
|
||||||
|
file: 'public/' + filename,
|
||||||
|
path: filename
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async (req: ServerRequest) => {
|
||||||
|
if (req.method != 'POST') {
|
||||||
|
return req.respond({ status: 405, body: JSON.stringify({ error: 'Method not allowed, use POST' }) })
|
||||||
|
}
|
||||||
|
|
||||||
|
const decoder = new TextDecoder()
|
||||||
|
const buf = await Deno.readAll(req.body)
|
||||||
|
const singleFileURL = JSON.parse(decoder.decode(buf))
|
||||||
|
if (typeof singleFileURL != 'string') {
|
||||||
|
return req.respond({ status: 422, body: JSON.stringify({ error: 'newSingle only accepts a single URL' }) })
|
||||||
|
}
|
||||||
|
const uploadedFileURL = await uploadFile(singleFileURL)
|
||||||
|
|
||||||
|
req.respond({
|
||||||
|
body: JSON.stringify(uploadedFileURL)
|
||||||
|
})
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue