-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #79 from christophehenry/WIP-InboxFilter
Add setFilter and FilterRule
- Loading branch information
Showing
11 changed files
with
499 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
'use strict'; | ||
|
||
import Model from './Model.js'; | ||
import uuid from 'uuid/v4'; | ||
import filterRuleConditions from './filterRules/FilterRuleConditions'; | ||
import filterRuleActions from './filterRules/FilterRuleActions'; | ||
import Utils from '../utils/Utils'; | ||
|
||
class FilterRule extends Model { | ||
/** | ||
* This class represents a JMAP [FilterRule]{@link http://jmap.io/spec.html}.<br /> | ||
* The _FilterRule_ object represents the state of incoming message filtering for an account. | ||
* | ||
* @constructor | ||
* @extends Model | ||
* | ||
* @param jmap {Client} The {@link Client} instance that created this _FilterRule_. | ||
* @param name {String} The name of the rule | ||
* | ||
* NOTE: How to use and extend this model ? | ||
* FilterRule is conceived so that a rule can be specified in a highly didactic way. For instance: | ||
* | ||
* new jmap.FilterRule(client, 'My filter') | ||
* .when.from | ||
* .value('admin@open-paas.org') | ||
* .comparator(jmap.FilterRule.Comparator.EXACTLY_EQUALS) | ||
* .then.moveTo | ||
* .mailboxId('36e4d1c0-a473-11e8-aa26-bfb5d32a28f6'); | ||
* | ||
* To achive this, it uses the builder design pattern. To extend this model with new actions and conditions, | ||
* you just need to create a new class that extends AbstractConditionAction and implements | ||
* AbstractConditionAction#_init and AbstractConditionAction#_toJSONObject. | ||
* | ||
* AbstractConditionAction#_init is called by AbstractConditionAction' constructor and | ||
* AbstractConditionAction#_toJSONObject is used to generate a JSON representation of the object. | ||
* Then, just provide any useful property. | ||
* | ||
* To make the new condition or action available to the builder, you need to extend FilterRuleCondition | ||
* (if defining a new condition) or FilterRuleAction (if defining a new action) | ||
* | ||
* @see Model | ||
*/ | ||
constructor(jmap, name) { | ||
super(jmap); | ||
|
||
this.id = uuid(); | ||
this.name = name; | ||
this.filterCondition = null; | ||
this.filterAction = null; | ||
} | ||
|
||
get then() { | ||
return filterRuleActions(this); | ||
} | ||
|
||
get when() { | ||
return filterRuleConditions(this); | ||
} | ||
|
||
toJSONObject() { | ||
Utils.assertRequiredParameterIsPresent(this.filterCondition, '', `Filter must have a condition. Use 'when'.`); | ||
Utils.assertRequiredParameterIsPresent(this.filterAction, '', `Filter must have an action. Use 'then'.`); | ||
this.filterCondition._validate(); | ||
this.filterAction._validate(); | ||
|
||
return { | ||
id: this.id, | ||
name: this.name, | ||
condition: this.filterCondition._toJSONObject(), | ||
action: this.filterAction._toJSONObject() | ||
}; | ||
} | ||
|
||
static fromJSONObject(jmap, object) { | ||
throw new Error('Not implemented'); | ||
} | ||
} | ||
|
||
FilterRule.ID = 'singleton'; | ||
FilterRule.Comparator = Object.freeze({ | ||
CONTAINS: 'contains', | ||
NOT_CONTAINS: 'not-contains', | ||
EXACTLY_EQUALS: 'exactly-equals', | ||
NOT_EXACTLY_EQUALS: 'not-exactly-equals' | ||
}); | ||
|
||
export default FilterRule; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
export default class AbstractConditionAction { | ||
constructor(filterRule) { | ||
this.filterRule = filterRule; | ||
this._init(); | ||
} | ||
|
||
/** | ||
* Do not override | ||
* @returns {*} | ||
*/ | ||
get when() { | ||
return this.filterRule.when; | ||
} | ||
|
||
/** | ||
* Do not override | ||
* @returns {*} | ||
*/ | ||
get then() { | ||
return this.filterRule.then; | ||
} | ||
|
||
/** | ||
* Do not override | ||
* @returns {*|JSON|{id, name, condition, action}} | ||
*/ | ||
toJSONObject() { | ||
return this.filterRule.toJSONObject(); | ||
} | ||
|
||
/** | ||
* Initialises the object. Called by the constructor | ||
* @private | ||
*/ | ||
_init() { | ||
throw new Error('_init not implemented in child class'); | ||
} | ||
|
||
/** | ||
* Creates a JSON representation of the model | ||
* @private | ||
*/ | ||
_toJSONObject() { | ||
throw new Error('_toJSONObject not implemented in child class'); | ||
} | ||
|
||
/** | ||
* Validates the object is correct with respect to JMap specification | ||
* Will be called by FilterRule#toJSONObject | ||
* @private | ||
*/ | ||
_validate() { | ||
throw new Error('_validate not implemented in child class'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
'use strict'; | ||
|
||
import AbstractConditionAction from './AbstractConditionAction'; | ||
import Utils from '../../utils/Utils'; | ||
|
||
class MoveTo extends AbstractConditionAction { | ||
_init() { | ||
this._mailboxId = null; | ||
} | ||
|
||
mailboxId(val) { | ||
this._mailboxId = val; | ||
|
||
return this; | ||
} | ||
|
||
_toJSONObject() { | ||
return { | ||
appendIn: { | ||
mailboxIds: [this._mailboxId] | ||
} | ||
}; | ||
} | ||
|
||
_validate() { | ||
Utils.assertRequiredParameterIsPresent(this._mailboxId, '', `Mailbox id is not set. Use mailboxId()`); | ||
} | ||
} | ||
|
||
export default function filterRuleActions(filterRule) { | ||
/** | ||
* Intermediate object to inject a action the to filter | ||
* | ||
* How to extend: | ||
* Create a new condition class extending {AbstractConditionAction} and make it available | ||
* by defining a new getter in the returned object. For instance: | ||
* | ||
* get moveTo() { | ||
* filterRule.filterAction = new MoveTo(filterRule); | ||
* return filterRule.filterAction; | ||
* } | ||
* | ||
* get delete() { | ||
* filterRule.filterCondition = new Delete(filterRule); | ||
* return filterRule.filterCondition | ||
* } | ||
* | ||
* @param filterRule {FilterRule} The filter that is being constructed | ||
* @returns {AbstractConditionAction} The new condition | ||
*/ | ||
return { | ||
get moveTo() { | ||
filterRule.filterAction = new MoveTo(filterRule); | ||
|
||
return filterRule.filterAction; | ||
} | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
'use strict'; | ||
|
||
import AbstractConditionAction from './AbstractConditionAction'; | ||
import FilterRule from '../FilterRule'; | ||
import Utils from '../../utils/Utils'; | ||
|
||
class From extends AbstractConditionAction { | ||
_init() { | ||
this._comparator = null; | ||
this._value = null; | ||
} | ||
|
||
value(val) { | ||
this._value = val; | ||
|
||
return this; | ||
} | ||
|
||
comparator(val) { | ||
if (!Utils.objectValuesIncludes(FilterRule.Comparator, val)) { | ||
throw new Error(`From#comparator(): ${val} must be one of ${Utils.objectValues(FilterRule.Comparator)}`); | ||
} | ||
this._comparator = val; | ||
|
||
return this; | ||
} | ||
|
||
_toJSONObject() { | ||
return { | ||
field: 'from', | ||
comparator: this._comparator, | ||
value: this._value, | ||
}; | ||
} | ||
|
||
_validate() { | ||
Utils.assertRequiredParameterIsPresent(this._comparator, '', 'Comprator is not set. Use comparator()'); | ||
Utils.assertRequiredParameterIsPresent(this._value, '', 'Value is not set. Use value()'); | ||
} | ||
} | ||
|
||
export default function filterRuleConditions(filterRule) { | ||
/** | ||
* Intermediate object to inject a condition the to filter | ||
* | ||
* How to extend: | ||
* Create a new condition class extending {AbstractConditionAction} and make it available | ||
* by defining a new getter in the returned obect. For instance: | ||
* | ||
* get from() { | ||
* filterRule.filterCondition = new From(filterRule); | ||
* return filterRule.filterCondition; | ||
* } | ||
* | ||
* get subject() { | ||
* filterRule.filterCondition = new Subject(filterRule); | ||
* return filterRule.filterCondition | ||
* } | ||
* | ||
* @param filterRule {FilterRule} The filter that is being constructed | ||
* @returns {AbstractConditionAction} The new condition | ||
*/ | ||
return { | ||
get from() { | ||
filterRule.filterCondition = new From(filterRule); | ||
|
||
return filterRule.filterCondition; | ||
} | ||
}; | ||
} |
Oops, something went wrong.