Add typescript
This commit is contained in:
parent
08c21db340
commit
a1037a810c
|
@ -1,19 +1,14 @@
|
|||
const { parseRequest } = require('./parser');
|
||||
const { getScreenshot } = require('./chromium');
|
||||
const { getHtml } = require('./template');
|
||||
const { writeTempFile, pathToFileURL } = require('./file');
|
||||
import { IncomingMessage, ServerResponse } from 'http';
|
||||
import { parseRequest } from './parser';
|
||||
import { getScreenshot } from './chromium';
|
||||
import { getHtml } from './template';
|
||||
import { writeTempFile, pathToFileURL } from './file';
|
||||
|
||||
async function handler(req, res) {
|
||||
async function handler(req: IncomingMessage, res: ServerResponse) {
|
||||
try {
|
||||
let {
|
||||
type = 'png',
|
||||
text = 'Hello',
|
||||
fontWeight = 'bold',
|
||||
image = 'now-black',
|
||||
} = parseRequest(req);
|
||||
const name = decodeURIComponent(text);
|
||||
const html = getHtml(name, fontWeight, image);
|
||||
const filePath = await writeTempFile(name, html);
|
||||
const { type, text, fontWeight, images } = parseRequest(req);
|
||||
const html = getHtml(text, fontWeight, images);
|
||||
const filePath = await writeTempFile(text, html);
|
||||
const fileUrl = pathToFileURL(filePath);
|
||||
const file = await getScreenshot(fileUrl, type);
|
||||
res.statusCode = 200;
|
|
@ -1,8 +1,9 @@
|
|||
const chrome = require('chrome-aws-lambda');
|
||||
const puppeteer = require('puppeteer-core');
|
||||
import * as chromeAwsLambda from 'chrome-aws-lambda';
|
||||
import { launch } from 'puppeteer-core';
|
||||
const chrome = chromeAwsLambda as any;
|
||||
|
||||
async function getScreenshot(url, type) {
|
||||
const browser = await puppeteer.launch({
|
||||
export async function getScreenshot(url: string, type: ScreenshotType) {
|
||||
const browser = await launch({
|
||||
args: chrome.args,
|
||||
executablePath: await chrome.executablePath,
|
||||
headless: chrome.headless,
|
||||
|
@ -15,5 +16,3 @@ async function getScreenshot(url, type) {
|
|||
await browser.close();
|
||||
return file;
|
||||
}
|
||||
|
||||
module.exports = { getScreenshot };
|
|
@ -1,21 +1,19 @@
|
|||
const { writeFile } = require('fs');
|
||||
const { join } = require('path');
|
||||
const { promisify } = require('util');
|
||||
import { writeFile } from 'fs';
|
||||
import { join } from 'path';
|
||||
import { promisify } from 'util';
|
||||
import { tmpdir } from 'os';
|
||||
import { URL } from 'url';
|
||||
const writeFileAsync = promisify(writeFile);
|
||||
const { tmpdir } = require('os');
|
||||
const { URL } = require('url');
|
||||
|
||||
async function writeTempFile(name, contents) {
|
||||
export async function writeTempFile(name: string, contents: string) {
|
||||
const randomPath = join(tmpdir(), `${name}.html`);
|
||||
console.log('Writing file to ' + randomPath);
|
||||
await writeFileAsync(randomPath, contents);
|
||||
return randomPath;
|
||||
}
|
||||
|
||||
function pathToFileURL(path) {
|
||||
export function pathToFileURL(path: string) {
|
||||
const { href } = new URL(path, 'file:');
|
||||
console.log('File url is ' + href);
|
||||
return href;
|
||||
}
|
||||
|
||||
module.exports = { writeTempFile, pathToFileURL }
|
4
now.json
4
now.json
|
@ -3,9 +3,9 @@
|
|||
"alias": "og-image.now.sh",
|
||||
"version": 2,
|
||||
"builds": [
|
||||
{ "src": "card.js", "use": "@now/node", "config": { "maxLambdaSize": "40mb" } }
|
||||
{ "src": "card.ts", "use": "@now/node@canary", "config": { "maxLambdaSize": "40mb" } }
|
||||
],
|
||||
"routes": [
|
||||
{ "src": "/(.*)", "dest": "/card.js" }
|
||||
{ "src": "/(.*)", "dest": "/card.ts" }
|
||||
]
|
||||
}
|
|
@ -12,5 +12,9 @@
|
|||
"dependencies": {
|
||||
"chrome-aws-lambda": "1.11.1",
|
||||
"puppeteer-core": "1.11.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/puppeteer-core": "^1.9.0",
|
||||
"typescript": "^3.2.4"
|
||||
}
|
||||
}
|
||||
|
|
13
parser.js
13
parser.js
|
@ -1,13 +0,0 @@
|
|||
const { parse } = require('url');
|
||||
|
||||
function parseRequest(req) {
|
||||
const { pathname = '/', query = {} } = parse(req.url, true);
|
||||
const { fontWeight, image } = query;
|
||||
console.log('Hit ' + pathname, query);
|
||||
const arr = pathname.slice(1).split('.');
|
||||
const type = arr.pop();
|
||||
const text = arr.join('.');
|
||||
return { type, text, fontWeight, image };
|
||||
}
|
||||
|
||||
module.exports = { parseRequest }
|
|
@ -0,0 +1,30 @@
|
|||
import { IncomingMessage } from 'http';
|
||||
import { parse } from 'url';
|
||||
|
||||
interface ParsedRequest {
|
||||
type: ScreenshotType;
|
||||
text: string;
|
||||
fontWeight: FontWeight;
|
||||
images: string[];
|
||||
};
|
||||
|
||||
export function parseRequest(req: IncomingMessage) {
|
||||
console.log('HTTP ' + req.url);
|
||||
const { pathname = '/', query = {} } = parse(req.url || '', true);
|
||||
const { fontWeight, images } = query;
|
||||
if (Array.isArray(fontWeight)) {
|
||||
throw new Error('Expected a single fontWeight');
|
||||
}
|
||||
const arr = pathname.slice(1).split('.');
|
||||
const type = arr.pop();
|
||||
const text = arr.join('.');
|
||||
const parsedRequest: ParsedRequest = {
|
||||
type: type as ScreenshotType,
|
||||
text: decodeURIComponent(text),
|
||||
fontWeight: fontWeight as FontWeight,
|
||||
images: Array.isArray(images) && images.length > 0
|
||||
? images
|
||||
: ['https://assets.zeit.co/image/upload/front/assets/design/now-black.svg'],
|
||||
};
|
||||
return parsedRequest;
|
||||
}
|
|
@ -1,11 +1,7 @@
|
|||
|
||||
const { readFileSync } = require('fs');
|
||||
import { readFileSync } from 'fs';
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {'bold' | 'normal'} fontWeight
|
||||
*/
|
||||
function getCss(fontWeight) {
|
||||
function getCss(fontWeight: FontWeight) {
|
||||
const regular = `${__dirname}/fonts/Inter-UI-Regular.woff2`;
|
||||
const bold = `${__dirname}/fonts/Inter-UI-Bold.woff2`;
|
||||
const buffer = readFileSync(fontWeight === 'bold' ? bold : regular);
|
||||
|
@ -46,14 +42,7 @@ function getCss(fontWeight) {
|
|||
}`;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} text
|
||||
* @param {'bold' | 'normal'} fontWeight
|
||||
* @param {'now-black' | 'now-white' | 'zeit-black-triangle' | 'zeit-white-triangle'} image
|
||||
*/
|
||||
function getHtml(text, fontWeight, image) {
|
||||
const logo = `https://assets.zeit.co/image/upload/front/assets/design/${image}.svg`;
|
||||
export function getHtml(text: string, fontWeight: FontWeight, images: string[]) {
|
||||
return `<html>
|
||||
<style>
|
||||
${getCss(fontWeight)}
|
||||
|
@ -61,12 +50,10 @@ function getHtml(text, fontWeight, image) {
|
|||
<body>
|
||||
<div>
|
||||
<div class="spacer">
|
||||
<img class="logo" src="${logo}" />
|
||||
<img class="logo" src="${images[0]}" />
|
||||
<div class="spacer">
|
||||
<div class="heading">${text}</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>`;
|
||||
}
|
||||
|
||||
module.exports = { getHtml }
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"jsx": "react",
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noImplicitReturns": true,
|
||||
"noEmitOnError": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"removeComments": true,
|
||||
"preserveConstEnums": true
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
type FontWeight = 'normal' | 'bold';
|
||||
type ScreenshotType = 'png' | 'jpeg' | undefined;
|
Loading…
Reference in New Issue