diff --git a/.eslintrc.js b/.eslintrc.js index c0b81682e92..268f2a485b0 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,5 +1,3 @@ -/* eslint-disable @typescript-eslint/no-var-requires */ - /* global module */ module.exports = { ignorePatterns: ['node_modules', 'plugin-server'], @@ -16,8 +14,9 @@ module.exports = { extends: [ 'plugin:@typescript-eslint/recommended', 'plugin:react/recommended', - 'prettier', + 'plugin:eslint-comments/recommended', 'plugin:storybook/recommended', + 'prettier', ], globals: { Atomics: 'readonly', @@ -43,12 +42,14 @@ module.exports = { html: true, }, ], - 'no-unused-vars': [ + 'no-unused-vars': 'off', + '@typescript-eslint/no-unused-vars': [ 'error', { ignoreRestSiblings: true, }, ], + '@typescript-eslint/prefer-ts-expect-error': 'error', '@typescript-eslint/explicit-function-return-type': 'off', '@typescript-eslint/explicit-module-boundary-types': 'off', '@typescript-eslint/no-empty-function': 'off', @@ -103,4 +104,5 @@ module.exports = { }, }, ], + reportUnusedDisableDirectives: true, } diff --git a/frontend/src/lib/components/CommandPalette/commandPaletteLogic.ts b/frontend/src/lib/components/CommandPalette/commandPaletteLogic.ts index 37540c5c30e..91b49db1e2e 100644 --- a/frontend/src/lib/components/CommandPalette/commandPaletteLogic.ts +++ b/frontend/src/lib/components/CommandPalette/commandPaletteLogic.ts @@ -191,7 +191,7 @@ export const commandPaletteLogic = kea({ return { ...commands, [command.key]: command } }, deregisterCommand: (commands, { commandKey }) => { - const { [commandKey]: _, ...cleanedCommands } = commands // eslint-disable-line + const { [commandKey]: _discard, ...cleanedCommands } = commands return cleanedCommands }, }, @@ -219,9 +219,7 @@ export const commandPaletteLogic = kea({ } } // Capture command execution, without useless data - // eslint-disable-next-line @typescript-eslint/no-unused-vars const { icon, index, ...cleanedResult }: Record = result - // eslint-disable-next-line @typescript-eslint/no-unused-vars const { resolver, ...cleanedCommand } = cleanedResult.source cleanedResult.source = cleanedCommand cleanedResult.isMobile = isMobile() diff --git a/frontend/src/lib/components/EventSelect/EventSelect.tsx b/frontend/src/lib/components/EventSelect/EventSelect.tsx index ae6cd234ffc..ce2a0257afa 100644 --- a/frontend/src/lib/components/EventSelect/EventSelect.tsx +++ b/frontend/src/lib/components/EventSelect/EventSelect.tsx @@ -51,10 +51,7 @@ export const EventSelect = ({ onChange, selectedEvents, addElement }: EventSelec } const popupLogic = { - // eslint-disable-next-line @typescript-eslint/explicit-function-return-type toggle: (open: boolean) => !open, - - // eslint-disable-next-line @typescript-eslint/explicit-function-return-type hide: () => false, } diff --git a/frontend/src/lib/components/ObjectTags/objectTagsLogic.test.ts b/frontend/src/lib/components/ObjectTags/objectTagsLogic.test.ts index 79ca7566edd..ef4c1d8c4c6 100644 --- a/frontend/src/lib/components/ObjectTags/objectTagsLogic.test.ts +++ b/frontend/src/lib/components/ObjectTags/objectTagsLogic.test.ts @@ -42,7 +42,7 @@ describe('objectTagsLogic', () => { addingNewTag: false, newTag: '', }) - // @ts-ignore + // @ts-expect-error const mockedOnChange = props.onChange?.mock as any expect(mockedOnChange.calls.length).toBe(1) expect(mockedOnChange.calls[0][0]).toBe('nightly') @@ -58,7 +58,7 @@ describe('objectTagsLogic', () => { .toMatchValues({ tags: ['a', 'b', 'c'], }) - // @ts-ignore + // @ts-expect-error expect(props.onChange?.mock.calls.length).toBe(0) }) it('handle deleting a tag', async () => { @@ -69,7 +69,7 @@ describe('objectTagsLogic', () => { .toMatchValues({ tags: ['b', 'c'], }) - // @ts-ignore + // @ts-expect-error const mockedOnChange = props.onChange?.mock as any expect(mockedOnChange.calls.length).toBe(1) expect(mockedOnChange.calls[0][0]).toBe('a') diff --git a/frontend/src/lib/components/PersonPropertySelect/PersonPropertySelect.tsx b/frontend/src/lib/components/PersonPropertySelect/PersonPropertySelect.tsx index 87de241673a..1fe9ece5313 100644 --- a/frontend/src/lib/components/PersonPropertySelect/PersonPropertySelect.tsx +++ b/frontend/src/lib/components/PersonPropertySelect/PersonPropertySelect.tsx @@ -121,10 +121,7 @@ export const PersonPropertySelect = ({ } const popupLogic = { - // eslint-disable-next-line @typescript-eslint/explicit-function-return-type toggle: (open: boolean) => !open, - - // eslint-disable-next-line @typescript-eslint/explicit-function-return-type hide: () => false, } diff --git a/frontend/src/lib/components/ResizableTable/TableConfig.tsx b/frontend/src/lib/components/ResizableTable/TableConfig.tsx index efe06bf9ef8..cbd622f1373 100644 --- a/frontend/src/lib/components/ResizableTable/TableConfig.tsx +++ b/frontend/src/lib/components/ResizableTable/TableConfig.tsx @@ -103,7 +103,7 @@ function ColumnConfigurator({ immutableColumns, defaultColumns }: TableConfigPro bodyStyle={{ padding: '16px 16px 0 16px' }} className="column-configurator-modal" okButtonProps={{ - // @ts-ignore + // @ts-expect-error 'data-attr': 'items-selector-confirm', }} okText="Save" diff --git a/frontend/src/lib/components/UniversalSearch/UniversalSearchPopup.tsx b/frontend/src/lib/components/UniversalSearch/UniversalSearchPopup.tsx index 49e41ebdf68..d764aaea303 100644 --- a/frontend/src/lib/components/UniversalSearch/UniversalSearchPopup.tsx +++ b/frontend/src/lib/components/UniversalSearch/UniversalSearchPopup.tsx @@ -169,7 +169,7 @@ export function UniversalSearchPopup({ modifier={{ name: 'offset', options: { - // @ts-ignore + // @ts-expect-error offset: ({ placement }) => { if (placement === 'right-start') { return [-25, -250] diff --git a/frontend/src/lib/hooks/useLongPress.js b/frontend/src/lib/hooks/useLongPress.js index d1dfbd42dec..83beb5df2b7 100644 --- a/frontend/src/lib/hooks/useLongPress.js +++ b/frontend/src/lib/hooks/useLongPress.js @@ -24,7 +24,7 @@ function diffInCoords(e, initialCoords) { - exclude = '' - selector for when to NOT start long-pressing */ export function useLongPress( - callback = (clicked = false, ms = null) => {}, // eslint-disable-line + callback = (clicked = false, ms = null) => {}, // eslint-disable-line @typescript-eslint/no-unused-vars { ms = 300, pixelDistance = 10, touch = true, click = true, exclude = '', clickMs = null } ) { const [startLongPress, setStartLongPress] = useState(null) @@ -34,7 +34,7 @@ export function useLongPress( let timerId if (startLongPress && ms) { timerId = setTimeout(() => { - callback(false, window.performance.now() - startLongPress, initialCoords) + callback?.(false, window.performance.now() - startLongPress, initialCoords) stop() }, ms) } diff --git a/frontend/src/lib/hooks/usePageVisibility.ts b/frontend/src/lib/hooks/usePageVisibility.ts index 284bba7351e..f40f9f59721 100644 --- a/frontend/src/lib/hooks/usePageVisibility.ts +++ b/frontend/src/lib/hooks/usePageVisibility.ts @@ -18,11 +18,11 @@ export function usePageVisibility(callback: (pageIsVisible: boolean) => void): v // Opera 12.10 and Firefox 18 and later support let hidden = 'hidden' let visibilityChange = 'visibilitychange' - // @ts-ignore - to avoid complaint that msHidden isn't on document + // @ts-expect-error - to avoid complaint that msHidden isn't on document if (typeof document.msHidden !== 'undefined') { hidden = 'msHidden' visibilityChange = 'msvisibilitychange' - // @ts-ignore - to avoid complaint that webkitHidden isn't on document + // @ts-expect-error - to avoid complaint that webkitHidden isn't on document } else if (typeof document.webkitHidden !== 'undefined') { hidden = 'webkitHidden' visibilityChange = 'webkitvisibilitychange' diff --git a/frontend/src/lib/utils/eventUsageLogic.ts b/frontend/src/lib/utils/eventUsageLogic.ts index 1c8141ea2c1..9679f5acfba 100644 --- a/frontend/src/lib/utils/eventUsageLogic.ts +++ b/frontend/src/lib/utils/eventUsageLogic.ts @@ -824,7 +824,7 @@ export const eventUsageLogic = kea({ posthog.capture('saved insights new insight clicked', { insight_type: insightType }) }, reportRecording: ({ recordingData, source, loadTime, type }) => { - // @ts-ignore + // @ts-expect-error const eventIndex = new EventIndex(recordingData?.snapshots || []) const payload: Partial = { load_time: loadTime, diff --git a/frontend/src/loadPostHogJS.tsx b/frontend/src/loadPostHogJS.tsx index b9236d320f7..01e9f20fa93 100644 --- a/frontend/src/loadPostHogJS.tsx +++ b/frontend/src/loadPostHogJS.tsx @@ -22,8 +22,7 @@ export function loadPostHogJS(): void { window.JS_POSTHOG_API_KEY, configWithSentry({ api_host: window.JS_POSTHOG_HOST, - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore + // @ts-expect-error _capture_metrics: true, rageclick: true, debug: window.JS_POSTHOG_SELF_CAPTURE, diff --git a/frontend/src/models/dashboardsModel.tsx b/frontend/src/models/dashboardsModel.tsx index 45974017689..f47292f91e4 100644 --- a/frontend/src/models/dashboardsModel.tsx +++ b/frontend/src/models/dashboardsModel.tsx @@ -155,8 +155,8 @@ export const dashboardsModel = kea({ [dashboard.id]: { ...state[dashboard.id], deleted: true }, }), delayedDeleteDashboard: (state, { id }) => { - // this gives us time to leave the /dashboard/:deleted_id page - const { [id]: _discard, ...rest } = state // eslint-disable-line + // This gives us time to leave the /dashboard/:deleted_id page + const { [id]: _discard, ...rest } = state return rest }, pinDashboardSuccess: (state, { dashboard }) => ({ ...state, [dashboard.id]: dashboard }), diff --git a/frontend/src/models/insightsModel.tsx b/frontend/src/models/insightsModel.tsx index 7153d4f6cc5..d88b2ea5968 100644 --- a/frontend/src/models/insightsModel.tsx +++ b/frontend/src/models/insightsModel.tsx @@ -100,7 +100,7 @@ export const insightsModel = kea({ layouts[size] = { w, h } }) - const { id: _discard, short_id: __discard, ...rest } = item // eslint-disable-line + const { id: _discard, short_id: __discard, ...rest } = item const newItem = dashboardId ? { ...rest, dashboards: [dashboardId], layouts } : { ...rest, layouts } const addedItem = await api.create(`api/projects/${teamLogic.values.currentTeamId}/insights`, newItem) diff --git a/frontend/src/scenes/PreflightCheck/preflightLogic.tsx b/frontend/src/scenes/PreflightCheck/preflightLogic.tsx index 8f4fb60b7d9..c47ed8eede5 100644 --- a/frontend/src/scenes/PreflightCheck/preflightLogic.tsx +++ b/frontend/src/scenes/PreflightCheck/preflightLogic.tsx @@ -219,7 +219,6 @@ export const preflightLogic = kea([ if (!preflight) { return [] } - // @ts-ignore return RELEVANT_CONFIGS.map((config) => ({ key: config.key, metric: config.label, diff --git a/frontend/src/scenes/apps/frontendAppsLogic.tsx b/frontend/src/scenes/apps/frontendAppsLogic.tsx index 2672389e5b2..85fe2259661 100644 --- a/frontend/src/scenes/apps/frontendAppsLogic.tsx +++ b/frontend/src/scenes/apps/frontendAppsLogic.tsx @@ -100,8 +100,7 @@ export const frontendAppsLogic = kea([ reducers({ frontendApps: { unloadFrontendApp: (frontendApps, { id }) => { - // eslint-disable-next-line - const { [id]: _removed, ...rest } = frontendApps + const { [id]: _discard, ...rest } = frontendApps return rest }, }, diff --git a/frontend/src/scenes/dashboard/dashboardLogic.ts b/frontend/src/scenes/dashboard/dashboardLogic.ts index 4758b7ab2d8..8bd51b85c70 100644 --- a/frontend/src/scenes/dashboard/dashboardLogic.ts +++ b/frontend/src/scenes/dashboard/dashboardLogic.ts @@ -576,7 +576,7 @@ export const dashboardLogic = kea({ values.items?.map((item) => { const layouts: Record = {} Object.entries(item.layouts).forEach(([layoutKey, layout]) => { - const { i, ...rest } = layout // eslint-disable-line + const { i, ...rest } = layout layouts[layoutKey] = rest }) return { id: item.id, layouts } diff --git a/frontend/src/scenes/feature-flags/featureFlagLogic.ts b/frontend/src/scenes/feature-flags/featureFlagLogic.ts index 6c8a2aa6d38..cf12d1433e8 100644 --- a/frontend/src/scenes/feature-flags/featureFlagLogic.ts +++ b/frontend/src/scenes/feature-flags/featureFlagLogic.ts @@ -265,7 +265,6 @@ export const featureFlagLogic = kea([ return NEW_FLAG }, saveFeatureFlag: async (updatedFlag: Partial) => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars const { created_at, id, ...flag } = updatedFlag try { diff --git a/frontend/src/scenes/insights/Insights.stories.tsx b/frontend/src/scenes/insights/Insights.stories.tsx index fcca16e5e00..2d0d9f76855 100644 --- a/frontend/src/scenes/insights/Insights.stories.tsx +++ b/frontend/src/scenes/insights/Insights.stories.tsx @@ -1,4 +1,3 @@ -/* eslint-disable */ import { Meta } from '@storybook/react' import { mswDecorator } from '~/mocks/browser' import { samplePersonProperties, sampleRetentionPeopleResponse } from 'scenes/insights/__mocks__/insight.mocks' @@ -20,6 +19,7 @@ export default { ], } as Meta +/* eslint-disable @typescript-eslint/no-var-requires */ export const TrendsLine = createInsightScene(require('./__mocks__/trendsLine.json')) export const TrendsLineBreakdown = createInsightScene(require('./__mocks__/trendsLineBreakdown.json')) export const TrendsBar = createInsightScene(require('./__mocks__/trendsBar.json')) @@ -36,7 +36,7 @@ export const FunnelLeftToRight = createInsightScene(require('./__mocks__/funnelL export const FunnelLeftToRightBreakdown = createInsightScene(require('./__mocks__/funnelLeftToRightBreakdown.json')) export const FunnelTopToBottom = createInsightScene(require('./__mocks__/funnelTopToBottom.json')) export const FunnelTopToBottomBreakdown = createInsightScene(require('./__mocks__/funnelTopToBottomBreakdown.json')) -export const funnelHistoricalTrends = createInsightScene(require('./__mocks__/funnelHistoricalTrends.json')) +export const FunnelHistoricalTrends = createInsightScene(require('./__mocks__/funnelHistoricalTrends.json')) export const FunnelTimeToConvert = createInsightScene(require('./__mocks__/funnelTimeToConvert.json')) export const Retention = createInsightScene(require('./__mocks__/retention.json')) @@ -44,3 +44,4 @@ export const RetentionBreakdown = createInsightScene(require('./__mocks__/retent export const Lifecycle = createInsightScene(require('./__mocks__/lifecycle.json')) export const Stickiness = createInsightScene(require('./__mocks__/stickiness.json')) export const UserPaths = createInsightScene(require('./__mocks__/userPaths.json')) +/* eslint-enable @typescript-eslint/no-var-requires */ diff --git a/frontend/src/scenes/insights/sharedUtils.ts b/frontend/src/scenes/insights/sharedUtils.ts index 084ba0cc322..a1bf2934524 100644 --- a/frontend/src/scenes/insights/sharedUtils.ts +++ b/frontend/src/scenes/insights/sharedUtils.ts @@ -21,12 +21,7 @@ export const keyForInsightLogicProps = } export function filterTrendsClientSideParams(filters: Partial): Partial { - const { - people_day: _skip_this_one, // eslint-disable-line - people_action: _skip_this_too, // eslint-disable-line - stickiness_days: __and_this, // eslint-disable-line - ...newFilters - } = filters + const { people_day: _discard, people_action: __discard, stickiness_days: ___discard, ...newFilters } = filters return newFilters } diff --git a/frontend/src/scenes/plugins/plugin/LogsDrawer.tsx b/frontend/src/scenes/plugins/plugin/LogsDrawer.tsx index 339e167cad6..7892a5ddea1 100644 --- a/frontend/src/scenes/plugins/plugin/LogsDrawer.tsx +++ b/frontend/src/scenes/plugins/plugin/LogsDrawer.tsx @@ -17,10 +17,8 @@ export function LogsDrawer(): JSX.Element { placement="left" destroyOnClose > - {!!lastShownLogsPlugin && ( - + {!!lastShownLogsPlugin?.pluginConfig.id && ( + )} ) diff --git a/frontend/src/scenes/plugins/pluginsLogic.ts b/frontend/src/scenes/plugins/pluginsLogic.ts index 14643bad8b1..66a269a438b 100644 --- a/frontend/src/scenes/plugins/pluginsLogic.ts +++ b/frontend/src/scenes/plugins/pluginsLogic.ts @@ -139,7 +139,7 @@ export const pluginsLogic = kea([ } await api.delete(`api/organizations/@current/plugins/${editingPlugin.id}`) capturePluginEvent(`plugin uninstalled`, editingPlugin) - const { [editingPlugin.id]: _discard, ...rest } = plugins // eslint-disable-line + const { [editingPlugin.id]: _discard, ...rest } = plugins return rest }, updatePlugin: async ({ id }) => { diff --git a/frontend/src/scenes/urls.ts b/frontend/src/scenes/urls.ts index 8381726940f..f7c39ab491a 100644 --- a/frontend/src/scenes/urls.ts +++ b/frontend/src/scenes/urls.ts @@ -1,79 +1,79 @@ -/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { DashboardType, FilterType, InsightShortId } from '~/types' import { combineUrl } from 'kea-router' -/* -To add a new URL to the front end: - - add a URL function here - - add a scene to the enum in sceneTypes.ts - - add a scene configuration in scenes.ts - - add a route to scene mapping in scenes.ts - - and add a scene import in appScenes.ts - - Sync the paths with AutoProjectMiddleware! +/** + * To add a new URL to the front end: + * - add a URL function here + * - add a scene to the enum in sceneTypes.ts + * - add a scene configuration in scenes.ts + * - add a route to scene mapping in scenes.ts + * - and add a scene import in appScenes.ts + * + * Sync the paths with AutoProjectMiddleware! */ export const urls = { - default: () => '/', - dashboards: () => '/dashboard', - dashboard: (id: string | number, highlightInsightId?: string) => + default: (): string => '/', + dashboards: (): string => '/dashboard', + dashboard: (id: string | number, highlightInsightId?: string): string => combineUrl(`/dashboard/${id}`, highlightInsightId ? { highlightInsightId } : {}).url, - sharedDashboard: (shareToken: string) => `/shared_dashboard/${shareToken}`, - createAction: () => `/data-management/actions/new`, // TODO: For consistency, this should be `/action/new` - action: (id: string | number) => `/data-management/actions/${id}`, - actions: () => '/data-management/actions', - eventDefinitions: () => '/data-management/events', - eventDefinition: (id: string | number) => `/data-management/events/${id}`, - eventPropertyDefinitions: () => '/data-management/event-properties', - eventPropertyDefinition: (id: string | number) => `/data-management/event-properties/${id}`, - events: () => '/events', - insightNew: (filters?: Partial, dashboardId?: DashboardType['id'] | null) => + sharedDashboard: (shareToken: string): string => `/shared_dashboard/${shareToken}`, + createAction: (): string => `/data-management/actions/new`, // TODO: For consistency, this should be `/action/new` + action: (id: string | number): string => `/data-management/actions/${id}`, + actions: (): string => '/data-management/actions', + eventDefinitions: (): string => '/data-management/events', + eventDefinition: (id: string | number): string => `/data-management/events/${id}`, + eventPropertyDefinitions: (): string => '/data-management/event-properties', + eventPropertyDefinition: (id: string | number): string => `/data-management/event-properties/${id}`, + events: (): string => '/events', + insightNew: (filters?: Partial, dashboardId?: DashboardType['id'] | null): string => combineUrl('/insights/new', dashboardId ? { dashboard: dashboardId } : {}, filters ? { filters } : {}).url, - insightEdit: (id: InsightShortId) => `/insights/${id}/edit`, - insightView: (id: InsightShortId) => `/insights/${id}`, - savedInsights: () => '/insights', - webPerformance: () => '/web-performance', - webPerformanceWaterfall: (id: string) => `/web-performance/${id}/waterfall`, - sessionRecordings: () => '/recordings', - person: (id: string, encode: boolean = true) => (encode ? `/person/${encodeURIComponent(id)}` : `/person/${id}`), - persons: () => '/persons', - groups: (groupTypeIndex: string) => `/groups/${groupTypeIndex}`, + insightEdit: (id: InsightShortId): string => `/insights/${id}/edit`, + insightView: (id: InsightShortId): string => `/insights/${id}`, + savedInsights: (): string => '/insights', + webPerformance: (): string => '/web-performance', + webPerformanceWaterfall: (id: string): string => `/web-performance/${id}/waterfall`, + sessionRecordings: (): string => '/recordings', + person: (id: string, encode: boolean = true): string => + encode ? `/person/${encodeURIComponent(id)}` : `/person/${id}`, + persons: (): string => '/persons', + groups: (groupTypeIndex: string): string => `/groups/${groupTypeIndex}`, // :TRICKY: Note that groupKey is provided by user. We need to override urlPatternOptions for kea-router. - group: (groupTypeIndex: string | number, groupKey: string, encode: boolean = true) => + group: (groupTypeIndex: string | number, groupKey: string, encode: boolean = true): string => `/groups/${groupTypeIndex}/${encode ? encodeURIComponent(groupKey) : groupKey}`, - cohort: (id: string | number) => `/cohorts/${id}`, - cohorts: () => '/cohorts', - experiment: (id: string | number) => `/experiments/${id}`, - experiments: () => '/experiments', - featureFlags: () => '/feature_flags', - featureFlag: (id: string | number) => `/feature_flags/${id}`, - annotations: () => '/annotations', - projectApps: () => '/project/apps', - frontendApp: (id: string | number) => `/app/${id}`, - projectCreateFirst: () => '/project/create', - projectHomepage: () => '/home', - projectSettings: () => '/project/settings', - mySettings: () => '/me/settings', - organizationSettings: () => '/organization/settings', - organizationCreateFirst: () => '/organization/create', - toolbarLaunch: () => '/toolbar', + cohort: (id: string | number): string => `/cohorts/${id}`, + cohorts: (): string => '/cohorts', + experiment: (id: string | number): string => `/experiments/${id}`, + experiments: (): string => '/experiments', + featureFlags: (): string => '/feature_flags', + featureFlag: (id: string | number): string => `/feature_flags/${id}`, + annotations: (): string => '/annotations', + projectApps: (): string => '/project/apps', + frontendApp: (id: string | number): string => `/app/${id}`, + projectCreateFirst: (): string => '/project/create', + projectHomepage: (): string => '/home', + projectSettings: (): string => '/project/settings', + mySettings: (): string => '/me/settings', + organizationSettings: (): string => '/organization/settings', + organizationCreateFirst: (): string => '/organization/create', + toolbarLaunch: (): string => '/toolbar', // Onboarding / setup routes - login: () => '/login', - passwordReset: () => '/reset', - passwordResetComplete: (userUuid: string, token: string) => `/reset/${userUuid}/${token}`, - preflight: () => '/preflight', - signup: () => '/signup', - inviteSignup: (id: string) => `/signup/${id}`, - ingestion: () => '/ingestion', + login: (): string => '/login', + passwordReset: (): string => '/reset', + passwordResetComplete: (userUuid: string, token: string): string => `/reset/${userUuid}/${token}`, + preflight: (): string => '/preflight', + signup: (): string => '/signup', + inviteSignup: (id: string): string => `/signup/${id}`, + ingestion: (): string => '/ingestion', // Cloud only - organizationBilling: () => '/organization/billing', - billingSubscribed: () => '/organization/billing/subscribed', + organizationBilling: (): string => '/organization/billing', + billingSubscribed: (): string => '/organization/billing/subscribed', // Self-hosted only - instanceLicenses: () => '/instance/licenses', - instanceStatus: () => '/instance/status', - instanceStaffUsers: () => '/instance/staff_users', - instanceKafkaInspector: () => '/instance/kafka_inspector', - instanceSettings: () => '/instance/settings', - instanceMetrics: () => `/instance/metrics`, - asyncMigrations: () => '/instance/async_migrations', - deadLetterQueue: () => '/instance/dead_letter_queue', + instanceLicenses: (): string => '/instance/licenses', + instanceStatus: (): string => '/instance/status', + instanceStaffUsers: (): string => '/instance/staff_users', + instanceKafkaInspector: (): string => '/instance/kafka_inspector', + instanceSettings: (): string => '/instance/settings', + instanceMetrics: (): string => `/instance/metrics`, + asyncMigrations: (): string => '/instance/async_migrations', + deadLetterQueue: (): string => '/instance/dead_letter_queue', } diff --git a/frontend/src/toolbar/actions/actionsLogic.ts b/frontend/src/toolbar/actions/actionsLogic.ts index fb14b94d9da..4280af00fd3 100644 --- a/frontend/src/toolbar/actions/actionsLogic.ts +++ b/frontend/src/toolbar/actions/actionsLogic.ts @@ -22,7 +22,7 @@ export const actionsLogic = kea({ allActions: [ [] as ActionType[], { - // eslint-disable-next-line + // eslint-disable-next-line @typescript-eslint/no-unused-vars getActions: async (_ = null, breakpoint: () => void) => { const response = await toolbarFetch('/api/projects/@current/actions/') const results = await response.json() diff --git a/package.json b/package.json index 0ee5a117008..b6c9370bc77 100644 --- a/package.json +++ b/package.json @@ -170,6 +170,7 @@ "eslint": "^7.8.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-cypress": "^2.11.2", + "eslint-plugin-eslint-comments": "^3.2.0", "eslint-plugin-prettier": "^3.1.4", "eslint-plugin-react": "^7.20.3", "eslint-plugin-storybook": "^0.5.7", diff --git a/plugin-server/.eslintrc.js b/plugin-server/.eslintrc.js index e17a1828969..2aa9a71dc5a 100644 --- a/plugin-server/.eslintrc.js +++ b/plugin-server/.eslintrc.js @@ -7,8 +7,8 @@ module.exports = { project: ['./tsconfig.eslint.json'], }, plugins: ['@typescript-eslint', 'simple-import-sort', 'prettier'], - extends: ['plugin:@typescript-eslint/recommended', 'prettier'], - ignorePatterns: ['bin', 'dist', 'node_modules', '**/protos.d.ts'], + extends: ['plugin:@typescript-eslint/recommended', 'plugin:eslint-comments/recommended', 'prettier'], + ignorePatterns: ['bin', 'dist', 'node_modules', 'src/config/idl'], rules: { 'simple-import-sort/imports': 'error', 'simple-import-sort/exports': 'error', @@ -19,6 +19,7 @@ module.exports = { ignoreRestSiblings: true, }, ], + '@typescript-eslint/prefer-ts-expect-error': 'error', '@typescript-eslint/explicit-function-return-type': 'off', '@typescript-eslint/no-non-null-assertion': 'off', '@typescript-eslint/no-var-requires': 'off', @@ -39,4 +40,5 @@ module.exports = { }, ], root: true, + reportUnusedDisableDirectives: true, } diff --git a/plugin-server/package.json b/plugin-server/package.json index f6355f2f598..afdfc27a61b 100644 --- a/plugin-server/package.json +++ b/plugin-server/package.json @@ -20,7 +20,7 @@ "start:dev": "NODE_ENV=dev BASE_DIR=.. ts-node-dev --debug --exit-child src/index.ts", "build": "yarn clean && yarn compile", "clean": "rimraf dist/*", - "protobuf:compile": "cd src/config/idl/ && rimraf protos.* && pbjs -t static-module -w commonjs -o protos.js *.proto --keep-case && pbts -o protos.d.ts protos.js && eslint --fix . && prettier --write .", + "protobuf:compile": "cd src/config/idl/ && rimraf protos.* && pbjs -t static-module -w commonjs -o protos.js *.proto --keep-case && pbts -o protos.d.ts protos.js && prettier --write .", "typescript:compile": "tsc -b", "typescript:check": "tsc --noEmit -p .", "compile": "yarn protobuf:compile && yarn typescript:compile", @@ -114,6 +114,7 @@ "babel-eslint": "^10.1.0", "eslint": "^7.28.0", "eslint-config-prettier": "^8.3.0", + "eslint-plugin-eslint-comments": "^3.2.0", "eslint-plugin-import": "^2.23.4", "eslint-plugin-node": "^11.1.0", "eslint-plugin-prettier": "^4.0.0", diff --git a/plugin-server/src/main/job-queues/job-queue-base.ts b/plugin-server/src/main/job-queues/job-queue-base.ts index dd357975145..23230827c16 100644 --- a/plugin-server/src/main/job-queues/job-queue-base.ts +++ b/plugin-server/src/main/job-queues/job-queue-base.ts @@ -34,7 +34,6 @@ export class JobQueueBase implements JobQueue { } startConsumer(onJob: OnJobCallback): void - // eslint-disable-next-line @typescript-eslint/require-await async startConsumer(onJob: OnJobCallback): Promise { this.onJob = onJob if (!this.started) { @@ -44,14 +43,12 @@ export class JobQueueBase implements JobQueue { } stopConsumer(): void - // eslint-disable-next-line @typescript-eslint/require-await async stopConsumer(): Promise { this.started = false await this.syncState() } pauseConsumer(): void - // eslint-disable-next-line @typescript-eslint/require-await async pauseConsumer(): Promise { this.paused = true await this.syncState() @@ -62,7 +59,6 @@ export class JobQueueBase implements JobQueue { } resumeConsumer(): void - // eslint-disable-next-line @typescript-eslint/require-await async resumeConsumer(): Promise { if (this.paused) { this.paused = false @@ -80,7 +76,6 @@ export class JobQueueBase implements JobQueue { if (this.timeout) { clearTimeout(this.timeout) } - // eslint-disable-next-line @typescript-eslint/await-thenable const hadSomething = await this.readState() this.timeout = setTimeout(() => this.syncState(), hadSomething ? 0 : this.intervalSeconds * 1000) } else { diff --git a/plugin-server/src/worker/ingestion/event-pipeline/runner.ts b/plugin-server/src/worker/ingestion/event-pipeline/runner.ts index ac460d1fccf..d9b0833bf3e 100644 --- a/plugin-server/src/worker/ingestion/event-pipeline/runner.ts +++ b/plugin-server/src/worker/ingestion/event-pipeline/runner.ts @@ -129,7 +129,7 @@ export class EventPipelineRunner { }) try { // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore + // @ts-expect-error return EVENT_PIPELINE_STEPS[name](this, ...args) } finally { clearTimeout(timeout) diff --git a/plugin-server/tests/shared/process-event.test.ts b/plugin-server/tests/shared/process-event.test.ts index 1c46084b16a..f18c39e5dd6 100644 --- a/plugin-server/tests/shared/process-event.test.ts +++ b/plugin-server/tests/shared/process-event.test.ts @@ -1749,8 +1749,6 @@ describe('when handling $identify', () => { // completing before continuing with the first identify. const originalCreatePerson = hub.db.createPerson.bind(hub.db) const createPersonMock = jest.fn(async (...args) => { - // eslint-disable-next-line - // @ts-ignore const result = await originalCreatePerson(...args) if (createPersonMock.mock.calls.length === 1) { diff --git a/plugin-server/tests/utils.test.ts b/plugin-server/tests/utils.test.ts index 05b7cec326f..92b79de69ac 100644 --- a/plugin-server/tests/utils.test.ts +++ b/plugin-server/tests/utils.test.ts @@ -233,7 +233,7 @@ describe('utils', () => { it('returns the right big integer', () => { const uuid = new UUID('99aBcDeF-1234-4321-0000-dcba87654321') // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore + // @ts-expect-error expect(uuid.valueOf()).toStrictEqual(0x99abcdef123443210000dcba87654321n) }) }) diff --git a/plugin-server/yarn.lock b/plugin-server/yarn.lock index 832a93d5318..046c5afc224 100644 --- a/plugin-server/yarn.lock +++ b/plugin-server/yarn.lock @@ -4564,6 +4564,14 @@ eslint-plugin-es@^3.0.0: eslint-utils "^2.0.0" regexpp "^3.0.0" +eslint-plugin-eslint-comments@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.0.tgz#9e1cd7b4413526abb313933071d7aba05ca12ffa" + integrity sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ== + dependencies: + escape-string-regexp "^1.0.5" + ignore "^5.0.5" + eslint-plugin-import@^2.23.4: version "2.23.4" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.23.4.tgz#8dceb1ed6b73e46e50ec9a5bb2411b645e7d3d97" @@ -5595,6 +5603,11 @@ ignore@^4.0.6: resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== +ignore@^5.0.5: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== + ignore@^5.1.1, ignore@^5.1.4: version "5.1.8" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" diff --git a/yarn.lock b/yarn.lock index 13d8dd01583..efd63697643 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8435,6 +8435,14 @@ eslint-plugin-cypress@^2.11.2: dependencies: globals "^11.12.0" +eslint-plugin-eslint-comments@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.0.tgz#9e1cd7b4413526abb313933071d7aba05ca12ffa" + integrity sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ== + dependencies: + escape-string-regexp "^1.0.5" + ignore "^5.0.5" + eslint-plugin-prettier@^3.1.4: version "3.1.4" resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.4.tgz#168ab43154e2ea57db992a2cd097c828171f75c2" @@ -10033,16 +10041,16 @@ ignore@^4.0.3, ignore@^4.0.6: resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== +ignore@^5.0.5, ignore@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== + ignore@^5.1.4: version "5.1.8" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== -ignore@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" - integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== - image-size@~0.5.0: version "0.5.5" resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c"