Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .github/workflows/codegen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,6 @@ jobs:
- name: Install Node.js dependencies
run: pnpm install

- name: Build packages
run: pnpm prebuild

- name: Wait for API to be ready
run: |
timeout 5m bash -c '
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ jobs:
- name: Install Node.js dependencies
run: pnpm install

- name: Run code:style check
- name: Run lint, tooling, and translation checks
run: |
pnpm run code:style
pnpm exec run-p lint test:tooling translations:inspect translations:ensure-consistency
3 changes: 0 additions & 3 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@ jobs:
- name: Install Node.js dependencies
run: pnpm install

- name: Build packages
run: pnpm prebuild

- name: Run Typescript
run: pnpm tsc

Expand Down
2 changes: 1 addition & 1 deletion jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export default {
'!src/**/*Const.ts',
],
coverageReporters: ['text-summary', 'lcov'],
collectCoverage: true,
collectCoverage: false,

testEnvironment: 'jsdom',

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"codegen:watch": "graphql-codegen --config codegen.yml -r dotenv/config --watch",
"test": "jest --config jest.config.ts",
"test:coverage": "jest --config jest.config.ts --coverage --runInBand",
"test:tooling": "node --test packages/configs/eslint.config.test.mjs",
"test:e2e": "cypress open --config-file cypress/cypress.config.js",
"translations:add": "node scripts/translations/add",
"translations:inspect": "node scripts/translations/inspect",
Expand Down
22 changes: 7 additions & 15 deletions packages/configs/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import { dirname, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'

import { fixupPluginRules } from '@eslint/compat'
import pluginJs from '@eslint/js'
import pluginImport from 'eslint-plugin-import'
Expand All @@ -10,6 +7,8 @@ import pluginReact from 'eslint-plugin-react'
import pluginReactHooks from 'eslint-plugin-react-hooks'
import pluginTailwind from 'eslint-plugin-tailwindcss'
import globals from 'globals'
import { dirname, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
import pluginTypescriptEslint from 'typescript-eslint'

import noDirectRrdNavImport from './eslint-rules/no-direct-rrd-nav-import.js'
Expand Down Expand Up @@ -106,22 +105,15 @@ export default [
'no-unneeded-ternary': 'warn',
'no-duplicate-imports': 'error',

// Prevent barrel imports from large libraries (impacts bundle size and dev performance)
'no-restricted-imports': [
'no-restricted-syntax': [
'error',
{
paths: [
{
name: '@mui/material',
message:
'Import from @mui/material/* instead. E.g., import Button from "@mui/material/Button"',
},
],
selector:
":matches(ImportDeclaration, ExportNamedDeclaration, ExportAllDeclaration)[source.value='@mui/material']",
message:
'Import from @mui/material/* instead. E.g., import Button from "@mui/material/Button"',
},
],
// Enforce slug-aware navigation wrappers (custom rule — error level,
// kept separate from `no-restricted-imports` which is also used below
// at `warn` severity for formik/dialog deprecations).
'lago/no-direct-rrd-nav-import': 'error',

// Plugins
Expand Down
46 changes: 46 additions & 0 deletions packages/configs/eslint.config.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { ESLint } from 'eslint'
import assert from 'node:assert/strict'
import test from 'node:test'
import { fileURLToPath } from 'node:url'

const eslint = new ESLint({ cwd: fileURLToPath(new URL('../../', import.meta.url)) })
const restrictionRules = new Set([
'no-restricted-imports',
'no-restricted-syntax',
'lago/no-direct-rrd-nav-import',
])

const cases = [
['MUI named imports', "import { Button } from '@mui/material'", 2],
['MUI namespace imports', "import * as Material from '@mui/material'", 2],
['MUI named re-exports', "export { Button } from '@mui/material'", 2],
['MUI star re-exports', "export * from '@mui/material'", 2],
['direct MUI imports', "import Button from '@mui/material/Button'", undefined],
['Formik imports', "import { useFormik } from 'formik'", 1],
[
'legacy dialog imports',
"import { AddCustomerDialog } from '~/components/customers/AddCustomerDialog'",
1,
],
[
'migrated dialog hooks',
"import { useAddCustomerDialog } from '~/components/customers/AddCustomerDialog'",
undefined,
],
['direct router navigation', "import { useNavigate } from 'react-router-dom'", 2],
['slug-aware router navigation', "import { useNavigate } from '~/core/router'", undefined],
]

for (const [name, source, severity] of cases) {
test(`effective import policy: ${name}`, async () => {
const [result] = await eslint.lintText(`${source}\n`, {
filePath: 'src/import-policy-probe.tsx',
})
const restrictions = result.messages.filter(({ ruleId }) => restrictionRules.has(ruleId))

assert.deepEqual(
restrictions.map((message) => message.severity),
severity === undefined ? [] : [severity],
)
})
}
5 changes: 4 additions & 1 deletion packages/design-system/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import path from 'path'
import { defineConfig } from 'vite'
import svgr from 'vite-plugin-svgr'

const peers = ['react', 'react-dom', '@mui/material', '@mui/x-date-pickers']

/**
* Vite configuration for building a React component library
*/
Expand Down Expand Up @@ -43,7 +45,8 @@ export default defineConfig({
'@mui/x-date-pickers': 'MaterialUIXDatePickers',
},
},
external: ['react', 'react-dom', '@mui/material', '@mui/x-date-pickers'],
external: (id: string): boolean =>
peers.some((peer) => id === peer || id.startsWith(`${peer}/`)),
},
cssCodeSplit: false,
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { gql } from '@apollo/client'
import { InputAdornment } from '@mui/material'
import InputAdornment from '@mui/material/InputAdornment'
import { useCallback, useMemo } from 'react'
import { generatePath, useParams } from 'react-router-dom'

Expand Down
Loading