diff --git a/.eslintrc b/.eslintrc index a8bdb516600..46805bc5b65 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,23 +1,104 @@ { - "extends": ["@rocket.chat/eslint-config"], - "parser": "babel-eslint", - "globals": { - "__meteor_bootstrap__" : false, - "__meteor_runtime_config__" : false, - "Assets" : false, - "chrome" : false + "extends": [ + "@rocket.chat/eslint-config" + ], + "parser": "babel-eslint", + "globals": { + "__meteor_bootstrap__": false, + "__meteor_runtime_config__": false, + "Assets": false, + "chrome": false, + "jscolor": false }, - "plugins": ["react"], - "rules": { - "jsx-quotes": ["error", "prefer-single"], + "plugins": [ + "react" + ], + "rules": { + "jsx-quotes": [ + "error", + "prefer-single" + ], "react/jsx-uses-react": "error", "react/jsx-uses-vars": "error", "react/jsx-no-undef": "error", - "react/jsx-fragments": ["error", "syntax"], + "react/jsx-fragments": [ + "error", + "syntax" + ], }, "settings": { "react": { "version": "detect", }, }, + "overrides": [ + { + "files": [ + "**/*.ts", + "**/*.tsx" + ], + "extends": [ + "@rocket.chat/eslint-config", + "plugin:@typescript-eslint/recommended", + "plugin:@typescript-eslint/eslint-recommended" + ], + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parser": "@typescript-eslint/parser", + "parserOptions": { + "sourceType": "module", + "ecmaVersion": 2018, + "warnOnUnsupportedTypeScriptVersion": false, + "ecmaFeatures": { + "experimentalObjectRestSpread": true, + "legacyDecorators": true + } + }, + "plugins": [ + "react", + "@typescript-eslint" + ], + "rules": { + "jsx-quotes": [ + "error", + "prefer-single" + ], + "react/jsx-uses-react": "error", + "react/jsx-uses-vars": "error", + "react/jsx-no-undef": "error", + "react/jsx-fragments": [ + "error", + "syntax" + ], + "@typescript-eslint/ban-ts-ignore": "off", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/interface-name-prefix": [ + "error", + "always" + ] + }, + "env": { + "browser": true, + "commonjs": true, + "es6": true, + "node": true + }, + "settings": { + "import/resolver": { + "node": { + "extensions": [ + ".js", + ".ts", + ".tsx" + ] + } + }, + "react": { + "version": "detect" + } + } + } + ] } diff --git a/.meteor/packages b/.meteor/packages index 09e237c2d25..ec716746c30 100644 --- a/.meteor/packages +++ b/.meteor/packages @@ -17,6 +17,7 @@ ddp-rate-limiter@1.0.7 ddp-common@1.4.0 dynamic-import@0.5.1 ecmascript@0.13.0 +typescript ejson@1.1.0 email@1.2.3 fastclick@1.0.13 diff --git a/.meteor/versions b/.meteor/versions index 33ffe5ded7f..0642cb7e72a 100644 --- a/.meteor/versions +++ b/.meteor/versions @@ -150,6 +150,7 @@ tmeasday:check-npm-versions@0.3.2 todda00:friendly-slugs@0.6.0 tracker@1.2.0 twitter-oauth@1.2.0 +typescript@3.7.0 ui@1.0.13 underscore@1.0.10 url@1.2.0 diff --git a/.scripts/set-version.js b/.scripts/set-version.js index 5f3a6e4b94c..102f8e14cb9 100644 --- a/.scripts/set-version.js +++ b/.scripts/set-version.js @@ -13,7 +13,7 @@ let pkgJson = {}; try { pkgJson = require(path.resolve( // eslint-disable-line import/no-dynamic-require process.cwd(), - './package.json' + './package.json', )); } catch (err) { console.error('no root package.json found'); @@ -87,7 +87,7 @@ git.status() type: 'confirm', message: 'Commit files?', name: 'commit', - }]) + }]), ) .then((answers) => { if (!answers.commit) { diff --git a/.scripts/start.js b/.scripts/start.js index 5d75151e225..bbc7f551c50 100644 --- a/.scripts/start.js +++ b/.scripts/start.js @@ -43,7 +43,7 @@ function startProcess(opts, callback) { const proc = spawn( opts.command, opts.params, - opts.options + opts.options, ); if (opts.waitForMessage) { diff --git a/.scripts/version.js b/.scripts/version.js index 461003c2d58..73fc12c46db 100644 --- a/.scripts/version.js +++ b/.scripts/version.js @@ -5,7 +5,7 @@ let pkgJson = {}; try { pkgJson = require(path.resolve( // eslint-disable-line import/no-dynamic-require process.cwd(), - './package.json' + './package.json', )); } catch (err) { console.error('no root package.json found'); diff --git a/app/api/server/v1/misc.js b/app/api/server/v1/misc.js index 51892359ec2..b17e0b7a1a1 100644 --- a/app/api/server/v1/misc.js +++ b/app/api/server/v1/misc.js @@ -162,7 +162,7 @@ API.v1.addRoute('spotlight', { authRequired: true }, { const { query } = this.queryParams; const result = Meteor.runAsUser(this.userId, () => - Meteor.call('spotlight', query) + Meteor.call('spotlight', query), ); return API.v1.success(result); diff --git a/app/api/server/v1/rooms.js b/app/api/server/v1/rooms.js index 92225c64fee..4db4c8326d6 100644 --- a/app/api/server/v1/rooms.js +++ b/app/api/server/v1/rooms.js @@ -134,8 +134,8 @@ API.v1.addRoute('rooms.saveNotification', { authRequired: true }, { const saveNotifications = (notifications, roomId) => { Object.keys(notifications).forEach((notificationKey) => Meteor.runAsUser(this.userId, () => - Meteor.call('saveNotificationSettings', roomId, notificationKey, notifications[notificationKey]) - ) + Meteor.call('saveNotificationSettings', roomId, notificationKey, notifications[notificationKey]), + ), ); }; const { roomId, notifications } = this.bodyParams; diff --git a/app/api/server/v1/subscriptions.js b/app/api/server/v1/subscriptions.js index 8ffa8711a33..236089ad1d6 100644 --- a/app/api/server/v1/subscriptions.js +++ b/app/api/server/v1/subscriptions.js @@ -62,7 +62,7 @@ API.v1.addRoute('subscriptions.read', { authRequired: true }, { }); Meteor.runAsUser(this.userId, () => - Meteor.call('readMessages', this.bodyParams.rid) + Meteor.call('readMessages', this.bodyParams.rid), ); return API.v1.success(); @@ -77,7 +77,7 @@ API.v1.addRoute('subscriptions.unread', { authRequired: true }, { } Meteor.runAsUser(this.userId, () => - Meteor.call('unreadMessages', firstUnreadMessage, roomId) + Meteor.call('unreadMessages', firstUnreadMessage, roomId), ); return API.v1.success(); diff --git a/app/apps/server/bridges/commands.js b/app/apps/server/bridges/commands.js index 9eefe190611..aab50a25bc2 100644 --- a/app/apps/server/bridges/commands.js +++ b/app/apps/server/bridges/commands.js @@ -170,7 +170,7 @@ export class AppCommandsBridge { Object.freeze(user), Object.freeze(room), Object.freeze(params), - threadId + threadId, ); return Promise.await(this.orch.getManager().getCommandManager().getPreviews(command, context)); } @@ -185,7 +185,7 @@ export class AppCommandsBridge { Object.freeze(user), Object.freeze(room), Object.freeze(params), - threadId + threadId, ); Promise.await(this.orch.getManager().getCommandManager().executePreview(command, preview, context)); } diff --git a/app/apps/server/bridges/messages.js b/app/apps/server/bridges/messages.js index 062efcd64b8..876c028b4db 100644 --- a/app/apps/server/bridges/messages.js +++ b/app/apps/server/bridges/messages.js @@ -77,7 +77,7 @@ export class AppMessageBridge { Users.findByIds(users, { fields: { _id: 1 } }) .fetch() .forEach(({ _id }) => - Notifications.notifyUser(_id, 'message', rmsg) + Notifications.notifyUser(_id, 'message', rmsg), ); } } diff --git a/app/apps/server/cron.js b/app/apps/server/cron.js index 0e51170734d..6c6f17b94c2 100644 --- a/app/apps/server/cron.js +++ b/app/apps/server/cron.js @@ -93,7 +93,7 @@ export const appsUpdateMarketplaceInfo = Meteor.bindEnvironment(function _appsUp Promise.await( Apps.updateAppsMarketplaceInfo(data) .then(notifyAdminsAboutInvalidApps) - .then(notifyAdminsAboutRenewedApps) + .then(notifyAdminsAboutRenewedApps), ); }); diff --git a/app/authorization/client/views/permissions.js b/app/authorization/client/views/permissions.js index d03ac7d52cb..1ad319988a8 100644 --- a/app/authorization/client/views/permissions.js +++ b/app/authorization/client/views/permissions.js @@ -8,13 +8,12 @@ import { Template } from 'meteor/templating'; import { Roles } from '../../../models'; import { ChatPermissions } from '../lib/ChatPermissions'; import { hasAllPermission } from '../hasPermission'; - -import { hasAtLeastOnePermission } from '..'; - import { t } from '../../../utils/client'; import { SideNav } from '../../../ui-utils/client/lib/SideNav'; import { CONSTANTS } from '../../lib'; +import { hasAtLeastOnePermission } from '..'; + Template.permissions.helpers({ tabsData() { const { @@ -85,7 +84,7 @@ Template.permissions.helpers({ _id: 1, }, limit, - } + }, ); }, @@ -105,7 +104,7 @@ Template.permissions.helpers({ group: 1, section: 1, }, - } + }, ); }, diff --git a/app/authorization/server/publications/permissions/emitter.js b/app/authorization/server/publications/permissions/emitter.js index ef958ed4850..a7062439eb4 100644 --- a/app/authorization/server/publications/permissions/emitter.js +++ b/app/authorization/server/publications/permissions/emitter.js @@ -25,7 +25,7 @@ Permissions.on('change', ({ clientAction, id, data, diff }) => { Notifications.notifyLoggedInThisInstance( 'permissions-changed', clientAction, - data + data, ); if (data.level && data.level === CONSTANTS.SETTINGS_LEVEL) { @@ -36,7 +36,7 @@ Permissions.on('change', ({ clientAction, id, data, diff }) => { Notifications.notifyLoggedInThisInstance( 'private-settings-changed', 'updated', - setting + setting, ); } }); diff --git a/app/authorization/server/publications/permissions/index.js b/app/authorization/server/publications/permissions/index.js index 8e74f7b6932..09e7ccffc6c 100644 --- a/app/authorization/server/publications/permissions/index.js +++ b/app/authorization/server/publications/permissions/index.js @@ -16,7 +16,7 @@ Meteor.methods({ remove: Permissions.trashFindDeletedAfter( updatedAt, {}, - { fields: { _id: 1, _deletedAt: 1 } } + { fields: { _id: 1, _deletedAt: 1 } }, ).fetch(), }; } diff --git a/app/callbacks/lib/callbacks.js b/app/callbacks/lib/callbacks.js index efc44c0ee59..d602e038420 100644 --- a/app/callbacks/lib/callbacks.js +++ b/app/callbacks/lib/callbacks.js @@ -50,7 +50,7 @@ const createCallbackTimed = (hook, callbacks) => callbacks .map(wrapCallback) .map(handleResult) - .reduce(pipe, identity) + .reduce(pipe, identity), ); const create = (hook, cbs) => @@ -79,7 +79,7 @@ callbacks.add = function( hook, callback, priority = callbacks.priority.MEDIUM, - id = Random.id() + id = Random.id(), ) { callbacks[hook] = getHooks(hook); if (callbacks[hook].find((cb) => cb.id === id)) { diff --git a/app/cas/client/cas_client.js b/app/cas/client/cas_client.js index 7046f4d024e..6cfa3c61d6f 100644 --- a/app/cas/client/cas_client.js +++ b/app/cas/client/cas_client.js @@ -45,7 +45,7 @@ Meteor.loginWithCas = function(options, callback) { const popup = openCenteredPopup( loginUrl, popup_width || 800, - popup_height || 600 + popup_height || 600, ); diff --git a/app/channel-settings/client/views/channelSettings.js b/app/channel-settings/client/views/channelSettings.js index 41332e2aa06..1d56f18ff3c 100644 --- a/app/channel-settings/client/views/channelSettings.js +++ b/app/channel-settings/client/views/channelSettings.js @@ -412,7 +412,7 @@ Template.channelSettingsEditing.onCreated(function() { canView() { return roomTypes.roomTypes[room.t].allowRoomSettingChange( room, - RoomSettingsEnum.SYSTEM_MESSAGES + RoomSettingsEnum.SYSTEM_MESSAGES, ); }, getValue() { @@ -425,9 +425,9 @@ Template.channelSettingsEditing.onCreated(function() { return call('saveRoomSettings', room._id, 'systemMessages', value).then( () => { toastr.success( - t('System_messages_setting_changed_successfully') + t('System_messages_setting_changed_successfully'), ); - } + }, ); }, }, @@ -572,9 +572,9 @@ Template.channelSettingsEditing.onCreated(function() { return call('saveRoomSettings', room._id, 'retentionOverrideGlobal', value).then( () => { toastr.success( - t('Retention_setting_changed_successfully') + t('Retention_setting_changed_successfully'), ); - } + }, ); }, }, @@ -596,9 +596,9 @@ Template.channelSettingsEditing.onCreated(function() { return call('saveRoomSettings', room._id, 'retentionMaxAge', value).then( () => { toastr.success( - t('Retention_setting_changed_successfully') + t('Retention_setting_changed_successfully'), ); - } + }, ); }, }, @@ -620,9 +620,9 @@ Template.channelSettingsEditing.onCreated(function() { return call('saveRoomSettings', room._id, 'retentionExcludePinned', value).then( () => { toastr.success( - t('Retention_setting_changed_successfully') + t('Retention_setting_changed_successfully'), ); - } + }, ); }, }, @@ -644,9 +644,9 @@ Template.channelSettingsEditing.onCreated(function() { return call('saveRoomSettings', room._id, 'retentionFilesOnly', value).then( () => { toastr.success( - t('Retention_setting_changed_successfully') + t('Retention_setting_changed_successfully'), ); - } + }, ); }, }, @@ -664,7 +664,7 @@ Template.channelSettingsEditing.onCreated(function() { save(value) { return call('saveRoomSettings', room._id, 'encrypted', value).then(() => { toastr.success( - t('Encrypted_setting_changed_successfully') + t('Encrypted_setting_changed_successfully'), ); }); }, diff --git a/app/chatpal-search/server/provider/provider.js b/app/chatpal-search/server/provider/provider.js index a46d935c725..18ee9a36f42 100644 --- a/app/chatpal-search/server/provider/provider.js +++ b/app/chatpal-search/server/provider/provider.js @@ -315,7 +315,7 @@ class ChatpalProvider extends SearchProvider { payload.start || 0, payload.rows || this._settings.get('PageSize'), callback, - params + params, ); } @@ -332,7 +332,7 @@ class ChatpalProvider extends SearchProvider { this._settings.get('Main_Language'), this._getAcl(context), type, - callback + callback, ); } } diff --git a/app/custom-sounds/client/admin/adminSounds.js b/app/custom-sounds/client/admin/adminSounds.js index 552bcd2ea42..ea508e99396 100644 --- a/app/custom-sounds/client/admin/adminSounds.js +++ b/app/custom-sounds/client/admin/adminSounds.js @@ -123,7 +123,7 @@ Template.adminSounds.onRendered(() => Tracker.afterFlush(function() { SideNav.setFlex('adminFlex'); SideNav.openFlex(); - }) + }), ); Template.adminSounds.events({ diff --git a/app/custom-sounds/client/admin/soundEdit.js b/app/custom-sounds/client/admin/soundEdit.js index c55f2f5a03d..6562c4b154c 100644 --- a/app/custom-sounds/client/admin/soundEdit.js +++ b/app/custom-sounds/client/admin/soundEdit.js @@ -133,7 +133,7 @@ Template.soundEdit.onCreated(function() { handleError(uploadError); console.log(uploadError); } - } + }, ); delete this.soundFile; toastr.success(TAPi18n.__('File_uploaded')); diff --git a/app/custom-sounds/client/lib/CustomSounds.js b/app/custom-sounds/client/lib/CustomSounds.js index 52e1666c4d8..09c175ac6c0 100644 --- a/app/custom-sounds/client/lib/CustomSounds.js +++ b/app/custom-sounds/client/lib/CustomSounds.js @@ -20,7 +20,7 @@ class CustomSoundsClass { sound.src = this.getURL(sound); } const audio = $('