mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-20 22:42:53 -05:00
Dynamic Routing Beta: Filter collections with NQL (#9704)
refs #9601 - replace jsonpath with [NQL](https://github.com/NexesJS/NQL) - jsonpath was just a temporary solution (a short-term fix) - with NQL we are able to filter collections more powerful in the near future - NQL is not feature complete - we still support `featured:true` for collections
This commit is contained in:
parent
fc9da07025
commit
7027980ad2
4 changed files with 43 additions and 30 deletions
|
@ -1,21 +1,7 @@
|
|||
const _ = require('lodash'),
|
||||
jsonpath = require('jsonpath'),
|
||||
nql = require('@nexes/nql'),
|
||||
debug = require('ghost-ignition').debug('services:url:generator'),
|
||||
localUtils = require('./utils'),
|
||||
/**
|
||||
* @TODO: This is a fake version of the upcoming GQL tool.
|
||||
* GQL will offer a tool to match a JSON against a filter.
|
||||
*/
|
||||
transformFilter = (filter) => {
|
||||
filter = '$[?(' + filter + ')]';
|
||||
filter = filter.replace(/(\w+):(\w+)/g, '@.$1 == "$2"');
|
||||
filter = filter.replace(/"true"/g, 'true');
|
||||
filter = filter.replace(/"false"/g, 'false');
|
||||
filter = filter.replace(/"0"/g, '0');
|
||||
filter = filter.replace(/"1"/g, '1');
|
||||
filter = filter.replace(/\+/g, ' && ');
|
||||
return filter;
|
||||
};
|
||||
localUtils = require('./utils');
|
||||
|
||||
class UrlGenerator {
|
||||
constructor(router, queue, resources, urls, position) {
|
||||
|
@ -29,7 +15,8 @@ class UrlGenerator {
|
|||
|
||||
// CASE: routers can define custom filters, but not required.
|
||||
if (this.router.getFilter()) {
|
||||
this.filter = transformFilter(this.router.getFilter());
|
||||
this.filter = this.router.getFilter();
|
||||
this.nql = nql(this.filter);
|
||||
debug('filter', this.filter);
|
||||
}
|
||||
|
||||
|
@ -117,7 +104,7 @@ class UrlGenerator {
|
|||
resource.reserve();
|
||||
this._resourceListeners(resource);
|
||||
return true;
|
||||
} else if (jsonpath.query(resource, this.filter).length) {
|
||||
} else if (this.nql.queryJSON(resource.data)) {
|
||||
this.urls.add({
|
||||
url: url,
|
||||
generatorId: this.uid,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const _ = require('lodash');
|
||||
const Promise = require('bluebird');
|
||||
const should = require('should');
|
||||
const jsonpath = require('jsonpath');
|
||||
const nql = require('@nexes/nql');
|
||||
const sinon = require('sinon');
|
||||
const urlUtils = require('../../../../server/services/url/utils');
|
||||
const UrlGenerator = require('../../../../server/services/url/UrlGenerator');
|
||||
|
@ -67,7 +67,7 @@ describe('Unit: services/url/UrlGenerator', function () {
|
|||
it('routing type has filter', function () {
|
||||
router.getFilter.returns('featured:true');
|
||||
const urlGenerator = new UrlGenerator(router, queue);
|
||||
urlGenerator.filter.should.eql('$[?(@.featured == true)]');
|
||||
urlGenerator.filter.should.eql('featured:true');
|
||||
});
|
||||
|
||||
it('routing type has changed', function () {
|
||||
|
@ -153,9 +153,10 @@ describe('Unit: services/url/UrlGenerator', function () {
|
|||
router.getFilter.returns(false);
|
||||
router.getResourceType.returns('posts');
|
||||
resource.isReserved.returns(false);
|
||||
sandbox.stub(jsonpath, 'query');
|
||||
|
||||
const urlGenerator = new UrlGenerator(router, queue, resources, urls);
|
||||
should.not.exist(urlGenerator.nql);
|
||||
|
||||
sandbox.stub(urlGenerator, '_generateUrl').returns('something');
|
||||
sandbox.stub(urlGenerator, '_resourceListeners');
|
||||
|
||||
|
@ -165,16 +166,16 @@ describe('Unit: services/url/UrlGenerator', function () {
|
|||
urlGenerator._resourceListeners.calledOnce.should.be.true();
|
||||
urls.add.calledOnce.should.be.true();
|
||||
resource.reserve.calledOnce.should.be.true();
|
||||
jsonpath.query.called.should.be.false();
|
||||
});
|
||||
|
||||
it('resource is taken', function () {
|
||||
router.getFilter.returns(false);
|
||||
router.getResourceType.returns('posts');
|
||||
resource.isReserved.returns(true);
|
||||
sandbox.stub(jsonpath, 'query');
|
||||
|
||||
const urlGenerator = new UrlGenerator(router, queue, resources, urls);
|
||||
should.not.exist(urlGenerator.nql);
|
||||
|
||||
sandbox.stub(urlGenerator, '_generateUrl').returns('something');
|
||||
sandbox.stub(urlGenerator, '_resourceListeners');
|
||||
|
||||
|
@ -184,7 +185,6 @@ describe('Unit: services/url/UrlGenerator', function () {
|
|||
urlGenerator._resourceListeners.called.should.be.false();
|
||||
urls.add.called.should.be.false();
|
||||
resource.reserve.called.should.be.false();
|
||||
jsonpath.query.called.should.be.false();
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -193,9 +193,10 @@ describe('Unit: services/url/UrlGenerator', function () {
|
|||
router.getFilter.returns('featured:true');
|
||||
router.getResourceType.returns('posts');
|
||||
resource.isReserved.returns(false);
|
||||
sandbox.stub(jsonpath, 'query').returns([true]);
|
||||
|
||||
const urlGenerator = new UrlGenerator(router, queue, resources, urls);
|
||||
sandbox.stub(urlGenerator.nql, 'queryJSON').returns(true);
|
||||
|
||||
sandbox.stub(urlGenerator, '_generateUrl').returns('something');
|
||||
sandbox.stub(urlGenerator, '_resourceListeners');
|
||||
|
||||
|
@ -205,16 +206,17 @@ describe('Unit: services/url/UrlGenerator', function () {
|
|||
urlGenerator._resourceListeners.calledOnce.should.be.true();
|
||||
urls.add.calledOnce.should.be.true();
|
||||
resource.reserve.calledOnce.should.be.true();
|
||||
jsonpath.query.calledOnce.should.be.true();
|
||||
urlGenerator.nql.queryJSON.called.should.be.true();
|
||||
});
|
||||
|
||||
it('no match', function () {
|
||||
router.getFilter.returns('featured:true');
|
||||
router.getResourceType.returns('posts');
|
||||
resource.isReserved.returns(false);
|
||||
sandbox.stub(jsonpath, 'query').returns([]);
|
||||
|
||||
const urlGenerator = new UrlGenerator(router, queue, resources, urls);
|
||||
sandbox.stub(urlGenerator.nql, 'queryJSON').returns(false);
|
||||
|
||||
sandbox.stub(urlGenerator, '_generateUrl').returns('something');
|
||||
sandbox.stub(urlGenerator, '_resourceListeners');
|
||||
|
||||
|
@ -224,16 +226,17 @@ describe('Unit: services/url/UrlGenerator', function () {
|
|||
urlGenerator._resourceListeners.called.should.be.false();
|
||||
urls.add.called.should.be.false();
|
||||
resource.reserve.called.should.be.false();
|
||||
jsonpath.query.calledOnce.should.be.true();
|
||||
urlGenerator.nql.queryJSON.called.should.be.true();
|
||||
});
|
||||
|
||||
it('resource is taken', function () {
|
||||
router.getFilter.returns('featured:true');
|
||||
router.getResourceType.returns('posts');
|
||||
resource.isReserved.returns(true);
|
||||
sandbox.stub(jsonpath, 'query').returns([]);
|
||||
|
||||
const urlGenerator = new UrlGenerator(router, queue, resources, urls);
|
||||
sandbox.stub(urlGenerator.nql, 'queryJSON').returns(true);
|
||||
|
||||
sandbox.stub(urlGenerator, '_generateUrl').returns('something');
|
||||
sandbox.stub(urlGenerator, '_resourceListeners');
|
||||
|
||||
|
@ -243,7 +246,7 @@ describe('Unit: services/url/UrlGenerator', function () {
|
|||
urlGenerator._resourceListeners.called.should.be.false();
|
||||
urls.add.called.should.be.false();
|
||||
resource.reserve.called.should.be.false();
|
||||
jsonpath.query.called.should.be.false();
|
||||
urlGenerator.nql.queryJSON.called.should.be.false();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
"cli": "^1.7.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nexes/nql": "0.0.1",
|
||||
"amperize": "0.3.7",
|
||||
"analytics-node": "2.4.1",
|
||||
"archiver": "1.3.0",
|
||||
|
|
22
yarn.lock
22
yarn.lock
|
@ -2,6 +2,24 @@
|
|||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@nexes/mongo-knex@0.0.0":
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@nexes/mongo-knex/-/mongo-knex-0.0.0.tgz#7a44a7263d8830c8416b90ba3c963c2c722e7b72"
|
||||
dependencies:
|
||||
lodash "^4.17.10"
|
||||
|
||||
"@nexes/nql-lang@0.0.0":
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@nexes/nql-lang/-/nql-lang-0.0.0.tgz#eb0fb807aea8aa64d3d0b454f3d1167af394f39a"
|
||||
|
||||
"@nexes/nql@0.0.1":
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@nexes/nql/-/nql-0.0.1.tgz#e8f5e5352badeffd67e371f22bccd41fa0c20c24"
|
||||
dependencies:
|
||||
"@nexes/mongo-knex" "0.0.0"
|
||||
"@nexes/nql-lang" "0.0.0"
|
||||
mingo "2.2.2"
|
||||
|
||||
"@segment/loosely-validate-event@^1.1.2":
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@segment/loosely-validate-event/-/loosely-validate-event-1.1.2.tgz#d77840999e3f7e43e74b3b0d43391c1526f793b8"
|
||||
|
@ -3762,6 +3780,10 @@ mimic-response@^1.0.0:
|
|||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.0.tgz#df3d3652a73fded6b9b0b24146e6fd052353458e"
|
||||
|
||||
mingo@2.2.2:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/mingo/-/mingo-2.2.2.tgz#be69d486ae6e0ac54b979dc5f4412db21851f693"
|
||||
|
||||
minimatch@0.3:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.3.0.tgz#275d8edaac4f1bb3326472089e7949c8394699dd"
|
||||
|
|
Loading…
Add table
Reference in a new issue