Signed-off-by: Sam Therapy <sam@samtherapy.net>
This commit is contained in:
parent
4d4c84981c
commit
133ae0618b
16 changed files with 167 additions and 243 deletions
127
index.js
127
index.js
|
@ -6,17 +6,9 @@ import cors from "cors";
|
|||
import errorPage from "./lib/errorPage.js";
|
||||
import morgan from "morgan";
|
||||
import { detector } from "megalodon";
|
||||
import helmet from "helmet";
|
||||
|
||||
const app = Express();
|
||||
app.use(
|
||||
helmet({
|
||||
contentSecurityPolicy: false,
|
||||
crossOriginEmbedderPolicy: false,
|
||||
crossOriginResourcePolicy: false,
|
||||
frameguard: false,
|
||||
})
|
||||
);
|
||||
app.disable("x-powered-by");
|
||||
|
||||
const logger = morgan(":method :url :status via :referrer - :response-time ms");
|
||||
|
||||
|
@ -44,13 +36,17 @@ app.get("/api/feed", cors(), logger, function (req, res) {
|
|||
return;
|
||||
}
|
||||
|
||||
const userUrl = feedUrl.replace(/\.atom.*/i, "");
|
||||
let userUrl = "";
|
||||
|
||||
if (typeof feedUrl === "string") {
|
||||
userUrl = feedUrl.replace(/\.atom.*/i, "");
|
||||
}
|
||||
|
||||
const redirectUrl = "/api/v1/feed?";
|
||||
const qs = ["userurl=" + encodeURIComponent(userUrl), "api=v1"];
|
||||
|
||||
["size", "theme", "boosts", "replies"].forEach((key) => {
|
||||
if (typeof req.query[key] != "undefined") {
|
||||
if (typeof req.query[key] !== "undefined") {
|
||||
qs.push(key + "=" + encodeURIComponent(req.query[key]));
|
||||
}
|
||||
});
|
||||
|
@ -64,78 +60,43 @@ app.get("/api/v1/feed", cors(), logger, async function (req, res) {
|
|||
// userUrl
|
||||
let type = req.query.instance_type;
|
||||
let userUrl = req.query.userurl;
|
||||
if (userUrl === "" || userUrl === undefined) {
|
||||
if (!userUrl) {
|
||||
const user = req.query.user;
|
||||
const instance = req.query.instance;
|
||||
if (type === "" || type === undefined) {
|
||||
if (!type) {
|
||||
type = await detector(instance).catch(() => "");
|
||||
}
|
||||
if (type === "mastodon" || type === "pleroma")
|
||||
userUrl = instance + "/users/" + user;
|
||||
else if (type === "misskey") userUrl = instance + "/@" + user;
|
||||
else {
|
||||
res
|
||||
.status(400)
|
||||
.send(errorPage(400, "You need to specify a user URL", null));
|
||||
return;
|
||||
switch (type) {
|
||||
case "mastodon":
|
||||
case "pleroma":
|
||||
userUrl = instance + "/users/" + user;
|
||||
break;
|
||||
case "misskey":
|
||||
userUrl = instance + "/@" + user;
|
||||
break;
|
||||
default:
|
||||
res
|
||||
.status(400)
|
||||
.send(errorPage(400, "You need to specify a user URL", null));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const feedUrl = req.query.feedurl;
|
||||
|
||||
const opts = {};
|
||||
if (req.query.size) {
|
||||
opts.size = req.query.size;
|
||||
}
|
||||
if (req.query.theme) {
|
||||
opts.theme = req.query.theme;
|
||||
if (opts.theme === "auto-auto") {
|
||||
switch (type) {
|
||||
case "mastodon":
|
||||
opts.theme = "masto-auto";
|
||||
break;
|
||||
case "pleroma":
|
||||
opts.theme = "pleroma";
|
||||
break;
|
||||
case "misskey":
|
||||
opts.theme = "misskey-auto";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (opts.theme === "auto-light") {
|
||||
switch (type) {
|
||||
case "mastodon":
|
||||
opts.theme = "masto-light";
|
||||
break;
|
||||
case "misskey":
|
||||
opts.theme = "misskey-light";
|
||||
break;
|
||||
case "pleroma":
|
||||
opts.theme = "pleroma-light";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (opts.theme === "auto-dark") {
|
||||
switch (type) {
|
||||
case "mastodon":
|
||||
opts.theme = "masto-dark";
|
||||
break;
|
||||
case "misskey":
|
||||
opts.theme = "misskey-dark";
|
||||
break;
|
||||
case "pleroma":
|
||||
opts.theme = "pleroma-dark";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (req.query.header) opts.header = req.query.header.toLowerCase() === "true";
|
||||
if (req.query.boosts) opts.boosts = req.query.boosts.toLowerCase() === "true";
|
||||
if (req.query.replies)
|
||||
opts.size = req.query.size;
|
||||
|
||||
opts.theme = req.query.theme;
|
||||
|
||||
opts.theme = opts.theme.replace("auto-", `${type}-`);
|
||||
opts.theme ??= "auto-auto";
|
||||
|
||||
if (typeof req.query.header === "string")
|
||||
opts.header = req.query.header.toLowerCase() === "true";
|
||||
if (typeof req.query.boosts === "string")
|
||||
opts.boosts = req.query.boosts.toLowerCase() === "true";
|
||||
if (typeof req.query.replies === "string")
|
||||
opts.replies = req.query.replies.toLowerCase() === "true";
|
||||
opts.instance_type = type;
|
||||
opts.userUrl = userUrl;
|
||||
|
@ -152,10 +113,28 @@ app.get("/api/v1/feed", cors(), logger, async function (req, res) {
|
|||
.status(500)
|
||||
.send(errorPage(500, null, { theme: opts.theme, size: opts.size }));
|
||||
// TODO log the error
|
||||
console.error(er, er.stack);
|
||||
console.error("error:", er, er.stack);
|
||||
});
|
||||
});
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
app.use(function (req, res, _next) {
|
||||
// respond with html page
|
||||
if (req.accepts("html")) {
|
||||
res.status(404).send("Not found");
|
||||
return;
|
||||
}
|
||||
|
||||
// respond with json
|
||||
if (req.accepts("json")) {
|
||||
res.status(404).json({ error: "Not found" });
|
||||
return;
|
||||
}
|
||||
|
||||
// default to plain-text. send()
|
||||
res.status(404).type("txt").send("Not found");
|
||||
});
|
||||
|
||||
app.listen(process.env.PORT || 8000, "127.0.0.1", function () {
|
||||
console.log("Server started, listening on " + (process.env.PORT || 8000));
|
||||
});
|
||||
|
|
|
@ -38,18 +38,15 @@ async function promiseSome(proms) {
|
|||
prom // it's already been called
|
||||
.then(resolve)
|
||||
.catch(() => {
|
||||
// console.warn(e);// for debugging
|
||||
resolve(null);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return await Promise.all(proms.map(noRejectWrap));
|
||||
return Promise.all(proms.map(noRejectWrap));
|
||||
}
|
||||
|
||||
export default async function (opts) {
|
||||
// let opts = opts;
|
||||
|
||||
let feedUrl = opts.feedUrl;
|
||||
let userUrl = opts.userUrl;
|
||||
let isIndex = false;
|
||||
|
@ -72,7 +69,7 @@ export default async function (opts) {
|
|||
let outbox = await apGet(user.outbox);
|
||||
|
||||
// outbox.first can be a string for a URL, or an object with stuffs in it
|
||||
if (typeof outbox.first == "object") {
|
||||
if (typeof outbox.first === "object") {
|
||||
feed = outbox.first;
|
||||
} else {
|
||||
feed = await apGet(outbox.first);
|
||||
|
@ -107,9 +104,9 @@ async function itemsForFeed(opts, user, feed) {
|
|||
// yes, I have to fetch all the fucking boosts for this whole feed apparently >:/
|
||||
let boostData = [];
|
||||
let boostUrls = feed.orderedItems
|
||||
.filter((i) => i.type == "Announce")
|
||||
.filter((i) => i.type === "Announce")
|
||||
.map((i) => i.object);
|
||||
// console.log(boostUrls);
|
||||
|
||||
boostData = await promiseSome(boostUrls.map(apGet));
|
||||
|
||||
// now get user data for each of those
|
||||
|
@ -126,8 +123,6 @@ async function itemsForFeed(opts, user, feed) {
|
|||
|
||||
// some URLs may have failed but IDGAF
|
||||
|
||||
// console.log(boostData[0]);
|
||||
|
||||
boostData.forEach((boostToot) => {
|
||||
if (!boostToot) {
|
||||
// failed request
|
||||
|
@ -137,31 +132,31 @@ async function itemsForFeed(opts, user, feed) {
|
|||
// inject in-place into items
|
||||
|
||||
let index = -1;
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
if (items[i].object == boostToot.id) {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
if (items[i].object === boostToot.id) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index == -1) {
|
||||
if (index === -1) {
|
||||
console.warn(`warning: couldn't match boost to item: ${boostToot}`);
|
||||
return;
|
||||
}
|
||||
|
||||
boostToot.object = boostToot; // this lets the later stage parser access object without errors :)
|
||||
items[i] = boostToot;
|
||||
items[index] = boostToot;
|
||||
});
|
||||
}
|
||||
|
||||
return items
|
||||
.filter((item) => {
|
||||
return typeof item.object == "object"; // handle weird cases
|
||||
return typeof item.object === "object"; // handle weird cases
|
||||
})
|
||||
.map((item) => {
|
||||
let enclosures = (item.object.attachment || [])
|
||||
.filter((a) => {
|
||||
return a.type == "Document";
|
||||
return a.type === "Document";
|
||||
})
|
||||
.map((a) => {
|
||||
return {
|
||||
|
@ -173,6 +168,18 @@ async function itemsForFeed(opts, user, feed) {
|
|||
|
||||
let op = item._userdata ? item._userdata : user;
|
||||
|
||||
let content =
|
||||
item.object && item.object.content ? item.object.content : ""; //TODO sanitize then render without entity escapes
|
||||
|
||||
item.object.tag.forEach((tag) => {
|
||||
if (tag.type === "Emoji") {
|
||||
content = content.replace(
|
||||
tag.name,
|
||||
`<img src="${tag.icon.url}" alt="${tag.name}" title="${tag.name}" width="32" height="32"/>`
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
isBoost: !!item._userdata,
|
||||
title: item._userdata
|
||||
|
@ -183,7 +190,7 @@ async function itemsForFeed(opts, user, feed) {
|
|||
isReply: !!(item.object && item.object.inReplyTo),
|
||||
hasCw: item.object.sensitive || false,
|
||||
cw: item.object.summary,
|
||||
content: item.object && item.object.content ? item.object.content : "", //TODO sanitize then render without entity escapes
|
||||
content: content,
|
||||
atomHref: item.published
|
||||
? item.published.replace(/\W+/g, "")
|
||||
: Math.random().toString().replace("./g", ""), // used for IDs
|
||||
|
@ -202,7 +209,7 @@ async function itemsForFeed(opts, user, feed) {
|
|||
});
|
||||
}
|
||||
|
||||
function getNextPage(opts, user, feed) {
|
||||
function getNextPage(opts, _user, feed) {
|
||||
//based on feed.next
|
||||
if (!feed.next) {
|
||||
return null;
|
||||
|
@ -220,7 +227,7 @@ function getNextPage(opts, user, feed) {
|
|||
|
||||
// add other params to the end
|
||||
["theme", "header", "size", "boosts", "replies"].forEach((k) => {
|
||||
if (typeof opts[k] != "undefined") {
|
||||
if (typeof opts[k] !== "undefined") {
|
||||
ret += `&${k}=${opts[k].toString()}`;
|
||||
}
|
||||
});
|
||||
|
@ -230,7 +237,6 @@ function getNextPage(opts, user, feed) {
|
|||
// utilities below
|
||||
|
||||
function getTimeDisplay(d) {
|
||||
// let d = d;
|
||||
if (typeof d !== "object") {
|
||||
d = new Date(d);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ export default function (code, message, displayOptions) {
|
|||
let msg;
|
||||
// const displayOptions = displayOptions || {};
|
||||
|
||||
if (code == 500 && !message) {
|
||||
if (code === 500 && !message) {
|
||||
msg =
|
||||
"<p>Sorry, we are having trouble fetching posts for this user. Please try again later.</p><br><p>If the issue persists, <a href='https://git.froth.zone/Sam/fedifeed/issues'>please open an issue on Gitea</a>, or message sam@froth.zone</p>";
|
||||
} else {
|
||||
|
|
|
@ -1,21 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>This is an iFrame how did you get here</title>
|
||||
<meta charset="UTF-8"></meta>
|
||||
<style type="text/css"></style>
|
||||
<base target="_top" /><!-- this element is amazing-->
|
||||
|
||||
<% if (opts.theme && opts.theme.toLowerCase() == 'masto-light'){ %>
|
||||
<% if (opts.theme && opts.theme?.toLowerCase() === 'masto-light' || opts.theme?.toLowerCase() === 'mastodon-light'){ %>
|
||||
<link rel="stylesheet" href="/css/masto-light.css"></link>
|
||||
<% } else if (opts.theme && opts.theme.toLowerCase() == 'masto-auto'){ %>
|
||||
<% } else if (opts.theme && opts.theme?.toLowerCase() === 'masto-auto' || opts.theme?.toLowerCase() === 'mastodon-auto'){ %>
|
||||
<link rel="stylesheet" href="/css/masto-auto.css"></link>
|
||||
<% } else if (opts.theme && opts.theme.toLowerCase() == 'misskey-dark'){ %>
|
||||
<% } else if (opts.theme && opts.theme?.toLowerCase() === 'misskey-dark' ){ %>
|
||||
<link rel="stylesheet" href="/css/misskey-dark.css"></link>
|
||||
<% } else if (opts.theme && opts.theme.toLowerCase() == 'misskey-light'){ %>
|
||||
<% } else if (opts.theme && opts.theme?.toLowerCase() === 'misskey-light'){ %>
|
||||
<link rel="stylesheet" href="/css/misskey-light.css"></link>
|
||||
<% } else if (opts.theme && opts.theme.toLowerCase() == 'misskey-auto'){ %>
|
||||
<% } else if (opts.theme && opts.theme?.toLowerCase() === 'misskey-auto'){ %>
|
||||
<link rel="stylesheet" href="/css/misskey-auto.css"></link>
|
||||
<% } else if (opts.theme && opts.theme.toLowerCase() == 'pleroma'){ %>
|
||||
<% } else if (opts.theme && opts.theme?.toLowerCase() === 'pleroma'){ %>
|
||||
<link rel="stylesheet" href="/css/pleroma.css"></link>
|
||||
<% } else { %>
|
||||
<link rel="stylesheet" href="/css/masto-dark.css"></link>
|
||||
|
@ -36,7 +37,7 @@
|
|||
<div class="header" style="<%= meta.headerImage?`background-image:url(${meta.headerImage})`:'' %>">
|
||||
<a class="header-left" target="_top" href="<%= meta.link %>">
|
||||
<% if (meta.avatar){ %>
|
||||
<img class="avatar circular" src="<%= meta.avatar %>"></img>
|
||||
<img class="avatar circular" src="<%= meta.avatar %>" alt="avatar"/>
|
||||
<% } %>
|
||||
</a>
|
||||
<div class="description header-right">
|
||||
|
@ -60,7 +61,7 @@
|
|||
<% } %>
|
||||
<div class="author">
|
||||
<a target="_top" class="avatar" href="<%- item.author.uri %>">
|
||||
<img class="avatar" src="<%- item.author.avatar %>"/>
|
||||
<img class="avatar" src="<%- item.author.avatar %>" alt="avatar"/>
|
||||
</a>
|
||||
<div class="author-info">
|
||||
<a target="_top" class="author-displayname" href="<%- item.author.uri %>"> <%= item.author.displayName %> </a>
|
||||
|
@ -127,13 +128,13 @@
|
|||
path: function(){
|
||||
// need to query this DOM my damn self
|
||||
let pageLinks = document.querySelectorAll('.hacky_link');
|
||||
if (!pageLinks || pageLinks.length == 0){
|
||||
if (!pageLinks || pageLinks.length === 0){
|
||||
console.log ('next page link could not be found');
|
||||
return false;
|
||||
}else{
|
||||
let finalLink = pageLinks[pageLinks.length-1].href;
|
||||
// make sure we don't load the same page twice
|
||||
if (!finalLink || finalLink == window.location.href || finalLink == lastPageLoaded){
|
||||
if (!finalLink || finalLink === window.location.href || finalLink === lastPageLoaded){
|
||||
console.log('this was the last page');
|
||||
return false;
|
||||
}else{
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
"cors": "2.8.5",
|
||||
"ejs": "3.1.8",
|
||||
"express": "4.18.1",
|
||||
"feedparser": "2.2.10",
|
||||
"helmet": "5.1.1",
|
||||
"megalodon": "4.1.0",
|
||||
"morgan": "1.10.0",
|
||||
"serve-static": "1.15.0",
|
||||
|
|
|
@ -381,3 +381,11 @@ body {
|
|||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.item-content img {
|
||||
margin: 0;
|
||||
}
|
||||
|
|
|
@ -197,3 +197,15 @@ input[type="checkbox"]:not(:checked) ~ label::after {
|
|||
input[type="checkbox"]:not(:checked) ~ div {
|
||||
display: none;
|
||||
}
|
||||
|
||||
img {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
img .item-content {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.item-content img {
|
||||
margin: 0;
|
||||
}
|
||||
|
|
|
@ -205,3 +205,11 @@ html,
|
|||
body {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
img {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.item-content img {
|
||||
margin: 0;
|
||||
}
|
||||
|
|
|
@ -426,3 +426,11 @@ body {
|
|||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.item-content img {
|
||||
margin: 0;
|
||||
}
|
||||
|
|
|
@ -207,3 +207,11 @@ input[type="checkbox"]:not(:checked) ~ label::after {
|
|||
input[type="checkbox"]:not(:checked) ~ div {
|
||||
display: none;
|
||||
}
|
||||
|
||||
img {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.item-content img {
|
||||
margin: 0;
|
||||
}
|
||||
|
|
|
@ -214,3 +214,11 @@ html,
|
|||
body {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
img {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.item-content img {
|
||||
margin: 0;
|
||||
}
|
||||
|
|
|
@ -197,3 +197,11 @@ input[type="checkbox"]:not(:checked) ~ label::after {
|
|||
input[type="checkbox"]:not(:checked) ~ div {
|
||||
display: none;
|
||||
}
|
||||
|
||||
img {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.item-content img {
|
||||
margin: 0;
|
||||
}
|
||||
|
|
|
@ -204,3 +204,11 @@ button:hover,
|
|||
a:hover {
|
||||
background-color: #394150;
|
||||
}
|
||||
|
||||
img {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.item-content img {
|
||||
margin: 0;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<br />
|
||||
<div>
|
||||
<h1>Fedifeed</h1>
|
||||
<h4>Embedded ActivityPub feeds for blogs, websites, etc.</h4>
|
||||
<h4>Embedded Mastodon/Pleroma/Misskey feeds for blogs, websites, etc.</h4>
|
||||
<a href="https://git.froth.zone/sam/fedifeed" class="cta button alt"
|
||||
>Fork on Gitea
|
||||
<img class="link-logo after" src="img/gitea-logo.svg" alt="Gitea Logo"
|
||||
|
@ -78,7 +78,7 @@
|
|||
<option value="auto-auto">
|
||||
auto-auto (depends on instance, automatic)
|
||||
</option>
|
||||
<option value="auto-dark">
|
||||
<option value="auto-dark" selected>
|
||||
auto-dark (depends on instance, use dark)
|
||||
</option>
|
||||
<option value="auto-light">
|
||||
|
@ -121,6 +121,7 @@
|
|||
<span class="iframe-contain">
|
||||
<iframe
|
||||
id="frame"
|
||||
title="Powered by Fedifeed"
|
||||
allowfullscreen
|
||||
sandbox="allow-top-navigation allow-scripts"
|
||||
width="400"
|
||||
|
|
|
@ -11,7 +11,7 @@ window.genUrl = function genUrl() {
|
|||
.checked).toString();
|
||||
let showHeader = document.getElementById("header").checked.toString();
|
||||
let portStr =
|
||||
window.location.port && window.location.port != 80
|
||||
window.location.port && window.location.port !== 80
|
||||
? ":" + window.location.port
|
||||
: "";
|
||||
|
||||
|
@ -30,7 +30,7 @@ window.genUrl = function genUrl() {
|
|||
// Prettier, WHY
|
||||
document.getElementById(
|
||||
"result"
|
||||
).value = `<iframe allowfullscreen sandbox="allow-top-navigation allow-scripts" width="${val(
|
||||
).value = `<iframe title="Powered by Fedifeed" allowfullscreen sandbox="allow-top-navigation allow-scripts" width="${val(
|
||||
"width"
|
||||
)}" height="${val("height")}" src="${iframeUrl}"></iframe>`;
|
||||
|
||||
|
|
135
yarn.lock
135
yarn.lock
|
@ -168,13 +168,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"addressparser@npm:^1.0.1":
|
||||
version: 1.0.1
|
||||
resolution: "addressparser@npm:1.0.1"
|
||||
checksum: 389051bc6a3a44082a6e7d6256c15e2aba55ae4799f1eed620e34f1c77ddf4dfe9baacc41c6ad25eb5f795195ff8a506dc07ef9e4bc033ee1ab3882edfed396d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"agent-base@npm:6, agent-base@npm:^6.0.2":
|
||||
version: 6.0.2
|
||||
resolution: "agent-base@npm:6.0.2"
|
||||
|
@ -274,13 +267,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"array-indexofobject@npm:~0.0.1":
|
||||
version: 0.0.1
|
||||
resolution: "array-indexofobject@npm:0.0.1"
|
||||
checksum: 2517000758e1a5975f346c9b88efeab5c42f1817313397761e9e4d27ed8bee7dea1f934e07bd35ff57be9c8ba5e6a27d70707dfb0c101c1fc4aea3bbd922c173
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"array-union@npm:^2.1.0":
|
||||
version: 2.1.0
|
||||
resolution: "array-union@npm:2.1.0"
|
||||
|
@ -554,13 +540,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"core-util-is@npm:~1.0.0":
|
||||
version: 1.0.3
|
||||
resolution: "core-util-is@npm:1.0.3"
|
||||
checksum: 9de8597363a8e9b9952491ebe18167e3b36e7707569eed0ebf14f8bba773611376466ae34575bca8cfe3c767890c859c74056084738f09d4e4a6f902b2ad7d99
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cors@npm:2.8.5":
|
||||
version: 2.8.5
|
||||
resolution: "cors@npm:2.8.5"
|
||||
|
@ -988,25 +967,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"feedparser@npm:2.2.10":
|
||||
version: 2.2.10
|
||||
resolution: "feedparser@npm:2.2.10"
|
||||
dependencies:
|
||||
addressparser: ^1.0.1
|
||||
array-indexofobject: ~0.0.1
|
||||
lodash.assign: ^4.2.0
|
||||
lodash.get: ^4.4.2
|
||||
lodash.has: ^4.5.2
|
||||
lodash.uniq: ^4.5.0
|
||||
mri: ^1.1.5
|
||||
readable-stream: ^2.3.7
|
||||
sax: ^1.2.4
|
||||
bin:
|
||||
feedparser: bin/feedparser.js
|
||||
checksum: 1b13452824b4711d32e38fbda1a165f40b2de8887bbe8d9dfb88bc9981575ed6bd7f8cca3e53ca22f7d1d564caffa1d632b2559545721433d6ea9a10dcb130be
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"file-entry-cache@npm:^6.0.1":
|
||||
version: 6.0.1
|
||||
resolution: "file-entry-cache@npm:6.0.1"
|
||||
|
@ -1300,13 +1260,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"helmet@npm:5.1.1":
|
||||
version: 5.1.1
|
||||
resolution: "helmet@npm:5.1.1"
|
||||
checksum: b72ba26cc431804ad3b8ecdc18db95409a492cbb7a7e825efc27fc502b9433fec39fc083f2aad4fe7ed1a89a4287560b59f4435f9689eebbae6a2b61a1ec1b7d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"http-cache-semantics@npm:^4.1.0":
|
||||
version: 4.1.0
|
||||
resolution: "http-cache-semantics@npm:4.1.0"
|
||||
|
@ -1430,7 +1383,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.3, inherits@npm:~2.0.3":
|
||||
"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.3":
|
||||
version: 2.0.4
|
||||
resolution: "inherits@npm:2.0.4"
|
||||
checksum: 4a48a733847879d6cf6691860a6b1e3f0f4754176e4d71494c41f3475553768b10f84b5ce1d40fbd0e34e6bfbb864ee35858ad4dd2cf31e02fc4a154b724d7f1
|
||||
|
@ -1497,13 +1450,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"isarray@npm:~1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "isarray@npm:1.0.0"
|
||||
checksum: f032df8e02dce8ec565cf2eb605ea939bdccea528dbcf565cdf92bfa2da9110461159d86a537388ef1acef8815a330642d7885b29010e8f7eac967c9993b65ab
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"isexe@npm:^2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "isexe@npm:2.0.0"
|
||||
|
@ -1569,27 +1515,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash.assign@npm:^4.2.0":
|
||||
version: 4.2.0
|
||||
resolution: "lodash.assign@npm:4.2.0"
|
||||
checksum: 75bbc6733c9f577c448031b4051f990f068802708891f94be9d4c2faffd6a9ec67a2c49671dafc908a068d35687765464853282842b4560b662e6c903d11cc90
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash.get@npm:^4.4.2":
|
||||
version: 4.4.2
|
||||
resolution: "lodash.get@npm:4.4.2"
|
||||
checksum: e403047ddb03181c9d0e92df9556570e2b67e0f0a930fcbbbd779370972368f5568e914f913e93f3b08f6d492abc71e14d4e9b7a18916c31fa04bd2306efe545
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash.has@npm:^4.5.2":
|
||||
version: 4.5.2
|
||||
resolution: "lodash.has@npm:4.5.2"
|
||||
checksum: b3ec829a86852331d48b3730ff06088a283d128a3965aa521ffd942bcf5c82e06bed3164ff7a7751d11e768d88f0d7bab316192091489caf20f452d42f7055d5
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash.merge@npm:^4.6.2":
|
||||
version: 4.6.2
|
||||
resolution: "lodash.merge@npm:4.6.2"
|
||||
|
@ -1597,13 +1522,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash.uniq@npm:^4.5.0":
|
||||
version: 4.5.0
|
||||
resolution: "lodash.uniq@npm:4.5.0"
|
||||
checksum: a4779b57a8d0f3c441af13d9afe7ecff22dd1b8ce1129849f71d9bbc8e8ee4e46dfb4b7c28f7ad3d67481edd6e51126e4e2a6ee276e25906d10f7140187c392d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lru-cache@npm:^6.0.0":
|
||||
version: 6.0.0
|
||||
resolution: "lru-cache@npm:6.0.0"
|
||||
|
@ -1837,13 +1755,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"mri@npm:^1.1.5":
|
||||
version: 1.2.0
|
||||
resolution: "mri@npm:1.2.0"
|
||||
checksum: 83f515abbcff60150873e424894a2f65d68037e5a7fcde8a9e2b285ee9c13ac581b63cfc1e6826c4732de3aeb84902f7c1e16b7aff46cd3f897a0f757a894e85
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ms@npm:2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "ms@npm:2.0.0"
|
||||
|
@ -2115,13 +2026,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"process-nextick-args@npm:~2.0.0":
|
||||
version: 2.0.1
|
||||
resolution: "process-nextick-args@npm:2.0.1"
|
||||
checksum: 1d38588e520dab7cea67cbbe2efdd86a10cc7a074c09657635e34f035277b59fbb57d09d8638346bf7090f8e8ebc070c96fa5fd183b777fff4f5edff5e9466cf
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"promise-inflight@npm:^1.0.1":
|
||||
version: 1.0.1
|
||||
resolution: "promise-inflight@npm:1.0.1"
|
||||
|
@ -2191,21 +2095,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"readable-stream@npm:^2.3.7":
|
||||
version: 2.3.7
|
||||
resolution: "readable-stream@npm:2.3.7"
|
||||
dependencies:
|
||||
core-util-is: ~1.0.0
|
||||
inherits: ~2.0.3
|
||||
isarray: ~1.0.0
|
||||
process-nextick-args: ~2.0.0
|
||||
safe-buffer: ~5.1.1
|
||||
string_decoder: ~1.1.1
|
||||
util-deprecate: ~1.0.1
|
||||
checksum: e4920cf7549a60f8aaf694d483a0e61b2a878b969d224f89b3bc788b8d920075132c4b55a7494ee944c7b6a9a0eada28a7f6220d80b0312ece70bbf08eeca755
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"readable-stream@npm:^3.6.0":
|
||||
version: 3.6.0
|
||||
resolution: "readable-stream@npm:3.6.0"
|
||||
|
@ -2276,8 +2165,6 @@ __metadata:
|
|||
eslint-config-prettier: 8.5.0
|
||||
eslint-plugin-prettier: 4.2.1
|
||||
express: 4.18.1
|
||||
feedparser: 2.2.10
|
||||
helmet: 5.1.1
|
||||
megalodon: 4.1.0
|
||||
morgan: 1.10.0
|
||||
prettier: 2.7.1
|
||||
|
@ -2296,7 +2183,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"safe-buffer@npm:5.1.2, safe-buffer@npm:~5.1.0, safe-buffer@npm:~5.1.1":
|
||||
"safe-buffer@npm:5.1.2":
|
||||
version: 5.1.2
|
||||
resolution: "safe-buffer@npm:5.1.2"
|
||||
checksum: f2f1f7943ca44a594893a852894055cf619c1fbcb611237fc39e461ae751187e7baf4dc391a72125e0ac4fb2d8c5c0b3c71529622e6a58f46b960211e704903c
|
||||
|
@ -2330,13 +2217,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sax@npm:^1.2.4":
|
||||
version: 1.2.4
|
||||
resolution: "sax@npm:1.2.4"
|
||||
checksum: d3df7d32b897a2c2f28e941f732c71ba90e27c24f62ee918bd4d9a8cfb3553f2f81e5493c7f0be94a11c1911b643a9108f231dd6f60df3fa9586b5d2e3e9e1fe
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"semver@npm:^7.3.5":
|
||||
version: 7.3.7
|
||||
resolution: "semver@npm:7.3.7"
|
||||
|
@ -2518,15 +2398,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"string_decoder@npm:~1.1.1":
|
||||
version: 1.1.1
|
||||
resolution: "string_decoder@npm:1.1.1"
|
||||
dependencies:
|
||||
safe-buffer: ~5.1.0
|
||||
checksum: 9ab7e56f9d60a28f2be697419917c50cac19f3e8e6c28ef26ed5f4852289fe0de5d6997d29becf59028556f2c62983790c1d9ba1e2a3cc401768ca12d5183a5b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"strip-ansi@npm:^6.0.1":
|
||||
version: 6.0.1
|
||||
resolution: "strip-ansi@npm:6.0.1"
|
||||
|
@ -2676,7 +2547,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"util-deprecate@npm:^1.0.1, util-deprecate@npm:~1.0.1":
|
||||
"util-deprecate@npm:^1.0.1":
|
||||
version: 1.0.2
|
||||
resolution: "util-deprecate@npm:1.0.2"
|
||||
checksum: 474acf1146cb2701fe3b074892217553dfcf9a031280919ba1b8d651a068c9b15d863b7303cb15bd00a862b498e6cf4ad7b4a08fb134edd5a6f7641681cb54a2
|
||||
|
|
Reference in a new issue