Skip to content

Commit 854255e

Browse files
committed
Add node14 template
For the current LTS version Signed-off-by: Alex Ellis (OpenFaaS Ltd) <[email protected]>
1 parent d50ca50 commit 854255e

File tree

8 files changed

+256
-2
lines changed

8 files changed

+256
-2
lines changed

.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,5 @@ build
66
.idea
77
**/bin/**
88
.settings
9-
10-
template
9+
/**/package-lock.json
1110
/**/node_modules

template/node14/.dockerignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*/node_modules

template/node14/Dockerfile

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
FROM --platform=${TARGETPLATFORM:-linux/amd64} ghcr.io/openfaas/of-watchdog:0.8.3 as watchdog
2+
FROM --platform=${TARGETPLATFORM:-linux/amd64} node:14-alpine as ship
3+
4+
ARG TARGETPLATFORM
5+
ARG BUILDPLATFORM
6+
7+
COPY --from=watchdog /fwatchdog /usr/bin/fwatchdog
8+
RUN chmod +x /usr/bin/fwatchdog
9+
10+
RUN apk --no-cache add curl ca-certificates \
11+
&& addgroup -S app && adduser -S -g app app
12+
13+
# Turn down the verbosity to default level.
14+
ENV NPM_CONFIG_LOGLEVEL warn
15+
16+
RUN chmod 777 /tmp
17+
18+
USER app
19+
20+
RUN mkdir -p /home/app/function
21+
22+
# Wrapper/boot-strapper
23+
WORKDIR /home/app
24+
COPY package.json ./
25+
26+
# This ordering means the npm installation is cached for the outer function handler.
27+
RUN npm i
28+
29+
# Copy outer function handler
30+
COPY index.js ./
31+
32+
# COPY function node packages and install, adding this as a separate
33+
# entry allows caching of npm install
34+
35+
WORKDIR /home/app/function
36+
COPY function/*.json ./
37+
38+
RUN npm i
39+
40+
# COPY function files and folders
41+
COPY function/ ./
42+
43+
# Run any tests that may be available
44+
RUN npm test
45+
46+
# Set correct permissions to use non root user
47+
WORKDIR /home/app/
48+
49+
ENV cgi_headers="true"
50+
ENV fprocess="node index.js"
51+
ENV mode="http"
52+
ENV upstream_url="http://127.0.0.1:3000"
53+
54+
ENV exec_timeout="10s"
55+
ENV write_timeout="15s"
56+
ENV read_timeout="15s"
57+
58+
ENV prefix_logs="false"
59+
60+
HEALTHCHECK --interval=3s CMD [ -e /tmp/.lock ] || exit 1
61+
62+
CMD ["fwatchdog"]
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
'use strict'
2+
3+
module.exports = async (event, context) => {
4+
const result = {
5+
'body': JSON.stringify(event.body),
6+
'content-type': event.headers["content-type"]
7+
}
8+
9+
return context
10+
.status(200)
11+
.succeed(result)
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"name": "openfaas-function",
3+
"version": "1.0.0",
4+
"description": "OpenFaaS Function",
5+
"main": "handler.js",
6+
"scripts": {
7+
"test": "echo \"Error: no test specified\" && exit 0"
8+
},
9+
"keywords": [],
10+
"author": "OpenFaaS Ltd",
11+
"license": "MIT"
12+
}

template/node14/index.js

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
// Copyright (c) Alex Ellis 2021. All rights reserved.
2+
// Copyright (c) OpenFaaS Author(s) 2021. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
4+
5+
"use strict"
6+
7+
const express = require('express')
8+
const app = express()
9+
const handler = require('./function/handler');
10+
const bodyParser = require('body-parser')
11+
12+
const defaultMaxSize = '100kb' // body-parser default
13+
14+
app.disable('x-powered-by');
15+
16+
const rawLimit = process.env.MAX_RAW_SIZE || defaultMaxSize
17+
const jsonLimit = process.env.MAX_JSON_SIZE || defaultMaxSize
18+
19+
app.use(function addDefaultContentType(req, res, next) {
20+
// When no content-type is given, the body element is set to
21+
// nil, and has been a source of contention for new users.
22+
23+
if(!req.headers['content-type']) {
24+
req.headers['content-type'] = "text/plain"
25+
}
26+
next()
27+
})
28+
29+
if (process.env.RAW_BODY === 'true') {
30+
app.use(bodyParser.raw({ type: '*/*' , limit: rawLimit }))
31+
} else {
32+
app.use(bodyParser.text({ type : "text/*" }));
33+
app.use(bodyParser.json({ limit: jsonLimit}));
34+
app.use(bodyParser.urlencoded({ extended: true }));
35+
}
36+
37+
const isArray = (a) => {
38+
return (!!a) && (a.constructor === Array);
39+
};
40+
41+
const isObject = (a) => {
42+
return (!!a) && (a.constructor === Object);
43+
};
44+
45+
class FunctionEvent {
46+
constructor(req) {
47+
this.body = req.body;
48+
this.headers = req.headers;
49+
this.method = req.method;
50+
this.query = req.query;
51+
this.path = req.path;
52+
}
53+
}
54+
55+
class FunctionContext {
56+
constructor(cb) {
57+
this.value = 200;
58+
this.cb = cb;
59+
this.headerValues = {};
60+
this.cbCalled = 0;
61+
}
62+
63+
status(value) {
64+
if(!value) {
65+
return this.value;
66+
}
67+
68+
this.value = value;
69+
return this;
70+
}
71+
72+
headers(value) {
73+
if(!value) {
74+
return this.headerValues;
75+
}
76+
77+
this.headerValues = value;
78+
return this;
79+
}
80+
81+
succeed(value) {
82+
let err;
83+
this.cbCalled++;
84+
this.cb(err, value);
85+
}
86+
87+
fail(value) {
88+
let message;
89+
this.cbCalled++;
90+
this.cb(value, message);
91+
}
92+
}
93+
94+
const middleware = async (req, res) => {
95+
const cb = (err, functionResult) => {
96+
if (err) {
97+
console.error(err);
98+
99+
return res.status(500)
100+
.send(err.toString ? err.toString() : err);
101+
}
102+
103+
if(isArray(functionResult) || isObject(functionResult)) {
104+
res.set(fnContext.headers())
105+
.status(fnContext.status()).send(JSON.stringify(functionResult));
106+
} else {
107+
res.set(fnContext.headers())
108+
.status(fnContext.status())
109+
.send(functionResult);
110+
}
111+
};
112+
113+
const fnEvent = new FunctionEvent(req);
114+
const fnContext = new FunctionContext(cb);
115+
116+
Promise.resolve(handler(fnEvent, fnContext, cb))
117+
.then(res => {
118+
if(!fnContext.cbCalled) {
119+
fnContext.succeed(res);
120+
}
121+
})
122+
.catch(e => {
123+
cb(e);
124+
});
125+
};
126+
127+
app.post('/*', middleware);
128+
app.get('/*', middleware);
129+
app.patch('/*', middleware);
130+
app.put('/*', middleware);
131+
app.delete('/*', middleware);
132+
app.options('/*', middleware);
133+
134+
const port = process.env.http_port || 3000;
135+
136+
app.listen(port, () => {
137+
console.log(`node12 listening on port: ${port}`)
138+
});
139+
140+

template/node14/package.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "openfaas-node12",
3+
"version": "1.0.0",
4+
"description": "",
5+
"main": "index.js",
6+
"scripts": {
7+
"test": "echo \"Error: no tests specified\" && exit 0"
8+
},
9+
"keywords": [],
10+
"author": "OpenFaaS Ltd",
11+
"license": "MIT",
12+
"dependencies": {
13+
"body-parser": "^1.18.2",
14+
"express": "^4.16.2"
15+
}
16+
}

template/node14/template.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
language: node12
2+
fprocess: node index.js
3+
welcome_message: |
4+
You have created a new function which uses Node.js 12 (TLS) and the OpenFaaS
5+
of-watchdog which gives greater control over HTTP responses.
6+
7+
npm i --save can be used to add third-party packages like request or cheerio
8+
npm documentation: https://docs.npmjs.com/
9+
10+
Unit tests are run at build time via "npm run", edit package.json to specify
11+
how you want to execute them.
12+

0 commit comments

Comments
 (0)