mirror of
https://github.com/holidayapi/holidayapi-node.git
synced 2025-06-21 12:36:33 +00:00
feat: get previous workday
This started as a feature request for our upstream API (closes #33) that led to a bit of rework to help make the library a bit more flexible in terms of not needing modification when something on the API changes. This update also includes your typical round of dependency updates and a bit of preemptive planning by way of dropping support for Node.js as we're on the cusp of it being out of maintenance and the release of Node.js v18.
This commit is contained in:
parent
c3de7ff9bd
commit
7de5339090
7 changed files with 3512 additions and 6265 deletions
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
|
@ -6,7 +6,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: ['12', '14', '16']
|
||||
node-version: ['14', '16']
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v2
|
||||
|
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2016, 2017, 2018, 2019, 2020 Gravity Boulevard, LLC
|
||||
Copyright (c) 2016, 2017, 2018, 2019, 2020, 2021, 2022 Gravity Boulevard, LLC
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
9346
package-lock.json
generated
9346
package-lock.json
generated
File diff suppressed because it is too large
Load diff
32
package.json
32
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "holidayapi",
|
||||
"version": "5.1.0",
|
||||
"version": "6.0.0",
|
||||
"description": "Official Node.js library for Holiday API",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
|
@ -21,26 +21,26 @@
|
|||
},
|
||||
"homepage": "https://holidayapi.com",
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
"node": ">= 14.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^26.0.19",
|
||||
"@types/jest": "^27.4.1",
|
||||
"@types/nock": "^11.1.0",
|
||||
"@types/node": "^15.12.2",
|
||||
"@types/node-fetch": "^2.5.7",
|
||||
"@typescript-eslint/eslint-plugin": "^4.11.1",
|
||||
"@typescript-eslint/parser": "^4.11.1",
|
||||
"eslint": "^7.16.0",
|
||||
"eslint-config-airbnb-base": "^14.2.1",
|
||||
"eslint-plugin-import": "^2.22.1",
|
||||
"eslint-plugin-jest": "^24.1.3",
|
||||
"jest": "^27.0.4",
|
||||
"nock": "^13.0.5",
|
||||
"ts-jest": "^27.0.3",
|
||||
"typescript": "^4.1.3"
|
||||
"@types/node": "^17.0.23",
|
||||
"@types/node-fetch": "^2.6.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.18.0",
|
||||
"@typescript-eslint/parser": "^5.18.0",
|
||||
"eslint": "^8.12.0",
|
||||
"eslint-config-airbnb-base": "^15.0.0",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-jest": "^26.1.3",
|
||||
"jest": "^27.5.1",
|
||||
"nock": "^13.2.4",
|
||||
"ts-jest": "^27.1.4",
|
||||
"typescript": "^4.6.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"node-fetch": "^2.6.1"
|
||||
"node-fetch": "^2"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
|
|
|
@ -56,7 +56,7 @@ export class HolidayAPI {
|
|||
|
||||
private async request(endpoint: Endpoint, request?: Requests): Promise<Responses> {
|
||||
const response = await fetch(this.createUrl(endpoint, request));
|
||||
let payload;
|
||||
let payload: any;
|
||||
|
||||
try {
|
||||
payload = await response.json();
|
||||
|
@ -76,14 +76,6 @@ export class HolidayAPI {
|
|||
}
|
||||
|
||||
async holidays(request: HolidaysRequest = {}): Promise<HolidaysResponse> {
|
||||
if (!request.country) {
|
||||
throw new Error('Missing country');
|
||||
} else if (!request.year) {
|
||||
throw new Error('Missing year');
|
||||
} else if (request.previous && request.upcoming) {
|
||||
throw new Error('Previous and upcoming are mutually exclusive');
|
||||
}
|
||||
|
||||
return this.request('holidays', request);
|
||||
}
|
||||
|
||||
|
@ -92,28 +84,10 @@ export class HolidayAPI {
|
|||
}
|
||||
|
||||
async workday(request: WorkdayRequest = {}): Promise<WorkdayResponse> {
|
||||
if (!request.country) {
|
||||
throw new Error('Missing country');
|
||||
} else if (!request.start) {
|
||||
throw new Error('Missing start date');
|
||||
} else if (!request.days) {
|
||||
throw new Error('Missing days');
|
||||
} else if (request.days < 1) {
|
||||
throw new Error('Days must be 1 or more');
|
||||
}
|
||||
|
||||
return this.request('workday', request);
|
||||
}
|
||||
|
||||
async workdays(request: WorkdaysRequest = {}): Promise<WorkdaysResponse> {
|
||||
if (!request.country) {
|
||||
throw new Error('Missing country');
|
||||
} else if (!request.start) {
|
||||
throw new Error('Missing start date');
|
||||
} else if (!request.end) {
|
||||
throw new Error('Missing end date');
|
||||
}
|
||||
|
||||
return this.request('workdays', request);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,129 +93,6 @@ describe('holidayapi', () => {
|
|||
expect(await holidayapi.countries()).toStrictEqual(expectedResponse);
|
||||
});
|
||||
|
||||
it('should return only countries with public holidays', async () => {
|
||||
const expectedResponse = {
|
||||
status: 200,
|
||||
requests: {
|
||||
used: 1000,
|
||||
available: 9000,
|
||||
resets: '2019-10-01 00:00:00',
|
||||
},
|
||||
countries: [
|
||||
{
|
||||
code: 'ST',
|
||||
name: 'Sao Tome and Principe',
|
||||
languages: ['pt'],
|
||||
codes: {
|
||||
'alpha-2': 'ST',
|
||||
'alpha-3': 'STP',
|
||||
numeric: 678,
|
||||
},
|
||||
flag: 'https://www.countryflags.io/ST/flat/64.png',
|
||||
subdivisions: [
|
||||
{
|
||||
code: 'ST-P',
|
||||
name: 'Príncipe',
|
||||
languages: ['pt'],
|
||||
},
|
||||
{
|
||||
code: 'ST-S',
|
||||
name: 'São Tomé',
|
||||
languages: ['pt'],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
mockRequest.get(`${basePath}&public=true`).reply(200, expectedResponse);
|
||||
expect(await holidayapi.countries({
|
||||
public: true,
|
||||
})).toStrictEqual(expectedResponse);
|
||||
});
|
||||
|
||||
it('should return one country', async () => {
|
||||
const expectedResponse = {
|
||||
status: 200,
|
||||
requests: {
|
||||
used: 1000,
|
||||
available: 9000,
|
||||
resets: '2019-10-01 00:00:00',
|
||||
},
|
||||
countries: [
|
||||
{
|
||||
code: 'ST',
|
||||
name: 'Sao Tome and Principe',
|
||||
languages: ['pt'],
|
||||
codes: {
|
||||
'alpha-2': 'ST',
|
||||
'alpha-3': 'STP',
|
||||
numeric: 678,
|
||||
},
|
||||
flag: 'https://www.countryflags.io/ST/flat/64.png',
|
||||
subdivisions: [
|
||||
{
|
||||
code: 'ST-P',
|
||||
name: 'Príncipe',
|
||||
languages: ['pt'],
|
||||
},
|
||||
{
|
||||
code: 'ST-S',
|
||||
name: 'São Tomé',
|
||||
languages: ['pt'],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
mockRequest.get(`${basePath}&country=ST`).reply(200, expectedResponse);
|
||||
expect(await holidayapi.countries({
|
||||
country: 'ST',
|
||||
})).toStrictEqual(expectedResponse);
|
||||
});
|
||||
|
||||
it('should search countries', async () => {
|
||||
const expectedResponse = {
|
||||
status: 200,
|
||||
requests: {
|
||||
used: 1000,
|
||||
available: 9000,
|
||||
resets: '2019-10-01 00:00:00',
|
||||
},
|
||||
countries: [
|
||||
{
|
||||
code: 'ST',
|
||||
name: 'Sao Tome and Principe',
|
||||
languages: ['pt'],
|
||||
codes: {
|
||||
'alpha-2': 'ST',
|
||||
'alpha-3': 'STP',
|
||||
numeric: 678,
|
||||
},
|
||||
flag: 'https://www.countryflags.io/ST/flat/64.png',
|
||||
subdivisions: [
|
||||
{
|
||||
code: 'ST-P',
|
||||
name: 'Príncipe',
|
||||
languages: ['pt'],
|
||||
},
|
||||
{
|
||||
code: 'ST-S',
|
||||
name: 'São Tomé',
|
||||
languages: ['pt'],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
mockRequest.get(`${basePath}&search=Sao`).reply(200, expectedResponse);
|
||||
expect(await holidayapi.countries({
|
||||
search: 'Sao',
|
||||
})).toStrictEqual(expectedResponse);
|
||||
});
|
||||
|
||||
it('should raise 4xx errors', async () => {
|
||||
const expectedResponse = {
|
||||
status: 429,
|
||||
|
@ -288,81 +165,6 @@ describe('holidayapi', () => {
|
|||
})).toStrictEqual(expectedResponse);
|
||||
});
|
||||
|
||||
it('should search holidays', async () => {
|
||||
const expectedResponse = {
|
||||
status: 200,
|
||||
requests: {
|
||||
used: 1000,
|
||||
available: 9000,
|
||||
resets: '2019-10-01 00:00:00',
|
||||
},
|
||||
holidays: [
|
||||
{
|
||||
name: 'Independence Day',
|
||||
date: '2015-07-04',
|
||||
observed: '2015-07-03',
|
||||
public: true,
|
||||
country: 'US',
|
||||
uuid: '88268759-9b90-468c-804f-b729b8418e7c',
|
||||
weekday: {
|
||||
date: {
|
||||
name: 'Saturday',
|
||||
numeric: '6',
|
||||
},
|
||||
observed: {
|
||||
name: 'Friday',
|
||||
numeric: '5',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
mockRequest.get(`${basePath}&country=US&year=2019&search=Independence`)
|
||||
.reply(200, expectedResponse);
|
||||
|
||||
expect(await holidayapi.holidays({
|
||||
country: 'US',
|
||||
year: 2019,
|
||||
search: 'Independence',
|
||||
})).toStrictEqual(expectedResponse);
|
||||
});
|
||||
|
||||
it('should error when country is missing', async () => {
|
||||
expect.assertions(1);
|
||||
|
||||
try {
|
||||
await holidayapi.holidays();
|
||||
} catch (err) {
|
||||
expect(err.message).toMatch(/missing country/i);
|
||||
}
|
||||
});
|
||||
|
||||
it('should error when year is missing', async () => {
|
||||
expect.assertions(1);
|
||||
|
||||
try {
|
||||
await holidayapi.holidays({ country: 'US' });
|
||||
} catch (err) {
|
||||
expect(err.message).toMatch(/missing year/i);
|
||||
}
|
||||
});
|
||||
|
||||
it('should error when both previous and upcoming', async () => {
|
||||
expect.assertions(1);
|
||||
|
||||
try {
|
||||
await holidayapi.holidays({
|
||||
country: 'US',
|
||||
year: 2019,
|
||||
previous: true,
|
||||
upcoming: true,
|
||||
});
|
||||
} catch (err) {
|
||||
expect(err.message).toMatch(/previous and upcoming/i);
|
||||
}
|
||||
});
|
||||
|
||||
it('should raise 4xx errors', async () => {
|
||||
const expectedResponse = {
|
||||
status: 429,
|
||||
|
@ -431,54 +233,6 @@ describe('holidayapi', () => {
|
|||
expect(await holidayapi.languages()).toStrictEqual(expectedResponse);
|
||||
});
|
||||
|
||||
it('should return one language', async () => {
|
||||
const expectedResponse = {
|
||||
status: 200,
|
||||
requests: {
|
||||
used: 1000,
|
||||
available: 9000,
|
||||
resets: '2019-10-01 00:00:00',
|
||||
},
|
||||
languages: [
|
||||
{
|
||||
code: 'hi',
|
||||
name: 'Hindi',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
mockRequest.get(`${basePath}&language=hi`).reply(200, expectedResponse);
|
||||
expect(await holidayapi.languages({
|
||||
language: 'hi',
|
||||
})).toStrictEqual(expectedResponse);
|
||||
});
|
||||
|
||||
it('should search languages', async () => {
|
||||
const expectedResponse = {
|
||||
status: 200,
|
||||
requests: {
|
||||
used: 1000,
|
||||
available: 9000,
|
||||
resets: '2019-10-01 00:00:00',
|
||||
},
|
||||
languages: [
|
||||
{
|
||||
code: 'hi',
|
||||
name: 'Hindi',
|
||||
},
|
||||
{
|
||||
code: 'zh',
|
||||
name: 'Chinese (Simplified)',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
mockRequest.get(`${basePath}&search=in`).reply(200, expectedResponse);
|
||||
expect(await holidayapi.languages({
|
||||
search: 'in',
|
||||
})).toStrictEqual(expectedResponse);
|
||||
});
|
||||
|
||||
it('should raise 4xx errors', async () => {
|
||||
const expectedResponse = {
|
||||
status: 429,
|
||||
|
@ -539,46 +293,6 @@ describe('holidayapi', () => {
|
|||
})).toStrictEqual(expectedResponse);
|
||||
});
|
||||
|
||||
it('should error when country is missing', async () => {
|
||||
expect.assertions(1);
|
||||
|
||||
try {
|
||||
await holidayapi.workday();
|
||||
} catch (err) {
|
||||
expect(err.message).toMatch(/missing country/i);
|
||||
}
|
||||
});
|
||||
|
||||
it('should error when start is missing', async () => {
|
||||
expect.assertions(1);
|
||||
|
||||
try {
|
||||
await holidayapi.workday({ country: 'US' });
|
||||
} catch (err) {
|
||||
expect(err.message).toMatch(/missing start date/i);
|
||||
}
|
||||
});
|
||||
|
||||
it('should error when days is missing', async () => {
|
||||
expect.assertions(1);
|
||||
|
||||
try {
|
||||
await holidayapi.workday({ country: 'US', start: '2019-07-01' });
|
||||
} catch (err) {
|
||||
expect(err.message).toMatch(/missing days/i);
|
||||
}
|
||||
});
|
||||
|
||||
it('should error when days is negative', async () => {
|
||||
expect.assertions(1);
|
||||
|
||||
try {
|
||||
await holidayapi.workday({ country: 'US', start: '2019-07-01', days: -10 });
|
||||
} catch (err) {
|
||||
expect(err.message).toMatch(/days must be 1 or more/i);
|
||||
}
|
||||
});
|
||||
|
||||
it('should raise 4xx errors', async () => {
|
||||
const expectedResponse = {
|
||||
status: 429,
|
||||
|
@ -632,36 +346,6 @@ describe('holidayapi', () => {
|
|||
})).toStrictEqual(expectedResponse);
|
||||
});
|
||||
|
||||
it('should error when country is missing', async () => {
|
||||
expect.assertions(1);
|
||||
|
||||
try {
|
||||
await holidayapi.workdays();
|
||||
} catch (err) {
|
||||
expect(err.message).toMatch(/missing country/i);
|
||||
}
|
||||
});
|
||||
|
||||
it('should error when start is missing', async () => {
|
||||
expect.assertions(1);
|
||||
|
||||
try {
|
||||
await holidayapi.workdays({ country: 'US' });
|
||||
} catch (err) {
|
||||
expect(err.message).toMatch(/missing start date/i);
|
||||
}
|
||||
});
|
||||
|
||||
it('should error when end is missing', async () => {
|
||||
expect.assertions(1);
|
||||
|
||||
try {
|
||||
await holidayapi.workdays({ country: 'US', start: '2019-07-01' });
|
||||
} catch (err) {
|
||||
expect(err.message).toMatch(/missing end date/i);
|
||||
}
|
||||
});
|
||||
|
||||
it('should raise 4xx errors', async () => {
|
||||
const expectedResponse = {
|
||||
status: 429,
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
"strict": true,
|
||||
"removeComments": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true
|
||||
"noUnusedParameters": true,
|
||||
"useUnknownInCatchVariables": false
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue