Skip to content

Commit

Permalink
feat: add readPackage helper (#106)
Browse files Browse the repository at this point in the history
As stated in the comment above the new function, this is a new isolated
function for reading and parsing a given package.json file.  This will
allow things like npm which already requires this module to tap into the
exact same code this module would use to parse a package.json file, but
not have to require the whole module if it is not going to need
normalization or saving.
  • Loading branch information
wraithgar committed Jun 3, 2024
1 parent e6c2bdd commit 62e585a
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 18 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,15 @@ await pkgJson.save()
// }
```

There is also a helper function exported for opening a package.json file
with no extra normalization or saving functionality.

```js
const { readPackage } = require('@npmcli/package-json/lib/read-package')
const rawData = await readPackage('./package.json')
// rawData will now have the package.json contents with no changes or normalizations
```

## API:

### `constructor()`
Expand Down
19 changes: 7 additions & 12 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
const { readFile, writeFile } = require('fs/promises')
const { resolve } = require('path')
const { readFile, writeFile } = require('node:fs/promises')
const { resolve } = require('node:path')
const parseJSON = require('json-parse-even-better-errors')

const updateDeps = require('./update-dependencies.js')
const updateScripts = require('./update-scripts.js')
const updateWorkspaces = require('./update-workspaces.js')
const normalize = require('./normalize.js')

const parseJSON = require('json-parse-even-better-errors')
const { read, parse } = require('./read-package.js')

// a list of handy specialized helper functions that take
// care of special cases that are handled by the npm cli
Expand Down Expand Up @@ -126,9 +127,8 @@ class PackageJson {
this.#path = path
let parseErr
try {
this.#readFileContent = await readFile(this.filename, 'utf8')
this.#readFileContent = await read(this.filename)
} catch (err) {
err.message = `Could not read package.json: ${err}`
if (!parseIndex) {
throw err
}
Expand Down Expand Up @@ -158,12 +158,7 @@ class PackageJson {

// Load data from a JSON string/buffer
fromJSON (data) {
try {
this.#manifest = parseJSON(data)
} catch (err) {
err.message = `Invalid package.json: ${err}`
throw err
}
this.#manifest = parse(data)
return this
}

Expand Down
4 changes: 2 additions & 2 deletions lib/normalize.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const valid = require('semver/functions/valid')
const clean = require('semver/functions/clean')
const fs = require('fs/promises')
const path = require('path')
const fs = require('node:fs/promises')
const path = require('node:path')
const { log } = require('proc-log')

/**
Expand Down
39 changes: 39 additions & 0 deletions lib/read-package.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// This is JUST the code needed to open a package.json file and parse it.
// It's isolated out so that code needing to parse a package.json file can do so in the same way as this module does, without needing to require the whole module, or needing to require the underlying parsing library.

const { readFile } = require('fs/promises')
const parseJSON = require('json-parse-even-better-errors')

async function read (filename) {
try {
const data = await readFile(filename, 'utf8')
return data
} catch (err) {
err.message = `Could not read package.json: ${err}`
throw err
}
}

function parse (data) {
try {
const content = parseJSON(data)
return content
} catch (err) {
err.message = `Invalid package.json: ${err}`
throw err
}
}

// This is what most external libs will use.
// PackageJson will call read and parse separately
async function readPackage (filename) {
const data = await read(filename)
const content = parse(data)
return content
}

module.exports = {
read,
parse,
readPackage,
}
7 changes: 7 additions & 0 deletions tap-snapshots/test/index.js.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -527,3 +527,10 @@ exports[`test/index.js TAP load update long package.json > should properly write
}
`

exports[`test/index.js TAP read package > must match snapshot 1`] = `
Object {
"name": "foo",
"version": "1.0.0",
}
`
16 changes: 14 additions & 2 deletions test/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const fs = require('fs')
const { resolve } = require('path')
const fs = require('node:fs')
const { join, resolve } = require('node:path')
const t = require('tap')
const PackageJson = require('../lib/index.js')

Expand Down Expand Up @@ -233,3 +233,15 @@ t.test('can set data', async t => {
message: /No package\.json to save to/,
})
})

t.test('read package', async t => {
const { readPackage } = require('../lib/read-package')
const path = t.testdir({
'package.json': JSON.stringify({
name: 'foo',
version: '1.0.0',
}),
})
const data = await readPackage(join(path, 'package.json'))
t.matchSnapshot(data)
})
2 changes: 1 addition & 1 deletion test/normalize.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const t = require('tap')
const { join } = require('path')
const { join } = require('node:path')
const pkg = require('../')
const rpj = require('read-package-json-fast')

Expand Down
2 changes: 1 addition & 1 deletion test/prepare.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const t = require('tap')
const pkg = require('../')
const { join } = require('path')
const { join } = require('node:path')

const testMethods = {
'@npmcli/package-json': async (t, testdir, { dir = (v) => v, ...opts } = {}) => {
Expand Down

0 comments on commit 62e585a

Please sign in to comment.