Skip to content
Merged
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
381 changes: 380 additions & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,20 @@ export default tseslint.config(
tseslint.configs.recommended,
{
rules: {
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/no-explicit-any': 'error',
// Our own values get real types; a file parsing outside input says so at the top (GRYT-1792).
'@typescript-eslint/no-restricted-types': ['error', { types: { unknown: "Type it. If it's outside input being checked, disable at the top of the file with the reason." } }],
'no-restricted-syntax': ['error', {
selector: "TSAsExpression > TSAsExpression.expression[typeAnnotation.type='TSUnknownKeyword']",
message: "Don't cast through unknown. Fix the types, or disable this line with the reason.",
}],
'no-nested-ternary': 'error',
eqeqeq: ['error', 'smart'],
'no-else-return': 'error',
'prefer-const': 'error',
'no-param-reassign': 'error',
'@typescript-eslint/no-non-null-assertion': 'error',
'@typescript-eslint/consistent-type-imports': ['error', { fixStyle: 'inline-type-imports', disallowTypeAnnotations: false }],
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
'@typescript-eslint/no-namespace': 'warn',
},
Expand All @@ -29,4 +42,370 @@ export default tseslint.config(
'@typescript-eslint/no-require-imports': 'off',
},
},
// Existing debt, listed per rule rather than marked in each file. The goal is to empty these (GRYT-1792).
// unknown: socket payloads arrive unchecked and are validated there.
{
files: [
'src/plugins/guard.ts',
'src/plugins/messaging.ts',
'src/routes/emojiBttvImport.ts',
'src/routes/uploads.ts',
'src/routes/webhookOpenapi.ts',
'src/routes/webhookSchemas.ts',
'src/services/webhookMedia.ts',
'src/socket/handlers/admin.ts',
'src/socket/handlers/calls.ts',
'src/socket/handlers/chat.ts',
'src/socket/handlers/contactPrefs.ts',
'src/socket/handlers/friends.ts',
'src/socket/handlers/join.ts',
'src/socket/handlers/mls.ts',
'src/socket/handlers/mlsPersonKey.ts',
'src/socket/handlers/plugins.ts',
'src/socket/handlers/push.ts',
'src/socket/handlers/reports.ts',
'src/socket/index.ts',
'src/socket/utils/server.ts',
'src/utils/fileUrl.ts',
],
rules: { '@typescript-eslint/no-restricted-types': 'off' },
},
// unknown: requests and responses arrive unchecked.
{
files: [
'src/routes/discordImport.ts',
'src/routes/emojiStaging.ts',
'src/routes/emojis.ts',
'src/routes/linkPreview.ts',
'src/routes/oembed.ts',
'src/services/workerCapabilities.ts',
'src/utils/httpErrors.ts',
'src/utils/safePreviewFetch.ts',
'src/versionCheck.ts',
],
rules: { '@typescript-eslint/no-restricted-types': 'off' },
},
// unknown: stored and parsed data arrives unchecked and is validated there.
{
files: [
'src/import/discord/exportFolder.ts',
'src/import/discord/importer.ts',
'src/plugins/host.ts',
'src/services/storeUploadedFile.ts',
'src/utils/memberCard.ts',
],
rules: { '@typescript-eslint/no-restricted-types': 'off' },
},
// unknown: caught errors are unknown until checked.
{
files: [
'src/admin/setOwner.ts',
'src/moderation/deleteMessage.ts',
'src/socket/handlers/members.ts',
],
rules: { '@typescript-eslint/no-restricted-types': 'off' },
},
// unknown: tests build loose payloads on purpose.
{
files: [
'src/plugins/host.test.ts',
'src/plugins/manifest.test.ts',
'src/plugins/messaging.test.ts',
'src/plugins/roundTrip.test.ts',
'src/routes/bannerUpload.test.ts',
'src/routes/discordImport.test.ts',
'src/routes/fileRead.test.ts',
'src/routes/groupIconUpload.test.ts',
'src/routes/routeJsonLimits.test.ts',
'src/routes/uploadAuthOrder.test.ts',
'src/routes/uploadQuarantine.test.ts',
'src/routes/webhookAvatar.test.ts',
'src/routes/webhookBodyErrors.test.ts',
'src/routes/webhookCards.test.ts',
'src/routes/webhookSchemas.test.ts',
'src/routes/webhookUrl.test.ts',
'src/services/mentionSyntax.test.ts',
'src/services/push.test.ts',
'src/services/pushPreview.test.ts',
'src/settings/externalEmojis.test.ts',
'src/socket/handlers/automatedChannels.test.ts',
'src/socket/handlers/blocks.test.ts',
'src/socket/handlers/callRinging.test.ts',
'src/socket/handlers/channelNotificationDefaults.test.ts',
'src/socket/handlers/channelPermissionRules.test.ts',
'src/socket/handlers/channelReactions.test.ts',
'src/socket/handlers/channelSidebarRow.test.ts',
'src/socket/handlers/channelVisibilityLeaks.test.ts',
'src/socket/handlers/chatErrorNonce.test.ts',
'src/socket/handlers/chatSearch.test.ts',
'src/socket/handlers/clientRecordLeaks.test.ts',
'src/socket/handlers/contactPrefs.test.ts',
'src/socket/handlers/conversationRefusalEvent.test.ts',
'src/socket/handlers/directMessages.test.ts',
'src/socket/handlers/dmKeys.test.ts',
'src/socket/handlers/folderPermissions.test.ts',
'src/socket/handlers/forgetIdentityLeavesVoice.test.ts',
'src/socket/handlers/forumTags.test.ts',
'src/socket/handlers/forumTopics.test.ts',
'src/socket/handlers/friends.test.ts',
'src/socket/handlers/identityReplace.test.ts',
'src/socket/handlers/leaveServer.test.ts',
'src/socket/handlers/liveMessageRecipients.test.ts',
'src/socket/handlers/massMentions.test.ts',
'src/socket/handlers/memberCard.test.ts',
'src/socket/handlers/memberInvites.test.ts',
'src/socket/handlers/mls.test.ts',
'src/socket/handlers/mlsPersonKey.test.ts',
'src/socket/handlers/mlsReports.test.ts',
'src/socket/handlers/ownerRoleColour.test.ts',
'src/socket/handlers/permissionGates.test.ts',
'src/socket/handlers/pluginMessages.test.ts',
'src/socket/handlers/polls.test.ts',
'src/socket/handlers/presenceRateLimit.test.ts',
'src/socket/handlers/presenceRichActivity.test.ts',
'src/socket/handlers/pushAudience.test.ts',
'src/socket/handlers/scopeTemplates.test.ts',
'src/socket/handlers/sendAcrossRestart.test.ts',
'src/socket/handlers/sessions.test.ts',
'src/socket/handlers/sidebarFolders.test.ts',
'src/socket/handlers/spamFilter.test.ts',
'src/socket/handlers/textMute.test.ts',
'src/socket/handlers/threadStatus.test.ts',
'src/socket/handlers/threadSummaryShape.test.ts',
'src/socket/handlers/tokenRefresh.test.ts',
'src/socket/handlers/typing.test.ts',
'src/socket/handlers/userReports.test.ts',
'src/socket/handlers/voiceChannelSwitch.test.ts',
'src/socket/handlers/voiceJoinAnnounce.test.ts',
'src/socket/handlers/voiceRoomAccess.test.ts',
'src/socket/handlers/voiceSpeakCapability.test.ts',
'src/socket/utils/callParticipants.test.ts',
'src/socket/utils/channelPermissionsPayload.test.ts',
'src/socket/utils/clientNotices.test.ts',
'src/socket/utils/emitToMember.test.ts',
'src/socket/utils/publicClientList.test.ts',
'src/socket/utils/serverDetailsBootstrap.test.ts',
'src/socket/utils/serverInfo.test.ts',
'src/socket/utils/voiceCapabilities.test.ts',
'src/socket/voiceRecovery.test.ts',
'src/utils/linkResolvers.test.ts',
'src/utils/memberCard.test.ts',
'src/utils/richActivity.test.ts',
],
rules: { '@typescript-eslint/no-restricted-types': 'off' },
},
// unknown: not typed yet.
{
files: [
'src/config/cors.ts',
'src/constants/permissions.ts',
'src/import/discord/dce.ts',
'src/moderation/spamFilter.ts',
'src/plugins/manifest.ts',
'src/polls/poll.ts',
'src/routes/uploadStorage.ts',
'src/services/mlsWire.ts',
'src/services/quarantineUpload.ts',
'src/utils/activityText.ts',
'src/utils/linkResolvers.ts',
'src/utils/profanityFilter.ts',
'src/utils/publicOnlyAgent.ts',
'src/utils/richActivity.ts',
'src/utils/wornString.ts',
],
rules: { '@typescript-eslint/no-restricted-types': 'off' },
},
// Casts through unknown where the types don't line up yet.
{
files: [
'src/plugins/roundTrip.test.ts',
'src/routes/discordImport.test.ts',
'src/routes/fileRead.test.ts',
'src/services/push.test.ts',
'src/services/quarantineUpload.ts',
'src/settings/externalEmojis.test.ts',
'src/socket/handlers/automatedChannels.test.ts',
'src/socket/handlers/blocks.test.ts',
'src/socket/handlers/callRinging.test.ts',
'src/socket/handlers/channelPermissionRules.test.ts',
'src/socket/handlers/channelReactions.test.ts',
'src/socket/handlers/channelSidebarRow.test.ts',
'src/socket/handlers/channelVisibilityLeaks.test.ts',
'src/socket/handlers/chatErrorNonce.test.ts',
'src/socket/handlers/chatSearch.test.ts',
'src/socket/handlers/clientRecordLeaks.test.ts',
'src/socket/handlers/contactPrefs.test.ts',
'src/socket/handlers/conversationRefusalEvent.test.ts',
'src/socket/handlers/directMessages.test.ts',
'src/socket/handlers/dmKeys.test.ts',
'src/socket/handlers/folderPermissions.test.ts',
'src/socket/handlers/forgetIdentityLeavesVoice.test.ts',
'src/socket/handlers/forumTags.test.ts',
'src/socket/handlers/forumTopics.test.ts',
'src/socket/handlers/friends.test.ts',
'src/socket/handlers/identityReplace.test.ts',
'src/socket/handlers/leaveServer.test.ts',
'src/socket/handlers/liveMessageRecipients.test.ts',
'src/socket/handlers/massMentions.test.ts',
'src/socket/handlers/memberCard.test.ts',
'src/socket/handlers/memberInvites.test.ts',
'src/socket/handlers/mls.test.ts',
'src/socket/handlers/mlsPersonKey.test.ts',
'src/socket/handlers/mlsReports.test.ts',
'src/socket/handlers/ownerRoleColour.test.ts',
'src/socket/handlers/permissionGates.test.ts',
'src/socket/handlers/pluginMessages.test.ts',
'src/socket/handlers/polls.test.ts',
'src/socket/handlers/presenceRateLimit.test.ts',
'src/socket/handlers/presenceRichActivity.test.ts',
'src/socket/handlers/pushAudience.test.ts',
'src/socket/handlers/scopeTemplates.test.ts',
'src/socket/handlers/sendAcrossRestart.test.ts',
'src/socket/handlers/sessions.test.ts',
'src/socket/handlers/sidebarFolders.test.ts',
'src/socket/handlers/spamFilter.test.ts',
'src/socket/handlers/textMute.test.ts',
'src/socket/handlers/threadStatus.test.ts',
'src/socket/handlers/threadSummaryShape.test.ts',
'src/socket/handlers/tokenRefresh.test.ts',
'src/socket/handlers/typing.test.ts',
'src/socket/handlers/userReports.test.ts',
'src/socket/handlers/voiceChannelSwitch.test.ts',
'src/socket/handlers/voiceJoinAnnounce.test.ts',
'src/socket/handlers/voiceRoomAccess.test.ts',
'src/socket/handlers/voiceSpeakCapability.test.ts',
'src/socket/utils/callParticipants.test.ts',
'src/socket/utils/clientNotices.test.ts',
'src/socket/utils/emitToMember.test.ts',
'src/socket/utils/serverInfo.test.ts',
'src/socket/utils/voiceCapabilities.test.ts',
'src/utils/richActivity.test.ts',
'src/utils/safePreviewFetch.ts',
],
rules: { 'no-restricted-syntax': 'off' },
},
// Non-null assertions from before the rule.
{
files: [
'src/import/discord/exportFolder.ts',
'src/import/discord/importer.test.ts',
'src/import/discord/importer.ts',
'src/import/discord/media.test.ts',
'src/index.ts',
'src/routes/discordImport.ts',
'src/routes/routeJsonLimits.test.ts',
'src/routes/uploadQuarantine.test.ts',
'src/routes/uploads.ts',
'src/routes/webhookAvatar.test.ts',
'src/routes/webhookCards.test.ts',
'src/routes/webhookSchemas.test.ts',
'src/routes/webhooks.ts',
'src/services/inviteRoles.ts',
'src/services/webhookMedia.test.ts',
'src/services/webhookMedia.ts',
'src/socket/handlers/admin.ts',
'src/socket/handlers/channelNotificationDefaults.test.ts',
'src/socket/handlers/channelPermissionRules.test.ts',
'src/socket/handlers/channelReactions.test.ts',
'src/socket/handlers/channelVisibilityLeaks.test.ts',
'src/socket/handlers/clientRecordLeaks.test.ts',
'src/socket/handlers/folderPermissions.test.ts',
'src/socket/handlers/forgetIdentityLeavesVoice.test.ts',
'src/socket/handlers/liveMessageRecipients.test.ts',
'src/socket/handlers/massMentions.test.ts',
'src/socket/handlers/mls.test.ts',
'src/socket/handlers/mlsReports.test.ts',
'src/socket/handlers/scopeTemplates.test.ts',
'src/socket/handlers/sessions.test.ts',
'src/socket/handlers/spamFilter.test.ts',
'src/socket/utils/callParticipants.test.ts',
'src/socket/utils/standing.ts',
'src/socket/utils/voiceCapabilities.test.ts',
'src/socket/voiceRecovery.test.ts',
'src/utils/byteRange.ts',
'src/utils/linkResolvers.test.ts',
'src/utils/richActivity.test.ts',
],
rules: { '@typescript-eslint/no-non-null-assertion': 'off' },
},
// Nested ternaries from before the rule.
{
files: [
'src/import/discord/importer.ts',
'src/routes/emojiBttvImport.ts',
'src/routes/emojis.ts',
'src/routes/server.ts',
'src/routes/uploads.ts',
'src/services/avatarImage.ts',
'src/services/webhookMedia.ts',
'src/settings/serverSettings.ts',
'src/socket/handlers/admin.ts',
'src/socket/handlers/join.ts',
'src/socket/utils/clients.ts',
'src/utils/httpErrors.ts',
],
rules: { 'no-nested-ternary': 'off' },
},
// Type-only imports not marked yet; a mechanical PR of its own fixes them.
{
files: [
'src/socket/handlers/admin.ts',
'src/socket/handlers/adminChannels.ts',
'src/socket/handlers/blocks.ts',
'src/socket/handlers/calls.ts',
'src/socket/handlers/chat.ts',
'src/socket/handlers/contactPrefs.ts',
'src/socket/handlers/dm.ts',
'src/socket/handlers/dmKeys.ts',
'src/socket/handlers/join.ts',
'src/socket/handlers/members.ts',
'src/socket/handlers/mentions.ts',
'src/socket/handlers/push.ts',
'src/socket/handlers/reports.ts',
'src/socket/handlers/types.ts',
'src/socket/handlers/typing.ts',
'src/socket/handlers/voice.ts',
'src/socket/index.ts',
'src/socket/middleware/auth.ts',
'src/socket/utils/channels.ts',
'src/socket/utils/clientNotices.ts',
'src/socket/utils/clients.ts',
'src/socket/utils/outdatedClient.ts',
'src/socket/utils/server.ts',
'src/socket/utils/systemMessages.ts',
],
rules: { '@typescript-eslint/consistent-type-imports': 'off' },
},
// Reassigned parameters from before the rule.
{
files: [
'src/socket/handlers/mls.ts',
'src/socket/handlers/mlsPersonKey.ts',
'src/socket/handlers/push.ts',
],
rules: { 'no-param-reassign': 'off' },
},
// any from before the rule.
{
files: [
'src/socket/utils/clientNotices.test.ts',
],
rules: { '@typescript-eslint/no-explicit-any': 'off' },
},
// Review-required paths are not edited from here. Their debt is exempted until a reviewed PR fixes it.
{
files: ['src/auth/**', 'src/middleware/**', 'src/db/**', 'src/storage/**'],
rules: {
'@typescript-eslint/no-restricted-types': 'off',
'no-restricted-syntax': 'off',
'no-nested-ternary': 'off',
eqeqeq: 'off',
'no-else-return': 'off',
'prefer-const': 'off',
'no-param-reassign': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/consistent-type-imports': 'off',
'@typescript-eslint/no-explicit-any': 'warn',
},
},
);
Loading