2.1.2-alpha.1 • Published 2 years ago

@bouncecode/typeorm-extension v2.1.2-alpha.1

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

npm version codecov Master Workflow Known Vulnerabilities

Typeorm Extension 🚀

This is a library to

  • create or drop the (default-) database 🔥
  • seed the database ⚡
  • validate, parse & apply fields, filter[s], include[s], page and sort parameter values ( extended JSON:API specification)

Important NOTE

From v2.0.0 onwards, this library requires a typeorm version >= v0.3.0 ☂.


Table of Contents

Installation

npm install typeorm-extension --save

Limitations

At the moment, only the following typeorm drivers are supported to create or drop a database:

  • CockroachDB
  • MSSQL
  • MySQL
  • Oracle
  • Postgres
  • SQLite

Usage

CLI

The following commands are available in the terminal:

  • typeorm-extension db:create to create the database
  • typeorm-extension db:drop to drop the database
  • typeorm-extension seed seed the database

Alternatively, the full command path can be set in the package.json file to run it e.g. with ts-node.

"scripts": {
  ...
  "db:create": "ts-node ./node_modules/typeorm-extension/dist/cli/index.js db:create",
  "db:drop": "ts-node ./node_modules/typeorm-extension/dist/cli/index.js db:drop",
  "seed": "ts-node ./node_modules/typeorm-extension/dist/cli/index.js seed"
  ...
}

Read the Seeding Configuration section to find out how to specify the path, for the seeder- & factory-location.

Options

OptionCommandsDefaultDeprecatedDescription
--root or -rdb:create, db:drop & seedprocess.cwd()noPath to the data-source / config file.
--dataSource or -ddb:create, db:drop & seeddata-sourcenoName of the data-source file.
--synchronize or -sdb:create & db:dropyesnoSynchronize the database schema after database creation. Options: yes or no.
--initialDatabasedb:createundefinednoSpecify the initial database to connect to. This option is only relevant for the postgres driver, which must always to connect to a database. If no database is provided, the database name will be equal to the connection user name.
--seedseedundefinednoSpecify a specific seed class to run.
--connection or -cdb:create, db:drop & seeddefaultyesName of the connection. Required if there are multiple connections.
--config or -fdb:create, db:drop & seedormconfig.jsyesName to the config file.

Database

An alternative to the CLI variant, is to create the database in the code base during the runtime of the application. Therefore, provide the DataSourceOptions for the DataSource manually, or let it be created automatically:

Create

Example #1

import { DataSource, DataSourceOptions } from "@bouncecode/typeorm";
import { createDatabase } from "typeorm-extension";

(async () => {
    const options: DataSourceOptions = {
        type: "better-sqlite",
        database: "db.sqlite",
    };

    // Create the database with specification of the DataSource options
    await createDatabase({
        options,
    });

    const dataSource = new DataSource(options);
    await dataSource.initialize();
    // do something with the DataSource
})();

Example #2

import { getConnectionOptions } from "@bouncecode/typeorm";
import { createDatabase } from "typeorm-extension";

(async () => {
    const options = await getConnectionOptions();

    // Create the database with specification of the DataSource options
    await createDatabase({
        options,
    });

    const dataSource = new DataSource(options);
    await dataSource.initialize();
    // do something with the DataSource
})();

Example #3

It is also possible to let the library automatically search for the data-source under the hood. Therefore, it will search by default for a data-source.{ts,js} file in the following directories:

  • {src,dist}/db/
  • {src,dist}/database
  • {src,dist}
import { createDatabase } from "typeorm-extension";

(async () => {
    // Create the database without specifying it manually
    await createDatabase();
})();

To get a better overview and understanding of the createDatabase function go to the functions section and read more about it.

Drop

Example #1

import { DataSource, DataSourceOptions } from "@bouncecode/typeorm";
import { dropDatabase } from "typeorm-extension";

(async () => {
    const options: DataSourceOptions = {
        type: "better-sqlite",
        database: "db.sqlite",
    };

    // Create the database with specification of the DataSource options
    await dropDatabase({
        options,
    });
})();

Example #2

import { getConnectionOptions } from "@bouncecode/typeorm";
import { dropDatabase } from "typeorm-extension";

(async () => {
    const options = await getConnectionOptions();

    // Create the database with specification of the DataSource options
    await dropDatabase({
        options,
    });
})();

Example #3

It is also possible to let the library automatically search for the data-source under the hood. Therefore, it will search by default for a data-source.{ts,js} file in the following directories:

  • {src,dist}/db/
  • {src,dist}/database
  • {src,dist}
import { dropDatabase } from "typeorm-extension";

(async () => {
    // Drop the database without specifying it manually
    await dropDatabase();
})();

To get a better overview and understanding of the dropDatabase function go to the functions section and read more about it.

Instances

Single

The default DataSource instance can be acquired, by not providing any alias at all or using the key default. If no DataSource instance or DataSourceOptions object is deposited initially the method will attempt to locate and load the DataSource file and initialize itself from there.

import { useDataSource } from "typeorm-extension";

(async () => {
    const dataSource: DataSource = await useDataSource();
})();

Reference(s):

Multiple

It is also possible to manage multiple DataSource instances. Therefore, each additional DataSource must be registered under a different alias. This can be done by either setting the DataSource instance or the DataSourceOptions object for the given alias.

import { DataSource, DataSourceOptions } from "@bouncecode/typeorm";
import { setDataSource, useDataSource } from "typeorm-extension";

(async () => {
    const secondDataSourceOptions: DataSourceOptions = {
        // ...
    };

    const dataSource = new DataSource(secondDataSourceOptions);
    setDataSource(dataSource, "second");

    const instance: DataSource = await useDataSource("second");
})();

Reference(s):

Seeding

Seeding the database is fairly easy and can be achieved by following the steps below:

  • Configuration: Specify the seed and factory location by path or object.
  • Entity: Define one or more entities.
  • Factory (optional): Define a factory for each entity for which data should be automatically generated.
  • Seed: Define one or more seed classes to populate the database with an initial data set or generated data by a factory.
  • Execute: Run the seeder(s) with the CLI or in the code base.

Configuration

The seeder- & factory-location, can be specified via:

  • environment variable(s)
  • extended data-source.ts file
  • runSeeder(s) method options parameter, in case of a direct code base usage

The default factory path is: src/database/factories/**/*{.ts,.js}

The default seed path is: src/database/seeds/**/*{.ts,.js}

env

TYPEORM_SEEDING_FACTORIES=src/database/factories/**/*{.ts,.js}
TYPEORM_SEEDING_SEEDS=src/database/seeds/**/*{.ts,.js}

data-source.ts

import { DataSource, DataSourceOptions } from "@bouncecode/typeorm";
import { SeederOptions } from "typeorm-extension";

const options: DataSourceOptions & SeederOptions = {
    type: "better-sqlite",
    database: "db.sqlite",

    seeds: ["src/database/seeds/**/*{.ts,.js}"],
    factories: ["src/database/factories/**/*{.ts,.js}"],
};

export const dataSource = new DataSource(options);

runSeeder(s)

import { DataSource, DataSourceOptions } from "@bouncecode/typeorm";
import { runSeeders, SeederOptions } from "typeorm-extension";

(async () => {
    const options: DataSourceOptions = {
        type: "better-sqlite",
        database: "db.sqlite",
    };

    const dataSource = new DataSource(options);
    await dataSource.initialize();

    runSeeders(dataSource, {
        seeds: ["src/database/seeds/**/*{.ts,.js}"],
        factories: ["src/database/factories/**/*{.ts,.js}"],
    });
})();

Entity

To get started, define one or more entities.

user.ts

import { Entity, PrimaryGeneratedColumn, Column } from "@bouncecode/typeorm";

@Entity()
export class User {
    @PrimaryGeneratedColumn()
    id: number;

    @Column()
    firstName: string;

    @Column()
    lastName: string;

    @Column()
    email: string;
}

Factory

To create entities with random data, create a factory for each desired entity. The definition of a factory is optional.

user.factory.ts

import { setSeederFactory } from "typeorm-extension";
import { User } from "./user";

export default setSeederFactory(User, (faker) => {
    const user = new User();
    user.firstName = faker.name.firstName("male");
    user.lastName = faker.name.lastName("male");
    user.email = faker.internet.email(user.firstName, user.lastName);

    return user;
});

Seed

And last but not least, create a seeder. The seeder can be called by the cli command seed or in the codebase by using the function runSeeder. A seeder class only requires one method, called run and provides the arguments dataSource & factoryManager.

user.seeder.ts

A seeder class must implement the Seeder interface, and could look like this:

import { Seeder, SeederFactoryManager } from "typeorm-extension";
import { DataSource } from "@bouncecode/typeorm";
import { User } from "./user";

export default class UserSeeder implements Seeder {
    public async run(
        dataSource: DataSource,
        factoryManager: SeederFactoryManager
    ): Promise<any> {
        const repository = dataSource.getRepository(User);
        await repository.insert([
            {
                firstName: "Caleb",
                lastName: "Barrows",
                email: "caleb.barrows@gmail.com",
            },
        ]);

        // ---------------------------------------------------

        const userFactory = await factoryManager.get(User);
        // save 1 factory generated entity, to the database
        await userFactory.save();

        // save 5 factory generated entities, to the database
        await userFactory.saveMany(5);
    }
}

Execute

Populate the database from the code base:

import { DataSource, DataSourceOptions } from "@bouncecode/typeorm";
import { runSeeders, SeederOptions } from "typeorm-extension";
import { User } from "user";

(async () => {
    const options: DataSourceOptions & SeederOptions = {
        type: "better-sqlite",
        database: "db.sqlite",
        entities: [User],

        seeds: ["./*.seeder.ts"],
        factories: ["./*.factory.ts"],
    };

    const dataSource = new DataSource(options);
    await dataSource.initialize();

    await runSeeders(dataSource);
})();

Populate the database by explicit definitions from the codebase.

import { DataSource, DataSourceOptions } from "@bouncecode/typeorm";
import { runSeeder, SeederOptions } from "typeorm-extension";
import { User } from "user";
import UserSeeder from "user.seeder";
import UserFactory from "user.factory";

(async () => {
    const options: DataSourceOptions & SeederOptions = {
        type: "better-sqlite",
        database: "db.sqlite",
        entities: [User],

        seeds: [UserSeeder],
        factories: [UserFactory],
    };

    const dataSource = new DataSource(options);
    await dataSource.initialize();

    await runSeeders(dataSource);
})();

Query

The query submodule enables query parameter (fields, filter, ...) values to be build, parsed & validated. Therefore, the @trapi/query library is used under the hood. The main functions and types are also exposed by this library.

For explanation proposes, two simple entities with a relation between them are declared to demonstrate the usage of the query utils:

import {
    Entity,
    PrimaryGeneratedColumn,
    Column,
    OneToOne,
    JoinColumn,
} from "@bouncecode/typeorm";

@Entity()
export class User {
    @PrimaryGeneratedColumn({ unsigned: true })
    id: number;

    @Column({ type: "varchar", length: 30 })
    @Index({ unique: true })
    name: string;

    @Column({ type: "varchar", length: 255, default: null, nullable: true })
    email: string;

    @OneToOne(() => Profile)
    profile: Profile;
}

@Entity()
export class Profile {
    @PrimaryGeneratedColumn({ unsigned: true })
    id: number;

    @Column({ type: "varchar", length: 255, default: null, nullable: true })
    avatar: string;

    @Column({ type: "varchar", length: 255, default: null, nullable: true })
    cover: string;

    @OneToOne(() => User)
    @JoinColumn()
    user: User;
}

In the following example express is used to handle the HTTP request. Each query parameter is applied individually in following code snippet (applyQueryFields, applyQueryFilter, ...).

import { getRepository } from "@bouncecode/typeorm";
import { Request, Response } from "express";
import {
    applyQueryFields,
    applyQueryFilters,
    applyQueryRelations,
    applyQueryPagination,
    applyQuerySort,
} from "typeorm-extension";

/**
 * Get many users.
 *
 * Request example
 * - url: /users?page[limit]=10&page[offset]=0&include=profile&filter[id]=1&fields[user]=id,name
 *
 * Return Example:
 * {
 *     data: [
 *         {id: 1, name: 'tada5hi', profile: {avatar: 'avatar.jpg', cover: 'cover.jpg'}}
 *      ],
 *     meta: {
 *        total: 1,
 *        limit: 20,
 *        offset: 0
 *    }
 * }
 * @param req
 * @param res
 */
export async function getUsers(req: Request, res: Response) {
    const { fields, filter, include, page, sort } = req.query;

    const repository = getRepository(User);
    const query = repository.createQueryBuilder("user");

    // -----------------------------------------------------

    const relationsParsed = applyQueryRelations(query, include, {
        defaultAlias: "user",
        allowed: ["profile"],
    });

    applyQuerySort(query, sort, {
        defaultAlias: "user",
        allowed: ["id", "name", "profile.id"],
        // profile.id can only be used as sorting key, if the relation 'profile' is included.
        relations: relationsParsed,
    });

    applyQueryFields(query, fields, {
        defaultAlias: "user",
        allowed: ["id", "name", "profile.id", "profile.avatar"],
        // porfile fields can only be included, if the relation 'profile' is included.
        relations: relationsParsed,
    });

    // only allow filtering users by id & name
    applyQueryFilters(query, filter, {
        defaultAlias: "user",
        allowed: ["id", "name", "profile.id"],
        // porfile.id can only be used as a filter, if the relation 'profile' is included.
        relations: relationsParsed,
    });

    // only allow to select 20 items at maximum.
    const pagination = applyQueryPagination(query, page, { maxLimit: 20 });

    // -----------------------------------------------------

    const [entities, total] = await query.getManyAndCount();

    return res.json({
        data: {
            data: entities,
            meta: {
                total,
                ...pagination,
            },
        },
    });
}

Functions - Database

createDatabase

function createDatabase(context?: DatabaseCreateContext): Promise<unknown>

Create database.

Example

Simple

// Only create database if it does not exist.
await createDatabase({ ifNotExist: true });

Synchronization

// To not synchronize database schema after database creation.
await createDatabase({ synchronize: false });

Charset

It is possible to explizit specify charset & characterSet, besides defining it as part of the DataSourceOptions object. E.g.

  • postgres
    await createDatabase({ characterSet: "UTF8" });
  • mysql
    await createDatabase({
        charset: "utf8mb4_general_ci",
        characterSet: "utf8mb4",
    });

DataSourceOptions

  • The typeorm DataSourceOptions object can be provided as options property to the createDatabase method.

    import { DataSourceOptions } from "@bouncecode/typeorm";
    import { createDatabase } from "typeorm-extension";
    
    (async () => {
        const options: DataSourceOptions = {
            //...
        };
        // Create database
        await createDatabase({
            options,
        });
    })();
  • if entities & subscribers are defined as path, it is possible to use them with e.g. ts-node as well as with the compiled version. Therefore, extend the DataSourceOptions with the extendDataSourceOptions utility method.

    import { DataSourceOptions } from "@bouncecode/typeorm";
    import { createDatabase, extendDataSourceOptions } from "typeorm-extension";
    
    (async () => {
        let options: DataSourceOptions = {
            // ...
        };
    
        options = await extendDataSourceOptions(options);
    
        // Create database
        await createDatabase({
            options,
        });
    })();

    This is achieved by rewriting the src path and .ts extension, to the dist (outDir) path and .js extension.

    If the function is not called within the ts-node runtime environment, the source path src/database/entities.ts for example, will be rewritten to dist/database/entities.js.

Parameters

NameTypeDescription
contextDatabaseCreateContextSpecify charset, coalition and DataSourceOptions. Details

Returns

Promise<unknown>

The function returns a promise with the query result of the underlying database driver.

dropDatabase

function dropDatabase(context?: DatabaseDropContext): Promise<unknown>

Drop database.

Example

Simple

import { createDatabase } from "typeorm-extension";

(async () => {
    await dropDatabase();
})();

DataSourceOptions

The typeorm DataSourceOptions object can be provided as options property to the dropDatabase method.

import { DataSourceOptions } from "@bouncecode/typeorm";
import { dropDatabase } from "typeorm-extension";

(async () => {
    const options: DataSourceOptions = {
        //...
    };
    // Drop database
    await dropDatabase({
        options,
    });
})();

Parameters

NameTypeDescription
contextDatabaseDropContextSpecify charset, coalition and DataSourceOptions. Details

Returns

Promise<unknown>

The function returns a promise with the query result of the underlying database driver.

Functions - Instances

setDataSource

function setDataSourceOptions(dataSource: DataSource, alias?: string): void

Set the default DataSource, by not providing any alias at all or using the key default. This method should only be used, if an additional DataSource should be registered or the library should not attempt to instantiate the instance on the fly.

Example

Single

import { setDataSource } from "typeorm-extension";
import { DataSource, DataSourceOptions } from "@bouncecode/typeorm";

const options: DataSourceOptions = {
    // ...
};

const dataSource = new DataSource(options);
setDataSource(dataSource);

Multiple

import { setDataSource } from "typeorm-extension";
import { DataSource, DataSourceOptions } from "@bouncecode/typeorm";

const options: DataSourceOptions = {
    // ...
};

const dataSource = new DataSource(options);
setDataSource(dataSource, "foo");

Parameters

NameTypeDescription
dataSourceDataSourceTypeorm DataSource instance.
aliasstring or undefinedAlias for depositing the typeorm DataSource instance. Default: default

Returns

void

useDataSource

function useDataSource(alias?: string): Promise<DataSource>

Use the default deposited DataSource, by not providing any alias at all or using the key default. If no DataSource instance or DataSourceOptions object is deposited initially, the method will attempt to locate, load & initialize the DataSource.

Example

Auto

import { useDataSource } from "typeorm-extension";

(async () => {
    // Load the deposited DataSource,
    // otherwise instanitate the instance from the deposited DataSourceOptions object
    const options = await useDataSource();
})();

Single

import { setDataSource, useDataSource } from "typeorm-extension";
import { DataSource, DataSourceOptions } from "@bouncecode/typeorm";

const options: DataSourceOptions = {
    // ...
};

const dataSource = new DataSource(options);
setDataSource(dataSource);

(async () => {
    // now the method can use the deposited configuration.
    const instance = await useDataSource();
})();

Multiple

import { setDataSource, useDataSource } from "typeorm-extension";
import { DataSource, DataSourceOptions } from "@bouncecode/typeorm";

const options: DataSourceOptions = {
    // ...
};

const dataSource = new DataSource(options);
setDataSource(dataSource, "foo");

(async () => {
    // now the method can use the deposited configuration.
    const instance = await useDataSource("foo");
})();

Parameters

NameTypeDescription
aliasstring or undefinedAlias for receiving the typeorm DataSource instance. Default: default

Returns

Promise<DataSource>

setDataSourceOptions

function setDataSourceOptions(options: DataSourceOptions, alias?: string): void

Set the default DataSourceOptions object, by not providing any alias at all or using the key default. The DataSource instance will be created from this configuration, if it has not already been created before.

Example

Single

import { setDataSourceOptions, useDataSource } from "typeorm-extension";
import { DataSourceOptions } from "@bouncecode/typeorm";

const options: DataSourceOptions = {
    // ...
};

setDataSourceOptions(options);

Multiple

import { setDataSourceOptions, useDataSource } from "typeorm-extension";
import { DataSourceOptions } from "@bouncecode/typeorm";

const options: DataSourceOptions = {
    // ...
};

setDataSourceOptions(options, "foo");

Parameters

NameTypeDescription
optionsDataSourceOptionsTypeorm DataSourceOptions object.
aliasstring or undefinedAlias for depositing the typeorm options object. Default: default

Returns

void

useDataSourceOptions

function useDataSourceOptions(alias?: string): Promise<DataSourceOptions>

Use the default deposited DataSourceOptions object, by not providing any alias at all or using the key default. If no DataSourceOptions object is deposited initially the method will attempt to locate and load the DataSource file and extract the options from there.

Therefore, it will search for a data-source.{ts,js} file in the following directories:

  • {src,dist}/db/
  • {src,dist}/database
  • {src,dist}

Example

Auto

import { useDataSourceOptions } from "typeorm-extension";
import { DataSourceOptions } from "@bouncecode/typeorm";

(async () => {
    // load the deposited options otherwise the library
    // will attempt to locate and load the data-source file and
    // extract the options from there
    const options = await useDataSourceOptions();
})();

Single

import { setDataSourceOptions, useDataSource } from "typeorm-extension";
import { DataSourceOptions } from "@bouncecode/typeorm";

const options: DataSourceOptions = {
    // ...
};

setDataSourceOptions(options);

(async () => {
    // now the method can use the deposited configuration.
    const options = await useDataSourceOptions();
})();

Multiple

import { setDataSourceOptions, useDataSource } from "typeorm-extension";
import { DataSourceOptions } from "@bouncecode/typeorm";

const options: DataSourceOptions = {
    // ...
};

setDataSourceOptions(options, "foo");

(async () => {
    // now the method can use the deposited configuration.
    const options = await useDataSourceOptions("foo");
})();

Parameters

NameTypeDescription
aliasstring or undefinedAlias for receiving the typeorm options object. Default: default

Returns

Promise<DataSourceOptions>

Functions - Seeding

runSeeder

function runSeeder(dataSource?: DataSource, seeder: SeederConstructor, options: SeederOptions): Promise<void>

Populate the database with a specific seeder.

Example

Simple

import { DataSource } from "@bouncecode/typeorm";
import { runSeeder, Seeder, SeederFactoryManager } from "typeorm-extension";

class SimpleSeeder implements Seeder {
    public async run(
        dataSource: DataSource,
        factoryManager: SeederFactoryManager
    ): Promise<void> {
        // ...
    }
}

(async () => {
    const dataSource = new DataSource({
        // ...
    });
    await dataSource.initialize();

    await runSeeder(dataSource, SimpleSeeder);
})();

SeederOptions

import { DataSource } from "@bouncecode/typeorm";
import { runSeeder, Seeder, SeederFactoryManager } from "typeorm-extension";

class SimpleSeeder implements Seeder {
    public async run(
        dataSource: DataSource,
        factoryManager: SeederFactoryManager
    ): Promise<void> {
        // ...
    }
}

(async () => {
    const dataSource = new DataSource({
        // ...
    });
    await dataSource.initialize();

    await runSeeder(dataSource, SimpleSeeder, {
        factories: ["src/database/factories/*{.ts,.js}"],
    });
})();

Parameters

NameTypeDescription
dataSourceDataSourceTypeorm DataSource Object
seederSeederConstructorA class which implements the Seeder Interface.
optionsSeederOptionsSeeding options to provide or overwrite the default ones. Details

Returns

Promise<void>

runSeeders

function runSeeders(dataSource?: DataSource, options: SeederOptions): Promise<void>

Populate the database.

Example

Simple

import { DataSource } from "@bouncecode/typeorm";
import { runSeeders } from "typeorm-extension";

(async () => {
    const dataSource = new DataSource({
        // ...
    });
    await dataSource.initialize();

    await runSeeder(dataSource);
})();

SeederOptions

import { DataSource } from "@bouncecode/typeorm";
import { runSeeders } from "typeorm-extension";

(async () => {
    const dataSource = new DataSource({
        // ...
    });
    await dataSource.initialize();

    await runSeeder(dataSource, {
        seeds: ["src/database/seeds/*{.ts,.js}"],
        factories: ["src/database/factories/*{.ts,.js}"],
    });
})();

Parameters

NameTypeDescription
dataSourceDataSourceTypeorm DataSource Object
optionsSeederOptionsSeeding options to provide or overwrite the default ones. Details

Returns

Promise<void>

Functions - Query

applyQueryFields

function applyQueryFields<T>(query: SelectQueryBuilder<T>, data: unknown, options?: FieldsApplyOptions): FieldsApplyOutput

Parse and apply fields of the main entity and optional of included relations passed in as Record<string, string[]> or string[] and apply them to the SelectQueryBuilder, in case they match the allowed fields.

Example

Simple

import { applyQueryFields } from "typeorm-extension";

const fields = applyQueryFields(query, ["name"], {
    allowed: ["id", "name"],
    defaultAlias: "user",
});

console.log(fields);
// [{alias: 'user', fields: ['name']}]

Type parameters

NameDescription
TTypeorm entity type

Parameters

NameTypeDescription
querySelectQueryBuilder<T>Typeorm SelectQueryBuilder Class.
dataunknownFields in raw format. F.e ['name'] or {user: ['name']}.
optionsFieldsApplyOptionsOptions for the fields to select.

Returns

FieldsApplyOutput

The function returns an array of objects. Each object has the properties fields and optional alias and addFields.

applyQueryFilters

function applyQueryFilters<T>(query: SelectQueryBuilder<T>, data: unknown, options?: FiltersApplyOptions): FiltersApplyOutput

Transform filters of the main entity and optional of included relations passed in as Record<string, unknown> and apply them to the SelectQueryBuilder, in case they match the allowed filters.

Example

Simple

import { applyQueryFilters } from "typeorm-extension";

const filters = applyQueryFilters(
    query,
    { id: 1 },
    {
        allowed: ["id", "name"],
        defaultAlias: "user",
    }
);

console.log(filters);
// [{alias: 'user', key: 'id', value: 1}]

Type parameters

NameDescription
TTypeorm entity type

Parameters

NameTypeDescription
querySelectQueryBuilder<T>Typeorm SelectQueryBuilder Class.
dataunknownFields in raw format. F.e {id: 1}.
optionsFiltersApplyOptionsOptions for the fields to select.

Returns

FiltersApplyOutput

The function returns an array of objects. Each object has the properties key and value.

applyQueryRelations

function applyQueryRelations<T>(query: SelectQueryBuilder<T>, data: unknown, options?: RelationsApplyOptions): RelationsApplyOutput

Transform relations passed in as string, string[] and apply them to the SelectQueryBuilder, in case they match the allowed relations.

Example

Simple

import { applyQueryRelations } from "typeorm-extension";

const includes = applyQueryRelations(query, ["roles"], {
    allowed: ["roles", "photos"],
    defaultAlias: "user",
});

console.log(includes);
// [{property: 'user.roles', alias: 'roles'}]

Type parameters

NameDescription
TTypeorm entity type

Parameters

NameTypeDescription
querySelectQueryBuilder<T>Typeorm SelectQueryBuilder Class.
dataunknownRelations in raw format. F.e ['roles'] or roles
optionsRelationsApplyOptionsOptions for the relations to include.

Returns

RelationsApplyOutput

The function returns an array of objects. Each object has the properties property and alias.

applyQueryPagination

function applyQueryPagination<T>(query: SelectQueryBuilder<T>, data: unknown, options?: PaginationApplyOptions): PaginationApplyOutput

Transform pagination data passed in as {limit?: number, offset?: number} and apply it to the SelectQueryBuilder.

Example

Simple

import { applyQueryPagination } from "typeorm-extension";

const pagination = applyQueryPagination(
    query,
    { limit: 100 },
    {
        maxLimit: 50,
    }
);

console.log(pagination);
// {limit: 50}

Type parameters

NameDescription
TTypeorm entity type

Parameters

NameTypeDescription
querySelectQueryBuilder<T>Typeorm SelectQueryBuilder Class.
dataunknownPagination data in raw format. F.e {limit: 20, offset: 10}.
optionsPaginationApplyOptionsOptions for the pagination to select.

Returns

PaginationApplyOutput

The function returns an object. The object might have the properties limit and offset.

applyQuerySort

function applyQuerySort<T>(query: SelectQueryBuilder<T>, data: unknown, options?: SortApplyOptions): SortApplyOutput

Transform sort fields passed in as string, string[] and apply them to the SelectQueryBuilder, in case they match the allowed fields to sort.

Example

Simple

import { applyQuerySort } from "typeorm-extension";

const sort = applyQuerySort(query, ["-name"], {
    allowed: ["id", "name"],
    defaultAlias: "user",
});

console.log(sort);
// {'user.name': 'DESC'}

Type parameters

NameDescription
TTypeorm entity type

Parameters

NameTypeDescription
querySelectQueryBuilder<T>Typeorm SelectQueryBuilder Class.
dataunknownSorting Fields in raw format. F.e ['-name'], -name or {name: 'DESC'}. The hyphen prefix indicates descending order.
optionsSortApplyOptionsOptions for the sorting strategy.

Returns

SortApplyOutput

The function returns an objects. Each key-value pair represents a field and the corresponding sorting direction.

Types

Types - Database

DatabaseBaseContext

import { DataSourceOptions } from "@bouncecode/typeorm";
import { DataSourceFindOptions } from "typeorm-extension";

export type DatabaseBaseContext = {
    /**
     * Options for finding the typeorm DataSource.
     *
     * Default: undefined
     */
    options?: DataSourceOptions;

    /**
     * Options for the find method, where to look for the data-source file.
     */
    findOptions?: DataSourceFindOptions;
};

DatabaseCreateContext

import { DatabaseBaseContext } from "typeorm-extension";

export type DatabaseCreateContext = DatabaseBaseContext & {
    /**
     * Only create database if not already exist.
     *
     * default: true
     */
    ifNotExist?: boolean;
    /**
     * Initial database to connect.
     *
     * default: undefined
     */
    initialDatabase?: string;
    /**
     * Synchronize database entities.
     *
     * default: true
     */
    synchronize?: boolean;
};

DatabaseDropContext

import { DatabaseBaseContext } from "typeorm-extension";

export type DatabaseDropContext = DatabaseBaseContext & {
    /**
     * Only drop database if existed.
     *
     * Default: true
     */
    ifExist?: boolean;
};

Types - Seeding

Seeder

import { DataSource } from "@bouncecode/typeorm";
import { SeederFactoryManager } from "typeorm-extension";

interface Seeder {
    run(
        dataSource: DataSource,
        factoryManager: SeederFactoryManager
    ): Promise<void>;
}

SeederConstructor

import { Seeder } from "typeorm-extension";

type SeederConstructor = new () => Seeder;

SeederOptions

import { SeederConstructor, SeederFactoryConfig } from "typeorm-extension";

export type SeederOptions = {
    seeds?: SeederConstructor[] | string[];
    seedName?: string;

    factories?: SeederFactoryConfig[] | string[];
    factoriesLoad?: boolean;
};

Types - Query

To understand the structure of the parsed query parameter values or to know which values can be passed as (i.e. buildQuery, parseQuery, ...) function argument, check out the Types and Functions section of the README.md file of the @trapi/query library.