mirror of
https://github.com/pezkuwichain/pezkuwi-extension.git
synced 2026-10-20 18:56:20 +00:00
Move to @pezkuwi/dev 0.86 (eslint 10 toolchain)
- @pezkuwi/dev, dev-test, dev-ts ^0.86.3 in the root and in every workspace package (they still asked for 0.84.3) - tsconfig.base target ES2022, the @pezkuwi/dev default; it carries the ErrorOptions type for `cause` - rethrown errors carry the original as `cause`; rejections are normalised to Error - page/messaging: the typed subscriber is called directly, not as `Function` - chrome mock: constant results through Promise.resolve - useLedger: drop a construction every branch below repeated - InputWithLabel: onKeyDown instead of the deprecated onKeyPress - Account: toggleActions + 1 instead of a pre-increment of a parameter - optional chains where a guard tested the same value - specs: mount<React.Component> so the wrappers are not `any`-typed - AccountsStore.set keeps its async override of KeyringStore.set: BaseStore.set handles its own failure, so it never rejects - extension-chains keeps its ChainProperties assertion: the package's own build does not load the type augmentation - the existing React Compiler findings (37, react-hooks rules only) are recorded in eslint-suppressions.json; a new one fails lint
This commit is contained in:
1 parent
0321454dc7
commit
9d769676e4
58 files changed
+2795
-3355
No files matched your search
@@ -0,0 +1,106 @@
|
||||
{
|
||||
"packages/extension-ui/src/Popup/Accounts/Account.tsx": {
|
||||
"react-hooks/set-state-in-effect": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"packages/extension-ui/src/Popup/Accounts/index.tsx": {
|
||||
"react-hooks/set-state-in-effect": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"packages/extension-ui/src/Popup/CreateAccount/index.tsx": {
|
||||
"react-hooks/set-state-in-effect": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"packages/extension-ui/src/Popup/Derive/DerivationPath.tsx": {
|
||||
"react-hooks/set-state-in-effect": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"packages/extension-ui/src/Popup/Derive/SelectParent.tsx": {
|
||||
"react-hooks/set-state-in-effect": {
|
||||
"count": 3
|
||||
}
|
||||
},
|
||||
"packages/extension-ui/src/Popup/ImportLedger.tsx": {
|
||||
"react-hooks/refs": {
|
||||
"count": 3
|
||||
}
|
||||
},
|
||||
"packages/extension-ui/src/Popup/ImportSeed/index.tsx": {
|
||||
"react-hooks/set-state-in-effect": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"packages/extension-ui/src/Popup/Signing/Extrinsic.tsx": {
|
||||
"react-hooks/refs": {
|
||||
"count": 3
|
||||
}
|
||||
},
|
||||
"packages/extension-ui/src/Popup/Signing/Request/SignArea.tsx": {
|
||||
"react-hooks/set-state-in-effect": {
|
||||
"count": 1
|
||||
},
|
||||
"react-hooks/static-components": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"packages/extension-ui/src/Popup/Signing/Request/index.tsx": {
|
||||
"react-hooks/set-state-in-effect": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"packages/extension-ui/src/Popup/Signing/index.tsx": {
|
||||
"react-hooks/set-state-in-effect": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"packages/extension-ui/src/Popup/index.tsx": {
|
||||
"react-hooks/set-state-in-effect": {
|
||||
"count": 2
|
||||
}
|
||||
},
|
||||
"packages/extension-ui/src/components/Address.tsx": {
|
||||
"react-hooks/set-state-in-effect": {
|
||||
"count": 3
|
||||
},
|
||||
"react-hooks/static-components": {
|
||||
"count": 2
|
||||
}
|
||||
},
|
||||
"packages/extension-ui/src/components/ErrorBoundary.tsx": {
|
||||
"react-hooks/set-state-in-effect": {
|
||||
"count": 2
|
||||
}
|
||||
},
|
||||
"packages/extension-ui/src/components/ValidatedInput.tsx": {
|
||||
"react-hooks/set-state-in-effect": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"packages/extension-ui/src/hooks/useIsMounted.ts": {
|
||||
"react-hooks/refs": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"packages/extension-ui/src/hooks/useLedger.ts": {
|
||||
"react-hooks/set-state-in-effect": {
|
||||
"count": 1
|
||||
},
|
||||
"react-hooks/set-state-in-render": {
|
||||
"count": 4
|
||||
}
|
||||
},
|
||||
"packages/extension-ui/src/hooks/useMetadata.ts": {
|
||||
"react-hooks/set-state-in-effect": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"packages/extension-ui/src/partials/AccountSelection.tsx": {
|
||||
"react-hooks/set-state-in-effect": {
|
||||
"count": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -11,13 +11,13 @@ export default [
|
||||
...baseConfig,
|
||||
{
|
||||
rules: {
|
||||
'import/extensions': 'off'
|
||||
'import-x/extensions': 'off'
|
||||
}
|
||||
},
|
||||
{
|
||||
files: ['**/*.spec.ts', '**/*.spec.tsx'],
|
||||
rules: {
|
||||
'deprecation/deprecation': 'off'
|
||||
'@typescript-eslint/no-deprecated': 'off'
|
||||
}
|
||||
}
|
||||
];
|
||||
+1
-1
@@ -47,7 +47,7 @@
|
||||
"test:one": "EXTENSION_PREFIX='test' pezkuwi-dev-run-test --env browser"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@pezkuwi/dev": "^0.85.12",
|
||||
"@pezkuwi/dev": "^0.86.3",
|
||||
"@types/node": "^20.10.5",
|
||||
"eslint-scope": "^5.1.1",
|
||||
"i18next-scanner": "^4.4.0",
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
"tslib": "^2.8.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@pezkuwi/dev-test": "^0.84.3",
|
||||
"@pezkuwi/dev-test": "^0.86.3",
|
||||
"@pezkuwi/extension-mocks": "0.62.27"
|
||||
}
|
||||
}
|
||||
@@ -9,8 +9,8 @@ import type { Registry, SignerPayloadJSON, SignerPayloadRaw } from '@pezkuwi/typ
|
||||
import type { SubjectInfo } from '@pezkuwi/ui-keyring/observable/types';
|
||||
import type { KeypairType } from '@pezkuwi/util-crypto/types';
|
||||
import type { AccountJson, AllowedPath, AuthorizeRequest, MessageTypes, MetadataRequest, RequestAccountBatchExport, RequestAccountChangePassword, RequestAccountCreateExternal, RequestAccountCreateHardware, RequestAccountCreateSuri, RequestAccountEdit, RequestAccountExport, RequestAccountForget, RequestAccountShow, RequestAccountTie, RequestAccountValidate, RequestActiveTabsUrlUpdate, RequestAuthorizeApprove, RequestBatchRestore, RequestDeriveCreate, RequestDeriveValidate, RequestJsonRestore, RequestMetadataApprove, RequestMetadataReject, RequestSeedCreate, RequestSeedValidate, RequestSigningApprovePassword, RequestSigningApproveSignature, RequestSigningCancel, RequestSigningIsLocked, RequestTypes, RequestUpdateAuthorizedAccounts, ResponseAccountExport, ResponseAccountsExport, ResponseAuthorizeList, ResponseDeriveValidate, ResponseJsonGetAccountInfo, ResponseSeedCreate, ResponseSeedValidate, ResponseSigningIsLocked, ResponseType, SigningRequest } from '../types.js';
|
||||
import type { AuthorizedAccountsDiff } from './State.js';
|
||||
import type State from './State.js';
|
||||
import type { AuthorizedAccountsDiff } from './State.js';
|
||||
|
||||
import { ALLOWED_PATH, PASSWORD_EXPIRY_MS } from '@pezkuwi/extension-base/defaults';
|
||||
import { metadataExpand } from '@pezkuwi/extension-chains';
|
||||
@@ -296,7 +296,7 @@ export default class Extension {
|
||||
try {
|
||||
keyring.restoreAccount(file, password);
|
||||
} catch (error) {
|
||||
throw new Error((error as Error).message);
|
||||
throw new Error((error as Error).message, { cause: error });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,7 +304,7 @@ export default class Extension {
|
||||
try {
|
||||
keyring.restoreAccounts(file, password);
|
||||
} catch (error) {
|
||||
throw new Error((error as Error).message);
|
||||
throw new Error((error as Error).message, { cause: error });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -320,7 +320,7 @@ export default class Extension {
|
||||
} as ResponseJsonGetAccountInfo;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
throw new Error((e as Error).message);
|
||||
throw new Error((e as Error).message, { cause: e });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -570,7 +570,6 @@ export default class Extension {
|
||||
}
|
||||
|
||||
// Weird thought, the eslint override is not needed in Tabs
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
public async handle<TMessageType extends MessageTypes> (id: string, type: TMessageType, request: RequestTypes[TMessageType], port?: chrome.runtime.Port): Promise<ResponseType<TMessageType>> {
|
||||
switch (type) {
|
||||
case 'pri(authorize.approve)':
|
||||
|
||||
@@ -30,7 +30,7 @@ interface AuthRequest extends Resolver<AuthResponse> {
|
||||
url: string;
|
||||
}
|
||||
|
||||
export type AuthorizedAccountsDiff = [url: string, authorizedAccounts: AuthUrlInfo['authorizedAccounts']][]
|
||||
export type AuthorizedAccountsDiff = [url: string, authorizedAccounts: AuthUrlInfo['authorizedAccounts']][];
|
||||
|
||||
interface MetaRequest extends Resolver<boolean> {
|
||||
id: string;
|
||||
@@ -50,7 +50,7 @@ type Providers = Record<string, {
|
||||
// The provider is not running at init, calling this will instantiate the
|
||||
// provider.
|
||||
start: () => ProviderInterface;
|
||||
}>
|
||||
}>;
|
||||
|
||||
interface SignRequest extends Resolver<ResponseSigning> {
|
||||
account: AccountJson;
|
||||
@@ -80,7 +80,7 @@ const NORMAL_WINDOW_OPTS: chrome.windows.CreateData = {
|
||||
export enum NotificationOptions {
|
||||
None,
|
||||
Normal,
|
||||
PopUp,
|
||||
PopUp
|
||||
}
|
||||
|
||||
const AUTH_URLS_KEY = 'authUrls';
|
||||
@@ -518,7 +518,7 @@ export default class State {
|
||||
return parsedUrl.origin;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
throw new Error('Invalid URL');
|
||||
throw new Error('Invalid URL', { cause: e });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -796,7 +796,7 @@ export default class State {
|
||||
try {
|
||||
this.handleSignRequest(url);
|
||||
} catch (error) {
|
||||
return Promise.reject(error);
|
||||
return Promise.reject(error instanceof Error ? error : new Error(String(error)));
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject): void => {
|
||||
|
||||
@@ -9,8 +9,8 @@ import type { JsonRpcResponse } from '@pezkuwi/rpc-provider/types';
|
||||
import type { SignerPayloadJSON, SignerPayloadRaw } from '@pezkuwi/types/types';
|
||||
import type { SubjectInfo } from '@pezkuwi/ui-keyring/observable/types';
|
||||
import type { AuthUrlInfo, MessageTypes, RequestAccountList, RequestAccountUnsubscribe, RequestAuthorizeTab, RequestRpcSend, RequestRpcSubscribe, RequestRpcUnsubscribe, RequestTypes, ResponseRpcListProviders, ResponseSigning, ResponseTypes, SubscriptionMessageTypes } from '../types.js';
|
||||
import type { AuthResponse } from './State.js';
|
||||
import type State from './State.js';
|
||||
import type { AuthResponse } from './State.js';
|
||||
|
||||
import { combineLatest, type Subscription } from 'rxjs';
|
||||
|
||||
@@ -113,7 +113,7 @@ export default class Tabs {
|
||||
private accountsUnsubscribe (url: string, { id }: RequestAccountUnsubscribe): boolean {
|
||||
const sub = this.#accountSubs[id];
|
||||
|
||||
if (!sub || sub.url !== url) {
|
||||
if (sub?.url !== url) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// Copyright 2019-2026 @pezkuwi/extension-base authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/* eslint-disable no-use-before-define */
|
||||
|
||||
import type { InjectedAccount, InjectedMetadataKnown, MetadataDef, ProviderList, ProviderMeta } from '@pezkuwi/extension-inject/types';
|
||||
import type { KeyringPair, KeyringPair$Json, KeyringPair$Meta } from '@pezkuwi/keyring/types';
|
||||
import type { JsonRpcResponse } from '@pezkuwi/rpc-provider/types';
|
||||
@@ -45,7 +43,7 @@ export interface AccountJson extends KeyringPair$Meta {
|
||||
|
||||
export type AccountWithChildren = AccountJson & {
|
||||
children?: AccountWithChildren[];
|
||||
}
|
||||
};
|
||||
|
||||
export interface AccountsContext {
|
||||
accounts: AccountJson[];
|
||||
@@ -74,7 +72,7 @@ export interface SigningRequest {
|
||||
url: string;
|
||||
}
|
||||
|
||||
export type ConnectedTabsUrlResponse = string[]
|
||||
export type ConnectedTabsUrlResponse = string[];
|
||||
|
||||
// [MessageType]: [RequestType, ResponseType, SubscriptionMessageType?]
|
||||
export interface RequestSignatures {
|
||||
@@ -148,7 +146,7 @@ export type RequestTypes = {
|
||||
[MessageType in keyof RequestSignatures]: RequestSignatures[MessageType][0]
|
||||
};
|
||||
|
||||
export type MessageTypesWithNullRequest = NullKeys<RequestTypes>
|
||||
export type MessageTypesWithNullRequest = NullKeys<RequestTypes>;
|
||||
|
||||
export interface TransportRequestMessage<TMessageType extends MessageTypes> {
|
||||
id: string;
|
||||
@@ -396,7 +394,7 @@ export type SubscriptionMessageTypes = NoUndefinedValues<{
|
||||
}>;
|
||||
|
||||
export type MessageTypesWithSubscriptions = keyof SubscriptionMessageTypes;
|
||||
export type MessageTypesWithNoSubscriptions = Exclude<MessageTypes, keyof SubscriptionMessageTypes>
|
||||
export type MessageTypesWithNoSubscriptions = Exclude<MessageTypes, keyof SubscriptionMessageTypes>;
|
||||
|
||||
export interface RequestSign {
|
||||
readonly payload: SignerPayloadJSON | SignerPayloadRaw;
|
||||
|
||||
@@ -30,9 +30,9 @@ const handlers: Handlers = {};
|
||||
|
||||
// a generic message sender that creates an event, returning a promise that will
|
||||
// resolve once the event is resolved (by the response listener just below this)
|
||||
export function sendMessage<TMessageType extends MessageTypesWithNullRequest>(message: TMessageType): Promise<ResponseTypes[TMessageType]>;
|
||||
export function sendMessage<TMessageType extends MessageTypesWithNoSubscriptions>(message: TMessageType, request: RequestTypes[TMessageType]): Promise<ResponseTypes[TMessageType]>;
|
||||
export function sendMessage<TMessageType extends MessageTypesWithSubscriptions>(message: TMessageType, request: RequestTypes[TMessageType], subscriber: (data: SubscriptionMessageTypes[TMessageType]) => void): Promise<ResponseTypes[TMessageType]>;
|
||||
export function sendMessage<TMessageType extends MessageTypesWithNullRequest> (message: TMessageType): Promise<ResponseTypes[TMessageType]>;
|
||||
export function sendMessage<TMessageType extends MessageTypesWithNoSubscriptions> (message: TMessageType, request: RequestTypes[TMessageType]): Promise<ResponseTypes[TMessageType]>;
|
||||
export function sendMessage<TMessageType extends MessageTypesWithSubscriptions> (message: TMessageType, request: RequestTypes[TMessageType], subscriber: (data: SubscriptionMessageTypes[TMessageType]) => void): Promise<ResponseTypes[TMessageType]>;
|
||||
|
||||
export function sendMessage<TMessageType extends MessageTypes> (message: TMessageType, request?: RequestTypes[TMessageType], subscriber?: (data: unknown) => void): Promise<ResponseTypes[TMessageType]> {
|
||||
return new Promise((resolve, reject): void => {
|
||||
@@ -79,8 +79,7 @@ export function handleResponse<TMessageType extends MessageTypes> (data: Transpo
|
||||
}
|
||||
|
||||
if (data.subscription) {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
(handler.subscriber as Function)(data.subscription);
|
||||
handler.subscriber?.(data.subscription);
|
||||
} else if (data.error) {
|
||||
handler.reject(new Error(data.error));
|
||||
} else {
|
||||
|
||||
@@ -15,10 +15,13 @@ export default class AccountsStore extends BaseStore<KeyringJson> implements Key
|
||||
);
|
||||
}
|
||||
|
||||
// KeyringStore.set returns void and the keyring does not wait on it;
|
||||
// BaseStore.set handles its own failure, so this promise never rejects.
|
||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||
public override async set (key: string, value: KeyringJson, update?: () => void): Promise<void> {
|
||||
// shortcut, don't save testing accounts in extension storage
|
||||
if (key.startsWith('account:') && value.meta && value.meta.isTesting) {
|
||||
update && update();
|
||||
if (key.startsWith('account:') && value.meta?.isTesting) {
|
||||
update?.();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ const expanded = new Map<string, Chain>();
|
||||
export function metadataExpand (definition: MetadataDef, isPartial = false): Chain {
|
||||
const cached = expanded.get(definition.genesisHash);
|
||||
|
||||
if (cached && cached.specVersion === definition.specVersion) {
|
||||
if (cached?.specVersion === definition.specVersion) {
|
||||
return cached;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,10 @@ export function metadataExpand (definition: MetadataDef, isPartial = false): Cha
|
||||
registry.register(types);
|
||||
}
|
||||
|
||||
// Needed in this package's own build, where the type augmentation is not
|
||||
// loaded and createType returns a plain Codec; the repository-wide lint sees
|
||||
// it augmented.
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||
registry.setChainProperties(registry.createType('ChainProperties', {
|
||||
ss58Format,
|
||||
tokenDecimals,
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
"tslib": "^2.8.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@pezkuwi/dev-test": "^0.84.3"
|
||||
"@pezkuwi/dev-test": "^0.86.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@pezkuwi/api": "*",
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
"tslib": "^2.8.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@pezkuwi/dev-test": "^0.84.3",
|
||||
"@pezkuwi/dev-test": "^0.86.3",
|
||||
"@types/chrome": "^0.0.254",
|
||||
"@types/firefox-webext-browser": "^111.0.5"
|
||||
},
|
||||
|
||||
@@ -7,7 +7,6 @@ import type { ExtDef } from '@pezkuwi/types/extrinsic/signedExtensions/types';
|
||||
import type { HexString } from '@pezkuwi/util/types';
|
||||
import type { KeypairType } from '@pezkuwi/util-crypto/types';
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
type This = typeof globalThis;
|
||||
|
||||
export type Unsubcall = () => void;
|
||||
@@ -80,7 +79,7 @@ export interface InjectedMetadata {
|
||||
provide: (definition: MetadataDef) => Promise<boolean>;
|
||||
}
|
||||
|
||||
export type ProviderList = Record<string, ProviderMeta>
|
||||
export type ProviderList = Record<string, ProviderMeta>;
|
||||
|
||||
export interface InjectedProvider extends ProviderInterface {
|
||||
listProviders: () => Promise<ProviderList>;
|
||||
|
||||
@@ -29,36 +29,21 @@ const messagingFake = new MessagingFake();
|
||||
chrome.runtime.connect.returns(messagingFake);
|
||||
|
||||
chrome.storage.local.get.returns(
|
||||
new Promise<Record<string, any>>((resolve, reject) => {
|
||||
try {
|
||||
const result = {
|
||||
authUrls: JSON.stringify({
|
||||
'http://localhost:3000': {
|
||||
authorizedAccounts: ['5FbSap4BsWfjyRhCchoVdZHkDnmDm3NEgLZ25mesq4aw2WvX'],
|
||||
count: 0,
|
||||
id: '11',
|
||||
origin: 'example.com',
|
||||
url: 'http://localhost:3000'
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
resolve(result);
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
Promise.resolve<Record<string, any>>({
|
||||
authUrls: JSON.stringify({
|
||||
'http://localhost:3000': {
|
||||
authorizedAccounts: ['5FbSap4BsWfjyRhCchoVdZHkDnmDm3NEgLZ25mesq4aw2WvX'],
|
||||
count: 0,
|
||||
id: '11',
|
||||
origin: 'example.com',
|
||||
url: 'http://localhost:3000'
|
||||
}
|
||||
})
|
||||
}));
|
||||
|
||||
chrome.storage.local.set.returns(
|
||||
new Promise<void>((resolve, reject) => {
|
||||
try {
|
||||
resolve();
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
}));
|
||||
chrome.storage.local.set.returns(Promise.resolve());
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-member-access
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
(window as any).chrome = (globalThis as any).chrome = chrome;
|
||||
|
||||
export default chrome;
|
||||
@@ -1,5 +1,4 @@
|
||||
// Copyright 2019-2026 @pezkuwi/extension-mocks authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// eslint-disable-line
|
||||
module.exports = '';
|
||||
@@ -56,7 +56,7 @@
|
||||
"tslib": "^2.8.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@pezkuwi/dev-test": "^0.84.3",
|
||||
"@pezkuwi/dev-test": "^0.86.3",
|
||||
"@pezkuwi/extension-mocks": "0.62.27",
|
||||
"@types/enzyme": "^3.10.18",
|
||||
"@types/enzyme-adapter-react-16": "^1.0.9",
|
||||
|
||||
@@ -25,7 +25,7 @@ const { configure, mount } = enzyme;
|
||||
// ...jest.requireActual('../../messaging')
|
||||
// }));
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
configure({ adapter: new Adapter() });
|
||||
|
||||
jest.spyOn(messaging, 'getAllMetadata').mockImplementation(() => Promise.resolve([]));
|
||||
|
||||
@@ -45,7 +45,7 @@ function Account ({ address, className, genesisHash, isExternal, isHardware, isH
|
||||
? selectedAccounts.filter((account) => account !== address)
|
||||
: [...selectedAccounts, address];
|
||||
|
||||
setSelectedAccounts && setSelectedAccounts(newList);
|
||||
setSelectedAccounts?.(newList);
|
||||
}, [address, selectedAccounts, setSelectedAccounts]);
|
||||
|
||||
const _onChangeGenesis = useCallback(
|
||||
@@ -57,7 +57,7 @@ function Account ({ address, className, genesisHash, isExternal, isHardware, isH
|
||||
);
|
||||
|
||||
const _toggleEdit = useCallback(
|
||||
(): void => setEditing(({ toggleActions }) => ({ isEditing: !isEditing, toggleActions: ++toggleActions })),
|
||||
(): void => setEditing(({ toggleActions }) => ({ isEditing: !isEditing, toggleActions: toggleActions + 1 })),
|
||||
[isEditing]
|
||||
);
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
// We _could_ reformat, but just keep it as-is, since this is actually
|
||||
// externally generated and not really user-editable
|
||||
|
||||
/* eslint-disable react/jsx-sort-props */
|
||||
/* eslint-disable react/jsx-max-props-per-line */
|
||||
/* eslint-disable @stylistic/jsx-sort-props */
|
||||
/* eslint-disable @stylistic/jsx-max-props-per-line */
|
||||
|
||||
import React from 'react';
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ interface Props {
|
||||
}
|
||||
|
||||
function AccountManagement ({ className }: Props): React.ReactElement<Props> {
|
||||
const { url } = useParams<{url: string}>();
|
||||
const { url } = useParams<{ url: string }>();
|
||||
const decodedUrl = decodeURIComponent(url);
|
||||
const { selectedAccounts = [], setSelectedAccounts } = useContext(AccountContext);
|
||||
const { t } = useTranslation();
|
||||
@@ -28,7 +28,7 @@ function AccountManagement ({ className }: Props): React.ReactElement<Props> {
|
||||
return;
|
||||
}
|
||||
|
||||
setSelectedAccounts && setSelectedAccounts(list[decodedUrl].authorizedAccounts);
|
||||
setSelectedAccounts?.(list[decodedUrl].authorizedAccounts);
|
||||
})
|
||||
.catch(console.error);
|
||||
}, [setSelectedAccounts, decodedUrl]);
|
||||
|
||||
@@ -20,7 +20,7 @@ import Request from './Request.js';
|
||||
|
||||
const { configure, mount } = enzyme;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
configure({ adapter: new Adapter() });
|
||||
|
||||
const oneRequest = [{ id: '1', request: { origin: '???' }, url: 'http://pezkuwichain.io' }];
|
||||
|
||||
@@ -30,7 +30,7 @@ function Request ({ authId, className, request: { origin }, url }: Props): React
|
||||
.filter(({ isDefaultAuthSelected }) => !!isDefaultAuthSelected)
|
||||
.map(({ address }) => address);
|
||||
|
||||
setSelectedAccounts && setSelectedAccounts(defaultAccountSelection);
|
||||
setSelectedAccounts?.(defaultAccountSelection);
|
||||
}, [accounts, setSelectedAccounts]);
|
||||
|
||||
const _onApprove = useCallback(
|
||||
|
||||
@@ -29,7 +29,7 @@ const { configure, mount } = enzyme;
|
||||
// For this file, there are a lot of them
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
configure({ adapter: new Adapter() });
|
||||
|
||||
describe('Create Account', () => {
|
||||
|
||||
@@ -38,12 +38,11 @@ function CreateAccount ({ className }: Props): React.ReactElement {
|
||||
setSeed(seed);
|
||||
})
|
||||
.catch(console.error);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
useEffect((): void => {
|
||||
if (seed) {
|
||||
const type = chain && chain.definition.chainType === 'ethereum'
|
||||
const type = chain?.definition.chainType === 'ethereum'
|
||||
? 'ethereum'
|
||||
: DEFAULT_TYPE;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import '@pezkuwi/extension-mocks/chrome';
|
||||
|
||||
import type { ReactWrapper } from 'enzyme';
|
||||
import type * as _ from '@pezkuwi/dev-test/globals.d.ts';
|
||||
import type { AccountJson, ResponseDeriveValidate } from '@pezkuwi/extension-base/background/types';
|
||||
import type { AccountJson } from '@pezkuwi/extension-base/background/types';
|
||||
|
||||
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
|
||||
import enzyme from 'enzyme';
|
||||
@@ -32,7 +32,7 @@ const { configure, mount } = enzyme;
|
||||
// For this file, there are a lot of them
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
configure({ adapter: new Adapter() });
|
||||
|
||||
const parentPassword = 'pass';
|
||||
@@ -57,7 +57,7 @@ describe('Derive', () => {
|
||||
}> => {
|
||||
const onActionStub = jest.fn();
|
||||
|
||||
const wrapper = mount(
|
||||
const wrapper = mount<React.Component>(
|
||||
<MemoryRouter initialEntries={ [`/account/derive/${accounts[account].address}`] }>
|
||||
<ActionContext.Provider value={onActionStub}>
|
||||
<AccountContext.Provider
|
||||
@@ -110,7 +110,7 @@ describe('Derive', () => {
|
||||
throw new Error('wrong suri');
|
||||
}
|
||||
|
||||
return { address: derivedAddress, suri: defaultDerivation } as ResponseDeriveValidate;
|
||||
return { address: derivedAddress, suri: defaultDerivation };
|
||||
});
|
||||
|
||||
it('Button is disabled and password field visible, path field is hidden', () => {
|
||||
@@ -216,7 +216,7 @@ describe('Derive', () => {
|
||||
|
||||
expect(button.prop('disabled')).toBe(true);
|
||||
expect(wrapper.find('.warning-message')).toHaveLength(1);
|
||||
// eslint-disable-next-line quotes
|
||||
// eslint-disable-next-line @stylistic/quotes
|
||||
expect(wrapper.find('.warning-message').first().text()).toEqual("`///password` not supported for derivation");
|
||||
});
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ const { configure, mount } = enzyme;
|
||||
// ...jest.requireActual('../messaging')
|
||||
// }));
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
configure({ adapter: new Adapter() });
|
||||
|
||||
describe('Export component', () => {
|
||||
|
||||
@@ -15,7 +15,7 @@ import { styled } from '../styled.js';
|
||||
|
||||
const MIN_LENGTH = 6;
|
||||
|
||||
interface Props extends RouteComponentProps<{address: string}> {
|
||||
interface Props extends RouteComponentProps<{ address: string }> {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
@@ -35,8 +35,8 @@ function Export ({ className, match: { params: { address } } }: Props): React.Re
|
||||
(password: string) => {
|
||||
setPass(password);
|
||||
setError('');
|
||||
}
|
||||
, []);
|
||||
},
|
||||
[]);
|
||||
|
||||
const _onExportButtonClick = useCallback(
|
||||
(): void => {
|
||||
@@ -46,7 +46,7 @@ function Export ({ className, match: { params: { address } } }: Props): React.Re
|
||||
.then(({ exportedJson }) => {
|
||||
const blob = new Blob([JSON.stringify(exportedJson)], { type: 'application/json; charset=utf-8' });
|
||||
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
||||
fileSaver.saveAs(blob, `${address}.json`);
|
||||
|
||||
onAction('/');
|
||||
|
||||
@@ -36,8 +36,8 @@ function ExportAll ({ className }: Props): React.ReactElement<Props> {
|
||||
(password: string) => {
|
||||
setPass(password);
|
||||
setError('');
|
||||
}
|
||||
, []);
|
||||
},
|
||||
[]);
|
||||
|
||||
const _onExportAllButtonClick = useCallback(
|
||||
(): void => {
|
||||
@@ -47,7 +47,7 @@ function ExportAll ({ className }: Props): React.ReactElement<Props> {
|
||||
.then(({ exportedJson }) => {
|
||||
const blob = new Blob([JSON.stringify(exportedJson)], { type: 'application/json; charset=utf-8' });
|
||||
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
||||
fileSaver.saveAs(blob, `batch_exported_account_${Date.now()}.json`);
|
||||
|
||||
onAction('/');
|
||||
|
||||
@@ -49,7 +49,7 @@ interface QrScanAddressProps {
|
||||
// ...jest.requireActual('../messaging')
|
||||
// }));
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
configure({ adapter: new Adapter() });
|
||||
|
||||
const typeName = async (wrapper: ReactWrapper, value: string) => {
|
||||
@@ -77,7 +77,6 @@ describe('ImportQr component', () => {
|
||||
</MemoryRouter>
|
||||
);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
act(() => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||
(wrapper.find('QrScanAddress').first().prop('onScan') as unknown as QrScanAddressProps['onScan'])(mockedAccount);
|
||||
|
||||
@@ -38,7 +38,7 @@ const account = {
|
||||
// For this file, there are a lot of them
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
configure({ adapter: new Adapter() });
|
||||
|
||||
jest.spyOn(messaging, 'getAllMetadata').mockImplementation(() => Promise.resolve([]));
|
||||
|
||||
@@ -36,7 +36,7 @@ function ImportSeed (): React.ReactElement {
|
||||
|
||||
useEffect((): void => {
|
||||
setType(
|
||||
chain && chain.definition.chainType === 'ethereum'
|
||||
chain?.definition.chainType === 'ethereum'
|
||||
? 'ethereum'
|
||||
: DEFAULT_TYPE
|
||||
);
|
||||
|
||||
@@ -120,7 +120,7 @@ function Extrinsic ({ className, payload, request: { blockNumber, genesisHash, m
|
||||
const chain = useMetadata(genesisHash);
|
||||
const specVersion = useRef(bnToBn(hexSpec)).current;
|
||||
const decoded = useMemo(
|
||||
() => chain && chain.hasMetadata
|
||||
() => chain?.hasMetadata
|
||||
? decodeMethod(method, chain, specVersion)
|
||||
: { args: null, method: null },
|
||||
[method, chain, specVersion]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright 2019-2026 @pezkuwi/extension-ui authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/* eslint-disable deprecation/deprecation */
|
||||
/* eslint-disable @typescript-eslint/no-deprecated */
|
||||
|
||||
import type { Chain } from '@pezkuwi/extension-chains/types';
|
||||
import type { Ledger, LedgerGeneric } from '@pezkuwi/hw-ledger';
|
||||
|
||||
@@ -41,7 +41,7 @@ const { configure, mount } = enzyme;
|
||||
// For this file, there are a lot of them
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
configure({ adapter: new Adapter() });
|
||||
|
||||
describe('Signing requests', () => {
|
||||
@@ -345,7 +345,6 @@ describe('Signing requests', () => {
|
||||
wrapper.find('FontAwesomeIcon.arrowRight').simulate('click');
|
||||
await act(flushAllPromises);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
act(() => {
|
||||
emitter.emit('request', [signRequests[0]]);
|
||||
});
|
||||
|
||||
@@ -3,20 +3,24 @@
|
||||
|
||||
declare module '*.svg' {
|
||||
const url: string;
|
||||
|
||||
export default url;
|
||||
}
|
||||
|
||||
declare module '*.png' {
|
||||
const url: string;
|
||||
|
||||
export default url;
|
||||
}
|
||||
|
||||
declare module '*.woff' {
|
||||
const url: string;
|
||||
|
||||
export default url;
|
||||
}
|
||||
|
||||
declare module '*.woff2' {
|
||||
const url: string;
|
||||
|
||||
export default url;
|
||||
}
|
||||
@@ -20,7 +20,7 @@ import { AccountNamePasswordCreation, Input, InputWithLabel, NextStepButton } fr
|
||||
|
||||
const { configure, mount } = enzyme;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
configure({ adapter: new Adapter() });
|
||||
|
||||
const account = {
|
||||
|
||||
@@ -40,7 +40,7 @@ function AccountNamePasswordCreation ({ buttonLabel, isBusy, onBackClick, onCrea
|
||||
|
||||
const _onPasswordChange = useCallback(
|
||||
(password: string | null) => {
|
||||
onPasswordChange && onPasswordChange(password || '');
|
||||
onPasswordChange?.(password || '');
|
||||
setPassword(password);
|
||||
},
|
||||
[onPasswordChange]
|
||||
@@ -50,7 +50,7 @@ function AccountNamePasswordCreation ({ buttonLabel, isBusy, onBackClick, onCrea
|
||||
() => {
|
||||
_onNameChange(null);
|
||||
setPassword(null);
|
||||
onBackClick && onBackClick();
|
||||
onBackClick?.();
|
||||
},
|
||||
[_onNameChange, onBackClick]
|
||||
);
|
||||
|
||||
@@ -38,7 +38,7 @@ const { configure, mount } = enzyme;
|
||||
// ...jest.requireActual('../MetadataCache')
|
||||
// }));
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
configure({ adapter: new Adapter() });
|
||||
|
||||
interface AccountTestJson extends AccountJson {
|
||||
@@ -121,7 +121,7 @@ const mountComponent = async (addressComponentProps: AddressComponentProps, cont
|
||||
const actionStub = jest.fn();
|
||||
const { actions = actionStub } = addressComponentProps;
|
||||
|
||||
const wrapper = mount(
|
||||
const wrapper = mount<React.Component>(
|
||||
<AccountContext.Provider
|
||||
value={{
|
||||
accounts: contextAccounts,
|
||||
|
||||
@@ -25,12 +25,12 @@ function Checkbox ({ checked, className, indeterminate, label, onChange, onClick
|
||||
}, [indeterminate]);
|
||||
|
||||
const _onChange = useCallback(
|
||||
(event: React.ChangeEvent<HTMLInputElement>) => onChange && onChange(event.target.checked),
|
||||
(event: React.ChangeEvent<HTMLInputElement>) => onChange?.(event.target.checked),
|
||||
[onChange]
|
||||
);
|
||||
|
||||
const _onClick = useCallback(
|
||||
() => onClick && onClick(),
|
||||
() => onClick?.(),
|
||||
[onClick]
|
||||
);
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ interface Props {
|
||||
function Dropdown ({ className, defaultValue, isDisabled, isFocussed, label, onBlur, onChange, options, value }: Props): React.ReactElement<Props> {
|
||||
const _onChange = useCallback(
|
||||
({ target: { value } }: React.ChangeEvent<HTMLSelectElement>) =>
|
||||
onChange && onChange(value.trim()),
|
||||
onChange?.(value.trim()),
|
||||
[onChange]
|
||||
);
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ function InputFile ({ accept, className = '', clearContent, convertHex, isDisabl
|
||||
const name = file.name;
|
||||
const data = convertResult(target.result as ArrayBuffer, convertHex);
|
||||
|
||||
onChange && onChange(data, name);
|
||||
onChange?.(data, name);
|
||||
dropRef && setFile({
|
||||
name,
|
||||
size: data.length
|
||||
|
||||
@@ -25,7 +25,7 @@ function InputFilter ({ className, onChange, placeholder, value, withReset = fal
|
||||
|
||||
const onResetFilter = useCallback(() => {
|
||||
onChange('');
|
||||
inputRef?.current && inputRef.current.select();
|
||||
inputRef?.current?.select();
|
||||
}, [onChange]);
|
||||
|
||||
return (
|
||||
|
||||
@@ -48,7 +48,7 @@ function InputWithLabel ({ className, defaultValue, disabled, isError, isFocused
|
||||
|
||||
const _onChange = useCallback(
|
||||
({ target: { value } }: React.ChangeEvent<HTMLInputElement>): void => {
|
||||
onChange && onChange(value);
|
||||
onChange?.(value);
|
||||
},
|
||||
[onChange]
|
||||
);
|
||||
@@ -67,7 +67,7 @@ function InputWithLabel ({ className, defaultValue, disabled, isError, isFocused
|
||||
onBlur={onBlur}
|
||||
onChange={_onChange}
|
||||
onFocus={onFocus}
|
||||
onKeyPress={_checkKey}
|
||||
onKeyDown={_checkKey}
|
||||
placeholder={placeholder}
|
||||
readOnly={isReadOnly}
|
||||
spellCheck={false}
|
||||
|
||||
@@ -20,7 +20,7 @@ interface Props {
|
||||
export default function TextAreaWithLabel ({ className, isError, isFocused, isReadOnly, label, onChange, rowsCount, value }: Props): React.ReactElement<Props> {
|
||||
const _onChange = useCallback(
|
||||
({ target: { value } }: React.ChangeEvent<HTMLTextAreaElement>): void => {
|
||||
onChange && onChange(value);
|
||||
onChange?.(value);
|
||||
},
|
||||
[onChange]
|
||||
);
|
||||
|
||||
@@ -23,7 +23,7 @@ type Props<T extends BasicProps> = T & {
|
||||
defaultValue?: string;
|
||||
onValidatedChange: (value: string | null) => void;
|
||||
validator: Validator<string>;
|
||||
}
|
||||
};
|
||||
|
||||
function ValidatedInput<T extends Record<string, unknown>> ({ className, component: Input, defaultValue, onValidatedChange, validator, ...props }: Props<T>): React.ReactElement<Props<T>> {
|
||||
const [value, setValue] = useState(defaultValue || '');
|
||||
|
||||
@@ -19,6 +19,6 @@ const MetadataReqContext = React.createContext<MetadataRequest[]>([]);
|
||||
const SettingsContext = React.createContext<SettingsStruct>(settings.get());
|
||||
const SigningReqContext = React.createContext<SigningRequest[]>([]);
|
||||
const ThemeSwitchContext = React.createContext<(theme: Theme) => void>(noop);
|
||||
const ToastContext = React.createContext<({show: (message: string) => void})>({ show: noop });
|
||||
const ToastContext = React.createContext<({ show: (message: string) => void })>({ show: noop });
|
||||
|
||||
export { AccountContext, ActionContext, AuthorizeReqContext, MediaContext, MetadataReqContext, SettingsContext, SigningReqContext, ThemeSwitchContext, ToastContext };
|
||||
@@ -14,7 +14,7 @@ export function chooseTheme (): Theme {
|
||||
: 'light';
|
||||
}
|
||||
|
||||
return window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches
|
||||
return window.matchMedia?.('(prefers-color-scheme: light)').matches
|
||||
? 'light'
|
||||
: 'dark';
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
// This is to ensure the legacy `class Ledger` doesn't throw linting errors.
|
||||
//
|
||||
/* eslint-disable deprecation/deprecation */
|
||||
/* eslint-disable @typescript-eslint/no-deprecated */
|
||||
|
||||
import type { Network } from '@pezkuwi/networks/types';
|
||||
import type { HexString } from '@pezkuwi/util/types';
|
||||
@@ -50,7 +50,7 @@ function getState (): StateBase {
|
||||
}
|
||||
|
||||
function retrieveLedger (genesis: string): LedgerGeneric | Ledger {
|
||||
let ledger: LedgerGeneric | Ledger | null = null;
|
||||
let ledger: LedgerGeneric | Ledger;
|
||||
|
||||
const currApp = settings.get().ledgerApp;
|
||||
|
||||
@@ -64,10 +64,6 @@ function retrieveLedger (genesis: string): LedgerGeneric | Ledger {
|
||||
|
||||
assert(def.slip44, 'Slip44 is not available for this network, please report an issue to update this chains slip44');
|
||||
|
||||
// All chains use the `slip44` from polkadot in their derivation path in ledger.
|
||||
// This interface is specific to the underlying PolkadotGenericApp.
|
||||
ledger = new LedgerGeneric('webusb', def.network, knownLedger['polkadot']);
|
||||
|
||||
if (currApp === 'generic') {
|
||||
// All chains use the `slip44` from polkadot in their derivation path in ledger.
|
||||
// This interface is specific to the underlying PolkadotGenericApp.
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { RefObject } from 'react';
|
||||
|
||||
import { useCallback, useEffect } from 'react';
|
||||
|
||||
export default function useOutsideClick (refs: RefObject<HTMLDivElement|null>[], callback: () => void): void {
|
||||
export default function useOutsideClick (refs: RefObject<HTMLDivElement | null>[], callback: () => void): void {
|
||||
const handleClick = useCallback((e: MouseEvent): void => {
|
||||
refs.every(({ current }) =>
|
||||
current &&
|
||||
|
||||
@@ -5,6 +5,6 @@ import { useContext } from 'react';
|
||||
|
||||
import { ToastContext } from '../components/contexts.js';
|
||||
|
||||
export default function useToast (): {show: (message: string) => void} {
|
||||
export default function useToast (): { show: (message: string) => void } {
|
||||
return useContext(ToastContext);
|
||||
}
|
||||
@@ -49,8 +49,7 @@ function onPortMessageHandler (data: Message['data']): void {
|
||||
}
|
||||
|
||||
if (data.subscription) {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
(handler.subscriber as Function)(data.subscription);
|
||||
handler.subscriber?.(data.subscription);
|
||||
} else if (data.error) {
|
||||
handler.reject(new Error(data.error));
|
||||
} else {
|
||||
@@ -68,9 +67,10 @@ const portConfig = {
|
||||
portName: PORT_EXTENSION
|
||||
};
|
||||
|
||||
function sendMessage<TMessageType extends MessageTypesWithNullRequest>(message: TMessageType): Promise<ResponseTypes[TMessageType]>;
|
||||
function sendMessage<TMessageType extends MessageTypesWithNoSubscriptions>(message: TMessageType, request: RequestTypes[TMessageType]): Promise<ResponseTypes[TMessageType]>;
|
||||
function sendMessage<TMessageType extends MessageTypesWithSubscriptions>(message: TMessageType, request: RequestTypes[TMessageType], subscriber: (data: SubscriptionMessageTypes[TMessageType]) => void): Promise<ResponseTypes[TMessageType]>;
|
||||
function sendMessage<TMessageType extends MessageTypesWithNullRequest> (message: TMessageType): Promise<ResponseTypes[TMessageType]>;
|
||||
function sendMessage<TMessageType extends MessageTypesWithNoSubscriptions> (message: TMessageType, request: RequestTypes[TMessageType]): Promise<ResponseTypes[TMessageType]>;
|
||||
function sendMessage<TMessageType extends MessageTypesWithSubscriptions> (message: TMessageType, request: RequestTypes[TMessageType], subscriber: (data: SubscriptionMessageTypes[TMessageType]) => void): Promise<ResponseTypes[TMessageType]>;
|
||||
|
||||
function sendMessage<TMessageType extends MessageTypes> (message: TMessageType, request?: RequestTypes[TMessageType], subscriber?: (data: unknown) => void): Promise<ResponseTypes[TMessageType]> {
|
||||
return new Promise((resolve, reject): void => {
|
||||
const id = getId();
|
||||
@@ -82,7 +82,7 @@ function sendMessage<TMessageType extends MessageTypes> (message: TMessageType,
|
||||
port = connectedPort;
|
||||
}).catch((error) => {
|
||||
console.error(`Failed to send message: ${(error as Error).message}`);
|
||||
reject(error);
|
||||
reject(error instanceof Error ? error : new Error(String(error)));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -30,12 +30,12 @@ function AccountSelection ({ className, origin, showHidden = false, url, withWar
|
||||
const allDisplayedAddresses = useMemo(
|
||||
() => showHidden
|
||||
? accounts.map(({ address }) => address)
|
||||
: allVisibleAccounts.map(({ address }) => address)
|
||||
, [accounts, allVisibleAccounts, showHidden]
|
||||
: allVisibleAccounts.map(({ address }) => address),
|
||||
[accounts, allVisibleAccounts, showHidden]
|
||||
);
|
||||
const areAllAccountsSelected = useMemo(
|
||||
() => selectedAccounts.length === allDisplayedAddresses.length
|
||||
, [allDisplayedAddresses.length, selectedAccounts.length]
|
||||
() => selectedAccounts.length === allDisplayedAddresses.length,
|
||||
[allDisplayedAddresses.length, selectedAccounts.length]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -54,12 +54,12 @@ function AccountSelection ({ className, origin, showHidden = false, url, withWar
|
||||
|
||||
const _onSelectAllToggle = useCallback(() => {
|
||||
if (areAllAccountsSelected) {
|
||||
setSelectedAccounts && setSelectedAccounts([]);
|
||||
setSelectedAccounts?.([]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
setSelectedAccounts && setSelectedAccounts(allDisplayedAddresses);
|
||||
setSelectedAccounts?.(allDisplayedAddresses);
|
||||
}, [allDisplayedAddresses, areAllAccountsSelected, setSelectedAccounts]
|
||||
);
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import Settings from './MenuSettings.js';
|
||||
|
||||
const { configure, mount } = enzyme;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
configure({ adapter: new Adapter() });
|
||||
|
||||
describe('Header component', () => {
|
||||
|
||||
@@ -39,8 +39,8 @@ function Header ({ children, className = '', onFilter, showAdd, showBackArrow, s
|
||||
const addMenuRef = useRef<HTMLDivElement>(null);
|
||||
const setIconRef = useRef(null);
|
||||
const setMenuRef = useRef<HTMLDivElement>(null);
|
||||
const isConnected = useMemo(() => connectedTabsUrl.length >= 1
|
||||
, [connectedTabsUrl]);
|
||||
const isConnected = useMemo(() => connectedTabsUrl.length >= 1,
|
||||
[connectedTabsUrl]);
|
||||
const onAction = useContext(ActionContext);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -74,7 +74,7 @@ function Header ({ children, className = '', onFilter, showAdd, showBackArrow, s
|
||||
const _onChangeFilter = useCallback(
|
||||
(filter: string) => {
|
||||
setFilter(filter);
|
||||
onFilter && onFilter(filter);
|
||||
onFilter?.(filter);
|
||||
},
|
||||
[onFilter]
|
||||
);
|
||||
@@ -91,8 +91,8 @@ function Header ({ children, className = '', onFilter, showAdd, showBackArrow, s
|
||||
);
|
||||
|
||||
const _onBackArrowClick = useCallback(
|
||||
() => onAction('../index.js')
|
||||
, [onAction]);
|
||||
() => onAction('../index.js'),
|
||||
[onAction]);
|
||||
|
||||
return (
|
||||
<div className={`${className} ${smallMargin ? 'smallMargin' : ''}`}>
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
"tslib": "^2.8.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@pezkuwi/dev": "^0.84.3",
|
||||
"@pezkuwi/dev": "^0.86.3",
|
||||
"browser-resolve": "^2.0.0",
|
||||
"buffer": "^6.0.3",
|
||||
"copy-webpack-plugin": "^11.0.0",
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
"extends": "@pezkuwi/dev/config/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"target": "ES2020",
|
||||
"target": "ES2022",
|
||||
/* FIXME Dropzone is problematic with nodenext resolution */
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Bundler",
|
||||
|
||||
Reference in new issue
Block a user