@vltpkg/package-json
Advanced tools
| 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"} |
+132
| 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" | ||
| } |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
8
-11.11%19353
-1.59%7
-12.5%1
Infinity%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
Updated