part 12 done

This commit is contained in:
QkoSad
2024-09-30 15:32:50 +03:00
parent 0a7a469d56
commit 33a5afd017
426 changed files with 46304 additions and 5 deletions
@@ -0,0 +1,61 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# 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
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Typescript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
# next.js build output
.next
@@ -0,0 +1,15 @@
FROM node:20
WORKDIR /usr/src/app
COPY --chown=node:node . .
RUN npm ci
ENV DEBUG=express:*
USER node
CMD npm start
@@ -0,0 +1,19 @@
# Express application
Install dependencies with `npm install`
Run with `npm start`
Or in development mode with `npm run dev`
# Visit counter
When running the server, visit http://localhost:3000 to see visit counter, or give environment variable `PORT` to change the port.
# MongoDB
The application has /todos crud which requires a MongoDB. Pass connection url with env `MONGO_URL`
# Redis
Pass connection url with env `REDIS_URL`
@@ -0,0 +1,20 @@
const express = require("express");
const logger = require("morgan");
const cors = require("cors");
const indexRouter = require("./routes/index");
const todosRouter = require("./routes/todos");
const statisticsRouter = require("./routes/statistics");
const app = express();
app.use(cors());
app.use(logger("dev"));
app.use(express.json());
app.use("/", indexRouter);
app.use("/todos", todosRouter);
app.use("/statistics", statisticsRouter);
module.exports = app;
@@ -0,0 +1,89 @@
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('todo-express-backend:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
@@ -0,0 +1,15 @@
FROM node:20
WORKDIR /usr/src/app
COPY --chown=node:node . .
RUN npm i
ENV DEBUG=express:*
USER node
CMD ["npm", "run", "dev", "--", "--host"]
@@ -0,0 +1,38 @@
services:
server:
image: todo-backend-dev
build:
context: .
dockerfile: dev.Dockerfile
volumes:
- ./:/usr/src/app
ports:
- 3000:3000
environment:
REDIS_URL: "redis://redis:6379"
MONGO_URL: "mongodb://the_username:the_password@mongo:27017/the_database"
mongo:
image: mongo
ports:
- 3456:27017
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: example
MONGO_INITDB_DATABASE: the_database
volumes:
- ./mongo/mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js
- mongo_data:/data/db
redis:
image: redis
ports:
- 3457:6379
# Everything else
command: ['redis-server', '--appendonly', 'yes'] # Overwrite the CMD
volumes: # Declare the volume
- ./redis_data:/data
volumes:
mongo_data:
@@ -0,0 +1,6 @@
services:
app: # The name of the service, can be anything
image: todo-backend # Declares which image to use
build: . # Declares where to build if image is not found
ports: # Declares the ports to publish
- 3000:3000
@@ -0,0 +1,10 @@
const mongoose = require('mongoose')
const Todo = require('./models/Todo')
const { MONGO_URL } = require('../util/config')
if (MONGO_URL && !mongoose.connection.readyState) mongoose.connect(MONGO_URL, { useNewUrlParser: true, useUnifiedTopology: true })
module.exports = {
Todo
}
@@ -0,0 +1,8 @@
const mongoose = require('mongoose')
const todoSchema = new mongoose.Schema({
text: String,
done: Boolean
})
module.exports = mongoose.model('Todo', todoSchema)
@@ -0,0 +1,15 @@
db.createUser({
user: 'the_username',
pwd: 'the_password',
roles: [
{
role: 'dbOwner',
db: 'the_database',
},
],
});
db.createCollection('todos');
db.todos.insert({ text: 'Write code', done: true });
db.todos.insert({ text: 'Learn about containers', done: false });
@@ -0,0 +1,2 @@
WiredTiger
WiredTiger 11.2.0: (November 10, 2022)
@@ -0,0 +1 @@
WiredTiger lock file
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,20 @@
{
"name": "todo-express-backend",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www",
"dev": "nodemon ./bin/www"
},
"dependencies": {
"cors": "^2.8.5",
"debug": "~2.6.9",
"express": "~4.16.1",
"mongoose": "^5.13.2",
"morgan": "~1.9.1",
"redis": "^3.1.2"
},
"devDependencies": {
"nodemon": "^2.0.12"
}
}
@@ -0,0 +1,27 @@
const redis = require('redis')
const { promisify } = require('util')
const { REDIS_URL } = require('../util/config')
let getAsync
let setAsync
if (!REDIS_URL) {
const redisIsDisabled = () => {
console.log('No REDIS_URL set, Redis is disabled')
return null
}
getAsync = redisIsDisabled
setAsync = redisIsDisabled
} else {
const client = redis.createClient({
url: REDIS_URL
})
getAsync = promisify(client.get).bind(client)
setAsync = promisify(client.set).bind(client)
}
module.exports = {
getAsync,
setAsync
}
@@ -0,0 +1,36 @@
*2
$6
SELECT
$1
0
*3
$3
set
$11
added_todos
$1
1
*2
$6
SELECT
$1
0
*3
$3
set
$11
added_todos
$1
2
*2
$6
SELECT
$1
0
*3
$3
set
$11
added_todos
$1
3
@@ -0,0 +1,2 @@
file appendonly.aof.1.base.rdb seq 1 type b
file appendonly.aof.1.incr.aof seq 1 type i
@@ -0,0 +1,19 @@
const express = require("express");
const router = express.Router();
const redis = require("../redis");
const configs = require("../util/config");
let visits = 0;
/* GET index data. */
router.get("/", async (req, res) => {
visits++;
res.send({
...configs,
visits,
});
});
module.exports = router;
@@ -0,0 +1,11 @@
const express = require("express");
const router = express.Router();
const { getAsync } = require("../redis/index");
/* GET todos listing. */
router.get("/", async (_, res) => {
const statistics = await getAsync("added_todos");
res.send(statistics);
});
module.exports = router;
@@ -0,0 +1,54 @@
const express = require("express");
const { Todo } = require("../mongo");
const router = express.Router();
const { getAsync, setAsync } = require("../redis/index");
/* GET todos listing. */
router.get("/", async (_, res) => {
const todos = await Todo.find({});
res.send(todos);
});
/* POST todo to listing. */
router.post("/", async (req, res) => {
const todo = await Todo.create({
text: req.body.text,
done: false,
});
const todoCounter = await getAsync("added_todos");
setAsync("added_todos", Number(todoCounter) + 1);
res.send(todo);
});
const singleRouter = express.Router();
const findByIdMiddleware = async (req, res, next) => {
const { id } = req.params;
req.todo = await Todo.findById(id);
if (!req.todo) return res.sendStatus(404);
next();
};
/* DELETE todo. */
singleRouter.delete("/", async (req, res) => {
await req.todo.delete();
res.sendStatus(200);
});
/* GET todo. */
singleRouter.get("/", async (req, res) => {
res.send(req.todo);
});
/* PUT todo. */
singleRouter.put("/", async (req, res) => {
const todo = await Todo.findByIdAndUpdate(req.todo._id, {
done: true,
});
res.send(todo);
});
router.use("/:id", findByIdMiddleware, singleRouter);
module.exports = router;
@@ -0,0 +1,7 @@
const MONGO_URL = process.env.MONGO_URL || undefined
const REDIS_URL = process.env.REDIS_URL || undefined
module.exports = {
MONGO_URL,//: 'mongodb://the_username:the_password@localhost:3456/the_database',
REDIS_URL//: '//localhost:6378'
}