npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@themost/jspa

v1.2.2

Published

MOST Web Framework Persistence API

Downloads

89

Readme

npm GitHub top language License GitHub last commit GitHub Release Date npm Snyk Vulnerabilities for npm package

MOST Web Framework Logo

@themost/jspa

@themost web framework JavaScript Persistent API on top of @themost/data ORM.

@themost/jspa is a mimic of Java Persistent API for Node.js environment and provides a set of tools for describing object relational mapping.

The following example describes a Thing class:

import { DataObject } from '@themost/data';
import { Column, Entity, GeneratedValue, GenerationType, Id, Table, Counter, Basic, Formula, ManyToOne, FetchType, ColumnDefault } from '@themost/jspa';

@Entity()
@Table()
class Thing extends DataObject {

    constructor() {
        super();
    }

    @Id()
    @Column()
    @GeneratedValue({
        strategy: GenerationType.Identity
    })
    public id?: Counter;

    @Basic()
    public name?: string;

    @Column()
    public alternateName?: string;

    @Column()
    public description?: string;

    @Column()
    public additionalType?: string;

    @Column()
    public sameAs?: string;

    @Column()
    public url?: string;

    @Column()
    public identifier?: string;

    @Column()
    public image?: string;

    @Column({
        nullable: false,
        updatable: false
    })
    @ColumnDefault(() => new Date())
    public dateCreated?: Date;

    @Column({
        nullable: false
    })
    @Formula(() => new Date())
    public dateModified?: Date;

    @Column({
        nullable: true,
        updatable: false,
        type: 'User'
    })
    @ManyToOne({
        fetchType: FetchType.Lazy
    })
    public createdBy?: any;

    @Column({
        nullable: true,
        type: 'User'
    })
    @ManyToOne({
        fetchType: FetchType.Lazy
    })
    public modifiedBy?: any;
}

export {
    Thing
}

Usage

npm i @themost/jspa

Annotations

@Entity

The basic annotation of a class. Use optional @Entity.name attribute to define the name of this entity if it's different than class name and @Entity.version attribute to allow @themost/data auto-upgrade operations to update database objects after any change.

@Entity({
    version: '1.0.0'
})
class Party extends Thing {
    ...
}

@Entity() annotation includes @Entity.privileges attribute to allow setting the collection of default privileges assigned to a class

@Entity({
    version: '1.0.0',
    privileges: [
        {
            mask: 15,
            type: 'global'
        },
        {
            mask: 15,
            type: 'global',
            account: 'Administrators'
        }
    ]
})
class Party extends Thing {
    ...
}

The previous example defines that Party will be accessible by each user which has permissions defined in data permission storage. It also defines that Administrators have full-access by default.

@Table

The optional @Table annotation allows you to specify the properties of the database objects that will be used to persist the entity in the database.

@Entity({
    version: '1.0.0'
})
@Table(
    name: 'PartyBase'
)
class Party extends Thing {
    ...
}
  • @Table.name

    The name of the table that will be used to persist objects. The default value provided by @themost/data is a concatenation of entity's name and word "Base" e.g. PartyBase, PostalAddressBase etc.

  • @Table.indexes

    A collection of indexes that should be included while creating or updating database objects.

      @Table(
          indexes: [
              {
                  columnList: [
                      'name'
                  ]
              },
              {
                  columnList: [
                      'email'
                  ]
              }
          ]
      )
      class Party extends Thing {
          ...
      }
  • @Table.uniqueConstraints

    A collection of unique constraints that should be included while creating or updating database objects based on database engine features.

      @Table(
          uniqueConstraints: [
              {
                  columnNames: [
                      'email'
                  ]
              }
          ]
      )
      class Party extends Thing {
          ...
      }

@Column

@Column annotation is used to specify the mapped column for a property

@Entity()
@Table()
class Thing extends DataObject {
    ...
    @Column()
    public name?: string;
}
  • @Column.name

    (Optional) A string which defines the column name. If @Column.name is missing property name is being used.

      class Thing extends DataObject {
          ...
          @Column({
              name: 'obj_name'
          })
          public name?: string;
      }
  • @Column.nullable

    (Optional) A boolean which indicates whether the mapped column is nullable of false. The default value is true.

  • @Column.type

    A string which defines the type of the column. Column may be one of the primitive column types of @themost/data or an object type

      class Thing extends DataObject {
          ...
          @Column({
              type: ColumnType.Text
          })
          public name;
    
          @Column({
              type: 'User'
          })
          public createdBy;
      }
  • @Column.length

    (Optional) The column length

      class Thing extends DataObject {
          ...
          @Column({
              type: ColumnType.Text,
              length: 100
          })
          public name;
      }
  • @Column.scale

    (Optional) The scale for a numeric column

  • @Column.precision

    (Optional) The precision for a numeric column

  • @Column.insertable

    (Optional) A boolean which indicates whether the column will be included while inserting objects or not

  • @Column.updatable

    (Optional) A boolean which indicates whether the column will be included while updating objects or not

@Id()

@Id is used to specify identity columns

@Entity()
@Table()
class Thing extends DataObject {
    
    @Id()
    @Column({
        type: ColumnType.Counter
    })
    @GeneratedValue({
        strategy: GenerationType.Identity
    })
    public id;
    ...
}

@GeneratedValue()

@GeneratedValue annotation is used to specify generation strategy for identity columns

@Entity()
@Table()
class Thing extends DataObject {
    
    @Id()
    @Column({
        type: ColumnType.Counter
    })
    @GeneratedValue({
        strategy: GenerationType.Identity
    })
    public id;
    ...
}

The available generation strategies are:

  • GenerationType.Auto: Based on the database’s support for primary key generation framework decides which generator type to be used.

  • GenerationType.Identity: In this case database is responsible for determining and assigning the next primary key.

  • GenerationType.Sequence: A sequence specify a database object that can be used as a source of primary key values.

  • GenerationType.Table: It keeps a separate table with the primary key values

@Formula

@Formula annotation is used to specify calculated values.

class Thing extends DataObject {

    ...
    @Formula((event) => {
        const context = event.context as any;
        let user: { name?: string } =context.interactiveUser;
        if (user && user.name) {
            return {
                name: user.name
            };
        }
        user = context.user;
        if (user && user.name) {
            return {
                name: user.name
            };
        }
        return null;
    })
    public createdBy?: any;

}

@Formula closure has event parameter of type FormulaArgs

  • FormulaArgs.context The current data context

  • Formula.model An instance of DataModel class which represents the current entity type

  • Formula.target The current object

@ColumnDefault

@ColumnDefault annotation defines the default value of the mapped column

@Entity()
@Table()
class Thing extends DataObject {
    ...
    @ColumnDefault(() => new Date())
    public dateCreated?: Date;
}

@ColumnDefault can be a simple closure which returns a single value or a closure which has event parameter of type ColumnDefaultArgs

  • ColumnDefaultArgs.context The current data context

  • ColumnDefaultArgs.model An instance of DataModel class which represents the current entity type

  • ColumnDefaultArgs.target The current object

@Embedded

@Embedded annotation is used to embed type into another type. An embedded type will be inserted, updated or deleted as result of an operation made on parent object.

@Entity()
class Place extends Thing {
    ...
    @Embedded()
    public address?: PostalAddress;
}

e.g. Place entity type embeds PostalAddress into address property.

@ManyToOne

@ManyToOne annotation defined a foreign-key association between two entity types

@Entity()
class Party extends Thing {

    ...
    @Column({
        nullable: false,
        updatable: false,
        type: 'User'
    })
    @ManyToOne({
        fetchType: FetchType.Lazy
    })
    public createdBy?: User;
}

e.g. Party.createdBy defines a foreign-key association between Party and User

  • @ManyToOne.optional A boolean which whether the association is optional or not.
  • @ManyToOne.fetchType Defines that data can be lazily or eagerly fetched

@OneToMany

@OneToMany annotation is used to implement one-to-many relationship between two entity types.

@Entity()
class Place extends Thing {

    ...
    @OneToMany({
        cascadeType: CascadeType.Detach,
        fetchType: FetchType.Lazy,
        mappedBy: 'containedIn',
        targetEntity: 'Place'
    })
    public containsPlace?: Place;

}

e.g. Place has a collection of places based on property containedIn

@OneToMany annotation has the following properties

  • @ManyToOne.fetchType Defines that data can be lazily or eagerly fetched
  • @ManyToOne.cascadeType Defines the cascade operation that will be used while removing an object.
  • @ManyToOne.mappedBy The target column that holds the association between the current entity type and the target entity type.
  • @ManyToOne.targetEntity The type of the target entity

@ManyToMany

@OneToMany annotation is used to implement many-to-many relationship between two entity types.

class Group extends Account {
    ...
    @ManyToMany({
        targetEntity: 'Account',
        fetchType: FetchType.Lazy,
        cascadeType: CascadeType.Detach
    })
    @JoinTable({
        name: 'GroupMembers',
        joinColumns: [
            {
                name: 'object',
                referencedColumnName: 'id'
            }
        ],
        inverseJoinColumns: [
            {
                name: 'value',
                referencedColumnName: 'id'
            }
        ]
    })
    public members?: Account[];
    ...
}

e.g. Every Group has a collection of members of type Account

@ManyToOne annotation has the following properties

  • @ManyToOne.fetchType Defines that data can be lazily or eagerly fetched
  • @ManyToOne.cascadeType Defines the cascade operation that will be used while removing an object.
  • @ManyToOne.targetEntity The type of the target entity

The @JoinTable annotation is being used to define the database object where this relationship will be stored. @JoinTable.joinColumns contains the local property and @JoinTable.inverseJoinColumns contains the foreign property.

e.g. Group.members many-to-many association will be stored in GroupMembers table where GroupMembers.object column will be a Group.id and GroupMembers.value column will be an Account.id.

@ElementCollection

@ElementCollection annotation is used to define a collection of primitive typed values e.g. an array of strings or numbers.

class Account extends Thing {
    ...
    @ManyToMany({
        targetClass: Text,
        fetchType: FetchType.Lazy
    })
    @CollectionTable({
        name: 'AccountTags',
        joinColumns: [
            {
                name: 'object',
                referencedColumnName: 'id'
            }
        ],
        inverseJoinColumns: [
            {
                name: 'value'
            }
        ]
    })
    tags;
    ...
}

e.g. Every Account has a collection of tags of type Text which is a subclass of String

The @CollectionTable annotation is being used to define the database object where this relationship will be stored. @CollectionTable.joinColumns contains the local property and @CollectionTable.inverseJoinColumns may contain the column where each value will be stored.

e.g. Account.tags will be persisted in AccountTags table where object field contains Account.id and value field contains Account.tag value.

@EntityListeners

@EntityListeners annotation defines a collection of classes that contain procedures which are going to be executed before and after CRUD operations.

@Entity()
@EntityListeners(OnUserUpdateListener, OnUserRemoveListener, OnUserInitListener)
class User extends Account {
    ...
}

e.g. OnUserUpdateListener contains PreUpdate and PostUpdate procedures

export class OnUserUpdateListener {
    @PreUpdate()
    async onPreUpdate(event: PreUpdateEvent) {
        //
    }
    @PostUpdate()
    async onPostUpdate(event: PostUpdateEvent) {
        //
    }
}

@PreInit

@PreInit annotation defines an event which will be occured before creating or updating an entity type

@PreInit()
async onPreInit(event: PreInitEvent) {
    //
}

@PostInit

@PostInit annotation defines an event which will be occured after creating or updating an entity type

@PostInit()
async onPostInit(event: PostInitEvent) {
    //
}

@PreLoad

@PreLoad annotation defines an event which will be occured before loading an entity

@PreLoad()
async onPreLoad(event: PreLoadEvent) {
    //
}

@PostLoad

@PostInit annotation defines an event which will be occured after loading an entity

@PostLoad()
async onPostLoad(event: PostLoadEvent) {
    //
}

@PrePersist

@PreLoad annotation defines an event which will be occured before inserting an entity

@PrePersist()
async onPrePersist(event: PrePersistEvent) {
    //
}

@PostPersist

@PostPersist annotation defines an event which will be occured after inserting an entity

@PostPersist()
async onPostPersist(event: PostPersistEvent) {
    //
}

@PreUpdate

@PreUpdate annotation defines an event which will be occured before updating an entity

@PreUpdate()
async onPreUpdate(event: PreUpdateEvent) {
    //
}

@PostUpdate

@PostUpdate annotation defines an event which will be occured after updating an entity

@PostUpdate()
async onPostUpdate(event: PostUpdateEvent) {
    //
}

@PreRemove

@PreRemove annotation defines an event which will be occured before removing an entity

@PreRemove()
async onPreRemove(event: PreRemoveEvent) {
    //
}

@PostUpdate

@PostRemove annotation defines an event which will be occured after removing an entity

@PostRemove()
async onPostRemove(event: PostRemoveEvent) {
    //
}