From 00956eaae5b9be693afa9d7b761ec1a07778f01d Mon Sep 17 00:00:00 2001 From: Patrick Mooney Date: Mon, 23 Jun 2014 18:09:56 -0500 Subject: [PATCH] Add ducktyping Filter.isFilter method This should make some headway in avoiding instanceof pitfalls when dealing with Filter objects. Fix mcavage/node-ldapjs#123 --- lib/client/client.js | 3 +-- lib/filters/filter.js | 15 +++++++++++++++ lib/filters/index.js | 2 ++ lib/filters/not_filter.js | 4 ++-- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/lib/client/client.js b/lib/client/client.js index 7b7c3f9..37ed83c 100644 --- a/lib/client/client.js +++ b/lib/client/client.js @@ -40,7 +40,6 @@ var SearchReference = messages.SearchReference; var SearchResponse = messages.SearchResponse; var Parser = messages.Parser; -var Filter = filters.Filter; var PresenceFilter = filters.PresenceFilter; var ConnectionError = errors.ConnectionError; @@ -640,7 +639,7 @@ Client.prototype.search = function search(base, options, controls, callback) { options.filter = filters.parseString(options.filter); } else if (!options.filter) { options.filter = new PresenceFilter({attribute: 'objectclass'}); - } else if (!(options.filter instanceof Filter)) { + } else if (!filters.isFilter(options.filter)) { throw new TypeError('options.filter (Filter) required'); } diff --git a/lib/filters/filter.js b/lib/filters/filter.js index c27a4ac..fbbdcea 100644 --- a/lib/filters/filter.js +++ b/lib/filters/filter.js @@ -44,6 +44,21 @@ function Filter(options) { } }); } + +Filter.isFilter = function isFilter(filter) { + if (!filter || typeof (filter) !== 'object') { + return false; + } + // Do our best to duck-type it + if ((filter instanceof Filter) || ( + typeof (filter.toBer) === 'functin' && + typeof (filter.matches) === 'function' && + typeof (filter._type) === 'number')) { + return true; + } + return false; +}; + module.exports = Filter; diff --git a/lib/filters/index.js b/lib/filters/index.js index 336ae38..d4bf21b 100644 --- a/lib/filters/index.js +++ b/lib/filters/index.js @@ -547,6 +547,8 @@ module.exports = { return _parseString(filter); }, + isFilter: Filter.isFilter, + AndFilter: AndFilter, ApproximateFilter: ApproximateFilter, EqualityFilter: EqualityFilter, diff --git a/lib/filters/not_filter.js b/lib/filters/not_filter.js index f4b9038..097bc41 100644 --- a/lib/filters/not_filter.js +++ b/lib/filters/not_filter.js @@ -13,7 +13,7 @@ var Protocol = require('../protocol'); function NotFilter(options) { if (typeof (options) === 'object') { - if (!options.filter || !(options.filter instanceof Filter)) + if (!options.filter || !Filter.isFilter(options.filter)) throw new TypeError('options.filter (Filter) required'); } else { @@ -37,7 +37,7 @@ module.exports = NotFilter; NotFilter.prototype.addFilter = function (f) { - if (!(f instanceof Filter)) + if (!Filter.isFilter(f)) throw new TypeError('filter (Filter) required'); this.filter = f; };