Linting a package.json
file
The next style file fixes a package.json
file using project-config:
{
rules: [
{
files: ["package.json"],
JMESPathsMatch: [
// name
// ----
// check that the name of the package match a regular expression
// or set it from the name of the root directory in `fix` mode
["regex_match('[a-z0-9-]{3,}', name)", true, "rootdir_name()"],
// version
// -------
// check that the version of the package match a regular expression
// or set it to '0.1.0' in `fix` mode
["regex_match('\\d+\\.\\d+\\.\\d+', version)", true, "0.1.0"],
// description
// -----------
// check that the description field has been added or add with an empty
// value in `fix` mode
["type(description)", "string"],
// keywords
// --------
// check that at least two keywords has been added, if fails create an empty
// array in `fix` mode
[
"op(length(keywords), '>', `1`)",
true,
"deepmerge(@, {keywords: []})",
],
// homepage
// --------
// check that the homepage field is pointing to a valid URL to Github
// or set it to 'https://github.com/mondeja/{rootdir_name}'
[
"op(op('https://www.github.com/mondeja/', '+', rootdir_name()), '==', homepage)",
true,
"set(@, 'homepage', op('https://www.github.com/mondeja/', '+', rootdir_name()))",
],
// bugs
// ----
// check that the bugs field is pointing to a valid URL to Github issue tracker
["type(bugs)", "object"],
[
"op(op(op('https://www.github.com/mondeja/', '+', rootdir_name()), '+', '/issues'), '==', bugs.url)",
true,
"deepmerge(@, {bugs: {url: op(op('https://www.github.com/mondeja/', '+', rootdir_name()), '+', '/issues')}})",
],
// funding
// -------
// check that the funding key is added and has a `type` and `url` keys
["type(funding)", "object"],
[
"type(funding.type)",
"string",
"deepmerge(@, {funding: {type: 'patreon'}})",
],
[
"type(funding.url)",
"string",
"deepmerge(@, {funding: {url: 'https://patreon.com/my-account'}})",
],
// repository
// ----------
// check that the repository field is pointing to a valid URL to Github
["type(repository)", "object"],
["repository.type", "git", "deepmerge(@, {repository: {type: 'git'}})"],
[
"op(op(op('https://www.github.com/mondeja/', '+', rootdir_name()), '+', '.git'), '==', repository.url)",
true,
"deepmerge(@, {repository: {url: op(op('https://www.github.com/mondeja/', '+', rootdir_name()), '+', '.git')}})",
],
// engines
// -------
["type(engines)", "object"],
[
"contains(keys(engines), 'node')",
true,
"deepmerge(@, {engines: {node: '^14.15.0 || >=16.0.0'}})",
],
// Remove invalid fields
// ---------------------
// - engineStrict, engine-strict (removed in NPM v3)
["contains(keys(@), 'engineStrict')", false],
["contains(keys(@), 'engine-strict')", false],
// - preferGlobal
["contains(keys(@), 'preferGlobal')", false],
// private
// -------
// set it explicitly: if not defined, set to `true`
["type(private)", "boolean", "set(@, 'private', `true`)"],
// scripts
// -------
// define a default `version` script to show the version of the program
["type(scripts)", "object"],
[
"contains(keys(scripts), 'version')",
true,
"deepmerge(@, {scripts: {version: 'node -e \\'console.log(require(\"./package.json\").version)\\''}})",
],
],
crossJMESPathsMatch: [
[
// license
// -------
// must be a valid SPDX OSI approved license identifier
"license",
[
"gh://spdx/license-list-data@v3.25.0/json/licenses.json",
"licenses[?isOsiApproved] | [?!isDeprecatedLicenseId].licenseId",
],
"contains([1], [0])",
true,
],
],
},
],
}
{
"name": "a-valid-project-name",
"version": "1.0.0",
"description": "",
"license": "BSD-3-Clause",
"keywords": [
"foo",
"bar"
],
"homepage": "https://github.com/mondeja/package-json",
"bugs": {
"url": "https://github.com/mondeja/package-json/issues"
},
"funding": {
"type": "patreon",
"url": "https://patreon.com/my-account"
},
"repository": {
"url": "https://github.com/mondeja/package-json.git",
"type": "git"
},
"engines": {
"node": "^14.15.0 || >=16.0.0"
},
"private": true,
"scripts": {
"version": "node -e 'console.log(require(\"./package.json\").version)'"
}
}