All files / src/moderation Moderation.ts

92.85% Statements 26/28
50% Branches 2/4
91.66% Functions 22/24
91.66% Lines 22/24

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115              10x     2x       2x             11x             1x             5x             4x 4x 6x   4x             1x             2x         1x     1x     1x             1x 1x                 11x     2x       13x       2x       6x                      
import { ModerationResponse, ModerationResult } from "../providers/Provider.js";
 
/**
 * Represents the results of a moderation request.
 * Can contain one or multiple results if multiple inputs were provided.
 */
export class Moderation implements Iterable<ModerationItem> {
  constructor(private readonly response: ModerationResponse) {}
 
  get id(): string {
    return this.response.id;
  }
 
  get model(): string {
    return this.response.model;
  }
 
  /**
   * Returns all results as ModerationItem instances
   */
  get results(): ModerationItem[] {
    return this.response.results.map((r) => new ModerationItem(r));
  }
 
  /**
   * Returns the number of results
   */
  get length(): number {
    return this.response.results.length;
  }
 
  /**
   * Returns true if any of the results are flagged
   */
  get flagged(): boolean {
    return this.response.results.some((r) => r.flagged);
  }
 
  /**
   * Aggregates all flagged categories across all results
   */
  get flaggedCategories(): string[] {
    const all = new Set<string>();
    for (const item of this.results) {
      item.flaggedCategories.forEach((cat) => all.add(cat));
    }
    return Array.from(all);
  }
 
  /**
   * Returns categories for the first result (most common case)
   */
  get categories(): Record<string, boolean> {
    return this.results[0]?.categories || {};
  }
 
  /**
   * Returns category scores for the first result
   */
  get categoryScores(): Record<string, number> {
    return this.results[0]?.categoryScores || {};
  }
 
  // --- Ruby-compatible aliases ---
  get flagged_categories(): string[] {
    return this.flaggedCategories;
  }
  get category_scores(): Record<string, number> {
    return this.categoryScores;
  }
  isFlagged(): boolean {
    return this.flagged;
  }
 
  /**
   * Makes the Moderation object iterable (yields results)
   */
  *[Symbol.iterator](): Iterator<ModerationItem> {
    for (const item of this.results) {
      yield item;
    }
  }
}
 
/**
 * Represents a single result within a moderation request
 */
export class ModerationItem {
  constructor(public readonly raw: ModerationResult) {}
 
  get flagged(): boolean {
    return this.raw.flagged;
  }
 
  get categories(): Record<string, boolean> {
    return this.raw.categories;
  }
 
  get categoryScores(): Record<string, number> {
    return this.raw.category_scores;
  }
 
  get flaggedCategories(): string[] {
    return Object.keys(this.categories).filter((cat) => this.categories[cat]);
  }
 
  // --- Ruby-compatible aliases ---
  get flagged_categories(): string[] {
    return this.flaggedCategories;
  }
  get category_scores(): Record<string, number> {
    return this.categoryScores;
  }
}