@visulima/package 5.0.0-alpha.30 → 5.0.0-alpha.32
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 +49 -0
- package/README.md +138 -0
- package/dist/error.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/lockfile.d.ts +8 -2
- package/dist/lockfile.js +1 -1
- package/dist/monorepo.js +1 -1
- package/dist/package-json.d.ts +1 -1
- package/dist/package-json.js +4 -4
- package/dist/package-manager.d.ts +3 -1
- package/dist/package-manager.js +5 -5
- package/dist/package.js +1 -1
- package/dist/packem_shared/PackageNotFoundError-Bi41exhP.js +1 -0
- package/dist/packem_shared/{package-json.d-R9WIRfmM.d.ts → package-json.d-BHWsl_Em.d.ts} +10 -1
- package/dist/pnpm.js +1 -1
- package/package.json +3 -3
- package/dist/packem_shared/PackageNotFoundError--qHnCLzN.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,52 @@
|
|
|
1
|
+
## @visulima/package [5.0.0-alpha.32](https://github.com/visulima/visulima/compare/@visulima/package@5.0.0-alpha.31...@visulima/package@5.0.0-alpha.32) (2026-06-30)
|
|
2
|
+
|
|
3
|
+
### Styles
|
|
4
|
+
|
|
5
|
+
* cs fixes ([2a960bb](https://github.com/visulima/visulima/commit/2a960bb1772c9dc70080e2d75d3a0d827034e294))
|
|
6
|
+
|
|
7
|
+
### Miscellaneous Chores
|
|
8
|
+
|
|
9
|
+
* add fallow code-intelligence across all packages ([a3b4821](https://github.com/visulima/visulima/commit/a3b48215002e86fed20f2973038b5d4a0aa1ce04))
|
|
10
|
+
* **fallow:** resolve dead-code findings ([c4125d5](https://github.com/visulima/visulima/commit/c4125d53e03ac9d90115399634535991927a96cc))
|
|
11
|
+
|
|
12
|
+
### Tests
|
|
13
|
+
|
|
14
|
+
* **package:** skip JSON-content-vs-file collision tests on Windows ([5c2d2f1](https://github.com/visulima/visulima/commit/5c2d2f15a4e0b8bf2dad70251c402d1b3fe19796))
|
|
15
|
+
|
|
16
|
+
### Continuous Integration
|
|
17
|
+
|
|
18
|
+
* **fallow:** make fallow:health advisory (--report-only) ([d57148e](https://github.com/visulima/visulima/commit/d57148ea0e3556b4c24d8d336b9fa14987f5dc7d))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Dependencies
|
|
22
|
+
|
|
23
|
+
* **@visulima/fs:** upgraded to 5.0.0-alpha.33
|
|
24
|
+
|
|
25
|
+
## @visulima/package [5.0.0-alpha.31](https://github.com/visulima/visulima/compare/@visulima/package@5.0.0-alpha.30...@visulima/package@5.0.0-alpha.31) (2026-06-13)
|
|
26
|
+
|
|
27
|
+
### Features
|
|
28
|
+
|
|
29
|
+
* **package:** recognise the modern bun.lock text lockfile ([8fec531](https://github.com/visulima/visulima/commit/8fec531a20c32857de93c801d4b42e0eff32c6a8))
|
|
30
|
+
|
|
31
|
+
### Bug Fixes
|
|
32
|
+
|
|
33
|
+
* **package:** replace unsafe type cast with String() coercions ([4c85a5e](https://github.com/visulima/visulima/commit/4c85a5e3fdeb194a0a2bbcee24b85ee23697d3ea))
|
|
34
|
+
* **package:** resolve caching and ReDoS findings ([fb9e5cb](https://github.com/visulima/visulima/commit/fb9e5cb0fbb5fad2078750464845c6b223e0afc5))
|
|
35
|
+
|
|
36
|
+
### Tests
|
|
37
|
+
|
|
38
|
+
* **package:** stop partial process stub leaking across ensurePackages tests ([7059537](https://github.com/visulima/visulima/commit/705953754fe0a64612de06ff1140a9e744b25bfe))
|
|
39
|
+
|
|
40
|
+
### Build System
|
|
41
|
+
|
|
42
|
+
* regenerate bundled-license manifests and types ordering ([af26588](https://github.com/visulima/visulima/commit/af26588d75aaa937fd4862800560bd4070a4878c))
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
### Dependencies
|
|
46
|
+
|
|
47
|
+
* **@visulima/fs:** upgraded to 5.0.0-alpha.32
|
|
48
|
+
* **@visulima/path:** upgraded to 3.0.0-alpha.13
|
|
49
|
+
|
|
1
50
|
## @visulima/package [5.0.0-alpha.30](https://github.com/visulima/visulima/compare/@visulima/package@5.0.0-alpha.29...@visulima/package@5.0.0-alpha.30) (2026-06-04)
|
|
2
51
|
|
|
3
52
|
|
package/README.md
CHANGED
|
@@ -155,6 +155,41 @@ const version = await getPackageManagerVersion("pnpm");
|
|
|
155
155
|
// => '8.15.0'
|
|
156
156
|
```
|
|
157
157
|
|
|
158
|
+
> `getPackageManagerVersion` only accepts the known managers (`npm`, `pnpm`, `yarn`, `bun`) and throws on anything else, so a `packageManager`-derived value from an untrusted repo can't be executed as an arbitrary binary.
|
|
159
|
+
|
|
160
|
+
#### identifyInitiatingPackageManager
|
|
161
|
+
|
|
162
|
+
Detects which package manager is currently executing the process by reading the `npm_config_user_agent` environment variable. Useful inside `postinstall`/`prepare` scripts to print the right install command. Returns `undefined` when the variable is not set.
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
import { identifyInitiatingPackageManager } from "@visulima/package";
|
|
166
|
+
|
|
167
|
+
const pm = identifyInitiatingPackageManager();
|
|
168
|
+
// => { name: 'pnpm', version: '8.15.0' } | { name: 'cnpm', ... } | undefined
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
#### generateMissingPackagesInstallMessage
|
|
172
|
+
|
|
173
|
+
Builds a human-readable message instructing the user how to install missing packages with each requested package manager.
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
import { generateMissingPackagesInstallMessage } from "@visulima/package";
|
|
177
|
+
|
|
178
|
+
const message = generateMissingPackagesInstallMessage("my-tool", ["typescript", "@types/node"], {
|
|
179
|
+
packageManagers: ["npm", "pnpm", "yarn"], // default: ["npm", "pnpm", "yarn"]
|
|
180
|
+
preMessage: "Some optional dependencies are missing.\n",
|
|
181
|
+
postMessage: "\nSee the docs for details.",
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
console.log(message);
|
|
185
|
+
// my-tool could not find the following packages
|
|
186
|
+
// typescript
|
|
187
|
+
// @types/node
|
|
188
|
+
// To install the missing packages, please run the following command:
|
|
189
|
+
// npm install typescript@latest @types/node@latest --save-dev
|
|
190
|
+
// ...
|
|
191
|
+
```
|
|
192
|
+
|
|
158
193
|
### Package.json Operations
|
|
159
194
|
|
|
160
195
|
#### parsePackageJson
|
|
@@ -218,6 +253,14 @@ const result3 = await parsePackageJson("./package.json", { cache: myCache }); //
|
|
|
218
253
|
const result4 = await parsePackageJson({ name: "test" }, { cache: true }); // Always parsed fresh
|
|
219
254
|
```
|
|
220
255
|
|
|
256
|
+
The module-level cache used when `cache: true` (and no custom cache is supplied) never expires on its own. Writing through `writePackageJson[Sync]` evicts the written path automatically, but if you mutate a package file out of band (e.g. in a long-running process or test), call `clearPackageJsonCache()` to drop all cached reads:
|
|
257
|
+
|
|
258
|
+
```typescript
|
|
259
|
+
import { clearPackageJsonCache } from "@visulima/package";
|
|
260
|
+
|
|
261
|
+
clearPackageJsonCache();
|
|
262
|
+
```
|
|
263
|
+
|
|
221
264
|
**Example File Formats**:
|
|
222
265
|
|
|
223
266
|
```yaml
|
|
@@ -335,6 +378,101 @@ import { ensurePackages } from "@visulima/package";
|
|
|
335
378
|
await ensurePackages(packageJson, ["typescript", "@types/node"], "devDependencies");
|
|
336
379
|
```
|
|
337
380
|
|
|
381
|
+
### Lockfile Parsing
|
|
382
|
+
|
|
383
|
+
A regex-based lockfile parser (no YAML dependency) covering all four mainstream JS package managers. Each entry is normalized to `{ name, version, integrity?, dependencies?, peerDependencies?, optionalDependencies? }`, so callers can build SBOMs, dedupe reports, or any other lockfile-derived artifact from a single source of truth.
|
|
384
|
+
|
|
385
|
+
Integrity support:
|
|
386
|
+
|
|
387
|
+
- **npm** (`package-lock.json` v2/v3): `integrity: "sha512-…"` ✅
|
|
388
|
+
- **pnpm** (`pnpm-lock.yaml`): `resolution: { integrity: "sha512-…" }` ✅
|
|
389
|
+
- **yarn v1** (Classic): `integrity "sha512-…"` ✅
|
|
390
|
+
- **yarn v2+** (Berry): emits `checksum: 10c0/…` (XXH64), which is not a cryptographic hash and is outside the CycloneDX 1.6 `HashAlgorithm` enum. Berry entries are still parsed (name / version / dependencies), but `integrity` is `undefined`.
|
|
391
|
+
- **bun** (`bun.lock`): `[versionKey, registryUrl, metadata, integrity]` tuples ✅
|
|
392
|
+
|
|
393
|
+
#### parseLockFile
|
|
394
|
+
|
|
395
|
+
Walks up from `cwd`, locates the nearest supported lockfile, reads it, and returns the parsed entries alongside the lockfile type and absolute path.
|
|
396
|
+
|
|
397
|
+
```typescript
|
|
398
|
+
import { parseLockFile, parseLockFileSync } from "@visulima/package";
|
|
399
|
+
|
|
400
|
+
const result = await parseLockFile();
|
|
401
|
+
// => { entries: [{ name: 'react', version: '18.2.0', integrity: { algorithm: 'sha512', hex: '…' } }, …], path: '/path/to/pnpm-lock.yaml', type: 'pnpm' }
|
|
402
|
+
|
|
403
|
+
// Synchronous version
|
|
404
|
+
const resultSync = parseLockFileSync("./some/dir");
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
#### Per-package-manager parsers
|
|
408
|
+
|
|
409
|
+
When you already have the lockfile contents (and know the format), call a specific parser directly. Each returns a `LockFileEntry[]`.
|
|
410
|
+
|
|
411
|
+
```typescript
|
|
412
|
+
import { parseNpmLockFile, parsePnpmLockFile, parseYarnLockFile, parseBunLockFile } from "@visulima/package";
|
|
413
|
+
import { readFileSync } from "node:fs";
|
|
414
|
+
|
|
415
|
+
const entries = parsePnpmLockFile(readFileSync("./pnpm-lock.yaml", "utf8"));
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
#### decodeSriIntegrity
|
|
419
|
+
|
|
420
|
+
Decodes a Subresource Integrity string (`sha512-<base64>`) into a `{ algorithm, hex }` pair. Returns `undefined` if the string is malformed, oversized, or uses an unsupported algorithm.
|
|
421
|
+
|
|
422
|
+
```typescript
|
|
423
|
+
import { decodeSriIntegrity } from "@visulima/package";
|
|
424
|
+
|
|
425
|
+
const integrity = decodeSriIntegrity("sha512-…");
|
|
426
|
+
// => { algorithm: 'sha512', hex: '…' } | undefined
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
### pnpm Catalogs & Workspaces
|
|
430
|
+
|
|
431
|
+
Helpers for reading and resolving pnpm [catalog](https://pnpm.io/catalogs) references from `pnpm-workspace.yaml`.
|
|
432
|
+
|
|
433
|
+
#### readPnpmCatalogs
|
|
434
|
+
|
|
435
|
+
Reads the catalog definitions for the workspace that owns `packagePath`. Returns `undefined` when the package is not part of a pnpm workspace.
|
|
436
|
+
|
|
437
|
+
```typescript
|
|
438
|
+
import { readPnpmCatalogs, readPnpmCatalogsSync } from "@visulima/package";
|
|
439
|
+
|
|
440
|
+
const catalogs = await readPnpmCatalogs("./packages/app/package.json");
|
|
441
|
+
// => { default: { react: '^18.0.0' }, named: { next: { react: '^19.0.0' } } } | undefined
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
#### isPackageInWorkspace
|
|
445
|
+
|
|
446
|
+
Checks whether a package path is covered by a workspace's `packages:` globs.
|
|
447
|
+
|
|
448
|
+
```typescript
|
|
449
|
+
import { isPackageInWorkspace } from "@visulima/package";
|
|
450
|
+
|
|
451
|
+
const inWorkspace = isPackageInWorkspace("/repo", "/repo/packages/app", ["packages/*"]);
|
|
452
|
+
// => true
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
> Catalog references are also resolved automatically when you pass `resolveCatalogs: true` to `parsePackageJson[Sync]` / `findPackageJson[Sync]` (see above).
|
|
456
|
+
|
|
457
|
+
### Subpath Exports
|
|
458
|
+
|
|
459
|
+
Every concern ships as its own entry point. Import from the narrowest one for the best tree-shaking — the root (`@visulima/package`) re-exports everything but pulls in all modules.
|
|
460
|
+
|
|
461
|
+
| Subpath | Contents |
|
|
462
|
+
| ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
463
|
+
| `@visulima/package/monorepo` | `findMonorepoRoot[Sync]` |
|
|
464
|
+
| `@visulima/package/package` | `findPackageRoot[Sync]` |
|
|
465
|
+
| `@visulima/package/package-json` | `findPackageJson[Sync]`, `parsePackageJson[Sync]`, `writePackageJson[Sync]`, `clearPackageJsonCache`, property helpers, `ensurePackages` |
|
|
466
|
+
| `@visulima/package/package-manager` | `findPackageManager[Sync]`, `findLockFile[Sync]`, `getPackageManagerVersion`, `identifyInitiatingPackageManager`, `generateMissingPackagesInstallMessage` |
|
|
467
|
+
| `@visulima/package/lockfile` | `parseLockFile[Sync]`, `parseNpmLockFile`, `parsePnpmLockFile`, `parseYarnLockFile`, `parseBunLockFile`, `decodeSriIntegrity` |
|
|
468
|
+
| `@visulima/package/pnpm` | `readPnpmCatalogs[Sync]`, `resolveCatalogReference[s]`, `resolveDependenciesCatalogReferences`, `isPackageInWorkspace` |
|
|
469
|
+
| `@visulima/package/error` | `PackageNotFoundError` |
|
|
470
|
+
|
|
471
|
+
```typescript
|
|
472
|
+
import { parseLockFile } from "@visulima/package/lockfile";
|
|
473
|
+
import { readPnpmCatalogs } from "@visulima/package/pnpm";
|
|
474
|
+
```
|
|
475
|
+
|
|
338
476
|
## Supported Node.js Versions
|
|
339
477
|
|
|
340
478
|
Libraries in this ecosystem make the best effort to track [Node.js’ release schedule](https://github.com/nodejs/release#release-schedule).
|
package/dist/error.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{default as a}from"./packem_shared/PackageNotFoundError
|
|
1
|
+
import{default as a}from"./packem_shared/PackageNotFoundError-Bi41exhP.js";export{a as PackageNotFoundError};
|
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, e as ensurePackages, f as findPackageJson, b as findPackageJsonSync, g as getPackageJsonProperty, h as hasPackageJsonAnyDependency,
|
|
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";
|
|
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';
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{default as o}from"./packem_shared/PackageNotFoundError
|
|
1
|
+
import{default as o}from"./packem_shared/PackageNotFoundError-Bi41exhP.js";import{decodeSriIntegrity as r,parseBunLockFile as c,parseLockFile as s,parseLockFileContent as g,parseLockFileSync as i,parseNpmLockFile as t,parsePnpmLockFile as k,parseYarnLockFile as p}from"./lockfile.js";import{findMonorepoRoot as f,findMonorepoRootSync as l}from"./monorepo.js";import{findPackageRoot as y,findPackageRootSync as m}from"./package.js";import{clearPackageJsonCache as J,ensurePackages as S,findPackageJson as L,findPackageJsonSync as M,getPackageJsonProperty as x,hasPackageJsonAnyDependency as C,hasPackageJsonProperty as R,parsePackageJson as u,parsePackageJsonSync as I,writePackageJson as h,writePackageJsonSync as v}from"./package-json.js";import{findLockFile as D,findLockFileSync as N,findPackageManager as A,findPackageManagerSync as B,generateMissingPackagesInstallMessage as E,getPackageManagerVersion as V,identifyInitiatingPackageManager as W}from"./package-manager.js";import{isPackageInWorkspace as b,readPnpmCatalogs as j,readPnpmCatalogsSync as q,resolveCatalogReference as z,resolveCatalogReferences as G,resolveDependenciesCatalogReferences as H}from"./pnpm.js";export{o as PackageNotFoundError,J as clearPackageJsonCache,r as decodeSriIntegrity,S as ensurePackages,D as findLockFile,N as findLockFileSync,f as findMonorepoRoot,l as findMonorepoRootSync,L as findPackageJson,M as findPackageJsonSync,A as findPackageManager,B as findPackageManagerSync,y as findPackageRoot,m as findPackageRootSync,E as generateMissingPackagesInstallMessage,x as getPackageJsonProperty,V as getPackageManagerVersion,C as hasPackageJsonAnyDependency,R as hasPackageJsonProperty,W as identifyInitiatingPackageManager,b as isPackageInWorkspace,c as parseBunLockFile,s as parseLockFile,g as parseLockFileContent,i as parseLockFileSync,t as parseNpmLockFile,u as parsePackageJson,I as parsePackageJsonSync,k as parsePnpmLockFile,p as parseYarnLockFile,j as readPnpmCatalogs,q as readPnpmCatalogsSync,z as resolveCatalogReference,G as resolveCatalogReferences,H as resolveDependenciesCatalogReferences,h as writePackageJson,v as writePackageJsonSync};
|
package/dist/lockfile.d.ts
CHANGED
|
@@ -1,4 +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
6
|
type LockFileType = "bun" | "npm" | "pnpm" | "yarn";
|
|
3
7
|
/** SRI algorithms the parser can decode into hex. */
|
|
4
8
|
type LockFileIntegrityAlgorithm = "sha256" | "sha384" | "sha512";
|
|
@@ -77,7 +81,9 @@ declare const parsePnpmLockFile: (content: string) => LockFileEntry[];
|
|
|
77
81
|
declare const parseYarnLockFile: (content: string) => LockFileEntry[];
|
|
78
82
|
/**
|
|
79
83
|
* Parses `bun.lock` (Bun v1.1+, JSON-ish with trailing commas). The
|
|
80
|
-
* binary `bun.lockb` format is
|
|
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).
|
|
81
87
|
*
|
|
82
88
|
* Attribution: format + tuple layout verified against lockparse
|
|
83
89
|
* (https://github.com/43081j/lockparse, MIT).
|
package/dist/lockfile.js
CHANGED
|
@@ -1 +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};
|
package/dist/monorepo.js
CHANGED
|
@@ -1 +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};
|
package/dist/package-json.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import '@visulima/fs';
|
|
2
2
|
import 'type-fest';
|
|
3
|
-
export { F as FindPackageJsonCache, a as NormalizedReadResult, e as ensurePackages, f as findPackageJson, b as findPackageJsonSync, g as getPackageJsonProperty, h as hasPackageJsonAnyDependency,
|
|
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";
|
|
4
4
|
import '@antfu/install-pkg';
|
|
5
5
|
import '@inquirer/core';
|
|
6
6
|
import '@inquirer/type';
|
package/dist/package-json.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
${
|
|
3
|
-
- ${
|
|
4
|
-
- `)}`),this.name="PackageJsonValidationError"}}const
|
|
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:
|
|
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};
|
|
@@ -37,8 +37,10 @@ declare const findPackageManager: (cwd?: URL | string) => Promise<PackageManager
|
|
|
37
37
|
declare const findPackageManagerSync: (cwd?: URL | string) => PackageManagerResult;
|
|
38
38
|
/**
|
|
39
39
|
* Function that retrieves the version of the specified package manager.
|
|
40
|
-
* @param name The name of the package manager.
|
|
40
|
+
* @param name The name of the package manager. Must be one of the known managers (`npm`, `pnpm`, `yarn`, `bun`).
|
|
41
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.
|
|
42
44
|
*/
|
|
43
45
|
declare const getPackageManagerVersion: (name: string) => string;
|
|
44
46
|
/**
|
package/dist/package-manager.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
|
|
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=`
|
|
2
2
|
${a.preMessage??""}
|
|
3
|
-
${e} could not find the following package${
|
|
3
|
+
${e} could not find the following package${r}
|
|
4
4
|
|
|
5
5
|
${n.join(`
|
|
6
6
|
`)}
|
|
7
7
|
|
|
8
|
-
To install the missing package${
|
|
9
|
-
`;const
|
|
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(`
|
|
10
10
|
|
|
11
11
|
or
|
|
12
12
|
|
|
13
|
-
`),a.postMessage&&(
|
|
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};
|
package/dist/package.js
CHANGED
|
@@ -1 +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};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{findPackageManagerSync as o}from"../package-manager.js";class n extends Error{constructor(e,r){if(typeof e=="string"&&(e=[e]),e.length===0){super("Package was not found.");return}if(r===void 0)try{r=o().packageManager}catch{}r??="npm",super(`Package '${e.join(" ")}' was not found. Please install it using '${r} install ${e.join(" ")}'`)}get code(){return"PACKAGE_NOT_FOUND"}set code(e){throw new Error("Cannot overwrite code PACKAGE_NOT_FOUND")}get name(){return"PackageNotFoundError"}set name(e){throw new Error("Cannot overwrite name of PackageNotFoundError")}}export{n as default};
|
|
@@ -81,6 +81,15 @@ declare const writePackageJsonSync: (data: PackageJson, options?: WriteJsonOptio
|
|
|
81
81
|
cwd?: URL | string;
|
|
82
82
|
}) => void;
|
|
83
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
|
+
/**
|
|
84
93
|
* A synchronous function to parse the package.json, package.yaml, or package.json5 file/object/string and return normalize the data.
|
|
85
94
|
* @param packageFile
|
|
86
95
|
* @param options
|
|
@@ -170,4 +179,4 @@ declare const hasPackageJsonAnyDependency: (packageJson: NormalizedPackageJson,
|
|
|
170
179
|
* @returns
|
|
171
180
|
*/
|
|
172
181
|
declare const ensurePackages: (packageJson: NormalizedPackageJson, packages: string[], installKey?: "dependencies" | "devDependencies", options?: EnsurePackagesOptions) => Promise<void>;
|
|
173
|
-
export { EnsurePackagesOptions as E, FindPackageJsonCache as F, NormalizedPackageJson as N, PackageJson as P, NormalizedReadResult as a, findPackageJsonSync as b,
|
|
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 };
|
package/dist/pnpm.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
import{findUp as f,findUpSync as d}from"@visulima/fs";import{readYaml as y,readYamlSync as u}from"@visulima/fs/yaml";import{dirname as i,relative as m}from"@visulima/path";const p=(e,a,t)=>{const o=i(e),s=i(a),l=s===o?".":m(o,s);return t.some(g=>{const n=g.startsWith("./")?g.slice(2):g,c=l.startsWith("./")?l.slice(2):l;if(n==="."&&c===".")return!0;if(n.endsWith("/**")){const r=n.slice(0,-3);return c===r||c.startsWith(`${r}/`)}if(n.endsWith("/*")){const r=n.slice(0,-2);return r===""?c!=="."&&!c.includes("/"):c.startsWith(`${r}/`)||c===r}return c===n||c.startsWith(`${n}/`)})},v=async e=>{const a=await f("pnpm-workspace.yaml",{cwd:i(e),type:"file"});if(!a)return;const t=await y(a),o=Array.isArray(t.packages)?t.packages:[];if(!p(a,e,o))return;const s={};return t.catalog&&typeof t.catalog=="object"&&(s.catalog=t.catalog),t.catalogs&&typeof t.catalogs=="object"&&(s.catalogs=t.catalogs),Object.keys(s).length>0?s:void 0},w=e=>{const a=d("pnpm-workspace.yaml",{cwd:i(e),type:"file"});if(!a)return;const t=u(a),o=Array.isArray(t.packages)?t.packages:[];if(!p(a,e,o))return;const s={};return t.catalog&&typeof t.catalog=="object"&&(s.catalog=t.catalog),t.catalogs&&typeof t.catalogs=="object"&&(s.catalogs=t.catalogs),Object.keys(s).length>0?s:void 0},h=(e,a,t)=>{if(a==="catalog:")return t.catalog?.[e];if(a.startsWith("catalog:")){const o=a.slice(8);return t.catalogs?.[o]?.[e]}},k=(e,a)=>{for(const[t,o]of Object.entries(e)){if(typeof o!="string")continue;const s=h(t,o,a);s&&(e[t]=s)}},C=(e,a)=>{const t=["dependencies","devDependencies","peerDependencies","optionalDependencies"];for(const o of t){if(!e[o]||typeof e[o]!="object")continue;const s=e[o];k(s,a)}};export{p as isPackageInWorkspace,v as readPnpmCatalogs,w as readPnpmCatalogsSync,h as resolveCatalogReference,C as resolveCatalogReferences,k as resolveDependenciesCatalogReferences};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@visulima/package",
|
|
3
|
-
"version": "5.0.0-alpha.
|
|
3
|
+
"version": "5.0.0-alpha.32",
|
|
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",
|
|
@@ -99,8 +99,8 @@
|
|
|
99
99
|
],
|
|
100
100
|
"dependencies": {
|
|
101
101
|
"@antfu/install-pkg": "^1.1.0",
|
|
102
|
-
"@visulima/fs": "5.0.0-alpha.
|
|
103
|
-
"@visulima/path": "3.0.0-alpha.
|
|
102
|
+
"@visulima/fs": "5.0.0-alpha.33",
|
|
103
|
+
"@visulima/path": "3.0.0-alpha.13",
|
|
104
104
|
"json5": "^2.2.3",
|
|
105
105
|
"normalize-package-data": "^9.0.0",
|
|
106
106
|
"yaml": "2.9.0"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var o=Object.defineProperty;var a=(r,e)=>o(r,"name",{value:e,configurable:!0});import{findPackageManagerSync as n}from"../package-manager.js";var c=Object.defineProperty,s=a((r,e)=>c(r,"name",{value:e,configurable:!0}),"t");class g extends Error{static{a(this,"s")}static{s(this,"PackageNotFoundError")}constructor(e,t){if(typeof e=="string"&&(e=[e]),e.length===0){super("Package was not found.");return}if(t===void 0)try{t=n().packageManager}catch{}t??="npm",super(`Package '${e.join(" ")}' was not found. Please install it using '${t} install ${e.join(" ")}'`)}get code(){return"PACKAGE_NOT_FOUND"}set code(e){throw new Error("Cannot overwrite code PACKAGE_NOT_FOUND")}get name(){return"PackageNotFoundError"}set name(e){throw new Error("Cannot overwrite name of PackageNotFoundError")}}export{g as default};
|