eslint-plugin-json-format
Advanced tools
Comparing version 1.1.0 to 1.2.0
const _ = require('lodash') | ||
const debug = require('debug')('json') | ||
const Diff = require('diff') | ||
const diffMatchPatch = require('diff-match-patch') | ||
const lineColumn = require('line-column') | ||
@@ -10,2 +10,6 @@ const path = require('path') | ||
const dmp = new diffMatchPatch() | ||
dmp.Diff_Timeout = 0.1 | ||
const pluginName = 'json' | ||
@@ -53,4 +57,2 @@ | ||
debug('verify:', ret) | ||
return ret | ||
@@ -61,6 +63,8 @@ } | ||
debug({ source }) | ||
// debug({ source }) | ||
let parsed | ||
const startTime = new Date() | ||
try { | ||
@@ -71,3 +75,3 @@ parsed = parseJSON(source) | ||
const res = /JSON5: (.*?) at (\d+):(\d+)/.exec(e.message) | ||
const res = /(.*)\sin JSON at position (\d+)/.exec(e.message) | ||
@@ -79,6 +83,8 @@ let line = 1 | ||
if (res) { | ||
debug(res[1], res[2]) | ||
line = res[2] | ||
col = res[3] | ||
debug('error parsed as:', res) | ||
message = res[1] | ||
const lineCol = lineColumn(source, +res[2]) | ||
line = lineCol.line | ||
col = lineCol.col | ||
} | ||
@@ -100,11 +106,17 @@ | ||
} | ||
debug({ parsed }) | ||
const endTime = new Date() | ||
debug('parsed:', endTime - startTime) | ||
// debug({ parsed }) | ||
const formatted = formatJSON(parsed) | ||
debug({ formatted }) | ||
debug('formatted') | ||
// debug({ formatted }) | ||
let fixes = getFixes(source, formatted) | ||
if (mode === 'package-json') { | ||
debug('sorting JSON') | ||
const sorted = formatJSON(sortPkgJSON(parsed, pluginSettings['package-json-sort-order'])) | ||
@@ -130,4 +142,6 @@ | ||
debug({ fixes }) | ||
// debug({ fixes }) | ||
debug('fixes count:', fixes.length) | ||
messages = messages.concat(fixes) | ||
@@ -154,3 +168,3 @@ | ||
debug({ pluginSettings }) | ||
// debug({ pluginSettings }) | ||
@@ -203,5 +217,11 @@ const basename = path.basename(filename) | ||
const diff = Diff.diffChars(source, formatted) | ||
const startTime = new Date() | ||
// old, slow diff algo | ||
// const diff = Diff.diffChars(source, formatted) | ||
const diff = dmp.diff_main(source, formatted) | ||
const endTime = new Date() | ||
debug({ diff }) | ||
debug('diff time:', endTime - startTime) | ||
// debug({ diff }) | ||
debug('diff length:', diff.length) | ||
@@ -212,4 +232,14 @@ let index = 0 | ||
_.each(diff, (d) => { | ||
_.each(diff, (_d) => { | ||
// const d = _d | ||
const d = { | ||
added: _d[0] === 1, | ||
removed: _d[0] === -1, | ||
value: _d[1], | ||
count: _d[1].length, | ||
} | ||
// debug({ d }) | ||
const valEscaped = d.value ? JSON.stringify(d.value) : '' | ||
@@ -216,0 +246,0 @@ |
@@ -29,27 +29,31 @@ const debug = require('debug')('json-settings') | ||
'package-json-sort-order': { | ||
type: 'array', | ||
default: [ | ||
'name', | ||
'version', | ||
'description', | ||
'private', | ||
'main', | ||
'browser', | ||
'scripts', | ||
'husky', | ||
'dependencies', | ||
'devDependencies', | ||
'peerDependencies', | ||
'files', | ||
'bin', | ||
'engines', | ||
'types', | ||
'typings', | ||
'productName', | ||
'license', | ||
'repository', | ||
'homepage', | ||
'author', | ||
'bugs', | ||
], | ||
type: ['array'], | ||
default: 'pro', | ||
presets: { | ||
'standard': [], | ||
'pro': [ | ||
'name', | ||
'version', | ||
'description', | ||
'private', | ||
'main', | ||
'browser', | ||
'scripts', | ||
'husky', | ||
'dependencies', | ||
'devDependencies', | ||
'peerDependencies', | ||
'files', | ||
'bin', | ||
'engines', | ||
'types', | ||
'typings', | ||
'productName', | ||
'license', | ||
'repository', | ||
'homepage', | ||
'author', | ||
'bugs', | ||
], | ||
}, | ||
}, | ||
@@ -69,21 +73,17 @@ } | ||
const warnings = [] | ||
const pluginSettings = _.mapValues(schema, (val, ruleName) => { | ||
const pluginSettings = _.mapValues(schema, (setting, ruleName) => { | ||
let settingValue = getSetting(settings, ruleName) | ||
if (settingValue == null) { | ||
settingValue = val.default | ||
settingValue = setting.default | ||
} else { | ||
debug('user supplied setting:', ruleName) | ||
} | ||
if (val.deprecated) { | ||
if (settingValue != null) { | ||
if (val.renamed) { | ||
errors.push({ | ||
message: stripIndent` | ||
Eslint Settings Error: [${namespace}]: | ||
Using deprecated settings key: "${namespace}/${ruleName}" | ||
Please rename this settings key to: "${namespace}/${val.renamed}" | ||
`, | ||
}) | ||
} | ||
} | ||
try { | ||
settingValue = getFinalSettingValue(settingValue, setting, ruleName) | ||
} catch (e) { | ||
errors.push({ | ||
message: e.message, | ||
}) | ||
@@ -93,17 +93,5 @@ return | ||
const type = typeOf(settingValue) | ||
debug('setting value', { ruleName, settingValue, type }) | ||
if (type !== val.type) { | ||
throw new Error(stripIndent` | ||
ESLint Settings Error [${namespace}]: | ||
invalid property value ${namespace}/${ruleName} | ||
expected type of ${val.type}, but got ${type}`) | ||
} | ||
{ return settingValue } | ||
return settingValue | ||
}) | ||
debug({ pluginSettings }) | ||
return { pluginSettings, warnings, errors } | ||
@@ -116,4 +104,57 @@ } | ||
schema, | ||
getDefault: (key) => getFinalSettingValue(schema[key].default, schema[key], key), | ||
} | ||
const typeOf = (obj) => Object.prototype.toString.call(obj).replace(/\[\w+ (\w+)\]/, '$1').toLowerCase() | ||
const typeOf = (obj) => { | ||
return Object.prototype.toString.call(obj).replace(/\[\w+ (\w+)\]/, '$1').toLowerCase() | ||
} | ||
const getFinalSettingValue = (val, setting, ruleName) => { | ||
const type = typeOf(val) | ||
const allowedTypes = _.isArray(setting.type) ? setting.type : [setting.type] | ||
// debug({ ruleName, allowedTypes, type }) | ||
if (setting.deprecated) { | ||
if (val != null) { | ||
throwDeprecatedError(setting, ruleName) | ||
} | ||
return | ||
} | ||
if (setting.presets && type === 'string') { | ||
if (!setting.presets[val]) { | ||
throwInvalidTypeError(type, setting, allowedTypes, ruleName) | ||
} | ||
return setting.presets[val] | ||
} | ||
if (!_.includes(allowedTypes, type)) { | ||
throwInvalidTypeError(type, setting, allowedTypes, ruleName) | ||
} | ||
return val | ||
} | ||
const throwInvalidTypeError = (type, setting, allowedTypes, ruleName) => { | ||
throw new Error(stripIndent` | ||
ESLint Settings Error [${namespace}]: | ||
invalid property value ${namespace}/${ruleName} | ||
expected type of ${allowedTypes.join(', ')}, but got ${type} | ||
${setting.presets ? ` | ||
You may also use one of the following preset values via string: | ||
${_.keys(setting.presets).map((v) => `'${v}'`).join(', ')} | ||
` : ''} | ||
`) | ||
} | ||
const throwDeprecatedError = (setting, ruleName) => { | ||
throw new Error(stripIndent` | ||
Eslint Settings Error: [${namespace}]: | ||
Using deprecated settings key: "${namespace}/${ruleName}" | ||
${setting.renamed ? `Please rename this settings key to: "${namespace}/${setting.renamed}"` : ''} | ||
`) | ||
} |
const _ = require('lodash') | ||
const debug = require('debug')('json:utils') | ||
const JSON5 = require('json5') | ||
const jsonFixer = require('json-fixer') | ||
const minimatch = require('minimatch') | ||
@@ -179,13 +179,26 @@ const path = require('path') | ||
try { | ||
parsed = JSON5.parse(source) | ||
parsed = JSON.parse(source) //JSON5.parse(source) | ||
} catch (e) { | ||
/* eslint-disable no-console */ | ||
debug('retrying with json-fix') | ||
// HACK: suppress annoying output from json-fixer... | ||
const _consoleError = console.error | ||
const _stdoutWrite = process.stdout.write | ||
console.error = _.noop | ||
process.stdout.write = _.noop | ||
try { | ||
debug('retrying parse with added commas') | ||
const _source = source.replace(/(["'\w]\s*)(?!<,)$/gm, '$1,') | ||
const _source = source.replace(/\h*'(\w+)':/gm, '"$1":').replace(/([\}\]]),\s*$/, '$1') | ||
const { data } = jsonFixer(_source, false) | ||
parsed = JSON5.parse(_source) | ||
parsed = data | ||
} catch (__) { | ||
// throw __ | ||
throw e | ||
} finally { | ||
// HACK: restore output | ||
console.error = _consoleError | ||
process.stdout.write = _stdoutWrite | ||
/* eslint-enable no-console */ | ||
} | ||
} | ||
@@ -192,0 +205,0 @@ |
{ | ||
"name": "eslint-plugin-json-format", | ||
"version": "1.1.0", | ||
"version": "1.2.0", | ||
"description": "lint and auto-fix json", | ||
@@ -21,4 +21,4 @@ "main": "lib/index.js", | ||
"debug": "^4.1.1", | ||
"diff": "^4.0.1", | ||
"json5": "^2.1.0", | ||
"diff-match-patch": "^1.0.4", | ||
"json-fixer": "^1.3.1", | ||
"line-column": "^1.0.2", | ||
@@ -25,0 +25,0 @@ "lodash": "^4.17.15", |
@@ -10,7 +10,7 @@ <div align="center"> | ||
Lint and auto-fix your `json` with `eslint` | ||
Lint, format, and auto-fix your `json` with `eslint` | ||
## Features | ||
- lint and auto-fix `json` files (files ending with `.json` or `rc`) | ||
- lint, format, and auto-fix `json` files (files ending with `.json` or `rc`) | ||
- auto-sort `package.json` files (default `true`, can be disabled and sorting configured) | ||
@@ -59,5 +59,5 @@ - ignores `json-with-comments` files (default `["**/.tsconfig.json", ".vscode/**"]`) | ||
## Configuration | ||
## Settings | ||
### default configuration** (`.eslintrc`): | ||
### default settings (`.eslintrc`): | ||
```json | ||
@@ -68,26 +68,3 @@ "settings": { | ||
"json/json-with-comments-files": ["**/tsconfig.json", ".vscode/**"], | ||
"json/package-json-sort-order": [ | ||
"name", | ||
"version", | ||
"description", | ||
"private", | ||
"main", | ||
"browser", | ||
"scripts", | ||
"husky", | ||
"dependencies", | ||
"devDependencies", | ||
"peerDependencies", | ||
"files", | ||
"bin", | ||
"engines", | ||
"types", | ||
"typings", | ||
"productName", | ||
"license", | ||
"repository", | ||
"homepage", | ||
"author", | ||
"bugs", | ||
] | ||
"json/package-json-sort-order": "pro" | ||
} | ||
@@ -97,4 +74,17 @@ ``` | ||
### examples: | ||
### `package-json-sort-order` | ||
You can configure the exact sort order of your `package.json` files (or turn it off entirely with the `sort-package-json` setting) | ||
By default the sort order is `"pro"` (will change to "standard" in next major version) | ||
#### Available sorting options | ||
**"pro"**: places scripts and depenedencies at the top, reducing need to scroll down to view them. Pros only. | ||
**"standard"**: default from [`sort-package-json`](https://github.com/keithamus/sort-package-json). This is a sane, standard order. | ||
**["your", "custom", "order", "here"]**: provide an array to manually set the sort order. | ||
### Settings examples | ||
to turn off `sort-package-json` for example, in your `.eslintrc`: | ||
@@ -101,0 +91,0 @@ ```json |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
22421
517
147
+ Addeddiff-match-patch@^1.0.4
+ Addedjson-fixer@^1.3.1
+ Added@babel/runtime@7.25.6(transitive)
+ Addeddiff-match-patch@1.0.5(transitive)
+ Addedjson-fixer@1.6.15(transitive)
+ Addedpegjs@0.10.0(transitive)
+ Addedregenerator-runtime@0.14.1(transitive)
- Removeddiff@^4.0.1
- Removedjson5@^2.1.0
- Removeddiff@4.0.2(transitive)
- Removedjson5@2.2.3(transitive)