Chore: Update eslint configuration (#224)

- Update missing dev dependencies
- Fix root .eslintrc.json and client and server versions
- Add lint.yaml workflow
- Remove babel settings
- Clean up and fix eslint and ts errors
This commit is contained in:
Elisha Nuchi
2024-06-02 18:01:12 -04:00
committed by GitHub
parent a976451c78
commit 85223ca42a
19 changed files with 1411 additions and 594 deletions
+20 -14
View File
@@ -1,31 +1,37 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"extends": [
"airbnb-base",
"plugin:prettier/recommended",
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react-hooks/recommended"
"plugin:@typescript-eslint/recommended"
],
"plugins": ["react-refresh", "prettier"],
"plugins": ["prettier", "googleappsscript"],
"env": {
"googleappsscript/googleappsscript": true
},
"rules": {
"prettier/prettier": "error",
"camelcase": "warn",
"import/prefer-default-export": "warn",
"import/no-extraneous-dependencies": "warn",
"prefer-object-spread": "warn",
"spaced-comment": "off",
"react-refresh/only-export-components": [
"warn",
{ "allowConstantExport": true }
"import/extensions": [
"error",
"ignorePackages",
{
"js": "never",
"ts": "never"
}
]
},
"parserOptions": {
"babelOptions": {
"configFile": "./dev/.babelrc"
}
},
"env": { "browser": true, "es2020": true },
"ignorePatterns": ["dist", ".eslintrc.json"],
"parser": "@typescript-eslint/parser"
"settings": {
"import/resolver": {
"node": {
"extensions": [".js", ".ts"]
}
}
}
}
+18
View File
@@ -0,0 +1,18 @@
name: Lint
on: [push, pull_request]
jobs:
lint:
runs-on: macos-13
timeout-minutes: 8
steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install packages
run: yarn install
- name: Run lint
run: yarn lint
+4 -3
View File
@@ -9,6 +9,7 @@
},
"scripts": {
"dev": "vite",
"lint": "eslint .",
"test:integration": "jest --forceExit test/local-development.test",
"test:integration:extended": "cross-env IS_EXTENDED=true jest --forceExit test/local-development.test",
"test:integration:extended:ci-reporter": "cross-env IS_EXTENDED=true jest --forceExit || node test/utils/image-reporter-standalone.js",
@@ -48,9 +49,7 @@
"react-transition-group": "^4.4.2"
},
"devDependencies": {
"@babel/core": "^7.24.4",
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@babel/preset-env": "^7.24.4",
"@babel/preset-env": "^7.24.6",
"@google/clasp": "^2.4.2",
"@types/expect-puppeteer": "^5.0.0",
"@types/jest-environment-puppeteer": "^5.0.2",
@@ -69,6 +68,7 @@
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-googleappsscript": "^1.0.4",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-jest": "^26.5.3",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-react-hooks": "^4.6.0",
@@ -83,6 +83,7 @@
"puppeteer": "^14.3.0",
"puppeteer-extra": "^3.2.3",
"puppeteer-extra-plugin-stealth": "^2.9.0",
"rollup": "^4.18.0",
"tailwindcss": "^3.4.3",
"typescript": "^5.2.2",
"vite": "^5.2.0",
-8
View File
@@ -1,8 +0,0 @@
{
"presets": ["@babel/react"],
"plugins": [
"@babel/plugin-proposal-object-rest-spread",
"@babel/plugin-proposal-class-properties",
"@babel/plugin-proposal-optional-chaining"
]
}
+12 -21
View File
@@ -1,35 +1,24 @@
{
"root": true,
"parser": "@babel/eslint-parser",
"extends": [
"airbnb-base",
"plugin:prettier/recommended",
"plugin:react/recommended"
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react-hooks/recommended"
],
"plugins": ["babel", "react", "prettier"],
"env": {
"browser": true,
"es6": true
},
"globals": {
"google": false,
"alert": false,
"css": true
},
"parserOptions": {
"ecmaVersion": 9,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"plugins": ["react-refresh", "prettier"],
"rules": {
"prettier/prettier": "error",
"react/prop-types": "warn",
"camelcase": "warn",
"import/prefer-default-export": "warn",
"import/no-extraneous-dependencies": "warn",
"prefer-object-spread": "warn",
"spaced-comment": "off",
"react-refresh/only-export-components": [
"warn",
{ "allowConstantExport": true }
],
"import/extensions": [
"error",
"ignorePackages",
@@ -50,5 +39,7 @@
"extensions": [".js", ".jsx", ".ts", ".tsx"]
}
}
}
},
"env": { "browser": true, "es2020": true },
"parser": "@typescript-eslint/parser"
}
@@ -23,9 +23,7 @@ const FormInput = ({ submitNewSheet }: FormInputProps) => {
};
return (
<form
onSubmit={handleSubmit}
>
<form onSubmit={handleSubmit}>
<Grid container spacing={2}>
<Grid item xs={10}>
<TextField
@@ -4,7 +4,6 @@ import { Button, Typography } from '@mui/material';
import FormInput from './FormInput';
import SheetTable from './SheetTable';
// This is a wrapper for google.script.run that lets us use promises.
import { serverFunctions } from '../../utils/serverFunctions';
@@ -40,29 +39,40 @@ const SheetEditor = () => {
</Typography>
<Typography variant="body1" gutterBottom sx={{ marginBottom: '30px' }}>
This is a sample app that uses the <code>mui</code> library
to help us build a simple React app. Enter a name for a new sheet, hit
enter and the new sheet will be created. Click the red button next to the sheet name to
delete it.
This is a sample app that uses the <code>mui</code> library to help us
build a simple React app. Enter a name for a new sheet, hit enter and
the new sheet will be created. Click the red button next to the sheet
name to delete it.
</Typography>
<FormInput submitNewSheet={submitNewSheet} />
{names.length > 0 &&
<SheetTable rows={names.map((name) => {
return {
sheetName: name.name,
goToButton: <Button
variant="outlined"
disabled={name?.isActive}
onClick={() => setActiveSheet(name.name)}
>Go To Sheet</Button>,
deleteButton: <Button
variant="contained"
color="error"
onClick={() => deleteSheet(name.index)}
>Delete</Button>
}
})} />}
{names.length > 0 && (
<SheetTable
rows={names.map((name) => {
return {
sheetName: name.name,
goToButton: (
<Button
variant="outlined"
disabled={name?.isActive}
onClick={() => setActiveSheet(name.name)}
>
Go To Sheet
</Button>
),
deleteButton: (
<Button
variant="contained"
color="error"
onClick={() => deleteSheet(name.index)}
>
Delete
</Button>
),
};
})}
/>
)}
</div>
);
};
@@ -1,5 +1,12 @@
import * as React from 'react';
import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from '@mui/material';
import {
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
} from '@mui/material';
type sheetRow = {
sheetName: string;
@@ -1,7 +1,11 @@
import { useState, ChangeEvent, FormEvent } from 'react';
import PropTypes from 'prop-types';
const FormInput = ({ submitNewSheet }: { submitNewSheet: Function }) => {
const FormInput = ({
submitNewSheet,
}: {
submitNewSheet: (arg: string) => void;
}) => {
const [inputValue, setInputValue] = useState('');
const handleChange = (event: ChangeEvent<HTMLInputElement>) =>
-18
View File
@@ -1,18 +0,0 @@
{
"presets": [
[
"@babel/env",
{
"modules": false
}
]
],
"plugins": [
"transform-es3-property-literals",
"transform-es3-member-expression-literals",
"@babel/plugin-proposal-class-properties",
"@babel/plugin-proposal-object-rest-spread",
"@babel/plugin-transform-object-assign",
"@babel/plugin-proposal-optional-chaining"
]
}
+16 -3
View File
@@ -1,7 +1,12 @@
{
"root": true,
"parser": "@babel/eslint-parser",
"extends": ["airbnb-base", "plugin:prettier/recommended"],
"parser": "@typescript-eslint/parser",
"extends": [
"airbnb-base",
"plugin:prettier/recommended",
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"plugins": ["prettier", "googleappsscript"],
"env": {
"googleappsscript/googleappsscript": true
@@ -11,7 +16,15 @@
"camelcase": "warn",
"import/prefer-default-export": "warn",
"import/no-extraneous-dependencies": "warn",
"prefer-object-spread": "warn"
"prefer-object-spread": "warn",
"import/extensions": [
"error",
"ignorePackages",
{
"js": "never",
"ts": "never"
}
]
},
"settings": {
"import/resolver": {
+1 -1
View File
@@ -1,3 +1,3 @@
{
"presets": ["@babel/preset-env"]
}
}
+6 -3
View File
@@ -1,12 +1,14 @@
{
"root": true,
"parser": "@babel/eslint-parser",
"parser": "@typescript-eslint/parser",
"extends": [
"airbnb-base",
"plugin:prettier/recommended",
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:jest/recommended"
],
"plugins": ["babel", "prettier"],
"plugins": ["prettier"],
"env": {
"browser": true,
"es6": true,
@@ -27,8 +29,9 @@
"jest/no-done-callback": "off",
"prettier/prettier": "error",
"camelcase": "warn",
"import/prefer-default-export": "warn",
"import/prefer-default-export": "off",
"import/no-extraneous-dependencies": "warn",
"import/extensions": "off",
"jest/expect-expect": "off",
"no-new": "off",
"no-underscore-dangle": "off"
+8 -4
View File
@@ -3,7 +3,6 @@
// This allows using stealth mode.
import fs from 'fs';
const fsPromises = fs.promises;
import os from 'os';
import path from 'path';
import puppeteer from 'puppeteer-extra';
@@ -11,9 +10,11 @@ import puppeteer from 'puppeteer-extra';
// add stealth plugin and use defaults (all evasion techniques)
import StealthPlugin from 'puppeteer-extra-plugin-stealth';
const DIR = path.join(os.tmpdir(), 'jest_puppeteer_global_setup');
import jestPuppeteerConfig from './jest-puppeteer.config.js';
const fsPromises = fs.promises;
const DIR = path.join(os.tmpdir(), 'jest_puppeteer_global_setup');
export default async function globalSetup() {
puppeteer.use(StealthPlugin());
const browser = await puppeteer.launch(jestPuppeteerConfig.launch);
@@ -23,5 +24,8 @@ export default async function globalSetup() {
// use the file system to expose the wsEndpoint for TestEnvironments
await fsPromises.mkdir(DIR, { recursive: true });
await fsPromises.writeFile(path.join(DIR, 'wsEndpoint'), browser.wsEndpoint());
};
await fsPromises.writeFile(
path.join(DIR, 'wsEndpoint'),
browser.wsEndpoint()
);
}
+3 -2
View File
@@ -3,10 +3,11 @@
// This allows using stealth mode.
import fs from 'fs';
const fsPromises = fs.promises;
import os from 'os';
import path from 'path';
const fsPromises = fs.promises;
const DIR = path.join(os.tmpdir(), 'jest_puppeteer_global_setup');
export default async function globalTeardown() {
// close the browser instance
@@ -14,4 +15,4 @@ export default async function globalTeardown() {
// clean-up the wsEndpoint file
await fsPromises.rmdir(DIR, { recursive: true, force: true });
};
}
+4 -2
View File
@@ -2,9 +2,9 @@ import fs from 'fs';
import path from 'path';
import { exec } from 'child_process';
import { configureToMatchImageSnapshot } from 'jest-image-snapshot';
import dotenv from 'dotenv';
import { openAddon } from './utils/open-addon';
import dotenv from 'dotenv';
dotenv.config();
const isExtended = `${process.env.IS_EXTENDED}` === 'true';
@@ -57,7 +57,9 @@ describe(`Local setup ${isExtended ? '*extended*' : ''}`, () => {
if (isExtended) {
await openAddon(page);
} else {
await page.goto('https://localhost:3000/dialog-demo-bootstrap/index.html');
await page.goto(
'https://localhost:3000/dialog-demo-bootstrap/index.html'
);
await page.waitForTimeout(3000);
}
});
+1 -5
View File
@@ -11,10 +11,6 @@ import NodeEnvironment from 'jest-environment-node';
const DIR = path.join(os.tmpdir(), 'jest_puppeteer_global_setup');
export default class PuppeteerEnvironment extends NodeEnvironment.default {
constructor(config) {
super(config);
}
async setup() {
await super.setup();
// get the wsEndpoint
@@ -36,4 +32,4 @@ export default class PuppeteerEnvironment extends NodeEnvironment.default {
getVmContext() {
return super.getVmContext();
}
}
}
+7 -2
View File
@@ -1,3 +1,4 @@
/* eslint-disable import/no-extraneous-dependencies */
import { resolve } from 'path';
import { BuildOptions, ServerOptions, build, defineConfig } from 'vite';
import { existsSync, readFileSync } from 'fs';
@@ -150,7 +151,7 @@ const buildConfig = ({ mode }: { mode: string }) => {
...clientEntrypoints.map((entrypoint) => ({
src: devServerWrapper,
dest: './',
rename: entrypoint.filename + '.html',
rename: `${entrypoint.filename}.html`,
transform: (contents: string) =>
contents
.toString()
@@ -175,16 +176,19 @@ const buildConfig = ({ mode }: { mode: string }) => {
name: 'build-client-production-bundles',
closeBundle: async () => {
console.log('Building client production bundles...');
// eslint-disable-next-line no-restricted-syntax
for (const clientEntrypoint of clientEntrypoints) {
console.log('Building client bundle for', clientEntrypoint.name);
// eslint-disable-next-line no-await-in-loop
const buildOutput = await build(
clientBuildConfig({
clientEntrypointRoot: clientEntrypoint.filename,
template: clientEntrypoint.template,
})
);
// eslint-disable-next-line no-await-in-loop
await writeFile(
resolve(__dirname, outDir, clientEntrypoint.filename + '.html'),
resolve(__dirname, outDir, `${clientEntrypoint.filename}.html`),
// @ts-expect-error - output is an array of RollupOutput
buildOutput.output[0].source
);
@@ -207,4 +211,5 @@ export default async ({ command, mode }: { command: string; mode: string }) => {
// for 'build' mode, we have two paths: build assets for local development, and build for production
return buildConfig({ mode });
}
return {};
};
+1266 -482
View File
File diff suppressed because it is too large Load Diff