👾Migrating routes and functions

pull/33/head
capitanwesler 5 years ago
parent 563d0a7c4c
commit 16c17ac0ca

@ -1 +1,2 @@
PORT=5000
PORT=
DATABASE=

@ -53,7 +53,8 @@
"got": "^11.8.1",
"helmet": "^4.4.1",
"mongodb": "^3.6.4",
"rss-to-json": "^1.1.2",
"mongoose": "^5.11.18",
"rss-parser": "^3.12.0",
"tough-cookie": "^4.0.0",
"ts-node-dev": "^1.1.1"
},

@ -1,7 +1,14 @@
import { Request, Response } from 'express';
import { NextFunction, Request, Response } from 'express';
import { requestGot } from '../utils/requestCall';
import { transformUrlServer } from '../utils/transformerUrl';
import urls from '../utils/urls';
/*
AnimeController - a class to manage the schedule,
top, all the animes, return the last episodes
with async to return promises.
*/
interface Schedule {
title: string;
mal_id: number;
@ -27,19 +34,46 @@ interface Top {
score: string;
}
interface Episode {
id: string;
title: string;
image: string;
episode: number;
servers: { id: string; url: string; direct: boolean };
}
interface Movie {
id: string;
title: string;
type: string;
page: string;
banner: string;
image: string;
synopsis: string;
status: string;
rate: string;
genres: string[];
episodes: object[];
}
export default class AnimeController {
async schedule(req: Request, res: Response) {
async schedule(req: Request, res: Response, next: NextFunction) {
const { day } = req.params;
let data: any;
const data: any = await requestGot(`${urls.BASE_JIKAN}schedule/${day}`, {
parse: true,
scrapy: false,
});
try {
data = await requestGot(`${urls.BASE_JIKAN}schedule/${day}`, {
parse: true,
scrapy: false,
});
} catch (err) {
return next(err);
}
const animeList: Schedule[] = data[day].map((doc: Schedule) => ({
title: doc.title,
mal_id: doc.mal_id,
image: doc.image_url,
const animeList: Schedule[] = data[day].map((item: Schedule) => ({
title: item.title,
mal_id: item.mal_id,
image: item.image_url,
}));
if (animeList.length > 0) {
@ -51,7 +85,7 @@ export default class AnimeController {
}
}
async top(req: Request, res: Response) {
async top(req: Request, res: Response, next: NextFunction) {
const { type, subtype, page } = req.params;
let data: any;
@ -68,9 +102,8 @@ export default class AnimeController {
scrapy: false,
});
}
} catch (error) {
console.log(error);
return res.status(404);
} catch (err) {
return next(err);
}
const top: Top[] = data.top.map((item: Top) => ({
@ -91,11 +124,17 @@ export default class AnimeController {
}
}
async getAllAnimes(req: Request, res: Response) {
const data: any = await requestGot(`${urls.BASE_ANIMEFLV}api/animes/list`, {
parse: true,
scrapy: false,
});
async getAllAnimes(req: Request, res: Response, next: NextFunction) {
let data: any;
try {
data = await requestGot(`${urls.BASE_ANIMEFLV}api/animes/list`, {
parse: true,
scrapy: false,
});
} catch (err) {
return next(err);
}
const animes: Anime[] = data.map((item: any) => ({
index: item[0],
@ -111,4 +150,81 @@ export default class AnimeController {
res.status(500).json({ message: 'Aruppi lost in the shell' });
}
}
async getLastEpisodes(req: Request, res: Response, next: NextFunction) {
let data: any;
let episodes: Episode[] = [];
try {
data = await requestGot(`${urls.BASE_ANIMEFLV_JELU}LatestEpisodesAdded`, {
parse: true,
scrapy: false,
});
} catch (err) {
return next(err);
}
for (const episode of data.episodes) {
const formattedEpisode: Episode = {
id: episode.id,
title: episode.title,
image: episode.poster,
episode: episode.episode,
servers: await transformUrlServer(episode.servers),
};
episodes.push(formattedEpisode);
}
if (episodes.length > 0) {
res.status(200).json({
episodes,
});
} else {
res.status(500).json({ message: 'Aruppi lost in the shell' });
}
}
async getContent(req: Request, res: Response, next: NextFunction) {
const { type, page, url } = req.params;
let data: any;
try {
data = await requestGot(
`${urls.BASE_ANIMEFLV_JELU}${
url.charAt(0).toUpperCase() + url.slice(1)
}/${type}/${page}`,
{
parse: true,
scrapy: false,
},
);
} catch (err) {
return next(err);
}
const animes: Movie[] = data[url.toLowerCase()].map((item: any) => {
return {
id: item.id,
title: item.title,
type: url.toLowerCase(),
page: page,
banner: item.banner,
image: item.poster,
synopsis: item.synopsis,
status: item.debut,
rate: item.rating,
genres: item.genres.map((genre: any) => genre),
episodes: item.episodes.map((episode: any) => episode),
};
});
if (animes.length > 0) {
res.status(200).json({
animes,
});
} else {
res.status(500).json({ message: 'Aruppi lost in the shell' });
}
}
}

@ -0,0 +1,184 @@
import { NextFunction, Request, Response } from 'express';
import { requestGot } from '../utils/requestCall';
import AnimeModel, { Anime } from '../database/models/anime.model';
import {
animeExtraInfo,
getAnimeVideoPromo,
getAnimeCharacters,
getRelatedAnimesFLV,
getRelatedAnimesMAL,
} from '../utils/util';
import urls from '../utils/urls';
/*
DirectoryController - async functions controlling the directory
in the database of MongoDB, functions like getAllDirectory from the DB
other functions with realation to the directory, like the season and stuff.
*/
interface TypeAnime {
title: string;
image: string;
genres: string[];
}
interface Season {
title: string;
image: string;
malink: string;
}
interface Archive {
year: string;
seasons: string[];
}
export default class DirectoryController {
async getAllDirectory(req: Request, res: Response, next: NextFunction) {
const { genres } = req.params;
try {
if (genres === 'sfw') {
res.status(200).json(
await AnimeModel.find({
genres: { $nin: ['ecchi', 'Ecchi'] },
}),
);
} else {
res.status(200).json(await AnimeModel.find());
}
} catch (err) {
return next(err);
}
}
async getSeason(req: Request, res: Response, next: NextFunction) {
const { year, type } = req.params;
let data: any;
try {
data = await requestGot(`${urls.BASE_JIKAN}season/${year}/${type}`, {
scrapy: false,
parse: true,
});
} catch (err) {
return next(err);
}
const season: TypeAnime[] = data.anime.map((item: any) => {
return {
title: item.title,
image: item.image_url,
genres: item.genres.map((genre: any) => genre.name),
};
});
if (season.length > 0) {
res.status(200).json({
season,
});
} else {
res.status(500).json({ message: 'Aruppi lost in the shell' });
}
}
async allSeasons(req: Request, res: Response, next: NextFunction) {
let data: any;
try {
data = await requestGot(`${urls.BASE_JIKAN}season/archive`, {
parse: true,
scrapy: false,
});
} catch (err) {
return next(err);
}
const archive: Archive[] = data.archive.map((item: any) => {
return {
year: item.year,
seasons: item.seasons,
};
});
if (archive.length > 0) {
res.status(200).json({ archive });
} else {
res.status(500).json({ message: 'Aruppi lost in the shell' });
}
}
async laterSeasons(req: Request, res: Response, next: NextFunction) {
let data: any;
try {
data = await requestGot(`${urls.BASE_JIKAN}season/later`, {
parse: true,
scrapy: false,
});
} catch (err) {
return next(err);
}
const future: Season[] = data.anime.map((item: any) => {
return {
title: item.title,
image: item.image_url,
malink: item.url,
};
});
if (future.length > 0) {
res.status(200).json({ future });
} else {
res.status(500).json({ message: 'Aruppi lost in the shell' });
}
}
async getMoreInfo(req: Request, res: Response, next: NextFunction) {
const { title } = req.params;
let resultAnime: Anime | null;
try {
resultAnime = await AnimeModel.findOne({
$or: [{ title: { $eq: title } }, { title: { $eq: `${title} (TV)` } }],
});
} catch (err) {
return next(err);
}
if (resultAnime) {
if (!resultAnime?.jkanime) {
res.status(200).json({
title: resultAnime.title || null,
poster: resultAnime.poster || null,
synopsis: resultAnime.description || null,
status: resultAnime.state || null,
type: resultAnime.type || null,
rating: resultAnime.score || null,
genres: resultAnime.genres || null,
moreInfo: await animeExtraInfo(resultAnime.mal_id),
promo: await getAnimeVideoPromo(resultAnime.mal_id),
characters: await getAnimeCharacters(resultAnime.mal_id),
related: await getRelatedAnimesFLV(resultAnime.id),
});
} else {
res.status(200).json({
title: resultAnime.title || null,
poster: resultAnime.poster || null,
synopsis: resultAnime.description || null,
status: resultAnime.state || null,
type: resultAnime.type || null,
rating: resultAnime.score || null,
genres: resultAnime.genres || null,
moreInfo: await animeExtraInfo(resultAnime.mal_id),
promo: await getAnimeVideoPromo(resultAnime.mal_id),
characters: await getAnimeCharacters(resultAnime.mal_id),
related: await getRelatedAnimesMAL(resultAnime.mal_id),
});
}
} else {
res.status(500).json({ message: 'Aruppi lost in the shell' });
}
}
}

@ -0,0 +1,143 @@
import { NextFunction, Request, Response } from 'express';
import Parser from 'rss-parser';
import urls from '../utils/urls';
import { obtainPreviewNews } from '../utils/obtainPreviews';
/*
UtilsController - controller to parse the
feed and get news, all with scraping and
parsing RSS.
*/
type CustomFeed = {
foo: string;
};
type CustomItem = {
bar: number;
itunes: { duration: string; image: string };
'content:encoded': string;
'content:encodedSnippet': string;
};
const parser: Parser<CustomFeed, CustomItem> = new Parser({
customFields: {
feed: ['foo'],
item: ['bar'],
},
});
interface News {
title?: string;
url?: string;
author?: string;
thumbnail?: string;
content?: string;
}
interface Podcast {
title?: string;
duration?: string;
created?: Date | string;
mp3?: string;
}
interface rssPage {
url: string;
author: string;
content: string;
}
export default class UtilsController {
async getAnitakume(req: Request, res: Response, next: NextFunction) {
let feed: CustomFeed & Parser.Output<CustomItem>;
try {
feed = await parser.parseURL(urls.BASE_IVOOX);
} catch (err) {
return next(err);
}
const podcast: Podcast[] = [];
const monthNames = [
'Enero',
'Febrero',
'Marzo',
'Abril',
'Mayo',
'Junio',
'Julio',
'Agosto',
'Septiembre',
'Octubre',
'Noviembre',
'Diciembre',
];
feed.items.forEach(item => {
const date: Date = new Date(item.pubDate!);
const formattedObject: Podcast = {
title: item.title,
duration: item.itunes.duration,
created: `${date.getDate()} de ${
monthNames[date.getMonth()]
} de ${date.getFullYear()}`,
mp3: item.enclosure?.url,
};
podcast.push(formattedObject);
});
if (podcast.length > 0) {
res.status(200).json({ podcast });
} else {
res.status(500).json({ message: 'Aruppi lost in the shell' });
}
}
async getNews(req: Request, res: Response, next: NextFunction) {
const news: News[] = [];
const pagesRss: rssPage[] = [
{ url: urls.BASE_KUDASAI, author: 'Kudasai', content: 'content_encoded' },
{
url: urls.BASE_PALOMITRON,
author: 'Palomitron',
content: 'description',
},
{
url: urls.BASE_RAMENPARADOS,
author: 'Ramen para dos',
content: 'content',
},
{
url: urls.BASE_CRUNCHYROLL,
author: 'Crunchyroll',
content: 'content_encoded',
},
];
try {
for (const rssPage of pagesRss) {
const feed = await parser.parseURL(rssPage.url);
feed.items.forEach(item => {
const formattedObject: News = {
title: item.title,
url: item.link,
author: feed.title?.includes('Crunchyroll')
? 'Crunchyroll'
: feed.title,
thumbnail: obtainPreviewNews(item['content:encoded']),
content: item['content:encodedSnippet'],
};
news.push(formattedObject);
});
}
} catch (err) {
return next(err);
}
res.json({ news });
}
}

@ -0,0 +1,20 @@
import mongoose from 'mongoose';
/*
Create the connection to the database
of mongodb.
*/
export const createConnection = (database: string | undefined) => {
mongoose.connect(`mongodb://${database}/anime-directory`, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
mongoose.connection.on('error', err => {
console.log('err', err);
});
mongoose.connection.on('connected', (err, res) => {
console.log('Database connected: mongoose.');
});
};

@ -0,0 +1,35 @@
import { Document, model, Types, Schema } from 'mongoose';
/*
This is the model for each anime
of the directory, the anime model.
*/
export interface Anime extends Document {
id: string;
title: string;
mal_id: number;
poster: string;
type: string;
genres: Types.Array<string>;
state: string;
score: string;
jkanime: boolean;
description: string;
}
// Schema for the anime
const AnimeSchema: Schema = new Schema({
id: { type: String },
title: { type: String },
mal_id: { type: Number },
poster: { type: String },
type: { type: String },
genres: [{ type: String }],
state: { type: String },
score: { type: String },
jkanime: { type: Boolean },
description: { type: String },
});
export default model<Anime>('Anime', AnimeSchema);

@ -6,6 +6,12 @@ import {
RequestHandler,
} from 'express';
/*
Error handler and notFound handler
for all the API like a middleware with
the function next of express.
*/
export const errorHandler: ErrorRequestHandler = (
err: any,
req: Request,
@ -13,8 +19,7 @@ export const errorHandler: ErrorRequestHandler = (
next: NextFunction,
) => {
const statusCode = res.statusCode !== 200 ? res.statusCode : 500;
res.status(statusCode);
res.json({
res.status(statusCode).json({
message: err.message,
stack: process.env.NODE_ENV === 'production' ? '🥞' : err.stack,
});
@ -30,14 +35,14 @@ export const notFound: any = (
next(error);
};
export const requestLoggerMiddleWare: RequestHandler = (req, res, next) => {
console.log(`${req.method} ${req.originalUrl}`);
const start: number = new Date().getTime();
res.on('finish', () => {
const elapsed: number = new Date().getTime() - start;
console.info(
`${req.method} ${req.originalUrl} ${req.statusCode} ${elapsed}ms`,
);
});
next();
};
// export const requestLoggerMiddleWare: RequestHandler = (req, res, next) => {
// console.log(`${req.method} ${req.originalUrl}`);
// const start: number = new Date().getTime();
// res.on('finish', () => {
// const elapsed: number = new Date().getTime() - start;
// console.info(
// `${req.method} ${req.originalUrl} ${req.statusCode} ${elapsed}ms`,
// );
// });
// next();
// };

@ -1,62 +1,92 @@
import { Router, Request, Response } from 'express';
import AnimeController from './controllers/AnimeController';
import DirectoryController from './controllers/DirectoryController';
import UtilsController from './controllers/UtilsController';
const routes = Router();
const animeController = new AnimeController();
const directoryController = new DirectoryController();
const utilsController = new UtilsController();
routes.get('/', (req: Request, res: Response) => {
// We dont want to enforce the redirect storing, so just check
res.set('Cache-Control', 'no-cache,proxy-revalidate');
res.redirect('/api/');
res.redirect('/api/v4/');
});
routes.get('/api/', (req: Request, res: Response) => {
/*
Routes - JSON
Message with the JSON of all the routes in the
/api, parameters and some examples, how to call the
endpoints of the /api.
*/
routes.get('/api/v4/', (req: Request, res: Response) => {
res.set('Cache-Control', 'no-store');
res.json({
message: 'Aruppi API - 🎏',
message: 'Aruppi /api - 🎏',
author: 'Jéluchu',
version: '4.0.0',
credits: 'The bitch loves APIs that offers data to Aruppi App',
credits: 'The bitch loves /apis that offers data to Aruppi App',
entries: [
{
Schedule: '/api/schedule/:day',
Top: '/api/top/:type/:page/:subtype',
AllAnimes: '/api/ allAnimes',
RandomAnime: '/api/randomAnime',
Anitakume: '/api/anitakume',
News: '/api/news',
Season: '/api/season/:year/:type',
'All Seasons': '/api/allSeasons',
'All Directory': '/api/allDirectory/:type',
Genres: '/api/getByGenres/:genre?/:order?/:page?',
'Futures Seasons': '/api/laterSeasons',
LastEpisodes: '/api/lastEpisodes',
Movies: '/api/movies/:type/:page',
Ovas: '/api/ova/:type/:page',
Specials: '/api/special/:type/:page',
Tv: '/api/tv/:type/:page',
MoreInfo: '/api/moreInfo/:title',
GetEpisodes: '/api/getEpisodes/:title',
GetAnimeServers: '/api/getAnimeServers/:id',
Search: '/api/search/:title',
Images: '/api/images/:query',
Videos: '/api/videos/:channelId',
'Type Videos': '/api/sectionedVideos/:type',
Radios: '/api/radio',
'All Themes': '/api/allThemes',
Themes: '/api/themes/:title',
'Year Themes': '/api/themesYear/:year?',
'Random Theme': '/api/randomTheme',
'Artists Theme': '/api/artists/:id?',
'Famous Platforms': '/api/destAnimePlatforms',
'Legal Platforms': '/api/platforms/:id?',
Schedule: '/api/v4/schedule/:day',
Top: '/api/v4/top/:type/:page/:subtype',
AllAnimes: '/api/v4/allAnimes',
RandomAnime: '/api/v4/randomAnime',
Anitakume: '/api/v4/anitakume',
News: '/api/v4/news',
Season: '/api/v4/season/:year/:type',
'All Seasons': '/api/v4/allSeasons',
'All Directory': '/api/v4/allDirectory/:type',
Genres: '/api/v4/getByGenres/:genre?/:order?/:page?',
'Futures Seasons': '/api/v4/laterSeasons',
LastEpisodes: '/api/v4/lastEpisodes',
Movies: '/api/v4/movies/:type/:page',
Ovas: '/api/v4/ova/:type/:page',
Specials: '/api/v4/special/:type/:page',
Tv: '/api/v4/tv/:type/:page',
MoreInfo: '/api/v4/moreInfo/:title',
GetEpisodes: '/api/v4/getEpisodes/:title',
GetAnimeServers: '/api/v4/getAnimeServers/:id',
Search: '/api/v4/search/:title',
Images: '/api/v4/images/:query',
Videos: '/api/v4/videos/:channelId',
'Type Videos': '/api/v4/sectionedVideos/:type',
Radios: '/api/v4/radio',
'All Themes': '/api/v4/allThemes',
Themes: '/api/v4/themes/:title',
'Year Themes': '/api/v4/themesYear/:year?',
'Random Theme': '/api/v4/randomTheme',
'Artists Theme': '/api/v4/artists/:id?',
'Famous Platforms': '/api/v4/destAnimePlatforms',
'Legal Platforms': '/api/v4/platforms/:id?',
},
],
});
});
routes.get('/api/schedule/:day', animeController.schedule);
routes.get('/api/top/:type/:page/:subtype?/', animeController.top);
routes.get('/api/allAnimes', animeController.getAllAnimes);
/* Routes of the app below */
/* Anime Controller */
routes.get('/api/v4/schedule/:day', animeController.schedule);
routes.get('/api/v4/top/:type/:page/:subtype?/', animeController.top);
routes.get('/api/v4/allAnimes', animeController.getAllAnimes);
routes.get('/api/v4/lastEpisodes', animeController.getLastEpisodes);
routes.get('/api/v4/:url/:type/:page', animeController.getContent);
/* Directory Controller */
routes.get(
'/api/v4/allDirectory/:genres?',
directoryController.getAllDirectory,
);
routes.get('/api/v4/season/:year/:type', directoryController.getSeason);
routes.get('/api/v4/allSeasons', directoryController.allSeasons);
routes.get('/api/v4/laterSeasons', directoryController.laterSeasons);
routes.get('/api/v4/moreInfo/:title', directoryController.getMoreInfo);
/* Utils Controller */
routes.get('/api/v4/anitakume', utilsController.getAnitakume);
routes.get('/api/v4/news', utilsController.getNews);
export default routes;

@ -3,18 +3,25 @@ import cors from 'cors';
import helmet from 'helmet';
import dotenv from 'dotenv';
import { errorHandler, notFound } from './middlewares/middleware';
import { createConnection } from './database/connection';
import routes from './routes';
const app: Application = express();
dotenv.config();
createConnection(process.env.DATABASE);
app.use(cors());
app.use(helmet());
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(routes);
app.use(errorHandler);
app.use(notFound);
app.use(errorHandler);
// Starting to listen the server in port
/*
Starting the server on the .env process
you can define the PORT where the server
is going to listen in the server.
ex: PORT=3000.
*/
app.listen(process.env.PORT || 3000);

@ -64,6 +64,13 @@
"@types/connect" "*"
"@types/node" "*"
"@types/bson@*":
version "4.0.3"
resolved "https://registry.yarnpkg.com/@types/bson/-/bson-4.0.3.tgz#30889d2ffde6262abbe38659364c631454999fbf"
integrity sha512-mVRvYnTOZJz3ccpxhr3wgxVmSeiYinW+zlzQz3SXWaJmD1DuL05Jeq7nKw3SnbKmbleW5qrLG5vdyWe/A9sXhw==
dependencies:
"@types/node" "*"
"@types/cacheable-request@^6.0.1":
version "6.0.1"
resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.1.tgz#5d22f3dded1fd3a84c0bbeb5039a7419c2c91976"
@ -146,6 +153,14 @@
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a"
integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==
"@types/mongodb@^3.5.27":
version "3.6.8"
resolved "https://registry.yarnpkg.com/@types/mongodb/-/mongodb-3.6.8.tgz#f80f0a3022c44d8db659a936434403ca3f4661df"
integrity sha512-8qNbL5/GFrljXc/QijcuQcUMYZ1iWNcqnJ6tneROwbfU0LsAjQ9bmq3aHi5lWXM4cyBPd2F/n9INAk/pZZttHw==
dependencies:
"@types/bson" "*"
"@types/node" "*"
"@types/node@*", "@types/node@^14.14.31":
version "14.14.31"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.31.tgz#72286bd33d137aa0d152d47ec7c1762563d34055"
@ -381,13 +396,6 @@ asynckit@^0.4.0:
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
axios@^0.21.0:
version "0.21.1"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8"
integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==
dependencies:
follow-redirects "^1.10.0"
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
@ -398,13 +406,6 @@ binary-extensions@^2.0.0:
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
bindings@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df"
integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==
dependencies:
file-uri-to-path "1.0.0"
bl@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/bl/-/bl-2.2.1.tgz#8c11a7b730655c5d56898cdc871224f40fd901d5"
@ -413,6 +414,11 @@ bl@^2.2.1:
readable-stream "^2.3.5"
safe-buffer "^5.1.1"
bluebird@3.5.1:
version "3.5.1"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9"
integrity sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==
body-parser@1.19.0, body-parser@^1.19.0:
version "1.19.0"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a"
@ -712,6 +718,13 @@ debug@2.6.9, debug@^2.6.9:
dependencies:
ms "2.0.0"
debug@3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
dependencies:
ms "2.0.0"
debug@^4.0.1, debug@^4.1.0, debug@^4.1.1:
version "4.3.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
@ -859,7 +872,7 @@ end-of-stream@^1.1.0:
dependencies:
once "^1.4.0"
entities@^2.0.0:
entities@^2.0.0, entities@^2.0.3:
version "2.2.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
@ -1210,11 +1223,6 @@ file-entry-cache@^5.0.1:
dependencies:
flat-cache "^2.0.1"
file-uri-to-path@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==
fill-range@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
@ -1264,11 +1272,6 @@ flatted@^2.0.0:
resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138"
integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==
follow-redirects@^1.10.0:
version "1.13.2"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.2.tgz#dd73c8effc12728ba5cf4259d760ea5fb83e3147"
integrity sha512-6mPTgLxYm3r6Bkkg0vNM0HTjfGrOEtsfbhagQvbxDEsEkpNhw582upBaoRZylzen6krEmxXJgt9Ju6HiI4O7BA==
form-data@^2.5.0:
version "2.5.1"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4"
@ -1409,21 +1412,6 @@ helmet@^4.4.1:
resolved "https://registry.yarnpkg.com/helmet/-/helmet-4.4.1.tgz#a17e1444d81d7a83ddc6e6f9bc6e2055b994efe7"
integrity sha512-G8tp0wUMI7i8wkMk2xLcEvESg5PiCitFMYgGRc/PwULB0RVhTP5GFdxOwvJwp9XVha8CuS8mnhmE8I/8dx/pbw==
hoek@5.x.x:
version "5.0.4"
resolved "https://registry.yarnpkg.com/hoek/-/hoek-5.0.4.tgz#0f7fa270a1cafeb364a4b2ddfaa33f864e4157da"
integrity sha512-Alr4ZQgoMlnere5FZJsIyfIjORBqZll5POhDsF4q64dPuJR6rNxXdDxtHSQq8OXRurhmx+PWYEE8bXRROY8h0w==
hoek@6.x.x:
version "6.1.3"
resolved "https://registry.yarnpkg.com/hoek/-/hoek-6.1.3.tgz#73b7d33952e01fe27a38b0457294b79dd8da242c"
integrity sha512-YXXAAhmF9zpQbC7LEcREFtXfGq5K1fmd+4PHkBq8NUqmzW3G+Dq10bI/i0KucLRwss3YYFQ0fSfoxBZYiGUqtQ==
hoek@^4.2.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.1.tgz#9634502aa12c445dd5a7c5734b572bb8738aacbb"
integrity sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==
hosted-git-info@^2.1.4:
version "2.8.8"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488"
@ -1644,27 +1632,11 @@ isarray@^1.0.0, isarray@~1.0.0:
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
isemail@3.x.x:
version "3.2.0"
resolved "https://registry.yarnpkg.com/isemail/-/isemail-3.2.0.tgz#59310a021931a9fb06bbb51e155ce0b3f236832c"
integrity sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg==
dependencies:
punycode "2.x.x"
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
joi@^13.1.2:
version "13.7.0"
resolved "https://registry.yarnpkg.com/joi/-/joi-13.7.0.tgz#cfd85ebfe67e8a1900432400b4d03bbd93fb879f"
integrity sha512-xuY5VkHfeOYK3Hdi91ulocfuFopwgbSORmIwzcwHKESQhC7w1kD5jaVSPnqDxS2I8t3RZ9omCKAxNwXN5zG1/Q==
dependencies:
hoek "5.x.x"
isemail "3.x.x"
topo "3.x.x"
js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
@ -1700,6 +1672,11 @@ json5@^1.0.1:
dependencies:
minimist "^1.2.0"
kareem@2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/kareem/-/kareem-2.3.2.tgz#78c4508894985b8d38a0dc15e1a8e11078f2ca93"
integrity sha512-STHz9P7X2L4Kwn72fA4rGyqyXdmrMSdxqHx9IXon/FXluXieaFA6KJ2upcHAHxQPQ0LeM/OjLrhFxifHewOALQ==
keyv@^4.0.0:
version "4.0.3"
resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.0.3.tgz#4f3aa98de254803cafcd2896734108daa35e4254"
@ -1884,7 +1861,7 @@ mkdirp@^1.0.4:
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
mongodb@^3.6.4:
mongodb@3.6.4, mongodb@^3.6.4:
version "3.6.4"
resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-3.6.4.tgz#ca59fd65b06831308262372ef9df6b78f9da97be"
integrity sha512-Y+Ki9iXE9jI+n9bVtbTOOdK0B95d6wVGSucwtBkvQ+HIvVdTCfpVRp01FDC24uhC/Q2WXQ8Lpq3/zwtB5Op9Qw==
@ -1897,6 +1874,45 @@ mongodb@^3.6.4:
optionalDependencies:
saslprep "^1.0.0"
mongoose-legacy-pluralize@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz#3ba9f91fa507b5186d399fb40854bff18fb563e4"
integrity sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==
mongoose@^5.11.18:
version "5.11.18"
resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-5.11.18.tgz#76fdcefeb2afc7409705fc44b58045953bba5ee1"
integrity sha512-RsrPR9nhkXZbO3ml0DcmdbfeMvFNhgFrP81S6o1P+lFnDTNEKYnGNRCIL+ojD69wj7H5jJaAdZ0SJ5IlKxCHqw==
dependencies:
"@types/mongodb" "^3.5.27"
bson "^1.1.4"
kareem "2.3.2"
mongodb "3.6.4"
mongoose-legacy-pluralize "1.0.2"
mpath "0.8.3"
mquery "3.2.4"
ms "2.1.2"
regexp-clone "1.0.0"
safe-buffer "5.2.1"
sift "7.0.1"
sliced "1.0.1"
mpath@0.8.3:
version "0.8.3"
resolved "https://registry.yarnpkg.com/mpath/-/mpath-0.8.3.tgz#828ac0d187f7f42674839d74921970979abbdd8f"
integrity sha512-eb9rRvhDltXVNL6Fxd2zM9D4vKBxjVVQNLNijlj7uoXUy19zNDsIif5zR+pWmPCWNKwAtqyo4JveQm4nfD5+eA==
mquery@3.2.4:
version "3.2.4"
resolved "https://registry.yarnpkg.com/mquery/-/mquery-3.2.4.tgz#9c5c2e285ea6c6f20673f3528973c99ee1aaa1a0"
integrity sha512-uOLpp7iRX0BV1Uu6YpsqJ5b42LwYnmu0WeF/f8qgD/On3g0XDaQM6pfn0m6UxO6SM8DioZ9Bk6xxbWIGHm2zHg==
dependencies:
bluebird "3.5.1"
debug "3.1.0"
regexp-clone "^1.0.0"
safe-buffer "5.1.2"
sliced "1.0.1"
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
@ -1917,11 +1933,6 @@ mute-stream@0.0.7:
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=
nan@^2.13.2:
version "2.14.2"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19"
integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==
natural-compare@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
@ -1937,14 +1948,6 @@ nice-try@^1.0.4:
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
node-expat@^2.3.18:
version "2.3.18"
resolved "https://registry.yarnpkg.com/node-expat/-/node-expat-2.3.18.tgz#d9e6949cecda15e131f14259b73dc7b9ed7bc560"
integrity sha512-9dIrDxXePa9HSn+hhlAg1wXkvqOjxefEbMclGxk2cEnq/Y3U7Qo5HNNqeo3fQ4bVmLhcdt3YN1TZy7WMZy4MHw==
dependencies:
bindings "^1.5.0"
nan "^2.13.2"
normalize-package-data@^2.3.2, normalize-package-data@^2.3.4:
version "2.5.0"
resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8"
@ -2245,7 +2248,7 @@ pump@^3.0.0:
end-of-stream "^1.1.0"
once "^1.3.1"
punycode@2.x.x, punycode@^2.1.0, punycode@^2.1.1:
punycode@^2.1.0, punycode@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
@ -2342,6 +2345,11 @@ redent@^1.0.0:
indent-string "^2.1.0"
strip-indent "^1.0.1"
regexp-clone@1.0.0, regexp-clone@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/regexp-clone/-/regexp-clone-1.0.0.tgz#222db967623277056260b992626354a04ce9bf63"
integrity sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw==
regexpp@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f"
@ -2424,13 +2432,13 @@ rimraf@^2.6.1:
dependencies:
glob "^7.1.3"
rss-to-json@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/rss-to-json/-/rss-to-json-1.1.2.tgz#279ba4e82a10f44ea6277e6594bd2910d000816c"
integrity sha512-88J6yuApSgYL7eU7fNMDNVp3K7za/Bp2cj9Mjh0flDqChX6WG8f6OLJHqBeuxcvQjxTVALUPz82MGJMAATZplg==
rss-parser@^3.12.0:
version "3.12.0"
resolved "https://registry.yarnpkg.com/rss-parser/-/rss-parser-3.12.0.tgz#b8888699ea46304a74363fbd8144671b2997984c"
integrity sha512-aqD3E8iavcCdkhVxNDIdg1nkBI17jgqF+9OqPS1orwNaOgySdpvq6B+DoONLhzjzwV8mWg37sb60e4bmLK117A==
dependencies:
axios "^0.21.0"
xml2json "^0.12.0"
entities "^2.0.3"
xml2js "^0.4.19"
run-async@^2.2.0:
version "2.4.1"
@ -2456,7 +2464,7 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
safe-buffer@^5.1.1, safe-buffer@^5.1.2:
safe-buffer@5.2.1, safe-buffer@^5.1.1, safe-buffer@^5.1.2:
version "5.2.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
@ -2473,6 +2481,11 @@ saslprep@^1.0.0:
dependencies:
sparse-bitfield "^3.0.3"
sax@>=0.6.0:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.5.0, semver@^5.5.1:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
@ -2531,6 +2544,11 @@ shebang-regex@^1.0.0:
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=
sift@7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/sift/-/sift-7.0.1.tgz#47d62c50b159d316f1372f8b53f9c10cd21a4b08"
integrity sha512-oqD7PMJ+uO6jV9EQCl0LrRw1OwsiPsiFQR5AR30heR+4Dl7jBBbDLnNvWiak20tzZlSE1H7RB30SX/1j/YYT7g==
signal-exit@^3.0.0, signal-exit@^3.0.2:
version "3.0.3"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
@ -2550,6 +2568,11 @@ slice-ansi@^2.1.0:
astral-regex "^1.0.0"
is-fullwidth-code-point "^2.0.0"
sliced@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/sliced/-/sliced-1.0.1.tgz#0b3a662b5d04c3177b1926bea82b03f837a2ef41"
integrity sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=
source-map-support@^0.5.12, source-map-support@^0.5.17:
version "0.5.19"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61"
@ -2730,13 +2753,6 @@ toidentifier@1.0.0:
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==
topo@3.x.x:
version "3.0.3"
resolved "https://registry.yarnpkg.com/topo/-/topo-3.0.3.tgz#d5a67fb2e69307ebeeb08402ec2a2a6f5f7ad95c"
integrity sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ==
dependencies:
hoek "6.x.x"
tough-cookie@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4"
@ -2901,14 +2917,18 @@ write@1.0.3:
dependencies:
mkdirp "^0.5.1"
xml2json@^0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/xml2json/-/xml2json-0.12.0.tgz#b2ae450b267033b76d896f86e022fa7bff678572"
integrity sha512-EPJHRWJnJUYbJlzR4pBhZODwWdi2IaYGtDdteJi0JpZ4OD31IplWALuit8r73dJuM4iHZdDVKY1tLqY2UICejg==
xml2js@^0.4.19:
version "0.4.23"
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66"
integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==
dependencies:
hoek "^4.2.1"
joi "^13.1.2"
node-expat "^2.3.18"
sax ">=0.6.0"
xmlbuilder "~11.0.0"
xmlbuilder@~11.0.0:
version "11.0.1"
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3"
integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==
xtend@^4.0.0:
version "4.0.2"

Loading…
Cancel
Save