Add typescript

This commit is contained in:
Steven 2019-01-21 15:31:16 -05:00
parent 08c21db340
commit a1037a810c
10 changed files with 85 additions and 63 deletions

View File

@ -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;

View File

@ -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,
@ -14,6 +15,4 @@ async function getScreenshot(url, type) {
const file = await page.screenshot({ type });
await browser.close();
return file;
}
module.exports = { getScreenshot };
}

View File

@ -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 }
}

View File

@ -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" }
]
}

View File

@ -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"
}
}

View File

@ -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 }

30
parser.ts Normal file
View File

@ -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;
}

View File

@ -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 }

20
tsconfig.json Normal file
View File

@ -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"
]
}

2
types.d.ts vendored Normal file
View File

@ -0,0 +1,2 @@
type FontWeight = 'normal' | 'bold';
type ScreenshotType = 'png' | 'jpeg' | undefined;