diff options
author | Nathan Fritz <fritzy@github.com> | 2021-12-16 21:01:56 +0300 |
---|---|---|
committer | Nathan Fritz <fritzy@github.com> | 2021-12-16 21:05:19 +0300 |
commit | d7265045730555c03b3142c004c7438e9577028c (patch) | |
tree | 035d81b3124bdaa09c21854934bf2b2b50e52e44 /workspaces/libnpmhook | |
parent | d8aac8448e983692cacb427e03f4688cd1b62e30 (diff) |
Bring in all libnpm modules + arborist as workspaces (#4166)
Added libnpm workspaces and arborist
Diffstat (limited to 'workspaces/libnpmhook')
-rw-r--r-- | workspaces/libnpmhook/.eslintrc.js | 14 | ||||
-rw-r--r-- | workspaces/libnpmhook/.gitignore | 23 | ||||
-rw-r--r-- | workspaces/libnpmhook/.npmrc | 3 | ||||
-rw-r--r-- | workspaces/libnpmhook/CHANGELOG.md | 110 | ||||
-rw-r--r-- | workspaces/libnpmhook/LICENSE.md | 16 | ||||
-rw-r--r-- | workspaces/libnpmhook/README.md | 271 | ||||
-rw-r--r-- | workspaces/libnpmhook/SECURITY.md | 3 | ||||
-rw-r--r-- | workspaces/libnpmhook/lib/index.js | 70 | ||||
-rw-r--r-- | workspaces/libnpmhook/package.json | 49 | ||||
-rw-r--r-- | workspaces/libnpmhook/test/fixtures/tnock.js | 12 | ||||
-rw-r--r-- | workspaces/libnpmhook/test/index.js | 267 |
11 files changed, 838 insertions, 0 deletions
diff --git a/workspaces/libnpmhook/.eslintrc.js b/workspaces/libnpmhook/.eslintrc.js new file mode 100644 index 000000000..022767bc3 --- /dev/null +++ b/workspaces/libnpmhook/.eslintrc.js @@ -0,0 +1,14 @@ +// This file is automatically added by @npmcli/template-oss. Do not edit. + +const { readdirSync: readdir } = require('fs') + +const localConfigs = readdir(__dirname) + .filter((file) => file.startsWith('.eslintrc.local.')) + .map((file) => `./${file}`) + +module.exports = { + extends: [ + '@npmcli', + ...localConfigs, + ], +} diff --git a/workspaces/libnpmhook/.gitignore b/workspaces/libnpmhook/.gitignore new file mode 100644 index 000000000..6ed44c72b --- /dev/null +++ b/workspaces/libnpmhook/.gitignore @@ -0,0 +1,23 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +# ignore everything in the root +/* + +# keep these +!/.commitlintrc.js +!/.npmrc +!/.eslintrc* +!/.github +!**/.gitignore +!/package.json +!/docs +!/bin +!/lib +!/map.js +!/tap-snapshots +!/test +!/scripts +!/README* +!/LICENSE* +!/SECURITY* +!/CHANGELOG* diff --git a/workspaces/libnpmhook/.npmrc b/workspaces/libnpmhook/.npmrc new file mode 100644 index 000000000..878b7ddef --- /dev/null +++ b/workspaces/libnpmhook/.npmrc @@ -0,0 +1,3 @@ +;This file is automatically added by @npmcli/template-oss. Do not edit. + +package-lock=false diff --git a/workspaces/libnpmhook/CHANGELOG.md b/workspaces/libnpmhook/CHANGELOG.md new file mode 100644 index 000000000..055727497 --- /dev/null +++ b/workspaces/libnpmhook/CHANGELOG.md @@ -0,0 +1,110 @@ +# Change Log + +<a name="6.0.0"></a> +# [6.0.0](https://github.com/npm/libnpmhook/compare/v5.0.2...v6.0.0) (2020-02-26) + +### Breaking Changes + +* [`aa629b4`](https://github.com/npm/libnpmhook/commit/aa629b4) fix: remove figgy-pudding ([@claudiahdz](https://github.com/claudiahdz)) + +### Miscellaneuous + +* [`ea795fb`](https://github.com/npm/libnpmhook/commit/ea795fb) chore: basic project updates ([@claudiahdz](https://github.com/claudiahdz)) +* [`a0fdf7e`](https://github.com/npm/libnpmhook/commit/a0fdf7e) chore: cleanup badges, contrib, readme ([@ruyadorno](https://github.com/ruyadorno)) + +--- + +All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. + +<a name="5.0.2"></a> +## [5.0.2](https://github.com/npm/libnpmhook/compare/v5.0.1...v5.0.2) (2018-08-24) + + + +<a name="5.0.1"></a> +## [5.0.1](https://github.com/npm/libnpmhook/compare/v5.0.0...v5.0.1) (2018-08-23) + + +### Bug Fixes + +* **deps:** move JSONStream to prod deps ([bb63594](https://github.com/npm/libnpmhook/commit/bb63594)) + + + +<a name="5.0.0"></a> +# [5.0.0](https://github.com/npm/libnpmhook/compare/v4.0.1...v5.0.0) (2018-08-21) + + +### Features + +* **api:** overhauled API ([46b271b](https://github.com/npm/libnpmhook/commit/46b271b)) + + +### BREAKING CHANGES + +* **api:** the API for ls() has changed, and rm() no longer errors on 404 + + + +<a name="4.0.1"></a> +## [4.0.1](https://github.com/npm/libnpmhook/compare/v4.0.0...v4.0.1) (2018-04-09) + + + +<a name="4.0.0"></a> +# [4.0.0](https://github.com/npm/libnpmhook/compare/v3.0.1...v4.0.0) (2018-04-08) + + +### meta + +* drop support for node 4 and 7 ([f2a301e](https://github.com/npm/libnpmhook/commit/f2a301e)) + + +### BREAKING CHANGES + +* node@4 and node@7 are no longer supported + + + +<a name="3.0.1"></a> +## [3.0.1](https://github.com/npm/libnpmhook/compare/v3.0.0...v3.0.1) (2018-04-08) + + + +<a name="3.0.0"></a> +# [3.0.0](https://github.com/npm/libnpmhook/compare/v2.0.1...v3.0.0) (2018-04-04) + + +### add + +* guess type based on name ([9418224](https://github.com/npm/libnpmhook/commit/9418224)) + + +### BREAKING CHANGES + +* hook type is now based on name prefix + + + +<a name="2.0.1"></a> +## [2.0.1](https://github.com/npm/libnpmhook/compare/v2.0.0...v2.0.1) (2018-03-16) + + +### Bug Fixes + +* **urls:** was hitting the wrong URL endpoints ([10171a9](https://github.com/npm/libnpmhook/commit/10171a9)) + + + +<a name="2.0.0"></a> +# [2.0.0](https://github.com/npm/libnpmhook/compare/v1.0.0...v2.0.0) (2018-03-16) + + + +<a name="1.0.0"></a> +# 1.0.0 (2018-03-16) + + +### Features + +* **api:** baseline working api ([122658e](https://github.com/npm/npm-hooks/commit/122658e)) diff --git a/workspaces/libnpmhook/LICENSE.md b/workspaces/libnpmhook/LICENSE.md new file mode 100644 index 000000000..8d28acf86 --- /dev/null +++ b/workspaces/libnpmhook/LICENSE.md @@ -0,0 +1,16 @@ +ISC License + +Copyright (c) npm, Inc. + +Permission to use, copy, modify, and/or distribute this software for +any purpose with or without fee is hereby granted, provided that the +above copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE COPYRIGHT HOLDER DISCLAIMS +ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE +USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/workspaces/libnpmhook/README.md b/workspaces/libnpmhook/README.md new file mode 100644 index 000000000..ce6e8c1a5 --- /dev/null +++ b/workspaces/libnpmhook/README.md @@ -0,0 +1,271 @@ +# libnpmhook + +[![npm version](https://img.shields.io/npm/v/libnpmhook.svg)](https://npm.im/libnpmhook) +[![license](https://img.shields.io/npm/l/libnpmhook.svg)](https://npm.im/libnpmhook) +[![Coverage Status](https://coveralls.io/repos/github/npm/libnpmhook/badge.svg?branch=latest)](https://coveralls.io/github/npm/libnpmhook?branch=latest) + +[`libnpmhook`](https://github.com/npm/libnpmhook) is a Node.js library for +programmatically managing the npm registry's server-side hooks. + +For a more general introduction to managing hooks, see [the introductory blog +post](https://blog.npmjs.org/post/145260155635/introducing-hooks-get-notifications-of-npm). + +## Table of Contents + +* [Example](#example) +* [Install](#install) +* [Contributing](#contributing) +* [API](#api) + * [hook opts](#opts) + * [`add()`](#add) + * [`rm()`](#rm) + * [`ls()`](#ls) + * [`ls.stream()`](#ls-stream) + * [`update()`](#update) + +## Example + +```js +const hooks = require('libnpmhook') + +console.log(await hooks.ls('mypkg', {token: 'deadbeef'})) +// array of hook objects on `mypkg`. +``` + +## Install + +`$ npm install libnpmhook` + +### API + +#### <a name="opts"></a> `opts` for `libnpmhook` commands + +`libnpmhook` uses [`npm-registry-fetch`](https://npm.im/npm-registry-fetch). +All options are passed through directly to that library, so please refer to [its +own `opts` +documentation](https://www.npmjs.com/package/npm-registry-fetch#fetch-options) +for options that can be passed in. + +A couple of options of note for those in a hurry: + +* `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. +* `opts.otp` - certain operations will require an OTP token to be passed in. If a `libnpmhook` command fails with `err.code === EOTP`, please retry the request with `{otp: <2fa token>}` + +#### <a name="add"></a> `> hooks.add(name, endpoint, secret, [opts]) -> Promise` + +`name` is the name of the package, org, or user/org scope to watch. The type is +determined by the name syntax: `'@foo/bar'` and `'foo'` are treated as packages, +`@foo` is treated as a scope, and `~user` is treated as an org name or scope. +Each type will attach to different events. + +The `endpoint` should be a fully-qualified http URL for the endpoint the hook +will send its payload to when it fires. `secret` is a shared secret that the +hook will send to that endpoint to verify that it's actually coming from the +registry hook. + +The returned Promise resolves to the full hook object that was created, +including its generated `id`. + +See also: [`POST +/v1/hooks/hook`](https://github.com/npm/registry/blob/master/docs/hooks/endpoints.md#post-v1hookshook) + +##### Example + +```javascript +await hooks.add('~zkat', 'https://example.com/api/added', 'supersekrit', { + token: 'myregistrytoken', + otp: '694207' +}) + +=> + +{ id: '16f7xoal', + username: 'zkat', + name: 'zkat', + endpoint: 'https://example.com/api/added', + secret: 'supersekrit', + type: 'owner', + created: '2018-08-21T20:05:25.125Z', + updated: '2018-08-21T20:05:25.125Z', + deleted: false, + delivered: false, + last_delivery: null, + response_code: 0, + status: 'active' } +``` + +#### <a name="find"></a> `> hooks.find(id, [opts]) -> Promise` + +Returns the hook identified by `id`. + +The returned Promise resolves to the full hook object that was found, or error +with `err.code` of `'E404'` if it didn't exist. + +See also: [`GET +/v1/hooks/hook/:id`](https://github.com/npm/registry/blob/master/docs/hooks/endpoints.md#get-v1hookshookid) + +##### Example + +```javascript +await hooks.find('16f7xoal', {token: 'myregistrytoken'}) + +=> + +{ id: '16f7xoal', + username: 'zkat', + name: 'zkat', + endpoint: 'https://example.com/api/added', + secret: 'supersekrit', + type: 'owner', + created: '2018-08-21T20:05:25.125Z', + updated: '2018-08-21T20:05:25.125Z', + deleted: false, + delivered: false, + last_delivery: null, + response_code: 0, + status: 'active' } +``` + +#### <a name="rm"></a> `> hooks.rm(id, [opts]) -> Promise` + +Removes the hook identified by `id`. + +The returned Promise resolves to the full hook object that was removed, if it +existed, or `null` if no such hook was there (instead of erroring). + +See also: [`DELETE +/v1/hooks/hook/:id`](https://github.com/npm/registry/blob/master/docs/hooks/endpoints.md#delete-v1hookshookid) + +##### Example + +```javascript +await hooks.rm('16f7xoal', { + token: 'myregistrytoken', + otp: '694207' +}) + +=> + +{ id: '16f7xoal', + username: 'zkat', + name: 'zkat', + endpoint: 'https://example.com/api/added', + secret: 'supersekrit', + type: 'owner', + created: '2018-08-21T20:05:25.125Z', + updated: '2018-08-21T20:05:25.125Z', + deleted: true, + delivered: false, + last_delivery: null, + response_code: 0, + status: 'active' } + +// Repeat it... +await hooks.rm('16f7xoal', { + token: 'myregistrytoken', + otp: '694207' +}) + +=> null +``` + +#### <a name="update"></a> `> hooks.update(id, endpoint, secret, [opts]) -> Promise` + +The `id` should be a hook ID from a previously-created hook. + +The `endpoint` should be a fully-qualified http URL for the endpoint the hook +will send its payload to when it fires. `secret` is a shared secret that the +hook will send to that endpoint to verify that it's actually coming from the +registry hook. + +The returned Promise resolves to the full hook object that was updated, if it +existed. Otherwise, it will error with an `'E404'` error code. + +See also: [`PUT +/v1/hooks/hook/:id`](https://github.com/npm/registry/blob/master/docs/hooks/endpoints.md#put-v1hookshookid) + +##### Example + +```javascript +await hooks.update('16fxoal', 'https://example.com/api/other', 'newsekrit', { + token: 'myregistrytoken', + otp: '694207' +}) + +=> + +{ id: '16f7xoal', + username: 'zkat', + name: 'zkat', + endpoint: 'https://example.com/api/other', + secret: 'newsekrit', + type: 'owner', + created: '2018-08-21T20:05:25.125Z', + updated: '2018-08-21T20:14:41.964Z', + deleted: false, + delivered: false, + last_delivery: null, + response_code: 0, + status: 'active' } +``` + +#### <a name="ls"></a> `> hooks.ls([opts]) -> Promise` + +Resolves to an array of hook objects associated with the account you're +authenticated as. + +Results can be further filtered with three values that can be passed in through +`opts`: + +* `opts.package` - filter results by package name +* `opts.limit` - maximum number of hooks to return +* `opts.offset` - pagination offset for results (use with `opts.limit`) + +See also: + * [`hooks.ls.stream()`](#ls-stream) + * [`GET +/v1/hooks`](https://github.com/npm/registry/blob/master/docs/hooks/endpoints.md#get-v1hooks) + +##### Example + +```javascript +await hooks.ls({token: 'myregistrytoken'}) + +=> +[ + { id: '16f7xoal', ... }, + { id: 'wnyf98a1', ... }, + ... +] +``` + +#### <a name="ls-stream"></a> `> hooks.ls.stream([opts]) -> Stream` + +Returns a stream of hook objects associated with the account you're +authenticated as. The returned stream is a valid `Symbol.asyncIterator` on +`node@>=10`. + +Results can be further filtered with three values that can be passed in through +`opts`: + +* `opts.package` - filter results by package name +* `opts.limit` - maximum number of hooks to return +* `opts.offset` - pagination offset for results (use with `opts.limit`) + +See also: + * [`hooks.ls()`](#ls) + * [`GET +/v1/hooks`](https://github.com/npm/registry/blob/master/docs/hooks/endpoints.md#get-v1hooks) + +##### Example + +```javascript +for await (let hook of hooks.ls.stream({token: 'myregistrytoken'})) { + console.log('found hook:', hook.id) +} + +=> +// outputs: +// found hook: 16f7xoal +// found hook: wnyf98a1 +``` diff --git a/workspaces/libnpmhook/SECURITY.md b/workspaces/libnpmhook/SECURITY.md new file mode 100644 index 000000000..a93106d0c --- /dev/null +++ b/workspaces/libnpmhook/SECURITY.md @@ -0,0 +1,3 @@ +<!-- This file is automatically added by @npmcli/template-oss. Do not edit. --> + +Please send vulnerability reports through [hackerone](https://hackerone.com/github). diff --git a/workspaces/libnpmhook/lib/index.js b/workspaces/libnpmhook/lib/index.js new file mode 100644 index 000000000..7cd18261d --- /dev/null +++ b/workspaces/libnpmhook/lib/index.js @@ -0,0 +1,70 @@ +'use strict' + +const fetch = require('npm-registry-fetch') +const validate = require('aproba') + +const eu = encodeURIComponent +const cmd = module.exports = {} +cmd.add = (name, endpoint, secret, opts = {}) => { + validate('SSSO', [name, endpoint, secret, opts]) + let type = 'package' + if (name.match(/^@[^/]+$/)) { + type = 'scope' + } + if (name[0] === '~') { + type = 'owner' + name = name.substr(1) + } + return fetch.json('/-/npm/v1/hooks/hook', { + ...opts, + method: 'POST', + body: { type, name, endpoint, secret }, + }) +} + +cmd.rm = (id, opts = {}) => { + validate('SO', [id, opts]) + return fetch.json(`/-/npm/v1/hooks/hook/${eu(id)}`, { + ...opts, + method: 'DELETE', + }).catch(err => { + if (err.code === 'E404') { + return null + } else { + throw err + } + }) +} + +cmd.update = (id, endpoint, secret, opts = {}) => { + validate('SSSO', [id, endpoint, secret, opts]) + return fetch.json(`/-/npm/v1/hooks/hook/${eu(id)}`, { + ...opts, + method: 'PUT', + body: { endpoint, secret }, + }) +} + +cmd.find = (id, opts = {}) => { + validate('SO', [id, opts]) + return fetch.json(`/-/npm/v1/hooks/hook/${eu(id)}`, opts) +} + +cmd.ls = (opts = {}) => { + return cmd.ls.stream(opts).collect() +} + +cmd.ls.stream = (opts = {}) => { + const { package: pkg, limit, offset } = opts + validate('S|Z', [pkg]) + validate('N|Z', [limit]) + validate('N|Z', [offset]) + return fetch.json.stream('/-/npm/v1/hooks', 'objects.*', { + ...opts, + query: { + package: pkg, + limit, + offset, + }, + }) +} diff --git a/workspaces/libnpmhook/package.json b/workspaces/libnpmhook/package.json new file mode 100644 index 000000000..4580aea64 --- /dev/null +++ b/workspaces/libnpmhook/package.json @@ -0,0 +1,49 @@ +{ + "name": "libnpmhook", + "version": "7.0.0", + "description": "programmatic API for managing npm registry hooks", + "main": "lib/index.js", + "files": [ + "bin", + "lib" + ], + "scripts": { + "prerelease": "npm t", + "postrelease": "npm publish && git push --follow-tags", + "test": "tap", + "lint": "eslint '**/*.js'", + "postlint": "npm-template-check", + "lintfix": "npm run lint -- --fix", + "preversion": "npm test", + "postversion": "npm publish", + "prepublishOnly": "git push origin --follow-tags", + "snap": "tap", + "posttest": "npm run lint" + }, + "tap": { + "check-coverage": true + }, + "repository": "https://github.com/npm/libnpmhook", + "keywords": [ + "npm", + "hooks", + "registry", + "npm api" + ], + "author": "GitHub Inc.", + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^11.0.0" + }, + "devDependencies": { + "nock": "^9.6.1", + "tap": "^15.1.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16" + }, + "templateOSS": { + "version": "2.4.1" + } +} diff --git a/workspaces/libnpmhook/test/fixtures/tnock.js b/workspaces/libnpmhook/test/fixtures/tnock.js new file mode 100644 index 000000000..048639a50 --- /dev/null +++ b/workspaces/libnpmhook/test/fixtures/tnock.js @@ -0,0 +1,12 @@ +'use strict' + +const nock = require('nock') + +module.exports = tnock +function tnock (t, host) { + const server = nock(host) + t.teardown(function () { + server.done() + }) + return server +} diff --git a/workspaces/libnpmhook/test/index.js b/workspaces/libnpmhook/test/index.js new file mode 100644 index 000000000..7ca3b06ae --- /dev/null +++ b/workspaces/libnpmhook/test/index.js @@ -0,0 +1,267 @@ +'use strict' + +const test = require('tap').test +const tnock = require('./fixtures/tnock.js') + +const hooks = require('../lib/index.js') + +const OPTS = { + registry: 'https://mock.reg/', +} + +const HOOK_URL = 'https://my.hook.url/' +const REG = 'https://registry.npmjs.org/' + +test('add package hook with no options', t => { + const params = { + type: 'package', + name: 'mypkg', + endpoint: HOOK_URL, + secret: 'sekrit', + } + const hook = Object.assign({ + id: 'deadbeef', + status: 'active', + }, params) + tnock(t, REG) + .post('/-/npm/v1/hooks/hook', params) + .reply(200, hook) + return hooks.add('mypkg', HOOK_URL, 'sekrit') + .then(json => t.same(json, hook)) +}) + +test('add package hook', t => { + const params = { + type: 'package', + name: 'mypkg', + endpoint: HOOK_URL, + secret: 'sekrit', + } + const hook = Object.assign({ + id: 'deadbeef', + status: 'active', + }, params) + tnock(t, OPTS.registry) + .post('/-/npm/v1/hooks/hook', params) + .reply(200, hook) + return hooks.add('mypkg', HOOK_URL, 'sekrit', OPTS) + .then(json => t.same(json, hook)) +}) + +test('add scoped package hook', t => { + const params = { + type: 'package', + name: '@myscope/mypkg', + endpoint: HOOK_URL, + secret: 'sekrit', + } + const hook = Object.assign({ + id: 'deadbeef', + status: 'active', + }, params) + tnock(t, OPTS.registry) + .post('/-/npm/v1/hooks/hook', params) + .reply(200, hook) + return hooks.add('@myscope/mypkg', HOOK_URL, 'sekrit', OPTS) + .then(json => t.same(json, hook)) +}) + +test('add owner hook', t => { + const params = { + type: 'owner', + name: 'myuser', + endpoint: HOOK_URL, + secret: 'sekrit', + } + const hook = Object.assign({ + id: 'deadbeef', + status: 'active', + }, params) + tnock(t, OPTS.registry) + .post('/-/npm/v1/hooks/hook', params) + .reply(200, hook) + return hooks.add('~myuser', HOOK_URL, 'sekrit', OPTS) + .then(json => t.same(json, hook)) +}) + +test('add scope hook', t => { + const params = { + type: 'scope', + name: '@myscope', + endpoint: HOOK_URL, + secret: 'sekrit', + } + const hook = Object.assign({ + id: 'deadbeef', + status: 'active', + }, params) + tnock(t, OPTS.registry) + .post('/-/npm/v1/hooks/hook', params) + .reply(200, hook) + return hooks.add('@myscope', HOOK_URL, 'sekrit', OPTS) + .then(json => t.same(json, hook)) +}) + +test('rm with no options', t => { + tnock(t, REG) + .delete('/-/npm/v1/hooks/hook/hithere') + .reply(200, { id: 'hithere' }) + return hooks.rm('hithere') + .then(json => t.equal(json.id, 'hithere')) +}) + +test('rm', t => { + tnock(t, OPTS.registry) + .delete('/-/npm/v1/hooks/hook/hithere') + .reply(200, { id: 'hithere' }) + return hooks.rm('hithere', OPTS) + .then(json => t.equal(json.id, 'hithere')) +}) + +test('rm null on 404', t => { + tnock(t, OPTS.registry) + .delete('/-/npm/v1/hooks/hook/hithere') + .reply(404) + return hooks.rm('hithere', OPTS) + .then(json => t.equal(json, null)) +}) + +test('rm null on other err', t => { + tnock(t, OPTS.registry) + .delete('/-/npm/v1/hooks/hook/hithere') + .reply(401) + return hooks.rm('hithere', OPTS).then( + () => { + throw new Error('should not succees') + }, + err => t.equal(err.code, 'E401', 'got a proper error + code') + ) +}) + +test('find with no options', t => { + tnock(t, REG) + .get('/-/npm/v1/hooks/hook/hithere') + .reply(200, { id: 'hithere' }) + return hooks.find('hithere') + .then(json => t.equal(json.id, 'hithere')) +}) + +test('find', t => { + tnock(t, OPTS.registry) + .get('/-/npm/v1/hooks/hook/hithere') + .reply(200, { id: 'hithere' }) + return hooks.find('hithere', OPTS) + .then(json => t.equal(json.id, 'hithere')) +}) + +test('ls', t => { + const entries = [ + { id: 'first' }, + { id: 'second' }, + { id: 'third' }, + ] + tnock(t, REG) + .get('/-/npm/v1/hooks') + .reply(200, { objects: entries }) + return hooks.ls().then( + json => t.same(json, entries) + ) +}) + +test('ls.stream', t => { + const entries = [ + { id: 'first' }, + { id: 'second' }, + { id: 'third' }, + ] + tnock(t, REG) + .get('/-/npm/v1/hooks') + .reply(200, { objects: entries }) + + return hooks.ls.stream().collect().then( + json => t.same(json, entries) + ) +}) + +test('ls', t => { + const entries = [ + { id: 'first' }, + { id: 'second' }, + { id: 'third' }, + ] + tnock(t, OPTS.registry) + .get('/-/npm/v1/hooks') + .reply(200, { objects: entries }) + return hooks.ls(OPTS).then( + json => t.same(json, entries) + ) +}) + +test('ls package', t => { + const entries = [ + { id: 'first' }, + { id: 'second' }, + { id: 'third' }, + ] + tnock(t, OPTS.registry) + .get('/-/npm/v1/hooks?package=%40npm%2Fhooks') + .reply(200, { objects: entries }) + return hooks.ls({ + ...OPTS, + package: '@npm/hooks', + }).then(json => t.same(json, entries)) +}) + +test('ls limit+offset', t => { + const entries = [ + { id: 'first' }, + { id: 'second' }, + { id: 'third' }, + ] + tnock(t, OPTS.registry) + .get('/-/npm/v1/hooks?limit=10&offset=20') + .reply(200, { objects: entries }) + return hooks.ls({ + ...OPTS, + limit: 10, + offset: 20, + }).then(json => t.same(json, entries)) +}) + +test('ls package+limit+offset', t => { + const entries = [ + { id: 'first' }, + { id: 'second' }, + { id: 'third' }, + ] + tnock(t, OPTS.registry) + .get('/-/npm/v1/hooks?package=%40npm%2Fhooks&limit=10&offset=20') + .reply(200, { objects: entries }) + return hooks.ls({ + ...OPTS, + limit: 10, + offset: 20, + package: '@npm/hooks', + }).then(json => t.same(json, entries)) +}) +test('update with no options', t => { + tnock(t, REG) + .put('/-/npm/v1/hooks/hook/hi') + .reply(200, (uri, body) => body) + return hooks.update('hi', HOOK_URL, 'sekrit') + .then(json => t.same(json, { + endpoint: HOOK_URL, + secret: 'sekrit', + })) +}) + +test('update', t => { + tnock(t, OPTS.registry) + .put('/-/npm/v1/hooks/hook/hi') + .reply(200, (uri, body) => body) + return hooks.update('hi', HOOK_URL, 'sekrit', OPTS) + .then(json => t.same(json, { + endpoint: HOOK_URL, + secret: 'sekrit', + })) +}) |