1.4.4 • Published 3 years ago

tofo v1.4.4

Weekly downloads
1
License
MIT
Repository
-
Last release
3 years ago

TOFO - TypeORM FindOptions Builder

TOFO stand for TypeORM FindOptions. this library allows you to transform automatically url query into TypeORM FindOptions queries.

Installation

npm install tofo

How it works?

npm.io

Usage

Quick Start

Use FindOptionBuilder export from package and pass your req.query as an argument.

Given the following url query string:

foo/?name__contains=foo&role__in=admin,common&age__gte=18&page=3&limit=10

Then build the query into FindOptions

import { FindOptionBuilder } from 'tofo';

const builder = new FindOptionBuilder(req.query);
const builtQuery = builder.build();

It will be transformed into:

{
  where: {
    foo: Like('%foo%'),
    role: In(['admin', 'common']),
    age: MoreThanOrEqual(18)
  },
  skip: 20,
  take: 10
}

Now your query is builted, pass it to your TypeORM repository.

const results = await fooRepository.find(builtQuery);

For another available syntax can be found in here:

Allowed Fields

By default, tofo accepting all fields passed in req.query. If you need to filtering for only some fields you can use setAllowedFields() function.

// Let's say this query got from req.query
const query = { name: "foo", status: "active", location: "Sukowati", limit: 5 };

const builder = new FindOptionBuilder(query);
// Set allowed fields
builder.setAllowedFields(['limit']);
builder.setAllowedFields(['name', 'status']);

// Build query
const builtQuery = builder.build();

It will be transformed into:

{
  skip: 0,
  take: 5,
  where: {
    name: 'foo',
    status: 'active'
  },
}

WARNING: you also need to set allowed builtin query options keys if needed, otherwise the keys will be removed before build.

Using POST method to retrieve data

Instead using req.query from GET method, you also can send data using POST method and retrieve the data from req.body.

curl --location --request POST 'http://localhost/api/foo' \
--header 'Content-Type: application/json' \
--data-raw '{
    "name": "foo",
    "status": "active"
}'

And handle data like

app.post('/api/foo', (req, res) => {
  const builder = new FindOptionBuilder(req.body); // => Process data from req.body
  const builtQuery = builder.build();
})

Available Lookups

LookupBehaviourExample
(none)Return entries that match with valuefoo=raul
containsReturn entries that contains valuefoo__contains=lopez
startswithReturn entries that starts with valuefoo__startswith=r
endswithReturn entries that ends with valuefoo__endswith=dev
isnullReturn entries with null valuefoo__isnull
ltReturn entries with value less than or equal to providedfoo__lt=18
lteReturn entries with value less than providedfoo__lte=18
gtReturns entries with value greater than providedfoo__gt=18
gteReturn entries with value greater than or equal to providedfoo__gte=18
inReturn entries that match with values in listfoo__in=admin,common
betweenReturn entries in rangefoo__between=1,27

Notice

You can use negative logic prefixing lookup with __not. Example: foo__not__contains=value

Querying a column from an embedded entity. Example: user.name=value

OR condition union

// ?$or=name:juste|age__gte:15&$or=user.role:admin
{
  where: [
    { name: 'juste', age: MoreThanOrEqual('15') },
    { user: { role: 'admin' } }
  ]
}

// ?city=Dahomey&$or=name:juste|age__gte:15&$or=user.role:admin
{
  where: [
    { name: 'juste', city: 'Dahomey', age: MoreThanOrEqual('15') },
    { user: { role: 'admin' }, city: 'Dahomey' }
  ]
}

Query Option Keys

OptionDefaultBehaviourExample
paginationtrueIf true, paginate results. If false, disable paginationpagination=false
page1Return entries for page pagepage=2
limit25Return entries for page page paginated by size limitlimit=15
order-Order for fields:^: Ascendant -: Descendantorder=^foo,-name,^surname
join-Set relationsjoin=posts,comments
select-Set fields selectionselect=name,phoneNumber

NOTE: If you using AllowedFields you also need to include these option keys also.


Available Methods

Remove precautionary fields from the query before building

removeField(field: string): FindOptionBuilder

Set Allowed Fields from the query before building

setAllowedFields(['allowed_field1', 'allowed_field2']): FindOptionBuilder

Others

You can use the frontend query builder to go faster without having to worry too much about the syntax.