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,