-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Clean up raw sub config types; add note type APIs (#57)
- Loading branch information
Showing
9 changed files
with
366 additions
and
87 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import test from 'ava'; | ||
|
||
test.todo('getAllNoteTypes'); | ||
test.todo('getNoteType'); | ||
test.todo('toJSON'); | ||
test.todo('toString'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import { | ||
DEFAULT_USERNOTE_TYPES, | ||
migrateConfigToLatestSchema, | ||
} from '../helpers/config'; | ||
import {RawSubredditConfig, RawUsernoteType} from '../types/RawSubredditConfig'; | ||
|
||
// type imports for doc references | ||
import type {Usernote} from '../types/Usernote'; | ||
|
||
/** | ||
* A class that interfaces with the raw contents of a subreddit's `toolbox` | ||
* wiki page, automatically handling schema checks and providing methods to read | ||
* and modify subreddit configuration. | ||
*/ | ||
export class SubredditConfig { | ||
private data: RawSubredditConfig; | ||
|
||
constructor (jsonString: string) { | ||
this.data = migrateConfigToLatestSchema(JSON.parse(jsonString)); | ||
} | ||
|
||
/** Returns all usernote types. */ | ||
getAllNoteTypes (): RawUsernoteType[] { | ||
// If the config doesn't specify any note types, make a copy of the | ||
// default set and add them to the config so the unambiguous form will | ||
// be written back | ||
if (!this.data.usernoteColors || !this.data.usernoteColors.length) { | ||
const defaultTypes = DEFAULT_USERNOTE_TYPES.map(noteType => ({ | ||
...noteType, | ||
})); | ||
this.data.usernoteColors = defaultTypes; | ||
} | ||
|
||
return this.data.usernoteColors; | ||
} | ||
|
||
/** | ||
* Returns the usernote type matching the given key. Useful for looking up | ||
* display information for a usernote from {@linkcode Usernote.noteType}. | ||
* | ||
* @example Get the color and text of a note type from the key: | ||
* ```ts | ||
* const toolbox = new ToolboxClient(reddit); | ||
* const subreddit = 'mildlyinteresting'; | ||
* | ||
* // Acquire a note somehow | ||
* const usernotes = toolbox.getUsernotes(subreddit); | ||
* const note = usernotes.get('eritbh')[0]; | ||
* | ||
* // Look up information about the type of this note | ||
* const subConfig = toolbox.getConfig(subreddit); | ||
* const {color, text} = subConfig.getNoteType(note.noteType); | ||
* ``` | ||
*/ | ||
getNoteType (key: string) { | ||
const noteTypes = this.getAllNoteTypes(); | ||
return noteTypes.find(noteType => noteType.key === key); | ||
} | ||
|
||
/** | ||
* Serializes the subreddit config data for writing back to the wiki. **This | ||
* method returns an object; you probably want {@linkcode toString} | ||
* instead.** | ||
* @returns Object which can be serialized to JSON and written as the | ||
* contents of the `toolbox` wiki page | ||
*/ | ||
toJSON () { | ||
return this.data; | ||
} | ||
|
||
/** | ||
* Stringifies the subreddit config data for writing back to the wiki. | ||
* @param indent Passed as the third argument of `JSON.stringify`. Useful | ||
* for debugging; however, because wiki space is limited, never provide this | ||
* parameter when actually saving config to the wiki. | ||
* @returns JSON string which can be saved as the contents of the `toolbox` | ||
* wiki page | ||
*/ | ||
toString (indent?: string | number) { | ||
return JSON.stringify(this.data, null, indent); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import test from 'ava'; | ||
|
||
test.todo('migrateConfigToLatestSchema'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import {RawSubredditConfig, RawUsernoteType} from '../types/RawSubredditConfig'; | ||
|
||
/** | ||
* The latest subreddit config schema version that this library can handle. If a | ||
* config page reports a schema version higher than this number, it can't be | ||
* processed with this version of the library. | ||
*/ | ||
export const LATEST_KNOWN_CONFIG_SCHEMA = 1; | ||
|
||
/** | ||
* The earliest subreddit config schema version that this library can handle. If | ||
* a config page reports a schema version lower than this number, it can't be | ||
* processed with this version of the library. | ||
*/ | ||
export const EARLIEST_KNOWN_CONFIG_SCHEMA = 1; | ||
|
||
/** Default usernote types used if subreddit config doesn't specify its own. */ | ||
export const DEFAULT_USERNOTE_TYPES: readonly RawUsernoteType[] = [ | ||
{key: 'gooduser', color: 'green', text: 'Good Contributor'}, | ||
{key: 'spamwatch', color: 'fuchsia', text: 'Spam Watch'}, | ||
{key: 'spamwarn', color: 'purple', text: 'Spam Warning'}, | ||
{key: 'abusewarn', color: 'orange', text: 'Abuse Warning'}, | ||
{key: 'ban', color: 'red', text: 'Ban'}, | ||
{key: 'permban', color: 'darkred', text: 'Permanent Ban'}, | ||
{key: 'botban', color: 'black', text: 'Bot Ban'}, | ||
]; | ||
|
||
/** | ||
* Checks the schema version of raw subreddit config data and attempts to update | ||
* it to the latest known schema version if it's out of date. Throws an error if | ||
* the data's current schema version is too old or new to handle. | ||
* @param data The subreddit config data object read from the wiki, as an object | ||
* (i.e. you should parse the page contents as JSON to pass into this function) | ||
* @returns Data object updated to latest schema version | ||
*/ | ||
export function migrateConfigToLatestSchema (data: any): RawSubredditConfig { | ||
if (data.ver < EARLIEST_KNOWN_CONFIG_SCHEMA) { | ||
throw new TypeError( | ||
`Unknown schema version ${data.ver} (earliest known version is ${EARLIEST_KNOWN_CONFIG_SCHEMA})`, | ||
); | ||
} | ||
if (data.ver > LATEST_KNOWN_CONFIG_SCHEMA) { | ||
throw new TypeError( | ||
`Unknown schema version ${data.ver} (latest known version is ${LATEST_KNOWN_CONFIG_SCHEMA})`, | ||
); | ||
} | ||
|
||
// In the future, if we ever do a schema bump to this page, migration steps | ||
// will go here. See also migrateUsernotesToLatestSchema() | ||
|
||
return data as RawSubredditConfig; | ||
} |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.