Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

npm-package-json-lint

Package Overview
Dependencies
Maintainers
1
Versions
90
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

npm-package-json-lint - npm Package Compare versions

Comparing version 3.7.0 to 4.0.0-beta.1

src/config/applyExtendsIfSpecified.js

33

CHANGELOG.md

@@ -7,9 +7,42 @@ # Change Log

### Added
- Added exception support to the following rules:
- [`no-absolute-version-dependencies`](https://github.com/tclindner/npm-package-json-lint/wiki/no-absolute-version-dependencies)
- [`no-absolute-version-devDependencies`](https://github.com/tclindner/npm-package-json-lint/wiki/no-absolute-version-devDependencies)
- [`no-caret-version-dependencies`](https://github.com/tclindner/npm-package-json-lint/wiki/no-caret-version-dependencies)
- [`no-caret-version-devDependencies`](https://github.com/tclindner/npm-package-json-lint/wiki/no-caret-version-devDependencies)
- [`no-tilde-version-dependencies`](https://github.com/tclindner/npm-package-json-lint/wiki/no-tilde-version-dependencies)
- [`no-tilde-version-devDependencies`](https://github.com/tclindner/npm-package-json-lint/wiki/no-tilde-version-devDependencies)
- [`prefer-absolute-version-dependencies`](https://github.com/tclindner/npm-package-json-lint/wiki/prefer-absolute-version-dependencies)
- [`prefer-absolute-version-devDependencies`](https://github.com/tclindner/npm-package-json-lint/wiki/prefer-absolute-version-devDependencies)
- [`prefer-caret-version-dependencies`](https://github.com/tclindner/npm-package-json-lint/wiki/prefer-caret-version-dependencies)
- [`prefer-caret-version-devDependencies`](https://github.com/tclindner/npm-package-json-lint/wiki/prefer-caret-version-devDependencies)
- [`prefer-no-version-zero-dependencies`](https://github.com/tclindner/npm-package-json-lint/wiki/prefer-no-version-zero-dependencies)
- [`prefer-no-version-zero-devDependencies`](https://github.com/tclindner/npm-package-json-lint/wiki/prefer-no-version-zero-devDependencies)
- [`prefer-tilde-version-dependencies`](https://github.com/tclindner/npm-package-json-lint/wiki/prefer-tilde-version-dependencies)
- [`prefer-tilde-version-devDependencies`](https://github.com/tclindner/npm-package-json-lint/wiki/prefer-tilde-version-devDependencies)
> Addresses [#93](https://github.com/tclindner/npm-package-json-lint/issues/93)
### Changed
- [`name-format`](https://github.com/tclindner/npm-package-json-lint/wiki/name-format) now checks the following things:
- Name is lowercase
- Name is less than 214 characters. This includes scope.
- Name doesn't start with a `.` or a `_`.
> Addresses [#115](https://github.com/tclindner/npm-package-json-lint/issues/115)
- Improved schema validation that runs against npm-package-json-lint config files. Highlights include:
- Better error messages. Ex: `- severity must be either "off", "warning", or "error".`
- Array type rules now ensure at least one item is passed.
- Array type rules now validate unique items are passed.
### Fixed
### Removed
- Dropped support for Node 6 and 7.
## [3.7.0] - 2019-06-16

@@ -16,0 +49,0 @@ ### Added

9

CONTRIBUTING.md

@@ -7,4 +7,4 @@ # Contributing

* [Node.js](https://nodejs.org/) - v6.0.0+
* [npm](https://www.npmjs.com/) - v3.0.0+
* [Node.js](https://nodejs.org/) - v8.0.0+
* [npm](https://www.npmjs.com/) - v6.0.0+

@@ -17,2 +17,7 @@ ## Install project dependencies

#### Branches
* Use the `v3.x.x` branch for fixes to v3.
* Use `master` for new enhancements and breaking changes for v4.
### Install project dependencies

@@ -19,0 +24,0 @@

{
"name": "npm-package-json-lint",
"version": "3.7.0",
"version": "4.0.0-beta.1",
"description": "Configurable linter for package.json files.",

@@ -32,3 +32,4 @@ "keywords": [

"eslint": "eslint . --format=node_modules/eslint-formatter-pretty",
"lint": "npm run eslint",
"npmpackagejsonlint": "node src/cli.js .",
"lint": "npm run eslint && npm run npmpackagejsonlint",
"test": "jest",

@@ -39,31 +40,32 @@ "test:ci": "jest --runInBand"

"ajv": "^6.10.0",
"ajv-errors": "^1.0.1",
"chalk": "^2.4.2",
"glob": "^7.1.4",
"cosmiconfig": "^5.2.1",
"debug": "^4.1.1",
"globby": "^10.0.1",
"ignore": "^5.1.2",
"is-path-inside": "^2.1.0",
"is-plain-obj": "^1.1.0",
"is-resolvable": "^1.1.0",
"log-symbols": "^2.2.0",
"is-plain-obj": "^2.0.0",
"log-symbols": "^3.0.0",
"meow": "^5.0.0",
"plur": "^3.1.1",
"semver": "^5.6.0",
"strip-json-comments": "^2.0.1",
"validator": "^10.11.0"
"semver": "^6.1.1",
"strip-json-comments": "^3.0.1"
},
"devDependencies": {
"eslint": "^5.16.0",
"eslint-config-tc": "^6.4.0",
"eslint-config-tc": "^6.5.0",
"eslint-formatter-pretty": "^2.1.1",
"eslint-plugin-import": "^2.17.3",
"eslint-plugin-prettier": "^3.1.0",
"figures": "^2.0.0",
"figures": "^3.0.0",
"jest": "^24.8.0",
"npm-package-json-lint-config-default": "^2.0.0",
"npm-package-json-lint-config-tc": "^2.2.0",
"prettier": "^1.18.2"
},
"engines": {
"node": ">=6.0.0",
"npm": ">=3.0.0"
"node": ">=8.0.0",
"npm": ">=6.0.0"
},
"license": "MIT"
}

@@ -35,4 +35,4 @@ # npm-package-json-lint

* [Node.js](https://nodejs.org/) - v6.0.0+
* [npm](http://npmjs.com) - v3.0.0+
* [Node.js](https://nodejs.org/) - v8.0.0+
* [npm](http://npmjs.com) - v6.0.0+

@@ -39,0 +39,0 @@ ### Use the cli

@@ -1,6 +0,5 @@

/* eslint global-require: 'off' */
const NpmPackageJsonLint = require('./NpmPackageJsonLint');
module.exports = {
NpmPackageJsonLint: require('./NpmPackageJsonLint'),
CLIEngine: require('./CLIEngine')
NpmPackageJsonLint
};
#!/usr/bin/env node
const chalk = require('chalk');
const debug = require('debug')('npm-package-json-lint:cli');
const meow = require('meow');
const CLIEngine = require('./CLIEngine');
const NpmPackageJsonLint = require('./NpmPackageJsonLint');
const Reporter = require('./Reporter');

@@ -12,3 +13,4 @@

twoLintErrorsDetected: 2,
runTimeException: 3
runTimeException: 3,
exceedMaxWarnings: 4
};

@@ -27,2 +29,3 @@

--ignorePath, -i Path to a file containing patterns that describe files to ignore. The path can be absolute or relative to process.cwd(). By default, npm-package-json-lint looks for .npmpackagejsonlintignore in process.cwd().
--maxWarnings, -mw Maximum number of warnings that can be detected before an error is thrown.

@@ -40,2 +43,4 @@ Examples

$ npmPkgJsonLint . -i .gitignore
$ npmPkgJsonLint . --maxWarnings 10
$ npmPkgJsonLint . -mw 10
`,

@@ -63,2 +68,7 @@ {

default: ''
},
maxWarnings: {
type: 'number',
alias: 'mw',
default: 10000000
}

@@ -75,3 +85,6 @@ }

debug(`patterns: ${patterns}`);
if (patterns.length === noPatternsProvided) {
debug(`No lint targets provided`);
console.log(chalk.red.bold('No lint targets provided'));

@@ -81,11 +94,2 @@ process.exit(exitCodes.oneMissingTarget);

// CLIEngine Options
const cliEngineOptions = {
configFile: cli.flags.configFile,
cwd: process.cwd(),
useConfigFiles: !cli.flags.noConfigFiles,
ignorePath: cli.flags.ignorePath,
rules: {}
};
try {

@@ -95,12 +99,25 @@ let exitCode = exitCodes.zeroClean;

const cliEngine = new CLIEngine(cliEngineOptions);
const cliEngineOutput = cliEngine.executeOnPackageJsonFiles(patterns);
debug(`Creating NpmPackageJsonLint instance`);
const npmPackageJsonLint = new NpmPackageJsonLint({
cwd: process.cwd(),
configFile: cli.flags.configFile,
patterns,
ignorePath: cli.flags.ignorePath,
quiet: cli.flags.quiet
});
const linterOutput = npmPackageJsonLint.lint();
if (cli.flags.quiet) {
cliEngineOutput.results = CLIEngine.getErrorResults(cliEngineOutput.results);
debug(`NpmPackageJsonLint.lint complete`);
debug(`Reporter.write starting`);
Reporter.write(linterOutput, cli.flags.quiet);
debug(`Reporter.write complete`);
if (linterOutput.warningCount > cli.flags.maxWarnings) {
debug(`Max warnings exceeded`);
exitCode = exitCodes.exceedMaxWarnings;
}
Reporter.write(cliEngineOutput, cli.flags.quiet);
if (cliEngineOutput.errorCount > noIssues) {
if (linterOutput.errorCount > noIssues) {
debug(`Lint errors detected`);
exitCode = exitCodes.twoLintErrorsDetected;

@@ -107,0 +124,0 @@ }

@@ -1,33 +0,13 @@

/* eslint class-methods-use-this: 'off', complexity: 'off' */
const debug = require('debug')('npm-package-json-lint:Config');
const cosmiconfig = require('cosmiconfig');
const fs = require('fs');
const path = require('path');
const os = require('os');
const isPathInside = require('is-path-inside');
const isResolvable = require('is-resolvable');
// const ConfigValidator = require('./config/ConfigValidator');
const cosmicConfigTransformer = require('./config/cosmicConfigTransformer');
const applyExtendsIfSpecified = require('./config/applyExtendsIfSpecified');
const applyOverrides = require('./config/applyOverrides');
const ConfigFile = require('./config/ConfigFile');
const ConfigFileType = require('./config/ConfigFileType');
const ConfigValidator = require('./config/ConfigValidator');
const noRules = 0;
/**
* Determines the base directory for node packages referenced in a config file.
* This does not include node_modules in the path so it can be used for all
* references relative to a config file.
*
* calculates the path of the project including npm-package-json-lint as a dependency
* NOTE: config-file is located in /src/
* ../ is npm-package-json-lint
* ../ is node_modules directory
* ../ is module referencing npm-package-json-lint
*
* @returns {String} The base directory for the file path.
* @private
*/
const getProjectDir = () => path.resolve(__dirname, '../../../');
/**
* Public Config class
* Config class
* @class

@@ -38,169 +18,70 @@ */

* Constructor
* @param {Object} providedOptions Options object
* @param {Object} linter Instance of npm-package-json-lint linter
*/
constructor(providedOptions, linter) {
const options = providedOptions || {};
this.linterContext = linter;
this.options = options;
this.useConfigFiles = options.useConfigFiles;
this.cliConfig = this.options.rules;
ConfigValidator.validateRules(this.cliConfig, 'cli', this.linterContext);
}
/**
* Loads the config options from a config specified on the command line.
*
* @param {String} config A shareable named config or path to a config file.
* @returns {undefined} No return
* @param {string} cwd The current working directory.
* @param {Object} config The user passed config object.
* @param {string} configFile The user passed configFile path.
* @param {string} configBaseDirectory The base directory that config should be pulled from.
*/
loadCliSpecifiedCfgFile(config) {
let configObj = ConfigFile.createEmptyConfig();
const firstChar = 0;
constructor(cwd, config, configFile, configBaseDirectory) {
if (config) {
const resolvable = isResolvable(config) || config.charAt(firstChar) === '@';
const filePath = resolvable ? config : path.resolve(this.options.cwd, config);
configObj = ConfigFile.load(filePath, this);
this.config = applyExtendsIfSpecified(config, 'PassedConfig');
}
return configObj;
this.cwd = cwd;
this.configFile = configFile;
this.configBaseDirectory = configBaseDirectory;
this.explorer = cosmiconfig('npmpackagejsonlint', {
transform: cosmicConfigTransformer.transform(cwd, configBaseDirectory)
});
}
/**
* Gets the personal config object from user's home directory.
* Gets the config for a file.
*
* @returns {Object} the personal config object (null if there is no personal config)
* @private
* @param {string} filePath File path of the file being linted.
* @returns {Object} A config object.
* @memberof Config
*/
getUserHomeConfig() {
if (typeof this.personalConfig === 'undefined') {
const userHomeDir = os.homedir();
let configObj = {};
getConfigForFile(filePath) {
debug(`Getting config for ${filePath}`);
const filePathToSearch = filePath;
const jsonRcFilePath = path.join(userHomeDir, ConfigFileType.rcFileName);
const javaScriptConfigFilePath = path.join(userHomeDir, ConfigFileType.javaScriptConfigFileName);
debug(`filePathToSearch: ${filePathToSearch}`);
let config;
if (fs.existsSync(jsonRcFilePath) && fs.statSync(jsonRcFilePath).isFile()) {
configObj = ConfigFile.load(jsonRcFilePath, this);
} else if (fs.existsSync(javaScriptConfigFilePath) && fs.statSync(javaScriptConfigFilePath).isFile()) {
configObj = ConfigFile.load(javaScriptConfigFilePath, this);
if (typeof this.config === 'undefined') {
debug(`User passed config is undefined.`);
if (this.configFile) {
debug(`Config file specified, loading it.`);
config = this.explorer.loadSync(this.configFile);
} else {
debug(`Config file wasn't specified, searching for config.`);
config = this.explorer.searchSync(filePathToSearch);
}
} else {
debug(`User passed config is set, using it.`);
const configBeforeOverrides = this.config;
this.personalConfig = configObj;
debug(`Applying overrides to config for ${filePath}`);
config = applyOverrides(this.cwd, filePath, configBeforeOverrides.rules, configBeforeOverrides.overrides);
debug(`Overrides applied for ${filePath}`);
}
return this.personalConfig;
}
if (!config) {
throw new Error(`No npm-package-json-lint configuration found.\n${filePathToSearch}`);
}
/* eslint-disable max-statements */
/**
* Finds local config files from the specified directory and its parent directories.
*
* @param {string} filePath a file in whose directory we start looking for a local config
* @returns {Object} Config object
*/
getProjectHierarchyConfig(filePath) {
let config = ConfigFile.createEmptyConfig();
if (Object.keys(config).length === noRules) {
throw new Error(`No rules specified in configuration.\n${filePathToSearch}`);
}
const directory = filePath ? path.dirname(filePath) : this.options.cwd;
debug(`Overrides applied for ${filePath}`);
if (directory === getProjectDir() || isPathInside(directory, getProjectDir())) {
const pkgJsonFilePath = path.join(directory, 'package.json');
const jsonRcFilePath = path.join(directory, ConfigFileType.rcFileName);
const javaScriptConfigFilePath = path.join(directory, ConfigFileType.javaScriptConfigFileName);
// ConfigValidator.validateRules(config, 'cli', this.linter);
if (fs.existsSync(pkgJsonFilePath) && fs.statSync(pkgJsonFilePath).isFile()) {
config = ConfigFile.loadFromPackageJson(pkgJsonFilePath, this);
}
if (
this.useConfigFiles &&
Object.keys(config.rules).length === noRules &&
fs.existsSync(jsonRcFilePath) &&
fs.statSync(jsonRcFilePath).isFile()
) {
config = ConfigFile.load(jsonRcFilePath, this);
} else if (
this.useConfigFiles &&
Object.keys(config.rules).length === noRules &&
fs.existsSync(javaScriptConfigFilePath) &&
fs.statSync(javaScriptConfigFilePath).isFile()
) {
config = ConfigFile.load(javaScriptConfigFilePath, this);
}
if (!config.hasOwnProperty('root') || !config.root) {
const parentPackageJsonFile = path.resolve(directory, '../', 'package.json');
const parentConfig = this.getProjectHierarchyConfig(parentPackageJsonFile);
// Merge base object
const mergedConfig = Object.assign({}, parentConfig, config);
// Merge rules
const rules = Object.assign({}, parentConfig.rules, config.rules);
// Override merged rules
mergedConfig.rules = rules;
config = mergedConfig;
}
}
return config;
}
/**
* Get config object.
* Order of precedence is:
* 1. Config supplied in package.json file
* 2. Config supplied in project hierarchy (files in current directory take precedence over parent directory)
* 3. Config file supplied in CLI argument
* 4. Direct rules supplied to CLI
*
* @param {string} filePath a file in whose directory we start looking for a local config
* @returns {Object} config object
*/
get(filePath) {
let finalConfig = {};
// Step 1: Get project hierarchy config from
// package.json property, .npmpackagejsonlintrc.json, and npmpackagejsonlint.config.js files
const projectHierarchyConfig = this.getProjectHierarchyConfig(filePath);
// Step 2: Load cli specified config
const cliSpecifiedCfgFileConfig = this.loadCliSpecifiedCfgFile(this.options.configFile);
// Step 3: Merge config
// NOTE: Object.assign does a shallow copy of objects, so we need to
// do this for all of it properties then create a new final object
const finalRules = Object.assign({}, projectHierarchyConfig.rules, cliSpecifiedCfgFileConfig.rules, this.cliConfig);
finalConfig = {rules: finalRules};
// Step 4: Check if any config has been found.
// If no, try to load personal config from user home directory
if (!Object.keys(finalConfig.rules).length) {
const personalConfig = this.getUserHomeConfig();
if (Object.keys(personalConfig).length) {
finalConfig = Object.assign({}, personalConfig);
} else {
// No config found in all locations
const relativeFilePath = `./${path.relative(this.options.cwd, filePath)}`;
throw new Error(`No npm-package-json-lint configuration found.\n${relativeFilePath}`);
}
}
// Step 5: return final config
return finalConfig;
}
}
module.exports = Config;

@@ -0,36 +1,224 @@

const Ajv = require('ajv');
const ajvErrors = require('ajv-errors');
const ajv = new Ajv({allErrors: true, jsonPointers: true});
ajvErrors(ajv);
/**
* Top level config properties
* @type {Object}
* Formats an array of schema validation errors.
*
* @param {Array} errors An array of error messages to format.
* @returns {String} Formatted error message
*/
const topLevelConfigProperties = {
extends: {type: ['string', 'array']},
rules: {type: 'object'},
root: {type: 'boolean'}
const formatSchemaErrors = errors => {
return errors.map(error => `\t- ${error.message}\n`).join('');
};
/**
* Config schema defintion
* @type {Object}
*/
const standardRuleSchema = {
type: 'string',
enum: ['off', 'warning', 'error'],
errorMessage: {
type: 'severity must be a string.',
enum: 'severity must be either "off", "warning", or "error".'
}
};
const arrayRuleSchema = {
type: 'array',
items: [
standardRuleSchema,
{
type: 'array',
minItems: 1,
uniqueItems: true,
errorMessage: {
type: 'the second item in an array rule config must be an array.',
minItems: 'the second item in an array rule config must have at least 1 item.',
uniqueItems: 'the second item in an array rule config must have unique items.'
}
}
],
minItems: 2,
maxItems: 2,
additionalItems: false,
errorMessage: {
type: 'rule config must be an array, e.g. ["error", ["value1", "value2"]].',
minItems: 'array rules must have two items, severity and options array. e.g. ["error", ["value1", "value2"]].',
maxItems: 'array rules must have two items, severity and options array. e.g. ["error", ["value1", "value2"]].',
additionalItems:
'array rules are only allowed two items, severity and the list is values. e.g. ["error", ["value1", "value2"]].'
}
};
const objectRuleSchema = {
type: 'array',
items: [
standardRuleSchema,
{
type: 'object',
errorMessage: {
type: 'the second item in an object rule config must be an object.'
}
}
],
minItems: 2,
maxItems: 2,
additionalItems: false,
errorMessage: {
type: 'rule config must be an array, e.g. ["error", {}].',
minItems: 'object rules must have two items, severity and options object. e.g. ["error", {}].',
maxItems: 'object rules must have two items, severity and options object. e.g. ["error", {}].',
additionalItems: 'object rules are only allowed two items, severity and options object. e.g. ["error", {}].'
}
};
const optionalObjExceptionsSchema = {
type: 'array',
items: [
{
type: 'string',
errorMessage: {
type: 'each exception must be a string.'
}
}
],
uniqueItems: true,
minItems: 1,
errorMessage: {
type: 'expections must be an array.',
minItems: 'expections must have at least 1 item.',
uniqueItems: 'expections must have unique items.'
}
};
const configurationSchema = {
type: 'object',
properties: topLevelConfigProperties,
additionalProperties: false
properties: {
extends: {
type: ['string', 'array'],
items: {
type: 'string'
},
minItems: 1,
uniqueItems: true,
errorMessage: {
type: 'extends must be either a string or an array of strings.',
minItems: 'extends must have at least one item if it is an array.',
uniqueItems: 'extends must have unique items if it is an array.'
}
},
rules: {
type: 'object',
errorMessage: {
type: 'rules must be an object.'
}
},
root: {
type: 'boolean',
errorMessage: {
type: 'root must be a boolean.'
}
}
},
additionalProperties: false,
errorMessage: {
type: 'npm-package-json-lint config should be an object.',
additionalProperties:
'npm-package-json-lint config has unexpected top-level property. Valid properties include: `extends`, `rules`, and `root`.'
}
};
/**
* Public ConfigSchema class
* @class
* Validates standard rules config.
*
* @param {Object} ruleConfig The ruleConfig object to validate.
* @returns {boolean} True if valid. Error if not.
*/
class ConfigSchema {
/**
* Gets configuration schema
*
* @returns {Object} schema object
*/
static get() {
return configurationSchema;
const isStandardRuleSchemaValid = ruleConfig => {
const validate = ajv.compile(standardRuleSchema);
const isValid = validate(ruleConfig);
if (!isValid) {
throw new Error(`${formatSchemaErrors(validate.errors)}`);
}
}
module.exports = ConfigSchema;
return true;
};
/**
* Validates array rules config.
*
* @param {Object} ruleConfig The ruleConfig object to validate.
* @returns {boolean} True if valid. Error if not.
*/
const isArrayRuleSchemaValid = ruleConfig => {
const validate = ajv.compile(arrayRuleSchema);
const isValid = validate(ruleConfig);
if (!isValid) {
throw new Error(`${formatSchemaErrors(validate.errors)}`);
}
return true;
};
/**
* Validates array rules config.
*
* @param {Object} ruleConfig The ruleConfig object to validate.
* @returns {boolean} True if valid. Error if not.
*/
const isObjectRuleSchemaValid = ruleConfig => {
const validate = ajv.compile(objectRuleSchema);
const isValid = validate(ruleConfig);
if (!isValid) {
throw new Error(`${formatSchemaErrors(validate.errors)}`);
}
return true;
};
/**
* Validates optional object exceptions config.
*
* @param {Object} ruleConfig The ruleConfig object to validate.
* @returns {boolean} True if valid. Error if not.
*/
const isOptionalObjExceptSchemaValid = ruleConfig => {
const validate = ajv.compile(optionalObjExceptionsSchema);
const isValid = validate(ruleConfig);
if (!isValid) {
throw new Error(`${formatSchemaErrors(validate.errors)}`);
}
return true;
};
/**
* Validates the top level properties of the config object.
*
* @param {Object} config The config object to validate.
* @param {string} source The name of the configuration source to report in any errors.
* @returns {boolean} True if valid. Error if not.
*/
const isConfigObjectSchemaValid = (config, source) => {
const validate = ajv.compile(configurationSchema);
const isValid = validate(config);
if (!isValid) {
throw new Error(`npm-package-json-lint configuration in ${source} is invalid:\n${formatSchemaErrors(validate.errors)}`);
}
return true;
};
module.exports = {
isConfigObjectSchemaValid,
isStandardRuleSchemaValid,
isArrayRuleSchemaValid,
isObjectRuleSchemaValid,
isOptionalObjExceptSchemaValid
};

@@ -1,75 +0,40 @@

/* eslint no-else-return: 'off' */
const Ajv = require('ajv');
const isPlainObj = require('is-plain-obj');
const ConfigSchema = require('./ConfigSchema');
/**
* Formats an array of schema validation errors.
* Validates object rule config
*
* @param {Array} errors An array of error messages to format.
* @returns {String} Formatted error message
* @param {Object} ruleConfig Object rule
* @return {Boolean} True if config is valid, false if not
* @static
*/
const formatSchemaErrors = errors => {
const secondChar = 1;
const isObjectRuleConfigValid = ruleConfig => {
if (typeof ruleConfig === 'string' && ruleConfig === 'off') {
return true;
}
return errors
.map(error => {
if (error.keyword === 'additionalProperties') {
const formattedPropertyPath = error.dataPath.length
? `${error.dataPath.slice(secondChar)}.${error.params.additionalProperty}`
: error.params.additionalProperty;
if (typeof ruleConfig === 'string' && ruleConfig !== 'off') {
throw new Error('\t- is an object type rule. It must be set to "off" if an object is not supplied.');
}
return `Unexpected top-level property "${formattedPropertyPath}"`;
}
if (error.keyword === 'type') {
const formattedField = error.dataPath.slice(secondChar);
const formattedExpectedType = Array.isArray(error.schema) ? error.schema.join('/') : error.schema;
const formattedValue = JSON.stringify(error.data);
return `Property "${formattedField}" is the wrong type (expected ${formattedExpectedType} but got \`${formattedValue}\`)`;
}
const field = error.dataPath[0] === '.' ? error.dataPath.slice(secondChar) : error.dataPath;
return `"${field}" ${error.message}. Value: ${JSON.stringify(error.data)}`;
})
.map(message => `\t- ${message}.\n`)
.join('');
return ConfigSchema.isObjectRuleSchemaValid(ruleConfig);
};
/**
* Validates if the severity config is set correctly
* @param {String} severity Severity the rule is set to
* @return {Boolean} True if the severity is valid. False if the severity is invalid.
* @private
*/
const isSeverityInvalid = severity =>
typeof severity !== 'string' ||
(typeof severity === 'string' && severity !== 'error' && severity !== 'warning' && severity !== 'off');
/**
* Validates object rule config
* Validates optional object rule config
*
* @param {Object} ruleConfig Object rule
* @return {Boolean} True if config is valid, false if not
* @param {Object} ruleConfig Object rule
* @return {Boolean} True if config is valid, false if not
* @static
*/
const isObjectRuleConfigValid = ruleConfig => {
const severityIndex = 0;
const isOptionalObjRuleConfigValid = ruleConfig => {
const object = 1;
if (typeof ruleConfig === 'string' && ruleConfig === 'off') {
return true;
} else if (typeof ruleConfig === 'string' && ruleConfig !== 'off') {
throw new Error('is an object type rule. It must be set to "off" if an object is not supplied.');
} else if (typeof ruleConfig[severityIndex] !== 'string' || isSeverityInvalid(ruleConfig[severityIndex])) {
throw new Error(
`first key must be set to "error", "warning", or "off". Currently set to "${ruleConfig[severityIndex]}".`
);
if (typeof ruleConfig === 'string') {
return ConfigSchema.isStandardRuleSchemaValid(ruleConfig);
}
if (!isPlainObj(ruleConfig[object])) {
throw new Error(`second key must be set an object. Currently set to "${ruleConfig[object]}".`);
if (ConfigSchema.isObjectRuleSchemaValid(ruleConfig)) {
if (ruleConfig[object].hasOwnProperty('exceptions')) {
return ConfigSchema.isOptionalObjExceptSchemaValid(ruleConfig[object].exceptions);
}
}

@@ -88,20 +53,11 @@

const isArrayRuleConfigValid = ruleConfig => {
const severityIndex = 0;
const arrayIndex = 1;
if (typeof ruleConfig === 'string' && ruleConfig === 'off') {
return true;
} else if (typeof ruleConfig === 'string' && ruleConfig !== 'off') {
throw new Error('is an array type rule. It must be set to "off" if an array is not supplied.');
} else if (typeof ruleConfig[severityIndex] !== 'string' || isSeverityInvalid(ruleConfig[severityIndex])) {
throw new Error(
`first key must be set to "error", "warning", or "off". Currently set to "${ruleConfig[severityIndex]}".`
);
}
if (!Array.isArray(ruleConfig[arrayIndex])) {
throw new Error(`second key must be set an array. Currently set to "${ruleConfig[arrayIndex]}".`);
if (typeof ruleConfig === 'string' && ruleConfig !== 'off') {
throw new Error('\t- is an array type rule. It must be set to "off" if an array is not supplied.');
}
return true;
return ConfigSchema.isArrayRuleSchemaValid(ruleConfig);
};

@@ -112,12 +68,8 @@

*
* @param {Object} ruleConfig Value for standard rule config
* @return {Boolean} True if config is valid, false if not
* @param {Object} ruleConfig Value for standard rule config
* @return {Boolean} True if config is valid, error if not
* @static
*/
const isStandardRuleConfigValid = ruleConfig => {
if (isSeverityInvalid(ruleConfig)) {
throw new Error(`must be set to "error", "warning", or "off". Currently set to "${ruleConfig}".`);
}
return true;
return ConfigSchema.isStandardRuleSchemaValid(ruleConfig);
};

@@ -141,2 +93,4 @@

isObjectRuleConfigValid(userConfig);
} else if (ruleModule.ruleType === 'optionalObject') {
isOptionalObjRuleConfigValid(userConfig);
} else {

@@ -146,3 +100,3 @@ isStandardRuleConfigValid(userConfig);

} catch (err) {
const modifiedErrorMessage = `Configuration for rule "${ruleName}" is invalid:\n\t${err.message}`;
const modifiedErrorMessage = `Configuration for rule "${ruleName}" is invalid:\n${err.message}`;

@@ -159,18 +113,2 @@ if (typeof source === 'string') {

/**
* Validates the top level properties of the config object.
*
* @param {Object} config The config object to validate.
* @param {string} source The name of the configuration source to report in any errors.
* @returns {undefined} No return
*/
const validateConfigSchema = (config, source) => {
const ajv = new Ajv({allErrors: true});
const schemaValidateResult = ajv.validate(ConfigSchema.get(), config);
if (!schemaValidateResult) {
throw new Error(`npm-package-json-lint configuration in ${source} is invalid:\n${formatSchemaErrors(ajv.errors)}`);
}
};
/**
* Public ConfigValidator class

@@ -190,3 +128,3 @@ * @class

static validate(config, source, linterContext) {
validateConfigSchema(config, source);
ConfigSchema.isConfigObjectSchemaValid(config, source);
ConfigValidator.validateRules(config.rules, source, linterContext);

@@ -193,0 +131,0 @@ }

@@ -6,2 +6,11 @@ const chalk = require('chalk');

/**
* A lint issue. It could be an error or a warning.
* @typedef {Object} LintIssue
* @property {string} lintId Unique, lowercase, hyphen-separate name for the lint
* @property {string} severity 'error' or 'warning'
* @property {string} node Name of the node in the JSON the lint audits
* @property {string} lintMessage Human-friendly message to users
*/
/**
* constructor

@@ -12,2 +21,3 @@ * @param {String} lintId Unique, lowercase, hyphen-separate name for the lint

* @param {String} lintMessage Human-friendly message to users
* @returns {LintIssue} An instance of {@link LintIssue}.
*/

@@ -23,3 +33,3 @@ constructor(lintId, severity, node, lintMessage) {

* Helper to convert the LintIssue to a printable string
* @return {String} Human-friendly message about the lint issue
* @returns {string} Human-friendly message about the lint issue
*/

@@ -26,0 +36,0 @@ toString() {

@@ -1,13 +0,110 @@

/* eslint class-methods-use-this: 'off', max-statements: 'off', guard-for-in: 'off', no-restricted-syntax: 'off' */
/* eslint max-lines-per-function: 'off', no-param-reassign: 'off', arrow-body-style: 'off' */
const debug = require('debug')('npm-package-json-lint:NpmPackageJsonLint');
const isPlainObj = require('is-plain-obj');
const Config = require('./Config');
const pkg = require('../package.json');
const Rules = require('./Rules');
const pkg = require('./../package.json');
const linter = require('./linter/linter');
const getFileList = require('./utils/getFileList');
const getIgnorer = require('./utils/getIgnorer');
const noIssues = 0;
/**
* Checks if the given issue is an error issue.
*
* @param {LintIssue} issue npm-package-json-lint issue
* @returns {boolean} True if error, false if warning.
* @private
*/
const isIssueAnError = issue => {
return issue.severity === 'error';
};
const isPackageJsonObjectValid = packageJsonObject => isPlainObj(packageJsonObject);
const areRequiredOptionsValid = (packageJsonObject, patterns) => {
return (
(!patterns && !isPackageJsonObjectValid(packageJsonObject)) ||
(patterns && (packageJsonObject || isPackageJsonObjectValid(packageJsonObject)))
);
};
/**
* Filters results to only include errors.
*
* @param {LintResult[]} results The results to filter.
* @returns {LintResult[]} The filtered results.
*/
const getErrorResults = results => {
const filtered = [];
results.forEach(result => {
const filteredIssues = result.issues.filter(isIssueAnError);
if (filteredIssues.length > noIssues) {
const filteredResult = {
issues: filteredIssues,
errorCount: filteredIssues.length,
warningCount: 0
};
filtered.push(Object.assign(result, filteredResult));
}
});
return filtered;
};
/**
* CLIEngine configuration object
*
* @typedef {Object} NpmPackageJsonLint
* @property {string} configFile The configuration file to use.
* @property {string} cwd The value to use for the current working directory.
* @property {boolean} useConfigFiles False disables use of .npmpackagejsonlintrc.json files, npmpackagejsonlint.config.js files, and npmPackageJsonLintConfig object in package.json file.
* @property {Object<string,*>} rules An object of rules to use.
*/
/**
* Public CLIEngine class
* @class
*/
class NpmPackageJsonLint {
/**
* constructor
* @param {NpmPackageJsonLint} options The options for the CLIEngine.
* @constructor
*/
constructor() {
constructor({
cwd,
packageJsonObject,
packageJsonFilePath,
config,
configFile,
configBaseDirectory,
patterns,
quiet,
ignorePath,
fix
}) {
this.cwd = cwd || process.cwd();
this.packageJsonObject = packageJsonObject;
this.packageJsonFilePath = packageJsonFilePath;
this.patterns = patterns;
this.quiet = quiet || false;
this.ignorePath = ignorePath || '';
this.fix = fix || false;
this.version = pkg.version;
// if (this.options.rules && Object.keys(this.options.rules).length) {
// ConfigValidator.validateRules(this.options.rules, 'cli', this.linter);
// }
this.configHelper = new Config(this.cwd, config, configFile, configBaseDirectory);
this.rules = new Rules();
this.version = pkg.version;
this.rules.load();

@@ -17,59 +114,62 @@ }

/**
* Runs configured rules against the provided package.json object.
* Runs the linter using the config specified in the constructor
*
* @param {Object} packageJsonData Valid package.json data
* @param {Object} configObj Configuration object
* @return {Object} Results object
* @returns {LinterResult} The results {@link LinterResult} from linting a collection of package.json files.
* @memberof NpmPackageJsonLint
*/
lint(packageJsonData, configObj) {
const lintIssues = [];
lint() {
debug('Starting lint');
for (const rule in configObj) {
const ruleModule = this.rules.get(rule);
if (areRequiredOptionsValid(this.packageJsonObject, this.patterns)) {
throw new Error(
'You must pass npm-package-json-lint a `patterns` glob or a `packageJsonObject` string, though not both.'
);
}
if (ruleModule.ruleType === 'array' || ruleModule.ruleType === 'object') {
const severity =
typeof configObj[rule] === 'string' && configObj[rule] === 'off' ? configObj[rule] : configObj[rule][0];
const ruleConfig = configObj[rule][1];
const ignorer = getIgnorer(this.cwd, this.ignorePath);
let linterOutput;
if (severity !== 'off') {
const lintResult = ruleModule.lint(packageJsonData, severity, ruleConfig);
if (this.patterns) {
debug('Linting using patterns');
const {patterns} = this;
if (typeof lintResult === 'object') {
lintIssues.push(lintResult);
}
}
} else {
const severity = configObj[rule];
if (!Array.isArray(patterns)) {
throw new Error('Patterns must be an array.');
}
if (severity !== 'off') {
const lintResult = ruleModule.lint(packageJsonData, severity);
const fileList = getFileList(patterns, this.cwd);
if (typeof lintResult === 'object') {
lintIssues.push(lintResult);
}
}
}
linterOutput = linter.executeOnPackageJsonFiles({
cwd: this.cwd,
fileList,
ignorer,
configHelper: this.configHelper,
rules: this.rules
});
} else {
debug('Linting using passed object.');
linterOutput = linter.executeOnPackageJsonObject({
cwd: this.cwd,
packageJsonObject: this.packageJsonObject,
ignorer,
filename: this.packageJsonFilePath,
configHelper: this.configHelper,
rules: this.rules
});
}
return {issues: lintIssues};
}
if (this.quiet) {
const errorsOnly = getErrorResults(linterOutput.results);
/**
* Gets entire rule set
*
* @returns {Object} Rule set
*/
getRules() {
return this.rules.getRules();
}
return {
results: errorsOnly,
ignoreCount: linterOutput.ignoreCount,
errorCount: linterOutput.errorCount,
warningCount: linterOutput.warningCount
};
}
/**
* Get the rule definition for a given ruleId (name)
*
* @param {String} rule Rule name
* @returns {Object} Rule object
*/
getRule(rule) {
return this.rules.get(rule);
debug('lint complete');
return linterOutput;
}

@@ -76,0 +176,0 @@ }

@@ -34,7 +34,11 @@ /* eslint no-restricted-syntax: 'off' */

const printIndividualResultSet = (resultSet, quiet) => {
const {filePath, issues, errorCount, warningCount} = resultSet;
const {filePath, issues, ignored, errorCount, warningCount} = resultSet;
if (errorCount > zeroIssues || (!quiet && warningCount > zeroIssues)) {
if (ignored) {
console.log('');
console.log(`${chalk.yellow.underline(filePath)} - ignored`);
} else if (errorCount > zeroIssues || (!quiet && warningCount > zeroIssues)) {
console.log('');
console.log(chalk.underline(filePath));

@@ -58,3 +62,3 @@

*
* @param {Object} cliEngineOutput Full results from linting. Includes an array of results and overall counts
* @param {Object} linterOutput Full results from linting. Includes an array of results and overall counts
* @param {Boolean} quiet True suppress warnings, false show warnings

@@ -64,4 +68,4 @@ * @returns {Undefined} No results

*/
const printTotals = (cliEngineOutput, quiet) => {
const {errorCount, warningCount} = cliEngineOutput;
const printTotals = (linterOutput, quiet) => {
const {errorCount, warningCount, ignoreCount} = linterOutput;

@@ -71,2 +75,3 @@ if (errorCount > zeroIssues || warningCount > zeroIssues) {

const warningCountMessage = `${warningCount} ${plur('warning', warningCount)}`;
const ignoreCountMessage = `${ignoreCount} ${plur('file', ignoreCount)} ignored`;

@@ -79,2 +84,3 @@ console.log('');

console.log(chalk.yellow.bold(warningCountMessage));
console.log(chalk.yellow.bold(ignoreCountMessage));
}

@@ -92,3 +98,3 @@ }

*
* @param {Object} cliEngineOutput An array of LintIssues
* @param {Object} linterOutput An array of LintIssues
* @param {boolean} quiet Flag indicating whether to print warnings.

@@ -98,9 +104,9 @@ * @return {undefined} No return

*/
static write(cliEngineOutput, quiet) {
for (const result of cliEngineOutput.results) {
static write(linterOutput, quiet) {
for (const result of linterOutput.results) {
printIndividualResultSet(result, quiet);
}
if (cliEngineOutput.results.length > oneFile) {
printTotals(cliEngineOutput, quiet);
if (linterOutput.results.length > oneFile) {
printTotals(linterOutput, quiet);
}

@@ -107,0 +113,0 @@ }

@@ -17,3 +17,5 @@ const {isObject, isString} = require('./../validators/type');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -17,3 +17,5 @@ const {isArray} = require('./../validators/type');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -17,3 +17,5 @@ const {isObject} = require('./../validators/type');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -17,3 +17,5 @@ const {isArray} = require('./../validators/type');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -17,3 +17,5 @@ const {isObject} = require('./../validators/type');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -39,3 +39,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -17,3 +17,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -17,3 +17,5 @@ const {isObject} = require('./../validators/type');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -17,3 +17,5 @@ const {isObject} = require('./../validators/type');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -17,3 +17,5 @@ const {isObject} = require('./../validators/type');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -17,3 +17,5 @@ const {isArray} = require('./../validators/type');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -17,3 +17,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -17,3 +17,5 @@ const {isArray} = require('./../validators/type');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -17,3 +17,5 @@ const {isString} = require('./../validators/type');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -17,3 +17,5 @@ const {isString} = require('./../validators/type');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -18,3 +18,5 @@ const {isArray} = require('./../validators/type');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -6,14 +6,30 @@ const {isLowercase} = require('./../validators/format');

const nodeName = 'name';
const message = 'Format should be all lowercase';
const ruleType = 'standard';
const maxLength = 214;
const lint = (packageJsonData, severity) => {
if (!isLowercase(packageJsonData, nodeName)) {
return new LintIssue(lintId, severity, nodeName, message);
if (!packageJsonData.hasOwnProperty(nodeName)) {
return true;
}
const name = packageJsonData[nodeName];
if (!isLowercase(name)) {
return new LintIssue(lintId, severity, nodeName, 'Format should be all lowercase');
}
if (name.length > maxLength) {
return new LintIssue(lintId, severity, nodeName, `name should be less than or equal to ${maxLength} characters.`);
}
if (name.startsWith('.') || name.startsWith('_')) {
return new LintIssue(lintId, severity, nodeName, 'name should not start with . or _');
}
return true;
};
module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -17,3 +17,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -1,2 +0,2 @@

const {isVersionAbsolute} = require('./../validators/dependency-audit');
const {areVersionsAbsolute} = require('./../validators/dependency-audit');
const LintIssue = require('./../LintIssue');

@@ -7,6 +7,6 @@

const message = 'You are using an invalid version range. Please do not use absolute versions.';
const ruleType = 'standard';
const ruleType = 'optionalObject';
const lint = (packageJsonData, severity) => {
if (packageJsonData.hasOwnProperty(nodeName) && isVersionAbsolute(packageJsonData, nodeName)) {
const lint = (packageJsonData, severity, config) => {
if (packageJsonData.hasOwnProperty(nodeName) && areVersionsAbsolute(packageJsonData, nodeName, config)) {
return new LintIssue(lintId, severity, nodeName, message);

@@ -18,3 +18,5 @@ }

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -1,2 +0,2 @@

const {isVersionAbsolute} = require('./../validators/dependency-audit');
const {areVersionsAbsolute} = require('./../validators/dependency-audit');
const LintIssue = require('./../LintIssue');

@@ -7,6 +7,6 @@

const message = 'You are using an invalid version range. Please do not use absolute versions.';
const ruleType = 'standard';
const ruleType = 'optionalObject';
const lint = (packageJsonData, severity) => {
if (packageJsonData.hasOwnProperty(nodeName) && isVersionAbsolute(packageJsonData, nodeName)) {
const lint = (packageJsonData, severity, config) => {
if (packageJsonData.hasOwnProperty(nodeName) && areVersionsAbsolute(packageJsonData, nodeName, config)) {
return new LintIssue(lintId, severity, nodeName, message);

@@ -18,3 +18,5 @@ }

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -7,8 +7,11 @@ const {doVersContainInvalidRange} = require('./../validators/dependency-audit');

const message = 'You are using an invalid version range. Please do not use ^.';
const ruleType = 'standard';
const ruleType = 'optionalObject';
const lint = (packageJsonData, severity) => {
const lint = (packageJsonData, severity, config) => {
const rangeSpecifier = '^';
if (packageJsonData.hasOwnProperty(nodeName) && doVersContainInvalidRange(packageJsonData, nodeName, rangeSpecifier)) {
if (
packageJsonData.hasOwnProperty(nodeName) &&
doVersContainInvalidRange(packageJsonData, nodeName, rangeSpecifier, config)
) {
return new LintIssue(lintId, severity, nodeName, message);

@@ -20,3 +23,5 @@ }

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -7,8 +7,11 @@ const {doVersContainInvalidRange} = require('./../validators/dependency-audit');

const message = 'You are using an invalid version range. Please do not use ^.';
const ruleType = 'standard';
const ruleType = 'optionalObject';
const lint = (packageJsonData, severity) => {
const lint = (packageJsonData, severity, config) => {
const rangeSpecifier = '^';
if (packageJsonData.hasOwnProperty(nodeName) && doVersContainInvalidRange(packageJsonData, nodeName, rangeSpecifier)) {
if (
packageJsonData.hasOwnProperty(nodeName) &&
doVersContainInvalidRange(packageJsonData, nodeName, rangeSpecifier, config)
) {
return new LintIssue(lintId, severity, nodeName, message);

@@ -20,3 +23,5 @@ }

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -17,3 +17,5 @@ const {hasDependency} = require('./../validators/dependency-audit');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -17,3 +17,5 @@ const {hasDependency} = require('./../validators/dependency-audit');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -17,3 +17,5 @@ const {hasDepPrereleaseVers} = require('./../validators/dependency-audit');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -17,3 +17,5 @@ const {hasDepPrereleaseVers} = require('./../validators/dependency-audit');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -7,8 +7,11 @@ const {doVersContainInvalidRange} = require('./../validators/dependency-audit');

const message = 'You are using an invalid version range. Please do not use ~.';
const ruleType = 'standard';
const ruleType = 'optionalObject';
const lint = (packageJsonData, severity) => {
const lint = (packageJsonData, severity, config) => {
const rangeSpecifier = '~';
if (packageJsonData.hasOwnProperty(nodeName) && doVersContainInvalidRange(packageJsonData, nodeName, rangeSpecifier)) {
if (
packageJsonData.hasOwnProperty(nodeName) &&
doVersContainInvalidRange(packageJsonData, nodeName, rangeSpecifier, config)
) {
return new LintIssue(lintId, severity, nodeName, message);

@@ -20,3 +23,5 @@ }

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -7,8 +7,11 @@ const {doVersContainInvalidRange} = require('./../validators/dependency-audit');

const message = 'You are using an invalid version range. Please do not use ~.';
const ruleType = 'standard';
const ruleType = 'optionalObject';
const lint = (packageJsonData, severity) => {
const lint = (packageJsonData, severity, config) => {
const rangeSpecifier = '~';
if (packageJsonData.hasOwnProperty(nodeName) && doVersContainInvalidRange(packageJsonData, nodeName, rangeSpecifier)) {
if (
packageJsonData.hasOwnProperty(nodeName) &&
doVersContainInvalidRange(packageJsonData, nodeName, rangeSpecifier, config)
) {
return new LintIssue(lintId, severity, nodeName, message);

@@ -20,3 +23,5 @@ }

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -17,3 +17,5 @@ const {isObject} = require('./../validators/type');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -17,3 +17,5 @@ const {isArray} = require('./../validators/type');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -17,3 +17,5 @@ const {isObject} = require('./../validators/type');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -1,3 +0,4 @@

const {isVersionAbsolute} = require('./../validators/dependency-audit');
const LintIssue = require('./../LintIssue');
const {doVersContainNonAbsolute} = require('../validators/dependency-audit');
const {exists} = require('../validators/property');
const LintIssue = require('../LintIssue');

@@ -7,6 +8,6 @@ const lintId = 'prefer-absolute-version-dependencies';

const message = 'You are using an invalid version range. Please use absolute versions.';
const ruleType = 'standard';
const ruleType = 'optionalObject';
const lint = (packageJsonData, severity) => {
if (!isVersionAbsolute(packageJsonData, nodeName)) {
const lint = (packageJsonData, severity, config) => {
if (exists(packageJsonData, nodeName) && doVersContainNonAbsolute(packageJsonData, nodeName, config)) {
return new LintIssue(lintId, severity, nodeName, message);

@@ -18,3 +19,5 @@ }

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -1,3 +0,4 @@

const {isVersionAbsolute} = require('./../validators/dependency-audit');
const LintIssue = require('./../LintIssue');
const {doVersContainNonAbsolute} = require('../validators/dependency-audit');
const {exists} = require('../validators/property');
const LintIssue = require('../LintIssue');

@@ -7,6 +8,6 @@ const lintId = 'prefer-absolute-version-devDependencies';

const message = 'You are using an invalid version range. Please use absolute versions.';
const ruleType = 'standard';
const ruleType = 'optionalObject';
const lint = (packageJsonData, severity) => {
if (!isVersionAbsolute(packageJsonData, nodeName)) {
const lint = (packageJsonData, severity, config) => {
if (exists(packageJsonData, nodeName) && doVersContainNonAbsolute(packageJsonData, nodeName, config)) {
return new LintIssue(lintId, severity, nodeName, message);

@@ -18,3 +19,5 @@ }

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};
const {isInAlphabeticalOrder} = require('./../validators/alphabetical-sort');
const {exists} = require('../validators/property');
const LintIssue = require('./../LintIssue');

@@ -10,2 +11,6 @@

const lint = (packageJsonData, severity) => {
if (!exists(packageJsonData, nodeName)) {
return true;
}
const result = isInAlphabeticalOrder(packageJsonData, nodeName);

@@ -25,3 +30,5 @@

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};
const {isInAlphabeticalOrder} = require('./../validators/alphabetical-sort');
const {exists} = require('../validators/property');
const LintIssue = require('./../LintIssue');

@@ -10,2 +11,6 @@

const lint = (packageJsonData, severity) => {
if (!exists(packageJsonData, nodeName)) {
return true;
}
const result = isInAlphabeticalOrder(packageJsonData, nodeName);

@@ -25,3 +30,5 @@

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};
const {isInAlphabeticalOrder} = require('./../validators/alphabetical-sort');
const {exists} = require('../validators/property');
const LintIssue = require('./../LintIssue');

@@ -10,2 +11,6 @@

const lint = (packageJsonData, severity) => {
if (!exists(packageJsonData, nodeName)) {
return true;
}
const result = isInAlphabeticalOrder(packageJsonData, nodeName);

@@ -25,3 +30,5 @@

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};
const {isInAlphabeticalOrder} = require('./../validators/alphabetical-sort');
const {exists} = require('../validators/property');
const LintIssue = require('./../LintIssue');

@@ -10,2 +11,6 @@

const lint = (packageJsonData, severity) => {
if (!exists(packageJsonData, nodeName)) {
return true;
}
const result = isInAlphabeticalOrder(packageJsonData, nodeName);

@@ -25,3 +30,5 @@

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};
const {isInAlphabeticalOrder} = require('./../validators/alphabetical-sort');
const {exists} = require('../validators/property');
const LintIssue = require('./../LintIssue');

@@ -10,2 +11,6 @@

const lint = (packageJsonData, severity) => {
if (!exists(packageJsonData, nodeName)) {
return true;
}
const result = isInAlphabeticalOrder(packageJsonData, nodeName);

@@ -25,3 +30,5 @@

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};
const {areVersRangesValid} = require('./../validators/dependency-audit');
const {exists} = require('../validators/property');
const LintIssue = require('./../LintIssue');

@@ -7,8 +8,8 @@

const message = 'You are using an invalid version range. Please use ^.';
const ruleType = 'standard';
const ruleType = 'optionalObject';
const lint = (packageJsonData, severity) => {
const lint = (packageJsonData, severity, config) => {
const rangeSpecifier = '^';
if (!areVersRangesValid(packageJsonData, nodeName, rangeSpecifier)) {
if (exists(packageJsonData, nodeName) && !areVersRangesValid(packageJsonData, nodeName, rangeSpecifier, config)) {
return new LintIssue(lintId, severity, nodeName, message);

@@ -20,3 +21,5 @@ }

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};
const {areVersRangesValid} = require('./../validators/dependency-audit');
const {exists} = require('../validators/property');
const LintIssue = require('./../LintIssue');

@@ -7,8 +8,8 @@

const message = 'You are using an invalid version range. Please use ^.';
const ruleType = 'standard';
const ruleType = 'optionalObject';
const lint = (packageJsonData, severity) => {
const lint = (packageJsonData, severity, config) => {
const rangeSpecifier = '^';
if (!areVersRangesValid(packageJsonData, nodeName, rangeSpecifier)) {
if (exists(packageJsonData, nodeName) && !areVersRangesValid(packageJsonData, nodeName, rangeSpecifier, config)) {
return new LintIssue(lintId, severity, nodeName, message);

@@ -20,3 +21,5 @@ }

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -0,1 +1,2 @@

const {exists} = require('../validators/property');
const LintIssue = require('./../LintIssue');

@@ -9,3 +10,3 @@

const lint = (packageJsonData, severity) => {
if (packageJsonData.hasOwnProperty(nodeName)) {
if (exists(packageJsonData, nodeName)) {
return new LintIssue(lintId, severity, nodeName, message);

@@ -17,3 +18,5 @@ }

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};
const {hasDepVersZero} = require('./../validators/dependency-audit');
const {exists} = require('../validators/property');
const LintIssue = require('./../LintIssue');

@@ -7,6 +8,6 @@

const message = 'You have invalid version 0 dependencies. Please use modules with a major version >= 1.';
const ruleType = 'standard';
const ruleType = 'optionalObject';
const lint = (packageJsonData, severity) => {
if (hasDepVersZero(packageJsonData, nodeName)) {
const lint = (packageJsonData, severity, config) => {
if (exists(packageJsonData, nodeName) && hasDepVersZero(packageJsonData, nodeName, config)) {
return new LintIssue(lintId, severity, nodeName, message);

@@ -18,3 +19,5 @@ }

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};
const {hasDepVersZero} = require('./../validators/dependency-audit');
const {exists} = require('../validators/property');
const LintIssue = require('./../LintIssue');

@@ -7,6 +8,6 @@

const message = 'You have invalid version 0 dependencies. Please use modules with a major version >= 1.';
const ruleType = 'standard';
const ruleType = 'optionalObject';
const lint = (packageJsonData, severity) => {
if (hasDepVersZero(packageJsonData, nodeName)) {
const lint = (packageJsonData, severity, config) => {
if (exists(packageJsonData, nodeName) && hasDepVersZero(packageJsonData, nodeName, config)) {
return new LintIssue(lintId, severity, nodeName, message);

@@ -18,3 +19,5 @@ }

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -19,3 +19,5 @@ const {isInPreferredOrder} = require('./../validators/property-order');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};
const {areVersRangesValid} = require('./../validators/dependency-audit');
const {exists} = require('../validators/property');
const LintIssue = require('./../LintIssue');

@@ -7,8 +8,8 @@

const message = 'You are using an invalid version range. Please use ~.';
const ruleType = 'standard';
const ruleType = 'optionalObject';
const lint = (packageJsonData, severity) => {
const lint = (packageJsonData, severity, config) => {
const rangeSpecifier = '~';
if (!areVersRangesValid(packageJsonData, nodeName, rangeSpecifier)) {
if (exists(packageJsonData, nodeName) && !areVersRangesValid(packageJsonData, nodeName, rangeSpecifier, config)) {
return new LintIssue(lintId, severity, nodeName, message);

@@ -20,3 +21,5 @@ }

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};
const {areVersRangesValid} = require('./../validators/dependency-audit');
const {exists} = require('../validators/property');
const LintIssue = require('./../LintIssue');

@@ -7,8 +8,8 @@

const message = 'You are using an invalid version range. Please use ~.';
const ruleType = 'standard';
const ruleType = 'optionalObject';
const lint = (packageJsonData, severity) => {
const lint = (packageJsonData, severity, config) => {
const rangeSpecifier = '~';
if (!areVersRangesValid(packageJsonData, nodeName, rangeSpecifier)) {
if (exists(packageJsonData, nodeName) && !areVersRangesValid(packageJsonData, nodeName, rangeSpecifier, config)) {
return new LintIssue(lintId, severity, nodeName, message);

@@ -20,3 +21,5 @@ }

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -17,3 +17,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -17,3 +17,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -18,3 +18,5 @@ const {isObject} = require('./../validators/type');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -21,3 +21,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -16,3 +16,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -11,4 +11,2 @@ /* eslint no-restricted-syntax: 'off' */

/* eslint-disable max-statements */
const lint = (packageJsonData, severity) => {

@@ -37,3 +35,5 @@ if (!isObject(packageJsonData, nodeName)) {

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -33,3 +33,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -43,3 +43,5 @@ /* eslint max-statements: 'off', no-restricted-syntax: 'off', guard-for-in: 'off' */

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -25,3 +25,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -27,3 +27,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -24,3 +24,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -27,3 +27,5 @@ const LintIssue = require('./../LintIssue');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -17,3 +17,5 @@ const {isValidVersionNumber} = require('./../validators/format');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -17,3 +17,5 @@ const {isString} = require('./../validators/type');

module.exports.lint = lint;
module.exports.ruleType = ruleType;
module.exports = {
lint,
ruleType
};

@@ -10,12 +10,2 @@ const increment = 1;

const isInAlphabeticalOrder = (packageJsonData, nodeName) => {
if (!packageJsonData.hasOwnProperty(nodeName)) {
return {
status: true,
data: {
invalidNode: null,
validNode: null
}
};
}
let isValid = true;

@@ -46,2 +36,4 @@ let data = {

module.exports.isInAlphabeticalOrder = isInAlphabeticalOrder;
module.exports = {
isInAlphabeticalOrder
};

@@ -1,4 +0,8 @@

/* eslint no-restricted-syntax: 'off', guard-for-in: 'off' */
/* eslint no-restricted-syntax: 'off', guard-for-in: 'off', no-continue: 'off' */
const semver = require('semver');
const hasExceptions = config => {
return typeof config === 'object' && config.hasOwnProperty('exceptions');
};
/**

@@ -52,12 +56,13 @@ * Determines whether or not the package has a given dependency

* Determines whether or not the package has a dependency with a major version of 0
* @param {object} packageJsonData Valid JSON
* @param {string} nodeName Name of a node in the package.json file
* @return {boolean} True if the package has a dependency with version 0. False if it does not or the node is missing.
* @param {object} packageJsonData Valid JSON
* @param {string} nodeName Name of a node in the package.json file
* @param {object} config Rule configuration
* @return {boolean} True if the package has a dependency with version 0. False if it does not or the node is missing.
*/
const hasDepVersZero = (packageJsonData, nodeName) => {
if (!packageJsonData.hasOwnProperty(nodeName)) {
return false;
}
const hasDepVersZero = (packageJsonData, nodeName, config) => {
for (const dependencyName in packageJsonData[nodeName]) {
if (hasExceptions(config) && config.exceptions.includes(dependencyName)) {
continue;
}
for (const dependencyName in packageJsonData[nodeName]) {
const dependencyVersRange = packageJsonData[nodeName][dependencyName];

@@ -95,8 +100,9 @@

* Determines whether or not all dependency version ranges match expected range
* @param {object} packageJsonData Valid JSON
* @param {string} nodeName Name of a node in the package.json file
* @param {string} rangeSpecifier A version range specifier
* @return {boolean} False if the package has an invalid range. True if it is not or the node is missing.
* @param {object} packageJsonData Valid JSON
* @param {string} nodeName Name of a node in the package.json file
* @param {string} rangeSpecifier A version range specifier
* @param {object} config Rule configuration
* @return {boolean} False if the package has an invalid range. True if it is not or the node is missing.
*/
const areVersRangesValid = (packageJsonData, nodeName, rangeSpecifier) => {
const areVersRangesValid = (packageJsonData, nodeName, rangeSpecifier, config) => {
if (!packageJsonData.hasOwnProperty(nodeName)) {

@@ -109,2 +115,6 @@ return true;

for (const dependencyName in packageJsonData[nodeName]) {
if (hasExceptions(config) && config.exceptions.includes(dependencyName)) {
continue;
}
const dependencyVersion = packageJsonData[nodeName][dependencyName];

@@ -122,8 +132,9 @@

* Determines if any dependencies have a version string that starts with the specified invalid range
* @param {object} packageJsonData Valid JSON
* @param {string} nodeName Name of a node in the package.json file
* @param {string} rangeSpecifier A version range specifier
* @return {Boolean} True if any dependencies versions start with the invalid range, false if they don't.
* @param {object} packageJsonData Valid JSON
* @param {string} nodeName Name of a node in the package.json file
* @param {string} rangeSpecifier A version range specifier
* @param {object} config Rule configuration
* @return {Boolean} True if any dependencies versions start with the invalid range, false if they don't.
*/
const doVersContainInvalidRange = (packageJsonData, nodeName, rangeSpecifier) => {
const doVersContainInvalidRange = (packageJsonData, nodeName, rangeSpecifier, config) => {
if (!packageJsonData.hasOwnProperty(nodeName)) {

@@ -136,2 +147,6 @@ return false;

for (const dependencyName in packageJsonData[nodeName]) {
if (hasExceptions(config) && config.exceptions.includes(dependencyName)) {
continue;
}
const dependencyVersion = packageJsonData[nodeName][dependencyName];

@@ -149,16 +164,18 @@

* Determines whether or not all dependency versions are absolut
* @param {object} packageJsonData Valid JSON
* @param {string} nodeName Name of a node in the package.json file
* @return {boolean} False if the package has an non-absolute version. True if it is not or the node is missing.
* @param {object} packageJsonData Valid JSON
* @param {string} nodeName Name of a node in the package.json file
* @param {object} config Rule configuration
* @return {boolean} False if the package has an non-absolute version. True if it is not or the node is missing.
*/
const isVersionAbsolute = (packageJsonData, nodeName) => {
if (!packageJsonData.hasOwnProperty(nodeName)) {
return true;
}
const NOT_FOUND = -1;
const absoluteVersionChecker = (packageJsonData, nodeName, config) => {
const notFound = -1;
const firstCharOfStr = 0;
let rangesValid = true;
let onlyAbsoluteVersionDetected = true;
let dependenciesChecked = 0;
for (const dependencyName in packageJsonData[nodeName]) {
if (hasExceptions(config) && config.exceptions.includes(dependencyName)) {
continue;
}
const dependencyVersion = packageJsonData[nodeName][dependencyName];

@@ -171,17 +188,51 @@

dependencyVersion.startsWith('<', firstCharOfStr) ||
dependencyVersion.indexOf('*') !== NOT_FOUND
dependencyVersion.indexOf('*') !== notFound
) {
rangesValid = false;
onlyAbsoluteVersionDetected = false;
}
dependenciesChecked += 1;
}
return rangesValid;
return {
onlyAbsoluteVersionDetected,
dependenciesChecked
};
};
module.exports.hasDependency = hasDependency;
module.exports.hasDepPrereleaseVers = hasDepPrereleaseVers;
module.exports.hasDepVersZero = hasDepVersZero;
module.exports.doesVersStartsWithRange = doesVersStartsWithRange;
module.exports.areVersRangesValid = areVersRangesValid;
module.exports.doVersContainInvalidRange = doVersContainInvalidRange;
module.exports.isVersionAbsolute = isVersionAbsolute;
/**
* Determines whether or not all dependency versions are absolut
* @param {object} packageJsonData Valid JSON
* @param {string} nodeName Name of a node in the package.json file
* @param {object} config Rule configuration
* @return {boolean} False if the package has an non-absolute version. True if it is not or the node is missing.
*/
const areVersionsAbsolute = (packageJsonData, nodeName, config) => {
const {onlyAbsoluteVersionDetected, dependenciesChecked} = absoluteVersionChecker(packageJsonData, nodeName, config);
return dependenciesChecked > 0 ? onlyAbsoluteVersionDetected : false;
};
/**
* Determines whether or not all dependency versions are absolut
* @param {object} packageJsonData Valid JSON
* @param {string} nodeName Name of a node in the package.json file
* @param {object} config Rule configuration
* @return {boolean} False if the package has an non-absolute version. True if it is not or the node is missing.
*/
const doVersContainNonAbsolute = (packageJsonData, nodeName, config) => {
const {onlyAbsoluteVersionDetected, dependenciesChecked} = absoluteVersionChecker(packageJsonData, nodeName, config);
return dependenciesChecked > 0 ? !onlyAbsoluteVersionDetected : false;
};
module.exports = {
hasDependency,
hasDepPrereleaseVers,
hasDepVersZero,
doesVersStartsWithRange,
areVersRangesValid,
doVersContainInvalidRange,
areVersionsAbsolute,
doVersContainNonAbsolute
};
const semver = require('semver');
const validator = require('validator');
/**
* Determines whether or not the node's value is lowercase
* @param {object} packageJsonData Valid JSON
* @param {string} nodeName Name of a node in the package.json file
* @return {boolean} True if the node is lowercase or is missing. False if it is not.
* Determines whether or not the string is lowercase
* @param {string} name Name
* @return {boolean} True if the string is lowercase or is missing. False if it is not.
*/
const isLowercase = (packageJsonData, nodeName) => {
if (!packageJsonData.hasOwnProperty(nodeName)) {
return true;
}
return validator.isLowercase(packageJsonData[nodeName]);
const isLowercase = name => {
return name === name.toLowerCase();
};

@@ -32,3 +26,5 @@

module.exports.isLowercase = isLowercase;
module.exports.isValidVersionNumber = isValidVersionNumber;
module.exports = {
isLowercase,
isValidVersionNumber
};

@@ -93,2 +93,4 @@ /* eslint max-statements: 'off' */

module.exports.isInPreferredOrder = isInPreferredOrder;
module.exports = {
isInPreferredOrder
};
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc