Skip to content

Commit

Permalink
Add node14 template
Browse files Browse the repository at this point in the history
For the current LTS version

Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
  • Loading branch information
alexellis committed Feb 15, 2021
1 parent d50ca50 commit 854255e
Show file tree
Hide file tree
Showing 8 changed files with 256 additions and 2 deletions.
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,5 @@ build
.idea
**/bin/**
.settings

template
/**/package-lock.json
/**/node_modules
1 change: 1 addition & 0 deletions template/node14/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*/node_modules
62 changes: 62 additions & 0 deletions template/node14/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
FROM --platform=${TARGETPLATFORM:-linux/amd64} ghcr.io/openfaas/of-watchdog:0.8.3 as watchdog
FROM --platform=${TARGETPLATFORM:-linux/amd64} node:14-alpine as ship

ARG TARGETPLATFORM
ARG BUILDPLATFORM

COPY --from=watchdog /fwatchdog /usr/bin/fwatchdog
RUN chmod +x /usr/bin/fwatchdog

RUN apk --no-cache add curl ca-certificates \
&& addgroup -S app && adduser -S -g app app

# Turn down the verbosity to default level.
ENV NPM_CONFIG_LOGLEVEL warn

RUN chmod 777 /tmp

USER app

RUN mkdir -p /home/app/function

# Wrapper/boot-strapper
WORKDIR /home/app
COPY package.json ./

# This ordering means the npm installation is cached for the outer function handler.
RUN npm i

# Copy outer function handler
COPY index.js ./

# COPY function node packages and install, adding this as a separate
# entry allows caching of npm install

WORKDIR /home/app/function
COPY function/*.json ./

RUN npm i

# COPY function files and folders
COPY function/ ./

# Run any tests that may be available
RUN npm test

# Set correct permissions to use non root user
WORKDIR /home/app/

ENV cgi_headers="true"
ENV fprocess="node index.js"
ENV mode="http"
ENV upstream_url="http://127.0.0.1:3000"

ENV exec_timeout="10s"
ENV write_timeout="15s"
ENV read_timeout="15s"

ENV prefix_logs="false"

HEALTHCHECK --interval=3s CMD [ -e /tmp/.lock ] || exit 1

CMD ["fwatchdog"]
12 changes: 12 additions & 0 deletions template/node14/function/handler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
'use strict'

module.exports = async (event, context) => {
const result = {
'body': JSON.stringify(event.body),
'content-type': event.headers["content-type"]
}

return context
.status(200)
.succeed(result)
}
12 changes: 12 additions & 0 deletions template/node14/function/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "openfaas-function",
"version": "1.0.0",
"description": "OpenFaaS Function",
"main": "handler.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 0"
},
"keywords": [],
"author": "OpenFaaS Ltd",
"license": "MIT"
}
140 changes: 140 additions & 0 deletions template/node14/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
// Copyright (c) Alex Ellis 2021. All rights reserved.
// Copyright (c) OpenFaaS Author(s) 2021. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

"use strict"

const express = require('express')
const app = express()
const handler = require('./function/handler');
const bodyParser = require('body-parser')

const defaultMaxSize = '100kb' // body-parser default

app.disable('x-powered-by');

const rawLimit = process.env.MAX_RAW_SIZE || defaultMaxSize
const jsonLimit = process.env.MAX_JSON_SIZE || defaultMaxSize

app.use(function addDefaultContentType(req, res, next) {
// When no content-type is given, the body element is set to
// nil, and has been a source of contention for new users.

if(!req.headers['content-type']) {
req.headers['content-type'] = "text/plain"
}
next()
})

if (process.env.RAW_BODY === 'true') {
app.use(bodyParser.raw({ type: '*/*' , limit: rawLimit }))
} else {
app.use(bodyParser.text({ type : "text/*" }));
app.use(bodyParser.json({ limit: jsonLimit}));
app.use(bodyParser.urlencoded({ extended: true }));
}

const isArray = (a) => {
return (!!a) && (a.constructor === Array);
};

const isObject = (a) => {
return (!!a) && (a.constructor === Object);
};

class FunctionEvent {
constructor(req) {
this.body = req.body;
this.headers = req.headers;
this.method = req.method;
this.query = req.query;
this.path = req.path;
}
}

class FunctionContext {
constructor(cb) {
this.value = 200;
this.cb = cb;
this.headerValues = {};
this.cbCalled = 0;
}

status(value) {
if(!value) {
return this.value;
}

this.value = value;
return this;
}

headers(value) {
if(!value) {
return this.headerValues;
}

this.headerValues = value;
return this;
}

succeed(value) {
let err;
this.cbCalled++;
this.cb(err, value);
}

fail(value) {
let message;
this.cbCalled++;
this.cb(value, message);
}
}

const middleware = async (req, res) => {
const cb = (err, functionResult) => {
if (err) {
console.error(err);

return res.status(500)
.send(err.toString ? err.toString() : err);
}

if(isArray(functionResult) || isObject(functionResult)) {
res.set(fnContext.headers())
.status(fnContext.status()).send(JSON.stringify(functionResult));
} else {
res.set(fnContext.headers())
.status(fnContext.status())
.send(functionResult);
}
};

const fnEvent = new FunctionEvent(req);
const fnContext = new FunctionContext(cb);

Promise.resolve(handler(fnEvent, fnContext, cb))
.then(res => {
if(!fnContext.cbCalled) {
fnContext.succeed(res);
}
})
.catch(e => {
cb(e);
});
};

app.post('/*', middleware);
app.get('/*', middleware);
app.patch('/*', middleware);
app.put('/*', middleware);
app.delete('/*', middleware);
app.options('/*', middleware);

const port = process.env.http_port || 3000;

app.listen(port, () => {
console.log(`node12 listening on port: ${port}`)
});


16 changes: 16 additions & 0 deletions template/node14/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "openfaas-node12",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no tests specified\" && exit 0"
},
"keywords": [],
"author": "OpenFaaS Ltd",
"license": "MIT",
"dependencies": {
"body-parser": "^1.18.2",
"express": "^4.16.2"
}
}
12 changes: 12 additions & 0 deletions template/node14/template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
language: node12
fprocess: node index.js
welcome_message: |
You have created a new function which uses Node.js 12 (TLS) and the OpenFaaS
of-watchdog which gives greater control over HTTP responses.
npm i --save can be used to add third-party packages like request or cheerio
npm documentation: https://docs.npmjs.com/
Unit tests are run at build time via "npm run", edit package.json to specify
how you want to execute them.

0 comments on commit 854255e

Please sign in to comment.