summaryrefslogtreecommitdiffstats
path: root/remote/test/puppeteer/tools/eslint
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /remote/test/puppeteer/tools/eslint
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'remote/test/puppeteer/tools/eslint')
-rw-r--r--remote/test/puppeteer/tools/eslint/package.json37
-rw-r--r--remote/test/puppeteer/tools/eslint/src/check-license.ts83
-rw-r--r--remote/test/puppeteer/tools/eslint/src/extensions.ts48
-rw-r--r--remote/test/puppeteer/tools/eslint/src/prettier-comments.js99
-rw-r--r--remote/test/puppeteer/tools/eslint/src/use-using.ts85
-rw-r--r--remote/test/puppeteer/tools/eslint/tsconfig.json14
-rw-r--r--remote/test/puppeteer/tools/eslint/tsdoc.json15
7 files changed, 381 insertions, 0 deletions
diff --git a/remote/test/puppeteer/tools/eslint/package.json b/remote/test/puppeteer/tools/eslint/package.json
new file mode 100644
index 0000000000..190367ae43
--- /dev/null
+++ b/remote/test/puppeteer/tools/eslint/package.json
@@ -0,0 +1,37 @@
+{
+ "name": "@puppeteer/eslint",
+ "version": "0.1.0",
+ "private": true,
+ "type": "commonjs",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/puppeteer/puppeteer/tree/main/tools/eslint"
+ },
+ "scripts": {
+ "build": "wireit",
+ "prepare": "wireit"
+ },
+ "wireit": {
+ "build": {
+ "command": "tsc -b",
+ "clean": "if-file-deleted",
+ "files": [
+ "src/**"
+ ],
+ "output": [
+ "lib/**",
+ "tsconfig.tsbuildinfo"
+ ]
+ },
+ "prepare": {
+ "dependencies": [
+ "build"
+ ]
+ }
+ },
+ "author": "The Chromium Authors",
+ "license": "Apache-2.0",
+ "devDependencies": {
+ "@prettier/sync": "0.5.0"
+ }
+}
diff --git a/remote/test/puppeteer/tools/eslint/src/check-license.ts b/remote/test/puppeteer/tools/eslint/src/check-license.ts
new file mode 100644
index 0000000000..7ae1a54384
--- /dev/null
+++ b/remote/test/puppeteer/tools/eslint/src/check-license.ts
@@ -0,0 +1,83 @@
+/**
+ * @license
+ * Copyright 2024 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import type {TSESTree} from '@typescript-eslint/utils';
+import {ESLintUtils} from '@typescript-eslint/utils';
+
+const createRule = ESLintUtils.RuleCreator(name => {
+ return `https://github.com/puppeteer/puppeteer/tree/main/tools/eslint/${name}.ts`;
+});
+
+const copyrightPattern = /Copyright ([0-9]{4}) Google Inc\./;
+
+// const currentYear = new Date().getFullYear;
+
+// const licenseHeader = `/**
+// * @license
+// * Copyright ${currentYear} Google Inc.
+// * SPDX-License-Identifier: Apache-2.0
+// */`;
+
+const enforceLicenseRule = createRule<[], 'licenseRule'>({
+ name: 'check-license',
+ meta: {
+ type: 'layout',
+ docs: {
+ description: 'Validate existence of license header',
+ requiresTypeChecking: false,
+ },
+ fixable: undefined, // TODO: change to 'code' once fixer works.
+ schema: [],
+ messages: {
+ licenseRule: 'Add license header.',
+ },
+ },
+ defaultOptions: [],
+ create(context) {
+ const sourceCode = context.sourceCode;
+ const comments = sourceCode.getAllComments();
+ const header =
+ comments[0]?.type === 'Block' && isHeaderComment(comments[0])
+ ? comments[0]
+ : null;
+
+ function isHeaderComment(comment: TSESTree.Comment) {
+ if (comment && comment.range[0] >= 0 && comment.range[1] <= 88) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ return {
+ Program(node) {
+ if (
+ header &&
+ header.value.includes('@license') &&
+ header.value.includes('SPDX-License-Identifier: Apache-2.0') &&
+ copyrightPattern.test(header.value)
+ ) {
+ return;
+ }
+
+ // Add header license
+ if (!header || !header.value.includes('@license')) {
+ // const startLoc: [number, number] = [0, 88];
+ context.report({
+ node: node,
+ messageId: 'licenseRule',
+ // TODO: fix the fixer.
+ // fix(fixer) {
+ // return fixer.insertTextBeforeRange(startLoc, licenseHeader);
+ // },
+ });
+ }
+ },
+ };
+ },
+});
+
+export = enforceLicenseRule;
diff --git a/remote/test/puppeteer/tools/eslint/src/extensions.ts b/remote/test/puppeteer/tools/eslint/src/extensions.ts
new file mode 100644
index 0000000000..89b9279625
--- /dev/null
+++ b/remote/test/puppeteer/tools/eslint/src/extensions.ts
@@ -0,0 +1,48 @@
+/**
+ * @license
+ * Copyright 2023 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+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;
diff --git a/remote/test/puppeteer/tools/eslint/src/prettier-comments.js b/remote/test/puppeteer/tools/eslint/src/prettier-comments.js
new file mode 100644
index 0000000000..3cbaad2909
--- /dev/null
+++ b/remote/test/puppeteer/tools/eslint/src/prettier-comments.js
@@ -0,0 +1,99 @@
+/**
+ * @license
+ * Copyright 2023 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+// @ts-nocheck
+// TODO: We should convert this to types.
+
+const prettier = require('@prettier/sync');
+
+const prettierConfigPath = '../../../.prettierrc.cjs';
+const prettierConfig = require(prettierConfigPath);
+
+const cleanupBlockComment = value => {
+ return value
+ .trim()
+ .split('\n')
+ .map(value => {
+ value = value.trim();
+ if (value.startsWith('*')) {
+ value = value.slice(1);
+ if (value.startsWith(' ')) {
+ value = value.slice(1);
+ }
+ }
+ return value.trimEnd();
+ })
+ .join('\n')
+ .trim();
+};
+
+const format = (value, offset) => {
+ return prettier
+ .format(value, {
+ ...prettierConfig,
+ parser: 'markdown',
+ // This is the print width minus 3 (the length of ` * `) and the offset.
+ printWidth: 80 - (offset + 3),
+ })
+ .trim();
+};
+
+const buildBlockComment = (value, offset) => {
+ const spaces = ' '.repeat(offset);
+ const lines = value.split('\n').map(line => {
+ return ` * ${line}`;
+ });
+ lines.unshift('/**');
+ lines.push(' */');
+ lines.forEach((line, i) => {
+ lines[i] = `${spaces}${line}`;
+ });
+ return lines.join('\n');
+};
+
+/**
+ * @type import("eslint").Rule.RuleModule
+ */
+const prettierCommentsRule = {
+ meta: {
+ type: 'suggestion',
+ docs: {
+ description: 'Enforce Prettier formatting on comments',
+ recommended: false,
+ },
+ fixable: 'code',
+ schema: [],
+ messages: {},
+ },
+
+ create(context) {
+ for (const comment of context.sourceCode.getAllComments()) {
+ switch (comment.type) {
+ case 'Block': {
+ const offset = comment.loc.start.column;
+ const value = cleanupBlockComment(comment.value);
+ const formattedValue = format(value, offset);
+ if (formattedValue !== value) {
+ context.report({
+ node: comment,
+ message: `Comment is not formatted correctly.`,
+ fix(fixer) {
+ return fixer.replaceText(
+ comment,
+ buildBlockComment(formattedValue, offset).trimStart()
+ );
+ },
+ });
+ }
+ break;
+ }
+ }
+ }
+ return {};
+ },
+};
+
+module.exports = prettierCommentsRule;
diff --git a/remote/test/puppeteer/tools/eslint/src/use-using.ts b/remote/test/puppeteer/tools/eslint/src/use-using.ts
new file mode 100644
index 0000000000..0c727a4334
--- /dev/null
+++ b/remote/test/puppeteer/tools/eslint/src/use-using.ts
@@ -0,0 +1,85 @@
+/**
+ * @license
+ * Copyright 2023 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import {ESLintUtils, TSESTree} from '@typescript-eslint/utils';
+
+const usingSymbols = ['ElementHandle', 'JSHandle'];
+
+const createRule = ESLintUtils.RuleCreator(name => {
+ return `https://github.com/puppeteer/puppeteer/tree/main/tools/eslint/${name}.js`;
+});
+
+const useUsingRule = createRule<[], 'useUsing' | 'useUsingFix'>({
+ name: 'use-using',
+ meta: {
+ docs: {
+ description: "Requires 'using' for element/JS handles.",
+ requiresTypeChecking: true,
+ },
+ hasSuggestions: true,
+ messages: {
+ useUsing: "Use 'using'.",
+ useUsingFix: "Replace with 'using' to ignore.",
+ },
+ schema: [],
+ type: 'problem',
+ },
+ defaultOptions: [],
+ create(context) {
+ const services = ESLintUtils.getParserServices(context);
+ const checker = services.program.getTypeChecker();
+
+ return {
+ VariableDeclaration(node): void {
+ if (['using', 'await using'].includes(node.kind) || node.declare) {
+ return;
+ }
+ for (const declaration of node.declarations) {
+ if (declaration.id.type === TSESTree.AST_NODE_TYPES.Identifier) {
+ const tsNode = services.esTreeNodeToTSNodeMap.get(declaration.id);
+ const type = checker.getTypeAtLocation(tsNode);
+ let isElementHandleReference = false;
+ if (type.isUnionOrIntersection()) {
+ for (const member of type.types) {
+ if (
+ member.symbol !== undefined &&
+ usingSymbols.includes(member.symbol.escapedName as string)
+ ) {
+ isElementHandleReference = true;
+ break;
+ }
+ }
+ } else {
+ isElementHandleReference =
+ type.symbol !== undefined
+ ? usingSymbols.includes(type.symbol.escapedName as string)
+ : false;
+ }
+ if (isElementHandleReference) {
+ context.report({
+ node: declaration.id,
+ messageId: 'useUsing',
+ suggest: [
+ {
+ messageId: 'useUsingFix',
+ fix(fixer) {
+ return fixer.replaceTextRange(
+ [node.range[0], node.range[0] + node.kind.length],
+ 'using'
+ );
+ },
+ },
+ ],
+ });
+ }
+ }
+ }
+ },
+ };
+ },
+});
+
+export = useUsingRule;
diff --git a/remote/test/puppeteer/tools/eslint/tsconfig.json b/remote/test/puppeteer/tools/eslint/tsconfig.json
new file mode 100644
index 0000000000..da26cc936b
--- /dev/null
+++ b/remote/test/puppeteer/tools/eslint/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": {
+ "module": "NodeNext",
+ "moduleResolution": "NodeNext",
+ "rootDir": "./src",
+ "outDir": "./lib",
+ "declaration": false,
+ "declarationMap": false,
+ "sourceMap": false,
+ "composite": false,
+ "removeComments": true,
+ },
+}
diff --git a/remote/test/puppeteer/tools/eslint/tsdoc.json b/remote/test/puppeteer/tools/eslint/tsdoc.json
new file mode 100644
index 0000000000..f5b91f4af6
--- /dev/null
+++ b/remote/test/puppeteer/tools/eslint/tsdoc.json
@@ -0,0 +1,15 @@
+{
+ "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json",
+
+ "extends": ["@microsoft/api-extractor/extends/tsdoc-base.json"],
+ "tagDefinitions": [
+ {
+ "tagName": "@license",
+ "syntaxKind": "modifier",
+ "allowMultiple": false
+ }
+ ],
+ "supportForTags": {
+ "@license": true
+ }
+}