@visulima/package 5.0.9 → 5.0.11

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/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ ## @visulima/package [5.0.11](https://github.com/visulima/visulima/compare/%40visulima%2Fpackage%405.0.10...%40visulima%2Fpackage%405.0.11) (2026-08-02)
2
+
3
+
4
+ ### Dependencies
5
+
6
+ * **@visulima/fs:** upgraded to 5.1.0
7
+ * **@visulima/path:** upgraded to 3.1.0
8
+
9
+ ## @visulima/package [5.0.10](https://github.com/visulima/visulima/compare/%40visulima%2Fpackage%405.0.9...%40visulima%2Fpackage%405.0.10) (2026-07-27)
10
+
11
+
12
+ ### Dependencies
13
+
14
+ * **@visulima/fs:** upgraded to 5.0.11
15
+
1
16
  ## @visulima/package [5.0.9](https://github.com/visulima/visulima/compare/%40visulima%2Fpackage%405.0.8...%40visulima%2Fpackage%405.0.9) (2026-07-27)
2
17
 
3
18
 
package/dist/error.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  /**
2
- * Error thrown when a package was not found.
3
- */
2
+ * Error thrown when a package was not found.
3
+ */
4
4
  declare class PackageNotFoundError extends Error {
5
5
  /**
6
- * @param packageName The name of the package that was not found.
7
- * @param packageManager The package manager used to install the package.
8
- */
6
+ * @param packageName The name of the package that was not found.
7
+ * @param packageManager The package manager used to install the package.
8
+ */
9
9
  constructor(packageName: string[] | string, packageManager?: string);
10
10
  get code(): string;
11
11
  set code(_name: string);
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ export { PackageNotFoundError } from "./error.js";
2
2
  export { type LockFileEntry, type LockFileIntegrity, type LockFileIntegrityAlgorithm, type LockFileParseResult, type LockFileType, decodeSriIntegrity, parseBunLockFile, parseLockFile, parseLockFileContent, parseLockFileSync, parseNpmLockFile, parsePnpmLockFile, parseYarnLockFile } from "./lockfile.js";
3
3
  export { type RootMonorepo, type Strategy, findMonorepoRoot, findMonorepoRootSync } from "./monorepo.js";
4
4
  export { findPackageRoot, findPackageRootSync } from "./package.js";
5
- export { type E as EnsurePackagesOptions, type F as FindPackageJsonCache, type N as NormalizedPackageJson, type a as NormalizedReadResult, type P as PackageJson, c as clearPackageJsonCache, e as ensurePackages, f as findPackageJson, b as findPackageJsonSync, g as getPackageJsonProperty, h as hasPackageJsonAnyDependency, d as hasPackageJsonProperty, p as parsePackageJson, i as parsePackageJsonSync, w as writePackageJson, j as writePackageJsonSync } from "./packem_shared/package-json.d-BHWsl_Em.js";
5
+ export { type E as EnsurePackagesOptions, type F as FindPackageJsonCache, type N as NormalizedPackageJson, type a as NormalizedReadResult, type P as PackageJson, c as clearPackageJsonCache, e as ensurePackages, f as findPackageJson, b as findPackageJsonSync, g as getPackageJsonProperty, h as hasPackageJsonAnyDependency, d as hasPackageJsonProperty, p as parsePackageJson, i as parsePackageJsonSync, w as writePackageJson, j as writePackageJsonSync } from "./packem_shared/package-json.d-62php2nC.js";
6
6
  export { type PackageManager, type PackageManagerResult, findLockFile, findLockFileSync, findPackageManager, findPackageManagerSync, generateMissingPackagesInstallMessage, getPackageManagerVersion, identifyInitiatingPackageManager } from "./package-manager.js";
7
7
  export { type PnpmCatalog, type PnpmCatalogs, isPackageInWorkspace, readPnpmCatalogs, readPnpmCatalogsSync, resolveCatalogReference, resolveCatalogReferences, resolveDependenciesCatalogReferences } from "./pnpm.js";
8
8
  import '@visulima/fs';
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Lockfiles the parser recognises. Both the modern text `bun.lock` and the
3
- * legacy binary `bun.lockb` map to the `bun` type, but only `bun.lock`
4
- * content is parseable — `bun.lockb` is a binary format and yields no entries.
5
- */
2
+ * Lockfiles the parser recognises. Both the modern text `bun.lock` and the
3
+ * legacy binary `bun.lockb` map to the `bun` type, but only `bun.lock`
4
+ * content is parseable — `bun.lockb` is a binary format and yields no entries.
5
+ */
6
6
  type LockFileType = "bun" | "npm" | "pnpm" | "yarn";
7
7
  /** SRI algorithms the parser can decode into hex. */
8
8
  type LockFileIntegrityAlgorithm = "sha256" | "sha384" | "sha512";
@@ -14,19 +14,19 @@ interface LockFileIntegrity {
14
14
  /** A single resolved package extracted from a lockfile. */
15
15
  interface LockFileEntry {
16
16
  /**
17
- * Declared runtime dependencies — `name → specifier[]` map. Values
18
- * are arrays so pnpm v9+ peer-context variants (the same dep name
19
- * resolved to different versions under different peer contexts)
20
- * can all be preserved. npm, yarn v1, bun, and pnpm v6-v8 always
21
- * produce single-element arrays; pnpm v9+ may produce multi-element
22
- * arrays for peer-context-sensitive deps.
23
- *
24
- * Specifiers are whatever the lockfile recorded — a range
25
- * (`^1.0.0`) for npm / yarn / bun, or an already-resolved exact
26
- * version for pnpm. Callers resolve each specifier against
27
- * {@link LockFileEntry.version} values elsewhere in the lockfile
28
- * when they need a concrete edge.
29
- */
17
+ * Declared runtime dependencies — `name → specifier[]` map. Values
18
+ * are arrays so pnpm v9+ peer-context variants (the same dep name
19
+ * resolved to different versions under different peer contexts)
20
+ * can all be preserved. npm, yarn v1, bun, and pnpm v6-v8 always
21
+ * produce single-element arrays; pnpm v9+ may produce multi-element
22
+ * arrays for peer-context-sensitive deps.
23
+ *
24
+ * Specifiers are whatever the lockfile recorded — a range
25
+ * (`^1.0.0`) for npm / yarn / bun, or an already-resolved exact
26
+ * version for pnpm. Callers resolve each specifier against
27
+ * {@link LockFileEntry.version} values elsewhere in the lockfile
28
+ * when they need a concrete edge.
29
+ */
30
30
  dependencies?: Record<string, string[]>;
31
31
  /** Decoded SRI digest, if the lockfile recorded one. */
32
32
  integrity?: LockFileIntegrity;
@@ -47,74 +47,74 @@ interface LockFileParseResult {
47
47
  type: LockFileType;
48
48
  }
49
49
  /**
50
- * Decodes a Subresource Integrity string (`sha512-&lt;base64>`) into a
51
- * `{ algorithm, hex }` pair. Returns `undefined` if the string is
52
- * malformed, oversized, or uses an unsupported algorithm.
53
- * @param sri Full SRI string, e.g. `sha512-&lt;base64>`.
54
- * @returns Decoded algorithm + hex digest, or `undefined` when the
55
- * input can't be parsed.
56
- */
50
+ * Decodes a Subresource Integrity string (`sha512-&lt;base64>`) into a
51
+ * `{ algorithm, hex }` pair. Returns `undefined` if the string is
52
+ * malformed, oversized, or uses an unsupported algorithm.
53
+ * @param sri Full SRI string, e.g. `sha512-&lt;base64>`.
54
+ * @returns Decoded algorithm + hex digest, or `undefined` when the
55
+ * input can't be parsed.
56
+ */
57
57
  declare const decodeSriIntegrity: (sri: string) => LockFileIntegrity | undefined;
58
58
  /**
59
- * Parses `package-lock.json` (npm v2 / v3 format).
60
- * @param content Raw JSON text of the lockfile.
61
- * @returns One {@link LockFileEntry} per distinct `name@version`.
62
- */
59
+ * Parses `package-lock.json` (npm v2 / v3 format).
60
+ * @param content Raw JSON text of the lockfile.
61
+ * @returns One {@link LockFileEntry} per distinct `name@version`.
62
+ */
63
63
  declare const parseNpmLockFile: (content: string) => LockFileEntry[];
64
64
  /**
65
- * Parses `pnpm-lock.yaml`. Regex-based; works for lockfile v6 through
66
- * v9. v9 moves concrete resolved dependency versions out of `packages:`
67
- * and into `snapshots:`; this parser reads both sections and unions
68
- * their dep-maps onto the final entry.
69
- * @param content Raw YAML text of the lockfile.
70
- * @returns One {@link LockFileEntry} per distinct `name@version`.
71
- */
65
+ * Parses `pnpm-lock.yaml`. Regex-based; works for lockfile v6 through
66
+ * v9. v9 moves concrete resolved dependency versions out of `packages:`
67
+ * and into `snapshots:`; this parser reads both sections and unions
68
+ * their dep-maps onto the final entry.
69
+ * @param content Raw YAML text of the lockfile.
70
+ * @returns One {@link LockFileEntry} per distinct `name@version`.
71
+ */
72
72
  declare const parsePnpmLockFile: (content: string) => LockFileEntry[];
73
73
  /**
74
- * Parses `yarn.lock` for Yarn Classic (v1) and Berry (v2+). Berry's
75
- * XXH64 `checksum:` is not a cryptographic hash and is intentionally
76
- * dropped; only v1's SRI `integrity:` flows through to
77
- * {@link LockFileEntry.integrity}.
78
- * @param content Raw text of the lockfile.
79
- * @returns One {@link LockFileEntry} per distinct `name@version`.
80
- */
74
+ * Parses `yarn.lock` for Yarn Classic (v1) and Berry (v2+). Berry's
75
+ * XXH64 `checksum:` is not a cryptographic hash and is intentionally
76
+ * dropped; only v1's SRI `integrity:` flows through to
77
+ * {@link LockFileEntry.integrity}.
78
+ * @param content Raw text of the lockfile.
79
+ * @returns One {@link LockFileEntry} per distinct `name@version`.
80
+ */
81
81
  declare const parseYarnLockFile: (content: string) => LockFileEntry[];
82
82
  /**
83
- * Parses `bun.lock` (Bun v1.1+, JSON-ish with trailing commas). The
84
- * legacy binary `bun.lockb` format is recognised by {@link inferLockFileType}
85
- * but cannot be decoded here — feeding its binary contents in returns an
86
- * empty array (the `JSON.parse` fails and is swallowed).
87
- *
88
- * Attribution: format + tuple layout verified against lockparse
89
- * (https://github.com/43081j/lockparse, MIT).
90
- * @param content Raw text of the lockfile.
91
- * @returns One {@link LockFileEntry} per distinct `name@version`.
92
- */
83
+ * Parses `bun.lock` (Bun v1.1+, JSON-ish with trailing commas). The
84
+ * legacy binary `bun.lockb` format is recognised by {@link inferLockFileType}
85
+ * but cannot be decoded here — feeding its binary contents in returns an
86
+ * empty array (the `JSON.parse` fails and is swallowed).
87
+ *
88
+ * Attribution: format + tuple layout verified against lockparse
89
+ * (https://github.com/43081j/lockparse, MIT).
90
+ * @param content Raw text of the lockfile.
91
+ * @returns One {@link LockFileEntry} per distinct `name@version`.
92
+ */
93
93
  declare const parseBunLockFile: (content: string) => LockFileEntry[];
94
94
  /**
95
- * Parses raw lockfile content of the given type. Returns an empty
96
- * array if the content is malformed or doesn't contain any package
97
- * entries.
98
- * @param content Raw text of the lockfile.
99
- * @param type Which parser to dispatch to.
100
- * @returns One {@link LockFileEntry} per distinct `name@version`.
101
- */
95
+ * Parses raw lockfile content of the given type. Returns an empty
96
+ * array if the content is malformed or doesn't contain any package
97
+ * entries.
98
+ * @param content Raw text of the lockfile.
99
+ * @param type Which parser to dispatch to.
100
+ * @returns One {@link LockFileEntry} per distinct `name@version`.
101
+ */
102
102
  declare const parseLockFileContent: (content: string, type: LockFileType) => LockFileEntry[];
103
103
  /**
104
- * Walks up from `cwd`, locates the nearest supported lockfile, reads
105
- * it, and returns the parsed entries alongside the lockfile type and
106
- * absolute path.
107
- * @param cwd Directory to start the search from. Defaults to
108
- * `process.cwd()` (delegated to `findUp`).
109
- * @returns The parsed result, keyed by the discovered lockfile path.
110
- * @throws If no supported lockfile can be found above `cwd`.
111
- */
104
+ * Walks up from `cwd`, locates the nearest supported lockfile, reads
105
+ * it, and returns the parsed entries alongside the lockfile type and
106
+ * absolute path.
107
+ * @param cwd Directory to start the search from. Defaults to
108
+ * `process.cwd()` (delegated to `findUp`).
109
+ * @returns The parsed result, keyed by the discovered lockfile path.
110
+ * @throws If no supported lockfile can be found above `cwd`.
111
+ */
112
112
  declare const parseLockFile: (cwd?: URL | string) => Promise<LockFileParseResult>;
113
113
  /**
114
- * Synchronous counterpart to {@link parseLockFile}.
115
- * @param cwd Directory to start the search from.
116
- * @returns The parsed result, keyed by the discovered lockfile path.
117
- * @throws If no supported lockfile can be found above `cwd`.
118
- */
114
+ * Synchronous counterpart to {@link parseLockFile}.
115
+ * @param cwd Directory to start the search from.
116
+ * @returns The parsed result, keyed by the discovered lockfile path.
117
+ * @throws If no supported lockfile can be found above `cwd`.
118
+ */
119
119
  declare const parseLockFileSync: (cwd?: URL | string) => LockFileParseResult;
120
120
  export { LockFileEntry, LockFileIntegrity, LockFileIntegrityAlgorithm, LockFileParseResult, LockFileType, decodeSriIntegrity, parseBunLockFile, parseLockFile, parseLockFileContent, parseLockFileSync, parseNpmLockFile, parsePnpmLockFile, parseYarnLockFile };
package/dist/lockfile.js CHANGED
@@ -1 +1 @@
1
- import{createRequire as E}from"node:module";import{findUp as I,findUpSync as N}from"@visulima/fs";const R=E(import.meta.url),h=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,$=n=>{if(typeof h<"u"&&h.versions&&h.versions.node){const[e,t]=h.versions.node.split(".").map(Number);if(e>22||e===22&&t>=3||e===20&&t>=16)return h.getBuiltinModule(n)}return R(n)},{readFileSync:A}=$("node:fs"),{readFile:C}=$("node:fs/promises"),U={sha256:"sha256",sha384:"sha384",sha512:"sha512"},B=1024,M=/^[A-Z0-9+/]+={0,2}$/i,j="node_modules/",m=/^['"]/,k=/['"]$/,T=/^[a-z][a-zA-Z0-9]*:\s*$/m,q=/resolution:\s*\{[^}]*integrity:\s*([^,}\s]+)/,P=/^["']?((?:@[^/@"']+\/)?[^@"'\n]+)@[^\n]+\n((?:[\t ][^\n]*(?:\n|$))+)/gm,z=/^\s+version:?\s+"?([^"\n]+)"?/m,J=/^\s+integrity[\s:]+"?([^"\s]+)"?/m,v=n=>{if(n.length>B)return;const e=n.indexOf("-");if(e<=0)return;const t=U[n.slice(0,e).toLowerCase()];if(!t)return;const s=n.slice(e+1);if(M.test(s))try{const c=Buffer.from(s,"base64");return c.length===0?void 0:{algorithm:t,hex:c.toString("hex")}}catch{return}},w=(n,e,t)=>{const s=`${t.name}@${t.version}`;e.has(s)||(e.add(s),n.push(t))},u=(n,e,t)=>{t&&Object.keys(t).length>0&&(n[e]={...t})},g=n=>{if(!n)return;const e={};for(const[t,s]of Object.entries(n))e[t]=[s];return Object.keys(e).length>0?e:void 0},Z=n=>{const e=[],t=new Set;let s;try{s=JSON.parse(n)}catch{return e}if(!s.packages)return e;for(const[c,o]of Object.entries(s.packages)){if(!c||!o.version)continue;const p=c.lastIndexOf(j);if(p===-1)continue;const i=c.slice(p+j.length);if(i.length===0)continue;const r=i.split("/"),a=i.startsWith("@")?2:1;if(r.length!==a||r.some(f=>f.length===0))continue;const l=o.name??i;if(l.startsWith("."))continue;const d={name:l,version:o.version};if(o.integrity){const f=v(o.integrity);f&&(d.integrity=f)}u(d,"dependencies",g(o.dependencies)),u(d,"peerDependencies",g(o.peerDependencies)),u(d,"optionalDependencies",g(o.optionalDependencies)),w(e,t,d)}return e},O=n=>{let e=n.trim();e.startsWith("/")&&(e=e.slice(1)),e=e.replace(m,"").replace(k,"");const t=e.indexOf("(");t>0&&(e=e.slice(0,t));const s=e.lastIndexOf("@");if(s<=0)return;const c=e.slice(0,s),o=e.slice(s+1);if(!(!c||!o||o.startsWith("link:")||o.startsWith("workspace:")||o.startsWith("file:")))return{name:c,version:o}},S=(n,e)=>{const t=new RegExp(String.raw`^${e}:\s*$`,"m").exec(n);if(!t)return;const s=t.index+t[0].length,c=T.exec(n.slice(s));return n.slice(s,c?s+c.index:n.length)},Y=n=>{const e=new Map,t=S(n,"snapshots");if(!t)return e;const s=/^ {2}(['"]?[^\s:][^:\n]*?['"]?):\s*\n((?: {4}[^\n]*\n?)+)/gm;let c;for(;(c=s.exec(t)??void 0)!==void 0;){const o=O(c[1]);if(!o)continue;const p=`${o.name}@${o.version}`,i=c[2],r=e.get(p)??{};for(const a of["dependencies","peerDependencies","optionalDependencies"]){const l=y(i,a);if(!l)continue;const d=r[a]??{};for(const[f,L]of Object.entries(l)){const x=d[f]??[];for(const D of L)x.includes(D)||x.push(D);d[f]=x}r[a]=d}e.set(p,r)}return e},G=n=>{const e=[],t=new Set,s=S(n,"packages");if(!s)return e;const c=Y(n),o=/^ {2}(['"]?[^\s:][^:\n]*?['"]?):\s*\n((?: {4}[^\n]*\n?)+)/gm;let p;for(;(p=o.exec(s)??void 0)!==void 0;){const i=O(p[1]);if(!i)continue;const r=p[2],a=q.exec(r),l={name:i.name,version:i.version};if(a?.[1]){const f=v(a[1]);f&&(l.integrity=f)}const d=c.get(`${i.name}@${i.version}`);u(l,"dependencies",d?.dependencies??y(r,"dependencies")),u(l,"peerDependencies",d?.peerDependencies??y(r,"peerDependencies")),u(l,"optionalDependencies",d?.optionalDependencies??y(r,"optionalDependencies")),w(e,t,l)}return e},y=(n,e)=>{const t=new RegExp(String.raw`^ {4}${e}:\s*\n((?: {6,}[^\n]*\n?)+)`,"m").exec(n);if(!t?.[1])return;const s={},c=/^ {6}([^\s:]+):\s*([^\n]+)/gm;let o;for(;(o=c.exec(t[1])??void 0)!==void 0;){const p=o[1].replace(m,"").replace(k,"");let i=o[2].trim();i=i.replace(m,"").replace(k,"");const r=i.indexOf("(");if(r>0&&(i=i.slice(0,r).trim()),!p||!i)continue;const a=s[p]??[];a.includes(i)||a.push(i),s[p]=a}return Object.keys(s).length>0?s:void 0},H=n=>{const e=[],t=new Set,s=P;s.lastIndex=0;let c;for(;(c=s.exec(n)??void 0)!==void 0;){const o=c[1].replace(m,"").replace(k,"");if(!o)continue;const p=c[2],i=z.exec(p);if(!i?.[1])continue;const r={name:o,version:i[1].trim()},a=J.exec(p);if(a?.[1]){const l=v(a[1]);l&&(r.integrity=l)}u(r,"dependencies",b(p,"dependencies")),u(r,"peerDependencies",b(p,"peerDependencies")),u(r,"optionalDependencies",b(p,"optionalDependencies")),w(e,t,r)}return e},b=(n,e)=>{const t=new RegExp(String.raw`^ {2}${e}:\s*\n((?: {4,}[^\n]*\n?)+)`,"m").exec(n);if(!t?.[1])return;const s={},c=/^ {4}(['"]?[^\s:'"]+['"]?)\s*(?::\s*)?['"]([^'"\n]+)['"]/gm;let o;for(;(o=c.exec(t[1])??void 0)!==void 0;){const p=o[1].replace(m,"").replace(k,""),i=o[2];if(p&&i){const r=s[p]??[];r.includes(i)||r.push(i),s[p]=r}}return Object.keys(s).length>0?s:void 0},K=/,(?=\s*[}\]])/g,Q=n=>{const e=[],t=new Set;let s;try{s=JSON.parse(n.replaceAll(K,""))}catch{return e}if(!s.packages)return e;for(const c of Object.values(s.packages)){const o=c[0];if(typeof o!="string")continue;const p=o.indexOf("@",1);if(p<=0)continue;const i=o.slice(0,p),r=o.slice(p+1);if(!i||!r||r.startsWith("workspace:")||r.startsWith("link:")||r.startsWith("file:"))continue;const a={name:i,version:r},l=c[3];if(typeof l=="string"&&l.length>0){const f=v(l);f&&(a.integrity=f)}const d=c[2];if(d&&typeof d=="object"&&!Array.isArray(d)){const f=d;u(a,"dependencies",g(f.dependencies)),u(a,"peerDependencies",g(f.peerDependencies)),u(a,"optionalDependencies",g(f.optionalDependencies))}w(e,t,a)}return e},W=n=>{if(n.endsWith("pnpm-lock.yaml"))return"pnpm";if(n.endsWith("package-lock.json"))return"npm";if(n.endsWith("yarn.lock"))return"yarn";if(n.endsWith("bun.lockb")||n.endsWith("bun.lock"))return"bun"},_=(n,e)=>{switch(e){case"bun":return Q(n);case"npm":return Z(n);case"pnpm":return G(n);case"yarn":return H(n);default:return[]}},F=["pnpm-lock.yaml","package-lock.json","yarn.lock","bun.lock","bun.lockb"],ee=async n=>{const e=await I(F,{type:"file",...n&&{cwd:n}});if(!e)throw new Error("Could not find a supported lock file (pnpm-lock.yaml, package-lock.json, yarn.lock, bun.lock)");const t=W(e);if(!t)throw new Error(`Unsupported lock file: ${e}`);const s=await C(e,"utf8");return{entries:_(s,t),path:e,type:t}},ne=n=>{const e=N(F,{type:"file",...n&&{cwd:n}});if(!e)throw new Error("Could not find a supported lock file (pnpm-lock.yaml, package-lock.json, yarn.lock, bun.lock)");const t=W(e);if(!t)throw new Error(`Unsupported lock file: ${e}`);return{entries:_(A(e,"utf8"),t),path:e,type:t}};export{v as decodeSriIntegrity,Q as parseBunLockFile,ee as parseLockFile,_ as parseLockFileContent,ne as parseLockFileSync,Z as parseNpmLockFile,G as parsePnpmLockFile,H as parseYarnLockFile};
1
+ import{createRequire as E}from"node:module";import{findUp as N,findUpSync as U}from"@visulima/fs";import{L as q}from"./packem_shared/lockfile-candidates-B-i5hlDs.js";let A;const C=n=>(A??=E(import.meta.url))(n),g=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,_=n=>{if(typeof g<"u"&&g.versions&&g.versions.node){const[e,t]=g.versions.node.split(".").map(Number);if(e>22||e===22&&t>=3||e===20&&t>=16)return g.getBuiltinModule(n)}return C(n)},{readFileSync:I}=_("node:fs"),{readFile:R}=_("node:fs/promises"),B={sha256:"sha256",sha384:"sha384",sha512:"sha512"},M=1024,T=/^[A-Z0-9+/]+={0,2}$/i,b="node_modules/",m=/^['"]/,k=/['"]$/,P=/^[a-z][a-zA-Z0-9]*:\s*$/m,z=/resolution:\s*\{[^}]*integrity:\s*([^,}\s]+)/,J=/^["']?((?:@[^/@"']+\/)?[^@"'\n]+)@[^\n]+\n((?:[\t ][^\n]*(?:\n|$))+)/gm,K=/^\s+version:?\s+"?([^"\n]+)"?/m,Z=/^\s+integrity[\s:]+"?([^"\s]+)"?/m,w=n=>{if(n.length>M)return;const e=n.indexOf("-");if(e<=0)return;const t=B[n.slice(0,e).toLowerCase()];if(!t)return;const s=n.slice(e+1);if(T.test(s))try{const r=Buffer.from(s,"base64");return r.length===0?void 0:{algorithm:t,hex:r.toString("hex")}}catch{return}},v=(n,e,t)=>{const s=`${t.name}@${t.version}`;e.has(s)||(e.add(s),n.push(t))},u=(n,e,t)=>{t&&Object.keys(t).length>0&&(n[e]={...t})},h=n=>{if(!n)return;const e={};for(const[t,s]of Object.entries(n))e[t]=[s];return Object.keys(e).length>0?e:void 0},Y=n=>{const e=[],t=new Set;let s;try{s=JSON.parse(n)}catch{return e}if(!s.packages)return e;for(const[r,o]of Object.entries(s.packages)){if(!r||!o.version)continue;const p=r.lastIndexOf(b);if(p===-1)continue;const i=r.slice(p+b.length);if(i.length===0)continue;const c=i.split("/"),a=i.startsWith("@")?2:1;if(c.length!==a||c.some(f=>f.length===0))continue;const l=o.name??i;if(l.startsWith("."))continue;const d={name:l,version:o.version};if(o.integrity){const f=w(o.integrity);f&&(d.integrity=f)}u(d,"dependencies",h(o.dependencies)),u(d,"peerDependencies",h(o.peerDependencies)),u(d,"optionalDependencies",h(o.optionalDependencies)),v(e,t,d)}return e},O=n=>{let e=n.trim();e.startsWith("/")&&(e=e.slice(1)),e=e.replace(m,"").replace(k,"");const t=e.indexOf("(");t>0&&(e=e.slice(0,t));const s=e.lastIndexOf("@");if(s<=0)return;const r=e.slice(0,s),o=e.slice(s+1);if(!(!r||!o||o.startsWith("link:")||o.startsWith("workspace:")||o.startsWith("file:")))return{name:r,version:o}},$=(n,e)=>{const t=new RegExp(String.raw`^${e}:\s*$`,"m").exec(n);if(!t)return;const s=t.index+t[0].length,r=P.exec(n.slice(s));return n.slice(s,r?s+r.index:n.length)},G=n=>{const e=new Map,t=$(n,"snapshots");if(!t)return e;const s=/^ {2}(['"]?[^\s:][^:\n]*?['"]?):\s*\n((?: {4}[^\n]*\n?)+)/gm;let r;for(;(r=s.exec(t)??void 0)!==void 0;){const o=O(r[1]);if(!o)continue;const p=`${o.name}@${o.version}`,i=r[2],c=e.get(p)??{};for(const a of["dependencies","peerDependencies","optionalDependencies"]){const l=y(i,a);if(!l)continue;const d=c[a]??{};for(const[f,F]of Object.entries(l)){const x=d[f]??[];for(const j of F)x.includes(j)||x.push(j);d[f]=x}c[a]=d}e.set(p,c)}return e},H=n=>{const e=[],t=new Set,s=$(n,"packages");if(!s)return e;const r=G(n),o=/^ {2}(['"]?[^\s:][^:\n]*?['"]?):\s*\n((?: {4}[^\n]*\n?)+)/gm;let p;for(;(p=o.exec(s)??void 0)!==void 0;){const i=O(p[1]);if(!i)continue;const c=p[2],a=z.exec(c),l={name:i.name,version:i.version};if(a?.[1]){const f=w(a[1]);f&&(l.integrity=f)}const d=r.get(`${i.name}@${i.version}`);u(l,"dependencies",d?.dependencies??y(c,"dependencies")),u(l,"peerDependencies",d?.peerDependencies??y(c,"peerDependencies")),u(l,"optionalDependencies",d?.optionalDependencies??y(c,"optionalDependencies")),v(e,t,l)}return e},y=(n,e)=>{const t=new RegExp(String.raw`^ {4}${e}:\s*\n((?: {6,}[^\n]*\n?)+)`,"m").exec(n);if(!t?.[1])return;const s={},r=/^ {6}([^\s:]+):\s*([^\n]+)/gm;let o;for(;(o=r.exec(t[1])??void 0)!==void 0;){const p=o[1].replace(m,"").replace(k,"");let i=o[2].trim();i=i.replace(m,"").replace(k,"");const c=i.indexOf("(");if(c>0&&(i=i.slice(0,c).trim()),!p||!i)continue;const a=s[p]??[];a.includes(i)||a.push(i),s[p]=a}return Object.keys(s).length>0?s:void 0},Q=n=>{const e=[],t=new Set,s=J;s.lastIndex=0;let r;for(;(r=s.exec(n)??void 0)!==void 0;){const o=r[1].replace(m,"").replace(k,"");if(!o)continue;const p=r[2],i=K.exec(p);if(!i?.[1])continue;const c={name:o,version:i[1].trim()},a=Z.exec(p);if(a?.[1]){const l=w(a[1]);l&&(c.integrity=l)}u(c,"dependencies",D(p,"dependencies")),u(c,"peerDependencies",D(p,"peerDependencies")),u(c,"optionalDependencies",D(p,"optionalDependencies")),v(e,t,c)}return e},D=(n,e)=>{const t=new RegExp(String.raw`^ {2}${e}:\s*\n((?: {4,}[^\n]*\n?)+)`,"m").exec(n);if(!t?.[1])return;const s={},r=/^ {4}(['"]?[^\s:'"]+['"]?)\s*(?::\s*)?['"]([^'"\n]+)['"]/gm;let o;for(;(o=r.exec(t[1])??void 0)!==void 0;){const p=o[1].replace(m,"").replace(k,""),i=o[2];if(p&&i){const c=s[p]??[];c.includes(i)||c.push(i),s[p]=c}}return Object.keys(s).length>0?s:void 0},V=/,(?=\s*[}\]])/g,X=n=>{const e=[],t=new Set;let s;try{s=JSON.parse(n.replaceAll(V,""))}catch{return e}if(!s.packages)return e;for(const r of Object.values(s.packages)){const o=r[0];if(typeof o!="string")continue;const p=o.indexOf("@",1);if(p<=0)continue;const i=o.slice(0,p),c=o.slice(p+1);if(!i||!c||c.startsWith("workspace:")||c.startsWith("link:")||c.startsWith("file:"))continue;const a={name:i,version:c},l=r[3];if(typeof l=="string"&&l.length>0){const f=w(l);f&&(a.integrity=f)}const d=r[2];if(d&&typeof d=="object"&&!Array.isArray(d)){const f=d;u(a,"dependencies",h(f.dependencies)),u(a,"peerDependencies",h(f.peerDependencies)),u(a,"optionalDependencies",h(f.optionalDependencies))}v(e,t,a)}return e},S=n=>{if(n.endsWith("pnpm-lock.yaml"))return"pnpm";if(n.endsWith("package-lock.json")||n.endsWith("npm-shrinkwrap.json"))return"npm";if(n.endsWith("yarn.lock"))return"yarn";if(n.endsWith("bun.lockb")||n.endsWith("bun.lock"))return"bun"},W=(n,e)=>{switch(e){case"bun":return X(n);case"npm":return Y(n);case"pnpm":return H(n);case"yarn":return Q(n);default:return[]}},L=[...q],se=async n=>{const e=await N(L,{type:"file",...n&&{cwd:n}});if(!e)throw new Error("Could not find a supported lock file (pnpm-lock.yaml, package-lock.json, npm-shrinkwrap.json, yarn.lock, bun.lock)");const t=S(e);if(!t)throw new Error(`Unsupported lock file: ${e}`);const s=await R(e,"utf8");return{entries:W(s,t),path:e,type:t}},oe=n=>{const e=U(L,{type:"file",...n&&{cwd:n}});if(!e)throw new Error("Could not find a supported lock file (pnpm-lock.yaml, package-lock.json, npm-shrinkwrap.json, yarn.lock, bun.lock)");const t=S(e);if(!t)throw new Error(`Unsupported lock file: ${e}`);return{entries:W(I(e,"utf8"),t),path:e,type:t}};export{w as decodeSriIntegrity,X as parseBunLockFile,se as parseLockFile,W as parseLockFileContent,oe as parseLockFileSync,Y as parseNpmLockFile,H as parsePnpmLockFile,Q as parseYarnLockFile};
@@ -4,23 +4,23 @@ interface RootMonorepo<T extends Strategy = Strategy> {
4
4
  strategy: T;
5
5
  }
6
6
  /**
7
- * An asynchronous function to find the root directory path and strategy for a monorepo based on
8
- * the given current working directory (cwd).
9
- * @param cwd The current working directory. The type of `cwd` is part of an `Options` type, specifically `Options["cwd"]`.
10
- * Default is undefined.
11
- * @returns A `Promise` that resolves to the root directory path and strategy for the monorepo.
12
- * The type of the returned promise is `Promise&lt;RootMonorepo>`.
13
- * @throws An `Error` if no monorepo root can be found using lerna, yarn, pnpm, or npm as indicators.
14
- */
7
+ * An asynchronous function to find the root directory path and strategy for a monorepo based on
8
+ * the given current working directory (cwd).
9
+ * @param cwd The current working directory. The type of `cwd` is part of an `Options` type, specifically `Options["cwd"]`.
10
+ * Default is undefined.
11
+ * @returns A `Promise` that resolves to the root directory path and strategy for the monorepo.
12
+ * The type of the returned promise is `Promise&lt;RootMonorepo>`.
13
+ * @throws An `Error` if no monorepo root can be found using lerna, yarn, pnpm, or npm as indicators.
14
+ */
15
15
  declare const findMonorepoRoot: (cwd?: URL | string) => Promise<RootMonorepo>;
16
16
  /**
17
- * An function to find the root directory path and strategy for a monorepo based on
18
- * the given current working directory (cwd).
19
- * @param cwd The current working directory. The type of `cwd` is part of an `Options` type, specifically `Options["cwd"]`.
20
- * Default is undefined.
21
- * @returns A `Promise` that resolves to the root directory path and strategy for the monorepo.
22
- * The type of the returned promise is `Promise&lt;RootMonorepo>`.
23
- * @throws An `Error` if no monorepo root can be found using lerna, yarn, pnpm, or npm as indicators.
24
- */
17
+ * An function to find the root directory path and strategy for a monorepo based on
18
+ * the given current working directory (cwd).
19
+ * @param cwd The current working directory. The type of `cwd` is part of an `Options` type, specifically `Options["cwd"]`.
20
+ * Default is undefined.
21
+ * @returns A `Promise` that resolves to the root directory path and strategy for the monorepo.
22
+ * The type of the returned promise is `Promise&lt;RootMonorepo>`.
23
+ * @throws An `Error` if no monorepo root can be found using lerna, yarn, pnpm, or npm as indicators.
24
+ */
25
25
  declare const findMonorepoRootSync: (cwd?: URL | string) => RootMonorepo;
26
26
  export { RootMonorepo, Strategy, findMonorepoRoot, findMonorepoRootSync };
package/dist/monorepo.js CHANGED
@@ -1 +1 @@
1
- import{createRequire as d}from"node:module";import{findUp as y,readJson as g,findUpSync as h,readJsonSync as j}from"@visulima/fs";import{NotFoundError as f}from"@visulima/fs/error";import{dirname as u,join as a}from"@visulima/path";import{findPackageManager as w,findPackageManagerSync as k}from"./package-manager.js";const m=d(import.meta.url),i=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,l=r=>{if(typeof i<"u"&&i.versions&&i.versions.node){const[e,t]=i.versions.node.split(".").map(Number);if(e>22||e===22&&t>=3||e===20&&t>=16)return i.getBuiltinModule(r)}return m(r)},{existsSync:c,readFileSync:p}=l("node:fs"),N=async r=>{const e=await y(["lerna.json","turbo.json"],{type:"file",...r&&{cwd:r}});if(e?.endsWith("lerna.json")){const n=await g(e);if(n&&typeof n=="object"&&!Array.isArray(n)){const o=n;if(o.useWorkspaces||o.packages)return{path:u(e),strategy:"lerna"}}}const t=e?.endsWith("turbo.json");try{const{packageManager:n,path:o}=await w(r);if(["npm","yarn"].includes(n)){const s=a(o,"package.json");if(c(s)&&p(a(o,"package.json"),"utf8").includes("workspaces"))return{path:o,strategy:t?"turbo":n}}else if(n==="pnpm"){const s=a(o,"pnpm-workspace.yaml");if(c(s))return{path:o,strategy:t?"turbo":"pnpm"}}}catch(n){if(!(n instanceof f))throw n}throw new Error(`No monorepo root could be found upwards from the directory ${String(r??process.cwd())} using lerna, yarn, pnpm, or npm as indicators.`)},R=r=>{const e=h(["lerna.json","turbo.json"],{type:"file",...r&&{cwd:r}});if(e?.endsWith("lerna.json")){const n=j(e);if(n.useWorkspaces||n.packages)return{path:u(e),strategy:"lerna"}}const t=e?.endsWith("turbo.json");try{const{packageManager:n,path:o}=k(r);if(["npm","yarn"].includes(n)){const s=a(o,"package.json");if(c(s)&&p(a(o,"package.json"),"utf8").includes("workspaces"))return{path:o,strategy:t?"turbo":n}}else if(n==="pnpm"){const s=a(o,"pnpm-workspace.yaml");if(c(s))return{path:o,strategy:t?"turbo":"pnpm"}}}catch(n){if(!(n instanceof f))throw n}throw new Error(`No monorepo root could be found upwards from the directory ${String(r??process.cwd())} using lerna, yarn, pnpm, or npm as indicators.`)};export{N as findMonorepoRoot,R as findMonorepoRootSync};
1
+ import{createRequire as l}from"node:module";import{findUp as j,readJson as b,findUpSync as w,readJsonSync as k}from"@visulima/fs";import{NotFoundError as u}from"@visulima/fs/error";import{parseJson as _}from"@visulima/fs/utils";import{dirname as d,join as a}from"@visulima/path";import{findPackageManager as M,findPackageManagerSync as S}from"./package-manager.js";let m;const g=t=>(m??=l(import.meta.url))(t),c=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,h=t=>{if(typeof c<"u"&&c.versions&&c.versions.node){const[o,e]=c.versions.node.split(".").map(Number);if(o>22||o===22&&e>=3||o===20&&e>=16)return c.getBuiltinModule(t)}return g(t)},{existsSync:i,readFileSync:f}=h("node:fs"),y=t=>{let o;try{o=_(t)}catch{return!1}if(!o||typeof o!="object"||Array.isArray(o))return!1;const{workspaces:e}=o;return typeof e=="object"&&e!==null},E=async t=>{const o=await j(["lerna.json","turbo.json"],{type:"file",...t&&{cwd:t}});if(o?.endsWith("lerna.json")){const r=await b(o);if(r&&typeof r=="object"&&!Array.isArray(r)){const n=r;if(n.useWorkspaces||n.packages)return{path:d(o),strategy:"lerna"}}}const e=o?.endsWith("turbo.json");try{const{packageManager:r,path:n}=await M(t);if(["npm","yarn"].includes(r)){const s=a(n,"package.json");if(i(s)){const p=f(a(n,"package.json"),"utf8");if(y(p))return{path:n,strategy:e?"turbo":r}}}else if(r==="pnpm"){const s=a(n,"pnpm-workspace.yaml");if(i(s))return{path:n,strategy:e?"turbo":"pnpm"}}}catch(r){if(!(r instanceof u))throw r}throw new Error(`No monorepo root could be found upwards from the directory ${String(t??process.cwd())} using lerna, yarn, pnpm, or npm as indicators.`)},J=t=>{const o=w(["lerna.json","turbo.json"],{type:"file",...t&&{cwd:t}});if(o?.endsWith("lerna.json")){const r=k(o);if(r&&typeof r=="object"&&!Array.isArray(r)){const n=r;if(n.useWorkspaces||n.packages)return{path:d(o),strategy:"lerna"}}}const e=o?.endsWith("turbo.json");try{const{packageManager:r,path:n}=S(t);if(["npm","yarn"].includes(r)){const s=a(n,"package.json");if(i(s)){const p=f(a(n,"package.json"),"utf8");if(y(p))return{path:n,strategy:e?"turbo":r}}}else if(r==="pnpm"){const s=a(n,"pnpm-workspace.yaml");if(i(s))return{path:n,strategy:e?"turbo":"pnpm"}}}catch(r){if(!(r instanceof u))throw r}throw new Error(`No monorepo root could be found upwards from the directory ${String(t??process.cwd())} using lerna, yarn, pnpm, or npm as indicators.`)};export{E as findMonorepoRoot,J as findMonorepoRootSync};
@@ -1,6 +1,6 @@
1
1
  import '@visulima/fs';
2
2
  import 'type-fest';
3
- export { F as FindPackageJsonCache, a as NormalizedReadResult, c as clearPackageJsonCache, e as ensurePackages, f as findPackageJson, b as findPackageJsonSync, g as getPackageJsonProperty, h as hasPackageJsonAnyDependency, d as hasPackageJsonProperty, p as parsePackageJson, i as parsePackageJsonSync, w as writePackageJson, j as writePackageJsonSync } from "./packem_shared/package-json.d-BHWsl_Em.js";
3
+ export { F as FindPackageJsonCache, a as NormalizedReadResult, c as clearPackageJsonCache, e as ensurePackages, f as findPackageJson, b as findPackageJsonSync, g as getPackageJsonProperty, h as hasPackageJsonAnyDependency, d as hasPackageJsonProperty, p as parsePackageJson, i as parsePackageJsonSync, w as writePackageJson, j as writePackageJsonSync } from "./packem_shared/package-json.d-62php2nC.js";
4
4
  import '@antfu/install-pkg';
5
5
  import '@inquirer/core';
6
6
  import '@inquirer/type';
@@ -1,4 +1,4 @@
1
- import{createRequire as q}from"node:module";import{installPackage as Y}from"@antfu/install-pkg";import{findUp as G,findUpSync as X,writeJson as z,writeJsonSync as U,readJson as V,readJsonSync as L,readFile as O,readFileSync as H}from"@visulima/fs";import{NotFoundError as x}from"@visulima/fs/error";import{toPath as v,parseJson as P}from"@visulima/fs/utils";import{readYaml as K,readYamlSync as Q}from"@visulima/fs/yaml";import{join as S}from"@visulima/path";import _ from"json5";import Z from"normalize-package-data";import{readPnpmCatalogs as N,resolveCatalogReferences as m,readPnpmCatalogsSync as I}from"./pnpm.js";const M=q(import.meta.url),h=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,E=r=>{if(typeof h<"u"&&h.versions&&h.versions.node){const[e,o]=h.versions.node.split(".").map(Number);if(e>22||e===22&&o>=3||e===20&&o>=16)return h.getBuiltinModule(r)}return M(r)},{existsSync:j}=E("node:fs"),{createInterface:ee}=E("node:readline"),{styleText:l}=E("node:util"),k=r=>{const e=typeof r;return r!==null&&(e==="object"||e==="function")},J=new Set(["__proto__","prototype","constructor"]),T=1e6,re=r=>r>="0"&&r<="9";function C(r){if(r==="0")return!0;if(/^[1-9]\d*$/.test(r)){const e=Number.parseInt(r,10);return e<=Number.MAX_SAFE_INTEGER&&e<=T}return!1}function b(r,e){return J.has(r)?!1:(r&&C(r)?e.push(Number.parseInt(r,10)):e.push(r),!0)}function te(r){if(typeof r!="string")throw new TypeError(`Expected a string, got ${typeof r}`);const e=[];let o="",t="start",a=!1,n=0;for(const s of r){if(n++,a){o+=s,a=!1;continue}if(s==="\\"){if(t==="index")throw new Error(`Invalid character '${s}' in an index at position ${n}`);if(t==="indexEnd")throw new Error(`Invalid character '${s}' after an index at position ${n}`);a=!0,t=t==="start"?"property":t;continue}switch(s){case".":{if(t==="index")throw new Error(`Invalid character '${s}' in an index at position ${n}`);if(t==="indexEnd"){t="property";break}if(!b(o,e))return[];o="",t="property";break}case"[":{if(t==="index")throw new Error(`Invalid character '${s}' in an index at position ${n}`);if(t==="indexEnd"){t="index";break}if(t==="property"||t==="start"){if((o||t==="property")&&!b(o,e))return[];o=""}t="index";break}case"]":{if(t==="index"){if(o==="")o=(e.pop()||"")+"[]",t="property";else{const i=Number.parseInt(o,10);!Number.isNaN(i)&&Number.isFinite(i)&&i>=0&&i<=Number.MAX_SAFE_INTEGER&&i<=T&&o===String(i)?e.push(i):e.push(o),o="",t="indexEnd"}break}if(t==="indexEnd")throw new Error(`Invalid character '${s}' after an index at position ${n}`);o+=s;break}default:{if(t==="index"&&!re(s))throw new Error(`Invalid character '${s}' in an index at position ${n}`);if(t==="indexEnd")throw new Error(`Invalid character '${s}' after an index at position ${n}`);t==="start"&&(t="property"),o+=s}}}switch(a&&(o+="\\"),t){case"property":{if(!b(o,e))return[];break}case"index":throw new Error("Index was not closed");case"start":{e.push("");break}}return e}function A(r){if(typeof r=="string")return te(r);if(Array.isArray(r)){const e=[];for(const[o,t]of r.entries()){if(typeof t!="string"&&typeof t!="number")throw new TypeError(`Expected a string or number for path segment at index ${o}, got ${typeof t}`);if(typeof t=="number"&&!Number.isFinite(t))throw new TypeError(`Path segment at index ${o} must be a finite number, got ${t}`);if(J.has(t))return[];typeof t=="string"&&C(t)?e.push(Number.parseInt(t,10)):e.push(t)}return e}return[]}function p(r,e,o){if(!k(r)||typeof e!="string"&&!Array.isArray(e))return o===void 0?r:o;const t=A(e);if(t.length===0)return o;for(let a=0;a<t.length;a++){const n=t[a];if(r=r[n],r==null){if(a!==t.length-1)return o;break}}return r===void 0?o:r}function y(r,e){if(!k(r)||typeof e!="string"&&!Array.isArray(e))return!1;const o=A(e);if(o.length===0)return!1;for(const t of o){if(!k(r)||!(t in r))return!1;r=r[t]}return!0}const oe=async r=>{const{default:e=!1,message:o,transformer:t}=r,a=s=>{const i=l(["cyan","bold"],"?"),c=l(["bold"],s),f=e?`${l(["greenBright"],"Y")}${l(["gray"],"/n")}`:`y/${l(["yellowBright"],"N")}`;return`${i} ${c} ${l(["gray"],`(${f})`)}`},n=s=>t?t(s):s?l(["greenBright"],"Yes"):l(["yellowBright"],"No");return new Promise(s=>{const i=ee({input:process.stdin,output:process.stdout}),c=a(o);i.question(c,f=>{i.close();const g=f.trim().toLowerCase();if(g===""){s(e);return}if(g==="y"||g==="yes"){console.log(`${l(["greenBright"],"✓")} ${n(!0)}`),s(!0);return}if(g==="n"||g==="no"){console.log(`${l(["yellowBright"],"✗")} ${n(!1)}`),s(!1);return}console.log(`${l(["gray"],"→")} ${n(e)}`),s(e)}),i.on("SIGINT",()=>{i.close(),console.log(`
2
- ${l(["gray"],"→")} ${n(e)}`),s(e)})})},ne=typeof process.stdout<"u"&&!process.versions.deno&&!globalThis.window,W=/, ([^,]*)$/,u=new Map,w=new Map,d=(r,e={})=>`${r}|s${String(e.strict?1:0)}|c${String(e.resolveCatalogs?1:0)}|j${String(e.json5===!1?0:1)}|y${String(e.yaml===!1?0:1)}|w${String(e.ignoreWarnings?1:0)}`,D=r=>r.trimStart().startsWith("{"),F=r=>{const e=`${r}|`;for(const o of[w,u])for(const t of o.keys())t.startsWith(e)&&o.delete(t)};class se extends Error{constructor(e){super(`The following warnings were encountered while normalizing package data:
1
+ import{createRequire as B}from"node:module";import{installPackage as M}from"@antfu/install-pkg";import{findUp as Y,findUpSync as G,writeJson as X,writeJsonSync as z,readJson as U,readJsonSync as V,readFile as L,readFileSync as H}from"@visulima/fs";import{NotFoundError as v}from"@visulima/fs/error";import{toPath as j,parseJson as x}from"@visulima/fs/utils";import{readYaml as K,readYamlSync as Q}from"@visulima/fs/yaml";import{join as P}from"@visulima/path";import _ from"json5";import Z from"normalize-package-data";import{readPnpmCatalogs as S,resolveCatalogReferences as y,readPnpmCatalogsSync as N}from"./pnpm.js";let R;const q=r=>(R??=B(import.meta.url))(r),h=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,k=r=>{if(typeof h<"u"&&h.versions&&h.versions.node){const[e,o]=h.versions.node.split(".").map(Number);if(e>22||e===22&&o>=3||e===20&&o>=16)return h.getBuiltinModule(r)}return q(r)},{existsSync:E}=k("node:fs"),{createInterface:ee}=k("node:readline"),{styleText:l}=k("node:util"),b=r=>{const e=typeof r;return r!==null&&(e==="object"||e==="function")},I=new Set(["__proto__","prototype","constructor"]),J=1e6,re=r=>r>="0"&&r<="9";function T(r){if(r==="0")return!0;if(/^[1-9]\d*$/.test(r)){const e=Number.parseInt(r,10);return e<=Number.MAX_SAFE_INTEGER&&e<=J}return!1}function $(r,e){return I.has(r)?!1:(r&&T(r)?e.push(Number.parseInt(r,10)):e.push(r),!0)}function te(r){if(typeof r!="string")throw new TypeError(`Expected a string, got ${typeof r}`);const e=[];let o="",t="start",n=!1,s=0;for(const a of r){if(s++,n){o+=a,n=!1;continue}if(a==="\\"){if(t==="index")throw new Error(`Invalid character '${a}' in an index at position ${s}`);if(t==="indexEnd")throw new Error(`Invalid character '${a}' after an index at position ${s}`);n=!0,t=t==="start"?"property":t;continue}switch(a){case".":{if(t==="index")throw new Error(`Invalid character '${a}' in an index at position ${s}`);if(t==="indexEnd"){t="property";break}if(!$(o,e))return[];o="",t="property";break}case"[":{if(t==="index")throw new Error(`Invalid character '${a}' in an index at position ${s}`);if(t==="indexEnd"){t="index";break}if(t==="property"||t==="start"){if((o||t==="property")&&!$(o,e))return[];o=""}t="index";break}case"]":{if(t==="index"){if(o==="")o=(e.pop()||"")+"[]",t="property";else{const i=Number.parseInt(o,10);!Number.isNaN(i)&&Number.isFinite(i)&&i>=0&&i<=Number.MAX_SAFE_INTEGER&&i<=J&&o===String(i)?e.push(i):e.push(o),o="",t="indexEnd"}break}if(t==="indexEnd")throw new Error(`Invalid character '${a}' after an index at position ${s}`);o+=a;break}default:{if(t==="index"&&!re(a))throw new Error(`Invalid character '${a}' in an index at position ${s}`);if(t==="indexEnd")throw new Error(`Invalid character '${a}' after an index at position ${s}`);t==="start"&&(t="property"),o+=a}}}switch(n&&(o+="\\"),t){case"property":{if(!$(o,e))return[];break}case"index":throw new Error("Index was not closed");case"start":{e.push("");break}}return e}function C(r){if(typeof r=="string")return te(r);if(Array.isArray(r)){const e=[];for(const[o,t]of r.entries()){if(typeof t!="string"&&typeof t!="number")throw new TypeError(`Expected a string or number for path segment at index ${o}, got ${typeof t}`);if(typeof t=="number"&&!Number.isFinite(t))throw new TypeError(`Path segment at index ${o} must be a finite number, got ${t}`);if(I.has(t))return[];typeof t=="string"&&T(t)?e.push(Number.parseInt(t,10)):e.push(t)}return e}return[]}function p(r,e,o){if(!b(r)||typeof e!="string"&&!Array.isArray(e))return o===void 0?r:o;const t=C(e);if(t.length===0)return o;for(let n=0;n<t.length;n++){const s=t[n];if(r=r[s],r==null){if(n!==t.length-1)return o;break}}return r===void 0?o:r}function oe(r,e){if(!b(r)||typeof e!="string"&&!Array.isArray(e))return!1;const o=C(e);if(o.length===0)return!1;for(const t of o){if(!b(r)||!(t in r))return!1;r=r[t]}return!0}const ne=async r=>{const{default:e=!1,message:o,transformer:t}=r,n=a=>{const i=l(["cyan","bold"],"?"),c=l(["bold"],a),f=e?`${l(["greenBright"],"Y")}${l(["gray"],"/n")}`:`y/${l(["yellowBright"],"N")}`;return`${i} ${c} ${l(["gray"],`(${f})`)}`},s=a=>t?t(a):a?l(["greenBright"],"Yes"):l(["yellowBright"],"No");return new Promise(a=>{const i=ee({input:process.stdin,output:process.stdout}),c=n(o);i.question(c,f=>{i.close();const g=f.trim().toLowerCase();if(g===""){a(e);return}if(g==="y"||g==="yes"){console.log(`${l(["greenBright"],"✓")} ${s(!0)}`),a(!0);return}if(g==="n"||g==="no"){console.log(`${l(["yellowBright"],"✗")} ${s(!1)}`),a(!1);return}console.log(`${l(["gray"],"→")} ${s(e)}`),a(e)}),i.on("SIGINT",()=>{i.close(),console.log(`
2
+ ${l(["gray"],"→")} ${s(!1)}`),a(!1)})})},se=typeof process.stdout<"u"&&!process.versions.deno&&!globalThis.window,A=/, ([^,]*)$/,u=new Map,m=new Map,d=(r,e={})=>{const o=e.strict&&e.ignoreWarnings?e.ignoreWarnings.map(String).toSorted((t,n)=>t.localeCompare(n)).join(","):"";return`${r}|s${String(e.strict?1:0)}|c${String(e.resolveCatalogs?1:0)}|j${String(e.json5===!1?0:1)}|y${String(e.yaml===!1?0:1)}|w${o}`},W=r=>r.trimStart().startsWith("{"),D=r=>{const e=`${r}|`;for(const o of[m,u])for(const t of o.keys())t.startsWith(e)&&o.delete(t)};class ae extends Error{constructor(e){super(`The following warnings were encountered while normalizing package data:
3
3
  - ${e.join(`
4
- - `)}`),this.name="PackageJsonValidationError"}}const $=(r,e,o=[])=>{const t=[];if(Z(r,a=>{t.push(a)},e),e&&t.length>0){const a=t.filter(n=>!o.some(s=>s instanceof RegExp?s.test(n):s===n));if(a.length>0)throw new se(a)}return r},ae=async r=>await K(r),ie=r=>Q(r),ce=async r=>{const e=await O(r);return _.parse(e)},fe=r=>{const e=H(r);return _.parse(e)},B=async(r,e)=>e?.yaml!==!1&&(r.endsWith(".yaml")||r.endsWith(".yml"))?ae(r):e?.json5!==!1&&r.endsWith(".json5")?ce(r):V(r),R=(r,e)=>e?.yaml!==!1&&(r.endsWith(".yaml")||r.endsWith(".yml"))?ie(r):e?.json5!==!1&&r.endsWith(".json5")?fe(r):L(r),be=async(r,e={})=>{const o={type:"file"};r&&(o.cwd=r);const t=["package.json"];e.yaml!==!1&&t.push("package.yaml","package.yml"),e.json5!==!1&&t.push("package.json5");const a=await G(t,o);if(!a)throw new x(`No such file or directory, for ${t.join(", ").replace(W," or $1")} found.`);const n=e.cache&&typeof e.cache!="boolean"?e.cache:w,s=d(a,e);if(e.cache&&n.has(s))return n.get(s);const i=await B(a,e);if(e.resolveCatalogs){const f=await N(a);f&&m(i,f)}$(i,e.strict??!1,e.ignoreWarnings);const c={packageJson:i,path:a};return e.cache&&n.set(s,c),c},ke=(r,e={})=>{const o={type:"file"};r&&(o.cwd=r);const t=["package.json"];e.yaml!==!1&&t.push("package.yaml","package.yml"),e.json5!==!1&&t.push("package.json5");const a=X(t,o);if(!a)throw new x(`No such file or directory, for ${t.join(", ").replace(W," or $1")} found.`);const n=e.cache&&typeof e.cache!="boolean"?e.cache:w,s=d(a,e);if(e.cache&&n.has(s))return n.get(s);const i=R(a,e);if(e.resolveCatalogs){const f=I(a);f&&m(i,f)}$(i,e.strict??!1,e.ignoreWarnings);const c={packageJson:i,path:a};return e.cache&&n.set(s,c),c},Ee=async(r,e={})=>{const{cwd:o,...t}=e,a=v(o??process.cwd()),n=S(a,"package.json");await z(n,r,t),F(n)},ve=(r,e={})=>{const{cwd:o,...t}=e,a=v(o??process.cwd()),n=S(a,"package.json");U(n,r,t),F(n)},je=()=>{w.clear(),u.clear()},xe=(r,e)=>{const o=typeof r=="object"&&!Array.isArray(r);if(!o&&typeof r!="string")throw new TypeError("`packageFile` should be either an `object` or a `string`.");let t,a=!1,n;if(o)t=structuredClone(r);else if(!D(r)&&j(r)){n=r;const i=e?.cache&&typeof e.cache!="boolean"?e.cache:u,c=d(n,e);if(e?.cache&&i.has(c))return i.get(c);t=R(n,e),a=!0}else t=P(r);if(e?.resolveCatalogs)if(a){const i=I(r);i&&m(t,i)}else throw new Error("The 'resolveCatalogs' option can only be used on a file path.");$(t,e?.strict??!1,e?.ignoreWarnings);const s=t;return a&&e?.cache&&(typeof e.cache=="boolean"?u:e.cache).set(d(n,e),s),s},Pe=async(r,e)=>{const o=typeof r=="object"&&!Array.isArray(r);if(!o&&typeof r!="string")throw new TypeError("`packageFile` should be either an `object` or a `string`.");let t,a=!1,n;if(o)t=structuredClone(r);else if(!D(r)&&j(r)){n=r;const i=e?.cache&&typeof e.cache!="boolean"?e.cache:u,c=d(n,e);if(e?.cache&&i.has(c))return i.get(c);t=await B(n,e),a=!0}else t=P(r);if(e?.resolveCatalogs)if(a){const i=await N(r);i&&m(t,i)}else throw new Error("The 'resolveCatalogs' option can only be used on a file path.");$(t,e?.strict??!1,e?.ignoreWarnings);const s=t;return a&&e?.cache&&(typeof e.cache=="boolean"?u:e.cache).set(d(n,e),s),s},Se=(r,e,o)=>p(r,e,o),_e=(r,e)=>y(r,e),Ne=(r,e,o)=>{const t=p(r,"dependencies",{}),a=p(r,"devDependencies",{}),n=p(r,"peerDependencies",{}),s={...t,...a,...o?.peerDeps===!1?{}:n};for(const i of e)if(y(s,i))return!0;return!1},Ie=async(r,e,o="dependencies",t={})=>{const a=p(r,"dependencies",{}),n=p(r,"devDependencies",{}),s=p(r,"peerDependencies",{}),i=[],c={deps:!0,devDeps:!0,peerDeps:!1,...t,...t.confirm?{confirm:{...t.confirm}}:{}};for(const f of e)c.deps&&y(a,f)||c.devDeps&&y(n,f)||c.peerDeps&&y(s,f)||i.push(f);if(i.length!==0){if(process.env.CI||ne&&!process.stdout.isTTY){const f=`Skipping package installation for [${e.join(", ")}] because the process is not interactive.`;if(t.throwOnWarn)throw new Error(f);t.logger?.warn?t.logger.warn(f):console.warn(f);return}if(typeof c.confirm?.message=="function"&&(c.confirm.message=c.confirm.message(i)),c.confirm?.message===void 0){const f=`${i.length===1?"Package is":"Packages are"} required for this config: ${i.join(", ")}. Do you want to install them?`;c.confirm===void 0?c.confirm={message:f}:c.confirm.message=f}await oe(c.confirm)&&await Y(i,{...c.installPackage,cwd:c.cwd?v(c.cwd):void 0,dev:o==="devDependencies"})}};export{je as clearPackageJsonCache,Ie as ensurePackages,be as findPackageJson,ke as findPackageJsonSync,Se as getPackageJsonProperty,Ne as hasPackageJsonAnyDependency,_e as hasPackageJsonProperty,Pe as parsePackageJson,xe as parsePackageJsonSync,Ee as writePackageJson,ve as writePackageJsonSync};
4
+ - `)}`),this.name="PackageJsonValidationError"}}const w=(r,e,o=[])=>{const t=[];if(Z(r,n=>{t.push(n)},e),e&&t.length>0){const n=t.filter(s=>!o.some(a=>a instanceof RegExp?a.test(s):a===s));if(n.length>0)throw new ae(n)}return r},ie=async r=>await K(r),ce=r=>Q(r),fe=async r=>{const e=await L(r);return _.parse(e)},le=r=>{const e=H(r);return _.parse(e)},F=async(r,e)=>e?.yaml!==!1&&(r.endsWith(".yaml")||r.endsWith(".yml"))?ie(r):e?.json5!==!1&&r.endsWith(".json5")?fe(r):U(r),O=(r,e)=>e?.yaml!==!1&&(r.endsWith(".yaml")||r.endsWith(".yml"))?ce(r):e?.json5!==!1&&r.endsWith(".json5")?le(r):V(r),ke=async(r,e={})=>{const o={type:"file"};r&&(o.cwd=r);const t=["package.json"];e.yaml!==!1&&t.push("package.yaml","package.yml"),e.json5!==!1&&t.push("package.json5");const n=await Y(t,o);if(!n)throw new v(`No such file or directory, for ${t.join(", ").replace(A," or $1")} found.`);const s=e.cache&&typeof e.cache!="boolean"?e.cache:m,a=d(n,e);if(e.cache&&s.has(a))return s.get(a);const i=await F(n,e);if(e.resolveCatalogs){const f=await S(n);f&&y(i,f)}w(i,e.strict??!1,e.ignoreWarnings);const c={packageJson:i,path:n};return e.cache&&s.set(a,c),c},je=(r,e={})=>{const o={type:"file"};r&&(o.cwd=r);const t=["package.json"];e.yaml!==!1&&t.push("package.yaml","package.yml"),e.json5!==!1&&t.push("package.json5");const n=G(t,o);if(!n)throw new v(`No such file or directory, for ${t.join(", ").replace(A," or $1")} found.`);const s=e.cache&&typeof e.cache!="boolean"?e.cache:m,a=d(n,e);if(e.cache&&s.has(a))return s.get(a);const i=O(n,e);if(e.resolveCatalogs){const f=N(n);f&&y(i,f)}w(i,e.strict??!1,e.ignoreWarnings);const c={packageJson:i,path:n};return e.cache&&s.set(a,c),c},Ee=async(r,e={})=>{const{cwd:o,...t}=e,n=j(o??process.cwd()),s=P(n,"package.json");await X(s,r,t),D(s)},ve=(r,e={})=>{const{cwd:o,...t}=e,n=j(o??process.cwd()),s=P(n,"package.json");z(s,r,t),D(s)},xe=()=>{m.clear(),u.clear()},Pe=(r,e)=>{const o=typeof r=="object"&&!Array.isArray(r);if(!o&&typeof r!="string")throw new TypeError("`packageFile` should be either an `object` or a `string`.");let t,n=!1,s;if(o)t=structuredClone(r);else if(!W(r)&&E(r)){s=r;const i=e?.cache&&typeof e.cache!="boolean"?e.cache:u,c=d(s,e);if(e?.cache&&i.has(c))return i.get(c);t=O(s,e),n=!0}else t=x(r);if(e?.resolveCatalogs)if(n){const i=N(r);i&&y(t,i)}else throw new Error("The 'resolveCatalogs' option can only be used on a file path.");w(t,e?.strict??!1,e?.ignoreWarnings);const a=t;return n&&e?.cache&&(typeof e.cache=="boolean"?u:e.cache).set(d(s,e),a),a},_e=async(r,e)=>{const o=typeof r=="object"&&!Array.isArray(r);if(!o&&typeof r!="string")throw new TypeError("`packageFile` should be either an `object` or a `string`.");let t,n=!1,s;if(o)t=structuredClone(r);else if(!W(r)&&E(r)){s=r;const i=e?.cache&&typeof e.cache!="boolean"?e.cache:u,c=d(s,e);if(e?.cache&&i.has(c))return i.get(c);t=await F(s,e),n=!0}else t=x(r);if(e?.resolveCatalogs)if(n){const i=await S(r);i&&y(t,i)}else throw new Error("The 'resolveCatalogs' option can only be used on a file path.");w(t,e?.strict??!1,e?.ignoreWarnings);const a=t;return n&&e?.cache&&(typeof e.cache=="boolean"?u:e.cache).set(d(s,e),a),a},Se=(r,e,o)=>p(r,e,o),Ne=(r,e)=>oe(r,e),Ie=(r,e,o)=>{const t=p(r,"dependencies",{}),n=p(r,"devDependencies",{}),s=p(r,"peerDependencies",{}),a={...t,...n,...o?.peerDeps===!1?{}:s};for(const i of e)if(Object.hasOwn(a,i))return!0;return!1},Je=async(r,e,o="dependencies",t={})=>{const n=p(r,"dependencies",{}),s=p(r,"devDependencies",{}),a=p(r,"peerDependencies",{}),i=[],c={deps:!0,devDeps:!0,peerDeps:!1,...t,...t.confirm?{confirm:{...t.confirm}}:{}};for(const f of e)c.deps&&Object.hasOwn(n??{},f)||c.devDeps&&Object.hasOwn(s??{},f)||c.peerDeps&&Object.hasOwn(a??{},f)||i.push(f);if(i.length!==0){if(process.env.CI||se&&!process.stdout.isTTY){const f=`Skipping package installation for [${e.join(", ")}] because the process is not interactive.`;if(t.throwOnWarn)throw new Error(f);t.logger?.warn?t.logger.warn(f):console.warn(f);return}if(typeof c.confirm?.message=="function"&&(c.confirm.message=c.confirm.message(i)),c.confirm?.message===void 0){const f=`${i.length===1?"Package is":"Packages are"} required for this config: ${i.join(", ")}. Do you want to install them?`;c.confirm===void 0?c.confirm={message:f}:c.confirm.message=f}await ne(c.confirm)&&await M(i,{...c.installPackage,cwd:c.cwd?j(c.cwd):void 0,dev:o==="devDependencies"})}};export{xe as clearPackageJsonCache,Je as ensurePackages,ke as findPackageJson,je as findPackageJsonSync,Se as getPackageJsonProperty,Ie as hasPackageJsonAnyDependency,Ne as hasPackageJsonProperty,_e as parsePackageJson,Pe as parsePackageJsonSync,Ee as writePackageJson,ve as writePackageJsonSync};
@@ -1,11 +1,11 @@
1
1
  /**
2
- * An asynchronous function that finds a lock file in the specified directory or any of its parent directories.
3
- * @param cwd Optional. The directory path to start the search from. The type of `cwd` is part of an `Options` type,
4
- * specifically `URL | string`. Defaults to the current working directory.
5
- * @returns A `Promise` that resolves with the path of the found lock file.
6
- * The type of the returned promise is `Promise&lt;string>`.
7
- * @throws An `Error` if no lock file is found.
8
- */
2
+ * An asynchronous function that finds a lock file in the specified directory or any of its parent directories.
3
+ * @param cwd Optional. The directory path to start the search from. The type of `cwd` is part of an `Options` type,
4
+ * specifically `URL | string`. Defaults to the current working directory.
5
+ * @returns A `Promise` that resolves with the path of the found lock file.
6
+ * The type of the returned promise is `Promise&lt;string>`.
7
+ * @throws An `Error` if no lock file is found.
8
+ */
9
9
  declare const findLockFile: (cwd?: URL | string) => Promise<string>;
10
10
  declare const findLockFileSync: (cwd?: URL | string) => string;
11
11
  type PackageManager = "bun" | "npm" | "pnpm" | "yarn";
@@ -14,57 +14,57 @@ type PackageManagerResult = {
14
14
  path: string;
15
15
  };
16
16
  /**
17
- * An asynchronous function that finds the package manager used in a project based on the presence of lock files
18
- * or package.json configuration. If found, it returns the package manager and the path to the lock file or package.json.
19
- * Throws an error if no lock file or package.json is found.
20
- * @param cwd Optional. The current working directory to start the search from. The type of `cwd` is part of an `Options`
21
- * type, specifically `URL | string`.
22
- * @returns A `Promise` that resolves to an object containing the package manager and path.
23
- * The return type of the function is `Promise&lt;PackageManagerResult>`.
24
- * @throws An `Error` if no lock file or package.json is found.
25
- */
17
+ * An asynchronous function that finds the package manager used in a project based on the presence of lock files
18
+ * or package.json configuration. If found, it returns the package manager and the path to the lock file or package.json.
19
+ * Throws an error if no lock file or package.json is found.
20
+ * @param cwd Optional. The current working directory to start the search from. The type of `cwd` is part of an `Options`
21
+ * type, specifically `URL | string`.
22
+ * @returns A `Promise` that resolves to an object containing the package manager and path.
23
+ * The return type of the function is `Promise&lt;PackageManagerResult>`.
24
+ * @throws An `Error` if no lock file or package.json is found.
25
+ */
26
26
  declare const findPackageManager: (cwd?: URL | string) => Promise<PackageManagerResult>;
27
27
  /**
28
- * An function that finds the package manager used in a project based on the presence of lock files
29
- * or package.json configuration. If found, it returns the package manager and the path to the lock file or package.json.
30
- * Throws an error if no lock file or package.json is found.
31
- * @param cwd Optional. The current working directory to start the search from. The type of `cwd` is part of an `Options`
32
- * type, specifically `URL | string`.
33
- * @returns A `Promise` that resolves to an object containing the package manager and path.
34
- * The return type of the function is `Promise&lt;PackageManagerResult>`.
35
- * @throws An `Error` if no lock file or package.json is found.
36
- */
28
+ * An function that finds the package manager used in a project based on the presence of lock files
29
+ * or package.json configuration. If found, it returns the package manager and the path to the lock file or package.json.
30
+ * Throws an error if no lock file or package.json is found.
31
+ * @param cwd Optional. The current working directory to start the search from. The type of `cwd` is part of an `Options`
32
+ * type, specifically `URL | string`.
33
+ * @returns A `Promise` that resolves to an object containing the package manager and path.
34
+ * The return type of the function is `Promise&lt;PackageManagerResult>`.
35
+ * @throws An `Error` if no lock file or package.json is found.
36
+ */
37
37
  declare const findPackageManagerSync: (cwd?: URL | string) => PackageManagerResult;
38
38
  /**
39
- * Function that retrieves the version of the specified package manager.
40
- * @param name The name of the package manager. Must be one of the known managers (`npm`, `pnpm`, `yarn`, `bun`).
41
- * @returns The version of the package manager. The return type of the function is `string`.
42
- * @throws An `Error` if `name` is not a recognized package manager. This guards against executing an
43
- * arbitrary or relative-path binary derived from untrusted input.
44
- */
39
+ * Function that retrieves the version of the specified package manager.
40
+ * @param name The name of the package manager. Must be one of the known managers (`npm`, `pnpm`, `yarn`, `bun`).
41
+ * @returns The version of the package manager. The return type of the function is `string`.
42
+ * @throws An `Error` if `name` is not a recognized package manager. This guards against executing an
43
+ * arbitrary or relative-path binary derived from untrusted input.
44
+ */
45
45
  declare const getPackageManagerVersion: (name: string) => string;
46
46
  /**
47
- * An asynchronous function that detects what package manager executes the process.
48
- *
49
- * Supports npm, pnpm, Yarn, cnpm, and bun. And also any other package manager that sets the npm_config_user_agent env variable.
50
- * @returns An object containing the name and version of the package manager,
51
- * or undefined if the package manager information cannot be determined.
52
- */
47
+ * An asynchronous function that detects what package manager executes the process.
48
+ *
49
+ * Supports npm, pnpm, Yarn, cnpm, and bun. And also any other package manager that sets the npm_config_user_agent env variable.
50
+ * @returns An object containing the name and version of the package manager,
51
+ * or undefined if the package manager information cannot be determined.
52
+ */
53
53
  declare const identifyInitiatingPackageManager: () => {
54
54
  name: PackageManager | "cnpm" | (string & {});
55
55
  version: string;
56
56
  } | undefined;
57
57
  /**
58
- * Function that generates a message to install missing packages.
59
- * @param packageName The name of the package that requires the missing packages.
60
- * @param missingPackages An array of missing package names.
61
- * @param options An object containing optional parameters:
62
- * @param options.packageManagers An array of package managers to include in the message. Defaults to \["npm", "pnpm", "yarn"\].
63
- * @param options.postMessage A string to append to the end of the message.
64
- * @param options.preMessage A string to prepend to the beginning of the message.
65
- * @returns A string message with instructions to install the missing packages using the specified package managers.
66
- * @throws An `Error` if no package managers are provided in the options.
67
- */
58
+ * Function that generates a message to install missing packages.
59
+ * @param packageName The name of the package that requires the missing packages.
60
+ * @param missingPackages An array of missing package names.
61
+ * @param options An object containing optional parameters:
62
+ * @param options.packageManagers An array of package managers to include in the message. Defaults to \["npm", "pnpm", "yarn"\].
63
+ * @param options.postMessage A string to append to the end of the message.
64
+ * @param options.preMessage A string to prepend to the beginning of the message.
65
+ * @returns A string message with instructions to install the missing packages using the specified package managers.
66
+ * @throws An `Error` if no package managers are provided in the options.
67
+ */
68
68
  declare const generateMissingPackagesInstallMessage: (packageName: string, missingPackages: string[], options: {
69
69
  packageManagers?: PackageManager[];
70
70
  postMessage?: string;
@@ -1,4 +1,4 @@
1
- import{createRequire as b}from"node:module";import{findUp as k,findUpSync as h}from"@visulima/fs";import{NotFoundError as f}from"@visulima/fs/error";import{parseJson as S}from"@visulima/fs/utils";import{join as p,dirname as s}from"@visulima/path";const $=b(import.meta.url),t=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,u=e=>{if(typeof t<"u"&&t.versions&&t.versions.node){const[n,a]=t.versions.node.split(".").map(Number);if(n>22||n===22&&a>=3||n===20&&a>=16)return t.getBuiltinModule(e)}return $(e)},{execFileSync:E}=u("node:child_process"),{existsSync:d,readFileSync:x}=u("node:fs"),g=["yarn.lock","package-lock.json","pnpm-lock.yaml","npm-shrinkwrap.json","bun.lock","bun.lockb"],m=new Set(["bun","npm","pnpm","yarn"]),w=e=>{const n=S(x(e,"utf8"));return typeof n?.packageManager=="string"?n.packageManager:void 0},y=e=>{let n;if(g.forEach(r=>{!n&&d(p(e,r))&&(n=p(e,r))}),n)return n;const a=p(e,"package.json");if(d(a)&&w(a)!==void 0)return a},M=e=>{if(!e)throw new f("Could not find a package manager");if(e.endsWith("package.json")){const n=w(e);if(n){const a=["npm","yarn","pnpm","bun"].find(r=>n.startsWith(r));if(a)return{packageManager:a,path:s(e)}}}if(e.endsWith("yarn.lock"))return{packageManager:"yarn",path:s(e)};if(e.endsWith("package-lock.json")||e.endsWith("npm-shrinkwrap.json"))return{packageManager:"npm",path:s(e)};if(e.endsWith("pnpm-lock.yaml"))return{packageManager:"pnpm",path:s(e)};if(e.endsWith("bun.lock")||e.endsWith("bun.lockb"))return{packageManager:"bun",path:s(e)};throw new f("Could not find a package manager")},N=async e=>{const n=await k(g,{type:"file",...e&&{cwd:e}});if(!n)throw new Error("Could not find lock file");return n},T=e=>{const n=h(g,{type:"file",...e&&{cwd:e}});if(!n)throw new Error("Could not find lock file");return n},U=async e=>{const n=await k(y,{...e&&{cwd:e}});return M(n)},q=e=>{const n=h(y,{...e&&{cwd:e}});return M(n)},B=e=>{if(!m.has(e))throw new Error(`Unsupported package manager "${e}". Expected one of: ${[...m].join(", ")}.`);return E(e,["--version"]).toString("utf8").trim()},D=()=>{if(!process.env.npm_config_user_agent)return;const e=process.env.npm_config_user_agent.split(" ")[0],n=e.lastIndexOf("/"),a=e.slice(0,Math.max(0,n));return{name:a==="npminstall"?"cnpm":a,version:e.slice(Math.max(0,n+1))}},L=(e,n,a)=>{const r=n.length===1?"":"s",l=a.packageManagers??["npm","pnpm","yarn"];if(l.length===0)throw new Error("No package managers provided, please provide at least one package manager");if(n.length===0)throw new Error("No missing packages provided, please provide at least one missing package");let c=`
1
+ import{createRequire as b}from"node:module";import{findUp as h,findUpSync as k}from"@visulima/fs";import{NotFoundError as f}from"@visulima/fs/error";import{parseJson as W}from"@visulima/fs/utils";import{join as p,dirname as s}from"@visulima/path";import{L as P}from"./packem_shared/lockfile-candidates-B-i5hlDs.js";let $;const E=e=>($??=b(import.meta.url))(e),o=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,m=e=>{if(typeof o<"u"&&o.versions&&o.versions.node){const[n,a]=o.versions.node.split(".").map(Number);if(n>22||n===22&&a>=3||n===20&&a>=16)return o.getBuiltinModule(e)}return E(e)},{execFileSync:S}=m("node:child_process"),{existsSync:l,readFileSync:x}=m("node:fs"),g=[...P],u=new Set(["bun","npm","pnpm","yarn"]),w=e=>{const n=W(x(e,"utf8"));return typeof n?.packageManager=="string"?n.packageManager:void 0},y=e=>{let n;if(g.forEach(r=>{!n&&l(p(e,r))&&(n=p(e,r))}),n)return n;const a=p(e,"package.json");if(l(a)&&w(a)!==void 0)return a},_=e=>{if(!e)throw new f("Could not find a package manager");if(e.endsWith("package.json")){const n=w(e);if(n){const a=["npm","yarn","pnpm","bun"].find(r=>n.startsWith(r));if(a)return{packageManager:a,path:s(e)}}}if(e.endsWith("yarn.lock"))return{packageManager:"yarn",path:s(e)};if(e.endsWith("package-lock.json")||e.endsWith("npm-shrinkwrap.json"))return{packageManager:"npm",path:s(e)};if(e.endsWith("pnpm-lock.yaml"))return{packageManager:"pnpm",path:s(e)};if(e.endsWith("bun.lock")||e.endsWith("bun.lockb"))return{packageManager:"bun",path:s(e)};throw new f("Could not find a package manager")},q=async e=>{const n=await h(g,{type:"file",...e&&{cwd:e}});if(!n)throw new Error("Could not find lock file");return n},D=e=>{const n=k(g,{type:"file",...e&&{cwd:e}});if(!n)throw new Error("Could not find lock file");return n},U=async e=>{const n=await h(y,{...e&&{cwd:e}});return _(n)},O=e=>{const n=k(y,{...e&&{cwd:e}});return _(n)},R=e=>{if(!u.has(e))throw new Error(`Unsupported package manager "${e}". Expected one of: ${[...u].join(", ")}.`);return S(e,["--version"]).toString("utf8").trim()},A=()=>{if(!process.env.npm_config_user_agent)return;const e=process.env.npm_config_user_agent.split(" ")[0],n=e.lastIndexOf("/"),a=e.slice(0,Math.max(0,n));return{name:a==="npminstall"?"cnpm":a,version:e.slice(Math.max(0,n+1))}},B=(e,n,a)=>{const r=n.length===1?"":"s",d=a.packageManagers??["npm","pnpm","yarn"];if(d.length===0)throw new Error("No package managers provided, please provide at least one package manager");if(n.length===0)throw new Error("No missing packages provided, please provide at least one missing package");let c=`
2
2
  ${a.preMessage??""}
3
3
  ${e} could not find the following package${r}
4
4
 
@@ -6,8 +6,8 @@ ${e} could not find the following package${r}
6
6
  `)}
7
7
 
8
8
  To install the missing package${r}, please run the following command:
9
- `;const _=o=>o.lastIndexOf("@")>0?o:`${o}@latest`,j=l.map(o=>{const i=n.map(v=>_(v)).join(" ");switch(o){case"bun":return` bun add ${i} -D`;case"npm":return` npm install ${i} --save-dev`;case"pnpm":return` pnpm add ${i} -D`;case"yarn":return` yarn add ${i} --dev`;default:throw new Error("Unknown package manager")}});return c+=j.join(`
9
+ `;const M=t=>t.lastIndexOf("@")>0?t:`${t}@latest`,v=d.map(t=>{const i=n.map(j=>M(j)).join(" ");switch(t){case"bun":return` bun add ${i} -D`;case"npm":return` npm install ${i} --save-dev`;case"pnpm":return` pnpm add ${i} -D`;case"yarn":return` yarn add ${i} --dev`;default:throw new Error("Unknown package manager")}});return c+=v.join(`
10
10
 
11
11
  or
12
12
 
13
- `),a.postMessage&&(c+=a.postMessage),c};export{N as findLockFile,T as findLockFileSync,U as findPackageManager,q as findPackageManagerSync,L as generateMissingPackagesInstallMessage,B as getPackageManagerVersion,D as identifyInitiatingPackageManager};
13
+ `),a.postMessage&&(c+=a.postMessage),c};export{q as findLockFile,D as findLockFileSync,U as findPackageManager,O as findPackageManagerSync,B as generateMissingPackagesInstallMessage,R as getPackageManagerVersion,A as identifyInitiatingPackageManager};
package/dist/package.d.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  /**
2
- * An asynchronous function that finds the root directory of a project based on certain lookup criteria.
3
- * @param cwd Optional. The current working directory to start the search from. The type of `cwd` is `string`.
4
- * @returns A `Promise` that resolves to the path of the root directory. The type of the returned promise is `Promise&lt;string>`.
5
- * @throws An `Error` if the root directory could not be found.
6
- * @example
7
- * const rootDirectory = await findPackageRoot();
8
- * console.log(rootDirectory); // '/path/to/project'
9
- */
2
+ * An asynchronous function that finds the root directory of a project based on certain lookup criteria.
3
+ * @param cwd Optional. The current working directory to start the search from. The type of `cwd` is `string`.
4
+ * @returns A `Promise` that resolves to the path of the root directory. The type of the returned promise is `Promise&lt;string>`.
5
+ * @throws An `Error` if the root directory could not be found.
6
+ * @example
7
+ * const rootDirectory = await findPackageRoot();
8
+ * console.log(rootDirectory); // '/path/to/project'
9
+ */
10
10
  declare const findPackageRoot: (cwd?: URL | string) => Promise<string>;
11
11
  declare const findPackageRootSync: (cwd?: URL | string) => string;
12
12
  export { findPackageRoot, findPackageRootSync };
package/dist/package.js CHANGED
@@ -1 +1 @@
1
- import{createRequire as d}from"node:module";import{findUp as c,findUpSync as s,readJsonSync as y}from"@visulima/fs";import{dirname as r,join as f}from"@visulima/path";import{findLockFile as g,findLockFileSync as m}from"./package-manager.js";const p=d(import.meta.url),i=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,u=e=>{if(typeof i<"u"&&i.versions&&i.versions.node){const[o,t]=i.versions.node.split(".").map(Number);if(o>22||o===22&&t>=3||o===20&&t>=16)return i.getBuiltinModule(e)}return p(e)},{existsSync:l}=u("node:fs"),a=e=>{if(l(f(e,"package.json"))){const o=y(f(e,"package.json"));if(o.name&&o.private!==!0)return"package.json"}},k=async e=>{try{const n=await g(e);return r(n)}catch{}const o=await c(".git/config",{...e&&{cwd:e},type:"file"});if(o)return r(r(o));const t=await c(a,{...e&&{cwd:e},type:"file"});if(t)return r(t);throw new Error("Could not find root directory")},S=e=>{try{const n=m(e);return r(n)}catch{}const o=s(".git/config",{...e&&{cwd:e},type:"file"});if(o)return r(r(o));const t=s(a,{...e&&{cwd:e},type:"file"});if(t)return r(t);throw new Error("Could not find root directory")};export{k as findPackageRoot,S as findPackageRootSync};
1
+ import{createRequire as d}from"node:module";import{findUp as c,findUpSync as s,readJsonSync as g}from"@visulima/fs";import{dirname as r,join as a}from"@visulima/path";import{findLockFile as m,findLockFileSync as _}from"./package-manager.js";let u;const p=e=>(u??=d(import.meta.url))(e),i=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,l=e=>{if(typeof i<"u"&&i.versions&&i.versions.node){const[t,o]=i.versions.node.split(".").map(Number);if(t>22||t===22&&o>=3||t===20&&o>=16)return i.getBuiltinModule(e)}return p(e)},{existsSync:y}=l("node:fs"),f=e=>{if(y(a(e,"package.json"))){const t=g(a(e,"package.json"));if(t.name&&t.private!==!0)return"package.json"}},R=async e=>{try{const n=await m(e);return r(n)}catch{}const t=await c(".git/config",{...e&&{cwd:e},type:"file"});if(t)return r(r(t));const o=await c(f,{...e&&{cwd:e},type:"file"});if(o)return r(o);throw new Error("Could not find root directory")},S=e=>{try{const n=_(e);return r(n)}catch{}const t=s(".git/config",{...e&&{cwd:e},type:"file"});if(t)return r(r(t));const o=s(f,{...e&&{cwd:e},type:"file"});if(o)return r(o);throw new Error("Could not find root directory")};export{R as findPackageRoot,S as findPackageRootSync};
@@ -0,0 +1 @@
1
+ const n=["pnpm-lock.yaml","package-lock.json","npm-shrinkwrap.json","yarn.lock","bun.lock","bun.lockb"];export{n as L};
@@ -0,0 +1,186 @@
1
+ import { WriteJsonOptions } from '@visulima/fs';
2
+ import { PackageJson as PackageJson$1, Paths, JsonObject } from 'type-fest';
3
+ import { InstallPackageOptions } from '@antfu/install-pkg';
4
+ import { Theme } from '@inquirer/core';
5
+ import { PartialDeep } from '@inquirer/type';
6
+ import { Package } from 'normalize-package-data';
7
+ type NormalizedPackageJson = Package & PackageJson;
8
+ type PackageJson = PackageJson$1;
9
+ type Cache<T = unknown> = Map<string, T>;
10
+ type EnsurePackagesOptions = {
11
+ /** Configuration for user confirmation prompts when installing packages */
12
+ confirm?: {
13
+ /** Default value for the confirmation prompt */
14
+ default?: boolean;
15
+ /** Message to display in the confirmation prompt, or a function that receives packages array */
16
+ message: string | ((packages: string[]) => string);
17
+ /**
18
+ * Theme configuration for the prompt interface.
19
+ * @deprecated Not implemented — the readline-based prompt ignores this option and uses
20
+ * fixed styling. It will be removed in a future major release.
21
+ */
22
+ theme?: PartialDeep<Theme>;
23
+ /** Function to transform the boolean value for display */
24
+ transformer?: (value: boolean) => string;
25
+ };
26
+ /** Current working directory for package operations */
27
+ cwd?: URL | string;
28
+ /** Whether to include regular dependencies in the operation */
29
+ deps?: boolean;
30
+ /** Whether to include development dependencies in the operation */
31
+ devDeps?: boolean;
32
+ /** Additional options for package installation (excluding cwd and dev which are handled separately) */
33
+ installPackage?: Omit<InstallPackageOptions, "cwd" | "dev">;
34
+ /** Custom logger interface for warning messages */
35
+ logger?: {
36
+ warn: (message: string) => void;
37
+ };
38
+ /** Whether to include peer dependencies in the operation */
39
+ peerDeps?: boolean;
40
+ /** Whether to throw an error when warnings are logged instead of just logging them */
41
+ throwOnWarn?: boolean;
42
+ };
43
+ type ReadOptions = {
44
+ cache?: FindPackageJsonCache | boolean;
45
+ ignoreWarnings?: (RegExp | string)[];
46
+ json5?: boolean;
47
+ resolveCatalogs?: boolean;
48
+ strict?: boolean;
49
+ yaml?: boolean;
50
+ };
51
+ type FindPackageJsonCache = Cache<NormalizedReadResult>;
52
+ type NormalizedReadResult = {
53
+ packageJson: NormalizedPackageJson;
54
+ path: string;
55
+ };
56
+ /**
57
+ * An asynchronous function to find the package.json, package.yaml, or package.json5 file in the specified directory or its parent directories.
58
+ * @param cwd The current working directory.
59
+ * @param options Configuration options including yaml, json5, and resolveCatalogs flags.
60
+ * @returns A `Promise` that resolves to an object containing the parsed package data and the file path.
61
+ * The type of the returned promise is `Promise&lt;NormalizedReadResult>`.
62
+ * @throws {Error} If no package file can be found or if strict mode is enabled and normalize warnings are thrown.
63
+ */
64
+ declare const findPackageJson: (cwd?: URL | string, options?: ReadOptions) => Promise<NormalizedReadResult>;
65
+ /**
66
+ * A synchronous function to find the package.json, package.yaml, or package.json5 file in the specified directory or its parent directories.
67
+ * @param cwd The current working directory.
68
+ * @param options Configuration options including yaml, json5, and resolveCatalogs flags.
69
+ * @returns An object containing the parsed package data and the file path.
70
+ * @throws {Error} If no package file can be found or if strict mode is enabled and normalize warnings are thrown.
71
+ */
72
+ declare const findPackageJsonSync: (cwd?: URL | string, options?: ReadOptions) => NormalizedReadResult;
73
+ /**
74
+ * An asynchronous function to write the package.json file with the given data.
75
+ * @param data The package.json data to write. The data is an intersection type of `PackageJson` and a record where keys are `string` and values can be any type.
76
+ * @param options Optional. The options for writing the package.json. If not provided, an empty object will be used `{}`.
77
+ * This is an intersection type of `WriteJsonOptions` and a record with an optional `cwd` key which type is `Options["cwd"]`.
78
+ * `cwd` represents the current working directory. If not specified, the default working directory will be used.
79
+ * @returns A `Promise` that resolves once the package.json file has been written. The type of the returned promise is `Promise&lt;void>`.
80
+ */
81
+ declare const writePackageJson: (data: PackageJson, options?: WriteJsonOptions & {
82
+ cwd?: URL | string;
83
+ }) => Promise<void>;
84
+ declare const writePackageJsonSync: (data: PackageJson, options?: WriteJsonOptions & {
85
+ cwd?: URL | string;
86
+ }) => void;
87
+ /**
88
+ * Clears the module-level package.json file and parse caches.
89
+ *
90
+ * The caches populated by `findPackageJson[Sync]` / `parsePackageJson[Sync]` when
91
+ * `cache: true` (and no custom cache is supplied) never expire on their own. Call this
92
+ * to drop all cached reads — for example in long-running processes or tests that mutate
93
+ * package files out of band.
94
+ */
95
+ declare const clearPackageJsonCache: () => void;
96
+ /**
97
+ * A synchronous function to parse the package.json, package.yaml, or package.json5 file/object/string and return normalize the data.
98
+ * @param packageFile
99
+ * @param options
100
+ * @param options.cache Cache for parsed results (only applies to file paths)
101
+ * @param options.ignoreWarnings List of warning messages or patterns to skip in strict mode
102
+ * @param options.resolveCatalogs Whether to resolve pnpm catalog references
103
+ * @param options.strict Whether to throw errors on normalization warnings
104
+ * @param options.yaml Whether to enable package.yaml parsing (default: true)
105
+ * @param options.json5 Whether to enable package.json5 parsing (default: true)
106
+ * @returns
107
+ * @throws {Error} If the packageFile parameter is not an object or a string or if strict mode is enabled and normalize warnings are thrown.
108
+ */
109
+ declare const parsePackageJsonSync: (packageFile: JsonObject | string, options?: {
110
+ cache?: Cache<NormalizedPackageJson> | boolean;
111
+ ignoreWarnings?: (RegExp | string)[];
112
+ json5?: boolean;
113
+ resolveCatalogs?: boolean;
114
+ strict?: boolean;
115
+ yaml?: boolean;
116
+ }) => NormalizedPackageJson;
117
+ /**
118
+ * An asynchronous function to parse the package.json, package.yaml, or package.json5 file/object/string and return normalize the data.
119
+ * @param packageFile
120
+ * @param options
121
+ * @param options.cache Cache for parsed results (only applies to file paths)
122
+ * @param options.ignoreWarnings List of warning messages or patterns to skip in strict mode
123
+ * @param options.strict Whether to throw errors on normalization warnings
124
+ * @param options.resolveCatalogs Whether to resolve pnpm catalog references
125
+ * @param options.yaml Whether to enable package.yaml parsing (default: true)
126
+ * @param options.json5 Whether to enable package.json5 parsing (default: true)
127
+ * @returns
128
+ * @throws {Error} If the packageFile parameter is not an object or a string or if strict mode is enabled and normalize warnings are thrown.
129
+ */
130
+ declare const parsePackageJson: (packageFile: JsonObject | string, options?: {
131
+ cache?: Cache<NormalizedPackageJson> | boolean;
132
+ ignoreWarnings?: (RegExp | string)[];
133
+ json5?: boolean;
134
+ resolveCatalogs?: boolean;
135
+ strict?: boolean;
136
+ yaml?: boolean;
137
+ }) => Promise<NormalizedPackageJson>;
138
+ /**
139
+ * An asynchronous function to get the value of a property from the package.json file.
140
+ * @param packageJson
141
+ * @param property
142
+ * @param defaultValue
143
+ * @returns
144
+ */
145
+ declare const getPackageJsonProperty: <T = unknown>(packageJson: NormalizedPackageJson, property: Paths<NormalizedPackageJson>, defaultValue?: T) => T;
146
+ /**
147
+ * An asynchronous function to check if a property exists in the package.json file.
148
+ * @param packageJson
149
+ * @param property
150
+ * @returns
151
+ */
152
+ declare const hasPackageJsonProperty: (packageJson: NormalizedPackageJson, property: Paths<NormalizedPackageJson>) => boolean;
153
+ /**
154
+ * An asynchronous function to check if any of the specified dependencies exist in the package.json file.
155
+ * @param packageJson
156
+ * @param arguments_
157
+ * @param options
158
+ * @param options.peerDeps Whether to include peer dependencies
159
+ * @returns
160
+ */
161
+ declare const hasPackageJsonAnyDependency: (packageJson: NormalizedPackageJson, arguments_: string[], options?: {
162
+ peerDeps?: boolean;
163
+ }) => boolean;
164
+ /**
165
+ * An asynchronous function to ensure that the specified packages are installed in the package.json file.
166
+ * If the packages are not installed, the user will be prompted to install them.
167
+ * If the user agrees, the packages will be installed.
168
+ * If the user declines, the function will return without installing the packages.
169
+ * If the user does not respond, the function will return without installing the packages.
170
+ * @param packageJson
171
+ * @param packages
172
+ * @param installKey
173
+ * @param options
174
+ * @param options.deps Whether to include regular dependencies
175
+ * @param options.devDeps Whether to include development dependencies
176
+ * @param options.peerDeps Whether to include peer dependencies
177
+ * @param options.throwOnWarn Whether to throw an error when warnings are logged instead of just logging them
178
+ * @param options.logger Whether to use a custom logger
179
+ * @param options.confirm Whether to use a custom confirmation prompt
180
+ * @param options.installPackage Whether to use a custom installation package
181
+ * @param options.cwd Whether to use a custom current working directory
182
+ * @param options.dev Whether to use a custom installation key
183
+ * @returns
184
+ */
185
+ declare const ensurePackages: (packageJson: NormalizedPackageJson, packages: string[], installKey?: "dependencies" | "devDependencies", options?: EnsurePackagesOptions) => Promise<void>;
186
+ export { EnsurePackagesOptions as E, FindPackageJsonCache as F, NormalizedPackageJson as N, PackageJson as P, NormalizedReadResult as a, findPackageJsonSync as b, clearPackageJsonCache as c, hasPackageJsonProperty as d, ensurePackages as e, findPackageJson as f, getPackageJsonProperty as g, hasPackageJsonAnyDependency as h, parsePackageJsonSync as i, writePackageJsonSync as j, parsePackageJson as p, writePackageJson as w };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@visulima/package",
3
- "version": "5.0.9",
3
+ "version": "5.0.11",
4
4
  "description": "A comprehensive package management utility that helps you find root directories, monorepos, package managers, and parse package.json, package.yaml, and package.json5 files with advanced features like catalog resolution.",
5
5
  "keywords": [
6
6
  "anolilab",
@@ -109,8 +109,8 @@
109
109
  },
110
110
  "dependencies": {
111
111
  "@antfu/install-pkg": "^1.1.0",
112
- "@visulima/fs": "5.0.10",
113
- "@visulima/path": "3.0.0",
112
+ "@visulima/fs": "5.1.0",
113
+ "@visulima/path": "3.1.0",
114
114
  "json5": "^2.2.3",
115
115
  "normalize-package-data": "^9.0.0",
116
116
  "yaml": "2.9.0"
@@ -1,182 +0,0 @@
1
- import { WriteJsonOptions } from '@visulima/fs';
2
- import { PackageJson as PackageJson$1, Paths, JsonObject } from 'type-fest';
3
- import { InstallPackageOptions } from '@antfu/install-pkg';
4
- import { Theme } from '@inquirer/core';
5
- import { PartialDeep } from '@inquirer/type';
6
- import { Package } from 'normalize-package-data';
7
- type NormalizedPackageJson = Package & PackageJson;
8
- type PackageJson = PackageJson$1;
9
- type Cache<T = unknown> = Map<string, T>;
10
- type EnsurePackagesOptions = {
11
- /** Configuration for user confirmation prompts when installing packages */
12
- confirm?: {
13
- /** Default value for the confirmation prompt */
14
- default?: boolean;
15
- /** Message to display in the confirmation prompt, or a function that receives packages array */
16
- message: string | ((packages: string[]) => string);
17
- /** Theme configuration for the prompt interface */
18
- theme?: PartialDeep<Theme>;
19
- /** Function to transform the boolean value for display */
20
- transformer?: (value: boolean) => string;
21
- };
22
- /** Current working directory for package operations */
23
- cwd?: URL | string;
24
- /** Whether to include regular dependencies in the operation */
25
- deps?: boolean;
26
- /** Whether to include development dependencies in the operation */
27
- devDeps?: boolean;
28
- /** Additional options for package installation (excluding cwd and dev which are handled separately) */
29
- installPackage?: Omit<InstallPackageOptions, "cwd" | "dev">;
30
- /** Custom logger interface for warning messages */
31
- logger?: {
32
- warn: (message: string) => void;
33
- };
34
- /** Whether to include peer dependencies in the operation */
35
- peerDeps?: boolean;
36
- /** Whether to throw an error when warnings are logged instead of just logging them */
37
- throwOnWarn?: boolean;
38
- };
39
- type ReadOptions = {
40
- cache?: FindPackageJsonCache | boolean;
41
- ignoreWarnings?: (RegExp | string)[];
42
- json5?: boolean;
43
- resolveCatalogs?: boolean;
44
- strict?: boolean;
45
- yaml?: boolean;
46
- };
47
- type FindPackageJsonCache = Cache<NormalizedReadResult>;
48
- type NormalizedReadResult = {
49
- packageJson: NormalizedPackageJson;
50
- path: string;
51
- };
52
- /**
53
- * An asynchronous function to find the package.json, package.yaml, or package.json5 file in the specified directory or its parent directories.
54
- * @param cwd The current working directory.
55
- * @param options Configuration options including yaml, json5, and resolveCatalogs flags.
56
- * @returns A `Promise` that resolves to an object containing the parsed package data and the file path.
57
- * The type of the returned promise is `Promise&lt;NormalizedReadResult>`.
58
- * @throws {Error} If no package file can be found or if strict mode is enabled and normalize warnings are thrown.
59
- */
60
- declare const findPackageJson: (cwd?: URL | string, options?: ReadOptions) => Promise<NormalizedReadResult>;
61
- /**
62
- * A synchronous function to find the package.json, package.yaml, or package.json5 file in the specified directory or its parent directories.
63
- * @param cwd The current working directory.
64
- * @param options Configuration options including yaml, json5, and resolveCatalogs flags.
65
- * @returns An object containing the parsed package data and the file path.
66
- * @throws {Error} If no package file can be found or if strict mode is enabled and normalize warnings are thrown.
67
- */
68
- declare const findPackageJsonSync: (cwd?: URL | string, options?: ReadOptions) => NormalizedReadResult;
69
- /**
70
- * An asynchronous function to write the package.json file with the given data.
71
- * @param data The package.json data to write. The data is an intersection type of `PackageJson` and a record where keys are `string` and values can be any type.
72
- * @param options Optional. The options for writing the package.json. If not provided, an empty object will be used `{}`.
73
- * This is an intersection type of `WriteJsonOptions` and a record with an optional `cwd` key which type is `Options["cwd"]`.
74
- * `cwd` represents the current working directory. If not specified, the default working directory will be used.
75
- * @returns A `Promise` that resolves once the package.json file has been written. The type of the returned promise is `Promise&lt;void>`.
76
- */
77
- declare const writePackageJson: (data: PackageJson, options?: WriteJsonOptions & {
78
- cwd?: URL | string;
79
- }) => Promise<void>;
80
- declare const writePackageJsonSync: (data: PackageJson, options?: WriteJsonOptions & {
81
- cwd?: URL | string;
82
- }) => void;
83
- /**
84
- * Clears the module-level package.json file and parse caches.
85
- *
86
- * The caches populated by `findPackageJson[Sync]` / `parsePackageJson[Sync]` when
87
- * `cache: true` (and no custom cache is supplied) never expire on their own. Call this
88
- * to drop all cached reads — for example in long-running processes or tests that mutate
89
- * package files out of band.
90
- */
91
- declare const clearPackageJsonCache: () => void;
92
- /**
93
- * A synchronous function to parse the package.json, package.yaml, or package.json5 file/object/string and return normalize the data.
94
- * @param packageFile
95
- * @param options
96
- * @param options.cache Cache for parsed results (only applies to file paths)
97
- * @param options.ignoreWarnings List of warning messages or patterns to skip in strict mode
98
- * @param options.resolveCatalogs Whether to resolve pnpm catalog references
99
- * @param options.strict Whether to throw errors on normalization warnings
100
- * @param options.yaml Whether to enable package.yaml parsing (default: true)
101
- * @param options.json5 Whether to enable package.json5 parsing (default: true)
102
- * @returns
103
- * @throws {Error} If the packageFile parameter is not an object or a string or if strict mode is enabled and normalize warnings are thrown.
104
- */
105
- declare const parsePackageJsonSync: (packageFile: JsonObject | string, options?: {
106
- cache?: Cache<NormalizedPackageJson> | boolean;
107
- ignoreWarnings?: (RegExp | string)[];
108
- json5?: boolean;
109
- resolveCatalogs?: boolean;
110
- strict?: boolean;
111
- yaml?: boolean;
112
- }) => NormalizedPackageJson;
113
- /**
114
- * An asynchronous function to parse the package.json, package.yaml, or package.json5 file/object/string and return normalize the data.
115
- * @param packageFile
116
- * @param options
117
- * @param options.cache Cache for parsed results (only applies to file paths)
118
- * @param options.ignoreWarnings List of warning messages or patterns to skip in strict mode
119
- * @param options.strict Whether to throw errors on normalization warnings
120
- * @param options.resolveCatalogs Whether to resolve pnpm catalog references
121
- * @param options.yaml Whether to enable package.yaml parsing (default: true)
122
- * @param options.json5 Whether to enable package.json5 parsing (default: true)
123
- * @returns
124
- * @throws {Error} If the packageFile parameter is not an object or a string or if strict mode is enabled and normalize warnings are thrown.
125
- */
126
- declare const parsePackageJson: (packageFile: JsonObject | string, options?: {
127
- cache?: Cache<NormalizedPackageJson> | boolean;
128
- ignoreWarnings?: (RegExp | string)[];
129
- json5?: boolean;
130
- resolveCatalogs?: boolean;
131
- strict?: boolean;
132
- yaml?: boolean;
133
- }) => Promise<NormalizedPackageJson>;
134
- /**
135
- * An asynchronous function to get the value of a property from the package.json file.
136
- * @param packageJson
137
- * @param property
138
- * @param defaultValue
139
- * @returns
140
- */
141
- declare const getPackageJsonProperty: <T = unknown>(packageJson: NormalizedPackageJson, property: Paths<NormalizedPackageJson>, defaultValue?: T) => T;
142
- /**
143
- * An asynchronous function to check if a property exists in the package.json file.
144
- * @param packageJson
145
- * @param property
146
- * @returns
147
- */
148
- declare const hasPackageJsonProperty: (packageJson: NormalizedPackageJson, property: Paths<NormalizedPackageJson>) => boolean;
149
- /**
150
- * An asynchronous function to check if any of the specified dependencies exist in the package.json file.
151
- * @param packageJson
152
- * @param arguments_
153
- * @param options
154
- * @param options.peerDeps Whether to include peer dependencies
155
- * @returns
156
- */
157
- declare const hasPackageJsonAnyDependency: (packageJson: NormalizedPackageJson, arguments_: string[], options?: {
158
- peerDeps?: boolean;
159
- }) => boolean;
160
- /**
161
- * An asynchronous function to ensure that the specified packages are installed in the package.json file.
162
- * If the packages are not installed, the user will be prompted to install them.
163
- * If the user agrees, the packages will be installed.
164
- * If the user declines, the function will return without installing the packages.
165
- * If the user does not respond, the function will return without installing the packages.
166
- * @param packageJson
167
- * @param packages
168
- * @param installKey
169
- * @param options
170
- * @param options.deps Whether to include regular dependencies
171
- * @param options.devDeps Whether to include development dependencies
172
- * @param options.peerDeps Whether to include peer dependencies
173
- * @param options.throwOnWarn Whether to throw an error when warnings are logged instead of just logging them
174
- * @param options.logger Whether to use a custom logger
175
- * @param options.confirm Whether to use a custom confirmation prompt
176
- * @param options.installPackage Whether to use a custom installation package
177
- * @param options.cwd Whether to use a custom current working directory
178
- * @param options.dev Whether to use a custom installation key
179
- * @returns
180
- */
181
- declare const ensurePackages: (packageJson: NormalizedPackageJson, packages: string[], installKey?: "dependencies" | "devDependencies", options?: EnsurePackagesOptions) => Promise<void>;
182
- export { EnsurePackagesOptions as E, FindPackageJsonCache as F, NormalizedPackageJson as N, PackageJson as P, NormalizedReadResult as a, findPackageJsonSync as b, clearPackageJsonCache as c, hasPackageJsonProperty as d, ensurePackages as e, findPackageJson as f, getPackageJsonProperty as g, hasPackageJsonAnyDependency as h, parsePackageJsonSync as i, writePackageJsonSync as j, parsePackageJson as p, writePackageJson as w };