Gathering detailed insights and metrics for sequelize-typescript
Gathering detailed insights and metrics for sequelize-typescript
Gathering detailed insights and metrics for sequelize-typescript
Gathering detailed insights and metrics for sequelize-typescript
sequelize-typescript-generator
Automatically generates typescript models compatible with sequelize-typescript library (https://www.npmjs.com/package/sequelize-typescript) directly from your source database.
sequelize-typescript-migration-lts
migration tool for sequelize & typescript users
sequelize-typescript-model-migration
Migration tool for sequelize-typescript
sequelize-typescript-migration
migration tool for sequelize & typescript users
Decorators and some other features for sequelize
npm install sequelize-typescript
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
2,796 Stars
1,094 Commits
282 Forks
31 Watching
24 Branches
77 Contributors
Updated on 26 Nov 2024
Minified
Minified + Gzipped
TypeScript (99.76%)
JavaScript (0.2%)
Shell (0.03%)
Cumulative downloads
Total Downloads
Last day
-11.8%
55,992
Compared to previous day
Last week
-2.7%
312,126
Compared to previous week
Last month
18.2%
1,321,029
Compared to previous month
Last year
14.4%
12,904,712
Compared to previous year
1
4
43
Decorators and some other features for sequelize (v6).
() => Model
?sequelize@6
1npm install --save-dev @types/node @types/validator 2npm install sequelize reflect-metadata sequelize-typescript
Your tsconfig.json
needs the following flags:
1"target": "es6", // or a more recent ecmascript version 2"experimentalDecorators": true, 3"emitDecoratorMetadata": true
SequelizeConfig
renamed to SequelizeOptions
modelPaths
property renamed to models
The @Scopes
and @DefaultScope
decorators now take lambda's as options
1@DefaultScope(() => ({...})) 2@Scopes(() => ({...}))
instead of deprecated way:
1@DefaultScope({...}) 2@Scopes({...}))
1import { Table, Column, Model, HasMany } from 'sequelize-typescript'; 2 3@Table 4class Person extends Model { 5 @Column 6 name: string; 7 8 @Column 9 birthday: Date; 10 11 @HasMany(() => Hobby) 12 hobbies: Hobby[]; 13}
1import { Table, Model } from 'sequelize-typescript'; 2 3@Table 4class Person extends Model {}
1import { Optional } from 'sequelize'; 2import { Table, Model } from 'sequelize-typescript'; 3 4interface PersonAttributes { 5 id: number; 6 name: string; 7} 8 9interface PersonCreationAttributes extends Optional<PersonAttributes, 'id'> {} 10 11@Table 12class Person extends Model<PersonAttributes, PersonCreationAttributes> {}
The model needs to extend the Model
class and has to be annotated with the @Table
decorator. All properties that
should appear as a column in the database require the @Column
annotation.
See more advanced example here.
@Table
The @Table
annotation can be used without passing any parameters. To specify some more define options, use
an object literal (all define options
from sequelize are valid):
1@Table({ 2 timestamps: true, 3 ... 4}) 5class Person extends Model {}
Decorator | Description |
---|---|
@Table | sets options.tableName=<CLASS_NAME> and options.modelName=<CLASS_NAME> automatically |
@Table(options: DefineOptions) | sets define options (also sets options.tableName=<CLASS_NAME> and options.modelName=<CLASS_NAME> if not already defined by define options) |
A primary key (id
) will be inherited from base class Model
. This primary key is by default an INTEGER
and has
autoIncrement=true
(This behaviour is a native sequelize thing). The id can easily be overridden by marking another
attribute as primary key. So either set @Column({primaryKey: true})
or use @PrimaryKey
together with @Column
.
@CreatedAt
, @UpdatedAt
, @DeletedAt
Annotations to define custom and type safe createdAt
, updatedAt
and deletedAt
attributes:
1 @CreatedAt 2 creationDate: Date; 3 4 @UpdatedAt 5 updatedOn: Date; 6 7 @DeletedAt 8 deletionDate: Date;
Decorator | Description |
---|---|
@CreatedAt | sets timestamps=true and createdAt='creationDate' |
@UpdatedAt | sets timestamps=true and updatedAt='updatedOn' |
@DeletedAt | sets timestamps=true , paranoid=true and deletedAt='deletionDate' |
@Column
The @Column
annotation can be used without passing any parameters. But therefore it is necessary that
the js type can be inferred automatically (see Type inference for details).
1 @Column 2 name: string;
If the type cannot or should not be inferred, use:
1import {DataType} from 'sequelize-typescript'; 2 3 @Column(DataType.TEXT) 4 name: string;
Or for a more detailed column description, use an object literal (all attribute options from sequelize are valid):
1 @Column({ 2 type: DataType.FLOAT, 3 comment: 'Some value', 4 ... 5 }) 6 value: number;
Decorator | Description |
---|---|
@Column | tries to infer dataType from js type |
@Column(dataType: DataType) | sets dataType explicitly |
@Column(options: AttributeOptions) | sets attribute options |
If you're in love with decorators: sequelize-typescript provides some more of them. The following decorators can be used together with the @Column annotation to make some attribute options easier available:
Decorator | Description | Options |
---|---|---|
@AllowNull(allowNull?: boolean) | sets attribute.allowNull (default is true ) | |
@AutoIncrement | sets attribute.autoIncrement=true | |
@Unique(options? UniqueOptions) | sets attribute.unique=true | UniqueOptions |
@Default(value: any) | sets attribute.defaultValue to specified value | |
@PrimaryKey | sets attribute.primaryKey=true | |
@Comment(value: string) | sets attribute.comment to specified string | |
Validate annotations | see Model validation |
The following types can be automatically inferred from javascript type. Others have to be defined explicitly.
Design type | Sequelize data type |
---|---|
string | STRING |
boolean | BOOLEAN |
number | INTEGER |
bigint | BIGINT |
Date | DATE |
Buffer | BLOB |
Get/set accessors do work as well
1@Table 2class Person extends Model { 3 @Column 4 get name(): string { 5 return 'My name is ' + this.getDataValue('name'); 6 } 7 8 set name(value: string) { 9 this.setDataValue('name', value); 10 } 11}
Except for minor variations sequelize-typescript will work like pure sequelize. (See sequelize docs)
To make the defined models available, you have to configure a Sequelize
instance from sequelize-typescript
(!).
1import { Sequelize } from 'sequelize-typescript'; 2 3const sequelize = new Sequelize({ 4 database: 'some_db', 5 dialect: 'sqlite', 6 username: 'root', 7 password: '', 8 storage: ':memory:', 9 models: [__dirname + '/models'], // or [Player, Team], 10});
Before you can use your models you have to tell sequelize where they can be found. So either set models
in the
sequelize config or add the required models later on by calling sequelize.addModels([Person])
or
sequelize.addModels([__dirname + '/models'])
:
1sequelize.addModels([Person]); 2sequelize.addModels(['path/to/models']);
1import {Sequelize} from 'sequelize-typescript'; 2 3const sequelize = new Sequelize({ 4 ... 5 models: [__dirname + '/**/*.model.ts'] 6}); 7// or 8sequelize.addModels([__dirname + '/**/*.model.ts']);
A model is matched to a file by its filename. E.g.
1// File User.ts matches the following exported model. 2export class User extends Model {}
This is done by comparison of the filename against all exported members. The
matching can be customized by specifying the modelMatch
function in the
configuration object.
For example, if your models are named user.model.ts
, and your class is called
User
, you can match these two by using the following function:
1import {Sequelize} from 'sequelize-typescript'; 2 3const sequelize = new Sequelize({ 4 models: [__dirname + '/models/**/*.model.ts'] 5 modelMatch: (filename, member) => { 6 return filename.substring(0, filename.indexOf('.model')) === member.toLowerCase(); 7 }, 8});
For each file that matches the *.model.ts
pattern, the modelMatch
function
will be called with its exported members. E.g. for the following file
1//user.model.ts 2import {Table, Column, Model} from 'sequelize-typescript'; 3 4export const UserN = 'Not a model'; 5export const NUser = 'Not a model'; 6 7@Table 8export class User extends Model { 9 10 @Column 11 nickname: string; 12}
The modelMatch
function will be called three times with the following arguments.
1user.model UserN -> false 2user.model NUser -> false 3user.model User -> true (User will be added as model)
Another way to match model to file is to make your model the default export.
1export default class User extends Model {}
⚠️ When using paths to add models, keep in mind that they will be loaded during runtime. This means that the path may differ from development time to execution time. For instance, using
.ts
extension within paths will only work together with ts-node.
Instantiation and inserts can be achieved in the good old sequelize way
1const person = Person.build({ name: 'bob', age: 99 }); 2person.save(); 3 4Person.create({ name: 'bob', age: 99 });
but sequelize-typescript also makes it possible to create instances with new
:
1const person = new Person({ name: 'bob', age: 99 }); 2person.save();
Finding and updating entries does also work like using native sequelize. So see sequelize docs for more details.
1Person.findOne().then((person) => { 2 person.age = 100; 3 return person.save(); 4}); 5 6Person.update( 7 { 8 name: 'bobby', 9 }, 10 { where: { id: 1 } } 11).then(() => {});
Relations can be described directly in the model by the @HasMany
, @HasOne
, @BelongsTo
, @BelongsToMany
and @ForeignKey
annotations.
1@Table 2class Player extends Model { 3 @Column 4 name: string; 5 6 @Column 7 num: number; 8 9 @ForeignKey(() => Team) 10 @Column 11 teamId: number; 12 13 @BelongsTo(() => Team) 14 team: Team; 15} 16 17@Table 18class Team extends Model { 19 @Column 20 name: string; 21 22 @HasMany(() => Player) 23 players: Player[]; 24}
That's all, sequelize-typescript does everything else for you. So when retrieving a team by find
1Team.findOne({ include: [Player] }).then((team) => { 2 team.players.forEach((player) => console.log(`Player ${player.name}`)); 3});
the players will also be resolved (when passing include: Player
to the find options)
1@Table 2class Book extends Model { 3 @BelongsToMany(() => Author, () => BookAuthor) 4 authors: Author[]; 5} 6 7@Table 8class Author extends Model { 9 @BelongsToMany(() => Book, () => BookAuthor) 10 books: Book[]; 11} 12 13@Table 14class BookAuthor extends Model { 15 @ForeignKey(() => Book) 16 @Column 17 bookId: number; 18 19 @ForeignKey(() => Author) 20 @Column 21 authorId: number; 22}
To access the through-table instance (instanceOf BookAuthor
in the upper example) type safely, the type
need to be set up manually. For Author
model it can be achieved like so:
1 @BelongsToMany(() => Book, () => BookAuthor) 2 books: Array<Book & {BookAuthor: BookAuthor}>;
For one-to-one use @HasOne(...)
(foreign key for the relation exists on the other model) and
@BelongsTo(...)
(foreign key for the relation exists on this model)
@ForeignKey
, @BelongsTo
, @HasMany
, @HasOne
, @BelongsToMany
APIDecorator | Description |
---|---|
@ForeignKey(relatedModelGetter: () => typeof Model) | marks property as foreignKey for related class |
@BelongsTo(relatedModelGetter: () => typeof Model) | sets SourceModel.belongsTo(RelatedModel, ...) while as is key of annotated property and foreignKey is resolved from source class |
@BelongsTo(relatedModelGetter: () => typeof Model, foreignKey: string) | sets SourceModel.belongsTo(RelatedModel, ...) while as is key of annotated property and foreignKey is explicitly specified value |
@BelongsTo(relatedModelGetter: () => typeof Model, options: AssociationOptionsBelongsTo) | sets SourceModel.belongsTo(RelatedModel, ...) while as is key of annotated property and options are additional association options |
@HasMany(relatedModelGetter: () => typeof Model) | sets SourceModel.hasMany(RelatedModel, ...) while as is key of annotated property and foreignKey is resolved from target related class |
@HasMany(relatedModelGetter: () => typeof Model, foreignKey: string) | sets SourceModel.hasMany(RelatedModel, ...) while as is key of annotated property and foreignKey is explicitly specified value |
@HasMany(relatedModelGetter: () => typeof Model, options: AssociationOptionsHasMany) | sets SourceModel.hasMany(RelatedModel, ...) while as is key of annotated property and options are additional association options |
@HasOne(relatedModelGetter: () => typeof Model) | sets SourceModel.hasOne(RelatedModel, ...) while as is key of annotated property and foreignKey is resolved from target related class |
@HasOne(relatedModelGetter: () => typeof Model, foreignKey: string) | sets SourceModel.hasOne(RelatedModel, ...) while as is key of annotated property and foreignKey is explicitly specified value |
@HasOne(relatedModelGetter: () => typeof Model, options: AssociationOptionsHasOne) | sets SourceModel.hasOne(RelatedModel, ...) while as is key of annotated property and options are additional association options |
@BelongsToMany(relatedModelGetter: () => typeof Model, through: (() => typeof Model)) | sets SourceModel.belongsToMany(RelatedModel, {through: ThroughModel, ...}) while as is key of annotated property and foreignKey /otherKey is resolved from through class |
@BelongsToMany(relatedModelGetter: () => typeof Model, through: (() => typeof Model), foreignKey: string) | sets SourceModel.belongsToMany(RelatedModel, {through: ThroughModel, ...}) while as is key of annotated property, foreignKey is explicitly specified value and otherKey is resolved from through class |
@BelongsToMany(relatedModelGetter: () => typeof Model, through: (() => typeof Model), foreignKey: string, otherKey: string) | sets SourceModel.belongsToMany(RelatedModel, {through: ThroughModel, ...}) while as is key of annotated property and foreignKey /otherKey are explicitly specified values |
@BelongsToMany(relatedModelGetter: () => typeof Model, through: string, foreignKey: string, otherKey: string) | sets SourceModel.belongsToMany(RelatedModel, {through: throughString, ...}) while as is key of annotated property and foreignKey /otherKey are explicitly specified values |
@BelongsToMany(relatedModelGetter: () => typeof Model, options: AssociationOptionsBelongsToMany) | sets SourceModel.belongsToMany(RelatedModel, {through: throughString, ...}) while as is key of annotated property and options are additional association values, including foreignKey and otherKey . |
Note that when using AssociationOptions, certain properties will be overwritten when the association is built, based on reflection metadata or explicit attribute parameters. For example, as
will always be the annotated property's name, and through
will be the explicitly stated value.
sequelize-typescript resolves the foreign keys by identifying the corresponding class references. So if you define a model with multiple relations like
1@Table 2class Book extends Model { 3 @ForeignKey(() => Person) 4 @Column 5 authorId: number; 6 7 @BelongsTo(() => Person) 8 author: Person; 9 10 @ForeignKey(() => Person) 11 @Column 12 proofreaderId: number; 13 14 @BelongsTo(() => Person) 15 proofreader: Person; 16} 17 18@Table 19class Person extends Model { 20 @HasMany(() => Book) 21 writtenBooks: Book[]; 22 23 @HasMany(() => Book) 24 proofedBooks: Book[]; 25}
sequelize-typescript cannot know which foreign key to use for which relation. So you have to add the foreign keys explicitly:
1 2 // in class "Books": 3 @BelongsTo(() => Person, 'authorId') 4 author: Person; 5 6 @BelongsTo(() => Person, 'proofreaderId') 7 proofreader: Person; 8 9 // in class "Person": 10 @HasMany(() => Book, 'authorId') 11 writtenBooks: Book[]; 12 13 @HasMany(() => Book, 'proofreaderId') 14 proofedBooks: Book[];
With the creation of a relation, sequelize generates some method on the corresponding
models. So when you create a 1:n relation between ModelA
and ModelB
, an instance of ModelA
will
have the functions getModelBs
, setModelBs
, addModelB
, removeModelB
, hasModelB
. These functions still exist with sequelize-typescript.
But TypeScript wont recognize them and will complain if you try to access getModelB
, setModelB
or
addModelB
. To make TypeScript happy, the Model.prototype
of sequelize-typescript has $set
, $get
, $add
functions.
1@Table 2class ModelA extends Model { 3 @HasMany(() => ModelB) 4 bs: ModelB[]; 5} 6 7@Table 8class ModelB extends Model { 9 @BelongsTo(() => ModelA) 10 a: ModelA; 11}
To use them, pass the property key of the respective relation as the first parameter:
1const modelA = new ModelA(); 2 3modelA 4 .$set('bs', [ 5 /* instance */ 6 ]) 7 .then(/* ... */); 8modelA.$add('b' /* instance */).then(/* ... */); 9modelA.$get('bs').then(/* ... */); 10modelA.$count('bs').then(/* ... */); 11modelA.$has('bs').then(/* ... */); 12modelA.$remove('bs' /* instance */).then(/* ... */); 13modelA.$create('bs' /* value */).then(/* ... */);
@Index
The @Index
annotation can be used without passing any parameters.
1@Table 2class Person extends Model { 3 @Index // Define an index with default name 4 @Column 5 name: string; 6 7 @Index // Define another index 8 @Column 9 birthday: Date; 10}
To specify index and index field options, use an object literal (see indexes define option):
1@Table 2class Person extends Model { 3 @Index('my-index') // Define a multi-field index on name and birthday 4 @Column 5 name: string; 6 7 @Index('my-index') // Add birthday as the second field to my-index 8 @Column 9 birthday: Date; 10 11 @Index({ 12 // index options 13 name: 'job-index', 14 parser: 'my-parser', 15 type: 'UNIQUE', 16 unique: true, 17 where: { isEmployee: true }, 18 concurrently: true, 19 using: 'BTREE', 20 operator: 'text_pattern_ops', 21 prefix: 'test-', 22 // index field options 23 length: 10, 24 order: 'ASC', 25 collate: 'NOCASE', 26 }) 27 @Column 28 jobTitle: string; 29 30 @Column 31 isEmployee: boolean; 32}
Decorator | Description |
---|---|
@Index | adds new index on decorated field to options.indexes |
@Index(name: string) | adds new index or adds the field to an existing index with specified name |
@Table(options: IndexDecoratorOptions) | sets both index and index field options |
createIndexDecorator()
The createIndexDecorator()
function can be used to create a decorator for an index with options specified with an object literal supplied as the argument. Fields are added to the index by decorating properties.
1const SomeIndex = createIndexDecorator(); 2const JobIndex = createIndexDecorator({ 3 // index options 4 name: 'job-index', 5 parser: 'my-parser', 6 type: 'UNIQUE', 7 unique: true, 8 where: { isEmployee: true }, 9 concurrently: true, 10 using: 'BTREE', 11 operator: 'text_pattern_ops', 12 prefix: 'test-', 13}); 14 15@Table 16class Person extends Model { 17 @SomeIndex // Add name to SomeIndex 18 @Column 19 name: string; 20 21 @SomeIndex // Add birthday to SomeIndex 22 @Column 23 birthday: Date; 24 25 @JobIndex({ 26 // index field options 27 length: 10, 28 order: 'ASC', 29 collate: 'NOCASE', 30 }) 31 @Column 32 jobTitle: string; 33 34 @Column 35 isEmployee: boolean; 36}
With sequelize-typescript@1
comes a repository mode. See docs for details.
The repository mode makes it possible to separate static operations like find
, create
, ... from model definitions.
It also empowers models so that they can be used with multiple sequelize instances.
Enable repository mode by setting repositoryMode
flag:
1const sequelize = new Sequelize({ 2 repositoryMode: true, 3 ..., 4});
Retrieve repository to create instances or perform search operations:
1const userRepository = sequelize.getRepository(User); 2 3const luke = await userRepository.create({ name: 'Luke Skywalker' }); 4const luke = await userRepository.findOne({ where: { name: 'luke' } });
For now one need to use the repositories within the include options in order to retrieve or create related data:
1const userRepository = sequelize.getRepository(User); 2const addressRepository = sequelize.getRepository(Address); 3 4userRepository.find({ include: [addressRepository] }); 5userRepository.create({ name: 'Bear' }, { include: [addressRepository] });
⚠️ This will change in the future: One will be able to refer the model classes instead of the repositories.
Nested scopes and includes in general won't work when using @Scope
annotation together with repository mode like:
1@Scopes(() => ({ 2 // includes 3 withAddress: { 4 include: [() => Address], 5 }, 6 // nested scopes 7 withAddressIncludingLatLng: { 8 include: [() => Address.scope('withLatLng')], 9 }, 10})) 11@Table 12class User extends Model {}
⚠️ This will change in the future: Simple includes will be implemented.
Validation options can be set through the @Column
annotation, but if you prefer to use separate decorators for
validation instead, you can do so by simply adding the validate options as decorators:
So that validate.isEmail=true
becomes @IsEmail
, validate.equals='value'
becomes @Equals('value')
and so on. Please notice that a validator that expects a boolean is translated to an annotation without a parameter.
See sequelize docs for all validators.
The following validators cannot simply be translated from sequelize validator to an annotation:
Validator | Annotation |
---|---|
validate.len=[number, number] | @Length({max?: number, min?: number}) |
validate[customName: string] | For custom validators also use the @Is(...) annotation: Either @Is('custom', (value) => { /* ... */}) or with named function @Is(function custom(value) { /* ... */}) |
1const HEX_REGEX = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/; 2 3@Table 4export class Shoe extends Model { 5 @IsUUID(4) 6 @PrimaryKey 7 @Column 8 id: string; 9 10 @Equals('lala') 11 @Column 12 readonly key: string; 13 14 @Contains('Special') 15 @Column 16 special: string; 17 18 @Length({ min: 3, max: 15 }) 19 @Column 20 brand: string; 21 22 @IsUrl 23 @Column 24 brandUrl: string; 25 26 @Is('HexColor', (value) => { 27 if (!HEX_REGEX.test(value)) { 28 throw new Error(`"${value}" is not a hex color value.`); 29 } 30 }) 31 @Column 32 primaryColor: string; 33 34 @Is(function hexColor(value: string): void { 35 if (!HEX_REGEX.test(value)) { 36 throw new Error(`"${value}" is not a hex color value.`); 37 } 38 }) 39 @Column 40 secondaryColor: string; 41 42 @Is(HEX_REGEX) 43 @Column 44 tertiaryColor: string; 45 46 @IsDate 47 @IsBefore('2017-02-27') 48 @Column 49 producedAt: Date; 50}
Scopes can be defined with annotations as well. The scope options are identical to native sequelize (See sequelize docs for more details)
@DefaultScope
and @Scopes
1@DefaultScope(() => ({ 2 attributes: ['id', 'primaryColor', 'secondaryColor', 'producedAt'], 3})) 4@Scopes(() => ({ 5 full: { 6 include: [Manufacturer], 7 }, 8 yellow: { 9 where: { primaryColor: 'yellow' }, 10 }, 11})) 12@Table 13export class ShoeWithScopes extends Model { 14 @Column 15 readonly secretKey: string; 16 17 @Column 18 primaryColor: string; 19 20 @Column 21 secondaryColor: string; 22 23 @Column 24 producedAt: Date; 25 26 @ForeignKey(() => Manufacturer) 27 @Column 28 manufacturerId: number; 29 30 @BelongsTo(() => Manufacturer) 31 manufacturer: Manufacturer; 32}
Hooks can be attached to your models. All Model-level hooks are supported. See the related unit tests for a summary.
Each hook must be a static
method. Multiple hooks can be attached to a single method, and you can define multiple methods for a given hook.
The name of the method cannot be the same as the name of the hook (for example, a @BeforeCreate
hook method cannot be named beforeCreate
). That’s because Sequelize has pre-defined methods with those names.
1@Table 2export class Person extends Model { 3 @Column 4 name: string; 5 6 @BeforeUpdate 7 @BeforeCreate 8 static makeUpperCase(instance: Person) { 9 // this will be called when an instance is created or updated 10 instance.name = instance.name.toLocaleUpperCase(); 11 } 12 13 @BeforeCreate 14 static addUnicorn(instance: Person) { 15 // this will also be called when an instance is created 16 instance.name += ' 🦄'; 17 } 18}
() => Model
?@ForeignKey(Model)
is much easier to read, so why is @ForeignKey(() => Model)
so important? When it
comes to circular-dependencies (which are in general solved by node for you) Model
can be undefined
when it gets passed to @ForeignKey. With the usage of a function, which returns the actual model, we prevent
this issue.
Unless you are using the repository mode, you won't be able to add one and the same model to multiple Sequelize instances with differently configured connections. So that one model will only work for one connection.
This is not only good practice regarding design, but also matters for the order
of execution. Since Typescript creates a __metadata("design:type", SomeModel)
call due to emitDecoratorMetadata
compile option, in some cases SomeModel
is probably not defined(not undefined!) and would throw a ReferenceError
.
When putting SomeModel
in a separate file, it would look like __metadata("design:type", SomeModel_1.SomeModel)
,
which does not throw an error.
If you need to minify your code, you need to set tableName
and modelName
in the DefineOptions
for @Table
annotation. sequelize-typescript
uses the class name as default name for tableName
and modelName
.
When the code is minified the class name will no longer be the originally
defined one (So that class User
will become class b
for example).
To contribute you can:
In order to open a pull request please:
npm install && npm run build && npm run cover
) and ensure your commits don't break the tests.In order to update the types for sequelize please go to the Definitely Typed repo, it would also be a good idea to open a PR into sequelize so that Sequelize can maintain its own types, but that might be harder than getting updated types into microsoft's repo. The Typescript team is slowly trying to encourage npm package maintainers to maintain their own typings, but Microsoft still has dedicated and good people maintaining the DT repo, accepting PR's and keeping quality high.
Keep in mind sequelize-typescript
does not provide typings for sequelize
- these are seperate things.
A lot of the types in sequelize-typescript
augment, refer to, or extend what sequelize already has.
The latest stable version of the package.
Stable Version
1
7.5/10
Summary
sequelize-typescript Prototype Pollution vulnerability
Affected Versions
< 2.1.6
Patched Versions
2.1.6
Reason
no dangerous workflow patterns detected
Reason
security policy file detected
Details
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
dependency not pinned by hash detected -- score normalized to 5
Details
Reason
Found 1/4 approved changesets -- score normalized to 2
Reason
0 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 0
Reason
detected GitHub workflow tokens with excessive permissions
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
project is not fuzzed
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Reason
41 existing vulnerabilities detected
Details
Score
Last Scanned on 2024-11-25
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More