Skip to content

Commit

Permalink
- Added rollup and bundle default handler
Browse files Browse the repository at this point in the history
- Fixed expected uri in origin response.
- Added util to rollup externals as it was breaking.
  • Loading branch information
thchia committed Aug 30, 2020
1 parent 552ad39 commit bd82c46
Show file tree
Hide file tree
Showing 12 changed files with 332 additions and 41 deletions.
2 changes: 1 addition & 1 deletion packages/libs/lambda-at-edge/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
!tests/**
dist/
dist/
13 changes: 11 additions & 2 deletions packages/libs/lambda-at-edge/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"types": "dist/index.d.ts",
"scripts": {
"prepare": "yarn build",
"build": "tsc -p tsconfig.build.json"
"build_backup": "tsc -p tsconfig.build.json",
"build": "rollup --config && tsc -p tsconfig.build.json"
},
"files": [
"dist"
Expand All @@ -31,18 +32,26 @@
},
"homepage": "https://github.com/danielcondemarin/serverless-next.js#readme",
"devDependencies": {
"@rollup/plugin-commonjs": "^15.0.0",
"@rollup/plugin-node-resolve": "^9.0.0",
"@rollup/plugin-typescript": "^5.0.2",
"@types/aws-lambda": "^8.10.57",
"@types/cookie": "^0.4.0",
"@types/execa": "^2.0.0",
"@types/fs-extra": "^9.0.1",
"@types/jsonwebtoken": "^8.5.0",
"@types/node": "^14.0.14",
"@types/path-to-regexp": "^1.7.0",
"path-to-regexp": "^6.1.0",
"rollup": "^2.26.6",
"ts-loader": "^7.0.5",
"typescript": "^3.9.6"
},
"dependencies": {
"@zeit/node-file-trace": "^0.6.5",
"cookie": "^0.4.1",
"execa": "^4.0.2",
"fs-extra": "^9.0.1",
"path-to-regexp": "^6.1.0"
"jsonwebtoken": "^8.5.1"
}
}
26 changes: 26 additions & 0 deletions packages/libs/lambda-at-edge/rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import commonjs from "@rollup/plugin-commonjs";
import typescript from "@rollup/plugin-typescript";
import { nodeResolve } from "@rollup/plugin-node-resolve";

export default {
input: "./src/default-handler.ts",
output: {
file: "dist/default-handler.js",
format: "cjs"
},
plugins: [
commonjs(),
nodeResolve(),
typescript({
tsconfig: "tsconfig.bundle.json"
})
],
external: [
"util",
"aws-lambda",
"./manifest.json",
"aws-sdk/clients/s3",
"./routes-manifest.json",
"./prerender-manifest.json"
]
};
8 changes: 0 additions & 8 deletions packages/libs/lambda-at-edge/src/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,14 +175,6 @@ class Builder {
join(this.outputDir, DEFAULT_LAMBDA_CODE_DIR, "manifest.json"),
buildManifest
),
fse.copy(
require.resolve("@sls-next/next-aws-cloudfront"),
join(
this.outputDir,
DEFAULT_LAMBDA_CODE_DIR,
"node_modules/@sls-next/next-aws-cloudfront/index.js"
)
),
fse.copy(
join(this.serverlessDir, "pages"),
join(this.outputDir, DEFAULT_LAMBDA_CODE_DIR, "pages"),
Expand Down
46 changes: 32 additions & 14 deletions packages/libs/lambda-at-edge/src/default-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Manifest from "./manifest.json";
// @ts-ignore
import { basePath } from "./routes-manifest.json";
import lambdaAtEdgeCompat from "@sls-next/next-aws-cloudfront";
import cookie from "cookie";
import {
CloudFrontRequest,
CloudFrontS3Origin,
Expand All @@ -21,23 +22,26 @@ import {
import S3 from "aws-sdk/clients/s3";
import { performance } from "perf_hooks";
import { ServerResponse } from "http";
import jsonwebtoken from "jsonwebtoken";

const parseCookieValue = (cookie: string) => {
return cookie.split(";").reduce<{ [key: string]: string }>((acc, curr) => {
const [key, value] = curr.split("=");
acc[key.trim()] = value.trim();
return acc;
}, {});
};
const NEXT_PREVIEW_DATA_COOKIE = "__next_preview_data";
const NEXT_PRERENDER_BYPASS_COOKIE = "__prerender_bypass";

const checkPreviewRequest = (request: CloudFrontRequest) => {
const getPreviewCookies = (request: CloudFrontRequest) => {
const targetCookie = request.headers.cookie || [];
return targetCookie.some((cookieObj) => {
const cookieValue = parseCookieValue(cookieObj.value);
const previewCookie = targetCookie.find((cookieObj) => {
const cookieValue = cookie.parse(cookieObj.value);
return (
cookieValue["__next_preview_data"] && cookieValue["__prerender_bypass"]
cookieValue[NEXT_PREVIEW_DATA_COOKIE] &&
cookieValue[NEXT_PRERENDER_BYPASS_COOKIE]
);
});
if (previewCookie) {
return cookie.parse(previewCookie.value) as {
[NEXT_PREVIEW_DATA_COOKIE]: string;
[NEXT_PRERENDER_BYPASS_COOKIE]: string;
};
}
};

const perfLogger = (logLambdaExecutionTimes: boolean): PerfLogger => {
Expand Down Expand Up @@ -224,7 +228,21 @@ const handleOriginRequest = async ({
const normalisedS3DomainName = normaliseS3OriginDomain(s3Origin);
const hasFallback = hasFallbackForUri(uri, prerenderManifest);
const { now, log } = perfLogger(manifest.logLambdaExecutionTimes);
const isPreviewRequest = checkPreviewRequest(request);
const isPreviewRequest = getPreviewCookies(request);

if (isPreviewRequest) {
try {
jsonwebtoken.verify(
isPreviewRequest[NEXT_PREVIEW_DATA_COOKIE],
prerenderManifest.preview.previewModeSigningKey
);
} catch (e) {
return {
status: "403",
statusDescription: "Forbidden"
};
}
}

s3Origin.domainName = normalisedS3DomainName;

Expand Down Expand Up @@ -276,7 +294,7 @@ const handleOriginRequest = async ({
}

// Render page
if (isDataRequest(uri)) {
if (isDataReq) {
const { renderOpts } = await page.renderReqToHTML(
req,
res,
Expand Down Expand Up @@ -317,7 +335,7 @@ const handleOriginResponse = async ({
}) => {
const response = event.Records[0].cf.response;
const request = event.Records[0].cf.request;
const uri = normaliseUri(request.uri);
const uri = normaliseUri(request.uri).replace(/\.html$/, "");
const { status } = response;
if (status !== "403") {
const pagePath = router(manifest)(uri);
Expand Down
11 changes: 1 addition & 10 deletions packages/libs/lambda-at-edge/tests/build/build.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ describe("Builder Tests", () => {

describe("Default Handler Artefact Files", () => {
it("copies build files", async () => {
expect.assertions(7);
expect.assertions(6);

const files = await fse.readdir(
join(outputDir, `${DEFAULT_LAMBDA_CODE_DIR}`)
Expand All @@ -170,24 +170,15 @@ describe("Builder Tests", () => {
const apiDirExists = await fse.pathExists(
join(outputDir, `${DEFAULT_LAMBDA_CODE_DIR}/pages/api`)
);
const compatLayerIncluded = await fse.pathExists(
join(
outputDir,
`${DEFAULT_LAMBDA_CODE_DIR}/node_modules/@sls-next/next-aws-cloudfront/index.js`
)
);

expect(files).toEqual([
"index.js",
"manifest.json",
"node_modules",
"pages",
"prerender-manifest.json",
"routes-manifest.json"
]);

expect(compatLayerIncluded).toEqual(true);

// api pages should not be included in the default lambda
expect(apiDirExists).toEqual(false);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import {
CloudFrontOrigin
} from "aws-lambda";

jest.mock("jsonwebtoken", () => ({
verify: jest.fn()
}));

jest.mock(
"../../src/prerender-manifest.json",
() => require("./prerender-manifest.json"),
Expand Down
3 changes: 2 additions & 1 deletion packages/libs/lambda-at-edge/tsconfig.build.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
"sourceMap": false,
"removeComments": true
},
"include": ["./src/"]
"include": ["./src/"],
"exclude": ["node_modules", "./src/default-handler.ts"]
}
14 changes: 14 additions & 0 deletions packages/libs/lambda-at-edge/tsconfig.bundle.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"module": "ESNext",
"target": "es2019",
"moduleResolution": "node",
"noImplicitAny": true,
"sourceMap": true,
"strict": true,
"allowJs": true
},
"include": ["./src/default-handler.ts"]
}
2 changes: 2 additions & 0 deletions packages/libs/lambda-at-edge/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ export type PreRenderedManifest = {
};
preview: {
previewModeId: string;
previewModeSigningKey: string;
previewModeEncryptionKey: string;
};
};

Expand Down
Loading

0 comments on commit bd82c46

Please sign in to comment.