|
| 1 | +import { |
| 2 | + DEFAULT_USERNOTE_TYPES, |
| 3 | + migrateConfigToLatestSchema, |
| 4 | +} from '../helpers/config'; |
| 5 | +import {RawSubredditConfig, RawUsernoteType} from '../types/RawSubredditConfig'; |
| 6 | + |
| 7 | +// type imports for doc references |
| 8 | +import type {Usernote} from '../types/Usernote'; |
| 9 | + |
| 10 | +/** |
| 11 | + * A class that interfaces with the raw contents of a subreddit's `toolbox` |
| 12 | + * wiki page, automatically handling schema checks and providing methods to read |
| 13 | + * and modify subreddit configuration. |
| 14 | + */ |
| 15 | +export class SubredditConfig { |
| 16 | + private data: RawSubredditConfig; |
| 17 | + |
| 18 | + constructor (jsonString: string) { |
| 19 | + this.data = migrateConfigToLatestSchema(JSON.parse(jsonString)); |
| 20 | + } |
| 21 | + |
| 22 | + /** Returns all usernote types. */ |
| 23 | + getAllNoteTypes (): RawUsernoteType[] { |
| 24 | + // If the config doesn't specify any note types, make a copy of the |
| 25 | + // default set and add them to the config so the unambiguous form will |
| 26 | + // be written back |
| 27 | + if (!this.data.usernoteColors || !this.data.usernoteColors.length) { |
| 28 | + const defaultTypes = DEFAULT_USERNOTE_TYPES.map(noteType => ({ |
| 29 | + ...noteType, |
| 30 | + })); |
| 31 | + this.data.usernoteColors = defaultTypes; |
| 32 | + } |
| 33 | + |
| 34 | + return this.data.usernoteColors; |
| 35 | + } |
| 36 | + |
| 37 | + /** |
| 38 | + * Returns the usernote type matching the given key. Useful for looking up |
| 39 | + * display information for a usernote from {@linkcode Usernote.noteType}. |
| 40 | + * |
| 41 | + * @example Get the color and text of a note type from the key: |
| 42 | + * ```ts |
| 43 | + * const toolbox = new ToolboxClient(reddit); |
| 44 | + * const subreddit = 'mildlyinteresting'; |
| 45 | + * |
| 46 | + * // Acquire a note somehow |
| 47 | + * const usernotes = toolbox.getUsernotes(subreddit); |
| 48 | + * const note = usernotes.get('eritbh')[0]; |
| 49 | + * |
| 50 | + * // Look up information about the type of this note |
| 51 | + * const subConfig = toolbox.getConfig(subreddit); |
| 52 | + * const {color, text} = subConfig.getNoteType(note.noteType); |
| 53 | + * ``` |
| 54 | + */ |
| 55 | + getNoteType (key: string) { |
| 56 | + const noteTypes = this.getAllNoteTypes(); |
| 57 | + return noteTypes.find(noteType => noteType.key === key); |
| 58 | + } |
| 59 | + |
| 60 | + /** |
| 61 | + * Serializes the subreddit config data for writing back to the wiki. **This |
| 62 | + * method returns an object; you probably want {@linkcode toString} |
| 63 | + * instead.** |
| 64 | + * @returns Object which can be serialized to JSON and written as the |
| 65 | + * contents of the `toolbox` wiki page |
| 66 | + */ |
| 67 | + toJSON () { |
| 68 | + return this.data; |
| 69 | + } |
| 70 | + |
| 71 | + /** |
| 72 | + * Stringifies the subreddit config data for writing back to the wiki. |
| 73 | + * @param indent Passed as the third argument of `JSON.stringify`. Useful |
| 74 | + * for debugging; however, because wiki space is limited, never provide this |
| 75 | + * parameter when actually saving config to the wiki. |
| 76 | + * @returns JSON string which can be saved as the contents of the `toolbox` |
| 77 | + * wiki page |
| 78 | + */ |
| 79 | + toString (indent?: string | number) { |
| 80 | + return JSON.stringify(this.data, null, indent); |
| 81 | + } |
| 82 | +} |
0 commit comments