Compare commits
2 Commits
ed9eb93013
...
cf2eb88662
Author | SHA1 | Date | |
---|---|---|---|
|
cf2eb88662 | ||
|
9723c825f7 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
.env
|
||||
node_modules/
|
||||
dist/
|
||||
|
13
Dockerfile
Normal file
13
Dockerfile
Normal file
@ -0,0 +1,13 @@
|
||||
FROM 'node:20'
|
||||
|
||||
RUN mkdir -p /usr/src/app/dist
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
COPY package.json /usr/src/app/
|
||||
COPY package-lock.json /usr/src/app/
|
||||
COPY dist /usr/src/app/dist
|
||||
|
||||
RUN npm ci --omit=dev
|
||||
EXPOSE 3003
|
||||
|
||||
CMD [ "npm", "run", "up:prod" ]
|
4
d-script/restart.sh
Normal file
4
d-script/restart.sh
Normal file
@ -0,0 +1,4 @@
|
||||
docker stop bh-mongo;
|
||||
docker volume rm bh-mongo-volume;
|
||||
docker volume create bh-mongo-volume;
|
||||
sh d-script/up-mongo.sh;
|
@ -5,6 +5,6 @@ docker \
|
||||
--name bh-mongo \
|
||||
-e MONGO_INITDB_ROOT_USERNAME=qqq \
|
||||
-e MONGO_INITDB_ROOT_PASSWORD=qqq \
|
||||
-p 27017:27017 \
|
||||
-p 8888:27017 \
|
||||
-v bh-mongo-volume:/data/db \
|
||||
mongo:8.0.3;
|
||||
|
15
docker-compose.yml
Normal file
15
docker-compose.yml
Normal file
@ -0,0 +1,15 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
bh:
|
||||
# build: .
|
||||
image: brojs/todo/bh:$TAG
|
||||
restart: always
|
||||
env_file: ./.env
|
||||
ports:
|
||||
- 3003:3003
|
||||
environment:
|
||||
- PORT=${PORT}
|
||||
- JWT_SECRET=${JWT_SECRET}
|
||||
- MONGO_CONNECT_URL=${MONGO_CONNECT_URL}
|
||||
|
3110
package-lock.json
generated
3110
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -14,16 +14,13 @@
|
||||
"dependencies": {
|
||||
"dotenv": "^16.4.5",
|
||||
"express": "^5.0.1",
|
||||
"express-json-validator-middleware": "^3.0.1",
|
||||
"install": "^0.13.0",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"npm": "^10.9.1",
|
||||
"pbkdf2-password": "^1.2.1",
|
||||
"ts-node": "^10.9.2"
|
||||
"mongoose": "^8.8.3",
|
||||
"pbkdf2-password": "^1.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^5.0.0",
|
||||
"nodemon": "^3.1.7",
|
||||
"ts-node": "^10.9.2",
|
||||
"ts-node-dev": "^2.0.0",
|
||||
"typescript": "^5.7.2"
|
||||
}
|
||||
|
29
src/connect.ts
Normal file
29
src/connect.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import mongoose from "mongoose";
|
||||
|
||||
import ItemListModel from "./model/todo-list";
|
||||
import ItemModel from "./model/todo-item";
|
||||
|
||||
export const connect = async () => {
|
||||
await mongoose.connect(process.env.MONGO_CONNECT_URL!);
|
||||
console.log("Connected to database");
|
||||
|
||||
const lists = await ItemListModel.find();
|
||||
|
||||
console.log(JSON.stringify(lists, null, 4))
|
||||
|
||||
if (lists.length === 0) {
|
||||
await ItemListModel.create({
|
||||
name: "Test List",
|
||||
});
|
||||
|
||||
const item = await ItemModel.create({
|
||||
title: "Test Item",
|
||||
});
|
||||
|
||||
lists.forEach(async (list) => {
|
||||
await (list as unknown as any).addItem(item);
|
||||
})
|
||||
}
|
||||
|
||||
console.log("Database initiated");
|
||||
};
|
17
src/main.ts
17
src/main.ts
@ -1,8 +1,9 @@
|
||||
import express, { json } from 'express';
|
||||
import { handleError } from './utils/errorHandler'
|
||||
import 'dotenv/config'
|
||||
|
||||
import { router } from './routes'
|
||||
import { handleError } from './utils/errorHandler'
|
||||
import { connect } from './connect';
|
||||
|
||||
const app = express();
|
||||
|
||||
@ -13,6 +14,14 @@ app.use(json({ limit: '100kb' }))
|
||||
app.use(router)
|
||||
|
||||
app.use(handleError)
|
||||
app.listen(port, () => {
|
||||
console.log(`App is running on port http://localhost:${port}`);
|
||||
})
|
||||
|
||||
const start = async () => {
|
||||
console.log('starting...')
|
||||
await connect()
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`App is running on port http://localhost:${port}`);
|
||||
})
|
||||
}
|
||||
|
||||
start()
|
||||
|
24
src/model/todo-item.ts
Normal file
24
src/model/todo-item.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { Schema, model } from 'mongoose'
|
||||
|
||||
const schema = new Schema({
|
||||
title: {type: String, required: true },
|
||||
description: String,
|
||||
created: { type: Date, default: () => new Date().toISOString() },
|
||||
done: { type: Boolean, default: false },
|
||||
// createdBy: { type: Schema.Types.ObjectId, required: true, ref: 'User' }
|
||||
deleted: { type: Boolean, default: false }
|
||||
})
|
||||
|
||||
schema.virtual('id').get(function () {
|
||||
return this._id.toHexString()
|
||||
})
|
||||
|
||||
schema.set('toJSON', {
|
||||
virtuals: true,
|
||||
versionKey: false,
|
||||
transform: (doc, ret) => {
|
||||
delete ret._id
|
||||
}
|
||||
})
|
||||
|
||||
export default model('Item', schema)
|
34
src/model/todo-list.ts
Normal file
34
src/model/todo-list.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import { Schema, model } from 'mongoose'
|
||||
|
||||
const schema = new Schema({
|
||||
name: String,
|
||||
items: [{ type: Schema.Types.ObjectId, required: true, ref: 'Item' }],
|
||||
created: { type: Date, default: () => new Date().toISOString() },
|
||||
// createdBy: { type: Schema.Types.ObjectId, required: true, ref: 'User' }
|
||||
deleted: { type: Boolean, default: false }
|
||||
})
|
||||
|
||||
schema.virtual('id').get(function () {
|
||||
return this._id.toHexString()
|
||||
})
|
||||
|
||||
schema.set('toJSON', {
|
||||
virtuals: true,
|
||||
versionKey: false,
|
||||
transform: (doc, ret) => {
|
||||
delete ret._id
|
||||
}
|
||||
})
|
||||
|
||||
schema.method('addItem', async function(item) {
|
||||
this.items.push(item._id)
|
||||
return await this.save()
|
||||
})
|
||||
|
||||
schema.method('removeItem', async function(item) {
|
||||
this.items = this.items.filter(i => i !== item._id)
|
||||
return await this.save()
|
||||
})
|
||||
|
||||
|
||||
export default model('TodoList', schema)
|
@ -3,9 +3,11 @@ import { Router } from "express";
|
||||
import pkg from '../../package.json'
|
||||
|
||||
import { router as usersRouter } from './users'
|
||||
import { router as todoRouter } from './todo'
|
||||
|
||||
export const router = Router();
|
||||
|
||||
router.get('/healthcheck', (req, res) => void res.send({ ok: true, version: pkg.version }));
|
||||
|
||||
router.use('/users', usersRouter)
|
||||
router.use('/users', usersRouter)
|
||||
router.use('/todo', todoRouter)
|
||||
|
66
src/routes/todo/index.ts
Normal file
66
src/routes/todo/index.ts
Normal file
@ -0,0 +1,66 @@
|
||||
import { Router } from "express";
|
||||
import ListsModel from '../../model/todo-list';
|
||||
import ItemModel from '../../model/todo-item';
|
||||
|
||||
export const router = Router();
|
||||
|
||||
router.get('/lists', async (req, res) => {
|
||||
const lists = await ListsModel.find({});
|
||||
|
||||
res.json(lists);
|
||||
})
|
||||
|
||||
router.post('/list', async (req, res) => {
|
||||
const { name } = req.body
|
||||
const list = await ListsModel.create({
|
||||
name
|
||||
});
|
||||
|
||||
res.json(list);
|
||||
})
|
||||
|
||||
router.delete('/item/:itemId', async (req, res) => {
|
||||
const { itemId } = req.params;
|
||||
|
||||
const item = await ItemModel.findById(itemId);
|
||||
|
||||
if (!item) throw new Error('Item not found');
|
||||
|
||||
await ItemModel.findByIdAndDelete(itemId);
|
||||
|
||||
res.send(item);
|
||||
})
|
||||
|
||||
router.get('/list/:listId', async (req, res) => {
|
||||
const { listId } = req.params;
|
||||
|
||||
const list = await ListsModel
|
||||
.findById(listId)
|
||||
.populate('items')
|
||||
.exec();
|
||||
|
||||
if (!list) throw new Error('List not found');
|
||||
|
||||
res.json(list);
|
||||
})
|
||||
|
||||
router.post('/:listId/item', async (req, res) => {
|
||||
const { listId } = req.params
|
||||
const { title, description = '' } = req.body
|
||||
|
||||
const list = await ListsModel.findById(listId);
|
||||
|
||||
if (!list) {
|
||||
throw new Error('List not found');
|
||||
}
|
||||
|
||||
const item = await ItemModel.create({
|
||||
title,
|
||||
description
|
||||
});
|
||||
|
||||
await (list as any).addItem(item);
|
||||
|
||||
res.send(item)
|
||||
})
|
||||
|
@ -1,7 +1,5 @@
|
||||
import { Router } from "express";
|
||||
import { Validator } from "express-json-validator-middleware";
|
||||
import bkfd2Password from "pbkdf2-password";
|
||||
import { promisify } from 'node:util'
|
||||
|
||||
import jwt from 'jsonwebtoken'
|
||||
|
||||
@ -12,8 +10,6 @@ const hasher = bkfd2Password();
|
||||
|
||||
export const router = Router();
|
||||
|
||||
const { validate } = new Validator({});
|
||||
|
||||
const user = {
|
||||
type: "object",
|
||||
required: ["name"],
|
||||
|
Loading…
Reference in New Issue
Block a user