Merge pull request #134 from RedHatTraining/gbianco/todo-backend-rewrite
new todo-backend
This commit is contained in:
commit
a22ab5004d
18 changed files with 7809 additions and 342 deletions
2
todo-backend/.gitignore
vendored
Normal file
2
todo-backend/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
node_modules
|
||||
dist
|
||||
27
todo-backend/Dockerfile
Normal file
27
todo-backend/Dockerfile
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# https://github.com/sclorg/s2i-nodejs-container
|
||||
FROM registry.access.redhat.com/ubi8/nodejs-14
|
||||
|
||||
LABEL version="1.0"
|
||||
LABEL description="To Do List application backend"
|
||||
LABEL creationDate="2017-12-25"
|
||||
LABEL updatedDate="2021-05-19"
|
||||
|
||||
USER 0
|
||||
|
||||
COPY . /opt/app-root/src
|
||||
|
||||
RUN cd /opt/app-root/src && \
|
||||
npm install && \
|
||||
npm run build
|
||||
|
||||
ENV DATABASE_SVC=192.168.0.10
|
||||
ENV DATABASE_PORT=3306
|
||||
ENV DATABASE_PASSWORD=secret-pass
|
||||
ENV DATABASE_INIT=true
|
||||
ENV PORT=3000
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
USER 1001
|
||||
|
||||
CMD npm start
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
var restify = require('restify');
|
||||
|
||||
var controller = require('./controllers/items');
|
||||
var serverinfo = require('./controllers/serverinfo');
|
||||
|
||||
var db = require('./models/db');
|
||||
var model = require('./models/items');
|
||||
|
||||
model.connect(db.params, function(err) {
|
||||
if (err) throw err;
|
||||
});
|
||||
|
||||
var server = restify.createServer()
|
||||
.use(restify.fullResponse())
|
||||
.use(restify.queryParser())
|
||||
.use(restify.bodyParser())
|
||||
.use(restify.CORS());;
|
||||
|
||||
controller.context(server, '/todo/api', model);
|
||||
serverinfo.context(server, '/todo/api');
|
||||
|
||||
var port = process.env.PORT || 8080;
|
||||
server.listen(port, function (err) {
|
||||
if (err)
|
||||
console.error(err);
|
||||
else
|
||||
console.log('App is ready at : ' + port);
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
process.on('uncaughtException', function (err) {
|
||||
console.error(JSON.parse(JSON.stringify(err, ['stack', 'message', 'inner'], 2)))
|
||||
});
|
||||
*/
|
||||
|
||||
35
todo-backend/build.ts
Normal file
35
todo-backend/build.ts
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
import fs from "fs-extra";
|
||||
import childProcess from "child_process";
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
// Remove current build
|
||||
await remove("./dist/");
|
||||
// Copy back-end files
|
||||
await exec("tsc --build tsconfig.prod.json", "./");
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
})();
|
||||
|
||||
function remove(loc: string): Promise<void> {
|
||||
return new Promise((res, rej) => {
|
||||
return fs.remove(loc, (err) => {
|
||||
return !!err ? rej(err) : res();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function exec(cmd: string, loc: string): Promise<void> {
|
||||
return new Promise((res, rej) => {
|
||||
return childProcess.exec(cmd, { cwd: loc }, (err, stdout, stderr) => {
|
||||
if (!!stdout) {
|
||||
console.log(stdout);
|
||||
}
|
||||
if (!!stderr) {
|
||||
console.warn(stderr);
|
||||
}
|
||||
return !!err ? rej(err) : res();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -1,131 +0,0 @@
|
|||
|
||||
var model = undefined;
|
||||
|
||||
exports.context = function(server, path, itemsModel) {
|
||||
if (!server)
|
||||
done('has to provide a restify server object');
|
||||
|
||||
var context = "/items";
|
||||
if (path)
|
||||
context = path + context;
|
||||
|
||||
server.get(context + '/', this.list);
|
||||
server.get(context + '/:id', this.read);
|
||||
server.get(context + '-count', this.count);
|
||||
server.post(context + '/', this.save);
|
||||
server.del(context + '/:id', this.destroy);
|
||||
|
||||
model = itemsModel;
|
||||
};
|
||||
|
||||
exports.list = function(req, res, next) {
|
||||
var page_no = req.query.page || 1;
|
||||
var sortField = req.query.sortFields || "id";
|
||||
var sortDirection = req.query.sortDirections || "asc";
|
||||
|
||||
model.listAll(page_no, sortField, sortDirection, function(err, items) {
|
||||
if (err) {
|
||||
res.send(err);
|
||||
}
|
||||
else {
|
||||
if (items) {
|
||||
model.countAll(function(err, n) {
|
||||
if (err) {
|
||||
res.send(err);
|
||||
}
|
||||
else {
|
||||
if (n) {
|
||||
var page = {
|
||||
"currentPage" : page_no,
|
||||
"list" : items,
|
||||
"pageSize" : 10,
|
||||
"sortDirections" : sortDirection,
|
||||
"sortFields" : sortField,
|
||||
"totalResults" : n
|
||||
};
|
||||
res.json(page);
|
||||
next();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
res.send(err);
|
||||
}
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
exports.read = function(req, res, next) {
|
||||
var key = req.params.id;
|
||||
model.read(key, function(err, item) {
|
||||
if (err) {
|
||||
res.send(err);
|
||||
}
|
||||
else {
|
||||
if (item) {
|
||||
res.json(item);
|
||||
next();
|
||||
}
|
||||
else {
|
||||
res.send(err);
|
||||
}
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
exports.count = function(req, res, next) {
|
||||
model.countAll(function(err, n) {
|
||||
if (err) {
|
||||
res.send(err);
|
||||
}
|
||||
else {
|
||||
var page = {
|
||||
count: n
|
||||
};
|
||||
res.json(page)
|
||||
next();
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
exports.save = function(req, res, next) {
|
||||
if (req.params.id) {
|
||||
model.update(req.params.id, req.params.description, req.params.done, function(err, item) {
|
||||
if (err) {
|
||||
res.send(err);
|
||||
}
|
||||
else {
|
||||
res.json(item);
|
||||
next();
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
model.create(req.params.description, req.params.done, function(err, item) {
|
||||
if (err) {
|
||||
res.send(err);
|
||||
}
|
||||
else {
|
||||
res.json(item);
|
||||
next();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
exports.destroy = function(req, res, next) {
|
||||
if (req.params.id) {
|
||||
model.destroy(req.params.id, function(err, item) {
|
||||
if (err) {
|
||||
res.send(err);
|
||||
}
|
||||
else {
|
||||
res.json(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
var os = require('os');
|
||||
|
||||
exports.context = function(server, path) {
|
||||
if (!server)
|
||||
done('has to provide a restify server object');
|
||||
|
||||
server.get(path + '/host', this.serverInfo);
|
||||
};
|
||||
|
||||
exports.serverInfo = function(req, res, next) {
|
||||
var address;
|
||||
var ifaces = os.networkInterfaces();
|
||||
|
||||
for (var dev in ifaces) {
|
||||
var iface = ifaces[dev].filter(function(details) {
|
||||
return details.family === 'IPv4' && details.internal === false;
|
||||
});
|
||||
if (iface.length > 0)
|
||||
address = iface[0].address;
|
||||
}
|
||||
|
||||
var reply = {
|
||||
ip: address,
|
||||
hostname: os.hostname()
|
||||
};
|
||||
res.json(reply);
|
||||
next();
|
||||
};
|
||||
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
|
||||
module.exports.params = {
|
||||
dbname: process.env.DATABASE_NAME,
|
||||
username: process.env.DATABASE_USER,
|
||||
password: process.env.DATABASE_PASSWORD,
|
||||
params: {
|
||||
host: process.env.DATABASE_SVC,
|
||||
dialect: 'mysql',
|
||||
}
|
||||
};
|
||||
|
|
@ -1,127 +0,0 @@
|
|||
var Sequelize = require("sequelize");
|
||||
|
||||
var Item = undefined;
|
||||
|
||||
module.exports.connect = function(params, callback) {
|
||||
var sequlz = new Sequelize(
|
||||
params.dbname, params.username, params.password,
|
||||
params.params);
|
||||
Item = sequlz.define('Item', {
|
||||
id: { type: Sequelize.BIGINT,
|
||||
primaryKey: true, unique: true, allowNull: false,
|
||||
autoIncrement: true },
|
||||
description: { type: Sequelize.STRING,
|
||||
allowNull: true },
|
||||
done: { type: Sequelize.BOOLEAN,
|
||||
allowNull: true }
|
||||
}, {
|
||||
timestamps: false,
|
||||
freezeTableName: true
|
||||
});
|
||||
|
||||
if (process.env.DATABASE_INIT == 'true') {
|
||||
Item.sync({ force: true }).then(function() {
|
||||
callback();
|
||||
}).catch(function(err) {
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
exports.disconnect = function(callback) {
|
||||
//XXX shouln'd to something to close or release the db connection?
|
||||
callback();
|
||||
}
|
||||
|
||||
exports.create = function(description, done, callback) {
|
||||
Item.create({
|
||||
//id: id,
|
||||
description: description,
|
||||
done: (done) ? true : false
|
||||
}).then(function(item) {
|
||||
callback(null, item);
|
||||
}).catch(function(err) {
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
|
||||
exports.update = function(key, description, done, callback) {
|
||||
Item.find({ where:{ id: key } }).then(function(item) {
|
||||
if (!item) {
|
||||
callback(new Error("Nothing found for key " + key));
|
||||
}
|
||||
else {
|
||||
item.updateAttributes({
|
||||
description: description,
|
||||
done: (done) ? true : false
|
||||
}).then(function() {
|
||||
callback(null, item);
|
||||
}).error(function(err) {
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
}).catch(function(err) {
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
exports.read = function(key, callback) {
|
||||
Item.find({ where:{ id: key } }).then(function(item) {
|
||||
if (!item) {
|
||||
callback(new Error("Nothing found for key " + key));
|
||||
}
|
||||
else {
|
||||
//XXX why recreating the item object?
|
||||
callback(null, {
|
||||
id: item.id,
|
||||
description: item.description,
|
||||
done: item.done
|
||||
});
|
||||
}
|
||||
}).catch(function(err) {
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
|
||||
exports.destroy = function(key, callback) {
|
||||
Item.find({ where:{ id: key } }).then(function(item) {
|
||||
if (!item) {
|
||||
callback(new Error("Nothing found for " + key));
|
||||
}
|
||||
else {
|
||||
item.destroy().then(function() {
|
||||
callback(null, item);
|
||||
}).error(function(err) {
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
}).catch(function(err) {
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
|
||||
exports.countAll = function(callback) {
|
||||
Item.findAll({
|
||||
attributes: [[Sequelize.fn('COUNT', Sequelize.col('id')), 'no_items']]
|
||||
}).then(function(n) {
|
||||
callback(null, n[0].get('no_items'));
|
||||
}).catch(function(err) {
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
|
||||
exports.listAll = function(page, sortField, sortDirection, callback) {
|
||||
Item.findAll({ offset: 10 * (page - 1), limit: 10, order: [[sortField, sortDirection]] }).then(function(items) {
|
||||
var theitems = [];
|
||||
items.forEach(function(item) {
|
||||
//XXX why recreating the item objects for theitems?
|
||||
theitems.push({
|
||||
id: item.id, description: item.description, done: item.done });
|
||||
});
|
||||
callback(null, theitems);
|
||||
}).catch(function(err) {
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
|
||||
7461
todo-backend/package-lock.json
generated
Normal file
7461
todo-backend/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1,16 +1,92 @@
|
|||
{
|
||||
"name": "todo-backend",
|
||||
"description": "multi-container version of the todoapp",
|
||||
"version": "0.0.2",
|
||||
"private": true,
|
||||
"author": "Red Hat Training",
|
||||
"license": "ASL",
|
||||
"version": "2.0.0",
|
||||
"scripts": {
|
||||
"start": "node app.js"
|
||||
"build": "./node_modules/.bin/ts-node build.ts",
|
||||
"lint": "eslint . --ext .ts",
|
||||
"start": "node -r module-alias/register ./dist",
|
||||
"start:dev": "nodemon"
|
||||
},
|
||||
"nodemonConfig": {
|
||||
"watch": [
|
||||
"src"
|
||||
],
|
||||
"ext": "ts, html",
|
||||
"ignore": [
|
||||
"src/public"
|
||||
],
|
||||
"exec": "./node_modules/.bin/ts-node -r tsconfig-paths/register ./src"
|
||||
},
|
||||
"_moduleAliases": {
|
||||
"@daos": "dist/daos",
|
||||
"@entities": "dist/entities",
|
||||
"@shared": "dist/shared",
|
||||
"@server": "dist/Server"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"plugins": [
|
||||
"@typescript-eslint"
|
||||
],
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:@typescript-eslint/recommended-requiring-type-checking"
|
||||
],
|
||||
"parserOptions": {
|
||||
"project": "./tsconfig.json"
|
||||
},
|
||||
"rules": {
|
||||
"max-len": [
|
||||
"error",
|
||||
{
|
||||
"code": 100
|
||||
}
|
||||
],
|
||||
"no-extra-boolean-cast": 0,
|
||||
"@typescript-eslint/restrict-plus-operands": 0,
|
||||
"@typescript-eslint/explicit-module-boundary-types": 0,
|
||||
"@typescript-eslint/no-explicit-any": 0,
|
||||
"@typescript-eslint/no-floating-promises": 0,
|
||||
"@typescript-eslint/no-unsafe-member-access": 0,
|
||||
"@typescript-eslint/no-unsafe-assignment": 0
|
||||
}
|
||||
},
|
||||
"eslintIgnore": [
|
||||
"src/public/",
|
||||
"build.ts"
|
||||
],
|
||||
"dependencies": {
|
||||
"restify": "4.3.0",
|
||||
"sequelize": "3.14.2",
|
||||
"mysql": "2.9.0"
|
||||
"command-line-args": "^5.1.1",
|
||||
"cookie-parser": "^1.4.5",
|
||||
"cors": "^2.8.5",
|
||||
"express": "^4.17.1",
|
||||
"express-async-errors": "^3.1.1",
|
||||
"jsonfile": "^6.1.0",
|
||||
"module-alias": "^2.2.2",
|
||||
"mysql2": "^2.2.5",
|
||||
"sequelize": "^6.6.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/command-line-args": "^5.0.0",
|
||||
"@types/cookie-parser": "^1.4.2",
|
||||
"@types/cors": "^2.8.10",
|
||||
"@types/express": "^4.17.11",
|
||||
"@types/find": "^0.2.1",
|
||||
"@types/fs-extra": "^9.0.11",
|
||||
"@types/jasmine": "^3.6.10",
|
||||
"@types/jsonfile": "^6.0.0",
|
||||
"@types/node": "^15.0.1",
|
||||
"@types/supertest": "^2.0.11",
|
||||
"@typescript-eslint/eslint-plugin": "^4.22.0",
|
||||
"@typescript-eslint/parser": "^4.22.0",
|
||||
"eslint": "^7.25.0",
|
||||
"find": "^0.3.0",
|
||||
"fs-extra": "^9.1.0",
|
||||
"nodemon": "^2.0.7",
|
||||
"supertest": "^6.1.3",
|
||||
"ts-node": "^9.1.1",
|
||||
"tsconfig-paths": "^3.9.0",
|
||||
"typescript": "^4.2.4"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
43
todo-backend/src/Server.ts
Normal file
43
todo-backend/src/Server.ts
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
import cookieParser from "cookie-parser";
|
||||
import express, { Request, Response } from "express";
|
||||
import "express-async-errors";
|
||||
import cors from "cors";
|
||||
import { Sequelize } from "sequelize";
|
||||
|
||||
import BaseRouter from "./routes";
|
||||
import { dbConnectionOptions } from "./entities/db";
|
||||
|
||||
const app = express();
|
||||
|
||||
// DO NOT USE in production as this allows any site to use our backend
|
||||
// you will need to configure cors separately for your application
|
||||
app.use(cors());
|
||||
|
||||
app.use(express.json());
|
||||
app.use(express.urlencoded({ extended: true }));
|
||||
app.use(cookieParser());
|
||||
|
||||
const sequelize = new Sequelize(dbConnectionOptions);
|
||||
sequelize
|
||||
.authenticate()
|
||||
.then(() => {
|
||||
console.log("Connection has been established successfully.");
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("Unable to connect to the database:", err);
|
||||
});
|
||||
|
||||
// Add APIs
|
||||
app.use("/api", BaseRouter);
|
||||
|
||||
// Print API errors
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
app.use((err: Error, req: Request, res: Response) => {
|
||||
console.error(err, true);
|
||||
return res.status(500).json({
|
||||
error: err.message,
|
||||
});
|
||||
});
|
||||
|
||||
// Export express instance
|
||||
export default app;
|
||||
54
todo-backend/src/entities/Item.ts
Normal file
54
todo-backend/src/entities/Item.ts
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
import { Sequelize, DataTypes, Model, Optional } from "sequelize";
|
||||
import { dbConnectionOptions } from "./db";
|
||||
|
||||
export interface TodoItemAttributes {
|
||||
id: number;
|
||||
description: string;
|
||||
done: boolean;
|
||||
}
|
||||
|
||||
type TodoItemCreationAttributes = Optional<TodoItemAttributes, "id">;
|
||||
|
||||
interface TodoItemInstance
|
||||
extends Model<TodoItemAttributes, TodoItemCreationAttributes> {
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
const sequelize = new Sequelize(dbConnectionOptions);
|
||||
|
||||
export const TodoItem = sequelize.define<TodoItemInstance>(
|
||||
"TodoItem",
|
||||
{
|
||||
id: {
|
||||
type: DataTypes.BIGINT,
|
||||
primaryKey: true,
|
||||
unique: true,
|
||||
allowNull: false,
|
||||
autoIncrement: true,
|
||||
},
|
||||
description: { type: DataTypes.STRING, allowNull: true },
|
||||
done: { type: DataTypes.BOOLEAN, allowNull: true },
|
||||
},
|
||||
{
|
||||
timestamps: false,
|
||||
freezeTableName: true,
|
||||
}
|
||||
);
|
||||
|
||||
// (re-)creates table (NOT database)
|
||||
if (process.env.DATABASE_INIT === "true") {
|
||||
TodoItem.sync({ force: true });
|
||||
}
|
||||
|
||||
export async function createTodoItem(todoItem: TodoItemCreationAttributes) {
|
||||
return TodoItem.create(todoItem).then((item) => item.get());
|
||||
}
|
||||
|
||||
export async function deleteTodoItem(id: number) {
|
||||
return TodoItem.destroy({ where: { id } });
|
||||
}
|
||||
|
||||
export async function listAllTodoItems(): Promise<TodoItemAttributes[]> {
|
||||
return TodoItem.findAll({}).then((items) => items.map((i) => i.get()));
|
||||
}
|
||||
18
todo-backend/src/entities/db.ts
Normal file
18
todo-backend/src/entities/db.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import { Options } from "sequelize";
|
||||
|
||||
const {
|
||||
DATABASE_NAME,
|
||||
DATABASE_USER,
|
||||
DATABASE_PASSWORD,
|
||||
DATABASE_SVC,
|
||||
DATABASE_PORT,
|
||||
} = process.env;
|
||||
|
||||
export const dbConnectionOptions: Options = {
|
||||
database: DATABASE_NAME ?? "todo",
|
||||
username: DATABASE_USER ?? "root",
|
||||
password: DATABASE_PASSWORD ?? "",
|
||||
host: DATABASE_SVC ?? "localhost",
|
||||
port: Number(DATABASE_PORT) ?? 3306,
|
||||
dialect: "mysql",
|
||||
};
|
||||
7
todo-backend/src/index.ts
Normal file
7
todo-backend/src/index.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import app from "@server";
|
||||
|
||||
// Start the server
|
||||
const port = Number(process.env.PORT || 8080);
|
||||
app.listen(port, () => {
|
||||
console.log("Express server started on port: " + port);
|
||||
});
|
||||
27
todo-backend/src/routes/Items.ts
Normal file
27
todo-backend/src/routes/Items.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import {
|
||||
createTodoItem,
|
||||
deleteTodoItem,
|
||||
listAllTodoItems,
|
||||
} from "@entities/Item";
|
||||
import { Request, Response } from "express";
|
||||
|
||||
export function handleCreate(req: Request, res: Response) {
|
||||
const { description, done } = req.body;
|
||||
|
||||
// NOTE production applications should use a validation framework
|
||||
if (typeof description !== "string" || typeof done !== "boolean") {
|
||||
res
|
||||
.status(400)
|
||||
.send("required parameters were either missing or the wrong type");
|
||||
} else {
|
||||
createTodoItem({ description, done }).then((item) => res.json(item));
|
||||
}
|
||||
}
|
||||
|
||||
export function handleReadAll(req: Request, res: Response) {
|
||||
listAllTodoItems().then((items) => res.json(items));
|
||||
}
|
||||
|
||||
export function handleDelete(req: Request, res: Response) {
|
||||
deleteTodoItem(Number(req.params.id)).then(() => res.json({}));
|
||||
}
|
||||
13
todo-backend/src/routes/index.ts
Normal file
13
todo-backend/src/routes/index.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import { Router } from "express";
|
||||
import { handleCreate, handleReadAll, handleDelete } from "./Items";
|
||||
|
||||
// Item routes
|
||||
const itemRouter = Router();
|
||||
itemRouter.get("/", handleReadAll);
|
||||
itemRouter.post("/", handleCreate);
|
||||
itemRouter.delete("/:id", handleDelete);
|
||||
|
||||
// Export the base-router
|
||||
const baseRouter = Router();
|
||||
baseRouter.use("/items", itemRouter);
|
||||
export default baseRouter;
|
||||
26
todo-backend/tsconfig.json
Normal file
26
todo-backend/tsconfig.json
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es6",
|
||||
"module": "commonjs",
|
||||
"checkJs": true,
|
||||
"outDir": "dist",
|
||||
"removeComments": true,
|
||||
"strict": true,
|
||||
"noImplicitAny": true,
|
||||
"alwaysStrict": true,
|
||||
"moduleResolution": "node",
|
||||
"baseUrl": "./",
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"paths": {
|
||||
"@daos/*": ["src/daos/*"],
|
||||
"@entities/*": ["src/entities/*"],
|
||||
"@shared/*": ["src/shared/*"],
|
||||
"@server": ["src/Server"]
|
||||
}
|
||||
},
|
||||
"include": ["src/**/*.ts", "spec/**/*.ts"],
|
||||
"exclude": ["src/public/"]
|
||||
}
|
||||
|
||||
11
todo-backend/tsconfig.prod.json
Normal file
11
todo-backend/tsconfig.prod.json
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"sourceMap": false
|
||||
},
|
||||
"exclude": [
|
||||
"spec",
|
||||
"src/**/*.mock.ts",
|
||||
"src/public/"
|
||||
]
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue