1# libnpmsearch
2
3[![npm version](https://img.shields.io/npm/v/libnpmsearch.svg)](https://npm.im/libnpmsearch)
4[![license](https://img.shields.io/npm/l/libnpmsearch.svg)](https://npm.im/libnpmsearch)
5[![CI - libnpmsearch](https://github.com/npm/cli/actions/workflows/ci-libnpmsearch.yml/badge.svg)](https://github.com/npm/cli/actions/workflows/ci-libnpmsearch.yml)
6
7[`libnpmsearch`](https://github.com/npm/libnpmsearch) is a Node.js library for
8programmatically accessing the npm search endpoint. It does **not** support
9legacy search through `/-/all`.
10
11## Table of Contents
12
13* [Example](#example)
14* [Install](#install)
15* [Contributing](#contributing)
16* [API](#api)
17  * [search opts](#opts)
18  * [`search()`](#search)
19  * [`search.stream()`](#search-stream)
20
21## Example
22
23```js
24const search = require('libnpmsearch')
25
26console.log(await search('libnpm'))
27=>
28[
29  {
30    name: 'libnpm',
31    description: 'programmatic npm API',
32    ...etc
33  },
34  {
35    name: 'libnpmsearch',
36    description: 'Programmatic API for searching in npm and compatible registries',
37    ...etc
38  },
39  ...more
40]
41```
42
43## Install
44
45`$ npm install libnpmsearch`
46
47### API
48
49#### <a name="opts"></a> `opts` for `libnpmsearch` commands
50
51The following opts are used directly by `libnpmsearch` itself:
52
53* `opts.limit` - Number of results to limit the query to. Default: 20
54* `opts.from` - Offset number for results. Used with `opts.limit` for pagination. Default: 0
55* `opts.detailed` - If true, returns an object with `package`, `score`, and `searchScore` fields, with `package` being what would usually be returned, and the other two containing details about how that package scored. Useful for UIs. Default: false
56* `opts.sortBy` - Used as a shorthand to set `opts.quality`, `opts.maintenance`, and `opts.popularity` with values that prioritize each one. Should be one of `'optimal'`, `'quality'`, `'maintenance'`, or `'popularity'`. Default: `'optimal'`
57* `opts.maintenance` - Decimal number between `0` and `1` that defines the weight of `maintenance` metrics when scoring and sorting packages. Default: `0.65` (same as `opts.sortBy: 'optimal'`)
58* `opts.popularity` - Decimal number between `0` and `1` that defines the weight of `popularity` metrics when scoring and sorting packages. Default: `0.98` (same as `opts.sortBy: 'optimal'`)
59* `opts.quality` - Decimal number between `0` and `1` that defines the weight of `quality` metrics when scoring and sorting packages. Default: `0.5` (same as `opts.sortBy: 'optimal'`)
60
61`libnpmsearch` uses [`npm-registry-fetch`](https://npm.im/npm-registry-fetch).
62Most options are passed through directly to that library, so please refer to
63[its own `opts`
64documentation](https://www.npmjs.com/package/npm-registry-fetch#fetch-options)
65for options that can be passed in.
66
67A couple of options of note for those in a hurry:
68
69* `opts.token` - can be passed in and will be used as the authentication token for the registry. For other ways to pass in auth details, see the n-r-f docs.
70
71#### <a name="search"></a> `> search(query, [opts]) -> Promise`
72
73`query` must be either a String or an Array of search terms.
74
75If `opts.limit` is provided, it will be sent to the API to constrain the number
76of returned results. You may receive more, or fewer results, at the endpoint's
77discretion.
78
79The returned Promise resolved to an Array of search results with the following
80format:
81
82```js
83{
84  name: String,
85  version: SemverString,
86  description: String || null,
87  maintainers: [
88    {
89      username: String,
90      email: String
91    },
92    ...etc
93  ] || null,
94  keywords: [String] || null,
95  date: Date || null
96}
97```
98
99If `opts.limit` is provided, it will be sent to the API to constrain the number
100of returned results. You may receive more, or fewer results, at the endpoint's
101discretion.
102
103For streamed results, see [`search.stream`](#search-stream).
104
105##### Example
106
107```javascript
108await search('libnpm')
109=>
110[
111  {
112    name: 'libnpm',
113    description: 'programmatic npm API',
114    ...etc
115  },
116  {
117    name: 'libnpmsearch',
118    description: 'Programmatic API for searching in npm and compatible registries',
119    ...etc
120  },
121  ...more
122]
123```
124
125#### <a name="search-stream"></a> `> search.stream(query, [opts]) -> Stream`
126
127`query` must be either a String or an Array of search terms.
128
129If `opts.limit` is provided, it will be sent to the API to constrain the number
130of returned results. You may receive more, or fewer results, at the endpoint's
131discretion.
132
133The returned Stream emits one entry per search result, with each entry having
134the following format:
135
136```js
137{
138  name: String,
139  version: SemverString,
140  description: String || null,
141  maintainers: [
142    {
143      username: String,
144      email: String
145    },
146    ...etc
147  ] || null,
148  keywords: [String] || null,
149  date: Date || null
150}
151```
152
153For getting results in one chunk, see [`search`](#search-stream).
154
155##### Example
156
157```javascript
158search.stream('libnpm').on('data', console.log)
159=>
160// entry 1
161{
162  name: 'libnpm',
163  description: 'programmatic npm API',
164  ...etc
165}
166// entry 2
167{
168  name: 'libnpmsearch',
169  description: 'Programmatic API for searching in npm and compatible registries',
170  ...etc
171}
172// etc
173```
174