feat(filter): Implement named filter criteria (author, item) infrastructure

Refactor internal code to handle anonymous or named criteria for filters
This commit is contained in:
FoxxMD
2022-04-13 11:28:32 -04:00
parent 69cb823203
commit 95eaa66080
17 changed files with 1165 additions and 392 deletions

View File

@@ -9,18 +9,10 @@ import objectHash from "object-hash";
export class ActivityStateFilterCriteria extends FilterCriteria<TypedActivityState> {
type: string = filterCriteriaTypeIdentifiers.activityState;
static async getOrInsertCriteria(database: DataSource, config: TypedActivityState) {
const repo = database.getRepository(this);
const existing = await repo.findOneBy({hash: objectHash.sha1(config), type: filterCriteriaTypeIdentifiers.activityState});
if(existing === null) {
return await repo.save(new this({criteria: config}));
}
}
constructor(data?: FilterCriteriaOptions<TypedActivityState>) {
super(data);
if(data !== undefined) {
this.id = `${this.type}-${this.hash}`;
this.generateId();
}
}
}

View File

@@ -14,7 +14,7 @@ export class ActivityStateFilterCriteriaResult extends FilterCriteriaResult<Type
constructor(data?: IFilterCriteriaResult<TypedActivityState>) {
super(data);
if(data !== undefined) {
this.criteria = new ActivityStateFilterCriteria({criteria: data.criteria});
this.criteria = new ActivityStateFilterCriteria(data.criteria);
}
}
}

View File

@@ -9,18 +9,10 @@ import {AuthorCriteria} from "../../interfaces";
export class AuthorFilterCriteria extends FilterCriteria<AuthorCriteria> {
type: string = filterCriteriaTypeIdentifiers.author;
static async getOrInsertCriteria(database: DataSource, config: AuthorCriteria) {
const repo = database.getRepository(this);
const existing = await repo.findOneBy({hash: objectHash.sha1(config), type: filterCriteriaTypeIdentifiers.author});
if(existing === null) {
return await repo.save(new this({criteria: config}));
}
}
constructor(data?: FilterCriteriaOptions<AuthorCriteria>) {
super(data);
if(data !== undefined) {
this.id = `${this.type}-${this.hash}`;
this.generateId();
}
}
}

View File

@@ -4,6 +4,7 @@ import {removeUndefinedKeys} from "../../../util";
export interface FilterCriteriaOptions<T> {
criteria: T
name?: string
}
export const filterCriteriaTypeIdentifiers = {
@@ -18,6 +19,9 @@ export abstract class FilterCriteria<T> {
@PrimaryColumn()
id!: string
@Column()
name?: string
@Column("simple-json")
criteria!: T;
@@ -39,8 +43,14 @@ export abstract class FilterCriteria<T> {
if(data !== undefined) {
this.criteria = removeUndefinedKeys(data.criteria);
this.hash = objectHash.sha1(this.criteria);
this.name = data.name;
this.generateId();
}
}
generateId() {
this.id = `${this.type}-${this.name !== undefined ? `-${this.name}-` : ''}${this.hash}`;
}
}

View File

@@ -54,7 +54,7 @@ export class AuthorFilterCriteriaResult extends FilterCriteriaResult<AuthorCrite
constructor(data?: IFilterCriteriaResult<AuthorCriteria>) {
super(data);
if (data !== undefined) {
this.criteria = new AuthorFilterCriteria({criteria: data.criteria});
this.criteria = new AuthorFilterCriteria(data.criteria);
}
}
}

View File

@@ -695,6 +695,12 @@ export class initApi1642180264563 implements MigrationInterface {
length: '300',
isPrimary: true,
},
{
name: 'name',
type: 'varchar',
length: '300',
isNullable: true
},
{
name: 'criteria',
type: 'text',

View File

@@ -1537,12 +1537,14 @@ export interface SnoowrapOptions {
export type FilterCriteriaDefaultBehavior = 'replace' | 'merge';
export interface FilterOptions<T> {
export type MaybeAnonymousCriteria<T> = T | NamedCriteria<T>;
export interface FilterOptionsJson<T> {
/**
* Will "pass" if any set of Criteria passes
* */
include?: T[]
include?: MaybeAnonymousCriteria<T>[]
/**
* * OR => if ANY exclude condition "does not" pass then the exclude test passes
@@ -1558,10 +1560,17 @@ export interface FilterOptions<T> {
*
* EX: `isMod: true, name: Automoderator` => Will pass if the Author IS NOT a mod and IS NOT named Automoderator
* */
exclude?: T[];
exclude?: MaybeAnonymousCriteria<T>[];
}
export interface FilterOptions<T> extends Omit<FilterOptionsJson<T>, 'include' | 'exclude'> {
include?: NamedCriteria<T>[]
exclude?: NamedCriteria<T>[];
}
/**
* If present then these Author criteria are checked before running. If criteria fails then this process is skipped.
* @examples [{"include": [{"flairText": ["Contributor","Veteran"]}, {"isMod": true}]}]
@@ -1584,7 +1593,7 @@ export interface ItemOptions extends FilterOptions<TypedActivityState> {
// * */
// export type ItemOptions = FilterOptions<SubmissionState> | FilterOptions<CommentState>
export type MinimalOrFullFilter<T> = T[] | FilterOptions<T>
export type MinimalOrFullFilter<T> = MaybeAnonymousCriteria<T>[] | FilterOptionsJson<T>
export interface FilterCriteriaDefaults {
itemIs?: MinimalOrFullFilter<TypedActivityState>
@@ -2305,6 +2314,11 @@ export interface AuthorCriteria {
isContributor?: boolean
}
export interface NamedCriteria<T extends AuthorCriteria | TypedActivityState> {
name?: string
criteria: T
}
export interface ActionResult extends ActionProcessResult {
premise: ObjectPremise
kind: string,
@@ -2481,7 +2495,7 @@ export interface FilterCriteriaPropertyResult<T> {
export interface FilterCriteriaResult<T> {
behavior: FilterBehavior
criteria: T//AuthorCriteria | TypedActivityStates
criteria: NamedCriteria<T>//AuthorCriteria | TypedActivityStates
propertyResults: FilterCriteriaPropertyResult<T>[]
passed: boolean
}

View File

@@ -229,10 +229,10 @@ export class AttributionRule extends Rule {
activities = await as.filter(activities, async (activity) => {
if (asSubmission(activity) && submissionState !== undefined) {
const {passed} = await this.resources.testItemCriteria(activity, submissionState, this.logger);
const {passed} = await this.resources.testItemCriteria(activity, {criteria: submissionState}, this.logger);
return passed;
} else if (commentState !== undefined) {
const {passed} = await this.resources.testItemCriteria(activity, commentState, this.logger);
const {passed} = await this.resources.testItemCriteria(activity, {criteria: commentState}, this.logger);
return passed;
}
return true;

View File

@@ -2,8 +2,8 @@ import {Rule, RuleJSONConfig, RuleOptions} from "./index";
import {Comment} from "snoowrap";
import Submission from "snoowrap/dist/objects/Submission";
import {checkAuthorFilter} from "../Subreddit/SubredditResources";
import {AuthorCriteria, RuleResult} from "../Common/interfaces";
import {normalizeCriteria} from "../util";
import {AuthorCriteria, AuthorOptions, RuleResult} from "../Common/interfaces";
import {buildFilter, normalizeCriteria} from "../util";
/**
* Checks the author of the Activity against AuthorCriteria. This differs from a Rule's AuthorOptions as this is a full Rule and will only pass/fail, not skip.
@@ -30,21 +30,15 @@ export interface AuthorRuleJSONConfig extends AuthorRuleConfig, RuleJSONConfig {
}
export class AuthorRule extends Rule {
include: AuthorCriteria[] = [];
exclude: AuthorCriteria[] = [];
authorOptions: AuthorOptions;
constructor(options: AuthorRuleOptions) {
super(options);
const {
include,
exclude,
} = options;
this.authorOptions = buildFilter(options ?? {});
this.include = include !== undefined ? include.map(x => normalizeCriteria(x)) : [];
this.exclude = exclude !== undefined ? exclude.map(x => normalizeCriteria(x)) : [];
if(this.include.length === 0 && this.exclude.length === 0) {
if(this.authorOptions.include?.length === 0 && this.authorOptions.exclude?.length === 0) {
throw new Error('At least one of the properties [include,exclude] on Author Rule must not be empty');
}
}
@@ -54,14 +48,11 @@ export class AuthorRule extends Rule {
}
protected getSpecificPremise(): object {
return {
include: this.include,
exclude: this.exclude,
};
return this.authorOptions;
}
protected async process(item: Comment | Submission): Promise<[boolean, RuleResult]> {
const [result, filterType] = await checkAuthorFilter(item, {include: this.include, exclude: this.exclude}, this.resources, this.logger);
const [result, filterType] = await checkAuthorFilter(item, this.authorOptions, this.resources, this.logger);
return Promise.resolve([result, this.getResult(result)]);
}
}

View File

@@ -332,10 +332,10 @@ export class RecentActivityRule extends Rule {
let validActivity: (Comment | Submission)[] = await as.filter(viableActivity, async (activity) => {
if (asSubmission(activity) && submissionState !== undefined) {
const {passed} = await this.resources.testItemCriteria(activity, submissionState, this.logger);
const {passed} = await this.resources.testItemCriteria(activity, {criteria: submissionState}, this.logger);
return passed;
} else if (commentState !== undefined) {
const {passed} = await this.resources.testItemCriteria(activity, commentState, this.logger);
const {passed} = await this.resources.testItemCriteria(activity, {criteria: commentState}, this.logger);
return passed;
}
return true;

View File

@@ -269,12 +269,19 @@
},
"type": "object"
},
"FilterOptions<AuthorCriteria>": {
"FilterOptionsJson<AuthorCriteria>": {
"properties": {
"exclude": {
"description": "Only runs if `include` is not present. Each Criteria is comprised of conditions that the filter (Author/Item) being checked must \"not\" pass. See excludeCondition for set behavior\n\nEX: `isMod: true, name: Automoderator` => Will pass if the Author IS NOT a mod and IS NOT named Automoderator",
"items": {
"$ref": "#/definitions/AuthorCriteria"
"anyOf": [
{
"$ref": "#/definitions/AuthorCriteria"
},
{
"$ref": "#/definitions/NamedCriteria<AuthorCriteria>"
}
]
},
"type": "array"
},
@@ -290,14 +297,21 @@
"include": {
"description": "Will \"pass\" if any set of Criteria passes",
"items": {
"$ref": "#/definitions/AuthorCriteria"
"anyOf": [
{
"$ref": "#/definitions/AuthorCriteria"
},
{
"$ref": "#/definitions/NamedCriteria<AuthorCriteria>"
}
]
},
"type": "array"
}
},
"type": "object"
},
"FilterOptions<TypedActivityState>": {
"FilterOptionsJson<TypedActivityState>": {
"properties": {
"exclude": {
"description": "Only runs if `include` is not present. Each Criteria is comprised of conditions that the filter (Author/Item) being checked must \"not\" pass. See excludeCondition for set behavior\n\nEX: `isMod: true, name: Automoderator` => Will pass if the Author IS NOT a mod and IS NOT named Automoderator",
@@ -308,6 +322,9 @@
},
{
"$ref": "#/definitions/CommentState"
},
{
"$ref": "#/definitions/NamedCriteria<TypedActivityState>"
}
]
},
@@ -331,6 +348,9 @@
},
{
"$ref": "#/definitions/CommentState"
},
{
"$ref": "#/definitions/NamedCriteria<TypedActivityState>"
}
]
},
@@ -339,6 +359,41 @@
},
"type": "object"
},
"NamedCriteria<AuthorCriteria>": {
"properties": {
"criteria": {
"$ref": "#/definitions/AuthorCriteria"
},
"name": {
"type": "string"
}
},
"required": [
"criteria"
],
"type": "object"
},
"NamedCriteria<TypedActivityState>": {
"properties": {
"criteria": {
"anyOf": [
{
"$ref": "#/definitions/SubmissionState"
},
{
"$ref": "#/definitions/CommentState"
}
]
},
"name": {
"type": "string"
}
},
"required": [
"criteria"
],
"type": "object"
},
"SubmissionState": {
"description": "Different attributes a `Submission` can be in. Only include a property if you want to check it.",
"examples": [
@@ -534,14 +589,21 @@
"properties": {
"authorIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<AuthorCriteria>"
},
{
"items": {
"$ref": "#/definitions/AuthorCriteria"
"anyOf": [
{
"$ref": "#/definitions/AuthorCriteria"
},
{
"$ref": "#/definitions/NamedCriteria<AuthorCriteria>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<AuthorCriteria>"
}
],
"description": "If present then these Author criteria are checked before running the Check. If criteria fails then the Check will fail."
@@ -565,9 +627,6 @@
},
"itemIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<TypedActivityState>"
},
{
"items": {
"anyOf": [
@@ -576,10 +635,16 @@
},
{
"$ref": "#/definitions/CommentState"
},
{
"$ref": "#/definitions/NamedCriteria<TypedActivityState>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<TypedActivityState>"
}
],
"description": "A list of criteria to test the state of the `Activity` against before running the check.\n\nIf any set of criteria passes the Check will be run. If the criteria fails then the Check will fail.\n\n* @examples [[{\"over_18\": true, \"removed': false}]]"

File diff suppressed because it is too large Load Diff

View File

@@ -595,14 +595,21 @@
"properties": {
"authorIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<AuthorCriteria>"
},
{
"items": {
"$ref": "#/definitions/AuthorCriteria"
"anyOf": [
{
"$ref": "#/definitions/AuthorCriteria"
},
{
"$ref": "#/definitions/NamedCriteria<AuthorCriteria>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<AuthorCriteria>"
}
],
"description": "Determine how authorIs defaults behave when authorIs is present on the check\n\n* merge => merges defaults with check's authorIs\n* replace => check authorIs will replace defaults (no defaults used)"
@@ -616,9 +623,6 @@
},
"itemIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<TypedActivityState>"
},
{
"items": {
"anyOf": [
@@ -627,10 +631,16 @@
},
{
"$ref": "#/definitions/CommentState"
},
{
"$ref": "#/definitions/NamedCriteria<TypedActivityState>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<TypedActivityState>"
}
]
},
@@ -645,12 +655,19 @@
},
"type": "object"
},
"FilterOptions<AuthorCriteria>": {
"FilterOptionsJson<AuthorCriteria>": {
"properties": {
"exclude": {
"description": "Only runs if `include` is not present. Each Criteria is comprised of conditions that the filter (Author/Item) being checked must \"not\" pass. See excludeCondition for set behavior\n\nEX: `isMod: true, name: Automoderator` => Will pass if the Author IS NOT a mod and IS NOT named Automoderator",
"items": {
"$ref": "#/definitions/AuthorCriteria"
"anyOf": [
{
"$ref": "#/definitions/AuthorCriteria"
},
{
"$ref": "#/definitions/NamedCriteria<AuthorCriteria>"
}
]
},
"type": "array"
},
@@ -666,14 +683,21 @@
"include": {
"description": "Will \"pass\" if any set of Criteria passes",
"items": {
"$ref": "#/definitions/AuthorCriteria"
"anyOf": [
{
"$ref": "#/definitions/AuthorCriteria"
},
{
"$ref": "#/definitions/NamedCriteria<AuthorCriteria>"
}
]
},
"type": "array"
}
},
"type": "object"
},
"FilterOptions<TypedActivityState>": {
"FilterOptionsJson<TypedActivityState>": {
"properties": {
"exclude": {
"description": "Only runs if `include` is not present. Each Criteria is comprised of conditions that the filter (Author/Item) being checked must \"not\" pass. See excludeCondition for set behavior\n\nEX: `isMod: true, name: Automoderator` => Will pass if the Author IS NOT a mod and IS NOT named Automoderator",
@@ -684,6 +708,9 @@
},
{
"$ref": "#/definitions/CommentState"
},
{
"$ref": "#/definitions/NamedCriteria<TypedActivityState>"
}
]
},
@@ -707,6 +734,9 @@
},
{
"$ref": "#/definitions/CommentState"
},
{
"$ref": "#/definitions/NamedCriteria<TypedActivityState>"
}
]
},
@@ -826,6 +856,41 @@
},
"type": "object"
},
"NamedCriteria<AuthorCriteria>": {
"properties": {
"criteria": {
"$ref": "#/definitions/AuthorCriteria"
},
"name": {
"type": "string"
}
},
"required": [
"criteria"
],
"type": "object"
},
"NamedCriteria<TypedActivityState>": {
"properties": {
"criteria": {
"anyOf": [
{
"$ref": "#/definitions/SubmissionState"
},
{
"$ref": "#/definitions/CommentState"
}
]
},
"name": {
"type": "string"
}
},
"required": [
"criteria"
],
"type": "object"
},
"NotificationConfig": {
"properties": {
"events": {

View File

@@ -341,14 +341,21 @@
"properties": {
"authorIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<AuthorCriteria>"
},
{
"items": {
"$ref": "#/definitions/AuthorCriteria"
"anyOf": [
{
"$ref": "#/definitions/AuthorCriteria"
},
{
"$ref": "#/definitions/NamedCriteria<AuthorCriteria>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<AuthorCriteria>"
}
],
"description": "If present then these Author criteria are checked before running the Check. If criteria fails then the Check will fail."
@@ -371,9 +378,6 @@
},
"itemIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<TypedActivityState>"
},
{
"items": {
"anyOf": [
@@ -382,10 +386,16 @@
},
{
"$ref": "#/definitions/CommentState"
},
{
"$ref": "#/definitions/NamedCriteria<TypedActivityState>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<TypedActivityState>"
}
],
"description": "A list of criteria to test the state of the `Activity` against before running the check.\n\nIf any set of criteria passes the Check will be run. If the criteria fails then the Check will fail.\n\n* @examples [[{\"over_18\": true, \"removed': false}]]"
@@ -567,14 +577,21 @@
"properties": {
"authorIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<AuthorCriteria>"
},
{
"items": {
"$ref": "#/definitions/AuthorCriteria"
"anyOf": [
{
"$ref": "#/definitions/AuthorCriteria"
},
{
"$ref": "#/definitions/NamedCriteria<AuthorCriteria>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<AuthorCriteria>"
}
],
"description": "If present then these Author criteria are checked before running the Check. If criteria fails then the Check will fail."
@@ -595,9 +612,6 @@
},
"itemIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<TypedActivityState>"
},
{
"items": {
"anyOf": [
@@ -606,10 +620,16 @@
},
{
"$ref": "#/definitions/CommentState"
},
{
"$ref": "#/definitions/NamedCriteria<TypedActivityState>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<TypedActivityState>"
}
],
"description": "A list of criteria to test the state of the `Activity` against before running the check.\n\nIf any set of criteria passes the Check will be run. If the criteria fails then the Check will fail.\n\n* @examples [[{\"over_18\": true, \"removed': false}]]"
@@ -789,12 +809,19 @@
},
"type": "object"
},
"FilterOptions<AuthorCriteria>": {
"FilterOptionsJson<AuthorCriteria>": {
"properties": {
"exclude": {
"description": "Only runs if `include` is not present. Each Criteria is comprised of conditions that the filter (Author/Item) being checked must \"not\" pass. See excludeCondition for set behavior\n\nEX: `isMod: true, name: Automoderator` => Will pass if the Author IS NOT a mod and IS NOT named Automoderator",
"items": {
"$ref": "#/definitions/AuthorCriteria"
"anyOf": [
{
"$ref": "#/definitions/AuthorCriteria"
},
{
"$ref": "#/definitions/NamedCriteria<AuthorCriteria>"
}
]
},
"type": "array"
},
@@ -810,14 +837,21 @@
"include": {
"description": "Will \"pass\" if any set of Criteria passes",
"items": {
"$ref": "#/definitions/AuthorCriteria"
"anyOf": [
{
"$ref": "#/definitions/AuthorCriteria"
},
{
"$ref": "#/definitions/NamedCriteria<AuthorCriteria>"
}
]
},
"type": "array"
}
},
"type": "object"
},
"FilterOptions<TypedActivityState>": {
"FilterOptionsJson<TypedActivityState>": {
"properties": {
"exclude": {
"description": "Only runs if `include` is not present. Each Criteria is comprised of conditions that the filter (Author/Item) being checked must \"not\" pass. See excludeCondition for set behavior\n\nEX: `isMod: true, name: Automoderator` => Will pass if the Author IS NOT a mod and IS NOT named Automoderator",
@@ -828,6 +862,9 @@
},
{
"$ref": "#/definitions/CommentState"
},
{
"$ref": "#/definitions/NamedCriteria<TypedActivityState>"
}
]
},
@@ -851,6 +888,9 @@
},
{
"$ref": "#/definitions/CommentState"
},
{
"$ref": "#/definitions/NamedCriteria<TypedActivityState>"
}
]
},
@@ -916,14 +956,21 @@
"properties": {
"authorIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<AuthorCriteria>"
},
{
"items": {
"$ref": "#/definitions/AuthorCriteria"
"anyOf": [
{
"$ref": "#/definitions/AuthorCriteria"
},
{
"$ref": "#/definitions/NamedCriteria<AuthorCriteria>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<AuthorCriteria>"
}
],
"description": "If present then these Author criteria are checked before running the Check. If criteria fails then the Check will fail."
@@ -994,9 +1041,6 @@
},
"itemIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<TypedActivityState>"
},
{
"items": {
"anyOf": [
@@ -1005,10 +1049,16 @@
},
{
"$ref": "#/definitions/CommentState"
},
{
"$ref": "#/definitions/NamedCriteria<TypedActivityState>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<TypedActivityState>"
}
],
"description": "A list of criteria to test the state of the `Activity` against before running the check.\n\nIf any set of criteria passes the Check will be run. If the criteria fails then the Check will fail.\n\n* @examples [[{\"over_18\": true, \"removed': false}]]"
@@ -1106,6 +1156,41 @@
},
"type": "object"
},
"NamedCriteria<AuthorCriteria>": {
"properties": {
"criteria": {
"$ref": "#/definitions/AuthorCriteria"
},
"name": {
"type": "string"
}
},
"required": [
"criteria"
],
"type": "object"
},
"NamedCriteria<TypedActivityState>": {
"properties": {
"criteria": {
"anyOf": [
{
"$ref": "#/definitions/SubmissionState"
},
{
"$ref": "#/definitions/CommentState"
}
]
},
"name": {
"type": "string"
}
},
"required": [
"criteria"
],
"type": "object"
},
"OccurredAt": {
"properties": {
"condition": {
@@ -1181,14 +1266,21 @@
"properties": {
"authorIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<AuthorCriteria>"
},
{
"items": {
"$ref": "#/definitions/AuthorCriteria"
"anyOf": [
{
"$ref": "#/definitions/AuthorCriteria"
},
{
"$ref": "#/definitions/NamedCriteria<AuthorCriteria>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<AuthorCriteria>"
}
],
"description": "If present then these Author criteria are checked before running the Check. If criteria fails then the Check will fail."
@@ -1199,9 +1291,6 @@
},
"itemIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<TypedActivityState>"
},
{
"items": {
"anyOf": [
@@ -1210,10 +1299,16 @@
},
{
"$ref": "#/definitions/CommentState"
},
{
"$ref": "#/definitions/NamedCriteria<TypedActivityState>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<TypedActivityState>"
}
],
"description": "A list of criteria to test the state of the `Activity` against before running the check.\n\nIf any set of criteria passes the Check will be run. If the criteria fails then the Check will fail.\n\n* @examples [[{\"over_18\": true, \"removed': false}]]"
@@ -1436,14 +1531,21 @@
"properties": {
"authorIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<AuthorCriteria>"
},
{
"items": {
"$ref": "#/definitions/AuthorCriteria"
"anyOf": [
{
"$ref": "#/definitions/AuthorCriteria"
},
{
"$ref": "#/definitions/NamedCriteria<AuthorCriteria>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<AuthorCriteria>"
}
],
"description": "If present then these Author criteria are checked before running the Check. If criteria fails then the Check will fail."
@@ -1473,9 +1575,6 @@
},
"itemIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<TypedActivityState>"
},
{
"items": {
"anyOf": [
@@ -1484,10 +1583,16 @@
},
{
"$ref": "#/definitions/CommentState"
},
{
"$ref": "#/definitions/NamedCriteria<TypedActivityState>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<TypedActivityState>"
}
],
"description": "A list of criteria to test the state of the `Activity` against before running the check.\n\nIf any set of criteria passes the Check will be run. If the criteria fails then the Check will fail.\n\n* @examples [[{\"over_18\": true, \"removed': false}]]"
@@ -1522,14 +1627,21 @@
"properties": {
"authorIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<AuthorCriteria>"
},
{
"items": {
"$ref": "#/definitions/AuthorCriteria"
"anyOf": [
{
"$ref": "#/definitions/AuthorCriteria"
},
{
"$ref": "#/definitions/NamedCriteria<AuthorCriteria>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<AuthorCriteria>"
}
],
"description": "If present then these Author criteria are checked before running the Check. If criteria fails then the Check will fail."
@@ -1593,9 +1705,6 @@
},
"itemIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<TypedActivityState>"
},
{
"items": {
"anyOf": [
@@ -1604,10 +1713,16 @@
},
{
"$ref": "#/definitions/CommentState"
},
{
"$ref": "#/definitions/NamedCriteria<TypedActivityState>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<TypedActivityState>"
}
],
"description": "A list of criteria to test the state of the `Activity` against before running the check.\n\nIf any set of criteria passes the Check will be run. If the criteria fails then the Check will fail.\n\n* @examples [[{\"over_18\": true, \"removed': false}]]"
@@ -1831,14 +1946,21 @@
"properties": {
"authorIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<AuthorCriteria>"
},
{
"items": {
"$ref": "#/definitions/AuthorCriteria"
"anyOf": [
{
"$ref": "#/definitions/AuthorCriteria"
},
{
"$ref": "#/definitions/NamedCriteria<AuthorCriteria>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<AuthorCriteria>"
}
],
"description": "If present then these Author criteria are checked before running the Check. If criteria fails then the Check will fail."
@@ -1868,9 +1990,6 @@
},
"itemIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<TypedActivityState>"
},
{
"items": {
"anyOf": [
@@ -1879,10 +1998,16 @@
},
{
"$ref": "#/definitions/CommentState"
},
{
"$ref": "#/definitions/NamedCriteria<TypedActivityState>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<TypedActivityState>"
}
],
"description": "A list of criteria to test the state of the `Activity` against before running the check.\n\nIf any set of criteria passes the Check will be run. If the criteria fails then the Check will fail.\n\n* @examples [[{\"over_18\": true, \"removed': false}]]"

View File

@@ -315,14 +315,21 @@
"properties": {
"authorIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<AuthorCriteria>"
},
{
"items": {
"$ref": "#/definitions/AuthorCriteria"
"anyOf": [
{
"$ref": "#/definitions/AuthorCriteria"
},
{
"$ref": "#/definitions/NamedCriteria<AuthorCriteria>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<AuthorCriteria>"
}
],
"description": "If present then these Author criteria are checked before running the Check. If criteria fails then the Check will fail."
@@ -345,9 +352,6 @@
},
"itemIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<TypedActivityState>"
},
{
"items": {
"anyOf": [
@@ -356,10 +360,16 @@
},
{
"$ref": "#/definitions/CommentState"
},
{
"$ref": "#/definitions/NamedCriteria<TypedActivityState>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<TypedActivityState>"
}
],
"description": "A list of criteria to test the state of the `Activity` against before running the check.\n\nIf any set of criteria passes the Check will be run. If the criteria fails then the Check will fail.\n\n* @examples [[{\"over_18\": true, \"removed': false}]]"
@@ -541,14 +551,21 @@
"properties": {
"authorIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<AuthorCriteria>"
},
{
"items": {
"$ref": "#/definitions/AuthorCriteria"
"anyOf": [
{
"$ref": "#/definitions/AuthorCriteria"
},
{
"$ref": "#/definitions/NamedCriteria<AuthorCriteria>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<AuthorCriteria>"
}
],
"description": "If present then these Author criteria are checked before running the Check. If criteria fails then the Check will fail."
@@ -569,9 +586,6 @@
},
"itemIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<TypedActivityState>"
},
{
"items": {
"anyOf": [
@@ -580,10 +594,16 @@
},
{
"$ref": "#/definitions/CommentState"
},
{
"$ref": "#/definitions/NamedCriteria<TypedActivityState>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<TypedActivityState>"
}
],
"description": "A list of criteria to test the state of the `Activity` against before running the check.\n\nIf any set of criteria passes the Check will be run. If the criteria fails then the Check will fail.\n\n* @examples [[{\"over_18\": true, \"removed': false}]]"
@@ -763,12 +783,19 @@
},
"type": "object"
},
"FilterOptions<AuthorCriteria>": {
"FilterOptionsJson<AuthorCriteria>": {
"properties": {
"exclude": {
"description": "Only runs if `include` is not present. Each Criteria is comprised of conditions that the filter (Author/Item) being checked must \"not\" pass. See excludeCondition for set behavior\n\nEX: `isMod: true, name: Automoderator` => Will pass if the Author IS NOT a mod and IS NOT named Automoderator",
"items": {
"$ref": "#/definitions/AuthorCriteria"
"anyOf": [
{
"$ref": "#/definitions/AuthorCriteria"
},
{
"$ref": "#/definitions/NamedCriteria<AuthorCriteria>"
}
]
},
"type": "array"
},
@@ -784,14 +811,21 @@
"include": {
"description": "Will \"pass\" if any set of Criteria passes",
"items": {
"$ref": "#/definitions/AuthorCriteria"
"anyOf": [
{
"$ref": "#/definitions/AuthorCriteria"
},
{
"$ref": "#/definitions/NamedCriteria<AuthorCriteria>"
}
]
},
"type": "array"
}
},
"type": "object"
},
"FilterOptions<TypedActivityState>": {
"FilterOptionsJson<TypedActivityState>": {
"properties": {
"exclude": {
"description": "Only runs if `include` is not present. Each Criteria is comprised of conditions that the filter (Author/Item) being checked must \"not\" pass. See excludeCondition for set behavior\n\nEX: `isMod: true, name: Automoderator` => Will pass if the Author IS NOT a mod and IS NOT named Automoderator",
@@ -802,6 +836,9 @@
},
{
"$ref": "#/definitions/CommentState"
},
{
"$ref": "#/definitions/NamedCriteria<TypedActivityState>"
}
]
},
@@ -825,6 +862,9 @@
},
{
"$ref": "#/definitions/CommentState"
},
{
"$ref": "#/definitions/NamedCriteria<TypedActivityState>"
}
]
},
@@ -890,14 +930,21 @@
"properties": {
"authorIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<AuthorCriteria>"
},
{
"items": {
"$ref": "#/definitions/AuthorCriteria"
"anyOf": [
{
"$ref": "#/definitions/AuthorCriteria"
},
{
"$ref": "#/definitions/NamedCriteria<AuthorCriteria>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<AuthorCriteria>"
}
],
"description": "If present then these Author criteria are checked before running the Check. If criteria fails then the Check will fail."
@@ -968,9 +1015,6 @@
},
"itemIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<TypedActivityState>"
},
{
"items": {
"anyOf": [
@@ -979,10 +1023,16 @@
},
{
"$ref": "#/definitions/CommentState"
},
{
"$ref": "#/definitions/NamedCriteria<TypedActivityState>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<TypedActivityState>"
}
],
"description": "A list of criteria to test the state of the `Activity` against before running the check.\n\nIf any set of criteria passes the Check will be run. If the criteria fails then the Check will fail.\n\n* @examples [[{\"over_18\": true, \"removed': false}]]"
@@ -1080,6 +1130,41 @@
},
"type": "object"
},
"NamedCriteria<AuthorCriteria>": {
"properties": {
"criteria": {
"$ref": "#/definitions/AuthorCriteria"
},
"name": {
"type": "string"
}
},
"required": [
"criteria"
],
"type": "object"
},
"NamedCriteria<TypedActivityState>": {
"properties": {
"criteria": {
"anyOf": [
{
"$ref": "#/definitions/SubmissionState"
},
{
"$ref": "#/definitions/CommentState"
}
]
},
"name": {
"type": "string"
}
},
"required": [
"criteria"
],
"type": "object"
},
"OccurredAt": {
"properties": {
"condition": {
@@ -1155,14 +1240,21 @@
"properties": {
"authorIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<AuthorCriteria>"
},
{
"items": {
"$ref": "#/definitions/AuthorCriteria"
"anyOf": [
{
"$ref": "#/definitions/AuthorCriteria"
},
{
"$ref": "#/definitions/NamedCriteria<AuthorCriteria>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<AuthorCriteria>"
}
],
"description": "If present then these Author criteria are checked before running the Check. If criteria fails then the Check will fail."
@@ -1173,9 +1265,6 @@
},
"itemIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<TypedActivityState>"
},
{
"items": {
"anyOf": [
@@ -1184,10 +1273,16 @@
},
{
"$ref": "#/definitions/CommentState"
},
{
"$ref": "#/definitions/NamedCriteria<TypedActivityState>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<TypedActivityState>"
}
],
"description": "A list of criteria to test the state of the `Activity` against before running the check.\n\nIf any set of criteria passes the Check will be run. If the criteria fails then the Check will fail.\n\n* @examples [[{\"over_18\": true, \"removed': false}]]"
@@ -1410,14 +1505,21 @@
"properties": {
"authorIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<AuthorCriteria>"
},
{
"items": {
"$ref": "#/definitions/AuthorCriteria"
"anyOf": [
{
"$ref": "#/definitions/AuthorCriteria"
},
{
"$ref": "#/definitions/NamedCriteria<AuthorCriteria>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<AuthorCriteria>"
}
],
"description": "If present then these Author criteria are checked before running the Check. If criteria fails then the Check will fail."
@@ -1447,9 +1549,6 @@
},
"itemIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<TypedActivityState>"
},
{
"items": {
"anyOf": [
@@ -1458,10 +1557,16 @@
},
{
"$ref": "#/definitions/CommentState"
},
{
"$ref": "#/definitions/NamedCriteria<TypedActivityState>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<TypedActivityState>"
}
],
"description": "A list of criteria to test the state of the `Activity` against before running the check.\n\nIf any set of criteria passes the Check will be run. If the criteria fails then the Check will fail.\n\n* @examples [[{\"over_18\": true, \"removed': false}]]"
@@ -1496,14 +1601,21 @@
"properties": {
"authorIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<AuthorCriteria>"
},
{
"items": {
"$ref": "#/definitions/AuthorCriteria"
"anyOf": [
{
"$ref": "#/definitions/AuthorCriteria"
},
{
"$ref": "#/definitions/NamedCriteria<AuthorCriteria>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<AuthorCriteria>"
}
],
"description": "If present then these Author criteria are checked before running the Check. If criteria fails then the Check will fail."
@@ -1567,9 +1679,6 @@
},
"itemIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<TypedActivityState>"
},
{
"items": {
"anyOf": [
@@ -1578,10 +1687,16 @@
},
{
"$ref": "#/definitions/CommentState"
},
{
"$ref": "#/definitions/NamedCriteria<TypedActivityState>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<TypedActivityState>"
}
],
"description": "A list of criteria to test the state of the `Activity` against before running the check.\n\nIf any set of criteria passes the Check will be run. If the criteria fails then the Check will fail.\n\n* @examples [[{\"over_18\": true, \"removed': false}]]"
@@ -1805,14 +1920,21 @@
"properties": {
"authorIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<AuthorCriteria>"
},
{
"items": {
"$ref": "#/definitions/AuthorCriteria"
"anyOf": [
{
"$ref": "#/definitions/AuthorCriteria"
},
{
"$ref": "#/definitions/NamedCriteria<AuthorCriteria>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<AuthorCriteria>"
}
],
"description": "If present then these Author criteria are checked before running the Check. If criteria fails then the Check will fail."
@@ -1842,9 +1964,6 @@
},
"itemIs": {
"anyOf": [
{
"$ref": "#/definitions/FilterOptions<TypedActivityState>"
},
{
"items": {
"anyOf": [
@@ -1853,10 +1972,16 @@
},
{
"$ref": "#/definitions/CommentState"
},
{
"$ref": "#/definitions/NamedCriteria<TypedActivityState>"
}
]
},
"type": "array"
},
{
"$ref": "#/definitions/FilterOptionsJson<TypedActivityState>"
}
],
"description": "A list of criteria to test the state of the `Activity` against before running the check.\n\nIf any set of criteria passes the Check will be run. If the criteria fails then the Check will fail.\n\n* @examples [[{\"over_18\": true, \"removed': false}]]"

View File

@@ -82,7 +82,7 @@ import {
ItemCritPropHelper,
ActivityDispatch,
FilterCriteriaPropertyResult,
ActivitySource, HistoricalStatsDisplay, UserNoteCriteria, AuthorCriteria, AuthorOptions, ItemOptions, JoinOperands,
ActivitySource, HistoricalStatsDisplay, UserNoteCriteria, AuthorCriteria, AuthorOptions, ItemOptions, JoinOperands, NamedCriteria,
} from "../Common/interfaces";
import UserNotes from "./UserNotes";
import Mustache from "mustache";
@@ -1169,7 +1169,9 @@ export class SubredditResources {
return await this.isSubreddit(await this.getSubreddit(item), state, this.logger);
}
async testAuthorCriteria(item: (Comment | Submission), authorOpts: AuthorCriteria, include = true): Promise<FilterCriteriaResult<AuthorCriteria>> {
async testAuthorCriteria(item: (Comment | Submission), authorOptsObj: NamedCriteria<AuthorCriteria>, include = true): Promise<FilterCriteriaResult<AuthorCriteria>> {
const {criteria: authorOpts} = authorOptsObj;
if (this.filterCriteriaTTL !== false) {
// in the criteria check we only actually use the `item` to get the author flair
// which will be the same for the entire subreddit
@@ -1191,19 +1193,23 @@ export class SubredditResources {
} else {
this.stats.cache.authorCrit.miss++;
cachedAuthorTest = await this.isAuthor(item, authorOpts, include);
cachedAuthorTest.criteria = authorOptsObj;
await this.cache.set(hash, cachedAuthorTest, {ttl: this.filterCriteriaTTL});
return cachedAuthorTest;
}
}
return await this.isAuthor(item, authorOpts, include);
const res = await this.isAuthor(item, authorOpts, include);
res.criteria = authorOptsObj;
return res;
}
async testItemCriteria(i: (Comment | Submission), activityState: TypedActivityState, logger: Logger, include = true, source?: ActivitySource): Promise<FilterCriteriaResult<TypedActivityState>> {
async testItemCriteria(i: (Comment | Submission), activityStateObj: NamedCriteria<TypedActivityState>, logger: Logger, include = true, source?: ActivitySource): Promise<FilterCriteriaResult<TypedActivityState>> {
const {criteria: activityState} = activityStateObj;
if(Object.keys(activityState).length === 0) {
return {
behavior: include ? 'include' : 'exclude',
criteria: activityState,
criteria: activityStateObj,
propertyResults: [],
passed: true
}
@@ -1231,7 +1237,7 @@ export class SubredditResources {
return {
behavior: include ? 'include' : 'exclude',
criteria: activityState,
criteria: activityStateObj,
propertyResults: Object.values(propResultsMap),
passed: false
}
@@ -1263,7 +1269,7 @@ export class SubredditResources {
itemResult.propertyResults.push(runtimeRes.propertyResults.find(x => x.property === 'source') as FilterCriteriaPropertyResult<TypedActivityState>);
}
}
itemResult.criteria = activityStateObj;
return itemResult;
} catch (err: any) {
if (err.logged !== true) {
@@ -1273,7 +1279,9 @@ export class SubredditResources {
}
}
return await this.isItem(i, activityState, logger, include, source);
const res = await this.isItem(i, activityState, logger, include, source);
res.criteria = activityStateObj;
return res;
}
async isSubreddit (subreddit: Subreddit, stateCriteriaRaw: SubredditState | StrongSubredditState, logger: Logger) {
@@ -1350,7 +1358,7 @@ export class SubredditResources {
if(Object.keys(stateCriteria).length === 0) {
return {
behavior: include ? 'include' : 'exclude',
criteria: stateCriteria,
criteria: {criteria: stateCriteria},
propertyResults: [],
passed: true
}
@@ -1641,7 +1649,7 @@ export class SubredditResources {
return {
behavior: include ? 'include' : 'exclude',
criteria: stateCriteria,
criteria: {criteria: stateCriteria},
propertyResults: propResults,
passed,
};
@@ -2026,7 +2034,7 @@ export class SubredditResources {
return {
behavior: include ? 'include' : 'exclude',
criteria: authorOpts,
criteria: {criteria: authorOpts},
propertyResults: propResults,
passed,
};
@@ -2437,7 +2445,8 @@ export const checkItemFilter = async (item: (Submission | Comment), filter: Item
if(include.length > 0) {
let index = 1
for(const state of include) {
for(const namedState of include) {
const { criteria: state, name } = namedState;
let critResult: FilterCriteriaResult<TypedActivityState>;
// need to determine if criteria is for comment or submission state
@@ -2453,21 +2462,21 @@ export const checkItemFilter = async (item: (Submission | Comment), filter: Item
propResultsMap.submissionState = subPropertyResult;
critResult = {
behavior: 'include',
criteria: state,
criteria: namedState,
propertyResults: Object.values(propResultsMap),
passed: false
}
} else {
critResult = await resources.testItemCriteria(item, restCommentState, parentLogger, true, source);
critResult.criteria = state;
critResult = await resources.testItemCriteria(item, {criteria: restCommentState}, parentLogger, true, source);
critResult.criteria = namedState;
critResult.propertyResults.unshift(subPropertyResult);
}
} else {
critResult = await resources.testItemCriteria(item, state, parentLogger, true, source);
critResult = await resources.testItemCriteria(item, namedState, parentLogger, true, source);
}
if(critResult.propertyResults.some(x => x.property === 'source')) {
critResult.criteria.source = source;
critResult.criteria.criteria.source = source;
}
//critResult = await resources.testItemCriteria(item, state, parentLogger);
@@ -2490,7 +2499,10 @@ export const checkItemFilter = async (item: (Submission | Comment), filter: Item
if (exclude.length > 0) {
let index = 1;
const summaries: string[] = [];
for (const state of exclude) {
for (const namedState of exclude) {
const { criteria: state, name } = namedState;
let critResult: FilterCriteriaResult<TypedActivityState>;
if(isCommentState(state) && asComment(item) && state.submissionState !== undefined) {
@@ -2504,21 +2516,21 @@ export const checkItemFilter = async (item: (Submission | Comment), filter: Item
propResultsMap.submissionState = subPropertyResult;
critResult = {
behavior: 'include',
criteria: state,
criteria: namedState,
propertyResults: Object.values(propResultsMap),
passed: false
}
} else {
critResult = await resources.testItemCriteria(item, restCommentState, parentLogger, false, source);
critResult.criteria = state;
critResult = await resources.testItemCriteria(item, {criteria: restCommentState}, parentLogger, false, source);
critResult.criteria = namedState;
critResult.propertyResults.unshift(subPropertyResult);
}
} else {
critResult = await resources.testItemCriteria(item, state, parentLogger, false, source);
critResult = await resources.testItemCriteria(item, namedState, parentLogger, false, source);
}
if(critResult.propertyResults.some(x => x.property === 'source')) {
critResult.criteria.source = source;
critResult.criteria.criteria.source = source;
}
//critResult = await resources.testItemCriteria(item, state, parentLogger, false);
@@ -2576,9 +2588,9 @@ export const checkCommentSubmissionStates = async (item: Comment, submissionStat
const sub = await resources.getActivity(subProxy);
const subStatesFilter: ItemOptions = {
include: excludeCondition === undefined ? submissionStates : undefined,
include: excludeCondition === undefined ? submissionStates.map(x => ({criteria: x})) : undefined,
excludeCondition,
exclude: excludeCondition === undefined ? undefined : submissionStates
exclude: excludeCondition === undefined ? undefined : submissionStates.map(x => ({criteria: x}))
}
const [subPass, _, subFilterResults] = await checkItemFilter(sub, subStatesFilter, resources, logger);

View File

@@ -32,7 +32,7 @@ import {
GenericComparison,
ImageComparisonResult,
ItemCritPropHelper, ItemOptions,
LogInfo, MinimalOrFullFilter,
LogInfo, MaybeAnonymousCriteria, MinimalOrFullFilter, NamedCriteria,
OperatorJsonConfig,
PermalinkRedditThings,
PollingOptionsStrong,
@@ -459,7 +459,7 @@ export const filterCriteriaSummary = <T>(val: FilterCriteriaResult<T>): [string,
propSummary.push(dnrProps);
}
const propSummaryStrArr = propSummary.map(x => `${x.props.length} ${x.name}${x.props.length > 0 ? ` (${x.props.map(y => y.property as string)})` : ''}`);
return [propSummaryStrArr.join(' | '), val.propertyResults.map(x => filterCriteriaPropertySummary(x, val.criteria))]
return [propSummaryStrArr.join(' | '), val.propertyResults.map(x => filterCriteriaPropertySummary(x, val.criteria.criteria))]
}
export const filterCriteriaPropertySummary = <T>(val: FilterCriteriaPropertyResult<T>, criteria: T): string => {
@@ -479,7 +479,7 @@ export const filterCriteriaPropertySummary = <T>(val: FilterCriteriaPropertyResu
found = '';
} else if(val.property === 'submissionState') {
const foundResult = val.found as FilterResult<SubmissionState>;
const criteriaResults = foundResult.criteriaResults.map((x, index) => `Criteria #${index + 1} => ${triggeredIndicator(x.passed)}\n ${x.propertyResults.map(y => filterCriteriaPropertySummary(y, x.criteria)).join('\n ')}`).join('\n ');
const criteriaResults = foundResult.criteriaResults.map((x, index) => `Criteria #${index + 1} => ${triggeredIndicator(x.passed)}\n ${x.propertyResults.map(y => filterCriteriaPropertySummary(y, x.criteria.criteria)).join('\n ')}`).join('\n ');
found = `\n ${criteriaResults}`;
} else {
found = ` => Found: ${val.found}`;
@@ -2345,6 +2345,37 @@ export const buildFilter = <T extends AuthorCriteria | TypedActivityState>(filte
}
}
export const normalizeCriteria = <T extends AuthorCriteria | TypedActivityState>(options: MaybeAnonymousCriteria<T>): NamedCriteria<T> => {
let name: string | undefined;
let criteria: T;
if (asNamedCriteria(options)) {
criteria = options.criteria;
name = options.name;
} else {
criteria = options;
}
if (asAuthorCriteria(criteria)) {
criteria = {
...criteria,
flairCssClass: typeof criteria.flairCssClass === 'string' ? [criteria.flairCssClass] : criteria.flairCssClass,
flairText: typeof criteria.flairText === 'string' ? [criteria.flairText] : criteria.flairText,
description: criteria.description === undefined ? undefined : Array.isArray(criteria.description) ? criteria.description : [criteria.description]
}
}
return {
name,
criteria
};
}
export const asNamedCriteria = <T>(val: MaybeAnonymousCriteria<T>): val is NamedCriteria<T> => {
return 'criteria' in val;
}
export const formatFilterData = (result: (RunResult | CheckSummary | RuleResult | ActionResult)) => {
const formattedResult: any = {
@@ -2593,20 +2624,6 @@ export const asAuthorCriteria = (val: any): val is AuthorCriteria => {
return false;
}
export const normalizeCriteria = <T extends AuthorCriteria | TypedActivityState>(options: T): T => {
if(asAuthorCriteria(options)) {
return {
...options,
flairCssClass: typeof options.flairCssClass === 'string' ? [options.flairCssClass] : options.flairCssClass,
flairText: typeof options.flairText === 'string' ? [options.flairText] : options.flairText,
description: options.description === undefined ? undefined : Array.isArray(options.description) ? options.description : [options.description]
}
}
return options;
}
export const criteriaPassWithIncludeBehavior = (passes: boolean, include: boolean) => {
// if inner statement IS TRUE then criteria FAILED
// so to get pass result reverse inner statement result