Supporting optional jsonValueValidator in Operator class?
Dieses Issue hat noch niemand übernommen.
Bewertung
- Schwierigkeit
- 3/5
- Geschätzter Aufwand
- 1-2 Tage
- Anfängerfreundlichkeit
- 42/100
- Issue-Typ
- Feature
- Klarheit
- Größtenteils klar
- Aktivitätsstatus
- Veraltet
- Tech-Stack
- javascript
- Bereich
- backend
Rechercherichtung
Beginne mit src/operator.js und dem Standard-Operator-Setup in src/engine-default-operators.js und reproduziere dann die Beispiele für in/notIn und contains/notContains aus dem Issue. Prüfe, wie sich der vorgeschlagene optionale jsonValueValidator auf die Operatorauswertung auswirken würde; als erledigt gilt die Aufgabe, wenn Nicht-Array-Werte für in/notIn ordnungsgemäß und konsistent mit dem dokumentierten Verhalten behandelt werden.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
In the documentation on JSON rules engine operators it states that the fact passed to the contains/notContains operators must be arrays. And I see in the Operator class that a factValueValidator function can be supplied to the constructor to ensure that the fact supplied to this operator meets that expectation.
Similarly, the documentation states that for in/notIn operators, the value side of the comparison must be an array. But unlike contains/notContains, there's no validation in place to check that this is the case. And that means you don't have the same graceful handling when a non-array value is passed where an array is expected. A minimal-ish example to illustrate how in/notIn are not symmetrical to contains/notContains:
const { Engine } = require('json-rules-engine');
const facts = {
people: {
someguy: 'dave',
otherguys: ['hal', 'stanley', 'alex']
},
};
// This rule will throw an error because the path $.nonexistentPath evaluates to undefined and b.indexOf(a) throws an error
const operatorInWithNonexistentValuePathRule = {
conditions: {
all: [
{
fact: 'people',
path: '$.someguy',
operator: 'in', // notIn produces the same error
value: {
fact: 'people',
path: '$.nonexistentpath'
}
}
]
},
event: {
type: 'in-with-nonexistent-value-path-rule',
}
};
// This rule will NOT throw an error because contains operator is defined with a factValueValidator that will return false if the factValue is not an array
const operatorContainsWithNonexistentFactPathRule = {
conditions: {
all: [
{
fact: 'people',
path: '$.nonexistentpath',
operator: 'contains',
value: {
fact: 'people',
path: '$.someguy'
}
}
]
},
event: {
type: 'contains-with-nonexistent-fact-path-rule',
}
};
function runEngine(
rule,
facts
){
const engine = new Engine();
engine.addRule(rule);
engine
.run(facts)
.then(({ failureEvents }) => {
failureEvents.map(event => console.log(event));
})
.catch(console.error);
}
runEngine(operatorInWithNonexistentValuePathRule, facts);
runEngine(operatorContainsWithNonexistentFactPathRule, facts);
I'm curious if this is the intentional/desired behavior here? Naively I would've expected that in/notIn operators can (and would) validate values similarly to how contains/notContains validate facts. I think this could be accomplished with a minor rewrite to the Operator class, something like:
'use strict'
export default class Operator {
/**
* Constructor
* @param {string} name - operator identifier
* @param {function(factValue, jsonValue)} callback - operator evaluation method
* @param {function} [factValueValidator] - optional validator for asserting the data type of the fact
* @param {function} [jsonValueValidator] - optional validator for asserting the data type of the "value" property of the condition
* @returns {Operator} - instance
*/
constructor (name, cb, factValueValidator) {
this.name = String(name)
if (!name) throw new Error('Missing operator name')
if (typeof cb !== 'function') throw new Error('Missing operator callback')
this.cb = cb
this.factValueValidator = factValueValidator
if (!this.factValueValidator) this.factValueValidator = () => true
this.jsonValueValidator = jsonValueValidator
if (!this.jsonValueValidator) this.jsonValueValidator = () => true
}
/**
* Takes the fact result and compares it to the condition 'value', using the callback
* @param {mixed} factValue - fact result
* @param {mixed} jsonValue - "value" property of the condition
* @returns {Boolean} - whether the values pass the operator test
*/
evaluate (factValue, jsonValue) {
return this.factValueValidator(factValue) && this.jsonValueValidator(jsonValue) && this.cb(factValue, jsonValue)
}
}
And tweaking the initialization of the default engine operators. If there's interest in doing something along these lines I'd be glad to try and throw together a small PR.
- Vorherrschende Sprache
- JavaScript
- Sterne
- 3.1k
- Forks
- 507
- PR-Merge-Kennzahlen
- Keine gemergten PRs in 30 T.
Entwicklungsumgebung
Dieses Projekt bietet weder Dev-Container noch Dockerfile noch Beitragsleitfaden – die Einrichtung liegt bei Ihnen. Beginnen Sie mit der README; die allgemeinen Schritte stehen in unserem Leitfaden für den ersten Beitrag.
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus CacheControl/json-rules-engine
-
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 35/100
CacheControl/json-rules-engine#427 · 1 Reaktion ·
-
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 35/100
-
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 48/100
CacheControl/json-rules-engine#424 · 1 Kommentar ·
-
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 25/100
CacheControl/json-rules-engine#421 · 1 Kommentar ·
-
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 38/100
CacheControl/json-rules-engine#417 · 1 Reaktion ·
Alle Issues in CacheControl/json-rules-engine
Ähnliche Issues
-
[Feature]:Offenenhancement
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 65/100
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 73/100
Uuriko/project-room#1554 ·
Maintainer antworten meist innerhalb von 1 Tag
-
automated issue report
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 62/100
lirantal/discoprint#36 ·
Maintainer antworten meist innerhalb von 1 Tag
-
accepting PR Content:HTML
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 88/100
mdn/content#45988 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 72/100
pnpm/pnpm#16635 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag