Skip to content

Commit

Permalink
v1.3.0 release 🎉
Browse files Browse the repository at this point in the history
- add eslint to github actions
- update deps
- closes #14 and type check config
  • Loading branch information
phamleduy04 committed Jan 25, 2023
1 parent 19126d4 commit aa5ff83
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 67 deletions.
16 changes: 16 additions & 0 deletions .github/workflows/eslint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: eslint-check
on:
push:
branches:
- "*"
pull_request:
branches:
- '*'

jobs:
eslint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: npm install
- run: npm run eslint
10 changes: 6 additions & 4 deletions example.config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@ location:
preferredDays: 'Monday'
# Put true/false without quotes if you want to book only same day appointment
sameDay: false
# Put how many day from today you want to book (7 is a good number)
daysAround: 9
# Put how many day from today you want to book from start to end (7 is a good number)
daysAround:
start: 0
end: 7

appSettings:
# Put true/false without quotes if you want to cancel the appointment automatically if found existing appointment
cancelIfExist: true
cancelIfExist: false
# The time interval (in ms) the app will recheck for newer dates
interval: 10000
# Set this to true if you using replit, heroku or something equivalent
Expand All @@ -47,4 +49,4 @@ webhook:
# private-api or apple-script
sendMethod: 'apple-script'
# iMessage or SMS
phoneNumberType: ''
phoneNumberType: 'SMS'
28 changes: 14 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "texas-dps-scheduler",
"version": "1.2.5",
"version": "1.3.0",
"description": "Texas DPS Automatic Scheduler",
"main": "dist/index.js",
"scripts": {
Expand All @@ -20,26 +20,26 @@
},
"homepage": "https://github.com/phamleduy04/texas-dps-scheduler#readme",
"devDependencies": {
"@eslint/create-config": "^0.3.1",
"@eslint/create-config": "^0.4.2",
"@types/ms": "^0.7.31",
"@types/node": "^18.7.18",
"@typescript-eslint/eslint-plugin": "^5.38.0",
"@typescript-eslint/parser": "^5.38.0",
"eslint": "^8.23.1",
"eslint-config-prettier": "^8.5.0",
"@types/node": "^18.11.18",
"@typescript-eslint/eslint-plugin": "^5.49.0",
"@typescript-eslint/parser": "^5.49.0",
"eslint": "^8.32.0",
"eslint-config-prettier": "^8.6.0",
"eslint-plugin-prettier": "^4.2.1",
"prettier": "^2.7.1",
"prettier": "^2.8.3",
"ts-node": "^10.9.1",
"tslib": "^2.4.0",
"typescript": "^4.8.3"
"tslib": "^2.4.1",
"typescript": "^4.9.4"
},
"dependencies": {
"chalk": "4.1.2",
"dayjs": "^1.11.5",
"dayjs": "^1.11.7",
"js-yaml": "^4.1.0",
"ms": "^2.1.3",
"p-queue": "6.6.2",
"undici": "^5.10.0",
"yaml": "^2.1.1"
"undici": "^5.16.0",
"yaml": "^2.2.1",
"zod": "^3.20.2"
}
}
18 changes: 12 additions & 6 deletions src/Client/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import undici from 'undici';
import ms from 'ms';
import pQueue from 'p-queue';
import sleep from 'timers/promises';
import parseConfig from '../Config';
import * as log from '../Log';
import dayjs from 'dayjs';
import isBetween from 'dayjs/plugin/isBetween';
dayjs.extend(isBetween);

import type { EligibilityPayload } from '../Interfaces/Eligibility';
import type { AvaliableLocationPayload, AvaliableLocationResponse } from '../Interfaces/AvaliableLocation';
Expand Down Expand Up @@ -129,21 +130,26 @@ class TexasScheduler {
TypeId: this.config.personalInfo.typeId || 71,
};
const response: AvaliableLocationDatesResponse = await this.requestApi('/api/AvailableLocationDates', 'POST', requestBody).then(res => res.body.json());
const avaliableDates = response.LocationAvailabilityDates.filter(
date => new Date(date.AvailabilityDate).valueOf() - new Date().valueOf() < ms(`${this.config.location.daysAround}d`) && date.AvailableTimeSlots.length > 0,
);
const avaliableDates = response.LocationAvailabilityDates.filter(date => {
const AvailabilityDate = dayjs(date.AvailabilityDate);
const today = dayjs();
return (
AvailabilityDate.isBetween(today.subtract(this.config.location.daysAround.start, 'day'), today.add(this.config.location.daysAround.end, 'day'), 'day') &&
date.AvailableTimeSlots.length > 0
);
});
if (avaliableDates.length !== 0) {
const booking = avaliableDates[0].AvailableTimeSlots[0];
log.info(`${location.Name} is avaliable on ${booking.FormattedStartDateTime}`);
if (!this.queue.isPaused) this.queue.pause();
this.holdSlot(booking, location);
return Promise.resolve(true);
}
log.info(`${location.Name} is not avaliable in around ${this.config.location.daysAround} days`);
log.info(`${location.Name} is not avaliable in around ${this.config.location.daysAround.start}-${this.config.location.daysAround.end} days from today!`);
return Promise.reject();
}

private async requestApi(path: string, method: "GET" | "POST", body: object) {
private async requestApi(path: string, method: 'GET' | 'POST', body: object) {
const response = await this.requestInstance.request({
method,
path,
Expand Down
52 changes: 9 additions & 43 deletions src/Config/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { readFileSync, existsSync } from 'fs';
import YAML from 'yaml';

import { configZod, Config } from '../Interfaces/Config';
import preferredDayList from '../Assets/preferredDay';
import * as log from '../Log';

const parseConfig = (): Config => {
if (!existsSync('./config.yml')) {
Expand All @@ -13,7 +14,13 @@ const parseConfig = (): Config => {
const configData = YAML.parse(file);
configData.location.preferredDays = parsePreferredDays(configData.location.preferredDays);
configData.personalInfo.phoneNumber = parsePhoneNumber(configData.personalInfo.phoneNumber);
return configData;
try {
return configZod.parse(configData);
} catch (e) {
log.error('[ERROR] Config file is not valid');
console.error(e);
process.exit(0);
}
};

export default parseConfig;
Expand All @@ -29,44 +36,3 @@ function parsePreferredDays(preferredDay: string): number {
if (preferredDayList[preferredDay]) return preferredDayList[preferredDay];
else return 0;
}

interface Config {
personalInfo: personalInfo;
location: location;
appSettings: appSettings;
webhook: webhook;
}

interface personalInfo {
firstName: string;
lastName: string;
dob: string;
email: string;
lastFourSSN: string;
phoneNumber?: string;
typeId?: number;
}

interface location {
zipCode: string;
miles: number;
preferredDays: number;
sameDay: boolean;
daysAround: number;
}

interface appSettings {
cancelIfExist: boolean;
interval: number;
webserver: boolean;
headersTimeout: number;
}

interface webhook {
enable: boolean;
url: string;
password: string;
phoneNumber: string;
sendMethod: 'private-api' | 'apple-script';
phoneNumberType: 'iMessage' | 'SMS';
}
41 changes: 41 additions & 0 deletions src/Interfaces/Config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { z } from 'zod';

const configZod = z.object({
personalInfo: z.object({
firstName: z.string(),
lastName: z.string(),
dob: z.string(),
email: z.string(),
lastFourSSN: z.string(),
phoneNumber: z.string().optional(),
typeId: z.number().optional(),
}),
location: z.object({
zipCode: z.string(),
miles: z.number(),
preferredDays: z.number(),
sameDay: z.boolean(),
daysAround: z.object({
start: z.number(),
end: z.number(),
}),
}),
appSettings: z.object({
cancelIfExist: z.boolean().default(false),
interval: z.number().default(10000),
webserver: z.boolean().default(false),
headersTimeout: z.number().default(20000),
}),
webhook: z.object({
enable: z.boolean().default(false),
url: z.string().optional(),
password: z.string().optional(),
phoneNumber: z.string().optional(),
sendMethod: z.union([z.literal('private-api'), z.literal('apple-script')]).default('apple-script'),
phoneNumberType: z.union([z.literal('iMessage'), z.literal('SMS')]).default('SMS'),
}),
});

type Config = z.infer<typeof configZod>;

export { Config, configZod };

0 comments on commit aa5ff83

Please sign in to comment.