mirror of
https://github.com/LemmyNet/lemmy-ui.git
synced 2024-12-22 19:01:26 +00:00
Merge pull request #1332 from alectrocute/breakout-role-utils
Organize `utils.ts` into folder, update imports
This commit is contained in:
commit
94bc9092ee
52 changed files with 376 additions and 303 deletions
|
@ -121,6 +121,7 @@
|
|||
"sortpack": "^2.3.4",
|
||||
"style-loader": "^3.3.2",
|
||||
"terser": "^5.17.3",
|
||||
"tsconfig-paths-webpack-plugin": "^4.0.1",
|
||||
"typescript": "^5.0.4",
|
||||
"webpack-dev-server": "4.15.0"
|
||||
},
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
import { hydrate } from "inferno-hydrate";
|
||||
import { Router } from "inferno-router";
|
||||
import { App } from "../shared/components/app/app";
|
||||
import { HistoryService } from "../shared/services/HistoryService";
|
||||
import { initializeSite } from "../shared/utils";
|
||||
|
||||
import "bootstrap/js/dist/collapse";
|
||||
import "bootstrap/js/dist/dropdown";
|
||||
import { HistoryService } from "../shared/services/HistoryService";
|
||||
|
||||
const site = window.isoData.site_res;
|
||||
initializeSite(site);
|
||||
initializeSite(window.isoData.site_res);
|
||||
|
||||
const wrapper = (
|
||||
<Router history={HistoryService.history}>
|
||||
|
@ -17,6 +16,7 @@ const wrapper = (
|
|||
);
|
||||
|
||||
const root = document.getElementById("root");
|
||||
|
||||
if (root) {
|
||||
hydrate(wrapper, root);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
import { isBrowser } from "@utils/browser";
|
||||
import { poll } from "@utils/helpers";
|
||||
import { amAdmin, canCreateCommunity } from "@utils/roles";
|
||||
import { Component, createRef, linkEvent } from "inferno";
|
||||
import { NavLink } from "inferno-router";
|
||||
import {
|
||||
|
@ -10,13 +13,9 @@ import { i18n } from "../../i18next";
|
|||
import { UserService } from "../../services";
|
||||
import { HttpService, RequestState } from "../../services/HttpService";
|
||||
import {
|
||||
amAdmin,
|
||||
canCreateCommunity,
|
||||
donateLemmyUrl,
|
||||
isBrowser,
|
||||
myAuth,
|
||||
numToSI,
|
||||
poll,
|
||||
showAvatars,
|
||||
toast,
|
||||
updateUnreadCountsInterval,
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
import {
|
||||
amCommunityCreator,
|
||||
canAdmin,
|
||||
canMod,
|
||||
isAdmin,
|
||||
isBanned,
|
||||
isMod,
|
||||
} from "@utils/roles";
|
||||
import classNames from "classnames";
|
||||
import { Component, InfernoNode, linkEvent } from "inferno";
|
||||
import { Link } from "inferno-router";
|
||||
|
@ -40,16 +48,10 @@ import {
|
|||
} from "../../interfaces";
|
||||
import { UserService } from "../../services";
|
||||
import {
|
||||
amCommunityCreator,
|
||||
canAdmin,
|
||||
canMod,
|
||||
colorList,
|
||||
commentTreeMaxDepth,
|
||||
futureDaysToUnixTime,
|
||||
getCommentParentId,
|
||||
isAdmin,
|
||||
isBanned,
|
||||
isMod,
|
||||
mdToHtml,
|
||||
mdToHtmlNoImages,
|
||||
myAuth,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { isBrowser } from "@utils/browser";
|
||||
import autosize from "autosize";
|
||||
import classNames from "classnames";
|
||||
import { NoOptionI18nKeys } from "i18next";
|
||||
|
@ -8,7 +9,6 @@ import { HttpService, UserService } from "../../services";
|
|||
import {
|
||||
concurrentImageUpload,
|
||||
customEmojisLookup,
|
||||
isBrowser,
|
||||
markdownFieldCharacterLimit,
|
||||
markdownHelpUrl,
|
||||
maxUploadImages,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { getQueryParams, getQueryString } from "@utils/helpers";
|
||||
import type { QueryParams } from "@utils/types";
|
||||
import { Component, linkEvent } from "inferno";
|
||||
import {
|
||||
CommunityResponse,
|
||||
|
@ -11,12 +13,9 @@ import { InitialFetchRequest } from "../../interfaces";
|
|||
import { FirstLoadService } from "../../services/FirstLoadService";
|
||||
import { HttpService, RequestState } from "../../services/HttpService";
|
||||
import {
|
||||
QueryParams,
|
||||
RouteDataResponse,
|
||||
editCommunity,
|
||||
getPageFromString,
|
||||
getQueryParams,
|
||||
getQueryString,
|
||||
myAuth,
|
||||
myAuthRequired,
|
||||
numToSI,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { getQueryParams, getQueryString } from "@utils/helpers";
|
||||
import type { QueryParams } from "@utils/types";
|
||||
import { Component, linkEvent } from "inferno";
|
||||
import { RouteComponentProps } from "inferno-router/dist/Route";
|
||||
import {
|
||||
|
@ -62,7 +64,6 @@ import { UserService } from "../../services";
|
|||
import { FirstLoadService } from "../../services/FirstLoadService";
|
||||
import { HttpService, RequestState } from "../../services/HttpService";
|
||||
import {
|
||||
QueryParams,
|
||||
RouteDataResponse,
|
||||
commentsToFlatNodes,
|
||||
communityRSSUrl,
|
||||
|
@ -75,8 +76,6 @@ import {
|
|||
getCommentParentId,
|
||||
getDataTypeString,
|
||||
getPageFromString,
|
||||
getQueryParams,
|
||||
getQueryString,
|
||||
myAuth,
|
||||
postToCommentSortType,
|
||||
relTags,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { amAdmin, amMod, amTopMod } from "@utils/roles";
|
||||
import { Component, InfernoNode, linkEvent } from "inferno";
|
||||
import { T } from "inferno-i18next-dess";
|
||||
import { Link } from "inferno-router";
|
||||
|
@ -16,15 +17,7 @@ import {
|
|||
} from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { UserService } from "../../services";
|
||||
import {
|
||||
amAdmin,
|
||||
amMod,
|
||||
amTopMod,
|
||||
getUnixTime,
|
||||
hostname,
|
||||
mdToHtml,
|
||||
myAuthRequired,
|
||||
} from "../../utils";
|
||||
import { getUnixTime, hostname, mdToHtml, myAuthRequired } from "../../utils";
|
||||
import { Badges } from "../common/badges";
|
||||
import { BannerIconHeader } from "../common/banner-icon-header";
|
||||
import { Icon, PurgeWarning, Spinner } from "../common/icon";
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import { getQueryParams, getQueryString } from "@utils/helpers";
|
||||
import { canCreateCommunity } from "@utils/roles";
|
||||
import type { QueryParams } from "@utils/types";
|
||||
import { NoOptionI18nKeys } from "i18next";
|
||||
import { Component, linkEvent, MouseEventHandler } from "inferno";
|
||||
import { Component, MouseEventHandler, linkEvent } from "inferno";
|
||||
import { T } from "inferno-i18next-dess";
|
||||
import { Link } from "inferno-router";
|
||||
import {
|
||||
|
@ -57,7 +60,7 @@ import { UserService } from "../../services";
|
|||
import { FirstLoadService } from "../../services/FirstLoadService";
|
||||
import { HttpService, RequestState } from "../../services/HttpService";
|
||||
import {
|
||||
canCreateCommunity,
|
||||
RouteDataResponse,
|
||||
commentsToFlatNodes,
|
||||
editComment,
|
||||
editPost,
|
||||
|
@ -68,16 +71,12 @@ import {
|
|||
getCommentParentId,
|
||||
getDataTypeString,
|
||||
getPageFromString,
|
||||
getQueryParams,
|
||||
getQueryString,
|
||||
getRandomFromList,
|
||||
mdToHtml,
|
||||
myAuth,
|
||||
postToCommentSortType,
|
||||
QueryParams,
|
||||
relTags,
|
||||
restoreScrollPosition,
|
||||
RouteDataResponse,
|
||||
saveScrollPosition,
|
||||
setIsoData,
|
||||
setupTippy,
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import { isBrowser } from "@utils/browser";
|
||||
import { Component, linkEvent } from "inferno";
|
||||
import { GetSiteResponse, LoginResponse } from "lemmy-js-client";
|
||||
import { i18n } from "../../i18next";
|
||||
import { UserService } from "../../services";
|
||||
import { HttpService, RequestState } from "../../services/HttpService";
|
||||
import { isBrowser, myAuth, setIsoData, toast, validEmail } from "../../utils";
|
||||
import { myAuth, setIsoData, toast, validEmail } from "../../utils";
|
||||
import { HtmlTags } from "../common/html-tags";
|
||||
import { Spinner } from "../common/icon";
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { isBrowser } from "@utils/browser";
|
||||
import { Options, passwordStrength } from "check-password-strength";
|
||||
import { NoOptionI18nKeys } from "i18next";
|
||||
import { Component, linkEvent } from "inferno";
|
||||
|
@ -13,7 +14,6 @@ import { i18n } from "../../i18next";
|
|||
import { UserService } from "../../services";
|
||||
import { HttpService, RequestState } from "../../services/HttpService";
|
||||
import {
|
||||
isBrowser,
|
||||
joinLemmyUrl,
|
||||
mdToHtml,
|
||||
myAuth,
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
import { debounce, getQueryParams, getQueryString } from "@utils/helpers";
|
||||
import { amAdmin, amMod } from "@utils/roles";
|
||||
import type { QueryParams } from "@utils/types";
|
||||
import { NoOptionI18nKeys } from "i18next";
|
||||
import { Component, linkEvent } from "inferno";
|
||||
import { T } from "inferno-i18next-dess";
|
||||
|
@ -34,17 +37,11 @@ import { FirstLoadService } from "../services/FirstLoadService";
|
|||
import { HttpService, RequestState } from "../services/HttpService";
|
||||
import {
|
||||
Choice,
|
||||
QueryParams,
|
||||
RouteDataResponse,
|
||||
amAdmin,
|
||||
amMod,
|
||||
debounce,
|
||||
fetchLimit,
|
||||
fetchUsers,
|
||||
getIdFromString,
|
||||
getPageFromString,
|
||||
getQueryParams,
|
||||
getQueryString,
|
||||
getUpdatedSearchId,
|
||||
myAuth,
|
||||
personToChoice,
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
import { getQueryParams, getQueryString } from "@utils/helpers";
|
||||
import { canMod, isAdmin, isBanned } from "@utils/roles";
|
||||
import type { QueryParams } from "@utils/types";
|
||||
import classNames from "classnames";
|
||||
import { NoOptionI18nKeys } from "i18next";
|
||||
import { Component, linkEvent } from "inferno";
|
||||
|
@ -53,9 +56,7 @@ import { UserService } from "../../services";
|
|||
import { FirstLoadService } from "../../services/FirstLoadService";
|
||||
import { HttpService, RequestState } from "../../services/HttpService";
|
||||
import {
|
||||
QueryParams,
|
||||
RouteDataResponse,
|
||||
canMod,
|
||||
capitalizeFirstLetter,
|
||||
editComment,
|
||||
editPost,
|
||||
|
@ -66,10 +67,6 @@ import {
|
|||
futureDaysToUnixTime,
|
||||
getCommentParentId,
|
||||
getPageFromString,
|
||||
getQueryParams,
|
||||
getQueryString,
|
||||
isAdmin,
|
||||
isBanned,
|
||||
mdToHtml,
|
||||
myAuth,
|
||||
myAuthRequired,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { amAdmin } from "@utils/roles";
|
||||
import { Component, linkEvent } from "inferno";
|
||||
import {
|
||||
CommentReportResponse,
|
||||
|
@ -24,7 +25,6 @@ import { FirstLoadService } from "../../services/FirstLoadService";
|
|||
import { RequestState } from "../../services/HttpService";
|
||||
import {
|
||||
RouteDataResponse,
|
||||
amAdmin,
|
||||
editCommentReport,
|
||||
editPostReport,
|
||||
editPrivateMessageReport,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { debounce } from "@utils/helpers";
|
||||
import { NoOptionI18nKeys } from "i18next";
|
||||
import { Component, linkEvent } from "inferno";
|
||||
import {
|
||||
|
@ -18,7 +19,6 @@ import {
|
|||
Choice,
|
||||
capitalizeFirstLetter,
|
||||
communityToChoice,
|
||||
debounce,
|
||||
elementUrl,
|
||||
emDash,
|
||||
fetchCommunities,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { getQueryParams } from "@utils/helpers";
|
||||
import type { QueryParams } from "@utils/types";
|
||||
import { Component } from "inferno";
|
||||
import { RouteComponentProps } from "inferno-router/dist/Route";
|
||||
import {
|
||||
|
@ -17,12 +19,10 @@ import {
|
|||
} from "../../services/HttpService";
|
||||
import {
|
||||
Choice,
|
||||
QueryParams,
|
||||
RouteDataResponse,
|
||||
enableDownvotes,
|
||||
enableNsfw,
|
||||
getIdFromString,
|
||||
getQueryParams,
|
||||
myAuth,
|
||||
setIsoData,
|
||||
} from "../../utils";
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { debounce } from "@utils/helpers";
|
||||
import autosize from "autosize";
|
||||
import { Component, InfernoNode, linkEvent } from "inferno";
|
||||
import {
|
||||
|
@ -18,7 +19,6 @@ import {
|
|||
archiveTodayUrl,
|
||||
capitalizeFirstLetter,
|
||||
communityToChoice,
|
||||
debounce,
|
||||
fetchCommunities,
|
||||
getIdFromString,
|
||||
ghostArchiveUrl,
|
||||
|
|
|
@ -1,3 +1,14 @@
|
|||
import { canShare, share } from "@utils/browser";
|
||||
import {
|
||||
amAdmin,
|
||||
amCommunityCreator,
|
||||
amMod,
|
||||
canAdmin,
|
||||
canMod,
|
||||
isAdmin,
|
||||
isBanned,
|
||||
isMod,
|
||||
} from "@utils/roles";
|
||||
import classNames from "classnames";
|
||||
import { Component, linkEvent } from "inferno";
|
||||
import { Link } from "inferno-router";
|
||||
|
@ -28,18 +39,9 @@ import { i18n } from "../../i18next";
|
|||
import { BanType, PostFormParams, PurgeType, VoteType } from "../../interfaces";
|
||||
import { UserService } from "../../services";
|
||||
import {
|
||||
amAdmin,
|
||||
amCommunityCreator,
|
||||
amMod,
|
||||
canAdmin,
|
||||
canMod,
|
||||
canShare,
|
||||
futureDaysToUnixTime,
|
||||
hostname,
|
||||
isAdmin,
|
||||
isBanned,
|
||||
isImage,
|
||||
isMod,
|
||||
isVideo,
|
||||
mdNoImages,
|
||||
mdToHtml,
|
||||
|
@ -49,7 +51,6 @@ import {
|
|||
numToSI,
|
||||
relTags,
|
||||
setupTippy,
|
||||
share,
|
||||
showScores,
|
||||
} from "../../utils";
|
||||
import { Icon, PurgeWarning, Spinner } from "../common/icon";
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { isBrowser } from "@utils/browser";
|
||||
import { debounce } from "@utils/helpers";
|
||||
import autosize from "autosize";
|
||||
import { Component, createRef, linkEvent, RefObject } from "inferno";
|
||||
import {
|
||||
|
@ -64,7 +66,6 @@ import {
|
|||
buildCommentsTree,
|
||||
commentsToFlatNodes,
|
||||
commentTreeMaxDepth,
|
||||
debounce,
|
||||
editComment,
|
||||
editWith,
|
||||
enableDownvotes,
|
||||
|
@ -73,7 +74,6 @@ import {
|
|||
getCommentParentId,
|
||||
getDepthFromComment,
|
||||
getIdFromProps,
|
||||
isBrowser,
|
||||
isImage,
|
||||
myAuth,
|
||||
restoreScrollPosition,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { debounce, getQueryParams, getQueryString } from "@utils/helpers";
|
||||
import type { QueryParams } from "@utils/types";
|
||||
import type { NoOptionI18nKeys } from "i18next";
|
||||
import { Component, linkEvent } from "inferno";
|
||||
import {
|
||||
|
@ -26,12 +28,10 @@ import { FirstLoadService } from "../services/FirstLoadService";
|
|||
import { HttpService, RequestState } from "../services/HttpService";
|
||||
import {
|
||||
Choice,
|
||||
QueryParams,
|
||||
RouteDataResponse,
|
||||
capitalizeFirstLetter,
|
||||
commentsToFlatNodes,
|
||||
communityToChoice,
|
||||
debounce,
|
||||
enableDownvotes,
|
||||
enableNsfw,
|
||||
fetchCommunities,
|
||||
|
@ -39,8 +39,6 @@ import {
|
|||
fetchUsers,
|
||||
getIdFromString,
|
||||
getPageFromString,
|
||||
getQueryParams,
|
||||
getQueryString,
|
||||
getUpdatedSearchId,
|
||||
myAuth,
|
||||
numToSI,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { isBrowser } from "./utils";
|
||||
import { isBrowser } from "@utils/browser";
|
||||
|
||||
const testHost = "0.0.0.0:8536";
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { isBrowser } from "@utils/browser";
|
||||
import i18next, { i18nTyped, Resource } from "i18next";
|
||||
import { UserService } from "./services";
|
||||
import { ar } from "./translations/ar";
|
||||
|
@ -31,7 +32,6 @@ import { sv } from "./translations/sv";
|
|||
import { vi } from "./translations/vi";
|
||||
import { zh } from "./translations/zh";
|
||||
import { zh_Hant } from "./translations/zh_Hant";
|
||||
import { isBrowser } from "./utils";
|
||||
|
||||
export const languages = [
|
||||
{ resource: ar, code: "ar", name: "العربية" },
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// import Cookies from 'js-cookie';
|
||||
import { isBrowser } from "@utils/browser";
|
||||
import IsomorphicCookie from "isomorphic-cookie";
|
||||
import jwt_decode from "jwt-decode";
|
||||
import { LoginResponse, MyUserInfo } from "lemmy-js-client";
|
||||
import { isHttps } from "../env";
|
||||
import { i18n } from "../i18next";
|
||||
import { isAuthPath, isBrowser, toast } from "../utils";
|
||||
import { isAuthPath, toast } from "../utils";
|
||||
|
||||
interface Claims {
|
||||
sub: number;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { isBrowser } from "@utils/browser";
|
||||
import { debounce, groupBy } from "@utils/helpers";
|
||||
import { Picker } from "emoji-mart";
|
||||
import emojiShortName from "emoji-short-name";
|
||||
import {
|
||||
|
@ -9,7 +11,6 @@ import {
|
|||
CommentReportView,
|
||||
CommentSortType,
|
||||
CommentView,
|
||||
CommunityModeratorView,
|
||||
CommunityView,
|
||||
CustomEmojiView,
|
||||
GetSiteMetadata,
|
||||
|
@ -17,7 +18,6 @@ import {
|
|||
Language,
|
||||
LemmyHttp,
|
||||
MyUserInfo,
|
||||
Person,
|
||||
PersonMentionView,
|
||||
PersonView,
|
||||
PostReportView,
|
||||
|
@ -235,92 +235,6 @@ export function futureDaysToUnixTime(days?: number): number | undefined {
|
|||
: undefined;
|
||||
}
|
||||
|
||||
export function canMod(
|
||||
creator_id: number,
|
||||
mods?: CommunityModeratorView[],
|
||||
admins?: PersonView[],
|
||||
myUserInfo = UserService.Instance.myUserInfo,
|
||||
onSelf = false
|
||||
): boolean {
|
||||
// You can do moderator actions only on the mods added after you.
|
||||
let adminsThenMods =
|
||||
admins
|
||||
?.map(a => a.person.id)
|
||||
.concat(mods?.map(m => m.moderator.id) ?? []) ?? [];
|
||||
|
||||
if (myUserInfo) {
|
||||
const myIndex = adminsThenMods.findIndex(
|
||||
id => id == myUserInfo.local_user_view.person.id
|
||||
);
|
||||
if (myIndex == -1) {
|
||||
return false;
|
||||
} else {
|
||||
// onSelf +1 on mod actions not for yourself, IE ban, remove, etc
|
||||
adminsThenMods = adminsThenMods.slice(0, myIndex + (onSelf ? 0 : 1));
|
||||
return !adminsThenMods.includes(creator_id);
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function canAdmin(
|
||||
creatorId: number,
|
||||
admins?: PersonView[],
|
||||
myUserInfo = UserService.Instance.myUserInfo,
|
||||
onSelf = false
|
||||
): boolean {
|
||||
return canMod(creatorId, undefined, admins, myUserInfo, onSelf);
|
||||
}
|
||||
|
||||
export function isMod(
|
||||
creatorId: number,
|
||||
mods?: CommunityModeratorView[]
|
||||
): boolean {
|
||||
return mods?.map(m => m.moderator.id).includes(creatorId) ?? false;
|
||||
}
|
||||
|
||||
export function amMod(
|
||||
mods?: CommunityModeratorView[],
|
||||
myUserInfo = UserService.Instance.myUserInfo
|
||||
): boolean {
|
||||
return myUserInfo ? isMod(myUserInfo.local_user_view.person.id, mods) : false;
|
||||
}
|
||||
|
||||
export function isAdmin(creatorId: number, admins?: PersonView[]): boolean {
|
||||
return admins?.map(a => a.person.id).includes(creatorId) ?? false;
|
||||
}
|
||||
|
||||
export function amAdmin(myUserInfo = UserService.Instance.myUserInfo): boolean {
|
||||
return myUserInfo?.local_user_view.person.admin ?? false;
|
||||
}
|
||||
|
||||
export function amCommunityCreator(
|
||||
creator_id: number,
|
||||
mods?: CommunityModeratorView[],
|
||||
myUserInfo = UserService.Instance.myUserInfo
|
||||
): boolean {
|
||||
const myId = myUserInfo?.local_user_view.person.id;
|
||||
// Don't allow mod actions on yourself
|
||||
return myId == mods?.at(0)?.moderator.id && myId != creator_id;
|
||||
}
|
||||
|
||||
export function amSiteCreator(
|
||||
creator_id: number,
|
||||
admins?: PersonView[],
|
||||
myUserInfo = UserService.Instance.myUserInfo
|
||||
): boolean {
|
||||
const myId = myUserInfo?.local_user_view.person.id;
|
||||
return myId == admins?.at(0)?.person.id && myId != creator_id;
|
||||
}
|
||||
|
||||
export function amTopMod(
|
||||
mods: CommunityModeratorView[],
|
||||
myUserInfo = UserService.Instance.myUserInfo
|
||||
): boolean {
|
||||
return mods.at(0)?.moderator.id == myUserInfo?.local_user_view.person.id;
|
||||
}
|
||||
|
||||
const imageRegex = /(http)?s?:?(\/\/[^"']*\.(?:jpg|jpeg|gif|png|svg|webp))/;
|
||||
const videoRegex = /(http)?s?:?(\/\/[^"']*\.(?:mp4|webm))/;
|
||||
const tldRegex = /([a-z0-9]+\.)*[a-z0-9]+\.[a-z]+/;
|
||||
|
@ -371,51 +285,6 @@ export function getDataTypeString(dt: DataType) {
|
|||
return dt === DataType.Post ? "Post" : "Comment";
|
||||
}
|
||||
|
||||
export function debounce<T extends any[], R>(
|
||||
func: (...e: T) => R,
|
||||
wait = 1000,
|
||||
immediate = false
|
||||
) {
|
||||
// 'private' variable for instance
|
||||
// The returned function will be able to reference this due to closure.
|
||||
// Each call to the returned function will share this common timer.
|
||||
let timeout: NodeJS.Timeout | null;
|
||||
|
||||
// Calling debounce returns a new anonymous function
|
||||
return function () {
|
||||
// reference the context and args for the setTimeout function
|
||||
const args = arguments;
|
||||
|
||||
// Should the function be called now? If immediate is true
|
||||
// and not already in a timeout then the answer is: Yes
|
||||
const callNow = immediate && !timeout;
|
||||
|
||||
// This is the basic debounce behavior where you can call this
|
||||
// function several times, but it will only execute once
|
||||
// [before or after imposing a delay].
|
||||
// Each time the returned function is called, the timer starts over.
|
||||
clearTimeout(timeout ?? undefined);
|
||||
|
||||
// Set the new timeout
|
||||
timeout = setTimeout(function () {
|
||||
// Inside the timeout function, clear the timeout variable
|
||||
// which will let the next execution run when in 'immediate' mode
|
||||
timeout = null;
|
||||
|
||||
// Check if the function already ran with the immediate flag
|
||||
if (!immediate) {
|
||||
// Call the original function with apply
|
||||
// apply lets you define the 'this' object as well as the arguments
|
||||
// (both captured before setTimeout)
|
||||
func.apply(this, args);
|
||||
}
|
||||
}, wait);
|
||||
|
||||
// Immediate mode and no wait timer? Execute the function..
|
||||
if (callNow) func.apply(this, args);
|
||||
} as (...e: T) => R;
|
||||
}
|
||||
|
||||
export async function fetchThemeList(): Promise<string[]> {
|
||||
return fetch("/css/themelist").then(res => res.json());
|
||||
}
|
||||
|
@ -1153,10 +1022,6 @@ export function siteBannerCss(banner: string): string {
|
|||
`;
|
||||
}
|
||||
|
||||
export function isBrowser() {
|
||||
return typeof window !== "undefined";
|
||||
}
|
||||
|
||||
export function setIsoData<T extends RouteData>(context: any): IsoData<T> {
|
||||
// If its the browser, you need to deserialize the data from the window
|
||||
if (isBrowser()) {
|
||||
|
@ -1286,21 +1151,6 @@ export function numToSI(value: number): string {
|
|||
return SHORTNUM_SI_FORMAT.format(value);
|
||||
}
|
||||
|
||||
export function isBanned(ps: Person): boolean {
|
||||
const expires = ps.ban_expires;
|
||||
// Add Z to convert from UTC date
|
||||
// TODO this check probably isn't necessary anymore
|
||||
if (expires) {
|
||||
if (ps.banned && new Date(expires + "Z") > new Date()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return ps.banned;
|
||||
}
|
||||
}
|
||||
|
||||
export function myAuth(): string | undefined {
|
||||
return UserService.Instance.auth();
|
||||
}
|
||||
|
@ -1332,15 +1182,6 @@ export function postToCommentSortType(sort: SortType): CommentSortType {
|
|||
}
|
||||
}
|
||||
|
||||
export function canCreateCommunity(
|
||||
siteRes: GetSiteResponse,
|
||||
myUserInfo = UserService.Instance.myUserInfo
|
||||
): boolean {
|
||||
const adminOnly = siteRes.site_view.local_site.community_creation_admin_only;
|
||||
// TODO: Make this check if user is logged on as well
|
||||
return !adminOnly || amAdmin(myUserInfo);
|
||||
}
|
||||
|
||||
export function isPostBlocked(
|
||||
pv: PostView,
|
||||
myUserInfo: MyUserInfo | undefined = UserService.Instance.myUserInfo
|
||||
|
@ -1421,64 +1262,12 @@ interface EmojiMartSkin {
|
|||
src: string;
|
||||
}
|
||||
|
||||
const groupBy = <T>(
|
||||
array: T[],
|
||||
predicate: (value: T, index: number, array: T[]) => string
|
||||
) =>
|
||||
array.reduce((acc, value, index, array) => {
|
||||
(acc[predicate(value, index, array)] ||= []).push(value);
|
||||
return acc;
|
||||
}, {} as { [key: string]: T[] });
|
||||
|
||||
export type QueryParams<T extends Record<string, any>> = {
|
||||
[key in keyof T]?: string;
|
||||
};
|
||||
|
||||
export function getQueryParams<T extends Record<string, any>>(processors: {
|
||||
[K in keyof T]: (param: string) => T[K];
|
||||
}): T {
|
||||
if (isBrowser()) {
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
|
||||
return Array.from(Object.entries(processors)).reduce(
|
||||
(acc, [key, process]) => ({
|
||||
...acc,
|
||||
[key]: process(searchParams.get(key)),
|
||||
}),
|
||||
{} as T
|
||||
);
|
||||
}
|
||||
|
||||
return {} as T;
|
||||
}
|
||||
|
||||
export function getQueryString<T extends Record<string, string | undefined>>(
|
||||
obj: T
|
||||
) {
|
||||
return Object.entries(obj)
|
||||
.filter(([, val]) => val !== undefined && val !== null)
|
||||
.reduce(
|
||||
(acc, [key, val], index) => `${acc}${index > 0 ? "&" : ""}${key}=${val}`,
|
||||
"?"
|
||||
);
|
||||
}
|
||||
|
||||
export function isAuthPath(pathname: string) {
|
||||
return /create_.*|inbox|settings|admin|reports|registration_applications/g.test(
|
||||
pathname
|
||||
);
|
||||
}
|
||||
|
||||
export function canShare() {
|
||||
return isBrowser() && !!navigator.canShare;
|
||||
}
|
||||
|
||||
export function share(shareData: ShareData) {
|
||||
if (isBrowser()) {
|
||||
navigator.share(shareData);
|
||||
}
|
||||
}
|
||||
|
||||
export function newVote(voteType: VoteType, myVote?: number): number {
|
||||
if (voteType == VoteType.Upvote) {
|
||||
return myVote == 1 ? 0 : 1;
|
||||
|
@ -1490,18 +1279,3 @@ export function newVote(voteType: VoteType, myVote?: number): number {
|
|||
export type RouteDataResponse<T extends Record<string, any>> = {
|
||||
[K in keyof T]: RequestState<T[K]>;
|
||||
};
|
||||
|
||||
function sleep(millis: number): Promise<void> {
|
||||
return new Promise(resolve => setTimeout(resolve, millis));
|
||||
}
|
||||
|
||||
/**
|
||||
* Polls / repeatedly runs a promise, every X milliseconds
|
||||
*/
|
||||
export async function poll(promiseFn: any, millis: number) {
|
||||
if (window.document.visibilityState !== "hidden") {
|
||||
await promiseFn();
|
||||
}
|
||||
await sleep(millis);
|
||||
return poll(promiseFn, millis);
|
||||
}
|
||||
|
|
5
src/shared/utils/browser/can-share.ts
Normal file
5
src/shared/utils/browser/can-share.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
import { isBrowser } from "@utils/browser";
|
||||
|
||||
export default function canShare() {
|
||||
return isBrowser() && !!navigator.canShare;
|
||||
}
|
5
src/shared/utils/browser/index.ts
Normal file
5
src/shared/utils/browser/index.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
import canShare from "./can-share";
|
||||
import isBrowser from "./is-browser";
|
||||
import share from "./share";
|
||||
|
||||
export { canShare, isBrowser, share };
|
3
src/shared/utils/browser/is-browser.ts
Normal file
3
src/shared/utils/browser/is-browser.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
export default function isBrowser() {
|
||||
return typeof window !== "undefined";
|
||||
}
|
7
src/shared/utils/browser/share.ts
Normal file
7
src/shared/utils/browser/share.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
import { isBrowser } from "@utils/browser";
|
||||
|
||||
export default function share(shareData: ShareData) {
|
||||
if (isBrowser()) {
|
||||
navigator.share(shareData);
|
||||
}
|
||||
}
|
24
src/shared/utils/helpers/debounce.ts
Normal file
24
src/shared/utils/helpers/debounce.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
export default function debounce<T extends any[], R>(
|
||||
func: (...e: T) => R,
|
||||
wait = 1000,
|
||||
immediate = false
|
||||
) {
|
||||
let timeout: NodeJS.Timeout | null;
|
||||
|
||||
return function () {
|
||||
const args = arguments;
|
||||
const callNow = immediate && !timeout;
|
||||
|
||||
clearTimeout(timeout ?? undefined);
|
||||
|
||||
timeout = setTimeout(function () {
|
||||
timeout = null;
|
||||
|
||||
if (!immediate) {
|
||||
func.apply(this, args);
|
||||
}
|
||||
}, wait);
|
||||
|
||||
if (callNow) func.apply(this, args);
|
||||
} as (...e: T) => R;
|
||||
}
|
21
src/shared/utils/helpers/get-query-params.ts
Normal file
21
src/shared/utils/helpers/get-query-params.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
import { isBrowser } from "@utils/browser";
|
||||
|
||||
export default function getQueryParams<
|
||||
T extends Record<string, any>
|
||||
>(processors: {
|
||||
[K in keyof T]: (param: string) => T[K];
|
||||
}): T {
|
||||
if (isBrowser()) {
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
|
||||
return Array.from(Object.entries(processors)).reduce(
|
||||
(acc, [key, process]) => ({
|
||||
...acc,
|
||||
[key]: process(searchParams.get(key)),
|
||||
}),
|
||||
{} as T
|
||||
);
|
||||
}
|
||||
|
||||
return {} as T;
|
||||
}
|
10
src/shared/utils/helpers/get-query-string.ts
Normal file
10
src/shared/utils/helpers/get-query-string.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
export default function getQueryString<
|
||||
T extends Record<string, string | undefined>
|
||||
>(obj: T) {
|
||||
return Object.entries(obj)
|
||||
.filter(([, val]) => val !== undefined && val !== null)
|
||||
.reduce(
|
||||
(acc, [key, val], index) => `${acc}${index > 0 ? "&" : ""}${key}=${val}`,
|
||||
"?"
|
||||
);
|
||||
}
|
8
src/shared/utils/helpers/group-by.ts
Normal file
8
src/shared/utils/helpers/group-by.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
export const groupBy = <T>(
|
||||
array: T[],
|
||||
predicate: (value: T, index: number, array: T[]) => string
|
||||
) =>
|
||||
array.reduce((acc, value, index, array) => {
|
||||
(acc[predicate(value, index, array)] ||= []).push(value);
|
||||
return acc;
|
||||
}, {} as { [key: string]: T[] });
|
8
src/shared/utils/helpers/index.ts
Normal file
8
src/shared/utils/helpers/index.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
import debounce from "./debounce";
|
||||
import getQueryParams from "./get-query-params";
|
||||
import getQueryString from "./get-query-string";
|
||||
import { groupBy } from "./group-by";
|
||||
import poll from "./poll";
|
||||
import sleep from "./sleep";
|
||||
|
||||
export { debounce, getQueryParams, getQueryString, groupBy, poll, sleep };
|
12
src/shared/utils/helpers/poll.ts
Normal file
12
src/shared/utils/helpers/poll.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import sleep from "./sleep";
|
||||
|
||||
/**
|
||||
* Polls / repeatedly runs a promise, every X milliseconds
|
||||
*/
|
||||
export default async function poll(promiseFn: any, millis: number) {
|
||||
if (window.document.visibilityState !== "hidden") {
|
||||
await promiseFn();
|
||||
}
|
||||
await sleep(millis);
|
||||
return poll(promiseFn, millis);
|
||||
}
|
3
src/shared/utils/helpers/sleep.ts
Normal file
3
src/shared/utils/helpers/sleep.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
export default function sleep(millis: number): Promise<void> {
|
||||
return new Promise(resolve => setTimeout(resolve, millis));
|
||||
}
|
7
src/shared/utils/roles/am-admin.ts
Normal file
7
src/shared/utils/roles/am-admin.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
import { UserService } from "../../services";
|
||||
|
||||
export default function amAdmin(
|
||||
myUserInfo = UserService.Instance.myUserInfo
|
||||
): boolean {
|
||||
return myUserInfo?.local_user_view.person.admin ?? false;
|
||||
}
|
12
src/shared/utils/roles/am-community-creator.ts
Normal file
12
src/shared/utils/roles/am-community-creator.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { CommunityModeratorView } from "lemmy-js-client";
|
||||
import { UserService } from "../../services";
|
||||
|
||||
export default function amCommunityCreator(
|
||||
creator_id: number,
|
||||
mods?: CommunityModeratorView[],
|
||||
myUserInfo = UserService.Instance.myUserInfo
|
||||
): boolean {
|
||||
const myId = myUserInfo?.local_user_view.person.id;
|
||||
// Don't allow mod actions on yourself
|
||||
return myId == mods?.at(0)?.moderator.id && myId != creator_id;
|
||||
}
|
10
src/shared/utils/roles/am-mod.ts
Normal file
10
src/shared/utils/roles/am-mod.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
import { isMod } from "@utils/roles";
|
||||
import { CommunityModeratorView } from "lemmy-js-client";
|
||||
import { UserService } from "../../services";
|
||||
|
||||
export default function amMod(
|
||||
mods?: CommunityModeratorView[],
|
||||
myUserInfo = UserService.Instance.myUserInfo
|
||||
): boolean {
|
||||
return myUserInfo ? isMod(myUserInfo.local_user_view.person.id, mods) : false;
|
||||
}
|
11
src/shared/utils/roles/am-site-creator.ts
Normal file
11
src/shared/utils/roles/am-site-creator.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
import { PersonView } from "lemmy-js-client";
|
||||
import { UserService } from "../../services";
|
||||
|
||||
export default function amSiteCreator(
|
||||
creator_id: number,
|
||||
admins?: PersonView[],
|
||||
myUserInfo = UserService.Instance.myUserInfo
|
||||
): boolean {
|
||||
const myId = myUserInfo?.local_user_view.person.id;
|
||||
return myId == admins?.at(0)?.person.id && myId != creator_id;
|
||||
}
|
9
src/shared/utils/roles/am-top-mod.ts
Normal file
9
src/shared/utils/roles/am-top-mod.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
import { CommunityModeratorView } from "lemmy-js-client";
|
||||
import { UserService } from "../../services";
|
||||
|
||||
export default function amTopMod(
|
||||
mods: CommunityModeratorView[],
|
||||
myUserInfo = UserService.Instance.myUserInfo
|
||||
): boolean {
|
||||
return mods.at(0)?.moderator.id == myUserInfo?.local_user_view.person.id;
|
||||
}
|
12
src/shared/utils/roles/can-admin.ts
Normal file
12
src/shared/utils/roles/can-admin.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { canMod } from "@utils/roles";
|
||||
import { PersonView } from "lemmy-js-client";
|
||||
import { UserService } from "../../services";
|
||||
|
||||
export default function canAdmin(
|
||||
creatorId: number,
|
||||
admins?: PersonView[],
|
||||
myUserInfo = UserService.Instance.myUserInfo,
|
||||
onSelf = false
|
||||
): boolean {
|
||||
return canMod(creatorId, undefined, admins, myUserInfo, onSelf);
|
||||
}
|
12
src/shared/utils/roles/can-create-community.ts
Normal file
12
src/shared/utils/roles/can-create-community.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { amAdmin } from "@utils/roles";
|
||||
import { GetSiteResponse } from "lemmy-js-client";
|
||||
import { UserService } from "../../services";
|
||||
|
||||
export default function canCreateCommunity(
|
||||
siteRes: GetSiteResponse,
|
||||
myUserInfo = UserService.Instance.myUserInfo
|
||||
): boolean {
|
||||
const adminOnly = siteRes.site_view.local_site.community_creation_admin_only;
|
||||
// TODO: Make this check if user is logged on as well
|
||||
return !adminOnly || amAdmin(myUserInfo);
|
||||
}
|
31
src/shared/utils/roles/can-mod.ts
Normal file
31
src/shared/utils/roles/can-mod.ts
Normal file
|
@ -0,0 +1,31 @@
|
|||
import { CommunityModeratorView, PersonView } from "lemmy-js-client";
|
||||
import { UserService } from "../../services";
|
||||
|
||||
export default function canMod(
|
||||
creator_id: number,
|
||||
mods?: CommunityModeratorView[],
|
||||
admins?: PersonView[],
|
||||
myUserInfo = UserService.Instance.myUserInfo,
|
||||
onSelf = false
|
||||
): boolean {
|
||||
// You can do moderator actions only on the mods added after you.
|
||||
let adminsThenMods =
|
||||
admins
|
||||
?.map(a => a.person.id)
|
||||
.concat(mods?.map(m => m.moderator.id) ?? []) ?? [];
|
||||
|
||||
if (myUserInfo) {
|
||||
const myIndex = adminsThenMods.findIndex(
|
||||
id => id == myUserInfo.local_user_view.person.id
|
||||
);
|
||||
if (myIndex == -1) {
|
||||
return false;
|
||||
} else {
|
||||
// onSelf +1 on mod actions not for yourself, IE ban, remove, etc
|
||||
adminsThenMods = adminsThenMods.slice(0, myIndex + (onSelf ? 0 : 1));
|
||||
return !adminsThenMods.includes(creator_id);
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
25
src/shared/utils/roles/index.ts
Normal file
25
src/shared/utils/roles/index.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
import amAdmin from "./am-admin";
|
||||
import amCommunityCreator from "./am-community-creator";
|
||||
import amMod from "./am-mod";
|
||||
import amSiteCreator from "./am-site-creator";
|
||||
import amTopMod from "./am-top-mod";
|
||||
import canAdmin from "./can-admin";
|
||||
import canCreateCommunity from "./can-create-community";
|
||||
import canMod from "./can-mod";
|
||||
import isAdmin from "./is-admin";
|
||||
import isBanned from "./is-banned";
|
||||
import isMod from "./is-mod";
|
||||
|
||||
export {
|
||||
amAdmin,
|
||||
amCommunityCreator,
|
||||
amMod,
|
||||
amSiteCreator,
|
||||
amTopMod,
|
||||
canAdmin,
|
||||
canCreateCommunity,
|
||||
canMod,
|
||||
isAdmin,
|
||||
isBanned,
|
||||
isMod,
|
||||
};
|
8
src/shared/utils/roles/is-admin.ts
Normal file
8
src/shared/utils/roles/is-admin.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
import { PersonView } from "lemmy-js-client";
|
||||
|
||||
export default function isAdmin(
|
||||
creatorId: number,
|
||||
admins?: PersonView[]
|
||||
): boolean {
|
||||
return admins?.map(a => a.person.id).includes(creatorId) ?? false;
|
||||
}
|
16
src/shared/utils/roles/is-banned.ts
Normal file
16
src/shared/utils/roles/is-banned.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { Person } from "lemmy-js-client";
|
||||
|
||||
export default function isBanned(ps: Person): boolean {
|
||||
const expires = ps.ban_expires;
|
||||
// Add Z to convert from UTC date
|
||||
// TODO this check probably isn't necessary anymore
|
||||
if (expires) {
|
||||
if (ps.banned && new Date(expires + "Z") > new Date()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return ps.banned;
|
||||
}
|
||||
}
|
8
src/shared/utils/roles/is-mod.ts
Normal file
8
src/shared/utils/roles/is-mod.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
import { CommunityModeratorView } from "lemmy-js-client";
|
||||
|
||||
export default function isMod(
|
||||
creatorId: number,
|
||||
mods?: CommunityModeratorView[]
|
||||
): boolean {
|
||||
return mods?.map(m => m.moderator.id).includes(creatorId) ?? false;
|
||||
}
|
3
src/shared/utils/types/index.ts
Normal file
3
src/shared/utils/types/index.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
import { QueryParams } from "./query-params";
|
||||
|
||||
export { QueryParams };
|
3
src/shared/utils/types/query-params.ts
Normal file
3
src/shared/utils/types/query-params.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
export type QueryParams<T extends Record<string, any>> = {
|
||||
[key in keyof T]?: string;
|
||||
};
|
|
@ -18,7 +18,13 @@
|
|||
"noImplicitReturns": true,
|
||||
"experimentalDecorators": true,
|
||||
"strictNullChecks": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"paths": {
|
||||
"@utils/roles": ["./shared/utils/roles/index"],
|
||||
"@utils/browser": ["./shared/utils/browser/index"],
|
||||
"@utils/helpers": ["./shared/utils/helpers/index"],
|
||||
"@utils/types": ["./shared/utils/types/index"],
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
|
|
|
@ -5,6 +5,7 @@ const CopyPlugin = require("copy-webpack-plugin");
|
|||
const RunNodeWebpackPlugin = require("run-node-webpack-plugin");
|
||||
const merge = require("lodash/merge");
|
||||
const { ServiceWorkerPlugin } = require("service-worker-webpack");
|
||||
const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin");
|
||||
const banner = `
|
||||
hash:[contentHash], chunkhash:[chunkhash], name:[name], filebase:[base], query:[query], file:[file]
|
||||
Source code: https://github.com/LemmyNet/lemmy-ui
|
||||
|
@ -19,6 +20,7 @@ const base = {
|
|||
hashFunction: "xxhash64",
|
||||
},
|
||||
resolve: {
|
||||
plugins: [new TsconfigPathsPlugin()],
|
||||
extensions: [".js", ".jsx", ".ts", ".tsx"],
|
||||
},
|
||||
performance: {
|
||||
|
|
33
yarn.lock
33
yarn.lock
|
@ -2714,7 +2714,7 @@ chalk@^2.0.0, chalk@^2.0.1:
|
|||
escape-string-regexp "^1.0.5"
|
||||
supports-color "^5.3.0"
|
||||
|
||||
chalk@^4.0.0, chalk@^4.0.2:
|
||||
chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
|
||||
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
|
||||
|
@ -3578,6 +3578,14 @@ enhanced-resolve@^5.14.0:
|
|||
graceful-fs "^4.2.4"
|
||||
tapable "^2.2.0"
|
||||
|
||||
enhanced-resolve@^5.7.0:
|
||||
version "5.15.0"
|
||||
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35"
|
||||
integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==
|
||||
dependencies:
|
||||
graceful-fs "^4.2.4"
|
||||
tapable "^2.2.0"
|
||||
|
||||
entities@^4.2.0, entities@^4.4.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
|
||||
|
@ -8686,6 +8694,11 @@ strip-ansi@^7.0.1:
|
|||
dependencies:
|
||||
ansi-regex "^6.0.1"
|
||||
|
||||
strip-bom@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
|
||||
integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==
|
||||
|
||||
strip-comments@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-comments/-/strip-comments-2.0.1.tgz#4ad11c3fbcac177a67a40ac224ca339ca1c1ba9b"
|
||||
|
@ -8938,6 +8951,24 @@ tributejs@^5.1.3:
|
|||
resolved "https://registry.yarnpkg.com/tributejs/-/tributejs-5.1.3.tgz#980600fc72865be5868893078b4bfde721129eae"
|
||||
integrity sha512-B5CXihaVzXw+1UHhNFyAwUTMDk1EfoLP5Tj1VhD9yybZ1I8DZJEv8tZ1l0RJo0t0tk9ZhR8eG5tEsaCvRigmdQ==
|
||||
|
||||
tsconfig-paths-webpack-plugin@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.0.1.tgz#a24651d0f69668a1abad38d3c2489855c257460d"
|
||||
integrity sha512-m5//KzLoKmqu2MVix+dgLKq70MnFi8YL8sdzQZ6DblmCdfuq/y3OqvJd5vMndg2KEVCOeNz8Es4WVZhYInteLw==
|
||||
dependencies:
|
||||
chalk "^4.1.0"
|
||||
enhanced-resolve "^5.7.0"
|
||||
tsconfig-paths "^4.1.2"
|
||||
|
||||
tsconfig-paths@^4.1.2:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz#ef78e19039133446d244beac0fd6a1632e2d107c"
|
||||
integrity sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==
|
||||
dependencies:
|
||||
json5 "^2.2.2"
|
||||
minimist "^1.2.6"
|
||||
strip-bom "^3.0.0"
|
||||
|
||||
tslib@^1.8.1:
|
||||
version "1.14.1"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
||||
|
|
Loading…
Reference in a new issue