Skip to content

Commit fda877b

Browse files
committed
feat: 新增 deno 的一种构建服务器
1 parent 1113867 commit fda877b

File tree

1 file changed

+337
-0
lines changed

1 file changed

+337
-0
lines changed

packages/edge-provider/index.mjs

+337
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,337 @@
1+
import { Application, Router } from 'https://deno.land/x/oak/mod.ts';
2+
import { Md5 } from 'https://deno.land/[email protected]/hash/md5.ts';
3+
import {
4+
fontSplit,
5+
Assets,
6+
DenoAdapter,
7+
} from 'https://cdn.jsdelivr.net/npm/@konghayao/cn-font-split/dist/browser/index.js';
8+
await DenoAdapter();
9+
Assets.pathTransform = (innerPath) =>
10+
innerPath.replace(
11+
'./',
12+
'https://cdn.jsdelivr.net/npm/@konghayao/cn-font-split/dist/browser/',
13+
);
14+
const UA =
15+
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36';
16+
const kv = await Deno.openKv();
17+
const app = new Application();
18+
const router = new Router();
19+
// 上传文件并存储
20+
router.post('/upload', async (ctx) => {
21+
const buffer = await ctx.request.body.arrayBuffer();
22+
const name = ctx.request.headers.get('filename');
23+
const hash = new Md5('md5').update(buffer).toString();
24+
console.log(hash);
25+
const cacheURL = await kv.get([hash]);
26+
console.log(cacheURL);
27+
if (cacheURL.value) {
28+
ctx.response.body = JSON.stringify({
29+
code: 50,
30+
msg: 'content existed',
31+
data: { name, hash, url: cacheURL.value },
32+
});
33+
} else {
34+
const url = await upload(new Blob([buffer]), name, hash);
35+
await kv.set([hash], url);
36+
ctx.response.body = JSON.stringify({
37+
code: 0,
38+
data: { name, hash, url },
39+
});
40+
}
41+
});
42+
// kv.set(["f7ee05dd168d7623046d621c8193c336" ], "https://we.tl/t-eCzYb8ZH3m")
43+
const downloadFromKV = async (hash) => {
44+
const url = (await kv.get([hash])).value;
45+
if (url) {
46+
return download(url);
47+
} else {
48+
console.log(hash, url);
49+
throw new Error('not found');
50+
}
51+
};
52+
router.get('/split', async (ctx) => {
53+
const hash = await ctx.request.url.searchParams.get('hash');
54+
console.log(hash);
55+
const charset = ctx.request.url.searchParams
56+
.get('splitText')
57+
.split('')
58+
.filter(Boolean)
59+
.map((i) => i.charCodeAt(0));
60+
const blob = await downloadFromKV(hash).then((res) => res.arrayBuffer());
61+
console.log(blob.byteLength);
62+
const pack = await new Promise((res) => {
63+
return fontSplit({
64+
FontPath: new Uint8Array(blob),
65+
destFold: '',
66+
chunkSize: 70 * 1024, // 如果需要的话,自己定制吧
67+
testHTML: false, // 输出一份 html 报告文件
68+
reporter: false, // 输出 json 格式报告
69+
previewImage: false, // 只要填入 这个参数,就会进行图片预览文件生成,文件为 SVG 格式
70+
threads: {}, // 默认开启多线程,速度飞快
71+
css: false,
72+
subsets: [charset],
73+
outputFile(name, blob) {
74+
res({ name, blob });
75+
},
76+
});
77+
});
78+
// 给 response 设置无限长的缓存
79+
ctx.response.set('filename', pack.name);
80+
ctx.response.set('Cache-Control', 'max-age=31536000, immutable');
81+
ctx.response.set('Content-Type', 'application/octet-stream');
82+
});
83+
app.use(router.routes());
84+
console.log('Server listening on http://localhost:8000');
85+
await app.listen({ port: 8000 });
86+
/**
87+
* download file from shortend_url
88+
* @param {*} shortened_url
89+
* @returns blob
90+
*/
91+
async function download(shortened_url) {
92+
const res = await fetch(shortened_url).then((res) => {
93+
const [transfer_id, security_hash] = res.url.split('/').slice(-2);
94+
const j = {
95+
intent: 'entire_transfer',
96+
security_hash: security_hash,
97+
};
98+
return fetch(
99+
`https://wetransfer.com/api/v4/transfers/${transfer_id}/download`,
100+
{
101+
headers: { 'content-type': 'application/json' },
102+
method: 'post',
103+
body: JSON.stringify(j),
104+
},
105+
).then((res) => res.json());
106+
});
107+
console.log(res.direct_link);
108+
return fetch(res.direct_link);
109+
}
110+
/**
111+
* upload to wetransfer
112+
* @param {*} file
113+
* @param {*} hash
114+
* @returns shared URL
115+
*/
116+
async function upload(file, filename, hash) {
117+
const transfer = await fetch(
118+
'https://wetransfer.com/api/v4/transfers/link',
119+
{
120+
headers: {
121+
accept: 'application/json, text/plain, */*',
122+
'accept-language': 'zh-CN,zh;q=0.9',
123+
'content-type': 'application/json',
124+
'sec-ch-ua':
125+
'"Google Chrome";v="123", "Not:A-Brand";v="8", "Chromium";v="123"',
126+
'sec-ch-ua-mobile': '?0',
127+
'sec-ch-ua-platform': '"macOS"',
128+
'sec-fetch-dest': 'empty',
129+
'sec-fetch-mode': 'cors',
130+
'sec-fetch-site': 'same-origin',
131+
'x-amplitude-country': 'CN',
132+
'x-amplitude-device-family': 'Macintosh',
133+
'x-amplitude-device-id': 'YexdY326lbjSrV1RiXozWp',
134+
'x-amplitude-device-type': 'Apple Macintosh',
135+
'x-amplitude-language': 'en',
136+
'x-amplitude-platform': 'Web',
137+
'x-app-origin': 'decoupled',
138+
'User-Agent': UA,
139+
Referer: 'https://wetransfer.com/',
140+
Origin: 'https://wetransfer.com',
141+
'x-requested-with': 'XMLHttpRequest',
142+
},
143+
referrer: 'https://wetransfer.com/',
144+
referrerPolicy: 'origin',
145+
body: JSON.stringify({
146+
message: '',
147+
display_name: filename,
148+
ui_language: 'en',
149+
domain_user_id: '2eb931a1-2f8f-4bf5-a649-1de732acd838',
150+
files: [{ name: filename, size: file.size, item_type: 'file' }],
151+
expire_in: 604800,
152+
}),
153+
method: 'POST',
154+
mode: 'cors',
155+
credentials: 'include',
156+
},
157+
).then((res) => res.json());
158+
let authorization = transfer.storm_upload_token;
159+
console.log('transfer', transfer);
160+
const urls = JSON.parse(atob(authorization.split('.')[1]));
161+
console.log('checked', urls);
162+
authorization = 'Bearer ' + authorization;
163+
await fetch(urls['storm.preflight_batch_url'], {
164+
headers: {
165+
accept: 'application/json',
166+
'accept-language': 'zh-CN,zh;q=0.9',
167+
authorization,
168+
'content-type': 'application/json',
169+
'sec-ch-ua':
170+
'"Google Chrome";v="123", "Not:A-Brand";v="8", "Chromium";v="123"',
171+
'sec-ch-ua-mobile': '?0',
172+
'sec-ch-ua-platform': '"macOS"',
173+
'sec-fetch-dest': 'empty',
174+
'sec-fetch-mode': 'cors',
175+
'sec-fetch-site': 'cross-site',
176+
'User-Agent': UA,
177+
Referer: 'https://wetransfer.com/',
178+
Origin: 'https://wetransfer.com',
179+
'x-requested-with': 'XMLHttpRequest',
180+
},
181+
referrer: 'https://wetransfer.com/',
182+
referrerPolicy: 'origin',
183+
body: JSON.stringify({
184+
items: [
185+
{
186+
path: filename,
187+
item_type: 'file',
188+
blocks: [{ content_length: file.size }],
189+
},
190+
],
191+
}),
192+
method: 'POST',
193+
mode: 'cors',
194+
credentials: 'include',
195+
}).then(async (res) => {
196+
if (res.status !== 200) {
197+
console.log(await res.text());
198+
throw new Error('preflict');
199+
}
200+
return res.blob();
201+
});
202+
console.log('preflict');
203+
const blocks = await fetch(urls['storm.announce_blocks_url'], {
204+
headers: {
205+
accept: 'application/json',
206+
'accept-language': 'zh-CN,zh;q=0.9',
207+
authorization,
208+
'content-type': 'application/json',
209+
'idempotency-key':
210+
'"0asfHJuFkqwuhgBlE1OBzZ_g8mkJl_DocAfD5Je23HvYwsYpLQxyz_XgJd2T9NPY"',
211+
'sec-ch-ua':
212+
'"Google Chrome";v="123", "Not:A-Brand";v="8", "Chromium";v="123"',
213+
'sec-ch-ua-mobile': '?0',
214+
'sec-ch-ua-platform': '"macOS"',
215+
'sec-fetch-dest': 'empty',
216+
'sec-fetch-mode': 'cors',
217+
'sec-fetch-site': 'cross-site',
218+
},
219+
referrer: 'https://wetransfer.com/',
220+
referrerPolicy: 'origin',
221+
body: JSON.stringify({
222+
blocks: [{ content_length: file.size, content_md5_hex: hash }],
223+
}),
224+
method: 'POST',
225+
mode: 'cors',
226+
credentials: 'include',
227+
}).then((res) => res.json());
228+
const url = blocks.data.blocks[0].presigned_put_url;
229+
console.log('got upload server url');
230+
await fetch(url, {
231+
headers: {
232+
accept: '*/*',
233+
'accept-language': 'zh-CN,zh;q=0.9',
234+
'sec-fetch-dest': 'empty',
235+
'sec-fetch-mode': 'cors',
236+
'sec-fetch-site': 'cross-site',
237+
},
238+
referrer: 'https://wetransfer.com/',
239+
referrerPolicy: 'origin',
240+
body: null,
241+
method: 'OPTIONS',
242+
mode: 'cors',
243+
credentials: 'omit',
244+
});
245+
await fetch(url, {
246+
headers: {
247+
accept: '*/*',
248+
'accept-language': 'zh-CN,zh;q=0.9',
249+
...blocks.data.blocks[0].put_request_headers,
250+
},
251+
referrer: 'https://wetransfer.com/',
252+
referrerPolicy: 'origin',
253+
body: file,
254+
method: 'PUT',
255+
mode: 'cors',
256+
credentials: 'omit',
257+
}).then((res) => {
258+
console.log(res.status);
259+
if (res.status >= 300) {
260+
throw Error('upload failed');
261+
}
262+
return res.blob();
263+
});
264+
await new Promise((resolve) => {
265+
setTimeout(resolve, 3000);
266+
});
267+
console.log('get Callback URL');
268+
const result = await fetch(urls['storm.create_batch_url'], {
269+
headers: {
270+
accept: 'application/json',
271+
'accept-language': 'zh-CN,zh;q=0.9',
272+
authorization,
273+
'content-type': 'application/json',
274+
'idempotency-key':
275+
'"0asfHJuFkqwuhgBlE1OBzZ_g8mkJl_DocAfD5Je23HvYwsYpLQxyz_XgJd2T9NPY"',
276+
'sec-ch-ua':
277+
'"Google Chrome";v="123", "Not:A-Brand";v="8", "Chromium";v="123"',
278+
'sec-ch-ua-mobile': '?0',
279+
'sec-ch-ua-platform': '"macOS"',
280+
'sec-fetch-dest': 'empty',
281+
'sec-fetch-mode': 'cors',
282+
'sec-fetch-site': 'cross-site',
283+
'x-deadline': '5',
284+
'x-error-budget': 'reqs=15 oks=14 avail=1.00',
285+
},
286+
referrer: 'https://wetransfer.com/',
287+
referrerPolicy: 'origin',
288+
body: JSON.stringify({
289+
items: [
290+
{
291+
path: filename,
292+
item_type: 'file',
293+
block_ids: [blocks.data.blocks[0].block_id],
294+
},
295+
],
296+
}),
297+
method: 'POST',
298+
mode: 'cors',
299+
credentials: 'include',
300+
}).then((res) => res.json());
301+
console.log(result);
302+
const finalize = await fetch(
303+
'https://wetransfer.com/api/v4/transfers/' + transfer.id + '/finalize',
304+
{
305+
headers: {
306+
accept: 'application/json, text/plain, */*',
307+
'accept-language': 'zh-CN,zh;q=0.9',
308+
'content-type': 'application/json',
309+
'sec-ch-ua':
310+
'"Google Chrome";v="123", "Not:A-Brand";v="8", "Chromium";v="123"',
311+
'sec-ch-ua-mobile': '?0',
312+
'sec-ch-ua-platform': '"macOS"',
313+
'sec-fetch-dest': 'empty',
314+
'sec-fetch-mode': 'cors',
315+
'sec-fetch-site': 'same-origin',
316+
'x-amplitude-country': 'CN',
317+
'x-amplitude-device-family': 'Macintosh',
318+
'x-amplitude-device-id': 'YexdY326lbjSrV1RiXozWp',
319+
'x-amplitude-device-type': 'Apple Macintosh',
320+
'x-amplitude-language': 'en',
321+
'x-amplitude-platform': 'Web',
322+
'x-app-origin': 'decoupled',
323+
'User-Agent': UA,
324+
Referer: 'https://wetransfer.com/',
325+
Origin: 'https://wetransfer.com',
326+
'x-requested-with': 'XMLHttpRequest',
327+
},
328+
referrer: 'https://wetransfer.com/',
329+
referrerPolicy: 'origin',
330+
body: '{"wants_storm":true}',
331+
method: 'PUT',
332+
},
333+
).then((res) => res.json());
334+
console.log(transfer.id);
335+
console.log(finalize);
336+
return finalize.shortened_url;
337+
}

0 commit comments

Comments
 (0)