refactor: Reduce circular dependencies

This commit is contained in:
FoxxMD
2022-05-09 20:12:08 -04:00
parent 951fab1070
commit 52ae16be1c
59 changed files with 388 additions and 355 deletions

View File

@@ -16,7 +16,7 @@ import EventEmitter from "events";
import {DispatchAction, DispatchActionJson} from "./DispatchAction";
import {CancelDispatchAction, CancelDispatchActionJson} from "./CancelDispatchAction";
import ContributorAction, {ContributorActionJson} from "./ContributorAction";
import {StructuredFilter} from "../Common/interfaces";
import {StructuredFilter} from "../Common/Infrastructure/Filters/FilterShapes";
export function actionFactory
(config: StructuredActionJson, logger: Logger, subredditName: string, resources: SubredditResources, client: ExtendedSnoowrap, emitter: EventEmitter): Action {

View File

@@ -4,10 +4,9 @@ import Snoowrap from "snoowrap";
import {ActionProcessResult, RuleResult} from "../Common/interfaces";
import Submission from "snoowrap/dist/objects/Submission";
import Comment from "snoowrap/dist/objects/Comment";
import {ActionTypes} from "../Common/types";
import {RuleResultEntity} from "../Common/Entities/RuleResultEntity";
import {runCheckOptions} from "../Subreddit/Manager";
import {ActionTarget} from "../Common/Infrastructure/Atomic";
import {ActionTarget, ActionTypes} from "../Common/Infrastructure/Atomic";
export class ApproveAction extends Action {

View File

@@ -3,9 +3,9 @@ import Action from "./index";
import Snoowrap, {Comment, Submission} from "snoowrap";
import {renderContent} from "../Utils/SnoowrapUtils";
import {ActionProcessResult, Footer, RuleResult} from "../Common/interfaces";
import {ActionTypes} from "../Common/types";
import {RuleResultEntity} from "../Common/Entities/RuleResultEntity";
import {runCheckOptions} from "../Subreddit/Manager";
import {ActionTypes} from "../Common/Infrastructure/Atomic";
export class BanAction extends Action {

View File

@@ -9,10 +9,9 @@ import {
} from "../Common/interfaces";
import dayjs from "dayjs";
import {isSubmission, parseDurationValToDuration} from "../util";
import {ActionTypes} from "../Common/types";
import {RuleResultEntity} from "../Common/Entities/RuleResultEntity";
import {runCheckOptions} from "../Subreddit/Manager";
import {ActionTarget, InclusiveActionTarget} from "../Common/Infrastructure/Atomic";
import {ActionTarget, ActionTypes, InclusiveActionTarget} from "../Common/Infrastructure/Atomic";
export class CancelDispatchAction extends Action {
identifiers?: (string | null)[];

View File

@@ -4,9 +4,9 @@ import Submission from "snoowrap/dist/objects/Submission";
import {renderContent} from "../Utils/SnoowrapUtils";
import {ActionProcessResult, Footer, RequiredRichContent, RichContent, RuleResult} from "../Common/interfaces";
import {truncateStringToLength} from "../util";
import {ActionTypes} from "../Common/types";
import {RuleResultEntity} from "../Common/Entities/RuleResultEntity";
import {runCheckOptions} from "../Subreddit/Manager";
import {ActionTypes} from "../Common/Infrastructure/Atomic";
export class CommentAction extends Action {
content: string;

View File

@@ -4,10 +4,9 @@ import Snoowrap from "snoowrap";
import {ActionProcessResult, RuleResult} from "../Common/interfaces";
import Submission from "snoowrap/dist/objects/Submission";
import Comment from "snoowrap/dist/objects/Comment";
import {ActionTypes} from "../Common/types";
import {RuleResultEntity} from "../Common/Entities/RuleResultEntity";
import {runCheckOptions} from "../Subreddit/Manager";
import {ActionTarget} from "../Common/Infrastructure/Atomic";
import {ActionTarget, ActionTypes} from "../Common/Infrastructure/Atomic";
export class ContributorAction extends Action {

View File

@@ -5,10 +5,9 @@ import {activityIsRemoved} from "../Utils/SnoowrapUtils";
import {ActionProcessResult, ActivityDispatchConfig, RuleResult} from "../Common/interfaces";
import dayjs from "dayjs";
import {activityDispatchConfigToDispatch, isSubmission, parseDurationValToDuration, randomId} from "../util";
import {ActionTypes} from "../Common/types";
import {RuleResultEntity} from "../Common/Entities/RuleResultEntity";
import {runCheckOptions} from "../Subreddit/Manager";
import {ActionTarget} from "../Common/Infrastructure/Atomic";
import {ActionTarget, ActionTypes} from "../Common/Infrastructure/Atomic";
export class DispatchAction extends Action {
dispatchData: ActivityDispatchConfig;

View File

@@ -2,9 +2,9 @@ import {ActionJson, ActionConfig} from "./index";
import Action from "./index";
import Snoowrap, {Comment, Submission} from "snoowrap";
import {ActionProcessResult, RuleResult} from "../Common/interfaces";
import {ActionTypes} from "../Common/types";
import {RuleResultEntity} from "../Common/Entities/RuleResultEntity";
import {runCheckOptions} from "../Subreddit/Manager";
import {ActionTypes} from "../Common/Infrastructure/Atomic";
export class LockAction extends Action {
getKind(): ActionTypes {

View File

@@ -13,9 +13,9 @@ import {
} from "../util";
import {SimpleError} from "../Utils/Errors";
import {ErrorWithCause} from "pony-cause";
import {ActionTypes} from "../Common/types";
import {RuleResultEntity} from "../Common/Entities/RuleResultEntity";
import {runCheckOptions} from "../Subreddit/Manager";
import {ActionTypes} from "../Common/Infrastructure/Atomic";
export class MessageAction extends Action {
content: string;

View File

@@ -5,9 +5,9 @@ import {activityIsRemoved} from "../Utils/SnoowrapUtils";
import {ActionProcessResult, RuleResult} from "../Common/interfaces";
import dayjs from "dayjs";
import {isSubmission} from "../util";
import {ActionTypes} from "../Common/types";
import {RuleResultEntity} from "../Common/Entities/RuleResultEntity";
import {runCheckOptions} from "../Subreddit/Manager";
import {ActionTypes} from "../Common/Infrastructure/Atomic";
export class RemoveAction extends Action {
spam: boolean;

View File

@@ -4,9 +4,9 @@ import Snoowrap, {Comment, Submission} from "snoowrap";
import {truncateStringToLength} from "../util";
import {renderContent} from "../Utils/SnoowrapUtils";
import {ActionProcessResult, RichContent, RuleResult} from "../Common/interfaces";
import {ActionTypes} from "../Common/types";
import {RuleResultEntity} from "../Common/Entities/RuleResultEntity";
import {runCheckOptions} from "../Subreddit/Manager";
import {ActionTypes} from "../Common/Infrastructure/Atomic";
// https://www.reddit.com/dev/api/oauth#POST_api_report
// denotes 100 characters maximum

View File

@@ -3,9 +3,9 @@ import Action, {ActionJson, ActionOptions} from "../index";
import {ActionProcessResult, RuleResult} from "../../Common/interfaces";
import Submission from 'snoowrap/dist/objects/Submission';
import Comment from 'snoowrap/dist/objects/Comment';
import {ActionTypes} from "../../Common/types";
import {RuleResultEntity} from "../../Common/Entities/RuleResultEntity";
import {runCheckOptions} from "../../Subreddit/Manager";
import {ActionTypes} from "../../Common/Infrastructure/Atomic";
export class FlairAction extends Action {
text: string;

View File

@@ -1,9 +1,9 @@
import Action, {ActionConfig, ActionJson, ActionOptions} from './index';
import {Comment, RedditUser, Submission} from 'snoowrap';
import {ActionProcessResult, RuleResult} from '../Common/interfaces';
import {ActionTypes} from "../Common/types";
import {RuleResultEntity} from "../Common/Entities/RuleResultEntity";
import {runCheckOptions} from "../Subreddit/Manager";
import {ActionTypes} from "../Common/Infrastructure/Atomic";
export class UserFlairAction extends Action {
text?: string;

View File

@@ -5,9 +5,9 @@ import {renderContent} from "../Utils/SnoowrapUtils";
import {UserNoteJson} from "../Subreddit/UserNotes";
import Submission from "snoowrap/dist/objects/Submission";
import {ActionProcessResult, RuleResult} from "../Common/interfaces";
import {ActionTypes} from "../Common/types";
import {RuleResultEntity} from "../Common/Entities/RuleResultEntity";
import {runCheckOptions} from "../Subreddit/Manager";
import {ActionTypes} from "../Common/Infrastructure/Atomic";
export class UserNoteAction extends Action {

View File

@@ -3,9 +3,7 @@ import {Logger} from "winston";
import {checkAuthorFilter, checkItemFilter, SubredditResources} from "../Subreddit/SubredditResources";
import {
ActionProcessResult,
ActionResult, AuthorOptions,
ChecksActivityState, FilterResult,
ObjectPremise, RuleResult, RunnableBaseJson, RunnableBaseOptions, StructuredRunnableBase
ActionResult, ObjectPremise, RuleResult
} from "../Common/interfaces";
import {mergeArr, normalizeCriteria} from "../util";
import LoggedError from "../Utils/LoggedError";
@@ -13,7 +11,6 @@ import {ExtendedSnoowrap} from '../Utils/SnoowrapClients';
import {ErrorWithCause} from "pony-cause";
import EventEmitter from "events";
import {runCheckOptions} from "../Subreddit/Manager";
import {ActionTypes} from "../Common/types";
import {ActionPremise} from "../Common/Entities/ActionPremise";
import objectHash from "object-hash";
import {RuleType} from "../Common/Entities/RuleType";
@@ -25,6 +22,9 @@ import {ActionResultEntity} from "../Common/Entities/ActionResultEntity";
import {FindOptionsWhere} from "typeorm/find-options/FindOptionsWhere";
import {RulePremise} from "../Common/Entities/RulePremise";
import {AuthorCriteria, TypedActivityState, TypedActivityStates} from "../Common/Infrastructure/Filters/FilterCriteria";
import {ActionTypes} from "../Common/Infrastructure/Atomic";
import {RunnableBaseJson, RunnableBaseOptions, StructuredRunnableBase} from "../Common/Infrastructure/Runnable";
import {AuthorOptions, ChecksActivityState, FilterResult} from "../Common/Infrastructure/Filters/FilterShapes";
export abstract class Action extends RunnableBase {
name?: string;

View File

@@ -5,7 +5,6 @@ import {Duration} from "dayjs/plugin/duration";
import EventEmitter from "events";
import {
BotInstanceConfig, DatabaseStatisticsOperatorConfig,
FilterCriteriaDefaults,
LogInfo,
PAUSED,
RUNNING,
@@ -41,6 +40,7 @@ import {QueueRunState} from "../Common/Entities/EntityRunState/QueueRunState";
import {EventsRunState} from "../Common/Entities/EntityRunState/EventsRunState";
import {ManagerRunState} from "../Common/Entities/EntityRunState/ManagerRunState";
import {Invokee, PollOn} from "../Common/Infrastructure/Atomic";
import {FilterCriteriaDefaults} from "../Common/Infrastructure/Filters/FilterShapes";
class Bot {

View File

@@ -19,26 +19,18 @@ import {
import {
ActionResult,
CheckResult,
ChecksActivityState,
CheckSummary,
FilterResult,
JoinCondition,
NotificationEventPayload,
PostBehavior, PostBehaviorOptionConfig, PostBehaviorOptionConfigStrong, PostBehaviorStrong,
RuleResult,
RuleSetResult, RunnableBaseJson,
RunnableBaseOptions, StructuredRunnableBase,
UserResultCache
RuleSetResult, UserResultCache
} from "../Common/interfaces";
import * as RuleSchema from '../Schema/Rule.json';
import * as RuleSetSchema from '../Schema/RuleSet.json';
import * as ActionSchema from '../Schema/Action.json';
import {
ActionObjectJson,
RuleJson,
RuleObjectJson,
ActionJson as ActionTypeJson,
StructuredRuleSetObjectJson, StructuredRuleObjectJson, StructuredActionObjectJson
ActionJson as ActionTypeJson
} from "../Common/types";
import {checkAuthorFilter, checkItemFilter, SubredditResources} from "../Subreddit/SubredditResources";
import {AuthorCriteria, AuthorOptions} from '..';
@@ -63,7 +55,13 @@ import {
RecordOutputType,
recordOutputTypes
} from "../Common/Infrastructure/Atomic";
import {FilterOptions, MinimalOrFullFilter, MinimalOrFullFilterJson} from "../Common/Infrastructure/Filters/FilterShapes";
import {
ChecksActivityState,
FilterOptions,
FilterResult,
MinimalOrFullFilter,
MinimalOrFullFilterJson
} from "../Common/Infrastructure/Filters/FilterShapes";
import {
CommentState,
SubmissionState,
@@ -71,6 +69,9 @@ import {
TypedActivityStates
} from "../Common/Infrastructure/Filters/FilterCriteria";
import {ActivityType} from "../Common/Infrastructure/Reddit";
import {RunnableBaseJson, RunnableBaseOptions, StructuredRunnableBase} from "../Common/Infrastructure/Runnable";
import {RuleJson, StructuredRuleObjectJson, StructuredRuleSetObjectJson} from "../Common/Infrastructure/RuleShapes";
import {ActionObjectJson, StructuredActionObjectJson} from "../Common/Infrastructure/ActionShapes";
const checkLogName = truncateStringToLength(25);

View File

@@ -1,4 +1,4 @@
import {ConfigFormat} from "../types";
import {ConfigFormat} from "../Infrastructure/Atomic";
export interface ConfigDocumentInterface<DocumentType> {
format: ConfigFormat;

View File

@@ -0,0 +1,9 @@
import AbstractConfigDocument from "./AbstractConfigDocument";
import {OperatorJsonConfig} from "../interfaces";
import {Document as YamlDocument} from "yaml";
export interface ConfigToObjectOptions {
location?: string,
jsonDocFunc?: (content: string, location?: string) => AbstractConfigDocument<OperatorJsonConfig>,
yamlDocFunc?: (content: string, location?: string) => AbstractConfigDocument<YamlDocument>
}

View File

@@ -0,0 +1,62 @@
import {ConfigFormat} from "../Infrastructure/Atomic";
import {Document as YamlDocument} from "yaml";
import {likelyJson5} from "../../util";
import JsonConfigDocument from "./JsonConfigDocument";
import YamlConfigDocument from "./YamlConfigDocument";
import {SimpleError} from "../../Utils/Errors";
import {ConfigDocumentInterface} from "./AbstractConfigDocument";
import {ConfigToObjectOptions} from "./ConfigToObjectOptions";
export const parseFromJsonOrYamlToObject = (content: string, options?: ConfigToObjectOptions): [ConfigFormat, ConfigDocumentInterface<YamlDocument | object>?, Error?, Error?] => {
let obj;
let configFormat: ConfigFormat = 'yaml';
let jsonErr,
yamlErr;
const likelyType = likelyJson5(content) ? 'json' : 'yaml';
const {
location,
jsonDocFunc = (content: string, location?: string) => new JsonConfigDocument(content, location),
yamlDocFunc = (content: string, location?: string) => new YamlConfigDocument(content, location),
} = options || {};
try {
const jsonObj = jsonDocFunc(content, location);
const output = jsonObj.toJS();
const oType = output === null ? 'null' : typeof output;
if (oType !== 'object') {
jsonErr = new SimpleError(`Parsing as json produced data of type '${oType}' (expected 'object')`);
obj = undefined;
} else {
obj = jsonObj;
configFormat = 'json';
}
} catch (err: any) {
jsonErr = err;
}
try {
const yamlObj = yamlDocFunc(content, location)
const output = yamlObj.toJS();
const oType = output === null ? 'null' : typeof output;
if (oType !== 'object') {
yamlErr = new SimpleError(`Parsing as yaml produced data of type '${oType}' (expected 'object')`);
obj = undefined;
} else if (obj === undefined && (likelyType !== 'json' || yamlObj.parsed.errors.length === 0)) {
configFormat = 'yaml';
if (yamlObj.parsed.errors.length !== 0) {
yamlErr = new Error(yamlObj.parsed.errors.join('\n'))
} else {
obj = yamlObj;
}
}
} catch (err: any) {
yamlErr = err;
}
if (obj === undefined) {
configFormat = likelyType;
}
return [configFormat, obj, jsonErr, yamlErr];
}

View File

@@ -1,8 +1,8 @@
import AbstractConfigDocument from "./AbstractConfigDocument";
import {stringify, parse} from 'comment-json';
import JSON5 from 'json5';
import {ConfigFormat} from "../types";
import {OperatorJsonConfig} from "../interfaces";
import {ConfigFormat} from "../Infrastructure/Atomic";
class JsonConfigDocument extends AbstractConfigDocument<OperatorJsonConfig> {

View File

@@ -1,6 +1,6 @@
import AbstractConfigDocument from "./AbstractConfigDocument";
import {Document, parseDocument} from 'yaml';
import {ConfigFormat} from "../types";
import {ConfigFormat} from "../Infrastructure/Atomic";
class YamlConfigDocument extends AbstractConfigDocument<Document> {

View File

@@ -10,13 +10,14 @@ import {
} from "typeorm";
import {ActionResultEntity} from "./ActionResultEntity";
import objectHash from "object-hash";
import {AuthorOptions, ItemOptions, ObjectPremise} from "../interfaces";
import {ObjectPremise} from "../interfaces";
import {TimeAwareAndUpdatedBaseEntity} from "./Base/TimeAwareAndUpdatedBaseEntity";
import {TimeAwareRandomBaseEntity} from "./Base/TimeAwareRandomBaseEntity";
import {ActionType} from "./ActionType";
import {ManagerEntity} from "./ManagerEntity";
import {capitalize} from "lodash";
import {TypedActivityStates} from "../Infrastructure/Filters/FilterCriteria";
import {AuthorOptions, ItemOptions} from "../Infrastructure/Filters/FilterShapes";
export interface ActionPremiseOptions {
kind: ActionType

View File

@@ -3,13 +3,13 @@ import {ActivityStateFilterResult} from "./FilterCriteria/ActivityStateFilterRes
import {AuthorFilterResult} from "./FilterCriteria/AuthorFilterResult";
import {CheckResultEntity} from "./CheckResultEntity";
import {ActionPremise} from "./ActionPremise";
import {FilterResult, FilterResult as IFilterResult} from "../interfaces";
import Submission from "snoowrap/dist/objects/Submission";
import Comment from "snoowrap/dist/objects/Comment";
import RedditUser from "snoowrap/dist/objects/RedditUser";
import {RandomIdBaseEntity} from "./Base/RandomIdBaseEntity";
import {TimeAwareRandomBaseEntity} from "./Base/TimeAwareRandomBaseEntity";
import {AuthorCriteria, TypedActivityState} from "../Infrastructure/Filters/FilterCriteria";
import {FilterResult as IFilterResult, FilterResult} from "../Infrastructure/Filters/FilterShapes";
export interface ActionResultEntityOptions {
run: boolean

View File

@@ -1,5 +1,5 @@
import {Entity, PrimaryColumn, Column, PrimaryGeneratedColumn} from "typeorm";
import {ActionTypes} from "../types";
import {ActionTypes} from "../Infrastructure/Atomic";
@Entity()
export class ActionType {

View File

@@ -15,8 +15,6 @@ import {RunResultEntity} from "./RunResultEntity";
import {RuleResultEntity} from "./RuleResultEntity";
import {ActionResultEntity} from "./ActionResultEntity";
import {
FilterResult as IFilterResult,
FilterResult,
RuleSetResult
} from "../interfaces";
import {RandomIdBaseEntity} from "./Base/RandomIdBaseEntity";
@@ -27,6 +25,7 @@ import {CheckToRuleSetResultEntity} from "./RunnableAssociation/CheckToRuleSetRe
import {isRuleSetResult} from "../../util";
import {JoinOperands, RecordOutputType} from "../Infrastructure/Atomic";
import {AuthorCriteria, TypedActivityState} from "../Infrastructure/Filters/FilterCriteria";
import {FilterResult, FilterResult as IFilterResult} from "../Infrastructure/Filters/FilterShapes";
export interface CheckResultEntityOptions {
triggered: boolean

View File

@@ -1,8 +1,8 @@
import {ChildEntity, ManyToOne} from "typeorm";
import {FilterCriteriaResult} from "./FilterCriteriaResult";
import {FilterCriteriaResult as IFilterCriteriaResult} from "../../interfaces";
import {ActivityStateFilterCriteria} from "./ActivityStateFilterCriteria";
import {TypedActivityState} from "../../Infrastructure/Filters/FilterCriteria";
import {FilterCriteriaResult as IFilterCriteriaResult} from "../../Infrastructure/Filters/FilterShapes";
@ChildEntity()
export class ActivityStateFilterCriteriaResult extends FilterCriteriaResult<TypedActivityState> {

View File

@@ -1,8 +1,11 @@
import {ChildEntity, OneToMany} from "typeorm";
import {FilterResult} from "./FilterResult";
import {FilterCriteriaResult as IFilterCriteriaResult, FilterResult as IFilterResult} from "../../interfaces";
import {ActivityStateFilterCriteriaResult} from "./ActivityStateFilterCriteriaResult";
import {TypedActivityState} from "../../Infrastructure/Filters/FilterCriteria";
import {
FilterCriteriaResult as IFilterCriteriaResult,
FilterResult as IFilterResult
} from "../../Infrastructure/Filters/FilterShapes";
@ChildEntity()
export class ActivityStateFilterResult extends FilterResult<TypedActivityState> {

View File

@@ -1,11 +1,11 @@
import {ChildEntity, ManyToOne, OneToMany} from "typeorm";
import {FilterResult} from "./FilterResult";
import {
FilterCriteriaResult as IFilterCriteriaResult,
FilterResult as IFilterResult,
} from "../../interfaces";
import {AuthorFilterCriteriaResult} from "./FilterCriteriaResult";
import {AuthorCriteria} from "../../Infrastructure/Filters/FilterCriteria";
import {
FilterCriteriaResult as IFilterCriteriaResult,
FilterResult as IFilterResult
} from "../../Infrastructure/Filters/FilterShapes";
@ChildEntity()
export class AuthorFilterResult extends FilterResult<AuthorCriteria> {

View File

@@ -1,12 +1,12 @@
import {ChildEntity, Column, Entity, ManyToOne, TableInheritance} from "typeorm";
import {
FilterCriteriaPropertyResult,
FilterCriteriaResult as IFilterCriteriaResult
} from "../../interfaces";
import {FilterResult} from "./FilterResult";
import {RandomIdBaseEntity} from "../Base/RandomIdBaseEntity";
import {AuthorFilterCriteria} from "./AuthorFilterCriteria";
import {AuthorCriteria} from "../../Infrastructure/Filters/FilterCriteria";
import {
FilterCriteriaPropertyResult,
FilterCriteriaResult as IFilterCriteriaResult
} from "../../Infrastructure/Filters/FilterShapes";
export interface FilterCriteriaResultOptions<T> {
behavior: string

View File

@@ -1,7 +1,7 @@
import {Entity, Column, PrimaryColumn, OneToMany, PrimaryGeneratedColumn, ManyToOne, TableInheritance} from "typeorm";
import {FilterCriteriaResult as IFilterCriteriaResult} from "../../interfaces";
import {RandomIdBaseEntity} from "../Base/RandomIdBaseEntity";
import {JoinOperands} from "../../Infrastructure/Atomic";
import {FilterCriteriaResult as IFilterCriteriaResult} from "../../Infrastructure/Filters/FilterShapes";
//import {FilterCriteriaResult} from "./FilterCriteriaResult";
export interface FilterResultOptions {

View File

@@ -11,7 +11,6 @@ import {
} from "typeorm";
import {RuleResultEntity} from "./RuleResultEntity";
import {
AuthorOptions, ItemOptions,
ObjectPremise
} from "../interfaces";
import objectHash from "object-hash";
@@ -21,6 +20,7 @@ import {RuleType} from "./RuleType";
import {ManagerEntity} from "./ManagerEntity";
import {capitalize} from "lodash";
import {TypedActivityStates} from "../Infrastructure/Filters/FilterCriteria";
import {AuthorOptions, ItemOptions} from "../Infrastructure/Filters/FilterShapes";
export interface RulePremiseOptions {
kind: RuleType

View File

@@ -12,11 +12,11 @@ import {RulePremise} from "./RulePremise";
import {CheckResultEntity} from "./CheckResultEntity";
import {ActivityStateFilterResult} from "./FilterCriteria/ActivityStateFilterResult";
import {AuthorFilterResult} from "./FilterCriteria/AuthorFilterResult";
import {FilterResult as IFilterResult, FilterResult} from "../interfaces";
import {RandomIdBaseEntity} from "./Base/RandomIdBaseEntity";
import {TimeAwareRandomBaseEntity} from "./Base/TimeAwareRandomBaseEntity";
import {RuleSetResultEntity} from "./RuleSetResultEntity";
import {AuthorCriteria, TypedActivityState} from "../Infrastructure/Filters/FilterCriteria";
import {FilterResult, FilterResult as IFilterResult} from "../Infrastructure/Filters/FilterShapes";
export interface RuleResultEntityOptions {
triggered?: boolean

View File

@@ -12,16 +12,13 @@ import {RulePremise} from "./RulePremise";
import {CheckResultEntity} from "./CheckResultEntity";
import {ActivityStateFilterResult} from "./FilterCriteria/ActivityStateFilterResult";
import {AuthorFilterResult} from "./FilterCriteria/AuthorFilterResult";
import {
FilterResult as IFilterResult,
FilterResult
} from "../interfaces";
import {RandomIdBaseEntity} from "./Base/RandomIdBaseEntity";
import {TimeAwareRandomBaseEntity} from "./Base/TimeAwareRandomBaseEntity";
import {RuleResultEntity} from "./RuleResultEntity";
import {RuleSetToRuleResultEntity} from "./RunnableAssociation/RuleSetToRuleResultEntity";
import {JoinOperands} from "../Infrastructure/Atomic";
import {AuthorCriteria, TypedActivityState} from "../Infrastructure/Filters/FilterCriteria";
import {FilterResult, FilterResult as IFilterResult} from "../Infrastructure/Filters/FilterShapes";
export interface RuleSetResultEntityOptions {
triggered: boolean

View File

@@ -16,9 +16,9 @@ import {AuthorFilterResult} from "./FilterCriteria/AuthorFilterResult";
import {CheckResultEntity} from "./CheckResultEntity";
import {RuleResultEntity} from "./RuleResultEntity";
import {CMEvent} from "./CMEvent";
import {FilterResult as IFilterResult} from "../interfaces";
import {TimeAwareRandomBaseEntity} from "./Base/TimeAwareRandomBaseEntity";
import {AuthorCriteria, TypedActivityState} from "../Infrastructure/Filters/FilterCriteria";
import {FilterResult as IFilterResult} from "../Infrastructure/Filters/FilterShapes";
//import {RunToCheckResultEntity} from "./RunnableAssociation/RunToCheckResultEntity";
export interface RunResultEntityOptions {

View File

@@ -0,0 +1,5 @@
import {StructuredRunnableBase} from "./Runnable";
import {ActionJson} from "../types";
export type ActionObjectJson = Exclude<ActionJson, string>;
export type StructuredActionObjectJson = Omit<ActionObjectJson, 'authorIs' | 'itemIs'> & StructuredRunnableBase

View File

@@ -12,6 +12,7 @@
*
* @pattern ^\s*(>|>=|<|<=)\s*(\d+)\s*(days|weeks|months|years|hours|minutes|seconds|milliseconds)\s*$
* */
export type DurationComparor = string;
/**
@@ -170,3 +171,18 @@ export type ActivitySourceTypes = 'poll' | 'dispatch' | 'user'; // TODO
* */
export type ActivitySource = NonDispatchActivitySource | DispatchSource;
export type ConfigFormat = 'json' | 'yaml';
export type ActionTypes =
'comment'
| 'lock'
| 'remove'
| 'report'
| 'approve'
| 'ban'
| 'flair'
| 'usernote'
| 'message'
| 'userflair'
| 'dispatch'
| 'cancelDispatch'
| 'contributor';

View File

@@ -0,0 +1,5 @@
import {SafeDictionary} from "ts-essentials";
import {AuthorCriteria} from "./FilterCriteria";
import {FilterCriteriaPropertyResult} from "./FilterShapes";
export type AuthorCritPropHelper = SafeDictionary<FilterCriteriaPropertyResult<AuthorCriteria>, keyof AuthorCriteria>;

View File

@@ -359,3 +359,4 @@ export interface CommentState extends ActivityState {
export type TypedActivityState = SubmissionState | CommentState;
export type TypedActivityStates = TypedActivityState[];
export type RequiredAuthorCrit = Required<AuthorCriteria>;

View File

@@ -1,5 +1,12 @@
import {JoinOperands} from "../Atomic";
import {ActivityState, AuthorCriteria, SubredditCriteria, TypedActivityState} from "./FilterCriteria";
import {FilterBehavior, JoinOperands} from "../Atomic";
import {
ActivityState,
AuthorCriteria,
FilterCriteriaDefaultBehavior,
SubredditCriteria,
TypedActivityState,
TypedActivityStates
} from "./FilterCriteria";
export interface NamedCriteria<T extends AuthorCriteria | TypedActivityState | SubredditCriteria | ActivityState> {
name?: string
@@ -60,3 +67,71 @@ export interface FilterOptions<T> extends FilterOptionsConfig<T> {
export type MinimalOrFullFilter<T> = MaybeAnonymousCriteria<T>[] | FilterOptions<T>
export type MinimalOrFullMaybeAnonymousFilter<T> = MaybeAnonymousCriteria<T>[] | FilterOptionsConfig<T>
export type MinimalOrFullFilterJson<T> = MaybeAnonymousOrStringCriteria<T>[] | FilterOptionsJson<T>
export type StructuredFilter<T> = Omit<T, 'authorIs' | 'itemIs'> & {
itemIs?: MinimalOrFullFilter<TypedActivityState>
authorIs?: MinimalOrFullFilter<AuthorCriteria>
}
/**
* 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}]}]
* */
export interface AuthorOptions extends FilterOptions<AuthorCriteria> {
}
/**
* A list of criteria to test the state of the `Activity` against before running. If criteria fails then this process is skipped.
*
* * @examples [{"include": [{"over_18": true, "removed': false}]}]
* */
export interface ItemOptions extends FilterOptions<TypedActivityState> {
}
export interface FilterCriteriaDefaults extends Omit<FilterCriteriaDefaultsJson, 'itemIs' | 'authorIs'> {
itemIs?: MinimalOrFullFilter<TypedActivityState>
authorIs?: MinimalOrFullFilter<AuthorCriteria>
}
export interface FilterCriteriaDefaultsJson {
itemIs?: MinimalOrFullFilterJson<TypedActivityState>
/**
* Determine how itemIs defaults behave when itemIs is present on the check
*
* * merge => adds defaults to check's itemIs
* * replace => check itemIs will replace defaults (no defaults used)
* */
itemIsBehavior?: FilterCriteriaDefaultBehavior
/**
* Determine how authorIs defaults behave when authorIs is present on the check
*
* * merge => merges defaults with check's authorIs
* * replace => check authorIs will replace defaults (no defaults used)
* */
authorIs?: MinimalOrFullFilterJson<AuthorCriteria>
authorIsBehavior?: FilterCriteriaDefaultBehavior
}
export interface FilterCriteriaPropertyResult<T> {
property: keyof T
found?: string | boolean | number | null | FilterResult<any>
passed?: null | boolean
reason?: string
behavior: FilterBehavior
}
export interface FilterCriteriaResult<T> {
behavior: FilterBehavior
criteria: NamedCriteria<T>//AuthorCriteria | TypedActivityStates
propertyResults: FilterCriteriaPropertyResult<T>[]
passed: boolean
}
export interface FilterResult<T> {
criteriaResults: FilterCriteriaResult<T>[]
join: JoinOperands
passed: boolean
}
export interface ChecksActivityState {
itemIs?: TypedActivityStates
}

View File

@@ -0,0 +1,10 @@
import {StructuredRunnableBase} from "./Runnable";
import {RuleSetObjectJson} from "../../Rule/RuleSet";
import {RuleObjectJsonTypes} from "../types";
export type RuleJson = RuleObjectJsonTypes | string;
export type RuleObjectJson = Exclude<RuleJson, string>
export type StructuredRuleObjectJson = Omit<RuleObjectJson, 'authorIs' | 'itemIs'> & StructuredRunnableBase
export type StructuredRuleSetObjectJson = Omit<RuleSetObjectJson, 'rules'> & {
rules: StructuredRuleObjectJson[]
}

View File

@@ -0,0 +1,33 @@
import {MinimalOrFullFilter, MinimalOrFullFilterJson} from "./Filters/FilterShapes";
import {AuthorCriteria, TypedActivityState} from "./Filters/FilterCriteria";
import {Logger} from "winston";
import {SubredditResources} from "../../Subreddit/SubredditResources";
export interface RunnableBaseOptions extends Omit<RunnableBaseJson, 'itemIs' | 'authorIs'> {
logger: Logger;
resources: SubredditResources
itemIs?: MinimalOrFullFilter<TypedActivityState>
authorIs?: MinimalOrFullFilter<AuthorCriteria>
}
export interface StructuredRunnableBase {
itemIs?: MinimalOrFullFilter<TypedActivityState>
authorIs?: MinimalOrFullFilter<AuthorCriteria>
}
export interface RunnableBaseJson {
/**
* A list of criteria to test the state of the `Activity` against before running the check.
*
* If any set of criteria passes the Check will be run. If the criteria fails then the Check will fail.
*
* * @examples [[{"over_18": true, "removed': false}]]
*
* */
itemIs?: MinimalOrFullFilterJson<TypedActivityState>
/**
* If present then these Author criteria are checked before running the Check. If criteria fails then the Check will fail.
* */
authorIs?: MinimalOrFullFilterJson<AuthorCriteria>
}

View File

@@ -1,12 +1,11 @@
import {Logger} from "winston";
import {
AuthorOptions, FilterResult, ItemOptions, RunnableBaseOptions
} from "./interfaces";
import {checkAuthorFilter, checkItemFilter, SubredditResources} from "../Subreddit/SubredditResources";
import {Comment, Submission} from "snoowrap";
import {runCheckOptions} from "../Subreddit/Manager";
import {buildFilter} from "../util";
import {AuthorCriteria, TypedActivityState} from "./Infrastructure/Filters/FilterCriteria";
import {RunnableBaseOptions} from "./Infrastructure/Runnable";
import {AuthorOptions, FilterResult, ItemOptions} from "./Infrastructure/Filters/FilterShapes";
export abstract class RunnableBase {

View File

@@ -1,5 +1,6 @@
import {FilterCriteriaDefaults, HistoricalStatsDisplay} from "./interfaces";
import {HistoricalStatsDisplay} from "./interfaces";
import path from "path";
import {FilterCriteriaDefaults} from "./Infrastructure/Filters/FilterShapes";
export const cacheOptDefaults = {ttl: 60, max: 500, checkPeriod: 600};
export const cacheTTLDefaults = {authorTTL: 60, userNotesTTL: 300, wikiTTL: 300, submissionTTL: 60, commentTTL: 60, filterCriteriaTTL: 60, subredditTTL: 600, selfTTL: 60};

View File

@@ -9,23 +9,18 @@ import {JsonOperatorConfigDocument, YamlOperatorConfigDocument} from "./Config/O
import {CommentCheckJson, SubmissionCheckJson} from "../Check";
import {SafeDictionary} from "ts-essentials";
import {RuleResultEntity} from "./Entities/RuleResultEntity";
import {Logger} from "winston";
import {SubredditResources} from "../Subreddit/SubredditResources";
import {Dayjs} from "dayjs";
import {
AuthorCriteria,
CommentState,
FilterCriteriaDefaultBehavior,
SubmissionState,
TypedActivityState,
TypedActivityStates
TypedActivityState
} from "./Infrastructure/Filters/FilterCriteria";
import {
ActivitySourceTypes,
CacheProvider,
DurationVal,
EventRetentionPolicyRange,
FilterBehavior,
JoinOperands,
NonDispatchActivitySource,
NotificationEventType,
@@ -40,10 +35,12 @@ import {
StringOperator
} from "./Infrastructure/Atomic";
import {
FilterOptions,
MinimalOrFullFilter,
MinimalOrFullFilterJson,
NamedCriteria
AuthorOptions,
FilterCriteriaDefaults,
FilterCriteriaDefaultsJson,
FilterCriteriaPropertyResult,
FilterResult,
ItemOptions
} from "./Infrastructure/Filters/FilterShapes";
import {LoggingOptions, LogLevel, StrongLoggingOptions} from "./Infrastructure/Logging";
import {DatabaseConfig, DatabaseDriver, DatabaseDriverConfig, DatabaseDriverType} from "./Infrastructure/Database";
@@ -677,10 +674,6 @@ export interface ThresholdCriteria {
condition: StringOperator
}
export interface ChecksActivityState {
itemIs?: TypedActivityStates
}
export interface DomainInfo {
display: string,
domain: string,
@@ -1024,21 +1017,6 @@ export interface SnoowrapOptions {
timeoutCodes?: string[]
}
/**
* 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}]}]
* */
export interface AuthorOptions extends FilterOptions<AuthorCriteria> {
}
/**
* A list of criteria to test the state of the `Activity` against before running. If criteria fails then this process is skipped.
*
* * @examples [{"include": [{"over_18": true, "removed': false}]}]
* */
export interface ItemOptions extends FilterOptions<TypedActivityState> {
}
// /**
// * A list of criteria to test the state of the `Activity` against before running. If criteria fails then this process is skipped.
// *
@@ -1046,30 +1024,6 @@ export interface ItemOptions extends FilterOptions<TypedActivityState> {
// * */
// export type ItemOptions = FilterOptions<SubmissionState> | FilterOptions<CommentState>
export interface FilterCriteriaDefaults extends Omit<FilterCriteriaDefaultsJson, 'itemIs' | 'authorIs'> {
itemIs?: MinimalOrFullFilter<TypedActivityState>
authorIs?: MinimalOrFullFilter<AuthorCriteria>
}
export interface FilterCriteriaDefaultsJson {
itemIs?: MinimalOrFullFilterJson<TypedActivityState>
/**
* Determine how itemIs defaults behave when itemIs is present on the check
*
* * merge => adds defaults to check's itemIs
* * replace => check itemIs will replace defaults (no defaults used)
* */
itemIsBehavior?: FilterCriteriaDefaultBehavior
/**
* Determine how authorIs defaults behave when authorIs is present on the check
*
* * merge => merges defaults with check's authorIs
* * replace => check authorIs will replace defaults (no defaults used)
* */
authorIs?: MinimalOrFullFilterJson<AuthorCriteria>
authorIsBehavior?: FilterCriteriaDefaultBehavior
}
export interface SubredditOverrides {
name: string
@@ -1881,27 +1835,6 @@ export interface DatabaseMigrationOptions {
continueOnAutomatedBackup?: boolean
}
export interface FilterCriteriaPropertyResult<T> {
property: keyof T
found?: string | boolean | number | null | FilterResult<any>
passed?: null | boolean
reason?: string
behavior: FilterBehavior
}
export interface FilterCriteriaResult<T> {
behavior: FilterBehavior
criteria: NamedCriteria<T>//AuthorCriteria | TypedActivityStates
propertyResults: FilterCriteriaPropertyResult<T>[]
passed: boolean
}
export interface FilterResult<T> {
criteriaResults: FilterCriteriaResult<T>[]
join: JoinOperands
passed: boolean
}
export interface TextTransformOptions {
/**
* A set of search-and-replace operations to perform on text values before performing a match. Transformations are performed in the order they are defined.
@@ -2032,37 +1965,3 @@ export interface ObjectPremise {
authorIs?: AuthorOptions
}
export interface RunnableBaseOptions extends Omit<RunnableBaseJson, 'itemIs' | 'authorIs'> {
logger: Logger;
resources: SubredditResources
itemIs?: MinimalOrFullFilter<TypedActivityState>
authorIs?: MinimalOrFullFilter<AuthorCriteria>
}
export interface StructuredRunnableBase {
itemIs?: MinimalOrFullFilter<TypedActivityState>
authorIs?: MinimalOrFullFilter<AuthorCriteria>
}
export type StructuredFilter<T> = Omit<T, 'authorIs' | 'itemIs'> & {
itemIs?: MinimalOrFullFilter<TypedActivityState>
authorIs?: MinimalOrFullFilter<AuthorCriteria>
}
export interface RunnableBaseJson {
/**
* A list of criteria to test the state of the `Activity` against before running the check.
*
* If any set of criteria passes the Check will be run. If the criteria fails then the Check will fail.
*
* * @examples [[{"over_18": true, "removed': false}]]
*
* */
itemIs?: MinimalOrFullFilterJson<TypedActivityState>
/**
* If present then these Author criteria are checked before running the Check. If criteria fails then the Check will fail.
* */
authorIs?: MinimalOrFullFilterJson<AuthorCriteria>
}

View File

@@ -17,35 +17,8 @@ import {MessageActionJson} from "../Action/MessageAction";
import {RepostRuleJSONConfig} from "../Rule/RepostRule";
import {DispatchActionJson} from "../Action/DispatchAction";
import {CancelDispatchActionJson} from "../Action/CancelDispatchAction";
import {SafeDictionary} from "ts-essentials";
import {FilterCriteriaPropertyResult, StructuredRunnableBase} from "./interfaces";
import {ContributorActionJson} from "../Action/ContributorAction";
import {RuleSetObjectJson} from "../Rule/RuleSet";
import {AuthorCriteria} from "./Infrastructure/Filters/FilterCriteria";
export type RuleObjectJsonTypes = RecentActivityRuleJSONConfig | RepeatActivityJSONConfig | AuthorRuleJSONConfig | AttributionJSONConfig | HistoryJSONConfig | RegexRuleJSONConfig | RepostRuleJSONConfig
export type RuleJson = RuleObjectJsonTypes | string;
export type RuleObjectJson = Exclude<RuleJson, string>
export type StructuredRuleObjectJson = Omit<RuleObjectJson, 'authorIs' | 'itemIs'> & StructuredRunnableBase
export type StructuredRuleSetObjectJson = Omit<RuleSetObjectJson, 'rules'> & {
rules: StructuredRuleObjectJson[]
}
export type ActionJson = CommentActionJson | FlairActionJson | ReportActionJson | LockActionJson | RemoveActionJson | ApproveActionJson | BanActionJson | UserNoteActionJson | MessageActionJson | UserFlairActionJson | DispatchActionJson | CancelDispatchActionJson | ContributorActionJson | string;
export type ActionObjectJson = Exclude<ActionJson, string>;
export type StructuredActionObjectJson = Omit<ActionObjectJson, 'authorIs' | 'itemIs'> & StructuredRunnableBase
// borrowed from https://github.com/jabacchetta/set-random-interval/blob/master/src/index.ts
export type SetRandomInterval = (
intervalFunction: () => void,
minDelay: number,
maxDelay: number,
) => { clear: () => void };
export type ConfigFormat = 'json' | 'yaml';
export type AuthorCritPropHelper = SafeDictionary<FilterCriteriaPropertyResult<AuthorCriteria>, keyof AuthorCriteria>;
export type RequiredAuthorCrit = Required<AuthorCriteria>;
export type ActionTypes = 'comment' | 'lock' | 'remove' | 'report' | 'approve' | 'ban' | 'flair' | 'usernote' | 'message' | 'userflair' | 'dispatch' | 'cancelDispatch' | 'contributor';

View File

@@ -6,7 +6,7 @@ import {
mergeArr, mergeFilters,
normalizeName,
overwriteMerge,
parseBool, parseFromJsonOrYamlToObject, randomId,
parseBool, randomId,
readConfigFile, removeFromSourceIfKeysExistsInDestination,
removeUndefinedKeys, resolvePathFromEnvWithRelative
} from "./util";
@@ -34,23 +34,13 @@ import {
RedditCredentials,
BotCredentialsJsonConfig,
BotCredentialsConfig,
FilterCriteriaDefaults,
OperatorFileConfig,
PostBehavior,
AuthorOptions,
RunnableBaseJson,
RunnableBaseOptions,
StructuredRunnableBase, FilterCriteriaDefaultsJson
PostBehavior
} from "./Common/interfaces";
import {isRuleSetJSON, RuleSetJson, RuleSetObjectJson} from "./Rule/RuleSet";
import deepEqual from "fast-deep-equal";
import {
ActionJson,
ActionObjectJson,
ConfigFormat,
RuleJson,
RuleObjectJson, StructuredActionObjectJson, StructuredRuleObjectJson,
StructuredRuleSetObjectJson
ActionJson
} from "./Common/types";
import {isActionJson} from "./Action";
import {getLogger, resolveLogDir} from "./Utils/loggerFactory";
@@ -78,17 +68,22 @@ import {
OperatorConfigDocumentInterface,
YamlOperatorConfigDocument
} from "./Common/Config/Operator";
import {ConfigDocumentInterface} from "./Common/Config/AbstractConfigDocument";
import {
ConfigDocumentInterface
} from "./Common/Config/AbstractConfigDocument";
import {Document as YamlDocument} from "yaml";
import {SimpleError} from "./Utils/Errors";
import {ErrorWithCause} from "pony-cause";
import {RunJson, RunStructuredJson} from "./Run";
import {AuthorRuleConfig} from "./Rule/AuthorRule";
import {
CacheProvider,
CacheProvider, ConfigFormat,
PollOn
} from "./Common/Infrastructure/Atomic";
import {
AuthorOptions,
FilterCriteriaDefaults,
FilterCriteriaDefaultsJson,
FilterOptionsJson,
MaybeAnonymousCriteria,
MaybeAnonymousOrStringCriteria, MinimalOrFullFilter, MinimalOrFullFilterJson, NamedCriteria
@@ -96,6 +91,15 @@ import {
import {AuthorCriteria, TypedActivityState, TypedActivityStates} from "./Common/Infrastructure/Filters/FilterCriteria";
import {StrongLoggingOptions} from "./Common/Infrastructure/Logging";
import {DatabaseDriver, DatabaseDriverConfig, DatabaseDriverType} from "./Common/Infrastructure/Database";
import {parseFromJsonOrYamlToObject} from "./Common/Config/ConfigUtil";
import {RunnableBaseJson, RunnableBaseOptions, StructuredRunnableBase} from "./Common/Infrastructure/Runnable";
import {
RuleJson,
RuleObjectJson,
StructuredRuleObjectJson,
StructuredRuleSetObjectJson
} from "./Common/Infrastructure/RuleShapes";
import {ActionObjectJson, StructuredActionObjectJson} from "./Common/Infrastructure/ActionShapes";
export interface ConfigBuilderOptions {
logger: Logger,

View File

@@ -3,10 +3,11 @@ import {Comment} from "snoowrap";
import Submission from "snoowrap/dist/objects/Submission";
import {checkAuthorFilter} from "../Subreddit/SubredditResources";
import {
AuthorOptions, RuleResult
RuleResult
} from "../Common/interfaces";
import {buildFilter, normalizeCriteria} from "../util";
import {
AuthorOptions,
MaybeAnonymousCriteria,
MaybeAnonymousOrStringCriteria,
NamedCriteria

View File

@@ -9,7 +9,7 @@ import RegexRule, {RegexRuleJSONConfig} from "./RegexRule";
import {SubredditResources} from "../Subreddit/SubredditResources";
import Snoowrap from "snoowrap";
import {RepostRule, RepostRuleJSONConfig} from "./RepostRule";
import {StructuredFilter} from "../Common/interfaces";
import {StructuredFilter} from "../Common/Infrastructure/Filters/FilterShapes";
export function ruleFactory
(config: StructuredRuleJson, logger: Logger, subredditName: string, resources: SubredditResources, client: Snoowrap): Rule {

View File

@@ -6,12 +6,12 @@ import {Logger} from "winston";
import {JoinCondition, RuleResult, RuleSetResult} from "../Common/interfaces";
import * as RuleSchema from '../Schema/Rule.json';
import Ajv from 'ajv';
import {RuleJson, RuleObjectJson, StructuredRuleObjectJson} from "../Common/types";
import {SubredditResources} from "../Subreddit/SubredditResources";
import {runCheckOptions} from "../Subreddit/Manager";
import {RuleResultEntity} from "../Common/Entities/RuleResultEntity";
import {RuleSetResultEntity} from "../Common/Entities/RuleSetResultEntity";
import {JoinOperands} from "../Common/Infrastructure/Atomic";
import {RuleJson, RuleObjectJson, StructuredRuleObjectJson} from "../Common/Infrastructure/RuleShapes";
export class RuleSet implements IRuleSet {
rules: Rule[] = [];

View File

@@ -4,12 +4,9 @@ import {Logger} from "winston";
import {findResultByPremise, mergeArr} from "../util";
import {checkAuthorFilter, checkItemFilter} from "../Subreddit/SubredditResources";
import {
AuthorOptions,
ChecksActivityState,
ObjectPremise,
ResultContext,
RuleResult as IRuleResult, RunnableBaseJson,
RunnableBaseOptions, StructuredRunnableBase
RuleResult as IRuleResult
} from "../Common/interfaces";
import {runCheckOptions} from "../Subreddit/Manager";
import {RuleResultEntity} from "../Common/Entities/RuleResultEntity";
@@ -18,6 +15,8 @@ import {RulePremise} from "../Common/Entities/RulePremise";
import {capitalize} from "lodash";
import {RunnableBase} from "../Common/RunnableBase";
import {FindOptionsWhere} from "typeorm/find-options/FindOptionsWhere";
import {RunnableBaseJson, RunnableBaseOptions, StructuredRunnableBase} from "../Common/Infrastructure/Runnable";
import {AuthorOptions, ChecksActivityState} from "../Common/Infrastructure/Filters/FilterShapes";
export interface RuleOptions extends RunnableBaseOptions {
name?: string;

View File

@@ -1,10 +1,9 @@
import {asStructuredCommentCheckJson, asStructuredSubmissionCheckJson, Check, CheckStructuredJson} from "../Check";
import {
ActionResult,
ActivityCheckJson, AuthorOptions, CheckResult, CheckSummary,
FilterCriteriaDefaults, FilterResult,
ActivityCheckJson, CheckResult, CheckSummary,
PostBehavior, PostBehaviorOption,
RuleResult, RunnableBaseJson, RunnableBaseOptions, RunResult, StructuredRunnableBase
RuleResult, RunResult
} from "../Common/interfaces";
import {SubmissionCheck} from "../Check/SubmissionCheck";
import {CommentCheck} from "../Check/CommentCheck";
@@ -24,6 +23,8 @@ import {RuleResultEntity} from "../Common/Entities/RuleResultEntity";
import {RunnableBase} from "../Common/RunnableBase";
import {AuthorCriteria, TypedActivityStates} from "../Common/Infrastructure/Filters/FilterCriteria";
import {PostBehaviorType} from "../Common/Infrastructure/Atomic";
import {RunnableBaseJson, RunnableBaseOptions, StructuredRunnableBase} from "../Common/Infrastructure/Runnable";
import {AuthorOptions, FilterCriteriaDefaults, FilterResult} from "../Common/Infrastructure/Filters/FilterShapes";
export class Run extends RunnableBase {
name: string;

View File

@@ -1382,21 +1382,24 @@
],
"items": {
"anyOf": [
{
"$ref": "#/definitions/FlairActionJson"
},
{
"$ref": "#/definitions/UserFlairActionJson"
},
{
"$ref": "#/definitions/CommentActionJson"
},
{
"$ref": "#/definitions/ReportActionJson"
},
{
"$ref": "#/definitions/LockActionJson"
},
{
"$ref": "#/definitions/RemoveActionJson"
},
{
"$ref": "#/definitions/ReportActionJson"
},
{
"$ref": "#/definitions/FlairActionJson"
},
{
"$ref": "#/definitions/UserNoteActionJson"
},
@@ -1409,9 +1412,6 @@
{
"$ref": "#/definitions/MessageActionJson"
},
{
"$ref": "#/definitions/UserFlairActionJson"
},
{
"$ref": "#/definitions/DispatchActionJson"
},
@@ -1562,6 +1562,9 @@
"description": "A list of Rules to run.\n\nIf `Rule` objects are triggered based on `condition` then `actions` will be performed.\n\nCan be `Rule`, `RuleSet`, or the `name` of any **named** `Rule` in your subreddit's configuration.\n\n**If `rules` is an empty array or not present then `actions` are performed immediately.**",
"items": {
"anyOf": [
{
"$ref": "#/definitions/RecentActivityRuleJSONConfig"
},
{
"$ref": "#/definitions/RepeatActivityJSONConfig"
},
@@ -1583,9 +1586,6 @@
{
"$ref": "#/definitions/RuleSetJson"
},
{
"$ref": "#/definitions/RecentActivityRuleJSONConfig"
},
{
"type": "string"
}
@@ -4835,6 +4835,9 @@
"description": "Can be `Rule` or the `name` of any **named** `Rule` in your subreddit's configuration",
"items": {
"anyOf": [
{
"$ref": "#/definitions/RecentActivityRuleJSONConfig"
},
{
"$ref": "#/definitions/RepeatActivityJSONConfig"
},
@@ -4853,9 +4856,6 @@
{
"$ref": "#/definitions/RepostRuleJSONConfig"
},
{
"$ref": "#/definitions/RecentActivityRuleJSONConfig"
},
{
"type": "string"
}
@@ -5117,21 +5117,24 @@
],
"items": {
"anyOf": [
{
"$ref": "#/definitions/FlairActionJson"
},
{
"$ref": "#/definitions/UserFlairActionJson"
},
{
"$ref": "#/definitions/CommentActionJson"
},
{
"$ref": "#/definitions/ReportActionJson"
},
{
"$ref": "#/definitions/LockActionJson"
},
{
"$ref": "#/definitions/RemoveActionJson"
},
{
"$ref": "#/definitions/ReportActionJson"
},
{
"$ref": "#/definitions/FlairActionJson"
},
{
"$ref": "#/definitions/UserNoteActionJson"
},
@@ -5144,9 +5147,6 @@
{
"$ref": "#/definitions/MessageActionJson"
},
{
"$ref": "#/definitions/UserFlairActionJson"
},
{
"$ref": "#/definitions/DispatchActionJson"
},
@@ -5297,6 +5297,9 @@
"description": "A list of Rules to run.\n\nIf `Rule` objects are triggered based on `condition` then `actions` will be performed.\n\nCan be `Rule`, `RuleSet`, or the `name` of any **named** `Rule` in your subreddit's configuration.\n\n**If `rules` is an empty array or not present then `actions` are performed immediately.**",
"items": {
"anyOf": [
{
"$ref": "#/definitions/RecentActivityRuleJSONConfig"
},
{
"$ref": "#/definitions/RepeatActivityJSONConfig"
},
@@ -5318,9 +5321,6 @@
{
"$ref": "#/definitions/RuleSetJson"
},
{
"$ref": "#/definitions/RecentActivityRuleJSONConfig"
},
{
"type": "string"
}

View File

@@ -1,6 +1,9 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"anyOf": [
{
"$ref": "#/definitions/RecentActivityRuleJSONConfig"
},
{
"$ref": "#/definitions/RepeatActivityJSONConfig"
},
@@ -19,9 +22,6 @@
{
"$ref": "#/definitions/RepostRuleJSONConfig"
},
{
"$ref": "#/definitions/RecentActivityRuleJSONConfig"
},
{
"type": "string"
}

View File

@@ -2987,6 +2987,9 @@
"description": "Can be `Rule` or the `name` of any **named** `Rule` in your subreddit's configuration",
"items": {
"anyOf": [
{
"$ref": "#/definitions/RecentActivityRuleJSONConfig"
},
{
"$ref": "#/definitions/RepeatActivityJSONConfig"
},
@@ -3005,9 +3008,6 @@
{
"$ref": "#/definitions/RepostRuleJSONConfig"
},
{
"$ref": "#/definitions/RecentActivityRuleJSONConfig"
},
{
"type": "string"
}

View File

@@ -11,7 +11,6 @@ import {
findLastIndex,
formatNumber, frequencyEqualOrLargerThanMin, getActivityAuthorName, isComment, isSubmission, likelyJson5,
mergeArr, normalizeName,
parseFromJsonOrYamlToObject,
parseRedditEntity,
pollingInfo,
resultsSummary,
@@ -28,7 +27,6 @@ import {
CheckSummary,
DEFAULT_POLLING_INTERVAL,
DEFAULT_POLLING_LIMIT,
FilterCriteriaDefaults,
LogInfo,
ManagerOptions,
ManagerStateChangeOption,
@@ -98,6 +96,8 @@ import {
recordOutputTypes,
RunState
} from "../Common/Infrastructure/Atomic";
import {parseFromJsonOrYamlToObject} from "../Common/Config/ConfigUtil";
import {FilterCriteriaDefaults} from "../Common/Infrastructure/Filters/FilterShapes";
export interface RunningState {
state: RunState,

View File

@@ -73,15 +73,10 @@ import {
UserResultCache,
ActionedEvent,
ThirdPartyCredentialsJsonConfig,
FilterCriteriaResult,
FilterResult,
RequiredItemCrit,
ItemCritPropHelper,
ActivityDispatch,
FilterCriteriaPropertyResult,
HistoricalStatsDisplay,
AuthorOptions,
ItemOptions
HistoricalStatsDisplay
} from "../Common/interfaces";
import UserNotes from "./UserNotes";
import Mustache from "mustache";
@@ -103,7 +98,6 @@ import globrex from 'globrex';
import {runMigrations} from "../Common/Migrations/CacheMigrationUtils";
import {isStatusError, MaybeSeriousErrorWithCause, SimpleError} from "../Utils/Errors";
import {ErrorWithCause} from "pony-cause";
import {AuthorCritPropHelper, RequiredAuthorCrit} from "../Common/types";
import {ManagerEntity} from "../Common/Entities/ManagerEntity";
import {Bot} from "../Common/Entities/Bot";
import {DispatchedEntity} from "../Common/Entities/DispatchedEntity";
@@ -117,7 +111,7 @@ import {RuleSetResultEntity} from "../Common/Entities/RuleSetResultEntity";
import {RulePremise} from "../Common/Entities/RulePremise";
import cloneDeep from "lodash/cloneDeep";
import {
AuthorCriteria, CommentState,
AuthorCriteria, CommentState, RequiredAuthorCrit,
StrongSubredditCriteria, SubmissionState,
SubredditCriteria, TypedActivityState, TypedActivityStates,
UserNoteCriteria
@@ -129,7 +123,13 @@ import {
ModeratorNameCriteria, statFrequencies, StatisticFrequency,
StatisticFrequencyOption
} from "../Common/Infrastructure/Atomic";
import {NamedCriteria} from "../Common/Infrastructure/Filters/FilterShapes";
import {
AuthorOptions, FilterCriteriaPropertyResult,
FilterCriteriaResult,
FilterResult,
ItemOptions,
NamedCriteria
} from "../Common/Infrastructure/Filters/FilterShapes";
import {
ActivityWindowCriteria,
HistoryFiltersOptions,
@@ -143,6 +143,7 @@ import {
CachedFetchedActivitiesResult, FetchedActivitiesResult,
SnoowrapActivity
} from "../Common/Infrastructure/Reddit";
import {AuthorCritPropHelper} from "../Common/Infrastructure/Filters/AuthorCritPropHelper";
export const DEFAULT_FOOTER = '\r\n*****\r\nThis action was performed by [a bot.]({{botLink}}) Mention a moderator or [send a modmail]({{modmailLink}}) if you any ideas, questions, or concerns about this action.';

View File

@@ -237,6 +237,6 @@ export {FormattedRuleResult} from "./Common/interfaces";
export {RuleResult} from "./Common/interfaces";
export {ResultContext} from "./Common/interfaces";
export {isRuleSetResult} from "./util";
export {AuthorOptions} from "./Common/interfaces";
export {UserNoteCriteria} from "./Common/Infrastructure/Filters/FilterCriteria";
export {AuthorCriteria} from "./Common/Infrastructure/Filters/FilterCriteria";
export {AuthorOptions} from "./Common/Infrastructure/Filters/FilterShapes";

View File

@@ -13,18 +13,11 @@ import {
ActionResult,
ActivityDispatch,
ActivityDispatchConfig,
AuthorOptions,
CacheOptions,
CheckSummary,
FilterCriteriaDefaults,
FilterCriteriaPropertyResult,
FilterCriteriaResult,
FilterResult,
ImageComparisonResult,
ItemCritPropHelper,
ItemOptions,
LogInfo,
OperatorJsonConfig,
PollingOptionsStrong,
PostBehaviorOptionConfig,
RegExResult,
@@ -34,12 +27,10 @@ import {
ResourceStats,
RuleResult,
RuleSetResult,
RunnableBaseJson,
RunResult,
SearchAndReplaceRegExp,
StringComparisonOptions
} from "./Common/interfaces";
import {Document as YamlDocument} from 'yaml'
import InvalidRegexError from "./Utils/InvalidRegexError";
import {accessSync, constants, promises} from "fs";
import {cacheOptDefaults, VERSION} from "./Common/defaults";
@@ -54,40 +45,48 @@ import fetch from "node-fetch";
import ImageData from "./Common/ImageData";
import {Sharp, SharpOptions} from "sharp";
import {ErrorWithCause, stackWithCauses} from "pony-cause";
import {ConfigFormat} from "./Common/types";
import stringSimilarity from 'string-similarity';
import calculateCosineSimilarity from "./Utils/StringMatching/CosineSimilarity";
import levenSimilarity from "./Utils/StringMatching/levenSimilarity";
import {isRateLimitError, isRequestError, isScopeError, isStatusError, SimpleError} from "./Utils/Errors";
import JsonConfigDocument from "./Common/Config/JsonConfigDocument";
import YamlConfigDocument from "./Common/Config/YamlConfigDocument";
import AbstractConfigDocument, {ConfigDocumentInterface} from "./Common/Config/AbstractConfigDocument";
import merge from "deepmerge";
import {RulePremise} from "./Common/Entities/RulePremise";
import {RuleResultEntity as RuleResultEntity} from "./Common/Entities/RuleResultEntity";
import {nanoid} from "nanoid";
import {
ActivityState,
AuthorCriteria, authorCriteriaProperties, CommentState, defaultStrongSubredditCriteriaOptions,
StrongSubredditCriteria, SubmissionState,
SubredditCriteria, TypedActivityState, TypedActivityStates,
AuthorCriteria,
authorCriteriaProperties,
CommentState,
defaultStrongSubredditCriteriaOptions,
StrongSubredditCriteria,
SubmissionState,
SubredditCriteria,
TypedActivityState,
UserNoteCriteria
} from "./Common/Infrastructure/Filters/FilterCriteria";
import {
ActivitySource,
ActivitySourceTypes,
CacheProvider,
DurationVal, RedditEntity, RedditEntityType,
statFrequencies, StatisticFrequency,
CacheProvider, ConfigFormat,
DurationVal,
RedditEntity,
RedditEntityType,
statFrequencies,
StatisticFrequency,
StatisticFrequencyOption,
StringOperator
} from "./Common/Infrastructure/Atomic";
import {DurationComparison, GenericComparison} from "./Common/Infrastructure/Comparisons";
import {
FilterOptions, FilterOptionsJson,
AuthorOptions,
FilterCriteriaDefaults, FilterCriteriaPropertyResult, FilterCriteriaResult,
FilterOptions,
FilterOptionsJson, FilterResult, ItemOptions,
MaybeAnonymousCriteria,
MaybeAnonymousOrStringCriteria,
MinimalOrFullFilter, MinimalOrFullMaybeAnonymousFilter,
MinimalOrFullFilter,
MinimalOrFullMaybeAnonymousFilter,
NamedCriteria
} from "./Common/Infrastructure/Filters/FilterShapes";
import {
@@ -95,14 +94,17 @@ import {
AuthorHistoryType,
FullNameTypes,
PermalinkRedditThings,
RedditThing, SnoowrapActivity
RedditThing,
SnoowrapActivity
} from "./Common/Infrastructure/Reddit";
import {
FullActivityWindowConfig,
ActivityWindowConfig,
ActivityWindowCriteria,
HistoryFiltersConfig, HistoryFiltersOptions
FullActivityWindowConfig,
HistoryFiltersConfig,
HistoryFiltersOptions
} from "./Common/Infrastructure/ActivityWindow";
import {RunnableBaseJson} from "./Common/Infrastructure/Runnable";
//import {ResembleSingleCallbackComparisonResult} from "resemblejs";
@@ -699,66 +701,6 @@ export const isActivityWindowConfig = (val: any): val is FullActivityWindowConfi
return false;
}
export interface ConfigToObjectOptions {
location?: string,
jsonDocFunc?: (content: string, location?: string) => AbstractConfigDocument<OperatorJsonConfig>,
yamlDocFunc?: (content: string, location?: string) => AbstractConfigDocument<YamlDocument>
}
export const parseFromJsonOrYamlToObject = (content: string, options?: ConfigToObjectOptions): [ConfigFormat, ConfigDocumentInterface<YamlDocument | object>?, Error?, Error?] => {
let obj;
let configFormat: ConfigFormat = 'yaml';
let jsonErr,
yamlErr;
const likelyType = likelyJson5(content) ? 'json' : 'yaml';
const {
location,
jsonDocFunc = (content: string, location?: string) => new JsonConfigDocument(content, location),
yamlDocFunc = (content: string, location?: string) => new YamlConfigDocument(content, location),
} = options || {};
try {
const jsonObj = jsonDocFunc(content, location);
const output = jsonObj.toJS();
const oType = output === null ? 'null' : typeof output;
if (oType !== 'object') {
jsonErr = new SimpleError(`Parsing as json produced data of type '${oType}' (expected 'object')`);
obj = undefined;
} else {
obj = jsonObj;
configFormat = 'json';
}
} catch (err: any) {
jsonErr = err;
}
try {
const yamlObj = yamlDocFunc(content, location)
const output = yamlObj.toJS();
const oType = output === null ? 'null' : typeof output;
if (oType !== 'object') {
yamlErr = new SimpleError(`Parsing as yaml produced data of type '${oType}' (expected 'object')`);
obj = undefined;
} else if (obj === undefined && (likelyType !== 'json' || yamlObj.parsed.errors.length === 0)) {
configFormat = 'yaml';
if(yamlObj.parsed.errors.length !== 0) {
yamlErr = new Error(yamlObj.parsed.errors.join('\n'))
} else {
obj = yamlObj;
}
}
} catch (err: any) {
yamlErr = err;
}
if (obj === undefined) {
configFormat = likelyType;
}
return [configFormat, obj, jsonErr, yamlErr];
}
export const comparisonTextOp = (val1: number, strOp: string, val2: number): boolean => {
switch (strOp) {
case '>':