added more docs

This commit is contained in:
Umed Khudoiberdiev 2016-04-12 09:38:57 +03:00
parent ae94b9bfc7
commit ae76db3211
16 changed files with 595 additions and 99 deletions

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
// Place your settings in this file to overwrite default and user settings.
{
}

View File

@ -5,7 +5,7 @@
TypeORM is an [Object Relational Mapper](1) (ORM) for node.js written in
Typescript that can help you to:
* automatically create your table schemas based on your model
* automatically create your table schemas based on your models
(javascript class, decorated with special decorators)
* ability to transparently insert / update / delete to the database
your objects
@ -17,7 +17,7 @@ between tables
TypeORM uses Data Mapper pattern, unlike all other javascript ORMs that
currently exist, which means you can write loosely coupled, scalable,
maintainable enterprise applications easily.
maintainable enterprise applications with less problems.
The benefit of using ORM for the programmer is the ability to focus on
the business logic and worry about persistence only as a secondary problem.
@ -49,11 +49,11 @@ need to do:
## Example
Lets create a sample application - photo album.
Lets create a sample application - a photo album.
#### create Photo entity class
First we create a new file `Photo.ts` and create a class there:
First we create a new file `Photo.ts` and put a class there:
```typescript
import {Table} from "typeorm/decorator/Tables";
@ -659,7 +659,7 @@ whose name is "My" or "Mishka", it will select results from 5 position
Selection result will be ordered by id in descending order. Photo's albums
will be left-joined and photo's metadata will be inner joined.
Learn more about FindOptions [here]().
Learn more about FindOptions [here](docs/repository.md#find-options).
#### using QueryBuilder to build complex queries
@ -688,7 +688,7 @@ whose name is "My" or "Mishka", it will select results from 5 position
Selection result will be ordered by id in descending order. Photo's albums
will be left-joined and photo's metadata will be inner joined.
Learn more about QueryBuilder [here]().
Learn more about QueryBuilder [here](docs/query-builder.md).
#### using EntityManager to work with any entity
@ -739,13 +739,13 @@ entityManager
});
```
Learn more about EntityManager [here]().
Learn more about EntityManager [here](docs/entity-manager.md).
## Learn more
* [connection and connection options](docs/connection-and-connection-options.md)
* [updating database schema](docs/updating-database-schema.md)
* [databases and drivers](docs/databases-and-drivers.md)
* [updating database schema](docs/updating-database-schema.md)
* [tables and table inheritance](docs/tables-and-table-inheritance.md)
* [table columns](docs/table-columns.md)
* [relations](docs/relations.md)
@ -755,6 +755,8 @@ Learn more about EntityManager [here]().
* [entity manager](docs/entity-manager.md)
* [subscribers and entity listeners](docs/subscribers-and-entity-listeners.md)
* [naming strategies](docs/naming-strategies.md)
* [decorators reference](docs/decorators-reference.md)
* [command line tools](docs/command-line-tools.md)
## Samples
@ -763,11 +765,11 @@ usages.
## Todos
ORM development is in progress. Readme and documentations expected to be soon.
ORM development is in progress. Api can be changed a lot. More documentation and features expected to be soon.
Feel free to contribute ;)
* add partial selection support
* in query builder should we use property names or table names? (right now its mixed)
* add partial selection support (lot of problems with partial selection. Is there real benefit for users to use it?)
* in query builder should we use property names or table names? (right now its kinda mixed)
* should all entities have a primary column?
* think about indices
* think more about cascades

View File

@ -0,0 +1,3 @@
## Command Line Tools
TBD

View File

@ -1,3 +1,159 @@
## Connection and connection options
TBD
You start using ORM by creating a connection with the database. In this section you will learn about:
* [Connection Manager that contains all connections to the databases](#connection-manager)
* [Working with connections](#working-with-connection)
* [Connection options](#connection-options)
* [How to use connection manager, connections and connection options](#example)
### Connection Manager
Connection manager allows to create a new connections and retrive previously created connections. Also it allows to import
entities and subscribers into specific connection. These are main public methods of the `ConnectionManager`:
* `createConnection(connectionName: string = "default", driver: Driver, options: ConnectionOptions): Connection`
Creates a new connection and registers it in the connection manager. It returns a newly created connection.
New connection will have a given *connection name*. If connection name is not given then "default" will be used as a
connection name. This name will be used to retrieve this connection later.
*Driver* needs to be specified to understand what kind of database will be used for this connection.
Right now it can be only a `mysql` driver.
*Options* specifies connection options. More about it later.
* `getConnection(connectionName: string = "default"): Connection`
Gets a connection with a given name that was created using `createConnection` method. Connection later can be used to
perform actions on it.
* `importEntities(connectionName: string = "default", entities: Function[]): void`
Imports all given entities and registers them in the connection with a given name.
* `importSubscribers(connectionName: string = "default", subscribers: Function[]): void`
Imports all given subscribers and registers them in the connection with a given name.
* `importEntitiesFromDirectories(connectionName: string = "default", paths: string[]): void`
Imports all entities from the given directories and registers them in the connection with a given name.
Paths is an array of directories from where to import entities.
* `importSubscribersFromDirectories(connectionName: string = "default", paths: string[]): void`
Imports all subscribers from the given directories and registers them in the connection with a given name.
Paths is an array of directories from where to import subscribers.
### Working with Connection
Connection is a database connection to specific database of the specific database management system.
There are several useful methods in the Connection object:
* `connect()`
Opens a new connection with the database.
* `close()`
Closes connection with the database.
* `getEntityManager()`
Gets [EntityManager](entity-manager.md) that is used to execute database operations on any entity
that is registered in this connection.
* `getRepository(entityClass: Function)`
Gets a [repository](repository.md) of the specific entity that provides all functionality
(selects/inserts/updates/deletes) with a table of the given entity class.
### Connection Options
To perform a connection you need to specify a connection options. ConnectionOptions is an interface:
```typescript
export interface ConnectionOptions {
url?: string; // connection url
host?: string; // database host
port?: number; // database host port
username?: string; // database username
password?: string; // database password
database?: string; // database name
autoSchemaCreate?: boolean; // set to true if you want your database schema to be auto created on each application launch
logging?: {
logger?: (message: any, level: string) => void; // some specific logger to be used. By default it is a console
logQueries?: boolean; // used if you want to log every executed query
logOnlyFailedQueries?: boolean; // used if you want to log only failed query
logFailedQueryError?: boolean; // used if you want to log error of the failed query
};
}
```
* To perform a connection you either must specify a connection `url`, either specify `host/port/username/password/database`.
* `autoSchemaCreate` allows you to automatically synchronize your database schema (create new tables,
remove/rename old columns, create foreign keys, etc.) on each application run. Note that there can be errors in schema
synchronization (mostly errors can be caused by unresolved foreign keys) and this will crash your application.
This option should not be used in production, only during development and only if you are too lazy to use
[command line tools](command-line-tools.md). Alternatively you can use [schema update gulp plugin](todo).
### Example
```typescript
// create a new connection manager
let connectionManager = new ConnectionManager();
// prepare connection options
let connectionOptions: ConnectionOptions = {
host: "localhost",
port: 3306,
username: "root",
password: "admin",
database: "test",
autoSchemaCreate: true
};
// create a new connection with mysql driver
connectionManager.createConnection(new MysqlDriver(), connectionOptions);
// import all entities from specific directory
connectionManager.importEntitiesFromDirectories(__dirname + "/entities");
// get our connection:
let connection = connectionManager.getConnection();
connection.connect().then(connection => {
// now we are connected to the database
// here we have a connection and we can use any of its methods
// lets say we have a Photo entity in the /entities directory
// and lets create a new Photo entity instance
// lets try to use entity manager
let entityManager = connection.getEntityManager();
// and lets create a new Photo entity instance
let photo = new Photo();
photo.name = "photo #1";
// and save it using entity manager
entityManager
.persist(photo)
.then(photo => {
console.log("Photo has been saved using entity manager");
});
// lets try to use repository
let repository = connection.getRepository(Photo);
// and lets create a new Photo entity instance
let photo = new Photo();
photo.name = "photo #2";
// and save it using repository
repository
.persist(photo)
.then(photo => {
console.log("Photo has been saved using repository");
});
}).catch(error => {
// looks like some error during connection. Lets log it to find details
console.log("error during connection to the database ", error);
});
```

View File

@ -1,3 +1,36 @@
## Databases and drivers
TBD
ORM is working with databases. To communicate with database it uses **database drivers**.
Database Driver communicates with specific database and performs queries you need.
### Driver Interface
Right now only `mysql` database driver is supported. If you need other driver, or you simply
want to contribute then feel free to add it - adding new drivers is not complicated.
Drivers are typically used within connection:
`let connection = connectionManager.createConnection("my-connection", new MysqlDriver());`
To access the driver you can do it from your connection instance:
`connection.driver`
There are several useful methods in the driver object:
* `driver.native`
Allows you to access a native layer of the driver. For example MysqlDriver is depend of npm's `mysql` package
and `mysqlDriver.native` will give you instance to that package.
* `driver.nativeConnection`
Allows you to access to a connection instance of the native layer of the driver. For example MysqlDriver is depend of
npm's `mysql` package and when we create a connection using that package it returns us some `connection instance` that
we save in the driver.nativeConnection.
Both methods are not recommended to use, but sometimes you have no choice because of the limits of the ORM abstraction
and you have to use them. In such situations both methods are very useful.
There are lot of other methods in the Driver, but you won't use them directly - they are used by other components, like
[Entity Manager](entity-manager.md) or [Repository](repository.md). You should use those components instead.

View File

@ -0,0 +1,3 @@
## Decorators Reference
TBD

View File

@ -1,3 +1,41 @@
## Relations
TBD
One of the best sides of TypeORM is relations support. You can build relations between your tables
easily without thinking of database schema and foreign keys. Relations are created using special decorators
on specific fields of entity objects.
* [@OneToOne and @OneToOneInverse decorators](#@OneToOne-and-@OneToOneInverse-decorators)
* [@OneToMany and @ManyToOne decorators](#@OneToMany-and-@ManyToOne-decorators)
* [@ManyToMany and @ManyToManyInverse decorators](#@ManyToMany-and-@ManyToManyInverse-decorators)
* [Self referencing](#self-referencing)
* [Relational decorators options](#RelationOptions)
### @OneToOne and @OneToOneInverse decorators
TBD
### @OneToMany and @ManyToOne decorators
TBD
### @ManyToMany and @ManyToManyInverse decorators
TBD
### Self referencing
TBD
### Relational decorators options
RelationOptions is an object with additional relation options:
* `name?: string` - column name for the relation in the database
* `cascadeInsert?: boolean` - allow cascade insert operations or not. If you set this to true, then any entity that
is new (means does not exist in the database) on the relation will be persisted too.
* `cascadeUpdate?: boolean` - allow cascade update operations or not. If you set this to true, then related entity
will be updated in the database if it was changed.
* `cascadeRemove?: boolean` - allow cascade remove operations or not. If you set this to true, then related entity
will be removed from the database if it was removed from this object.
* `onDelete?: string` - Database-level operation `ON DELETE` is an action that must be performed when related row in
the database has been removed.

View File

@ -1,3 +1,75 @@
## Repository
TBD
For each entity you have there is a Repository for it. Repository provides functionality to work with your entity.
There are several useful methods of the Repository:
* `hasId(entity: Entity): boolean`
Sometimes you want to check if your entity already has id or not. This maybe useful in situations when you want to
check if your object is new or not.
* `create(plainJsObject?: Object): Entity`
Creates a new empty instance of entity. If `plainJsObject` is given then new entity will be created and all properties
from the `plainJsObject` that can be mapped to this entity will be copied to the new entity.
* `createMany(plainJsObjects: Object[]): Entity[]`
Creates multiple new entities based on array of plain javascript objects. Properties for each plain javascript object
will be copied to newly created entities if they should exist there.
* `initialize(object: Object): Promise<Entity>`
Creates a new entity from the given plan javascript object. If entity already exist in the database, then
it loads it (and everything related to it), replaces all values with the new ones from the given object
and returns this new entity. This new entity is actually a loaded from the db entity with all properties
replaced from the new object.
* `persist(entity: Entity): Promise<Entity>`
Persists (saves) a given entity in the database. If entity does not exist in the database then it inserts it,
else if entity already exist in the database then it updates it.
* `remove(entity: Entity): Promise<Entity>`
Removes a given entity from the database.
* ```typescript
find(): Promise<Entity[]>
find(conditions: Object): Promise<Entity[]>;
find(options: FindOptions): Promise<Entity[]>;
find(conditions: Object, options: FindOptions): Promise<Entity[]>;
```
Finds entities that match given conditions or given find options.
* ```typescript
findOne(): Promise<Entity>;
findOne(conditions: Object): Promise<Entity>;
findOne(options: FindOptions): Promise<Entity>;
findOne(conditions: Object, options: FindOptions): Promise<Entity>;
```
Finds the first entity that match given conditions or given find options.
* `findById(id: any, options?: FindOptions): Promise<Entity>`
Finds entity with a given entity id.
* `findAndCount(conditions?: Object, options?: FindOptions): Promise<{ items: Entity[], count: number }>`
Finds entities that match given conditions or given find options plus gets a overall count of this items (for
pagination purposes).
* `createQueryBuilder(alias: string): QueryBuilder<Entity>`
Creates a new query builder that can be used to build a sql query and get the results of the executed query. You can
learn more about query builder [here](docs/query-builder.md).
* `query(sql: string): Promise<any>`
Executes raw SQL query.
* `transaction(runInTransaction: () => Promise<any>): Promise<any>`
Executes everything in the given function in a single transaction.

View File

@ -1,70 +1,172 @@
## Tables and columns
## Table columns
### Creating a basic table
Entity consist of columns. For each entity column, column in the database will be created.
Every object that you want to be saved in the database must have `@Table`
decorator and each property you want to be saved from your object must
have `@Column` decorator. Let's start with an example:
* [@Column decorator](#@column)
* [@PrimaryColumn decorator](#@primary-column)
* [@CreateDateColumn decorator](#@create-date-column)
* [@UpdateDateColumn decorator](#@update-date-column)
* [Column types](#column-type)
* [Column options](#column-options)
* [Columns usage example](#example)
#### @Column
Column decorator simply marks an entity property to be a table column.
There are several column decorator signatures:
```typescript
@Column(options?: ColumnOptions)
@Column(type?: ColumnType, options?: ColumnOptions)
```
#### @PrimaryColumn
PrimaryColumn marks an entity property as a column and creates a primary key for it.
There are several column decorator signatures:
```typescript
@PrimaryColumn(options?: ColumnOptions)
@PrimaryColumn(type?: ColumnType, options?: ColumnOptions)
```
#### @CreateDateColumn
CreateDateColumn adds a simple datetime column to the table. During its first persistence (e.g. insertion) it
sets current date as a value of the property object.
```typescript
@CreateDateColumn(options?: ColumnOptions)
```
#### @UpdateDateColumn
UpdateDateColumn adds a simple datetime column to the table. Each time object is persisted, this column value is updated
to the current date.
```typescript
@CreateDateColumn(options?: ColumnOptions)
```
#### ColumnType
ColumnType can be one of:
* `string` will be mapped to db's `varchar`
* `text` will be mapped to db's `text`
* `number` will be mapped to db's `double`
* `integer` will be mapped to db's `int`
* `int` will be mapped to db's `int`
* `smallint` will be mapped to db's `int`
* `bigint` will be mapped to db's `int`
* `float` will be mapped to db's `float`
* `double` will be mapped to db's `double`
* `decimal` will be mapped to db's `decimal`
* `date` will be mapped to db's `datetime`
* `time` will be mapped to db's `time`
* `datetime` will be mapped to db's `datetime`
* `boolean` will be mapped to db's `boolean`
* `json` will be mapped to db's `text`
* `simple_array` will be mapped to db's `text`
If you omit a column type, type will be guessed automatically based on variable type:
* `number` will be mapped to `float`
* `boolean` will be mapped to `boolean`
* `string` will be mapped to `varchar`
* `Date` will be mapped to `datetime`
#### ColumnOptions
ColumnOptions is an object with additional column options:
* `name?: string` - column name in the database
* `type?: ColumnType` - column type also can be specified via column options
* `length?: string` - column type's length. For example type = "string" and length = 100 means that ORM will create a
column with type varchar(100).
* `autoIncrement?: boolean` - specifies if this column will use AUTO_INCREMENT or not (e.g. generated number)
* `unique?: boolean` - specifies if column's value must be unique or not.
* `nullable?: boolean` - indicates if column's value can be set to NULL.
* `columnDefinition?: string` - Extra column definition. Should be used only in emergency situations.
Note that if you'll use this property auto schema generation will not work properly anymore.
* `comment?: string` - column comment
* `precision?: number` - The precision for a decimal (exact numeric) column (applies only for decimal column), which is the maximum
number of digits that are stored for the values.
* `scale?: number` - The scale for a decimal (exact numeric) column (applies only for decimal column), which represents the number
of digits to the right of the decimal point and must not be greater than precision.
* `collation?: string` - Column collation. Note that not all databases support it.
#### Example
```typescript
@Table("photo")
class Photo {
@PrimaryColumn()
/**
* Primary column with auto increment key.
*/
@PrimaryColumn("int", { autoIncrement: true })
id: number;
/**
* Simple string column.
*/
@Column()
name: string;
/**
* Simple boolean column.
*/
@Column()
filename: string;
isPublished: boolean;
/**
* Simple numeric (float) column.
*/
@Column()
scale: number;
/**
* Simple numeric (integer) column.
*/
@Column("integer")
size: number;
/**
* Simple column that contains a date.
*/
@Column()
publishedDate: Date;
/**
* Simple column that contains a big text.
*/
@Column("text")
description: string;
/**
* Simple column that contains a short text.
*/
@Column({
length: 3
})
locale: string;
/**
* This column's value must be unique.
*/
@Column({
unique: true
})
slug: string;
/**
* This column's value can be nullable.
*/
@Column({
nullable: true
})
metadata: string;
}
```
* `@Table` decorator registers your class in ORM, and allows you to make
different operations with instances of this class directly in the db.
After you mark your class with this decorator and run schema update
process, ORM will create a table in the db for you, with all proper
columns, keys and so on. After you define your class as a @Table you
can do various operations like inserting, updating, removing, fining
objects of this class in the database. In this example we also specified
a name for this table (`@Table("photo")`). ORM will create a table in
the database with such name - "photos".
* `@Column` decorator marks properties of your class to be persisted into
the database. For each property of your class decorated by `@Table`
decorator ORM will create a column in the table, and this property's
value will be saved to database when you'll save a class instance.
* `@PrimaryColumn` decorator marks a property of your class that must
be a primary-key in your table. It works the same way as @Column decorator,
but the main difference is that it also creates a PRIMARY KEY for this
column. This decorator is always used when you want to create an id-based
column, including auto-increment id.
### Primary and regular columns
By default column type used in the database is automatically guessed
from property type. But type that is set for property is not desirable
for the type used in the database. For example type `number
You can specify a type of column that will be used `@Column`
```typescript
@Table("photo")
class Photo {
@Column("string")
name: string;
@Column()
filename: string;
@Column()
description: string;
}
```

View File

@ -1,3 +1,57 @@
## Tables and table inheritance
TBD
### Tables
ORM creates tables for each class that you decorated with `@Table` decorator and which you loaded into your
connection.
```typescript
@Table("photos")
export class Photo {
}
```
Each table must have a primary column (using `@PrimaryColumn` decotator) [*todo: really?*] and can contain
other [columns](table-columns.md).
### Table inheritance
If multiple tables has same properties you may want to find them a common abstraction and create a base
class for them. In this base class you'll have a common for all inherited classes columns. To ahieve this you
must mark your table with `@AbstractTable()` decorator:
```typescript
@AbstractTable()
export class BasePhoto {
@PrimaryColumn("int", { autoIncrement: true })
id: string;
@Column()
name: string;
@Column()
url: string;
}
@Table("public_photos")
export class Photo extends BasePhoto {
@Column()
authorName: string;
}
@Table("private_photos")
export class Photo extends BasePhoto {
@Column()
isPublished: boolean;
}
```
This will create you two tables `public_photos` and `private_photos` with 5 columns each.
Right now only columns are inherited. Relations are ignored.

View File

@ -1,3 +1,17 @@
## Updating database schema
TBD
Your database schema is managed automatically by ORM:
* tables are created for all entities
* columns are created for all entity columns
* foreign keys are set for all relations
* junction tables are created for all many-to-many relations
All this must be in sync to make ORM to work correctly. To make a synchronization there are two ways:
* set in [connection options](connection-and-connection-options.md#connection-options) `autoSchemaCreate: true`.
In this case database schema will be automatically synchronized each time you run the application.
* use [schema update gulp plugin](todo) and run schema synchronization process each time you need it.
First approach is not recommended to use in production, however it can be handy during development.

View File

@ -121,27 +121,8 @@ export class Connection {
}
/**
* Registers entity metadatas for the current connection.
* Gets EntityManager of this connection.
*/
addEntityMetadatas(metadatas: EntityMetadata[]) {
this._entityMetadatas = this._entityMetadatas.concat(metadatas);
this.repositoryAndMetadatas = this.repositoryAndMetadatas.concat(metadatas.map(metadata => this.createRepoMeta(metadata)));
}
/**
* Registers entity listener metadatas for the current connection.
*/
addEntityListenerMetadatas(metadatas: EntityListenerMetadata[]) {
this._entityListenerMetadatas = this._entityListenerMetadatas.concat(metadatas);
}
/**
* Registers subscribers for the current connection.
*/
addSubscribers(subscribers: OrmSubscriber<any>[]) {
this._subscribers = this._subscribers.concat(subscribers);
}
getEntityManager() {
return this.entityManager;
}
@ -164,11 +145,33 @@ export class Connection {
getEntityMetadata(entityClass: Function): EntityMetadata {
const metadata = this.entityMetadatas.find(metadata => metadata.target === entityClass);
if (!metadata)
throw new MetadataNotFoundError(entityClass);
throw new MetadataNotFoundError(entityClass);
return metadata;
}
/**
* Registers entity metadatas for the current connection.
*/
addEntityMetadatas(metadatas: EntityMetadata[]) {
this._entityMetadatas = this._entityMetadatas.concat(metadatas);
this.repositoryAndMetadatas = this.repositoryAndMetadatas.concat(metadatas.map(metadata => this.createRepoMeta(metadata)));
}
/**
* Registers entity listener metadatas for the current connection.
*/
addEntityListenerMetadatas(metadatas: EntityListenerMetadata[]) {
this._entityListenerMetadatas = this._entityListenerMetadatas.concat(metadatas);
}
/**
* Registers subscribers for the current connection.
*/
addSubscribers(subscribers: OrmSubscriber<any>[]) {
this._subscribers = this._subscribers.concat(subscribers);
}
// -------------------------------------------------------------------------
// Private Methods
// -------------------------------------------------------------------------

View File

@ -44,7 +44,7 @@ export interface ConnectionOptions {
logging?: {
/**
* Some specific logger to be used. By default it console.
* Some specific logger to be used. By default it is a console.
*/
logger?: (message: any, level: string) => void;

View File

@ -13,6 +13,11 @@ export interface Driver {
*/
native: any;
/**
* Access to the connection of the native interface of the database.
*/
nativeConnection: any;
/**
* Connection used in this driver.
*/

View File

@ -45,6 +45,13 @@ export class MysqlDriver extends BaseDriver implements Driver {
get native(): any {
return this.mysql;
}
/**
* Access to the native implementation of the database.
*/
get nativeConnection(): any {
return this.mysqlConnection;
}
/**
* Database name to which this connection is made.

View File

@ -32,7 +32,7 @@ export class Repository<Entity> {
}
/**
* Creates a new query builder that can be used to build an sql query.
* Creates a new query builder that can be used to build a sql query.
*/
createQueryBuilder(alias: string): QueryBuilder<Entity> {
return this.connection.driver
@ -56,7 +56,7 @@ export class Repository<Entity> {
/**
* Creates a entities from the given array of plain javascript objects.
*/
createMany(copyFromObjects: any[]): Entity[] {
createMany(copyFromObjects: Object[]): Entity[] {
return copyFromObjects.map(object => this.create(object));
}
@ -80,7 +80,8 @@ export class Repository<Entity> {
}
/**
* Persists (saves) a given entity in the database.
* Persists (saves) a given entity in the database. If entity does not exist in the database then it inserts it,
* else if entity already exist in the database then it updates it.
*/
persist(entity: Entity): Promise<Entity> {
let loadedDbEntity: any;
@ -115,7 +116,7 @@ export class Repository<Entity> {
}
/**
* Finds entities that match given conditions.
* Finds all entities.
*/
find(): Promise<Entity[]>;
@ -125,7 +126,7 @@ export class Repository<Entity> {
find(conditions: Object): Promise<Entity[]>;
/**
* Finds entities that match given conditions.
* Finds entities with options applied.
*/
find(options: FindOptions): Promise<Entity[]>;