validate-package-exports 0.6.0 → 0.6.1
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/dist/cli.mjs +2 -2
- package/package.json +13 -13
package/dist/cli.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/*!
|
|
3
3
|
* @file validate-package-exports
|
|
4
|
-
* @version 0.6.
|
|
4
|
+
* @version 0.6.1
|
|
5
5
|
* @license MIT
|
|
6
6
|
* @copyright Eric King 2024
|
|
7
7
|
* @see {@link https://github.com/webdeveric/validate-package-exports/#readme}
|
|
8
8
|
*/
|
|
9
|
-
import{setMaxListeners as ue}from"node:events";import{Readable as le}from"node:stream";var a=class{name;code;message;entryPoint;error;constructor(e){this.name=e.name,this.code=e.code,this.message=e.message,this.entryPoint=e.entryPoint,this.error=e.error}toString(){let e=this.code===0?"\u2705":this.code===1?"\u274C":"\u{1F610}";return this.code===1?`${e} ${this.name}: ${this.message} (${JSON.stringify(this.entryPoint.itemPath)}) ${this.error??""}`.trim():`${e} ${this.name}: ${this.message}`}};import{EventEmitter as ne}from"node:events";import{dirname as ie}from"node:path";import{Readable as x}from"node:stream";import{relative as F}from"node:path";import{stat as dt}from"node:fs/promises";async function $(t){try{return(await dt(t)).isFile()}catch{return!1}}async function A(t){try{if(await $(t.resolvedPath)===!1)throw new Error(`${t.resolvedPath} is not a file`);return new a({name:"file-exists",code:0,message:`${F(process.cwd(),t.resolvedPath)} exists`,entryPoint:t})}catch(e){return new a({name:"file-exists",code:1,entryPoint:t,message:`${F(process.cwd(),t.resolvedPath)} does not exist`,error:e instanceof Error?e:new Error(String(e))})}}import{relative as N}from"node:path";import{exec as Pt}from"node:child_process";import{promisify as gt}from"node:util";var l=gt(Pt);async function B(t,e){try{return await l(`node --check ${t.resolvedPath}`,e),new a({code:0,entryPoint:t,message:`${N(process.cwd(),t.resolvedPath)} has valid syntax`,name:"check-syntax"})}catch(r){return new a({code:1,entryPoint:t,error:r instanceof Error?r:new Error(String(r)),message:`Could not validate syntax for ${N(process.cwd(),t.resolvedPath)}`,name:"check-syntax"})}}import{relative as vt,dirname as Rt,basename as jt}from"node:path";function M(t,e){return e==="."?t:`${t}/${e.replace(/^\.\//,"")}`}function J(t,e="commonjs",r){return r==="require"||t.endsWith(".cjs")?"commonjs":r==="import"||t.endsWith(".mjs")?"module":e}import{createRequire as Et}from"node:module";import{basename as ht,dirname as xt,join as kt,resolve as wt}from"node:path";function I(t){let e=new Map;return(...o)=>{let i=e.get(o[0]);if(i)return i;let n=t(...o);return e.set(o[0],n),n}}var bt=I(Et);function q(t,e){let r=wt(e.directory,t);if(e.type==="commonjs")try{let i=bt(e.directory).resolve(r);return kt(xt(r),ht(i))}catch{}return r}function p({moduleName:t,modulePath:e,packageContext:r,subpath:o,itemPath:i,condition:n}){let s=q(e,r);return{moduleName:t??(o?M(r.name,o):void 0),packagePath:r.path,type:J(e,r.type,n),fileName:jt(s),relativePath:vt(r.directory,s),directory:Rt(s),resolvedPath:s,subpath:o,condition:n,itemPath:i}}function D(t,e){return typeof t=="string"?{[e]:t}:t}function*L(t,e){if(t.bin)for(let[r,o]of Object.entries(D(t.bin,t.name)))yield p({condition:void 0,itemPath:typeof t.bin=="string"?["bin"]:["bin",r],modulePath:o,packageContext:e,subpath:void 0})}import{opendir as Ct}from"node:fs/promises";import{resolve as St}from"node:path";async function*T(t,e){if(typeof t.directories?.bin=="string"){let r=await Ct(t.directories.bin);for await(let o of r)o.isFile()&&(yield p({condition:void 0,itemPath:["directories","bin"],modulePath:St(t.directories.bin,o.name),packageContext:e,subpath:void 0}))}}import{isObject as d}from"@webdeveric/utils/predicate/isObject";import{isOptionalString as y}from"@webdeveric/utils/predicate/isOptionalString";import{isString as w}from"@webdeveric/utils/predicate/isString";import{isStringArray as Ot}from"@webdeveric/utils/predicate/isStringArray";import{isStringRecord as $t}from"@webdeveric/utils/predicate/isStringRecord";import{createStringMatchingPredicate as b}from"@webdeveric/utils/predicate-factory/createStringMatchingPredicate";import{everyItem as G}from"@webdeveric/utils/predicate-factory/everyItem";import{maybeUndefined as u}from"@webdeveric/utils/predicate-factory/maybeUndefined";function Ft(t){return t==="commonjs"||t==="module"}var At=u(Ft),_=b(/\.\d+(\.gz)?$/),Nt=G(_),Bt=t=>_(t)||Nt(t),Mt=u(Bt);function Jt(t){return d(t)&&y(t.bin)&&y(t.man)}var It=u(Jt);function qt(t){return w(t)||$t(t)}var Dt=u(qt);function V(t){return typeof t=="string"&&t.startsWith("./")}var Lt=/^(?<before>\.\/[^*]*)\*(?<after>[^*]*)$/,rr=b(Lt);function v(t){return t===null||V(t)}var Tt=b(/^(?![\\.0-9])./);function P(t){return d(t)?Object.entries(t).every(([r,o])=>Tt(r)&&C(o)):!1}function R(t){return d(t)?Object.entries(t).every(([r,o])=>(r==="."||V(r))&&C(o)):!1}function z(t){return v(t)||P(t)}var j=G(z);function C(t){return z(t)||j(t)}function Gt(t){return C(t)||R(t)}var _t=u(Gt),S=t=>d(t)&&Object.entries(t).every(e=>typeof e[0]=="string"&&(typeof e[1]=="string"||typeof e[1]=="boolean"));function Vt(t){return w(t)||S(t)}var zt=u(Vt),Ut=u(Ot);function U(t){return d(t)&&w(t.name)&&y(t.version)&&y(t.main)&&y(t.module)&&zt(t.browser)&&y(t.types)&&Mt(t.man)&&It(t.directories)&&At(t.type)&&_t(t.exports)&&Dt(t.bin)&&Ut(t.files)}function*W(t,e){if(t.browser){if(S(t.browser)){let r=Object.entries(t.browser).filter(o=>typeof o[0]=="string"&&typeof o[1]=="string");for(let[o,i]of r)yield p({condition:void 0,itemPath:["browser",o],modulePath:i,packageContext:e,subpath:void 0});return}yield p({condition:void 0,itemPath:["browser"],modulePath:t.browser,packageContext:e,subpath:void 0})}}var h=class{processExportsEntryPath(e,r,o){return e===null?[]:[p({modulePath:e,subpath:".",...r,packageContext:o})]}processExportsEntry(e,r,o){return P(e)?this.processConditionalExports(e,r,o):this.processExportsEntryPath(e,r,o)}processExportsEntryArray(e,r,o){return e.map((i,n)=>this.processExportsEntry(i,{...r,itemPath:[...r.itemPath,n]},o)).flat()}processSubpathExports(e,r,o){return Object.entries(e).map(([i,n])=>this.process(n,{...r,subpath:i,itemPath:[...r.itemPath,i]},o)).flat()}processConditionalExports(e,r,o){let i=(n,s,m)=>{if(P(s))return n;if(m.at(-1)==="default"){let f=m.at(-2);if(typeof f=="string")return f}return n};return Object.entries(e).map(([n,s])=>{let m=[...r.itemPath,n];return this.process(s,{...r,condition:i(n,s,m),itemPath:m},o)}).flat()}process(e,r,o){return v(e)?this.processExportsEntryPath(e,r,o):j(e)?this.processExportsEntryArray(e,r,o):R(e)?this.processSubpathExports(e,r,o):P(e)?this.processConditionalExports(e,r,o):[]}};import{opendir as Wt}from"node:fs/promises";import{resolve as Ht}from"node:path";function Kt(t,e){return["moduleName","relativePath","fileName","resolvedPath"].reduce((o,i)=>{let n=o[i];return n&&(o[i]=n.replace("*",e)),o},structuredClone(t))}async function*H(t,e,r){let o=await Wt(t);for await(let i of o){let n=Ht(t,i.name);i.isDirectory()?yield*H(n,e,r):i.isFile()&&(typeof r.suffix>"u"||i.name.endsWith(r.suffix))&&(yield Kt(e,r.findStar(n)))}}async function*K(t){if(!t.resolvedPath.includes("*")){yield t;return}let[e,r]=t.resolvedPath.split("*"),o={prefix:e,suffix:r,prefixPattern:e?new RegExp(`^${e}`,"i"):void 0,suffixPattern:r?new RegExp(`${r}$`,"i"):void 0,findStar(i){let n=i;return this.prefixPattern&&(n=n.replace(this.prefixPattern,"")),this.suffixPattern&&(n=n.replace(this.suffixPattern,"")),n}};yield*H(t.directory,t,o)}async function*Q(t,e){if(t.exports){let r=new h().process(t.exports,{itemPath:["exports"]},e);for(let o of r)yield*K(o)}}function*X(t,e){t.main&&(yield p({moduleName:e.name,condition:void 0,itemPath:["main"],modulePath:t.main,packageContext:e,subpath:void 0}))}function*Y(t,e){t.module&&(yield p({moduleName:e.name,condition:void 0,itemPath:["module"],modulePath:t.module,packageContext:e,subpath:void 0}))}function*Z(t,e){let r="types"in t?"types":"typings"in t?"typings":void 0;if(r){let o=t[r];o&&(yield p({condition:"types",itemPath:[r],modulePath:o,packageContext:e,subpath:void 0}))}}async function*tt(t,e){yield*L(t,e),yield*T(t,e),yield*W(t,e),yield*X(t,e),yield*Y(t,e),yield*Z(t,e),yield*Q(t,e)}import Qt from"@npmcli/arborist";import Xt from"npm-packlist";import{sep as et}from"node:path";function rt(t){return et==="/"?t:t.replaceAll("/",et)}async function ot(t){let r=await new Qt({path:t}).loadActual();return(await Xt(r)).map(i=>rt(i))}import{AssertionError as Yt}from"node:assert";function nt(t){if(!U(t))throw new Yt({message:"input is not PackageJson",actual:t})}import{readFile as Zt}from"node:fs/promises";async function it(t){let e=await Zt(t,"utf-8");return JSON.parse(e)}async function st(t){let e=await it(t);return nt(e),e}import te from"node:assert";function at(){let[t]=process.versions.node.split(".");return te(t),Number.parseInt(t)}var ee=at();async function ct(t,e){let r=/\.json$/i.test(t)?`node --input-type=module --eval="import '${t}' ${ee<20?"assert":"with"} { type: 'json' };" --no-warnings`:`node --input-type=module --eval="import '${t}';"`;await l(r,e)}async function pt(t,e){try{return typeof t.moduleName=="string"?(await ct(t.moduleName,e),new a({code:0,entryPoint:t,message:`"${t.moduleName}" works with import`,name:"import"})):new a({code:2,entryPoint:t,message:`Import skipped: ${t.itemPath.join(".")}`,name:"import"})}catch(r){return new a({code:1,entryPoint:t,error:r instanceof Error?r:new Error(String(r)),message:`${t.moduleName??t.itemPath.join(".")} cannot be imported`,name:"import"})}}async function mt(t,e){let r=`node --input-type=commonjs --eval="require('${t}');"`;await l(r,e)}async function ft(t,e){try{return typeof t.moduleName=="string"?(await mt(t.moduleName,e),new a({code:0,entryPoint:t,message:`"${t.moduleName}" works with require`,name:"require"})):new a({code:2,entryPoint:t,message:`Require skipped: ${t.itemPath.join(".")}`,name:"require"})}catch(r){return new a({code:1,entryPoint:t,error:r instanceof Error?r:new Error(String(r)),message:`${t.moduleName??t.itemPath.join(".")} cannot be required`,name:"require"})}}function re(t){return t.type==="module"&&t.itemPath.length===1&&t.itemPath[0]==="main"?!1:typeof t.condition>"u"||t.condition==="require"}function oe(t){return typeof t.condition>"u"||t.condition==="import"}async function ut(t,e){let r=[];try{typeof t.moduleName=="string"&&(re(t)&&r.push(await ft(t,e)),oe(t)&&r.push(await pt(t,e)))}catch(o){if(o instanceof Error)throw new Error(`Unable to verify "${t.moduleName}"`,{cause:o})}return r}var k=class extends ne{options;packageDirectory;#e;#t;constructor(e){super(),this.options=e,this.packageDirectory=ie(this.options.package),this.#e=0,this.#t=e.controller}processResult(e){this.emit("result",e),e.code===1&&(this.#e=1,this.options.bail&&this.#t.abort())}processResults(e){[e].flat().forEach(r=>this.processResult(r))}async checkFilesExist(e){return await x.from(e).map(async r=>{let o=await A(r);return this.processResults(o),o},{signal:this.#t.signal,concurrency:this.options.concurrency}).toArray({signal:this.#t.signal})}async checkSyntax(e){let r=e.filter(o=>/\.[cm]?js$/i.test(o.resolvedPath));return await x.from(r).map(async o=>{let i=await B(o,{signal:this.#t.signal});return this.processResults(i),i},{signal:this.#t.signal,concurrency:this.options.concurrency}).toArray({signal:this.#t.signal})}async verifyIncludes(e){return(await x.from(e).map(async r=>{let o=await ut(r,{cwd:this.packageDirectory,signal:this.#t.signal});return this.processResults(o),o},{signal:this.#t.signal,concurrency:this.options.concurrency}).toArray({signal:this.#t.signal})).flat()}async checkPacklist(e,r){let o=new Set(await ot(r.directory)),i=e.map(n=>{let s=o.has(n.relativePath);return new a({name:"packlist",code:s?0:1,message:s?`${n.relativePath} will be packed`:`${n.relativePath} will not be packed`,error:s?void 0:new Error("EntryPoint relativePath not found in packlist files"),entryPoint:n})});return this.processResults(i),i}async run(){let e=await st(this.options.package),r={name:e.name,type:e.type??"commonjs",path:this.options.package,directory:this.packageDirectory},o=await x.from(tt(e,r),{objectMode:!0}).toArray({signal:this.#t.signal}),i=new Set,n=m=>{m.forEach(f=>{f.code===1&&i.add(f.entryPoint)})},s=m=>m.filter(f=>!i.has(f));return n(await this.checkFilesExist(o)),this.options.check&&n(await this.checkSyntax(s(o))),this.options.verify&&n(await this.verifyIncludes(s(o))),n(await this.checkPacklist(s(o),r)),this.#e}};import{parseArgs as ae}from"node:util";import{availableParallelism as se}from"node:os";function lt(t){let e=se(),r=Number.parseInt(`${t}`);return Number.isInteger(r)?Math.max(1,Math.min(r,e)):e}function yt(t){let e={args:t,allowPositionals:!0,strict:!0,tokens:!1,options:{concurrency:{type:"string",short:"c"},bail:{type:"boolean",short:"b",default:process.env.CI==="true"},check:{type:"boolean",default:!1,short:"s"},verify:{type:"boolean",default:!1,short:"v"},json:{type:"boolean",default:!1,short:"j"},info:{type:"boolean",default:process.env.RUNNER_DEBUG==="1",short:"i"},"no-bail":{type:"boolean",default:!1},"no-info":{type:"boolean",default:!1}}},{values:r,positionals:o}=ae(e),i=r["no-bail"]??e.options["no-bail"].default,n=r["no-info"]??e.options["no-info"].default;return{packages:o.length?o:["./package.json"],concurrency:lt(r.concurrency),bail:i?!1:r.bail??e.options.bail.default,check:r.check??e.options.check.default,verify:r.verify??e.options.verify.default,json:r.json??e.options.verify.default,info:n?!1:r.info??e.options.info.default}}import{stat as ce}from"node:fs/promises";import{basename as pe,join as me,resolve as fe}from"node:path";async function O(t){let e=await ce(t);if(e.isDirectory())return await O(me(t,"package.json"));if(e.isFile()&&pe(t)==="package.json")return fe(t);throw new Error(`Unable to resolve package.json from ${t}`)}try{let{json:t,info:e,packages:r,...o}=yt(),i=await le.from(r).map(c=>O(c),{concurrency:o.concurrency}).toArray(),n=[],s=c=>{n.push(c),!t&&(e||c.code===1)&&console.log(c.toString())},m=new AbortController;ue(100,m.signal);let f=i.map(c=>{let g=new k({...o,package:c,controller:m});return g.on("result",s),g});try{for(let c of f)await c.run()}catch(c){if(c instanceof Error&&c.name!=="AbortError")throw c}process.exitCode=n.reduce((c,g)=>g.code===1?1:c,0),t&&process.stdout.write(JSON.stringify(n.filter(c=>e||c.code===1),null,2))}catch(t){console.group("validate-package-exports"),console.dir(t,{depth:null}),console.groupEnd(),process.exitCode??=1}
|
|
9
|
+
import{setMaxListeners as ue}from"node:events";import{Readable as le}from"node:stream";var a=class{name;code;message;entryPoint;error;constructor(e){this.name=e.name,this.code=e.code,this.message=e.message,this.entryPoint=e.entryPoint,this.error=e.error}toString(){let e=this.code===0?"\u2705":this.code===1?"\u274C":"\u{1F610}";return this.code===1?`${e} ${this.name}: ${this.message} (${JSON.stringify(this.entryPoint.itemPath)}) ${this.error??""}`.trim():`${e} ${this.name}: ${this.message}`}};import{EventEmitter as ne}from"node:events";import{dirname as ie}from"node:path";import{Readable as x}from"node:stream";import{relative as F}from"node:path";import{stat as dt}from"node:fs/promises";async function $(t){try{return(await dt(t)).isFile()}catch{return!1}}async function A(t){try{if(await $(t.resolvedPath)===!1)throw new Error(`${t.resolvedPath} is not a file`);return new a({name:"file-exists",code:0,message:`${F(process.cwd(),t.resolvedPath)} exists`,entryPoint:t})}catch(e){return new a({name:"file-exists",code:1,entryPoint:t,message:`${F(process.cwd(),t.resolvedPath)} does not exist`,error:e instanceof Error?e:new Error(String(e))})}}import{relative as N}from"node:path";import{exec as Pt}from"node:child_process";import{promisify as gt}from"node:util";var l=gt(Pt);async function B(t,e){try{return await l(`node --check ${t.resolvedPath}`,e),new a({code:0,entryPoint:t,message:`${N(process.cwd(),t.resolvedPath)} has valid syntax`,name:"check-syntax"})}catch(r){return new a({code:1,entryPoint:t,error:r instanceof Error?r:new Error(String(r)),message:`Could not validate syntax for ${N(process.cwd(),t.resolvedPath)}`,name:"check-syntax"})}}import{relative as vt,dirname as Rt,basename as jt}from"node:path";function M(t,e){return e==="."?t:`${t}/${e.replace(/^\.\//,"")}`}function J(t,e="commonjs",r){return r==="require"||t.endsWith(".cjs")?"commonjs":r==="import"||t.endsWith(".mjs")?"module":e}import{createRequire as Et}from"node:module";import{basename as ht,dirname as xt,join as kt,resolve as wt}from"node:path";function I(t){let e=new Map;return(...o)=>{let i=e.get(o[0]);if(i)return i;let n=t(...o);return e.set(o[0],n),n}}var bt=I(Et);function q(t,e){let r=wt(e.directory,t);if(e.type==="commonjs")try{let i=bt(e.directory).resolve(r);return kt(xt(r),ht(i))}catch{}return r}function p({moduleName:t,modulePath:e,packageContext:r,subpath:o,itemPath:i,condition:n}){let s=q(e,r);return{moduleName:t??(o?M(r.name,o):void 0),packagePath:r.path,type:J(e,r.type,n),fileName:jt(s),relativePath:vt(r.directory,s),directory:Rt(s),resolvedPath:s,subpath:o,condition:n,itemPath:i}}function D(t,e){return typeof t=="string"?{[e]:t}:t}function*L(t,e){if(t.bin)for(let[r,o]of Object.entries(D(t.bin,t.name)))yield p({condition:void 0,itemPath:typeof t.bin=="string"?["bin"]:["bin",r],modulePath:o,packageContext:e,subpath:void 0})}import{opendir as Ct}from"node:fs/promises";import{resolve as St}from"node:path";async function*T(t,e){if(typeof t.directories?.bin=="string"){let r=await Ct(t.directories.bin);for await(let o of r)o.isFile()&&(yield p({condition:void 0,itemPath:["directories","bin"],modulePath:St(t.directories.bin,o.name),packageContext:e,subpath:void 0}))}}import{isObject as d}from"@webdeveric/utils/predicate/isObject";import{isOptionalString as y}from"@webdeveric/utils/predicate/isOptionalString";import{isString as w}from"@webdeveric/utils/predicate/isString";import{isStringArray as Ot}from"@webdeveric/utils/predicate/isStringArray";import{isStringRecord as $t}from"@webdeveric/utils/predicate/isStringRecord";import{createStringMatchingPredicate as b}from"@webdeveric/utils/predicate-factory/createStringMatchingPredicate";import{everyItem as G}from"@webdeveric/utils/predicate-factory/everyItem";import{maybeUndefined as u}from"@webdeveric/utils/predicate-factory/maybeUndefined";function Ft(t){return t==="commonjs"||t==="module"}var At=u(Ft),_=b(/\.\d+(\.gz)?$/),Nt=G(_),Bt=t=>_(t)||Nt(t),Mt=u(Bt);function Jt(t){return d(t)&&y(t.bin)&&y(t.man)}var It=u(Jt);function qt(t){return w(t)||$t(t)}var Dt=u(qt);function V(t){return typeof t=="string"&&t.startsWith("./")}var Lt=/^(?<before>\.\/[^*]*)\*(?<after>[^*]*)$/,rr=b(Lt);function v(t){return t===null||V(t)}var Tt=b(/^(?![\\.0-9])./);function P(t){return d(t)?Object.entries(t).every(([r,o])=>Tt(r)&&C(o)):!1}function R(t){return d(t)?Object.entries(t).every(([r,o])=>(r==="."||V(r))&&C(o)):!1}function z(t){return v(t)||P(t)}var j=G(z);function C(t){return z(t)||j(t)}function Gt(t){return C(t)||R(t)}var _t=u(Gt),S=t=>d(t)&&Object.entries(t).every(e=>typeof e[0]=="string"&&(typeof e[1]=="string"||typeof e[1]=="boolean"));function Vt(t){return w(t)||S(t)}var zt=u(Vt),Ut=u(Ot);function U(t){return d(t)&&w(t.name)&&y(t.version)&&y(t.main)&&y(t.module)&&zt(t.browser)&&y(t.types)&&Mt(t.man)&&It(t.directories)&&At(t.type)&&_t(t.exports)&&Dt(t.bin)&&Ut(t.files)}function*W(t,e){if(t.browser){if(S(t.browser)){let r=Object.entries(t.browser).filter(o=>typeof o[0]=="string"&&typeof o[1]=="string");for(let[o,i]of r)yield p({condition:void 0,itemPath:["browser",o],modulePath:i,packageContext:e,subpath:void 0});return}yield p({condition:void 0,itemPath:["browser"],modulePath:t.browser,packageContext:e,subpath:void 0})}}var h=class{processExportsEntryPath(e,r,o){return e===null?[]:[p({modulePath:e,subpath:".",...r,packageContext:o})]}processExportsEntry(e,r,o){return P(e)?this.processConditionalExports(e,r,o):this.processExportsEntryPath(e,r,o)}processExportsEntryArray(e,r,o){return e.map((i,n)=>this.processExportsEntry(i,{...r,itemPath:[...r.itemPath,n]},o)).flat()}processSubpathExports(e,r,o){return Object.entries(e).map(([i,n])=>this.process(n,{...r,subpath:i,itemPath:[...r.itemPath,i]},o)).flat()}processConditionalExports(e,r,o){let i=(n,s,m)=>{if(P(s))return n;if(m.at(-1)==="default"){let f=m.at(-2);if(typeof f=="string")return f}return n};return Object.entries(e).map(([n,s])=>{let m=[...r.itemPath,n];return this.process(s,{...r,condition:i(n,s,m),itemPath:m},o)}).flat()}process(e,r,o){return v(e)?this.processExportsEntryPath(e,r,o):j(e)?this.processExportsEntryArray(e,r,o):R(e)?this.processSubpathExports(e,r,o):P(e)?this.processConditionalExports(e,r,o):[]}};import{opendir as Wt}from"node:fs/promises";import{resolve as Ht}from"node:path";function Kt(t,e){return["moduleName","relativePath","fileName","resolvedPath"].reduce((o,i)=>{let n=o[i];return n&&(o[i]=n.replace("*",e)),o},structuredClone(t))}async function*H(t,e,r){let o=await Wt(t);for await(let i of o){let n=Ht(t,i.name);i.isDirectory()?yield*H(n,e,r):i.isFile()&&(typeof r.suffix>"u"||i.name.endsWith(r.suffix))&&(yield Kt(e,r.findStar(n)))}}async function*K(t){if(!t.resolvedPath.includes("*")){yield t;return}let[e,r]=t.resolvedPath.split("*"),o={prefix:e,suffix:r,prefixPattern:e?new RegExp(`^${e}`,"i"):void 0,suffixPattern:r?new RegExp(`${r}$`,"i"):void 0,findStar(i){let n=i;return this.prefixPattern&&(n=n.replace(this.prefixPattern,"")),this.suffixPattern&&(n=n.replace(this.suffixPattern,"")),n}};yield*H(t.directory,t,o)}async function*Q(t,e){if(t.exports){let r=new h().process(t.exports,{itemPath:["exports"]},e);for(let o of r)yield*K(o)}}function*X(t,e){t.main&&(yield p({moduleName:e.name,condition:void 0,itemPath:["main"],modulePath:t.main,packageContext:e,subpath:void 0}))}function*Y(t,e){t.module&&(yield p({moduleName:e.name,condition:void 0,itemPath:["module"],modulePath:t.module,packageContext:e,subpath:void 0}))}function*Z(t,e){let r="types"in t?"types":"typings"in t?"typings":void 0;if(r){let o=t[r];o&&(yield p({condition:"types",itemPath:[r],modulePath:o,packageContext:e,subpath:void 0}))}}async function*tt(t,e){yield*L(t,e),yield*T(t,e),yield*W(t,e),yield*X(t,e),yield*Y(t,e),yield*Z(t,e),yield*Q(t,e)}import Qt from"@npmcli/arborist";import Xt from"npm-packlist";import{sep as et}from"node:path";function rt(t){return et==="/"?t:t.replaceAll("/",et)}async function ot(t){let r=await new Qt({path:t}).loadActual();return(await Xt(r)).map(i=>rt(i))}import{AssertionError as Yt}from"node:assert";function nt(t){if(!U(t))throw new Yt({message:"input is not PackageJson",actual:t})}import{readFile as Zt}from"node:fs/promises";async function it(t){let e=await Zt(t,"utf-8");return JSON.parse(e)}async function st(t){let e=await it(t);return nt(e),e}import te from"node:assert";function at(){let[t]=process.versions.node.split(".");return te(t),Number.parseInt(t)}var ee=at();async function ct(t,e){let r=/\.json$/i.test(t)?`node --input-type=module --eval="import '${t}' ${ee<20?"assert":"with"} { type: 'json' };" --no-warnings`:`node --input-type=module --eval="import '${t}';"`;await l(r,e)}async function pt(t,e){try{return typeof t.moduleName=="string"?(await ct(t.moduleName,e),new a({code:0,entryPoint:t,message:`"${t.moduleName}" works with import`,name:"import"})):new a({code:2,entryPoint:t,message:`Import skipped: ${t.itemPath.join(".")}`,name:"import"})}catch(r){return new a({code:1,entryPoint:t,error:r instanceof Error?r:new Error(String(r)),message:`${t.moduleName??t.itemPath.join(".")} cannot be imported`,name:"import"})}}async function mt(t,e){let r=`node --input-type=commonjs --eval="require('${t}');"`;await l(r,e)}async function ft(t,e){try{return typeof t.moduleName=="string"?(await mt(t.moduleName,e),new a({code:0,entryPoint:t,message:`"${t.moduleName}" works with require`,name:"require"})):new a({code:2,entryPoint:t,message:`Require skipped: ${t.itemPath.join(".")}`,name:"require"})}catch(r){return new a({code:1,entryPoint:t,error:r instanceof Error?r:new Error(String(r)),message:`${t.moduleName??t.itemPath.join(".")} cannot be required`,name:"require"})}}function re(t){if(t.itemPath.length===1){let e=t.itemPath[0];if(e==="main"||e==="exports")return t.type!=="module"}return typeof t.condition>"u"||t.condition==="require"}function oe(t){return typeof t.condition>"u"||t.condition==="import"}async function ut(t,e){let r=[];try{typeof t.moduleName=="string"&&(re(t)&&r.push(await ft(t,e)),oe(t)&&r.push(await pt(t,e)))}catch(o){if(o instanceof Error)throw new Error(`Unable to verify "${t.moduleName}"`,{cause:o})}return r}var k=class extends ne{options;packageDirectory;#e;#t;constructor(e){super(),this.options=e,this.packageDirectory=ie(this.options.package),this.#e=0,this.#t=e.controller}processResult(e){this.emit("result",e),e.code===1&&(this.#e=1,this.options.bail&&this.#t.abort())}processResults(e){[e].flat().forEach(r=>this.processResult(r))}async checkFilesExist(e){return await x.from(e).map(async r=>{let o=await A(r);return this.processResults(o),o},{signal:this.#t.signal,concurrency:this.options.concurrency}).toArray({signal:this.#t.signal})}async checkSyntax(e){let r=e.filter(o=>/\.[cm]?js$/i.test(o.resolvedPath));return await x.from(r).map(async o=>{let i=await B(o,{signal:this.#t.signal});return this.processResults(i),i},{signal:this.#t.signal,concurrency:this.options.concurrency}).toArray({signal:this.#t.signal})}async verifyIncludes(e){return(await x.from(e).map(async r=>{let o=await ut(r,{cwd:this.packageDirectory,signal:this.#t.signal});return this.processResults(o),o},{signal:this.#t.signal,concurrency:this.options.concurrency}).toArray({signal:this.#t.signal})).flat()}async checkPacklist(e,r){let o=new Set(await ot(r.directory)),i=e.map(n=>{let s=o.has(n.relativePath);return new a({name:"packlist",code:s?0:1,message:s?`${n.relativePath} will be packed`:`${n.relativePath} will not be packed`,error:s?void 0:new Error("EntryPoint relativePath not found in packlist files"),entryPoint:n})});return this.processResults(i),i}async run(){let e=await st(this.options.package),r={name:e.name,type:e.type??"commonjs",path:this.options.package,directory:this.packageDirectory},o=await x.from(tt(e,r),{objectMode:!0}).toArray({signal:this.#t.signal}),i=new Set,n=m=>{m.forEach(f=>{f.code===1&&i.add(f.entryPoint)})},s=m=>m.filter(f=>!i.has(f));return n(await this.checkFilesExist(o)),this.options.check&&n(await this.checkSyntax(s(o))),this.options.verify&&n(await this.verifyIncludes(s(o))),n(await this.checkPacklist(s(o),r)),this.#e}};import{parseArgs as ae}from"node:util";import{availableParallelism as se}from"node:os";function lt(t){let e=se(),r=Number.parseInt(`${t}`);return Number.isInteger(r)?Math.max(1,Math.min(r,e)):e}function yt(t){let e={args:t,allowPositionals:!0,strict:!0,tokens:!1,options:{concurrency:{type:"string",short:"c"},bail:{type:"boolean",short:"b",default:process.env.CI==="true"},check:{type:"boolean",default:!1,short:"s"},verify:{type:"boolean",default:!1,short:"v"},json:{type:"boolean",default:!1,short:"j"},info:{type:"boolean",default:process.env.RUNNER_DEBUG==="1",short:"i"},"no-bail":{type:"boolean",default:!1},"no-info":{type:"boolean",default:!1}}},{values:r,positionals:o}=ae(e),i=r["no-bail"]??e.options["no-bail"].default,n=r["no-info"]??e.options["no-info"].default;return{packages:o.length?o:["./package.json"],concurrency:lt(r.concurrency),bail:i?!1:r.bail??e.options.bail.default,check:r.check??e.options.check.default,verify:r.verify??e.options.verify.default,json:r.json??e.options.verify.default,info:n?!1:r.info??e.options.info.default}}import{stat as ce}from"node:fs/promises";import{basename as pe,join as me,resolve as fe}from"node:path";async function O(t){let e=await ce(t);if(e.isDirectory())return await O(me(t,"package.json"));if(e.isFile()&&pe(t)==="package.json")return fe(t);throw new Error(`Unable to resolve package.json from ${t}`)}try{let{json:t,info:e,packages:r,...o}=yt(),i=await le.from(r).map(c=>O(c),{concurrency:o.concurrency}).toArray(),n=[],s=c=>{n.push(c),!t&&(e||c.code===1)&&console.log(c.toString())},m=new AbortController;ue(100,m.signal);let f=i.map(c=>{let g=new k({...o,package:c,controller:m});return g.on("result",s),g});try{for(let c of f)await c.run()}catch(c){if(c instanceof Error&&c.name!=="AbortError")throw c}process.exitCode=n.reduce((c,g)=>g.code===1?1:c,0),t&&process.stdout.write(JSON.stringify(n.filter(c=>e||c.code===1),null,2))}catch(t){console.group("validate-package-exports"),console.dir(t,{depth:null}),console.groupEnd(),process.exitCode??=1}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "validate-package-exports",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "Validate your package.json exports actually exist, have valid syntax, and can be imported or required without issues.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"validate",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
},
|
|
17
17
|
"repository": {
|
|
18
18
|
"type": "git",
|
|
19
|
-
"url": "https://github.com/webdeveric/validate-package-exports.git"
|
|
19
|
+
"url": "git+https://github.com/webdeveric/validate-package-exports.git"
|
|
20
20
|
},
|
|
21
21
|
"bugs": {
|
|
22
22
|
"url": "https://github.com/webdeveric/validate-package-exports/issues"
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"homepage": "https://github.com/webdeveric/validate-package-exports/#readme",
|
|
25
25
|
"type": "module",
|
|
26
26
|
"bin": {
|
|
27
|
-
"validate-package-exports": "
|
|
27
|
+
"validate-package-exports": "dist/cli.mjs"
|
|
28
28
|
},
|
|
29
29
|
"files": [
|
|
30
30
|
"./dist"
|
|
@@ -40,14 +40,14 @@
|
|
|
40
40
|
"npm-packlist": "^8.0.2"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@types/node": "^20.14.
|
|
43
|
+
"@types/node": "^20.14.15",
|
|
44
44
|
"@types/npm-packlist": "^7.0.3",
|
|
45
45
|
"@types/npmcli__arborist": "^5.6.9",
|
|
46
|
-
"@vitest/coverage-v8": "^2.0.
|
|
47
|
-
"@webdeveric/eslint-config-ts": "^0.
|
|
46
|
+
"@vitest/coverage-v8": "^2.0.5",
|
|
47
|
+
"@webdeveric/eslint-config-ts": "^0.9.0",
|
|
48
48
|
"@webdeveric/prettier-config": "^0.3.0",
|
|
49
49
|
"cross-env": "^7.0.3",
|
|
50
|
-
"cspell": "^8.
|
|
50
|
+
"cspell": "^8.13.3",
|
|
51
51
|
"esbuild": "^0.23.0",
|
|
52
52
|
"esbuild-plugin-clean": "^1.0.1",
|
|
53
53
|
"esbuild-plugin-environment": "^0.4.0",
|
|
@@ -55,12 +55,12 @@
|
|
|
55
55
|
"eslint-config-prettier": "^9.1.0",
|
|
56
56
|
"eslint-import-resolver-typescript": "^3.6.1",
|
|
57
57
|
"eslint-plugin-import": "^2.29.1",
|
|
58
|
-
"husky": "^9.1.
|
|
59
|
-
"lint-staged": "^15.2.
|
|
58
|
+
"husky": "^9.1.4",
|
|
59
|
+
"lint-staged": "^15.2.8",
|
|
60
60
|
"prettier": "^3.3.3",
|
|
61
61
|
"typescript": "^5.5.4",
|
|
62
|
-
"vite-tsconfig-paths": "^
|
|
63
|
-
"vitest": "^2.0.
|
|
62
|
+
"vite-tsconfig-paths": "^5.0.1",
|
|
63
|
+
"vitest": "^2.0.5"
|
|
64
64
|
},
|
|
65
65
|
"scripts": {
|
|
66
66
|
"prevalidate": "pnpm build:dev",
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"typecheck": "tsc --noEmit && tsc -p ./tsconfig.project-files.json",
|
|
73
73
|
"spellcheck": "cspell --no-progress \"./src/**/*.{ts,js,json}\" \"./*.{md,js,mjs,mts}\" \"./LICENSE\" \"./package.json\"",
|
|
74
74
|
"lint": "eslint ./src ./*.{mjs,mts} --ext .ts",
|
|
75
|
-
"test": "vitest
|
|
76
|
-
"coverage": "vitest run
|
|
75
|
+
"test": "vitest",
|
|
76
|
+
"coverage": "vitest run --coverage"
|
|
77
77
|
}
|
|
78
78
|
}
|