diff --git a/package-lock.json b/package-lock.json index de6ded304..0980d3750 100644 --- a/package-lock.json +++ b/package-lock.json @@ -252,10 +252,9 @@ } }, "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -265,7 +264,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -274,7 +272,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "requires": { "color-name": "~1.1.4" } @@ -282,20 +279,17 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -510,6 +504,57 @@ "table": "^5.2.3", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "eslint-config-airbnb-base": { diff --git a/package.json b/package.json index 4ff2e196b..bde78ca06 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,11 @@ { "name": "tdarr_plugins", "version": "1.0.0", - "description": "There are two types of plugin:", - "main": "Tdarr_Plugin_aaaa_Pre_Proc_Example.js", - "dependencies": {}, + "description": "Tdar Plugins Repo", + "main": "", + "dependencies": { + "chalk": "^4.1.2" + }, "devDependencies": { "chai": "^4.3.6", "eslint": "^7.14.0", diff --git a/tests/checkPlugins.js b/tests/checkPlugins.js index 725531a71..13bab9d25 100644 --- a/tests/checkPlugins.js +++ b/tests/checkPlugins.js @@ -1,12 +1,16 @@ /* eslint no-console: 0 */ // --> OFF +/* eslint max-len: 0 */ const fs = require('fs'); +const chalk = require('chalk'); const folders = [ './Community', './examples', ]; +let errorEncountered = false; + folders.forEach((folder) => { const files = fs.readdirSync(folder).filter((row) => row.includes('.js')); @@ -28,16 +32,16 @@ folders.forEach((folder) => { const importLib = 'const lib = require(\'../methods/lib\')();'; if (!read.includes(importLib)) { - console.log(`Plugin error: '${folder}/${files[i]}' does not contain ${importLib}`); + console.log(chalk.red(`Plugin error: '${folder}/${files[i]}' does not contain ${importLib}`)); read = `${importLib}\n${read}`; // fs.writeFileSync(`${folder}/${files[i]}`, read) - process.exit(1); + errorEncountered = true; } const detailsText = 'const details = () =>'; if (!read.includes(detailsText)) { - console.log(`Plugin error: '${folder}/${files[i]}' does not contain ${detailsText}`); - process.exit(1); + console.log(chalk.red(`Plugin error: '${folder}/${files[i]}' does not contain ${detailsText}`)); + errorEncountered = true; } const syncText = 'const plugin = (file, librarySettings, inputs, otherArguments) => {'; @@ -46,27 +50,27 @@ folders.forEach((folder) => { if (!read.includes(syncText) && !read.includes(asyncText) ) { - console.log(`Plugin error: '${folder}/${files[i]}' does not contain ${syncText} or ${asyncText}`); - process.exit(1); + console.log(chalk.red(`Plugin error: '${folder}/${files[i]}' does not contain ${syncText} or ${asyncText}`)); + errorEncountered = true; } const inputsText = 'inputs = lib.loadDefaultValues(inputs, details);'; if (!read.includes(inputsText) ) { - console.log(`Plugin error: '${folder}/${files[i]}' does not contain ${inputsText}`); - process.exit(1); + console.log(chalk.red(`Plugin error: '${folder}/${files[i]}' does not contain ${inputsText}`)); + errorEncountered = true; } const exportText = `module.exports.details = details; module.exports.plugin = plugin;`; if (!read.includes(exportText)) { - console.log(`Plugin error: '${folder}/${files[i]}' does not contain ${exportText}`); + console.log(chalk.red(`Plugin error: '${folder}/${files[i]}' does not contain ${exportText}`)); read = read.replace('module.exports.details = details;', ''); read = read.replace('module.exports.plugin = plugin;', ''); read += `\n${exportText}`; // fs.writeFileSync(`${folder}/${files[i]}`, read) - process.exit(1); + errorEncountered = true; } // check deps are within functions @@ -80,8 +84,8 @@ module.exports.plugin = plugin;`; const countOpen = allBefore.join(keyWord).split('{').length - 1; const countClose = allBefore.join(keyWord).split('}').length - 1; if (countOpen === countClose) { - console.log(`Plugin has requires outside of function '${folder}/${files[i]}'`); - process.exit(1); + console.log(chalk.red(`Plugin has requires outside of function '${folder}/${files[i]}'`)); + errorEncountered = true; } } } @@ -91,64 +95,66 @@ module.exports.plugin = plugin;`; // eslint-disable-next-line import/no-dynamic-require,global-require pluginDetails = require(`.${folder}/${files[i]}`).details(); } catch (err) { - console.log(err.message); - process.exit(1); + console.log(chalk.red(err.message)); + errorEncountered = true; } const detailsKeys = Object.keys(pluginDetails); + // eslint-disable-next-line no-loop-func detailsOrder.forEach((detail) => { if (detailsKeys.indexOf(detail) === -1) { - console.log(`Plugin details is missing '${folder}/${files[i]}' : ${detail}`); - process.exit(1); + console.log(chalk.red(`Plugin details is missing '${folder}/${files[i]}' : ${detail}`)); + errorEncountered = true; } }); + // eslint-disable-next-line no-loop-func detailsKeys.forEach((detail, index) => { if (detailsOrder[index] !== detail) { - console.log(`Plugin details keys are not in the correct order: '${folder}/${files[i]}' ${detail}`); - process.exit(1); + console.log(chalk.red(`Plugin details keys are not in the correct order: '${folder}/${files[i]}' ${detail}`)); + errorEncountered = true; } }); if (detailsKeys.length < detailsOrder.length) { - console.log(`Plugin details are too few '${folder}/${files[i]}'`); - process.exit(1); + console.log(chalk.red(`Plugin details are too few '${folder}/${files[i]}'`)); + errorEncountered = true; } if (!['Pre-processing', 'Post-processing'].includes(pluginDetails.Stage)) { - console.log(`Plugin does not have a valid Type'${folder}/${files[i]}'`); - process.exit(1); + console.log(chalk.red(`Plugin does not have a valid Type'${folder}/${files[i]}'`)); + errorEncountered = true; } if (!['Video', 'Audio', 'Subtitle', 'Any'].includes(pluginDetails.Type)) { - console.log(`Plugin does not have a valid Type'${folder}/${files[i]}'`); - process.exit(1); + console.log(chalk.red(`Plugin does not have a valid Type'${folder}/${files[i]}'`)); + errorEncountered = true; } if (files[i].split('.js').join('') !== pluginDetails.id) { - console.log(`Plugin file name does not match details id'${folder}/${files[i]}'`); - process.exit(1); + console.log(chalk.red(`Plugin file name does not match details id'${folder}/${files[i]}'`)); + errorEncountered = true; } if (!['Transcode', 'Filter'].includes(pluginDetails.Operation)) { - console.log(`Plugin does not have a valid Operation '${folder}/${files[i]}'`); - process.exit(1); + console.log(chalk.red(`Plugin does not have a valid Operation '${folder}/${files[i]}'`)); + errorEncountered = true; } else if (detailsKeys.length > detailsOrder.length) { - console.log(`Plugin details are too many '${folder}/${files[i]}'`); - process.exit(1); + console.log(chalk.red(`Plugin details are too many '${folder}/${files[i]}'`)); + errorEncountered = true; } else if (pluginDetails.Inputs && !Array.isArray(pluginDetails.Inputs)) { // Check default values are set; - console.log(`Plugin Inputs is not an array: ${files[i]}`); - process.exit(1); + console.log(chalk.red(`Plugin Inputs is not an array: ${files[i]}`)); + errorEncountered = true; } else if (pluginDetails.Inputs && Array.isArray(pluginDetails.Inputs)) { const inputs = pluginDetails.Inputs; const savedInputs = {}; for (let j = 0; j < inputs.length; j += 1) { // Prevent duplicate plugin inputs if (savedInputs[inputs[j].name] === true) { - console.log(`Plugin Input already exists: '${folder}/${files[i]}' : ${inputs[j].name}`); - process.exit(1); + console.log(chalk.red(`Plugin Input already exists: '${folder}/${files[i]}' : ${inputs[j].name}`)); + errorEncountered = true; } else { savedInputs[inputs[j].name] = true; } @@ -161,31 +167,31 @@ module.exports.plugin = plugin;`; || inputKeys[3] !== 'inputUI' || inputKeys[4] !== 'tooltip' ) { - console.log(`Plugin Input keys are not in correct order: '${folder}/${files[i]}' : ${inputs[j].name}`); - process.exit(1); + console.log(chalk.red(`Plugin Input keys are not in correct order: '${folder}/${files[i]}' : ${inputs[j].name}`)); + errorEncountered = true; } else if (inputs[j].type === undefined || !pluginInputTypes.includes(inputs[j].type)) { - console.log(`Plugin Input does not have a type: '${folder}/${files[i]}' : ${inputs[j].name}`); - process.exit(1); + console.log(chalk.red(`Plugin Input does not have a type: '${folder}/${files[i]}' : ${inputs[j].name}`)); + errorEncountered = true; } else if ( (inputs[j].type === 'string' && typeof inputs[j].defaultValue !== 'string') || (inputs[j].type === 'number' && typeof inputs[j].defaultValue !== 'number') || (inputs[j].type === 'boolean' && typeof inputs[j].defaultValue !== 'boolean') ) { - console.log(`Plugin Input type does not match defaultValue type: - '${folder}/${files[i]}' : ${inputs[j].name}`); - process.exit(1); + console.log(chalk.red(`Plugin Input type does not match defaultValue type: + '${folder}/${files[i]}' : ${inputs[j].name}`)); + errorEncountered = true; } else if (!['text', 'dropdown'].includes(inputs[j].inputUI.type)) { - console.log(`Plugin Input inputUI is invalid: '${folder}/${files[i]}' : ${inputs[j].name}`); - process.exit(1); + console.log(chalk.red(`Plugin Input inputUI is invalid: '${folder}/${files[i]}' : ${inputs[j].name}`)); + errorEncountered = true; } else if (inputs[j].defaultValue === undefined) { - console.log(`Plugin Input does not have a default value: '${folder}/${files[i]}' : ${inputs[j].name}`); - process.exit(1); + console.log(chalk.red(`Plugin Input does not have a default value: '${folder}/${files[i]}' : ${inputs[j].name}`)); + errorEncountered = true; } const count = read.split(inputs[j].name).length - 1; if (count === 1) { - console.log(`Plugin Input is not used: '${folder}/${files[i]}' : ${inputs[j].name}`); - process.exit(1); + console.log(chalk.red(`Plugin Input is not used: '${folder}/${files[i]}' : ${inputs[j].name}`)); + errorEncountered = true; } } } @@ -195,3 +201,8 @@ module.exports.plugin = plugin;`; }); console.log('Done!'); + +if (errorEncountered) { + console.log('Errors encountered'); + process.exit(1); +}