Copy forward-headers from nginx to local node-fetch. Fixes #73

This commit is contained in:
Dessalines 2020-11-12 15:56:46 -06:00
parent ebe60406be
commit e86cd3eddb
18 changed files with 206 additions and 189 deletions

View File

@ -15,7 +15,7 @@
}, },
"repository": "https://github.com/LemmyNet/lemmy-ui", "repository": "https://github.com/LemmyNet/lemmy-ui",
"dependencies": { "dependencies": {
"@typescript-eslint/parser": "^4.6.1", "@typescript-eslint/parser": "^4.7.0",
"autosize": "^4.0.2", "autosize": "^4.0.2",
"choices.js": "^9.0.1", "choices.js": "^9.0.1",
"emoji-short-name": "^1.0.0", "emoji-short-name": "^1.0.0",
@ -43,7 +43,7 @@
"tippy.js": "^6.2.7", "tippy.js": "^6.2.7",
"toastify-js": "^1.9.3", "toastify-js": "^1.9.3",
"tributejs": "^5.1.3", "tributejs": "^5.1.3",
"ws": "^7.3.1" "ws": "^7.4.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.12.3", "@babel/core": "^7.12.3",
@ -53,29 +53,29 @@
"@babel/preset-typescript": "^7.12.1", "@babel/preset-typescript": "^7.12.1",
"@babel/runtime": "^7.12.5", "@babel/runtime": "^7.12.5",
"@types/autosize": "^3.0.6", "@types/autosize": "^3.0.6",
"@types/express": "^4.17.8", "@types/express": "^4.17.9",
"@types/node": "^14.14.6", "@types/node": "^14.14.7",
"@types/node-fetch": "^2.5.7", "@types/node-fetch": "^2.5.7",
"@types/serialize-javascript": "^4.0.0", "@types/serialize-javascript": "^4.0.0",
"babel-loader": "^8.0.6", "babel-loader": "^8.2.1",
"babel-plugin-inferno": "^6", "babel-plugin-inferno": "^6",
"bootstrap": "^4.5.3", "bootstrap": "^4.5.3",
"bootswatch": "^4.5.3", "bootswatch": "^4.5.3",
"clean-webpack-plugin": "^3.0.0", "clean-webpack-plugin": "^3.0.0",
"copy-webpack-plugin": "^6.3.0", "copy-webpack-plugin": "^6.3.0",
"css-loader": "^5.0.1", "css-loader": "^5.0.1",
"eslint": "^7.12.1", "eslint": "^7.13.0",
"eslint-plugin-jane": "^9.0.4", "eslint-plugin-jane": "^9.0.4",
"husky": "^4.3.0", "husky": "^4.3.0",
"lemmy-js-client": "^1.0.14", "lemmy-js-client": "^1.0.15",
"lint-staged": "^10.5.1", "lint-staged": "^10.5.1",
"mini-css-extract-plugin": "^1.2.1", "mini-css-extract-plugin": "^1.3.1",
"node-fetch": "^2.6.1", "node-fetch": "^2.6.1",
"node-sass": "^5.0.0", "node-sass": "^5.0.0",
"prettier": "^2.1.2", "prettier": "^2.1.2",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"run-node-webpack-plugin": "^1.3.0", "run-node-webpack-plugin": "^1.3.0",
"sass-loader": "^10.0.5", "sass-loader": "^10.1.0",
"sortpack": "^2.1.9", "sortpack": "^2.1.9",
"style-loader": "^2.0.0", "style-loader": "^2.0.0",
"terser": "^5.3.8", "terser": "^5.3.8",

View File

@ -1,4 +1,3 @@
// import cookieParser = require('cookie-parser');
import serialize from 'serialize-javascript'; import serialize from 'serialize-javascript';
import express from 'express'; import express from 'express';
import { StaticRouter } from 'inferno-router'; import { StaticRouter } from 'inferno-router';
@ -6,14 +5,16 @@ import { renderToString } from 'inferno-server';
import { matchPath } from 'inferno-router'; import { matchPath } from 'inferno-router';
import path from 'path'; import path from 'path';
import { App } from '../shared/components/app'; import { App } from '../shared/components/app';
import { IsoData } from '../shared/interfaces'; import { InitialFetchRequest, IsoData } from '../shared/interfaces';
import { routes } from '../shared/routes'; import { routes } from '../shared/routes';
import IsomorphicCookie from 'isomorphic-cookie'; import IsomorphicCookie from 'isomorphic-cookie';
import { lemmyHttp, setAuth } from '../shared/utils'; import { setAuth } from '../shared/utils';
import { GetSiteForm } from 'lemmy-js-client'; import { GetSiteForm, LemmyHttp } from 'lemmy-js-client';
import process from 'process'; import process from 'process';
import { Helmet } from 'inferno-helmet'; import { Helmet } from 'inferno-helmet';
import { initializeSite } from '../shared/initialize'; import { initializeSite } from '../shared/initialize';
import { httpUri } from '../shared/env';
import { IncomingHttpHeaders } from 'http';
const server = express(); const server = express();
const port = 1234; const port = 1234;
@ -34,12 +35,20 @@ server.get('/*', async (req, res) => {
let promises: Promise<any>[] = []; let promises: Promise<any>[] = [];
let headers = setForwardedHeaders(req.headers);
let initialFetchReq: InitialFetchRequest = {
client: new LemmyHttp(httpUri, headers),
auth,
path: req.path,
};
// Get site data first // Get site data first
let site = await lemmyHttp.getSite(getSiteForm); let site = await initialFetchReq.client.getSite(getSiteForm);
initializeSite(site); initializeSite(site);
if (activeRoute.fetchInitialData) { if (activeRoute.fetchInitialData) {
promises.push(...activeRoute.fetchInitialData(auth, req.path)); promises.push(...activeRoute.fetchInitialData(initialFetchReq));
} }
let routeData = await Promise.all(promises); let routeData = await Promise.all(promises);
@ -119,16 +128,25 @@ server.get('/*', async (req, res) => {
</html> </html>
`); `);
}); });
let Server = server.listen(port, () => {
server.listen(port, () => {
console.log(`http://localhost:${port}`); console.log(`http://localhost:${port}`);
}); });
/** function setForwardedHeaders(
* Used to restart server by fuseBox headers: IncomingHttpHeaders
*/ ): { [key: string]: string } {
export async function shutdown() { let out = {
Server.close(); host: headers.host,
Server = undefined; };
if (headers['x-real-ip']) {
out['x-real-ip'] = headers['x-real-ip'];
}
if (headers['x-forwarded-for']) {
out['x-forwarded-for'] = headers['x-forwarded-for'];
}
return out;
} }
process.on('SIGINT', () => { process.on('SIGINT', () => {

View File

@ -18,7 +18,6 @@ import {
setIsoData, setIsoData,
wsSubscribe, wsSubscribe,
isBrowser, isBrowser,
lemmyHttp,
setAuth, setAuth,
} from '../utils'; } from '../utils';
import autosize from 'autosize'; import autosize from 'autosize';
@ -26,6 +25,7 @@ import { SiteForm } from './site-form';
import { UserListing } from './user-listing'; import { UserListing } from './user-listing';
import { HtmlTags } from './html-tags'; import { HtmlTags } from './html-tags';
import { i18n } from '../i18next'; import { i18n } from '../i18next';
import { InitialFetchRequest } from 'shared/interfaces';
interface AdminSettingsState { interface AdminSettingsState {
siteRes: GetSiteResponse; siteRes: GetSiteResponse;
@ -71,10 +71,10 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
} }
} }
static fetchInitialData(auth: string, _path: string): Promise<any>[] { static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
let form: GetSiteConfig = {}; let form: GetSiteConfig = {};
setAuth(form, auth); setAuth(form, req.auth);
return [lemmyHttp.getSiteConfig(form)]; return [req.client.getSiteConfig(form)];
} }
componentDidMount() { componentDidMount() {

View File

@ -18,13 +18,13 @@ import {
toast, toast,
getPageFromProps, getPageFromProps,
isBrowser, isBrowser,
lemmyHttp,
setAuth, setAuth,
setIsoData, setIsoData,
wsSubscribe, wsSubscribe,
} from '../utils'; } from '../utils';
import { CommunityLink } from './community-link'; import { CommunityLink } from './community-link';
import { i18n } from '../i18next'; import { i18n } from '../i18next';
import { InitialFetchRequest } from 'shared/interfaces';
const communityLimit = 100; const communityLimit = 100;
@ -237,17 +237,17 @@ export class Communities extends Component<any, CommunitiesState> {
WebSocketService.Instance.listCommunities(listCommunitiesForm); WebSocketService.Instance.listCommunities(listCommunitiesForm);
} }
static fetchInitialData(auth: string, path: string): Promise<any>[] { static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
let pathSplit = path.split('/'); let pathSplit = req.path.split('/');
let page = pathSplit[3] ? Number(pathSplit[3]) : 1; let page = pathSplit[3] ? Number(pathSplit[3]) : 1;
let listCommunitiesForm: ListCommunitiesForm = { let listCommunitiesForm: ListCommunitiesForm = {
sort: SortType.TopAll, sort: SortType.TopAll,
limit: communityLimit, limit: communityLimit,
page, page,
}; };
setAuth(listCommunitiesForm, auth); setAuth(listCommunitiesForm, req.auth);
return [lemmyHttp.listCommunities(listCommunitiesForm)]; return [req.client.listCommunities(listCommunitiesForm)];
} }
parseMessage(msg: WebSocketJsonResponse) { parseMessage(msg: WebSocketJsonResponse) {

View File

@ -1,6 +1,6 @@
import { Component, linkEvent } from 'inferno'; import { Component, linkEvent } from 'inferno';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { DataType } from '../interfaces'; import { DataType, InitialFetchRequest } from '../interfaces';
import { import {
UserOperation, UserOperation,
GetCommunityResponse, GetCommunityResponse,
@ -50,7 +50,6 @@ import {
setIsoData, setIsoData,
wsSubscribe, wsSubscribe,
isBrowser, isBrowser,
lemmyHttp,
setAuth, setAuth,
communityRSSUrl, communityRSSUrl,
} from '../utils'; } from '../utils';
@ -150,8 +149,8 @@ export class Community extends Component<any, State> {
}; };
} }
static fetchInitialData(auth: string, path: string): Promise<any>[] { static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
let pathSplit = path.split('/'); let pathSplit = req.path.split('/');
let promises: Promise<any>[] = []; let promises: Promise<any>[] = [];
// It can be /c/main, or /c/1 // It can be /c/main, or /c/1
@ -165,8 +164,8 @@ export class Community extends Component<any, State> {
} }
let communityForm: GetCommunityForm = id ? { id } : { name: name_ }; let communityForm: GetCommunityForm = id ? { id } : { name: name_ };
setAuth(communityForm, auth); setAuth(communityForm, req.auth);
promises.push(lemmyHttp.getCommunity(communityForm)); promises.push(req.client.getCommunity(communityForm));
let dataType: DataType = pathSplit[4] let dataType: DataType = pathSplit[4]
? DataType[pathSplit[4]] ? DataType[pathSplit[4]]
@ -188,8 +187,8 @@ export class Community extends Component<any, State> {
type_: ListingType.Community, type_: ListingType.Community,
}; };
this.setIdOrName(getPostsForm, id, name_); this.setIdOrName(getPostsForm, id, name_);
setAuth(getPostsForm, auth); setAuth(getPostsForm, req.auth);
promises.push(lemmyHttp.getPosts(getPostsForm)); promises.push(req.client.getPosts(getPostsForm));
} else { } else {
let getCommentsForm: GetCommentsForm = { let getCommentsForm: GetCommentsForm = {
page, page,
@ -198,11 +197,11 @@ export class Community extends Component<any, State> {
type_: ListingType.Community, type_: ListingType.Community,
}; };
this.setIdOrName(getCommentsForm, id, name_); this.setIdOrName(getCommentsForm, id, name_);
setAuth(getCommentsForm, auth); setAuth(getCommentsForm, req.auth);
promises.push(lemmyHttp.getComments(getCommentsForm)); promises.push(req.client.getComments(getCommentsForm));
} }
promises.push(lemmyHttp.listCategories()); promises.push(req.client.listCategories());
return promises; return promises;
} }

View File

@ -16,10 +16,10 @@ import {
wsJsonToRes, wsJsonToRes,
wsSubscribe, wsSubscribe,
isBrowser, isBrowser,
lemmyHttp,
} from '../utils'; } from '../utils';
import { WebSocketService, UserService } from '../services'; import { WebSocketService, UserService } from '../services';
import { i18n } from '../i18next'; import { i18n } from '../i18next';
import { InitialFetchRequest } from 'shared/interfaces';
interface CreateCommunityState { interface CreateCommunityState {
site: Site; site: Site;
@ -100,8 +100,8 @@ export class CreateCommunity extends Component<any, CreateCommunityState> {
this.props.history.push(`/c/${community.name}`); this.props.history.push(`/c/${community.name}`);
} }
static fetchInitialData(_auth: string, _path: string): Promise<any>[] { static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
return [lemmyHttp.listCategories()]; return [req.client.listCategories()];
} }
parseMessage(msg: WebSocketJsonResponse) { parseMessage(msg: WebSocketJsonResponse) {

View File

@ -4,7 +4,6 @@ import { PostForm } from './post-form';
import { HtmlTags } from './html-tags'; import { HtmlTags } from './html-tags';
import { import {
isBrowser, isBrowser,
lemmyHttp,
setAuth, setAuth,
setIsoData, setIsoData,
toast, toast,
@ -23,6 +22,7 @@ import {
SortType, SortType,
} from 'lemmy-js-client'; } from 'lemmy-js-client';
import { i18n } from '../i18next'; import { i18n } from '../i18next';
import { InitialFetchRequest } from 'shared/interfaces';
interface CreatePostState { interface CreatePostState {
site: Site; site: Site;
@ -138,13 +138,13 @@ export class CreatePost extends Component<any, CreatePostState> {
this.props.history.push(`/post/${id}`); this.props.history.push(`/post/${id}`);
} }
static fetchInitialData(auth: string, _path: string): Promise<any>[] { static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
let listCommunitiesForm: ListCommunitiesForm = { let listCommunitiesForm: ListCommunitiesForm = {
sort: SortType.TopAll, sort: SortType.TopAll,
limit: 9999, limit: 9999,
}; };
setAuth(listCommunitiesForm, auth); setAuth(listCommunitiesForm, req.auth);
return [lemmyHttp.listCommunities(listCommunitiesForm)]; return [req.client.listCommunities(listCommunitiesForm)];
} }
parseMessage(msg: WebSocketJsonResponse) { parseMessage(msg: WebSocketJsonResponse) {

View File

@ -15,7 +15,6 @@ import {
import { import {
getRecipientIdFromProps, getRecipientIdFromProps,
isBrowser, isBrowser,
lemmyHttp,
setAuth, setAuth,
setIsoData, setIsoData,
toast, toast,
@ -23,6 +22,7 @@ import {
wsSubscribe, wsSubscribe,
} from '../utils'; } from '../utils';
import { i18n } from '../i18next'; import { i18n } from '../i18next';
import { InitialFetchRequest } from 'shared/interfaces';
interface CreatePrivateMessageProps {} interface CreatePrivateMessageProps {}
@ -78,15 +78,15 @@ export class CreatePrivateMessage extends Component<
WebSocketService.Instance.getUserDetails(form); WebSocketService.Instance.getUserDetails(form);
} }
static fetchInitialData(auth: string, path: string): Promise<any>[] { static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
let user_id = Number(path.split('/').pop()); let user_id = Number(req.path.split('/').pop());
let form: GetUserDetailsForm = { let form: GetUserDetailsForm = {
user_id, user_id,
sort: SortType.New, sort: SortType.New,
saved_only: false, saved_only: false,
}; };
setAuth(form, auth); setAuth(form, req.auth);
return [lemmyHttp.getUserDetails(form)]; return [req.client.getUserDetails(form)];
} }
get documentTitle(): string { get documentTitle(): string {

View File

@ -30,7 +30,6 @@ import {
setupTippy, setupTippy,
setIsoData, setIsoData,
wsSubscribe, wsSubscribe,
lemmyHttp,
setAuth, setAuth,
isBrowser, isBrowser,
} from '../utils'; } from '../utils';
@ -39,6 +38,7 @@ import { PrivateMessage } from './private-message';
import { HtmlTags } from './html-tags'; import { HtmlTags } from './html-tags';
import { SortSelect } from './sort-select'; import { SortSelect } from './sort-select';
import { i18n } from '../i18next'; import { i18n } from '../i18next';
import { InitialFetchRequest } from 'shared/interfaces';
enum UnreadOrAll { enum UnreadOrAll {
Unread, Unread,
@ -404,7 +404,7 @@ export class Inbox extends Component<any, InboxState> {
i.refetch(); i.refetch();
} }
static fetchInitialData(auth: string, _path: string): Promise<any>[] { static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
let promises: Promise<any>[] = []; let promises: Promise<any>[] = [];
// It can be /u/me, or /username/1 // It can be /u/me, or /username/1
@ -414,8 +414,8 @@ export class Inbox extends Component<any, InboxState> {
page: 1, page: 1,
limit: fetchLimit, limit: fetchLimit,
}; };
setAuth(repliesForm, auth); setAuth(repliesForm, req.auth);
promises.push(lemmyHttp.getReplies(repliesForm)); promises.push(req.client.getReplies(repliesForm));
let userMentionsForm: GetUserMentionsForm = { let userMentionsForm: GetUserMentionsForm = {
sort: SortType.New, sort: SortType.New,
@ -423,16 +423,16 @@ export class Inbox extends Component<any, InboxState> {
page: 1, page: 1,
limit: fetchLimit, limit: fetchLimit,
}; };
setAuth(userMentionsForm, auth); setAuth(userMentionsForm, req.auth);
promises.push(lemmyHttp.getUserMentions(userMentionsForm)); promises.push(req.client.getUserMentions(userMentionsForm));
let privateMessagesForm: GetPrivateMessagesForm = { let privateMessagesForm: GetPrivateMessagesForm = {
unread_only: true, unread_only: true,
page: 1, page: 1,
limit: fetchLimit, limit: fetchLimit,
}; };
setAuth(privateMessagesForm, auth); setAuth(privateMessagesForm, req.auth);
promises.push(lemmyHttp.getPrivateMessages(privateMessagesForm)); promises.push(req.client.getPrivateMessages(privateMessagesForm));
return promises; return promises;
} }

View File

@ -24,7 +24,7 @@ import {
BanUserResponse, BanUserResponse,
WebSocketJsonResponse, WebSocketJsonResponse,
} from 'lemmy-js-client'; } from 'lemmy-js-client';
import { DataType } from '../interfaces'; import { DataType, InitialFetchRequest } from '../interfaces';
import { WebSocketService, UserService } from '../services'; import { WebSocketService, UserService } from '../services';
import { PostListings } from './post-listings'; import { PostListings } from './post-listings';
import { CommentNodes } from './comment-nodes'; import { CommentNodes } from './comment-nodes';
@ -56,7 +56,6 @@ import {
wsSubscribe, wsSubscribe,
isBrowser, isBrowser,
setAuth, setAuth,
lemmyHttp,
} from '../utils'; } from '../utils';
import { i18n } from '../i18next'; import { i18n } from '../i18next';
import { T } from 'inferno-i18next'; import { T } from 'inferno-i18next';
@ -175,8 +174,8 @@ export class Main extends Component<any, MainState> {
}; };
} }
static fetchInitialData(auth: string, path: string): Promise<any>[] { static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
let pathSplit = path.split('/'); let pathSplit = req.path.split('/');
let dataType: DataType = pathSplit[3] let dataType: DataType = pathSplit[3]
? DataType[pathSplit[3]] ? DataType[pathSplit[3]]
: DataType.Post; : DataType.Post;
@ -206,8 +205,8 @@ export class Main extends Component<any, MainState> {
sort, sort,
type_, type_,
}; };
setAuth(getPostsForm, auth); setAuth(getPostsForm, req.auth);
promises.push(lemmyHttp.getPosts(getPostsForm)); promises.push(req.client.getPosts(getPostsForm));
} else { } else {
let getCommentsForm: GetCommentsForm = { let getCommentsForm: GetCommentsForm = {
page, page,
@ -215,18 +214,18 @@ export class Main extends Component<any, MainState> {
sort, sort,
type_, type_,
}; };
setAuth(getCommentsForm, auth); setAuth(getCommentsForm, req.auth);
promises.push(lemmyHttp.getComments(getCommentsForm)); promises.push(req.client.getComments(getCommentsForm));
} }
let trendingCommunitiesForm: ListCommunitiesForm = { let trendingCommunitiesForm: ListCommunitiesForm = {
sort: SortType.Hot, sort: SortType.Hot,
limit: 6, limit: 6,
}; };
promises.push(lemmyHttp.listCommunities(trendingCommunitiesForm)); promises.push(req.client.listCommunities(trendingCommunitiesForm));
if (auth) { if (req.auth) {
promises.push(lemmyHttp.getFollowedCommunities({ auth })); promises.push(req.client.getFollowedCommunities({ auth: req.auth }));
} }
return promises; return promises;

View File

@ -26,12 +26,12 @@ import {
setIsoData, setIsoData,
wsSubscribe, wsSubscribe,
isBrowser, isBrowser,
lemmyHttp,
} from '../utils'; } from '../utils';
import { MomentTime } from './moment-time'; import { MomentTime } from './moment-time';
import { HtmlTags } from './html-tags'; import { HtmlTags } from './html-tags';
import moment from 'moment'; import moment from 'moment';
import { i18n } from '../i18next'; import { i18n } from '../i18next';
import { InitialFetchRequest } from 'shared/interfaces';
interface ModlogState { interface ModlogState {
combined: { combined: {
@ -443,8 +443,8 @@ export class Modlog extends Component<any, ModlogState> {
WebSocketService.Instance.getModlog(modlogForm); WebSocketService.Instance.getModlog(modlogForm);
} }
static fetchInitialData(_auth: string, path: string): Promise<any>[] { static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
let pathSplit = path.split('/'); let pathSplit = req.path.split('/');
let communityId = pathSplit[3]; let communityId = pathSplit[3];
let promises: Promise<any>[] = []; let promises: Promise<any>[] = [];
@ -457,7 +457,7 @@ export class Modlog extends Component<any, ModlogState> {
modlogForm.community_id = Number(communityId); modlogForm.community_id = Number(communityId);
} }
promises.push(lemmyHttp.getModlog(modlogForm)); promises.push(req.client.getModlog(modlogForm));
return promises; return promises;
} }

View File

@ -25,7 +25,11 @@ import {
ListCategoriesResponse, ListCategoriesResponse,
Category, Category,
} from 'lemmy-js-client'; } from 'lemmy-js-client';
import { CommentSortType, CommentViewType } from '../interfaces'; import {
CommentSortType,
CommentViewType,
InitialFetchRequest,
} from '../interfaces';
import { WebSocketService, UserService } from '../services'; import { WebSocketService, UserService } from '../services';
import { import {
wsJsonToRes, wsJsonToRes,
@ -41,7 +45,6 @@ import {
getCommentIdFromProps, getCommentIdFromProps,
wsSubscribe, wsSubscribe,
setAuth, setAuth,
lemmyHttp,
isBrowser, isBrowser,
previewLines, previewLines,
isImage, isImage,
@ -112,8 +115,8 @@ export class Post extends Component<any, PostState> {
WebSocketService.Instance.getPost(form); WebSocketService.Instance.getPost(form);
} }
static fetchInitialData(auth: string, path: string): Promise<any>[] { static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
let pathSplit = path.split('/'); let pathSplit = req.path.split('/');
let promises: Promise<any>[] = []; let promises: Promise<any>[] = [];
let id = Number(pathSplit[2]); let id = Number(pathSplit[2]);
@ -121,10 +124,10 @@ export class Post extends Component<any, PostState> {
let postForm: GetPostForm = { let postForm: GetPostForm = {
id, id,
}; };
setAuth(postForm, auth); setAuth(postForm, req.auth);
promises.push(lemmyHttp.getPost(postForm)); promises.push(req.client.getPost(postForm));
promises.push(lemmyHttp.listCategories()); promises.push(req.client.listCategories());
return promises; return promises;
} }

View File

@ -27,7 +27,6 @@ import {
commentsToFlatNodes, commentsToFlatNodes,
setIsoData, setIsoData,
wsSubscribe, wsSubscribe,
lemmyHttp,
setAuth, setAuth,
} from '../utils'; } from '../utils';
import { PostListing } from './post-listing'; import { PostListing } from './post-listing';
@ -37,6 +36,7 @@ import { CommunityLink } from './community-link';
import { SortSelect } from './sort-select'; import { SortSelect } from './sort-select';
import { CommentNodes } from './comment-nodes'; import { CommentNodes } from './comment-nodes';
import { i18n } from '../i18next'; import { i18n } from '../i18next';
import { InitialFetchRequest } from 'shared/interfaces';
interface SearchProps { interface SearchProps {
q: string; q: string;
@ -132,8 +132,8 @@ export class Search extends Component<any, SearchState> {
}; };
} }
static fetchInitialData(auth: string, path: string): Promise<any>[] { static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
let pathSplit = path.split('/'); let pathSplit = req.path.split('/');
let promises: Promise<any>[] = []; let promises: Promise<any>[] = [];
let form: SearchForm = { let form: SearchForm = {
@ -143,10 +143,10 @@ export class Search extends Component<any, SearchState> {
page: this.getPageFromProps(pathSplit[9]), page: this.getPageFromProps(pathSplit[9]),
limit: fetchLimit, limit: fetchLimit,
}; };
setAuth(form, auth); setAuth(form, req.auth);
if (form.q != '') { if (form.q != '') {
promises.push(lemmyHttp.search(form)); promises.push(req.client.search(form));
} }
return promises; return promises;

View File

@ -17,7 +17,7 @@ import {
PostResponse, PostResponse,
BanUserResponse, BanUserResponse,
} from 'lemmy-js-client'; } from 'lemmy-js-client';
import { UserDetailsView } from '../interfaces'; import { InitialFetchRequest, UserDetailsView } from '../interfaces';
import { WebSocketService, UserService } from '../services'; import { WebSocketService, UserService } from '../services';
import { import {
wsJsonToRes, wsJsonToRes,
@ -41,7 +41,6 @@ import {
saveCommentRes, saveCommentRes,
createPostLikeFindRes, createPostLikeFindRes,
setAuth, setAuth,
lemmyHttp,
previewLines, previewLines,
editPostFindRes, editPostFindRes,
} from '../utils'; } from '../utils';
@ -187,8 +186,8 @@ export class User extends Component<any, UserState> {
return page ? Number(page) : 1; return page ? Number(page) : 1;
} }
static fetchInitialData(auth: string, path: string): Promise<any>[] { static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
let pathSplit = path.split('/'); let pathSplit = req.path.split('/');
let promises: Promise<any>[] = []; let promises: Promise<any>[] = [];
// It can be /u/me, or /username/1 // It can be /u/me, or /username/1
@ -212,8 +211,8 @@ export class User extends Component<any, UserState> {
limit: fetchLimit, limit: fetchLimit,
}; };
this.setIdOrName(form, user_id, username); this.setIdOrName(form, user_id, username);
setAuth(form, auth); setAuth(form, req.auth);
promises.push(lemmyHttp.getUserDetails(form)); promises.push(req.client.getUserDetails(form));
return promises; return promises;
} }

View File

@ -1,4 +1,4 @@
import { GetSiteResponse } from 'lemmy-js-client'; import { GetSiteResponse, LemmyHttp } from 'lemmy-js-client';
export interface IsoData { export interface IsoData {
path: string; path: string;
@ -15,6 +15,12 @@ declare global {
} }
} }
export interface InitialFetchRequest {
auth: string;
path: string;
client: LemmyHttp;
}
export enum CommentSortType { export enum CommentSortType {
Hot, Hot,
Top, Top,

View File

@ -15,9 +15,10 @@ import { AdminSettings } from './components/admin-settings';
import { Inbox } from './components/inbox'; import { Inbox } from './components/inbox';
import { Search } from './components/search'; import { Search } from './components/search';
import { Instances } from './components/instances'; import { Instances } from './components/instances';
import { InitialFetchRequest } from './interfaces';
interface IRoutePropsWithFetch extends IRouteProps { interface IRoutePropsWithFetch extends IRouteProps {
fetchInitialData?(auth: string, path: string): Promise<any>[]; fetchInitialData?(req: InitialFetchRequest): Promise<any>[];
} }
export const routes: IRoutePropsWithFetch[] = [ export const routes: IRoutePropsWithFetch[] = [
@ -25,12 +26,12 @@ export const routes: IRoutePropsWithFetch[] = [
path: `/`, path: `/`,
exact: true, exact: true,
component: Main, component: Main,
fetchInitialData: (auth, path) => Main.fetchInitialData(auth, path), fetchInitialData: req => Main.fetchInitialData(req),
}, },
{ {
path: `/home/data_type/:data_type/listing_type/:listing_type/sort/:sort/page/:page`, path: `/home/data_type/:data_type/listing_type/:listing_type/sort/:sort/page/:page`,
component: Main, component: Main,
fetchInitialData: (auth, path) => Main.fetchInitialData(auth, path), fetchInitialData: req => Main.fetchInitialData(req),
}, },
{ {
path: `/login`, path: `/login`,
@ -39,101 +40,98 @@ export const routes: IRoutePropsWithFetch[] = [
{ {
path: `/create_post`, path: `/create_post`,
component: CreatePost, component: CreatePost,
fetchInitialData: (auth, path) => CreatePost.fetchInitialData(auth, path), fetchInitialData: req => CreatePost.fetchInitialData(req),
}, },
{ {
path: `/create_community`, path: `/create_community`,
component: CreateCommunity, component: CreateCommunity,
fetchInitialData: (auth, path) => fetchInitialData: req => CreateCommunity.fetchInitialData(req),
CreateCommunity.fetchInitialData(auth, path),
}, },
{ {
path: `/create_private_message/recipient/:recipient_id`, path: `/create_private_message/recipient/:recipient_id`,
component: CreatePrivateMessage, component: CreatePrivateMessage,
fetchInitialData: (auth, path) => fetchInitialData: req => CreatePrivateMessage.fetchInitialData(req),
CreatePrivateMessage.fetchInitialData(auth, path),
}, },
{ {
path: `/communities/page/:page`, path: `/communities/page/:page`,
component: Communities, component: Communities,
fetchInitialData: (auth, path) => Communities.fetchInitialData(auth, path), fetchInitialData: req => Communities.fetchInitialData(req),
}, },
{ {
path: `/communities`, path: `/communities`,
component: Communities, component: Communities,
fetchInitialData: (auth, path) => Communities.fetchInitialData(auth, path), fetchInitialData: req => Communities.fetchInitialData(req),
}, },
{ {
path: `/post/:id/comment/:comment_id`, path: `/post/:id/comment/:comment_id`,
component: Post, component: Post,
fetchInitialData: (auth, path) => Post.fetchInitialData(auth, path), fetchInitialData: req => Post.fetchInitialData(req),
}, },
{ {
path: `/post/:id`, path: `/post/:id`,
component: Post, component: Post,
fetchInitialData: (auth, path) => Post.fetchInitialData(auth, path), fetchInitialData: req => Post.fetchInitialData(req),
}, },
{ {
path: `/c/:name/data_type/:data_type/sort/:sort/page/:page`, path: `/c/:name/data_type/:data_type/sort/:sort/page/:page`,
component: Community, component: Community,
fetchInitialData: (auth, path) => Community.fetchInitialData(auth, path), fetchInitialData: req => Community.fetchInitialData(req),
}, },
{ {
path: `/community/:id`, path: `/community/:id`,
component: Community, component: Community,
fetchInitialData: (auth, path) => Community.fetchInitialData(auth, path), fetchInitialData: req => Community.fetchInitialData(req),
}, },
{ {
path: `/c/:name`, path: `/c/:name`,
component: Community, component: Community,
fetchInitialData: (auth, path) => Community.fetchInitialData(auth, path), fetchInitialData: req => Community.fetchInitialData(req),
}, },
{ {
path: `/u/:username/view/:view/sort/:sort/page/:page`, path: `/u/:username/view/:view/sort/:sort/page/:page`,
component: User, component: User,
fetchInitialData: (auth, path) => User.fetchInitialData(auth, path), fetchInitialData: req => User.fetchInitialData(req),
}, },
{ {
path: `/user/:id`, path: `/user/:id`,
component: User, component: User,
fetchInitialData: (auth, path) => User.fetchInitialData(auth, path), fetchInitialData: req => User.fetchInitialData(req),
}, },
{ {
path: `/u/:username`, path: `/u/:username`,
component: User, component: User,
fetchInitialData: (auth, path) => User.fetchInitialData(auth, path), fetchInitialData: req => User.fetchInitialData(req),
}, },
{ {
path: `/inbox`, path: `/inbox`,
component: Inbox, component: Inbox,
fetchInitialData: (auth, path) => Inbox.fetchInitialData(auth, path), fetchInitialData: req => Inbox.fetchInitialData(req),
}, },
{ {
path: `/modlog/community/:community_id`, path: `/modlog/community/:community_id`,
component: Modlog, component: Modlog,
fetchInitialData: (auth, path) => Modlog.fetchInitialData(auth, path), fetchInitialData: req => Modlog.fetchInitialData(req),
}, },
{ {
path: `/modlog`, path: `/modlog`,
component: Modlog, component: Modlog,
fetchInitialData: (auth, path) => Modlog.fetchInitialData(auth, path), fetchInitialData: req => Modlog.fetchInitialData(req),
}, },
{ path: `/setup`, component: Setup }, { path: `/setup`, component: Setup },
{ {
path: `/admin`, path: `/admin`,
component: AdminSettings, component: AdminSettings,
fetchInitialData: (auth, path) => fetchInitialData: req => AdminSettings.fetchInitialData(req),
AdminSettings.fetchInitialData(auth, path),
}, },
{ {
path: `/search/q/:q/type/:type/sort/:sort/page/:page`, path: `/search/q/:q/type/:type/sort/:sort/page/:page`,
component: Search, component: Search,
fetchInitialData: (auth, path) => Search.fetchInitialData(auth, path), fetchInitialData: req => Search.fetchInitialData(req),
}, },
{ {
path: `/search`, path: `/search`,
component: Search, component: Search,
fetchInitialData: (auth, path) => Search.fetchInitialData(auth, path), fetchInitialData: req => Search.fetchInitialData(req),
}, },
{ {
path: `/password_change/:token`, path: `/password_change/:token`,

View File

@ -43,11 +43,8 @@ import {
SearchResponse, SearchResponse,
CommentResponse, CommentResponse,
PostResponse, PostResponse,
LemmyHttp,
} from 'lemmy-js-client'; } from 'lemmy-js-client';
import { httpUri } from './env';
import { CommentSortType, DataType, IsoData } from './interfaces'; import { CommentSortType, DataType, IsoData } from './interfaces';
import { UserService, WebSocketService } from './services'; import { UserService, WebSocketService } from './services';
@ -84,8 +81,6 @@ export const postRefetchSeconds: number = 60 * 1000;
export const fetchLimit: number = 20; export const fetchLimit: number = 20;
export const mentionDropdownFetchLimit = 10; export const mentionDropdownFetchLimit = 10;
export const lemmyHttp = new LemmyHttp(httpUri);
export const languages = [ export const languages = [
{ code: 'ca', name: 'Català' }, { code: 'ca', name: 'Català' },
{ code: 'en', name: 'English' }, { code: 'en', name: 'English' },

126
yarn.lock
View File

@ -1079,10 +1079,10 @@
"@types/qs" "*" "@types/qs" "*"
"@types/range-parser" "*" "@types/range-parser" "*"
"@types/express@^4.17.8": "@types/express@^4.17.9":
version "4.17.8" version "4.17.9"
resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.8.tgz#3df4293293317e61c60137d273a2e96cd8d5f27a" resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.9.tgz#f5f2df6add703ff28428add52bdec8a1091b0a78"
integrity sha512-wLhcKh3PMlyA2cNAB9sjM1BntnhPMiM0JOBwPBqttjHev2428MLEB4AYVN+d8s2iyCVZac+o41Pflm/ZH5vLXQ== integrity sha512-SDzEIZInC4sivGIFY4Sz1GG6J9UObPwCInYJjko2jzOf/Imx/dlpume6Xxwj1ORL82tBbmN4cPDIDkLbWHk9hw==
dependencies: dependencies:
"@types/body-parser" "*" "@types/body-parser" "*"
"@types/express-serve-static-core" "*" "@types/express-serve-static-core" "*"
@ -1142,10 +1142,10 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.6.0.tgz#7d4411bf5157339337d7cff864d9ff45f177b499" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.6.0.tgz#7d4411bf5157339337d7cff864d9ff45f177b499"
integrity sha512-mikldZQitV94akrc4sCcSjtJfsTKt4p+e/s0AGscVA6XArQ9kFclP+ZiYUMnq987rc6QlYxXv/EivqlfSLxpKA== integrity sha512-mikldZQitV94akrc4sCcSjtJfsTKt4p+e/s0AGscVA6XArQ9kFclP+ZiYUMnq987rc6QlYxXv/EivqlfSLxpKA==
"@types/node@^14.14.6": "@types/node@^14.14.7":
version "14.14.6" version "14.14.7"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.6.tgz#146d3da57b3c636cc0d1769396ce1cfa8991147f" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.7.tgz#8ea1e8f8eae2430cf440564b98c6dfce1ec5945d"
integrity sha512-6QlRuqsQ/Ox/aJEQWBEJG7A9+u7oSYl3mem/K8IzxXG/kAGbV1YPD9Bg9Zw3vyxC/YP+zONKwy8hGkSt1jxFMw== integrity sha512-Zw1vhUSQZYw+7u5dAwNbIA9TuTotpzY/OF7sJM9FqPOF3SPjKnxrjoTktXDZgUjybf4cWVBP7O8wvKdSaGHweg==
"@types/normalize-package-data@^2.4.0": "@types/normalize-package-data@^2.4.0":
version "2.4.0" version "2.4.0"
@ -1270,14 +1270,14 @@
"@typescript-eslint/typescript-estree" "4.5.0" "@typescript-eslint/typescript-estree" "4.5.0"
debug "^4.1.1" debug "^4.1.1"
"@typescript-eslint/parser@^4.6.1": "@typescript-eslint/parser@^4.7.0":
version "4.6.1" version "4.7.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.6.1.tgz#b801bff67b536ecc4a840ac9289ba2be57e02428" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.7.0.tgz#44bdab0f788b478178368baa65d3365fdc63da1c"
integrity sha512-lScKRPt1wM9UwyKkGKyQDqf0bh6jm8DQ5iN37urRIXDm16GEv+HGEmum2Fc423xlk5NUOkOpfTnKZc/tqKZkDQ== integrity sha512-+meGV8bMP1sJHBI2AFq1GeTwofcGiur8LoIr6v+rEmD9knyCqDlrQcFHR0KDDfldHIFDU/enZ53fla6ReF4wRw==
dependencies: dependencies:
"@typescript-eslint/scope-manager" "4.6.1" "@typescript-eslint/scope-manager" "4.7.0"
"@typescript-eslint/types" "4.6.1" "@typescript-eslint/types" "4.7.0"
"@typescript-eslint/typescript-estree" "4.6.1" "@typescript-eslint/typescript-estree" "4.7.0"
debug "^4.1.1" debug "^4.1.1"
"@typescript-eslint/scope-manager@4.1.0": "@typescript-eslint/scope-manager@4.1.0":
@ -1296,13 +1296,13 @@
"@typescript-eslint/types" "4.5.0" "@typescript-eslint/types" "4.5.0"
"@typescript-eslint/visitor-keys" "4.5.0" "@typescript-eslint/visitor-keys" "4.5.0"
"@typescript-eslint/scope-manager@4.6.1": "@typescript-eslint/scope-manager@4.7.0":
version "4.6.1" version "4.7.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.6.1.tgz#21872b91cbf7adfc7083f17b8041149148baf992" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.7.0.tgz#2115526085fb72723ccdc1eeae75dec7126220ed"
integrity sha512-f95+80r6VdINYscJY1KDUEDcxZ3prAWHulL4qRDfNVD0I5QAVSGqFkwHERDoLYJJWmEAkUMdQVvx7/c2Hp+Bjg== integrity sha512-ILITvqwDJYbcDCROj6+Ob0oCKNg3SH46iWcNcTIT9B5aiVssoTYkhKjxOMNzR1F7WSJkik4zmuqve5MdnA0DyA==
dependencies: dependencies:
"@typescript-eslint/types" "4.6.1" "@typescript-eslint/types" "4.7.0"
"@typescript-eslint/visitor-keys" "4.6.1" "@typescript-eslint/visitor-keys" "4.7.0"
"@typescript-eslint/types@4.1.0": "@typescript-eslint/types@4.1.0":
version "4.1.0" version "4.1.0"
@ -1314,10 +1314,10 @@
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.5.0.tgz#98256e07bad1c8d15d0c9627ebec82fd971bb3c3" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.5.0.tgz#98256e07bad1c8d15d0c9627ebec82fd971bb3c3"
integrity sha512-n2uQoXnyWNk0Les9MtF0gCK3JiWd987JQi97dMSxBOzVoLZXCNtxFckVqt1h8xuI1ix01t+iMY4h4rFMj/303g== integrity sha512-n2uQoXnyWNk0Les9MtF0gCK3JiWd987JQi97dMSxBOzVoLZXCNtxFckVqt1h8xuI1ix01t+iMY4h4rFMj/303g==
"@typescript-eslint/types@4.6.1": "@typescript-eslint/types@4.7.0":
version "4.6.1" version "4.7.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.6.1.tgz#d3ad7478f53f22e7339dc006ab61aac131231552" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.7.0.tgz#5e95ef5c740f43d942542b35811f87b62fccca69"
integrity sha512-k2ZCHhJ96YZyPIsykickez+OMHkz06xppVLfJ+DY90i532/Cx2Z+HiRMH8YZQo7a4zVd/TwNBuRCdXlGK4yo8w== integrity sha512-uLszFe0wExJc+I7q0Z/+BnP7wao/kzX0hB5vJn4LIgrfrMLgnB2UXoReV19lkJQS1a1mHWGGODSxnBx6JQC3Sg==
"@typescript-eslint/typescript-estree@4.1.0": "@typescript-eslint/typescript-estree@4.1.0":
version "4.1.0" version "4.1.0"
@ -1347,13 +1347,13 @@
semver "^7.3.2" semver "^7.3.2"
tsutils "^3.17.1" tsutils "^3.17.1"
"@typescript-eslint/typescript-estree@4.6.1": "@typescript-eslint/typescript-estree@4.7.0":
version "4.6.1" version "4.7.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.6.1.tgz#6025cce724329413f57e4959b2d676fceeca246f" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.7.0.tgz#539531167f05ba20eb0b6785567076679e29d393"
integrity sha512-/J/kxiyjQQKqEr5kuKLNQ1Finpfb8gf/NpbwqFFYEBjxOsZ621r9AqwS9UDRA1Rrr/eneX/YsbPAIhU2rFLjXQ== integrity sha512-5XZRQznD1MfUmxu1t8/j2Af4OxbA7EFU2rbo0No7meb46eHgGkSieFdfV6omiC/DGIBhH9H9gXn7okBbVOm8jw==
dependencies: dependencies:
"@typescript-eslint/types" "4.6.1" "@typescript-eslint/types" "4.7.0"
"@typescript-eslint/visitor-keys" "4.6.1" "@typescript-eslint/visitor-keys" "4.7.0"
debug "^4.1.1" debug "^4.1.1"
globby "^11.0.1" globby "^11.0.1"
is-glob "^4.0.1" is-glob "^4.0.1"
@ -1377,12 +1377,12 @@
"@typescript-eslint/types" "4.5.0" "@typescript-eslint/types" "4.5.0"
eslint-visitor-keys "^2.0.0" eslint-visitor-keys "^2.0.0"
"@typescript-eslint/visitor-keys@4.6.1": "@typescript-eslint/visitor-keys@4.7.0":
version "4.6.1" version "4.7.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.6.1.tgz#6b125883402d8939df7b54528d879e88f7ba3614" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.7.0.tgz#6783824f22acfc49e754970ed21b88ac03b80e6f"
integrity sha512-owABze4toX7QXwOLT3/D5a8NecZEjEWU1srqxENTfqsY3bwVnl3YYbOh6s1rp2wQKO9RTHFGjKes08FgE7SVMw== integrity sha512-aDJDWuCRsf1lXOtignlfiPODkzSxxop7D0rZ91L6ZuMlcMCSh0YyK+gAfo5zN/ih6WxMwhoXgJWC3cWQdaKC+A==
dependencies: dependencies:
"@typescript-eslint/types" "4.6.1" "@typescript-eslint/types" "4.7.0"
eslint-visitor-keys "^2.0.0" eslint-visitor-keys "^2.0.0"
"@webassemblyjs/ast@1.9.0": "@webassemblyjs/ast@1.9.0":
@ -1971,14 +1971,14 @@ babel-eslint@10.1.0, babel-eslint@^10.1.0:
eslint-visitor-keys "^1.0.0" eslint-visitor-keys "^1.0.0"
resolve "^1.12.0" resolve "^1.12.0"
babel-loader@^8.0.6: babel-loader@^8.2.1:
version "8.1.0" version "8.2.1"
resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.1.0.tgz#c611d5112bd5209abe8b9fa84c3e4da25275f1c3" resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.1.tgz#e53313254677e86f27536f5071d807e01d24ec00"
integrity sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw== integrity sha512-dMF8sb2KQ8kJl21GUjkW1HWmcsL39GOV5vnzjqrCzEPNY0S0UfMLnumidiwIajDSBmKhYf5iRW+HXaM4cvCKBw==
dependencies: dependencies:
find-cache-dir "^2.1.0" find-cache-dir "^2.1.0"
loader-utils "^1.4.0" loader-utils "^1.4.0"
mkdirp "^0.5.3" make-dir "^2.1.0"
pify "^4.0.1" pify "^4.0.1"
schema-utils "^2.6.5" schema-utils "^2.6.5"
@ -3589,10 +3589,10 @@ eslint-visitor-keys@^2.0.0:
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8"
integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==
eslint@^7.12.1: eslint@^7.13.0:
version "7.12.1" version "7.13.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.12.1.tgz#bd9a81fa67a6cfd51656cdb88812ce49ccec5801" resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.13.0.tgz#7f180126c0dcdef327bfb54b211d7802decc08da"
integrity sha512-HlMTEdr/LicJfN08LB3nM1rRYliDXOmfoO4vj39xN6BLpFzF00hbwBoqHk8UcJ2M/3nlARZWy/mslvGEuZFvsg== integrity sha512-uCORMuOO8tUzJmsdRtrvcGq5qposf7Rw0LwkTJkoDbOycVQtQjmnhZSuLQnozLE4TmAzlMVV45eCHmQ1OpDKUQ==
dependencies: dependencies:
"@babel/code-frame" "^7.0.0" "@babel/code-frame" "^7.0.0"
"@eslint/eslintrc" "^0.2.1" "@eslint/eslintrc" "^0.2.1"
@ -5457,10 +5457,10 @@ lcid@^1.0.0:
dependencies: dependencies:
invert-kv "^1.0.0" invert-kv "^1.0.0"
lemmy-js-client@^1.0.14: lemmy-js-client@^1.0.15:
version "1.0.14" version "1.0.15"
resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-1.0.14.tgz#81a847dd0c7d97c83913f198717498c223dc371e" resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-1.0.15.tgz#7f47c8fd93c50d77a770d8828ca9aac7a227606e"
integrity sha512-hiGxAnAD5RFmE8qHMBtYNNYD/UrfCZ5JzmVEH/i5Vg/v5i/ZVmebx20uWtRMmdSSy6s4GbW0w4niszLW6SaJ3Q== integrity sha512-2NkdwtdjuvyYsBiro5sdOirN3IuoQW1X7hH5az5fu59nKHLDpHm8BoktMmtf0u2cmOy+C5zg4ksK2UlG60Pe0g==
leven@^3.1.0: leven@^3.1.0:
version "3.1.0" version "3.1.0"
@ -5780,7 +5780,7 @@ make-dir@^1.0.0:
dependencies: dependencies:
pify "^3.0.0" pify "^3.0.0"
make-dir@^2.0.0: make-dir@^2.0.0, make-dir@^2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5"
integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==
@ -6019,10 +6019,10 @@ mimic-fn@^2.1.0:
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
mini-css-extract-plugin@^1.2.1: mini-css-extract-plugin@^1.3.1:
version "1.2.1" version "1.3.1"
resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-1.2.1.tgz#30ea7dee632b3002b0c77aeed447790408cb247e" resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-1.3.1.tgz#1375c88b2bc2a9d197670a55761edcd1b5d72f21"
integrity sha512-G3yw7/TQaPfkuiR73MDcyiqhyP8SnbmLhUbpC76H+wtQxA6wfKhMCQOCb6wnPK0dQbjORAeOILQqEesg4/wF7A== integrity sha512-jIOheqh9EU98rqj6ZaFTYNNDSFqdakNqaUZfkYwaXPjI9batmXVXX+K71NrqRAgtoGefELBMld1EQ7dqSAD5SQ==
dependencies: dependencies:
loader-utils "^2.0.0" loader-utils "^2.0.0"
schema-utils "^3.0.0" schema-utils "^3.0.0"
@ -6152,7 +6152,7 @@ mixin-deep@^1.2.0:
for-in "^1.0.2" for-in "^1.0.2"
is-extendable "^1.0.1" is-extendable "^1.0.1"
"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5, mkdirp@~0.5.0, mkdirp@~0.5.1: "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.5, mkdirp@~0.5.0, mkdirp@~0.5.1:
version "0.5.5" version "0.5.5"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
@ -8064,10 +8064,10 @@ sass-graph@2.2.5:
scss-tokenizer "^0.2.3" scss-tokenizer "^0.2.3"
yargs "^13.3.2" yargs "^13.3.2"
sass-loader@^10.0.5: sass-loader@^10.1.0:
version "10.0.5" version "10.1.0"
resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-10.0.5.tgz#f53505b5ddbedf43797470ceb34066ded82bb769" resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-10.1.0.tgz#1727fcc0c32ab3eb197cda61d78adf4e9174a4b3"
integrity sha512-2LqoNPtKkZq/XbXNQ4C64GFEleSEHKv6NPSI+bMC/l+jpEXGJhiRYkAQToO24MR7NU4JRY2RpLpJ/gjo2Uf13w== integrity sha512-ZCKAlczLBbFd3aGAhowpYEy69Te3Z68cg8bnHHl6WnSCvnKpbM6pQrz957HWMa8LKVuhnD9uMplmMAHwGQtHeg==
dependencies: dependencies:
klona "^2.0.4" klona "^2.0.4"
loader-utils "^2.0.0" loader-utils "^2.0.0"
@ -9644,10 +9644,10 @@ ws@^6.2.1:
dependencies: dependencies:
async-limiter "~1.0.0" async-limiter "~1.0.0"
ws@^7.3.1: ws@^7.4.0:
version "7.3.1" version "7.4.0"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.3.1.tgz#d0547bf67f7ce4f12a72dfe31262c68d7dc551c8" resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.0.tgz#a5dd76a24197940d4a8bb9e0e152bb4503764da7"
integrity sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA== integrity sha512-kyFwXuV/5ymf+IXhS6f0+eAFvydbaBW3zjpT6hUdAh/hbVjTIB5EHBGi0bPoCLSK2wcuz3BrEkB9LrYv1Nm4NQ==
xdg-basedir@^3.0.0: xdg-basedir@^3.0.0:
version "3.0.0" version "3.0.0"