1 Commits

Author SHA1 Message Date
Blake Joynes
eb4e707ff9 add test actions 2023-04-15 14:32:11 -04:00
14 changed files with 107 additions and 96 deletions

View File

@@ -0,0 +1,18 @@
name: GitHub Actions Demo
run-name: ${{ github.actor }} is testing out GitHub Actions 🚀
on: [push]
jobs:
Explore-GitHub-Actions:
runs-on: ubuntu-latest
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!"
- run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
- name: Check out repository code
uses: actions/checkout@v3
- run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner."
- run: echo "🖥️ The workflow is now ready to test your code on the runner."
- name: List files in the repository
run: |
ls ${{ github.workspace }}
- run: echo "🍏 This job's status is ${{ job.status }}."

View File

@@ -1,33 +0,0 @@
# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
# For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
name: Node.js Package
on:
release:
types: [created]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
- run: npm ci
- run: npm test
publish-npm:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
registry-url: https://registry.npmjs.org/
- run: npm ci
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{secrets.npm_token}}

View File

@@ -1,6 +1,6 @@
{
"name": "tmdb-ts",
"version": "0.2.0",
"version": "0.1.9",
"description": "TMDB v3 library wrapper",
"main": "dist/index.js",
"types": "dist/index.d.ts",

View File

@@ -1,5 +1,4 @@
import fetch from 'cross-fetch';
import { parseOptions } from './utils';
const BASE_URL_V3 = 'https://api.themoviedb.org/3';
@@ -8,9 +7,8 @@ export default class Api {
this.accessToken = accessToken;
}
async get<T>(path: string, options?: Record<string, any>): Promise<T> {
const params = parseOptions(options);
const response = await fetch(`${BASE_URL_V3}${path}?${params}`, {
async get<T>(path: string): Promise<T> {
const response = await fetch(`${BASE_URL_V3}${path}`, {
method: 'GET',
headers: {
Authorization: `Bearer ${this.accessToken}`,

View File

@@ -1,5 +1,6 @@
import { BaseEndpoint } from './base';
import { ChangeOptions, Changes } from '../types/changes';
import { parseOptions } from '../utils';
export class ChangeEndpoint extends BaseEndpoint {
constructor(protected readonly accessToken: string) {
@@ -7,14 +8,17 @@ export class ChangeEndpoint extends BaseEndpoint {
}
async movies(options?: ChangeOptions): Promise<Changes> {
return await this.api.get<Changes>(`/movie/changes`, options);
const params = parseOptions(options);
return await this.api.get<Changes>(`/movie/changes?${params}`);
}
async tvShows(options?: ChangeOptions): Promise<Changes> {
return await this.api.get<Changes>(`/tv/changes`, options);
const params = parseOptions(options);
return await this.api.get<Changes>(`/tv/changes?${params}`);
}
async person(options?: ChangeOptions): Promise<Changes> {
return await this.api.get<Changes>(`/person/change`, options);
const params = parseOptions(options);
return await this.api.get<Changes>(`/person/changes${params}`);
}
}

View File

@@ -4,6 +4,7 @@ import {
LanguageOption,
Translations,
} from '../types';
import { parseOptions } from '../utils';
import { BaseEndpoint } from './base';
const BASE_COLLECTION = '/collection';
@@ -17,16 +18,16 @@ export class CollectionsEndpoint extends BaseEndpoint {
id: number,
options?: LanguageOption
): Promise<DetailedCollection> {
const params = parseOptions(options);
return await this.api.get<DetailedCollection>(
`${BASE_COLLECTION}/${id}`,
options
`${BASE_COLLECTION}/${id}?${params}`
);
}
async images(id: number, options?: LanguageOption): Promise<ImageCollection> {
const params = parseOptions(options);
return await this.api.get<ImageCollection>(
`${BASE_COLLECTION}/${id}/images`,
options
`${BASE_COLLECTION}/${id}/images?${params}`
);
}
@@ -34,9 +35,9 @@ export class CollectionsEndpoint extends BaseEndpoint {
id: number,
options?: LanguageOption
): Promise<Translations> {
const params = parseOptions(options);
return await this.api.get<Translations>(
`${BASE_COLLECTION}/${id}/translations`,
options
`${BASE_COLLECTION}/${id}/translations?${params}`
);
}
}

View File

@@ -3,6 +3,7 @@ import {
SortOption,
TvShowDiscoverResult,
} from '../types';
import { parseOptions } from '../utils';
import { BaseEndpoint } from './base';
const BASE_DISCOVER = '/discover';
@@ -69,16 +70,16 @@ export class DiscoverEndpoint extends BaseEndpoint {
}
async movie(options?: MovieQueryOptions): Promise<MovieDiscoverResult> {
const params = parseOptions(options);
return await this.api.get<MovieDiscoverResult>(
`${BASE_DISCOVER}/movie`,
options
`${BASE_DISCOVER}/movie?${params}`
);
}
async tvShow(options?: TvShowQueryOptions): Promise<TvShowDiscoverResult> {
const params = parseOptions(options);
return await this.api.get<TvShowDiscoverResult>(
`${BASE_DISCOVER}/tv`,
options
`${BASE_DISCOVER}/tv?${params}`
);
}
}

View File

@@ -1,5 +1,6 @@
import { BaseEndpoint } from './base';
import { ExternalIdOptions, FindResult } from '../types';
import { parseOptions } from '../utils';
export class FindEndpoint extends BaseEndpoint {
constructor(accessToken: string) {
@@ -10,6 +11,7 @@ export class FindEndpoint extends BaseEndpoint {
externalId: string,
options: ExternalIdOptions
): Promise<FindResult> {
return await this.api.get<FindResult>(`/find/${externalId}`, options);
const params = parseOptions(options);
return await this.api.get<FindResult>(`/find/${externalId}?${params}`);
}
}

View File

@@ -1,5 +1,6 @@
import { BaseEndpoint } from './base';
import { BelongingMovies, Keyword, KeywordsOptions } from '../types';
import { parseOptions } from '../utils';
const BASE_Keyword = '/keyword';
@@ -16,9 +17,9 @@ export class KeywordsEndpoint extends BaseEndpoint {
keywordId: number,
options?: KeywordsOptions
): Promise<BelongingMovies> {
const params = parseOptions(options);
return await this.api.get<BelongingMovies>(
`${BASE_Keyword}/${keywordId}/movies`,
options
`${BASE_Keyword}/${keywordId}/movies?${params}`
);
}
}

View File

@@ -25,6 +25,7 @@ import {
Videos,
WatchProviders,
} from '../types';
import { parseOptions } from '../utils';
const BASE_MOVIE = '/movie';
@@ -44,9 +45,9 @@ export class MoviesEndpoint extends BaseEndpoint {
}
async changes(id: number, options?: ChangeOptions): Promise<MovieChanges> {
const params = parseOptions(options);
return await this.api.get<MovieChanges>(
`${BASE_MOVIE}/${id}/changes`,
options
`${BASE_MOVIE}/${id}/changes?${params}`
);
}
@@ -70,16 +71,19 @@ export class MoviesEndpoint extends BaseEndpoint {
id: number,
options?: LanguageOption | PageOption
): Promise<MovieLists> {
return await this.api.get<MovieLists>(`${BASE_MOVIE}/${id}/lists`, options);
const params = parseOptions(options);
return await this.api.get<MovieLists>(
`${BASE_MOVIE}/${id}/lists?${params}`
);
}
async recommendations(
id: number,
options?: PageOption
): Promise<Recommendations> {
const params = parseOptions(options);
return await this.api.get<Recommendations>(
`${BASE_MOVIE}/${id}/recommendations`,
options
`${BASE_MOVIE}/${id}/recommendations?${params}`
);
}
@@ -90,13 +94,14 @@ export class MoviesEndpoint extends BaseEndpoint {
}
async reviews(id: number, options?: PageOption): Promise<Reviews> {
return await this.api.get<Reviews>(`${BASE_MOVIE}/${id}/reviews`, options);
const params = parseOptions(options);
return await this.api.get<Reviews>(`${BASE_MOVIE}/${id}/reviews?${params}`);
}
async similar(id: number, options?: PageOption): Promise<SimilarMovies> {
const params = parseOptions(options);
return await this.api.get<SimilarMovies>(
`${BASE_MOVIE}/${id}/similar`,
options
`${BASE_MOVIE}/${id}/similar?${params}`
);
}
@@ -125,31 +130,32 @@ export class MoviesEndpoint extends BaseEndpoint {
async nowPlaying(
options?: PageOption & LanguageOption & RegionOption
): Promise<MoviesPlayingNow> {
const params = parseOptions(options);
return await this.api.get<MoviesPlayingNow>(
`${BASE_MOVIE}/now_playing`,
options
`${BASE_MOVIE}/now_playing?${params}`
);
}
async popular(options?: PageOption): Promise<PopularMovies> {
return await this.api.get<PopularMovies>(`${BASE_MOVIE}/popular`, options);
const params = parseOptions(options);
return await this.api.get<PopularMovies>(`${BASE_MOVIE}/popular?${params}`);
}
async topRated(
options?: PageOption & LanguageOption & RegionOption
): Promise<TopRatedMovies> {
const params = parseOptions(options);
return await this.api.get<TopRatedMovies>(
`${BASE_MOVIE}/top_rated`,
options
`${BASE_MOVIE}/top_rated?${params}`
);
}
async upcoming(
options?: PageOption & LanguageOption & RegionOption
): Promise<UpcomingMovies> {
const params = parseOptions(options);
return await this.api.get<UpcomingMovies>(
`${BASE_MOVIE}/upcoming`,
options
`${BASE_MOVIE}/upcoming?${params}`
);
}
}

View File

@@ -12,6 +12,7 @@ import {
PopularPersons,
TaggedImages,
} from '../types';
import { parseOptions } from '../utils';
import { BaseEndpoint } from './base';
const BASE_PERSON = '/person';
@@ -26,9 +27,9 @@ export class PeopleEndpoint extends BaseEndpoint {
}
async changes(id: number, options?: ChangeOptions): Promise<PersonChanges> {
const params = parseOptions(options);
return await this.api.get<PersonChanges>(
`${BASE_PERSON}/${id}/changes`,
options
`${BASE_PERSON}/${id}/changes?${params}`
);
}
@@ -61,9 +62,9 @@ export class PeopleEndpoint extends BaseEndpoint {
}
async taggedImages(id: number, options?: PageOption): Promise<TaggedImages> {
const params = parseOptions(options);
return await this.api.get<TaggedImages>(
`${BASE_PERSON}/${id}/tagged_images`,
options
`${BASE_PERSON}/${id}/tagged_images?${params}`
);
}
@@ -78,9 +79,9 @@ export class PeopleEndpoint extends BaseEndpoint {
}
async popular(options?: PageOption): Promise<PopularPersons> {
const params = parseOptions(options);
return await this.api.get<PopularPersons>(
`${BASE_PERSON}/popular`,
options
`${BASE_PERSON}/popular?${params}`
);
}
}

View File

@@ -1,6 +1,7 @@
import { BaseEndpoint } from './base';
import { Search } from '../types/search';
import { Collection, Company, Movie, Person, TV } from '../types';
import { parseOptions } from '../utils';
const BASE_SEARCH = '/search';
@@ -30,39 +31,44 @@ export class SearchEndpoint extends BaseEndpoint {
}
async companies(options: SearchOptions): Promise<Search<Company>> {
const params = parseOptions(options);
return await this.api.get<Search<Company>>(
`${BASE_SEARCH}/company`,
options
`${BASE_SEARCH}/company?${params}`
);
}
async collections(options: SearchOptions): Promise<Search<Collection>> {
const params = parseOptions(options);
return await this.api.get<Search<Collection>>(
`${BASE_SEARCH}/collection`,
options
`${BASE_SEARCH}/collection?${params}`
);
}
async keywords(
options: SearchOptions
): Promise<Search<{ id: string; name: string }>> {
const params = parseOptions(options);
return await this.api.get<Search<{ id: string; name: string }>>(
`${BASE_SEARCH}/keyword`,
options
`${BASE_SEARCH}/keyword?${params}`
);
}
async movies(options: MovieSearchOptions): Promise<Search<Movie>> {
return await this.api.get<Search<Movie>>(`${BASE_SEARCH}/movie`, options);
const params = parseOptions(options);
return await this.api.get<Search<Movie>>(`${BASE_SEARCH}/movie?${params}`);
}
async people(options: PeopleSearchOptions): Promise<Search<Person>> {
return await this.api.get<Search<Person>>(`${BASE_SEARCH}/person`, options);
const params = parseOptions(options);
return await this.api.get<Search<Person>>(
`${BASE_SEARCH}/person?${params}`
);
}
// TODO: Multi search
async tvShows(options: TvSearchOptions): Promise<Search<TV>> {
return await this.api.get<Search<TV>>(`${BASE_SEARCH}/tv`, options);
const params = parseOptions(options);
return await this.api.get<Search<TV>>(`${BASE_SEARCH}/tv?${params}`);
}
}

View File

@@ -27,6 +27,7 @@ import {
Videos,
WatchProviders,
} from '../types';
import { parseOptions } from '../utils';
const BASE_TV = '/tv';
@@ -46,9 +47,9 @@ export class TvShowsEndpoint extends BaseEndpoint {
}
async changes(id: number, options?: ChangeOptions): Promise<TvShowChanges> {
const params = parseOptions(options);
return await this.api.get<TvShowChanges>(
`${BASE_TV}/${id}/changes`,
options
`${BASE_TV}/${id}/changes?${params}`
);
}
@@ -88,14 +89,15 @@ export class TvShowsEndpoint extends BaseEndpoint {
id: number,
options?: PageOption
): Promise<Recommendations> {
const params = parseOptions(options);
return await this.api.get<Recommendations>(
`${BASE_TV}/${id}/recommendations`,
options
`${BASE_TV}/${id}/recommendations?${params}`
);
}
async reviews(id: number, options?: PageOption): Promise<Reviews> {
return await this.api.get<Reviews>(`${BASE_TV}/${id}/reviews`, options);
const params = parseOptions(options);
return await this.api.get<Reviews>(`${BASE_TV}/${id}/reviews?${params}`);
}
async screenedTheatrically(id: number): Promise<ScreenedTheatrically> {
@@ -105,9 +107,9 @@ export class TvShowsEndpoint extends BaseEndpoint {
}
async similar(id: number, options?: PageOption): Promise<SimilarTvShows> {
const params = parseOptions(options);
return await this.api.get<SimilarTvShows>(
`${BASE_TV}/${id}/similar`,
options
`${BASE_TV}/${id}/similar?${params}`
);
}
@@ -140,21 +142,25 @@ export class TvShowsEndpoint extends BaseEndpoint {
async airingToday(
options?: PageOption & LanguageOption & RegionOption
): Promise<TvShowsAiringToday> {
const params = parseOptions(options);
return await this.api.get<TvShowsAiringToday>(
`${BASE_TV}/airing_today`,
options
`${BASE_TV}/airing_today?${params}`
);
}
async popular(
options?: PageOption & LanguageOption & RegionOption
): Promise<PopularTvShows> {
return await this.api.get<PopularTvShows>(`${BASE_TV}/popular`, options);
const params = parseOptions(options);
return await this.api.get<PopularTvShows>(`${BASE_TV}/popular?${params}`);
}
async topRated(
options?: PageOption & LanguageOption & RegionOption
): Promise<TopRatedTvShows> {
return await this.api.get<TopRatedTvShows>(`${BASE_TV}/top_rated`, options);
const params = parseOptions(options);
return await this.api.get<TopRatedTvShows>(
`${BASE_TV}/top_rated?${params}`
);
}
}

View File

@@ -1,4 +1,4 @@
export function parseOptions(options?: Record<string, any>): string {
/* eslint-disable @typescript-eslint/no-explicit-any */
export function parseOptions(options?: { [s: string]: any }): string {
return options ? new URLSearchParams(Object.entries(options)).toString() : '';
}