npm-package-json-lint
Version:
Configurable linter for package.json files.
10 lines (9 loc) • 16.6 kB
JavaScript
var Ee=Object.create;var R=Object.defineProperty;var Pe=Object.getOwnPropertyDescriptor;var Je=Object.getOwnPropertyNames;var Le=Object.getPrototypeOf,$e=Object.prototype.hasOwnProperty;var Se=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),Ae=(t,e)=>{for(var r in e)R(t,r,{get:e[r],enumerable:!0})},X=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of Je(e))!$e.call(t,o)&&o!==r&&R(t,o,{get:()=>e[o],enumerable:!(n=Pe(e,o))||n.enumerable});return t};var g=(t,e,r)=>(r=t!=null?Ee(Le(t)):{},X(e||!t||!t.__esModule?R(r,"default",{value:t,enumerable:!0}):r,t)),Me=t=>X(R({},"__esModule",{value:!0}),t);var Ce=Se((Ut,rt)=>{rt.exports={name:"npm-package-json-lint",version:"0.0.0",description:"Configurable linter for package.json files.",keywords:["lint","linter","package.json","audit","auditor","npm-package-json-lint"],homepage:"https://github.com/tclindner/npm-package-json-lint",bugs:{url:"https://github.com/tclindner/npm-package-json-lint/issues"},author:"Thomas Lindner",repository:{type:"git",url:"https://github.com/tclindner/npm-package-json-lint.git"},bin:{npmPkgJsonLint:"dist/cli.js"},files:["CONTRIBUTING.md","dist"],main:"dist/api.js",types:"dist/src/api.d.ts",scripts:{build:"npm run esbuild && npm run tsc",esbuild:"node esbuild.config.js",eslint:"eslint .",npmpackagejsonlint:"node dist/cli.js ./package.json",lint:"npm run eslint && npm run npmpackagejsonlint",test:"npm run build && jest","test:ci":"jest --runInBand",tsc:"tsc --project tsconfig.json"},dependencies:{ajv:"^6.12.6","ajv-errors":"^1.0.1",chalk:"^4.1.2",cosmiconfig:"^8.3.6",debug:"^4.3.6",globby:"^11.1.0",ignore:"^5.3.2","is-plain-obj":"^3.0.0","jsonc-parser":"^3.3.1","log-symbols":"^4.1.0",meow:"^9.0.0",plur:"^4.0.0",semver:"^7.6.3",slash:"^3.0.0","strip-json-comments":"^3.1.1","type-fest":"^4.26.1","validate-npm-package-name":"^6.0.0"},devDependencies:{"@types/jest":"^30.0.0","@types/node":"^24.0.7","@typescript-eslint/eslint-plugin":"^8.35.0","@typescript-eslint/parser":"^8.35.0",esbuild:"^0.25.5","esbuild-node-externals":"^1.18.0",eslint:"^8.57.0","eslint-config-tc":"^27.0.0","eslint-config-typescript-tc":"^11.0.0","eslint-plugin-eslint-comments":"^3.2.0","eslint-plugin-import":"^2.32.0","eslint-plugin-jest":"^29.0.1","eslint-plugin-prettier":"^5.5.1","eslint-plugin-unicorn":"^56.0.1",figures:"^3.2.0",jest:"^30.0.3","npm-package-json-lint-config-default":"^8.0.0","npm-package-json-lint-config-tc":"^9.0.0",prettier:"^3.6.2","ts-jest":"^29.4.0",typescript:"^5.4.5"},engines:{node:">=20.0.0",npm:">=10.0.0"},license:"MIT"}});var pt={};Ae(pt,{LintIssue:()=>A,NpmPackageJsonLint:()=>S,Rules:()=>j,Severity:()=>b,write:()=>Fe});module.exports=Me(pt);var Re=g(require("is-plain-obj")),Y=g(require("slash"));var _=require("cosmiconfig");var Z=g(require("ajv")),ee=g(require("ajv-errors")),C=new Z.default({allErrors:!0,jsonPointers:!0});(0,ee.default)(C);var F=t=>t.map(e=>` - ${e.message}
`).join(""),V={type:"string",enum:["off","warning","error"],errorMessage:{type:"severity must be a string.",enum:'severity must be either "off", "warning", or "error".'}},qe=t=>({type:"array",items:[V,{type:"array",minItems:t,uniqueItems:!0,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:!1,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"]].'}}),Ve={type:"array",items:[V,{type:"object",errorMessage:{type:"the second item in an object rule config must be an object."}}],minItems:2,maxItems:2,additionalItems:!1,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", {}].'}},Te={type:"array",items:[{type:"string",errorMessage:{type:"each exception must be a string."}}],uniqueItems:!0,minItems:1,errorMessage:{type:"expections must be an array.",minItems:"expections must have at least 1 item.",uniqueItems:"expections must have unique items."}};var T=t=>{let e=C.compile(V);if(!e(t))throw new Error(`${F(e.errors)}`);return!0},te=(t,e)=>{let r=C.compile(qe(e));if(!r(t))throw new Error(`${F(r.errors)}`);return!0},N=t=>{let e=C.compile(Ve);if(!e(t))throw new Error(`${F(e.errors)}`);return!0},re=t=>{let e=C.compile(Te);if(!e(t))throw new Error(`${F(e.errors)}`);return!0};var De=t=>{if(typeof t=="string"&&t==="off")return!0;if(typeof t=="string"&&t!=="off")throw new Error(' - is an object type rule. It must be set to "off" if an object is not supplied.');return N(t)},He=t=>typeof t=="string"?T(t):N(t)&&t[1].hasOwnProperty("exceptions")?re(t[1].exceptions):!0,_e=(t,e)=>{if(typeof t=="string"&&t==="off")return!0;if(typeof t=="string"&&t!=="off")throw new Error(' - is an array type rule. It must be set to "off" if an array is not supplied.');return te(t,e)},Be=t=>T(t),Ue=(t,e,r,n)=>{if(t)try{switch(t.ruleType){case"array":{_e(r,t.minItems);break}case"object":{De(r);break}case"optionalObject":{He(r);break}default:Be(r)}}catch(o){let s=`Configuration for rule "${e}" is invalid:
${o.message}`;throw typeof n=="string"?new Error(`${n}:
${s}`):new Error(s)}},ne=(t,e,r)=>{t&&Object.keys(t).forEach(n=>{let o=r.get(n);Ue(o,n,t[n],e)})};var ue=g(require("path"));var E=g(require("path"));var oe=g(require("fs")),se=g(require("strip-json-comments")),Ge=t=>require(t),We=t=>oe.default.readFileSync(t,"utf8").replace(/^\uFEFF/,""),ie=(t,e)=>{throw new Error(`Failed to read config file: ${t}.
Error: ${e.message}`)},ze=Symbol("JSON source"),I=t=>{let e={},r="";try{r=We(t),e=JSON.parse((0,se.default)(r))}catch(n){ie(t,n)}return Object.defineProperty(e,ze,{value:r,enumerable:!1,writable:!1,configurable:!1}),e},ae=t=>{let e={};try{e=Ge(t)}catch(r){ie(t,r)}return e};var D=require("debug")("npm-package-json-lint:applyExtendsIfSpecified"),le=(t,e,r)=>{let n=t.extends;return Array.isArray(t.extends)||(n=[t.extends]),n.reduceRight((o,s)=>{try{let i=Ye(s,r),a={...i,...o},l={...i.rules,...o.rules},c=Array.isArray(i.plugins)?i.plugins:[],m=Array.isArray(o.plugins)?o.plugins:[],f=[...c,...m],k=[...new Set(f)],q=Array.isArray(i.overrides)?i.overrides:[],Ie=Array.isArray(o.overrides)?o.overrides:[],Q=[...q,...Ie];return a.rules=l,f.length>0&&(a.plugins=k),Q.length>0&&(a.overrides=Q),a}catch(i){throw i.message+=`
Referenced from: ${e}`,i}},t)},Ye=(t,e)=>{let r={},n=t;if(t.startsWith("./"))n=E.default.join(process.cwd(),t),r=Ke(n);else{let o=require.resolve(n,{paths:[E.default.dirname(e)]});r=require(o)}return Object.keys(r).length>0&&r.extends&&(r=le(r,n,e)),r},Ke=t=>{let e={};switch(E.default.extname(t)){case".js":{e=ae(t);break}case".json":{e=I(t);break}default:throw new Error(`Unsupport config file extension. File path: ${t}`)}return e},P=(t,e)=>{let r={...t};return D("Loading extends, if applicable"),r!=null&&r.hasOwnProperty("extends")&&r.extends&&(D("extends property present, applying."),r=le(r,e,e)),D("Loading extends complete"),r};var ce=g(require("path")),ge=g(require("globby")),v=require("debug")("npm-package-json-lint:applyOverrides"),J=(t,e,r,n)=>{let o={...r};return v("overrides"),v(n),n&&n.forEach(s=>{let a=s.patterns.filter(c=>c.length).map(c=>c.endsWith("/package.json")?c:`${c}/package.json`),l=ge.default.sync(a,{cwd:t,gitignore:!0});v("globFiles"),v(l),l.forEach(c=>{let m=ce.default.resolve(t,c);e===m&&(o={...o,...s.rules})})}),v("finalRules"),v(o),o};var y=require("debug")("npm-package-json-lint:cosmicConfigTransformer"),H=(t,e,r)=>(y(`cwd: ${t}`),y("configBaseDirectory"),y(e),n=>{if(y("cosmiconfigResult"),y(n),!n)return null;let{config:o,filepath:s}=n;y("cosmiconfigResult.config"),y(o),y("cosmiconfigResult.filepath"),y(s);let i=e||ue.default.dirname(s||""),a={...o},l=P(a,r);return J(t,r,l.rules,l.overrides)});var p=require("debug")("npm-package-json-lint:Config"),Qe=0,L=class{constructor(e,r,n,o,s){r&&(this.config=P(r,"PassedConfig")),this.cwd=e,this.configFile=n,this.configBaseDirectory=o,this.rules=s}getConfigForFile(e){p(`Getting config for ${e}`);let r=e;p(`filePathToSearch: ${r}`);let n;if(typeof this.config>"u")p("User passed config is undefined."),this.configFile?(p("Config file specified, loading it."),n=(0,_.cosmiconfigSync)("npmpackagejsonlint",{transform:H(this.cwd,this.configBaseDirectory,e)}).load(this.configFile)):(p("Config file wasn't specified, searching for config."),n=(0,_.cosmiconfigSync)("npmpackagejsonlint",{transform:H(this.cwd,this.configBaseDirectory,r)}).search(r));else{p("User passed config is set, using it.");let o=this.config;p(`Applying overrides to config for ${e}`),n=J(this.cwd,e,o.rules,o.overrides),p(`Overrides applied for ${e}`)}if(!n)throw new Error(`No npm-package-json-lint configuration found.
${r}`);if(Object.keys(n).length===Qe)throw new Error(`No rules specified in configuration.
${r}`);return p(`Overrides applied for ${e}`),p("Final Config"),p(n),ne(n,"cli",this.rules),n}};var pe=g(require("chalk")),me=require("fs"),B=g(require("path")),j=class{constructor(){this.rules={}}load(){let e=B.default.join(__dirname,"rules");try{return(0,me.readdirSync)(e).forEach(r=>{let s=r.slice(0,-3),i=B.default.join(e,r);this.registerRule(s,i)}),this.rules}catch(r){throw new Error(`Error while loading rules from rules directory - ${r.message}`)}}get(e){if(typeof this.rules[e]>"u"){let o=`Rule, ${e}, is invalid. Please ensure it matches a valid option.`;throw new Error(pe.default.bold.red(o))}return require(this.rules[e])}getRules(){return this.rules}registerRule(e,r){this.rules[e]=r}};var w=g(require("path"));var b=(n=>(n.Error="error",n.Warning="warning",n.Off="off",n))(b||{});var de=t=>t.reduce((r,n)=>{let o=n.severity==="error",s=o?r.errorCount+1:r.errorCount,i=o?r.warningCount:r.warningCount+1;return{errorCount:s,warningCount:i}},{errorCount:0,warningCount:0}),U=t=>t.reduce((e,r)=>({ignoreCount:r.ignored?e.ignoreCount+1:e.ignoreCount,errorCount:e.errorCount+r.errorCount,warningCount:e.warningCount+r.warningCount}),{ignoreCount:0,errorCount:0,warningCount:0});var u=require("debug")("npm-package-json-lint:linter"),G=t=>{let{cwd:e,fileName:r,ignored:n,issues:o,errorCount:s,warningCount:i}=t;return{filePath:`./${w.default.relative(e,r)}`,issues:o,ignored:n,errorCount:s,warningCount:i}},Xe=(t,e,r)=>{let n=[];for(let o in e){let s=r.get(o),i="off",a;if(s.ruleType==="array"||s.ruleType==="object"?(i=typeof e[o]=="string"&&e[o]==="off"?e[o]:e[o][0],a=typeof e[o]=="string"?{}:e[o][1]):s.ruleType==="optionalObject"?typeof e[o]=="string"?(i=e[o],a={}):(i=e[o][0],a=e[o][1]):i=e[o],i!=="off"){let l=s.lint(t,i,a);l!==null&&n.push(l)}}return n},fe=(t,e,r,n,o)=>{let s=Xe(e,r,o),i=de(s);return G({cwd:t,fileName:n,ignored:!1,issues:s,errorCount:i.errorCount,warningCount:i.warningCount})},Ze=(t,e,r,n)=>{let o=I(w.default.resolve(e));return fe(t,o,r,e,n)},ye=t=>{let{cwd:e,packageJsonObject:r,filename:n,ignorer:o,configHelper:s,rules:i}=t;u("executing on package.json object");let a=[],l=n||"",c=w.default.isAbsolute(l)?l:w.default.resolve(e,l),m=w.default.relative(e,c);if(o.ignores(m)){u(`Ignored: ${m}`);let k=G({cwd:e,fileName:c,ignored:!0,issues:[],errorCount:0,warningCount:0});a.push(k)}else{u(`Getting config for ${c}`);let k=s.getConfigForFile(c);u(`Config fetched for ${c}`);let q=fe(e,r,k,c,i);a.push(q)}u("Aggregating overall counts");let f=U(a);return u("stats"),u(f),{results:a,ignoreCount:f.ignoreCount,errorCount:f.errorCount,warningCount:f.warningCount}},he=t=>{let{cwd:e,fileList:r,ignorer:n,configHelper:o,rules:s}=t;u("executing on package.json files");let i=r.map(l=>{let c=w.default.relative(e,l);if(n.ignores(c))return u(`Ignored: ${c}`),G({cwd:e,fileName:l,ignored:!0,issues:[],errorCount:0,warningCount:0});u(`Getting config for ${l}`);let m=o.getConfigForFile(l);return u(`Config fetched for ${l}`),Ze(e,l,m,s)});u("Aggregating overall counts");let a=U(i);return u("stats"),u(a),{results:i,ignoreCount:a.ignoreCount,errorCount:a.errorCount,warningCount:a.warningCount}};var be=g(require("path")),we=g(require("globby")),d=require("debug")("npm-package-json-lint:getFileList"),ve=(t,e)=>{d("patterns"),d(t);let r=t.filter(a=>a.length);d("filteredPatterns"),d(r);let n=r.map(a=>a.endsWith("/package.json")?a:`${a}/**/package.json`);n.push("!**/node_modules/**"),d("globPatterns"),d(n);let o=[],s=new Set,i=we.default.sync(n,{cwd:e,gitignore:!0});return d("globFiles"),d(i),i.forEach(a=>{let l=be.default.resolve(e,a);s.has(l)||(s.add(l),o.push(l))}),d("Final file list from `getFileList`"),d(o),o};var je=g(require("fs")),z=g(require("path")),xe=g(require("ignore")),W=require("debug")("npm-package-json-lint:getIgnorer"),et=".npmpackagejsonlintignore",tt="ENOENT",ke=(t,e)=>{let r=e||et;W(`ignoreFilePath: ${r}`);let n=z.default.isAbsolute(r)?r:z.default.resolve(t,r);W(`absoluteIgnoreFilePath: ${n}`);let o="";try{o=je.default.readFileSync(n,"utf8")}catch(s){if(s.code!==tt)throw s}return W("Ignore text added"),(0,xe.default)().add(o)};var $=require("debug")("npm-package-json-lint:NpmPackageJsonLint"),nt=Ce(),ot=0,st=t=>t.severity==="error",Oe=t=>(0,Re.default)(t),it=(t,e)=>!e&&!Oe(t)||e&&(t||Oe(t)),at=t=>{let e=[];return t.forEach(r=>{let n=r.issues.filter(st);if(n.length>ot){let o={issues:n,errorCount:n.length,warningCount:0};e.push(Object.assign(r,o))}}),e},S=class{constructor(e){let{cwd:r,packageJsonObject:n,packageJsonFilePath:o,config:s,configFile:i,configBaseDirectory:a,patterns:l,quiet:c,ignorePath:m,fix:f}=e;this.cwd=(0,Y.default)(r||process.cwd()),this.packageJsonObject=n,this.packageJsonFilePath=o&&(0,Y.default)(o),this.patterns=l,this.quiet=c||!1,this.ignorePath=m||"",this.fix=f||!1,this.version=nt.version,this.rules=new j,this.rules.load(),this.configHelper=new L(this.cwd,s,i,a,this.rules)}lint(){if($("Starting lint"),it(this.packageJsonObject,this.patterns))throw new Error("You must pass npm-package-json-lint a `patterns` glob or a `packageJsonObject` string, though not both.");let e=ke(this.cwd,this.ignorePath),r;if(this.patterns){if($("Linting using patterns"),!Array.isArray(this.patterns))throw new TypeError("Patterns must be an array.");let n=ve(this.patterns,this.cwd);r=he({cwd:this.cwd,fileList:n,ignorer:e,configHelper:this.configHelper,rules:this.rules})}else $("Linting using passed object."),r=ye({cwd:this.cwd,packageJsonObject:this.packageJsonObject,ignorer:e,filename:this.packageJsonFilePath,configHelper:this.configHelper,rules:this.rules});return this.quiet?{results:at(r.results),ignoreCount:r.ignoreCount,errorCount:r.errorCount,warningCount:r.warningCount}:($("lint complete"),r)}};var O=g(require("chalk")),K=g(require("log-symbols"));var A=class{constructor(e,r,n,o){this.lintId=e,this.severity=r,this.node=n,this.lintMessage=o}toString(){let e=this.severity==="error"?K.default.error:K.default.warning,r=O.default.cyan.bold(this.lintId),n=O.default.magenta.bold(this.node),o=this.severity==="error"?O.default.red.bold(this.lintMessage):O.default.yellow(this.lintMessage);return`${e} ${r} - node: ${n} - ${o}`}};var h=g(require("chalk")),x=g(require("plur")),M=0,lt=1,ct=t=>{t.forEach(e=>{console.log(e.toString())})},gt=(t,e)=>{let{filePath:r,issues:n,ignored:o,errorCount:s,warningCount:i}=t;if(o)console.log(""),console.log(`${h.default.yellow.underline(r)} - ignored`);else if(s>M||!e&&i>M){console.log(""),console.log(h.default.underline(r)),ct(n);let a=`${s} ${(0,x.default)("error",s)}`,l=`${i} ${(0,x.default)("warning",i)}`;console.log(h.default.red.bold(a)),e||console.log(h.default.yellow.bold(l))}},ut=(t,e)=>{let{errorCount:r,warningCount:n,ignoreCount:o}=t;if(r>M||n>M){let s=`${r} ${(0,x.default)("error",r)}`,i=`${n} ${(0,x.default)("warning",n)}`,a=`${o} ${(0,x.default)("file",o)} ignored`;console.log(""),console.log(h.default.underline("Totals")),console.log(h.default.red.bold(s)),e||(console.log(h.default.yellow.bold(i)),console.log(h.default.yellow.bold(a)))}},Fe=(t,e)=>{t.results.forEach(r=>{gt(r,e)}),t.results.length>lt&&ut(t,e)};0&&(module.exports={LintIssue,NpmPackageJsonLint,Rules,Severity,write});
//# sourceMappingURL=api.js.map