From 9b8f01716774a960073e944823ab727cc867a8f6 Mon Sep 17 00:00:00 2001 From: MCMXC <16797721+mcmxcdev@users.noreply.github.com> Date: Wed, 26 Jul 2023 06:29:03 -0600 Subject: chore: improve lint setup (#397) - update eslint config to closely mirror the ones from ferdium-app - add .eslintignore - opt in to eslint `reportUnusedDisableDirectives` config option - remove `trailingComma: all` from `prettier` config which is default in `prettier` v3 - autofix or disable a lot of lint issues throughout codebase - add `volta` configuration to `package.json` to autoload correct `node` and `pnpm` versions - upgrade all `eslint` and `prettier` related dependencies to latest - update lint:fix npm script - reformat touched files with prettier - bumped up minor version for all recipes that have changes - introduced injection of 'service.css' where it was missing in many recipes --------- Co-authored-by: Vijay A --- scripts/create.js | 31 +++++++++++++--------------- scripts/package.js | 44 +++++++++++++++++++++++----------------- scripts/sample_recipe/webview.js | 4 ++-- 3 files changed, 41 insertions(+), 38 deletions(-) (limited to 'scripts') diff --git a/scripts/create.js b/scripts/create.js index 199a23b..158b2f2 100644 --- a/scripts/create.js +++ b/scripts/create.js @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ /** * Create a new recipe for your service */ @@ -18,19 +19,15 @@ pnpm create WhatsApp FerdiumDev } const recipeName = process.argv[2]; -const recipe = recipeName.toLowerCase().replace(/\s/g, '-'); +const recipe = recipeName.toLowerCase().replaceAll(/\s/g, '-'); const folderName = process.argv[3] || 'Ferdium'; -const filesThatNeedTextReplace = [ - 'package.json', - 'index.js', - 'webview.js', -]; +const filesThatNeedTextReplace = ['package.json', 'index.js', 'webview.js']; -const toPascalCase = (str) => { +const toPascalCase = str => { const words = str - .replace(/[^a-z]/g, '') + .replaceAll(/[^a-z]/g, '') .split(/\W/) - .map((word) => { + .map(word => { if (word.length === 0) { return word; } @@ -38,16 +35,16 @@ const toPascalCase = (str) => { return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(); }); return words.join(''); -} +}; const pascalCasedName = toPascalCase(recipe); // PascalCased recipe ID only containing a-z, for usage as the JavaScript class name (async () => { // Folder paths const userData = process.env.APPDATA || - (process.platform == 'darwin' - ? process.env.HOME + '/Library/Application Support' - : process.env.HOME + '/.config'); + (process.platform === 'darwin' + ? `${process.env.HOME}/Library/Application Support` + : `${process.env.HOME}/.config`); const recipesFolder = path.join(userData, folderName, 'recipes'); const devRecipeFolder = path.join(recipesFolder, 'dev'); const newRecipeFolder = path.join(devRecipeFolder, recipe); @@ -60,7 +57,7 @@ const pascalCasedName = toPascalCase(recipe); // PascalCased recipe ID only cont ); return; } - await fs.ensureDir(devRecipeFolder); + fs.ensureDirSync(devRecipeFolder); if (fs.existsSync(newRecipeFolder)) { console.log('⚠️ Recipe already exists'); @@ -70,17 +67,17 @@ const pascalCasedName = toPascalCase(recipe); // PascalCased recipe ID only cont console.log('[Info] Passed pre-checks'); // Copy sample recipe to recipe folder - await fs.copy(sampleRecipe, newRecipeFolder); + fs.copySync(sampleRecipe, newRecipeFolder); console.log('[Info] Copied recipe'); // Replace placeholders with the recipe-specific values for (const file of filesThatNeedTextReplace) { const filePath = path.join(newRecipeFolder, file); - let contents = await fs.readFile(filePath, 'utf8'); + let contents = fs.readFileSync(filePath, 'utf8'); contents = contents.replace(/SERVICE/g, recipe); contents = contents.replace(/SNAME/g, recipeName); contents = contents.replace(/SPASCAL/g, pascalCasedName); - await fs.writeFile(filePath, contents); + fs.writeFileSync(filePath, contents); } console.log('[Info] Prepared new recipe'); diff --git a/scripts/package.js b/scripts/package.js index e1e3d5c..0482775 100644 --- a/scripts/package.js +++ b/scripts/package.js @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ /** * Package all recipes */ @@ -6,7 +7,8 @@ const fs = require('fs-extra'); const path = require('path'); const sizeOf = require('image-size'); const simpleGit = require('simple-git'); -const pkgVersionChangedMatcher = new RegExp(/\n\+.*version.*/); + +const pkgVersionChangedMatcher = /\n\+.*version.*/; // Publicly availible link to this repository's recipe folder // Used for generating public icon URLs @@ -21,7 +23,7 @@ const compress = (src, dest) => dest, tar: { // Don't package .DS_Store files and .md files - ignore: function (name) { + ignore(name) { return path.basename(name) === '.DS_Store' || name.endsWith('.md'); }, }, @@ -63,18 +65,19 @@ const compress = (src, dest) => .filter(dir => dir.isDirectory()) .map(dir => dir.name); - for (let recipe of availableRecipes) { + for (const recipe of availableRecipes) { const recipeSrc = path.join(recipesFolder, recipe); const mandatoryFiles = ['package.json', 'icon.svg', 'webview.js']; // Check that each mandatory file exists - for (let file of mandatoryFiles) { + for (const file of mandatoryFiles) { const filePath = path.join(recipeSrc, file); + // eslint-disable-next-line no-await-in-loop if (!(await fs.pathExists(filePath))) { console.log( `⚠️ Couldn't package "${recipe}": Folder doesn't contain a "${file}".`, ); - unsuccessful++; + unsuccessful += 1; } } if (unsuccessful > 0) { @@ -89,22 +92,24 @@ const compress = (src, dest) => console.log( `⚠️ Couldn't package "${recipe}": Recipe SVG icon isn't a square`, ); - unsuccessful++; + unsuccessful += 1; continue; } // Check that user.js does not exist const userJs = path.join(recipeSrc, 'user.js'); + // eslint-disable-next-line no-await-in-loop if (await fs.pathExists(userJs)) { console.log( `⚠️ Couldn't package "${recipe}": Folder contains a "user.js".`, ); - unsuccessful++; + unsuccessful += 1; continue; } // Read package.json const packageJson = path.join(recipeSrc, 'package.json'); + // eslint-disable-next-line no-await-in-loop const config = await fs.readJson(packageJson); // Make sure it contains all required fields @@ -112,10 +117,10 @@ const compress = (src, dest) => console.log( `⚠️ Couldn't package "${recipe}": Could not read or parse "package.json"`, ); - unsuccessful++; + unsuccessful += 1; continue; } - let configErrors = []; + const configErrors = []; if (!config.id) { configErrors.push( "The recipe's package.json contains no 'id' field. This field should contain a unique ID made of lowercase letters (a-z), numbers (0-9), hyphens (-), periods (.), and underscores (_)", @@ -227,6 +232,7 @@ const compress = (src, dest) => const relativeRepoSrc = path.relative(repoRoot, recipeSrc); // Check for changes in recipe's directory, and if changes are present, then the changes should contain a version bump + // eslint-disable-next-line no-await-in-loop await git.diffSummary(relativeRepoSrc, (err, result) => { if (err) { configErrors.push( @@ -239,11 +245,7 @@ const compress = (src, dest) => result.deletions !== 0) ) { const pkgJsonRelative = path.relative(repoRoot, packageJson); - if (!result.files.some(({ file }) => file === pkgJsonRelative)) { - configErrors.push( - `Found changes in '${relativeRepoSrc}' without the corresponding version bump in '${pkgJsonRelative}'`, - ); - } else { + if (result.files.some(({ file }) => file === pkgJsonRelative)) { git.diff(pkgJsonRelative, (_diffErr, diffResult) => { if (diffResult && !pkgVersionChangedMatcher.test(diffResult)) { configErrors.push( @@ -251,6 +253,10 @@ const compress = (src, dest) => ); } }); + } else { + configErrors.push( + `Found changes in '${relativeRepoSrc}' without the corresponding version bump in '${pkgJsonRelative}'`, + ); } } }); @@ -259,14 +265,14 @@ const compress = (src, dest) => if (configErrors.length > 0) { console.log(`⚠️ Couldn't package "${recipe}": There were errors in the recipe's package.json: ${configErrors.reduce((str, err) => `${str}\n${err}`)}`); - unsuccessful++; + unsuccessful += 1; } if (!fs.existsSync(path.join(recipeSrc, 'index.js'))) { console.log( `⚠️ Couldn't package "${recipe}": The recipe doesn't contain a "index.js"`, ); - unsuccessful++; + unsuccessful += 1; } // Package to .tar.gz @@ -289,9 +295,9 @@ const compress = (src, dest) => // Sort package list alphabetically recipeList = recipeList.sort((a, b) => { - let textA = a.id.toLowerCase(); - let textB = b.id.toLowerCase(); - return textA < textB ? -1 : (textA > textB ? 1 : 0); + const textA = a.id.toLowerCase(); + const textB = b.id.toLowerCase(); + return textA < textB ? -1 : textA > textB ? 1 : 0; }); await fs.writeJson(allJson, recipeList, { spaces: 2, diff --git a/scripts/sample_recipe/webview.js b/scripts/sample_recipe/webview.js index 86bb422..2a81dec 100644 --- a/scripts/sample_recipe/webview.js +++ b/scripts/sample_recipe/webview.js @@ -1,9 +1,9 @@ -const _path = _interopRequireDefault(require('path')); - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +const _path = _interopRequireDefault(require('path')); + module.exports = Ferdium => { // TODO: If your SNAME service has unread messages, uncomment these lines to implement the logic for updating the badges // const getMessages = () => { -- cgit v1.2.3-54-g00ecf