mirror of
https://github.com/holidayapi/holidayapi-node.git
synced 2025-06-21 12:36:33 +00:00
Merge pull request #6 from holidayapi/development-v2
feat: port to typescript
This commit is contained in:
parent
b6ad36a075
commit
4886f14bc3
21 changed files with 7096 additions and 111 deletions
83
src/holidayapi.ts
Normal file
83
src/holidayapi.ts
Normal 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
9
src/index.ts
Normal 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
81
src/types.ts
Normal 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,
|
||||
}[],
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue