diff --git a/.eslintrc.js b/.eslintrc.js index 5a4bfa44890..59061092781 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -157,6 +157,8 @@ module.exports = { 'rulesdir/prettier-comments': 'error', // Enforces clean up of used resources. 'rulesdir/use-using': 'error', + // Enforces consistent file extension + 'rulesdir/extensions': 'error', // Brackets keep code readable. curly: ['error', 'all'], // Brackets keep code readable and `return` intentions clear. diff --git a/packages/puppeteer-core/src/bidi/lifecycle.ts b/packages/puppeteer-core/src/bidi/lifecycle.ts index 5bb52b08e7f..1d0b44fb3b3 100644 --- a/packages/puppeteer-core/src/bidi/lifecycle.ts +++ b/packages/puppeteer-core/src/bidi/lifecycle.ts @@ -19,10 +19,10 @@ import type { ObservableInput, ObservedValueOf, OperatorFunction, -} from '../../third_party/rxjs/rxjs'; -import {catchError} from '../../third_party/rxjs/rxjs'; -import type {PuppeteerLifeCycleEvent} from '../cdp/LifecycleWatcher'; -import {ProtocolError, TimeoutError} from '../common/Errors'; +} from '../../third_party/rxjs/rxjs.js'; +import {catchError} from '../../third_party/rxjs/rxjs.js'; +import type {PuppeteerLifeCycleEvent} from '../cdp/LifecycleWatcher.js'; +import {ProtocolError, TimeoutError} from '../common/Errors.js'; export type BiDiNetworkIdle = Extract< PuppeteerLifeCycleEvent, diff --git a/packages/puppeteer-core/tools/ensure-correct-devtools-protocol-package.ts b/packages/puppeteer-core/tools/ensure-correct-devtools-protocol-package.ts index fcc35e1cb5f..6f17bf71cb4 100644 --- a/packages/puppeteer-core/tools/ensure-correct-devtools-protocol-package.ts +++ b/packages/puppeteer-core/tools/ensure-correct-devtools-protocol-package.ts @@ -33,7 +33,6 @@ * find the one closest to our Chrome revision. */ -// eslint-disable-next-line import/extensions import {execSync} from 'child_process'; import packageJson from '../package.json' assert {type: 'json'}; diff --git a/tools/eslint/src/extensions.ts b/tools/eslint/src/extensions.ts new file mode 100644 index 00000000000..68f236983f3 --- /dev/null +++ b/tools/eslint/src/extensions.ts @@ -0,0 +1,58 @@ +/** + * Copyright 2023 Google Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {ESLintUtils} from '@typescript-eslint/utils'; + +const createRule = ESLintUtils.RuleCreator(name => { + return `https://github.com/puppeteer/puppeteer/tree/main/tools/eslint/${name}.js`; +}); + +const enforceExtensionRule = createRule<[], 'extensionsRule'>({ + name: 'extensions', + meta: { + docs: { + description: 'Requires `.js` for imports', + requiresTypeChecking: false, + }, + messages: { + extensionsRule: 'Add `.js` to import.', + }, + schema: [], + fixable: 'code', + type: 'problem', + }, + defaultOptions: [], + create(context) { + return { + ImportDeclaration(node): void { + const file = node.source.value.split('/').pop(); + + if (!node.source.value.startsWith('.') || file?.includes('.')) { + return; + } + context.report({ + node: node.source, + messageId: 'extensionsRule', + fix(fixer) { + return fixer.replaceText(node.source, `'${node.source.value}.js'`); + }, + }); + }, + }; + }, +}); + +export = enforceExtensionRule;