feat: pull country or language by code.

* feat: pull country or language by code.

This differs from the existing `search` functionality in that it allows
you to explicitly pull back a single country or language instead of
anything that matches (which could result in more items returned than
expected).

* refactor(types): add new types for the affected endpoints.
* docs(readme): update to include examples for new functionality.
* test: expand tests to include new parameters.
* feat(package): upgrade dependencies to the latest versions.
* fix(eslint): adjust configuration based on an updated dependency.
* docs(license): bump the year of the license.
This commit is contained in:
Josh Sherman 2020-02-11 18:46:30 -06:00
parent 9b40c4050e
commit 17a7914fdc
No known key found for this signature in database
GPG key ID: 55B058A80530EF22
10 changed files with 4543 additions and 1958 deletions

View file

@ -1,35 +1,44 @@
{
"env": {
"browser": true,
"es6": true,
"jest/globals": true,
"node": true
},
"extends": [
"airbnb-base",
"plugin:import/typescript"
"env": {
"es6": true,
"jest/globals": true,
"node": true
},
"extends": [
"airbnb-base",
"plugin:import/typescript"
],
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module"
},
"plugins": [
"@typescript-eslint",
"jest"
],
"rules": {
"@typescript-eslint/no-unused-vars": "error",
"import/extensions": [
"error",
"always",
{
"ts": "never",
"tsx": "never"
}
],
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module"
},
"plugins": [
"@typescript-eslint",
"jest"
"import/no-extraneous-dependencies": [
"error",
{
"devDependencies": ["**/*.test.ts"]
}
],
"rules": {
"@typescript-eslint/no-unused-vars": "error",
"import/no-extraneous-dependencies": [
"error",
{ "devDependencies": ["**/*.test.ts"] }
],
"import/prefer-default-export": "off",
"lines-between-class-members": "off",
"no-unused-vars": "off"
}
"import/prefer-default-export": "off",
"lines-between-class-members": "off",
"no-unused-vars": "off"
}
}

View file

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2016, 2017, 2018, 2019 Gravity Boulevard, LLC
Copyright (c) 2016, 2017, 2018, 2019, 2020 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

View file

@ -103,7 +103,15 @@ holidayApi.holidays({ country: 'US', year: 2019 })
holidayApi.countries();
```
#### Search for a country by code or name
#### Fetch a supported country by code
```javascript
holidayApi.countries({
country: 'NO',
});
```
#### Search for countries by code or name
```javascript
holidayApi.countries({
@ -119,7 +127,15 @@ holidayApi.countries({
holidayApi.languages();
```
#### Search for a language by code or name
#### Fetch a supported language by code
```javascript
holidayApi.language({
language: 'es',
});
```
#### Search for languages by code or name
```javascript
holidayApi.language({

View file

@ -1,4 +1,4 @@
import { CountriesResponse, HolidaysResponse, HolidaysRequest, LanguagesResponse, Request } from './types';
import { CountriesRequest, CountriesResponse, HolidaysResponse, HolidaysRequest, LanguagesRequest, LanguagesResponse } from './types';
export declare class HolidayAPI {
baseUrl: string;
key: string;
@ -8,7 +8,7 @@ export declare class HolidayAPI {
});
private createUrl;
private request;
countries(request?: Request): Promise<CountriesResponse>;
countries(request?: CountriesRequest): Promise<CountriesResponse>;
holidays(request?: HolidaysRequest): Promise<HolidaysResponse>;
languages(request?: Request): Promise<LanguagesResponse>;
languages(request?: LanguagesRequest): Promise<LanguagesResponse>;
}

11
dist/types.d.ts vendored
View file

@ -1,11 +1,14 @@
export declare type Endpoint = 'countries' | 'holidays' | 'languages';
export declare type Request = {
declare type Request = {
format?: 'csv' | 'json' | 'php' | 'tsv' | 'yaml' | 'xml';
key?: string;
pretty?: boolean;
search?: string;
};
export declare type Requests = Request | HolidaysRequest;
export declare type Requests = CountriesRequest | HolidaysRequest | LanguagesRequest;
export declare type CountriesRequest = Request & {
country?: string;
};
export declare type HolidaysRequest = Request & {
country?: string;
day?: number;
@ -17,6 +20,9 @@ export declare type HolidaysRequest = Request & {
upcoming?: boolean;
year?: number;
};
export declare type LanguagesRequest = Request & {
language?: string;
};
export declare type Response = {
requests: {
available: number;
@ -62,3 +68,4 @@ export declare type LanguagesResponse = Response & {
name: string;
}[];
};
export {};

6278
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
{
"name": "holidayapi",
"version": "3.0.0",
"version": "3.1.0",
"description": "Official Node.js library for Holiday API",
"main": "dist/index.js",
"types": "dist/index.d.ts",
@ -24,26 +24,28 @@
"node": ">= 8.0.0"
},
"devDependencies": {
"@types/jest": "^24.0.22",
"@types/jest": "^25.1.2",
"@types/nock": "^11.1.0",
"@types/node": "^12.12.7",
"@types/node-fetch": "^2.5.3",
"@typescript-eslint/eslint-plugin": "^2.7.0",
"@typescript-eslint/parser": "^2.7.0",
"coveralls": "^3.0.7",
"eslint": "^6.6.0",
"@types/node": "^13.7.1",
"@types/node-fetch": "^2.5.4",
"@typescript-eslint/eslint-plugin": "^2.19.2",
"@typescript-eslint/parser": "^2.19.2",
"coveralls": "^3.0.9",
"eslint": "^6.8.0",
"eslint-config-airbnb-base": "^14.0.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-jest": "^23.0.3",
"jest": "^24.9.0",
"nock": "^11.7.0",
"ts-jest": "^24.1.0",
"typescript": "^3.7.2"
"eslint-plugin-import": "^2.20.1",
"eslint-plugin-jest": "^23.7.0",
"jest": "^25.1.0",
"nock": "^11.8.2",
"ts-jest": "^25.2.0",
"typescript": "^3.7.5"
},
"dependencies": {
"node-fetch": "^2.6.0"
},
"scripts": {
"build": "tsc",
"lint": "eslint --ext .js,.ts src/ tests/",
"test": "jest --coverage --coverageReporters=text-lcov | coveralls"
}
}

View file

@ -8,8 +8,8 @@
import fetch from 'node-fetch';
import { URL, URLSearchParams } from 'url';
import {
CountriesResponse, Endpoint, HolidaysResponse, HolidaysRequest,
LanguagesResponse, Request, Requests, Responses,
CountriesRequest, CountriesResponse, Endpoint, HolidaysResponse,
HolidaysRequest, LanguagesRequest, LanguagesResponse, Requests, Responses,
} from './types';
export class HolidayAPI {
@ -61,7 +61,7 @@ export class HolidayAPI {
return payload;
}
async countries(request?: Request): Promise<CountriesResponse> {
async countries(request?: CountriesRequest): Promise<CountriesResponse> {
return this.request('countries', request);
}
@ -77,7 +77,7 @@ export class HolidayAPI {
return this.request('holidays', request);
}
async languages(request?: Request): Promise<LanguagesResponse> {
async languages(request?: LanguagesRequest): Promise<LanguagesResponse> {
return this.request('languages', request);
}
}

View file

@ -7,14 +7,18 @@
export type Endpoint = 'countries' | 'holidays' | 'languages';
export type Request = {
type Request = {
format?: 'csv' | 'json' | 'php' | 'tsv' | 'yaml' | 'xml',
key?: string,
pretty?: boolean,
search?: string,
};
export type Requests = Request | HolidaysRequest;
export type Requests = CountriesRequest | HolidaysRequest | LanguagesRequest;
export type CountriesRequest = Request & {
country?: string,
};
export type HolidaysRequest = Request & {
country?: string,
@ -28,6 +32,10 @@ export type HolidaysRequest = Request & {
year?: number,
};
export type LanguagesRequest = Request & {
language?: string,
};
export type Response = {
requests: {
available: number,

View file

@ -93,6 +93,47 @@ describe('holidayapi', () => {
expect(await holidayapi.countries()).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,
@ -349,6 +390,28 @@ 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,