diff --git a/README.md b/README.md index 16fa1d2..77e161e 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ npm i --save advent-of-code-client ## How to use -Initializing the client: +**Initializing the client:** ```javascript import { AocClient } from 'advent-of-code-client'; @@ -22,7 +22,7 @@ const client = new AocClient({ }); ``` -Fetching the puzzle input: +**Fetching the puzzle input:** ```javascript const input = await client.getInput(); @@ -51,26 +51,31 @@ const part2 = (input) => { await client.run([part1, part2], true); ``` -Transforming inputs before they are returned from `.getInput()`. This can be especially useful if you are running your puzzle parts automatically. When using the `.setInputTransform(transform)` method, the input to each part function will be the transformed / parsed data. +**Transforming inputs before they are returned from `.getInput()`:** + +This can be especially useful if you are running your puzzle parts automatically. When using the `inputTransform` option when creating the client, the input passed to each part function will be the transformed / parsed data. For convenience there are a couple of pre-defined transform functions for commonly used transformations (i.e. splitting data by lines). The pre-defined transform functions are exported as `transforms`: ```javascript import { transforms } from 'advent-of-code-client'; -client.setInputTransform(transforms.lines); +const client = new AocClient({ + ... // other options + inputTransform: transforms.lines // automatically split the input by lines +}); ``` You can also specify your own transform function: ```javascript - -const myTransform = rawData => { - ... // transform data - return transformedData; -} - -client.setInputTransform(myTransform); +const client = new AocClient({ + ... // other options + inputTransform: (rawData) => { + ... // transform data + return transformedData; + } +}); ``` ## Authentication diff --git a/src/AocClient.ts b/src/AocClient.ts index ab1bbde..4ca2f0d 100644 --- a/src/AocClient.ts +++ b/src/AocClient.ts @@ -10,24 +10,33 @@ import type { Config, PartFn, Result, - TransformFn + TransformFn, + ClientOptions } from './AocClient.types'; const getCacheKey = ({ year, day, token, part }: CacheKeyParams) => `${year}:${day}:${token}:${part}`; +const noopTransform = (input: string) => input; /** * A class that handles fetching input from and submitting answers to Advent Of Code. * Each instance of the class corresponds to a puzzle for a specific day and year based on the configuration. */ -class AocClient { +class AocClient { private config: Config; private cache: Cache; - private transform: TransformFn; + private transform: TransformFn; /** - * @param {object} config + * @param {object} options */ - constructor({ year, day, token, useCache = true, debug = false }: Config) { + constructor({ + year, + day, + token, + useCache = true, + debug = false, + inputTransform = noopTransform as TransformFn + }: ClientOptions) { if ( !year || Number.isNaN(year) || @@ -64,7 +73,12 @@ class AocClient { globalThis.aocDebug = true; } this.cache = new CacheConf(); - this.transform = null; + if (typeof inputTransform !== 'function') { + throw new Error( + 'Invalid inputTransform option, inputTransform must be a function' + ); + } + this.transform = inputTransform; } private _hasCompletedPart(part: number) { @@ -85,7 +99,7 @@ class AocClient { logger.log('Fetching input...'); const input = await getInput(this.config, this.cache); const trimmedInput = input.trim(); - return this.transform ? this.transform(trimmedInput) : trimmedInput; + return this.transform(trimmedInput); } /** @@ -139,7 +153,9 @@ class AocClient { * @param {boolean} autoSubmit - when true the answers for each part will be submitted to Advent Of Code automatically, otherwise each answer will require confirmation before it will be submitted. */ async run( - parts: [part1: PartFn] | [part1: PartFn, part2: PartFn], + parts: + | [part1: PartFn] + | [part1: PartFn, part2: PartFn], autoSubmit = false ) { if (!parts || !parts.length || parts.length > 2) { @@ -215,12 +231,6 @@ class AocClient { } return Promise.resolve(); } - - setInputTransform(transform: TransformFn) { - if (typeof transform !== 'function') - throw new Error('transform must be a function'); - this.transform = transform; - } } export default AocClient; diff --git a/src/AocClient.types.ts b/src/AocClient.types.ts index b29dec2..51126d9 100644 --- a/src/AocClient.types.ts +++ b/src/AocClient.types.ts @@ -23,6 +23,10 @@ export type Config = { debug?: boolean; }; +export type ClientOptions = Config & { + inputTransform?: TransformFn; +}; + export type Cache = { get: (key: string, options?: { ignoreMaxAge?: boolean }) => any; set: ( @@ -36,8 +40,8 @@ export type Cache = { isExpired: (key: string) => boolean; }; -export type TransformFn = (input: string) => any; +export type TransformFn = (input: string) => T; export type Result = number | string; -export type PartFn = (input: any) => Result; +export type PartFn = (input: T) => Result;