You've already forked matrix-react-sdk
mirror of
https://github.com/matrix-org/matrix-react-sdk.git
synced 2025-08-06 10:22:45 +03:00
Update to React 18
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
19
package.json
19
package.json
@@ -63,8 +63,8 @@
|
||||
"lint:workflows": "find .github/workflows -type f \\( -iname '*.yaml' -o -iname '*.yml' \\) | xargs -I {} sh -c 'echo \"Linting {}\"; action-validator \"{}\"'"
|
||||
},
|
||||
"resolutions": {
|
||||
"@types/react-dom": "17.0.25",
|
||||
"@types/react": "17.0.80",
|
||||
"@types/react-dom": "18.3.0",
|
||||
"@types/react": "18.3.3",
|
||||
"@types/seedrandom": "3.0.8",
|
||||
"oidc-client-ts": "3.0.1",
|
||||
"jwt-decode": "4.0.0",
|
||||
@@ -81,7 +81,6 @@
|
||||
"@matrix-org/react-sdk-module-api": "^2.4.0",
|
||||
"@matrix-org/spec": "^1.7.0",
|
||||
"@sentry/browser": "^8.0.0",
|
||||
"@testing-library/react-hooks": "^8.0.1",
|
||||
"@vector-im/compound-design-tokens": "^1.6.1",
|
||||
"@vector-im/compound-web": "^5.5.0",
|
||||
"@zxcvbn-ts/core": "^3.0.4",
|
||||
@@ -129,10 +128,10 @@
|
||||
"posthog-js": "1.149.1",
|
||||
"qrcode": "1.5.3",
|
||||
"re-resizable": "^6.9.0",
|
||||
"react": "17.0.2",
|
||||
"react": "^18.3.1",
|
||||
"react-beautiful-dnd": "^13.1.0",
|
||||
"react-blurhash": "^0.3.0",
|
||||
"react-dom": "17.0.2",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-focus-lock": "^2.5.1",
|
||||
"react-transition-group": "^4.4.1",
|
||||
"rfc4648": "^1.4.0",
|
||||
@@ -167,7 +166,7 @@
|
||||
"@playwright/test": "^1.40.1",
|
||||
"@testing-library/dom": "^9.0.0",
|
||||
"@testing-library/jest-dom": "^6.0.0",
|
||||
"@testing-library/react": "^12.1.5",
|
||||
"@testing-library/react": "^14",
|
||||
"@testing-library/user-event": "^14.4.3",
|
||||
"@types/commonmark": "^0.27.4",
|
||||
"@types/content-type": "^1.1.5",
|
||||
@@ -187,9 +186,9 @@
|
||||
"@types/node-fetch": "^2.6.2",
|
||||
"@types/pako": "^2.0.0",
|
||||
"@types/qrcode": "^1.3.5",
|
||||
"@types/react": "17.0.80",
|
||||
"@types/react": "18.3.3",
|
||||
"@types/react-beautiful-dnd": "^13.0.0",
|
||||
"@types/react-dom": "17.0.25",
|
||||
"@types/react-dom": "18.3.0",
|
||||
"@types/react-transition-group": "^4.4.0",
|
||||
"@types/sanitize-html": "2.11.0",
|
||||
"@types/sdp-transform": "^2.4.6",
|
||||
@@ -246,6 +245,10 @@
|
||||
"postcss": "^8.4.19",
|
||||
"webpack": "^4.0.0 || ^5.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.19",
|
||||
"webpack": "^4.0.0 || ^5.0.0"
|
||||
},
|
||||
"@casualbot/jest-sonar-reporter": {
|
||||
"outputDirectory": "coverage",
|
||||
"outputName": "jest-sonar-report.xml",
|
||||
|
3
src/@types/react.d.ts
vendored
3
src/@types/react.d.ts
vendored
@@ -21,4 +21,7 @@ declare module "react" {
|
||||
function forwardRef<T, P = {}>(
|
||||
render: (props: PropsWithChildren<P>, ref: React.ForwardedRef<T>) => React.ReactElement | null,
|
||||
): (props: P & React.RefAttributes<T>) => React.ReactElement | null;
|
||||
|
||||
// Fix lazy types - https://stackoverflow.com/a/71017028
|
||||
function lazy<T extends ComponentType<any>>(factory: () => Promise<{ default: T }>): T;
|
||||
}
|
||||
|
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { Key, MutableRefObject, ReactElement, ReactFragment, ReactInstance, ReactPortal } from "react";
|
||||
import React, { Key, MutableRefObject, ReactElement, ReactInstance } from "react";
|
||||
import ReactDom from "react-dom";
|
||||
|
||||
interface IChildProps {
|
||||
@@ -35,7 +35,7 @@ interface IProps {
|
||||
innerRef?: MutableRefObject<any>;
|
||||
}
|
||||
|
||||
function isReactElement(c: ReactElement | ReactFragment | ReactPortal): c is ReactElement {
|
||||
function isReactElement(c: ReturnType<(typeof React.Children)["toArray"]>[number]): c is ReactElement {
|
||||
return typeof c === "object" && "type" in c;
|
||||
}
|
||||
|
||||
@@ -110,7 +110,8 @@ export default class NodeAnimator extends React.Component<IProps> {
|
||||
}
|
||||
|
||||
private collectNode(k: Key, node: React.ReactInstance, restingStyle: React.CSSProperties): void {
|
||||
if (node && this.nodes[k] === undefined && this.props.startStyles.length > 0) {
|
||||
const key = typeof k === "bigint" ? Number(k) : k;
|
||||
if (node && this.nodes[key] === undefined && this.props.startStyles.length > 0) {
|
||||
const startStyles = this.props.startStyles;
|
||||
const domNode = ReactDom.findDOMNode(node);
|
||||
// start from startStyle 1: 0 is the one we gave it
|
||||
@@ -124,7 +125,7 @@ export default class NodeAnimator extends React.Component<IProps> {
|
||||
this.applyStyles(domNode as HTMLElement, restingStyle);
|
||||
}, 0);
|
||||
}
|
||||
this.nodes[k] = node;
|
||||
this.nodes[key] = node;
|
||||
|
||||
if (this.props.innerRef) {
|
||||
this.props.innerRef.current = node;
|
||||
|
@@ -97,6 +97,12 @@ type WithKeyFunction<T> = T extends Key
|
||||
toKey: (key: T) => Key;
|
||||
};
|
||||
|
||||
export interface AdditionalOptionsProps {
|
||||
menuDisplayed: boolean;
|
||||
closeMenu: () => void;
|
||||
openMenu: () => void;
|
||||
}
|
||||
|
||||
type IProps<T> = WithKeyFunction<T> & {
|
||||
value: T;
|
||||
options: readonly GenericDropdownMenuOption<T>[] | readonly GenericDropdownMenuGroup<T>[];
|
||||
@@ -105,11 +111,7 @@ type IProps<T> = WithKeyFunction<T> & {
|
||||
onOpen?: (ev: ButtonEvent) => void;
|
||||
onClose?: (ev: ButtonEvent) => void;
|
||||
className?: string;
|
||||
AdditionalOptions?: FunctionComponent<{
|
||||
menuDisplayed: boolean;
|
||||
closeMenu: () => void;
|
||||
openMenu: () => void;
|
||||
}>;
|
||||
AdditionalOptions?: FunctionComponent<AdditionalOptionsProps>;
|
||||
};
|
||||
|
||||
export function GenericDropdownMenu<T>({
|
||||
|
@@ -117,7 +117,7 @@ export const ThreadPanelHeader: React.FC<{
|
||||
) : null;
|
||||
|
||||
const onMarkAllThreadsReadClick = React.useCallback(
|
||||
(e) => {
|
||||
(e: React.MouseEvent) => {
|
||||
PosthogTrackers.trackInteraction("WebThreadsMarkAllReadButton", e);
|
||||
if (!roomContext.room) {
|
||||
logger.error("No room in context to mark all threads read");
|
||||
|
@@ -19,7 +19,7 @@ limitations under the License.
|
||||
|
||||
import React, { forwardRef, useCallback, useContext, useEffect, useState } from "react";
|
||||
import classNames from "classnames";
|
||||
import { ClientEvent } from "matrix-js-sdk/src/matrix";
|
||||
import { ClientEvent, SyncState } from "matrix-js-sdk/src/matrix";
|
||||
import { Avatar } from "@vector-im/compound-web";
|
||||
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
@@ -80,7 +80,7 @@ const useImageUrl = ({ url, urls }: { url?: string | null; urls?: string[] }): [
|
||||
}, [url, JSON.stringify(urls)]); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
|
||||
const cli = useContext(MatrixClientContext);
|
||||
const onClientSync = useCallback((syncState, prevState) => {
|
||||
const onClientSync = useCallback((syncState: SyncState, prevState: SyncState | null) => {
|
||||
// Consider the client reconnected if there is no error with syncing.
|
||||
// This means the state could be RECONNECTING, SYNCING, PREPARED or CATCHUP.
|
||||
const reconnected = syncState !== "ERROR" && prevState !== syncState;
|
||||
|
@@ -26,6 +26,7 @@ interface OptionProps {
|
||||
id?: string;
|
||||
className?: string;
|
||||
onClick: ((ev: ButtonEvent) => void) | null;
|
||||
children?: ReactNode;
|
||||
}
|
||||
|
||||
export const Option: React.FC<OptionProps> = ({ inputRef, children, endAdornment, className, ...props }) => {
|
||||
|
@@ -26,7 +26,11 @@ import SdkConfig from "../../../SdkConfig";
|
||||
import { SettingLevel } from "../../../settings/SettingLevel";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import { Protocols } from "../../../utils/DirectoryUtils";
|
||||
import { GenericDropdownMenu, GenericDropdownMenuItem } from "../../structures/GenericDropdownMenu";
|
||||
import {
|
||||
AdditionalOptionsProps,
|
||||
GenericDropdownMenu,
|
||||
GenericDropdownMenuItem,
|
||||
} from "../../structures/GenericDropdownMenu";
|
||||
import TextInputDialog from "../dialogs/TextInputDialog";
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
import withValidation from "../elements/Validation";
|
||||
@@ -181,7 +185,7 @@ export const NetworkDropdown: React.FC<IProps> = ({ protocols, config, setConfig
|
||||
}));
|
||||
|
||||
const addNewServer = useCallback(
|
||||
({ closeMenu }) => (
|
||||
({ closeMenu }: AdditionalOptionsProps) => (
|
||||
<>
|
||||
<span className="mx_GenericDropdownMenu_divider" />
|
||||
<MenuItemRadio
|
||||
|
@@ -15,7 +15,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { ContextType, CSSProperties, MutableRefObject } from "react";
|
||||
import React, { ContextType, CSSProperties, MutableRefObject, ReactNode } from "react";
|
||||
import { Room } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import WidgetUtils from "../../../utils/WidgetUtils";
|
||||
@@ -28,6 +28,7 @@ interface IProps {
|
||||
persistentRoomId: string;
|
||||
pointerEvents?: CSSProperties["pointerEvents"];
|
||||
movePersistedElement: MutableRefObject<(() => void) | undefined>;
|
||||
children?: ReactNode;
|
||||
}
|
||||
|
||||
export default class PersistentApp extends React.Component<IProps> {
|
||||
|
@@ -17,7 +17,7 @@ limitations under the License.
|
||||
|
||||
import React, { useCallback, useContext } from "react";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { MatrixEvent, Room } from "matrix-js-sdk/src/matrix";
|
||||
import { MatrixEvent, Room, RoomState } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import dis from "../../../dispatcher/dispatcher";
|
||||
import { Action } from "../../../dispatcher/actions";
|
||||
@@ -52,7 +52,7 @@ export const RoomPredecessorTile: React.FC<IProps> = ({ mxEvent, timestamp }) =>
|
||||
const predecessor = useRoomState(
|
||||
roomContext.room,
|
||||
useCallback(
|
||||
(state) => state.findPredecessor(msc3946ProcessDynamicPredecessor),
|
||||
(state: RoomState) => state.findPredecessor(msc3946ProcessDynamicPredecessor),
|
||||
[msc3946ProcessDynamicPredecessor],
|
||||
),
|
||||
);
|
||||
@@ -63,9 +63,9 @@ export const RoomPredecessorTile: React.FC<IProps> = ({ mxEvent, timestamp }) =>
|
||||
|
||||
dis.dispatch<ViewRoomPayload>({
|
||||
action: Action.ViewRoom,
|
||||
event_id: predecessor.eventId,
|
||||
event_id: predecessor?.eventId,
|
||||
highlighted: true,
|
||||
room_id: predecessor.roomId,
|
||||
room_id: predecessor?.roomId,
|
||||
metricsTrigger: "Predecessor",
|
||||
metricsViaKeyboard: e.type !== "click",
|
||||
});
|
||||
@@ -126,7 +126,7 @@ export const RoomPredecessorTile: React.FC<IProps> = ({ mxEvent, timestamp }) =>
|
||||
|
||||
const predecessorPermalink = prevRoom
|
||||
? createLinkWithRoom(prevRoom, predecessor.roomId, predecessor.eventId)
|
||||
: createLinkWithoutRoom(predecessor.roomId, predecessor.viaServers, predecessor.eventId);
|
||||
: createLinkWithoutRoom(predecessor.roomId, predecessor?.viaServers ?? [], predecessor.eventId);
|
||||
|
||||
const link = (
|
||||
<a href={predecessorPermalink} onClick={onLinkClicked}>
|
||||
|
@@ -27,6 +27,7 @@ interface IProps {
|
||||
|
||||
export default class TextualEvent extends React.Component<IProps> {
|
||||
public static contextType = RoomContext;
|
||||
public declare context: React.ContextType<typeof RoomContext>;
|
||||
|
||||
public render(): React.ReactNode {
|
||||
const text = TextForEvent.textForEvent(
|
||||
|
@@ -14,10 +14,11 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import React, { ReactNode } from "react";
|
||||
|
||||
interface Props {
|
||||
label: string;
|
||||
children?: ReactNode;
|
||||
}
|
||||
|
||||
export const enum SeparatorKind {
|
||||
|
@@ -34,6 +34,7 @@ import { WidgetType } from "../../../widgets/WidgetType";
|
||||
import { WidgetMessagingStore } from "../../../stores/widgets/WidgetMessagingStore";
|
||||
import WidgetUtils from "../../../utils/WidgetUtils";
|
||||
import { ElementWidgetActions } from "../../../stores/widgets/ElementWidgetActions";
|
||||
import { ButtonEvent } from "../elements/AccessibleButton";
|
||||
|
||||
interface Props {
|
||||
widgetId: string;
|
||||
@@ -62,7 +63,7 @@ export const WidgetPip: FC<Props> = ({ widgetId, room, viewingRoom, onStartMovin
|
||||
const call = useCallForWidget(widgetId, room.roomId);
|
||||
|
||||
const onBackClick = useCallback(
|
||||
(ev) => {
|
||||
(ev: ButtonEvent) => {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
|
||||
@@ -87,7 +88,7 @@ export const WidgetPip: FC<Props> = ({ widgetId, room, viewingRoom, onStartMovin
|
||||
);
|
||||
|
||||
const onLeaveClick = useCallback(
|
||||
(ev) => {
|
||||
(ev: ButtonEvent) => {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
|
||||
|
@@ -424,6 +424,7 @@ export const UserOptionsSection: React.FC<{
|
||||
member: Member;
|
||||
canInvite: boolean;
|
||||
isSpace?: boolean;
|
||||
children?: ReactNode;
|
||||
}> = ({ member, canInvite, isSpace, children }) => {
|
||||
const cli = useContext(MatrixClientContext);
|
||||
|
||||
@@ -1036,7 +1037,7 @@ const IgnoreToggleButton: React.FC<{
|
||||
}, [cli, member.userId]);
|
||||
// Recheck also if we receive new accountData m.ignored_user_list
|
||||
const accountDataHandler = useCallback(
|
||||
(ev) => {
|
||||
(ev: MatrixEvent) => {
|
||||
if (ev.getType() === "m.ignored_user_list") {
|
||||
setIsIgnored(cli.isUserIgnored(member.userId));
|
||||
}
|
||||
|
@@ -116,7 +116,10 @@ export default function RoomHeader({
|
||||
|
||||
const askToJoinEnabled = useFeatureEnabled("feature_ask_to_join");
|
||||
|
||||
const videoClick = useCallback((ev) => videoCallClick(ev, callOptions[0]), [callOptions, videoCallClick]);
|
||||
const videoClick = useCallback(
|
||||
(ev: React.MouseEvent) => videoCallClick(ev, callOptions[0]),
|
||||
[callOptions, videoCallClick],
|
||||
);
|
||||
|
||||
const toggleCallButton = (
|
||||
<Tooltip label={isViewingCall ? _t("voip|minimise_call") : _t("voip|maximise_call")}>
|
||||
|
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { ChangeEvent, useCallback, useEffect, useMemo, useState } from "react";
|
||||
import React, { ChangeEvent, ReactNode, useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { EditInPlace, Alert, ErrorMessage } from "@vector-im/compound-web";
|
||||
import { Icon as PopOutIcon } from "@vector-im/compound-design-tokens/icons/pop-out.svg";
|
||||
@@ -37,7 +37,7 @@ import Modal from "../../../Modal";
|
||||
import defaultDispatcher from "../../../dispatcher/dispatcher";
|
||||
import { Flex } from "../../utils/Flex";
|
||||
|
||||
const SpinnerToast: React.FC = ({ children }) => (
|
||||
const SpinnerToast: React.FC<{ children?: ReactNode }> = ({ children }) => (
|
||||
<>
|
||||
<InlineSpinner />
|
||||
{children}
|
||||
|
@@ -45,7 +45,7 @@ const QuickSettingsButton: React.FC<{
|
||||
useSettingValue<Record<MetaSpace, boolean>>("Spaces.enabledMetaSpaces");
|
||||
|
||||
const currentRoomId = SdkContextClass.instance.roomViewStore.getRoomId();
|
||||
const developerModeEnabled = useSettingValue("developerMode");
|
||||
const developerModeEnabled = useSettingValue<boolean>("developerMode");
|
||||
|
||||
let contextMenu: JSX.Element | undefined;
|
||||
if (menuDisplayed && handle.current) {
|
||||
|
@@ -26,9 +26,9 @@ export const useAccountData = <T extends {}>(cli: MatrixClient, eventType: strin
|
||||
const [value, setValue] = useState<T | undefined>(() => tryGetContent<T>(cli.getAccountData(eventType)));
|
||||
|
||||
const handler = useCallback(
|
||||
(event) => {
|
||||
(event: MatrixEvent) => {
|
||||
if (event.getType() !== eventType) return;
|
||||
setValue(event.getContent());
|
||||
setValue(event.getContent<T>());
|
||||
},
|
||||
[eventType],
|
||||
);
|
||||
|
@@ -52,13 +52,6 @@ counterpart.setSeparator(KEY_SEPARATOR);
|
||||
const FALLBACK_LOCALE = "en";
|
||||
counterpart.setFallbackLocale(FALLBACK_LOCALE);
|
||||
|
||||
export interface ErrorOptions {
|
||||
// Because we're mixing the subsitution variables and `cause` into the same object
|
||||
// below, we want them to always explicitly say whether there is an underlying error
|
||||
// or not to avoid typos of "cause" slipping through unnoticed.
|
||||
cause: unknown | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to rethrow an error with a user-friendly translatable message while maintaining
|
||||
* access to that original underlying error. Downstream consumers can display the
|
||||
@@ -78,13 +71,8 @@ export interface ErrorOptions {
|
||||
export class UserFriendlyError extends Error {
|
||||
public readonly translatedMessage: string;
|
||||
|
||||
public constructor(message: TranslationKey, substitutionVariablesAndCause?: IVariables & ErrorOptions) {
|
||||
const errorOptions = {
|
||||
cause: substitutionVariablesAndCause?.cause,
|
||||
};
|
||||
// Prevent "Could not find /%\(cause\)s/g in x" logs to the console by removing it from the list
|
||||
const substitutionVariables = { ...substitutionVariablesAndCause };
|
||||
delete substitutionVariables["cause"];
|
||||
public constructor(message: TranslationKey, cause?: Error | unknown, substitutionVariables?: IVariables) {
|
||||
const errorOptions = { cause };
|
||||
|
||||
// Create the error with the English version of the message that we want to show
|
||||
// up in the logs
|
||||
@@ -445,7 +433,7 @@ export function replaceByRegexes(text: string, mapping: IVariables | Tags): stri
|
||||
}
|
||||
|
||||
if (shouldWrapInSpan) {
|
||||
return React.createElement("span", null, ...output);
|
||||
return React.createElement("span", null, ...(output as Array<number | string | React.ReactNode>));
|
||||
} else {
|
||||
return output.join("");
|
||||
}
|
||||
|
@@ -429,7 +429,7 @@ describe("InviteDialog", () => {
|
||||
|
||||
describe("when clicking »Start DM anyway«", () => {
|
||||
beforeEach(async () => {
|
||||
await userEvent.click(screen.getByRole("button", { name: "Start DM anyway", exact: true }));
|
||||
await userEvent.click(screen.getByRole("button", { name: "Start DM anyway" }));
|
||||
});
|
||||
|
||||
it("should start the DM", () => {
|
||||
|
@@ -14,8 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { renderHook } from "@testing-library/react-hooks";
|
||||
import { act } from "@testing-library/react";
|
||||
import { renderHook, act } from "@testing-library/react";
|
||||
|
||||
import { usePlainTextListeners } from "../../../../../../src/components/views/rooms/wysiwyg_composer/hooks/usePlainTextListeners";
|
||||
|
||||
|
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import { renderHook } from "@testing-library/react-hooks";
|
||||
import {
|
||||
MatrixClient,
|
||||
MatrixEventEvent,
|
||||
@@ -23,7 +22,7 @@ import {
|
||||
PendingEventOrdering,
|
||||
Room,
|
||||
} from "matrix-js-sdk/src/matrix";
|
||||
import { act } from "@testing-library/react";
|
||||
import { renderHook, act } from "@testing-library/react";
|
||||
|
||||
import MatrixClientContext from "../../../../src/contexts/MatrixClientContext";
|
||||
import { stubClient } from "../../../test-utils";
|
||||
|
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { renderHook } from "@testing-library/react-hooks/dom";
|
||||
import { renderHook } from "@testing-library/react";
|
||||
import { MatrixClient, NotificationCountType, Room } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { useRoomThreadNotifications } from "../../../src/hooks/room/useRoomThreadNotifications";
|
||||
|
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { renderHook } from "@testing-library/react-hooks";
|
||||
import { renderHook } from "@testing-library/react";
|
||||
|
||||
import { useDebouncedCallback } from "../../src/hooks/spotlight/useDebouncedCallback";
|
||||
|
||||
|
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { renderHook, RenderHookResult } from "@testing-library/react-hooks/dom";
|
||||
import { renderHook, RenderHookResult } from "@testing-library/react";
|
||||
|
||||
import { useLatestResult } from "../../src/hooks/useLatestResult";
|
||||
|
||||
@@ -28,7 +28,7 @@ beforeEach(() => {
|
||||
});
|
||||
|
||||
function simulateRequest(
|
||||
hookResult: RenderHookResult<typeof useLatestResult, ReturnType<typeof useLatestResult>>["result"],
|
||||
hookResult: RenderHookResult<ReturnType<typeof useLatestResult>, typeof useLatestResult>["result"],
|
||||
{ id, delayInMs, result }: { id: string; delayInMs: number; result: string },
|
||||
) {
|
||||
const [setQuery, setResult] = hookResult.current;
|
||||
|
@@ -14,8 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { act } from "@testing-library/react";
|
||||
import { renderHook } from "@testing-library/react-hooks/dom";
|
||||
import { act, renderHook, waitFor } from "@testing-library/react";
|
||||
import { IPushRules, MatrixClient, PushRuleKind, RuleId } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { useNotificationSettings } from "../../src/hooks/useNotificationSettings";
|
||||
@@ -69,10 +68,9 @@ describe("useNotificationSettings", () => {
|
||||
|
||||
it("correctly parses model", async () => {
|
||||
await act(async () => {
|
||||
const { result, waitForNextUpdate } = renderHook(() => useNotificationSettings(cli));
|
||||
const { result } = renderHook(() => useNotificationSettings(cli));
|
||||
expect(result.current.model).toEqual(null);
|
||||
await waitForNextUpdate();
|
||||
expect(result.current.model).toEqual(expectedModel);
|
||||
await waitFor(() => expect(result.current.model).toEqual(expectedModel));
|
||||
expect(result.current.hasPendingChanges).toBeFalsy();
|
||||
});
|
||||
});
|
||||
@@ -88,14 +86,12 @@ describe("useNotificationSettings", () => {
|
||||
const setPushRuleActions = jest.fn(cli.setPushRuleActions);
|
||||
cli.setPushRuleActions = setPushRuleActions;
|
||||
|
||||
const { result, waitForNextUpdate } = renderHook(() => useNotificationSettings(cli));
|
||||
const { result } = renderHook(() => useNotificationSettings(cli));
|
||||
expect(result.current.model).toEqual(null);
|
||||
await waitForNextUpdate();
|
||||
expect(result.current.model).toEqual(expectedModel);
|
||||
await waitFor(() => expect(result.current.model).toEqual(expectedModel));
|
||||
expect(result.current.hasPendingChanges).toBeFalsy();
|
||||
await result.current.reconcile(DefaultNotificationSettings);
|
||||
await waitForNextUpdate();
|
||||
expect(result.current.hasPendingChanges).toBeFalsy();
|
||||
await waitFor(() => expect(result.current.hasPendingChanges).toBeFalsy());
|
||||
expect(addPushRule).toHaveBeenCalledTimes(0);
|
||||
expect(deletePushRule).toHaveBeenCalledTimes(9);
|
||||
expect(deletePushRule).toHaveBeenCalledWith("global", PushRuleKind.ContentSpecific, "justjann3");
|
||||
|
@@ -14,8 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { waitFor } from "@testing-library/react";
|
||||
import { renderHook, act } from "@testing-library/react-hooks/dom";
|
||||
import { waitFor, renderHook, act } from "@testing-library/react";
|
||||
import { MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { useProfileInfo } from "../../src/hooks/useProfileInfo";
|
||||
|
@@ -14,8 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { waitFor } from "@testing-library/react";
|
||||
import { renderHook, act } from "@testing-library/react-hooks/dom";
|
||||
import { waitFor, renderHook, act } from "@testing-library/react";
|
||||
import { IRoomDirectoryOptions, MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { usePublicRoomDirectory } from "../../src/hooks/usePublicRoomDirectory";
|
||||
|
@@ -14,8 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { waitFor } from "@testing-library/react";
|
||||
import { renderHook, act } from "@testing-library/react-hooks/dom";
|
||||
import { waitFor, renderHook, act } from "@testing-library/react";
|
||||
import { MatrixClient, MatrixEvent, Room } from "matrix-js-sdk/src/matrix";
|
||||
import { KnownMembership } from "matrix-js-sdk/src/types";
|
||||
|
||||
|
@@ -14,8 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { waitFor } from "@testing-library/react";
|
||||
import { renderHook, act } from "@testing-library/react-hooks/dom";
|
||||
import { waitFor, renderHook, act } from "@testing-library/react";
|
||||
import { mocked } from "jest-mock";
|
||||
import { SlidingSync } from "matrix-js-sdk/src/sliding-sync";
|
||||
import { Room } from "matrix-js-sdk/src/matrix";
|
||||
|
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { renderHook } from "@testing-library/react-hooks";
|
||||
import { renderHook } from "@testing-library/react";
|
||||
import { EventStatus, NotificationCountType, PendingEventOrdering, Room } from "matrix-js-sdk/src/matrix";
|
||||
import { KnownMembership } from "matrix-js-sdk/src/types";
|
||||
|
||||
|
@@ -14,8 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { waitFor } from "@testing-library/react";
|
||||
import { renderHook, act } from "@testing-library/react-hooks/dom";
|
||||
import { waitFor, renderHook, act } from "@testing-library/react";
|
||||
import { MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { useUserDirectory } from "../../src/hooks/useUserDirectory";
|
||||
|
@@ -15,8 +15,7 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import { renderHook } from "@testing-library/react-hooks";
|
||||
import { waitFor } from "@testing-library/react";
|
||||
import { renderHook, waitFor } from "@testing-library/react";
|
||||
|
||||
import { useUserOnboardingTasks } from "../../src/hooks/useUserOnboardingTasks";
|
||||
import { useUserOnboardingContext } from "../../src/hooks/useUserOnboardingContext";
|
||||
|
@@ -14,8 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { renderHook } from "@testing-library/react-hooks";
|
||||
import { act } from "@testing-library/react";
|
||||
import { renderHook, act } from "@testing-library/react";
|
||||
|
||||
import UIStore, { UI_EVENTS } from "../../src/stores/UIStore";
|
||||
import { useWindowWidth } from "../../src/hooks/useWindowWidth";
|
||||
|
@@ -32,6 +32,8 @@ import {
|
||||
TranslatedString,
|
||||
UserFriendlyError,
|
||||
TranslationKey,
|
||||
IVariables,
|
||||
Tags,
|
||||
} from "../src/languageHandler";
|
||||
import { stubClient } from "./test-utils";
|
||||
import { setupLanguageMock } from "./setup/setupLanguage";
|
||||
@@ -214,13 +216,7 @@ describe("languageHandler JSX", function () {
|
||||
const plurals = "common|and_n_others";
|
||||
const variableSub = "slash_command|ignore_dialog_description";
|
||||
|
||||
type TestCase = [
|
||||
string,
|
||||
TranslationKey,
|
||||
Record<string, unknown>,
|
||||
Record<string, unknown> | undefined,
|
||||
TranslatedString,
|
||||
];
|
||||
type TestCase = [string, TranslationKey, IVariables, Tags | undefined, TranslatedString];
|
||||
const testCasesEn: TestCase[] = [
|
||||
// description of the test case, translationString, variables, tags, expected result
|
||||
["translates a basic string", basicString, {}, undefined, "Rooms"],
|
||||
|
@@ -118,6 +118,9 @@ describe("ProxiedApiModule", () => {
|
||||
describe("openDialog", () => {
|
||||
it("should open dialog with a custom title and default options", async () => {
|
||||
class MyDialogContent extends DialogContent {
|
||||
public constructor(props: DialogProps) {
|
||||
super(props);
|
||||
}
|
||||
trySubmit = async () => ({ result: true });
|
||||
render = () => <p>This is my example content.</p>;
|
||||
}
|
||||
@@ -147,6 +150,9 @@ describe("ProxiedApiModule", () => {
|
||||
|
||||
it("should open dialog with custom options", async () => {
|
||||
class MyDialogContent extends DialogContent {
|
||||
public constructor(props: DialogProps) {
|
||||
super(props);
|
||||
}
|
||||
trySubmit = async () => ({ result: true });
|
||||
render = () => <p>This is my example content.</p>;
|
||||
}
|
||||
@@ -178,6 +184,9 @@ describe("ProxiedApiModule", () => {
|
||||
|
||||
it("should update the options from the opened dialog", async () => {
|
||||
class MyDialogContent extends DialogContent {
|
||||
public constructor(props: DialogProps) {
|
||||
super(props);
|
||||
}
|
||||
trySubmit = async () => ({ result: true });
|
||||
render = () => {
|
||||
const onClick = () => {
|
||||
@@ -231,6 +240,9 @@ describe("ProxiedApiModule", () => {
|
||||
|
||||
it("should cancel the dialog from within the dialog", async () => {
|
||||
class MyDialogContent extends DialogContent {
|
||||
public constructor(props: DialogProps) {
|
||||
super(props);
|
||||
}
|
||||
trySubmit = async () => ({ result: true });
|
||||
render = () => (
|
||||
<button type="button" onClick={this.props.cancel}>
|
||||
|
104
yarn.lock
104
yarn.lock
@@ -1845,10 +1845,10 @@
|
||||
emojibase "^15.0.0"
|
||||
emojibase-data "^15.0.0"
|
||||
|
||||
"@matrix-org/matrix-sdk-crypto-wasm@^7.0.0":
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@matrix-org/matrix-sdk-crypto-wasm/-/matrix-sdk-crypto-wasm-7.0.0.tgz#8d6abdb9ded8656cc9e2a7909913a34bf3fc9b3a"
|
||||
integrity sha512-MOencXiW/gI5MuTtCNsuojjwT5DXCrjMqv9xOslJC9h2tPdLFFFMGr58dY5Lis4DRd9MRWcgrGowUIHOqieWTA==
|
||||
"@matrix-org/matrix-sdk-crypto-wasm@^6.0.0":
|
||||
version "6.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@matrix-org/matrix-sdk-crypto-wasm/-/matrix-sdk-crypto-wasm-6.2.1.tgz#94cd1263656e2b4f3b1dc6f728856efab8920aca"
|
||||
integrity sha512-5mav0EKog0w9NWRRxFzZ+ZcT5Il/KlLh1bsQXgxfhzfJq1RgWLLu+OsvHSZau5NSbPxfOd4ZTWc2ZLAf+V/8mg==
|
||||
|
||||
"@matrix-org/matrix-wysiwyg@2.37.4":
|
||||
version "2.37.4"
|
||||
@@ -2369,20 +2369,6 @@
|
||||
dependencies:
|
||||
"@sinonjs/commons" "^3.0.0"
|
||||
|
||||
"@testing-library/dom@^8.0.0":
|
||||
version "8.20.0"
|
||||
resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-8.20.0.tgz#914aa862cef0f5e89b98cc48e3445c4c921010f6"
|
||||
integrity sha512-d9ULIT+a4EXLX3UU8FBjauG9NnsZHkHztXoIcTsOKoOw030fyjheN9svkTULjJxtYag9DZz5Jz5qkWZDPxTFwA==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.10.4"
|
||||
"@babel/runtime" "^7.12.5"
|
||||
"@types/aria-query" "^5.0.1"
|
||||
aria-query "^5.0.0"
|
||||
chalk "^4.1.0"
|
||||
dom-accessibility-api "^0.5.9"
|
||||
lz-string "^1.4.4"
|
||||
pretty-format "^27.0.2"
|
||||
|
||||
"@testing-library/dom@^9.0.0":
|
||||
version "9.3.4"
|
||||
resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-9.3.4.tgz#50696ec28376926fec0a1bf87d9dbac5e27f60ce"
|
||||
@@ -2411,22 +2397,14 @@
|
||||
lodash "^4.17.21"
|
||||
redent "^3.0.0"
|
||||
|
||||
"@testing-library/react-hooks@^8.0.1":
|
||||
version "8.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@testing-library/react-hooks/-/react-hooks-8.0.1.tgz#0924bbd5b55e0c0c0502d1754657ada66947ca12"
|
||||
integrity sha512-Aqhl2IVmLt8IovEVarNDFuJDVWVvhnr9/GCU6UUnrYXwgDFF9h2L2o2P9KBni1AST5sT6riAyoukFLyjQUgD/g==
|
||||
"@testing-library/react@^14":
|
||||
version "14.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-14.3.1.tgz#29513fc3770d6fb75245c4e1245c470e4ffdd830"
|
||||
integrity sha512-H99XjUhWQw0lTgyMN05W3xQG1Nh4lq574D8keFf1dDoNTJgp66VbJozRaczoF+wsiaPJNt/TcnfpLGufGxSrZQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.12.5"
|
||||
react-error-boundary "^3.1.0"
|
||||
|
||||
"@testing-library/react@^12.1.5":
|
||||
version "12.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-12.1.5.tgz#bb248f72f02a5ac9d949dea07279095fa577963b"
|
||||
integrity sha512-OfTXCJUFgjd/digLUuPxa0+/3ZxsQmE7ub9kcbW/wi96Bh3o/p5vrETcBGfP17NWPGqeYYl5LTRpwyGoMC4ysg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.12.5"
|
||||
"@testing-library/dom" "^8.0.0"
|
||||
"@types/react-dom" "<18.0.0"
|
||||
"@testing-library/dom" "^9.0.0"
|
||||
"@types/react-dom" "^18.0.0"
|
||||
|
||||
"@testing-library/user-event@^14.4.3":
|
||||
version "14.5.2"
|
||||
@@ -2767,12 +2745,12 @@
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-dom@17.0.25", "@types/react-dom@<18.0.0":
|
||||
version "17.0.25"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.25.tgz#e0e5b3571e1069625b3a3da2b279379aa33a0cb5"
|
||||
integrity sha512-urx7A7UxkZQmThYA4So0NelOVjx3V4rNFVJwp0WZlbIK5eM4rNJDiN3R/E9ix0MBh6kAEojk/9YL+Te6D9zHNA==
|
||||
"@types/react-dom@18.3.0", "@types/react-dom@^18.0.0":
|
||||
version "18.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.3.0.tgz#0cbc818755d87066ab6ca74fbedb2547d74a82b0"
|
||||
integrity sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==
|
||||
dependencies:
|
||||
"@types/react" "^17"
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-redux@^7.1.20":
|
||||
version "7.1.25"
|
||||
@@ -2791,13 +2769,12 @@
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react@*", "@types/react@17.0.80", "@types/react@^17":
|
||||
version "17.0.80"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.80.tgz#a5dfc351d6a41257eb592d73d3a85d3b7dbcbb41"
|
||||
integrity sha512-LrgHIu2lEtIo8M7d1FcI3BdwXWoRQwMoXOZ7+dPTW0lYREjmlHl3P0U1VD0i/9tppOuv8/sam7sOjx34TxSFbA==
|
||||
"@types/react@*", "@types/react@18.3.3":
|
||||
version "18.3.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.3.tgz#9679020895318b0915d7a3ab004d92d33375c45f"
|
||||
integrity sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==
|
||||
dependencies:
|
||||
"@types/prop-types" "*"
|
||||
"@types/scheduler" "^0.16"
|
||||
csstype "^3.0.2"
|
||||
|
||||
"@types/retry@0.12.0":
|
||||
@@ -2812,11 +2789,6 @@
|
||||
dependencies:
|
||||
htmlparser2 "^8.0.0"
|
||||
|
||||
"@types/scheduler@^0.16":
|
||||
version "0.16.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.8.tgz#ce5ace04cfeabe7ef87c0091e50752e36707deff"
|
||||
integrity sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==
|
||||
|
||||
"@types/sdp-transform@^2.4.6":
|
||||
version "2.4.9"
|
||||
resolved "https://registry.yarnpkg.com/@types/sdp-transform/-/sdp-transform-2.4.9.tgz#26ef39f487a6909b0512f580b80920a366b27f52"
|
||||
@@ -6822,7 +6794,7 @@ lru-cache@^6.0.0:
|
||||
dependencies:
|
||||
yallist "^4.0.0"
|
||||
|
||||
lz-string@^1.4.4, lz-string@^1.5.0:
|
||||
lz-string@^1.5.0:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941"
|
||||
integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==
|
||||
@@ -7826,21 +7798,13 @@ react-clientside-effect@^1.2.6:
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.12.13"
|
||||
|
||||
react-dom@17.0.2:
|
||||
version "17.0.2"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23"
|
||||
integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==
|
||||
react-dom@^18.3.1:
|
||||
version "18.3.1"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4"
|
||||
integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
scheduler "^0.20.2"
|
||||
|
||||
react-error-boundary@^3.1.0:
|
||||
version "3.1.4"
|
||||
resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-3.1.4.tgz#255db92b23197108757a888b01e5b729919abde0"
|
||||
integrity sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.12.5"
|
||||
scheduler "^0.23.2"
|
||||
|
||||
react-focus-lock@^2.5.1:
|
||||
version "2.12.1"
|
||||
@@ -7919,13 +7883,12 @@ react-transition-group@^4.4.1:
|
||||
loose-envify "^1.4.0"
|
||||
prop-types "^15.6.2"
|
||||
|
||||
react@17.0.2:
|
||||
version "17.0.2"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"
|
||||
integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==
|
||||
react@^18.3.1:
|
||||
version "18.3.1"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891"
|
||||
integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
|
||||
read-pkg-up@^7.0.1:
|
||||
version "7.0.1"
|
||||
@@ -8259,13 +8222,12 @@ saxes@^6.0.0:
|
||||
dependencies:
|
||||
xmlchars "^2.2.0"
|
||||
|
||||
scheduler@^0.20.2:
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91"
|
||||
integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==
|
||||
scheduler@^0.23.2:
|
||||
version "0.23.2"
|
||||
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3"
|
||||
integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
|
||||
schema-utils@^3.0.0:
|
||||
version "3.1.1"
|
||||
|
Reference in New Issue
Block a user