Chapter 4,6: prettier updates and web framework samples

This commit is contained in:
Beth Griggs
2020-05-31 19:31:42 +01:00
parent b43bf2c378
commit 0d8170c265
43 changed files with 4820 additions and 242 deletions
+3 -3
View File
@@ -1,5 +1,5 @@
<form method="POST" enctype="multipart/form-data">
<label for="userfile">File:</label>
<input type="file" id="userfile" name="userfile"><br>
<input type="submit">
<label for="userfile">File:</label>
<input type="file" id="userfile" name="userfile" /><br />
<input type="submit" />
</form>
+43 -40
View File
@@ -1,55 +1,58 @@
const fs = require('fs')
const http = require('http')
const path = require('path')
const fs = require("fs");
const http = require("http");
const path = require("path");
const form = fs.readFileSync(path.join(__dirname, 'public', 'form.html'))
const form = fs.readFileSync(path.join(__dirname, "public", "form.html"));
const formidable = require('formidable')
const formidable = require("formidable");
http.createServer((req, res) => {
if (req.method === 'GET') {
get(res)
return
http
.createServer((req, res) => {
if (req.method === "GET") {
get(res);
return;
}
if (req.method === 'POST') {
post(req, res)
return
if (req.method === "POST") {
post(req, res);
return;
}
error(405, res)
}).listen(3000)
error(405, res);
})
.listen(3000);
function get(res) {
res.writeHead(200, {
'Content-Type': 'text/html'
})
res.end(form)
res.writeHead(200, {
"Content-Type": "text/html",
});
res.end(form);
}
function post(req, res) {
if (!/multipart\/form-data/.test(req.headers['content-type'])) {
error(415, res)
return
}
if (!/multipart\/form-data/.test(req.headers["content-type"])) {
error(415, res);
return;
}
const form = formidable({
multiples: true,
uploadDir: './uploads'
const form = formidable({
multiples: true,
uploadDir: "./uploads",
});
form.parse(req, (err, fields, files) => {
if (err) return err;
res.writeHead(200, {
"Content-Type": "application/json",
});
form.parse(req, (err, fields, files) => {
if (err) return err
res.writeHead(200, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify({
fields,
files
}))
})
res.end(
JSON.stringify({
fields,
files,
})
);
});
}
function error(code, res) {
res.statusCode = code
res.end(http.STATUS_CODES[code])
}
res.statusCode = code;
res.end(http.STATUS_CODES[code]);
}
+13 -13
View File
@@ -1,28 +1,28 @@
const http = require('http')
const http = require("http");
const HOSTNAME = process.env.HOSTNAME || '0.0.0.0'
const PORT = process.env.PORT || 8080
const HOSTNAME = process.env.HOSTNAME || "0.0.0.0";
const PORT = process.env.PORT || 8080;
const server = http.createServer((req, res) => {
if (req.method !== 'GET') return error(res, 405)
if (req.url === '/todo') return todo(res)
if (req.url === '/') return index(res)
error(res, 404)
if (req.method !== "GET") return error(res, 405);
if (req.url === "/todo") return todo(res);
if (req.url === "/") return index(res);
error(res, 404);
});
function error(res, code) {
res.statusCode = code
res.end(`{"error": "${http.STATUS_CODES[code]}"}`)
res.statusCode = code;
res.end(`{"error": "${http.STATUS_CODES[code]}"}`);
}
function todo(res) {
res.end('[{"task_id": 1, "description": "walk dog"}]}')
res.end('[{"task_id": 1, "description": "walk dog"}]}');
}
function index(res) {
res.end('{"name": "todo-server"}')
res.end('{"name": "todo-server"}');
}
server.listen(PORT, HOSTNAME, () => {
console.log('Server listening on', server.address())
})
console.log("Server listening on", server.address());
});
+16 -16
View File
@@ -1,28 +1,28 @@
const https = require('https')
const https = require("https");
// http.get('http://example.com', (res) => res.pipe(process.stdout))
const payload = `{
"name": "Beth",
"job": "Software Engineer"
}`
}`;
const opts = {
method: 'POST',
hostname: 'postman-echo.com',
path: '/post',
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(payload)
}
}
method: "POST",
hostname: "postman-echo.com",
path: "/post",
headers: {
"Content-Type": "application/json",
"Content-Length": Buffer.byteLength(payload),
},
};
const req = https.request(opts, (res) => {
process.stdout.write('Status Code: ' + res.statusCode + '\n')
process.stdout.write('Body: ')
res.pipe(process.stdout)
})
process.stdout.write("Status Code: " + res.statusCode + "\n");
process.stdout.write("Body: ");
res.pipe(process.stdout);
});
req.on('error', (err) => console.error('Error: ', err))
req.on("error", (err) => console.error("Error: ", err));
req.end(payload)
req.end(payload);
+42 -41
View File
@@ -1,56 +1,57 @@
const http = require('http')
const fs = require('fs')
const path = require('path')
const http = require("http");
const fs = require("fs");
const path = require("path");
const form = fs.readFileSync(path.join(__dirname, 'public', 'form.html'))
const form = fs.readFileSync(path.join(__dirname, "public", "form.html"));
http.createServer((req, res) => {
if (req.method === 'GET') {
get(res)
return
http
.createServer((req, res) => {
if (req.method === "GET") {
get(res);
return;
}
if (req.method === 'POST') {
post(req, res)
return
if (req.method === "POST") {
post(req, res);
return;
}
error(405, res)
}).listen(3000)
error(405, res);
})
.listen(3000);
function get(res) {
res.writeHead(200, {
'Content-Type': 'text/html'
})
res.end(form)
res.writeHead(200, {
"Content-Type": "text/html",
});
res.end(form);
}
function post(req, res) {
if (req.headers['content-type'] !== 'application/json') {
error(415, res)
return
if (req.headers["content-type"] !== "application/json") {
error(415, res);
return;
}
let input = "";
req.on("data", (chunk) => {
input += chunk.toString();
});
req.on("end", () => {
const parsed = JSON.parse(input);
if (parsed.err) {
error(400, "Bad Request", res);
return;
}
let input = '';
req.on('data', chunk => {
input += chunk.toString()
})
req.on('end', () => {
const parsed = JSON.parse(input)
if (parsed.err) {
error(400, 'Bad Request', res)
return
}
console.log('Received data: ', parsed)
res.end('{"data": ' + input + "}")
})
console.log("Received data: ", parsed);
res.end('{"data": ' + input + "}");
});
}
function error(code, res) {
res.statusCode = code
res.end(http.STATUS_CODES[code])
}
res.statusCode = code;
res.end(http.STATUS_CODES[code]);
}
+23 -23
View File
@@ -1,30 +1,30 @@
<form method="POST">
<label for="forename">Forename:</label>
<input id="forename" name="forename">
<label for="surname">Surname:</label>
<input id="surname" name="surname">
<input type="submit" value="Submit">
<label for="forename">Forename:</label>
<input id="forename" name="forename" />
<label for="surname">Surname:</label>
<input id="surname" name="surname" />
<input type="submit" value="Submit" />
</form>
<script>
document.forms[0].addEventListener('submit', (event) => {
event.preventDefault()
document.forms[0].addEventListener("submit", (event) => {
event.preventDefault();
let data = {
'forename': document.getElementById('forename').value,
'surname': document.getElementById('surname').value
};
console.log('data', data);
let data = {
forename: document.getElementById("forename").value,
surname: document.getElementById("surname").value,
};
console.log("data", data);
fetch('http://localhost:3000', {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
}).then(function (response) {
console.log(response);
return response.json();
});
fetch("http://localhost:3000", {
method: "post",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
}).then(function (response) {
console.log(response);
return response.json();
});
</script>
});
</script>
+34 -32
View File
@@ -1,48 +1,50 @@
const http = require('http')
const fs = require('fs')
const path = require('path')
const http = require("http");
const fs = require("fs");
const path = require("path");
const form = fs.readFileSync(path.join(__dirname, 'public', 'form.html'))
const form = fs.readFileSync(path.join(__dirname, "public", "form.html"));
http.createServer((req, res) => {
if (req.method === 'GET') {
get(res)
return
http
.createServer((req, res) => {
if (req.method === "GET") {
get(res);
return;
}
if (req.method === 'POST') {
post(req, res)
return
if (req.method === "POST") {
post(req, res);
return;
}
error(405, res)
}).listen(3000)
error(405, res);
})
.listen(3000);
function get(res) {
res.writeHead(200, {
'Content-Type': 'text/html'
})
res.end(form)
res.writeHead(200, {
"Content-Type": "text/html",
});
res.end(form);
}
function post(req, res) {
if (req.headers['content-type'] !== 'application/x-www-form-urlencoded') {
error(415, res)
return
}
if (req.headers["content-type"] !== "application/x-www-form-urlencoded") {
error(415, res);
return;
}
let input = '';
let input = "";
req.on('data', chunk => {
input += chunk.toString()
})
req.on("data", (chunk) => {
input += chunk.toString();
});
req.on('end', () => {
console.log(input);
res.end(http.STATUS_CODES[200])
})
req.on("end", () => {
console.log(input);
res.end(http.STATUS_CODES[200]);
});
}
function error(code, res) {
res.statusCode = code
res.end(http.STATUS_CODES[code])
}
res.statusCode = code;
res.end(http.STATUS_CODES[code]);
}
+15 -12
View File
@@ -1,18 +1,21 @@
const nodemailer = require("nodemailer")
const nodemailer = require("nodemailer");
let transporter = nodemailer.createTransport({
host: "localhost",
port: 4321
})
host: "localhost",
port: 4321,
});
transporter.sendMail({
from: 'beth@example.com',
to: 'laddie@example.com',
transporter.sendMail(
{
from: "beth@example.com",
to: "laddie@example.com",
subject: "Hello",
text: "Hello world!"
}, (err, info) => {
text: "Hello world!",
},
(err, info) => {
if (err) {
console.log(err)
console.log(err);
}
console.log("Message Sent:", info)
})
console.log("Message Sent:", info);
}
);
+9 -9
View File
@@ -1,14 +1,14 @@
const SMTPServer = require("smtp-server").SMTPServer
const SMTPServer = require("smtp-server").SMTPServer;
const PORT = 4321
const PORT = 4321;
const server = new SMTPServer({
disabledCommands: ['STARTTLS', 'AUTH'],
logger: true
})
disabledCommands: ["STARTTLS", "AUTH"],
logger: true,
});
server.on('error', err => {
console.error(err);
})
server.on("error", (err) => {
console.error(err);
});
server.listen(PORT)
server.listen(PORT);
+7 -7
View File
@@ -1,11 +1,11 @@
const fs = require('fs')
const http = require('http')
const fs = require("fs");
const http = require("http");
const index = fs.readFileSync('public/index.html')
const index = fs.readFileSync("public/index.html");
const server = http.createServer((req, res) => {
res.setHeader('Content-Type', 'text/html')
res.end(index)
})
res.setHeader("Content-Type", "text/html");
res.end(index);
});
server.listen(8080)
server.listen(8080);
+13 -13
View File
@@ -1,18 +1,18 @@
const WebSocket = require('ws')
const ws = new WebSocket('ws://localhost:3000')
const WebSocket = require("ws");
const ws = new WebSocket("ws://localhost:3000");
ws.on('open', () => {
console.log('Connected')
})
ws.on("open", () => {
console.log("Connected");
});
ws.on('close', () => {
console.log('Disconnected')
})
ws.on("close", () => {
console.log("Disconnected");
});
ws.on('message', (message) => {
console.log('Received:', message)
})
ws.on("message", (message) => {
console.log("Received:", message);
});
setInterval(() => {
ws.send("Hello")
}, 3000)
ws.send("Hello");
}, 3000);
+21 -21
View File
@@ -1,32 +1,32 @@
<h1>Communicating with WebSockets</h1>
<input id="msg"><button id="send">Send</button>
<input id="msg" /><button id="send">Send</button>
<div id="output"></div>
<script>
const ws = new WebSocket('ws://localhost:3000')
const output = document.getElementById('output')
const send = document.getElementById('send')
const ws = new WebSocket("ws://localhost:3000");
const output = document.getElementById("output");
const send = document.getElementById("send");
send.addEventListener('click', () => {
const msg = document.getElementById('msg').value
ws.send(msg)
output.innerHTML += log('Sent', msg)
})
send.addEventListener("click", () => {
const msg = document.getElementById("msg").value;
ws.send(msg);
output.innerHTML += log("Sent", msg);
});
function log(event, msg) {
return '<p>' + event + ': ' + msg + '</p>'
}
function log(event, msg) {
return "<p>" + event + ": " + msg + "</p>";
}
ws.onmessage = function (e) {
output.innerHTML += log('Received', e.data)
}
ws.onmessage = function (e) {
output.innerHTML += log("Received", e.data);
};
ws.onclose = function (e) {
output.innerHTML += log('Disconnected', e.code)
}
ws.onclose = function (e) {
output.innerHTML += log("Disconnected", e.code);
};
ws.onerror = function (e) {
output.innerHTML += log('Error', e.data)
}
ws.onerror = function (e) {
output.innerHTML += log("Error", e.data);
};
</script>
+9 -9
View File
@@ -1,12 +1,12 @@
const WebSocket = require('ws')
const WebSocket = require("ws");
const WebSocketServer = new WebSocket.Server({
port: 3000
})
port: 3000,
});
WebSocketServer.on('connection', (socket) => {
socket.on('message', (msg) => {
console.log('Received:', msg)
if (msg === 'Hello') socket.send('World!')
})
})
WebSocketServer.on("connection", (socket) => {
socket.on("message", (msg) => {
console.log("Received:", msg);
if (msg === "Hello") socket.send("World!");
});
});
@@ -0,0 +1,62 @@
# Logs
logs
*.log
npm-debug.log*
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules
jspm_packages
# Optional npm cache directory
.npm
# Optional REPL history
.node_repl_history
# 0x
profile-*
# mac files
.DS_Store
# vim swap files
*.swp
# webstorm
.idea
# vscode
.vscode
*code-workspace
# clinic
profile*
*clinic*
*flamegraph*
# generated code
examples/typescript-server.js
test/types/index.js
+28
View File
@@ -0,0 +1,28 @@
'use strict'
const path = require('path')
const AutoLoad = require('fastify-autoload')
module.exports = function (fastify, opts, next) {
// Place here your custom code!
// Do not touch the following lines
// This loads all plugins defined in plugins
// those should be support plugins that are reused
// through your application
fastify.register(AutoLoad, {
dir: path.join(__dirname, 'plugins'),
options: Object.assign({}, opts)
})
// This loads all plugins defined in services
// define your routes in one of these
fastify.register(AutoLoad, {
dir: path.join(__dirname, 'services'),
options: Object.assign({}, opts)
})
// Make sure to call next when done
next()
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,26 @@
{
"name": "fastify-generated",
"version": "1.0.0",
"description": "",
"main": "app.js",
"directories": {
"test": "test"
},
"scripts": {
"test": "tap test/**/*.test.js",
"start": "fastify start -l info app.js",
"dev": "fastify start -w -l info -P app.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"fastify": "^2.0.0",
"fastify-plugin": "^1.5.0",
"fastify-autoload": "^1.0.0",
"fastify-cli": "^1.5.0"
},
"devDependencies": {
"tap": "^12.5.3"
}
}
@@ -0,0 +1,16 @@
# Plugins Folder
Plugins define behavior that is common to all the routes in your
application. Authentication, caching, templates, and all the other cross
cutting concerns should be handled by plugins placed in this folder.
Files in this folder are typically defined through the
[`fastify-plugin`](https://github.com/fastify/fastify-plugin) module,
making them non-encapsulated. They can define decorators and set hooks
that will then be used in the rest of your application.
Check out:
* [The hitchhiker's guide to plugins](https://github.com/fastify/fastify/blob/master/docs/Plugins-Guide.md)
* [Fastify decorators](https://www.fastify.io/docs/latest/Decorators/).
* [Fastify lifecycle](https://www.fastify.io/docs/latest/Lifecycle/).
@@ -0,0 +1,21 @@
'use strict'
const fp = require('fastify-plugin')
// the use of fastify-plugin is required to be able
// to export the decorators to the outer scope
module.exports = fp(function (fastify, opts, next) {
fastify.decorate('someSupport', function () {
return 'hugs'
})
next()
})
// If you prefer async/await, use the following
//
// module.exports = fp(async function (fastify, opts) {
// fastify.decorate('someSupport', function () {
// return 'hugs'
// })
// })
@@ -0,0 +1,24 @@
# Services Folder
Services define routes within your application. Fastify provides an
easy path to a microservice architecture, in the future you might want
to independently deploy some of those.
In this folder you should define all the services that define the routes
of your web application.
Each service is a [Fastify
plugin](https://www.fastify.io/docs/latest/Plugins/), it is
encapsulated (it can have its own independent plugins) and it is
typically stored in a file; be careful to group your routes logically,
e.g. all `/users` routes in a `users.js` file. We have added
a `root.js` file for you with a '/' root added.
If a single file become too large, create a folder and add a `index.js` file there:
this file must be a Fastify plugin, and it will be loaded automatically
by the application. You can now add as many files as you want inside that folder.
In this way you can create complex services within a single monolith,
and eventually extract them.
If you need to share functionality between services, place that
functionality into the `plugins` folder, and share it via
[decorators](https://www.fastify.io/docs/latest/Decorators/).
@@ -0,0 +1,17 @@
'use strict'
module.exports = function (fastify, opts, next) {
fastify.get('/example', function (request, reply) {
reply.send('this is an example')
})
next()
}
// If you prefer async/await, use the following
//
// module.exports = async function (fastify, opts) {
// fastify.get('/example', async function (request, reply) {
// return 'this is an example'
// })
// }
@@ -0,0 +1,17 @@
'use strict'
module.exports = function (fastify, opts, next) {
fastify.get('/', function (request, reply) {
reply.send({ root: true })
})
next()
}
// If you prefer async/await, use the following
//
// module.exports = async function (fastify, opts) {
// fastify.get('/', async function (request, reply) {
// return { root: true }
// })
// }
@@ -0,0 +1,34 @@
'use strict'
// This file contains code that we reuse
// between our tests.
const Fastify = require('fastify')
const fp = require('fastify-plugin')
const App = require('../app')
// Fill in this config with all the configurations
// needed for testing the application
function config () {
return {}
}
// automatically build and tear down our instance
function build (t) {
const app = Fastify()
// fastify-plugin ensures that all decorators
// are exposed for testing purposes, this is
// different from the production setup
app.register(fp(App), config())
// tear down our app after we are done
t.tearDown(app.close.bind(app))
return app
}
module.exports = {
config,
build
}
@@ -0,0 +1,26 @@
'use strict'
const { test } = require('tap')
const Fastify = require('fastify')
const Support = require('../../plugins/support')
test('support works standalone', (t) => {
t.plan(2)
const fastify = Fastify()
fastify.register(Support)
fastify.ready((err) => {
t.error(err)
t.equal(fastify.someSupport(), 'hugs')
})
})
// If you prefer async/await, use the following
//
// test('support works standalone', async (t) => {
// const fastify = Fastify()
// fastify.register(Support)
//
// await fastify.ready()
// t.equal(fastify.someSupport(), 'hugs')
// })
@@ -0,0 +1,27 @@
'use strict'
const { test } = require('tap')
const { build } = require('../helper')
test('example is loaded', (t) => {
t.plan(2)
const app = build(t)
app.inject({
url: '/example'
}, (err, res) => {
t.error(err)
t.equal(res.payload, 'this is an example')
})
})
// If you prefer async/await, use the following
//
// test('example is loaded', async (t) => {
// const app = build(t)
//
// const res = await app.inject({
// url: '/example'
// })
// t.equal(res.payload, 'this is an example')
// })
@@ -0,0 +1,27 @@
'use strict'
const { test } = require('tap')
const { build } = require('../helper')
test('default root route', (t) => {
t.plan(2)
const app = build(t)
app.inject({
url: '/'
}, (err, res) => {
t.error(err)
t.deepEqual(JSON.parse(res.payload), { root: true })
})
})
// If you prefer async/await, use the following
//
// test('default root route', async (t) => {
// const app = build(t)
//
// const res = await app.inject({
// url: '/'
// })
// t.deepEqual(JSON.parse(res.payload), { root: true })
// })
@@ -0,0 +1,7 @@
async function routes(fastify) {
fastify.get("/", async (request, reply) => {
return { message: "Hello world!" };
});
}
module.exports = routes;
+1 -3
View File
@@ -2,9 +2,7 @@ const fastify = require("fastify")();
const PORT = process.env.PORT || 3000;
fastify.get("/", async (request, reply) => {
return { message: "Hello world!" };
});
fastify.register(require("./plugins/hello-route"));
const startServer = async () => {
try {
+1
View File
@@ -0,0 +1 @@
This is a static file.
+336
View File
@@ -0,0 +1,336 @@
{
"name": "hapi-app",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@hapi/accept": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/@hapi/accept/-/accept-5.0.1.tgz",
"integrity": "sha512-fMr4d7zLzsAXo28PRRQPXR1o2Wmu+6z+VY1UzDp0iFo13Twj8WePakwXBiqn3E1aAlTpSNzCXdnnQXFhst8h8Q==",
"requires": {
"@hapi/boom": "9.x.x",
"@hapi/hoek": "9.x.x"
}
},
"@hapi/address": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@hapi/address/-/address-4.0.1.tgz",
"integrity": "sha512-0oEP5UiyV4f3d6cBL8F3Z5S7iWSX39Knnl0lY8i+6gfmmIBj44JCBNtcMgwyS+5v7j3VYavNay0NFHDS+UGQcw==",
"requires": {
"@hapi/hoek": "^9.0.0"
}
},
"@hapi/ammo": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/@hapi/ammo/-/ammo-5.0.1.tgz",
"integrity": "sha512-FbCNwcTbnQP4VYYhLNGZmA76xb2aHg9AMPiy18NZyWMG310P5KdFGyA9v2rm5ujrIny77dEEIkMOwl0Xv+fSSA==",
"requires": {
"@hapi/hoek": "9.x.x"
}
},
"@hapi/b64": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@hapi/b64/-/b64-5.0.0.tgz",
"integrity": "sha512-ngu0tSEmrezoiIaNGG6rRvKOUkUuDdf4XTPnONHGYfSGRmDqPZX5oJL6HAdKTo1UQHECbdB4OzhWrfgVppjHUw==",
"requires": {
"@hapi/hoek": "9.x.x"
}
},
"@hapi/boom": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/@hapi/boom/-/boom-9.1.0.tgz",
"integrity": "sha512-4nZmpp4tXbm162LaZT45P7F7sgiem8dwAh2vHWT6XX24dozNjGMg6BvKCRvtCUcmcXqeMIUqWN8Rc5X8yKuROQ==",
"requires": {
"@hapi/hoek": "9.x.x"
}
},
"@hapi/bounce": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@hapi/bounce/-/bounce-2.0.0.tgz",
"integrity": "sha512-JesW92uyzOOyuzJKjoLHM1ThiOvHPOLDHw01YV8yh5nCso7sDwJho1h0Ad2N+E62bZyz46TG3xhAi/78Gsct6A==",
"requires": {
"@hapi/boom": "9.x.x",
"@hapi/hoek": "9.x.x"
}
},
"@hapi/bourne": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-2.0.0.tgz",
"integrity": "sha512-WEezM1FWztfbzqIUbsDzFRVMxSoLy3HugVcux6KDDtTqzPsLE8NDRHfXvev66aH1i2oOKKar3/XDjbvh/OUBdg=="
},
"@hapi/call": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@hapi/call/-/call-8.0.0.tgz",
"integrity": "sha512-4xHIWWqaIDQlVU88XAnomACSoC7iWUfaLfdu2T7I0y+HFFwZUrKKGfwn6ik4kwKsJRMnOliG3UXsF8V/94+Lkg==",
"requires": {
"@hapi/address": "4.x.x",
"@hapi/boom": "9.x.x",
"@hapi/hoek": "9.x.x"
}
},
"@hapi/catbox": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/@hapi/catbox/-/catbox-11.1.0.tgz",
"integrity": "sha512-FDEjfn26RZRyOEPeZdaAL7dRiAK5FOGuwTnTw0gxK30csAlKeOHsEnoIxnLIXx7QOS17eUaOk6+MiweWQM6Keg==",
"requires": {
"@hapi/boom": "9.x.x",
"@hapi/hoek": "9.x.x",
"@hapi/joi": "17.x.x",
"@hapi/podium": "4.x.x"
}
},
"@hapi/catbox-memory": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@hapi/catbox-memory/-/catbox-memory-5.0.0.tgz",
"integrity": "sha512-ByuxVJPHNaXwLzbBv4GdTr6ccpe1nG+AfYt+8ftDWEJY7EWBWzD+Klhy5oPTDGzU26pNUh1e7fcYI1ILZRxAXQ==",
"requires": {
"@hapi/boom": "9.x.x",
"@hapi/hoek": "9.x.x"
}
},
"@hapi/content": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/@hapi/content/-/content-5.0.2.tgz",
"integrity": "sha512-mre4dl1ygd4ZyOH3tiYBrOUBzV7Pu/EOs8VLGf58vtOEECWed8Uuw6B4iR9AN/8uQt42tB04qpVaMyoMQh0oMw==",
"requires": {
"@hapi/boom": "9.x.x"
}
},
"@hapi/cryptiles": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@hapi/cryptiles/-/cryptiles-5.1.0.tgz",
"integrity": "sha512-fo9+d1Ba5/FIoMySfMqPBR/7Pa29J2RsiPrl7bkwo5W5o+AN1dAYQRi4SPrPwwVxVGKjgLOEWrsvt1BonJSfLA==",
"requires": {
"@hapi/boom": "9.x.x"
}
},
"@hapi/file": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@hapi/file/-/file-2.0.0.tgz",
"integrity": "sha512-WSrlgpvEqgPWkI18kkGELEZfXr0bYLtr16iIN4Krh9sRnzBZN6nnWxHFxtsnP684wueEySBbXPDg/WfA9xJdBQ=="
},
"@hapi/formula": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@hapi/formula/-/formula-2.0.0.tgz",
"integrity": "sha512-V87P8fv7PI0LH7LiVi8Lkf3x+KCO7pQozXRssAHNXXL9L1K+uyu4XypLXwxqVDKgyQai6qj3/KteNlrqDx4W5A=="
},
"@hapi/hapi": {
"version": "19.1.1",
"resolved": "https://registry.npmjs.org/@hapi/hapi/-/hapi-19.1.1.tgz",
"integrity": "sha512-rpQzSs0XsHSF7usM4qdJJ0Bcmhs9stWhUW3OiamW33bw4qL8q3uEgUKB9KH8ODmluCAkkXOQ0X0Dh9t94E5VIw==",
"requires": {
"@hapi/accept": "^5.0.1",
"@hapi/ammo": "^5.0.1",
"@hapi/boom": "9.x.x",
"@hapi/bounce": "2.x.x",
"@hapi/call": "8.x.x",
"@hapi/catbox": "11.x.x",
"@hapi/catbox-memory": "5.x.x",
"@hapi/heavy": "7.x.x",
"@hapi/hoek": "9.x.x",
"@hapi/joi": "17.x.x",
"@hapi/mimos": "5.x.x",
"@hapi/podium": "4.x.x",
"@hapi/shot": "5.x.x",
"@hapi/somever": "3.x.x",
"@hapi/statehood": "^7.0.2",
"@hapi/subtext": "^7.0.3",
"@hapi/teamwork": "4.x.x",
"@hapi/topo": "5.x.x"
}
},
"@hapi/heavy": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@hapi/heavy/-/heavy-7.0.0.tgz",
"integrity": "sha512-n/nheUG6zNleWkjY+3fzV3VJIAumUCaa/WoTmurjqlYY5JgC5ZKOpvP7tWi8rXmKZhbcXgjH3fHFoM55LoBT7g==",
"requires": {
"@hapi/boom": "9.x.x",
"@hapi/hoek": "9.x.x",
"@hapi/joi": "17.x.x"
}
},
"@hapi/hoek": {
"version": "9.0.4",
"resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.0.4.tgz",
"integrity": "sha512-EwaJS7RjoXUZ2cXXKZZxZqieGtc7RbvQhUy8FwDoMQtxWVi14tFjeFCYPZAM1mBCpOpiBpyaZbb9NeHc7eGKgw=="
},
"@hapi/inert": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@hapi/inert/-/inert-6.0.1.tgz",
"integrity": "sha512-oLxAmtWni3nH4INU2gcXFnHBw0GhHYF3HR71hAWrPc91dq+iFYGfawfaMbonwGr5DkzFiGe8Ir5sZAt2AqeINA==",
"requires": {
"@hapi/ammo": "5.x.x",
"@hapi/boom": "9.x.x",
"@hapi/bounce": "2.x.x",
"@hapi/hoek": "9.x.x",
"@hapi/joi": "17.x.x",
"lru-cache": "5.x.x"
}
},
"@hapi/iron": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/@hapi/iron/-/iron-6.0.0.tgz",
"integrity": "sha512-zvGvWDufiTGpTJPG1Y/McN8UqWBu0k/xs/7l++HVU535NLHXsHhy54cfEMdW7EjwKfbBfM9Xy25FmTiobb7Hvw==",
"requires": {
"@hapi/b64": "5.x.x",
"@hapi/boom": "9.x.x",
"@hapi/bourne": "2.x.x",
"@hapi/cryptiles": "5.x.x",
"@hapi/hoek": "9.x.x"
}
},
"@hapi/joi": {
"version": "17.1.1",
"resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-17.1.1.tgz",
"integrity": "sha512-p4DKeZAoeZW4g3u7ZeRo+vCDuSDgSvtsB/NpfjXEHTUjSeINAi/RrVOWiVQ1isaoLzMvFEhe8n5065mQq1AdQg==",
"requires": {
"@hapi/address": "^4.0.1",
"@hapi/formula": "^2.0.0",
"@hapi/hoek": "^9.0.0",
"@hapi/pinpoint": "^2.0.0",
"@hapi/topo": "^5.0.0"
}
},
"@hapi/mimos": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@hapi/mimos/-/mimos-5.0.0.tgz",
"integrity": "sha512-EVS6wJYeE73InTlPWt+2e3Izn319iIvffDreci3qDNT+t3lA5ylJ0/SoTaID8e0TPNUkHUSsgJZXEmLHvoYzrA==",
"requires": {
"@hapi/hoek": "9.x.x",
"mime-db": "1.x.x"
}
},
"@hapi/nigel": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@hapi/nigel/-/nigel-4.0.0.tgz",
"integrity": "sha512-Bqs1pjcDnDQo/XGoiCCNHWTFcMzPbz3L4KU04njeFQMzzEmsojMRX7TX+PezQYCMKtHJOtMg0bHxZyMGqYtbSA==",
"requires": {
"@hapi/hoek": "9.x.x",
"@hapi/vise": "4.x.x"
}
},
"@hapi/pez": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/@hapi/pez/-/pez-5.0.2.tgz",
"integrity": "sha512-jr1lAm8mE7J2IBxvDIuDI1qy2aAsoaD2jxOUd/7JRg/Vmrzco8HdKhtz4fKk6KHU6zbbsAp5m5aSWWVTUrag7g==",
"requires": {
"@hapi/b64": "5.x.x",
"@hapi/boom": "9.x.x",
"@hapi/content": "^5.0.2",
"@hapi/hoek": "9.x.x",
"@hapi/nigel": "4.x.x"
}
},
"@hapi/pinpoint": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@hapi/pinpoint/-/pinpoint-2.0.0.tgz",
"integrity": "sha512-vzXR5MY7n4XeIvLpfl3HtE3coZYO4raKXW766R6DZw/6aLqR26iuZ109K7a0NtF2Db0jxqh7xz2AxkUwpUFybw=="
},
"@hapi/podium": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/@hapi/podium/-/podium-4.1.0.tgz",
"integrity": "sha512-k/n0McAu8PvonfQRLyKKUvvdb+Gh/O5iAeIwv535Hpxw9B1qZcrYdZyWtHZ8O5PkA9/b/Kk+BdvtgcxeKMB/2g==",
"requires": {
"@hapi/hoek": "9.x.x",
"@hapi/joi": "17.x.x",
"@hapi/teamwork": "4.x.x"
}
},
"@hapi/shot": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@hapi/shot/-/shot-5.0.0.tgz",
"integrity": "sha512-JXddnJkRh3Xhv9lY1tA+TSIUaoODKbdNIPL/M8WFvFQKOttmGaDeqTW5e8Gf01LtLI7L5DraLMULHjrK1+YNFg==",
"requires": {
"@hapi/hoek": "9.x.x",
"@hapi/joi": "17.x.x"
}
},
"@hapi/somever": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@hapi/somever/-/somever-3.0.0.tgz",
"integrity": "sha512-Upw/kmKotC9iEmK4y047HMYe4LDKsE5NWfjgX41XNKmFvxsQL7OiaCWVhuyyhU0ShDGBfIAnCH8jZr49z/JzZA==",
"requires": {
"@hapi/bounce": "2.x.x",
"@hapi/hoek": "9.x.x"
}
},
"@hapi/statehood": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/@hapi/statehood/-/statehood-7.0.2.tgz",
"integrity": "sha512-+0VNxysQu+UYzkfvAXq3X4aN65TnUwiR7gsq2cQ/4Rq26nCJjHAfrkYReEeshU2hPmJ3m5QuaBzyDqRm8WOpyg==",
"requires": {
"@hapi/boom": "9.x.x",
"@hapi/bounce": "2.x.x",
"@hapi/bourne": "2.x.x",
"@hapi/cryptiles": "5.x.x",
"@hapi/hoek": "9.x.x",
"@hapi/iron": "6.x.x",
"@hapi/joi": "17.x.x"
}
},
"@hapi/subtext": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/@hapi/subtext/-/subtext-7.0.3.tgz",
"integrity": "sha512-CekDizZkDGERJ01C0+TzHlKtqdXZxzSWTOaH6THBrbOHnsr3GY+yiMZC+AfNCypfE17RaIakGIAbpL2Tk1z2+A==",
"requires": {
"@hapi/boom": "9.x.x",
"@hapi/bourne": "2.x.x",
"@hapi/content": "^5.0.2",
"@hapi/file": "2.x.x",
"@hapi/hoek": "9.x.x",
"@hapi/pez": "^5.0.1",
"@hapi/wreck": "17.x.x"
}
},
"@hapi/teamwork": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@hapi/teamwork/-/teamwork-4.0.0.tgz",
"integrity": "sha512-V6xYOrr5aFv/IJqNPneaYCu8vuGTKisamqHVRS3JJnbZr18TrpXdsJOYk9pjPhFti+M2YETPebQLUr820N5NoQ=="
},
"@hapi/topo": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.0.0.tgz",
"integrity": "sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw==",
"requires": {
"@hapi/hoek": "^9.0.0"
}
},
"@hapi/vise": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@hapi/vise/-/vise-4.0.0.tgz",
"integrity": "sha512-eYyLkuUiFZTer59h+SGy7hUm+qE9p+UemePTHLlIWppEd+wExn3Df5jO04bFQTm7nleF5V8CtuYQYb+VFpZ6Sg==",
"requires": {
"@hapi/hoek": "9.x.x"
}
},
"@hapi/wreck": {
"version": "17.0.0",
"resolved": "https://registry.npmjs.org/@hapi/wreck/-/wreck-17.0.0.tgz",
"integrity": "sha512-d8lqCinbKyDByn7GzJDRDbitddhIEydNm44UcAMejfhEH3o4IYvKYq6K8cAqXbilXPuvZc0ErlUOg9SDdgRtMw==",
"requires": {
"@hapi/boom": "9.x.x",
"@hapi/bourne": "2.x.x",
"@hapi/hoek": "9.x.x"
}
},
"lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
"requires": {
"yallist": "^3.0.2"
}
},
"mime-db": {
"version": "1.44.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
"integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg=="
},
"yallist": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
}
}
}
+16
View File
@@ -0,0 +1,16 @@
{
"name": "hapi-app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@hapi/hapi": "^19.1.1",
"@hapi/inert": "^6.0.1"
}
}
+27
View File
@@ -0,0 +1,27 @@
const Hapi = require("@hapi/hapi");
const path = require("path");
const PORT = process.env.PORT || 3000;
const HOSTNAME = process.env.HOSTNAME || "localhost";
const initialize = async () => {
const server = Hapi.server({
port: PORT,
host: HOSTNAME,
});
await server.register(require("@hapi/inert"));
server.route({
method: "GET",
path: "/",
handler: {
file: path.join(__dirname, "files/file.txt"),
},
});
await server.start();
console.log("Server running on %s", server.info.uri);
};
initialize();
+3
View File
@@ -0,0 +1,3 @@
{
"git.ignoreLimitWarning": true
}