Merge pull request #6 from holidayapi/development-v2

feat: port to typescript
This commit is contained in:
Josh Sherman 2019-09-09 22:30:30 -05:00 committed by GitHub
parent b6ad36a075
commit 4886f14bc3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 7096 additions and 111 deletions

83
src/holidayapi.ts Normal file
View file

@ -0,0 +1,83 @@
/**
* Copyright (c) Gravity Boulevard, LLC
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import fetch from 'node-fetch';
import { URL, URLSearchParams } from 'url';
import {
CountriesResponse, Endpoint, HolidaysResponse, HolidaysRequest,
LanguagesResponse, Request, Requests, Responses,
} from './types';
export class HolidayAPI {
baseUrl: string;
key: string;
constructor({ key, version = 1 }: { key?: string, version?: number }) {
const getYours = 'get yours at HolidayAPI.com';
const uuidRegExp = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/;
if (!key) {
throw new Error(`Missing API key, ${getYours}`);
}
if (!uuidRegExp.test(key)) {
throw new Error(`Invalid API key, ${getYours}`);
}
if (version !== 1) {
throw new Error('Invalid version number, expected "1"');
}
this.baseUrl = `https://holidayapi.com/v${version}/`;
this.key = key;
}
private createUrl(endpoint: Endpoint, request?: Requests): string {
const parameters = { key: this.key, ...request } as any;
const url = new URL(endpoint, this.baseUrl);
url.search = new URLSearchParams(parameters).toString();
return url.toString();
}
private async request(endpoint: Endpoint, request?: Requests): Promise<Responses> {
const response = await fetch(this.createUrl(endpoint, request));
let payload;
try {
payload = await response.json();
} catch (err) {
payload = {};
}
if (!response.ok) {
throw new Error(payload.error || response.statusText);
}
return payload;
}
async countries(request?: Request): Promise<CountriesResponse> {
return this.request('countries', request);
}
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);
}
async languages(request?: Request): Promise<LanguagesResponse> {
return this.request('languages', request);
}
}

9
src/index.ts Normal file
View file

@ -0,0 +1,9 @@
/**
* Copyright (c) Gravity Boulevard, LLC
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
export * from './types';
export * from './holidayapi';

81
src/types.ts Normal file
View file

@ -0,0 +1,81 @@
/**
* Copyright (c) Gravity Boulevard, LLC
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
export type Endpoint = 'countries' | 'holidays' | 'languages';
export type Request = {
key?: string,
format?: 'csv' | 'json' | 'php' | 'tsv' | 'yaml' | 'xml',
pretty?: boolean,
};
export type Requests = Request | HolidaysRequest;
export type HolidaysRequest = Request & {
country?: string,
year?: number,
day?: number,
month?: number,
language?: string,
previous?: boolean,
public?: boolean,
search?: string,
subdivisions?: boolean,
upcoming?: boolean,
};
export type Response = {
requests: {
available: number,
resets: Date,
used: number,
},
status: number,
error?: string,
};
export type Responses = (
CountriesResponse | HolidaysResponse | LanguagesResponse
);
export type CountriesResponse = Response & {
countries?: {
code: string,
codes: {
'alpha-2': string,
'alpha-3': string,
numeric: string,
},
flag: string,
languages: string[],
name: string,
subdivisions: {
code: string,
languages: string[],
name: string,
}[],
}[],
};
export type HolidaysResponse = Response & {
holidays?: {
country: string,
date: Date,
name: string,
observed: Date,
public: boolean,
uuid: string,
subdivisions?: string[],
}[],
};
export type LanguagesResponse = Response & {
languages?: {
code: string,
name: string,
}[],
};