@smarlhens/npm-check-engines 0.10.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -82,12 +82,14 @@ validatePackageJson({ packageJsonString }); // can throw Errors if unexpected fo
82
82
  validatePackageLock({ packageLockString }); // can throw Errors if unexpected format
83
83
 
84
84
  // packageJson is the content of your package.json with updated engines
85
+ // packageLock is the content of your package-lock.json with updated engines of the root project in packages
85
86
  // enginesRangeToSet contains changes if you want to display them
86
- const { enginesRangeToSet, packageJson } = checkEnginesFromString({
87
+ const { enginesRangeToSet, packageJson, packageLock } = checkEnginesFromString({
87
88
  packageJsonString,
88
89
  packageLockString,
89
90
  });
90
91
  console.log(packageJson);
92
+ console.log(packageLock);
91
93
  console.log(
92
94
  enginesRangeToSet
93
95
  .map(({ engine, range, rangeToSet }) => `${engine} range "${range}" replaced by "${rangeToSet}"`)
@@ -103,22 +105,20 @@ console.log(
103
105
  Usage: nce [options]
104
106
 
105
107
  Options:
106
- -p, --path Path to the NPM package folder. Default will use current folder. [string]
107
108
  -q, --quiet Enable quiet mode. [boolean] [default: false]
108
109
  -d, --debug Enable debug mode. Can be used with environment variable DEBUG=nce.
109
110
  [boolean] [default: false]
110
111
  -v, --verbose A little more detailed than the default output. [boolean] [default: false]
111
112
  -e, --engines Select engines to check. Default will check all engines defined. [array]
112
- -u, --update Update engines in package.json file. [boolean] [default: false]
113
+ -u, --update Update engines in package.json and package-lock.json. [boolean] [default: false]
114
+ --enableEngineStrict Enable engine strict. [boolean] [default: false]
113
115
  --help Show help [boolean]
114
116
  --version Show version number [boolean]
115
117
 
116
118
  Examples:
117
119
  nce Check package-lock.json file in current working directory.
118
- nce -p examples -u Check package-lock.json file and update engines in package.json in relative examples
119
- directory.
120
120
 
121
- © 2022 Samuel MARLHENS
121
+ © 2023 Samuel MARLHENS
122
122
  ```
123
123
 
124
124
  ---
@@ -134,79 +134,90 @@ $ DEBUG=* nce -d
134
134
  <summary>output with debug</summary>
135
135
 
136
136
  ```text
137
- [STARTED] Checking npm package engines range constraints in package-lock.json file...
138
- [TITLE] Checking npm package engines range constraints in examples\package-lock.json file...
139
- [STARTED] Load package.json file...
140
- nce Relative path to package.json: examples\package.json +0ms
141
- nce Validate JSON schema of examples\package.json +3ms
142
- [SUCCESS] Load package.json file...
143
- [STARTED] Load package-lock.json file...
144
- nce Relative path to package-lock.json: examples\package-lock.json +7ms
145
- nce Validate JSON schema of examples\package-lock.json +1ms
146
- [SUCCESS] Load package-lock.json file...
137
+ [STARTED] Checking npm package engines range constraints in package-lock.json...
138
+ [STARTED] Reading package-lock.json...
139
+ [SUCCESS] Reading package-lock.json...
140
+ [STARTED] Reading package.json...
141
+ [SUCCESS] Reading package.json...
142
+ [STARTED] Validating package-lock.json...
143
+ [SUCCESS] Validating package-lock.json...
144
+ [STARTED] Validating package.json...
145
+ [SUCCESS] Validating package.json...
147
146
  [STARTED] Compute engines range constraints...
148
147
  nce:node Package has no constraints for current engine +0ms
149
- nce:node Final computed engine range constraint: * +0ms
150
- nce:node Package has no constraints for current engine +0ms
148
+ nce:node Final computed engine range constraint: * +1ms
149
+ nce:node Package has no engines +0ms
151
150
  nce:node Compare: * and >=6.9.0 +1ms
152
151
  nce:node Range >=6.9.0 is a subset of * +1ms
153
152
  nce:node New most restrictive range: >=6.9.0 +0ms
154
153
  nce:node Compare: >=6.9.0 and >=12.22.0 +0ms
155
- nce:node Range >=12.22.0 is a subset of >=6.9.0 +1ms
154
+ nce:node Range >=12.22.0 is a subset of >=6.9.0 +0ms
156
155
  nce:node New most restrictive range: >=12.22.0 +0ms
157
156
  nce:node Ignored range: * +0ms
158
- nce:node Compare: >=12.22.0 and >=7.0.0 +0ms
157
+ nce:node Compare: >=12.22.0 and >=7.0.0 +1ms
159
158
  nce:node Range >=12.22.0 is a subset of >=7.0.0 +0ms
160
- nce:node Package node_modules/noengines has no constraints for current engine +1ms
159
+ nce:node Package node_modules/noengines has no engines +0ms
161
160
  nce:node Compare: >=12.22.0 and >=12.13.0 <13.0.0-0||>=14.15.0 <15.0.0-0||>=16.10.0 <17.0.0-0||>=17.0.0 +1ms
162
161
  nce:node Applying minimal version 12.22.0 to both ranges. +0ms
163
162
  nce:node Compare: >=12.22.0 and >=12.22.0 <13.0.0-0||>=14.15.0 <15.0.0-0||>=16.10.0 <17.0.0-0||>=17.0.0 +1ms
164
- nce:node Range >=12.22.0 <13.0.0-0||>=14.15.0 <15.0.0-0||>=16.10.0 <17.0.0-0||>=17.0.0 is a subset of >=12.22.0 +1ms
163
+ nce:node Range >=12.22.0 <13.0.0-0||>=14.15.0 <15.0.0-0||>=16.10.0 <17.0.0-0||>=17.0.0 is a subset of >=12.22.0 +0ms
165
164
  nce:node New most restrictive range: >=12.22.0 <13.0.0-0||>=14.15.0 <15.0.0-0||>=16.10.0 <17.0.0-0||>=17.0.0 +0ms
166
- nce:node Compare: >=12.22.0 <13.0.0-0||>=14.15.0 <15.0.0-0||>=16.10.0 <17.0.0-0||>=17.0.0 and >=16.0.0||>=14.17.0 <15.0.0-0 +0ms
167
- nce:node Applying minimal version 14.17.0 to both ranges. +1ms
165
+ nce:node Compare: >=12.22.0 <13.0.0-0||>=14.15.0 <15.0.0-0||>=16.10.0 <17.0.0-0||>=17.0.0 and >=16.0.0||>=14.17.0 <15.0.0-0 +1ms
166
+ nce:node Applying minimal version 14.17.0 to both ranges. +0ms
168
167
  nce:node Compare: >=14.17.0 <15.0.0-0||>=16.10.0 <17.0.0-0||>=17.0.0 and >=14.17.0 <15.0.0-0||>=16.0.0 +0ms
169
168
  nce:node Range >=14.17.0 <15.0.0-0||>=16.10.0 <17.0.0-0||>=17.0.0 is a subset of >=14.17.0 <15.0.0-0||>=16.0.0 +0ms
170
- nce:node New most restrictive range: >=14.17.0 <15.0.0-0||>=16.10.0 <17.0.0-0||>=17.0.0 +0ms
169
+ nce:node New most restrictive range: >=14.17.0 <15.0.0-0||>=16.10.0 <17.0.0-0||>=17.0.0 +1ms
171
170
  nce:node Final computed engine range constraint: >=14.17.0 <15.0.0-0||>=16.10.0 <17.0.0-0||>=17.0.0 +0ms
172
171
  nce:npm Package has no constraints for current engine +0ms
173
172
  nce:npm Final computed engine range constraint: * +0ms
174
- nce:npm Package has no constraints for current engine +0ms
173
+ nce:npm Package has no engines +0ms
175
174
  nce:npm Package node_modules/foo has no constraints for current engine +0ms
176
- nce:npm Package node_modules/bar has no constraints for current engine +0ms
175
+ nce:npm Compare: * and >=6.0.0 +1ms
176
+ nce:npm Range >=6.0.0 is a subset of * +0ms
177
+ nce:npm New most restrictive range: >=6.0.0 +0ms
177
178
  nce:npm Package node_modules/all has no constraints for current engine +0ms
178
179
  nce:npm Package node_modules/arr has no constraints for current engine +0ms
179
- nce:npm Package node_modules/noengines has no constraints for current engine +0ms
180
- nce:npm Package node_modules/complex1 has no constraints for current engine +1ms
180
+ nce:npm Package node_modules/noengines has no engines +0ms
181
+ nce:npm Package node_modules/complex1 has no constraints for current engine +0ms
181
182
  nce:npm Package node_modules/complex2 has no constraints for current engine +0ms
182
- nce:npm Final computed engine range constraint: * +0ms
183
+ nce:npm Final computed engine range constraint: >=6.0.0 +0ms
183
184
  nce:yarn Package has no constraints for current engine +0ms
184
185
  nce:yarn Final computed engine range constraint: * +0ms
185
- nce:yarn Package has no constraints for current engine +0ms
186
- nce:yarn Package node_modules/foo has no constraints for current engine +0ms
187
- nce:yarn Package node_modules/bar has no constraints for current engine +0ms
186
+ nce:yarn Package has no engines +0ms
187
+ nce:yarn Package node_modules/foo has no constraints for current engine +1ms
188
+ nce:yarn Compare: * and >=1.22.4 <2.0.0-0 +0ms
189
+ nce:yarn Range >=1.22.4 <2.0.0-0 is a subset of * +0ms
190
+ nce:yarn New most restrictive range: >=1.22.4 <2.0.0-0 +0ms
188
191
  nce:yarn Package node_modules/all has no constraints for current engine +0ms
189
- nce:yarn Package node_modules/arr has no constraints for current engine +1ms
190
- nce:yarn Package node_modules/noengines has no constraints for current engine +0ms
192
+ nce:yarn Package node_modules/arr has no constraints for current engine +0ms
193
+ nce:yarn Package node_modules/noengines has no engines +0ms
191
194
  nce:yarn Package node_modules/complex1 has no constraints for current engine +0ms
192
195
  nce:yarn Package node_modules/complex2 has no constraints for current engine +0ms
193
- nce:yarn Final computed engine range constraint: * +0ms
196
+ nce:yarn Final computed engine range constraint: >=1.22.4 <2.0.0-0 +0ms
194
197
  [SUCCESS] Compute engines range constraints...
195
198
  [STARTED] Output computed engines range constraints...
196
199
  nce:node Simplified computed engine range constraint: ^14.17.0 || ^16.10.0 || >=17.0.0 +0ms
200
+ nce:npm Simplified computed engine range constraint: >=6.0.0 +0ms
201
+ nce:yarn Simplified computed engine range constraint: ^1.22.4 +0ms
197
202
  [TITLE] Computed engines range constraints:
198
203
  [TITLE]
199
204
  [TITLE] node * → ^14.17.0 || ^16.10.0 || >=17.0.0
205
+ [TITLE] npm * → >=6.0.0
206
+ [TITLE] yarn * → ^1.22.4
200
207
  [TITLE]
201
- [TITLE] Run nce -p examples -d -u to upgrade package.json.
208
+ [TITLE] Run nce -d -u to upgrade package.json.
202
209
  [SUCCESS] Output computed engines range constraints...
203
- [STARTED] Update package.json file...
210
+ [STARTED] Enabling engine-strict using .npmrc...
211
+ [SKIPPED] Enabling engine-strict is disabled by default.
212
+ [STARTED] Updating package.json...
204
213
  [SKIPPED] Update is disabled by default.
205
214
  [SUCCESS] Computed engines range constraints:
206
215
  [SUCCESS]
207
216
  [SUCCESS] node * → ^14.17.0 || ^16.10.0 || >=17.0.0
217
+ [SUCCESS] npm * → >=6.0.0
218
+ [SUCCESS] yarn * → ^1.22.4
208
219
  [SUCCESS]
209
- [SUCCESS] Run nce -p examples -d -u to upgrade package.json.
220
+ [SUCCESS] Run nce -d -u to upgrade package.json.
210
221
  ```
211
222
 
212
223
  </details>
package/dist/bin/nce.cjs CHANGED
@@ -1,8 +1,10 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var ee=Object.create;var V=Object.defineProperty;var te=Object.getOwnPropertyDescriptor;var ne=Object.getOwnPropertyNames;var re=Object.getPrototypeOf,ae=Object.prototype.hasOwnProperty;var c=(t,e)=>V(t,"name",{value:e,configurable:!0});var ie=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of ne(e))!ae.call(t,i)&&i!==n&&V(t,i,{get:()=>e[i],enumerable:!(r=te(e,i))||r.enumerable});return t};var d=(t,e,n)=>(n=t!=null?ee(re(t)):{},ie(e||!t||!t.__esModule?V(n,"default",{value:t,enumerable:!0}):n,t));var se=c(()=>typeof document>"u"?new URL("file:"+__filename).href:document.currentScript&&document.currentScript.src||new URL("main.js",document.baseURI).href,"getImportMetaUrl"),y=se();var B=require("find-up"),G=d(require("fs/promises"),1),K=require("path"),Q=require("url"),X=d(require("update-notifier"),1);var U=d(require("ajv"),1),a=d(require("chalk"),1),A=d(require("cli-table"),1),R=d(require("constants"),1),E=d(require("debug"),1),I=require("listr2"),N=require("lodash-es"),k=d(require("fs/promises"),1),$=require("path"),o=d(require("semver"),1),M=d(require("sort-package-json"),1);var x=["node","npm","yarn"],oe="package-lock.json",ce="package.json",le="nce",w=(0,E.default)(le),pe=c(()=>E.default.disable(),"namespaces"),ge=c(t=>E.default.enable(t),"enableNamespaces"),me=c(({debug:t,quiet:e,verbose:n},r=process.env)=>{if(e)return{renderer:"silent"};if(n)return{renderer:"simple"};let i=r.TERM==="dumb";return t||i||r.NODE_ENV==="test"?{renderer:"verbose"}:{renderer:"default",rendererOptions:{dateFormat:!1}}},"renderer"),D=c(async t=>{var g;let e=t,n=c(l=>x.includes(l),"isValidConstraintEngine"),r={workingDir:(0,$.normalize)(process.cwd()),update:e.update||!1,verbose:e.verbose||!1,quiet:e.quiet||!1,debug:e.debug||!1,engines:((g=e.engines)==null?void 0:g.filter(n))||[],enableEngineStrict:e.enableEngineStrict||!1,packageLockPath:(0,$.join)(process.cwd(),oe),packageJsonPath:(0,$.join)(process.cwd(),ce)},i={...me({quiet:r.quiet,debug:r.debug,verbose:r.verbose})},s=pe();return r.debug&&ge(s),$e({options:r,context:i}).run()},"checkEnginesFromCLI"),j=new U.default,J={type:"object",properties:{engines:{anyOf:[{type:"object",additionalProperties:{type:"string"},oneOf:[{required:["node"]},{required:["npm"]},{required:["yarn"]}]},{type:"array",items:{type:"string"}},{type:"object",not:{required:["engines"]}}]}}},de={type:"object",properties:{lockfileVersion:{type:"number",enum:[1,2,3]},dependencies:{type:"object",patternProperties:{"^.*$":J}},packages:{type:"object",patternProperties:{"^.*$":J}}},required:["lockfileVersion"],oneOf:[{properties:{lockfileVersion:{const:1}},required:["dependencies"],not:{required:["packages"]}},{properties:{lockfileVersion:{const:2}},required:["dependencies"]},{properties:{lockfileVersion:{const:3}},required:["packages"],not:{required:["dependencies"]}}]},b={loose:!1},S=c(t=>[...t.map(e=>[...e])].sort((e,n)=>o.compare(e[0].semver,n[0].semver)),"sortRangeSet"),v=c(t=>new o.Range(t.map(e=>e.map(n=>n.value).join(" ")).join("||"),b),"setToRange"),L=c((t,e)=>[...t.map(n=>[...n])].filter(n=>n[0].semver.major>=e.major).map(n=>(n[0].semver.major===e.major&&o.gte(e,n[0].semver,b)&&(n[0]=new o.Comparator(`${n[0].operator}${e.raw}`)),n)),"applyMinVersionToRangeSet"),O=c((t,e,n,r)=>{if(r(`${a.default.white("Compare:")} ${a.default.blue(t.raw)} ${a.default.white("and")} ${a.default.blue(e.raw)}`),o.subset(t,e))return r(`${a.default.white("Range")} ${a.default.green(t.raw)} ${a.default.white("is a subset of")} ${a.default.blue(e.raw)}`),n.push(e.raw),t;if(o.subset(e,t))return r(`${a.default.white("Range")} ${a.default.green(e.raw)} ${a.default.white("is a subset of")} ${a.default.blue(t.raw)}`),n.push(t.raw),e;let i=o.minVersion(t,b)||new o.SemVer("*"),s=o.minVersion(e,b)||new o.SemVer("*"),g=S(t.set),l=S(e.set);if(!o.eq(i,s,b)){let C=o.compare(i,s)===-1?s:i;r(`${a.default.white("Applying minimal version")} ${a.default.yellow(C.version)} ${a.default.white("to both ranges.")}`);let q=v(L(g,C)),F=v(L(l,C));if(q.intersects(F,b))return O(q,F,n,r);throw new Error("Not yet implemented :/")}let p=g.shift(),m=l.shift(),u=p||m;if(!u)throw new Error("Not yet implemented :/");let f=[u],h=v(g),Y=v(l),Z=O(h,Y,n,r);return f.push(...S(Z.set)),v(f)},"restrictiveRange"),T=c(t=>{if(!t||t.raw==="*")return"*";let e=[];return S(t.set).forEach(r=>{let[i,s]=r;r.length===2&&i.operator===">="&&s.operator==="<"&&i.semver.major+1===s.semver.major?e.push(`^${i.semver.version}`):r.length===1&&i.operator===">="?e.push(i.value):e.push(`${i.value} ${(s==null?void 0:s.value)||""}`.trim())}),e.join(" || ")},"humanizeRange"),ue=c((t,e)=>{var n;if(typeof t=="object"&&e in t)return t[e];if((0,N.isArray)(t)&&t.some(r=>r.includes(e)))return(n=t.find(r=>r.includes(e)))==null?void 0:n.replace(e,"")},"getConstraintFromEngines"),P=c(({packages:t,constraintKey:e,debug:n})=>{let r=new o.Range("*"),i=[],s=n.extend(e);for(let[g,l]of Object.entries(t)){let{engines:p}=l;if(!p){s(`${a.default.white("Package")} ${a.default.gray(g)} ${a.default.white("has no engines")}`);continue}let m=ue(p,e);if(!m){s(`${a.default.white("Package")} ${a.default.gray(g)} ${a.default.white("has no constraints for current engine")}`);continue}let u=o.validRange(m);if(!u){s(`${a.default.red(m)} ${a.default.white("is not a valid semver range")}`);continue}if(i.indexOf(u)!==-1){s(`${a.default.white("Ignored range:")} ${a.default.gray(u)}`);continue}let f=new o.Range(u,b);if(!r){r=f,s(`${a.default.white("New most restrictive range:")} ${a.default.green(r.raw)}`);continue}let h=O(r,f,i,s);r.raw!==h.raw&&(r=h,s(`${a.default.white("New most restrictive range:")} ${a.default.green(r.raw)}`))}return s(r?`${a.default.white("Final computed engine range constraint:")} ${a.default.blue(r.raw)}`:`${a.default.white("No computed engine range constraint")}`),r},"computeEnginesConstraint"),fe=c(t=>new A.default({style:{head:[],border:[],compact:!1,"padding-left":1,"padding-right":1},colWidths:t,colAligns:["left","left","left","left"],chars:{top:"","top-mid":"","top-left":"","top-right":"",bottom:"","bottom-mid":"","bottom-left":"","bottom-right":"",left:"","left-mid":"",mid:"","mid-mid":"",right:"","right-mid":"",middle:""}}),"createOutputTable"),ke=c(t=>{let e=["nce"];return t.engines&&e.push(...t.engines.map(n=>["-e",n]).flat()),t.quiet&&e.push("-q"),t.debug&&e.push("-d"),t.verbose&&e.push("-v"),e.push("-u"),e.join(" ")},"generateUpdateCommandFromContext"),he=c(t=>{let e=JSON.parse(t.packageLockString),n=JSON.parse(t.packageJsonString),r=t.engines,i=[],s=c(p=>x.indexOf(p)!==-1,"filterEngineConstraintKey"),g=[...x];r&&r.length>0&&(g=r.filter(s));let l;e.lockfileVersion===1?l=e.dependencies:e.lockfileVersion===2?l=e.packages?e.packages:e.dependencies:e.lockfileVersion===3&&(l=e.packages);for(let p of g){let m=P({packages:{"":{engines:n.engines||{}}},constraintKey:p,debug:w}),u=P({packages:l,constraintKey:p,debug:w}),f=T(u),h=T(m);f!==h&&(i.push({engine:p,range:h,rangeToSet:f}),n.engines=(0,N.merge)({},n.engines,{[p]:f}))}return{packageJson:n,enginesRangeToSet:i}},"checkEnginesFromString"),we=c(t=>{let e=j.compile(de),n=e(JSON.parse(t.packageLockString));if(!n)throw new Error(`Invalid package-lock.json: ${j.errorsText(e.errors)}`);return n},"validatePackageLock"),be=c(t=>{let e=j.compile(J),n=e(JSON.parse(t.packageJsonString));if(!n)throw new Error(`Invalid package.json: ${j.errorsText(e.errors)}`);return n},"validatePackageJson"),ve=c(({options:t,parent:e})=>[{title:"Reading package-lock.json...",task:async n=>{n.packageLockString=await k.default.readFile(t.packageLockPath,"utf8")}},{title:"Reading package.json...",task:async n=>{n.packageJsonString=await k.default.readFile(t.packageJsonPath,"utf8")}},{title:"Validating package-lock.json...",task:n=>{we(n)}},{title:"Validating package.json...",task:n=>{be(n)}},{title:"Compute engines range constraints...",task:n=>{Object.assign(n,he(n))}},{title:"Output computed engines range constraints...",task:n=>{let r=n.enginesRangeToSet,i="\u2192",s=[2,2,2,2],g=[];for(let{engine:l,range:p,rangeToSet:m}of r)w.extend(l)(`${a.default.white("Simplified computed engine range constraint:")} ${a.default.blue(m)}`),s=[Math.max(s[0],l.length+2),Math.max(s[1],p.length+2),i.length+2,Math.max(s[3],m.length+2)],g.push([l,p,i,m]);if(r.length===0)e.title=`All computed engines range constraints are up-to-date ${a.default.green(":)")}`;else{let l=fe(s);l.push(...g);let p=`Computed engines range constraints:
2
+ "use strict";var Z=Object.create;var O=Object.defineProperty;var ee=Object.getOwnPropertyDescriptor;var ne=Object.getOwnPropertyNames;var te=Object.getPrototypeOf,re=Object.prototype.hasOwnProperty;var c=(n,e)=>O(n,"name",{value:e,configurable:!0});var ae=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of ne(e))!re.call(n,i)&&i!==t&&O(n,i,{get:()=>e[i],enumerable:!(r=ee(e,i))||r.enumerable});return n};var k=(n,e,t)=>(t=n!=null?Z(te(n)):{},ae(e||!n||!n.__esModule?O(t,"default",{value:n,enumerable:!0}):t,n));var ie=c(()=>typeof document>"u"?new URL("file:"+__filename).href:document.currentScript&&document.currentScript.src||new URL("main.js",document.baseURI).href,"getImportMetaUrl"),E=ie();var W=require("find-up"),B=k(require("fs/promises"),1),G=require("path"),K=require("url"),Q=k(require("update-notifier"),1);var T=k(require("ajv"),1),a=k(require("chalk"),1),U=k(require("cli-table"),1),J=k(require("debug"),1),A=require("listr2"),y=require("lodash-es"),d=k(require("fs/promises"),1),R=require("path"),o=k(require("semver"),1),I=k(require("sort-package-json"),1);var F=["node","npm","yarn"],se="package-lock.json",oe="package.json",ce="nce",$=(0,J.default)(ce),le=c(()=>J.default.disable(),"namespaces"),pe=c(n=>J.default.enable(n),"enableNamespaces"),ge=c(({debug:n,quiet:e,verbose:t},r=process.env)=>{if(e)return{renderer:"silent"};if(t)return{renderer:"simple"};let i=r.TERM==="dumb";return n||i||r.NODE_ENV==="test"?{renderer:"verbose"}:{renderer:"default",rendererOptions:{dateFormat:!1}}},"renderer"),M=c(async n=>{var g;let e=n,t=c(l=>F.includes(l),"isValidConstraintEngine"),r={workingDir:(0,R.normalize)(process.cwd()),update:e.update||!1,verbose:e.verbose||!1,quiet:e.quiet||!1,debug:e.debug||!1,engines:((g=e.engines)==null?void 0:g.filter(t))||[],enableEngineStrict:e.enableEngineStrict||!1,packageLockPath:(0,R.join)(process.cwd(),se),packageJsonPath:(0,R.join)(process.cwd(),oe)},i={...ge({quiet:r.quiet,debug:r.debug,verbose:r.verbose})},s=le();return r.debug&&pe(s),ve({options:r,context:i}).run()},"checkEnginesFromCLI"),C=new T.default,q={type:"object",properties:{engines:{anyOf:[{type:"object",additionalProperties:{type:"string"},oneOf:[{required:["node"]},{required:["npm"]},{required:["yarn"]}]},{type:"array",items:{type:"string"}},{type:"object",not:{required:["engines"]}}]}}},me={type:"object",properties:{lockfileVersion:{type:"number",enum:[1,2,3]},dependencies:{type:"object",patternProperties:{"^.*$":q}},packages:{type:"object",patternProperties:{"^.*$":q}}},required:["lockfileVersion"],oneOf:[{properties:{lockfileVersion:{const:1}},required:["dependencies"],not:{required:["packages"]}},{properties:{lockfileVersion:{const:2}},required:["dependencies"]},{properties:{lockfileVersion:{const:3}},required:["packages"],not:{required:["dependencies"]}}]},b={loose:!1},V=c(n=>[...n.map(e=>[...e])].sort((e,t)=>o.compare(e[0].semver,t[0].semver)),"sortRangeSet"),j=c(n=>new o.Range(n.map(e=>e.map(t=>t.value).join(" ")).join("||"),b),"setToRange"),x=c((n,e)=>[...n.map(t=>[...t])].filter(t=>t[0].semver.major>=e.major).map(t=>(t[0].semver.major===e.major&&o.gte(e,t[0].semver,b)&&(t[0]=new o.Comparator(`${t[0].operator}${e.raw}`)),t)),"applyMinVersionToRangeSet"),N=c((n,e,t,r)=>{if(r(`${a.default.white("Compare:")} ${a.default.blue(n.raw)} ${a.default.white("and")} ${a.default.blue(e.raw)}`),o.subset(n,e))return r(`${a.default.white("Range")} ${a.default.green(n.raw)} ${a.default.white("is a subset of")} ${a.default.blue(e.raw)}`),t.push(e.raw),n;if(o.subset(e,n))return r(`${a.default.white("Range")} ${a.default.green(e.raw)} ${a.default.white("is a subset of")} ${a.default.blue(n.raw)}`),t.push(n.raw),e;let i=o.minVersion(n,b)||new o.SemVer("*"),s=o.minVersion(e,b)||new o.SemVer("*"),g=V(n.set),l=V(e.set);if(!o.eq(i,s,b)){let S=o.compare(i,s)===-1?s:i;r(`${a.default.white("Applying minimal version")} ${a.default.yellow(S.version)} ${a.default.white("to both ranges.")}`);let u=j(x(g,S)),w=j(x(l,S));return u.test(S.raw)?w.test(S.raw)?u.intersects(w,b)?N(u,w,t,r):w.intersects(u,b)?N(w,u,t,r):(r(`${a.default.white("Unable to find intersection range")}: ${a.default.blue(u.raw)} and ${a.default.blue(w.raw)}, returning ${a.default.green(u.raw)}`),u):(r(`${a.default.white("Following range is not valid")}: ${a.default.red(w.raw)}, returning ${a.default.green(u.raw)}`),u):(r(`${a.default.white("Following range is not valid")}: ${a.default.red(u.raw)}, returning ${a.default.green(w.raw)}`),w)}let p=g.shift(),m=l.shift(),h=p||m;if(!h)throw new Error("Not yet implemented :/");let f=[h],v=j(g),X=j(l),Y=N(v,X,t,r);return f.push(...V(Y.set)),j(f)},"restrictiveRange"),L=c(n=>{if(!n||n.raw==="*")return"*";let e=[];return V(n.set).forEach(r=>{let[i,s]=r;r.length===2&&i.operator===">="&&s.operator==="<"&&i.semver.major+1===s.semver.major?e.push(`^${i.semver.version}`):r.length===1&&i.operator===">="?e.push(i.value):e.push(`${i.value} ${(s==null?void 0:s.value)||""}`.trim())}),e.join(" || ")},"humanizeRange"),ue=c((n,e)=>{var t;if(typeof n=="object"&&e in n)return n[e];if((0,y.isArray)(n)&&n.some(r=>r.includes(e)))return(t=n.find(r=>r.includes(e)))==null?void 0:t.replace(e,"")},"getConstraintFromEngines"),P=c(({packages:n,constraintKey:e,debug:t})=>{let r=new o.Range("*"),i=[],s=t.extend(e);for(let[g,l]of Object.entries(n)){let{engines:p}=l;if(!p){s(`${a.default.white("Package")} ${a.default.gray(g)} ${a.default.white("has no engines")}`);continue}let m=ue(p,e);if(!m){s(`${a.default.white("Package")} ${a.default.gray(g)} ${a.default.white("has no constraints for current engine")}`);continue}let h=o.validRange(m);if(!h){s(`${a.default.red(m)} ${a.default.white("is not a valid semver range")}`);continue}if(i.indexOf(h)!==-1){s(`${a.default.white("Ignored range:")} ${a.default.gray(h)}`);continue}let f=new o.Range(h,b);if(!r){r=f,s(`${a.default.white("New most restrictive range:")} ${a.default.green(r.raw)}`);continue}let v=N(r,f,i,s);r.raw!==v.raw&&(r=v,s(`${a.default.white("New most restrictive range:")} ${a.default.green(r.raw)}`))}return s(r?`${a.default.white("Final computed engine range constraint:")} ${a.default.blue(r.raw)}`:`${a.default.white("No computed engine range constraint")}`),r},"computeEnginesConstraint"),de=c(n=>new U.default({style:{head:[],border:[],compact:!1,"padding-left":1,"padding-right":1},colWidths:n,colAligns:["left","left","left","left"],chars:{top:"","top-mid":"","top-left":"","top-right":"",bottom:"","bottom-mid":"","bottom-left":"","bottom-right":"",left:"","left-mid":"",mid:"","mid-mid":"",right:"","right-mid":"",middle:""}}),"createOutputTable"),fe=c(n=>{let e=["nce"];return n.engines&&e.push(...n.engines.map(t=>["-e",t]).flat()),n.quiet&&e.push("-q"),n.debug&&e.push("-d"),n.verbose&&e.push("-v"),e.push("-u"),e.join(" ")},"generateUpdateCommandFromContext"),ke=c(n=>{let e=JSON.parse(n.packageLockString),t=JSON.parse(n.packageJsonString),r=n.engines,i=[],s=c(p=>F.indexOf(p)!==-1,"filterEngineConstraintKey"),g=[...F];r&&r.length>0&&(g=r.filter(s));let l;e.lockfileVersion===1?l=e.dependencies:e.lockfileVersion===2?l=e.packages?e.packages:e.dependencies:e.lockfileVersion===3&&(l=e.packages);for(let p of g){let m=P({packages:{"":{engines:t.engines||{}}},constraintKey:p,debug:$}),h=P({packages:(0,y.merge)({},{"":{engines:t.engines||{}}},l),constraintKey:p,debug:$}),f=L(h),v=L(m);f!==v&&(i.push({engine:p,range:v,rangeToSet:f}),t.engines=(0,y.merge)({},t.engines,{[p]:f}),(e.lockfileVersion===2||e.lockfileVersion===3)&&e.packages&&(e.packages[""].engines=(0,y.merge)({},e.packages[""].engines,{[p]:f})))}return{packageJson:t,packageLock:e,enginesRangeToSet:i}},"checkEnginesFromString"),he=c(n=>{let e=C.compile(me),t=e(JSON.parse(n.packageLockString));if(!t)throw new Error(`Invalid package-lock.json: ${C.errorsText(e.errors)}`);return t},"validatePackageLock"),we=c(n=>{let e=C.compile(q),t=e(JSON.parse(n.packageJsonString));if(!t)throw new Error(`Invalid package.json: ${C.errorsText(e.errors)}`);return t},"validatePackageJson"),be=c(({options:n,parent:e})=>[{title:"Reading package-lock.json...",task:async t=>{t.packageLockString=await d.default.readFile(n.packageLockPath,"utf8")}},{title:"Reading package.json...",task:async t=>{t.packageJsonString=await d.default.readFile(n.packageJsonPath,"utf8")}},{title:"Validating package-lock.json...",task:t=>{he(t)}},{title:"Validating package.json...",task:t=>{we(t)}},{title:"Compute engines range constraints...",task:t=>{Object.assign(t,ke((0,y.merge)({},t,{engines:n.engines})))}},{title:"Output computed engines range constraints...",task:t=>{let r=t.enginesRangeToSet,i="\u2192",s=[2,2,2,2],g=[];for(let{engine:l,range:p,rangeToSet:m}of r)$.extend(l)(`${a.default.white("Simplified computed engine range constraint:")} ${a.default.blue(m)}`),s=[Math.max(s[0],l.length+2),Math.max(s[1],p.length+2),i.length+2,Math.max(s[3],m.length+2)],g.push([l,p,i,m]);if(r.length===0)e.title=`All computed engines range constraints are up-to-date ${a.default.green(":)")}`;else{let l=de(s);l.push(...g);let p=`Computed engines range constraints:
3
3
 
4
- ${l.toString()}`;t.update||(p+=`
4
+ ${l.toString()}`;n.update||(p+=`
5
5
 
6
- Run ${a.default.cyan(ke(t))} to upgrade package.json.`),e.title=p}}},{title:"Enabling engine-strict using .npmrc...",skip:()=>t.enableEngineStrict?!t.enableEngineStrict:"Enabling engine-strict is disabled by default.",task:async()=>{let n=".npmrc";try{await k.default.access(n,R.F_OK|R.R_OK),(await k.default.readFile(n,"utf8")).includes("engine-strict=true")?w(".npmrc file already contains engine-strict=true"):(await k.default.appendFile(n,`engine-strict=true
7
- `),w(".npmrc file has been updated to set engine-strict=true"))}catch{await k.default.writeFile(n,`engine-strict=true
8
- `),w(".npmrc file has been created and set engine-strict=true")}}},{title:"Updating package.json...",skip:()=>t.update?!t.update:"Update is disabled by default.",task:n=>(w(`${a.default.white("Write JSON to")} ${a.default.blue("package.json")}`),k.default.writeFile(t.packageJsonPath,JSON.stringify((0,M.default)(n.packageJson),null,2)))}],"checkEnginesTasks"),$e=c(({options:t,context:e})=>new I.Listr([{title:"Checking npm package engines range constraints in package-lock.json...",task:(n,r)=>r.newListr(i=>ve({parent:i,options:t}))}],e),"checkEnginesCommand");var z=d(require("yargs"),1),H=require("yargs/helpers"),_=(0,z.default)((0,H.hideBin)(process.argv)),W=_.scriptName("nce").usage("Usage: $0 [options]").example("$0","Check package-lock.json file in current working directory.").strict().options({quiet:{boolean:!0,alias:"q",default:!1,description:"Enable quiet mode."},debug:{boolean:!0,alias:"d",default:!1,description:"Enable debug mode. Can be used with environment variable DEBUG=nce."},verbose:{boolean:!0,alias:"v",default:!1,description:"A little more detailed than the default output."},engines:{array:!0,alias:"e",description:"Select engines to check. Default will check all engines defined."},update:{boolean:!0,alias:"u",default:!1,description:"Update engines in package.json file."},enableEngineStrict:{boolean:!0,default:!1,description:"Enable engine strict."}}).help("help").version().wrap(_.terminalWidth()).epilog("\xA9 2022 Samuel MARLHENS").argv;(async()=>{let t=await(0,B.findUp)("package.json",{type:"file",cwd:(0,K.dirname)((0,Q.fileURLToPath)(y))}),e=JSON.parse(await G.default.readFile(t,"utf8")),n=(0,X.default)({pkg:e,updateCheckInterval:1e3*60,shouldNotifyInNpmScript:!0});n.update&&n.update.latest!==e.version&&n.notify({defer:!1,isGlobal:!0});let r=await W;await D(r)})();
6
+ Run ${a.default.cyan(fe(n))} to upgrade package.json.`),e.title=p}}},{title:"Updating package.json...",skip:()=>n.update?!n.update:"Update is disabled by default.",task:t=>($(`${a.default.white("Write JSON to")} ${a.default.blue("package.json")}`),Promise.all([d.default.writeFile(n.packageJsonPath,JSON.stringify((0,I.default)(t.packageJson),null,2)+`
7
+ `),d.default.writeFile(n.packageLockPath,JSON.stringify(t.packageLock,null,2)+`
8
+ `)]))},{title:"Enabling engine-strict using .npmrc...",skip:()=>n.enableEngineStrict?!n.enableEngineStrict:"Enabling engine-strict is disabled by default.",task:async()=>{let t=".npmrc";try{await d.default.access(t,d.default.constants.F_OK|d.default.constants.R_OK),(await d.default.readFile(t,"utf8")).includes("engine-strict=true")?$(".npmrc file already contains engine-strict=true"):(await d.default.appendFile(t,`engine-strict=true
9
+ `),$(".npmrc file has been updated to set engine-strict=true"))}catch{await d.default.writeFile(t,`engine-strict=true
10
+ `),$(".npmrc file has been created and set engine-strict=true")}}}],"checkEnginesTasks"),ve=c(({options:n,context:e})=>new A.Listr([{title:"Checking npm package engines range constraints in package-lock.json...",task:(t,r)=>r.newListr(i=>be({parent:i,options:n}))}],e),"checkEnginesCommand");var _=k(require("yargs"),1),z=require("yargs/helpers"),D=(0,_.default)((0,z.hideBin)(process.argv)),H=D.scriptName("nce").usage("Usage: $0 [options]").example("$0","Check package-lock.json file in current working directory.").strict().options({quiet:{boolean:!0,alias:"q",default:!1,description:"Enable quiet mode."},debug:{boolean:!0,alias:"d",default:!1,description:"Enable debug mode. Can be used with environment variable DEBUG=nce."},verbose:{boolean:!0,alias:"v",default:!1,description:"A little more detailed than the default output."},engines:{array:!0,alias:"e",description:"Select engines to check. Default will check all engines defined."},update:{boolean:!0,alias:"u",default:!1,description:"Update engines in package.json and package-lock.json."},enableEngineStrict:{boolean:!0,default:!1,description:"Enable engine strict."}}).help("help").version().wrap(D.terminalWidth()).epilog("\xA9 2023 Samuel MARLHENS").argv;(async()=>{let n=await(0,W.findUp)("package.json",{type:"file",cwd:(0,G.dirname)((0,K.fileURLToPath)(E))}),e=JSON.parse(await B.default.readFile(n,"utf8")),t=(0,Q.default)({pkg:e,updateCheckInterval:1e3*60,shouldNotifyInNpmScript:!0});t.update&&t.update.latest!==e.version&&t.notify({defer:!1,isGlobal:!0});let r=await H;await M(r)})();
package/dist/bin/nce.js CHANGED
@@ -1,8 +1,10 @@
1
1
  #!/usr/bin/env node
2
- var D=Object.defineProperty;var c=(t,e)=>D(t,"name",{value:e,configurable:!0});import{findUp as me}from"find-up";import de from"node:fs/promises";import{dirname as ue}from"node:path";import{fileURLToPath as fe}from"node:url";import ke from"update-notifier";import M from"ajv";import a from"chalk";import z from"cli-table";import*as y from"constants";import N from"debug";import{Listr as _}from"listr2";import{isArray as H,merge as W}from"lodash-es";import k from"node:fs/promises";import{join as J,normalize as B}from"node:path";import*as o from"semver";import G from"sort-package-json";var j=["node","npm","yarn"],K="package-lock.json",Q="package.json",X="nce",h=N(X),Y=c(()=>N.disable(),"namespaces"),Z=c(t=>N.enable(t),"enableNamespaces"),ee=c(({debug:t,quiet:e,verbose:n},r=process.env)=>{if(e)return{renderer:"silent"};if(n)return{renderer:"simple"};let s=r.TERM==="dumb";return t||s||r.NODE_ENV==="test"?{renderer:"verbose"}:{renderer:"default",rendererOptions:{dateFormat:!1}}},"renderer"),T=c(async t=>{var g;let e=t,n=c(l=>j.includes(l),"isValidConstraintEngine"),r={workingDir:B(process.cwd()),update:e.update||!1,verbose:e.verbose||!1,quiet:e.quiet||!1,debug:e.debug||!1,engines:((g=e.engines)==null?void 0:g.filter(n))||[],enableEngineStrict:e.enableEngineStrict||!1,packageLockPath:J(process.cwd(),K),packageJsonPath:J(process.cwd(),Q)},s={...ee({quiet:r.quiet,debug:r.debug,verbose:r.verbose})},i=Y();return r.debug&&Z(i),le({options:r,context:s}).run()},"checkEnginesFromCLI"),$=new M,E={type:"object",properties:{engines:{anyOf:[{type:"object",additionalProperties:{type:"string"},oneOf:[{required:["node"]},{required:["npm"]},{required:["yarn"]}]},{type:"array",items:{type:"string"}},{type:"object",not:{required:["engines"]}}]}}},te={type:"object",properties:{lockfileVersion:{type:"number",enum:[1,2,3]},dependencies:{type:"object",patternProperties:{"^.*$":E}},packages:{type:"object",patternProperties:{"^.*$":E}}},required:["lockfileVersion"],oneOf:[{properties:{lockfileVersion:{const:1}},required:["dependencies"],not:{required:["packages"]}},{properties:{lockfileVersion:{const:2}},required:["dependencies"]},{properties:{lockfileVersion:{const:3}},required:["packages"],not:{required:["dependencies"]}}]},w={loose:!1},v=c(t=>[...t.map(e=>[...e])].sort((e,n)=>o.compare(e[0].semver,n[0].semver)),"sortRangeSet"),b=c(t=>new o.Range(t.map(e=>e.map(n=>n.value).join(" ")).join("||"),w),"setToRange"),O=c((t,e)=>[...t.map(n=>[...n])].filter(n=>n[0].semver.major>=e.major).map(n=>(n[0].semver.major===e.major&&o.gte(e,n[0].semver,w)&&(n[0]=new o.Comparator(`${n[0].operator}${e.raw}`)),n)),"applyMinVersionToRangeSet"),R=c((t,e,n,r)=>{if(r(`${a.white("Compare:")} ${a.blue(t.raw)} ${a.white("and")} ${a.blue(e.raw)}`),o.subset(t,e))return r(`${a.white("Range")} ${a.green(t.raw)} ${a.white("is a subset of")} ${a.blue(e.raw)}`),n.push(e.raw),t;if(o.subset(e,t))return r(`${a.white("Range")} ${a.green(e.raw)} ${a.white("is a subset of")} ${a.blue(t.raw)}`),n.push(t.raw),e;let s=o.minVersion(t,w)||new o.SemVer("*"),i=o.minVersion(e,w)||new o.SemVer("*"),g=v(t.set),l=v(e.set);if(!o.eq(s,i,w)){let S=o.compare(s,i)===-1?i:s;r(`${a.white("Applying minimal version")} ${a.yellow(S.version)} ${a.white("to both ranges.")}`);let C=b(O(g,S)),V=b(O(l,S));if(C.intersects(V,w))return R(C,V,n,r);throw new Error("Not yet implemented :/")}let p=g.shift(),m=l.shift(),d=p||m;if(!d)throw new Error("Not yet implemented :/");let u=[d],f=b(g),U=b(l),I=R(f,U,n,r);return u.push(...v(I.set)),b(u)},"restrictiveRange"),q=c(t=>{if(!t||t.raw==="*")return"*";let e=[];return v(t.set).forEach(r=>{let[s,i]=r;r.length===2&&s.operator===">="&&i.operator==="<"&&s.semver.major+1===i.semver.major?e.push(`^${s.semver.version}`):r.length===1&&s.operator===">="?e.push(s.value):e.push(`${s.value} ${(i==null?void 0:i.value)||""}`.trim())}),e.join(" || ")},"humanizeRange"),ne=c((t,e)=>{var n;if(typeof t=="object"&&e in t)return t[e];if(H(t)&&t.some(r=>r.includes(e)))return(n=t.find(r=>r.includes(e)))==null?void 0:n.replace(e,"")},"getConstraintFromEngines"),x=c(({packages:t,constraintKey:e,debug:n})=>{let r=new o.Range("*"),s=[],i=n.extend(e);for(let[g,l]of Object.entries(t)){let{engines:p}=l;if(!p){i(`${a.white("Package")} ${a.gray(g)} ${a.white("has no engines")}`);continue}let m=ne(p,e);if(!m){i(`${a.white("Package")} ${a.gray(g)} ${a.white("has no constraints for current engine")}`);continue}let d=o.validRange(m);if(!d){i(`${a.red(m)} ${a.white("is not a valid semver range")}`);continue}if(s.indexOf(d)!==-1){i(`${a.white("Ignored range:")} ${a.gray(d)}`);continue}let u=new o.Range(d,w);if(!r){r=u,i(`${a.white("New most restrictive range:")} ${a.green(r.raw)}`);continue}let f=R(r,u,s,i);r.raw!==f.raw&&(r=f,i(`${a.white("New most restrictive range:")} ${a.green(r.raw)}`))}return i(r?`${a.white("Final computed engine range constraint:")} ${a.blue(r.raw)}`:`${a.white("No computed engine range constraint")}`),r},"computeEnginesConstraint"),re=c(t=>new z({style:{head:[],border:[],compact:!1,"padding-left":1,"padding-right":1},colWidths:t,colAligns:["left","left","left","left"],chars:{top:"","top-mid":"","top-left":"","top-right":"",bottom:"","bottom-mid":"","bottom-left":"","bottom-right":"",left:"","left-mid":"",mid:"","mid-mid":"",right:"","right-mid":"",middle:""}}),"createOutputTable"),ae=c(t=>{let e=["nce"];return t.engines&&e.push(...t.engines.map(n=>["-e",n]).flat()),t.quiet&&e.push("-q"),t.debug&&e.push("-d"),t.verbose&&e.push("-v"),e.push("-u"),e.join(" ")},"generateUpdateCommandFromContext"),ie=c(t=>{let e=JSON.parse(t.packageLockString),n=JSON.parse(t.packageJsonString),r=t.engines,s=[],i=c(p=>j.indexOf(p)!==-1,"filterEngineConstraintKey"),g=[...j];r&&r.length>0&&(g=r.filter(i));let l;e.lockfileVersion===1?l=e.dependencies:e.lockfileVersion===2?l=e.packages?e.packages:e.dependencies:e.lockfileVersion===3&&(l=e.packages);for(let p of g){let m=x({packages:{"":{engines:n.engines||{}}},constraintKey:p,debug:h}),d=x({packages:l,constraintKey:p,debug:h}),u=q(d),f=q(m);u!==f&&(s.push({engine:p,range:f,rangeToSet:u}),n.engines=W({},n.engines,{[p]:u}))}return{packageJson:n,enginesRangeToSet:s}},"checkEnginesFromString"),se=c(t=>{let e=$.compile(te),n=e(JSON.parse(t.packageLockString));if(!n)throw new Error(`Invalid package-lock.json: ${$.errorsText(e.errors)}`);return n},"validatePackageLock"),oe=c(t=>{let e=$.compile(E),n=e(JSON.parse(t.packageJsonString));if(!n)throw new Error(`Invalid package.json: ${$.errorsText(e.errors)}`);return n},"validatePackageJson"),ce=c(({options:t,parent:e})=>[{title:"Reading package-lock.json...",task:async n=>{n.packageLockString=await k.readFile(t.packageLockPath,"utf8")}},{title:"Reading package.json...",task:async n=>{n.packageJsonString=await k.readFile(t.packageJsonPath,"utf8")}},{title:"Validating package-lock.json...",task:n=>{se(n)}},{title:"Validating package.json...",task:n=>{oe(n)}},{title:"Compute engines range constraints...",task:n=>{Object.assign(n,ie(n))}},{title:"Output computed engines range constraints...",task:n=>{let r=n.enginesRangeToSet,s="\u2192",i=[2,2,2,2],g=[];for(let{engine:l,range:p,rangeToSet:m}of r)h.extend(l)(`${a.white("Simplified computed engine range constraint:")} ${a.blue(m)}`),i=[Math.max(i[0],l.length+2),Math.max(i[1],p.length+2),s.length+2,Math.max(i[3],m.length+2)],g.push([l,p,s,m]);if(r.length===0)e.title=`All computed engines range constraints are up-to-date ${a.green(":)")}`;else{let l=re(i);l.push(...g);let p=`Computed engines range constraints:
2
+ var D=Object.defineProperty;var c=(t,e)=>D(t,"name",{value:e,configurable:!0});import{findUp as pe}from"find-up";import me from"node:fs/promises";import{dirname as ue}from"node:path";import{fileURLToPath as de}from"node:url";import fe from"update-notifier";import M from"ajv";import a from"chalk";import z from"cli-table";import C from"debug";import{Listr as _}from"listr2";import{isArray as H,merge as S}from"lodash-es";import f from"node:fs/promises";import{join as J,normalize as W}from"node:path";import*as o from"semver";import B from"sort-package-json";var V=["node","npm","yarn"],G="package-lock.json",K="package.json",Q="nce",v=C(Q),X=c(()=>C.disable(),"namespaces"),Y=c(t=>C.enable(t),"enableNamespaces"),Z=c(({debug:t,quiet:e,verbose:n},r=process.env)=>{if(e)return{renderer:"silent"};if(n)return{renderer:"simple"};let s=r.TERM==="dumb";return t||s||r.NODE_ENV==="test"?{renderer:"verbose"}:{renderer:"default",rendererOptions:{dateFormat:!1}}},"renderer"),P=c(async t=>{var p;let e=t,n=c(l=>V.includes(l),"isValidConstraintEngine"),r={workingDir:W(process.cwd()),update:e.update||!1,verbose:e.verbose||!1,quiet:e.quiet||!1,debug:e.debug||!1,engines:((p=e.engines)==null?void 0:p.filter(n))||[],enableEngineStrict:e.enableEngineStrict||!1,packageLockPath:J(process.cwd(),G),packageJsonPath:J(process.cwd(),K)},s={...Z({quiet:r.quiet,debug:r.debug,verbose:r.verbose})},i=X();return r.debug&&Y(i),ce({options:r,context:s}).run()},"checkEnginesFromCLI"),R=new M,N={type:"object",properties:{engines:{anyOf:[{type:"object",additionalProperties:{type:"string"},oneOf:[{required:["node"]},{required:["npm"]},{required:["yarn"]}]},{type:"array",items:{type:"string"}},{type:"object",not:{required:["engines"]}}]}}},ee={type:"object",properties:{lockfileVersion:{type:"number",enum:[1,2,3]},dependencies:{type:"object",patternProperties:{"^.*$":N}},packages:{type:"object",patternProperties:{"^.*$":N}}},required:["lockfileVersion"],oneOf:[{properties:{lockfileVersion:{const:1}},required:["dependencies"],not:{required:["packages"]}},{properties:{lockfileVersion:{const:2}},required:["dependencies"]},{properties:{lockfileVersion:{const:3}},required:["packages"],not:{required:["dependencies"]}}]},w={loose:!1},j=c(t=>[...t.map(e=>[...e])].sort((e,n)=>o.compare(e[0].semver,n[0].semver)),"sortRangeSet"),y=c(t=>new o.Range(t.map(e=>e.map(n=>n.value).join(" ")).join("||"),w),"setToRange"),O=c((t,e)=>[...t.map(n=>[...n])].filter(n=>n[0].semver.major>=e.major).map(n=>(n[0].semver.major===e.major&&o.gte(e,n[0].semver,w)&&(n[0]=new o.Comparator(`${n[0].operator}${e.raw}`)),n)),"applyMinVersionToRangeSet"),E=c((t,e,n,r)=>{if(r(`${a.white("Compare:")} ${a.blue(t.raw)} ${a.white("and")} ${a.blue(e.raw)}`),o.subset(t,e))return r(`${a.white("Range")} ${a.green(t.raw)} ${a.white("is a subset of")} ${a.blue(e.raw)}`),n.push(e.raw),t;if(o.subset(e,t))return r(`${a.white("Range")} ${a.green(e.raw)} ${a.white("is a subset of")} ${a.blue(t.raw)}`),n.push(t.raw),e;let s=o.minVersion(t,w)||new o.SemVer("*"),i=o.minVersion(e,w)||new o.SemVer("*"),p=j(t.set),l=j(e.set);if(!o.eq(s,i,w)){let $=o.compare(s,i)===-1?i:s;r(`${a.white("Applying minimal version")} ${a.yellow($.version)} ${a.white("to both ranges.")}`);let u=y(O(p,$)),h=y(O(l,$));return u.test($.raw)?h.test($.raw)?u.intersects(h,w)?E(u,h,n,r):h.intersects(u,w)?E(h,u,n,r):(r(`${a.white("Unable to find intersection range")}: ${a.blue(u.raw)} and ${a.blue(h.raw)}, returning ${a.green(u.raw)}`),u):(r(`${a.white("Following range is not valid")}: ${a.red(h.raw)}, returning ${a.green(u.raw)}`),u):(r(`${a.white("Following range is not valid")}: ${a.red(u.raw)}, returning ${a.green(h.raw)}`),h)}let g=p.shift(),m=l.shift(),k=g||m;if(!k)throw new Error("Not yet implemented :/");let d=[k],b=y(p),U=y(l),I=E(b,U,n,r);return d.push(...j(I.set)),y(d)},"restrictiveRange"),F=c(t=>{if(!t||t.raw==="*")return"*";let e=[];return j(t.set).forEach(r=>{let[s,i]=r;r.length===2&&s.operator===">="&&i.operator==="<"&&s.semver.major+1===i.semver.major?e.push(`^${s.semver.version}`):r.length===1&&s.operator===">="?e.push(s.value):e.push(`${s.value} ${(i==null?void 0:i.value)||""}`.trim())}),e.join(" || ")},"humanizeRange"),ne=c((t,e)=>{var n;if(typeof t=="object"&&e in t)return t[e];if(H(t)&&t.some(r=>r.includes(e)))return(n=t.find(r=>r.includes(e)))==null?void 0:n.replace(e,"")},"getConstraintFromEngines"),q=c(({packages:t,constraintKey:e,debug:n})=>{let r=new o.Range("*"),s=[],i=n.extend(e);for(let[p,l]of Object.entries(t)){let{engines:g}=l;if(!g){i(`${a.white("Package")} ${a.gray(p)} ${a.white("has no engines")}`);continue}let m=ne(g,e);if(!m){i(`${a.white("Package")} ${a.gray(p)} ${a.white("has no constraints for current engine")}`);continue}let k=o.validRange(m);if(!k){i(`${a.red(m)} ${a.white("is not a valid semver range")}`);continue}if(s.indexOf(k)!==-1){i(`${a.white("Ignored range:")} ${a.gray(k)}`);continue}let d=new o.Range(k,w);if(!r){r=d,i(`${a.white("New most restrictive range:")} ${a.green(r.raw)}`);continue}let b=E(r,d,s,i);r.raw!==b.raw&&(r=b,i(`${a.white("New most restrictive range:")} ${a.green(r.raw)}`))}return i(r?`${a.white("Final computed engine range constraint:")} ${a.blue(r.raw)}`:`${a.white("No computed engine range constraint")}`),r},"computeEnginesConstraint"),te=c(t=>new z({style:{head:[],border:[],compact:!1,"padding-left":1,"padding-right":1},colWidths:t,colAligns:["left","left","left","left"],chars:{top:"","top-mid":"","top-left":"","top-right":"",bottom:"","bottom-mid":"","bottom-left":"","bottom-right":"",left:"","left-mid":"",mid:"","mid-mid":"",right:"","right-mid":"",middle:""}}),"createOutputTable"),re=c(t=>{let e=["nce"];return t.engines&&e.push(...t.engines.map(n=>["-e",n]).flat()),t.quiet&&e.push("-q"),t.debug&&e.push("-d"),t.verbose&&e.push("-v"),e.push("-u"),e.join(" ")},"generateUpdateCommandFromContext"),ae=c(t=>{let e=JSON.parse(t.packageLockString),n=JSON.parse(t.packageJsonString),r=t.engines,s=[],i=c(g=>V.indexOf(g)!==-1,"filterEngineConstraintKey"),p=[...V];r&&r.length>0&&(p=r.filter(i));let l;e.lockfileVersion===1?l=e.dependencies:e.lockfileVersion===2?l=e.packages?e.packages:e.dependencies:e.lockfileVersion===3&&(l=e.packages);for(let g of p){let m=q({packages:{"":{engines:n.engines||{}}},constraintKey:g,debug:v}),k=q({packages:S({},{"":{engines:n.engines||{}}},l),constraintKey:g,debug:v}),d=F(k),b=F(m);d!==b&&(s.push({engine:g,range:b,rangeToSet:d}),n.engines=S({},n.engines,{[g]:d}),(e.lockfileVersion===2||e.lockfileVersion===3)&&e.packages&&(e.packages[""].engines=S({},e.packages[""].engines,{[g]:d})))}return{packageJson:n,packageLock:e,enginesRangeToSet:s}},"checkEnginesFromString"),ie=c(t=>{let e=R.compile(ee),n=e(JSON.parse(t.packageLockString));if(!n)throw new Error(`Invalid package-lock.json: ${R.errorsText(e.errors)}`);return n},"validatePackageLock"),se=c(t=>{let e=R.compile(N),n=e(JSON.parse(t.packageJsonString));if(!n)throw new Error(`Invalid package.json: ${R.errorsText(e.errors)}`);return n},"validatePackageJson"),oe=c(({options:t,parent:e})=>[{title:"Reading package-lock.json...",task:async n=>{n.packageLockString=await f.readFile(t.packageLockPath,"utf8")}},{title:"Reading package.json...",task:async n=>{n.packageJsonString=await f.readFile(t.packageJsonPath,"utf8")}},{title:"Validating package-lock.json...",task:n=>{ie(n)}},{title:"Validating package.json...",task:n=>{se(n)}},{title:"Compute engines range constraints...",task:n=>{Object.assign(n,ae(S({},n,{engines:t.engines})))}},{title:"Output computed engines range constraints...",task:n=>{let r=n.enginesRangeToSet,s="\u2192",i=[2,2,2,2],p=[];for(let{engine:l,range:g,rangeToSet:m}of r)v.extend(l)(`${a.white("Simplified computed engine range constraint:")} ${a.blue(m)}`),i=[Math.max(i[0],l.length+2),Math.max(i[1],g.length+2),s.length+2,Math.max(i[3],m.length+2)],p.push([l,g,s,m]);if(r.length===0)e.title=`All computed engines range constraints are up-to-date ${a.green(":)")}`;else{let l=te(i);l.push(...p);let g=`Computed engines range constraints:
3
3
 
4
- ${l.toString()}`;t.update||(p+=`
4
+ ${l.toString()}`;t.update||(g+=`
5
5
 
6
- Run ${a.cyan(ae(t))} to upgrade package.json.`),e.title=p}}},{title:"Enabling engine-strict using .npmrc...",skip:()=>t.enableEngineStrict?!t.enableEngineStrict:"Enabling engine-strict is disabled by default.",task:async()=>{let n=".npmrc";try{await k.access(n,y.F_OK|y.R_OK),(await k.readFile(n,"utf8")).includes("engine-strict=true")?h(".npmrc file already contains engine-strict=true"):(await k.appendFile(n,`engine-strict=true
7
- `),h(".npmrc file has been updated to set engine-strict=true"))}catch{await k.writeFile(n,`engine-strict=true
8
- `),h(".npmrc file has been created and set engine-strict=true")}}},{title:"Updating package.json...",skip:()=>t.update?!t.update:"Update is disabled by default.",task:n=>(h(`${a.white("Write JSON to")} ${a.blue("package.json")}`),k.writeFile(t.packageJsonPath,JSON.stringify(G(n.packageJson),null,2)))}],"checkEnginesTasks"),le=c(({options:t,context:e})=>new _([{title:"Checking npm package engines range constraints in package-lock.json...",task:(n,r)=>r.newListr(s=>ce({parent:s,options:t}))}],e),"checkEnginesCommand");import pe from"yargs";import{hideBin as ge}from"yargs/helpers";var P=pe(ge(process.argv)),A=P.scriptName("nce").usage("Usage: $0 [options]").example("$0","Check package-lock.json file in current working directory.").strict().options({quiet:{boolean:!0,alias:"q",default:!1,description:"Enable quiet mode."},debug:{boolean:!0,alias:"d",default:!1,description:"Enable debug mode. Can be used with environment variable DEBUG=nce."},verbose:{boolean:!0,alias:"v",default:!1,description:"A little more detailed than the default output."},engines:{array:!0,alias:"e",description:"Select engines to check. Default will check all engines defined."},update:{boolean:!0,alias:"u",default:!1,description:"Update engines in package.json file."},enableEngineStrict:{boolean:!0,default:!1,description:"Enable engine strict."}}).help("help").version().wrap(P.terminalWidth()).epilog("\xA9 2022 Samuel MARLHENS").argv;(async()=>{let t=await me("package.json",{type:"file",cwd:ue(fe(import.meta.url))}),e=JSON.parse(await de.readFile(t,"utf8")),n=ke({pkg:e,updateCheckInterval:1e3*60,shouldNotifyInNpmScript:!0});n.update&&n.update.latest!==e.version&&n.notify({defer:!1,isGlobal:!0});let r=await A;await T(r)})();
6
+ Run ${a.cyan(re(t))} to upgrade package.json.`),e.title=g}}},{title:"Updating package.json...",skip:()=>t.update?!t.update:"Update is disabled by default.",task:n=>(v(`${a.white("Write JSON to")} ${a.blue("package.json")}`),Promise.all([f.writeFile(t.packageJsonPath,JSON.stringify(B(n.packageJson),null,2)+`
7
+ `),f.writeFile(t.packageLockPath,JSON.stringify(n.packageLock,null,2)+`
8
+ `)]))},{title:"Enabling engine-strict using .npmrc...",skip:()=>t.enableEngineStrict?!t.enableEngineStrict:"Enabling engine-strict is disabled by default.",task:async()=>{let n=".npmrc";try{await f.access(n,f.constants.F_OK|f.constants.R_OK),(await f.readFile(n,"utf8")).includes("engine-strict=true")?v(".npmrc file already contains engine-strict=true"):(await f.appendFile(n,`engine-strict=true
9
+ `),v(".npmrc file has been updated to set engine-strict=true"))}catch{await f.writeFile(n,`engine-strict=true
10
+ `),v(".npmrc file has been created and set engine-strict=true")}}}],"checkEnginesTasks"),ce=c(({options:t,context:e})=>new _([{title:"Checking npm package engines range constraints in package-lock.json...",task:(n,r)=>r.newListr(s=>oe({parent:s,options:t}))}],e),"checkEnginesCommand");import le from"yargs";import{hideBin as ge}from"yargs/helpers";var T=le(ge(process.argv)),A=T.scriptName("nce").usage("Usage: $0 [options]").example("$0","Check package-lock.json file in current working directory.").strict().options({quiet:{boolean:!0,alias:"q",default:!1,description:"Enable quiet mode."},debug:{boolean:!0,alias:"d",default:!1,description:"Enable debug mode. Can be used with environment variable DEBUG=nce."},verbose:{boolean:!0,alias:"v",default:!1,description:"A little more detailed than the default output."},engines:{array:!0,alias:"e",description:"Select engines to check. Default will check all engines defined."},update:{boolean:!0,alias:"u",default:!1,description:"Update engines in package.json and package-lock.json."},enableEngineStrict:{boolean:!0,default:!1,description:"Enable engine strict."}}).help("help").version().wrap(T.terminalWidth()).epilog("\xA9 2023 Samuel MARLHENS").argv;(async()=>{let t=await pe("package.json",{type:"file",cwd:ue(de(import.meta.url))}),e=JSON.parse(await me.readFile(t,"utf8")),n=fe({pkg:e,updateCheckInterval:1e3*60,shouldNotifyInNpmScript:!0});n.update&&n.update.latest!==e.version&&n.notify({defer:!1,isGlobal:!0});let r=await A;await P(r)})();
package/dist/lib/nce.cjs CHANGED
@@ -1,7 +1,9 @@
1
- "use strict";var K=Object.create;var $=Object.defineProperty;var B=Object.getOwnPropertyDescriptor;var G=Object.getOwnPropertyNames;var Q=Object.getPrototypeOf,X=Object.prototype.hasOwnProperty;var c=(n,e)=>$(n,"name",{value:e,configurable:!0});var Y=(n,e)=>{for(var t in e)$(n,t,{get:e[t],enumerable:!0})},L=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of G(e))!X.call(n,a)&&a!==t&&$(n,a,{get:()=>e[a],enumerable:!(r=B(e,a))||r.enumerable});return n};var f=(n,e,t)=>(t=n!=null?K(Q(n)):{},L(e||!n||!n.__esModule?$(t,"default",{value:n,enumerable:!0}):t,n)),Z=n=>L($({},"__esModule",{value:!0}),n);var ue={};Y(ue,{applyMinVersionToRangeSet:()=>q,checkEnginesFromCLI:()=>ie,checkEnginesFromString:()=>I,humanizeRange:()=>N,rangeOptions:()=>h,restrictiveRange:()=>R,setToRange:()=>v,sortRangeSet:()=>j,validatePackageJson:()=>U,validatePackageLock:()=>_});module.exports=Z(ue);var A=f(require("ajv"),1),s=f(require("chalk"),1),M=f(require("cli-table"),1),E=f(require("constants"),1),V=f(require("debug"),1),z=require("listr2"),O=require("lodash-es"),k=f(require("fs/promises"),1),y=require("path"),o=f(require("semver"),1),D=f(require("sort-package-json"),1);var C=["node","npm","yarn"],ee="package-lock.json",ne="package.json",te="nce",b=(0,V.default)(te),re=c(()=>V.default.disable(),"namespaces"),se=c(n=>V.default.enable(n),"enableNamespaces"),ae=c(({debug:n,quiet:e,verbose:t},r=process.env)=>{if(e)return{renderer:"silent"};if(t)return{renderer:"simple"};let a=r.TERM==="dumb";return n||a||r.NODE_ENV==="test"?{renderer:"verbose"}:{renderer:"default",rendererOptions:{dateFormat:!1}}},"renderer"),ie=c(async n=>{var l;let e=n,t=c(g=>C.includes(g),"isValidConstraintEngine"),r={workingDir:(0,y.normalize)(process.cwd()),update:e.update||!1,verbose:e.verbose||!1,quiet:e.quiet||!1,debug:e.debug||!1,engines:((l=e.engines)==null?void 0:l.filter(t))||[],enableEngineStrict:e.enableEngineStrict||!1,packageLockPath:(0,y.join)(process.cwd(),ee),packageJsonPath:(0,y.join)(process.cwd(),ne)},a={...ae({quiet:r.quiet,debug:r.debug,verbose:r.verbose})},i=re();return r.debug&&se(i),me({options:r,context:a}).run()},"checkEnginesFromCLI"),S=new A.default,J={type:"object",properties:{engines:{anyOf:[{type:"object",additionalProperties:{type:"string"},oneOf:[{required:["node"]},{required:["npm"]},{required:["yarn"]}]},{type:"array",items:{type:"string"}},{type:"object",not:{required:["engines"]}}]}}},oe={type:"object",properties:{lockfileVersion:{type:"number",enum:[1,2,3]},dependencies:{type:"object",patternProperties:{"^.*$":J}},packages:{type:"object",patternProperties:{"^.*$":J}}},required:["lockfileVersion"],oneOf:[{properties:{lockfileVersion:{const:1}},required:["dependencies"],not:{required:["packages"]}},{properties:{lockfileVersion:{const:2}},required:["dependencies"]},{properties:{lockfileVersion:{const:3}},required:["packages"],not:{required:["dependencies"]}}]},h={loose:!1},j=c(n=>[...n.map(e=>[...e])].sort((e,t)=>o.compare(e[0].semver,t[0].semver)),"sortRangeSet"),v=c(n=>new o.Range(n.map(e=>e.map(t=>t.value).join(" ")).join("||"),h),"setToRange"),q=c((n,e)=>[...n.map(t=>[...t])].filter(t=>t[0].semver.major>=e.major).map(t=>(t[0].semver.major===e.major&&o.gte(e,t[0].semver,h)&&(t[0]=new o.Comparator(`${t[0].operator}${e.raw}`)),t)),"applyMinVersionToRangeSet"),R=c((n,e,t,r)=>{if(r(`${s.default.white("Compare:")} ${s.default.blue(n.raw)} ${s.default.white("and")} ${s.default.blue(e.raw)}`),o.subset(n,e))return r(`${s.default.white("Range")} ${s.default.green(n.raw)} ${s.default.white("is a subset of")} ${s.default.blue(e.raw)}`),t.push(e.raw),n;if(o.subset(e,n))return r(`${s.default.white("Range")} ${s.default.green(e.raw)} ${s.default.white("is a subset of")} ${s.default.blue(n.raw)}`),t.push(n.raw),e;let a=o.minVersion(n,h)||new o.SemVer("*"),i=o.minVersion(e,h)||new o.SemVer("*"),l=j(n.set),g=j(e.set);if(!o.eq(a,i,h)){let x=o.compare(a,i)===-1?i:a;r(`${s.default.white("Applying minimal version")} ${s.default.yellow(x.version)} ${s.default.white("to both ranges.")}`);let F=v(q(l,x)),T=v(q(g,x));if(F.intersects(T,h))return R(F,T,t,r);throw new Error("Not yet implemented :/")}let p=l.shift(),m=g.shift(),u=p||m;if(!u)throw new Error("Not yet implemented :/");let d=[u],w=v(l),H=v(g),W=R(w,H,t,r);return d.push(...j(W.set)),v(d)},"restrictiveRange"),N=c(n=>{if(!n||n.raw==="*")return"*";let e=[];return j(n.set).forEach(r=>{let[a,i]=r;r.length===2&&a.operator===">="&&i.operator==="<"&&a.semver.major+1===i.semver.major?e.push(`^${a.semver.version}`):r.length===1&&a.operator===">="?e.push(a.value):e.push(`${a.value} ${(i==null?void 0:i.value)||""}`.trim())}),e.join(" || ")},"humanizeRange"),ce=c((n,e)=>{var t;if(typeof n=="object"&&e in n)return n[e];if((0,O.isArray)(n)&&n.some(r=>r.includes(e)))return(t=n.find(r=>r.includes(e)))==null?void 0:t.replace(e,"")},"getConstraintFromEngines"),P=c(({packages:n,constraintKey:e,debug:t})=>{let r=new o.Range("*"),a=[],i=t.extend(e);for(let[l,g]of Object.entries(n)){let{engines:p}=g;if(!p){i(`${s.default.white("Package")} ${s.default.gray(l)} ${s.default.white("has no engines")}`);continue}let m=ce(p,e);if(!m){i(`${s.default.white("Package")} ${s.default.gray(l)} ${s.default.white("has no constraints for current engine")}`);continue}let u=o.validRange(m);if(!u){i(`${s.default.red(m)} ${s.default.white("is not a valid semver range")}`);continue}if(a.indexOf(u)!==-1){i(`${s.default.white("Ignored range:")} ${s.default.gray(u)}`);continue}let d=new o.Range(u,h);if(!r){r=d,i(`${s.default.white("New most restrictive range:")} ${s.default.green(r.raw)}`);continue}let w=R(r,d,a,i);r.raw!==w.raw&&(r=w,i(`${s.default.white("New most restrictive range:")} ${s.default.green(r.raw)}`))}return i(r?`${s.default.white("Final computed engine range constraint:")} ${s.default.blue(r.raw)}`:`${s.default.white("No computed engine range constraint")}`),r},"computeEnginesConstraint"),ge=c(n=>new M.default({style:{head:[],border:[],compact:!1,"padding-left":1,"padding-right":1},colWidths:n,colAligns:["left","left","left","left"],chars:{top:"","top-mid":"","top-left":"","top-right":"",bottom:"","bottom-mid":"","bottom-left":"","bottom-right":"",left:"","left-mid":"",mid:"","mid-mid":"",right:"","right-mid":"",middle:""}}),"createOutputTable"),pe=c(n=>{let e=["nce"];return n.engines&&e.push(...n.engines.map(t=>["-e",t]).flat()),n.quiet&&e.push("-q"),n.debug&&e.push("-d"),n.verbose&&e.push("-v"),e.push("-u"),e.join(" ")},"generateUpdateCommandFromContext"),I=c(n=>{let e=JSON.parse(n.packageLockString),t=JSON.parse(n.packageJsonString),r=n.engines,a=[],i=c(p=>C.indexOf(p)!==-1,"filterEngineConstraintKey"),l=[...C];r&&r.length>0&&(l=r.filter(i));let g;e.lockfileVersion===1?g=e.dependencies:e.lockfileVersion===2?g=e.packages?e.packages:e.dependencies:e.lockfileVersion===3&&(g=e.packages);for(let p of l){let m=P({packages:{"":{engines:t.engines||{}}},constraintKey:p,debug:b}),u=P({packages:g,constraintKey:p,debug:b}),d=N(u),w=N(m);d!==w&&(a.push({engine:p,range:w,rangeToSet:d}),t.engines=(0,O.merge)({},t.engines,{[p]:d}))}return{packageJson:t,enginesRangeToSet:a}},"checkEnginesFromString"),_=c(n=>{let e=S.compile(oe),t=e(JSON.parse(n.packageLockString));if(!t)throw new Error(`Invalid package-lock.json: ${S.errorsText(e.errors)}`);return t},"validatePackageLock"),U=c(n=>{let e=S.compile(J),t=e(JSON.parse(n.packageJsonString));if(!t)throw new Error(`Invalid package.json: ${S.errorsText(e.errors)}`);return t},"validatePackageJson"),le=c(({options:n,parent:e})=>[{title:"Reading package-lock.json...",task:async t=>{t.packageLockString=await k.default.readFile(n.packageLockPath,"utf8")}},{title:"Reading package.json...",task:async t=>{t.packageJsonString=await k.default.readFile(n.packageJsonPath,"utf8")}},{title:"Validating package-lock.json...",task:t=>{_(t)}},{title:"Validating package.json...",task:t=>{U(t)}},{title:"Compute engines range constraints...",task:t=>{Object.assign(t,I(t))}},{title:"Output computed engines range constraints...",task:t=>{let r=t.enginesRangeToSet,a="\u2192",i=[2,2,2,2],l=[];for(let{engine:g,range:p,rangeToSet:m}of r)b.extend(g)(`${s.default.white("Simplified computed engine range constraint:")} ${s.default.blue(m)}`),i=[Math.max(i[0],g.length+2),Math.max(i[1],p.length+2),a.length+2,Math.max(i[3],m.length+2)],l.push([g,p,a,m]);if(r.length===0)e.title=`All computed engines range constraints are up-to-date ${s.default.green(":)")}`;else{let g=ge(i);g.push(...l);let p=`Computed engines range constraints:
1
+ "use strict";var W=Object.create;var R=Object.defineProperty;var K=Object.getOwnPropertyDescriptor;var B=Object.getOwnPropertyNames;var G=Object.getPrototypeOf,Q=Object.prototype.hasOwnProperty;var c=(n,e)=>R(n,"name",{value:e,configurable:!0});var X=(n,e)=>{for(var t in e)R(n,t,{get:e[t],enumerable:!0})},L=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of B(e))!Q.call(n,a)&&a!==t&&R(n,a,{get:()=>e[a],enumerable:!(r=K(e,a))||r.enumerable});return n};var $=(n,e,t)=>(t=n!=null?W(G(n)):{},L(e||!n||!n.__esModule?R(t,"default",{value:n,enumerable:!0}):t,n)),Y=n=>L(R({},"__esModule",{value:!0}),n);var me={};X(me,{applyMinVersionToRangeSet:()=>x,checkEnginesFromCLI:()=>ae,checkEnginesFromString:()=>D,humanizeRange:()=>N,rangeOptions:()=>h,restrictiveRange:()=>E,setToRange:()=>y,sortRangeSet:()=>V,validatePackageJson:()=>U,validatePackageLock:()=>I});module.exports=Y(me);var T=$(require("ajv"),1),s=$(require("chalk"),1),A=$(require("cli-table"),1),J=$(require("debug"),1),M=require("listr2"),j=require("lodash-es"),d=$(require("fs/promises"),1),O=require("path"),o=$(require("semver"),1),z=$(require("sort-package-json"),1);var C=["node","npm","yarn"],Z="package-lock.json",ee="package.json",ne="nce",v=(0,J.default)(ne),te=c(()=>J.default.disable(),"namespaces"),re=c(n=>J.default.enable(n),"enableNamespaces"),se=c(({debug:n,quiet:e,verbose:t},r=process.env)=>{if(e)return{renderer:"silent"};if(t)return{renderer:"simple"};let a=r.TERM==="dumb";return n||a||r.NODE_ENV==="test"?{renderer:"verbose"}:{renderer:"default",rendererOptions:{dateFormat:!1}}},"renderer"),ae=c(async n=>{var p;let e=n,t=c(g=>C.includes(g),"isValidConstraintEngine"),r={workingDir:(0,O.normalize)(process.cwd()),update:e.update||!1,verbose:e.verbose||!1,quiet:e.quiet||!1,debug:e.debug||!1,engines:((p=e.engines)==null?void 0:p.filter(t))||[],enableEngineStrict:e.enableEngineStrict||!1,packageLockPath:(0,O.join)(process.cwd(),Z),packageJsonPath:(0,O.join)(process.cwd(),ee)},a={...se({quiet:r.quiet,debug:r.debug,verbose:r.verbose})},i=te();return r.debug&&re(i),pe({options:r,context:a}).run()},"checkEnginesFromCLI"),F=new T.default,q={type:"object",properties:{engines:{anyOf:[{type:"object",additionalProperties:{type:"string"},oneOf:[{required:["node"]},{required:["npm"]},{required:["yarn"]}]},{type:"array",items:{type:"string"}},{type:"object",not:{required:["engines"]}}]}}},ie={type:"object",properties:{lockfileVersion:{type:"number",enum:[1,2,3]},dependencies:{type:"object",patternProperties:{"^.*$":q}},packages:{type:"object",patternProperties:{"^.*$":q}}},required:["lockfileVersion"],oneOf:[{properties:{lockfileVersion:{const:1}},required:["dependencies"],not:{required:["packages"]}},{properties:{lockfileVersion:{const:2}},required:["dependencies"]},{properties:{lockfileVersion:{const:3}},required:["packages"],not:{required:["dependencies"]}}]},h={loose:!1},V=c(n=>[...n.map(e=>[...e])].sort((e,t)=>o.compare(e[0].semver,t[0].semver)),"sortRangeSet"),y=c(n=>new o.Range(n.map(e=>e.map(t=>t.value).join(" ")).join("||"),h),"setToRange"),x=c((n,e)=>[...n.map(t=>[...t])].filter(t=>t[0].semver.major>=e.major).map(t=>(t[0].semver.major===e.major&&o.gte(e,t[0].semver,h)&&(t[0]=new o.Comparator(`${t[0].operator}${e.raw}`)),t)),"applyMinVersionToRangeSet"),E=c((n,e,t,r)=>{if(r(`${s.default.white("Compare:")} ${s.default.blue(n.raw)} ${s.default.white("and")} ${s.default.blue(e.raw)}`),o.subset(n,e))return r(`${s.default.white("Range")} ${s.default.green(n.raw)} ${s.default.white("is a subset of")} ${s.default.blue(e.raw)}`),t.push(e.raw),n;if(o.subset(e,n))return r(`${s.default.white("Range")} ${s.default.green(e.raw)} ${s.default.white("is a subset of")} ${s.default.blue(n.raw)}`),t.push(n.raw),e;let a=o.minVersion(n,h)||new o.SemVer("*"),i=o.minVersion(e,h)||new o.SemVer("*"),p=V(n.set),g=V(e.set);if(!o.eq(a,i,h)){let S=o.compare(a,i)===-1?i:a;r(`${s.default.white("Applying minimal version")} ${s.default.yellow(S.version)} ${s.default.white("to both ranges.")}`);let u=y(x(p,S)),w=y(x(g,S));return u.test(S.raw)?w.test(S.raw)?u.intersects(w,h)?E(u,w,t,r):w.intersects(u,h)?E(w,u,t,r):(r(`${s.default.white("Unable to find intersection range")}: ${s.default.blue(u.raw)} and ${s.default.blue(w.raw)}, returning ${s.default.green(u.raw)}`),u):(r(`${s.default.white("Following range is not valid")}: ${s.default.red(w.raw)}, returning ${s.default.green(u.raw)}`),u):(r(`${s.default.white("Following range is not valid")}: ${s.default.red(u.raw)}, returning ${s.default.green(w.raw)}`),w)}let l=p.shift(),m=g.shift(),k=l||m;if(!k)throw new Error("Not yet implemented :/");let f=[k],b=y(p),_=y(g),H=E(b,_,t,r);return f.push(...V(H.set)),y(f)},"restrictiveRange"),N=c(n=>{if(!n||n.raw==="*")return"*";let e=[];return V(n.set).forEach(r=>{let[a,i]=r;r.length===2&&a.operator===">="&&i.operator==="<"&&a.semver.major+1===i.semver.major?e.push(`^${a.semver.version}`):r.length===1&&a.operator===">="?e.push(a.value):e.push(`${a.value} ${(i==null?void 0:i.value)||""}`.trim())}),e.join(" || ")},"humanizeRange"),oe=c((n,e)=>{var t;if(typeof n=="object"&&e in n)return n[e];if((0,j.isArray)(n)&&n.some(r=>r.includes(e)))return(t=n.find(r=>r.includes(e)))==null?void 0:t.replace(e,"")},"getConstraintFromEngines"),P=c(({packages:n,constraintKey:e,debug:t})=>{let r=new o.Range("*"),a=[],i=t.extend(e);for(let[p,g]of Object.entries(n)){let{engines:l}=g;if(!l){i(`${s.default.white("Package")} ${s.default.gray(p)} ${s.default.white("has no engines")}`);continue}let m=oe(l,e);if(!m){i(`${s.default.white("Package")} ${s.default.gray(p)} ${s.default.white("has no constraints for current engine")}`);continue}let k=o.validRange(m);if(!k){i(`${s.default.red(m)} ${s.default.white("is not a valid semver range")}`);continue}if(a.indexOf(k)!==-1){i(`${s.default.white("Ignored range:")} ${s.default.gray(k)}`);continue}let f=new o.Range(k,h);if(!r){r=f,i(`${s.default.white("New most restrictive range:")} ${s.default.green(r.raw)}`);continue}let b=E(r,f,a,i);r.raw!==b.raw&&(r=b,i(`${s.default.white("New most restrictive range:")} ${s.default.green(r.raw)}`))}return i(r?`${s.default.white("Final computed engine range constraint:")} ${s.default.blue(r.raw)}`:`${s.default.white("No computed engine range constraint")}`),r},"computeEnginesConstraint"),ce=c(n=>new A.default({style:{head:[],border:[],compact:!1,"padding-left":1,"padding-right":1},colWidths:n,colAligns:["left","left","left","left"],chars:{top:"","top-mid":"","top-left":"","top-right":"",bottom:"","bottom-mid":"","bottom-left":"","bottom-right":"",left:"","left-mid":"",mid:"","mid-mid":"",right:"","right-mid":"",middle:""}}),"createOutputTable"),ge=c(n=>{let e=["nce"];return n.engines&&e.push(...n.engines.map(t=>["-e",t]).flat()),n.quiet&&e.push("-q"),n.debug&&e.push("-d"),n.verbose&&e.push("-v"),e.push("-u"),e.join(" ")},"generateUpdateCommandFromContext"),D=c(n=>{let e=JSON.parse(n.packageLockString),t=JSON.parse(n.packageJsonString),r=n.engines,a=[],i=c(l=>C.indexOf(l)!==-1,"filterEngineConstraintKey"),p=[...C];r&&r.length>0&&(p=r.filter(i));let g;e.lockfileVersion===1?g=e.dependencies:e.lockfileVersion===2?g=e.packages?e.packages:e.dependencies:e.lockfileVersion===3&&(g=e.packages);for(let l of p){let m=P({packages:{"":{engines:t.engines||{}}},constraintKey:l,debug:v}),k=P({packages:(0,j.merge)({},{"":{engines:t.engines||{}}},g),constraintKey:l,debug:v}),f=N(k),b=N(m);f!==b&&(a.push({engine:l,range:b,rangeToSet:f}),t.engines=(0,j.merge)({},t.engines,{[l]:f}),(e.lockfileVersion===2||e.lockfileVersion===3)&&e.packages&&(e.packages[""].engines=(0,j.merge)({},e.packages[""].engines,{[l]:f})))}return{packageJson:t,packageLock:e,enginesRangeToSet:a}},"checkEnginesFromString"),I=c(n=>{let e=F.compile(ie),t=e(JSON.parse(n.packageLockString));if(!t)throw new Error(`Invalid package-lock.json: ${F.errorsText(e.errors)}`);return t},"validatePackageLock"),U=c(n=>{let e=F.compile(q),t=e(JSON.parse(n.packageJsonString));if(!t)throw new Error(`Invalid package.json: ${F.errorsText(e.errors)}`);return t},"validatePackageJson"),le=c(({options:n,parent:e})=>[{title:"Reading package-lock.json...",task:async t=>{t.packageLockString=await d.default.readFile(n.packageLockPath,"utf8")}},{title:"Reading package.json...",task:async t=>{t.packageJsonString=await d.default.readFile(n.packageJsonPath,"utf8")}},{title:"Validating package-lock.json...",task:t=>{I(t)}},{title:"Validating package.json...",task:t=>{U(t)}},{title:"Compute engines range constraints...",task:t=>{Object.assign(t,D((0,j.merge)({},t,{engines:n.engines})))}},{title:"Output computed engines range constraints...",task:t=>{let r=t.enginesRangeToSet,a="\u2192",i=[2,2,2,2],p=[];for(let{engine:g,range:l,rangeToSet:m}of r)v.extend(g)(`${s.default.white("Simplified computed engine range constraint:")} ${s.default.blue(m)}`),i=[Math.max(i[0],g.length+2),Math.max(i[1],l.length+2),a.length+2,Math.max(i[3],m.length+2)],p.push([g,l,a,m]);if(r.length===0)e.title=`All computed engines range constraints are up-to-date ${s.default.green(":)")}`;else{let g=ce(i);g.push(...p);let l=`Computed engines range constraints:
2
2
 
3
- ${g.toString()}`;n.update||(p+=`
3
+ ${g.toString()}`;n.update||(l+=`
4
4
 
5
- Run ${s.default.cyan(pe(n))} to upgrade package.json.`),e.title=p}}},{title:"Enabling engine-strict using .npmrc...",skip:()=>n.enableEngineStrict?!n.enableEngineStrict:"Enabling engine-strict is disabled by default.",task:async()=>{let t=".npmrc";try{await k.default.access(t,E.F_OK|E.R_OK),(await k.default.readFile(t,"utf8")).includes("engine-strict=true")?b(".npmrc file already contains engine-strict=true"):(await k.default.appendFile(t,`engine-strict=true
6
- `),b(".npmrc file has been updated to set engine-strict=true"))}catch{await k.default.writeFile(t,`engine-strict=true
7
- `),b(".npmrc file has been created and set engine-strict=true")}}},{title:"Updating package.json...",skip:()=>n.update?!n.update:"Update is disabled by default.",task:t=>(b(`${s.default.white("Write JSON to")} ${s.default.blue("package.json")}`),k.default.writeFile(n.packageJsonPath,JSON.stringify((0,D.default)(t.packageJson),null,2)))}],"checkEnginesTasks"),me=c(({options:n,context:e})=>new z.Listr([{title:"Checking npm package engines range constraints in package-lock.json...",task:(t,r)=>r.newListr(a=>le({parent:a,options:n}))}],e),"checkEnginesCommand");0&&(module.exports={applyMinVersionToRangeSet,checkEnginesFromCLI,checkEnginesFromString,humanizeRange,rangeOptions,restrictiveRange,setToRange,sortRangeSet,validatePackageJson,validatePackageLock});
5
+ Run ${s.default.cyan(ge(n))} to upgrade package.json.`),e.title=l}}},{title:"Updating package.json...",skip:()=>n.update?!n.update:"Update is disabled by default.",task:t=>(v(`${s.default.white("Write JSON to")} ${s.default.blue("package.json")}`),Promise.all([d.default.writeFile(n.packageJsonPath,JSON.stringify((0,z.default)(t.packageJson),null,2)+`
6
+ `),d.default.writeFile(n.packageLockPath,JSON.stringify(t.packageLock,null,2)+`
7
+ `)]))},{title:"Enabling engine-strict using .npmrc...",skip:()=>n.enableEngineStrict?!n.enableEngineStrict:"Enabling engine-strict is disabled by default.",task:async()=>{let t=".npmrc";try{await d.default.access(t,d.default.constants.F_OK|d.default.constants.R_OK),(await d.default.readFile(t,"utf8")).includes("engine-strict=true")?v(".npmrc file already contains engine-strict=true"):(await d.default.appendFile(t,`engine-strict=true
8
+ `),v(".npmrc file has been updated to set engine-strict=true"))}catch{await d.default.writeFile(t,`engine-strict=true
9
+ `),v(".npmrc file has been created and set engine-strict=true")}}}],"checkEnginesTasks"),pe=c(({options:n,context:e})=>new M.Listr([{title:"Checking npm package engines range constraints in package-lock.json...",task:(t,r)=>r.newListr(a=>le({parent:a,options:n}))}],e),"checkEnginesCommand");0&&(module.exports={applyMinVersionToRangeSet,checkEnginesFromCLI,checkEnginesFromString,humanizeRange,rangeOptions,restrictiveRange,setToRange,sortRangeSet,validatePackageJson,validatePackageLock});
package/dist/lib/nce.js CHANGED
@@ -1,7 +1,9 @@
1
- var L=Object.defineProperty;var c=(n,e)=>L(n,"name",{value:e,configurable:!0});import P from"ajv";import s from"chalk";import A from"cli-table";import*as j from"constants";import V from"debug";import{Listr as M}from"listr2";import{isArray as z,merge as D}from"lodash-es";import k from"node:fs/promises";import{join as C,normalize as I}from"node:path";import*as o from"semver";import _ from"sort-package-json";var S=["node","npm","yarn"],U="package-lock.json",H="package.json",W="nce",h=V(W),K=c(()=>V.disable(),"namespaces"),B=c(n=>V.enable(n),"enableNamespaces"),G=c(({debug:n,quiet:e,verbose:t},r=process.env)=>{if(e)return{renderer:"silent"};if(t)return{renderer:"simple"};let i=r.TERM==="dumb";return n||i||r.NODE_ENV==="test"?{renderer:"verbose"}:{renderer:"default",rendererOptions:{dateFormat:!1}}},"renderer"),he=c(async n=>{var l;let e=n,t=c(g=>S.includes(g),"isValidConstraintEngine"),r={workingDir:I(process.cwd()),update:e.update||!1,verbose:e.verbose||!1,quiet:e.quiet||!1,debug:e.debug||!1,engines:((l=e.engines)==null?void 0:l.filter(t))||[],enableEngineStrict:e.enableEngineStrict||!1,packageLockPath:C(process.cwd(),U),packageJsonPath:C(process.cwd(),H)},i={...G({quiet:r.quiet,debug:r.debug,verbose:r.verbose})},a=K();return r.debug&&B(a),se({options:r,context:i}).run()},"checkEnginesFromCLI"),$=new P,R={type:"object",properties:{engines:{anyOf:[{type:"object",additionalProperties:{type:"string"},oneOf:[{required:["node"]},{required:["npm"]},{required:["yarn"]}]},{type:"array",items:{type:"string"}},{type:"object",not:{required:["engines"]}}]}}},Q={type:"object",properties:{lockfileVersion:{type:"number",enum:[1,2,3]},dependencies:{type:"object",patternProperties:{"^.*$":R}},packages:{type:"object",patternProperties:{"^.*$":R}}},required:["lockfileVersion"],oneOf:[{properties:{lockfileVersion:{const:1}},required:["dependencies"],not:{required:["packages"]}},{properties:{lockfileVersion:{const:2}},required:["dependencies"]},{properties:{lockfileVersion:{const:3}},required:["packages"],not:{required:["dependencies"]}}]},w={loose:!1},v=c(n=>[...n.map(e=>[...e])].sort((e,t)=>o.compare(e[0].semver,t[0].semver)),"sortRangeSet"),b=c(n=>new o.Range(n.map(e=>e.map(t=>t.value).join(" ")).join("||"),w),"setToRange"),J=c((n,e)=>[...n.map(t=>[...t])].filter(t=>t[0].semver.major>=e.major).map(t=>(t[0].semver.major===e.major&&o.gte(e,t[0].semver,w)&&(t[0]=new o.Comparator(`${t[0].operator}${e.raw}`)),t)),"applyMinVersionToRangeSet"),E=c((n,e,t,r)=>{if(r(`${s.white("Compare:")} ${s.blue(n.raw)} ${s.white("and")} ${s.blue(e.raw)}`),o.subset(n,e))return r(`${s.white("Range")} ${s.green(n.raw)} ${s.white("is a subset of")} ${s.blue(e.raw)}`),t.push(e.raw),n;if(o.subset(e,n))return r(`${s.white("Range")} ${s.green(e.raw)} ${s.white("is a subset of")} ${s.blue(n.raw)}`),t.push(n.raw),e;let i=o.minVersion(n,w)||new o.SemVer("*"),a=o.minVersion(e,w)||new o.SemVer("*"),l=v(n.set),g=v(e.set);if(!o.eq(i,a,w)){let y=o.compare(i,a)===-1?a:i;r(`${s.white("Applying minimal version")} ${s.yellow(y.version)} ${s.white("to both ranges.")}`);let O=b(J(l,y)),x=b(J(g,y));if(O.intersects(x,w))return E(O,x,t,r);throw new Error("Not yet implemented :/")}let p=l.shift(),m=g.shift(),u=p||m;if(!u)throw new Error("Not yet implemented :/");let d=[u],f=b(l),F=b(g),T=E(f,F,t,r);return d.push(...v(T.set)),b(d)},"restrictiveRange"),q=c(n=>{if(!n||n.raw==="*")return"*";let e=[];return v(n.set).forEach(r=>{let[i,a]=r;r.length===2&&i.operator===">="&&a.operator==="<"&&i.semver.major+1===a.semver.major?e.push(`^${i.semver.version}`):r.length===1&&i.operator===">="?e.push(i.value):e.push(`${i.value} ${(a==null?void 0:a.value)||""}`.trim())}),e.join(" || ")},"humanizeRange"),X=c((n,e)=>{var t;if(typeof n=="object"&&e in n)return n[e];if(z(n)&&n.some(r=>r.includes(e)))return(t=n.find(r=>r.includes(e)))==null?void 0:t.replace(e,"")},"getConstraintFromEngines"),N=c(({packages:n,constraintKey:e,debug:t})=>{let r=new o.Range("*"),i=[],a=t.extend(e);for(let[l,g]of Object.entries(n)){let{engines:p}=g;if(!p){a(`${s.white("Package")} ${s.gray(l)} ${s.white("has no engines")}`);continue}let m=X(p,e);if(!m){a(`${s.white("Package")} ${s.gray(l)} ${s.white("has no constraints for current engine")}`);continue}let u=o.validRange(m);if(!u){a(`${s.red(m)} ${s.white("is not a valid semver range")}`);continue}if(i.indexOf(u)!==-1){a(`${s.white("Ignored range:")} ${s.gray(u)}`);continue}let d=new o.Range(u,w);if(!r){r=d,a(`${s.white("New most restrictive range:")} ${s.green(r.raw)}`);continue}let f=E(r,d,i,a);r.raw!==f.raw&&(r=f,a(`${s.white("New most restrictive range:")} ${s.green(r.raw)}`))}return a(r?`${s.white("Final computed engine range constraint:")} ${s.blue(r.raw)}`:`${s.white("No computed engine range constraint")}`),r},"computeEnginesConstraint"),Y=c(n=>new A({style:{head:[],border:[],compact:!1,"padding-left":1,"padding-right":1},colWidths:n,colAligns:["left","left","left","left"],chars:{top:"","top-mid":"","top-left":"","top-right":"",bottom:"","bottom-mid":"","bottom-left":"","bottom-right":"",left:"","left-mid":"",mid:"","mid-mid":"",right:"","right-mid":"",middle:""}}),"createOutputTable"),Z=c(n=>{let e=["nce"];return n.engines&&e.push(...n.engines.map(t=>["-e",t]).flat()),n.quiet&&e.push("-q"),n.debug&&e.push("-d"),n.verbose&&e.push("-v"),e.push("-u"),e.join(" ")},"generateUpdateCommandFromContext"),ee=c(n=>{let e=JSON.parse(n.packageLockString),t=JSON.parse(n.packageJsonString),r=n.engines,i=[],a=c(p=>S.indexOf(p)!==-1,"filterEngineConstraintKey"),l=[...S];r&&r.length>0&&(l=r.filter(a));let g;e.lockfileVersion===1?g=e.dependencies:e.lockfileVersion===2?g=e.packages?e.packages:e.dependencies:e.lockfileVersion===3&&(g=e.packages);for(let p of l){let m=N({packages:{"":{engines:t.engines||{}}},constraintKey:p,debug:h}),u=N({packages:g,constraintKey:p,debug:h}),d=q(u),f=q(m);d!==f&&(i.push({engine:p,range:f,rangeToSet:d}),t.engines=D({},t.engines,{[p]:d}))}return{packageJson:t,enginesRangeToSet:i}},"checkEnginesFromString"),ne=c(n=>{let e=$.compile(Q),t=e(JSON.parse(n.packageLockString));if(!t)throw new Error(`Invalid package-lock.json: ${$.errorsText(e.errors)}`);return t},"validatePackageLock"),te=c(n=>{let e=$.compile(R),t=e(JSON.parse(n.packageJsonString));if(!t)throw new Error(`Invalid package.json: ${$.errorsText(e.errors)}`);return t},"validatePackageJson"),re=c(({options:n,parent:e})=>[{title:"Reading package-lock.json...",task:async t=>{t.packageLockString=await k.readFile(n.packageLockPath,"utf8")}},{title:"Reading package.json...",task:async t=>{t.packageJsonString=await k.readFile(n.packageJsonPath,"utf8")}},{title:"Validating package-lock.json...",task:t=>{ne(t)}},{title:"Validating package.json...",task:t=>{te(t)}},{title:"Compute engines range constraints...",task:t=>{Object.assign(t,ee(t))}},{title:"Output computed engines range constraints...",task:t=>{let r=t.enginesRangeToSet,i="\u2192",a=[2,2,2,2],l=[];for(let{engine:g,range:p,rangeToSet:m}of r)h.extend(g)(`${s.white("Simplified computed engine range constraint:")} ${s.blue(m)}`),a=[Math.max(a[0],g.length+2),Math.max(a[1],p.length+2),i.length+2,Math.max(a[3],m.length+2)],l.push([g,p,i,m]);if(r.length===0)e.title=`All computed engines range constraints are up-to-date ${s.green(":)")}`;else{let g=Y(a);g.push(...l);let p=`Computed engines range constraints:
1
+ var P=Object.defineProperty;var c=(n,e)=>P(n,"name",{value:e,configurable:!0});import T from"ajv";import s from"chalk";import A from"cli-table";import F from"debug";import{Listr as M}from"listr2";import{isArray as z,merge as y}from"lodash-es";import f from"node:fs/promises";import{join as J,normalize as D}from"node:path";import*as o from"semver";import I from"sort-package-json";var E=["node","npm","yarn"],U="package-lock.json",_="package.json",H="nce",$=F(H),W=c(()=>F.disable(),"namespaces"),K=c(n=>F.enable(n),"enableNamespaces"),B=c(({debug:n,quiet:e,verbose:t},r=process.env)=>{if(e)return{renderer:"silent"};if(t)return{renderer:"simple"};let i=r.TERM==="dumb";return n||i||r.NODE_ENV==="test"?{renderer:"verbose"}:{renderer:"default",rendererOptions:{dateFormat:!1}}},"renderer"),ke=c(async n=>{var p;let e=n,t=c(g=>E.includes(g),"isValidConstraintEngine"),r={workingDir:D(process.cwd()),update:e.update||!1,verbose:e.verbose||!1,quiet:e.quiet||!1,debug:e.debug||!1,engines:((p=e.engines)==null?void 0:p.filter(t))||[],enableEngineStrict:e.enableEngineStrict||!1,packageLockPath:J(process.cwd(),U),packageJsonPath:J(process.cwd(),_)},i={...B({quiet:r.quiet,debug:r.debug,verbose:r.verbose})},a=W();return r.debug&&K(a),re({options:r,context:i}).run()},"checkEnginesFromCLI"),V=new T,O={type:"object",properties:{engines:{anyOf:[{type:"object",additionalProperties:{type:"string"},oneOf:[{required:["node"]},{required:["npm"]},{required:["yarn"]}]},{type:"array",items:{type:"string"}},{type:"object",not:{required:["engines"]}}]}}},G={type:"object",properties:{lockfileVersion:{type:"number",enum:[1,2,3]},dependencies:{type:"object",patternProperties:{"^.*$":O}},packages:{type:"object",patternProperties:{"^.*$":O}}},required:["lockfileVersion"],oneOf:[{properties:{lockfileVersion:{const:1}},required:["dependencies"],not:{required:["packages"]}},{properties:{lockfileVersion:{const:2}},required:["dependencies"]},{properties:{lockfileVersion:{const:3}},required:["packages"],not:{required:["dependencies"]}}]},h={loose:!1},S=c(n=>[...n.map(e=>[...e])].sort((e,t)=>o.compare(e[0].semver,t[0].semver)),"sortRangeSet"),j=c(n=>new o.Range(n.map(e=>e.map(t=>t.value).join(" ")).join("||"),h),"setToRange"),C=c((n,e)=>[...n.map(t=>[...t])].filter(t=>t[0].semver.major>=e.major).map(t=>(t[0].semver.major===e.major&&o.gte(e,t[0].semver,h)&&(t[0]=new o.Comparator(`${t[0].operator}${e.raw}`)),t)),"applyMinVersionToRangeSet"),R=c((n,e,t,r)=>{if(r(`${s.white("Compare:")} ${s.blue(n.raw)} ${s.white("and")} ${s.blue(e.raw)}`),o.subset(n,e))return r(`${s.white("Range")} ${s.green(n.raw)} ${s.white("is a subset of")} ${s.blue(e.raw)}`),t.push(e.raw),n;if(o.subset(e,n))return r(`${s.white("Range")} ${s.green(e.raw)} ${s.white("is a subset of")} ${s.blue(n.raw)}`),t.push(n.raw),e;let i=o.minVersion(n,h)||new o.SemVer("*"),a=o.minVersion(e,h)||new o.SemVer("*"),p=S(n.set),g=S(e.set);if(!o.eq(i,a,h)){let v=o.compare(i,a)===-1?a:i;r(`${s.white("Applying minimal version")} ${s.yellow(v.version)} ${s.white("to both ranges.")}`);let u=j(C(p,v)),w=j(C(g,v));return u.test(v.raw)?w.test(v.raw)?u.intersects(w,h)?R(u,w,t,r):w.intersects(u,h)?R(w,u,t,r):(r(`${s.white("Unable to find intersection range")}: ${s.blue(u.raw)} and ${s.blue(w.raw)}, returning ${s.green(u.raw)}`),u):(r(`${s.white("Following range is not valid")}: ${s.red(w.raw)}, returning ${s.green(u.raw)}`),u):(r(`${s.white("Following range is not valid")}: ${s.red(u.raw)}, returning ${s.green(w.raw)}`),w)}let l=p.shift(),m=g.shift(),k=l||m;if(!k)throw new Error("Not yet implemented :/");let d=[k],b=j(p),N=j(g),L=R(b,N,t,r);return d.push(...S(L.set)),j(d)},"restrictiveRange"),q=c(n=>{if(!n||n.raw==="*")return"*";let e=[];return S(n.set).forEach(r=>{let[i,a]=r;r.length===2&&i.operator===">="&&a.operator==="<"&&i.semver.major+1===a.semver.major?e.push(`^${i.semver.version}`):r.length===1&&i.operator===">="?e.push(i.value):e.push(`${i.value} ${(a==null?void 0:a.value)||""}`.trim())}),e.join(" || ")},"humanizeRange"),Q=c((n,e)=>{var t;if(typeof n=="object"&&e in n)return n[e];if(z(n)&&n.some(r=>r.includes(e)))return(t=n.find(r=>r.includes(e)))==null?void 0:t.replace(e,"")},"getConstraintFromEngines"),x=c(({packages:n,constraintKey:e,debug:t})=>{let r=new o.Range("*"),i=[],a=t.extend(e);for(let[p,g]of Object.entries(n)){let{engines:l}=g;if(!l){a(`${s.white("Package")} ${s.gray(p)} ${s.white("has no engines")}`);continue}let m=Q(l,e);if(!m){a(`${s.white("Package")} ${s.gray(p)} ${s.white("has no constraints for current engine")}`);continue}let k=o.validRange(m);if(!k){a(`${s.red(m)} ${s.white("is not a valid semver range")}`);continue}if(i.indexOf(k)!==-1){a(`${s.white("Ignored range:")} ${s.gray(k)}`);continue}let d=new o.Range(k,h);if(!r){r=d,a(`${s.white("New most restrictive range:")} ${s.green(r.raw)}`);continue}let b=R(r,d,i,a);r.raw!==b.raw&&(r=b,a(`${s.white("New most restrictive range:")} ${s.green(r.raw)}`))}return a(r?`${s.white("Final computed engine range constraint:")} ${s.blue(r.raw)}`:`${s.white("No computed engine range constraint")}`),r},"computeEnginesConstraint"),X=c(n=>new A({style:{head:[],border:[],compact:!1,"padding-left":1,"padding-right":1},colWidths:n,colAligns:["left","left","left","left"],chars:{top:"","top-mid":"","top-left":"","top-right":"",bottom:"","bottom-mid":"","bottom-left":"","bottom-right":"",left:"","left-mid":"",mid:"","mid-mid":"",right:"","right-mid":"",middle:""}}),"createOutputTable"),Y=c(n=>{let e=["nce"];return n.engines&&e.push(...n.engines.map(t=>["-e",t]).flat()),n.quiet&&e.push("-q"),n.debug&&e.push("-d"),n.verbose&&e.push("-v"),e.push("-u"),e.join(" ")},"generateUpdateCommandFromContext"),Z=c(n=>{let e=JSON.parse(n.packageLockString),t=JSON.parse(n.packageJsonString),r=n.engines,i=[],a=c(l=>E.indexOf(l)!==-1,"filterEngineConstraintKey"),p=[...E];r&&r.length>0&&(p=r.filter(a));let g;e.lockfileVersion===1?g=e.dependencies:e.lockfileVersion===2?g=e.packages?e.packages:e.dependencies:e.lockfileVersion===3&&(g=e.packages);for(let l of p){let m=x({packages:{"":{engines:t.engines||{}}},constraintKey:l,debug:$}),k=x({packages:y({},{"":{engines:t.engines||{}}},g),constraintKey:l,debug:$}),d=q(k),b=q(m);d!==b&&(i.push({engine:l,range:b,rangeToSet:d}),t.engines=y({},t.engines,{[l]:d}),(e.lockfileVersion===2||e.lockfileVersion===3)&&e.packages&&(e.packages[""].engines=y({},e.packages[""].engines,{[l]:d})))}return{packageJson:t,packageLock:e,enginesRangeToSet:i}},"checkEnginesFromString"),ee=c(n=>{let e=V.compile(G),t=e(JSON.parse(n.packageLockString));if(!t)throw new Error(`Invalid package-lock.json: ${V.errorsText(e.errors)}`);return t},"validatePackageLock"),ne=c(n=>{let e=V.compile(O),t=e(JSON.parse(n.packageJsonString));if(!t)throw new Error(`Invalid package.json: ${V.errorsText(e.errors)}`);return t},"validatePackageJson"),te=c(({options:n,parent:e})=>[{title:"Reading package-lock.json...",task:async t=>{t.packageLockString=await f.readFile(n.packageLockPath,"utf8")}},{title:"Reading package.json...",task:async t=>{t.packageJsonString=await f.readFile(n.packageJsonPath,"utf8")}},{title:"Validating package-lock.json...",task:t=>{ee(t)}},{title:"Validating package.json...",task:t=>{ne(t)}},{title:"Compute engines range constraints...",task:t=>{Object.assign(t,Z(y({},t,{engines:n.engines})))}},{title:"Output computed engines range constraints...",task:t=>{let r=t.enginesRangeToSet,i="\u2192",a=[2,2,2,2],p=[];for(let{engine:g,range:l,rangeToSet:m}of r)$.extend(g)(`${s.white("Simplified computed engine range constraint:")} ${s.blue(m)}`),a=[Math.max(a[0],g.length+2),Math.max(a[1],l.length+2),i.length+2,Math.max(a[3],m.length+2)],p.push([g,l,i,m]);if(r.length===0)e.title=`All computed engines range constraints are up-to-date ${s.green(":)")}`;else{let g=X(a);g.push(...p);let l=`Computed engines range constraints:
2
2
 
3
- ${g.toString()}`;n.update||(p+=`
3
+ ${g.toString()}`;n.update||(l+=`
4
4
 
5
- Run ${s.cyan(Z(n))} to upgrade package.json.`),e.title=p}}},{title:"Enabling engine-strict using .npmrc...",skip:()=>n.enableEngineStrict?!n.enableEngineStrict:"Enabling engine-strict is disabled by default.",task:async()=>{let t=".npmrc";try{await k.access(t,j.F_OK|j.R_OK),(await k.readFile(t,"utf8")).includes("engine-strict=true")?h(".npmrc file already contains engine-strict=true"):(await k.appendFile(t,`engine-strict=true
6
- `),h(".npmrc file has been updated to set engine-strict=true"))}catch{await k.writeFile(t,`engine-strict=true
7
- `),h(".npmrc file has been created and set engine-strict=true")}}},{title:"Updating package.json...",skip:()=>n.update?!n.update:"Update is disabled by default.",task:t=>(h(`${s.white("Write JSON to")} ${s.blue("package.json")}`),k.writeFile(n.packageJsonPath,JSON.stringify(_(t.packageJson),null,2)))}],"checkEnginesTasks"),se=c(({options:n,context:e})=>new M([{title:"Checking npm package engines range constraints in package-lock.json...",task:(t,r)=>r.newListr(i=>re({parent:i,options:n}))}],e),"checkEnginesCommand");export{J as applyMinVersionToRangeSet,he as checkEnginesFromCLI,ee as checkEnginesFromString,q as humanizeRange,w as rangeOptions,E as restrictiveRange,b as setToRange,v as sortRangeSet,te as validatePackageJson,ne as validatePackageLock};
5
+ Run ${s.cyan(Y(n))} to upgrade package.json.`),e.title=l}}},{title:"Updating package.json...",skip:()=>n.update?!n.update:"Update is disabled by default.",task:t=>($(`${s.white("Write JSON to")} ${s.blue("package.json")}`),Promise.all([f.writeFile(n.packageJsonPath,JSON.stringify(I(t.packageJson),null,2)+`
6
+ `),f.writeFile(n.packageLockPath,JSON.stringify(t.packageLock,null,2)+`
7
+ `)]))},{title:"Enabling engine-strict using .npmrc...",skip:()=>n.enableEngineStrict?!n.enableEngineStrict:"Enabling engine-strict is disabled by default.",task:async()=>{let t=".npmrc";try{await f.access(t,f.constants.F_OK|f.constants.R_OK),(await f.readFile(t,"utf8")).includes("engine-strict=true")?$(".npmrc file already contains engine-strict=true"):(await f.appendFile(t,`engine-strict=true
8
+ `),$(".npmrc file has been updated to set engine-strict=true"))}catch{await f.writeFile(t,`engine-strict=true
9
+ `),$(".npmrc file has been created and set engine-strict=true")}}}],"checkEnginesTasks"),re=c(({options:n,context:e})=>new M([{title:"Checking npm package engines range constraints in package-lock.json...",task:(t,r)=>r.newListr(i=>te({parent:i,options:n}))}],e),"checkEnginesCommand");export{C as applyMinVersionToRangeSet,ke as checkEnginesFromCLI,Z as checkEnginesFromString,q as humanizeRange,h as rangeOptions,R as restrictiveRange,j as setToRange,S as sortRangeSet,ne as validatePackageJson,ee as validatePackageLock};
@@ -1 +1 @@
1
- "use strict";var d=Object.create;var n=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var b=(e,a)=>{for(var i in a)n(e,i,{get:a[i],enumerable:!0})},o=(e,a,i,l)=>{if(a&&typeof a=="object"||typeof a=="function")for(let t of p(a))!f.call(e,t)&&t!==i&&n(e,t,{get:()=>a[t],enumerable:!(l=u(a,t))||l.enumerable});return e};var m=(e,a,i)=>(i=e!=null?d(g(e)):{},o(a||!e||!e.__esModule?n(i,"default",{value:e,enumerable:!0}):i,e)),h=e=>o(n({},"__esModule",{value:!0}),e);var k={};b(k,{cli:()=>v});module.exports=h(k);var s=m(require("yargs"),1),c=require("yargs/helpers"),r=(0,s.default)((0,c.hideBin)(process.argv)),v=r.scriptName("nce").usage("Usage: $0 [options]").example("$0","Check package-lock.json file in current working directory.").strict().options({quiet:{boolean:!0,alias:"q",default:!1,description:"Enable quiet mode."},debug:{boolean:!0,alias:"d",default:!1,description:"Enable debug mode. Can be used with environment variable DEBUG=nce."},verbose:{boolean:!0,alias:"v",default:!1,description:"A little more detailed than the default output."},engines:{array:!0,alias:"e",description:"Select engines to check. Default will check all engines defined."},update:{boolean:!0,alias:"u",default:!1,description:"Update engines in package.json file."},enableEngineStrict:{boolean:!0,default:!1,description:"Enable engine strict."}}).help("help").version().wrap(r.terminalWidth()).epilog("\xA9 2022 Samuel MARLHENS").argv;0&&(module.exports={cli});
1
+ "use strict";var d=Object.create;var n=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var b=(e,a)=>{for(var i in a)n(e,i,{get:a[i],enumerable:!0})},o=(e,a,i,l)=>{if(a&&typeof a=="object"||typeof a=="function")for(let t of p(a))!f.call(e,t)&&t!==i&&n(e,t,{get:()=>a[t],enumerable:!(l=u(a,t))||l.enumerable});return e};var m=(e,a,i)=>(i=e!=null?d(g(e)):{},o(a||!e||!e.__esModule?n(i,"default",{value:e,enumerable:!0}):i,e)),h=e=>o(n({},"__esModule",{value:!0}),e);var v={};b(v,{cli:()=>k});module.exports=h(v);var s=m(require("yargs"),1),c=require("yargs/helpers"),r=(0,s.default)((0,c.hideBin)(process.argv)),k=r.scriptName("nce").usage("Usage: $0 [options]").example("$0","Check package-lock.json file in current working directory.").strict().options({quiet:{boolean:!0,alias:"q",default:!1,description:"Enable quiet mode."},debug:{boolean:!0,alias:"d",default:!1,description:"Enable debug mode. Can be used with environment variable DEBUG=nce."},verbose:{boolean:!0,alias:"v",default:!1,description:"A little more detailed than the default output."},engines:{array:!0,alias:"e",description:"Select engines to check. Default will check all engines defined."},update:{boolean:!0,alias:"u",default:!1,description:"Update engines in package.json and package-lock.json."},enableEngineStrict:{boolean:!0,default:!1,description:"Enable engine strict."}}).help("help").version().wrap(r.terminalWidth()).epilog("\xA9 2023 Samuel MARLHENS").argv;0&&(module.exports={cli});
package/dist/lib/yargs.js CHANGED
@@ -1 +1 @@
1
- import a from"yargs";import{hideBin as i}from"yargs/helpers";var e=a(i(process.argv)),r=e.scriptName("nce").usage("Usage: $0 [options]").example("$0","Check package-lock.json file in current working directory.").strict().options({quiet:{boolean:!0,alias:"q",default:!1,description:"Enable quiet mode."},debug:{boolean:!0,alias:"d",default:!1,description:"Enable debug mode. Can be used with environment variable DEBUG=nce."},verbose:{boolean:!0,alias:"v",default:!1,description:"A little more detailed than the default output."},engines:{array:!0,alias:"e",description:"Select engines to check. Default will check all engines defined."},update:{boolean:!0,alias:"u",default:!1,description:"Update engines in package.json file."},enableEngineStrict:{boolean:!0,default:!1,description:"Enable engine strict."}}).help("help").version().wrap(e.terminalWidth()).epilog("\xA9 2022 Samuel MARLHENS").argv;export{r as cli};
1
+ import a from"yargs";import{hideBin as i}from"yargs/helpers";var e=a(i(process.argv)),r=e.scriptName("nce").usage("Usage: $0 [options]").example("$0","Check package-lock.json file in current working directory.").strict().options({quiet:{boolean:!0,alias:"q",default:!1,description:"Enable quiet mode."},debug:{boolean:!0,alias:"d",default:!1,description:"Enable debug mode. Can be used with environment variable DEBUG=nce."},verbose:{boolean:!0,alias:"v",default:!1,description:"A little more detailed than the default output."},engines:{array:!0,alias:"e",description:"Select engines to check. Default will check all engines defined."},update:{boolean:!0,alias:"u",default:!1,description:"Update engines in package.json and package-lock.json."},enableEngineStrict:{boolean:!0,default:!1,description:"Enable engine strict."}}).help("help").version().wrap(e.terminalWidth()).epilog("\xA9 2023 Samuel MARLHENS").argv;export{r as cli};
package/dist/nce.d.ts CHANGED
@@ -22,6 +22,25 @@ type LockPackageEngines = LockPackageEnginesObject | LockPackageEnginesArray;
22
22
  type OptionalEngines = {
23
23
  engines?: LockPackageEngines;
24
24
  };
25
+ type PackageDependencies = {
26
+ [dependencyName: string]: OptionalEngines;
27
+ };
28
+ type PackageLockDependencies = {
29
+ dependencies: PackageDependencies;
30
+ };
31
+ type PackageLockPackages = {
32
+ packages: PackageDependencies;
33
+ };
34
+ type PackageLockVersion1 = {
35
+ lockfileVersion: 1;
36
+ } & PackageLockDependencies;
37
+ type PackageLockVersion2 = {
38
+ lockfileVersion: 2;
39
+ } & Partial<PackageLockPackages> & PackageLockDependencies;
40
+ type PackageLockVersion3 = {
41
+ lockfileVersion: 3;
42
+ } & PackageLockPackages;
43
+ type PackageLock = PackageLockVersion1 | PackageLockVersion2 | PackageLockVersion3;
25
44
  type EngineRangeToSet = {
26
45
  engine: EngineConstraintKey;
27
46
  range: string;
@@ -34,6 +53,7 @@ type CheckEnginesInput = {
34
53
  };
35
54
  type CheckEnginesOutput = {
36
55
  packageJson: OptionalEngines;
56
+ packageLock: PackageLock;
37
57
  enginesRangeToSet: EngineRangeToSet[];
38
58
  };
39
59
  type CheckEnginesContext = CheckEnginesInput & Partial<CheckEnginesOutput>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smarlhens/npm-check-engines",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "description": "Node.JS engines constraint checker written in TypeScript.",
5
5
  "keywords": [
6
6
  "node",
@@ -69,31 +69,31 @@
69
69
  "semver": "7.3.8",
70
70
  "sort-package-json": "2.4.1",
71
71
  "update-notifier": "6.0.2",
72
- "yargs": "17.7.0"
72
+ "yargs": "17.7.1"
73
73
  },
74
74
  "devDependencies": {
75
- "@commitlint/cli": "17.4.3",
76
- "@commitlint/config-conventional": "17.4.3",
77
- "@swc/core": "1.3.35",
78
- "@trivago/prettier-plugin-sort-imports": "4.0.0",
75
+ "@commitlint/cli": "17.4.4",
76
+ "@commitlint/config-conventional": "17.4.4",
77
+ "@swc/core": "1.3.37",
78
+ "@trivago/prettier-plugin-sort-imports": "4.1.1",
79
79
  "@types/cli-table": "0.3.1",
80
80
  "@types/debug": "4.1.7",
81
81
  "@types/lodash-es": "4.17.6",
82
- "@types/node": "18.13.0",
82
+ "@types/node": "18.14.6",
83
83
  "@types/semver": "7.3.13",
84
84
  "@types/update-notifier": "6.0.2",
85
85
  "@types/yargs": "17.0.22",
86
- "@vitest/coverage-c8": "0.28.5",
86
+ "@vitest/coverage-c8": "0.29.2",
87
87
  "execa": "7.0.0",
88
88
  "husky": "8.0.3",
89
89
  "lint-staged": "13.1.2",
90
90
  "prettier": "2.8.4",
91
- "rimraf": "4.1.2",
91
+ "rimraf": "4.3.0",
92
92
  "ts-node": "10.9.1",
93
93
  "tslib": "2.5.0",
94
94
  "tsup": "6.6.3",
95
95
  "typescript": "4.9.5",
96
- "vitest": "0.28.5"
96
+ "vitest": "0.29.2"
97
97
  },
98
98
  "engines": {
99
99
  "node": "^16.14.0 || ^18.0.0",