@seanmcgary/database
TypeScript icon, indicating that this package has built-in type declarations

3.3.1 • Public • Published

@seanmcgary/database

Database boilerplate using Sequelize.

Install

yarn add @seanmcgary/database

Use

Usage caveats and notes due to some sequelize weirdness:

  • Column and table names should be camelCased when used in JS/TS. Sequelize will automatically convert to/from snake_case since that is how things are represented in Postgres
  • createdAt and updatedAt columns are automatically added for each table
  • Each table will automatically get a column called id which will be a SERIAL type and set as the primary key. To override it, simple add an id column manually and give it a type.

Example directory structure and files:

.
├── package.json
├── src
│   ├── db
│   │   └── index.ts
│   ├── migrations
│   │   └── 20180407084900-example-migration.ts
│   └── models
│       └── exampleUserModel.ts
├── tsconfig.json
└── yarn.lock

4 directories, 6 files

src/db/index.ts

import { DB, MigrationConfig, DBConfig } from '@seanmcgary/database';
import * as path from 'path';

import exampleUserModel from '../models/exampleUserModel';

const databaseConfig = {
	username: 'some-username',
	password: 'some-password',
	database: 'example-db',
	host: '127.0.0.1'
};

const migrationConfig  = {
	path: path.normalize(`${__dirname}/../migrations`)
};

const db = new DB(
	<DBConfig>databaseConfig,
	<MigrationConfig>migrationConfig
);

db.init((db: DB) => {
	const User = db.setModel('User', db.loadModel(exampleUserModel));
});

db.migrate();

export default db;

src/models/exampleUserModel.ts

import { Sequelize, ModelOptions, Model, DataTypes, BuildOptions, ModelAttributes } from 'sequelize';
import { ModelWrapper, StaticModel, AllowedFields, FieldMessages } from '@seanmcgary/database';

export interface UserInstanceFields {
	password: string;
	username: string;
	email: string;
}

// tslint:disable-next-line:no-any
export interface UserInstance extends UserInstanceFields, Model {
	doesPasswordMatch(storedPassword: string, providedPassword: string): boolean;
	toJSON(sanitize?: boolean): UserInstanceFields;
}

type UserInstanceStatic = StaticModel<UserInstance>;

export class User extends ModelWrapper<UserInstance, UserInstanceStatic> {
	constructor(db: Sequelize, modelName: string, attributes: ModelAttributes, options: ModelOptions) {
		super(db, modelName, attributes, options);
	}

	get allowedFields(): AllowedFields {
		return {
			create: ['email', 'password', 'username'],
			update: ['email', 'password', 'username']
		};
	}

	get fieldMessages(): FieldMessages {
		return User.fieldMessages;
	}

	static get fieldMessages(): FieldMessages {
		return {
			email: {
				invalid: 'Please provide a valid email address'
			},
			password: {
				invalid: 'Password must be at least 8 characters'
			},
			username: {
				invalid: 'Please provide a valid username',
				unique: 'That username is already taken'
			}
		};
	}
}

export default function(db: Sequelize): User {
	return new User(db, 'users', {
		email: {
			type: DataTypes.STRING,
			allowNull: true,
			defaultValue: null,
			validate: {
				isEmail: true,
				notEmpty: true
			}
		},
		username: {
			type: DataTypes.STRING,
			allowNull: false,
			validate: {
				notEmpty: true,
				len: [1, 128]
			},
			unique: true
		},
		password: {
			type: DataTypes.STRING,
			allowNull: false,
			validate: {
				len: [8, 255]
			}
		}
	}, {
		freezeTableName: true,
		timestamps: true
	});
}

Readme

Keywords

none

Package Sidebar

Install

npm i @seanmcgary/database

Weekly Downloads

0

Version

3.3.1

License

MIT

Unpacked Size

126 kB

Total Files

23

Last publish

Collaborators

  • smcgary