From ad3d13a2feab477e145443da46b66858f91a4657 Mon Sep 17 00:00:00 2001 From: Constantin Metz Date: Wed, 10 Mar 2021 17:48:18 +0100 Subject: [PATCH 1/6] basic typescript migration --- express-main-example/.gitignore | 1 + .../express/routes/instruments.js | 60 ---------------- .../express/routes/orchestras.js | 64 ----------------- express-main-example/express/routes/users.js | 60 ---------------- express-main-example/package.json | 42 ++++++----- .../sqlite-example-database/helpers/random.js | 9 --- .../sqlite-example-database/setup.js | 53 -------------- .../{express/app.js => src/express/app.ts} | 28 +++++--- .../helpers.js => src/express/helpers.ts} | 6 +- .../src/express/routes/instruments.ts | 63 +++++++++++++++++ .../src/express/routes/orchestras.ts | 69 +++++++++++++++++++ .../src/express/routes/users.ts | 63 +++++++++++++++++ .../{index.js => src/index.ts} | 12 ++-- .../sequelize/extra-setup.ts} | 6 +- .../index.js => src/sequelize/index.ts} | 18 ++--- .../sequelize/models/instrument.model.ts} | 10 +-- .../sequelize/models/orchestra.model.ts} | 10 +-- .../sequelize/models/user.model.ts} | 12 ++-- .../sqlite-example-database/helpers/random.ts | 7 ++ .../src/sqlite-example-database/setup.ts | 49 +++++++++++++ express-main-example/tsconfig.json | 13 ++++ 21 files changed, 344 insertions(+), 311 deletions(-) delete mode 100644 express-main-example/express/routes/instruments.js delete mode 100644 express-main-example/express/routes/orchestras.js delete mode 100644 express-main-example/express/routes/users.js delete mode 100644 express-main-example/sqlite-example-database/helpers/random.js delete mode 100644 express-main-example/sqlite-example-database/setup.js rename express-main-example/{express/app.js => src/express/app.ts} (77%) rename express-main-example/{express/helpers.js => src/express/helpers.ts} (78%) create mode 100644 express-main-example/src/express/routes/instruments.ts create mode 100644 express-main-example/src/express/routes/orchestras.ts create mode 100644 express-main-example/src/express/routes/users.ts rename express-main-example/{index.js => src/index.ts} (60%) rename express-main-example/{sequelize/extra-setup.js => src/sequelize/extra-setup.ts} (54%) rename express-main-example/{sequelize/index.js => src/sequelize/index.ts} (67%) rename express-main-example/{sequelize/models/instrument.model.js => src/sequelize/models/instrument.model.ts} (80%) rename express-main-example/{sequelize/models/orchestra.model.js => src/sequelize/models/orchestra.model.ts} (66%) rename express-main-example/{sequelize/models/user.model.js => src/sequelize/models/user.model.ts} (75%) create mode 100644 express-main-example/src/sqlite-example-database/helpers/random.ts create mode 100644 express-main-example/src/sqlite-example-database/setup.ts create mode 100644 express-main-example/tsconfig.json diff --git a/express-main-example/.gitignore b/express-main-example/.gitignore index b622412..31b5726 100644 --- a/express-main-example/.gitignore +++ b/express-main-example/.gitignore @@ -1,2 +1,3 @@ node_modules *.sqlite +dist diff --git a/express-main-example/express/routes/instruments.js b/express-main-example/express/routes/instruments.js deleted file mode 100644 index 7e56a08..0000000 --- a/express-main-example/express/routes/instruments.js +++ /dev/null @@ -1,60 +0,0 @@ -const { models } = require('../../sequelize'); -const { getIdParam } = require('../helpers'); - -async function getAll(req, res) { - const instruments = await models.instrument.findAll(); - res.status(200).json(instruments); -}; - -async function getById(req, res) { - const id = getIdParam(req); - const instrument = await models.instrument.findByPk(id); - if (instrument) { - res.status(200).json(instrument); - } else { - res.status(404).send('404 - Not found'); - } -}; - -async function create(req, res) { - if (req.body.id) { - res.status(400).send(`Bad request: ID should not be provided, since it is determined automatically by the database.`) - } else { - await models.instrument.create(req.body); - res.status(201).end(); - } -}; - -async function update(req, res) { - const id = getIdParam(req); - - // We only accept an UPDATE request if the `:id` param matches the body `id` - if (req.body.id === id) { - await models.instrument.update(req.body, { - where: { - id: id - } - }); - res.status(200).end(); - } else { - res.status(400).send(`Bad request: param ID (${id}) does not match body ID (${req.body.id}).`); - } -}; - -async function remove(req, res) { - const id = getIdParam(req); - await models.instrument.destroy({ - where: { - id: id - } - }); - res.status(200).end(); -}; - -module.exports = { - getAll, - getById, - create, - update, - remove, -}; diff --git a/express-main-example/express/routes/orchestras.js b/express-main-example/express/routes/orchestras.js deleted file mode 100644 index af2b02b..0000000 --- a/express-main-example/express/routes/orchestras.js +++ /dev/null @@ -1,64 +0,0 @@ -const { models } = require('../../sequelize'); -const { getIdParam } = require('../helpers'); - -async function getAll(req, res) { - const orchestras = 'includeInstruments' in req.query ? - await models.orchestra.findAll({ include: models.instrument }) : - await models.orchestra.findAll(); - res.status(200).json(orchestras); -}; - -async function getById(req, res) { - const id = getIdParam(req); - const orchestra = 'includeInstruments' in req.query ? - await models.orchestra.findByPk(id, { include: models.instrument }) : - await models.orchestra.findByPk(id); - if (orchestra) { - res.status(200).json(orchestra); - } else { - res.status(404).send('404 - Not found'); - } -}; - -async function create(req, res) { - if (req.body.id) { - res.status(400).send(`Bad request: ID should not be provided, since it is determined automatically by the database.`) - } else { - await models.orchestra.create(req.body); - res.status(201).end(); - } -}; - -async function update(req, res) { - const id = getIdParam(req); - - // We only accept an UPDATE request if the `:id` param matches the body `id` - if (req.body.id === id) { - await models.orchestra.update(req.body, { - where: { - id: id - } - }); - res.status(200).end(); - } else { - res.status(400).send(`Bad request: param ID (${id}) does not match body ID (${req.body.id}).`); - } -}; - -async function remove(req, res) { - const id = getIdParam(req); - await models.orchestra.destroy({ - where: { - id: id - } - }); - res.status(200).end(); -}; - -module.exports = { - getAll, - getById, - create, - update, - remove, -}; diff --git a/express-main-example/express/routes/users.js b/express-main-example/express/routes/users.js deleted file mode 100644 index f87f8e7..0000000 --- a/express-main-example/express/routes/users.js +++ /dev/null @@ -1,60 +0,0 @@ -const { models } = require('../../sequelize'); -const { getIdParam } = require('../helpers'); - -async function getAll(req, res) { - const users = await models.user.findAll(); - res.status(200).json(users); -}; - -async function getById(req, res) { - const id = getIdParam(req); - const user = await models.user.findByPk(id); - if (user) { - res.status(200).json(user); - } else { - res.status(404).send('404 - Not found'); - } -}; - -async function create(req, res) { - if (req.body.id) { - res.status(400).send(`Bad request: ID should not be provided, since it is determined automatically by the database.`) - } else { - await models.user.create(req.body); - res.status(201).end(); - } -}; - -async function update(req, res) { - const id = getIdParam(req); - - // We only accept an UPDATE request if the `:id` param matches the body `id` - if (req.body.id === id) { - await models.user.update(req.body, { - where: { - id: id - } - }); - res.status(200).end(); - } else { - res.status(400).send(`Bad request: param ID (${id}) does not match body ID (${req.body.id}).`); - } -}; - -async function remove(req, res) { - const id = getIdParam(req); - await models.user.destroy({ - where: { - id: id - } - }); - res.status(200).end(); -}; - -module.exports = { - getAll, - getById, - create, - update, - remove, -}; diff --git a/express-main-example/package.json b/express-main-example/package.json index 302b680..127d937 100644 --- a/express-main-example/package.json +++ b/express-main-example/package.json @@ -1,20 +1,26 @@ { - "name": "express-main-example", - "version": "0.0.0", - "description": "This is an example of how to setup Sequelize and Express together in a project for NodeJS 10 and above.", - "main": "index.js", - "scripts": { - "start": "node index.js", - "setup-example-db": "node sqlite-example-database/setup.js" - }, - "engines": { - "node": ">=10" - }, - "license": "MIT", - "dependencies": { - "body-parser": "^1.19.0", - "express": "^4.17.1", - "sequelize": "^6.3.3", - "sqlite3": "^5.0.0" - } + "name": "express-main-example", + "version": "0.0.0", + "description": "This is an example of how to setup Sequelize and Express together in a project for NodeJS 10 and above.", + "main": "index.js", + "scripts": { + "start": "tsc-watch --onSuccess \"node dist/index.js\"", + "setup-example-db": "tsc && node dist/sqlite-example-database/setup.js" + }, + "engines": { + "node": ">=10" + }, + "license": "MIT", + "dependencies": { + "body-parser": "^1.19.0", + "express": "^4.17.1", + "sequelize": "^6.3.3", + "sqlite3": "^5.0.0" + }, + "devDependencies": { + "@types/body-parser": "^1.19.0", + "@types/express": "^4.17.11", + "tsc-watch": "^4.2.9", + "typescript": "^4.2.3" + } } diff --git a/express-main-example/sqlite-example-database/helpers/random.js b/express-main-example/sqlite-example-database/helpers/random.js deleted file mode 100644 index aa8dd82..0000000 --- a/express-main-example/sqlite-example-database/helpers/random.js +++ /dev/null @@ -1,9 +0,0 @@ -function pickRandom(args) { - return args[Math.floor(Math.random() * args.length)]; -} - -function randomDate() { - return new Date(new Date() - 200000000000 * Math.random()); -} - -module.exports = { pickRandom, randomDate }; diff --git a/express-main-example/sqlite-example-database/setup.js b/express-main-example/sqlite-example-database/setup.js deleted file mode 100644 index a480043..0000000 --- a/express-main-example/sqlite-example-database/setup.js +++ /dev/null @@ -1,53 +0,0 @@ -const sequelize = require('../sequelize'); -const { pickRandom, randomDate } = require('./helpers/random'); - -async function reset() { - console.log('Will rewrite the SQLite example database, adding some dummy data.'); - - await sequelize.sync({ force: true }); - - await sequelize.models.user.bulkCreate([ - { username: 'jack-sparrow' }, - { username: 'white-beard' }, - { username: 'black-beard' }, - { username: 'brown-beard' }, - ]); - - await sequelize.models.orchestra.bulkCreate([ - { name: 'Jalisco Philharmonic' }, - { name: 'Symphony No. 4' }, - { name: 'Symphony No. 8' }, - ]); - - // Let's create random instruments for each orchestra - for (const orchestra of await sequelize.models.orchestra.findAll()) { - for (let i = 0; i < 10; i++) { - const type = pickRandom([ - 'violin', - 'trombone', - 'flute', - 'harp', - 'trumpet', - 'piano', - 'guitar', - 'pipe organ', - ]); - - await orchestra.createInstrument({ - type: type, - purchaseDate: randomDate() - }); - - // The following would be equivalent in this case: - // await sequelize.models.instrument.create({ - // type: type, - // purchaseDate: randomDate(), - // orchestraId: orchestra.id - // }); - } - } - - console.log('Done!'); -} - -reset(); diff --git a/express-main-example/express/app.js b/express-main-example/src/express/app.ts similarity index 77% rename from express-main-example/express/app.js rename to express-main-example/src/express/app.ts index c3821b5..adb79de 100644 --- a/express-main-example/express/app.js +++ b/express-main-example/src/express/app.ts @@ -1,22 +1,28 @@ -const express = require('express'); -const bodyParser = require('body-parser'); +import express, { NextFunction, Request, Response } from "express"; +import { json, urlencoded } from "body-parser"; const routes = { - users: require('./routes/users'), - instruments: require('./routes/instruments'), - orchestras: require('./routes/orchestras'), + users: require("./routes/users"), + instruments: require("./routes/instruments"), + orchestras: require("./routes/orchestras"), // Add more routes here... // items: require('./routes/items'), }; const app = express(); -app.use(bodyParser.json()); -app.use(bodyParser.urlencoded({ extended: true })); +app.use(json()); +app.use(urlencoded({ extended: true })); + +type Handler = ( + req?: Request, + res?: Response, + next?: NextFunction +) => Promise | void; // We create a wrapper to workaround async errors not being transmitted correctly. -function makeHandlerAwareOfAsyncErrors(handler) { - return async function(req, res, next) { +function makeHandlerAwareOfAsyncErrors(handler: Handler) { + return async function (req: Request, res: Response, next: NextFunction) { try { await handler(req, res); } catch (error) { @@ -26,7 +32,7 @@ function makeHandlerAwareOfAsyncErrors(handler) { } // We provide a root route just as an example -app.get('/', (req, res) => { +app.get("/", (req: Request, res: Response) => { res.send(`

Hello, Sequelize + Express!

Make sure you have executed npm run setup-example-db once to have a populated example database. Otherwise, you will get 'no such table' errors.

@@ -69,4 +75,4 @@ for (const [routeName, routeController] of Object.entries(routes)) { } } -module.exports = app; +export default app; diff --git a/express-main-example/express/helpers.js b/express-main-example/src/express/helpers.ts similarity index 78% rename from express-main-example/express/helpers.js rename to express-main-example/src/express/helpers.ts index d0b303f..f3836ca 100644 --- a/express-main-example/express/helpers.js +++ b/express-main-example/src/express/helpers.ts @@ -1,11 +1,11 @@ +import { Request } from "express"; + // A helper function to assert the request ID param is valid // and convert it to a number (since it comes as a string by default) -function getIdParam(req) { +export function getIdParam(req: Request) { const id = req.params.id; if (/^\d+$/.test(id)) { return Number.parseInt(id, 10); } throw new TypeError(`Invalid ':id' param: "${id}"`); } - -module.exports = { getIdParam }; diff --git a/express-main-example/src/express/routes/instruments.ts b/express-main-example/src/express/routes/instruments.ts new file mode 100644 index 0000000..80c3ec8 --- /dev/null +++ b/express-main-example/src/express/routes/instruments.ts @@ -0,0 +1,63 @@ +import { Request, Response } from "express"; +import sequelize from "../../sequelize"; +import { getIdParam } from "../helpers"; + +const { models } = sequelize; + +export async function getAll(req: Request, res: Response) { + const instruments = await models.instrument.findAll(); + res.status(200).json(instruments); +} + +export async function getById(req: Request, res: Response) { + const id = getIdParam(req); + const instrument = await models.instrument.findByPk(id); + if (instrument) { + res.status(200).json(instrument); + } else { + res.status(404).send("404 - Not found"); + } +} + +export async function create(req: Request, res: Response) { + if (req.body.id) { + res + .status(400) + .send( + `Bad request: ID should not be provided, since it is determined automatically by the database.` + ); + } else { + await models.instrument.create(req.body); + res.status(201).end(); + } +} + +export async function update(req: Request, res: Response) { + const id = getIdParam(req); + + // We only accept an UPDATE request if the `:id` param matches the body `id` + if (req.body.id === id) { + await models.instrument.update(req.body, { + where: { + id: id, + }, + }); + res.status(200).end(); + } else { + res + .status(400) + .send( + `Bad request: param ID (${id}) does not match body ID (${req.body.id}).` + ); + } +} + +export async function remove(req: Request, res: Response) { + const id = getIdParam(req); + await models.instrument.destroy({ + where: { + id: id, + }, + }); + res.status(200).end(); +} diff --git a/express-main-example/src/express/routes/orchestras.ts b/express-main-example/src/express/routes/orchestras.ts new file mode 100644 index 0000000..4c49146 --- /dev/null +++ b/express-main-example/src/express/routes/orchestras.ts @@ -0,0 +1,69 @@ +import { Request, Response } from "express"; +import sequelize from "../../sequelize"; +import { getIdParam } from "../helpers"; + +const { models } = sequelize; + +export async function getAll(req: Request, res: Response) { + const orchestras = + "includeInstruments" in req.query + ? await models.orchestra.findAll({ include: models.instrument }) + : await models.orchestra.findAll(); + res.status(200).json(orchestras); +} + +export async function getById(req: Request, res: Response) { + const id = getIdParam(req); + const orchestra = + "includeInstruments" in req.query + ? await models.orchestra.findByPk(id, { include: models.instrument }) + : await models.orchestra.findByPk(id); + if (orchestra) { + res.status(200).json(orchestra); + } else { + res.status(404).send("404 - Not found"); + } +} + +export async function create(req: Request, res: Response) { + if (req.body.id) { + res + .status(400) + .send( + `Bad request: ID should not be provided, since it is determined automatically by the database.` + ); + } else { + await models.orchestra.create(req.body); + res.status(201).end(); + } +} + +export async function update(req: Request, res: Response) { + const id = getIdParam(req); + + // We only accept an UPDATE request if the `:id` param matches the body `id` + if (req.body.id === id) { + await models.orchestra.update(req.body, { + where: { + id: id, + }, + }); + res.status(200).end(); + } else { + res + .status(400) + .send( + `Bad request: param ID (${id}) does not match body ID (${req.body.id}).` + ); + } +} + +export async function remove(req: Request, res: Response) { + const id = getIdParam(req); + await models.orchestra.destroy({ + where: { + id: id, + }, + }); + res.status(200).end(); +} diff --git a/express-main-example/src/express/routes/users.ts b/express-main-example/src/express/routes/users.ts new file mode 100644 index 0000000..e23604e --- /dev/null +++ b/express-main-example/src/express/routes/users.ts @@ -0,0 +1,63 @@ +import { Request, Response } from "express"; +import sequelize from "../../sequelize"; +import { getIdParam } from "../helpers"; + +const { models } = sequelize; + +export async function getAll(req: Request, res: Response) { + const users = await models.user.findAll(); + res.status(200).json(users); +} + +export async function getById(req: Request, res: Response) { + const id = getIdParam(req); + const user = await models.user.findByPk(id); + if (user) { + res.status(200).json(user); + } else { + res.status(404).send("404 - Not found"); + } +} + +export async function create(req: Request, res: Response) { + if (req.body.id) { + res + .status(400) + .send( + `Bad request: ID should not be provided, since it is determined automatically by the database.` + ); + } else { + await models.user.create(req.body); + res.status(201).end(); + } +} + +export async function update(req: Request, res: Response) { + const id = getIdParam(req); + + // We only accept an UPDATE request if the `:id` param matches the body `id` + if (req.body.id === id) { + await models.user.update(req.body, { + where: { + id: id, + }, + }); + res.status(200).end(); + } else { + res + .status(400) + .send( + `Bad request: param ID (${id}) does not match body ID (${req.body.id}).` + ); + } +} + +export async function remove(req: Request, res: Response) { + const id = getIdParam(req); + await models.user.destroy({ + where: { + id: id, + }, + }); + res.status(200).end(); +} diff --git a/express-main-example/index.js b/express-main-example/src/index.ts similarity index 60% rename from express-main-example/index.js rename to express-main-example/src/index.ts index 94640fe..4160a54 100644 --- a/express-main-example/index.js +++ b/express-main-example/src/index.ts @@ -1,14 +1,14 @@ -const app = require('./express/app'); -const sequelize = require('./sequelize'); +import app from "./express/app"; +import sequelize from "./sequelize"; const PORT = 8080; async function assertDatabaseConnectionOk() { console.log(`Checking database connection...`); try { await sequelize.authenticate(); - console.log('Database connection OK!'); + console.log("Database connection OK!"); } catch (error) { - console.log('Unable to connect to the database:'); + console.log("Unable to connect to the database:"); console.log(error.message); process.exit(1); } @@ -20,7 +20,9 @@ async function init() { console.log(`Starting Sequelize + Express example on port ${PORT}...`); app.listen(PORT, () => { - console.log(`Express server started on port ${PORT}. Try some routes, such as '/api/users'.`); + console.log( + `Express server started on port ${PORT}. Try some routes, such as '/api/users'.` + ); }); } diff --git a/express-main-example/sequelize/extra-setup.js b/express-main-example/src/sequelize/extra-setup.ts similarity index 54% rename from express-main-example/sequelize/extra-setup.js rename to express-main-example/src/sequelize/extra-setup.ts index 7d8fc6f..c749174 100644 --- a/express-main-example/sequelize/extra-setup.js +++ b/express-main-example/src/sequelize/extra-setup.ts @@ -1,8 +1,8 @@ -function applyExtraSetup(sequelize) { +import { Sequelize } from "sequelize/types"; + +export function applyExtraSetup(sequelize: Sequelize) { const { instrument, orchestra } = sequelize.models; orchestra.hasMany(instrument); instrument.belongsTo(orchestra); } - -module.exports = { applyExtraSetup }; diff --git a/express-main-example/sequelize/index.js b/express-main-example/src/sequelize/index.ts similarity index 67% rename from express-main-example/sequelize/index.js rename to express-main-example/src/sequelize/index.ts index c0f9ee4..90789ab 100644 --- a/express-main-example/sequelize/index.js +++ b/express-main-example/src/sequelize/index.ts @@ -1,20 +1,20 @@ -const { Sequelize } = require('sequelize'); -const { applyExtraSetup } = require('./extra-setup'); +import { Sequelize } from "sequelize"; +import { applyExtraSetup } from "./extra-setup"; // In a real app, you should keep the database connection URL as an environment variable. // But for this example, we will just use a local SQLite database. // const sequelize = new Sequelize(process.env.DB_CONNECTION_URL); const sequelize = new Sequelize({ - dialect: 'sqlite', - storage: 'sqlite-example-database/example-db.sqlite', + dialect: "sqlite", + storage: "sqlite-example-database/example-db.sqlite", logQueryParameters: true, - benchmark: true + benchmark: true, }); const modelDefiners = [ - require('./models/user.model'), - require('./models/instrument.model'), - require('./models/orchestra.model'), + require("./models/user.model"), + require("./models/instrument.model"), + require("./models/orchestra.model"), // Add more models here... // require('./models/item'), ]; @@ -28,4 +28,4 @@ for (const modelDefiner of modelDefiners) { applyExtraSetup(sequelize); // We export the sequelize connection instance to be used around our app. -module.exports = sequelize; +export default sequelize; diff --git a/express-main-example/sequelize/models/instrument.model.js b/express-main-example/src/sequelize/models/instrument.model.ts similarity index 80% rename from express-main-example/sequelize/models/instrument.model.js rename to express-main-example/src/sequelize/models/instrument.model.ts index 0bbad3a..0342609 100644 --- a/express-main-example/sequelize/models/instrument.model.js +++ b/express-main-example/src/sequelize/models/instrument.model.ts @@ -1,16 +1,16 @@ -const { DataTypes } = require('sequelize'); +import { DataTypes, Sequelize } from "sequelize"; // We export a function that defines the model. // This function will automatically receive as parameter the Sequelize connection object. -module.exports = (sequelize) => { - sequelize.define('instrument', { +module.exports = (sequelize: Sequelize) => { + sequelize.define("instrument", { // The following specification of the 'id' attribute could be omitted // since it is the default. id: { allowNull: false, autoIncrement: true, primaryKey: true, - type: DataTypes.INTEGER + type: DataTypes.INTEGER, }, type: { allowNull: false, @@ -25,7 +25,7 @@ module.exports = (sequelize) => { // }, purchaseDate: { allowNull: false, - type: DataTypes.DATE + type: DataTypes.DATE, }, // We also want it to have a 'orchestraId' field, but we don't have to define it here. // It will be defined automatically when Sequelize applies the associations. diff --git a/express-main-example/sequelize/models/orchestra.model.js b/express-main-example/src/sequelize/models/orchestra.model.ts similarity index 66% rename from express-main-example/sequelize/models/orchestra.model.js rename to express-main-example/src/sequelize/models/orchestra.model.ts index b6f06f9..9302d54 100644 --- a/express-main-example/sequelize/models/orchestra.model.js +++ b/express-main-example/src/sequelize/models/orchestra.model.ts @@ -1,20 +1,20 @@ -const { DataTypes } = require('sequelize'); +import { DataTypes, Sequelize } from "sequelize"; // We export a function that defines the model. // This function will automatically receive as parameter the Sequelize connection object. -module.exports = (sequelize) => { - sequelize.define('orchestra', { +module.exports = (sequelize: Sequelize) => { + sequelize.define("orchestra", { // The following specification of the 'id' attribute could be omitted // since it is the default. id: { allowNull: false, autoIncrement: true, primaryKey: true, - type: DataTypes.INTEGER + type: DataTypes.INTEGER, }, name: { allowNull: false, - type: DataTypes.STRING + type: DataTypes.STRING, }, }); }; diff --git a/express-main-example/sequelize/models/user.model.js b/express-main-example/src/sequelize/models/user.model.ts similarity index 75% rename from express-main-example/sequelize/models/user.model.js rename to express-main-example/src/sequelize/models/user.model.ts index f1f5118..cdb1c74 100644 --- a/express-main-example/sequelize/models/user.model.js +++ b/express-main-example/src/sequelize/models/user.model.ts @@ -1,16 +1,16 @@ -const { DataTypes } = require('sequelize'); +import { DataTypes, Sequelize } from "sequelize"; // We export a function that defines the model. // This function will automatically receive as parameter the Sequelize connection object. -module.exports = (sequelize) => { - sequelize.define('user', { +module.exports = (sequelize: Sequelize) => { + sequelize.define("user", { // The following specification of the 'id' attribute could be omitted // since it is the default. id: { allowNull: false, autoIncrement: true, primaryKey: true, - type: DataTypes.INTEGER + type: DataTypes.INTEGER, }, username: { allowNull: false, @@ -19,8 +19,8 @@ module.exports = (sequelize) => { validate: { // We require usernames to have length of at least 3, and // only use letters, numbers and underscores. - is: /^\w{3,}$/ - } + is: /^\w{3,}$/, + }, }, }); }; diff --git a/express-main-example/src/sqlite-example-database/helpers/random.ts b/express-main-example/src/sqlite-example-database/helpers/random.ts new file mode 100644 index 0000000..887c88a --- /dev/null +++ b/express-main-example/src/sqlite-example-database/helpers/random.ts @@ -0,0 +1,7 @@ +export function pickRandom(args: string[]) { + return args[Math.floor(Math.random() * args.length)]; +} + +export function randomDate() { + return new Date(+new Date() - 200000000000 * Math.random()); +} diff --git a/express-main-example/src/sqlite-example-database/setup.ts b/express-main-example/src/sqlite-example-database/setup.ts new file mode 100644 index 0000000..228d08a --- /dev/null +++ b/express-main-example/src/sqlite-example-database/setup.ts @@ -0,0 +1,49 @@ +import sequelize from "../sequelize"; +import { pickRandom, randomDate } from "./helpers/random"; + +async function reset() { + console.log( + "Will rewrite the SQLite example database, adding some dummy data." + ); + + await sequelize.sync({ force: true }); + + await sequelize.models.user.bulkCreate([ + { username: "jack-sparrow" }, + { username: "white-beard" }, + { username: "black-beard" }, + { username: "brown-beard" }, + ]); + + await sequelize.models.orchestra.bulkCreate([ + { name: "Jalisco Philharmonic" }, + { name: "Symphony No. 4" }, + { name: "Symphony No. 8" }, + ]); + + // Let's create random instruments for each orchestra + for (const orchestra of await sequelize.models.orchestra.findAll()) { + for (let i = 0; i < 10; i++) { + const type = pickRandom([ + "violin", + "trombone", + "flute", + "harp", + "trumpet", + "piano", + "guitar", + "pipe organ", + ]); + + await sequelize.models.instrument.create({ + type: type, + purchaseDate: randomDate(), + orchestraId: (orchestra as any).id, + }); + } + } + + console.log("Done!"); +} + +reset(); diff --git a/express-main-example/tsconfig.json b/express-main-example/tsconfig.json new file mode 100644 index 0000000..7466b6b --- /dev/null +++ b/express-main-example/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "strict": false, + "noImplicitAny": false, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "rootDir": "src", + "outDir": "dist" + } +} From b7885c87cc71f431507b575c74af6256dd38f204 Mon Sep 17 00:00:00 2001 From: Constantin Metz Date: Wed, 10 Mar 2021 18:14:29 +0100 Subject: [PATCH 2/6] rewritten model definition with ModelDefined type --- .../src/express/routes/instruments.ts | 18 ++--- .../src/express/routes/orchestras.ts | 23 +++--- .../src/express/routes/users.ts | 14 ++-- .../src/sequelize/connection.ts | 13 ++++ .../src/sequelize/extra-setup.ts | 11 ++- express-main-example/src/sequelize/index.ts | 30 ++------ .../src/sequelize/models/instrument.model.ts | 74 +++++++++++-------- .../src/sequelize/models/orchestra.model.ts | 45 ++++++----- .../src/sequelize/models/user.model.ts | 55 ++++++++------ .../src/sqlite-example-database/setup.ts | 15 ++-- 10 files changed, 157 insertions(+), 141 deletions(-) create mode 100644 express-main-example/src/sequelize/connection.ts diff --git a/express-main-example/src/express/routes/instruments.ts b/express-main-example/src/express/routes/instruments.ts index 80c3ec8..6294616 100644 --- a/express-main-example/src/express/routes/instruments.ts +++ b/express-main-example/src/express/routes/instruments.ts @@ -1,17 +1,15 @@ import { Request, Response } from "express"; -import sequelize from "../../sequelize"; +import { Instrument } from "../../sequelize/models/instrument.model"; import { getIdParam } from "../helpers"; -const { models } = sequelize; - export async function getAll(req: Request, res: Response) { - const instruments = await models.instrument.findAll(); + const instruments = await Instrument.findAll(); res.status(200).json(instruments); } export async function getById(req: Request, res: Response) { const id = getIdParam(req); - const instrument = await models.instrument.findByPk(id); + const instrument = await Instrument.findByPk(id); if (instrument) { res.status(200).json(instrument); } else { @@ -27,7 +25,7 @@ export async function create(req: Request, res: Response) { `Bad request: ID should not be provided, since it is determined automatically by the database.` ); } else { - await models.instrument.create(req.body); + await Instrument.create(req.body); res.status(201).end(); } } @@ -37,9 +35,9 @@ export async function update(req: Request, res: Response) { // We only accept an UPDATE request if the `:id` param matches the body `id` if (req.body.id === id) { - await models.instrument.update(req.body, { + await Instrument.update(req.body, { where: { - id: id, + id, }, }); res.status(200).end(); @@ -54,9 +52,9 @@ export async function update(req: Request, res: Response) { export async function remove(req: Request, res: Response) { const id = getIdParam(req); - await models.instrument.destroy({ + await Instrument.destroy({ where: { - id: id, + id, }, }); res.status(200).end(); diff --git a/express-main-example/src/express/routes/orchestras.ts b/express-main-example/src/express/routes/orchestras.ts index 4c49146..eefd111 100644 --- a/express-main-example/src/express/routes/orchestras.ts +++ b/express-main-example/src/express/routes/orchestras.ts @@ -1,14 +1,13 @@ import { Request, Response } from "express"; -import sequelize from "../../sequelize"; +import { Instrument } from "../../sequelize/models/instrument.model"; +import { Orchestra } from "../../sequelize/models/orchestra.model"; import { getIdParam } from "../helpers"; -const { models } = sequelize; - export async function getAll(req: Request, res: Response) { const orchestras = "includeInstruments" in req.query - ? await models.orchestra.findAll({ include: models.instrument }) - : await models.orchestra.findAll(); + ? await Orchestra.findAll({ include: Instrument }) + : await Orchestra.findAll(); res.status(200).json(orchestras); } @@ -16,8 +15,8 @@ export async function getById(req: Request, res: Response) { const id = getIdParam(req); const orchestra = "includeInstruments" in req.query - ? await models.orchestra.findByPk(id, { include: models.instrument }) - : await models.orchestra.findByPk(id); + ? await Orchestra.findByPk(id, { include: Instrument }) + : await Orchestra.findByPk(id); if (orchestra) { res.status(200).json(orchestra); } else { @@ -33,7 +32,7 @@ export async function create(req: Request, res: Response) { `Bad request: ID should not be provided, since it is determined automatically by the database.` ); } else { - await models.orchestra.create(req.body); + await Orchestra.create(req.body); res.status(201).end(); } } @@ -43,9 +42,9 @@ export async function update(req: Request, res: Response) { // We only accept an UPDATE request if the `:id` param matches the body `id` if (req.body.id === id) { - await models.orchestra.update(req.body, { + await Orchestra.update(req.body, { where: { - id: id, + id, }, }); res.status(200).end(); @@ -60,9 +59,9 @@ export async function update(req: Request, res: Response) { export async function remove(req: Request, res: Response) { const id = getIdParam(req); - await models.orchestra.destroy({ + await Orchestra.destroy({ where: { - id: id, + id, }, }); res.status(200).end(); diff --git a/express-main-example/src/express/routes/users.ts b/express-main-example/src/express/routes/users.ts index e23604e..8bcfaea 100644 --- a/express-main-example/src/express/routes/users.ts +++ b/express-main-example/src/express/routes/users.ts @@ -1,17 +1,15 @@ import { Request, Response } from "express"; -import sequelize from "../../sequelize"; +import { User } from "../../sequelize/models/user.model"; import { getIdParam } from "../helpers"; -const { models } = sequelize; - export async function getAll(req: Request, res: Response) { - const users = await models.user.findAll(); + const users = await User.findAll(); res.status(200).json(users); } export async function getById(req: Request, res: Response) { const id = getIdParam(req); - const user = await models.user.findByPk(id); + const user = await User.findByPk(id); if (user) { res.status(200).json(user); } else { @@ -27,7 +25,7 @@ export async function create(req: Request, res: Response) { `Bad request: ID should not be provided, since it is determined automatically by the database.` ); } else { - await models.user.create(req.body); + await User.create(req.body); res.status(201).end(); } } @@ -37,7 +35,7 @@ export async function update(req: Request, res: Response) { // We only accept an UPDATE request if the `:id` param matches the body `id` if (req.body.id === id) { - await models.user.update(req.body, { + await User.update(req.body, { where: { id: id, }, @@ -54,7 +52,7 @@ export async function update(req: Request, res: Response) { export async function remove(req: Request, res: Response) { const id = getIdParam(req); - await models.user.destroy({ + await User.destroy({ where: { id: id, }, diff --git a/express-main-example/src/sequelize/connection.ts b/express-main-example/src/sequelize/connection.ts new file mode 100644 index 0000000..f6640dc --- /dev/null +++ b/express-main-example/src/sequelize/connection.ts @@ -0,0 +1,13 @@ +import { Sequelize } from "sequelize"; + +// In a real app, you should keep the database connection URL as an environment variable. +// But for this example, we will just use a local SQLite database. +// const sequelize = new Sequelize(process.env.DB_CONNECTION_URL); +const sequelize = new Sequelize({ + dialect: "sqlite", + storage: "sqlite-example-database/example-db.sqlite", + logQueryParameters: true, + benchmark: true, +}); + +export default sequelize; diff --git a/express-main-example/src/sequelize/extra-setup.ts b/express-main-example/src/sequelize/extra-setup.ts index c749174..7f93b23 100644 --- a/express-main-example/src/sequelize/extra-setup.ts +++ b/express-main-example/src/sequelize/extra-setup.ts @@ -1,8 +1,7 @@ -import { Sequelize } from "sequelize/types"; +import { Instrument } from "./models/instrument.model"; +import { Orchestra } from "./models/orchestra.model"; -export function applyExtraSetup(sequelize: Sequelize) { - const { instrument, orchestra } = sequelize.models; - - orchestra.hasMany(instrument); - instrument.belongsTo(orchestra); +export function applyExtraSetup() { + Orchestra.hasMany(Instrument); + Instrument.belongsTo(Orchestra); } diff --git a/express-main-example/src/sequelize/index.ts b/express-main-example/src/sequelize/index.ts index 90789ab..09488d5 100644 --- a/express-main-example/src/sequelize/index.ts +++ b/express-main-example/src/sequelize/index.ts @@ -1,31 +1,13 @@ -import { Sequelize } from "sequelize"; import { applyExtraSetup } from "./extra-setup"; -// In a real app, you should keep the database connection URL as an environment variable. -// But for this example, we will just use a local SQLite database. -// const sequelize = new Sequelize(process.env.DB_CONNECTION_URL); -const sequelize = new Sequelize({ - dialect: "sqlite", - storage: "sqlite-example-database/example-db.sqlite", - logQueryParameters: true, - benchmark: true, -}); +import sequelize from "./connection"; -const modelDefiners = [ - require("./models/user.model"), - require("./models/instrument.model"), - require("./models/orchestra.model"), - // Add more models here... - // require('./models/item'), -]; - -// We define all models according to their files. -for (const modelDefiner of modelDefiners) { - modelDefiner(sequelize); -} +// must reference all models, after importing the sequelize connection. +import "./models/instrument.model"; +import "./models/orchestra.model"; +import "./models/user.model"; // We execute any extra setup after the models are defined, such as adding associations. -applyExtraSetup(sequelize); +applyExtraSetup(); -// We export the sequelize connection instance to be used around our app. export default sequelize; diff --git a/express-main-example/src/sequelize/models/instrument.model.ts b/express-main-example/src/sequelize/models/instrument.model.ts index 0342609..29e7bf6 100644 --- a/express-main-example/src/sequelize/models/instrument.model.ts +++ b/express-main-example/src/sequelize/models/instrument.model.ts @@ -1,33 +1,43 @@ -import { DataTypes, Sequelize } from "sequelize"; +import { DataTypes, ModelDefined } from "sequelize"; +import sequelize from "../connection"; -// We export a function that defines the model. -// This function will automatically receive as parameter the Sequelize connection object. -module.exports = (sequelize: Sequelize) => { - sequelize.define("instrument", { - // The following specification of the 'id' attribute could be omitted - // since it is the default. - id: { - allowNull: false, - autoIncrement: true, - primaryKey: true, - type: DataTypes.INTEGER, - }, - type: { - allowNull: false, - type: DataTypes.STRING, - }, - // type: { - // allowNull: false, - // type: DataTypes.STRING, - // validate: { - // isIn: [['string', 'wind', 'percussion']] - // } - // }, - purchaseDate: { - allowNull: false, - type: DataTypes.DATE, - }, - // We also want it to have a 'orchestraId' field, but we don't have to define it here. - // It will be defined automatically when Sequelize applies the associations. - }); -}; +interface InstrumentAttributes { + id: number; + type: string; + purchaseDate: Date; + orchestraId: number; +} + +interface InstrumentCreationAttributes + extends Omit {} + +export const Instrument: ModelDefined< + InstrumentAttributes, + InstrumentCreationAttributes +> = sequelize.define("instrument", { + // The following specification of the 'id' attribute could be omitted + // since it is the default. + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: DataTypes.INTEGER, + }, + type: { + allowNull: false, + type: DataTypes.STRING, + }, + // type: { + // allowNull: false, + // type: DataTypes.STRING, + // validate: { + // isIn: [['string', 'wind', 'percussion']] + // } + // }, + purchaseDate: { + allowNull: false, + type: DataTypes.DATE, + }, + // We also want it to have a 'orchestraId' field, but we don't have to define it here. + // It will be defined automatically when Sequelize applies the associations. +}); diff --git a/express-main-example/src/sequelize/models/orchestra.model.ts b/express-main-example/src/sequelize/models/orchestra.model.ts index 9302d54..9d41fe0 100644 --- a/express-main-example/src/sequelize/models/orchestra.model.ts +++ b/express-main-example/src/sequelize/models/orchestra.model.ts @@ -1,20 +1,27 @@ -import { DataTypes, Sequelize } from "sequelize"; +import { DataTypes, ModelDefined } from "sequelize"; +import sequelize from "../connection"; -// We export a function that defines the model. -// This function will automatically receive as parameter the Sequelize connection object. -module.exports = (sequelize: Sequelize) => { - sequelize.define("orchestra", { - // The following specification of the 'id' attribute could be omitted - // since it is the default. - id: { - allowNull: false, - autoIncrement: true, - primaryKey: true, - type: DataTypes.INTEGER, - }, - name: { - allowNull: false, - type: DataTypes.STRING, - }, - }); -}; +interface OrchestraAttributes { + id: number; + name: string; +} + +interface OrchestraCreationAttributes extends Omit {} + +export const Orchestra: ModelDefined< + OrchestraAttributes, + OrchestraCreationAttributes +> = sequelize.define("orchestra", { + // The following specification of the 'id' attribute could be omitted + // since it is the default. + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: DataTypes.INTEGER, + }, + name: { + allowNull: false, + type: DataTypes.STRING, + }, +}); diff --git a/express-main-example/src/sequelize/models/user.model.ts b/express-main-example/src/sequelize/models/user.model.ts index cdb1c74..58d1409 100644 --- a/express-main-example/src/sequelize/models/user.model.ts +++ b/express-main-example/src/sequelize/models/user.model.ts @@ -1,26 +1,33 @@ -import { DataTypes, Sequelize } from "sequelize"; +import { DataTypes, ModelDefined } from "sequelize"; +import sequelize from "../connection"; -// We export a function that defines the model. -// This function will automatically receive as parameter the Sequelize connection object. -module.exports = (sequelize: Sequelize) => { - sequelize.define("user", { - // The following specification of the 'id' attribute could be omitted - // since it is the default. - id: { - allowNull: false, - autoIncrement: true, - primaryKey: true, - type: DataTypes.INTEGER, - }, - username: { - allowNull: false, - type: DataTypes.STRING, - unique: true, - validate: { - // We require usernames to have length of at least 3, and - // only use letters, numbers and underscores. - is: /^\w{3,}$/, - }, +interface UserAttributes { + id: number; + username: string; +} + +interface UserCreationAttributes extends Omit {} + +export const User: ModelDefined< + UserAttributes, + UserCreationAttributes +> = sequelize.define("user", { + // The following specification of the 'id' attribute could be omitted + // since it is the default. + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: DataTypes.INTEGER, + }, + username: { + allowNull: false, + type: DataTypes.STRING, + unique: true, + validate: { + // We require usernames to have length of at least 3, and + // only use letters, numbers and underscores. + is: /^\w{3,}$/, }, - }); -}; + }, +}); diff --git a/express-main-example/src/sqlite-example-database/setup.ts b/express-main-example/src/sqlite-example-database/setup.ts index 228d08a..32d94dd 100644 --- a/express-main-example/src/sqlite-example-database/setup.ts +++ b/express-main-example/src/sqlite-example-database/setup.ts @@ -1,4 +1,7 @@ import sequelize from "../sequelize"; +import { Instrument } from "../sequelize/models/instrument.model"; +import { Orchestra } from "../sequelize/models/orchestra.model"; +import { User } from "../sequelize/models/user.model"; import { pickRandom, randomDate } from "./helpers/random"; async function reset() { @@ -8,21 +11,21 @@ async function reset() { await sequelize.sync({ force: true }); - await sequelize.models.user.bulkCreate([ + await User.bulkCreate([ { username: "jack-sparrow" }, { username: "white-beard" }, { username: "black-beard" }, { username: "brown-beard" }, ]); - await sequelize.models.orchestra.bulkCreate([ + await Orchestra.bulkCreate([ { name: "Jalisco Philharmonic" }, { name: "Symphony No. 4" }, { name: "Symphony No. 8" }, ]); // Let's create random instruments for each orchestra - for (const orchestra of await sequelize.models.orchestra.findAll()) { + for (const orchestra of await Orchestra.findAll()) { for (let i = 0; i < 10; i++) { const type = pickRandom([ "violin", @@ -35,10 +38,10 @@ async function reset() { "pipe organ", ]); - await sequelize.models.instrument.create({ - type: type, + await Instrument.create({ + type, purchaseDate: randomDate(), - orchestraId: (orchestra as any).id, + orchestraId: orchestra.get().id, }); } } From cd6720cf9b79ff39c65a1e56b5fbcbfa37298bee Mon Sep 17 00:00:00 2001 From: Constantin Metz Date: Wed, 10 Mar 2021 18:15:24 +0100 Subject: [PATCH 3/6] run typescript on strict mode --- express-main-example/tsconfig.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/express-main-example/tsconfig.json b/express-main-example/tsconfig.json index 7466b6b..3fe40d2 100644 --- a/express-main-example/tsconfig.json +++ b/express-main-example/tsconfig.json @@ -2,8 +2,8 @@ "compilerOptions": { "target": "es5", "module": "commonjs", - "strict": false, - "noImplicitAny": false, + "strict": true, + "noImplicitAny": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, From aaa26a4c800d2abca188db61bf8d351c2128bfc2 Mon Sep 17 00:00:00 2001 From: Constantin Metz Date: Wed, 10 Mar 2021 18:27:42 +0100 Subject: [PATCH 4/6] added explanation on why id is omitted also added an explanation on why the orchestraId field must be defined in the interface, although we don't explicitly define it --- .../src/sequelize/models/instrument.model.ts | 6 ++++++ .../src/sequelize/models/orchestra.model.ts | 2 ++ express-main-example/src/sequelize/models/user.model.ts | 2 ++ 3 files changed, 10 insertions(+) diff --git a/express-main-example/src/sequelize/models/instrument.model.ts b/express-main-example/src/sequelize/models/instrument.model.ts index 29e7bf6..d654add 100644 --- a/express-main-example/src/sequelize/models/instrument.model.ts +++ b/express-main-example/src/sequelize/models/instrument.model.ts @@ -5,9 +5,15 @@ interface InstrumentAttributes { id: number; type: string; purchaseDate: Date; + + // We need to specify the 'orchestraId' field here, + // because it will automatically be defined later on + // when Sequelize applies the associations orchestraId: number; } +// we can omit the 'id' field, since we aren't required +// to set it manually when creating a new entry interface InstrumentCreationAttributes extends Omit {} diff --git a/express-main-example/src/sequelize/models/orchestra.model.ts b/express-main-example/src/sequelize/models/orchestra.model.ts index 9d41fe0..f3316e1 100644 --- a/express-main-example/src/sequelize/models/orchestra.model.ts +++ b/express-main-example/src/sequelize/models/orchestra.model.ts @@ -6,6 +6,8 @@ interface OrchestraAttributes { name: string; } +// we can omit the 'id' field, since we aren't required +// to set it manually when creating a new entry interface OrchestraCreationAttributes extends Omit {} export const Orchestra: ModelDefined< diff --git a/express-main-example/src/sequelize/models/user.model.ts b/express-main-example/src/sequelize/models/user.model.ts index 58d1409..7150222 100644 --- a/express-main-example/src/sequelize/models/user.model.ts +++ b/express-main-example/src/sequelize/models/user.model.ts @@ -6,6 +6,8 @@ interface UserAttributes { username: string; } +// we can omit the 'id' field, since we aren't required +// to set it manually when creating a new entry interface UserCreationAttributes extends Omit {} export const User: ModelDefined< From dc94484b933ee8f8e168a36ecc9088ce40a72967 Mon Sep 17 00:00:00 2001 From: Constantin Metz Date: Wed, 10 Mar 2021 18:32:46 +0100 Subject: [PATCH 5/6] added documentation on import order --- express-main-example/src/index.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/express-main-example/src/index.ts b/express-main-example/src/index.ts index 4160a54..0a4470a 100644 --- a/express-main-example/src/index.ts +++ b/express-main-example/src/index.ts @@ -1,5 +1,10 @@ import app from "./express/app"; + +// it is important to import sequelize at least once in the app, +// as this will create the database connection, and also create the relations +// between all models. import sequelize from "./sequelize"; + const PORT = 8080; async function assertDatabaseConnectionOk() { From 38752e77a7d4ae7b6157bc680a4c683fee674e5b Mon Sep 17 00:00:00 2001 From: Constantin Metz Date: Wed, 10 Mar 2021 18:39:19 +0100 Subject: [PATCH 6/6] make id field optional, instead of omitting it --- .../src/sequelize/models/instrument.model.ts | 6 +++--- .../src/sequelize/models/orchestra.model.ts | 7 ++++--- express-main-example/src/sequelize/models/user.model.ts | 6 +++--- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/express-main-example/src/sequelize/models/instrument.model.ts b/express-main-example/src/sequelize/models/instrument.model.ts index d654add..8757ac6 100644 --- a/express-main-example/src/sequelize/models/instrument.model.ts +++ b/express-main-example/src/sequelize/models/instrument.model.ts @@ -1,4 +1,4 @@ -import { DataTypes, ModelDefined } from "sequelize"; +import { DataTypes, ModelDefined, Optional } from "sequelize"; import sequelize from "../connection"; interface InstrumentAttributes { @@ -12,10 +12,10 @@ interface InstrumentAttributes { orchestraId: number; } -// we can omit the 'id' field, since we aren't required +// we can make the 'id' field optional, since we aren't required // to set it manually when creating a new entry interface InstrumentCreationAttributes - extends Omit {} + extends Optional {} export const Instrument: ModelDefined< InstrumentAttributes, diff --git a/express-main-example/src/sequelize/models/orchestra.model.ts b/express-main-example/src/sequelize/models/orchestra.model.ts index f3316e1..5d948ac 100644 --- a/express-main-example/src/sequelize/models/orchestra.model.ts +++ b/express-main-example/src/sequelize/models/orchestra.model.ts @@ -1,4 +1,4 @@ -import { DataTypes, ModelDefined } from "sequelize"; +import { DataTypes, ModelDefined, Optional } from "sequelize"; import sequelize from "../connection"; interface OrchestraAttributes { @@ -6,9 +6,10 @@ interface OrchestraAttributes { name: string; } -// we can omit the 'id' field, since we aren't required +// we can make the 'id' field optional, since we aren't required // to set it manually when creating a new entry -interface OrchestraCreationAttributes extends Omit {} +interface OrchestraCreationAttributes + extends Optional {} export const Orchestra: ModelDefined< OrchestraAttributes, diff --git a/express-main-example/src/sequelize/models/user.model.ts b/express-main-example/src/sequelize/models/user.model.ts index 7150222..ac87f98 100644 --- a/express-main-example/src/sequelize/models/user.model.ts +++ b/express-main-example/src/sequelize/models/user.model.ts @@ -1,4 +1,4 @@ -import { DataTypes, ModelDefined } from "sequelize"; +import { DataTypes, ModelDefined, Optional } from "sequelize"; import sequelize from "../connection"; interface UserAttributes { @@ -6,9 +6,9 @@ interface UserAttributes { username: string; } -// we can omit the 'id' field, since we aren't required +// we can make the 'id' field optional, since we aren't required // to set it manually when creating a new entry -interface UserCreationAttributes extends Omit {} +interface UserCreationAttributes extends Optional {} export const User: ModelDefined< UserAttributes,