Skip to content
This repository was archived by the owner on Sep 2, 2025. It is now read-only.

Commit 3518aac

Browse files
author
Dekel Barzilay
committed
Migrated to Objection v2
1 parent c9be8e2 commit 3518aac

File tree

5 files changed

+79
-78
lines changed

5 files changed

+79
-78
lines changed

README.md

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -141,35 +141,33 @@ Note that all this eager related options are optional.
141141

142142
- **`allowedEager`** - relation expression to limit the allowed eager queries in
143143
the service. Defaults to `'[]'`, meaning no eager queries allowed. See
144-
[`allowEager`](https://vincit.github.io/objection.js/api/query-builder/eager-methods.html#alloweager)
144+
[`allowGraph`](https://vincit.github.io/objection.js/api/query-builder/eager-methods.html#allowgraph)
145145
documentation.
146146
- **`eagerFilters`** - option to impose compulsory eager filter. It takes an
147147
object or array of objects with the following properties:
148148
- `expression` - the relation expression that the filter will be applied.
149149
- `filter` - the filter function. It uses
150-
[`modifyEager`](https://vincit.github.io/objection.js/api/query-builder/eager-methods.html#modifyeager)
150+
[`modifyGraph`](https://vincit.github.io/objection.js/api/query-builder/eager-methods.html#modifygraph)
151151
internally.
152-
- **`namedEagerFilters`** - object containing named eager filter functions.
153-
Filter is opt-in via `$eager` parameter.
154152

155153
#### Query Operators
156154

157-
- **`$eager`** - eager load relations defined in models'
158-
`relationMappings` getter methods or in the `namedEagerFilters` option. See
159-
[`eager`](https://vincit.github.io/objection.js/api/query-builder/eager-methods.html#eager) documentation.
160-
- **`$joinRelation`** - filter based on a relation's field. See
161-
[`joinRelation`](https://vincit.github.io/objection.js/api/query-builder/join-methods.html#joinrelation)
155+
- **`$eager`** - eager load relations defined in models' `relationMappings` getter methods. See
156+
[`withGraphFetched`](https://vincit.github.io/objection.js/api/query-builder/eager-methods.html#withgraphfetched) documentation.
157+
158+
- **`$joinRelation`** - filter based on a relation's field. use with `$eager` to also fetch the relation. See
159+
[`joinRelated`](https://vincit.github.io/objection.js/api/query-builder/join-methods.html#joinrelated)
162160
documentation.
163-
- **`$joinEager`** - filter based on a relation's field using
164-
`JoinEagerAlgorithm`. See
165-
[`$joinEager`](https://vincit.github.io/objection.js/api/query-builder/eager-methods.html#joineager)
161+
162+
- **`$joinEager`** - filter based on a relation's field. See
163+
[`withGraphJoined`](https://vincit.github.io/objection.js/api/query-builder/eager-methods.html#withgraphjoined)
166164
documentation.
165+
167166
- **`$modifyEager`** - filter relation based on a relation's field,
168167
e.g. `companies.find({ query: { $eager: 'employees', $modifyEager: { employees: { name: 'John' } } } })`
168+
169169
- **`$mergeEager`** - merge an eager expression to `$eager`,
170170
e.g. `companies.find({ query: { $eager: 'employees', $mergeEager: 'ceos' } })`
171-
- **`$pick`** - pick properties from result models. See
172-
[`pick`](https://vincit.github.io/objection.js/api/query-builder/other-methods.html#pick) documentation.
173171

174172
- **`$select`** - add SELECT statement with given array of column names. See
175173
[`$select`](https://vincit.github.io/objection.js/api/query-builder/find-methods.html#select) documentation.
@@ -212,10 +210,8 @@ Note that all this eager related options are optional.
212210
[`transaction`](https://vincit.github.io/objection.js/api/objection/#transaction)
213211
documentation.
214212

215-
- **`mergeAllowEager`** - Just like allowEager but instead of replacing query
216-
builder’s allowEager expression this method merges the given expression to the
217-
existing expression. See
218-
[`mergeAllowEager`](https://vincit.github.io/objection.js/api/query-builder/eager-methods.html#mergealloweager)
213+
- **`mergeAllowEager`** - Will merge the given expression to the existing expression from the `allowEager` service option.
214+
See [`allowGraph`](https://vincit.github.io/objection.js/api/query-builder/eager-methods.html#allowgraph)
219215
documentation.
220216

221217
### Composite primary keys
@@ -315,7 +311,7 @@ included in `$eager` query when using the `update` service method._
315311
- **`allowedUpsert`** - relation expression to allow relations to be upserted
316312
along with update. Defaults to `null`, meaning relations will not be
317313
automatically upserted unless specified here. See
318-
[`allowUpsert`](https://vincit.github.io/objection.js/api/query-builder/mutate-methods.html#allowupsert)
314+
[`allowGraph`](https://vincit.github.io/objection.js/api/query-builder/eager-methods.html#allowgraph)
319315
documentation.
320316
- **`upsertGraphOptions`** - See
321317
[`upsertGraphOptions`](https://vincit.github.io/objection.js/api/types/#type-upsertgraphoptions)
@@ -364,7 +360,7 @@ included in `$eager` query._
364360
- **`allowedInsert`** - relation expression to allow relations to be created
365361
along with insert. Defaults to `null`, meaning relations will not be
366362
automatically created unless specified here. See
367-
[`allowInsert`](https://vincit.github.io/objection.js/api/query-builder/mutate-methods.html#allowinsert)
363+
[`allowGraph`](https://vincit.github.io/objection.js/api/query-builder/eager-methods.html#allowgraph)
368364
documentation.
369365
- **`insertGraphOptions`** - See
370366
[`insertGraphOptions`](https://vincit.github.io/objection.js/api/types/#type-insertgraphoptions)
@@ -425,11 +421,6 @@ module.exports = function(app) {
425421
paginate,
426422
whitelist: ['$eager', '$joinRelation'],
427423
allowedEager: '[user, subtask]',
428-
namedEagerFilters: {
429-
unDone: function(builder) {
430-
builder.where('done', false);
431-
}
432-
},
433424
eagerFilters: [
434425
{
435426
expression: 'subtask',
@@ -533,7 +524,7 @@ class User extends Model {
533524
};
534525
}
535526

536-
static get namedFilters() {
527+
static get modifiers() {
537528
return {
538529
active: builder => {
539530
builder.where('status', 'active');
@@ -624,13 +615,16 @@ class Todo extends Model {
624615
};
625616
}
626617

627-
static get namedFilters() {
618+
static get modifiers() {
628619
const knex = this.app.get('knex');
629620

630621
return {
622+
unDone: function(builder) {
623+
builder.where('complete', false);
624+
},
631625
overdue: builder => {
632626
builder
633-
.where('complete', '=', false)
627+
.where('complete', false)
634628
.where('dueDate', '<', knex.fn.now());
635629
}
636630
};
@@ -811,18 +805,30 @@ try {
811805
812806
## Migrating to `feathers-objection` v2
813807
814-
`feathers-objection` 2.0.0 comes with important security and usability updates.
808+
`feathers-objection` 2.0.0 comes with important security and usability updates
815809
816-
> **Important:** For general migration information to the new database adapter
817-
> functionality see
818-
> [crow.docs.feathersjs.com/migrating.html#database-adapters](https://crow.docs.feathersjs.com/migrating.html#database-adapters).
810+
> **Important:** For general migration information to the new database adapter functionality see
811+
> [crow.docs.feathersjs.com/migrating.html#database-adapters](https://crow.docs.feathersjs.com/migrating.html#database-adapters)
819812
820813
The following breaking changes have been introduced:
821814
822815
- All methods allow additional query parameters
823816
- Multiple updates are disabled by default (see the `multi` option)
824817
- Objection related operators are disabled by default (see the `whitelist`
825818
option)
819+
820+
## Migrating to `feathers-objection` v5
821+
822+
`feathers-objection` 5.0.0 comes with usability updates and was migrated to use Objection v2
823+
824+
> **Important:** For general migration information to Objection v2 see
825+
> [https://vincit.github.io/objection.js/release-notes/migration.html](https://vincit.github.io/objection.js/release-notes/migration.html)
826+
827+
The following breaking changes have been introduced:
828+
829+
- `$pick` query operator was removed
830+
- `namedEagerFilters` service option was removed. use Model's [`modifiers`](https://vincit.github.io/objection.js/recipes/modifiers.html#modifiers) instead
831+
- Model's `namedFilters` property was renamed to `modifiers`
826832
827833
## License
828834

src/index.js

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,6 @@ const NON_COMPARISON_OPERATORS = [
6666
'?&'
6767
];
6868

69-
const NO_RELATIONS = RelationExpression.create('[]');
70-
7169
/**
7270
* Class representing an feathers adapter for Objection.js ORM.
7371
* @param {object} options
@@ -93,8 +91,7 @@ class Service extends AdapterService {
9391

9492
this.idSeparator = options.idSeparator || ',';
9593
this.jsonSchema = options.model.jsonSchema;
96-
this.allowedEager = options.allowedEager && RelationExpression.create(options.allowedEager);
97-
this.namedEagerFilters = options.namedEagerFilters;
94+
this.allowedEager = options.allowedEager;
9895
this.eagerFilters = options.eagerFilters;
9996
this.allowedInsert = options.allowedInsert && RelationExpression.create(options.allowedInsert);
10097
this.insertGraphOptions = options.insertGraphOptions;
@@ -162,7 +159,6 @@ class Service extends AdapterService {
162159
if (params.$joinRelation) { delete params.$joinRelation; }
163160
if (params.$modifyEager) { delete params.$modifyEager; }
164161
if (params.$mergeEager) { delete params.$mergeEager; }
165-
if (params.$pick) { delete params.$pick; }
166162
if (params.$noSelect) { delete params.$noSelect; }
167163

168164
Object.keys(params || {}).forEach(key => {
@@ -264,8 +260,9 @@ class Service extends AdapterService {
264260
const { filters, query } = this.filterQuery(params);
265261
const q = this._createQuery(params).skipUndefined();
266262

267-
const allowEager = this.mergeRelations(this.allowedEager, params.mergeAllowEager);
268-
q.allowEager(allowEager || NO_RELATIONS);
263+
if (this.allowedEager) { q.allowGraph(this.allowedEager); }
264+
265+
if (params.mergeAllowEager) { q.allowGraph(params.mergeAllowEager); }
269266

270267
// $select uses a specific find syntax, so it has to come first.
271268
if (filters.$select) {
@@ -274,27 +271,27 @@ class Service extends AdapterService {
274271

275272
// $eager for Objection eager queries
276273
if (query && query.$eager) {
277-
q.eager(query.$eager, this.namedEagerFilters);
274+
q.withGraphFetched(query.$eager);
275+
278276
delete query.$eager;
279277
}
280278

281279
if (query && query.$joinEager) {
282-
q
283-
.eagerAlgorithm(this.Model.JoinEagerAlgorithm)
284-
.eager(query.$joinEager, this.namedEagerFilters);
280+
q.withGraphJoined(query.$joinEager);
281+
285282
delete query.$joinEager;
286283
}
287284

288285
if (query && query.$joinRelation) {
289286
q
290287
.distinct(`${this.Model.tableName}.*`)
291-
.joinRelation(query.$joinRelation);
288+
.joinRelated(query.$joinRelation);
292289

293290
delete query.$joinRelation;
294291
}
295292

296293
if (query && query.$mergeEager) {
297-
q.mergeEager(query.$mergeEager);
294+
q[query.$joinEager ? 'withGraphJoined' : 'withGraphFetched'](query.$mergeEager);
298295

299296
delete query.$mergeEager;
300297
}
@@ -304,27 +301,22 @@ class Service extends AdapterService {
304301
const eagerFilters = Array.isArray(this.eagerFilters) ? this.eagerFilters : [this.eagerFilters];
305302

306303
for (const eagerFilter of eagerFilters) {
307-
q.modifyEager(eagerFilter.expression, eagerFilter.filter);
304+
q.modifyGraph(eagerFilter.expression, eagerFilter.filter);
308305
}
309306
}
310307

311308
if (query && query.$modifyEager) {
312309
for (const eagerFilterExpression of Object.keys(query.$modifyEager)) {
313310
const eagerFilterQuery = query.$modifyEager[eagerFilterExpression];
314311

315-
q.modifyEager(eagerFilterExpression, builder => {
312+
q.modifyGraph(eagerFilterExpression, builder => {
316313
this.objectify(builder, eagerFilterQuery);
317314
});
318315
}
319316

320317
delete query.$modifyEager;
321318
}
322319

323-
if (query && query.$pick) {
324-
q.pick(query.$pick);
325-
delete query.$pick;
326-
}
327-
328320
// build up the knex query out of the query params
329321
this.objectify(q, query);
330322

@@ -384,7 +376,7 @@ class Service extends AdapterService {
384376

385377
if (query.$joinRelation) {
386378
countQuery
387-
.joinRelation(query.$joinRelation)
379+
.joinRelated(query.$joinRelation)
388380
.countDistinct({ total: idColumns });
389381
} else if (idColumns.length > 1) {
390382
countQuery.countDistinct({ total: idColumns });
@@ -441,11 +433,11 @@ class Service extends AdapterService {
441433

442434
if (this.createUseUpsertGraph) {
443435
if (allowedUpsert) {
444-
q.allowUpsert(allowedUpsert);
436+
q.allowGraph(allowedUpsert);
445437
}
446438
q.upsertGraphAndFetch(data, this.upsertGraphOptions);
447439
} else if (allowedInsert) {
448-
q.allowInsert(allowedInsert);
440+
q.allowGraph(allowedInsert);
449441
q.insertGraph(data, this.insertGraphOptions);
450442
} else {
451443
q.insert(data, this.id);
@@ -503,7 +495,7 @@ class Service extends AdapterService {
503495
const allowedUpsert = this.mergeRelations(this.allowedUpsert, params.mergeAllowUpsert);
504496
if (allowedUpsert) {
505497
return this._createQuery(params)
506-
.allowUpsert(allowedUpsert)
498+
.allowGraph(allowedUpsert)
507499
.upsertGraphAndFetch(newObject, this.upsertGraphOptions);
508500
}
509501

@@ -546,7 +538,7 @@ class Service extends AdapterService {
546538
const dataCopy = Object.assign({}, data, this.getIdsQuery(id, null, false));
547539

548540
return this._createQuery(params)
549-
.allowUpsert(allowedUpsert)
541+
.allowGraph(allowedUpsert)
550542
.upsertGraphAndFetch(dataCopy, this.upsertGraphOptions);
551543
}
552544

test/index.test.js

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -134,13 +134,8 @@ const app = feathers()
134134
model: Company,
135135
id: 'id',
136136
multi: ['create', 'remove', 'patch'],
137-
whitelist: ['$eager', '$modifyEager', '$mergeEager', '$pick', '$between', '$notBetween', '$containsKey', '$contains', '$contained', '$any', '$all', '$noSelect', '$like'],
137+
whitelist: ['$eager', '$modifyEager', '$mergeEager', '$between', '$notBetween', '$containsKey', '$contains', '$contained', '$any', '$all', '$noSelect', '$like'],
138138
allowedEager: '[ceos, clients]',
139-
namedEagerFilters: {
140-
notSnoop (builder) {
141-
return builder.whereNot('name', 'Snoop');
142-
}
143-
},
144139
eagerFilters: [
145140
{
146141
expression: 'ceos',
@@ -299,12 +294,6 @@ describe('Feathers Objection Service', () => {
299294
});
300295
});
301296

302-
describe('when missing namedEagerFilters', () => {
303-
it('sets the default to be undefined', () => {
304-
expect(people.namedEagerFilters).to.equal(undefined);
305-
});
306-
});
307-
308297
describe('when missing eagerFilters', () => {
309298
it('sets the default to be undefined', () => {
310299
expect(people.eagerFilters).to.equal(undefined);
@@ -805,13 +794,6 @@ describe('Feathers Objection Service', () => {
805794
});
806795
});
807796

808-
it('allows eager queries with pick', () => {
809-
return companies.find({ query: { $eager: 'ceos', $pick: ['ceos'] } }).then(data => {
810-
expect(data[0].ceos).to.be.ok;
811-
expect(data[0].ceo).to.be.undefined;
812-
});
813-
});
814-
815797
it('allows eager queries with named filters', () => {
816798
return companies
817799
.find({ query: { $eager: 'ceos(notSnoop)' } })
@@ -881,7 +863,7 @@ describe('Feathers Objection Service', () => {
881863
});
882864
});
883865

884-
it('allows joinRelation queries', () => {
866+
it('allows joinRelation queries and eager', () => {
885867
return employees
886868
.find({
887869
query: {
@@ -896,6 +878,22 @@ describe('Feathers Objection Service', () => {
896878
});
897879

898880
it('allows filtering by relation field with joinRelation queries', () => {
881+
return employees
882+
.find({
883+
query: {
884+
$joinRelation: 'company',
885+
'company.name': {
886+
$like: 'google'
887+
}
888+
}
889+
})
890+
.then(data => {
891+
expect(data.length).to.equal(1);
892+
expect(data[0].name).to.equal('Luke');
893+
});
894+
});
895+
896+
it('allows filtering by relation field with joinRelation queries and eager', () => {
899897
return employees
900898
.find({
901899
query: {

test/people.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,10 @@ export default class People extends Model {
1515
created: { type: ['boolean', 'null'] }
1616
}
1717
}
18+
19+
static modifiers = {
20+
notSnoop: builder => {
21+
builder.whereNot('name', 'Snoop');
22+
}
23+
}
1824
}

types/index.d.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ export interface ObjectionServiceOptions extends ServiceOptions {
88
idSeparator: string;
99
jsonSchema: any;
1010
allowedEager: string | object;
11-
namedEagerFilters: any;
1211
eagerFilters: any;
1312
allowedInsert: string | object;
1413
insertGraphOptions: any;

0 commit comments

Comments
 (0)