Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

@vltpkg/package-json

Package Overview
Dependencies
Maintainers
6
Versions
51
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@vltpkg/package-json - npm Package Compare versions

Comparing version
1.0.0-rc.10
to
1.0.0-rc.11
+28
dist/index.d.ts
import type { NormalizedManifest } from '@vltpkg/types';
export declare class PackageJson {
#private;
/**
* Reads and parses contents of a `package.json` file at a directory `dir`.
* `reload` will optionally skip reading from the cache when set to `true`.
*/
read(dir: string, { reload }?: {
reload?: boolean;
}): NormalizedManifest;
/**
* Optionally reads and parses contents of a `package.json` file at a
* directory `dir`. Returns `undefined` if it could not be read.
*/
maybeRead(dir: string, { reload }?: {
reload?: boolean;
}): NormalizedManifest | undefined;
write(dir: string, manifest: NormalizedManifest, indent?: number): void;
save(manifest: NormalizedManifest): void;
fix(manifest: NormalizedManifest): void;
/**
* Walks up the directory tree from the current working directory
* and returns the path to the first `package.json` file found.
* Returns undefined if no package.json is found.
*/
find(cwd?: string, home?: string): string | undefined;
}
//# sourceMappingURL=index.d.ts.map
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAgBvD,qBAAa,WAAW;;IAgBtB;;;OAGG;IACH,IAAI,CACF,GAAG,EAAE,MAAM,EACX,EAAE,MAAM,EAAE,GAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAO,GACpC,kBAAkB;IAsCrB;;;OAGG;IACH,SAAS,CACP,GAAG,EAAE,MAAM,EACX,EAAE,MAAM,EAAE,GAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAO,GACpC,kBAAkB,GAAG,SAAS;IAQjC,KAAK,CACH,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,kBAAkB,EAC5B,MAAM,CAAC,EAAE,MAAM,GACd,IAAI;IA6BP,IAAI,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI;IAcxC,GAAG,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI;IAcvC;;;;OAIG;IACH,IAAI,CACF,GAAG,GAAE,MAAsB,EAC3B,IAAI,GAAE,MAAkB,GACvB,MAAM,GAAG,SAAS;CAWtB"}
import { error } from '@vltpkg/error-cause';
import { asManifest, longDependencyTypes, normalizeManifest, } from '@vltpkg/types';
import { readFileSync, writeFileSync, lstatSync } from 'node:fs';
import { resolve } from 'node:path';
import { homedir } from 'node:os';
import { parse, stringify } from 'polite-json';
import { walkUp } from 'walk-up-path';
const exists = (path) => {
try {
lstatSync(path);
return true;
}
catch {
return false;
}
};
export class PackageJson {
/**
* cache of `package.json` loads
*/
#cache = new Map();
/**
* cache of `package.json` paths by manifest
*/
#pathCache = new Map();
/**
* cache of load errors
*/
#errCache = new Map();
/**
* Reads and parses contents of a `package.json` file at a directory `dir`.
* `reload` will optionally skip reading from the cache when set to `true`.
*/
read(dir, { reload } = {}) {
const cachedPackageJson = !reload && this.#cache.get(dir);
if (cachedPackageJson) {
return cachedPackageJson;
}
const filename = dir.endsWith('package.json') ?
resolve(dir)
: resolve(dir, 'package.json');
const fail = (err) => error('Could not read package.json file', err, this.read);
const cachedError = !reload && this.#errCache.get(dir);
if (cachedError) {
throw fail(cachedError);
}
try {
const res = normalizeManifest(asManifest(parse(readFileSync(filename, { encoding: 'utf8' }))));
this.#cache.set(dir, res);
this.#pathCache.set(res, dir);
return res;
}
catch (err) {
const ec = {
path: filename,
cause: err,
};
this.#errCache.set(dir, ec);
throw fail(ec);
}
}
/**
* Optionally reads and parses contents of a `package.json` file at a
* directory `dir`. Returns `undefined` if it could not be read.
*/
maybeRead(dir, { reload } = {}) {
try {
return this.read(dir, { reload });
}
catch {
return undefined;
}
}
write(dir, manifest, indent) {
const filename = dir.endsWith('package.json') ?
resolve(dir)
: resolve(dir, 'package.json');
this.fix(manifest);
try {
// This assumes kIndent and kNewline are already present on the manifest because we would
// only write a package.json after reading it which will set those properties.
writeFileSync(filename, stringify(manifest, undefined, indent));
this.#cache.set(dir, manifest);
this.#pathCache.set(manifest, dir);
}
catch (err) {
// If there was an error writing to this package.json then also delete it from our cache
// just in case a future read would get stale data.
this.#cache.delete(dir);
this.#pathCache.delete(manifest);
throw error('Could not write package.json file', {
path: filename,
cause: err,
}, this.write);
}
}
save(manifest) {
const dir = this.#pathCache.get(manifest);
if (!dir) {
throw error('Could not save manifest', {
manifest,
}, this.save);
}
this.write(dir, manifest);
}
fix(manifest) {
for (const depType of longDependencyTypes) {
const deps = manifest[depType];
if (deps) {
// should sort dependencies by name
manifest[depType] = Object.fromEntries(Object.entries(deps).sort(([a], [b]) => a.localeCompare(b, 'en')));
}
}
}
/**
* Walks up the directory tree from the current working directory
* and returns the path to the first `package.json` file found.
* Returns undefined if no package.json is found.
*/
find(cwd = process.cwd(), home = homedir()) {
for (const dir of walkUp(cwd)) {
// don't look in home directory
if (dir === home)
break;
const packageJsonPath = resolve(dir, 'package.json');
if (exists(packageJsonPath)) {
return packageJsonPath;
}
}
}
}
//# sourceMappingURL=index.js.map
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { error } from '@vltpkg/error-cause'\nimport type { ErrorCauseOptions } from '@vltpkg/error-cause'\nimport {\n asManifest,\n longDependencyTypes,\n normalizeManifest,\n} from '@vltpkg/types'\nimport type { NormalizedManifest } from '@vltpkg/types'\nimport { readFileSync, writeFileSync, lstatSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport { homedir } from 'node:os'\nimport { parse, stringify } from 'polite-json'\nimport { walkUp } from 'walk-up-path'\n\nconst exists = (path: string): boolean => {\n try {\n lstatSync(path)\n return true\n } catch {\n return false\n }\n}\n\nexport class PackageJson {\n /**\n * cache of `package.json` loads\n */\n #cache = new Map<string, NormalizedManifest>()\n\n /**\n * cache of `package.json` paths by manifest\n */\n #pathCache = new Map<NormalizedManifest, string>()\n\n /**\n * cache of load errors\n */\n #errCache = new Map<string, ErrorCauseOptions>()\n\n /**\n * Reads and parses contents of a `package.json` file at a directory `dir`.\n * `reload` will optionally skip reading from the cache when set to `true`.\n */\n read(\n dir: string,\n { reload }: { reload?: boolean } = {},\n ): NormalizedManifest {\n const cachedPackageJson = !reload && this.#cache.get(dir)\n if (cachedPackageJson) {\n return cachedPackageJson\n }\n\n const filename =\n dir.endsWith('package.json') ?\n resolve(dir)\n : resolve(dir, 'package.json')\n\n const fail = (err: ErrorCauseOptions) =>\n error('Could not read package.json file', err, this.read)\n\n const cachedError = !reload && this.#errCache.get(dir)\n if (cachedError) {\n throw fail(cachedError)\n }\n\n try {\n const res = normalizeManifest(\n asManifest(\n parse(readFileSync(filename, { encoding: 'utf8' })),\n ),\n )\n this.#cache.set(dir, res)\n this.#pathCache.set(res, dir)\n return res\n } catch (err) {\n const ec: ErrorCauseOptions = {\n path: filename,\n cause: err,\n }\n this.#errCache.set(dir, ec)\n throw fail(ec)\n }\n }\n\n /**\n * Optionally reads and parses contents of a `package.json` file at a\n * directory `dir`. Returns `undefined` if it could not be read.\n */\n maybeRead(\n dir: string,\n { reload }: { reload?: boolean } = {},\n ): NormalizedManifest | undefined {\n try {\n return this.read(dir, { reload })\n } catch {\n return undefined\n }\n }\n\n write(\n dir: string,\n manifest: NormalizedManifest,\n indent?: number,\n ): void {\n const filename =\n dir.endsWith('package.json') ?\n resolve(dir)\n : resolve(dir, 'package.json')\n this.fix(manifest)\n\n try {\n // This assumes kIndent and kNewline are already present on the manifest because we would\n // only write a package.json after reading it which will set those properties.\n writeFileSync(filename, stringify(manifest, undefined, indent))\n this.#cache.set(dir, manifest)\n this.#pathCache.set(manifest, dir)\n } catch (err) {\n // If there was an error writing to this package.json then also delete it from our cache\n // just in case a future read would get stale data.\n this.#cache.delete(dir)\n this.#pathCache.delete(manifest)\n throw error(\n 'Could not write package.json file',\n {\n path: filename,\n cause: err,\n },\n this.write,\n )\n }\n }\n\n save(manifest: NormalizedManifest): void {\n const dir = this.#pathCache.get(manifest)\n if (!dir) {\n throw error(\n 'Could not save manifest',\n {\n manifest,\n },\n this.save,\n )\n }\n this.write(dir, manifest)\n }\n\n fix(manifest: NormalizedManifest): void {\n for (const depType of longDependencyTypes) {\n const deps = manifest[depType]\n if (deps) {\n // should sort dependencies by name\n manifest[depType] = Object.fromEntries(\n Object.entries(deps).sort(([a], [b]) =>\n a.localeCompare(b, 'en'),\n ),\n )\n }\n }\n }\n\n /**\n * Walks up the directory tree from the current working directory\n * and returns the path to the first `package.json` file found.\n * Returns undefined if no package.json is found.\n */\n find(\n cwd: string = process.cwd(),\n home: string = homedir(),\n ): string | undefined {\n for (const dir of walkUp(cwd)) {\n // don't look in home directory\n if (dir === home) break\n\n const packageJsonPath = resolve(dir, 'package.json')\n if (exists(packageJsonPath)) {\n return packageJsonPath\n }\n }\n }\n}\n"]}
+5
-19
{
"name": "@vltpkg/package-json",
"description": "Manage reading package.json files",
"version": "1.0.0-rc.10",
"version": "1.0.0-rc.11",
"repository": {

@@ -11,18 +11,7 @@ "type": "git",

"author": "vlt technology inc. <support@vlt.sh> (http://vlt.sh)",
"tshy": {
"selfLink": false,
"liveDev": true,
"dialects": [
"esm"
],
"exports": {
"./package.json": "./package.json",
".": "./src/index.ts"
}
},
"dependencies": {
"polite-json": "^5.0.0",
"walk-up-path": "^4.0.0",
"@vltpkg/error-cause": "1.0.0-rc.10",
"@vltpkg/types": "1.0.0-rc.10"
"@vltpkg/error-cause": "1.0.0-rc.11",
"@vltpkg/types": "1.0.0-rc.11"
},

@@ -35,3 +24,2 @@ "devDependencies": {

"tap": "^21.5.0",
"tshy": "^3.1.0",
"typedoc": "~0.27.9",

@@ -49,3 +37,3 @@ "typescript": "5.7.3",

"prettier": "../../.prettierrc.js",
"module": "./dist/esm/index.js",
"module": "./dist/index.js",
"type": "module",

@@ -56,4 +44,3 @@ "exports": {

"import": {
"types": "./dist/esm/index.d.ts",
"default": "./dist/esm/index.js"
"default": "./dist/index.js"
}

@@ -73,5 +60,4 @@ }

"posttest": "tsc --noEmit",
"tshy": "tshy",
"typecheck": "tsc --noEmit"
}
}
import type { NormalizedManifest } from '@vltpkg/types';
export declare class PackageJson {
#private;
/**
* Reads and parses contents of a `package.json` file at a directory `dir`.
* `reload` will optionally skip reading from the cache when set to `true`.
*/
read(dir: string, { reload }?: {
reload?: boolean;
}): NormalizedManifest;
/**
* Optionally reads and parses contents of a `package.json` file at a
* directory `dir`. Returns `undefined` if it could not be read.
*/
maybeRead(dir: string, { reload }?: {
reload?: boolean;
}): NormalizedManifest | undefined;
write(dir: string, manifest: NormalizedManifest, indent?: number): void;
save(manifest: NormalizedManifest): void;
fix(manifest: NormalizedManifest): void;
/**
* Walks up the directory tree from the current working directory
* and returns the path to the first `package.json` file found.
* Returns undefined if no package.json is found.
*/
find(cwd?: string, home?: string): string | undefined;
}
//# sourceMappingURL=index.d.ts.map
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAgBvD,qBAAa,WAAW;;IAgBtB;;;OAGG;IACH,IAAI,CACF,GAAG,EAAE,MAAM,EACX,EAAE,MAAM,EAAE,GAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAO,GACpC,kBAAkB;IAsCrB;;;OAGG;IACH,SAAS,CACP,GAAG,EAAE,MAAM,EACX,EAAE,MAAM,EAAE,GAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAO,GACpC,kBAAkB,GAAG,SAAS;IAQjC,KAAK,CACH,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,kBAAkB,EAC5B,MAAM,CAAC,EAAE,MAAM,GACd,IAAI;IA6BP,IAAI,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI;IAcxC,GAAG,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI;IAcvC;;;;OAIG;IACH,IAAI,CACF,GAAG,GAAE,MAAsB,EAC3B,IAAI,GAAE,MAAkB,GACvB,MAAM,GAAG,SAAS;CAWtB"}
import { error } from '@vltpkg/error-cause';
import { asManifest, longDependencyTypes, normalizeManifest, } from '@vltpkg/types';
import { readFileSync, writeFileSync, lstatSync } from 'node:fs';
import { resolve } from 'node:path';
import { homedir } from 'node:os';
import { parse, stringify } from 'polite-json';
import { walkUp } from 'walk-up-path';
const exists = (path) => {
try {
lstatSync(path);
return true;
}
catch {
return false;
}
};
export class PackageJson {
/**
* cache of `package.json` loads
*/
#cache = new Map();
/**
* cache of `package.json` paths by manifest
*/
#pathCache = new Map();
/**
* cache of load errors
*/
#errCache = new Map();
/**
* Reads and parses contents of a `package.json` file at a directory `dir`.
* `reload` will optionally skip reading from the cache when set to `true`.
*/
read(dir, { reload } = {}) {
const cachedPackageJson = !reload && this.#cache.get(dir);
if (cachedPackageJson) {
return cachedPackageJson;
}
const filename = dir.endsWith('package.json') ?
resolve(dir)
: resolve(dir, 'package.json');
const fail = (err) => error('Could not read package.json file', err, this.read);
const cachedError = !reload && this.#errCache.get(dir);
if (cachedError) {
throw fail(cachedError);
}
try {
const res = normalizeManifest(asManifest(parse(readFileSync(filename, { encoding: 'utf8' }))));
this.#cache.set(dir, res);
this.#pathCache.set(res, dir);
return res;
}
catch (err) {
const ec = {
path: filename,
cause: err,
};
this.#errCache.set(dir, ec);
throw fail(ec);
}
}
/**
* Optionally reads and parses contents of a `package.json` file at a
* directory `dir`. Returns `undefined` if it could not be read.
*/
maybeRead(dir, { reload } = {}) {
try {
return this.read(dir, { reload });
}
catch {
return undefined;
}
}
write(dir, manifest, indent) {
const filename = dir.endsWith('package.json') ?
resolve(dir)
: resolve(dir, 'package.json');
this.fix(manifest);
try {
// This assumes kIndent and kNewline are already present on the manifest because we would
// only write a package.json after reading it which will set those properties.
writeFileSync(filename, stringify(manifest, undefined, indent));
this.#cache.set(dir, manifest);
this.#pathCache.set(manifest, dir);
}
catch (err) {
// If there was an error writing to this package.json then also delete it from our cache
// just in case a future read would get stale data.
this.#cache.delete(dir);
this.#pathCache.delete(manifest);
throw error('Could not write package.json file', {
path: filename,
cause: err,
}, this.write);
}
}
save(manifest) {
const dir = this.#pathCache.get(manifest);
if (!dir) {
throw error('Could not save manifest', {
manifest,
}, this.save);
}
this.write(dir, manifest);
}
fix(manifest) {
for (const depType of longDependencyTypes) {
const deps = manifest[depType];
if (deps) {
// should sort dependencies by name
manifest[depType] = Object.fromEntries(Object.entries(deps).sort(([a], [b]) => a.localeCompare(b, 'en')));
}
}
}
/**
* Walks up the directory tree from the current working directory
* and returns the path to the first `package.json` file found.
* Returns undefined if no package.json is found.
*/
find(cwd = process.cwd(), home = homedir()) {
for (const dir of walkUp(cwd)) {
// don't look in home directory
if (dir === home)
break;
const packageJsonPath = resolve(dir, 'package.json');
if (exists(packageJsonPath)) {
return packageJsonPath;
}
}
}
}
//# sourceMappingURL=index.js.map
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { error } from '@vltpkg/error-cause'\nimport type { ErrorCauseOptions } from '@vltpkg/error-cause'\nimport {\n asManifest,\n longDependencyTypes,\n normalizeManifest,\n} from '@vltpkg/types'\nimport type { NormalizedManifest } from '@vltpkg/types'\nimport { readFileSync, writeFileSync, lstatSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport { homedir } from 'node:os'\nimport { parse, stringify } from 'polite-json'\nimport { walkUp } from 'walk-up-path'\n\nconst exists = (path: string): boolean => {\n try {\n lstatSync(path)\n return true\n } catch {\n return false\n }\n}\n\nexport class PackageJson {\n /**\n * cache of `package.json` loads\n */\n #cache = new Map<string, NormalizedManifest>()\n\n /**\n * cache of `package.json` paths by manifest\n */\n #pathCache = new Map<NormalizedManifest, string>()\n\n /**\n * cache of load errors\n */\n #errCache = new Map<string, ErrorCauseOptions>()\n\n /**\n * Reads and parses contents of a `package.json` file at a directory `dir`.\n * `reload` will optionally skip reading from the cache when set to `true`.\n */\n read(\n dir: string,\n { reload }: { reload?: boolean } = {},\n ): NormalizedManifest {\n const cachedPackageJson = !reload && this.#cache.get(dir)\n if (cachedPackageJson) {\n return cachedPackageJson\n }\n\n const filename =\n dir.endsWith('package.json') ?\n resolve(dir)\n : resolve(dir, 'package.json')\n\n const fail = (err: ErrorCauseOptions) =>\n error('Could not read package.json file', err, this.read)\n\n const cachedError = !reload && this.#errCache.get(dir)\n if (cachedError) {\n throw fail(cachedError)\n }\n\n try {\n const res = normalizeManifest(\n asManifest(\n parse(readFileSync(filename, { encoding: 'utf8' })),\n ),\n )\n this.#cache.set(dir, res)\n this.#pathCache.set(res, dir)\n return res\n } catch (err) {\n const ec: ErrorCauseOptions = {\n path: filename,\n cause: err,\n }\n this.#errCache.set(dir, ec)\n throw fail(ec)\n }\n }\n\n /**\n * Optionally reads and parses contents of a `package.json` file at a\n * directory `dir`. Returns `undefined` if it could not be read.\n */\n maybeRead(\n dir: string,\n { reload }: { reload?: boolean } = {},\n ): NormalizedManifest | undefined {\n try {\n return this.read(dir, { reload })\n } catch {\n return undefined\n }\n }\n\n write(\n dir: string,\n manifest: NormalizedManifest,\n indent?: number,\n ): void {\n const filename =\n dir.endsWith('package.json') ?\n resolve(dir)\n : resolve(dir, 'package.json')\n this.fix(manifest)\n\n try {\n // This assumes kIndent and kNewline are already present on the manifest because we would\n // only write a package.json after reading it which will set those properties.\n writeFileSync(filename, stringify(manifest, undefined, indent))\n this.#cache.set(dir, manifest)\n this.#pathCache.set(manifest, dir)\n } catch (err) {\n // If there was an error writing to this package.json then also delete it from our cache\n // just in case a future read would get stale data.\n this.#cache.delete(dir)\n this.#pathCache.delete(manifest)\n throw error(\n 'Could not write package.json file',\n {\n path: filename,\n cause: err,\n },\n this.write,\n )\n }\n }\n\n save(manifest: NormalizedManifest): void {\n const dir = this.#pathCache.get(manifest)\n if (!dir) {\n throw error(\n 'Could not save manifest',\n {\n manifest,\n },\n this.save,\n )\n }\n this.write(dir, manifest)\n }\n\n fix(manifest: NormalizedManifest): void {\n for (const depType of longDependencyTypes) {\n const deps = manifest[depType]\n if (deps) {\n // should sort dependencies by name\n manifest[depType] = Object.fromEntries(\n Object.entries(deps).sort(([a], [b]) =>\n a.localeCompare(b, 'en'),\n ),\n )\n }\n }\n }\n\n /**\n * Walks up the directory tree from the current working directory\n * and returns the path to the first `package.json` file found.\n * Returns undefined if no package.json is found.\n */\n find(\n cwd: string = process.cwd(),\n home: string = homedir(),\n ): string | undefined {\n for (const dir of walkUp(cwd)) {\n // don't look in home directory\n if (dir === home) break\n\n const packageJsonPath = resolve(dir, 'package.json')\n if (exists(packageJsonPath)) {\n return packageJsonPath\n }\n }\n }\n}\n"]}
{
"type": "module"
}