11import { getConfigValue } from '../config.js' ;
2+ import {
3+ EmptyResponseError ,
4+ InternalServerError ,
5+ NotAuthorizedError ,
6+ PuzzleNotFoundError ,
7+ } from '../errors/apiErrors.js' ;
28import { sizeOfStringInKb } from '../formatting.js' ;
39import { logger } from '../logger.js' ;
4- import {
5- extractTextContentOfMain ,
6- parseResponseMessage ,
7- sanitizeMessage ,
8- } from './parseSubmissionResponse.js' ;
910import { puzzleAnswerUrl , puzzleInputUrl } from './urls.js' ;
1011/**
1112 * Creates a headers object which can be passed to fetch.
@@ -23,46 +24,33 @@ const getHeaders = (authenticationToken) => ({
2324 * @param {Number } day - The day of the puzzle.
2425 * @param {Promise<String> } authenticationToken - Token to authenticate with aoc.
2526 */
26- export const downloadInput = async ( year , day , authenticationToken ) => {
27+ export const getInput = async ( year , day , authenticationToken ) => {
2728 logger . debug ( 'downloading input file for year: %s, day: %s' , year , day ) ;
28-
2929 if ( ! authenticationToken ) {
30- throw new Error (
31- 'Authentication Token is required to query advent of code.'
32- ) ;
30+ throw new NotAuthorizedError ( ) ;
3331 }
3432
35- // query api
3633 const url = puzzleInputUrl ( year , day ) ;
3734 logger . debug ( 'querying url for input: %s' , url ) ;
3835 const response = await fetch ( url , {
3936 headers : getHeaders ( authenticationToken ) ,
4037 } ) ;
4138
42- // bad request, authentication failed.
4339 if ( response . status === 400 ) {
44- throw new Error ( 'Authentication failed, double check authentication token' ) ;
40+ throw new NotAuthorizedError ( ) ;
4541 }
46- // not found, invalid day or year.
4742 if ( response . status === 404 ) {
48- throw new Error ( 'That year/day combination could not be found' ) ;
43+ throw new PuzzleNotFoundError ( year , day ) ;
4944 }
50- // handle all other error status codes
5145 if ( ! response . ok ) {
52- throw new Error (
53- `Unexpected server error while downloading input file, error: ${ response . status } - ${ response . statusText } `
54- ) ;
46+ throw new InternalServerError ( response . status , response . statusText ) ;
5547 }
5648
57- // expect text of response is the input.
5849 const text = await response . text ( ) ;
59-
50+ logger . debug ( 'downloaded: %s' , sizeOfStringInKb ( text ) ) ;
6051 if ( ! text ) {
61- throw new Error ( 'Advent of code returned empty input' ) ;
52+ throw new EmptyResponseError ( ) ;
6253 }
63-
64- logger . debug ( 'downloaded: %s' , sizeOfStringInKb ( text ) ) ;
65-
6654 return text ;
6755} ;
6856
@@ -74,22 +62,19 @@ export const downloadInput = async (year, day, authenticationToken) => {
7462 * @param {String|Number } solution - The solution to test.
7563 * @param {String } authenticationToken - Token to authenticate with aoc.
7664 */
77- export const submitSolution = async (
65+ export const postAnswer = async (
7866 year ,
7967 day ,
8068 level ,
8169 solution ,
8270 authenticationToken
8371) => {
84- logger . debug ( 'submitting solution to advent of code' , { year, day, level } ) ;
72+ logger . debug ( 'posting answer to advent of code' , { year, day, level } ) ;
8573
8674 if ( ! authenticationToken ) {
87- throw new Error (
88- 'Authentication Token is required to query advent of code.'
89- ) ;
75+ throw new NotAuthorizedError ( ) ;
9076 }
9177
92- // post to api
9378 const url = puzzleAnswerUrl ( year , day ) ;
9479 logger . debug ( 'posting to url: %s' , url ) ;
9580 const response = await fetch ( url , {
@@ -101,34 +86,20 @@ export const submitSolution = async (
10186 body : `level=${ level } &answer=${ solution } ` ,
10287 } ) ;
10388
104- // bad request, authentication failed.
105- // as of writing advent returns a 302 to redirect the user to the puzzle page on fail
106- // but check 400 too just incase.
89+ // server can sometimes redirect (302) back to puzzle page if auth fails.
10790 if ( response . status === 400 || response . status === 302 ) {
108- throw new Error ( 'Authentication failed, double check authentication token' ) ;
91+ throw new NotAuthorizedError ( ) ;
10992 }
110- // not found, invalid day or year.
11193 if ( response . status === 404 ) {
112- throw new Error ( 'That year/day combination could not be found' ) ;
94+ throw new PuzzleNotFoundError ( year , day ) ;
11395 }
114- // bail on any other type of http error
11596 if ( ! response . ok ) {
116- throw new Error (
117- `Unexpected server error while posting solution, error: ${ response . status } - ${ response . statusText } `
118- ) ;
97+ throw new InternalServerError ( response . status , response . statusText ) ;
11998 }
12099
121- // advent of code doesn't return status codes, we have to parse the html.
122- // grab the text content of the <main> element which contains the message we need.
123- const responseMessage = sanitizeMessage (
124- extractTextContentOfMain ( await response . text ( ) )
125- ) ;
126-
127- if ( ! responseMessage ) {
128- throw new Error ( 'Unable get message from advent of code response.' ) ;
100+ const text = await response . text ( ) ;
101+ if ( ! text ) {
102+ throw new EmptyResponseError ( ) ;
129103 }
130-
131- // the content of the message tells us what happened
132- // parse this message to determine the submission result.
133- return parseResponseMessage ( responseMessage ) ;
104+ return text ;
134105} ;
0 commit comments