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

yaspeller

Package Overview
Dependencies
Maintainers
1
Versions
65
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

yaspeller - npm Package Compare versions

Comparing version 6.1.0 to 7.0.0

lib/cli/options.js

4

CHANGELOG.md
# Changelog
## v7.0.0
- Drop support for Node.js < 10.
- Add .yaspellerrc.js and .yaspellerrc.json for project config #153, #150
## v6.1.0

@@ -4,0 +8,0 @@ - Fix lost symlink #145, #128.

@@ -18,2 +18,4 @@ 'use strict';

}
process.exit();
}

@@ -20,0 +22,0 @@

64

lib/cli/index.js

@@ -7,14 +7,12 @@ 'use strict';

const programOptions = require('../options');
const dict = require('../dictionary');
const { cliActionInit } = require('./actions');
const { defaultConfig } = require('../config');
const dictionary = require('../dictionary');
const { setCliOptions, getMergedOptions } = require('./options');
const reports = require('../reports');
const tasks = require('../tasks');
const { prepareRegExpToIgnoreText } = require('../helpers/ignore');
const { getConfig, defaultConfig } = require('../config');
const { setDebugMode } = require('../helpers/debug');
const { cliActionInit } = require('./actions');
programOptions.init({defaultIgnoreTags: defaultConfig.ignoreTags.join(',')});
setCliOptions(defaultConfig);
program.parse(process.argv);

@@ -27,40 +25,8 @@

const jsonConfig = getConfig(program.config);
const json = Object.assign({}, defaultConfig, jsonConfig.data);
const mergedOptions = getMergedOptions(program.config);
const settings = {
excludeFiles: json.excludeFiles,
options: json.options || {}
};
dictionary.loadDictionaries(program.dictionary, mergedOptions.configDictionary);
[
'checkYo',
'fileExtensions',
'format',
'ignoreTags',
'ignoreText',
'lang',
'maxRequests'
].forEach(function(key) {
settings[key] = program[key] || json[key];
});
settings.ignoreText = prepareRegExpToIgnoreText(settings.ignoreText);
programOptions.apiOptions.forEach(function(el) {
const key = el[0];
if (program[key]) {
settings.options[key] = true;
} else if (typeof json[key] !== 'undefined') {
settings.options[key] = json[key];
}
});
dict.set(program.dictionary, json.dictionary);
reports.addReports(program.report || json.report);
if (program.init) {
cliActionInit();
process.exit();
}

@@ -73,12 +39,12 @@

reports.onstart();
reports.set(mergedOptions.report);
reports.onStart();
async.series(
isStdin ?
tasks.forStdin(settings, program.stdinFilename) :
tasks.forResources(program.args, settings),
function() {
reports.onend(jsonConfig.relativePath);
process.exit();
}
);
tasks.forStdin(program.stdinFilename, mergedOptions) :
tasks.forResources(program.args, mergedOptions)
).then(() => {
reports.onComplete(mergedOptions.configRelativePath);
process.exit();
});

@@ -40,4 +40,6 @@ 'use strict';

'package.json',
'.yaspeller.json',
'.yaspellerrc',
'.yaspeller.json'
'.yaspellerrc.js',
'.yaspellerrc.json',
]

@@ -77,4 +79,18 @@ });

/**
* Get merged config.
*
* @param {string} filename
* @returns {Object}
*/
function getMergedConfig(filename) {
const config = getConfig(filename);
return Object.assign({
configRelativePath: config.relativePath,
}, defaultConfig, config.data);
}
/**
* Check config properties.
*
*
* @param {*} obj

@@ -102,4 +118,5 @@ * @param {string|undefined} file

module.exports = {
defaultConfig,
getConfig,
defaultConfig,
getMergedConfig,
};

@@ -10,3 +10,3 @@ 'use strict';

const { loadFileAsJson } = require('./helpers/file');
const { uniq } = require('./helpers/array');
const { uniq, notUniq } = require('./helpers/array');
const { consoleError, consoleWarn, consoleLog, consoleDebug } = require('./helpers/console');

@@ -19,47 +19,24 @@

module.exports = {
class Dictionary {
constructor() {
this.dict = [];
}
/**
* Set dictionary.
*
* @param {Array} files
* @param {Array} configDictionary - Dictionary from .yaspellerrc
* @param {string[]} words
*/
set(files, configDictionary) {
let commonUniqueWords = [];
let count = 0;
let result = [];
set(words) {
this.dict = this.prepareDictionaryWords(words);
}
const prepare = (words, file) => {
result = result.concat(words);
this.checkDuplicates(words, `Dictionary duplicate words in "${file}":`);
this.checkTyposInDictionary(words, file);
commonUniqueWords = commonUniqueWords.concat(uniq(words));
count++;
};
if (configDictionary) {
prepare(configDictionary, '.yaspellerrc');
}
files && files.forEach(function(file) {
prepare(this.loadDictionary(file), file);
}, this);
if (count > 1) {
this.checkDuplicates(commonUniqueWords, 'Duplicate words in dictionaries:');
}
this._dict = this.prepareDictionary(result);
},
/**
* Get dictionary.
*
* @returns {Array}
* @returns {RegExp[]}
*/
get() {
return this._dict;
},
_dict: [],
return this.dict;
}
/**

@@ -69,3 +46,3 @@ * Load dictionary.

* @param {string} file - JSON file.
* @returns {Array}
* @returns {string[]}
*/

@@ -75,3 +52,3 @@ loadDictionary(file) {

consoleDebug('Get/check dictionary: ' + file);
consoleDebug(`Get/check dictionary: ${file}`);

@@ -81,3 +58,3 @@ try {

consoleDebug('Use dictionary: ' + file);
consoleDebug(`Use dictionary: ${file}`);
} catch (e) {

@@ -89,4 +66,38 @@ consoleError(e);

return data;
},
}
/**
* Load dictionaries.
*
* @param {string[]} files
* @param {string[]} configDictionary - Dictionary from .yaspellerrc
*/
loadDictionaries(files, configDictionary) {
let count = 0;
let result = [];
const prepare = (words, file) => {
result = result.concat(uniq(words));
this.checkDuplicateWords(words, `Dictionary duplicate words in "${file}":`);
this.checkTyposInDictionary(words, file);
count++;
};
if (configDictionary) {
prepare(configDictionary, '.yaspellerrc');
}
files && files.forEach(file => {
prepare(this.loadDictionary(file), file);
});
if (count >= 2) {
this.checkDuplicateWords(result, 'Duplicate words in dictionaries:');
}
this.set(result);
}
/**
* Check duplicate words in dictionary.

@@ -98,4 +109,4 @@ *

*/
checkDuplicates(words, title) {
const duplicates = this.getDuplicates(words);
checkDuplicateWords(words, title) {
const duplicates = notUniq(words);
if (duplicates.length) {

@@ -108,3 +119,4 @@ consoleWarn(title + '\n' + duplicates.join('\n') + '\n');

return false;
},
}
/**

@@ -119,11 +131,11 @@ * Check typos in dictionary.

const typos = [];
words.forEach(function(word) {
if (hasEngRusLetters(word)) {
typos.push(word);
words.forEach(item => {
if (hasEngRusLetters(item)) {
typos.push(item);
}
});
const hasTypos = typos.length ? true : false;
const hasTypos = Boolean(typos.length);
if (hasTypos) {
consoleWarn('Has typos in "' + file + '":');
consoleWarn(`Has typos in "${file}":`);
typos.forEach(item => {

@@ -139,3 +151,4 @@ consoleWarn(item +

return hasTypos;
},
}
/**

@@ -147,14 +160,15 @@ * Remove typos that is in the dictionary.

*/
removeDictWords(data) {
removeDictionaryWordsFromData(data) {
const result = [];
const dictionary = this.get();
data.forEach(function(typo) {
data.forEach(typo => {
if (typo.code === ERROR_TOO_MANY_ERRORS || this.isTypo(typo.word, dictionary)) {
result.push(typo);
}
}, this);
});
return result;
},
}
/**

@@ -164,19 +178,19 @@ * It's a typo?

* @param {string} word
* @param {string[]|RegExp[]} dictionary
* @param {RegExp[]} dictionary
* @returns {boolean}
*/
isTypo(word, dictionary) {
return !dictionary.some(function(dictWord) {
return dictWord.test(word);
});
},
return !dictionary.some(item => item.test(word));
}
/**
* Prepare dictionary.
* Prepare dictionary words.
*
* @param {string[]} dict
* @returns {Array}
* @param {string[]} dictionaryWords
* @returns {RegExp[]}
*/
prepareDictionary(dict) {
prepareDictionaryWords(dictionaryWords) {
const result = [];
dict.forEach(function(word) {
dictionaryWords.forEach(word => {
if (this.isNotOptimizedRegExp(word)) {

@@ -190,7 +204,7 @@ consoleWarn(`Not optimized dictionary RegExp in "${word}"`);

let preparedWord = word.replace(rePrepare, ($, $1, $2) => '[' + $1 + $1.toUpperCase() + ']' + $2);
if (preparedWord.search(/\^/) !== 0) {
preparedWord = '^' + preparedWord;
}
if (preparedWord.search(/\$/) !== preparedWord.length - 1) {

@@ -205,6 +219,7 @@ preparedWord += '$';

}
}, this);
});
return result;
},
}
/**

@@ -226,24 +241,5 @@ * Is not optimized RegExp?

return false;
},
/**
* Get duplicate words.
*
* @param {string[]} words
* @returns {string[]}
*/
getDuplicates(words) {
const buffer = {};
const result = [];
}
}
words.forEach(function(word) {
if (!buffer[word]) {
buffer[word] = 1;
} else if (buffer[word] === 1) {
buffer[word]++;
result.push(word);
}
});
return result;
},
};
module.exports = new Dictionary();

@@ -11,4 +11,27 @@ /**

/**
* Get a array with not unique values.
*
* @param {Array} arr
* @returns {Array}
*/
function notUniq(arr) {
const buffer = {};
const result = [];
arr.forEach(item => {
if (!buffer[item]) {
buffer[item] = 1;
} else if (buffer[item] === 1) {
buffer[item]++;
result.push(item);
}
});
return result;
}
module.exports = {
uniq,
notUniq,
};

@@ -63,6 +63,7 @@ 'use strict';

module.exports = {
onstart() {
name: 'console',
onStart() {
consoleLog('Spelling check:');
},
oneach(err, data) {
onResourceComplete(err, data) {
const errors = [];

@@ -102,3 +103,3 @@ if (err) {

},
onend(data, stats, configPath) {
onComplete(data, stats, configPath) {
if (!program.onlyErrors && stats.total) {

@@ -114,3 +115,3 @@ if (stats.hasTypos) {

}
if (!stats.errors) {

@@ -117,0 +118,0 @@ consoleOk('No errors.');

@@ -12,3 +12,4 @@ 'use strict';

module.exports = {
onend(data) {
name: 'error_dictionary',
onComplete(data) {
let buffer = [];

@@ -15,0 +16,0 @@

'use strict';
module.exports = {
onstart() {
console.log('onstart');
name: 'example',
onStart() {
console.log('onStart');
},
oneach(err, data) {
console.log('oneach: ', err, data);
onResourceComplete(error, data) {
console.log('onResourceComplete', error, data);
},
onend(data, stats) {
console.log('onend: ', data, stats);
onComplete(data, stats) {
console.log('onComplete', data, stats);
}
};

@@ -69,3 +69,4 @@ 'use strict';

module.exports = {
oneach(err, data) {
name: 'html',
onResourceComplete(err, data) {
const html = [];

@@ -126,3 +127,3 @@ if (err) {

},
onend(data, stats) {
onComplete(data, stats) {
const content = '<div class="total">Processed resources: ' + stats.total +

@@ -129,0 +130,0 @@ ' (<span class="sym-err">χ</span>– ' + stats.errors +

'use strict';
const program = require('commander');
const pth = require('path');
const { defaultConfig } = require('../config');
const { uniq } = require('../helpers/array');
const { consoleError } = require('../helpers/console');
const { splitByCommas } = require('../helpers/string');
const stats = {
errors: 0,
hasTypos: false,
ok: 0,
total: 0,
};
const reports = [];
const reportNames = new Set();
const buffer = [];
const consoleReport = require('./console');
const errorDictionaryReport = require('./error_dictionary');
const htmlReport = require('./html');
const jsonReport = require('./json');
const markdownReport = require('./markdown');
module.exports = {
addReports(names) {
names.forEach(function(name) {
const moduleName = pth.extname(name) === '.js' ? name : './' + name;
class Reports {
constructor() {
this.buffer = [];
if (reportNames.has(moduleName)) {
this.innerReports = [
consoleReport,
errorDictionaryReport,
htmlReport,
jsonReport,
markdownReport,
];
this.innerReportsByName = this.innerReports.reduce((acc, current) => {
acc[current.name] = current;
return acc;
}, {});
this.stats = {
errors: 0,
hasTypos: false,
ok: 0,
total: 0,
};
this.reports = [];
}
/**
* Set reports.
*
* @param {string|string[]|undefined} names
*/
set(names) {
this.reports = [];
if (typeof names === 'string') {
names = splitByCommas(names);
} else if (Array.isArray(names)) {
names = names.map(item => item.trim());
} else {
names = [];
}
names = uniq(names).filter(Boolean);
if (!names.length) {
names = defaultConfig.report;
}
names.forEach(name => {
const report = this.innerReportsByName[name] || this.loadExternalReport(name);
if (report) {
this.reports.push(report);
}
});
}
/**
* Load external report.
*
* @param {string} name
* @returns {Report|undefined}
*/
loadExternalReport(name) {
try {
const report = require(require.resolve(name, {
paths: ['./']
}));
if (!report.name) {
consoleError(`Missing "name" property in report module "${name}".`);
return;
}
try {
reports.push(require(moduleName));
reportNames.add(moduleName);
} catch (e) {
consoleError(`Can't load report module "${moduleName}".`);
consoleError(e);
if (!report.onStart && !report.onComplete && !report.onResourceComplete) {
consoleError(`Missing methods (onStart, onResourceComplete or onComplete) in report module "${name}".`);
return;
}
return report;
} catch (e) {
consoleError(e);
}
}
onStart() {
this.reports.forEach(report => {
report.onStart && report.onStart();
});
},
onstart() {
reports.forEach(function(name) {
name.onstart && name.onstart();
});
},
oneach(hasError, data, dictionary) {
stats.total++;
}
onResourceComplete(hasError, data, dictionary) {
this.stats.total++;
const hasTypos = Boolean(data && data.data && data.data.length);
if (hasTypos) {
stats.hasTypos = true;
this.stats.hasTypos = true;
}
if (hasError || hasTypos) {
stats.errors++;
this.stats.errors++;
buffer.push([hasError, data]);
this.buffer.push([hasError, data]);
} else {
stats.ok++;
this.stats.ok++;
if (!program.onlyErrors) {
buffer.push([hasError, data]);
this.buffer.push([hasError, data]);
}

@@ -63,12 +130,24 @@ }

if (!program.onlyErrors || hasError || hasTypos) {
reports.forEach(function(name) {
name.oneach && name.oneach(hasError, data, dictionary);
this.reports.forEach(report => {
report.onResourceComplete && report.onResourceComplete(hasError, data, dictionary);
});
}
},
onend(configPath) {
reports.forEach(function(name) {
name.onend && name.onend(buffer, stats, configPath);
}
onComplete(configPath) {
this.reports.forEach(report => {
report.onComplete && report.onComplete(this.buffer, this.stats, configPath);
});
}
};
}
module.exports = new Reports();
/**
@typedef Report
@type {Object}
@property {string} name
@property {Function?} onStart
@property {Function?} onResourceComplete
@property {Function?} onComplete
*/

@@ -11,3 +11,4 @@ 'use strict';

module.exports = {
onend(data) {
name: 'json',
onComplete(data) {
try {

@@ -14,0 +15,0 @@ fs.writeFileSync(filename, jsonStringify(data));

@@ -35,3 +35,4 @@ 'use strict';

module.exports = {
oneach(err, data) {
name: 'markdown',
onResourceComplete(err, data) {
const text = [];

@@ -81,3 +82,3 @@ if (err) {

},
onend(data, stats) {
onComplete(data, stats) {
const text = '<br/><br/>Processed resources: ' + stats.total +

@@ -84,0 +85,0 @@ ' (χ – ' + stats.errors + ', ✓ – ' + stats.ok + ')<br/>' +

@@ -8,3 +8,3 @@ 'use strict';

const dict = require('./dictionary');
const dictionary = require('./dictionary');
const exitCodes = require('./exit-codes');

@@ -22,3 +22,3 @@ const reports = require('./reports');

if (hasData(err, data)) {
data.data = dict.removeDictWords(data.data);
data.data = dictionary.removeDictionaryWordsFromData(data.data);
data.data = yaspeller.removeDuplicates(data.data);

@@ -39,3 +39,3 @@

reports.oneach(err, data);
reports.onResourceComplete(err, data);
}

@@ -90,7 +90,7 @@

*
* @param {string} filename
* @param {Object} settings
* @param {string} [filename]
* @returns {Array}
*/
forStdin(settings, filename) {
forStdin(filename, settings) {
return [function(callback) {

@@ -97,0 +97,0 @@ let text = '';

The MIT License (MIT)
© 2018 Denis Seleznev, <hcodes@yandex.ru>
© 2020 Denis Seleznev, <hcodes@yandex.ru>

@@ -5,0 +5,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy

@@ -13,3 +13,3 @@ {

"description": "Search tool typos in the text, files and websites",
"version": "6.1.0",
"version": "7.0.0",
"license": "MIT",

@@ -37,3 +37,3 @@ "homepage": "https://github.com/hcodes/yaspeller",

"async": "^3.2.0",
"chalk": "^3.0.0",
"chalk": "^4.0.0",
"commander": "^3.0.0",

@@ -62,3 +62,3 @@ "cosmiconfig": "^6.0.0",

"engines": {
"node": ">=8"
"node": ">=10"
},

@@ -76,4 +76,7 @@ "scripts": {

".yaspellerrc.default.json",
"LICENSE.md"
"CHANGELOG.md",
"LICENSE.md",
"README.md",
"README.ru.md"
]
}

@@ -7,3 +7,2 @@ yaspeller

[![Dependency Status](https://img.shields.io/david/hcodes/yaspeller.svg)](https://david-dm.org/hcodes/yaspeller)
[![Known Vulnerabilities](https://snyk.io/test/github/hcodes/yaspeller/badge.svg)](https://snyk.io/test/github/hcodes/yaspeller)

@@ -164,2 +163,4 @@ <img align="right" width="200" src="https://raw.githubusercontent.com/hcodes/yaspeller/master/images/logo.png" />

- `.yaspellerrc`
- `.yaspellerrc.js`
- `.yaspellerrc.json`
- `.yaspeller.json`

@@ -166,0 +167,0 @@ - `package.json`, field `yaspeller`

@@ -7,3 +7,2 @@ yaspeller

[![Dependency Status](https://img.shields.io/david/hcodes/yaspeller.svg)](https://david-dm.org/hcodes/yaspeller)
[![Known Vulnerabilities](https://snyk.io/test/github/hcodes/yaspeller/badge.svg)](https://snyk.io/test/github/hcodes/yaspeller)

@@ -155,2 +154,4 @@ <img align="right" width="200" src="https://raw.githubusercontent.com/hcodes/yaspeller/master/images/logo.png" />

- `.yaspellerrc`
- `.yaspellerrc.js`
- `.yaspellerrc.json`
- `.yaspeller.json`

@@ -157,0 +158,0 @@ - `package.json`, поле `yaspeller`

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