mirror of
https://github.com/FoxxMD/context-mod.git
synced 2026-04-19 03:00:07 -04:00
fix(modnote): Fix initial implementation bugs
* Improve action criteria to FullCriteria function * Don't include undefined properties * Iterate entries with switch to simplify property transformations * Fix mod action test switch case matching to be case-insensitive (same as key) * Fix missing/bad assignments for filtering mod actions * Fix typo usage of foundNoteResult in modActions case block * Throw error if mod action criteria isn't recognized as note/log instead of silently falling back to log
This commit is contained in:
@@ -141,19 +141,43 @@ export interface FullModNoteCriteria extends FullModActionCriteria, Omit<ModNote
|
||||
note?: RegExp[]
|
||||
}
|
||||
|
||||
const arrayableModNoteProps = ['activityType','noteType','note'];
|
||||
|
||||
export const asModNoteCriteria = (val: any): val is ModNoteCriteria => {
|
||||
return val !== null && typeof val === 'object' && ('noteType' in val || 'note' in val);
|
||||
}
|
||||
|
||||
export const toFullModNoteCriteria = (val: ModNoteCriteria): FullModNoteCriteria => {
|
||||
return {
|
||||
type: ['NOTE'],
|
||||
count: val.count === undefined ? undefined : parseGenericValueComparison(val.count),
|
||||
search: val.search,
|
||||
activityType: val.activityType === undefined ? undefined : (Array.isArray(val.activityType) ? val.activityType : [val.activityType]),
|
||||
noteType: val.noteType === undefined ? undefined : (Array.isArray(val.noteType) ? val.noteType : [val.noteType]),
|
||||
note: val.note === undefined ? undefined : (Array.isArray(val.note) ? val.note.map(x => parseStringToRegexOrLiteralSearch(x)) : [parseStringToRegexOrLiteralSearch(val.note)]),
|
||||
}
|
||||
|
||||
const result = Object.entries(val).reduce((acc: FullModNoteCriteria, curr) => {
|
||||
const [k,v] = curr;
|
||||
|
||||
if(v === undefined) {
|
||||
return acc;
|
||||
}
|
||||
|
||||
const rawVal = arrayableModNoteProps.includes(k) && !Array.isArray(v) ? [v] : v;
|
||||
|
||||
switch(k) {
|
||||
case 'search':
|
||||
acc.search = rawVal;
|
||||
break;
|
||||
case 'count':
|
||||
acc.count = parseGenericValueComparison(rawVal);
|
||||
break;
|
||||
case 'activityType':
|
||||
case 'noteType':
|
||||
acc[k] = rawVal;
|
||||
break;
|
||||
case 'note':
|
||||
acc[k] = rawVal.map((x: string) => parseStringToRegexOrLiteralSearch(x))
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
result.type = ['NOTE'];
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -169,21 +193,42 @@ export interface FullModLogCriteria extends FullModActionCriteria, Omit<ModLogCr
|
||||
description?: RegExp[]
|
||||
}
|
||||
|
||||
const arrayableModLogProps = ['type','activityType','action','description','details', 'type'];
|
||||
|
||||
export const asModLogCriteria = (val: any): val is ModLogCriteria => {
|
||||
return val !== null && typeof val === 'object' && ('action' in val || 'details' in val || 'description' in val || 'activityType' in val);
|
||||
return val !== null && typeof val === 'object' && !asModNoteCriteria(val) && ('action' in val || 'details' in val || 'description' in val || 'activityType' in val || 'search' in val || 'count' in val || 'type' in val);
|
||||
}
|
||||
|
||||
|
||||
export const toFullModLogCriteria = (val: ModLogCriteria): FullModLogCriteria => {
|
||||
return {
|
||||
count: val.count === undefined ? undefined : parseGenericValueComparison(val.count),
|
||||
search: val.search,
|
||||
type: val.type === undefined ? undefined : (Array.isArray(val.type) ? val.type : [val.type]).map(x => x.toUpperCase()) as ModActionType[],
|
||||
activityType: val.activityType === undefined ? undefined : (Array.isArray(val.activityType) ? val.activityType : [val.activityType]),
|
||||
action: val.action === undefined ? undefined : (Array.isArray(val.action) ? val.action.map(x => parseStringToRegexOrLiteralSearch(x)) : [parseStringToRegexOrLiteralSearch(val.action)]),
|
||||
description: val.description === undefined ? undefined : (Array.isArray(val.description) ? val.description.map(x => parseStringToRegexOrLiteralSearch(x)) : [parseStringToRegexOrLiteralSearch(val.description)]),
|
||||
details: val.details === undefined ? undefined : (Array.isArray(val.details) ? val.details.map(x => parseStringToRegexOrLiteralSearch(x)) : [parseStringToRegexOrLiteralSearch(val.details)]),
|
||||
}
|
||||
|
||||
return Object.entries(val).reduce((acc: FullModLogCriteria, curr) => {
|
||||
const [k,v] = curr;
|
||||
|
||||
if(v === undefined) {
|
||||
return acc;
|
||||
}
|
||||
|
||||
const rawVal = arrayableModLogProps.includes(k) && !Array.isArray(v) ? [v] : v;
|
||||
|
||||
switch(k) {
|
||||
case 'search':
|
||||
acc.search = rawVal;
|
||||
break;
|
||||
case 'count':
|
||||
acc.count = parseGenericValueComparison(rawVal);
|
||||
break;
|
||||
case 'activityType':
|
||||
case 'type':
|
||||
acc[k as keyof FullModLogCriteria] = rawVal;
|
||||
break;
|
||||
case 'action':
|
||||
case 'description':
|
||||
case 'details':
|
||||
acc[k as keyof FullModLogCriteria] = rawVal.map((x: string) => parseStringToRegexOrLiteralSearch(x))
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
|
||||
export const authorCriteriaProperties = ['name', 'flairCssClass', 'flairText', 'flairTemplate', 'isMod', 'userNotes', 'modActions', 'age', 'linkKarma', 'commentKarma', 'totalKarma', 'verified', 'shadowBanned', 'description', 'isContributor'];
|
||||
|
||||
@@ -2874,7 +2874,7 @@ export class SubredditResources {
|
||||
|
||||
let actionsToUse: ModNote[] = [];
|
||||
if(asModNoteCriteria(actionCriteria)) {
|
||||
actionsToUse.filter(x => x.type === 'NOTE');
|
||||
actionsToUse = actionsToUse.filter(x => x.type === 'NOTE');
|
||||
} else {
|
||||
actionsToUse = modActions;
|
||||
}
|
||||
@@ -2905,7 +2905,7 @@ export class SubredditResources {
|
||||
return false
|
||||
}
|
||||
break;
|
||||
case 'activityType':
|
||||
case 'activitytype':
|
||||
const anyMatch = v.some((a: ActivityType) => {
|
||||
switch (a) {
|
||||
case 'submission':
|
||||
@@ -2941,10 +2941,10 @@ export class SubredditResources {
|
||||
|
||||
return true;
|
||||
}); // filter end
|
||||
} else {
|
||||
} else if(asModNoteCriteria(actionCriteria)) {
|
||||
const fullCrit = toFullModNoteCriteria(actionCriteria as ModNoteCriteria);
|
||||
const fullCritEntries = Object.entries(fullCrit);
|
||||
validActions = modActions.filter(x => {
|
||||
validActions = actionsToUse.filter(x => {
|
||||
|
||||
// filter out any notes that occur before time range
|
||||
if(cutoffDate !== undefined && x.createdAt.isBefore(cutoffDate)) {
|
||||
@@ -2957,7 +2957,7 @@ export class SubredditResources {
|
||||
continue;
|
||||
}
|
||||
switch (key) {
|
||||
case 'noteType':
|
||||
case 'notetype':
|
||||
if (!v.map((x: ModUserNoteLabel) => x.toUpperCase()).includes((x.note.label as ModUserNoteLabel))) {
|
||||
return false
|
||||
}
|
||||
@@ -2972,7 +2972,7 @@ export class SubredditResources {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'activityType':
|
||||
case 'activitytype':
|
||||
const anyMatch = v.some((a: ActivityType) => {
|
||||
switch (a) {
|
||||
case 'submission':
|
||||
@@ -2997,11 +2997,13 @@ export class SubredditResources {
|
||||
|
||||
return true;
|
||||
}); // filter end
|
||||
} else {
|
||||
throw new SimpleError(`Could not determine if a modActions criteria was for Mod Log or Mod Note. Given: ${JSON.stringify(actionCriteria)}`);
|
||||
}
|
||||
|
||||
switch (search) {
|
||||
case 'current':
|
||||
if (modActions.length === 0) {
|
||||
if (validActions.length === 0) {
|
||||
actionResult.push('No Mod Actions present');
|
||||
} else {
|
||||
actionResult.push('Current Action matches criteria');
|
||||
@@ -3038,12 +3040,12 @@ export class SubredditResources {
|
||||
if (isPercent) {
|
||||
// avoid divide by zero
|
||||
const percent = notes.length === 0 ? 0 : validActions.length / actionsToUse.length;
|
||||
foundNoteResult.push(`${formatNumber(percent)}% of ${actionsToUse.length} matched criteria`);
|
||||
actionResult.push(`${formatNumber(percent)}% of ${actionsToUse.length} matched criteria`);
|
||||
if (comparisonTextOp(percent, operator, value / 100)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
foundNoteResult.push(`${validActions.length} matched criteria`);
|
||||
actionResult.push(`${validActions.length} matched criteria`);
|
||||
if (comparisonTextOp(validActions.length, operator, value)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user