From ae02169e975448e0c31779dee9f6096bd3330348 Mon Sep 17 00:00:00 2001 From: ephraimduncan Date: Thu, 5 Mar 2026 19:09:19 +0000 Subject: [PATCH] chore: migrate linting and formatting to oxlint and oxfmt --- .eslintignore | 8 - .eslintrc.cjs | 16 - .oxfmtrc.json | 33 + .oxlintrc.json | 50 + .prettierignore | 20 - apps/docs/src/app/og/docs/[...slug]/route.tsx | 164 +- apps/openpage-api/package.json | 2 +- .../dialogs/account-delete-dialog.tsx | 2 +- .../dialogs/assistant-confirmation-dialog.tsx | 2 +- .../document-move-to-folder-dialog.tsx | 4 +- .../dialogs/document-resend-dialog.tsx | 2 +- .../dialogs/envelope-download-dialog.tsx | 12 +- .../dialogs/folder-delete-dialog.tsx | 2 +- .../components/dialogs/folder-move-dialog.tsx | 2 +- .../dialogs/organisation-create-dialog.tsx | 18 +- .../organisation-email-create-dialog.tsx | 4 +- ...rganisation-email-domain-delete-dialog.tsx | 2 +- .../organisation-group-create-dialog.tsx | 4 +- .../organisation-member-invite-dialog.tsx | 8 +- .../public-profile-template-manage-dialog.tsx | 6 +- .../dialogs/team-email-delete-dialog.tsx | 2 +- .../dialogs/team-group-create-dialog.tsx | 2 +- .../template-move-to-folder-dialog.tsx | 4 +- .../dialogs/token-delete-dialog.tsx | 2 +- .../dialogs/webhook-delete-dialog.tsx | 2 +- .../dialogs/webhook-test-dialog.tsx | 2 +- .../configure-document-advanced-settings.tsx | 12 +- .../configure-document-recipients.tsx | 8 +- .../authoring/configure-document-upload.tsx | 10 +- .../authoring/configure-document-view.tsx | 4 +- .../components/embed/embed-client-loading.tsx | 2 +- .../embed/embed-document-completed.tsx | 4 +- .../embed/embed-document-rejected.tsx | 8 +- .../embed/embed-document-waiting-for-turn.tsx | 6 +- .../multisign/multi-sign-document-list.tsx | 20 +- .../2fa/enable-authenticator-app-dialog.tsx | 6 +- .../forms/2fa/recovery-code-list.tsx | 2 +- .../app/components/forms/avatar-image.tsx | 2 +- .../forms/branding-preferences-form.tsx | 12 +- .../editor/editor-field-checkbox-form.tsx | 8 +- .../editor/editor-field-dropdown-form.tsx | 2 +- .../editor-field-generic-field-forms.tsx | 4 +- .../forms/editor/editor-field-number-form.tsx | 2 +- .../forms/editor/editor-field-radio-form.tsx | 4 +- .../editor/editor-field-signature-form.tsx | 2 +- .../forms/organisation-update-form.tsx | 2 +- .../components/forms/public-profile-form.tsx | 6 +- .../forms/search-param-selector.tsx | 2 +- apps/remix/app/components/forms/signup.tsx | 28 +- .../app/components/forms/team-update-form.tsx | 2 +- .../admin-monthly-active-user-charts.tsx | 2 +- .../admin-stats-signer-conversion-chart.tsx | 2 +- .../admin-stats-users-with-documents.tsx | 2 +- .../app/components/general/app-header.tsx | 12 +- .../components/general/app-nav-desktop.tsx | 6 +- .../app/components/general/app-nav-mobile.tsx | 8 +- .../direct-template-signing-auth-page.tsx | 2 +- .../document-signing/access-auth-2fa-form.tsx | 10 +- .../document-signing-attachments-popover.tsx | 8 +- .../document-signing-auth-dialog.tsx | 4 +- .../document-signing-auth-page.tsx | 2 +- .../document-signing-auth-provider.tsx | 6 +- .../document-signing-auto-sign.tsx | 2 +- .../document-signing-checkbox-field.tsx | 8 +- .../document-signing-date-field.tsx | 8 +- .../document-signing-disclosure.tsx | 2 +- .../document-signing-dropdown-field.tsx | 10 +- .../document-signing-field-container.tsx | 4 +- .../document-signing-fields.tsx | 8 +- .../document-signing-radio-field.tsx | 4 +- .../document-signing-text-field.tsx | 2 +- .../document/document-attachments-popover.tsx | 6 +- .../document/document-page-view-dropdown.tsx | 2 +- .../document-page-view-information.tsx | 2 +- .../document-recipient-link-copy-dialog.tsx | 6 +- .../envelope-editor-fields-drag-drop.tsx | 6 +- .../envelope-editor-title-input.tsx | 2 +- .../components/general/folder/folder-card.tsx | 16 +- .../general/generic-error-layout.tsx | 4 +- .../general/legacy-field-warning-popover.tsx | 2 +- .../app/components/general/menu-switcher.tsx | 14 +- .../components/general/org-menu-switcher.tsx | 36 +- .../organisation-invitations.tsx | 2 +- .../components/general/period-selector.tsx | 2 +- .../components/general/settings-header.tsx | 2 +- .../app/components/general/stack-avatar.tsx | 2 +- .../general/teams/team-email-dropdown.tsx | 2 +- .../template-page-view-documents-table.tsx | 4 +- .../template-page-view-information.tsx | 2 +- .../template-page-view-recent-activity.tsx | 30 +- .../template-page-view-recipients.tsx | 12 +- .../general/user-profile-skeleton.tsx | 26 +- .../components/general/user-profile-timur.tsx | 22 +- .../components/general/webhook-logs-sheet.tsx | 30 +- .../documents-table-action-dropdown.tsx | 2 +- .../tables/documents-table-empty-state.tsx | 2 +- .../tables/documents-table-sender-filter.tsx | 2 +- .../app/components/tables/inbox-table.tsx | 6 +- .../organisation-billing-invoices-table.tsx | 2 +- .../tables/organisation-insights-table.tsx | 8 +- .../organisation-member-invites-table.tsx | 4 +- .../tables/organisation-members-table.tsx | 4 +- .../tables/organisation-teams-table.tsx | 2 +- ...ettings-public-profile-templates-table.tsx | 20 +- .../components/tables/team-groups-table.tsx | 4 +- .../components/tables/team-members-table.tsx | 4 +- .../templates-table-action-dropdown.tsx | 6 +- .../user-billing-organisations-table.tsx | 4 +- .../tables/user-organisations-table.tsx | 2 +- .../admin+/documents._index.tsx | 10 +- .../_authenticated+/admin+/site-settings.tsx | 2 +- .../app/routes/_authenticated+/dashboard.tsx | 24 +- .../app/routes/_authenticated+/inbox.tsx | 4 +- .../o.$orgUrl.settings.billing.tsx | 4 +- .../o.$orgUrl.settings.email-domains.$id.tsx | 2 +- .../o.$orgUrl.settings.groups.$id.tsx | 2 +- .../o.$orgUrl.settings.sso.tsx | 12 +- .../_authenticated+/o.$orgUrl.support.tsx | 16 +- .../settings+/security._index.tsx | 2 +- .../t.$teamUrl+/documents.$id.edit.tsx | 4 +- .../t.$teamUrl+/documents.folders._index.tsx | 6 +- .../t.$teamUrl+/settings._index.tsx | 8 +- .../t.$teamUrl+/settings.branding.tsx | 2 +- .../t.$teamUrl+/settings.public-profile.tsx | 4 +- .../t.$teamUrl+/settings.tokens.tsx | 10 +- .../settings.webhooks.$id._index.tsx | 12 +- .../t.$teamUrl+/settings.webhooks._index.tsx | 8 +- .../t.$teamUrl+/templates.folders._index.tsx | 6 +- apps/remix/app/routes/_profile+/_layout.tsx | 6 +- apps/remix/app/routes/_profile+/p.$url.tsx | 18 +- .../routes/_recipient+/d.$token+/_index.tsx | 2 +- .../routes/_unauthenticated+/check-email.tsx | 2 +- .../_unauthenticated+/forgot-password.tsx | 4 +- .../_unauthenticated+/o.$orgUrl.signin.tsx | 20 +- .../organisation.decline.$token.tsx | 4 +- .../organisation.invite.$token.tsx | 8 +- .../reset-password.$token.tsx | 4 +- .../reset-password._index.tsx | 2 +- .../app/routes/_unauthenticated+/signin.tsx | 6 +- .../team.verify.email.$token.tsx | 8 +- .../_unauthenticated+/unverified-account.tsx | 6 +- .../_unauthenticated+/verify-email.$token.tsx | 12 +- .../_unauthenticated+/verify-email._index.tsx | 4 +- .../v1+/authoring_.completed.create.tsx | 4 +- .../routes/embed+/v1+/multisign+/_index.tsx | 4 +- benchmarks/lint-format-migration.md | 35 + lint-staged.config.cjs | 15 +- package-lock.json | 20052 +++++----------- package.json | 8 +- packages/api/package.json | 4 +- .../autosave-subject-step.spec.ts | 32 +- packages/auth/package.json | 4 +- .../template-confirmation-email.tsx | 4 +- .../template-document-cancel.tsx | 2 +- .../template-document-completed.tsx | 2 +- .../template-document-invite.tsx | 4 +- .../template-document-pending.tsx | 2 +- .../template-document-recipient-signed.tsx | 2 +- .../template-document-rejected.tsx | 2 +- .../template-document-rejection-confirmed.tsx | 2 +- .../template-document-self-signed.tsx | 4 +- .../template-document-super-delete.tsx | 2 +- .../template-forgot-password.tsx | 4 +- .../template-reset-password.tsx | 4 +- .../email/templates/bulk-send-complete.tsx | 2 +- .../document-created-from-direct-template.tsx | 4 +- ...organisation-account-link-confirmation.tsx | 2 +- .../email/templates/organisation-invite.tsx | 2 +- .../recipient-removed-from-document.tsx | 2 +- packages/eslint-config/index.cjs | 82 - packages/eslint-config/package.json | 20 - packages/eslint-config/tsconfig.json | 9 - packages/lib/constants/auth.ts | 4 +- packages/lib/package.json | 4 +- packages/prettier-config/index.cjs | 42 - packages/prettier-config/package.json | 15 - packages/trpc/package.json | 4 +- .../document-global-auth-access-select.tsx | 2 +- .../document-global-auth-action-select.tsx | 2 +- .../document/document-read-only-fields.tsx | 2 +- .../document-send-email-message-helper.tsx | 8 +- .../document/document-share-button.tsx | 5 +- .../document-signature-settings-tooltip.tsx | 2 +- .../document/document-visibility-select.tsx | 2 +- .../envelope-recipient-field-tooltip.tsx | 2 +- .../recipient-action-auth-select.tsx | 2 +- .../recipient/recipient-role-select.tsx | 12 +- packages/ui/components/signing-card.tsx | 8 +- packages/ui/package.json | 4 +- packages/ui/primitives/accordion.tsx | 2 +- packages/ui/primitives/alert-dialog.tsx | 6 +- packages/ui/primitives/alert.tsx | 12 +- packages/ui/primitives/avatar.tsx | 8 +- packages/ui/primitives/badge.tsx | 5 +- packages/ui/primitives/button.tsx | 13 +- packages/ui/primitives/card.tsx | 7 +- packages/ui/primitives/checkbox.tsx | 4 +- packages/ui/primitives/color-picker.tsx | 2 +- packages/ui/primitives/command.tsx | 14 +- packages/ui/primitives/context-menu.tsx | 18 +- packages/ui/primitives/document-dropzone.tsx | 50 +- .../primitives/document-flow/add-settings.tsx | 12 +- .../checkbox-field.tsx | 14 +- .../date-field.tsx | 4 +- .../dropdown-field.tsx | 6 +- .../email-field.tsx | 4 +- .../initials-field.tsx | 4 +- .../name-field.tsx | 4 +- .../number-field.tsx | 18 +- .../radio-field.tsx | 8 +- .../text-field.tsx | 12 +- .../send-document-action-dialog.tsx | 4 +- .../ui/primitives/document-upload-button.tsx | 2 +- packages/ui/primitives/dropdown-menu.tsx | 14 +- packages/ui/primitives/field-selector.tsx | 6 +- packages/ui/primitives/form/form.tsx | 2 +- packages/ui/primitives/hover-card.tsx | 2 +- packages/ui/primitives/input.tsx | 2 +- packages/ui/primitives/label.tsx | 2 +- packages/ui/primitives/menubar.tsx | 20 +- .../ui/primitives/multi-select-combobox.tsx | 2 +- packages/ui/primitives/multiselect.tsx | 12 +- packages/ui/primitives/navigation-menu.tsx | 10 +- packages/ui/primitives/password-input.tsx | 4 +- packages/ui/primitives/pin-input.tsx | 6 +- packages/ui/primitives/popover.tsx | 2 +- packages/ui/primitives/progress.tsx | 4 +- packages/ui/primitives/radio-group.tsx | 4 +- packages/ui/primitives/recipient-selector.tsx | 12 +- packages/ui/primitives/scroll-area.tsx | 2 +- packages/ui/primitives/select.tsx | 8 +- packages/ui/primitives/separator.tsx | 2 +- packages/ui/primitives/sheet.tsx | 16 +- .../signature-pad-color-picker.tsx | 18 +- .../signature-pad/signature-pad-upload.tsx | 2 +- .../signature-pad/signature-tabs.tsx | 6 +- packages/ui/primitives/skeleton.tsx | 2 +- packages/ui/primitives/slider.tsx | 6 +- packages/ui/primitives/spinner.tsx | 2 +- packages/ui/primitives/switch.tsx | 4 +- packages/ui/primitives/table.tsx | 8 +- packages/ui/primitives/tabs.tsx | 6 +- .../add-template-placeholder-recipients.tsx | 14 +- packages/ui/primitives/textarea.tsx | 2 +- packages/ui/primitives/theme-switcher.tsx | 14 +- packages/ui/primitives/toast.tsx | 10 +- packages/ui/primitives/toggle.tsx | 4 +- packages/ui/primitives/tooltip.tsx | 2 +- prettier.config.cjs | 1 - tsconfig.eslint.json | 4 - 250 files changed, 7228 insertions(+), 14870 deletions(-) delete mode 100644 .eslintignore delete mode 100644 .eslintrc.cjs create mode 100644 .oxfmtrc.json create mode 100644 .oxlintrc.json delete mode 100644 .prettierignore create mode 100644 benchmarks/lint-format-migration.md delete mode 100644 packages/eslint-config/index.cjs delete mode 100644 packages/eslint-config/package.json delete mode 100644 packages/eslint-config/tsconfig.json delete mode 100644 packages/prettier-config/index.cjs delete mode 100644 packages/prettier-config/package.json delete mode 100644 prettier.config.cjs delete mode 100644 tsconfig.eslint.json diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index b7f7e638f..000000000 --- a/.eslintignore +++ /dev/null @@ -1,8 +0,0 @@ -# Config files -*.config.js -*.config.cjs - -# Statically hosted javascript files -apps/*/public/*.js -apps/*/public/*.cjs -scripts/ diff --git a/.eslintrc.cjs b/.eslintrc.cjs deleted file mode 100644 index 455860ea1..000000000 --- a/.eslintrc.cjs +++ /dev/null @@ -1,16 +0,0 @@ -/** @type {import('eslint').Linter.Config} */ -module.exports = { - root: true, - extends: ['@documenso/eslint-config'], - rules: { - '@next/next/no-img-element': 'off', - 'no-unreachable': 'error', - 'react-hooks/exhaustive-deps': 'off', - }, - settings: { - next: { - rootDir: ['apps/*/'], - }, - }, - ignorePatterns: ['lingui.config.ts', 'packages/lib/translations/**/*.js'], -}; diff --git a/.oxfmtrc.json b/.oxfmtrc.json new file mode 100644 index 000000000..7261c287a --- /dev/null +++ b/.oxfmtrc.json @@ -0,0 +1,33 @@ +{ + "$schema": "./node_modules/oxfmt/configuration_schema.json", + "printWidth": 100, + "tabWidth": 2, + "semi": true, + "singleQuote": true, + "trailingComma": "all", + "arrowParens": "always", + "importOrder": [ + "^server-only|client-only$", + "^react$", + "^next(/.*)?$", + "", + "^@documenso/(.*)$", + "^~/(.*)$", + "^[./]" + ], + "importOrderSeparation": true, + "importOrderSortSpecifiers": true, + "sortTailwindcss": { + "functions": ["cn", "cva"] + }, + "sortPackageJson": false, + "ignorePatterns": [ + "packages/lib/translations/**/*.js", + "*.test.ts", + "apps/docs/content/**/*.mdx", + "*.css", + "*.po", + "*.md", + "*.json" + ] +} diff --git a/.oxlintrc.json b/.oxlintrc.json new file mode 100644 index 000000000..8fffddfcb --- /dev/null +++ b/.oxlintrc.json @@ -0,0 +1,50 @@ +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "plugins": ["typescript", "import", "react", "nextjs", "promise"], + "env": { "browser": true, "node": true, "es2022": true }, + "categories": { "correctness": "error" }, + "rules": { + "eslint/no-unused-vars": [ + "warn", + { + "vars": "all", + "varsIgnorePattern": "^_", + "args": "after-used", + "argsIgnorePattern": "^_", + "destructuredArrayIgnorePattern": "^_" + } + ], + + "eslint/no-promise-executor-return": "error", + "eslint/prefer-promise-reject-errors": "error", + "eslint/no-unreachable": "error", + + "typescript/no-floating-promises": "error", + "typescript/no-misused-promises": ["error", { "checksVoidReturn": { "attributes": false } }], + "typescript/promise-function-async": "error", + "typescript/require-await": "error", + "typescript/consistent-type-assertions": ["warn", { "assertionStyle": "never" }], + "typescript/consistent-type-imports": [ + "warn", + { + "prefer": "type-imports", + "fixStyle": "separate-type-imports", + "disallowTypeAnnotations": false + } + ], + + "react/no-unescaped-entities": "off", + "react/exhaustive-deps": "off", + "nextjs/no-html-link-for-pages": "off", + "nextjs/no-img-element": "off" + }, + "ignorePatterns": [ + "*.config.js", + "*.config.cjs", + "apps/*/public/*.js", + "apps/*/public/*.cjs", + "scripts/", + "lingui.config.ts", + "packages/lib/translations/**/*.js" + ] +} diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index f5c70c1d5..000000000 --- a/.prettierignore +++ /dev/null @@ -1,20 +0,0 @@ -node_modules -.next -public -**/**/node_modules -**/**/.next -**/**/public -packages/lib/translations/**/*.js - -*.lock -*.log -*.test.ts - -.gitignore -.npmignore -.prettierignore -.DS_Store -.eslintignore - -# Docs MDX - Prettier strips indentation from code blocks inside components -apps/docs/content/**/*.mdx diff --git a/apps/docs/src/app/og/docs/[...slug]/route.tsx b/apps/docs/src/app/og/docs/[...slug]/route.tsx index 1a7153f47..8dd602453 100644 --- a/apps/docs/src/app/og/docs/[...slug]/route.tsx +++ b/apps/docs/src/app/og/docs/[...slug]/route.tsx @@ -40,104 +40,102 @@ export async function GET(_req: Request, { params }: RouteContext<'/og/docs/[... const { logoSrc, fonts } = await loadAssets(); return new ImageResponse( - ( +
+ {/* Green accent bar */} +
+ + {/* Top: Logo */} +
+ {/* eslint-disable-next-line @next/next/no-img-element */} + Documenso + + | + + Docs +
+ + {/* Middle: Title + description */}
- {/* Green accent bar */} -
- - {/* Top: Logo */} -
40 ? '48px' : '56px', + fontWeight: 700, + lineHeight: 1.15, + letterSpacing: '-0.025em', + margin: 0, }} > - {/* eslint-disable-next-line @next/next/no-img-element */} - Documenso - + {page.data.description && ( +

- | - - Docs -

- - {/* Middle: Title + description */} -
-

40 ? '48px' : '56px', - fontWeight: 700, - lineHeight: 1.15, - letterSpacing: '-0.025em', + lineHeight: 1.4, margin: 0, + maxWidth: '900px', + overflow: 'hidden', + textOverflow: 'ellipsis', + display: '-webkit-box', + WebkitLineClamp: 2, + WebkitBoxOrient: 'vertical', }} > - {page.data.title} -

- {page.data.description && ( -

- {page.data.description} -

- )} -
- - {/* Bottom: URL */} -
- - docs.documenso.com{page.url} - -
+ {page.data.description} +

+ )}
- ), + + {/* Bottom: URL */} +
+ + docs.documenso.com{page.url} + +
+
, { width: 1200, height: 630, diff --git a/apps/openpage-api/package.json b/apps/openpage-api/package.json index 8657dca8d..0a82e1fff 100644 --- a/apps/openpage-api/package.json +++ b/apps/openpage-api/package.json @@ -6,7 +6,7 @@ "dev": "next dev -p 3003", "build": "next build", "start": "next start -p 3003", - "lint:fix": "next lint --fix", + "lint:fix": "oxlint --type-aware --fix .", "clean": "rimraf .next && rimraf node_modules" }, "dependencies": { diff --git a/apps/remix/app/components/dialogs/account-delete-dialog.tsx b/apps/remix/app/components/dialogs/account-delete-dialog.tsx index 5c528dfc4..2302cf626 100644 --- a/apps/remix/app/components/dialogs/account-delete-dialog.tsx +++ b/apps/remix/app/components/dialogs/account-delete-dialog.tsx @@ -122,7 +122,7 @@ export const AccountDeleteDialog = ({ className }: AccountDeleteDialogProps) => diff --git a/apps/remix/app/components/dialogs/assistant-confirmation-dialog.tsx b/apps/remix/app/components/dialogs/assistant-confirmation-dialog.tsx index 16e9a5719..f148633e9 100644 --- a/apps/remix/app/components/dialogs/assistant-confirmation-dialog.tsx +++ b/apps/remix/app/components/dialogs/assistant-confirmation-dialog.tsx @@ -115,7 +115,7 @@ export function AssistantConfirmationDialog({
{!isEditingNextSigner && (
-

+

The next recipient to sign this document will be{' '} {form.watch('name')} ( diff --git a/apps/remix/app/components/dialogs/document-move-to-folder-dialog.tsx b/apps/remix/app/components/dialogs/document-move-to-folder-dialog.tsx index 45ec1465a..06c5f60c2 100644 --- a/apps/remix/app/components/dialogs/document-move-to-folder-dialog.tsx +++ b/apps/remix/app/components/dialogs/document-move-to-folder-dialog.tsx @@ -165,7 +165,7 @@ export const DocumentMoveToFolderDialog = ({

- + +
No folders found
)} diff --git a/apps/remix/app/components/dialogs/document-resend-dialog.tsx b/apps/remix/app/components/dialogs/document-resend-dialog.tsx index d8c0a73ee..1bfb6cb88 100644 --- a/apps/remix/app/components/dialogs/document-resend-dialog.tsx +++ b/apps/remix/app/components/dialogs/document-resend-dialog.tsx @@ -183,7 +183,7 @@ export const DocumentResendDialog = ({ document, recipients }: DocumentResendDia