• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nguyenhuuit / adventofcode-runner / 15927816902

27 Jun 2025 01:44PM UTC coverage: 93.865% (+4.1%) from 89.753%
15927816902

push

github

nguyenhuuit
chore: add option to display version

158 of 169 branches covered (93.49%)

Branch coverage included in aggregate %.

3 of 8 new or added lines in 3 files covered. (37.5%)

1 existing line in 1 file now uncovered.

607 of 646 relevant lines covered (93.96%)

8.38 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.28
/src/utils/aocClient.ts
1
import axios from 'axios';
1✔
2

3
import { config } from '@utils/config';
1✔
4
import { APP_NAME, APP_VERSION } from '@utils/constants';
1✔
5

6
class AocClient {
7
  private client;
8

9
  private constructor() {
10
    this.client = axios.create({
1✔
11
      baseURL: 'https://adventofcode.com',
12
      headers: {
13
        Cookie: config.sessionToken ? `session=${config.sessionToken}` : '',
1!
14
        'User-Agent': `Advent Of Code Runner (${APP_NAME}@${APP_VERSION})`,
15
      },
16
    });
17
  }
18

19
  private static instance: AocClient;
20

21
  public static getInstance(): AocClient {
22
    if (!AocClient.instance) {
1✔
23
      AocClient.instance = new AocClient();
1✔
24
    }
25
    return AocClient.instance;
1✔
26
  }
27

28
  async fetchInput(year: string, day: string): Promise<string> {
29
    if (!config.sessionToken) {
2✔
30
      throw new Error('SESSION is required to fetch input');
1✔
31
    }
32
    const response = await this.client.get(`/${year}/day/${day}/input`);
1✔
33
    return response.data;
1✔
34
  }
35

36
  async fetchProblem(year: string, day: string): Promise<string> {
37
    if (!config.sessionToken) {
2✔
38
      throw new Error('SESSION is required to fetch problem');
1✔
39
    }
40
    const response = await this.client.get(`/${year}/day/${day}`);
1✔
41
    return response.data;
1✔
42
  }
43

44
  async submitAnswer(
45
    year: string,
46
    day: string,
47
    part: number,
48
    answer: string
49
  ): Promise<{ correct: boolean; message: string; waitingTime?: string }> {
50
    if (!config.sessionToken) {
7✔
51
      throw new Error('SESSION is required to submit answer');
1✔
52
    }
53

54
    const response = await this.client.post(
6✔
55
      `/${year}/day/${day}/answer`,
56
      `level=${part}&answer=${encodeURIComponent(answer)}`,
57
      {
58
        headers: {
59
          'Content-Type': 'application/x-www-form-urlencoded',
60
        },
61
      }
62
    );
63

64
    const html = response.data;
6✔
65
    const isCorrect = html.includes("That's the right answer!");
6✔
66
    const isTooLow = html.includes("That's not the right answer; your answer is too low.");
6✔
67
    const isTooHigh = html.includes("That's not the right answer; your answer is too high.");
6✔
68
    const isAlreadyComplete = html.includes("You don't seem to be solving the right level.");
6✔
69
    const isRateLimited = html.includes('You gave an answer too recently');
6✔
70

71
    let message = 'Unknown response';
6✔
72
    let waitingTime: string | undefined;
73

74
    if (isCorrect) {
6✔
75
      message = 'Correct answer!';
1✔
76
    } else if (isTooLow) {
5✔
77
      message = 'Too low';
1✔
78
    } else if (isTooHigh) {
4✔
79
      message = 'Too high';
1✔
80
    } else if (isAlreadyComplete) {
3✔
81
      message = 'Already completed';
1✔
82
    } else if (isRateLimited) {
2✔
83
      message = 'Rate limited';
1✔
84
      const waitingTimeMatch = html.match(/have ([0-9msh ]+) left to wait/);
1✔
85
      if (waitingTimeMatch) {
1✔
86
        waitingTime = waitingTimeMatch[1];
1✔
87
      }
88
    } else {
89
      message = 'Incorrect answer';
1✔
90
    }
91

92
    return { correct: isCorrect, message, waitingTime };
6✔
93
  }
94
}
95

96
export const aocClient = AocClient.getInstance();
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc