Converted utils & api to typescript. Webpack setup

This commit is contained in:
2022-07-26 22:09:41 +02:00
parent 8308a7231a
commit a4a669e774
10 changed files with 142 additions and 25 deletions

View File

@@ -27,6 +27,7 @@
"@babel/plugin-transform-runtime": "7.17.0", "@babel/plugin-transform-runtime": "7.17.0",
"@babel/preset-env": "7.16.11", "@babel/preset-env": "7.16.11",
"@babel/runtime": "7.17.2", "@babel/runtime": "7.17.2",
"@types/node": "^18.6.1",
"babel-loader": "8.2.3", "babel-loader": "8.2.3",
"css-loader": "6.7.0", "css-loader": "6.7.0",
"documentation": "^11.0.0", "documentation": "^11.0.0",
@@ -35,6 +36,8 @@
"sass": "1.49.9", "sass": "1.49.9",
"sass-loader": "12.6.0", "sass-loader": "12.6.0",
"terser-webpack-plugin": "5.3.1", "terser-webpack-plugin": "5.3.1",
"ts-loader": "^9.3.1",
"typescript": "^4.7.4",
"vue-loader": "15.9.8", "vue-loader": "15.9.8",
"vue-template-compiler": "2.6.14", "vue-template-compiler": "2.6.14",
"webpack": "5.70.0", "webpack": "5.70.0",

View File

@@ -1,15 +1,17 @@
import config from "@/config.json"; import config from "./config";
import { IList } from "./interfaces/IList";
const SEASONED_URL = config.SEASONED_URL || window.location.origin; let { SEASONED_URL, ELASTIC_URL, ELASTIC_INDEX } = config;
const ELASTIC_URL = config.ELASTIC_URL; if (!SEASONED_URL) {
const ELASTIC_INDEX = config.ELASTIC_INDEX; SEASONED_URL = window.location.origin;
}
// TODO // TODO
// - Move autorization token and errors here? // - Move autorization token and errors here?
const checkStatusAndReturnJson = response => { const checkStatusAndReturnJson = response => {
if (!response.ok) { if (!response.ok) {
throw resp; throw response;
} }
return response.json(); return response.json();
}; };
@@ -31,13 +33,13 @@ const getMovie = (
const url = new URL("/api/v2/movie", SEASONED_URL); const url = new URL("/api/v2/movie", SEASONED_URL);
url.pathname = `${url.pathname}/${id.toString()}`; url.pathname = `${url.pathname}/${id.toString()}`;
if (checkExistance) { if (checkExistance) {
url.searchParams.append("check_existance", true); url.searchParams.append("check_existance", "true");
} }
if (credits) { if (credits) {
url.searchParams.append("credits", true); url.searchParams.append("credits", "true");
} }
if (release_dates) { if (release_dates) {
url.searchParams.append("release_dates", true); url.searchParams.append("release_dates", "true");
} }
return fetch(url.href) return fetch(url.href)
@@ -58,10 +60,10 @@ const getShow = (id, checkExistance = false, credits = false) => {
const url = new URL("/api/v2/show", SEASONED_URL); const url = new URL("/api/v2/show", SEASONED_URL);
url.pathname = `${url.pathname}/${id.toString()}`; url.pathname = `${url.pathname}/${id.toString()}`;
if (checkExistance) { if (checkExistance) {
url.searchParams.append("check_existance", true); url.searchParams.append("check_existance", "true");
} }
if (credits) { if (credits) {
url.searchParams.append("credits", true); url.searchParams.append("credits", "true");
} }
return fetch(url.href) return fetch(url.href)
@@ -72,6 +74,10 @@ const getShow = (id, checkExistance = false, credits = false) => {
}); });
}; };
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
/** /**
* Fetches tmdb person by id. Can optionally include cast credits in result object. * Fetches tmdb person by id. Can optionally include cast credits in result object.
* @param {number} id * @param {number} id
@@ -82,7 +88,7 @@ const getPerson = (id, credits = false) => {
const url = new URL("/api/v2/person", SEASONED_URL); const url = new URL("/api/v2/person", SEASONED_URL);
url.pathname = `${url.pathname}/${id.toString()}`; url.pathname = `${url.pathname}/${id.toString()}`;
if (credits) { if (credits) {
url.searchParams.append("credits", true); url.searchParams.append("credits", "true");
} }
return fetch(url.href) return fetch(url.href)
@@ -162,9 +168,12 @@ const getPersonCredits = id => {
* @param {number} [page=1] * @param {number} [page=1]
* @returns {object} Tmdb list response * @returns {object} Tmdb list response
*/ */
const getTmdbMovieListByName = (name, page = 1) => { const getTmdbMovieListByName = (
name: string,
page: number = 1
): Promise<IList> => {
const url = new URL("/api/v2/movie/" + name, SEASONED_URL); const url = new URL("/api/v2/movie/" + name, SEASONED_URL);
url.searchParams.append("page", page); url.searchParams.append("page", page.toString());
return fetch(url.href).then(resp => resp.json()); return fetch(url.href).then(resp => resp.json());
// .catch(error => { console.error(`api error getting list: ${name}, page: ${page}`); throw error }) // .catch(error => { console.error(`api error getting list: ${name}, page: ${page}`); throw error })
@@ -175,9 +184,9 @@ const getTmdbMovieListByName = (name, page = 1) => {
* @param {number} [page=1] * @param {number} [page=1]
* @returns {object} Request response * @returns {object} Request response
*/ */
const getRequests = (page = 1) => { const getRequests = (page: number = 1) => {
const url = new URL("/api/v2/request", SEASONED_URL); const url = new URL("/api/v2/request", SEASONED_URL);
url.searchParams.append("page", page); url.searchParams.append("page", page.toString());
return fetch(url.href).then(resp => resp.json()); return fetch(url.href).then(resp => resp.json());
// .catch(error => { console.error(`api error getting list: ${name}, page: ${page}`); throw error }) // .catch(error => { console.error(`api error getting list: ${name}, page: ${page}`); throw error })
@@ -185,7 +194,7 @@ const getRequests = (page = 1) => {
const getUserRequests = (page = 1) => { const getUserRequests = (page = 1) => {
const url = new URL("/api/v1/user/requests", SEASONED_URL); const url = new URL("/api/v1/user/requests", SEASONED_URL);
url.searchParams.append("page", page); url.searchParams.append("page", page.toString());
return fetch(url.href).then(resp => resp.json()); return fetch(url.href).then(resp => resp.json());
}; };
@@ -203,8 +212,8 @@ const searchTmdb = (query, page = 1, adult = false, mediaType = null) => {
} }
url.searchParams.append("query", query); url.searchParams.append("query", query);
url.searchParams.append("page", page); url.searchParams.append("page", page.toString());
url.searchParams.append("adult", adult); url.searchParams.append("adult", adult.toString());
return fetch(url.href) return fetch(url.href)
.then(resp => resp.json()) .then(resp => resp.json())
@@ -369,7 +378,7 @@ const login = (username, password, throwError = false) => {
}); });
}; };
const logout = () => { const logout = (throwError = false) => {
const url = new URL("/api/v1/user/logout", SEASONED_URL); const url = new URL("/api/v1/user/logout", SEASONED_URL);
const options = { method: "POST" }; const options = { method: "POST" };

View File

@@ -48,7 +48,7 @@ import AutocompleteDropdown from "@/components/header/AutocompleteDropdown";
import IconSearch from "src/icons/IconSearch"; import IconSearch from "src/icons/IconSearch";
import IconClose from "src/icons/IconClose"; import IconClose from "src/icons/IconClose";
import config from "@/config.json"; import config from "@/config";
export default { export default {
name: "SearchInput", name: "SearchInput",

9
src/config.ts Normal file
View File

@@ -0,0 +1,9 @@
import type IConfig from "./interfaces/IConfig";
const config: IConfig = {
SEASONED_URL: "",
ELASTIC_URL: "https://elastic.kevinmidboe.com/",
ELASTIC_INDEX: "shows,movies"
};
export default config;

View File

@@ -0,0 +1,5 @@
export default interface IConfig {
SEASONED_URL: string;
ELASTIC_URL: string;
ELASTIC_INDEX: string;
}

56
src/interfaces/IList.ts Normal file
View File

@@ -0,0 +1,56 @@
export interface IList {
results: Array<IMovie | IShow | IPerson | IRequest>;
page: number;
total_results: number;
total_pages: number;
}
export enum ListTypes {
Movie = "movie",
Show = "show",
Person = "person",
Request = "request"
}
export enum RequestTypes {
Requested = "requested"
}
export interface IMovie {
id: number;
title: string;
year: number;
overview: string;
poster: string;
backdrop: string;
release_date: string | Date;
rating: number;
type: ListTypes.Movie;
}
export interface IShow {
id: number;
title: string;
year: number;
overview: string;
poster: string;
backdrop: string;
type: ListTypes.Show;
}
export interface IPerson {
id: number;
title: string;
poster: string;
birthday: string | null;
deathday: string | null;
known_for_department: string;
adult: boolean;
}
export interface IRequest extends IMovie {
requested_by: string;
ip: string;
status: string | RequestTypes;
user_agent: string;
}

View File

@@ -1,14 +1,14 @@
export const sortableSize = string => { export const sortableSize = (string: string) => {
const UNITS = ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; const UNITS = ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
const [numStr, unit] = string.split(" "); const [numStr, unit] = string.split(" ");
if (UNITS.indexOf(unit) === -1) return string; if (UNITS.indexOf(unit) === -1) return string;
const exponent = UNITS.indexOf(unit) * 3; const exponent = UNITS.indexOf(unit) * 3;
return numStr * Math.pow(10, exponent); return Number(numStr) * Math.pow(10, exponent);
}; };
export const parseJwt = token => { export const parseJwt = (token: string) => {
var base64Url = token.split(".")[1]; var base64Url = token.split(".")[1];
var base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/"); var base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
var jsonPayload = decodeURIComponent( var jsonPayload = decodeURIComponent(
@@ -23,7 +23,11 @@ export const parseJwt = token => {
return JSON.parse(jsonPayload); return JSON.parse(jsonPayload);
}; };
export const buildImageProxyUrl = (width, height, asset) => { export const buildImageProxyUrl = (
width: number,
height: number,
asset: string
) => {
const proxyHost = `http://imgproxy.schleppe:8080/insecure/`; const proxyHost = `http://imgproxy.schleppe:8080/insecure/`;
const proxySizeOptions = `resize:fill:${Math.floor(width / 1)}:${Math.floor( const proxySizeOptions = `resize:fill:${Math.floor(width / 1)}:${Math.floor(
height / 1 height / 1

26
tsconfig.json Normal file
View File

@@ -0,0 +1,26 @@
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"strict": false,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"lib": ["esnext", "dom"],
"outDir": "lib",
"baseUrl": "/",
"paths": {
"@": ["src"]
}
},
"include": [
"src/**/*.js",
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*.tsx",
"src/**/*.vue"
],
"exclude": ["node_modules"]
}

View File

@@ -35,6 +35,11 @@ module.exports = {
test: /\.vue$/, test: /\.vue$/,
use: ["vue-loader"] use: ["vue-loader"]
}, },
{
test: /\.tsx?$/,
loader: "ts-loader",
exclude: /node_modules/
},
{ {
test: /\.scss$/, test: /\.scss$/,
use: [ use: [
@@ -62,7 +67,7 @@ module.exports = {
}) })
], ],
resolve: { resolve: {
extensions: [".js", ".vue", ".json", ".scss"], extensions: [".js", ".ts", ".vue", ".json", ".scss"],
alias: { alias: {
vue$: "vue/dist/vue.common.js", vue$: "vue/dist/vue.common.js",
"@": path.resolve(__dirname, "src"), "@": path.resolve(__dirname, "src"),