### Initialization Flow Example Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/MANIFEST.txt Provides an example of the typical initialization flow for Sequelize-TypeScript, including configuration and model loading. ```typescript import { Sequelize } from 'sequelize-typescript'; async function initializeSequelize() { const sequelize = new Sequelize({ dialect: 'sqlite', storage: ':memory:', models: [__dirname + '/models'], // Load models from the models directory // Other Sequelize options... }); try { await sequelize.authenticate(); console.log('Connection has been established successfully.'); await sequelize.sync(); // Sync models to the database console.log('Database synchronized.'); } catch (error) { console.error('Unable to connect to the database:', error); } return sequelize; } initializeSequelize().then(sequelize => { // Use the sequelize instance here }); ``` -------------------------------- ### Scope Application Example Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/MANIFEST.txt Demonstrates how to apply scopes to queries. ```typescript import { Table, Column, Model, Scopes } from 'sequelize-typescript'; @Table export class Post extends Model { @Column title: string; @Column published: boolean; @Scopes(() => ({ published: { where: { published: true } }, with_title: (title: string) => ({ where: { title } }) })) static readonly scopes: {}; } // Applying scopes const publishedPosts = await Post.scope('published').findAll(); const specificPost = await Post.scope({ method: ['with_title', 'My Post Title'] }).findOne(); ``` -------------------------------- ### Model Initialization Example Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/MANIFEST.txt Demonstrates the full initialization process for models using Sequelize-TypeScript. ```typescript import { Sequelize } from 'sequelize-typescript'; import * as path from 'path'; const sequelize = new Sequelize({ dialect: 'sqlite', storage: ':memory:', models: [__dirname + '/models/**/*.ts'], // or path.join(__dirname, '/models') // If you are using TypeScript, you might want to use the 'sequelize-typescript' module // which provides decorators and model synchronization. // For example: // import { User } from './models/User'; // import { Post } from './models/Post'; // const sequelize = new Sequelize({ // // ... other options // models: [User, Post] // }); }); ``` -------------------------------- ### Model Definition Example Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/MANIFEST.txt Example of defining a User model with various column decorators. ```typescript import { Table, Column, Model, DataType, PrimaryKey, AutoIncrement, Unique, AllowNull, Default, Comment, Index, CreatedAt, UpdatedAt, DeletedAt, ForeignKey, BelongsTo, HasMany, HasOne, BelongsToMany, Scopes, DefaultScope } from 'sequelize-typescript'; @Table export class User extends Model { @PrimaryKey @AutoIncrement @Column id: number; @Unique @AllowNull(false) @Column username: string; @Default(0) @Column points: number; @Comment('This is a comment') @Index @Column bio: string; @CreatedAt creationDate; @UpdatedAt updateTimestamp; @DeletedAt deletionTimestamp; @ForeignKey(() => Role) @Column roleId: number; @BelongsTo(() => Role) role: Role; @HasMany(() => Post) posts: Post[]; @HasOne(() => Profile) profile: Profile; @BelongsToMany(() => Group, () => UserGroup) groups: Group[]; @Scopes(() => ({ default: { where: { active: true } }, with_posts: { include: [Post] } })) static readonly scopes: {}; @DefaultScope static readonly defaultScope: {} = { where: { active: true } }; } ``` -------------------------------- ### Custom Metadata Access Example Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/MANIFEST.txt Example of accessing custom metadata stored on a model. ```typescript import { Model, Column, Table, DataType } from 'sequelize-typescript'; @Table export class User extends Model { @Column name: string; @Column({ // Custom metadata can be added here _custom: { someValue: 123, anotherValue: 'abc' } }) email: string; } // Accessing custom metadata const emailColumn = User.rawAttributes.email; const customMetadata = emailColumn.fieldOptions._custom; console.log(customMetadata.someValue); // 123 console.log(customMetadata.anotherValue); // abc ``` -------------------------------- ### Complete Example: Model Definitions Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/MANIFEST.txt Shows complete model definitions for User, Post, Comment, Role, and UserRole, including relationships and decorators. ```typescript import { Sequelize, Model, Table, Column, DataType, ForeignKey, BelongsTo, HasMany, BelongsToMany } from 'sequelize-typescript'; // User Model @Table export class User extends Model { @Column({ primaryKey: true, autoIncrement: true, type: DataType.INTEGER }) id!: number; @Column({ allowNull: false, unique: true, type: DataType.STRING }) username!: string; @HasMany(() => Post) posts!: Post[]; @BelongsToMany(() => Role, () => UserRole) roles!: Role[]; } // Post Model @Table export class Post extends Model { @Column({ primaryKey: true, autoIncrement: true, type: DataType.INTEGER }) id!: number; @Column({ allowNull: false, type: DataType.STRING }) title!: string; @Column({ type: DataType.TEXT }) content!: string; @ForeignKey(() => User) @Column({ allowNull: false, type: DataType.INTEGER }) userId!: number; @BelongsTo(() => User) user!: User; @HasMany(() => Comment) comments!: Comment[]; } // Comment Model @Table export class Comment extends Model { @Column({ primaryKey: true, autoIncrement: true, type: DataType.INTEGER }) id!: number; @Column({ type: DataType.TEXT }) content!: string; @ForeignKey(() => Post) @Column({ allowNull: false, type: DataType.INTEGER }) postId!: number; @ForeignKey(() => User) @Column({ allowNull: false, type: DataType.INTEGER }) userId!: number; @BelongsTo(() => Post) post!: Post; @BelongsTo(() => User) user!: User; } // Role Model @Table export class Role extends Model { @Column({ primaryKey: true, autoIncrement: true, type: DataType.INTEGER }) id!: number; @Column({ allowNull: false, unique: true, type: DataType.STRING }) name!: string; @BelongsToMany(() => User, () => UserRole) users!: User[]; } // UserRole Join Model @Table export class UserRole extends Model { @ForeignKey(() => User) @Column({ primaryKey: true, type: DataType.INTEGER }) userId!: number; @ForeignKey(() => Role) @Column({ primaryKey: true, type: DataType.INTEGER }) roleId!: number; @BelongsTo(() => User) user!: User; @BelongsTo(() => Role) role!: Role; } // Example of initializing Sequelize with these models // const sequelize = new Sequelize({ // dialect: 'sqlite', // storage: ':memory:', // models: [User, Post, Comment, Role, UserRole] // }); ``` -------------------------------- ### Install sequelize-typescript and Dependencies Source: https://github.com/sequelize/sequelize-typescript/blob/master/README.md Install the necessary development and runtime dependencies for sequelize-typescript. This includes types for Node and validator, along with sequelize, reflect-metadata, and sequelize-typescript itself. ```sh npm install --save-dev @types/node @types/validator npm install sequelize reflect-metadata sequelize-typescript ``` -------------------------------- ### Sequelize Initialization with Model Matching Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/05-sequelize-configuration.md Example of initializing Sequelize with custom model paths and a model matching function to load entities. ```typescript const sequelize = new Sequelize({ models: [__dirname + '/models/**/*.entity.ts'], modelMatch: (filename, member) => { // Match: user.entity.ts -> User class const baseName = filename.substring(0, filename.lastIndexOf('.entity')); return baseName === member.toLowerCase(); }, }); ``` -------------------------------- ### Raw Query Example Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/MANIFEST.txt Demonstrates how to execute raw SQL queries using Sequelize-TypeScript's query method. ```typescript import { Sequelize } from 'sequelize-typescript'; // Assume Sequelize is initialized // const sequelize = new Sequelize(...); async function executeRawQuery() { const query = 'SELECT * FROM users WHERE username = :username'; const replacements = { username: 'testuser' }; try { const users = await sequelize.query(query, { replacements: replacements, model: User, // Specify the model to map results to mapToModel: true, raw: false // Set to true to get plain JSON objects }); console.log('Raw query result:', users.map(u => u.toJSON())); } catch (error) { console.error('Error executing raw query:', error); } } // executeRawQuery(); ``` -------------------------------- ### Connection Pooling Configuration Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/MANIFEST.txt Example of configuring connection pooling for Sequelize. ```typescript import { Sequelize } from 'sequelize-typescript'; const sequelize = new Sequelize({ dialect: 'postgres', host: 'localhost', username: 'user', password: 'password', database: 'database', pool: { max: 5, // maximum number of connections in the pool min: 0, // minimum number of connections in the pool acquire: 30000, // maximum time (ms) that pool will try to get connection before throwing error idle: 10000 // the maximum time (ms) a connection can be idle before being released } }); ``` -------------------------------- ### Transaction Example Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/MANIFEST.txt Demonstrates how to perform multiple database operations atomically within a transaction. ```typescript import { Sequelize, Model, Table, Column, DataType } from 'sequelize-typescript'; // Assume User and Account models are defined and associated // const sequelize = new Sequelize(...); // sequelize.addModels([User, Account]); async function performTransaction() { try { await sequelize.transaction(async (transaction) => { // Create a user const user = await User.create({ username: 'trans_user', email: 'trans@example.com' }, { transaction }); // Create an account for the user const account = await Account.create({ accountNumber: '123456789', userId: user.id }, { transaction }); console.log('Transaction successful:', { user: user.toJSON(), account: account.toJSON() }); // If any error occurs within this block, the transaction will be rolled back. }); } catch (error) { console.error('Transaction failed:', error); } } // performTransaction(); ``` -------------------------------- ### Complex Query Example Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/MANIFEST.txt Shows an example of a complex query involving multiple includes, where clauses, and orderings. ```typescript import { Sequelize, Model, Table, Column, DataType, ForeignKey, HasMany, BelongsTo, Order, WhereOptions } from 'sequelize-typescript'; // Assume User, Post, and Comment models are defined and associated // const sequelize = new Sequelize(...); // sequelize.addModels([User, Post, Comment]); async function complexQuery() { const userIdToFind = 1; const minComments = 2; const postsWithComments: Order[] = [['createdAt', 'DESC']]; const whereClause: WhereOptions = { '$user.id$': userIdToFind, '$comments.length$': { [Sequelize.Op.gte]: minComments // Requires Sequelize.Op } }; const results = await Post.findAll({ include: [ { model: User, where: { id: userIdToFind } // Filter by user ID }, { model: Comment, required: true // Ensures only posts with comments are returned } ], where: whereClause, order: postsWithComments, group: ['Post.id', 'User.id', 'Comments.id'], // Grouping might be needed depending on query complexity having: Sequelize.literal('COUNT(DISTINCT "Comments"."id") >= :minComments', { minComments: minComments }) }); console.log('Complex query results:', results.map(p => p.toJSON())); } // complexQuery(); ``` -------------------------------- ### Validation Error Example Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/MANIFEST.txt Example demonstrating how validation errors are thrown and how to handle them. ```typescript import { Table, Column, Model, Validate } from 'sequelize-typescript'; @Table export class Product extends Model { @Column name: string; @Validate({ isNumeric: true, min: 10 }) @Column price: number; } async function createProduct() { try { await Product.create({ name: 'Test Product', price: 5 // This will fail validation }); } catch (error) { console.error('Validation Error:', error.errors); // error.errors will contain an array of validation error objects } } ``` -------------------------------- ### Repository Mode Example Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/MANIFEST.txt Demonstrates the usage of Sequelize-TypeScript in repository mode, providing a more object-oriented approach to data access. ```typescript import { Sequelize, Repository } from 'sequelize-typescript'; import { User } from './models/User'; const sequelize = new Sequelize({ dialect: 'sqlite', storage: ':memory:', repositoryMode: true, // Enable repository mode models: [User] }); async function run() { const userRepository: Repository = sequelize.getRepository(User); // Create a new user const newUser = await userRepository.create({ username: 'testuser' }); await newUser.save(); // Find users const users = await userRepository.findAll(); console.log(users); } run(); ``` -------------------------------- ### Sequelize-TypeScript Model Initialization Flow Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/09-initialization-and-patterns.md Demonstrates the complete process of defining models with decorators, creating a Sequelize instance, adding models, and performing basic operations. This example covers model definition, instance creation, and model addition, leading to ready-to-use models. ```typescript 1. Define Model Classes with Decorators ↓ 2. Create Sequelize Instance ↓ 3. Call sequelize.addModels() ↓ 4. Read Decorator Metadata - @Table: model options - @Column: column definitions - @Index: index definitions - @ForeignKey, @BelongsTo, etc: associations - @Scopes, @DefaultScope: scopes - @Hook decorators: lifecycle hooks ↓ 5. Initialize Models via Model.initialize() ↓ 6. Establish Associations via model.associate() ↓ 7. Resolve Scopes ↓ 8. Install Hooks ↓ 9. Models Ready for Use ``` ```typescript @Table class User extends Model { @Column name: string; @HasMany(() => Post) posts: Post[]; } @Table class Post extends Model { @Column title: string; @ForeignKey(() => User) @Column userId: number; @BelongsTo(() => User) author: User; } // 2. Create Sequelize instance const sequelize = new Sequelize({ dialect: 'sqlite', storage: ':memory:', }); // 3. Add models (triggers steps 4-8) sequelize.addModels([User, Post]); // 9. Models are now ready const user = await User.create({ name: 'John' }); const post = await Post.create({ title: 'Hello', userId: user.id }); ``` -------------------------------- ### Using Repository Mode for CRUD Operations Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/05-sequelize-configuration.md Demonstrates how to get a repository instance and perform create, find, update, and delete operations on a User model. ```typescript @Table class User extends Model { @Column name: string; } const sequelize = new Sequelize({ repositoryMode: true, models: [User], dialect: 'sqlite', storage: ':memory:', }); const userRepository = sequelize.getRepository(User); // Create const user = await userRepository.create({ name: 'John' }); // Find const users = await userRepository.findAll(); const user = await userRepository.findOne({ where: { id: 1 } }); // Update await userRepository.update({ name: 'Jane' }, { where: { id: 1 } }); // Delete await userRepository.destroy({ where: { id: 1 } }); ``` -------------------------------- ### Hook Execution Example Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/MANIFEST.txt Illustrates how to define and use hooks for model lifecycle events. ```typescript import { Table, Column, Model, BeforeCreate, AfterCreate, BeforeUpdate, AfterUpdate, BeforeDestroy, AfterDestroy } from 'sequelize-typescript'; @Table export class Post extends Model { @Column title: string; @BeforeCreate static async beforeCreateHook(instance: Post) { console.log('Before create hook:', instance.title); } @AfterCreate static async afterCreateHook(instance: Post) { console.log('After create hook:', instance.title); } @BeforeUpdate static async beforeUpdateHook(instance: Post) { console.log('Before update hook:', instance.title); } @AfterUpdate static async afterUpdateHook(instance: Post) { console.log('After update hook:', instance.title); } @BeforeDestroy static async beforeDestroyHook(instance: Post) { console.log('Before destroy hook:', instance.title); } @AfterDestroy static async afterDestroyHook(instance: Post) { console.log('After destroy hook:', instance.title); } } ``` -------------------------------- ### Model Definition Example Source: https://github.com/sequelize/sequelize-typescript/blob/master/README.md An example of a model class exported for sequelize-typescript to discover. The class name is used for matching against filenames. ```typescript // File User.ts matches the following exported model. export class User extends Model {} ``` -------------------------------- ### Model Definition and Usage Example Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/01-model-decorators.md Demonstrates how to define a User model using decorators and perform common operations like creating, finding, and managing relations. ```typescript @Table class User extends Model<{ id: number; name: string }, { name: string }> { @Column @PrimaryKey id: number; @Column name: string; } // Creating const user = new User({ name: 'John' }); await user.save(); // Finding const found = await User.findOne({ where: { id: 1 } }); // Relations const posts = await user.$get('posts'); await user.$add('post', post); ``` -------------------------------- ### Create User Instance with ModelType Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/06-types-reference.md Example demonstrating how to use the ModelType to define a specific model constructor (UserType) and create new model instances. ```typescript type UserType = ModelType<{ name: string }, { id: number; name: string }>; function createUser(ModelClass: UserType, data: any): Model { return new ModelClass(data); } ``` -------------------------------- ### Comprehensive Validation Example Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/02-column-decorators.md This example demonstrates the combined usage of multiple validation decorators (@IsEmail, @Length, @IsUrl, @IsInt, @Min, @Max) along with other column decorators (@AllowNull, @Unique) in a Sequelize-TypeScript model. ```typescript @Table class User extends Model { @Column @IsEmail @AllowNull(false) @Unique email: string; @Column @Length({ min: 3, max: 50 }) @AllowNull(false) name: string; @Column @IsUrl @AllowNull(true) website: string; @Column @IsInt @Min(0) @Max(120) age: number; } ``` -------------------------------- ### Association Typing Example Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/MANIFEST.txt Illustrates how to properly type associations between models. ```typescript import { Table, Column, Model, ForeignKey, BelongsTo, HasMany } from 'sequelize-typescript'; export class Role extends Model { @Column name: string; } @Table export class User extends Model { @Column username: string; @ForeignKey(() => Role) @Column roleId: number; @BelongsTo(() => Role) role: Role; } @Table export class Post extends Model { @Column title: string; @ForeignKey(() => User) @Column authorId: number; @BelongsTo(() => User) author: User; @HasMany(() => Comment) comments: Comment[]; } @Table export class Comment extends Model { @Column text: string; @ForeignKey(() => Post) @Column postId: number; @BelongsTo(() => Post) post: Post; } ``` -------------------------------- ### Association Usage Example Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/MANIFEST.txt Shows how to use defined associations to fetch related data, like posts for a user. ```typescript import { Sequelize, Model, Table, Column, DataType, ForeignKey, HasMany, BelongsTo } from 'sequelize-typescript'; // Assume User and Post models are defined with a HasMany association // @Table // export class User extends Model { // @Column({ primaryKey: true, autoIncrement: true }) id!: number; // @Column username!: string; // @HasMany(() => Post) posts!: Post[]; // } // @Table // export class Post extends Model { // @Column({ primaryKey: true, autoIncrement: true }) id!: number; // @Column title!: string; // @ForeignKey(() => User) userId!: number; // @BelongsTo(() => User) user!: User; // } // Assume Sequelize is initialized and models are added // const sequelize = new Sequelize(...); // sequelize.addModels([User, Post]); async function useAssociations() { // Create a user and some posts const user = await User.create({ username: 'assoc_user' }); await Post.create({ title: 'First Post', userId: user.id }); await Post.create({ title: 'Second Post', userId: user.id }); // Find a user and include their posts const foundUser = await User.findOne({ where: { username: 'assoc_user' }, include: [Post] }); if (foundUser) { console.log(`User: ${foundUser.username}`); console.log('Posts:'); foundUser.posts.forEach(post => { console.log(`- ${post.title}`); }); } } // useAssociations(); ``` -------------------------------- ### Hook Execution Example Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/MANIFEST.txt Illustrates the execution flow of hooks during model operations like create, update, and destroy. ```typescript import { Table, Column, Model, BeforeCreate, AfterCreate, BeforeUpdate, AfterUpdate, BeforeDestroy, AfterDestroy } from 'sequelize-typescript'; @Table export class Task extends Model { @Column({ primaryKey: true, autoIncrement: true, type: DataType.INTEGER }) id!: number; @Column({ allowNull: false, type: DataType.STRING }) description!: string; @Column({ defaultValue: false, type: DataType.BOOLEAN }) completed!: boolean; @BeforeCreate static async beforeCreateHook(instance: Task) { console.log(`[Task Hook] Before creating task: ${instance.description}`); } @AfterCreate static async afterCreateHook(instance: Task) { console.log(`[Task Hook] After creating task: ${instance.id}`); } @BeforeUpdate static async beforeUpdateHook(instance: Task) { console.log(`[Task Hook] Before updating task: ${instance.id}`); } @AfterUpdate static async afterUpdateHook(instance: Task) { console.log(`[Task Hook] After updating task: ${instance.id}`); } @BeforeDestroy static async beforeDestroyHook(instance: Task) { console.log(`[Task Hook] Before destroying task: ${instance.id}`); } @AfterDestroy static async afterDestroyHook(instance: Task) { console.log(`[Task Hook] After destroying task: ${instance.id}`); } } // Assume Sequelize is initialized and Task model is added // const sequelize = new Sequelize(...); // sequelize.addModels([Task]); async function executeHooks() { const task = await Task.create({ description: 'Learn Sequelize hooks' }); task.completed = true; await task.save(); await task.destroy(); } // executeHooks(); ``` -------------------------------- ### Project Dependencies Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/07-complete-example.md Install the necessary packages for sequelize-typescript. Includes sequelize, sequelize-typescript, and reflect-metadata. ```json { "dependencies": { "sequelize": "^6.29.0", "sequelize-typescript": "^2.1.6", "reflect-metadata": "^0.1.13" }, "devDependencies": { "@types/node": "^18.0.0", "@types/validator": "^13.0.0", "typescript": "^4.8.0" } } ``` -------------------------------- ### ModelMatch Type Definition and Example Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/06-types-reference.md Defines a custom matching function for discovering model files. The example shows how to match a filename like 'user.model.ts' to a class named 'User'. ```typescript type ModelMatch = (filename: string, member: string) => boolean ``` ```typescript const modelMatch = (filename: string, member: string): boolean => { // Match user.model.ts to User class const baseName = filename.substring(0, filename.lastIndexOf('.model')); return baseName === member.toLowerCase(); }; ``` -------------------------------- ### Custom Validator Implementation Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/MANIFEST.txt Example of creating and using a custom validator. ```typescript import { Table, Column, Model, Validate, BeforeValidate } from 'sequelize-typescript'; @Table export class User extends Model { @Column name: string; @Validate({ isCustomEmail: (value: string) => { if (!value.endsWith('@example.com')) { throw new Error('Email must be from example.com'); } } }) @Column email: string; @BeforeValidate static async beforeValidateHook(instance: User) { console.log('Before validation:', instance.email); } } ``` -------------------------------- ### Get Repository and Create/Find User Source: https://github.com/sequelize/sequelize-typescript/blob/master/README.md Retrieve a repository for a specific model to create new instances or perform search operations. Use `getRepository` to obtain the repository instance. ```typescript const userRepository = sequelize.getRepository(User); const luke = await userRepository.create({ name: 'Luke Skywalker' }); const luke = await userRepository.findOne({ where: { name: 'luke' } }); ``` -------------------------------- ### Validation Usage Example Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/MANIFEST.txt Shows how to apply validation decorators to ensure data integrity before saving to the database. ```typescript import { Sequelize, Model, Table, Column, DataType, IsEmail, Min, NotEmpty } from 'sequelize-typescript'; @Table export class Registration extends Model { @Column({ primaryKey: true, autoIncrement: true, type: DataType.INTEGER }) id!: number; @NotEmpty @Column({ allowNull: false, type: DataType.STRING }) name!: string; @IsEmail @Column({ allowNull: false, unique: true, type: DataType.STRING }) email!: string; @Min(18) @Column({ type: DataType.INTEGER }) age?: number; } // Assume Sequelize is initialized and Registration model is added // const sequelize = new Sequelize(...); // sequelize.addModels([Registration]); async function useValidation() { try { // This will succeed const validUser = await Registration.create({ name: 'Valid User', email: 'valid@example.com', age: 30 }); console.log('Valid user created:', validUser.toJSON()); // This will fail due to validation errors await Registration.create({ name: '', // Fails NotEmpty email: 'invalid-email', age: 15 // Fails Min(18) }); } catch (error: any) { console.error('Validation Errors:', error.errors.map((e: any) => e.message)); } } // useValidation(); ``` -------------------------------- ### Sequelize-TypeScript Hook Execution Example Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/09-initialization-and-patterns.md Shows how to define and use lifecycle hooks like BeforeValidate, BeforeCreate, BeforeSave, and AfterCreate in a sequelize-typescript model. ```typescript @Table class User extends Model { @Column email: string; @BeforeValidate static beforeValidate(instance: User): void { console.log('1. BeforeValidate'); // Normalize email instance.email = instance.email.toLowerCase(); } @BeforeCreate static beforeCreate(instance: User): void { console.log('2. BeforeCreate'); // Set defaults } @BeforeSave static beforeSave(instance: User): void { console.log('3. BeforeSave'); // Final preparations } @AfterCreate static afterCreate(instance: User): void { console.log('4. AfterCreate'); // Emit events, log, etc. } } // Output when calling User.create({ email: 'JOHN@EXAMPLE.COM' }): // 1. BeforeValidate // 2. BeforeCreate // 3. BeforeSave // 4. AfterCreate // email is now 'john@example.com' ``` -------------------------------- ### Modern Scope Syntax with Decorators Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/04-hooks-scopes-indexes.md Demonstrates the modern syntax for defining default and named scopes using decorators with functions. Usage examples show how to apply these scopes. ```typescript @DefaultScope(() => ({ attributes: ['id', 'name', 'email'], where: { active: true } })) @Scopes(() => ({ withPosts: { include: [() => Post], }, inactive: { where: { active: false }, }, recent: { where: { createdAt: { [Op.gte]: sequelize.where( sequelize.fn('DATE_SUB', sequelize.fn('NOW'), sequelize.literal('INTERVAL 7 DAY')), Op.lte, sequelize.col('createdAt') ) } }, }, })) @Table class User extends Model { @Column name: string; @Column email: string; @Column active: boolean; @HasMany(() => Post) posts: Post[]; } // Usage const activeUsers = await User.findAll(); // Uses defaultScope const allUsers = await User.unscoped().findAll(); // Ignores default scope const usersPosts = await User.scope('withPosts').findAll(); const inactiveUsers = await User.scope('inactive').findAll(); const recentUsers = await User.scope('recent').findAll(); ``` -------------------------------- ### Scope Usage Example Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/MANIFEST.txt Demonstrates how to apply named scopes defined on a model to filter query results. ```typescript import { Sequelize, Model, Table, Column, DataType, Scopes } from 'sequelize-typescript'; @Scopes({ active: { where: { active: true } }, recent: { order: [['createdAt', 'DESC']], limit: 5 } }) @Table export class Article extends Model
{ @Column({ primaryKey: true, autoIncrement: true, type: DataType.INTEGER }) id!: number; @Column({ allowNull: false, type: DataType.STRING }) title!: string; @Column({ type: DataType.TEXT }) content!: string; @Column({ defaultValue: true, type: DataType.BOOLEAN }) active!: boolean; @Column({ type: DataType.DATE }) createdAt!: Date; } // Assume Sequelize is initialized and Article model is added // const sequelize = new Sequelize(...); // sequelize.addModels([Article]); async function useScopes() { // Create some articles await Article.create({ title: 'Active Article 1', active: true }); await Article.create({ title: 'Inactive Article', active: false }); await Article.create({ title: 'Active Article 2', active: true }); // Find active articles using the 'active' scope const activeArticles = await Article.scope('active').findAll(); console.log('Active Articles:', activeArticles.map(a => a.toJSON())); // Find recent articles using the 'recent' scope const recentArticles = await Article.scope('recent').findAll(); console.log('Recent Articles:', recentArticles.map(a => a.toJSON())); // Combine scopes (if supported by Sequelize version or custom implementation) // const activeAndRecent = await Article.scope(['active', 'recent']).findAll(); } // useScopes(); ``` -------------------------------- ### Example Code Snippet Placeholder Source: https://github.com/sequelize/sequelize-typescript/blob/master/ISSUE_TEMPLATE.md This section is a placeholder for users to insert relevant code snippets, such as tsconfig and sequelize options, to illustrate their issue or feature request. ```typescript insert short code snippets here ``` -------------------------------- ### Instance Method: $get Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/01-model-decorators.md Retrieves related instance(s) specified by a property key. This method is used to fetch associated data. ```typescript $get( propertyKey: K, options?: AssociationGetOptions ): Promise<$GetType> ``` -------------------------------- ### Sequelize Data Type Usage Example Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/05-sequelize-configuration.md Demonstrates how to use various Sequelize data types to define model columns in a TypeScript class. ```typescript @Table class Product extends Model { @Column(DataType.STRING(255)) name: string; @Column(DataType.TEXT) description: string; @Column(DataType.DECIMAL(10, 2)) price: number; @Column(DataType.INTEGER) quantity: number; @Column(DataType.BOOLEAN) isActive: boolean; @Column(DataType.ENUM('draft', 'published', 'archived')) status: string; @Column(DataType.JSON) metadata: any; @Column(DataType.DATE) publishedAt: Date; } ``` -------------------------------- ### getRepository Method Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/05-sequelize-configuration.md Gets a repository for a model, enabling repository pattern usage. This is useful for abstracting data access operations. ```APIDOC #### getRepository Gets a repository for a model in repository mode. ```typescript getRepository(modelClass: new () => M): Repository ``` **Parameters:** | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | modelClass | `new () => M` | Yes | The model class | **Returns:** Repository instance for the model **Example:** ```typescript const userRepository = sequelize.getRepository(User); const user = await userRepository.create({ name: 'John' }); const users = await userRepository.findAll(); ``` ``` -------------------------------- ### Model Definition with Custom Matching Source: https://github.com/sequelize/sequelize-typescript/blob/master/README.md An example TypeScript model file demonstrating custom matching logic. It exports a constant and a model class, where only the class is intended to be matched. ```TypeScript //user.model.ts import {Table, Column, Model} from 'sequelize-typescript'; export const UserN = 'Not a model'; export const NUser = 'Not a model'; @Table export class User extends Model { @Column nickname: string; } ``` -------------------------------- ### Sequelize-TypeScript Model Validation Example Source: https://github.com/sequelize/sequelize-typescript/blob/master/README.md Demonstrates various validation decorators for model fields, including UUID, equality, containment, length, URL, custom regex, date, and before date validations. ```typescript const HEX_REGEX = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/; @Table export class Shoe extends Model { @IsUUID(4) @PrimaryKey @Column id: string; @Equals('lala') @Column readonly key: string; @Contains('Special') @Column special: string; @Length({ min: 3, max: 15 }) @Column brand: string; @IsUrl @Column brandUrl: string; @Is('HexColor', (value) => { if (!HEX_REGEX.test(value)) { throw new Error(`"${value}" is not a hex color value.`); } }) @Column primaryColor: string; @Is(function hexColor(value: string): void { if (!HEX_REGEX.test(value)) { throw new Error(`"${value}" is not a hex color value.`); } }) @Column secondaryColor: string; @Is(HEX_REGEX) @Column tertiaryColor: string; @IsDate @IsBefore('2017-02-27') @Column producedAt: Date; } ``` -------------------------------- ### Usage of @HasOne Association Methods Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/03-association-decorators.md After defining a @HasOne relationship, Sequelize generates methods to interact with the associated model. These include getting, setting, creating, and destroying the associated instance. This example demonstrates fetching a user with their profile and then accessing and setting the profile. ```typescript // Usage const user = await User.findOne({ include: [Profile] }); const profile = await user.$get('profile'); await user.$set('profile', profile); ``` -------------------------------- ### Sequelize Initialization and Patterns Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/MANIFEST.txt Covers the step-by-step model initialization process, decorator metadata, model resolution, associations, lifecycle events, scopes, validation, and type safety patterns. ```APIDOC ## Initialization and Patterns ### Description This section details the process of initializing models with Sequelize-TypeScript, including explanations of decorator metadata storage, model resolution for associations, handling circular dependencies, and understanding model lifecycle events. ### Key Concepts - **Model Initialization Flow**: Step-by-step guide to setting up your models. - **Decorator Metadata**: Explanation of how decorators store metadata. - **Model Resolution**: How models are found and associated. - **Circular Dependencies**: Strategies for managing dependencies between models. - **Lifecycle Events**: Understanding hooks for create, update, and delete operations. - **Scopes**: How to define and apply scopes for query filtering. - **Validation**: The validation flow and how to implement custom validators. - **Type Safety**: Patterns for achieving type safety with interfaces and associations. - **Performance**: Considerations for connection pooling and overall performance. ### Example: Custom Metadata Access ```typescript // Example of accessing custom metadata import { getMetadataStorage } from 'sequelize-typescript'; const metadata = getMetadataStorage(); console.log(metadata.get('customKey')); ``` ### Example: Association Typing ```typescript import { Model, Table, Column, HasMany } from 'sequelize-typescript'; @Table export class User extends Model { @Column name: string; @HasMany(() => Post) posts: Post[]; } @Table export class Post extends Model { @Column title: string; @Column userId: number; } ``` ``` -------------------------------- ### Sequelize Constructor Overloads Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/05-sequelize-configuration.md Demonstrates different ways to instantiate the Sequelize class using connection parameters, a connection URI, or specific dialects like SQLite and PostgreSQL. ```typescript import { Sequelize } from 'sequelize-typescript'; // With connection parameters const sequelize = new Sequelize({ database: 'mydb', username: 'root', password: 'password', host: 'localhost', port: 3306, dialect: 'mysql', models: [__dirname + '/models'], }); // With URI const sequelize = new Sequelize( 'mysql://root:password@localhost:3306/mydb', { models: [__dirname + '/models'], } ); // With SQLite const sequelize = new Sequelize({ dialect: 'sqlite', storage: ':memory:', models: [__dirname + '/models'], }); // With PostgreSQL const sequelize = new Sequelize({ dialect: 'postgres', host: 'localhost', username: 'postgres', password: 'password', database: 'mydb', models: [__dirname + '/models'], }); ``` -------------------------------- ### Sequelize Initialization with Configuration Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/05-sequelize-configuration.md Initialize Sequelize with various configuration options including database credentials, logging, and connection pooling. Models can be passed directly or via a path. ```typescript // Complete initialization example const sequelize = new Sequelize({ database: 'myapp', username: 'root', password: 'password', host: 'localhost', dialect: 'mysql', logging: console.log, // Log all SQL queries pool: { max: 5, min: 0, idle: 10000, }, }); ``` ```typescript // Option 1: Pass models in config const sequelize1 = new Sequelize({ ...config, models: [__dirname + '/models'], }); ``` ```typescript // Option 2: Add models after creation sequelize.addModels([User, Post, Comment]); sequelize.addModels([__dirname + '/models/**/*.model.ts']); ``` -------------------------------- ### Instance Method: $create Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/01-model-decorators.md Creates new instances and relates them to the source instance. This is a convenient way to create and associate data in one step. ```typescript $create( propertyKey: string, values: any, options?: AssociationCreateOptions ): Promise ``` -------------------------------- ### Utility Type for $get() Method Return Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/06-types-reference.md $GetType is a utility type that determines the return type of the $get() method. It returns the array type if the input is an array, otherwise, it returns the single instance type or null. ```typescript type $GetType = NonNullable extends any[] ? NonNullable : NonNullable | null ``` -------------------------------- ### User Model with BeforeCreate, BeforeUpdate, and AfterFind Hooks Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/04-hooks-scopes-indexes.md Demonstrates applying multiple hooks to a User model. BeforeCreate and BeforeUpdate hooks are used to hash the password, while AfterFind removes sensitive data from query results. Ensure the method name is different from the hook name. ```typescript @Table class User extends Model { @Column email: string; @Column password: string; // Method name must be different from hook name @BeforeCreate @BeforeUpdate static hashPassword(instance: User): void { // Hash password before saving instance.password = bcrypt.hashSync(instance.password, 10); } @BeforeCreate static addDefaults(instance: User): void { // Add defaults instance.email = instance.email.toLowerCase(); } @AfterFind static removeSensitiveData(instances: User | User[]): void { // Remove password from result if (Array.isArray(instances)) { instances.forEach(i => delete i.password); } else if (instances) { delete instances.password; } } } ``` -------------------------------- ### Sequelize Class Constructor Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/MANIFEST.txt Illustrates the initialization of the Sequelize class with different database connection options. ```typescript import { Sequelize } from 'sequelize-typescript'; // PostgreSQL example const sequelizePostgres = new Sequelize({ dialect: 'postgres', host: 'localhost', username: 'postgres', password: 'password', database: 'database_name', models: [__dirname + '/models'] // Path to model files }); // MySQL example const sequelizeMysql = new Sequelize('mysql://user:password@host:port/database'); // SQLite example const sequelizeSqlite = new Sequelize({ dialect: 'sqlite', storage: 'database.sqlite', models: [__dirname + '/models'] }); ``` -------------------------------- ### Model.initialize Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/01-model-decorators.md Initializes the model with attributes and options, defining the structure and behavior of a model. ```APIDOC ## initialize Initializes the model with attributes and options. ```typescript static initialize, M extends InstanceType>( attributes: ModelAttributes, options: InitOptions ): MS ``` ### Parameters #### Path Parameters - **attributes** (ModelAttributes) - Required - Column definitions from `@Column` decorators - **options** (InitOptions) - Required - Model options from `@Table` and other decorators ### Returns The model class ``` -------------------------------- ### Create a Model Instance Directly Source: https://github.com/sequelize/sequelize-typescript/blob/master/README.md Instantiate a model and save it to the database in a single step using the `create` method. This is a convenient shortcut for build and save operations. ```typescript Person.create({ name: 'bob', age: 99 }); ``` -------------------------------- ### AssociationGetOptions Type Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/06-types-reference.md Extends Sequelize's FindOptions for use with $get() and $has() association methods. ```typescript interface AssociationGetOptions extends FindOptions { // Inherits from Sequelize FindOptions } ``` -------------------------------- ### Create Sequelize Migration Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/07-complete-example.md Use the sequelize-cli to generate a new migration file for creating a table. ```bash npx sequelize-cli migration:create --name create-users ``` -------------------------------- ### Configure Sequelize Instance with Models Path Source: https://github.com/sequelize/sequelize-typescript/blob/master/README.md Initialize a Sequelize instance with the path to your model files. This ensures all models within the specified directory are loaded. ```typescript import { Sequelize } from 'sequelize-typescript'; const sequelize = new Sequelize({ database: 'some_db', dialect: 'sqlite', username: 'root', password: '', storage: ':memory:', models: [__dirname + '/models'], // or [Player, Team], }); ``` -------------------------------- ### Product Model with BeforeCreate and BeforeUpdate for Slug Generation Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/04-hooks-scopes-indexes.md Shows how to use BeforeCreate and BeforeUpdate hooks on a Product model to automatically generate a URL-friendly slug from the product name. This ensures slugs are consistent for both creation and updates. ```typescript @Table class Product extends Model { @Column name: string; @Column slug: string; @BeforeCreate @BeforeUpdate static generateSlug(instance: Product): void { instance.slug = instance.name.toLowerCase().replace(/\s+/g, '-'); } } ``` -------------------------------- ### Validation Decorator Examples Source: https://github.com/sequelize/sequelize-typescript/blob/master/_autodocs/MANIFEST.txt Demonstrates the usage of various validation decorators to enforce data integrity constraints on model columns. ```typescript import { Column, DataType, Model, Table, AllowNull, Unique, Default, Comment, IsEmail, IsUrl, IsDate, Min, Max, Len, Is, Not, Equals, In, NotEmpty, NotNull, IsAlpha, IsAlphanumeric, IsNumeric, IsUUID, IsIPv4, IsIPv6 } from 'sequelize-typescript'; @Table export class UserProfile extends Model { @AllowNull(false) @IsEmail @Column email!: string; @IsUrl @Column website?: string; @IsDate @Column birthDate?: Date; @Min(18) @Column age?: number; @Max(120) @Column maxAge?: number; @Len(5, 20) @Column username!: string; @Is('^[a-zA-Z]+$', 'custom validation message') @Column customField?: string; @Not('bad_value', 'custom validation message') @Column notField?: string; @Equals('specific_value') @Column equalsField?: string; @In(['admin', 'user', 'guest']) @Column role!: string; @NotEmpty @Column notEmptyField!: string; @NotNull @Column notNullField!: string; @IsAlpha @Column alphaField?: string; @IsAlphanumeric @Column alphanumericField?: string; @IsNumeric @Column numericField?: string; @IsUUID(4) @Column uuidField?: string; @IsIPv4 @Column ipv4Field?: string; @IsIPv6 @Column ipv6Field?: string; } ```