New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

node-ncbi

Package Overview
Dependencies
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

node-ncbi - npm Package Compare versions

Comparing version 0.2.1 to 0.3.0

src/gateways/parse.js

14

bin/repl.js

@@ -11,10 +11,14 @@

const url = replServer.context.url = function(params) {
params.test = true;
var urlGateway = gateway(params);
const url = replServer.context.url = function(args) {
var urlGateway = gateway(args);
return urlGateway.generateUrl();
}
replServer.context.open = function(params) {
open(url(params));
replServer.context.open = function(args) {
open(url(args));
return;
}
replServer.context.noop = function() {
return '';
}
'use strict';
module.exports = require('./src/controllers');
module.exports = {
pubmed: require('./src/pubmed'),
createSearch: function() {
console.error('createSearch has been deprecated. Please use the pure function `ncbi.pubmed.search` instead.');
},
createCitation: function() {
console.error('createCitation has been deprecated. Please use pure functions instead (see documentation)');
}
}
{
"name": "node-ncbi",
"version": "0.2.1",
"version": "0.3.0",
"description": "Access and parse the NCBI eUtils API in Node or the Browser",

@@ -27,6 +27,7 @@ "keywords": [

"popsicle": "^0.5.12",
"underscore": "^1.8.3",
"react-addons-update": "^15.0.2",
"xml2js": "^0.4.9"
},
"devDependencies": {
"babel-preset-es2015": "^6.6.0",
"gulp": "^3.9.1",

@@ -33,0 +34,0 @@ "gulp-eslint": "^2.0.0",

@@ -7,2 +7,5 @@ # node-ncbi

**Note:** Browser use isn't ideal right now due to the very large XML parser. I'll come with a dedicated script
that relies on the browser's native DOM parsing to get around this.
## Getting started

@@ -16,7 +19,7 @@

### PubMed Searches
### Performing a search
```js
let pubmedSearch = ncbi.createSearch('actin');
pubmedSearch.search().then((results) => {
const pubmed = ncbi.pubmed;
pubmed.search('actin').then((results) => {
console.log(results);

@@ -26,29 +29,41 @@ });

Will log an array of objects. The objects represent PubMed "summaries" containing title, authors, journal and citation information, etc..
Will log
```
{
count: (Number),
papers: (Array)
}
```
where `count` is the total number of papers, independent of pagination. The "papers" represent PubMed "summaries" containing title, authors, journal and citation information, etc..
By default, 10 results will be retrieved at a time. To get the next set of results:
```js
pubmedSearch.getPage(1).then( ... );
```javascript
pubmed.search('actin', 1).then((results) => {
console.log(results);
});
```
**Note**: An earlier version used `pubmedSearch.nextPage` without an argument. I decided that storing this one tiny piece of state in the controller was stupid.
To change the number of results retrieved at a time:
```js
let pubmedSearch = ncbi.createSearch('actin', {
resultsPerPage: 100
```javascript
pubmed.search('actin', 0, 20).then((results) => {
console.log(results);
});
```
###Getting the details of a paper
###Looking up a specific paper
```js
var paper = ncbi.createCitation(20517925);
```javascript
pubmed.summary(20517925).then((paper) => {
console.log(paper);
});
```
where the only argument is a PMID (PubMed ID #).
The following methods are available:
In addition, following methods are available:
- `abstract()` - get the abstract

@@ -68,37 +83,19 @@ - `summary()` - get the "summary" - an object of fields containing title, authors, citation info, etc.

### Overview
### REPL
The module consists of three main parts: a Gateway class that controls access to the API, a set of Document parsers for finding the required information in the returned documents, and Controllers for tying the two together.
To help with creating Gateways are seeing the data structures returned by the API, node-ncbi provides a custom REPL. Start it with `npm start`. You can then run `url({object})` or `open({object})` where {object} is an object literal that looks like the following:
Since many of the exposed methods require accessing the API multiple times (ie - perform a search and get ID numbers, then find the individual documents by sending those ID numbers) controllers configure as many gateways and parsers as needed to accomplish a particular task.
Gateways are instantiated with an object literal as follows:
```js
let gateway = Gateway({
documentType: 'esearch' | 'esummary' | 'elink' | 'efetch' (default: 'esearch'),
responseType: 'json' | 'xml' (default: 'json'),
params: {} (set of parameters for the API)
test: false
});
```javascript
utility: 'esearch',
params: {
db: 'pubmed',
term: query,
retstart: start,
retmax: resultsPerPage
}
```
See the [API documentaion](http://www.ncbi.nlm.nih.gov/books/NBK25500/) for more information on document types and available parameters.
`url` will log the URL needed to access eUtils while `open` will open that URL in a browser. This can help with debugging and to look at the actual data which is useful to create new queries. [See the full documentation of eUtils](http://www.ncbi.nlm.nih.gov/books/NBK25500/) for more information on creating
queries.
A set of PubMed IDs can be added like so:
```js
gateway.addIds([1111111, 2222222]);
```
The most important method is `gateway.send()` which returns a Promise resolving to the appropriate parser for the returned document type. The parser methods are pretty self-explanatory and are named for the type of information that they will return.
### REPL
To help with creating Gateways are seeing the data structures returned by the API, node-ncbi provides a custom REPL. Start it with `npm start`. You can then run `url({object})` or `open({object})` where {object} is an object literal for creating gateways as described above. `url` will log the URL needed to access eUtils while `open` will open that URL in a browser. This can help to see the actual data which is useful to create new parsers.
### Unit tests
The Gateway and the Parsers are tested independetly in `test/test.js`. Run with `gulp test`.
### ESLint

@@ -105,0 +102,0 @@

@@ -1,7 +0,5 @@

'strict mode';
const _ = require('underscore');
const update = require('react-addons-update');
const popsicle = require('popsicle');
const createParser = require('../documents');
const parse = require('./parse');

@@ -22,28 +20,6 @@ /**

Gateway.getBase = function() {
return this.base = 'http://eutils.ncbi.nlm.nih.gov/entrez/eutils/' + this.settings.documentType + '.fcgi?';
return this.base = 'http://eutils.ncbi.nlm.nih.gov/entrez/eutils/' + this.settings.utility + '.fcgi?';
}
/**
* Set parameters after object instatiation.
* Note: this method is also called by the constructor to add the responseType
* as the retmode property.
* @arg: params | Object | new URL parameters indexed by name
* @return the URL parameters after modification
*/
Gateway.addParams = function(params) {
_.extend(this.settings.params, params);
return this.settings.params;
}
/**
* Add article IDs for performing an efetch or esummary type of request.
* @arg: ids | Array | array of ID numbers (eg pubmed ids)
* @return: the full Object of URL parameters
*/
Gateway.addIds = function(ids) {
var idString = _.isArray(ids) ? ids.join() : ids;
return this.addParams({id: idString});
}
/**
* Create the URL to access the API.

@@ -56,4 +32,9 @@ * @return String | A URL representing the call that will be made, based on this.settings

for (var key in this.settings.params) {
url = url + key + '=' + this.settings.params[key];
url = url + '&';
try {
url += key + '=' + this.settings.params[key].toString();
url += '&';
} catch(e) {
//skip if this parameter cannot be converted to a string
continue;
}
}

@@ -72,7 +53,2 @@ //remove final &

var url = this.generateUrl();
if (this.test) {
return new Promise(function(resolve) {
resolve('Test call to NCBI eUtils: ' + url);
});
}
return popsicle({

@@ -84,4 +60,5 @@ method: 'GET',

/**
* Send off the request and create a parser.
* Send off the request and parse the returned data.
* @return Promise | Call .then(function(document)) to access the methods in the

@@ -94,12 +71,8 @@ * parser object (count, ids, summaries, abstract).

*/
Gateway.resolve = function(methodName) {
return this.send().then(document => {
var parser = createParser(document.body, this.settings.documentType);
if (methodName) {
return parser[methodName]();
} else {
return parser;
}
Gateway.resolve = function(query) {
return this.send().then(res => {
const dataObj = parse(res.body);
return query(dataObj);
});
}
};

@@ -117,11 +90,14 @@ /**

module.exports = function(args) {
var gateway = Object.create(Gateway);
gateway.settings = _.extend({
documentType: 'esearch',
responseType: 'json',
params: {},
test: false
}, args);
gateway.addParams({retmode: gateway.settings.responseType});
const defaults = {
utility: 'esearch',
params: {
retmode: 'json',
db: 'pubmed'
}
};
const settings = update(defaults, {$merge: args, params: {$merge: args.params}});
const gateway = Object.assign(Object.create(Gateway), {
settings: settings
});
return gateway;
}

@@ -15,5 +15,6 @@ 'use strict';

*/
pubmedSearch: function(query, start, end) {
pubmedSearch: function(query, page, resultsPerPage) {
const start = page * resultsPerPage;
return createGateway({
documentType: 'esearch',
utility: 'esearch',
params: {

@@ -23,3 +24,3 @@ db: 'pubmed',

retstart: start,
retmax: end - start
retmax: resultsPerPage
}

@@ -33,10 +34,9 @@ });

pubmedSummary: function(ids) {
const gateway = createGateway({
documentType: 'esummary',
return createGateway({
utility: 'esummary',
params: {
db: 'pubmed'
db: 'pubmed',
id: ids
}
});
gateway.addIds(ids);
return gateway;
},

@@ -49,11 +49,10 @@

pubmedRecord: function(ids) {
const gateway = createGateway({
documentType: 'efetch',
responseType: 'xml',
return createGateway({
utility: 'efetch',
params: {
db: 'pubmed'
db: 'pubmed',
retmode: 'xml',
id: ids
}
});
gateway.addIds(ids);
return gateway;
},

@@ -68,14 +67,13 @@

pubmedLinks: function(id) {
const gateway = createGateway({
documentType: 'elink',
return createGateway({
utility: 'elink',
params: {
db: 'pubmed',
dbfrom: 'pubmed',
cmd: 'neighbor'
cmd: 'neighbor',
id: id
}
});
gateway.addIds(id);
return gateway;
}
}

@@ -20,3 +20,3 @@ /* eslint-env mocha, node */

it('should build a valid search url from parameters', function() {
assert.equal(search.generateUrl(), 'http://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=pubmed&term=ydenberg%20ca&retstart=0&retmax=10&retmode=json');
assert.equal(search.generateUrl(), 'http://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?retmode=json&db=pubmed&term=ydenberg%20ca&retstart=0&retmax=10');
});

@@ -32,3 +32,3 @@ });

it('should build a valid link url from parameters', function() {
assert.equal(links.generateUrl(), 'http://eutils.ncbi.nlm.nih.gov/entrez/eutils/elink.fcgi?db=pubmed&dbfrom=pubmed&cmd=neighbor&retmode=json&id=22588722');
assert.equal(links.generateUrl(), 'http://eutils.ncbi.nlm.nih.gov/entrez/eutils/elink.fcgi?retmode=json&db=pubmed&dbfrom=pubmed&cmd=neighbor&id=22588722');
});

@@ -39,9 +39,13 @@ });

const parse = require('../src/gateways/parse');
function getDoc(filename, callback) {
var fs = require('fs');
var path = require('path');
fs.readFile(path.join(__dirname, 'docs', filename), 'UTF-8', callback);
fs.readFile(path.join(__dirname, 'docs', filename), 'UTF-8', (err, data) => {
callback(err, parse(data));
});
}
var createParser = require('../src/documents');
var q = require('../src/queries');
describe('parser', function() {

@@ -52,4 +56,3 @@

getDoc('search.json', function(err, contents) {
var parser = createParser(contents, 'esearch');
assert.equal(parser.count(), 9);
assert.equal(q.count(contents), 9);
done();

@@ -63,4 +66,3 @@ });

getDoc('search.json', function(err, contents) {
var parser = createParser(contents, 'esearch');
assert.equal(parser.ids().length, 9);
assert.equal(q.ids(contents).length, 9);
done();

@@ -74,5 +76,3 @@ })

getDoc('summary.json', function(err, contents) {
var parser = createParser(contents, 'esummary');
var summaries = parser.summaries();
assert.equal(summaries.length, 9);
assert.equal(q.summaries(contents).length, 9);
done();

@@ -86,4 +86,3 @@ });

getDoc('fetch.xml', function(err, contents) {
var parser = createParser(contents, 'efetch');
assert.ok( parser.abstracts(true) );
assert.equal(typeof q.abstract(contents), 'string');
done();

@@ -94,7 +93,6 @@ });

describe('citedBy', function() {
describe('findLinks', function() {
it('should find all of the papers that have cited this one', function(done) {
getDoc('elink.json', function(err, contents) {
var parser = createParser(contents, 'elink');
assert.equal(parser.citedBy().length, 2);
assert.equal(q.findLinks('pubmed_pubmed_citedin', contents).length, 2);
done();

@@ -105,19 +103,23 @@ });

describe('cites', function() {
it('should find all the papers this paper cites', function(done) {
getDoc('elink.json', function(err, contents) {
var parser = createParser(contents, 'elink');
assert.ok(parser.cites());
done();
});
});
});
function areSummaries(summaries) {
return (typeof summaries[0].articleids === 'object');
}
var pubmed = require('../src/pubmed');
describe('Pubmed module', function() {
it('should perform a search', function(done) {
pubmed.search('ydenberg ca').then(results => {
assert(areSummaries(results.papers));
done();
})
});
describe('similar', function() {
it('should find all the papers PubMed flags as similar to this one', function(done) {
getDoc('elink.json', function(err, contents) {
var parser = createParser(contents, 'elink');
assert.ok(parser.similar());
done();
});
it('should return papers that cite this one', function(done) {
pubmed.citedBy(19188495).then(results => {
assert(areSummaries(results));
done();
});

@@ -124,0 +126,0 @@ });

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc