Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: leather-io/extension
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v2.21.0-dev.5
Choose a base ref
...
head repository: leather-io/extension
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: dev
Choose a head ref
Loading
Showing 1,517 changed files with 103,903 additions and 39,557 deletions.
125 changes: 101 additions & 24 deletions .dependency-cruiser.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,78 @@
/** @type {import('dependency-cruiser').IConfiguration} */
module.exports = {
export default {
extends: 'dependency-cruiser/configs/recommended',

forbidden: [
// Note: this rule is intended to override the rule by the same name in the
// `dependency-cruiser/configs/recommended` set. It removes `punycode` from
// the path given this repo uses the third party `punycode` package, not
// Node.js' deprecated built-in with the same name.
{
name: 'no-deprecated-core',
comment:
'This module depends on a node core module that has been deprecated. Find an ' +
"alternative - these are bound to exist - node doesn't deprecate lightly.",
severity: 'error',
from: {},
to: {
dependencyTypes: ['core'],
path: '^(domain|constants|sys|_linklist|_stream_wrap)$',
},
},
// Overriding from recommended set
{
name: 'not-to-unresolvable',
comment:
"This module depends on a module that cannot be found ('resolved to disk'). " +
"If it's an npm module: add it to your package.json. In all other cases you " +
'likely already know what to do.',
severity: 'error',
from: {},
to: {
// Types only package falsely triggers this rule
pathNot: ['@octokit'],
// Depcruiser fails on some legitimate type imports, so allowing them there
dependencyTypesNot: ['type-only'],
couldNotResolve: true,
},
},
{
name: 'no-orphans',
severity: 'warn',
from: { orphan: true },
severity: 'error',
from: {
orphan: true,
pathNot: ['^src/shared/models/global-types.ts', '^src/app/ui/icons/docs/icons-list.ts'],
},
to: {},
},
{
name: 'only-import-state-via-hooks',
name: 'script-context-not-to-another',
comment: 'One script context must not depend on another',
severity: 'error',
from: { path: '^src/*', pathNot: ['^src/store/*'] },
from: { path: '(^src/)([^/]+)/' },
to: {
path: ['^src/store/*'],
pathNot: [`src.*\.hooks\.ts`, `src.*\.models\.ts`, `src.*\.utils\.ts`],
path: '^$1',
pathNot: ['$1$2', '^src/shared'],
dependencyTypesNot: ['type-only'],
},
},
{
name: 'ban-jotai-outside-store',
severity: 'error',
from: { path: '^src/*', pathNot: ['^src/store/*'] },
from: { path: '^src', pathNot: ['^src/app/store/*'] },
to: { path: 'jotai*' },
},
{
name: 'ban-non-type-imports-from-webextension-polyfill',
severity: 'error',
from: { path: '^src' },
to: { path: 'webextension-polyfill', dependencyTypesNot: ['type-only'] },
},
{
name: 'component-cannot-import-pages-or-features',
severity: 'error',
from: { path: 'src/components*' },
to: { path: ['^src/pages*', '^src/features/*'] },
from: { path: ['src/app/components*', 'src/app/ui'] },
to: { path: ['^src/app/pages*', '^src/app/features/*'] },
},
{
name: 'no-circular',
@@ -50,33 +94,66 @@ module.exports = {
// },
{
name: 'features-cannot-import-pages',
comment: 'Pages are higher level abstractions than features and are typically non-reusable',
severity: 'error',
from: { path: '^src/features/.*' },
to: { path: '^src/pages/.*' },
from: { path: '^src/app/features/.*' },
to: { path: '^src/app/pages/.*' },
},
// TODO: Replace in future with new icon library
// {
// name: 'only-allow-react-icons-fi',
// comment: 'Ensure only icons from `fi` group are allowed',
// severity: 'error',
// from: { path: '^src' },
// to: { path: 'react-icons.*', pathNot: 'react-icons/fi' },
// },
{
name: 'background-cannot-import-content-scripts',
name: 'no-using-pino-directly',
comment: 'Enforce use of Pino logging library via @logger wrapper',
severity: 'error',
from: { path: '^src/background/.*' },
to: { path: '^src/content-scripts/.*' },
from: { path: '^src', pathNot: ['^src/shared/logger*'] },
to: { path: 'pino' },
},
{
name: 'content-cannot-import-background-script',
name: 'no-inter-pages-deps',
comment: 'Prohibit dependencies between pages',
severity: 'error',
from: { path: '^src/content-scripts/.*' },
to: { path: '^src/background/.*' },
from: { path: '^src/app/pages/([^/]+)/.+' },
to: {
path: '^src/app/pages/([^/]+)/.+',
pathNot: '^src/app/pages/$1/.+',
},
},
{
name: 'only-allow-react-icons-fi',
name: 'no-feature-component-external-use',
comment: `Only a given feature may import its child 'src/feature/xxx/components'`,
severity: 'error',
from: { path: '^src' },
to: { path: 'react-icons.*', pathNot: 'react-icons/fi' },
from: { path: '(^src/app/features/)([^/]+)' },
to: {
path: '^src/app/features/[^/]+/components',
pathNot: '$1$2/',
},
},
{
name: 'no-using-pino-directly',
name: 'no-feature-component-sibling-use',
comment: `Features cannot depend on a sibling feature's components`,
severity: 'error',
from: { path: '^src', pathNot: ['^src/common/logger.ts$'] },
to: { path: 'pino' },
from: { pathNot: ['^src/app/features'] },
to: { path: '^src/app/features/([^/]+)/components' },
},
{
name: 'no-logger-inpage-use',
comment: `Inpage cannot use logger, which uses unavailable APIs`,
severity: 'error',
from: { path: '^src/inpage' },
to: { path: '^src/shared/logger' },
},
{
name: 'no-external-tab-usage',
comment: `Inpage cannot use logger, which uses unavailable APIs`,
severity: 'error',
from: { path: '^src', pathNot: ['^src/app/ui/components/tabs'] },
to: { path: '@radix-ui/react-tabs' },
},
],
options: {
11 changes: 11 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
COINBASE_APP_ID=coinbaseappid
MOONPAY_API_KEY=moonpayapikey
SEGMENT_WRITE_KEY=segmentwritekey
SENTRY_DSN=sentrydsn
TRANSAK_API_KEY=transakapikey
WALLET_ENVIRONMENT=development
BESTINSLOT_API_KEY=bestinslotapikey
BITFLOW_API_HOST=bitflowapihost
BITFLOW_API_KEY=bitflowapikey
BITFLOW_STACKS_API_HOST=bitflowstacksapihost
BITFLOW_READONLY_CALL_API_HOST=bitflowreadonlycallapihost
137 changes: 137 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
const avoidWindowOpenMsg = 'Use `openInNewTab` helper';
const avoidFetchMsg = 'Use `axios` instead for consistency with the rest of the project';

module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
project: './tsconfig.json',
},
env: {
browser: true,
node: true,
es6: true,
},
globals: {
page: true,
browser: true,
context: true,
},
extends: [
'plugin:@typescript-eslint/recommended',
'plugin:react/recommended',
'plugin:react/jsx-runtime',
'plugin:react-hooks/recommended',
'plugin:storybook/recommended',
'plugin:storybook/csf',
],
ignorePatterns: ['./leather-styles'],
plugins: ['react', 'react-hooks', '@typescript-eslint'],
settings: {
react: {
version: 'detect',
},
},
rules: {
'no-console': ['error'],
'no-duplicate-imports': ['error'],
'prefer-const': [
'error',
{
ignoreReadBeforeAssign: false,
},
],
'no-restricted-globals': [
'error',
{ name: 'open', message: avoidWindowOpenMsg },
{ name: 'fetch', message: avoidFetchMsg },
],
'no-restricted-properties': [
'error',
{
object: 'window',
property: 'open',
message: avoidWindowOpenMsg,
},
{
object: 'globalThis',
property: 'open',
message: avoidWindowOpenMsg,
},
{
object: 'window',
property: 'close',
message: 'Use `closeWindow` utility helper',
},
{
object: 'window',
property: 'fetch',
message: avoidFetchMsg,
},
],
'@typescript-eslint/no-floating-promises': ['warn'],
'@typescript-eslint/no-unnecessary-type-assertion': ['warn'],
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-unsafe-assignment': [0],
'@typescript-eslint/no-unsafe-return': [0],
'@typescript-eslint/no-unsafe-call': [0],
'@typescript-eslint/no-unsafe-member-access': [0],
'@typescript-eslint/restrict-template-expressions': [0],
'@typescript-eslint/explicit-module-boundary-types': [0],
'@typescript-eslint/no-unnecessary-type-constraint': ['off'],
'@typescript-eslint/no-non-null-asserted-optional-chain': ['off'],
'@typescript-eslint/no-explicit-any': ['off'],
'@typescript-eslint/no-meaningless-void-operator': 'error',
'@typescript-eslint/ban-types': ['error'],
// This rule is off until we can enable tsconfig noUncheckedIndexedAccess
'@typescript-eslint/no-unnecessary-condition': 'off',
'@typescript-eslint/consistent-type-definitions': ['error', 'interface'],
'@typescript-eslint/array-type': ['error'],
'@typescript-eslint/method-signature-style': ['error', 'method'],
'no-warning-comments': [0],

'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': ['error'],

'react/function-component-definition': 'error',
'react/display-name': 'off',
'react/prop-types': 'off',
'react/no-unescaped-entities': 'off',
'react/jsx-uses-react': 'off',
'react/react-in-jsx-scope': 'off',
},
overrides: [
{
files: ['test/**', 'src/**/*.spec.ts'],
rules: {
'no-console': [0],
},
},
{
files: ['src/**/*'],
excludedFiles: 'src/app/store/**',
rules: {
'no-restricted-imports': [
'error',
{
paths: [
{
name: 'react-redux',
importNames: ['useSelector'],
message: 'Selectors must be exported from the store via a hook',
},
{
name: '@radix-ui/themes',
importNames: ['Flex'],
message: 'Layout components should be imported from leather-styles/jsx',
},
],
},
],
},
},
{
files: ['*.mdx'],
extends: 'plugin:mdx/recommended',
},
],
};
54 changes: 0 additions & 54 deletions .eslintrc.js

This file was deleted.

Loading