diff --git a/.changeset/two-poets-relate.md b/.changeset/two-poets-relate.md new file mode 100644 index 0000000..966eaef --- /dev/null +++ b/.changeset/two-poets-relate.md @@ -0,0 +1,5 @@ +--- +'@untidy/thetvdb': minor +--- + +feat: support `/companies` endpoint diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 65a2d45..0f647ce 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -23,7 +23,7 @@ jobs: - name: Setup pnpm uses: pnpm/action-setup@v2.4.0 with: - version: 8.9.0 + version: 8.9.2 - name: Setup Node uses: actions/setup-node@v3.8.1 diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index e077d49..e290c90 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -11,7 +11,7 @@ export default defineConfig({ nav: [ { text: 'Guide', link: '/guide/getting-started' }, { - text: '0.3.0', + text: '0.4.0', items: [ { text: 'Changelog', diff --git a/docs/api/thetvdb.md b/docs/api/thetvdb.md index 49d0ced..d80660c 100644 --- a/docs/api/thetvdb.md +++ b/docs/api/thetvdb.md @@ -216,6 +216,68 @@ Returns a character base record await client.getCharacter('64140522'); ``` +## getCompanies + +Returns a paginated list of companies records + +| params | type | Required | Description | +| ------ | -------- | :------: | ------------------------------------ | +| page | `string` | Optional | The `page` of the Companies records. | + +### Supported endpoint + +| method | endpoint | +| ------------------------------- | ------------ | +| | `/companies` | + +### First 500 Companies records + +```js +await client.getCompanies(); +``` + +### Companies records for the page 94 + +```js +await client.getCompanies('94'); +``` + +## getCompaniesTypes + +This method returns a list of companies records and does not require any parameters. + +### Supported endpoint + +| method | endpoint | +| ------------------------------- | ------------------ | +| | `/companies/types` | + +### Companies types records + +```js +await client.getCompaniesTypes(); +``` + +## getCompanyById + +Returns a company record + +| params | type | Required | Description | +| ------ | -------- | :------: | ------------------------ | +| id | `string` | Yes | The `id` of the Company. | + +### Supported endpoint + +| method | endpoint | +| ------------------------------- | ---------------- | +| | `/companies/:id` | + +### Single company record + +```js +await client.getCompanyById('4'); +``` + ## getEpisode Returns an episode base or extended record diff --git a/docs/guide/supported-endpoints.md b/docs/guide/supported-endpoints.md index fd54438..3206e8c 100644 --- a/docs/guide/supported-endpoints.md +++ b/docs/guide/supported-endpoints.md @@ -23,9 +23,9 @@ List of endpoints from [TheTVDB API V4](https://thetvdb.github.io/v4-api/). | `/awards/categories/{id}` | :white_check_mark: | | `/awards/categories/{id}/extended` | :white_check_mark: | | `/characters/{id}` | :white_check_mark: | -| `/companies` | :interrobang: | -| `/companies/types` | :interrobang: | -| `/companies/{id}` | :interrobang: | +| `/companies` | :white_check_mark: | +| `/companies/types` | :white_check_mark: | +| `/companies/{id}` | :white_check_mark: | | `/content/ratings` | :white_check_mark: | | `/countries` | :white_check_mark: | | `/entities` | :interrobang: | diff --git a/src/main.ts b/src/main.ts index cdc7770..2b81780 100644 --- a/src/main.ts +++ b/src/main.ts @@ -142,6 +142,29 @@ interface Character extends SharedProps { personImgURL: string | null; } +interface Company extends Omit { + activeDate: string; + aliases: Aliases[]; + country: string; + inactiveDate: string; + primaryCompanyType: number; + slug: string; + parentCompany: { + id: number; + name: string; + relation: { + id: number; + typeName: string; + }; + }; + tagOptions: TagOptions[]; +} + +interface CompanyType { + companyTypeId: number; + companyTypeName: string; +} + interface Episode extends SharedProps { seriesId: number; aired: string | null; @@ -410,6 +433,9 @@ type GetAwardsCategoriesById = Data; type GetAwardsCategoriesByIdExtended = Data; type GetCharacter = Data; +type GetCompanies = DataLink; +type GetCompaniesTypes = Data; +type GetCompanyById = Data; type GetFilteredMovie = DataLink; @@ -509,6 +535,24 @@ export class TheTVDB extends Base { return await this.fetcher(endpoint); } + public async getCompanies(page?: string): Promise { + let endpoint = this.api + '/v4/companies'; + if (typeof page === 'string' && page.length > 0 && page.length < 3) { + endpoint += `?page=${page}`; + } + return await this.fetcher(endpoint); + } + + public async getCompaniesTypes(): Promise { + return await this.fetcher(this.api + '/v4/companies/types'); + } + + public async getCompanyById(id: string): Promise { + this.validateInput(id, 'Required company id'); + + return await this.fetcher(`${this.api}/v4/companies/${id}`); + } + public async getFilteredMovie(options: FilterOptions): Promise { this.validateInput(options?.country, 'Required country of origin'); this.validateInput(options?.lang, 'Required language'); diff --git a/src/playground.ts b/src/playground.ts index 9d2f4da..386eea7 100644 --- a/src/playground.ts +++ b/src/playground.ts @@ -1,7 +1,7 @@ import { config } from 'dotenv'; import { join, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; -import { TheTVDB, TheTVDBExtended } from './index.js'; +import { TheTVDB } from './index.js'; const ROOT_DIR = resolve(fileURLToPath(import.meta.url), '../..'); const ENVFILE = join(ROOT_DIR, '.env'); @@ -10,10 +10,11 @@ config({ path: ENVFILE }); const TOKEN = process.env.TVDB_API_TOKEN; const client = new TheTVDB(TOKEN); +/* const clientExtended = new TheTVDBExtended(TOKEN); const langs = await clientExtended.getLanguages(); -console.log(langs); +console.log(langs); */ -const movie = await client.getMovie({ id: '12586' }); +const movie = await client.getCompanies('94'); console.log(movie); diff --git a/tests/main.test.ts b/tests/main.test.ts index e5d39cd..7f84731 100644 --- a/tests/main.test.ts +++ b/tests/main.test.ts @@ -85,6 +85,49 @@ describe('getCharacter()', () => { }); }); +describe('getCompanies()', () => { + test('returns a successful response without a page', async () => { + const { data } = await client.getCompanies(); + expect(Array.isArray(data)).toBe(true); + expect(data).toHaveLength(1); + expect(data[0]?.id).toBe(48649); + expect(data[0]?.name).toBe('Ananey'); + }); + + test('returns a successful response with page', async () => { + const { data } = await client.getCompanies('94'); + expect(Array.isArray(data)).toBe(true); + expect(data).toHaveLength(2); + expect(data[0]?.id).toBe(48646); + expect(data[1]?.name).toBe('New Group Productions'); + }); +}); + +describe('getCompaniesTypes()', () => { + test('returns a successful response', async () => { + const { data } = await client.getCompaniesTypes(); + expect(Array.isArray(data)).toBe(true); + expect(data).toHaveLength(2); + expect(data[0]?.companyTypeId).toBe(1); + expect(data[1]?.companyTypeName).toBe('Studio'); + }); +}); + +describe('getCompanyById()', () => { + it('throws an error if no id is provided', async () => { + // @ts-expect-error: expect a parameter id + await expect(async () => await client.getCompanyById()).rejects.toThrow('Required company id'); + }); + + test('returns a successful response', async () => { + const { data } = await client.getCompanyById('4'); + + expect(data.id).toBe(4); + expect(data.name).toBe('Aaj TV'); + expect(data.country).toBe('pak'); + }); +}); + describe('getEpisode()', () => { it('throws an error if no id is provided', async () => { // @ts-expect-error: expect a parameter id diff --git a/tests/mocks/handlers.ts b/tests/mocks/handlers.ts index b61b799..2407aba 100644 --- a/tests/mocks/handlers.ts +++ b/tests/mocks/handlers.ts @@ -10,6 +10,10 @@ import { awardsId, awardsIdExtended, character, + companies, + companiesPage, + companiesTypes, + companyId, contentRatings, countries, episodes, @@ -64,6 +68,21 @@ export const handlers: RestHandler[] = [ rest.get('https://api4.thetvdb.com/v4/awards', async (_req, res, ctx) => { return await res(ctx.json(awards)); }), + rest.get('https://api4.thetvdb.com/v4/companies', async (req, res, ctx) => { + if (req.url.href === 'https://api4.thetvdb.com/v4/companies?page=94') { + return await res(ctx.json(companiesPage)); + } else { + return await res(ctx.json(companies)); + } + }), + rest.get('https://api4.thetvdb.com/v4/companies/:path', async (req, res, ctx) => { + switch (req.url.href) { + case 'https://api4.thetvdb.com/v4/companies/types': + return await res(ctx.json(companiesTypes)); + default: + return await res(ctx.json(companyId)); + } + }), rest.get('https://api4.thetvdb.com/v4/content/ratings', async (_req, res, ctx) => { return await res(ctx.json(contentRatings)); }), diff --git a/tests/mocks/response.ts b/tests/mocks/response.ts index 7fe7cf2..e7bb02b 100644 --- a/tests/mocks/response.ts +++ b/tests/mocks/response.ts @@ -1,16 +1,12 @@ // https://api4.thetvdb.com/v4/artwork/63237874/extended const artworkExtended = { - data: { - movieId: 145830, - }, + data: { movieId: 145830 }, }; // https://api4.thetvdb.com/v4/artwork/63237874 const artwork = { status: 'success', - data: { - id: 63237874, - }, + data: { id: 63237874 }, }; // https://api4.thetvdb.com/v4/artwork/statuses @@ -22,86 +18,84 @@ const artworkStatuses = { // https://api4.thetvdb.com/v4/artwork/types const artworkTypes = { status: 'success', - data: [ - { - thumbHeight: 140, - }, - { - id: 2, - imageFormat: 'JPG', - }, - ], + data: [{ thumbHeight: 140 }, { id: 2, imageFormat: 'JPG' }], }; // https://api4.thetvdb.com/v4/awards const awards = { status: 'success', - data: [ - { - id: 1, - name: 'Academy Awards', - }, - ], + data: [{ id: 1, name: 'Academy Awards' }], }; // https://api4.thetvdb.com/v4/awards/1 const awardsId = { - data: { - id: 1, - name: 'Academy Awards', - }, + data: { id: 1, name: 'Academy Awards' }, }; // https://api4.thetvdb.com/v4/awards/1/extended const awardsIdExtended = { data: { - categories: [ - { - id: 1, - name: 'Best Picture', - }, - ], + categories: [{ id: 1, name: 'Best Picture' }], }, }; // https://api4.thetvdb.com/v4/awards/categories/42 const awardsCategoryId = { - data: { - id: 42, - name: 'Best Actor in a Television Series – Drama', - }, + data: { id: 42, name: 'Best Actor in a Television Series – Drama' }, }; // https://api4.thetvdb.com/v4/awards/categories/42/extended const awardsCategoryIdExtended = { data: { - nominees: [ - { - id: 6352, - isWinner: true, - }, - ], + nominees: [{ id: 6352, isWinner: true }], }, }; // https://api4.thetvdb.com/v4/characters/64140522 const character = { - data: { - id: 64140522, - name: 'Spike Spiegel', - }, + data: { id: 64140522, name: 'Spike Spiegel' }, }; -// https://api4.thetvdb.com/v4/content/ratings -const contentRatings = { - status: 'success', +// https://api4.thetvdb.com/v4/companies +const companies = { + data: [{ id: 48649, name: 'Ananey' }], +}; + +// https://api4.thetvdb.com/v4/companies?page=94 +const companiesPage = { data: [ { - name: 'ATP', + id: 48646, + }, + { + name: 'New Group Productions', }, ], }; +// https://api4.thetvdb.com/v4/companies/types +const companiesTypes = { + data: [ + { + companyTypeId: 1, + }, + { + companyTypeName: 'Studio', + }, + ], +}; + +// https://api4.thetvdb.com/v4/companies/4 +const companyId = { + data: { id: 4, name: 'Aaj TV', country: 'pak' }, +}; + +// https://api4.thetvdb.com/v4/content/ratings +const contentRatings = { + status: 'success', + data: [{ name: 'ATP' }], +}; + // https://api4.thetvdb.com/v4/countries const countries = { status: 'success', @@ -312,35 +306,22 @@ const movieEM = { // https://api4.thetvdb.com/v4/movies/3646/extended?short=true const movieES = { - data: { - characters: null, - artworks: null, - trailers: null, - }, + data: { characters: null, artworks: null, trailers: null }, }; // https://api4.thetvdb.com/v4/movies/3646/extended const movieE = { data: { trailers: [ - { - id: 143117, - language: 'spa', - }, - { - id: 143118, - language: 'eng', - }, + { id: 143117, language: 'spa' }, + { id: 143118, language: 'eng' }, ], }, }; // https://api4.thetvdb.com/v4/movies/12586 const movie = { - data: { - id: 12586, - slug: 'macross-do-you-remember-love', - }, + data: { id: 12586, slug: 'macross-do-you-remember-love' }, }; // https://api4.thetvdb.com/v4/seasons/6365/extended?meta=translations @@ -462,6 +443,10 @@ export { awardsId, awardsIdExtended, character, + companies, + companiesPage, + companiesTypes, + companyId, contentRatings, countries, episodes,