diff --git a/README.md b/README.md index 589629f..2c0d381 100644 --- a/README.md +++ b/README.md @@ -200,6 +200,17 @@ hubspot.contacts.properties.deleteGroup(name) hubspot.contacts.properties.delete(name) ``` +### CRM associations + +```javascript +hubspot.crm.associations.create(data) +hubspot.crm.associations.createBatch(data) +hubspot.crm.associations.delete(data) +hubspot.crm.associations.deleteBatch(data) +// not an official API, wrapper doing two API calls. Callbacks not supported at +// this time +``` + ### Pages ```javascript @@ -217,6 +228,7 @@ hubspot.deals.getById(id) hubspot.deals.getAssociated(objectType, objectId, opts) hubspot.deals.deleteById(id) hubspot.deals.updateById(id, data) +hubspot.deals.updateBatch(data) hubspot.deals.create(data) hubspot.deals.associate(id, objectType, associatedObjectId) hubspot.deals.removeAssociation(id, objectType, associatedObjectId) diff --git a/contributing.md b/contributing.md index 5632649..186d0b2 100644 --- a/contributing.md +++ b/contributing.md @@ -3,7 +3,7 @@ Before submitting a pull request, please make sure the following is done: 1. Fork the repository and create your branch from master. -2. Run `npm build`. This will: +2. Run `npm run build`. This will: 1. Run `npm install` in the repository root. 2. Ensure the test suite passes with `npm test`. 3. Format your code with prettier and eslint using `npm run lint`. diff --git a/index.d.ts b/index.d.ts index fcdd7f9..b0af4a9 100644 --- a/index.d.ts +++ b/index.d.ts @@ -18,18 +18,35 @@ import { File } from './lib/typescript/file' import { Subscription } from './lib/typescript/subscription' import { Campaign } from './lib/typescript/campaign' import { Broadcast } from './lib/typescript/broadcast' +import { CRM } from './lib/typescript/crm' import { Emails } from './lib/typescript/emails' - interface BaseOptions { baseUrl?: string } -export interface ApiOptions extends BaseOptions { +export interface BottleneckOptions { + maxConcurrent?: number | null; + minTime?: number; + highWater?: number | null; + reservoir?: number | null; + reservoirRefreshInterval?: number | null; + reservoirRefreshAmount?: number | null; + reservoirIncreaseInterval?: number | null; + reservoirIncreaseAmount?: number | null; + reservoirIncreaseMaximum?: number | null; + [key: string]: any; +} + +export interface LimiterOptions { + limiter?: BottleneckOptions +} + +export interface ApiOptions extends BaseOptions, LimiterOptions { apiKey: string } -export interface AccessTokenOptions extends BaseOptions { +export interface AccessTokenOptions extends BaseOptions, LimiterOptions { accessToken: string } @@ -63,6 +80,7 @@ declare class Hubspot { subscriptions: Subscription campaigns: Campaign broadcasts: Broadcast + crm: CRM emails: Emails } diff --git a/lib/client.js b/lib/client.js index 2db04b1..80e9e63 100644 --- a/lib/client.js +++ b/lib/client.js @@ -2,6 +2,7 @@ const Broadcast = require('./broadcast') const Campaign = require('./campaign') const Company = require('./company') const Contact = require('./contact') +const CRM = require('./crm') const Page = require('./page') const Deal = require('./deal') const Engagement = require('./engagement') @@ -38,7 +39,7 @@ class Client extends EventEmitter { typeof options.maxUsePercent !== 'undefined' ? options.maxUsePercent : MAX_USE_PERCENT_DEFAULT - this.baseUrl = options.baseUrl || 'http://api.hubapi.com' + this.baseUrl = options.baseUrl || 'https://api.hubapi.com' this.apiTimeout = options.timeout || API_TIMEOUT this.apiCalls = 0 this.on('apiCall', params => { @@ -75,6 +76,7 @@ class Client extends EventEmitter { this.timelines = new Timeline(this) this.subscriptions = new Subscription(this) this.workflows = new Workflow(this) + this.crm = new CRM(this) } requestStats() { diff --git a/lib/company.js b/lib/company.js index 8a03e34..026153b 100644 --- a/lib/company.js +++ b/lib/company.js @@ -46,8 +46,8 @@ class Company { getByDomain(domain) { return this.client._request({ - method: 'GET', - path: '/companies/v2/companies/domain/' + domain, + method: 'POST', + path: `/companies/v2/domains/${domain}/companies`, }) } diff --git a/lib/crm.js b/lib/crm.js new file mode 100644 index 0000000..5476904 --- /dev/null +++ b/lib/crm.js @@ -0,0 +1,10 @@ +const Associations = require('./crm_association') + +class CRM { + constructor(client) { + this.client = client + this.associations = new Associations(this.client) + } +} + +module.exports = CRM diff --git a/lib/crm_association.js b/lib/crm_association.js new file mode 100644 index 0000000..719666d --- /dev/null +++ b/lib/crm_association.js @@ -0,0 +1,39 @@ +class Associations { + constructor(client) { + this.client = client + } + + create(data) { + return this.client._request({ + method: 'PUT', + path: '/crm-associations/v1/associations', + body: data, + }) + } + + createBatch(data) { + return this.client._request({ + method: 'PUT', + path: '/crm-associations/v1/associations/create-batch', + body: data, + }) + } + + delete(data) { + return this.client._request({ + method: 'PUT', + path: '/crm-associations/v1/associations/delete', + body: data, + }) + } + + deleteBatch(data) { + return this.client._request({ + method: 'PUT', + path: '/crm-associations/v1/associations/delete-batch', + body: data, + }) + } +} + +module.exports = Associations diff --git a/lib/deal.js b/lib/deal.js index 3bcd312..2217204 100644 --- a/lib/deal.js +++ b/lib/deal.js @@ -63,6 +63,14 @@ class Deal { }) } + updateBatch(data) { + return this.client._request({ + method: 'POST', + path: '/deals/v1/batch-async/update', + body: data, + }) + } + create(data) { return this.client._request({ method: 'POST', diff --git a/lib/oauth.js b/lib/oauth.js index 04202ff..76e52ea 100644 --- a/lib/oauth.js +++ b/lib/oauth.js @@ -51,6 +51,13 @@ class OAuth { return results }) } + + getPortalInfo() { + return this.client._request({ + method: 'GET', + path: `/oauth/v1/access-tokens/${this.client.accessToken}` + }) + } } module.exports = OAuth diff --git a/lib/timeline.js b/lib/timeline.js index 5a47814..1b2fe95 100644 --- a/lib/timeline.js +++ b/lib/timeline.js @@ -6,7 +6,7 @@ class Timeline { } createEventType(applicationId, userId, data) { - data['applicationId'] = data['applicationId'] || applicationId + data.applicationId = data.applicationId || applicationId const parameters = { method: 'POST', path: `/integrations/v1/${applicationId}/timeline/event-types?userId=${userId}`, @@ -16,7 +16,7 @@ class Timeline { } updateEventType(applicationId, eventTypeId, data) { - data['applicationId'] = data['applicationId'] || applicationId + data.applicationId = data.applicationId || applicationId const parameters = { method: 'PUT', path: `/integrations/v1/${applicationId}/timeline/event-types/${eventTypeId}`, @@ -37,7 +37,7 @@ class Timeline { } updateEventTypeProperty(applicationId, eventTypeId, propertyId, data) { - data['id'] = data['id'] || propertyId + data.id = data.id || propertyId const parameters = { method: 'PUT', path: `/integrations/v1/${applicationId}/timeline/event-types/${eventTypeId}/properties`, diff --git a/lib/typescript/contact.ts b/lib/typescript/contact.ts index 4f48154..a07da27 100644 --- a/lib/typescript/contact.ts +++ b/lib/typescript/contact.ts @@ -26,7 +26,7 @@ declare class Contact { getRecentlyModified(opts: {}): RequestPromise - createOrUpdate(email: string, data: any[]): RequestPromise + createOrUpdate(email: string, data: {}): RequestPromise delete(id: number): RequestPromise diff --git a/lib/typescript/crm.ts b/lib/typescript/crm.ts new file mode 100644 index 0000000..e770e97 --- /dev/null +++ b/lib/typescript/crm.ts @@ -0,0 +1,7 @@ +import { Associations } from './crm_associations' + +declare class CRM { + associations: Associations +} + +export { CRM } diff --git a/lib/typescript/crm_associations.ts b/lib/typescript/crm_associations.ts new file mode 100644 index 0000000..e058abf --- /dev/null +++ b/lib/typescript/crm_associations.ts @@ -0,0 +1,20 @@ +import { RequestPromise } from 'request-promise' + +export interface IHubspotCRMAssociation { + fromObjectId: number + toObjectId: number + category: string + definitionId: number +} + +declare class Associations { + create(data: IHubspotCRMAssociation): RequestPromise + + createBatch(data: IHubspotCRMAssociation[]): RequestPromise + + delete(data: IHubspotCRMAssociation): RequestPromise + + deleteBatch(data: IHubspotCRMAssociation[]): RequestPromise +} + +export { Associations } diff --git a/lib/typescript/deal.ts b/lib/typescript/deal.ts index 9311c40..9aaff49 100644 --- a/lib/typescript/deal.ts +++ b/lib/typescript/deal.ts @@ -18,6 +18,8 @@ declare class Deal { create(data: {}): RequestPromise + updateBatch(data: {}[]): RequestPromise + associate( id: number, objectType: string, diff --git a/package-lock.json b/package-lock.json index 414d4d7..521a8df 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "hubspot", - "version": "2.2.1", + "version": "2.3.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -134,9 +134,9 @@ "dev": true }, "@types/node": { - "version": "10.14.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.5.tgz", - "integrity": "sha512-Ja7d4s0qyGFxjGeDq5S7Si25OFibSAHUi6i17UWnwNnpitADN7hah9q0Tl25gxuV5R1u2Bx+np6w4LHXfHyj/g==", + "version": "12.7.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.11.tgz", + "integrity": "sha512-Otxmr2rrZLKRYIybtdG/sgeO+tHY20GxeDjcGmUnmmlCWyEnv2a2x1ZXBo3BTec4OiTXMQCiazB8NMBf0iRlFw==", "dev": true }, "@types/request": { @@ -181,15 +181,15 @@ "dev": true }, "acorn": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", - "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", + "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==", "dev": true }, "acorn-jsx": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz", - "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.2.tgz", + "integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==", "dev": true }, "ajv": { @@ -245,6 +245,12 @@ "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, + "arg": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.1.tgz", + "integrity": "sha512-SlmP3fEA88MBv0PypnXZ8ZfJhwmDeIE3SP71j37AiXQBXYosPV0x6uISAaHYSlSVhmHOVkomen0tbGk6Anlebw==", + "dev": true + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -264,12 +270,6 @@ "es-abstract": "^1.7.0" } }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", @@ -330,9 +330,9 @@ "integrity": "sha512-FG+nFEZChJrbQ9tIccIfZJBz3J7mLrAhxakAbnrJWn8d7aKOC+LWifa0G+p4ZqKp4y13T7juYvdhq9NzKdsrjw==" }, "bottleneck": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.18.0.tgz", - "integrity": "sha512-U1xiBRaokw4yEguzikOl0VrnZp6uekjpmfrh6rKtr1D+/jFjYCL6J83ZXlGtlBDwVdTmJJ+4Lg5FpB3xmLSiyA==" + "version": "2.19.5", + "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", + "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==" }, "brace-expansion": { "version": "1.1.11", @@ -560,13 +560,55 @@ } }, "cross-env": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-5.2.0.tgz", - "integrity": "sha512-jtdNFfFW1hB7sMhr/H6rW1Z45LFqyI431m3qU6bFXcQ3Eh7LtBuG3h74o7ohHZ3crrRkkqHlo4jYHFPcjroANg==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-6.0.3.tgz", + "integrity": "sha512-+KqxF6LCvfhWvADcDPqo64yVIB31gv/jQulX2NGzKS/g3GEVz6/pt4wjHFtFWsHMddebWD/sDthJemzM4MaAag==", "dev": true, "requires": { - "cross-spawn": "^6.0.5", - "is-windows": "^1.0.0" + "cross-spawn": "^7.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz", + "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "path-key": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.0.tgz", + "integrity": "sha512-8cChqz0RP6SHJkMt48FW0A7+qUOn+OsnOsVtzI59tZ8m+5bCSk7hzwET0pulwOM2YMn9J1efb07KB9l9f30SGg==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "which": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.1.tgz", + "integrity": "sha512-N7GBZOTswtB9lkQBZA4+zAXrjEIWAUOB93AvzUiudRzRxhUdLURQ7D/gAIMY1gatT/LTbmbcv8SiYazy3eYB7w==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } } }, "cross-spawn": { @@ -658,9 +700,9 @@ } }, "dotenv": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.2.0.tgz", - "integrity": "sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.1.0.tgz", + "integrity": "sha512-GUE3gqcDCaMltj2++g6bRQ5rBJWtkWTmqmD0fo1RnnMuUqHNCt2oTPeDnS9n6fKYvlhn7AeBkb38lymBtWBQdA==", "dev": true }, "ecc-jsbn": { @@ -725,62 +767,92 @@ "dev": true }, "eslint": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", - "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.5.1.tgz", + "integrity": "sha512-32h99BoLYStT1iq1v2P9uwpyznQ4M2jRiFB6acitKz52Gqn+vPaMDUTB1bYi1WN4Nquj2w+t+bimYUG83DC55A==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "ajv": "^6.9.1", + "ajv": "^6.10.0", "chalk": "^2.1.0", "cross-spawn": "^6.0.5", "debug": "^4.0.1", "doctrine": "^3.0.0", - "eslint-scope": "^4.0.3", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^5.0.1", + "eslint-scope": "^5.0.0", + "eslint-utils": "^1.4.2", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.1.1", "esquery": "^1.0.1", "esutils": "^2.0.2", "file-entry-cache": "^5.0.1", "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", + "glob-parent": "^5.0.0", "globals": "^11.7.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^6.2.2", - "js-yaml": "^3.13.0", + "inquirer": "^6.4.1", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.3.0", - "lodash": "^4.17.11", + "lodash": "^4.17.14", "minimatch": "^3.0.4", "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", "progress": "^2.0.0", "regexpp": "^2.0.1", - "semver": "^5.5.1", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", + "semver": "^6.1.2", + "strip-ansi": "^5.2.0", + "strip-json-comments": "^3.0.1", "table": "^5.2.3", - "text-table": "^0.2.0" + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "strip-json-comments": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "dev": true + } } }, "eslint-config-prettier": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-3.6.0.tgz", - "integrity": "sha512-ixJ4U3uTLXwJts4rmSVW/lMXjlGwCijhBJHk8iVqKKSifeI0qgFEfWl8L63isfc8Od7EiBALF6BX3jKLluf/jQ==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.4.0.tgz", + "integrity": "sha512-YrKucoFdc7SEko5Sxe4r6ixqXPDP1tunGw91POeZTTRKItf/AMFYt/YLEQtZMkR2LVpAVhcAcZgcWpm1oGPW7w==", "dev": true, "requires": { "get-stdin": "^6.0.0" } }, "eslint-config-standard": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-12.0.0.tgz", - "integrity": "sha512-COUz8FnXhqFitYj4DTqHzidjIL/t4mumGZto5c7DrBpvWoie+Sn3P4sLEzUGeYhRElWuFEf8K1S1EfvD1vixCQ==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-14.1.0.tgz", + "integrity": "sha512-EF6XkrrGVbvv8hL/kYa/m6vnvmUT+K82pJJc4JJVMM6+Qgqh0pnwprSxdduDLB9p/7bIxD+YV5O0wfb8lmcPbA==", "dev": true }, "eslint-import-resolver-node": { @@ -811,9 +883,9 @@ } }, "eslint-module-utils": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.0.tgz", - "integrity": "sha512-14tltLm38Eu3zS+mt0KvILC3q8jyIAH518MlG+HO0p+yK885Lb1UHTY/UgR91eOyGdmxAPb+OLoW4znqIT6Ndw==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.1.tgz", + "integrity": "sha512-H6DOj+ejw7Tesdgbfs4jeS4YMFrT8uI8xwd1gtQqXssaR0EQ26L+2O/w6wkYFy2MymON0fTwHmXBvvfLNZVZEw==", "dev": true, "requires": { "debug": "^2.6.8", @@ -838,19 +910,27 @@ } }, "eslint-plugin-es": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-1.4.0.tgz", - "integrity": "sha512-XfFmgFdIUDgvaRAlaXUkxrRg5JSADoRC8IkKLc/cISeR3yHVMefFHQZpcyXXEUUPHfy5DwviBcrfqlyqEwlQVw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-2.0.0.tgz", + "integrity": "sha512-f6fceVtg27BR02EYnBhgWLFQfK6bN4Ll0nQFrBHOlCsAyxeZkn0NHns5O0YZOPrV1B3ramd6cgFwaoFLcSkwEQ==", "dev": true, "requires": { - "eslint-utils": "^1.3.0", - "regexpp": "^2.0.1" + "eslint-utils": "^1.4.2", + "regexpp": "^3.0.0" + }, + "dependencies": { + "regexpp": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.0.0.tgz", + "integrity": "sha512-Z+hNr7RAVWxznLPuA7DIh8UNX1j9CDrUQxskw9IrBE1Dxue2lyXT+shqEIeLUjrokxIP8CMy1WkjgG3rTsd5/g==", + "dev": true + } } }, "eslint-plugin-import": { - "version": "2.17.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.17.2.tgz", - "integrity": "sha512-m+cSVxM7oLsIpmwNn2WXTJoReOF9f/CtLMo7qOVmKd1KntBy0hEcuNZ3erTmWjx+DxRO0Zcrm5KwAvI9wHcV5g==", + "version": "2.18.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.18.2.tgz", + "integrity": "sha512-5ohpsHAiUBRNaBWAF08izwUGlbrJoJJ+W9/TBwsGoR1MnlgfwMIKrFeSjWbt6moabiXW9xNvtFz+97KHRfI4HQ==", "dev": true, "requires": { "array-includes": "^3.0.3", @@ -860,10 +940,10 @@ "eslint-import-resolver-node": "^0.3.2", "eslint-module-utils": "^2.4.0", "has": "^1.0.3", - "lodash": "^4.17.11", "minimatch": "^3.0.4", + "object.values": "^1.1.0", "read-pkg-up": "^2.0.0", - "resolve": "^1.10.0" + "resolve": "^1.11.0" }, "dependencies": { "debug": { @@ -890,48 +970,71 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true + }, + "resolve": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", + "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } } } }, "eslint-plugin-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-7.0.1.tgz", - "integrity": "sha512-lfVw3TEqThwq0j2Ba/Ckn2ABdwmL5dkOgAux1rvOk6CO7A6yGyPI2+zIxN6FyNkp1X1X/BSvKOceD6mBWSj4Yw==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-10.0.0.tgz", + "integrity": "sha512-1CSyM/QCjs6PXaT18+zuAXsjXGIGo5Rw630rSKwokSs2jrYURQc4R5JZpoanNCqwNmepg+0eZ9L7YiRUJb8jiQ==", "dev": true, "requires": { - "eslint-plugin-es": "^1.3.1", - "eslint-utils": "^1.3.1", - "ignore": "^4.0.2", + "eslint-plugin-es": "^2.0.0", + "eslint-utils": "^1.4.2", + "ignore": "^5.1.1", "minimatch": "^3.0.4", - "resolve": "^1.8.1", - "semver": "^5.5.0" + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "dependencies": { + "ignore": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", + "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "eslint-plugin-prettier": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.0.1.tgz", - "integrity": "sha512-/PMttrarPAY78PLvV3xfWibMOdMDl57hmlQ2XqFeA37wd+CJ7WSxV7txqjVPHi/AAFKd2lX0ZqfsOc/i5yFCSQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.1.tgz", + "integrity": "sha512-A+TZuHZ0KU0cnn56/9mfR7/KjUJ9QNVXUhwvRFSR7PGPe0zQR6PTkmyqg1AtUUEOzTqeRsUwyKFh0oVZKVCrtA==", "dev": true, "requires": { "prettier-linter-helpers": "^1.0.0" } }, "eslint-plugin-promise": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.1.1.tgz", - "integrity": "sha512-faAHw7uzlNPy7b45J1guyjazw28M+7gJokKUjC5JSFoYfUEyy6Gw/i7YQvmv2Yk00sUjWcmzXQLpU1Ki/C2IZQ==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz", + "integrity": "sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==", "dev": true }, "eslint-plugin-standard": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.0.0.tgz", - "integrity": "sha512-OwxJkR6TQiYMmt1EsNRMe5qG3GsbjlcOhbGUBY4LtavF9DsLaTcoR+j2Tdjqi23oUwKNUqX7qcn5fPStafMdlA==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.0.1.tgz", + "integrity": "sha512-v/KBnfyaOMPmZc/dmc6ozOdWqekGp7bBGq4jLAecEfPGmfKiWS4sA8sC0LqiV9w5qmXAtXVn4M3p1jSyhY85SQ==", "dev": true }, "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", + "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", "dev": true, "requires": { "esrecurse": "^4.1.0", @@ -939,26 +1042,29 @@ } }, "eslint-utils": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", - "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", - "dev": true + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz", + "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.0.0" + } }, "eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", + "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", "dev": true }, "espree": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", - "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.1.tgz", + "integrity": "sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ==", "dev": true, "requires": { - "acorn": "^6.0.7", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.0.0" + "acorn": "^7.0.0", + "acorn-jsx": "^5.0.2", + "eslint-visitor-keys": "^1.1.0" } }, "esprima": { @@ -986,9 +1092,9 @@ } }, "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true }, "esutils": { @@ -1003,9 +1109,9 @@ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, "external-editor": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", - "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "dev": true, "requires": { "chardet": "^0.7.0", @@ -1153,9 +1259,9 @@ } }, "flatted": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz", - "integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", + "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", "dev": true }, "foreground-child": { @@ -1253,6 +1359,15 @@ "path-is-absolute": "^1.0.0" } }, + "glob-parent": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, "globals": { "version": "11.11.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", @@ -1373,9 +1488,9 @@ "dev": true }, "import-fresh": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.0.0.tgz", - "integrity": "sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", + "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==", "dev": true, "requires": { "parent-module": "^1.0.0", @@ -1405,9 +1520,9 @@ "dev": true }, "inquirer": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.3.1.tgz", - "integrity": "sha512-MmL624rfkFt4TG9y/Jvmt8vdmOo836U7Y0Hxr2aFk3RelZEGX4Igk0KabWrcaaZaTv9uzglOqWh1Vly+FAWAXA==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", + "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", "dev": true, "requires": { "ansi-escapes": "^3.2.0", @@ -1416,7 +1531,7 @@ "cli-width": "^2.0.0", "external-editor": "^3.0.3", "figures": "^2.0.0", - "lodash": "^4.17.11", + "lodash": "^4.17.12", "mute-stream": "0.0.7", "run-async": "^2.2.0", "rxjs": "^6.4.0", @@ -1466,12 +1581,27 @@ "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", "dev": true }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, "is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", @@ -1507,12 +1637,6 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -2031,7 +2155,7 @@ "dependencies": { "find-up": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "resolved": false, "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { @@ -2040,7 +2164,7 @@ }, "locate-path": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "resolved": false, "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "requires": { @@ -2059,7 +2183,7 @@ }, "p-locate": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "resolved": false, "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "requires": { @@ -2107,6 +2231,18 @@ "es-abstract": "^1.5.1" } }, + "object.values": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz", + "integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.12.0", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -2235,12 +2371,6 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", @@ -2295,9 +2425,9 @@ "dev": true }, "prettier": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.17.0.tgz", - "integrity": "sha512-sXe5lSt2WQlCbydGETgfm1YBShgOX4HxQkFPvbxkcwgDvGDeqVau8h+12+lmSVlP3rHPz0oavfddSZg/q+Szjw==", + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.18.2.tgz", + "integrity": "sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw==", "dev": true }, "prettier-linter-helpers": { @@ -2480,9 +2610,9 @@ } }, "rxjs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.1.tgz", - "integrity": "sha512-y0j31WJc83wPu31vS1VlAFW5JGrnGC+j+TtGAa1fRQphy48+fDYiDmX8tjGloToEsMkxnouOg/1IzXGKkJnZMg==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", + "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", "dev": true, "requires": { "tslib": "^1.9.0" @@ -2549,9 +2679,9 @@ "dev": true }, "source-map-support": { - "version": "0.5.12", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", - "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==", + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "dev": true, "requires": { "buffer-from": "^1.0.0", @@ -2680,17 +2810,29 @@ } }, "table": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/table/-/table-5.2.3.tgz", - "integrity": "sha512-N2RsDAMvDLvYwFcwbPyF3VmVSSkuF+G1e+8inhBLtHpvwXGw4QRPEZhihQNeEN0i1up6/f6ObCJXNdlRG3YVyQ==", + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", "dev": true, "requires": { - "ajv": "^6.9.1", - "lodash": "^4.17.11", + "ajv": "^6.10.2", + "lodash": "^4.17.14", "slice-ansi": "^2.1.0", "string-width": "^3.0.0" }, "dependencies": { + "ajv": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", @@ -2878,33 +3020,30 @@ } }, "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.4.1.tgz", + "integrity": "sha512-5LpRN+mTiCs7lI5EtbXmF/HfMeCjzt7DH9CZwtkr6SywStrNQC723wG+aOWFiLNn7zT3kD/RnFqi3ZUfr4l5Qw==", "dev": true, "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", + "arg": "^4.1.0", + "diff": "^4.0.1", "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", "source-map-support": "^0.5.6", - "yn": "^2.0.0" + "yn": "^3.0.0" }, "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "diff": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", + "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", "dev": true } } }, "tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", "dev": true }, "tunnel-agent": { @@ -2936,9 +3075,9 @@ "dev": true }, "typescript": { - "version": "3.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.5.tgz", - "integrity": "sha512-YycBxUb49UUhdNMU5aJ7z5Ej2XGmaIBL0x34vZ82fn3hGvD+bgrMrVDpatgz2f7YxUMJxMkbWxJZeAvDxVe7Vw==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.3.tgz", + "integrity": "sha512-N7bceJL1CtRQ2RiG0AQME13ksR7DiuQh/QehubYcghzv20tnh+MQnQIuJddTmsbqYj+dztchykemz0zFzlvdQw==", "dev": true }, "uglify-js": { @@ -2974,6 +3113,12 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" }, + "v8-compile-cache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", + "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "dev": true + }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -3212,9 +3357,9 @@ } }, "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true } } diff --git a/package.json b/package.json index 8af3b23..5ff2c30 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hubspot", - "version": "2.2.1", + "version": "2.3.1", "description": "A node wrapper for the HubSpot API", "main": "index.js", "scripts": { @@ -28,32 +28,32 @@ }, "license": "MIT", "dependencies": { - "bottleneck": "^2.3.0", + "bottleneck": "^2.19.5", "debug": "^4.1.1", "lodash": "^4.17.15", "request": "^2.88.0", "request-promise": "^4.2.4" }, "devDependencies": { - "@types/node": "^10.5.1", + "@types/node": "^12.7.11", "@types/request": "^2.48.3", "@types/request-promise": "^4.1.44", "chai": "^4.2.0", - "cross-env": "^5.2.0", - "dotenv": "^6.2.0", - "eslint": "^5.7.0", - "eslint-config-prettier": "^3.3.0", - "eslint-config-standard": "12.0.0", - "eslint-plugin-import": "^2.9.0", - "eslint-plugin-node": "^7.0.1", - "eslint-plugin-prettier": "^3.0.0", - "eslint-plugin-promise": "^4.0.1", - "eslint-plugin-standard": "4.0.0", + "cross-env": "^6.0.3", + "dotenv": "^8.1.0", + "eslint": "^6.5.1", + "eslint-config-prettier": "^6.4.0", + "eslint-config-standard": "14.1.0", + "eslint-plugin-import": "^2.18.2", + "eslint-plugin-node": "^10.0.0", + "eslint-plugin-prettier": "^3.1.1", + "eslint-plugin-promise": "^4.2.1", + "eslint-plugin-standard": "4.0.1", "mocha": "^6.2.1", "nock": "^11.4.0", "nyc": "^14.1.1", - "prettier": "^1.15.3", - "ts-node": "^7.0.1", - "typescript": "^3.1.3" + "prettier": "^1.18.2", + "ts-node": "^8.4.1", + "typescript": "^3.6.3" } } diff --git a/test/contact_properties.js b/test/contact_properties.js index 20916d3..c67e514 100644 --- a/test/contact_properties.js +++ b/test/contact_properties.js @@ -57,9 +57,7 @@ describe('contacts.properties', function() { describe('getByName', function() { const getByNameEndpoint = { - path: `/properties/v1/contacts/properties/named/${ - contactPropertyProperties.name - }`, + path: `/properties/v1/contacts/properties/named/${contactPropertyProperties.name}`, response: contactPropertyProperties, } fakeHubspotApi.setupServer({ getEndpoints: [getByNameEndpoint] }) @@ -87,9 +85,7 @@ describe('contacts.properties', function() { describe('delete', function() { const deleteEndpoint = { - path: `/properties/v1/contacts/properties/named/${ - contactPropertyProperties.name - }`, + path: `/properties/v1/contacts/properties/named/${contactPropertyProperties.name}`, statusCode: 204, } fakeHubspotApi.setupServer({ deleteEndpoints: [deleteEndpoint] }) @@ -134,9 +130,7 @@ describe('contacts.properties', function() { describe('update', function() { const description = 'Updated display name' const updateEndpoint = { - path: `/properties/v1/contacts/properties/named/${ - contactPropertyProperties.name - }`, + path: `/properties/v1/contacts/properties/named/${contactPropertyProperties.name}`, response: Object.assign({}, contactPropertyProperties, { description }), } fakeHubspotApi.setupServer({ putEndpoints: [updateEndpoint] }) @@ -197,9 +191,7 @@ describe('contacts.properties', function() { statusCode: 409, } const updateEndpoint = { - path: `/properties/v1/contacts/properties/named/${ - contactPropertyProperties.name - }`, + path: `/properties/v1/contacts/properties/named/${contactPropertyProperties.name}`, response: Object.assign({}, contactPropertyProperties, { description }), } fakeHubspotApi.setupServer({ diff --git a/test/contacts.js b/test/contacts.js index d2ea87b..4343fe9 100644 --- a/test/contacts.js +++ b/test/contacts.js @@ -444,7 +444,7 @@ describe('contacts', function() { describe('merge', function() { let primaryVid = 12345 let secondaryVid = 3456 - let mergeData = { primaryVid: primaryVid, secondaryVid: secondaryVid } + const mergeData = { primaryVid: primaryVid, secondaryVid: secondaryVid } let c = [] diff --git a/test/crm_associations.js b/test/crm_associations.js new file mode 100644 index 0000000..e00d325 --- /dev/null +++ b/test/crm_associations.js @@ -0,0 +1,235 @@ +const { expect } = require('chai') +const Hubspot = require('..') +const fakeHubspotApi = require('./helpers/fake_hubspot_api') + +describe('crm.associations', function() { + const hubspot = new Hubspot({ + accessToken: process.env.ACCESS_TOKEN || 'fake-token', + }) + const dealProperties = [ + { + value: 'MadKudu', + name: 'dealname', + }, + { + value: 'appointmentscheduled', + name: 'dealstage', + }, + { + value: 'default', + name: 'pipeline', + }, + { + value: Date.now(), + name: 'closedate', + }, + { + value: '60000', + name: 'amount', + }, + { + value: 'newbusiness', + name: 'dealtype', + }, + ] + const companyProperties = [ + { name: 'name', value: 'A company name' }, + { name: 'description', value: 'A company description' }, + ] + const createTestDeal = () => + hubspot.deals.create({ properties: dealProperties }) + const deleteTestDeal = dealId => hubspot.deals.deleteById(dealId) + const createTestCompany = () => + hubspot.companies.create({ properties: companyProperties }) + const createDealWithCompany = () => + hubspot.companies + .create({ properties: companyProperties }) + .then(companyData => { + return hubspot.deals + .create({ + associations: { + associatedCompanyIds: [companyData.companyId], + }, + properties: dealProperties, + }) + .then(dealData => { + return { + dataCompanyId: companyData.companyId, + dataDealId: dealData.dealId, + } + }) + }) + const deleteTestCompany = companyId => hubspot.companies.delete(companyId) + + describe('create', function() { + let dealId = 123 + let companyId = 234 + const category = 'HUBSPOT_DEFINED' + const createAssociationEndpoint = { + path: `/crm-associations/v1/associations`, + statusCode: 204, + } + fakeHubspotApi.setupServer({ putEndpoints: [createAssociationEndpoint] }) + + before(function() { + if (process.env.NOCK_OFF) { + return Promise.all([ + createTestDeal().then(data => (dealId = data.dealId)), + createTestCompany().then(data => (companyId = data.companyId)), + ]) + } + }) + after(function() { + if (process.env.NOCK_OFF) { + return Promise.all([ + deleteTestDeal(dealId), + deleteTestCompany(companyId), + ]) + } + }) + + it('Returns a 204', function() { + return hubspot.crm.associations + .create({ + fromObjectId: dealId, + toObjectId: companyId, + category: category, + definitionId: 5, + }) + .then(data => { + expect(data).to.be.an('undefined') + }) + }) + }) + + describe('createBatch', function() { + let dealId = 123 + let companyId = 234 + const category = 'HUBSPOT_DEFINED' + const createBatchAssociationEndpoint = { + path: `/crm-associations/v1/associations/create-batch`, + statusCode: 204, + } + fakeHubspotApi.setupServer({ + putEndpoints: [createBatchAssociationEndpoint], + }) + + before(function() { + if (process.env.NOCK_OFF) { + return Promise.all([ + createTestDeal().then(data => (dealId = data.dealId)), + createTestCompany().then(data => (companyId = data.companyId)), + ]) + } + }) + after(function() { + if (process.env.NOCK_OFF) { + return Promise.all([ + deleteTestDeal(dealId), + deleteTestCompany(companyId), + ]) + } + }) + + it('Returns a 204', function() { + return hubspot.crm.associations + .createBatch([ + { + fromObjectId: dealId, + toObjectId: companyId, + category: category, + definitionId: 5, + }, + ]) + .then(data => { + expect(data).to.be.an('undefined') + }) + }) + }) + + describe('delete', function() { + let dealId = 123 + let companyId = 234 + const category = 'HUBSPOT_DEFINED' + const deleteAssociationEndpoint = { + path: `/crm-associations/v1/associations/delete`, + statusCode: 204, + } + fakeHubspotApi.setupServer({ putEndpoints: [deleteAssociationEndpoint] }) + + before(function() { + if (process.env.NOCK_OFF) { + return createDealWithCompany().then(({ dataDealId, dataCompanyId }) => { + dealId = dataDealId + companyId = dataCompanyId + }) + } + }) + after(function() { + if (process.env.NOCK_OFF) { + return Promise.all([ + deleteTestDeal(dealId), + deleteTestCompany(companyId), + ]) + } + }) + + it('Returns a 204', function() { + return hubspot.crm.associations + .delete({ + fromObjectId: dealId, + toObjectId: companyId, + category: category, + definitionId: 5, + }) + .then(data => { + expect(data).to.be.an('undefined') + }) + }) + }) + + describe('deleteBatch', function() { + let dealId = 123 + let companyId = 234 + const category = 'HUBSPOT_DEFINED' + const deleteBatchAssociationEndpoint = { + path: `/crm-associations/v1/associations/delete-batch`, + statusCode: 204, + } + fakeHubspotApi.setupServer({ + putEndpoints: [deleteBatchAssociationEndpoint], + }) + + before(function() { + if (process.env.NOCK_OFF) { + return Promise.all([ + createTestDeal().then(data => (dealId = data.dealId)), + createTestCompany().then(data => (companyId = data.companyId)), + ]) + } + }) + after(function() { + if (process.env.NOCK_OFF) { + return Promise.all([ + deleteTestDeal(dealId), + deleteTestCompany(companyId), + ]) + } + }) + + it('Returns a 204', function() { + return hubspot.crm.associations + .deleteBatch([ + { + fromObjectId: dealId, + toObjectId: companyId, + category: category, + definitionId: 5, + }, + ]) + .then(data => { + expect(data).to.be.an('undefined') + }) + }) + }) +}) diff --git a/test/deals.js b/test/deals.js index 1f1f87d..f33da5d 100644 --- a/test/deals.js +++ b/test/deals.js @@ -221,6 +221,40 @@ describe('deals', function() { }) }) + describe('updateBatch', function() { + const dealIds = [123, 234, 345] + let updateBatch = dealIds.map(objectId => ({ + objectId, + dealProperties, + })) + + const updateBatchEndpoint = { + path: '/deals/v1/batch-async/update', + statusCode: 202, + request: updateBatch, + } + fakeHubspotApi.setupServer({ + postEndpoints: [updateBatchEndpoint], + }) + + before(function() { + if (process.env.NOCK_OFF) { + return hubspot.deals.get({ count: 3 }).then(data => { + updateBatch = data.contacts.map(({ objectId }) => ({ + objectId, + dealProperties, + })) + }) + } + }) + + it('should update a batch of deals', function() { + return hubspot.deals.updateBatch(updateBatch).then(data => { + expect(data).to.equal(undefined) + }) + }) + }) + describe('create', function() { let dealId const createDealEndpoint = { diff --git a/test/helpers/nock_helper.js b/test/helpers/nock_helper.js index 43e75e4..7dd8ba5 100644 --- a/test/helpers/nock_helper.js +++ b/test/helpers/nock_helper.js @@ -10,12 +10,12 @@ const mockEndpoint = ({ statusCode = 200, }) => { if (responseError) { - nock('http://api.hubapi.com', { encodedQueryParams: true }) + nock('https://api.hubapi.com', { encodedQueryParams: true }) .intercept(path, verb, request) .query(query) .replyWithError(responseError) } else { - nock('http://api.hubapi.com', { encodedQueryParams: true }) + nock('https://api.hubapi.com', { encodedQueryParams: true }) .intercept(path, verb, request) .query(query) .reply(statusCode, response) diff --git a/test/workflows.js b/test/workflows.js index 698b510..515f3b9 100644 --- a/test/workflows.js +++ b/test/workflows.js @@ -5,7 +5,7 @@ const Hubspot = require('..') const hubspot = new Hubspot({ apiKey: 'demo' }) describe('workflows', function() { - let workflowId = 2641273 + const workflowId = 2641273 let contactId let contactEmail